Merge branch 'evennia:main' into spawnupdate-fix
This commit is contained in:
commit
7c81d37e36
47 changed files with 422 additions and 373 deletions
|
|
@ -1 +1 @@
|
|||
1.0-dev
|
||||
1.0.2
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import time
|
|||
from codecs import lookup as codecs_lookup
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
from evennia.server.sessionhandler import SESSIONS
|
||||
from evennia.utils import create, logger, search, utils
|
||||
|
||||
|
|
@ -191,7 +190,8 @@ class CmdCharCreate(COMMAND_DEFAULT_CLASS):
|
|||
elif not new_character.db.desc:
|
||||
new_character.db.desc = "This is a character."
|
||||
self.msg(
|
||||
f"Created new character {new_character.key}. Use |wic {new_character.key}|n to enter the game as this character."
|
||||
f"Created new character {new_character.key}. Use |wic {new_character.key}|n to enter"
|
||||
" the game as this character."
|
||||
)
|
||||
logger.log_sec(
|
||||
f"Character Created: {new_character} (Caller: {account}, IP: {self.session.address})."
|
||||
|
|
@ -317,11 +317,13 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
|
|||
if account.db._playable_characters:
|
||||
# look at the playable_characters list first
|
||||
character_candidates.extend(
|
||||
account.search(
|
||||
self.args,
|
||||
candidates=account.db._playable_characters,
|
||||
search_object=True,
|
||||
quiet=True,
|
||||
utils.make_iter(
|
||||
account.search(
|
||||
self.args,
|
||||
candidates=account.db._playable_characters,
|
||||
search_object=True,
|
||||
quiet=True,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
|
@ -370,12 +372,14 @@ class CmdIC(COMMAND_DEFAULT_CLASS):
|
|||
account.puppet_object(session, new_character)
|
||||
account.db._last_puppet = new_character
|
||||
logger.log_sec(
|
||||
f"Puppet Success: (Caller: {account}, Target: {new_character}, IP: {self.session.address})."
|
||||
f"Puppet Success: (Caller: {account}, Target: {new_character}, IP:"
|
||||
f" {self.session.address})."
|
||||
)
|
||||
except RuntimeError as exc:
|
||||
self.msg(f"|rYou cannot become |C{new_character.name}|n: {exc}")
|
||||
logger.log_sec(
|
||||
f"Puppet Failed: %s (Caller: {account}, Target: {new_character}, IP: {self.session.address})."
|
||||
f"Puppet Failed: %s (Caller: {account}, Target: {new_character}, IP:"
|
||||
f" {self.session.address})."
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -670,7 +674,8 @@ class CmdOption(COMMAND_DEFAULT_CLASS):
|
|||
else:
|
||||
flags[new_name] = new_val
|
||||
self.msg(
|
||||
f"Option |w{new_name}|n was changed from '|w{old_val}|n' to '|w{new_val}|n'."
|
||||
f"Option |w{new_name}|n was changed from '|w{old_val}|n' to"
|
||||
f" '|w{new_val}|n'."
|
||||
)
|
||||
return {new_name: new_val}
|
||||
except Exception as err:
|
||||
|
|
@ -1024,7 +1029,7 @@ class CmdStyle(COMMAND_DEFAULT_CLASS):
|
|||
style <option> = <value>
|
||||
|
||||
Configure stylings for in-game display elements like table borders, help
|
||||
entriest etc. Use without arguments to see all available options.
|
||||
entries etc. Use without arguments to see all available options.
|
||||
|
||||
"""
|
||||
|
||||
|
|
|
|||
|
|
@ -1925,6 +1925,7 @@ class CmdDiscord2Chan(COMMAND_DEFAULT_CLASS):
|
|||
/delete - alias to remove
|
||||
/guild - toggle the Discord server tag on/off
|
||||
/channel - toggle the Evennia/Discord channel tags on/off
|
||||
/start - tell the bot to start, in case it lost its connection
|
||||
|
||||
Example:
|
||||
discord2chan mydiscord = 555555555555555
|
||||
|
|
@ -1943,6 +1944,7 @@ class CmdDiscord2Chan(COMMAND_DEFAULT_CLASS):
|
|||
"guild",
|
||||
"list",
|
||||
"remove",
|
||||
"start",
|
||||
)
|
||||
locks = "cmd:serversetting(DISCORD_ENABLED) and pperm(Developer)"
|
||||
help_category = "Comms"
|
||||
|
|
@ -1973,6 +1975,13 @@ class CmdDiscord2Chan(COMMAND_DEFAULT_CLASS):
|
|||
f"WARNING: The Discord bot's typeclass is '{discord_bot.typeclass_path}'. This does not match {settings.DISCORD_BOT_CLASS} in settings!"
|
||||
)
|
||||
|
||||
if "start" in self.switches:
|
||||
if discord_bot.sessions.all():
|
||||
self.msg("The Discord bot is already running.")
|
||||
else:
|
||||
discord_bot.start()
|
||||
return
|
||||
|
||||
if "guild" in self.switches:
|
||||
discord_bot.db.tag_guild = not discord_bot.db.tag_guild
|
||||
self.msg(
|
||||
|
|
|
|||
|
|
@ -371,8 +371,9 @@ class CmdInventory(COMMAND_DEFAULT_CLASS):
|
|||
|
||||
table = self.styled_table(border="header")
|
||||
for item in items:
|
||||
singular, _ = item.get_numbered_name(1, self.caller)
|
||||
table.add_row(
|
||||
f"|C{item.name}|n",
|
||||
f"|C{singular}|n",
|
||||
"{}|n".format(utils.crop(raw_ansi(item.db.desc or ""), width=50) or ""),
|
||||
)
|
||||
string = f"|wYou are carrying:\n{table}"
|
||||
|
|
@ -424,8 +425,8 @@ class CmdGet(COMMAND_DEFAULT_CLASS):
|
|||
if not success:
|
||||
caller.msg("This can't be picked up.")
|
||||
else:
|
||||
caller.msg(f"You pick up {obj.name}.")
|
||||
caller.location.msg_contents(f"{caller.name} picks up {obj.name}.", exclude=caller)
|
||||
singular, _ = obj.get_numbered_name(1, caller)
|
||||
caller.location.msg_contents(f"$You() $conj(pick) up {singular}.", from_obj=caller)
|
||||
# calling at_get hook method
|
||||
obj.at_get(caller)
|
||||
|
||||
|
|
@ -472,8 +473,8 @@ class CmdDrop(COMMAND_DEFAULT_CLASS):
|
|||
if not success:
|
||||
caller.msg("This couldn't be dropped.")
|
||||
else:
|
||||
caller.msg("You drop %s." % (obj.name,))
|
||||
caller.location.msg_contents(f"{caller.name} drops {obj.name}.", exclude=caller)
|
||||
singular, _ = obj.get_numbered_name(1, caller)
|
||||
caller.location.msg_contents(f"$You() $conj(drop) {singular}.", from_obj=caller)
|
||||
# Call the object script's at_drop() method.
|
||||
obj.at_drop(caller)
|
||||
|
||||
|
|
@ -510,11 +511,13 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
target = caller.search(self.rhs)
|
||||
if not (to_give and target):
|
||||
return
|
||||
|
||||
singular, _ = to_give.get_numbered_name(1, caller)
|
||||
if target == caller:
|
||||
caller.msg(f"You keep {to_give.key} to yourself.")
|
||||
caller.msg(f"You keep {singular} to yourself.")
|
||||
return
|
||||
if not to_give.location == caller:
|
||||
caller.msg(f"You are not holding {to_give.key}.")
|
||||
caller.msg(f"You are not holding {singular}.")
|
||||
return
|
||||
|
||||
# calling at_pre_give hook method
|
||||
|
|
@ -524,10 +527,10 @@ class CmdGive(COMMAND_DEFAULT_CLASS):
|
|||
# give object
|
||||
success = to_give.move_to(target, quiet=True, move_type="give")
|
||||
if not success:
|
||||
caller.msg(f"You could not give {to_give.key}.")
|
||||
caller.msg(f"You could not give {singular} to {target.key}.")
|
||||
else:
|
||||
caller.msg(f"You give {to_give.key} to {target.key}.")
|
||||
target.msg(f"{caller.key} gives you {to_give.key}.")
|
||||
caller.msg(f"You give {singular} to {target.key}.")
|
||||
target.msg(f"{caller.key} gives you {singular}.")
|
||||
# Call the object script's at_give() method.
|
||||
to_give.at_give(caller, target)
|
||||
|
||||
|
|
|
|||
|
|
@ -627,7 +627,7 @@ class CmdHelp(COMMAND_DEFAULT_CLASS):
|
|||
)
|
||||
if suggestions:
|
||||
help_text += (
|
||||
"\n... But matches where found within the help "
|
||||
"\n... But matches were found within the help "
|
||||
"texts of the suggestions below."
|
||||
)
|
||||
suggestions = [
|
||||
|
|
|
|||
|
|
@ -112,13 +112,13 @@ class TestGeneral(BaseEvenniaCommandTest):
|
|||
self.call(general.CmdNick(), "/list", "Defined Nicks:")
|
||||
|
||||
def test_get_and_drop(self):
|
||||
self.call(general.CmdGet(), "Obj", "You pick up Obj.")
|
||||
self.call(general.CmdDrop(), "Obj", "You drop Obj.")
|
||||
self.call(general.CmdGet(), "Obj", "You pick up an Obj.")
|
||||
self.call(general.CmdDrop(), "Obj", "You drop an Obj.")
|
||||
|
||||
def test_give(self):
|
||||
self.call(general.CmdGive(), "Obj to Char2", "You aren't carrying Obj.")
|
||||
self.call(general.CmdGive(), "Obj = Char2", "You aren't carrying Obj.")
|
||||
self.call(general.CmdGet(), "Obj", "You pick up Obj.")
|
||||
self.call(general.CmdGet(), "Obj", "You pick up an Obj.")
|
||||
self.call(general.CmdGive(), "Obj to Char2", "You give")
|
||||
self.call(general.CmdGive(), "Obj = Char", "You give", caller=self.char2)
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class Character(ComponentHolderMixin, DefaultCharacter):
|
|||
|
||||
Components need to inherit the Component class directly and require a name.
|
||||
```python
|
||||
from evennia.contrib.components import Component
|
||||
from evennia.contrib.base_systems.components import Component
|
||||
|
||||
class Health(Component):
|
||||
name = "health"
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ is being combined instead):
|
|||
See the [sword example](evennia.contrib.game_systems.crafting.example_recipes) for an example
|
||||
of how to design a recipe tree for crafting a sword from base elements.
|
||||
|
||||
## Intallation and Usage
|
||||
## Installation and Usage
|
||||
|
||||
Import the `CmdCraft` command from evennia/contrib/crafting/crafting.py and
|
||||
add it to your Character cmdset. Reload and the `craft` command will be
|
||||
|
|
@ -115,7 +115,7 @@ class RecipeBread(CraftingRecipe):
|
|||
## Adding new recipes
|
||||
|
||||
A *recipe* is a class inheriting from
|
||||
`evennia.contrib.crafting.crafting.CraftingRecipe`. This class implements the
|
||||
`evennia.contrib.game_systems.crafting.CraftingRecipe`. This class implements the
|
||||
most common form of crafting - that using in-game objects. Each recipe is a
|
||||
separate class which gets initialized with the consumables/tools you provide.
|
||||
|
||||
|
|
@ -137,7 +137,7 @@ example setting:
|
|||
```python
|
||||
# in mygame/world/myrecipes.py
|
||||
|
||||
from evennia.contrib.crafting.crafting import CraftingRecipe
|
||||
from evennia.contrib.game_systems.crafting import CraftingRecipe
|
||||
|
||||
class WoodenPuppetRecipe(CraftingRecipe):
|
||||
"""A puppet""""
|
||||
|
|
@ -200,7 +200,7 @@ in-game command:
|
|||
In code we would do
|
||||
|
||||
```python
|
||||
from evennia.contrib.crafting.crafting import craft
|
||||
from evennia.contrib.game_systems.crafting import craft
|
||||
puppet = craft(crafter, "wooden puppet", knife, wood)
|
||||
|
||||
```
|
||||
|
|
@ -259,7 +259,7 @@ parent class and have your recipes inherit from this.
|
|||
|
||||
```python
|
||||
from random import randint
|
||||
from evennia.contrib.crafting.crafting import CraftingRecipe
|
||||
from evennia.contrib.game_systems.crafting import CraftingRecipe
|
||||
|
||||
class SkillRecipe(CraftingRecipe):
|
||||
"""A recipe that considers skill"""
|
||||
|
|
|
|||
|
|
@ -16,11 +16,12 @@ In more detail, in `mygame/commands/default_cmdsets.py`:
|
|||
|
||||
```python
|
||||
...
|
||||
from evennia.contrib import extended_room # <---
|
||||
from evennia.contrib.grid import extended_room # <---
|
||||
|
||||
class CharacterCmdset(default_cmds.Character_CmdSet):
|
||||
class CharacterCmdset(default_cmds.CharacterCmdSet):
|
||||
...
|
||||
def at_cmdset_creation(self):
|
||||
super().at_cmdset_creation()
|
||||
...
|
||||
self.add(extended_room.ExtendedRoomCmdSet) # <---
|
||||
|
||||
|
|
@ -28,7 +29,10 @@ class CharacterCmdset(default_cmds.Character_CmdSet):
|
|||
|
||||
Then reload to make the new commands available. Note that they only work
|
||||
on rooms with the typeclass `ExtendedRoom`. Create new rooms with the right
|
||||
typeclass or use the `typeclass` command to swap existing rooms.
|
||||
typeclass or use the `typeclass` command to swap existing rooms. Note that since
|
||||
this contrib overrides the `look` command, you will need to add the
|
||||
`extended_room.ExtendedRoomCmdSet` to the default character cmdset *after*
|
||||
super().at_cmdset_creation(), or it will be overridden by the default look.
|
||||
|
||||
## Features
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Specifically, in `mygame/commands/default_cmdsets.py`:
|
|||
...
|
||||
from evennia.contrib.grid.ingame_map_display import MapDisplayCmdSet # <---
|
||||
|
||||
class CharacterCmdset(default_cmds.Character_CmdSet):
|
||||
class CharacterCmdset(default_cmds.CharacterCmdSet):
|
||||
...
|
||||
def at_cmdset_creation(self):
|
||||
...
|
||||
|
|
|
|||
|
|
@ -2,14 +2,6 @@
|
|||
XYZGrid - Griatch 2021
|
||||
|
||||
"""
|
||||
from . import example, launchcmd, prototypes, tests, utils, xymap, xymap_legend, xyzgrid, xyzroom
|
||||
|
||||
from . import commands # noqa
|
||||
from . import example # noqa
|
||||
from . import launchcmd # noqa
|
||||
from . import prototypes # noqa
|
||||
from . import tests # noqa
|
||||
from . import utils # noqa
|
||||
from . import xymap # noqa
|
||||
from . import xymap_legend # noqa
|
||||
from . import xyzgrid # noqa
|
||||
from . import xyzroom # noqa
|
||||
from . import commands # isort:skip - this needs to be imported last
|
||||
|
|
|
|||
|
|
@ -463,7 +463,10 @@ class XYZRoom(DefaultRoom):
|
|||
)
|
||||
|
||||
sessions = looker.sessions.get()
|
||||
client_width, _ = sessions[0].get_client_size() if sessions else CLIENT_DEFAULT_WIDTH
|
||||
if sessions:
|
||||
client_width, _ = sessions[0].get_client_size()
|
||||
else:
|
||||
client_width = CLIENT_DEFAULT_WIDTH
|
||||
|
||||
map_width = xymap.max_x
|
||||
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ This module adds no new commands; embed it in your say/emote/whisper commands.
|
|||
### Usage:
|
||||
|
||||
```python
|
||||
from evennia.contrib import rplanguage
|
||||
from evennia.contrib.rpg.rpsystem import rplanguage
|
||||
|
||||
# need to be done once, here we create the "default" lang
|
||||
rplanguage.add_language()
|
||||
|
|
|
|||
|
|
@ -128,7 +128,6 @@ class EvAdventureDungeonRoom(EvAdventureRoom):
|
|||
class EvAdventureDungeonExit(DefaultExit):
|
||||
"""
|
||||
Dungeon exit. This will not create the target room until it's traversed.
|
||||
It must be created referencing the dungeon_orchestrator it belongs to.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -142,7 +141,8 @@ class EvAdventureDungeonExit(DefaultExit):
|
|||
def at_traverse(self, traversing_object, target_location, **kwargs):
|
||||
"""
|
||||
Called when traversing. `target_location` will be None if the
|
||||
target was not yet created.
|
||||
target was not yet created. It checks the current location to get the
|
||||
dungeon-orchestrator in use.
|
||||
|
||||
"""
|
||||
if target_location == self.location:
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ object with its own functionality and state tracking.
|
|||
|
||||
Create the button with
|
||||
|
||||
create/drop button:tutorials.red_button.RedButton
|
||||
create/drop button:contrib.tutorials.red_button.RedButton
|
||||
|
||||
Note that you must drop the button before you can see its messages! It's
|
||||
imperative that you press the red button. You know you want to.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ Evmenu.
|
|||
|
||||
Log in as superuser (#1), then run
|
||||
|
||||
batchcommand tutorials.tutorial_world.build
|
||||
batchcommand contrib.tutorials.tutorial_world.build
|
||||
|
||||
Wait a little while for building to complete and don't run the command
|
||||
again even if it's slow. This builds the world and connect it to Limbo
|
||||
|
|
|
|||
|
|
@ -31,25 +31,27 @@ HELP_ENTRY_DICTS = [
|
|||
"category": "General",
|
||||
"locks": "read:perm(Developer)",
|
||||
"text": """
|
||||
Evennia is a MUD game server in Python.
|
||||
Evennia is a MU-game server and framework written in Python. You can read more
|
||||
on https://www.evennia.com.
|
||||
|
||||
# subtopics
|
||||
|
||||
## Installation
|
||||
|
||||
You'll find installation instructions on https:evennia.com
|
||||
You'll find installation instructions on https://www.evennia.com.
|
||||
|
||||
## Community
|
||||
|
||||
There are many ways to get help and communicate with other devs!
|
||||
|
||||
### IRC
|
||||
### Discussions
|
||||
|
||||
The irc channel is #evennia on irc.freenode.net
|
||||
The Discussions forum is found at https://github.com/evennia/evennia/discussions.
|
||||
|
||||
### Discord
|
||||
|
||||
There is also a discord channel you can find from the sidebard on evennia.com.
|
||||
There is also a discord channel for chatting - connect using the
|
||||
following link: https://discord.gg/AJJpcRUhtF
|
||||
|
||||
""",
|
||||
},
|
||||
|
|
@ -58,7 +60,7 @@ HELP_ENTRY_DICTS = [
|
|||
"category": "building",
|
||||
"text": """
|
||||
Evennia comes with a bunch of default building commands. You can
|
||||
find a building tutorial in the evennia documentation.
|
||||
find a beginner tutorial in the Evennia documentation.
|
||||
|
||||
""",
|
||||
},
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -8,7 +8,7 @@ msgstr ""
|
|||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2022-10-29 18:53+0000\n"
|
||||
"PO-Revision-Date: 2022-03-20 19:55+0100\n"
|
||||
"PO-Revision-Date: 2022-12-16 15:09+0100\n"
|
||||
"Last-Translator: Christophe Petry <toktoktheeo@outlook.com>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr\n"
|
||||
|
|
@ -16,7 +16,7 @@ msgstr ""
|
|||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
"X-Generator: Poedit 3.0.1\n"
|
||||
"X-Generator: Poedit 3.2.2\n"
|
||||
|
||||
#: accounts/accounts.py:341
|
||||
#, python-brace-format
|
||||
|
|
@ -28,6 +28,8 @@ msgstr "|c{key}|R est déjà contrôlé par un autre compte."
|
|||
msgid ""
|
||||
"You cannot control any more puppets (max {_MAX_NR_SIMULTANEOUS_PUPPETS})"
|
||||
msgstr ""
|
||||
"Vous ne pouvez contrôler plus de poupées (Maximum : "
|
||||
"{_MAX_NR_SIMULTANEOUS_PUPPETS})"
|
||||
|
||||
#: accounts/accounts.py:555
|
||||
msgid "Too many login failures; please try again in a few minutes."
|
||||
|
|
@ -73,9 +75,8 @@ msgstr ""
|
|||
"problème persiste."
|
||||
|
||||
#: accounts/accounts.py:918
|
||||
#, fuzzy
|
||||
msgid "Account being deleted."
|
||||
msgstr "Suppression du compte."
|
||||
msgstr "Le compte a été supprimé."
|
||||
|
||||
#: accounts/accounts.py:1475 accounts/accounts.py:1819
|
||||
#, python-brace-format
|
||||
|
|
@ -382,12 +383,12 @@ msgstr "Vous avez maintenant {name} en votre possession."
|
|||
#: objects/objects.py:1863
|
||||
#, python-brace-format
|
||||
msgid "{object} arrives to {destination} from {origin}."
|
||||
msgstr ""
|
||||
msgstr "{object} arrive à {destination} depuis {origin}."
|
||||
|
||||
#: objects/objects.py:1865
|
||||
#, python-brace-format
|
||||
msgid "{object} arrives to {destination}."
|
||||
msgstr ""
|
||||
msgstr "{object} arrive à {destination}."
|
||||
|
||||
#: objects/objects.py:2530
|
||||
msgid "Invalid character name."
|
||||
|
|
@ -421,10 +422,9 @@ msgid "{name} has entered the game."
|
|||
msgstr "{name} est entré(e) dans le jeu."
|
||||
|
||||
#: objects/objects.py:2716
|
||||
#, fuzzy, python-brace-format
|
||||
#| msgid "{name} has left the game."
|
||||
#, python-brace-format
|
||||
msgid "{name} has left the game{reason}."
|
||||
msgstr "{name} est sorti(e) du jeu."
|
||||
msgstr "{name} est sorti(e) du jeu ({reason})."
|
||||
|
||||
#: objects/objects.py:2838
|
||||
msgid "This is a room."
|
||||
|
|
@ -552,6 +552,8 @@ msgid ""
|
|||
"Diff contains non-dicts that are not on the form (old, new, action_to_take): "
|
||||
"{diffpart}"
|
||||
msgstr ""
|
||||
"\"diff\" contient des non-dicts qui ne sont pas formatés (ancien, nouveau, "
|
||||
"action à prendre): {diffpart}"
|
||||
|
||||
#: scripts/scripthandler.py:51
|
||||
#, fuzzy, python-brace-format
|
||||
|
|
@ -613,7 +615,7 @@ msgstr "délai d'inactivité dépassé"
|
|||
|
||||
#: server/server.py:177
|
||||
msgid " (connection lost)"
|
||||
msgstr ""
|
||||
msgstr " (connexion perdue)"
|
||||
|
||||
#: server/sessionhandler.py:41
|
||||
msgid "Your client sent an incorrect UTF-8 sequence."
|
||||
|
|
@ -738,6 +740,8 @@ msgstr ""
|
|||
#: utils/eveditor.py:143
|
||||
msgid "|rNo save function defined. Buffer cannot be saved.|n"
|
||||
msgstr ""
|
||||
"|rAucune fonction d'enregistrement définie. La pile ne peut être "
|
||||
"sauvegardée.|n"
|
||||
|
||||
#: utils/eveditor.py:145
|
||||
msgid "No changes need saving"
|
||||
|
|
@ -745,7 +749,7 @@ msgstr "Aucune modification ne doit être sauvegardée"
|
|||
|
||||
#: utils/eveditor.py:146
|
||||
msgid "Exited editor."
|
||||
msgstr "Sortie de l'éditeur:"
|
||||
msgstr "Sortie de l'éditeur."
|
||||
|
||||
#: utils/eveditor.py:149
|
||||
#, python-brace-format
|
||||
|
|
@ -755,6 +759,10 @@ msgid ""
|
|||
"\n"
|
||||
"|rQuit function gave an error. Skipping.|n\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"{error}\n"
|
||||
"\n"
|
||||
"|rLa fonction quitter à retourner une erreur. On passe.|n\n"
|
||||
|
||||
#: utils/eveditor.py:157
|
||||
#, python-brace-format
|
||||
|
|
@ -766,6 +774,13 @@ msgid ""
|
|||
"to non-persistent mode (which means the editor session won't survive\n"
|
||||
"an eventual server reload - so save often!)|n\n"
|
||||
msgstr ""
|
||||
"\n"
|
||||
"{error}\n"
|
||||
"\n"
|
||||
"L'éditeur n'a pas pu sauvergarder en mode persistent. Changement pour le "
|
||||
"mode non-persistant. \n"
|
||||
"Cela signifie que l'éditeur ne survivra pas à un rechargement du serveur, \n"
|
||||
"alors sauvegardez souvent !\n"
|
||||
|
||||
#: utils/eveditor.py:167
|
||||
msgid ""
|
||||
|
|
@ -773,26 +788,29 @@ msgid ""
|
|||
"EvEditor callbacks could not be pickled, for example because it's a class "
|
||||
"method or is defined inside another function."
|
||||
msgstr ""
|
||||
"EvEditeur erreur du mode persistant. Usuellement, c'est lorsque un ou "
|
||||
"plusieurs appel n'ont pu aboutir dans l'éditeur. Par exemple, c'est "
|
||||
"parcequ'une méthode de class et définie à l'intérieur d'une autre fonction."
|
||||
|
||||
#: utils/eveditor.py:173
|
||||
msgid "Nothing to undo."
|
||||
msgstr ""
|
||||
msgstr "Rien pour revenir en arrière."
|
||||
|
||||
#: utils/eveditor.py:174
|
||||
msgid "Nothing to redo."
|
||||
msgstr ""
|
||||
msgstr "Rien à rétablir."
|
||||
|
||||
#: utils/eveditor.py:175
|
||||
msgid "Undid one step."
|
||||
msgstr ""
|
||||
msgstr "Un pas supprimé."
|
||||
|
||||
#: utils/eveditor.py:176
|
||||
msgid "Redid one step."
|
||||
msgstr ""
|
||||
msgstr "Un pas ajouté."
|
||||
|
||||
#: utils/eveditor.py:494
|
||||
msgid "Single ':' added to buffer."
|
||||
msgstr ""
|
||||
msgstr "Un seul ':' ajouté à la pile."
|
||||
|
||||
#: utils/eveditor.py:509
|
||||
msgid "Save before quitting?"
|
||||
|
|
@ -806,7 +824,7 @@ msgstr ""
|
|||
#: utils/eveditor.py:529
|
||||
#, python-brace-format
|
||||
msgid "Deleted {string}."
|
||||
msgstr ""
|
||||
msgstr "{string} supprimé."
|
||||
|
||||
#: utils/eveditor.py:534
|
||||
msgid "You must give a search word to delete."
|
||||
|
|
@ -815,17 +833,17 @@ msgstr "Vous devez donner un mot de recherche à supprimer."
|
|||
#: utils/eveditor.py:540
|
||||
#, python-brace-format
|
||||
msgid "Removed {arg1} for lines {l1}-{l2}."
|
||||
msgstr ""
|
||||
msgstr "{arg1} retiré des lignes {l1}-{l2}."
|
||||
|
||||
#: utils/eveditor.py:546
|
||||
#, python-brace-format
|
||||
msgid "Removed {arg1} for {line}."
|
||||
msgstr ""
|
||||
msgstr "{arg1} retiré de la ligne {line}"
|
||||
|
||||
#: utils/eveditor.py:562
|
||||
#, python-brace-format
|
||||
msgid "Cleared {nlines} lines from buffer."
|
||||
msgstr ""
|
||||
msgstr "{nlines} lignes nettoyées depuis la pile."
|
||||
|
||||
#: utils/eveditor.py:567
|
||||
#, python-brace-format
|
||||
|
|
@ -835,7 +853,7 @@ msgstr ""
|
|||
#: utils/eveditor.py:574
|
||||
#, python-brace-format
|
||||
msgid "{line}, {cbuf} cut."
|
||||
msgstr ""
|
||||
msgstr "{line}, {cbuf} coupée."
|
||||
|
||||
#: utils/eveditor.py:578
|
||||
msgid "Copy buffer is empty."
|
||||
|
|
@ -844,7 +862,7 @@ msgstr "Le tampon de copie est vide."
|
|||
#: utils/eveditor.py:583
|
||||
#, python-brace-format
|
||||
msgid "Pasted buffer {cbuf} to {line}."
|
||||
msgstr ""
|
||||
msgstr "La Pile (buffer) copié de {cbuf} à {line}"
|
||||
|
||||
#: utils/eveditor.py:591
|
||||
msgid "You need to enter a new line and where to insert it."
|
||||
|
|
@ -853,7 +871,7 @@ msgstr "Vous devez saisir une nouvelle ligne et indiquer où l'insérer."
|
|||
#: utils/eveditor.py:596
|
||||
#, python-brace-format
|
||||
msgid "Inserted {num} new line(s) at {line}."
|
||||
msgstr ""
|
||||
msgstr "{num} ligne(s) insérée(s) depuis la ligne : {line}."
|
||||
|
||||
#: utils/eveditor.py:604
|
||||
msgid "You need to enter a replacement string."
|
||||
|
|
@ -862,7 +880,7 @@ msgstr "Vous devez saisir une chaîne de remplacement."
|
|||
#: utils/eveditor.py:609
|
||||
#, python-brace-format
|
||||
msgid "Replaced {num} line(s) at {line}."
|
||||
msgstr ""
|
||||
msgstr "{num} lignes remplacées à partir de la ligne {line}."
|
||||
|
||||
#: utils/eveditor.py:616
|
||||
msgid "You need to enter text to insert."
|
||||
|
|
@ -871,16 +889,16 @@ msgstr "Vous devez saisir le texte à insérer."
|
|||
#: utils/eveditor.py:624
|
||||
#, python-brace-format
|
||||
msgid "Inserted text at beginning of {line}."
|
||||
msgstr ""
|
||||
msgstr "Texte ajouté au début de la ligne {line}."
|
||||
|
||||
#: utils/eveditor.py:628
|
||||
msgid "You need to enter text to append."
|
||||
msgstr ""
|
||||
msgstr "Vous avez besoin d'insérer du texte à ajouter."
|
||||
|
||||
#: utils/eveditor.py:636
|
||||
#, python-brace-format
|
||||
msgid "Appended text to end of {line}."
|
||||
msgstr ""
|
||||
msgstr "Text ajouté à la fin de la ligne {line}."
|
||||
|
||||
#: utils/eveditor.py:641
|
||||
msgid "You must give a search word and something to replace it with."
|
||||
|
|
@ -890,36 +908,36 @@ msgstr ""
|
|||
#: utils/eveditor.py:647
|
||||
#, python-brace-format
|
||||
msgid "Search-replaced {arg1} -> {arg2} for lines {l1}-{l2}."
|
||||
msgstr ""
|
||||
msgstr "Rechercher-remplacer {arg1} -> {arg2} pour les lignes {l1}-{l2}."
|
||||
|
||||
#: utils/eveditor.py:653
|
||||
#, python-brace-format
|
||||
msgid "Search-replaced {arg1} -> {arg2} for {line}."
|
||||
msgstr ""
|
||||
msgstr "Recherche-remplacer {arg1} -> {arg2} pour la ligne {line}."
|
||||
|
||||
#: utils/eveditor.py:677
|
||||
#, python-brace-format
|
||||
msgid "Flood filled lines {l1}-{l2}."
|
||||
msgstr ""
|
||||
msgstr "Lignes remplies (inondées ?) {l1}-{l2}."
|
||||
|
||||
#: utils/eveditor.py:679
|
||||
#, python-brace-format
|
||||
msgid "Flood filled {line}."
|
||||
msgstr ""
|
||||
msgstr "\"flood\" rempli {line}."
|
||||
|
||||
#: utils/eveditor.py:701
|
||||
msgid "Valid justifications are"
|
||||
msgstr ""
|
||||
msgstr "Les justification validées sont"
|
||||
|
||||
#: utils/eveditor.py:710
|
||||
#, python-brace-format
|
||||
msgid "{align}-justified lines {l1}-{l2}."
|
||||
msgstr ""
|
||||
msgstr "{align}-lignes justifiées{l1}-{l2}."
|
||||
|
||||
#: utils/eveditor.py:716
|
||||
#, python-brace-format
|
||||
msgid "{align}-justified {line}."
|
||||
msgstr ""
|
||||
msgstr "{align}-justified {line}."
|
||||
|
||||
#: utils/eveditor.py:728
|
||||
#, python-brace-format
|
||||
|
|
@ -976,11 +994,11 @@ msgstr "Auto-indentation désactivée."
|
|||
#: utils/eveditor.py:1093
|
||||
#, python-brace-format
|
||||
msgid "Line Editor [{name}]"
|
||||
msgstr ""
|
||||
msgstr "Édition ligne [{name}]"
|
||||
|
||||
#: utils/eveditor.py:1101
|
||||
msgid "(:h for help)"
|
||||
msgstr ""
|
||||
msgstr "(:h pour l'aide)"
|
||||
|
||||
#: utils/evmenu.py:302
|
||||
#, python-brace-format
|
||||
|
|
@ -1026,15 +1044,15 @@ msgstr "|rChoix invalide.|n"
|
|||
|
||||
#: utils/evmenu.py:1439
|
||||
msgid "|Wcurrent|n"
|
||||
msgstr ""
|
||||
msgstr "|WActuel|n"
|
||||
|
||||
#: utils/evmenu.py:1447
|
||||
msgid "|wp|Wrevious page|n"
|
||||
msgstr ""
|
||||
msgstr "|wp|Wage précédente|n"
|
||||
|
||||
#: utils/evmenu.py:1454
|
||||
msgid "|wn|Wext page|n"
|
||||
msgstr ""
|
||||
msgstr "|wp|Wpage suivante|n"
|
||||
|
||||
#: utils/evmenu.py:1689
|
||||
msgid "Aborted."
|
||||
|
|
|
|||
|
|
@ -538,8 +538,16 @@ def _get_twistd_cmdline(pprofiler, sprofiler):
|
|||
Compile the command line for starting a Twisted application using the 'twistd' executable.
|
||||
|
||||
"""
|
||||
portal_cmd = [TWISTED_BINARY, "--python={}".format(PORTAL_PY_FILE)]
|
||||
server_cmd = [TWISTED_BINARY, "--python={}".format(SERVER_PY_FILE)]
|
||||
portal_cmd = [
|
||||
TWISTED_BINARY,
|
||||
f"--python={PORTAL_PY_FILE}",
|
||||
"--logger=evennia.utils.logger.GetPortalLogObserver",
|
||||
]
|
||||
server_cmd = [
|
||||
TWISTED_BINARY,
|
||||
f"--python={SERVER_PY_FILE}",
|
||||
"--logger=evennia.utils.logger.GetServerLogObserver",
|
||||
]
|
||||
|
||||
if os.name != "nt":
|
||||
# PID files only for UNIX
|
||||
|
|
@ -1363,8 +1371,8 @@ def set_gamedir(path):
|
|||
global GAMEDIR
|
||||
|
||||
Ndepth = 10
|
||||
settings_path = os.path.join("server", "conf", "settings.py")
|
||||
os.chdir(GAMEDIR)
|
||||
settings_path = SETTINGS_DOTPATH.replace(".", os.sep) + ".py"
|
||||
os.chdir(path)
|
||||
for i in range(Ndepth):
|
||||
gpath = os.getcwd()
|
||||
if "server" in os.listdir(gpath):
|
||||
|
|
|
|||
|
|
@ -84,7 +84,7 @@ def should_retry(status_code):
|
|||
|
||||
class DiscordWebsocketServerFactory(WebSocketClientFactory, protocol.ReconnectingClientFactory):
|
||||
"""
|
||||
A variant of the websocket-factory that auto-reconnects.
|
||||
A customized websocket client factory that navigates the Discord gateway process.
|
||||
|
||||
"""
|
||||
|
||||
|
|
@ -94,7 +94,7 @@ class DiscordWebsocketServerFactory(WebSocketClientFactory, protocol.Reconnectin
|
|||
noisy = False
|
||||
gateway = None
|
||||
resume_url = None
|
||||
do_retry = True
|
||||
is_connecting = False
|
||||
|
||||
def __init__(self, sessionhandler, *args, **kwargs):
|
||||
self.uid = kwargs.get("uid")
|
||||
|
|
@ -122,8 +122,8 @@ class DiscordWebsocketServerFactory(WebSocketClientFactory, protocol.Reconnectin
|
|||
d = readBody(response)
|
||||
d.addCallback(self.websocket_init, *args, **kwargs)
|
||||
return d
|
||||
elif should_retry(response.code):
|
||||
delay(300, self.get_gateway_url, *args, **kwargs)
|
||||
else:
|
||||
logger.log_warn("Discord gateway request failed.")
|
||||
|
||||
d.addCallback(cbResponse)
|
||||
|
||||
|
|
@ -132,6 +132,7 @@ class DiscordWebsocketServerFactory(WebSocketClientFactory, protocol.Reconnectin
|
|||
callback for when the URL is gotten
|
||||
"""
|
||||
data = json.loads(str(payload, "utf-8"))
|
||||
self.is_connecting = False
|
||||
if url := data.get("url"):
|
||||
self.gateway = f"{url}/?v={DISCORD_API_VERSION}&encoding=json".encode("utf-8")
|
||||
useragent = kwargs.pop("useragent", DISCORD_USER_AGENT)
|
||||
|
|
@ -179,30 +180,7 @@ class DiscordWebsocketServerFactory(WebSocketClientFactory, protocol.Reconnectin
|
|||
connector (Connector): Represents the connection.
|
||||
|
||||
"""
|
||||
logger.log_info("Attempting connection to Discord...")
|
||||
|
||||
def clientConnectionFailed(self, connector, reason):
|
||||
"""
|
||||
Called when Client failed to connect.
|
||||
|
||||
Args:
|
||||
connector (Connection): Represents the connection.
|
||||
reason (str): The reason for the failure.
|
||||
|
||||
"""
|
||||
protocol.ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
|
||||
|
||||
def clientConnectionLost(self, connector, reason):
|
||||
"""
|
||||
Called when Client loses connection.
|
||||
|
||||
Args:
|
||||
connector (Connection): Represents the connection.
|
||||
reason (str): The reason for the failure.
|
||||
|
||||
"""
|
||||
if self.do_retry or not self.bot:
|
||||
self.retry(connector)
|
||||
logger.log_info("Connecting to Discord...")
|
||||
|
||||
def reconnect(self):
|
||||
"""
|
||||
|
|
@ -210,33 +188,30 @@ class DiscordWebsocketServerFactory(WebSocketClientFactory, protocol.Reconnectin
|
|||
de-registering the session and then reattaching a new one.
|
||||
|
||||
"""
|
||||
# set the retry flag to False so it doesn't attempt an automatic retry
|
||||
# and duplicate the connection
|
||||
self.do_retry = False
|
||||
# disconnect everything
|
||||
self.bot.transport.loseConnection()
|
||||
self.sessionhandler.server_disconnect(self.bot)
|
||||
# set up the reconnection
|
||||
if self.resume_url:
|
||||
self.url = self.resume_url
|
||||
elif self.gateway:
|
||||
self.url = self.gateway
|
||||
else:
|
||||
# we don't know where to reconnect to! start from the beginning
|
||||
self.get_gateway_url()
|
||||
return
|
||||
self.start()
|
||||
# we don't know where to reconnect to! we'll start from the beginning
|
||||
self.url = None
|
||||
# reset the internal delay, since this is a deliberate disconnect
|
||||
self.delay = self.initialDelay
|
||||
# disconnect to allow the reconnection process to kick in
|
||||
self.bot.sendClose()
|
||||
self.sessionhandler.server_disconnect(self.bot)
|
||||
|
||||
def start(self):
|
||||
"Connect protocol to remote server"
|
||||
|
||||
if not self.gateway:
|
||||
# we can't actually start yet
|
||||
# we don't know where to connect to
|
||||
# get the gateway URL from Discord
|
||||
self.is_connecting = True
|
||||
self.get_gateway_url()
|
||||
else:
|
||||
# set the retry flag so we maintain this connection
|
||||
self.do_retry = True
|
||||
elif not self.is_connecting:
|
||||
# everything is good, connect
|
||||
connectWS(self)
|
||||
|
||||
|
||||
|
|
@ -255,7 +230,6 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS):
|
|||
def __init__(self):
|
||||
WebSocketClientProtocol.__init__(self)
|
||||
_BASE_SESSION_CLASS.__init__(self)
|
||||
self.restart_downtime = None
|
||||
|
||||
def at_login(self):
|
||||
pass
|
||||
|
|
@ -265,8 +239,7 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS):
|
|||
Called when connection is established.
|
||||
|
||||
"""
|
||||
self.restart_downtime = None
|
||||
self.restart_task = None
|
||||
logger.log_msg("Discord connection established.")
|
||||
self.factory.bot = self
|
||||
|
||||
self.init_session("discord", "discord.gg", self.factory.sessionhandler)
|
||||
|
|
@ -352,11 +325,11 @@ class DiscordClient(WebSocketClientProtocol, _BASE_SESSION_CLASS):
|
|||
"""
|
||||
if self.nextHeartbeatCall:
|
||||
self.nextHeartbeatCall.cancel()
|
||||
self.disconnect(reason)
|
||||
if code >= 4000:
|
||||
logger.log_err(f"Discord connection closed: {reason}")
|
||||
self.nextHeartbeatCall = None
|
||||
if wasClean:
|
||||
logger.log_info(f"Discord connection closed ({code}) reason: {reason}")
|
||||
else:
|
||||
logger.log_info(f"Discord disconnected: {reason}")
|
||||
logger.log_info(f"Discord connection lost.")
|
||||
|
||||
def _send_json(self, data):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -68,27 +68,27 @@ class TestLauncher(TwistedTestCase):
|
|||
@patch("evennia.server.evennia_launcher.os.name", new="posix")
|
||||
def test_get_twisted_cmdline(self):
|
||||
pcmd, scmd = evennia_launcher._get_twistd_cmdline(False, False)
|
||||
self.assertTrue("portal.py" in pcmd[1])
|
||||
self.assertTrue("--pidfile" in pcmd[2])
|
||||
self.assertTrue("server.py" in scmd[1])
|
||||
self.assertTrue("--pidfile" in scmd[2])
|
||||
self.assertIn("portal.py", pcmd[1])
|
||||
self.assertIn("--pidfile", pcmd[3])
|
||||
self.assertIn("server.py", scmd[1])
|
||||
self.assertIn("--pidfile", scmd[3])
|
||||
|
||||
pcmd, scmd = evennia_launcher._get_twistd_cmdline(True, True)
|
||||
self.assertTrue("portal.py" in pcmd[1])
|
||||
self.assertTrue("--pidfile" in pcmd[2])
|
||||
self.assertTrue("--profiler=cprofile" in pcmd[4], "actual: {}".format(pcmd))
|
||||
self.assertTrue("--profile=" in pcmd[5])
|
||||
self.assertTrue("server.py" in scmd[1])
|
||||
self.assertTrue("--pidfile" in scmd[2])
|
||||
self.assertTrue("--pidfile" in scmd[2])
|
||||
self.assertTrue("--profiler=cprofile" in scmd[4], "actual: {}".format(scmd))
|
||||
self.assertTrue("--profile=" in scmd[5])
|
||||
self.assertIn("portal.py", pcmd[1])
|
||||
self.assertIn("--pidfile", pcmd[3])
|
||||
self.assertIn("--profiler=cprofile", pcmd[5], pcmd)
|
||||
self.assertIn("--profile=", pcmd[6])
|
||||
self.assertIn("server.py", scmd[1])
|
||||
self.assertIn("--pidfile", scmd[3])
|
||||
self.assertIn("--pidfile", scmd[3])
|
||||
self.assertIn("--profiler=cprofile", scmd[5], "actual: {}".format(scmd))
|
||||
self.assertIn("--profile=", scmd[6])
|
||||
|
||||
@patch("evennia.server.evennia_launcher.os.name", new="nt")
|
||||
def test_get_twisted_cmdline_nt(self):
|
||||
pcmd, scmd = evennia_launcher._get_twistd_cmdline(False, False)
|
||||
self.assertTrue(len(pcmd) == 2, "actual: {}".format(pcmd))
|
||||
self.assertTrue(len(scmd) == 2, "actual: {}".format(scmd))
|
||||
self.assertTrue(len(pcmd) == 3, pcmd)
|
||||
self.assertTrue(len(scmd) == 3, scmd)
|
||||
|
||||
@patch("evennia.server.evennia_launcher.reactor.stop")
|
||||
def test_reactor_stop(self, mockstop):
|
||||
|
|
|
|||
|
|
@ -1737,7 +1737,7 @@ class NickHandler(AttributeHandler):
|
|||
regex = re.compile(nick_regex, re.I + re.DOTALL + re.U)
|
||||
self._regex_cache[nick_regex] = regex
|
||||
|
||||
is_match, raw_string = parse_nick_template(raw_string.strip(), regex, template)
|
||||
is_match, raw_string = parse_nick_template(raw_string, regex, template)
|
||||
if is_match:
|
||||
break
|
||||
return raw_string
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ except ImportError:
|
|||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.utils.safestring import SafeString
|
||||
|
||||
from evennia.utils import logger
|
||||
from evennia.utils.utils import is_iter, to_bytes, uses_database
|
||||
|
||||
|
|
|
|||
|
|
@ -273,22 +273,12 @@ from django.conf import settings
|
|||
|
||||
# i18n
|
||||
from django.utils.translation import gettext as _
|
||||
|
||||
from evennia import CmdSet, Command
|
||||
from evennia.commands import cmdhandler
|
||||
from evennia.utils import logger
|
||||
from evennia.utils.ansi import strip_ansi
|
||||
from evennia.utils.evtable import EvColumn, EvTable
|
||||
from evennia.utils.utils import (
|
||||
crop,
|
||||
dedent,
|
||||
is_iter,
|
||||
m_len,
|
||||
make_iter,
|
||||
mod_import,
|
||||
pad,
|
||||
to_str,
|
||||
)
|
||||
from evennia.utils.utils import crop, dedent, is_iter, m_len, make_iter, mod_import, pad, to_str
|
||||
|
||||
# read from protocol NAWS later?
|
||||
_MAX_TEXT_WIDTH = settings.CLIENT_DEFAULT_WIDTH
|
||||
|
|
|
|||
|
|
@ -288,8 +288,8 @@ def justify(text, width=None, align="l", indent=0, fillchar=" "):
|
|||
# absolute mode - just crop or fill to width
|
||||
abs_lines = []
|
||||
for line in text.split("\n"):
|
||||
nlen = len(line)
|
||||
if len(line) < width:
|
||||
nlen = m_len(line)
|
||||
if m_len(line) < width:
|
||||
line += sp * (width - nlen)
|
||||
else:
|
||||
line = crop(line, width=width, suffix="")
|
||||
|
|
@ -304,7 +304,7 @@ def justify(text, width=None, align="l", indent=0, fillchar=" "):
|
|||
for ip, paragraph in enumerate(paragraphs):
|
||||
if ip > 0:
|
||||
words.append(("\n", 0))
|
||||
words.extend((word, len(word)) for word in paragraph.split())
|
||||
words.extend((word, m_len(word)) for word in paragraph.split())
|
||||
|
||||
if not words:
|
||||
# Just whitespace!
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue