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!
If you want to check out the working demo, and check for updates, click here
Offline
Hmm, what needs to be modified?
Offline
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.
Offline
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 ).
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 = 0That 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
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
Offline
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)
Offline
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
pen13 wrote:
Meep join?
ok, would you like to be the squeak smalltalk coder?
Offline
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.
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
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:
[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.
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