commit
b99c8aa704
8 changed files with 62 additions and 70 deletions
|
|
@ -48,6 +48,8 @@ without arguments starts a full interactive Python console.
|
||||||
`.get_command_info()` method for easier overloading and access. (Volund)
|
`.get_command_info()` method for easier overloading and access. (Volund)
|
||||||
- Removed unused `CYCLE_LOGFILES` setting. Added `SERVER_LOG_DAY_ROTATION`
|
- Removed unused `CYCLE_LOGFILES` setting. Added `SERVER_LOG_DAY_ROTATION`
|
||||||
and `SERVER_LOG_MAX_SIZE` (and equivalent for PORTAL) to control log rotation.
|
and `SERVER_LOG_MAX_SIZE` (and equivalent for PORTAL) to control log rotation.
|
||||||
|
- Addded `inside_rec` lockfunc - if room is locked, the normal `inside()` lockfunc will
|
||||||
|
fail e.g. for your inventory objs (since their loc is you), whereas this will pass.
|
||||||
|
|
||||||
|
|
||||||
## Evennia 0.9 (2018-2019)
|
## Evennia 0.9 (2018-2019)
|
||||||
|
|
|
||||||
|
|
@ -2832,8 +2832,8 @@ class CmdTeleport(COMMAND_DEFAULT_CLASS):
|
||||||
reference. A puppeted object cannot be moved to None.
|
reference. A puppeted object cannot be moved to None.
|
||||||
loc - teleport object to the target's location instead of its contents
|
loc - teleport object to the target's location instead of its contents
|
||||||
|
|
||||||
Teleports an object somewhere. If no object is given, you yourself
|
Teleports an object somewhere. If no object is given, you yourself are
|
||||||
is teleported to the target location.
|
teleported to the target location.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
key = "tel"
|
key = "tel"
|
||||||
|
|
|
||||||
|
|
@ -547,11 +547,39 @@ def inside(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
Usage:
|
Usage:
|
||||||
inside()
|
inside()
|
||||||
|
|
||||||
Only true if accessing_obj is "inside" accessed_obj
|
True if accessing_obj is 'inside' accessing_obj. Note that this only checks
|
||||||
|
one level down. So if if the lock is on a room, you will pass but not your
|
||||||
|
inventory (since their location is you, not the locked object). If you
|
||||||
|
want also nested objects to pass the lock, use the `insiderecursive`
|
||||||
|
lockfunc.
|
||||||
"""
|
"""
|
||||||
return accessing_obj.location == accessed_obj
|
return accessing_obj.location == accessed_obj
|
||||||
|
|
||||||
|
|
||||||
|
def inside_rec(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
|
"""
|
||||||
|
Usage:
|
||||||
|
inside_rec()
|
||||||
|
|
||||||
|
True if accessing_obj is inside the accessed obj, at up to 10 levels
|
||||||
|
of recursion (so if this lock is on a room, then an object inside a box
|
||||||
|
in your inventory will also pass the lock).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def _recursive_inside(obj, accessed_obj, lvl=1):
|
||||||
|
if obj.location:
|
||||||
|
if obj.location == accessed_obj:
|
||||||
|
return True
|
||||||
|
elif lvl >= 10:
|
||||||
|
# avoid infinite recursions
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return _recursive_inside(obj.location, accessed_obj, lvl + 1)
|
||||||
|
return False
|
||||||
|
|
||||||
|
return _recursive_inside(accessing_obj, accessed_obj)
|
||||||
|
|
||||||
|
|
||||||
def holds(accessing_obj, accessed_obj, *args, **kwargs):
|
def holds(accessing_obj, accessed_obj, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Usage:
|
Usage:
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ except ImportError:
|
||||||
|
|
||||||
from evennia import settings_default
|
from evennia import settings_default
|
||||||
from evennia.locks import lockfuncs
|
from evennia.locks import lockfuncs
|
||||||
|
from evennia.utils.create import create_object
|
||||||
|
|
||||||
# ------------------------------------------------------------
|
# ------------------------------------------------------------
|
||||||
# Lock testing
|
# Lock testing
|
||||||
|
|
@ -179,6 +180,13 @@ class TestLockfuncs(EvenniaTest):
|
||||||
self.assertEqual(False, lockfuncs.inside(self.char1, self.room2))
|
self.assertEqual(False, lockfuncs.inside(self.char1, self.room2))
|
||||||
self.assertEqual(True, lockfuncs.holds(self.room1, self.char1))
|
self.assertEqual(True, lockfuncs.holds(self.room1, self.char1))
|
||||||
self.assertEqual(False, lockfuncs.holds(self.room2, self.char1))
|
self.assertEqual(False, lockfuncs.holds(self.room2, self.char1))
|
||||||
|
# test recursively
|
||||||
|
self.assertEqual(True, lockfuncs.inside_rec(self.char1, self.room1))
|
||||||
|
self.assertEqual(False, lockfuncs.inside_rec(self.char1, self.room2))
|
||||||
|
inventory_item = create_object(key="InsideTester", location=self.char1)
|
||||||
|
self.assertEqual(True, lockfuncs.inside_rec(inventory_item, self.room1))
|
||||||
|
self.assertEqual(False, lockfuncs.inside_rec(inventory_item, self.room2))
|
||||||
|
inventory_item.delete()
|
||||||
|
|
||||||
def test_has_account(self):
|
def test_has_account(self):
|
||||||
self.assertEqual(True, lockfuncs.has_account(self.char1, None))
|
self.assertEqual(True, lockfuncs.has_account(self.char1, None))
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ SRESET = chr(19) # shutdown server in reset mode
|
||||||
PYTHON_MIN = "3.7"
|
PYTHON_MIN = "3.7"
|
||||||
TWISTED_MIN = "18.0.0"
|
TWISTED_MIN = "18.0.0"
|
||||||
DJANGO_MIN = "2.1"
|
DJANGO_MIN = "2.1"
|
||||||
DJANGO_REC = "2.2.9"
|
DJANGO_REC = "2.2"
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sys.path[1] = EVENNIA_ROOT
|
sys.path[1] = EVENNIA_ROOT
|
||||||
|
|
@ -1281,7 +1281,7 @@ def check_main_evennia_dependencies():
|
||||||
try:
|
try:
|
||||||
dversion = ".".join(str(num) for num in django.VERSION if isinstance(num, int))
|
dversion = ".".join(str(num) for num in django.VERSION if isinstance(num, int))
|
||||||
# only the main version (1.5, not 1.5.4.0)
|
# only the main version (1.5, not 1.5.4.0)
|
||||||
dversion_main = ".".join(dversion.split(".")[:3])
|
dversion_main = ".".join(dversion.split(".")[:2])
|
||||||
if LooseVersion(dversion) < LooseVersion(DJANGO_MIN):
|
if LooseVersion(dversion) < LooseVersion(DJANGO_MIN):
|
||||||
print(ERROR_DJANGO_MIN.format(dversion=dversion_main, django_min=DJANGO_MIN))
|
print(ERROR_DJANGO_MIN.format(dversion=dversion_main, django_min=DJANGO_MIN))
|
||||||
error = True
|
error = True
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# Evennia Game Index Client
|
# Evennia Game Index Client
|
||||||
|
|
||||||
Greg Taylor 2016
|
Greg Taylor 2016, Griatch 2020
|
||||||
|
|
||||||
This contrib features a client for the [Evennia Game Index]
|
This is a client for the [Evennia Game Index]
|
||||||
(http://evennia-game-index.appspot.com/), a listing of games built on
|
(http://evennia-game-index.appspot.com/), a listing of games built on
|
||||||
Evennia. By listing your game on the index, you make it easy for other
|
Evennia. By listing your game on the index, you make it easy for other
|
||||||
people in the community to discover your creation.
|
people in the community to discover your creation.
|
||||||
|
|
@ -14,74 +14,24 @@ on remedying this.*
|
||||||
|
|
||||||
## Listing your Game
|
## Listing your Game
|
||||||
|
|
||||||
To list your game, you'll need to enable the Evennia Game Index client.
|
To list your game, go to your game dir and run
|
||||||
Start by `cd`'ing to your game directory. From there, open up
|
|
||||||
`server/conf/server_services_plugins.py`. It might look something like this
|
|
||||||
if you don't have any other optional add-ons enabled:
|
|
||||||
|
|
||||||
```python
|
evennia connections
|
||||||
"""
|
|
||||||
Server plugin services
|
|
||||||
|
|
||||||
This plugin module can define user-created services for the Server to
|
Follow the prompts to add details to the listing. Use `evennia reload`. In your log (visible with `evennia --log`
|
||||||
start.
|
you should see a note that info has been sent to the game index.
|
||||||
|
|
||||||
This module must handle all imports and setups required to start a
|
## Detailed settings
|
||||||
twisted service (see examples in evennia.server.server). It must also
|
|
||||||
contain a function start_plugin_services(application). Evennia will
|
|
||||||
call this function with the main Server application (so your services
|
|
||||||
can be added to it). The function should not return anything. Plugin
|
|
||||||
services are started last in the Server startup process.
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
If you don't want to use the wizard you can configure your game listing by opening up `server/conf/settings.py` and
|
||||||
def start_plugin_services(server):
|
|
||||||
"""
|
|
||||||
This hook is called by Evennia, last in the Server startup process.
|
|
||||||
|
|
||||||
server - a reference to the main server application.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
```
|
|
||||||
|
|
||||||
To enable the client, import `EvenniaGameIndexService` and fire it up after the
|
|
||||||
Evennia server has finished starting:
|
|
||||||
|
|
||||||
```python
|
|
||||||
"""
|
|
||||||
Server plugin services
|
|
||||||
|
|
||||||
This plugin module can define user-created services for the Server to
|
|
||||||
start.
|
|
||||||
|
|
||||||
This module must handle all imports and setups required to start a
|
|
||||||
twisted service (see examples in evennia.server.server). It must also
|
|
||||||
contain a function start_plugin_services(application). Evennia will
|
|
||||||
call this function with the main Server application (so your services
|
|
||||||
can be added to it). The function should not return anything. Plugin
|
|
||||||
services are started last in the Server startup process.
|
|
||||||
"""
|
|
||||||
|
|
||||||
from evennia.contrib.egi_client import EvenniaGameIndexService
|
|
||||||
|
|
||||||
def start_plugin_services(server):
|
|
||||||
"""
|
|
||||||
This hook is called by Evennia, last in the Server startup process.
|
|
||||||
|
|
||||||
server - a reference to the main server application.
|
|
||||||
"""
|
|
||||||
egi_service = EvenniaGameIndexService()
|
|
||||||
server.services.addService(egi_service)
|
|
||||||
```
|
|
||||||
|
|
||||||
Next, configure your game listing by opening up `server/conf/settings.py` and
|
|
||||||
using the following as a starting point:
|
using the following as a starting point:
|
||||||
|
|
||||||
```python
|
```python
|
||||||
######################################################################
|
######################################################################
|
||||||
# Contrib config
|
# Game index
|
||||||
######################################################################
|
######################################################################
|
||||||
|
|
||||||
|
GAME_INDEX_ENABLED = True
|
||||||
GAME_INDEX_LISTING = {
|
GAME_INDEX_LISTING = {
|
||||||
'game_status': 'pre-alpha',
|
'game_status': 'pre-alpha',
|
||||||
# Optional, comment out or remove if N/A
|
# Optional, comment out or remove if N/A
|
||||||
|
|
|
||||||
|
|
@ -314,7 +314,9 @@ class AMPMultiConnectionProtocol(amp.AMP):
|
||||||
try:
|
try:
|
||||||
super(AMPMultiConnectionProtocol, self).dataReceived(data)
|
super(AMPMultiConnectionProtocol, self).dataReceived(data)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
_get_logger().log_trace("Discarded incoming partial (packed) data (len {})".format(len(data)))
|
_get_logger().log_trace(
|
||||||
|
"Discarded incoming partial (packed) data (len {})".format(len(data))
|
||||||
|
)
|
||||||
elif self.multibatches:
|
elif self.multibatches:
|
||||||
# invalid AMP, but we have a pending multi-batch that is not yet complete
|
# invalid AMP, but we have a pending multi-batch that is not yet complete
|
||||||
if data[-2:] == NULNUL:
|
if data[-2:] == NULNUL:
|
||||||
|
|
@ -323,7 +325,9 @@ class AMPMultiConnectionProtocol(amp.AMP):
|
||||||
try:
|
try:
|
||||||
super(AMPMultiConnectionProtocol, self).dataReceived(data)
|
super(AMPMultiConnectionProtocol, self).dataReceived(data)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
_get_logger().log_trace("Discarded incoming multi-batch (packed) data (len {})".format(len(data)))
|
_get_logger().log_trace(
|
||||||
|
"Discarded incoming multi-batch (packed) data (len {})".format(len(data))
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
# not an AMP communication, return warning
|
# not an AMP communication, return warning
|
||||||
self.transport.write(_HTTP_WARNING)
|
self.transport.write(_HTTP_WARNING)
|
||||||
|
|
|
||||||
|
|
@ -577,7 +577,7 @@ def to_pickle(data):
|
||||||
except TypeError:
|
except TypeError:
|
||||||
return item
|
return item
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_error(f"The object {item} of type {type(item)} could not be stored.")
|
logger.log_err(f"The object {item} of type {type(item)} could not be stored.")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
return process_item(data)
|
return process_item(data)
|
||||||
|
|
@ -716,7 +716,7 @@ def do_pickle(data):
|
||||||
try:
|
try:
|
||||||
return dumps(data, protocol=PICKLE_PROTOCOL)
|
return dumps(data, protocol=PICKLE_PROTOCOL)
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_error(f"Could not pickle data for storage: {data}")
|
logger.log_err(f"Could not pickle data for storage: {data}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -725,7 +725,7 @@ def do_unpickle(data):
|
||||||
try:
|
try:
|
||||||
return loads(to_bytes(data))
|
return loads(to_bytes(data))
|
||||||
except Exception:
|
except Exception:
|
||||||
logger.log_error(f"Could not unpickle data from storage: {data}")
|
logger.log_err(f"Could not unpickle data from storage: {data}")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue