Make adding to the BlockDB threadsafe.

This commit is contained in:
UnknownShadow200 2016-07-31 14:17:07 +10:00
parent a5c06065ca
commit a30dadfa1c
4 changed files with 44 additions and 56 deletions

View File

@ -128,7 +128,6 @@ namespace MCGalaxy.Drawing.Ops {
static void DoDrawOp(PendingDrawOp item, Player p) { static void DoDrawOp(PendingDrawOp item, Player p) {
Level lvl = item.Level; Level lvl = item.Level;
Level.BlockPos bP = default(Level.BlockPos);
if (item.Affected > Server.DrawReloadLimit) { if (item.Affected > Server.DrawReloadLimit) {
foreach (var b in item.Op.Perform(item.Marks, p, lvl, item.Brush)) { foreach (var b in item.Op.Perform(item.Marks, p, lvl, item.Brush)) {
@ -146,24 +145,18 @@ namespace MCGalaxy.Drawing.Ops {
foreach (var b in item.Op.Perform(item.Marks, p, lvl, item.Brush)) { foreach (var b in item.Op.Perform(item.Marks, p, lvl, item.Brush)) {
if (b.Block == Block.Zero) continue; if (b.Block == Block.Zero) continue;
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) continue; if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) continue;
bP.name = p.name;
bP.index = lvl.PosToInt(b.X, b.Y, b.Z);
bP.SetData(b.Block, b.ExtBlock, b.Block == 0);
if (lvl.UseBlockDB) int index = lvl.PosToInt(b.X, b.Y, b.Z);
lvl.blockCache.Add(bP); lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
BlockQueue.Addblock(p, bP.index, b.Block, b.ExtBlock); BlockQueue.Addblock(p, index, b.Block, b.ExtBlock);
} }
} else { } else {
foreach (var b in item.Op.Perform(item.Marks, p, item.Level, item.Brush)) { foreach (var b in item.Op.Perform(item.Marks, p, item.Level, item.Brush)) {
if (b.Block == Block.Zero) continue; if (b.Block == Block.Zero) continue;
if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) continue; if (!lvl.DoBlockchange(p, b.X, b.Y, b.Z, b.Block, b.ExtBlock, true)) continue;
bP.name = p.name;
bP.index = lvl.PosToInt(b.X, b.Y, b.Z);
bP.SetData(b.Block, b.ExtBlock, b.Block == 0); int index = lvl.PosToInt(b.X, b.Y, b.Z);
if (lvl.UseBlockDB) lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
lvl.blockCache.Add(bP);
Player.GlobalBlockchange(lvl, b.X, b.Y, b.Z, b.Block, b.ExtBlock); Player.GlobalBlockchange(lvl, b.X, b.Y, b.Z, b.Block, b.ExtBlock);
} }
} }

View File

@ -127,43 +127,35 @@ namespace MCGalaxy {
chunk[(y & 0x0F) << 8 | (z & 0x0F) << 4 | (x & 0x0F)] = 0; chunk[(y & 0x0F) << 8 | (z & 0x0F) << 4 | (x & 0x0F)] = 0;
} }
public void SetTile(ushort x, ushort y, ushort z, byte type, Player p, byte extType = 0) { public void SetTile(ushort x, ushort y, ushort z, byte block, Player p, byte extBlock = 0) {
int b = PosToInt(x, y, z); int index = PosToInt(x, y, z);
if (blocks == null || b < 0) return; if (blocks == null || index < 0) return;
byte oldType = blocks[b]; byte oldBlock = blocks[index], oldExtBlock = 0;
blocks[b] = type; blocks[index] = block;
byte oldExtType = 0;
changed = true; changed = true;
if (oldType == Block.custom_block) { if (oldBlock == Block.custom_block) {
oldExtType = GetExtTile(x, y, z); oldExtBlock = GetExtTile(x, y, z);
if (type != Block.custom_block) if (block != Block.custom_block)
RevertExtTileNoCheck(x, y, z); RevertExtTileNoCheck(x, y, z);
} }
if (type == Block.custom_block) if (block == Block.custom_block)
SetExtTileNoCheck(x, y, z, extType); SetExtTileNoCheck(x, y, z, extBlock);
if (p == null) if (p == null) return;
return;
Level.BlockPos bP = default(Level.BlockPos);
bP.name = p.name;
bP.index = b;
bP.SetData(type, extType, type == 0);
if (UseBlockDB)
blockCache.Add(bP);
AddToBlockDB(p, index, block, extBlock, block == 0);
Player.UndoPos Pos; Player.UndoPos Pos;
Pos.x = x; Pos.y = y; Pos.z = z; Pos.x = x; Pos.y = y; Pos.z = z;
Pos.mapName = this.name; Pos.mapName = this.name;
Pos.type = oldType; Pos.extType = oldExtType; Pos.type = oldBlock; Pos.extType = oldExtBlock;
Pos.newtype = type; Pos.newExtType = extType; Pos.newtype = block; Pos.newExtType = extBlock;
Pos.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; Pos.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
p.UndoBuffer.Add(this, Pos); p.UndoBuffer.Add(this, Pos);
} }
bool CheckTNTWarsChange(Player p, ushort x, ushort y, ushort z, ref byte type) { bool CheckTNTWarsChange(Player p, ushort x, ushort y, ushort z, ref byte block) {
if (!(type == Block.tnt || type == Block.bigtnt || type == Block.nuketnt || type == Block.smalltnt)) if (!(block == Block.tnt || block == Block.bigtnt || block == Block.nuketnt || block == Block.smalltnt))
return true; return true;
TntWarsGame game = TntWarsGame.GetTntWarsGame(p); TntWarsGame game = TntWarsGame.GetTntWarsGame(p);
@ -177,7 +169,7 @@ namespace MCGalaxy {
Player.Message(p, "TNT Wars: You have passed the maximum amount of TNT that can be placed!"); return false; Player.Message(p, "TNT Wars: You have passed the maximum amount of TNT that can be placed!"); return false;
} }
p.TntAtATime(); p.TntAtATime();
type = Block.smalltnt; block = Block.smalltnt;
return true; return true;
} }
@ -440,18 +432,25 @@ namespace MCGalaxy {
return pos.X < Width && pos.Y < Height && pos.Z < Length; return pos.X < Width && pos.Y < Height && pos.Z < Length;
} }
public void AddToBlockDB(Player p, int index, byte block, byte extBlock, bool delete) {
if (!UseBlockDB) return;
BlockPos bP = default(BlockPos);
bP.name = p.name;
bP.index = index;
bP.SetData(block, extBlock, delete);
lock (blockCacheLock)
blockCache.Add(bP);
}
public void UpdateBlock(Player p, ushort x, ushort y, ushort z, public void UpdateBlock(Player p, ushort x, ushort y, ushort z,
byte block, byte extBlock, bool drawn = false) { byte block, byte extBlock, bool drawn = false) {
if (!DoBlockchange(p, x, y, z, block, extBlock, drawn)) return; if (!DoBlockchange(p, x, y, z, block, extBlock, drawn)) return;
BlockPos bP = default(BlockPos); int index = PosToInt(x, y, z);
bP.name = p.name; AddToBlockDB(p, index, block, extBlock, block == 0);
bP.index = PosToInt(x, y, z);
bP.SetData(block, extBlock, block == 0);
if (UseBlockDB)
blockCache.Add(bP);
if (bufferblocks) if (bufferblocks)
BlockQueue.Addblock(p, bP.index, block, extBlock); BlockQueue.Addblock(p, index, block, extBlock);
else else
Player.GlobalBlockchange(this, x, y, z, block, extBlock); Player.GlobalBlockchange(this, x, y, z, block, extBlock);
} }

View File

@ -72,6 +72,7 @@ namespace MCGalaxy {
public List<UndoPos> UndoBuffer = new List<UndoPos>(); public List<UndoPos> UndoBuffer = new List<UndoPos>();
public List<Zone> ZoneList; public List<Zone> ZoneList;
public bool backedup; public bool backedup;
internal readonly object blockCacheLock = new object();
public List<BlockPos> blockCache = new List<BlockPos>(); public List<BlockPos> blockCache = new List<BlockPos>();
[ConfigBool("UseBlockDB", "Other", null, true)] [ConfigBool("UseBlockDB", "Other", null, true)]
public bool UseBlockDB = true; public bool UseBlockDB = true;

View File

@ -72,11 +72,6 @@ namespace MCGalaxy {
RevertBlock(x, y, z); return; RevertBlock(x, y, z); return;
} }
Level.BlockPos bP = default(Level.BlockPos);
bP.name = name;
bP.index = level.PosToInt(x, y, z);
bP.SetData(block, extBlock, false);
lastClick.X = x; lastClick.Y = y; lastClick.Z = z; lastClick.X = x; lastClick.Y = y; lastClick.Z = z;
if (Blockchange != null) { if (Blockchange != null) {
Blockchange(this, x, y, z, block, extBlock); return; Blockchange(this, x, y, z, block, extBlock); return;
@ -123,14 +118,14 @@ namespace MCGalaxy {
RevertBlock(x, y, z); return; RevertBlock(x, y, z); return;
} }
} }
//else
int index = level.PosToInt(x, y, z);
if (!painting && action == 0) { if (!painting && action == 0) {
bP.flags |= 1; if (DeleteBlock(old, x, y, z, block, extBlock))
if (DeleteBlock(old, x, y, z, block, extBlock) && level.UseBlockDB) level.AddToBlockDB(this, index, block, extBlock, true);
level.blockCache.Add(bP);
} else { } else {
if (PlaceBlock(old, x, y, z, block, extBlock) && level.UseBlockDB) if (PlaceBlock(old, x, y, z, block, extBlock))
level.blockCache.Add(bP); level.AddToBlockDB(this, index, block, extBlock, false);
} }
} }