Fix entries sometimes incorrectly being added to BlockDB.

This commit is contained in:
UnknownShadow200 2017-02-04 22:29:53 +11:00
parent fb563ff4c7
commit 5eb6f0a34b
4 changed files with 100 additions and 106 deletions

View File

@ -20,13 +20,13 @@ using MCGalaxy.Blocks.Physics;
namespace MCGalaxy.Blocks {
/// <summary> Returns whether this block handles the player placing a block at the given coordinates. </summary>
/// <remarks>If this returns true, the usual 'dirt/grass below' behaviour and 'adding to the BlockDB' is skipped. </remarks>
public delegate bool HandleDelete(Player p, byte oldBlock, ushort x, ushort y, ushort z);
/// <summary> Handles the player placing a block at the given coordinates. </summary>
/// <remarks> Use p.ChangeBlock to do a normal player block change (adds to BlockDB, updates dirt/grass beneath) </remarks>
public delegate void HandleDelete(Player p, byte oldBlock, ushort x, ushort y, ushort z);
/// <summary> Returns whether this block handles the player deleting a block at the given coordinates. </summary>
/// <remarks> If this returns true, the usual 'checking dirt/grass below' and 'adding to the BlockDB' is skipped. </remarks>
public delegate bool HandlePlace(Player p, byte oldBlock, ushort x, ushort y, ushort z);
/// <summary> Handles the player deleting a block at the given coordinates. </summary>
/// <remarks> Use p.ChangeBlock to do a normal player block change (adds to BlockDB, updates dirt/grass beneath) </remarks>
public delegate void HandlePlace(Player p, byte oldBlock, ushort x, ushort y, ushort z);
/// <summary> Returns whether this block handles the player walking through this block at the given coordinates. </summary>
/// <remarks> If this returns true, the usual 'death check' behaviour is skipped. </remarks>

View File

@ -23,8 +23,8 @@ namespace MCGalaxy.Blocks {
internal static class DeleteBehaviour {
internal static bool RocketStart(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.physics < 2 || p.level.physics == 5) { p.RevertBlock(x, y, z); return true; }
internal static void RocketStart(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.physics < 2 || p.level.physics == 5) { p.RevertBlock(x, y, z); return; }
int dx = 0, dy = 0, dz = 0;
p.RevertBlock(x, y, z);
@ -41,11 +41,10 @@ namespace MCGalaxy.Blocks {
p.level.Blockchange((ushort)( x + dx * 2 ), (ushort)( y + dy * 2 ), (ushort)( z + dz * 2 ), Block.rockethead);
p.level.Blockchange((ushort)( x + dx ), (ushort)( y + dy ), (ushort)( z + dz ), Block.lava_fire);
}
return true;
}
internal static bool Firework(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.physics == 0 || p.level.physics == 5) { p.RevertBlock(x, y, z); return true; }
internal static void Firework(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.physics == 0 || p.level.physics == 5) { p.RevertBlock(x, y, z); return; }
Random rand = new Random();
ushort x2 = (ushort)(x + rand.Next(0, 2) - 1);
@ -61,21 +60,19 @@ namespace MCGalaxy.Blocks {
args.Type2 = PhysicsArgs.Dissipate; args.Value2 = 100;
p.level.Blockchange(x2, (ushort)(y + 1), z2, Block.lavastill, false, args);
}
p.RevertBlock(x, y, z); return true;
}
internal static bool C4Det(Player p, byte block, ushort x, ushort y, ushort z) {
C4Physics.BlowUp(new ushort[] { x, y, z }, p.level);
p.ChangeBlock(x, y, z, Block.air, 0);
return false;
}
internal static bool RevertDoor(Player p, byte block, ushort x, ushort y, ushort z) {
p.RevertBlock(x, y, z);
return true;
}
internal static bool Door(Player p, byte block, ushort x, ushort y, ushort z) {
internal static void C4Det(Player p, byte block, ushort x, ushort y, ushort z) {
C4Physics.BlowUp(new ushort[] { x, y, z }, p.level);
p.ChangeBlock(x, y, z, Block.air, 0); // if block updated, return false so we add to blockdb
}
internal static void RevertDoor(Player p, byte block, ushort x, ushort y, ushort z) {
p.RevertBlock(x, y, z);
}
internal static void Door(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.physics != 0) {
bool isExt = false;
if (block == Block.custom_block) {
@ -89,44 +86,39 @@ namespace MCGalaxy.Blocks {
} else {
p.RevertBlock(x, y, z);
}
return true;
}
internal static bool ODoor(Player p, byte block, ushort x, ushort y, ushort z) {
internal static void ODoor(Player p, byte block, ushort x, ushort y, ushort z) {
if (block == Block.odoor8 || block == Block.odoor8_air) {
p.level.Blockchange(x, y, z, Block.Props[block].ODoorId, 0);
} else {
p.RevertBlock(x, y, z);
}
return true;
}
internal static bool DoPortal(Player p, byte block, ushort x, ushort y, ushort z) {
if (Portal.Handle(p, x, y, z)) return true;
internal static void DoPortal(Player p, byte block, ushort x, ushort y, ushort z) {
if (Portal.Handle(p, x, y, z)) return;
p.ChangeBlock(x, y, z, Block.air, 0);
return false;
}
internal static bool DoMessageBlock(Player p, byte block, ushort x, ushort y, ushort z) {
if (MessageBlock.Handle(p, x, y, z, true)) return true;
internal static void DoMessageBlock(Player p, byte block, ushort x, ushort y, ushort z) {
if (MessageBlock.Handle(p, x, y, z, true)) return;
p.ChangeBlock(x, y, z, Block.air, 0);
return false;
}
internal static bool CustomBlock(Player p, byte block, ushort x, ushort y, ushort z) {
internal static void CustomBlock(Player p, byte block, ushort x, ushort y, ushort z) {
byte extBlock = p.level.GetExtTile(x, y, z);
if (p.level.CustomBlockProps[extBlock].IsPortal) {
return DoPortal(p, block, x, y, z);
DoPortal(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsMessageBlock) {
return DoMessageBlock(p, block, x, y, z);
DoMessageBlock(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsTDoor) {
return RevertDoor(p, block, x, y, z);
RevertDoor(p, block, x, y, z);
} else if (p.level.CustomBlockProps[extBlock].IsDoor) {
return Door(p, block, x, y, z);
Door(p, block, x, y, z);
} else {
p.ChangeBlock(x, y, z, Block.air, 0);
}
p.ChangeBlock(x, y, z, Block.air, 0);
return false;
}
}
}

View File

@ -22,18 +22,18 @@ namespace MCGalaxy.Blocks {
internal static class PlaceBehaviour {
internal static bool Grass(Player p, byte block, ushort x, ushort y, ushort z) {
return DirtGrass(p, Block.grass, x, y, z);
internal static void Grass(Player p, byte block, ushort x, ushort y, ushort z) {
DirtGrass(p, Block.grass, x, y, z);
}
internal static bool Dirt(Player p, byte block, ushort x, ushort y, ushort z) {
return DirtGrass(p, Block.dirt, x, y, z);
internal static void Dirt(Player p, byte block, ushort x, ushort y, ushort z) {
DirtGrass(p, Block.dirt, x, y, z);
}
static bool DirtGrass(Player p, byte block, ushort x, ushort y, ushort z) {
static void DirtGrass(Player p, byte block, ushort x, ushort y, ushort z) {
Level lvl = p.level;
if (!lvl.GrassGrow || !(lvl.physics == 0 || lvl.physics == 5)) {
p.ChangeBlock(x, y, z, block, 0); return false;
p.ChangeBlock(x, y, z, block, 0); return;
}
byte above = lvl.GetTile(x, (ushort)(y + 1), z), extAbove = 0;
@ -43,51 +43,49 @@ namespace MCGalaxy.Blocks {
block = (above == Block.Invalid || Block.LightPass(above, extAbove, lvl.CustomBlockDefs))
? Block.grass : Block.dirt;
p.ChangeBlock(x, y, z, block, 0);
return false;
}
internal static bool Stairs(Player p, byte block, ushort x, ushort y, ushort z) {
internal static void Stairs(Player p, byte block, ushort x, ushort y, ushort z) {
if (!(p.level.physics == 0 || p.level.physics == 5)
|| p.level.GetTile(x, (ushort)(y - 1), z) != Block.staircasestep) {
p.ChangeBlock(x, y, z, Block.staircasestep, 0); return false;
p.ChangeBlock(x, y, z, Block.staircasestep, 0); return;
}
p.SendBlockchange(x, y, z, Block.air); //send the air block back only to the user.
p.SendBlockchange(x, y, z, Block.air); // send the air block back only to the user
p.ChangeBlock(x, (ushort)(y - 1), z, Block.staircasefull, 0);
return false;
}
internal static bool CobbleStairs(Player p, byte block, ushort x, ushort y, ushort z) {
internal static void CobbleStairs(Player p, byte block, ushort x, ushort y, ushort z) {
if (!(p.level.physics == 0 || p.level.physics == 5)
|| p.level.GetTile(x, (ushort)(y - 1), z) != Block.cobblestoneslab) {
p.ChangeBlock(x, y, z, Block.cobblestoneslab, 0); return false;
p.ChangeBlock(x, y, z, Block.cobblestoneslab, 0); return;
}
p.SendBlockchange(x, y, z, Block.air); //send the air block back only to the user.
p.SendBlockchange(x, y, z, Block.air); // send the air block back only to the user
p.ChangeBlock(x, (ushort)(y - 1), z, Block.stone, 0);
return false;
}
internal static bool C4(Player p, byte block, ushort x, ushort y, ushort z) {
internal static void C4(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.physics == 0 || p.level.physics == 5) {
p.RevertBlock(x, y, z); return false;
p.RevertBlock(x, y, z); return;
}
C4Data c4 = C4Physics.Find(p.level, p.c4circuitNumber);
if (c4 != null) c4.list.Add(p.level.PosToInt(x, y, z));
p.ChangeBlock(x, y, z, Block.c4, 0); return false;
p.ChangeBlock(x, y, z, Block.c4, 0);
}
internal static bool C4Det(Player p, byte block, ushort x, ushort y, ushort z) {
internal static void C4Det(Player p, byte block, ushort x, ushort y, ushort z) {
if (p.level.physics == 0 || p.level.physics == 5) {
p.c4circuitNumber = -1; p.RevertBlock(x, y, z); return false;
p.c4circuitNumber = -1;
p.RevertBlock(x, y, z); return;
}
C4Data c4 = C4Physics.Find(p.level, p.c4circuitNumber);
if (c4 != null) c4.detIndex = p.level.PosToInt(x, y, z);
p.c4circuitNumber = -1;
p.ChangeBlock(x, y, z, Block.c4det, 0); return false;
p.ChangeBlock(x, y, z, Block.c4det, 0);
}
}
}

View File

@ -48,9 +48,8 @@ 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), oldExt = 0;
if (old == Block.Invalid) return;
if (old == Block.custom_block) oldExt = level.GetExtTile(x, y, z);
byte oldB = level.GetTile(x, y, z);
if (oldB == Block.Invalid) return;
if (jailed || !agreed || !canBuild) { RevertBlock(x, y, z); return; }
if (level.IsMuseum && Blockchange == null) return;
@ -66,7 +65,7 @@ namespace MCGalaxy {
RevertBlock(x, y, z); return;
}
if (Server.zombie.Running && Server.zombie.HandlesManualChange(this, x, y, z, action, block, old))
if (Server.zombie.Running && Server.zombie.HandlesManualChange(this, x, y, z, action, block, oldB))
return;
if ( Server.lava.active && Server.lava.HasPlayer(this) && Server.lava.IsPlayerDead(this) ) {
@ -83,7 +82,7 @@ namespace MCGalaxy {
OnBlockChangeEvent.Call(this, x, y, z, block, extBlock);
if (cancelBlock) { cancelBlock = false; return; }
if (old >= Block.air_flood && old <= Block.air_door_air) {
if (oldB >= Block.air_flood && oldB <= Block.air_door_air) {
SendMessage("Block is active, you cannot disturb it.");
RevertBlock(x, y, z); return;
}
@ -104,35 +103,25 @@ namespace MCGalaxy {
}
}
if (!CheckManualChange(old, block, doDelete)) {
if (!CheckManualChange(oldB, block, doDelete)) {
RevertBlock(x, y, z); return;
}
byte blockRaw = block;
if (block < Block.CpeCount) block = bindings[block];
ushort flags = BlockDBFlags.ManualPlace;
if (painting && !doDelete) flags = BlockDBFlags.Painted;
//Ignores updating blocks that are the same and send block only to the player
byte newBlock = (painting || action == 1) ? block : (byte)0;
if (old == newBlock && (painting || blockRaw != block)) {
if (old != Block.custom_block || extBlock == level.GetExtTile(x, y, z)) {
byte newB = (painting || action == 1) ? block : Block.air;
if (oldB == newB && (painting || blockRaw != block)) {
if (oldB != Block.custom_block || extBlock == level.GetExtTile(x, y, z)) {
RevertBlock(x, y, z); return;
}
}
byte heldExt = 0;
byte heldBlock = GetActualHeldBlock(out heldExt);
if (doDelete) {
if (DeleteBlock(old, x, y, z, block, extBlock)) {
level.BlockDB.Cache.Add(this, x, y, z, flags,
old, oldExt, 0, 0);
}
DeleteBlock(oldB, x, y, z, block, extBlock);
} else {
if (PlaceBlock(old, x, y, z, block, extBlock)) {
level.BlockDB.Cache.Add(this, x, y, z, flags,
old, oldExt, heldBlock, heldExt);
}
PlaceBlock(oldB, x, y, z, block, extBlock);
}
}
@ -149,49 +138,64 @@ namespace MCGalaxy {
return true;
}
bool DeleteBlock(byte old, ushort x, ushort y, ushort z, byte block, byte extBlock) {
if (deleteMode) { return ChangeBlock(x, y, z, Block.air, 0); }
bool changed = true;
void DeleteBlock(byte old, ushort x, ushort y, ushort z, byte block, byte extBlock) {
if (deleteMode) { ChangeBlock(x, y, z, Block.air, 0); return; }
HandleDelete handler = BlockBehaviour.deleteHandlers[old];
if (handler != null) {
if (handler(this, old, x, y, z)) return false;
handler(this, old, x, y, z);
} else {
changed = ChangeBlock(x, y, z, Block.air, 0);
ChangeBlock(x, y, z, Block.air, 0);
}
bool autoDelete = level.GrassGrow && (level.physics == 0 || level.physics == 5);
if (autoDelete && level.GetTile(x, (ushort)(y - 1), z) == Block.dirt)
ChangeBlock(x, (ushort)(y - 1), z, Block.grass, 0);
return changed;
}
bool PlaceBlock(byte old, ushort x, ushort y, ushort z, byte block, byte extBlock) {
void PlaceBlock(byte old, ushort x, ushort y, ushort z, byte block, byte extBlock) {
if (modeType != 0) {
if (old == modeType) SendBlockchange(x, y, z, old);
else ChangeBlock(x, y, z, modeType, 0);
return true;
return;
}
HandlePlace handler = BlockBehaviour.placeHandlers[block];
if (handler != null) {
if (handler(this, old, x, y, z)) return false;
handler(this, old, x, y, z);
} else {
return ChangeBlock(x, y, z, block, extBlock);
ChangeBlock(x, y, z, block, extBlock);
}
}
/// <summary> Updates the block at the given position, mainly intended for manual changes by the player. </summary>
/// <remarks> Adds to the BlockDB. Also turns block below to grass/dirt depending on light. </remarks>
/// <returns> true if block was updated, false if not. </returns>
public bool ChangeBlock(ushort x, ushort y, ushort z, byte block, byte extBlock) {
byte old = level.GetTile(x, y, z), extOld = 0;
if (old == Block.custom_block) extOld = level.GetExtTile(x, y, z);
if (!level.DoBlockchange(this, x, y, z, block, extBlock)) return false;
Player.GlobalBlockchange(level, x, y, z, block, extBlock);
ushort flags = BlockDBFlags.ManualPlace;
if (painting && Replacable(old)) flags = BlockDBFlags.Painted;
level.BlockDB.Cache.Add(this, x, y, z, flags, old, extOld, block, extBlock);
bool autoGrass = level.GrassGrow && (level.physics == 0 || level.physics == 5);
if (!autoGrass) return true;
byte below = level.GetTile(x, (ushort)(y - 1), z);
if (below == Block.dirt && block == Block.air) {
level.Blockchange(this, x, (ushort)(y - 1), z, Block.grass);
}
if (below == Block.grass && !Block.LightPass(block, extBlock, level.CustomBlockDefs)) {
level.Blockchange(this, x, (ushort)(y - 1), z, Block.dirt);
}
return true;
}
/// <summary> Updates the block at the given position, also turning the block below to dirt if the block above blocks light. </summary>
internal bool ChangeBlock(ushort x, ushort y, ushort z, byte block, byte extBlock) {
if (!level.DoBlockchange(this, x, y, z, block, extBlock)) return false;
Player.GlobalBlockchange(level, x, y, z, block, extBlock);
if (level.GrassGrow && level.GetTile(x, (ushort)(y - 1), z) == Block.grass
&& !Block.LightPass(block, extBlock, level.CustomBlockDefs)) {
level.Blockchange(this, x, (ushort)(y - 1), z, Block.dirt);
}
return true;
static bool Replacable(byte block) {
block = Block.Convert(block);
return block == Block.air || (block >= Block.water && block <= Block.lavastill);
}
byte[] ProcessReceived(byte[] buffer) {