summaryrefslogtreecommitdiff
path: root/curses
diff options
context:
space:
mode:
authorLivio Recchia <recchialivio@libero.it>2020-02-10 23:06:34 +0100
committerLivio Recchia <recchialivio@libero.it>2020-02-10 23:06:34 +0100
commit9a13903a2f7d3a65fdf15a65fb59cccd622e2066 (patch)
tree9403b7dff39eb5e5d7fa0f79efb69b496add4c4b /curses
parent11cc316b74d5f3f283413a33e7693b314741aa4a (diff)
downloadmanachat-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.py78
-rw-r--r--curses/cui.pycbin0 -> 2466 bytes
-rw-r--r--curses/handlers.py39
-rw-r--r--curses/handlers.pycbin0 -> 1829 bytes
-rw-r--r--curses/tmwcli.py134
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
new file mode 100644
index 0000000..2a46ef6
--- /dev/null
+++ b/curses/cui.pyc
Binary files differ
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
new file mode 100644
index 0000000..e75a37f
--- /dev/null
+++ b/curses/handlers.pyc
Binary files differ
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()