diff --git a/evennia/accounts/accounts.py b/evennia/accounts/accounts.py index 6700e1e286..5c9e80bd7e 100644 --- a/evennia/accounts/accounts.py +++ b/evennia/accounts/accounts.py @@ -57,6 +57,7 @@ _MULTISESSION_MODE = settings.MULTISESSION_MODE _AUTO_CREATE_CHARACTER_WITH_ACCOUNT = settings.AUTO_CREATE_CHARACTER_WITH_ACCOUNT _AUTO_PUPPET_ON_LOGIN = settings.AUTO_PUPPET_ON_LOGIN _MAX_NR_SIMULTANEOUS_PUPPETS = settings.MAX_NR_SIMULTANEOUS_PUPPETS +_PERMISSION_MULTIPLE_PUPPETS = settings.PERMISSION_MULTIPLE_PUPPETS _MAX_NR_CHARACTERS = settings.MAX_NR_CHARACTERS _CMDSET_ACCOUNT = settings.CMDSET_ACCOUNT _MUDINFO_CHANNEL = None @@ -526,7 +527,7 @@ class DefaultAccount(AccountDB, metaclass=TypeclassBase): already_puppeted = self.get_all_puppets() if ( not self.is_superuser - and not self.check_permstring("Developer") + and not self.check_permstring(_PERMISSION_MULTIPLE_PUPPETS) and obj not in already_puppeted and len(self.get_all_puppets()) >= _MAX_NR_SIMULTANEOUS_PUPPETS ): diff --git a/evennia/accounts/tests.py b/evennia/accounts/tests.py index d6268b3162..497df1dfbe 100644 --- a/evennia/accounts/tests.py +++ b/evennia/accounts/tests.py @@ -427,6 +427,26 @@ class TestDefaultAccountEv(BaseEvenniaTest): self.account.puppet_object(self.session, self.char1) self.account.msg.assert_called_with("You are already puppeting this object.") + def test_puppet_limit(self): + "Test that PERMISSION_MULTIPLE_PUPPETS controls who can bypass the puppet limit." + self.account.msg = MagicMock() + self.char2.locks.add("puppet:all()") + with ( + patch.object(self.account, "get_all_puppets", return_value=[MagicMock()]), + patch("evennia.accounts.accounts._MULTISESSION_MODE", 2), + patch("evennia.accounts.accounts._MAX_NR_SIMULTANEOUS_PUPPETS", 1), + patch("evennia.accounts.accounts._PERMISSION_MULTIPLE_PUPPETS", "Developer"), + ): + self.account.is_superuser = False + self.account.permissions.remove("Developer") + self.account.puppet_object(self.session, self.char2) + self.account.msg.assert_called_with("You cannot control any more puppets (max 1)") + + self.account.msg.reset_mock() + self.account.permissions.add("Developer") + self.account.puppet_object(self.session, self.char2) + self.account.msg.assert_not_called() + @patch("evennia.accounts.accounts.time.time", return_value=10000) def test_idle_time(self, mock_time): self.session.cmd_last_visible = 10000 - 10 diff --git a/evennia/settings_default.py b/evennia/settings_default.py index 4eb71067ea..62b369eef8 100644 --- a/evennia/settings_default.py +++ b/evennia/settings_default.py @@ -810,6 +810,8 @@ AUTO_PUPPET_ON_LOGIN = True # How many *different* characters an account can puppet *at the same time*. A value # above 1 only makes a difference together with MULTISESSION_MODE > 1. MAX_NR_SIMULTANEOUS_PUPPETS = 1 +# The permission required to bypass MAX_NR_SIMULTANEOUS_PUPPETS. +PERMISSION_MULTIPLE_PUPPETS = "Developer" # The maximum number of characters allowed by be created by the default ooc # char-creation command. This can be seen as how big of a 'stable' of characters # an account can have (not how many you can puppet at the same time). Set to