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

#276 2012-01-18 21:07:02

JSO
Community Moderator
Registered: 2007-06-23
Posts: 1000+

Re: Chat.PY and Other Features

Hm - it seems like I have connected succesfully, although I don't know if anyone is online. Why doesn't it show a short message about other members in the room?  smile


http://oi48.tinypic.com/2v1q0e9.jpg

Offline

 

#277 2012-01-18 22:25:00

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

Re: Chat.PY and Other Features

JSO wrote:

Hm - it seems like I have connected succesfully, although I don't know if anyone is online. Why doesn't it show a short message about other members in the room?  smile

type /list. If that doesn't work, try manually broadcasting "<chat/online", then try again.


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

Offline

 

#278 2012-01-18 23:06:56

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

Re: Chat.PY and Other Features

JSO wrote:

Hm - it seems like I have connected succesfully, although I don't know if anyone is online. Why doesn't it show a short message about other members in the room?  smile

What Zippy said, but it's actually broadcasting ">chat/online" and then you look at the sensor-value block for "chat/online" then it should display it.

I'm online now.  smile

Offline

 

#279 2012-01-20 13:22:58

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

Re: Chat.PY and Other Features

I'm on the chat now. Anyone else want to go on?


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

Offline

 

#280 2012-01-20 18:01:34

christian2000
Scratcher
Registered: 2010-11-01
Posts: 100+

Re: Chat.PY and Other Features

meee


blerp......
http://obscureinternet.com/wp-content/uploads/Fail-at-Life-Funny-Cards.png

Offline

 

#281 2012-01-20 18:58:01

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

Re: Chat.PY and Other Features

So you're not impersonating...


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

Offline

 

#282 2012-01-20 18:58:52

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

Re: Chat.PY and Other Features

bobbybee wrote:

So you're not impersonating...

It's impossible to impersonate *Magnie. He's a ServerNinja.  tongue

Offline

 

#283 2012-01-20 18:59:17

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

Re: Chat.PY and Other Features

Wow, I really didn't see it coming  smile


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

Offline

 

#284 2012-01-20 19:04:16

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

Re: Chat.PY and Other Features

Code:

# Scratch Server
# Version 1.0.0
# By: Magnie

import threading
import socket
import sys
from array import array
from time import strftime
import time
import cPickle
import hashlib
import math
#import urllib.request

class Server: 
    def __init__(self): 

        # Server Information
        self.host = '' # Game host
        self.port = int( raw_input("Host Port: ") ) # Game port
        self.backlog = 5 # Maximum clients?
        self.size = 1024 # Maximum receive size
        self.server = None 
        self.threads = [] # Client threads ( just a record )
        
    def setup(self):
        
        try:
            vari_file = open("variables.txt", "r") # All the variables and values are saved to this file, so they still exist even after a Server reset
            self.variables = cPickle.load(vari_file)
            vari_file.close()
        except IOError:
            vari_file = open("variables.txt", "w")
            cPickle.dump({}, vari_file)
            vari_file.close()
            self.variables = {} # { 'variable' : 'value' }
        
        try:
            bad_file = open("badwords.txt", "r") # Bad words list.
            self.badwords = bad_file.read().split("\n")
            self.badwords.pop()
            bad_file.close()
        except IOError:
            bad_file = open("badwords.txt", "w")
            bad_file.close()
            self.badwords = []
        
        try:
            good_file = open("goodwords.txt", "r") # Good words list.
            self.goodwords = good_file.read().split("\n")
            self.goodwords.pop()
            good_file.close()
        except IOError:
            good_file = open("goodwords.txt", "w")
            good_file.close()
            self.goodwords = []
        
        try:
            auth_file = open("accounts.txt", "r") # All the accounts are saved here.
            self.auth = cPickle.load(auth_file)
            auth_file.close()
        except IOError:
            auth_file = open("accounts.txt", "w")
            cPickle.dump({}, auth_file)
            auth_file.close()
            self.auth = {} # { user : ['word', 'rank'] }
            save()
        
        try:
            log_file = open("log.txt", "r") # This logs all data sent to the server, can be used for debugging purposes.
            self.log = log_file.read().split("\n")
            log_file.close()
        except IOError:
            log_file = open("log.txt", "w")
            log_file.close()
            self.log = []
        
        self.blocked_ips = [] # Blocked IP list.
        self.mute_list = [] # Muted name list for chat.
        
        self.motd = '''
        Welcome to the Server!
        If you are seeing this, you have successfully connected!
        Please read the rules on the forum thread before chatting
        with anyone.
        
        http://scratch.mit.edu/forums/viewtopic.php?pid=1083067
        Please support it so you can chat in your browser!
        ''' # The MOTD. I may add a feature so I can change it without reseting the server.
        self.join_message = " has joined!" # The messages for joining and leaving.
        self.left_message = " has left!"

    def open_socket(self): 
        try: # Try settings up the connection
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Define socket type
            self.server.bind((self.host,self.port)) # Bind server to port
            self.server.listen( self.backlog ) # Wait for clients to connect
        except socket.error, (value,message): # If it can't connect Then print out the error and shut down the server.
            if self.server: 
                self.server.close() 
            print "Could not open socket: " + message 
            sys.exit(1)

    def run(self):
        self.open_socket() # Open a socket so people can connect.
        self.setup() # Run the set up
        running = 1
        id = 0 # To define each client.
        while running:
            id += 1 # Increase so no client has the same ID.
            c = Client(self.server.accept()) # Waits for a client then accepts it.
            print c.address[0]
            if c.address[0] not in self.blocked_ips: # Checks if the user is not in the IP ban list.
                c.start() # Starts it.
                self.threads.append(c) # Adds it to a list so the variable c and be used for the next client.

        # Disconnect all clients.
        self.server.close() # Disconnect socket.
        for c in self.threads: # For each thread
            c.join() # End that thread.

