def load(cls, directory: str, definitions: str) -> World:
        wrapper = cls(directory, definitions)
        fp = open(path.join(directory, "level.dat"), "rb")
        root_tag = nbt.NBTFile(fileobj=fp)
        fp.close()

        return World(directory, root_tag, wrapper)
Exemple #2
0
    def readconsole(self, buff):
        """Internally-used function that parses a particular
        console line.
        """
        if not self.wrapper.events.callevent(
                "server.consoleMessage", {"message": buff}):
            return False

        if len(buff) < 1:
            return
        # Standardize the line to only include the text (removing
        # time and log pre-pends)
        line_words = buff.split(' ')[self.prepends_offset:]

        # find the actual offset is where server output line
        # starts (minus date/time and info stamps).
        # .. and load the proper ops file
        if "Starting minecraft server version" in buff and \
                self.prepends_offset == 0:

            for place in range(len(line_words)-1):
                self.prepends_offset = place
                if line_words[place] == "Starting":
                    break

            line_words = buff.split(' ')[self.prepends_offset:]
            self.version = getargs(line_words, 4)
            semantics = self.version.split(".")
            release = get_int(getargs(semantics, 0))
            major = get_int(getargs(semantics, 1))
            minor = get_int(getargs(semantics, 2))
            self.version_compute = minor + (major * 100) + (release * 10000)

            # 1.7.6 (protocol 5) is the cutoff where ops.txt became ops.json
            if self.version_compute > 10705 and self.protocolVersion < 0:
                self.protocolVersion = 5
            self.refresh_ops()

        if len(line_words) < 1:
            return

        # the server attempted to print a blank line
        if len(line_words[0]) < 1:
            print('')
            return

        # parse or modify the server output section
        #
        #

        # Over-ride OP help console display
        if "/op <player>" in buff:
            new_usage = "player> [-s SUPER-OP] [-o OFFLINE] [-l <level>]"
            message = buff.replace("player>", new_usage)
            buff = message

        if "While this makes the game possible to play" in buff:
            prefix = " ".join(buff.split(' ')[:self.prepends_offset])

            if not self.wrapper.wrapper_onlinemode:
                message = (
                    "%s Since you are running Wrapper in OFFLINE mode, THIS "
                    "COULD BE SERIOUS!\n%s Wrapper is not handling any"
                    " authenication.\n%s This is only ok if this wrapper "
                    "is not accessible from either port %s or port %s"
                    " (I.e., this wrapper is a multiworld for a hub server, or"
                    " you are doing your own authorization via a plugin)." % (
                        prefix, prefix, prefix,
                        self.server_port, self.wrapper.proxy.proxy_port))
            else:
                message = (
                    "%s Since you are running Wrapper in proxy mode, this"
                    " should be ok because Wrapper is handling the"
                    " authenication, PROVIDED no one can access port"
                    " %s from outside your network." % (
                        prefix, self.server_port))

            if self.wrapper.proxymode:
                buff = message

        # check for server console spam before printing to wrapper console
        server_spaming = False
        for things in self.spammy_stuff:
            if things in buff:
                server_spaming = True

        # server_spaming setting does not stop it from being parsed below.
        if not server_spaming:
            if not self.server_muted:
                self.wrapper.write_stdout(buff, "server")
            else:
                self.queued_lines.append(buff)

        # region server console parsing section

        # read port of server
        if "Starting Minecraft server" in buff:
            self.server_port = get_int(buff.split('on *:')[1])

        # confirm server start
        elif "Done (" in buff:
            self._toggle_server_started()
            self.changestate(STARTED)
            self.log.info("Server started")
            self.bootTime = time.time()

        # Getting world name
        elif "Preparing level" in buff:
            self.worldname = getargs(line_words, 2).replace('"', "")
            self.world = World(self.worldname, self)
            if self.wrapper.proxymode:
                self.entity_control = EntityControl(self)
        # Player Message
        if getargs(line_words, 0)[0] == "<":
            name = self.stripspecial(getargs(line_words, 0)[1:-1])
            message = self.stripspecial(getargsafter(line_words, 1))
            original = getargsafter(line_words, 0)
            self.wrapper.events.callevent("player.message", {
                "player": self.getplayer(name),
                "message": message,
                "original": original
            })

        # Player Login
        elif getargs(line_words, 1) == "logged":
            name = self.stripspecial(
                getargs(line_words, 0)[0:getargs(line_words, 0).find("[")])
            eid = get_int(getargs(line_words, 6))
            locationtext = getargs(buff.split(" ("), 1)[:-1].split(", ")
            locationtext[0] = locationtext[0].replace("[world]", "")
            location = get_int(
                float(locationtext[0])), get_int(
                float(locationtext[1])), get_int(
                float(locationtext[2]))
            self.login(name, eid, location)

        # Player Logout
        elif "lost connection" in buff:
            name = getargs(line_words, 0)
            self.logout(name)

        # player action
        elif getargs(line_words, 0) == "*":
            name = self.stripspecial(getargs(line_words, 1))
            message = self.stripspecial(getargsafter(line_words, 2))
            self.wrapper.events.callevent("player.action", {
                "player": self.getplayer(name),
                "action": message
            })

        # Player Achievement
        elif "has just earned the achievement" in buff:
            name = self.stripspecial(getargs(line_words, 0))
            achievement = getargsafter(line_words, 6)
            self.wrapper.events.callevent("player.achievement", {
                "player": name,
                "achievement": achievement
            })

        # /say command
        elif getargs(
                line_words, 0)[0] == "[" and getargs(line_words, 0)[-1] == "]":
            if self.getservertype != "vanilla":
                # Unfortunately, Spigot and Bukkit output things
                # that conflict with this.
                return
            name = self.stripspecial(getargs(line_words, 0)[1:-1])
            message = self.stripspecial(getargsafter(line_words, 1))
            original = getargsafter(line_words, 0)
            self.wrapper.events.callevent("server.say", {
                "player": name,
                "message": message,
                "original": original
            })

        # Player Death
        elif getargs(line_words, 1) in self.deathprefixes:
            name = self.stripspecial(getargs(line_words, 0))
            self.wrapper.events.callevent("player.death", {
                "player": self.getplayer(name),
                "death": getargsafter(line_words, 1)
            })

        # server lagged
        elif "Can't keep up!" in buff:
            skipping_ticks = getargs(line_words, 17)
            self.wrapper.events.callevent("server.lagged", {
                "ticks": get_int(skipping_ticks)
            })
    def readConsole(self, line):
        """ Internally-use function that parses a particular console line """
        def args(i):
            try:
                return line.split(" ")[i]
            except:
                return ""

        def argsAfter(i):
            try:
                return " ".join(line.split(" ")[i:])
            except:
                return ""

        if not self.wrapper.callEvent("server.consoleMessage",
                                      {"message": line}):
            return False
        print line
        deathPrefixes = [
            "fell", "was", "drowned", "blew", "walked", "went", "burned",
            "hit", "tried", "died", "got", "starved", "suffocated", "withered"
        ]
        if not self.config["General"]["pre-1.7-mode"]:
            if len(args(3)) < 1: return
            if args(
                    3
            ) == "Done":  # Confirmation that the server finished booting
                self.changeState(2)
                self.log.info("Server started")
                self.bootTime = time.time()
            elif args(3) == "Preparing" and args(
                    4) == "level":  # Getting world name
                self.worldName = args(5).replace('"', "")
                self.world = World(self.worldName, self)
            elif args(3)[0] == "<":  # Player Message
                name = self.stripSpecial(args(3)[1:-1])
                message = self.stripSpecial(argsAfter(4))
                original = argsAfter(3)
                self.wrapper.callEvent(
                    "player.message", {
                        "player": self.getPlayer(name),
                        "message": message,
                        "original": original
                    })
            elif args(4) == "logged":  # Player Login
                name = self.stripSpecial(args(3)[0:args(3).find("[")])
                self.login(name)
            elif args(4) == "lost":  # Player Logout
                name = args(3)
                self.logout(name)
            elif args(3) == "*":
                name = self.stripSpecial(args(4))
                message = self.stripSpecial(argsAfter(5))
                self.wrapper.callEvent("player.action", {
                    "player": self.getPlayer(name),
                    "action": message
                })
            elif args(3)[0] == "[" and args(3)[-1] == "]":  # /say command
                name = self.stripSpecial(args(3)[1:-1])
                message = self.stripSpecial(argsAfter(4))
                original = argsAfter(3)
                self.wrapper.callEvent("server.say", {
                    "player": name,
                    "message": message,
                    "original": original
                })
            elif args(4) == "has" and args(
                    8) == "achievement":  # Player Achievement
                name = self.stripSpecial(args(3))
                achievement = argsAfter(9)
                self.wrapper.callEvent("player.achievement", {
                    "player": name,
                    "achievement": achievement
                })
            elif args(4) in deathPrefixes:  # Player Death
                name = self.stripSpecial(args(3))
                self.wrapper.callEvent("player.death", {
                    "player": self.getPlayer(name),
                    "death": argsAfter(4)
                })
        else:
            if len(args(3)) < 1: return
            if args(
                    3
            ) == "Done":  # Confirmation that the server finished booting
                self.changeState(2)
                self.log.info("Server started")
                self.bootTime = time.time()
            elif args(3) == "Preparing" and args(
                    4) == "level":  # Getting world name
                self.worldName = args(5).replace('"', "")
                self.world = World(self.worldName)
            elif args(3)[0] == "<":  # Player Message
                name = self.stripSpecial(args(3)[1:-1])
                message = self.stripSpecial(argsAfter(4))
                original = argsAfter(3)
                self.wrapper.callEvent(
                    "player.message", {
                        "player": self.getPlayer(name),
                        "message": message,
                        "original": original
                    })
            elif args(4) == "logged":  # Player Login
                name = self.stripSpecial(args(3)[0:args(3).find("[")])
                self.login(name)
            elif args(4) == "lost":  # Player Logout
                name = args(3)
                self.logout(name)
            elif args(3) == "*":
                name = self.stripSpecial(args(4))
                message = self.stripSpecial(argsAfter(5))
                self.wrapper.callEvent("player.action", {
                    "player": self.getPlayer(name),
                    "action": message
                })
            elif args(3)[0] == "[" and args(3)[-1] == "]":  # /say command
                name = self.stripSpecial(args(3)[1:-1])
                message = self.stripSpecial(argsAfter(4))
                original = argsAfter(3)
                if name == "Server": return
                self.wrapper.callEvent("server.say", {
                    "player": name,
                    "message": message,
                    "original": original
                })
            elif args(4) == "has" and args(
                    8) == "achievement":  # Player Achievement
                name = self.stripSpecial(args(3))
                achievement = argsAfter(9)
                self.wrapper.callEvent("player.achievement", {
                    "player": name,
                    "achievement": achievement
                })
            elif args(4) in deathPrefixes:  # Player Death
                name = self.stripSpecial(args(3))
                deathMessage = self.config["Death"]["death-kick-messages"][
                    random.randrange(
                        0, len(self.config["Death"]["death-kick-messages"]))]
                if self.config["Death"][
                        "kick-on-death"] and name in self.config["Death"][
                            "users-to-kick"]:
                    self.console("kick %s %s" % (name, deathMessage))
                self.wrapper.callEvent("player.death", {
                    "player": self.getPlayer(name),
                    "death": argsAfter(4)
                })
Exemple #4
0
    def readconsole(self, buff):
        """Internally-used function that parses a particular
        console line.
        """

        if len(buff) < 1:
            return
        # Standardize the line to only include the text (removing
        # time and log pre-pends)
        line_words = buff.split(' ')[self.prepends_offset:]

        # find the actual offset is where server output line
        # starts (minus date/time and info stamps).
        # .. and load the proper ops file
        if "Starting minecraft server version" in buff and \
                self.prepends_offset == 0:

            for place in range(len(line_words)-1):
                self.prepends_offset = place
                if line_words[place] == "Starting":
                    break

            line_words = buff.split(' ')[self.prepends_offset:]
            self.vitals.version = getargs(line_words, 4)
            semantics = self.vitals.version.split(".")
            release = get_int(getargs(semantics, 0))
            major = get_int(getargs(semantics, 1))
            minor = get_int(getargs(semantics, 2))
            self.vitals.version_compute = minor + (major * 100) + (release * 10000)  # noqa

            # 1.7.6 (protocol 5) is the cutoff where ops.txt became ops.json
            if self.vitals.version_compute > 10705 and self.vitals.protocolVersion < 0:  # noqa
                self.vitals.protocolVersion = 5
                self.wrapper.api.registerPermission("mc1.7.6", value=True)
            if self.vitals.version_compute < 10702 and self.wrapper.proxymode:
                self.log.warning("\nProxy mode cannot run because the "
                                 "server is a pre-Netty version:\n\n"
                                 "http://wiki.vg/Protocol_version_numbers"
                                 "#Versions_before_the_Netty_rewrite\n\n"
                                 "Server will continue in non-proxy mode.")
                self.wrapper.disable_proxymode()
                return

            self.refresh_ops()

        if len(line_words) < 1:
            return

        # the server attempted to print a blank line
        if len(line_words[0]) < 1:
            print('')
            return

        # parse or modify the server output section
        #
        #

        # Over-ride OP help console display
        if "/op <player>" in buff:
            new_usage = "player> [-s SUPER-OP] [-o OFFLINE] [-l <level>]"
            message = buff.replace("player>", new_usage)
            buff = message
        if "/whitelist <on|off" in buff:
            new_usage = "/whitelist <on|off|list|add|remvove|reload|offline|online>"  # noqa
            message = new_usage
            buff = message

        if "While this makes the game possible to play" in buff:
            prefix = " ".join(buff.split(' ')[:self.prepends_offset])

            if not self.wrapper.wrapper_onlinemode:
                message = (
                    "%s Since you are running Wrapper in OFFLINE mode, THIS "
                    "COULD BE SERIOUS!\n%s Wrapper is not handling any"
                    " authentication.\n%s This is only ok if this wrapper "
                    "is not accessible from either port %s or port %s"
                    " (I.e., this wrapper is a multiworld for a hub server, or"
                    " you are doing your own authorization via a plugin)." % (
                        prefix, prefix, prefix,
                        self.vitals.server_port, self.wrapper.proxy.proxy_port))
            else:
                message = (
                    "%s Since you are running Wrapper in proxy mode, this"
                    " should be ok because Wrapper is handling the"
                    " authentication, PROVIDED no one can access port"
                    " %s from outside your network." % (
                        prefix, self.vitals.server_port))

            if self.wrapper.proxymode:
                buff = message

        # read port of server and display proxy port, if applicable
        if "Starting Minecraft server on" in buff:
            self.vitals.server_port = get_int(buff.split(':')[-1:][0])

        # check for server console spam before printing to wrapper console
        server_spaming = False
        for things in self.vitals.spammy_stuff:
            if things in buff:
                server_spaming = True

        # server_spaming setting does not stop it from being parsed below.
        if not server_spaming:
            if not self.server_muted:
                self.wrapper.write_stdout(buff, "server")
            else:
                self.queued_lines.append(buff)

        first_word = getargs(line_words, 0)
        second_word = getargs(line_words, 1)
        # be careful about how these elif's are handled!
        # confirm server start
        if "Done (" in buff:
            self._toggle_server_started()
            self.changestate(STARTED)
            self.log.info("Server started")
            if self.wrapper.proxymode:
                self.log.info("Proxy listening on *:%s", self.wrapper.proxy.proxy_port)  # noqa

        # Getting world name
        elif "Preparing level" in buff:
            self.vitals.worldname = getargs(line_words, 2).replace('"', "")
            self.world = World(self.vitals.worldname, self)

        # Player Message
        elif first_word[0] == "<":
            # get a name out of <name>
            name = self.stripspecial(first_word[1:-1])
            message = self.stripspecial(getargsafter(line_words, 1))
            original = getargsafter(line_words, 0)
            playerobj = self.getplayer(name)
            if playerobj:
                self.wrapper.events.callevent("player.message", {
                    "player": self.getplayer(name),
                    "message": message,
                    "original": original
                }, abortable=False)
                """ eventdoc
                    <group> core/mcserver.py <group>
    
                    <description> Player chat scrubbed from the console.
                    <description>
    
                    <abortable> No
                    <abortable>
    
                    <comments>
                    This event is triggered by console chat which has already been sent. 
                    This event returns the player object. if used in a string context, 
                    ("%s") it's repr (self.__str__) is self.username (no need to do 
                    str(player) or player.username in plugin code).
                    <comments>
    
                    <payload>
                    "player": playerobject (self.__str__ represents as player.username)
                    "message": <str> type - what the player said in chat. ('hello everyone')
                    "original": The original line of text from the console ('<mcplayer> hello everyone`)
                    <payload>
    
                """  # noqa
            else:
                self.log.debug("Console has chat from '%s', but wrapper has no "
                               "known logged-in player object by that name.", name)  # noqa
        # Player Login
        elif second_word == "logged":
            user_desc = first_word.split("[/")
            name = user_desc[0]
            ip_addr = user_desc[1].split(":")[0]
            eid = get_int(getargs(line_words, 6))
            locationtext = getargs(buff.split(" ("), 1)[:-1].split(", ")
            # spigot versus vanilla
            # SPIGOT - [12:13:19 INFO]: *******[/] logged in with entity id 123 at ([world]316.86789318152546, 67.12426603789697, -191.9069627257038)  # noqa
            # VANILLA - [23:24:34] [Server thread/INFO]: *******[/127.0.0.1:47434] logged in with entity id 149 at (46.29907483845001, 63.0, -270.1293488726086)  # noqa
            if len(locationtext[0].split("]")) > 1:
                x_c = get_int(float(locationtext[0].split("]")[1]))
            else:
                x_c = get_int(float(locationtext[0]))
            y_c = get_int(float(locationtext[1]))
            z_c = get_int(float(locationtext[2]))
            location = x_c, y_c, z_c

            self.login(name, eid, location, ip_addr)

        # Player Logout
        elif "lost connection" in buff:
            name = first_word
            self.logout(name)

        # player action
        elif first_word == "*":
            name = self.stripspecial(second_word)
            message = self.stripspecial(getargsafter(line_words, 2))
            self.wrapper.events.callevent("player.action", {
                "player": self.getplayer(name),
                "action": message
            }, abortable=False)

        # Player Achievement
        elif "has just earned the achievement" in buff:
            name = self.stripspecial(first_word)
            achievement = getargsafter(line_words, 6)
            self.wrapper.events.callevent("player.achievement", {
                "player": name,
                "achievement": achievement
            }, abortable=False)

        # /say command
        elif getargs(
                line_words, 0)[0] == "[" and first_word[-1] == "]":
            if self.getservertype != "vanilla":
                # Unfortunately, Spigot and Bukkit output things
                # that conflict with this.
                return
            name = self.stripspecial(first_word[1:-1])
            message = self.stripspecial(getargsafter(line_words, 1))
            original = getargsafter(line_words, 0)
            self.wrapper.events.callevent("server.say", {
                "player": name,
                "message": message,
                "original": original
            }, abortable=False)

        # Player Death
        elif second_word in self.deathprefixes:
            name = self.stripspecial(first_word)
            self.wrapper.events.callevent("player.death", {
                "player": self.getplayer(name),
                "death": getargsafter(line_words, 1)
            }, abortable=False)

        # server lagged
        elif "Can't keep up!" in buff:
            skipping_ticks = getargs(line_words, 17)
            self.wrapper.events.callevent("server.lagged", {
                "ticks": get_int(skipping_ticks)
            }, abortable=False)

        # player teleport
        elif second_word == "Teleported" and getargs(line_words, 3) == "to":
            playername = getargs(line_words, 2)
            # [SurestTexas00: Teleported SapperLeader to 48.49417131908783, 77.67081086259394, -279.88880690937475]  # noqa
            if playername in self.wrapper.servervitals.players:
                playerobj = self.getplayer(playername)
                playerobj._position = [
                    get_int(float(getargs(line_words, 4).split(",")[0])),
                    get_int(float(getargs(line_words, 5).split(",")[0])),
                    get_int(float(getargs(line_words, 6).split("]")[0])), 0, 0
                ]
                self.wrapper.events.callevent(
                    "player.teleport",
                    {"player": playerobj}, abortable=False)

                """ eventdoc
                    <group> core/mcserver.py <group>

                    <description> When player teleports.
                    <description>

                    <abortable> No <abortable>

                    <comments> driven from console message "Teleported ___ to ....".
                    <comments>

                    <payload>
                    "player": player object
                    <payload>

                """  # noqa
        elif first_word == "Teleported" and getargs(line_words, 2) == "to":
            playername = second_word
            # Teleported SurestTexas00 to 48.49417131908783, 77.67081086259394, -279.88880690937475  # noqa
            if playername in self.wrapper.servervitals.players:
                playerobj = self.getplayer(playername)
                playerobj._position = [
                    get_int(float(getargs(line_words, 3).split(",")[0])),
                    get_int(float(getargs(line_words, 4).split(",")[0])),
                    get_int(float(getargs(line_words, 5))), 0, 0
                ]
                self.wrapper.events.callevent(
                    "player.teleport",
                    {"player": playerobj}, abortable=False)

                """ eventdoc