fix: use more robust parsing of large timespans
This commit is contained in:
parent
07becc3c8f
commit
7e381d61f6
2 changed files with 79 additions and 3 deletions
|
|
@ -1512,7 +1512,7 @@ namespace TShockAPI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TShock.Utils.TryParseTime(duration, out int seconds))
|
if (TShock.Utils.TryParseTime(duration, out ulong seconds))
|
||||||
{
|
{
|
||||||
expiration = DateTime.UtcNow.AddSeconds(seconds);
|
expiration = DateTime.UtcNow.AddSeconds(seconds);
|
||||||
}
|
}
|
||||||
|
|
@ -1880,7 +1880,7 @@ namespace TShockAPI
|
||||||
|
|
||||||
if (args.Parameters.Count > 2)
|
if (args.Parameters.Count > 2)
|
||||||
{
|
{
|
||||||
int time;
|
ulong time;
|
||||||
if (!TShock.Utils.TryParseTime(args.Parameters[2], out time))
|
if (!TShock.Utils.TryParseTime(args.Parameters[2], out time))
|
||||||
{
|
{
|
||||||
args.Player.SendErrorMessage("Invalid time string! Proper format: _d_h_m_s, with at least one time specifier.");
|
args.Player.SendErrorMessage("Invalid time string! Proper format: _d_h_m_s, with at least one time specifier.");
|
||||||
|
|
@ -1888,7 +1888,7 @@ namespace TShockAPI
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ply[0].tempGroupTimer = new System.Timers.Timer(time * 1000);
|
ply[0].tempGroupTimer = new System.Timers.Timer(time * 1000d);
|
||||||
ply[0].tempGroupTimer.Elapsed += ply[0].TempGroupTimerElapsed;
|
ply[0].tempGroupTimer.Elapsed += ply[0].TempGroupTimerElapsed;
|
||||||
ply[0].tempGroupTimer.Start();
|
ply[0].tempGroupTimer.Start();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -607,6 +607,82 @@ namespace TShockAPI
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to parse a string as a positive timespan (_d_m_h_s).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="str">The time string.</param>
|
||||||
|
/// <param name="seconds">The seconds.</param>
|
||||||
|
/// <returns>Whether the string was parsed successfully.</returns>
|
||||||
|
public bool TryParseTime(string str, out ulong seconds)
|
||||||
|
{
|
||||||
|
seconds = 0;
|
||||||
|
|
||||||
|
if (string.IsNullOrWhiteSpace(str))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var sb = new StringBuilder(3);
|
||||||
|
for (int i = 0; i < str.Length; i++)
|
||||||
|
{
|
||||||
|
if (char.IsDigit(str[i]) || (str[i] == '-' || str[i] == '+' || str[i] == ' '))
|
||||||
|
sb.Append(str[i]);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
if (!int.TryParse(sb.ToString().Trim(' '), out num))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
sb.Clear();
|
||||||
|
|
||||||
|
if (num == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int numSeconds;
|
||||||
|
switch (str[i])
|
||||||
|
{
|
||||||
|
case 's':
|
||||||
|
numSeconds = num;
|
||||||
|
break;
|
||||||
|
case 'm':
|
||||||
|
numSeconds = num * 60;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
numSeconds = num * 60 * 60;
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
numSeconds = num * 60 * 60 * 24;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numSeconds > 0)
|
||||||
|
{
|
||||||
|
if (ulong.MaxValue - seconds < (uint)numSeconds)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
seconds += (uint)numSeconds;
|
||||||
|
}
|
||||||
|
else if (seconds >= (uint)Math.Abs(numSeconds))
|
||||||
|
{
|
||||||
|
seconds -= (uint)Math.Abs(numSeconds);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sb.Length != 0)
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Searches for a projectile by identity and owner
|
/// Searches for a projectile by identity and owner
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue