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

#1 2010-11-16 12:48:04

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

Python Network Mirror for Scratch

So I've created a mirror that takes what is sent to it from Scratch and sends it to a Python server. This is basically the opposite of what Mesh does. Instead of sharing the variables with all clients connected to it, all variables are kept to a single client unless you program the server to share the variable. So I've created a quick project for an example to be built off of.

http://scratch.mit.edu/projects/Magnie/1419926 <- The Example Scratch Project

The Python Mirror:

Code:

# Scratch Mirror
# Version 1.0.0
# By: Magnie

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
    scratchServer.send(data)
    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 = 42002

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 should easily be shrunk into a smaller mirror, for example:

Code:

# Scratch Mirror
# Version 1.0.0
# By: Magnie

from array import array
import socket
import time

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 = 42002

scratchSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
scratchSock.connect((CHOST, CPORT))

scratchServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
scratchServer.connect((SHOST, SPORT))

print("Fully Connected.")

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

Mirror Requirements: Python 2.6+, Scratch, Server to Connect to.

Now for the Example Server:

Code:

#!/usr/bin/env python

"""
An echo server that uses threads to handle multiple clients at a time.
Entering any line of input at the terminal will exit the server.
"""

import select
import socket
import sys
import threading
from array import array
import time
import re


# Parse Data Definitions
def parseData(str):
    #Check for a broadcast
    e = re.search('broadcast\s\"(.*)\"',str)
    if e:
        #We have a broadcast!
        return 'parsed = 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!
        return 'parsed = 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!
        return 'parsed = sensorUpdateIn("'+e.group(1)+'","'+e.group(2)+'")'

def sensorUpdateIn(var,value):
    #print "Scratch changed "+var+" to: "+value
    return 'sensor-update '+value
    
    
def broadcastIn(broadcast):
    #print "Scratch broadcasted: "+broadcast
    return 'broadcast '+broadcast
# End

class Server:
    def __init__(self):
        self.host = ''
        self.port = 42002
        self.backlog = 5
        self.size = 1024
        self.server = None
        self.threads = []

    def open_socket(self):
        try:
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server.bind((self.host,self.port))
            self.server.listen(5)
        except socket.error, (value,message):
            if self.server:
                self.server.close()
            print "Could not open socket: " + message
            sys.exit(1)

    def run(self):
        self.open_socket()
        input = [self.server,sys.stdin]
        running = 1
        while running:
            inputready,outputready,exceptready = select.select(input,[],[])

            for s in inputready:

                if s == self.server:
                    # handle the server socket
                    c = Client(self.server.accept())
                    c.start()
                    self.threads.append(c)

                elif s == sys.stdin:
                    # handle standard input
                    junk = sys.stdin.readline()
                    running = 0

        # close all threads

        self.server.close()
        for c in self.threads:
            c.join()

class Client(threading.Thread):
    def __init__(self,(client,address)):
        threading.Thread.__init__(self)
        self.client = client
        self.address = address
        self.size = 1024
        lcs.append([0,0])
        #print lcs
        self.ids = len(lcs)-1
        #print self.ids

    def run(self):
        #print self.address,'has connected.'
        running = 1
        while running:
            data = self.client.recv(self.size)
            if data:
                exec parseData(data)
                if parsed == 'broadcast start': # Start/Setup
                    exe = '''sendScratchCommand('sensor-update "x" "'''+str(lcs[self.ids][0])+'''"')
sendScratchCommand('sensor-update "y" "'''+str(lcs[self.ids][1])+'''"')
'''
                # Movement Start
                elif parsed == 'broadcast up': # Move Up
                    lcs[self.ids][1] += 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "y" "'''+str(lcs[self.ids][1])+'''"')'''
                elif parsed == 'broadcast down': # Move Down
                    lcs[self.ids][1] -= 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "y" "'''+str(lcs[self.ids][1])+'''"')'''
                elif parsed == 'broadcast left': # Move Left
                    lcs[self.ids][0] -= 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "x" "'''+str(lcs[self.ids][0])+'''"')'''
                elif parsed == 'broadcast right': # Move Right
                    lcs[self.ids][0] += 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "x" "'''+str(lcs[self.ids][0])+'''"')'''
                # Movement End

                else: # Unknown Command
                    exe = 'print "Error, no such command."'
                self.client.send(exe)
            else:
                self.client.close()
                running = 0

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

