Merge.
This commit is contained in:
commit
70b8f074f1
20 changed files with 905 additions and 253 deletions
116
src/players/migrations/0014_adding_objs_m2m.py
Normal file
116
src/players/migrations/0014_adding_objs_m2m.py
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding M2M table for field db_objs on 'PlayerDB'
|
||||
db.create_table('players_playerdb_db_objs', (
|
||||
('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
|
||||
('playerdb', models.ForeignKey(orm['players.playerdb'], null=False)),
|
||||
('objectdb', models.ForeignKey(orm['objects.objectdb'], null=False))
|
||||
))
|
||||
db.create_unique('players_playerdb_db_objs', ['playerdb_id', 'objectdb_id'])
|
||||
|
||||
if not db.dry_run:
|
||||
for player in orm.PlayerDB.objects.all():
|
||||
# move data from old field to new
|
||||
if player.db_obj:
|
||||
player.db_objs.add(player.db_obj)
|
||||
player.save()
|
||||
|
||||
def backwards(self, orm):
|
||||
# Removing M2M table for field db_objs on 'PlayerDB'
|
||||
db.delete_table('players_playerdb_db_objs')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'objects.objectdb': {
|
||||
'Meta': {'object_name': 'ObjectDB'},
|
||||
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'db_destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destinations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}),
|
||||
'db_sessid': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'players.playerattribute': {
|
||||
'Meta': {'object_name': 'PlayerAttribute'},
|
||||
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']"}),
|
||||
'db_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'players.playerdb': {
|
||||
'Meta': {'object_name': 'PlayerDB'},
|
||||
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'obj_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_objs': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'objs_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||
},
|
||||
'players.playernick': {
|
||||
'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'},
|
||||
'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']"}),
|
||||
'db_real': ('django.db.models.fields.TextField', [], {}),
|
||||
'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['players']
|
||||
106
src/players/migrations/0015_removing_obj.py
Normal file
106
src/players/migrations/0015_removing_obj.py
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Deleting field 'PlayerDB.db_obj'
|
||||
db.delete_column('players_playerdb', 'db_obj_id')
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Adding field 'PlayerDB.db_obj'
|
||||
db.add_column('players_playerdb', 'db_obj',
|
||||
self.gf('django.db.models.fields.related.ForeignKey')(related_name='obj_set', null=True, to=orm['objects.ObjectDB'], blank=True),
|
||||
keep_default=False)
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'objects.objectdb': {
|
||||
'Meta': {'object_name': 'ObjectDB'},
|
||||
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
|
||||
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'db_destination': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'destinations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_home': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'homes_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'db_location': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locations_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'db_player': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']", 'null': 'True', 'blank': 'True'}),
|
||||
'db_sessid': ('django.db.models.fields.IntegerField', [], {'null': 'True'}),
|
||||
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'players.playerattribute': {
|
||||
'Meta': {'object_name': 'PlayerAttribute'},
|
||||
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']"}),
|
||||
'db_value': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
},
|
||||
'players.playerdb': {
|
||||
'Meta': {'object_name': 'PlayerDB'},
|
||||
'db_cmdset_storage': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'db_date_created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'db_is_connected': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'db_key': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'db_lock_storage': ('django.db.models.fields.CharField', [], {'max_length': '512', 'blank': 'True'}),
|
||||
'db_objs': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'related_name': "'objs_set'", 'null': 'True', 'to': "orm['objects.ObjectDB']"}),
|
||||
'db_permissions': ('django.db.models.fields.CharField', [], {'max_length': '255', 'blank': 'True'}),
|
||||
'db_typeclass_path': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'unique': 'True'})
|
||||
},
|
||||
'players.playernick': {
|
||||
'Meta': {'unique_together': "(('db_nick', 'db_type', 'db_obj'),)", 'object_name': 'PlayerNick'},
|
||||
'db_nick': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'db_obj': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['players.PlayerDB']"}),
|
||||
'db_real': ('django.db.models.fields.TextField', [], {}),
|
||||
'db_type': ('django.db.models.fields.CharField', [], {'default': "'inputline'", 'max_length': '16', 'null': 'True', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['players']
|
||||
|
|
@ -161,8 +161,9 @@ class PlayerDB(TypedObject):
|
|||
help_text="The <I>User</I> object holds django-specific authentication for each Player. A unique User should be created and tied to each Player, the two should never be switched or changed around. The User will be deleted automatically when the Player is.")
|
||||
# the in-game object connected to this player (if any).
|
||||
# Use the property 'obj' to access.
|
||||
db_obj = models.ForeignKey("objects.ObjectDB", null=True, blank=True,
|
||||
verbose_name="character", help_text='In-game object.')
|
||||
db_objs = models.ManyToManyField("objects.ObjectDB", null=True,
|
||||
verbose_name="characters", related_name="objs_set",
|
||||
help_text="In-game objects.")
|
||||
# store a connected flag here too, not just in sessionhandler.
|
||||
# This makes it easier to track from various out-of-process locations
|
||||
db_is_connected = models.BooleanField(default=False, verbose_name="is_connected", help_text="If player is connected to game or not")
|
||||
|
|
@ -195,11 +196,12 @@ class PlayerDB(TypedObject):
|
|||
|
||||
# obj property (wraps db_obj)
|
||||
#@property
|
||||
def obj_get(self):
|
||||
def objs_get(self):
|
||||
"Getter. Allows for value = self.obj"
|
||||
return get_field_cache(self, "obj")
|
||||
return self.db_objs.all()
|
||||
#return get_field_cache(self, "objs").all()
|
||||
#@obj.setter
|
||||
def obj_set(self, value):
|
||||
def objs_set(self, value):
|
||||
"Setter. Allows for self.obj = value"
|
||||
global _TYPECLASS
|
||||
if not _TYPECLASS:
|
||||
|
|
@ -208,15 +210,19 @@ class PlayerDB(TypedObject):
|
|||
if isinstance(value, _TYPECLASS):
|
||||
value = value.dbobj
|
||||
try:
|
||||
set_field_cache(self, "obj", value)
|
||||
self.db_objs.add(value)
|
||||
self.save()
|
||||
#set_field_cache(self, "obj", value)
|
||||
except Exception:
|
||||
logger.log_trace()
|
||||
raise Exception("Cannot assign %s as a player object!" % value)
|
||||
#@obj.deleter
|
||||
def obj_del(self):
|
||||
def objs_del(self):
|
||||
"Deleter. Allows for del self.obj"
|
||||
del_field_cache(self, "obj")
|
||||
obj = property(obj_get, obj_set, obj_del)
|
||||
self.db_objs.clear()
|
||||
self.save()
|
||||
#del_field_cache(self, "obj")
|
||||
objs = property(objs_get, objs_set, objs_del)
|
||||
|
||||
# whereas the name 'obj' is consistent with the rest of the code,
|
||||
# 'character' is a more intuitive property name, so we
|
||||
|
|
@ -236,6 +242,7 @@ class PlayerDB(TypedObject):
|
|||
"Deleter. Allows for del self.character"
|
||||
del_field_cache(self, "obj")
|
||||
character = property(character_get, character_set, character_del)
|
||||
|
||||
# cmdset_storage property
|
||||
# This seems very sensitive to caching, so leaving it be for now /Griatch
|
||||
#@property
|
||||
|
|
@ -358,32 +365,220 @@ class PlayerDB(TypedObject):
|
|||
# PlayerDB class access methods
|
||||
#
|
||||
|
||||
def msg(self, outgoing_string, from_obj=None, data=None):
|
||||
def msg(self, outgoing_string, from_obj=None, data=None, sessid=None):
|
||||
"""
|
||||
Evennia -> User
|
||||
This is the main route for sending data back to the user from the server.
|
||||
|
||||
outgoing_string (string) - text data to send
|
||||
from_obj (Object/Player) - source object of message to send
|
||||
data (dict) - arbitrary data object containing eventual protocol-specific options
|
||||
sessid - the session id of the session to send to. If not given, return to
|
||||
all sessions connected to this player. This is usually only
|
||||
relevant when using msg() directly from a player-command (from
|
||||
a command on a Character, the character automatically stores and
|
||||
handles the sessid).
|
||||
"""
|
||||
if from_obj:
|
||||
# call hook
|
||||
try:
|
||||
_GA(from_obj, "at_msg_send")(outgoing_string, to_obj=self, data=data)
|
||||
except Exception:
|
||||
pass
|
||||
if (_GA(self, "character") and not
|
||||
_GA(self, "character").at_msg_receive(outgoing_string, from_obj=from_obj, data=data)):
|
||||
# the at_msg_receive() hook may block receiving of certain messages
|
||||
return
|
||||
|
||||
outgoing_string = utils.to_str(outgoing_string, force_string=True)
|
||||
|
||||
for session in _GA(self, 'sessions'):
|
||||
session = None
|
||||
if sessid:
|
||||
session = _GA(self, "get_session")(sessid)
|
||||
if session:
|
||||
char = _GA(self, "get_character")(sessid=sessid)
|
||||
if char and not char.at_msg_receive(outgoing_string, from_obj=from_obj, data=data):
|
||||
# if hook returns false, cancel send
|
||||
return
|
||||
session.msg(outgoing_string, data)
|
||||
else:
|
||||
# if no session was specified, send to them all
|
||||
for sess in _GA(self, 'get_all_sessions')():
|
||||
sess.msg(outgoing_string, data)
|
||||
|
||||
def inmsg(self, ingoing_string, sessid):
|
||||
"""
|
||||
User -> Evennia
|
||||
This is the reverse of msg - used by sessions to relay
|
||||
messages/data back into the game. It is normally not called
|
||||
from inside game code but only by the serversessions directly.
|
||||
|
||||
ingoing_string - text string (i.e. command string)
|
||||
data - dictionary of optional data
|
||||
session - session sending this data
|
||||
"""
|
||||
character = _GA(self, "get_character")(sessid=sessid)
|
||||
if character:
|
||||
# execute command on character
|
||||
_GA(character, "execute_cmd")(ingoing_string, sessid=sessid)
|
||||
else:
|
||||
# a non-character session; this goes to player directly
|
||||
_GA(self, "execute_cmd")(ingoing_string, sessid=sessid)
|
||||
|
||||
def connect_session_to_character(self, sessid, character, force=False):
|
||||
"""
|
||||
Connect the given session to a character through this player.
|
||||
Note that this assumes the character has previously been
|
||||
linked to the player using self.connect_character().
|
||||
|
||||
force - drop existing connection to other character
|
||||
|
||||
Returns True if connection was successful, False otherwise
|
||||
"""
|
||||
# first check if we already have a character tied to this session
|
||||
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||
if char:
|
||||
if force and char != character:
|
||||
_GA(self, "disconnect_session_from_character")(sessid)
|
||||
else:
|
||||
return
|
||||
# do the connection
|
||||
character.sessid = sessid
|
||||
# update cache
|
||||
cache = get_prop_cache(self, "_characters") or {}
|
||||
cache[sessid] = character
|
||||
set_prop_cache(self, "_characters", cache)
|
||||
# call hooks
|
||||
character.at_init()
|
||||
if character:
|
||||
# start (persistent) scripts on this object
|
||||
#ScriptDB.objects.validate(obj=character)
|
||||
pass
|
||||
if character.db.FIRST_LOGIN:
|
||||
character.at_first_login()
|
||||
del character.db.FIRST_LOGIN
|
||||
character.at_pre_login()
|
||||
character.at_post_login()
|
||||
return True
|
||||
|
||||
def disconnect_session_from_character(self, sessid):
|
||||
"""
|
||||
Disconnect a session from the characterm (still keeping the
|
||||
connection to the Player)
|
||||
returns the newly disconnected character, if it existed
|
||||
"""
|
||||
if not sessid:
|
||||
return
|
||||
char = _GA(self, "get_character")(sessid=sessid, return_dbobj=True)
|
||||
if char:
|
||||
# call hook before disconnecting
|
||||
_GA(char.typeclass, "at_disconnect")()
|
||||
del char.sessid
|
||||
# update cache
|
||||
cache = get_prop_cache(self, "_characters") or {}
|
||||
if sessid in cache:
|
||||
del cache[sessid]
|
||||
set_prop_cache(self, "_characters", cache)
|
||||
return char
|
||||
|
||||
def get_session(self, sessid):
|
||||
"""
|
||||
Return session with given sessid connected to this player.
|
||||
"""
|
||||
return SESSIONS.sessions_from_player(self, sessid=sessid)
|
||||
|
||||
def get_all_sessions(self):
|
||||
"Return all sessions connected to this player"
|
||||
return SESSIONS.sessions_from_player(self)
|
||||
|
||||
def get_character(self, sessid=None, character=None, return_dbobj=False):
|
||||
"""
|
||||
Get the character connected to this player and sessid
|
||||
|
||||
sessid - return character connected to this sessid,
|
||||
character - return character if connected to this player, else None.
|
||||
|
||||
Combining both keywords will check the entire connection - if the
|
||||
given session is currently connected to the given char. If no
|
||||
keywords are given, returns all connected characters.
|
||||
"""
|
||||
cache = get_prop_cache(self, "_characters") or {}
|
||||
if sessid:
|
||||
# try to return a character with a given sessid
|
||||
char = cache.get(sessid)
|
||||
if not char:
|
||||
char = _GA(self, "db_objs").filter(db_player=self, db_sessid=sessid) or None
|
||||
if char:
|
||||
char = char[0]
|
||||
cache[sessid] = char
|
||||
set_prop_cache(self, "_characters", cache)
|
||||
if character:
|
||||
return char and (char == character.dbobj and (return_dbobj and char or char.typeclass)) or None
|
||||
return char and (return_dbobj and char or char.typeclass) or None
|
||||
elif character:
|
||||
char = _GA(self, "db_objs").filter(id=_GA(character.dbobj, "id"))
|
||||
return char and (return_dbobj and char[0] or char[0].typeclass) or None
|
||||
else:
|
||||
# no sessid given - return all available characters
|
||||
return list(return_dbobj and o or o.typeclass for o in self.db_objs.all())
|
||||
|
||||
def get_all_characters(self):
|
||||
"""
|
||||
Readability-wrapper for getting all characters
|
||||
"""
|
||||
return _GA(self, "get_character")(sessid=None, character=None)
|
||||
|
||||
def connect_character(self, character, sessid=None):
|
||||
"""
|
||||
Use the Player to connect a Character to a session. Note that
|
||||
we don't do any access checks at this point. Note that if the
|
||||
game was fully restarted (including the Portal), this must be
|
||||
used, since sessids will have changed as players reconnect.
|
||||
|
||||
if sessid is given, also connect the sessid to the character.
|
||||
"""
|
||||
# first disconnect any other character from this session
|
||||
char = character.dbobj
|
||||
_GA(self, "disconnect_character")(char)
|
||||
char.player = self
|
||||
_GA(self, "db_objs").add(char)
|
||||
_GA(self, "save")()
|
||||
if sessid:
|
||||
return _GA(self, "connect_session_to_character")(sessid=sessid, character=char)
|
||||
return True
|
||||
|
||||
def disconnect_character(self, character):
|
||||
"""
|
||||
Disconnect a character from this player, either based
|
||||
on sessid or by giving the character object directly
|
||||
|
||||
Returns newly disconnected character.
|
||||
"""
|
||||
if not character:
|
||||
return
|
||||
char = _GA(self, "get_character")(character=character, return_dbobj=True)
|
||||
if char:
|
||||
_GA(self, "disconnect_session_from_character")(char.sessid)
|
||||
_GA(self, "db_objs").remove(char)
|
||||
del char.player
|
||||
del char.sessid
|
||||
self.save()
|
||||
# clear cache
|
||||
cache = get_prop_cache(self, "_characters") or {}
|
||||
[cache.pop(sessid) for sessid,stored_char in cache.items() if stored_char==char]
|
||||
set_prop_cache(self, "_characters", cache)
|
||||
return char
|
||||
|
||||
|
||||
def swap_character(self, new_character, delete_old_character=False):
|
||||
def disconnect_all_characters(self):
|
||||
for char in self.db_objs.all():
|
||||
_GA(self, "disconnect_character")(char)
|
||||
|
||||
def swap_character(self, old_character, new_character):
|
||||
"""
|
||||
Swaps character, if possible
|
||||
Swaps character between sessions, if possible
|
||||
"""
|
||||
return _GA(self, "__class__").objects.swap_character(self, new_character, delete_old_character=delete_old_character)
|
||||
this_sessid = old_character.sessid
|
||||
other_sessd = new_character.sessid
|
||||
this_char = _GA(self, "disconnect_session_from_character")(this_sessid)
|
||||
other_char = _GA(self, "disconnect_session_from_character")(other_sessid)
|
||||
_GA(self, "connect_session_to_character")(this_sessid, other_char)
|
||||
_GA(self, "connect_session_to_character")(other_sessid, this_char)
|
||||
|
||||
def delete(self, *args, **kwargs):
|
||||
"Make sure to delete user also when deleting player - the two may never exist separately."
|
||||
|
|
@ -401,7 +596,7 @@ class PlayerDB(TypedObject):
|
|||
# Execution/action methods
|
||||
#
|
||||
|
||||
def execute_cmd(self, raw_string):
|
||||
def execute_cmd(self, raw_string, sessid=None):
|
||||
"""
|
||||
Do something as this player. This command transparently
|
||||
lets its typeclass execute the command.
|
||||
|
|
@ -417,7 +612,7 @@ class PlayerDB(TypedObject):
|
|||
if nick.db_nick in raw_list:
|
||||
raw_string = raw_string.replace(nick.db_nick, nick.db_real, 1)
|
||||
break
|
||||
return cmdhandler.cmdhandler(self.typeclass, raw_string)
|
||||
return cmdhandler.cmdhandler(self.typeclass, raw_string, sessid=sessid)
|
||||
|
||||
def search(self, ostring, return_character=False):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -88,17 +88,21 @@ class Player(TypeClass):
|
|||
|
||||
## methods inherited from database model
|
||||
|
||||
def msg(self, outgoing_string, from_obj=None, data=None):
|
||||
def msg(self, outgoing_string, from_obj=None, data=None, sessid=None):
|
||||
"""
|
||||
Evennia -> User
|
||||
This is the main route for sending data back to the user from the server.
|
||||
|
||||
outgoing_string (string) - text data to send
|
||||
from_obj (Object/Player) - source object of message to send
|
||||
data (?) - arbitrary data object containing eventual protocol-specific options
|
||||
|
||||
"""
|
||||
self.dbobj.msg(outgoing_string, from_obj=from_obj, data=data)
|
||||
data (dict) - arbitrary data object containing eventual protocol-specific options
|
||||
sessid - the session id of the session to send to. If not given, return to
|
||||
all sessions connected to this player. This is usually only
|
||||
relevant when using msg() directly from a player-command (from
|
||||
a command on a Character, the character automatically stores and
|
||||
handles the sessid).
|
||||
"""
|
||||
self.dbobj.msg(outgoing_string, from_obj=from_obj, data=data, sessid=sessid)
|
||||
|
||||
def swap_character(self, new_character, delete_old_character=False):
|
||||
"""
|
||||
|
|
@ -111,7 +115,7 @@ class Player(TypeClass):
|
|||
"""
|
||||
return self.dbobj.swap_character(new_character, delete_old_character=delete_old_character)
|
||||
|
||||
def execute_cmd(self, raw_string):
|
||||
def execute_cmd(self, raw_string, sessid=None):
|
||||
"""
|
||||
Do something as this object. This command transparently
|
||||
lets its typeclass execute the command. Evennia also calls
|
||||
|
|
@ -119,6 +123,7 @@ class Player(TypeClass):
|
|||
|
||||
Argument:
|
||||
raw_string (string) - raw command input
|
||||
sessid (int) - id of session executing the command. This sets the sessid property on the command
|
||||
|
||||
Returns Deferred - this is an asynchronous Twisted object that will
|
||||
not fire until the command has actually finished executing. To overload
|
||||
|
|
@ -129,7 +134,7 @@ class Player(TypeClass):
|
|||
This return is not used at all by Evennia by default, but might be useful
|
||||
for coders intending to implement some sort of nested command structure.
|
||||
"""
|
||||
return self.dbobj.execute_cmd(raw_string)
|
||||
return self.dbobj.execute_cmd(raw_string, sessid=sessid)
|
||||
|
||||
def search(self, ostring, return_character=False):
|
||||
"""
|
||||
|
|
@ -293,8 +298,7 @@ class Player(TypeClass):
|
|||
"""
|
||||
# Character.at_post_login also looks around. Only use
|
||||
# this as a backup when logging in without a character
|
||||
if not self.character:
|
||||
self.execute_cmd("look")
|
||||
self.execute_cmd("look")
|
||||
|
||||
def at_disconnect(self, reason=None):
|
||||
"""
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue