mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-28 07:56:20 -04:00
Sort of get /undo rewrite working, but mainly still broken.
This commit is contained in:
parent
10ee303c41
commit
1993bcf13e
@ -23,128 +23,154 @@ using MCGalaxy.Util;
|
|||||||
|
|
||||||
namespace MCGalaxy.Commands
|
namespace MCGalaxy.Commands
|
||||||
{
|
{
|
||||||
public sealed class CmdUndo : Command
|
public sealed class CmdUndo : Command
|
||||||
{
|
{
|
||||||
public override string name { get { return "undo"; } }
|
public override string name { get { return "undo"; } }
|
||||||
public override string shortcut { get { return "u"; } }
|
public override string shortcut { get { return "u"; } }
|
||||||
public override string type { get { return CommandTypes.Building; } }
|
public override string type { get { return CommandTypes.Building; } }
|
||||||
public override bool museumUsable { get { return true; } }
|
public override bool museumUsable { get { return true; } }
|
||||||
public override LevelPermission defaultRank { get { return LevelPermission.Guest; } }
|
public override LevelPermission defaultRank { get { return LevelPermission.Guest; } }
|
||||||
public override CommandPerm[] AdditionalPerms {
|
public override CommandPerm[] AdditionalPerms {
|
||||||
get { return new[] {
|
get { return new[] {
|
||||||
new CommandPerm(LevelPermission.Operator, "The lowest rank to undo other players actions", 1),
|
new CommandPerm(LevelPermission.Operator, "The lowest rank to undo other players actions", 1),
|
||||||
new CommandPerm(LevelPermission.AdvBuilder, "The lowest rank to be able to undo physics", 2),
|
new CommandPerm(LevelPermission.AdvBuilder, "The lowest rank to be able to undo physics", 2),
|
||||||
}; }
|
}; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void Use(Player p, string message) {
|
public override void Use(Player p, string message) {
|
||||||
if (p != null) p.RedoBuffer.Clear();
|
if (p != null) p.RedoBuffer.Clear();
|
||||||
int ignored = 0;
|
int ignored = 0;
|
||||||
if (message == "") {
|
if (message == "") {
|
||||||
if (p == null) { Player.SendMessage(null, "Console doesn't have an undo buffer."); return; }
|
if (p == null) { Player.SendMessage(null, "Console doesn't have an undo buffer."); return; }
|
||||||
message = p.name.ToLower() + " 30";
|
UndoSelf(p); return;
|
||||||
} else if (p != null && int.TryParse(message, out ignored)) {
|
} else if (p != null && int.TryParse(message, out ignored)) {
|
||||||
message = p.name.ToLower() + " " + message;
|
message = p.name.ToLower() + " " + message;
|
||||||
}
|
}
|
||||||
|
|
||||||
string[] parts = message.Split(' ');
|
string[] parts = message.Split(' ');
|
||||||
bool undoPhysics = parts[0].CaselessEq("physics");
|
bool undoPhysics = parts[0].CaselessEq("physics");
|
||||||
Player who = undoPhysics ? null : PlayerInfo.Find(parts[0]);
|
Player who = undoPhysics ? null : PlayerInfo.Find(parts[0]);
|
||||||
long seconds = GetSeconds(p, who, parts.Length > 1 ? parts[1] : "30");
|
long seconds = GetSeconds(p, who, parts.Length > 1 ? parts[1] : "30");
|
||||||
|
|
||||||
if (parts.Length > 1 && parts[1].CaselessEq("update")) {
|
if (parts.Length > 1 && parts[1].CaselessEq("update")) {
|
||||||
UndoFile.UpgradePlayerUndoFiles(parts[0]);
|
UndoFile.UpgradePlayerUndoFiles(parts[0]);
|
||||||
Player.SendMessage(p, "Updated undo files for " + parts[0] + " to the new binary format.");
|
Player.SendMessage(p, "Updated undo files for " + parts[0] + " to the new binary format.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (who != null)
|
if (who != null)
|
||||||
UndoOnlinePlayer(p, seconds, who);
|
UndoOnlinePlayer(p, seconds, who);
|
||||||
else if (undoPhysics)
|
else if (undoPhysics)
|
||||||
UndoLevelPhysics(p, seconds);
|
UndoLevelPhysics(p, seconds);
|
||||||
else
|
else
|
||||||
UndoOfflinePlayer(p, seconds, parts[0]);
|
UndoOfflinePlayer(p, seconds, parts[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const int undoMax = -1; // allows everything to be undone.
|
const int undoMax = -1; // allows everything to be undone.
|
||||||
internal static long GetSeconds(Player p, Player who, string param) {
|
internal static long GetSeconds(Player p, Player who, string param) {
|
||||||
long secs;
|
long secs;
|
||||||
if (param.CaselessEq("all")) {
|
if (param.CaselessEq("all")) {
|
||||||
secs = (p.group.maxUndo == undoMax || p == who) ? int.MaxValue : p.group.maxUndo;
|
secs = (p.group.maxUndo == undoMax || p == who) ? int.MaxValue : p.group.maxUndo;
|
||||||
} else if (!long.TryParse(param, out secs)) {
|
} else if (!long.TryParse(param, out secs)) {
|
||||||
Player.SendMessage(p, "Invalid seconds, using 30 seconds.");
|
Player.SendMessage(p, "Invalid seconds, using 30 seconds.");
|
||||||
return 30;
|
return 30;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (secs == 0) secs = 5400;
|
if (secs == 0) secs = 5400;
|
||||||
if (p != null && p != who && p.group.maxUndo != undoMax && secs > p.group.maxUndo) {
|
if (p != null && p != who && p.group.maxUndo != undoMax && secs > p.group.maxUndo) {
|
||||||
Player.SendMessage(p, p.group.name + "s may only undo up to " + p.group.maxUndo + " seconds.");
|
Player.SendMessage(p, p.group.name + "s may only undo up to " + p.group.maxUndo + " seconds.");
|
||||||
return p.group.maxUndo;
|
return p.group.maxUndo;
|
||||||
}
|
}
|
||||||
return secs;
|
return secs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void UndoOnlinePlayer(Player p, long seconds, Player who) {
|
void UndoSelf(Player p) {
|
||||||
if (p != null && p != who) {
|
UndoDrawOpEntry[] entries = p.UndoDrawOps.Items;
|
||||||
if (who.group.Permission > p.group.Permission) {
|
if (entries.Length == 0) {
|
||||||
MessageTooHighRank(p, "undo", true); return;
|
Player.SendMessage(p, "You have no draw operations to undo.");
|
||||||
}
|
Player.SendMessage(p, "Try using %T/undo <seconds> %Sinstead.");
|
||||||
if (!CheckAdditionalPerm(p)) { MessageNeedPerms(p, "can undo other players."); return; }
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UndoOnlineDrawOp op = new UndoOnlineDrawOp();
|
for (int i = entries.Length - 1; i >= 0; i--) {
|
||||||
op.Start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
|
UndoDrawOpEntry entry = entries[i];
|
||||||
op.who = who;
|
if (entry.DrawOpName == "UndoSelf") continue;
|
||||||
DrawOp.DoDrawOp(op, null, p, new [] { Vec3U16.MaxVal, Vec3U16.MaxVal } );
|
|
||||||
|
|
||||||
Level saveLevel = op.saveLevel;
|
UndoSelfDrawOp op = new UndoSelfDrawOp();
|
||||||
if (p == who) {
|
op.who = p;
|
||||||
Player.SendMessage(p, "Undid your actions for the past &b" + seconds + " %Sseconds.");
|
op.Start = entry.Start; op.End = entry.End;
|
||||||
} else {
|
DrawOp.DoDrawOp(op, null, p, new [] { Vec3U16.MaxVal, Vec3U16.MaxVal } );
|
||||||
Player.SendChatFrom(who, who.color + who.DisplayName + "%S's actions for the past &b" + seconds + " seconds were undone.", false);
|
|
||||||
}
|
|
||||||
Server.s.Log(who.name + "'s actions for the past " + seconds + " seconds were undone.");
|
|
||||||
if (saveLevel != null) saveLevel.Save(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UndoOfflinePlayer(Player p, long seconds, string whoName) {
|
entry.UndoDrawOpName = entry.DrawOpName;
|
||||||
if (!CheckAdditionalPerm(p)) { MessageNeedPerms(p, "can undo other players."); return; }
|
entry.DrawOpName = "UndoSelf";
|
||||||
UndoOfflineDrawOp op = new UndoOfflineDrawOp();
|
return;
|
||||||
op.Start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
|
}
|
||||||
op.whoName = whoName;
|
|
||||||
DrawOp.DoDrawOp(op, null, p, new [] { Vec3U16.MaxVal, Vec3U16.MaxVal } );
|
|
||||||
|
|
||||||
if (op.foundUser) {
|
Player.SendMessage(p, "Max number of draw operations that can be undone reached.");
|
||||||
Player.GlobalMessage(Server.FindColor(whoName) + whoName + "%S's actions for the past &b" + seconds + " %Sseconds were undone.");
|
Player.SendMessage(p, "Try using %T/undo <seconds> %Sinstead.");
|
||||||
Server.s.Log(whoName + "'s actions for the past " + seconds + " seconds were undone.");
|
}
|
||||||
p.level.Save(true);
|
|
||||||
} else {
|
|
||||||
Player.SendMessage(p, "Could not find player specified.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UndoLevelPhysics(Player p, long seconds) {
|
void UndoOnlinePlayer(Player p, long seconds, Player who) {
|
||||||
if (!CheckAdditionalPerm(p, 2)) { MessageNeedPerms(p, "can undo physics.", 2); return; }
|
if (p != null && p != who) {
|
||||||
if (p != null && !p.group.CanExecute("physics")) {
|
if (who.group.Permission > p.group.Permission) {
|
||||||
Player.SendMessage(p, "You can only undo physics if you can use /physics."); return;
|
MessageTooHighRank(p, "undo", true); return;
|
||||||
}
|
}
|
||||||
Command.all.Find("physics").Use(p, "0");
|
if (!CheckAdditionalPerm(p)) { MessageNeedPerms(p, "can undo other players."); return; }
|
||||||
UndoPhysicsDrawOp op = new UndoPhysicsDrawOp();
|
}
|
||||||
op.seconds = seconds;
|
|
||||||
DrawOp.DoDrawOp(op, null, p, new [] { Vec3U16.MaxVal, Vec3U16.MaxVal } );
|
|
||||||
|
|
||||||
Player.GlobalMessage("Physics were undone &b" + seconds + " %Sseconds");
|
UndoOnlineDrawOp op = new UndoOnlineDrawOp();
|
||||||
Server.s.Log( "Physics were undone &b" + seconds + " %Sseconds");
|
op.Start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
|
||||||
p.level.Save(true);
|
op.who = who;
|
||||||
}
|
DrawOp.DoDrawOp(op, null, p, new [] { Vec3U16.MaxVal, Vec3U16.MaxVal } );
|
||||||
|
|
||||||
public override void Help(Player p) {
|
Level saveLevel = op.saveLevel;
|
||||||
Player.SendMessage(p, "/undo [player] [seconds] - Undoes the blockchanges made by [player] in the previous [seconds].");
|
if (p == who) {
|
||||||
if (p == null || (p.group.maxUndo <= 500000 || p.group.maxUndo == 0))
|
Player.SendMessage(p, "Undid your actions for the past &b" + seconds + " %Sseconds.");
|
||||||
Player.SendMessage(p, "/undo [player] all - &cWill undo 68 years, 18 days, 15 hours, 28 minutes, 31 seconds for [player]");
|
} else {
|
||||||
if (p == null || (p.group.maxUndo <= 1800 || p.group.maxUndo == 0))
|
Player.SendChatFrom(who, who.color + who.DisplayName + "%S's actions for the past &b" + seconds + " seconds were undone.", false);
|
||||||
Player.SendMessage(p, "/undo [player] - &cWill undo 30 minutes");
|
}
|
||||||
Player.SendMessage(p, "/undo physics [seconds] - Undoes the physics for the current map");
|
Server.s.Log(who.name + "'s actions for the past " + seconds + " seconds were undone.");
|
||||||
}
|
if (saveLevel != null) saveLevel.Save(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UndoOfflinePlayer(Player p, long seconds, string whoName) {
|
||||||
|
if (!CheckAdditionalPerm(p)) { MessageNeedPerms(p, "can undo other players."); return; }
|
||||||
|
UndoOfflineDrawOp op = new UndoOfflineDrawOp();
|
||||||
|
op.Start = DateTime.UtcNow.AddTicks(-seconds * TimeSpan.TicksPerSecond);
|
||||||
|
op.whoName = whoName;
|
||||||
|
DrawOp.DoDrawOp(op, null, p, new [] { Vec3U16.MaxVal, Vec3U16.MaxVal } );
|
||||||
|
|
||||||
|
if (op.foundUser) {
|
||||||
|
Player.GlobalMessage(Server.FindColor(whoName) + whoName + "%S's actions for the past &b" + seconds + " %Sseconds were undone.");
|
||||||
|
Server.s.Log(whoName + "'s actions for the past " + seconds + " seconds were undone.");
|
||||||
|
p.level.Save(true);
|
||||||
|
} else {
|
||||||
|
Player.SendMessage(p, "Could not find player specified.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UndoLevelPhysics(Player p, long seconds) {
|
||||||
|
if (!CheckAdditionalPerm(p, 2)) { MessageNeedPerms(p, "can undo physics.", 2); return; }
|
||||||
|
if (p != null && !p.group.CanExecute("physics")) {
|
||||||
|
Player.SendMessage(p, "You can only undo physics if you can use /physics."); return;
|
||||||
|
}
|
||||||
|
Command.all.Find("physics").Use(p, "0");
|
||||||
|
UndoPhysicsDrawOp op = new UndoPhysicsDrawOp();
|
||||||
|
op.seconds = seconds;
|
||||||
|
DrawOp.DoDrawOp(op, null, p, new [] { Vec3U16.MaxVal, Vec3U16.MaxVal } );
|
||||||
|
|
||||||
|
Player.GlobalMessage("Physics were undone &b" + seconds + " %Sseconds");
|
||||||
|
Server.s.Log( "Physics were undone &b" + seconds + " %Sseconds");
|
||||||
|
p.level.Save(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Help(Player p) {
|
||||||
|
Player.SendMessage(p, "/undo [player] [seconds] - Undoes the blockchanges made by [player] in the previous [seconds].");
|
||||||
|
if (p == null || (p.group.maxUndo <= 500000 || p.group.maxUndo == 0))
|
||||||
|
Player.SendMessage(p, "/undo [player] all - &cWill undo 68 years, 18 days, 15 hours, 28 minutes, 31 seconds for [player]");
|
||||||
|
if (p == null || (p.group.maxUndo <= 1800 || p.group.maxUndo == 0))
|
||||||
|
Player.SendMessage(p, "/undo [player] - &cWill undo 30 minutes");
|
||||||
|
Player.SendMessage(p, "/undo physics [seconds] - Undoes the physics for the current map");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,20 +188,17 @@ namespace MCGalaxy.Drawing.Ops {
|
|||||||
entry.DrawOpName = op.Name;
|
entry.DrawOpName = op.Name;
|
||||||
entry.LevelName = p.level.name;
|
entry.LevelName = p.level.name;
|
||||||
entry.Start = DateTime.UtcNow;
|
entry.Start = DateTime.UtcNow;
|
||||||
|
// Use same time method as DoBlockchange writing to undo buffer
|
||||||
|
int timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
|
||||||
|
entry.Start = Server.StartTime.AddTicks(timeDelta * TimeSpan.TicksPerSecond);
|
||||||
|
|
||||||
bool needReveal = op.DetermineDrawOpMethod(p.level, affected);
|
bool needReveal = op.DetermineDrawOpMethod(p.level, affected);
|
||||||
op.Perform(marks, p, p.level, brush);
|
op.Perform(marks, p, p.level, brush);
|
||||||
entry.End = DateTime.UtcNow;
|
timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
|
||||||
|
entry.End = Server.StartTime.AddTicks(timeDelta * TimeSpan.TicksPerSecond);
|
||||||
|
|
||||||
if (entry.Start > p.UndoBuffer.LastClear) {
|
if (op.Name != "UndoSelf")
|
||||||
UndoDrawOpEntry[] items = p.UndoDrawOps.Items;
|
p.UndoDrawOps.Add(entry);
|
||||||
if (items.Length == 25)
|
|
||||||
p.UndoDrawOps.Remove(items[0]);
|
|
||||||
} else { // UndoBuffer has been cleared during the draw op.
|
|
||||||
entry.Start = p.UndoBuffer.LastClear;
|
|
||||||
p.RemoveInvalidUndos();
|
|
||||||
}
|
|
||||||
p.UndoDrawOps.Add(entry);
|
|
||||||
DoReload(p, needReveal);
|
DoReload(p, needReveal);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,10 @@ using MCGalaxy.Util;
|
|||||||
|
|
||||||
namespace MCGalaxy.Drawing.Ops {
|
namespace MCGalaxy.Drawing.Ops {
|
||||||
|
|
||||||
|
public class UndoSelfDrawOp : UndoOnlineDrawOp {
|
||||||
|
public override string Name { get { return "UndoSelf"; } }
|
||||||
|
}
|
||||||
|
|
||||||
public class UndoOnlineDrawOp : DrawOp {
|
public class UndoOnlineDrawOp : DrawOp {
|
||||||
|
|
||||||
public override string Name { get { return "UndoOnline"; } }
|
public override string Name { get { return "UndoOnline"; } }
|
||||||
|
@ -151,7 +151,7 @@ namespace MCGalaxy.Util {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public sealed class UndoDrawOpEntry {
|
public sealed class UndoDrawOpEntry {
|
||||||
public string DrawOpName;
|
public string DrawOpName, UndoDrawOpName;
|
||||||
public string LevelName;
|
public string LevelName;
|
||||||
public DateTime Start, End;
|
public DateTime Start, End;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user