diff --git a/agb.html b/agb.html
new file mode 100644
index 0000000..be3ec36
--- /dev/null
+++ b/agb.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+ Nutzungsbedingungen (AGB) - ManagerX
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/datenschutz.html b/datenschutz.html
new file mode 100644
index 0000000..e8a4750
--- /dev/null
+++ b/datenschutz.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+ Datenschutz - ManagerX
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/bot/embeds.py b/examples/bot/embeds.py
new file mode 100644
index 0000000..ac19583
--- /dev/null
+++ b/examples/bot/embeds.py
@@ -0,0 +1,35 @@
+# How Works Embeds?
+
+import discord
+from discord import slash_command
+import ezcord
+
+class Embeds(ezcord.Cog):
+ def __init__(self, bot):
+ self.bot = bot
+
+ @slash_command(name="embed", description="Embeds")
+ async def embed(self, ctx):
+ embed = discord.Embed(
+ title="Hello World!", # Embed Title
+ description="This is a embed", # Embed Description
+ color=discord.Color.blue() # Embed Color
+ )
+ embed.set_author(
+ name="Embeds", # Embed Author Name
+ icon_url=self.bot.user.avatar.url # Embed Author Icon
+ )
+ embed.set_footer(
+ text="Embeds", # Embed Footer Text
+ icon_url=self.bot.user.avatar.url # Embed Footer Icon
+ )
+ embed.set_thumbnail(
+ url=self.bot.user.avatar.url # Embed Thumbnail
+ )
+ embed.set_image(
+ url=self.bot.user.avatar.url # Embed Image
+ )
+ await ctx.respond(embed=embed)
+
+def setup(bot):
+ bot.add_cog(Embeds(bot)) # Add the Cog to the Bot
\ No newline at end of file
diff --git a/impressum.html b/impressum.html
new file mode 100644
index 0000000..2284dec
--- /dev/null
+++ b/impressum.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+ Impressum - ManagerX
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/api/dashboard/routes.py b/src/api/dashboard/routes.py
index 03edf98..2ed0e7a 100644
--- a/src/api/dashboard/routes.py
+++ b/src/api/dashboard/routes.py
@@ -6,7 +6,7 @@
# Wir erstellen einen Router, den wir später in die Haupt-App einbinden
router = APIRouter(
- prefix="/api/v1/managerx",
+ prefix="/v1/managerx",
tags=["dashboard"]
)
diff --git a/src/bot/cogs/fun/4gewinnt.py b/src/bot/cogs/fun/4gewinnt.py
index 9af9f1c..1fd08a4 100644
--- a/src/bot/cogs/fun/4gewinnt.py
+++ b/src/bot/cogs/fun/4gewinnt.py
@@ -19,6 +19,8 @@
ROWS = 6
COLUMNS = 7
DEFAULT_TIMEOUT = 300 # 5 Minuten
+ACTIVE_AI_GAMES = 0
+MAX_AI_GAMES = 5
# Improved difficulty levels with better depth and strategy
DIFFICULTY_CONFIG = {
@@ -489,7 +491,7 @@ async def callback(self, interaction: discord.Interaction):
)
class Connect4View(View):
- def __init__(self, player1, player2, messages, is_ai_mode=False, difficulty="medium"):
+ def __init__(self, player1, player2, messages, is_ai_mode=False, difficulty="medium", on_cleanup=None):
super().__init__(timeout=DEFAULT_TIMEOUT)
self.player1 = player1
self.player2 = player2
@@ -504,6 +506,8 @@ def __init__(self, player1, player2, messages, is_ai_mode=False, difficulty="med
self.move_count = 0
self.move_history: List[tuple] = []
self.game_ended = False
+ self.on_cleanup = on_cleanup
+ self.cleaned_up = False
for col in range(COLUMNS):
self.add_item(Connect4Button(col, self))
@@ -673,6 +677,10 @@ async def end_game(self, interaction: discord.Interaction, winner: bool, board_s
else:
await interaction.response.edit_message(embed=embed, view=self)
+ if self.on_cleanup and not self.cleaned_up:
+ self.on_cleanup()
+ self.cleaned_up = True
+
self.stop()
async def on_timeout(self):
@@ -680,6 +688,10 @@ async def on_timeout(self):
self.game_ended = True
for child in self.children:
child.disabled = True
+
+ if self.on_cleanup and not self.cleaned_up:
+ self.on_cleanup()
+ self.cleaned_up = True
# ───────────────────────────────────────────────
# >> Cog
@@ -712,8 +724,22 @@ async def connect4(
# AI mode
if opponent is None:
+ global ACTIVE_AI_GAMES
+ if ACTIVE_AI_GAMES >= MAX_AI_GAMES:
+ await ctx.respond(
+ "Tut uns leid, unsere KI wird gerade stark beansprucht. Bitte warte einen Moment damit unsere CPU last nicht in das Unendliche geht",
+ ephemeral=True
+ )
+ return
+
+ ACTIVE_AI_GAMES += 1
+
+ def cleanup():
+ global ACTIVE_AI_GAMES
+ ACTIVE_AI_GAMES -= 1
+
ai_user = ctx.guild.me
- view = Connect4View(ctx.author, ai_user, messages, is_ai_mode=True, difficulty=difficulty)
+ view = Connect4View(ctx.author, ai_user, messages, is_ai_mode=True, difficulty=difficulty, on_cleanup=cleanup)
difficulty_info = DIFFICULTY_CONFIG.get(difficulty, DIFFICULTY_CONFIG["medium"])
difficulty_emoji = {"easy": "😊", "medium": "🤔", "hard": "😈"}
diff --git a/src/bot/cogs/fun/tictactoe.py b/src/bot/cogs/fun/tictactoe.py
index 8d77f7f..b9fd25b 100644
--- a/src/bot/cogs/fun/tictactoe.py
+++ b/src/bot/cogs/fun/tictactoe.py
@@ -16,6 +16,8 @@
# >> Constants
# ───────────────────────────────────────────────
DEFAULT_TIMEOUT = 120
+ACTIVE_AI_GAMES = 0
+MAX_AI_GAMES = 5
DIFFICULTY_CONFIG = {
"easy": {
@@ -344,7 +346,7 @@ async def callback(self, interaction: discord.Interaction):
await interaction.response.edit_message(content=next_turn_msg, view=view)
class TicTacToeView(View):
- def __init__(self, player1, player2, messages, is_ai_mode=False, difficulty="medium"):
+ def __init__(self, player1, player2, messages, is_ai_mode=False, difficulty="medium", on_cleanup=None):
super().__init__(timeout=DEFAULT_TIMEOUT)
self.player1 = player1
self.player2 = player2
@@ -356,6 +358,8 @@ def __init__(self, player1, player2, messages, is_ai_mode=False, difficulty="med
self.difficulty = difficulty
self.ai = TicTacToeAI(difficulty) if is_ai_mode else None
self.game_ended = False
+ self.on_cleanup = on_cleanup
+ self.cleaned_up = False
for x in range(3):
for y in range(3):
@@ -477,6 +481,10 @@ async def end_game(self, interaction: discord.Interaction, winner: Optional[str]
else:
await interaction.response.edit_message(embed=embed, view=self)
+ if self.on_cleanup and not self.cleaned_up:
+ self.on_cleanup()
+ self.cleaned_up = True
+
self.stop()
async def on_timeout(self):
@@ -484,6 +492,10 @@ async def on_timeout(self):
self.game_ended = True
for child in self.children:
child.disabled = True
+
+ if self.on_cleanup and not self.cleaned_up:
+ self.on_cleanup()
+ self.cleaned_up = True
# ───────────────────────────────────────────────
# >> Cog
@@ -514,8 +526,22 @@ async def tictactoe(
# AI mode
if opponent is None:
+ global ACTIVE_AI_GAMES
+ if ACTIVE_AI_GAMES >= MAX_AI_GAMES:
+ await ctx.respond(
+ "Tut uns leid, unsere KI wird gerade stark beansprucht. Bitte warte einen Moment damit unsere CPU last nicht in das Unendliche geht",
+ ephemeral=True
+ )
+ return
+
+ ACTIVE_AI_GAMES += 1
+
+ def cleanup():
+ global ACTIVE_AI_GAMES
+ ACTIVE_AI_GAMES -= 1
+
ai_user = ctx.guild.me
- view = TicTacToeView(ctx.author, ai_user, messages, is_ai_mode=True, difficulty=difficulty)
+ view = TicTacToeView(ctx.author, ai_user, messages, is_ai_mode=True, difficulty=difficulty, on_cleanup=cleanup)
difficulty_info = DIFFICULTY_CONFIG.get(difficulty, DIFFICULTY_CONFIG["medium"])
difficulty_emoji = {"easy": "😊", "medium": "🤔", "hard": "😈"}
diff --git a/src/web/entries/agb.tsx b/src/web/entries/agb.tsx
new file mode 100644
index 0000000..b9482f3
--- /dev/null
+++ b/src/web/entries/agb.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+import { createRoot } from "react-dom/client";
+import { BrowserRouter } from "react-router-dom";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import Nutzungsbedingungen from "../pages/Nutzungsbedingungen";
+import "../index.css";
+
+const queryClient = new QueryClient();
+
+createRoot(document.getElementById("root")!).render(
+
+
+
+
+
+
+
+);
diff --git a/src/web/entries/datenschutz.tsx b/src/web/entries/datenschutz.tsx
new file mode 100644
index 0000000..5555d34
--- /dev/null
+++ b/src/web/entries/datenschutz.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+import { createRoot } from "react-dom/client";
+import { BrowserRouter } from "react-router-dom";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import Datenschutz from "../pages/Datenschutz";
+import "../index.css";
+
+const queryClient = new QueryClient();
+
+createRoot(document.getElementById("root")!).render(
+
+
+
+
+
+
+
+);
diff --git a/src/web/entries/impressum.tsx b/src/web/entries/impressum.tsx
new file mode 100644
index 0000000..1e5137e
--- /dev/null
+++ b/src/web/entries/impressum.tsx
@@ -0,0 +1,18 @@
+import React from "react";
+import { createRoot } from "react-dom/client";
+import { BrowserRouter } from "react-router-dom";
+import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
+import Impressum from "../pages/Impressum";
+import "../index.css";
+
+const queryClient = new QueryClient();
+
+createRoot(document.getElementById("root")!).render(
+
+
+
+
+
+
+
+);
diff --git a/vite.config.ts b/vite.config.ts
index 81cfebb..4027700 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -28,5 +28,13 @@ export default defineConfig(({ mode }) => ({
// Optimierung für sauberen Code
minify: "esbuild",
reportCompressedSize: false,
+ rollupOptions: {
+ input: {
+ main: path.resolve(__dirname, "index.html"),
+ datenschutz: path.resolve(__dirname, "datenschutz.html"),
+ impressum: path.resolve(__dirname, "impressum.html"),
+ agb: path.resolve(__dirname, "agb.html"),
+ },
+ },
},
}));
\ No newline at end of file