Source

pygamegsoc12 / alchemymadness / server.py

from weakref import WeakKeyDictionary
from threading import Thread, Timer, Event
from PodSixNet.Server import Server
from PodSixNet.Channel import Channel

MAX_CLIENTS = 4

class ClientChannel(Channel):
    def __init__(self, *args, **kwargs):
        Channel.__init__(self, *args, **kwargs)
        self.id = -1
        self.data = {'test': 123}
        self._server.add_player(self)
    
    def Network(self, data):
        print data
        
    def Network_update(self, data):
        del data['action']
        self.data = data
        self._server.send_to_all(dict(data, action='update', id=self.id), self)
        
    def Network_msg(self, data):
        self._server.send_to_all({'action':'msg', 'id':self.id, 'msg':data['msg']}, self)

    def Close(self):
        self._server.del_player(self)

class GameServer(Server):
    channelClass = ClientChannel
    
    def __init__(self, port, *args, **kwargs):
        Server.__init__(self, localaddr=('', port), *args, **kwargs)
        self.players = WeakKeyDictionary()
        self._stop = Event()
        self.av_id = 0

    def Connected(self, channel, addr):
        print 'New connection:', channel
        
    def add_player(self, player):
        if len(self.players) >= MAX_CLIENTS:
            player.Send({'action':'info', 'info':'Server full'})
            player.Pump()
            player.close()
            return
        else:
            player.id = self.av_id
            self.av_id += 1
            print 'New player #%d (%s:%s)' % (player.id, player.addr[0], player.addr[0])
            player.Send(dict(player.data, action='init'))
            for p in self.players:
                player.Send({'action':'add', 'id':p.id})
            player.Pump()            
            self.send_to_all({'action':'add', 'id':player.id}, player)
            self.players[player] = True

    def del_player(self, player):
        print 'Deleting player @ %s:%s' % player.addr
        if self.players.has_key(player):
            self.send_to_all({'action': 'del', 'id':player.id}, player)
            del self.players[player]
    
    def send_to_all(self, data, exclude=None):
        for p in self.players:
            if not p is exclude:
                p.Send(data)
        
    def run(self):
        while not self._stop.wait(0.001):
            self.Pump()
        
if __name__ == "__main__":
    print "serving @10000"
    GameServer(10000).run()