Various cleanups in the recent modifications, and improvements to how time is handled and displayed.

.
Griatch
This commit is contained in:
Griatch 2009-11-25 19:27:32 +00:00
parent 1ea7e69821
commit 4d9081d710
7 changed files with 152 additions and 108 deletions

View file

@ -766,7 +766,6 @@ def cmd_help(command):
GLOBAL_CMD_TABLE.add_command("help", cmd_help)
## def cmd_testevent(command):
## from src import events
## from src import scheduler

View file

@ -9,6 +9,7 @@ if not functions_general.host_os_is('nt'):
# Don't import the resource module if the host OS is Windows.
import resource
import django
from django.conf import settings
from src.objects.models import Object
from src import scheduler
from src import defines_global
@ -43,11 +44,24 @@ def cmd_time(command):
Server local time.
"""
gtime = gametime.time()
gtime_h = functions_general.time_format(gtime, style=2)
ictime = gtime * settings.TIME_FACTOR
ictime_h = functions_general.time_format(ictime, style=2)
uptime = time.time() - command.session.server.start_time
uptime_h = functions_general.time_format(uptime, style=2)
synctime = gametime.time_last_sync()
ltime = time.strftime('%a %b %d %H:%M:%S %Y (%Z)', time.localtime())
string = " Current game time: %i s." % gtime
string += "\n Time since cache was last saved: %i s." % synctime
string += "\n Current server time: %s" % ltime
synctime_h = functions_general.time_format(synctime, style=2)
ltime = time.strftime('%a %b %d %H:%M:%S %Y (%Z)', time.localtime())
string = " Real-world times:"
string += "\n -- Main time counter: %s (%i s)." % (gtime_h, gtime)
string += "\n -- Time since last reboot: %s (%i s). " % (uptime_h, uptime)
string += "\n -- Time since cache was last saved: %s (%i s)." % (synctime_h,
synctime)
string += "\n -- Current server time: %s" % ltime
string += "\n In-game time (time factor %s):" % settings.TIME_FACTOR
string += "\n -- Time passed: %s" % ictime_h
command.source_object.emit_to(string)
GLOBAL_CMD_TABLE.add_command("@time", cmd_time, priv_tuple=("genperms.game_info",),
@ -66,19 +80,22 @@ def cmd_uptime(command):
server = command.session.server
start_delta = time.time() - server.start_time
source_object.emit_to('Current server time : %s' %
(time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))
source_object.emit_to('Server start time : %s' %
(time.strftime('%a %b %d %H:%M %Y', time.localtime(server.start_time),)))
source_object.emit_to('Server uptime : %s' %
functions_general.time_format(start_delta, style=2))
# os.getloadavg() is not available on Windows.
string = " Server time info:"
string += "\n -- Current server time : %s" % \
(time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),))
string += "\n -- Server start time : %s" % \
(time.strftime('%a %b %d %H:%M %Y',
time.localtime(server.start_time),))
string += "\n -- Server uptime : %s" % \
(functions_general.time_format(start_delta, style=2))
if not functions_general.host_os_is('nt'):
# os.getloadavg() is not available on Windows.
loadavg = os.getloadavg()
source_object.emit_to('Server load (1 min) : %.2f' %
loadavg[0])
GLOBAL_CMD_TABLE.add_command("@uptime", cmd_uptime, priv_tuple=("genperms.game_info",),
string += "\n -- Server load (1 min) : %.2f" % loadavg[0]
source_object.emit_to(string)
GLOBAL_CMD_TABLE.add_command("@uptime",
cmd_uptime,
priv_tuple=("genperms.game_info",),
help_category="Admin")
def cmd_list(command):
@ -195,10 +212,12 @@ def cmd_showcache(command):
"""
source_object = command.source_object
str_cache, str_pcache = cache.show()
ncache = len(str_cache.split(','))
npcache = len(str_pcache.split(','))
string = ""
if str_cache:
string += "\nVolatile cache:\n " + str_cache
string += "\nVolatile cache (%i):\n %s" % (ncache, str_cache)
if str_pcache:
string += "\nPersistent cache:\n " + str_pcache
string += "\nPersistent cache (%i):\n %s" % (npcache, str_pcache)
source_object.emit_to(string)
GLOBAL_CMD_TABLE.add_command("@showcache", cmd_showcache, priv_tuple=("genperms.game_info",), help_category="Admin"),

View file

