Skip to content

Instantly share code, notes, and snippets.

@Pixailz
Created October 8, 2024 01:02
Show Gist options
  • Select an option

  • Save Pixailz/5744124b6a980af73a4e00f1f38a0093 to your computer and use it in GitHub Desktop.

Select an option

Save Pixailz/5744124b6a980af73a4e00f1f38a0093 to your computer and use it in GitHub Desktop.
import sys
import json
import gzip
# in requirements.txt
import pyperclip
from base64 import b64decode, b64encode
from pprint import pprint
DEBUG = 0
BP_SIG = "SHAPEZ2-1-"
ENT_ID = {
"signal": "ConstantSignalDefaultInternalVariant"
}
ENT_TYPE = {}
ENT_TYPE["signal_producer"] = [
"invalid",
"null",
"conflict",
"integer",
"false",
"true",
"shape",
"fluid"
]
ENT_ITEM_SIG = b"\x01\x01"
SHAPE_BASE = {
"base": [ "P-", "Cu" ],
"order": [ 0, 3, 2, 1 ]
}
ENCODING = "utf-8"
# FUNCTIONS
def int2str(n, endian = 'l', signed = 's'):
e = 'little'
s = True
if endian != 'l':
e = 'big'
if signed != 's':
s = False
r = ""
for l in n.to_bytes(4, e, signed=s):
r += chr(l)
return r
def get_nb_signal_producer(data):
nb = 0
for i in data["BP"]["Entries"]:
if "C" in i and i["T"] == ENT_ID["signal"]:
# print(b64decode(i["C"]))
nb += 1
return nb
def get_fmt_sig_shape(signal):
content = []
if type(signal) == str:
content = "\x06\x01\x01" + chr(len(signal)) + "\x00" + signal
elif type(signal) == int:
if signal == 0:
content = "\x04"
elif signal == 1:
content = "\x05"
else:
# content = f"\x03{int2str(signal)}"
content = 0x03.to_bytes(1, "little", signed=True)
content += signal.to_bytes(4, "little", signed=True)
print(content)
return b64encode(content).decode(ENCODING)
elif signal == None:
content = "\x01"
else:
print("unknwn signal type")
return
return b64encode(content.encode(ENCODING)).decode(ENCODING)
def get_pos(ent):
x = ent.get("X", 0)
y = ent.get("Y", 0)
z = ent.get("L", 0)
# return (x, y, z)
return (z, x, y)
def bin2shape(b, base):
return base[1] if b == "1" else base[0]
def int2shape_ordered(nshape, base):
_1 = bin2shape(nshape[base["order"][0]], base["base"])
_2 = bin2shape(nshape[base["order"][1]], base["base"])
_3 = bin2shape(nshape[base["order"][2]], base["base"])
_4 = bin2shape(nshape[base["order"][3]], base["base"])
return f"{_1}{_2}{_3}{_4}"
def char2shape(c, base):
nshape = []
for i in c:
nshape.append(i)
nshape.reverse()
return int2shape_ordered(nshape, base)
def int2shape(n, base=SHAPE_BASE, bpad = 0):
shape_str = ""
bin_str = f"{n:b}"
bin_str_pad = len(bin_str) % 4
if bin_str_pad:
bin_str = "0" * (4 - (bin_str_pad)) + bin_str
bin_str_blen = len(bin_str) / 4
while bin_str_blen < bpad:
bin_str = f"{'0' * 4}{bin_str}"
print(bin_str)
bpad -= 1
shape_part = []
for i in range(len(bin_str), 0, -4):
shape_part.append(char2shape(bin_str[i - 4:i], base))
return ':'.join(shape_part)
# CLASS
class S2Blueprint():
def __init__(self, data = None):
self.data = data
# Get blueprint from clipboard
def data_get(self):
if DEBUG == 1:
self.data = DEBUG_BP
else:
input("Copy Shapez2 blueprint into the clipboard and then press enter")
self.data = pyperclip.paste()
if DEBUG == 1:
print(f"Raw blueprint:\n> {self.data}")
self.data_process()
def data_process(self):
self.data_check()
self.data_decode()
self.index_update()
# check if data is a correct shdapez2 blueprint
def data_check(self):
if not self.data.startswith(BP_SIG):
print("Error: not a Shapez2 blueprint")
return True
return False
def data_decode(self):
self.data = gzip.decompress(b64decode(self.data.removeprefix(BP_SIG)))
self.data = json.loads(self.data)
if DEBUG == 1:
print(f"JSON blueprint:\n> ", end="")
pprint(self.data)
def index_update(self):
self.index = []
for ent in self.data["BP"]["Entries"]:
if ent["T"] != ENT_ID["signal"]:
continue
pos = get_pos(ent)
if pos == (None, None):
continue
self.index.append(pos)
self.index.sort()
def data_encode(self):
print("\nencoding\n")
self.data = json.dumps(self.data, separators=(",", ":")).encode(ENCODING)
self.data = BP_SIG + b64encode(gzip.compress(self.data)).decode(ENCODING) + "$"
if DEBUG == 1:
print(self.data)
def data_modify(self, data):
print(len(data))
print(len(self.index))
nb_signal_producer = get_nb_signal_producer(self.data)
nb_data = len(data)
if nb_data > nb_signal_producer:
print(
"Error: wrong data supplied, "
f"need {nb_signal_producer}, given {len(data)}"
)
return
i = 0
for _pos in self.index:
ent = None
pos = None
for _ent in self.data["BP"]["Entries"]:
pos = get_pos(_ent)
if pos == _pos:
ent = _ent
break
if ent is None:
print(f"{_pos} not found")
continue
if i >= nb_data:
ent["C"] = get_fmt_sig_shape(None)
else:
if DEBUG == 1:
print(f"Encoding {data[i]} at {pos}")
ent["C"] = get_fmt_sig_shape(data[i])
i += 1
self.data_encode()
def data_copy(self):
pyperclip.copy(self.data)
# MAIN
def main_DM74184():
DEBUG_DATA = [
0x00, 0b00_0000,
0x01, 0b00_0001,
0x02, 0b00_0010,
0x03, 0b00_0011,
0x04, 0b00_0100,
0x05, 0b00_1000,
0x06, 0b00_1001,
0x07, 0b00_1010,
0x08, 0b00_1011,
0x09, 0b00_1100,
0x0a, 0b01_0000,
0x0b, 0b01_0001,
0x0c, 0b01_0010,
0x0d, 0b01_0011,
0x0e, 0b01_0100,
0x0f, 0b01_1000,
0x10, 0b01_1001,
0x11, 0b01_1010,
0x12, 0b01_1011,
0x13, 0b01_1100,
0x14, 0b10_0000,
0x15, 0b10_0001,
0x16, 0b10_0010,
0x17, 0b10_0011,
0x18, 0b10_0100,
0x19, 0b10_1000,
0x1a, 0b10_1001,
0x1b, 0b10_1010,
0x1c, 0b10_1011,
0x1d, 0b10_1100,
0x1e, 0b11_0000,
0x1f, 0b11_0001,
]
DEBUG_DATA = [ int2shape(d, SHAPE_BASE, 2) for d in DEBUG_DATA ]
DEBUG_BP = "SHAPEZ2-1-H4sIAMfcA2cA/6xbXYvaUBD9L5c+ptA7+Vga2IfqtsVioR9b26XsQ9BoL7WJ3ETKIv73xsZ1NSZr7sxBUCSZSe6ZmXPnZHSjJirWr16Hnhp8UvFGvSgfVqmK1WBtljOTLZSnRtM82x26ScpExT+Vqb7Hj8cL5WXr5bJ+U8WvZJXGw3X9UvdbT73NSmvSojLcqB8qfqk9dVd9+J76ouLq/ba62Hdj05t0nqyX5cCa2SIdZWVqs2Q5SaxJslJtvdrYr42pNhvmWVFWh7+aRXXu3kHT1FPD6tQ3n6+vm158mRc6XoiufY3zhZm+T8p0mP9ZJTbt74YaDkbzLgz2AIYSAAMIgCEEwBADYOAKYHAG3dDmRXHBqlr6+P/dirJ3fFiwPIflvuh8aYh8Hp+76ZPVUngDILwhEN4QCW/Ag/fEzDHziWvFviI7DQCRx8QcEO3+AeYhLCk3WJ1pYJ1pVJ25FpgkzytbEkSBgFEgYBQIEgVyjAKPqaIO23E6b677o7E2t+msffc6WfSRo3e5/ZvYWS+KlvnwAT4I4CM6KsVewLY4aL38h3U2LU2edZnTsfn5lenbapBMf19egaTJjhA1KWyx9eOdtK6iH4qY/jxybFUk+hCibiDqECMOXaUNS9lIem7I9gPZ/THttasYl6uWCNdMQTSLPr0rGX3AZE/EUj1yyQ6UlEDBjtTrPD0pkJNaHBTgYxSg/NDAoPCeoYQyNXEoM8KREeHIiABkREAyIhYZkZiMCEdGhCMjApIRsciI+GREYjIiHBkRjowISEauQWGFQ/DMkPhJcNUhFvVFsXgyCZIF7unpuczVkxPHfNaQqZZuWUZ3zjQfp5wMhiB4Bgg8A2c8z8Zb/TcsDRmO6Zbl94zD0YS0Zx21jJFQxYBw2HTFLgx5f6c7F8YpEizaAQ7tgIl2x7SMUzywWAXsWJ2Nad3KCRRamQ92ucjBF9SGRtYGwpOQezQon8cYYAkGLAGAJRbN6GenHP1oBtJlt0DqwC8OzHLHGVbuhynMzhjXyEWAbSniVyCkG4skpYfTGIiWOOBDCREYzL42ZOzDuA4Loe0E0g7SDjF5itMAoRvcCNbfRlIxAexPI/mujtZtOCERSIEGijaRDgjZMkCDg4PT1GJJrXHBIUlwNDs4IbIdbkw6EBRFUooiHEWRnKIITFEEoyiSUhThKIokFEVsiiIwRRGMokhKUYSjKJJQFDnpNt/1bGdl6DPu6upZ3d31y8CDoasJZ2R8mAo5/Hjw3lMDkyX2YZLawuz+NrX7b9V2+08AAQYAJAN9hGc1AAA=$"
bp = S2Blueprint()
bp.data = DEBUG_BP
bp.data_process()
pprint(DEBUG_DATA)
bp.data_modify(DEBUG_DATA)
bp.data_copy()
def main_fatcatx_hexDispRom():
# hexRom FatCatX
SHAPE_BASE_OUT = {
"base": [ "P-", "Cg" ],
"order": [ 0, 1, 2, 3 ]
}
"""
. | . | . | x | . | . | . |
. .|. .|x .|. .|. .|. x|. .|
x | . | . | . | . | . | . |
. .|x .|. .|. .|. x|. .|. .|
.0| .1| .2| .3| .4| .5| x6|
0: 0b0100_1000
1: 0b0000_0001
2: 0b0000_0010
3: 0b0000_0100
4: 0b0001_0000
5: 0b0010_0000
6: 0b1000_0000
"""
DEBUG_DATA = [
int2shape(0b1011_0111, SHAPE_BASE_OUT, 2), int2shape(0x0),
int2shape(0b0011_0000, SHAPE_BASE_OUT, 2), int2shape(0x1),
int2shape(0b1110_1101, SHAPE_BASE_OUT, 2), int2shape(0x2),
int2shape(0b1111_1100, SHAPE_BASE_OUT, 2), int2shape(0x3),
int2shape(0b0111_1010, SHAPE_BASE_OUT, 2), int2shape(0x4),
int2shape(0b1101_1110, SHAPE_BASE_OUT, 2), int2shape(0x5),
int2shape(0b1101_1111, SHAPE_BASE_OUT, 2), int2shape(0x6),
int2shape(0b0011_0100, SHAPE_BASE_OUT, 2), int2shape(0x7),
int2shape(0b1111_1111, SHAPE_BASE_OUT, 2), int2shape(0x8),
int2shape(0b1111_1110, SHAPE_BASE_OUT, 2), int2shape(0x9),
int2shape(0b0111_1111, SHAPE_BASE_OUT, 2), int2shape(0xa),
int2shape(0b1101_1011, SHAPE_BASE_OUT, 2), int2shape(0xb),
int2shape(0b1000_0111, SHAPE_BASE_OUT, 2), int2shape(0xc),
int2shape(0b1111_1001, SHAPE_BASE_OUT, 2), int2shape(0xd),
int2shape(0b1000_1111, SHAPE_BASE_OUT, 2), int2shape(0xe),
int2shape(0b0000_1111, SHAPE_BASE_OUT, 2), int2shape(0xf),
]
DEBUG_BP = "SHAPEZ2-1-H4sIAG8SBGcA/7SZX2+bMBDAv4u1RyzVkEgbUh9C2k2JqDSaJls09QERyrwyQIYoiqJ895GSJgYMxWevlapG+O7sn+8vOaAVssnNl7GBnO/IPqBPxT4LkY2cLY03NImQgWZBmpwe3fmFj+xfiJaf7ffnOTKSbRxXf1D+289Ce7qtftHz0UD3ScFomJeCB/QT2dgy0BrZIwM9lVamaZIXflIsaJT48V344m/jYpYUISs/rnxGy2flDqanDU1ub9HRqJSYb0qsSombRjT45hfh7KUh+kAZS1m4aciVxh/b0tP0b+azUGx94nHWCW/9B2XheeMOo5uopeBdyuKlZA4e3Tv3nrMI4vl+mcw99ymr/p+SRRBx26oMmPIGvBZZAiRraiFLQGQJlKznriZFSZMn67lenayk6sluNil/mlwxCKwGpBjGFBMFdy2hJvNF8CcrAb+5rshdsQlg+yBkC00Hyoitmn2oA1as3sO8xoroSFuXrPV4SRLdqOpCpg7LRNqyuk1MIMfFWs6LJVHXnBESFV4tKuB6lk09axVta4G2EVhbINBGgNoahfUcfedI5KLPFLgSKMgHmbF0mDm1BtdcUi9mtcDi6sGUpXneVQ4EeWCI6LXT41Z/TdnOZ5uO9aZEoRq8kCs0g9fX7nvgYSEyVgfU+TYJCpomvenC0uOU4taHK2pyfjKSE7qMBC6ki5vsIlE7YPHqICOCq1yDroOCC21qLSAUcW7r7MJMMPtXEXuixN7UyJ4osCdq7BsJX8weSD3tGi6g2LUBxyrEMdHv7q1Jbs2fWJp83jV6KDi8pguwBHuBMrw0EO0+hehLkI38CBpMdO2CAHfhahxVoBiwRg4YdB0CR4a097tme6+k7UY8yCjpHInHGSWdn8VDjat1tLm+ZBCONlqMvb1G66x3Zqd/qRkTngwLQlN62IEoaHayMoOPZOGUXN4qfDKjkAsbbuCSVi/+ocPR/4mh1kDdc+l9Z8Sj3kO64UvxQQdxztntgYssM8cPXnv8TSD0AVVMjI6ZsL+5q71VI5BYrBUWIrXvZsqB2bd6/bgnsDkdtfe3dzTPYn/f4YHnjY9lr/Vqbdy74QGeddUzFPazgRya+Gy/CllOT98Znr5YPB7/CSDAAG8ROihkHAAA$"
bp = S2Blueprint()
bp.data = DEBUG_BP
bp.data_process()
pprint(DEBUG_DATA)
bp.data_modify(DEBUG_DATA)
bp.data_copy()
main_fatcatx_hexDispRom()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment