changeset 487:711c75115675

Various netplay-related fixes.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Sat, 28 Sep 2013 20:11:41 +0200
parents 2f53be1b2f60
children 791faab05445
files eosd pytouhou/game/game.pyx pytouhou/games/eosd.py pytouhou/network.py pytouhou/ui/gamerunner.pyx
diffstat 5 files changed, 33 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/eosd
+++ b/eosd
@@ -46,7 +46,7 @@ parser.add_argument('--no-music', action
 parser.add_argument('--hints', metavar='HINTS', default=None, help='Hints file, to display text while playing.')
 parser.add_argument('--verbosity', metavar='VERBOSITY', choices=['DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'], help='Select the wanted logging level.')
 parser.add_argument('--game', metavar='GAME', choices=['EoSD'], default='EoSD', help='Select the game engine to use.')
-parser.add_argument('--port', metavar='PORT', type=int, default=0, help='Port to use for netplay')
+parser.add_argument('--port', metavar='PORT', type=int, default=0, help='Local port to use for netplay')
 parser.add_argument('--remote', metavar='REMOTE', default=None, help='Remote address')
 
 args = parser.parse_args()
@@ -139,9 +139,10 @@ def main(window, path, data, stage_num, 
         save_replay.rank = rank
         save_replay.character = character
 
+    difficulty = 16
+    default_power = [0, 64, 128, 128, 128, 128, 0][stage_num - 1]
+
     if port != 0:
-        players = [PlayerState(character=0), PlayerState(character=2)]
-
         if remote:
             remote_addr, remote_port = remote.split(':')
             addr = remote_addr, int(remote_port)
@@ -152,20 +153,20 @@ def main(window, path, data, stage_num, 
 
         prng = Random(0)
         con = Network(port, addr, selected_player)
+        states = [PlayerState(character=1, power=default_power, continues=continues),
+                  PlayerState(character=3, power=default_power, continues=continues)]
     else:
         con = None
+        selected_player = 0
+        states = [PlayerState(character=character, power=default_power, continues=continues)]
 
     if hints:
         with open(hints, 'rb') as file:
             hints = Hint.read(file)
 
-    difficulty = 16
-    default_power = [0, 64, 128, 128, 128, 128, 0][stage_num - 1]
-    states = [PlayerState(character=character, power=default_power, continues=continues)]
-
     game_class = GameBossRush if boss_rush else Game
 
-    common = Common(resource_loader)
+    common = Common(resource_loader, states[selected_player])
     runner = GameRunner(window, resource_loader, skip=skip_replay, con=con)
     while True:
         if replay:
--- a/pytouhou/game/game.pyx
+++ b/pytouhou/game/game.pyx
@@ -179,7 +179,6 @@ cdef class Game:
         cdef Player player
         cdef Bullet bullet
 
-        player = self.players[0] #TODO
         score = 0
         bonus = 2000
         for bullet in self.bullets:
@@ -187,9 +186,12 @@ cdef class Game:
             score += bonus
             bonus += 10
         self.bullets = []
-        player.state.score += score
         #TODO: display the final bonus score.
 
+        #TODO: do we really want to give it to each player?
+        for player in self.players:
+            player.state.score += score
+
 
     cpdef kill_enemies(self):
         cdef Enemy enemy
--- a/pytouhou/games/eosd.py
+++ b/pytouhou/games/eosd.py
@@ -28,7 +28,7 @@ from pytouhou.vm.eclrunner import ECLMai
 
 
 class EoSDCommon(object):
-    def __init__(self, resource_loader):
+    def __init__(self, resource_loader, player_state):
         self.etama = resource_loader.get_multi_anm(('etama3.anm', 'etama4.anm'))
         self.bullet_types = [BulletType(self.etama[0], 0, 11, 14, 15, 16, hitbox_size=2,
                                         type_id=0),
@@ -75,7 +75,7 @@ class EoSDCommon(object):
                            ('face08a.anm', 'face12a.anm', 'face12b.anm', 'face12c.anm')]
 
         self.characters = resource_loader.get_eosd_characters()
-        self.interface = EoSDInterface(resource_loader)
+        self.interface = EoSDInterface(resource_loader, player_state)
 
 
 
@@ -129,8 +129,9 @@ class EoSDGame(Game):
 
 
 class EoSDInterface(object):
-    def __init__(self, resource_loader):
+    def __init__(self, resource_loader, player_state):
         self.game = None
+        self.player_state = player_state
         front = resource_loader.get_single_anm('front.anm')
         self.ascii_anm = resource_loader.get_single_anm('ascii.anm')
 
@@ -221,7 +222,7 @@ class EoSDInterface(object):
             if elem.removed: #XXX
                 self.level_start = []
 
-        player_state = self.game.players[0].state
+        player_state = self.player_state
 
         self.highscore = max(self.highscore, player_state.effective_score)
         self.labels['highscore'].set_text('%09d' % self.highscore)
--- a/pytouhou/network.py
+++ b/pytouhou/network.py
@@ -1,9 +1,13 @@
 import socket
-import struct
+from struct import Struct
 from select import select
-import time
+from time import time
+
+from pytouhou.utils.helpers import get_logger
 
-MSG_STRUCT = struct.Struct('!HHH')
+logger = get_logger(__name__)
+
+MSG_STRUCT = Struct('!HHH')
 
 class Network(object):
     def __init__(self, port=8080, dest=None, selected_player=0):
@@ -22,10 +26,10 @@ class Network(object):
     def read_message(self):
         message = None
 
-        start_time = time.time()
+        start_time = time()
         delta = 1./60.
 
-        rlist, wlist, xlist = select([self.sock], [], [], delta)
+        rlist, _, _ = select([self.sock], [], [], delta)
         while rlist:
             msg, addr = rlist[0].recvfrom(MSG_STRUCT.size)
             # Check whether the message comes from the right address
@@ -38,20 +42,19 @@ class Network(object):
                 if frame in (self.frame, self.frame + 1):
                     message = (frame, keystate, old_keystate)
             else:
-                print('Mismatch', self.remote_addr, addr)
+                logger.error('Mismatch, got a message from %s, waiting for %s.', self.remote_addr, addr)
 
             # If no valid message has been read, wait for one as long as possible
             # else, read as much as we can without blocking.
-            delta = 0 if message else max(0, 1./60. - (time.time() - start_time))
-            rlist, wlist, xlist = select(rlist, [], [], delta)
+            delta = 0 if message else max(0, 1./60. - (time() - start_time))
+            rlist, _, _ = select(rlist, [], [], delta)
 
         return message
 
 
     def send_message(self):
-        frame, keystate, old_keystate = self.frame, self.keystate, self.old_keystate
         if self.remote_addr is not None:
-            self.sock.sendto(MSG_STRUCT.pack(frame, keystate, old_keystate), self.remote_addr)
+            self.sock.sendto(MSG_STRUCT.pack(self.frame, self.keystate, self.old_keystate), self.remote_addr)
 
 
     def run_game_iter(self, game, keystate, other_keystate):
@@ -85,6 +88,6 @@ class Network(object):
                     raise Exception #TODO
                 self.run_game_iter(game, self.keystate, self.remote_keystate)
             elif game.frame > 2:
-                print('ARGH')
+                logger.warn('Message not received in time, dropping frame.')
 
 
--- a/pytouhou/ui/gamerunner.pyx
+++ b/pytouhou/ui/gamerunner.pyx
@@ -134,7 +134,7 @@ cdef class GameRunner(Runner):
             if self.save_keystates is not None:
                 self.save_keystates.append(keystate)
 
-            if self.con:
+            if self.con is not None:
                 self.con.run_iter(self.game, keystate)
             else:
                 self.game.run_iter([keystate])