public void Blockchange(Player p, ushort x, ushort y, ushort z, byte type, byte extType = 0) { string errorLocation = "start"; retry: try { if (x < 0 || y < 0 || z < 0) return; if (x >= Width || y >= Height || z >= Length) return; byte b = GetTile(x, y, z), extB = 0; if (b == Block.custom_block) extB = GetExtTile(x, y, z); errorLocation = "Permission checking"; if (!CheckAffectPermissions(p, x, y, z, b, type, extType)) { p.RevertBlock(x, y, z); return; } if (b == Block.sponge && physics > 0 && type != Block.sponge) PhysSpongeRemoved(PosToInt(x, y, z)); if (b == Block.lava_sponge && physics > 0 && type != Block.lava_sponge) PhysSpongeRemoved(PosToInt(x, y, z), true); errorLocation = "Undo buffer filling"; Player.UndoPos Pos; Pos.x = x; Pos.y = y; Pos.z = z; Pos.mapName = name; Pos.type = b; Pos.extType = extB; Pos.newtype = type; Pos.newExtType = extType; Pos.timePlaced = DateTime.Now; p.UndoBuffer.Add(Pos); errorLocation = "Setting tile"; p.loginBlocks++; p.overallBlocks++; SetTile(x, y, z, type); if (b == Block.custom_block && type != Block.custom_block) RevertExtTileNoCheck(x, y, z); if (type == Block.custom_block) SetExtTileNoCheck(x, y, z, extType); errorLocation = "Block sending"; bool diffBlock = Block.Convert(b) != Block.Convert(type); if (!diffBlock && b == Block.custom_block) diffBlock = extType != extB; if (diffBlock && !Instant) Player.GlobalBlockchange(this, x, y, z, type, extType); errorLocation = "Growing grass"; if (GetTile(x, (ushort)(y - 1), z) == Block.grass && GrassDestroy && !Block.LightPass(type)) { Blockchange(p, x, (ushort)(y - 1), z, Block.dirt); } errorLocation = "Adding physics"; if (p.PlayingTntWars && type == Block.smalltnt) AddCheck(PosToInt(x, y, z), "", false, p); if (physics > 0) if (Block.Physics(type)) AddCheck(PosToInt(x, y, z), "", false, p); changed = true; backedup = false; } catch (OutOfMemoryException) { Player.SendMessage(p, "Undo buffer too big! Cleared!"); p.UndoBuffer.Clear(); goto retry; } catch (Exception e) { Server.ErrorLog(e); Chat.GlobalMessageOps(p.name + " triggered a non-fatal error on " + name); Chat.GlobalMessageOps("Error location: " + errorLocation); Server.s.Log(p.name + " triggered a non-fatal error on " + name); Server.s.Log("Error location: " + errorLocation); } }
/// <summary> Clears the block change handler, and reverts the block back /// to the existing one in the world. </summary> protected static void RevertAndClearState(Player p, ushort x, ushort y, ushort z) { p.ClearBlockchange(); p.RevertBlock(x, y, z); }
/// <summary> Returns: <br/> /// 0 - block change was not performed <br/> /// 1 - old block was same as new block visually (e.g. white to door_white)<br/> /// 2 - old block was different to new block visually </summary> /// <remarks> The return code can be used to avoid sending redundant block changes. </remarks> public int DoBlockchange(Player p, ushort x, ushort y, ushort z, BlockID block, bool drawn = false) { string errorLocation = "start"; try { if (x >= Width || y >= Height || z >= Length) { return(0); } BlockID old = GetBlock(x, y, z); errorLocation = "Permission checking"; if (!CheckAffect(p, x, y, z, old, block)) { p.RevertBlock(x, y, z); return(0); } if (old == block) { return(0); } if (old == Block.Sponge && physics > 0 && block != Block.Sponge) { OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), false); } if (old == Block.LavaSponge && physics > 0 && block != Block.LavaSponge) { OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), true); } p.SessionModified++; p.TotalModified++; if (drawn) { p.TotalDrawn++; } else if (block == Block.Air) { p.TotalDeleted++; } else { p.TotalPlaced++; } errorLocation = "Setting tile"; if (block >= Block.Extended) { #if TEN_BIT_BLOCKS SetTile(x, y, z, Block.ExtendedClass[block >> Block.ExtendedShift]); #else SetTile(x, y, z, Block.custom_block); #endif FastSetExtTile(x, y, z, (BlockRaw)block); } else { SetTile(x, y, z, (BlockRaw)block); if (old >= Block.Extended) { FastRevertExtTile(x, y, z); } } errorLocation = "Adding physics"; if (physics > 0 && ActivatesPhysics(block)) { AddCheck(PosToInt(x, y, z)); } Changed = true; backedup = false; return(Block.VisuallyEquals(old, block) ? 1 : 2); } catch (Exception e) { Logger.LogError(e); Chat.MessageOps(p.name + " triggered a non-fatal error on " + ColoredName + ", %Sat location: " + errorLocation); Logger.Log(LogType.Warning, "{0} triggered a non-fatal error on {1}, %Sat location: {2}", p.name, ColoredName, errorLocation); return(0); } }
/// <summary> Returns: <br/> /// 0 - block change was not performed <br/> /// 1 - old block was same as new block visually (e.g. white to door_white)<br/> /// 2 - old block was different to new block visually </summary> /// <remarks> The return code can be used to avoid sending redundant block changes. </remarks> public int DoBlockchange(Player p, ushort x, ushort y, ushort z, ExtBlock block, bool drawn = false) { string errorLocation = "start"; try { if (x >= Width || y >= Height || z >= Length) { return(0); } ExtBlock old = GetBlock(x, y, z); errorLocation = "Permission checking"; if (!CheckAffectPermissions(p, x, y, z, old, block)) { p.RevertBlock(x, y, z); return(0); } if (old == block) { return(0); } if (old.BlockID == Block.Sponge && physics > 0 && block.BlockID != Block.Sponge) { OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), false); } if (old.BlockID == Block.LavaSponge && physics > 0 && block.BlockID != Block.LavaSponge) { OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), true); } p.SessionModified++; p.TotalModified++; if (drawn) { p.TotalDrawn++; } else if (block.BlockID == Block.Air) { p.TotalDeleted++; } else { p.TotalPlaced++; } errorLocation = "Setting tile"; SetTile(x, y, z, block.BlockID); if (old.BlockID == Block.custom_block && block.BlockID != Block.custom_block) { RevertExtTileNoCheck(x, y, z); } if (block.BlockID == Block.custom_block) { SetExtTileNoCheck(x, y, z, block.ExtID); } errorLocation = "Adding physics"; if (p.PlayingTntWars && block.BlockID == Block.TNT_Small) { AddTntCheck(PosToInt(x, y, z), p); } if (physics > 0 && ActivatesPhysics(block)) { AddCheck(PosToInt(x, y, z)); } Changed = true; backedup = false; return(old.VisuallyEquals(block) ? 1 : 2); } catch (Exception e) { Logger.LogError(e); Chat.MessageOps(p.name + " triggered a non-fatal error on " + ColoredName + ", %Sat location: " + errorLocation); Logger.Log(LogType.Warning, "{0} triggered a non-fatal error on {1}, %Sat location: {2}", p.name, ColoredName, errorLocation); return(0); } }
protected static void RevertAndClearState(Player p, ushort x, ushort y, ushort z) { p.ClearBlockchange(); p.RevertBlock(x, y, z); }
public bool DoBlockchange(Player p, ushort x, ushort y, ushort z, byte block, byte extBlock = 0, bool drawn = false) { string errorLocation = "start"; retry: try { //if (x < 0 || y < 0 || z < 0) return; if (x >= Width || y >= Height || z >= Length) { return(false); } byte old = GetTile(x, y, z), extOld = 0; if (old == Block.custom_block) { extOld = GetExtTile(x, y, z); } errorLocation = "Permission checking"; if (!CheckAffectPermissions(p, x, y, z, old, block, extBlock)) { p.RevertBlock(x, y, z); return(false); } if (old == Block.sponge && physics > 0 && block != Block.sponge) { OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z)); } if (old == Block.lava_sponge && physics > 0 && block != Block.lava_sponge) { OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), true); } errorLocation = "Undo buffer filling"; Player.UndoPos Pos; Pos.x = x; Pos.y = y; Pos.z = z; Pos.mapName = name; Pos.type = old; Pos.extType = extOld; Pos.newtype = block; Pos.newExtType = extBlock; Pos.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; p.UndoBuffer.Add(this, Pos); errorLocation = "Setting tile"; p.IncrementBlockStats(block, drawn); SetTile(x, y, z, block); if (old == Block.custom_block && block != Block.custom_block) { RevertExtTileNoCheck(x, y, z); } if (block == Block.custom_block) { SetExtTileNoCheck(x, y, z, extBlock); } errorLocation = "Adding physics"; if (p.PlayingTntWars && block == Block.smalltnt) { AddTntCheck(PosToInt(x, y, z), p); } if (physics > 0 && ActivatesPhysics(block, extBlock)) { AddCheck(PosToInt(x, y, z)); } changed = true; backedup = false; bool diffBlock = old == Block.custom_block ? extOld != extBlock : Block.Convert(old) != Block.Convert(block); return(diffBlock); } catch (OutOfMemoryException) { Player.Message(p, "Undo buffer too big! Cleared!"); p.UndoBuffer.Clear(); p.RemoveInvalidUndos(); goto retry; } catch (Exception e) { Server.ErrorLog(e); Chat.MessageOps(p.name + " triggered a non-fatal error on " + ColoredName); Chat.MessageOps("Error location: " + errorLocation); Server.s.Log(p.name + " triggered a non-fatal error on " + ColoredName); Server.s.Log("Error location: " + errorLocation); return(false); } }
void Player_PlayerBlockChange(Player p, ushort x, ushort y, ushort z, byte type, byte extType) { if (started) { if (p.level == mainlevel && !blueteam.members.Contains(p) && !redteam.members.Contains(p)) { p.RevertBlock(x, y, z); Player.SendMessage(p, "You are not on a team!"); Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p); } if (p.level == mainlevel && blueteam.members.Contains(p) && x == redbase.x && y == redbase.y && z == redbase.z && mainlevel.GetTile(redbase.x, redbase.y, redbase.z) != Block.air) { Chat.GlobalMessageLevel(mainlevel, blueteam.color + p.name + " took the " + redteam.color + " red team's FLAG!"); GetPlayer(p).hasflag = true; } if (p.level == mainlevel && redteam.members.Contains(p) && x == bluebase.x && y == bluebase.y && z == bluebase.z && mainlevel.GetTile(bluebase.x, bluebase.y, bluebase.z) != Block.air) { Chat.GlobalMessageLevel(mainlevel, redteam.color + p.name + " took the " + blueteam.color + " blue team's FLAG"); GetPlayer(p).hasflag = true; } if (p.level == mainlevel && blueteam.members.Contains(p) && x == bluebase.x && y == bluebase.y && z == bluebase.z && mainlevel.GetTile(bluebase.x, bluebase.y, bluebase.z) != Block.air) { if (GetPlayer(p).hasflag) { Chat.GlobalMessageLevel(mainlevel, blueteam.color + p.name + " RETURNED THE FLAG!"); GetPlayer(p).hasflag = false; GetPlayer(p).cap++; GetPlayer(p).points += cappoint; blueteam.points++; mainlevel.Blockchange(redbase.x, redbase.y, redbase.z, Block.red); p.RevertBlock(x, y, z); Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p); if (blueteam.points >= maxpoints) { End(); return; } } else { Player.SendMessage(p, "You cant take your own flag!"); p.RevertBlock(x, y, z); Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p); } } if (p.level == mainlevel && redteam.members.Contains(p) && x == redbase.x && y == redbase.y && z == redbase.z && mainlevel.GetTile(redbase.x, redbase.y, redbase.z) != Block.air) { if (GetPlayer(p).hasflag) { Chat.GlobalMessageLevel(mainlevel, redteam.color + p.name + " RETURNED THE FLAG!"); GetPlayer(p).hasflag = false; GetPlayer(p).points += cappoint; GetPlayer(p).cap++; redteam.points++; mainlevel.Blockchange(bluebase.x, bluebase.y, bluebase.z, Block.blue); p.RevertBlock(x, y, z); Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p); if (redteam.points >= maxpoints) { End(); return; } } else { Player.SendMessage(p, "You cant take your own flag!"); p.RevertBlock(x, y, z); Plugin.CancelPlayerEvent(PlayerEvents.BlockChange, p); } } } }
internal bool DoBlockchange(Player p, ushort x, ushort y, ushort z, byte type, byte extType = 0) { string errorLocation = "start"; retry: try { //if (x < 0 || y < 0 || z < 0) return; if (x >= Width || y >= Height || z >= Length) { return(false); } byte b = GetTile(x, y, z), extB = 0; if (b == Block.custom_block) { extB = GetExtTile(x, y, z); } errorLocation = "Permission checking"; if (!CheckAffectPermissions(p, x, y, z, b, type, extType)) { p.RevertBlock(x, y, z); return(false); } if (b == Block.sponge && physics > 0 && type != Block.sponge) { OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z)); } if (b == Block.lava_sponge && physics > 0 && type != Block.lava_sponge) { OtherPhysics.DoSpongeRemoved(this, PosToInt(x, y, z), true); } errorLocation = "Undo buffer filling"; Player.UndoPos Pos; Pos.x = x; Pos.y = y; Pos.z = z; Pos.mapName = name; Pos.type = b; Pos.extType = extB; Pos.newtype = type; Pos.newExtType = extType; Pos.timeDelta = (int)DateTime.UtcNow.Subtract(Server.StartTime).TotalSeconds; p.UndoBuffer.Add(this, Pos); errorLocation = "Setting tile"; p.loginBlocks++; p.overallBlocks++; SetTile(x, y, z, type); if (b == Block.custom_block && type != Block.custom_block) { RevertExtTileNoCheck(x, y, z); } if (type == Block.custom_block) { SetExtTileNoCheck(x, y, z, extType); } errorLocation = "Adding physics"; if (p.PlayingTntWars && type == Block.smalltnt) { AddTntCheck(PosToInt(x, y, z), p); } if (physics > 0 && Block.Physics(type)) { AddCheck(PosToInt(x, y, z)); } changed = true; backedup = false; bool diffBlock = b == Block.custom_block ? extB != extType : Block.Convert(b) != Block.Convert(type); return(diffBlock); } catch (OutOfMemoryException) { Player.SendMessage(p, "Undo buffer too big! Cleared!"); p.UndoBuffer.Clear(); p.RemoveInvalidUndos(); goto retry; } catch (Exception e) { Server.ErrorLog(e); Chat.GlobalMessageOps(p.name + " triggered a non-fatal error on " + name); Chat.GlobalMessageOps("Error location: " + errorLocation); Server.s.Log(p.name + " triggered a non-fatal error on " + name); Server.s.Log("Error location: " + errorLocation); return(false); } }