Try to fix issue where time component of dates saved to the DB was being saved/loaded with culture specific time separator instead of : (Thanks Fam0r)

This commit is contained in:
UnknownShadow200 2024-03-12 19:01:01 +11:00
parent 82ba8b5054
commit 0fd9dd802b
11 changed files with 44 additions and 30 deletions

View File

@ -54,7 +54,7 @@ namespace MCGalaxy.Commands.Chatting
}
Database.AddRow("Inbox" + name, "PlayerFrom, TimeSent, Contents",
p.name, DateTime.Now.ToString(Database.DateFormat), message);
p.name, DateTime.Now.ToInvariantDateString(), message);
p.CheckForMessageSpam();
Player target = PlayerInfo.FindExact(name);

View File

@ -30,7 +30,7 @@ namespace MCGalaxy.Commands.Info
public override bool UseableWhenFrozen { get { return true; } }
public override void Use(Player p, string message, CommandData data) {
string end = DateTime.Now.ToString(Database.DateFormat);
string end = DateTime.Now.ToInvariantDateString();
string start = "thismonth", name = null;
string[] args = message.SplitSpaces();

View File

@ -146,13 +146,13 @@ namespace MCGalaxy.Commands.Maintenance {
return;
}
DateTime date;
if (!DateTime.TryParseExact(args[2], Database.DateFormat, null, 0, out date)) {
DateTime dt;
if (!args[2].TryParseInvariantDateString(out dt)) {
p.Message("Invalid date. It must be in format: " + Database.DateFormat);
return;
}
if (who != null) setter(date);
if (who != null) setter(dt);
PlayerDB.Update(args[0], column, args[2]);
MessageDataChanged(p, args[0], args[1], args[2]);
}

View File

@ -241,7 +241,7 @@ namespace MCGalaxy.SQL
string RawGetDateTime(int col) {
DateTime date = GetDateTime(col);
return date.ToString(Database.DateFormat);
return date.ToInvariantDateString();
}
public override string GetStringValue(int col) {

View File

@ -27,7 +27,7 @@ namespace MCGalaxy.SQL
public static class Database
{
public static IDatabaseBackend Backend;
public const string DateFormat = "yyyy-MM-dd HH:mm:ss";
public const string DateFormat = "yyyy-MM-dd HH:mm:ss";
/// <summary> Counts rows in the given table. </summary>
/// <param name="modifier"> Optional SQL to filter which rows are counted. </param>
@ -244,9 +244,10 @@ namespace MCGalaxy.SQL
}
public static DateTime ParseDBDate(string value) {
DateTime date;
DateTime dt;
// prefer the exact format
if (DateTime.TryParseExact(value, DateFormat, null, 0, out date)) return date;
if (value.TryParseInvariantDateString(out dt)) return dt;
return DateTime.Parse(value);
}
}

View File

@ -56,7 +56,7 @@ namespace MCGalaxy.DB
p.FirstLogin = DateTime.Now;
p.TimesVisited = 1;
string now = DateTime.Now.ToString(Database.DateFormat);
string now = DateTime.Now.ToInvariantDateString();
Database.AddRow("Players", "Name, IP, FirstLogin, LastLogin, totalLogin, Title, " +
"totalDeaths, Money, totalBlocks, totalKicked, Messages, TimeSpent",
p.name, p.ip, now, now, 1, "", 0, 0, 0, 0, 0, (long)p.TotalTime.TotalSeconds);
@ -155,17 +155,17 @@ namespace MCGalaxy.DB
static DateTime ParseDateTime(ISqlRecord record, string name) {
int i = record.GetOrdinal(name);
DateTime dt;
// dates are a major pain
string raw = record.GetStringValue(i);
if (raw.TryParseInvariantDateString(out dt)) return dt;
try {
string raw = record.GetStringValue(i);
return DateTime.ParseExact(raw, Database.DateFormat, null);
} catch {
try {
return record.GetDateTime(i);
} catch (Exception ex) {
Logger.LogError("Error parsing date", ex);
return DateTime.MinValue;
}
return record.GetDateTime(i);
} catch (Exception ex) {
Logger.LogError("Error parsing date", ex);
return DateTime.MinValue;
}
}

View File

@ -202,11 +202,11 @@ namespace MCGalaxy.Modules.Relay.Discord
if (obj.TryGetValue("s", out sequence))
Session.LastSeq = (string)sequence;
string eventName = (string)obj["t"];
object rawData;
string eventName = (string)obj["t"];
object rawData;
obj.TryGetValue("d", out rawData);
JsonObject data = (JsonObject)rawData;
JsonObject data = rawData as JsonObject;
if (eventName == "READY") {
HandleReady(data);

View File

@ -665,7 +665,7 @@ namespace MCGalaxy
try { //opstats patch (since 5.5.11)
if (Server.Opstats.CaselessContains(cmd) || (cmd.CaselessEq("review") && args.CaselessEq("next") && Server.reviewlist.Count > 0)) {
Database.AddRow("Opstats", "Time, Name, Cmd, Cmdmsg",
DateTime.Now.ToString(Database.DateFormat), name, cmd, args);
DateTime.Now.ToInvariantDateString(), name, cmd, args);
}
} catch { }

View File

@ -182,7 +182,7 @@ namespace MCGalaxy {
long drawn = PlayerData.Pack(TotalDeleted, TotalDrawn);
Database.UpdateRows("Players", "IP=@0, LastLogin=@1, totalLogin=@2, totalDeaths=@3, Money=@4, " +
"totalBlocks=@5, totalCuboided=@6, totalKicked=@7, TimeSpent=@8, Messages=@9", "WHERE Name=@10",
ip, LastLogin.ToString(Database.DateFormat),
ip, LastLogin.ToInvariantDateString(),
TimesVisited, TimesDied, money, blocks,
drawn, TimesBeenKicked, (long)TotalTime.TotalSeconds, TotalMessagesSent, name);
}

View File

@ -36,7 +36,7 @@ namespace MCGalaxy
bool didJoin = false;
try {
didJoin = name == null ? GotoLevel(p, lvl) : GotoMap(p, name);
didJoin = name == null ? GotoLevel(p, lvl, false) : GotoMap(p, name);
} finally {
Interlocked.Exchange(ref p.UsingGoto, 0);
Server.DoGC();
@ -50,14 +50,14 @@ namespace MCGalaxy
static bool GotoMap(Player p, string name) {
Level lvl = LevelInfo.FindExact(name);
if (lvl != null) return GotoLevel(p, lvl);
if (lvl != null) return GotoLevel(p, lvl, false);
if (Server.Config.AutoLoadMaps) {
string map = Matcher.FindMaps(p, name);
if (map == null) return false;
lvl = LevelInfo.FindExact(map);
if (lvl != null) return GotoLevel(p, lvl);
if (lvl != null) return GotoLevel(p, lvl, false);
return LoadOfflineLevel(p, map);
} else {
lvl = Matcher.FindLevels(p, name);
@ -66,7 +66,7 @@ namespace MCGalaxy
Command.Find("Search").Use(p, "levels " + name);
return false;
}
return GotoLevel(p, lvl);
return GotoLevel(p, lvl, false);
}
}
@ -87,13 +87,13 @@ namespace MCGalaxy
LevelActions.Load(p, map, false);
Level lvl = LevelInfo.FindExact(map);
if (lvl != null) return GotoLevel(p, lvl);
if (lvl != null) return GotoLevel(p, lvl, true);
p.Message("Level \"{0}\" failed to be auto-loaded.", map);
return false;
}
static bool GotoLevel(Player p, Level lvl) {
static bool GotoLevel(Player p, Level lvl, bool autoloaded) {
if (p.level == lvl) { p.Message("You are already in {0}&S.", lvl.ColoredName); return false; }
bool canJoin = lvl.CanJoin(p);

View File

@ -46,5 +46,18 @@ namespace MCGalaxy
TimeSpan oldestDelta = now - log[0];
return oldestDelta > checkInterval;
}
// Can't just use HH:mm:ss, as e.g. Finnish converts : to .
// https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings#timeSeparator
const string INVARIANT_DATE_FORMAT = "yyyy-MM-dd HH':'mm':'ss";
public static string ToInvariantDateString(this DateTime time) {
return time.ToString(INVARIANT_DATE_FORMAT);
}
public static bool TryParseInvariantDateString(this string str, out DateTime dt) {
return DateTime.TryParseExact(str, INVARIANT_DATE_FORMAT, null, 0, out dt);
}
}
}