Now save old block to BlockDB

This commit is contained in:
UnknownShadow200 2016-12-21 22:31:04 +11:00
parent 7a4ffbc589
commit 9cbe726eeb
8 changed files with 144 additions and 87 deletions

View File

@ -182,7 +182,6 @@ namespace MCGalaxy.Commands.CPE {
Player.Message(p, "%T/customcolors remove [code] %H- Removes that custom color.");
Player.Message(p, "%T/customcolors list [offset] %H- lists all custom colors.");
Player.Message(p, "%T/customcolors edit [code] [name/fallback/hex]");
}
}
}
}

View File

@ -59,8 +59,8 @@ namespace MCGalaxy.Commands {
ListInMemory(p, ref foundAny, names, x, y, z);
if (!foundAny) Player.Message(p, "No block change records found for this block.");
OutputMessageBlock(p, b, id, x, y, z);
OutputPortal(p, b, id, x, y, z);
BlockDBChange.OutputMessageBlock(p, b, id, x, y, z);
BlockDBChange.OutputPortal(p, b, id, x, y, z);
GC.Collect();
GC.WaitForPendingFinalizers();
@ -71,17 +71,25 @@ namespace MCGalaxy.Commands {
if (!Database.TableExists("Block" + p.level.name)) return;
using (DataTable Blocks = Database.Backend.GetRows("Block" + p.level.name, "*",
"WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z)) {
DateTime now = DateTime.Now;
BlockDBEntry entry = default(BlockDBEntry);
entry.OldRaw = Block.Invalid;
for (int i = 0; i < Blocks.Rows.Count; i++) {
foundAny = true;
DataRow row = Blocks.Rows[i];
string name = row["Username"].ToString().Trim();
DateTime time = DateTime.Parse(row["TimePerformed"].ToString());
byte block = byte.Parse(row["Type"].ToString());
DateTime time = DateTime.Parse(row["TimePerformed"].ToString());
TimeSpan delta = time - BlockDB.Epoch;
entry.TimeDelta = (int)delta.TotalSeconds;
entry.Flags = BlockDBFlags.ManualPlace;
byte flags = ParseFlags(row["Deleted"].ToString());
bool deleted = (flags & 1) != 0, isExt = (flags & 2) != 0;
Output(p, name, block, isExt, deleted, now - time);
if ((flags & 1) == 0) { // block was placed
entry.NewRaw = byte.Parse(row["Type"].ToString());
entry.Flags |= (flags & 2) != 0 ? BlockDBFlags.NewCustom : BlockDBFlags.None;
}
BlockDBChange.Output(p, name, entry);
}
}
}
@ -101,11 +109,7 @@ namespace MCGalaxy.Commands {
names[entry.PlayerID] = name;
}
foundAny = true;
DateTime time = BlockDB.Epoch.AddSeconds(entry.TimeDelta);
bool deleted = entry.NewRaw == 0;
bool extBlock = (entry.Flags & BlockDBFlags.NewCustom) != 0;
Output(p, name, entry.NewRaw, extBlock, deleted, now - time);
BlockDBChange.Output(p, name, entry);
}
static void ListInMemory(Player p, ref bool foundAny, Dictionary<int, string> names,
@ -117,69 +121,7 @@ namespace MCGalaxy.Commands {
if (entries.Items[i].Index != index) continue;
OutputEntry(p, ref foundAny, names, entries.Items[i]);
}
}
static void Output(Player p, string user, byte raw, bool isExt,
bool deleted, TimeSpan delta) {
byte block = isExt ? Block.custom_block : raw;
byte extBlock = isExt ? raw : (byte)0;
string blockName = p.level.BlockName(block, extBlock);
if (raw == Block.custom_block && !isExt) // Before started tracking IsExt in BlockDB
blockName = Block.Name(raw);
Player.Message(p, "{0} ago {1} {2}",
delta.Shorten(true, false), PlayerInfo.GetColoredName(p, user),
deleted ? "&4deleted %S(using " + blockName + ")" : "&3placed %S" + blockName);
}
static void OutputMessageBlock(Player p, byte block, byte extBlock,
ushort x, ushort y, ushort z) {
if (block == Block.custom_block) {
if (!p.level.CustomBlockProps[extBlock].IsMessageBlock) return;
} else {
if (!Block.Props[block].IsMessageBlock) return;
}
try {
if (!Database.Backend.TableExists("Messages" + p.level.name)) return;
DataTable messages = Database.Backend.GetRows("Messages" + p.level.name, "*",
"WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z);
int last = messages.Rows.Count - 1;
if (last == -1) { messages.Dispose(); return; }
string message = messages.Rows[last]["Message"].ToString().Trim();
message = message.Replace("\\'", "\'");
Player.Message(p, "Message Block contents: {0}", message);
} catch {
}
}
static void OutputPortal(Player p, byte block, byte extBlock,
ushort x, ushort y, ushort z) {
if (block == Block.custom_block) {
if (!p.level.CustomBlockProps[extBlock].IsPortal) return;
} else {
if (!Block.Props[block].IsPortal) return;
}
try {
if (!Database.Backend.TableExists("Portals" + p.level.name)) return;
DataTable portals = Database.Backend.GetRows("Portals" + p.level.name, "*",
"WHERE EntryX=@0 AND EntryY=@1 AND EntryZ=@2", x, y, z);
int last = portals.Rows.Count - 1;
if (last == -1) { portals.Dispose(); return; }
string exitMap = portals.Rows[last]["ExitMap"].ToString().Trim();
ushort exitX = U16(portals.Rows[last]["ExitX"]);
ushort exitY = U16(portals.Rows[last]["ExitY"]);
ushort exitZ = U16(portals.Rows[last]["ExitZ"]);
Player.Message(p, "Portal destination: ({0}, {1}, {2}) in {3}",
exitX, exitY, exitZ, exitMap);
} catch {
}
}
}
static ushort U16(object x) { return ushort.Parse(x.ToString()); }

View File

@ -0,0 +1,97 @@
/*
Copyright 2015 MCGalaxy
Dual-licensed under the Educational Community License, Version 2.0 and
the GNU General Public License, Version 3 (the "Licenses"); you may
not use this file except in compliance with the Licenses. You may
obtain a copy of the Licenses at
http://www.opensource.org/licenses/ecl2.php
http://www.gnu.org/licenses/gpl-3.0.html
Unless required by applicable law or agreed to in writing,
software distributed under the Licenses are distributed on an "AS IS"
BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
or implied. See the Licenses for the specific language governing
permissions and limitations under the Licenses.
*/
using System;
using System.Data;
using MCGalaxy.SQL;
namespace MCGalaxy.DB {
/// <summary> Outputs information about a block and its changes to the user. </summary>
public static class BlockDBChange {
public static void Output(Player p, string name, BlockDBEntry entry) {
byte oldBlock = entry.OldRaw, oldExt = 0, newBlock = entry.NewRaw, newExt = 0;
if ((entry.Flags & BlockDBFlags.OldCustom) != 0) {
oldExt = oldBlock; oldBlock = Block.custom_block;
}
if ((entry.Flags & BlockDBFlags.NewCustom) != 0) {
newExt = newBlock; newBlock = Block.custom_block;
}
TimeSpan delta = DateTime.UtcNow.Subtract(entry.Time);
name = PlayerInfo.GetColoredName(p, name);
if (newBlock == Block.air) {
Player.Message(p, "{0} ago {1} &4deleted %S{2}",
delta.Shorten(true, false), name, p.level.BlockName(oldBlock, oldExt));
} else {
Player.Message(p, "{0} ago {1} &3placed %S{2}",
delta.Shorten(true, false), name, p.level.BlockName(newBlock, newExt));
}
}
public static void OutputMessageBlock(Player p, byte block, byte extBlock,
ushort x, ushort y, ushort z) {
if (block == Block.custom_block) {
if (!p.level.CustomBlockProps[extBlock].IsMessageBlock) return;
} else {
if (!Block.Props[block].IsMessageBlock) return;
}
try {
if (!Database.Backend.TableExists("Messages" + p.level.name)) return;
DataTable messages = Database.Backend.GetRows("Messages" + p.level.name, "*",
"WHERE X=@0 AND Y=@1 AND Z=@2", x, y, z);
int last = messages.Rows.Count - 1;
if (last == -1) { messages.Dispose(); return; }
string message = messages.Rows[last]["Message"].ToString().Trim();
message = message.Replace("\\'", "\'");
Player.Message(p, "Message Block contents: {0}", message);
} catch {
}
}
public static void OutputPortal(Player p, byte block, byte extBlock,
ushort x, ushort y, ushort z) {
if (block == Block.custom_block) {
if (!p.level.CustomBlockProps[extBlock].IsPortal) return;
} else {
if (!Block.Props[block].IsPortal) return;
}
try {
if (!Database.Backend.TableExists("Portals" + p.level.name)) return;
DataTable portals = Database.Backend.GetRows("Portals" + p.level.name, "*",
"WHERE EntryX=@0 AND EntryY=@1 AND EntryZ=@2", x, y, z);
int last = portals.Rows.Count - 1;
if (last == -1) { portals.Dispose(); return; }
string exitMap = portals.Rows[last]["ExitMap"].ToString().Trim();
ushort exitX = U16(portals.Rows[last]["ExitX"]);
ushort exitY = U16(portals.Rows[last]["ExitY"]);
ushort exitZ = U16(portals.Rows[last]["ExitZ"]);
Player.Message(p, "Portal destination: ({0}, {1}, {2}) in {3}",
exitX, exitY, exitZ, exitMap);
} catch {
}
}
static ushort U16(object x) { return ushort.Parse(x.ToString()); }
}
}

View File

@ -39,9 +39,13 @@ namespace MCGalaxy.DB {
/// <summary> Flags for the block change. </summary>
public ushort Flags;
/// <summary> The point in time this change occured at. </summary>
public DateTime Time { get { return BlockDB.Epoch.AddSeconds(TimeDelta); } }
}
public static class BlockDBFlags {
public const ushort None = 0x0000;
public const ushort ManualPlace = 0x0001;
public const ushort Painted = 0x0002;
public const ushort Drawn = 0x0004;

View File

@ -182,19 +182,23 @@ namespace MCGalaxy.Drawing.Ops {
static void BufferedOutput(DrawOpBlock b, Player p, Level lvl) {
if (b.Block == Block.Invalid) return;
byte old = lvl.GetTile(b.X, b.Y, b.Z), oldExt = 0;
if (old == Block.custom_block) oldExt = lvl.GetExtTile(b.X, b.Y, b.Z);
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) return;
int index = lvl.PosToInt(b.X, b.Y, b.Z);
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
lvl.AddToBlockDB(p, index, old, oldExt, b.Block, b.ExtBlock);
BlockQueue.Addblock(p, index, b.Block, b.ExtBlock);
}
static void SlowOutput(DrawOpBlock b, Player p, Level lvl) {
if (b.Block == Block.Invalid) return;
byte old = lvl.GetTile(b.X, b.Y, b.Z), oldExt = 0;
if (old == Block.custom_block) oldExt = lvl.GetExtTile(b.X, b.Y, b.Z);
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) return;
int index = lvl.PosToInt(b.X, b.Y, b.Z);
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
lvl.AddToBlockDB(p, index, old, oldExt, b.Block, b.ExtBlock);
Player.GlobalBlockchange(lvl, b.X, b.Y, b.Z, b.Block, b.ExtBlock);
}

View File

@ -145,7 +145,7 @@ namespace MCGalaxy {
SetExtTileNoCheck(x, y, z, extBlock);
if (p == null) return;
AddToBlockDB(p, index, block, extBlock, block == 0);
AddToBlockDB(p, index, oldBlock, oldExtBlock, block, extBlock);
Player.UndoPos Pos;
Pos.x = x; Pos.y = y; Pos.z = z;
Pos.mapName = this.name;
@ -428,30 +428,38 @@ namespace MCGalaxy {
return x >= 0 && y >= 0 && z >= 0 && x < Width && y < Height && z < Length;
}
public void AddToBlockDB(Player p, int index, byte block, byte extBlock, bool delete) {
public void AddToBlockDB(Player p, int index, byte oldBlock,
byte oldExtBlock, byte block, byte extBlock) {
if (!UseBlockDB) return;
BlockDBEntry entry;
entry.PlayerID = p.UserID;
entry.TimeDelta = (int)DateTime.UtcNow.Subtract(BlockDB.Epoch).TotalSeconds;
entry.Index = index;
entry.OldRaw = Block.Invalid; // TODO: need to fill out old block properly
entry.NewRaw = delete ? Block.air : block;
entry.OldRaw = oldBlock; entry.NewRaw = block;
entry.Flags = BlockDBFlags.ManualPlace;
if (block == Block.custom_block) {
entry.Flags |= BlockDBFlags.NewCustom;
entry.NewRaw = extBlock;
}
if (oldBlock == Block.custom_block) {
entry.Flags |= BlockDBFlags.OldCustom;
entry.OldRaw = oldExtBlock;
}
lock (blockCacheLock)
blockCache.Add(entry);
}
public void UpdateBlock(Player p, ushort x, ushort y, ushort z,
byte block, byte extBlock, bool drawn = false) {
byte old = GetTile(x, y, z), oldExt = 0;
if (old == Block.custom_block) oldExt = GetExtTile(x, y, z);
if (!DoBlockchange(p, x, y, z, block, extBlock, drawn)) return;
int index = PosToInt(x, y, z);
AddToBlockDB(p, index, block, extBlock, block == 0);
AddToBlockDB(p, index, old, oldExt, block, extBlock);
if (bufferblocks)
BlockQueue.Addblock(p, index, block, extBlock);

View File

@ -405,6 +405,7 @@
<Compile Include="Database\BlockDB\BlockDB.cs" />
<Compile Include="Database\BlockDB\BlockDBFile.cs" />
<Compile Include="Database\BlockDB\BlockDBEntry.cs" />
<Compile Include="Database\BlockDB\BlockDBChange.cs" />
<Compile Include="Database\BlockDB\DBUpgrader.cs" />
<Compile Include="Database\BlockDB\BlockDBTableDumper.cs" />
<Compile Include="Database\BlockDB\NameConverter.cs" />

View File

@ -47,8 +47,10 @@ namespace MCGalaxy {
public void ManualChange(ushort x, ushort y, ushort z, byte action,
byte block, byte extBlock, bool checkPlaceDist) {
byte old = level.GetTile(x, y, z);
byte old = level.GetTile(x, y, z), oldExt = 0;
if (old == Block.Invalid) return;
if (old == Block.custom_block) oldExt = level.GetExtTile(x, y, z);
if (jailed || !agreed || !canBuild) { RevertBlock(x, y, z); return; }
if (level.IsMuseum && Blockchange == null) return;
@ -121,10 +123,10 @@ namespace MCGalaxy {
int index = level.PosToInt(x, y, z);
if (doDelete) {
if (DeleteBlock(old, x, y, z, block, extBlock))
level.AddToBlockDB(this, index, heldBlock, heldExt, true);
level.AddToBlockDB(this, index, old, oldExt, 0, 0);
} else {
if (PlaceBlock(old, x, y, z, block, extBlock))
level.AddToBlockDB(this, index, heldBlock, heldExt, false);
level.AddToBlockDB(this, index, old, oldExt, heldBlock, heldExt);
}
}