Server Requirements: Python 2.6+, Ubuntu ( Or any other Unix System, untested on Mac. ), will not work on Windows.

Also, this Server goes with the Example Scratch Project that I linked to at the top of this Topic. You can move Up, Down, Left and Right. And that's all.

Another Note: The mirror only works for one Scratch program at a time. So you won't be able to test two projects out on one computer, unless you change the port and all that other stuff....... You won't be able to see another person because this is not an MMO.  smile  It's a single Player game hosted on a server.  smile

Advantages: Works over the Internet and LAN.
Disadvantages:
- Unable to make Multiplayer games with the current mirror. < Screw this, here's a way: http://scratch.mit.edu/forums/viewtopic.php?pid=602348#p602348
- Very tedious programming

So basically what you can do is create a simple Single Player RPG server.
Well, now you can create Multiplayer games.  big_smile

There isn't much, just customise it to what you want to do with it. Create a login system or something. Eh, I have no ideas what you could do with it, but you should be able to do a lot more with it than using Mesh. ( *is Anti-Mesh currently* )

I'll work on the Mirror to allow you to make a Multiplayer game later. But there's that. Have fun.  smile  - Screw this too, here's this: http://scratch.mit.edu/forums/viewtopic.php?pid=602348#p602348

P.S. I kind of realised that not many people on the Scratch Site have a Unix system with Scratch ( I made all of this on Ubuntu 9 I think ) so there isn't much luck for the Windows users to host a server and test it out. Sorry about that.  hmm

Also Credit to: http://ilab.cs.byu.edu/python/threadingmodule.html For the Threading Echo Server. Which is what the Example Server is based off of. ( Or just modified. ) Also, credit to Fullmoon for the parsing data definitions.  smile

Notes:
- The port that is being used for the Server is 42002, since Scratch uses 42001.
- For the Mirror, change SHOST to the IP Address of the server if it's not on the same computer.

Last edited by Magnie (2010-11-20 12:47:19)

Offline

 

#2 2010-11-17 21:01:49

midnightleopard
Scratcher
Registered: 2007-09-13
Posts: 1000+

Re: Python Network Mirror for Scratch

nice magnie, I didn't know you still used scratch! I know python, but nothing about the Socket Module. I consider myself good at everything else though.


http://pwp.wizards.com/5103673563/Scorecards/Landscape.png

Offline

 

#3 2010-11-17 21:19:23

fullmoon
Retired Community Moderator
Registered: 2007-06-04
Posts: 1000+

Re: Python Network Mirror for Scratch

This is really cool! I haven't tested it yet but I'll be sure to soon.


http://i302.photobucket.com/albums/nn100/fullmoon32/wow.jpg

Offline

 

#4 2010-11-17 22:34:22

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

Re: Python Network Mirror for Scratch

Midnight: Thank you.  smile  If you know any pygame and collisions, I could use some help with that to make a game maker.  smile

Fullmoon: I need to give you credit too, let me go edit it quickly. - There, edited.  smile

