def _raw(self, console_input): try: if len(getargsafter(console_input[1:].split(" "), 1)) > 0: self.javaserver.console( getargsafter(console_input[1:].split(" "), 1)) else: self.log.info("Usage: /raw [command]") except EnvironmentError as e: self.log.warning(e)
def command_banip(self, player, payload): if not player.isOp() > 2: player.message("&cPermission Denied") return False commargs = payload["args"] ipaddress = getargs(commargs, 0) banexpires = False reason = "the Ban Hammer has Spoken" if len(commargs) > 1: # check last argument for "d:<days> if commargs[len(commargs) - 1][0:2].lower() == "d:": days = int(float(commargs[len(commargs) - 1][2:])) if days > 0: banexpires = time.time() + (days * 86400) reason = getargsafter(commargs, 1) returnmessage = self.wrapper.proxy.banip(ipaddress, reason, player.username, banexpires) if returnmessage[:6] == "Banned": player.message({"text": "%s" % returnmessage, "color": "yellow"}) else: player.message({"text": "IP ban failed!", "color": "red"}) player.message(returnmessage) return returnmessage
def command_banplayer(self, player, payload): if not player.isOp() > 2: player.message("&cPermission Denied") return False commargs = payload["args"] playername = getargs(commargs, 0) banexpires = False reason = "the Ban Hammer has Spoken" timeunit = 86400 # days is default lookupuuid = self.wrapper.uuids.getuuidbyusername(playername) if not lookupuuid: player.message({"text": "Not a valid Username!", "color": "red"}) return False if len(commargs) > 1: # check last argument for "d:<days> unitsare = commargs[len(commargs) - 1][0:2].lower() if unitsare in ("d:", "h:"): if unitsare == "h:": timeunit /= 24 units = int(float(commargs[len(commargs) - 1][2:])) if units > 0: banexpires = time.time() + (units * timeunit) reason = getargsafter(commargs, 1) returnmessage = self.wrapper.proxy.banuuid(lookupuuid, reason, player.username, banexpires) if returnmessage[:6] == "Banned": player.message({"text": "%s" % returnmessage, "color": "yellow"}) else: player.message({"text": "UUID ban failed!", "color": "red"}) player.message(returnmessage) return returnmessage
def command_banip(self, player, payload): if not player.isOp() > 2: player.message("&cPermission Denied") return False commargs = payload["args"] ipaddress = getargs(commargs, 0) banexpires = False reason = "the Ban Hammer has Spoken" if len(commargs) > 1: # check last argument for "d:<days> if commargs[len(commargs)-1][0:2].lower() == "d:": days = int(float(commargs[len(commargs)-1][2:])) if days > 0: banexpires = time.time() + (days * 86400) reason = getargsafter(commargs, 1) returnmessage = self.wrapper.proxy.banip( ipaddress, reason, player.username, banexpires) if returnmessage[:6] == "Banned": player.message({"text": "%s" % returnmessage, "color": "yellow"}) else: player.message({"text": "IP ban failed!", "color": "red"}) player.message(returnmessage) return returnmessage
def command_banplayer(self, player, payload): if not player.isOp() > 2: player.message("&cPermission Denied") return False commargs = payload["args"] playername = getargs(commargs, 0) banexpires = False reason = "the Ban Hammer has Spoken" timeunit = 86400 # days is default lookupuuid = self.wrapper.uuids.getuuidbyusername(playername) if not lookupuuid: player.message({"text": "Not a valid Username!", "color": "red"}) return False if len(commargs) > 1: # check last argument for "d:<days> unitsare = commargs[len(commargs) - 1][0:2].lower() if unitsare in ("d:", "h:"): if unitsare == "h:": timeunit /= 24 units = int(float(commargs[len(commargs) - 1][2:])) if units > 0: banexpires = time.time() + (units * timeunit) reason = getargsafter(commargs, 1) returnmessage = self.wrapper.proxy.banuuid( lookupuuid, reason, player.username, banexpires) if returnmessage[:6] == "Banned": player.message({"text": "%s" % returnmessage, "color": "yellow"}) else: player.message({"text": "UUID ban failed!", "color": "red"}) player.message(returnmessage) return returnmessage
def command_password(self, player, payload): if not player.isOp() > 4: player.message("&cPermission Denied") return command = getargs(payload["args"], 0) def showhelp(): player.message("&2Usage: /password <group> <item> <data>") player.message( "&2 in console, use 'prompt' for <data> to be invisibly") player.message( "&2 prompted if there is an 'over the shoulder' concern.") player.message( "&2 Sample usage to change IRC remote control password:"******"&2 /password IRC control-irc-pass NEWsuckypassword") if command in ("help", "h", "info", "about"): showhelp() return group = getargs(payload["args"], 0) setting = getargs(payload["args"], 1) data = getargsafter(payload["args"], 2) if data == "prompt": data = get_passphrase("Please enter data to be hashed/stored") if group not in self.config: player.message( "&c wrapper.properties has no such group '%s'" % group) showhelp() return if setting not in self.config[group]: player.message( "&c There is no item '%s' in group '%s'" % (setting, group)) return final_data = self.cipher.encrypt(data) player.message("&2 data encrypted!") self.config[group][setting] = final_data self.config_manager.save()
def command_perms(self, player, payload): if not self._superop(player): return False def usage(l): player.message("&cUsage: /%s %s" % (payload["command"], l)) command = getargs(payload["args"], 0) if command == "groups": group = getargs(payload["args"], 1) subcommand = getargs(payload["args"], 2) if subcommand == "new": call_result = self.perms.group_create(group) player.message("&a%s" % call_result) elif subcommand == "delete": call_result = self.perms.group_delete(group) player.message("&a%s" % call_result) elif subcommand == "set": node = getargs(payload["args"], 3) value = getargsafter(payload["args"], 4) call_result = self.perms.group_set_permission( group, node, value) if call_result: player.message("&aGroup permission set.") else: usage("groups %s set <permissionNode> [value]" % group) elif subcommand == "remove": node = getargs(payload["args"], 3) call_result = self.perms.group_delete_permission(group, node) player.message("&a%s" % call_result) elif subcommand == "info": if group not in self.wrapper.permissions["groups"]: player.message("&cGroup '%s' does not exist!" % group) return player.message("&aUsers in the group '%s':" % group) for uuid in self.wrapper.permissions["users"]: if group in self.wrapper.permissions["users"][uuid][ "groups"]: player.message( "%s: &2%s" % (self.wrapper.uuids.getusernamebyuuid(uuid), uuid)) player.message("&aPermissions for the group '%s':" % group) for node in self.wrapper.permissions["groups"][group][ "permissions"]: value = self.wrapper.permissions["groups"][group][ "permissions"][node] if value: player.message("- %s: &2%s" % (node, value)) elif not value: player.message("- %s: &4%s" % (node, value)) else: player.message("- %s: &7%s" % (node, value)) else: player.message("&cList of groups: %s" % ", ".join(self.wrapper.permissions["groups"])) usage("groups <groupName> [new/delete/set/remove/info]") elif command == "users": username = getargs(payload["args"], 1) subcommand = getargs(payload["args"], 2) uuid = self.wrapper.uuids.getuuidbyusername(username) if str(uuid) not in self.wrapper.permissions: self.perms.fill_user(str(uuid)) if subcommand == "group": group = getargs(payload["args"], 3) if len(group) > 0 and len(uuid) > 0: call_result = self.perms.set_group(str(uuid), group) if not call_result: player.message( "&ccommand failed, check wrapper log for info.") else: usage("users <username> group <groupName>") elif subcommand == "set": node = getargs(payload["args"], 3) value = getargsafter(payload["args"], 4) if len(node) > 0: call_result = self.perms.set_permission( str(uuid), node, value) player.message("&a%s" % call_result) else: usage("users %s set <permissionNode> [value]" % username) elif subcommand == "remove": node = getargs(payload["args"], 3) if len(node) > 0: call_result = self.perms.remove_permission(str(uuid), node) player.message("&a%s" % call_result) else: usage("users %s remove <permissionNode>" % username) elif subcommand == "info": player.message("&aUser '%s' is in these groups: " % username) for group in self.wrapper.permissions["users"][str( uuid)]["groups"]: player.message("- %s" % group) player.message( "&aUser '%s' is granted these individual permissions (not including permissions inherited from groups): " % username) for node in self.wrapper.permissions["users"][str( uuid)]["permissions"]: value = self.wrapper.permissions["users"][str( uuid)]["permissions"][node] if value: player.message("- %s: %s" % (node, value)) elif not value: player.message("- %s: %s" % (node, value)) else: player.message("- %s: %s" % (node, value)) else: usage("users <username> <group/set/remove/info>") else: usage("<groups/users/RESET> (Note: RESET is case-sensitive!)") player.message("&cAlias commands: /perms, /perm, /super") return False
def command_help(self, player, payload): helpgroups = [{ "name": "Minecraft", "description": "List regular server commands" }] for hid in self.wrapper.help: plugin = self.wrapper.help[hid] for helpitem in plugin: helpgroups.append({ "name": helpitem, "description": plugin[helpitem][0] }) if len(getargs(payload["args"], 1)) > 0: group = getargs(payload["args"], 0) page = getargs(payload["args"], 1) else: group = "" page = getargs(payload["args"], 0) try: page = int(page) - 1 except: if len(page) > 0: group = page page = 0 # This controls cases where user typed '/help <plugin>' if len(group) > 0: # if player typed (or clicked) '/help Minecraft [page]' if group == "Minecraft": player.execute("help %d" % (page + 1)) time.sleep(.1) player.message({ "text": "", "extra": [{ "text": "Page %s" % (page + 2), "color": "blue", "underlined": True, "clickEvent": { "action": "run_command", "value": "%shelp Minecraft %d" % (self.wrapper.command_prefix, page + 2) } }, { "text": " " }] }) else: # Padding, for the sake of making it look a bit nicer player.message(" ") for hid in self.wrapper.help: for groupname in self.wrapper.help[hid]: # if groupName.lower() == group: if groupname == group: group = self.wrapper.help[hid][groupname][1] items = [] # i is each help item, like: # ('/bmlist', 'List bookmark names', None) for i in group: command, args, permission = i[0].split( " ")[0], "", None if len(i[0].split(" ")) > 1: # if there are args after the command args = getargsafter(i[0].split(" "), 1) # TODO we should really base permission on the # actual command permission, and not a # (potentially inconsistent) help entry! # will only display is player has permission if not player.hasPermission(i[2]): permission = { "text": "You do not have permission to" " use this command.", "color": "gray", "italic": True } items.append({ "text": "", "extra": [ { "text": command, "color": "gray", "italic": True, "hoverEvent": { "action": "show_text", "value": permission } }, ] }) continue if len(i) > 1 and player.isOp(): permission = { "text": "Requires permission '%s'." % i[2], "color": "gray", "italic": True } items.append({ "text": "", "extra": [{ "text": command, "color": "gold", "clickEvent": { "action": "suggest_command", "value": "%s%s" % (self.wrapper.command_prefix, command[1:]) }, "hoverEvent": { "action": "show_text", "value": permission } }, { "text": " " + args, "color": "red", "italic": True }, { "text": " - %s " % i[1] }] }) _showpage( player, page, items, "help %s" % groupname, 4, command_prefix=self.wrapper.command_prefix) return player.message("&cThe help group '%s' does not exist." % group) # Plain old /help - print list of help groups else: items = [] for v in helpgroups: items.append({ "text": "", "extra": [{ "text": "%s\n" % v["name"], "color": "gold", }, { "text": "/help %s 1" % v["name"], "color": "blue", "clickEvent": { "action": "run_command", "value": "%shelp %s" % (self.wrapper.command_prefix, v["name"]) } }, { "text": " - " + v["description"] }] }) _showpage(player, page, items, "help", 4, command_prefix=self.wrapper.command_prefix) return False
def parse(self): if getargs(self.line.split(" "), 1) == "001": for command in self.config["IRC"]["autorun-irc-commands"]: self.send(command) for channel in self.channels: self.send("JOIN %s" % channel) self.ready = True self.log.info("Connected to IRC!") self.state = True self.nickAttempts = 0 if getargs(self.line.split(" "), 1) == "433": self.log.info("Nickname '%s' already in use.", self.nickname) self.nickAttempts += 1 if self.nickAttempts > 2: name = bytearray(self.nickname) for i in xrange(3): name[len(self.nickname) / 3 * i] = chr(random.randrange(97, 122)) self.nickname = str(name) else: self.nickname += "_" self.auth() self.log.info("Attemping to use nickname '%s'.", self.nickname) if getargs(self.line.split(" "), 1) == "JOIN": nick = getargs(self.line.split(" "), 0)[1:getargs(self.line.split(" "), 0).find("!")] channel = getargs(self.line.split(" "), 2)[1:][:-1] self.log.info("%s joined %s", nick, channel) self.wrapper.events.callevent("irc.join", {"nick": nick, "channel": channel}) if getargs(self.line.split(" "), 1) == "PART": nick = getargs(self.line.split(" "), 0)[1:getargs(self.line.split(" "), 0).find("!")] channel = getargs(self.line.split(" "), 2) self.log.info("%s parted %s", nick, channel) self.wrapper.events.callevent("irc.part", {"nick": nick, "channel": channel}) if getargs(self.line.split(" "), 1) == "MODE": try: nick = getargs(self.line.split(" "), 0)[1:getargs(self.line.split(" "), 0).find('!')] channel = getargs(self.line.split(" "), 2) modes = getargs(self.line.split(" "), 3) user = getargs(self.line.split(" "), 4)[:-1] self.console(channel, [{ "text": user, "color": "green" }, { "text": " received modes %s from %s" % (modes, nick), "color": "white" }]) except Exception as e: self.log.debug("Exception in IRC in parse (MODE): \n%s", e) pass if getargs(self.line.split(" "), 0) == "PING": self.send("PONG %s" % getargs(self.line.split(" "), 1)) if getargs(self.line.split(" "), 1) == "QUIT": nick = getargs(self.line.split(" "), 0)[1:getargs(self.line.split(" "), 0).find("!")] message = getargsafter(self.line.split(" "), 2)[1:].strip("\n").strip("\r") self.wrapper.events.callevent("irc.quit", {"nick": nick, "message": message, "channel": None}) if getargs(self.line.split(" "), 1) == "PRIVMSG": channel = getargs(self.line.split(" "), 2) nick = getargs(self.line.split(" "), 0)[1:getargs(self.line.split(" "), 0).find("!")] message = getargsafter(self.line.split(" "), 3)[1:].strip("\n").strip("\r") if channel[0] == "#": if message.strip() == ".players": users = "" for user in self.javaserver.players: users += "%s " % user self.send("PRIVMSG %s :There are currently %s users on the server: %s" % (channel, len(self.javaserver.players), users)) elif message.strip() == ".about": self.send("PRIVMSG %s :Wrapper.py Version %s" % (channel, self.wrapper.getbuildstring())) else: message = message.decode("utf-8", "ignore") if getargs(message.split(" "), 0) == "\x01ACTION": self.wrapper.events.callevent("irc.action", {"nick": nick, "channel": channel, "action": getargsafter(message.split(" "), 1)[:-1]}) self.log.info("[%s] * %s %s", channel, nick, getargsafter(message.split(" "), 1)[:-1]) else: self.wrapper.events.callevent("irc.message", {"nick": nick, "channel": channel, "message": message}) self.log.info("[%s] <%s> %s", channel, nick, message) elif self.config["IRC"]["control-from-irc"]: self.log.info("[PRIVATE] (%s) %s", nick, message) def msg(string): self.log.info("[PRIVATE] (%s) %s", self.nickname, string) self.send("PRIVMSG %s :%s" % (nick, string)) if self.config["IRC"]["control-irc-pass"] == "password": msg("A new password is required in wrapper.properties. Please change it.") return if "password" in self.config["IRC"]["control-irc-pass"]: msg("Please choose a password that doesn't contain the term 'password'.") return if nick in self.authorized: if int(time.time()) - self.authorized[nick] < 900: if getargs(message.split(" "), 0) == 'hi': msg('Hey there!') elif getargs(message.split(" "), 0) == 'help': # eventually I need to make help only one or two # lines, to prevent getting kicked/banned for spam msg("run [command] - run command on server") msg("togglebackups - temporarily turn backups on or off. this setting is not permanent " "and will be lost on restart") msg("halt - shutdown server and Wrapper.py, will not auto-restart") msg("kill - force server restart without clean shutdown - only use when server " "is unresponsive") msg("start/restart/stop - start the server/automatically stop and start server/stop " "the server without shutting down Wrapper") msg("status - show status of the server") msg("check-update - check for new Wrapper.py updates, but don't install them") msg("update-wrapper - check and install new Wrapper.py updates") msg("Wrapper.py Version %s by benbaptist" % self.wrapper.getbuildstring()) # msg('console - toggle console output to this private message') elif getargs(message.split(" "), 0) == 'togglebackups': self.config["Backups"]["enabled"] = not self.config["Backups"]["enabled"] if self.config["Backups"]["enabled"]: msg('Backups are now on.') else: msg('Backups are now off.') self.configmgr.save() # 'config' is just the json dictionary of items, not the Config class elif getargs(message.split(" "), 0) == 'run': if getargs(message.split(" "), 1) == '': msg('Usage: run [command]') else: command = " ".join(message.split(' ')[1:]) self.javaserver.console(command) elif getargs(message.split(" "), 0) == 'halt': self.wrapper.halt = True self.javaserver.console("stop") self.javaserver.changestate(3) elif getargs(message.split(" "), 0) == 'restart': self.javaserver.restart("Restarting server from IRC remote") self.javaserver.changestate(3) elif getargs(message.split(" "), 0) == 'stop': self.javaserver.console('stop') self.javaserver.stop_server_command("Stopped from IRC remote") msg("Server stopping") elif getargs(message.split(" "), 0) == 'start': self.javaserver.start() msg("Server starting") elif getargs(message.split(" "), 0) == 'kill': self.javaserver.kill("Killing server from IRC remote") msg("Server terminated.") elif getargs(message.split(" "), 0) == 'status': if self.javaserver.state == 2: msg("Server is running.") elif self.javaserver.state == 1: msg("Server is currently starting/frozen.") elif self.javaserver.state == 0: msg("Server is stopped. Type 'start' to fire it back up.") elif self.javaserver.state == 3: msg("Server is in the process of shutting down/restarting.") else: msg("Server is in unknown state. This is probably a Wrapper.py bug - report it! " "(state #%d)" % self.javaserver.state) if self.wrapper.javaserver.getmemoryusage(): msg("Server Memory Usage: %d bytes" % self.wrapper.javaserver.getmemoryusage()) elif getargs(message.split(" "), 0) == 'check-update': msg("Checking for new updates...") update = self.wrapper.get_wrapper_update_info() if update: version, build, repotype = update if repotype == "stable": msg("New Wrapper.py Version %s available! (you have %s)" % (".".join([str(_) for _ in version]), self.wrapper.getbuildstring())) elif repotype == "dev": msg("New Wrapper.py development build %s #%d available! (you have %s #%d)" % (".".join([str(_) for _ in version]), build, version_info.__version__, version_info.__build__)) else: msg("Unknown new version: %s | %d | %s" % (version, build, repotype)) msg("To perform the update, type update-wrapper.") else: if version_info.__branch__ == "stable": msg("No new stable Wrapper.py versions available.") elif version_info.__branch__ == "dev": msg("No new development Wrapper.py versions available.") elif getargs(message.split(" "), 0) == 'update-wrapper': msg("Checking for new updates...") update = self.wrapper.get_wrapper_update_info() if update: version, build, repotype = update if repotype == "stable": msg("New Wrapper.py Version %s available! (you have %s)" % (".".join([str(_) for _ in version]), self.wrapper.getbuildstring())) elif repotype == "dev": msg("New Wrapper.py development build %s #%d available! (you have %s #%d)" % (".".join(version), build, version_info.__version__, version_info.__build__)) else: msg("Unknown new version: %s | %d | %s" % (version, build, repotype)) msg("Performing update..") if self.wrapper.performupdate(version, build, repotype): msg("Update completed! Version %s #%d (%s) is now installed. Please reboot " "Wrapper.py to apply changes." % (version, build, repotype)) else: msg("An error occured while performing update.") msg("Please check the Wrapper.py console as soon as possible for an explanation " "and traceback.") msg("If you are unsure of the cause, please file a bug report on http://github.com" "/benbaptist/minecraft-wrapper.") else: if version_info.__branch__ == "stable": msg("No new stable Wrapper.py versions available.") elif version_info.__branch__ == "dev": msg("No new development Wrapper.py versions available.") elif getargs(message.split(" "), 0) == "about": msg("Wrapper.py by benbaptist - Version %s (build #%d)" % (version_info.__version__, version_info.__branch__)) else: msg('Unknown command. Type help for more commands') else: msg("Session expired, re-authorize.") del self.authorized[nick] else: if getargs(message.split(" "), 0) == 'auth': if getargs(message.split(" "), 1) == self.config["IRC"]["control-irc-pass"]: msg("Authorization success! You'll remain logged in for 15 minutes.") self.authorized[nick] = int(time.time()) else: msg("Invalid password.") else: msg('Not authorized. Type "auth [password]" to login.')
def command_perms(self, player, payload): if not self._superop(player, 5): return False def usage(l): player.message("&cUsage: /%s %s" % (payload["command"], l)) command = getargs(payload["args"], 0) if command in ("help", "h", "info", "about"): self.reset_confirmed = False subcommand = getargs(payload["args"], 1) if subcommand in ("group", "groups", "gr", "g"): player.message("&2/perms group <groupname> ...") player.message("&2 new/info -create new group / get info") player.message("&2 set <node> <value> -set a perm for this group") player.message("&2 delete -deletes the group entirely") player.message("&2 remove <node> -just remove a node") elif subcommand in ("users", "user", "use", "u"): player.message("&2/perms user <player> ...") player.message("&2 info -display permissions for a player") player.message("&2 group <group> -assign player to <group>") player.message("&2 group <group> remove -remove player from <group>") player.message("&2 set <node> <value> -set a perm for this player") player.message("&2 remove <node> -remove perm <node> for this player") else: player.message("&2The primary subcommands are group, user, RESET") player.message("&2Help with groups use: /perms help groups") player.message("&2Help with users use: /perms help users") elif command in ("gr", "group", "groups"): self.reset_confirmed = False group = getargs(payload["args"], 1) subcommand = getargs(payload["args"], 2) if subcommand == "new": call_result = self.perms.group_create(group) player.message("&a%s" % call_result) elif subcommand == "delete": call_result = self.perms.group_delete(group) player.message("&a%s" % call_result) elif subcommand == "set": node = getargs(payload["args"], 3) value = getargsafter(payload["args"], 4) call_result = self.perms.group_set_permission( group, node, value) if call_result: player.message("&aGroup permission %s set to %s.", node, value) else: usage("groups %s set <permissionNode> <value>" % group) elif subcommand == "remove": node = getargs(payload["args"], 3) call_result = self.perms.group_delete_permission(group, node) player.message("&a%s" % call_result) elif subcommand == "info": if group not in self.wrapper.wrapper_permissions.Data["groups"]: player.message("&cGroup '%s' does not exist!" % group) return player.message("&aUsers in the group '%s':" % group) for uuid in self.wrapper.wrapper_permissions.Data["users"]: if group in self.wrapper.wrapper_permissions.Data[ "users"][uuid]["groups"]: player.message("%s: &2%s" % (self.wrapper.uuids.getusernamebyuuid(uuid), uuid)) player.message("&aPermissions for the group '%s':" % group) for node in self.wrapper.wrapper_permissions.Data[ "groups"][group]["permissions"]: value = self.wrapper.wrapper_permissions.Data[ "groups"][group]["permissions"][node] if value: player.message("- %s: &2%s" % (node, value)) elif not value: player.message("- %s: &4%s" % (node, value)) else: player.message("- %s: &7%s" % (node, value)) else: player.message("&6List of groups:&b %s" % ", ".join(self.wrapper.wrapper_permissions.Data["groups"])) usage("groups <groupName> [new|delete(group)|info]/[set|remove(node) <node> <value>]") player.message("&cTry '/perms help groups' for more info...") elif command in ("user", "users"): self.reset_confirmed = False username = getargs(payload["args"], 1) subcommand = getargs(payload["args"], 2) uuid = self.wrapper.uuids.getuuidbyusername(username) if str(uuid) not in self.wrapper.wrapper_permissions.Data["users"]: self.perms.fill_user(str(uuid)) if subcommand in ("group", "groups"): group = getargs(payload["args"], 3) remove = getargs(payload["args"], 4) == "remove" if len(group) > 0 and len(str(uuid)) > 0: if remove: call_result = self.perms.remove_group(str(uuid), group) else: call_result = self.perms.set_group(str(uuid), group) if not call_result: player.message( "&ccommand failed, check wrapper log for info.") else: player.message("&aCommand succeeded.") else: usage("users <username> group <groupName> [remove]") elif subcommand == "set": node = getargs(payload["args"], 3) value = getargsafter(payload["args"], 4) if len(node) > 0: call_result = self.perms.set_permission(str(uuid), node, value) player.message("&a%s" % call_result) else: usage("users %s set <permissionNode> [value]" % username) elif subcommand == "remove": node = getargs(payload["args"], 3) if len(node) > 0: call_result = self.perms.remove_permission(str(uuid), node) player.message("&a%s" % call_result) else: usage("users %s remove <permissionNode>" % username) elif subcommand == "info": player.message("&aUser '%s' is in these groups: " % username) for group in self.wrapper.wrapper_permissions.Data["users"][str(uuid)]["groups"]: player.message("- %s" % group) player.message( "&aUser '%s' is granted these individual permissions (not including permissions inherited from groups): " % username) for node in self.wrapper.wrapper_permissions.Data[ "users"][str(uuid)]["permissions"]: value = self.wrapper.wrapper_permissions.Data[ "users"][str(uuid)]["permissions"][node] if value: player.message("- %s: %s" % (node, value)) elif not value: player.message("- %s: %s" % (node, value)) else: player.message("- %s: %s" % (node, value)) else: usage("users <username> <group/set/remove/info>") player.message("&cTry '/perms help users' for more info...") elif command == "RESET": if self.reset_confirmed and ((time.time() - self.reset_timeout) < 30): self.perms.clear_group_data() self.perms.clear_user_data() self.reset_confirmed = False player.message("&cGroup and player permissions have been cleared!") else: self.reset_timeout = time.time() self.reset_confirmed = True player.message("&cARE YOU SURE?") player.message("&cThis will delete all groups and clear all user permissions!") player.message("Confirm your intent by running '/perms RESET' again within 30 seconds.") else: self.reset_confirmed = False usage("<help/groups/users/RESET> (Note: RESET is case-sensitive!)") player.message("&cAlias commands: /perms, /perm, /super") return False
def command_help(self, player, payload): helpgroups = [{"name": "Minecraft", "description": "List regular server commands"}] for hid in self.wrapper.help: plugin = self.wrapper.help[hid] for helpitem in plugin: helpgroups.append( {"name": helpitem, "description": plugin[helpitem][0]}) if len(getargs(payload["args"], 1)) > 0: group = getargs(payload["args"], 0) page = getargs(payload["args"], 1) else: group = "" page = getargs(payload["args"], 0) try: page = int(page) - 1 except: if len(page) > 0: group = page page = 0 # This controls cases where user typed '/help <plugin>' if len(group) > 0: # if player typed (or clicked) '/help Minecraft [page]' if group == "Minecraft": player.execute("help %d" % (page + 1)) time.sleep(.1) player.message({ "text": "", "extra": [{ "text": "Page %s" % (page + 2), "color": "blue", "underlined": True, "clickEvent": { "action": "run_command", "value": "%shelp Minecraft %d" % ( self.wrapper.servervitals.command_prefix, page + 2) } }, { "text": " " }] }) else: # Padding, for the sake of making it look a bit nicer player.message(" ") for hid in self.wrapper.help: for groupname in self.wrapper.help[hid]: # if groupName.lower() == group: if groupname == group: group = self.wrapper.help[hid][groupname][1] items = [] # i is each help item, like: # ('/bmlist', 'List bookmark names', None) for i in group: command, args, permission = i[0].split(" ")[0], "", None if len(i[0].split(" ")) > 1: # if there are args after the command args = getargsafter(i[0].split(" "), 1) # will only display if player has permission if not player.hasPermission(i[2]): if player.isOp(): permission = { "text": "You do not have permission to" " use this command.", "color": "gray", "italic": True } items.append({ "text": "", "extra": [{ "text": command, "color": "gray", "italic": True, "hoverEvent": { "action": "show_text", "value": permission } }, ] }) continue if len(i) > 1 and player.isOp(): permission = {"text": "Requires permission '%s'." % i[2], "color": "gray", "italic": True} items.append({ "text": "", "extra": [{ "text": command, "color": "gold", "clickEvent": { "action": "suggest_command", "value": "%s%s" % (self.wrapper.servervitals.command_prefix, command[1:]) }, "hoverEvent": { "action": "show_text", "value": permission } }, { "text": " " + args, "color": "red", "italic": True }, { "text": " - %s " % i[1] }] }) if len(items) == 0: items.append({ "text": "", "extra": [{ "text": "No permission to run any of these commands", "color": "gray", "italic": "true", }] }) _showpage(player, page, items, "help %s" % groupname, 4, command_prefix=self.wrapper.servervitals.command_prefix) return player.message("&cThe help group '%s' does not exist." % group) # Plain old /help - print list of help groups else: items = [] for v in helpgroups: shortdesc = v["description"][0:30] if len(shortdesc) < len(v["description"]): shortdesc = shortdesc + "..." groupcolor = "gold" if v["name"] == "Minecraft": groupcolor = "white" items.append({ "text": "", "extra": [ { "text": "%s " % v["name"], "color": groupcolor, "hoverEvent": { "action": "show_text", "value": v["description"] } }, { "text": "[click help]", "color": "blue", "clickEvent": { "action": "run_command", "value": "%shelp %s" % ( self.wrapper.servervitals.command_prefix, v["name"]) }, "hoverEvent": { "action": "show_text", "value": "%shelp %s" % ( self.wrapper.servervitals.command_prefix, v["name"]) } }, { "text": " - " + shortdesc }] }) _showpage(player, page, items, "help", 8, command_prefix=self.wrapper.servervitals.command_prefix) return False
def parse(self, dataline): _line = py_str(dataline, self.encoding) if getargs(_line.split(" "), 1) == "001": for command in self.config["IRC"]["autorun-irc-commands"]: self.send(command) for channel in self.channels: self.send("JOIN %s" % channel) self.ready = True self.log.info("Connected to IRC!") self.state = True self.nickAttempts = 0 if getargs(_line.split(" "), 1) == "433": self.log.info("Nickname '%s' already in use.", self.nickname) self.nickAttempts += 1 if self.nickAttempts > 2: name = bytearray(self.nickname) for i in xrange(3): name[len(self.nickname) / 3 * i] = chr(random.randrange(97, 122)) self.nickname = str(name) else: self.nickname += "_" self.auth() self.log.info("Attemping to use nickname '%s'.", self.nickname) if getargs(_line.split(" "), 1) == "JOIN": nick = getargs(_line.split(" "), 0)[1:getargs(_line.split(" "), 0).find("!")] channel = getargs(_line.split(" "), 2)[1:][:-1] self.log.info("%s joined %s", nick, channel) self.wrapper.events.callevent("irc.join", {"nick": nick, "channel": channel}, abortable=False) if getargs(_line.split(" "), 1) == "PART": nick = getargs(_line.split(" "), 0)[1:getargs(_line.split(" "), 0).find("!")] channel = getargs(_line.split(" "), 2) self.log.info("%s parted %s", nick, channel) self.wrapper.events.callevent("irc.part", {"nick": nick, "channel": channel}, abortable=False) if getargs(_line.split(" "), 1) == "MODE": try: nick = getargs(_line.split(" "), 0)[1:getargs(_line.split(" "), 0).find('!')] channel = getargs(_line.split(" "), 2) modes = getargs(_line.split(" "), 3) user = getargs(_line.split(" "), 4)[:-1] self.console(channel, [{ "text": user, "color": "green" }, { "text": " received modes %s from %s" % (modes, nick), "color": "white" }]) except Exception as e: self.log.debug("Exception in IRC in parse (MODE): \n%s", e) pass if getargs(_line.split(" "), 0) == "PING": self.send("PONG %s" % getargs(_line.split(" "), 1)) if getargs(_line.split(" "), 1) == "QUIT": nick = getargs(_line.split(" "), 0)[1:getargs(_line.split(" "), 0).find("!")] message = getargsafter(_line.split(" "), 2)[1:].strip("\n").strip("\r") self.wrapper.events.callevent("irc.quit", {"nick": nick, "message": message, "channel": None}, abortable=False) if getargs(_line.split(" "), 1) == "PRIVMSG": channel = getargs(_line.split(" "), 2) nick = getargs(_line.split(" "), 0)[1:getargs(_line.split(" "), 0).find("!")] message = getargsafter(_line.split(" "), 3)[1:].strip("\n").strip("\r") if channel[0] == "#": if message.strip() == ".players": users = "" for user in self.javaserver.players: users += "%s " % user self.send("PRIVMSG %s :There are currently %s users on the server: %s" % (channel, len(self.javaserver.players), users)) elif message.strip() == ".about": self.send("PRIVMSG %s :Wrapper.py Version %s" % (channel, self.wrapper.getbuildstring())) else: if not PY3: message = message.decode(self.encoding, "ignore") # TODO - not sure if this part is going to work in PY3 # now that message is a properly encoded string, not a b"" sequence if getargs(message.split(" "), 0) == "\x01ACTION": self.wrapper.events.callevent("irc.action", {"nick": nick, "channel": channel, "action": getargsafter(message.split(" "), 1)[:-1]}, abortable = False ) self.log.info("[%s] * %s %s", channel, nick, getargsafter(message.split(" "), 1)[:-1]) else: self.wrapper.events.callevent("irc.message", {"nick": nick, "channel": channel, "message": message}, abortable=False ) self.log.info("[%s] <%s> %s", channel, nick, message) elif self.config["IRC"]["control-from-irc"]: self.log.info("[PRIVATE] (%s) %s", nick, message) def msg(string): self.log.info("[PRIVATE] (%s) %s", self.nickname, string) self.send("PRIVMSG %s :%s" % (nick, string)) if self.config["IRC"]["control-irc-pass"] == "password": msg("A new password is required in wrapper.properties. Please change it.") if "password" in self.config["IRC"]["control-irc-pass"]: msg("The password is not secure. You must use the console to enter a password.") return if nick in self.authorized: if int(time.time()) - self.authorized[nick] < 900: if getargs(message.split(" "), 0) == 'hi': msg('Hey there!') elif getargs(message.split(" "), 0) == 'help': # eventually I need to make help only one or two # lines, to prevent getting kicked/banned for spam msg("run [command] - run command on server") msg("togglebackups - temporarily turn backups on or off. this setting is not permanent " "and will be lost on restart") msg("halt - shutdown server and Wrapper.py, will not auto-restart") msg("kill - force server restart without clean shutdown - only use when server " "is unresponsive") msg("start/restart/stop - start the server/automatically stop and start server/stop " "the server without shutting down Wrapper") msg("status - show status of the server") msg("check-update - check for new Wrapper.py updates, but don't install them") msg("update-wrapper - check and install new Wrapper.py updates") msg("Wrapper.py Version %s by benbaptist" % self.wrapper.getbuildstring()) # msg('console - toggle console output to this private message') elif getargs(message.split(" "), 0) == 'togglebackups': self.config["Backups"]["enabled"] = not self.config["Backups"]["enabled"] if self.config["Backups"]["enabled"]: msg('Backups are now on.') else: msg('Backups are now off.') self.configmgr.save() # 'config' is just the json dictionary of items, not the Config class elif getargs(message.split(" "), 0) == 'run': if getargs(message.split(" "), 1) == '': msg('Usage: run [command]') else: command = " ".join(message.split(' ')[1:]) self.javaserver.console(command) elif getargs(message.split(" "), 0) == 'halt': msg("Halting wrapper... Bye.") self.wrapper.shutdown() elif getargs(message.split(" "), 0) == 'restart': msg("restarting from IRC remote") self.log.info("Restarting server from IRC remote") self.javaserver.restart() elif getargs(message.split(" "), 0) == 'stop': msg("Stopping from IRC remote") self.log.info("Stopped from IRC remote") self.javaserver.stop_server_command() elif getargs(message.split(" "), 0) == 'start': self.javaserver.start() msg("Server starting") elif getargs(message.split(" "), 0) == 'kill': self.javaserver.kill("Killing server from IRC remote") msg("Server terminated.") elif getargs(message.split(" "), 0) == 'status': if self.javaserver.state == 2: msg("Server is running.") elif self.javaserver.state == 1: msg("Server is currently starting/frozen.") elif self.javaserver.state == 0: msg("Server is stopped. Type 'start' to fire it back up.") elif self.javaserver.state == 3: msg("Server is in the process of shutting down/restarting.") else: msg("Server is in unknown state. This is probably a Wrapper.py bug - report it! " "(state #%d)" % self.javaserver.state) if self.wrapper.javaserver.getmemoryusage(): msg("Server Memory Usage: %d bytes" % self.wrapper.javaserver.getmemoryusage()) elif getargs(message.split(" "), 0) in ('check-update', 'update-wrapper'): msg("Checking for new updates...") update = self.wrapper.get_wrapper_update_info() repotype = None version = None if update: version, repotype = update build = version[4] newversion = version_handler.get_version(version) yourversion = version_handler.get_version(version_info.__version__) msg( "New Wrapper.py Version %s (%s) is available! (you have %s)" % (newversion, repotype, yourversion) ) msg("To perform the update, type update-wrapper.") else: msg("No new %s Wrapper.py versions available." % version_info.__branch__) if getargs(message.split(" "), 0) == 'update-wrapper' and update: msg("Performing update..") if self.wrapper.performupdate(version, repotype): msg( "Update completed! Version %s (%s) is now installed. Please reboot " "Wrapper.py to apply changes." % (version, repotype) ) else: msg("An error occured while performing update.") msg("Please check the Wrapper.py console as soon as possible for an explanation " "and traceback.") msg("If you are unsure of the cause, please file a bug report.") elif getargs(message.split(" "), 0) == "about": msg("Wrapper.py by benbaptist - Version %s (%d)" % ( version_info.__version__, version_info.__branch__)) else: msg('Unknown command. Type help for more commands') else: msg("Session expired, re-authorize.") del self.authorized[nick] else: if getargs(message.split(" "), 0) == 'auth': if self.pass_handler.check_pw(getargs(message.split(" "), 1), self.config["IRC"]["control-irc-pass"]): msg("Authorization success! You'll remain logged in for 15 minutes.") self.authorized[nick] = int(time.time()) else: msg("Invalid password.") else: msg('Not authorized. Type "auth [password]" to login.')
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
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.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) # noqa if len(self.version.split("w")) > 1: # It is a snap shot self.version_compute = 10800 # 1.7.6 (protocol 5) is the cutoff where ops.txt became ops.json if self.version_compute > 10705 and self.protocolVersion < 0: # noqa self.protocolVersion = 5 self.wrapper.api.registerPermission("mc1.7.6", value=True) if self.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: try: pport = "either port %s or " % self.wrapper.proxy.proxy_port except AttributeError: pport = "" 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 %sport %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, pport, self.server_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.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.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.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.worldname = getargs(line_words, 2).replace('"', "") self.world = World(self.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.players: playerobj = self.getplayer(playername) try: 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 ] except ValueError: pass 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.players: playerobj = self.getplayer(playername) try: 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 ] except ValueError: pass self.wrapper.events.callevent( "player.teleport", {"player": playerobj}, abortable=False) """ eventdoc
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, 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.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) # 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: 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 "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.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" " authenication, 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) # 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) # 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 getargs(line_words, 0)[0] == "<": # get a name out of <name> 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 }) """ eventdoc <group> core/mcserver.py <group> <description> Player chat scrubbed from the console. <description> <abortable> <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> """ # Player Login elif getargs(line_words, 1) == "logged": user_desc = getargs(line_words, 0).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(", ") 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 = 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) }) # player teleport elif getargs(line_words, 0) == "Teleported" and getargs(line_words, 2) == "to": playername = getargs(line_words, 1) 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}) """ eventdoc