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

#76 2011-12-02 00:45:03

ohaiderstudios
Scratcher
Registered: 2010-10-31
Posts: 100+

Re: Lets make a wwm!!

Okay...a little bit of slowdown on code generator (called PynCone) development. I think I'll have to extensively modify the server code to make it customizable...this'll take longer than I thought!  tongue
If you want to check out the working demo, and check for updates, click here


Fork Clamor on GitHub!

Offline

 

#77 2011-12-02 11:02:22

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

Re: Lets make a wwm!!

Hmm, what needs to be modified?

Offline

 

#78 2011-12-02 19:18:07

ohaiderstudios
Scratcher
Registered: 2010-10-31
Posts: 100+

Re: Lets make a wwm!!

Magnie wrote:

Hmm, what needs to be modified?

Just some stuff, like the fact that the server does some unwanted processing (like 'up' changes the y value by 1, which isn't needed if the game doesn't involve y or 'up' or anything like that)
I just need it to be more generic.


Fork Clamor on GitHub!

Offline

 

#79 2011-12-02 19:30:33

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

Re: Lets make a wwm!!

ohaiderstudios wrote:

Magnie wrote:

Hmm, what needs to be modified?

Just some stuff, like the fact that the server does some unwanted processing (like 'up' changes the y value by 1, which isn't needed if the game doesn't involve y or 'up' or anything like that)
I just need it to be more generic.

Oh yeah, that was just used as an example. You can take all of that code and remove it. It will still work without any problems ( besides the client disconnecting ).

Code:

class Client(threading.Thread): 
    def __init__(self,(client,address)): 
        threading.Thread.__init__(self) 
        self.client = client 
        self.address = address 
        self.size = 1024 
        
        print self.address, 'has connected.'

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

            data = self.client.recv(self.size) # Wait for data.
            data = parseScratchCommand(data) # Parse the data.
            print data # Print it
            if data[0] == 'sensor-update': # If a variable is updated
                continue

            elif data[0] == 'broadcast': # If a broadcast is sent
                continue

                else:
                    continue
            
            else: 
                self.client.close() # Close the connection.
                print self.address, 'has closed the connection.' # Debugging purposes and just informative if you are watching it.
                running = 0

That is the skeleton of the Client class. It'll ignore all broadcasts and sensor-updates, if any other data is sent, it will disconnect the client.

Offline

 

#80 2011-12-02 19:45:28

flashgocrazy
Scratcher
Registered: 2011-01-12
Posts: 500+

Re: Lets make a wwm!!

I made a app for the worldzord fourms, but I have to wait for paddle2see to say I can post a link to the worldzord fourms  sad


◕‿◕

Offline

 

#81 2011-12-02 22:42:11

ohaiderstudios
Scratcher
Registered: 2010-10-31
Posts: 100+

Re: Lets make a wwm!!

This may seem really noobish, but I just can't figure it out.
In Scratch, once I have enabled RSC, how can I change the
("slider" sensor value)
to
("x" sensor value)


Fork Clamor on GitHub!

Offline

 

#82 2011-12-03 01:37:51

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

Re: Lets make a wwm!!

ohaiderstudios wrote:

This may seem really noobish, but I just can't figure it out.
In Scratch, once I have enabled RSC, how can I change the
("slider" sensor value)
to
("x" sensor value)

Make sure the sensor-update is sent.

sensor-update "x" "150"

Offline

 

#83 2011-12-05 01:24:11

pen13
Scratcher
Registered: 2010-08-27
Posts: 100+

Re: Lets make a wwm!!

Meep join?


http://womrealms.com/char.php?nomimg1:3ri855a
pen13 http://blocks.scratchr.org/API.php?user=pen13&action=onlineStatus green= online gray=offline

Offline

 

#84 2011-12-11 19:44:26

flashgocrazy
Scratcher
Registered: 2011-01-12
Posts: 500+

Re: Lets make a wwm!!

pen13 wrote:

Meep join?

ok, would you like to be the squeak smalltalk coder?


◕‿◕

Offline

 

#85 2011-12-13 16:30:27

flashgocrazy
Scratcher
Registered: 2011-01-12
Posts: 500+

Re: Lets make a wwm!!

bump


◕‿◕

Offline

 

#86 2011-12-17 09:37:17

flashgocrazy
Scratcher
Registered: 2011-01-12
Posts: 500+

Re: Lets make a wwm!!

Magnie wrote:

Okay, I have created the Scratch Live Clone for the Python Server:

Code:

# Scratch Server
# Version 1.0.0
# By: Magnie

import threading
import socket
import sys
from array import array

