From 13df50e0f7e0c5b0ddf51417ad4e219f119a30e7 Mon Sep 17 00:00:00 2001 From: Elmo Todurov Date: Thu, 17 Aug 2023 13:21:44 +0300 Subject: [PATCH 1/9] Add a way to send newlines through repeat module --- modules/repeat.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/modules/repeat.py b/modules/repeat.py index a0e6378..564e01b 100644 --- a/modules/repeat.py +++ b/modules/repeat.py @@ -10,5 +10,7 @@ def __init__(self, mud): def alias(self, line): if line == '': self.mud.send(self.outlog[0]) + elif line == '#nl': + self.mud.send('') else: self.outlog.appendleft(line) From e7d85b8391c8ed684010f1df153d8674a90a53a1 Mon Sep 17 00:00:00 2001 From: Tyler Abair Date: Sat, 19 Aug 2023 10:16:13 -0400 Subject: [PATCH 2/9] Allow sending a new line through the repeat module - Stop sending input line if repeat module intercepts it - Send nothing if repeat is triggered when there's no previous command to repeat --- modules/repeat.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/repeat.py b/modules/repeat.py index 564e01b..a70b15d 100644 --- a/modules/repeat.py +++ b/modules/repeat.py @@ -9,8 +9,13 @@ def __init__(self, mud): def alias(self, line): if line == '': - self.mud.send(self.outlog[0]) + if len(self.outlog) > 0: + self.mud.send(self.outlog[0]) + # Signal to the client that the alias has consumed the input line + return True elif line == '#nl': self.mud.send('') + return True # Consume input line else: self.outlog.appendleft(line) + From 83aa0002a9ca709c8b24a14ea1ca6eac5368a74a Mon Sep 17 00:00:00 2001 From: Tyler Abair Date: Sun, 20 Aug 2023 15:51:59 -0400 Subject: [PATCH 3/9] Fix crash when mud disconnects --- pycat.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pycat.py b/pycat.py index 82d68d6..ac96a26 100755 --- a/pycat.py +++ b/pycat.py @@ -212,8 +212,11 @@ def run(self): self.handle_from_telnet() elif fd == self.socketToPipeR: self.handle_from_pipe() - except Exception as e: - traceback.print_exc() + except Exception as error: + if type(error) is EOFError: + pass # This simply means the telnet connection was closed. + else: + traceback.print_exc() finally: self.log("Closing") self.telnet.close() From e697d7fd4b3a9a72b7b592806619ee3cb1537e4e Mon Sep 17 00:00:00 2001 From: Tyler Abair Date: Sun, 20 Aug 2023 16:13:16 -0400 Subject: [PATCH 4/9] Fix first crash when sending interrupt signal --- pycat.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pycat.py b/pycat.py index ac96a26..447bb2d 100755 --- a/pycat.py +++ b/pycat.py @@ -231,7 +231,10 @@ def main(): port = int(sys.argv[2]) arg = sys.argv[3] if len(sys.argv) == 4 else None ses = Session(world_module, port, arg) - ses.run() + try: + ses.run() + except KeyboardInterrupt: + pass assert(__name__ == '__main__') From 51ae64f7412bbf44923003c4518984b402dabad3 Mon Sep 17 00:00:00 2001 From: Tyler Abair Date: Sun, 20 Aug 2023 16:16:01 -0400 Subject: [PATCH 5/9] Undo inclusion of changes from repeat-newline branch --- modules/repeat.py | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/modules/repeat.py b/modules/repeat.py index a70b15d..a0e6378 100644 --- a/modules/repeat.py +++ b/modules/repeat.py @@ -9,13 +9,6 @@ def __init__(self, mud): def alias(self, line): if line == '': - if len(self.outlog) > 0: - self.mud.send(self.outlog[0]) - # Signal to the client that the alias has consumed the input line - return True - elif line == '#nl': - self.mud.send('') - return True # Consume input line + self.mud.send(self.outlog[0]) else: self.outlog.appendleft(line) - From ee5a56ef9e1612d8918fb41527b6d065be0822a1 Mon Sep 17 00:00:00 2001 From: Tyler Abair Date: Sun, 20 Aug 2023 16:19:18 -0400 Subject: [PATCH 6/9] Raise the interrupt so user only has to interrupt once --- pycat.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pycat.py b/pycat.py index 447bb2d..67a80b3 100755 --- a/pycat.py +++ b/pycat.py @@ -234,7 +234,7 @@ def main(): try: ses.run() except KeyboardInterrupt: - pass + raise assert(__name__ == '__main__') From c636f2c81de4ed06680ab0f2bd6931ba9eb623b9 Mon Sep 17 00:00:00 2001 From: Tyler Abair Date: Mon, 21 Aug 2023 21:53:51 -0400 Subject: [PATCH 7/9] Cleaner way of exiting pycat.py with interrupt --- pycat.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/pycat.py b/pycat.py index 67a80b3..662939a 100755 --- a/pycat.py +++ b/pycat.py @@ -212,9 +212,11 @@ def run(self): self.handle_from_telnet() elif fd == self.socketToPipeR: self.handle_from_pipe() - except Exception as error: + except (Exception, KeyboardInterrupt) as error: if type(error) is EOFError: pass # This simply means the telnet connection was closed. + elif type(error) is KeyboardInterrupt: + raise # pass the user's C^c up to main() else: traceback.print_exc() finally: @@ -234,7 +236,7 @@ def main(): try: ses.run() except KeyboardInterrupt: - raise + exit(0) # Exit on C^c assert(__name__ == '__main__') From 91e12fb3485c440d38a59e1a5353065110494f0c Mon Sep 17 00:00:00 2001 From: Tyler Abair Date: Tue, 22 Aug 2023 09:57:01 -0400 Subject: [PATCH 8/9] Add exit message for clarity. --- pycat.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pycat.py b/pycat.py index 662939a..9c90ffa 100755 --- a/pycat.py +++ b/pycat.py @@ -236,6 +236,7 @@ def main(): try: ses.run() except KeyboardInterrupt: + print('\nConnection Terminated. Awaiting interrupt to exit program.') exit(0) # Exit on C^c From f864824f51143fb8e19e2444638b1fa9d4abafdb Mon Sep 17 00:00:00 2001 From: Tyler Abair Date: Thu, 24 Aug 2023 16:15:03 -0400 Subject: [PATCH 9/9] Begin groundwork for customizable command character. --- modular.py | 4 ++-- modules/eval.py | 4 ++-- modules/file_editor.py | 2 +- modules/gzlogging.py | 4 ++-- modules/logging.py | 4 ++-- modules/mapper.py | 4 ++-- modules/scholar.py | 2 +- pycat.py | 4 +++- 8 files changed, 15 insertions(+), 13 deletions(-) diff --git a/modular.py b/modular.py index 5de8704..93fa4f1 100644 --- a/modular.py +++ b/modular.py @@ -121,8 +121,8 @@ def alias(self, line): else: line = sublines[0] - if re.match(r'#\d+ .+', line): - match = re.match(r'#(\d+) (.+)', line) + if re.match(self.mud.cmd_char + r'\d+ .+', line): + match = re.match(self.mud.cmd_char + r'(\d+) (.+)', line) times, cmd = match.groups() for i in range(int(times)): if not self.alias(cmd): diff --git a/modules/eval.py b/modules/eval.py index 0b3279c..6a42a9a 100644 --- a/modules/eval.py +++ b/modules/eval.py @@ -4,11 +4,11 @@ class Eval(BaseModule): def alias(self, line): - if line.startswith('#py '): + if line.startswith(self.mud.cmd_char + 'py '): rest = line[4:] self.mud.log("\n" + pformat(eval(rest))) return True - elif line.startswith('#pye '): + elif line.startswith(self.mud.cmd_char + 'pye '): rest = line[5:] exec(rest) return True diff --git a/modules/file_editor.py b/modules/file_editor.py index c3c1e9e..a31ea6c 100644 --- a/modules/file_editor.py +++ b/modules/file_editor.py @@ -22,7 +22,7 @@ def alias(self, line: str) -> bool: elif line.startswith("#edit "): self.send_file(line[6:]) return True - elif line.startswith('#write-file '): + elif line.startswith(self.mud.cmd_char + 'write-file '): self.write_file(line[12:]) return True return False diff --git a/modules/gzlogging.py b/modules/gzlogging.py index 041d511..570bdbe 100644 --- a/modules/gzlogging.py +++ b/modules/gzlogging.py @@ -14,8 +14,8 @@ def quit(self): self.file.close() def alias(self, line): - if line.startswith('#grep '): - arg = line[len('#grep '):] + if line.startswith(self.mud.cmd_char + 'grep '): + arg = line[len(self.mud.cmd_char + 'grep '):] grep = subprocess.Popen(['/bin/sh', '-c', 'tail -n10000 {} | zgrep -a {}'.format(self.logfname, arg)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = grep.communicate(timeout=5) self.mud.log('\n' + out.decode('utf-8')) diff --git a/modules/logging.py b/modules/logging.py index 5655c34..13d7c4b 100644 --- a/modules/logging.py +++ b/modules/logging.py @@ -12,8 +12,8 @@ def quit(self): self.file.close() def alias(self, line): - if line.startswith('#grep '): - arg = line[len('#grep '):] + if line.startswith(self.mud.cmd_char + 'grep '): + arg = line[len(self.mud.cmd_char + 'grep '):] grep = subprocess.Popen(['/bin/sh', '-c', 'tail -n10000 {} | grep -a {}'.format(self.logfname, arg)], stdout=subprocess.PIPE, stderr=subprocess.PIPE) out, err = grep.communicate(timeout=5) self.mud.log('\n' + out.decode('utf-8')) diff --git a/modules/mapper.py b/modules/mapper.py index c9e9868..a8fbab1 100644 --- a/modules/mapper.py +++ b/modules/mapper.py @@ -511,7 +511,7 @@ def startExit(self, args): self.exitFrom['data'] = dict(zone=room['zone'], terrain = room['terrain']) for k, v in room['exits'].items(): self.exitFrom['exits'][k.lower()] = {'tgt': roomnr(v)} - self.log("Type '#map endexit' when you're in the right room, or #map endexit abort") + self.log(f"Type '{self.mud.cmd_char}map endexit' when you're in the right room, or #map endexit abort") self.exitKw = self.exitKw.replace(';', '\n') self.exitKw = self.exitKw.replace('~', '\n') self.log("Exit: " + repr(self.exitKw)) @@ -739,7 +739,7 @@ def __init__(self, mud, drawAreas, mapfname, spacesInRun=True): def alias(self, line): words = line.split(' ') - if words[0].lower() != '#map': + if words[0].lower() != self.mud.cmd_char + 'map': return if len(words) == 1: diff --git a/modules/scholar.py b/modules/scholar.py index 78f183b..7f94b72 100644 --- a/modules/scholar.py +++ b/modules/scholar.py @@ -148,7 +148,7 @@ def doneTeaching(world, matches): class Scholar(BaseModule): def getAliases(self): return { - '#learnfrom (.+)': learnFrom, + self.mud.cmd_char + 'learnfrom (.+)': learnFrom, } def getTriggers(self): diff --git a/pycat.py b/pycat.py index 9c90ffa..a2c2fe9 100755 --- a/pycat.py +++ b/pycat.py @@ -21,6 +21,8 @@ def __init__(self, world_module, port, arg): self.world_module = world_module self.arg = arg self.world = world_module.getClass()(self, self.arg) + self.cmd_char = '#' # The prefix for pycat commands + try: self.socketToPipeR, self.pipeToSocketW, self.stopFlag, runProxy = proxy('::1', port) self.pipeToSocketW = os.fdopen(self.pipeToSocketW, 'wb') @@ -179,7 +181,7 @@ def handle_from_pipe(self): def handle_output_line(self, data): pprint.pprint(data) - if data == '#reload' and self.world: + if data == self.cmd_char + 'reload' and self.world: self.log('Reloading world') try: state = self.world.state