mirror of
https://github.com/evennia/evennia.git
synced 2026-03-16 21:06:30 +01:00
281 lines
11 KiB
Python
281 lines
11 KiB
Python
"""
|
|
The help command. The basic idea is that help texts for commands
|
|
are best written by those that write the commands - the admins. So
|
|
command-help is all auto-loaded and searched from the current command
|
|
set. The normal, database-tied help system is used for collaborative
|
|
creation of other help topics such as RP help or game-world aides.
|
|
"""
|
|
|
|
from src.utils.utils import fill, dedent
|
|
from src.commands.command import Command
|
|
from src.help.models import HelpEntry
|
|
from src.permissions.permissions import has_perm
|
|
from src.utils import create
|
|
from game.gamesrc.commands.default.muxcommand import MuxCommand
|
|
|
|
LIST_ARGS = ["list", "all"]
|
|
|
|
def format_help_entry(title, help_text, aliases=None,
|
|
suggested=None):
|
|
"This visually formats the help entry."
|
|
string = "-"*70 + "\n"
|
|
if title:
|
|
string += "Help topic for {w%s{n" % (title.capitalize())
|
|
if aliases:
|
|
string += " (aliases: %s)" % (", ".join(aliases))
|
|
if help_text:
|
|
string += "\n%s" % dedent(help_text.rstrip())
|
|
if suggested:
|
|
string += "\nSuggested:\n"
|
|
string += fill(", ".join(suggested))
|
|
string.strip()
|
|
string += "\n" + "-"*70
|
|
return string
|
|
|
|
def format_help_list(hdict_cmds, hdict_db):
|
|
"Output a category-ordered list"
|
|
string = "\n\r" + "-"*70 + "\n\r {gCommand help entries{n\n" + "-"*70
|
|
for category in sorted(hdict_cmds.keys()):
|
|
string += "\n {w%s{n:\n" % \
|
|
(str(category).capitalize())
|
|
string += fill(", ".join(sorted(hdict_cmds[category])))
|
|
if hdict_db:
|
|
string += "\n\r\n\r" + "-"*70 + "\n\r {gOther help entries{n\n" + '-'*70
|
|
for category in sorted(hdict_db.keys()):
|
|
string += "\n\r {w%s{n:\n" % (str(category).capitalize())
|
|
string += fill(", ".join(sorted([str(topic) for topic in hdict_db[category]])))
|
|
return string
|
|
|
|
class CmdHelp(Command):
|
|
"""
|
|
The main help command
|
|
|
|
Usage:
|
|
help <topic or command>
|
|
help list
|
|
help all
|
|
|
|
This will search for help on commands and other
|
|
topics related to the game.
|
|
"""
|
|
key = "help"
|
|
# this is a special cmdhandler flag that makes the cmdhandler also pack
|
|
# the current cmdset with the call to self.func().
|
|
return_cmdset = True
|
|
|
|
def parse(self):
|
|
"""
|
|
inp is a string containing the command or topic match.
|
|
"""
|
|
self.args = self.args.strip().lower()
|
|
|
|
def func(self):
|
|
"""
|
|
Run the dynamic help entry creator.
|
|
"""
|
|
query, cmdset = self.args, self.cmdset
|
|
caller = self.caller
|
|
|
|
if not query:
|
|
query = "all"
|
|
|
|
# Listing help entries
|
|
|
|
if query in LIST_ARGS:
|
|
# we want to list all available help entries
|
|
hdict_cmd = {}
|
|
for cmd in (cmd for cmd in cmdset if has_perm(caller, cmd, 'cmd')
|
|
if not cmd.key.startswith('__')
|
|
and not (hasattr(cmd, 'is_exit') and cmd.is_exit)):
|
|
if hdict_cmd.has_key(cmd.help_category):
|
|
hdict_cmd[cmd.help_category].append(cmd.key)
|
|
else:
|
|
hdict_cmd[cmd.help_category] = [cmd.key]
|
|
hdict_db = {}
|
|
for topic in (topic for topic in HelpEntry.objects.get_all_topics()
|
|
if has_perm(caller, topic, 'view')):
|
|
if hdict_db.has_key(topic.help_category):
|
|
hdict_db[topic.help_category].append(topic.key)
|
|
else:
|
|
hdict_db[topic.help_category] = [topic.key]
|
|
help_entry = format_help_list(hdict_cmd, hdict_db)
|
|
caller.msg(help_entry)
|
|
return
|
|
|
|
# Look for a particular help entry
|
|
|
|
# Cmd auto-help dynamic entries
|
|
cmdmatches = [cmd for cmd in cmdset
|
|
if query in cmd and has_perm(caller, cmd, 'cmd')]
|
|
if len(cmdmatches) > 1:
|
|
# multiple matches. Try to limit it down to exact match
|
|
exactmatches = [cmd for cmd in cmdmatches if cmd == query]
|
|
if exactmatches:
|
|
cmdmatches = exactmatches
|
|
|
|
# Help-database static entries
|
|
dbmatches = \
|
|
[topic for topic in
|
|
HelpEntry.objects.find_topicmatch(query, exact=False)
|
|
if has_perm(caller, topic, 'view')]
|
|
if len(dbmatches) > 1:
|
|
exactmatches = \
|
|
[topic for topic in
|
|
HelpEntry.objects.find_topicmatch(query, exact=True)
|
|
if has_perm(caller, topic, 'view')]
|
|
if exactmatches:
|
|
dbmatches = exactmatches
|
|
|
|
# Handle result
|
|
if (not cmdmatches) and (not dbmatches):
|
|
# no normal match. Check if this is a category match instead
|
|
categ_cmdmatches = [cmd for cmd in cmdset
|
|
if query == cmd.help_category and has_perm(caller, cmd, 'cmd')]
|
|
categ_dbmatches = \
|
|
[topic for topic in
|
|
HelpEntry.objects.find_topics_with_category(query)
|
|
if has_perm(caller, topic, 'view')]
|
|
if categ_cmdmatches or categ_dbmatches:
|
|
help_entry = format_help_list({query:categ_cmdmatches},
|
|
{query:categ_dbmatches})
|
|
else:
|
|
help_entry = "No help entry found for '%s'" % query
|
|
|
|
elif len(cmdmatches) == 1:
|
|
# we matched against a command name or alias. Show its help entry.
|
|
suggested = []
|
|
if dbmatches:
|
|
suggested = [entry.key for entry in dbmatches]
|
|
cmd = cmdmatches[0]
|
|
help_entry = format_help_entry(cmd.key, cmd.__doc__,
|
|
aliases=cmd.aliases,
|
|
suggested=suggested)
|
|
elif len(dbmatches) == 1:
|
|
# matched against a database entry
|
|
entry = dbmatches[0]
|
|
help_entry = format_help_entry(entry.key, entry.entrytext)
|
|
else:
|
|
# multiple matches of either type
|
|
cmdalts = [cmd.key for cmd in cmdmatches]
|
|
dbalts = [entry.key for entry in dbmatches]
|
|
helptext = "Multiple help entries match your search ..."
|
|
help_entry = format_help_entry("", helptext, None, cmdalts + dbalts)
|
|
|
|
# send result to user
|
|
caller.msg(help_entry)
|
|
|
|
class CmdSetHelp(MuxCommand):
|
|
"""
|
|
@sethelp - edit the help database
|
|
|
|
Usage:
|
|
@sethelp[/switches] <topic>[,category[,permission,permission,...]] = <text>
|
|
|
|
Switches:
|
|
add - add or replace a new topic with text.
|
|
append - add text to the end of topic with a newline between.
|
|
merge - As append, but don't add a newline between the old
|
|
text and the appended text.
|
|
delete - remove help topic.
|
|
force - (used with add) create help topic also if the topic
|
|
already exists.
|
|
|
|
Examples:
|
|
@sethelp/add throw = This throws something at ...
|
|
@sethelp/append pickpocketing,Thievery,is_thief, is_staff) = This steals ...
|
|
@sethelp/append pickpocketing, ,is_thief, is_staff) = This steals ...
|
|
|
|
"""
|
|
key = "@sethelp"
|
|
permissions = "cmd:sethelp"
|
|
help_category = "Building"
|
|
|
|
def func(self):
|
|
"Implement the function"
|
|
|
|
caller = self.caller
|
|
switches = self.switches
|
|
lhslist = self.lhslist
|
|
rhs = self.rhs
|
|
|
|
if not self.rhs:
|
|
caller.msg("Usage: @sethelp/[add|del|append|merge] <topic>[,category[,permission,..] = <text>]")
|
|
return
|
|
|
|
topicstr = ""
|
|
category = ""
|
|
permissions = ""
|
|
try:
|
|
topicstr = lhslist[0]
|
|
category = lhslist[1]
|
|
permissions = ",".join(lhslist[2:])
|
|
except Exception:
|
|
pass
|
|
if not topicstr:
|
|
caller.msg("You have to define a topic!")
|
|
return
|
|
string = ""
|
|
print topicstr, category, permissions
|
|
|
|
if switches and switches[0] in ('append', 'app','merge'):
|
|
# add text to the end of a help topic
|
|
# find the topic to append to
|
|
old_entry = None
|
|
try:
|
|
old_entry = HelpEntry.objects.get(key=topicstr)
|
|
except Exception:
|
|
pass
|
|
if not old_entry:
|
|
string = "Could not find topic '%s'. You must give an exact name." % topicstr
|
|
else:
|
|
entrytext = old_entry.entrytext
|
|
if switches[0] == 'merge':
|
|
old_entry.entrytext = "%s %s" % (entrytext, self.rhs)
|
|
string = "Added the new text right after the old one (merge)."
|
|
else:
|
|
old_entry.entrytext = "%s\n\n%s" % (entrytext, self.rhs)
|
|
string = "Added the new text as a new paragraph after the old one (append)"
|
|
old_entry.save()
|
|
|
|
elif switches and switches[0] in ('delete','del'):
|
|
#delete a help entry
|
|
old_entry = None
|
|
try:
|
|
old_entry = HelpEntry.objects.get(key=topicstr)
|
|
except Exception:
|
|
pass
|
|
if not old_entry:
|
|
string = "Could not find topic. You must give an exact name."
|
|
else:
|
|
old_entry.delete()
|
|
string = "Deleted the help entry '%s'." % topicstr
|
|
|
|
else:
|
|
# add a new help entry.
|
|
force_create = ('for' in switches) or ('force' in switches)
|
|
old_entry = None
|
|
try:
|
|
old_entry = HelpEntry.objects.get(key=topicstr)
|
|
except Exception:
|
|
pass
|
|
if old_entry:
|
|
if force_create:
|
|
old_entry.key = topicstr
|
|
old_entry.entrytext = self.rhs
|
|
old_entry.help_category = category
|
|
old_entry.permissions = permissions
|
|
old_entry.save()
|
|
string = "Overwrote the old topic '%s' with a new one." % topicstr
|
|
else:
|
|
string = "Topic '%s' already exists. Use /force to overwrite it." % topicstr
|
|
else:
|
|
# no old entry. Create a new one.
|
|
new_entry = create.create_help_entry(topicstr,
|
|
rhs, category, permissions)
|
|
if new_entry:
|
|
string = "Topic '%s' was successfully created." % topicstr
|
|
else:
|
|
string = "Error when creating topic '%s'! Maybe it already exists?" % topicstr
|
|
|
|
# give feedback
|
|
caller.msg(string)
|