diff options
author | Livio Recchia <recchialivio@libero.it> | 2020-02-10 23:06:34 +0100 |
---|---|---|
committer | Livio Recchia <recchialivio@libero.it> | 2020-02-10 23:06:34 +0100 |
commit | 9a13903a2f7d3a65fdf15a65fb59cccd622e2066 (patch) | |
tree | 9403b7dff39eb5e5d7fa0f79efb69b496add4c4b /curses | |
parent | 11cc316b74d5f3f283413a33e7693b314741aa4a (diff) | |
download | manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.tar.gz manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.tar.bz2 manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.tar.xz manachat-9a13903a2f7d3a65fdf15a65fb59cccd622e2066.zip |
Initial commit
Diffstat (limited to 'curses')
-rw-r--r-- | curses/cui.py | 78 | ||||
-rw-r--r-- | curses/cui.pyc | bin | 0 -> 2466 bytes | |||
-rw-r--r-- | curses/handlers.py | 39 | ||||
-rw-r--r-- | curses/handlers.pyc | bin | 0 -> 1829 bytes | |||
-rw-r--r-- | curses/tmwcli.py | 134 |
5 files changed, 251 insertions, 0 deletions
diff --git a/curses/cui.py b/curses/cui.py new file mode 100644 index 0000000..5405765 --- /dev/null +++ b/curses/cui.py @@ -0,0 +1,78 @@ +#-*- coding: utf-8 -*- +""" +Curses-based console user interface for TMW chat client. +""" + +import curses +from curses.textpad import Textbox + +stdscr = None +chatlog_win = None +input_win = None +players_win = None +input_textbox = None + + +def init(): + global stdscr, chatlog_win, input_win, players_win, input_textbox + + stdscr = curses.initscr() + curses.cbreak() + curses.noecho() + stdscr.keypad(1) + + h, w = stdscr.getmaxyx() + PNW = 20 # player name width + INH = 4 # input window height + + stdscr.vline(0, w - PNW - 1, curses.ACS_VLINE, h) + stdscr.hline(h - INH - 1, 0, curses.ACS_HLINE, w - PNW - 1) + + chatlog_win = curses.newwin(h - INH - 1, w - PNW - 1, 0, 0) + input_win = curses.newwin(INH, w - PNW - 1, h - INH, 0) + players_win = curses.newwin(h, PNW, 0, w - PNW) + + chatlog_win.idlok(1) + chatlog_win.scrollok(1) + + players_win.idlok(1) + players_win.scrollok(1) + + input_textbox = Textbox(input_win) + input_textbox.stripspaces = True + + stdscr.noutrefresh() + input_win.noutrefresh() + players_win.noutrefresh() + chatlog_win.noutrefresh() + + curses.doupdate() + + +def chatlog_append(line): + if line[-1] != "\n": + line = line + "\n" + chatlog_win.addstr(line) + chatlog_win.refresh() + + +def input_loop(callback): + def v(ch): + # chatlog_append(curses.keyname(ch)) + if ch in (curses.KEY_ENTER, curses.ascii.NL): + return curses.ascii.BEL + return ch + + cmd = '' + while cmd not in ('/exit', '/quit'): + cmd = input_textbox.edit(v).strip() + callback(cmd) + input_win.clear() + input_win.move(0, 0) + + +def finalize(): + stdscr.keypad(0) + curses.echo() + curses.nocbreak() + curses.endwin() diff --git a/curses/cui.pyc b/curses/cui.pyc Binary files differnew file mode 100644 index 0000000..2a46ef6 --- /dev/null +++ b/curses/cui.pyc diff --git a/curses/handlers.py b/curses/handlers.py new file mode 100644 index 0000000..28a7562 --- /dev/null +++ b/curses/handlers.py @@ -0,0 +1,39 @@ + +import net.mapserv as mapserv +from utils import extends +import cui +import textutils +from loggers import debuglog + + +__all__ = [] + + +@extends('smsg_whisper_response') +def send_whisper_result(data): + if data.code == 0: + last_nick = mapserv.last_whisper['to'] + cui.input_win.clear() + cui.input_win.addstr('/w "{}" '.format(last_nick)) + cui.input_win.refresh() + + +@extends('smsg_player_warp') +def player_warp(data): + mapserv.cmsg_map_loaded() + m = "[warp] {} ({},{})".format(data.map, data.x, data.y) + debuglog.info(m) + + +@extends('smsg_map_login_success') +def map_login_success(data): + mapserv.cmsg_map_loaded() + + +@extends('smsg_connection_problem') +def connection_problem(data): + error_codes = { + 2 : "Account already in use" + } + msg = error_codes.get(data.code, str(data.code)) + debuglog.error('Connection problem: %s', msg) diff --git a/curses/handlers.pyc b/curses/handlers.pyc Binary files differnew file mode 100644 index 0000000..e75a37f --- /dev/null +++ b/curses/handlers.pyc diff --git a/curses/tmwcli.py b/curses/tmwcli.py new file mode 100644 index 0000000..679019b --- /dev/null +++ b/curses/tmwcli.py @@ -0,0 +1,134 @@ +#!/usr/bin/python2 + +import os +import sys +import logging +import time +import asyncore +import threading +from ConfigParser import ConfigParser + +# add .. to PYTHONPATH +parent, _ = os.path.split(os.getcwd()) +sys.path.insert(0, parent) +sys.path.insert(1, os.path.join(parent, "plugins")) + +try: + import construct + del construct +except ImportError: + sys.path.insert(1, os.path.join(parent, "external")) + +del parent + +import cui +import handlers +import net +import net.mapserv as mapserv +import plugins +import monsterdb +import itemdb +from commands import process_line +from net.onlineusers import OnlineUsers +from loggers import netlog, debuglog +from logicmanager import logic_manager + + +class SideBarUpdater(threading.Thread): + + def __init__(self, window, online_users_obj, update_interval=20): + self._active = True + self._timer = 0 + self._update_interval = update_interval + self._online_users_obj = online_users_obj + self._window = window + threading.Thread.__init__(self) + + def run(self): + while self._active: + if (time.time() - self._timer) > self._update_interval: + self._window.clear() + for user in self._online_users_obj.online_users: + print user + self._window.addstr(user + '\n') + self._window.refresh() + self._timer = time.time() + else: + time.sleep(1.0) + + def stop(self): + self._active = False + + +class CursesDebugLogHandler(logging.Handler): + def emit(self, record): + msg = self.format(record) + cui.chatlog_append(msg) + + +def loop(): + try: + while True: + asyncore.loop(timeout=0.2, count=5) + logic_manager.tick() + except KeyboardInterrupt: + return + + +if __name__ == "__main__": + config = ConfigParser() + if len(sys.argv) > 1: + config.read(sys.argv[1]) + else: + config.read('../manachat.ini') + + rootLogger = logging.getLogger('') + rootLogger.addHandler(logging.NullHandler()) + + dbgh = CursesDebugLogHandler() + dbgh.setFormatter(logging.Formatter("[%(asctime)s] %(message)s", + datefmt="%H:%M")) + debuglog.addHandler(dbgh) + debuglog.setLevel(logging.INFO) + + if config.getboolean('Other', 'log_network_packets'): + import os + import tempfile + + logfile = os.path.join(tempfile.gettempdir(), "netlog.txt") + netlog.setLevel(logging.INFO) + fh = logging.FileHandler(logfile, mode="w") + fmt = logging.Formatter("[%(asctime)s] %(message)s", + datefmt="%Y-%m-%d %H:%M:%S") + fh.setFormatter(fmt) + netlog.addHandler(fh) + + cui.init() + + plugins.load_plugins(config) + + monsterdb.read_monster_db('../monsterdb.txt') + itemdb.load_itemdb('../itemdb.txt') + + online_users = OnlineUsers(config.get('Other', 'online_txt_url')) + online_users.start() + side_bar_updater = SideBarUpdater(cui.players_win, online_users) + side_bar_updater.start() + + net.login(host=config.get('Server', 'host'), + port=config.getint('Server', 'port'), + username=config.get('Player', 'username'), + password=config.get('Player', 'password'), + charname=config.get('Player', 'charname')) + + t = threading.Thread(target=loop) + t.setDaemon(True) + t.start() + + cui.input_loop(process_line) + + side_bar_updater.stop() + online_users.stop() + cui.finalize() + + mapserv.cleanup() |