class Client(threading.Thread): 
    def __init__(self,(client,address)): 
        threading.Thread.__init__(self) 
        self.client = client 
        self.address = address 
        self.size = 1024 
        self.follow = []
        
        self.chat = Chat("")
        #self.space = Space()
        
        self.alive = 1 # If the socket some how disconnects in a way that the thread doesn't die,
                       # this is switched to zero and the thread will be deleted.
        
        if self.address in s.blocked_ips:
            print self.address, 'failed to connect.'
        else:
            print self.address, 'has connected.'

    def run(self): 
        self.running = 1 
        while self.running:

            try:
                data = self.client.recv(self.size) # Wait for data.
                save() # Save the log
                if self.address[0] in s.blocked_ips: # If the IP is banned while being connect,
                    data = ''                        # it sets the data to '' so the is disconnects.
            except: # If there is an error of any kind, it disconnects the client.
                data = ''
            
            data = parseScratchCommand(data) # Parse the data.
            #print self.address[0], ":", data
            
            if data[0] == '*ping': # If a user wants to test something, they can send a ping.
                self.client.send("Pong")
                print self.address[0], 'sent a ping.'
            
            elif data[0] == 'sensor-update': # If a variable is updated
                
                print self.address[0], ":", data
                data[1] = data[1].replace('"', "") # Put it into an easy structure.
                data[2] = data[2].replace('"', "")
                data[-1] = data[-1].replace('"', "")
                
                args = data[2:-1]
                
                if data[1] == "Name":
                    if self.chat.name == "":
                        self.chat.name = data[2]
                        self.chat.rank = '-'
                    else:
                        if self.chat.rank != '#' and self.name not in s.mute_list:
                            self.chat.name = data[2]
                            self.chat.rank = "-"
                
                if data[1] == "Space/TurnL":
                    self.space.turn_left()
                
                if data[1] == "Space/TurnR":
                    self.space.turn_right()
                
                if data[1] == "Space/Forward":
                    self.space.go_forward()
                
                if data[1] == "Space/Shot":
                    self.space.fire_shot()
                
                continue

            elif data[0] == 'broadcast': # If a broadcast is sent
                
                data[1] = data[1][1:]
                data[-1] = data[-1][:-1]
                
                if data[1] == '': continue
                
                if data[1][0] == '<' or data[1][0] == '>':
                    if data[1][1:] not in s.variables: # If the variable doesn't exist, create it.
                        s.variables[ data[1][1:] ] = ""
                        
                if data[1][0] == '>': # The client wants to get the value of a variable
                    vari = data[1][1:]
                    value = s.variables[ vari ]
                    
                    # Start of Reserved Variables #
                    if vari == 'time':
                        value = strftime("%H:%M:%S")
                    
                    if vari == 'chat/online':
                        value = self.chat.online()
                    
                    #  End of Reserved Variables  #
                    
                    self.get_var(vari, value)
                    
                elif data[1][0] == '<': # The client wants to set a variable.
                    vari = data[1][1:]
                    value = ' '.join( data[2:] )
                    
                    # Start of Reserved Variables #
                    if vari == 'chat':
                        value = self.chat.message(value)
                        if value == False:
                            continue
                            
                    if vari == 'chat/addGood':
                        value = self.chat.addGood(value)
                    
                    if vari == 'chat/addBad':
                        value = self.chat.addBad(value)
                    
                    if vari == 'chat/mute':
                        value = self.chat.mute(value)

                    if vari == 'chat/ipban':
                        value = self.chat.ipban(value)
                    
                    if vari == 'chat/ipof':
                        value = self.chat.ipof(value)
                  
                    if vari == 'chat/auth':
                        value = self.chat.auth(value)
                    
                    if vari == 'chat/rank':
                        value = self.chat.ranker(value)
                    
                    if vari == 'chat/temprank':
                        value = self.chat.ranker2(value)
                    
                    if vari == 'chat/create':
                        value = self.chat.create(value)
                    
                    if vari == 'chat/delete':
                        value = self.chat.delete(value)
                    
                    if vari == 'chat/motd':
                        self.chat.new_motd(value)
                    
                    if vari == 'direct':
                        value = self.chat.direct_broadcast(value)
                    
                    #  End of Reserved Variables  #
                    
                    self.set_var( vari, value )
                    
                    s.log.append(self.address[0]+"("+self.chat.name+"): "+vari+" = "+value)
                    
                elif data[1][0] == '^': # The client wants to "follow" a variable for updates.
                    vari = data[1][1:]
                    
                    self.follow_var( vari )
                
                elif data[1] == '*flush': # Clean up all the dead threads.
                    i = 0
                    deleted = 0
                    for ip in s.threads:
                        if ip.alive == 0:
                            s.threads.pop(i)
                            deleted += 1
                        i += 1
                    self.client.send( sendScratchCommand('sensor-update "*flushed" "'+str(deleted)+'"') )
                    print "Deleted",deleted,"threads."
                    
                else:
                    print self.address[0], ":", data
                    s.log.append(self.address[0]+"("+self.chat.name+"): "+str(data))
                    continue
            
            else: # If there isn't anything the data goes with, disconnect.
                print self.address[0], ":", data
                self.client.close() # Close the connection.
                print self.address, 'has closed the connection.' # Debugging purposes and just informative if you are watching it.
                self.running = 0
                self.alive = 0
                
                if "chat" in self.follow:
                    self.set_var( "chat", self.chat.left() )
                
    def follow_update(self, vari):
        if vari in self.follow and self.alive == 1:
            value = s.variables[ vari ]
            try:
                self.client.send( sendScratchCommand('sensor-update "'+vari+'" "'+value+'"') )
                self.client.send( sendScratchCommand('broadcast "^follow_update_'+vari+'"') )
                self.client.send( sendScratchCommand('broadcast "^follow_update"') )
            except:
                print '--Dead Thread--'
                self.running = 0
                self.alive = 0
                self.join()
    
    def set_var(self, vari, value):
                    
        s.variables[ vari ] = value
        
        #if self.alive == 1:
        #    self.client.send( sendScratchCommand('sensor-update "'+vari+'" "'+value+'"') )
                    
        for follow in s.threads:
            follow.follow_update(vari)
                    
        print self.address[0],":",vari,"=",value
                    
        save()
        s.variables[ "last_save" ] = "["+strftime("%H:%M:%S")+"]"

    def get_var(self, vari, value):
        
        if self.alive == 1:
            self.client.send( sendScratchCommand('sensor-update "'+vari+'" "'+value+'"') ) # Send client the value of 'vari'
                    
        print self.address[0], "retrevied variable ", vari,"."

    def follow_var(self, vari):
        self.follow.append( vari )
                    
        if vari == 'chat' and self.alive == 1:
            motd = self.chat.motd()
            self.client.send( sendScratchCommand('sensor-update "chat" "'+motd+'"') )
            self.client.send( sendScratchCommand('broadcast "^follow_update"') )
            self.client.send( sendScratchCommand('broadcast "^follow_update_chat"') )
            time.sleep(0.3)
            self.set_var("chat", self.chat.name+" has joined!")
            
                    
        print self.address, "has followed", vari,"."
    