class Server: 
    def __init__(self): 

        # Server Information
        self.host = '' # Game host
        self.port = 42002 # Game port
        self.backlog = 5 # Maximum clients?
        self.size = 1024 # Maximum receive size
        self.server = None 
        self.threads = [] # Client threads ( just a record )
        self.variables = {} # user : value

        # Game Information

    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()
        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.
            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 
        
        print self.address, 'has connected.'

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

            data = self.client.recv(self.size) # Wait for data.
            data = parseScratchCommand(data) # Parse the data.
            print data # Print it
            if data[0] == 'sensor-update': # If a variable is updated
                continue

            elif data[0] == 'broadcast': # If a broadcast is sent
                
                data[1] = data[1][1:]
                data[-1] = data[-1][:-1]
                print data
                
                if data[1][0] == '<' or data[1][0] == '>':
                    if data[1][1:] not in s.variables:
                        s.variables[ data[1] ] = ""
                        
                if data[1][0] == '>':
                    vari = data[1][1:]
                    value = s.variables[ vari ]
                    self.client.send( sendScratchCommand('sensor-update "'+vari+'" '+value) )
                elif data[1][0] == '<':
                    vari = data[1][1:]
                    value = ' '.join( data[2:] )
                    s.variables[ vari ] = value
                    self.client.send( sendScratchCommand('sensor-update "'+vari+'" '+value) )
                else:
                    continue
            
            else: 
                self.client.close() # Close the connection.
                print self.address, 'has closed the connection.' # Debugging purposes and just informative if you are watching it.
                running = 0 
                
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)

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

Will run on Windows and I see no reason it shouldn't on any other OS. You set variables by broadcasting "<var value" and you get variables with ">var". "<" set; ">" get. Now all I need to add it the "global broadcast" system, where if the user decides to "follow" a variable, then the user will be sent the update when it is updated.  smile  This will probably be the hardest part.

Edit: Or it won't... Added "global broadcast" and fixed a few bugs in the first one:

Code:

# Scratch Server
# Version 1.0.0
# By: Magnie

import threading
import socket
import sys
from array import array

class Server: 
    def __init__(self): 

        # Server Information
        self.host = '' # Game host
        self.port = 42002 # Game port
        self.backlog = 5 # Maximum clients?
        self.size = 1024 # Maximum receive size
        self.server = None 
        self.threads = [] # Client threads ( just a record )
        self.variables = {} # user : value

        # Game Information

    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()
        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.
            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 = []
        
        print self.address, 'has connected.'

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

            data = self.client.recv(self.size) # Wait for data.
            data = parseScratchCommand(data) # Parse the data.
            print data # Print it
            if data[0] == 'sensor-update': # If a variable is updated

                continue

            elif data[0] == 'broadcast': # If a broadcast is sent
                
                data[1] = data[1][1:]
                data[-1] = data[-1][:-1]
                print data
                
                if data[1] == '': continue
                
                if data[1][0] == '<' or data[1][0] == '>':
                    if data[1][1:] not in s.variables:
                        s.variables[ data[1][1:] ] = ""
                        
                if data[1][0] == '>':
                    vari = data[1][1:]
                    value = s.variables[ vari ]
                    self.client.send( sendScratchCommand('sensor-update "'+vari+'" "'+value+'"') )
                    
                    for follow in s.threads:
                        follow.follow_update(vari)
                    
                elif data[1][0] == '<':
                    vari = data[1][1:]
                    value = ' '.join( data[2:] )
                    s.variables[ vari ] = value
                    self.client.send( sendScratchCommand('sensor-update "'+vari+'" "'+value+'"') )
                    
                    for follow in s.threads:
                        follow.follow_update(vari)
                    
                elif data[1][0] == '^':
                    vari = data[1][1:]
                    self.follow.append( vari )
                    
                else:
                    continue
            
            else: 
                self.client.close() # Close the connection.
                print self.address, 'has closed the connection.' # Debugging purposes and just informative if you are watching it.
                running = 0 
                
    def follow_update(self, vari):
        if vari in self.follow:
            value = s.variables[ vari ]
            self.client.send( sendScratchCommand('sensor-update "'+vari+'" "'+value+'"') )
            self.client.send( sendScratchCommand('broadcast "^follow_update"') )
            
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)

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

Broadcast Cheat Sheet:
^var = Follow var
>var = Get var
<var value = Set var to value

Basically send a broadcast with one of the special ( >/</^ ) characters at the beginning to set/get/follow a variable. Variables can only be one word long.

Could you test it and find bugs?

yeah, but I need a tutorial how to set it up on localhost


◕‿◕

Offline

 

#87 2011-12-17 11:12:11

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

Re: Lets make a wwm!!

flashgocrazy wrote:

yeah, but I need a tutorial how to set it up on localhost

Do you know what Python is? Find out what it is, then download the program and install it. Once you've done that, create a .txt document ( on Desktop, right-click select 'New' then select 'New Text Document' ). Rename the text document to any name, and change the .txt to .py. After that, open the .txt document in Notepad ( double-clicking it won't work ) then copy the code to the server ( the bottom one of the post you quoted ) and paste it into the Document. Save the document then double click the file. A black box should appear and may stay blank ( with a cursor ). If that happens then the server is working! If it doesn't create a .bat file ( by renaming the .txt file ) and put two lines of code in it:

Code:

[put the Python Server name here].py
pause

Run it again then copy all the text and post the error here ( preferably in [code] boxes ). Remove any info about your computer first though.  smile

Do you same with the client. But before you run the Python client, open Scratch and turn on Remote Sensors ( go to sensors, at the bottom below the HR line, right-click any of the blocks and select "Enable Remote Sensors" ). After the dialog box saying that it has been enabled, run the Python Client, it should say "Connecting To Scratch" and "Connecting To Server".

If you come across an error, copy the trace-back and paste it here. Though before you do that, read through the text of the client ( there will be comments after # signs ) and you may find your problem. A common error is that the server and client won't be able to connect, if it's that, make sure the 'HOST' variables values are the correct IP address ( 127.0.0.1, if you are just doing it on your computer ).

Offline

 

Board footer