X-Git-Url: https://plomlompom.com/repos/berlin_corona.txt?a=blobdiff_plain;f=rogue_chat_curses.py;h=e037e7d5943f3762ffc72f08952a4d0f20fcec67;hb=957e53c2d64cbb227f5bfe34653c766381659f01;hp=33b2750788c4c9b241158c9943ff428d726c9a8e;hpb=6bf479a40acf55042c5ea4834701d09073af172c;p=plomrogue2 diff --git a/rogue_chat_curses.py b/rogue_chat_curses.py index 33b2750..e037e7d 100755 --- a/rogue_chat_curses.py +++ b/rogue_chat_curses.py @@ -2,6 +2,7 @@ import curses import queue import threading +import time from plomrogue.game import GameBase from plomrogue.parser import Parser from plomrogue.mapping import YX, MapGeometrySquare, MapGeometryHex @@ -103,6 +104,10 @@ def cmd_MAP(game, geometry, size, content): } cmd_MAP.argtypes = 'string:map_geometry yx_tuple:pos string' +def cmd_FOV(game, content): + game.fov = content +cmd_FOV.argtypes = 'string' + def cmd_MAP_CONTROL(game, content): game.map_control_content = content cmd_MAP_CONTROL.argtypes = 'string' @@ -177,6 +182,7 @@ class Game(GameBase): self.register_command(cmd_GAME_ERROR) self.register_command(cmd_PLAY_ERROR) self.register_command(cmd_TASKS) + self.register_command(cmd_FOV) self.map_content = '' self.player_id = -1 self.info_db = {} @@ -257,11 +263,48 @@ class TUI: for k in keys_conf: self.keys[k] = keys_conf[k] self.show_help = False + self.disconnected = True + self.force_instant_connect = True + self.input_lines = [] + self.fov = '' curses.wrapper(self.loop) def flash(self): curses.flash() + def connect(self): + + def handle_recv(msg): + if msg == 'BYE': + self.socket.close() + else: + self.queue.put(msg) + + self.log_msg('@ attempting connect') + socket_client_class = PlomSocketClient + if self.host.startswith('ws://') or self.host.startswith('wss://'): + socket_client_class = WebSocketClient + try: + self.socket = socket_client_class(handle_recv, self.host) + self.socket_thread = threading.Thread(target=self.socket.run) + self.socket_thread.start() + self.disconnected = False + self.socket.send('TASKS') + self.switch_mode('login') + except ConnectionRefusedError: + self.log_msg('@ server connect failure') + self.disconnected = True + self.switch_mode('waiting_for_server') + self.do_refresh = True + + def reconnect(self): + self.log_msg('@ attempting reconnect') + self.send('QUIT') + time.sleep(0.1) # FIXME necessitated by some some strange SSL race + # conditions with ws4py, find out what exactly + self.switch_mode('waiting_for_server') + self.connect() + def send(self, msg): try: if hasattr(self.socket, 'plom_closed') and self.socket.plom_closed: @@ -269,6 +312,8 @@ class TUI: self.socket.send(msg) except (BrokenPipeError, BrokenSocketConnection): self.log_msg('@ server disconnected :(') + self.disconnected = True + self.force_instant_connect = True self.do_refresh = True def log_msg(self, msg): @@ -310,7 +355,6 @@ class TUI: self.restore_input_values() def loop(self, stdscr): - import time import datetime def safe_addstr(y, x, line): @@ -324,38 +368,6 @@ class TUI: stdscr.insstr(y, self.size.x - 2, ' ') stdscr.addstr(y, x, cut) - def connect(): - - def handle_recv(msg): - if msg == 'BYE': - self.socket.close() - else: - self.queue.put(msg) - - socket_client_class = PlomSocketClient - if self.host.startswith('ws://') or self.host.startswith('wss://'): - socket_client_class = WebSocketClient - while True: - try: - self.socket = socket_client_class(handle_recv, self.host) - self.socket_thread = threading.Thread(target=self.socket.run) - self.socket_thread.start() - self.socket.send('TASKS') - self.switch_mode('login') - return - except ConnectionRefusedError: - self.log_msg('@ server connect failure, trying again …') - draw_screen() - stdscr.refresh() - time.sleep(1) - - def reconnect(): - self.send('QUIT') - time.sleep(0.1) # FIXME necessitated by some some strange SSL race - # conditions with ws4py, find out what exactly - self.switch_mode('waiting_for_server') - connect() - def handle_input(msg): command, args = self.parser.parse(msg) command(*args) @@ -412,18 +424,20 @@ class TUI: if not self.game.turn_complete: return pos_i = self.explorer.y * self.game.map_geometry.size.x + self.explorer.x - info = 'TERRAIN: %s\n' % self.game.map_content[pos_i] - for t in self.game.things: - if t.position == self.explorer: - info += 'PLAYER @: %s\n' % t.name - if self.explorer in self.game.portals: - info += 'PORTAL: ' + self.game.portals[self.explorer] + '\n' - else: - info += 'PORTAL: (none)\n' - if self.explorer in self.game.info_db: - info += 'ANNOTATION: ' + self.game.info_db[self.explorer] - else: - info += 'ANNOTATION: waiting …' + info = 'outside field of view' + if self.game.fov[pos_i] == '.': + info = 'TERRAIN: %s\n' % self.game.map_content[pos_i] + for t in self.game.things: + if t.position == self.explorer: + info += 'PLAYER @: %s\n' % t.name + if self.explorer in self.game.portals: + info += 'PORTAL: ' + self.game.portals[self.explorer] + '\n' + else: + info += 'PORTAL: (none)\n' + if self.explorer in self.game.info_db: + info += 'ANNOTATION: ' + self.game.info_db[self.explorer] + else: + info += 'ANNOTATION: waiting …' lines = msg_into_lines_of_width(info, self.window_width) height_header = 2 for i in range(len(lines)): @@ -559,13 +573,18 @@ class TUI: self.explorer = YX(0, 0) self.input_ = '' input_prompt = '> ' - connect() - last_ping = datetime.datetime.now() - interval = datetime.timedelta(seconds=30) + interval = datetime.timedelta(seconds=5) + last_ping = datetime.datetime.now() - interval while True: + if self.disconnected and self.force_instant_connect: + self.force_instant_connect = False + self.connect() now = datetime.datetime.now() if now - last_ping > interval: - self.send('PING') + if self.disconnected: + self.connect() + else: + self.send('PING') last_ping = now if self.do_refresh: draw_screen() @@ -608,13 +627,11 @@ class TUI: self.input_ = "" self.switch_mode('play') elif self.mode == self.mode_chat and key == '\n': - if self.input_[0] == '/': + if self.input_[0] == '/': # FIXME fails on empty input if self.input_ in {'/' + self.keys['switch_to_play'], '/play'}: self.switch_mode('play') elif self.input_ in {'/' + self.keys['switch_to_study'], '/study'}: self.switch_mode('study') - elif self.input_ == '/reconnect': - reconnect() elif self.input_.startswith('/nick'): tokens = self.input_.split(maxsplit=1) if len(tokens) == 2: @@ -650,7 +667,7 @@ class TUI: elif self.mode == self.mode_teleport and key == '\n': if self.input_ == 'YES!': self.host = self.teleport_target_host - reconnect() + self.reconnect() else: self.log_msg('@ teleport aborted') self.switch_mode('play')