waengine 1.0.8 → 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 +12 -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/client.js +22 -0
- package/src/index.js +2 -0
- package/src/message.js +109 -1
- package/src/plugin-manager-fixed.js +116 -0
- package/src/plugin-manager.js +105 -0
- package/src/sticker-creator.js +413 -0
- package/src/storage.js +5 -4
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
// 📚 Education Plugin
|
|
2
|
+
export default class EducationPlugin {
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
this.name = 'education-plugin';
|
|
6
|
+
this.version = '1.0.0';
|
|
7
|
+
this.description = 'Bildungs-System mit Wikipedia, Wörterbuch, Mathe und Code-Hilfe';
|
|
8
|
+
|
|
9
|
+
this.mathOperators = {
|
|
10
|
+
'+': (a, b) => a + b,
|
|
11
|
+
'-': (a, b) => a - b,
|
|
12
|
+
'*': (a, b) => a * b,
|
|
13
|
+
'/': (a, b) => a / b,
|
|
14
|
+
'^': (a, b) => Math.pow(a, b),
|
|
15
|
+
'sqrt': (a) => Math.sqrt(a),
|
|
16
|
+
'sin': (a) => Math.sin(a),
|
|
17
|
+
'cos': (a) => Math.cos(a),
|
|
18
|
+
'tan': (a) => Math.tan(a)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async searchWikipedia(query) {
|
|
23
|
+
try {
|
|
24
|
+
// Verwende HTTP Client für Wikipedia API
|
|
25
|
+
const response = await this.client.http.get(`https://de.wikipedia.org/api/rest_v1/page/summary/${encodeURIComponent(query)}`);
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
title: response.title,
|
|
29
|
+
extract: response.extract,
|
|
30
|
+
url: response.content_urls?.desktop?.page,
|
|
31
|
+
thumbnail: response.thumbnail?.source
|
|
32
|
+
};
|
|
33
|
+
} catch (error) {
|
|
34
|
+
return {
|
|
35
|
+
title: query,
|
|
36
|
+
extract: `Artikel über "${query}" nicht gefunden. Versuche einen anderen Suchbegriff.`,
|
|
37
|
+
url: `https://de.wikipedia.org/wiki/${encodeURIComponent(query)}`,
|
|
38
|
+
thumbnail: null
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
async defineWord(word) {
|
|
44
|
+
// Simuliertes Wörterbuch
|
|
45
|
+
const definitions = {
|
|
46
|
+
'javascript': 'Eine Programmiersprache für Web-Entwicklung',
|
|
47
|
+
'node': 'JavaScript-Laufzeitumgebung für Server-Anwendungen',
|
|
48
|
+
'api': 'Application Programming Interface - Schnittstelle zwischen Anwendungen',
|
|
49
|
+
'bot': 'Automatisiertes Programm das Aufgaben ausführt',
|
|
50
|
+
'whatsapp': 'Messaging-Dienst für Smartphones und Computer'
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return definitions[word.toLowerCase()] || `Definition für "${word}" nicht gefunden. Versuche !wiki ${word} für mehr Informationen.`;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
solveMath(expression) {
|
|
57
|
+
try {
|
|
58
|
+
// Einfacher Mathe-Parser (sicherheitshalber begrenzt)
|
|
59
|
+
const sanitized = expression.replace(/[^0-9+\-*/.() ]/g, '');
|
|
60
|
+
|
|
61
|
+
// Verwende Function constructor für sichere Evaluation
|
|
62
|
+
const result = Function(`"use strict"; return (${sanitized})`)();
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
expression: expression,
|
|
66
|
+
result: result,
|
|
67
|
+
success: true
|
|
68
|
+
};
|
|
69
|
+
} catch (error) {
|
|
70
|
+
return {
|
|
71
|
+
expression: expression,
|
|
72
|
+
result: 'Ungültiger mathematischer Ausdruck',
|
|
73
|
+
success: false
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
explainCode(code, language = 'javascript') {
|
|
79
|
+
const explanations = {
|
|
80
|
+
'console.log': 'Gibt Text in der Konsole aus',
|
|
81
|
+
'function': 'Definiert eine wiederverwendbare Funktion',
|
|
82
|
+
'const': 'Deklariert eine Konstante (unveränderliche Variable)',
|
|
83
|
+
'let': 'Deklariert eine Variable mit Block-Scope',
|
|
84
|
+
'var': 'Deklariert eine Variable mit Function-Scope',
|
|
85
|
+
'if': 'Bedingte Anweisung - führt Code nur aus wenn Bedingung wahr ist',
|
|
86
|
+
'for': 'Schleife - wiederholt Code eine bestimmte Anzahl mal',
|
|
87
|
+
'while': 'Schleife - wiederholt Code solange Bedingung wahr ist',
|
|
88
|
+
'return': 'Gibt einen Wert aus einer Funktion zurück',
|
|
89
|
+
'async': 'Markiert eine Funktion als asynchron',
|
|
90
|
+
'await': 'Wartet auf das Ergebnis einer asynchronen Operation'
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
let explanation = `💻 **Code-Erklärung (${language}):**\n\n`;
|
|
94
|
+
explanation += `\`\`\`${language}\n${code}\n\`\`\`\n\n`;
|
|
95
|
+
|
|
96
|
+
// Suche nach bekannten Keywords
|
|
97
|
+
const foundKeywords = [];
|
|
98
|
+
Object.keys(explanations).forEach(keyword => {
|
|
99
|
+
if (code.includes(keyword)) {
|
|
100
|
+
foundKeywords.push(`• **${keyword}**: ${explanations[keyword]}`);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
if (foundKeywords.length > 0) {
|
|
105
|
+
explanation += '📝 **Erklärungen:**\n' + foundKeywords.join('\n');
|
|
106
|
+
} else {
|
|
107
|
+
explanation += '💡 Sende kleinere Code-Snippets für detailliertere Erklärungen.';
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return explanation;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
getRandomFact() {
|
|
114
|
+
const facts = [
|
|
115
|
+
'Der erste Computer-Bug war tatsächlich ein echter Käfer, der 1947 in einem Computer gefunden wurde.',
|
|
116
|
+
'Das Internet wiegt etwa 50 Gramm - das Gewicht aller Elektronen in Bewegung.',
|
|
117
|
+
'JavaScript wurde in nur 10 Tagen entwickelt.',
|
|
118
|
+
'Das erste YouTube-Video wurde am 23. April 2005 hochgeladen.',
|
|
119
|
+
'Es gibt mehr mögliche Schachspiele als Atome im beobachtbaren Universum.',
|
|
120
|
+
'Der Begriff "Spam" für unerwünschte E-Mails kommt von Monty Python.',
|
|
121
|
+
'Das @-Symbol wird in verschiedenen Sprachen unterschiedlich genannt: Klammeraffe (Deutsch), Snabel-a (Dänisch), oder Elefantenohr (Tschechisch).'
|
|
122
|
+
];
|
|
123
|
+
|
|
124
|
+
return facts[Math.floor(Math.random() * facts.length)];
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
getCommands() {
|
|
128
|
+
return {
|
|
129
|
+
'wiki': this.handleWiki.bind(this),
|
|
130
|
+
'define': this.handleDefine.bind(this),
|
|
131
|
+
'math': this.handleMath.bind(this),
|
|
132
|
+
'code': this.handleCode.bind(this),
|
|
133
|
+
'learn': this.handleLearn.bind(this),
|
|
134
|
+
'fact': this.handleFact.bind(this),
|
|
135
|
+
'study': this.handleStudy.bind(this)
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async handleWiki(msg, args) {
|
|
140
|
+
if (args.length === 0) {
|
|
141
|
+
return msg.reply('❌ Verwendung: !wiki <suchbegriff>\n\n📚 Beispiel: !wiki JavaScript');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const query = args.join(' ');
|
|
145
|
+
await msg.reply(`📚 Suche Wikipedia-Artikel über "${query}"...`);
|
|
146
|
+
|
|
147
|
+
const article = await this.searchWikipedia(query);
|
|
148
|
+
|
|
149
|
+
let wikiText = `📚 **Wikipedia: ${article.title}**\n\n`;
|
|
150
|
+
wikiText += `${article.extract}\n\n`;
|
|
151
|
+
wikiText += `🔗 Mehr lesen: ${article.url}`;
|
|
152
|
+
|
|
153
|
+
await msg.reply(wikiText);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
async handleDefine(msg, args) {
|
|
157
|
+
if (args.length === 0) {
|
|
158
|
+
return msg.reply('❌ Verwendung: !define <wort>\n\n📖 Beispiel: !define API');
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
const word = args.join(' ');
|
|
162
|
+
const definition = await this.defineWord(word);
|
|
163
|
+
|
|
164
|
+
let defineText = `📖 **Definition: ${word}**\n\n`;
|
|
165
|
+
defineText += definition;
|
|
166
|
+
|
|
167
|
+
await msg.reply(defineText);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
async handleMath(msg, args) {
|
|
171
|
+
if (args.length === 0) {
|
|
172
|
+
return msg.reply('❌ Verwendung: !math <ausdruck>\n\n🧮 Beispiele:\n• !math 2 + 2\n• !math 15 * 8\n• !math (10 + 5) / 3');
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const expression = args.join(' ');
|
|
176
|
+
const result = this.solveMath(expression);
|
|
177
|
+
|
|
178
|
+
let mathText = `🧮 **Mathe-Rechner:**\n\n`;
|
|
179
|
+
mathText += `📝 Ausdruck: ${result.expression}\n`;
|
|
180
|
+
|
|
181
|
+
if (result.success) {
|
|
182
|
+
mathText += `✅ Ergebnis: ${result.result}`;
|
|
183
|
+
} else {
|
|
184
|
+
mathText += `❌ Fehler: ${result.result}`;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
await msg.reply(mathText);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
async handleCode(msg, args) {
|
|
191
|
+
if (args.length === 0) {
|
|
192
|
+
return msg.reply('❌ Verwendung: !code <code>\n\n💻 Beispiel: !code console.log("Hello World")');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
const code = args.join(' ');
|
|
196
|
+
const explanation = this.explainCode(code);
|
|
197
|
+
|
|
198
|
+
await msg.reply(explanation);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async handleLearn(msg, args) {
|
|
202
|
+
if (args.length === 0) {
|
|
203
|
+
const topics = [
|
|
204
|
+
'🌐 **Web Development**: HTML, CSS, JavaScript',
|
|
205
|
+
'🐍 **Python**: Programmierung für Anfänger',
|
|
206
|
+
'⚛️ **React**: Frontend Framework',
|
|
207
|
+
'🟢 **Node.js**: Backend JavaScript',
|
|
208
|
+
'🗄️ **Datenbanken**: SQL, MongoDB',
|
|
209
|
+
'🔧 **Git**: Versionskontrolle',
|
|
210
|
+
'☁️ **Cloud**: AWS, Azure, Google Cloud'
|
|
211
|
+
];
|
|
212
|
+
|
|
213
|
+
let learnText = `📚 **Lernthemen:**\n\n`;
|
|
214
|
+
learnText += topics.join('\n') + '\n\n';
|
|
215
|
+
learnText += '💡 Verwende: !learn <thema> für Details';
|
|
216
|
+
|
|
217
|
+
return msg.reply(learnText);
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
const topic = args.join(' ').toLowerCase();
|
|
221
|
+
const resources = {
|
|
222
|
+
'javascript': '📚 **JavaScript lernen:**\n\n• MDN Web Docs\n• JavaScript.info\n• FreeCodeCamp\n• Codecademy\n\n💡 Starte mit Variablen, Funktionen und DOM-Manipulation!',
|
|
223
|
+
'python': '🐍 **Python lernen:**\n\n• Python.org Tutorial\n• Automate the Boring Stuff\n• Python Crash Course\n• Codecademy Python\n\n💡 Perfekt für Anfänger und Automatisierung!',
|
|
224
|
+
'react': '⚛️ **React lernen:**\n\n• React Docs\n• React Tutorial\n• Scrimba React Course\n• Full Stack Open\n\n💡 Lerne erst JavaScript, dann React!',
|
|
225
|
+
'node': '🟢 **Node.js lernen:**\n\n• Node.js Docs\n• The Node.js Handbook\n• Express.js Guide\n• NPM Packages\n\n💡 Ideal für Backend-Entwicklung!'
|
|
226
|
+
};
|
|
227
|
+
|
|
228
|
+
const resource = resources[topic] || `📚 Ressourcen für "${topic}" nicht gefunden. Versuche: !learn ohne Parameter für verfügbare Themen.`;
|
|
229
|
+
|
|
230
|
+
await msg.reply(resource);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async handleFact(msg, args) {
|
|
234
|
+
const fact = this.getRandomFact();
|
|
235
|
+
|
|
236
|
+
await msg.reply(`💡 **Wusstest du schon?**\n\n${fact}`);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async handleStudy(msg, args) {
|
|
240
|
+
const userId = msg.getSender();
|
|
241
|
+
|
|
242
|
+
if (args.length === 0) {
|
|
243
|
+
const studyTime = this.client.storage.read.from('education').get(`${userId}.studyTime`) || 0;
|
|
244
|
+
const studyDays = this.client.storage.read.from('education').get(`${userId}.studyDays`) || 0;
|
|
245
|
+
|
|
246
|
+
let studyText = `📊 **Deine Lernstatistiken:**\n\n`;
|
|
247
|
+
studyText += `⏱️ Gesamte Lernzeit: ${Math.floor(studyTime / 60)} Minuten\n`;
|
|
248
|
+
studyText += `📅 Lerntage: ${studyDays}\n\n`;
|
|
249
|
+
studyText += `💡 Verwende !study start um eine Lernsession zu beginnen`;
|
|
250
|
+
|
|
251
|
+
return msg.reply(studyText);
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
const action = args[0].toLowerCase();
|
|
255
|
+
|
|
256
|
+
if (action === 'start') {
|
|
257
|
+
this.client.storage.write.in('education').set(`${userId}.sessionStart`, Date.now());
|
|
258
|
+
await msg.reply('📚 **Lernsession gestartet!**\n\n⏱️ Viel Erfolg beim Lernen!\n💡 Verwende !study stop um die Session zu beenden');
|
|
259
|
+
} else if (action === 'stop') {
|
|
260
|
+
const sessionStart = this.client.storage.read.from('education').get(`${userId}.sessionStart`);
|
|
261
|
+
|
|
262
|
+
if (!sessionStart) {
|
|
263
|
+
return msg.reply('❌ Keine aktive Lernsession gefunden!');
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
const sessionTime = Math.floor((Date.now() - sessionStart) / 1000 / 60); // Minuten
|
|
267
|
+
|
|
268
|
+
this.client.storage.write.in('education').increment(`${userId}.studyTime`, sessionTime);
|
|
269
|
+
this.client.storage.write.in('education').increment(`${userId}.studyDays`, 1);
|
|
270
|
+
this.client.storage.delete.from('education').key(`${userId}.sessionStart`);
|
|
271
|
+
|
|
272
|
+
await msg.reply(`✅ **Lernsession beendet!**\n\n⏱️ Dauer: ${sessionTime} Minuten\n🎉 Gut gemacht!`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Games Plugin",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Spiele-System mit Quiz, Würfel, RPS und mehr",
|
|
5
|
+
"author": "WAEngine",
|
|
6
|
+
"commands": [
|
|
7
|
+
"dice",
|
|
8
|
+
"flip",
|
|
9
|
+
"rps",
|
|
10
|
+
"quiz",
|
|
11
|
+
"answer",
|
|
12
|
+
"number",
|
|
13
|
+
"gamestats",
|
|
14
|
+
"gameleaderboard"
|
|
15
|
+
],
|
|
16
|
+
"permissions": {
|
|
17
|
+
"dice": "all",
|
|
18
|
+
"flip": "all",
|
|
19
|
+
"rps": "all",
|
|
20
|
+
"quiz": "all",
|
|
21
|
+
"answer": "all",
|
|
22
|
+
"number": "all",
|
|
23
|
+
"gamestats": "all",
|
|
24
|
+
"gameleaderboard": "all"
|
|
25
|
+
},
|
|
26
|
+
"settings": {
|
|
27
|
+
"maxDiceSides": 100,
|
|
28
|
+
"quizTimeout": 60000,
|
|
29
|
+
"numberGuessRange": {
|
|
30
|
+
"min": 1,
|
|
31
|
+
"max": 100
|
|
32
|
+
},
|
|
33
|
+
"leaderboardLimit": 10
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
// 🎲 Games Plugin
|
|
2
|
+
export default class GamesPlugin {
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
this.name = 'games-plugin';
|
|
6
|
+
this.version = '1.0.0';
|
|
7
|
+
this.description = 'Spiele-System mit Quiz, Würfel, RPS und mehr';
|
|
8
|
+
|
|
9
|
+
this.quizQuestions = [
|
|
10
|
+
{ question: 'Was ist die Hauptstadt von Deutschland?', answers: ['Berlin', 'München', 'Hamburg', 'Köln'], correct: 0 },
|
|
11
|
+
{ question: 'Welches Jahr war die erste Mondlandung?', answers: ['1967', '1969', '1971', '1973'], correct: 1 },
|
|
12
|
+
{ question: 'Wer hat JavaScript erfunden?', answers: ['Bill Gates', 'Steve Jobs', 'Brendan Eich', 'Mark Zuckerberg'], correct: 2 },
|
|
13
|
+
{ question: 'Was ist 15 × 8?', answers: ['110', '120', '130', '140'], correct: 1 },
|
|
14
|
+
{ question: 'Welcher Planet ist der größte?', answers: ['Saturn', 'Jupiter', 'Neptun', 'Uranus'], correct: 1 }
|
|
15
|
+
];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
rollDice(sides = 6) {
|
|
19
|
+
return Math.floor(Math.random() * sides) + 1;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
flipCoin() {
|
|
23
|
+
return Math.random() < 0.5 ? 'Kopf' : 'Zahl';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
playRPS(playerChoice) {
|
|
27
|
+
const choices = ['rock', 'paper', 'scissors'];
|
|
28
|
+
const botChoice = choices[Math.floor(Math.random() * 3)];
|
|
29
|
+
|
|
30
|
+
const wins = {
|
|
31
|
+
rock: 'scissors',
|
|
32
|
+
paper: 'rock',
|
|
33
|
+
scissors: 'paper'
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
let result;
|
|
37
|
+
if (playerChoice === botChoice) {
|
|
38
|
+
result = 'tie';
|
|
39
|
+
} else if (wins[playerChoice] === botChoice) {
|
|
40
|
+
result = 'win';
|
|
41
|
+
} else {
|
|
42
|
+
result = 'lose';
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return { playerChoice, botChoice, result };
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
getRandomQuestion() {
|
|
49
|
+
return this.quizQuestions[Math.floor(Math.random() * this.quizQuestions.length)];
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
async startQuiz(userId, groupId) {
|
|
53
|
+
const question = this.getRandomQuestion();
|
|
54
|
+
const quizId = Date.now().toString();
|
|
55
|
+
|
|
56
|
+
this.client.storage.write.in('games').set(`quiz.${quizId}`, {
|
|
57
|
+
question: question.question,
|
|
58
|
+
answers: question.answers,
|
|
59
|
+
correct: question.correct,
|
|
60
|
+
userId,
|
|
61
|
+
groupId,
|
|
62
|
+
startTime: Date.now(),
|
|
63
|
+
answered: false
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
return { quizId, question };
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
async answerQuiz(quizId, answerIndex, userId) {
|
|
70
|
+
const quiz = this.client.storage.read.from('games').get(`quiz.${quizId}`);
|
|
71
|
+
|
|
72
|
+
if (!quiz || quiz.answered) {
|
|
73
|
+
return { success: false, error: 'Quiz nicht gefunden oder bereits beantwortet' };
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
if (userId !== quiz.userId) {
|
|
77
|
+
return { success: false, error: 'Das ist nicht dein Quiz!' };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const isCorrect = answerIndex === quiz.correct;
|
|
81
|
+
const timeTaken = Date.now() - quiz.startTime;
|
|
82
|
+
|
|
83
|
+
this.client.storage.write.in('games').set(`quiz.${quizId}.answered`, true);
|
|
84
|
+
|
|
85
|
+
this.client.storage.write.in('games').increment(`stats.${userId}.quizzes`, 1);
|
|
86
|
+
if (isCorrect) {
|
|
87
|
+
this.client.storage.write.in('games').increment(`stats.${userId}.correct`, 1);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
success: true,
|
|
92
|
+
correct: isCorrect,
|
|
93
|
+
correctAnswer: quiz.answers[quiz.correct],
|
|
94
|
+
timeTaken: Math.round(timeTaken / 1000)
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async getLeaderboard(game = 'quiz') {
|
|
99
|
+
const stats = this.client.storage.read.from('games').get('stats') || {};
|
|
100
|
+
const leaderboard = [];
|
|
101
|
+
|
|
102
|
+
Object.entries(stats).forEach(([userId, userStats]) => {
|
|
103
|
+
if (userStats[game]) {
|
|
104
|
+
leaderboard.push({
|
|
105
|
+
userId,
|
|
106
|
+
score: userStats.correct || 0,
|
|
107
|
+
total: userStats.quizzes || 0,
|
|
108
|
+
percentage: userStats.quizzes ? Math.round((userStats.correct / userStats.quizzes) * 100) : 0
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
leaderboard.sort((a, b) => b.score - a.score);
|
|
114
|
+
return leaderboard.slice(0, 10);
|
|
115
|
+
}
|
|
116
|
+
getCommands() {
|
|
117
|
+
return {
|
|
118
|
+
'dice': this.handleDice.bind(this),
|
|
119
|
+
'flip': this.handleFlip.bind(this),
|
|
120
|
+
'rps': this.handleRPS.bind(this),
|
|
121
|
+
'quiz': this.handleQuiz.bind(this),
|
|
122
|
+
'answer': this.handleAnswer.bind(this),
|
|
123
|
+
'gamestats': this.handleGameStats.bind(this),
|
|
124
|
+
'gameleaderboard': this.handleGameLeaderboard.bind(this),
|
|
125
|
+
'number': this.handleNumberGuess.bind(this)
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
async handleDice(msg, args) {
|
|
130
|
+
const sides = parseInt(args[0]) || 6;
|
|
131
|
+
if (sides < 2 || sides > 100) {
|
|
132
|
+
return msg.reply('❌ Würfel muss zwischen 2 und 100 Seiten haben!');
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const result = this.rollDice(sides);
|
|
136
|
+
await msg.reply(`🎲 **Würfel Ergebnis:**\n\n🎯 ${result} (von ${sides})`);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async handleFlip(msg, args) {
|
|
140
|
+
const result = this.flipCoin();
|
|
141
|
+
const emoji = result === 'Kopf' ? '🪙' : '💰';
|
|
142
|
+
|
|
143
|
+
await msg.reply(`${emoji} **Münzwurf:**\n\n🎯 ${result}!`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async handleRPS(msg, args) {
|
|
147
|
+
if (args.length === 0) {
|
|
148
|
+
return msg.reply('❌ Verwendung: !rps <rock/paper/scissors>\n\n🪨 Rock\n📄 Paper\n✂️ Scissors');
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const playerChoice = args[0].toLowerCase();
|
|
152
|
+
const validChoices = ['rock', 'paper', 'scissors'];
|
|
153
|
+
|
|
154
|
+
if (!validChoices.includes(playerChoice)) {
|
|
155
|
+
return msg.reply('❌ Ungültige Wahl! Verwende: rock, paper oder scissors');
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const game = this.playRPS(playerChoice);
|
|
159
|
+
const emojis = { rock: '🪨', paper: '📄', scissors: '✂️' };
|
|
160
|
+
|
|
161
|
+
let resultText = `🎮 **Schere-Stein-Papier**\n\n`;
|
|
162
|
+
resultText += `👤 Du: ${emojis[game.playerChoice]}\n`;
|
|
163
|
+
resultText += `🤖 Bot: ${emojis[game.botChoice]}\n\n`;
|
|
164
|
+
|
|
165
|
+
if (game.result === 'win') {
|
|
166
|
+
resultText += '🎉 **Du gewinnst!**';
|
|
167
|
+
} else if (game.result === 'lose') {
|
|
168
|
+
resultText += '😔 **Du verlierst!**';
|
|
169
|
+
} else {
|
|
170
|
+
resultText += '🤝 **Unentschieden!**';
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
await msg.reply(resultText);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
async handleQuiz(msg, args) {
|
|
177
|
+
const userId = msg.getSender();
|
|
178
|
+
const groupId = msg.from;
|
|
179
|
+
|
|
180
|
+
const { quizId, question } = await this.startQuiz(userId, groupId);
|
|
181
|
+
|
|
182
|
+
let quizText = `🧠 **Quiz Zeit!**\n\n`;
|
|
183
|
+
quizText += `❓ ${question.question}\n\n`;
|
|
184
|
+
|
|
185
|
+
question.answers.forEach((answer, index) => {
|
|
186
|
+
quizText += `${index + 1}. ${answer}\n`;
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
quizText += `\n💡 Antworte mit: !answer ${quizId} <1-4>`;
|
|
190
|
+
|
|
191
|
+
await msg.reply(quizText);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
async handleAnswer(msg, args) {
|
|
195
|
+
if (args.length < 2) {
|
|
196
|
+
return msg.reply('❌ Verwendung: !answer <quiz-id> <antwort-nummer>');
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
const quizId = args[0];
|
|
200
|
+
const answerIndex = parseInt(args[1]) - 1;
|
|
201
|
+
const userId = msg.getSender();
|
|
202
|
+
|
|
203
|
+
if (isNaN(answerIndex) || answerIndex < 0 || answerIndex > 3) {
|
|
204
|
+
return msg.reply('❌ Antwort muss zwischen 1 und 4 sein!');
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
const result = await this.answerQuiz(quizId, answerIndex, userId);
|
|
208
|
+
|
|
209
|
+
if (!result.success) {
|
|
210
|
+
return msg.reply(`❌ ${result.error}`);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
let resultText = `📊 **Quiz Ergebnis:**\n\n`;
|
|
214
|
+
|
|
215
|
+
if (result.correct) {
|
|
216
|
+
resultText += `✅ **Richtig!**\n`;
|
|
217
|
+
} else {
|
|
218
|
+
resultText += `❌ **Falsch!**\n`;
|
|
219
|
+
resultText += `💡 Richtige Antwort: ${result.correctAnswer}\n`;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
resultText += `⏱️ Zeit: ${result.timeTaken}s`;
|
|
223
|
+
|
|
224
|
+
await msg.reply(resultText);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
async handleGameStats(msg, args) {
|
|
228
|
+
const userId = msg.getSender();
|
|
229
|
+
const stats = this.client.storage.read.from('games').get(`stats.${userId}`) || {};
|
|
230
|
+
|
|
231
|
+
const quizzes = stats.quizzes || 0;
|
|
232
|
+
const correct = stats.correct || 0;
|
|
233
|
+
const percentage = quizzes ? Math.round((correct / quizzes) * 100) : 0;
|
|
234
|
+
|
|
235
|
+
let statsText = `📊 **Deine Game Stats:**\n\n`;
|
|
236
|
+
statsText += `🧠 Quiz gespielt: ${quizzes}\n`;
|
|
237
|
+
statsText += `✅ Richtige Antworten: ${correct}\n`;
|
|
238
|
+
statsText += `📈 Erfolgsquote: ${percentage}%`;
|
|
239
|
+
|
|
240
|
+
await msg.reply(statsText);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async handleGameLeaderboard(msg, args) {
|
|
244
|
+
const leaderboard = await this.getLeaderboard('quiz');
|
|
245
|
+
|
|
246
|
+
if (leaderboard.length === 0) {
|
|
247
|
+
return msg.reply('📊 **Leaderboard ist leer!**\n\n🎮 Spiele !quiz um auf die Liste zu kommen');
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
let lbText = '🏆 **Quiz Leaderboard**\n\n';
|
|
251
|
+
|
|
252
|
+
leaderboard.forEach((entry, index) => {
|
|
253
|
+
const medal = index === 0 ? '🥇' : index === 1 ? '🥈' : index === 2 ? '🥉' : `${index + 1}.`;
|
|
254
|
+
lbText += `${medal} @${entry.userId.split('@')[0]}\n`;
|
|
255
|
+
lbText += `✅ ${entry.score}/${entry.total} (${entry.percentage}%)\n\n`;
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
await msg.reply(lbText);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
async handleNumberGuess(msg, args) {
|
|
262
|
+
const userId = msg.getSender();
|
|
263
|
+
const activeGame = this.client.storage.read.from('games').get(`number.${userId}`);
|
|
264
|
+
|
|
265
|
+
if (!activeGame) {
|
|
266
|
+
// Neues Spiel starten
|
|
267
|
+
const number = Math.floor(Math.random() * 100) + 1;
|
|
268
|
+
this.client.storage.write.in('games').set(`number.${userId}`, {
|
|
269
|
+
number,
|
|
270
|
+
attempts: 0,
|
|
271
|
+
startTime: Date.now()
|
|
272
|
+
});
|
|
273
|
+
|
|
274
|
+
return msg.reply('🔢 **Zahlenraten gestartet!**\n\n🎯 Ich denke an eine Zahl zwischen 1 und 100\n💡 Rate mit: !number <zahl>');
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
if (args.length === 0) {
|
|
278
|
+
return msg.reply('❌ Gib eine Zahl zwischen 1 und 100 ein!');
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
const guess = parseInt(args[0]);
|
|
282
|
+
if (isNaN(guess) || guess < 1 || guess > 100) {
|
|
283
|
+
return msg.reply('❌ Zahl muss zwischen 1 und 100 sein!');
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
activeGame.attempts++;
|
|
287
|
+
this.client.storage.write.in('games').set(`number.${userId}.attempts`, activeGame.attempts);
|
|
288
|
+
|
|
289
|
+
if (guess === activeGame.number) {
|
|
290
|
+
const timeTaken = Math.round((Date.now() - activeGame.startTime) / 1000);
|
|
291
|
+
this.client.storage.delete.from('games').key(`number.${userId}`);
|
|
292
|
+
|
|
293
|
+
await msg.reply(`🎉 **Richtig geraten!**\n\n🎯 Die Zahl war: ${activeGame.number}\n🔢 Versuche: ${activeGame.attempts}\n⏱️ Zeit: ${timeTaken}s`);
|
|
294
|
+
} else if (guess < activeGame.number) {
|
|
295
|
+
await msg.reply(`📈 **Zu niedrig!**\n\n🔢 Versuch ${activeGame.attempts}: ${guess}\n💡 Die Zahl ist höher`);
|
|
296
|
+
} else {
|
|
297
|
+
await msg.reply(`📉 **Zu hoch!**\n\n🔢 Versuch ${activeGame.attempts}: ${guess}\n💡 Die Zahl ist niedriger`);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "moderation-plugin",
|
|
3
|
+
"displayName": "Moderation Plugin",
|
|
4
|
+
"version": "1.0.0",
|
|
5
|
+
"description": "Erweiterte Moderation mit Auto-Mod, Spam-Schutz und Admin-Tools",
|
|
6
|
+
"author": "WAEngine",
|
|
7
|
+
"category": "moderation",
|
|
8
|
+
"permissions": [
|
|
9
|
+
"admin_only",
|
|
10
|
+
"group_management",
|
|
11
|
+
"message_deletion"
|
|
12
|
+
],
|
|
13
|
+
"commands": [
|
|
14
|
+
{
|
|
15
|
+
"name": "warn",
|
|
16
|
+
"description": "Warnung an User vergeben",
|
|
17
|
+
"usage": "!warn @user [grund]",
|
|
18
|
+
"adminOnly": true
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "unwarn",
|
|
22
|
+
"description": "Warnung von User entfernen",
|
|
23
|
+
"usage": "!unwarn @user",
|
|
24
|
+
"adminOnly": true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"name": "warnings",
|
|
28
|
+
"description": "Warnungen anzeigen",
|
|
29
|
+
"usage": "!warnings [@user]",
|
|
30
|
+
"adminOnly": false
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "kick",
|
|
34
|
+
"description": "User aus Gruppe entfernen",
|
|
35
|
+
"usage": "!kick @user [grund]",
|
|
36
|
+
"adminOnly": true
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"name": "automod",
|
|
40
|
+
"description": "Auto-Moderation verwalten",
|
|
41
|
+
"usage": "!automod [on/off]",
|
|
42
|
+
"adminOnly": true
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"name": "modstats",
|
|
46
|
+
"description": "Moderations-Statistiken",
|
|
47
|
+
"usage": "!modstats",
|
|
48
|
+
"adminOnly": false
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
"name": "rules",
|
|
52
|
+
"description": "Gruppenregeln anzeigen",
|
|
53
|
+
"usage": "!rules",
|
|
54
|
+
"adminOnly": false
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
"name": "setrules",
|
|
58
|
+
"description": "Gruppenregeln festlegen",
|
|
59
|
+
"usage": "!setrules <regel1> | <regel2>",
|
|
60
|
+
"adminOnly": true
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"name": "purge",
|
|
64
|
+
"description": "Nachrichten löschen",
|
|
65
|
+
"usage": "!purge <anzahl>",
|
|
66
|
+
"adminOnly": true
|
|
67
|
+
}
|
|
68
|
+
],
|
|
69
|
+
"settings": {
|
|
70
|
+
"autoMod": {
|
|
71
|
+
"maxMessages": 5,
|
|
72
|
+
"timeWindow": 10000,
|
|
73
|
+
"banWords": ["spam", "werbung", "fake", "scam"],
|
|
74
|
+
"maxCapsPercent": 70,
|
|
75
|
+
"maxEmojis": 10
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
"dependencies": [],
|
|
79
|
+
"storage": [
|
|
80
|
+
"warnings",
|
|
81
|
+
"autoMod",
|
|
82
|
+
"rules",
|
|
83
|
+
"bans",
|
|
84
|
+
"mutes"
|
|
85
|
+
]
|
|
86
|
+
}
|