changeset 45:a3a29126cb9a

merge
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sat, 07 Jul 2012 18:06:19 +0200
parents cad91d3c70be (current diff) 0df16f291a11 (diff)
children 02d26987c201
files zrpn/board.py zrpn/main.py
diffstat 12 files changed, 189 insertions(+), 60 deletions(-) [+]
line wrap: on
line diff
--- a/zrpn/board.py	Sat Jul 07 18:01:10 2012 +0200
+++ b/zrpn/board.py	Sat Jul 07 18:06:19 2012 +0200
@@ -75,6 +75,15 @@
                         killed += 1
                     count = 1
                 last_cell = cell
+            
+            if count >= GROUP_SIZE:
+                # x = column after the end of the line
+                x += 1
+                for i in xrange(x - count, x):
+                    self.board[y][i] = 0
+                    self.die((i, y), turn)
+                killed += 1
+
         for x, cell in enumerate(self.board[0]):
             last_cell = 0
             count = 1
--- a/zrpn/main.py	Sat Jul 07 18:01:10 2012 +0200
+++ b/zrpn/main.py	Sat Jul 07 18:06:19 2012 +0200
@@ -4,9 +4,12 @@
 import pygame
 import sys
 
+import pygame_network as net
+import pygame_network.event
+
 import board
 import display
-
+import packets
 
 class Game(object):
     def __init__(self):
@@ -28,8 +31,33 @@
                     self.display.do_animations(animations)
             self.display.frame()
 
+class Client(object):
+    def __init__(self, address, port):
+        self.display = None
+        self.connected = False
+        self.client = net.Client()
+        self.connection = self.client.connect(address, port)
+
+    def run(self):
+        while True:
+            for event in pygame.event.get():
+                if event.type == pygame.QUIT:
+                    sys.exit()
+                elif event.type == pygame.MOUSEBUTTONDOWN:
+                    x, y = event.pos[0] // 24, event.pos[1] // 24
+                    self.connection.net_click(x, y)
+                elif event.type == net.event.NETWORK:
+                    if event.net_type == net.event.NET_RECEIVED:
+                        if event.p_type == packets.INIT:
+                            self.display.Display(event.packet.board, event.packet.sprites)
+                        elif event.net_type == packets.ANIMATION:
+                            self.display.do_animations((event.packet,))
+            self.display.frame()
+            self.client.step()
+
 
 def main():
+    #Client('localhost', 10000).run()
     Game().run()
 
 if __name__ == '__main__':
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zrpn/packets.py	Sat Jul 07 18:06:19 2012 +0200
@@ -0,0 +1,4 @@
+import pygame_network as net
+INIT = net.register('init', ('board', 'sprites'))
+ANIMATION = net.register('animation', ('kind', 'sprite', 'delay'))
+CLICK = net.register('click', ('x', 'y'))
--- a/zrpn/pygame_network/__init__.py	Sat Jul 07 18:01:10 2012 +0200
+++ b/zrpn/pygame_network/__init__.py	Sat Jul 07 18:06:19 2012 +0200
@@ -1,6 +1,7 @@
 import packet
-import client
 import syncobject
+from client import Client
+from server import Server
+from receiver import Receiver
 
-import logging as _logging
-_logging.basicConfig(level=_logging.DEBUG)
+register = packet.PacketManager.register
--- a/zrpn/pygame_network/client.py	Sat Jul 07 18:01:10 2012 +0200
+++ b/zrpn/pygame_network/client.py	Sat Jul 07 18:06:19 2012 +0200
@@ -7,6 +7,14 @@
 
 
 class Client(object):
+    """Class representing network client
+
+    Example:
+        client = pygame_network.client.Client()
+        connection = client.connect("localhost", 10000)
+        while True:
+            client.step()
+    """
     def __init__(self, connections_limit=1, channel_limit=0, in_bandwidth=0, out_bandwidth=0):
         self.host = enet.Host(None, connections_limit, channel_limit, in_bandwidth, out_bandwidth)
         self._peers = {}
@@ -31,13 +39,13 @@
         event = host.service(timeout)
         while event is not None:
             if event.type == enet.EVENT_TYPE_CONNECT:
+                _logger.info('Connected to %s', event.peer.address)
                 self._peers[event.peer.data]._connect()
-                _logger.info('Connected to %s', event.peer.address)
             elif event.type == enet.EVENT_TYPE_DISCONNECT:
+                _logger.info('Disconnected from %s', event.peer.address)
                 self._peers[event.peer.data]._disconnect()
                 del self._peers[event.peer.data]
-                _logger.info('Disconnected from %s', event.peer.address)
             elif event.type == enet.EVENT_TYPE_RECEIVE:
+                _logger.info('Received data from %s', event.peer.address)
                 self._peers[event.peer.data]._receive(event.packet.data, event.channelID)
-                _logger.info('Received data from %s', event.peer.address)
             event = host.check_events()
--- a/zrpn/pygame_network/connection.py	Sat Jul 07 18:01:10 2012 +0200
+++ b/zrpn/pygame_network/connection.py	Sat Jul 07 18:06:19 2012 +0200
@@ -1,4 +1,16 @@
-from weakref import WeakKeyDictionary, proxy
+__all__ = ('Connection',
+           'STATE_ACKNOWLEDGING_CONNECT',
+           'STATE_ACKNOWLEDGING_DISCONNECT',
+           'STATE_CONNECTED',
+           'STATE_CONNECTING',
+           'STATE_CONNECTION_PENDING',
+           'STATE_CONNECTION_SUCCEEDED',
+           'STATE_DISCONNECTED',
+           'STATE_DISCONNECTING',
+           'STATE_DISCONNECT_LATER',
+           'STATE_ZOMBIE')
+
+from weakref import proxy
 from functools import partial
 import enet
 from packet import PacketManager
@@ -22,17 +34,18 @@
 
 
 class Connection(object):
-    """Class allowing to send messages and packets
+    """Class allowing to send packets
 
-    peer - connection to send packet over
-    channel - channel of connection
+    It's created by by Client or Server, shouldn't be created manually.
 
-    example:
-        client = Client()
-        # chat_msg packet is defined in packets module
-        client.net_chat_msg('Tom', 'Test message')
-        # alternative
-        client.send(packets.chat_msg('Tom', 'Test message'))
+    Sending is possible in two ways:
+    * using net_<packet_name> methods, where <packet_name>
+      is name of packet registered in PacketManager
+    * using send method with packet as argument
+
+    Attributes:
+        parent - proxy to Client / Server instance
+        peer - Enet peer instance
     """
 
     def __init__(self, parent, peer, packet_manager=PacketManager):
@@ -40,7 +53,7 @@
         self.peer = peer
         self._packet_cnt = 0
         self._packet_manager = packet_manager
-        self._receiver = None
+        self._receivers = []
 
     def __del__(self):
         self.peer.disconnect_now()
@@ -63,7 +76,7 @@
     def send(self, packet, *args, **kwargs):
         """Send packet to remote host
 
-        Client.send(packet, *args, **kwargs): return int
+        Connection.send(packet, *args, **kwargs): return int
 
         packet - class created by PacketManager.register or packet name
 
@@ -88,46 +101,52 @@
     def _receive(self, data, channel):
         packet_id, packet = self._packet_manager.unpack(data)
         _received_event(self, channel, packet, packet_id)
-        if self._receiver is not None:
-            name = 'net_' + packet.__class__.__name__
-            getattr(self._receiver, name, self._receiver.on_recive)(channel, packet_id, packet)
+        name = 'net_' + packet.__class__.__name__
+        for r in self._receivers:
+            getattr(r, name, r.on_recive)(channel, packet_id, packet)
 
     def _connect(self):
         _connected_event(self)
-        if self._receiver is not None:
-            self._receiver.on_connect()
+        for r in self._receivers:
+            r.on_connect()
 
     def _disconnect(self):
         _disconnected_event(self)
