[Twisted-Python] Writing a plug-in for an online game that uses UDP

Ibrahim Mubarak ibmub80 at yahoo.com
Sun Jul 25 16:31:58 EDT 2004


Hi,

I am currently writing a server prototype for an online game called "If I Were U" (GPL). It will
be using UDP and a MySQL db. I was successful in writing the code as a plug-in. I love the idea of
being able to seperate in different files the levels of abstraction. But I am not sure of how to
go about the following:
I have an iiwuServer class derived from DatagramProtocol. I defined the datagramReceived method.
This method calls one of my other classes's methods which returns a deferred object (this is where
the connection to the db happens). I am trying to set the callback function for this deferred
object and I want it to be a method of iiwuServer as I need to access the transport member object
which in its turn writes out a datagram to the client. And I am not sure how to set up the
callbackArgs for it (the "self" argument for methods is where I am confused).

What am I doing wrong?

Also, if you have a couple of minutes, can u look at my other three code segments (found after the
iiwuServer) and tell me if you see anything that should be changed. Don't worry, the code is not
that long. The thing is that in the documentation, each part (UDP, plug-in, deferred, etc...) are
very well explained. But when I tried to put all that together, I got a little confused as I did
not see any examples of UDP plug-ins or more complex deferred callback functions.

All these segments are actually files in a folder called UDPServer. If you prefer that I send you
the directory tarred and zipped, let me know. All that is left out is the empty __init__.py file
in the folder.

Thanks a lot,
Ib
http://www.iiwu.org

Here is the code for the protocol (file name: iiwuserverprotocol.py):
////////CODE START\\\\\\\\
############################
##This is where the UDP packets are recieved and then sent to the server logic
############################
from twisted.internet.protocol import DatagramProtocol
from UDPServer import iiwuserverlogic

class iiwuServer(DatagramProtocol):
    iiwuservice = iiwuserverlogic.LoginService()
    def sendingOutput(self, result, host, port):
        """
            A callback for the deferred object returned
        """
        self.transport.write(str(result) + "\n" + str(self) + "\n", (host, port))
        return
    
    def datagramReceived(self, data, (host, port)):
        msg = data.split()
        if len(msg) != 1 and len(msg) != 3:
            self.sendingOutput("error" , host, port)
            return
        
        if msg[0] == "log" and len(msg) == 3:
            user = msg[1]
            pswd = msg[2]
            self.iiwuservice.logUser(user, pswd, host, port).addCallback(self.sendingOutput(self,
host, port))
            return 
        
        if msg[0] == "get":
            self.iiwuservice.loggedUsers().addCallback(self.sendingOutput(self, host, port))
            return 
            
        return    
\\\\\\\\CODE END////////

Here is the code for the server's logic (file name: iiwuserverlogic.py):
////////CODE START\\\\\\\\
##############################
##This is where all the logic of the server lies
##############################
from twisted.python import components
from twisted.enterprise import adbapi 
class IService(components.Interface):
    """
        An object that recieves messages.
    """

class LoginService:
    """
        Respond to different messages
    """
    __implements__ = IService

    def __init__(self):
        """
            Setting up the db connection pool
        """
        self.dbpool = adbapi.ConnectionPool("MySQLdb", 'database_name', 'login', 'password')
        return
        
    def mysqlQuery(self, q):
        """
            Run a MySql query and return the result
        """
        result = self.dbpool.runQuery(q)
        return result  #Returning a Deferred object
        
    def logUser(self, name, pswd, ip, port):
        """
            Connects to the DB and logs the user, returning nothing
        """
        query = "INSERT INTO users (name, pswd, ip, port) VALUES (%s, %s, %s, %s)" % (name, pswd,
ip, port)
        return self.mysqlQuery(query)
        
    def loggedUsers(self):
        """
            Connects to the DB and returns a list of the users logged in
        """
        query = "SELECT * FROM users"
        return self.mysqlQuery(query)
\\\\\\\\CODE END////////

Here is the code for the tap construction (file name: servertap.py):
////////CODE START\\\\\\\\
from twisted.application import internet    # services that run TCP/SSL/etc.
from UDPServer import iiwuserverprotocol    # Protocol
from UDPServer import iiwuserverlogic       # Server code
from twisted.python import usage            # twisted command-line processing

class Options(usage.Options):
    """
        Defining options when building the application
    """
    optParameters = [["port", "p", 8007, "Port number to listen on for iiwuServer protocol."]]

def makeService(config):
    """
        Return a service that will be attached to the application.
    """
    protocol = iiwuserverprotocol.iiwuServer()
    port = int(config["port"])          # UCP port to listen on
    # Finally, set up our protocol when events arrive on the specified port
    return internet.UDPServer(port, protocol)
\\\\\\\\CODE END////////

Finally, here is the plugins.tml file:
////////CODE START\\\\\\\\
register("IIWU Server TAP Builder",
         "UDPServer.servertap",
         description="""
         IIWU TAP builder module.
         """            ,
         type="tap",
         tapname="iiwuserv")
\\\\\\\\CODE END////////



	
		
__________________________________
Do you Yahoo!?
New and Improved Yahoo! Mail - 100MB free storage!
http://promotions.yahoo.com/new_mail 




More information about the Twisted-Python mailing list