Discuss Scratch
- Discussion Forums
- » Advanced Topics
- » PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
- bigspeedfpv
- Scratcher
500+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
yes it's by ip
- MonkeyBean2
- Scratcher
100+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
I'm working on a minecraft renderer, and eventually fully featured client in scratch, and since I'm too lazy gzip in scratch would probably be too slow, and I don't want to try connecting over cloud variables yet, I've decided to write a “simple” (more like apocalyptic spaghetti mess) proxy in python to proxy websocket connections from a js script interacting with the scratch project to the raw tcp minecraft server (and the other way around too) (btw I would still need a very similar proxy if I had chosen to use cloud variables now), but unfortunately I get an error when I call sock.recvfrom(2097151) from inside a asyncio task.
Apart from proxying, the proxy does two things:
- Split up and combine chunks of the tcp stream to get individual minecraft packets
- Handle compression
Here's the error:
And here's my code:
proxy/main.py:
I don't think you need lib.py, as it doesn't have anything that directly interacts with the socket - it's just a library of helper functions.
Apart from proxying, the proxy does two things:
- Split up and combine chunks of the tcp stream to get individual minecraft packets
- Handle compression
Here's the error:
Task exception was never retrieved
future: <Task finished name='Task-8' coro=<serverToClient() done, defined at proxy/proxy.py:106> exception=OSError(9, 'Bad file descriptor')>
Traceback (most recent call last):
File "proxy/proxy.py", line 107, in serverToClient
tcp2web(sock, websocket, statestuff)
File "proxy/proxy.py", line 34, in tcp2web
data, thing = sock.recvfrom(2097151)
OSError: [Errno 9] Bad file descriptor
And here's my code:
proxy/main.py:
import socket import asyncio from websockets.server import serve from io import BytesIO import lib def handle_packet(stream, statestuff): if statestuff.state == 'login': if packet_id == 0x03: # set compression compression_threshhold = lib.decode_varint(stream) print(f'set compression, threshhold = {statestuff.compression_threshhold}') if packet_id == 0x02: # login success # print(stream.getvalue()) print('0x02 msg login success:', stream.getvalue()) UUID = stream.read(7) print(f'login success, UUID: {UUID.hex()}') statestuff.state = 'play' print('state switched to play, stopping intervention.') def tcp2web(sock, websocket, statestuff): currentPacketLength = None carreyover = bytearray() while True: data, thing = sock.recvfrom(2097151) # errors here :/ if len(data) == 0: break orig_stream = BytesIO(carreyover+data) stream_len = len(data) currentPacketTotalLength = None currentPacket = BytesIO() # repeat over packets while True: if currentPacketTotalLength == None: if orig_stream.tell() > orig_stream.getbuffer().nbytes - 3: # read more data from socket, as there might not be enough data to read the entire varint carreyover = orig_stream.read() break length = lib.decode_varint(orig_stream) # get packet length currentPacketTotalLength = length currentPacket = BytesIO() else: packet_accumulated_length = currentPacket.getbuffer().nbytes # current length of recieved packet n_bytes_left = currentPacketTotalLength-packet_accumulated_length currentPacket.write(orig_stream.read(n_bytes_left)) if n_bytes_left <= stream_len: # entire packet has been read # send packet over websocket (packet is stored in currentPacket) orig_stream = currentPacket if statestuff.compression_threshhold == None or statestuff.compression_threshhold < 0: # uncompressed length = packet_length packet_id = lib.decode_varint(orig_stream) stream = orig_stream else: stream, packet_id = lib.decompress_packet(orig_stream.read()) handle_packet(stream, statestuff) websocket.send(stream) if n_bytes_left < stream_len: # new packet follows - continue to next iteration to read next packet currentPacketTotalLength = None continue else: break async def web2tcp(sock, websocket, statestuff): async for message in websocket: if statestuff.compression_threshhold == None or statestuff.compression_threshhold < 0: # don't compress sock.sendall(lib.packet_noid(message)) else: # do compress sock.sendall(lib.compressed_packet_noid(message)) class Blah: compression_threshhold = None state = 'login' async def clientToServer(sock, websocket, statestuff): await web2tcp(sock, websocket, statestuff) async def serverToClient(sock, websocket, statestuff): tcp2web(sock, websocket, statestuff) async def echo(websocket): msg = await websocket.recv() print(msg) host, port = msg.split(':')[:2] if not port: port = 25565 port = int(port) print(host, port) statestuff = Blah() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((host, port)) # print(sock.recvfrom(2097151)) # doesn't error here # tcp2web(sock, websocket, statestuff) asyncio.create_task(serverToClient(sock, websocket, statestuff)) asyncio.create_task(clientToServer(sock, websocket, statestuff)) async def main(): async with serve(echo, "localhost", 5823): await asyncio.Future() # run forever asyncio.run(main())
I don't think you need lib.py, as it doesn't have anything that directly interacts with the socket - it's just a library of helper functions.
- applejuiceproduc
- Scratcher
1000+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
deleted
Last edited by applejuiceproduc (July 25, 2023 13:13:41)
A signature
- applejuiceproduc
- Scratcher
1000+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
In a file like this:
(only showing some of the file, it goes on for another 3,000 lines)
How would I make a python script that removes everything except the country name, the country code (AF, AX…) and the population (4 lines after the name)?
I tried this:
But it didn't work at all. The output was very wrong.
(I know range(0, 100) isn't enough, but it still didn't even do the first ones right.)
1
Afghanistan
AF
004
034
38928346
5313081
13.65%
$500
Southern Asia
Asia
2
Aland Islands
AX
248
154
29013
15957
55.00%
$0
Northern Europe
Europe
3
Albania
AL
008
039
2877797
2296867
79.81%
$4,122
Southern Europe
Europe
4
Algeria
DZ
012
015
43851044
24532023
55.94%
$3,627
Northern Africa
Africa
5
American Samoa
AS
016
061
55191
30355
55.00%
$11,922
Polynesia
Oceania
6
Andorra
AD
020
039
77265
77751
100.63%
$36,996
Southern Europe
Europe
How would I make a python script that removes everything except the country name, the country code (AF, AX…) and the population (4 lines after the name)?
I tried this:
file_read = open("pop2.txt", "r") data = file_read.read().split("\n") n = 11 x = 1 for x in range(0, 100): try: del data[(n - 1) + x :: n] del data[(n - 2) + x :: n] del data[(n - 3) + x :: n] del data[(n - 4) + x :: n] del data[(n - 5) + x :: n] del data[(n - 7) + x :: n] del data[(n - 8) + x :: n] del data[(n - 9) + x :: n] del data[(n - 11) + x :: n] x = x + 11 except: break file2 = open("data.txt", "w") for x in data: file2.write(x + "\n")
(I know range(0, 100) isn't enough, but it still didn't even do the first ones right.)
Last edited by applejuiceproduc (July 25, 2023 14:52:14)
A signature
- rishi272011
- Scratcher
99 posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
In a file like this:(only showing some of the file, it goes on for another 3,000 lines)1
Afghanistan
AF
004
034
38928346
5313081
13.65%
$500
Southern Asia
Asia
2
Aland Islands
AX
248
154
29013
15957
55.00%
$0
Northern Europe
Europe
3
Albania
AL
008
039
2877797
2296867
79.81%
$4,122
Southern Europe
Europe
4
Algeria
DZ
012
015
43851044
24532023
55.94%
$3,627
Northern Africa
Africa
5
American Samoa
AS
016
061
55191
30355
55.00%
$11,922
Polynesia
Oceania
6
Andorra
AD
020
039
77265
77751
100.63%
$36,996
Southern Europe
Europe
How would I make a python script that removes everything except the country name, the country code (AF, AX…) and the population (4 lines after the name)?
try this:data = [] previous_out = "_" with open("pop2.txt", "r") as f: for lcv in range(0, 10000): #Change this to whatever is required f.readline() #skip number name = f.readline().strip("\n") code = f.readline().strip("\n") for i in range(2): f.readline() population = f.readline().strip("\n") for i in range(5): f.readline() #store the data data.append(name) data.append(code) data.append(population) new_out = "*" * int((lcv / 500)) if not (new_out == previous_out): print(new_out) previous_out = new_out print("length: ", len(data)) with open("pop2.txt", "w") as f: for x in data: f.write(x + "\n")
Last edited by rishi272011 (July 25, 2023 15:49:14)
- Air_heads
- Scratcher
92 posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
I'm too lazy gzip in scratch would probably be too slow, and I don't want to try connecting over cloud variables yet, I've decided to write a “simple” (more like apocalyptic spaghetti mess) proxy in python to proxy websocket connections from a js script interacting with the scratch project to the raw tcp minecraft server (and the other way around too) (btw I would still need a very similar proxy if I had chosen to use cloud variables now), but unfortunately I get an error when I call sock.recvfrom(2097151) from inside a asyncio task.I'm working on a minecraft renderer, and eventually fully featured client in scratch, and since
Apart from proxying, the proxy does two things:
- Split up and combine chunks of the tcp stream to get individual minecraft packets
- Handle compression
Here's the error:Task exception was never retrieved
future: <Task finished name='Task-8' coro=<serverToClient() done, defined at proxy/proxy.py:106> exception=OSError(9, 'Bad file descriptor')>
Traceback (most recent call last):
File "proxy/proxy.py", line 107, in serverToClient
tcp2web(sock, websocket, statestuff)
File "proxy/proxy.py", line 34, in tcp2web
data, thing = sock.recvfrom(2097151)
OSError: [Errno 9] Bad file descriptor
And here's my code:
proxy/main.py:import socket import asyncio from websockets.server import serve from io import BytesIO import lib def handle_packet(stream, statestuff): if statestuff.state == 'login': if packet_id == 0x03: # set compression compression_threshhold = lib.decode_varint(stream) print(f'set compression, threshhold = {statestuff.compression_threshhold}') if packet_id == 0x02: # login success # print(stream.getvalue()) print('0x02 msg login success:', stream.getvalue()) UUID = stream.read(7) print(f'login success, UUID: {UUID.hex()}') statestuff.state = 'play' print('state switched to play, stopping intervention.') def tcp2web(sock, websocket, statestuff): currentPacketLength = None carreyover = bytearray() while True: data, thing = sock.recvfrom(2097151) # errors here :/ if len(data) == 0: break orig_stream = BytesIO(carreyover+data) stream_len = len(data) currentPacketTotalLength = None currentPacket = BytesIO() # repeat over packets while True: if currentPacketTotalLength == None: if orig_stream.tell() > orig_stream.getbuffer().nbytes - 3: # read more data from socket, as there might not be enough data to read the entire varint carreyover = orig_stream.read() break length = lib.decode_varint(orig_stream) # get packet length currentPacketTotalLength = length currentPacket = BytesIO() else: packet_accumulated_length = currentPacket.getbuffer().nbytes # current length of recieved packet n_bytes_left = currentPacketTotalLength-packet_accumulated_length currentPacket.write(orig_stream.read(n_bytes_left)) if n_bytes_left <= stream_len: # entire packet has been read # send packet over websocket (packet is stored in currentPacket) orig_stream = currentPacket if statestuff.compression_threshhold == None or statestuff.compression_threshhold < 0: # uncompressed length = packet_length packet_id = lib.decode_varint(orig_stream) stream = orig_stream else: stream, packet_id = lib.decompress_packet(orig_stream.read()) handle_packet(stream, statestuff) websocket.send(stream) if n_bytes_left < stream_len: # new packet follows - continue to next iteration to read next packet currentPacketTotalLength = None continue else: break async def web2tcp(sock, websocket, statestuff): async for message in websocket: if statestuff.compression_threshhold == None or statestuff.compression_threshhold < 0: # don't compress sock.sendall(lib.packet_noid(message)) else: # do compress sock.sendall(lib.compressed_packet_noid(message)) class Blah: compression_threshhold = None state = 'login' async def clientToServer(sock, websocket, statestuff): await web2tcp(sock, websocket, statestuff) async def serverToClient(sock, websocket, statestuff): tcp2web(sock, websocket, statestuff) async def echo(websocket): msg = await websocket.recv() print(msg) host, port = msg.split(':')[:2] if not port: port = 25565 port = int(port) print(host, port) statestuff = Blah() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((host, port)) # print(sock.recvfrom(2097151)) # doesn't error here # tcp2web(sock, websocket, statestuff) asyncio.create_task(serverToClient(sock, websocket, statestuff)) asyncio.create_task(clientToServer(sock, websocket, statestuff)) async def main(): async with serve(echo, "localhost", 5823): await asyncio.Future() # run forever asyncio.run(main())
I don't think you need lib.py, as it doesn't have anything that directly interacts with the socket - it's just a library of helper functions.
Maybe use a await keyword? I never really used asyncio before so idk…
- Air_heads
- Scratcher
92 posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
I'm too lazy gzip in scratch would probably be too slow, and I don't want to try connecting over cloud variables yet, I've decided to write a “simple” (more like apocalyptic spaghetti mess) proxy in python to proxy websocket connections from a js script interacting with the scratch project to the raw tcp minecraft server (and the other way around too) (btw I would still need a very similar proxy if I had chosen to use cloud variables now), but unfortunately I get an error when I call sock.recvfrom(2097151) from inside a asyncio task.I'm working on a minecraft renderer, and eventually fully featured client in scratch, and since
Apart from proxying, the proxy does two things:
- Split up and combine chunks of the tcp stream to get individual minecraft packets
- Handle compression
Here's the error:Task exception was never retrieved
future: <Task finished name='Task-8' coro=<serverToClient() done, defined at proxy/proxy.py:106> exception=OSError(9, 'Bad file descriptor')>
Traceback (most recent call last):
File "proxy/proxy.py", line 107, in serverToClient
tcp2web(sock, websocket, statestuff)
File "proxy/proxy.py", line 34, in tcp2web
data, thing = sock.recvfrom(2097151)
OSError: [Errno 9] Bad file descriptor
And here's my code:
proxy/main.py:import socket import asyncio from websockets.server import serve from io import BytesIO import lib def handle_packet(stream, statestuff): if statestuff.state == 'login': if packet_id == 0x03: # set compression compression_threshhold = lib.decode_varint(stream) print(f'set compression, threshhold = {statestuff.compression_threshhold}') if packet_id == 0x02: # login success # print(stream.getvalue()) print('0x02 msg login success:', stream.getvalue()) UUID = stream.read(7) print(f'login success, UUID: {UUID.hex()}') statestuff.state = 'play' print('state switched to play, stopping intervention.') def tcp2web(sock, websocket, statestuff): currentPacketLength = None carreyover = bytearray() while True: data, thing = sock.recvfrom(2097151) # errors here :/ if len(data) == 0: break orig_stream = BytesIO(carreyover+data) stream_len = len(data) currentPacketTotalLength = None currentPacket = BytesIO() # repeat over packets while True: if currentPacketTotalLength == None: if orig_stream.tell() > orig_stream.getbuffer().nbytes - 3: # read more data from socket, as there might not be enough data to read the entire varint carreyover = orig_stream.read() break length = lib.decode_varint(orig_stream) # get packet length currentPacketTotalLength = length currentPacket = BytesIO() else: packet_accumulated_length = currentPacket.getbuffer().nbytes # current length of recieved packet n_bytes_left = currentPacketTotalLength-packet_accumulated_length currentPacket.write(orig_stream.read(n_bytes_left)) if n_bytes_left <= stream_len: # entire packet has been read # send packet over websocket (packet is stored in currentPacket) orig_stream = currentPacket if statestuff.compression_threshhold == None or statestuff.compression_threshhold < 0: # uncompressed length = packet_length packet_id = lib.decode_varint(orig_stream) stream = orig_stream else: stream, packet_id = lib.decompress_packet(orig_stream.read()) handle_packet(stream, statestuff) websocket.send(stream) if n_bytes_left < stream_len: # new packet follows - continue to next iteration to read next packet currentPacketTotalLength = None continue else: break async def web2tcp(sock, websocket, statestuff): async for message in websocket: if statestuff.compression_threshhold == None or statestuff.compression_threshhold < 0: # don't compress sock.sendall(lib.packet_noid(message)) else: # do compress sock.sendall(lib.compressed_packet_noid(message)) class Blah: compression_threshhold = None state = 'login' async def clientToServer(sock, websocket, statestuff): await web2tcp(sock, websocket, statestuff) async def serverToClient(sock, websocket, statestuff): tcp2web(sock, websocket, statestuff) async def echo(websocket): msg = await websocket.recv() print(msg) host, port = msg.split(':')[:2] if not port: port = 25565 port = int(port) print(host, port) statestuff = Blah() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((host, port)) # print(sock.recvfrom(2097151)) # doesn't error here # tcp2web(sock, websocket, statestuff) asyncio.create_task(serverToClient(sock, websocket, statestuff)) asyncio.create_task(clientToServer(sock, websocket, statestuff)) async def main(): async with serve(echo, "localhost", 5823): await asyncio.Future() # run forever asyncio.run(main())
I don't think you need lib.py, as it doesn't have anything that directly interacts with the socket - it's just a library of helper functions.
“A socket can not be reused once the connection is closed, i.e. you can not call socket.connect() on a closed socket.” - Random stackoverflow post | You need to create a new socket every time the connection is closed.
- -RabbitWorld-
- Scratcher
1000+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
Is it possible to use python like php and store data? Make a login system?
♥ SDS Manager
♥ 6 Featured Studios
♥ FPC #517
♥ SWC Reviewer
- davidtheplatform
- Scratcher
500+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
Yes, you can open files with open( Is it possible to use python like php and store data? Make a login system?file name).
More info: https://www.w3schools.com/python/python_file_handling.asp
Generation 4: the first time you see this copy and paste it on top of your sig in the scratch forums and increase generation by 1. Social experiment.
- LoIdesMio
- Scratcher
100+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
Or just not close the connection p.s i dont know what im saying but it sounded right enoughI'm too lazy gzip in scratch would probably be too slow, and I don't want to try connecting over cloud variables yet, I've decided to write a “simple” (more like apocalyptic spaghetti mess) proxy in python to proxy websocket connections from a js script interacting with the scratch project to the raw tcp minecraft server (and the other way around too) (btw I would still need a very similar proxy if I had chosen to use cloud variables now), but unfortunately I get an error when I call sock.recvfrom(2097151) from inside a asyncio task.I'm working on a minecraft renderer, and eventually fully featured client in scratch, and since
Apart from proxying, the proxy does two things:
- Split up and combine chunks of the tcp stream to get individual minecraft packets
- Handle compression
Here's the error:Task exception was never retrieved
future: <Task finished name='Task-8' coro=<serverToClient() done, defined at proxy/proxy.py:106> exception=OSError(9, 'Bad file descriptor')>
Traceback (most recent call last):
File "proxy/proxy.py", line 107, in serverToClient
tcp2web(sock, websocket, statestuff)
File "proxy/proxy.py", line 34, in tcp2web
data, thing = sock.recvfrom(2097151)
OSError: [Errno 9] Bad file descriptor
And here's my code:
proxy/main.py:import socket import asyncio from websockets.server import serve from io import BytesIO import lib def handle_packet(stream, statestuff): if statestuff.state == 'login': if packet_id == 0x03: # set compression compression_threshhold = lib.decode_varint(stream) print(f'set compression, threshhold = {statestuff.compression_threshhold}') if packet_id == 0x02: # login success # print(stream.getvalue()) print('0x02 msg login success:', stream.getvalue()) UUID = stream.read(7) print(f'login success, UUID: {UUID.hex()}') statestuff.state = 'play' print('state switched to play, stopping intervention.') def tcp2web(sock, websocket, statestuff): currentPacketLength = None carreyover = bytearray() while True: data, thing = sock.recvfrom(2097151) # errors here :/ if len(data) == 0: break orig_stream = BytesIO(carreyover+data) stream_len = len(data) currentPacketTotalLength = None currentPacket = BytesIO() # repeat over packets while True: if currentPacketTotalLength == None: if orig_stream.tell() > orig_stream.getbuffer().nbytes - 3: # read more data from socket, as there might not be enough data to read the entire varint carreyover = orig_stream.read() break length = lib.decode_varint(orig_stream) # get packet length currentPacketTotalLength = length currentPacket = BytesIO() else: packet_accumulated_length = currentPacket.getbuffer().nbytes # current length of recieved packet n_bytes_left = currentPacketTotalLength-packet_accumulated_length currentPacket.write(orig_stream.read(n_bytes_left)) if n_bytes_left <= stream_len: # entire packet has been read # send packet over websocket (packet is stored in currentPacket) orig_stream = currentPacket if statestuff.compression_threshhold == None or statestuff.compression_threshhold < 0: # uncompressed length = packet_length packet_id = lib.decode_varint(orig_stream) stream = orig_stream else: stream, packet_id = lib.decompress_packet(orig_stream.read()) handle_packet(stream, statestuff) websocket.send(stream) if n_bytes_left < stream_len: # new packet follows - continue to next iteration to read next packet currentPacketTotalLength = None continue else: break async def web2tcp(sock, websocket, statestuff): async for message in websocket: if statestuff.compression_threshhold == None or statestuff.compression_threshhold < 0: # don't compress sock.sendall(lib.packet_noid(message)) else: # do compress sock.sendall(lib.compressed_packet_noid(message)) class Blah: compression_threshhold = None state = 'login' async def clientToServer(sock, websocket, statestuff): await web2tcp(sock, websocket, statestuff) async def serverToClient(sock, websocket, statestuff): tcp2web(sock, websocket, statestuff) async def echo(websocket): msg = await websocket.recv() print(msg) host, port = msg.split(':')[:2] if not port: port = 25565 port = int(port) print(host, port) statestuff = Blah() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((host, port)) # print(sock.recvfrom(2097151)) # doesn't error here # tcp2web(sock, websocket, statestuff) asyncio.create_task(serverToClient(sock, websocket, statestuff)) asyncio.create_task(clientToServer(sock, websocket, statestuff)) async def main(): async with serve(echo, "localhost", 5823): await asyncio.Future() # run forever asyncio.run(main())
I don't think you need lib.py, as it doesn't have anything that directly interacts with the socket - it's just a library of helper functions.
“A socket can not be reused once the connection is closed, i.e. you can not call socket.connect() on a closed socket.” - Random stackoverflow post | You need to create a new socket every time the connection is closed.
Last edited by LoIdesMio (Aug. 1, 2023 22:54:30)
I make cloud Games! Using Scratchattach by @TimMcCool!
- ajskateboarder
- Scratcher
1000+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
If you want to use a markup language that works similar to PHP, try Flask (a Python web framework) with Jinja (the markup language). Is it possible to use python like php and store data? Make a login system?
Here's a primer on it: https://realpython.com/primer-on-jinja-templating/
- Air_heads
- Scratcher
92 posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
Or just not close the connection p.s i dont know what im saying but it sounded right enoughI'm too lazy gzip in scratch would probably be too slow, and I don't want to try connecting over cloud variables yet, I've decided to write a “simple” (more like apocalyptic spaghetti mess) proxy in python to proxy websocket connections from a js script interacting with the scratch project to the raw tcp minecraft server (and the other way around too) (btw I would still need a very similar proxy if I had chosen to use cloud variables now), but unfortunately I get an error when I call sock.recvfrom(2097151) from inside a asyncio task.I'm working on a minecraft renderer, and eventually fully featured client in scratch, and since
Apart from proxying, the proxy does two things:
- Split up and combine chunks of the tcp stream to get individual minecraft packets
- Handle compression
Here's the error:Task exception was never retrieved
future: <Task finished name='Task-8' coro=<serverToClient() done, defined at proxy/proxy.py:106> exception=OSError(9, 'Bad file descriptor')>
Traceback (most recent call last):
File "proxy/proxy.py", line 107, in serverToClient
tcp2web(sock, websocket, statestuff)
File "proxy/proxy.py", line 34, in tcp2web
data, thing = sock.recvfrom(2097151)
OSError: [Errno 9] Bad file descriptor
And here's my code:
proxy/main.py:import socket import asyncio from websockets.server import serve from io import BytesIO import lib def handle_packet(stream, statestuff): if statestuff.state == 'login': if packet_id == 0x03: # set compression compression_threshhold = lib.decode_varint(stream) print(f'set compression, threshhold = {statestuff.compression_threshhold}') if packet_id == 0x02: # login success # print(stream.getvalue()) print('0x02 msg login success:', stream.getvalue()) UUID = stream.read(7) print(f'login success, UUID: {UUID.hex()}') statestuff.state = 'play' print('state switched to play, stopping intervention.') def tcp2web(sock, websocket, statestuff): currentPacketLength = None carreyover = bytearray() while True: data, thing = sock.recvfrom(2097151) # errors here :/ if len(data) == 0: break orig_stream = BytesIO(carreyover+data) stream_len = len(data) currentPacketTotalLength = None currentPacket = BytesIO() # repeat over packets while True: if currentPacketTotalLength == None: if orig_stream.tell() > orig_stream.getbuffer().nbytes - 3: # read more data from socket, as there might not be enough data to read the entire varint carreyover = orig_stream.read() break length = lib.decode_varint(orig_stream) # get packet length currentPacketTotalLength = length currentPacket = BytesIO() else: packet_accumulated_length = currentPacket.getbuffer().nbytes # current length of recieved packet n_bytes_left = currentPacketTotalLength-packet_accumulated_length currentPacket.write(orig_stream.read(n_bytes_left)) if n_bytes_left <= stream_len: # entire packet has been read # send packet over websocket (packet is stored in currentPacket) orig_stream = currentPacket if statestuff.compression_threshhold == None or statestuff.compression_threshhold < 0: # uncompressed length = packet_length packet_id = lib.decode_varint(orig_stream) stream = orig_stream else: stream, packet_id = lib.decompress_packet(orig_stream.read()) handle_packet(stream, statestuff) websocket.send(stream) if n_bytes_left < stream_len: # new packet follows - continue to next iteration to read next packet currentPacketTotalLength = None continue else: break async def web2tcp(sock, websocket, statestuff): async for message in websocket: if statestuff.compression_threshhold == None or statestuff.compression_threshhold < 0: # don't compress sock.sendall(lib.packet_noid(message)) else: # do compress sock.sendall(lib.compressed_packet_noid(message)) class Blah: compression_threshhold = None state = 'login' async def clientToServer(sock, websocket, statestuff): await web2tcp(sock, websocket, statestuff) async def serverToClient(sock, websocket, statestuff): tcp2web(sock, websocket, statestuff) async def echo(websocket): msg = await websocket.recv() print(msg) host, port = msg.split(':')[:2] if not port: port = 25565 port = int(port) print(host, port) statestuff = Blah() with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sock: sock.connect((host, port)) # print(sock.recvfrom(2097151)) # doesn't error here # tcp2web(sock, websocket, statestuff) asyncio.create_task(serverToClient(sock, websocket, statestuff)) asyncio.create_task(clientToServer(sock, websocket, statestuff)) async def main(): async with serve(echo, "localhost", 5823): await asyncio.Future() # run forever asyncio.run(main())
I don't think you need lib.py, as it doesn't have anything that directly interacts with the socket - it's just a library of helper functions.
“A socket can not be reused once the connection is closed, i.e. you can not call socket.connect() on a closed socket.” - Random stackoverflow post | You need to create a new socket every time the connection is closed.
1. You probably need to close it when a user leaves the project, so that the server doesn’t error out.
2. You probably would need to close it for testing purposes.
- wvzack
- Scratcher
500+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
I just got a raspberry pi and tried downloading scratch attach with pip install -U scratchattach it worked but when i try importing it it says module not found. Thank!
- mybearworld
- Scratcher
1000+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
The -U means upgrade. You should run it without the -U if you're installing it for the first time. I just got a raspberry pi and tried downloading scratch attach with pip install -U scratchattach it worked but when i try importing it it says module not found. Thank!
Signatures are the only place where assets links still work.
- wvzack
- Scratcher
500+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
ok i will try. still doesn't work.The -U means upgrade. You should run it without the -U if you're installing it for the first time. I just got a raspberry pi and tried downloading scratch attach with pip install -U scratchattach it worked but when i try importing it it says module not found. Thank!
Last edited by wvzack (Aug. 24, 2023 12:13:49)
- mybearworld
- Scratcher
1000+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
(#915)Can you copy and paste your prompt and the output?ok i will try. still doesn't work.The -U means upgrade. You should run it without the -U if you're installing it for the first time. I just got a raspberry pi and tried downloading scratch attach with pip install -U scratchattach it worked but when i try importing it it says module not found. Thank!
Signatures are the only place where assets links still work.
- mybearworld
- Scratcher
1000+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
(#917)Hmm. Can you try using `pip3 install scratchattach` (instead of just `pip`)?No i am using a vnc i will take screenshot. Can you copy and paste your prompt and the output?
-snip-
Signatures are the only place where assets links still work.
- wvzack
- Scratcher
500+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
Ok.(#917)Hmm. Can you try using `pip3 install scratchattach` (instead of just `pip`)?No i am using a vnc i will take screenshot. Can you copy and paste your prompt and the output?
-snip-
- wvzack
- Scratcher
500+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
It worked thx so much!(#917)Hmm. Can you try using `pip3 install scratchattach` (instead of just `pip`)?No i am using a vnc i will take screenshot. Can you copy and paste your prompt and the output?
-snip-
- wvzack
- Scratcher
500+ posts
PyHelp - The official Scratch Python help forum | Ask, help, discuss, & more! | +800 posts! |
My code that should make a newline is not working
it returns
time = datetime.now() timestring = now.strftime("%d/%m/%Y %H:%M:%S") notes = project.notes project.set_notes(notes, + "/n", + timestring)
Traceback (most recent call last):
File "/home/pi/Python scripts/codestreamdowntime.py", line 12, in <module>
project.set_notes(notes, + "/n", + dt_string)
TypeError: bad operand type for unary +: 'str'