annotate pytouhou/network.py @ 485:c099802e2435

Improve network latency by increasing game latency to 3 frames.
author Thibaut Girka <thib@sitedethib.com>
date Sun, 15 Jan 2012 15:36:23 +0100
parents 699c8e8c7738
children 711c75115675
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
1 import socket
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
2 import struct
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
3 from select import select
483
216107767b8a Remove useless checksum, and wait as long as possible for valid packets (do not stop waiting on invalid packets)
Thibaut Girka <thib@sitedethib.com>
parents: 482
diff changeset
4 import time
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
5
485
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
6 MSG_STRUCT = struct.Struct('!HHH')
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
7
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
8 class Network(object):
479
1de67f332f00 Fix several synchro issues
Thibaut Girka <thib@sitedethib.com>
parents: 478
diff changeset
9 def __init__(self, port=8080, dest=None, selected_player=0):
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
10 self.frame = 0
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
11 self.keystate = 0
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
12 self.old_keystate = 0
485
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
13 self.remote_keystate = 0
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
14
479
1de67f332f00 Fix several synchro issues
Thibaut Girka <thib@sitedethib.com>
parents: 478
diff changeset
15 self.selected_player = selected_player
1de67f332f00 Fix several synchro issues
Thibaut Girka <thib@sitedethib.com>
parents: 478
diff changeset
16
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
17 self.remote_addr = dest
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
18 self.sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
19 self.sock.bind(('', port))
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
20
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
21
484
699c8e8c7738 Don't stick with the remote user unless the game has started, avoid skipping to prevent desynchro
Thibaut Girka <thib@sitedethib.com>
parents: 483
diff changeset
22 def read_message(self):
699c8e8c7738 Don't stick with the remote user unless the game has started, avoid skipping to prevent desynchro
Thibaut Girka <thib@sitedethib.com>
parents: 483
diff changeset
23 message = None
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
24
483
216107767b8a Remove useless checksum, and wait as long as possible for valid packets (do not stop waiting on invalid packets)
Thibaut Girka <thib@sitedethib.com>
parents: 482
diff changeset
25 start_time = time.time()
216107767b8a Remove useless checksum, and wait as long as possible for valid packets (do not stop waiting on invalid packets)
Thibaut Girka <thib@sitedethib.com>
parents: 482
diff changeset
26 delta = 1./60.
216107767b8a Remove useless checksum, and wait as long as possible for valid packets (do not stop waiting on invalid packets)
Thibaut Girka <thib@sitedethib.com>
parents: 482
diff changeset
27
216107767b8a Remove useless checksum, and wait as long as possible for valid packets (do not stop waiting on invalid packets)
Thibaut Girka <thib@sitedethib.com>
parents: 482
diff changeset
28 rlist, wlist, xlist = select([self.sock], [], [], delta)
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
29 while rlist:
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
30 msg, addr = rlist[0].recvfrom(MSG_STRUCT.size)
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
31 # Check whether the message comes from the right address
484
699c8e8c7738 Don't stick with the remote user unless the game has started, avoid skipping to prevent desynchro
Thibaut Girka <thib@sitedethib.com>
parents: 483
diff changeset
32 if self.frame == 0 or addr == self.remote_addr:
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
33 self.remote_addr = addr
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
34
483
216107767b8a Remove useless checksum, and wait as long as possible for valid packets (do not stop waiting on invalid packets)
Thibaut Girka <thib@sitedethib.com>
parents: 482
diff changeset
35 frame, keystate, old_keystate = MSG_STRUCT.unpack(msg)
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
36
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
37 # Check for well-formedness
483
216107767b8a Remove useless checksum, and wait as long as possible for valid packets (do not stop waiting on invalid packets)
Thibaut Girka <thib@sitedethib.com>
parents: 482
diff changeset
38 if frame in (self.frame, self.frame + 1):
484
699c8e8c7738 Don't stick with the remote user unless the game has started, avoid skipping to prevent desynchro
Thibaut Girka <thib@sitedethib.com>
parents: 483
diff changeset
39 message = (frame, keystate, old_keystate)
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
40 else:
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
41 print('Mismatch', self.remote_addr, addr)
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
42
484
699c8e8c7738 Don't stick with the remote user unless the game has started, avoid skipping to prevent desynchro
Thibaut Girka <thib@sitedethib.com>
parents: 483
diff changeset
43 # If no valid message has been read, wait for one as long as possible
699c8e8c7738 Don't stick with the remote user unless the game has started, avoid skipping to prevent desynchro
Thibaut Girka <thib@sitedethib.com>
parents: 483
diff changeset
44 # else, read as much as we can without blocking.
699c8e8c7738 Don't stick with the remote user unless the game has started, avoid skipping to prevent desynchro
Thibaut Girka <thib@sitedethib.com>
parents: 483
diff changeset
45 delta = 0 if message else max(0, 1./60. - (time.time() - start_time))
483
216107767b8a Remove useless checksum, and wait as long as possible for valid packets (do not stop waiting on invalid packets)
Thibaut Girka <thib@sitedethib.com>
parents: 482
diff changeset
46 rlist, wlist, xlist = select(rlist, [], [], delta)
216107767b8a Remove useless checksum, and wait as long as possible for valid packets (do not stop waiting on invalid packets)
Thibaut Girka <thib@sitedethib.com>
parents: 482
diff changeset
47
484
699c8e8c7738 Don't stick with the remote user unless the game has started, avoid skipping to prevent desynchro
Thibaut Girka <thib@sitedethib.com>
parents: 483
diff changeset
48 return message
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
49
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
50
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
51 def send_message(self):
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
52 frame, keystate, old_keystate = self.frame, self.keystate, self.old_keystate
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
53 if self.remote_addr is not None:
483
216107767b8a Remove useless checksum, and wait as long as possible for valid packets (do not stop waiting on invalid packets)
Thibaut Girka <thib@sitedethib.com>
parents: 482
diff changeset
54 self.sock.sendto(MSG_STRUCT.pack(frame, keystate, old_keystate), self.remote_addr)
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
55
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
56
479
1de67f332f00 Fix several synchro issues
Thibaut Girka <thib@sitedethib.com>
parents: 478
diff changeset
57 def run_game_iter(self, game, keystate, other_keystate):
1de67f332f00 Fix several synchro issues
Thibaut Girka <thib@sitedethib.com>
parents: 478
diff changeset
58 keystates = [other_keystate, other_keystate]
1de67f332f00 Fix several synchro issues
Thibaut Girka <thib@sitedethib.com>
parents: 478
diff changeset
59 keystates[self.selected_player] = keystate
1de67f332f00 Fix several synchro issues
Thibaut Girka <thib@sitedethib.com>
parents: 478
diff changeset
60 game.run_iter(keystates)
1de67f332f00 Fix several synchro issues
Thibaut Girka <thib@sitedethib.com>
parents: 478
diff changeset
61
1de67f332f00 Fix several synchro issues
Thibaut Girka <thib@sitedethib.com>
parents: 478
diff changeset
62
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
63 def run_iter(self, game, keystate):
485
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
64 if game.frame % 3 == 0:
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
65 # Phase 1: Update game with old data
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
66 self.run_game_iter(game, self.keystate, self.remote_keystate)
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
67 elif game.frame % 3 == 1:
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
68 # Phase 2: Update data, send new data, update game with old data
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
69 self.old_keystate, self.keystate = self.keystate, keystate
485
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
70 self.frame = game.frame // 3
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
71 self.send_message()
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
72 self.run_game_iter(game, self.old_keystate, self.remote_keystate)
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
73 elif game.frame % 3 == 2:
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
74 # Phase 3: Send new data, get remote data, update game with new data
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
75 self.send_message()
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
76 # Follow one valid update
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
77 message = self.read_message()
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
78 if message:
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
79 frame, keystate, old_keystate = message
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
80 if frame == self.frame:
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
81 self.remote_keystate = keystate
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
82 elif frame == self.frame + 1:
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
83 self.remote_keystate = old_keystate
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
84 else:
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
85 raise Exception #TODO
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
86 self.run_game_iter(game, self.keystate, self.remote_keystate)
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
87 elif game.frame > 2:
c099802e2435 Improve network latency by increasing game latency to 3 frames.
Thibaut Girka <thib@sitedethib.com>
parents: 484
diff changeset
88 print('ARGH')
480
d666856acb52 Hopefully improve performance
Thibaut Girka <thib@sitedethib.com>
parents: 479
diff changeset
89
475
9d4d52793eca Experimental netplay! Yay!
Thibaut Girka <thib@sitedethib.com>
parents:
diff changeset
90