Tidy up drawop code a bit

This commit is contained in:
UnknownShadow200 2018-07-11 12:50:35 +10:00
parent 1cd23d6c12
commit 1d5a01231c
6 changed files with 66 additions and 66 deletions

View File

@ -82,9 +82,10 @@ namespace MCGalaxy.Commands.Moderation {
foreach (Level lvl in levels) {
op.SetMarks(marks);
op.SetLevel(lvl);
op.Player = p; p.level = lvl;
DrawOpPerformer.DoQueuedDrawOp(p, op, null, marks);
op.Player = p;
DrawOpPerformer.Execute(p, op, null, marks);
}
p.level = null;
} else {
DrawOpPerformer.Do(op, null, p, marks);
}

View File

@ -52,7 +52,7 @@ namespace MCGalaxy.Drawing.Ops {
for (int i = 0; i < zones.Length; i++) {
// player could potentially modify blocks in this particular zone
if (zones[i].Access.CheckAllowed(p)) return false;
}
}
return !lvl.BuildAccess.CheckDetailed(p);
}
@ -86,7 +86,7 @@ namespace MCGalaxy.Drawing.Ops {
return true;
}
internal static void DoQueuedDrawOp(Player p, DrawOp op, Brush brush, Vec3S32[] marks) {
static void DoQueuedDrawOp(Player p, DrawOp op, Brush brush, Vec3S32[] marks) {
PendingDrawOp item = new PendingDrawOp();
item.Op = op; item.Brush = brush; item.Marks = marks;
@ -113,38 +113,38 @@ namespace MCGalaxy.Drawing.Ops {
return;
}
}
UndoDrawOpEntry entry = new UndoDrawOpEntry();
entry.DrawOpName = item.Op.Name;
entry.LevelName = item.Op.Level.name;
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);
if (item.Brush != null) item.Brush.Configure(item.Op, p);
bool needReload = DoDrawOp(item, p);
timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds + 1;
entry.End = Server.StartTime.AddTicks(timeDelta * TimeSpan.TicksPerSecond);
if (item.Op.Undoable) p.DrawOps.Add(entry);
if (p.DrawOps.Count > 200) p.DrawOps.RemoveFirst();
if (needReload) DoReload(p, item.Op.Level);
item.Op.TotalModified = 0; // reset total modified (as drawop instances are reused in static mode)
Execute(p, item.Op, item.Brush, item.Marks);
}
}
static bool DoDrawOp(PendingDrawOp item, Player p) {
Level lvl = item.Op.Level;
DrawOpOutputter outputter = new DrawOpOutputter(item.Op);
internal static void Execute(Player p, DrawOp op, Brush brush, Vec3S32[] marks) {
UndoDrawOpEntry entry = new UndoDrawOpEntry();
entry.DrawOpName = op.Name;
entry.LevelName = op.Level.name;
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);
if (item.Op.AffectedByTransform) {
p.Transform.Perform(item.Marks, p, lvl, item.Op, item.Brush, outputter.Output);
if (brush != null) brush.Configure(op, p);
Level lvl = op.Level;
DrawOpOutputter outputter = new DrawOpOutputter(op);
if (op.AffectedByTransform) {
p.Transform.Perform(marks, p, lvl, op, brush, outputter.Output);
} else {
item.Op.Perform(item.Marks, item.Brush, outputter.Output);
op.Perform(marks, brush, outputter.Output);
}
return item.Op.TotalModified >= outputter.reloadThreshold;
bool needsReload = op.TotalModified >= outputter.reloadThreshold;
timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds + 1;
entry.End = Server.StartTime.AddTicks(timeDelta * TimeSpan.TicksPerSecond);
if (op.Undoable) p.DrawOps.Add(entry);
if (p.DrawOps.Count > 200) p.DrawOps.RemoveFirst();
if (needsReload) DoReload(p, op.Level);
op.TotalModified = 0; // reset total modified (as drawop instances are reused in static mode)
}
static void DoReload(Player p, Level lvl) {
@ -161,7 +161,7 @@ namespace MCGalaxy.Drawing.Ops {
readonly DrawOp op;
internal readonly int reloadThreshold;
public DrawOpOutputter(DrawOp op) {
public DrawOpOutputter(DrawOp op) {
this.op = op;
reloadThreshold = op.Level.ReloadThreshold;
}
@ -201,10 +201,8 @@ namespace MCGalaxy.Drawing.Ops {
}
}
if (p != null) {
lvl.BlockDB.Cache.Add(p, b.X, b.Y, b.Z, op.Flags, old, b.Block);
p.SessionModified++; p.TotalModified++; p.TotalDrawn++; // increment block stats inline
}
lvl.BlockDB.Cache.Add(p, b.X, b.Y, b.Z, op.Flags, old, b.Block);
p.SessionModified++; p.TotalModified++; p.TotalDrawn++; // increment block stats inline
// Potentially buffer the block change
if (op.TotalModified == reloadThreshold) {
@ -212,10 +210,11 @@ namespace MCGalaxy.Drawing.Ops {
p.Message("Changed over {0} blocks, preparing to reload map..", reloadThreshold);
}
lock (lvl.queueLock)
lvl.blockqueue.Clear();
lock (lvl.queueLock) { lvl.blockqueue.Clear(); }
} else if (op.TotalModified < reloadThreshold) {
if (!Block.VisuallyEquals(old, b.Block)) BlockQueue.Add(p, index, b.Block);
if (!Block.VisuallyEquals(old, b.Block)) {
BlockQueue.Add(p, lvl, index, b.Block);
}
if (lvl.physics > 0) {
if (old == Block.Sponge && b.Block != Block.Sponge)

View File

@ -68,6 +68,23 @@ namespace MCGalaxy.Games {
t.Name = "MCG_" + GameName;
t.Start();
}
public void AutoStart() {
if (!GetConfig().StartImmediately) return;
try {
Start(Player.Console, "", int.MaxValue);
} catch (Exception ex) {
Logger.LogError("Error auto-starting " + GameName, ex);
}
}
protected virtual string GetStartMap(RoundsGame game, string forcedMap) {
if (forcedMap.Length > 0) return forcedMap;
List<string> maps = Picker.GetCandidateMaps(game);
if (maps == null || maps.Count == 0) return null;
return LevelPicker.GetRandomMap(new Random(), maps);
}
void RunGame() {
try {
@ -90,14 +107,6 @@ namespace MCGalaxy.Games {
IGame.RunningGames.Remove(this);
}
protected virtual string GetStartMap(RoundsGame game, string forcedMap) {
if (forcedMap.Length > 0) return forcedMap;
List<string> maps = Picker.GetCandidateMaps(game);
if (maps == null || maps.Count == 0) return null;
return LevelPicker.GetRandomMap(new Random(), maps);
}
protected virtual bool SetMap(string map) {
Picker.QueuedMap = null;
Level next = LevelInfo.FindExact(map);

View File

@ -43,8 +43,7 @@ namespace MCGalaxy {
task.Delay = TimeSpan.FromMilliseconds(Interval);
}
public static void Add(Player p, int index, BlockID block) {
if (index == -1) return;
public static void Add(Player p, Level lvl, int index, BlockID block) {
// Bit packing format
// 32-63: index
// 12-31: session ID
@ -53,9 +52,7 @@ namespace MCGalaxy {
flags |= (ulong)p.SessionID << idShift;
flags |= (ulong)block & blockMask;
lock (p.level.queueLock) {
p.level.blockqueue.Add(flags);
}
lock (lvl.queueLock) { lvl.blockqueue.Add(flags); }
}
public static void RemoveAll(Player p) {

View File

@ -411,8 +411,11 @@ namespace MCGalaxy {
BlockDB.Cache.Add(p, x, y, z, flags, old, block);
if (type == 1) return; // not different visually
if (buffered) BlockQueue.Add(p, index, block);
else Player.GlobalBlockchange(this, x, y, z, block);
if (buffered) {
BlockQueue.Add(p, p.level, index, block);
} else {
Player.GlobalBlockchange(this, x, y, z, block);
}
}
public BlockDefinition GetBlockDef(BlockID block) {

View File

@ -119,23 +119,14 @@ namespace MCGalaxy {
TimeSpan.FromMilliseconds(ServerConfig.PositionUpdateInterval));
}
static void InitGame(RoundsGame game) {
if (!game.GetConfig().StartImmediately) return;
try {
game.Start(Player.Console, "", int.MaxValue);
} catch (Exception ex) {
Logger.LogError("Error auto-starting " + game.GameName, ex);
}
}
static void InitRest(SchedulerTask task) {
IRC = new IRCBot();
if (ServerConfig.UseIRC) IRC.Connect();
InitGame(CountdownGame.Instance);
InitGame(ZSGame.Instance);
InitGame(LSGame.Instance);
InitGame(CTFGame.Instance);
CountdownGame.Instance.AutoStart();
ZSGame.Instance.AutoStart();
LSGame.Instance.AutoStart();
CTFGame.Instance.AutoStart();
MainScheduler.QueueRepeat(BlockQueue.Loop, null,
TimeSpan.FromMilliseconds(BlockQueue.Interval));