-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient.py
More file actions
135 lines (120 loc) · 3.24 KB
/
client.py
File metadata and controls
135 lines (120 loc) · 3.24 KB
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
# Based on https://www.bogotobogo.com/python/python_network_programming_tcp_server_client_chat_server_chat_client_select.php
import sys
import socket
import threading
import time
import json
from user import User
from model import DataModel
import display
model = DataModel()
waiting = 2
running = True
def start(host, port, name):
t1=threading.Thread(target=run_client, args=(host, port, name))
t1.start()
while waiting:
time.sleep(1)
print("Connected")
display.start_display(model)
global running
running = False
return
def run_client(host, port, name):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(2)
global model
global waiting
# connect to remote host
try:
sock.connect((host, port))
except:
print('Unable to connect')
sys.exit()
sock.settimeout(2)
sock.send(('@' + name + '$').encode())
while running:
# incoming message from remote server, s
try:
dataset = sock.recv(4096).decode()
if not dataset:
model.add_message('<Disconnected>')
model.quit = True
return
for data in dataset.split('$'):
if len(data) == 0:
continue
elif data[0] == "C":
# print message
r = int(data.split('&')[0][1:])
if r == model.me.room or r == -1:
model.add_message(data.split('&')[1])
elif data[0] == 'M':
# move user
data = data.split('&')
i = int(data[0][1:])
model.users[i].pos = int(data[1])
model.users[i].room = int(data[2])
elif data[0] == 'N':
# change username
print('That name is invalid or already taken')
name = input('Try a different name: ')
sock.send(('@' + name).encode())
elif data[0] == "J":
# add user
user = User(data[1:])
model.users[user.index] = user
model.refresh()
model.add_message("<%s Joined the server>" % user.name)
elif data[0] == "U":
# add existing users
user = User(data[1:])
model.users[user.index] = user
if user.name == name and model.me == None:
model.add_message(name + ' connected to server')
model.me = user
user.avatar = '@'
waiting -= 1
model.refresh()
elif data[0] == "L":
# remove user
i = int(data[1:])
if i == model.me.index:
model.add_message('<Disconnected>')
model.quit = True
return
name = model.users[i].name
del model.users[i]
model.refresh()
model.add_message("<%s Left the server>" % name)
elif data[0] == "D" and waiting:
# load map details
try:
model.hall.deserialize(data)
except json.decoder.JSONDecodeError:
print("Network error: please close and try again")
model.quit = True
return
waiting -= 1
except socket.timeout:
while not model.send.empty():
sock.send(model.send.get().encode())
if model.moved:
sock.send(("M%d&%d&%d$" % (model.me.index, model.me.pos, model.me.room)).encode())
model.add_message('<Disconnected>')
model.quit = True
if __name__ == "__main__":
try:
name = ''
if(len(sys.argv) < 2):
print('Usage : python client.py <hostname> username')
sys.exit()
elif(len(sys.argv) < 3):
name = input('Enter username: ')
else:
name = sys.argv[2]
start(sys.argv[1], 1234, name)
sys.exit(0)
except KeyboardInterrupt:
print('\nInterrupted')
sys.exit(0)