""" Admin commands """ from django.conf import settings from django.contrib.auth.models import User from src.players.models import PlayerDB from src.server.sessionhandler import SESSIONS from src.utils import utils from src.commands.default.muxcommand import MuxCommand class CmdBoot(MuxCommand): """ @boot Usage @boot[/switches] [: reason] Switches: quiet - Silently boot without informing player port - boot by port number instead of name or dbref Boot a player object from the server. If a reason is supplied it will be echoed to the user unless /quiet is set. """ key = "@boot" locks = "cmd:perm(boot) or perm(Wizard)" help_category = "Admin" def func(self): "Implementing the function" caller = self.caller args = self.args if not args: caller.msg("Usage: @boot[/switches] [:reason]") return if ':' in args: args, reason = [a.strip() for a in args.split(':', 1)] boot_list = [] reason = "" if 'port' in self.switches: # Boot a particular port. sessions = SESSIONS.get_session_list(True) for sess in sessions: # Find the session with the matching port number. if sess.getClientAddress()[1] == int(args): boot_list.append(sess) break else: # Boot by player object pobj = caller.search("*%s" % args, global_search=True) if not pobj: return if pobj.character.has_player: if not pobj.access(caller, 'boot'): string = "You don't have the permission to boot %s." pobj.msg(string) return # we have a bootable object with a connected user matches = SESSIONS.sessions_from_player(pobj) for match in matches: boot_list.append(match) else: caller.msg("That object has no connected player.") return if not boot_list: caller.msg("No matches found.") return # Carry out the booting of the sessions in the boot list. feedback = None if not 'quiet' in self.switches: feedback = "You have been disconnected by %s.\n" % caller.name if reason: feedback += "\nReason given: %s" % reason for session in boot_list: name = session.name session.msg(feedback) session.disconnect() caller.msg("You booted %s." % name) class CmdDelPlayer(MuxCommand): """ delplayer - delete player from server Usage: @delplayer[/switch] [: reason] Switch: delobj - also delete the player's currently assigned in-game object. Completely deletes a user from the server database, making their nick and e-mail again available. """ key = "@delplayer" locks = "cmd:perm(delplayer) or perm(Immortals)" help_category = "Admin" def func(self): "Implements the command." caller = self.caller args = self.args if not args: caller.msg("Usage: @delplayer[/delobj] [: reason]") return reason = "" if ':' in args: args, reason = [arg.strip() for arg in args.split(':', 1)] # We use player_search since we want to be sure to find also players # that lack characters. players = caller.search("*%s" % args) if not players: try: players = PlayerDB.objects.filter(id=args) except ValueError: pass if not players: # try to find a user instead of a Player try: user = User.objects.get(id=args) except Exception: try: user = User.objects.get(username__iexact=args) except Exception: string = "No Player nor User found matching '%s'." % args caller.msg(string) return try: player = user.get_profile() except Exception: player = None if player and not player.access(caller, 'delete'): string = "You don't have the permissions to delete this player." caller.msg(string) return string = "" name = user.username user.delete() if player: name = player.name player.delete() string = "Player %s was deleted." % name else: string += "The User %s was deleted. It had no Player associated with it." % name caller.msg(string) return elif utils.is_iter(players): string = "There were multiple matches:" for player in players: string += "\n %s %s" % (player.id, player.key) return else: # one single match player = players user = player.user character = player.character if not player.access(caller, 'delete'): string = "You don't have the permissions to delete that player." caller.msg(string) return uname = user.username # boot the player then delete if character and character.has_player: caller.msg("Booting and informing player ...") string = "\nYour account '%s' is being *permanently* deleted.\n" % uname if reason: string += " Reason given:\n '%s'" % reason character.msg(string) caller.execute_cmd("@boot %s" % uname) player.delete() user.delete() caller.msg("Player %s was successfully deleted." % uname) class CmdEmit(MuxCommand): """ @emit Usage: @emit[/switches] [, , ... =] @remit [, , ... =] @pemit [, , ... =] Switches: room : limit emits to rooms only (default) players : limit emits to players only contents : send to the contents of matched objects too Emits a message to the selected objects or to your immediate surroundings. If the object is a room, send to its contents. @remit and @pemit are just limited forms of @emit, for sending to rooms and to players respectively. """ key = "@emit" aliases = ["@pemit", "@remit"] locks = "cmd:perm(emit) or perm(Builders)" help_category = "Admin" def func(self): "Implement the command" caller = self.caller args = self.args if not args: string = "Usage: " string += "\n@emit[/switches] [, , ... =] " string += "\n@remit [, , ... =] " string += "\n@pemit [, , ... =] " caller.msg(string) return rooms_only = 'rooms' in self.switches players_only = 'players' in self.switches send_to_contents = 'contents' in self.switches # we check which command was used to force the switches if self.cmdstring == '@remit': rooms_only = True elif self.cmdstring == '@pemit': players_only = True if not self.rhs: message = self.args objnames = [caller.location.key] else: message = self.rhs objnames = self.lhslist # send to all objects for objname in objnames: obj = caller.search(objname, global_search=True) if not obj: return if rooms_only and not obj.location == None: caller.msg("%s is not a room. Ignored." % objname) continue if players_only and not obj.has_player: caller.msg("%s has no active player. Ignored." % objname) continue if obj.access(caller, 'tell'): obj.msg(message) if send_to_contents: for content in obj.contents: content.msg(message) caller.msg("Emitted to %s and its contents." % objname) else: caller.msg("Emitted to %s." % objname) else: caller.msg("You are not allowed to send to %s." % objname) class CmdNewPassword(MuxCommand): """ @setpassword Usage: @userpassword = Set a player's password. """ key = "@userpassword" locks = "cmd:perm(newpassword) or perm(Wizards)" help_category = "Admin" def func(self): "Implement the function." caller = self.caller if not self.rhs: caller.msg("Usage: @userpassword = ") return # the player search also matches 'me' etc. player = caller.search("*%s" % self.lhs, global_search=True) if not player: return player.user.set_password(self.rhs) player.user.save() caller.msg("%s - new password set to '%s'." % (player.name, self.rhs)) if player.character != caller: player.msg("%s has changed your password to '%s'." % (caller.name, self.rhs)) class CmdPerm(MuxCommand): """ @perm - set permissions Usage: @perm[/switch] [] = [] @perm[/switch] [*] = [] Switches: del : delete the given permission from . list : list all permissions, or those set on Use * before the search string to add permissions to a player. This command sets/clears individual permission strings on an object. Use /list without any arguments to see all available permissions or those defined on the / argument. """ key = "@perm" aliases = "@setperm" locks = "cmd:perm(perm) or perm(Immortals)" help_category = "Admin" def func(self): "Implement function" caller = self.caller switches = self.switches lhs, rhs = self.lhs, self.rhs if not self.args: if "list" not in switches: string = "Usage: @setperm[/switch] [object = permission]\n" string += " @setperm[/switch] [*player = permission]" caller.msg(string) return else: #just print all available permissions string = "\nAll defined permission groups and keys (i.e. not locks):" pgroups = list(PermissionGroup.objects.all()) pgroups.sort(lambda x, y: cmp(x.key, y.key)) # sort by group key for pgroup in pgroups: string += "\n\n - {w%s{n (%s):" % (pgroup.key, pgroup.desc) string += "\n%s" % \ utils.fill(", ".join(sorted(pgroup.group_permissions))) caller.msg(string) return # locate the object/player obj = caller.search(lhs, global_search=True) if not obj: return pstring = "" if utils.inherits_from(obj, settings.BASE_PLAYER_TYPECLASS): pstring = " Player " if not rhs: string = "Permission string on %s{w%s{n: " % (pstring, obj.key) if not obj.permissions: string += "" else: string += ", ".join(obj.permissions) if pstring and obj.is_superuser: string += "\n(... But this player is a SUPERUSER! " string += "All access checked are passed automatically.)" elif obj.player and obj.player.is_superuser: string += "\n(... But this object's player is a SUPERUSER! " string += "All access checked are passed automatically.)" caller.msg(string) return # we supplied an argument on the form obj = perm cstring = "" tstring = "" if 'del' in switches: # delete the given permission(s) from object. for perm in self.rhslist: try: index = obj.permissions.index(perm) except ValueError: cstring += "\nPermission '%s' was not defined on %s%s." % (perm, pstring, lhs) continue permissions = obj.permissions del permissions[index] obj.permissions = permissions cstring += "\nPermission '%s' was removed from %s%s." % (perm, pstring, obj.name) tstring += "\n%s revokes the permission '%s' from you." % (caller.name, perm) else: # As an extra check, we warn the user if they customize the # permission string (which is okay, and is used by the lock system) permissions = obj.permissions for perm in self.rhslist: if perm in permissions: cstring += "\nPermission '%s' is already defined on %s%s." % (rhs, pstring, obj.name) else: permissions.append(perm) obj.permissions = permissions cstring += "\nPermission '%s' given to %s%s." % (rhs, pstring, obj.name) tstring += "\n%s granted you the permission '%s'." % (caller.name, rhs) caller.msg(cstring.strip()) if tstring: obj.msg(tstring.strip()) class CmdPuppet(MuxCommand): """ Switch control to an object Usage: @puppet This will attempt to "become" a different character. Note that this command does not check so that the target object has the appropriate cmdset. You cannot puppet a character that is already "taken". """ key = "@puppet" locks = "cmd:perm(puppet) or perm(Builders)" help_category = "Admin" def func(self): """ Simple puppet method (does not check permissions) """ caller = self.caller if not self.args: caller.msg("Usage: @puppet ") return player = caller.player new_character = caller.search(self.args) if not new_character: return if not utils.inherits_from(new_character, settings.BASE_CHARACTER_TYPECLASS): caller.msg("%s is not a Character." % self.args) return if new_character.player: caller.msg("This character is already under the control of a player.") if player.swap_character(new_character): new_character.msg("You now control %s." % new_character.name) else: caller.msg("You cannot control %s." % new_character.name) class CmdWall(MuxCommand): """ @wall Usage: @wall Announces a message to all connected players. """ key = "@wall" locks = "cmd:perm(wall) or perm(Wizards)" help_category = "Admin" def func(self): "Implements command" if not self.args: self.caller.msg("Usage: @wall ") return message = "%s shouts \"%s\"" % (self.caller.name, self.args) SESSIONS.announce_all(message)