New timestamps feature in version 4.62

Posted by Nick Gammon on Sat 25 Sep 2010 09:36 AM — 20 posts, 90,712 views.

Australia Forum Administrator #0
Version 4.62 of MUSHclient introduces the ability to timestamp each line in the output window.

Lines can be marked individually depending on whether they are:

  • Input (stuff you type)
  • Output (stuff from the MUD)
  • Notes (scripted messages)


An example is here:



To make it easier to use, version 4.62+ has a new plugin "Timestamps" that, if installed, activates the timestamps.

Template:saveplugin=Timestamps
To save and install the Timestamps plugin do this:
  1. Copy the code below (in the code box) to the Clipboard
  2. Open a text editor (such as Notepad) and paste the plugin code into it
  3. Save to disk on your PC, preferably in your plugins directory, as Timestamps.xml
    • The "plugins" directory is usually under the "worlds" directory inside where you installed MUSHclient.
  4. Go to the MUSHclient File menu -> Plugins
  5. Click "Add"
  6. Choose the file Timestamps.xml (which you just saved in step 3) as a plugin
  7. Click "Close"
  8. Save your world file, so that the plugin loads next time you open it.


You can customize the messages (so you might put "input" on an input line). If you are planning to customize it you should save it under a different file name so it isn't replaced next time you upgrade MUSHclient.


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<!--
Change the following variables to customise your timestamps:

TIMESTAMP_INPUT  : what to put in front of things you type
TIMESTAMP_OUTPUT : what to put in front of MUD output
TIMESTAMP_NOTES  : what to put in front of scripted notes

Text colours:

TIMESTAMP_INPUT_TEXT_COLOUR
TIMESTAMP_OUTPUT_TEXT_COLOUR
TIMESTAMP_NOTES_TEXT_COLOUR

Background (behind the timestamp) colours:

TIMESTAMP_INPUT_BACK_COLOUR
TIMESTAMP_OUTPUT_BACK_COLOUR
TIMESTAMP_NOTES_BACK_COLOUR

Special characters for date/time etc.

General
%E - MUSHclient initial (startup) directory
%F - world files directory
%L - log files directory
%N - world name
%P - player name

Date/time
%a - Abbreviated weekday name
%A - Full weekday name
%b - Abbreviated month name
%B - Full month name
%c - Date and time representation appropriate for locale
%d - Day of month as decimal number (01 - 31)
%H - Hour in 24-hour format (00 - 23)

%I - Hour in 12-hour format (01 - 12)
%j - Day of year as decimal number (001 - 366)
%m - Month as decimal number (01 - 12)
%M - Minute as decimal number (00 - 59)
%p - A.M./P.M. indicator for 12-hour clock
%S - Second as decimal number (00 - 59)
%U - Week of year as decimal number, with Sunday as first day of week (00 - 53)
%w - Weekday as decimal number (0 - 6; Sunday is 0)
%W - Week of year as decimal number, with Monday as first day of week (00 - 53)
%x - Date representation for current locale
%X - Time representation for current locale
%y - Year without century, as decimal number (00 - 99)
%Y - Year with century, as decimal number
%z, %Z  - Time-zone name or abbreviation; no characters if time zone is unknown
%% - Percent sign

%e - Elapsed time in microseconds since world started
%D - Delta time, in microseconds, since previous line

-->

<muclient>
<plugin
   name="Timestamps"
   author="Nick Gammon"
   id="559d05b18c3fd5602a433cf8"
   language="Lua"
   purpose="Adds a timestamp to each line in the output window"
   save_state="y"
   date_written="2010-09-25 14:02:11"
   requires="4.62"
   version="1.0"
   >
<description trim="y">
<![CDATA[
Enable this plugin to see timestamps.

Disable to hide them.
]]>
</description>

</plugin>


<!--  Script  -->


