gameserver.py
上传用户:ghyvgy
上传日期:2009-05-26
资源大小:547k
文件大小:4k
源码类别:

其他游戏

开发平台:

Python

  1. # gameserver.py
  2. #
  3. # Trivial implementation of an asynchronous game server
  4. # based on the Python asyncore.py and asynchat.py 
  5. # modules.
  6. #
  7. # Author: Matthew Walker
  8. #         mwalker@softhome.net
  9. #
  10. import asynchat
  11. import asyncore
  12. import socket
  13. import string
  14. import traceback
  15. import sys
  16. import request
  17. import objmgr
  18. import os
  19. import deferred
  20. import request
  21. import re
  22. # special object id for game server
  23. ID_SERVER = -100  # so as not to collide with generated ids
  24. class GameServer (asyncore.dispatcher):
  25.   """
  26.   Main server for game, center of the universe, as it were.
  27.   This is based on the python asyncore module, which is a 
  28.   really cool way to develop asynchronous servers very easily.
  29.   Oh, and 42.
  30.   """
  31.   
  32.   def __init__ (self, port):
  33.     #print 'GameServer.__init__( %s )' % (port,)
  34.     asyncore.dispatcher.__init__ (self)
  35.     self.create_socket (socket.AF_INET, socket.SOCK_STREAM)
  36.     self.set_reuse_addr()
  37.     here = ('', port)
  38.     self.bind (here)
  39.     self.listen (5)
  40.     self.clients = {}
  41.     self.id = ID_SERVER
  42.     objmgr.AddObject(self, self.id)
  43.   def handle_accept (self):
  44.     #print 'GameServer.handle_accept()'
  45.     ClientConnection (self, self.accept())
  46.   def request (self, id, data):
  47.     #print 'GameServer.request( %s )' % (data,)
  48.     requester = self.clients[id]
  49.     # deferred call to request handler
  50.     deferred.Call(request.ID_REQUEST, 'Handle', (id, data))
  51.   def respond (self, result):
  52.     requester = self.clients[result.clientid]
  53.     requester.reply(str(result))
  54.     if not requester.loggedin:
  55.       self.close_client(result.clientid)
  56.   def pre_close_client (self, clientid):
  57.     requester = self.clients[clientid]
  58.     requester.loggedin = 0
  59.   def close_client (self, clientid):
  60.     requester = self.clients[clientid]
  61.     requester.handle_close()
  62.   def add_connection (self, id, connection):
  63.     #print 'add_connection( %s, %s )' % (id, connection)
  64.     assert(not self.clients.get(id))
  65.     self.clients[id] = connection
  66.   def remove_connection (self, id, connection):
  67.     #print 'remove_connection( %s, %s )' % (id, connection)
  68.     del self.clients[id]
  69.   def handle_error (self):
  70.     print 'GameServer: ERROR'
  71.     traceback.print_exc()
  72.   def handle_close (self):
  73.     objmgr.RemoveObject(self)
  74. class ClientConnection (asynchat.async_chat):
  75.   """
  76.   Manages interactions with a single client.
  77.   """
  78.   conn_counter = 0    # class level counter, always increments
  79.   loginString = "Please enter your name: "
  80.   promptString = "Let's play!> "
  81.   def __init__ (self, server, (conn, addr)):
  82.     asynchat.async_chat.__init__ (self, conn)
  83.     self.set_terminator (os.linesep)
  84.     self.server = server
  85.     self.id = ClientConnection.conn_counter
  86.     self.server.add_connection(self.id, self)
  87.     ClientConnection.conn_counter += 1
  88.     self.buffer = ''
  89.     self.loginchecked = 0
  90.     self.check_login()
  91.     #print 'ClientConnection[ %d ].__init__( %s, %s )' % (self.id, server, (conn, addr))
  92.   def __del__(self):
  93.     print 'ClientConnection.__del__()'
  94.   def collect_incoming_data (self, data):
  95.     #print 'ClientConnection[ %d ].collect_incoming_data()' % (self.id,)
  96.     self.buffer = self.buffer + data
  97.     # echo
  98.     self.push(data)
  99.     
  100.   def found_terminator (self):
  101.     #print 'ClientConnection[ %d ].found_terminator()' % (self.id,)
  102.     data = self.buffer
  103.     self.buffer = ''
  104.     print '<== (%d) %s' % (self.id, repr(data))
  105.     self.push(os.linesep)
  106.     if self.check_login(data):
  107.       self.server.request (self.id, data)
  108.   def handle_close (self):
  109.     #print 'ClientConnection[ %d ].handle_close()' % (self.id,)
  110.     print 'Closing'
  111.     self.server.remove_connection(self.id, self)
  112.     self.connected = 0
  113.     self.close()
  114.   def handle_error (self):
  115.     print 'ClientConnection[ %s ]: ERROR' % (self,)
  116.     traceback.print_exc()
  117.   def check_login (self, data=''):
  118.     """ Login state machine."""
  119.     if not self.loginchecked:
  120.       self.loginchecked = 1
  121.       self.loggedin = 0
  122.       self.push(self.loginString)
  123.       return 0
  124.     elif not self.loggedin:
  125.       # assume any data provided is the name
  126.       self.loggedin = 1
  127.       name = re.sub(r's+', '_', data)
  128.       self.server.request (self.id, '_LOGIN %s' % (name,))
  129.       return 0
  130.     return 1
  131.   def prompt (self):
  132.     self.push(self.promptString)
  133.   def reply (self, data):
  134.     if data:
  135.       data = re.sub(r'n', os.linesep, data)  # replace newlines with linesep
  136.       self.push(data + os.linesep)
  137.     if self.loggedin:
  138.       self.prompt()