Mercurial > touhou
comparison pytouhou/network.py @ 475:9d4d52793eca
Experimental netplay! Yay!
author | Thibaut Girka <thib@sitedethib.com> |
---|---|
date | Wed, 28 Dec 2011 18:45:09 +0100 |
parents | |
children | e71b1bcf952a |
comparison
equal
deleted
inserted
replaced
228:8f4cd1c01d22 | 475:9d4d52793eca |
---|---|
1 import socket | |
2 import struct | |
3 from select import select | |
4 | |
5 MSG_STRUCT = struct.Struct('!IHHB') | |
6 | |
7 class Network(object): | |
8 def __init__(self, port=8080, dest=None): | |
9 self.frame = 0 | |
10 self.keystate = 0 | |
11 self.old_keystate = 0 | |
12 | |
13 self.remote_addr = dest | |
14 self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) | |
15 self.sock.setblocking(0) | |
16 self.sock.bind(('', port)) | |
17 | |
18 | |
19 def read_messages(self): | |
20 messages = [] | |
21 | |
22 rlist, wlist, xlist = select([self.sock], [], [], 0) | |
23 while rlist: | |
24 msg, addr = rlist[0].recvfrom(MSG_STRUCT.size) | |
25 # Check whether the message comes from the right address | |
26 if self.remote_addr is None or addr == self.remote_addr: | |
27 self.remote_addr = addr | |
28 | |
29 frame, keystate, old_keystate, checksum = MSG_STRUCT.unpack(msg) | |
30 | |
31 # Check for well-formedness | |
32 if checksum == sum(ord(c) for c in msg[:-1]) & 0xFF: | |
33 messages.append((frame, keystate, old_keystate, checksum)) | |
34 else: | |
35 print('Mismatch', self.remote_addr, addr) | |
36 | |
37 rlist, wlist, xlist = select(rlist, [], [], 0) | |
38 | |
39 return messages | |
40 | |
41 | |
42 def send_message(self): | |
43 frame, keystate, old_keystate = self.frame, self.keystate, self.old_keystate | |
44 if self.remote_addr is not None: | |
45 checksum = frame + (frame >> 8) + (frame >> 16) + (frame >> 24) | |
46 checksum += keystate + (keystate >> 8) | |
47 checksum += old_keystate + (old_keystate >> 8) | |
48 checksum &= 0xFF | |
49 self.sock.sendto(MSG_STRUCT.pack(frame, keystate, old_keystate, checksum), self.remote_addr) | |
50 | |
51 | |
52 def run_iter(self, game, keystate): | |
53 if self.frame < game.frame: | |
54 self.old_keystate, self.keystate = self.keystate, keystate | |
55 self.frame = game.frame | |
56 | |
57 for frame, keystate, old_keystate, checksum in self.read_messages(): | |
58 if frame == game.frame: | |
59 game.run_iter([self.keystate, keystate]) | |
60 elif frame == game.frame + 1: | |
61 print('Skipped') | |
62 game.run_iter([self.keystate, old_keystate]) | |
63 game.run_iter([self.keystate, keystate]) | |
64 | |
65 self.send_message() | |
66 |