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) {
Level lvl = item.Level;
Level.BlockPos bP = default(Level.BlockPos);
if (item.Affected > Server.DrawReloadLimit) {
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)) {
if (b.Block == Block.Zero) 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)
lvl.blockCache.Add(bP);
BlockQueue.Addblock(p, bP.index, b.Block, b.ExtBlock);
int index = lvl.PosToInt(b.X, b.Y, b.Z);
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
BlockQueue.Addblock(p, index, b.Block, b.ExtBlock);
}
} else {
foreach (var b in item.Op.Perform(item.Marks, p, item.Level, item.Brush)) {
if (b.Block == Block.Zero) 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)
lvl.blockCache.Add(bP);
int index = lvl.PosToInt(b.X, b.Y, b.Z);
lvl.AddToBlockDB(p, index, b.Block, b.ExtBlock, b.Block == 0);
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;
}
public void SetTile(ushort x, ushort y, ushort z, byte type, Player p, byte extType = 0) {
int b = PosToInt(x, y, z);
if (blocks == null || b < 0) return;
public void SetTile(ushort x, ushort y, ushort z, byte block, Player p, byte extBlock = 0) {
int index = PosToInt(x, y, z);
if (blocks == null || index < 0) return;
byte oldType = blocks[b];
blocks[b] = type;
byte oldExtType = 0;
byte oldBlock = blocks[index], oldExtBlock = 0;
blocks[index] = block;
changed = true;
if (oldType == Block.custom_block) {
oldExtType = GetExtTile(x, y, z);
if (type != Block.custom_block)
if (oldBlock == Block.custom_block) {
oldExtBlock = GetExtTile(x, y, z);
if (block != Block.custom_block)
RevertExtTileNoCheck(x, y, z);
}
if (type == Block.custom_block)
SetExtTileNoCheck(x, y, z, extType);
if (p == null)
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);
if (block == Block.custom_block)
SetExtTileNoCheck(x, y, z, extBlock);
if (p == null) return;
AddToBlockDB(p, index, block, extBlock, block == 0);
Player.UndoPos Pos;
Pos.x = x; Pos.y = y; Pos.z = z;
Pos.mapName = this.name;
Pos.type = oldType; Pos.extType = oldExtType;
Pos.newtype = type; Pos.newExtType = extType;
Pos.type = oldBlock; Pos.extType = oldExtBlock;
Pos.newtype = block; Pos.newExtType = extBlock;
Pos.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds;
p.UndoBuffer.Add(this, Pos);
}
bool CheckTNTWarsChange(Player p, ushort x, ushort y, ushort z, ref byte type) {
if (!(type == Block.tnt || type == Block.bigtnt || type == Block.nuketnt || type == Block.smalltnt))
bool CheckTNTWarsChange(Player p, ushort x, ushort y, ushort z, ref byte block) {
if (!(block == Block.tnt || block == Block.bigtnt || block == Block.nuketnt || block == Block.smalltnt))
return true;
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;
}
p.TntAtATime();
type = Block.smalltnt;
block = Block.smalltnt;
return true;
}
@ -440,18 +432,25 @@ namespace MCGalaxy {
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,
byte block, byte extBlock, bool drawn = false) {
if (!DoBlockchange(p, x, y, z, block, extBlock, drawn)) return;
BlockPos bP = default(BlockPos);
bP.name = p.name;
bP.index = PosToInt(x, y, z);
bP.SetData(block, extBlock, block == 0);
if (UseBlockDB)
blockCache.Add(bP);
int index = PosToInt(x, y, z);
AddToBlockDB(p, index, block, extBlock, block == 0);
if (bufferblocks)
BlockQueue.Addblock(p, bP.index, block, extBlock);
BlockQueue.Addblock(p, index, block, extBlock);
else
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<Zone> ZoneList;
public bool backedup;
internal readonly object blockCacheLock = new object();
public List<BlockPos> blockCache = new List<BlockPos>();
[ConfigBool("UseBlockDB", "Other", null, true)]
public bool UseBlockDB = true;

View File

@ -72,11 +72,6 @@ namespace MCGalaxy {
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;
if (Blockchange != null) {
Blockchange(this, x, y, z, block, extBlock); return;
@ -123,14 +118,14 @@ namespace MCGalaxy {
RevertBlock(x, y, z); return;
}
}
//else
int index = level.PosToInt(x, y, z);
if (!painting && action == 0) {
bP.flags |= 1;
if (DeleteBlock(old, x, y, z, block, extBlock) && level.UseBlockDB)
level.blockCache.Add(bP);
if (DeleteBlock(old, x, y, z, block, extBlock))
level.AddToBlockDB(this, index, block, extBlock, true);
} else {
if (PlaceBlock(old, x, y, z, block, extBlock) && level.UseBlockDB)
level.blockCache.Add(bP);
if (PlaceBlock(old, x, y, z, block, extBlock))
level.AddToBlockDB(this, index, block, extBlock, false);
}
}