From d3ee5a565b1461011428c85abbff444e2ff4f7f9 Mon Sep 17 00:00:00 2001 From: Griatch Date: Sat, 19 May 2012 12:36:11 +0200 Subject: [PATCH] Added a loader to the server that automatically detects changes in default cmdsets and typeclasses (like when you change them in settings.py), loops over all objects in the database and updates the places were the old default was set. This will make it more intuitive to overload the default locations (which is the natural thing to do after all). After this update, just make sure to @reload your server once before editing your settings.py; this will store the old settings for you, so they change-detection can work subsequently. --- src/server/server.py | 39 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/src/server/server.py b/src/server/server.py index 25e727a883..bfbfe9bb78 100644 --- a/src/server/server.py +++ b/src/server/server.py @@ -10,7 +10,6 @@ by game/evennia.py). import time import sys import os -import signal if os.name == 'nt': # For Windows batchfile we need an extra path insertion here. sys.path.insert(0, os.path.dirname(os.path.dirname( @@ -128,6 +127,41 @@ class Evennia(object): cursor.execute("PRAGMA count_changes=OFF") cursor.execute("PRAGMA temp_store=2") + def update_defaults(self): + """ + We make sure to store the most important object defaults here, so we can catch if they + change and update them on-objects automatically. This allows for changing default cmdset locations + and default typeclasses in the settings file and have them auto-update all already existing + objects. + """ + # setting names + settings_names = ("CMDSET_DEFAULT", "CMDSET_OOC", "BASE_PLAYER_TYPECLASS", "BASE_OBJECT_TYPECLASS", + "BASE_CHARACTER_TYPECLASS", "BASE_ROOM_TYPECLASS", "BASE_EXIT_TYPECLASS", "BASE_SCRIPT_TYPECLASS") + # get previous and current settings so they can be compared + settings_compare = zip([ServerConfig.objects.conf(name) for name in settings_names], + [settings.__getattr__(name) for name in settings_names]) + mismatches = [i for i, tup in enumerate(settings_compare) if tup[0] and tup[1] and tup[0] != tup[1]] + if len(mismatches): # can't use any() since mismatches may be [0] which reads as False for any() + # we have a changed default. Import relevant objects and run the update + from src.objects.models import ObjectDB + from src.players.models import PlayerDB + for i, prev, curr in ((i, tup[0], tup[1]) for i, tup in enumerate(settings_compare) if i in mismatches): + # update the database + print " one or more default cmdset/typeclass settings changed. Updating defaults stored in database ..." + if i == 0: [obj.__setattr__("cmdset_storage", curr) for obj in ObjectDB.objects.filter(db_cmdset_storage__exact=prev)] + if i == 1: [ply.__setattr__("cmdset_storage", curr) for ply in PlayerDB.objects.filter(db_cmdset_storage__exact=prev)] + if i == 2: [ply.__setattr__("typeclass_path", curr) for ply in PlayerDB.objects.filter(db_typeclass_path__exact=prev)] + if i in (3,4,5,6): [obj.__setattr__("typeclass_path",curr) + for obj in ObjectDB.objects.filter(db_typeclass_path__exact=prev)] + if i == 7: [scr.__setattr__("typeclass_path", curr) for scr in ScriptDB.objects.filter(db_typeclass_path__exact=prev)] + # store the new default and clean caches + ServerConfig.objects.conf(settings_names[i], curr) + ObjectDB.flush_instance_cache() + PlayerDB.flush_instance_cache() + ScriptDB.flush_instance_cache() + # if this is the first start we might not have a "previous" setup saved. Store it now. + [ServerConfig.objects.conf(settings_names[i], tup[1]) for i, tup in enumerate(settings_compare) if not tup[0]] + def run_initial_setup(self): """ This attempts to run the initial_setup script of the server. @@ -158,6 +192,9 @@ class Evennia(object): from src.objects.models import ObjectDB from src.players.models import PlayerDB + #update eventual changed defaults + self.update_defaults() + #print "run_init_hooks:", ObjectDB.get_all_cached_instances() [(o.typeclass, o.at_init()) for o in ObjectDB.get_all_cached_instances()] [(p.typeclass, p.at_init()) for p in PlayerDB.get_all_cached_instances()]