From 2d53d75aea978efafa3ae3210445d0361b20ba05 Mon Sep 17 00:00:00 2001
From: Griatch
Date: Mon, 19 Oct 2020 22:46:24 +0200
Subject: [PATCH] Updated HTML docs
---
docs/0.9.5/.buildinfo | 2 +-
.../_modules/evennia/accounts/accounts.html | 28 +-
.../_modules/evennia/commands/command.html | 23 +-
.../evennia/commands/default/help.html | 235 +-
.../evennia/commands/default/system.html | 4 +-
.../evennia/commands/default/tests.html | 15 +-
.../evennia/commands/default/unloggedin.html | 1 +
.../_modules/evennia/contrib/rpsystem.html | 3 +-
.../evennia/contrib/turnbattle/tb_range.html | 1 -
.../contrib/tutorial_world/intro_menu.html | 5 +-
.../evennia/contrib/tutorial_world/mob.html | 13 +-
.../contrib/tutorial_world/objects.html | 20 +-
docs/0.9.5/_modules/evennia/help/models.html | 16 +-
.../_modules/evennia/locks/lockfuncs.html | 5 -
.../_modules/evennia/objects/models.html | 47 +-
.../_modules/evennia/objects/objects.html | 128 +-
.../_modules/evennia/server/amp_client.html | 4 +-
.../_modules/evennia/server/inputfuncs.html | 1 -
.../_modules/evennia/server/portal/amp.html | 2 +-
.../evennia/server/portal/amp_server.html | 5 +-
.../evennia/server/portal/portal.html | 21 +-
.../server/portal/portalsessionhandler.html | 24 +-
.../_modules/evennia/server/portal/ssh.html | 25 +-
.../_modules/evennia/server/portal/ssl.html | 6 +-
.../evennia/server/portal/telnet.html | 32 +-
.../evennia/server/portal/telnet_oob.html | 32 +-
.../evennia/server/portal/webclient.html | 10 +-
.../profiling/dummyrunner_settings.html | 18 +-
.../0.9.5/_modules/evennia/server/server.html | 36 +-
.../evennia/server/serversession.html | 137 +-
.../_modules/evennia/server/session.html | 26 +-
.../evennia/server/sessionhandler.html | 93 +-
.../evennia/typeclasses/attributes.html | 1111 ++++++---
.../evennia/typeclasses/managers.html | 24 +-
.../_modules/evennia/typeclasses/models.html | 197 +-
.../_modules/evennia/typeclasses/tags.html | 34 +
docs/0.9.5/_modules/evennia/utils/ansi.html | 65 +-
.../evennia/utils/batchprocessors.html | 148 +-
docs/0.9.5/_modules/evennia/utils/create.html | 35 +-
.../_modules/evennia/utils/dbserialize.html | 2 +-
.../_modules/evennia/utils/eveditor.html | 74 +-
docs/0.9.5/_modules/evennia/utils/evform.html | 69 +-
docs/0.9.5/_modules/evennia/utils/evmenu.html | 234 +-
docs/0.9.5/_modules/evennia/utils/evmore.html | 163 +-
.../0.9.5/_modules/evennia/utils/evtable.html | 52 +-
.../_modules/evennia/utils/inlinefuncs.html | 45 +-
.../_modules/evennia/utils/optionclasses.html | 14 +-
.../_modules/evennia/utils/picklefield.html | 2 +-
docs/0.9.5/_modules/evennia/utils/search.html | 1 +
.../evennia/utils/test_resources.html | 20 +-
docs/0.9.5/_modules/evennia/utils/utils.html | 328 ++-
.../evennia/utils/validatorfuncs.html | 4 +-
docs/0.9.5/api/evennia-api.html | 10 +-
docs/0.9.5/api/evennia.accounts.accounts.html | 88 +
docs/0.9.5/api/evennia.commands.command.html | 16 +-
.../api/evennia.commands.default.account.html | 65 +
.../api/evennia.commands.default.admin.html | 42 +-
...evennia.commands.default.batchprocess.html | 10 +
.../evennia.commands.default.building.html | 138 +-
.../api/evennia.commands.default.comms.html | 84 +-
.../api/evennia.commands.default.general.html | 64 +-
.../api/evennia.commands.default.help.html | 12 +-
.../evennia.commands.default.muxcommand.html | 10 +
.../evennia.commands.default.syscommands.html | 20 +
.../api/evennia.commands.default.system.html | 52 +-
.../api/evennia.commands.default.tests.html | 17 +
.../evennia.commands.default.unloggedin.html | 33 +-
.../api/evennia.comms.channelhandler.html | 5 +
docs/0.9.5/api/evennia.contrib.barter.html | 47 +-
.../api/evennia.contrib.building_menu.html | 15 +
docs/0.9.5/api/evennia.contrib.chargen.html | 10 +
docs/0.9.5/api/evennia.contrib.clothing.html | 37 +-
docs/0.9.5/api/evennia.contrib.dice.html | 5 +
.../api/evennia.contrib.email_login.html | 33 +-
.../api/evennia.contrib.extended_room.html | 20 +
docs/0.9.5/api/evennia.contrib.fieldfill.html | 5 +
docs/0.9.5/api/evennia.contrib.gendersub.html | 5 +
...vennia.contrib.ingame_python.commands.html | 7 +-
docs/0.9.5/api/evennia.contrib.mail.html | 10 +
.../0.9.5/api/evennia.contrib.mapbuilder.html | 5 +
.../0.9.5/api/evennia.contrib.menu_login.html | 5 +
.../api/evennia.contrib.multidescer.html | 5 +
docs/0.9.5/api/evennia.contrib.puzzles.html | 30 +
docs/0.9.5/api/evennia.contrib.rpsystem.html | 42 +-
.../0.9.5/api/evennia.contrib.simpledoor.html | 10 +
docs/0.9.5/api/evennia.contrib.slow_exit.html | 10 +
.../api/evennia.contrib.talking_npc.html | 5 +
.../api/evennia.contrib.tree_select.html | 5 +
.../evennia.contrib.turnbattle.tb_basic.html | 32 +-
.../evennia.contrib.turnbattle.tb_equip.html | 52 +-
.../evennia.contrib.turnbattle.tb_items.html | 37 +-
.../evennia.contrib.turnbattle.tb_magic.html | 47 +-
.../evennia.contrib.turnbattle.tb_range.html | 52 +-
...b.tutorial_examples.cmdset_red_button.html | 41 +-
.../evennia.contrib.tutorial_world.mob.html | 7 +-
...vennia.contrib.tutorial_world.objects.html | 103 +-
.../evennia.contrib.tutorial_world.rooms.html | 64 +-
.../api/evennia.contrib.unixcommand.html | 5 +
docs/0.9.5/api/evennia.help.models.html | 6 +
docs/0.9.5/api/evennia.html | 10 +-
docs/0.9.5/api/evennia.objects.models.html | 18 +-
docs/0.9.5/api/evennia.objects.objects.html | 79 +-
...ia.server.portal.portalsessionhandler.html | 11 +
docs/0.9.5/api/evennia.server.portal.ssh.html | 18 +-
.../api/evennia.server.portal.telnet.html | 20 +-
.../api/evennia.server.portal.telnet_oob.html | 31 +-
...server.profiling.dummyrunner_settings.html | 32 +-
docs/0.9.5/api/evennia.server.server.html | 30 +-
.../api/evennia.server.serversession.html | 139 +-
.../api/evennia.server.sessionhandler.html | 51 +-
docs/0.9.5/api/evennia.server.signals.html | 20 +-
.../api/evennia.typeclasses.attributes.html | 903 ++++++--
.../api/evennia.typeclasses.managers.html | 18 +-
.../0.9.5/api/evennia.typeclasses.models.html | 102 +-
docs/0.9.5/api/evennia.typeclasses.tags.html | 27 +
docs/0.9.5/api/evennia.utils.ansi.html | 54 +-
.../api/evennia.utils.batchprocessors.html | 137 +-
docs/0.9.5/api/evennia.utils.create.html | 33 +-
docs/0.9.5/api/evennia.utils.dbserialize.html | 2 +-
docs/0.9.5/api/evennia.utils.eveditor.html | 96 +-
docs/0.9.5/api/evennia.utils.evform.html | 11 +-
docs/0.9.5/api/evennia.utils.evmenu.html | 203 +-
docs/0.9.5/api/evennia.utils.evmore.html | 162 +-
docs/0.9.5/api/evennia.utils.evtable.html | 28 +-
docs/0.9.5/api/evennia.utils.html | 10 +-
docs/0.9.5/api/evennia.utils.inlinefuncs.html | 40 +-
.../api/evennia.utils.optionclasses.html | 6 +-
docs/0.9.5/api/evennia.utils.search.html | 30 +
.../api/evennia.utils.test_resources.html | 1 -
docs/0.9.5/api/evennia.utils.utils.html | 245 +-
.../api/evennia.utils.validatorfuncs.html | 2 +-
docs/0.9.5/genindex.html | 782 ++++++-
docs/0.9.5/objects.inv | Bin 71922 -> 73236 bytes
docs/0.9.5/searchindex.js | 2 +-
docs/1.0-dev/.buildinfo | 2 +-
docs/1.0-dev/Coding/Coding-Overview.html | 22 +-
.../Components/Components-Overview.html | 22 +-
docs/1.0-dev/Concepts/Concepts-Overview.html | 22 +-
docs/1.0-dev/Contribs/Contrib-Overview.html | 22 +-
docs/1.0-dev/Evennia-API.html | 23 +-
docs/1.0-dev/Evennia-Introduction.html | 22 +-
docs/1.0-dev/How-To-Get-And-Give-Help.html | 22 +-
docs/1.0-dev/Howto/Howto-Overview.html | 22 +-
.../Howto/Starting/Part1/Adding-Commands.html | 52 +-
.../Starting/Part1/Building-Quickstart.html | 76 +-
.../Howto/Starting/Part1/Creating-Things.html | 44 +-
.../Howto/Starting/Part1/Django-queries.html | 64 +-
.../Part1/Evennia-Library-Overview.html | 44 +-
.../Starting/Part1/Gamedir-Overview.html | 64 +-
.../Starting/Part1/Learning-Typeclasses.html | 88 +-
.../Starting/Part1/More-on-Commands.html | 64 +-
.../Part1/Python-basic-introduction.html | 84 +-
.../Part1/Python-classes-and-objects.html | 60 +-
.../Starting/Part1/Searching-Things.html | 84 +-
.../Howto/Starting/Part1/Starting-Part1.html | 57 +-
.../Part1/Tutorial-World-Introduction.html | 52 +-
.../Howto/Starting/Part2/Game-Planning.html | 30 +-
.../Part2/Planning-Some-Useful-Contribs.html | 30 +-
.../Part2/Planning-The-Tutorial-Game.html | 4 +-
.../Part2/Planning-Where-Do-I-Begin.html | 30 +-
.../Howto/Starting/Part2/Starting-Part2.html | 26 +-
.../Howto/Starting/Part3/Starting-Part3.html | 30 +-
.../Howto/Starting/Part4/Starting-Part4.html | 1 +
.../Howto/Starting/Part5/Starting-Part5.html | 1 +
docs/1.0-dev/Links.html | 12 +-
docs/1.0-dev/Setup/Setup-Overview.html | 22 +-
docs/1.0-dev/Setup/Setup-Quickstart.html | 22 +-
docs/1.0-dev/Unimplemented.html | 35 +-
.../_modules/django/db/models/query.html | 1988 +++++++++++++++++
.../_modules/django/utils/deconstruct.html | 146 ++
.../_modules/evennia/accounts/accounts.html | 28 +-
.../_modules/evennia/commands/command.html | 23 +-
.../evennia/commands/default/help.html | 235 +-
.../evennia/commands/default/system.html | 4 +-
.../evennia/commands/default/tests.html | 15 +-
.../evennia/commands/default/unloggedin.html | 1 +
.../contrib/awsstorage/aws_s3_cdn.html | 956 ++++++++
.../evennia/contrib/awsstorage/tests.html | 694 ++++++
.../_modules/evennia/contrib/rpsystem.html | 3 +-
.../_modules/evennia/contrib/test_traits.html | 998 +++++++++
.../_modules/evennia/contrib/traits.html | 1495 +++++++++++++
.../evennia/contrib/turnbattle/tb_range.html | 1 -
.../contrib/tutorial_examples/mirror.html | 155 ++
.../contrib/tutorial_world/intro_menu.html | 5 +-
.../evennia/contrib/tutorial_world/mob.html | 13 +-
.../contrib/tutorial_world/objects.html | 20 +-
.../1.0-dev/_modules/evennia/help/models.html | 16 +-
.../_modules/evennia/locks/lockfuncs.html | 5 -
.../_modules/evennia/objects/models.html | 47 +-
.../_modules/evennia/objects/objects.html | 128 +-
.../_modules/evennia/server/amp_client.html | 4 +-
.../_modules/evennia/server/inputfuncs.html | 1 -
.../_modules/evennia/server/portal/amp.html | 2 +-
.../evennia/server/portal/amp_server.html | 5 +-
.../evennia/server/portal/portal.html | 21 +-
.../server/portal/portalsessionhandler.html | 24 +-
.../_modules/evennia/server/portal/ssh.html | 25 +-
.../_modules/evennia/server/portal/ssl.html | 6 +-
.../evennia/server/portal/telnet.html | 32 +-
.../evennia/server/portal/telnet_oob.html | 32 +-
.../evennia/server/portal/webclient.html | 10 +-
.../profiling/dummyrunner_settings.html | 18 +-
.../_modules/evennia/server/server.html | 36 +-
.../evennia/server/serversession.html | 137 +-
.../_modules/evennia/server/session.html | 26 +-
.../evennia/server/sessionhandler.html | 93 +-
.../evennia/typeclasses/attributes.html | 1111 ++++++---
.../evennia/typeclasses/managers.html | 24 +-
.../_modules/evennia/typeclasses/models.html | 197 +-
.../_modules/evennia/typeclasses/tags.html | 34 +
docs/1.0-dev/_modules/evennia/utils/ansi.html | 65 +-
.../evennia/utils/batchprocessors.html | 148 +-
.../_modules/evennia/utils/create.html | 35 +-
.../_modules/evennia/utils/dbserialize.html | 2 +-
.../_modules/evennia/utils/eveditor.html | 74 +-
.../_modules/evennia/utils/evform.html | 69 +-
.../_modules/evennia/utils/evmenu.html | 234 +-
.../_modules/evennia/utils/evmore.html | 163 +-
.../_modules/evennia/utils/evtable.html | 52 +-
.../_modules/evennia/utils/inlinefuncs.html | 45 +-
.../_modules/evennia/utils/optionclasses.html | 14 +-
.../_modules/evennia/utils/picklefield.html | 2 +-
.../_modules/evennia/utils/search.html | 1 +
.../evennia/utils/test_resources.html | 20 +-
.../1.0-dev/_modules/evennia/utils/utils.html | 328 ++-
.../evennia/utils/validatorfuncs.html | 4 +-
.../_modules/evennia/web/api/filters.html | 216 ++
.../_modules/evennia/web/api/permissions.html | 179 ++
.../_modules/evennia/web/api/serializers.html | 322 +++
.../_modules/evennia/web/api/tests.html | 263 +++
.../_modules/evennia/web/api/views.html | 216 ++
docs/1.0-dev/_modules/index.html | 13 +
.../1.0-dev/_modules/rest_framework/test.html | 487 ++++
docs/1.0-dev/_sources/Evennia-API.md.txt | 3 +-
.../Starting/Part1/Adding-Commands.md.txt | 6 +-
.../Starting/Part1/Building-Quickstart.md.txt | 4 -
.../Starting/Part1/Creating-Things.md.txt | 4 -
.../Starting/Part1/Django-queries.md.txt | 4 -
.../Part1/Evennia-Library-Overview.md.txt | 3 -
.../Starting/Part1/Gamedir-Overview.md.txt | 3 -
.../Part1/Learning-Typeclasses.md.txt | 3 -
.../Starting/Part1/More-on-Commands.md.txt | 3 -
.../Part1/Python-basic-introduction.md.txt | 3 -
.../Part1/Python-classes-and-objects.md.txt | 3 -
.../Starting/Part1/Searching-Things.md.txt | 4 -
.../Starting/Part1/Starting-Part1.md.txt | 52 +-
.../Part1/Tutorial-World-Introduction.md.txt | 4 -
.../Howto/Starting/Part2/Game-Planning.md.txt | 3 -
.../Planning-Some-Useful-Contribs.md.txt | 3 -
.../Part2/Planning-The-Tutorial-Game.md.txt | 4 -
.../Part2/Planning-Where-Do-I-Begin.md.txt | 4 -
.../Starting/Part2/Starting-Part2.md.txt | 13 +-
.../Starting/Part3/Starting-Part3.md.txt | 13 +-
.../Starting/Part4/Starting-Part4.md.txt | 4 +-
.../Starting/Part5/Starting-Part5.md.txt | 1 +
docs/1.0-dev/_sources/Unimplemented.md.txt | 5 +-
docs/1.0-dev/_sources/index.md.txt | 19 +
docs/1.0-dev/api/evennia-api.html | 28 +-
.../api/evennia.accounts.accounts.html | 88 +
.../1.0-dev/api/evennia.commands.command.html | 16 +-
.../api/evennia.commands.default.account.html | 67 +-
.../api/evennia.commands.default.admin.html | 42 +-
...evennia.commands.default.batchprocess.html | 10 +
.../evennia.commands.default.building.html | 134 +-
.../api/evennia.commands.default.comms.html | 82 +-
.../api/evennia.commands.default.general.html | 66 +-
.../api/evennia.commands.default.help.html | 12 +-
.../evennia.commands.default.muxcommand.html | 10 +
.../evennia.commands.default.syscommands.html | 20 +
.../api/evennia.commands.default.system.html | 54 +-
.../api/evennia.commands.default.tests.html | 17 +
.../evennia.commands.default.unloggedin.html | 31 +-
.../api/evennia.comms.channelhandler.html | 5 +
...evennia.contrib.awsstorage.aws_s3_cdn.html | 467 +++-
.../api/evennia.contrib.awsstorage.html | 1 +
.../api/evennia.contrib.awsstorage.tests.html | 221 +-
docs/1.0-dev/api/evennia.contrib.barter.html | 45 +
.../api/evennia.contrib.building_menu.html | 15 +
docs/1.0-dev/api/evennia.contrib.chargen.html | 12 +-
.../1.0-dev/api/evennia.contrib.clothing.html | 35 +
docs/1.0-dev/api/evennia.contrib.dice.html | 5 +
.../api/evennia.contrib.email_login.html | 31 +-
.../api/evennia.contrib.extended_room.html | 22 +-
.../api/evennia.contrib.fieldfill.html | 5 +
.../api/evennia.contrib.gendersub.html | 5 +
docs/1.0-dev/api/evennia.contrib.html | 18 +-
...vennia.contrib.ingame_python.commands.html | 5 +
docs/1.0-dev/api/evennia.contrib.mail.html | 10 +
.../api/evennia.contrib.mapbuilder.html | 5 +
.../api/evennia.contrib.menu_login.html | 5 +
.../api/evennia.contrib.multidescer.html | 5 +
docs/1.0-dev/api/evennia.contrib.puzzles.html | 30 +
.../1.0-dev/api/evennia.contrib.rpsystem.html | 42 +-
.../api/evennia.contrib.simpledoor.html | 10 +
.../api/evennia.contrib.slow_exit.html | 10 +
.../api/evennia.contrib.talking_npc.html | 5 +
.../api/evennia.contrib.test_traits.html | 402 +++-
docs/1.0-dev/api/evennia.contrib.traits.html | 824 ++++++-
.../api/evennia.contrib.tree_select.html | 5 +
.../evennia.contrib.turnbattle.tb_basic.html | 32 +-
.../evennia.contrib.turnbattle.tb_equip.html | 52 +-
.../evennia.contrib.turnbattle.tb_items.html | 37 +-
.../evennia.contrib.turnbattle.tb_magic.html | 47 +-
.../evennia.contrib.turnbattle.tb_range.html | 52 +-
...b.tutorial_examples.cmdset_red_button.html | 43 +-
...nnia.contrib.tutorial_examples.mirror.html | 75 +-
.../evennia.contrib.tutorial_world.mob.html | 7 +-
...vennia.contrib.tutorial_world.objects.html | 101 +-
.../evennia.contrib.tutorial_world.rooms.html | 66 +-
.../api/evennia.contrib.unixcommand.html | 5 +
docs/1.0-dev/api/evennia.help.models.html | 6 +
docs/1.0-dev/api/evennia.html | 28 +-
docs/1.0-dev/api/evennia.objects.models.html | 18 +-
docs/1.0-dev/api/evennia.objects.objects.html | 79 +-
...ia.server.portal.portalsessionhandler.html | 11 +
.../api/evennia.server.portal.ssh.html | 18 +-
.../api/evennia.server.portal.telnet.html | 20 +-
.../api/evennia.server.portal.telnet_oob.html | 31 +-
...server.profiling.dummyrunner_settings.html | 32 +-
docs/1.0-dev/api/evennia.server.server.html | 30 +-
.../api/evennia.server.serversession.html | 139 +-
.../api/evennia.server.sessionhandler.html | 51 +-
docs/1.0-dev/api/evennia.server.signals.html | 20 +-
.../api/evennia.typeclasses.attributes.html | 903 ++++++--
.../api/evennia.typeclasses.managers.html | 18 +-
.../api/evennia.typeclasses.models.html | 102 +-
.../1.0-dev/api/evennia.typeclasses.tags.html | 27 +
docs/1.0-dev/api/evennia.utils.ansi.html | 54 +-
.../api/evennia.utils.batchprocessors.html | 137 +-
docs/1.0-dev/api/evennia.utils.create.html | 33 +-
.../api/evennia.utils.dbserialize.html | 2 +-
docs/1.0-dev/api/evennia.utils.eveditor.html | 96 +-
docs/1.0-dev/api/evennia.utils.evform.html | 11 +-
docs/1.0-dev/api/evennia.utils.evmenu.html | 203 +-
docs/1.0-dev/api/evennia.utils.evmore.html | 162 +-
docs/1.0-dev/api/evennia.utils.evtable.html | 28 +-
docs/1.0-dev/api/evennia.utils.html | 10 +-
.../api/evennia.utils.inlinefuncs.html | 40 +-
.../api/evennia.utils.optionclasses.html | 6 +-
docs/1.0-dev/api/evennia.utils.search.html | 30 +
.../api/evennia.utils.test_resources.html | 1 -
docs/1.0-dev/api/evennia.utils.utils.html | 245 +-
.../api/evennia.utils.validatorfuncs.html | 2 +-
docs/1.0-dev/api/evennia.web.api.filters.html | 198 +-
.../api/evennia.web.api.permissions.html | 99 +-
.../api/evennia.web.api.serializers.html | 292 ++-
docs/1.0-dev/api/evennia.web.api.tests.html | 70 +-
docs/1.0-dev/api/evennia.web.api.urls.html | 18 +-
docs/1.0-dev/api/evennia.web.api.views.html | 300 ++-
docs/1.0-dev/genindex.html | 1721 +++++++++++++-
docs/1.0-dev/index.html | 14 +-
docs/1.0-dev/objects.inv | Bin 74551 -> 78710 bytes
docs/1.0-dev/py-modindex.html | 55 +
docs/1.0-dev/searchindex.js | 2 +-
docs/1.0-dev/toc.html | 24 +-
355 files changed, 24586 insertions(+), 5844 deletions(-)
create mode 100644 docs/1.0-dev/_modules/django/db/models/query.html
create mode 100644 docs/1.0-dev/_modules/django/utils/deconstruct.html
create mode 100644 docs/1.0-dev/_modules/evennia/contrib/awsstorage/aws_s3_cdn.html
create mode 100644 docs/1.0-dev/_modules/evennia/contrib/awsstorage/tests.html
create mode 100644 docs/1.0-dev/_modules/evennia/contrib/test_traits.html
create mode 100644 docs/1.0-dev/_modules/evennia/contrib/traits.html
create mode 100644 docs/1.0-dev/_modules/evennia/contrib/tutorial_examples/mirror.html
create mode 100644 docs/1.0-dev/_modules/evennia/web/api/filters.html
create mode 100644 docs/1.0-dev/_modules/evennia/web/api/permissions.html
create mode 100644 docs/1.0-dev/_modules/evennia/web/api/serializers.html
create mode 100644 docs/1.0-dev/_modules/evennia/web/api/tests.html
create mode 100644 docs/1.0-dev/_modules/evennia/web/api/views.html
create mode 100644 docs/1.0-dev/_modules/rest_framework/test.html
diff --git a/docs/0.9.5/.buildinfo b/docs/0.9.5/.buildinfo
index 09c5021c47..faf79d3291 100644
--- a/docs/0.9.5/.buildinfo
+++ b/docs/0.9.5/.buildinfo
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: 75efcd5cc8712eff6ba9e68cfd2962a8
+config: b3d6691cbcfd884f2c512e34b39ac37e
tags: 645f666f9bcd5a90fca523b33c5a78b7
diff --git a/docs/0.9.5/_modules/evennia/accounts/accounts.html b/docs/0.9.5/_modules/evennia/accounts/accounts.html
index e5db96d662..9639b85792 100644
--- a/docs/0.9.5/_modules/evennia/accounts/accounts.html
+++ b/docs/0.9.5/_modules/evennia/accounts/accounts.html
@@ -73,7 +73,7 @@
SIGNAL_OBJECT_POST_PUPPET,
SIGNAL_OBJECT_POST_UNPUPPET,
)
-from evennia.typeclasses.attributes import NickHandler
+from evennia.typeclasses.attributes import NickHandler, ModelAttributeBackend
from evennia.scripts.scripthandler import ScriptHandler
from evennia.commands.cmdsethandler import CmdSetHandler
from evennia.utils.optionhandler import OptionHandler
@@ -81,7 +81,7 @@
from django.utils.translation import gettext as _
from random import getrandbits
-__all__ = ("DefaultAccount",)
+__all__ = ("DefaultAccount", "DefaultGuest")
_SESSIONS = None
@@ -240,7 +240,7 @@
[docs] @lazy_property
def nicks(self):
-
return NickHandler(self)
+ return NickHandler(self, ModelAttributeBackend)
[docs] @lazy_property
def sessions(self):
@@ -1588,21 +1588,21 @@
return look_string
-class DefaultGuest(DefaultAccount):
+[docs]class DefaultGuest(DefaultAccount):
"""
This class is used for guest logins. Unlike Accounts, Guests and
their characters are deleted after disconnection.
"""
-
@classmethod
+
[docs] @classmethod
def create(cls, **kwargs):
"""
Forwards request to cls.authenticate(); returns a DefaultGuest object
if one is available for use.
"""
-
return cls.authenticate(**kwargs)
+
return cls.authenticate(**kwargs)
-
@classmethod
+
[docs] @classmethod
def authenticate(cls, **kwargs):
"""
Gets or creates a Guest account object.
@@ -1674,9 +1674,9 @@
logger.log_trace()
return None, errors
-
return account, errors
+
return account, errors
-
def at_post_login(self, session=None, **kwargs):
+
[docs] def at_post_login(self, session=None, **kwargs):
"""
In theory, guests only have one character regardless of which
MULTISESSION_MODE we're in. They don't get a choice.
@@ -1688,9 +1688,9 @@
"""
self._send_to_connect_channel(_("|G{key} connected|n").format(key=self.key))
-
self.puppet_object(session, self.db._last_puppet)
+
self.puppet_object(session, self.db._last_puppet)
-
def at_server_shutdown(self):
+
[docs] def at_server_shutdown(self):
"""
We repeat the functionality of `at_disconnect()` here just to
be on the safe side.
@@ -1699,9 +1699,9 @@
characters = self.db._playable_characters
for character in characters:
if character:
-
character.delete()
+
character.delete()
-
def at_post_disconnect(self, **kwargs):
+
[docs] def at_post_disconnect(self, **kwargs):
"""
Once having disconnected, destroy the guest's characters and
@@ -1715,7 +1715,7 @@
for character in characters:
if character:
character.delete()
-
self.delete()
+
self.delete()
diff --git a/docs/0.9.5/_modules/evennia/commands/command.html b/docs/0.9.5/_modules/evennia/commands/command.html
index f61a95c9f0..2a9dac9b0c 100644
--- a/docs/0.9.5/_modules/evennia/commands/command.html
+++ b/docs/0.9.5/_modules/evennia/commands/command.html
@@ -125,6 +125,15 @@
break
cls.help_category = cls.help_category.lower()
+ # pre-prepare a help index entry for quicker lookup
+ cls.search_index_entry = {
+ "key": cls.key,
+ "aliases": " ".join(cls.aliases),
+ "category": cls.help_category,
+ "text": cls.__doc__,
+ "tags": "",
+ }
+
-
-[docs] def client_height(self):
-
"""
-
Get the client screenheight for the session using this command.
-
-
Returns:
-
client height (int): The height (in characters) of the client window.
-
-
"""
-
if self.session:
-
return self.session.protocol_flags.get(
-
"SCREENHEIGHT", {0: settings.CLIENT_DEFAULT_HEIGHT}
-
)[0]
-
return settings.CLIENT_DEFAULT_HEIGHT
[docs] def styled_table(self, *args, **kwargs):
"""
diff --git a/docs/0.9.5/_modules/evennia/commands/default/help.html b/docs/0.9.5/_modules/evennia/commands/default/help.html
index 16aa771d2d..52acd8c9d1 100644
--- a/docs/0.9.5/_modules/evennia/commands/default/help.html
+++ b/docs/0.9.5/_modules/evennia/commands/default/help.html
@@ -53,8 +53,14 @@
from evennia.commands.command import Command
from evennia.help.models import HelpEntry
from evennia.utils import create, evmore
+
from evennia.utils.ansi import ANSIString
from evennia.utils.eveditor import EvEditor
-
from evennia.utils.utils import string_suggestions, class_from_module
+
from evennia.utils.utils import (
+
string_suggestions,
+
class_from_module,
+
inherits_from,
+
format_grid,
+
)
COMMAND_DEFAULT_CLASS = class_from_module(settings.COMMAND_DEFAULT_CLASS)
HELP_MORE = settings.HELP_MORE
@@ -65,6 +71,71 @@
_DEFAULT_WIDTH = settings.CLIENT_DEFAULT_WIDTH
_SEP = "|C" + "-" * _DEFAULT_WIDTH + "|n"
+
_LUNR = None
+
_LUNR_EXCEPTION = None
+
+
+
class HelpCategory:
+
def __init__(self, key):
+
self.key = key
+
+
@property
+
def search_index_entry(self):
+
return {
+
"key": str(self),
+
"aliases": "",
+
"category": self.key,
+
"tags": "",
+
"text": "",
+
}
+
+
def __str__(self):
+
return f"Category: {self.key}"
+
+
def __eq__(self, other):
+
return str(self).lower() == str(other).lower()
+
+
def __hash__(self):
+
return id(self)
+
+
+
def help_search_with_index(query, candidate_entries, suggestion_maxnum=5):
+
"""
+
Lunr-powered fast index search and suggestion wrapper
+
"""
+
global _LUNR, _LUNR_EXCEPTION
+
if not _LUNR:
+
# we have to delay-load lunr because it messes with logging if it's imported
+
# before twisted's logging has been set up
+
from lunr import lunr as _LUNR
+
from lunr.exceptions import QueryParseError as _LUNR_EXCEPTION
+
+
indx = [cnd.search_index_entry for cnd in candidate_entries]
+
mapping = {indx[ix]["key"]: cand for ix, cand in enumerate(candidate_entries)}
+
+
search_index = _LUNR(
+
ref="key",
+
fields=[
+
{"field_name": "key", "boost": 10},
+
{"field_name": "aliases", "boost": 9},
+
{"field_name": "category", "boost": 8},
+
{"field_name": "tags", "boost": 5},
+
{"field_name": "text", "boost": 1},
+
],
+
documents=indx,
+
)
+
try:
+
matches = search_index.search(query)[:suggestion_maxnum]
+
except _LUNR_EXCEPTION:
+
# this is a user-input problem
+
matches = []
+
+
# matches (objs), suggestions (strs)
+
return (
+
[mapping[match["ref"]] for match in matches],
+
[str(match["ref"]) for match in matches], # + f" (score {match['score']})") # good debug
+
)
+
[docs]class CmdHelp(Command):
"""
@@ -108,7 +179,7 @@
if type(self).help_more:
usemore = True
-
if self.session and self.session.protocol_key in ("websocket", "ajax/comet"):
+
if self.session and self.session.protocol_key in ("websocket", "ajax/comet",):
try:
options = self.account.db._saved_webclient_options
if options and options["helppopup"]:
@@ -152,30 +223,34 @@
string += "\n" + _SEP
return string
-
[docs] def check_show_help(self, cmd, caller):
"""
@@ -216,7 +291,7 @@
False: the command shouldn't appear in the table.
"""
-
return cmd.access(caller, "view", default=True)
+
return True
[docs] def parse(self):
"""
@@ -249,8 +324,8 @@
]
all_categories = list(
set(
-
[cmd.help_category.lower() for cmd in all_cmds]
-
+ [topic.help_category.lower() for topic in all_topics]
+
[HelpCategory(cmd.help_category) for cmd in all_cmds]
+
+ [HelpCategory(topic.help_category) for topic in all_topics]
)
)
@@ -271,78 +346,51 @@
self.msg_help(self.format_help_list(hdict_cmd, hdict_topic))
return
-
# Try to access a particular command
+
# Try to access a particular help entry or category
+
entries = [cmd for cmd in all_cmds if cmd] + list(HelpEntry.objects.all()) + all_categories
-
# build vocabulary of suggestions and rate them by string similarity.
-
suggestions = None
-
if suggestion_maxnum > 0:
-
vocabulary = (
-
[cmd.key for cmd in all_cmds if cmd]
-
+ [topic.key for topic in all_topics]
-
+ all_categories
+
for match_query in [f"{query}~1", f"{query}*"]:
+
# We first do an exact word-match followed by a start-by query
+
matches, suggestions = help_search_with_index(
+
match_query, entries, suggestion_maxnum=self.suggestion_maxnum
)
-
[vocabulary.extend(cmd.aliases) for cmd in all_cmds]
-
suggestions = [
-
sugg
-
for sugg in string_suggestions(
-
query, set(vocabulary), cutoff=suggestion_cutoff, maxnum=suggestion_maxnum
-
)
-
if sugg != query
-
]
-
if not suggestions:
-
suggestions = [
-
sugg for sugg in vocabulary if sugg != query and sugg.startswith(query)
-
]
-
# try an exact command auto-help match
-
match = [cmd for cmd in all_cmds if cmd == query]
+
if matches:
+
match = matches[0]
+
if isinstance(match, HelpCategory):
+
formatted = self.format_help_list(
+
{
+
match.key: [
+
cmd.key
+
for cmd in all_cmds
+
if match.key.lower() == cmd.help_category
+
]
+
},
+
{
+
match.key: [
+
topic.key
+
for topic in all_topics
+
if match.key.lower() == topic.help_category
+
]
+
},
+
)
+
elif inherits_from(match, "evennia.commands.command.Command"):
+
formatted = self.format_help_entry(
+
match.key,
+
match.get_help(caller, cmdset),
+
aliases=match.aliases,
+
suggested=suggestions[1:],
+
)
+
else:
+
formatted = self.format_help_entry(
+
match.key,
+
match.entrytext,
+
aliases=match.aliases.all(),
+
suggested=suggestions[1:],
+
)
-
if not match:
-
# try an inexact match with prefixes stripped from query and cmds
-
_query = query[1:] if query[0] in CMD_IGNORE_PREFIXES else query
-
-
match = [
-
cmd
-
for cmd in all_cmds
-
for m in cmd._matchset
-
if m == _query or m[0] in CMD_IGNORE_PREFIXES and m[1:] == _query
-
]
-
-
if len(match) == 1:
-
cmd = match[0]
-
key = cmd.auto_help_display_key if hasattr(cmd, "auto_help_display_key") else cmd.key
-
formatted = self.format_help_entry(
-
key,
-
cmd.get_help(caller, cmdset),
-
aliases=cmd.aliases,
-
suggested=suggestions,
-
)
-
self.msg_help(formatted)
-
return
-
-
# try an exact database help entry match
-
match = list(HelpEntry.objects.find_topicmatch(query, exact=True))
-
if len(match) == 1:
-
formatted = self.format_help_entry(
-
match[0].key,
-
match[0].entrytext,
-
aliases=match[0].aliases.all(),
-
suggested=suggestions,
-
)
-
self.msg_help(formatted)
-
return
-
-
# try to see if a category name was entered
-
if query in all_categories:
-
self.msg_help(
-
self.format_help_list({
-
query: [
-
cmd.auto_help_display_key if hasattr(cmd, "auto_help_display_key") else cmd.key
-
for cmd in all_cmds if cmd.help_category == query]},
-
{query: [topic.key for topic in all_topics if topic.help_category == query]},
-
)
-
)
-
return
+
self.msg_help(formatted)
+
return
# no exact matches found. Just give suggestions.
self.msg(
@@ -423,7 +471,10 @@
self.msg("You have to define a topic!")
return
topicstrlist = topicstr.split(";")
-
topicstr, aliases = (topicstrlist[0], topicstrlist[1:] if len(topicstr) > 1 else [])
+
topicstr, aliases = (
+
topicstrlist[0],
+
topicstrlist[1:] if len(topicstr) > 1 else [],
+
)
aliastxt = ("(aliases: %s)" % ", ".join(aliases)) if aliases else ""
old_entry = None
@@ -452,7 +503,7 @@
helpentry = old_entry
else:
helpentry = create.create_help_entry(
-
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases
+
topicstr, self.rhs, category=category, locks=lockstring, aliases=aliases,
)
self.caller.db._editing_help = helpentry
diff --git a/docs/0.9.5/_modules/evennia/commands/default/system.html b/docs/0.9.5/_modules/evennia/commands/default/system.html
index e35f6ce014..0c236ad30b 100644
--- a/docs/0.9.5/_modules/evennia/commands/default/system.html
+++ b/docs/0.9.5/_modules/evennia/commands/default/system.html
@@ -434,7 +434,9 @@
if noecho:
prompt = "..." if console.push(line) else main_prompt
else:
-
prompt = line if console.push(line) else f"{line}\n{main_prompt}"
+
if line:
+
self.caller.msg(f">>> {line}")
+
prompt = line if console.push(line) else main_prompt
except SystemExit:
break
self.msg("|gClosing the Python console.|n")
diff --git a/docs/0.9.5/_modules/evennia/commands/default/tests.html b/docs/0.9.5/_modules/evennia/commands/default/tests.html
index 8c2cbbc737..34d17d8294 100644
--- a/docs/0.9.5/_modules/evennia/commands/default/tests.html
+++ b/docs/0.9.5/_modules/evennia/commands/default/tests.html
@@ -314,8 +314,21 @@
[docs]class TestHelp(CommandTest):
+
[docs] def setUp(self):
+
super().setUp()
+
# we need to set up a logger here since lunr takes over the logger otherwise
+
import logging
+
+
logging.basicConfig(level=logging.ERROR)
+
+
[docs] def tearDown(self):
+
super().tearDown()
+
import logging
+
+
logging.disable(level=logging.ERROR)
+
[docs] def test_help(self):
-
self.call(help.CmdHelp(), "", "Command help entries", cmdset=CharacterCmdSet())
+
self.call(help.CmdHelp(), "", "Admin", cmdset=CharacterCmdSet())
[docs] def test_set_help(self):
self.call(
diff --git a/docs/0.9.5/_modules/evennia/commands/default/unloggedin.html b/docs/0.9.5/_modules/evennia/commands/default/unloggedin.html
index 23b949ea3b..b4af40b12e 100644
--- a/docs/0.9.5/_modules/evennia/commands/default/unloggedin.html
+++ b/docs/0.9.5/_modules/evennia/commands/default/unloggedin.html
@@ -335,6 +335,7 @@
|wquit|n - abort the connection
First create an account e.g. with |wcreate Anna c67jHL8p|n
+
(If you have spaces in your name, use double quotes: |wcreate "Anna the Barbarian" c67jHL8p|n
Next you can connect to the game: |wconnect Anna c67jHL8p|n
You can use the |wlook|n command if you want to see the connect screen again.
diff --git a/docs/0.9.5/_modules/evennia/contrib/rpsystem.html b/docs/0.9.5/_modules/evennia/contrib/rpsystem.html
index ccf7a921d7..b8f7146d72 100644
--- a/docs/0.9.5/_modules/evennia/contrib/rpsystem.html
+++ b/docs/0.9.5/_modules/evennia/contrib/rpsystem.html
@@ -324,7 +324,8 @@
the markers and a tuple (langname, saytext), where
langname can be None.
Raises:
-
rplanguage.LanguageError: If an invalid language was specified.
+
evennia.contrib.rpsystem.LanguageError: If an invalid language was
+
specified.
Notes:
Note that no errors are raised if the wrong language identifier
diff --git a/docs/0.9.5/_modules/evennia/contrib/turnbattle/tb_range.html b/docs/0.9.5/_modules/evennia/contrib/turnbattle/tb_range.html
index e6043e86f9..ef167d79dc 100644
--- a/docs/0.9.5/_modules/evennia/contrib/turnbattle/tb_range.html
+++ b/docs/0.9.5/_modules/evennia/contrib/turnbattle/tb_range.html
@@ -683,7 +683,6 @@
Args:
to_init (object): Object to initialize range field for.
-
Keyword Args:
anchor_obj (object): Object to copy range values from, or None for a random object.
add_distance (int): Distance to put between to_init object and anchor object.
diff --git a/docs/0.9.5/_modules/evennia/contrib/tutorial_world/intro_menu.html b/docs/0.9.5/_modules/evennia/contrib/tutorial_world/intro_menu.html
index 706444a0b2..925f9a2599 100644
--- a/docs/0.9.5/_modules/evennia/contrib/tutorial_world/intro_menu.html
+++ b/docs/0.9.5/_modules/evennia/contrib/tutorial_world/intro_menu.html
@@ -473,8 +473,9 @@
and the main window.
- Use |y<Return>|n (or click the arrow on the right) to send your input.
-
- Use |yShift + <up/down-arrow>|n to step back and forth in your command-history.
-
- Use |yShift + <Return>|n to add a new line to your input without sending.
+
- Use |yCtrl + <up/down-arrow>|n to step back and forth in your command-history.
+
- Use |yCtrl + <Return>|n to add a new line to your input without sending.
+
(Cmd instead of Ctrl-key on Macs)
There is also some |wextra|n info to learn about customizing the webclient.
diff --git a/docs/0.9.5/_modules/evennia/contrib/tutorial_world/mob.html b/docs/0.9.5/_modules/evennia/contrib/tutorial_world/mob.html
index 4115af4819..8687437b25 100644
--- a/docs/0.9.5/_modules/evennia/contrib/tutorial_world/mob.html
+++ b/docs/0.9.5/_modules/evennia/contrib/tutorial_world/mob.html
@@ -110,7 +110,7 @@
stationary (idling) until attacked.
aggressive: if set, will attack Characters in
the same room using whatever Weapon it
-
carries (see tutorial_world.objects.Weapon).
+
carries (see tutorial_world.objects.TutorialWeapon).
if unset, the mob will never engage in combat
no matter what.
hunting: if set, the mob will pursue enemies trying
@@ -209,9 +209,9 @@
be "ticked".
Args:
-
interval (int): The number of seconds
+
interval (int or None): The number of seconds
between ticks
-
hook_key (str): The name of the method
+
hook_key (str or None): The name of the method
(on this mob) to call every interval
seconds.
stop (bool, optional): Just stop the
@@ -413,16 +413,11 @@
return
# we use the same attack commands as defined in
-
# tutorial_world.objects.Weapon, assuming that
+
# tutorial_world.objects.TutorialWeapon, assuming that
# the mob is given a Weapon to attack with.
attack_cmd = random.choice(("thrust", "pierce", "stab", "slash", "chop"))
self.execute_cmd("%s %s" % (attack_cmd, target))
-
if target.db.health is None:
-
# This is not an attackable target
-
logger.log_err(f"{self.key} found {target} had an `health` attribute of `None`.")
-
return
-
# analyze the current state
if target.db.health <= 0:
# we reduced the target to <= 0 health. Move them to the
diff --git a/docs/0.9.5/_modules/evennia/contrib/tutorial_world/objects.html b/docs/0.9.5/_modules/evennia/contrib/tutorial_world/objects.html
index c84d0a7c8b..db3dab64d7 100644
--- a/docs/0.9.5/_modules/evennia/contrib/tutorial_world/objects.html
+++ b/docs/0.9.5/_modules/evennia/contrib/tutorial_world/objects.html
@@ -55,8 +55,8 @@
Obelisk
LightSource
CrumblingWall
-
Weapon
-
WeaponRack
+
TutorialWeapon
+
TutorialWeaponRack
"""
@@ -832,7 +832,7 @@
# -------------------------------------------------------------
#
-
# Weapon - object type
+
# TutorialWeapon - object type
#
# A weapon is necessary in order to fight in the tutorial
# world. A weapon (which here is assumed to be a bladed
@@ -972,7 +972,7 @@
self.add(CmdAttack())
-[docs]class Weapon(TutorialObject):
+
[docs]class TutorialWeapon(TutorialObject):
"""
This defines a bladed weapon.
@@ -984,7 +984,7 @@
"""
-
[docs] def at_object_creation(self):
+
[docs] def at_object_creation(self):
"""Called at first creation of the object"""
super().at_object_creation()
self.db.hit = 0.4 # hit chance
@@ -993,7 +993,7 @@
self.db.magic = False
self.cmdset.add_default(CmdSetWeapon, permanent=True)
-
[docs] def reset(self):
+
[docs] def reset(self):
"""
When reset, the weapon is simply deleted, unless it has a place
to return to.
@@ -1023,7 +1023,7 @@
WEAPON_PROTOTYPES = {
"weapon": {
-
"typeclass": "evennia.contrib.tutorial_world.objects.Weapon",
+
"typeclass": "evennia.contrib.tutorial_world.objects.TutorialWeapon",
"key": "Weapon",
"hit": 0.2,
"parry": 0.2,
@@ -1168,7 +1168,7 @@
self.add(CmdGetWeapon())
-
[docs]class WeaponRack(TutorialObject):
+
[docs]class TutorialWeaponRack(TutorialObject):
"""
This object represents a weapon store. When people use the
"get weapon" command on this rack, it will produce one
@@ -1185,7 +1185,7 @@
"""
-
[docs] def at_object_creation(self):
+
[docs] def at_object_creation(self):
"""
called at creation
"""
@@ -1204,7 +1204,7 @@
self.db.no_more_weapons_msg = "you find nothing else of use."
self.db.available_weapons = ["knife", "dagger", "sword", "club"]
-
[docs] def produce_weapon(self, caller):
+
[docs] def produce_weapon(self, caller):
"""
This will produce a new weapon from the rack,
assuming the caller hasn't already gotten one. When
diff --git a/docs/0.9.5/_modules/evennia/help/models.html b/docs/0.9.5/_modules/evennia/help/models.html
index e7bf886807..db79c56666 100644
--- a/docs/0.9.5/_modules/evennia/help/models.html
+++ b/docs/0.9.5/_modules/evennia/help/models.html
@@ -114,7 +114,8 @@
db_tags = models.ManyToManyField(
Tag,
blank=True,
-
help_text="tags on this object. Tags are simple string markers to identify, group and alias objects.",
+
help_text="tags on this object. Tags are simple string markers to "
+
"identify, group and alias objects.",
)
# (deprecated, only here to allow MUX helpfile load (don't use otherwise)).
# TODO: remove this when not needed anymore.
@@ -164,6 +165,19 @@
"""
return self.locks.check(accessing_obj, access_type=access_type, default=default)
+
@property
+
def search_index_entry(self):
+
"""
+
Property for easily retaining a search index entry for this object.
+
"""
+
return {
+
"key": self.db_key,
+
"aliases": " ".join(self.aliases.all()),
+
"category": self.db_help_category,
+
"text": self.db_entrytext,
+
"tags": " ".join(str(tag) for tag in self.tags.all()),
+
}
+
#
# Web/Django methods
#
diff --git a/docs/0.9.5/_modules/evennia/locks/lockfuncs.html b/docs/0.9.5/_modules/evennia/locks/lockfuncs.html
index b7942694ee..9743b5569d 100644
--- a/docs/0.9.5/_modules/evennia/locks/lockfuncs.html
+++ b/docs/0.9.5/_modules/evennia/locks/lockfuncs.html
@@ -580,8 +580,6 @@
Only true if accessed_obj has the specified tag and optional
category.
"""
-
if hasattr(accessed_obj, "obj"):
-
accessed_obj = accessed_obj.obj
tagkey = args[0] if args else None
category = args[1] if len(args) > 1 else None
return bool(accessed_obj.tags.get(tagkey, category=category))
@@ -613,9 +611,6 @@
in your inventory will also pass the lock).
"""
-
if hasattr(accessed_obj, "obj"):
-
accessed_obj = accessed_obj.obj
-
def _recursive_inside(obj, accessed_obj, lvl=1):
if obj.location:
if obj.location == accessed_obj:
diff --git a/docs/0.9.5/_modules/evennia/objects/models.html b/docs/0.9.5/_modules/evennia/objects/models.html
index 5aa38956f6..2caa92c4b7 100644
--- a/docs/0.9.5/_modules/evennia/objects/models.html
+++ b/docs/0.9.5/_modules/evennia/objects/models.html
@@ -54,6 +54,7 @@
the database object. Like everything else, they can be accessed
transparently through the decorating TypeClass.
"""
+
from collections import defaultdict
from django.conf import settings
from django.db import models
from django.core.exceptions import ObjectDoesNotExist
@@ -83,34 +84,49 @@
"""
self.obj = obj
-
self._pkcache = {}
+
self._pkcache = set()
self._idcache = obj.__class__.__instance_cache__
+
self._typecache = defaultdict(set)
self.init()
+
[docs] def load(self):
+
"""
+
Retrieves all objects from database. Used for initializing.
+
+
Returns:
+
Objects (list of ObjectDB)
+
"""
+
return list(self.obj.locations_set.all())
+
[docs] def init(self):
"""
Re-initialize the content cache
"""
-
self._pkcache.update(
-
dict((obj.pk, None) for obj in ObjectDB.objects.filter(db_location=self.obj) if obj.pk)
-
)
+
objects = self.load()
+
self._pkcache = {obj.pk for obj in objects}
+
for obj in objects:
+
for ctype in obj._content_types:
+
self._typecache[ctype].add(obj.pk)
-
[docs] def get(self, exclude=None):
+
[docs] def get(self, exclude=None, content_type=None):
"""
Return the contents of the cache.
Args:
exclude (Object or list of Object): object(s) to ignore
+
content_type (str or None): Filter list by a content-type. If None, don't filter.
Returns:
objects (list): the Objects inside this location
"""
-
if exclude:
-
pks = [pk for pk in self._pkcache if pk not in [excl.pk for excl in make_iter(exclude)]]
+
if content_type is not None:
+
pks = self._typecache[content_type]
else:
pks = self._pkcache
+
if exclude:
+
pks = pks - {excl.pk for excl in make_iter(exclude)}
try:
return [self._idcache[pk] for pk in pks]
except KeyError:
@@ -120,10 +136,9 @@
try:
return [self._idcache[pk] for pk in pks]
except KeyError:
-
# this means the central instance_cache was totally flushed.
-
# Re-fetching from database will rebuild the necessary parts of the cache
-
# for next fetch.
-
return list(ObjectDB.objects.filter(db_location=self.obj))
+
# this means an actual failure of caching. Return real database match.
+
logger.log_err("contents cache failed for %s." % self.obj.key)
+
return self.load()
[docs] def add(self, obj):
"""
@@ -133,7 +148,9 @@
obj (Object): object to add
"""
-
self._pkcache[obj.pk] = None
+
self._pkcache.add(obj.pk)
+
for ctype in obj._content_types:
+
self._typecache[ctype].add(obj.pk)
[docs] def remove(self, obj):
"""
@@ -143,7 +160,10 @@
obj (Object): object to remove
"""
-
self._pkcache.pop(obj.pk, None)
+
self._pkcache.remove(obj.pk)
+
for ctype in obj._content_types:
+
if obj.pk in self._typecache[ctype]:
+
self._typecache[ctype].remove(obj.pk)
[docs] def clear(self):
"""
@@ -151,6 +171,7 @@
"""
self._pkcache = {}
+
self._typecache = defaultdict(set)
self.init()
diff --git a/docs/0.9.5/_modules/evennia/objects/objects.html b/docs/0.9.5/_modules/evennia/objects/objects.html
index 16adaba36e..158162ed4a 100644
--- a/docs/0.9.5/_modules/evennia/objects/objects.html
+++ b/docs/0.9.5/_modules/evennia/objects/objects.html
@@ -53,7 +53,7 @@
from django.conf import settings
from evennia.typeclasses.models import TypeclassBase
-
from evennia.typeclasses.attributes import NickHandler
+
from evennia.typeclasses.attributes import NickHandler, ModelAttributeBackend
from evennia.objects.manager import ObjectManager
from evennia.objects.models import ObjectDB
from evennia.scripts.scripthandler import ScriptHandler
@@ -245,6 +245,9 @@
"""
+
# Used for sorting / filtering in inventories / room contents.
+
_content_types = ("object",)
+
# lockstring of newly created objects, for easy overloading.
# Will be formatted with the appropriate attributes.
lockstring = "control:id({account_id}) or perm(Admin);delete:id({account_id}) or perm(Admin)"
@@ -263,7 +266,7 @@
[docs] @lazy_property
def nicks(self):
-
return NickHandler(self)
+
return NickHandler(self, ModelAttributeBackend)
[docs] @lazy_property
def sessions(self):
@@ -298,7 +301,7 @@
and not self.db_account.attributes.get("_quell")
)
-
[docs] def contents_get(self, exclude=None):
+
[docs] def contents_get(self, exclude=None, content_type=None):
"""
Returns the contents of this object, i.e. all
objects that has this object set as its location.
@@ -307,17 +310,18 @@
Args:
exclude (Object): Object to exclude from returned
contents list
+
content_type (str): A content_type to filter by. None for no
+
filtering.
Returns:
contents (list): List of contents of this Object.
Notes:
-
Also available as the `contents` property.
+
Also available as the `contents` property, minus exclusion
+
and filtering.
"""
-
con = self.contents_cache.get(exclude=exclude)
-
# print "contents_get:", self, con, id(self), calledby() # DEBUG
-
return con
+
return self.contents_cache.get(exclude=exclude, content_type=content_type)
[docs] def contents_set(self, *args):
"You cannot replace this property"
@@ -413,6 +417,7 @@
nofound_string=None,
multimatch_string=None,
use_dbref=None,
+
stacked=0,
):
"""
Returns an Object matching a search string/condition
@@ -468,10 +473,19 @@
will be treated like a normal string. If `None` (default), the ability to query by
#dbref is turned on if `self` has the permission 'Builder' and is turned off
otherwise.
+
stacked (int, optional): If > 0, multimatches will be analyzed to determine if they
+
only contains identical objects; these are then assumed 'stacked' and no multi-match
+
error will be generated, instead `stacked` number of matches will be returned. If
+
`stacked` is larger than number of matches, returns that number of matches. If
+
the found stack is a mix of objects, return None and handle the multi-match
+
error depending on the value of `quiet`.
Returns:
-
match (Object, None or list): will return an Object/None if `quiet=False`,
-
otherwise it will return a list of 0, 1 or more matches.
+
Object: If finding a match an `quiet=False`
+
None: If not finding a unique match and `quiet=False`.
+
list: With 0, 1 or more matching objects if `quiet=True`
+
list: With 2 or more matching objects if `stacked` is a positive integer and
+
the matched stack has only object-copies.
Notes:
To find Accounts, use eg. `evennia.account_search`. If
@@ -539,8 +553,29 @@
use_dbref=use_dbref,
)
+
nresults = len(results)
+
if stacked > 0 and nresults > 1:
+
# handle stacks, disable multimatch errors
+
nstack = nresults
+
if not exact:
+
# we re-run exact match agains one of the matches to
+
# make sure we were not catching partial matches not belonging
+
# to the stack
+
nstack = len(ObjectDB.objects.get_objs_with_key_or_alias(
+
results[0].key,
+
exact=True,
+
candidates=list(results),
+
typeclasses=[typeclass] if typeclass else None
+
))
+
if nstack == nresults:
+
# a valid stack, return multiple results
+
return list(results)[:stacked]
+
if quiet:
+
# don't auto-handle error messaging
return list(results)
+
+
# handle error messages
return _AT_SEARCH_RESULT(
results,
self,
@@ -1697,20 +1732,26 @@
**kwargs (dict): Arbitrary, optional arguments for users
overriding the call (unused by default).
"""
+
+
def filter_visible(obj_list):
+
# Helper method to determine if objects are visible to the looker.
+
return [obj for obj in obj_list if obj != looker and obj.access(looker, "view")]
+
if not looker:
return ""
+
# get and identify all objects
-
visible = (con for con in self.contents if con != looker and con.access(looker, "view"))
-
exits, users, things = [], [], defaultdict(list)
-
for con in visible:
-
key = con.get_display_name(looker)
-
if con.destination:
-
exits.append(key)
-
elif con.has_account:
-
users.append("|c%s|n" % key)
-
else:
-
# things can be pluralized
-
things[key].append(con)
+
exits_list = filter_visible(self.contents_get(content_type="exit"))
+
users_list = filter_visible(self.contents_get(content_type="character"))
+
things_list = filter_visible(self.contents_get(content_type="object"))
+
+
things = defaultdict(list)
+
+
for thing in things_list:
+
things[thing.key].append(thing)
+
users = [f"|c{user.key}|n" for user in users_list]
+
exits = [ex.key for ex in exits_list]
+
# get description, build string
string = "|c%s|n\n" % self.get_display_name(looker)
desc = self.db.desc
@@ -2068,6 +2109,9 @@
"""
+
# Tuple of types used for indexing inventory contents. Characters generally wouldn't be in
+
# anyone's inventory, but this also governs displays in room contents.
+
_content_types = ("character",)
# lockstring of newly created rooms, for easy overloading.
# Will be formatted with the appropriate attributes.
lockstring = (
@@ -2107,6 +2151,13 @@
# If no typeclass supplied, use this class
kwargs["typeclass"] = kwargs.pop("typeclass", cls)
+
# Normalize to latin characters and validate, if necessary, the supplied key
+
key = cls.normalize_name(key)
+
+
if not cls.validate_name(key):
+
errors.append("Invalid character name.")
+
return obj, errors
+
# Set the supplied key as the name of the intended object
kwargs["key"] = key
@@ -2156,6 +2207,38 @@
return obj, errors
+
[docs] @classmethod
+
def normalize_name(cls, name):
+
"""
+
Normalize the character name prior to creating. Note that this should be refactored
+
to support i18n for non-latin scripts, but as we (currently) have no bug reports requesting better
+
support of non-latin character sets, requiring character names to be latinified is an acceptable option.
+
+
Args:
+
name (str) : The name of the character
+
+
Returns:
+
latin_name (str) : A valid name.
+
"""
+
+
from evennia.utils.utils import latinify
+
+
latin_name = latinify(name, default="X")
+
return latin_name
+
+
[docs] @classmethod
+
def validate_name(cls, name):
+
""" Validate the character name prior to creating. Overload this function to add custom validators
+
+
Args:
+
name (str) : The name of the character
+
Returns:
+
valid (bool) : True if character creation should continue; False if it should fail
+
+
"""
+
+
return True # Default validator does not perform any operations
+
[docs] def basetype_setup(self):
"""
Setup character-specific security.
@@ -2284,6 +2367,10 @@
location is always `None`.
"""
+
# A tuple of strings used for indexing this object inside an inventory.
+
# Generally, a room isn't expected to HAVE a location, but maybe in some games?
+
_content_types = ("room",)
+
# lockstring of newly created rooms, for easy overloading.
# Will be formatted with the {id} of the creating object.
lockstring = (
@@ -2443,6 +2530,7 @@
"""
+
_content_types = ("exit",)
exit_command = ExitCommand
priority = 101
diff --git a/docs/0.9.5/_modules/evennia/server/amp_client.html b/docs/0.9.5/_modules/evennia/server/amp_client.html
index b997e5a11c..5e68c4930e 100644
--- a/docs/0.9.5/_modules/evennia/server/amp_client.html
+++ b/docs/0.9.5/_modules/evennia/server/amp_client.html
@@ -46,9 +46,11 @@
"""
import os
+
from django.conf import settings
from evennia.server.portal import amp
from twisted.internet import protocol
from evennia.utils import logger
+
from evennia.utils.utils import class_from_module
[docs]class AMPClientFactory(protocol.ReconnectingClientFactory):
@@ -74,7 +76,7 @@
"""
self.server = server
-
self.protocol = AMPServerClientProtocol
+
self.protocol = class_from_module(settings.AMP_CLIENT_PROTOCOL_CLASS)
self.maxDelay = 10
# not really used unless connecting to multiple servers, but
# avoids having to check for its existence on the protocol
diff --git a/docs/0.9.5/_modules/evennia/server/inputfuncs.html b/docs/0.9.5/_modules/evennia/server/inputfuncs.html
index 330cf2aa50..fdbef11188 100644
--- a/docs/0.9.5/_modules/evennia/server/inputfuncs.html
+++ b/docs/0.9.5/_modules/evennia/server/inputfuncs.html
@@ -528,7 +528,6 @@
Keyword Args:
<option name>: an option to save
-
"""
account = session.account
diff --git a/docs/0.9.5/_modules/evennia/server/portal/amp.html b/docs/0.9.5/_modules/evennia/server/portal/amp.html
index 77e0764566..0f751a2ed6 100644
--- a/docs/0.9.5/_modules/evennia/server/portal/amp.html
+++ b/docs/0.9.5/_modules/evennia/server/portal/amp.html
@@ -56,7 +56,7 @@
import pickle
from twisted.internet.defer import DeferredList, Deferred
-
from evennia.utils.utils import to_str, variable_from_module
+
from evennia.utils.utils import variable_from_module
# delayed import
_LOGGER = None
diff --git a/docs/0.9.5/_modules/evennia/server/portal/amp_server.html b/docs/0.9.5/_modules/evennia/server/portal/amp_server.html
index caa7308fcb..664a59f69a 100644
--- a/docs/0.9.5/_modules/evennia/server/portal/amp_server.html
+++ b/docs/0.9.5/_modules/evennia/server/portal/amp_server.html
@@ -52,6 +52,7 @@
from django.conf import settings
from subprocess import Popen, STDOUT
from evennia.utils import logger
+
from evennia.utils.utils import class_from_module
def _is_windows():
@@ -97,7 +98,7 @@
"""
self.portal = portal
-
self.protocol = AMPServerProtocol
+
self.protocol = class_from_module(settings.AMP_SERVER_PROTOCOL_CLASS)
self.broadcasts = []
self.server_connection = None
self.launcher_connection = None
@@ -115,7 +116,7 @@
protocol (Protocol): The created protocol.
"""
-
self.portal.amp_protocol = AMPServerProtocol()
+
self.portal.amp_protocol = self.protocol()
self.portal.amp_protocol.factory = self
return self.portal.amp_protocol
diff --git a/docs/0.9.5/_modules/evennia/server/portal/portal.html b/docs/0.9.5/_modules/evennia/server/portal/portal.html
index 4e95eaa721..d190355b63 100644
--- a/docs/0.9.5/_modules/evennia/server/portal/portal.html
+++ b/docs/0.9.5/_modules/evennia/server/portal/portal.html
@@ -68,7 +68,7 @@
evennia._init()
-
from evennia.utils.utils import get_evennia_version, mod_import, make_iter
+
from evennia.utils.utils import get_evennia_version, mod_import, make_iter, class_from_module
from evennia.server.portal.portalsessionhandler import PORTAL_SESSIONS
from evennia.utils import logger
from evennia.server.webserver import EvenniaReverseProxyResource
@@ -327,6 +327,8 @@
from evennia.server.portal import telnet
+
_telnet_protocol = class_from_module(settings.TELNET_PROTOCOL_CLASS)
+
for interface in TELNET_INTERFACES:
ifacestr = ""
if interface not in ("0.0.0.0", "::") or len(TELNET_INTERFACES) > 1:
@@ -335,7 +337,7 @@
pstring = "%s:%s" % (ifacestr, port)
factory = telnet.TelnetServerFactory()
factory.noisy = False
-
factory.protocol = telnet.TelnetProtocol
+
factory.protocol = _telnet_protocol
factory.sessionhandler = PORTAL_SESSIONS
telnet_service = internet.TCPServer(port, factory, interface=interface)
telnet_service.setName("EvenniaTelnet%s" % pstring)
@@ -350,6 +352,8 @@
from evennia.server.portal import telnet_ssl
+
_ssl_protocol = class_from_module(settings.SSL_PROTOCOL_CLASS)
+
for interface in SSL_INTERFACES:
ifacestr = ""
if interface not in ("0.0.0.0", "::") or len(SSL_INTERFACES) > 1:
@@ -359,7 +363,7 @@
factory = protocol.ServerFactory()
factory.noisy = False
factory.sessionhandler = PORTAL_SESSIONS
-
factory.protocol = telnet_ssl.SSLProtocol
+
factory.protocol = _ssl_protocol
ssl_context = telnet_ssl.getSSLContext()
if ssl_context:
@@ -383,6 +387,8 @@
from evennia.server.portal import ssh
+
_ssh_protocol = class_from_module(settings.SSH_PROTOCOL_CLASS)
+
for interface in SSH_INTERFACES:
ifacestr = ""
if interface not in ("0.0.0.0", "::") or len(SSH_INTERFACES) > 1:
@@ -390,11 +396,7 @@
for port in SSH_PORTS:
pstring = "%s:%s" % (ifacestr, port)
factory = ssh.makeFactory(
-
{
-
"protocolFactory": ssh.SshProtocol,
-
"protocolArgs": (),
-
"sessions": PORTAL_SESSIONS,
-
}
+
{"protocolFactory": _ssh_protocol, "protocolArgs": (), "sessions": PORTAL_SESSIONS,}
)
factory.noisy = False
ssh_service = internet.TCPServer(port, factory, interface=interface)
@@ -410,6 +412,7 @@
# Start a reverse proxy to relay data to the Server-side webserver
websocket_started = False
+
_websocket_protocol = class_from_module(settings.WEBSOCKET_PROTOCOL_CLASS)
for interface in WEBSERVER_INTERFACES:
ifacestr = ""
if interface not in ("0.0.0.0", "::") or len(WEBSERVER_INTERFACES) > 1:
@@ -444,7 +447,7 @@
factory = Websocket()
factory.noisy = False
-
factory.protocol = webclient.WebSocketClient
+
factory.protocol = _websocket_protocol
factory.sessionhandler = PORTAL_SESSIONS
websocket_service = internet.TCPServer(port, factory, interface=w_interface)
websocket_service.setName("EvenniaWebSocket%s:%s" % (w_ifacestr, port))
diff --git a/docs/0.9.5/_modules/evennia/server/portal/portalsessionhandler.html b/docs/0.9.5/_modules/evennia/server/portal/portalsessionhandler.html
index 9aa10be81f..91be8bf870 100644
--- a/docs/0.9.5/_modules/evennia/server/portal/portalsessionhandler.html
+++ b/docs/0.9.5/_modules/evennia/server/portal/portalsessionhandler.html
@@ -48,8 +48,10 @@
from collections import deque, namedtuple
from twisted.internet import reactor
from django.conf import settings
-
from evennia.server.sessionhandler import SessionHandler, PCONN, PDISCONN, PCONNSYNC, PDISCONNALL
+
from evennia.server.sessionhandler import SessionHandler
+
from evennia.server.portal.amp import PCONN, PDISCONN, PCONNSYNC, PDISCONNALL
from evennia.utils.logger import log_trace
+
from evennia.utils.utils import class_from_module
# module import
_MOD_IMPORT = None
@@ -109,6 +111,19 @@
"""
self.connection_time = time.time()
+[docs] def generate_sessid(self):
+
"""
+
Simply generates a sessid that's guaranteed to be unique for this Portal run.
+
+
Returns:
+
sessid
+
+
"""
+
self.latest_sessid += 1
+
if self.latest_sessid in self:
+
return self.generate_sessid()
+
return self.latest_sessid
+
[docs] def connect(self, session):
"""
Called by protocol at first connect. This adds a not-yet
@@ -132,8 +147,7 @@
if not session.sessid:
# if the session already has a sessid (e.g. being inherited in the
# case of a webclient auto-reconnect), keep it
-
self.latest_sessid += 1
-
session.sessid = self.latest_sessid
+
session.sessid = self.generate_sessid()
session.server_connected = False
_CONNECTION_QUEUE.appendleft(session)
if len(_CONNECTION_QUEUE) > 1:
@@ -504,7 +518,9 @@
log_trace()
-PORTAL_SESSIONS = PortalSessionHandler()
+_PORTAL_SESSION_HANDLER_CLASS = class_from_module(settings.PORTAL_SESSION_HANDLER_CLASS)
+
+PORTAL_SESSIONS = _PORTAL_SESSION_HANDLER_CLASS()
diff --git a/docs/0.9.5/_modules/evennia/server/portal/ssh.html b/docs/0.9.5/_modules/evennia/server/portal/ssh.html
index 9e43ed66d9..5dbf39cfd7 100644
--- a/docs/0.9.5/_modules/evennia/server/portal/ssh.html
+++ b/docs/0.9.5/_modules/evennia/server/portal/ssh.html
@@ -84,10 +84,9 @@
from twisted.python import components
from django.conf import settings
-from evennia.server import session
from evennia.accounts.models import AccountDB
from evennia.utils import ansi
-from evennia.utils.utils import to_str
+from evennia.utils.utils import to_str, class_from_module
_RE_N = re.compile(r"\|n$")
_RE_SCREENREADER_REGEX = re.compile(
@@ -115,6 +114,8 @@
_PRIVATE_KEY_FILE, _PUBLIC_KEY_FILE
)
+_BASE_SESSION_CLASS = class_from_module(settings.BASE_SESSION_CLASS)
+
# not used atm
[docs]class SSHServerFactory(protocol.ServerFactory):
@@ -125,7 +126,7 @@
return "SSH"
-[docs]class SshProtocol(Manhole, session.Session):
+
[docs]class SshProtocol(Manhole, _BASE_SESSION_CLASS):
"""
Each account connecting over ssh gets this protocol assigned to
them. All communication between game and account goes through
@@ -318,18 +319,18 @@
text (str): The first argument is always the text string to send. No other arguments
are considered.
Keyword Args:
-
options (dict): Send-option flags:
+
options (dict): Send-option flags (booleans)
-
- mxp: Enforce MXP link support.
-
- ansi: Enforce no ANSI colors.
-
- xterm256: Enforce xterm256 colors, regardless of TTYPE setting.
-
- nocolor: Strip all colors.
-
- raw: Pass string through without any ansi processing
-
(i.e. include Evennia ansi markers but do not
+
- mxp: enforce mxp link support.
+
- ansi: enforce no ansi colors.
+
- xterm256: enforce xterm256 colors, regardless of ttype setting.
+
- nocolor: strip all colors.
+
- raw: pass string through without any ansi processing
+
(i.e. include evennia ansi markers but do not
convert them into ansi tokens)
-
- echo: Turn on/off line echo on the client. Turn
+
- echo: turn on/off line echo on the client. turn
off line echo for client, for example for password.
-
Note that it must be actively turned back on again!
+
note that it must be actively turned back on again!
"""
# print "telnet.send_text", args,kwargs # DEBUG
diff --git a/docs/0.9.5/_modules/evennia/server/portal/ssl.html b/docs/0.9.5/_modules/evennia/server/portal/ssl.html
index 161644b900..8ea08bd247 100644
--- a/docs/0.9.5/_modules/evennia/server/portal/ssl.html
+++ b/docs/0.9.5/_modules/evennia/server/portal/ssl.html
@@ -59,7 +59,7 @@
raise ImportError(errstr.format(err=error))
from django.conf import settings
-
from evennia.server.portal.telnet import TelnetProtocol
+
from evennia.utils.utils import class_from_module
_GAME_DIR = settings.GAME_DIR
@@ -84,8 +84,10 @@
{exestring}
"""
+
_TELNET_PROTOCOL_CLASS = class_from_module(settings.TELNET_PROTOCOL_CLASS)
-
[docs]class SSLProtocol(TelnetProtocol):
+
+
[docs]class SSLProtocol(_TELNET_PROTOCOL_CLASS):
"""
Communication is the same as telnet, except data transfer
is done with encryption.
diff --git a/docs/0.9.5/_modules/evennia/server/portal/telnet.html b/docs/0.9.5/_modules/evennia/server/portal/telnet.html
index 133f7eb08b..2ff272b22d 100644
--- a/docs/0.9.5/_modules/evennia/server/portal/telnet.html
+++ b/docs/0.9.5/_modules/evennia/server/portal/telnet.html
@@ -66,12 +66,11 @@
LINEMODE_TRAPSIG,
)
from django.conf import settings
-
from evennia.server.session import Session
from evennia.server.portal import ttype, mssp, telnet_oob, naws, suppress_ga
from evennia.server.portal.mccp import Mccp, mccp_compress, MCCP
from evennia.server.portal.mxp import Mxp, mxp_parse
from evennia.utils import ansi
-
from evennia.utils.utils import to_bytes
+
from evennia.utils.utils import to_bytes, class_from_module
_RE_N = re.compile(r"\|n$")
_RE_LEND = re.compile(br"\n$|\r$|\r\n$|\r\x00$|", re.MULTILINE)
@@ -97,6 +96,9 @@
)
+
_BASE_SESSION_CLASS = class_from_module(settings.BASE_SESSION_CLASS)
+
+
[docs]class TelnetServerFactory(protocol.ServerFactory):
"This is only to name this better in logs"
noisy = False
@@ -105,7 +107,7 @@
return "Telnet"
-
[docs]class TelnetProtocol(Telnet, StatefulTelnetProtocol, Session):
+
[docs]class TelnetProtocol(Telnet, StatefulTelnetProtocol, _BASE_SESSION_CLASS):
"""
Each player connecting over telnet (ie using most traditional mud
clients) gets a telnet protocol instance assigned to them. All
@@ -429,19 +431,19 @@
text (str): The first argument is always the text string to send. No other arguments
are considered.
Keyword Args:
-
options (dict): Send-option flags:
+
options (dict): Send-option flags
-
- mxp: Enforce MXP link support.
-
- ansi: Enforce no ANSI colors.
-
- xterm256: Enforce xterm256 colors, regardless of TTYPE.
-
- noxterm256: Enforce no xterm256 color support, regardless of TTYPE.
-
- nocolor: Strip all Color, regardless of ansi/xterm256 setting.
-
- raw: Pass string through without any ansi processing
-
(i.e. include Evennia ansi markers but do not
-
convert them into ansi tokens)
-
- echo: Turn on/off line echo on the client. Turn
-
off line echo for client, for example for password.
-
Note that it must be actively turned back on again!
+
- mxp: Enforce MXP link support.
+
- ansi: Enforce no ANSI colors.
+
- xterm256: Enforce xterm256 colors, regardless of TTYPE.
+
- noxterm256: Enforce no xterm256 color support, regardless of TTYPE.
+
- nocolor: Strip all Color, regardless of ansi/xterm256 setting.
+
- raw: Pass string through without any ansi processing
+
(i.e. include Evennia ansi markers but do not
+
convert them into ansi tokens)
+
- echo: Turn on/off line echo on the client. Turn
+
off line echo for client, for example for password.
+
Note that it must be actively turned back on again!
"""
text = args[0] if args else ""
diff --git a/docs/0.9.5/_modules/evennia/server/portal/telnet_oob.html b/docs/0.9.5/_modules/evennia/server/portal/telnet_oob.html
index 59e8d16a6c..2b8d0a7910 100644
--- a/docs/0.9.5/_modules/evennia/server/portal/telnet_oob.html
+++ b/docs/0.9.5/_modules/evennia/server/portal/telnet_oob.html
@@ -51,21 +51,16 @@
instruct the client to play sounds or to update a graphical health
bar.
-
> Note that in Evennia's Web client, all send commands are "OOB commands",
-
(including the "text" one), there is no equivalence to MSDP/GMCP for the
-
webclient since it doesn't need it.
+
Note that in Evennia's Web client, all send commands are "OOB
+
commands", (including the "text" one), there is no equivalence to
+
MSDP/GMCP for the webclient since it doesn't need it.
This implements the following telnet OOB communication protocols:
-
- MSDP (Mud Server Data Protocol), as per
-
http://tintin.sourceforge.net/msdp/
+
- MSDP (Mud Server Data Protocol), as per http://tintin.sourceforge.net/msdp/
- GMCP (Generic Mud Communication Protocol) as per
http://www.ironrealms.com/rapture/manual/files/FeatGMCP-txt.html#Generic_MUD_Communication_Protocol%28GMCP%29
-
Following the lead of KaVir's protocol snippet, we first check if client
-
supports MSDP and if not, we fallback to GMCP with a MSDP header where
-
applicable.
-
----
"""
@@ -202,16 +197,16 @@
MSDP structures on these forms:
::
-
[cmdname, [], {}] -> VAR cmdname VAL ""
-
[cmdname, [arg], {}] -> VAR cmdname VAL arg
-
[cmdname, [args],{}] -> VAR cmdname VAL ARRAYOPEN VAL arg VAL arg ... ARRAYCLOSE
-
[cmdname, [], {kwargs}] -> VAR cmdname VAL TABLEOPEN VAR key VAL val ... TABLECLOSE
+
[cmdname, [], {}] -> VAR cmdname VAL ""
+
[cmdname, [arg], {}] -> VAR cmdname VAL arg
+
[cmdname, [args],{}] -> VAR cmdname VAL ARRAYOPEN VAL arg VAL arg ... ARRAYCLOSE
+
[cmdname, [], {kwargs}] -> VAR cmdname VAL TABLEOPEN VAR key VAL val ... TABLECLOSE
[cmdname, [args], {kwargs}] -> VAR cmdname VAL ARRAYOPEN VAL arg VAL arg ... ARRAYCLOSE
VAR cmdname VAL TABLEOPEN VAR key VAL val ... TABLECLOSE
-
Further nesting is not supported, so if an array argument consists
-
of an array (for example), that array will be json-converted to a
-
string.
+
Further nesting is not supported, so if an array argument
+
consists of an array (for example), that array will be
+
json-converted to a string.
"""
msdp_cmdname = "{msdp_var}{msdp_cmdname}{msdp_val}".format(
@@ -281,11 +276,10 @@
[cmd.name, [arg], {}] -> Cmd.Name arg
[cmd.name, [args],{}] -> Cmd.Name [args]
[cmd.name, [], {kwargs}] -> Cmd.Name {kwargs}
-
[cmdname, [args, {kwargs}] -> Core.Cmdname [[args],{kwargs}]
+
[cmdname, [args, {kwargs}] -> Core.Cmdname [[args],{kwargs}]
Notes:
-
There are also a few default mappings between evennia outputcmds and
-
GMCP:
+
There are also a few default mappings between evennia outputcmds and GMCP:
::
client_options -> Core.Supports.Get
diff --git a/docs/0.9.5/_modules/evennia/server/portal/webclient.html b/docs/0.9.5/_modules/evennia/server/portal/webclient.html
index d0d95206a6..67ee7a41bc 100644
--- a/docs/0.9.5/_modules/evennia/server/portal/webclient.html
+++ b/docs/0.9.5/_modules/evennia/server/portal/webclient.html
@@ -58,10 +58,8 @@
import re
import json
import html
-
from twisted.internet.protocol import Protocol
from django.conf import settings
-
from evennia.server.session import Session
-
from evennia.utils.utils import to_str, mod_import
+
from evennia.utils.utils import mod_import, class_from_module
from evennia.utils.ansi import parse_ansi
from evennia.utils.text2html import parse_html
from autobahn.twisted.websocket import WebSocketServerProtocol
@@ -81,10 +79,10 @@
# called when the browser is navigating away from the page
GOING_AWAY = WebSocketServerProtocol.CLOSE_STATUS_CODE_GOING_AWAY
-
STATE_CLOSING = WebSocketServerProtocol.STATE_CLOSING
+
_BASE_SESSION_CLASS = class_from_module(settings.BASE_SESSION_CLASS)
-
[docs]class WebSocketClient(WebSocketServerProtocol, Session):
+
[docs]class WebSocketClient(WebSocketServerProtocol, _BASE_SESSION_CLASS):
"""
Implements the server-side of the Websocket connection.
"""
@@ -298,8 +296,6 @@
return
else:
return
-
# just to be sure
-
text = to_str(text)
flags = self.protocol_flags
diff --git a/docs/0.9.5/_modules/evennia/server/profiling/dummyrunner_settings.html b/docs/0.9.5/_modules/evennia/server/profiling/dummyrunner_settings.html
index f420e75626..765d885f5a 100644
--- a/docs/0.9.5/_modules/evennia/server/profiling/dummyrunner_settings.html
+++ b/docs/0.9.5/_modules/evennia/server/profiling/dummyrunner_settings.html
@@ -47,15 +47,15 @@
The settings are global variables:
-
TIMESTEP - time in seconds between each 'tick'
-
CHANCE_OF_ACTION - chance 0-1 of action happening
-
CHANCE_OF_LOGIN - chance 0-1 of login happening
-
TELNET_PORT - port to use, defaults to settings.TELNET_PORT
-
ACTIONS - see below
+
- TIMESTEP - time in seconds between each 'tick'
+
- CHANCE_OF_ACTION - chance 0-1 of action happening
+
- CHANCE_OF_LOGIN - chance 0-1 of login happening
+
- TELNET_PORT - port to use, defaults to settings.TELNET_PORT
+
- ACTIONS - see below
ACTIONS is a tuple
-
```
+
```python
(login_func, logout_func, (0.3, func1), (0.1, func2) ... )
```
@@ -78,14 +78,14 @@
The client object has the following relevant properties and methods:
- key - an optional client key. This is only used for dummyrunner output.
-
Default is "Dummy-<cid>"
+
Default is "Dummy-<cid>"
- cid - client id
- gid - globally unique id, hashed with time stamp
- istep - the current step
- exits - an empty list. Can be used to store exit names
- objs - an empty list. Can be used to store object names
- counter() - returns a unique increasing id, hashed with time stamp
-
to make it unique also between dummyrunner instances.
+
to make it unique also between dummyrunner instances.
The return should either be a single command string or a tuple of
command strings. This list of commands will always be executed every
@@ -93,7 +93,7 @@
(no randomness) and allows for setting up a more complex chain of
commands (such as creating an account and logging in).
-
---
+
----
"""
# Dummy runner settings
diff --git a/docs/0.9.5/_modules/evennia/server/server.html b/docs/0.9.5/_modules/evennia/server/server.html
index 9e5151a12e..237e9920f6 100644
--- a/docs/0.9.5/_modules/evennia/server/server.html
+++ b/docs/0.9.5/_modules/evennia/server/server.html
@@ -40,12 +40,12 @@
Source code for evennia.server.server
"""
-This module implements the main Evennia server process, the core of
-the game engine.
+This module implements the main Evennia server process, the core of the game
+engine.
-This module should be started with the 'twistd' executable since it
-sets up all the networking features. (this is done automatically
-by evennia/server/server_runner.py).
+This module should be started with the 'twistd' executable since it sets up all
+the networking features. (this is done automatically by
+evennia/server/server_runner.py).
"""
import time
@@ -63,6 +63,7 @@
django.setup()
import evennia
+import importlib
evennia._init()
@@ -72,7 +73,6 @@
from evennia.accounts.models import AccountDB
from evennia.scripts.models import ScriptDB
from evennia.server.models import ServerConfig
-from evennia.server import initial_setup
from evennia.utils.utils import get_evennia_version, mod_import, make_iter
from evennia.utils import logger
@@ -382,6 +382,7 @@
Once finished the last_initial_setup_step is set to -1.
"""
global INFO_DICT
+ initial_setup = importlib.import_module(settings.INITIAL_SETUP_MODULE)
last_initial_setup_step = ServerConfig.objects.conf("last_initial_setup_step")
if not last_initial_setup_step:
# None is only returned if the config does not exist,
@@ -440,18 +441,17 @@
"""
Shuts down the server from inside it.
- Keyword Args:
- mode (str): Sets the server restart mode:
- - 'reload': server restarts, no "persistent" scripts
- are stopped, at_reload hooks called.
- - 'reset' - server restarts, non-persistent scripts stopped,
- at_shutdown hooks called but sessions will not
- be disconnected.
- -'shutdown' - like reset, but server will not auto-restart.
- _reactor_stopping: This is set if server is stopped by a kill
- command OR this method was already called
- once - in both cases the reactor is dead/stopping already.
-
+ mode - sets the server restart mode.
+ - 'reload' - server restarts, no "persistent" scripts
+ are stopped, at_reload hooks called.
+ - 'reset' - server restarts, non-persistent scripts stopped,
+ at_shutdown hooks called but sessions will not
+ be disconnected.
+ - 'shutdown' - like reset, but server will not auto-restart.
+ _reactor_stopping - this is set if server is stopped by a kill
+ command OR this method was already called
+ once - in both cases the reactor is
+ dead/stopping already.
"""
if _reactor_stopping and hasattr(self, "shutdown_complete"):
# this means we have already passed through this method
diff --git a/docs/0.9.5/_modules/evennia/server/serversession.html b/docs/0.9.5/_modules/evennia/server/serversession.html
index d93037930a..ce95a5bccd 100644
--- a/docs/0.9.5/_modules/evennia/server/serversession.html
+++ b/docs/0.9.5/_modules/evennia/server/serversession.html
@@ -47,7 +47,6 @@
It is stored on the Server side (as opposed to protocol-specific sessions which
are stored on the Portal side)
"""
-import weakref
import time
from django.utils import timezone
from django.conf import settings
@@ -57,6 +56,7 @@
from evennia.commands.cmdsethandler import CmdSetHandler
from evennia.server.session import Session
from evennia.scripts.monitorhandler import MONITOR_HANDLER
+from evennia.typeclasses.attributes import AttributeHandler, InMemoryAttributeBackend, DbHolder
_GA = object.__getattribute__
_SA = object.__setattr__
@@ -66,124 +66,6 @@
# i18n
from django.utils.translation import gettext as _
-# Handlers for Session.db/ndb operation
-
-
-[docs]class NDbHolder(object):
-
"""Holder for allowing property access of attributes"""
-
-
[docs] def __init__(self, obj, name, manager_name="attributes"):
-
_SA(self, name, _GA(obj, manager_name))
-
_SA(self, "name", name)
-
-
def __getattribute__(self, attrname):
-
if attrname == "all":
-
# we allow to overload our default .all
-
attr = _GA(self, _GA(self, "name")).get("all")
-
return attr if attr else _GA(self, "all")
-
return _GA(self, _GA(self, "name")).get(attrname)
-
-
def __setattr__(self, attrname, value):
-
_GA(self, _GA(self, "name")).add(attrname, value)
-
-
def __delattr__(self, attrname):
-
_GA(self, _GA(self, "name")).remove(attrname)
-
-
[docs] def get_all(self):
-
return _GA(self, _GA(self, "name")).all()
-
-
all = property(get_all)
-
-
-[docs]class NAttributeHandler(object):
-
"""
-
NAttributeHandler version without recache protection.
-
This stand-alone handler manages non-database saving.
-
It is similar to `AttributeHandler` and is used
-
by the `.ndb` handler in the same way as `.db` does
-
for the `AttributeHandler`.
-
"""
-
-
[docs] def __init__(self, obj):
-
"""
-
Initialized on the object
-
"""
-
self._store = {}
-
self.obj = weakref.proxy(obj)
-
-
[docs] def has(self, key):
-
"""
-
Check if object has this attribute or not.
-
-
Args:
-
key (str): The Nattribute key to check.
-
-
Returns:
-
has_nattribute (bool): If Nattribute is set or not.
-
-
"""
-
return key in self._store
-
-
[docs] def get(self, key, default=None):
-
"""
-
Get the named key value.
-
-
Args:
-
key (str): The Nattribute key to get.
-
-
Returns:
-
the value of the Nattribute.
-
-
"""
-
return self._store.get(key, default)
-
-
[docs] def add(self, key, value):
-
"""
-
Add new key and value.
-
-
Args:
-
key (str): The name of Nattribute to add.
-
value (any): The value to store.
-
-
"""
-
self._store[key] = value
-
-
[docs] def remove(self, key):
-
"""
-
Remove Nattribute from storage.
-
-
Args:
-
key (str): The name of the Nattribute to remove.
-
-
"""
-
if key in self._store:
-
del self._store[key]
-
-
[docs] def clear(self):
-
"""
-
Remove all NAttributes from handler.
-
-
"""
-
self._store = {}
-
-
[docs] def all(self, return_tuples=False):
-
"""
-
List the contents of the handler.
-
-
Args:
-
return_tuples (bool, optional): Defines if the Nattributes
-
are returns as a list of keys or as a list of `(key, value)`.
-
-
Returns:
-
nattributes (list): A list of keys `[key, key, ...]` or a
-
list of tuples `[(key, value), ...]` depending on the
-
setting of `return_tuples`.
-
-
"""
-
if return_tuples:
-
return [(key, value) for (key, value) in self._store.items() if not key.startswith("_")]
-
return [key for key in self._store if not key.startswith("_")]
-
# -------------------------------------------------------------
# Server Session
@@ -216,6 +98,10 @@
cmdset_storage = property(__cmdset_storage_get, __cmdset_storage_set)
+ @property
+ def id(self):
+ return self.sessid
+
[docs] def at_sync(self):
"""
This is called whenever a session has been resynced with the
@@ -385,7 +271,7 @@
Update the protocol_flags and sync them with Portal.
Keyword Args:
-
any: A key:value pair to set in the
+
protocol_flag (any): A key and value to set in the
protocol_flags dictionary.
Notes:
@@ -417,14 +303,13 @@
the respective inputfuncs.
Keyword Args:
-
any: Incoming data from protocol on
+
kwargs (any): Incoming data from protocol on
the form `{"commandname": ((args), {kwargs}),...}`
Notes:
This method is here in order to give the user
a single place to catch and possibly process all incoming data from
the client. It should usually always end by sending
this data off to `self.sessionhandler.call_inputfuncs(self, **kwargs)`.
-
"""
self.sessionhandler.call_inputfuncs(self, **kwargs)
@@ -434,7 +319,9 @@
Args:
text (str): String input.
- kwargs (str or tuple): Send-commands identified
+
+ Keyword Args:
+ any (str or tuple): Send-commands identified
by their keys. Or "options", carrying options
for the protocol(s).
@@ -530,7 +417,7 @@
[docs] @lazy_property
def nattributes(self):
-
return NAttributeHandler(self)
+ return AttributeHandler(self, InMemoryAttributeBackend)
[docs] @lazy_property
def attributes(self):
@@ -548,7 +435,7 @@
try:
return self._ndb_holder
except AttributeError:
-
self._ndb_holder = NDbHolder(self, "nattrhandler", manager_name="nattributes")
+
self._ndb_holder = DbHolder(self, "nattrhandler", manager_name="nattributes")
return self._ndb_holder
# @ndb.setter
diff --git a/docs/0.9.5/_modules/evennia/server/session.html b/docs/0.9.5/_modules/evennia/server/session.html
index 6435748e93..8a1a3b5a27 100644
--- a/docs/0.9.5/_modules/evennia/server/session.html
+++ b/docs/0.9.5/_modules/evennia/server/session.html
@@ -76,26 +76,6 @@
"""
-
# names of attributes that should be affected by syncing.
-
_attrs_to_sync = (
-
"protocol_key",
-
"address",
-
"suid",
-
"sessid",
-
"uid",
-
"csessid",
-
"uname",
-
"logged_in",
-
"puid",
-
"conn_time",
-
"cmd_last",
-
"cmd_last_visible",
-
"cmd_total",
-
"protocol_flags",
-
"server_data",
-
"cmdset_storage_string",
-
)
-
[docs] def init_session(self, protocol_key, address, sessionhandler):
"""
Initialize the Session. This should be called by the protocol when
@@ -162,9 +142,9 @@
the keys given by self._attrs_to_sync.
"""
-
return dict(
-
(key, value) for key, value in self.__dict__.items() if key in self._attrs_to_sync
-
)
+
return {
+
attr: getattr(self, attr) for attr in settings.SESSION_SYNC_ATTRS if hasattr(self, attr)
+
}
[docs] def load_sync_data(self, sessdata):
"""
diff --git a/docs/0.9.5/_modules/evennia/server/sessionhandler.html b/docs/0.9.5/_modules/evennia/server/sessionhandler.html
index 9bbc191276..cdd7d0e6e5 100644
--- a/docs/0.9.5/_modules/evennia/server/sessionhandler.html
+++ b/docs/0.9.5/_modules/evennia/server/sessionhandler.html
@@ -45,12 +45,12 @@
There are two similar but separate stores of sessions:
-
- ServerSessionHandler - this stores generic game sessions
-
for the game. These sessions has no knowledge about
-
how they are connected to the world.
-
- PortalSessionHandler - this stores sessions created by
-
twisted protocols. These are dumb connectors that
-
handle network communication but holds no game info.
+
- ServerSessionHandler - this stores generic game sessions
+
for the game. These sessions has no knowledge about
+
how they are connected to the world.
+
- PortalSessionHandler - this stores sessions created by
+
twisted protocols. These are dumb connectors that
+
handle network communication but holds no game info.
"""
import time
@@ -64,7 +64,9 @@
make_iter,
delay,
callables_from_module,
+
class_from_module,
)
+
from evennia.server.portal import amp
from evennia.server.signals import SIGNAL_ACCOUNT_POST_LOGIN, SIGNAL_ACCOUNT_POST_LOGOUT
from evennia.server.signals import SIGNAL_ACCOUNT_POST_FIRST_LOGIN, SIGNAL_ACCOUNT_POST_LAST_LOGOUT
from evennia.utils.inlinefuncs import parse_inlinefunc
@@ -88,25 +90,6 @@
DUMMYSESSION = DummySession()
-
# AMP signals
-
PCONN = chr(1) # portal session connect
-
PDISCONN = chr(2) # portal session disconnect
-
PSYNC = chr(3) # portal session sync
-
SLOGIN = chr(4) # server session login
-
SDISCONN = chr(5) # server session disconnect
-
SDISCONNALL = chr(6) # server session disconnect all
-
SSHUTD = chr(7) # server shutdown
-
SSYNC = chr(8) # server session sync
-
SCONN = chr(11) # server portal connection (for bots)
-
PCONNSYNC = chr(12) # portal post-syncing session
-
PDISCONNALL = chr(13) # portal session discnnect all
-
SRELOAD = chr(14) # server reloading (have portal start a new server)
-
SSTART = chr(15) # server start (portal must already be running anyway)
-
PSHUTD = chr(16) # portal (+server) shutdown
-
SSHUTD = chr(17) # server shutdown
-
PSTATUS = chr(18) # ping server or portal status
-
SRESET = chr(19) # server shutdown in reset mode
-
# i18n
from django.utils.translation import gettext as _
@@ -214,23 +197,20 @@
Args:
session (Session): The relevant session instance.
-
kwargs (dict) Each keyword represents a
-
send-instruction, with the keyword itself being the name
+
kwargs (dict) Each keyword represents a send-instruction, with the keyword itself being the name
of the instruction (like "text"). Suitable values for each
keyword are:
-
::
-
-
arg -> [[arg], {}]
-
[args] -> [[args], {}]
-
{kwargs} -> [[], {kwargs}]
-
[args, {kwargs}] -> [[arg], {kwargs}]
-
[[args], {kwargs}] -> [[args], {kwargs}]
+
- arg -> [[arg], {}]
+
- [args] -> [[args], {}]
+
- {kwargs} -> [[], {kwargs}]
+
- [args, {kwargs}] -> [[arg], {kwargs}]
+
- [[args], {kwargs}] -> [[args], {kwargs}]
Returns:
kwargs (dict): A cleaned dictionary of cmdname:[[args],{kwargs}] pairs,
-
where the keys, args and kwargs have all been converted to
-
send-safe entities (strings or numbers), and inlinefuncs have been
-
applied.
+
where the keys, args and kwargs have all been converted to
+
send-safe entities (strings or numbers), and inlinefuncs have been
+
applied.
"""
options = kwargs.pop("options", None) or {}
@@ -494,7 +474,7 @@
"""
self.server.amp_protocol.send_AdminServer2Portal(
-
DUMMYSESSION, operation=SCONN, protocol_path=protocol_path, config=configdict
+
DUMMYSESSION, operation=amp.SCONN, protocol_path=protocol_path, config=configdict
)
[docs] def portal_restart_server(self):
@@ -502,14 +482,14 @@
Called by server when reloading. We tell the portal to start a new server instance.
"""
-
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=SRELOAD)
+
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=amp.SRELOAD)
[docs] def portal_reset_server(self):
"""
Called by server when reloading. We tell the portal to start a new server instance.
"""
-
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=SRESET)
+
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=amp.SRESET)
[docs] def portal_shutdown(self):
"""
@@ -517,7 +497,7 @@
itself down)
"""
-
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=PSHUTD)
+
self.server.amp_protocol.send_AdminServer2Portal(DUMMYSESSION, operation=amp.PSHUTD)
[docs] def login(self, session, account, force=False, testmode=False):
"""
@@ -565,7 +545,7 @@
# sync the portal to the session
if not testmode:
self.server.amp_protocol.send_AdminServer2Portal(
-
session, operation=SLOGIN, sessiondata={"logged_in": True, "uid": session.uid}
+
session, operation=amp.SLOGIN, sessiondata={"logged_in": True, "uid": session.uid}
)
account.at_post_login(session=session)
if nsess < 2:
@@ -610,7 +590,7 @@
if sync_portal:
# inform portal that session should be closed.
self.server.amp_protocol.send_AdminServer2Portal(
-
session, operation=SDISCONN, reason=reason
+
session, operation=amp.SDISCONN, reason=reason
)
[docs] def all_sessions_portal_sync(self):
@@ -621,7 +601,7 @@
"""
sessdata = self.get_all_sync_data()
return self.server.amp_protocol.send_AdminServer2Portal(
-
DUMMYSESSION, operation=SSYNC, sessiondata=sessdata
+
DUMMYSESSION, operation=amp.SSYNC, sessiondata=sessdata
)
[docs] def session_portal_sync(self, session):
@@ -632,7 +612,7 @@
"""
sessdata = {session.sessid: session.get_sync_data()}
return self.server.amp_protocol.send_AdminServer2Portal(
-
DUMMYSESSION, operation=SSYNC, sessiondata=sessdata, clean=False
+
DUMMYSESSION, operation=amp.SSYNC, sessiondata=sessdata, clean=False
)
[docs] def session_portal_partial_sync(self, session_data):
@@ -645,7 +625,7 @@
"""
return self.server.amp_protocol.send_AdminServer2Portal(
-
DUMMYSESSION, operation=SSYNC, sessiondata=session_data, clean=False
+
DUMMYSESSION, operation=amp.SSYNC, sessiondata=session_data, clean=False
)
[docs] def disconnect_all_sessions(self, reason="You have been disconnected."):
@@ -661,7 +641,7 @@
del session
# tell portal to disconnect all sessions
self.server.amp_protocol.send_AdminServer2Portal(
-
DUMMYSESSION, operation=SDISCONNALL, reason=reason
+
DUMMYSESSION, operation=amp.SDISCONNALL, reason=reason
)
[docs] def disconnect_duplicate_sessions(
@@ -804,8 +784,9 @@
Given a client identification hash (for session types that offer them)
return all sessions with a matching hash.
-
Args:
+
Args
csessid (str): The session hash.
+
Returns:
sessions (list): The sessions with matching .csessid, if any.
@@ -868,9 +849,9 @@
-
SESSION_HANDLER = ServerSessionHandler()
+
# import class from settings
+
_SESSION_HANDLER_CLASS = class_from_module(settings.SERVER_SESSION_HANDLER_CLASS)
+
+
# Instantiate class. These globals are used to provide singleton-like behavior.
+
SESSION_HANDLER = _SESSION_HANDLER_CLASS()
SESSIONS = SESSION_HANDLER # legacy
diff --git a/docs/0.9.5/_modules/evennia/typeclasses/attributes.html b/docs/0.9.5/_modules/evennia/typeclasses/attributes.html
index 67175b1449..276ba1c7a3 100644
--- a/docs/0.9.5/_modules/evennia/typeclasses/attributes.html
+++ b/docs/0.9.5/_modules/evennia/typeclasses/attributes.html
@@ -53,6 +53,8 @@
import fnmatch
import weakref
+
from collections import defaultdict
+
from django.db import models
from django.conf import settings
from django.utils.encoding import smart_str
@@ -72,7 +74,7 @@
# -------------------------------------------------------------
-
[docs]class Attribute(SharedMemoryModel):
+
[docs]class IAttribute:
"""
Attributes are things that are specific to different types of objects. For
example, a drink container needs to store its fill level, whereas an exit
@@ -94,6 +96,112 @@
- category (str): Optional character string for grouping the
Attribute.
+
This class is an API/Interface/Abstract base class; do not instantiate it directly.
+
"""
+
+
[docs] @lazy_property
+
def locks(self):
+
return LockHandler(self)
+
+
key = property(lambda self: self.db_key)
+
strvalue = property(lambda self: self.db_strvalue)
+
category = property(lambda self: self.db_category)
+
model = property(lambda self: self.db_model)
+
attrtype = property(lambda self: self.db_attrtype)
+
date_created = property(lambda self: self.db_date_created)
+
+
def __lock_storage_get(self):
+
return self.db_lock_storage
+
+
def __lock_storage_set(self, value):
+
self.db_lock_storage = value
+
+
def __lock_storage_del(self):
+
self.db_lock_storage = ""
+
+
lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del)
+
+
[docs] def access(self, accessing_obj, access_type="read", default=False, **kwargs):
+
"""
+
Determines if another object has permission to access.
+
+
Args:
+
accessing_obj (object): Entity trying to access this one.
+
access_type (str, optional): Type of access sought, see
+
the lock documentation.
+
default (bool, optional): What result to return if no lock
+
of access_type was found. The default, `False`, means a lockdown
+
policy, only allowing explicit access.
+
kwargs (any, optional): Not used; here to make the API consistent with
+
other access calls.
+
+
Returns:
+
result (bool): If the lock was passed or not.
+
+
"""
+
result = self.locks.check(accessing_obj, access_type=access_type, default=default)
+
return result
+
+
#
+
#
+
# Attribute methods
+
#
+
#
+
+
def __str__(self):
+
return smart_str("%s(%s)" % (self.db_key, self.id))
+
+
def __repr__(self):
+
return "%s(%s)" % (self.db_key, self.id)
+
+
+
[docs]class InMemoryAttribute(IAttribute):
+
"""
+
This Attribute is used purely for NAttributes/NAttributeHandler. It has no database backend.
+
"""
+
+
# Primary Key has no meaning for an InMemoryAttribute. This merely serves to satisfy other code.
+
+
[docs] def __init__(self, pk, **kwargs):
+
"""
+
Create an Attribute that exists only in Memory.
+
+
Args:
+
pk (int): This is a fake 'primary key' / id-field. It doesn't actually have to be unique, but is fed an
+
incrementing number from the InMemoryBackend by default. This is needed only so Attributes can be
+
sorted. Some parts of the API also see the lack of a .pk field as a sign that the Attribute was
+
deleted.
+
**kwargs: Other keyword arguments are used to construct the actual Attribute.
+
"""
+
self.id = pk
+
self.pk = pk
+
+
# Copy all kwargs to local properties. We use db_ for compatability here.
+
for key, value in kwargs.items():
+
# Value and locks are special. We must call the wrappers.
+
if key == "value":
+
self.value = value
+
elif key == "lock_storage":
+
self.lock_storage = value
+
else:
+
setattr(self, f"db_{key}", value)
+
+
# value property (wraps db_value)
+
def __value_get(self):
+
return self.db_value
+
+
def __value_set(self, new_value):
+
self.db_value = new_value
+
+
def __value_del(self):
+
pass
+
+
value = property(__value_get, __value_set, __value_del)
+
+
+
[docs]class Attribute(IAttribute, SharedMemoryModel):
+
"""
+
This attribute is stored via Django. Most Attributes will be using this class.
"""
#
@@ -150,35 +258,10 @@
# Database manager
# objects = managers.AttributeManager()
-
[docs] @lazy_property
-
def locks(self):
-
return LockHandler(self)
-
class Meta(object):
"Define Django meta options"
verbose_name = "Evennia Attribute"
-
# read-only wrappers
-
key = property(lambda self: self.db_key)
-
strvalue = property(lambda self: self.db_strvalue)
-
category = property(lambda self: self.db_category)
-
model = property(lambda self: self.db_model)
-
attrtype = property(lambda self: self.db_attrtype)
-
date_created = property(lambda self: self.db_date_created)
-
-
def __lock_storage_get(self):
-
return self.db_lock_storage
-
-
def __lock_storage_set(self, value):
-
self.db_lock_storage = value
-
self.save(update_fields=["db_lock_storage"])
-
-
def __lock_storage_del(self):
-
self.db_lock_storage = ""
-
self.save(update_fields=["db_lock_storage"])
-
-
lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del)
-
# Wrapper properties to easily set database fields. These are
# @property decorators that allows to access these fields using
# normal python operations (without having to remember to save()
@@ -187,6 +270,20 @@
# value = self.attr and del self.attr respectively (where self
# is the object in question).
+
# lock_storage wrapper. Overloaded for saving to database.
+
def __lock_storage_get(self):
+
return self.db_lock_storage
+
+
def __lock_storage_set(self, value):
+
super().__lock_storage_set(value)
+
self.save(update_fields=["db_lock_storage"])
+
+
def __lock_storage_del(self):
+
super().__lock_storage_del()
+
self.save(update_fields=["db_lock_storage"])
+
+
lock_storage = property(__lock_storage_get, __lock_storage_set, __lock_storage_del)
+
# value property (wraps db_value)
# @property
def __value_get(self):
@@ -205,7 +302,6 @@
see self.__value_get.
"""
self.db_value = to_pickle(new_value)
-
# print("value_set, self.db_value:", repr(self.db_value)) # DEBUG
self.save(update_fields=["db_value"])
# @value.deleter
@@ -213,40 +309,7 @@
"""Deleter. Allows for del attr.value. This removes the entire attribute."""
self.delete()
-
value = property(__value_get, __value_set, __value_del)
-
-
#
-
#
-
# Attribute methods
-
#
-
#
-
-
def __str__(self):
-
return smart_str("%s(%s)" % (self.db_key, self.id))
-
-
def __repr__(self):
-
return "%s(%s)" % (self.db_key, self.id)
-
-
[docs] def access(self, accessing_obj, access_type="attrread", default=False, **kwargs):
-
"""
-
Determines if another object has permission to access.
-
-
Args:
-
accessing_obj (object): Entity trying to access this one.
-
access_type (str, optional): Type of access sought, see
-
the lock documentation.
-
default (bool, optional): What result to return if no lock
-
of access_type was found. The default, `False`, means a lockdown
-
policy, only allowing explicit access.
-
kwargs (any, optional): Not used; here to make the API consistent with
-
other access calls.
-
-
Returns:
-
result (bool): If the lock was passed or not.
-
-
"""
-
result = self.locks.check(accessing_obj, access_type=access_type, default=default)
-
return result
+
value = property(__value_get, __value_set, __value_del)
#
@@ -254,59 +317,145 @@
#
-
[docs]class AttributeHandler(object):
+
[docs]class IAttributeBackend:
"""
-
Handler for adding Attributes to the object.
+
Abstract interface for the backends used by the Attribute Handler.
+
+
All Backends must implement this base class.
"""
-
_m2m_fieldname = "db_attributes"
_attrcreate = "attrcreate"
_attredit = "attredit"
_attrread = "attrread"
-
_attrtype = None
+
_attrclass = None
-
[docs] def __init__(self, obj):
-
"""Initialize handler."""
-
self.obj = obj
-
self._objid = obj.id
-
self._model = to_str(obj.__dbclass__.__name__.lower())
+
[docs] def __init__(self, handler, attrtype):
+
self.handler = handler
+
self.obj = handler.obj
+
self._attrtype = attrtype
+
self._objid = handler.obj.id
self._cache = {}
# store category names fully cached
self._catcache = {}
# full cache was run on all attributes
self._cache_complete = False
-
def _query_all(self):
-
"Fetch all Attributes on this object"
-
query = {
-
"%s__id" % self._model: self._objid,
-
"attribute__db_model__iexact": self._model,
-
"attribute__db_attrtype": self._attrtype,
-
}
-
return [
-
conn.attribute
-
for conn in getattr(self.obj, self._m2m_fieldname).through.objects.filter(**query)
-
]
+
[docs] def query_all(self):
+
"""
+
Fetch all Attributes from this object.
-
def _fullcache(self):
+
Returns:
+
attrlist (list): A list of Attribute objects.
+
"""
+
raise NotImplementedError()
+
+
[docs] def query_key(self, key, category):
+
"""
+
+
Args:
+
key (str): The key of the Attribute being searched for.
+
category (str or None): The category of the desired Attribute.
+
+
Returns:
+
attribute (IAttribute): A single Attribute.
+
"""
+
raise NotImplementedError()
+
+
[docs] def query_category(self, category):
+
"""
+
Returns every matching Attribute as a list, given a category.
+
+
This method calls up whatever storage the backend uses.
+
+
Args:
+
category (str or None): The category to query.
+
+
Returns:
+
attrs (list): The discovered Attributes.
+
"""
+
raise NotImplementedError()
+
+
def _full_cache(self):
"""Cache all attributes of this object"""
if not _TYPECLASS_AGGRESSIVE_CACHE:
return
-
attrs = self._query_all()
-
self._cache = dict(
-
(
-
"%s-%s"
-
% (
-
to_str(attr.db_key).lower(),
-
attr.db_category.lower() if attr.db_category else None,
-
),
-
attr,
-
)
+
attrs = self.query_all()
+
self._cache = {
+
f"{to_str(attr.key).lower()}-{attr.category.lower() if attr.category else None}": attr
for attr in attrs
-
)
+
}
self._cache_complete = True
-
def _getcache(self, key=None, category=None):
+
def _get_cache_key(self, key, category):
+
"""
+
+
+
Args:
+
key (str): The key of the Attribute being searched for.
+
category (str or None): The category of the desired Attribute.
+
+
Returns:
+
attribute (IAttribute): A single Attribute.
+
"""
+
cachekey = "%s-%s" % (key, category)
+
cachefound = False
+
try:
+
attr = _TYPECLASS_AGGRESSIVE_CACHE and self._cache[cachekey]
+
cachefound = True
+
except KeyError:
+
attr = None
+
+
if attr and (not hasattr(attr, "pk") and attr.pk is None):
+
# clear out Attributes deleted from elsewhere. We must search this anew.
+
attr = None
+
cachefound = False
+
del self._cache[cachekey]
+
if cachefound and _TYPECLASS_AGGRESSIVE_CACHE:
+
if attr:
+
return [attr] # return cached entity
+
else:
+
return [] # no such attribute: return an empty list
+
else:
+
conn = self.query_key(key, category)
+
if conn:
+
attr = conn[0].attribute
+
if _TYPECLASS_AGGRESSIVE_CACHE:
+
self._cache[cachekey] = attr
+
return [attr] if attr.pk else []
+
else:
+
# There is no such attribute. We will explicitly save that
+
# in our cache to avoid firing another query if we try to
+
# retrieve that (non-existent) attribute again.
+
if _TYPECLASS_AGGRESSIVE_CACHE:
+
self._cache[cachekey] = None
+
return []
+
+
def _get_cache_category(self, category):
+
"""
+
Retrieves Attribute list (by category) from cache.
+
+
Args:
+
category (str or None): The category to query.
+
+
Returns:
+
attrs (list): The discovered Attributes.
+
"""
+
catkey = "-%s" % category
+
if _TYPECLASS_AGGRESSIVE_CACHE and catkey in self._catcache:
+
return [attr for key, attr in self._cache.items() if key.endswith(catkey) and attr]
+
else:
+
# we have to query to make this category up-date in the cache
+
attrs = self.query_category(category)
+
if _TYPECLASS_AGGRESSIVE_CACHE:
+
for attr in attrs:
+
if attr.pk:
+
cachekey = "%s-%s" % (attr.key, category)
+
self._cache[cachekey] = attr
+
# mark category cache as up-to-date
+
self._catcache[catkey] = True
+
return attrs
+
+
def _get_cache(self, key=None, category=None):
"""
Retrieve from cache or database (always caches)
@@ -332,85 +481,31 @@
key = key.strip().lower() if key else None
category = category.strip().lower() if category else None
if key:
-
cachekey = "%s-%s" % (key, category)
-
cachefound = False
-
try:
-
attr = _TYPECLASS_AGGRESSIVE_CACHE and self._cache[cachekey]
-
cachefound = True
-
except KeyError:
-
attr = None
+
return self._get_cache_key(key, category)
+
return self._get_cache_category(category)
-
if attr and (not hasattr(attr, "pk") and attr.pk is None):
-
# clear out Attributes deleted from elsewhere. We must search this anew.
-
attr = None
-
cachefound = False
-
del self._cache[cachekey]
-
if cachefound and _TYPECLASS_AGGRESSIVE_CACHE:
-
if attr:
-
return [attr] # return cached entity
-
else:
-
return [] # no such attribute: return an empty list
-
else:
-
query = {
-
"%s__id" % self._model: self._objid,
-
"attribute__db_model__iexact": self._model,
-
"attribute__db_attrtype": self._attrtype,
-
"attribute__db_key__iexact": key.lower(),
-
"attribute__db_category__iexact": category.lower() if category else None,
-
}
-
if not self.obj.pk:
-
return []
-
conn = getattr(self.obj, self._m2m_fieldname).through.objects.filter(**query)
-
if conn:
-
attr = conn[0].attribute
-
if _TYPECLASS_AGGRESSIVE_CACHE:
-
self._cache[cachekey] = attr
-
return [attr] if attr.pk else []
-
else:
-
# There is no such attribute. We will explicitly save that
-
# in our cache to avoid firing another query if we try to
-
# retrieve that (non-existent) attribute again.
-
if _TYPECLASS_AGGRESSIVE_CACHE:
-
self._cache[cachekey] = None
-
return []
-
else:
-
# only category given (even if it's None) - we can't
-
# assume the cache to be complete unless we have queried
-
# for this category before
-
catkey = "-%s" % category
-
if _TYPECLASS_AGGRESSIVE_CACHE and catkey in self._catcache:
-
return [attr for key, attr in self._cache.items() if key.endswith(catkey) and attr]
-
else:
-
# we have to query to make this category up-date in the cache
-
query = {
-
"%s__id" % self._model: self._objid,
-
"attribute__db_model__iexact": self._model,
-
"attribute__db_attrtype": self._attrtype,
-
"attribute__db_category__iexact": category.lower() if category else None,
-
}
-
attrs = [
-
conn.attribute
-
for conn in getattr(self.obj, self._m2m_fieldname).through.objects.filter(
-
**query
-
)
-
]
-
if _TYPECLASS_AGGRESSIVE_CACHE:
-
for attr in attrs:
-
if attr.pk:
-
cachekey = "%s-%s" % (attr.db_key, category)
-
self._cache[cachekey] = attr
-
# mark category cache as up-to-date
-
self._catcache[catkey] = True
-
return attrs
+
[docs] def get(self, key=None, category=None):
+
"""
+
Frontend for .get_cache. Retrieves Attribute(s).
-
def _setcache(self, key, category, attr_obj):
+
Args:
+
key (str, optional): Attribute key to query for
+
category (str, optional): Attribiute category
+
+
Returns:
+
args (list): Returns a list of zero or more matches
+
found from cache or database.
+
"""
+
return self._get_cache(key, category)
+
+
def _set_cache(self, key, category, attr_obj):
"""
Update cache.
Args:
key (str): A cleaned key string
category (str or None): A cleaned category name
-
attr_obj (Attribute): The newly saved attribute
+
attr_obj (IAttribute): The newly saved attribute
"""
if not _TYPECLASS_AGGRESSIVE_CACHE:
@@ -424,7 +519,7 @@
self._catcache.pop(catkey, None)
self._cache_complete = False
-
def _delcache(self, key, category):
+
def _delete_cache(self, key, category):
"""
Remove attribute from cache
@@ -447,7 +542,7 @@
self._catcache.pop(catkey, None)
self._cache_complete = False
-
[docs] def reset_cache(self):
+
[docs] def reset_cache(self):
"""
Reset cache from the outside.
"""
@@ -455,6 +550,431 @@
self._cache = {}
self._catcache = {}
+
[docs] def do_create_attribute(self, key, category, lockstring, value, strvalue):
+
"""
+
Does the hard work of actually creating Attributes, whatever is needed.
+
+
Args:
+
key (str): The Attribute's key.
+
category (str or None): The Attribute's category, or None
+
lockstring (str): Any locks for the Attribute.
+
value (obj): The Value of the Attribute.
+
strvalue (bool): Signifies if this is a strvalue Attribute. Value MUST be a string or
+
this will lead to Trouble. Ignored for InMemory attributes.
+
+
Returns:
+
attr (IAttribute): The new Attribute.
+
"""
+
raise NotImplementedError()
+
+
[docs] def create_attribute(self, key, category, lockstring, value, strvalue=False, cache=True):
+
"""
+
Creates Attribute (using the class specified for the backend), (optionally) caches it, and returns it.
+
+
This MUST actively save the Attribute to whatever database backend is used, AND
+
call self.set_cache(key, category, new_attrobj)
+
+
Args:
+
key (str): The Attribute's key.
+
category (str or None): The Attribute's category, or None
+
lockstring (str): Any locks for the Attribute.
+
value (obj): The Value of the Attribute.
+
strvalue (bool): Signifies if this is a strvalue Attribute. Value MUST be a string or
+
this will lead to Trouble. Ignored for InMemory attributes.
+
cache (bool): Whether to cache the new Attribute
+
+
Returns:
+
attr (IAttribute): The new Attribute.
+
"""
+
attr = self.do_create_attribute(key, category, lockstring, value, strvalue)
+
if cache:
+
self._set_cache(key, category, attr)
+
return attr
+
+
[docs] def do_update_attribute(self, attr, value):
+
"""
+
Simply sets a new Value to an Attribute.
+
+
Args:
+
attr (IAttribute): The Attribute being changed.
+
value (obj): The Value for the Attribute.
+
+
"""
+
raise NotImplementedError()
+
+
[docs] def do_batch_update_attribute(self, attr_obj, category, lock_storage, new_value, strvalue):
+
"""
+
Called opnly by batch add. For the database backend, this is a method
+
of updating that can alter category and lock-storage.
+
+
Args:
+
attr_obj (IAttribute): The Attribute being altered.
+
category (str or None): The attribute's (new) category.
+
lock_storage (str): The attribute's new locks.
+
new_value (obj): The Attribute's new value.
+
strvalue (bool): Signifies if this is a strvalue Attribute. Value MUST be a string or
+
this will lead to Trouble. Ignored for InMemory attributes.
+
"""
+
raise NotImplementedError()
+
+
[docs] def do_batch_finish(self, attr_objs):
+
"""
+
Called after batch_add completed. Used for handling database operations
+
and/or caching complications.
+
+
Args:
+
attr_objs (list of IAttribute): The Attributes created/updated thus far.
+
+
"""
+
raise NotImplementedError()
+
+
[docs] def batch_add(self, *args, **kwargs):
+
"""
+
Batch-version of `.add()`. This is more efficient than repeat-calling
+
`.add` when having many Attributes to add.
+
+
Args:
+
*args (tuple): Tuples of varying length representing the
+
Attribute to add to this object. Supported tuples are
+
+
- (key, value)
+
- (key, value, category)
+
- (key, value, category, lockstring)
+
- (key, value, category, lockstring, default_access)
+
+
Raises:
+
RuntimeError: If trying to pass a non-iterable as argument.
+
+
Notes:
+
The indata tuple order matters, so if you want a lockstring but no
+
category, set the category to `None`. This method does not have the
+
ability to check editing permissions and is mainly used internally.
+
It does not use the normal `self.add` but applies the Attributes
+
directly to the database.
+
+
"""
+
new_attrobjs = []
+
strattr = kwargs.get("strattr", False)
+
for tup in args:
+
if not is_iter(tup) or len(tup) < 2:
+
raise RuntimeError("batch_add requires iterables as arguments (got %r)." % tup)
+
ntup = len(tup)
+
keystr = str(tup[0]).strip().lower()
+
new_value = tup[1]
+
category = str(tup[2]).strip().lower() if ntup > 2 and tup[2] is not None else None
+
lockstring = tup[3] if ntup > 3 else ""
+
+
attr_objs = self._get_cache(keystr, category)
+
+
if attr_objs:
+
attr_obj = attr_objs[0]
+
# update an existing attribute object
+
self.do_batch_update_attribute(attr_obj, category, lockstring, new_value, strattr)
+
else:
+
new_attr = self.do_create_attribute(
+
keystr, category, lockstring, new_value, strvalue=strattr
+
)
+
new_attrobjs.append(new_attr)
+
if new_attrobjs:
+
self.do_batch_finish(new_attrobjs)
+
+
[docs] def do_delete_attribute(self, attr):
+
"""
+
Does the hard work of actually deleting things.
+
+
Args:
+
attr (IAttribute): The attribute to delete.
+
"""
+
raise NotImplementedError()
+
+
[docs] def delete_attribute(self, attr):
+
"""
+
Given an Attribute, deletes it. Also remove it from cache.
+
+
Args:
+
attr (IAttribute): The attribute to delete.
+
"""
+
if not attr:
+
return
+
self._delete_cache(attr.key, attr.category)
+
self.do_delete_attribute(attr)
+
+
[docs] def update_attribute(self, attr, value):
+
"""
+
Simply updates an Attribute.
+
+
Args:
+
attr (IAttribute): The attribute to delete.
+
value (obj): The new value.
+
"""
+
self.do_update_attribute(attr, value)
+
+
[docs] def do_batch_delete(self, attribute_list):
+
"""
+
Given a list of attributes, deletes them all.
+
The default implementation is fine, but this is overridable since some databases may allow
+
for a better method.
+
+
Args:
+
attribute_list (list of IAttribute):
+
"""
+
for attribute in attribute_list:
+
self.delete_attribute(attribute)
+
+
[docs] def clear_attributes(self, category, accessing_obj, default_access):
+
"""
+
Remove all Attributes on this object.
+
+
Args:
+
category (str, optional): If given, clear only Attributes
+
of this category.
+
accessing_obj (object, optional): If given, check the
+
`attredit` lock on each Attribute before continuing.
+
default_access (bool, optional): Use this permission as
+
fallback if `access_obj` is given but there is no lock of
+
type `attredit` on the Attribute in question.
+
+
"""
+
category = category.strip().lower() if category is not None else None
+
+
if not self._cache_complete:
+
self._full_cache()
+
+
if category is not None:
+
attrs = [attr for attr in self._cache.values() if attr.category == category]
+
else:
+
attrs = self._cache.values()
+
+
if accessing_obj:
+
self.do_batch_delete(
+
[
+
attr
+
for attr in attrs
+
if attr.access(accessing_obj, self._attredit, default=default_access)
+
]
+
)
+
else:
+
# have to cast the results to a list or we'll get a RuntimeError for removing from the dict we're iterating
+
self.do_batch_delete(list(attrs))
+
self.reset_cache()
+
+
[docs] def get_all_attributes(self):
+
"""
+
Simply returns all Attributes of this object, sorted by their IDs.
+
+
Returns:
+
attributes (list of IAttribute)
+
"""
+
if _TYPECLASS_AGGRESSIVE_CACHE:
+
if not self._cache_complete:
+
self._full_cache()
+
return sorted([attr for attr in self._cache.values() if attr], key=lambda o: o.id)
+
else:
+
return sorted([attr for attr in self.query_all() if attr], key=lambda o: o.id)
+
+
+
[docs]class InMemoryAttributeBackend(IAttributeBackend):
+
"""
+
This Backend for Attributes stores NOTHING in the database. Everything is kept in memory, and normally lost
+
on a crash, reload, shared memory flush, etc. It generates IDs for the Attributes it manages, but these are
+
of little importance beyond sorting and satisfying the caching logic to know an Attribute hasn't been
+
deleted out from under the cache's nose.
+
+
"""
+
+
_attrclass = InMemoryAttribute
+
+
[docs] def __init__(self, handler, attrtype):
+
super().__init__(handler, attrtype)
+
self._storage = dict()
+
self._category_storage = defaultdict(list)
+
self._id_counter = 0
+
+
def _next_id(self):
+
"""
+
Increments the internal ID counter and returns the new value.
+
+
Returns:
+
next_id (int): A simple integer.
+
"""
+
self._id_counter += 1
+
return self._id_counter
+
+
[docs] def query_all(self):
+
return self._storage.values()
+
+
[docs] def query_key(self, key, category):
+
found = self._storage.get((key, category), None)
+
if found:
+
return [found]
+
return []
+
+
[docs] def query_category(self, category):
+
if category is None:
+
return self._storage.values()
+
return self._category_storage.get(category, [])
+
+
[docs] def do_create_attribute(self, key, category, lockstring, value, strvalue):
+
"""
+
See parent class.
+
+
strvalue has no meaning for InMemory attributes.
+
+
"""
+
new_attr = self._attrclass(
+
pk=self._next_id(), key=key, category=category, lock_storage=lockstring, value=value
+
)
+
self._storage[(key, category)] = new_attr
+
self._category_storage[category].append(new_attr)
+
return new_attr
+
+
[docs] def do_update_attribute(self, attr, value):
+
attr.value = value
+
+
[docs] def do_batch_update_attribute(self, attr_obj, category, lock_storage, new_value, strvalue):
+
"""
+
No need to bother saving anything. Just set some values.
+
"""
+
attr_obj.db_category = category
+
attr_obj.db_lock_storage = lock_storage if lock_storage else ""
+
attr_obj.value = new_value
+
+
[docs] def do_batch_finish(self, attr_objs):
+
"""
+
Nothing to do here for In-Memory.
+
+
Args:
+
attr_objs (list of IAttribute): The Attributes created/updated thus far.
+
"""
+
pass
+
+
[docs] def do_delete_attribute(self, attr):
+
"""
+
Removes the Attribute from local storage. Once it's out of the cache, garbage collection will handle the rest.
+
+
Args:
+
attr (IAttribute): The attribute to delete.
+
"""
+
del self._storage[(attr.key, attr.category)]
+
self._category_storage[attr.category].remove(attr)
+
+
+
[docs]class ModelAttributeBackend(IAttributeBackend):
+
"""
+
Uses Django models for storing Attributes.
+
"""
+
+
_attrclass = Attribute
+
_m2m_fieldname = "db_attributes"
+
+
[docs] def __init__(self, handler, attrtype):
+
super().__init__(handler, attrtype)
+
self._model = to_str(handler.obj.__dbclass__.__name__.lower())
+
+
[docs] def query_all(self):
+
query = {
+
"%s__id" % self._model: self._objid,
+
"attribute__db_model__iexact": self._model,
+
"attribute__db_attrtype": self._attrtype,
+
}
+
return [
+
conn.attribute
+
for conn in getattr(self.obj, self._m2m_fieldname).through.objects.filter(**query)
+
]
+
+
[docs] def query_key(self, key, category):
+
query = {
+
"%s__id" % self._model: self._objid,
+
"attribute__db_model__iexact": self._model,
+
"attribute__db_attrtype": self._attrtype,
+
"attribute__db_key__iexact": key.lower(),
+
"attribute__db_category__iexact": category.lower() if category else None,
+
}
+
if not self.obj.pk:
+
return []
+
return getattr(self.obj, self._m2m_fieldname).through.objects.filter(**query)
+
+
[docs] def query_category(self, category):
+
query = {
+
"%s__id" % self._model: self._objid,
+
"attribute__db_model__iexact": self._model,
+
"attribute__db_attrtype": self._attrtype,
+
"attribute__db_category__iexact": category.lower() if category else None,
+
}
+
return [
+
conn.attribute
+
for conn in getattr(self.obj, self._m2m_fieldname).through.objects.filter(**query)
+
]
+
+
[docs] def do_create_attribute(self, key, category, lockstring, value, strvalue):
+
kwargs = {
+
"db_key": key,
+
"db_category": category,
+
"db_model": self._model,
+
"db_lock_storage": lockstring if lockstring else "",
+
"db_attrtype": self._attrtype,
+
}
+
if strvalue:
+
kwargs["db_value"] = None
+
kwargs["db_strvalue"] = value
+
else:
+
kwargs["db_value"] = to_pickle(value)
+
kwargs["db_strvalue"] = None
+
new_attr = self._attrclass(**kwargs)
+
new_attr.save()
+
getattr(self.obj, self._m2m_fieldname).add(new_attr)
+
self._set_cache(key, category, new_attr)
+
return new_attr
+
+
[docs] def do_update_attribute(self, attr, value):
+
attr.value = value
+
+
[docs] def do_batch_update_attribute(self, attr_obj, category, lock_storage, new_value, strvalue):
+
attr_obj.db_category = category
+
attr_obj.db_lock_storage = lock_storage if lock_storage else ""
+
if strvalue:
+
# store as a simple string (will not notify OOB handlers)
+
attr_obj.db_strvalue = new_value
+
attr_obj.value = None
+
else:
+
# store normally (this will also notify OOB handlers)
+
attr_obj.value = new_value
+
attr_obj.db_strvalue = None
+
attr_obj.save(update_fields=["db_strvalue", "db_value", "db_category", "db_lock_storage"])
+
+
[docs] def do_batch_finish(self, attr_objs):
+
# Add new objects to m2m field all at once
+
getattr(self.obj, self._m2m_fieldname).add(*attr_objs)
+
+
[docs] def do_delete_attribute(self, attr):
+
try:
+
attr.delete()
+
except AssertionError:
+
# This could happen if the Attribute has already been deleted.
+
pass
+
+
+
[docs]class AttributeHandler:
+
"""
+
Handler for adding Attributes to the object.
+
"""
+
+
_attrcreate = "attrcreate"
+
_attredit = "attredit"
+
_attrread = "attrread"
+
_attrtype = None
+
+
[docs] def __init__(self, obj, backend_class):
+
"""
+
Setup the AttributeHandler.
+
+
Args:
+
obj (TypedObject): An Account, Object, Channel, ServerSession (not technically a typed object), etc.
+
backend_class (IAttributeBackend class): The class of the backend to use.
+
"""
+
self.obj = obj
+
self.backend = backend_class(self, self._attrtype)
+
[docs] def has(self, key=None, category=None):
"""
Checks if the given Attribute (or list of Attributes) exists on
@@ -476,7 +996,7 @@
category = category.strip().lower() if category is not None else None
for keystr in make_iter(key):
keystr = key.strip().lower()
-
ret.extend(bool(attr) for attr in self._getcache(keystr, category))
+
ret.extend(bool(attr) for attr in self.backend.get(keystr, category))
return ret[0] if len(ret) == 1 else ret
[docs] def get(
@@ -534,7 +1054,7 @@
ret = []
for keystr in make_iter(key):
# it's okay to send a None key
-
attr_objs = self._getcache(keystr, category)
+
attr_objs = self.backend.get(keystr, category)
if attr_objs:
ret.extend(attr_objs)
elif raise_exception:
@@ -600,33 +1120,15 @@
category = category.strip().lower() if category is not None else None
keystr = key.strip().lower()
-
attr_obj = self._getcache(key, category)
+
attr_obj = self.backend.get(key, category)
if attr_obj:
# update an existing attribute object
attr_obj = attr_obj[0]
-
if strattr:
-
# store as a simple string (will not notify OOB handlers)
-
attr_obj.db_strvalue = value
-
attr_obj.save(update_fields=["db_strvalue"])
-
else:
-
# store normally (this will also notify OOB handlers)
-
attr_obj.value = value
+
self.backend.update_attribute(attr_obj, value)
else:
# create a new Attribute (no OOB handlers can be notified)
-
kwargs = {
-
"db_key": keystr,
-
"db_category": category,
-
"db_model": self._model,
-
"db_attrtype": self._attrtype,
-
"db_value": None if strattr else to_pickle(value),
-
"db_strvalue": value if strattr else None,
-
}
-
new_attr = Attribute(**kwargs)
-
new_attr.save()
-
getattr(self.obj, self._m2m_fieldname).add(new_attr)
-
# update cache
-
self._setcache(keystr, category, new_attr)
+
self.backend.create_attribute(keystr, category, lockstring, value, strattr)
[docs] def batch_add(self, *args, **kwargs):
"""
@@ -638,10 +1140,10 @@
length) representing the Attribute to add to this object.
Supported tuples are
-
- `(key, value)`
-
- `(key, value, category)`
-
- `(key, value, category, lockstring)`
-
- `(key, value, category, lockstring, default_access)`
+
- (key, value)
+
- (key, value, category)
+
- (key, value, category, lockstring)
+
- (key, value, category, lockstring, default_access)
Keyword Args:
strattr (bool): If `True`, value must be a string. This
@@ -661,50 +1163,7 @@
to the database.
"""
-
new_attrobjs = []
-
strattr = kwargs.get("strattr", False)
-
for tup in args:
-
if not is_iter(tup) or len(tup) < 2:
-
raise RuntimeError("batch_add requires iterables as arguments (got %r)." % tup)
-
ntup = len(tup)
-
keystr = str(tup[0]).strip().lower()
-
new_value = tup[1]
-
category = str(tup[2]).strip().lower() if ntup > 2 and tup[2] is not None else None
-
lockstring = tup[3] if ntup > 3 else ""
-
-
attr_objs = self._getcache(keystr, category)
-
-
if attr_objs:
-
attr_obj = attr_objs[0]
-
# update an existing attribute object
-
attr_obj.db_category = category
-
attr_obj.db_lock_storage = lockstring or ""
-
attr_obj.save(update_fields=["db_category", "db_lock_storage"])
-
if strattr:
-
# store as a simple string (will not notify OOB handlers)
-
attr_obj.db_strvalue = new_value
-
attr_obj.save(update_fields=["db_strvalue"])
-
else:
-
# store normally (this will also notify OOB handlers)
-
attr_obj.value = new_value
-
else:
-
# create a new Attribute (no OOB handlers can be notified)
-
kwargs = {
-
"db_key": keystr,
-
"db_category": category,
-
"db_model": self._model,
-
"db_attrtype": self._attrtype,
-
"db_value": None if strattr else to_pickle(new_value),
-
"db_strvalue": new_value if strattr else None,
-
"db_lock_storage": lockstring or "",
-
}
-
new_attr = Attribute(**kwargs)
-
new_attr.save()
-
new_attrobjs.append(new_attr)
-
self._setcache(keystr, category, new_attr)
-
if new_attrobjs:
-
# Add new objects to m2m field all at once
-
getattr(self.obj, self._m2m_fieldname).add(*new_attrobjs)
+
self.backend.batch_add(*args, **kwargs)
[docs] def remove(
self,
@@ -753,20 +1212,13 @@
for keystr in make_iter(key):
keystr = keystr.lower()
-
attr_objs = self._getcache(keystr, category)
+
attr_objs = self.backend.get(keystr, category)
for attr_obj in attr_objs:
if not (
accessing_obj
and not attr_obj.access(accessing_obj, self._attredit, default=default_access)
):
-
try:
-
attr_obj.delete()
-
except AssertionError:
-
print("Assertionerror for attr.delete()")
-
# this happens if the attr was already deleted
-
pass
-
finally:
-
self._delcache(keystr, category)
+
self.backend.delete_attribute(attr_obj)
if not attr_objs and raise_exception:
raise AttributeError
@@ -784,27 +1236,7 @@
type `attredit` on the Attribute in question.
"""
-
category = category.strip().lower() if category is not None else None
-
-
if not self._cache_complete:
-
self._fullcache()
-
-
if category is not None:
-
attrs = [attr for attr in self._cache.values() if attr.category == category]
-
else:
-
attrs = self._cache.values()
-
-
if accessing_obj:
-
[
-
attr.delete()
-
for attr in attrs
-
if attr and attr.access(accessing_obj, self._attredit, default=default_access)
-
]
-
else:
-
[attr.delete() for attr in attrs if attr and attr.pk]
-
self._cache = {}
-
self._catcache = {}
-
self._cache_complete = False
+
self.backend.clear_attributes(category, accessing_obj, default_access)
[docs] def all(self, accessing_obj=None, default_access=True):
"""
@@ -823,12 +1255,7 @@
their values!) in the handler.
"""
-
if _TYPECLASS_AGGRESSIVE_CACHE:
-
if not self._cache_complete:
-
self._fullcache()
-
attrs = sorted([attr for attr in self._cache.values() if attr], key=lambda o: o.id)
-
else:
-
attrs = sorted([attr for attr in self._query_all() if attr], key=lambda o: o.id)
+
attrs = self.backend.get_all_attributes()
if accessing_obj:
return [
@@ -837,7 +1264,42 @@
if attr.access(accessing_obj, self._attredit, default=default_access)
]
else:
-
return attrs
+
return attrs
+
+[docs] def reset_cache(self):
+
self.backend.reset_cache()
+
+
+# DbHolders for .db and .ndb properties on Typeclasses.
+
+_GA = object.__getattribute__
+_SA = object.__setattr__
+
+
+[docs]class DbHolder(object):
+
"Holder for allowing property access of attributes"
+
+
[docs] def __init__(self, obj, name, manager_name="attributes"):
+
_SA(self, name, _GA(obj, manager_name))
+
_SA(self, "name", name)
+
+
def __getattribute__(self, attrname):
+
if attrname == "all":
+
# we allow to overload our default .all
+
attr = _GA(self, _GA(self, "name")).get("all")
+
return attr if attr else _GA(self, "all")
+
return _GA(self, _GA(self, "name")).get(attrname)
+
+
def __setattr__(self, attrname, value):
+
_GA(self, _GA(self, "name")).add(attrname, value)
+
+
def __delattr__(self, attrname):
+
_GA(self, _GA(self, "name")).remove(attrname)
+
+
[docs] def get_all(self):
+
return _GA(self, _GA(self, "name")).get_all_attributes()
+
+
all = property(get_all)
# Nick templating
@@ -889,13 +1351,13 @@
matched by the in_template.
Returns:
- (regex, str): Regex to match against strings and a template
- Template with markers `{arg1}`, `{arg2}`, etc for
- replacement using the standard `.format` method.
+ regex (regex): Regex to match against strings
+ template (str): Template with markers ``{arg1}, {arg2}``, etc for
+ replacement using the standard .format method.
Raises:
- attributes.NickTemplateInvalid: If the in/out template does not have a matching
- number of $args.
+ evennia.typecalasses.attributes.NickTemplateInvalid: If the in/out
+ template does not have a matching number of `$args`.
"""
@@ -1080,95 +1542,6 @@
if is_match:
break
return raw_string
-
-
-[docs]class NAttributeHandler(object):
-
"""
-
This stand-alone handler manages non-database saving.
-
It is similar to `AttributeHandler` and is used
-
by the `.ndb` handler in the same way as `.db` does
-
for the `AttributeHandler`.
-
"""
-
-
[docs] def __init__(self, obj):
-
"""
-
Initialized on the object
-
"""
-
self._store = {}
-
self.obj = weakref.proxy(obj)
-
-
[docs] def has(self, key):
-
"""
-
Check if object has this attribute or not.
-
-
Args:
-
key (str): The Nattribute key to check.
-
-
Returns:
-
has_nattribute (bool): If Nattribute is set or not.
-
-
"""
-
return key in self._store
-
-
[docs] def get(self, key):
-
"""
-
Get the named key value.
-
-
Args:
-
key (str): The Nattribute key to get.
-
-
Returns:
-
the value of the Nattribute.
-
-
"""
-
return self._store.get(key, None)
-
-
[docs] def add(self, key, value):
-
"""
-
Add new key and value.
-
-
Args:
-
key (str): The name of Nattribute to add.
-
value (any): The value to store.
-
-
"""
-
self._store[key] = value
-
-
[docs] def remove(self, key):
-
"""
-
Remove Nattribute from storage.
-
-
Args:
-
key (str): The name of the Nattribute to remove.
-
-
"""
-
if key in self._store:
-
del self._store[key]
-
-
[docs] def clear(self):
-
"""
-
Remove all NAttributes from handler.
-
-
"""
-
self._store = {}
-
-
[docs] def all(self, return_tuples=False):
-
"""
-
List the contents of the handler.
-
-
Args:
-
return_tuples (bool, optional): Defines if the Nattributes
-
are returns as a list of keys or as a list of `(key, value)`.
-
-
Returns:
-
nattributes (list): A list of keys `[key, key, ...]` or a
-
list of tuples `[(key, value), ...]` depending on the
-
setting of `return_tuples`.
-
-
"""
-
if return_tuples:
-
return [(key, value) for (key, value) in self._store.items() if not key.startswith("_")]
-
return [key for key in self._store if not key.startswith("_")]
diff --git a/docs/0.9.5/_modules/evennia/typeclasses/managers.html b/docs/0.9.5/_modules/evennia/typeclasses/managers.html
index 92df063f5d..3810825c74 100644
--- a/docs/0.9.5/_modules/evennia/typeclasses/managers.html
+++ b/docs/0.9.5/_modules/evennia/typeclasses/managers.html
@@ -72,17 +72,15 @@
# Attribute manager methods
[docs] def get_attribute(
-
self, key=None, category=None, value=None, strvalue=None,
-
obj=None, attrtype=None, **kwargs):
+
self, key=None, category=None, value=None, strvalue=None, obj=None, attrtype=None, **kwargs
+
):
"""
-
Return Attribute objects by key, by category, by value, by
-
`strvalue`, by object (it is stored on) or with a combination of
-
those criteria.
+
Return Attribute objects by key, by category, by value, by strvalue, by
+
object (it is stored on) or with a combination of those criteria.
Args:
-
key (str, optional): The attribute's key to search for.
-
category (str, optional): The category of the attribute(s)
-
to search for.
+
key (str, optional): The attribute's key to search for
+
category (str, optional): The category of the attribute(s) to search for.
value (str, optional): The attribute value to search for.
Note that this is not a very efficient operation since it
will query for a pickled entity. Mutually exclusive to
@@ -93,13 +91,13 @@
precedence if given.
obj (Object, optional): On which object the Attribute to
search for is.
-
attrtype (str, optional): An attribute-type to search for.
+
attrype (str, optional): An attribute-type to search for.
By default this is either `None` (normal Attributes) or
`"nick"`.
-
kwargs (any): Currently unused. Reserved for future use.
+
**kwargs (any): Currently unused. Reserved for future use.
Returns:
-
attributes (list): The matching Attributes.
+
list: The matching Attributes.
"""
dbmodel = self.model.__dbclass__.__name__.lower()
@@ -217,7 +215,7 @@
to search for.
obj (Object, optional): On which object the Tag to
search for is.
-
tagtype (str, optional): One of None (normal tags),
+
tagtype (str, optional): One of `None` (normal tags),
"alias" or "permission"
global_search (bool, optional): Include all possible tags,
not just tags on this object
@@ -620,7 +618,7 @@
for parent in (parent for parent in parents if hasattr(parent, "path")):
query = query | Q(db_typeclass_path__exact=parent.path)
# actually query the database
-
return self.filter(query)
+ return super().filter(query)
class TypeclassManager(TypedObjectManager):
diff --git a/docs/0.9.5/_modules/evennia/typeclasses/models.html b/docs/0.9.5/_modules/evennia/typeclasses/models.html
index 48e843b873..700c534889 100644
--- a/docs/0.9.5/_modules/evennia/typeclasses/models.html
+++ b/docs/0.9.5/_modules/evennia/typeclasses/models.html
@@ -65,8 +65,6 @@
This module also contains the Managers for the respective models; inherit from
these to create custom managers.
-----
-
"""
from django.db.models import signals
@@ -79,7 +77,13 @@
from django.utils.encoding import smart_str
from django.utils.text import slugify
-from evennia.typeclasses.attributes import Attribute, AttributeHandler, NAttributeHandler
+from evennia.typeclasses.attributes import (
+ Attribute,
+ AttributeHandler,
+ ModelAttributeBackend,
+ InMemoryAttributeBackend,
+)
+from evennia.typeclasses.attributes import DbHolder
from evennia.typeclasses.tags import Tag, TagHandler, AliasHandler, PermissionHandler
from evennia.utils.idmapper.models import SharedMemoryModel, SharedMemoryModelBase
@@ -203,35 +207,6 @@
return new_class
-class DbHolder(object):
- """
- Holder for allowing property access of attributes.
-
- """
-
- def __init__(self, obj, name, manager_name="attributes"):
- _SA(self, name, _GA(obj, manager_name))
- _SA(self, "name", name)
-
- def __getattribute__(self, attrname):
- if attrname == "all":
- # we allow to overload our default .all
- attr = _GA(self, _GA(self, "name")).get("all")
- return attr if attr else _GA(self, "all")
- return _GA(self, _GA(self, "name")).get(attrname)
-
- def __setattr__(self, attrname, value):
- _GA(self, _GA(self, "name")).add(attrname, value)
-
- def __delattr__(self, attrname):
- _GA(self, _GA(self, "name")).remove(attrname)
-
- def get_all(self):
- return _GA(self, _GA(self, "name")).all()
-
- all = property(get_all)
-
-
#
# Main TypedObject abstraction
#
@@ -355,8 +330,10 @@
than use the one in the model.
Args:
- *args: Passed through to parent.
- **kwargs: Passed through to parent.
+ Passed through to parent.
+
+ Keyword Args:
+ Passed through to parent.
Notes:
The loading mechanism will attempt the following steps:
@@ -383,7 +360,7 @@
# initialize all handlers in a lazy fashion
[docs] @lazy_property
def attributes(self):
-
return AttributeHandler(self)
+ return AttributeHandler(self, ModelAttributeBackend)
[docs] @lazy_property
def locks(self):
@@ -403,7 +380,7 @@
[docs] @lazy_property
def nattributes(self):
-
return NAttributeHandler(self)
+
return AttributeHandler(self, InMemoryAttributeBackend)
diff --git a/docs/0.9.5/api/evennia.contrib.puzzles.html b/docs/0.9.5/api/evennia.contrib.puzzles.html
index 26326be846..d963b40c23 100644
--- a/docs/0.9.5/api/evennia.contrib.puzzles.html
+++ b/docs/0.9.5/api/evennia.contrib.puzzles.html
@@ -205,6 +205,11 @@ to all the variables defined therein.
lock_storage = 'cmd:perm(puzzle) or perm(Builder)'
+
+-
+
search_index_entry = {'aliases': '@puzzlerecipe', 'category': 'puzzles', 'key': '@puzzle', 'tags': '', 'text': "\n Creates a puzzle recipe. A puzzle consists of puzzle-parts that\n the player can 'use' together to create a specified result.\n\n Usage:\n @puzzle name,<part1[,part2,...>] = <result1[,result2,...]>\n\n Example:\n create/drop balloon\n create/drop glass of water\n create/drop water balloon\n @puzzle waterballon,balloon,glass of water = water balloon\n @del ballon, glass of water, water balloon\n @armpuzzle #1\n\n Notes:\n Each part and result are objects that must (temporarily) exist and be placed in their\n corresponding location in order to create the puzzle. After the creation of the puzzle,\n these objects are not needed anymore and can be deleted. Components of the puzzle\n will be re-created by use of the `@armpuzzle` command later.\n\n "}
+
+
@@ -268,6 +273,11 @@ to all the variables defined therein.
lock_storage = 'cmd:perm(puzzleedit) or perm(Builder)'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'puzzles', 'key': '@puzzleedit', 'tags': '', 'text': "\n Edits puzzle properties\n\n Usage:\n @puzzleedit[/delete] <#dbref>\n @puzzleedit <#dbref>/use_success_message = <Custom message>\n @puzzleedit <#dbref>/use_success_location_message = <Custom message from {caller} producing {result_names}>\n @puzzleedit <#dbref>/mask = attr1[,attr2,...]>\n @puzzleedit[/addpart] <#dbref> = <obj[,obj2,...]>\n @puzzleedit[/delpart] <#dbref> = <obj[,obj2,...]>\n @puzzleedit[/addresult] <#dbref> = <obj[,obj2,...]>\n @puzzleedit[/delresult] <#dbref> = <obj[,obj2,...]>\n\n Switches:\n addpart - adds parts to the puzzle\n delpart - removes parts from the puzzle\n addresult - adds results to the puzzle\n delresult - removes results from the puzzle\n delete - deletes the recipe. Existing parts and results aren't modified\n\n mask - attributes to exclude during matching (e.g. location, desc, etc.)\n use_success_location_message containing {result_names} and {caller} will\n automatically be replaced with correct values. Both are optional.\n\n When removing parts/results, it's possible to remove all.\n\n "}
+
+
@@ -315,6 +325,11 @@ to all the variables defined therein.
lock_storage = 'cmd:perm(armpuzzle) or perm(Builder)'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'puzzles', 'key': '@armpuzzle', 'tags': '', 'text': '\n Arms a puzzle by spawning all its parts.\n\n Usage:\n @armpuzzle <puzzle #dbref>\n\n Notes:\n Create puzzles with `@puzzle`; get list of\n defined puzzles using `@lspuzzlerecipes`.\n\n '}
+
+
@@ -363,6 +378,11 @@ to all the variables defined therein.
lock_storage = 'cmd:pperm(use) or pperm(Player)'
+
+-
+
search_index_entry = {'aliases': 'combine', 'category': 'puzzles', 'key': 'use', 'tags': '', 'text': '\n Use an object, or a group of objects at once.\n\n\n Example:\n You look around you and see a pole, a long string, and a needle.\n\n use pole, long string, needle\n\n Genius! You built a fishing pole.\n\n\n Usage:\n use <obj1> [,obj2,...]\n '}
+
+
@@ -407,6 +427,11 @@ to all the variables defined therein.
lock_storage = 'cmd:perm(lspuzzlerecipes) or perm(Builder)'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'puzzles', 'key': '@lspuzzlerecipes', 'tags': '', 'text': '\n Searches for all puzzle recipes\n\n Usage:\n @lspuzzlerecipes\n '}
+
+
@@ -451,6 +476,11 @@ to all the variables defined therein.
lock_storage = 'cmd:perm(lsarmedpuzzles) or perm(Builder)'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'puzzles', 'key': '@lsarmedpuzzles', 'tags': '', 'text': '\n Searches for all armed puzzles\n\n Usage:\n @lsarmedpuzzles\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.rpsystem.html b/docs/0.9.5/api/evennia.contrib.rpsystem.html
index 6397a55de3..7031c3d5de 100644
--- a/docs/0.9.5/api/evennia.contrib.rpsystem.html
+++ b/docs/0.9.5/api/evennia.contrib.rpsystem.html
@@ -265,7 +265,10 @@ langname can be None.
- Raises
-rplanguage.LanguageError – If an invalid language was specified.
+-
Notes
@@ -550,6 +553,11 @@ mechanism. This is useful for adding masks/hoods etc.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'command', 'tags': '', 'text': 'simple parent'}
+
+
@@ -603,6 +611,11 @@ a different language.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': ':', 'category': 'general', 'key': 'emote', 'tags': '', 'text': '\n Emote an action, allowing dynamic replacement of\n text in the emote.\n\n Usage:\n emote text\n\n Example:\n emote /me looks around.\n emote With a flurry /me attacks /tall man with his sword.\n emote "Hello", /me says.\n\n Describes an event in the world. This allows the use of /ref\n markers to replace with the short descriptions or recognized\n strings of objects in the same room. These will be translated to\n emotes to match each person seeing it. Use "..." for saying\n things and langcode"..." without spaces to say something in\n a different language.\n\n '}
+
+
@@ -646,6 +659,11 @@ a different language.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '" \'', 'category': 'general', 'key': 'say', 'tags': '', 'text': '\n speak as your character\n\n Usage:\n say <message>\n\n Talk to those in your current location.\n '}
+
+
@@ -689,6 +707,11 @@ a different language.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'sdesc', 'tags': '', 'text': '\n Assign yourself a short description (sdesc).\n\n Usage:\n sdesc <short description>\n\n Assigns a short description to yourself.\n\n '}
+
+
@@ -747,6 +770,11 @@ sdesc in the emote, regardless of who is seeing it.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'pose', 'tags': '', 'text': "\n Set a static pose\n\n Usage:\n pose <pose>\n pose default <pose>\n pose reset\n pose obj = <pose>\n pose default obj = <pose>\n pose reset obj =\n\n Examples:\n pose leans against the tree\n pose is talking to the barkeep.\n pose box = is sitting on the floor.\n\n Set a static pose. This is the end of a full sentence that starts\n with your sdesc. If no full stop is given, it will be added\n automatically. The default pose is the pose you get when using\n pose reset. Note that you can use sdescs/recogs to reference\n people in your pose, but these always appear as that person's\n sdesc in the emote, regardless of who is seeing it.\n\n "}
+
+
@@ -772,7 +800,7 @@ Using the command without arguments will list all current recogs.
-
-
aliases = ['recognize', 'forget']
+aliases = ['forget', 'recognize']
@@ -797,6 +825,11 @@ Using the command without arguments will list all current recogs.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'forget recognize', 'category': 'general', 'key': 'recog', 'tags': '', 'text': '\n Recognize another person in the same room.\n\n Usage:\n recog\n recog sdesc as alias\n forget alias\n\n Example:\n recog tall man as Griatch\n forget griatch\n\n This will assign a personal alias for a person, or forget said alias.\n Using the command without arguments will list all current recogs.\n\n '}
+
+
@@ -841,6 +874,11 @@ set in self.parse())
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'unmask', 'category': 'general', 'key': 'mask', 'tags': '', 'text': "\n Wear a mask\n\n Usage:\n mask <new sdesc>\n unmask\n\n This will put on a mask to hide your identity. When wearing\n a mask, your sdesc will be replaced by the sdesc you pick and\n people's recognitions of you will be disabled.\n\n "}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.simpledoor.html b/docs/0.9.5/api/evennia.contrib.simpledoor.html
index 844a428a2b..b91b8e7d30 100644
--- a/docs/0.9.5/api/evennia.contrib.simpledoor.html
+++ b/docs/0.9.5/api/evennia.contrib.simpledoor.html
@@ -179,6 +179,11 @@ unique.
lock_storage = 'cmd:perm(open) or perm(Builder)'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'building', 'key': 'open', 'tags': '', 'text': '\n open a new exit from the current room\n\n Usage:\n open <new exit>[;alias;alias..][:typeclass] [,<return exit>[;alias;..][:typeclass]]] = <destination>\n\n Handles the creation of exits. If a destination is given, the exit\n will point there. The <return exit> argument sets up an exit at the\n destination leading back to the current room. Destination name\n can be given both as a #dbref and a name, if that name is globally\n unique.\n\n '}
+
+
@@ -222,6 +227,11 @@ close <door>
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'close', 'category': 'general', 'key': 'open', 'tags': '', 'text': '\n Open and close a door\n\n Usage:\n open <door>\n close <door>\n\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.slow_exit.html b/docs/0.9.5/api/evennia.contrib.slow_exit.html
index fe21819461..6234747004 100644
--- a/docs/0.9.5/api/evennia.contrib.slow_exit.html
+++ b/docs/0.9.5/api/evennia.contrib.slow_exit.html
@@ -133,6 +133,11 @@ is assumed.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'setspeed', 'tags': '', 'text': "\n set your movement speed\n\n Usage:\n setspeed stroll|walk|run|sprint\n\n This will set your movement speed, determining how long time\n it takes to traverse exits. If no speed is set, 'walk' speed\n is assumed.\n "}
+
+
@@ -172,6 +177,11 @@ stored deferred from the exit traversal above.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'stop', 'tags': '', 'text': '\n stop moving\n\n Usage:\n stop\n\n Stops the current movement, if any.\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.talking_npc.html b/docs/0.9.5/api/evennia.contrib.talking_npc.html
index c8d6416183..df16543092 100644
--- a/docs/0.9.5/api/evennia.contrib.talking_npc.html
+++ b/docs/0.9.5/api/evennia.contrib.talking_npc.html
@@ -120,6 +120,11 @@ that NPC and give you options on what to talk about.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'talk', 'tags': '', 'text': '\n Talks to an npc\n\n Usage:\n talk\n\n This command is only available if a talkative non-player-character\n (NPC) is actually present. It will strike up a conversation with\n that NPC and give you options on what to talk about.\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.tree_select.html b/docs/0.9.5/api/evennia.contrib.tree_select.html
index 4c0ffaf8f6..970329f94b 100644
--- a/docs/0.9.5/api/evennia.contrib.tree_select.html
+++ b/docs/0.9.5/api/evennia.contrib.tree_select.html
@@ -369,6 +369,11 @@ set in self.parse())
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'namecolor', 'tags': '', 'text': '\n Set or remove a special color on your name. Just an example for the\n easy menu selection tree contrib.\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_basic.html b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_basic.html
index fb5d9b0057..5536932541 100644
--- a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_basic.html
+++ b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_basic.html
@@ -500,6 +500,11 @@ When it’s your turn, you can attack other characters.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'fight', 'tags': '', 'text': "\n Starts a fight with everyone in the same room as you.\n\n Usage:\n fight\n\n When you start a fight, everyone in the room who is able to\n fight is added to combat, and a turn order is randomly rolled.\n When it's your turn, you can attack other characters.\n "}
+
+
@@ -539,6 +544,11 @@ a chance to hit, and if successful, will deal damage.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'attack', 'tags': '', 'text': '\n Attacks another character.\n\n Usage:\n attack <target>\n\n When in a fight, you may attack another character. The attack has\n a chance to hit, and if successful, will deal damage.\n '}
+
+
@@ -559,7 +569,7 @@ if there are still any actions you can take.
-
-
aliases = ['hold', 'wait']
+aliases = ['wait', 'hold']
@@ -578,6 +588,11 @@ if there are still any actions you can take.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}
+
+
@@ -618,6 +633,11 @@ fight ends.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'spare', 'category': 'combat', 'key': 'disengage', 'tags': '', 'text': "\n Passes your turn and attempts to end combat.\n\n Usage:\n disengage\n\n Ends your turn early and signals that you're trying to end\n the fight. If all participants in a fight disengage, the\n fight ends.\n "}
+
+
@@ -657,6 +677,11 @@ rest if you’re not in a fight.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'rest', 'tags': '', 'text': "\n Recovers damage.\n\n Usage:\n rest\n\n Resting recovers your HP to its maximum, but you can only\n rest if you're not in a fight.\n "}
+
+
@@ -698,6 +723,11 @@ topics related to the game.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '?', 'category': 'general', 'key': 'help', 'tags': '', 'text': '\n View help or a list of topics\n\n Usage:\n help <topic or command>\n help list\n help all\n\n This will search for help on commands and other\n topics related to the game.\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_equip.html b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_equip.html
index fc690aa45f..7bfc60ea26 100644
--- a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_equip.html
+++ b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_equip.html
@@ -617,6 +617,11 @@ When it’s your turn, you can attack other characters.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'fight', 'tags': '', 'text': "\n Starts a fight with everyone in the same room as you.\n\n Usage:\n fight\n\n When you start a fight, everyone in the room who is able to\n fight is added to combat, and a turn order is randomly rolled.\n When it's your turn, you can attack other characters.\n "}
+
+
@@ -656,6 +661,11 @@ a chance to hit, and if successful, will deal damage.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'attack', 'tags': '', 'text': '\n Attacks another character.\n\n Usage:\n attack <target>\n\n When in a fight, you may attack another character. The attack has\n a chance to hit, and if successful, will deal damage.\n '}
+
+
@@ -676,7 +686,7 @@ if there are still any actions you can take.
-
-
aliases = ['hold', 'wait']
+aliases = ['wait', 'hold']
@@ -695,6 +705,11 @@ if there are still any actions you can take.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}
+
+
@@ -735,6 +750,11 @@ fight ends.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'spare', 'category': 'combat', 'key': 'disengage', 'tags': '', 'text': "\n Passes your turn and attempts to end combat.\n\n Usage:\n disengage\n\n Ends your turn early and signals that you're trying to end\n the fight. If all participants in a fight disengage, the\n fight ends.\n "}
+
+
@@ -774,6 +794,11 @@ rest if you’re not in a fight.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'rest', 'tags': '', 'text': "\n Recovers damage.\n\n Usage:\n rest\n\n Resting recovers your HP to its maximum, but you can only\n rest if you're not in a fight.\n "}
+
+
@@ -815,6 +840,11 @@ topics related to the game.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '?', 'category': 'general', 'key': 'help', 'tags': '', 'text': '\n View help or a list of topics\n\n Usage:\n help <topic or command>\n help list\n help all\n\n This will search for help on commands and other\n topics related to the game.\n '}
+
+
@@ -858,6 +888,11 @@ currently wielding.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'wield', 'tags': '', 'text': '\n Wield a weapon you are carrying\n\n Usage:\n wield <weapon>\n\n Select a weapon you are carrying to wield in combat. If\n you are already wielding another weapon, you will switch\n to the weapon you specify instead. Using this command in\n combat will spend your action for your turn. Use the\n "unwield" command to stop wielding any weapon you are\n currently wielding.\n '}
+
+
@@ -897,6 +932,11 @@ weapon you are currently wielding and become unarmed.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'unwield', 'tags': '', 'text': '\n Stop wielding a weapon.\n\n Usage:\n unwield\n\n After using this command, you will stop wielding any\n weapon you are currently wielding and become unarmed.\n '}
+
+
@@ -937,6 +977,11 @@ command to remove any armor you are wearing.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'don', 'tags': '', 'text': '\n Don armor that you are carrying\n\n Usage:\n don <armor>\n\n Select armor to wear in combat. You can\'t use this\n command in the middle of a fight. Use the "doff"\n command to remove any armor you are wearing.\n '}
+
+
@@ -977,6 +1022,11 @@ You can’t use this command in combat.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'doff', 'tags': '', 'text': "\n Stop wearing armor.\n\n Usage:\n doff\n\n After using this command, you will stop wearing any\n armor you are currently using and become unarmored.\n You can't use this command in combat.\n "}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_items.html b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_items.html
index de559deab7..b90ea03ec1 100644
--- a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_items.html
+++ b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_items.html
@@ -651,6 +651,11 @@ When it’s your turn, you can attack other characters.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'fight', 'tags': '', 'text': "\n Starts a fight with everyone in the same room as you.\n\n Usage:\n fight\n\n When you start a fight, everyone in the room who is able to\n fight is added to combat, and a turn order is randomly rolled.\n When it's your turn, you can attack other characters.\n "}
+
+
@@ -690,6 +695,11 @@ a chance to hit, and if successful, will deal damage.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'attack', 'tags': '', 'text': '\n Attacks another character.\n\n Usage:\n attack <target>\n\n When in a fight, you may attack another character. The attack has\n a chance to hit, and if successful, will deal damage.\n '}
+
+
@@ -710,7 +720,7 @@ if there are still any actions you can take.
-
-
aliases = ['hold', 'wait']
+aliases = ['wait', 'hold']
@@ -729,6 +739,11 @@ if there are still any actions you can take.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}
+
+
@@ -769,6 +784,11 @@ fight ends.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'spare', 'category': 'combat', 'key': 'disengage', 'tags': '', 'text': "\n Passes your turn and attempts to end combat.\n\n Usage:\n disengage\n\n Ends your turn early and signals that you're trying to end\n the fight. If all participants in a fight disengage, the\n fight ends.\n "}
+
+
@@ -808,6 +828,11 @@ rest if you’re not in a fight.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'rest', 'tags': '', 'text': "\n Recovers damage.\n\n Usage:\n rest\n\n Resting recovers your HP to its maximum, but you can only\n rest if you're not in a fight.\n "}
+
+
@@ -849,6 +874,11 @@ topics related to the game.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '?', 'category': 'general', 'key': 'help', 'tags': '', 'text': '\n View help or a list of topics\n\n Usage:\n help <topic or command>\n help list\n help all\n\n This will search for help on commands and other\n topics related to the game.\n '}
+
+
@@ -889,6 +919,11 @@ to attack others, and as such can only be used in combat.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'use', 'tags': '', 'text': '\n Use an item.\n\n Usage:\n use <item> [= target]\n\n An item can have various function - looking at the item may\n provide information as to its effects. Some items can be used\n to attack others, and as such can only be used in combat.\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_magic.html b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_magic.html
index 66a2341f19..6ad8b23441 100644
--- a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_magic.html
+++ b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_magic.html
@@ -523,6 +523,11 @@ When it’s your turn, you can attack other characters.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'fight', 'tags': '', 'text': "\n Starts a fight with everyone in the same room as you.\n\n Usage:\n fight\n\n When you start a fight, everyone in the room who is able to\n fight is added to combat, and a turn order is randomly rolled.\n When it's your turn, you can attack other characters.\n "}
+
+
@@ -562,6 +567,11 @@ a chance to hit, and if successful, will deal damage.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'attack', 'tags': '', 'text': '\n Attacks another character.\n\n Usage:\n attack <target>\n\n When in a fight, you may attack another character. The attack has\n a chance to hit, and if successful, will deal damage.\n '}
+
+
@@ -582,7 +592,7 @@ if there are still any actions you can take.
-
-
aliases = ['hold', 'wait']
+aliases = ['wait', 'hold']
@@ -601,6 +611,11 @@ if there are still any actions you can take.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}
+
+
@@ -641,6 +656,11 @@ fight ends.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'spare', 'category': 'combat', 'key': 'disengage', 'tags': '', 'text': "\n Passes your turn and attempts to end combat.\n\n Usage:\n disengage\n\n Ends your turn early and signals that you're trying to end\n the fight. If all participants in a fight disengage, the\n fight ends.\n "}
+
+
@@ -694,6 +714,11 @@ fight ends.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'magic', 'key': 'learnspell', 'tags': '', 'text': "\n Learn a magic spell.\n\n Usage:\n learnspell <spell name>\n\n Adds a spell by name to your list of spells known.\n\n The following spells are provided as examples:\n\n |wmagic missile|n (3 MP): Fires three missiles that never miss. Can target\n up to three different enemies.\n\n |wflame shot|n (3 MP): Shoots a high-damage jet of flame at one target.\n\n |wcure wounds|n (5 MP): Heals damage on one target.\n\n |wmass cure wounds|n (10 MP): Like 'cure wounds', but can heal up to 5\n targets at once.\n\n |wfull heal|n (12 MP): Heals one target back to full HP.\n\n |wcactus conjuration|n (2 MP): Creates a cactus.\n "}
+
+
@@ -741,6 +766,11 @@ function.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'magic', 'key': 'cast', 'tags': '', 'text': "\n Cast a magic spell that you know, provided you have the MP\n to spend on its casting.\n\n Usage:\n cast <spellname> [= <target1>, <target2>, etc...]\n\n Some spells can be cast on multiple targets, some can be cast\n on only yourself, and some don't need a target specified at all.\n Typing 'cast' by itself will give you a list of spells you know.\n "}
+
+
@@ -780,6 +810,11 @@ only rest if you’re not in a fight.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'rest', 'tags': '', 'text': "\n Recovers damage and restores MP.\n\n Usage:\n rest\n\n Resting recovers your HP and MP to their maximum, but you can\n only rest if you're not in a fight.\n "}
+
+
@@ -819,6 +854,11 @@ other targets in combat.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'status', 'tags': '', 'text': '\n Gives combat information.\n\n Usage:\n status\n\n Shows your current and maximum HP and your distance from\n other targets in combat.\n '}
+
+
@@ -860,6 +900,11 @@ topics related to the game.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '?', 'category': 'general', 'key': 'help', 'tags': '', 'text': '\n View help or a list of topics\n\n Usage:\n help <topic or command>\n help list\n help all\n\n This will search for help on commands and other\n topics related to the game.\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_range.html b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_range.html
index 46813d862b..62782b3b9a 100644
--- a/docs/0.9.5/api/evennia.contrib.turnbattle.tb_range.html
+++ b/docs/0.9.5/api/evennia.contrib.turnbattle.tb_range.html
@@ -814,6 +814,11 @@ When it’s your turn, you can attack other characters.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'fight', 'tags': '', 'text': "\n Starts a fight with everyone in the same room as you.\n\n Usage:\n fight\n\n When you start a fight, everyone in the room who is able to\n fight is added to combat, and a turn order is randomly rolled.\n When it's your turn, you can attack other characters.\n "}
+
+
@@ -855,6 +860,11 @@ you. Use the ‘approach’ command to get closer to a target.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'attack', 'tags': '', 'text': "\n Attacks another character in melee.\n\n Usage:\n attack <target>\n\n When in a fight, you may attack another character. The attack has\n a chance to hit, and if successful, will deal damage. You can only\n attack engaged targets - that is, targets that are right next to\n you. Use the 'approach' command to get closer to a target.\n "}
+
+
@@ -897,6 +907,11 @@ nearby enemies.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'shoot', 'tags': '', 'text': "\n Attacks another character from range.\n\n Usage:\n shoot <target>\n\n When in a fight, you may shoot another character. The attack has\n a chance to hit, and if successful, will deal damage. You can attack\n any target in combat by shooting, but can't shoot if there are any\n targets engaged with you. Use the 'withdraw' command to retreat from\n nearby enemies.\n "}
+
+
@@ -936,6 +951,11 @@ characters you are 0 spaces away from.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'approach', 'tags': '', 'text': '\n Approaches an object.\n\n Usage:\n approach <target>\n\n Move one space toward a character or object. You can only attack\n characters you are 0 spaces away from.\n '}
+
+
@@ -974,6 +994,11 @@ characters you are 0 spaces away from.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'withdraw', 'tags': '', 'text': '\n Moves away from an object.\n\n Usage:\n withdraw <target>\n\n Move one space away from a character or object.\n '}
+
+
@@ -994,7 +1019,7 @@ if there are still any actions you can take.
-
-
aliases = ['hold', 'wait']
+aliases = ['wait', 'hold']
@@ -1013,6 +1038,11 @@ if there are still any actions you can take.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'wait hold', 'category': 'combat', 'key': 'pass', 'tags': '', 'text': '\n Passes on your turn.\n\n Usage:\n pass\n\n When in a fight, you can use this command to end your turn early, even\n if there are still any actions you can take.\n '}
+
+
@@ -1053,6 +1083,11 @@ fight ends.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'spare', 'category': 'combat', 'key': 'disengage', 'tags': '', 'text': "\n Passes your turn and attempts to end combat.\n\n Usage:\n disengage\n\n Ends your turn early and signals that you're trying to end\n the fight. If all participants in a fight disengage, the\n fight ends.\n "}
+
+
@@ -1092,6 +1127,11 @@ rest if you’re not in a fight.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'rest', 'tags': '', 'text': "\n Recovers damage.\n\n Usage:\n rest\n\n Resting recovers your HP to its maximum, but you can only\n rest if you're not in a fight.\n "}
+
+
@@ -1131,6 +1171,11 @@ other targets in combat.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'combat', 'key': 'status', 'tags': '', 'text': '\n Gives combat information.\n\n Usage:\n status\n\n Shows your current and maximum HP and your distance from\n other targets in combat.\n '}
+
+
@@ -1172,6 +1217,11 @@ topics related to the game.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '?', 'category': 'general', 'key': 'help', 'tags': '', 'text': '\n View help or a list of topics\n\n Usage:\n help <topic or command>\n help list\n help all\n\n This will search for help on commands and other\n topics related to the game.\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.tutorial_examples.cmdset_red_button.html b/docs/0.9.5/api/evennia.contrib.tutorial_examples.cmdset_red_button.html
index 5a870746c6..36cfe18046 100644
--- a/docs/0.9.5/api/evennia.contrib.tutorial_examples.cmdset_red_button.html
+++ b/docs/0.9.5/api/evennia.contrib.tutorial_examples.cmdset_red_button.html
@@ -86,6 +86,11 @@ push the lid of the button away.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'nudge', 'category': 'general', 'key': 'nudge lid', 'tags': '', 'text': "\n Try to nudge the button's lid\n\n Usage:\n nudge lid\n\n This command will have you try to\n push the lid of the button away.\n "}
+
+
@@ -104,7 +109,7 @@ push the lid of the button away.
-
-
aliases = ['push', 'press', 'press button']
+aliases = ['press button', 'push', 'press']
@@ -133,6 +138,11 @@ lid-state respectively.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'press button push press', 'category': 'general', 'key': 'push button', 'tags': '', 'text': '\n Push the red button\n\n Usage:\n push button\n\n '}
+
+
@@ -177,6 +187,11 @@ of causing the lamp to break.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'smash lid break lid smash', 'category': 'general', 'key': 'smash glass', 'tags': '', 'text': '\n smash glass\n\n Usage:\n smash glass\n\n Try to smash the glass of the button.\n '}
+
+
@@ -195,7 +210,7 @@ of causing the lamp to break.
-
-
aliases = ['open button', 'open']
+aliases = ['open', 'open button']
@@ -219,6 +234,11 @@ of causing the lamp to break.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'open open button', 'category': 'general', 'key': 'open lid', 'tags': '', 'text': '\n open lid\n\n Usage:\n open lid\n\n '}
+
+
@@ -262,6 +282,11 @@ of causing the lamp to break.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'close', 'category': 'general', 'key': 'close lid', 'tags': '', 'text': '\n close the lid\n\n Usage:\n close lid\n\n Closes the lid of the red button.\n '}
+
+
@@ -281,7 +306,7 @@ of causing the lamp to break.
-
-
aliases = ['listen', 'feel', 'ex', 'get', 'examine', 'l']
+aliases = ['examine', 'l', 'listen', 'get', 'ex', 'feel']
@@ -305,6 +330,11 @@ of causing the lamp to break.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'examine l listen get ex feel', 'category': 'general', 'key': 'look', 'tags': '', 'text': "\n Looking around in darkness\n\n Usage:\n look <obj>\n\n ... not that there's much to see in the dark.\n\n "}
+
+
@@ -347,6 +377,11 @@ of causing the lamp to break.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'h', 'category': 'general', 'key': 'help', 'tags': '', 'text': '\n Help function while in the blinded state\n\n Usage:\n help\n\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.tutorial_world.mob.html b/docs/0.9.5/api/evennia.contrib.tutorial_world.mob.html
index b5fe984895..ac44210fd5 100644
--- a/docs/0.9.5/api/evennia.contrib.tutorial_world.mob.html
+++ b/docs/0.9.5/api/evennia.contrib.tutorial_world.mob.html
@@ -87,6 +87,11 @@ to turn on/off the mob.”
lock_storage = 'cmd:superuser()'
+
+-
+
search_index_entry = {'aliases': 'moboff', 'category': 'general', 'key': 'mobon', 'tags': '', 'text': "\n Activates/deactivates Mob\n\n Usage:\n mobon <mob>\n moboff <mob>\n\n This turns the mob from active (alive) mode\n to inactive (dead) mode. It is used during\n building to activate the mob once it's\n prepared.\n "}
+
+
@@ -122,7 +127,7 @@ the way it came. If unset, the mob will remain
stationary (idling) until attacked.
- aggressive: if set, will attack Characters in
the same room using whatever Weapon it
-carries (see tutorial_world.objects.Weapon).
+carries (see tutorial_world.objects.TutorialWeapon).
if unset, the mob will never engage in combat
no matter what.
diff --git a/docs/0.9.5/api/evennia.contrib.tutorial_world.objects.html b/docs/0.9.5/api/evennia.contrib.tutorial_world.objects.html
index c22c66fa5c..1da18d6e9f 100644
--- a/docs/0.9.5/api/evennia.contrib.tutorial_world.objects.html
+++ b/docs/0.9.5/api/evennia.contrib.tutorial_world.objects.html
@@ -49,8 +49,8 @@ TutorialClimbable
Obelisk
LightSource
CrumblingWall
-Weapon
-WeaponRack
+TutorialWeapon
+TutorialWeaponRack
-
class
evennia.contrib.tutorial_world.objects.TutorialObject(*args, **kwargs)[source]
@@ -133,6 +133,11 @@ Attribute “readable_text” on the object and displays that.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'tutorialworld', 'key': 'read', 'tags': '', 'text': '\n Usage:\n read [obj]\n\n Read some text of a readable object.\n '}
+
+
@@ -230,6 +235,11 @@ Attribute and add the readable cmdset.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'tutorialworld', 'key': 'climb', 'tags': '', 'text': '\n Climb an object\n\n Usage:\n climb <object>\n\n This allows you to climb.\n '}
+
+
@@ -350,7 +360,7 @@ of the object. We overload it with our own version.
-
-
aliases = ['light', 'burn']
+aliases = ['burn', 'light']
@@ -375,6 +385,11 @@ to sit on a “lightable” object, we operate only on self.obj.
lock_storage = 'cmd:holds()'
+
+-
+
search_index_entry = {'aliases': 'burn light', 'category': 'tutorialworld', 'key': 'on', 'tags': '', 'text': '\n Creates light where there was none. Something to burn.\n '}
+
+
@@ -476,7 +491,7 @@ shift green root up/down
-
-
aliases = ['shiftroot', 'move', 'push', 'pull']
+aliases = ['move', 'push', 'pull', 'shiftroot']
@@ -510,6 +525,11 @@ yellow/green - horizontal roots
lock_storage = 'cmd:locattr(is_lit)'
+
+-
+
search_index_entry = {'aliases': 'move push pull shiftroot', 'category': 'tutorialworld', 'key': 'shift', 'tags': '', 'text': '\n Shifts roots around.\n\n Usage:\n shift blue root left/right\n shift red root left/right\n shift yellow root up/down\n shift green root up/down\n\n '}
+
+
@@ -524,7 +544,7 @@ yellow/green - horizontal roots
-
-
aliases = ['button', 'push button', 'press button']
+aliases = ['push button', 'press button', 'button']
@@ -548,6 +568,11 @@ yellow/green - horizontal roots
lock_storage = 'cmd:objattr(button_exposed) and objlocattr(is_lit)'
+
+-
+
search_index_entry = {'aliases': 'push button press button button', 'category': 'tutorialworld', 'key': 'press', 'tags': '', 'text': '\n Presses a button.\n '}
+
+
@@ -689,7 +714,7 @@ parry - forgoes your attack but will make you harder to hit on next
-
-
aliases = ['fight', 'parry', 'kill', 'defend', 'thrust', 'chop', 'bash', 'stab', 'hit', 'slash', 'pierce']
+aliases = ['thrust', 'parry', 'defend', 'stab', 'kill', 'slash', 'hit', 'pierce', 'chop', 'bash', 'fight']
@@ -713,6 +738,11 @@ parry - forgoes your attack but will make you harder to hit on next
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'thrust parry defend stab kill slash hit pierce chop bash fight', 'category': 'tutorialworld', 'key': 'attack', 'tags': '', 'text': '\n Attack the enemy. Commands:\n\n stab <enemy>\n slash <enemy>\n parry\n\n stab - (thrust) makes a lot of damage but is harder to hit with.\n slash - is easier to land, but does not make as much damage.\n parry - forgoes your attack but will make you harder to hit on next\n enemy attack.\n\n '}
+
+
@@ -734,8 +764,8 @@ parry - forgoes your attack but will make you harder to hit on next
--
-class
evennia.contrib.tutorial_world.objects.Weapon(*args, **kwargs)[source]
+-
+class
evennia.contrib.tutorial_world.objects.TutorialWeapon(*args, **kwargs)[source]
Bases: evennia.contrib.tutorial_world.objects.TutorialObject
This defines a bladed weapon.
@@ -748,38 +778,38 @@ damage - base damage given (modified by hit success and
--
-
at_object_creation()[source]
+-
+
at_object_creation()[source]
Called at first creation of the object
--
-
reset()[source]
+-
+
reset()[source]
When reset, the weapon is simply deleted, unless it has a place
to return to.
--
-exception
DoesNotExist
+-
+exception
DoesNotExist
Bases: evennia.contrib.tutorial_world.objects.TutorialObject.DoesNotExist
--
-exception
MultipleObjectsReturned
+-
+exception
MultipleObjectsReturned
Bases: evennia.contrib.tutorial_world.objects.TutorialObject.MultipleObjectsReturned
--
-
path = 'evennia.contrib.tutorial_world.objects.Weapon'
+-
+
path = 'evennia.contrib.tutorial_world.objects.TutorialWeapon'
--
-
typename = 'Weapon'
+-
+
typename = 'TutorialWeapon'
@@ -825,6 +855,11 @@ itself handle all messages.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'tutorialworld', 'key': 'get weapon', 'tags': '', 'text': '\n Usage:\n get weapon\n\n This will try to obtain a weapon from the container.\n '}
+
+
@@ -851,8 +886,8 @@ itself handle all messages.
--
-class
evennia.contrib.tutorial_world.objects.WeaponRack(*args, **kwargs)[source]
+-
+class
evennia.contrib.tutorial_world.objects.TutorialWeaponRack(*args, **kwargs)[source]
Bases: evennia.contrib.tutorial_world.objects.TutorialObject
This object represents a weapon store. When people use the
“get weapon” command on this rack, it will produce one
@@ -870,14 +905,14 @@ grab another one.
--
-
at_object_creation()[source]
+-
+
at_object_creation()[source]
called at creation
--
-
produce_weapon(caller)[source]
+-
+
produce_weapon(caller)[source]
This will produce a new weapon from the rack,
assuming the caller hasn’t already gotten one. When
doing so, the caller will get Tagged with the id
@@ -886,25 +921,25 @@ pulling weapons from it indefinitely.
--
-exception
DoesNotExist
+-
+exception
DoesNotExist
Bases: evennia.contrib.tutorial_world.objects.TutorialObject.DoesNotExist
--
-exception
MultipleObjectsReturned
+-
+exception
MultipleObjectsReturned
Bases: evennia.contrib.tutorial_world.objects.TutorialObject.MultipleObjectsReturned
--
-
path = 'evennia.contrib.tutorial_world.objects.WeaponRack'
+-
+
path = 'evennia.contrib.tutorial_world.objects.TutorialWeaponRack'
--
-
typename = 'WeaponRack'
+-
+
typename = 'TutorialWeaponRack'
diff --git a/docs/0.9.5/api/evennia.contrib.tutorial_world.rooms.html b/docs/0.9.5/api/evennia.contrib.tutorial_world.rooms.html
index 029fdde9ba..d8892d7672 100644
--- a/docs/0.9.5/api/evennia.contrib.tutorial_world.rooms.html
+++ b/docs/0.9.5/api/evennia.contrib.tutorial_world.rooms.html
@@ -86,6 +86,11 @@ called tutorial_info and display that.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'tut', 'category': 'tutorialworld', 'key': 'tutorial', 'tags': '', 'text': '\n Get help during the tutorial\n\n Usage:\n tutorial [obj]\n\n This command allows you to get behind-the-scenes info\n about an object or the current location.\n\n '}
+
+
@@ -139,6 +144,11 @@ the set_detail method and uses it.
lock_storage = 'cmd:perm(Builder)'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'tutorialworld', 'key': '@detail', 'tags': '', 'text': '\n sets a detail on a room\n\n Usage:\n @detail <key> = <description>\n @detail <key>;<alias>;... = description\n\n Example:\n @detail walls = The walls are covered in ...\n @detail castle;ruin;tower = The distant ruin ...\n\n This sets a "detail" on the object this command is defined on\n (TutorialRoom for this tutorial). This detail can be accessed with\n the TutorialRoomLook command sitting on TutorialRoom objects (details\n are set as a simple dictionary on the room). This is a Builder command.\n\n We custom parse the key for the ;-separator in order to create\n multiple aliases to the detail all at once.\n '}
+
+
@@ -186,6 +196,11 @@ code except for adding in the details.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'l ls', 'category': 'tutorialworld', 'key': 'look', 'tags': '', 'text': '\n looks at the room and on details\n\n Usage:\n look <obj>\n look <room detail>\n look *<account>\n\n Observes your location, details at your location or objects\n in your vicinity.\n\n Tutorial: This is a child of the default Look command, that also\n allows us to look at "details" in the room. These details are\n things to examine and offers some extra description without\n actually having to be actual database objects. It uses the\n return_detail() hook on TutorialRooms for this.\n '}
+
+
@@ -222,6 +237,11 @@ to all the variables defined therein.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': 'abort', 'category': 'general', 'key': 'give up', 'tags': '', 'text': '\n Give up the tutorial-world quest and return to Limbo, the start room of the\n server.\n\n '}
+
+
@@ -427,6 +447,11 @@ set in self.parse())
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'intro', 'tags': '', 'text': '\n Start the Evennia intro wizard.\n\n Usage:\n intro\n\n '}
+
+
@@ -556,6 +581,11 @@ on the bridge, 0 - 4.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'e', 'category': 'tutorialworld', 'key': 'east', 'tags': '', 'text': '\n Go eastwards across the bridge.\n\n Tutorial info:\n This command relies on the caller having two Attributes\n (assigned by the room when entering):\n - east_exit: a unique name or dbref to the room to go to\n when exiting east.\n - west_exit: a unique name or dbref to the room to go to\n when exiting west.\n The room must also have the following Attributes\n - tutorial_bridge_posistion: the current position on\n on the bridge, 0 - 4.\n\n '}
+
+
@@ -614,6 +644,11 @@ on the bridge, 0 - 4.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'w', 'category': 'tutorialworld', 'key': 'west', 'tags': '', 'text': '\n Go westwards across the bridge.\n\n Tutorial info:\n This command relies on the caller having two Attributes\n (assigned by the room when entering):\n - east_exit: a unique name or dbref to the room to go to\n when exiting east.\n - west_exit: a unique name or dbref to the room to go to\n when exiting west.\n The room must also have the following property:\n - tutorial_bridge_posistion: the current position on\n on the bridge, 0 - 4.\n\n '}
+
+
@@ -658,6 +693,11 @@ if they fall off the bridge.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'l', 'category': 'tutorialworld', 'key': 'look', 'tags': '', 'text': '\n looks around at the bridge.\n\n Tutorial info:\n This command assumes that the room has an Attribute\n "fall_exit", a unique name or dbref to the place they end upp\n if they fall off the bridge.\n '}
+
+
@@ -672,7 +712,7 @@ if they fall off the bridge.
-
-
aliases = ['h', '?']
+aliases = ['?', 'h']
@@ -696,6 +736,11 @@ if they fall off the bridge.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '? h', 'category': 'tutorial world', 'key': 'help', 'tags': '', 'text': '\n Overwritten help command while on the bridge.\n '}
+
+
@@ -819,7 +864,7 @@ to find something.
-
-
aliases = ['fiddle', 'feel', 'feel around', 'search', 'l']
+aliases = ['l', 'search', 'fiddle', 'feel around', 'feel']
@@ -845,6 +890,11 @@ random chance of eventually finding a light source.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': 'l search fiddle feel around feel', 'category': 'tutorialworld', 'key': 'look', 'tags': '', 'text': '\n Look around in darkness\n\n Usage:\n look\n\n Look around in the darkness, trying\n to find something.\n '}
+
+
@@ -883,6 +933,11 @@ random chance of eventually finding a light source.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'tutorialworld', 'key': 'help', 'tags': '', 'text': '\n Help command for the dark state.\n '}
+
+
@@ -925,6 +980,11 @@ suggestions)
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': '__nomatch_command', 'tags': '', 'text': "\n This is a system command. Commands with special keys are used to\n override special sitations in the game. The CMD_NOMATCH is used\n when the given command is not found in the current command set (it\n replaces Evennia's default behavior or offering command\n suggestions)\n "}
+
+
diff --git a/docs/0.9.5/api/evennia.contrib.unixcommand.html b/docs/0.9.5/api/evennia.contrib.unixcommand.html
index 463f7835ef..336776b9f2 100644
--- a/docs/0.9.5/api/evennia.contrib.unixcommand.html
+++ b/docs/0.9.5/api/evennia.contrib.unixcommand.html
@@ -317,6 +317,11 @@ use its add_argument method.
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'command', 'tags': '', 'text': '\n Unix-type commands, supporting short and long options.\n\n This command syntax uses the Unix-style commands with short options\n (-X) and long options (--something). The `argparse` module is\n used to parse the command.\n\n In order to use it, you should override two methods:\n - `init_parser`: this method is called when the command is created.\n It can be used to set options in the parser. `self.parser`\n contains the `argparse.ArgumentParser`, so you can add arguments\n here.\n - `func`: this method is called to execute the command, but after\n the parser has checked the arguments given to it are valid.\n You can access the namespace of valid arguments in `self.opts`\n at this point.\n\n The help of UnixCommands is derived from the docstring, in a\n slightly different way than usual: the first line of the docstring\n is used to represent the program description (the very short\n line at the top of the help message). The other lines below are\n used as the program\'s "epilog", displayed below the options. It\n means in your docstring, you don\'t have to write the options.\n They will be automatically provided by the parser and displayed\n accordingly. The `argparse` module provides a default \'-h\' or\n \'--help\' option on the command. Typing |whelp commandname|n will\n display the same as |wcommandname -h|n, though this behavior can\n be changed.\n\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.help.models.html b/docs/0.9.5/api/evennia.help.models.html
index 6ec8b1aaf7..b3c84370c2 100644
--- a/docs/0.9.5/api/evennia.help.models.html
+++ b/docs/0.9.5/api/evennia.help.models.html
@@ -139,6 +139,12 @@ access_type - type of access sought
default - what to return if no lock of access_type was found
+
+-
+property
search_index_entry
+Property for easily retaining a search index entry for this object.
+
+
-
web_get_admin_url()[source]
diff --git a/docs/0.9.5/api/evennia.html b/docs/0.9.5/api/evennia.html
index c3fb30e709..216e311a07 100644
--- a/docs/0.9.5/api/evennia.html
+++ b/docs/0.9.5/api/evennia.html
@@ -371,8 +371,14 @@ with ‘q’, remove the break line and restart server when finished.
evennia.utils
- evennia.utils.ansi
- evennia.utils.batchprocessors
- evennia.utils.containers
diff --git a/docs/0.9.5/api/evennia.objects.models.html b/docs/0.9.5/api/evennia.objects.models.html
index bba6ff7bdf..ee713bbc44 100644
--- a/docs/0.9.5/api/evennia.objects.models.html
+++ b/docs/0.9.5/api/evennia.objects.models.html
@@ -69,6 +69,17 @@ handler is defined
+
+-
+
load()[source]
+Retrieves all objects from database. Used for initializing.
+
+- Returns
+Objects (list of ObjectDB)
+
+
+
+
-
init()[source]
@@ -77,11 +88,14 @@ handler is defined
-
-
get(exclude=None)[source]
+get(exclude=None, content_type=None)[source]
Return the contents of the cache.
- Parameters
-exclude (Object or list of Object) – object(s) to ignore
+
+exclude (Object or list of Object) – object(s) to ignore
+content_type (str or None) – Filter list by a content-type. If None, don’t filter.
+
- Returns
objects (list) – the Objects inside this location
diff --git a/docs/0.9.5/api/evennia.objects.objects.html b/docs/0.9.5/api/evennia.objects.objects.html
index 7f2a1674cc..5ae613659c 100644
--- a/docs/0.9.5/api/evennia.objects.objects.html
+++ b/docs/0.9.5/api/evennia.objects.objects.html
@@ -197,21 +197,26 @@ currently connected to this object.
-
-
contents_get(exclude=None)[source]
+contents_get(exclude=None, content_type=None)[source]
Returns the contents of this object, i.e. all
objects that has this object set as its location.
This should be publically available.
- Parameters
-exclude (Object) – Object to exclude from returned
-contents list
+-
- Returns
contents (list) – List of contents of this Object.
Notes
-Also available as the contents property.
+Also available as the contents property, minus exclusion
+and filtering.
@@ -228,15 +233,20 @@ objects that has this object set as its location.
This should be publically available.
- Parameters
-exclude (Object) – Object to exclude from returned
-contents list
+-
- Returns
contents (list) – List of contents of this Object.
Notes
-Also available as the contents property.
+Also available as the contents property, minus exclusion
+and filtering.
@@ -300,7 +310,7 @@ plural (str): The determined plural form of the key, including the count.
-
-
search(searchdata, global_search=False, use_nicks=True, typeclass=None, location=None, attribute_name=None, quiet=False, exact=False, candidates=None, nofound_string=None, multimatch_string=None, use_dbref=None)[source]
+search(searchdata, global_search=False, use_nicks=True, typeclass=None, location=None, attribute_name=None, quiet=False, exact=False, candidates=None, nofound_string=None, multimatch_string=None, use_dbref=None, stacked=0)[source]
Returns an Object matching a search string/condition
Perform a standard object search in the database, handling
multiple results and lack thereof gracefully. By default, only
@@ -362,14 +372,22 @@ to find an object (globally) by its database-id 123. If False,
will be treated like a normal string. If None (default), the ability to query by
#dbref is turned on if self has the permission ‘Builder’ and is turned off
otherwise.
+stacked (int, optional) – If > 0, multimatches will be analyzed to determine if they
+only contains identical objects; these are then assumed ‘stacked’ and no multi-match
+error will be generated, instead stacked number of matches will be returned. If
+stacked is larger than number of matches, returns that number of matches. If
+the found stack is a mix of objects, return None and handle the multi-match
+error depending on the value of quiet.
Returns
-match (Object, None or list) –
-
-- will return an Object/None if quiet=False,
otherwise it will return a list of 0, 1 or more matches.
-
-
+Object – If finding a match an quiet=False
+None: If not finding a unique match and quiet=False.
+list: With 0, 1 or more matching objects if quiet=True
+list: With 2 or more matching objects if stacked is a positive integer and
+
+the matched stack has only object-copies.
+
@@ -1493,6 +1511,36 @@ errors (list): A list of errors in string form, if any.
+
+-
+classmethod
normalize_name(name)[source]
+Normalize the character name prior to creating. Note that this should be refactored
+to support i18n for non-latin scripts, but as we (currently) have no bug reports requesting better
+support of non-latin character sets, requiring character names to be latinified is an acceptable option.
+
+- Parameters
+name (str) – The name of the character
+
+- Returns
+latin_name (str) – A valid name.
+
+
+
+
+
+-
+classmethod
validate_name(name)[source]
+Validate the character name prior to creating. Overload this function to add custom validators
+
+- Parameters
+name (str) – The name of the character
+
+- Returns
+valid (bool) – True if character creation should continue; False if it should fail
+
+
+
+
-
basetype_setup()[source]
@@ -1722,6 +1770,11 @@ overriding the call (unused by default).
lock_storage = 'cmd:all();'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'command', 'tags': '', 'text': '\n This is a command that simply cause the caller to traverse\n the object it is attached to.\n\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.server.portal.portalsessionhandler.html b/docs/0.9.5/api/evennia.server.portal.portalsessionhandler.html
index d747cc1e17..5c42a771c5 100644
--- a/docs/0.9.5/api/evennia.server.portal.portalsessionhandler.html
+++ b/docs/0.9.5/api/evennia.server.portal.portalsessionhandler.html
@@ -62,6 +62,17 @@ to the server using the AMP connection.
At this point, the AMP connection is already established.
+
+-
+
generate_sessid()[source]
+Simply generates a sessid that’s guaranteed to be unique for this Portal run.
+
+- Returns
+sessid
+
+
+
+
-
connect(session)[source]
diff --git a/docs/0.9.5/api/evennia.server.portal.ssh.html b/docs/0.9.5/api/evennia.server.portal.ssh.html
index 5849973acb..efb91d7dbb 100644
--- a/docs/0.9.5/api/evennia.server.portal.ssh.html
+++ b/docs/0.9.5/api/evennia.server.portal.ssh.html
@@ -224,18 +224,18 @@ reaching this point.
are considered.
- Keyword Arguments
-options (dict) –
Send-option flags:
+options (dict) –
Send-option flags (booleans)
-mxp: Enforce MXP link support.
-ansi: Enforce no ANSI colors.
-xterm256: Enforce xterm256 colors, regardless of TTYPE setting.
-nocolor: Strip all colors.
-raw: Pass string through without any ansi processing
-(i.e. include Evennia ansi markers but do not
+
mxp: enforce mxp link support.
+ansi: enforce no ansi colors.
+xterm256: enforce xterm256 colors, regardless of ttype setting.
+nocolor: strip all colors.
+raw: pass string through without any ansi processing
+(i.e. include evennia ansi markers but do not
convert them into ansi tokens)
-echo: Turn on/off line echo on the client. Turn
+
echo: turn on/off line echo on the client. turn
off line echo for client, for example for password.
-Note that it must be actively turned back on again!
+note that it must be actively turned back on again!
diff --git a/docs/0.9.5/api/evennia.server.portal.telnet.html b/docs/0.9.5/api/evennia.server.portal.telnet.html
index c815019cbf..d2f715df35 100644
--- a/docs/0.9.5/api/evennia.server.portal.telnet.html
+++ b/docs/0.9.5/api/evennia.server.portal.telnet.html
@@ -241,19 +241,25 @@ disconnect this protocol.
are considered.
- Keyword Arguments
-options (dict) –
Send-option flags:
+options (dict) –
Send-option flags
mxp: Enforce MXP link support.
ansi: Enforce no ANSI colors.
xterm256: Enforce xterm256 colors, regardless of TTYPE.
noxterm256: Enforce no xterm256 color support, regardless of TTYPE.
nocolor: Strip all Color, regardless of ansi/xterm256 setting.
-raw: Pass string through without any ansi processing
-(i.e. include Evennia ansi markers but do not
-convert them into ansi tokens)
-echo: Turn on/off line echo on the client. Turn
-off line echo for client, for example for password.
-Note that it must be actively turned back on again!
+
+- raw: Pass string through without any ansi processing
(i.e. include Evennia ansi markers but do not
+convert them into ansi tokens)
+
+
+
+
+- echo: Turn on/off line echo on the client. Turn
off line echo for client, for example for password.
+Note that it must be actively turned back on again!
+
+
+
diff --git a/docs/0.9.5/api/evennia.server.portal.telnet_oob.html b/docs/0.9.5/api/evennia.server.portal.telnet_oob.html
index 98b08d2c8b..af19203274 100644
--- a/docs/0.9.5/api/evennia.server.portal.telnet_oob.html
+++ b/docs/0.9.5/api/evennia.server.portal.telnet_oob.html
@@ -46,19 +46,15 @@ commands, by contrast, can have many forms and it is up to the client
how and if they are handled. Examples of OOB instructions could be to
instruct the client to play sounds or to update a graphical health
bar.
-> Note that in Evennia’s Web client, all send commands are “OOB commands”,
-(including the “text” one), there is no equivalence to MSDP/GMCP for the
-webclient since it doesn’t need it.
+Note that in Evennia’s Web client, all send commands are “OOB
+commands”, (including the “text” one), there is no equivalence to
+MSDP/GMCP for the webclient since it doesn’t need it.
This implements the following telnet OOB communication protocols:
-Following the lead of KaVir’s protocol snippet, we first check if client
-supports MSDP and if not, we fallback to GMCP with a MSDP header where
-applicable.
-
@@ -138,17 +134,17 @@ supported.
Notes
The output of this encoding will be
MSDP structures on these forms:
-[cmdname, [], {}] -> VAR cmdname VAL ""
-[cmdname, [arg], {}] -> VAR cmdname VAL arg
-[cmdname, [args],{}] -> VAR cmdname VAL ARRAYOPEN VAL arg VAL arg ... ARRAYCLOSE
-[cmdname, [], {kwargs}] -> VAR cmdname VAL TABLEOPEN VAR key VAL val ... TABLECLOSE
+[cmdname, [], {}] -> VAR cmdname VAL ""
+[cmdname, [arg], {}] -> VAR cmdname VAL arg
+[cmdname, [args],{}] -> VAR cmdname VAL ARRAYOPEN VAL arg VAL arg ... ARRAYCLOSE
+[cmdname, [], {kwargs}] -> VAR cmdname VAL TABLEOPEN VAR key VAL val ... TABLECLOSE
[cmdname, [args], {kwargs}] -> VAR cmdname VAL ARRAYOPEN VAL arg VAL arg ... ARRAYCLOSE
VAR cmdname VAL TABLEOPEN VAR key VAL val ... TABLECLOSE
-Further nesting is not supported, so if an array argument consists
-of an array (for example), that array will be json-converted to a
-string.
+Further nesting is not supported, so if an array argument
+consists of an array (for example), that array will be
+json-converted to a string.
@@ -175,12 +171,11 @@ be stripped on the Evennia side.
[cmd.name, [arg], {}] -> Cmd.Name arg
[cmd.name, [args],{}] -> Cmd.Name [args]
[cmd.name, [], {kwargs}] -> Cmd.Name {kwargs}
-[cmdname, [args, {kwargs}] -> Core.Cmdname [[args],{kwargs}]
+[cmdname, [args, {kwargs}] -> Core.Cmdname [[args],{kwargs}]
Notes
-There are also a few default mappings between evennia outputcmds and
-GMCP:
+There are also a few default mappings between evennia outputcmds and GMCP:
client_options -> Core.Supports.Get
get_inputfuncs -> Core.Commands.Get
get_value -> Char.Value.Get
diff --git a/docs/0.9.5/api/evennia.server.profiling.dummyrunner_settings.html b/docs/0.9.5/api/evennia.server.profiling.dummyrunner_settings.html
index 154eaae626..f00316e1fb 100644
--- a/docs/0.9.5/api/evennia.server.profiling.dummyrunner_settings.html
+++ b/docs/0.9.5/api/evennia.server.profiling.dummyrunner_settings.html
@@ -42,13 +42,17 @@
This module defines dummyrunner settings and sets up
the actions available to dummy accounts.
The settings are global variables:
-TIMESTEP - time in seconds between each ‘tick’
-CHANCE_OF_ACTION - chance 0-1 of action happening
-CHANCE_OF_LOGIN - chance 0-1 of login happening
-TELNET_PORT - port to use, defaults to settings.TELNET_PORT
-ACTIONS - see below
+
+TIMESTEP - time in seconds between each ‘tick’
+CHANCE_OF_ACTION - chance 0-1 of action happening
+CHANCE_OF_LOGIN - chance 0-1 of login happening
+TELNET_PORT - port to use, defaults to settings.TELNET_PORT
+ACTIONS - see below
+
ACTIONS is a tuple
-
(login_func, logout_func, (0.3, func1), (0.1, func2) … )
+
(login_func, logout_func, (0.3, func1), (0.1, func2) ... )
+
+
where the first entry is the function to call on first connect, with a
chance of occurring given by CHANCE_OF_LOGIN. This function is usually
responsible for logging in the account. The second entry is always
@@ -65,28 +69,22 @@ returns a string or a list of command strings to execute. Use the
client object for optionally saving data between actions.
The client object has the following relevant properties and methods:
-
-- key - an optional client key. This is only used for dummyrunner output.
Default is “Dummy-<cid>”
-
-
-
+key - an optional client key. This is only used for dummyrunner output.
+Default is “Dummy-<cid>”
cid - client id
gid - globally unique id, hashed with time stamp
istep - the current step
exits - an empty list. Can be used to store exit names
objs - an empty list. Can be used to store object names
-
-- counter() - returns a unique increasing id, hashed with time stamp
to make it unique also between dummyrunner instances.
-
-
-
+counter() - returns a unique increasing id, hashed with time stamp
+to make it unique also between dummyrunner instances.
The return should either be a single command string or a tuple of
command strings. This list of commands will always be executed every
TIMESTEP with a chance given by CHANCE_OF_ACTION by in the order given
(no randomness) and allows for setting up a more complex chain of
commands (such as creating an account and logging in).
-
—
+
-
evennia.server.profiling.dummyrunner_settings.c_login(client)[source]
diff --git a/docs/0.9.5/api/evennia.server.server.html b/docs/0.9.5/api/evennia.server.server.html
index b1be222e92..505401017f 100644
--- a/docs/0.9.5/api/evennia.server.server.html
+++ b/docs/0.9.5/api/evennia.server.server.html
@@ -38,11 +38,11 @@
evennia.server.server
-
This module implements the main Evennia server process, the core of
-the game engine.
-
This module should be started with the ‘twistd’ executable since it
-sets up all the networking features. (this is done automatically
-by evennia/server/server_runner.py).
+
This module implements the main Evennia server process, the core of the game
+engine.
+
This module should be started with the ‘twistd’ executable since it sets up all
+the networking features. (this is done automatically by
+evennia/server/server_runner.py).
-
class
evennia.server.server.Evennia(application)[source]
@@ -99,20 +99,20 @@ Once finished the last_initial_setup_step is set to -1.
-
shutdown(mode='reload', _reactor_stopping=False)[source]
Shuts down the server from inside it.
-
-- Keyword Arguments
-
diff --git a/docs/0.9.5/api/evennia.server.serversession.html b/docs/0.9.5/api/evennia.server.serversession.html
index bd1ae44a21..273211c3c3 100644
--- a/docs/0.9.5/api/evennia.server.serversession.html
+++ b/docs/0.9.5/api/evennia.server.serversession.html
@@ -43,126 +43,6 @@ a connection to the outside world but don’t know any details about how the
connection actually happens (so it’s the same for telnet, web, ssh etc).
It is stored on the Server side (as opposed to protocol-specific sessions which
are stored on the Portal side)
-
--
-class
evennia.server.serversession.NDbHolder(obj, name, manager_name='attributes')[source]
-Bases: object
-Holder for allowing property access of attributes
-
--
-
__init__(obj, name, manager_name='attributes')[source]
-Initialize self. See help(type(self)) for accurate signature.
-
-
-
--
-
get_all()[source]
-
-
-
--
-property
all
-
-
-
-
-
--
-class
evennia.server.serversession.NAttributeHandler(obj)[source]
-Bases: object
-NAttributeHandler version without recache protection.
-This stand-alone handler manages non-database saving.
-It is similar to AttributeHandler and is used
-by the .ndb handler in the same way as .db does
-for the AttributeHandler.
-
--
-
__init__(obj)[source]
-Initialized on the object
-
-
-
--
-
has(key)[source]
-Check if object has this attribute or not.
-
-- Parameters
-key (str) – The Nattribute key to check.
-
-- Returns
-has_nattribute (bool) – If Nattribute is set or not.
-
-
-
-
-
--
-
get(key, default=None)[source]
-Get the named key value.
-
-- Parameters
-key (str) – The Nattribute key to get.
-
-- Returns
-the value of the Nattribute.
-
-
-
-
-
--
-
add(key, value)[source]
-Add new key and value.
-
-- Parameters
--
-
-
-
-
-
--
-
remove(key)[source]
-Remove Nattribute from storage.
-
-- Parameters
-key (str) – The name of the Nattribute to remove.
-
-
-
-
-
--
-
clear()[source]
-Remove all NAttributes from handler.
-
-
-
--
-
all(return_tuples=False)[source]
-List the contents of the handler.
-
-- Parameters
-return_tuples (bool, optional) – Defines if the Nattributes
-are returns as a list of keys or as a list of (key, value).
-
-- Returns
-nattributes (list) –
-
-- A list of keys [key, key, …] or a
list of tuples [(key, value), …] depending on the
-setting of return_tuples.
-
-
-
-
-
-
-
-
-
-
class
evennia.server.serversession.ServerSession[source]
@@ -183,6 +63,11 @@ through their session.
property cmdset_storage
+
+-
+property
id
+
+
-
at_sync()[source]
@@ -295,7 +180,7 @@ idle timers and command counters.
Update the protocol_flags and sync them with Portal.
- Keyword Arguments
-any – A key:value pair to set in the
+
protocol_flag (any) – A key and value to set in the
protocol_flags dictionary.
@@ -328,7 +213,7 @@ for the protocol(s).
the respective inputfuncs.
- Keyword Arguments
-any – Incoming data from protocol on
+
kwargs (any) – Incoming data from protocol on
the form {“commandname”: ((args), {kwargs}),…}
@@ -345,12 +230,12 @@ this data off to self.sessionhandler.call_inputfuncs(self, **kwargs)Wrapper to mimic msg() functionality of Objects and Accounts.
- Parameters
--
+for the protocol(s).
diff --git a/docs/0.9.5/api/evennia.server.sessionhandler.html b/docs/0.9.5/api/evennia.server.sessionhandler.html
index 0b5964ffcf..be28c169c7 100644
--- a/docs/0.9.5/api/evennia.server.sessionhandler.html
+++ b/docs/0.9.5/api/evennia.server.sessionhandler.html
@@ -41,8 +41,7 @@
This module defines handlers for storing sessions when handles
sessions of users connecting to the server.
There are two similar but separate stores of sessions:
-
-
+
- ServerSessionHandler - this stores generic game sessions
for the game. These sessions has no knowledge about
how they are connected to the world.
@@ -56,7 +55,6 @@ handle network communication but holds no game info.
-
-
class
evennia.server.sessionhandler.DummySession[source]
@@ -120,30 +118,22 @@ sessions in store.
- Parameters
session (Session) – The relevant session instance.
-kwargs (dict) –
send-instruction, with the keyword itself being the name
-of the instruction (like “text”). Suitable values for each
-keyword are:
-arg -> [[arg], {}]
-[args] -> [[args], {}]
-{kwargs} -> [[], {kwargs}]
-[args, {kwargs}] -> [[arg], {kwargs}]
-[[args], {kwargs}] -> [[args], {kwargs}]
-
-
-
+kwargs (dict) – of the instruction (like “text”). Suitable values for each
+keyword are:
+- arg -> [[arg], {}]
+- [args] -> [[args], {}]
+- {kwargs} -> [[], {kwargs}]
+- [args, {kwargs}] -> [[arg], {kwargs}]
+- [[args], {kwargs}] -> [[args], {kwargs}]
- Returns
-kwargs (dict) –
-
-- A cleaned dictionary of cmdname:[[args],{kwargs}] pairs,
where the keys, args and kwargs have all been converted to
+
kwargs (dict) – A cleaned dictionary of cmdname:[[args],{kwargs}] pairs,
+where the keys, args and kwargs have all been converted to
send-safe entities (strings or numbers), and inlinefuncs have been
applied.
-
-
-
@@ -492,12 +482,13 @@ object.
sessions_from_csessid(csessid)[source]
Given a client identification hash (for session types that offer them)
return all sessions with a matching hash.
-
-- Parameters
-csessid (str) – The session hash.
+
+- Args
csessid (str): The session hash.
-- Returns
-sessions (list) – The sessions with matching .csessid, if any.
+
+
+- Returns
+sessions (list) – The sessions with matching .csessid, if any.
@@ -554,17 +545,17 @@ this class’ sessionhandler.call_inputfunc with the
-
call_inputfuncs(session, **kwargs)[source]
-Split incoming data into its inputfunc counterparts.
-This should be called by the serversession.data_in
-as sessionhandler.call_inputfunc(self, **kwargs).
+Split incoming data into its inputfunc counterparts. This should be
+called by the serversession.data_in as
+sessionhandler.call_inputfunc(self, **kwargs).
We also intercept OOB communication here.
- Parameters
sessions (Session) – Session.
- Keyword Arguments
-kwargs (any) – Incoming data from protocol on
-the form {“commandname”: ((args), {kwargs}),…}
+any (tuple) – Incoming data from protocol, each
+on the form commandname=((args), {kwargs}).
diff --git a/docs/0.9.5/api/evennia.server.signals.html b/docs/0.9.5/api/evennia.server.signals.html
index ccf5929847..7ea4491ce3 100644
--- a/docs/0.9.5/api/evennia.server.signals.html
+++ b/docs/0.9.5/api/evennia.server.signals.html
@@ -38,22 +38,20 @@
evennia.server.signals
-
This module brings Django Signals into Evennia. These are events that
-can be subscribed to by importing a given Signal and using the
-following code.
-
THIS_SIGNAL.connect(callback, sender_object**)
+This module brings Django Signals into Evennia. These are events that can be
+subscribed to by importing a given Signal and using the following code.
+THIS_SIGNAL.connect(callback, sender_object)
-When other code calls THIS_SIGNAL.send(sender, **kwargs), the callback
-will be triggered.
-Callbacks must be in the following format:
+When other code calls THIS_SIGNAL.send(sender, **kwargs), the callback will
+be triggered.
+Callbacks must be on the following format:
def my_callback(sender, **kwargs):
- ...
+ # ...
-This is used on top of hooks to make certain features easier to
-add to contribs without necessitating a full takeover of hooks
-that may be in high demand.
+This is used on top of hooks to make certain features easier to add to contribs
+without necessitating a full takeover of hooks that may be in high demand.
diff --git a/docs/0.9.5/api/evennia.typeclasses.attributes.html b/docs/0.9.5/api/evennia.typeclasses.attributes.html
index 0e87486a5c..4fd095d1b3 100644
--- a/docs/0.9.5/api/evennia.typeclasses.attributes.html
+++ b/docs/0.9.5/api/evennia.typeclasses.attributes.html
@@ -44,9 +44,9 @@ both pure-string values and pickled arbitrary data.
the Attribute- and NickHandlers as well as the
NAttributeHandler,
which is a non-db version of Attributes.
--
-class
evennia.typeclasses.attributes.Attribute(*args, **kwargs)[source]
-Bases: evennia.utils.idmapper.models.SharedMemoryModel
+-
+class
evennia.typeclasses.attributes.IAttribute[source]
+Bases: object
Attributes are things that are specific to different types of objects. For
example, a drink container needs to store its fill level, whereas an exit
needs to store its open/closed/locked/unlocked state. These are done via
@@ -81,6 +81,106 @@ attributes on the fly as we like.
+
This class is an API/Interface/Abstract base class; do not instantiate it directly.
+
+-
+
locks[source]
+
+
+
+-
+property
key
+
+
+
+-
+property
strvalue
+
+
+
+-
+property
category
+
+
+
+-
+property
model
+
+
+
+-
+property
attrtype
+
+
+
+-
+property
date_created
+
+
+
+-
+property
lock_storage
+
+
+
+-
+
access(accessing_obj, access_type='read', default=False, **kwargs)[source]
+Determines if another object has permission to access.
+
+- Parameters
+
+accessing_obj (object) – Entity trying to access this one.
+access_type (str, optional) – Type of access sought, see
+the lock documentation.
+default (bool, optional) – What result to return if no lock
+of access_type was found. The default, False, means a lockdown
+policy, only allowing explicit access.
+kwargs (any, optional) – Not used; here to make the API consistent with
+other access calls.
+
+
+- Returns
+result (bool) – If the lock was passed or not.
+
+
+
+
+
+
+
+-
+class
evennia.typeclasses.attributes.InMemoryAttribute(pk, **kwargs)[source]
+Bases: evennia.typeclasses.attributes.IAttribute
+This Attribute is used purely for NAttributes/NAttributeHandler. It has no database backend.
+
+-
+
__init__(pk, **kwargs)[source]
+Create an Attribute that exists only in Memory.
+
+- Parameters
+
+pk (int) – This is a fake ‘primary key’ / id-field. It doesn’t actually have to be unique, but is fed an
+incrementing number from the InMemoryBackend by default. This is needed only so Attributes can be
+sorted. Some parts of the API also see the lack of a .pk field as a sign that the Attribute was
+deleted.
+**kwargs – Other keyword arguments are used to construct the actual Attribute.
+
+
+
+
+
+
+-
+property
value
+
+
+
+
+
+-
+class
evennia.typeclasses.attributes.Attribute(*args, **kwargs)[source]
+Bases: evennia.typeclasses.attributes.IAttribute, evennia.utils.idmapper.models.SharedMemoryModel
+This attribute is stored via Django. Most Attributes will be using this class.
-
db_key
@@ -137,41 +237,6 @@ object the first time, the query is executed.
object the first time, the query is executed.
-
--
-
locks[source]
-
-
-
--
-property
key
-
-
-
--
-property
strvalue
-
-
-
--
-property
category
-
-
-
--
-property
model
-
-
-
--
-property
attrtype
-
-
-
--
-property
date_created
-
-
-
property
lock_storage
@@ -186,29 +251,6 @@ as storing a dbobj which is then deleted elsewhere) out-of-sync.
The overhead of unpickling seems hard to avoid.
-
--
-
access(accessing_obj, access_type='attrread', default=False, **kwargs)[source]
-Determines if another object has permission to access.
-
-- Parameters
-
-accessing_obj (object) – Entity trying to access this one.
-access_type (str, optional) – Type of access sought, see
-the lock documentation.
-default (bool, optional) – What result to return if no lock
-of access_type was found. The default, False, means a lockdown
-policy, only allowing explicit access.
-kwargs (any, optional) – Not used; here to make the API consistent with
-other access calls.
-
-
-- Returns
-result (bool) – If the lock was passed or not.
-
-
-
-
-
exception
DoesNotExist
@@ -237,6 +279,18 @@ instances.
class built by **create_forward_many_to_many_manager()** defined below.
+
+-
+property
attrtype
+A wrapper for getting database field db_attrtype.
+
+
+
+-
+property
category
+A wrapper for getting database field db_category.
+
+
-
channeldb_set
@@ -253,6 +307,12 @@ instances.
class built by **create_forward_many_to_many_manager()** defined below.
+
+-
+property
date_created
+A wrapper for getting database field db_date_created.
+
+
-
get_next_by_db_date_created(*, field=<django.db.models.fields.DateTimeField: db_date_created>, is_next=True, **kwargs)
@@ -270,6 +330,18 @@ class built by **create_forward_many_to_many_manager()** define
object the first time, the query is executed.
+
+-
+property
key
+A wrapper for getting database field db_key.
+
+
+
+-
+property
model
+A wrapper for getting database field db_model.
+
+
-
objectdb_set
@@ -307,6 +379,12 @@ instances.
class built by **create_forward_many_to_many_manager()** defined below.
+
+-
+property
strvalue
+A wrapper for getting database field db_strvalue.
+
+
-
typename = 'SharedMemoryModelBase'
@@ -314,21 +392,544 @@ class built by **create_forward_many_to_many_manager()** define
+
+-
+class
evennia.typeclasses.attributes.IAttributeBackend(handler, attrtype)[source]
+Bases: object
+Abstract interface for the backends used by the Attribute Handler.
+All Backends must implement this base class.
+
+-
+
__init__(handler, attrtype)[source]
+Initialize self. See help(type(self)) for accurate signature.
+
+
+
+-
+
query_all()[source]
+Fetch all Attributes from this object.
+
+- Returns
+attrlist (list) – A list of Attribute objects.
+
+
+
+
+
+-
+
query_key(key, category)[source]
+
+- Parameters
+-
+
+- Returns
+attribute (IAttribute) – A single Attribute.
+
+
+
+
+
+-
+
query_category(category)[source]
+Returns every matching Attribute as a list, given a category.
+This method calls up whatever storage the backend uses.
+
+- Parameters
+category (str or None) – The category to query.
+
+- Returns
+attrs (list) – The discovered Attributes.
+
+
+
+
+
+-
+
get(key=None, category=None)[source]
+Frontend for .get_cache. Retrieves Attribute(s).
+
+- Parameters
+
+key (str, optional) – Attribute key to query for
+category (str, optional) – Attribiute category
+
+
+- Returns
+args (list) –
+
+- Returns a list of zero or more matches
found from cache or database.
+
+
+
+
+
+
+
+
+-
+
reset_cache()[source]
+Reset cache from the outside.
+
+
+
+-
+
do_create_attribute(key, category, lockstring, value, strvalue)[source]
+Does the hard work of actually creating Attributes, whatever is needed.
+
+- Parameters
+
+key (str) – The Attribute’s key.
+category (str or None) – The Attribute’s category, or None
+lockstring (str) – Any locks for the Attribute.
+value (obj) – The Value of the Attribute.
+strvalue (bool) – Signifies if this is a strvalue Attribute. Value MUST be a string or
+this will lead to Trouble. Ignored for InMemory attributes.
+
+
+- Returns
+attr (IAttribute) – The new Attribute.
+
+
+
+
+
+-
+
create_attribute(key, category, lockstring, value, strvalue=False, cache=True)[source]
+Creates Attribute (using the class specified for the backend), (optionally) caches it, and returns it.
+This MUST actively save the Attribute to whatever database backend is used, AND
+call self.set_cache(key, category, new_attrobj)
+
+- Parameters
+
+key (str) – The Attribute’s key.
+category (str or None) – The Attribute’s category, or None
+lockstring (str) – Any locks for the Attribute.
+value (obj) – The Value of the Attribute.
+strvalue (bool) – Signifies if this is a strvalue Attribute. Value MUST be a string or
+this will lead to Trouble. Ignored for InMemory attributes.
+cache (bool) – Whether to cache the new Attribute
+
+
+- Returns
+attr (IAttribute) – The new Attribute.
+
+
+
+
+
+-
+
do_update_attribute(attr, value)[source]
+Simply sets a new Value to an Attribute.
+
+- Parameters
+-
+
+
+
+
+
+-
+
do_batch_update_attribute(attr_obj, category, lock_storage, new_value, strvalue)[source]
+Called opnly by batch add. For the database backend, this is a method
+of updating that can alter category and lock-storage.
+
+- Parameters
+
+attr_obj (IAttribute) – The Attribute being altered.
+category (str or None) – The attribute’s (new) category.
+lock_storage (str) – The attribute’s new locks.
+new_value (obj) – The Attribute’s new value.
+strvalue (bool) – Signifies if this is a strvalue Attribute. Value MUST be a string or
+this will lead to Trouble. Ignored for InMemory attributes.
+
+
+
+
+
+
+-
+
do_batch_finish(attr_objs)[source]
+Called after batch_add completed. Used for handling database operations
+and/or caching complications.
+
+- Parameters
+attr_objs (list of IAttribute) – The Attributes created/updated thus far.
+
+
+
+
+
+-
+
batch_add(*args, **kwargs)[source]
+Batch-version of .add(). This is more efficient than repeat-calling
+.add when having many Attributes to add.
+
+- Parameters
+*args (tuple) –
Tuples of varying length representing the
+Attribute to add to this object. Supported tuples are
+
+(key, value)
+(key, value, category)
+(key, value, category, lockstring)
+(key, value, category, lockstring, default_access)
+
+
+
+- Raises
+RuntimeError – If trying to pass a non-iterable as argument.
+
+
+Notes
+The indata tuple order matters, so if you want a lockstring but no
+category, set the category to None. This method does not have the
+ability to check editing permissions and is mainly used internally.
+It does not use the normal self.add but applies the Attributes
+directly to the database.
+
+
+
+-
+
do_delete_attribute(attr)[source]
+Does the hard work of actually deleting things.
+
+- Parameters
+attr (IAttribute) – The attribute to delete.
+
+
+
+
+
+-
+
delete_attribute(attr)[source]
+Given an Attribute, deletes it. Also remove it from cache.
+
+- Parameters
+attr (IAttribute) – The attribute to delete.
+
+
+
+
+
+-
+
update_attribute(attr, value)[source]
+Simply updates an Attribute.
+
+- Parameters
+-
+
+
+
+
+
+-
+
do_batch_delete(attribute_list)[source]
+Given a list of attributes, deletes them all.
+The default implementation is fine, but this is overridable since some databases may allow
+for a better method.
+
+- Parameters
+attribute_list (list of IAttribute) –
+
+
+
+
+
+-
+
clear_attributes(category, accessing_obj, default_access)[source]
+Remove all Attributes on this object.
+
+- Parameters
+
+category (str, optional) – If given, clear only Attributes
+of this category.
+accessing_obj (object, optional) – If given, check the
+attredit lock on each Attribute before continuing.
+default_access (bool, optional) – Use this permission as
+fallback if access_obj is given but there is no lock of
+type attredit on the Attribute in question.
+
+
+
+
+
+
+-
+
get_all_attributes()[source]
+Simply returns all Attributes of this object, sorted by their IDs.
+
+- Returns
+attributes (list of IAttribute)
+
+
+
+
+
+
+
+-
+class
evennia.typeclasses.attributes.InMemoryAttributeBackend(handler, attrtype)[source]
+Bases: evennia.typeclasses.attributes.IAttributeBackend
+This Backend for Attributes stores NOTHING in the database. Everything is kept in memory, and normally lost
+on a crash, reload, shared memory flush, etc. It generates IDs for the Attributes it manages, but these are
+of little importance beyond sorting and satisfying the caching logic to know an Attribute hasn’t been
+deleted out from under the cache’s nose.
+
+-
+
__init__(handler, attrtype)[source]
+Initialize self. See help(type(self)) for accurate signature.
+
+
+
+-
+
query_all()[source]
+Fetch all Attributes from this object.
+
+- Returns
+attrlist (list) – A list of Attribute objects.
+
+
+
+
+
+-
+
query_key(key, category)[source]
+
+- Parameters
+-
+
+- Returns
+attribute (IAttribute) – A single Attribute.
+
+
+
+
+
+-
+
query_category(category)[source]
+Returns every matching Attribute as a list, given a category.
+This method calls up whatever storage the backend uses.
+
+- Parameters
+category (str or None) – The category to query.
+
+- Returns
+attrs (list) – The discovered Attributes.
+
+
+
+
+
+-
+
do_create_attribute(key, category, lockstring, value, strvalue)[source]
+See parent class.
+strvalue has no meaning for InMemory attributes.
+
+
+
+-
+
do_update_attribute(attr, value)[source]
+Simply sets a new Value to an Attribute.
+
+- Parameters
+-
+
+
+
+
+
+-
+
do_batch_update_attribute(attr_obj, category, lock_storage, new_value, strvalue)[source]
+No need to bother saving anything. Just set some values.
+
+
+
+-
+
do_batch_finish(attr_objs)[source]
+Nothing to do here for In-Memory.
+
+- Parameters
+attr_objs (list of IAttribute) – The Attributes created/updated thus far.
+
+
+
+
+
+-
+
do_delete_attribute(attr)[source]
+Removes the Attribute from local storage. Once it’s out of the cache, garbage collection will handle the rest.
+
+- Parameters
+attr (IAttribute) – The attribute to delete.
+
+
+
+
+
+
+
+-
+class
evennia.typeclasses.attributes.ModelAttributeBackend(handler, attrtype)[source]
+Bases: evennia.typeclasses.attributes.IAttributeBackend
+Uses Django models for storing Attributes.
+
+-
+
__init__(handler, attrtype)[source]
+Initialize self. See help(type(self)) for accurate signature.
+
+
+
+-
+
query_all()[source]
+Fetch all Attributes from this object.
+
+- Returns
+attrlist (list) – A list of Attribute objects.
+
+
+
+
+
+-
+
query_key(key, category)[source]
+
+- Parameters
+-
+
+- Returns
+attribute (IAttribute) – A single Attribute.
+
+
+
+
+
+-
+
query_category(category)[source]
+Returns every matching Attribute as a list, given a category.
+This method calls up whatever storage the backend uses.
+
+- Parameters
+category (str or None) – The category to query.
+
+- Returns
+attrs (list) – The discovered Attributes.
+
+
+
+
+
+-
+
do_create_attribute(key, category, lockstring, value, strvalue)[source]
+Does the hard work of actually creating Attributes, whatever is needed.
+
+- Parameters
+
+key (str) – The Attribute’s key.
+category (str or None) – The Attribute’s category, or None
+lockstring (str) – Any locks for the Attribute.
+value (obj) – The Value of the Attribute.
+strvalue (bool) – Signifies if this is a strvalue Attribute. Value MUST be a string or
+this will lead to Trouble. Ignored for InMemory attributes.
+
+
+- Returns
+attr (IAttribute) – The new Attribute.
+
+
+
+
+
+-
+
do_update_attribute(attr, value)[source]
+Simply sets a new Value to an Attribute.
+
+- Parameters
+-
+
+
+
+
+
+-
+
do_batch_update_attribute(attr_obj, category, lock_storage, new_value, strvalue)[source]
+Called opnly by batch add. For the database backend, this is a method
+of updating that can alter category and lock-storage.
+
+- Parameters
+
+attr_obj (IAttribute) – The Attribute being altered.
+category (str or None) – The attribute’s (new) category.
+lock_storage (str) – The attribute’s new locks.
+new_value (obj) – The Attribute’s new value.
+strvalue (bool) – Signifies if this is a strvalue Attribute. Value MUST be a string or
+this will lead to Trouble. Ignored for InMemory attributes.
+
+
+
+
+
+
+-
+
do_batch_finish(attr_objs)[source]
+Called after batch_add completed. Used for handling database operations
+and/or caching complications.
+
+- Parameters
+attr_objs (list of IAttribute) – The Attributes created/updated thus far.
+
+
+
+
+
+-
+
do_delete_attribute(attr)[source]
+Does the hard work of actually deleting things.
+
+- Parameters
+attr (IAttribute) – The attribute to delete.
+
+
+
+
+
+
-
-class
evennia.typeclasses.attributes.AttributeHandler(obj)[source]
+class evennia.typeclasses.attributes.AttributeHandler(obj, backend_class)[source]
Bases: object
Handler for adding Attributes to the object.
-
-
__init__(obj)[source]
-Initialize handler.
-
-
-
--
-
reset_cache()[source]
-Reset cache from the outside.
+__init__(obj, backend_class)[source]
+Setup the AttributeHandler.
+
+- Parameters
+
+obj (TypedObject) – An Account, Object, Channel, ServerSession (not technically a typed object), etc.
+backend_class (IAttributeBackend class) – The class of the backend to use.
+
+
+
@@ -443,14 +1044,12 @@ repeat-calling add when having many Attributes to add.
*args (tuple) –
Each argument should be a tuples (can be of varying
length) representing the Attribute to add to this object.
Supported tuples are
-
-
-(key, value)
-(key, value, category)
-(key, value, category, lockstring)
-(key, value, category, lockstring, default_access)
+
+(key, value)
+(key, value, category)
+(key, value, category, lockstring)
+(key, value, category, lockstring, default_access)
-
- Keyword Arguments
@@ -549,6 +1148,34 @@ Attributes has no lock of type attrread defined on them.
+
+-
+
reset_cache()[source]
+
+
+
+
+
+-
+class
evennia.typeclasses.attributes.DbHolder(obj, name, manager_name='attributes')[source]
+Bases: object
+Holder for allowing property access of attributes
+
+-
+
__init__(obj, name, manager_name='attributes')[source]
+Initialize self. See help(type(self)) for accurate signature.
+
+
+
+-
+
get_all()[source]
+
+
+
+-
+property
all
+
+
@@ -570,17 +1197,15 @@ matched by the in_template.
- Returns
-(regex, str) –
-
-- Regex to match against strings and a template
Template with markers {arg1}, {arg2}, etc for
-replacement using the standard .format method.
-
-
-
+regex (regex) – Regex to match against strings
+template (str): Template with markers **{arg1}, {arg2}**, etc for
+replacement using the standard .format method.
- Raises
-attributes.NickTemplateInvalid – If the in/out template does not have a matching
-number of $args.
+-
@@ -613,7 +1238,15 @@ They also always use the
strvalue fields for their data.
-
__init__(*args, **kwargs)[source]
-Initialize handler.
+Setup the AttributeHandler.
+
+- Parameters
+
+obj (TypedObject) – An Account, Object, Channel, ServerSession (not technically a typed object), etc.
+backend_class (IAttributeBackend class) – The class of the backend to use.
+
+
+
@@ -726,102 +1359,6 @@ with nicks stored on the Account level.
-
--
-class
evennia.typeclasses.attributes.NAttributeHandler(obj)[source]
-Bases: object
-This stand-alone handler manages non-database saving.
-It is similar to AttributeHandler and is used
-by the .ndb handler in the same way as .db does
-for the AttributeHandler.
-
--
-
__init__(obj)[source]
-Initialized on the object
-
-
-
--
-
has(key)[source]
-Check if object has this attribute or not.
-
-- Parameters
-key (str) – The Nattribute key to check.
-
-- Returns
-has_nattribute (bool) – If Nattribute is set or not.
-
-
-
-
-
--
-
get(key)[source]
-Get the named key value.
-
-- Parameters
-key (str) – The Nattribute key to get.
-
-- Returns
-the value of the Nattribute.
-
-
-
-
-
--
-
add(key, value)[source]
-Add new key and value.
-
-- Parameters
--
-
-
-
-
-
--
-
remove(key)[source]
-Remove Nattribute from storage.
-
-- Parameters
-key (str) – The name of the Nattribute to remove.
-
-
-
-
-
--
-
clear()[source]
-Remove all NAttributes from handler.
-
-
-
--
-
all(return_tuples=False)[source]
-List the contents of the handler.
-
-- Parameters
-return_tuples (bool, optional) – Defines if the Nattributes
-are returns as a list of keys or as a list of (key, value).
-
-- Returns
-nattributes (list) –
-
-- A list of keys [key, key, …] or a
list of tuples [(key, value), …] depending on the
-setting of return_tuples.
-
-
-
-
-
-
-
-
-
diff --git a/docs/0.9.5/api/evennia.typeclasses.managers.html b/docs/0.9.5/api/evennia.typeclasses.managers.html
index 48f78e4f9a..988dd8293f 100644
--- a/docs/0.9.5/api/evennia.typeclasses.managers.html
+++ b/docs/0.9.5/api/evennia.typeclasses.managers.html
@@ -49,15 +49,13 @@ all Attributes and TypedObjects).
-
get_attribute(key=None, category=None, value=None, strvalue=None, obj=None, attrtype=None, **kwargs)[source]
-Return Attribute objects by key, by category, by value, by
-strvalue, by object (it is stored on) or with a combination of
-those criteria.
+Return Attribute objects by key, by category, by value, by strvalue, by
+object (it is stored on) or with a combination of those criteria.
- Parameters
-key (str, optional) – The attribute’s key to search for.
-category (str, optional) – The category of the attribute(s)
-to search for.
+key (str, optional) – The attribute’s key to search for
+category (str, optional) – The category of the attribute(s) to search for.
value (str, optional) – The attribute value to search for.
Note that this is not a very efficient operation since it
will query for a pickled entity. Mutually exclusive to
@@ -68,14 +66,14 @@ mutually exclusive to the value keyword and will take
precedence if given.
obj (Object, optional) – On which object the Attribute to
search for is.
-attrtype (str, optional) – An attribute-type to search for.
+
attrype (str, optional) – An attribute-type to search for.
By default this is either None (normal Attributes) or
“nick”.
-kwargs (any) – Currently unused. Reserved for future use.
+**kwargs (any) – Currently unused. Reserved for future use.
- Returns
-attributes (list) – The matching Attributes.
+list – The matching Attributes.
@@ -167,7 +165,7 @@ stored on) or with a combination of those criteria.
to search for.
obj (Object, optional) – On which object the Tag to
search for is.
-
tagtype (str, optional) – One of None (normal tags),
+
tagtype (str, optional) – One of None (normal tags),
“alias” or “permission”
global_search (bool, optional) – Include all possible tags,
not just tags on this object
diff --git a/docs/0.9.5/api/evennia.typeclasses.models.html b/docs/0.9.5/api/evennia.typeclasses.models.html
index dfa7cdfde4..ed4fefd8ed 100644
--- a/docs/0.9.5/api/evennia.typeclasses.models.html
+++ b/docs/0.9.5/api/evennia.typeclasses.models.html
@@ -59,7 +59,6 @@ The admin should usually not have to deal directly with the database object
layer.
This module also contains the Managers for the respective models; inherit from
these to create custom managers.
-
-
class
evennia.typeclasses.models.TypedObject(*args, **kwargs)[source]
@@ -158,10 +157,10 @@ a class based on the db_typeclass_path database field rather
than use the one in the model.
- Parameters
--
+
through to parent. (Passed) –
+
+ - Keyword Arguments
+through to parent. (Passed) –
Notes
@@ -367,7 +366,7 @@ superuser lock bypass (be careful with this one).
- Keyword Arguments
-kwargs (any) – Ignored, but is there to make the api
+
kwar (any) – Ignored, but is there to make the api
consistent with the object-typeclass method access, which
use it to feed to its hook methods.
@@ -400,36 +399,30 @@ without involving any locks.
property db
Attribute handler wrapper. Allows for the syntax
obj.db.attrname = value
- and
+# and
value = obj.db.attrname
- and
+# and
del obj.db.attrname
- and
+# and
all_attr = obj.db.all()
+# (unless there is an attribute
+# named 'all', in which case that will be returned instead).
-(unless there is an attribute named ‘all’, in which case that will be
-returned instead).
-
property
ndb
-A non-attr_obj store (NonDataBase). Everything stored to this is
-guaranteed to be cleared when a server is shutdown. Syntax is same as
-for the .db property, e.g.
-obj.ndb.attrname = value
- and
-value = obj.ndb.attrname
- and
-del obj.ndb.attrname
- and
-all_attr = obj.ndb.all()
-
-
-What makes this preferable over just assigning properties directly on
-the object is that Evennia can track caching for these properties and
-for example avoid wiping objects with set .ndb data on cache flushes.
+NonDataBase). Everything stored
+to this is guaranteed to be cleared when a server is shutdown.
+Syntax is same as for the _get_db_holder() method and
+property, e.g. obj.ndb.attr = value etc.
+
+- Type
+A non-attr_obj store (ndb
+
+
@@ -516,27 +509,22 @@ at/getting information for this object.
classmethod web_get_create_url()[source]
Returns the URI path for a View that allows users to create new
instances of this object.
+ex. Chargen = ‘/characters/create/’
+For this to work, the developer must have defined a named view somewhere
+in urls.py that follows the format ‘modelname-action’, so in this case
+a named view of ‘character-create’ would be referenced by this method.
+ex.
+url(r’characters/create/’, ChargenView.as_view(), name=’character-create’)
+If no View has been created and defined in urls.py, returns an
+HTML anchor.
+This method is naive and simply returns a path. Securing access to
+the actual view and limiting who can create new objects is the
+developer’s responsibility.
- Returns
path (str) – URI path to object creation page, if defined.
-Examples
-Chargen = '/characters/create/'
-
-
-For this to work, the developer must have defined a named view somewhere
-in urls.py that follows the format ‘modelname-action’, so in this case
-a named view of ‘character-create’ would be referenced by this method.
-url(r'characters/create/', ChargenView.as_view(), name='character-create')
-
-
-If no View has been created and defined in urls.py, returns an
-HTML anchor.
-Notes
-This method is naive and simply returns a path. Securing access to
-the actual view and limiting who can create new objects is the
-developer’s responsibility.
@@ -556,12 +544,12 @@ this object.
For this to work, the developer must have defined a named view somewhere
in urls.py that follows the format ‘modelname-action’, so in this case
a named view of ‘character-detail’ would be referenced by this method.
-CharDetailView.as_view(), name='character-detail')
+url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$',
+ CharDetailView.as_view(), name='character-detail')
If no View has been created and defined in urls.py, returns an
HTML anchor.
-Notes
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can view this object is the
developer’s responsibility.
@@ -574,7 +562,7 @@ developer’s responsibility.
object.
- Returns
-path (str) – URI path to object puppet page, if defined.
+str – URI path to object puppet page, if defined.
Examples
@@ -590,7 +578,6 @@ a named view of ‘character-puppet’ would be referenced by this method.
If no View has been created and defined in urls.py, returns an
HTML anchor.
-
Notes
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can view this object is the developer’s
responsibility.
@@ -603,7 +590,7 @@ responsibility.
object.
- Returns
-path (str) – URI path to object update page, if defined.
+str – URI path to object update page, if defined.
Examples
@@ -619,7 +606,6 @@ a named view of ‘character-update’ would be referenced by this method.
If no View has been created and defined in urls.py, returns an
HTML anchor.
-Notes
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can modify objects is the developer’s
responsibility.
@@ -638,19 +624,19 @@ responsibility.
Oscar (Character) = '/characters/oscar/1/delete/'
-For this to work, the developer must have defined a named view somewhere
-in urls.py that follows the format ‘modelname-action’, so in this case
-a named view of ‘character-detail’ would be referenced by this method.
+For this to work, the developer must have defined a named view
+somewhere in urls.py that follows the format ‘modelname-action’, so
+in this case a named view of ‘character-detail’ would be referenced
+by this method.
url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/delete/$',
CharDeleteView.as_view(), name='character-delete')
-If no View has been created and defined in urls.py, returns an
-HTML anchor.
-Notes
+If no View has been created and defined in urls.py, returns an HTML
+anchor.
This method is naive and simply returns a path. Securing access to
-the actual view and limiting who can delete this object is the developer’s
-responsibility.
+the actual view and limiting who can delete this object is the
+developer’s responsibility.
@@ -676,12 +662,12 @@ this object.
For this to work, the developer must have defined a named view somewhere
in urls.py that follows the format ‘modelname-action’, so in this case
a named view of ‘character-detail’ would be referenced by this method.
-CharDetailView.as_view(), name='character-detail')
+url(r'characters/(?P<slug>[\w\d\-]+)/(?P<pk>[0-9]+)/$',
+ CharDetailView.as_view(), name='character-detail')
If no View has been created and defined in urls.py, returns an
HTML anchor.
-Notes
This method is naive and simply returns a path. Securing access to
the actual view and limiting who can view this object is the
developer’s responsibility.
diff --git a/docs/0.9.5/api/evennia.typeclasses.tags.html b/docs/0.9.5/api/evennia.typeclasses.tags.html
index e4c99d30e6..9ed3374673 100644
--- a/docs/0.9.5/api/evennia.typeclasses.tags.html
+++ b/docs/0.9.5/api/evennia.typeclasses.tags.html
@@ -269,6 +269,33 @@ existing Tag object, this will be re-used and no new Tag
will be created.
+
+-
+
has(tag=None, category=None, return_list=False)[source]
+Checks if the given Tag (or list of Tags) exists on the object.
+
+- Parameters
+
+tag (str or iterable) – The Tag key or tags to check for.
+If None, search by category.
+category (str, optional) – Limit the check to Tags with this
+category (note, that None is the default category).
+
+
+- Returns
+has_tag (bool or list) –
+
+- If the Tag exists on this object or not.
If tag was given as an iterable then the return is a list of booleans.
+
+
+
+
+- Raises
+ValueError – If neither tag nor category is given.
+
+
+
+
-
get(key=None, default=None, category=None, return_tagobj=False, return_list=False)[source]
diff --git a/docs/0.9.5/api/evennia.utils.ansi.html b/docs/0.9.5/api/evennia.utils.ansi.html
index f91da60e6b..b5d17cab10 100644
--- a/docs/0.9.5/api/evennia.utils.ansi.html
+++ b/docs/0.9.5/api/evennia.utils.ansi.html
@@ -39,24 +39,25 @@
evennia.utils.ansi
ANSI - Gives colour to text.
-
Use the codes defined in ANSIPARSER in your text to apply colour to text
-according to the ANSI standard.
-
This is |rRed text|n and this is normal again.
+Use the codes defined in ANSIPARSER in your text
+to apply colour to text according to the ANSI standard.
+Examples:
+"This is |rRed text|n and this is normal again."
-Mostly you should not need to call parse_ansi() explicitly; it is run by
-Evennia just before returning data to/from the user. Depreciated/decativated
-example forms are available in contribs by extending the ansi mapping
-This module also contains the ANSIString custom string-type, which correctly
-wraps/manipulates and tracks lengths of strings containing ANSI-markup.
-
+Mostly you should not need to call parse_ansi() explicitly;
+it is run by Evennia just before returning data to/from the
+user. Depreciated example forms are available by extending
+the ansi mapping.
-
class
evennia.utils.ansi.ANSIParser[source]
Bases: object
-A class that parses ANSI markup to ANSI command sequences
-We also allow to escape colour codes by prepending with
-an extra |, so ||r will literally print |r.
+A class that parses ANSI markup
+to ANSI command sequences
+We also allow to escape colour codes
+by prepending with a for xterm256,
+an extra | for Merc-style codes
-
ansi_map = [('|n', '\x1b[0m'), ('|/', '\r\n'), ('|-', '\t'), ('|_', ' '), ('|*', '\x1b[7m'), ('|^', '\x1b[5m'), ('|u', '\x1b[4m'), ('|r', '\x1b[1m\x1b[31m'), ('|g', '\x1b[1m\x1b[32m'), ('|y', '\x1b[1m\x1b[33m'), ('|b', '\x1b[1m\x1b[34m'), ('|m', '\x1b[1m\x1b[35m'), ('|c', '\x1b[1m\x1b[36m'), ('|w', '\x1b[1m\x1b[37m'), ('|x', '\x1b[1m\x1b[30m'), ('|R', '\x1b[22m\x1b[31m'), ('|G', '\x1b[22m\x1b[32m'), ('|Y', '\x1b[22m\x1b[33m'), ('|B', '\x1b[22m\x1b[34m'), ('|M', '\x1b[22m\x1b[35m'), ('|C', '\x1b[22m\x1b[36m'), ('|W', '\x1b[22m\x1b[37m'), ('|X', '\x1b[22m\x1b[30m'), ('|h', '\x1b[1m'), ('|H', '\x1b[22m'), ('|!R', '\x1b[31m'), ('|!G', '\x1b[32m'), ('|!Y', '\x1b[33m'), ('|!B', '\x1b[34m'), ('|!M', '\x1b[35m'), ('|!C', '\x1b[36m'), ('|!W', '\x1b[37m'), ('|!X', '\x1b[30m'), ('|[R', '\x1b[41m'), ('|[G', '\x1b[42m'), ('|[Y', '\x1b[43m'), ('|[B', '\x1b[44m'), ('|[M', '\x1b[45m'), ('|[C', '\x1b[46m'), ('|[W', '\x1b[47m'), ('|[X', '\x1b[40m')]
@@ -417,15 +418,9 @@ occurrence of the separator rather than the first.
- Returns
-result (tuple) –
-
-prefix (ANSIString): The part of the string before the
-separator
-sep (ANSIString): The separator itself
-postfix (ANSIString): The part of the string after the
-separator.
-
-
+ANSIString – The part of the string before the separator
+ANSIString: The separator itself
+ANSIString: The part of the string after the separator.
@@ -771,12 +766,15 @@ left untouched. Characters mapped to None are deleted.
join(iterable)[source]
Joins together strings in an iterable, using this string between each
one.
+NOTE: This should always be used for joining strings when ANSIStrings
+are involved. Otherwise color information will be discarded by python,
+due to details in the C implementation of strings.
- Parameters
iterable (list of strings) – A list of strings to join together
- Returns
-result (ANSIString) –
+ANSIString –
- A single string with all of the iterable’s
contents concatenated, with this string between each.
@@ -785,18 +783,10 @@ one.
Examples
-
-- ::
ANSIString(‘, ‘).join([‘up’, ‘right’, ‘left’, ‘down’])
-
-
-Would return
-ANSIString('up, right, left, down')
+>>> ANSIString(', ').join(['up', 'right', 'left', 'down'])
+ANSIString('up, right, left, down')
-Notes
-This should always be used for joining strings when ANSIStrings are
-involved. Otherwise color information will be discarded by python,
-due to details in the C implementation of strings.
diff --git a/docs/0.9.5/api/evennia.utils.batchprocessors.html b/docs/0.9.5/api/evennia.utils.batchprocessors.html
index 234417375c..9e95cd1f19 100644
--- a/docs/0.9.5/api/evennia.utils.batchprocessors.html
+++ b/docs/0.9.5/api/evennia.utils.batchprocessors.html
@@ -39,23 +39,21 @@
evennia.utils.batchprocessors
This module contains the core methods for the Batch-command- and
-Batch-code-processors respectively. In short, these are two different
-ways to build a game world using a normal text-editor without having
-to do so ‘on the fly’ in-game. They also serve as an automatic backup
-so you can quickly recreate a world also after a server reset. The
-functions in this module is meant to form the backbone of a system
-called and accessed through game commands.
-
The Batch-command processor is the simplest. It simply runs a list of
-in-game commands in sequence by reading them from a text file. The
-advantage of this is that the builder only need to remember the normal
-in-game commands. They are also executing with full permission checks
-etc, making it relatively safe for builders to use. The drawback is
-that in-game there is really a builder-character walking around
-building things, and it can be important to create rooms and objects
-in the right order, so the character can move between them. Also
-objects that affects players (such as mobs, dark rooms etc) will
-affect the building character too, requiring extra care to turn
-off/on.
+Batch-code-processors respectively. In short, these are two different ways to
+build a game world using a normal text-editor without having to do so ‘on the
+fly’ in-game. They also serve as an automatic backup so you can quickly
+recreate a world also after a server reset. The functions in this module is
+meant to form the backbone of a system called and accessed through game
+commands.
+
The Batch-command processor is the simplest. It simply runs a list of in-game
+commands in sequence by reading them from a text file. The advantage of this is
+that the builder only need to remember the normal in-game commands. They are
+also executing with full permission checks etc, making it relatively safe for
+builders to use. The drawback is that in-game there is really a
+builder-character walking around building things, and it can be important to
+create rooms and objects in the right order, so the character can move between
+them. Also objects that affects players (such as mobs, dark rooms etc) will
+affect the building character too, requiring extra care to turn off/on.
The Batch-code processor is a more advanced system that accepts full
Python code, executing in chunks. The advantage of this is much more
power; practically anything imaginable can be coded and handled using
@@ -68,33 +66,38 @@ etc. You also need to know Python and Evennia’s API. Hence it’s
recommended that the batch-code processor is limited only to
superusers or highly trusted staff.
-
Batch-Command processor file syntax
+
Batch-command processor file syntax
The batch-command processor accepts ‘batchcommand files’ e.g
batch.ev, containing a sequence of valid Evennia commands in a
simple format. The engine runs each command in sequence, as if they
had been run at the game prompt.
Each Evennia command must be delimited by a line comment to mark its
-end. This way entire game worlds can be created and planned offline; it is
+end.
+
look
+# delimiting comment
+create/drop box
+# another required comment
+
+
+
One can also inject another batchcmdfile:
+
#INSERT path.batchcmdfile
+
+
+
This way entire game worlds can be created and planned offline; it is
especially useful in order to create long room descriptions where a
real offline text editor is often much better than any online text
editor or prompt.
-
There is only one batchcommand-specific entry to use in a batch-command
-files (all others are just like in-game commands):
-
-
Example of batch.ev file:
+
+
Example of batch.ev file:
# batch file
# all lines starting with # are comments; they also indicate
# that a command definition is over.
-@create box
+create box
# this comment ends the @create command.
-@set box/desc = A large box.
+set box/desc = A large box.
Inside are some scattered piles of clothing.
@@ -107,24 +110,25 @@ written in this file.
# (so two empty lines becomes a new paragraph).
-@teleport #221
+teleport #221
# (Assuming #221 is a warehouse or something.)
# (remember, this comment ends the @teleport command! Don'f forget it)
# Example of importing another file at this point.
-#INSERT examples.batch
+#IMPORT examples.batch
-@drop box
+drop box
# Done, the box is in the warehouse! (this last comment is not necessary to
-# close the @drop command since it's the end of the file)
+# close the drop command since it's the end of the file)
An example batch file is contrib/examples/batch_example.ev.
+
-
Batch-Code processor file syntax
+
Batch-code processor file syntax
The Batch-code processor accepts full python modules (e.g. batch.py)
that looks identical to normal Python files. The difference from
importing and running any Python module is that the batch-code module
@@ -155,13 +159,17 @@ this file.
Importing works as normal. The following variables are automatically
made available in the script namespace.
-caller - The object executing the batchscript
-DEBUG - This is a boolean marking if the batchprocessor is running
-in debug mode. It can be checked to e.g. delete created objects
+
caller - The object executing the batchscript
+
+- DEBUG - This is a boolean marking if the batchprocessor is running
in debug mode. It can be checked to e.g. delete created objects
when running a CODE block multiple times during testing.
-(avoids creating a slew of same-named db objects)
+(avoids creating a slew of same-named db objects)
+
+
+
-
Example batch.py file:
+
+
Example batch.py file
#HEADER
from django.conf import settings
@@ -189,7 +197,6 @@ when running a CODE block multiple times during testing.
script = create.create_script()
-
-
evennia.utils.batchprocessors.read_batchfile(pythonpath, file_ending='.py')[source]
@@ -206,7 +213,7 @@ or .py). The ending should not be included in the python path.
- Returns
-str – The text content of the batch file.
+text (str) – The text content of the batch file.
- Raises
IOError – If problems reading file.
@@ -222,13 +229,22 @@ or .py). The ending should not be included in the python path.
-
parse_file(pythonpath)[source]
-This parses the lines of a batchfile according to the following
-rules:
+This parses the lines of a batch-command-file.
+
+- Parameters
+pythonpath (str) – The dot-python path to the file.
+
+- Returns
+list – A list of all parsed commands with arguments, as strings.
+
+
+Notes
+Parsing follows the following rules:
-# at the beginning of a line marks the end of the command before
+
A # at the beginning of a line marks the end of the command before
it. It is also a comment and any number of # can exist on
subsequent lines (but not inside comments).
-#INSERT at the beginning of a line imports another
+
#INSERT at the beginning of a line imports another
batch-cmd file file and pastes it into the batch file as if
it was written there.
Commands are placed alone at the beginning of a line and their
@@ -263,30 +279,28 @@ a newline (so two empty lines is a paragraph).
-
parse_file(pythonpath)[source]
-This parses the lines of a batchfile according to the following
-rules:
+This parses the lines of a batch-code file
- Parameters
pythonpath (str) – The dot-python path to the file.
- Returns
-codeblocks (list) –
+list –
-- A list of all #CODE blocks, each with
prepended #HEADER data. If no #CODE blocks were found,
-this will be a list of one element.
+- A list of all #CODE blocks, each with
prepended #HEADER block data. If no #CODE
+blocks were found, this will be a list of one element
+containing all code in the file (so a normal Python file).
Notes
+Parsing is done according to the following rules:
-
-- Code before a #CODE/HEADER block are considered part of
the first code/header block or is the ONLY block if no
-#CODE/HEADER blocks are defined.
-
-
-
+Code before a #CODE/HEADER block are considered part of
+the first code/header block or is the ONLY block if no
+#CODE/HEADER blocks are defined.
Lines starting with #HEADER starts a header block (ends other blocks)
Lines starting with #CODE begins a code block (ends other blocks)
Lines starting with #INSERT are on form #INSERT filename. Code from
@@ -319,6 +333,7 @@ namespace.
+
@@ -345,8 +360,14 @@ namespace.
diff --git a/docs/0.9.5/api/evennia.utils.create.html b/docs/0.9.5/api/evennia.utils.create.html
index b8aae93351..830785c882 100644
--- a/docs/0.9.5/api/evennia.utils.create.html
+++ b/docs/0.9.5/api/evennia.utils.create.html
@@ -38,25 +38,15 @@
evennia.utils.create
-
This module gathers all the essential database-creation
-functions for the game engine’s various object types.
-
Only objects created ‘stand-alone’ are in here, e.g. object Attributes
-are always created directly through their respective objects.
-
Each creation_* function also has an alias named for the entity being
-created, such as create_object() and object(). This is for
-consistency with the utils.search module and allows you to do the
-shorter “create.object()”.
-
The respective object managers hold more methods for manipulating and
-searching objects already existing in the database.
-
-- Models covered:
Objects
-Scripts
-Help
-Message
-Channel
-Accounts
-
-
+
This module gathers all the essential database-creation functions for the game
+engine’s various object types.
+
Only objects created ‘stand-alone’ are in here. E.g. object Attributes are
+always created through their respective objects handlers.
+
Each creation_* function also has an alias named for the entity being created,
+such as create_object() and object(). This is for consistency with the
+utils.search module and allows you to do the shorter create.object().
+
The respective object managers hold more methods for manipulating and searching
+objects already existing in the database.
-
evennia.utils.create.create_object(typeclass=None, key=None, location=None, home=None, permissions=None, locks=None, aliases=None, tags=None, destination=None, report_to=None, nohome=False, attributes=None, nattributes=None)[source]
@@ -66,15 +56,14 @@ Accounts
typeclass (class or str) – Class or python path to a typeclass.
key (str) – Name of the new object. If not set, a name of
-#dbref will be set.
+#dbref will be set.
home (Object or str) – Obj or #dbref to use as the object’s
home location.
permissions (list) – A list of permission strings or tuples (permstring, category).
locks (str) – one or more lockstrings, separated by semicolons.
aliases (list) – A list of alternative keys or tuples (aliasstring, category).
tags (list) – List of tag keys or tuples (tagkey, category) or (tagkey, category, data).
-destination (Object or str) – Obj or #dbref to use as an Exit’s
-target.
+destination (Object or str) – Obj or #dbref to use as an Exit’s target.
report_to (Object) – The object to return error messages to.
nohome (bool) – This allows the creation of objects without a
default home location; only used when creating the default
diff --git a/docs/0.9.5/api/evennia.utils.dbserialize.html b/docs/0.9.5/api/evennia.utils.dbserialize.html
index 42b657b260..17658e27af 100644
--- a/docs/0.9.5/api/evennia.utils.dbserialize.html
+++ b/docs/0.9.5/api/evennia.utils.dbserialize.html
@@ -87,7 +87,7 @@ will save to when they update. It must have a ‘value’ property
that saves assigned data to the database. Skip if not
serializing onto a given object. If db_obj is given, this
function will convert lists, dicts and sets to their
-_SaverList, _SaverDict and _SaverSet counterparts.
+_SaverList, _SaverDict and _SaverSet counterparts.
- Returns
diff --git a/docs/0.9.5/api/evennia.utils.eveditor.html b/docs/0.9.5/api/evennia.utils.eveditor.html
index c5c27fb64e..f955aa0686 100644
--- a/docs/0.9.5/api/evennia.utils.eveditor.html
+++ b/docs/0.9.5/api/evennia.utils.eveditor.html
@@ -39,47 +39,39 @@
evennia.utils.eveditor
EvEditor (Evennia Line Editor)
-
This implements an advanced line editor for editing longer texts
-in-game. The editor mimics the command mechanisms of the “VI” editor
-(a famous line-by-line editor) as far as reasonable.
+
This implements an advanced line editor for editing longer texts in-game. The
+editor mimics the command mechanisms of the “VI” editor (a famous line-by-line
+editor) as far as reasonable.
Features of the editor:
-
-
+
undo/redo.
edit/replace on any line of the buffer.
search&replace text anywhere in buffer.
formatting of buffer, or selection, to certain width + indentations.
allow to echo the input or not, depending on your client.
+in-built help
-
-
To use the editor, just import EvEditor from this module
-and initialize it:
+
To use the editor, just import EvEditor from this module and initialize it:
from evennia.utils.eveditor import EvEditor
-EvEditor(caller, loadfunc=None, savefunc=None, quitfunc=None, key="", persistent=True)
+
+# set up an editor to edit the caller's 'desc' Attribute
+def _loadfunc(caller):
+ return caller.db.desc
+
+def _savefunc(caller, buffer):
+ caller.db.desc = buffer.strip()
+ return True
+
+def _quitfunc(caller):
+ caller.msg("Custom quit message")
+
+# start the editor
+EvEditor(caller, loadfunc=None, savefunc=None, quitfunc=None, key="",
+ persistent=True, code=False)
-
-caller is the user of the editor, the one to see all feedback.
-loadfunc(caller) is called when the editor is first launched; the
-return from this function is loaded as the starting buffer in the
-editor.
-safefunc(caller, buffer) is called with the current buffer when
-saving in the editor. The function should return True/False depending
-on if the saving was successful or not.
-quitfunc(caller) is called when the editor exits. If this is given,
-no automatic quit messages will be given.
-key is an optional identifier for the editing session, to be
-displayed in the editor.
-persistent means the editor state will be saved to the database making it
-survive a server reload. Note that using this mode, the load- save-
-and quit-funcs must all be possible to pickle - notable unusable
-callables are class methods and functions defined inside other
-functions. With persistent=False, no such restriction exists.
-code set to True activates features on the EvEditor to enter Python code.
-
-
In addition, the EvEditor can be used to enter Python source code,
-and offers basic handling of indentation.
-
+
The editor can also be used to format Python code and be made to
+survive a reload. See the EvEditor class for more details.
-
class
evennia.utils.eveditor.CmdSaveYesNo(**kwargs)[source]
@@ -123,6 +115,11 @@ command was given specifically as “no” or “n”.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '__noinput_command', 'category': 'general', 'key': '__nomatch_command', 'tags': '', 'text': '\n Save the editor state on quit. This catches\n nomatches (defaults to Yes), and avoid saves only if\n command was given specifically as "no" or "n".\n '}
+
+
@@ -181,17 +178,19 @@ command was given specifically as “no” or “n”.
-
parse()[source]
-Handles pre-parsing
-
-- Usage:
:cmd [li] [w] [txt]
-
-
+Handles pre-parsing. Editor commands are on the form
+
Where all arguments are optional.
-li - line number (int), starting from 1. This could also
-be a range given as <l>:<l>.
-w - word(s) (string), could be encased in quotes.
-txt - extra text (string), could be encased in quotes.
+
+- li - line number (int), starting from 1. This could also
be a range given as <l>:<l>.
+
+
+
+w - word(s) (string), could be encased in quotes.
+txt - extra text (string), could be encased in quotes.
@@ -215,6 +214,11 @@ be a range given as <l>:<l>.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '', 'category': 'general', 'key': 'command', 'tags': '', 'text': '\n Base parent for editor commands\n '}
+
+
@@ -250,6 +254,11 @@ indentation.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': '__noinput_command', 'category': 'general', 'key': '__nomatch_command', 'tags': '', 'text': '\n No command match - Inputs line of text into buffer.\n '}
+
+
@@ -264,7 +273,7 @@ indentation.
-
-
aliases = [':p', ':', ':r', ':w', ':UU', ':uu', ':<', ':f', ':y', ':dw', ':dd', ':>', ':q', ':!', ':S', '::', ':echo', ':j', ':::', ':s', ':u', ':=', ':q!', ':DD', ':x', ':fi', ':fd', ':A', ':i', ':wq', ':I', ':h']
+aliases = [':>', ':x', ':UU', ':', ':!', ':w', ':=', ':dd', ':S', ':DD', ':p', ':::', ':wq', ':u', ':I', ':A', ':uu', ':h', ':y', ':echo', ':r', ':fi', ':q!', ':s', ':dw', '::', ':j', ':fd', ':i', ':<', ':q', ':f']
@@ -290,6 +299,11 @@ efficient presentation.
lock_storage = 'cmd:all()'
+
+-
+
search_index_entry = {'aliases': ':> :x :UU : :! :w := :dd :S :DD :p ::: :wq :u :I :A :uu :h :y :echo :r :fi :q! :s :dw :: :j :fd :i :< :q :f', 'category': 'general', 'key': ':editor_command_group', 'tags': '', 'text': '\n Commands for the editor\n '}
+
+
diff --git a/docs/0.9.5/api/evennia.utils.evform.html b/docs/0.9.5/api/evennia.utils.evform.html
index 1a5dd2c9ba..b00c4b068d 100644
--- a/docs/0.9.5/api/evennia.utils.evform.html
+++ b/docs/0.9.5/api/evennia.utils.evform.html
@@ -72,6 +72,7 @@ object when displaying the form.
| cccccccc | cccccccccccccccccBccccccccccccccccc |
| | |
-------------------------------------------------
+'''
The first line of the FORM string is ignored. The forms and table
@@ -162,16 +163,16 @@ EvCell or Tables.
-
__init__(filename=None, cells=None, tables=None, form=None, **kwargs)[source]
-Initiate the form.
+Initiate the form
- Keyword Arguments
filename (str) – Path to template file.
-cells (dict) – A dictionary mapping of {id:text}.
-tables (dict) – A dictionary mapping of {id:EvTable}.
-form (dict) – A dictionary of
+
cells (dict) – A dictionary mapping {id: text}
+tables (dict) – A dictionary mapping {id: EvTable}.
+form (dict) – A dictionary
{“FORMCHAR”:char, “TABLECHAR”:char, “FORM”:templatestring}.
-if this is given, filename is not read.
+If this is given, filename is not read.
diff --git a/docs/0.9.5/api/evennia.utils.evmenu.html b/docs/0.9.5/api/evennia.utils.evmenu.html
index 09b8fdbdd6..2ff2990b3f 100644
--- a/docs/0.9.5/api/evennia.utils.evmenu.html
+++ b/docs/0.9.5/api/evennia.utils.evmenu.html
@@ -38,9 +38,10 @@
-
Where caller is the object using the menu and input_string is the
+
Where caller is the object using the menu and input_string is the
command entered by the user on the previous node (the command
entered to get to this node). The node function code will only be
executed once per node-visit and the system will accept nodes with
@@ -91,50 +92,43 @@ deleted when the menu is exited.
returned as None as well. If the options are returned as None, the
menu is immediately exited and the default “look” command is called.
-text (str, tuple or None): Text shown at this node. If a tuple, the
-second element in the tuple is a help text to display at this
-node when the user enters the menu help command there.
+
+- text (str, tuple or None): Text shown at this node. If a tuple, the
second element in the tuple is a help text to display at this
+node when the user enters the menu help command there.
+
+
+
options (tuple, dict or None): If None, this exits the menu.
If a single dict, this is a single-option node. If a tuple,
-it should be a tuple of option dictionaries. Option dicts have
-the following keys:
+it should be a tuple of option dictionaries. Option dicts have the following keys:
-
-- key (str or tuple, optional): What to enter to choose this option.
If a tuple, it must be a tuple of strings, where the first string is the
+
key (str or tuple, optional): What to enter to choose this option.
+If a tuple, it must be a tuple of strings, where the first string is the
key which will be shown to the user and the others are aliases.
If unset, the options’ number will be used. The special key _default
marks this option as the default fallback when no other option matches
the user input. There can only be one _default option per node. It
-will not be displayed in the list.
-
-
-
+will not be displayed in the list.
desc (str, optional): This describes what choosing the option will do.
-
-- goto (str, tuple or callable): If string, should be the name of node to go to
when this option is selected. If a callable, it has the signature
+
goto (str, tuple or callable): If string, should be the name of node to go to
+when this option is selected. If a callable, it has the signature
callable(caller[,raw_input][,**kwargs]). If a tuple, the first element
-is the callable and the second is a dict with the kwargs to pass to
+is the callable and the second is a dict with the **kwargs to pass to
the callable. Those kwargs will also be passed into the next node if possible.
Such a callable should return either a str or a (str, dict), where the
string is the name of the next node to go to and the dict is the new,
(possibly modified) kwarg to pass into the next node. If the callable returns
-None or the empty string, the current node will be revisited.
-
-
-
-
-- exec (str, callable or tuple, optional): This takes the same input as goto above
and runs before it. If given a node name, the node will be executed but will not
+None or the empty string, the current node will be revisited.
+exec (str, callable or tuple, optional): This takes the same input as goto above
+and runs before it. If given a node name, the node will be executed but will not
be considered the next node. If node/callback returns str or (str, dict), these will
replace the goto step (goto callbacks will not fire), with the string being the
next node name and the optional dict acting as the kwargs-input for the next node.
-If an exec callable returns None, the current node is re-run.
-
-
-
+If an exec callable returns the empty string (only), the current node is re-run.
-
If key is not given, the option will automatically be identified by
+
If key is not given, the option will automatically be identified by
its number 1..N.
Example:
# in menu_module.py
@@ -188,9 +182,8 @@ same Using help will show the help text, otherwise a list of
available commands while in menu mode.
The menu tree is exited either by using the in-menu quit command or by
reaching a node without any options.
-For a menu demo, import CmdTestMenu from this module and add it to
-your default cmdset. Run it with this module, like testmenu
-evennia.utils.evmenu.
+For a menu demo, import CmdTestMenu from this module and add it to
+your default cmdset. Run it with this module, like testmenu evennia.utils.evmenu.