def pruneoldbackups(self, filename="IndependentPurge"): if len(self.backups) > self.config["Backups"]["backups-keep"]: self.log.info("Deleting old backups...") while len(self.backups) > self.config["Backups"]["backups-keep"]: backup = self.backups[0] if not self.wrapper.events.callevent("wrapper.backupDelete", {"file": filename}): """ eventdoc <group> Backups <group> <description> Called upon deletion of a backup file. <description> <abortable> Yes, return False to abort. <abortable> <comments> <comments> <payload> "file": filename <payload> """ break try: os.remove('%s/%s' % (self.config["Backups"]["backup-location"], backup[1])) except Exception as e: self.log.error("Failed to delete backup (%s)", e) self.log.info("Deleting old backup: %s", datetime.datetime.fromtimestamp(int(backup[0])).strftime('%Y-%m-%d_%H:%M:%S')) # hink = self.backups[0][1][:] # not used... del self.backups[0] putjsonfile(self.backups, "backups", self.config["Backups"]["backup-location"])
def _json_save(self): putcode = putjsonfile(self.Data, self.name, self.root) if not putcode: self.log.exception( "Error encoutered while saving json data:\n'%s/%s.%s'" "\nData Dump:\n%s" % ( self.root, self.name, self.file_ext, self.Data))
def _json_save(self): putcode = putjsonfile(self.Data, self.name, self.root) if not putcode: self.log.exception( "Error encoutered while saving json data:\n'%s/%s.%s'" "\nData Dump:\n%s" % ( self.root, self.name, self.file_ext, self.Data))
def banip(self, ipaddress, reason="The Ban Hammer has spoken!", source="Wrapper", expires=False): """ Ban an IP address (IPV-4) :param ipaddress - ip address to ban :param reason - text reason for ban :param source - source (author/op) of ban. :param expires - expiration in seconds from epoch time. Field exists but not used by the vanilla server. - implement it for tempbans in future? - Gets converted to string representation in the ban file. This probably only works on 1.7.10 servers or later """ if not isipv4address(ipaddress): return "Invalid IPV4 address: %s" % ipaddress banlist = getjsonfile("banned-ips", self.srv_data.serverpath) if banlist is not False: # file and directory exist. if banlist is None: # file was empty or not valid banlist = dict() # ensure valid dict before operating on it if find_in_json(banlist, "ip", ipaddress): return "address already banned" # error text else: if expires: try: expiration = epoch_to_timestr(expires) except Exception as e: print('Exception: %s' % e) return "expiration date invalid" # error text else: expiration = "forever" banlist.append({ "ip": ipaddress, "created": epoch_to_timestr(time.time()), "source": source, "expires": expiration, "reason": reason }) if putjsonfile(banlist, "banned-ips", self.srv_data.serverpath): banned = "" for client in self.srv_data.clients: if client.ip == str(ipaddress): console_command = "kick %s Your IP is Banned!" % client.username self.eventhandler.callevent( "proxy.console", {"command": console_command}) """ eventdoc <description> internalfunction <description> """ banned += "\n%s" % client.username return "Banned ip address: %s\nPlayers kicked as " \ "a result:%s" % (ipaddress, banned) return "Could not write banlist to disk" else: return "Banlist not found on disk"
def pruneoldbackups(self, filename="IndependentPurge"): if len(self.backups) > self.config["Backups"]["backups-keep"]: self.log.info("Deleting old backups...") while len(self.backups) > self.config["Backups"]["backups-keep"]: backup = self.backups[0] if not self.wrapper.events.callevent("wrapper.backupDelete", {"file": filename}): break try: os.remove('%s/%s' % (self.config["Backups"]["backup-location"], backup[1])) except Exception as e: self.log.error("Failed to delete backup (%s)", e) self.log.info("Deleting old backup: %s", datetime.datetime.fromtimestamp(int(backup[0])).strftime('%Y-%m-%d_%H:%M:%S')) # hink = self.backups[0][1][:] # not used... del self.backups[0] putjsonfile(self.backups, "backups", self.config["Backups"]["backup-location"])
def banuuidraw(self, uuid, username, reason="The Ban Hammer has spoken!", source="Wrapper", expires=False): """ Ban a raw uuid/name combination with no mojang error checks :param uuid - uuid to ban (MCUUID) :param username - Name of player to ban :param reason - text reason for ban :param source - source (author/op) of ban. :param expires - expiration in seconds from epoch time. Field exists but not used by the vanilla server - implement it for tempbans in future? Gets converted to string representation in the ban file. This probably only works on 1.7.10 servers or later """ banlist = getjsonfile("banned-players", self.srv_data.serverpath) if banlist is not False: # file and directory exist. if banlist is None: # file was empty or not valid banlist = dict() # ensure valid dict before operating on it if find_in_json(banlist, "uuid", str(uuid)): return "player already banned" # error text else: if expires: try: expiration = epoch_to_timestr(expires) except Exception as e: print('Exception: %s' % e) return "expiration date invalid" # error text else: expiration = "forever" banlist.append({ "uuid": uuid.string, "name": username, "created": epoch_to_timestr(time.time()), "source": source, "expires": expiration, "reason": reason }) if putjsonfile(banlist, "banned-players", self.srv_data.serverpath): self.log.info("kicking %s... %s", username, reason) console_command = "kick %s Banned: %s" % (username, reason) self.eventhandler.callevent("proxy.console", {"command": console_command}, abortable=False) """ eventdoc <description> internalfunction <description> """ # noqa return "Banned %s: %s - %s" % (username, uuid, reason) return "Could not write banlist to disk" else: return "Banlist not found on disk"
def banip(self, ipaddress, reason="The Ban Hammer has spoken!", source="Wrapper", expires=False): """ Ban an IP address (IPV-4) :param ipaddress - ip address to ban :param reason - text reason for ban :param source - source (author/op) of ban. :param expires - expiration in seconds from epoch time. Field exists but not used by the vanilla server. - implement it for tempbans in future? - Gets converted to string representation in the ban file. This probably only works on 1.7.10 servers or later """ if not isipv4address(ipaddress): return "Invalid IPV4 address: %s" % ipaddress banlist = getjsonfile("banned-ips", self.srv_data.serverpath) if banlist is not False: # file and directory exist. if banlist is None: # file was empty or not valid banlist = dict() # ensure valid dict before operating on it if find_in_json(banlist, "ip", ipaddress): return "address already banned" # error text else: if expires: try: expiration = epoch_to_timestr(expires) except Exception as e: print('Exception: %s' % e) return "expiration date invalid" # error text else: expiration = "forever" banlist.append({"ip": ipaddress, "created": epoch_to_timestr(time.time()), "source": source, "expires": expiration, "reason": reason}) if putjsonfile(banlist, "banned-ips", self.srv_data.serverpath): banned = "" for client in self.srv_data.clients: if client.ip == str(ipaddress): console_command = "kick %s Your IP is Banned!" % client.username self.eventhandler.callevent("proxy.console", {"command": console_command}) """ eventdoc <description> internalfunction <description> """ banned += "\n%s" % client.username return "Banned ip address: %s\nPlayers kicked as " \ "a result:%s" % (ipaddress, banned) return "Could not write banlist to disk" else: return "Banlist not found on disk"
def banuuid(self, uuid, reason="The Ban Hammer has spoken!", source="Wrapper", expires=False): """ Ban someone by UUID This is the 1.7.6 way to ban.. :param uuid - uuid to ban (MCUUID) :param reason - text reason for ban :param source - source (author/op) of ban. :param expires - expiration in seconds from epoch time. Field exists but not used by the vanilla server - implement it for tempbans in future? Gets converted to string representation in the ban file. This probably only works on 1.7.10 servers or later """ banlist = getjsonfile("banned-players", self.srv_data.serverpath) if banlist is not False: # file and directory exist. if banlist is None: # file was empty or not valid banlist = dict() # ensure valid dict before operating on it if find_in_json(banlist, "uuid", str(uuid)): return "player already banned" # error text else: if expires: try: expiration = epoch_to_timestr(expires) except Exception as e: print('Exception: %s' % e) return "expiration date invalid" # error text else: expiration = "forever" name = self.uuids.getusernamebyuuid(uuid.string) banlist.append({ "uuid": uuid.string, "name": name, "created": epoch_to_timestr(time.time()), "source": source, "expires": expiration, "reason": reason }) if putjsonfile(banlist, "banned-players", self.srv_data.serverpath): # this actually is not needed. Commands now handle the kick. console_command = "kick %s %s" % (name, reason) self.run_command(console_command) return "Banned %s: %s" % (name, reason) return "Could not write banlist to disk" else: return "Banlist not found on disk"
def pruneoldbackups(self, filename="IndependentPurge"): if len(self.backups) > self.config["Backups"]["backups-keep"]: self.log.info("Deleting old backups...") while len(self.backups) > self.config["Backups"]["backups-keep"]: backup = self.backups[0] if not self.wrapper.events.callevent( "wrapper.backupDelete", {"file": filename}): # noqa """ eventdoc <group> Backups <group> <description> Called upon deletion of a backup file. <description> <abortable> Yes, return False to abort. <abortable> <comments> <comments> <payload> "file": filename <payload> """ # noqa break try: os.remove( '%s/%s' % (self.config["Backups"]["backup-location"], backup[1])) except Exception as e: self.log.error("Failed to delete backup (%s)", e) self.log.info( "Deleting old backup: %s", datetime.datetime.fromtimestamp(int( backup[0])).strftime('%Y-%m-%d_%H:%M:%S')) # noqa # hink = self.backups[0][1][:] # not used... del self.backups[0] putjsonfile(self.backups, "backups", self.config["Backups"]["backup-location"])
def banuuidraw(self, uuid, username, reason="The Ban Hammer has spoken!", source="Wrapper", expires=False): """ Ban a raw uuid/name combination with no mojang error checks :param uuid - uuid to ban (MCUUID) :param username - Name of player to ban :param reason - text reason for ban :param source - source (author/op) of ban. :param expires - expiration in seconds from epoch time. Field exists but not used by the vanilla server - implement it for tempbans in future? Gets converted to string representation in the ban file. This probably only works on 1.7.10 servers or later """ banlist = getjsonfile("banned-players", self.srv_data.serverpath) if banlist is not False: # file and directory exist. if banlist is None: # file was empty or not valid banlist = dict() # ensure valid dict before operating on it if find_in_json(banlist, "uuid", str(uuid)): return "player already banned" # error text else: if expires: try: expiration = epoch_to_timestr(expires) except Exception as e: print('Exception: %s' % e) return "expiration date invalid" # error text else: expiration = "forever" banlist.append({"uuid": uuid.string, "name": username, "created": epoch_to_timestr(time.time()), "source": source, "expires": expiration, "reason": reason}) if putjsonfile(banlist, "banned-players", self.srv_data.serverpath): self.log.info("kicking %s... %s", username, reason) console_command = "kick %s Banned: %s" % (username, reason) self.eventhandler.callevent("proxy.console", {"command": console_command}) """ eventdoc <description> internalfunction <description> """ return "Banned %s: %s - %s" % (username, uuid, reason) return "Could not write banlist to disk" else: return "Banlist not found on disk"
def banuuid(self, uuid, reason="The Ban Hammer has spoken!", source="Wrapper", expires=False): """ Ban someone by UUID This is the 1.7.6 way to ban.. :param uuid - uuid to ban (MCUUID) :param reason - text reason for ban :param source - source (author/op) of ban. :param expires - expiration in seconds from epoch time. Field exists but not used by the vanilla server - implement it for tempbans in future? Gets converted to string representation in the ban file. This probably only works on 1.7.10 servers or later """ banlist = getjsonfile( "banned-players", self.javaserver.serverpath ) if banlist is not False: # file and directory exist. if banlist is None: # file was empty or not valid banlist = dict() # ensure valid dict before operating on it if find_in_json(banlist, "uuid", str(uuid)): return "player already banned" # error text else: if expires: try: expiration = epoch_to_timestr(expires) except Exception as e: print('Exception: %s' % e) return "expiration date invalid" # error text else: expiration = "forever" name = self.uuids.getusernamebyuuid(uuid.string) banlist.append({"uuid": uuid.string, "name": name, "created": epoch_to_timestr(time.time()), "source": source, "expires": expiration, "reason": reason}) if putjsonfile(banlist, "banned-players", self.javaserver.serverpath): # this actually is not needed. Commands now handle the kick. console_command = "kick %s %s" % (name, reason) self.run_command(console_command) return "Banned %s: %s" % (name, reason) return "Could not write banlist to disk" else: return "Banlist not found on disk"
def pardonname(self, username): banlist = getjsonfile("banned-players", self.serverpath) if banlist is not False: # file and directory exist. if banlist is None: # file was empty or not valid return "No bans have ever been recorded..?" banrecord = find_in_json(banlist, "name", str(username)) if banrecord: for x in banlist: if x == banrecord: banlist.remove(x) if putjsonfile(banlist, "banned-players", self.serverpath): return "pardoned %s" % username return "Could not write banlist to disk" else: return "That person was never banned" # error text else: return "Banlist not found on disk" # error text
def pardonname(self, username): banlist = getjsonfile("banned-players", self.srv_data.serverpath) if banlist is not False: # file and directory exist. if banlist is None: # file was empty or not valid return "No bans have ever been recorded..?" banrecord = find_in_json(banlist, "name", str(username)) if banrecord: for x in banlist: if x == banrecord: banlist.remove(x) if putjsonfile(banlist, "banned-players", self.srv_data.serverpath): return "pardoned %s" % username return "Could not write banlist to disk" else: return "That person was never banned" # error text else: return "Banlist not found on disk" # error text
def pardonip(self, ipaddress): if not isipv4address(ipaddress): return "Invalid IPV4 address: %s" % ipaddress banlist = getjsonfile("banned-ips", self.serverpath) if banlist is not False: # file and directory exist. if banlist is None: # file was empty or not valid return "No IP bans have ever been recorded." banrecord = find_in_json(banlist, "ip", ipaddress) if banrecord: for x in banlist: if x == banrecord: banlist.remove(x) if putjsonfile(banlist, "banned-ips", self.serverpath): return "pardoned %s" % ipaddress return "Could not write banlist to disk" else: return "That address was never banned" # error text else: return "Banlist not found on disk" # error text
def pardonip(self, ipaddress): if not isipv4address(ipaddress): return "Invalid IPV4 address: %s" % ipaddress banlist = getjsonfile("banned-ips", self.srv_data.serverpath) if banlist is not False: # file and directory exist. if banlist is None: # file was empty or not valid return "No IP bans have ever been recorded." banrecord = find_in_json(banlist, "ip", ipaddress) if banrecord: for x in banlist: if x == banrecord: banlist.remove(x) if putjsonfile(banlist, "banned-ips", self.srv_data.serverpath): return "pardoned %s" % ipaddress return "Could not write banlist to disk" else: return "That address was never banned" # error text else: return "Banlist not found on disk" # error text
def command_op(self, player, payload): if player is None: player = self.wrapper.xplayer if not self._superop(player, 9): return False # get argument flags flags = [x.lower() for x in payload["args"]] superop = "-s" in flags op_level = "-l" in flags offline_mode = "-o" in flags new_operator_name = getargs(payload["args"], 0) valid_uuid = self.wrapper.uuids.getuuidbyusername(new_operator_name) if not offline_mode and valid_uuid is None: player.message("&c'%s' is not a valid player name!" % new_operator_name) return False if offline_mode: name = new_operator_name uuid = str(self.wrapper.uuids.getuuidfromname(name)) else: uuid = str(valid_uuid) name = self.wrapper.uuids.getusernamebyuuid(uuid) superlevel = 4 # default if op_level: for index, x in enumerate(flags): if x == "-l": break # noinspection PyUnboundLocalVariable arg_level = get_int(getargs(flags, index + 1)) superlevel = max(1, arg_level) if superop and superlevel > 4: superlevel = max(5, superlevel) # 2 = make sure server STARTED if self.wrapper.javaserver.state == 2: self.wrapper.javaserver.console("op %s" % name) # if not, wrapper makes ops.json edits else: self.wrapper.javaserver.refresh_ops(read_super_ops=False) oplist = self.wrapper.javaserver.operator_list newop_item = { "uuid": uuid, "name": name, "level": min(4, superlevel), "bypassesPlayerLimit": False } if oplist: for op, ops in enumerate(oplist): # We don't expect it is already there, but if so... if uuid == ops["uuid"]: oplist.pop(op) oplist.append(newop_item) else: oplist = [ newop_item, ] result = putjsonfile(oplist, "ops") if result: player.message("&6Ops.json file saved ok.") else: player.message("&cSomething went wrong writing ops.json.") # update the superops.txt file if superop: set_item(name, superlevel, "superops.txt") player.message("&6Updated as SuperOP.") time.sleep(.5) self.wrapper.javaserver.refresh_ops()
def loadconfig(self): # load older versions of wrapper.properties to preserve prior settings. if os.path.exists("wrapper.properties"): with open("wrapper.properties", "r") as f: oldconfig = f.read() oldconfig = "Deprecated File! Use the 'wrapper.properties.json' instead!\n\n%s" % oldconfig with open("_wrapper.properties", "w") as f: f.write(oldconfig) os.remove("wrapper.properties") # Create new config if none exists if not os.path.exists("wrapper.properties.json"): putjsonfile(CONFIG, "wrapper.properties", sort=True) self.exit = True # Read existing configuration self.config = getjsonfile("wrapper.properties") # the only data file that must be UTF-8 if self.config is None: self.log.error("I think you messed up the Json formatting of your " "wrapper.properties.json file. " "Take your file and have it checked at: \n" "http://jsonlint.com/") self.exit = True # detection and addition must be separated to prevent changing dictionary while iterating over it. # detect changes changesmade = False deprecated_entries = [] new_sections = [] new_entries = [] for section in CONFIG: if section not in self.config: self.log.debug("Adding section [%s] to configuration", section) new_sections.append(section) changesmade = True for configitem in CONFIG[section]: if section in self.config: # mark deprecated items for deletion if configitem in self.config[section]: if CONFIG[section][configitem] == "deprecated": self.log.debug("Deprecated item '%s' in section '%s'. - removing it from" " wrapper properties", configitem, section) deprecated_entries.append([section, configitem]) changesmade = True # mark new items for addition else: # handle new items in an existing section if CONFIG[section][configitem] != "deprecated": # avoid re-adding deprecated items self.log.debug("Item '%s' in section '%s' not in wrapper properties - adding it!", configitem, section) new_entries.append([section, configitem]) changesmade = True else: # handle new items in a (new) section self.log.debug("Item '%s' in new section '%s' not in wrapper properties - adding it!", configitem, section) if CONFIG[section][configitem] != "deprecated": new_entries.append([section, configitem]) changesmade = True # Apply changes and save. if changesmade: # add new section if len(new_sections) > 0: for added_section in new_sections: self.config[added_section] = {} # Removed deprecated entries if len(deprecated_entries) > 0: for removed in deprecated_entries: del self.config[removed[0]][removed[1]] # Add new entries if len(new_entries) > 0: for added in new_entries: self.config[added[0]][added[1]] = CONFIG[added[0]][added[1]] self.save() self.exit = True if self.exit: self.log.warning( "Updated wrapper.properties.json file - check and edit configuration if needed and start again.") sys.exit()
def save(self): putjsonfile(self.config, "wrapper.properties", sort=True)
def loadconfig(self): # load older versions of wrapper.properties to preserve prior settings. if os.path.exists("wrapper.properties"): with open("wrapper.properties", "r") as f: oldconfig = f.read() oldconfig = "Deprecated File! Use the 'wrapper.properties.json' instead!\n\n%s" % oldconfig with open("_wrapper.properties", "w") as f: f.write(oldconfig) os.remove("wrapper.properties") # Create new config if none exists if not os.path.exists("wrapper.properties.json"): putjsonfile(CONFIG, "wrapper.properties", sort=True) self.exit = True # Read existing configuration self.config = getjsonfile( "wrapper.properties") # the only data file that must be UTF-8 if self.config is None: self.log.error("I think you messed up the Json formatting of your " "wrapper.properties.json file. " "Take your file and have it checked at: \n" "http://jsonlint.com/") self.exit = True # detection and addition must be separated to prevent changing dictionary while iterating over it. # detect changes changesmade = False deprecated_entries = [] new_sections = [] new_entries = [] for section in CONFIG: if section not in self.config: self.log.debug("Adding section [%s] to configuration", section) new_sections.append(section) changesmade = True for configitem in CONFIG[section]: if section in self.config: # mark deprecated items for deletion if configitem in self.config[section]: if CONFIG[section][configitem] == "deprecated": self.log.debug( "Deprecated item '%s' in section '%s'. - removing it from" " wrapper properties", configitem, section) deprecated_entries.append([section, configitem]) changesmade = True # mark new items for addition else: # handle new items in an existing section if CONFIG[section][ configitem] != "deprecated": # avoid re-adding deprecated items self.log.debug( "Item '%s' in section '%s' not in wrapper properties - adding it!", configitem, section) new_entries.append([section, configitem]) changesmade = True else: # handle new items in a (new) section self.log.debug( "Item '%s' in new section '%s' not in wrapper properties - adding it!", configitem, section) if CONFIG[section][configitem] != "deprecated": new_entries.append([section, configitem]) changesmade = True # Apply changes and save. if changesmade: # add new section if len(new_sections) > 0: for added_section in new_sections: self.config[added_section] = {} # Removed deprecated entries if len(deprecated_entries) > 0: for removed in deprecated_entries: del self.config[removed[0]][removed[1]] # Add new entries if len(new_entries) > 0: for added in new_entries: self.config[added[0]][added[1]] = CONFIG[added[0]][ added[1]] self.save() self.exit = True if self.exit: self.log.warning( "Updated wrapper.properties.json file - check and edit configuration if needed and start again." ) sys.exit()
def __init__(self, apply_pre1_11=False): self.entitylist = ENTITIES if apply_pre1_11: self.apply_pre1_11() # provide a readout file for the user's reference. putjsonfile(self.entitylist, "entities", "./wrapper-data/json/")
def save(self): putjsonfile(self.config, "wrapper.properties", sort=True)
def command_op(self, player, payload): # if player is None: This is a security vulnerability. console is # already set to an xplayer # player = self.wrapper.xplayer if not self._superop(player, 9): return False # get argument flags flags = [x.lower() for x in payload["args"]] superop = "-s" in flags op_level = "-l" in flags offline_mode = "-o" in flags new_operator_name = getargs(payload["args"], 0) valid_uuid = self.wrapper.uuids.getuuidbyusername(new_operator_name) if not offline_mode and valid_uuid is None: player.message( "&c'%s' is not a valid player name!" % new_operator_name) return False if offline_mode: name = new_operator_name uuid = str(self.wrapper.uuids.getuuidfromname(name)) else: uuid = str(valid_uuid) name = self.wrapper.uuids.getusernamebyuuid(uuid) superlevel = 4 # default if op_level: for index, x in enumerate(flags): if x == "-l": break # noinspection PyUnboundLocalVariable arg_level = get_int(getargs(flags, index + 1)) superlevel = max(1, arg_level) if superop and superlevel > 4: superlevel = max(5, superlevel) # 2 = make sure server STARTED if self.wrapper.servervitals.state == 2: self.wrapper.javaserver.console("op %s" % name) # if not, wrapper makes ops.json edits else: self.wrapper.javaserver.refresh_ops(read_super_ops=False) oplist = self.wrapper.servervitals.operator_list newop_item = { "uuid": uuid, "name": name, "level": min(4, superlevel), "bypassesPlayerLimit": False } if oplist: for op, ops in enumerate(oplist): # We don't expect it is already there, but if so... if uuid == ops["uuid"]: oplist.pop(op) oplist.append(newop_item) else: oplist = [newop_item, ] result = putjsonfile(oplist, "ops") if result: player.message("&6Ops.json file saved ok.") else: player.message("&cSomething went wrong writing ops.json.") # update the superops.txt file if superop: set_item(name, superlevel, "superops.txt") player.message("&6Updated as SuperOP.") time.sleep(.5) self.wrapper.javaserver.refresh_ops()
def __init__(self, apply_pre1_11=False): self.entitylist = ENTITIES if apply_pre1_11: self.apply_pre1_11() # provide a readout file for the user's reference. putjsonfile(self.entitylist, "entities", "./wrapper-data/json/")