Support timespans in /undo and /highlight.

This commit is contained in:
UnknownShadow200 2016-08-29 17:44:00 +10:00
parent 4738e7d83f
commit 7bb22c4c69
11 changed files with 82 additions and 75 deletions

View File

@ -84,7 +84,7 @@ namespace MCGalaxy.Commands {
static void Output(Player p, string user, byte block, bool deleted, TimeSpan delta) {
string bName = Block.Name(block);
Player.Message(p, "{0} ago {1} {2}",
Player.Message(p, "{0} ago {1} {2}",
delta.Shorten(true, false), PlayerInfo.GetColoredName(p, user),
deleted ? "&4deleted%S (using " + bName + ")" : "&3placed%S " + bName);
}

View File

@ -32,26 +32,22 @@ namespace MCGalaxy.Commands {
public CmdHighlight() { }
public override void Use(Player p, string message) {
long seconds;
TimeSpan delta;
bool found = false;
if (Player.IsSuper(p)) { MessageInGameOnly(p); return; }
if (message == "") message = p.name + " 1800";
string[] args = message.Split(' ');
string name = args[0];
if (args.Length >= 2) {
if (!long.TryParse(args[1], out seconds)) {
Player.Message(p, "Invalid seconds."); return;
}
} else if (long.TryParse(args[0], out seconds)) {
if (!args[1].TryParseShort(p, 's', "highlight the past", out delta)) return;
} else if (ParseTimespan(args[0], out delta)) {
args[0] = p.name;
} else {
seconds = 30 * 60;
delta = TimeSpan.FromMinutes(30);
}
if (seconds <= 0) seconds = 30 * 60;
DateTime start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
Player who = PlayerInfo.Find(name);
DateTime start = DateTime.UtcNow.Subtract(delta);
Player who = PlayerInfo.Find(args[0]);
bool done = false;
if (who != null) {
found = true;
@ -60,17 +56,25 @@ namespace MCGalaxy.Commands {
done = HighlightBlocks(p, start, cache);
}
}
if (!done) UndoFormat.DoHighlight(p, name.ToLower(), start, ref found);
if (!done) UndoFormat.DoHighlight(p, args[0].ToLower(), start, ref found);
if (found) {
Player.Message(p, "Now highlighting &b{0} %Sseconds for {1}",
seconds, PlayerInfo.GetColoredName(p, name));
Player.Message(p, "Now highlighting past &b{0} %Sfor {1}",
delta.Shorten(), PlayerInfo.GetColoredName(p, args[0]));
Player.Message(p, "&cUse /reload to un-highlight");
} else {
Player.Message(p, "Could not find player specified.");
}
}
static bool ParseTimespan(string input, out TimeSpan delta) {
delta = TimeSpan.Zero;
try { delta = input.ParseShort('s'); return true;
} catch (ArgumentException) { return false;
} catch (FormatException) { return false;
}
}
static bool HighlightBlocks(Player p, DateTime start, UndoCache cache) {
UndoFormatArgs args = new UndoFormatArgs(p, start);
UndoFormat format = new UndoFormatOnline(cache);
@ -79,10 +83,11 @@ namespace MCGalaxy.Commands {
}
public override void Help(Player p) {
Player.Message(p, "%T/highlight [player] [seconds]");
Player.Message(p, "%HHighlights blocks modified by [player] in the last [seconds]");
Player.Message(p, "%HIf no [seconds] is given, highlights for last 30 minutes");
Player.Message(p, "&c/highlight cannot be disabled, you must use /reload to un-highlight");
Player.Message(p, "%T/highlight [player] <timespan>");
Player.Message(p, "%HHighlights blocks modified by [player] in the past <timespan>");
Player.Message(p, "%H e.g. to highlight for 90 minutes, <timespan> would be %S1h30m");
Player.Message(p, "%HIf <timespan> is not given, highlights for last 30 minutes");
Player.Message(p, "&c/highlight cannot be disabled, use /reload to un-highlight");
}
}
}

View File

@ -70,7 +70,7 @@ namespace MCGalaxy.Commands.Moderation {
public override void Help(Player p) {
Player.Message(p, "%T/tempban [name] [timespan] <reason>");
Player.Message(p, "%HBans [name] for [timespan]. Max is 1 day, default is 1 hour.");
Player.Message(p, "%H e.g. to tempban for 90 minutes, [timespan] would be 1h30m");
Player.Message(p, "%H e.g. to tempban for 90 minutes, [timespan] would be %S1h30m");
Player.Message(p, "%HTemp bans will reset on server restart");
Player.Message(p, "%HFor <reason>, @number can be used as a shortcut for that rule.");
}

View File

@ -159,7 +159,7 @@ namespace MCGalaxy.Commands.Moderation {
public override void Help(Player p) {
Player.Message(p, "%T/temprank [player] [rank] [timespan]");
Player.Message(p, "%HSets a temporary rank for the specified player.");
Player.Message(p, "%H e.g. to temprank for 90 minutes, [timespan] would be 1h30m");
Player.Message(p, "%H e.g. to temprank for 90 minutes, [timespan] would be %S1h30m");
Player.Message(p, "%T/temprank [player] info");
Player.Message(p, "%HLists information about the temp rank for the given player.");
Player.Message(p, "%T/temprank <player> delete %H- Removes player's temp rank.");

View File

@ -35,7 +35,8 @@ namespace MCGalaxy.Commands {
string[] parts = message.Split(' ');
args.message = parts[0];
args.seconds = CmdUndo.GetSeconds(p, null, parts.Length > 1 ? parts[1] : "30");
args.delta = CmdUndo.GetDelta(p, null, parts.Length > 1 ? parts[1] : "30");
if (args.delta == TimeSpan.MinValue) return;
Player.Message(p, "Place two blocks to determine the edges.");
p.MakeSelection(2, args, DoUndo);
@ -56,13 +57,13 @@ namespace MCGalaxy.Commands {
}
UndoOnlineDrawOp op = new UndoOnlineDrawOp();
op.Start = DateTime.UtcNow.AddTicks(-args.seconds * TimeSpan.TicksPerSecond);
op.Start = DateTime.UtcNow.Subtract(args.delta);
op.who = who;
DrawOp.DoDrawOp(op, null, p, marks);
Player.SendChatFrom(who, who.ColoredName +
"%S's actions for the past &b" + args.seconds + " seconds were undone.", false);
Server.s.Log(who.name + "'s actions for the past " + args.seconds + " seconds were undone.");
"%S's actions for the past &b" + args.delta.Shorten() + " %Swere undone.", false);
Server.s.Log(who.name + "'s actions for the past " + args.delta.Shorten() + " were undone.");
}
void UndoOfflinePlayer(Player p, string whoName, UndoArgs args, Vec3S32[] marks) {
@ -72,21 +73,21 @@ namespace MCGalaxy.Commands {
}
UndoOfflineDrawOp op = new UndoOfflineDrawOp();
op.Start = DateTime.UtcNow.AddTicks(-args.seconds * TimeSpan.TicksPerSecond);
op.Start = DateTime.UtcNow.Subtract(args.delta);
op.whoName = whoName;
DrawOp.DoDrawOp(op, null, p, marks);
if (op.found) {
Chat.MessageAll("{0}{1}%S's actions for the past &b{2} %Sseconds were undone.",
group.color, whoName, args.seconds);
Server.s.Log(whoName + "'s actions for the past " + args.seconds + " seconds were undone.");
Chat.MessageAll("{0}{1}%S's actions for the past &b{2} %Swere undone.",
group.color, whoName, args.delta.Shorten());
Server.s.Log(whoName + "'s actions for the past " + args.delta.Shorten() + " were undone.");
p.level.Save(true);
} else {
Player.Message(p, "Could not find player specified.");
}
}
struct UndoArgs { public string message; public long seconds; }
struct UndoArgs { public string message; public TimeSpan delta; }
public override void Help(Player p) {
Player.Message(p, "%T/undoarea [player] [seconds]");

View File

@ -48,7 +48,8 @@ namespace MCGalaxy.Commands.Building {
string[] parts = message.Split(' ');
bool undoPhysics = parts[0].CaselessEq("physics");
Player who = undoPhysics ? null : PlayerInfo.Find(parts[0]);
long seconds = GetSeconds(p, who, parts.Length > 1 ? parts[1] : "30");
TimeSpan delta = GetDelta(p, who, parts.Length > 1 ? parts[1] : "30");
if (delta == TimeSpan.MinValue) return;
if (parts.Length > 1 && parts[1].CaselessEq("update")) {
UndoFormat.UpgradePlayerUndoFiles(parts[0]);
@ -57,29 +58,33 @@ namespace MCGalaxy.Commands.Building {
}
if (who != null)
UndoOnlinePlayer(p, seconds, who);
UndoOnlinePlayer(p, delta, who);
else if (undoPhysics)
UndoLevelPhysics(p, seconds);
UndoLevelPhysics(p, delta);
else
UndoOfflinePlayer(p, seconds, parts[0]);
UndoOfflinePlayer(p, delta, parts[0]);
}
const int undoMax = -1; // allows everything to be undone.
internal static long GetSeconds(Player p, Player who, string param) {
long secs;
internal static TimeSpan GetDelta(Player p, Player who, string param) {
TimeSpan delta;
bool canAll = p == null || p == who || p.group.maxUndo == undoMax;
if (param.CaselessEq("all")) {
secs = (p == null || p.group.maxUndo == undoMax || p == who) ? int.MaxValue : p.group.maxUndo;
} else if (!long.TryParse(param, out secs)) {
Player.Message(p, "Invalid seconds, using 30 seconds.");
return 30;
return TimeSpan.FromSeconds(canAll ? int.MaxValue : p.group.maxUndo);
} else if (!param.TryParseShort(p, 's', "undo the past", out delta)) {
Player.Message(p, "Undoing for 30 seconds.");
return TimeSpan.MinValue;
}
if (secs == 0) secs = 5400;
if (p != null && p != who && p.group.maxUndo != undoMax && secs > p.group.maxUndo) {
Player.Message(p, p.group.name + "s may only undo up to " + p.group.maxUndo + " seconds.");
return p.group.maxUndo;
if (delta.TotalSeconds == 0)
delta = TimeSpan.FromMinutes(90);
if (!canAll && delta.TotalSeconds > p.group.maxUndo) {
Player.Message(p, "{0}%Ss may only undo up to {1} seconds.",
p.group.ColoredName, p.group.maxUndo);
return TimeSpan.FromSeconds(p.group.maxUndo);
}
return secs;
return delta;
}
void UndoSelf(Player p) {
@ -108,36 +113,36 @@ namespace MCGalaxy.Commands.Building {
Player.Message(p, "Try using %T/undo <seconds> %Sinstead.");
}
void UndoOnlinePlayer(Player p, long seconds, Player who) {
void UndoOnlinePlayer(Player p, TimeSpan delta, Player who) {
if (p != null && p != who && !CheckUndoPerms(p, who.group)) return;
UndoOnlineDrawOp op;
if (p == who) op = new UndoSelfDrawOp();
else op = new UndoOnlineDrawOp();
op.Start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
op.Start = DateTime.UtcNow.Subtract(delta);
op.who = who;
DrawOp.DoDrawOp(op, null, p, new Vec3S32[] { Vec3U16.MaxVal, Vec3U16.MaxVal } );
if (p == who) {
Player.Message(p, "Undid your actions for the past &b" + seconds + " %Sseconds.");
Player.Message(p, "Undid your actions for the past &b" + delta.Shorten() + "%S.");
} else {
Player.SendChatFrom(who, who.ColoredName + "%S's actions for the past &b" + seconds + " seconds were undone.", false);
Player.SendChatFrom(who, who.ColoredName + "%S's actions for the past &b" + delta.Shorten() + " %Swere undone.", false);
}
Server.s.Log(who.name + "'s actions for the past " + seconds + " seconds were undone.");
Server.s.Log(who.name + "'s actions for the past " + delta.Shorten() + " were undone.");
}
void UndoOfflinePlayer(Player p, long seconds, string whoName) {
void UndoOfflinePlayer(Player p, TimeSpan delta, string whoName) {
if (p != null && !CheckUndoPerms(p, Group.findPlayerGroup(whoName))) return;
UndoOfflineDrawOp op = new UndoOfflineDrawOp();
op.Start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
op.Start = DateTime.UtcNow.Subtract(delta);
op.whoName = whoName;
DrawOp.DoDrawOp(op, null, p, new Vec3S32[] { Vec3U16.MaxVal, Vec3U16.MaxVal } );
if (op.found) {
Chat.MessageAll("{0}%S's actions for the past &b{1} %Sseconds were undone.",
PlayerInfo.GetColoredName(p, whoName), seconds);
Server.s.Log(whoName + "'s actions for the past " + seconds + " seconds were undone.");
Chat.MessageAll("{0}%S's actions for the past &b{1} %S were undone.",
PlayerInfo.GetColoredName(p, whoName), delta.Shorten());
Server.s.Log(whoName + "'s actions for the past " + delta.Shorten() + " were undone.");
if (p != null) p.level.Save(true);
} else {
Player.Message(p, "Could not find player specified.");
@ -150,18 +155,18 @@ namespace MCGalaxy.Commands.Building {
return true;
}
void UndoLevelPhysics(Player p, long seconds) {
void UndoLevelPhysics(Player p, TimeSpan delta) {
if (!CheckExtraPerm(p, 2)) { MessageNeedExtra(p, "undo physics.", 2); return; }
if (p != null && !p.group.CanExecute("physics")) {
Player.Message(p, "You can only undo physics if you can use /physics."); return;
}
CmdPhysics.SetPhysics(p.level, 0);
UndoPhysicsDrawOp op = new UndoPhysicsDrawOp();
op.seconds = seconds;
op.Start = DateTime.UtcNow.Subtract(delta);
DrawOp.DoDrawOp(op, null, p, new Vec3S32[] { Vec3U16.MaxVal, Vec3U16.MaxVal } );
Chat.MessageAll("Physics were undone &b{0} %Sseconds", seconds);
Server.s.Log( "Physics were undone &b" + seconds + " %Sseconds");
Chat.MessageAll("Physics were undone &b{0}", delta.Shorten());
Server.s.Log("Physics were undone &b" + delta.Shorten());
p.level.Save(true);
}

View File

@ -37,12 +37,10 @@ namespace MCGalaxy.Commands {
if (p.hackrank) {
Player.Message(p, Colors.red + "You have already hacked a rank!"); return;
}
Group grp = Group.Find(message);
if (grp != null) {
DoFakeRank(p, grp);
} else {
Player.Message(p, "Invalid Rank!");
}
Group grp = Group.FindMatches(p, message);
if (grp == null) return;
DoFakeRank(p, grp);
}
void DoFakeRank(Player p, Group newRank) {

View File

@ -33,8 +33,6 @@ namespace MCGalaxy.Drawing.Brushes {
public override byte NextBlock(DrawOp op) { return block; }
public override byte NextExtBlock(DrawOp op) { return extBlock; }
// TODO: OVerride validate
}
public sealed class StripedBrush : Brush {

View File

@ -94,7 +94,7 @@ namespace MCGalaxy.Drawing.Ops {
public override string Name { get { return "UndoPhysics"; } }
public override bool AffectedByTransform { get { return false; } }
internal long seconds;
internal DateTime Start;
public override long BlocksAffected(Level lvl, Vec3S32[] marks) { return -1; }
@ -103,30 +103,30 @@ namespace MCGalaxy.Drawing.Ops {
int count = lvl.currentUndo;
for (int i = count; i >= 0; i--) {
try {
if (!CheckBlockPhysics(p, lvl, seconds, i)) break;
if (!CheckBlockPhysics(p, lvl, i)) break;
} catch { }
}
} else {
int count = lvl.currentUndo;
for (int i = count; i >= 0; i--) {
try {
if (!CheckBlockPhysics(p, lvl, seconds, i)) break;
if (!CheckBlockPhysics(p, lvl, i)) break;
} catch { }
}
for (int i = lvl.UndoBuffer.Count - 1; i > count; i--) {
try {
if (!CheckBlockPhysics(p, lvl, seconds, i)) break;
if (!CheckBlockPhysics(p, lvl, i)) break;
} catch { }
}
}
yield break;
}
bool CheckBlockPhysics(Player p, Level lvl, long seconds, int i) {
bool CheckBlockPhysics(Player p, Level lvl, int i) {
Level.UndoPos undo = lvl.UndoBuffer[i];
byte b = lvl.GetTile(undo.index);
DateTime time = Server.StartTime.AddTicks((undo.flags >> 2) * TimeSpan.TicksPerSecond);
if (time.AddTicks(seconds * TimeSpan.TicksPerSecond) < DateTime.UtcNow) return false;
if (time < Start) return false;
byte newType = (undo.flags & 2) != 0 ? Block.custom_block : undo.newRawType;
if (b == newType || Block.Convert(b) == Block.water || Block.Convert(b) == Block.lava) {

View File

@ -84,7 +84,7 @@ namespace MCGalaxy {
DateTime startTime;
public TimeSpan time {
get { return DateTime.UtcNow - startTime; }
set { startTime = DateTime.UtcNow.Add(-value); }
set { startTime = DateTime.UtcNow.Subtract(value); }
}
public string name;

View File

@ -29,7 +29,7 @@ namespace MCGalaxy {
Add(ref time, value.Days, 'd', spaces);
Add(ref time, value.Hours, 'h', spaces);
Add(ref time, value.Minutes, 'm', spaces);
if (seconds && value.Days < 1)
if (value.TotalMinutes <= 1 || (seconds && value.Days < 1))
Add(ref time, value.Seconds, 's', spaces);
if (time == "") time = seconds ? "0s" : "0m";