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
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 = []
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:
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):
self.restore_input_values()
def loop(self, stdscr):
- import time
import datetime
def safe_addstr(y, x, line):
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)
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()
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:
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')
this.url = url;
this.websocket = new WebSocket(this.url);
this.websocket.onopen = function(event) {
- window.setInterval(function() { server.send(['PING']) }, 30000);
- this.send('TASKS');
+ server.connected = true;
+ server.send(['TASKS']);
tui.log_msg("@ server connected! :)");
tui.switch_mode(mode_login);
};
this.websocket.onclose = function(event) {
+ server.connected = false;
+ tui.switch_mode(mode_waiting_for_server);
tui.log_msg("@ server disconnected :(");
- tui.log_msg("@ hint: try the '/reconnect' command");
};
this.websocket.onmessage = this.handle_event;
},
- reconnect: function() {
- this.reconnect_to(this.url);
- },
reconnect_to: function(url) {
this.websocket.close();
this.init(url);
} else if (tokens[0] === 'GAME_ERROR') {
tui.log_msg('? game error: ' + tokens[1]);
} else if (tokens[0] === 'PONG') {
- console.log('PONG');
+ ;
} else {
tui.log_msg('? unhandled input: ' + event.data);
}
} else {
tui.log_msg('? need message target and message');
}
- } else if (tokens[0].slice(1) == 'reconnect') {
- if (tokens.length > 1) {
- server.reconnect_to(tokens[1]);
- } else {
- server.reconnect();
- }
} else {
tui.log_msg('? unknown command');
}
tui.inputEl.focus();
}
}, 100);
+window.setInterval(function() {
+ if (server.connected) {
+ server.send(['PING']);
+ } else {
+ server.reconnect_to(server.url);
+ tui.log_msg('@ attempting reconnect …')
+ }
+}, 5000);
</script>
</body></html>