def __init__(self, wrapper): self.wrapper = wrapper self.api = API(wrapper, "Web", internal=True) self.log = logging.getLogger('Web') self.config = wrapper.config self.serverpath = self.config["General"]["server-directory"] self.socket = False self.data = Storage("web") if "keys" not in self.data.Data: self.data.Data["keys"] = [] # if not self.config["Web"]["web-password"] == None: # self.log.info("Changing web-mode password because web-password was changed in wrapper.properties") # ***** change code to hashlib if this gets uncommented # self.data.Data["password"] = md5.md5(self.config["Web"]["web-password"]).hexdigest() # self.config["Web"]["web-password"] = None # self.wrapper.configManager.save() self.api.registerEvent("server.consoleMessage", self.onServerConsole) self.api.registerEvent("player.message", self.onPlayerMessage) self.api.registerEvent("player.login", self.onPlayerJoin) self.api.registerEvent("player.logout", self.onPlayerLeave) self.api.registerEvent("irc.message", self.onChannelMessage) self.consoleScrollback = [] self.chatScrollback = [] self.memoryGraph = [] self.loginAttempts = 0 self.lastAttempt = 0 self.disableLogins = 0
def __init__(self, wrapper): self.wrapper = wrapper self.config = wrapper.config # Remember if you need to save use 'wrapper.configManager.save()' not config.save self.log = logging.getLogger('Web') self.check_password = self.wrapper.cipher.check_pw() if not Flask: self.config["Web"]["web-enabled"] = False self.wrapper.configManager.save() self.log.critical( "You don't have the 'flask/flask_socketio' dashboard dependencies installed " "on your system. You can now restart, but Web mode is disabled." ) self.wrapper.haltsig.halt = True self.app = Flask(__name__) self.app.config['SECRET_KEY'] = "".join( [chr(random.randrange(48, 90)) for i in range(32)]) # LOL self.socketio = SocketIO(self.app) # Flask filters def strftime(f): return datetime.datetime.fromtimestamp( int(f)).strftime('%Y-%m-%d @ %I:%M%p') self.app.jinja_env.filters["strftime"] = strftime # Register handlers self.add_decorators() self.data_storage = Storage("dash") if "keys" not in self.data_storage.Data: self.data_storage.Data["keys"] = [] self.loginAttempts = 0 self.last_attempt = 0 self.disableLogins = 0 # Start thread for running server t = threading.Thread(target=self.run, args=()) t.daemon = True t.start()
def __init__(self, wrapper): self.wrapper = wrapper self.api = wrapper.api self.log = logging.getLogger('Web') self.config = wrapper.config self.serverpath = self.config["General"]["server-directory"] self.pass_handler = self.wrapper.cipher self.socket = False self.storage = Storage("web", pickle=False) self.data = self.storage.Data self.xplayer = ConsolePlayer(self.wrapper, self.console_output) self.adminname = "Web Admin" self.xplayer.username = self.adminname self.onlyusesafe_ips = self.config["Web"]["safe-ips-use"] self.safe_ips = self.config["Web"]["safe-ips"] if "keys" not in self.data: self.data["keys"] = [] # Register events self.api.registerEvent("server.consoleMessage", self.on_server_console) self.api.registerEvent("player.message", self.on_player_message) self.api.registerEvent("player.login", self.on_player_join) self.api.registerEvent("player.logout", self.on_player_leave) self.api.registerEvent("irc.message", self.on_channel_message) self.consoleScrollback = [] self.chatScrollback = [] self.memoryGraph = [] self.loginAttempts = 0 self.lastAttempt = 0 self.disableLogins = 0 self.props = "" self.propsCount = 0
def __init__(self, wrapper): self.wrapper = wrapper self.api = API(wrapper, "Web", internal=True) self.log = logging.getLogger('Web') self.config = wrapper.config self.serverpath = self.config["General"]["server-directory"] self.socket = False self.data = Storage("web") self.pass_handler = self.wrapper.cipher if "keys" not in self.data.Data: self.data.Data["keys"] = [] self.api.registerEvent("server.consoleMessage", self.onServerConsole) self.api.registerEvent("player.message", self.onPlayerMessage) self.api.registerEvent("player.login", self.onPlayerJoin) self.api.registerEvent("player.logout", self.onPlayerLeave) self.api.registerEvent("irc.message", self.onChannelMessage) self.consoleScrollback = [] self.chatScrollback = [] self.memoryGraph = [] self.loginAttempts = 0 self.lastAttempt = 0 self.disableLogins = 0
def __init__(self, username, wrapper): self.wrapper = wrapper self.javaserver = wrapper.javaserver self.log = wrapper.log self.username = username self.loggedIn = time.time() # TODO - clean this out. let player objects GC with their client? # mcserver will set this to false later to close the thread. self.abort = False # meanwhile, it still needs to respect wrapper halts self.wrapper_signal = self.wrapper.halt # these are all MCUUID objects.. I have separated out various # uses of uuid to clarify for later refractoring # --------------- # Mojang uuid - the bought and paid Mojand UUID. Never # changes- our one constant point of reference per player. # offline uuid - created as a MD5 hash of "OfflinePlayer:%s" % username # client uuid - what the client stores as the uuid (should be # the same as Mojang?) The player.uuid used by old api (and # internally here). # server uuid = the local server uuid... used to reference # the player on the local server. Could be same as Mojang UUID # if server is in online mode or same as offline if server is # in offline mode (proxy mode). # ******************* # This can be False if cache (and requests) Fail... bad name or # bad Mojang service connection. self.mojangUuid = self.wrapper.uuids.getuuidbyusername(username) # IF False error carries forward, this is not a valid player, # for whatever reason... self.clientUuid = self.mojangUuid # These two are offline by default. self.offlineUuid = self.wrapper.uuids.getuuidfromname(self.username) # Start out as the Offline - # change it to Mojang if local server is Online self.serverUuid = self.offlineUuid self.ipaddress = "127.0.0.0" self.loginposition = [0, 0, 0] self._position = [0, 0, 0, 0, 0] # internally used for non-proxy mode self.client = None self.clientgameversion = self.wrapper.servervitals.protocolVersion self.clientboundPackets = Packets_cb(self.clientgameversion) self.serverboundPackets = Packets_sb(self.clientgameversion) self.playereid = None # some player properties associated with abilities # # default is 1. Should normally be congruent with speed. self.field_of_view = float(1) # Client set godmode is 0x01 self.godmode = 0x00 # Client set creative is 0x08 self.creative = 0x00 # default is 1 self.fly_speed = float(1) if self.wrapper.proxy: gotclient = False for client in self.wrapper.servervitals.clients: if client.username == self.username: self.client = client # Both MCUUID objects self.clientUuid = client.uuid self.serverUuid = client.serveruuid self.ipaddress = client.ip # pktSB already set to self.wrapper.servervitals.protocolVersion self.clientboundPackets = self.client.pktCB self.clientgameversion = self.client.clientversion gotclient = True break if not gotclient: self.log.error("Proxy is on, but this client is not " "listed in wrapper.proxy.clients!") self.log.error("The usual cause of this would be that" " someone is connecting directly to" " your server port and not the wrapper" " proxy port!") # Process login data self.data = Storage(self.clientUuid.string, root="wrapper-data/players") if "firstLoggedIn" not in self.data.Data: self.data.Data["firstLoggedIn"] = (time.time(), time.tzname) if "logins" not in self.data.Data: self.data.Data["logins"] = {} self.data.Data["lastLoggedIn"] = (self.loggedIn, time.tzname) self.data.save() # start player logged in time tracking thread t = threading.Thread(target=self._track, args=()) t.daemon = True t.start()
def __init__(self, secret_passphrase): # setup log and config # needs a false setting on first in case config does not # load (like after changes). self.storage = False self.log = logging.getLogger('Wrapper.py') self.configManager = Config() self.configManager.loadconfig() self.config = self.configManager.config # Read Config items # hard coded cursor for non-readline mode self.cursor = ">" # This was to allow alternate encodings self.encoding = self.config["General"]["encoding"] self.serverpath = self.config["General"]["server-directory"] self.proxymode = self.config["Proxy"]["proxy-enabled"] self.wrapper_onlinemode = self.config["Proxy"]["online-mode"] self.halt_message = self.config["Misc"]["halt-message"] # encryption items (for passwords and sensitive user data) # salt is generated and stored in wrapper.properties.json config_changes = False salt = self.config["General"]["salt"] if not salt: salt = gensalt(self.encoding) self.config["General"]["salt"] = salt config_changes = True # passphrase is provided at startup by the wrapper operator or script (not stored) passphrase = phrase_to_url_safebytes(secret_passphrase, self.encoding, salt) self.cipher = Crypt(passphrase, self.encoding) # Update passwords (hash any plaintext passwords) for groups in self.config: for cfg_items in self.config[groups]: if cfg_items[-10:] == "-plaintext": # i.e., cfg_items ===> like ["web-password-plaintext"] hash_item = cfg_items[:-10] # hash_item ===> i.e., ["web-password"] if hash_item in self.config[groups] and self.config[ groups][cfg_items]: # encrypt contents of (i.e.) ["web-password-plaintext"] hashed_item = self.cipher.encrypt( self.config[groups][cfg_items]) # store in "" ["Web"]["web-password"] self.config[groups][hash_item] = hashed_item # set plaintext item to false (successful digest) self.config[groups][cfg_items] = False config_changes = True # Patch any old update paths "..wrapper/development/build/version.json" # new paths are: "..wrapper/development" for entries in self.config["Updates"]: if "/build/version.json" in str(self.config["Updates"][entries]): oldentry = copy.copy(self.config["Updates"][entries]) self.config["Updates"][entries] = oldentry.split( "/build/version.json")[0] config_changes = True # save changes made to config file if config_changes: self.configManager.save() # reload branch update info. self.auto_update_wrapper = self.config["Updates"][ "auto-update-wrapper"] self.auto_update_branch = self.config["Updates"]["auto-update-branch"] if not self.auto_update_branch: self.update_url = "https://raw.githubusercontent.com/benbaptist/minecraft-wrapper/development" else: self.update_url = self.config["Updates"][self.auto_update_branch] self.use_timer_tick_event = self.config["Gameplay"][ "use-timer-tick-event"] self.use_readline = not (self.config["Misc"]["use-betterconsole"]) # Storages self.wrapper_storage = Storage("wrapper", encoding=self.encoding) self.wrapper_permissions = Storage("permissions", encoding=self.encoding, pickle=False) self.wrapper_usercache = Storage("usercache", encoding=self.encoding, pickle=False) # storage Data objects self.storage = self.wrapper_storage.Data self.usercache = self.wrapper_usercache.Data # self.wrapper_permissions accessed only by permissions module # core functions and datasets self.perms = Permissions(self) self.uuids = UUIDS(self.log, self.usercache) self.plugins = Plugins(self) self.commands = Commands(self) self.events = Events(self) self.players = {} self.registered_permissions = {} self.help = {} self.input_buff = "" self.sig_int = False self.command_hist = ['/help', 'help'] self.command_index = 1 # init items that are set up later (or opted out of/ not set up.) self.javaserver = None self.api = None self.irc = None self.scripts = None self.web = None self.proxy = None self.backups = None # HaltSig - Why? ... because if self.halt was just `False`, passing # a self.halt would simply be passing `False` (immutable). Changing # the value of self.halt would not necessarily change the value of the # passed parameter (unless it was specifically referenced back as # `wrapper.halt`). Since the halt signal needs to be passed, possibly # several layers deep, and into modules that it may be desireable to # not have direct access to wrapper, using a HaltSig object is # more desireable and reliable in behavior. self.halt = HaltSig() self.updated = False # future plan to expose this to api self.xplayer = ConsolePlayer(self) # Error messages for non-standard import failures. if not readline and self.use_readline: self.log.warning( "'readline' not imported. This is needed for proper" " console functioning. Press <Enter> to acknowledge...") sys.stdin.readline() # requests is just being used in too many places to try # and track its usages piece-meal. if not requests: self.log.error( "You must have the requests module installed to use wrapper!" " console functioning. Press <Enter> to Exit...") sys.stdin.readline() self._halt() # create server/proxy vitals and config objects self.servervitals = ServerVitals(self.players) # LETS TAKE A SECOND TO DISCUSS PLAYER OBJECTS: # The ServerVitals class gets passed the player object list now, but # player objects are now housed in wrapper. This is how we are # passing information between proxy and wrapper. self.servervitals.serverpath = self.config["General"][ "server-directory"] self.servervitals.state = OFF self.servervitals.command_prefix = self.config["Misc"][ "command-prefix"] self.proxyconfig = ProxyConfig() self.proxyconfig.proxy = self.config["Proxy"] self.proxyconfig.entity = self.config["Entities"]
def getStorage(self, name, world=False, formatting="pickle"): """ Returns a storage object manager. The manager contains the storage object, 'Data' (a dictionary). 'Data' contains the data your plugin will remember across reboots. :NOTE: This method is somewhat different from previous Wrapper versions prior to 0.10.1 (build 182). The storage object is no longer a data object itself; It is a manager used for controlling the saving of the object data. The actual data is contained in Dictionary subitem 'Data' ___ :Args: :name: The name of the storage (on disk). :world: :False: set the storage's location to '/wrapper-data/plugins'. :True: set the storage path to '<serverpath>/<worldname>/plugins'. :formatting="pickle": Pickle formatting is the default. pickling is less strict than json formats and leverages binary storage. Use of json (or future implemented formats) can result in errors if your keys or data do not conform to json standards (like use of string keys). However, pickle is not generally human-readable, whereas json is human readable. If you need a human-readable copy (for debugging), consider using self.api.helpers.putjsonfile(<yourDictionary>) to write a copy to disk in Json. if you do so, check the return status of `putjsonfile` to make sure it was written. ___ :sample methods: The new method: .. code:: python # to start a storage: self.homes = self.api.getStorage("homes", True) # access the data: for player in self.homes.Data: # note upper case `D` print("player %s has a home at: %s" % ( player, self.homes.Data[player])) # to save (storages also do periodic saves every minute): self.homes.save() # to close (and save): def onDisable(self): self.homes.close() .. the key difference is here (under the old Storage API): .. code:: python # This used to work under the former API # however, this will produce an exception # because "self.homes" is no longer an # iterable data set: for player in self.homes: <= Exception! print("player %s has a home at: %s" % ( player, self.homes[player])) .. **tip** *to make the transition easier for existing code, redefine your the storage statements above like this to re-write as few lines as possible (and avoid problems with other plugins that might link to your plugin's data)*: .. code:: python # change your storage setup from: self.homes = self.api.getStorage("homes", True) # to: self.homestorage = self.api.getStorage("homes", True) self.homes = homestorage.Data # Now the only other change you need to make is to any # .save() or .close() statements: def onDisable(self): # self.homes.close() # change to - self.homestorage.close() .. """ pickle = False if formatting == "pickle": pickle = True if world: return Storage( name, root="%s/%s/plugins/%s" % (self.serverpath, self.minecraft.getWorldName(), self.id), pickle=pickle) else: return Storage(name, root="wrapper-data/plugins/%s" % self.id, pickle=pickle)
def _update_db(index, term, docid): if _db.get(term, False): if _db[term].get(docid, False): _db[term][docid].update([index]) else: _db[term][docid] = set([index]) else: _db[term][docid] = set([index]) if __name__ == '__main__': processing = Preprocessing() print('Hurray !!! Program Started') data = Doc()._registerInstances()._getInstance('XML').parse('data.xml') glData = Storage()._transformData(data)._get_transformed_version() glData['tokens'] = glData['TEXT'].apply( lambda row: processing._action(row)) print 'tokens', glData['tokens'] result = zip(glData['DOCID'], glData['tokens']) print 'result', result for docid, etW in result: map(lambda term: _update_db(term[0], term[1], docid), list(enumerate(etW))) p_in_idx = Storage()._set_data_positional_data_frame( _db.keys(), _db.values())._get_positional_data_frame()
def getStorage(self, name, world=False, pickle=True): """ Returns a storage object manager for saving data between reboots. :Args: :name: The name of the storage (on disk). :world: THe location of the storage on disk - :False: '/wrapper-data/plugins'. :True: '<serverpath>/<worldname>/plugins'. :Pickle: Whether wrapper should pickle or save as json. Pickle formatting is the default. pickling is less strict than json formats and leverages binary storage. Use of json can result in errors if your keys or data do not conform to json standards (like use of string keys). However, pickle is not generally human-readable, whereas json is human readable. :Returns: A storage object manager. The manager contains a storage dictionary called 'Data'. 'Data' contains the data your plugin will remember across reboots. ___ :NOTE: This method is somewhat different from previous Wrapper versions prior to 0.10.1 (build 182). The storage object is no longer a data object itself; It is a manager used for controlling the saving of the object data. The actual data is contained in the property/dictionary variable 'Data' ___ :sample methods: The new method: .. code:: python # to start a storage: self.homes = self.api.getStorage("homes", True) # access the data: for player in self.homes.Data: # note upper case `D` print("player %s has a home at: %s" % ( player, self.homes.Data[player])) # to save (storages also do periodic saves every minute): self.homes.save() # to close (and save): def onDisable(self): self.homes.close() # to load a storage from disk: self.homes.load() .. the key difference is here (under the old Storage API): .. code:: python # This used to work under the former API # however, this will produce an exception # because "self.homes" is no longer an # iterable data set: for player in self.homes: <= Exception! print("player %s has a home at: %s" % ( player, self.homes[player])) .. **tip** *to make the transition easier for existing code, redefine your the storage statements above like this to re-write as few lines as possible (and avoid problems with other plugins that might link to your plugin's data)*: .. code:: python # change your storage setup from: self.homes = self.api.getStorage("homes", True) # to: self.homestorage = self.api.getStorage("homes", True) self.homes = homestorage.Data # Now the only other change you need to make is to any # .save() or .close() statements: def onDisable(self): # self.homes.close() # change to - self.homestorage.close() .. """ if world: return Storage( name, root="%s/%s/plugins/%s" % (self.serverpath, self.minecraft.getWorldName(), self.id), pickle=pickle) else: return Storage(name, root="wrapper-data/plugins/%s" % self.id, pickle=pickle)
def __init__(self, username, wrapper): """ :UUIDS: All uuids are wrapper's MCUUID objects. If being used in a string context, they must be used with the *.string property (or str() explicitly): player.mojangUuid.string player.mojangUuis.__str__ str(player.mojangUuid) The only exception to this is the `uuid` property, which is always a string. :uuid (property, string): This will pull the best uuid available in this order- :1) mojangUuid: The bought and paid Mojand UUID. Never changes and is the prefered way to ID player keys. :2) offlineUuid: A MD5 hash of "OfflinePlayer:%s" % username :3) clientUuid: What the client believes is the uuid. If Wrapper is online, this should be the same as mojangUuid. :4) serverUuid: The player's local uuid on the server, usually the same as offline uuid. :param username: :param wrapper: """ self.wrapper = wrapper self.javaserver = wrapper.javaserver self.log = wrapper.log self.username = username self.loggedIn = time.time() # mcserver will set this to false later to close the thread. self.abort = False self.data = None # meanwhile, it still needs to respect wrapper halts self.wrapper_signal = self.wrapper.haltsig self.kick_nonproxy_connects = self.wrapper.config["Proxy"][ "disconnect-nonproxy-connections"] self.mojangUuid = False self.clientUuid = False # These two are offline by default. self.offlineUuid = self.wrapper.uuids.getuuidfromname(self.username) self.serverUuid = self.offlineUuid self.ipaddress = "127.0.0.0" self.loginposition = [0, 0, 0] self._position = [0, 0, 0, 0, 0] # internally used for non-proxy mode self.client = None self.clientgameversion = self.wrapper.javaserver.protocolVersion self.cbpkt = Packets_cb(self.clientgameversion) self.sbpkt = Packets_sb(self.clientgameversion) self.playereid = None # some player properties associated with abilities # # default is 1. Should normally be congruent with speed. self.field_of_view = float(1) # Client set godmode is 0x01 self.godmode = 0x00 # Client set creative is 0x08 self.creative = 0x00 # default is 1 self.fly_speed = float(1) if self.wrapper.proxy: gotclient = False for client in self.wrapper.proxy.clients: if client.username == self.username: self.client = client self.clientUuid = client.wrapper_uuid self.serverUuid = client.local_uuid self.mojangUuid = client.mojanguuid self.ipaddress = client.ip # pktSB already set to self.wrapper.javaserver.protocolVersion # noqa self.clientboundPackets = self.client.pktCB self.clientgameversion = self.client.clientversion gotclient = True break if not gotclient: pprint.pprint(self.wrapper.proxy.clients) self.log.error("Proxy is on, but this client is not " "listed in proxy.clients!") self.log.error("The usual cause of this would be that" " someone attempted to connect directly to" " your server port and not the wrapper" " proxy port, but can also be the result of" " a player that has abruptly disconnected.") if self.kick_nonproxy_connects: port = self.wrapper.proxy.proxy_port self.log.info("API.player Kicked %s" % self.name) self.abort = True self.wrapper.javaserver.console( "kick %s %s" % ( self.name, "Access Denied! Use port %s instead!" % port ) ) return if not self.mojangUuid: # poll cache/mojang for proper uuid self.mojangUuid = self.wrapper.uuids.getuuidbyusername(username) # Process login data self.data = Storage( self.mojangUuid.string, root="wrapper-data/players") if "firstLoggedIn" not in self.data.Data: self.data.Data["firstLoggedIn"] = (time.time(), time.tzname) if "logins" not in self.data.Data: self.data.Data["logins"] = {} self.data.Data["lastLoggedIn"] = (self.loggedIn, time.tzname) self.data.save() # start player logged in time tracking thread t = threading.Thread(target=self._track, args=()) t.daemon = True t.start()
def __init__(self): # setup log and config # needs a false setting on first in case config does not # load (like after changes). self.storage = False self.log = logging.getLogger('Wrapper.py') self.configManager = Config() self.configManager.loadconfig() # set up config self.config = self.configManager.config # Read Config items # hard coded cursor for non-readline mode self.cursor = ">" self.wrapper_ban_system = False # This was to allow alternate encodings self.encoding = self.config["General"]["encoding"] self.proxymode = self.config["Proxy"]["proxy-enabled"] self.wrapper_onlinemode = self.config["Proxy"]["online-mode"] self.wrapper_ban_system = self.proxymode and self.wrapper_ban_system self.auto_update_wrapper = self.config["Updates"][ "auto-update-wrapper"] self.auto_update_branch = self.config["Updates"]["auto-update-branch"] self.use_timer_tick_event = self.config["Gameplay"][ "use-timer-tick-event"] self.command_prefix = self.config["Misc"]["command-prefix"] self.use_readline = self.config["Misc"]["use-readline"] # Storages self.wrapper_storage = Storage("wrapper", encoding=self.encoding) self.wrapper_permissions = Storage("permissions", encoding=self.encoding, pickle=False) self.wrapper_usercache = Storage("usercache", encoding=self.encoding, pickle=False) # storage Data objects self.storage = self.wrapper_storage.Data self.permissions = self.wrapper_permissions.Data self.usercache = self.wrapper_usercache.Data # core functions and datasets self.perms = Permissions(self) self.uuids = UUIDS(self) self.plugins = Plugins(self) self.commands = Commands(self) self.events = Events(self) self.registered_permissions = {} self.help = {} self.input_buff = "" self.sig_int = False self.command_hist = ['/help', 'help'] self.command_index = 1 # init items that are set up later (or opted out of/ not set up.) self.javaserver = None self.api = None self.irc = None self.scripts = None self.web = None self.proxy = None self.backups = None self.halt = False self.updated = False # future plan to expose this to api self.xplayer = ConsolePlayer(self) # define the slot once here and not at each clients Instantiation: self.inv_slots = range(46) # Error messages for non-standard import failures. if not readline and self.use_readline: self.log.warning( "'readline' not imported. This is needed for proper" " console functioning. Press <Enter> to acknowledge...") sys.stdin.readline() # requests is just being used in too many places to try # and track its usages piece-meal. if not requests: self.log.error( "You must have the requests module installed to use wrapper!" " console functioning. Press <Enter> to Exit...") sys.stdin.readline() self._halt()