View previous topic :: View next topic |
Author |
Message |
Dracos
Joined: 16 Oct 2006 Posts: 21
|
Posted: Fri Jan 26, 2007 11:40 Post subject: NEGATIVE nwnx time? |
|
|
I don't know why but this happens randmoly on my server:
1. On module load I make nwnx-time start a timer on the object MODULE.
2. When my pc rests to check if he's allowed (meaning has passed the least amount of time to rest again) it's all okay for a while but then sometimes something strange happens, and when this "something" occurs, if I look the Query timer log in the nwnx4 dir it displays a NEGATIVE (like -2467893) number. What can be the cause? |
|
Back to top |
|
|
Grinning Fool
Joined: 12 Feb 2005 Posts: 264
|
Posted: Fri Jan 26, 2007 17:55 Post subject: |
|
|
sounds like an int overflow -- how long was the timer running? _________________ Khalidine, a NWN2 persistent world
Looking for volunteers. |
|
Back to top |
|
|
Dracos
Joined: 16 Oct 2006 Posts: 21
|
Posted: Fri Jan 26, 2007 18:38 Post subject: |
|
|
Here it is:
Code: |
NWNX Timer Plugin V.0.0.1
(c) 2006 by Ingmar Stieger (Papillon)
visit us at http://www.nwnx.org
* Plugin initialized.
o Starting timer REST_MODULE_TIMER0
o Elapsed timer REST_MODULE_TIMER0: 1621947360 µs / 1621947.360 msec / 1621.947 sec
o Elapsed timer REST_MODULE_TIMER0: 1626947909 µs / 1626947.909 msec / 1626.948 sec
o Elapsed timer REST_MODULE_TIMER0: -2803305909 µs / -2803305.909 msec / -2803.306 sec
o Elapsed timer REST_MODULE_TIMER0: -2803305596 µs / -2803305.596 msec / -2803.306 sec
o Elapsed timer REST_MODULE_TIMER0: -2794309949 µs / -2794309.949 msec / -2794.310 sec
o Elapsed timer REST_MODULE_TIMER0: -2794309644 µs / -2794309.644 msec / -2794.310 sec
o Elapsed timer REST_MODULE_TIMER0: 931219131 µs / 931219.131 msec / 931.219 sec
o Elapsed timer REST_MODULE_TIMER0: 1062935714 µs / 1062935.714 msec / 1062.936 sec
o Elapsed timer REST_MODULE_TIMER0: 1062936015 µs / 1062936.015 msec / 1062.936 sec
o Elapsed timer REST_MODULE_TIMER0: 1231478927 µs / 1231478.927 msec / 1231.479 sec
o Elapsed timer REST_MODULE_TIMER0: 1231479349 µs / 1231479.349 msec / 1231.479 sec
o Elapsed timer REST_MODULE_TIMER0: -741526170 µs / -741526.170 msec / -741.526 sec
o Elapsed timer REST_MODULE_TIMER0: -512444517 µs / -512444.517 msec / -512.445 sec
o Elapsed timer REST_MODULE_TIMER0: -507443420 µs / -507443.420 msec / -507.443 sec
o Elapsed timer REST_MODULE_TIMER0: -46693062 µs / -46693.062 msec / -46.693 sec
o Elapsed timer REST_MODULE_TIMER0: -41692963 µs / -41692.963 msec / -41.693 sec
o Elapsed timer REST_MODULE_TIMER0: -37033502 µs / -37033.502 msec / -37.034 sec
o Elapsed timer REST_MODULE_TIMER0: -32033592 µs / -32033.592 msec / -32.034 sec
o Elapsed timer REST_MODULE_TIMER0: 975493789 µs / 975493.789 msec / 975.494 sec
o Elapsed timer REST_MODULE_TIMER0: 975494062 µs / 975494.062 msec / 975.494 sec
o Elapsed timer REST_MODULE_TIMER0: 1064979557 µs / 1064979.557 msec / 1064.980 sec
o Elapsed timer REST_MODULE_TIMER0: 1069981435 µs / 1069981.435 msec / 1069.981 sec | [/code] |
|
Back to top |
|
|
Grinning Fool
Joined: 12 Feb 2005 Posts: 264
|
Posted: Fri Jan 26, 2007 19:12 Post subject: |
|
|
Hmm - it does look like it's cycling back and forth within the int datatype limits. Even if this were correctable within the timer plugin, NWN itself limits ints to 32 bit - that means the max number it can support is 2147483648.
Looks like you'll have to find another way to check rest time; or maybe Papillon could add an additional function to get elapsed time in whole seconds? _________________ Khalidine, a NWN2 persistent world
Looking for volunteers. |
|
Back to top |
|
|
Papillon x-man
Joined: 28 Dec 2004 Posts: 1060 Location: Germany
|
Posted: Sat Jan 27, 2007 22:28 Post subject: |
|
|
Well, I could, but that is a bit out of the scope of the timer plugin (which really is for measuring very short, but accurate timings).
I used the following code for testing rest timeouts back in the days.... have a look at the example to see how it can be used.
Code: |
// Name : Date and time functions (aps persistence version)
// Author : Ingmar Stieger / Papillon
// Created : August 27, 2002
// Modified : April 21, 2003
// Modified : August 30, 2003 (removed call to SpeakString)
// Implemented datatype
// * DateTime
// Implemented functions
// * addDateTime() : Add two DateTimes
// * subDateTime() : Substract two DateTimes
// * compareDateTime() : Compare two DateTimes
// * getCurrentDateTime() : Return current DateTime
// * newDateTime() : Create new DateTime with given values
// * SetLocalDateTime() : Set oObject's local DateTime variable to date
// * GetLocalDateTime() : Get oObject's local DateTime variable
// * SetPersistentDateTime() : Set oObject's persistent DateTime variable to date
// * GetPersistentDateTime() : Set oObject's persistent DateTime variable to date
// * debugPrintDateTime() : Print DateTime for debugging purposes
// * DateTimeToString) : Convert DateTime to string
// See function headers for details
//
// Example:
/* object oPC = GetPCSpeaker();
struct DateTime date1 = getCurrentDateTime();
struct DateTime date2 = newDateTime(0,0,0,8); // 8 hours later
struct DateTime finished = addDateTime(date1, date2);
SetLocalDateTime(oPC, "forge_shortsword_blade_finished", finished);
*/
// Date datatype
struct DateTime
{
int year;
int month;
int day;
int hour;
int minute;
int second;
int millisecond;
};
//
// Add two DateTimes
//
struct DateTime addDateTime(struct DateTime date1, struct DateTime date2)
{
int overflow;
// add milliseconds
if (date1.millisecond + date2.millisecond > 999)
{
date1.second++;
overflow = 1000;
}
date1.millisecond = date1.millisecond + date2.millisecond - overflow;
overflow = 0;
// add seconds
if (date1.second + date2.second > 59)
{
date1.minute++;
overflow = 60;
}
date1.second = date1.second + date2.second - overflow;
overflow = 0;
// add minutes
if (date1.minute + date2.minute > 59)
{
date1.hour++;
overflow = 60;
}
date1.minute = date1.minute + date2.minute - overflow;
overflow = 0;
// add hours
if (date1.hour + date2.hour > 23)
{
date1.day++;
overflow = 24;
}
date1.hour = date1.hour + date2.hour - overflow;
overflow = 0;
// add days
if (date1.day + date2.day > 28)
{
date1.month++;
overflow = 28;
}
date1.day = date1.day + date2.day - overflow;
overflow = 0;
// add months
if (date1.month + date2.month > 12)
{
date1.year++;
overflow = 12;
}
date1.month = date1.month + date2.month - overflow;
overflow = 0;
// add years
date1.year = date1.year + date2.year;
return date1;
}
//
// Substract two DateTimes
//
// returns date1 - date2
//
struct DateTime subDateTime(struct DateTime date1, struct DateTime date2)
{
int underflow;
// sub milliseconds
if (date1.millisecond - date2.millisecond < 0)
{
date1.second--;
underflow = 1000;
}
date1.millisecond = date1.millisecond - date2.millisecond + underflow;
underflow = 0;
// sub seconds
if (date1.second - date2.second < 0)
{
date1.minute--;
underflow = 60;
}
date1.second = date1.second - date2.second + underflow;
underflow = 0;
// sub minutes
if (date1.minute - date2.minute < 0)
{
date1.hour--;
underflow = 60;
}
date1.minute = date1.minute - date2.minute + underflow;
underflow = 0;
// sub hours
if (date1.hour - date2.hour < 0)
{
date1.day--;
underflow = 24;
}
date1.hour = date1.hour - date2.hour + underflow;
underflow = 0;
// sub days
if (date1.day - date2.day < 0)
{
date1.month--;
underflow = 28;
}
date1.day = date1.day - date2.day + underflow;
underflow = 0;
// sub months
if (date1.month - date2.month < 0)
{
date1.year--;
underflow = 12;
}
date1.month = date1.month - date2.month + underflow;
underflow = 0;
// sub years
date1.year = date1.year - date2.year;
return date1;
}
//
// Compare two DateTimes
//
// returns < 0 if date1 is earlier than date2
// returns = 0 if date1 and date2 are the same
// returns > 0 if date1 is later than date2
//
int compareDateTime(struct DateTime date1, struct DateTime date2)
{
if (date1.year != date2.year)
return (date1.year - date2.year);
if (date1.month != date2.month)
return (date1.month - date2.month);
if (date1.day != date2.day)
return (date1.day - date2.day);
if (date1.hour != date2.hour)
return (date1.hour - date2.hour);
if (date1.minute != date2.minute)
return (date1.minute - date2.minute);
if (date1.second != date2.second)
return (date1.second - date2.second);
if (date1.millisecond != date2.millisecond)
return (date1.millisecond - date2.millisecond);
return 0;
}
//
// Return current DateTime
//
struct DateTime getCurrentDateTime()
{
struct DateTime now;
now.year = GetCalendarYear();
now.month = GetCalendarMonth();
now.day = GetCalendarDay();
now.hour = GetTimeHour();
now.minute = GetTimeMinute();
now.second = GetTimeSecond();
now.millisecond = GetTimeMillisecond();
return now;
}
//
// Create new DateTime with given values;
//
struct DateTime newDateTime(int year = 0, int month = 0, int day = 0, int hour = 0,
int minute = 0, int second = 0, int millisecond = 0)
{
struct DateTime newDate;
newDate.year = year;
newDate.month = month;
newDate.day = day;
newDate.hour = hour;
newDate.minute = minute;
newDate.second = second;
newDate.millisecond = millisecond;
return newDate;
}
//
// Set oObject's local DateTime variable to date
//
void SetLocalDateTime(object oObject, string sVarName, struct DateTime date)
{
SetLocalInt(oObject, sVarName + "year", date.year);
SetLocalInt(oObject, sVarName + "month", date.month);
SetLocalInt(oObject, sVarName + "day", date.day);
SetLocalInt(oObject, sVarName + "hour", date.hour);
SetLocalInt(oObject, sVarName + "minute", date.minute);
SetLocalInt(oObject, sVarName + "second", date.second);
SetLocalInt(oObject, sVarName + "millisecond", date.millisecond);
}
//
// Get oObject's local DateTime variable
//
struct DateTime GetLocalDateTime(object oObject, string sVarName)
{
struct DateTime date;
date.year = GetLocalInt(oObject, sVarName + "year");
date.month = GetLocalInt(oObject, sVarName + "month");
date.day = GetLocalInt(oObject, sVarName + "day");
date.hour = GetLocalInt(oObject, sVarName + "hour");
date.minute = GetLocalInt(oObject, sVarName + "minute");
date.second = GetLocalInt(oObject, sVarName + "second");
date.millisecond = GetLocalInt(oObject, sVarName + "millisecond");
return date;
}
//
// Set oObject's persistent DateTime variable to date
//
void SetPersistentDateTime(object oObject, string sVarName, struct DateTime date, int iExpiration =
0, string sScriptFile = "pwdata")
{
string sDateTime;
sDateTime = IntToString(date.year);
sDateTime += ":" + IntToString(date.month);
sDateTime += ":" + IntToString(date.day);
sDateTime += ":" + IntToString(date.hour);
sDateTime += ":" + IntToString(date.minute);
sDateTime += ":" + IntToString(date.second);
sDateTime += ":" + IntToString(date.millisecond);
SetPersistentString(oObject, sVarName, sDateTime, iExpiration, sScriptFile);
}
//
// Decode encoded DateTime String
// note: function calls itself only if sDateTime contains a ':'
// so an endless recursion could only happen when given a endless
// string sDateTime ;)
//
struct DateTime DecodeDateTimeRecursive(struct DateTime date, string sDateTime, int depth = 0)
{
int iDelimiterPos;
int iChars;
string subString;
iDelimiterPos = FindSubString(sDateTime, ":");
if (iDelimiterPos != -1)
{
iChars = GetStringLength(sDateTime) - iDelimiterPos - 1;
subString = GetStringRight(sDateTime, iChars);
date = DecodeDateTimeRecursive(date, subString, depth + 1);
sDateTime = GetStringLeft(sDateTime, iDelimiterPos);
}
switch (depth)
{
case 6:
date.millisecond = StringToInt(sDateTime);
break;
case 5:
date.second = StringToInt(sDateTime);
break;
case 4:
date.minute = StringToInt(sDateTime);
break;
case 3:
date.hour = StringToInt(sDateTime);
break;
case 2:
date.day = StringToInt(sDateTime);
break;
case 1:
date.month = StringToInt(sDateTime);
break;
case 0:
date.year = StringToInt(sDateTime);
break;
}
return date;
}
//
// Get oObject's persistent DateTime variable
//
struct DateTime GetPersistentDateTime(object oObject, string sVarName)
{
struct DateTime date;
string sDateTime;
sDateTime = GetPersistentString(oObject, sVarName);
date = DecodeDateTimeRecursive(date, sDateTime);
return date;
}
//
// Hour to string
//
string HourToString(struct DateTime date)
{
if (date.hour < 10)
return "0" + IntToString(date.hour);
else
return IntToString(date.hour);
}
//
// Minute to string
//
string MinuteToString(struct DateTime date)
{
if (date.minute < 10)
return "0" + IntToString(date.minute);
else
return IntToString(date.minute);
}
//
// Second to string
//
string SecondToString(struct DateTime date)
{
if (date.second < 10)
return "0" + IntToString(date.second);
else
return IntToString(date.second);
}
//
// Print DateTime for debugging purposes
// format: mm/dd/yyyy, hh:mm:ss:ms
//
void debugPrintDateTime(struct DateTime date)
{
SpeakString("DateTime: " + IntToString(date.month) + "/" +
IntToString(date.day) + "/" +
IntToString(date.year) + ", " +
HourToString(date) + ":" +
MinuteToString(date) + ":" +
SecondToString(date) + "(:" + IntToString(date.millisecond) + ")");
}
//
// Convert DateTime to String
// format: year:month:day:hour:minute:second:millisecond
//
string DateTimeToString(struct DateTime date)
{
string sDateTime;
sDateTime = IntToString(date.year);
sDateTime += ":" + IntToString(date.month);
sDateTime += ":" + IntToString(date.day);
sDateTime += ":" + IntToString(date.hour);
sDateTime += ":" + IntToString(date.minute);
sDateTime += ":" + IntToString(date.second);
sDateTime += ":" + IntToString(date.millisecond);
return sDateTime;
}
|
And then:
Code: |
// Name : avlis_onrest
// Purpose : Restrict player resting
// Author : Ingmar Stieger
// Modified : December 23, 2002
// Configuration START
int iUnrestrictedLevels = 2; // all levels up to 2 may rest as often as they like
int iRestMinHours = 4; // At least 4 hours must pass before resting is allowed again
// Configuration END
#include "datetime"
void main()
{
object oPC = GetLastPCRested();
if (!GetIsPC(oPC))
return;
// level restriction. Level 1+2 may rest as often as they want.
if (GetHitDice(oPC) <= iUnrestrictedLevels)
return;
struct DateTime dNow = getCurrentDateTime();
struct DateTime dLastRested = GetLocalDateTime(oPC, "last_rested_datetime");
struct DateTime dDelay = newDateTime(0,0,0,iRestMinHours);
struct DateTime dSoonest = addDateTime(dLastRested, dDelay);
switch (GetLastRestEventType())
{
case REST_EVENTTYPE_REST_STARTED:
if (compareDateTime(dNow, dSoonest) < 0)
{
SendMessageToPC(oPC, "You can rest only every "
+ IntToString(iRestMinHours) + " hours.");
SetLocalInt(oPC, "last_rest_allowed", FALSE);
AssignCommand(oPC,ClearAllActions());
}
else
SetLocalInt(oPC, "last_rest_allowed", TRUE);
break;
case REST_EVENTTYPE_REST_FINISHED:
SetLocalDateTime(oPC, "last_rested_datetime", getCurrentDateTime());
break;
case REST_EVENTTYPE_REST_CANCELLED:
if (GetLocalInt(oPC, "last_rest_allowed") == TRUE)
SetLocalDateTime(oPC, "last_rested_datetime", getCurrentDateTime());
break;
}
}
|
Of course, this is NWN1 code, so it might have to be modified for NWN2. _________________ Papillon |
|
Back to top |
|
|
Urlord
Joined: 17 Nov 2006 Posts: 122
|
Posted: Sun Jan 28, 2007 4:37 Post subject: |
|
|
I think this is a good segway for me to plug our Time and Date function Library. You can finde it on the vault - HERE.
We also have a List Function Library Here.
Sorry for the plugs - One was relavent and the other I couldn't resist. They really are great functions though - Try them. _________________ Jim (aka, Urlord)
Visit the Persistent World of Nymri |
|
Back to top |
|
|
Dracos
Joined: 16 Oct 2006 Posts: 21
|
Posted: Sun Jan 28, 2007 11:22 Post subject: |
|
|
WELL What can I say...
THANKS A LOT GUYS! |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|