diff --git a/MCGalaxy/Commands/Chat/CmdSend.cs b/MCGalaxy/Commands/Chat/CmdSend.cs
index eaa89881b..01e2143ca 100644
--- a/MCGalaxy/Commands/Chat/CmdSend.cs
+++ b/MCGalaxy/Commands/Chat/CmdSend.cs
@@ -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);
diff --git a/MCGalaxy/Commands/Information/CmdOpStats.cs b/MCGalaxy/Commands/Information/CmdOpStats.cs
index 47ef59c84..30b1acb1c 100644
--- a/MCGalaxy/Commands/Information/CmdOpStats.cs
+++ b/MCGalaxy/Commands/Information/CmdOpStats.cs
@@ -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();
diff --git a/MCGalaxy/Commands/Maintenance/CmdPlayerEdit.cs b/MCGalaxy/Commands/Maintenance/CmdPlayerEdit.cs
index f06f518da..e713a156c 100644
--- a/MCGalaxy/Commands/Maintenance/CmdPlayerEdit.cs
+++ b/MCGalaxy/Commands/Maintenance/CmdPlayerEdit.cs
@@ -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]);
}
diff --git a/MCGalaxy/Database/Backends/MySQL.cs b/MCGalaxy/Database/Backends/MySQL.cs
index 15b5d28ce..0873ee62c 100644
--- a/MCGalaxy/Database/Backends/MySQL.cs
+++ b/MCGalaxy/Database/Backends/MySQL.cs
@@ -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) {
diff --git a/MCGalaxy/Database/Database.cs b/MCGalaxy/Database/Database.cs
index f6d3b0f6c..5ab0a3eb5 100644
--- a/MCGalaxy/Database/Database.cs
+++ b/MCGalaxy/Database/Database.cs
@@ -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";
/// Counts rows in the given table.
/// Optional SQL to filter which rows are counted.
@@ -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);
}
}
diff --git a/MCGalaxy/Database/PlayerData.cs b/MCGalaxy/Database/PlayerData.cs
index 0ee90a28f..7b68bce79 100644
--- a/MCGalaxy/Database/PlayerData.cs
+++ b/MCGalaxy/Database/PlayerData.cs
@@ -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;
}
}
diff --git a/MCGalaxy/Modules/Relay/Discord/DiscordWebsocket.cs b/MCGalaxy/Modules/Relay/Discord/DiscordWebsocket.cs
index 6919b8704..461cdacf9 100644
--- a/MCGalaxy/Modules/Relay/Discord/DiscordWebsocket.cs
+++ b/MCGalaxy/Modules/Relay/Discord/DiscordWebsocket.cs
@@ -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);
diff --git a/MCGalaxy/Player/Player.Handlers.cs b/MCGalaxy/Player/Player.Handlers.cs
index 52317ff5d..3fd40f639 100644
--- a/MCGalaxy/Player/Player.Handlers.cs
+++ b/MCGalaxy/Player/Player.Handlers.cs
@@ -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 { }
diff --git a/MCGalaxy/Player/Player.cs b/MCGalaxy/Player/Player.cs
index d392b47f8..1ef01e244 100644
--- a/MCGalaxy/Player/Player.cs
+++ b/MCGalaxy/Player/Player.cs
@@ -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);
}
diff --git a/MCGalaxy/Player/PlayerActions.cs b/MCGalaxy/Player/PlayerActions.cs
index 4b67b3969..8b4c1404f 100644
--- a/MCGalaxy/Player/PlayerActions.cs
+++ b/MCGalaxy/Player/PlayerActions.cs
@@ -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);
diff --git a/MCGalaxy/util/Extensions/DateExts.cs b/MCGalaxy/util/Extensions/DateExts.cs
index 654eb4178..4eb6664fe 100644
--- a/MCGalaxy/util/Extensions/DateExts.cs
+++ b/MCGalaxy/util/Extensions/DateExts.cs
@@ -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);
+ }
}
}