diff --git a/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs b/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs
index 87a8d8726..53f9adc6e 100644
--- a/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs
+++ b/ClassicalSharp/Blocks/BlockInfo.BoundsBox.cs
@@ -1,114 +1,114 @@
-// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
-using System;
-using OpenTK;
-using ClassicalSharp;
-using BlockID = System.UInt16;
-
-namespace ClassicalSharp {
-
- /// Stores various properties about the blocks in Minecraft Classic.
- public static partial class BlockInfo {
-
- internal static void CalcRenderBounds(BlockID block) {
- Vector3 min = MinBB[block], max = MaxBB[block];
-
- if (IsLiquid[block]) {
- min.X -= 0.1f/16f; max.X -= 0.1f/16f;
- min.Z -= 0.1f/16f; max.Z -= 0.1f/16f;
- min.Y -= 1.5f/16f; max.Y -= 1.5f/16f;
- } else if (Draw[block] == DrawType.Translucent && Collide[block] != CollideType.Solid) {
- min.X += 0.1f/16f; max.X += 0.1f/16f;
- min.Z += 0.1f/16f; max.Z += 0.1f/16f;
- min.Y -= 0.1f/16f; max.Y -= 0.1f/16f;
- }
-
- RenderMinBB[block] = min; RenderMaxBB[block] = max;
- }
-
- internal static byte CalcLightOffset(BlockID block) {
- int flags = 0xFF;
- Vector3 min = MinBB[block], max = MaxBB[block];
-
- if (min.X != 0) flags &= ~(1 << Side.Left);
- if (max.X != 1) flags &= ~(1 << Side.Right);
- if (min.Z != 0) flags &= ~(1 << Side.Front);
- if (max.Z != 1) flags &= ~(1 << Side.Back);
-
- if ((min.Y != 0 && max.Y == 1) && Draw[block] != DrawType.Gas) {
- flags &= ~(1 << Side.Top);
- flags &= ~(1 << Side.Bottom);
- }
- return (byte)flags;
- }
-
- internal static void RecalculateSpriteBB() {
- using (FastBitmap fastBmp = new FastBitmap(TerrainAtlas2D.Atlas, true, true)) {
- for (int i = 0; i < Count; i++) {
- if (Draw[i] != DrawType.Sprite) continue;
- RecalculateBB((BlockID)i, fastBmp);
- }
- }
- }
-
- const float angle = 45f * Utils.Deg2Rad;
- static readonly Vector3 centre = new Vector3(0.5f, 0, 0.5f);
- internal static void RecalculateBB(BlockID block, FastBitmap fastBmp) {
- int elemSize = fastBmp.Width / 16;
- int texId = GetTextureLoc(block, Side.Right);
- int texX = texId & 0x0F, texY = texId >> 4;
-
- float topY = GetSpriteBB_TopY(elemSize, texX, texY, fastBmp);
- float bottomY = GetSpriteBB_BottomY(elemSize, texX, texY, fastBmp);
- float leftX = GetSpriteBB_LeftX(elemSize, texX, texY, fastBmp);
- float rightX = GetSpriteBB_RightX(elemSize, texX, texY, fastBmp);
-
- MinBB[block] = Utils.RotateY(leftX - 0.5f, bottomY, 0, angle) + centre;
- MaxBB[block] = Utils.RotateY(rightX - 0.5f, topY, 0, angle) + centre;
- CalcRenderBounds(block);
- }
-
- unsafe static float GetSpriteBB_TopY(int size, int tileX, int tileY, FastBitmap fastBmp) {
- for (int y = 0; y < size; y++) {
- int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size);
- for (int x = 0; x < size; x++) {
- if ((byte)(row[x] >> 24) != 0)
- return 1 - (float)y / size;
- }
- }
- return 0;
- }
-
- unsafe static float GetSpriteBB_BottomY(int size, int tileX, int tileY, FastBitmap fastBmp) {
- for (int y = size - 1; y >= 0; y--) {
- int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size);
- for (int x = 0; x < size; x++) {
- if ((byte)(row[x] >> 24) != 0)
- return 1 - (float)(y + 1) / size;
- }
- }
- return 1;
- }
-
- unsafe static float GetSpriteBB_LeftX(int size, int tileX, int tileY, FastBitmap fastBmp) {
- for (int x = 0; x < size; x++) {
- for (int y = 0; y < size; y++) {
- int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size);
- if ((byte)(row[x] >> 24) != 0)
- return (float)x / size;
- }
- }
- return 1;
- }
-
- unsafe static float GetSpriteBB_RightX(int size, int tileX, int tileY, FastBitmap fastBmp) {
- for (int x = size - 1; x >= 0; x--) {
- for (int y = 0; y < size; y++) {
- int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size);
- if ((byte)(row[x] >> 24) != 0)
- return (float)(x + 1) / size;
- }
- }
- return 0;
- }
- }
+// Copyright 2014-2017 ClassicalSharp | Licensed under BSD-3
+using System;
+using OpenTK;
+using ClassicalSharp;
+using BlockID = System.UInt16;
+
+namespace ClassicalSharp {
+
+ /// Stores various properties about the blocks in Minecraft Classic.
+ public static partial class BlockInfo {
+
+ internal static void CalcRenderBounds(BlockID block) {
+ Vector3 min = MinBB[block], max = MaxBB[block];
+
+ if (IsLiquid[block]) {
+ min.X -= 0.1f/16f; max.X -= 0.1f/16f;
+ min.Z -= 0.1f/16f; max.Z -= 0.1f/16f;
+ min.Y -= 1.5f/16f; max.Y -= 1.5f/16f;
+ } else if (Draw[block] == DrawType.Translucent && Collide[block] != CollideType.Solid) {
+ min.X += 0.1f/16f; max.X += 0.1f/16f;
+ min.Z += 0.1f/16f; max.Z += 0.1f/16f;
+ min.Y -= 0.1f/16f; max.Y -= 0.1f/16f;
+ }
+
+ RenderMinBB[block] = min; RenderMaxBB[block] = max;
+ }
+
+ internal static byte CalcLightOffset(BlockID block) {
+ int flags = 0xFF;
+ Vector3 min = MinBB[block], max = MaxBB[block];
+
+ if (min.X != 0) flags &= ~(1 << Side.Left);
+ if (max.X != 1) flags &= ~(1 << Side.Right);
+ if (min.Z != 0) flags &= ~(1 << Side.Front);
+ if (max.Z != 1) flags &= ~(1 << Side.Back);
+
+ if ((min.Y != 0 && max.Y == 1) && Draw[block] != DrawType.Gas) {
+ flags &= ~(1 << Side.Top);
+ flags &= ~(1 << Side.Bottom);
+ }
+ return (byte)flags;
+ }
+
+ internal static void RecalculateSpriteBB() {
+ using (FastBitmap fastBmp = new FastBitmap(TerrainAtlas2D.Atlas, true, true)) {
+ for (int i = 0; i < Count; i++) {
+ if (Draw[i] != DrawType.Sprite) continue;
+ RecalculateBB((BlockID)i, fastBmp);
+ }
+ }
+ }
+
+ const float angle = 45f * Utils.Deg2Rad;
+ static readonly Vector3 centre = new Vector3(0.5f, 0, 0.5f);
+ internal static void RecalculateBB(BlockID block, FastBitmap fastBmp) {
+ int elemSize = fastBmp.Width / 16;
+ int texId = GetTextureLoc(block, Side.Right);
+ int texX = texId & 0x0F, texY = texId >> 4;
+
+ float topY = GetSpriteBB_TopY(elemSize, texX, texY, fastBmp);
+ float bottomY = GetSpriteBB_BottomY(elemSize, texX, texY, fastBmp);
+ float leftX = GetSpriteBB_LeftX(elemSize, texX, texY, fastBmp);
+ float rightX = GetSpriteBB_RightX(elemSize, texX, texY, fastBmp);
+
+ MinBB[block] = Utils.RotateY(leftX - 0.5f, bottomY, 0, angle) + centre;
+ MaxBB[block] = Utils.RotateY(rightX - 0.5f, topY, 0, angle) + centre;
+ CalcRenderBounds(block);
+ }
+
+ unsafe static float GetSpriteBB_TopY(int size, int tileX, int tileY, FastBitmap fastBmp) {
+ for (int y = 0; y < size; y++) {
+ int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size);
+ for (int x = 0; x < size; x++) {
+ if ((byte)(row[x] >> 24) != 0)
+ return 1 - (float)y / size;
+ }
+ }
+ return 0;
+ }
+
+ unsafe static float GetSpriteBB_BottomY(int size, int tileX, int tileY, FastBitmap fastBmp) {
+ for (int y = size - 1; y >= 0; y--) {
+ int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size);
+ for (int x = 0; x < size; x++) {
+ if ((byte)(row[x] >> 24) != 0)
+ return 1 - (float)(y + 1) / size;
+ }
+ }
+ return 1;
+ }
+
+ unsafe static float GetSpriteBB_LeftX(int size, int tileX, int tileY, FastBitmap fastBmp) {
+ for (int x = 0; x < size; x++) {
+ for (int y = 0; y < size; y++) {
+ int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size);
+ if ((byte)(row[x] >> 24) != 0)
+ return (float)x / size;
+ }
+ }
+ return 1;
+ }
+
+ unsafe static float GetSpriteBB_RightX(int size, int tileX, int tileY, FastBitmap fastBmp) {
+ for (int x = size - 1; x >= 0; x--) {
+ for (int y = 0; y < size; y++) {
+ int* row = fastBmp.GetRowPtr(tileY * size + y) + (tileX * size);
+ if ((byte)(row[x] >> 24) != 0)
+ return (float)(x + 1) / size;
+ }
+ }
+ return 0;
+ }
+ }
}
\ No newline at end of file
diff --git a/ClassicalSharp/Entities/Components/HacksComponent.cs b/ClassicalSharp/Entities/Components/HacksComponent.cs
index 50af6558a..681a8849c 100644
--- a/ClassicalSharp/Entities/Components/HacksComponent.cs
+++ b/ClassicalSharp/Entities/Components/HacksComponent.cs
@@ -127,17 +127,18 @@ namespace ClassicalSharp.Entities {
/// Sets the user type of this user. This is used to control permissions for grass,
/// bedrock, water and lava blocks on servers that don't support CPE block permissions.
- public void SetUserType(byte value) {
+ public void SetUserType(byte value, bool setBlockPerms) {
bool isOp = value >= 100 && value <= 127;
UserType = value;
- BlockInfo.CanPlace[Block.Bedrock] = isOp;
- BlockInfo.CanDelete[Block.Bedrock] = isOp;
-
- BlockInfo.CanPlace[Block.Water] = isOp;
- BlockInfo.CanPlace[Block.StillWater] = isOp;
- BlockInfo.CanPlace[Block.Lava] = isOp;
- BlockInfo.CanPlace[Block.StillLava] = isOp;
CanSeeAllNames = isOp;
+ if (!setBlockPerms) return;
+
+ BlockInfo.CanPlace[Block.Bedrock] = isOp;
+ BlockInfo.CanDelete[Block.Bedrock] = isOp;
+ BlockInfo.CanPlace[Block.Water] = isOp;
+ BlockInfo.CanPlace[Block.StillWater] = isOp;
+ BlockInfo.CanPlace[Block.Lava] = isOp;
+ BlockInfo.CanPlace[Block.StillLava] = isOp;
}
/// Disables any hacks if their respective CanHackX value is set to false.
diff --git a/ClassicalSharp/Network/CPESupport.cs b/ClassicalSharp/Network/CPESupport.cs
index 81befcc27..2bb6e768a 100644
--- a/ClassicalSharp/Network/CPESupport.cs
+++ b/ClassicalSharp/Network/CPESupport.cs
@@ -14,7 +14,7 @@ namespace ClassicalSharp.Network {
internal int ServerExtensionsCount;
internal bool sendHeldBlock, useMessageTypes;
internal int envMapVer = 2, blockDefsExtVer = 2;
- internal bool needD3Fix, extEntityPos, twoWayPing;
+ internal bool needD3Fix, extEntityPos, twoWayPing, blockPerms;
public void Reset(Game game) {
ServerExtensionsCount = 0;
@@ -38,6 +38,8 @@ namespace ClassicalSharp.Network {
useMessageTypes = true;
} else if (ext == "ExtPlayerList") {
net.UsingExtPlayerList = true;
+ } else if (ext == "BlockPermissions") {
+ blockPerms = true;
} else if (ext == "PlayerClick") {
net.UsingPlayerClick = true;
} else if (ext == "EnvMapAppearance") {
diff --git a/ClassicalSharp/Network/Protocols/Classic.cs b/ClassicalSharp/Network/Protocols/Classic.cs
index 1c27de458..ab07dbfd7 100644
--- a/ClassicalSharp/Network/Protocols/Classic.cs
+++ b/ClassicalSharp/Network/Protocols/Classic.cs
@@ -59,7 +59,7 @@ namespace ClassicalSharp.Network.Protocols {
net.ServerMotd = reader.ReadString();
game.Chat.SetLogName(net.ServerName);
- game.LocalPlayer.Hacks.SetUserType(reader.ReadUInt8());
+ game.LocalPlayer.Hacks.SetUserType(reader.ReadUInt8(), !net.cpeData.blockPerms);
game.LocalPlayer.Hacks.HacksFlags = net.ServerName + net.ServerMotd;
game.LocalPlayer.Hacks.UpdateHacksState();
}
@@ -264,7 +264,7 @@ namespace ClassicalSharp.Network.Protocols {
}
void HandleSetPermission() {
- game.LocalPlayer.Hacks.SetUserType(reader.ReadUInt8());
+ game.LocalPlayer.Hacks.SetUserType(reader.ReadUInt8(), !net.cpeData.blockPerms);
game.LocalPlayer.Hacks.UpdateHacksState();
}
diff --git a/src/Client/EntityComponents.c b/src/Client/EntityComponents.c
index b108a8023..b9bdbf00d 100644
--- a/src/Client/EntityComponents.c
+++ b/src/Client/EntityComponents.c
@@ -221,10 +221,11 @@ void HacksComp_ParseAllFlag(HacksComp* hacks, const UInt8* incFlag, const UInt8*
}
}
-void HacksComp_SetUserType(HacksComp* hacks, UInt8 value) {
+void HacksComp_SetUserType(HacksComp* hacks, UInt8 value, bool setBlockPerms) {
bool isOp = value >= 100 && value <= 127;
hacks->UserType = value;
hacks->CanSeeAllNames = isOp;
+ if (!setBlockPerms) return;
Block_CanPlace[BLOCK_BEDROCK] = isOp;
Block_CanDelete[BLOCK_BEDROCK] = isOp;