Switched to berconpy, implemented listener

This commit is contained in:
2024-06-13 00:07:40 +02:00
parent 7bada37794
commit 1b897a70a9
7 changed files with 205 additions and 364 deletions

146
api.py Normal file
View File

@@ -0,0 +1,146 @@
import asyncio
import logging
import uvicorn
import json
import os
from pydantic import BaseModel
import berconpy as rcon
from fastapi import FastAPI, HTTPException, Depends
# RCON Server Details
credentials_file = os.path.join(os.path.dirname(__file__), "credentials.json")
with open(credentials_file) as f:
credentials = json.load(f)
IP_ADDR = credentials["SERVER_ADDRESS"]
PORT = credentials["SERVER_PORT"]
PASSWORD = credentials["RCON_PASSWORD"]
# Logging Configuration
log = logging.getLogger("berconpy")
log.setLevel(logging.DEBUG)
handler = logging.StreamHandler()
handler.setFormatter(logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s"))
log.addHandler(handler)
# RCON Client Initialization
client = rcon.AsyncRCONClient()
# FastAPI Initialization
app = FastAPI()
# Player Model
class Player(BaseModel):
name: str
score: int
class PlayerAction(BaseModel):
playerid: str
reason: str
duration: int = None # Optional for ban duration
# Dependency to get RCON manager
async def get_rcon_manager():
async with client.connect(IP_ADDR, PORT, PASSWORD):
yield client
# FastAPI Endpoint to List Players
@app.get("/players")
async def list_players(rcon: rcon.AsyncRCONClient = Depends(get_rcon_manager)):
try:
response = await rcon.send_command("players")
players = []
for line in response.splitlines():
parts = line.split()
if len(parts) >= 2:
name = parts[0]
try:
score = int(parts[1])
except ValueError:
score = 0
player = Player(name=name, score=score)
players.append(player)
return players
except Exception as e:
log.error(f"Error fetching players: {e}")
raise HTTPException(status_code=500, detail="Error fetching players")
# Kick Player Endpoint
@app.post("/kick")
async def kick_player(action: PlayerAction, rcon: rcon.AsyncRCONClient = Depends(get_rcon_manager)):
try:
response = await rcon.send_command(f'kick {action.playerid} {action.reason}')
return {"response": response}
except Exception as e:
log.error(f"Error kicking player: {e}")
raise HTTPException(status_code=500, detail="Error kicking player")
# Ban Player Endpoint
@app.post("/ban")
async def ban_player(action: PlayerAction, rcon: rcon.AsyncRCONClient = Depends(get_rcon_manager)):
try:
duration_str = f"{action.duration} " if action.duration else ""
response = await rcon.send_command(f'ban {action.playerid} {duration_str}"{action.reason}"')
return {"response": response}
except Exception as e:
log.error(f"Error banning player: {e}")
raise HTTPException(status_code=500, detail="Error banning player")
# Unlock Server Endpoint
@app.post("/unlock")
async def unlock_server(rcon: rcon.AsyncRCONClient = Depends(get_rcon_manager)):
try:
response = await rcon.send_command('#unlock')
return {"response": response}
except Exception as e:
log.error(f"Error unlocking server: {e}")
raise HTTPException(status_code=500, detail="Error unlocking server")
# Global Message Endpoint
@app.post("/global_message")
async def global_message(message: str, rcon: rcon.AsyncRCONClient = Depends(get_rcon_manager)):
try:
response = await rcon.send_command(f'Say -1 {message}')
return {"response": response}
except Exception as e:
log.error(f"Error sending global message: {e}")
raise HTTPException(status_code=500, detail="Error sending global message")
# Direct Message Endpoint
@app.post("/direct_message")
async def direct_message(playerid: str, message: str, rcon: rcon.AsyncRCONClient = Depends(get_rcon_manager)):
try:
response = await rcon.send_command(f'Say {playerid} {message}')
return {"response": response}
except Exception as e:
log.error(f"Error sending direct message: {e}")
raise HTTPException(status_code=500, detail="Error sending direct message")
# Lock Server Endpoint
@app.post("/lock")
async def lock_server(rcon: rcon.AsyncRCONClient = Depends(get_rcon_manager)):
try:
response = await rcon.send_command('#lock')
return {"response": response}
except Exception as e:
log.error(f"Error locking server: {e}")
raise HTTPException(status_code=500, detail="Error locking server")
# RCON Event Handlers
@client.dispatch.on_login
async def on_login():
print("Connected to RCON server.")
@client.dispatch.on_message
async def on_message(message: str):
print("Received message from server:", message)
@client.dispatch.on_command
async def server_response_to_command(response: str):
if not response:
return print("on_command: <empty>")
print("on_command:", response)
# Main Function to Run FastAPI App
if __name__ == "__main__":
uvicorn.run(app, host="0.0.0.0", port=8000)