waengine 1.0.7 β 1.0.9
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/CHANGELOG.md +89 -0
- package/FEATURES.md +2354 -0
- package/PLUGIN-SYSTEM.md +271 -0
- package/package.json +14 -3
- package/plugins/analytics-plugin/config.json +91 -0
- package/plugins/analytics-plugin/index.js +461 -0
- package/plugins/creative-plugin/config.json +87 -0
- package/plugins/creative-plugin/index.js +320 -0
- package/plugins/economy-system/config.json +48 -0
- package/plugins/economy-system/index.js +237 -0
- package/plugins/education-plugin/index.js +275 -0
- package/plugins/games-plugin/config.json +35 -0
- package/plugins/games-plugin/index.js +300 -0
- package/plugins/moderation-plugin/config.json +86 -0
- package/plugins/moderation-plugin/index.js +458 -0
- package/plugins/music-plugin/config.json +32 -0
- package/plugins/music-plugin/index.js +221 -0
- package/plugins/travel-plugin/index.js +230 -0
- package/src/ai-integration.js +185 -0
- package/src/client.js +41 -0
- package/src/http-client.js +276 -0
- package/src/index.js +6 -0
- package/src/message.js +127 -1
- package/src/plugin-manager-fixed.js +116 -0
- package/src/plugin-manager.js +105 -0
- package/src/scheduler.js +322 -0
- package/src/sticker-creator.js +413 -0
- package/src/storage.js +422 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
// π¨ Creative Plugin
|
|
2
|
+
export default class CreativePlugin {
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
this.name = 'creative-plugin';
|
|
6
|
+
this.version = '1.0.0';
|
|
7
|
+
this.description = 'Kreative Tools fΓΌr Memes, ASCII-Art, Zitate und mehr';
|
|
8
|
+
|
|
9
|
+
this.memeTemplates = [
|
|
10
|
+
'Das GefΓΌhl wenn...',
|
|
11
|
+
'Niemand:\nAbsolut niemand:\nIch:',
|
|
12
|
+
'Erwartung vs. RealitΓ€t',
|
|
13
|
+
'Wenn du denkst es wird besser...\nAber dann:',
|
|
14
|
+
'POV: Du bist...',
|
|
15
|
+
'Das ist fine π₯',
|
|
16
|
+
'Stonks π',
|
|
17
|
+
'Not stonks π'
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
this.quotes = [
|
|
21
|
+
'Das Leben ist wie ein Fahrrad. Um das Gleichgewicht zu halten, musst du in Bewegung bleiben. - Albert Einstein',
|
|
22
|
+
'Sei du selbst die VerΓ€nderung, die du dir wΓΌnschst fΓΌr diese Welt. - Mahatma Gandhi',
|
|
23
|
+
'Der beste Weg, die Zukunft vorherzusagen, ist, sie zu erschaffen. - Peter Drucker',
|
|
24
|
+
'Erfolg ist nicht endgΓΌltig, Misserfolg ist nicht fatal: Es ist der Mut weiterzumachen, der zΓ€hlt. - Winston Churchill',
|
|
25
|
+
'Innovation unterscheidet zwischen einem AnfΓΌhrer und einem Nachfolger. - Steve Jobs',
|
|
26
|
+
'Das Einzige, was wir zu fΓΌrchten haben, ist die Furcht selbst. - Franklin D. Roosevelt',
|
|
27
|
+
'TrΓ€ume nicht dein Leben, lebe deinen Traum. - Mark Twain',
|
|
28
|
+
'Wer kΓ€mpft, kann verlieren. Wer nicht kΓ€mpft, hat schon verloren. - Bertolt Brecht'
|
|
29
|
+
];
|
|
30
|
+
|
|
31
|
+
this.asciiArt = {
|
|
32
|
+
'heart': 'β₯β₯β₯β₯β₯β₯β₯\nβ₯ β₯\nβ₯ β₯ β₯\n β₯ β₯\n β₯ β₯\n β₯',
|
|
33
|
+
'star': ' β
\n β
β
β
\n β
β
β
β
β
\n β
β
β
β
β
β
β
\nβ
β
β
β
β
β
β
β
β
\n β
β
β
β
β
β
β
\n β
β
β
β
β
\n β
β
β
\n β
',
|
|
34
|
+
'smile': ' βΊβΊβΊβΊβΊ\n βΊ βΊ\nβΊ β β βΊ\nβΊ β‘ βΊ\n βΊ βΊ\n βΊβΊβΊβΊβΊ',
|
|
35
|
+
'cat': ' /\\_/\\\n( o.o )\n > ^ <',
|
|
36
|
+
'dog': ' β©___β©\n | |\n | β β |\n | Ο |\n |_______|\n U U'
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
generateMeme(template, text) {
|
|
41
|
+
const memeText = template.replace(/\.\.\./g, text);
|
|
42
|
+
|
|
43
|
+
return `π **Meme Generator**\n\n${memeText}\n\nπ Erstellt mit WAEngine Creative Plugin`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
generateRandomQuote() {
|
|
47
|
+
const quote = this.quotes[Math.floor(Math.random() * this.quotes.length)];
|
|
48
|
+
|
|
49
|
+
return `π **Zitat des Tages**\n\n"${quote}"\n\nβ¨ Lass dich inspirieren!`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
generateAsciiArt(type) {
|
|
53
|
+
const art = this.asciiArt[type.toLowerCase()];
|
|
54
|
+
|
|
55
|
+
if (!art) {
|
|
56
|
+
return `β ASCII-Art "${type}" nicht gefunden!\n\nπ VerfΓΌgbar: ${Object.keys(this.asciiArt).join(', ')}`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return `π¨ **ASCII-Art: ${type}**\n\n\`\`\`\n${art}\n\`\`\``;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
generateTextArt(text) {
|
|
63
|
+
// Einfache Text-zu-ASCII Konvertierung
|
|
64
|
+
const bigLetters = {
|
|
65
|
+
'A': ' βββ \n ββ ββ\nβ βββ β\nβ β β β\nββ ββ\n βββββ',
|
|
66
|
+
'B': 'βββββββ \nβ ββ\nβββββββ \nβ ββ\nβββββββ',
|
|
67
|
+
'C': ' ββββββ \nβ β\nβ \nβ β\n ββββββ',
|
|
68
|
+
'D': 'βββββββ \nβ ββ\nβ ββ\nβ ββ\nβββββββ',
|
|
69
|
+
'E': 'ββββββββ\nβ \nββββββ \nβ \nββββββββ',
|
|
70
|
+
'F': 'ββββββββ\nβ \nββββββ \nβ \nβ',
|
|
71
|
+
'G': ' βββββββ\nβ \nβ ββββ \nβ β \n βββββββ',
|
|
72
|
+
'H': 'β β\nβ β\nβββββββ\nβ β\nβ β',
|
|
73
|
+
'I': 'βββββββ\n β \n β \n β \nβββββββ',
|
|
74
|
+
'J': 'βββββββ\n β \n β \nβ β \n βββββ',
|
|
75
|
+
'K': 'β β \nβ β \nββββ \nβ β \nβ β',
|
|
76
|
+
'L': 'β \nβ \nβ \nβ \nβββββββ',
|
|
77
|
+
'M': 'β β\nββ ββ\nβ β β β\nβ β\nβ β',
|
|
78
|
+
'N': 'β β\nββ β\nβ β β\nβ ββ β\nβ βββ',
|
|
79
|
+
'O': ' βββββ \nβ β\nβ β\nβ β\n βββββ',
|
|
80
|
+
'P': 'βββββββ\nβ β\nβββββββ\nβ \nβ',
|
|
81
|
+
'Q': ' βββββ \nβ β\nβ β β\nβ βββ\n ββββββ',
|
|
82
|
+
'R': 'βββββββ\nβ β\nβββββββ\nβ β \nβ β',
|
|
83
|
+
'S': ' ββββββ\nβ \n ββββββ\n β\nββββββ',
|
|
84
|
+
'T': 'βββββββ\n β \n β \n β \n β',
|
|
85
|
+
'U': 'β β\nβ β\nβ β\nβ β\n βββββ',
|
|
86
|
+
'V': 'β β\nβ β\nβ β\n β β \n β',
|
|
87
|
+
'W': 'β β\nβ β\nβ β β\nβ β β β\nβ β',
|
|
88
|
+
'X': 'β β\n β β \n β \n β β \nβ β',
|
|
89
|
+
'Y': 'β β\n β β \n β \n β \n β',
|
|
90
|
+
'Z': 'βββββββ\n ββ\n ββ \n ββ \nβββββββ'
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const chars = text.toUpperCase().split('');
|
|
94
|
+
const lines = ['', '', '', '', '', ''];
|
|
95
|
+
|
|
96
|
+
chars.forEach(char => {
|
|
97
|
+
if (bigLetters[char]) {
|
|
98
|
+
const letterLines = bigLetters[char].split('\n');
|
|
99
|
+
letterLines.forEach((line, index) => {
|
|
100
|
+
lines[index] += line + ' ';
|
|
101
|
+
});
|
|
102
|
+
} else if (char === ' ') {
|
|
103
|
+
lines.forEach((line, index) => {
|
|
104
|
+
lines[index] += ' ';
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
return `π¨ **Text-Art: ${text}**\n\n\`\`\`\n${lines.join('\n')}\n\`\`\``;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
generateColorText(text, style = 'rainbow') {
|
|
113
|
+
const styles = {
|
|
114
|
+
'rainbow': ['π΄', 'π ', 'π‘', 'π’', 'π΅', 'π£'],
|
|
115
|
+
'fire': ['π₯', 'π§‘', 'β€οΈ', 'π'],
|
|
116
|
+
'ocean': ['π', 'π', 'π΅', 'π'],
|
|
117
|
+
'nature': ['π±', 'πΏ', 'π', 'π'],
|
|
118
|
+
'space': ['β', 'π', 'β¨', 'π']
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
const colors = styles[style] || styles.rainbow;
|
|
122
|
+
let coloredText = '';
|
|
123
|
+
|
|
124
|
+
for (let i = 0; i < text.length; i++) {
|
|
125
|
+
if (text[i] !== ' ') {
|
|
126
|
+
coloredText += colors[i % colors.length] + text[i];
|
|
127
|
+
} else {
|
|
128
|
+
coloredText += ' ';
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return `π¨ **${style.toUpperCase()} Text**\n\n${coloredText}`;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
generateRandomFact() {
|
|
136
|
+
const facts = [
|
|
137
|
+
'Honig verdirbt nie. ArchΓ€ologen haben 3000 Jahre alten Honig gefunden, der noch essbar war!',
|
|
138
|
+
'Bananen sind Beeren, aber Erdbeeren nicht.',
|
|
139
|
+
'Ein Oktopus hat drei Herzen und blaues Blut.',
|
|
140
|
+
'Flamingos sind nur rosa wegen ihrer ErnΓ€hrung.',
|
|
141
|
+
'Wombats haben wΓΌrfelfΓΆrmigen Kot.',
|
|
142
|
+
'Seepferdchen sind die einzigen Tiere, bei denen das MΓ€nnchen schwanger wird.',
|
|
143
|
+
'Pinguine haben Knie, man kann sie nur nicht sehen.',
|
|
144
|
+
'Koalas schlafen 22 Stunden am Tag.',
|
|
145
|
+
'Delfine haben Namen fΓΌr sich selbst.',
|
|
146
|
+
'Elefanten kΓΆnnen nicht springen.'
|
|
147
|
+
];
|
|
148
|
+
|
|
149
|
+
const fact = facts[Math.floor(Math.random() * facts.length)];
|
|
150
|
+
|
|
151
|
+
return `π€― **Unglaublicher Fakt!**\n\n${fact}\n\nπ Wissen ist Macht!`;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
generateJoke() {
|
|
155
|
+
const jokes = [
|
|
156
|
+
'Warum nehmen Geister keine Drogen? Weil sie schon high genug sind! π»',
|
|
157
|
+
'Was ist grΓΌn und klopft an der TΓΌr? Ein Klopfsalat! π₯¬',
|
|
158
|
+
'Warum kΓΆnnen Geister so schlecht lΓΌgen? Weil man durch sie hindurchsehen kann! π»',
|
|
159
|
+
'Was ist weiΓ und stΓΆrt beim Essen? Eine Lawine! β·οΈ',
|
|
160
|
+
'Warum ist ein Buch ΓΌber Helium so gut? Man kann es nicht weglegen! π',
|
|
161
|
+
'Was sagt ein groΓer Stift zum kleinen Stift? Wachs-mal-stift! βοΈ',
|
|
162
|
+
'Warum summen Bienen? Weil sie den Text nicht kennen! π',
|
|
163
|
+
'Was ist rot und schlecht fΓΌr die ZΓ€hne? Ein Ziegelstein! π§±',
|
|
164
|
+
'Warum gehen Ameisen nicht in die Kirche? Weil sie Insekten sind! π',
|
|
165
|
+
'Was ist gelb und kann nicht schwimmen? Ein Bagger! π'
|
|
166
|
+
];
|
|
167
|
+
|
|
168
|
+
const joke = jokes[Math.floor(Math.random() * jokes.length)];
|
|
169
|
+
|
|
170
|
+
return `π **Witz des Tages**\n\n${joke}\n\nπ Lachen ist die beste Medizin!`;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
generateStoryPrompt() {
|
|
174
|
+
const characters = ['ein mutiger Ritter', 'eine kluge Hexe', 'ein freundlicher Drache', 'ein neugieriger Roboter', 'eine geheimnisvolle Katze'];
|
|
175
|
+
const settings = ['in einem verzauberten Wald', 'auf einem fernen Planeten', 'in einer unterirdischen Stadt', 'in der Zukunft', 'in einem magischen Schloss'];
|
|
176
|
+
const conflicts = ['muss ein RΓ€tsel lΓΆsen', 'sucht nach einem verlorenen Schatz', 'rettet die Welt', 'findet neue Freunde', 'entdeckt ein Geheimnis'];
|
|
177
|
+
|
|
178
|
+
const character = characters[Math.floor(Math.random() * characters.length)];
|
|
179
|
+
const setting = settings[Math.floor(Math.random() * settings.length)];
|
|
180
|
+
const conflict = conflicts[Math.floor(Math.random() * conflicts.length)];
|
|
181
|
+
|
|
182
|
+
return `π **Story-Prompt Generator**\n\nπ **Charakter:** ${character}\nπ **Setting:** ${setting}\nβ‘ **Konflikt:** ${conflict}\n\nβοΈ Schreibe deine eigene Geschichte mit diesen Elementen!`;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
getCommands() {
|
|
186
|
+
return {
|
|
187
|
+
'meme': this.handleMeme.bind(this),
|
|
188
|
+
'quote': this.handleQuote.bind(this),
|
|
189
|
+
'ascii': this.handleAscii.bind(this),
|
|
190
|
+
'textart': this.handleTextArt.bind(this),
|
|
191
|
+
'colortext': this.handleColorText.bind(this),
|
|
192
|
+
'fact': this.handleFact.bind(this),
|
|
193
|
+
'joke': this.handleJoke.bind(this),
|
|
194
|
+
'story': this.handleStory.bind(this),
|
|
195
|
+
'inspire': this.handleInspire.bind(this),
|
|
196
|
+
'creative': this.handleCreative.bind(this)
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
async handleMeme(msg, args) {
|
|
201
|
+
if (args.length === 0) {
|
|
202
|
+
let memeText = `π **Meme Generator**\n\nπ **VerfΓΌgbare Templates:**\n`;
|
|
203
|
+
this.memeTemplates.forEach((template, index) => {
|
|
204
|
+
memeText += `${index + 1}. ${template}\n`;
|
|
205
|
+
});
|
|
206
|
+
memeText += `\nπ‘ Verwendung: !meme <nummer> <text>\nπ Beispiel: !meme 1 Programmieren lernen`;
|
|
207
|
+
|
|
208
|
+
return msg.reply(memeText);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
const templateIndex = parseInt(args[0]) - 1;
|
|
212
|
+
const text = args.slice(1).join(' ');
|
|
213
|
+
|
|
214
|
+
if (templateIndex < 0 || templateIndex >= this.memeTemplates.length) {
|
|
215
|
+
return msg.reply(`β Template ${args[0]} existiert nicht!\n\nπ‘ Verwende !meme ohne Parameter fΓΌr alle Templates.`);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (!text) {
|
|
219
|
+
return msg.reply('β Bitte gib einen Text fΓΌr das Meme an!');
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const meme = this.generateMeme(this.memeTemplates[templateIndex], text);
|
|
223
|
+
await msg.reply(meme);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
async handleQuote(msg, args) {
|
|
227
|
+
const quote = this.generateRandomQuote();
|
|
228
|
+
await msg.reply(quote);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async handleAscii(msg, args) {
|
|
232
|
+
if (args.length === 0) {
|
|
233
|
+
const available = Object.keys(this.asciiArt).join(', ');
|
|
234
|
+
return msg.reply(`π¨ **ASCII-Art Generator**\n\nπ VerfΓΌgbar: ${available}\n\nπ‘ Verwendung: !ascii <typ>\nπ Beispiel: !ascii heart`);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const type = args[0];
|
|
238
|
+
const art = this.generateAsciiArt(type);
|
|
239
|
+
await msg.reply(art);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
async handleTextArt(msg, args) {
|
|
243
|
+
if (args.length === 0) {
|
|
244
|
+
return msg.reply('β Verwendung: !textart <text>\n\nπ¨ Beispiel: !textart HELLO\nπ‘ Funktioniert am besten mit kurzen WΓΆrtern!');
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
const text = args.join(' ');
|
|
248
|
+
|
|
249
|
+
if (text.length > 10) {
|
|
250
|
+
return msg.reply('β Text zu lang! Maximal 10 Zeichen fΓΌr beste Darstellung.');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
const textArt = this.generateTextArt(text);
|
|
254
|
+
await msg.reply(textArt);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
async handleColorText(msg, args) {
|
|
258
|
+
if (args.length === 0) {
|
|
259
|
+
return msg.reply('β Verwendung: !colortext <text> [stil]\n\nπ¨ **Stile:** rainbow, fire, ocean, nature, space\nπ Beispiel: !colortext Hello World rainbow');
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
const style = args[args.length - 1];
|
|
263
|
+
const validStyles = ['rainbow', 'fire', 'ocean', 'nature', 'space'];
|
|
264
|
+
|
|
265
|
+
let text, selectedStyle;
|
|
266
|
+
|
|
267
|
+
if (validStyles.includes(style)) {
|
|
268
|
+
text = args.slice(0, -1).join(' ');
|
|
269
|
+
selectedStyle = style;
|
|
270
|
+
} else {
|
|
271
|
+
text = args.join(' ');
|
|
272
|
+
selectedStyle = 'rainbow';
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const coloredText = this.generateColorText(text, selectedStyle);
|
|
276
|
+
await msg.reply(coloredText);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
async handleFact(msg, args) {
|
|
280
|
+
const fact = this.generateRandomFact();
|
|
281
|
+
await msg.reply(fact);
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
async handleJoke(msg, args) {
|
|
285
|
+
const joke = this.generateJoke();
|
|
286
|
+
await msg.reply(joke);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
async handleStory(msg, args) {
|
|
290
|
+
const storyPrompt = this.generateStoryPrompt();
|
|
291
|
+
await msg.reply(storyPrompt);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
async handleInspire(msg, args) {
|
|
295
|
+
const inspirations = [
|
|
296
|
+
this.generateRandomQuote(),
|
|
297
|
+
this.generateRandomFact(),
|
|
298
|
+
this.generateStoryPrompt()
|
|
299
|
+
];
|
|
300
|
+
|
|
301
|
+
const inspiration = inspirations[Math.floor(Math.random() * inspirations.length)];
|
|
302
|
+
await msg.reply(inspiration);
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
async handleCreative(msg, args) {
|
|
306
|
+
let creativeText = `π¨ **Creative Plugin - Γbersicht**\n\n`;
|
|
307
|
+
creativeText += `π **!meme** - Meme Generator mit Templates\n`;
|
|
308
|
+
creativeText += `π **!quote** - Inspirierende Zitate\n`;
|
|
309
|
+
creativeText += `π¨ **!ascii** - ASCII-Art erstellen\n`;
|
|
310
|
+
creativeText += `β¨ **!textart** - GroΓer Text-Art\n`;
|
|
311
|
+
creativeText += `π **!colortext** - Bunter Text mit Emojis\n`;
|
|
312
|
+
creativeText += `π€― **!fact** - Unglaubliche Fakten\n`;
|
|
313
|
+
creativeText += `π **!joke** - Lustige Witze\n`;
|
|
314
|
+
creativeText += `π **!story** - Story-Prompt Generator\n`;
|
|
315
|
+
creativeText += `β¨ **!inspire** - ZufΓ€llige Inspiration\n\n`;
|
|
316
|
+
creativeText += `π‘ Verwende jeden Befehl ohne Parameter fΓΌr Details!`;
|
|
317
|
+
|
|
318
|
+
await msg.reply(creativeText);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Economy System",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "VollstΓ€ndiges Wirtschaftssystem mit Coins, Shop und Daily Rewards",
|
|
5
|
+
"author": "WAEngine",
|
|
6
|
+
"commands": [
|
|
7
|
+
"balance",
|
|
8
|
+
"daily",
|
|
9
|
+
"work",
|
|
10
|
+
"shop",
|
|
11
|
+
"buy",
|
|
12
|
+
"transfer",
|
|
13
|
+
"inventory",
|
|
14
|
+
"leaderboard"
|
|
15
|
+
],
|
|
16
|
+
"permissions": {
|
|
17
|
+
"balance": "all",
|
|
18
|
+
"daily": "all",
|
|
19
|
+
"work": "all",
|
|
20
|
+
"shop": "all",
|
|
21
|
+
"buy": "all",
|
|
22
|
+
"transfer": "group-only",
|
|
23
|
+
"inventory": "all",
|
|
24
|
+
"leaderboard": "all"
|
|
25
|
+
},
|
|
26
|
+
"settings": {
|
|
27
|
+
"dailyReward": {
|
|
28
|
+
"min": 100,
|
|
29
|
+
"max": 600
|
|
30
|
+
},
|
|
31
|
+
"workCooldown": 3600000,
|
|
32
|
+
"transferEnabled": true,
|
|
33
|
+
"shopItems": [
|
|
34
|
+
{
|
|
35
|
+
"id": "vip",
|
|
36
|
+
"name": "π VIP Status",
|
|
37
|
+
"price": 5000,
|
|
38
|
+
"description": "VIP Rang fΓΌr 30 Tage"
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"id": "boost",
|
|
42
|
+
"name": "β‘ XP Boost",
|
|
43
|
+
"price": 1000,
|
|
44
|
+
"description": "2x XP fΓΌr 24h"
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// π° Economy System Plugin
|
|
2
|
+
export default class EconomyPlugin {
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
this.name = 'economy-system';
|
|
6
|
+
this.version = '1.0.0';
|
|
7
|
+
this.description = 'VollstΓ€ndiges Wirtschaftssystem mit Coins, Shop und Daily Rewards';
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
// Coins System
|
|
11
|
+
async getBalance(userId) {
|
|
12
|
+
return this.client.storage.read.from('economy').get(`${userId}.coins`) || 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async addCoins(userId, amount) {
|
|
16
|
+
this.client.storage.write.in('economy').increment(`${userId}.coins`, amount);
|
|
17
|
+
return await this.getBalance(userId);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async removeCoins(userId, amount) {
|
|
21
|
+
const balance = await this.getBalance(userId);
|
|
22
|
+
if (balance < amount) return false;
|
|
23
|
+
|
|
24
|
+
this.client.storage.write.in('economy').increment(`${userId}.coins`, -amount);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async transfer(fromId, toId, amount) {
|
|
29
|
+
if (await this.removeCoins(fromId, amount)) {
|
|
30
|
+
await this.addCoins(toId, amount);
|
|
31
|
+
return true;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Daily System
|
|
37
|
+
async claimDaily(userId) {
|
|
38
|
+
const lastDaily = this.client.storage.read.from('economy').get(`${userId}.lastDaily`) || 0;
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
const dayMs = 24 * 60 * 60 * 1000;
|
|
41
|
+
|
|
42
|
+
if (now - lastDaily < dayMs) {
|
|
43
|
+
const timeLeft = dayMs - (now - lastDaily);
|
|
44
|
+
const hours = Math.floor(timeLeft / (60 * 60 * 1000));
|
|
45
|
+
const minutes = Math.floor((timeLeft % (60 * 60 * 1000)) / (60 * 1000));
|
|
46
|
+
return { success: false, timeLeft: `${hours}h ${minutes}m` };
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const reward = Math.floor(Math.random() * 500) + 100; // 100-600 Coins
|
|
50
|
+
await this.addCoins(userId, reward);
|
|
51
|
+
this.client.storage.write.in('economy').set(`${userId}.lastDaily`, now);
|
|
52
|
+
|
|
53
|
+
return { success: true, reward };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// Shop System
|
|
57
|
+
getShopItems() {
|
|
58
|
+
return [
|
|
59
|
+
{ id: 'vip', name: 'π VIP Status', price: 5000, description: 'VIP Rang fΓΌr 30 Tage' },
|
|
60
|
+
{ id: 'boost', name: 'β‘ XP Boost', price: 1000, description: '2x XP fΓΌr 24h' },
|
|
61
|
+
{ id: 'title', name: 'π Custom Title', price: 2500, description: 'Eigener Titel' },
|
|
62
|
+
{ id: 'color', name: 'π¨ Name Color', price: 1500, description: 'Farbiger Name' }
|
|
63
|
+
];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
async buyItem(userId, itemId) {
|
|
67
|
+
const items = this.getShopItems();
|
|
68
|
+
const item = items.find(i => i.id === itemId);
|
|
69
|
+
|
|
70
|
+
if (!item) return { success: false, error: 'Item nicht gefunden' };
|
|
71
|
+
|
|
72
|
+
if (await this.removeCoins(userId, item.price)) {
|
|
73
|
+
this.client.storage.write.in('economy').push(`${userId}.inventory`, {
|
|
74
|
+
id: item.id,
|
|
75
|
+
name: item.name,
|
|
76
|
+
boughtAt: Date.now()
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return { success: true, item };
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return { success: false, error: 'Nicht genug Coins' };
|
|
83
|
+
}
|
|
84
|
+
getCommands() {
|
|
85
|
+
return {
|
|
86
|
+
'balance': this.handleBalance.bind(this),
|
|
87
|
+
'daily': this.handleDaily.bind(this),
|
|
88
|
+
'transfer': this.handleTransfer.bind(this),
|
|
89
|
+
'shop': this.handleShop.bind(this),
|
|
90
|
+
'buy': this.handleBuy.bind(this),
|
|
91
|
+
'inventory': this.handleInventory.bind(this),
|
|
92
|
+
'leaderboard': this.handleLeaderboard.bind(this),
|
|
93
|
+
'work': this.handleWork.bind(this)
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Command Handlers
|
|
98
|
+
async handleBalance(msg, args) {
|
|
99
|
+
const userId = msg.getSender();
|
|
100
|
+
const balance = await this.getBalance(userId);
|
|
101
|
+
|
|
102
|
+
await msg.reply(`π° **Dein Kontostand:**\n\nπ ${balance.toLocaleString()} Coins`);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
async handleDaily(msg, args) {
|
|
106
|
+
const userId = msg.getSender();
|
|
107
|
+
const result = await this.claimDaily(userId);
|
|
108
|
+
|
|
109
|
+
if (result.success) {
|
|
110
|
+
await msg.reply(`π **Daily Reward erhalten!**\n\nπ +${result.reward} Coins\nπ° Neuer Kontostand: ${(await this.getBalance(userId)).toLocaleString()}`);
|
|
111
|
+
} else {
|
|
112
|
+
await msg.reply(`β° **Daily bereits abgeholt!**\n\nβ³ NΓ€chste Daily in: ${result.timeLeft}`);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
async handleTransfer(msg, args) {
|
|
117
|
+
if (!msg.isGroup) return msg.reply('β Transfer nur in Gruppen mΓΆglich!');
|
|
118
|
+
|
|
119
|
+
const mentions = msg.getMentions();
|
|
120
|
+
if (mentions.length === 0 || args.length < 2) {
|
|
121
|
+
return msg.reply('β Verwendung: !transfer @user <amount>');
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
const fromId = msg.getSender();
|
|
125
|
+
const toId = mentions[0];
|
|
126
|
+
const amount = parseInt(args[1]);
|
|
127
|
+
|
|
128
|
+
if (isNaN(amount) || amount <= 0) {
|
|
129
|
+
return msg.reply('β UngΓΌltiger Betrag!');
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (fromId === toId) {
|
|
133
|
+
return msg.reply('β Du kannst dir nicht selbst Coins senden!');
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (await this.transfer(fromId, toId, amount)) {
|
|
137
|
+
await msg.reply(`β
**Transfer erfolgreich!**\n\nπΈ ${amount} Coins an @${toId.split('@')[0]} gesendet`, [toId]);
|
|
138
|
+
} else {
|
|
139
|
+
await msg.reply('β Nicht genug Coins fΓΌr den Transfer!');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
async handleShop(msg, args) {
|
|
144
|
+
const items = this.getShopItems();
|
|
145
|
+
let shopText = 'π **Economy Shop**\n\n';
|
|
146
|
+
|
|
147
|
+
items.forEach((item, index) => {
|
|
148
|
+
shopText += `${index + 1}. ${item.name}\nπ ${item.price.toLocaleString()} Coins\nπ ${item.description}\n\n`;
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
shopText += 'π‘ Kaufe mit: !buy <item-id>';
|
|
152
|
+
await msg.reply(shopText);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async handleBuy(msg, args) {
|
|
156
|
+
if (args.length === 0) {
|
|
157
|
+
return msg.reply('β Verwendung: !buy <item-id>\n\nπ‘ Siehe !shop fΓΌr verfΓΌgbare Items');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
const userId = msg.getSender();
|
|
161
|
+
const itemId = args[0].toLowerCase();
|
|
162
|
+
const result = await this.buyItem(userId, itemId);
|
|
163
|
+
|
|
164
|
+
if (result.success) {
|
|
165
|
+
await msg.reply(`β
**Kauf erfolgreich!**\n\nποΈ ${result.item.name} gekauft\nπ -${result.item.price} Coins`);
|
|
166
|
+
} else {
|
|
167
|
+
await msg.reply(`β **Kauf fehlgeschlagen!**\n\nβ οΈ ${result.error}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
async handleInventory(msg, args) {
|
|
172
|
+
const userId = msg.getSender();
|
|
173
|
+
const inventory = this.client.storage.read.from('economy').get(`${userId}.inventory`) || [];
|
|
174
|
+
|
|
175
|
+
if (inventory.length === 0) {
|
|
176
|
+
return msg.reply('π¦ **Dein Inventar ist leer!**\n\nπ Besuche den !shop um Items zu kaufen');
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
let invText = 'π¦ **Dein Inventar:**\n\n';
|
|
180
|
+
inventory.forEach((item, index) => {
|
|
181
|
+
invText += `${index + 1}. ${item.name}\nπ
Gekauft: ${new Date(item.boughtAt).toLocaleDateString()}\n\n`;
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
await msg.reply(invText);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
async handleLeaderboard(msg, args) {
|
|
188
|
+
const economyData = this.client.storage.read.from('economy').all() || {};
|
|
189
|
+
const leaderboard = [];
|
|
190
|
+
|
|
191
|
+
Object.entries(economyData).forEach(([userId, data]) => {
|
|
192
|
+
if (data.coins && data.coins > 0) {
|
|
193
|
+
leaderboard.push({ userId, coins: data.coins });
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
leaderboard.sort((a, b) => b.coins - a.coins);
|
|
198
|
+
const top10 = leaderboard.slice(0, 10);
|
|
199
|
+
|
|
200
|
+
let lbText = 'π **Coins Leaderboard**\n\n';
|
|
201
|
+
top10.forEach((entry, index) => {
|
|
202
|
+
const medal = index === 0 ? 'π₯' : index === 1 ? 'π₯' : index === 2 ? 'π₯' : `${index + 1}.`;
|
|
203
|
+
lbText += `${medal} @${entry.userId.split('@')[0]}\nπ ${entry.coins.toLocaleString()} Coins\n\n`;
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
await msg.reply(lbText);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
async handleWork(msg, args) {
|
|
210
|
+
const userId = msg.getSender();
|
|
211
|
+
const lastWork = this.client.storage.read.from('economy').get(`${userId}.lastWork`) || 0;
|
|
212
|
+
const now = Date.now();
|
|
213
|
+
const cooldown = 60 * 60 * 1000; // 1 Stunde
|
|
214
|
+
|
|
215
|
+
if (now - lastWork < cooldown) {
|
|
216
|
+
const timeLeft = cooldown - (now - lastWork);
|
|
217
|
+
const minutes = Math.floor(timeLeft / (60 * 1000));
|
|
218
|
+
return msg.reply(`β° **Arbeit Cooldown!**\n\nβ³ Noch ${minutes} Minuten warten`);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const jobs = [
|
|
222
|
+
{ name: 'π Pizza liefern', min: 50, max: 150 },
|
|
223
|
+
{ name: 'π Taxi fahren', min: 80, max: 200 },
|
|
224
|
+
{ name: 'π» Programmieren', min: 100, max: 300 },
|
|
225
|
+
{ name: 'π¨ Design erstellen', min: 75, max: 250 },
|
|
226
|
+
{ name: 'π¦ Pakete sortieren', min: 40, max: 120 }
|
|
227
|
+
];
|
|
228
|
+
|
|
229
|
+
const job = jobs[Math.floor(Math.random() * jobs.length)];
|
|
230
|
+
const earnings = Math.floor(Math.random() * (job.max - job.min + 1)) + job.min;
|
|
231
|
+
|
|
232
|
+
await this.addCoins(userId, earnings);
|
|
233
|
+
this.client.storage.write.in('economy').set(`${userId}.lastWork`, now);
|
|
234
|
+
|
|
235
|
+
await msg.reply(`πΌ **Arbeit erledigt!**\n\n${job.name}\nπ +${earnings} Coins verdient\nπ° Neuer Kontostand: ${(await this.getBalance(userId)).toLocaleString()}`);
|
|
236
|
+
}
|
|
237
|
+
}
|