-        if self._receiver is not None:
-            self._receiver.on_disconnect()
+        for r in self._receivers:
+            r.on_disconnect()
 
     def disconnect(self):
+        """Request a disconnection.
+        """
         self.peer.disconnect()
 
     def disconnect_later(self):
+        """Request a disconnection from a peer, but only after all queued
+        outgoing packets are sent.
+        """
         self.peer.disconnect_later()
 
+    def disconnect_now(self):
+        """Force an immediate disconnection.
+        """
+        self.peer.disconnect_now()
+
+    def add_receiver(self, receiver):
+        """Add new Receiver to handle packets.
+
+        Connection.add_receiver(receiver)
+
+        receiver - instance of Receiver subclass
+        """
+        self._receivers.append(receiver)
+        receiver.connection = proxy(self)
+
     @property
     def state(self):
+        """Connection state."""
         return self.peer.state
 
     @property
     def address(self):
+        """Connection address."""
         return self.peer.address
-
-
-class Receiver(object):
-    def __init__(self, connection, *args, **kwargs):
-        super(Receiver, self).__init__(*args, **kwargs)
-        connection._receiver = proxy(self)
-        self.connection = connection
-
-    def on_connect(self):
-        pass
-
-    def on_disconnect(self):
-        pass
-
-    def on_recive(self, channel, packet_id, packet):
-        pass
--- a/zrpn/pygame_network/event.py	Sat Jul 07 18:01:10 2012 +0200
+++ b/zrpn/pygame_network/event.py	Sat Jul 07 18:06:19 2012 +0200
@@ -1,3 +1,9 @@
+__all__ = ('NETWORK',
+           'NET_CONNECTED',
+           'NET_DISCONNECTED',
+           'NET_RECEIVED',
+           'NET_RESPONSE')
+
 from weakref import proxy
 import pygame
 from pygame.event import Event
@@ -11,6 +17,11 @@
 NET_RESPONSE = 3  # TODO: response !!
 
 
