From 47d44643c3f3a5f5bf1ef896c959d844f4163820 Mon Sep 17 00:00:00 2001
From: DerGrumpf
Date: Wed, 24 Jul 2024 14:46:46 +0200
Subject: [PATCH] init
---
.gitignore | 2 +
bot/.dockerignore | 6 ++
bot/.env | 7 ++
bot/Dockerfile | 8 ++
bot/bot.py | 35 +++++++
bot/cogs/minecraft.py | 185 ++++++++++++++++++++++++++++++++++++
bot/cogs/user_management.py | 12 +++
bot/compose.yml | 16 ++++
bot/requirements.txt | 14 +++
bot/test.py | 8 ++
compose.yml | 5 +
pgadmin4/.env | 3 +
pgadmin4/compose.yml | 19 ++++
pgadmin4/server.json | 13 +++
postgres/.env | 2 +
postgres/compose.yml | 18 ++++
16 files changed, 353 insertions(+)
create mode 100644 bot/.dockerignore
create mode 100644 bot/.env
create mode 100644 bot/Dockerfile
create mode 100644 bot/bot.py
create mode 100644 bot/cogs/minecraft.py
create mode 100644 bot/cogs/user_management.py
create mode 100644 bot/compose.yml
create mode 100644 bot/requirements.txt
create mode 100644 bot/test.py
create mode 100644 compose.yml
create mode 100644 pgadmin4/.env
create mode 100644 pgadmin4/compose.yml
create mode 100644 pgadmin4/server.json
create mode 100644 postgres/.env
create mode 100644 postgres/compose.yml
diff --git a/.gitignore b/.gitignore
index 0d950e3..06efbe0 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,3 +2,5 @@
*/__pycache__/
*/data/
+*.pyc
+.DS_Store
diff --git a/bot/.dockerignore b/bot/.dockerignore
new file mode 100644
index 0000000..2aed3fe
--- /dev/null
+++ b/bot/.dockerignore
@@ -0,0 +1,6 @@
+env/
+__pycache__
+test.py
+Dockerfile
+compose.yml
+data/
diff --git a/bot/.env b/bot/.env
new file mode 100644
index 0000000..706b0f3
--- /dev/null
+++ b/bot/.env
@@ -0,0 +1,7 @@
+# Discord Stuff
+TOKEN = MTI1MDc1MjY1OTY1NzQ1NzY3NA.G9NOoM.6oIosKzw35aJz3QZZ-dkbqDpIO3JxvOeropvqk
+
+# RCON
+RCON_SERVER = 100.80.35.55
+RCON_PASS = garde-studios
+RCON_PORT = 31066
diff --git a/bot/Dockerfile b/bot/Dockerfile
new file mode 100644
index 0000000..c21f683
--- /dev/null
+++ b/bot/Dockerfile
@@ -0,0 +1,8 @@
+FROM python:3.12.4
+
+ADD requirements.txt .
+RUN pip install --upgrade pip
+RUN pip install -r requirements.txt
+ADD . .
+
+CMD ["python", "main.py"]
diff --git a/bot/bot.py b/bot/bot.py
new file mode 100644
index 0000000..c929153
--- /dev/null
+++ b/bot/bot.py
@@ -0,0 +1,35 @@
+import discord
+from discord.ext import commands
+
+from cogs.minecraft import Minecraft
+from cogs.user_management import UserManager
+
+# Setup Environment
+import os
+from dotenv import load_dotenv
+load_dotenv()
+
+# Discord Stuff
+TOKEN = os.environ['TOKEN']
+
+# Server Stuff
+RCON_SERVER = os.environ['RCON_SERVER']
+RCON_PASS = os.environ['RCON_PASS']
+RCON_PORT = int(os.environ['RCON_PORT'])
+
+# Setup Basic Permission
+intents = discord.Intents.default()
+intents.message_content = True
+
+# Define the actual Bot
+bot = commands.Bot(command_prefix='-', intents=intents)
+
+async def setup():
+ await bot.add_cog(Minecraft(bot, RCON_SERVER, RCON_PASS, RCON_PORT))
+ await bot.add_cog(UserManager(bot))
+
+@bot.event
+async def on_ready():
+ await setup()
+
+bot.run(TOKEN)
diff --git a/bot/cogs/minecraft.py b/bot/cogs/minecraft.py
new file mode 100644
index 0000000..db10c72
--- /dev/null
+++ b/bot/cogs/minecraft.py
@@ -0,0 +1,185 @@
+import discord
+from discord.ext import commands
+from mcrcon import MCRcon
+import enum
+from statemachine import StateMachine, State
+from statemachine.states import States
+
+class BorderWarsSession(StateMachine):
+ "A workflow maschine for managing InGame States"
+ Nothing = State(initial=True)
+ Initialization = State()
+ Safe = State()
+ Fight = State()
+ SuddenDeath = State()
+ End = State()
+
+ init_game = Nothing.to(Initialization)
+ start_game = Initialization.to(Safe)
+ start_fight = Safe.to(Fight)
+ start_last_round = Fight.to(SuddenDeath)
+ end_game = Fight.to(End) | SuddenDeath.to(End)
+
+ abort = Initialization.to(Nothing) | Safe.to(Nothing) | Fight.to(Nothing) | SuddenDeath.to(Nothing) | End.to(Nothing) | Nothing.to(Nothing)
+ reset = End.to(Initialization)
+
+ @Initialization.enter
+ def initialization(self) -> list:
+
+
+ @Safe.enter
+ def safe(self) -> list:
+ # Chat countdown
+ return [
+ '''/title @a subtitle ["",{"text":"bei ","color":"blue"},{"text":"BORDER WARS!","bold":true,"color":"red"}]''',
+ '''/title @a title {"text":"Viel Glück!","bold":true,"color":"blue"}''',
+ "playsound minecraft:entity.wither.spawn ambient @a 0 64 080",
+ "/worldborder set 1000",
+ "/gamerule keepInventory true"
+ ]
+
+ @Fight.enter
+ def fight(self) -> list:
+ # Timer Starten
+ return [
+ '''/title @a subtitle {"text":"ÜBERLEBEN!","bold":true,"color":"red"}''',
+ '''/title @a title {"text":"Möge der beste","color":"blue"}''',
+ "/playsound minecraft:item.totem.use ambient @a 0 64 0 80",
+ "/worldborder set 75 3600",
+ "/gamerule keepInventory false"
+ ]
+
+ @SuddenDeath.enter
+ def death(self) -> list:
+ # Timer Starten
+ return [
+ '''/title @a title ["",{"text":"Sudden ","color":"dark_blue"},{"text":"DEATH!","bold":true,"color":"red"}]''',
+ "/playsound minecraft:entity.ender_dragon.growl ambient @a 0 64 0 80",
+ "/worldborder set 5 600"
+ ]
+
+ @End.enter
+ def end(self, playername: str) -> list:
+ return [
+ "/worldborder center 0 0",
+ "/worldborder set 75",
+ "/gamerule keepInventory true",
+ '''/title @a subtitle ["",{"text":"''' + playername + '''","bold":true,"color":"red"},{"text":" gewinnt","color":"dark_blue"}]''',
+ '''/title @a title {"text":"ENDE!","color":"dark_blue"}''',
+ "/playsound minecraft:entity.ender_dragon_death ambient @a 0 64 0 80",
+ ]
+
+
+class Whitelist(StateMachine):
+ "A workflow machine for managing Whitelist states"
+ On = State(initial=True)
+ Off = State()
+ toggle = On.to(Off) | Off.to(On)
+
+class RCON(MCRcon):
+ def __init__(self, ip: str, secret: str, port: int = 31066):
+ super().__init__(ip, secret, port)
+ self.connect()
+
+ def whitelist(self):
+ self.whitelist.toggle()
+ cmds = "/whitelist {}".format(self.whitelist.current_state.id)
+ print(cmds)
+
+ def _sendcmd(self, cmds: str | list) -> None:
+ if isinstance(cmds, str):
+ return self.server.command(str)
+ if isinstance(cmds, list):
+ return [self.server.commands(cmd) for cmd in cmds]
+
+ def __del__(self):
+ self.disconnect()
+
+class Minecraft(commands.Cog):
+ def __init__(self, bot: commands.Bot, ip: str, secret: str, port: int = 31066):
+ self.bot = bot
+ self.server = RCON(ip, secret, port)
+ self.session = BorderWarsSession()
+ self.whitelist = Whitelist()
+
+ @commands.hybrid_command(name='whitelist')
+ async def whitelist(self, ctx: commands.Context):
+ """
+ Toggles Servers Whitelist
+
+ Parameters
+ ----------
+ ctx: commands.Context
+ The context of the command invocation
+ """
+ await self.whitelist.activate_initial_state()
+ await ctx.send("Whitelist")
+
+ @commands.hybrid_command(name='start')
+ async def start(self, ctx: commands.Context):
+ """
+ Starts a Border Wars Session
+
+ Parameters
+ ----------
+ ctx: commands.Context
+ The context of the command invocation
+ """
+ cmds =
+ await ctx.send("Start")
+
+ @commands.hybrid_command(name='init')
+ async def init(self, ctx: commands.Context):
+ """
+ Initialize a Border Wars session
+
+ Parameters
+ ----------
+ ctx: commands.Context
+ The context of the command invocation
+ """
+ cmds = [
+ "/worldborder center 0 0",
+ "/worldborder set 5",
+ "/whitelist off"
+ ]
+ await self.session.activate_initial_state()
+ await self.session.init_game()
+ await ctx.send(self.session.current_state)
+
+ @commands.hybrid_command(name='end')
+ async def end(self, ctx: commands.Context):
+ """
+ Ends a Border Wars session
+
+ Parameters
+ ----------
+ ctx: commands.Context
+ The context of the command invocation
+ """
+ await ctx.send("End")
+
+ @commands.hybrid_command(name='rules')
+ async def rules(self, ctx: commands.Context):
+ """
+ Displays the Border Wars rules
+
+ Parameters
+ ----------
+ ctx: commands.Context
+ The context of the command invocation
+ """
+ await ctx.send("Rules")
+
+ @commands.hybrid_command(name='custom')
+ async def custom(self, ctx: commands.Context):
+ """
+ Register a custom command
+
+ Parameters
+ ----------
+ ctx: commands.Context
+ The context of the command invocation
+ """
+ await ctx.send("Custom")
+
diff --git a/bot/cogs/user_management.py b/bot/cogs/user_management.py
new file mode 100644
index 0000000..5283d20
--- /dev/null
+++ b/bot/cogs/user_management.py
@@ -0,0 +1,12 @@
+from discord.ext import commands
+from sqlalchemy import create_engine
+from sqlalchemy.orm import DeclarativeBase
+
+#engine = create_engine("sqlite://user.sqlite", echo=True)
+#connection = engine.connect()
+
+class User(DeclarativeBase):
+ pass
+
+class UserManager(commands.Cog):
+ pass
diff --git a/bot/compose.yml b/bot/compose.yml
new file mode 100644
index 0000000..b9b088e
--- /dev/null
+++ b/bot/compose.yml
@@ -0,0 +1,16 @@
+services:
+ bot:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ # volumes:
+ # - bot_data:/home
+
+
+volumes:
+ bot_data:
+ driver: local
+ driver_opts:
+ type: none
+ device: ./data
+ o: bind
diff --git a/bot/requirements.txt b/bot/requirements.txt
new file mode 100644
index 0000000..c7b829a
--- /dev/null
+++ b/bot/requirements.txt
@@ -0,0 +1,14 @@
+aiohttp==3.9.5
+aiosignal==1.3.1
+attrs==23.2.0
+discord.py==2.4.0
+frozenlist==1.4.1
+greenlet==3.0.3
+idna==3.7
+mcrcon==0.7.0
+multidict==6.0.5
+python-dotenv==1.0.1
+python-statemachine==2.3.1
+SQLAlchemy==2.0.31
+typing_extensions==4.12.2
+yarl==1.9.4
diff --git a/bot/test.py b/bot/test.py
new file mode 100644
index 0000000..257cd65
--- /dev/null
+++ b/bot/test.py
@@ -0,0 +1,8 @@
+import enum
+
+
+ #off = states.On.to(states.Off)
+ #on = states.Off.to(states.On)
+
+if __name__ == "__main__":
+ WhitelistMachine()._graph().write_png("./whitelist.png")
diff --git a/compose.yml b/compose.yml
new file mode 100644
index 0000000..bad5fcc
--- /dev/null
+++ b/compose.yml
@@ -0,0 +1,5 @@
+include:
+ - ./bot/compose.yml
+ - ./postgres/compose.yml
+ # - ./pgadmin4/compose.yml
+
diff --git a/pgadmin4/.env b/pgadmin4/.env
new file mode 100644
index 0000000..94bde4d
--- /dev/null
+++ b/pgadmin4/.env
@@ -0,0 +1,3 @@
+PGADMIN_DEFAULT_EMAIL=p.keier@beyerstedt-it.de
+PGADMIN_DEFAULT_PASSWORD=1P2h3i4lon
+PGADMIN_DISABLE_POSTFIX=true
diff --git a/pgadmin4/compose.yml b/pgadmin4/compose.yml
new file mode 100644
index 0000000..0336a8c
--- /dev/null
+++ b/pgadmin4/compose.yml
@@ -0,0 +1,19 @@
+services:
+ pgadmin:
+ image: dpage/pgadmin4
+ container_name: pg4
+ restart: always
+ env_file: ./.env
+ ports:
+ - "8888:80"
+ volumes:
+ - ./server.json:/var/lib/pgadmin/server.json
+ - pg4_data:/var/lib/pgadmin
+
+volumes:
+ pg4_data:
+ driver: local
+ driver_opts:
+ type: none
+ device: ./data
+ o: bind
diff --git a/pgadmin4/server.json b/pgadmin4/server.json
new file mode 100644
index 0000000..b2cb579
--- /dev/null
+++ b/pgadmin4/server.json
@@ -0,0 +1,13 @@
+{
+ "Servers": {
+ "1": {
+ "Name": "Bot",
+ "Group": "Local",
+ "Port": 5432,
+ "Username": "garde-studios",
+ "Host": "localhost",
+ "SSLMode": "prefer",
+ "MaintenanceDB": "postgres"
+ }
+ }
+}
diff --git a/postgres/.env b/postgres/.env
new file mode 100644
index 0000000..f643c22
--- /dev/null
+++ b/postgres/.env
@@ -0,0 +1,2 @@
+POSTGRES_USER=garde-studios
+POSTGRES_PASSWORD=garde-studios
diff --git a/postgres/compose.yml b/postgres/compose.yml
new file mode 100644
index 0000000..0819cb9
--- /dev/null
+++ b/postgres/compose.yml
@@ -0,0 +1,18 @@
+services:
+ db:
+ image: postgres
+ container_name: pgdb
+ restart: always
+ env_file: ./.env
+ ports:
+ - "5432:5432"
+ volumes:
+ - db_data:/var/lib/postgresql/data
+
+volumes:
+ db_data:
+ driver: local
+ driver_opts:
+ type: none
+ device: ./data
+ o: bind