-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpylanthia.py
136 lines (111 loc) · 4.25 KB
/
pylanthia.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
""" A terminal-based python client for dragonrealms
"""
import argparse
import threading
import queue
import os
import logging
import datetime
from lib import setup_game_connection
from lib.game_state import GlobalGameState
from lib import gametime_incrementor
from lib import get_tcp_lines
from lib import text_processing
from lib import command_processing
from lib import urwid_ui
# TODO: move logging to a lib module
# see lib/xml_parser.py for best practice importing the logger
# from: https://stackoverflow.com/a/15735146
log_filename = "{}_log.{}.txt".format(
"dr", datetime.datetime.now().strftime("%Y-%m-%d.%H:%M:%S")
)
log_directory = "logs"
log_location = os.path.join(log_directory, log_filename)
logging.basicConfig(filename=log_location, level=logging.DEBUG)
def main(character=None):
""" Manage all the threads, update to async await
note: preprocess_lines_thread.daemon = True # closes when main thread ends
"""
game_state = GlobalGameState()
tcp_lines = queue.Queue() # split the tcp buffer on '\r\n'
preprocessed_lines = queue.Queue()
class LoggerQueue(queue.Queue):
""" Queue that logs whatever is put() to it.
"""
def textline_logger(target_fn):
def func(self, *args, **kwargs):
if args[0][0][0] == "text":
logging.info(str(args[0][0][1]))
else:
logging.info(str(args[0]))
return target_fn(self, *args, **kwargs)
return func
@textline_logger
def put(self, *args, **kwargs):
"""
could easily log here instead of the complex decorator pattern
but this is for fun
"""
super(LoggerQueue, self).put(*args, **kwargs)
text_lines = LoggerQueue()
# some issue when writing from submodules, maybe related to file handle, doubt it
# here we make the file, which may make the handle accessible? worth a shot
logging.debug("Initating logfile.")
# TODO: this doesn't seem to work? or if it does, it isn't clean...
game_state.quit_event = (
threading.Event()
) # set this flag with quit_event.set() to quit from main thread
# this should probably be initialized in game_state or something
# we should probably try to reacquire a socket if we lose it
gamesock, game_state.lichprocess = setup_game_connection.game_connection_controller(
game_state, character
)
preprocess_lines_thread = threading.Thread(
target=text_processing.preprocess_tcp_lines,
args=(game_state, tcp_lines, preprocessed_lines),
)
preprocess_lines_thread.daemon = True
preprocess_lines_thread.start()
process_lines_thread = threading.Thread(
target=text_processing.process_lines,
args=(preprocessed_lines, text_lines, game_state),
)
process_lines_thread.daemon = True
process_lines_thread.start()
tcp_thread = threading.Thread(
target=get_tcp_lines.get_tcp_lines,
args=(tcp_lines, gamesock, game_state.BUFSIZE, game_state.TCP_BUFFER_SLEEP),
)
tcp_thread.daemon = True
tcp_thread.start()
command_queue_thread = threading.Thread(
target=command_processing.process_command_queue,
args=(game_state, tcp_lines, gamesock, game_state.COMMAND_PROCESSING_SPEED),
)
command_queue_thread.daemon = True
command_queue_thread.start()
gametime_thread = threading.Thread(
target=gametime_incrementor.gametime_incrementer, args=(game_state,)
)
gametime_thread.daemon = True
gametime_thread.start()
# start the UI and UI refresh thread
# urwid must have its own time.sleep somewhere in its loop, since it doesn't dominate everything
urwid_ui.urwid_main(
game_state, text_lines, game_state.SCREEN_REFRESH_SPEED
)
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Specify startup parameters.")
parser.add_argument(
"-c",
"--character",
dest="character",
help="Start directly into a character.",
type=str,
required=False,
)
args = parser.parse_args()
try:
main(args.character)
except KeyboardInterrupt:
print("Exiting gracefully through either ctrl-c or game exit/quit command.")