a1ab013f50a3dce6f8c4b46ed6ad5aeac9a2acc3
[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(Player):
8         def __init__(self, colour, address = (None,4562), baseplayer = None):
9                 
10                 if baseplayer != None:
11                         name = baseplayer.name + " --> @network"
12                 else:
13                         name = "<-- @network"
14                 
15                 
16                                 
17                 Player.__init__(self, name, colour)
18                 debug("Colour is " + str(self.colour))
19                 
20                 self.socket = socket.socket()
21                 self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
22                 self.baseplayer = baseplayer
23                 #self.socket.setblocking(0)
24                 
25                 self.address = address
26                 self.server = (address[0] == None)
27
28                 if self.colour == "black":
29                         self.address = (self.address[0], self.address[1] + 1)
30                                 
31                 debug(str(self) + ":"+str(self.address))
32                 
33                 self.board = None
34                         
35                         
36         def connect(self):      
37                 if self.address[0] == None:
38                         self.host = "0.0.0.0" #socket.gethostname() # Breaks things???
39                         self.socket.bind((self.host, self.address[1]))
40                         self.socket.listen(5)   
41
42                         self.src, self.actual_address = self.socket.accept()
43                         
44                         self.src.send("ok\n")
45                         s = self.get_response()
46                         if s == "QUIT":
47                                 self.src.close()
48                                 return
49                         elif s != "ok":
50                                 self.src.close()
51                                 self.__init__(colour, (self.address[0], int(s)), baseplayer)
52                                 return
53                         
54                 else:
55                         self.socket.connect(self.address)
56                         self.src = self.socket
57                         self.src.send("ok\n")
58                         s = self.get_response()
59                         if s == "QUIT":
60                                 self.src.close()
61                                 return
62                         elif s != "ok":
63                                 self.src.close()
64                                 self.__init__(colour, (self.address[0], int(s)), baseplayer)
65                                 return
66                         
67
68         def select(self):
69                 if self.baseplayer != None:
70                         s = self.baseplayer.select()
71                         self.send_message(str(s[0]) + " " + str(s[1]))
72                         return s
73                 return map(int,self.get_response().split(" "))
74         
75         def get_move(self):
76                 if self.baseplayer != None:
77                         s = self.baseplayer.get_move()
78                         self.send_message(str(s[0]) + " " + str(s[1]))
79                         return s
80                 return map(int,self.get_response().split(" "))
81         
82         def update(self, result):
83                 if self.baseplayer != None:
84                         result = self.baseplayer.update(result)
85                         self.send_message(result)
86                         return result
87                 if self.server:
88                         self.send_message(result)
89                 else:
90                         s = self.get_response()
91                         if self.board != None:
92                                 self.board.update(s)
93                         
94         def __str__(self):
95                 return "Network<"+str(self.colour)+","+str(self.baseplayer)+">:"+str(self.address)
96
97         def get_response(self):
98                 debug(str(self) + " get_response called...")
99                 # Timeout the start of the message (first character)
100                 if network_timeout_start > 0.0:
101                         ready = select.select([self.src], [], [], network_timeout_start)[0]
102                 else:
103                         ready = [self.src]
104                 if self.src in ready:
105                         s = self.src.recv(1)
106                 else:
107                         raise Exception("UNRESPONSIVE")
108
109
110                 while s[len(s)-1] != '\n':
111                         # Timeout on each character in the message
112                         if network_timeout_delay > 0.0:
113                                 ready = select.select([self.src], [], [], network_timeout_delay)[0]
114                         else:
115                                 ready = [self.src]
116                         if self.src in ready:
117                                 s += self.src.recv(1) 
118                         else:
119                                 raise Exception("UNRESPONSIVE")
120
121                 debug(str(self) + " get_response returns " + s.strip(" \r\n"))
122                 return s.strip(" \r\n")
123
124         def send_message(self,s):
125                 if network_timeout_start > 0.0:
126                         ready = select.select([], [self.src], [], network_timeout_start)[1]
127                 else:
128                         ready = [self.src]
129
130                 if self.src in ready:
131                         self.src.send(s + "\n")
132                 else:
133                         raise Exception("UNRESPONSIVE")
134                 
135                 debug(str(self) + " send_message sent " + s)
136
137         def check_quit(self, s):
138                 s = s.split(" ")
139                 if s[0] == "QUIT":
140                         with game.lock:
141                                 game.final_result = " ".join(s[1:]) + " " + str(opponent(self.colour))
142                         game.stop()
143                         return True
144                         
145         def quit(self, result):
146                 if self.baseplayer != None:
147                         self.send_message("QUIT")
148                         
149                 with game.lock:
150                         game.final_result = result
151                 game.stop()     
152
153
154
155
156                 

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