@ -184,13 +184,10 @@ class IEvt_Sync_PCache(IntervalEvent):
"""
This is the function that is fired every self.interval seconds.
"""
infostring = "Syncing time, events and persistent cache to disk."
logger.log_infomsg(infostring)
# updating the current time
time0 = time.time()
time1 = gametime.time(time0)
cache.set_pcache("_game_time0", time0)
cache.set_pcache("_game_time", time1)
#infostring = "Syncing time, events and persistent cache to disk."
#logger.log_infomsg(infostring)
# save the current time
gametime.time_save()
# update the event database to pcache
ecache = [event for event in scheduler.SCHEDULE
if event.persistent]

View file

@ -1,8 +1,8 @@
"""
The gametime module handles the global passage of time in the mud.
It also
It also supplies some useful methods to convert between
in-mud time and real-worl time.
"""
from django.conf import settings
@ -33,6 +33,34 @@ WEEK = DAY * settings.TIME_DAY_PER_WEEK
MONTH = WEEK * settings.TIME_WEEK_PER_MONTH
YEAR = MONTH * settings.TIME_MONTH_PER_YEAR
# Access routines
def time(currtime=None):
"""
Find the current in-game time (in seconds) since the start of the mud.
The value returned from this function can be used to track the 'true'
in-game time since only the time the game has actually been active will
be adding up (ignoring downtimes).
Obs: depending on how often the persistent cache is saved to disk
(this is defined in the config file), there might be some discrepancy
here after a server crash, notably that some time will be 'lost' (i.e.
the time since last backup). If this is a concern, consider saving
the cache more often.
currtime : An externally calculated current time to compare with.
This is used by Evennia to make sure to sync the game
time to a new real-world timestamp
"""
# saved real world timestamp (seconds since 1970 or so)
time0 = cache.get_pcache("_game_time0")
# saved game time at real-world time time0
time1 = cache.get_pcache("_game_time")
if currtime:
return time1 + (currtime - time0)
else:
return time1 + (time_module.time() - time0)
def gametime_to_realtime(secs=0, mins=0, hrs=0, days=0,
weeks=0, months=0, yrs=0):
"""
@ -63,37 +91,20 @@ def realtime_to_gametime(secs=0, mins=0, hrs=0, days=0,
weeks*604800 + months*2419200 + yrs*29030400)
return stot
def time(currtime=None):
"""
Find the current in-game time (in seconds) since the start of the mud.
This is the main measure of in-game time and is persistently saved to
disk, so is the main thing to use to determine passage of time like
seasons etc.
Obs depending on how often the persistent cache is saved to disk
(this is defined in the config file), there might be some discrepancy
here after a server crash, notably that some time will be 'lost' (i.e.
the time since last backup). If this is a concern, consider saving
the cache more often.
currtime : An externally calculated current time to compare with.
"""
time0 = cache.get_pcache("_game_time0")
time1 = cache.get_pcache("_game_time")
if currtime:
return time1 + (currtime - time0)
else:
return time1 + (time_module.time() - time0)
def time_last_sync():
"""
Calculates the time since the system was last synced to disk. This e.g. used
to adjust event counters for offline time. The error of this measure is
dependent on how often the cache is saved to disk.
"""
time0 = cache.get_pcache("_game_time0")
return time_module.time() - time0
# Time administration routines
def time_init():
"""
Called by Evennia's initial startup; this should normally not be called from
a running game, it resets the global in-game time!
"""
time0 = time_module.time()
time1 = 0
cache.set_pcache("_game_time0", time0)
cache.set_pcache("_game_time", time1)
cache.save_pcache()
def time_save():
"""
Force a save of the current time to persistent cache.
@ -106,4 +117,17 @@ def time_save():
cache.set_pcache("_game_time0", time0)
cache.set_pcache("_game_time", time1)
cache.save_pcache()
def time_last_sync():
"""
Calculates the time since the system was last synced to disk. This e.g. used
to adjust event counters for offline time, resulting in a maximum error being
the time between backups.
"""
# Real-world timestamp for last backup
time0 = cache.get_pcache("_game_time0")
# The correction factor is the time
# since last backup + downtime.
return time_module.time() - time0

View file