class Chat:
    
    def __init__(self, name):
        self.name = name
        self.rank = "-" # Ranks from Highest to Lowest: *, ~, +, -, !, #
        self.warned = 0
        self.old_chat = ""
    
    def message(self, value):
    
        if self.name in s.mute_list and self.rank not in "*~" or self.rank == '#':
            return False
        
        if value == self.old_chat:
            return False
        
        self.old_chat = value
        
        skip = censor(value)
        if skip == 'skip' or self.rank not in '-!#':
            pass
        elif skip == 'cuss':
            if self.warned == 0:
                value = "["+strftime("%H:%M:%S")+"]ServerNinja: No swearing, "+self.name+", you have been warned."
                s.mute_list.append(self.name)
                self.warned = 1
            else:
                value = "["+strftime("%H:%M:%S")+"]ServerNinja: No swearing, "+self.name+", you have been muted. If you were muted because of typing out a word that was not a swear word, please contact Magnie or Ohaider to add the word as an exception and they will unmute you."
                self.warned = 0
        
        value = value.split(":")
        value[0] = self.rank+self.name
        value = ':'.join(value)
        value = "["+strftime("%H:%M:%S")+"]"+value
        
        return value
    
    def auth(self, value):
        value = value.split(" ")
        if len(value) != 2:
            return self.name+ ' has failed to login.'
        name = value[0]
        word = hashlib.sha512( value[1] ).digest()
        if name not in s.auth:
            return self.name+ ' has failed to login as '+ name
        
        if s.auth[name][0] == word:
            if s.auth[name][1] != "*" and s.auth[name][1] != "~" and self.rank == '#':
                return self.name+ ' has failed to login as '+ name
            
            self.rank = s.auth[name][1]
            self.name = name
            return name+' has logged in as '+self.name+'.'
        else:
            self.rank = "!"
            return self.name+ ' has failed to login as '+ name
            
    def create(self, value):
        if self.name in s.mute_list:
            return self.name+ " has failed to create "+ name
        value = value.split(" ")
        if len(value) != 2:
            return self.name+ ' has failed to create an account.'
        name = value[0]
        word = hashlib.sha512( value[1] ).digest()
        if name in s.auth:
            return name+ " is already taken."
        else:
            s.auth[name] = [word, '+']
            return self.name+ " has created "+ name
            save()
    
    def delete(self, value):
        if self.rank != '*':
            return self.name+" has attempted to delete "+value
        
        if value in s.auth:
            del s.auth[value]
            return self.name+" has deleted account "+value
        return self.name+" has attempted to delete the account "+value
    
    def mute(self, value):
        if self.rank not in '*~':
            return self.name+" tried to mute "+value
        if value in s.mute_list:
            s.mute_list.remove(value)
        else:
            s.mute_list.append(value)
        
        return self.name+" has either muted or unmuted "+value
    
    def ipban(self, value):
        if self.rank != '*':
            return self.name+" tried to ip ban."
        if value in s.blocked_ips:
            s.blocked_ips.remove(value)
        else:
            s.blocked_ips.append(value)
    
    def ipof(self, value):
        if self.rank not in '*~':
            return self.name+" tried to find the IP of "+value
        
        for ip in s.threads:
            if ip.chat.name == value:
                return ip.address[0]
        return "No such user."
    
    def ranker(self, value):
        
        if self.rank == '*':
            value = value.split(' ')
            name = value[0]
            rank = value[1]
            if name in s.auth:
                s.auth[name] = [s.auth[name][0], rank]
                return self.name+ " has set "+ name+ " to "+rank
            else:
                return self.name+ " has failed to set "+ name+ " to "+rank
        
    def ranker2(self, value):
        if self.rank == '*':
            value = value.split(' ')
            name = value[0]
            rank = value[1]
            for ip in s.threads:
                if ip.chat.name == name:
                    ip.chat.rank = rank
        
        return 'False'
    
    def motd(self):
    
        return s.motd
    
    def join(self):
        
        return self.name+s.join_message
    
    def left(self):
        
        return self.name+s.left_message
    
    def addGood(self, value):
        if self.rank not in '*~':
            return self.name+', please login as a Moderator or Awesome Owner.'
        if value in s.goodwords:
            s.goodwords.remove(value)
        else:
            s.goodwords.append(value)
        return "["+strftime("%H:%M:%S")+"] Word Added."
    
    def addBad(self, value):
        if self.rank not in '*~':
            return self.name+', please login as a Moderator or Awesome Owner.'
        if value in s.badwords:
            s.badwords.remove(value)
        else:
            s.badwords.append(value)
        return "["+strftime("%H:%M:%S")+"] Word Added."
    
    def online(self):
        
        online = ""
        for user in s.threads:
            if "chat" in user.follow and user.alive == 1:
                online += user.chat.name+", "
        online = online[0:-2]+"."
        return online
    
    def new_motd(self, value):
        if self.rank not in '*':
            return "Fail"
        
        s.motd = value
    
    def direct_broadcast(self, value):
        
        value = value.split(' ')
        
        for ip in s.threads:
            if ip.chat.name == value[0]:
                while xrange(1, int(value[1])):
                    ip.client.send( sendScratchCommand( 'broadcast "'+' '.join( value[2:] )+'"' ) )
        
        return '0'
    
def save():
    try:
        vari_file = open("variables.txt", "w")
        cPickle.dump(s.variables, vari_file) # variable : value
        vari_file.close()
    
        auth_file = open("accounts.txt", "w")
        cPickle.dump(s.auth, auth_file) # user : ['word', 'rank']
        auth_file.close()
        
        bad_file = open("badwords.txt", "w")
        for line in s.badwords:
            bad_file.write(line+"\n")
        bad_file.close()
        
        good_file = open("goodwords.txt", "w")
        for line in s.goodwords:
            good_file.write(line+"\n")
        good_file.close()
        
        log_file = open("log.txt", "w")
        for log in s.log:
            log_file.write(log+"\n")
        log_file.close()
    except IOError ,e:
        print e

def parseScratchCommand(cmd):
    cmd = cmd[4:] # Remove the first four letters ( it's annoying to deal with )
    cmd = cmd.split(' ') # Split the string where there is a space. It helps to find out broadcasts.
    return cmd # Return the list. ['broadcast/sensor-update', 'valueWord1', 'valueWord2']

def sendScratchCommand(cmd): # I was never sure what this did, but it's required.
    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))
    return (a.tostring() + cmd)

def censor(value):
    value = value.lower().split()
    for word in value:
        cuss = 0
        for bad in s.badwords:
            if bad in word:
                for good in s.goodwords:
                    if bad in good and word == good:
                        cuss = 0
                        break
                    else:
                        cuss = 1
        if cuss == 0:
            continue
        else:
            break
    if cuss == 1:
        return 'cuss'
    else:
        return 'skip'
        
def authenticateUser(username, password):
        string = "http://scratch.mit.edu/api/authenticateuser?username=", username, "&password=" , password
        string = "".join(string)
        fp = urllib.request.urlopen(string)
        result = fp.read()
        fp.close()
        result = result.decode("utf8")
        if result == ' \r\nfalse':
            return False
        else:
            return True

if __name__ == "__main__":
    s = Server() 
    s.run()

Current server source.

Offline

 

#285 2012-01-20 21:20:22

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

Re: Chat.PY and Other Features

zippynk wrote:

I'm on the chat now. Anyone else want to go on?

Again, but if I'm not online on the forums, this post is most likely outdated.

Last edited by zippynk (2012-01-21 11:09:03)


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

Offline

 

#286 2012-01-21 18:56:00

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

Re: Chat.PY and Other Features

I updated the FireMMO thread, the newest post has a link to the Windows version of FireMMO.


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

Offline

 

#287 2012-01-21 21:52:19

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

Re: Chat.PY and Other Features

Wait a second, "Magnie has muted or unmuted bobbybee". Was that a mistake?


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

Offline

 

#288 2012-01-22 00:44:29

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

Re: Chat.PY and Other Features

zippynk wrote:

Wait a second, "Magnie has muted or unmuted bobbybee". Was that a mistake?

I don't think he's muted if that's what you are wondering.

Offline

 

#289 2012-01-22 04:03:34

J_B_Production
Scratcher
Registered: 2011-09-18
Posts: 100+

Re: Chat.PY and Other Features

It doesnt work!

Offline

 

#290 2012-01-22 06:36:43

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

Re: Chat.PY and Other Features

Well, I can't talk on my normal name.


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

Offline

 

#291 2012-01-22 07:47:41

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

Re: Chat.PY and Other Features

Oh, Magnie, can you tell me if you can get the FireMMO binary working. (I updated the link, at least scroll down)
Btw, the port the Windows binary is using it 42002.


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

Offline

 

#292 2012-01-22 11:40:19

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

Re: Chat.PY and Other Features

bobbybee wrote:

Well, I can't talk on my normal name.

I noticed that the last mute was that "Magnie has either muted or unmuted bobbybee," but I don't think that happened on purpose. I think you should request for Magnie to un-mute you


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

Offline

 

#293 2012-01-22 12:07:25

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

Re: Chat.PY and Other Features

Nah, I can survive using a name like bobbybeeRealAccount...


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

Offline

 

#294 2012-01-23 10:31:03

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

Re: Chat.PY and Other Features

J_B_Production wrote:

It doesnt work!

Could you explain what's wrong?

Also bobbybee, next time you are on, can you try your name again? I think I fixed it, though I'm not entirely sure.

Last edited by Magnie (2012-01-23 10:34:06)

Offline

 

#295 2012-01-23 15:51:06

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

Re: Chat.PY and Other Features

Alright. I'll try in a few hours. (I have very limited time right now)


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

Offline

 

#296 2012-01-24 13:58:59

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

Re: Chat.PY and Other Features

New Announcement!

You can skip downloading the project now and go to this link: http://zero-bgn.de/scratchgerman/meshjava/ which uses a Mesh Java Player, allowing you to chat with your browser! All thanks to ZeroLuck!

Offline

 

#297 2012-01-25 07:12:17

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

Re: Chat.PY and Other Features

Do you know how to set it up with FireMMO? Speaking of FIreMMO, has the new version I released worked?


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

Offline

 

#298 2012-01-25 13:38:03

ZeroLuck
Scratcher
Registered: 2010-02-23
Posts: 500+

Re: Chat.PY and Other Features

@Magnie
I am able to chat with my MeshJavaPlayer with many accounts at once...
( If you want I can send you a screen shot  big_smile  )
But can you look in the "Java console"?
I think there will be the stack trace of the error...

Last edited by ZeroLuck (2012-01-25 13:38:36)


http://3.bp.blogspot.com/-oL2Atzp0Byw/T465vIQ36dI/AAAAAAAAADo/1vqL4PvhkM0/s1600/scratchdachwiki.png

Offline

 

#299 2012-01-28 10:14:46

cocolover76
Scratcher
Registered: 2011-10-09
Posts: 500+

Re: Chat.PY and Other Features

Stop IP-banning me. It's getting annoying. I didn't break any rules.


http://i.imgur.com/HfEPZ.gifhttp://i.imgur.com/pvKb6.png

Offline

 

#300 2012-01-28 10:52:18

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

Re: Chat.PY and Other Features

cocolover76 wrote:

Stop IP-banning me. It's getting annoying. I didn't break any rules.

I never IP banned you. In fact, I've never IP banned anyone yet.

Offline

 

Board footer