From f83c2bddf89cb8b787f7f03c175831ac7d3108c9 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sun, 29 Aug 2010 18:46:58 +0000 Subject: [PATCH] Trunk: Merged the Devel-branch (branches/griatch) into /trunk. This constitutes a major refactoring of Evennia. Development will now continue in trunk. See the wiki and the past posts to the mailing list for info. /Griatch --- ABOUT | 71 - CODING_STYLE | 50 +- INSTALL | 129 +- LICENSE | 2 +- README | 161 +- TODO | 9 - VERSION | 1 + docs/Doxyfile | 1630 ++++++++++++++ docs/README | 57 +- docs/doxygen/Doxyfile | 275 --- docs/doxygen/README | 8 - game/evennia.py | 112 +- game/gamesrc/commands/basecommand.py | 78 + .../{events => commands/default}/__init__.py | 0 game/gamesrc/commands/default/batchprocess.py | 689 ++++++ .../commands/default/cmdset_default.py | 98 + .../commands/default/cmdset_unloggedin.py | 21 + game/gamesrc/commands/default/comms.py | 792 +++++++ game/gamesrc/commands/default/general.py | 703 ++++++ game/gamesrc/commands/default/help.py | 281 +++ game/gamesrc/commands/default/info.py | 204 ++ game/gamesrc/commands/default/muxcommand.py | 147 ++ game/gamesrc/commands/default/objmanip.py | 1685 +++++++++++++++ game/gamesrc/commands/default/privileged.py | 670 ++++++ game/gamesrc/commands/default/syscommands.py | 173 ++ game/gamesrc/commands/default/tests.py | 190 ++ .../default/unimplemented}/__init__.py | 0 .../commands/default/unimplemented}/imc2.py | 0 .../commands/default/unimplemented}/irc.py | 0 .../commands/default/unimplemented}/search.py | 70 +- game/gamesrc/commands/default/unloggedin.py | 295 +++ .../commands/examples/cmdset_red_button.py | 292 +++ game/gamesrc/commands/examples/example.py | 129 -- game/gamesrc/commands/examples/misc_tests.py | 136 -- .../commands/examples/state_example.py | 333 --- game/gamesrc/events/example.py | 67 - .../{parents/base => objects}/__init__.py | 0 game/gamesrc/objects/baseobjects.py | 158 ++ .../{parents => objects}/examples/__init__.py | 0 game/gamesrc/objects/examples/red_button.py | 168 ++ game/gamesrc/parents/base/README | 6 - game/gamesrc/parents/base/basicobject.py | 27 - game/gamesrc/parents/base/basicplayer.py | 21 - .../parents/examples/custom_basicobject.py | 75 - .../parents/examples/custom_basicplayer.py | 76 - game/gamesrc/parents/examples/red_button.py | 220 -- .../{web/apps => gamesrc/scripts}/__init__.py | 0 game/gamesrc/scripts/basescript.py | 63 + .../scripts/examples}/__init__.py | 0 .../scripts/examples/red_button_scripts.py | 275 +++ game/gamesrc/utils.py | 123 -- .../{batch_example.ev => batch_cmds.ev} | 9 +- game/gamesrc/world/examples/batch_code.py | 71 + game/manage.py | 133 +- game/web/apps/website/models.py | 3 - game/web/apps/website/urls.py | 5 - game/web/apps/website/webcontext.py | 9 - game/web/media/images/LICENCE | 4 + game/web/media/images/evennia_logo.png | Bin 0 -> 688250 bytes game/web/media/images/evennia_logo_small.png | Bin 0 -> 17938 bytes game/web/media/images/favicon.ico | Bin 0 -> 1406 bytes game/web/{apps/website => news}/__init__.py | 0 game/web/news/admin.py | 17 + game/web/{apps => }/news/models.py | 16 +- game/web/{apps => }/news/urls.py | 7 +- game/web/{apps => }/news/views.py | 14 +- game/web/templates/admin/base_site.html | 11 + game/web/templates/admin/index.html | 242 +++ .../{html => templates}/prosimii/base.html | 15 +- .../prosimii/flatpages/default.html | 0 .../{html => templates}/prosimii/index.html | 33 +- .../prosimii/news/archive.html | 4 +- .../prosimii/news/search_form.html | 4 +- .../prosimii/news/show_entry.html | 4 +- .../prosimii/registration/logged_out.html | 0 .../prosimii/registration/login.html | 2 +- .../web/{html => templates}/prosimii/tbi.html | 0 game/web/urls.py | 18 +- {src/cache => game/web/utils}/__init__.py | 0 game/web/{ => utils}/apache_wsgi.conf | 2 +- .../web/utils}/evennia_modpy_apache.conf | 1 + .../web/utils}/evennia_wsgi_apache.conf | 2 +- game/web/utils/general_context.py | 46 + .../managers => game/web/website}/__init__.py | 0 game/web/website/models.py | 7 + game/web/website/urls.py | 10 + game/web/{apps => }/website/views.py | 34 +- sitecustomize.py | 8 +- src/alias_mgr.py | 19 - src/cache/cache.py | 284 --- src/cache/managers/cache.py | 20 - src/cache/models.py | 56 - src/cache/views.py | 1 - src/channels/admin.py | 14 - src/channels/models.py | 126 -- src/cmdhandler.py | 564 ----- src/cmdtable.py | 89 - src/commands/batchprocess.py | 543 ----- src/commands/cmdhandler.py | 364 ++++ src/commands/cmdparser.py | 174 ++ src/commands/cmdset.py | 338 +++ src/commands/cmdsethandler.py | 376 ++++ src/commands/command.py | 149 ++ src/commands/comsys.py | 623 ------ src/commands/general.py | 807 ------- src/commands/info.py | 223 -- src/commands/objmanip.py | 1670 --------------- src/commands/paging.py | 136 -- src/commands/parents.py | 97 - src/commands/privileged.py | 879 -------- src/commands/unloggedin.py | 127 -- src/{channels => comms}/__init__.py | 0 src/comms/admin.py | 40 + src/comms/channelhandler.py | 138 ++ src/comms/managers.py | 322 +++ src/comms/models.py | 590 +++++ src/comsys.py | 398 ---- src/config/admin.py | 30 +- src/config/edit_aliases.py | 27 - src/config/manager.py | 91 + src/config/managers/commandalias.py | 8 - src/config/managers/configvalue.py | 34 - src/config/managers/connectscreen.py | 18 - src/config/models.py | 206 +- src/config/views.py | 1 - src/config_defaults.py | 461 ---- src/defines_global.py | 49 - src/events.py | 196 -- src/exceptions_generic.py | 11 - src/flags.py | 30 - src/gametime.py | 133 -- src/genperms/models.py | 10 - src/genperms/views.py | 1 - src/{config/managers => help}/__init__.py | 0 src/help/admin.py | 12 + src/help/manager.py | 86 + src/help/models.py | 158 ++ .../help/mux_help_db.json | 2 +- src/helpsys/admin.py | 9 - src/helpsys/fixtures/initial_data.json | 1 - src/helpsys/helpsystem.py | 415 ---- src/helpsys/managers.py | 47 - src/helpsys/models.py | 63 - src/helpsys/update_from_file.py | 15 - src/helpsys/views.py | 1 - src/imc2/connection.py | 9 +- src/imc2/events.py | 6 +- src/imc2/imc_ansi.py | 11 +- src/imc2/models.py | 6 +- src/imc2/reply_listener.py | 3 +- src/initial_setup.py | 190 -- src/irc/connection.py | 5 +- src/irc/models.py | 6 +- src/locks.py | 330 --- src/logger.py | 32 - src/objects/__init__.py | 0 src/objects/admin.py | 35 +- src/objects/exceptions.py | 11 - src/objects/exithandler.py | 88 + src/objects/manager.py | 388 ++++ src/objects/managers/attribute.py | 18 - src/objects/managers/object.py | 598 ------ src/objects/models.py | 1896 ++++++----------- src/objects/object_search_funcs.py | 104 + src/objects/objects.py | 376 ++++ src/objects/util/object.py | 29 - src/objects/views.py | 1 - src/{genperms => permissions}/__init__.py | 0 src/permissions/admin.py | 18 + src/permissions/default_permissions.py | 100 + src/permissions/lockfunc_default.py | 188 ++ src/permissions/manager.py | 25 + src/permissions/models.py | 150 ++ src/permissions/permissions.py | 644 ++++++ src/{helpsys => players}/__init__.py | 0 src/players/admin.py | 29 + src/players/manager.py | 147 ++ src/players/models.py | 278 +++ src/players/player.py | 79 + src/scheduler.py | 97 - src/script_parents/basicobject.py | 281 --- src/script_parents/basicplayer.py | 187 -- src/scripthandler.py | 70 - src/{objects/managers => scripts}/__init__.py | 0 src/scripts/admin.py | 29 + src/scripts/manager.py | 171 ++ src/scripts/models.py | 255 +++ src/scripts/scripthandler.py | 158 ++ src/scripts/scripts.py | 303 +++ src/server.py | 205 -- src/{objects/util => server}/__init__.py | 0 src/server/initial_setup.py | 250 +++ src/server/server.py | 155 ++ src/server/session.py | 262 +++ .../sessionhandler.py} | 110 +- src/session.py | 246 --- src/settings_default.py | 431 ++++ src/statetable.py | 402 ---- .../__init__.py | 0 src/typeclasses/managers.py | 158 ++ src/typeclasses/models.py | 966 +++++++++ src/typeclasses/typeclass.py | 185 ++ src/util/functions_general.py | 116 - src/util/functions_user.py | 30 - src/{util => utils}/__init__.py | 0 src/{ => utils}/ansi.py | 25 +- src/utils/batchprocessors.py | 399 ++++ src/utils/create.py | 443 ++++ src/utils/debug.py | 253 +++ src/utils/gametime.py | 208 ++ src/utils/idmapper/LICENSE | 9 + src/utils/idmapper/__init__.py | 41 + src/utils/idmapper/base.py | 129 ++ src/utils/idmapper/manager.py | 15 + src/utils/idmapper/models.py | 2 + src/utils/idmapper/tests.py | 70 + src/utils/logger.py | 69 + src/utils/reimport.py | 658 ++++++ src/utils/reloads.py | 140 ++ src/utils/search.py | 167 ++ src/utils/utils.py | 250 +++ tools/mux_help_importer.py | 147 -- 222 files changed, 22304 insertions(+), 14371 deletions(-) delete mode 100644 ABOUT delete mode 100644 TODO create mode 100644 VERSION create mode 100644 docs/Doxyfile delete mode 100644 docs/doxygen/Doxyfile delete mode 100644 docs/doxygen/README create mode 100644 game/gamesrc/commands/basecommand.py rename game/gamesrc/{events => commands/default}/__init__.py (100%) create mode 100644 game/gamesrc/commands/default/batchprocess.py create mode 100644 game/gamesrc/commands/default/cmdset_default.py create mode 100644 game/gamesrc/commands/default/cmdset_unloggedin.py create mode 100644 game/gamesrc/commands/default/comms.py create mode 100644 game/gamesrc/commands/default/general.py create mode 100644 game/gamesrc/commands/default/help.py create mode 100644 game/gamesrc/commands/default/info.py create mode 100644 game/gamesrc/commands/default/muxcommand.py create mode 100644 game/gamesrc/commands/default/objmanip.py create mode 100644 game/gamesrc/commands/default/privileged.py create mode 100644 game/gamesrc/commands/default/syscommands.py create mode 100644 game/gamesrc/commands/default/tests.py rename game/gamesrc/{parents => commands/default/unimplemented}/__init__.py (100%) rename {src/commands => game/gamesrc/commands/default/unimplemented}/imc2.py (100%) rename {src/commands => game/gamesrc/commands/default/unimplemented}/irc.py (100%) rename {src/commands => game/gamesrc/commands/default/unimplemented}/search.py (78%) create mode 100644 game/gamesrc/commands/default/unloggedin.py create mode 100644 game/gamesrc/commands/examples/cmdset_red_button.py delete mode 100644 game/gamesrc/commands/examples/example.py delete mode 100644 game/gamesrc/commands/examples/misc_tests.py delete mode 100644 game/gamesrc/commands/examples/state_example.py delete mode 100644 game/gamesrc/events/example.py rename game/gamesrc/{parents/base => objects}/__init__.py (100%) create mode 100644 game/gamesrc/objects/baseobjects.py rename game/gamesrc/{parents => objects}/examples/__init__.py (100%) create mode 100644 game/gamesrc/objects/examples/red_button.py delete mode 100644 game/gamesrc/parents/base/README delete mode 100644 game/gamesrc/parents/base/basicobject.py delete mode 100644 game/gamesrc/parents/base/basicplayer.py delete mode 100644 game/gamesrc/parents/examples/custom_basicobject.py delete mode 100644 game/gamesrc/parents/examples/custom_basicplayer.py delete mode 100644 game/gamesrc/parents/examples/red_button.py rename game/{web/apps => gamesrc/scripts}/__init__.py (100%) create mode 100644 game/gamesrc/scripts/basescript.py rename game/{web/apps/news => gamesrc/scripts/examples}/__init__.py (100%) mode change 100755 => 100644 create mode 100644 game/gamesrc/scripts/examples/red_button_scripts.py delete mode 100644 game/gamesrc/utils.py rename game/gamesrc/world/examples/{batch_example.ev => batch_cmds.ev} (87%) create mode 100644 game/gamesrc/world/examples/batch_code.py delete mode 100644 game/web/apps/website/models.py delete mode 100644 game/web/apps/website/urls.py delete mode 100644 game/web/apps/website/webcontext.py create mode 100644 game/web/media/images/LICENCE create mode 100755 game/web/media/images/evennia_logo.png create mode 100755 game/web/media/images/evennia_logo_small.png create mode 100644 game/web/media/images/favicon.ico rename game/web/{apps/website => news}/__init__.py (100%) mode change 100644 => 100755 create mode 100644 game/web/news/admin.py rename game/web/{apps => }/news/models.py (78%) rename game/web/{apps => }/news/urls.py (56%) rename game/web/{apps => }/news/views.py (95%) create mode 100644 game/web/templates/admin/base_site.html create mode 100644 game/web/templates/admin/index.html rename game/web/{html => templates}/prosimii/base.html (86%) rename game/web/{html => templates}/prosimii/flatpages/default.html (100%) rename game/web/{html => templates}/prosimii/index.html (61%) rename game/web/{html => templates}/prosimii/news/archive.html (97%) rename game/web/{html => templates}/prosimii/news/search_form.html (93%) rename game/web/{html => templates}/prosimii/news/show_entry.html (88%) rename game/web/{html => templates}/prosimii/registration/logged_out.html (100%) rename game/web/{html => templates}/prosimii/registration/login.html (90%) rename game/web/{html => templates}/prosimii/tbi.html (100%) rename {src/cache => game/web/utils}/__init__.py (100%) rename game/web/{ => utils}/apache_wsgi.conf (91%) rename {docs => game/web/utils}/evennia_modpy_apache.conf (99%) rename {docs => game/web/utils}/evennia_wsgi_apache.conf (95%) create mode 100644 game/web/utils/general_context.py rename {src/cache/managers => game/web/website}/__init__.py (100%) create mode 100644 game/web/website/models.py create mode 100644 game/web/website/urls.py rename game/web/{apps => }/website/views.py (54%) delete mode 100644 src/alias_mgr.py delete mode 100644 src/cache/cache.py delete mode 100644 src/cache/managers/cache.py delete mode 100644 src/cache/models.py delete mode 100644 src/cache/views.py delete mode 100644 src/channels/admin.py delete mode 100644 src/channels/models.py delete mode 100755 src/cmdhandler.py delete mode 100644 src/cmdtable.py delete mode 100644 src/commands/batchprocess.py create mode 100644 src/commands/cmdhandler.py create mode 100644 src/commands/cmdparser.py create mode 100644 src/commands/cmdset.py create mode 100644 src/commands/cmdsethandler.py create mode 100644 src/commands/command.py delete mode 100644 src/commands/comsys.py delete mode 100644 src/commands/general.py delete mode 100644 src/commands/info.py delete mode 100644 src/commands/objmanip.py delete mode 100644 src/commands/paging.py delete mode 100644 src/commands/parents.py delete mode 100644 src/commands/privileged.py delete mode 100644 src/commands/unloggedin.py rename src/{channels => comms}/__init__.py (100%) create mode 100644 src/comms/admin.py create mode 100644 src/comms/channelhandler.py create mode 100644 src/comms/managers.py create mode 100644 src/comms/models.py delete mode 100644 src/comsys.py delete mode 100644 src/config/edit_aliases.py create mode 100644 src/config/manager.py delete mode 100644 src/config/managers/commandalias.py delete mode 100644 src/config/managers/configvalue.py delete mode 100644 src/config/managers/connectscreen.py delete mode 100755 src/config/views.py delete mode 100644 src/config_defaults.py delete mode 100644 src/defines_global.py delete mode 100644 src/events.py delete mode 100644 src/exceptions_generic.py delete mode 100644 src/flags.py delete mode 100644 src/gametime.py delete mode 100644 src/genperms/models.py delete mode 100644 src/genperms/views.py rename src/{config/managers => help}/__init__.py (100%) create mode 100644 src/help/admin.py create mode 100644 src/help/manager.py create mode 100644 src/help/models.py rename game/docs/help_files.json => src/help/mux_help_db.json (76%) delete mode 100644 src/helpsys/admin.py delete mode 100644 src/helpsys/fixtures/initial_data.json delete mode 100644 src/helpsys/helpsystem.py delete mode 100644 src/helpsys/managers.py delete mode 100644 src/helpsys/models.py delete mode 100644 src/helpsys/update_from_file.py delete mode 100644 src/helpsys/views.py delete mode 100644 src/initial_setup.py delete mode 100644 src/locks.py delete mode 100644 src/logger.py mode change 100755 => 100644 src/objects/__init__.py delete mode 100644 src/objects/exceptions.py create mode 100644 src/objects/exithandler.py create mode 100644 src/objects/manager.py delete mode 100644 src/objects/managers/attribute.py delete mode 100644 src/objects/managers/object.py mode change 100755 => 100644 src/objects/models.py create mode 100644 src/objects/object_search_funcs.py create mode 100644 src/objects/objects.py delete mode 100644 src/objects/util/object.py delete mode 100755 src/objects/views.py rename src/{genperms => permissions}/__init__.py (100%) create mode 100644 src/permissions/admin.py create mode 100644 src/permissions/default_permissions.py create mode 100644 src/permissions/lockfunc_default.py create mode 100644 src/permissions/manager.py create mode 100644 src/permissions/models.py create mode 100644 src/permissions/permissions.py rename src/{helpsys => players}/__init__.py (100%) create mode 100644 src/players/admin.py create mode 100644 src/players/manager.py create mode 100644 src/players/models.py create mode 100644 src/players/player.py delete mode 100644 src/scheduler.py delete mode 100644 src/script_parents/basicobject.py delete mode 100644 src/script_parents/basicplayer.py delete mode 100644 src/scripthandler.py rename src/{objects/managers => scripts}/__init__.py (100%) create mode 100644 src/scripts/admin.py create mode 100644 src/scripts/manager.py create mode 100644 src/scripts/models.py create mode 100644 src/scripts/scripthandler.py create mode 100644 src/scripts/scripts.py delete mode 100755 src/server.py rename src/{objects/util => server}/__init__.py (100%) create mode 100644 src/server/initial_setup.py create mode 100644 src/server/server.py create mode 100644 src/server/session.py rename src/{session_mgr.py => server/sessionhandler.py} (53%) delete mode 100755 src/session.py create mode 100644 src/settings_default.py delete mode 100644 src/statetable.py rename src/{script_parents => typeclasses}/__init__.py (100%) create mode 100644 src/typeclasses/managers.py create mode 100644 src/typeclasses/models.py create mode 100644 src/typeclasses/typeclass.py delete mode 100644 src/util/functions_general.py delete mode 100644 src/util/functions_user.py rename src/{util => utils}/__init__.py (100%) rename src/{ => utils}/ansi.py (90%) create mode 100644 src/utils/batchprocessors.py create mode 100644 src/utils/create.py create mode 100644 src/utils/debug.py create mode 100644 src/utils/gametime.py create mode 100644 src/utils/idmapper/LICENSE create mode 100755 src/utils/idmapper/__init__.py create mode 100755 src/utils/idmapper/base.py create mode 100755 src/utils/idmapper/manager.py create mode 100755 src/utils/idmapper/models.py create mode 100755 src/utils/idmapper/tests.py create mode 100644 src/utils/logger.py create mode 100644 src/utils/reimport.py create mode 100644 src/utils/reloads.py create mode 100644 src/utils/search.py create mode 100644 src/utils/utils.py delete mode 100755 tools/mux_help_importer.py diff --git a/ABOUT b/ABOUT deleted file mode 100644 index 79c9764cf3..0000000000 --- a/ABOUT +++ /dev/null @@ -1,71 +0,0 @@ -Evennia Proof-of-Concept ------------------------- -Evennia is a proof-of-concept MUD server written entirely in Python, backed -by SQL. The project rises from a general dissatisfaction with the limitations -of softcode in MUX and MUSH, and the generally inflexible Diku-derivatives and -relatives. - -Evennia represents a combination of several technologies, and most importantly -of all, my first venture into codebase design. You may find things within -the source that look strange to you, perhaps not ideally designed. I'm open -to suggestions, but this really is largely an experiment and a learning -experience. - -Design Objectives ------------------ -1) To create a MU* server that serves as a great foundation for capable admins -to craft into their respective games. It is not my intention to provide a -full-fledged, ready-to-run base, I'm releasing the means to make such games. - -2) Development of games on Evennia must be easy for anyone with some degree -of Python experience. Building needs to be easy, and per-room, per-object, -and environmental customizations need to be simple to do. - -3) The server must utilize SQL as a storage back-end to allow for web->game -integration. See the details on Django later on in the document for more -details. - -4) Any and all game-specific configuration must reside in SQL, not -external configuration files. The only exception is the settings.py file -containing the SQL information. - -How it all Works ----------------- -Python (Including the SQL driver of your choice) - |-Twisted (http://twistedmatrix.com) - |-SQL (MySQL, SQLite, Postgresql) - |-Django (http://djangoproject.com) - -Evennia is built on top of Twisted, a networking engine that handles a lot -of the guts and lower-level socket stuff for us. - -Serving as our storage medium, SQL is one of the more important and unique -features of the codebase. It allows for very simple code in many cases, and -can lead to a game being a lot more scalable due to the inherent speed of -most modern SQL servers. Another extremely important benefit is that by -storing everything in SQL, we make the entire game accessible from other -means, such as a website. Which leads us to the next component. - -Django is perhaps one of the most interesting introductions to the codebase, -since I'm not aware of any other server using it to run MU*'s. Django is -technically a Python web framework, but it also includes a great data modeling -and database abstraction module. This means that things like Players or -Objects can be represented by a very short class, then related to one another. -This allows us to add, remove, delete, and manipulate things in our database -very easily. Another huge benefit is the admin interface that Django more -or less automatically generates for us. Instead of a bunch of clunky admin -commands, you can fire up your web browser and administer pretty much -everything from there, although equivalent in-game commands may be offered. -The possibilities for developing your game's website are nearly endless with -this tandem of MU* server, SQL, and Django. - -Support -------- -The best place for support is the Evennia website, located at: - http://evennia.com - -Reporting Bugs --------------- -Make sure to report any bugs you encounter on the issue tracker on our Google -Code project. This is easily reached at: - http://code.evennia.com diff --git a/CODING_STYLE b/CODING_STYLE index 1c145e998f..dc3678ab78 100644 --- a/CODING_STYLE +++ b/CODING_STYLE @@ -1,3 +1,4 @@ + Evennia Code Style ------------------ All code submitted or committed to the Evennia project needs to follow the @@ -5,21 +6,48 @@ guidelines outlined in Python PEP 8, which may be found at: http://www.python.org/dev/peps/pep-0008/ -A quick list of other stuff ---------------------------- - * 4-space indention, NO TABS! - * Unix line endings - * CamelCase is only used for classes, nothing else. - * All variables and functions are to be lowercase, and words separated by - underscores. +A quick list of code style points +--------------------------------- + * 4-space indendation, NO TABS! + * Unix line endings. + * CamelCase is only used for classes, nothing else. + * All non-global variable names and all function names are to be lowercase, + words separated by underscores. Variable names should always be more than + two letters long. + * Module-level global variables (only) are to be in CAPITAL letters. * Imports are to be done in this order: - - Python modules (Global, outside of Evennia) + - Python modules (builtins and modules otherwise unrelated to Evennia) + - Twisted - Django - - Project modules + - Evennia src/ modules + - Evennia game/ modules + +Pylint +------ +The program 'pylint' (http://www.logilab.org/857) is a useful tool for checking +your Python code for errors. It will also check how well your code adheres to +the PEP 8 guidelines and tells you what can be improved. + +Since pylint cannot catch dynamically created variables used in commands and +elsewhere in Evennia, one needs to reduce some checks to avoid false errors and +warnings. For best results, run pylint like this: + + > pylint --disable=E1101,E0102,F0401,W0232,R0903 filename.py + +To avoid entering the options every time, you can auto-create a pylintrc file by +using the option --generate-rcfile. You need to dump this output into a +file .pylintrc, for example like this (linux): + + > pylint --disable=E1101,E0102,F0401,W0232,R0903 --generate-rcfile >& ~/.pylintrc + +From now on you can then just run + + > pylint filename.py + Ask Questions! -------------- -If any of this outlined in PEP 8 or the list above doesn't make sense, please +If any of the rules outlined in PEP 8 or in the list above doesn't make sense, please don't hesitate to ask on the Evennia mailing list at http://evennia.com. Keeping our code style uniform makes this project much easier for a wider group -of people to participate in. +of people to participate in. \ No newline at end of file diff --git a/INSTALL b/INSTALL index 240f403c8d..d9e78d9a68 100644 --- a/INSTALL +++ b/INSTALL @@ -1,37 +1,114 @@ -The most detailed and up-to-date instructions can always be found at -http://groups.google.com/group/evennia/web/getting-started?hl=en -It is recommended that you refer to there. The instructions below -should be fine, but are terse and may be slightly out of date. + +Evennia install +--------------- + Requirements ------------ -* Python 2.5 strongly recommended, although 2.3 or 2.4 may work just fine. -* Twisted -- http://twistedmatrix.com/ -* PySqlite2 (If you're using the default SQLite driver) -* Django (Latest trunk from Subversion recommended) -* Optional: Apache2 or equivalent webserver with a Python interpreter - module. Required for web interface. + +* Python (www.python.org) + Version 2.5+ strongly recommended, although 2.3 or 2.4 *may* work just fine. + +* Twisted (http://twistedmatrix.com) + Version 10.0+ + + ZopeInterface 3.0+ (www.zope.org/Products/ZopeInterface) + + (pywin32 (sourceforge.net/projects/pywin32) - needed for Windows only) + +* Django (www.djangoproject.com) + Version 1.1+ or latest subversion trunk recommended. + + PIL library (www.pythonware.com/products/pil) + +* PySqlite2 (http://code.google.com/p/pysqlite) + Needed if you want to use the sqlite default database. Otherwise you need to + check which databases are supported by Django and install/setup that instead. + +* Apache2 (http://httpd.apache.org) + Optional. Other equivalent webservers with a Python interpreter module can also + be used. Required for serving final production web interface (not needed for + web development, django has a test server that's good enough for that). + +* Subversion (subversion.apache.org) + This is needed to download Evennia itself. + +Users of most decent Linux distros should be able to install all the above through +their normal package managers. Windows users will need to visit the various homepages +and install the programs manually. + Installation ------------ -At this point in time, the codebase is changing so rapidly that writing -installation instructions is pretty much pointless. When we get to that stage -in development, we'll make sure to update this. But for the really determined -(or stubborn), here's a rough outline: -* Install Django. -* Get a copy of the Evennia source. -* Optional: Set up your apache2.conf to point mod-python to the settings.py - file if you want the web features. -* Change to the evennia/game directory and run something like: - python manage.py +* Make sure you have/install the prerequsites listed above. + +* Get a copy of the Evennia source through subversion (SVN): + + > svn checkout http://code.google.com/p/evennia/source/checkout evennia + + Once you have downloaded, this is as much internet connectivity you need + for trying out Evennia; you don't need to run any web server or to make + anything visible online (that's for when you have a game created and + want people to join it). For now it runs just fine locally on your machine. + +* Change to the evennia/game directory and run + + > python manage.py + This will create a settings.py file. You may override any of the default values in src/config_defaults.py by pasting them into settings.py and - changing the values. + changing the values. Never edit src/config_defaults.py directly! + * If you want to use anything other than the default SQLite setup, copy and - modify the DATABASE_* variables from src/config_defaults.py. -* Run 'python manage.py syncdb' -* Run 'python evennia.py -i start'. This will start the MU* server on port 4000 - by default. You may change this via the web interface or by editing the - config table in SQL. + modify the database-related variables from src/config_defaults.py. + +* Run + + > python manage.py syncdb + + This sets up the database. Answer 'yes' to create an admin account. Supply + a name, e-mail and password when prompted. Remember what you enter since + they are used when you log into the server as admin. The name given will + be the name of your admin character. + +* Run + + > python evennia.py -i start + + This will start the MU* server on port 4000 by default. You may change + this in the settings.py file by changing the variable GAMEPORTS to one + or more port numbers you want to use. + + Note: Using -i starts the server in 'interactive mode' - it will print + messages to standard output and you can shut it down with (on most systems) + Ctrl-C. To start the server as a background process (suitable for production + environments), just skip the -i flag. A server running as a process is + stopped with 'python evennia.py stop'. + +* Start up your MUD client of choice and point it to your server and port 4000. + If you are just running locally the server name is most likely 'localhost'. + * Login with the email address and password you provided to the syncdb script. + Welcome to Evennia! + + +Web features (Optional) +----------------------- + + If you want to test web features you can also start Django's + test web server. You should start this as a separate process, e.g. + in a separate terminal. Go to Evennia's game/ directory and enter + + > python manage.py runserver + + (obs, not to be confused with 'testserver'). + + Django's test webserver starts up locally on port 8000. Point your webbrowser + to 'localhost:8000' and you should see Evennia's nice default page, + graphics and all (gasp!). You cannot play the game from here, but you can + view and edit the database extensively using the powerful admin interface, + courtesy of Django. + + Note: You should never use the django testserver for anything more than local + tests. If you have a full-fledged web server (like Apache) running you should use + that for production environments. Set up your apache2.conf to point mod-python + to your newly created settings.py file (see online documentation for details). + diff --git a/LICENSE b/LICENSE index 1349d1e3b5..cee8df8309 100644 --- a/LICENSE +++ b/LICENSE @@ -8,7 +8,7 @@ Definitions ----------- * "Package" refers to the collection of files distributed by the Copyright Holder, and derivatives of that collection of files created through textual modification. * "Standard Version" refers to such a Package if it has not been modified, or has been modified in accordance with the wishes of the Copyright Holder as specified below. - * "Copyright Holder" is Gregory Taylor. + * "Copyright Holder" is Gregory Taylor and Griatch (griatch AT gmail DOT com). * "You" is you, if you're thinking about copying or distributing this Package. * "Distribution fee" is a fee you charge for providing a copy of this Package to another party. * "Freely Available" means that no fee is charged for the right to use the item, though there may be fees involved in handling the item. It also means that recipients of the item may redistribute it under the same conditions they received it. diff --git a/README b/README index ff90ab2bbf..c2d29a2f37 100644 --- a/README +++ b/README @@ -1,10 +1,34 @@ + +Evennia README http://evennia.com +-------------- + +- < 2010 (earlier revisions) +- May 2010 - merged ABOUT and README. Added Current status /Griatch +- Aug 2010 - evennia devel merged into trunk /Griatch + +Contents: +--------- +- Version +- About Evennia +- Current Status +- Contact, Support and Development +- Directory structure +- Design Objectives +- The Components + + +Version +------- +Evennia Alpha SVN version + About Evennia ------------- Evennia is a proof-of-concept MU* server that aims to provide a functional -base for developers. While there are quite a few codebases that do the same +bare-bones base for developers. While there are quite a few codebases that do the same (and very well in many cases), we are taking a unique spin on the problem. Some of our flagship features include (or will one day include): +* Coded fully in Python using Django and Twisted * Extensive web integration. * The ability to build/administer through a web browser. * Shared accounts between the website and the game. @@ -13,6 +37,7 @@ Some of our flagship features include (or will one day include): (djangoproject.com) * Simple and easily extensible design. * Very granular permissions. Individual and group based. +* Powerful an extremely extendable base system The essential points here are the web integration and the SQL backing via Django. The Django framework has database abstraction abilities that give us @@ -24,19 +49,135 @@ many features free, such as: simple yet very powerful. * For any model we outline for the server's use, we have the ability to more or less automatically generate a web-based admin interface for it with - two lines of code. This lets you Create, Update, or Delete entries. + two lines of code. This lets you Create, Update, or Delete entries, as well + limit permissions for those abilities. * On the web-based side of things, features such as automatic form validation, abstraction of sessions and cookies, and access to whatever game data you - desire are all attractive. - -Support and Development + desire are all attractive. + +See the INSTALL file for help on setting up and running Evennia. + + +Current Status +-------------- +Aug 2010: +Evennia-griatch-branch is ready for merging with trunk. This marks +a rather big change in the inner workings of the server, but should +hopefully bring everything together into one consistent package as +code development continues. + +May 2010: +Evennia is currently being heavily revised and cleaned from +the years of gradual piecemeal development. It is thus in a very +'Alpha' stage at the moment. This means that old code snippets +will not be backwards compatabile. Changes touch almost all +parts of Evennia's innards, from the way Objects are handled +to Events, Commands and Permissions. + + +Contact, Support and Development ----------------------- -Since we're so early in development, we really can't hope to offer much support. -However, if you'd like to report bugs, make suggestions, or help with the -code work, visit either or both of the following links: +We are early in development, but we try to give support best we can +if you feel daring enough to play with the codebase. Make a post to +the mailing list or chat us up on IRC if you have questions. We also +have a bug tracker if you want to report bugs. Finally, if +you are willing to help with the code work, we much appreciate all help! +Visit either of the following resources: * Evennia Webpage http://evennia.com + +* Evennia wiki (documentation) + http://code.google.com/p/evennia/wiki/Index -* Evennia Code Page - http://code.evennia.com +* Evennia Code Page (See INSTALL text for installation) + http://code.google.com/p/evennia/source/checkout + +* Bug tracker + http://code.google.com/p/evennia/issues/list + +* IRC channel + visit channel #evennia on the Freenode IRC network + + +Directory structure +------------------- +evennia + |_______src + | |___(engine-related dirs) + | + |_______game (start the server) + |___gamesrc + |___(game-related dirs) + +The two main directories you will spend most of your time in +are src/ and game/ (probably mostly game/). + +Basically src contains everything related to +running the gritty stuff behind the scenes. Unless you are an +Evennia developer you should normally make sure never to edit +things in src/, since this is where we push new revisions that +may overwrite your changes when you update. You will however +need to have a good feeling for the resources supplied by +the functions in src, since accessing them correctly is the key +to making your dream game come true. + +If src/ is the Evennia developer's domain, the game/ directory +on the other hand contains YOUR game. This is where you will +define and extend the commands, objects and systems of Evennia +to make your dream game. game/ contains the main server settings +and the actual evennia executable to start things. game/gamesrc/ +holds all the templates for creating objects in your virtual world. + +With this little first orientation, you should head into the online +Evennia wiki documentation to get going with the codebase. + + +Design Objectives +----------------- +1) To create a barebones MU* server that serves as a great foundation +for capable admins to craft their own respective games. It is not the +intention to provide a full-fledged, ready-to-run base, rather Evennia +is offering the means to make such games. + +2) Development of games on Evennia must be easy for anyone with some degree +of Python experience. Building needs to be easy, and per-room, per-object, +and environmental customizations need to be simple to do. + +3) The server must utilize SQL as a storage back-end to allow for web->game +integration. See the details on Django later on in the document for more +details. + +4) Any and all game-specific configuration must reside in SQL, not +external configuration files. The only exception is the settings.py file +containing the SQL information. + + +The Components +-------------- +Python (Including the SQL driver of your choice) + |-Twisted (http://twistedmatrix.com) + |-SQL (MySQL, SQLite, Postgresql) + |-Django (http://djangoproject.com) + +Evennia is built on top of Twisted, a networking engine that handles a lot +of the guts and lower-level socket stuff for us. + +Serving as our storage medium, SQL allows for very simple code in many cases, and +can lead to a game being a lot more scalable due to the inherent speed of +most modern SQL servers. Another extremely important benefit is that by +storing everything in SQL, we make the entire game accessible from other +means, such as a website. Which leads us to the next component. + +Django is perhaps one of the most interesting introductions to the codebase. + Django is technically a Python web framework, but it also includes a great +data modeling and database abstraction module. This means that things like +Players or Objects can be represented by a very short class, then related to one +another. This allows us to add, remove, delete, and manipulate things in our database +very easily. Another huge benefit is the admin interface that Django more +or less automatically generates for us. Instead of a bunch of clunky admin +commands, you can fire up your web browser and administer pretty much +everything from there, although equivalent in-game commands may be offered. + +The possibilities for developing your game's website are nearly endless with +this tandem of MU* server, SQL, and Django. \ No newline at end of file diff --git a/TODO b/TODO deleted file mode 100644 index 0b9f2d1b3f..0000000000 --- a/TODO +++ /dev/null @@ -1,9 +0,0 @@ -TODO List ---------- -The TODO list has all of the things currently needing attention the most in it. -If you are feeling ambitious, tackle as much as you can and send patches -to the project site or via email to gtaylor@clemson.edu. - -To see what is currently in need of work, visit the issue tracker at: - - http://code.google.com/p/evennia/issues/list \ No newline at end of file diff --git a/VERSION b/VERSION new file mode 100644 index 0000000000..0776212ec9 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +SVN-griatch-branch \ No newline at end of file diff --git a/docs/Doxyfile b/docs/Doxyfile new file mode 100644 index 0000000000..a6597f4edc --- /dev/null +++ b/docs/Doxyfile @@ -0,0 +1,1630 @@ +# Doxyfile 1.7.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = Evennia + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = SVN-Alpha + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = YES + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = YES + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = YES + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = NO + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will rougly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = YES + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = NO + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. +# This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../ + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = docs + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. +# If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. +# Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. +# The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. +# Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = YES + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Evennia development team + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = YES + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. +# This is useful +# if you want to understand what is going on. +# On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans.ttf + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = YES + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/docs/README b/docs/README index 2fc3d5c6ca..c5f068e0ca 100644 --- a/docs/README +++ b/docs/README @@ -1,14 +1,57 @@ -* Evennia documentation +DOCS README +----------- - To build the auto-documentation (overview of all the sources, with comments), read the - instructions in ./doxygen. +* Evennia docs and manual -The most updated 'manual' is currently the online wiki, at + - The most updated documentation is found in the online wiki, - http://code.google.com/p/evennia/wiki/Index?tm=6 + http://code.google.com/p/evennia/wiki/Index + + - You can also ask for help from the evennia community, -You can ask for help from the evennia community here: + http://groups.google.com/group/evennia - http://groups.google.com/group/evennia + - Or by visiting our irc channel, + #evennia on the Freenode network + + +* Evennia source auto-docs + + In this folder you can build the developer auto-docs + (a fancy searchable index of the entire source tree). + This makes use of doxygen, a doc generator that parses + the source tree and creates docs on the fly. + + - Install doxygen (v1.7+) + + Doxygen is available for most platforms from + http://www.stack.nl/~dimitri/doxygen/ + or through your package manager in Linux. + + - Run + + > doxygen Doxyfile + + This will create the auto-docs in a folder 'html'. + + - Start your web browser and point it to + + /docs/html/index.html + + - If you prefer a pdf version for printing, use LaTeX by + activating the relevant section in Doxyfile. Run the + doxygen command again as above and a new folder 'latex' + will be created with the latex sources. With the latex + processing system installed, then run + + > make + + in the newly created folder to create the pdf. Be warned + however that the pdf docs are >340 pages long! + + - Doxyfile is lavishly documented and allows for plenty of + configuration to get the docs to look the way you want. + You can also output to other formats suitable for various + developer environments, Windows help files etc. diff --git a/docs/doxygen/Doxyfile b/docs/doxygen/Doxyfile deleted file mode 100644 index 79e72f5eed..0000000000 --- a/docs/doxygen/Doxyfile +++ /dev/null @@ -1,275 +0,0 @@ -# Doxyfile 1.4.7 - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -PROJECT_NAME = Evennia -PROJECT_NUMBER = Pre-Alpha -OUTPUT_DIRECTORY = ./output/ -CREATE_SUBDIRS = NO -OUTPUT_LANGUAGE = English -USE_WINDOWS_ENCODING = NO -BRIEF_MEMBER_DESC = YES -REPEAT_BRIEF = YES -ABBREVIATE_BRIEF = "The $name class" \ - "The $name widget" \ - "The $name file" \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the -ALWAYS_DETAILED_SEC = NO -INLINE_INHERITED_MEMB = NO -FULL_PATH_NAMES = YES -STRIP_FROM_PATH = ./doxygen/ -STRIP_FROM_INC_PATH = -SHORT_NAMES = NO -JAVADOC_AUTOBRIEF = NO -MULTILINE_CPP_IS_BRIEF = NO -DETAILS_AT_TOP = NO -INHERIT_DOCS = YES -SEPARATE_MEMBER_PAGES = NO -TAB_SIZE = 8 -ALIASES = -OPTIMIZE_OUTPUT_FOR_C = NO -OPTIMIZE_OUTPUT_JAVA = YES -BUILTIN_STL_SUPPORT = NO -DISTRIBUTE_GROUP_DOC = NO -SUBGROUPING = YES -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- -EXTRACT_ALL = NO -EXTRACT_PRIVATE = NO -EXTRACT_STATIC = NO -EXTRACT_LOCAL_CLASSES = YES -EXTRACT_LOCAL_METHODS = NO -HIDE_UNDOC_MEMBERS = YES -HIDE_UNDOC_CLASSES = YES -HIDE_FRIEND_COMPOUNDS = NO -HIDE_IN_BODY_DOCS = NO -INTERNAL_DOCS = NO -CASE_SENSE_NAMES = YES -HIDE_SCOPE_NAMES = NO -SHOW_INCLUDE_FILES = YES -INLINE_INFO = YES -SORT_MEMBER_DOCS = YES -SORT_BRIEF_DOCS = NO -SORT_BY_SCOPE_NAME = NO -GENERATE_TODOLIST = YES -GENERATE_TESTLIST = YES -GENERATE_BUGLIST = YES -GENERATE_DEPRECATEDLIST= YES -ENABLED_SECTIONS = -MAX_INITIALIZER_LINES = 30 -SHOW_USED_FILES = YES -SHOW_DIRECTORIES = NO -FILE_VERSION_FILTER = -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- -QUIET = NO -WARNINGS = YES -WARN_IF_UNDOCUMENTED = YES -WARN_IF_DOC_ERROR = YES -WARN_NO_PARAMDOC = NO -WARN_FORMAT = "$file:$line: $text" -WARN_LOGFILE = -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- -INPUT = ../../ -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.d \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.cs \ - *.php \ - *.php3 \ - *.inc \ - *.m \ - *.mm \ - *.dox \ - *.py \ - *.C \ - *.CC \ - *.C++ \ - *.II \ - *.I++ \ - *.H \ - *.HH \ - *.H++ \ - *.CS \ - *.PHP \ - *.PHP3 \ - *.M \ - *.MM \ - *.PY -RECURSIVE = YES -EXCLUDE = -EXCLUDE_SYMLINKS = NO -EXCLUDE_PATTERNS = -EXAMPLE_PATH = -EXAMPLE_PATTERNS = * -EXAMPLE_RECURSIVE = NO -IMAGE_PATH = -INPUT_FILTER = -FILTER_PATTERNS = -FILTER_SOURCE_FILES = NO -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- -SOURCE_BROWSER = YES -INLINE_SOURCES = NO -STRIP_CODE_COMMENTS = YES -REFERENCED_BY_RELATION = YES -REFERENCES_RELATION = YES -REFERENCES_LINK_SOURCE = YES -USE_HTAGS = NO -VERBATIM_HEADERS = YES -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- -ALPHABETICAL_INDEX = NO -COLS_IN_ALPHA_INDEX = 5 -IGNORE_PREFIX = -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- -GENERATE_HTML = YES -HTML_OUTPUT = html -HTML_FILE_EXTENSION = .html -HTML_HEADER = -HTML_FOOTER = -HTML_STYLESHEET = -HTML_ALIGN_MEMBERS = YES -GENERATE_HTMLHELP = NO -CHM_FILE = -HHC_LOCATION = -GENERATE_CHI = NO -BINARY_TOC = NO -TOC_EXPAND = NO -DISABLE_INDEX = NO -ENUM_VALUES_PER_LINE = 4 -GENERATE_TREEVIEW = YES -TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- -ENABLE_PREPROCESSING = YES -MACRO_EXPANSION = NO -EXPAND_ONLY_PREDEF = NO -SEARCH_INCLUDES = YES -INCLUDE_PATH = -INCLUDE_FILE_PATTERNS = -PREDEFINED = -EXPAND_AS_DEFINED = -SKIP_FUNCTION_MACROS = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- -TAGFILES = -GENERATE_TAGFILE = -ALLEXTERNALS = NO -EXTERNAL_GROUPS = YES -PERL_PATH = /usr/bin/perl -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- -CLASS_DIAGRAMS = YES -HIDE_UNDOC_RELATIONS = YES -HAVE_DOT = NO -CLASS_GRAPH = YES -COLLABORATION_GRAPH = YES -GROUP_GRAPHS = YES -UML_LOOK = NO -TEMPLATE_RELATIONS = NO -INCLUDE_GRAPH = YES -INCLUDED_BY_GRAPH = YES -CALL_GRAPH = NO -CALLER_GRAPH = NO -GRAPHICAL_HIERARCHY = YES -DIRECTORY_GRAPH = YES -DOT_IMAGE_FORMAT = png -DOT_PATH = -DOTFILE_DIRS = -MAX_DOT_GRAPH_WIDTH = 1024 -MAX_DOT_GRAPH_HEIGHT = 1024 -MAX_DOT_GRAPH_DEPTH = 1000 -DOT_TRANSPARENT = NO -DOT_MULTI_TARGETS = NO -GENERATE_LEGEND = YES -DOT_CLEANUP = YES -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- -SEARCHENGINE = YES diff --git a/docs/doxygen/README b/docs/doxygen/README deleted file mode 100644 index 3ba97345cf..0000000000 --- a/docs/doxygen/README +++ /dev/null @@ -1,8 +0,0 @@ -To create the developer auto-docs, install doxygen (it's available for most platforms here: - http://www.stack.nl/~dimitri/doxygen/ ), and run - -> doxygen Doxyfile - -in this directory. This will create the auto-docs in ./output/html. To read, point your web browser to -evennia/docs/doxygen/output/html/index.html. If you prefer a pdf / paper hardcopy, install the LaTeX -system and activate the relevant section in Doxyfile. diff --git a/game/evennia.py b/game/evennia.py index 229d82ddd5..6ce7372374 100755 --- a/game/evennia.py +++ b/game/evennia.py @@ -5,49 +5,104 @@ EVENNIA SERVER STARTUP SCRIPT Sets the appropriate environmental variables and launches the server process. Run the script with the -h flag to see usage information. """ -from optparse import OptionParser -from subprocess import Popen, call import os import sys import signal +from optparse import OptionParser +from subprocess import Popen, call # Set the Python path up so we can get to settings.py from here. sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) os.environ['DJANGO_SETTINGS_MODULE'] = 'game.settings' -from django.conf import settings -SERVER_PY_FILE = os.path.join(settings.SRC_DIR, 'server.py') -# Determine what the twistd binary name is. Eventually may want to have a -# setting in settings.py to specify the path to the containing directory. +if not os.path.exists('settings.py'): + # make sure we have a settings.py file. + print " No settings.py file found. Launching manage.py ..." + + import game.manage + + print """ + Now configure Evennia by editing your new settings.py file. + If you haven't already, you should also create/configure the + database with 'python manage.py syncdb' before continuing. + + When you are ready, run this program again to start the server.""" + sys.exit() + +# Get the settings +from django.conf import settings + +# Setup the launch of twisted depending on which operating system we use if os.name == 'nt': - TWISTED_BINARY = 'twistd.bat' + try: + # Test for for win32api import win32api except ImportError: - print "=" * 78 - print """ERROR: Unable to import win32api, which Twisted requires to run. You may - download it from: + print """ + ERROR: Unable to import win32api, which Twisted requires to run. + You may download it from: - http://starship.python.net/crew/mhammond/win32/Downloads.html""" - print "=" * 78 + http://sourceforge.net/projects/pywin32 + or + http://starship.python.net/crew/mhammond/win32/Downloads.html""" sys.exit() + + if not os.path.exists('twistd.bat'): + # Test for executable twisted batch file. This calls the twistd.py + # executable that is usually not found on the path in Windows. + # It's not enough to locate scripts.twistd, what we want is the + # executable script C:\PythonXX/Scripts/twistd.py. Alas we cannot + # hardcode this location since we don't know if user has Python + # in a non-standard location, so we try to figure it out. + from twisted.scripts import twistd + twistd_path = os.path.abspath( + os.path.join(os.path.dirname(twistd.__file__), + os.pardir, os.pardir, os.pardir, os.pardir, + 'scripts', 'twistd.py')) + bat_file = open('twistd.bat','w') + bat_file.write("@%s %%*" % twistd_path) + bat_file.close() + print """ + INFO: Since you are running Windows, a twistd.bat file was created for you. + The twistd.bat is a simple batch file that tries to call the twisted + executable. The system has determined this to be: + + %s + + If you should run into errors you might need to edit twistd.bat to point to + the correct location of the Twisted executable (usually called twistd.py). + + When you are ready, run this program again to retry the server restart.""" % twistd_path + sys.exit() + + TWISTED_BINARY = 'twistd.bat' else: TWISTED_BINARY = 'twistd' +# Setup access of the evennia server itself +SERVER_PY_FILE = os.path.join(settings.SRC_DIR, 'server/server.py') + # Add this to the environmental variable for the 'twistd' command. -tmppath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) +thispath = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) if 'PYTHONPATH' in os.environ: - os.environ['PYTHONPATH'] += (":%s" % tmppath) + os.environ['PYTHONPATH'] += (":%s" % thispath) else: - os.environ['PYTHONPATH'] = tmppath + os.environ['PYTHONPATH'] = thispath def cycle_logfile(): """ - Move the old log file to evennia.log (by default). - """ - if os.path.exists(settings.DEFAULT_LOG_FILE): - os.rename(settings.DEFAULT_LOG_FILE, - settings.DEFAULT_LOG_FILE+'.old') + Move the old log file to evennia.log.old (by default). + + """ + logfile = settings.DEFAULT_LOG_FILE.strip() + logfile_old = logfile + '.old' + if os.path.exists(logfile): + # Cycle the old logfiles to *.old + if os.path.exists(logfile_old): + # E.g. Windows don't support rename-replace + os.remove(logfile_old) + os.rename(logfile, logfile_old) def start_daemon(parser, options, args): """ @@ -59,7 +114,8 @@ def start_daemon(parser, options, args): print "A twistd.pid file exists in the current directory, which suggests that the server is already running." sys.exit() - print 'Starting in daemon mode...' + print '\nStarting Evennia server in daemon mode ...' + print 'Logging to: %s.' % settings.DEFAULT_LOG_FILE # Move the old evennia.log file out of the way. cycle_logfile() @@ -74,7 +130,9 @@ def start_interactive(parser, options, args): Start in interactive mode, which means the process is foregrounded and all logging output is directed to stdout. """ - print 'Starting in interactive mode...' + print '\nStarting Evennia server in interactive mode (stop with keyboard interrupt) ...' + print 'Logging to: Standard output.' + try: call([TWISTED_BINARY, '-n', @@ -88,7 +146,7 @@ def stop_server(parser, options, args): """ if os.name == 'posix': if os.path.exists('twistd.pid'): - print 'Stoping the server...' + print 'Stopping the Evennia server...' f = open('twistd.pid', 'r') pid = f.read() os.kill(int(pid), signal.SIGINT) @@ -96,16 +154,18 @@ def stop_server(parser, options, args): else: print "No twistd.pid file exists, the server doesn't appear to be running." elif os.name == 'nt': - print 'TODO not implented' + print '\n\rStopping cannot be done safely under this operating system.' + print 'Kill server using the task manager or shut it down from inside the game.' else: - print 'Unknown OS delected, can not kill' + print '\n\rUnknown OS detected, can not stop. ' + def main(): """ Beginning of the program logic. """ parser = OptionParser(usage="%prog [options] ", - description="This command starts or stops the Evennia game server.") + description="This command starts or stops the Evennia game server. Note that you have to setup the database by running 'manage.py syncdb' before starting the server for the first time.") parser.add_option('-i', '--interactive', action='store_true', dest='interactive', default=False, help='Start in interactive mode') diff --git a/game/gamesrc/commands/basecommand.py b/game/gamesrc/commands/basecommand.py new file mode 100644 index 0000000000..e558292705 --- /dev/null +++ b/game/gamesrc/commands/basecommand.py @@ -0,0 +1,78 @@ + +""" +This is the parent class for all Commands in Evennia. Inherit from this and +overload the member functions to define your own commands. +See commands/default/muxcommand.py for an example. + +""" + +from src.commands.command import Command as BaseCommand +from src.permissions import permissions +from src.utils import utils + +class Command(BaseCommand): + """ + Note that the class's __doc__ string (this text) is + used by Evennia to create the automatic help entry for + the command, so make sure to document consistently here. + """ + def has_perm(self, srcobj): + """ + This is called by the cmdhandler to determine + if srcobj is allowed to execute this command. This + also determines if the command appears in help etc. + + By default, We use checks of the 'c' type of lock to determine + if the command should be run. + """ + return permissions.has_perm(srcobj, self, 'cmd') + + def parse(self): + """ + This method is called by the cmdhandler once the command name + has been identified. It creates a new set of member variables + that can be later accessed from self.func() (see below) + + The following variables are available for our use when entering this + method (from the command definition, and assigned on the fly by the + cmdhandler): + self.key - the name of this command ('look') + self.aliases - the aliases of this cmd ('l') + self.permissions - permission string for this command + self.help_category - overall category of command + + self.caller - the object calling this command + self.cmdstring - the actual command name used to call this + (this allows you to know which alias was used, + for example) + self.args - the raw input; everything following self.cmdstring. + self.cmdset - the cmdset from which this command was picked. Not + often used (useful for commands like 'help' or to + list all available commands etc) + self.obj - the object on which this command was defined. It is often + the same as self.caller. + """ + pass + + + def func(self): + """ + This is the hook function that actually does all the work. It is called + by the cmdhandler right after self.parser() finishes, and so has access + to all the variables defined therein. + """ + # a simple test command to show the available properties + string = "-" * 50 + string += "\n{w%s{n - Command variables from evennia:\n" % self.key + string += "-" * 50 + string += "\nname of cmd (self.key): {w%s{n\n" % self.key + string += "cmd aliases (self.aliases): {w%s{n\n" % self.aliases + string += "cmd perms (self.permissions): {w%s{n\n" % self.permissions + string += "help category (self.help_category): {w%s{n\n" % self.help_category + string += "object calling (self.caller): {w%s{n\n" % self.caller + string += "object storing cmdset (self.obj): {w%s{n\n" % self.obj + string += "command string given (self.cmdstring): {w%s{n\n" % self.cmdstring + # show cmdset.key instead of cmdset to shorten output + string += utils.fill("current cmdset (self.cmdset): {w%s{n\n" % self.cmdset) + + self.caller.msg(string) diff --git a/game/gamesrc/events/__init__.py b/game/gamesrc/commands/default/__init__.py similarity index 100% rename from game/gamesrc/events/__init__.py rename to game/gamesrc/commands/default/__init__.py diff --git a/game/gamesrc/commands/default/batchprocess.py b/game/gamesrc/commands/default/batchprocess.py new file mode 100644 index 0000000000..8450525073 --- /dev/null +++ b/game/gamesrc/commands/default/batchprocess.py @@ -0,0 +1,689 @@ +""" +Batch processors + +These commands implements the 'batch-command' and 'batch-code' +processors, using the functionality in src.utils.batchprocessors. +They allow for offline world-building. + +Batch-command is the simpler system. This reads a file (*.ev) +containing a list of in-game commands and executes them in sequence as +if they had been entered in the game (including permission checks +etc). + +Example batch-command file: game/gamesrc/commands/examples/example_batch_cmd.ev + +Batch-code is a full-fledged python code interpreter that reads blocks +of python code (*.py) and executes them in sequence. This allows for +much more power than Batch-command, but requires knowing Python and +the Evennia API. It is also a severe security risk and should +therefore always be limited to superusers only. + +Example batch-code file: game/gamesrc/commands/examples/example_batch_code.py + +""" +from traceback import format_exc +from django.conf import settings +from src.utils import batchprocessors +from game.gamesrc.commands.default.muxcommand import MuxCommand +from src.commands.cmdset import CmdSet + +#global defines for storage + +CWHITE = r"%cn%ch%cw" +CRED = r"%cn%ch%cr" +CGREEN = r"%cn%ci%cg" +CYELLOW = r"%cn%ch%cy" +CNORM = r"%cn" + + +#------------------------------------------------------------ +# Helper functions +#------------------------------------------------------------ + +def batch_cmd_exec(caller): + """ + Helper function for executing a single batch-command entry + """ + ptr = caller.ndb.batch_stackptr + stack = caller.ndb.batch_stack + command = stack[ptr] + cmdname = command[:command.find(" ")] + caller.msg("%s %02i/%02i: %s %s%s" % (CGREEN, ptr+1, + len(stack), + cmdname, + CGREEN, " "*(50-len(cmdname)))) + try: + caller.execute_cmd(command) + except Exception: + caller.msg(format_exc()) + return False + return True + + +def batch_code_exec(caller): + """ + Helper function for executing a single batch-code entry + """ + ptr = caller.ndb.batch_stackptr + stack = caller.ndb.batch_stack + debug = caller.ndb.batch_debug + + codedict = stack[ptr] + caller.msg("%s %02i/%02i: %s %s%s" % (CGREEN, ptr + 1, + len(stack), + codedict["firstline"], + CGREEN, " "*(50-len(codedict["firstline"])))) + err = batchprocessors.batch_code_exec(codedict, + extra_environ={"caller":caller}, debug=debug) + if err: + caller.msg(err) + return False + return True + + +def step_pointer(caller, step=1): + """ + Step in stack, returning the item located. + + stackptr - current position in stack + stack - the stack of units + step - how many steps to move from stackptr + """ + ptr = caller.ndb.batch_stackptr + stack = caller.ndb.batch_stack + nstack = len(stack) + if ptr + step <= 0: + caller.msg("Beginning of batch file.") + if ptr + step >= nstack: + caller.msg("End of batch file.") + caller.ndb.batch_stackptr = max(0, min(nstack-1, ptr + step)) + +def show_curr(caller, showall=False): + "Show the current position in stack." + stackptr = caller.ndb.batch_stackptr + stack = caller.ndb.batch_stack + + if stackptr >= len(stack): + caller.ndb.batch_stackptr = len(stack) - 1 + show_curr(caller, showall) + return + entry = stack[stackptr] + if type(entry) == dict: + # we first try the batch-code syntax + firstline = entry['code'][:min(35, len(entry['code'])-1)] + codeall = entry['code'] + else: + # we try the batch-cmd syntax instead + firstline = entry[:min(35, len(entry)-1)] + codeall = entry + string = "%s %02i/%02i: %s %s %s %s%s" % (CGREEN, + stackptr+1, len(stack), + firstline, CGREEN, + "(hh for help)", + " "*(35-len(firstline.strip())), + CNORM) + if showall: + string += "\n%s" % codeall + caller.msg(string) + + +#------------------------------------------------------------ +# main access commands +#------------------------------------------------------------ + +class CmdBatchCommands(MuxCommand): + """ + Build from batch-command file + + Usage: + @batchcommands[/interactive] + + Switch: + interactive - this mode will offer more control when + executing the batch file, like stepping, + skipping, reloading etc. + + Runs batches of commands from a batch-cmd text file (*.ev). + + """ + key = "@batchcommands" + aliases = ["@batchcommand", "@batchcmd"] + permissions = "cmd:batchcommands" + help_category = "Building" + + def func(self): + "Starts the processor." + + caller = self.caller + + args = self.args + if not args: + caller.msg("Usage: @batchcommands[/interactive] ") + return + python_path = self.args + + #parse indata file + + commands = batchprocessors.parse_batchcommand_file(python_path) + if not commands: + string = "'%s' not found.\nYou have to supply the python path " + string += "of the file relative to \nyour batch-file directory (%s)." + caller.msg(string % (python_path, settings.BASE_BATCHPROCESS_PATH)) + return + switches = self.switches + + # Store work data in cache + caller.ndb.batch_stack = commands + caller.ndb.batch_stackptr = 0 + caller.ndb.batch_pythonpath = python_path + caller.ndb.batch_batchmode = "batch_commands" + caller.cmdset.add(BatchSafeCmdSet) + + if 'inter' in switches or 'interactive' in switches: + # Allow more control over how batch file is executed + + # Set interactive state directly + caller.cmdset.add(BatchInteractiveCmdSet) + + caller.msg("\nBatch-command processor - Interactive mode for %s ..." % python_path) + show_curr(caller) + else: + caller.msg("Running Batch-command processor - Automatic mode for %s ..." % python_path) + # add the 'safety' cmdset in case the batch processing adds cmdsets to us + for inum in range(len(commands)): + # loop through the batch file + if not batch_cmd_exec(caller): + return + step_pointer(caller, 1) + # clean out the safety cmdset and clean out all other temporary attrs. + caller.cmdset.delete(BatchSafeCmdSet) + del caller.ndb.batch_stack + del caller.ndb.batch_stackptr + del caller.ndb.batch_pythonpath + del caller.ndb.batch_batchmode + string = " Batchfile '%s' applied." % python_path + caller.msg("%s%s%s" % (CGREEN, string, " "*(60-len(string)))) + +class CmdBatchCode(MuxCommand): + """ + Build from batch-code file + + Usage: + @batchcode[/interactive] + + Switch: + interactive - this mode will offer more control when + executing the batch file, like stepping, + skipping, reloading etc. + debug - auto-delete all objects that has been marked as + deletable in the script file (see example files for + syntax). This is useful so as to to not leave multiple + object copies behind when testing out the script. + + Runs batches of commands from a batch-code text file (*.py). + + """ + key = "@batchcode" + aliases = ["@batchcodes"] + permissions = "cmd:batchcodes" + help_category = "Building" + + def func(self): + "Starts the processor." + + caller = self.caller + + args = self.args + if not args: + caller.msg("Usage: @batchcode[/interactive/debug] ") + return + python_path = self.args + + #parse indata file + codes = batchprocessors.parse_batchcode_file(python_path) + if not codes: + string = "'%s' not found.\nYou have to supply the python path " + string += "of the file relative to \nyour batch-file directory (%s)." + caller.msg(string % (python_path, settings.BASE_BATCHPROCESS_PATH)) + return + switches = self.switches + + debug = False + if 'debug' in switches: + debug = True + + # Store work data in cache + caller.ndb.batch_stack = codes + caller.ndb.batch_stackptr = 0 + caller.ndb.batch_pythonpath = python_path + caller.ndb.batch_batchmode = "batch_code" + caller.ndb.batch_debug = debug + caller.cmdset.add(BatchSafeCmdSet) + + if 'inter' in switches or 'interactive'in switches: + # Allow more control over how batch file is executed + + # Set interactive state directly + caller.cmdset.add(BatchInteractiveCmdSet) + + caller.msg("\nBatch-code processor - Interactive mode for %s ..." % python_path) + show_curr(caller) + else: + caller.msg("Running Batch-code processor - Automatic mode for %s ..." % python_path) + # add the 'safety' cmdset in case the batch processing adds cmdsets to us + for inum in range(len(codes)): + # loop through the batch file + if not batch_code_exec(caller): + return + step_pointer(caller, 1) + # clean out the safety cmdset and clean out all other temporary attrs. + caller.cmdset.delete(BatchSafeCmdSet) + del caller.ndb.batch_stack + del caller.ndb.batch_stackptr + del caller.ndb.batch_pythonpath + del caller.ndb.batch_batchmode + string = " Batchfile '%s' applied." % python_path + caller.msg("%s%s%s" % (CGREEN, string, " "*(60-len(string)))) + +#------------------------------------------------------------ +# State-commands for the interactive batch processor modes +# (these are the same for both processors) +#------------------------------------------------------------ + +class CmdStateAbort(MuxCommand): + """ + @abort + + Exits back the default cmdset, regardless of what state + we are currently in. + """ + key = "@abort" + help_category = "BatchProcess" + + def func(self): + "Exit back to default." + caller = self.caller + del caller.ndb.batch_stack + del caller.ndb.batch_stackptr + del caller.ndb.batch_pythonpath + del caller.ndb.batch_batchmode + # clear everything but the default cmdset. + caller.cmdset.delete(BatchSafeCmdSet) + caller.cmdset.clear() + caller.msg("Exit: Cleared back to default state.") + +class CmdStateLL(MuxCommand): + """ + ll + + Look at the full source for the current + command definition. + """ + key = "ll" + help_category = "BatchProcess" + + def func(self): + show_curr(self.caller, showall=True) + +class CmdStatePP(MuxCommand): + """ + pp + + Process the currently shown command definition. + """ + key = "pp" + help_category = "BatchProcess" + + def func(self): + """ + This checks which type of processor we are running. + """ + caller = self.caller + if caller.ndb.batch_batchmode == "batch_code": + batch_code_exec(caller) + else: + batch_cmd_exec(caller) + + +class CmdStateRR(MuxCommand): + """ + rr + + Reload the batch file, keeping the current + position in it. + """ + key = "rr" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + if caller.ndb.batch_batchmode == "batch_code": + batchprocessors.read_batchcommand_file(caller.ndb.batch_pythonpath) + else: + batchprocessors.read_batchcode_file(caller.ndb.batch_pythonpath) + caller.msg("\nFile reloaded. Staying on same command.\n") + show_curr(caller) + +class CmdStateRRR(MuxCommand): + """ + rrr + + Reload the batch file, starting over + from the beginning. + """ + key = "rrr" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + if caller.ndb.batch_batchmode == "batch_code": + batchprocessors.read_batchcommand_file(caller.ndb.batch_pythonpath) + else: + batchprocessors.read_batchcode_file(caller.ndb.batch_pythonpath) + caller.ndb.batch_stackptr = 0 + caller.msg("\nFile reloaded. Restarting from top.\n") + show_curr(caller) + +class CmdStateNN(MuxCommand): + """ + nn + + Go to next command. No commands are executed. + """ + key = "nn" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + arg = self.args + if arg and arg.isdigit(): + step = int(self.args) + else: + step = 1 + step_pointer(caller, step) + show_curr(caller) + +class CmdStateNL(MuxCommand): + """ + nl + + Go to next command, viewing its full source. + No commands are executed. + """ + key = "nl" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + arg = self.args + if arg and arg.isdigit(): + step = int(self.args) + else: + step = 1 + step_pointer(caller, step) + show_curr(caller, showall=True) + +class CmdStateBB(MuxCommand): + """ + bb + + Backwards to previous command. No commands + are executed. + """ + key = "bb" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + arg = self.args + if arg and arg.isdigit(): + step = -int(self.args) + else: + step = -1 + step_pointer(caller, step) + show_curr(caller) + +class CmdStateBL(MuxCommand): + """ + bl + + Backwards to previous command, viewing its full + source. No commands are executed. + """ + key = "bl" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + arg = self.args + if arg and arg.isdigit(): + step = -int(self.args) + else: + step = -1 + step_pointer(caller, step) + show_curr(caller, showall=True) + +class CmdStateSS(MuxCommand): + """ + ss [steps] + + Process current command, then step to the next + one. If steps is given, + process this many commands. + """ + key = "ss" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + arg = self.args + if arg and arg.isdigit(): + step = int(self.args) + else: + step = 1 + + for istep in range(step): + if caller.ndb.batch_batchmode == "batch_code": + batch_code_exec(caller) + else: + batch_cmd_exec(caller) + step_pointer(caller, 1) + show_curr(caller) + +class CmdStateSL(MuxCommand): + """ + sl [steps] + + Process current command, then step to the next + one, viewing its full source. If steps is given, + process this many commands. + """ + key = "sl" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + arg = self.args + if arg and arg.isdigit(): + step = int(self.args) + else: + step = 1 + + for istep in range(step): + if caller.ndb.batch_batchmode == "batch_code": + batch_code_exec(caller) + else: + batch_cmd_exec(caller) + step_pointer(caller, 1) + show_curr(caller) + +class CmdStateCC(MuxCommand): + """ + cc + + Continue to process all remaining + commands. + """ + key = "cc" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + nstack = len(caller.ndb.batch_stack) + ptr = caller.ndb.batch_stackptr + step = nstack - ptr + + for istep in range(step): + if caller.ndb.batch_batchmode == "batch_code": + batch_code_exec(caller) + else: + batch_cmd_exec(caller) + step_pointer(caller, 1) + show_curr(caller) + + del caller.ndb.batch_stack + del caller.ndb.batch_stackptr + del caller.ndb.batch_pythonpath + del caller.ndb.batch_batchmode + caller.msg("Finished processing batch file.") + +class CmdStateJJ(MuxCommand): + """ + j + + Jump to specific command number + """ + key = "j" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + arg = self.args + if arg and arg.isdigit(): + number = int(self.args)-1 + else: + caller.msg("You must give a number index.") + return + ptr = caller.ndb.batch_stackptr + step = number - ptr + step_pointer(caller, step) + show_curr(caller) + +class CmdStateJL(MuxCommand): + """ + jl + + Jump to specific command number and view its full source. + """ + key = "jl" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + arg = self.args + if arg and arg.isdigit(): + number = int(self.args)-1 + else: + caller.msg("You must give a number index.") + return + ptr = caller.ndb.batch_stackptr + step = number - ptr + step_pointer(caller, step) + show_curr(caller, showall=True) + +class CmdStateQQ(MuxCommand): + """ + qq + + Quit the batchprocessor. + """ + key = "qq" + help_category = "BatchProcess" + + def func(self): + caller = self.caller + del caller.ndb.batch_stack + del caller.ndb.batch_stackptr + del caller.ndb.batch_pythonpath + del caller.ndb.batch_batchmode + caller.cmdset.delete(BatchSafeCmdSet) + caller.cmdset.delete(BatchInteractiveCmdSet) + caller.scripts.validate() # this will clear interactive mode. + caller.msg("Aborted interactive batch mode.") + +class CmdStateHH(MuxCommand): + "Help command" + + key = "help" + aliases = "hh" + help_category = "BatchProcess" + + def func(self): + string = """ + Interactive batch processing commands: + nn [steps] - next command (no processing) + nl [steps] - next & look + bb [steps] - back to previous command (no processing) + bl [steps] - back & look + jj - jump to command nr N (no processing) + jl - jump & look + pp - process currently shown command (no step) + ss [steps] - process & step + sl [steps] - process & step & look + ll - look at full definition of current command + rr - reload batch file (stay on current) + rrr - reload batch file (start from first) + hh - this help list + + cc - continue processing to end, then quit. + qq - quit (abort all remaining commands) + """ + self.caller.msg(string) + + + +#------------------------------------------------------------ +# +# Defining the cmdsets for the interactive batchprocessor +# mode (same for both processors) +# +#------------------------------------------------------------ + +class BatchSafeCmdSet(CmdSet): + """ + The base cmdset for the batch processor. + This sets a 'safe' @abort command that will + always be available to get out of everything. + """ + key = "Batch_default" + priority = 104 # override other cmdsets. + + def at_cmdset_creation(self): + "Init the cmdset" + self.add(CmdStateAbort()) + +class BatchInteractiveCmdSet(CmdSet): + """ + The cmdset for the interactive batch processor mode. + """ + key = "Batch_interactive" + priority = 104 + + def at_cmdset_creation(self): + "init the cmdset" + self.add(CmdStateAbort()) + self.add(CmdStateLL()) + self.add(CmdStatePP()) + self.add(CmdStateRR()) + self.add(CmdStateRRR()) + self.add(CmdStateNN()) + self.add(CmdStateNL()) + self.add(CmdStateBB()) + self.add(CmdStateBL()) + self.add(CmdStateSS()) + self.add(CmdStateSL()) + self.add(CmdStateCC()) + self.add(CmdStateJJ()) + self.add(CmdStateJL()) + self.add(CmdStateQQ()) + self.add(CmdStateHH()) diff --git a/game/gamesrc/commands/default/cmdset_default.py b/game/gamesrc/commands/default/cmdset_default.py new file mode 100644 index 0000000000..103aedb704 --- /dev/null +++ b/game/gamesrc/commands/default/cmdset_default.py @@ -0,0 +1,98 @@ +""" +This module ties together all the commands of the default command set. +""" +from src.commands.cmdset import CmdSet +from game.gamesrc.commands.default import general, help, privileged +from game.gamesrc.commands.default import tests, comms, objmanip +from game.gamesrc.commands.default import info, batchprocess + +class DefaultCmdSet(CmdSet): + """ + Implements the default command set. + """ + key = "DefaultMUX" + + def at_cmdset_creation(self): + "Populates the cmdset" + + # The general commands + self.add(general.CmdLook()) + self.add(general.CmdPassword()) + self.add(general.CmdWall()) + self.add(general.CmdInventory()) + self.add(general.CmdQuit()) + self.add(general.CmdPose()) + self.add(general.CmdNick()) + self.add(general.CmdEmit()) + self.add(general.CmdGet()) + self.add(general.CmdDrop()) + self.add(general.CmdWho()) + self.add(general.CmdSay()) + self.add(general.CmdGroup()) + + # The help system + self.add(help.CmdHelp()) + self.add(help.CmdSetHelp()) + + # Privileged commands + self.add(privileged.CmdReload()) + self.add(privileged.CmdPy()) + self.add(privileged.CmdListScripts()) + self.add(privileged.CmdListCmdSets()) + self.add(privileged.CmdListObjects()) + self.add(privileged.CmdBoot()) + self.add(privileged.CmdDelPlayer()) + self.add(privileged.CmdNewPassword()) + self.add(privileged.CmdHome()) + self.add(privileged.CmdService()) + self.add(privileged.CmdShutdown()) + self.add(privileged.CmdPerm()) + + # Info commands + self.add(info.CmdVersion()) + self.add(info.CmdTime()) + self.add(info.CmdList()) + self.add(info.CmdPs()) + self.add(info.CmdStats()) + + # Object manipulation commands + self.add(objmanip.CmdTeleport()) + self.add(objmanip.CmdSetObjAlias()) + self.add(objmanip.CmdWipe()) + self.add(objmanip.CmdSetAttribute()) + self.add(objmanip.CmdName()) + self.add(objmanip.CmdDesc()) + #self.add(objmanip.CmdCpAttr()) #TODO - need testing/debugging + #self.add(objmanip.CmdMvAttr()) #TODO - need testing/debugging + self.add(objmanip.CmdFind()) + self.add(objmanip.CmdCopy()) #TODO - need testing/debugging + self.add(objmanip.CmdOpen()) + self.add(objmanip.CmdLink()) + self.add(objmanip.CmdUnLink()) + self.add(objmanip.CmdCreate()) + self.add(objmanip.CmdDig()) + self.add(objmanip.CmdDestroy()) + self.add(objmanip.CmdExamine()) + self.add(objmanip.CmdTypeclass()) + self.add(objmanip.CmdDebug()) + + # Comm commands + self.add(comms.CmdAddCom()) + self.add(comms.CmdDelCom()) + self.add(comms.CmdComlist()) + self.add(comms.CmdClist()) + self.add(comms.CmdCdestroy()) + self.add(comms.CmdChannelCreate()) + self.add(comms.CmdCdesc()) + self.add(comms.CmdPage()) + + # Batchprocessor commands + self.add(batchprocess.CmdBatchCommands()) + self.add(batchprocess.CmdBatchCode()) + + # Testing commands + self.add(tests.CmdTest()) + self.add(tests.CmdTestState()) + self.add(tests.CmdTestPerms()) + self.add(tests.TestCom()) + diff --git a/game/gamesrc/commands/default/cmdset_unloggedin.py b/game/gamesrc/commands/default/cmdset_unloggedin.py new file mode 100644 index 0000000000..2cf714a671 --- /dev/null +++ b/game/gamesrc/commands/default/cmdset_unloggedin.py @@ -0,0 +1,21 @@ +""" +This module describes the unlogged state of the default game. +The setting STATE_UNLOGGED should be set to the python path +of the state instance in this module. +""" +from src.commands.cmdset import CmdSet +from game.gamesrc.commands.default import unloggedin + +class UnloggedinCmdSet(CmdSet): + """ + Sets up the unlogged cmdset. + """ + key = "Unloggedin" + + def at_cmdset_creation(self): + "Populate the cmdset" + self.add(unloggedin.CmdConnect()) + self.add(unloggedin.CmdCreate()) + self.add(unloggedin.CmdQuit()) + self.add(unloggedin.CmdUnconnectedLook()) + self.add(unloggedin.CmdUnconnectedHelp()) diff --git a/game/gamesrc/commands/default/comms.py b/game/gamesrc/commands/default/comms.py new file mode 100644 index 0000000000..a4d4abdcde --- /dev/null +++ b/game/gamesrc/commands/default/comms.py @@ -0,0 +1,792 @@ +""" +Comsys command module. +""" + +from src.comms.models import Channel, Msg, ChannelConnection +from game.gamesrc.commands.default.muxcommand import MuxCommand +from src.utils import create +from src.permissions.permissions import has_perm + + +def find_channel(caller, channelname): + """ + Helper function for searching for a single channel with + some error handling. + """ + channels = Channel.objects.channel_search(channelname) + if not channels: + caller.msg("Channel '%s' not found." % channelname) + return None + elif len(channels) > 1: + matches = ", ".join(["%s(%s)" % (chan.key, chan.id) for chan in channels]) + caller.msg("Multiple channels match (be more specific): \n%s" % matches) + return None + return channels[0] + +class CmdAddCom(MuxCommand): + """ + addcom - join a channel with alias + + Usage: + addcom [alias=] + + Allows adding an alias for a channel to make is easier and + faster to use. Subsequent calls of this command can + be used to add multiple aliases. + """ + + key = "addcom" + help_category = "Comms" + + def func(self): + "Implement the command" + + caller = self.caller + args = self.args + player = caller.player + + if not args: + caller.msg("Usage: addcom [alias =] channelname.") + return + + if self.rhs: + # rhs holds the channelname + channelname = self.rhs + alias = self.lhs + else: + channelname = self.args + alias = None + + channel = find_channel(caller, channelname) + if not channel: + # we use the custom search method to handle errors. + return + + # check permissions + if not has_perm(player, channel, 'chan_listen'): + caller.msg("You are not allowed to listen to this channel.") + return + + string = "" + if not channel.has_connection(player): + # we want to connect as well. + if not channel.connect_to(player): + # if this would have returned True, the player is connected + caller.msg("You are not allowed to join this channel.") + return + else: + string += "You now listen to the channel %s. " % channel.key + + if alias: + # create a nick and add it to the caller. + nicks = caller.nicks + nicks[alias.strip()] = channel.key + caller.nicks = nicks # nicks auto-save to database. + string += "You can now refer to the channel %s with the alias '%s'." + caller.msg(string % (channel.key, alias)) + else: + string += "No alias added." + caller.msg(string) + + +class CmdDelCom(MuxCommand): + """ + delcom - remove a channel alias + + Usage: + delcom + + Removes the specified alias to a channel. If this is the last alias, + the user is effectively removed from the channel. + """ + + key = "delcom" + help_category = "Comms" + + def func(self): + "Implementing the command. " + + caller = self.caller + + if not self.args: + caller.msg("Usage: delcom ") + return + + #find all the nicks defining this channel + searchnick = self.args.lower() + nicks = caller.nicks + channicks = [nick for nick in nicks.keys() + if nick == searchnick] + if not channicks: + caller.msg("You don't have any such alias defined.") + return + #if there are possible nick matches, look if they match a channel. + channel = None + for nick in channicks: + channel = find_channel(caller, nicks[nick]) + if channel: + break + if not channel: + caller.msg("No channel with alias '%s' found." % searchnick) + return + player = caller.player + + if not channel.has_connection(player): + caller.msg("You are not on that channel.") + else: + if len(channicks) > 1: + del nicks[searchnick] + caller.msg("Your alias '%s' for channel %s was cleared." % (searchnick, + channel.key)) + else: + del nicks[searchnick] + channel.disconnect_from(player) + caller.msg("You stop listening to channel '%s'." % channel.key) + # have to save nicks back too + caller.nicks = nicks + +class CmdComlist(MuxCommand): + """ + comlist - list channel memberships + + Usage: + comlist + + Lists the channels a user is subscribed to. + """ + + key = "comlist" + aliases = ["channels"] + help_category = "Comms" + + def func(self): + "Implement the command" + + + caller = self.caller + player = caller.player + + connections = ChannelConnection.objects.get_all_player_connections(player) + + if not connections: + caller.msg("You don't listen to any channels.") + return + + # get aliases: + nicks = caller.nicks + channicks = {} + for connection in connections: + channame = connection.channel.key.lower() + channicks[channame] = ", ".join([nick for nick in nicks + if nicks[nick].lower() == channame]) + + string = "Your subscribed channels (use @clist for full chan list)\n" + string += "** Alias Channel Status\n" + + for connection in connections: + string += " %s%s %-15.14s%-22.15s\n" % ('-', '-', + channicks[connection.channel.key.lower()], + connection.channel.key) + string = string[:-1] + caller.msg(string) + + +# def cmd_allcom(command): +# """ +# allcom - operate on all channels + +# Usage: +# allcom [on | off | who | clear] + +# Allows the user to universally turn off or on all channels they are on, +# as well as perform a 'who' for all channels they are on. Clear deletes +# all channels. + +# Without argument, works like comlist. +# """ + +# caller = self.caller +# arg = self.args +# if not arg: +# cmd_comlist(command) +# caller.msg("(allcom arguments: 'on', 'off', 'who' and 'clear'.)") +# return +# arg = arg.strip() +# if arg == 'clear': +# cmd_clearcom(command) +# return + +# #get names and alias of all subscribed channels +# chandict = comsys.plr_get_cdict(self.session) +# aliaslist = chandict.keys() +# aliaslist.sort() +# if arg == "on": +# for alias in aliaslist: +# comsys.plr_chan_on(self.session, alias) +# elif arg == "off": +# for alias in aliaslist: +# comsys.plr_chan_off(self.session, alias) +# elif arg == "who": +# s = "" +# if not aliaslist: +# s += " (No channels) " +# for alias in aliaslist: +# s += "-- %s (alias: %s)\n" % (chandict[alias][0],alias) +# sess_list = comsys.get_cwho_list(chandict[alias][0]) +# objlist = [sess.get_pobject() for sess in sess_list] +# plist = [p.get_name(show_dbref=caller.sees_dbrefs()) +# for p in filter(lambda o: o.is_player(), objlist)] +# olist = [o.get_name(show_dbref=caller.sees_dbrefs()) +# for o in filter(lambda o: not o.is_player(), objlist)] +# plist.sort() +# olist.sort() +# if plist: +# s += " Players:\n " +# for pname in plist: +# s += "%s, " % pname +# s = s[:-2] + "\n" +# if olist: +# s += " Objects:\n " +# for oname in olist: +# s += "%s, " % oname +# s = s[:-2] + "\n" +# s = s[:-1] +# caller.msg(s) +# GLOBAL_CMD_TABLE.add_self("allcom", cmd_allcom, help_category="Comms") + +## def cmd_clearcom(self): +## """ +## clearcom - removes all channels + +## Usage: +## clearcom + +## Effectively runs delcom on all channels the user is on. It will remove +## their aliases, remove them from the channel, and clear any titles they +## have set. +## """ +## caller = self.caller +## #get aall subscribed channel memberships +## memberships = caller.channel_membership_set.all() + +## if not memberships: +## s = "No channels to delete. " +## else: +## s = "Deleting all channels in your subscriptions ...\n" +## for membership in memberships: +## chan_name = membership.channel.get_name() +## s += "You have left %s.\n" % chan_name +## comsys.plr_del_channel(caller, membership.user_alias) +## comsys.send_cmessage(chan_name, "%s has left the channel." % caller.get_name(show_dbref=False)) +## s = s[:-1] +## caller.msg(s) +## GLOBAL_CMD_TABLE.add_self("clearcom", cmd_clearcom) + + +class CmdClist(MuxCommand): + """ + @clist + + Usage: + @clist + list channels + all channels + + Lists all available channels in the game. + """ + key = "@clist" + aliases = ["channellist", "all channels"] + help_category = "Comms" + + def func(self): + "Implement function" + + caller = self.caller + + string = "All channels (use comlist to see your subscriptions)\n" + + string += "** Channel Perms Description\n" + channels = Channel.objects.get_all_channels() + if not channels: + string += "(No channels) " + for chan in channels: + if has_perm(caller, chan, 'can_listen'): + string += " %s%s %-15.14s%-22.15s%s\n" % \ + ('-', + '-', + chan.key, + chan.permissions, + #chan.get_owner().get_name(show_dbref=False), + chan.desc) + string = string[:-1] + #s += "** End of Channel List **" + caller.msg(string) + +class CmdCdestroy(MuxCommand): + """ + @cdestroy + + Usage: + @cdestroy + + Destroys a channel that you control. + """ + + key = "@cdestroy" + help_category = "Comms" + + def func(self): + "Destroy objects cleanly." + caller = self.caller + + if not self.args: + caller.msg("Usage: @cdestroy ") + return + channel = find_channel(caller, self.args) + if not channel: + caller.msg("Could not find channel %s." % self.args) + return + if not has_perm(caller, channel, 'chan_admin', default_deny=True): + caller.msg("You are not allowed to do that.") + return + + message = "Channel %s is being destroyed. Make sure to change your aliases." % channel.key + msgobj = create.create_message(caller, message, channel) + channel.msg(msgobj) + channel.delete() + caller.msg("Channel %s was destroyed." % channel) + + +## def cmd_cset(self): +## """ +## @cset + +## Sets various flags on a channel. +## """ +## # TODO: Implement cmd_cset +## pass + +## def cmd_ccharge(self): +## """ +## @ccharge + +## Sets the cost to transmit over a channel. Default is free. +## """ +## # TODO: Implement cmd_ccharge +## pass + +## def cmd_cboot(self): +## """ +## @cboot + +## Usage: +## @cboot[/quiet] = + +## Kicks a player or object from a channel you control. +## """ +## caller = self.caller +## args = self.args +## switches = self.self_switches + +## if not args or not "=" in args: +## caller.msg("Usage: @cboot[/quiet] = ") +## return +## cname, objname = args.split("=",1) +## cname, objname = cname.strip(), objname.strip() +## if not cname or not objname: +## caller.msg("You must supply both channel and object.") +## return +## try: +## channel = CommChannel.objects.get(name__iexact=cname) +## except CommChannel.DoesNotExist: +## caller.msg("Could not find channel %s." % cname) +## return + +## #do we have power over this channel? +## if not channel.controlled_by(caller) or caller.has_perm("channels.channel_admin"): +## caller.msg("You don't have that power in channel '%s'." % cname) +## return + +## #mux specification requires an * before player objects. +## player_boot = False +## if objname[0] == '*': +## player_boot = True +## objname = objname[1:] +## bootobj = Object.objects.player_name_search(objname) +## if not bootobj: +## caller.msg("Object '%s' not found." % objname) +## return +## if bootobj.is_player() and not player_boot: +## caller.msg("To boot players you need to start their name with an '*'. ") +## return + +## #check so that this object really is on the channel in the first place +## membership = bootobj.channel_membership_set.filter(channel__name__iexact=cname) +## if not membership: +## caller.msg("'%s' is not on channel '%s'." % (objname,cname)) +## return + +## #announce to channel +## if not 'quiet' in switches: +## comsys.send_cmessage(cname, "%s boots %s from channel." % \ +## (caller.get_name(show_dbref=False), objname)) + +## #all is set, boot the object by removing all its aliases from the channel. +## for mship in membership: +## comsys.plr_del_channel(bootobj, mship.user_alias) + +## GLOBAL_CMD_TABLE.add_self("@cboot", cmd_cboot, help_category="Comms") + + +## def cmd_cemit(self): +## """ +## @cemit - send a message to channel + +## Usage: +## @cemit = +## @cemit/noheader = +## @cemit/sendername = + +## Allows the user to send a message over a channel as long as +## they own or control it. It does not show the user's name unless they +## provide the /sendername switch. + +## [[channel_selfs]] + +## Useful channel selfs +## (see their help pages for detailed help and options) + +## - Listing channels +## clist - show all channels available to you +## comlist - show channels you listen to + +## - Joining/parting channels +## addcom - add your alias for a channel +## delcom - remove alias for channel +## (leave channel if no more aliases) +## allcom - view, on/off or remove all your channels +## clearcom - removes all channels + +## - Other +## who - list who's online +## off - silence channel temporarily +## on - turn silenced channel back on +## """ +## caller = self.caller + +## if not self.args: +## caller.msg("@cemit[/switches] = ") +## return + +## eq_args = self.args.split('=', 1) + +## if len(eq_args) != 2: +## caller.msg("You must provide a channel name and a message to emit.") +## return + +## cname = eq_args[0].strip() +## cmessage = eq_args[1].strip() +## final_cmessage = cmessage +## if len(cname) == 0: +## caller.msg("You must provide a channel name to emit to.") +## return +## if len(cmessage) == 0: +## caller.msg("You must provide a message to emit.") +## return + +## name_matches = comsys.cname_search(cname, exact=True) +## if name_matches: +## cname_parsed = name_matches[0].get_name() +## else: +## caller.msg("Could not find channel %s." % (cname,)) +## return + +## # If this is False, don't show the channel header before +## # the message. For example: [Public] Woohoo! +## show_channel_header = True +## if "noheader" in self.self_switches: +## if not caller.has_perm("objects.emit_commchannel"): +## caller.msg(defines_global.NOPERMS_MSG) +## return +## final_cmessage = cmessage +## show_channel_header = False +## else: +## if "sendername" in self.self_switches: +## if not comsys.plr_has_channel(self.session, cname_parsed, +## return_muted=False): +## caller.msg("You must be on %s to do that." % (cname_parsed,)) +## return +## final_cmessage = "%s: %s" % (caller.get_name(show_dbref=False), +## cmessage) +## else: +## if not caller.has_perm("objects.emit_commchannel"): +## caller.msg(defines_global.NOPERMS_MSG) +## return +## final_cmessage = cmessage + +## if not "quiet" in self.self_switches: +## caller.msg("Sent - %s" % (name_matches[0],)) +## comsys.send_cmessage(cname_parsed, final_cmessage, +## show_header=show_channel_header) + +## #pipe to external channels (IRC, IMC) eventually mapped to this channel +## comsys.send_cexternal(cname_parsed, cmessage, caller=caller) + +## GLOBAL_CMD_TABLE.add_self("@cemit", cmd_cemit,priv_tuple=("channels.emit_commchannel",), +## help_category="Comms") + +## def cmd_cwho(self): +## """ +## @cwho + +## Usage: +## @cwho channel[/all] + +## Displays the name, status and object type for a given channel. +## Adding /all after the channel name will list disconnected players +## as well. +## """ +## session = self.session +## caller = self.caller + +## if not self.args: +## cmd_clist(self) +## caller.msg("Usage: @cwho [/all]") +## return + +## channel_name = self.args + +## if channel_name.strip() == '': +## caller.msg("You must specify a channel name.") +## return + +## name_matches = comsys.cname_search(channel_name, exact=True) + +## if name_matches: +## # Check to make sure the user has permission to use @cwho. +## is_channel_admin = caller.has_perm("objects.channel_admin") +## is_controlled_by_plr = name_matches[0].controlled_by(caller) + +## if is_controlled_by_plr or is_channel_admin: +## comsys.msg_cwho(caller, channel_name) +## else: +## caller.msg("Permission denied.") +## return +## else: +## caller.msg("No channel with that name was found.") +## return +## GLOBAL_CMD_TABLE.add_self("@cwho", cmd_cwho, help_category="Comms") + +class CmdChannelCreate(MuxCommand): + """ + @ccreate + channelcreate + Usage: + @ccreate [;alias;alias...] = description + + Creates a new channel owned by you. + """ + + key = "@ccreate" + aliases = "channelcreate" + permissions = "cmd:ccreate" + help_category = "Comms" + + def func(self): + "Implement the command" + + caller = self.caller + + if not self.args: + caller.msg("Usage @ccreate [;alias;alias..] = description") + return + + description = "" + + if self.rhs: + description = self.rhs + lhs = self.lhs + channame = lhs + aliases = None + if ';' in lhs: + channame, aliases = [part.strip().lower() + for part in lhs.split(';', 1) if part.strip()] + aliases = [alias.strip().lower() + for alias in aliases.split(';') if alias.strip()] + channel = Channel.objects.channel_search(channame) + if channel: + caller.msg("A channel with that name already exists.") + return + # Create and set the channel up + permissions = "chan_send:%s,chan_listen:%s,chan_admin:has_id(%s)" % \ + ("Players","Players",caller.id) + new_chan = create.create_channel(channame, aliases, description, permissions) + new_chan.connect_to(caller) + caller.msg("Created channel %s and connected to it." % new_chan.key) + + +## def cmd_cchown(self): +## """ +## @cchown + +## Usage: +## @cchown = + +## Changes the owner of a channel. +## """ +## caller = self.caller +## args = self.args +## if not args or "=" not in args: +## caller.msg("Usage: @cchown = ") +## return +## cname, pname = args.split("=",1) +## cname, pname = cname.strip(), pname.strip() +## #locate channel +## try: +## channel = CommChannel.objects.get(name__iexact=cname) +## except CommChannel.DoesNotExist: +## caller.msg("Channel '%s' not found." % cname) +## return +## #check so we have ownership to give away. +## if not channel.controlled_by(caller) and not caller.has_perm("channels.channel_admin"): +## caller.msg("You don't control this channel.") +## return +## #find the new owner +## new_owner = Object.objects.player_name_search(pname) +## if not new_owner: +## caller.msg("New owner '%s' not found." % pname) +## return +## old_owner = channel.get_owner() +## old_pname = old_owner.get_name(show_dbref=False) +## if old_owner == new_owner: +## caller.msg("Owner unchanged.") +## return +## #all is set, change owner +## channel.set_owner(new_owner) +## caller.msg("Owner of %s changed from %s to %s." % (cname, old_pname, pname)) +## new_owner.msg("%s transfered ownership of channel '%s' to you." % (old_pname, cname)) +## GLOBAL_CMD_TABLE.add_self("@cchown", cmd_cchown, help_category="Comms") + + +class CmdCdesc(MuxCommand): + """ + @cdesc - set channel description + + Usage: + @cdesc = + + Changes the description of the channel as shown in + channel lists. + """ + + key = "@cdesc" + permissions = "cmd:cdesc" + help_category = "Comms" + + def func(self): + "Implement command" + + caller = self.caller + + if not self.rhs: + caller.msg("Usage: @cdesc = ") + return + channel = find_channel(caller, self.lhs) + if not channel: + caller.msg("Channel '%s' not found." % self.lhs) + return + #check permissions + if not has_perm(caller, channel, 'channel_admin'): + caller.msg("You cant admin this channel.") + return + # set the description + channel.desc = self.rhs + channel.save() + caller.msg("Description of channel '%s' set to '%s'." % (channel.key, self.rhs)) + + +class CmdPage(MuxCommand): + """ + page - send private message + + Usage: + page[/switches] [,,... = ] + tell '' + + Switch: + list - show your last 10 tells/pages. + + Send a message to target user (if online). If no + argument is given, you will instead see who was the last + person you paged to. + """ + + key = "page" + aliases = ['tell'] + permissions = "cmd:tell" + help_category = "Comms" + + def func(self): + + "Implement function using the Msg methods" + + caller = self.caller + player = caller.player + + + # get the last message we sent + messages = list(Msg.objects.get_messages_by_sender(player)) + pages = [msg for msg in messages + if msg.receivers] + if pages: + lastpage = pages[-1] + + if 'list' in self.switches: + if len(messages) > 10: + lastpages = messages[-10:] + else: + lastpages = messages + lastpages = "\n ".join(["%s to %s: %s" % (mess.date_sent, mess.receivers.all(), + mess.message) + for mess in messages]) + caller.msg("Your latest pages:\n %s" % lastpages ) + return + + if not self.args or not self.rhs: + if pages: + string = "You last paged %s." % (", ".join([obj.name + for obj in lastpage.receivers.all()])) + caller.msg(string) + return + else: + string = "You haven't paged anyone yet." + caller.msg(string) + return + + + # Build a list of targets + + if not self.lhs: + # If there are no targets, then set the targets + # to the last person they paged. + receivers = lastpage.receivers + else: + receivers = self.lhslist + + recobjs = [] + for receiver in receivers: + obj = caller.search("*%s" % (receiver.lstrip('*')), global_search=True) + if not obj: + return + recobjs.append(obj) + + header = "{wPlayer{n {c%s{n {wpages:{n" % caller.key + message = self.rhs + # create the persistent message object + msg = create.create_message(caller, message, + receivers=recobjs) + # tell the players they got a message. + for obj in recobjs: + obj.msg("%s %s" % (header, message)) + caller.msg("You paged %s with '%s'." % (recobjs, message)) + diff --git a/game/gamesrc/commands/default/general.py b/game/gamesrc/commands/default/general.py new file mode 100644 index 0000000000..2bc4c59986 --- /dev/null +++ b/game/gamesrc/commands/default/general.py @@ -0,0 +1,703 @@ +""" +Generic command module. Pretty much every command should go here for +now. +""" +import time +from src.server import sessionhandler +from src.permissions.models import PermissionGroup +from src.permissions.permissions import has_perm, has_perm_string +from src.objects.models import HANDLE_SEARCH_ERRORS +from src.utils import utils + +from game.gamesrc.commands.default.muxcommand import MuxCommand + +class CmdLook(MuxCommand): + """ + look + + Usage: + look + look + + Observes your location or objects in your vicinity. + """ + key = "look" + aliases = ["l"] + + def func(self): + """ + Handle the looking. + """ + caller = self.caller + args = self.args # caller.msg(inp) + + if args: + # Use search to handle duplicate/nonexistant results. + looking_at_obj = caller.search(args) + if not looking_at_obj: + return + else: + looking_at_obj = caller.location + if not looking_at_obj: + caller.msg("Location: None") + return + # get object's appearance + caller.msg(looking_at_obj.return_appearance(caller)) + # the object's at_desc() method. + looking_at_obj.at_desc(looker=caller) + +class CmdPassword(MuxCommand): + """ + @password - set your password + + Usage: + @password = + + Changes your password. Make sure to pick a safe one. + """ + key = "@password" + + def func(self): + "hook function." + + caller = self.caller + + if not self.rhs: + caller.msg("Usage: @password = ") + return + oldpass = self.lhslist[0] # this is already stripped by parse() + newpass = self.rhslist[0] # '' + try: + uaccount = caller.user + except AttributeError: + caller.msg("This is only applicable for players.") + return + if not uaccount.check_password(oldpass): + caller.msg("The specified old password isn't correct.") + elif len(newpass) < 3: + caller.msg("Passwords must be at least three characters long.") + else: + uaccount.set_password(newpass) + uaccount.save() + caller.msg("Password changed.") + +class CmdNick(MuxCommand): + """ + Define a personal alias/nick + + Usage: + alias[/switches] = [] + nick '' + + Switches: + obj - alias an object + player - alias a player + clearall - clear all your aliases + list - show all defined aliases + + If no switch is given, a command/channel alias is created, used + to replace strings before sending the command. + + Creates a personal nick for some in-game object or + string. When you enter that string, it will be replaced + with the alternate string. The switches dictate in what + situations the nick is checked and substituted. If string + is None, the alias (if it exists) will be cleared. + Obs - no objects are actually changed with this command, + if you want to change the inherent aliases of an object, + use the @alias command instead. + """ + key = "alias" + aliases = ["nick"] + + def func(self): + "Create the nickname" + + caller = self.caller + switches = self.switches + + if 'list' in switches: + string = "{wAliases:{n \n" + string = string + "\n\r".join(["%s = %s" % (alias, replace) + for alias, replace + in caller.nicks.items()]) + caller.msg(string) + return + if 'clearall' in switches: + del caller.nicks + caller.msg("Cleared all aliases.") + return + + if not self.args or not self.lhs: + caller.msg("Usage: alias[/switches] string = [alias]") + return + + alias = self.lhs + rstring = self.rhs + err = None + if rstring == alias: + err = "No point in setting alias same as the string to replace..." + caller.msg(err) + return + elif 'obj' in switches: + # object alias, for adressing objects + # (including user-controlled ones) + err = caller.set_nick("_obj:%s" % alias, rstring) + atype = "Object" + elif 'player' in switches: + # player alias, used for messaging + err = caller.set_nick("_player:%s" % alias, rstring) + atype = "Player " + else: + # a command/channel alias - these are replaced if + # they begin a command string. + caller.msg(rstring) + caller.msg("going in: %s %s" % (alias, rstring)) + err = caller.set_nick(alias, rstring) + atype = "Command/channel " + if err: + if rstring: + err = "%salias %s changed from '%s' to '%s'." % (atype, alias, err, rstring) + else: + err = "Cleared %salias '%s'(='%s')." % (atype, alias, err) + else: + err = "Set %salias '%s' = '%s'" % (atype, alias, rstring) + caller.msg(err.capitalize()) + +class CmdEmit(MuxCommand): + """ + @emit + + Usage: + @emit[/switches] [, , ... =] + @remit [, , ... =] + @pemit [, , ... =] + + Switches: + room : limit emits to rooms only + players : limit emits to players only + contents : send to the contents of matched objects too + + Emits a message to the selected objects or to + your immediate surroundings. If the object is a room, + send to its contents. @remit and @pemit are just + limited forms of @emit, for sending to rooms and + to players respectively. + """ + key = "@emit" + aliases = ["@pemit", "@remit"] + permissions = "cmd:emit" + help_category = "Comms" + + def func(self): + "Implement the command" + + caller = self.caller + args = self.args + + if not args: + string = "Usage: " + string += "\n@emit[/switches] [, , ... =] " + string += "\n@remit [, , ... =] " + string += "\n@pemit [, , ... =] " + caller.msg(string) + return + + rooms_only = 'rooms' in self.switches + players_only = 'players' in self.switches + send_to_contents = 'contents' in self.switches + + # we check which command was used to force the switches + if self.cmdstring == '@remit': + rooms_only = True + elif self.cmdstring == '@pemit': + players_only = True + + if not self.rhs: + message = self.args + objnames = [caller.location.key] + else: + message = self.rhs + objnames = self.lhslist + + # send to all objects + for objname in objnames: + obj = caller.search(objname, global_search=True) + if not obj: + return + if rooms_only and not obj.location == None: + caller.msg("%s is not a room. Ignored." % objname) + continue + if players_only and not obj.has_player: + caller.msg("%s has no active player. Ignored." % objname) + continue + if has_perm(caller, obj, 'send_to'): + obj.msg(message) + if send_to_contents: + for content in obj.contents: + content.msg(message) + caller.msg("Emitted to %s and its contents." % objname) + else: + caller.msg("Emitted to %s." % objname) + else: + caller.msg("You are not allowed to send to %s." % objname) + +class CmdWall(MuxCommand): + """ + @wall + + Usage: + @wall + + Announces a message to all connected players. + """ + key = "@wall" + permissions = "cmd:wall" + + def func(self): + "Implements command" + if not self.args: + self.caller.msg("Usage: @wall ") + return + message = "%s shouts \"%s\"" % (self.caller.name, self.args) + sessionhandler.announce_all(message) + + +class CmdInventory(MuxCommand): + """ + inventory + + Usage: + inventory + inv + + Shows a player's inventory. + """ + key = "inventory" + aliases = ["inv", "i"] + + def func(self): + "hook function" + string = "You are carrying:" + for item in self.caller.contents: + string += "\n %s" % item.name + self.caller.msg(string) + + ## money = int(caller.MONEY) + ## if money == 1: + ## money_name = ConfigValue.objects.get_configvalue("MONEY_NAME_SINGULAR") + ## else: + ## money_name = ConfigValue.objects.get_configvalue("MONEY_NAME_PLURAL") + ##caller.msg("You have %d %s." % (money, money_name)) + + +class CmdGet(MuxCommand): + """ + get + + Usage: + get + + Picks up an object from your location and puts it in + your inventory. + """ + key = "get" + aliases = "grab" + + def func(self): + "implements the command." + + caller = self.caller + + if not self.args: + caller.msg("Get what?") + return + obj = caller.search(self.args) + if not obj: + return + if caller == obj: + caller.msg("You can't get yourself.") + return + if obj.player or obj.db._destination: + # don't allow picking up player objects, nor exits. + caller.msg("You can't get that.") + return + if not has_perm(caller, obj, 'get'): + #TODO - have the object store fail messages? + caller.msg("You can't get that.") + return + + obj.move_to(caller, quiet=True) + caller.msg("You pick up %s." % obj.name) + caller.location.msg_contents("%s picks up %s." % + (caller.name, + obj.name), + exclude=caller) + # calling hook method + obj.at_get(caller) + + +class CmdDrop(MuxCommand): + """ + drop + + Usage: + drop + + Lets you drop an object from your inventory into the + location you are currently in. + """ + + key = "drop" + + def func(self): + "Implement command" + + caller = self.caller + if not self.args: + caller.msg("Drop what?") + return + + results = caller.search(self.args, ignore_errors=True) + # we process the results ourselves since we want to sift out only + # those in our inventory. + results = [obj for obj in results if obj in caller.contents] + # now we send it into the handler. + obj = HANDLE_SEARCH_ERRORS(caller, self.args, results, False) + if not obj: + return + + obj.move_to(caller.location, quiet=True) + caller.msg("You drop %s." % (obj.name,)) + caller.location.msg_contents("%s drops %s." % + (caller.name, obj.name), + exclude=caller) + # Call the object script's at_drop() method. + obj.at_drop(caller) + + +class CmdQuit(MuxCommand): + """ + quit + + Usage: + quit + + Gracefully disconnect from the game. + """ + key = "quit" + + def func(self): + "hook function" + sessions = self.caller.sessions + for session in sessions: + session.msg("Quitting. Hope to see you soon again.") + session.handle_close() + +class CmdWho(MuxCommand): + """ + who + + Usage: + who + doing + + Shows who is currently online. Doing is an + alias that limits info also for those with + all permissions. + """ + + key = "who" + aliases = "doing" + + def func(self): + """ + Get all connected players by polling session. + """ + + caller = self.caller + session_list = sessionhandler.get_sessions() + + if self.cmdstring == "doing": + show_session_data = False + else: + show_session_data = has_perm_string(caller, "Immortals,Wizards") + + if show_session_data: + retval = "Player Name On For Idle Room Cmds Host\n\r" + else: + retval = "Player Name On For Idle\n\r" + + for session in session_list: + if not session.logged_in: + continue + delta_cmd = time.time() - session.cmd_last_visible + delta_conn = time.time() - session.conn_time + plr_pobject = session.get_character() + + if show_session_data: + retval += '%-31s%9s %4s%-3s#%-6d%5d%3s%-25s\r\n' % \ + (plr_pobject.name[:25], \ + # On-time + utils.time_format(delta_conn,0), \ + # Idle time + utils.time_format(delta_cmd,1), \ + # Flags + '', \ + # Location + plr_pobject.location.id, \ + session.cmd_total, \ + # More flags? + '', \ + session.address[0]) + else: + retval += '%-31s%9s %4s%-3s\r\n' % \ + (plr_pobject.name[:25], \ + # On-time + utils.time_format(delta_conn,0), \ + # Idle time + utils.time_format(delta_cmd,1), \ + # Flags + '') + retval += '%d Players logged in.' % (len(session_list),) + + caller.msg(retval) + +class CmdSay(MuxCommand): + """ + say + + Usage: + say + + Talk to those in your current location. + """ + + key = "say" + + def func(self): + "Run the say command" + + caller = self.caller + + if not self.args: + caller.msg("Say what?") + return + + speech = self.args + + # calling the speech hook on the location + speech = caller.location.at_say(caller, speech) + + # Feedback for the object doing the talking. + caller.msg("You say, '%s'" % speech) + + # Build the string to emit to neighbors. + emit_string = "{c%s{n says, '%s'" % (caller.name, + speech) + caller.location.msg_contents(emit_string, + exclude=caller) + +## def cmd_fsay(command): +## """ +## @fsay - make an object say something + +## Usage: +## @fsay = + +## Make an object talk to its current location. +## """ +## caller = command.caller +## args = command.command_argument + +## if not args or not "=" in args: +## caller.msg("Usage: @fsay = ") +## return +## target, speech = [arg.strip() for arg in args.split("=",1)] + +## # find object +## if target in ['here']: +## results = [caller.location] +## elif target in ['me','my']: +## results = [caller] +## else: +## results = Object.objects.global_object_name_search(target) +## if not results: +## caller.msg("No matches found for '%s'." % target) +## return +## if len(results) > 1: +## string = "There are multiple matches. Please use #dbref to be more specific." +## for result in results: +## string += "\n %s" % results.name +## caller.msg(string) +## return +## target = results[0] + +## # permission check +## if not caller.controls_other(target): +## caller.msg("Cannot pose %s (you don's control it)" % target.name) +## return + +## # Feedback for the object doing the talking. +## caller.msg("%s says, '%s%s'" % (target.name, +## speech, +## ANSITable.ansi['normal'])) + +## # Build the string to emit to neighbors. +## emit_string = "%s says, '%s'" % (target.name, +## speech) +## target.location.msg_contents(emit_string, +## exclude=caller) +## GLOBAL_CMD_TABLE.add_command("@fsay", cmd_fsay) + +class CmdPose(MuxCommand): + """ + pose - strike a pose + + Usage: + pose + pose's + + Example: + pose is standing by the wall, smiling. + -> others will see: + Tom is standing by the wall, smiling. + + Describe an script being taken. The pose text will + automatically begin with your name. + """ + key = "pose" + aliases = [":", "emote"] + + def parse(self): + """ + Custom parse the cases where the emote + starts with some special letter, such + as 's, at which we don't want to separate + the caller's name and the emote with a + space. + """ + args = self.args + if args and not args[0] in ["'", ",", ":"]: + args = " %s" % args + self.args = args + + def func(self): + "Hook function" + if not self.args: + msg = "Do what?" + else: + msg = "%s%s" % (self.caller.name, self.args) + self.caller.location.msg_contents(msg) + +## def cmd_fpose(command): +## """ +## @fpose - force an object to pose + +## Usage: +## @fpose[/switches] = + +## Switches: +## nospace : put no text between the object's name +## and the start of the pose. + +## Describe an action being taken as performed by obj. +## The pose text will automatically begin with the name +## of the object. +## """ +## caller = command.caller +## args = command.command_argument + +## if not args or not "=" in args: +## caller.msg("Usage: @fpose = ") +## return +## target, pose_string = [arg.strip() for arg in args.split("=",1)] +## # find object +## if target in ['here']: +## results = [caller.location] +## elif target in ['me','my']: +## results = [caller] +## else: +## results = Object.objects.global_object_name_search(target) +## if not results: +## caller.msg("No matches found for '%s'." % target) +## return +## if len(results) > 1: +## string = "There are multiple matches. Please use #dbref to be more specific." +## for result in results: +## string += "\n %s" % results.name +## caller.msg(string) +## return +## target = results[0] + +## # permission check +## if not caller.controls_other(target): +## caller.msg("Cannot pose %s (you don's control it)" % target.name) +## return + +## if "nospace" in command.command_switches: +## # Output without a space between the player name and the emote. +## sent_msg = "%s%s" % (target.name, +## pose_string) +## else: +## # No switches, default. +## sent_msg = "%s %s" % (target.name, +## pose_string) + +## caller.location.msg_contents(sent_msg) +## GLOBAL_CMD_TABLE.add_command("@fpose", cmd_fpose) + + +class CmdGroup(MuxCommand): + """ + group - show your groups + + Usage: + group + + This command shows you which user permission groups + you are a member of, if any. + """ + key = "group" + aliases = "groups" + + def func(self): + "Load the permission groups" + + caller = self.caller + + string = "" + if caller.player and caller.player.is_superuser: + string += "\n This is a SUPERUSER account! Group membership does not matter." + else: + # get permissions and determine if they are groups + perms = [perm.strip().lower() for perm in caller.player.permissions + if perm.strip()] + for group in [group for group in PermissionGroup.objects.all() + if group.key.lower() in perms]: + string += "\n %s\t\t%s" % (group.key, [str(perm) for perm in group.group_permissions]) + if string: + string = "\nYour (%s's) group memberships: %s" % (caller.name, string) + else: + string = "\nYou are not not a member of any groups." + caller.msg(string) + +## def cmd_apropos(command): +## """ +## apropos - show rough help matches + +## Usage: +## apropos +## or +## suggest + +## This presents a list of topics very loosely matching your +## search text. Use this command when you are searching for +## help on a certain concept but don't know any exact +## command names. You can also use the normal help command +## with the /apropos switch to get the same functionality. +## """ +## arg = command.command_argument +## command.caller.execute_cmd("help/apropos %s" % arg) +## GLOBAL_CMD_TABLE.add_command("apropos", cmd_apropos) +## GLOBAL_CMD_TABLE.add_command("suggest", cmd_apropos) diff --git a/game/gamesrc/commands/default/help.py b/game/gamesrc/commands/default/help.py new file mode 100644 index 0000000000..b50760d561 --- /dev/null +++ b/game/gamesrc/commands/default/help.py @@ -0,0 +1,281 @@ +""" +The help command. The basic idea is that help texts for commands +are best written by those that write the commands - the admins. So +command-help is all auto-loaded and searched from the current command +set. The normal, database-tied help system is used for collaborative +creation of other help topics such as RP help or game-world aides. +""" + +from src.utils.utils import fill, dedent +from src.commands.command import Command +from src.help.models import HelpEntry +from src.permissions.permissions import has_perm +from src.utils import create +from game.gamesrc.commands.default.muxcommand import MuxCommand + +LIST_ARGS = ["list", "all"] + +def format_help_entry(title, help_text, aliases=None, + suggested=None): + "This visually formats the help entry." + string = "-"*70 + "\n" + if title: + string += "Help topic for {w%s{n" % (title.capitalize()) + if aliases: + string += " (aliases: %s)" % (", ".join(aliases)) + if help_text: + string += "\n%s" % dedent(help_text.rstrip()) + if suggested: + string += "\nSuggested:\n" + string += fill(", ".join(suggested)) + string.strip() + string += "\n" + "-"*70 + return string + +def format_help_list(hdict_cmds, hdict_db): + "Output a category-ordered list" + string = "\n\r" + "-"*70 + "\n\r {gCommand help entries{n\n" + "-"*70 + for category in sorted(hdict_cmds.keys()): + string += "\n {w%s{n:\n" % \ + (str(category).capitalize()) + string += fill(", ".join(sorted(hdict_cmds[category]))) + if hdict_db: + string += "\n\r\n\r" + "-"*70 + "\n\r {gOther help entries{n\n" + '-'*70 + for category in sorted(hdict_db.keys()): + string += "\n\r {w%s{n:\n" % (str(category).capitalize()) + string += fill(", ".join(sorted([str(topic) for topic in hdict_db[category]]))) + return string + +class CmdHelp(Command): + """ + The main help command + + Usage: + help + help list + help all + + This will search for help on commands and other + topics related to the game. + """ + key = "help" + # this is a special cmdhandler flag that makes the cmdhandler also pack + # the current cmdset with the call to self.func(). + return_cmdset = True + + def parse(self): + """ + inp is a string containing the command or topic match. + """ + self.args = self.args.strip().lower() + + def func(self): + """ + Run the dynamic help entry creator. + """ + query, cmdset = self.args, self.cmdset + caller = self.caller + + if not query: + query = "all" + + # Listing help entries + + if query in LIST_ARGS: + # we want to list all available help entries + hdict_cmd = {} + for cmd in (cmd for cmd in cmdset if has_perm(caller, cmd, 'cmd') + if not cmd.key.startswith('__') + and not (hasattr(cmd, 'is_exit') and cmd.is_exit)): + if hdict_cmd.has_key(cmd.help_category): + hdict_cmd[cmd.help_category].append(cmd.key) + else: + hdict_cmd[cmd.help_category] = [cmd.key] + hdict_db = {} + for topic in (topic for topic in HelpEntry.objects.get_all_topics() + if has_perm(caller, topic, 'view')): + if hdict_db.has_key(topic.help_category): + hdict_db[topic.help_category].append(topic.key) + else: + hdict_db[topic.help_category] = [topic.key] + help_entry = format_help_list(hdict_cmd, hdict_db) + caller.msg(help_entry) + return + + # Look for a particular help entry + + # Cmd auto-help dynamic entries + cmdmatches = [cmd for cmd in cmdset + if query in cmd and has_perm(caller, cmd, 'cmd')] + if len(cmdmatches) > 1: + # multiple matches. Try to limit it down to exact match + exactmatches = [cmd for cmd in cmdmatches if cmd == query] + if exactmatches: + cmdmatches = exactmatches + + # Help-database static entries + dbmatches = \ + [topic for topic in + HelpEntry.objects.find_topicmatch(query, exact=False) + if has_perm(caller, topic, 'view')] + if len(dbmatches) > 1: + exactmatches = \ + [topic for topic in + HelpEntry.objects.find_topicmatch(query, exact=True) + if has_perm(caller, topic, 'view')] + if exactmatches: + dbmatches = exactmatches + + # Handle result + if (not cmdmatches) and (not dbmatches): + # no normal match. Check if this is a category match instead + categ_cmdmatches = [cmd for cmd in cmdset + if query == cmd.help_category and has_perm(caller, cmd, 'cmd')] + categ_dbmatches = \ + [topic for topic in + HelpEntry.objects.find_topics_with_category(query) + if has_perm(caller, topic, 'view')] + if categ_cmdmatches or categ_dbmatches: + help_entry = format_help_list({query:categ_cmdmatches}, + {query:categ_dbmatches}) + else: + help_entry = "No help entry found for '%s'" % query + + elif len(cmdmatches) == 1: + # we matched against a command name or alias. Show its help entry. + suggested = [] + if dbmatches: + suggested = [entry.key for entry in dbmatches] + cmd = cmdmatches[0] + help_entry = format_help_entry(cmd.key, cmd.__doc__, + aliases=cmd.aliases, + suggested=suggested) + elif len(dbmatches) == 1: + # matched against a database entry + entry = dbmatches[0] + help_entry = format_help_entry(entry.key, entry.entrytext) + else: + # multiple matches of either type + cmdalts = [cmd.key for cmd in cmdmatches] + dbalts = [entry.key for entry in dbmatches] + helptext = "Multiple help entries match your search ..." + help_entry = format_help_entry("", helptext, None, cmdalts + dbalts) + + # send result to user + caller.msg(help_entry) + +class CmdSetHelp(MuxCommand): + """ + @sethelp - edit the help database + + Usage: + @sethelp[/switches] [,category[,permission,permission,...]] = + + Switches: + add - add or replace a new topic with text. + append - add text to the end of topic with a newline between. + merge - As append, but don't add a newline between the old + text and the appended text. + delete - remove help topic. + force - (used with add) create help topic also if the topic + already exists. + + Examples: + @sethelp/add throw = This throws something at ... + @sethelp/append pickpocketing,Thievery,is_thief, is_staff) = This steals ... + @sethelp/append pickpocketing, ,is_thief, is_staff) = This steals ... + + """ + key = "@sethelp" + permissions = "cmd:sethelp" + help_category = "Building" + + def func(self): + "Implement the function" + + caller = self.caller + switches = self.switches + lhslist = self.lhslist + rhs = self.rhs + + if not self.rhs: + caller.msg("Usage: @sethelp/[add|del|append|merge] [,category[,permission,..] = ]") + return + + topicstr = "" + category = "" + permissions = "" + try: + topicstr = lhslist[0] + category = lhslist[1] + permissions = ",".join(lhslist[2:]) + except Exception: + pass + if not topicstr: + caller.msg("You have to define a topic!") + return + string = "" + print topicstr, category, permissions + + if switches and switches[0] in ('append', 'app','merge'): + # add text to the end of a help topic + # find the topic to append to + old_entry = None + try: + old_entry = HelpEntry.objects.get(key=topicstr) + except Exception: + pass + if not old_entry: + string = "Could not find topic '%s'. You must give an exact name." % topicstr + else: + entrytext = old_entry.entrytext + if switches[0] == 'merge': + old_entry.entrytext = "%s %s" % (entrytext, self.rhs) + string = "Added the new text right after the old one (merge)." + else: + old_entry.entrytext = "%s\n\n%s" % (entrytext, self.rhs) + string = "Added the new text as a new paragraph after the old one (append)" + old_entry.save() + + elif switches and switches[0] in ('delete','del'): + #delete a help entry + old_entry = None + try: + old_entry = HelpEntry.objects.get(key=topicstr) + except Exception: + pass + if not old_entry: + string = "Could not find topic. You must give an exact name." + else: + old_entry.delete() + string = "Deleted the help entry '%s'." % topicstr + + else: + # add a new help entry. + force_create = ('for' in switches) or ('force' in switches) + old_entry = None + try: + old_entry = HelpEntry.objects.get(key=topicstr) + except Exception: + pass + if old_entry: + if force_create: + old_entry.key = topicstr + old_entry.entrytext = self.rhs + old_entry.help_category = category + old_entry.permissions = permissions + old_entry.save() + string = "Overwrote the old topic '%s' with a new one." % topicstr + else: + string = "Topic '%s' already exists. Use /force to overwrite it." % topicstr + else: + # no old entry. Create a new one. + new_entry = create.create_help_entry(topicstr, + rhs, category, permissions) + if new_entry: + string = "Topic '%s' was successfully created." % topicstr + else: + string = "Error when creating topic '%s'! Maybe it already exists?" % topicstr + + # give feedback + caller.msg(string) diff --git a/game/gamesrc/commands/default/info.py b/game/gamesrc/commands/default/info.py new file mode 100644 index 0000000000..7702fafd3c --- /dev/null +++ b/game/gamesrc/commands/default/info.py @@ -0,0 +1,204 @@ +""" +Commands that are generally staff-oriented that show information regarding +the server instance. +""" +import os +import django, twisted +from django.contrib.auth.models import User +from src.objects.models import ObjectDB +from src.scripts.models import ScriptDB +from src.utils import utils +from src.utils import gametime +from game.gamesrc.commands.default.muxcommand import MuxCommand +from src.commands import cmdsethandler + +class CmdVersion(MuxCommand): + """ + @version - game version + + Usage: + @version + + Display the game version info. + """ + + key = "@version" + help_category = "System" + + def func(self): + "Show the version" + version = utils.get_evennia_version() + string = "-"*50 +"\n\r" + string += " Evennia %s\n\r" % version + string += " (Django %s, " % (django.get_version()) + string += " Twisted %s)\n\r" % (twisted.version.short()) + string += "-"*50 + self.caller.msg(string) + +class CmdTime(MuxCommand): + """ + @time + + Usage: + @time + + Server local time. + """ + key = "@time" + aliases = "@uptime" + permissions = "cmd:time" + help_category = "System" + + def func(self): + "Show times." + + string2 = "\nCurrent server uptime:\n %i yrs, %i months, " + string2 += "%i weeks, %i days, %i hours, %i minutes and %i secs." + string2 = string2 % gametime.uptime(format=True) + + string3 = "\nTotal running time (gametime x %g):" % (1.0/gametime.TIMEFACTOR) + string3 += "\n %i yrs, %i months, %i weeks, %i days, " + string3 += "%i hours, %i minutes and %i secs." + string3 = string3 % gametime.runtime(format=True) + #print "runtime:", gametime.runtime() + string1 = "\nTotal game time (realtime x %g):" % (gametime.TIMEFACTOR) + string1 += "\n %i yrs, %i months, %i weeks, %i days, " + string1 += "%i hours, %i minutes and %i secs." + string1 = string1 % (gametime.gametime(format=True)) + #print "gametime:", gametime.gametime() + string4 = "" + if not utils.host_os_is('nt'): + # os.getloadavg() is not available on Windows. + loadavg = os.getloadavg() + string4 = "\n Server load (1 min) : %g%%" % (100 * loadavg[0]) + string = "%s%s%s%s" % (string2, string3, string1, string4) + self.caller.msg(string) + +class CmdList(MuxCommand): + """ + @list - list info + + Usage: + @list commands | process + + Shows game related information depending + on which argument is given. + """ + key = "@list" + permissions = "cmd:list" + help_category = "System" + + def func(self): + "Show list." + + caller = self.caller + if not self.args: + caller.msg("Usage: @list commands|process") + return + + string = "" + if self.arglist[0] in ["com", "command", "commands"]: + string = "Command sets currently in cache:" + for cmdset in cmdsethandler.get_cached_cmdsets(): + string += "\n %s" % cmdset + elif self.arglist[0] in ["proc","process"]: + if utils.host_os_is('nt'): + string = "Feature not available on Windows." + else: + import resource + loadavg = os.getloadavg() + string = "\n Server load (1 min) : %.2f " % loadavg[0] + psize = resource.getpagesize() + rusage = resource.getrusage(resource.RUSAGE_SELF) + string += "\n Process ID: %10d" % os.getpid() + string += "\n Bytes per page: %10d" % psize + string += "\n Time used: %10d, user: %g" % (rusage[0], rusage[1]) + string += "\n Integral mem: %10d shared, %10d, private, %10d stack " % \ + (rusage[3], rusage[4], rusage[5]) + string += "\n Max res mem: %10d pages %10d bytes" % \ + (rusage[2],rusage[2] * psize) + string += "\n Page faults: %10d hard %10d soft %10d swapouts " % \ + (rusage[7], rusage[6], rusage[8]) + string += "\n Disk I/O: %10d reads %10d writes " % \ + (rusage[9], rusage[10]) + string += "\n Network I/O: %10d in %10d out " % \ + (rusage[12], rusage[11]) + string += "\n Context swi: %10d vol %10d forced %10d sigs " % \ + (rusage[14], rusage[15], rusage[13]) + else: + string = "Not a valid option." + # send info + caller.msg(string) + +class CmdPs(MuxCommand): + """ + @ps - list processes + Usage + @ps + + Shows the process/event table. + """ + key = "@ps" + permissions = "cmd:ps" + help_category = "System" + + def func(self): + "run the function." + + string = "Processes Scheduled:\n-- PID [time/interval] [repeats] description --" + all_scripts = ScriptDB.objects.get_all_scripts() + repeat_scripts = [script for script in all_scripts if script.interval] + nrepeat_scripts = [script for script in all_scripts if script not in repeat_scripts] + + string = "\nNon-timed scripts:" + for script in nrepeat_scripts: + string += "\n %i %s %s" % (script.id, script.key, script.desc) + + string += "\n\nTimed scripts:" + for script in repeat_scripts: + repeats = "[inf] " + if script.repeats: + repeats = "[%i] " % script.repeats + string += "\n %i %s [%d/%d] %s%s" % (script.id, script.key, + script.time_until_next_repeat(), + script.interval, + repeats, + script.desc) + string += "\nTotals: %d interval scripts" % len(all_scripts) + self.caller.msg(string) + +class CmdStats(MuxCommand): + """ + @stats - show object stats + + Usage: + @stats + + Shows stats about the database. + """ + + key = "@stats" + aliases = "@db" + permissions = "cmd:stats" + help_category = "System" + + def func(self): + "Show all stats" + + # get counts for all typeclasses + stats_dict = ObjectDB.objects.object_totals() + # get all objects + stats_allobj = ObjectDB.objects.all().count() + # get all rooms + stats_room = ObjectDB.objects.filter(obj_location=None).count() + # get all players + stats_users = User.objects.all().count() + + string = "-"*60 + string += "\n Number of users: %i" % stats_users + string += "\n Total number of objects: %i" % stats_allobj + string += "\n Number of rooms (location==None): %i" % stats_room + string += "\n Object type statistics:" + for path, num in stats_dict.items(): + string += "\n %i - %s" % (num, path) + self.caller.msg(string) diff --git a/game/gamesrc/commands/default/muxcommand.py b/game/gamesrc/commands/default/muxcommand.py new file mode 100644 index 0000000000..6209fec197 --- /dev/null +++ b/game/gamesrc/commands/default/muxcommand.py @@ -0,0 +1,147 @@ +""" +The command template for the default MUX-style command set +""" + +from src.utils import utils +from game.gamesrc.commands.basecommand import Command + +class MuxCommand(Command): + """ + This sets up the basis for a MUX command. The idea + is that most other Mux-related commands should just + inherit from this and don't have to implement much + parsing of their own unless they do something particularly + advanced. + + Note that the class's __doc__ string (this text) is + used by Evennia to create the automatic help entry for + the command, so make sure to document consistently here. + """ + def has_perm(self, srcobj): + """ + This is called by the cmdhandler to determine + if srcobj is allowed to execute this command. + We just show it here for completeness - we + are satisfied using the default check in Command. + """ + return super(MuxCommand, self).has_perm(srcobj) + + def parse(self): + """ + This method is called by the cmdhandler once the command name + has been identified. It creates a new set of member variables + that can be later accessed from self.func() (see below) + + The following variables are available for our use when entering this + method (from the command definition, and assigned on the fly by the + cmdhandler): + self.key - the name of this command ('look') + self.aliases - the aliases of this cmd ('l') + self.permissions - permission string for this command + self.help_category - overall category of command + + self.caller - the object calling this command + self.cmdstring - the actual command name used to call this + (this allows you to know which alias was used, + for example) + self.args - the raw input; everything following self.cmdstring. + self.cmdset - the cmdset from which this command was picked. Not + often used (useful for commands like 'help' or to + list all available commands etc) + self.obj - the object on which this command was defined. It is often + the same as self.caller. + + A MUX command has the following possible syntax: + + name[ with several words][/switch[/switch..]] arg1[,arg2,...] [[=|,] arg[,..]] + + The 'name[ with several words]' part is already dealt with by the + cmdhandler at this point, and stored in self.cmdname (we don't use + it here). The rest of the command is stored in self.args, which can start + with the switch indicator /. + + This parser breaks self.args into its constituents and stores them in the + following variables: + self.switches = [list of /switches (without the /)] + self.raw = This is the raw argument input, including switches + self.args = This is re-defined to be everything *except* the switches + self.lhs = Everything to the left of = (lhs:'left-hand side'). If + no = is found, this is identical to self.args. + self.rhs: Everything to the right of = (rhs:'right-hand side'). + If no '=' is found, this is None. + self.lhslist - [self.lhs split into a list by comma] + self.rhslist - [list of self.rhs split into a list by comma] + self.arglist = [list of space-separated args (stripped, including '=' if it exists)] + + All args and list members are stripped of excess whitespace around the + strings, but case is preserved. + """ + raw = self.args + args = raw.strip() + + # split out switches + switches = [] + if args and len(args) >1 and args[0] == "/": + # we have a switch, or a set of switches. These end with a space. + #print "'%s'" % args + switches = args[1:].split(None, 1) + if len(switches) > 1: + switches, args = switches + switches = switches.split('/') + else: + args = "" + switches = switches[0].split('/') + arglist = [arg.strip() for arg in args.split(None)] + + # check for arg1, arg2, ... = argA, argB, ... constructs + lhs, rhs = args, None + lhslist, rhslist = [arg.strip() for arg in args.split(',')], [] + if args and '=' in args: + lhs, rhs = [arg.strip() for arg in args.split('=', 1)] + lhslist = [arg.strip() for arg in lhs.split(',')] + rhslist = [arg.strip() for arg in rhs.split(',')] + + # save to object properties: + self.raw = raw + self.switches = switches + self.args = args.strip() + self.arglist = arglist + self.lhs = lhs + self.lhslist = lhslist + self.rhs = rhs + self.rhslist = rhslist + + def func(self): + """ + This is the hook function that actually does all the work. It is called + by the cmdhandler right after self.parser() finishes, and so has access + to all the variables defined therein. + """ + # a simple test command to show the available properties + string = "-" * 50 + string += "\n{w%s{n - Command variables from evennia:\n" % self.key + string += "-" * 50 + string += "\nname of cmd (self.key): {w%s{n\n" % self.key + string += "cmd aliases (self.aliases): {w%s{n\n" % self.aliases + string += "cmd perms (self.permissions): {w%s{n\n" % self.permissions + string += "help category (self.help_category): {w%s{n\n" % self.help_category + string += "object calling (self.caller): {w%s{n\n" % self.caller + string += "object storing cmdset (self.obj): {w%s{n\n" % self.obj + string += "command string given (self.cmdstring): {w%s{n\n" % self.cmdstring + # show cmdset.key instead of cmdset to shorten output + string += utils.fill("current cmdset (self.cmdset): {w%s{n\n" % self.cmdset) + + + string += "\n" + "-" * 50 + string += "\nVariables from MuxCommand baseclass\n" + string += "-" * 50 + string += "\nraw argument (self.raw): {w%s{n \n" % self.raw + string += "cmd args (self.args): {w%s{n\n" % self.args + string += "cmd switches (self.switches): {w%s{n\n" % self.switches + string += "space-separated arg list (self.arglist): {w%s{n\n" % self.arglist + string += "lhs, left-hand side of '=' (self.lhs): {w%s{n\n" % self.lhs + string += "lhs, comma separated (self.lhslist): {w%s{n\n" % self.lhslist + string += "rhs, right-hand side of '=' (self.rhs): {w%s{n\n" % self.rhs + string += "rhs, comma separated (self.rhslist): {w%s{n\n" % self.rhslist + string += "-" * 50 + self.caller.msg(string) diff --git a/game/gamesrc/commands/default/objmanip.py b/game/gamesrc/commands/default/objmanip.py new file mode 100644 index 0000000000..d13eee8349 --- /dev/null +++ b/game/gamesrc/commands/default/objmanip.py @@ -0,0 +1,1685 @@ +""" +These commands typically are to do with building or modifying Objects. +""" +from django.conf import settings +from src.permissions.permissions import has_perm, has_perm_string +from src.objects.models import ObjectDB, ObjAttribute +from game.gamesrc.commands.default.muxcommand import MuxCommand +from src.utils import create +from src.utils import utils +from src.utils import debug + +class ObjManipCommand(MuxCommand): + """ + This is a parent class for some of the defining objmanip commands + since they tend to have some more variables to define new objects. + + Each object definition can have several components. First is + always a name, followed by an optional alias list and finally an + some optional data, such as a typeclass or a location. A comma ',' + separates different objects. Like this: + + name1;alias;alias;alias:option, name2 ;alias;alias ... + + Spaces between all components are stripped. + + A second situation is attribute manipulation. Such commands + are simpler and appear in combinations + + objname/attr/attr/attr, objname/attr, ... + + Stores four new attributes with the parsed data. + + """ + #OBS - this is just a parent - it's not intended to + #actually be included in a commandset on its own! + + def parse(self): + """ + We need to expand the default parsing to get all + the cases, see the module doc. + """ + # get all the normal parsing done (switches etc) + super(ObjManipCommand, self).parse() + + lhs_objs = [] + rhs_objs = [] + + #first, we deal with the left hand side of an eventual = + for objdef in self.lhslist: + #lhslist is already split by ',' + aliases, option = [], None + if ':' in objdef: + objdef, option = [str(part).strip() + for part in objdef.rsplit(':', 1)] + if ';' in objdef: + objdef, aliases = [str(part).strip() + for part in objdef.split(';', 1)] + aliases = [str(alias).strip().lower() + for alias in aliases.split(';') if alias.strip()] + lhs_objs.append({"name":objdef, + 'option': option, 'aliases': aliases}) + + #next, the right hand side of = + for objdef in self.rhslist: + #rhslist is already split by ',' + aliases, option = [], None + if ':' in objdef: + objdef, option = [str(part).strip() + for part in objdef.rsplit(':', 1)] + if ';' in objdef: + objdef, aliases = [str(part).strip() + for part in objdef.split(';', 1)] + aliases = [str(alias).strip().lower() + for alias in aliases.split(';') if alias.strip()] + rhs_objs.append({"name":objdef, 'option': option, 'aliases': aliases}) + + # We make a second sweep to handle attributes-on-objects + lhs_objattr = [] + rhs_objattr = [] + + # first left hand side + for objdef in self.lhslist: + attrs = [] + if '/' in objdef: + objdef, attrs = [str(part).strip() + for part in objdef.split('/', 1)] + attrs = [str(part).strip().lower() + for part in attrs.split('/') if part.strip()] + lhs_objattr.append({"name":objdef, 'attrs':attrs}) + # right hand side + for objdef in self.rhslist: + attrs = [] + if '/' in objdef: + objdef, attrs = [str(part).strip() + for part in objdef.split('/', 1)] + attrs = [str(part).strip().lower() + for part in attrs.split('/') if part.strip()] + rhs_objattr.append({"name":objdef, 'attrs':attrs}) + + self.lhs_objs = lhs_objs + self.rhs_objs = rhs_objs + self.lhs_objattr = lhs_objattr + self.rhs_objattr = rhs_objattr + + +class CmdTeleport(MuxCommand): + """ + teleport + + Usage: + teleport/switch [ =] + + Switches: + quiet - don't inform the source and target + locations about the move. + + Teleports an object somewhere. If no object is + given we are teleporting ourselves. + """ + key = "teleport" + aliases = "tel" + permissions = "cmd:teleport" + help_category = "Building" + + def func(self): + "Performs the teleport" + + caller = self.caller + args = self.args + lhs, rhs = self.lhs, self.rhs + switches = self.switches + + if not args: + caller.msg("Usage: teleport[/switches] [ =] |home") + return + # The quiet switch suppresses leaving and arrival messages. + if "quiet" in switches: + tel_quietly = True + else: + tel_quietly = False + + if rhs: + obj_to_teleport = caller.search(lhs, global_search=True) + destination = caller.search(rhs, global_search=True) + else: + obj_to_teleport = caller + destination = caller.search(args, global_search=True) + if not obj_to_teleport: + caller.msg("Did not find object to teleport.") + return + if not destination: + caller.msg("Destination not found.") + return + if obj_to_teleport == destination: + caller.msg("You can't teleport an object inside of itself!") + return + # try the teleport + if obj_to_teleport.move_to(destination, quiet=tel_quietly, + emit_to_obj=caller): + caller.msg("Teleported.") + +class CmdSetObjAlias(MuxCommand): + """ + Adding permanent aliases + + Usage: + @alias = alias[,alias,alias,...] + + Assigns aliases to an object so it can be referenced by more + than one name. Observe that this is not the same thing as aliases + created with the 'alias' command! Aliases set with @alias are + changing the object in question, making those aliases usable + by everyone. + """ + + key = "@alias" + aliases = "@setobjalias" + permissions = "cmd:setobjalias" + help_category = "Building" + + def func(self): + "Set the aliases." + caller = self.caller + objname, aliases = self.lhs, self.rhslist + + if not aliases: + caller.msg("Usage: @alias = ") + return + # Find the object to receive aliases + obj = caller.search(objname, global_search=True) + # Use search to handle duplicate/nonexistant results. + if not obj: + return + if not has_perm(caller, obj, 'modify_attributes'): + caller.msg("You don't have permission to do that.") + return + # merge the old and new aliases (if any) + old_aliases = obj.aliases.split(',') + new_aliases = [str(alias).strip().lower() + for alias in aliases if alias.strip()] + # make the aliases only appear once + old_aliases.extend(new_aliases) + aliases = list(set(old_aliases)) + aliases = ",".join(str(alias).lower().strip() for alias in aliases if alias) + # save back to object. + obj.aliases = aliases + obj.save() + caller.msg("Aliases for '%s' are now set to [%s]." % (obj.name, aliases)) + + +class CmdName(ObjManipCommand): + """ + cname - change the name and/or aliases of an object + + Usage: + @name obj = name;alias1;alias2 + + Rename an object to something new. + + """ + + key = "@name" + aliases = ["@rename"] + permissions = "cmd:rename" + help_category = "Building" + + def func(self): + "change the name" + + caller = self.caller + if not self.args: + string = "Usage: @name = [;alias;alias;...]" + caller.msg(string) + return + + if self.lhs_objs: + objname = self.lhs_objs[0]['name'] + obj = caller.search(objname) + if not obj: + return + if self.rhs_objs: + newname = self.rhs_objs[0]['name'] + aliases = self.rhs_objs[0]['aliases'] + else: + newname = self.rhs + aliases = None + if not newname and not aliases: + caller.msg("No names or aliases defined!") + return + # change the name and set aliases: + if newname: + obj.name = newname + if aliases: + obj.aliases = aliases + caller.msg("Object's name changed to '%s' %s." % (newname, ", ".join(aliases))) + +class CmdWipe(ObjManipCommand): + """ + @wipe - clears attributes + + Usage: + @wipe [/attribute[/attribute...]] + + Example: + @wipe box + @wipe box/colour + + Wipes all of an object's attributes, or optionally only those + matching the given attribute-wildcard search string. + """ + key = "@wipe" + permissions = "cmd:wipe" + help_category = "Building" + + def func(self): + """ + inp is the dict produced in ObjManipCommand.parse() + """ + + caller = self.caller + + if not self.args: + caller.msg("Usage: @wipe [/attribute/attribute...]") + return + + # get the attributes set by our custom parser + objname = self.lhs_objattr[0]['name'] + attrs = self.lhs_objattr[0]['attrs'] + + obj = caller.search(objname) + if not obj: + return + if not attrs: + # wipe everything + for attr in obj.get_all_attributes(): + attr.delete() + string = "Wiped all attributes on %s." % obj.name + else: + for attrname in attrs: + obj.attr(attrname, delete=True ) + string = "Wiped attributes %s on %s." + string = string % (",".join(attrs), obj.name) + caller.msg(string) + + +class CmdSetAttribute(ObjManipCommand): + """ + @set - set attributes + + Usage: + @set / = + @set / = + @set / + + Sets attributes on objects. The second form clears + a previously set attribute while the last form + inspects the current value of the attribute + (if any). + """ + + key = "@set" + permissions = "cmd:set" + help_category = "Building" + + def func(self): + "Implement the set attribute - a limited form of @py." + + caller = self.caller + if not self.args: + caller.msg("Usage: @set obj/attr = value. Use empty value to clear.") + return + + # get values prepared by the parser + value = self.rhs + objname = self.lhs_objattr[0]['name'] + attrs = self.lhs_objattr[0]['attrs'] + + obj = caller.search(objname) + if not obj: + return + + string = "" + if not value: + if self.rhs == None: + # no = means we inspect the attribute(s) + for attr in attrs: + value = obj.attr(attr) + if value: + string += "\n%s.db.%s = %s" % (obj.name, attr, value) + else: + string += "\n%s has no attribute '%s'." % (obj.name, attr) + else: + # deleting the attribute(s) + for attr in attrs: + if obj.attr(attr): + obj.attr(attr, delete=True) + string += "\nAttribute %s.db.%s deleted." % (obj.name, attr) + else: + string += "\n%s has no attribute '%s'." % (obj.name, attr) + else: + # setting attribute(s) + for attr in attrs: + obj.attr(attr, value) + string += "\nAttribute %s.%s created." % (obj.name, attr) + # send feedback + caller.msg(string.strip('\n')) + +class CmdCpAttr(MuxCommand): + """ + @cpattr - copy attributes + + Usage: + @cpattr / = / [,/,/,...] + @cpattr / = [,,,...] + @cpattr = / [,/,/,...] + @cpattr = [,,,...] + + Example: + @cpattr coolness = Anna/chillout, Anna/nicety, Tom/nicety + -> + copies the coolness attribute (defined on yourself), to attributes + on Anna and Tom. + + Copy the attribute one object to one or more attributes on another object. + """ + key = "@cpattr" + permissions = "cmd:cpattr" + help_category = "Building" + + def func(self): + """ + Do the copying. + """ + caller = self.caller + + if not self.rhs: + string = """Usage: + @cpattr / = / [,/,/,...] + @cpattr / = [,,,...] + @cpattr = / [,/,/,...] + @cpattr = [,,,...]""" + caller.msg(string) + return + + lhs_objattr = self.lhs_objattr + to_objs = self.rhs_objattr + from_obj_name = lhs_objattr[0]['name'] + from_obj_attrs = lhs_objattr[0]['attrs'] + + if not from_obj_attrs: + # this means the from_obj_name is actually an attribute name on self. + from_obj_attrs = [from_obj_name] + from_obj = self + from_obj_name = self.name + else: + from_obj = caller.search(from_obj_name) + if not from_obj or not to_objs: + caller.msg("Have to supply both source object and target(s).") + return + srcvalue = from_obj.attr(from_obj_attrs[0]) + + #copy to all to_obj:ects + string = "Copying %s=%s (with value %s) ..." % (from_obj_name, + from_obj_attrs[0], srcvalue) + for to_obj in to_objs: + to_obj_name = to_obj['name'] + to_obj_attrs = to_obj['attrs'] + to_obj = caller.search(to_obj_name) + if not to_obj: + string += "\nCould not find object '%s'" % to_obj_name + continue + for inum, from_attr in enumerate(from_obj_attrs): + try: + to_attr = to_obj_attrs[inum] + except IndexError: + # if there are too few attributes given + # on the to_obj, we copy the original name instead. + to_attr = from_attr + to_obj.attr(to_attr, srcvalue) + string += "\nCopied %s.%s -> %s.%s." % (from_obj.name, from_attr, + to_obj_name, to_attr) + caller.msg(string) + +class CmdMvAttr(ObjManipCommand): + """ + @mvattr - move attributes + + Usage: + @mvattr /attr[/attr/attr...] = [/attr/attr/...] + + Moves attributes around. If the target object's attribute names are given, + the source attributes will be moved into those attributes instead. The + old attribute(s) will be deleted from the source object (unless source + and target are the same, in which case this is like a copy operation) + """ + key = "@mvattr" + permissions = "cmd:mvattr" + help_category = "Building" + + def func(self): + "We use the parsed values from ObjManipCommand.parse()." + + caller = self.caller + + if not self.lhs or not self.rhs: + caller.msg("Usage: @mvattr /attr[/attr/..] = [/attr/attr..]") + return + + from_obj_name = self.lhs_objattr[0]['name'] + from_obj_attrs = self.lhs_objattr[0]['attrs'] + to_obj_name = self.rhs_objattr[0]['name'] + to_obj_attrs = self.rhs_objattr[0]['name'] + + # find from-object + from_obj = caller.search(from_obj_name) + if not from_obj: + return + #find to-object + to_obj = caller.search_for_object(to_obj_name) + if not to_obj: + return + + # if we copy on the same object, we have to + # be more careful. + same_object = to_obj == from_obj + + #do the moving + string = "" + for inum, from_attr in enumerate(from_obj_attrs): + from_value = from_obj.attr(from_attr) + if not from_value: + string += "\nAttribute '%s' not found on source object %s." + string = string % (from_attr, from_obj.name) + else: + try: + to_attr = to_obj_attrs[inum] + except KeyError: + # too few attributes on the target, so we add the + # source attrname instead + if same_object: + # we can't do that on the same object though, + # it would be just copying to itself. + string += "\nToo few attribute names on target, and " + string += "can't copy same-named attribute to itself." + continue + to_attr = from_attr + # Do the move + to_obj.attr(to_attr, from_value) + from_obj.attr(from_attr, delete=True) + string += "\nMoved %s.%s -> %s.%s." % (from_obj_name, from_attr, + to_obj_name, to_attr) + caller.msg(string) + +class CmdFind(MuxCommand): + """ + find + + Usage: + find + + Searches for an object of a particular name. + """ + + key = "find" + permissions = "cmd:find" + help_category = "Building" + + def func(self): + "Search functionality" + caller = self.caller + arglist = self.arglist + + if not arglist: + caller.msg("Usage: @find ")# [,low [,high]]") + return + searchstring = arglist[0] + if len(arglist) > 1: + low = arglist[1] + if len(arglist) > 2: + high = arglist[2] + #TODO: Implement efficient db search with limits + result = caller.search(searchstring, global_search=True) + if not result: + return + string = "%s(#%s) - %s" % (result.name, result.id, result) + caller.msg(string) + +class CmdCreate(ObjManipCommand): + """ + @create - create new objects + + Usage: + @create[/drop] objname[;alias;alias...][:typeclass], objname... + + switch: + drop - automatically drop the new object into your current location (this is not echoed) + + Creates one or more new objects. If typeclass is given, the object + is created as a child of this typeclass. The typeclass script is + assumed to be located under game/gamesrc/types and any further + directory structure is given in Python notation. So if you have a + correct typeclass object defined in + game/gamesrc/types/examples/red_button.py, you could create a new + object of this type like this: + + @create button;red : examples.red_button + + """ + + key = "@create" + permissions = "cmd:create" + help_category = "Building" + + def func(self): + """ + Creates the object. + """ + + caller = self.caller + + if not self.args: + string = "Usage: @create[/drop] [;alias;alias...] [:typeclass_path]" + caller.msg(string) + return + + # create the objects + for objdef in self.lhs_objs: + string = "" + name = objdef['name'] + aliases = objdef['aliases'] + typeclass = objdef['option'] + + # analyze typeclass. If it starts at the evennia basedir, + # (i.e. starts with game or src) we let it be, otherwise we + # add a base path as defined in settings + if typeclass and not (typeclass.startswith('src.') or + typeclass.startswith('game.')): + typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH, + typeclass) + + # create object (if not a valid typeclass, the default + # object typeclass will automatically be used) + obj = create.create_object(typeclass, name, caller, + home=caller, aliases=aliases) + if not obj: + string += "\nError when creating object." + continue + if aliases: + string += "\nYou create a new %s: %s (aliases: %s)." + string = string % (obj.typeclass, obj.name, ", ".join(aliases)) + else: + string += "\nYou create a new %s: %s." + string = string % (obj.typeclass, obj.name) + if 'drop' in self.switches: + if caller.location: + obj.move_to(caller.location, quiet=True) + caller.msg(string) + + +class CmdCopy(ObjManipCommand): + """ + @copy - copy objects + + Usage: + @copy[/reset] [= new_name][;alias;alias..][:new_location] [,new_name2 ...] + + switch: + reset - make a 'clean' copy off the object, thus + removing any changes that might have been made to the original + since it was first created. + + Create one or more copies of an object. If you don't supply any targets, one exact copy + of the original object will be created with the name *_copy. + """ + + key = "@copy" + permissions = "cmd:copy" + help_category = "Building" + + def func(self): + "Uses ObjManipCommand.parse()" + + caller = self.caller + args = self.args + if not args: + caller.msg("Usage: @copy [=new_name[;alias;alias..]][:new_location]") + return + + if not self.rhs: + # this has no target =, so an identical new object is created. + from_obj_name = self.args + from_obj = caller.search(from_obj_name) + if not from_obj: + return + to_obj_name = "%s_copy" % from_obj_name + to_obj_aliases = from_obj.aliases + to_obj_location = from_obj.location + copiedobj = ObjectDB.objects.copy_object(from_obj, to_obj_name, + to_obj_location, to_obj_aliases) + if copiedobj: + string = "Identical copy of %s, named '%s' was created." % (to_obj_name, to_obj_name) + else: + string = "There was an error copying %s." + else: + # we have specified =. This might mean many object targets + from_obj_name = self.lhs_objs[0]['name'] + from_obj = caller.search(from_obj_name) + if not from_obj: + return + for objdef in self.lhs_objs: + # loop through all possible copy-to targets + to_obj_name = objdef['name'] + to_obj_aliases = objdef['aliases'] + to_obj_location = objdef['option'] + copiedobj = ObjectDB.objects.copy_object(from_obj, to_obj_name, + to_obj_location, to_obj_aliases) + if copiedobj: + string = "Copied %s to '%s' (aliases: %s)." % (from_obj_name, to_obj_name, + to_obj_aliases) + else: + string = "There was an error copying %s to '%s'." % (from_obj_name, + to_obj_name) + # we are done, echo to user + caller.msg(string) + +class CmdOpen(ObjManipCommand): + """ + @open - create new exit + + Usage: + @open [;alias;alias..][:typeclass] = [,[;alias;..][:typeclass]]] + + Handles the creation of exits. If a destination is given, the exit + will point there. The argument sets up an exit at the + destination leading back to the current room. Destination name + can be given both as a #dbref and a name, if that name is globally + unique. + + """ + key = "@open" + permissions = "cmd:open" + help_category = "Building" + + # a custom member method to chug out exits and do checks + def create_exit(self, exit_name, location, destination, exit_aliases=None, typeclass=None): + """ + Helper function to avoid code duplication. + At this point we know destination is a valid location, but + all arguments are strings/lists. + + """ + caller = self.caller + string = "" + # check if this exit object already exists here + exit_obj = [obj for obj in location.contents + if (obj.key.lower() == exit_name.lower() and obj.db._destination)] + if exit_obj: + exit_obj = exit_obj[0] + old_destination = exit_obj.db._destination + if old_destination: + string = "Exit %s already exists." % exit_name + if old_destination != destination: + # reroute the old exit. + exit_obj.db._destination = destination + exit_obj.aliases = exit_aliases + string += " Rerouted its old destination '%s' to '%s' and changed aliases." % \ + (old_destination.name, destination.name) + else: + # exit does not exist before. Create a new one. + exit_obj = create.create_object(typeclass, key=exit_name, + location=location, + aliases=exit_aliases) + if exit_obj: + # storing an attribute _destination is what makes it an exit! + exit_obj.db._destination = destination + string = "Created new Exit '%s' to %s (aliases: %s)." % (exit_name, + destination.name, + exit_aliases) + else: + string = "Error: Exit '%s' not created." % (exit_name) + # emit results + caller.msg(string) + return exit_obj + + def func(self): + """ + This is where the processing starts. + Uses the ObjManipCommand.parser() for pre-processing + as well as the self.create_exit() method. + """ + caller = self.caller + + if not self.args or not self.rhs: + string = "Usage: @open [;alias;alias...][:typeclass] " + string += "= [;alias..][:typeclass]]]" + caller.msg(string) + return + + # We must have a location to open an exit + location = caller.location + if not location: + caller.msg("You cannot create an exit from a None-location.") + return + + # obtain needed info from cmdline + + exit_name = self.lhs_objs[0]['name'] + exit_aliases = self.lhs_objs[0]['aliases'] + exit_typeclass = self.lhs_objs[0]['option'] + + # analyze typeclass. If it starts at the evennia basedir, + # (i.e. starts with game or src) we let it be, otherwise we + # add a base path as defined in settings + if exit_typeclass and not (exit_typeclass.startswith('src.') or + exit_typeclass.startswith('game.')): + exit_typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH, + exit_typeclass) + + dest_name = self.rhs_objs[0]['name'] + + # first, check so the destination exists. + destination = caller.search(dest_name, global_search=True) + if not destination: + return + + # Create exit + + ok = self.create_exit(exit_name, location, destination, exit_aliases, exit_typeclass) + if not ok: + # an error; the exit was not created, so we quit. + return + + # We are done with exit creation. Check if we want a return-exit too. + + if len(self.rhs_objs) > 1: + back_exit_name = self.rhs_objs[1]['name'] + back_exit_aliases = self.rhs_objs[1]['name'] + back_exit_typeclass = self.rhs_objs[1]['option'] + + # analyze typeclass. If it starts at the evennia basedir, + # (i.e. starts with game or src) we let it be, otherwise we + # add a base path as defined in settings + if back_exit_typeclass and not (back_exit_typeclass.startswith('src.') or + back_exit_typeclass.startswith('game.')): + back_exit_typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH, + back_exit_typeclass) + # Create the back-exit + self.create_exit(back_exit_name, destination, location, + back_exit_aliases, back_exit_typeclass) + +## +## def cmd_chown(command): +## """ +## @chown - change ownerships + +## Usage: +## @chown = + +## Changes the ownership of an object. The new owner specified must be a +## player object. +## """ +## caller = command.caller + +## if not command.command_argument: +## caller.msg("Usage: @chown = ") +## return + +## eq_args = command.command_argument.split('=', 1) +## target_name = eq_args[0] +## owner_name = eq_args[1] + +## if len(target_name) == 0: +## caller.msg("Change the ownership of what?") +## return + +## if len(eq_args) > 1: +## target_obj = caller.search_for_object(target_name) +## # Use search_for_object to handle duplicate/nonexistant results. +## if not target_obj: +## return + +## if not caller.controls_other(target_obj) and not caller.has_perm("objects.admin_ownership"): +## caller.msg(defines_global.NOCONTROL_MSG) +## return + +## owner_obj = caller.search_for_object(owner_name) +## # Use search_for_object to handle duplicate/nonexistant results. +## if not owner_obj: +## return +## if not owner_obj.is_player(): +## caller.msg("Only players may own objects.") +## return +## if target_obj.is_player(): +## caller.msg("You may not change the ownership of player objects.") +## return + +## target_obj.set_owner(owner_obj) +## caller.msg("%s now owns %s." % (owner_obj, target_obj)) +## else: +## # We haven't provided a target. +## caller.msg("Who should be the new owner of the object?") +## return +## GLOBAL_CMD_TABLE.add_command("@chown", cmd_chown, priv_tuple=("objects.modify_attributes", +## "objects.admin_ownership"), +## help_category="Building" ) + +class CmdLink(MuxCommand): + """ + @link - connect objects + + Usage: + @link[/switches] = + @link[/switches] = + @link[/switches] + + Switches: + twoway - this is only useful when both + and are Exits. If so, a link back + from to will also be created. + + + If is an exit, set its destination. For all other object types, this + command sets the object's Home. + The second form sets the destination/home to None and the third form inspects + the current value of destination/home on . + """ + + key = "@link" + permissions = "cmd:link" + + def func(self): + "Perform the link" + caller = self.caller + + if not self.args: + caller.msg("Usage: @link[/twoway] = ") + return + + object_name = self.lhs + + # get object + obj = caller.search(object_name, global_search=True) + if not obj: + return + + string = "" + if self.rhs: + # this means a target name was given + target = caller.search(self.rhs, global_search=True) + if not target: + return + # if obj is an exit (has db attribute _destination), + # set that, otherwise set home. + if obj.db._destination: + obj.db._destination = target + if "twoway" in self.switches: + if target.db._destination: + target.db._destination = obj + string = "Link created %s <-> %s (two-way)." % (obj.name, target.name) + else: + string = "Cannot create two-way link to non-exit." + string += " Link created %s -> %s (one way)." % (obj.name, target.name) + else: + string = "Link created %s -> %s (one way)." % (obj.name, target.name) + else: + # obj is not an exit (has not attribute _destination), + # so set home instead + obj.home = target + string = "Set %s's home to %s." % (obj.name, target.name) + + elif self.rhs == None: + # this means that no = was given (otherwise rhs + # would have been an empty string). So we inspect + # the home/destination on object + dest = obj.db._destination + if dest: + "%s is an exit to %s." % (obj.name, dest.name) + else: + string = "%s has home %s." % (obj.name, obj.home) + else: + # We gave the command @link 'obj = ' which means we want to + # clear _destination or set home to None. + if obj.db._destination: + obj.db._destination = "None" # it can't be None, or _destination would + # be deleted and obj cease being an exit! + string = "Exit %s no longer links anywhere." % obj.name + else: + obj.home = None + string = "%s no longer has a home." % obj.name + # give feedback + caller.msg(string) + +class CmdUnLink(CmdLink): + """ + @unlink - unconnect objects + + Usage: + @unlink + + Unlinks an object, for example an exit, disconnecting + it from whatever it was connected to. + """ + # this is just a child of CmdLink + + key = "@unlink" + permissions = "cmd:unlink" + help_key = "Building" + + def func(self): + """ + All we need to do here is to set the right command + and call func in CmdLink + """ + + caller = self.caller + + if not self.args: + caller.msg("Usage: @unlink ") + return + + # This mimics '@link = ' which is the same as @unlink + self.rhs = "" + + # call the @link functionality + super(CmdUnLink, self).func() + + +class CmdDig(ObjManipCommand): + """ + @dig - build and connect new rooms to the current one + + Usage: + @dig[/switches] roomname[;alias;alias...][:typeclass] + [= exit_to_there[;alias][:typeclass]] + [, exit_to_here[;alias][:typeclass]] + + Switches: + teleport - move yourself to the new room + + Example: + @dig kitchen = north; n, south;s : big_scary_door + + This command is a convenient way to build rooms quickly; it creates the new room and you can optionally + set up exits back and forth between your current room and the new one. You can add as many aliases as you + like to the name of the room and the exits in question; an example would be 'north;no;n'. + """ + key = "@dig" + permissions = "cmd:dig" + help_category = "Building" + + def func(self): + "Do the digging. Inherits variables from ObjManipCommand.parse()" + + caller = self.caller + + if not self.lhs: + string = "Usage: @dig[/teleport] roomname[:parent] [= exit_there" + string += "[;alias;alias..][:parent]] " + string += "[, exit_back_here[;alias;alias..][:parent]]" + caller.msg(string) + return + + room = self.lhs_objs[0] + + if not room["name"]: + caller.msg("You must supply a new room name.") + return + location = caller.location + + # Create the new room + typeclass = room['option'] + if not typeclass: + typeclass = settings.BASE_ROOM_TYPECLASS + # analyze typeclass. If it starts at the evennia basedir, + # (i.e. starts with game or src) we let it be, otherwise we + # add a base path as defined in settings + if typeclass and not (typeclass.startswith('src.') or + typeclass.startswith('game.')): + typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH, + typeclass) + + new_room = create.create_object(typeclass, room["name"], + aliases=room["aliases"]) + room_string = "Created room '%s' of type %s." % (new_room.name, typeclass) + + exit_to_string = "" + exit_back_string = "" + + if self.rhs_objs: + to_exit = self.rhs_objs[0] + if not to_exit["name"]: + exit_to_string = \ + "\n\rYou didn't give a name for the exit to the new room." + elif not location: + exit_to_string = \ + "\n\rYou cannot create an exit from a None-location." + else: + # Build the exit to the new room from the current one + typeclass = to_exit["option"] + if not typeclass: + typeclass = settings.BASE_EXIT_TYPECLASS + # analyze typeclass. If it starts at the evennia basedir, + # (i.e. starts with game or src) we let it be, otherwise we + # add a base path as defined in settings + if typeclass and not (typeclass.startswith('src.') or + typeclass.startswith('game.')): + typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH, + typeclass) + new_to_exit = create.create_object(typeclass, to_exit["name"], + location, + aliases=to_exit["aliases"]) + new_to_exit.db._destination = new_room + exit_to_string = "\n\rCreated new Exit to new room: %s (aliases: %s)." + exit_to_string = exit_to_string % (new_to_exit.name, + new_to_exit.aliases) + + if len(self.rhs_objs) > 1: + # Building the exit back to the current room + back_exit = self.rhs_objs[1] + if not back_exit["name"]: + exit_back_string = \ + "\n\rYou didn't give a name for the exit back here." + elif not location: + exit_back_string = \ + "\n\rYou cannot create an exit back to a None-location." + else: + typeclass = back_exit["option"] + if not typeclass: + typeclass = settings.BASE_EXIT_TYPECLASS + # analyze typeclass. If it starts at the evennia basedir, + # (i.e. starts with game or src) we let it be, otherwise we + # add a base path as defined in settings + if typeclass and not (typeclass.startswith('src.') or + typeclass.startswith('game.')): + typeclass = "%s.%s" % (settings.BASE_TYPECLASS_PATH, + typeclass) + new_back_exit = create.create_object(typeclass, back_exit["name"], + new_room, + aliases=back_exit["aliases"]) + new_back_exit.db._destination = location + exit_back_string = "\n\rExit back from new room: %s (aliases: %s)." + exit_back_string = exit_back_string % (new_back_exit.name, + new_back_exit.aliases) + caller.msg("%s%s%s" % (room_string, exit_to_string, exit_back_string)) + if new_room and 'teleport' in self.switches: + caller.move_to(new_room) + +class CmdDesc(MuxCommand): + """ + @desc - describe an object or room + + Usage: + @desc [ =] >description> + + Setts the "desc" attribute on an + object. If an object is not given, + describe the current room. + """ + key = "@desc" + aliases = "@describe" + permissions = "cmd:desc" + help_category = "Building" + + def func(self): + "Define command" + + caller = self.caller + if not self.args: + caller.msg("Usage: @desc [ =] >description>") + return + + if self.rhs: + # We have an = + obj = caller.search(self.lhs) + if not obj: + return + desc = self.rhs + else: + obj = caller + desc = self.args + # storing the description + obj.db.desc = desc + caller.msg("The description was set on %s." % obj.key) + + +class CmdDestroy(MuxCommand): + """ + @destroy - remove objects from the game + + Usage: + @destroy[/] obj [,obj2, obj3, ...] + @delete '' + + switches: + override - The @destroy command will usually avoid accidentally destroying + player objects. This switch overrides this safety. + + Destroys one or many objects. + """ + + key = "@destroy" + aliases = "@delete" + permissions = "cmd:destroy" + help_category = "Building" + + def func(self): + "Implements the command." + + caller = self.caller + + if not self.args or not self.lhslist: + caller.msg("Usage: @destroy[/switches] obj [,obj2, obj3, ...]") + return + + string = "" + for objname in self.lhslist: + obj = caller.search(objname) + if not obj: + continue + objname = obj.name + if obj.player and not 'override' in self.switches: + string += "\n\rObject %s is a player object. Use /override to delete anyway." % objname + continue + if not has_perm(caller, obj, 'create'): + string += "\n\rYou don't have permission to delete %s." % objname + continue + # do the deletion + okay = obj.delete() + if not okay: + string += "\n\rERROR: %s NOT deleted, probably because at_obj_delete() returned False." % objname + else: + string += "\n\r%s was deleted." % objname + caller.msg(string.strip('\n')) + + +#NOT VALID IN NEW SYSTEM! +## def cmd_lock(command): +## """ +## @lock - limit use of objects + +## Usage: +## @lock[/switch] [:type] [= [,key2,key3,...]] + +## Switches: +## add - add a lock (default) from object +## del - remove a lock from object +## list - view all locks on object (default) +## type: +## DefaultLock - the default lock type (default) +## UseLock - prevents usage of objects' commands +## EnterLock - blocking objects from entering the object + +## Locks an object for everyone except those matching the keys. +## The keys can be of the following types (and searched in this order): +## - a user #dbref (#2, #45 etc) +## - a Group name (Builder, Immortal etc, case sensitive) +## - a Permission string (genperms.get, etc) +## - a Function():return_value pair. (ex: alliance():Red). The +## function() is called on the locked object (if it exists) and +## if its return value matches the Key is passed. If no +## return_value is given, matches against True. +## - an Attribute:return_value pair (ex: key:yellow_key). The +## Attribute is the name of an attribute defined on the locked +## object. If this attribute has a value matching return_value, +## the lock is passed. If no return_value is given, +## attributes will be searched, requiring a True +## value. + +## If no keys at all are given, the object is locked for everyone. +## When the lock blocks a user, you may customize which error is given by +## storing error messages in an attribute. For DefaultLocks, UseLocks and +## EnterLocks, these attributes are called lock_msg, use_lock_msg and +## enter_lock_msg respectively. + +## [[lock_types]] + +## Lock types: + +## Name: Affects: Effect: +## ----------------------------------------------------------------------- +## DefaultLock: Exits: controls who may traverse the exit to +## its destination. +## Rooms: controls whether the player sees a failure +## message after the room description when +## looking at the room. +## Players/Things: controls who may 'get' the object. + +## UseLock: All but Exits: controls who may use commands defined on +## the locked object. + +## EnterLock: Players/Things: controls who may enter/teleport into +## the object. +## VisibleLock: Players/Things: controls if the object is visible to +## someone using the look command. + +## Fail messages echoed to the player are stored in the attributes 'lock_msg', +## 'use_lock_msg', 'enter_lock_msg' and 'visible_lock_msg' on the locked object +## in question. If no such message is stored, a default will be used (or none at +## all in some cases). +## """ + +## caller = command.caller +## arg = command.command_argument +## switches = command.command_switches + +## if not arg: +## caller.msg("Usage: @lock[/switch] [:type] [= [,key2,key3,...]]") +## return +## keys = "" +## #deal with all possible arguments. +## try: +## lside, keys = arg.split("=",1) +## except ValueError: +## lside = arg +## lside, keys = lside.strip(), keys.strip() +## try: +## obj_name, ltype = lside.split(":",1) +## except: +## obj_name = lside +## ltype = "DefaultLock" +## obj_name, ltype = obj_name.strip(), ltype.strip() + +## if ltype not in ["DefaultLock","UseLock","EnterLock","VisibleLock"]: +## caller.msg("Lock type '%s' not recognized." % ltype) +## return + +## obj = caller.search_for_object(obj_name) +## if not obj: +## return + +## obj_locks = obj.LOCKS + +## if "list" in switches: +## if not obj_locks: +## s = "There are no locks on %s." % obj.name +## else: +## s = "Locks on %s:" % obj.name +## s += obj_locks.show() +## caller.msg(s) +## return + +## # we are trying to change things. Check permissions. +## if not caller.controls_other(obj): +## caller.msg(defines_global.NOCONTROL_MSG) +## return + +## if "del" in switches: +## # clear a lock +## if obj_locks: +## if not obj_locks.has_type(ltype): +## caller.msg("No %s set on this object." % ltype) +## else: +## obj_locks.del_type(ltype) +## obj.LOCKS = obj_locks +## caller.msg("Cleared lock %s on %s." % (ltype, obj.name)) +## else: +## caller.msg("No %s set on this object." % ltype) +## return +## else: +## #try to add a lock +## if not obj_locks: +## obj_locks = locks.Locks() +## if not keys: +## #add an impassable lock +## obj_locks.add_type(ltype, locks.Key()) +## caller.msg("Added impassable '%s' lock to %s." % (ltype, obj.name)) +## else: +## keys = [k.strip() for k in keys.split(",")] +## obj_keys, group_keys, perm_keys = [], [], [] +## func_keys, attr_keys = [], [] +## allgroups = [g.name for g in Group.objects.all()] +## allperms = ["%s.%s" % (p.content_type.app_label, p.codename) +## for p in Permission.objects.all()] +## for key in keys: +## #differentiate different type of keys +## if Object.objects.is_dbref(key): +## # this is an object key, like #2, #6 etc +## obj_keys.append(key) +## elif key in allgroups: +## # a group key +## group_keys.append(key) +## elif key in allperms: +## # a permission string +## perm_keys.append(key) +## elif '()' in key: +## # a function()[:returnvalue] tuple. +## # Check if we also request a return value +## funcname, rvalue = [k.strip() for k in key.split('()',1)] +## if not funcname: +## funcname = "lock_func" +## rvalue = rvalue.lstrip(':') +## if not rvalue: +## rvalue = True +## # pack for later adding. +## func_keys.append((funcname, rvalue)) +## elif ':' in key: +## # an attribute[:returnvalue] tuple. +## attr_name, rvalue = [k.strip() for k in key.split(':',1)] +## # pack for later adding +## attr_keys.append((attr_name, rvalue)) +## else: +## caller.msg("Key '%s' is not recognized as a valid dbref, group or permission." % key) +## return +## # Create actual key objects from the respective lists +## keys = [] +## if obj_keys: +## keys.append(locks.ObjKey(obj_keys)) +## if group_keys: +## keys.append(locks.GroupKey(group_keys)) +## if perm_keys: +## keys.append(locks.PermKey(perm_keys)) +## if func_keys: +## keys.append(locks.FuncKey(func_keys, obj.dbref)) +## if attr_keys: +## keys.append(locks.AttrKey(attr_keys)) + +## #store the keys in the lock +## obj_locks.add_type(ltype, keys) +## kstring = " " +## for key in keys: +## kstring += " %s," % key +## kstring = kstring[:-1] +## caller.msg("Added lock '%s' to %s with keys%s." % (ltype, obj.name, kstring)) +## obj.LOCKS = obj_locks +## GLOBAL_CMD_TABLE.add_command("@lock", cmd_lock, priv_tuple=("objects.create",), help_category="Building") + + +class CmdExamine(ObjManipCommand): + """ + examine - detailed info on objects + + Usage: + examine [[/attrname]] + + The examine command shows detailed game info about an + object and optionally a specific attribute on it. + If object is not specified, the current location is examined. + """ + key = "examine" + aliases = ["ex"] + permissions = "cmd:examine" + help_category = "Building" + + def crop_line(self, text, heading="", line_width=79): + """ + Crops a line of text, adding [...] if doing so. + + heading + text + eventual [...] will not exceed line_width. + """ + headlen = len(str(heading)) + textlen = len(str(text)) + if textlen > (line_width - headlen): + text = "%s[...]" % text[:line_width - headlen - 5] + return text + + + def format_attributes(self, obj, attrname=None): + """ + Helper function that returns info about attributes and/or + non-persistent data stored on object + """ + if attrname: + db_attr = [obj.attr(attrname)] + try: + ndb_attr = [(attrname, object.__getattribute__(obj.ndb, attrname))] + except Exception: + ndb_attr = [(attrname, None)] + else: + db_attr = [(attr.key, attr.value) for attr in ObjAttribute.objects.filter(db_obj=obj)] + try: + ndb_attr = [(aname, avalue) for aname, avalue in obj.ndb.__dict__.items()] + except Exception: + ndb_attr = [(None, None)] + string = "" + if db_attr and db_attr[0]: + #self.caller.msg(db_attr) + string += "\n{wPersistent attributes{n:" + for attr, value in db_attr: + value = self.crop_line(value, attr) + string += "\n %s = %s" % (attr, value) + if ndb_attr and ndb_attr[0]: + string += "\n{wNon-persistent attributes{n:" + for attr, value in ndb_attr: + value = self.crop_line(value, attr) + string += "\n %s = %s" % (attr, value) + return string + + def format_output(self, obj): + """ + Helper function that creates a nice report about an object. + + returns a string. + """ + dbref = "" + if has_perm_string(self.caller, 'see_dbref'): + dbref = "(#%i)" % obj.id + string = "\n{wName{n: %s%s" % (obj.name, dbref) + if obj.has_player: + string += "\n{wPlayer{n: %s" % obj.player.name + string += "\n{wTypeclass{n: %s" % utils.fill(obj.typeclass) + string += "\n{wLocation{n: %s" % obj.location + perms = obj.permissions + if obj.player and obj.player.is_superuser: + perms = "" + string += "\n{wPerms/Locks{n: %s" % utils.fill(perms) + if obj.cmdset.all(): + string += "\n{wCurrent Cmdset{n:\n\r %s" % obj.cmdset + if obj.scripts.all(): + string += "\n{wScripts{n:\n\r %s" % obj.scripts + # add the attributes + string += self.format_attributes(obj) + # add the contents + exits = [] + pobjs = [] + things = [] + for content in obj.contents: + if content.db._destination: + # an exit + exits.append(content) + elif content.player: + pobjs.append(content) + else: + things.append(content) + if exits: + string += "\n{wExits{n: " + ", ".join([exit.name for exit in exits]) + if pobjs: + string += "\n{wCharacters{n: " + ", ".join(["{c%s{n" % pobj.name for pobj in pobjs]) + if things: + string += "\n{wContents{n: " + ", ".join([cont.name for cont in obj.contents + if cont not in exits and cont not in pobjs]) + #output info + return "-"*50 + '\n' + string.strip() + "\n" + '-'*50 + + def func(self): + "Process command" + caller = self.caller + + if not self.args: + # If no arguments are provided, examine the invoker's location. + obj = caller.location + if not has_perm(caller, obj, 'obj_info'): + #If we don't have special info access, just look at the object instead. + caller.exec_cmd('look %s' % obj.name) + return + string = self.format_output(obj) + + else: + # we have given a specific target object + + string = "" + + for objdef in self.lhs_objattr: + + obj_name = objdef['name'] + obj_attrs = objdef['attrs'] + + obj = caller.search(obj_name) + + if not obj: + string += "\nObject '%s' not found." % obj_name + continue + if not has_perm(caller, obj, 'obj_info'): + #If we don't have special info access, just look at the object instead. + caller.exec_cmd('look %s' % obj_name) + continue + if obj_attrs: + for attrname in obj_attrs: + # we are only interested in specific attributes + string += self.format_attributes(obj, attrname) + else: + string += self.format_output(obj) + # Send it all + caller.msg(string) + + +class CmdTypeclass(MuxCommand): + """ + @typeclass - set object typeclass + + Usage: + @typclass[/switch] [= ] + @type '' + @parent '' + + Switch: + reset - clean out *all* the attributes on the object - + basically making this a new clean object. + + Example: + @type button = examples.red_button.RedButton + + Sets an object's typeclass. The typeclass must be identified + by its location using python dot-notation pointing to the correct + module and class. If no typeclass is given (or a wrong typeclass + is given), the object will be set to the default typeclass. + The location of the typeclass module is searched from + the default typeclass directory, as defined in the server settings. + + """ + + key = "@typeclass" + aliases = "@type, @parent" + permissions = "cmd:typeclass" + help_category = "Building" + + def func(self): + "Implements command" + + caller = self.caller + + if not self.args: + caller.msg("Usage: @type [= + + Switches: + obj - debug an object + script - debug a script + + Examples: + @debug/script game.gamesrc.scripts.myscript.MyScript + @debug/script myscript.MyScript + @debug/obj examples.red_button.RedButton + + This command helps when debugging the codes of objects and scripts. + It creates the given object and runs tests on its hooks. You can + supply both full paths (starting from the evennia base directory), + otherwise the system will start from the defined root directory + for scripts and objects respectively (defined in settings file). + + """ + + key = "@debug" + permissions = "cmd:debug" + help_category = "Building" + + def func(self): + "Running the debug" + + if not self.args or not self.switches: + self.caller.msg("Usage: @debug[/obj][/script] ") + return + + path = self.args + + if 'obj' in self.switches or 'object' in self.switches: + # analyze path. If it starts at the evennia basedir, + # (i.e. starts with game or src) we let it be, otherwise we + # add a base path as defined in settings + if path and not (path.startswith('src.') or + path.startswith('game.')): + path = "%s.%s" % (settings.BASE_TYPECLASS_PATH, + path) + + # create and debug the object + self.caller.msg(debug.debug_object(path, self.caller)) + self.caller.msg(debug.debug_object_scripts(path, self.caller)) + + elif 'script' in self.switches: + # analyze path. If it starts at the evennia basedir, + # (i.e. starts with game or src) we let it be, otherwise we + # add a base path as defined in settings + if path and not (path.startswith('src.') or + path.startswith('game.')): + path = "%s.%s" % (settings.BASE_SCRIPT_PATH, + path) + + self.caller.msg(debug.debug_syntax_script(path)) diff --git a/game/gamesrc/commands/default/privileged.py b/game/gamesrc/commands/default/privileged.py new file mode 100644 index 0000000000..73e094e87f --- /dev/null +++ b/game/gamesrc/commands/default/privileged.py @@ -0,0 +1,670 @@ +""" +This file contains commands that require special permissions to +use. These are generally @-prefixed commands, but there are +exceptions. +""" + +import traceback +from django.contrib.auth.models import User +from src.server import sessionhandler +from src.scripts.models import ScriptDB +from src.objects.models import ObjectDB +from src.permissions.models import PermissionGroup +from src.scripts.scripthandler import format_script_list +from src.utils import reloads, create, logger, utils +from src.permissions.permissions import has_perm +from game.gamesrc.commands.default.muxcommand import MuxCommand + + +class CmdReload(MuxCommand): + """ + Reload the system + + Usage: + @reload + + This reloads the system modules and + re-validates all scripts. + """ + key = "@reload" + permissions = "cmd:reload" + help_category = "System" + + def func(self): + """ + reload the system. + """ + caller = self.caller + reloads.reload_modules() + reloads.reload_scripts() + reloads.reload_commands() + +class CmdPy(MuxCommand): + """ + Execute a snippet of python code + + Usage: + @py + + In this limited python environment, only two + variables are defined: 'self'/'me' which refers to one's + own object, and 'here' which refers to the current + location. + """ + key = "@py" + aliases = ["!"] + permissions = "cmd:py" + help_category = "Admin" + + def func(self): + "hook function" + + caller = self.caller + pycode = self.args + + if not pycode: + string = "Usage: @py " + caller.msg(string) + return + # create temporary test objects for playing with + script = create.create_script("src.scripts.scripts.DoNothing", + 'testscript') + obj = create.create_object("src.objects.objects.Object", + 'testobject') + available_vars = {'self':caller, + 'me':caller, + 'here':caller.location, + 'obj':obj, + 'script':script} + caller.msg(">>> %s" % pycode) + try: + ret = eval(pycode, {}, available_vars) + ret = "<<< %s" % str(ret) + except Exception: + try: + exec(pycode, {}, available_vars) + ret = "<<< Done." + except Exception: + errlist = traceback.format_exc().split('\n') + if len(errlist) > 4: + errlist = errlist[4:] + ret = "\n".join("<<< %s" % line for line in errlist if line) + caller.msg(ret) + obj.delete() + script.delete() + +class CmdListScripts(MuxCommand): + """ + List all scripts. + + Usage: + @scripts[/switches] [] + + Switches: + stop - stops an existing script + validate - run a validation on the script(s) + + If no switches are given, this command just views all active + scripts. The argument can be either an object, at which point it + will be searched for all scripts defined on it, or an script name + or dbref. For using the /stop switch, a unique script dbref is + required since whole classes of scripts often have the same name. + """ + key = "@scripts" + aliases = "@listscripts" + permissions = "cmd:listscripts" + help_category = "Admin" + + def func(self): + "implement method" + + caller = self.caller + args = self.args + + string = "" + if args: + # test first if this is an script match + scripts = ScriptDB.objects.get_all_scripts(key=args) + if not scripts: + # try to find an object instead. + objects = ObjectDB.objects.pobject_search(caller, + args, + global_search=True) + if objects: + scripts = [] + for obj in objects: + # get all scripts on the object(s) + scripts.extend(ScriptDB.objects.get_all_scripts_on_obj(obj)) + else: + # we want all scripts. + scripts = ScriptDB.objects.get_all_scripts() + if not scripts: + return + #caller.msg(scripts) + + if self.switches and self.switches[0] in ('stop', 'del', 'delete'): + # we want to delete something + if not scripts: + string = "No scripts/objects matching '%s'. " % args + string += "Be more specific." + elif len(scripts) == 1: + # we have a unique match! + string = "Stopping script '%s'." % scripts[0].key + scripts[0].stop() + ScriptDB.objects.validate() #just to be sure all is synced + else: + # multiple matches. + string = "Multiple script matches. Please refine your search:\n" + string += ", ".join([str(script.key) for script in scripts]) + + elif self.switches and self.switches[0] in ("validate", "valid", "val"): + # run validation on all found scripts + nr_started, nr_stopped = ScriptDB.objects.validate(scripts=scripts) + string = "Validated %s scripts. " % ScriptDB.objects.all().count() + string += "Started %s and stopped %s scripts." % (nr_started, + nr_stopped) + else: + # No stopping or validation. We just want to view things. + string = format_script_list(scripts) + caller.msg(string) + + +class CmdListCmdSets(MuxCommand): + """ + list command sets on an object + + Usage: + @listcmdsets [obj] + + This displays all cmdsets assigned + to a user. Defaults to yourself. + """ + key = "@listcmdsets" + permissions = "cmd:listcmdsets" + + def func(self): + "list the cmdsets" + + caller = self.caller + if self.arglist: + obj = caller.search(self.arglist[0]) + if not obj: + return + else: + obj = caller + string = "%s" % obj.cmdset + caller.msg(string) + +class CmdListObjects(MuxCommand): + """ + List all objects in database + + Usage: + @listobjects [nr] + + Gives a list of nr latest objects in database ang give + statistics. If not given, nr defaults to 10. + """ + key = "@listobjects" + aliases = ["@listobj", "@listobjs"] + permissions = "cmd:listobjects" + help_category = "Building" + + def func(self): + "Implement the command" + + caller = self.caller + + if self.args and self.args.isdigit(): + nlim = int(self.args) + else: + nlim = 10 + dbtotals = ObjectDB.objects.object_totals() + #print dbtotals + string = "\nObjects in database:\n" + string += "Count\tTypeclass" + for path, count in dbtotals.items(): + string += "\n %s\t%s" % (count, path) + string += "\nLast %s Objects created:" % nlim + objs = list(ObjectDB.objects.all()) + for i, obj in enumerate(objs): + if i <= nlim: + string += "\n %s\t%s(#%i) (%s)" % \ + (obj.date_created, obj.name, obj.id, str(obj.typeclass)) + else: + break + caller.msg(string) + +class CmdBoot(MuxCommand): + """ + @boot + + Usage + @boot[/switches] [: reason] + + Switches: + quiet - Silently boot without informing player + port - boot by port number instead of name or dbref + + Boot a player object from the server. If a reason is + supplied it will be echoed to the user unless /quiet is set. + """ + + key = "@boot" + permissions = "cmd:boot" + help_category = "Admin" + + def func(self): + "Implementing the function" + caller = self.caller + args = self.args + + if not args: + caller.msg("Usage: @boot[/switches] [:reason]") + return + + if ':' in args: + args, reason = [a.strip() for a in args.split(':', 1)] + boot_list = [] + reason = "" + + if 'port' in self.switches: + # Boot a particular port. + sessions = sessionhandler.get_session_list(True) + for sess in sessions: + # Find the session with the matching port number. + if sess.getClientAddress()[1] == int(args): + boot_list.append(sess) + break + else: + # Boot by player object + pobj = caller.search("*%s" % args, global_search=True) + if not pobj: + return + pobj = pobj[0] + if pobj.has_player: + if not has_perm(caller, pobj, 'can_boot'): + string = "You don't have the permission to boot %s." + pobj.msg(string) + return + # we have a bootable object with a connected user + matches = sessionhandler.sessions_from_object(pobj) + for match in matches: + boot_list.append(match) + else: + caller.msg("That object has no connected player.") + return + + if not boot_list: + caller.msg("No matches found.") + return + + # Carry out the booting of the sessions in the boot list. + + feedback = None + if not 'quiet' in self.switches: + feedback = "You have been disconnected by %s.\n" % caller.name + if reason: + feedback += "\nReason given: %s" % reason + + for session in boot_list: + name = session.name + if feedback: + session.msg(feedback) + session.disconnectClient() + sessionhandler.remove_session(session) + caller.msg("You booted %s." % name) + + +class CmdDelPlayer(MuxCommand): + """ + delplayer - delete player from server + + Usage: + @delplayer[/switch] [: reason] + + Switch: + delobj - also delete the player's currently + assigned in-game object. + + Completely deletes a user from the server database, + making their nick and e-mail again available. + """ + + key = "@delplayer" + permissions = "cmd:delplayer" + help_category = "Admin" + + def func(self): + "Implements the command." + + caller = self.caller + args = self.args + + if not args: + caller.msg("Usage: @delplayer[/delobj] ") + return + + reason = "" + if ':' in args: + args, reason = [arg.strip() for arg in args.split(':', 1)] + + # Search for the object connected to this user (this is done by + # adding a * to the beginning of the search criterion) + pobj = caller.search("*%s" % args, global_search=True) + if not pobj: + # if we cannot find an object connected to this user, + # try a more direct approach + try: + user = User.objects.get(id=args) + except Exception: + try: + user = User.objects.get(name__iexact=args) + except Exception: + caller.msg("Could not find user/id '%s'." % args) + return + uprofile = user.get_profile + else: + user = pobj.user + uprofile = pobj.user_profile + + if not has_perm(caller, uprofile, 'manage_players'): + string = "You don't have the permissions to delete that player." + caller.msg(string) + return + + uname = user.username + # boot the player then delete + if pobj and pobj.has_user: + caller.msg("Booting and informing player ...") + msg = "\nYour account '%s' is being *permanently* deleted.\n" % uname + if reason: + msg += " Reason given:\n '%s'" % reason + pobj.msg(msg) + caller.execute_cmd("@boot %s" % uname) + + uprofile.delete() + user.delete() + caller.msg("Player %s was successfully deleted." % uname) + + +class CmdNewPassword(MuxCommand): + """ + @newpassword + + Usage: + @newpassword = + + Set a player's password. + """ + + key = "@newpassword" + permissions = "cmd:newpassword" + help_category = "Admin" + + def func(self): + "Implement the function." + + caller = self.caller + + if not self.rhs: + caller.msg("Usage: @newpassword = ") + return + + pobj = caller.search("*%s" % self.lhs, global_search=True) + if not pobj: + # if we cannot find an object connected to this user, + # try a more direct approach + try: + user = User.objects.get(id=self.lhs) + except Exception: + try: + user = User.objects.get(name__iexact=self.lhs) + except Exception: + caller.msg("Could not find user/id '%s'." % self.lhs) + return + else: + user = pobj.user + user.set_password(self.rhs) + user.save() + caller.msg("%s - new password set to '%s'." % (user.username, self.rhs)) + if pobj: + pobj.msg("%s has changed your password to '%s'." % (caller.name, self.rhs)) + +class CmdHome(MuxCommand): + """ + home + + Usage: + home + + Teleport the player to their home. + """ + + key = "home" + permissions = "cmd:home" + + def func(self): + "Implement the command" + caller = self.caller + home = caller.home + if not home: + caller.msg("You have no home set.") + else: + caller.move_to(home) + caller.msg("There's no place like home ...") + + +class CmdService(MuxCommand): + """ + @service - manage services + + Usage: + @service[/switch] + + Switches: + start - activates a service + stop - stops a service + list - shows all available services + + Service management system. Allows for the listing, + starting, and stopping of services. + """ + + key = "@service" + permissions = "cmd:service" + help_category = "Admin" + + def func(self): + "Implement command" + + caller = self.caller + switches = self.switches + + if not switches or \ + switches[0] not in ["list","start","stop"]: + caller.msg("Usage: @servive/ [service]") + return + switch = switches[0] + + # get all services + sessions = caller.sessions + if not sessions: + return + service_collection = sessions[0].server.service_collection + + if switch == "list": + # Just display the list of installed services and their + # status, then exit. + string = "-" * 40 + string += "\nService Listing" + + for service in service_collection.services: + if service.running: + status = 'Running' + else: + status = 'Inactive' + string += '\n * %s (%s)' % (service.name, status) + string += "\n" + "-" * 40 + caller.msg(string) + return + + # Get the service to start / stop + + try: + service = service_collection.getServiceNamed(self.args) + except Exception: + string = 'Invalid service name. This command is case-sensitive. ' + string += 'See @service/list.' + caller.msg(string) + return + + if switch == "stop": + # Stopping a service gracefully closes it and disconnects + # any connections (if applicable). + + if not service.running: + caller.msg('That service is not currently running.') + return + # We don't want to kill the main Evennia TCPServer services + # here. If wanting to kill a listening port, one needs to + # do it through settings.py and a restart. + if service.name[:7] == 'Evennia': + string = "You can not stop Evennia TCPServer services this way." + string += "\nTo e.g. remove a listening port, change settings file and restart." + caller.msg(string) + return + #comsys.cemit_mudinfo("%s is *Stopping* the service '%s'." % (sname, service.name)) #TODO! + service.stopService() + return + + if switch == "start": + #Starts a service. + if service.running: + caller.msg('That service is already running.') + return + #comsys.cemit_mudinfo("%s is *Starting* the service '%s'." % (sname,service.name)) #TODO! + service.startService() + +class CmdShutdown(MuxCommand): + + """ + @shutdown + + Usage: + @shutdown [announcement] + + Shut the game server down gracefully. + """ + key = "@shutdown" + permissions = "cmd:shutdown" + help_category = "System" + + def func(self): + "Define function" + try: + session = self.caller.sessions[0] + except Exception: + return + self.caller.msg('Shutting down server ...') + announcement = "\nServer is being SHUT DOWN!\n" + if self.args: + announcement += "%s\n" % self.args + + sessionhandler.announce_all(announcement) + logger.log_infomsg('Server shutdown by %s.' % self.caller.name) + + # access server through session so we don't call server directly + # (importing it directly would restart it...) + session.server.shutdown() + +class CmdPerm(MuxCommand): + """ + @perm - set permissions + + Usage: + @perm[/switch] [] = [] + + Switches: + del : delete the given permission from . + list : list all permissions, or those set on + + This command sets/clears individual permission strings on a user. + Use /list without any arguments to see all available permissions + or those defined on the argument. + """ + key = "@perm" + permissions = "cmd:perm" + help_category = "Admin" + + def func(self): + "Implement function" + + caller = self.caller + switches = self.switches + lhs, rhs = self.lhs, self.rhs + + if not self.args and "list" not in switches: + caller.msg("Usage: @setperm[/switch] [user = permission]") + return + if "list" in switches: + #just print all available permissions + string = "\nAll currently available permissions (i.e. not locks):" + pgroups = PermissionGroup.objects.all() + for pgroup in pgroups: + string += "\n\n - %s (%s):" % (pgroup.key, pgroup.desc) + string += "\n%s" % \ + utils.fill(", ".join(pgroup.group_permissions.split(','))) + caller.msg(string) + return + + pobj = caller.search("*%s" % self.lhs, global_search=True) + if not pobj: + # if we cannot find an object connected to this user, + # try a more direct approach + try: + user = User.objects.get(id=self.lhs) + except Exception: + try: + user = User.objects.get(name__iexact=self.lhs) + except Exception: + caller.msg("Could not find user/id '%s'." % self.lhs) + return + else: + pobj = pobj + user = pobj.user + uprofile = user.get_profile() + + if not rhs: + #if we didn't have any =, we list the permissions set on . + if user.is_superuser: + string = "\n This is a SUPERUSER account! " + string += "All permissions are automatically set." + else: + string = "Permissions set on this object:\n" + string += uprofile.permissions + caller.msg(string) + return + + # we supplied an argument on the form obj = perm + + if 'del' in switches: + # delete the given permission from object. + uprofile.del_perm(rhs) + caller.msg("Permission '%s' removed (if it existed)." % rhs) + if pobj: + pobj.msg("%s revokes the permission '%s' from you." % (caller.name, rhs)) + + else: + # As an extra check, we warn the user if they customize the + # permission string (which is okay, and is used by the lock system) + uprofile.set_perm(rhs) + string = "Permission '%s' given to %s." % (rhs, uprofile.user.username) + if not any(group.contains(rhs) + for group in PermissionGroup.objects.all()): + string += "Note: The given permission is not found in any permission groups." + string += "\nThis is not an error, it just shows that it will work only as a lock." + caller.msg(string) + if pobj: + pobj.msg("%s granted you the permission '%s'." % (caller.name, rhs)) + diff --git a/game/gamesrc/commands/default/syscommands.py b/game/gamesrc/commands/default/syscommands.py new file mode 100644 index 0000000000..6afcf77007 --- /dev/null +++ b/game/gamesrc/commands/default/syscommands.py @@ -0,0 +1,173 @@ +""" +System commands + +These are the default commands called by the system commandhandler +when various exceptions occur. If one of these commands are not +implemented and part of the current cmdset, the engine falls back +to a default solution instead. + +Some system commands are shown in this module +as a REFERENCE only (they are not all added to Evennia's +default cmdset since they don't currently do anything differently from the +default backup systems hard-wired in the engine). + +Overloading these commands in a cmdset can be used to create +interesting effects. An example is using the NoMatch system command +to implement a line-editor where you don't have to start each +line with a command (if there is no match to a known command, +the line is just added to the editor buffer). +""" +from game.gamesrc.commands.default.muxcommand import MuxCommand +from src.comms.models import Channel +from src.utils import create +from src.permissions.permissions import has_perm + +# The command keys the engine is calling +# (the actual names all start with __) +from src.commands.cmdhandler import CMD_NOINPUT +from src.commands.cmdhandler import CMD_NOMATCH +from src.commands.cmdhandler import CMD_MULTIMATCH +from src.commands.cmdhandler import CMD_NOPERM +from src.commands.cmdhandler import CMD_CHANNEL +from src.commands.cmdhandler import CMD_EXIT + + +# Command called when there is no input at line +# (i.e. an lone return key) + +class SystemNoInput(MuxCommand): + """ + This is called when there is no input given + """ + key = CMD_NOINPUT + + def func(self): + "Do nothing." + pass + +# +# Command called when there was no match to the +# command name +# + +class SystemNoMatch(MuxCommand): + """ + No command was found matching the given input. + """ + key = CMD_NOMATCH + + def func(self): + """ + This is given the failed raw string as input. + """ + self.caller.msg("Huh?") + +# +# Command called when there were mulitple matches to the command. +# +class SystemMultimatch(MuxCommand): + """ + Multiple command matches + """ + key = CMD_MULTIMATCH + + def func(self): + """ + argument to cmd is a comma-separated string of + all the clashing matches. + """ + self.caller.msg("Multiple matches found:\n %s" % self.args) + +class SystemNoPerm(MuxCommand): + """ + This is called when the user does not have the + correct permissions to use a particular command. + """ + key = CMD_NOPERM + + def func(self): + """ + This receives the original raw + input string (the one whose command failed to validate) + as argument. + """ + self.caller.msg("You are not allowed to do that.") + + +# Command called when the comman given at the command line +# was identified as a channel name, like there existing a +# channel named 'ooc' and the user wrote +# > ooc Hello! + +class SystemSendToChannel(MuxCommand): + """ + This is a special command that the cmdhandler calls + when it detects that the command given matches + an existing Channel object key (or alias). + """ + + key = CMD_CHANNEL + permissions = "cmd:use_channels" + + def parse(self): + channelname, msg = self.args.split(':', 1) + self.args = channelname.strip(), msg.strip() + + def func(self): + """ + Create a new message and send it to channel, using + the already formatted input. + """ + caller = self.caller + channelkey, msg = self.args + if not msg: + caller.msg("Say what?") + return + channel = Channel.objects.get_channel(channelkey) + if not channel: + caller.msg("Channel '%s' not found." % channelkey) + return + if not channel.has_connection(caller): + string = "You are not connected to channel '%s'." + caller.msg(string % channelkey) + return + if not has_perm(caller, channel, 'chan_send'): + string = "You are not permitted to send to channel '%s'." + caller.msg(string % channelkey) + return + msg = "[%s] %s: %s" % (channel.key, caller.name, msg) + msgobj = create.create_message(caller, msg, channels=[channel]) + channel.msg(msgobj) + +# +# Command called when the system recognizes the command given +# as matching an exit from the room. E.g. if there is an exit called 'door' +# and the user gives the command +# > door +# the exit 'door' should be traversed to its destination. + +class SystemUseExit(MuxCommand): + """ + Handles what happens when user gives a valid exit + as a command. It receives the raw string as input. + """ + key = CMD_EXIT + + def func(self): + """ + Handle traversing an exit + """ + caller = self.caller + if not self.args: + return + exit_name = self.args + exi = caller.search(exit_name) + if not exi: + return + destination = exi.attr('_destination') + if not destination: + return + if has_perm(caller, exit, 'traverse'): + caller.move_to(destination) + else: + caller.msg("You cannot enter") diff --git a/game/gamesrc/commands/default/tests.py b/game/gamesrc/commands/default/tests.py new file mode 100644 index 0000000000..0d885f9554 --- /dev/null +++ b/game/gamesrc/commands/default/tests.py @@ -0,0 +1,190 @@ +""" +This defines some test commands for use while testing the MUD. +Just remove these commands from the default state when they +are not needed anymore. +""" + +from django.db import IntegrityError +from src.comms.models import Msg +from game.gamesrc.commands.default.muxcommand import MuxCommand +from src.permissions import permissions +from src.utils import create + +# Test permissions + +class CmdTest(MuxCommand): + """ + test the command system + + Usage: + @test + + This command will echo back all argument or switches + given to it, showcasing the muxcommand style. + """ + + key = "@test" + aliases = ["@te", "@test all"] + permissions = "cmd:Immortals Wizards" + + # the muxcommand class itself handles the display + # so we just defer to it by not adding any function. + pass + + +class CmdTestPerms(MuxCommand): + """ + Test command - test permissions + + Usage: + @testperm [[lockstring] [=permstring]] + + With no arguments, runs a sequence of tests for the + permission system using the calling player's permissions. + + If is given, match caller's permissions + against these locks. If also is given, + match this against the given locks instead. + + """ + key = "@testperm" + permissions = "cmd:Immortals Wizards" + + def func(self, srcobj, inp): + """ + Run tests + """ + if srcobj.user.is_superuser: + srcobj.msg("You are a superuser. Permission tests are pointless.") + return + # create a test object + obj = create.create_object(None, "accessed_object") # this will use default typeclass + obj_id = obj.id + srcobj.msg("obj_attr: %s" % obj.attr("testattr")) + + # perms = ["has_permission", "has permission", "skey:has_permission", + # "has_id(%s)" % obj_id, "has_attr(testattr)", + # "has_attr(testattr, testattr_value)"] + + # test setting permissions + uprofile = srcobj.user.get_profile() + # do testing + srcobj.msg("----------------") + + permissions.set_perm(obj, "has_permission") + permissions.add_perm(obj, "skey:has_permission") + srcobj.msg(" keys:[%s] locks:[%s]" % (uprofile.permissions, obj.permissions)) + srcobj.msg("normal permtest: %s" % permissions.has_perm(uprofile, obj)) + srcobj.msg("skey permtest: %s" % permissions.has_perm(uprofile, obj, 'skey')) + + permissions.set_perm(uprofile, "has_permission") + srcobj.msg(" keys:[%s] locks:[%s]" % (uprofile.permissions, obj.permissions)) + srcobj.msg("normal permtest: %s" % permissions.has_perm(uprofile, obj)) + srcobj.msg("skey permtest: %s" % permissions.has_perm(uprofile, obj, 'skey')) + + # function tests + permissions.set_perm(obj, "has_id(%s)" % (uprofile.id)) + srcobj.msg(" keys:[%s] locks:[%s]" % (uprofile.permissions, obj.permissions)) + srcobj.msg("functest: %s" % permissions.has_perm(uprofile, obj)) + + uprofile.attr("testattr", "testattr_value") + permissions.set_perm(obj, "has_attr(testattr, testattr_value)") + srcobj.msg(" keys:[%s] locks:[%s]" % (uprofile.permissions, obj.permissions)) + srcobj.msg("functest: %s" % permissions.has_perm(uprofile, obj)) + + # cleanup of test permissions + permissions.del_perm(uprofile, "has_permission") + srcobj.msg(" cleanup: keys:[%s] locks:[%s]" % (uprofile.permissions, obj.permissions)) + obj.delete() + uprofile.attr("testattr", delete=True) + + +# Add/remove states + +EXAMPLE_STATE="game.gamesrc.commands.examples.example.EXAMPLESTATE" + +class CmdTestState(MuxCommand): + """ + Test command - add a state. + + Usage: + @teststate[/switch] [] + Switches: + add - add a state + clear - remove all added states. + list - view current state stack + reload - reload current state stack + + If no python path is given, an example state will be added. + You will know it worked if you can use the commands '@testcommand' + and 'smile'. + """ + + key = "@teststate" + alias = "@testingstate" + permissions = "cmd:Immortals Wizards" + + def func(self, source_object, inp): + """ + inp is the dict returned from MuxCommand's parser. + """ + switches = inp["switches"] + if not switches or switches[0] not in ["add", "clear", "list", "reload"]: + string = "Usage: @teststate[/add|clear|list|reload] []" + source_object.msg(string) + elif "clear" in switches: + source_object.statehandler.clear() + source_object.msg("All states cleared.") + return + elif "list" in switches: + string = "%s" % source_object.statehandler + source_object.msg(string) + elif "reload" in switches: + source_object.statehandler.load() + source_object.msg("States reloaded.") + else: #add + arg = inp["raw"] + if not arg: + arg = EXAMPLE_STATE + source_object.statehandler.add(arg) + string = "Added state '%s'." % source_object.statehandler.state.key + source_object.msg(string) + +class TestCom(MuxCommand): + """ + Test the command system + + Usage: + @testcom/create/list [channel] + """ + key = "@testcom" + permissions = "cmd:Immortals Wizards" + + def func(self): + "Run the test program" + caller = self.caller + + if 'create' in self.switches: + if self.args: + chankey = self.args + try: + channel = create.create_channel(chankey) + except IntegrityError: + caller.msg("Channel '%s' already exists." % chankey) + return + channel.connect_to(caller) + caller.msg("Created new channel %s" % chankey) + msgobj = create.create_message(caller.player, + "First post to new channel!") + channel.msg(msgobj) + + return + elif 'list' in self.switches: + msgresults = Msg.objects.get_messages_by_sender(caller) + string = "\n".join(["%s %s: %s" % (msg.date_sent, + [str(chan.key) for chan in msg.channels.all()], + msg.message) + for msg in msgresults]) + caller.msg(string) + return + caller.msg("Usage: @testcom/create channel") diff --git a/game/gamesrc/parents/__init__.py b/game/gamesrc/commands/default/unimplemented/__init__.py similarity index 100% rename from game/gamesrc/parents/__init__.py rename to game/gamesrc/commands/default/unimplemented/__init__.py diff --git a/src/commands/imc2.py b/game/gamesrc/commands/default/unimplemented/imc2.py similarity index 100% rename from src/commands/imc2.py rename to game/gamesrc/commands/default/unimplemented/imc2.py diff --git a/src/commands/irc.py b/game/gamesrc/commands/default/unimplemented/irc.py similarity index 100% rename from src/commands/irc.py rename to game/gamesrc/commands/default/unimplemented/irc.py diff --git a/src/commands/search.py b/game/gamesrc/commands/default/unimplemented/search.py similarity index 78% rename from src/commands/search.py rename to game/gamesrc/commands/default/unimplemented/search.py index 4c6520170d..c163b35e33 100644 --- a/src/commands/search.py +++ b/game/gamesrc/commands/default/unimplemented/search.py @@ -2,7 +2,8 @@ Implementation of the @search command that resembles MUX2. """ from django.db.models import Q -from src.objects.models import Object +#from src.objects.models import Object +from src.utils import OBJECT as Object from src import defines_global from src.cmdtable import GLOBAL_CMD_TABLE @@ -18,13 +19,13 @@ def _parse_restriction_split(source_object, restriction_split, search_low_dbnum, try: search_low_dbnum = int(restriction_split[1].strip()) except ValueError: - source_object.emit_to("Invalid value for low dbref limit.") + source_object.msg("Invalid value for low dbref limit.") return False if restriction_size >= 3: try: search_high_dbnum = int(restriction_split[2].strip()) except ValueError: - source_object.emit_to("Invalid value for high dbref limit.") + source_object.msg("Invalid value for high dbref limit.") return False return search_low_dbnum, search_high_dbnum @@ -38,40 +39,33 @@ def display_results(source_object, search_query): room_list = [] exit_list = [] player_list = [] - + # this bits gotta get totally redone for obj in search_query: - if obj.is_thing(): - thing_list.append(obj) - elif obj.is_room(): - room_list.append(obj) - elif obj.is_exit(): - exit_list.append(obj) - elif obj.is_player(): - player_list.append(obj) + thing_list.append(obj) # Render each section for different object types if thing_list: - source_object.emit_to("\n\rTHINGS:") + source_object.msg("\n\rTHINGS:") for thing in thing_list: - source_object.emit_to(thing.get_name(show_dbref=True, show_flags=True)) + source_object.msg(thing.name) if exit_list: - source_object.emit_to("\n\rEXITS:") + source_object.msg("\n\rEXITS:") for exit in exit_list: - source_object.emit_to(exit.get_name(show_dbref=True, show_flags=True)) + source_object.msg(exit.name) if room_list: - source_object.emit_to("\n\rROOMS:") + source_object.msg("\n\rROOMS:") for room in room_list: - source_object.emit_to(room.get_name(show_dbref=True, show_flags=True)) + source_object.msg(room.name) if player_list: - source_object.emit_to("\n\rPLAYER:") + source_object.msg("\n\rPLAYER:") for player in player_list: - source_object.emit_to(player.get_name(show_dbref=True, show_flags=True)) + source_object.msg(player.name) # Show the total counts by type - source_object.emit_to("\n\rFound: Rooms...%d Exits...%d Things...%d Players...%d" % ( + source_object.msg("\n\rFound: Rooms...%d Exits...%d Things...%d Players...%d" % ( len(room_list), len(exit_list), len(thing_list), @@ -104,7 +98,7 @@ def build_query(source_object, search_query, search_player, search_type, elif search_restriction == "player": search_query = search_query.filter(type=defines_global.OTYPE_PLAYER) else: - source_object.emit_to("Invalid class. See 'help SEARCH CLASSES'.") + source_object.msg("Invalid class. See 'help SEARCH CLASSES'.") return None elif search_type == "parent": search_query = search_query.filter(script_parent__iexact=search_restriction) @@ -128,11 +122,11 @@ def build_query(source_object, search_query, search_player, search_type, search_query = search_query.filter(zone=zone_obj) elif search_type == "power": # TODO: Need this once we have powers implemented. - source_object.emit_to("To be implemented...") + source_object.msg("To be implemented...") return None elif search_type == "flags": flag_list = search_restriction.split() - #source_object.emit_to("restriction: %s" % flag_list) + #source_object.msg("restriction: %s" % flag_list) for flag in flag_list: search_query = search_query.filter(Q(flags__icontains=flag) | Q(nosave_flags__icontains=flag)) @@ -171,9 +165,9 @@ def cmd_search(command): search_type = eq_split[0] restriction_split = eq_split[1].split(',') search_restriction = restriction_split[0].strip() - #source_object.emit_to("@search class=restriction") - #source_object.emit_to("eq_split: %s" % eq_split) - #source_object.emit_to("restriction_split: %s" % restriction_split) + #source_object.msg("@search class=restriction") + #source_object.msg("eq_split: %s" % eq_split) + #source_object.msg("restriction_split: %s" % restriction_split) try: search_low_dbnum, search_high_dbnum = _parse_restriction_split(source_object, @@ -186,19 +180,19 @@ def cmd_search(command): else: # @search player if len(first_check_split) == 1: - #source_object.emit_to("@search player") - #source_object.emit_to(first_check_split) + #source_object.msg("@search player") + #source_object.msg(first_check_split) search_player = first_check_split[0] else: - #source_object.emit_to("@search player class=restriction") - #source_object.emit_to(first_check_split) + #source_object.msg("@search player class=restriction") + #source_object.msg(first_check_split) search_player = first_check_split[0] eq_split = first_check_split[1].split('=', 1) search_type = eq_split[0] - #source_object.emit_to("eq_split: %s" % eq_split) + #source_object.msg("eq_split: %s" % eq_split) restriction_split = eq_split[1].split(',') search_restriction = restriction_split[0] - #source_object.emit_to("restriction_split: %s" % restriction_split) + #source_object.msg("restriction_split: %s" % restriction_split) try: search_low_dbnum, search_high_dbnum = _parse_restriction_split(source_object, @@ -210,11 +204,11 @@ def cmd_search(command): search_query = Object.objects.all() - #source_object.emit_to("search_player: %s" % search_player) - #source_object.emit_to("search_type: %s" % search_type) - #source_object.emit_to("search_restriction: %s" % search_restriction) - #source_object.emit_to("search_lowdb: %s" % search_low_dbnum) - #source_object.emit_to("search_highdb: %s" % search_high_dbnum) + #source_object.msg("search_player: %s" % search_player) + #source_object.msg("search_type: %s" % search_type) + #source_object.msg("search_restriction: %s" % search_restriction) + #source_object.msg("search_lowdb: %s" % search_low_dbnum) + #source_object.msg("search_highdb: %s" % search_high_dbnum) # Clean up these variables for comparisons. try: diff --git a/game/gamesrc/commands/default/unloggedin.py b/game/gamesrc/commands/default/unloggedin.py new file mode 100644 index 0000000000..21b511bef8 --- /dev/null +++ b/game/gamesrc/commands/default/unloggedin.py @@ -0,0 +1,295 @@ +""" +Commands that are available from the connect screen. +""" +import traceback +#from django.contrib.auth.models import User +from django.conf import settings +from django.contrib.auth.models import User +from src.players.models import PlayerDB +from src.objects.models import ObjectDB +from src.config.models import ConfigValue +from src.comms.models import Channel +from src.utils import create, logger, utils +from game.gamesrc.commands.default.muxcommand import MuxCommand + +class CmdConnect(MuxCommand): + """ + Connect to the game. + + Usage (at login screen): + connect + + Use the create command to first create an account before logging in. + """ + key = "connect" + aliases = ["conn", "con", "co"] + + def func(self): + """ + Uses the Django admin api. Note that unlogged-in commands + have a unique position in that their func() receives + a session object instead of a source_object like all + other types of logged-in commands (this is because + there is no object yet before the player has logged in) + """ + + session = self.caller + arglist = self.arglist + + if not arglist or len(arglist) < 2: + session.msg("\n\r Usage (without <>): connect ") + return + uemail = arglist[0] + password = arglist[1] + + # Match an email address to an account. + email_match = PlayerDB.objects.get_player_from_email(uemail) + # No playername match + if not email_match: + string = "The email '%s' does not match any accounts." % uemail + string += "\n\r\n\rIf you are new you should first create a new account " + string += "using the 'create' command." + session.msg(string) + return + # We have at least one result, so we can check the password. + player = email_match + if not player.user.check_password(password): + session.msg("Incorrect password.") + return + + # We are logging in, get/setup the player object controlled by player + + character = player.character + if not character: + # Create a new character object to tie the player to. This should + # usually not be needed unless the old character object was manually + # deleted. + default_home_id = ConfigValue.objects.conf(db_key="default_home") + default_home = ObjectDB.objects.get_id(default_home_id) + typeclass = settings.BASE_CHARACTER_TYPECLASS + character = create.create_object(typeclass=typeclass, + key=player.name, + location=default_home, + home=default_home, + player=player) + + character.db.FIRST_LOGIN = "True" + + # Getting ready to log the player in. + + # Check if this is the first time the + # *player* connects + if player.db.FIRST_LOGIN: + player.at_first_login() + del player.db.FIRST_LOGIN + + # check if this is the first time the *character* + # character (needs not be the first time the player + # does so, e.g. if the player has several characters) + if character.db.FIRST_LOGIN: + character.at_first_login() + del character.db.FIRST_LOGIN + + # actually do the login, calling + # customization hooks before and after. + player.at_pre_login() + character.at_pre_login() + + session.login(player) + + player.at_post_login() + character.at_post_login() + # run look + #print "character:", character, character.scripts.all(), character.cmdset.current + character.execute_cmd('look') + + +class CmdCreate(MuxCommand): + """ + Create a new account. + + Usage (at login screen): + create \"playername\" + + This creates a new player account. + + """ + key = "create" + aliases = ["cre", "cr"] + + def parse(self): + """ + The parser must handle the multiple-word player + name enclosed in quotes: + connect "Long name with many words" my@myserv.com mypassw + """ + super(CmdCreate, self).parse() + + self.playerinfo = [] + if len(self.arglist) < 3: + return + if len(self.arglist) > 3: + # this means we have a multi_word playername. pop from the back. + password = self.arglist.pop() + email = self.arglist.pop() + # what remains is the playername. + playername = " ".join(self.arglist) + else: + playername, email, password = self.arglist + + playername = playername.replace('"', '') # remove " + playername = playername.replace("'", "") + self.playerinfo = (playername, email, password) + + def func(self): + "Do checks and create account" + + session = self.caller + + try: + playername, email, password = self.playerinfo + except ValueError: + string = "\n\r Usage (without <>): create \"\" " + session.msg(string) + return + if not playername: + # entered an empty string + session.msg("\n\r You have to supply a longer playername, surrounded by quotes.") + return + if not email or not password: + session.msg("\n\r You have to supply an e-mail address followed by a password." ) + return + + if not utils.validate_email_address(email): + # check so the email at least looks ok. + session.msg("'%s' is not a valid e-mail address." % email) + return + + # Run sanity and security checks + + if PlayerDB.objects.get_player_from_name(playername) or User.objects.filter(username=playername): + # player already exists + session.msg("Sorry, there is already a player with the name '%s'." % playername) + elif PlayerDB.objects.get_player_from_email(email): + # email already set on a player + session.msg("Sorry, there is already a player with that email address.") + elif len(password) < 3: + # too short password + string = "Your password must be at least 3 characters or longer." + string += "\n\rFor best security, make it at least 8 characters long, " + string += "avoid making it a real word and mix numbers into it." + session.msg(string) + else: + # everything's ok. Create the new player account + try: + default_home_id = ConfigValue.objects.conf(db_key="default_home") + default_home = ObjectDB.objects.get_id(default_home_id) + + typeclass = settings.BASE_CHARACTER_TYPECLASS + permissions = settings.PERMISSION_PLAYER_DEFAULT + + new_character = create.create_player(playername, email, password, + permissions=permissions, + location=default_home, + typeclass=typeclass, + home=default_home) + new_character.db.FIRST_LOGIN = True + new_player = new_character.player + new_player.db.FIRST_LOGIN = True + + # join the new player to the public channel + pchanneldef = settings.CHANNEL_PUBLIC + if pchanneldef: + pchannel = Channel.objects.get_channel(pchanneldef[0]) + if not pchannel.connect_to(new_player): + string = "New player '%s' could not connect to public channel!" % new_player.key + logger.log_errmsg(string) + + string = "A new account '%s' was created with the email address %s. Welcome!" + string += "\n\nYou can now log with the command 'connect %s '." + session.msg(string % (playername, email, email)) + except Exception: + # we have to handle traceback ourselves at this point, if + # we don't, errors will give no feedback. + string = "%s\nThis is a bug. Please e-mail an admin if the problem persists." + session.msg(string % (traceback.format_exc())) + logger.log_errmsg(traceback.format_exc()) + +class CmdQuit(MuxCommand): + """ + We maintain a different version of the quit command + here for unconnected players for the sake of simplicity. The logged in + version is a bit more complicated. + """ + key = "quit" + aliases = ["q", "qu"] + + def func(self): + "Simply close the connection." + session = self.caller + session.msg("Good bye! Disconnecting ...") + session.handle_close() + +class CmdUnconnectedLook(MuxCommand): + """ + This is an unconnected version of the look command for simplicity. + All it does is re-show the connect screen. + """ + key = "look" + aliases = "l" + + def func(self): + "Show the connect screen." + try: + self.caller.game_connect_screen() + except Exception: + self.caller.msg("Connect screen not found. Enter 'help' for aid.") + +class CmdUnconnectedHelp(MuxCommand): + """ + This is an unconnected version of the help command, + for simplicity. It shows a pane or info. + """ + key = "help" + aliases = ["h", "?"] + + def func(self): + "Shows help" + + string = \ + """Welcome to Evennia! + +Commands available at this point: + create - create a new account + connect - login with an existing account + look - re-show the connect screen + help - this help + quit - leave + +To login to the system, you need to do one of the following: + +1) If you have no previous account, you need to use the 'create' + command followed by your desired character name (in quotes), your + e-mail address and finally a password of your choice. Like + this: + + > create "Anna the Barbarian" anna@myemail.com tuK3221mP + + It's always a good idea (not only here, but everywhere on the net) + to not use a regular word for your password. Make it longer than + 3 characters (ideally 6 or more) and mix numbers and capitalization + into it. Now proceed to 2). + +2) If you have an account already, either because you just created + one in 1) above, or you are returning, use the 'connect' command + followed by the e-mail and password you previously set. + Example: + + > connect anna@myemail.com tuK3221mP + + This should log you in. Run 'help' again once you're logged in + to get more aid. Welcome to Evennia! + +You can use the 'look' command if you want to see the connect screen again. +""" + self.caller.msg(string) diff --git a/game/gamesrc/commands/examples/cmdset_red_button.py b/game/gamesrc/commands/examples/cmdset_red_button.py new file mode 100644 index 0000000000..165dae5978 --- /dev/null +++ b/game/gamesrc/commands/examples/cmdset_red_button.py @@ -0,0 +1,292 @@ +""" +This defines the cmdset for the red_button. Here we have defined +the commands and the cmdset in the same module, but if you +have many different commands to merge it if often better +to define the cmdset separately, picking and choosing from +among the available commands as to what should be included in the +cmdset - this way you can often re-use the commands too. +""" + +import random +from src.commands.cmdset import CmdSet +from game.gamesrc.commands.basecommand import Command + +# Some simple commands for the red button + +#------------------------------------------------------------ +# Commands defined for the red button +#------------------------------------------------------------ + +class CmdNudge(Command): + """ + Try to nudge the button's lid + + Usage: + nudge lid + + This command will have you try to + push the lid of the button away. + """ + + key = "nudge lid" # two-word command name! + alias = ["nudge"] + + def func(self): + """ + nudge the lid. + """ + rand = random.random() + if rand < 0.5: + string = "You nudge at the lid. It seems stuck." + elif 0.5 <= 0.5 < 0.7: + string = "You move the lid back and forth. It won't budge." + else: + string = "You manage to get a nail under the lid. It pops open." + self.obj.open_lid() + self.caller.msg(string) + +class CmdPush(Command): + """ + Push the red button + + Usage: + push button + + """ + key = "push button" + aliases = ["push", "press button", "press"] + + def func(self): + """ + Note that we choose to implement this with checking for + if the lid is open/closed. This is because this command + is likely to be tries regardless of the state of the lid. + + An alternative would be to make two versions of this command + and tuck them into the cmdset linked to the Open and Closed + lid-state respectively. + + """ + + if self.obj.db.lid_open: + string = "You reach out to press the big red button ..." + string += "\n\nA BOOM! A bright light blinds you!" + string += "\nThe world goes dark ..." + self.caller.msg(string) + self.obj.press_button(self.caller) + self.caller.location.msg_contents("%s presses the button. BOOM! %s is blinded by a flash!" % + (self.caller.name, self.caller.name), exclude=self.caller) + else: + string = "You cannot push the button - there is a glass lid covering it." + self.caller.msg(string) + + +class CmdSmashGlass(Command): + """ + smash glass + + Usage: + smash glass + + Try to smash the glass of the button. + """ + + key = "smash glass" + aliases = ["smash lid", "break lid", "smash"] + + def func(self): + """ + The lid won't open, but there is a small chance + of causing the lamp to break. + """ + rand = random.random() + + if rand < 0.2: + string = "You smash your hand against the glass" + string += " with all your might. The lid won't budge" + string += " but you cause quite the tremor through the button's mount." + self.caller.msg(string) # have to be called before breakage since that + # also gives a return feedback to the room. + self.obj.break_lamp() + return + elif rand < 0.6: + string = "You hit the lid hard. It doesn't move an inch." + else: + string = "You place a well-aimed fist against the glass of the lid." + string += "Unfortunately all you get is a pain in your hand. Maybe" + string += " you should just try to open the lid instead?" + self.caller.msg(string) + self.caller.location.msg_contents("%s tries to smash the glass of the button." % + (self.caller.name), exclude=self.caller) + +class CmdOpenLid(Command): + """ + open lid + + Usage: + open lid + + """ + + key = "open lid" + aliases = ["open button", 'open'] + + def func(self): + "simply call the right function." + + if self.obj.db.lid_locked: + self.caller.msg("This lid seems locked in place for the moment.") + return + + self.caller.location.msg_contents("%s opens the lid of the button." % + (self.caller.name), exclude=self.caller) + self.obj.open_lid() + +class CmdCloseLid(Command): + """ + close the lid + + Usage: + close lid + + Closes the lid of the red button. + """ + + key = "close lid" + aliases = ["close"] + + def func(self): + "Close the lid" + self.obj.close_lid() + self.caller.location.msg_contents("%s closes the button's lid." % + (self.caller.name), exclude=self.caller) + +class CmdBlindLook(Command): + """ + Looking around in darkness + + Usage: + look + + ... not that there's much to see in the dark. + + """ + + key = "look" + aliases = ["l", "get", "examine", "ex", "feel", "listen"] + def func(self): + "This replaces all the senses when blinded." + + # we decide what to reply based on which command was + # actually tried + + if self.cmdstring == "get": + string = "You fumble around blindly without finding anything." + elif self.cmdstring == "examine": + string = "You try to examine your surroundings, but can't see a thing." + elif self.cmdstring == "listen": + string = "You are deafened by the boom." + elif self.cmdstring == "feel": + string = "You fumble around, hands outstretched. You bump your knee." + else: + # trying to look + string = "You are temporarily blinded by the flash. " + string += "Until it wears off, all you can do is feel around blindly." + self.caller.msg(string) + self.caller.location.msg_contents("%s stumbles around, blinded." % + (self.caller.name), exclude=self.caller) + +class CmdBlindHelp(Command): + """ + Help function while in the blinded state + + Usage: + help + + """ + key = "help" + aliases = "h" + def func(self): + "Give a message." + self.caller.msg("You are beyond help ... until you can see again.") + + +#--------------------------------------------------------------- +# Command sets for the red button +#--------------------------------------------------------------- + + +# We next tuck these commands into their respective command sets. +# (note that we are overdoing the cdmset separation a bit here +# to show how it works). + +class DefaultCmdSet(CmdSet): + """ + The default cmdset always sits + on the button object and whereas other + command sets may be added/merge onto it + and hide it, removing them will always + bring it back. It's added to the object + using obj.cmdset.add_default(). + """ + key = "RedButtonDefault" + mergetype = "Union" # this is default, we don't really need to put it here. + + def at_cmdset_creation(self): + "Init the cmdset" + self.add(CmdPush()) + +class LidClosedCmdSet(CmdSet): + """ + A simple cmdset tied to the redbutton object. + + It contains the commands that launches the other + command sets, making the red button a self-contained + item (i.e. you don't have to manually add any + scripts etc to it when creating it). + """ + key = "LidClosedCmdSet" + # default Union is used *except* if we are adding to a + # cmdset named RedButtonOpen - this one we replace + # completely. + key_mergetype = {"LidOpenCmdSet": "Replace"} + + def at_cmdset_creation(self): + "Populates the cmdset when it is instantiated." + self.add(CmdNudge()) + self.add(CmdSmashGlass()) + self.add(CmdOpenLid()) + +class LidOpenCmdSet(CmdSet): + """ + This is the opposite of the Closed cmdset. + """ + key = "LidOpenCmdSet" + # default Union is used *except* if we are adding to a + # cmdset named RedButtonClose - this one we replace + # completely. + key_mergetype = {"LidClosedCmdSet": "Replace"} + + def at_cmdset_creation(self): + "setup the cmdset (just one command)" + self.add(CmdCloseLid()) + +class BlindCmdSet(CmdSet): + """ + This is the cmdset added to the *player* when + the button is pushed. + """ + key = "BlindCmdSet" + # we want it to completely replace all normal commands + # until the timed script removes it again. + mergetype = "Replace" + # we want to stop the player from walking around + # in this blinded state, so we hide all exits too. + # (channel commands will still work). + no_exits = True # keep player in the same room + no_objs = True # don't allow object commands + + def at_cmdset_creation(self): + "Setup the blind cmdset" + self.add(CmdBlindLook()) + self.add(CmdBlindHelp()) diff --git a/game/gamesrc/commands/examples/example.py b/game/gamesrc/commands/examples/example.py deleted file mode 100644 index 0be240df64..0000000000 --- a/game/gamesrc/commands/examples/example.py +++ /dev/null @@ -1,129 +0,0 @@ -""" -This is an example command module for showing the pluggable command -system in action. - -You'll need to make sure that this or any new modules you create are -added to game/settings.py under CUSTOM_COMMAND_MODULES or -CUSTOM_UNLOGGED_COMMAND_MODULES, which are tuples of module import -path strings. See src/config_defaults.py for more details. - -E.g. to add this example command for testing, your entry in -game/settings.py would look like this: - -CUSTOM_COMMAND_MODULES = ('game.gamesrc.commands.examples.example',) - -(note the extra comma at the end to make this into a Python -tuple. It's only needed if you have only one entry.) You need to -restart the Evennia server before new files are recognized. Once this -is done once, you don't have to restart again, just use -@reload/commands to use the changes you make to your modules. -""" - -# This is the common global CommandTable object which we'll be adding the -# example command(s) to. -from src.cmdtable import GLOBAL_CMD_TABLE - -# The main command definition. We can add any number of commands this way in the -# same file. -def cmd_example(command): - """ - example - example command - - Usage: - @testcommand[/switches] - - switches: - (can be any string, e.g. /test1 or /tom/sarah/peter) - - This is the help text for the 'example' command, a command to - show how the pluggable command system works. - - For testing, you can try calling this with different switches and - arguments, like - > example/test/test2 Hello - and see what is returned. - - [[example_auto_help]] - - This is a subtopic to the main example command help entry. It is - done by the help system splitting the text by markup of the - form [ [title ] ] (with no spaces between the square brackets) - - Note that this help entry is auto-added as long as HELP_AUTO - is not set to False in your game/settings.py file. - Any number of subtopics like this one can be added on the fly - using the auto-help system. See help topics on 'help' and - 'help_markup' for more information and options. - """ - - # By building one big string and passing it at once, we cut down on a lot - # of emit_to() calls, which is generally a good idea. - retval = "----- Example Command -----\n\r" - # source_object is the object executing the command - retval += " Source object: %s\n\r" % command.source_object - # session points to a user Session (session.py) object (if applicable) - retval += " Session: %s\n\r" % command.session - # The raw, un-parsed input - retval += " Raw input: %s\n\r" % command.raw_input - # The command name being executed - retval += " Command: %s\n\r" % command.command_string - # A list of switches provided (if any) - retval += " Switches: %s\n\r" % command.command_switches - # A string with any arguments provided with the command - retval += " Arguments: %s\n\r" % command.command_argument - # The function that was looked up via cmdtable.py - retval += " Function: %s\n\r" % command.command_function - # Extra variables passed with cmdtable.py's add_command(). - retval += " Extra vars: %s\n\r" % command.extra_vars - - # Some more info for more advanced commands. - if not command.command_switches and \ - command.command_argument: - retval += "\n Obs: When no switches, also multi-word\n" - retval += " command names are possible. Max allowed\n" - retval += " length is set in game/settings.py.\n" - retval += " So if there exist a matching command in the\n" - retval += " command table, Evennia would also allow\n" - retval += " the following as valid commands (and the\n" - retval += " argument list would shrink accordingly):\n" - multi = "" - for arg in command.command_argument.split(): - multi += " %s" % arg - retval += " %s%s\n" % (command.command_string, multi) - - # send string to player - command.source_object.emit_to(retval) - -# Add the command to the common global command table. Note that -# this will auto-create help entries 'example' and -# "example_auto_help" for us. -GLOBAL_CMD_TABLE.add_command("@testcommand", cmd_example) - -# -# another simple example -# -def cmd_emote_smile(command): - """ - smile - break a smile - - Usage: - smile - - A 'smile' emote. - """ - #get the source object (that is, the player using the command) - source_object = command.source_object - #find name of caller - name = source_object.get_name(show_dbref=False) - #get the location caller is at - location = source_object.get_location() - #build the emote - text = "%s smiles." % name - #emit the emote to everyone at the current location - location.emit_to_contents(text) - -# add to global command table (we probably want an auto-help entry -# for this, but we are turning auto-help off anyway, to show -# how it works) -GLOBAL_CMD_TABLE.add_command('smile', cmd_emote_smile, - auto_help_override=False) diff --git a/game/gamesrc/commands/examples/misc_tests.py b/game/gamesrc/commands/examples/misc_tests.py deleted file mode 100644 index a9e154b266..0000000000 --- a/game/gamesrc/commands/examples/misc_tests.py +++ /dev/null @@ -1,136 +0,0 @@ -""" -This module contains various commands for testing some -of Evennia's subsystems. They were used for initial testing -but are also instructive for playing around with to learn -how different systems work. See also state_example.py. - -To make these commands available in-game, add this module -to the CUSTOM_COMMAND_MODULES tuple in game/settings.py -as 'game.gamesrc.commands.examples.misc_tests'. - -None of these commands are auto-added to the help database -(they have no docstrings) in order to help make it clean. -""" - -from src.cmdtable import GLOBAL_CMD_TABLE - -#------------------------------------------------------------ -# Tests of the event system -#------------------------------------------------------------ - -def cmd_testevent(command): - # - # This test allows testing the event system - # - # Usage: - # @testevent [pid] - # - # Without argument, this command creates - # a dummy event in the process table. - # Use @ps to see it. Give the equivalent - # pid to remove it again (careful though, - # this command can also remove useful - # events if you give the wrong pid). - # - from src import events - from src import scheduler - - source_object = command.source_object - - if not source_object.is_superuser(): - # To avoid accidental access to process table - source_object.emit_to("This command is superuser only.") - return - - if not command.command_argument: - # No argument given; create a new test event. - event = events.IntervalEvent() - event.description = "Test event created with @testevent." - event.repeats = 3 - event.interval = 5 - pid = scheduler.add_event(event) - string = "Event with pid %s added. " % pid - string += "It repeats %i times and waits " % event.repeats - string += "for %i seconds between each repeat." % event.interval - string += "After all repeats, it will delete itself." - string += "\nUse @ps to see it and give this " - string += "command with the pid as argument to delete it." - source_object.emit_to(string) - else: - # An argument given; assume this is a pid. - try: - pid = int(command.command_argument) - except: - source_object.emit_to("Not a valid argument. You must give a number.") - return - if pid < 3: - string = "This low pid might belong to a system process, \n" - string += "so as a safety measure you cannot delete it using \n" - string += "this test command. Use @delevent instead." - source_object.emit_to(string) - return - pid = command.command_argument - scheduler.del_event(pid) - string = "Event with pid %s removed (if it existed)." % pid - string += " Confirm this worked using @ps." - source_object.emit_to(string) -GLOBAL_CMD_TABLE.add_command("@testevent", cmd_testevent, - auto_help_override=False) - - -#------------------------------------------------------------ -# Test of Cache system -#------------------------------------------------------------ - -def cmd_testcache(command): - # - # Tests the cache system by writing to it - # back and forth several times. - # - # Usage: - # @testcache [get] - # - # Use without 'get' to store test data in - # caches and with 'get' to read them back - # and make sure they all saved as they - # should. You might also want to - # try shut down the server between - # calls to make sure the persistent - # cache does survive the shutdown. - - from src.cache import cache - from src import gametime - - source_object = command.source_object - switches = command.command_switches - - s1 = "Value: Cache: OK" - s2 = "Value: PCache 1 (set using property assignment): OK" - s3 = "Value: PCache 2 (set using function call): OK" - if switches and "get" in switches: - # Reading from cache - source_object.emit_to("Reading from cache ...") - cache.load_pcache() - cache_vol = source_object.cache.testcache - source_object.emit_to("< volatile cache:\n %s" % cache_vol) - cache_perm = source_object.pcache.testcache_perm - source_object.emit_to("< persistent cache 1/2:\n %s" % cache_perm) - cache_perm2 = cache.get_pcache("permtest2") - source_object.emit_to("< persistent cache 2/2:\n %s" % cache_perm2) - else: - # Saving to cache - source_object.emit_to("Save to cache ...") - source_object.cache.testcache = s1 - # using two different ways to set pcache - source_object.pcache.testcache_perm = s2 - cache.set_pcache("permtest2", s3) - - source_object.emit_to("> volatile cache:\n %s" % s1) - source_object.emit_to("> persistent cache 1/2:\n %s" % s2) - source_object.emit_to("> persistent cache 2/2:\n %s" % s3) - cache.save_pcache() - string = "Caches saved. Use /get as a switch to read them back." - source_object.emit_to(string) - source_object.emit_to("Running Gametime: %i" % gametime.time()) -GLOBAL_CMD_TABLE.add_command("@testcache", cmd_testcache, - auto_help_override=False) diff --git a/game/gamesrc/commands/examples/state_example.py b/game/gamesrc/commands/examples/state_example.py deleted file mode 100644 index ec95dea76c..0000000000 --- a/game/gamesrc/commands/examples/state_example.py +++ /dev/null @@ -1,333 +0,0 @@ -""" -Example of using the state system. The State system allows a player -object to be 'trapped' in a special environment where different -commands are available than normal. This is very useful in order to -implement anything from menus and combat states to npc-conversational -choices and inline text-editors. - -This example uses the State system to create a simple menu. - -To test out this example, add this module to the -CUSTOM_COMMAND_MODULES tuple in your game/settings.py as -'game.gamesrc.commands.examples.state_example' (see ./example.py for -another example). You need to restart the Evennia server before new -files are recognized. - -Next enter the mud and give the command - -> @testmenu - -Note that the help entries related to this little menu are not part of -the normal help database, they are stored with the state and only -accessible from inside it. Try 'help entermenu' from outside the state -and 'help' and 'info' from inside the menu to see the auto-help system -in action. - -To further test the state system, try the command - -> @teststate - -This takes arguments between 1-6 to set up various states with varying -access to different global commands. - -See also misc_tests.py for other tests. -""" - -# This is the normal command table, accessible by default -from src.cmdtable import GLOBAL_CMD_TABLE - -# The statetable contains sets of cmdtables that is made available -# only when we are in a particular state (possibly overriding -# same-named commands in GLOBAL_CMD_TABLE). -from src.statetable import GLOBAL_STATE_TABLE - -# -# Implementing a simple 'menu' state -# - -#the name of our state, to make sure it's the same everywhere -STATENAME = 'menu' - -# -# 'entry' command. This takes the player from the normal game -# mode into the menu state. This must be added to the -# GLOBAL_CMD_TABLE like any other command. -# -def cmd_entermenu(command): - """ - entermenu - enter the example menu - - Usage: - entermenu - - This is the 'entry' command that takes the player from the normal - gameplay mode into the 'menu' state. - """ - # get the player object calling the command - source_object = command.source_object - - # this is important: we use the set_state() command - # to shift the player into a state named 'menu'. Other useful - # access functions on source_object are get_state() - # and clear_state(), the latter returns the player to - # the normal mode of gameplay. - source_object.set_state(STATENAME) - - #show a welcome text . - string = """ - Welcome to the Demo menu! In this small demo all you can do is - select one of the two options so it changes colour. This is just - intended to show off the possibilities of the state system. More - interesting things should of course happen in a real menu. - - Use @exit to leave the menu. - """ - source_object.emit_to(string) - - # show the menu - source_object.execute_cmd('menu') - -# -# Below are commands only available while in the 'menu' state. -# Note that the _doc__ strings of the functions -# can be read as help entries when in the menu. -# -def menu_cmd_option1(command): - """ - option1 - This command, obviously, selects the first option. - """ - source_object = command.source_object - print_menu(source_object, 1) - -def menu_cmd_option2(command): - """ - option2 - This command selects the second option. Duh. - """ - source_object = command.source_object - print_menu(source_object, 2) - -def menu_cmd_menu(command): - """ - menu - - Clears the options and redraws the menu. - - [[autohelp]] - - Auto-help - - This is an extra topic to test the auto-help functionality. The state-help - system supports nested ('related') topics using [ [subtopic] ] markup, - just like the normal help index does. - """ - source_object = command.source_object - print_menu(source_object) - -# -# helper function -# -def print_menu(source_obj, choice=None): - """ - Utility function to print the menu. More interesting things - would happen here in a real menu. - """ - - if choice == 1: - #ansi colouring; see src.ansi - chtext = "%s> option1\n %soption2" % ('%ch%cy','%cn%cy') - elif choice == 2: - chtext = " %soption1\n%s> option2" % ('%cn%cy','%ch%cy') - else: - chtext = " %soption1\n option2" % ('%cn%cy') - - string ="\n%sMenu: \n%s\n %shelp \n @exit" % ('%ch%cr', chtext, '%cn%cy') - source_obj.emit_to(string) - -# Add the 'entry' command to the normal command table -GLOBAL_CMD_TABLE.add_command("@testmenu", cmd_entermenu, - auto_help_override=False) - -# create the state. We make sure the player can exit it at -# any time by @exit. -GLOBAL_STATE_TABLE.add_state(STATENAME, exit_command=True) - -# Add the menu commands to the state table by tying them to the 'menu' -# state. It is important that the name of the state matches what we -# set the player-object to in the 'entry' command. -GLOBAL_STATE_TABLE.add_command(STATENAME, "option1", menu_cmd_option1) -GLOBAL_STATE_TABLE.add_command(STATENAME, "option2", menu_cmd_option2) -GLOBAL_STATE_TABLE.add_command(STATENAME, "menu", menu_cmd_menu) - - -# -# enterstate - testing the depth of the state system -# - -# This is a test suite that shows off all the features of the state -# system. It sets up a test command @test_state that takes an -# argument 1-6 for moving into states with different -# characteristics. Note that the only difference as to how the various -# states are created lies in the options given to the add_state() -# function. Use @exit to leave any state. - -# defining the test-state names so they are the same everywhere -TSTATE1 = 'no_globals' -TSTATE2 = 'all_globals' -TSTATE3 = 'include_some_globals' -TSTATE4 = 'exclude_some_globals' -TSTATE5 = 'global_allow_exits' -TSTATE6 = 'noglobal_allow_exits_obj_cmds' - -# -#the test command 'enterstate' -# -def cmd_test_state(command): - """ - @teststate - testing the state system - - Usage: @teststate [1 - 6] - - Give arguments 1-6 to enter different game states. Use @exit to - get out of the state at any time. - - 1: A very limited state; only contains the 'test' state command. - 2: All global commands are included (so this should be the same as - normal operation, except you cannot traverse exits and use - object-based cmds) - 3: /Only/ the global commands 'get' and 'inventory' are included - into the state. - 4: All global commands /except/ 'get' and 'inventory' are available - 5: All global commands availabe + ability to traverse exits (not use - object-based cmds). - 6: Only the 'test' command available, but ability to - both traverse exits and use object-based cmds. - - Ideas for in-game use: - 1: Try out the '@testmenu' command for an example of this state. - 2: Could be used in order to stop someone from moving despite exits - being open (tied up? In combat?) - 3: someone incapacitated or blinded might get only limited commands - available - 4: in e.g. a combat state, things like crafting should not be - possible. - 5: Pretty much default operation, just removing some global commands. - Maybe limiting the use of magical weapons in a room or similar. - 6: A state of panic - You can move, but not take in your surroundings. - - ... the possibilities are endless. - """ - source_object = command.source_object - args = command.command_argument - # check for missing arguments - if not args: - source_object.emit_to("Usage: @teststate [1 - 6]") - return - # build up a return string - string = "\n Entering state ... \nThis state includes the" - string += " commands 'test', 'help', '@exit' and " - arg = args.strip() - - # step through the various options - if arg == '1': - string += "no global commands at all. \nWith some more state commands, " - string += "this state would work well for e.g. a " - string += "combat state or a menu where the player don't need access " - string += "to the normal command definitions. Take a special " - string += "look at the help command, which is in fact a " - string += "state-only version of the normal help." - state = TSTATE1 - elif arg == '2': - string += "all global commands. You should be able to do " - string += "everything as normal, but not move around." - state = TSTATE2 - elif arg == '3': - string += "the global commands 'inv' and 'get' only." - state = TSTATE3 - elif arg == '4': - string += "all global commands *except* 'inv' and 'get' (try " - string += "using them). \nThis allows you to disable commands that " - string += "should not be possible at a certain time (like starting " - string += "to craft while in the middle of a fight or something)." - state = TSTATE4 - elif arg == '5': - string += "all global commands as well as the ability to traverse " - string += "exits. You do not have the ability to use commands " - string += "defined on objects though." - state = TSTATE5 - elif arg == '6': - string += "no globals at all, but you have the ability to both " - string += "use exits and commands on items. \nThis would maybe be " - string += "interesting for a 'total darkness' state or maybe a " - string += "'panic' state where you can move around but cannot " - string += "actually take in your surroundings." - state = TSTATE6 - else: - source_object.emit_to("Usage: enterstate 1 - 6") - return - #set the state - source_object.set_state(state) - info = "%s\n (Now in state %s: '%s' ... use @exit to leave the state.)" - source_object.emit_to(info % (string, arg, state)) -# -# define a simple command to include in all states. -# -def cmd_instate_cmd(command): - """ - test - - Usage: - test - - This is the help text for the test command (created with the - auto_help sytem). This is a state-only command that does not - exist outside this state. Since this state is completely isolated - from the normal gameplay, commands can also harmlessly redefine - any normal command - so if there was a normal command named - 'test', it would remain unchanged when we leave the state. - """ - command.source_object.emit_to("This state command (test) works!") - -# -# Create the test states -# - -#define some global commands to filter for -CMDFILTER = ['get', 'inventory'] - -#1: A simple, basic state with no global commands -GLOBAL_STATE_TABLE.add_state(TSTATE1, exit_command=True) - -#2: Include all normal commands in the state -GLOBAL_STATE_TABLE.add_state(TSTATE2, exit_command=True, global_cmds='all') - -#3: Include only the two global commands in cmdfilter -GLOBAL_STATE_TABLE.add_state(TSTATE3, exit_command=True, - global_cmds='include', global_filter=CMDFILTER) - -#4: Include all global commands except the ones in cmdfilter -GLOBAL_STATE_TABLE.add_state(TSTATE4, exit_command=True, - global_cmds='exclude', global_filter=CMDFILTER) - -#5: Include all global commands + ability to traverse exits -GLOBAL_STATE_TABLE.add_state(TSTATE5, exit_command=True, - global_cmds='all', - allow_exits=True) - -#6: No global commands, allow exits and commands defined on objects. -GLOBAL_STATE_TABLE.add_state(TSTATE6, exit_command=True, - allow_exits=True, allow_obj_cmds=True) - -#append the "test" function to all states -GLOBAL_STATE_TABLE.add_command(TSTATE1, 'test', cmd_instate_cmd) -GLOBAL_STATE_TABLE.add_command(TSTATE2, 'test', cmd_instate_cmd) -GLOBAL_STATE_TABLE.add_command(TSTATE3, 'test', cmd_instate_cmd) -GLOBAL_STATE_TABLE.add_command(TSTATE4, 'test', cmd_instate_cmd) -GLOBAL_STATE_TABLE.add_command(TSTATE5, 'test', cmd_instate_cmd) -GLOBAL_STATE_TABLE.add_command(TSTATE6, 'test', cmd_instate_cmd) - -#create the entry function for testing all states -GLOBAL_CMD_TABLE.add_command('@teststate', cmd_test_state) - - diff --git a/game/gamesrc/events/example.py b/game/gamesrc/events/example.py deleted file mode 100644 index 67aae71104..0000000000 --- a/game/gamesrc/events/example.py +++ /dev/null @@ -1,67 +0,0 @@ -""" -Example of the event system. To try it out, make sure to import it from somewhere -covered by @reload (like the script parent). Create an object inheriting -the red_button parent to see its effects (e.g. @create button=examples/red_button) - -Technically the event don't contain any game logics, all it does is locate all -objects inheriting to a particular script parent and calls one of its functions -at a regular interval. - -Note that this type of event will cause *all* red buttons to blink at the same -time, regardless when they were created. This is a very efficient way -to do it (it is also very useful for global events like weather patterns -and day-night cycles), but you can also add events directly to individual objecs -(see the example event in gamesrc/parents/examples/red_button) -""" - -import traceback -from src.events import IntervalEvent -from src import scheduler -from src.objects.models import Object - -#the logger is useful for debugging -from src import logger - -class EventBlinkButton(IntervalEvent): - """ - This event lets the button flash at regular intervals. - """ - def __init__(self): - """ - Note that we do NOT make this event persistent across - reboots since we are actually creating it (i.e. restarting it) - every time the module is reloaded. - """ - super(EventBlinkButton, self).__init__() - self.name = 'event_blink_red_button' - #how often to blink, in seconds - self.interval = 30 - #the description is seen when you run @ps in-game. - self.description = "Blink red buttons regularly." - - def event_function(self): - """ - This stub function is automatically fired every self.interval seconds. - - In this case we do a search for all objects inheriting from the correct - parent and call a function on them. - - Note that we must make sure to handle all tracebacks in this - function to avoid trouble. - """ - #find all objects inheriting from red_button (parents are per definition - #stored with the gamesrc/parent/ drawer as a base) - parent = 'examples.red_button' - buttons = Object.objects.global_object_script_parent_search(parent) - - for b in buttons: - try: - b.scriptlink.blink() - except: - # Print all tracebacks to the log instead of letting them by. - # This is important, we must handle these exceptions gracefully! - logger.log_errmsg(traceback.print_exc()) - -#create and add the event to the global handler -blink_event = EventBlinkButton() -scheduler.add_event(blink_event) diff --git a/game/gamesrc/parents/base/__init__.py b/game/gamesrc/objects/__init__.py similarity index 100% rename from game/gamesrc/parents/base/__init__.py rename to game/gamesrc/objects/__init__.py diff --git a/game/gamesrc/objects/baseobjects.py b/game/gamesrc/objects/baseobjects.py new file mode 100644 index 0000000000..b29bc43039 --- /dev/null +++ b/game/gamesrc/objects/baseobjects.py @@ -0,0 +1,158 @@ +""" +These are the base object typeclasses, a convenient shortcut to the +objects in src/objects/objects.py. You can start building your game +from these bases if you want. + +To change these defaults to point to some other object, +change some or all of these variables in settings.py: +BASE_OBJECT_TYPECLASS +BASE_CHARACTER_TYPECLASS +BASE_ROOM_TYPECLASS +BASE_EXIT_TYPECLASS +BASE_PLAYER_TYPECLASS + +Some of the main uses for these settings are not hard-coded in +Evennia, rather they are convenient defaults for in-game commands +(which you may change) Example would be build commands like '@dig' +knowing to create a particular room-type object). + +New instances of Objects (inheriting from these typeclasses) +are created with src.utils.create.create_object(typeclass, ...) +where typeclass is the python path to the class you want to use. +""" +from src.objects.objects import Object as BaseObject +from src.objects.objects import Character as BaseCharacter +from src.objects.objects import Room as BaseRoom +from src.objects.objects import Exit as BaseExit +from src.players.player import Player as BasePlayer + +class Object(BaseObject): + """ + This is the root typeclass object, implementing an in-game Evennia + game object, such as having a location, being able to be + manipulated or looked at, etc. If you create a new typeclass, it + must always inherit from this object (or any of the other objects + in this file, since they all actually inherit from BaseObject, as + seen in src.object.objects). + + The BaseObject class implements several hooks tying into the game + engine. By re-implementing these hooks you can control the + system. You should never need to re-implement special Python + methods, such as __init__ and especially never __getattribute__ and + __setattr__ since these are used heavily by the typeclass system + of Evennia and messing with them might well break things for you. + + Hooks (these are class methods, so their arguments should also start with self): + at_object_creation() - only called once, when object is first created. + Almost all object customizations go here. + at_first_login() - only called once, the very first time user logs in. + at_pre_login() - called every time the user connects, after they have + identified, just before the system actually logs them in. + at_post_login() - called at the end of login, just before setting the + player loose in the world. + at_disconnect() - called just before the use is disconnected (this is also + called if the system determines the player lost their link) + at_object_delete() - called just before the database object is permanently + deleted from the database with obj.delete(). Note that cleaning out contents + and deleting connected exits is not needed, this is handled + automatically when doing obj.delete(). If this method returns + False, deletion is aborted. + + at_before_move(destination) - called by obj.move_to() just before moving object to the destination. + If this method returns False, move is cancelled. + announce_move_from(destination) - called while still standing in the old location, + if obj.move_to() has argument quiet=False. + announce_move_to(source_location) - called after move, while standing in the new location + if obj.move_to() has argument quiet=False. + at_after_move(source_location) - always called after a move has been performed. + + at_object_leave(obj, target_location) - called when this object loose an object (e.g. + someone leaving the room, an object is given away etc) + at_object_receive(obj, source_location) - called when this object receives another object + (e.g. a room being entered, an object moved into inventory) + + return_appearance(looker) - by default, this is used by the 'look' command to + request this object to describe itself. Looker + is the object requesting to get the information. + at_desc(looker=None) - by default called whenever the appearance is requested. + """ + pass + +class Character(BaseCharacter): + """ + This is the default object created for a new user connecting - the + in-game player character representation. Note that it's important + that at_object_creation sets up an script that adds the Default + command set whenever the player logs in - otherwise they won't be + able to use any commands! + """ + def at_object_creation(self): + # This adds the default cmdset to the player every time they log + # in. Don't change this unless you really know what you are doing. + #self.scripts.add(scripts.AddDefaultCmdSet) + super(Character, self).at_object_creation() + + # expand with whatever customizations you want below... + # ... + +class Room(BaseRoom): + """ + Rooms are like any object, except their location is None + (which is default). Usually this object should be + assigned to room-building commands by use of the + settings.BASE_ROOM_TYPECLASS variable. + """ + pass + +class Exit(BaseExit): + """ + Exits are connectors between rooms. They are identified by the + engine by having an attribute "_destination" defined on themselves, + pointing to a valid room object. That is usually defined when + the exit is created (in, say, @dig or @link-type commands), not + hard-coded in their typeclass. Exits do have to make sure they + clean up a bit after themselves though, easiest accomplished + by letting by_object_delete() call the object's parent. + """ + def at_object_delete(self): + """ + The game needs to do some cache cleanups when deleting an exit, + so we make sure to call super() here. If this method returns + False, the deletion is aborted. + """ + # handle some cleanups + return super(Exit, self).at_object_delete() + # custom modifications below. + # ... + + +class Player(BasePlayer): + """ + This class describes the actual OOC player (i.e. the user connecting + to the MUD). It does NOT have visual appearance in the game world (that + is handled by the character which is connected to this). Comm channels + are attended/joined using this object. + + It can be useful e.g. for storing configuration options for your game, but + should generally not hold any character-related info (that's best handled + on the character level). + + Can be set using BASE_PLAYER_TYPECLASS. + + The following hooks are called by the engine. Note that all of the following + are called on the character object too, and mostly at the same time. + + at_player_creation() - This is called once, the very first time + the player is created (i.e. first time they + register with the game). It's a good place + to store attributes all players should have, + like configuration values etc. + at_pre_login() - called every time the user connects, after they have + identified, just before the system actually logs them in. + at_post_login() - called at the end of login, just before setting the + player loose in the world. + at_disconnect() - called just before the use is disconnected (this is also + called if the system determines the player lost their link) + + """ + pass diff --git a/game/gamesrc/parents/examples/__init__.py b/game/gamesrc/objects/examples/__init__.py similarity index 100% rename from game/gamesrc/parents/examples/__init__.py rename to game/gamesrc/objects/examples/__init__.py diff --git a/game/gamesrc/objects/examples/red_button.py b/game/gamesrc/objects/examples/red_button.py new file mode 100644 index 0000000000..fbb0d9b8ff --- /dev/null +++ b/game/gamesrc/objects/examples/red_button.py @@ -0,0 +1,168 @@ +""" +An example script parent for a nice red button object. It has +custom commands defined on itself that are only useful in relation to this +particular object. See example.py in gamesrc/commands for more info +on the pluggable command system. + +Assuming this script remains in gamesrc/parents/examples, create an object +of this type using @create button:examples.red_button + +This file also shows the use of the Event system to make the button +send a message to the players at regular intervals. To show the use of +Events, we are tying two types of events to the red button, one which cause ALL +red buttons in the game to blink in sync (gamesrc/events/example.py) and one +event which cause the protective glass lid over the button to close +again some time after it was opened. + +Note that if you create a test button you must drop it before you can +see its messages! +""" +import random +from game.gamesrc.objects.baseobjects import Object +from game.gamesrc.scripts.examples import red_button_scripts as scriptexamples +from game.gamesrc.commands.examples import cmdset_red_button as cmdsetexamples + +# +# Definition of the object itself +# + +class RedButton(Object): + """ + This class describes an evil red button. + It will use the script definition in + game/gamesrc/events/example.py to blink + at regular intervals until the lightbulb + breaks. It also use the EventCloselid script to + close the lid and do nasty stuff when pressed. + """ + def at_object_creation(self): + """ + This function is called when object is created. Use this + instead of e.g. __init__. + """ + # store desc + desc = "This is a large red button, inviting yet evil-looking. " + desc += "A closed glass lid protects it." + self.db.desc = desc + + # We have to define all the variables the scripts + # are checking/using *before* adding the scripts or + # they might be deactivated before even starting! + self.db.lid_open = False + self.db.lamp_works = True + self.db.lid_locked = False + + # set the default cmdset to the object, permanent=True means a + # script will automatically be created to always add this. + self.cmdset.add_default(cmdsetexamples.DefaultCmdSet, permanent=True) + + # since the other cmdsets relevant to the button are added 'on the fly', + # we need to setup custom scripts to do this for us (also, these scripts + # check so they are valid (i.e. the lid is actually still closed)). + # The AddClosedCmdSet script makes sure to add the Closed-cmdset. + self.scripts.add(scriptexamples.ClosedLidState) + # the script EventBlinkButton makes the button blink regularly. + self.scripts.add(scriptexamples.BlinkButtonEvent) + + # state-changing methods + + def open_lid(self, feedback=True): + """ + Open the glass lid and start the timer so it will soon close + again. + """ + + if self.db.lid_open: + return + + desc = "This is a large red button, inviting yet evil-looking. " + desc += "Its glass cover is open and the button exposed." + self.db.desc = desc + self.db.lid_open = True + + if feedback and self.location: + string = "The lid slides clear of the button with a click." + string += "\nA ticking sound is heard, suggesting the lid might have" + string += " some sort of timed locking mechanism." + self.location.msg_contents(string) + + # with the lid open, we validate scripts; this will clean out + # scripts that depend on the lid to be closed. + self.scripts.validate() + # now add new scripts that define the open-lid state + self.obj.scripts.add(scriptexamples.OpenLidState) + # we also add a scripted event that will close the lid after a while. + # (this one cleans itself after being called once) + self.scripts.add(scriptexamples.CloseLidEvent) + + def close_lid(self, feedback=True): + """ + Close the glass lid. This validates all scripts on the button, + which means that scripts only being valid when the lid is open + will go away automatically. + """ + + if not self.db.lid_open: + return + + desc = "This is a large red button, inviting yet evil-looking. " + desc += "Its glass cover is closed, protecting it." + self.db.desc = desc + self.db.lid_open = False + + if feedback and self.location: + string = "With a click the lid slides back, securing the button once again." + self.location.msg_contents(string) + + # clean out scripts depending on lid to be open + self.scripts.validate() + # add scripts related to the closed state + self.scripts.add(scriptexamples.ClosedLidState) + + def break_lamp(self, feedback=True): + """ + Breaks the lamp in the button, stopping it from blinking. + + """ + self.db.lamp_works = False + self.obj.db.desc = "The big red button has stopped blinking for the time being." + + if feedback and self.location: + string = "The lamp flickers, the button going dark." + self.location.msg_contents(string) + self.scripts.validate() + + def press_button(self, pobject): + """ + Someone was foolish enough to press the button! + pobject - the person pressing the button + """ + # deactivate the button so it won't flash/close lid etc. + self.scripts.add(scriptexamples.DeactivateButtonEvent) + # blind the person pressing the button. Note that this + # script is set on the *character* pressing the button! + pobject.scripts.add(scriptexamples.BlindedState) + + # script-related methods + + def blink(self): + """ + The script system will regularly call this + function to make the button blink. Now and then + it won't blink at all though, to add some randomness + to how often the message is echoed. + """ + loc = self.location + if loc: + rand = random.random() + if rand < 0.2: + string = "The red button flashes briefly." + elif rand < 0.4: + string = "The red button blinks invitingly." + elif rand < 0.6: + string = "The red button flashes. You know you wanna push it!" + else: + # no blink + return + loc.msg_contents(string) + diff --git a/game/gamesrc/parents/base/README b/game/gamesrc/parents/base/README deleted file mode 100644 index 42314d2060..0000000000 --- a/game/gamesrc/parents/base/README +++ /dev/null @@ -1,6 +0,0 @@ -Do not modify files in this directory! They are base classes from which other -things may be sub-classed. Modifying these classes may cause conflicts the -next time you upgrade manually or through subversion. - -Instead, sub-class the classes contained here and point the default parent -imports in settings.py to your new classes. \ No newline at end of file diff --git a/game/gamesrc/parents/base/basicobject.py b/game/gamesrc/parents/base/basicobject.py deleted file mode 100644 index 4fc54bcb66..0000000000 --- a/game/gamesrc/parents/base/basicobject.py +++ /dev/null @@ -1,27 +0,0 @@ -""" -This is the base object type/interface that all parents are derived from by -default. Each object type sub-classes this class and over-rides methods as -needed. - -NOTE: This file should NOT be directly modified. Sub-class this in -your own class in game/gamesrc/parents and change -SCRIPT_DEFAULT_OBJECT variable in settings.py to point to the new class. -""" -from src.script_parents.basicobject import EvenniaBasicObject - -class BasicObject(EvenniaBasicObject): - pass - -def class_factory(source_obj): - """ - This method is called any script you retrieve (via the scripthandler). It - creates an instance of the class and returns it transparently. - - source_obj: (Object) A reference to the object being scripted (the child). - - Since this is the only place where the object is actually instantiated, - this is also the place to put commands you want to act on this object, - do this by obj.command_table.add_command('cmd', cmd_def). - """ - obj = BasicObject(source_obj) - return obj diff --git a/game/gamesrc/parents/base/basicplayer.py b/game/gamesrc/parents/base/basicplayer.py deleted file mode 100644 index 0445f44049..0000000000 --- a/game/gamesrc/parents/base/basicplayer.py +++ /dev/null @@ -1,21 +0,0 @@ -""" -This is the basic Evennia-standard player parent. - -NOTE: This file should NOT be directly modified. Sub-class the BasicPlayer -class in your own class in game/gamesrc/parents and change the -SCRIPT_DEFAULT_PLAYER variable in settings.py to point to the new class. -""" -from src.script_parents.basicobject import EvenniaBasicObject -from src.script_parents.basicplayer import EvenniaBasicPlayer - -class BasicPlayer(EvenniaBasicObject, EvenniaBasicPlayer): - pass - -def class_factory(source_obj): - """ - This method is called any script you retrieve (via the scripthandler). It - creates an instance of the class and returns it transparently. - - source_obj: (Object) A reference to the object being scripted (the child). - """ - return BasicPlayer(source_obj) diff --git a/game/gamesrc/parents/examples/custom_basicobject.py b/game/gamesrc/parents/examples/custom_basicobject.py deleted file mode 100644 index c98ec183cc..0000000000 --- a/game/gamesrc/parents/examples/custom_basicobject.py +++ /dev/null @@ -1,75 +0,0 @@ -""" -Simple example of a custom modified object, derived from the base object. - -If you want to make this your new default object type, move this into -gamesrc/parents and set SCRIPT_DEFAULT_OBJECT = 'custom_basicobject' -in game/settings.py. - -Generally, if you want to conveniently set future objects to inherit from this -script parent, this file and others like it need to be -located under the game/gamesrc/parent directory. -""" -from game.gamesrc.parents.base.basicobject import BasicObject - -class CustomBasicObject(BasicObject): - """ - This defines the base class of all non-player objects in game. - """ - def at_object_creation(self): - """ - This function is called whenever the object is created. Use - this instead of __init__ to set start attributes etc on a - particular object type. - """ - - #Set an "sdesc" (short description) attribute on object, - #defaulting to its given name - - #get the stored object related to this class - obj = self.scripted_obj - - #find out the object's name - name = obj.get_name(fullname=False, - show_dbref=False, - show_flags=False) - #assign the name to the new attribute - obj.set_attribute('sdesc', name) - - def at_object_destruction(self, pobject=None): - """ - This is triggered when an object is about to be destroyed via - @destroy ONLY. If an object is deleted via delete(), it is assumed - that this method is to be skipped. - - values: - * pobject: (Object) The object requesting the action. - """ - pass - - def at_before_move(self, target_location): - """ - This hook is called just before the object is moved. - Input: - target_location (obj): The location the player is about to move to. - Return value: - If this function returns anything but None (no return value), - the move is aborted. This allows for character-based move - restrictions (not only exit locks). - """ - pass - - def at_after_move(self): - """ - This hook is called just after the object has been successfully moved. - """ - pass - - -def class_factory(source_obj): - """ - This method is called by any script you retrieve (via the scripthandler). It - creates an instance of the class and returns it transparently. - - source_obj: (Object) A reference to the object being scripted (the child). - """ - return CustomBasicObject(source_obj) diff --git a/game/gamesrc/parents/examples/custom_basicplayer.py b/game/gamesrc/parents/examples/custom_basicplayer.py deleted file mode 100644 index 2d4490d886..0000000000 --- a/game/gamesrc/parents/examples/custom_basicplayer.py +++ /dev/null @@ -1,76 +0,0 @@ -""" -This is an example of customizing the basic player character object. -You will want to do this to add all sorts of custom things like -attributes, skill values, injuries and so on. - -If you want to make this the default player object for all players, -move it into gamesrc/parents and set SCRIPT_DEFAULT_PLAYER = -'custom_basicplayer' in game/settings.py. -""" - -from game.gamesrc.parents.base.basicplayer import BasicPlayer - -class CustomBasicPlayer(BasicPlayer): - """ - This is the base class for all players in game. - """ - def at_player_creation(self): - """ - Called when player object is first created. Use this - instead of __init__ to define any custom attributes - all your player characters should have. - """ - - #Example: Adding a default sdesc (short description) - - #get the stored object related to this class - pobject = self.scripted_obj - #set the attribute - pobject.set_attribute('sdesc', 'A normal person') - - def at_pre_login(self, session): - """ - Called when the player has entered the game but has not - logged in yet. - """ - pass - - def at_post_login(self, session): - """ - This command is called after the player has logged in but - before he is allowed to give any commands. - """ - #get the object linked to this class - pobject = self.scripted_obj - - #find out more about our object - name = pobject.get_name(fullname=False, - show_dbref=False, - show_flags=False) - sdesc = pobject.get_attribute_value('sdesc') - - #send a greeting using our new sdesc attribute - pobject.emit_to("You are now logged in as %s - %s." % (name, sdesc)) - - #tell everyone else we're here - pobject.get_location().emit_to_contents("%s - %s, has connected." % - (name, sdesc), exclude=pobject) - #show us our surroundings - pobject.execute_cmd("look") - - def at_move(self): - """ - This is triggered whenever the object is moved to a new location - (for whatever reason) using the src.objects.models.move_to() function. - """ - pass - - -def class_factory(source_obj): - """ - This method is called by any script you retrieve (via the scripthandler). It - creates an instance of the class and returns it transparently. - - source_obj: (Object) A reference to the object being scripted (the child). - """ - return CustomBasicPlayer(source_obj) diff --git a/game/gamesrc/parents/examples/red_button.py b/game/gamesrc/parents/examples/red_button.py deleted file mode 100644 index 6b65e505a4..0000000000 --- a/game/gamesrc/parents/examples/red_button.py +++ /dev/null @@ -1,220 +0,0 @@ -""" -An example script parent for a nice red button object. It has -custom commands defined on itself that are only useful in relation to this -particular object. See example.py in gamesrc/commands for more info -on the pluggable command system. - -Assuming this script remains in gamesrc/parents/examples, create an object -of this type using @create button:examples.red_button - -This file also shows the use of the Event system to make the button -send a message to the players at regular intervals. To show the use of -Events, we are tying two types of events to the red button, one which cause ALL -red buttons in the game to blink in sync (gamesrc/events/example.py) and one -event which cause the protective glass lid over the button to close -again some time after it was opened. - -Note that if you create a test button you must drop it before you can -see its messages! -""" -import traceback -from game.gamesrc.parents.base.basicobject import BasicObject -from src.objects.models import Object -from src.events import IntervalEvent -from src import scheduler -from src import logger - - -# -# Events -# - -# Importing this will start the blink event ticking, only one -# blink event is used for all red buttons. -import game.gamesrc.events.example - -# We also create an object-specific event. - -class EventCloselid(IntervalEvent): - """ - This event closes the glass lid over the button - some time after it was opened. - """ - def __init__(self, obj): - """ - Note how we take an object as an argument, - this will allow instances of this event to - operate on this object only. - """ - # we must call super to make sure things work! - super(EventCloselid, self).__init__() - # store the object reference - self.obj_dbref = obj.dbref() - # This is used in e.g. @ps to show what the event does - self.description = "Close lid on %s" % obj - # We make sure that this event survives a reboot - self.persistent = True - # How many seconds from event creation to closing - # the lid - self.interval = 20 - # We only run the event one time before it deletes itself. - self.repeats = 1 - - def event_function(self): - """ - This function is called every self.interval seconds. - Note that we must make sure to handle all errors from - this call to avoid trouble. - """ - try: - # if the lid is open, close it. We have to find the object - # again since it might have changed. - obj = Object.objects.get_object_from_dbref(self.obj_dbref) - if obj.has_flag("LID_OPEN"): - obj.scriptlink.close_lid() - retval = "The glass cover over the button silently closes by itself." - obj.get_location().emit_to_contents(retval) - except: - # send the traceback to the log instead of letting it by. - # It is important that we handle exceptions gracefully here! - logger.log_errmsg(traceback.print_exc()) - - -# -# Object commands -# -# Commands for using the button object. These are added to -# the object in the class_factory function at the -# bottom of this module. -# - -def cmd_open_lid(command): - """ - Open the glass lid cover over the button. - """ - # In the case of object commands, you can use this to - # get the object the command is defined on. - obj = command.scripted_obj - - if obj.has_flag("LID_OPEN"): - retval = "The lid is already open." - else: - retval = "You lift the lid, exposing the tempting button." - obj.scriptlink.open_lid() - command.source_object.emit_to(retval) - -def cmd_close_lid(command): - """ - Close the lid again. - """ - obj = command.scripted_obj - if not obj.has_flag("LID_OPEN"): - retval = "The lid is already open." - else: - retval = "You secure the glass cover over the button." - obj.scriptlink.close_lid() - command.source_object.emit_to(retval) - -def cmd_push_button(command): - """ - - This is a simple command that handles a user pressing the - button by returning a message. The button can only be - """ - obj = command.scripted_obj - - if obj.has_flag("LID_OPEN"): - retval = "You press the button ..." - retval += "\n ..." - retval += "\n BOOOOOM!" - obj.scriptlink.close_lid() - else: - retval = "There is a glass lid covering " - retval += "the button as a safety measure. If you " - retval += "want to press the button you need to open " - retval += "the lid first." - command.source_object.emit_to(retval) - - -# -# Definition of the object itself -# - -class RedButton(BasicObject): - """ - This class describes an evil red button. - It will use the event definition in - game/gamesrc/events/example.py to blink - at regular intervals until the lightbulb - breaks. It also use the EventCloselid event defined - above to close the lid - """ - def at_object_creation(self): - """ - This function is called when object is created. Use this - preferably over __init__. - """ - #get stored object related to this class - obj = self.scripted_obj - - obj.set_attribute('desc', "This is a big red button. It has a glass cover.") - obj.set_attribute("breakpoint", 5) - obj.set_attribute("count", 0) - - # add the object-based commands to the button - obj.add_command("open lid", cmd_open_lid) - obj.add_command("lift lid", cmd_open_lid) - obj.add_command("close lid", cmd_close_lid) - obj.add_command("push button", cmd_push_button) - obj.add_command("push the button", cmd_push_button) - - def open_lid(self): - """ - Open the glass lid and start the timer so it will - soon close again. - """ - self.scripted_obj.set_flag("LID_OPEN") - scheduler.add_event(EventCloselid(self.scripted_obj)) - - def close_lid(self): - """ - Close the glass lid - """ - self.scripted_obj.unset_flag("LID_OPEN") - - def blink(self): - """ - If the event system is active, it will regularly call this - function to make the button blink. Note the use of attributes - to store the variable count and breakpoint in a persistent - way. - """ - obj = self.scripted_obj - - try: - count = int(obj.get_attribute_value("count")) - breakpoint = int(obj.get_attribute_value("breakpoint")) - except TypeError: - return - - if count <= breakpoint: - if int(count) == int(breakpoint): - string = "The button flashes, then goes dark. " - string += "Looks like the lamp just broke." - else: - string = "The red button flashes, demanding your attention." - count += 1 - obj.set_attribute("count", count) - obj.get_location().emit_to_contents(string) - -def class_factory(source_obj): - """ - This method is called by any script you retrieve (via the scripthandler). It - creates an instance of the class and returns it transparently. - - source_obj: (Object) A reference to the object being scripted (the child). - - This is a good place for adding new commands to the button since this is - where it is actually instantiated. - """ - return RedButton(source_obj) diff --git a/game/web/apps/__init__.py b/game/gamesrc/scripts/__init__.py similarity index 100% rename from game/web/apps/__init__.py rename to game/gamesrc/scripts/__init__.py diff --git a/game/gamesrc/scripts/basescript.py b/game/gamesrc/scripts/basescript.py new file mode 100644 index 0000000000..fafe440feb --- /dev/null +++ b/game/gamesrc/scripts/basescript.py @@ -0,0 +1,63 @@ +""" +The base object to inherit from when implementing new Scripts. + +Scripts are objects that handle everything in the game having +a time-component (i.e. that may change with time, with or without +a player being involved in the change). Scripts can work like "events", +in that they are triggered at regular intervals to do a certain script, +but an Script set on an object can also be responsible for silently +checking if its state changes, so as to update it. Evennia use several +in-built scripts to keep track of things like time, to clean out +dropped connections etc. + +New Script objects (from these classes) are created using the +src.utils.create.create_script(scriptclass, ...) where scriptclass +is the python path to the specific class of script you want to use. +""" + +from src.scripts.scripts import Script as BaseScript + +class Script(BaseScript): + """ + All scripts should inherit from this class and implement + some or all of its hook functions and variables. + + Important variables controlling the script object: + self.key - the name of all scripts inheriting from this class + (defaults to ), used in lists and searches. + self.desc - a description of the script, used in lists + self.interval (seconds) - How often the event is triggered and calls self.at_repeat() + (see below) Defaults to 0 - that is, never calls at_repeat(). + self.start_delay (True/False). If True, will wait self.interval seconds + befor calling self.at_repeat() for the first time. Defaults to False. + self.repeats - The number of times at_repeat() should be called before automatically + stopping the script. Default is 0, which means infinitely many repeats. + self.persistent (True/False). If True, the script will survive a server restart + (defaults to False). + + self.obj (game Object)- this ties this script to a particular object. It is + usually not needed to set this parameter explicitly; it's set in the + create methods. + + + Hook methods (should also include self as the first argument): + at_script_creation() - called only once, when an object of this class + is first created. + is_valid() - is called to check if the script is valid to be running + at the current time. If is_valid() returns False, the running + script is stopped and removed from the game. You can use this + to check state changes (i.e. an script tracking some combat + stats at regular intervals is only valid to run while there is + actual combat going on). + at_start() - Called every time the script is started, which for persistent + scripts is at least once every server start. Note that this is + unaffected by self.delay_start, which only delays the first call + to at_repeat(). + at_repeat() - Called every self.interval seconds. It will be called immediately + upon launch unless self.delay_start is True, which will delay + the first call of this method by self.interval seconds. If + self.interval==0, this method will never be called. + at_stop() - Called as the script object is stopped and is about to be removed from + the game, e.g. because is_valid() returned False. + """ + pass diff --git a/game/web/apps/news/__init__.py b/game/gamesrc/scripts/examples/__init__.py old mode 100755 new mode 100644 similarity index 100% rename from game/web/apps/news/__init__.py rename to game/gamesrc/scripts/examples/__init__.py diff --git a/game/gamesrc/scripts/examples/red_button_scripts.py b/game/gamesrc/scripts/examples/red_button_scripts.py new file mode 100644 index 0000000000..b15ccba97d --- /dev/null +++ b/game/gamesrc/scripts/examples/red_button_scripts.py @@ -0,0 +1,275 @@ +""" +Example of scripts. + +These are scripts intended for a particular object - the +red_button object type in gamesrc/types/examples. A few variations +on uses of scripts are included. + +""" +from game.gamesrc.scripts.basescript import Script +from game.gamesrc.commands.examples import cmdset_red_button as cmdsetexamples + +# +# Scripts as state-managers +# +# Scripts have many uses, one of which is to statically +# make changes when a particular state of an object changes. +# There is no "timer" involved in this case (although there could be), +# whenever the script determines it is "invalid", it simply shuts down +# along with all the things it controls. +# +# To show as many features as possible of the script and cmdset systems, +# we will use three scripts controlling one state each of the red_button, +# each with its own set of commands, handled by cmdsets - one for when +# the button has its lid open, and one for when it is closed and a +# last one for when the player pushed the button and gets blinded by +# a bright light. The last one also has a timer component that allows it +# to remove itself after a while (and the player recovers their eyesight). + +class ClosedLidState(Script): + """ + This manages the cmdset for the "closed" button state. What this + means is that while this script is valid, we add the RedButtonClosed + cmdset to it (with commands like open, nudge lid etc) + """ + def at_script_creation(self): + "Called when script first created." + self.desc = "Script that manages the closed-state cmdsets for red button." + self.persistent = True + + def at_start(self): + """ + This is called once every server restart, so we want to add the + (memory-resident) cmdset to the object here. is_valid is automatically + checked so we don't need to worry about adding the script to an + open lid. + """ + #All we do is add the cmdset for the closed state. + self.obj.cmdset.add(cmdsetexamples.LidClosedCmdSet) + + def is_valid(self): + """ + The script is only valid while the lid is closed. + self.obj is the red_button on which this script is defined. + """ + return not self.obj.db.lid_open + + def at_stop(self): + """ + When the script stops we must make sure to clean up after us. + + """ + self.obj.cmdset.delete(cmdsetexamples.LidClosedCmdSet) + + +class OpenLidState(Script): + """ + This manages the cmdset for the "open" button state. This will add + the RedButtonOpen + """ + def at_script_creation(self): + "Called when script first created." + self.desc = "Script that manages the opened-state cmdsets for red button." + self.persistent = True + + def at_start(self): + """ + This is called once every server restart, so we want to add the + (memory-resident) cmdset to the object here. is_valid is + automatically checked, so we don't need to worry about + adding the cmdset to a closed lid-button. + """ + #print "In Open at_start (should add cmdset)" + self.obj.cmdset.add(cmdsetexamples.LidOpenCmdSet) + + def is_valid(self): + """ + The script is only valid while the lid is open. + self.obj is the red_button on which this script is defined. + """ + return self.obj.db.lid_open + + def at_stop(self): + """ + When the script stops (like if the lid is closed again) + we must make sure to clean up after us. + """ + self.obj.cmdset.delete(cmdsetexamples.LidOpenCmdSet) + + +class BlindedState(Script): + """ + This is a timed state. + + This adds a (very limited) cmdset TO THE PLAYER, during a certain time, + after which the script will close and all functions are + restored. It's up to the function starting the script to actually + set it on the right player object. + """ + def at_script_creation(self): + """ + We set up the script here. + """ + self.key = "temporary_blinder" + self.desc = "Temporarily blinds the player for a little while." + self.interval = 20 # seconds + self.start_delay = True # we don't want it to stop until after 20s. + self.repeats = 1 # this will go away after interval seconds. + self.persistent = False # we will ditch this if server goes down + + def at_start(self): + """ + We want to add the cmdset to the linked object. + + Note that the RedButtonBlind cmdset is defined to completly + replace the other cmdsets on the stack while it is active + (this means that while blinded, only operations in this cmdset + will be possible for the player to perform). It is however + not persistent, so should there be a bug in it, we just need + to restart the server to clear out of it during development. + """ + self.obj.cmdset.add(cmdsetexamples.BlindCmdSet) + + def at_stop(self): + """ + It's important that we clear out that blinded cmdset + when we are done! + """ + self.obj.msg("Your blink feverishly as your eyesight slowly returns.") + self.obj.location.msg_contents("%s seems to be recovering their eyesight." + % self.obj.name, + exclude=self.obj) + self.obj.cmdset.delete() # this will clear the latest added cmdset, + # (which is the blinded one). + + +# +# Timer/Event-like Scripts +# +# Scripts can also work like timers, or "events". Below we +# define three such timed events that makes the button a little +# more "alive" - one that makes the button blink menacingly, another +# that makes the lid covering the button slide back after a while. +# + +class CloseLidEvent(Script): + """ + This event closes the glass lid over the button + some time after it was opened. It's a one-off + script that should be started/created when the + lid is opened. + """ + def at_script_creation(self): + """ + Called when script object is first created. Sets things up. + We want to have a lid on the button that the user can pull + aside in order to make the button 'pressable'. But after a set + time that lid should auto-close again, making the button safe + from pressing (and deleting this command). + """ + self.key = "lid_closer" + self.desc = "Closes lid on a red buttons" + self.interval = 20 # seconds + self.start_delay = True # we want to pospone the launch. + self.repeats = 1 # we only close the lid once + self.persistent = True # even if the server crashes in those 20 seconds, + # the lid will still close once the game restarts. + + def is_valid(self): + """ + This script can only operate if the lid is open; if it + is already closed, the script is clearly invalid. + + Note that we are here relying on an self.obj being + defined (and being a RedButton object) - this we should be able to + expect since this type of script is always tied to one individual + red button object and not having it would be an error. + """ + return self.obj.db.lid_open + + def at_repeat(self): + """ + Called after self.interval seconds. It closes the lid. Before this method is + called, self.is_valid() is automatically checked, so there is no need to + check this manually. + """ + self.obj.close_lid() + +class BlinkButtonEvent(Script): + """ + This timed script lets the button flash at regular intervals. + """ + def at_script_creation(self): + """ + Sets things up. We want the button's lamp to blink at + regular intervals, unless it's broken (can happen + if you try to smash the glass, say). + """ + self.key = "blink_button" + self.desc = "Blinks red buttons" + self.interval = 35 #seconds + self.start_delay = False #blink right away + self.persistent = True #keep blinking also after server reboot + + def is_valid(self): + """ + Button will keep blinking unless it is broken. + """ + #print "self.obj.db.lamp_works:", self.obj.db.lamp_works + return self.obj.db.lamp_works + + def at_repeat(self): + """ + Called every self.interval seconds. Makes the lamp in + the button blink. + """ + self.obj.blink() + +class DeactivateButtonEvent(Script): + """ + This deactivates the button for a short while (it won't blink, won't + close its lid etc). It is meant to be called when the button is pushed + and run as long as the blinded effect lasts. We cannot put these methods + in the AddBlindedCmdSet script since that script is defined on the *player* + whereas this one must be defined on the *button*. + """ + def at_script_creation(self): + """ + Sets things up. + """ + self.key = "deactivate_button" + self.desc = "Deactivate red button temporarily" + self.interval = 21 #seconds + self.start_delay = True # wait with the first repeat for self.interval seconds. + self.persistent = True + self.repeats = 1 # only do this once + + def at_start(self): + """ + Deactivate the button. Observe that this method is always + called directly, regardless of the value of self.start_delay + (that just controls when at_repeat() is called) + """ + # closing the lid will also add the ClosedState script + self.obj.close_lid(feedback=False) + # lock the lid so other players can't access it until the + # first one's effect has worn off. + self.obj.db.lid_locked = True + # breaking the lamp also sets a correct desc + self.obj.break_lamp(feedback=False) + + def at_repeat(self): + """ + When this is called, reset the functionality of the button. + """ + # restore button's desc. + + self.obj.db.lamp_works = True + desc = "This is a large red button, inviting yet evil-looking. " + desc += "Its glass cover is closed, protecting it." + self.db.desc = desc + # re-activate the blink button event. + self.obj.scripts.add(BlinkButtonEvent) + # unlock the lid + self.obj.db.lid_locked = False + self.obj.scripts.validate() diff --git a/game/gamesrc/utils.py b/game/gamesrc/utils.py deleted file mode 100644 index 6cbbeefe55..0000000000 --- a/game/gamesrc/utils.py +++ /dev/null @@ -1,123 +0,0 @@ -""" -This module offers a collection of useful general functions from the -game engine to make things easier to find. -Just import game.gamesrc.utils and refer to the globals defined herein. - -Note that this is not intended as a comprehensive collection, merely -a convenient place to refer to for the methods we have found to be -often used. You will still have to refer to the modules -in evennia/src for more specialized operations. - -You will also want to be well familiar with all the facilities each -object offers. The object model is defined in src/objects/models.py. -""" -#------------------------------------------------------------ -# imports -#------------------------------------------------------------ - -from django.conf import settings as in_settings -from src import logger -from src import scheduler as in_scheduler -from src.objects.models import Object -from src import defines_global -from src.cmdtable import GLOBAL_CMD_TABLE as in_GLOBAL_CMD_TABLE -from src.statetable import GLOBAL_STATE_TABLE as in_GLOBAL_STATE_TABLE -from src.events import IntervalEvent as in_IntervalEvent - -#------------------------------------------------------------ -# Import targets -#------------------------------------------------------------ - -settings = in_settings -GLOBAL_CMD_TABLE = in_GLOBAL_CMD_TABLE -GLOBAL_STATE_TABLE = in_GLOBAL_STATE_TABLE - -# Events -scheduler = in_scheduler -IntervalEvent = in_IntervalEvent - - -#------------------------------------------------------------ -# Log to file/stdio -# log_xxxmsg(msg) -#------------------------------------------------------------ - -log_errmsg = logger.log_errmsg -log_warnmsg = logger.log_warnmsg -log_infomsg = logger.log_infomsg - - -#------------------------------------------------------------ -# Search methods -#------------------------------------------------------------ - -# NOTE: All objects also has search_for_object() defined -# directly on themselves, which is a convenient entryway into a -# local and global search with automatic feedback to the -# calling player. - -# def get_object_from_dbref(dbref): -# Returns an object when given a dbref. -get_object_from_dbref = Object.objects.get_object_from_dbref - -# def dbref_search(dbref_string, limit_types=False): -# Searches for a given dbref. -dbref_search = Object.objects.dbref_search - -# def global_object_name_search(ostring, exact_match=True, limit_types=[]): -# Searches through all objects for a name match. -global_object_name_search = Object.objects.global_object_name_search - -# def global_object_script_parent_search(script_parent): -# Searches through all objects returning those which has a certain script parent. -global_object_script_parent_search = Object.objects.global_object_script_parent_search - -# def player_name_search(searcher, ostring): -# Search players by name. -player_name_search = Object.objects.player_name_search - -# def local_and_global_search(searcher, ostring, search_contents=True, -# search_location=True, dbref_only=False, -# limit_types=False, attribute_name=None): -# Searches an object's location then globally for a dbref or name match. -local_and_global_search = Object.objects.local_and_global_search - - -#------------------------------------------------------------ -# Creation commands -#------------------------------------------------------------ - -# def create_object(name, otype, location, owner, home=None, script_parent=None): -# Create a new object -create_object = Object.objects.create_object - -# def copy_object(original_object, new_name=None, new_location=None, reset=False): -# Create and return a new object as a copy of the source object. All will -# be identical to the original except for the dbref. Does not allow the -# copying of Player objects. -copy_object = Object.objects.copy_object - - -#------------------------------------------------------------ -# Validation -#------------------------------------------------------------ - -# NOTE: The easiest way to check if an object -# is of a particular type is to use each object's -# is_X() function, like is_superuser(), is_thing(), -# is_room(), is_player(), is_exit() and get_type(). - -OTYPE_NOTHING = defines_global.OTYPE_NOTHING -OTYPE_PLAYER = defines_global.OTYPE_PLAYER -OTYPE_ROOM = defines_global.OTYPE_ROOM -OTYPE_THING = defines_global.OTYPE_THING -OTYPE_EXIT = defines_global.OTYPE_EXIT -OTYPE_GOING = defines_global.OTYPE_GOING -TYPE_GARBAGE = defines_global.OTYPE_GARBAGE - -NOPERMS_MSG = defines_global.NOPERMS_MSG -NOCONTROL_MSG = defines_global.NOCONTROL_MSG - -# def is_dbref(self, dbstring, require_pound=True): -# Is the input a well-formed dbref number? -is_dbref = Object.objects.is_dbref diff --git a/game/gamesrc/world/examples/batch_example.ev b/game/gamesrc/world/examples/batch_cmds.ev similarity index 87% rename from game/gamesrc/world/examples/batch_example.ev rename to game/gamesrc/world/examples/batch_cmds.ev index a209a2279c..12ce59eb4b 100644 --- a/game/gamesrc/world/examples/batch_example.ev +++ b/game/gamesrc/world/examples/batch_cmds.ev @@ -3,9 +3,8 @@ # # It allows batch processing of normal Evennia commands. # Test it by loading it with the @batchprocess command -# (superuser only): # -# @batchprocess[/interactive] +# @batchprocess[/interactive] examples.batch_example # # A # as the first symbol on a line begins a comment and # marks the end of a previous command definition (important!). @@ -18,12 +17,12 @@ # This creates a red button -@create button +@create button:examples.red_button.RedButton # This comment ends input for @create # Next command: -@set button=desc: +@set button/desc = This is a large red button. Now and then it flashes in an evil, yet strangely tantalizing way. @@ -52,6 +51,6 @@ know you want to! @teleport #2 #... and drop it (remember, this comment ends input to @teleport, so don't -#forget it!) The very last command in the file needs not be ended with #. +#forget it!) The very last command in the file need not be ended with #. drop button \ No newline at end of file diff --git a/game/gamesrc/world/examples/batch_code.py b/game/gamesrc/world/examples/batch_code.py new file mode 100644 index 0000000000..401661fc05 --- /dev/null +++ b/game/gamesrc/world/examples/batch_code.py @@ -0,0 +1,71 @@ +# +# Batchcode script +# +# +# The Batch-code processor accepts full python modules (e.g. "batch.py") that +# looks identical to normal Python files with a few exceptions that allows them +# to the executed in blocks. This way of working assures a sequential execution +# of the file and allows for features like stepping from block to block +# (without executing those coming before), as well as automatic deletion +# of created objects etc. You can however also run a batch-code python file +# directly using Python (and can also be de). + +# Code blocks are separated by python comments starting with special code words. + +# #HEADER - this denotes commands global to the entire file, such as +# import statements and global variables. They will +# automatically be made available for each block. Observe +# that changes to these variables made in one block is not +# preserved between blocks!) +# #CODE [objname, objname, ...] - This designates a code block that will be executed like a +# stand-alone piece of code together with any #HEADER +# defined. s mark the (variable-)names of objects created in the code, +# and which may be auto-deleted by the processor if desired (such as when +# debugging the script). E.g., if the code contains the command +# myobj = create.create_object(...), you could put 'myobj' in the #CODE header +# regardless of what the created object is actually called in-game. + +# The following variables are automatically made available for the script: + +# caller - the object executing the script +# +# + +#HEADER + +# everything in this block will be imported to all CODE blocks when +# they are executed. + +from src.utils import create, search +from game.gamesrc.typeclasses.examples import red_button +from game.gamesrc.typeclasses import basetypes + +#CODE + +# This is the first code block. Within each block, python +# code works as normal. + +# get the limbo room. +limbo = search.objects(caller, 'Limbo', global_search=True)[0] +caller.msg(limbo) +# create a red button in limbo +red_button = create.create_object(red_button.RedButton, key="Red button", + location=limbo, aliases=["button"]) + +# we take a look at what we created +caller.msg("A %s was created." % red_button.key) + +#CODE table, chair + +# this code block has 'table' and 'chair' set as deletable +# objects. This means that when the batchcode processor runs in +# testing mode, objects created in these variables will be deleted +# again (so as to avoid duplicate objects when testing the script). + +limbo = search.objects(caller, 'Limbo', global_search=True)[0] +caller.msg(limbo.key) +table = create.create_object(basetypes.Object, key="Table", location=limbo) +chair = create.create_object(basetypes.Object, key="Chair", location=limbo) + +string = "A %s and %s were created. If debug was active, they were deleted again." +caller.msg(string % (table, chair)) diff --git a/game/manage.py b/game/manage.py index 94a14e323a..328e0c1599 100755 --- a/game/manage.py +++ b/game/manage.py @@ -1,28 +1,129 @@ #!/usr/bin/env python +""" +Set up the evennia system. A first startup consists of giving +the command './manage syncdb' to setup the system and create +the database. +""" + import sys import os # Tack on the root evennia directory to the python path. sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) -""" -If settings.py doesn't already exist, create it and populate it with some -basic stuff. -""" +try: + VERSION = open("%s%s%s" % (os.pardir, os.sep, 'VERSION')).readline().strip() +except IOError: + VERSION = "Unknown version" + +_CREATED_SETTINGS = False if not os.path.exists('settings.py'): - print "Can't find a settings.py file, creating one for you." - f = open('settings.py', 'w') - f.write('"""\nMaster server configuration file. You may override any of the values in the\nsrc/config_defaults.py here. Copy-paste the variables here, and make changes to\nthis file rather than editing config_defaults.py directly.\n"""\n') - f.write('from src.config_defaults import *') - f.close() + # If settings.py doesn't already exist, create it and populate it with some + # basic stuff. + + settings_file = open('settings.py', 'w') + _CREATED_SETTINGS = True + + string = \ + """# +# Evennia MU* server configuration file +# +# You may customize your setup by copy&pasting the variables you want +# to change from the master config file src/settings_default.py to +# this file. Try to *only* copy over things you really need to customize +# and do *not* make any changes to src/settings_default.py directly. +# This way you'll always have a sane default to fall back on +# (also, the master file may change with server updates). +# + +from src.settings_default import * + +################################################### +# Evennia base server config +################################################### + +################################################### +# Evennia Database config +################################################### + +################################################### +# Evennia in-game parsers +################################################### + +################################################### +# Default command sets +################################################### + +################################################### +# Default Object typeclasses +################################################### + +################################################### +# Batch processor +################################################### + +################################################### +# Game Time setup +################################################### + +################################################### +# Game Permissions +################################################### + +################################################### +# In-game Channels created from server start +################################################### + +################################################### +# IMC2 Configuration +################################################### + +################################################### +# IRC config +################################################### + +################################################### +# Config for Django web features +################################################### + +################################################### +# Evennia components (django apps) +###################################################""" + + settings_file.write(string) + settings_file.close() + + print """ + Welcome to Evennia (version %s)! + Created a fresh settings.py file for you.""" % VERSION + + try: from game import settings -except ImportError: - import sys - sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__) - sys.exit(1) - +except Exception: + import traceback + string = "\n" + traceback.format_exc() + string += """\n + Error: Couldn't import the file 'settings.py' in the directory + containing %r. There can be two reasons for this: + 1) You moved your settings.py elsewhere. In that case you need to run + django-admin.py, passing it the true location of your settings module. + 2) The settings module is where it's supposed to be, but an exception + was raised when trying to load it. Review the traceback above to + resolve the problem, then try again. + """ % __file__ + print string + sys.exit(1) + if __name__ == "__main__": - from django.core.management import execute_manager - execute_manager(settings) + from django.core.management import execute_manager + if _CREATED_SETTINGS: + print """ + Edit your new settings.py file as needed, then run + 'python manage syncdb' and follow the prompts to + create the database and your superuser account. + """ + sys.exit() + # run the django setups + execute_manager(settings) diff --git a/game/web/apps/website/models.py b/game/web/apps/website/models.py deleted file mode 100644 index 71a8362390..0000000000 --- a/game/web/apps/website/models.py +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/game/web/apps/website/urls.py b/game/web/apps/website/urls.py deleted file mode 100644 index 83e0d0ad39..0000000000 --- a/game/web/apps/website/urls.py +++ /dev/null @@ -1,5 +0,0 @@ -from django.conf.urls.defaults import * - -urlpatterns = patterns('game.web.apps.website.views', - (r'^$', 'page_index'), -) diff --git a/game/web/apps/website/webcontext.py b/game/web/apps/website/webcontext.py deleted file mode 100644 index c123ddbeaa..0000000000 --- a/game/web/apps/website/webcontext.py +++ /dev/null @@ -1,9 +0,0 @@ -from src.config.models import ConfigValue - -def general_context(request): - """ - Returns common Evennia-related context stuff. - """ - return { - 'game_name': ConfigValue.objects.get_configvalue('site_name'), - } diff --git a/game/web/media/images/LICENCE b/game/web/media/images/LICENCE new file mode 100644 index 0000000000..79b2e03244 --- /dev/null +++ b/game/web/media/images/LICENCE @@ -0,0 +1,4 @@ +The evennia logo (the python snaking a cogwheel-globe) was created in 2009 +by Griatch (www.griatch-art.deviantart.com, www.griatch.com) using open-source software (of course). + +The logo is released with the same licence as Evennia itself (look in evennia/LICENCE). diff --git a/game/web/media/images/evennia_logo.png b/game/web/media/images/evennia_logo.png new file mode 100755 index 0000000000000000000000000000000000000000..62942f7b1f3de9669835bfbb98c57c01bfcf897b GIT binary patch literal 688250 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

!y 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

$< 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
nHpfkBwW02z@1nQf+x)$auHFZ>8O*SRARdw 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 y=LDb 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�rz^Uy~g*TK=Q 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