+def conf_newtwork_event(val=1):
+    global NETWORK
+    NETWORK = USEREVENT + val
+
+
 def _connected_event(connection):
     pygame.event.post(Event(NETWORK, {
         'net_type': NET_CONNECTED,
--- a/zrpn/pygame_network/packet.py	Sat Jul 07 18:01:10 2012 +0200
+++ b/zrpn/pygame_network/packet.py	Sat Jul 07 18:06:19 2012 +0200
@@ -50,7 +50,7 @@
         self._hash = None
 
     @classmethod
-    def register(cls, name, field_names, channel=0, flags=enet.PACKET_FLAG_RELIABLE):
+    def register(cls, name, field_names=tuple(), channel=0, flags=enet.PACKET_FLAG_RELIABLE):
         """Register new packet type
 
         PacketManager.register(name, field_names, channel, flags): return class
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zrpn/pygame_network/receiver.py	Sat Jul 07 18:06:19 2012 +0200
@@ -0,0 +1,12 @@
+class Receiver(object):
+    """Base class for objects receiving packets through net_packet_name
+    functions
+    """
+    def on_connect(self):
+        pass
+
+    def on_disconnect(self):
+        pass
+
+    def on_recive(self, channel, packet_id, packet):
+        pass
--- a/zrpn/pygame_network/server.py	Sat Jul 07 18:01:10 2012 +0200
+++ b/zrpn/pygame_network/server.py	Sat Jul 07 18:06:19 2012 +0200
@@ -1,5 +1,7 @@
 import logging
+from weakref import proxy
 import enet
+from receiver import Receiver
 from packet import PacketManager
 from connection import Connection
 
@@ -8,41 +10,43 @@
 
 class Server(object):
     packet_manager = PacketManager
-    receiver = None
+    receiver_cls = None
 
-    def __init__(self, address, port, connections_limit=4, channel_limit=0, in_bandwidth=0, out_bandwidth=0):
+    def __init__(self, address='', port=0, connections_limit=4, # max 4095
+                 channel_limit=0, in_bandwidth=0, out_bandwidth=0):
         address = enet.Address(address, port)
-        self.host = enet.Host(address, connections_limit, channel_limit, in_bandwidth, out_bandwidth)
-        self._peers = {}
+        self.host = enet.Host(address, connections_limit, channel_limit,
+                              in_bandwidth, out_bandwidth)
+        self.peers = {}
         self._peer_cnt = 0
         self.packet_manager._frozen = True
 
     def step(self, timeout=0):
-        if len(self._peers) == 0:
-            return
         host = self.host
         event = host.service(timeout)
         while event is not None:
             if event.type == enet.EVENT_TYPE_CONNECT:
                 if event.data == self.packet_manager.get_hash():
+                    _logger.info('Connection with %s accepted', event.peer.address)
                     peer_id = self._peer_cnt = self._peer_cnt + 1
                     peer_id = str(peer_id)
                     event.peer.data = peer_id
                     connection = Connection(self, event.peer, self.packet_manager)
-                    self._peers[peer_id] = connection
-                    # TODO: add receiver
+                    if issubclass(self.receiver_cls, Receiver):
+                        receiver = self.receiver_cls()
+                        receiver.server = proxy(self)
+                        connection.add_receiver(receiver)
+                    self.peers[peer_id] = connection
                     connection._connect()
-                    _logger.info('Connection with %s accepted', event.peer.address)
                 else:
-                    event.peer.data = 'N'
-                    event.peer.disconnect()
-                    _logger.warning('Connection with %s refused, incompatible packets set', event.peer.address)
+                    _logger.warning('Connection with %s refused, PacketManager'\
+                                    ' hash incorrect', event.peer.address)
+                    event.peer.disconnect_now()
             elif event.type == enet.EVENT_TYPE_DISCONNECT:
-                if event.peer.data != 'N':
-                    self._peers[event.peer.data]._disconnect()
-                    del self._peers[event.peer.data]
                 _logger.info('Disconnected from %s', event.peer.address)
+                self.peers[event.peer.data]._disconnect()
+                del self.peers[event.peer.data]
             elif event.type == enet.EVENT_TYPE_RECEIVE:
-                self._peers[event.peer.data]._receive(event.packet.data, event.channelID)
                 _logger.info('Received data from %s', event.peer.address)
+                self.peers[event.peer.data]._receive(event.packet.data, event.channelID)
             event = host.check_events()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/zrpn/server.py	Sat Jul 07 18:06:19 2012 +0200
@@ -0,0 +1,31 @@
+import pygame_network as net
+import board
+import packets
+
+class ClientReceiver(net.Receiver):
+    def net_click(self, channel, packet_id, packet):
+        self.server.board.kill_one(packet)
+        animations = self.server.board.update()
+        for connection in self.server.peers.values():
+            connection.net_animation()
+
+    def on_connected(self):
+        self.connection.net_init(self.server.board.board, self.server.board.cells)
+
+class Server(object):
+    def __init__(self, port):
+        self.server = net.Server(port=port)
+        self.server.receiver_cls = ClientReceiver
+        self.server.board = board.Board()
+
+    def run(self):
+        while True:
+            self.server.step(1000)
+
+
+def main():
+    Server(10000).run()
+
+if __name__ == '__main__':
+    main()
+
--- a/zrpn/sprites.py	Sat Jul 07 18:01:10 2012 +0200
+++ b/zrpn/sprites.py	Sat Jul 07 18:06:19 2012 +0200
@@ -27,7 +27,8 @@
         super(Cell, self).__init__()
         if self.sheet is None:
             self.sheet = load_sheet('zrpn.png', 24)
-        self.image = self.sheet[kind * 2]
+        self.steps = [self.sheet[kind * 2], self.sheet[kind * 2 + 1]]
+        self.image = self.steps[0]
         self.rect = self.image.get_rect()
         self.rect.topleft = x * 24, y * 24
         self.animations = []
@@ -59,6 +60,7 @@
     def anim_fall(self):
         for step in xrange(8):
             self.rect.move_ip((0, 3))
+            self.image = self.steps[step % 2]
             yield
 
     def anim_die(self):