<script>
<![CDATA[

TIMESTAMP_INPUT   = "%H:%M:%S $ "
TIMESTAMP_OUTPUT  = "%H:%M:%S > "
TIMESTAMP_NOTES   = "%H:%M:%S ! "

TIMESTAMP_INPUT_TEXT_COLOUR   = ColourNameToRGB ("maroon")
TIMESTAMP_OUTPUT_TEXT_COLOUR  = ColourNameToRGB ("white")
TIMESTAMP_NOTES_TEXT_COLOUR   = ColourNameToRGB ("cyan")

TIMESTAMP_INPUT_BACK_COLOUR   = ColourNameToRGB ("#151515")
TIMESTAMP_OUTPUT_BACK_COLOUR  = ColourNameToRGB ("#151515")
TIMESTAMP_NOTES_BACK_COLOUR   = ColourNameToRGB ("#151515")

function OnPluginInstall ()

  -- if disabled last time, stay disabled
  if GetVariable ("enabled") == "false" then
    ColourNote ("yellow", "", "Warning: Plugin " .. GetPluginName ().. " is currently disabled.")
    check (EnablePlugin(GetPluginID (), false))
    return
  end -- they didn't enable us last time
 
  OnPluginEnable ()
  
end -- OnPluginInstall

function OnPluginSaveState ()
  SetVariable ("enabled", tostring (GetPluginInfo (GetPluginID (), 17)))
end -- OnPluginSaveState

function OnPluginDisable ()

  SetAlphaOption ("timestamp_input",  "")
  SetAlphaOption ("timestamp_output", "")
  SetAlphaOption ("timestamp_notes",  "")
  Redraw ()
  
end -- OnPluginDisable

function OnPluginEnable ()
 
  SetAlphaOption ("timestamp_input",  TIMESTAMP_INPUT)
  SetAlphaOption ("timestamp_output", TIMESTAMP_OUTPUT)
  SetAlphaOption ("timestamp_notes",  TIMESTAMP_NOTES)
  
  SetOption ("timestamp_input_text_colour",   TIMESTAMP_INPUT_TEXT_COLOUR )
  SetOption ("timestamp_output_text_colour",  TIMESTAMP_OUTPUT_TEXT_COLOUR )
  SetOption ("timestamp_notes_text_colour",   TIMESTAMP_NOTES_TEXT_COLOUR )

  SetOption ("timestamp_input_back_colour",   TIMESTAMP_INPUT_BACK_COLOUR )
  SetOption ("timestamp_output_back_colour",  TIMESTAMP_OUTPUT_BACK_COLOUR )
  SetOption ("timestamp_notes_back_colour",   TIMESTAMP_NOTES_BACK_COLOUR )

  Redraw ()
  
end -- OnPluginEnable


]]>
</script>


</muclient>
Amended on Sat 21 Nov 2015 02:04 AM by Fiendish
Australia Forum Administrator #1
You can manually (with an alias, for example) turn on the timestamps like this:


SetAlphaOption ("timestamp_input", "(input) %H:%M:%S > " )
SetOption      ("timestamp_input_text_colour", ColourNameToRGB ("brown") )

SetAlphaOption ("timestamp_output", "%H:%M:%S (%P) > " )
SetOption      ("timestamp_output_text_colour", ColourNameToRGB ("white") )


Just to clarify, the timestamps are displayed as part of the output-drawing routine. The actual data in the output buffer is unchanged. Triggers do not need to change to take into account the timestamps - they are not actually part of the text of the line.

You can turn them on or off at will (set to an empty string to turn them off). So you could leave them off normally and then just use the timestamps plugin to check when certain events happened, and then disable the plugin to hide the timestamps.
#2
Is there any chance of getting a milliseconds field to use with this? In my own efforts to build a new client based on the MUSHclient source, I had added that feature, and I think it worked pretty well. Sub-second timing is very useful to all the MUD meta-gamers trying to min/max everything. :)
USA #3
You should be able to use any of the flags defined for the logging feature, I think?

Documentation said:
Special characters for date/time etc.
-------------------------------------

General

%E - MUSHclient startup (initial) directory
%F - world files directory
%L - log files directory
%n - new line (in some cases on*ly)
%N - world name
%P - player name

Date/time

%a - Abbreviated weekday name
%A - Full weekday name
%b - Abbreviated month name
%B - Full month name
%c - Date and time representation appropriate for locale
%d - Day of month as decimal number (01 - 31)

%H - Hour in 24-hour format (00 - 23)

%I - Hour in 12-hour format (01 - 12)
%j - Day of year as decimal number (001 - 366)
%m - Month as decimal number (01 - 12)
%M - Minute as decimal number (00 - 59)
%p - Current locale's A.M./P.M. indicator for 12-hour clock
%S - Second as decimal number (00 - 59)
%U - Week of year as decimal number, with Sunday as first day of week (00 - 53)
%w - Weekday as decimal number (0 - 6; Sunday is 0)
%W - Week of year as decimal number, with Monday as first day of week (00 - 53)

%x - Date representation for current locale
%X - Time representation for current locale
%y - Year without century, as decimal number (00 - 99)
%Y - Year with century, as decimal number
%z, %Z - Time-zone name or abbreviation; no characters if time zone is unknown
%% - Percent sign

Modification

The # flag may prefix any formatting code. In that case, the meaning of the format code is changed as follows.

%#a, %#A, %#b, %#B, %#p, %#X, %#z, %#Z, %#% - # flag is ignored.

%#c - Long date and time representation, appropriate for current locale. For example: "Tuesday, March 14, 1995, 12:41:29".

%#x - Long date representation, appropriate to current locale. For example: "Tuesday, March 4, 1995".

%#d, %#H, %#I, %#j, %#m, %#M, %#S, %#U, %#w, %#W, %#y, %#Y - Remove leading zeros (if any).
Amended on Mon 27 Sep 2010 08:19 PM by Twisol
#4
Yes, I know, and you just quoted something Nick had already included in his posted code. :P

None of those is milliseconds!
USA #5
Oh. Sorry! I could have sworn I had used milliseconds before, but I guess not...
Amended on Mon 27 Sep 2010 08:37 PM by Twisol
Australia Forum Administrator #6
I was heading for the computer this morning thinking "well at least no-one has asked for millisconds, thank goodness!". Then I glanced at the forum ...

Larkin said:

None of those is milliseconds!


The trouble is, the time internally is stored as seconds (not milliseconds). Also, the time formatting routines (the operating system library) doesn't provide a format code for sub-seconds.

Do you really want milliseconds? Bear in mind the lag from server to client means that much more than 0.1 seconds is network lag, not actual game time.

Lines nowadays have the high-precision timer information on them. What could be feasible is to show either:

  • Delta time (ie. the time in milliseconds from one line to the next) or
  • Elapsed time (ie. the time in seconds/milliseconds from some arbitrary start point - like the time you were connected)


Australia Forum Administrator #7
See first post comments:


%e - Elapsed time in microseconds since world started
%D - Delta time, in microseconds, since previous line

Australia Forum Administrator #8
I decided to give the delta time 3 leading digits otherwise the lines zig-zag annoyingly if you get some delta times in the range 0 to 9 seconds, some 10 to 99, and some 100 seconds or more.

However if anyone thinks they might have a delta time of over 999 seconds (16.65 minutes), and want things to line up, I can make it 4 digits. After that it gets a bit ridiculous.
Amended on Mon 27 Sep 2010 10:11 PM by Nick Gammon
Netherlands #9
I think three digits is more than plenty. The moment there's more than 20 minutes between the different lines of input, you obviously don't really need that amount of detail.

