def update(self, dt): """ This method is scheduled to be called repeatedly by the pyglet clock. Parameters ---------- dt : float The change in time since the last call. """ G.eventhandler.call("gameloop:tick:start", dt) self.cpu_usage_timer += dt if self.cpu_usage_timer > config.CPU_USAGE_REFRESH_TIME: self.cpu_usage = psutil.cpu_percent(interval=None) self.cpu_usage_timer = 0 # todo: change to attribute in State-class if dt > 3 and G.statehandler.active_state.NAME not in [ "minecraft:modloading" ]: logger.println( "[warning] running behind normal tick, did you overload game? missing " + str(dt - 1.0 / TICKS_PER_SEC) + " seconds") self.world.process_queue() sector = sectorize(self.position) if sector != self.sector: pyglet.clock.schedule_once( lambda _: G.world.change_sectors(self.sector, sector), 0.1) if self.sector is None: G.world.process_entire_queue() self.sector = sector G.eventhandler.call("gameloop:tick:end", dt)
def add_recipe_from_file(self, file: str): data = ResourceLocator.read(file, "json") result = self.add_recipe_from_data(data) if result is None and "--debugrecipes" in sys.argv: logger.println( "error in decoding recipe from file {}: type '{}' not found". format(file, data["type"]))
def _error_counter(self, image, blockname): if self.tries >= 10: logger.println( "[BLOCKITEMGENERATOR][FATAL][ERROR] failed to generate block item for {}" .format(self.tasks[self.blockindex])) self.last_image = image file = G.local + "/tmp/blockitemgenerator_fail_{}_of_{}.png".format( self.failed_counter, self.tasks[self.blockindex].replace( ":", "__")) image.save(file) logger.println( "[BLOCKITEMGENERATOR][FATAL][ERROR] image will be saved at {}". format(file)) file = "assets/missingtexture.png" # use missing texture instead self.generate_item(blockname, file) event.TickHandler.handler.bind( G.world.get_active_dimension().remove_block, 4, args=[(0, 0, 0)]) pyglet.clock.schedule_once(self.add_new_screen, 0.5) # event.TickHandler.handler.bind(self.add_new_screen, 10) self.blockindex += 1 self.failed_counter += 1 if self.failed_counter % 3 == 0 and self.SETUP_TIME <= 10: self.SETUP_TIME += 1 self.CLEANUP_TIME += 1 return pyglet.clock.schedule_once(self.take_image, 0.05) # event.TickHandler.handler.bind(self.take_image, 1) self.tries += 1
def add_new_screen(self, *args): self.blockindex += 1 if self.blockindex >= len(self.tasks): self.close() return G.world.get_active_dimension().hide_block((0, 0, 0)) try: blockinstance = G.world.get_active_dimension().add_block( (0, 0, 0), self.tasks[self.blockindex], block_update=False) if blockinstance.BLOCK_ITEM_GENERATOR_STATE is not None: blockinstance.set_model_state( blockinstance.BLOCK_ITEM_GENERATOR_STATE) blockinstance.face_state.update() except ValueError: logger.println( "[BLOCKITEMGENERATOR][ERROR] block '{}' can't be added to world. Failed with " "following exception".format(self.tasks[self.blockindex])) self.blockindex += 1 pyglet.clock.schedule_once(self.add_new_screen, self.SETUP_TIME / 20) # event.TickHandler.handler.bind(self.add_new_screen, self.SETUP_TIME) traceback.print_exc() return except: print(self.tasks[self.blockindex]) raise self.parts[1].progress = self.blockindex + 1 self.parts[1].text = "{}/{}: {}".format(self.blockindex + 1, len(self.tasks), self.tasks[self.blockindex]) # todo: add states pyglet.clock.schedule_once(self.take_image, self.SETUP_TIME / 20) # event.TickHandler.handler.bind(self.take_image, self.SETUP_TIME) G.world.get_active_dimension().get_chunk( 0, 0, generate=False).is_ready = True
def load(self): if self.status == DataPackStatus.SYSTEM_ERROR: return # when the data pack was active, unload it first try: if self.status in (DataPackStatus.ACTIVATED, DataPackStatus.DEACTIVATED): self.unload() self.access = ResourceLocator.ResourceDirectory(self.directory) if os.path.isdir(self.directory) else \ ResourceLocator.ResourceZipFile(self.directory) info = self.access.read("pack.mcmeta", "json")["pack"] if info["pack_format"] not in (1, 2, 3): self.status = DataPackStatus.ERROR logger.println( "[DATAPACK][ERROR] datapack version '{}' can't be loaded". format(info["pack_format"])) return self.description = info["description"] for file in self.access.get_all_entries_in_directory("data"): if file.endswith("/"): continue split = file.split("/") if "function" in file: name = "{}:{}".format(split[1], "/".join(split[3:]).split(".")[0]) self.function_table[ name] = chat.command.McFunctionFile.McFunctionFile( self.access.read(file, None).decode("UTF-8"), name) except: self.status = DataPackStatus.SYSTEM_ERROR logger.println("error during loading data pack '{}'".format( self.name)) traceback.print_exc() logger.write_exception() return self.status = DataPackStatus.ACTIVATED
def locate_transfer(vm, name): """Using specific parameters to locate transfer function. Args: vm: virtual machine includes all env information name: the name of contract Returns: """ if global_vars.apply_function_address is None: return # check whether the type is valid transfer type apply_func_type = structure.FunctionType() apply_func_type.args = bytearray([bin_format.i64, bin_format.i64, bin_format.i64]) apply_func_type.rets = bytearray() apply_func = vm.store.funcs[vm.module_instance.funcaddrs[global_vars.apply_function_address]] global_vars.locate() if apply_func.functype == apply_func_type: params = [utils.eos_abi_to_int(name), utils.eos_abi_to_int('eosio.token'), utils.eos_abi_to_int('transfer')] global_vars.locate() try: vm.exec_by_address(global_vars.apply_function_address, params) except AssertionError as e: logger.println(f'unreachable transfer: {e}') except SystemExit as e: logger.debugln(f'transfer found') global_vars.sym_exec()
def normalize_ceil(position): try: x, y, z = position if type(position) == tuple else tuple(position) x, y, z = (int(math.ceil(x)), int(math.ceil(y)), int(math.ceil(z))) return x, y, z except: logger.println(position) raise
def call(self, event_name, *args, **kwargs): """ call an event on this event bus. also works when deactivated :param event_name: the name of the event to call :param args: arguments to give :param kwargs: kwargs to give :return: an list of tuple of (return value, info) """ result = [] if event_name not in self.event_subscriptions: return result exception_occ = False for function, eargs, ekwargs, info in self.event_subscriptions[ event_name]: dif = "Exception" try: start = time.time() result.append((function( *list(args) + list(self.extra_arguments[0]) + list(eargs), **{ **kwargs, **self.extra_arguments[1], **ekwargs }), info)) dif = time.time() - start except SystemExit: raise except: if not exception_occ: logger.println( "EXCEPTION DURING CALLING EVENT '{}' OVER ".format( event_name)) traceback.print_stack() exception_occ = True logger.println("exception:") traceback.print_exc() logger.write_exception() logger.println( "during calling function: {} with arguments: {}".format( function, list(args) + list(self.extra_arguments[0]) + list(eargs), { **kwargs, **self.extra_arguments[1], **ekwargs }, sep="\n")) logger.println("function info: '{}'".format(info)) if G.debugevents: with open(G.local + "/debug/eventbus_{}.txt".format(self.id), mode="a") as f: f.write( "\nevent call of '{}' takes {}s until finish".format( function, dif)) if exception_occ and self.crash_on_error: logger.println("\nout of the above reasons, the game has crashes") sys.exit(-1) return result
def on_key_press(self, symbol, modifiers): """ called when an key is pressed :param symbol: the symbol that is pressed :param modifiers: the modifiers that are used """ if symbol == 65288: # BACK self.text = self.text[:self.active_index - 1] + self.text[self.active_index:] self.active_index -= 1 elif symbol == key.DELETE and self.active_index < len(self.text): self.text = self.text[:self. active_index] + self.text[self.active_index + 1:] elif symbol == 65360: self.active_index = 0 # begin key elif symbol == key.END: self.active_index = len(self.text) elif symbol == key.ENTER: # execute command self.CANCEL_INPUT = False G.eventhandler.call("chat:text_enter", self.text) logger.println("[CHAT][INFO] entered text: '{}'".format(self.text), write_into_console=False) if self.CANCEL_INPUT: self.history.insert(0, self.text) self.close() return if self.text.startswith("/"): # execute command G.commandparser.parse(self.text) else: self.print_ln(self.text) self.history.insert(0, self.text) self.close() elif symbol == key.UP and self.historyindex < len( self.history) - 1: # go one item up in the history self.historyindex += 1 self.text = self.history[self.historyindex] self.active_index = len(self.text) elif symbol == key.DOWN and self.historyindex >= 0: # go one item down in the history self.historyindex -= 1 if self.historyindex != -1: self.text = self.history[self.historyindex] else: self.text = "" self.active_index = len(self.text) elif symbol == key.LEFT: self.active_index -= 1 if self.active_index < 0: self.active_index = len(self.text) + self.active_index + 1 elif symbol == key.RIGHT: self.active_index += 1 if self.active_index > len(self.text): self.active_index = 0 elif symbol == key.V and modifiers & key.MOD_CTRL: # insert text from clipboard self.enter(clipboard.paste())
def _from_data(cls, name, data): try: return BlockStateDefinition(data, name) except BlockStateNotNeeded: pass # do we need this model? except: logger.println( "error during loading model for {} from data {}".format( name, data)) traceback.print_exc()
def after_sym_exec(name): if global_vars.fake_eos_transfer_count > 0: logger.println(f'{name}: fake eos found') if global_vars.forged_transfer_notification_count > 0: logger.println(f'{name}: forged transfer notification found') if global_vars.block_dependency_count > 0: logger.println(f'{name}: dependency found') if global_vars.ethereum_delegate_call > 0: logger.println(f'{name}: delegate call found') if global_vars.ethereum_greedy > 0: logger.println(f'{name}: greedy found')
def _switch_to(self, statename): if statename not in self.states: return self.CANCEL_SWITCH_STATE = False G.eventhandler.call("state:switch:pre", statename) if self.CANCEL_SWITCH_STATE: return if self.active_state: self.active_state.deactivate() self.active_state = self.states[statename] self.active_state.activate() G.eventhandler.call("state:switch:post", statename) logger.println("[STATEHANDLER][STATE CHANGE] state changed to '{}'".format(statename), write_into_console=False)
def __init__(self, item_name_or_instance, amount=1): if issubclass(type(item_name_or_instance), item.Item.Item): self.item = item_name_or_instance elif type(item_name_or_instance) == str: if item_name_or_instance in G.registry.get_by_name("item").registered_object_map: self.item = G.registry.get_by_name("item").registered_object_map[item_name_or_instance]() else: logger.println("can't find item named {}".format(item_name_or_instance)) self.item = None else: self.item = None self.amount = amount if self.item and 0 <= amount <= self.item.get_max_stack_size() else 0
def can_set_item(self, itemstack) -> bool: itemname = itemstack.get_item_name() flag1 = self.allowed_item_tags is not None flag2 = flag1 and (any([itemname in G.taghandler.taggroups["items"].tags[x].entries for x in self.allowed_item_tags]) or itemstack.get_item_name() is None) flag3 = self.allowed_item_func is not None flag4 = flag3 and self.allowed_item_func(itemstack) try: return (flag1 and flag2) or (flag3 and flag4) or not (flag1 or flag3) except: logger.println("[GUI][ERROR] error during executing check func '{}'".format(self.allowed_item_func)) traceback.print_exc() return False
def _from_file(cls, file: str): try: s = file.split("/") modname = s[s.index("blockstates") - 1] return BlockStateDefinition( ResourceLocator.read(file, "json"), "{}:{}".format(modname, s[-1].split(".")[0])) except BlockStateNotNeeded: pass except: logger.println( "error during loading model from file {}".format(file)) traceback.print_exc()
def call_as_stack(self, eventname, *args, amount=1, **kwargs): result = [] if eventname not in self.event_subscriptions: raise RuntimeError("event bus has no notation for this event") if len(self.event_subscriptions[eventname]) < amount: raise RuntimeError( "can't run event. EventBus is for this event empty") exception_occ = False for _ in range(amount): function, eargs, ekwargs, info = self.event_subscriptions[ eventname].pop(0) start = time.time() try: result.append((function( *list(args) + list(self.extra_arguments[0]) + list(eargs), **{ **kwargs, **self.extra_arguments[1], **ekwargs }), info)) except: if not exception_occ: logger.println( "EXCEPTION DURING CALLING EVENT {} OVER ".format( eventname)) traceback.print_stack() exception_occ = True logger.println("exception:") traceback.print_exc() logger.write_exception() logger.println("during calling function:", function, "with arguments:", list(args) + list(self.extra_arguments[0]) + list(eargs), { **kwargs, **self.extra_arguments[1], **ekwargs }, sep="\n") logger.println("function info:", info) dif = time.time() - start if G.debugevents: with open(G.local + "/debug/eventbus_{}.txt".format(self.id), mode="a") as f: f.write("\nevent call of {} takes {}s until finish".format( function, dif)) if exception_occ and self.crash_on_error: logger.println("\nout of the above reasons, the game has crashes") sys.exit(-1) return result
def update_status(self): if any([ self.slots[0].itemstack.get_item_name() in G.craftinghandler.furnace_recipes[x] for x in self.types ]): if self.fuel_left == 0: if self.slots[1].itemstack.is_empty(): self.reset() return # consume one fuel try: fuel = self.slots[1].itemstack.item.FUEL self.fuel_max = fuel self.fuel_left += fuel except AttributeError: logger.println( "[FUEL][WARNING] item '{}' was marked as fuel but did NOT have FUEL-attribute" .format(self.slots[1].itemstack.get_item_name())) self.reset() return self.slots[1].itemstack.add_amount(-1) if self.slots[0].itemstack.get_item_name() == self.old_item_name: return self.old_item_name = self.slots[0].itemstack.get_item_name() self.smelt_start = time.time() for x in self.types: if self.old_item_name in G.craftinghandler.furnace_recipes[x]: recipe = G.craftinghandler.furnace_recipes[x][ self.old_item_name] break else: logger.println("[ERROR] no recipe found") self.reset() return if self.slots[2].itemstack.get_item_name() is not None and ( self.slots[2].itemstack.get_item_name() != recipe.output or self.slots[2].itemstack.amount >= self.slots[2].itemstack.item.get_max_stack_size()): if not self.slots[2].itemstack.is_empty(): print( self.slots[2].itemstack.get_item_name() != recipe.output, self.slots[2].itemstack.amount, self.slots[2].itemstack.item.get_max_stack_size()) self.reset() return self.recipe: crafting.FurnaceCrafting.FurnesRecipe = recipe self.block.active = True self.block.face_state.update() else: self.reset()
def __init__(self): self.found_mods = [] self.mods = {} self.modorder = [] self.active_directory = None self.active_loading_stage = 0 self.lasttime_mods = {} self.found_mod_instances = [] if os.path.exists(G.local + "/build/mods.json"): with open(G.local + "/build/mods.json") as f: self.lasttime_mods = json.load(f) elif not G.prebuilding: logger.println( "[WARNING] can't locate mods.json in build-folder. This may be an error" )
def special_build(self, used): if used not in self.found_models: logger.println( "model error: can't locate model for '{}'".format(used)) return file = self.found_models[used] if type(file) == str: data = ResourceLocator.read(file, "json") else: data = file if "parent" in data: self.__let_subscribe_to_build(data["parent"]) depend = [data["parent"]] else: depend = [] self.dependence_list.append((used, depend))
def _load_from_old_json(data: dict, file: str): if "main files" in data: files = data["main files"] for location in (files if type(files) == list else [files]): try: importlib.import_module( location.replace("/", ".").replace("\\", ".")) except ModuleNotFoundError: logger.println( "[MODLOADER][ERROR] can't load mod file {}".format( location)) return else: logger.println( "[ERROR] mod.json of '{}' does NOT contain an 'main files'-attribute" .format(file))
def sort_mods(self): modinfo = {} errors = [] for mod in self.found_mods: if mod.name in modinfo: errors.append( " -Mod '{}' has more than one version in the folder. Please load only every mod ONES" .format(mod.name)) errors.append(" found in: {}".format(mod.path)) else: modinfo[mod.name] = [] for mod in self.found_mods: depends = mod.dependinfo[0][:] for depend in depends: if not depend.arrival(): errors.append( "- Mod '{}' needs mod '{}' which is not provided". format(mod.name, depend)) for depend in mod.dependinfo[2]: if depend.arrival(): errors.append( "- Mod '{}' is incompatible with '{}'".format( mod.name, depend)) for mod in self.found_mods: for depend in mod.dependinfo[4]: if depend.name in modinfo and depend.name not in modinfo[ mod.name]: modinfo[mod.name].append(depend.name) for depend in mod.dependinfo[3]: if depend.name in modinfo and mod.name not in modinfo[ depend.name]: modinfo[depend.name].append(mod.name) if len(errors) > 0: logger.println("errors with mods:") logger.println(" ", end="") logger.println(*errors, sep="\n ") sys.exit(-1) self.modorder = list( util.math.topological_sort([(key, modinfo[key]) for key in modinfo.keys()])) logger.println("mod loading order: ") logger.println( " -", "\n - ".join([ "{} ({})".format(name, self.mods[name].version) for name in self.modorder ]))
def unload(self): if self.status == DataPackStatus.SYSTEM_ERROR: return if self.status == DataPackStatus.INACTIVE or self.status == DataPackStatus.UNLOADED: raise ValueError("can't un-load an not loaded datapack") self.status = DataPackStatus.DEACTIVATED # deactivated access during working try: self.function_table.clear() # unload all .mcfunction files except: self.status = DataPackStatus.SYSTEM_ERROR logger.println("error during unloading data pack '{}'".format( self.name)) logger.write_exception() traceback.print_exc() return self.status = DataPackStatus.UNLOADED # we have successfully unloaded the data-pack if self.access: self.access.close() self.access = None
def load_data(from_block_item_generator=False): if G.prebuilding and not from_block_item_generator: return G.eventhandler.call("itemhandler:build:atlases:load") if not os.path.exists(G.local + "/build/itematlases"): os.makedirs(G.local + "/build/itematlases") elif os.path.exists(G.local + "/build/itematlases/index.json"): with open(G.local + "/build/itematlases/index.json") as f: indextable = json.load(f) for file in os.listdir(G.local + "/build/itematlases"): if not file.endswith(".json") and file in indextable: atlas = texture.TextureAtlas.TextureAtlas( size=indextable[file]["size"], image_size=(32, 32), add_missing_texture=False, pyglet_special_pos=False) image = PIL.Image.open(G.local + "/build/itematlases/" + file) atlas.texture = image atlas.images = indextable[file]["loaded_item_file_names"] atlas.imagelocations = indextable[file]["locations"] TEXTURE_ATLASES.append(atlas) if not G.prebuilding: atlas.group = pyglet.image.ImageGrid( pyglet.image.load(G.local + "/build/itematlases/" + file), *atlas.size) items.itemindextable = indextable["loaded_item_file_names"] if not G.prebuilding: with open(G.local + "/build/itemblockfactory.json") as f: data = json.load(f) for entry in data[:]: name = entry[0] obj = factory.ItemFactory.ItemFactory().setName( name).setHasBlockFlag(True).setDefaultItemFile(entry[1]) blocktable = G.registry.get_by_name( "block").registered_object_map if name in blocktable: block = blocktable[name] block.modify_block_item(obj) obj.finish() else: logger.println( "[ERROR] during constructing block item for {}: Failed to find block" .format(name)) data.remove(entry) with open(G.local + "/build/itemblockfactory.json", mode="w") as f: json.dump(data, f)
def kill(self, test_totem=True): if test_totem: # todo: add effects if self.get_active_inventory_slot().get_itemstack().get_item_name( ) == "minecraft:totem_of_undying": self.get_active_inventory_slot().get_itemstack().clean() self.hearts = 20 self.hunger = 20 return elif self.inventorys["main"].slots[45].get_itemstack( ).get_item_name() == "minecraft:totem_of_undying": self.inventorys["main"].slots[45].get_itemstack().clean() self.hearts = 20 self.hunger = 20 return super().kill() # todo: create an new entity for player if not globals.world.gamerulehandler.table[ "keepInventory"].status.status: globals.commandparser.parse("/clear") if globals.world.gamerulehandler.table[ "showDeathMessages"].status.status: logger.println("[CHAT] player {} died".format(self.name)) globals.window.position = (globals.world.spawnpoint[0], util.math.get_max_y( globals.world.spawnpoint), globals.world.spawnpoint[1]) self.active_inventory_slot = 0 globals.window.dy = 0 globals.chat.close() self.xp = 0 self.xp_level = 0 self.hearts = 20 self.hunger = 20 globals.window.flying = False self.armor_level = 0 self.armor_toughness = 0 globals.eventhandler.call("player:die", self) self.reset_moving_slot() globals.inventoryhandler.close_all_inventories() # todo: recalculate armor level! if not globals.world.gamerulehandler.table[ "doImmediateRespawn"].status.status: globals.statehandler.switch_to( "minecraft:escape_state") # todo: add special state
def load(self, modname, check_mod_dirs=True, load_direct=False): if modname in self.loaded_mod_dirs and check_mod_dirs: logger.println( "ERROR: mod '{}' has tried to load crafting recipes twice or more" .format(modname)) return # make sure to load only ones! self.loaded_mod_dirs.add(modname) for itemname in ResourceLocator.get_all_entries( "data/{}/recipes".format(modname)): if itemname.endswith("/"): continue if not load_direct: G.modloader.mods[modname].eventbus.subscribe( "stage:recipe:bake", self.add_recipe_from_file, itemname, info="loading crafting recipe from {}".format(itemname)) else: self.add_recipe_from_file(itemname)
def build(self): raw = self.entries[:] old_entries = self.entries self.entries = [] for entry in raw: if entry.startswith("#"): if entry not in self.master.tags: if self.load_tries > 4: logger.println("[TAG][FATAL] failed to load tag {} as tag {} was not found".format(self.name, entry)) self.load_tries = 0 old_entries.remove(entry) continue self.entries = old_entries mod.ModMcpython.mcpython.eventbus.subscribe("stage:tag:load", self.build) self.load_tries += 1 return self.entries += self.master.tags[entry].entries else: self.entries.append(entry)
def execution_and_analyze(contract_path): name = os.path.basename(contract_path).split('.wasm')[0] try: global_vars.vm = vm = load(contract_path) except Exception as e: logger.println(f'{e}: [{name}] failed initialization') return try: global_vars.set_name_int64(name) except Exception as e: logger.debugln(f'invalid contract name {name}: {e}') try: before_sym_exec(vm, name.split('_')[0]) detect_fake_eos(vm, name.split('_')[0]) after_sym_exec(name) except Exception as e: logger.println(f'Error: {e}') finally: global_vars.clear_count()
def normalize(position): """ Accepts `position` of arbitrary precision and returns the block containing that position. Parameters ---------- position : tuple of len 3 Returns ------- block_position : tuple of ints of len 3 """ try: x, y, z = position if type(position) == tuple else tuple(position) x, y, z = (int(round(x)), int(round(y)), int(round(z))) return x, y, z except: logger.println(position) raise
def load_model(self, name: str): if name in self.models: return location = self.found_models[name] try: if type(location) == str: modeldata = ResourceLocator.read(location, "json") self.models[name] = rendering.model.Model.Model( modeldata.copy(), "block/" + location.split("/")[-1].split(".")[0], name.split(":")[0] if name.count(":") == 1 else "minecraft") else: self.models[name] = rendering.model.Model.Model( location.copy(), name, name.split(":")[0] if name.count(":") == 1 else "minecraft") except: logger.println("error during loading model '{}' named '{}'".format( location, name)) traceback.print_exc() traceback.print_stack()
def reload_crafting_recipes(self): G.eventhandler.call("craftinghandler:reload:prepare") # all shapeless recipes sorted after item count self.crafting_recipes_shapeless = {} # all shaped recipes sorted after item count and than size self.crafting_recipes_shaped = {} # all smelting outputs sorted after ingredient self.furnace_recipes = {} G.eventhandler.call("craftinghandler:reload:start") for i, modname in enumerate(list(self.loaded_mod_dirs)): logger.println( "\r[MODLOADER][INFO] reloading mod recipes for mod {} ({}/{})". format(modname, i + 1, len(self.loaded_mod_dirs)), end="") self.load(modname, check_mod_dirs=False, load_direct=True) logger.println() G.eventhandler.call("craftinghandler:reload:finish")