# 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 = '127.0.0.1'
SPORT = 7070
# ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### #
# 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)
command.remove(' ')
#command.remove('')
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.
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
if server: pass
except: # If either are dead, end the program.
running = 0
print "Finished running."
Offline
bobbybee wrote:
What should I change to prevent this issue, then? Or how should I dump the commands list?
Just print commands before the "for command in commands".
Offline
It's always duplicating the message a thousand times.
Connecting to Scratch...
Connected to Scratch!
Listening for Scratch messages.
Connecting to Scratch Server...
Connected to Server!
Listening for Server messages.
sensor-update "g" 0 "i" 151 "inpacket" "bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: H
['g', ' 0 ', 'i', ' 151 ', 'inpacket', ' ', 'bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: H']
!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: H
!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: H
!bobb
: Hello!bobbybee: Hello!bobbybee: Hello!" "j" 25 "message" "What do you no about telnet?e" "name" "bobbybee" "packet" "Fxt/m/bobbybee/Hello!/"
sensor-update "packet" "Fxt/m/bobbybee/I am testing chat./"
['packet', ' ', 'Fxt/m/bobbybee/I am testing chat./', ' ']
sensor-update "inpacket" "esting
['inpacket', ' ', 'esting']
t.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing
t.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing
t.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bo
ee: I am testing chat.bobb"
sensor-update "inpacket" "ybee:
['inpacket', ' ', 'ybee: ']
testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am te
g chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am test
chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am tes
chat.bobbybee: I am testi"
sensor-update "inpacket" "ng cha
['inpacket', ' ', 'ng cha']
bbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee:
Exception in thread Thread-1:
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 522, in __bootstrap_inner
self.run()
File "mirror.py", line 103, in run
data = self.parse_message(data)
File "mirror.py", line 66, in parse_message
broadcasts.append(command[0])
IndexError: list index out of range
Offline
bobbybee wrote:
It's always duplicating the message a thousand times.
Code:
Connecting to Scratch... Connected to Scratch! Listening for Scratch messages. Connecting to Scratch Server... Connected to Server! Listening for Server messages. sensor-update "g" 0 "i" 151 "inpacket" "bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: H ['g', ' 0 ', 'i', ' 151 ', 'inpacket', ' ', 'bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: H'] !bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: H !bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: Hello!bobbybee: H !bobb : Hello!bobbybee: Hello!bobbybee: Hello!" "j" 25 "message" "What do you no about telnet?e" "name" "bobbybee" "packet" "Fxt/m/bobbybee/Hello!/" sensor-update "packet" "Fxt/m/bobbybee/I am testing chat./" ['packet', ' ', 'Fxt/m/bobbybee/I am testing chat./', ' '] sensor-update "inpacket" "esting ['inpacket', ' ', 'esting'] t.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing t.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing t.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bo ee: I am testing chat.bobb" sensor-update "inpacket" "ybee: ['inpacket', ' ', 'ybee: '] testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am te g chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am test chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am tes chat.bobbybee: I am testi" sensor-update "inpacket" "ng cha ['inpacket', ' ', 'ng cha'] bbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: I am testing chat.bobbybee: Exception in thread Thread-1: Traceback (most recent call last): File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 522, in __bootstrap_inner self.run() File "mirror.py", line 103, in run data = self.parse_message(data) File "mirror.py", line 66, in parse_message broadcasts.append(command[0]) IndexError: list index out of range
I'm not entirely sure. Usually the server should be parsing and dealing with messages sent to it. The mirror shouldn't do anything, cause people can just modify it and possibly crash the server by sending invalid messages.
There isn't much I can do cause I don't fully understand what you are trying to do. If you are filtering before messages go into the parser, then that would mess it up. Messages should just be filtered after.
Last edited by Magnie (2012-02-21 14:36:34)
Offline
Doh! Just did a telnet, and it's a bug in the server, not client. I'm stupid...
Offline
Can I help test? I know HTML, and Scratch, as well as a good amount of Batch, and a tad bit of other languages here and there like PHP, and Java.
Last edited by elfin8er (2012-02-22 00:29:48)

Offline
Sure! I just need to isolate a few last-minute bugs.
Offline
I just recently posted a project using FireMMO called FireChat. It is the first practical example of FireMMO that serves as a simple chat room. Unlike mesh chatrooms, it operates at lightning speed (more like 2.66 GHz speed).
Offline
I didn't change anything major, but try connecting now.
Offline
bobbybee wrote:
I didn't change anything major, but try connecting now.
Sweet, it works! No duplicates! Now all you need to do is run the server 24/7. xD
Also what VPN thing did you use to allow me to connect?
Offline
It's some program called Port Map. It gives me the creeps, though. (no password and an open port!)
Offline
Here is the code for messaging:
void extendMessage(int client, char* packet){
int i = 0;
char response[1024];
sprintf(response, "%s: %s", splitRetVal[2], splitRetVal[3]);
while(i < (MAX_USERS_SERVER-1)){
write(msgsock[i], response, strlen(response));
++i;
}
}Offline
I implemented closing the socket. Hopefully this will work better. (the server is back on)
Last edited by bobbybee (2012-02-23 16:35:03)
Offline
Thanks! Do you want to go on FireChat. Just don't spam it, I haven't implemented security yet.
Offline
You can never be too safe!
Offline
slinger wrote:
You have a point :3
edit: where can I download a standalone binary without compiling hte source?
For the server or mirror?
Offline
slinger wrote:
The mirror.
There isn't one, but I'm making one right now.
Offline
slinger wrote:
![]()
I'm a noob at networking so I think that's the thing that lets me to connect to firechat, is it not?
It is.
Offline
slinger wrote:
Ok great
![]()
Also thanks for creating the standalone!
Offline