-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclient_state_machine.py
216 lines (190 loc) · 8.87 KB
/
client_state_machine.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
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
"""
Created on Sun Apr 5 00:00:32 2015
@author: zhengzhang
"""
from chat_utils import *
import json
class ClientSM:
def __init__(self, s):
self.state = S_OFFLINE
self.peer = ''
self.me = ''
self.out_msg = ''
self.s = s
self.flag = 0
self.initiating = 0
self.colors = ['black','white']
self.chessboard = [[-1 for i in range(10)] for j in range(10)]
self.game_peer = ''
def set_state(self, state):
self.state = state
def get_state(self):
return self.state
def set_myname(self, name):
self.me = name
def get_myname(self):
return self.me
def connect_to(self, peer):
msg = json.dumps({"action":"connect", "target":peer})
mysend(self.s, msg)
response = json.loads(myrecv(self.s))
if response["status"] == "success":
self.peer = peer
self.out_msg += 'You are connected with '+ self.peer + '\n'
return (True)
elif response["status"] == "busy":
self.out_msg += 'User is busy. Please try again later\n'
elif response["status"] == "self":
self.out_msg += 'Cannot talk to yourself (sick)\n'
else:
self.out_msg += 'User is not online, try again later\n'
return(False)
def disconnect(self):
msg = json.dumps({"action":"disconnect"})
mysend(self.s, msg)
self.out_msg += 'You are disconnected from ' + self.peer + '\n'
self.peer = ''
def proc(self, my_msg, peer_msg):
self.out_msg = ''
#deal with invitations
if self.flag == 1:
if my_msg == 'y':
mysend(self.s, json.dumps({"action":"game_accept", "target":self.game_peer}))
self.initiating = 1
else:
mysend(self.s, json.dumps({"action":"game_reject", "target":self.game_peer}))
self.flag=0
return ''
#deal with game stuff
if my_msg[:5] == '/game':
operators = my_msg.split()
try:
if operators[1] == 'start':
if operators[2] == self.me:
raise Exception
else:
mysend(self.s, json.dumps({"action":"game_start", "target":operators[2]}))
elif operators[1] == 'move':
mysend(self.s, json.dumps({"action":"game_move", "x":operators[2], "y":operators[3],"target":self.game_peer}))
elif operators[1] == 'quit':
mysend(self.s, json.dumps({"action":"game_quit", "target":self.game_peer}))
else:
self.out_msg += "Invalid command\n"
except:
self.out_msg += 'Invalid command\n'
return self.out_msg
if len(peer_msg) > 0:
pm = json.loads(peer_msg)
if pm["action"] == "game_start":
self.out_msg += "starting game with {}, you are {}!".format(pm["from"],self.colors[self.initiating])
self.game_peer = pm["from"]
elif pm["action"] == "game_reject":
self.out_msg += '{} rejects your request\n'.format(pm["from"])
elif pm["action"] == "game_invite":
self.out_msg += "{} invite you to play game, do you want to join?(y/N)\n".format(pm["from"])
self.game_peer = pm["from"]
self.flag = 1
elif pm["action"] == "game_win":
self.game_peer == ''
self.out_msg += 'game ended, {} wins!\n'.format(pm["from"])
self.chessboard = [[-1 for i in range(10)] for j in range(10)]
elif pm["action"] == "game_move":
if pm["from"] == self.game_peer:
self.chessboard[int(pm["x"])][int(pm["y"])] = 1
else:
self.chessboard[int(pm["x"])][int(pm["y"])] = 0
self.out_msg += '{} placed on ({},{})'.format(pm["from"], pm["x"], pm["y"])
elif pm["action"] == "game_error":
self.out_msg += 'game error: ' + pm["status"]+'\n'
elif pm["action"] == "game_quit":
self.game_peer = ''
self.out_msg += 'game ended, {} quits!\n'.format(pm["from"])
self.chessboard = [[-1 for i in range(10)] for j in range(10)]
#==============================================================================
# Once logged in, do a few things: get peer listing, connect, search
# And, of course, if you are so bored, just go
# This is event handling instate "S_LOGGEDIN"
#==============================================================================
if self.state == S_LOGGEDIN:
# todo: can't deal with multiple lines yet
if len(my_msg) > 0:
if my_msg == 'q':
self.out_msg += 'See you next time!\n'
self.state = S_OFFLINE
elif my_msg == 'time':
mysend(self.s, json.dumps({"action":"time"}))
time_in = json.loads(myrecv(self.s))["results"]
self.out_msg += "Time is: " + time_in
elif my_msg == 'who':
mysend(self.s, json.dumps({"action":"list"}))
logged_in = json.loads(myrecv(self.s))["results"]
self.out_msg += 'Here are all the users in the system:\n'
self.out_msg += logged_in
elif my_msg[0] == 'c':
peer = my_msg[1:]
peer = peer.strip()
if self.connect_to(peer) == True:
self.state = S_CHATTING
self.out_msg += 'Connect to ' + peer + '. Chat away!\n\n'
self.out_msg += '-----------------------------------\n'
else:
self.out_msg += 'Connection unsuccessful\n'
elif my_msg[0] == '?':
term = my_msg[1:].strip()
mysend(self.s, json.dumps({"action":"search", "target":term}))
search_rslt = json.loads(myrecv(self.s))["results"].strip()
if (len(search_rslt)) > 0:
self.out_msg += search_rslt + '\n\n'
else:
self.out_msg += '\'' + term + '\'' + ' not found\n\n'
elif my_msg[0] == 'p' and my_msg[1:].isdigit():
poem_idx = my_msg[1:].strip()
mysend(self.s, json.dumps({"action":"poem", "target":poem_idx}))
poem = json.loads(myrecv(self.s))["results"]
# print(poem)
if (len(poem) > 0):
self.out_msg += poem + '\n\n'
else:
self.out_msg += 'Sonnet ' + poem_idx + ' not found\n\n'
else:
self.out_msg += menu
if len(peer_msg) > 0:
peer_msg = json.loads(peer_msg)
if peer_msg["action"] == "connect":
self.peer = peer_msg["from"]
self.out_msg += 'Request from ' + self.peer + '\n'
self.out_msg += 'You are connected with ' + self.peer
self.out_msg += '. Chat away!\n\n'
self.out_msg += '------------------------------------\n'
self.state = S_CHATTING
#==============================================================================
# Start chatting, 'bye' for quit
# This is event handling instate "S_CHATTING"
#==============================================================================
elif self.state == S_CHATTING:
if len(my_msg) > 0: # my stuff going out
mysend(self.s, json.dumps({"action":"exchange", "from":"[" + self.me + "]", "message":my_msg}))
if my_msg == 'bye':
self.disconnect()
self.state = S_LOGGEDIN
self.peer = ''
if len(peer_msg) > 0: # peer's stuff, coming in
peer_msg = json.loads(peer_msg)
if 'game' in peer_msg["action"]:
pass
elif peer_msg["action"] == "connect":
self.out_msg += "(" + peer_msg["from"] + " joined)\n"
elif peer_msg["action"] == "disconnect":
self.state = S_LOGGEDIN
else:
self.out_msg += peer_msg["from"] + peer_msg["message"]
# Display the menu again
if self.state == S_LOGGEDIN:
self.out_msg += menu
#==============================================================================
# invalid state
#==============================================================================
else:
self.out_msg += 'How did you wind up here??\n'
print_state(self.state)
return self.out_msg