Actually commit stuff from ages ago
[progcomp2013.git] / qchess / src / network.py
1 import socket
2 import select
3
4 network_timeout_start = -1.0 # Timeout in seconds to wait for the start of a message
5 network_timeout_delay = 1.0 # Maximum time between two characters being received
6
7 class Network():
8         def __init__(self, colour, address = None):
9                 self.socket = socket.socket()
10                 #self.socket.setblocking(0)
11
12                 if colour == "white":
13                         self.port = 4562
14                 else:
15                         self.port = 4563
16
17                 self.src = None
18
19         #       print str(self) + " listens on port " + str(self.port)
20
21                 if address == None:
22                         self.host = socket.gethostname()
23                         self.socket.bind((self.host, self.port))
24                         self.socket.listen(5)   
25
26                         self.src, self.address = self.socket.accept()
27                         self.src.send("ok\n")
28                         if self.get_response() == "QUIT":
29                                 self.src.close()
30                 else:
31                         self.host = address
32                         self.socket.connect((address, self.port))
33                         self.src = self.socket
34                         self.src.send("ok\n")
35                         if self.get_response() == "QUIT":
36                                 self.src.close()
37
38         def get_response(self):
39                 # Timeout the start of the message (first character)
40                 if network_timeout_start > 0.0:
41                         ready = select.select([self.src], [], [], network_timeout_start)[0]
42                 else:
43                         ready = [self.src]
44                 if self.src in ready:
45                         s = self.src.recv(1)
46                 else:
47                         raise Exception("UNRESPONSIVE")
48
49
50                 while s[len(s)-1] != '\n':
51                         # Timeout on each character in the message
52                         if network_timeout_delay > 0.0:
53                                 ready = select.select([self.src], [], [], network_timeout_delay)[0]
54                         else:
55                                 ready = [self.src]
56                         if self.src in ready:
57                                 s += self.src.recv(1) 
58                         else:
59                                 raise Exception("UNRESPONSIVE")
60
61                 return s.strip(" \r\n")
62
63         def send_message(self,s):
64                 if network_timeout_start > 0.0:
65                         ready = select.select([], [self.src], [], network_timeout_start)[1]
66                 else:
67                         ready = [self.src]
68
69                 if self.src in ready:
70                         self.src.send(s + "\n")
71                 else:
72                         raise Exception("UNRESPONSIVE")
73
74         def check_quit(self, s):
75                 s = s.split(" ")
76                 if s[0] == "QUIT":
77                         with game.lock:
78                                 game.final_result = " ".join(s[1:]) + " " + str(opponent(self.colour))
79                         game.stop()
80                         return True
81
82                 
83
84 class NetworkSender(Player,Network):
85         def __init__(self, base_player, address = None):
86                 self.base_player = base_player
87                 Player.__init__(self, base_player.name, base_player.colour)
88
89                 self.address = address
90
91         def connect(self):
92                 Network.__init__(self, self.base_player.colour, self.address)
93
94
95
96         def select(self):
97                 [x,y] = self.base_player.select()
98                 choice = self.board.grid[x][y]
99                 s = str(x) + " " + str(y)
100                 #print str(self) + ".select sends " + s
101                 self.send_message(s)
102                 return [x,y]
103
104         def get_move(self):
105                 [x,y] = self.base_player.get_move()
106                 s = str(x) + " " + str(y)
107                 #print str(self) + ".get_move sends " + s
108                 self.send_message(s)
109                 return [x,y]
110
111         def update(self, s):
112                 self.base_player.update(s)
113                 s = s.split(" ")
114                 [x,y] = map(int, s[0:2])
115                 selected = self.board.grid[x][y]
116                 if selected != None and selected.colour == self.colour and len(s) > 2 and not "->" in s:
117                         s = " ".join(s[0:3])
118                         for i in range(2):
119                                 if selected.types_revealed[i] == True:
120                                         s += " " + str(selected.types[i])
121                                 else:
122                                         s += " unknown"
123                         #print str(self) + ".update sends " + s
124                         self.send_message(s)
125                                 
126
127         def quit(self, final_result):
128                 self.base_player.quit(final_result)
129                 #self.src.send("QUIT " + str(final_result) + "\n")
130                 self.src.close()
131
132 class NetworkReceiver(Player,Network):
133         def __init__(self, colour, address=None):
134                 
135                 Player.__init__(self, address, colour)
136
137                 self.address = address
138
139                 self.board = None
140
141         def connect(self):
142                 Network.__init__(self, self.colour, self.address)
143                         
144
145         def select(self):
146                 
147                 s = self.get_response()
148                 #print str(self) + ".select gets " + s
149                 [x,y] = map(int,s.split(" "))
150                 if x == -1 and y == -1:
151                         #print str(self) + ".select quits the game"
152                         with game.lock:
153                                 game.final_state = "network terminated " + self.colour
154                         game.stop()
155                 return [x,y]
156         def get_move(self):
157                 s = self.get_response()
158                 #print str(self) + ".get_move gets " + s
159                 [x,y] = map(int,s.split(" "))
160                 if x == -1 and y == -1:
161                         #print str(self) + ".get_move quits the game"
162                         with game.lock:
163                                 game.final_state = "network terminated " + self.colour
164                         game.stop()
165                 return [x,y]
166
167         def update(self, result):
168                 
169                 result = result.split(" ")
170                 [x,y] = map(int, result[0:2])
171                 selected = self.board.grid[x][y]
172                 if selected != None and selected.colour == self.colour and len(result) > 2 and not "->" in result:
173                         s = self.get_response()
174                         #print str(self) + ".update - receives " + str(s)
175                         s = s.split(" ")
176                         selected.choice = int(s[2])
177                         for i in range(2):
178                                 selected.types[i] = str(s[3+i])
179                                 if s[3+i] == "unknown":
180                                         selected.types_revealed[i] = False
181                                 else:
182                                         selected.types_revealed[i] = True
183                         selected.current_type = selected.types[selected.choice] 
184                 else:
185                         pass
186                         #print str(self) + ".update - ignore result " + str(result)                     
187                 
188
189         def quit(self, final_result):
190                 self.src.close()
191         

UCC git Repository :: git.ucc.asn.au