def paramTrace(inputs, blockids, origin, libs, fn_args, object_number): if inputs[0] == 1: if inputs[1] == None: return getblock(idgen.getID(), "text", [""]) return getblock(idgen.getID(), "text", [str(inputs[1][1])]) elif inputs[0] == 4: return getblock(idgen.getID(), "number", [inputs[1][1]]) elif inputs[0] == 3: if inputs[1][0] == 12: ret = getblock(idgen.getID(), "get_variable", [libs.get_var(inputs[1][2]), None]) return ret else: ret = chunkTrace(inputs[1], blockids, origin, libs, fn_args, object_number) return ret[0] elif inputs[0] == 2: ret = chunkTrace(inputs[1], blockids, origin, libs, fn_args, object_number) return ret elif inputs[0] == 12: ret = getblock(idgen.getID(), "get_variable", [libs.get_var(inputs[2]), None]) return ret else: #todo pass
def convert(origin: dict, libs, object_number): blockids = {} header = [] functions = [] for i in origin: blockids[i] = idgen.getID() block = origin[i] ret = libs.find(block["opcode"]) if ret != None: if ret["type"] == "header": header.append(i) continue if "parent" in block: if block["parent"] == None: print(f"HEADER MISS! {block['opcode']}") ret = [] for i in header: if origin[i]["opcode"] == "procedures_definition": functions.append([ procedures.convert(i, origin, libs, object_number), origin[origin[i]["inputs"]["custom_block"] [1]]["mutation"]["proccode"] ]) else: ret.append(chunkTrace(i, blockids, origin, libs, {}, object_number)) return ret, functions
def get_fn_definition(params, types): fn_definition = blocks.getblock(idgen.getID(), "function_create", []) block, arglists = subargs(params, types) fn_definition["params"] = [block, None] return fn_definition
def convert_broadcast(origin: dict): ret = {} for i in origin: name = origin[i] ret[i] = {"id": idgen.getID(), "name": name} print(f"Converted: Broadcast '{i}' to '{ret[i]['id']}'") return ret
def subargs(args, types): if len(args) == 0: return None, [] fnParam, argblock = None, None sub, fn_args = subargs(args[1:], types[1:]) if types[0] == "string": fnParam = blocks.getblock(idgen.getID(), f"stringParam_{idgen.getID()}", []) argblock = blocks.getblock(idgen.getID(), "function_field_string", [fnParam, sub]) elif types[0] == "boolean": fnParam = blocks.getblock(idgen.getID(), f"booleanParam_{idgen.getID()}", []) argblock = blocks.getblock(idgen.getID(), "function_field_boolean", [fnParam, sub]) elif types[0] == "label": fnParam = {"type": None} argblock = blocks.getblock(idgen.getID(), "function_field_label", [args[0], sub]) return argblock, [fnParam["type"]] + fn_args
def initEntfile(): ent: dict = {} ent["objects"] = [] ent["scenes"] = [{"id": idgen.getID(), "name": "stage"}] ent["variables"] = [{ "name": "초시계", "id": "time", "visible": False, "value": "0", "variableType": "timer", "isCloud": False, "isRealTime": False, "cloudDate": False, "object": None, "x": 134, "y": -70 }, { "name": "대답", "id": "answ", "visible": False, "value": "0", "variableType": "answer", "isCloud": False, "isRealTime": False, "cloudDate": False, "object": None, "x": 150, "y": -100 }] ent["messages"] = [] ent["functions"] = [] ent["tables"] = [] ent["interface"] = {"canvasWidth": 640, "menuWidth": 280, "object": "1111"} ent["expansionBlocks"] = [] ent["aiUtilizeBlocks"] = [] ent["externalModules"] = [] ent["speed"] = 60 ent["likeCnt"] = 0 ent["recentLikeCnt"] = 0 ent["childCnt"] = 0 ent["comment"] = 0 ent["visit"] = 0 ent["name"] = "Generated by ScratchEntry Generator" ent["user"] = "******" ent["isopen"] = False ent["isPracticalCourse"] = False return ent
def getNewVar(name, value, target): var = { "name": name, "value": value, "id": idgen.getID(), "cloudDate": False, "isCloud": False, "isRealTime": False, "object": target, "variableType": "variable", "visible": False, "x": 0, "y": 0 } return var
def convert(cur, origin, libs, object_number): source = cur cur = origin[cur]["inputs"]["custom_block"][1] args = json.loads(origin[cur]["mutation"]["argumentids"]) names = json.loads(origin[cur]["mutation"]["argumentnames"]) proccode = origin[cur]["mutation"]["proccode"] ret = blocks.getblock(libs.get_fn(proccode), "function_create", []) types = [] while True: st = proccode.find("%s") nu = proccode.find("%n") bo = proccode.find("%b") if st == -1 and bo == -1 and nu == -1: break if st == -1: st = 999999999999999 if bo == -1: bo = 999999999999999 if nu == -1: nu = 999999999999999 s = list(proccode) t = min(st, bo, nu) s[t] = ' ' if s[t + 1] == 'n' or s[t + 1] == 's': types.append("string") elif s[t + 1] == 'b': types.append("boolean") proccode = "".join(s) block, arglists = subargs([proccode] + args, ["label"] + types) ret["params"] = [block, None] fn_args = {} for x in range(len(args)): fn_args[names[x]] = arglists[x + 1] blockids = {} for i in origin: blockids[i] = idgen.getID() b = blocks.chunkTrace(origin[source]["next"], blockids, origin, libs, fn_args, object_number) if b == None: b = [] return [ret] + b
def getNewList(name, values, target): var = { "name": name, "value": 0, "id": idgen.getID(), "array": values, "cloudDate": False, "isCloud": False, "isRealTime": False, "object": target, "variableType": "list", "visible": False, "x": 0, "y": 0, "height": 120, "width": 100, } return var
broadcasts = variables.convert_broadcast(origin["targets"][0]["broadcasts"]) dataids = {**varids, **listids} for x in vars + lists: ent["variables"].append(x) for x in dataids: libs.create_var(x, dataids[x]) for x in broadcasts: ent["messages"].append(broadcasts[x]) libs.create_brd(x, broadcasts[x]) #함수 찾기 for x in origin["targets"]: for j in x["blocks"]: if x["blocks"][j]["opcode"] == "procedures_prototype": libs.create_fn(x["blocks"][j]["mutation"]["proccode"], idgen.getID()) #오브젝트 변환하기 ent["objects"], localvars, localdatas, localbroadcasts, spts_lib, costumes = sprites.convert( origin["targets"]) #지역 변수, 신호, 모양 받기 for x in localvars: ent["variables"].append(x) for x in localbroadcasts: ent["messages"].append(broadcasts[x]) libs.create_brd(x, localbroadcasts[x]) for x in localdatas: libs.create_var(x, localdatas[x]) for x in spts_lib: libs.create_spt(x, spts_lib[x])
def resetlist(list): fn_definition = [procedures.get_fn_definition([ idgen.getID() ], ["string"])] fnid = idgen.getID() fn_call = blocks.getblock(idgen.getID(), f"func_{fnid}", [blocks.getblock(idgen.getID(), "text", ["리스트 비우기"]), None]) fn_internal_self_call = blocks.getblock(idgen.getID(), f"func_{fnid}", [blocks.getblock(idgen.getID(), "text", ["리스트 비우기 재귀"]), None]) fn_internal_delete_item = blocks.getblock(idgen.getID(), f"remove_value_from_list", [1, list, None]) fn_internal_a = blocks.getblock(idgen.getID(), f"text", ['0', None]) fn_internal_b = blocks.getblock(idgen.getID(), f"length_of_list", [None, list, None]) fn_internal_condition = blocks.getblock(idgen.getID(), "boolean_basic_operator", [fn_internal_a, "LESS", fn_internal_b, None]) fn_internal_if = blocks.getblock(idgen.getID(), "_if", [fn_internal_condition, [], None], statement = [[fn_internal_delete_item, fn_internal_self_call], None]) fn_definition.append(fn_internal_if) return {"content": json.dumps([fn_definition]), "id": fnid}, fn_call
def chunkTrace(cur, blockids, origin, libs, fn_args, object_number): if cur == None: return ret = [] while True: if origin[cur]["opcode"] == "argument_reporter_string_number" or origin[ cur]["opcode"] == "argument_reporter_boolean": name = origin[cur]["fields"]["VALUE"][0] if not name in fn_args: ret.append(getblock(idgen.getID(), "number", [0])) else: ret.append(getblock(blockids[cur], fn_args[name], [None])) elif origin[cur]["opcode"] == "procedures_call": args = json.loads(origin[cur]["mutation"]["argumentids"]) fnid = libs.get_fn(origin[cur]["mutation"]["proccode"]) params = [] for argid in args: params.append( paramTrace(origin[cur]["inputs"][argid], blockids, origin, libs, fn_args, object_number)) ret.append(getblock(blockids[cur], f"func_{fnid}", params + [None])) else: found = libs.find(origin[cur]["opcode"]) if found != None: params = [] for x in found["params"]: if x[0] == '"': params.append(x[1:]) elif x[0] == '#': fields, dicts = x[1:].split(";") after = json.loads(dicts) before = origin[cur]["fields"][fields][0] if before in after: params.append(after[before]) else: params.append(before) elif x[0:2] == '!!': params.append( libs.get_brd( origin[cur]["fields"]["BROADCAST_OPTION"][1])) elif x[0] == '>': data = origin[origin[cur]["inputs"]["CLONE_OPTION"] [1]]["fields"]["CLONE_OPTION"][0] if data == "_myself_": data = "self" else: data = libs.get_spt(data) params.append(data) elif x[0] == '!': params.append( libs.get_brd(origin[cur]["inputs"] ["BROADCAST_INPUT"][1][2])) elif x[0] == '^': data = origin[cur]["inputs"]["COSTUME"][1] if type(data) == list: params.append( getblock(idgen.getID(), "get_pictures", [ paramTrace(data, blockids, origin, libs, fn_args, object_number) ])) else: params.append( getblock(idgen.getID(), "get_pictures", [ libs.get_costume( object_number, origin[data]["fields"]["COSTUME"][0]) ])) elif x[0] == '*': dat = origin[origin[cur]["inputs"][x[1:]] [1]]["fields"][x[1:]][0] if x[1:] == "TOUCHINGOBJECTMENU": params.append(libs.get_spt(dat)) if x[1:] == "KEY_OPTION": params.append(libs.keyconvert(dat)) elif x == '&VARIABLE' or x == '&LIST': params.append( libs.get_var(origin[cur]["fields"][x[1:]][1])) elif x == '&NULL': params.append(None) else: d = paramTrace(origin[cur]["inputs"][x], blockids, origin, libs, fn_args, object_number) if type(d) == list: d = d[0] params.append(d) if found["type"] == "direct" or found[ "type"] == "operator" or found["type"] == "header": if found["code"] == "boolean_not": ret.append( getblock(blockids[cur], found["code"], params[1] + [None])) ret.append( getblock(blockids[cur], found["code"], params + [None])) elif found["type"] == "substk": if "SUBSTACK" in origin[cur]["inputs"]: substk = paramTrace(origin[cur]["inputs"]["SUBSTACK"], blockids, origin, libs, fn_args, object_number) else: substk = [] if found["code"] == "if_else" or found[ "code"] == "_if" or found[ "code"] == "repeat_while_true": substk2 = None if found["code"] == "if_else": if not "SUBSTACK2" in origin[cur]["inputs"]: substk2 = [] else: substk2 = paramTrace( origin[cur]["inputs"]["SUBSTACK2"], blockids, origin, libs, fn_args, object_number) if params == [[]]: print(f"stop by {cur}") ret.append( getblock(blockids[cur], found["code"], [params[0], None], statement=[substk, substk2])) else: ret.append( getblock(blockids[cur], found["code"], params + [None], statement=[substk])) elif found["type"] == "macro": if found["code"] == "resetlist": fn_definition, fn_call = macros.resetlist(params[0]) ret.append(fn_definition) ret.append(fn_call) else: print(f"BLOCK MISS! {origin[cur]['opcode']}") #print(f"Converted: Block '{cur}'") if origin[cur]["next"] == None: break cur = origin[cur]["next"] return ret
def convert(origin: dict): dict_items = [] localvars = [] localbroadcasts = [] localdatas = {} spts_lib = {} costumes = {} object_number = 1 for i in origin: if i["isStage"] == True: continue ret = dict() ret["id"] = idgen.getID() ret["name"] = i["name"] #지역변수 처리 vars, varids = variables.convert(i["variables"], target=ret["id"]) lists, listids = variables.convert(i["lists"], target=ret["id"], isList=True) broadcasts = variables.convert_broadcast(i["broadcasts"]) localvars += vars + lists localbroadcasts += broadcasts localdatas = {**localdatas, **varids, **listids} ret["objectType"] = "sprite" ret["rotateMethod"] = "free" ret["scene"] = "qqqq" ret["lock"] = False ret["sprite"] = {"pictures": []} for j in i["costumes"]: image = PIL.Image.open( f"temp/{j['md5ext'][0:2]}/{j['md5ext'][2:4]}/image/{j['assetId']}.png" ) width, height = image.size ret["sprite"]["pictures"].append({ "id": idgen.getID(), "dimension": { "width": width, "height": height }, "fileurl": f"temp/{j['md5ext'][0:2]}/{j['md5ext'][2:4]}/image/{j['md5ext']}", "name": j["name"], "filename": j["assetId"], "imageType": j["md5ext"][-3::1], "scale": 100 }) costumes[f"{object_number}::{j['name']}"] = ret["sprite"][ "pictures"][-1]["id"] ret["selectedPictureId"] = ret["sprite"]["pictures"][ i["currentCostume"]]["id"] ret["entity"] = { "font": "undefinedpx", "x": i["x"], "y": i["y"], "size": i["size"], "visible": i["visible"], "rotation": (i["direction"] + 270) % 360, "direction": 90, "width": ret["sprite"]["pictures"][ i["currentCostume"]]["dimension"]["width"], "height": ret["sprite"]["pictures"][ i["currentCostume"]]["dimension"]["height"], "regX": ret["sprite"]["pictures"][ i["currentCostume"]]["dimension"]["width"] / 2, "regY": ret["sprite"]["pictures"][i["currentCostume"]]["dimension"] ["height"] / 2, "scaleX": 1, "scaleY": 1, } print(f"Converted: Sprite '{i['name']}' to '{ret['id']}'") dict_items.append(ret) spts_lib[i["name"]] = ret["id"] object_number += 1 return dict_items, localvars, localdatas, localbroadcasts, spts_lib, costumes