void Undo(long UID, int time, Level l, Player online) { long since=DateTime.Now.AddSeconds(-time).Ticks; int count = 0; foreach (var ch in BlockChangeHistory.GetCurrentIfUID(l.Name, (uint)UID, since)) { RedoHistory.Add((uint)UID, l.Name, ch.Item1, ch.Item2, ch.Item3, ch.Item4); count++; } foreach (var ch in BlockChangeHistory.Undo(l.Name, (uint)UID, since)) { l.BlockChange(ch.Item1, ch.Item2, ch.Item3, ch.Item4); } online.SendMessage("&e" + count + Server.DefaultColor + " Blocks changed"); return; }
void Undo(long UID, int time, Level l, Player online) { if (online != null) { online.history.Undo(DateTime.Now.AddSeconds(-time).Ticks, l); } return; if (UID == -1) return; string datetime = DateTime.Now.AddSeconds(time * -1).ToString("yyyy-MM-dd HH:mm:ss.fff"); // DataTable blockchanges = Database.fillData("SElECT * FROM Blocks WHERE UID=" + UID + " AND Date > '" + datetime + "' ORDER BY Date"); int x = 0; int y = 0; int z = 0; byte was = 0; Stopwatch s = new Stopwatch(); s.Start(); int i = 0; foreach(NameValueCollection nvm in Database.getData("SElECT X, Y, Z, Was, Date FROM Blocks WHERE UID=" + UID + " AND Date > '" + datetime + "' ORDER BY Date DESC")){ i++; x = int.Parse(nvm["X"].ToString()); y = int.Parse(nvm["Y"].ToString()); z = int.Parse(nvm["Z"].ToString()); was = byte.Parse(nvm["Was"].ToString()); l.BlockChange((ushort)x, (ushort)z, (ushort)y, was); } Database.executeQuery("DELETE FROM Blocks WHERE DATE > '" + datetime + "'"); s.Stop(); Logger.Log("used " + s.Elapsed + " for " + i + " undos"); // blockchanges.Dispose(); }
private static void redo(ExtraData<Tuple<short, short, short>, Tuple<long, byte>> toChange, Level l, long UID, Player p = null) { MemoryStream ms = new MemoryStream(); BinaryWriter bw = new BinaryWriter(ms); foreach (Tuple<short, short, short> v in toChange.Keys) { byte currentBlock = l.GetBlock(v.Item1, v.Item2, v.Item3); byte newBlock = toChange[v].Item2; if (currentBlock != newBlock) { if (p != null && p.Level == l) { lock (p.history.lock_recent) { p.history.recentTimes.Add(DateTime.Now.Ticks); p.history.recentChanges.Add(new Tuple<Tuple<short, short, short>, byte, byte>(v, currentBlock, newBlock)); } } else { bw.Write(DateTime.Now.Ticks); bw.Write(v.Item1); bw.Write(v.Item2); bw.Write(v.Item3); bw.Write(currentBlock); bw.Write(newBlock); } l.BlockChange(new Vector3S(v.Item1, v.Item2, v.Item3), newBlock); //TODO: Create BlockChange(short,short,short); } } bw.Close(); if (ms.Length != 0) { string path = GetFullPath((p == null) ? UID : p.UID, l); ms.Position = 0; BinaryReader br = new BinaryReader(ms); long initialTime = br.ReadInt64(); br.Close(); FileStream fs = new FileStream(path + initialTime + historyEnding, FileMode.Create, FileAccess.Write); GZipStream gz = new GZipStream(fs, CompressionMode.Compress); gz.Write(ms.ToArray(), 0, (int)ms.Length); gz.Close(); fs.Close(); } ms.Close(); }
public void Undo(long since, Level l) { ExtraData<Tuple<short, short, short>, Tuple<long, byte>> toChange = GetOriginalBlocks(since, l); List<long> asked = new List<long>(); foreach (Player p in l.Players) { if (p != player) toChange = p.history.redoRecentOthersUndo(toChange, since, l); } toChange = redoArchiveOthersUndoForAllPlayers(toChange, since, l); string path = GetFullPath(l); if (!Directory.Exists(path)) Directory.CreateDirectory(path); string tmppath = GetFullPath(l) + DateTime.Now.Ticks + futureEnding; FileStream fs = new FileStream(tmppath, FileMode.Create, FileAccess.Write); GZipStream gz = new GZipStream(fs, CompressionMode.Compress); BinaryWriter bw = new BinaryWriter(gz); foreach (Tuple<short, short, short> v in toChange.Keys) { //all changes are associated to the time in the filename byte tmp = l.GetBlock(v.Item1, v.Item2, v.Item3); if (tmp != toChange[v].Item2) { bw.Write(v.Item1);//coords bw.Write(v.Item2); bw.Write(v.Item3); bw.Write(toChange[v].Item2);//after undo l.BlockChange(new Vector3S(v.Item1, v.Item2, v.Item3), toChange[v].Item2); } } bw.Close(); gz.Close(); fs.Close(); }
/// <summary> /// Fills the <see cref="Cuboid"/> with <paramref name="block"/>. /// </summary> /// <param name="block">The <see cref="Block"/> to fill with.</param> /// <param name="world">The <see cref="Level"/>.</param> /// <param name="p">The player.</param> /// <remarks></remarks> public void Fill(Block block, Level world, Player p = null) { var buffer = new List<Pos>(); ushort x, z, y; ushort xmin = (ushort) Min.x, xmax = (ushort) Max.x, zmin = (ushort) Min.z, zmax = (ushort) Max.z, ymin = (ushort) Min.y, ymax = (ushort) Max.y; for (x = xmin; x <= xmax; ++x) for (z = zmin; z <= zmax; ++z) for (y = ymin; y <= ymax; ++y) if (world.GetBlock(x, z, y) != block) BufferAdd(buffer, x, z, y); //Level Blockqueue if (p != null) p.SendMessage(buffer.Count.ToString(CultureInfo.InvariantCulture) + " blocks."); buffer.ForEach( pos => world.BlockChange((ushort) (pos.pos.x), (ushort) (pos.pos.z), (ushort) (pos.pos.y), block, p)); }