The detail is mostly meant (if I understand right) for high-paced games where combat and such have things happen in fast succession, and people like to know how long some things took to happen.
#10
In my own development efforts, I used a more precise timekeeping, based off of your CmcDateTime (I think it's called). The time is captured as a double, and that includes some sub-second value, so I pulled out milliseconds by removing the integer portion.

It might be possible for you to use your more precise date/time class for this purpose, maybe?
Australia Forum Administrator #11
Yes well the CmcDateTime is unfortunately a bit of a compromise. The reason is, I can't seem to get the actual high-precision time from the operating system, and the way CmcDateTime works around that is to add in the high-precision timer (which is just a time difference) to the low-precision date/time, thus fudging up a high-precision time.

You can read about it in mcdatetime.cpp near where I say "This considerable amount of mucking around is because ...".

Unfortunately again this method seems to have a "drift" so it resynchronizes every 60 seconds. Thus there is a discontinuity in the time every 60 seconds, which is likely to throw out things like PvP timing.

So ...

I think there are two sorts of time here. One is the "real life" time. If your house is anything like mine, all the clocks there show different times, and I'm talking out by a minute, not by a second ... much to my great annoyance, and I actually have over my desk a clock which is synchronized to the GPS time, which is about the only one which shows the correct time.

Anyway, the approximate time of day is fine for things like complaining to the MUD admin that someone killed you and danced on your grave. That gives them the approximate time to check their logs.

The second situation is where you are timing events, like how long between attack rounds, or how quickly you get healed. And in those cases a time difference, rather than an absolute time, is more relevant.

So the new timestamp "delta time" or "elapsed time from an arbitrary point" will be fine for that, and is going to be around 1 microsecond precision, which should be plenty.


USA #12
I think you and I shared code at one point where I had a function for high-precision timing under Windows -- perhaps in a BabbleMUD prototype. Let me know if you can't find it and I'll see if I can.
Australia Forum Administrator #13
If you mean high-precision time-of-day - no I can't find it.

I can do high-precision timing of intervals.
Australia Forum Administrator #14
This is what the interval timing looks like:



This is a bit contrived - you normally wouldn't show both. On the left is the elapsed time, on the right is the delta time.

You can see that lines which probably arrived in the same packet get processed very fast (around 60 to 70 microseconds). The big gaps are places like when waiting for me to type (eg. 8 seconds). And the message about "Twilight descends" which occurred 12 seconds after the earlier message.

Interestingly in my case, it seemed to take only 10 or 20 milliseconds to respond to player input (this is a local MUD, so you would expect it to be fairly fast).

Oh, and lol at the message from Smaug "You are starving to death. You feel great.".

So, apart from starving to death, I feel great, is that it?
Amended on Tue 28 Sep 2010 05:10 AM by Nick Gammon
USA #15
Ah -- it was probably for high-performance timing, yes. The Unix version gives you the actual time of day whereas the Windows version measures it according to program lifetime or something like that. That must be the offset stuff you were talking about: using an initial timestamp along with the high-performance timer, and then adding the difference of the current high-perf timer and the original high-perf timer to the original timestamp.

Actually I'm a little surprised that that gets you the kind of time drift you were talking about... oh well.

Sorry for the noise. :-)
#16
I have code for a Windows version of gettimeofday that has served me well on a few projects. If it's useful to you in any way, you're welcome to it!

int gettimeofday(struct timeval* tv, struct timezone* tz)
{
  static __int64 Adjustment = 0;
  __int64 Now = 0;
  
  if (!Adjustment)
  {
    SYSTEMTIME st = {1970,1,0,1,0,0,0};
    SystemTimeToFileTime(&st, (LPFILETIME)&Adjustment);
  }
  
  GetSystemTimeAsFileTime((LPFILETIME)&Now);
  Now -= Adjustment;
  
  tv->tv_sec = (long)(Now / 10000000);
  tv->tv_usec = (long)((Now / 100) - (((__int64)tv->tv_sec * 1000) * 100));
  return 0;
}
Australia Forum Administrator #17
Thanks for that. I must have missed that before. I note from MSDN this comment however "Warning: this method only returns the time in resolutions of 15ms (0.015s)".

Whilst that is better than one second resolution, it isn't as good as the high-precision timers.
#18
Im currently using a modified version of your chat redirecting script. I have it sorting my ic channels and my ooc channels into two seperate windows. I tried to add this plugin and I get the following

[WARNING] C:\Program Files (x86)\MUSHclient\worlds\plugins\Timestamps.xml
Line 24: Invalid '--' inside comment (Cannot load)

Being a complete newb to scripting I cannot figure this out.

Help please?
Australia Forum Administrator #19
Near the start of the plugin is this:


Special characters for date/time etc.
-------------------------------------


Just delete the line with the hyphens in it. I must have added that without testing.

It's just a comment anyway.

I amended the original to not have that line in it.