Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # Scratch Mirror
- # Version 1.5.0
- # Originally by: Magnie. Modified by bobbybee for use in FireMMO
- import socket # Network base
- import time # For delaying purposes mostly.
- import threading # So it can send and receive at the same time anytime.
- import array
- # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
- # CHOST is the IP Scratch is running on, if you are running it #
- # on this computer, then the IP is 127.0.0.1 #
- # Theoretically you could run this Mirror on another computer. #
- # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
- # CPOST is the port Scratch is listening on, the default is #
- # 42001. Usually this is only change by a Scratcher who knows a #
- # about Squeak and networking with sockets. #
- # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
- CHOST = '127.0.0.1'
- CPORT = 42001
- # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
- # SHOST is the IP the server is running on. #
- # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
- # SPORT is the port that the server is using. 42002 is the #
- # unofficial port for Scratch Servers. The host will need to make #
- # sure to port-forward the port so people can connect from the #
- # internet. #
- # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
- SHOST = '96.127.188.39'
- SPORT = 8089
- # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
- # Some extra settings that are more for advanced users are below. #
- # ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
- # Time between checking the threads for broken ones.
- THREADCHECK = 5
- class Client(threading.Thread): # This class listens for messages sent from Scratch and sends it to the Server.
- def parse_message(self, message):
- if message:
- sensors = {}
- broadcasts = []
- commands = []
- i = 0
- while True:
- length = ord(message[i]) + ord(message[i+1]) + ord(message[i+2]) + ord(message[i+3])
- command = message[i + 4:i + length + 4]
- commands.append(command)
- if (i + length + 4) < len(message):
- i = (i+4) + length
- else:
- del command
- break
- for command in commands:
- if command[0] == 'b':
- command = command.split('"')
- command.pop(0)
- broadcasts.append(command[0])
- elif command[0] == 's':
- command = command.split('"')
- command.pop(0)
- try:
- command.remove(' ')
- except ValueError:
- pass
- sensors[command[0]] = command[1]
- return dict([('sensor-update', sensors), ('broadcast', broadcasts)])
- else:
- return None
- def sendScratchCommand(self, cmd):
- n = len(cmd)
- a = array('c')
- a.append(chr((n >> 24) & 0xFF))
- a.append(chr((n >> 16) & 0xFF))
- a.append(chr((n >> 8) & 0xFF))
- a.append(chr(n & 0xFF))
- server.sock.send(a.tostring() + cmd)
- def __init__(self, CHOST, CPORT):
- threading.Thread.__init__(self) # Initialize it, basically just separate it from the main thread.
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Defines the type of connection ( UPD, TCP on IPv4 or IPv6 )
- print("Connecting to Scratch...")
- self.sock.connect((CHOST, CPORT)) # Connect to Scratch
- print("Connected to Scratch!")
- def run(self):
- global running
- print "Listening for Scratch messages."
- while running:
- data = self.sock.recv(1024) # Wait for something to be sent to the mirror
- data = self.parse_message(data)
- for sensor in data['sensor-update']:
- if sensor == "packet":
- self.send(data['sensor-update'][sensor])
- def send(self, message):
- server.sock.send(message) # Send the data to the server.
- class Server(threading.Thread): # This class listens for messages from the Server and sends it to Scratch.
- def sendScratchCommand(self, cmd):
- n = len(cmd)
- a = []
- a.append(chr((n >> 24) & 0xFF))
- a.append(chr((n >> 16) & 0xFF))
- a.append(chr((n >> 8) & 0xFF))
- a.append(chr(n & 0xFF))
- scratch.sock.send(''.join(a) + cmd)
- def __init__(self, SHOST, SPORT):
- threading.Thread.__init__(self) # Initialize it, basically just separate it from the main thread.
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Defines the type of connection ( UPD, TCP on IPv4 or IPv6 )
- print("Connecting to Scratch Server...")
- self.sock.connect((SHOST, SPORT)) # Connect to the Server.
- print("Connected to Server!")
- def run(self):
- global running
- print "Listening for Server messages."
- while running:
- data = self.sock.recv(1024) # Listens for messages sent from the Server.
- print(data);
- self.sendScratchCommand("sensor-update packet \""+data+"\"");
- self.sendScratchCommand("broadcast dataready")
- def send(self, message):
- scratch.sock.send(message) # Sends messages to Scratch.
- running = 1
- scratch = Client(CHOST, CPORT) # Start up the class for Scratch
- scratch.start() # This starts the 'run' function.
- server = Server(SHOST, SPORT) # Start up the class for Server
- server.start() # This starts the 'run' function on the class as well.
- while running:
- time.sleep(THREADCHECK) # The longer the wait time, the less CPU is used I think.
- try: # Check if the either thread died ( or exists anymore ).
- if scratch:
- pass
- except Exception, e:
- print e
- running = 0Xff
Advertisement
Add Comment
Please, Sign In to add comment