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
|
#! /usr/bin/python3
import json
import sys
import termios
import tty
import signal
import getpass
import hashlib
import base64
from .connection import Connection
from .gameclient import Client
from .display import Display
from .parseargs import parse_args
from ratuil.screen import Screen
from asciifarmclient.common import messages
def main(argv=None):
(name, socketType, address, keybindings, characters, colours, logfile, ratuil_args) = parse_args(argv)
connection = Connection(socketType)
try:
connection.connect(address)
except ConnectionRefusedError:
print("ERROR: Could not connect to server.\nAre you sure that the server is running and that you're connecting to the right address?", file=sys.stderr)
return
if not introduce(connection, name):
return
error = None
closeMessage = None
#os.environ.setdefault("ESCDELAY", "25")
fd = sys.stdin.fileno()
oldterm = termios.tcgetattr(fd)
try:
tty.setraw(sys.stdin)
Screen.default.hide_cursor()
display = Display(characters, ratuil_args)
client = Client(display, name, connection, keybindings, logfile)
signal.signal(signal.SIGWINCH, client.onSigwinch)
try:
client.start()
except KeyboardInterrupt:
client.close("^C caught, goodbye")
except Exception as e:
# throw the execption outside ncurses
# so the cleanup can happen first
error = e
closeMessage = client.closeMessage
finally:
## Set everything back to normal
termios.tcsetattr(fd, termios.TCSADRAIN, oldterm)
Screen.default.finalize()
if error is not None:
raise error
if closeMessage:
print(closeMessage, file=sys.stderr)
def introduce(connection, name):
connection.send(messages.NameMessage(name))
print("introducing to server as {}".format(name))
response = connection.receive()
if response is None:
print("connection lost")
return False
if isinstance(response, messages.ConnectedMessage):
print("connection successful")
return True
if isinstance(response, messages.MessageMessage):
return response.type == "connect"
if isinstance(response, messages.ErrorMessage):
if response.errType == "registered":
print("'{}' is a registered name. Enter password to login, or restart the client with the -n <name> option to choose a different name".format(name))
password = getpass.getpass()
m = hashlib.sha256()
m.update(bytes("asciifarm{name}{pw}{name}asciifarm".format(name=name, pw=password), "utf-8"))
passbytes = m.digest()
passtoken = base64.b64encode(passbytes).decode("ascii")
connection.send(messages.AuthMessage(name, passtoken))
response = connection.receive()
if response is None:
print("connection lost")
return False
if isinstance(response, messages.ConnectedMessage):
print("connection successful")
return True
print("Connection unsuccessful: {}".format(response.to_json()))
return False
else:
print("Error: {}".format(response.to_json()), file=sys.stderr)
return False
print("Invalid server response: {}".format(response.to_json()), file=sys.stderr)
return False
|