mirror of
https://github.com/evennia/evennia.git
synced 2026-04-04 15:07:16 +02:00
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)
|
||||
|
||||
|
||||
|
||||
## def cmd_testevent(command):
|
||||
## from src import events
|
||||
## 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.
|
||||
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"),
|
||||
|
|
|
|||
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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():
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue