mirror of
https://github.com/ClassiCube/MCGalaxy.git
synced 2025-09-24 05:03:34 -04:00
DB: /highlight now uses new BlockDB
This commit is contained in:
parent
831f002d34
commit
8d2c184589
@ -18,6 +18,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using MCGalaxy.DB;
|
||||
using MCGalaxy.Undo;
|
||||
|
||||
namespace MCGalaxy.Commands {
|
||||
@ -33,7 +34,6 @@ namespace MCGalaxy.Commands {
|
||||
|
||||
public override void Use(Player p, string message) {
|
||||
TimeSpan delta;
|
||||
bool found = false;
|
||||
if (Player.IsSuper(p)) { MessageInGameOnly(p); return; }
|
||||
if (message == "") message = p.name + " 1800";
|
||||
string[] args = message.Split(' ');
|
||||
@ -46,28 +46,31 @@ namespace MCGalaxy.Commands {
|
||||
delta = TimeSpan.FromMinutes(30);
|
||||
}
|
||||
|
||||
string name = PlayerInfo.FindMatchesPreferOnline(p, args[0]);
|
||||
if (name == null) return;
|
||||
|
||||
|
||||
DateTime start = DateTime.UtcNow.Subtract(delta);
|
||||
Player who = PlayerInfo.Find(args[0]);
|
||||
bool done = false;
|
||||
if (who != null) {
|
||||
found = true;
|
||||
UndoCache cache = who.UndoBuffer;
|
||||
using (IDisposable locker = cache.ClearLock.AccquireReadLock()) {
|
||||
done = HighlightBlocks(p, start, cache);
|
||||
}
|
||||
int[] ids = NameConverter.FindIds(name);
|
||||
bool found = false, done = false;
|
||||
if (ids.Length > 0) {
|
||||
HighlightHelper helper = new HighlightHelper();
|
||||
done = helper.DoHighlight(ids, start, p);
|
||||
found = helper.found;
|
||||
}
|
||||
|
||||
if (!done) {
|
||||
UndoFormatArgs undoArgs = new UndoFormatArgs(p, start, DateTime.MaxValue, null);
|
||||
UndoFormat.DoHighlight(args[0].ToLower(), ref found, undoArgs);
|
||||
UndoFormat.DoHighlight(name.ToLower(), ref found, undoArgs);
|
||||
}
|
||||
|
||||
if (found) {
|
||||
Player.Message(p, "Now highlighting past &b{0} %Sfor {1}",
|
||||
delta.Shorten(), PlayerInfo.GetColoredName(p, args[0]));
|
||||
delta.Shorten(), PlayerInfo.GetColoredName(p, name));
|
||||
Player.Message(p, "&cUse /reload to un-highlight");
|
||||
} else {
|
||||
Player.Message(p, "Could not find player specified.");
|
||||
Player.Message(p, "No changes found by {1} %Sin the past &b{0}",
|
||||
delta.Shorten(), PlayerInfo.GetColoredName(p, name));
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,11 +82,43 @@ namespace MCGalaxy.Commands {
|
||||
}
|
||||
}
|
||||
|
||||
static bool HighlightBlocks(Player p, DateTime start, UndoCache cache) {
|
||||
UndoFormatArgs args = new UndoFormatArgs(p, start, DateTime.MaxValue, null);
|
||||
UndoFormat format = new UndoFormatOnline(cache);
|
||||
UndoFormat.DoHighlight(null, format, args);
|
||||
return args.Stop;
|
||||
class HighlightHelper {
|
||||
Player p;
|
||||
BufferedBlockSender buffer;
|
||||
Vec3U16 dims;
|
||||
public bool found;
|
||||
|
||||
public bool DoHighlight(int[] ids, DateTime start, Player p) {
|
||||
buffer = new BufferedBlockSender(p);
|
||||
this.p = p;
|
||||
bool reachedStart = p.level.BlockDB.FindChangesBy(ids, start, DateTime.MaxValue,
|
||||
out dims, HighlightBlock);
|
||||
buffer.Send(true);
|
||||
|
||||
buffer.player = null;
|
||||
buffer.level = null;
|
||||
buffer = null;
|
||||
this.p = null;
|
||||
return reachedStart;
|
||||
}
|
||||
|
||||
void HighlightBlock(BlockDBEntry entry) {
|
||||
byte oldBlock = entry.OldRaw, newBlock = entry.NewRaw;
|
||||
if ((entry.Flags & BlockDBFlags.OldCustom) != 0) oldBlock = Block.custom_block;
|
||||
if ((entry.Flags & BlockDBFlags.NewCustom) != 0) newBlock = Block.custom_block;
|
||||
found = true;
|
||||
|
||||
byte highlight = (newBlock == Block.air
|
||||
|| Block.Convert(oldBlock) == Block.water || oldBlock == Block.waterstill
|
||||
|| Block.Convert(oldBlock) == Block.lava || oldBlock == Block.lavastill)
|
||||
? Block.red : Block.green;
|
||||
|
||||
int x = entry.Index % dims.X;
|
||||
int y = (entry.Index / dims.X) / dims.Z;
|
||||
int z = (entry.Index / dims.X) % dims.Z;
|
||||
int index = p.level.PosToInt((ushort)x, (ushort)y, (ushort)z);
|
||||
buffer.Add(index, highlight, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Help(Player p) {
|
||||
|
@ -112,11 +112,9 @@ namespace MCGalaxy.DB {
|
||||
Vec3U16 dims = Dims;
|
||||
// Read entries from memory cache
|
||||
int index = (y * dims.Z + z) * dims.X + x;
|
||||
FastList<BlockDBEntry> entries = Cache;
|
||||
|
||||
for (int i = 0; i < entries.Count; i++) {
|
||||
if (entries.Items[i].Index != index) continue;
|
||||
output(entries.Items[i]);
|
||||
for (int i = 0; i < Cache.Count; i++) {
|
||||
if (Cache.Items[i].Index != index) continue;
|
||||
output(Cache.Items[i]);
|
||||
}
|
||||
|
||||
// Read entries from disc cache
|
||||
@ -132,22 +130,31 @@ namespace MCGalaxy.DB {
|
||||
}
|
||||
|
||||
/// <summary> Outputs all block changes by the given players. </summary>
|
||||
public void FindChangesBy(int[] ids, DateTime start, DateTime end,
|
||||
/// <returns> whether an entry before start time was reached. </returns>
|
||||
public bool FindChangesBy(int[] ids, DateTime start, DateTime end,
|
||||
out Vec3U16 dims, Action<BlockDBEntry> output) {
|
||||
long startDelta = (long)start.Subtract(Epoch).TotalSeconds;
|
||||
long endDelta = (long)end.Subtract(Epoch).TotalSeconds;
|
||||
|
||||
using (IDisposable readLock = locker.AccquireReadLock()) {
|
||||
dims = Dims;
|
||||
// Read entries from memory cache
|
||||
for (int i = Cache.Count - 1; i >= 0; i--) {
|
||||
BlockDBEntry entry = Cache.Items[i];
|
||||
if (entry.TimeDelta < startDelta) return true;
|
||||
if (entry.TimeDelta > endDelta) continue;
|
||||
|
||||
for (int j = 0; j < ids.Length; j++) {
|
||||
if (entry.PlayerID != ids[j]) continue;
|
||||
output(entry); break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!File.Exists(FilePath)) return;
|
||||
int startDelta = (int)start.Subtract(Epoch).TotalSeconds;
|
||||
int endDelta = (int)end.Subtract(Epoch).TotalSeconds;
|
||||
// Read entries from disc cache
|
||||
if (!File.Exists(FilePath)) return false;
|
||||
using (Stream s = File.OpenRead(FilePath)) {
|
||||
BlockDBFile.ReadHeader(s, out dims);
|
||||
|
||||
if (ids.Length == 1) {
|
||||
BlockDBFile.FindChangesBy(s, ids[0], startDelta, endDelta, output);
|
||||
} else {
|
||||
BlockDBFile.FindChangesBy(s, ids, startDelta, endDelta, output);
|
||||
}
|
||||
return BlockDBFile.FindChangesBy(s, ids, startDelta, endDelta, output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -100,7 +100,9 @@ namespace MCGalaxy.DB {
|
||||
}
|
||||
|
||||
/// <summary> Iterates from the very newest to oldest entry in the BlockDB. </summary>
|
||||
public static void FindChangesBy(Stream s, int id, int start, int end, Action<BlockDBEntry> output) {
|
||||
/// <returns> whether an entry before start time was reached. </returns>
|
||||
public static bool FindChangesBy(Stream s, int[] ids, long start, long end,
|
||||
Action<BlockDBEntry> output) {
|
||||
byte[] bulk = new byte[BulkEntries * EntrySize];
|
||||
fixed (byte* ptr = bulk) {
|
||||
int entries = (int)(s.Length / EntrySize) - HeaderEntries;
|
||||
@ -109,50 +111,26 @@ namespace MCGalaxy.DB {
|
||||
while (entries > 0) {
|
||||
int count = Math.Min(entries, BulkEntries);
|
||||
s.Position -= count * EntrySize;
|
||||
|
||||
ReadFully(s, bulk, count * EntrySize);
|
||||
BlockDBEntry* entryPtr = (BlockDBEntry*)ptr;
|
||||
entryPtr += (count - 1);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (entryPtr->TimeDelta < start) return;
|
||||
|
||||
if (entryPtr->TimeDelta <= end && entryPtr->PlayerID == id) {
|
||||
output(*entryPtr);
|
||||
}
|
||||
entryPtr++;
|
||||
}
|
||||
entries -= count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Iterates from the very newest to oldest entry in the BlockDB. </summary>
|
||||
public static void FindChangesBy(Stream s, int[] ids, int start, int end, Action<BlockDBEntry> output) {
|
||||
byte[] bulk = new byte[BulkEntries * EntrySize];
|
||||
fixed (byte* ptr = bulk) {
|
||||
int entries = (int)(s.Length / EntrySize) - HeaderEntries;
|
||||
s.Position = s.Length;
|
||||
|
||||
while (entries > 0) {
|
||||
int count = Math.Min(entries, BulkEntries);
|
||||
s.Position -= count * EntrySize;
|
||||
ReadFully(s, bulk, count * EntrySize);
|
||||
BlockDBEntry* entryPtr = (BlockDBEntry*)ptr;
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (entryPtr->TimeDelta < start) return;
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
if (entryPtr->TimeDelta < start) return true;
|
||||
|
||||
if (entryPtr->TimeDelta <= end) {
|
||||
for (int j = 0; j < ids.Length; j++) {
|
||||
if (entryPtr->PlayerID == ids[j]) {
|
||||
output(*entryPtr); break;
|
||||
}
|
||||
if (entryPtr->PlayerID != ids[j]) continue;
|
||||
output(*entryPtr); break;
|
||||
}
|
||||
}
|
||||
entryPtr++;
|
||||
entryPtr--;
|
||||
}
|
||||
entries -= count;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
@ -36,7 +36,7 @@ namespace MCGalaxy.DB {
|
||||
}
|
||||
}
|
||||
|
||||
public static List<int> FindIds(string name) {
|
||||
public static int[] FindIds(string name) {
|
||||
List<string> invalid = Server.invalidIds.All();
|
||||
List<int> ids = new List<int>();
|
||||
|
||||
@ -49,7 +49,7 @@ namespace MCGalaxy.DB {
|
||||
ids.Add(PlayerData.ParseInt(raw));
|
||||
}
|
||||
}
|
||||
return ids;
|
||||
return ids.ToArray();
|
||||
}
|
||||
|
||||
public static int InvalidNameID(string name) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user