Use sensible format of storing time spent as seconds instead of clunky awful date format in DB.

This commit is contained in:
UnknownShadow200 2017-05-12 09:44:05 +10:00
parent 254518b32c
commit 2c9441b9ed
8 changed files with 90 additions and 26 deletions

View File

@ -93,7 +93,7 @@ namespace MCGalaxy.Commands.Info {
info.TotalPlaced = data.TotalPlaced; info.TotalDeleted = data.TotalDeleted;
info.LoginBlocks = -1;
info.TimeSpent = data.TotalTime.ParseDBTime();
info.TimeSpent = data.TotalTime;
info.First = data.FirstLogin;
info.Last = data.LastLogin;
info.Logins = data.Logins; info.Kicks = data.Kicks;

View File

@ -16,6 +16,7 @@
permissions and limitations under the Licenses.
*/
using System;
using MCGalaxy.Eco;
namespace MCGalaxy.Commands.Info {
class WhoInfo {

View File

@ -15,10 +15,10 @@
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using System.Data;
using MCGalaxy.DB;
using MCGalaxy.SQL;
using System;
using System.Data;
using MCGalaxy.DB;
using MCGalaxy.SQL;
namespace MCGalaxy.Commands.Maintenance {
public sealed class CmdPlayerEdit : Command {
@ -102,7 +102,7 @@ namespace MCGalaxy.Commands.Maintenance {
SetInteger(p, args, PlayerData.ColumnKicked, 1000000000, who,
v => who.totalKicked = v, UpdateDB); break;
case "timespent":
SetTimespan(p, args, PlayerData.ColumnTimeSpent, who, v => who.time = v.ParseDBTime()); break;
SetTimespan(p, args, PlayerData.ColumnTimeSpent, who, v => who.time = v); break;
case "color":
SetColor(p, args, PlayerData.ColumnColor, who, v => who.color = (v == "" ? who.group.color : v)); break;
case "titlecolor":
@ -151,23 +151,23 @@ namespace MCGalaxy.Commands.Maintenance {
MessageDataChanged(p, args[0], args[1], args[2]);
}
static void SetTimespan(Player p, string[] args, string column, Player who, Action<string> setter) {
static void SetTimespan(Player p, string[] args, string column, Player who, Action<TimeSpan> setter) {
if (args.Length < 3) {
Player.Message(p, "Timespan must be in the format: <number><quantifier>..");
Player.Message(p, CommandParser.TimespanHelp, "set time spent to");
return;
}
TimeSpan timeFrame = TimeSpan.Zero;
if (!CommandParser.GetTimespan(p, args[2], ref timeFrame, "set time spent to", 'm')) return;
TimeSpan span = TimeSpan.Zero;
if (!CommandParser.GetTimespan(p, args[2], ref span, "set time spent to", 'm')) return;
string time = timeFrame.ToDBTime();
if (who != null) {
setter(time);
setter(span);
} else {
UpdateDB(args[0], time, column);
long secs = (long)span.TotalSeconds;
UpdateDB(args[0], secs.ToString(), column);
}
MessageDataChanged(p, args[0], args[1], timeFrame.Shorten(true));
MessageDataChanged(p, args[0], args[1], span.Shorten(true));
}
static void SetInteger(Player p, string[] args, string column, int max, Player who,

View File

@ -20,8 +20,8 @@ using System.Data;
using MCGalaxy.SQL;
namespace MCGalaxy.DB {
/// <summary> Retrieves or sets player stats in the database. </summary>
/// <summary> Retrieves or sets player stats in the database. </summary>
public class PlayerData {
public const string DBTable = "Players";
@ -40,11 +40,12 @@ namespace MCGalaxy.DB {
public const string ColumnTotalBlocks = "totalBlocks";
public const string ColumnTotalCuboided = "totalCuboided";
public string Name, Color, Title, TitleColor, TotalTime, IP;
public string Name, Color, Title, TitleColor, IP;
public DateTime FirstLogin, LastLogin;
public int UserID, Money, Deaths, Logins, Kicks;
public long TotalModified, TotalDrawn, TotalPlaced, TotalDeleted;
public TimeSpan TotalTime;
internal static void Create(Player p) {
p.prefix = "";
@ -64,7 +65,7 @@ namespace MCGalaxy.DB {
Database.Backend.AddRow(DBTable, "Name, IP, FirstLogin, LastLogin, totalLogin, Title, " +
"totalDeaths, Money, totalBlocks, totalKicked, TimeSpent",
p.name, p.ip, now, now, 1, "", 0, 0, 0, 0, p.time.ToDBTime());
p.name, p.ip, now, now, 1, "", 0, 0, 0, 0, (long)p.time.TotalSeconds);
using (DataTable ids = Database.Backend.GetRows(DBTable,
"ID", "WHERE Name = @0", p.name)) {
@ -80,7 +81,7 @@ namespace MCGalaxy.DB {
internal static void Load(DataTable playerDb, Player p) {
PlayerData data = PlayerData.Fill(playerDb.Rows[0]);
p.totalLogins = data.Logins + 1;
p.time = data.TotalTime.ParseDBTime();
p.time = data.TotalTime;
p.UserID = data.UserID;
p.firstLogin = data.FirstLogin;
p.lastLogin = data.LastLogin;
@ -106,7 +107,12 @@ namespace MCGalaxy.DB {
data.IP = row["IP"].ToString().Trim();
data.UserID = ParseInt(row["ID"].ToString());
data.TotalTime = row[ColumnTimeSpent].ToString();
try {
long secs = PlayerData.ParseLong(row[ColumnTimeSpent].ToString());
data.TotalTime = TimeSpan.FromSeconds(secs);
} catch {
data.TotalTime = row[ColumnTimeSpent].ToString().ParseDBTime();
}
data.FirstLogin = DateTime.Parse(row[ColumnFirstLogin].ToString());
data.LastLogin = DateTime.Parse(row[ColumnLastLogin].ToString());

View File

@ -144,7 +144,7 @@ namespace MCGalaxy {
"totalBlocks=@5, totalCuboided=@6, totalKicked=@7, TimeSpent=@8", "WHERE Name=@9",
ip, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
totalLogins, overallDeath, money, blocks,
cuboided, totalKicked, time.ToDBTime(), name);
cuboided, totalKicked, (long)time.TotalSeconds, name);
Server.zombie.SaveZombieStats(this);
}

View File

@ -116,7 +116,8 @@ namespace MCGalaxy {
Background.QueueOnce(LoadAutoloadMaps);
Background.QueueOnce(UpgradeTasks.MovePreviousLevelFiles);
Background.QueueOnce(UpgradeTasks.UpgradeOldLockdown);
Background.QueueOnce(UpgradeTasks.UpgradeDBTimeSpent);
Background.QueueOnce(SetupSocket);
Background.QueueOnce(InitTimers);
Background.QueueOnce(InitRest);

View File

@ -23,6 +23,10 @@ using System.Threading;
using MCGalaxy.Commands.World;
using MCGalaxy.Games;
using MCGalaxy.Generator;
using MCGalaxy.DB;
using System.Data;
using System.Data.Common;
using MCGalaxy.SQL;
namespace MCGalaxy.Tasks {
internal static class UpgradeTasks {
@ -146,5 +150,61 @@ namespace MCGalaxy.Tasks {
Server.lockdown.Save();
Directory.Delete("text/lockdown/map");
}
internal static void UpgradeDBTimeSpent() {
DataTable table = Database.Backend.GetRows(PlayerData.DBTable, "TimeSpent", "LIMIT 1");
if (table.Rows.Count == 0) return; // no players
string time = table.Rows[0]["TimeSpent"].ToString();
if (time.IndexOf(' ') == -1) return; // already upgraded
Server.s.Log("Upgrading TimeSpent column in database to new format..");
DumpPlayerTimeSpents();
UpgradePlayerTimeSpents();
Server.s.Log("Upgraded " + playerCount + " rows. (" + playerFailed + " rows failed)");
}
static List<int> playerIds;
static List<long> playerSeconds;
static int playerCount, playerFailed = 0;
static void DumpPlayerTimeSpents() {
playerIds = new List<int>();
playerSeconds = new List<long>();
Database.ExecuteReader("SELECT ID, TimeSpent FROM Players", AddPlayerTimeSpent);
}
static void AddPlayerTimeSpent(IDataReader reader) {
playerCount++;
try {
int id = reader.GetInt32(0);
TimeSpan span = reader.GetString(1).ParseDBTime();
playerIds.Add(id);
playerSeconds.Add((long)span.TotalSeconds);
} catch {
playerFailed++;
}
}
static void UpgradePlayerTimeSpents() {
using (BulkTransaction bulk = Database.Backend.CreateBulk()) {
IDataParameter idParam = bulk.CreateParam("@0", DbType.Int32);
IDataParameter secsParam = bulk.CreateParam("@1", DbType.Int64);
IDbCommand cmd = bulk.CreateCommand("UPDATE Players SET TimeSpent = @1 WHERE ID = @0");
cmd.Parameters.Add(idParam);
cmd.Parameters.Add(secsParam);
for (int i = 0; i < playerIds.Count; i++) {
idParam.Value = playerIds[i];
secsParam.Value = playerSeconds[i];
cmd.ExecuteNonQuery();
}
bulk.Commit();
}
}
}
}

View File

@ -21,10 +21,6 @@ using System.Collections.Generic;
namespace MCGalaxy {
public static class DateExts {
public static string ToDBTime(this TimeSpan value) {
return value.Days + " " + value.Hours + " " + value.Minutes + " " + value.Seconds;
}
public static TimeSpan ParseDBTime(this string value) {
string[] parts = value.SplitSpaces();
return new TimeSpan(int.Parse(parts[0]), int.Parse(parts[1]),