@ -17,7 +17,7 @@ from src import session_mgr
from src import scheduler
from src import events
from src.cache import cache
from src import gametime
# Main module methods
def get_god_user():
@ -170,16 +170,8 @@ def start_game_time():
"""
This creates a persistent time stamp (in s since an arbitrary start)
upon first server start and is saved and updated regularly in persistent cache.
_game_time0 is the current absolute time (in s since an arbitrary start)
_game_time is the current relative number of seconds that the server has been running
(not counting offline time), accurate to the time between
cache saves, when this is stored.
"""
time0 = time.time()
time1 = 0
cache.set_pcache("_game_time0", time0)
cache.set_pcache("_game_time", time1)
cache.save_pcache()
gametime.time_init()
def handle_setup():
"""

View file

@ -64,7 +64,25 @@ class Attribute(models.Model):
if self.attr_ispickled:
attr_value = pickle.loads(attr_value)
return attr_value
def set_value(self, new_value):
"""
Sets an attributes value
"""
if new_value == None:
self.delete()
return
#pickle everything but strings
if type(new_value) != type(str()):
new_value = pickle.dumps(new_value) #,pickle.HIGHEST_PROTOCOL)
ispickled = True
else:
new_value = new_value
ispickled = False
self.attr_value = new_value
self.attr_ispickled = ispickled
self.save()
def get_object(self):
"""
Returns the object that the attribute resides on.
@ -99,6 +117,8 @@ class Attribute(models.Model):
return "%s%s%s: %s" % (ANSITable.ansi["hilite"],
self.get_name(),ANSITable.ansi["normal"],
self.get_value())
value = property(fget=get_value,fset=set_value)
class Object(models.Model):
"""
@ -634,35 +654,22 @@ class Object(models.Model):
if self.has_attribute(attribute):
attrib_obj = \
Attribute.objects.filter(attr_object=self).filter(attr_name__iexact=attribute)[0]
if new_value != None:
#pickle if anything else than str
if type(new_value) != type(str()):
new_value = pickle.dumps(new_value)#,pickle.HIGHEST_PROTOCOL)
ispickled = True
else:
new_value = new_value
ispickled = False
if attrib_obj:
# Save over the existing attribute's value.
attrib_obj.attr_value = new_value
attrib_obj.attr_ispickled = ispickled
attrib_obj.save()
else:
# Create a new attribute
new_attrib = Attribute()
new_attrib.attr_name = attribute
new_attrib.attr_value = new_value
new_attrib.attr_object = self
new_attrib.attr_hidden = False
new_attrib.attr_ispickled = ispickled
new_attrib.save()
elif attrib_obj:
# If you do something like @set me=attrib: , destroy the attrib.
attrib_obj.delete()
if new_value == None:
if attrib_obj:
attrib_obj.delete()
return
if attrib_obj:
# Save over the existing attribute's value.
attrib_obj.set_value(new_value)
else:
# Create a new attribute
new_attrib = Attribute()
new_attrib.attr_name = attribute
new_attrib.attr_object = self
new_attrib.attr_hidden = False
new_attrib.set_value(new_value)
def get_attribute_value(self, attrib, default=None):
"""
@ -682,10 +689,8 @@ class Object(models.Model):
return attrib.get_value()
else:
return default
attribute = property(fget=get_attribute_value, fset=set_attribute)
def get_attribute_obj(self, attrib):
def get_attribute_obj(self, attrib, auto_create=False):
"""
Returns the attribute object matching the specified name.
@ -694,9 +699,16 @@ class Object(models.Model):
if self.has_attribute(attrib):
return Attribute.objects.filter(attr_object=self).filter(attr_name=attrib)
else:
return False
if auto_create:
new_attrib = Attribute()
new_attrib.attr_name = attrib
new_attrib.attr_object = self
new_attrib.attr_hidden = False
new_attrib.save()
return new_attrib
else:
return False
def clear_attribute(self, attribute):
"""
Removes an attribute entirely.
@ -717,8 +729,7 @@ class Object(models.Model):
"""
return [attr for attr in self.attribute_set.all()
if not attr.is_hidden()]
def clear_all_attributes(self):
"""
Clears all of an object's attributes.

View file

@ -63,17 +63,19 @@ class EvenniaService(service.Service):
if not firstrun:
# Find out how much offset the timer is (due to being
# offline).
time_sync = gametime.time_last_sync()
downtime_sync = gametime.time_last_sync()
# Sync the in-game timer.
cache.set_pcache("_game_time0", self.start_time)
gametime.time_save()
# Fire up the event scheduler.
event_cache = cache.get_pcache("_persistent_event_cache")
if event_cache and type(event_cache) == type(list()):
for event in event_cache:
# we adjust the executed time to account for offline time.
event.time_last_executed = event.time_last_executed + time_sync
# We adjust the last executed time to account for offline time.
# If we don't, the events will be confused since their last
# executed time is further away than their firing interval.
event.time_last_executed = event.time_last_executed + downtime_sync
scheduler.add_event(event)
print '-'*50