Also Update: I've realised you can make an MMO or at least a 2+ player game. So I won't need to update the Mirror. ( *cheers* I'm so lazy ). You can have the server update all the required variables every time you broadcast "update" or some other unique thing. And which another broadcast from the server would be named "GameUpdate" it would run through all the necessary items for input and other random stuff, then update all the locations of the players. ( Or vise-versa ) I'm working on a quick project that does exactly that. though it will take a day to program it in Python and the Project.

But oh well, and since this new networking technique isn't very popular, there's no one to drive people crazy by the suspense.  big_smile

Last edited by Magnie (2010-11-17 23:28:39)

Offline

 

#5 2010-11-20 12:41:30

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

Re: Python Network Mirror for Scratch

Okay, I've made a 1-4 multiplayer project and a server for it. Though with the Scratch Project, it could probably be coded better, or in a more understandable way. But anyways:

http://scratch.mit.edu/projects/Magnie/1428357 - Project
Server:

Code:

#!/usr/bin/env python

"""
An echo server that uses threads to handle multiple clients at a time.
Entering any line of input at the terminal will exit the server.
"""

import select
import socket
import sys
import threading
from array import array
import time
import re


# Parse Data Definitions
def parseData(str):
    #Check for a broadcast
    e = re.search('broadcast\s\"(.*)\"',str)
    if e:
        #We have a broadcast!
        return 'parsed = 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!
        return 'parsed = 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!
        return 'parsed = sensorUpdateIn("'+e.group(1)+'","'+e.group(2)+'")'
    return 'parsed = None'

def sensorUpdateIn(var,value):
    #print "Scratch changed "+var+" to: "+value
    return 'sensor-update '+value
    
    
def broadcastIn(broadcast):
    #print "Scratch broadcasted: "+broadcast
    return 'broadcast '+broadcast
# End

class Server:
    def __init__(self):
        self.host = ''
        self.port = 42002
        self.backlog = 5
        self.size = 1024
        self.server = None
        self.threads = []

    def open_socket(self):
        try:
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server.bind((self.host,self.port))
            self.server.listen(5)
        except socket.error, (value,message):
            if self.server:
                self.server.close()
            print "Could not open socket: " + message
            sys.exit(1)

    def run(self):
        self.open_socket()
        input = [self.server,sys.stdin]
        running = 1
        while running:
            inputready,outputready,exceptready = select.select(input,[],[])

            for s in inputready:

                if s == self.server:
                    # handle the server socket
                    c = Client(self.server.accept())
                    c.start()
                    self.threads.append(c)
                    #if len(self.threads) < 4: # If there aren't already 4 players, then allow connection
                    #    c = Client(self.server.accept())
                    #    c.start()
                    #    self.threads.append(c)
                    #else: # If there are 4 players, then deny connection.
                    #    Client.close()

                elif s == sys.stdin:
                    # handle standard input
                    junk = sys.stdin.readline()
                    running = 0

        # close all threads

        self.server.close()
        for c in self.threads:
            c.join()

class Client(threading.Thread):
    def __init__(self,(client,address)):
        threading.Thread.__init__(self)
        self.client = client
        self.address = address
        self.size = 1024
        lcs.append([0,0])
        #print lcs
        self.ids = len(lcs)-1
        #print self.ids

    def run(self):
        #print self.address,'has connected.'
        running = 1
        while running:
            data = self.client.recv(self.size)
            if data: # Commands Start
                exec parseData(data)
                if parsed == 'broadcast start': # Start/Setup
                    exe = '''sendScratchCommand('sensor-update "id" "'''+str(self.ids)+'''"')
sendScratchCommand('sensor-update "'''+str(self.ids)+'''x" "'''+str(lcs[self.ids][0])+'''"')
sendScratchCommand('sensor-update "'''+str(self.ids)+'''y" "'''+str(lcs[self.ids][1])+'''"')
'''
                # Movement Start
                elif parsed == 'broadcast up': # Move Up
                    lcs[self.ids][1] += SPEED
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "'''+str(self.ids)+'''y" "'''+str(lcs[self.ids][1])+'''"')'''
                elif parsed == 'broadcast down': # Move Down
                    lcs[self.ids][1] -= SPEED
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "'''+str(self.ids)+'''y" "'''+str(lcs[self.ids][1])+'''"')'''
                elif parsed == 'broadcast left': # Move Left
                    lcs[self.ids][0] -= SPEED
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "'''+str(self.ids)+'''x" "'''+str(lcs[self.ids][0])+'''"')'''
                elif parsed == 'broadcast right': # Move Right
                    lcs[self.ids][0] += SPEED
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "'''+str(self.ids)+'''x" "'''+str(lcs[self.ids][0])+'''"')'''
                # Movement End

                elif parsed == 'broadcast ServerUpdate': # Update all locations for each player.
                    exe = ''''''
                    x = 0
                    for i in lcs:
                        exe += '''
sendScratchCommand('sensor-update "'''+str(x)+'''y" "'''+str(lcs[x][1])+'''"')
sendScratchCommand('sensor-update "'''+str(x)+'''x" "'''+str(lcs[x][0])+'''"')
'''
                        x += 1
                    exe += '''
sendScratchCommand('sensor-update "players" "'''+str(len(s.threads))+'''"')
sendScratchCommand('broadcast "GameUpdate"')
'''

                else: # Unknown Command
                    exe = 'print "Error, no such command."'
                self.client.send(exe) # Commands End
            else:
                self.client.close()
                running = 0

if __name__ == "__main__":
    lcs = []
    SPEED = 2
    s = Server()
    s.run()

The game will only run on Unix Systems ( I've tested with Ubuntu, the mirror will not work on Windows, well, at least this game doesn't work on Windows. )

I've also found a way to connect multiple Scratch Programs to separate Mirrors. So it's simple, open up the source code ( Shift+Click R > Open > Browser ) go to Scratch-Networking > ScratchServer ( then click the Class button ) > utilities > portNumber > Then edit the 42001 to 42003 or some other port then also edit CPORT on the Mirror to that same port. Though this is a very irritating process if you want to test it with four clients, so you'll need to really make sure you aren't going to mess things up.  tongue

Also, I like to comment out the sensorUpdateIn definition so it doesn't mess with the server. Though it will give a "error" message that it doesn't know the "command" it's still nice to comment it out. I suggest commenting out all the server data and processing, but keep the print command. How I've done it: Any other way, you'll get a nasty error.

Code:

def sensorUpdateIn(var,value):
    print "Scratch changed "+var+" to: "+value
    #scratchServer.send(data)
    #serverData = scratchServer.recv(1024)
    #exec serverData
    #print serverData

Well, cheers! I hope you all enjoy another random project of mine.  big_smile

Offline

 

#6 2011-01-22 03:51:52

comp500
Scratcher
Registered: 2010-01-08
Posts: 1000+

Re: Python Network Mirror for Scratch

I was thinking of using a hacked version of Mesh enabled scratch to make little 'servers'
Like:
Time servers
Internet servers
e.t.c.


800 posts! W00T! Oh sorry im not on a lot but at least i have 1000+ posts

Offline

 

#7 2011-01-22 10:36:28

markyparky56
Scratcher
Registered: 2008-03-20
Posts: 1000+

Re: Python Network Mirror for Scratch

Tell me, what are the advantages of a single player game hosted on a mesh compared to a single player game that isn't?


http://j.mp/jgVnTq
Check out my game engine development site: NewDawn I'm a Level 171 Scratcher.I am http://bit.ly/nkvLNT

Offline

 

#8 2011-02-27 04:00:20

muddyfish
New Scratcher
Registered: 2011-01-27
Posts: 13

Re: Python Network Mirror for Scratch

It works:)
Now making it using pythPr

Offline

 

#9 2011-03-03 15:08:19

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

Re: Python Network Mirror for Scratch

comp500: That would be interesting to see, if you get one up, could you show it?

markyparky56: What do you mean? Having a Single Player Game on a server, you can save Data there and you can access it from any computer, but Single Player Games off-line can only be played on that computer. But I don't understand very much of what you are talking about.  hmm  Could you explain a little?

Offline

 

#10 2011-03-13 07:54:36

bitzmaker
Scratcher
Registered: 2011-02-21
Posts: 19

Re: Python Network Mirror for Scratch

i have a question, why doesn't it work on windows?


i am not new people i just lost my old account's password called 'bitz'

Offline

 

#11 2011-03-14 21:37:46

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

Re: Python Network Mirror for Scratch

bitzmaker: The server doesn't work cause Python module 'select' on Windows doesn't work the same way as it does on a Linux computer. The client doesn't seem to work because it has different types of characters being translated, but I'm not really sure why it doesn't work.

Offline

 

#12 2011-03-26 07:44:02

bitzmaker
Scratcher
Registered: 2011-02-21
Posts: 19

Re: Python Network Mirror for Scratch

great explaination


i am not new people i just lost my old account's password called 'bitz'

Offline

 

#13 2011-04-15 10:25:03

gregory1132
New Scratcher
Registered: 2011-04-15
Posts: 1

Re: Python Network Mirror for Scratch

you could use a script that does this
host plays sound to connect
client picks this up
host plays sound to start game
note(the script would pick up messages by picking up the voloume sent at, so 2 Dubbing Cables would be needed)

from there all that needs doing is that host and client keeps sending there messages

note i will be releasing this script by 01/05/25 i will post the link to it here

Offline

 

#14 2011-04-15 10:57:31

markyparky56
Scratcher
Registered: 2008-03-20
Posts: 1000+

Re: Python Network Mirror for Scratch

gregory1132 wrote:

you could use a script that does this
host plays sound to connect
client picks this up
host plays sound to start game
note(the script would pick up messages by picking up the voloume sent at, so 2 Dubbing Cables would be needed)

from there all that needs doing is that host and client keeps sending there messages

note i will be releasing this script by 01/05/25 i will post the link to it here

sound and is a realy sound... why not just a message? e.g. to join - <Username>join to start game - Start

Simple enough.


http://j.mp/jgVnTq
Check out my game engine development site: NewDawn I'm a Level 171 Scratcher.I am http://bit.ly/nkvLNT

Offline

 

#15 2011-04-15 12:54:16

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

Re: Python Network Mirror for Scratch

gregory1132 wrote:

you could use a script that does this
host plays sound to connect
client picks this up
host plays sound to start game
note(the script would pick up messages by picking up the voloume sent at, so 2 Dubbing Cables would be needed)

from there all that needs doing is that host and client keeps sending there messages

note i will be releasing this script by 01/05/25 i will post the link to it here

I don't fully understand what you mean. What I need to do is set it up so it sends and receives at the same time.

Offline

 

#16 2011-04-22 19:56:56

GP1
Scratcher
Registered: 2009-07-06
Posts: 1000+

Re: Python Network Mirror for Scratch

Magnie wrote:

Server Requirements: Python 2.6+, Ubuntu ( Or any other Unix System, untested on Mac. ), will not work on Windows...

DARN!! Do you think you could make it work for windows?


I am currently http://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=imagehttp://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=text and I finally got over 1000 posts.

Offline

 

#17 2011-04-26 20:02:00

GP1
Scratcher
Registered: 2009-07-06
Posts: 1000+

Re: Python Network Mirror for Scratch

cool, but I'm confused


I am currently http://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=imagehttp://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=text and I finally got over 1000 posts.

Offline

 

#18 2011-04-26 23:12:42

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

Re: Python Network Mirror for Scratch

This should work for Windows, though I haven't tested it:

Code:

#!/usr/bin/env python

"""
An echo server that uses threads to handle multiple clients at a time.
Entering any line of input at the terminal will exit the server.
"""

import socket
import sys
import threading
from array import array
import time
import re


# Parse Data Definitions
def parseData(str):
    #Check for a broadcast
    e = re.search('broadcast\s\"(.*)\"',str)
    if e:
        #We have a broadcast!
        return 'parsed = 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!
        return 'parsed = 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!
        return 'parsed = sensorUpdateIn("'+e.group(1)+'","'+e.group(2)+'")'

def sensorUpdateIn(var,value):
    #print "Scratch changed "+var+" to: "+value
    return 'sensor-update '+value
    
    
def broadcastIn(broadcast):
    #print "Scratch broadcasted: "+broadcast
    return 'broadcast '+broadcast
# End

class Server:
    def __init__(self):
        self.host = ''
        self.port = 42002
        self.backlog = 5
        self.size = 1024
        self.server = None
        self.threads = []

    def open_socket(self):
        try:
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server.bind((self.host,self.port))
            self.server.listen(5)
        except socket.error, (value,message):
            if self.server:
                self.server.close()
            print "Could not open socket: " + message
            sys.exit(1)

    def run(self):
        self.open_socket()
        input = [self.server,sys.stdin]
        running = 1
        while running:

            c = Client(self.server.accept())
            c.start()
            self.threads.append(c)

        # close all threads

        self.server.close()
        for c in self.threads:
            c.join()

class Client(threading.Thread):
    def __init__(self,(client,address)):
        threading.Thread.__init__(self)
        self.client = client
        self.address = address
        self.size = 1024
        lcs.append([0,0])
        #print lcs
        self.ids = len(lcs)-1
        #print self.ids

    def run(self):
        #print self.address,'has connected.'
        running = 1
        while running:
            data = self.client.recv(self.size)
            if data:
                exec parseData(data)
                if parsed == 'broadcast start': # Start/Setup
                    exe = '''sendScratchCommand('sensor-update "x" "'''+str(lcs[self.ids][0])+'''"')
sendScratchCommand('sensor-update "y" "'''+str(lcs[self.ids][1])+'''"')
'''
                # Movement Start
                elif parsed == 'broadcast up': # Move Up
                    lcs[self.ids][1] += 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "y" "'''+str(lcs[self.ids][1])+'''"')'''
                elif parsed == 'broadcast down': # Move Down
                    lcs[self.ids][1] -= 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "y" "'''+str(lcs[self.ids][1])+'''"')'''
                elif parsed == 'broadcast left': # Move Left
                    lcs[self.ids][0] -= 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "x" "'''+str(lcs[self.ids][0])+'''"')'''
                elif parsed == 'broadcast right': # Move Right
                    lcs[self.ids][0] += 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "x" "'''+str(lcs[self.ids][0])+'''"')'''
                # Movement End

                else: # Unknown Command
                    exe = 'print "Error, no such command."'
                self.client.send(exe)
            else:
                self.client.close()
                running = 0

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

Offline

 

#20 2011-05-03 19:30:01

GP1
Scratcher
Registered: 2009-07-06
Posts: 1000+

Re: Python Network Mirror for Scratch

Magnie wrote:

This should work for Windows, though I haven't tested it:

Code:

#!/usr/bin/env python

"""
An echo server that uses threads to handle multiple clients at a time.
Entering any line of input at the terminal will exit the server.
"""

import socket
import sys
import threading
from array import array
import time
import re


# Parse Data Definitions
def parseData(str):
    #Check for a broadcast
    e = re.search('broadcast\s\"(.*)\"',str)
    if e:
        #We have a broadcast!
        return 'parsed = 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!
        return 'parsed = 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!
        return 'parsed = sensorUpdateIn("'+e.group(1)+'","'+e.group(2)+'")'

def sensorUpdateIn(var,value):
    #print "Scratch changed "+var+" to: "+value
    return 'sensor-update '+value
    
    
def broadcastIn(broadcast):
    #print "Scratch broadcasted: "+broadcast
    return 'broadcast '+broadcast
# End

class Server:
    def __init__(self):
        self.host = ''
        self.port = 42002
        self.backlog = 5
        self.size = 1024
        self.server = None
        self.threads = []

    def open_socket(self):
        try:
            self.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            self.server.bind((self.host,self.port))
            self.server.listen(5)
        except socket.error, (value,message):
            if self.server:
                self.server.close()
            print "Could not open socket: " + message
            sys.exit(1)

    def run(self):
        self.open_socket()
        input = [self.server,sys.stdin]
        running = 1
        while running:

            c = Client(self.server.accept())
            c.start()
            self.threads.append(c)

        # close all threads

        self.server.close()
        for c in self.threads:
            c.join()

class Client(threading.Thread):
    def __init__(self,(client,address)):
        threading.Thread.__init__(self)
        self.client = client
        self.address = address
        self.size = 1024
        lcs.append([0,0])
        #print lcs
        self.ids = len(lcs)-1
        #print self.ids

    def run(self):
        #print self.address,'has connected.'
        running = 1
        while running:
            data = self.client.recv(self.size)
            if data:
                exec parseData(data)
                if parsed == 'broadcast start': # Start/Setup
                    exe = '''sendScratchCommand('sensor-update "x" "'''+str(lcs[self.ids][0])+'''"')
sendScratchCommand('sensor-update "y" "'''+str(lcs[self.ids][1])+'''"')
'''
                # Movement Start
                elif parsed == 'broadcast up': # Move Up
                    lcs[self.ids][1] += 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "y" "'''+str(lcs[self.ids][1])+'''"')'''
                elif parsed == 'broadcast down': # Move Down
                    lcs[self.ids][1] -= 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "y" "'''+str(lcs[self.ids][1])+'''"')'''
                elif parsed == 'broadcast left': # Move Left
                    lcs[self.ids][0] -= 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "x" "'''+str(lcs[self.ids][0])+'''"')'''
                elif parsed == 'broadcast right': # Move Right
                    lcs[self.ids][0] += 1
                    #print lcs
                    exe = '''sendScratchCommand('sensor-update "x" "'''+str(lcs[self.ids][0])+'''"')'''
                # Movement End

                else: # Unknown Command
                    exe = 'print "Error, no such command."'
                self.client.send(exe)
            else:
                self.client.close()
                running = 0

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

thanks. I'm using it for Kitcat's WWM, you see. I was just trying see how, but I found a way!! thanks a whole lot with cherries on top!!!!!!!!!!!!!!!!!!! smile


I am currently http://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=imagehttp://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=text and I finally got over 1000 posts.

Offline

 

#21 2011-05-03 19:53:27

GP1
Scratcher
Registered: 2009-07-06
Posts: 1000+

Re: Python Network Mirror for Scratch

is there any special way to activate these scripts? just wondering.


I am currently http://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=imagehttp://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=text and I finally got over 1000 posts.

Offline

 

#22 2011-05-03 21:41:16

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

Re: Python Network Mirror for Scratch

What scripts do you mean?

Offline

 

#23 2011-05-03 22:41:26

GP1
Scratcher
Registered: 2009-07-06
Posts: 1000+

Re: Python Network Mirror for Scratch

I think you know what I-never mind. I mean in python, how do you run the above scripts/mirrors?


I am currently http://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=imagehttp://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=text and I finally got over 1000 posts.

Offline

 

#24 2011-05-04 16:04:58

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

Re: Python Network Mirror for Scratch

Depending on the OS there are different ways, on Linux you can try:

Code:

cd /path/to/mirror/server
python mirror.py

on Windows, you'll need to install Python then just double-click the mirror.py and it should run, if it gives any errors, you can try running it in IDLE ( Start > All Programs > Python > IDLE ) and find out what the errors are and then fix them.

Offline

 

#25 2011-05-04 17:56:18

GP1
Scratcher
Registered: 2009-07-06
Posts: 1000+

Re: Python Network Mirror for Scratch

yay!! that works! now, how do I connect Scratch and python together? (I'm full of questions for you)


I am currently http://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=imagehttp://blocks.scratchr.org/API.php?user=GP1&amp;action=onlineStatus&amp;type=text and I finally got over 1000 posts.

Offline

 

Board footer