SpaceFaceTemplate / SpaceFace.py
SFP's picture
Create SpaceFace.py
d8d884a verified
raw
history blame
5.01 kB
import coding
import scratchattach as scratch3
import threading
import time
import random
global conn
global projectid
global endpoint
global users
users = {}
with open("password.txt") as f:
session = scratch3.login("PolyPenguin", f.read())
class User:
def __init__(self, name, id):
self.name = name
self.id = id
class Responder:
def __init__(self, projectid, channel, can_respond, can_stream, value):
self.projectid = projectid
self.can_respond = can_respond
self.can_stream = can_stream
self.channel = channel
self.cooldown = time.time()
self.wrote = False
self.last_value = value
def poll(self):
value = scratch3.get_var(self.projectid, "channel "+str(self.channel))
if value != self.last_value and value != None:
self.last_value = value
binary = coding.decimal_to_binary(int(value))
if binary[1:3]=="01":
value = str(coding.binary_to_decimal(binary[3:]))
if binary[1:3]=="10":
value = str("true" if binary[3:] == 1 else "false")
if binary[1:3]=="11":
value = coding.convert_to_text(binary[3:])
return value
def close(self):
if self.can_stream or not self.can_respond:
conn.set_var("channel "+str(self.channel), "0")
else:
while str(scratch3.get_var(self.projectid, "channel "+str(self.channel))) !="0":
pass
def respond(self, response):
global conn
if self.wrote and not self.can_stream:
raise Exception("Can't stream to this as a response")
if not (self.can_respond or self.can_stream):
raise Exception("Can't respond to this")
while time.time() - self.cooldown < 0.5:
time.sleep(0.5 - (time.time() - self.cooldown))
if self.can_respond or self.can_stream:
payload = "1"
if type(response) is int:
payload+="01"+coding.decimal_to_binary(response)
elif type(response) is bool:
payload+="10"+"1" if response else "0"
elif type(response) is str:
payload+="11"+coding.convert_to_binary(response)
self.last_value = str(coding.binary_to_decimal(payload))
conn.set_var("channel "+str(self.channel), str(coding.binary_to_decimal(payload)))
t= time.time()
times=0.2
while scratch3.get_var(self.projectid, "channel "+str(self.channel)) !=str(coding.binary_to_decimal(payload)):
if time.time()-t>=times:
print("Message not sent, retrying")
times+=0.1
conn.set_var("channel "+str(self.channel), str(coding.binary_to_decimal(payload)))
t=time.time()
self.wrote = True
class ConnectionEndpoint:
def __init__(self):
pass
def receivedMessage(self, message, user, responder):
global users
r=random.randrange(1, 2047)
while r in users:
r=random.randrange(1, 2047)
users[r] = User(message, r)
responder.respond(r)
responder.close()
def thread(n):
global users
global conn
global projectid
global endpoint
conn.set_var("channel "+str(n), "0")
while True:
value = scratch3.get_var(projectid, "channel "+str(n))
if str(value) != "0" and value != None:
binary = coding.decimal_to_binary(int(value))
reqendpoint = coding.binary_to_decimal(binary[1:6])
header = coding.binary_to_decimal(binary[6:17])
staticpayload = binary[17] == '1'
streamingpayload = binary[18] == '1'
acceptstaticpayload = binary[19] == '1'
acceptstreamingpayload = binary[20] == '1'
payload = None
if staticpayload and not streamingpayload:
payloadformat = binary[21:23]
if payloadformat == "01":
payload = str(coding.binary_to_decimal(binary[23:]))
if payloadformat == "10":
payload = "true" if binary[23:]=='1' else "false"
if payloadformat == "11":
payload = coding.convert_to_text(binary[23:])
respond = Responder(projectid, n, acceptstaticpayload, acceptstreamingpayload, value)
if header in users:
user = users[header]
else:
user = None
endpoint[reqendpoint].receivedMessage(payload, user, respond)
def start_server(endpoints, project_id):
global projectid
global conn
global endpoint
endpoints.insert(0, ConnectionEndpoint())
endpoint = endpoints
projectid = project_id
conn = session.connect_cloud(project_id)
threads = [threading.Thread(target=thread, args=(i+1,)) for i in range(10)]
for t in threads:
t.start()
return t