This is a read-only archive of the old Scratch 1.x Forums.
Try searching the current Scratch discussion forums.

#226 2012-02-08 18:59:53

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Well, yes, I guess. Just to make sure the current revision of the program works right, could you download (and run) the program that I linked to above. (are you Windows or Mac?)


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#227 2012-02-08 20:04:16

Necromaster
Scratcher
Registered: 2010-04-07
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

bobbybee wrote:

Well, yes, I guess. Just to make sure the current revision of the program works right, could you download (and run) the program that I linked to above. (are you Windows or Mac?)

I have 8 computers. (Not all my own, but I have access to all)

3 windows, 5 macs.

Offline

 

#228 2012-02-09 07:19:23

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Would you like to host the server on a Windows or on a Mac. Here are some pro's and con's, if it matters:

Windows:

+In more active development (more installs)
+Control pannel available
-Not native to me
-I can't help debug if Google can't help

Mac/*nix:
+I'm posting on one now
+FireMMO was originally written for a mac computer
+The windows source code is merely a hack of this code. (that's why it's not available)
+I can help debug if things go wrong
-Not many people have tested it (me, my grandmother, that's about it)
-It has no control panel, although I can easily port it if it matters
-Requires a bit more programming knowledge to get working properly


Also, what languages are you good at? There is one major piece of development that needs to get done, and you may be a candidate to develop that section of FireMMO.

I hope I didn't bore you,
-bobbybee (FireMMO Founder, FireMMO Owner, and FireMMO Lead Programmer)


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#229 2012-02-12 11:45:00

ImagineIt
Scratcher
Registered: 2011-02-28
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Can I test please? I would program, but I don't know how. sad  I wish I could.

Offline

 

#230 2012-02-12 17:01:06

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Definitely! I need a lot more testers.


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#231 2012-02-12 17:19:33

ImagineIt
Scratcher
Registered: 2011-02-28
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Can I have a download link please?

Offline

 

#232 2012-02-12 17:47:41

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Windows: http://firemmo.site50.net/firemmo2windowsbuild3.zip.
Mac/Ubuntu/Other: (just tell me, I have one, just need to know if you need one)

-bobbybee (FireMMO Founder, FireMMO Owner, and FireMMO Lead Programmer)


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#233 2012-02-12 18:46:24

zippynk
Scratcher
Registered: 2011-07-23
Posts: 500+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

bobbybee wrote:

Windows: http://firemmo.site50.net/firemmo2windowsbuild3.zip.
Mac/Ubuntu/Other: (just tell me, I have one, just need to know if you need one)

-bobbybee (FireMMO Founder, FireMMO Owner, and FireMMO Lead Programmer)

I have a mac
and I have no PC  sad
and no PC VM  sad
So I need a mac version  hmm

Edit: I might have a vm.

Last edited by zippynk (2012-02-12 18:51:51)


https://dl.dropbox.com/u/60598636/trifocal_interlude_soundcloud_button.png

Offline

 

#234 2012-02-12 19:30:39

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

I have the binary, let me upload it. (give me a minute)


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#235 2012-02-12 19:33:02

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

The mac binary can be found here: http://firemmo.site50.net/firemmo2macbuild1.zip

-bobbybee (FireMMO Founder, FireMMO Owner, and FireMMO Lead Programmer)


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#236 2012-02-13 18:40:57

Magnie
Scratcher
Registered: 2007-12-12
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

What's the Python error?

Offline

 

#237 2012-02-13 18:42:11

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

It's not so much an error, rather more of it simply not working. Let me get the code.


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#238 2012-02-13 18:54:18

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Code:

# Scratch Mirror
# Version 1.0.0
# By: Magnie (edited by bobbybee for use in FireMMO version 2.0+)

from array import array
import socket
import time
import re

def parseData(str):
    #Check for a broadcast
    e = re.search('broadcast\s\"(.*)\"',str)
    if e:
        #We have a broadcast!
        broadcastIn(e.group(1))
    #Check for a sensor-update with quoted second value (string)
    e = re.search('sensor-update\s\"(.*?)\"\s\"(.*?)\"',str)
    if e:
        #Got one!
        sensorUpdateIn(e.group(1),e.group(2))
    #Look for a sensor-update with a numeric second value
    e = re.search('sensor-update\s\"(.*?)\"\s([-|\d|.]+)',str)
    if e:
        #Success!
        sensorUpdateIn(e.group(1),e.group(2))

def sensorUpdateIn(var,value):
    print "Scratch changed "+var+" to: "+value
    if var in ['packet']:
        scratchServer.send("F"+value)
    serverData = scratchServer.recv(1024)
    exec serverData
    #print serverData
    
    
def broadcastIn(broadcast):
    print "Scratch broadcasted: "+broadcast
    scratchServer.send(data)
    serverData = scratchServer.recv(1024)
    exec serverData
    #print serverData

def sendScratchCommand(cmd):
    n = len(cmd)
    a = array('c')
    a.append(chr((n >> 24) & 0xFF))
    a.append(chr((n >> 16) & 0xFF))
    a.append(chr((n >>  8) & 0xFF))
    a.append(chr(n & 0xFF))
    scratchSock.send(a.tostring() + cmd)
    #print a.tostring() + cmd



CHOST = '127.0.0.1'
CPORT = 42001

SHOST = '127.0.0.1'
SPORT = 7070

print("Connecting to Scratch...")
scratchSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
scratchSock.connect((CHOST, CPORT))
print("Connected to Scratch!")
print("Connecting to Server...")
scratchServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
scratchServer.connect((SHOST, SPORT))
print("Connected to Server!")

# print incoming data forever
while 1:
    time.sleep(0.01)
    data = scratchSock.recv(1024)
    parseData(data)
    if not data: break
    #print data

This a python program that is based off of a mirror that you made. (not sure which) I'm expecting that whenever I update the packet variable, the python will send it's value to the server, however this only happens when the mirror is first launched, rather than every time that the variable is updated. I think that the message isn't being received, however I haven't debugged it so I can't say for sure where it is messing up. (perhaps the parsing is bad)


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#239 2012-02-13 18:59:19

Magnie
Scratcher
Registered: 2007-12-12
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Yeah.. That one seems to be out-dated. Try this one:

Code:

# Scratch Mirror
# Version 1.5.0
# By: Magnie

import socket # Network base
import time # For delaying purposes mostly.
import threading # So it can send and receive at the same time anytime.

# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# CHOST is the IP Scratch is running on, if you are running it    #
# on this computer, then the IP is 127.0.0.1                      #
# Theoretically you could run this Mirror on another computer.    #
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# CPOST is the port Scratch is listening on, the default is       #
# 42001. Usually this is only change by a Scratcher who knows a   #
# about Squeak and networking with sockets.                       #
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
CHOST = '127.0.0.1'
CPORT = 42001

# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# SHOST is the IP the server is running on.                       #
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# SPORT is the port that the server is using. 42002 is the        #
# unofficial port for Scratch Servers. The host will need to make #
# sure to port-forward the port so people can connect from the    #
# internet.                                                       #
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
SHOST = raw_input("Server IP: ")
SPORT = int( raw_input("Server Port: ") )

# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# Some extra settings that are more for advanced users are below. #
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #

# Time between checking the threads for broken ones.
THREADCHECK = 5



class Client(threading.Thread): # This class listens for messages sent from Scratch and sends it to the Server.
    def __init__(self, CHOST, CPORT):
        threading.Thread.__init__(self) # Initialize it, basically just separate it from the main thread.
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Defines the type of connection ( UPD, TCP on IPv4 or IPv6 )
        print("Connecting to Scratch...")
        self.sock.connect((CHOST, CPORT)) # Connect to Scratch
        print("Connected to Scratch!")
        
        self.alive = 1
        
    def run(self):
        global running
        print "Listening for Scratch messages."
        while running:
            try:
                data = self.sock.recv(1024) # Listens for messages sent from Scratch.
                self.send(data)
            except:
                self.alive = 0
    
    def send(self, message):
        server.sock.send(message) # Send the data to the server.
    
    def disconnect(self):
        self.sock.close()

class Server(threading.Thread): # This class listens for messages from the Server and sends it to Scratch.
    def __init__(self, SHOST, SPORT):
        threading.Thread.__init__(self) # Initialize it, basically just separate it from the main thread.
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Defines the type of connection ( UPD, TCP on IPv4 or IPv6 )
        print("Connecting to Scratch Server...")
        self.sock.connect((SHOST, SPORT)) # Connect to the Server.
        print("Connected to Server!")
        
        self.alive = 1
        
    def run(self):   
        global running
        print "Listening for Server messages."
        while running:
            try:
                data = self.sock.recv(1024) # Listens for messages sent from the Server.
                self.send(data)
            except:
                self.alive = 0
    
    def send(self, message):
        scratch.sock.send(message) # Sends messages to Scratch.
    
    def disconnect(self):
        self.sock.close()


running = 1
server = Server(SHOST, SPORT) # Start up the class for Server
server.start() # This starts the 'run' function on the class as well.

scratch = Client(CHOST, CPORT) # Start up the class for Scratch
scratch.start() # This starts the 'run' function.

while running:
    time.sleep(THREADCHECK) # The longer the wait time, the less CPU is used I think.
    if scratch.alive != 1: running = 0
    if server.alive != 1: running = 0
    
    if running == 0:
        running = 0
        server.disconnect() # Tell the server thread to disconnect
        scratch.disconnect() # Tell the scratch thread to disconnect

        server.join() # End the server thread.
        scratch.join() # End the scratch thread.
        print 'Error Check: Yes.'
    else:
        pass
        #print 'Error Check: No errors.'
print "Finished running."

Offline

 

#240 2012-02-13 19:08:49

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Alright. I'll try to merge the changes into one mirror, that will hopefully work. I just noticed that the 2 times that I made the most progress on FireMMO, you were online on the FireMMO topic. (or in the case of Chat.py...)


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#241 2012-02-13 19:12:27

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Also Magnie, what python code snippet should I use in order to separate the type of packet from it's parameters. I need to know what variable is being changed so I know whether or not I should send it's value to the server.

EDIT: Wooh! 500 Posts!

Last edited by bobbybee (2012-02-13 19:12:43)


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#242 2012-02-13 20:23:05

Magnie
Scratcher
Registered: 2007-12-12
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

You can either use the parser with version 1.0.0 and the same method of sending the command, or you can use this to parse:

Code:

def parse_message(self, message):
        #TODO: parse sensorupdates with quotes in sensor names and values
        #       make more readable
        #print message
        if message:
            sensors = {}
            broadcasts = []

            commands = []
            i = 0
            while True:
                length = ord(message[i]) + ord(message[i+1]) + ord(message[i+2]) + ord(message[i+3])
            
                command = message[i + 4:i + length + 4]
                commands.append(command)
                if (i + length + 4) < len(message):
                    i = (i+4) + length
                else:
                    del command
                    break
            
            for command in commands:
                if command[0] == 'b':
                    command = command.split('"')
                    command.pop(0)
                    broadcasts.append(command[0])
                
                elif command[0] == 's':
                    command = command.split('"')
                    command.pop(0)
                    command.remove(' ')
                    command.remove('')
                    sensors[command[0]] = command[1]
        
            return dict([('sensor-update', sensors), ('broadcast', broadcasts)])
        else: 
            return None

That snippet goes into a class. You can use it to parse the data, it returns the data like this:

Code:

{
'broadcast' : ['broadcast1', 'broadcast2'],
'sensor-update' : { 'sensor1' : 'sensor1value', 'sensor2' : 'sensor2value' }
}

So you can use code like this (it all goes in the Client class, you'll need to indent):

Code:

def sendScratchCommand(self, cmd):
    n = len(cmd)
    a = array('c')
    a.append(chr((n >> 24) & 0xFF))
    a.append(chr((n >> 16) & 0xFF))
    a.append(chr((n >>  8) & 0xFF))
    a.append(chr(n & 0xFF))
    server.send(a.tostring() + cmd)

data = self.parse_message(data)
for broadcast in data['broadcast']:
    self.sendScratchCommand('broadcast "'+broadcast+'"')

for sensor in data['sensor-update']:
    self.sendScratchCommand('sensor-update "'+sensor+'" "'+data['sensor-update'][sensor]+'"')

Last edited by Magnie (2012-02-13 20:23:49)

Offline

 

#243 2012-02-13 21:55:22

zippynk
Scratcher
Registered: 2011-07-23
Posts: 500+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

I ran the mac version in Terminal, and it says "Binded". What do I do next?


https://dl.dropbox.com/u/60598636/trifocal_interlude_soundcloud_button.png

Offline

 

#244 2012-02-14 06:22:25

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

@Magnie
I'll try that when I get a chance

@zippynk
The binded means that server is running on your computer. You then need to use the mirror to connect with Scratch. In the mean time, open another terminal window. Type 'telnet localhost 7070'. Then type a command like, 'Fr/j/0/zippynk'.

-bobbybee (FireMMO Founder, FireMMO Owner, and FireMMO Lead Programmer)


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#245 2012-02-14 09:47:49

Magnie
Scratcher
Registered: 2007-12-12
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

bobbybee wrote:

@Magnie
I'll try that when I get a chance

@zippynk
The binded means that server is running on your computer. You then need to use the mirror to connect with Scratch. In the mean time, open another terminal window. Type 'telnet localhost 7070'. Then type a command like, 'Fr/j/0/zippynk'.

-bobbybee (FireMMO Founder, FireMMO Owner, and FireMMO Lead Programmer)

You should make a little guide explaining all the commands and what they do.  smile

Offline

 

#246 2012-02-14 18:25:33

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

@Magnie
It's funny you say that--I'm actually making a little PDF about FireMMO, protocols, networking, and best of all (drum roll please) FireMMO's networking protocol.


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#247 2012-02-14 19:25:16

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Alright Magnie, I put together the Python mirror. However, there is one error that I'm getting that I don't know how to fix the error is this:

Traceback (most recent call last):
  File "mirror.py", line 107, in <module>
    class Server(threading.Thread, SHOST, SPORT): # This class listens for messages from the Server and sends it to Scratch.
TypeError: Error when calling the metaclass bases
    metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases


This is the code:

Code:

# Scratch Mirror
# Version 1.5.0
# By: Magnie

import socket # Network base
import time # For delaying purposes mostly.
import threading # So it can send and receive at the same time anytime.

# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# CHOST is the IP Scratch is running on, if you are running it    #
# on this computer, then the IP is 127.0.0.1                      #
# Theoretically you could run this Mirror on another computer.    #
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# CPOST is the port Scratch is listening on, the default is       #
# 42001. Usually this is only change by a Scratcher who knows a   #
# about Squeak and networking with sockets.                       #
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
CHOST = '127.0.0.1'
CPORT = 42001

# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# SHOST is the IP the server is running on.                       #
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# SPORT is the port that the server is using. 42002 is the        #
# unofficial port for Scratch Servers. The host will need to make #
# sure to port-forward the port so people can connect from the    #
# internet.                                                       #
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
SHOST = '127.0.0.1'
SPORT = 7070

# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# Some extra settings that are more for advanced users are below. #
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #

# Time between checking the threads for broken ones.
THREADCHECK = 5



class Client(threading.Thread): # This class listens for messages sent from Scratch and sends it to the Server.
    def parse_message(self, message):
        if message:
            sensors = {}
            broadcasts = []

            commands = []
            i = 0
            while True:
                length = ord(message[i]) + ord(message[i+1]) + ord(message[i+2]) + ord(message[i+3])
            
                command = message[i + 4:i + length + 4]
                commands.append(command)
                if (i + length + 4) < len(message):
                    i = (i+4) + length
                else:
                    del command
                    break
            
            for command in commands:
                if command[0] == 'b':
                    command = command.split('"')
                    command.pop(0)
                    broadcasts.append(command[0])
                
                elif command[0] == 's':
                    command = command.split('"')
                    command.pop(0)
                    command.remove(' ')
                    command.remove('')
                    sensors[command[0]] = command[1]
        
            return dict([('sensor-update', sensors), ('broadcast', broadcasts)])
        else: 
            return None
    def sendScratchCommand(self, cmd):
        n = len(cmd)
        a = array('c')
        a.append(chr((n >> 24) & 0xFF))
        a.append(chr((n >> 16) & 0xFF))
        a.append(chr((n >>  8) & 0xFF))
        a.append(chr(n & 0xFF))
        server.sock.send(a.tostring() + cmd)
    
    def __init__(self, CHOST, CPORT):
        threading.Thread.__init__(self) # Initialize it, basically just separate it from the main thread.
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Defines the type of connection ( UPD, TCP on IPv4 or IPv6 )
        print("Connecting to Scratch...")
        self.sock.connect((CHOST, CPORT)) # Connect to Scratch
        print("Connected to Scratch!")
        
    def run(self):
        global running
        print "Listening for Scratch messages."
        while running:
            data = self.sock.recv(1024) # Wait for something to be sent to the mirror
            
            data = self.parse_message(data)
            for sensor in data['sensor-update']:
                if sensor == "packet":
                    self.send(data['sensor-update'][sensor])

    
    def send(self, message):
        server.sock.send(message) # Send the data to the server.

class Server(threading.Thread, SHOST, SPORT): # This class listens for messages from the Server and sends it to Scratch.
    def sendScratchCommand(self, cmd):
        n = len(cmd)
        a = array('c')
        a.append(chr((n >> 24) & 0xFF))
        a.append(chr((n >> 16) & 0xFF))
        a.append(chr((n >>  8) & 0xFF))
        a.append(chr(n & 0xFF))
        scratch.sock.send(a.tostring() + cmd)
    def __init__(self):
        threading.Thread.__init__(self) # Initialize it, basically just separate it from the main thread.
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Defines the type of connection ( UPD, TCP on IPv4 or IPv6 )
        print("Connecting to Scratch Server...")
        self.sock.connect((SHOST, SPORT)) # Connect to the Server.
        print("Connected to Server!")
        
    def run(self):   
        global running
        print "Listening for Server messages."
        while running:    
            data = self.sock.recv(1024) # Listens for messages sent from the Server.
            self.sendScratchCommand("sensor-update 'packet' '"+data+"'");
    
    def send(self, message):
        scratch.sock.send(message) # Sends messages to Scratch.

running = 1
scratch = Client(CHOST, CPORT) # Start up the class for Scratch
scratch.start() # This starts the 'run' function.

server = Server(SHOST, SPORT) # Start up the class for Server
server.start() # This starts the 'run' function on the class as well.

while running:
    time.sleep(THREADCHECK) # The longer the wait time, the less CPU is used I think.
    try: # Check if the either thread died ( or exists anymore ).
        if scratch: pass
        if server: pass
    except: # If either are dead, end the program.
        running = 0
        print "Finished running."

I support the Free Software Foundation. Protect our digital rights!

Offline

 

#248 2012-02-14 23:41:12

Magnie
Scratcher
Registered: 2007-12-12
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

SHOST and SPORT go in __init__(self, SHOST, SPORT):, not class Server(thread.Thread):.

Offline

 

#249 2012-02-15 06:16:01

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Thanks.


I support the Free Software Foundation. Protect our digital rights!

Offline

 

#250 2012-02-15 16:33:36

bobbybee
Scratcher
Registered: 2009-10-18
Posts: 1000+

Re: FireMMO: The Ultimate MMO Development Kit (previously MMO Project)

Woot, woot. I finished the mirror. (python, of course) How do I compile it to exe/app? Or is that not possible?


I support the Free Software Foundation. Protect our digital rights!

Offline

 

Board footer