aboutsummaryrefslogtreecommitdiffstats
path: root/pycrctrl.py
diff options
context:
space:
mode:
Diffstat (limited to 'pycrctrl.py')
-rw-r--r--pycrctrl.py145
1 files changed, 109 insertions, 36 deletions
diff --git a/pycrctrl.py b/pycrctrl.py
index 1d2248d..e53a722 100644
--- a/pycrctrl.py
+++ b/pycrctrl.py
@@ -97,6 +97,12 @@ class CmdResult(IntEnum):
RightsFail = 2
RuntimeError = 3
+class Capability(IntEnum):
+ Unknown = -1
+ User = 0
+ Admin = 1
+ Moderator = 2
+
class PyCRCtrl(object):
"""Server control"""
@@ -121,6 +127,7 @@ class PyCRCtrl(object):
league = True
__state = "Lobby"
+ __ingamechat = "aktiviert"
#RegExps = {
# "lobbyStartExp" : "((?:Los geht's!|Action go!)\s*)",
@@ -130,13 +137,17 @@ class PyCRCtrl(object):
# "shutdownExp" : r"^Internetspiel ausgewertet(.*)"
# }
+ capabilities = {}
+ _capa_old = {}
+
def __init__(self, irc=None, path=None, config="pycrctrl.conf"):
if sys.platform == "win32":
- raise NotImplementedError("{} wird nicht unterstützt!".format(sys.platform))
+ raise NotImplementedError("{} wird nicht unterstützt!".format(sys.platform))
self.irc = irc
self.path = path
self.loadConfigFile(config)
+ self.loadCapabilities()
self.loadScenarioList()
self.codec = codec = QTextCodec.codecForName(self.config.get("encoding"))
self.queue = queue.Queue(5)
@@ -152,7 +163,18 @@ class PyCRCtrl(object):
def state(self, text):
if text in ["Lobby", "Lädt", "Läuft"]:
self.__state = text
- self.setTopic("Aktuelles Szenario: {} | {}".format(self.scenario, self.state))
+ topic = "Aktuelles Szenario: {} | {}{} | Ingamechat ist {}.".format(self.scenario, self.state, (" | Liga" if self.scenario in self.league_scenlist else ""), self.ingamechat)
+ self.setTopic(topic)
+
+ @property
+ def ingamechat(self):
+ return self.__ingamechat
+
+ @ingamechat.setter
+ def ingamechat(self, text):
+ if text in ["aktiviert", "deaktiviert"]:
+ self.__ingamechat = text
+ self.state = self.state
def loadScenarioList(self) -> bool:
if self.path == None:
@@ -166,7 +188,15 @@ class PyCRCtrl(object):
return True
- def loadConfigFile(self, config):
+ def loadCapabilities(self) -> bool:
+ if self.path == None:
+ return False
+
+ _capa_old = json.load(open(os.path.join(self.path, "capabilities.conf"), "r"))
+ return True
+
+
+ def loadConfigFile(self, config) -> bool:
if self.path == None:
return False
@@ -187,7 +217,7 @@ class PyCRCtrl(object):
return True
- def host(self, scenario=None) -> str:
+ def host(self, scenario=None, user=None) -> str:
if scenario == None:
return (CmdResult.SyntaxFail, "Bitte gib einen Szenarionamen an!")
if type(scenario) in [bytes, QByteArray]:
@@ -211,7 +241,7 @@ class PyCRCtrl(object):
if self.queue.full() == False:
self.queue.put(scenario)
- return (CmdResult.Success, 'Szenario "{}" wurde der Warteschlange hinzugefügt.'.format(scenario))
+ return (CmdResult.Success, 'Szenario "{}" wurde der Warteschlange hinzugefügt.'.format(scenario))
else:
return (CmdResult.RuntimeError, "Die Warteschlange ist voll!")
@@ -223,6 +253,8 @@ class PyCRCtrl(object):
self.scenario = self.queue.get()
else:
self.scenario = random.choice(self.scenlist)
+
+ self.capabilities = self._capa_old
self.clonk = subprocess.Popen(
'./{} {} "{}"'.format(self.config.get("engine"), self.config.get("commandline") + (" --" if type(self).__name__ == "PyOCCtrl" else " /") + ("league" if self.scenario in self.league_scenlist() else "noleague"),self.scenario),
0,
@@ -267,22 +299,24 @@ class PyCRCtrl(object):
if output[0] == ">":
output = output[1:]
- if output.find(self.config.get("prefix")) != -1 and output.find("<{}>".format(self.irc.nick)) == -1:
- part = output[output.find(self.config.get("prefix"))+len(self.config.get("prefix")):].split(" ",1)
+
+ part = re.match("<(.*)> ({})(.*)".format(self.config.get("prefix")), output)
+ if part and part.group(0) != self.irc.nick:
+ cmd = part.group(3).split(" ", 1)
found = False
x = None
- if len(part) > 0:
+ if len(cmd) > 0:
for key in self.commands.keys():
- if key == part[0].splitlines()[0]:
+ if key == cmd[0].splitlines()[0]:
found = True
try:
- x = self.commands[key](part[1])
+ x = self.commands[key](cmd[1].split(" "), user=part.group(1))
except IndexError:
- x = self.commands[key]()
+ x = self.commands[key](user=part.group(1))
break
if not found:
- self.writeToServer('Unbekannter Befehl: "' + part[0] + '"!')
+ self.writeToServer('Unbekannter Befehl: "' + part.group(2) + '"!')
if x:
if type(x) == tuple and x[1] != "":
self.writeToServer(x[1])
@@ -297,14 +331,12 @@ class PyCRCtrl(object):
except (UnicodeDecodeError, UnicodeEncodeError):
pass
- if self.irc:
+ if self.irc and self.ingamechat == "aktiviert":
if output.find("<" + self.irc.nick + ">") == -1:
- if bool(re.match(r"^<.*>", output) and output.find("[IRC]") == -1) and \
- bool(output.find(self.config.get("prefix")) == -1):
+ if re.match(r"^<.*>", output) and output.find("[IRC]") == -1 and output.find(self.config.get("prefix")) == -1:
self.irc.reply("[Clonk]{}".format(output), to=self.config.get("channels")["ingame"])
- elif bool(re.match(self.decodeRegExp(self.config.get("RegExps")["joinExp"]), output)) or \
- bool(re.match(self.decodeRegExp(self.config.get("RegExps")["leaveExp"]), output)):
+ elif re.match(self.decodeRegExp(self.config.get("RegExps")["joinExp"]), output) or re.match(self.decodeRegExp(self.config.get("RegExps")["leaveExp"]), output):
self.irc.reply(output, to=self.config.get("channels")["ingame"])
@@ -331,7 +363,7 @@ class PyCRCtrl(object):
return (CmdResult.Success, "")
def doPrivmsg(self, msg):
- if not self.irc:
+ if not (self.irc and self.ingamechat == "aktiviert"):
return
for channel in msg.args[0].split(","):
if channel == self.config.get("channels")["ingame"] and msg.nick != self.irc.nick:
@@ -369,11 +401,39 @@ class PyCRCtrl(object):
self.topic = text
return bool(self.irc.sendMsg(ircmsgs.topic(self.config.get("channels")["ingame"], text)))
- def start(self, time=None):
+ def admin(self, prm=None, user=""):
+ """Setzt den Rundenadmin."""
+ try:
+ if not prm:
+ raise IndexError
+ prm = " ".join(prm)
+
+ if (self.capabilities[prm], self.capabilities[user]) > (Capability.Admin, Capability.Admin):
+ return (CmdResult.RuntimeError, "Du hast bereits mehr Rechte als ein Rundenadmin!")
+
+
+ except KeyError:
+ pass
+
+ except IndexError:
+ return (CmdResult.SyntaxFail, "Nicht genügend Argumente!")
+
+ for u, c in self.capabilities.items():
+ if c == Capability.Admin:
+ return (CmdResult.RuntimeError, "{} ist bereits Rundenadmin!".format(u))
+
+
+ self.capabilities[prm] = self.capabilities[user] = Capability.Admin
+ return (CmdResult.Success, "{} (Spielername: {}) wurde als Rundenadmin eingetragen!".format(user, prm))
+
+
+ def start(self, time=None, user=""):
+ """Startet das Spiel."""
+ if not self.checkCapability(Capability.Admin, user): return (CmdResult.RightsFail, "Du hast nicht die nötige Berechtigung.".encode("utf-8"))
self.stopped = False
if time:
try:
- time = int(time.split(" ")[0])
+ time = int(time[0])
except:
time = 5
self.writeToServer("/start {}".format(time))
@@ -383,7 +443,9 @@ class PyCRCtrl(object):
return (CmdResult.Success, "")
- def stop(self, prm=None):
+ def stop(self, prm=None, user=""):
+ """Stoppt den Countdown."""
+ if not self.checkCapability(Capability.Admin, user): return (CmdResult.RightsFail, "Du hast nicht die nötige Berechtigung.".encode("utf-8"))
def stopping(self):
while self.clonk and self.stopped:
self.writeToServer("/start 60000")
@@ -398,15 +460,17 @@ class PyCRCtrl(object):
return (CmdResult.Success, "")
- def help(self, prm=None):
- self.writeToServer("Verfügbare Befehle:")
+ def help(self, prm=None, user=""):
+ """Gibt die Hilfe aus."""
+ self.writeToServer("Verfügbare Befehle:".encode("utf-8"))
for text, function in self.commands.items():
- self.writeToServer(text)
+ self.writeToServer("{} -- {}".format(text, function.__doc__))
return (CmdResult.Success, "")
- def displayQueue(self, prm=None):
+ def displayQueue(self, prm=None, user=""):
+ """Gibt die Warteschlange aus."""
self.writeToServer(b"Warteschlange:")
for i,scen in enumerate(self.queue.queue):
@@ -415,17 +479,26 @@ class PyCRCtrl(object):
return (CmdResult.Success, "")
- def list(self, prm=None):
+ def list(self, prm=None, user=""):
+ """Zeigt die Szenarioliste an."""
self.writeToServer(b"List:\n-------------")
for scen in self.scenlist:
self.writeToServer(scen)
return (CmdResult.Success, "")
- def ircCommands(self, prm=None):
+ def ircCommands(self, prm=None, user=""):
+ """Enthält Befehle zur Steuerung der IRC-Funktionen."""
+ if not self.checkCapability(Capability.Admin, user): return (CmdResult.RightsFail, "Du hast nicht die nötige Berechtigung.".encode("utf-8"))
if not prm:
return (CmdResult.SyntaxFail, "")
+ if prm[0] == "ingamechat":
+ if prm[1] == "off":
+ self.ingamechat = "deaktiviert"
+ elif prm[1] == "on":
+ self.ingamechat = "aktiviert"
+
return (CmdResult.Success, "")
def IsRunning(self) -> bool:
@@ -456,17 +529,17 @@ class PyCRCtrl(object):
self.scenlist().append(name)
Pickler(open(os.path.join(self.path, "scenlist"), "wb")).dump(self.scenlist())
return self
+
+ def checkCapability(self, capability, user=""):
+ if not user:
+ return False
+ try:
+ return (True if self.capabilities[user] >= capability else False)
+
+ except KeyError:
+ return False
-
-class PyOCCtrl(PyCRCtrl):
-
-
-
- engine = "openclonk-server"
- codec = QTextCodec.codecForName("UTF-8")
- commandline = "--fullscreen --lobby=300 --faircrew --record --config=config.txt"
-
#
#
#