Various cleanups in the recent modifications, and improvements to how time is handled and displayed.
. Griatch
This commit is contained in:
parent
1ea7e69821
commit
4d9081d710
7 changed files with 152 additions and 108 deletions
|
|
@ -766,7 +766,6 @@ def cmd_help(command):
|
||||||
GLOBAL_CMD_TABLE.add_command("help", cmd_help)
|
GLOBAL_CMD_TABLE.add_command("help", cmd_help)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## def cmd_testevent(command):
|
## def cmd_testevent(command):
|
||||||
## from src import events
|
## from src import events
|
||||||
## from src import scheduler
|
## from src import scheduler
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ if not functions_general.host_os_is('nt'):
|
||||||
# Don't import the resource module if the host OS is Windows.
|
# Don't import the resource module if the host OS is Windows.
|
||||||
import resource
|
import resource
|
||||||
import django
|
import django
|
||||||
|
from django.conf import settings
|
||||||
from src.objects.models import Object
|
from src.objects.models import Object
|
||||||
from src import scheduler
|
from src import scheduler
|
||||||
from src import defines_global
|
from src import defines_global
|
||||||
|
|
@ -43,11 +44,24 @@ def cmd_time(command):
|
||||||
Server local time.
|
Server local time.
|
||||||
"""
|
"""
|
||||||
gtime = gametime.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()
|
synctime = gametime.time_last_sync()
|
||||||
|
synctime_h = functions_general.time_format(synctime, style=2)
|
||||||
ltime = time.strftime('%a %b %d %H:%M:%S %Y (%Z)', time.localtime())
|
ltime = time.strftime('%a %b %d %H:%M:%S %Y (%Z)', time.localtime())
|
||||||
string = " Current game time: %i s." % gtime
|
string = " Real-world times:"
|
||||||
string += "\n Time since cache was last saved: %i s." % synctime
|
string += "\n -- Main time counter: %s (%i s)." % (gtime_h, gtime)
|
||||||
string += "\n Current server time: %s" % ltime
|
|
||||||
|
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)
|
command.source_object.emit_to(string)
|
||||||
|
|
||||||
GLOBAL_CMD_TABLE.add_command("@time", cmd_time, priv_tuple=("genperms.game_info",),
|
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
|
server = command.session.server
|
||||||
start_delta = time.time() - server.start_time
|
start_delta = time.time() - server.start_time
|
||||||
|
|
||||||
source_object.emit_to('Current server time : %s' %
|
string = " Server time info:"
|
||||||
(time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),)))
|
string += "\n -- Current server time : %s" % \
|
||||||
source_object.emit_to('Server start time : %s' %
|
(time.strftime('%a %b %d %H:%M %Y (%Z)', time.localtime(),))
|
||||||
(time.strftime('%a %b %d %H:%M %Y', time.localtime(server.start_time),)))
|
string += "\n -- Server start time : %s" % \
|
||||||
source_object.emit_to('Server uptime : %s' %
|
(time.strftime('%a %b %d %H:%M %Y',
|
||||||
functions_general.time_format(start_delta, style=2))
|
time.localtime(server.start_time),))
|
||||||
|
string += "\n -- Server uptime : %s" % \
|
||||||
# os.getloadavg() is not available on Windows.
|
(functions_general.time_format(start_delta, style=2))
|
||||||
if not functions_general.host_os_is('nt'):
|
if not functions_general.host_os_is('nt'):
|
||||||
|
# os.getloadavg() is not available on Windows.
|
||||||
loadavg = os.getloadavg()
|
loadavg = os.getloadavg()
|
||||||
source_object.emit_to('Server load (1 min) : %.2f' %
|
string += "\n -- Server load (1 min) : %.2f" % loadavg[0]
|
||||||
loadavg[0])
|
source_object.emit_to(string)
|
||||||
GLOBAL_CMD_TABLE.add_command("@uptime", cmd_uptime, priv_tuple=("genperms.game_info",),
|
GLOBAL_CMD_TABLE.add_command("@uptime",
|
||||||
|
cmd_uptime,
|
||||||
|
priv_tuple=("genperms.game_info",),
|
||||||
help_category="Admin")
|
help_category="Admin")
|
||||||
|
|
||||||
def cmd_list(command):
|
def cmd_list(command):
|
||||||
|
|
@ -195,10 +212,12 @@ def cmd_showcache(command):
|
||||||
"""
|
"""
|
||||||
source_object = command.source_object
|
source_object = command.source_object
|
||||||
str_cache, str_pcache = cache.show()
|
str_cache, str_pcache = cache.show()
|
||||||
|
ncache = len(str_cache.split(','))
|
||||||
|
npcache = len(str_pcache.split(','))
|
||||||
string = ""
|
string = ""
|
||||||
if str_cache:
|
if str_cache:
|
||||||
string += "\nVolatile cache:\n " + str_cache
|
string += "\nVolatile cache (%i):\n %s" % (ncache, str_cache)
|
||||||
if str_pcache:
|
if str_pcache:
|
||||||
string += "\nPersistent cache:\n " + str_pcache
|
string += "\nPersistent cache (%i):\n %s" % (npcache, str_pcache)
|
||||||
source_object.emit_to(string)
|
source_object.emit_to(string)
|
||||||
GLOBAL_CMD_TABLE.add_command("@showcache", cmd_showcache, priv_tuple=("genperms.game_info",), help_category="Admin"),
|
GLOBAL_CMD_TABLE.add_command("@showcache", cmd_showcache, priv_tuple=("genperms.game_info",), help_category="Admin"),
|
||||||
|
|
|
||||||
|
|
@ -184,13 +184,10 @@ class IEvt_Sync_PCache(IntervalEvent):
|
||||||
"""
|
"""
|
||||||
This is the function that is fired every self.interval seconds.
|
This is the function that is fired every self.interval seconds.
|
||||||
"""
|
"""
|
||||||
infostring = "Syncing time, events and persistent cache to disk."
|
#infostring = "Syncing time, events and persistent cache to disk."
|
||||||
logger.log_infomsg(infostring)
|
#logger.log_infomsg(infostring)
|
||||||
# updating the current time
|
# save the current time
|
||||||
time0 = time.time()
|
gametime.time_save()
|
||||||
time1 = gametime.time(time0)
|
|
||||||
cache.set_pcache("_game_time0", time0)
|
|
||||||
cache.set_pcache("_game_time", time1)
|
|
||||||
# update the event database to pcache
|
# update the event database to pcache
|
||||||
ecache = [event for event in scheduler.SCHEDULE
|
ecache = [event for event in scheduler.SCHEDULE
|
||||||
if event.persistent]
|
if event.persistent]
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
"""
|
"""
|
||||||
The gametime module handles the global passage of time in the mud.
|
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
|
from django.conf import settings
|
||||||
|
|
@ -33,6 +33,34 @@ WEEK = DAY * settings.TIME_DAY_PER_WEEK
|
||||||
MONTH = WEEK * settings.TIME_WEEK_PER_MONTH
|
MONTH = WEEK * settings.TIME_WEEK_PER_MONTH
|
||||||
YEAR = MONTH * settings.TIME_MONTH_PER_YEAR
|
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,
|
def gametime_to_realtime(secs=0, mins=0, hrs=0, days=0,
|
||||||
weeks=0, months=0, yrs=0):
|
weeks=0, months=0, yrs=0):
|
||||||
"""
|
"""
|
||||||
|
|
@ -63,36 +91,19 @@ def realtime_to_gametime(secs=0, mins=0, hrs=0, days=0,
|
||||||
weeks*604800 + months*2419200 + yrs*29030400)
|
weeks*604800 + months*2419200 + yrs*29030400)
|
||||||
return stot
|
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
|
# Time administration routines
|
||||||
(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.
|
def time_init():
|
||||||
"""
|
"""
|
||||||
time0 = cache.get_pcache("_game_time0")
|
Called by Evennia's initial startup; this should normally not be called from
|
||||||
time1 = cache.get_pcache("_game_time")
|
a running game, it resets the global in-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
|
time0 = time_module.time()
|
||||||
to adjust event counters for offline time. The error of this measure is
|
time1 = 0
|
||||||
dependent on how often the cache is saved to disk.
|
cache.set_pcache("_game_time0", time0)
|
||||||
"""
|
cache.set_pcache("_game_time", time1)
|
||||||
time0 = cache.get_pcache("_game_time0")
|
cache.save_pcache()
|
||||||
return time_module.time() - time0
|
|
||||||
|
|
||||||
def time_save():
|
def time_save():
|
||||||
"""
|
"""
|
||||||
|
|
@ -107,3 +118,16 @@ def time_save():
|
||||||
cache.set_pcache("_game_time", time1)
|
cache.set_pcache("_game_time", time1)
|
||||||
cache.save_pcache()
|
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
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ from src import session_mgr
|
||||||
from src import scheduler
|
from src import scheduler
|
||||||
from src import events
|
from src import events
|
||||||
from src.cache import cache
|
from src.cache import cache
|
||||||
|
from src import gametime
|
||||||
# Main module methods
|
# Main module methods
|
||||||
|
|
||||||
def get_god_user():
|
def get_god_user():
|
||||||
|
|
@ -170,16 +170,8 @@ def start_game_time():
|
||||||
"""
|
"""
|
||||||
This creates a persistent time stamp (in s since an arbitrary start)
|
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.
|
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()
|
gametime.time_init()
|
||||||
time1 = 0
|
|
||||||
cache.set_pcache("_game_time0", time0)
|
|
||||||
cache.set_pcache("_game_time", time1)
|
|
||||||
cache.save_pcache()
|
|
||||||
|
|
||||||
def handle_setup():
|
def handle_setup():
|
||||||
"""
|
"""
|
||||||
|
|
|
||||||
|
|
@ -65,6 +65,24 @@ class Attribute(models.Model):
|
||||||
attr_value = pickle.loads(attr_value)
|
attr_value = pickle.loads(attr_value)
|
||||||
return 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):
|
def get_object(self):
|
||||||
"""
|
"""
|
||||||
Returns the object that the attribute resides on.
|
Returns the object that the attribute resides on.
|
||||||
|
|
@ -99,6 +117,8 @@ class Attribute(models.Model):
|
||||||
return "%s%s%s: %s" % (ANSITable.ansi["hilite"],
|
return "%s%s%s: %s" % (ANSITable.ansi["hilite"],
|
||||||
self.get_name(),ANSITable.ansi["normal"],
|
self.get_name(),ANSITable.ansi["normal"],
|
||||||
self.get_value())
|
self.get_value())
|
||||||
|
value = property(fget=get_value,fset=set_value)
|
||||||
|
|
||||||
|
|
||||||
class Object(models.Model):
|
class Object(models.Model):
|
||||||
"""
|
"""
|
||||||
|
|
@ -635,34 +655,21 @@ class Object(models.Model):
|
||||||
attrib_obj = \
|
attrib_obj = \
|
||||||
Attribute.objects.filter(attr_object=self).filter(attr_name__iexact=attribute)[0]
|
Attribute.objects.filter(attr_object=self).filter(attr_name__iexact=attribute)[0]
|
||||||
|
|
||||||
if new_value != None:
|
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:
|
if attrib_obj:
|
||||||
# Save over the existing attribute's value.
|
attrib_obj.delete()
|
||||||
attrib_obj.attr_value = new_value
|
return
|
||||||
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 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):
|
def get_attribute_value(self, attrib, default=None):
|
||||||
"""
|
"""
|
||||||
|
|
@ -683,9 +690,7 @@ class Object(models.Model):
|
||||||
else:
|
else:
|
||||||
return default
|
return default
|
||||||
|
|
||||||
attribute = property(fget=get_attribute_value, fset=set_attribute)
|
def get_attribute_obj(self, attrib, auto_create=False):
|
||||||
|
|
||||||
def get_attribute_obj(self, attrib):
|
|
||||||
"""
|
"""
|
||||||
Returns the attribute object matching the specified name.
|
Returns the attribute object matching the specified name.
|
||||||
|
|
||||||
|
|
@ -694,8 +699,15 @@ class Object(models.Model):
|
||||||
if self.has_attribute(attrib):
|
if self.has_attribute(attrib):
|
||||||
return Attribute.objects.filter(attr_object=self).filter(attr_name=attrib)
|
return Attribute.objects.filter(attr_object=self).filter(attr_name=attrib)
|
||||||
else:
|
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):
|
def clear_attribute(self, attribute):
|
||||||
"""
|
"""
|
||||||
|
|
@ -718,7 +730,6 @@ class Object(models.Model):
|
||||||
return [attr for attr in self.attribute_set.all()
|
return [attr for attr in self.attribute_set.all()
|
||||||
if not attr.is_hidden()]
|
if not attr.is_hidden()]
|
||||||
|
|
||||||
|
|
||||||
def clear_all_attributes(self):
|
def clear_all_attributes(self):
|
||||||
"""
|
"""
|
||||||
Clears all of an object's attributes.
|
Clears all of an object's attributes.
|
||||||
|
|
|
||||||
|
|
@ -63,17 +63,19 @@ class EvenniaService(service.Service):
|
||||||
if not firstrun:
|
if not firstrun:
|
||||||
# Find out how much offset the timer is (due to being
|
# Find out how much offset the timer is (due to being
|
||||||
# offline).
|
# offline).
|
||||||
time_sync = gametime.time_last_sync()
|
downtime_sync = gametime.time_last_sync()
|
||||||
|
|
||||||
# Sync the in-game timer.
|
# Sync the in-game timer.
|
||||||
cache.set_pcache("_game_time0", self.start_time)
|
gametime.time_save()
|
||||||
|
|
||||||
# Fire up the event scheduler.
|
# Fire up the event scheduler.
|
||||||
event_cache = cache.get_pcache("_persistent_event_cache")
|
event_cache = cache.get_pcache("_persistent_event_cache")
|
||||||
if event_cache and type(event_cache) == type(list()):
|
if event_cache and type(event_cache) == type(list()):
|
||||||
for event in event_cache:
|
for event in event_cache:
|
||||||
# we adjust the executed time to account for offline time.
|
# We adjust the last executed time to account for offline time.
|
||||||
event.time_last_executed = event.time_last_executed + time_sync
|
# 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)
|
scheduler.add_event(event)
|
||||||
|
|
||||||
print '-'*50
|
print '-'*50
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue