Merge branch 'main' into evadventure_work
This commit is contained in:
commit
1f3d4ed840
23 changed files with 112 additions and 93 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -1,13 +1,18 @@
|
|||
# Changelog
|
||||
|
||||
## Main branch
|
||||
## Evennia 1.3.0
|
||||
|
||||
- Feature: Better ANSI color fallbacks (InspectorCaracal)
|
||||
Apr 29, 2023
|
||||
|
||||
- Feature: Better ANSI color fallbacks (InspectorCaracal).
|
||||
- Feature: Add support for saving `deque` with `maxlen` to Attributes (before
|
||||
`maxlen` was ignored).
|
||||
- Tools: More unit tests for scripts (Storsorken)
|
||||
- Fix: The username validator did not display errors correctly in web
|
||||
registration form.
|
||||
- Fix: Components contrib had issues with inherited typeclasses (ChrisLR)
|
||||
- Fix: f-string fix in clothing contrib (aMiss-aWry)
|
||||
- Fix: Have `EvenniaTestCase` properly flush idmapper cache (bradleymarques)
|
||||
- Tools: More unit tests for scripts (Storsorken)
|
||||
- Docs: Made separate doc pages for Exits, Characters and Rooms. Expanded on how
|
||||
to change the description of an in-game object with templating.
|
||||
- Docs: A multitude of doc issues and typos fixed.
|
||||
|
|
|
|||
|
|
@ -58,10 +58,10 @@ _multiversion-check-env:
|
|||
@EVDIR=$(EVDIR) EVGAMEDIR=$(EVGAMEDIR) bash -e checkenv.sh multiversion
|
||||
|
||||
_clean_api_index:
|
||||
rm source/api/*
|
||||
rm -f source/api/*
|
||||
|
||||
_clean_api_rsts:
|
||||
rm source/api/*.rst
|
||||
rm -f source/api/*.rst
|
||||
|
||||
# remove superfluos 'module' and 'package' text from api headers
|
||||
_reformat_apidoc_headers:
|
||||
|
|
|
|||
|
|
@ -1,13 +1,21 @@
|
|||
# Changelog
|
||||
|
||||
## Main branch
|
||||
## Evennia 1.3.0
|
||||
|
||||
Apr 29, 2023
|
||||
|
||||
- Feature: Better ANSI color fallbacks (InspectorCaracal).
|
||||
- Feature: Add support for saving `deque` with `maxlen` to Attributes (before
|
||||
`maxlen` was ignored).
|
||||
- Fix: More unit tests for scripts (Storsorken)
|
||||
- Fix: The username validator did not display errors correctly in web
|
||||
registration form.
|
||||
- Fix: Components contrib had issues with inherited typeclasses (ChrisLR)
|
||||
- Fix: f-string fix in clothing contrib (aMiss-aWry)
|
||||
- Fix: Have `EvenniaTestCase` properly flush idmapper cache (bradleymarques)
|
||||
- Tools: More unit tests for scripts (Storsorken)
|
||||
- Docs: Made separate doc pages for Exits, Characters and Rooms. Expanded on how
|
||||
to change the description of an in-game object with templating.
|
||||
- Docs: Fixed a multitude of doc issues.
|
||||
- Docs: A multitude of doc issues and typos fixed.
|
||||
|
||||
## Evennia 1.2.1
|
||||
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ To test this, run
|
|||
|
||||
to run the entire test module
|
||||
|
||||
evennia test --settings setings.py world.tests
|
||||
evennia test --settings settings.py world.tests
|
||||
|
||||
or a specific class:
|
||||
|
||||
|
|
|
|||
|
|
@ -17,8 +17,8 @@ Channels can be used both for chats between [Accounts](./Accounts.md) and betwee
|
|||
- Private guild channels for planning and organization (IC/OOC depending on game)
|
||||
- Cyberpunk-style retro chat rooms (IC)
|
||||
- In-game radio channels (IC)
|
||||
- Group telephathy (IC)
|
||||
- Walkie talkies (IC)
|
||||
- Group telepathy (IC)
|
||||
- Walkie-talkies (IC)
|
||||
|
||||
```{versionchanged} 1.0
|
||||
|
||||
|
|
@ -150,7 +150,7 @@ To create/destroy a new channel on the fly you can do
|
|||
Aliases are optional but can be good for obvious shortcuts everyone may want to
|
||||
use. The description is used in channel-listings. You will automatically join a
|
||||
channel you created and will be controlling it. You can also use `channel/desc` to
|
||||
change the description on a channel you wnn later.
|
||||
change the description on a channel you own later.
|
||||
|
||||
If you control a channel you can also kick people off it:
|
||||
|
||||
|
|
@ -223,7 +223,7 @@ channels you could override the `help` command and change the lockstring to:
|
|||
|
||||
```
|
||||
|
||||
Add this custom command to your default cmdset and regular users wil now get an
|
||||
Add this custom command to your default cmdset and regular users will now get an
|
||||
access-denied error when trying to use use these switches.
|
||||
|
||||
## Using channels in code
|
||||
|
|
@ -263,7 +263,7 @@ below:
|
|||
3. `channel.at_post_channel_msg(message, **kwargs)`
|
||||
|
||||
Note that `Accounts` and `Objects` both have their have separate sets of hooks.
|
||||
So make sure you modify the set actually used by your subcribers (or both).
|
||||
So make sure you modify the set actually used by your subscribers (or both).
|
||||
Default channels all use `Account` subscribers.
|
||||
|
||||
### Channel class
|
||||
|
|
@ -379,7 +379,7 @@ Notable `Channel` hooks:
|
|||
a class-method that will happily remove found channel-aliases from the user linked to _any_
|
||||
channel, not only from the channel the method is called on.
|
||||
- `pre_join_channel(subscriber)` - if this returns `False`, connection will be refused.
|
||||
- `post_join_channel(subscriber)` - by default this sets up a users's channel-nicks/aliases.
|
||||
- `post_join_channel(subscriber)` - by default this sets up a users' channel-nicks/aliases.
|
||||
- `pre_leave_channel(subscriber)` - if this returns `False`, the user is not allowed to leave.
|
||||
- `post_leave_channel(subscriber)` - this will clean up any channel aliases/nicks of the user.
|
||||
- `delete` the standard typeclass-delete mechanism will also automatically un-subscribe all
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@
|
|||
|
||||
*Exits* are in-game [Objects](./Objects.md) connecting other objects (usually [Rooms](./Rooms.md)) together.
|
||||
|
||||
> Note that Exits are one-way objects, so in order for two Rooms to be linked bi-directionally, there will need to be two exits.
|
||||
|
||||
An object named `north` or `in` might be exits, as well as `door`, `portal` or `jump out the window`.
|
||||
|
||||
An exit has two things that separate them from other objects.
|
||||
|
|
@ -29,7 +31,7 @@ The default exit functionality is all defined on the [DefaultExit](DefaultExit)
|
|||
|
||||
Exits are [locked](./Locks.md) using an `access_type` called *traverse* and also make use of a few hook methods for giving feedback if the traversal fails. See `evennia.DefaultExit` for more info.
|
||||
|
||||
Exits are normally overridden on a case-by-case basis, but if you want to change the default exit createad by rooms like `dig` , `tunnel` or `open` you can change it in settings:
|
||||
Exits are normally overridden on a case-by-case basis, but if you want to change the default exit created by rooms like `dig`, `tunnel` or `open` you can change it in settings:
|
||||
|
||||
BASE_EXIT_TYPECLASS = "typeclasses.exits.Exit"
|
||||
|
||||
|
|
@ -53,3 +55,7 @@ The process of traversing an exit is as follows:
|
|||
1. On the Exit object, `at_post_traverse(obj, source)` is triggered.
|
||||
|
||||
If the move fails for whatever reason, the Exit will look for an Attribute `err_traverse` on itself and display this as an error message. If this is not found, the Exit will instead call `at_failed_traverse(obj)` on itself.
|
||||
|
||||
### Creating Exits in code
|
||||
|
||||
For an example of how to create Exits programatically please see [this guide](../Howtos/Beginner-Tutorial/Part1/Beginner-Tutorial-Creating-Things.md#linking-exits-and-rooms-in-code).
|
||||
|
|
|
|||
|
|
@ -104,7 +104,7 @@ Below are the access_types checked by the default commandset.
|
|||
- `search` - this controls if the object can be found with the
|
||||
`DefaultObject.search` method (usually referred to with `caller.search`
|
||||
in Commands). This is how to create entirely 'undetectable' in-game objects.
|
||||
If not setting this lock excplicitly, all objects are assumed searchable.
|
||||
If not setting this lock explicitly, all objects are assumed searchable.
|
||||
Note that if you are aiming to make some _permanently invisible game system,
|
||||
using a [Script](./Scripts.md) is a better bet.
|
||||
- `get`- who may pick up the object and carry it around.
|
||||
|
|
@ -330,7 +330,7 @@ error message. Sounds good! Let's start by setting that on the box:
|
|||
Next we need to craft a Lock of type *get* on our box. We want it to only be passed if the accessing
|
||||
object has the attribute *strength* of the right value. For this we would need to create a lock
|
||||
function that checks if attributes have a value greater than a given value. Luckily there is already
|
||||
such a one included in evennia (see `evennia/locks/lockfuncs.py`), called `attr_gt`.
|
||||
such a one included in Evennia (see `evennia/locks/lockfuncs.py`), called `attr_gt`.
|
||||
|
||||
So the lock string will look like this: `get:attr_gt(strength, 50)`. We put this on the box now:
|
||||
|
||||
|
|
|
|||
|
|
@ -88,7 +88,7 @@ If you cannot find your language in `evennia/evennia/locale/` it's because noone
|
|||
has translated it yet. Alternatively you might have the language but find the
|
||||
translation bad ... You are welcome to help improve the situation!
|
||||
|
||||
To start a new translation you need to first have cloned the Evennia repositry
|
||||
To start a new translation you need to first have cloned the Evennia repository
|
||||
with GIT and activated a python virtualenv as described on the
|
||||
[Setup Quickstart](../Setup/Installation.md) page.
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,26 @@
|
|||
# Components
|
||||
|
||||
_Contrib by ChrisLR 2021_
|
||||
Contrib by ChrisLR, 2021
|
||||
|
||||
# The Components Contrib
|
||||
Expand typeclasses using a components/composition approach.
|
||||
|
||||
## The Components Contrib
|
||||
|
||||
This contrib introduces Components and Composition to Evennia.
|
||||
Each 'Component' class represents a feature that will be 'enabled' on a typeclass instance.
|
||||
You can register these components on an entire typeclass or a single object at runtime.
|
||||
It supports both persisted attributes and in-memory attributes by using Evennia's AttributeHandler.
|
||||
|
||||
# Pros
|
||||
## Pros
|
||||
- You can reuse a feature across multiple typeclasses without inheritance
|
||||
- You can cleanly organize each feature into a self-contained class.
|
||||
- You can check if your object supports a feature without checking its instance.
|
||||
|
||||
# Cons
|
||||
## Cons
|
||||
- It introduces additional complexity.
|
||||
- A host typeclass instance is required.
|
||||
|
||||
# How to install
|
||||
## How to install
|
||||
|
||||
To enable component support for a typeclass,
|
||||
import and inherit the ComponentHolderMixin, similar to this
|
||||
|
|
@ -126,7 +128,7 @@ from typeclasses.components import health
|
|||
```
|
||||
Both of the above examples will work.
|
||||
|
||||
# Full Example
|
||||
## Full Example
|
||||
```python
|
||||
from evennia.contrib.base_systems import components
|
||||
|
||||
|
|
|
|||
|
|
@ -111,9 +111,9 @@ Additional color markup styles for Evennia (extending or replacing the default
|
|||
|
||||
### `components`
|
||||
|
||||
__Contrib by ChrisLR 2021__
|
||||
_Contrib by ChrisLR, 2021_
|
||||
|
||||
# The Components Contrib
|
||||
Expand typeclasses using a components/composition approach.
|
||||
|
||||
[Read the documentation](./Contrib-Components.md) - [Browse the Code](evennia.contrib.base_systems.components)
|
||||
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ Let's make us one of _those_!
|
|||
|
||||
create/drop button:tutorials.red_button.RedButton
|
||||
|
||||
The same way we did with the Script Earler, we specify a "Python-path" to the Python code we want Evennia to use for creating the object. There you go - one red button.
|
||||
The same way we did with the Script earlier, we specify a "Python-path" to the Python code we want Evennia to use for creating the object. There you go - one red button.
|
||||
|
||||
The RedButton is an example object intended to show off a few of Evennia's features. You will find that the [Typeclass](../../../Components/Typeclasses.md) and [Commands](../../../Components/Commands.md) controlling it are inside [evennia/contrib/tutorials/red_button](../../../api/evennia.contrib.tutorials.red_button.md)
|
||||
|
||||
|
|
|
|||
|
|
@ -320,7 +320,7 @@ class EvAdventureRollEngine:
|
|||
defender_defense = getattr(defender, defense_type.value, 1) + 10
|
||||
result, quality = self.saving_throw(attacker, bonus_type=attack_type,
|
||||
target=defender_defense,
|
||||
advantage=advantave, disadvantage=disadvantage)
|
||||
advantage=advantage, disadvantage=disadvantage)
|
||||
|
||||
return result, quality
|
||||
```
|
||||
|
|
@ -584,8 +584,8 @@ class TestEvAdventureRuleEngine(BaseEvenniaTest):
|
|||
@patch("evadventure.rules.randint")
|
||||
def test_roll(self, mock_randint):
|
||||
mock_randint.return_value = 4
|
||||
self.assertEqual(self.roll_engine.roll("1d6", 4)
|
||||
self.assertEqual(self.roll_engine.roll("2d6", 2 * 4)
|
||||
self.assertEqual(self.roll_engine.roll("1d6", 4))
|
||||
self.assertEqual(self.roll_engine.roll("2d6"), 2 * 4)
|
||||
|
||||
# test of the other rule methods below ...
|
||||
```
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ class NPCMerchant(Object):
|
|||
def open_shop(self, shopper):
|
||||
menunodes = {} # TODO!
|
||||
shopname = self.db.shopname or "The shop"
|
||||
EvMenu(shopper, menunodes, startnode="shop_start",
|
||||
EvMenu(shopper, menunodes, startnode="shopfront",
|
||||
shopname=shopname, shopkeeper=self, wares=self.contents)
|
||||
|
||||
```
|
||||
|
|
@ -215,7 +215,7 @@ class NPCMerchant(Object):
|
|||
"inspect_and_buy": node_inspect_and_buy
|
||||
}
|
||||
shopname = self.db.shopname or "The shop"
|
||||
EvMenu(shopper, menunodes, startnode="shop_start",
|
||||
EvMenu(shopper, menunodes, startnode="shopfront",
|
||||
shopname=shopname, shopkeeper=self, wares=self.contents)
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -78,6 +78,7 @@ If `localhost` doesn't work when trying to connect to your local game, try `127.
|
|||
## Mac Troubleshooting
|
||||
|
||||
- Some Mac users have reported not being able to connect to `localhost` (i.e. your own computer). If so, try to connect to `127.0.0.1` instead, which is the same thing. Use port 4000 from mud clients and port 4001 from the web browser as usual.
|
||||
- If you get a `MemoryError` when starting Evennia, or when looking at the log, this may be due to an sqlite versioning issue. [A user in our forums](https://github.com/evennia/evennia/discussions/2638#discussioncomment-3630761) found a working solution for this. [Here](https://github.com/evennia/evennia/issues/3120#issuecomment-1442540538) is another variation to solve it.
|
||||
|
||||
## Windows Troubleshooting
|
||||
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
1.2.1
|
||||
1.3.0
|
||||
|
|
|
|||
|
|
@ -20,7 +20,6 @@ from django.core.exceptions import ImproperlyConfigured, ValidationError
|
|||
from django.utils import timezone
|
||||
from django.utils.module_loading import import_string
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from evennia.accounts.manager import AccountManager
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.commands.cmdsethandler import CmdSetHandler
|
||||
|
|
@ -38,13 +37,7 @@ from evennia.typeclasses.attributes import ModelAttributeBackend, NickHandler
|
|||
from evennia.typeclasses.models import TypeclassBase
|
||||
from evennia.utils import class_from_module, create, logger
|
||||
from evennia.utils.optionhandler import OptionHandler
|
||||
from evennia.utils.utils import (
|
||||
is_iter,
|
||||
lazy_property,
|
||||
make_iter,
|
||||
to_str,
|
||||
variable_from_module,
|
||||
)
|
||||
from evennia.utils.utils import is_iter, lazy_property, make_iter, to_str, variable_from_module
|
||||
|
||||
__all__ = ("DefaultAccount", "DefaultGuest")
|
||||
|
||||
|
|
@ -509,7 +502,6 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase):
|
|||
Returns:
|
||||
validators (list): List of instantiated Validator objects.
|
||||
"""
|
||||
|
||||
objs = []
|
||||
for validator in validator_config:
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ Communication commands:
|
|||
"""
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from evennia.accounts import bots
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.comms.comms import DefaultChannel
|
||||
|
|
@ -777,7 +776,6 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
maxwidth=_DEFAULT_WIDTH,
|
||||
)
|
||||
for chan in subscribed:
|
||||
|
||||
locks = "-"
|
||||
chanid = "-"
|
||||
if chan.access(self.caller, "control"):
|
||||
|
|
@ -1158,7 +1156,6 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
reason = reason[0].strip() if reason else ""
|
||||
|
||||
for chan in channels:
|
||||
|
||||
if not chan.access(caller, "control"):
|
||||
self.msg(f"You need 'control'-access to boot a user from {chan.key}.")
|
||||
return
|
||||
|
|
@ -1245,9 +1242,11 @@ class CmdChannel(COMMAND_DEFAULT_CLASS):
|
|||
)
|
||||
ask_yes_no(
|
||||
caller,
|
||||
(
|
||||
f"Are you sure you want to ban user {target.key} from "
|
||||
f"channel(s) {channames} (make sure name/channels are correct{reasonwarn}) "
|
||||
"{options}?",
|
||||
"{options}?"
|
||||
),
|
||||
_ban_user,
|
||||
"Aborted.",
|
||||
)
|
||||
|
|
@ -1360,7 +1359,7 @@ class CmdPage(COMMAND_DEFAULT_CLASS):
|
|||
targets.append(target_obj)
|
||||
message = self.rhs.strip()
|
||||
else:
|
||||
target, *message = self.args.split(" ", 4)
|
||||
target, *message = self.args.split(" ", 1)
|
||||
if target and target.isnumeric():
|
||||
# a number to specify a historic page
|
||||
number = int(target)
|
||||
|
|
@ -1970,7 +1969,8 @@ class CmdDiscord2Chan(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
if not discord_bot.is_typeclass(settings.DISCORD_BOT_CLASS, exact=True):
|
||||
self.msg(
|
||||
f"WARNING: The Discord bot's typeclass is '{discord_bot.typeclass_path}'. This does not match {settings.DISCORD_BOT_CLASS} in settings!"
|
||||
f"WARNING: The Discord bot's typeclass is '{discord_bot.typeclass_path}'. This does"
|
||||
f" not match {settings.DISCORD_BOT_CLASS} in settings!"
|
||||
)
|
||||
|
||||
if "start" in self.switches:
|
||||
|
|
@ -1984,13 +1984,15 @@ class CmdDiscord2Chan(COMMAND_DEFAULT_CLASS):
|
|||
if "guild" in self.switches:
|
||||
discord_bot.db.tag_guild = not discord_bot.db.tag_guild
|
||||
self.msg(
|
||||
f"Messages to Evennia |wwill {'' if discord_bot.db.tag_guild else 'not '}|ninclude the Discord server."
|
||||
f"Messages to Evennia |wwill {'' if discord_bot.db.tag_guild else 'not '}|ninclude"
|
||||
" the Discord server."
|
||||
)
|
||||
return
|
||||
if "channel" in self.switches:
|
||||
discord_bot.db.tag_channel = not discord_bot.db.tag_channel
|
||||
self.msg(
|
||||
f"Relayed messages |wwill {'' if discord_bot.db.tag_channel else 'not '}|ninclude the originating channel."
|
||||
f"Relayed messages |wwill {'' if discord_bot.db.tag_channel else 'not '}|ninclude"
|
||||
" the originating channel."
|
||||
)
|
||||
return
|
||||
|
||||
|
|
@ -2029,7 +2031,8 @@ class CmdDiscord2Chan(COMMAND_DEFAULT_CLASS):
|
|||
dc_chan_names = discord_bot.attributes.get("discord_channels", {})
|
||||
dc_info = dc_chan_names.get(dc_chan, {"name": "unknown", "guild": "unknown"})
|
||||
self.msg(
|
||||
f"Removed link between {ev_chan} and #{dc_info.get('name','?')}@{dc_info.get('guild','?')}"
|
||||
f"Removed link between {ev_chan} and"
|
||||
f" #{dc_info.get('name','?')}@{dc_info.get('guild','?')}"
|
||||
)
|
||||
return
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -1,24 +1,26 @@
|
|||
# Components
|
||||
|
||||
_Contrib by ChrisLR 2021_
|
||||
Contrib by ChrisLR, 2021
|
||||
|
||||
# The Components Contrib
|
||||
Expand typeclasses using a components/composition approach.
|
||||
|
||||
## The Components Contrib
|
||||
|
||||
This contrib introduces Components and Composition to Evennia.
|
||||
Each 'Component' class represents a feature that will be 'enabled' on a typeclass instance.
|
||||
You can register these components on an entire typeclass or a single object at runtime.
|
||||
It supports both persisted attributes and in-memory attributes by using Evennia's AttributeHandler.
|
||||
|
||||
# Pros
|
||||
## Pros
|
||||
- You can reuse a feature across multiple typeclasses without inheritance
|
||||
- You can cleanly organize each feature into a self-contained class.
|
||||
- You can check if your object supports a feature without checking its instance.
|
||||
|
||||
# Cons
|
||||
## Cons
|
||||
- It introduces additional complexity.
|
||||
- A host typeclass instance is required.
|
||||
|
||||
# How to install
|
||||
## How to install
|
||||
|
||||
To enable component support for a typeclass,
|
||||
import and inherit the ComponentHolderMixin, similar to this
|
||||
|
|
@ -126,7 +128,7 @@ from typeclasses.components import health
|
|||
```
|
||||
Both of the above examples will work.
|
||||
|
||||
# Full Example
|
||||
## Full Example
|
||||
```python
|
||||
from evennia.contrib.base_systems import components
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import re
|
|||
from django.conf import settings
|
||||
from django.core.exceptions import ValidationError
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from evennia.accounts.models import AccountDB
|
||||
|
||||
|
||||
|
|
@ -24,7 +23,6 @@ class EvenniaUsernameAvailabilityValidator:
|
|||
raises ValidationError otherwise.
|
||||
|
||||
"""
|
||||
|
||||
# Check guest list
|
||||
if settings.GUEST_LIST and username.lower() in (
|
||||
guest.lower() for guest in settings.GUEST_LIST
|
||||
|
|
@ -45,8 +43,7 @@ class EvenniaPasswordValidator:
|
|||
def __init__(
|
||||
self,
|
||||
regex=r"^[\w. @+\-',]+$",
|
||||
policy="Password should contain a mix of letters, "
|
||||
"spaces, digits and @/./+/-/_/'/, only.",
|
||||
policy="Password should contain a mix of letters, spaces, digits and @/./+/-/_/'/, only.",
|
||||
):
|
||||
"""
|
||||
Constructs a standard Django password validator.
|
||||
|
|
|
|||
|
|
@ -558,9 +558,19 @@ class EvenniaTestCase(TestCase):
|
|||
"""
|
||||
For use with gamedir settings; Just like the normal test case, only for naming consistency.
|
||||
|
||||
Notes:
|
||||
|
||||
- Inheriting from this class will bypass EvenniaTestMixin, and therefore
|
||||
not setup some default objects. This can result in faster tests.
|
||||
|
||||
- If you do inherit from this class for your unit tests, and have
|
||||
overridden the tearDown() method, please also call flush_cache(). Not
|
||||
doing so will result in flakey and order-dependent tests due to the
|
||||
Django ID cache not being flushed.
|
||||
"""
|
||||
|
||||
pass
|
||||
def tearDown(self) -> None:
|
||||
flush_cache()
|
||||
|
||||
|
||||
@override_settings(**DEFAULT_SETTINGS)
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ from django.conf import settings
|
|||
from django.contrib import messages
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.urls import reverse_lazy
|
||||
|
||||
from evennia.utils import class_from_module
|
||||
from evennia.web.website import forms
|
||||
|
||||
|
|
@ -56,22 +55,16 @@ class AccountCreateView(AccountMixin, EvenniaCreateView):
|
|||
password = form.cleaned_data["password1"]
|
||||
email = form.cleaned_data.get("email", "")
|
||||
|
||||
# Create account
|
||||
# Create account. This also runs all validations on the username/password.
|
||||
account, errs = self.typeclass.create(username=username, password=password, email=email)
|
||||
|
||||
# If unsuccessful, display error messages to user
|
||||
if not account:
|
||||
[messages.error(self.request, err) for err in errs]
|
||||
|
||||
# Call the Django "form failure" hook
|
||||
# password validation happens earlier, only username checks appear here.
|
||||
form.add_error("username", ", ".join(errs))
|
||||
return self.form_invalid(form)
|
||||
|
||||
else:
|
||||
# Inform user of success
|
||||
messages.success(
|
||||
self.request,
|
||||
"Your account '%s' was successfully created! "
|
||||
"You may log in using it now." % account.name,
|
||||
self.request, f"Your account '{account.name}' was successfully created!"
|
||||
)
|
||||
|
||||
# Redirect the user to the login page
|
||||
return HttpResponseRedirect(self.success_url)
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|||
|
||||
[project]
|
||||
name = "evennia"
|
||||
version = "1.2.1"
|
||||
version = "1.3.0"
|
||||
maintainers = [{ name = "Griatch", email = "griatch@gmail.com" }]
|
||||
description = "A full-featured toolkit and server for text-based multiplayer games (MUDs, MU*, etc)."
|
||||
requires-python = ">=3.10"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue