This commit is contained in:
DerGrumpf 2024-07-24 14:46:46 +02:00
parent ce267219fa
commit 47d44643c3
16 changed files with 353 additions and 0 deletions

2
.gitignore vendored
View File

@ -2,3 +2,5 @@
*/__pycache__/
*/data/
*.pyc
.DS_Store

6
bot/.dockerignore Normal file
View File

@ -0,0 +1,6 @@
env/
__pycache__
test.py
Dockerfile
compose.yml
data/

7
bot/.env Normal file
View File

@ -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

8
bot/Dockerfile Normal file
View File

@ -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"]

35
bot/bot.py Normal file
View File

@ -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)

185
bot/cogs/minecraft.py Normal file
View File

@ -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")

View File

@ -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

16
bot/compose.yml Normal file
View File

@ -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

14
bot/requirements.txt Normal file
View File

@ -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

8
bot/test.py Normal file
View File

@ -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")

5
compose.yml Normal file
View File

@ -0,0 +1,5 @@
include:
- ./bot/compose.yml
- ./postgres/compose.yml
# - ./pgadmin4/compose.yml

3
pgadmin4/.env Normal file
View File

@ -0,0 +1,3 @@
PGADMIN_DEFAULT_EMAIL=p.keier@beyerstedt-it.de
PGADMIN_DEFAULT_PASSWORD=1P2h3i4lon
PGADMIN_DISABLE_POSTFIX=true

19
pgadmin4/compose.yml Normal file
View File

@ -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

13
pgadmin4/server.json Normal file
View File

@ -0,0 +1,13 @@
{
"Servers": {
"1": {
"Name": "Bot",
"Group": "Local",
"Port": 5432,
"Username": "garde-studios",
"Host": "localhost",
"SSLMode": "prefer",
"MaintenanceDB": "postgres"
}
}
}

2
postgres/.env Normal file
View File

@ -0,0 +1,2 @@
POSTGRES_USER=garde-studios
POSTGRES_PASSWORD=garde-studios

18
postgres/compose.yml Normal file
View File

@ -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