From 32b38fb2649fb282b6446c4e544866c0161aa7da Mon Sep 17 00:00:00 2001 From: mohe2015 Date: Sun, 6 Nov 2016 19:30:19 +0100 Subject: Anticheat fastbreak (#3411) Added block hardness checks when breaking blocks. --- Server/Plugins/APIDump/APIDesc.lua | 1818 ++++++++++++++++++++++++++++++++++++ src/BlockID.h | 30 +- src/BlockInfo.cpp | 199 ++++ src/BlockInfo.h | 5 + src/ClientHandle.cpp | 27 + src/ClientHandle.h | 6 + src/Defines.h | 301 ++++++ src/Entities/Pawn.cpp | 21 + src/Entities/Pawn.h | 6 + src/Entities/Player.cpp | 92 ++ src/Entities/Player.h | 21 + src/Items/CMakeLists.txt | 1 + src/Items/ItemAxe.h | 48 + src/Items/ItemHandler.cpp | 20 + src/Items/ItemHandler.h | 4 + src/Items/ItemPickaxe.h | 23 + src/Items/ItemShears.h | 22 + src/Items/ItemShovel.h | 31 + src/Items/ItemSword.h | 28 + src/Root.cpp | 3 + 20 files changed, 2702 insertions(+), 4 deletions(-) create mode 100644 src/Items/ItemAxe.h diff --git a/Server/Plugins/APIDump/APIDesc.lua b/Server/Plugins/APIDump/APIDesc.lua index 79cb2c8e3..a32bec2e8 100644 --- a/Server/Plugins/APIDump/APIDesc.lua +++ b/Server/Plugins/APIDump/APIDesc.lua @@ -2064,6 +2064,24 @@ return }, Notes = "Returns the {{cBlockInfo}} structure for the specified block type.", }, + GetHardness = + { + IsStatic = true, + Params = + { + { + Name = "BlockType", + Type = "number", + }, + }, + Returns = + { + { + Type = "number", + }, + }, + Notes = "Returns the block's hardness. The bigger the harder the block.", + }, GetBlockHeight = { IsStatic = true, @@ -14489,6 +14507,1806 @@ end }, Constants = { + E_BLOCK_ACACIA_DOOR = + { + Notes = "The blocktype for acacia door" + }, + E_BLOCK_ACACIA_FENCE = + { + Notes = "The blocktype for acacia fence" + }, + E_BLOCK_ACACIA_FENCE_GATE = + { + Notes = "The blocktype for acacia fence gate" + }, + E_BLOCK_ACACIA_WOOD_STAIRS = + { + Notes = "The blocktype for acacia wood stairs" + }, + E_BLOCK_ACTIVATOR_RAIL = + { + Notes = "The blocktype for activator rail" + }, + E_BLOCK_ACTIVE_COMPARATOR = + { + Notes = "The blocktype for active comparator" + }, + E_BLOCK_AIR = + { + Notes = "The blocktype for air" + }, + E_BLOCK_ANVIL = + { + Notes = "The blocktype for anvil" + }, + E_BLOCK_ANVIL_HIGH_DAMAGE = + { + Notes = "The blocktype for anvil high damage" + }, + E_BLOCK_ANVIL_LOW_DAMAGE = + { + Notes = "The blocktype for anvil low damage" + }, + E_BLOCK_ANVIL_NO_DAMAGE = + { + Notes = "The blocktype for anvil no damage" + }, + E_BLOCK_ANVIL_X = + { + Notes = "The blocktype for anvil x" + }, + E_BLOCK_ANVIL_Z = + { + Notes = "The blocktype for anvil z" + }, + E_BLOCK_BARRIER = + { + Notes = "The blocktype for barrier" + }, + E_BLOCK_BEACON = + { + Notes = "The blocktype for beacon" + }, + E_BLOCK_BED = + { + Notes = "The blocktype for bed" + }, + E_BLOCK_BEDROCK = + { + Notes = "The blocktype for bedrock" + }, + E_BLOCK_BED_BED_HEAD = + { + Notes = "The blocktype for bed bed head" + }, + E_BLOCK_BED_OCCUPIED = + { + Notes = "The blocktype for bed occupied" + }, + E_BLOCK_BED_XM = + { + Notes = "The blocktype for bed xm" + }, + E_BLOCK_BED_XP = + { + Notes = "The blocktype for bed xp" + }, + E_BLOCK_BED_ZM = + { + Notes = "The blocktype for bed zm" + }, + E_BLOCK_BED_ZP = + { + Notes = "The blocktype for bed zp" + }, + E_BLOCK_BEETROOTS = + { + Notes = "The blocktype for beetroots" + }, + E_BLOCK_BIG_FLOWER = + { + Notes = "The blocktype for big flower" + }, + E_BLOCK_BIRCH_DOOR = + { + Notes = "The blocktype for birch door" + }, + E_BLOCK_BIRCH_FENCE = + { + Notes = "The blocktype for birch fence" + }, + E_BLOCK_BIRCH_FENCE_GATE = + { + Notes = "The blocktype for birch fence gate" + }, + E_BLOCK_BIRCH_WOOD_STAIRS = + { + Notes = "The blocktype for birch wood stairs" + }, + E_BLOCK_BLOCK_OF_COAL = + { + Notes = "The blocktype for block of coal" + }, + E_BLOCK_BLOCK_OF_REDSTONE = + { + Notes = "The blocktype for block of redstone" + }, + E_BLOCK_BONE_BLOCK = + { + Notes = "The blocktype for bone block" + }, + E_BLOCK_BOOKCASE = + { + Notes = "The blocktype for bookcase" + }, + E_BLOCK_BREWING_STAND = + { + Notes = "The blocktype for brewing stand" + }, + E_BLOCK_BRICK = + { + Notes = "The blocktype for brick" + }, + E_BLOCK_BRICK_STAIRS = + { + Notes = "The blocktype for brick stairs" + }, + E_BLOCK_BROWN_MUSHROOM = + { + Notes = "The blocktype for brown mushroom" + }, + E_BLOCK_BURNING_FURNACE = + { + Notes = "The blocktype for burning furnace" + }, + E_BLOCK_BUTTON_PRESSED = + { + Notes = "The blocktype for button pressed" + }, + E_BLOCK_BUTTON_XM = + { + Notes = "The blocktype for button xm" + }, + E_BLOCK_BUTTON_XP = + { + Notes = "The blocktype for button xp" + }, + E_BLOCK_BUTTON_YM = + { + Notes = "The blocktype for button ym" + }, + E_BLOCK_BUTTON_YP = + { + Notes = "The blocktype for button yp" + }, + E_BLOCK_BUTTON_ZM = + { + Notes = "The blocktype for button zm" + }, + E_BLOCK_BUTTON_ZP = + { + Notes = "The blocktype for button zp" + }, + E_BLOCK_CACTUS = + { + Notes = "The blocktype for cactus" + }, + E_BLOCK_CAKE = + { + Notes = "The blocktype for cake" + }, + E_BLOCK_CARPET = + { + Notes = "The blocktype for carpet" + }, + E_BLOCK_CARROTS = + { + Notes = "The blocktype for carrots" + }, + E_BLOCK_CAULDRON = + { + Notes = "The blocktype for cauldron" + }, + E_BLOCK_CHAIN_COMMAND_BLOCK = + { + Notes = "The blocktype for chain command block" + }, + E_BLOCK_CHEST = + { + Notes = "The blocktype for chest" + }, + E_BLOCK_CHORUS_FLOWER = + { + Notes = "The blocktype for chorus flower" + }, + E_BLOCK_CHORUS_PLANT = + { + Notes = "The blocktype for chorus plant" + }, + E_BLOCK_CLAY = + { + Notes = "The blocktype for clay" + }, + E_BLOCK_COAL_ORE = + { + Notes = "The blocktype for coal ore" + }, + E_BLOCK_COBBLESTONE = + { + Notes = "The blocktype for cobblestone" + }, + E_BLOCK_COBBLESTONE_STAIRS = + { + Notes = "The blocktype for cobblestone stairs" + }, + E_BLOCK_COBBLESTONE_WALL = + { + Notes = "The blocktype for cobblestone wall" + }, + E_BLOCK_COBWEB = + { + Notes = "The blocktype for cobweb" + }, + E_BLOCK_COCOA_POD = + { + Notes = "The blocktype for cocoa pod" + }, + E_BLOCK_COMMAND_BLOCK = + { + Notes = "The blocktype for command block" + }, + E_BLOCK_CRAFTING_TABLE = + { + Notes = "The blocktype for crafting table" + }, + E_BLOCK_CROPS = + { + Notes = "The blocktype for crops" + }, + E_BLOCK_DANDELION = + { + Notes = "The blocktype for dandelion" + }, + E_BLOCK_DARK_OAK_DOOR = + { + Notes = "The blocktype for dark oak door" + }, + E_BLOCK_DARK_OAK_FENCE = + { + Notes = "The blocktype for dark oak fence" + }, + E_BLOCK_DARK_OAK_FENCE_GATE = + { + Notes = "The blocktype for dark oak fence gate" + }, + E_BLOCK_DARK_OAK_WOOD_STAIRS = + { + Notes = "The blocktype for dark oak wood stairs" + }, + E_BLOCK_DAYLIGHT_SENSOR = + { + Notes = "The blocktype for daylight sensor" + }, + E_BLOCK_DEAD_BUSH = + { + Notes = "The blocktype for dead bush" + }, + E_BLOCK_DETECTOR_RAIL = + { + Notes = "The blocktype for detector rail" + }, + E_BLOCK_DIAMOND_BLOCK = + { + Notes = "The blocktype for diamond block" + }, + E_BLOCK_DIAMOND_ORE = + { + Notes = "The blocktype for diamond ore" + }, + E_BLOCK_DIRT = + { + Notes = "The blocktype for dirt" + }, + E_BLOCK_DISPENSER = + { + Notes = "The blocktype for dispenser" + }, + E_BLOCK_DOUBLE_RED_SANDSTONE_SLAB = + { + Notes = "The blocktype for double red sandstone slab" + }, + E_BLOCK_DOUBLE_STONE_SLAB = + { + Notes = "The blocktype for double stone slab" + }, + E_BLOCK_DOUBLE_WOODEN_SLAB = + { + Notes = "The blocktype for double wooden slab" + }, + E_BLOCK_DRAGON_EGG = + { + Notes = "The blocktype for dragon egg" + }, + E_BLOCK_DROPPER = + { + Notes = "The blocktype for dropper" + }, + E_BLOCK_EMERALD_BLOCK = + { + Notes = "The blocktype for emerald block" + }, + E_BLOCK_EMERALD_ORE = + { + Notes = "The blocktype for emerald ore" + }, + E_BLOCK_ENCHANTMENT_TABLE = + { + Notes = "The blocktype for enchantment table" + }, + E_BLOCK_ENDER_CHEST = + { + Notes = "The blocktype for ender chest" + }, + E_BLOCK_END_BRICKS = + { + Notes = "The blocktype for end bricks" + }, + E_BLOCK_END_GATEWAY = + { + Notes = "The blocktype for end gateway" + }, + E_BLOCK_END_PORTAL = + { + Notes = "The blocktype for end portal" + }, + E_BLOCK_END_PORTAL_FRAME = + { + Notes = "The blocktype for end portal frame" + }, + E_BLOCK_END_ROD = + { + Notes = "The blocktype for end rod" + }, + E_BLOCK_END_STONE = + { + Notes = "The blocktype for end stone" + }, + E_BLOCK_FARMLAND = + { + Notes = "The blocktype for farmland" + }, + E_BLOCK_FENCE = + { + Notes = "The blocktype for fence" + }, + E_BLOCK_FENCE_GATE = + { + Notes = "The blocktype for fence gate" + }, + E_BLOCK_FIRE = + { + Notes = "The blocktype for fire" + }, + E_BLOCK_FLOWER = + { + Notes = "The blocktype for flower" + }, + E_BLOCK_FLOWER_POT = + { + Notes = "The blocktype for flower pot" + }, + E_BLOCK_FROSTED_ICE = + { + Notes = "The blocktype for frosted ice" + }, + E_BLOCK_FURNACE = + { + Notes = "The blocktype for furnace" + }, + E_BLOCK_GLASS = + { + Notes = "The blocktype for glass" + }, + E_BLOCK_GLASS_PANE = + { + Notes = "The blocktype for glass pane" + }, + E_BLOCK_GLOWSTONE = + { + Notes = "The blocktype for glowstone" + }, + E_BLOCK_GOLD_BLOCK = + { + Notes = "The blocktype for gold block" + }, + E_BLOCK_GOLD_ORE = + { + Notes = "The blocktype for gold ore" + }, + E_BLOCK_GRASS = + { + Notes = "The blocktype for grass" + }, + E_BLOCK_GRASS_PATH = + { + Notes = "The blocktype for grass path" + }, + E_BLOCK_GRAVEL = + { + Notes = "The blocktype for gravel" + }, + E_BLOCK_HARDENED_CLAY = + { + Notes = "The blocktype for hardened clay" + }, + E_BLOCK_HAY_BALE = + { + Notes = "The blocktype for hay bale" + }, + E_BLOCK_HEAD = + { + Notes = "The blocktype for head" + }, + E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE = + { + Notes = "The blocktype for heavy weighted pressure plate" + }, + E_BLOCK_HOPPER = + { + Notes = "The blocktype for hopper" + }, + E_BLOCK_HUGE_BROWN_MUSHROOM = + { + Notes = "The blocktype for huge brown mushroom" + }, + E_BLOCK_HUGE_RED_MUSHROOM = + { + Notes = "The blocktype for huge red mushroom" + }, + E_BLOCK_ICE = + { + Notes = "The blocktype for ice" + }, + E_BLOCK_INACTIVE_COMPARATOR = + { + Notes = "The blocktype for inactive comparator" + }, + E_BLOCK_INVERTED_DAYLIGHT_SENSOR = + { + Notes = "The blocktype for inverted daylight sensor" + }, + E_BLOCK_IRON_BARS = + { + Notes = "The blocktype for iron bars" + }, + E_BLOCK_IRON_BLOCK = + { + Notes = "The blocktype for iron block" + }, + E_BLOCK_IRON_DOOR = + { + Notes = "The blocktype for iron door" + }, + E_BLOCK_IRON_ORE = + { + Notes = "The blocktype for iron ore" + }, + E_BLOCK_IRON_TRAPDOOR = + { + Notes = "The blocktype for iron trapdoor" + }, + E_BLOCK_JACK_O_LANTERN = + { + Notes = "The blocktype for jack o lantern" + }, + E_BLOCK_JUKEBOX = + { + Notes = "The blocktype for jukebox" + }, + E_BLOCK_JUNGLE_DOOR = + { + Notes = "The blocktype for jungle door" + }, + E_BLOCK_JUNGLE_FENCE = + { + Notes = "The blocktype for jungle fence" + }, + E_BLOCK_JUNGLE_FENCE_GATE = + { + Notes = "The blocktype for jungle fence gate" + }, + E_BLOCK_JUNGLE_WOOD_STAIRS = + { + Notes = "The blocktype for jungle wood stairs" + }, + E_BLOCK_LADDER = + { + Notes = "The blocktype for ladder" + }, + E_BLOCK_LAPIS_BLOCK = + { + Notes = "The blocktype for lapis block" + }, + E_BLOCK_LAPIS_ORE = + { + Notes = "The blocktype for lapis ore" + }, + E_BLOCK_LAVA = + { + Notes = "The blocktype for lava" + }, + E_BLOCK_LEAVES = + { + Notes = "The blocktype for leaves" + }, + E_BLOCK_LEVER = + { + Notes = "The blocktype for lever" + }, + E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE = + { + Notes = "The blocktype for light weighted pressure plate" + }, + E_BLOCK_LILY_PAD = + { + Notes = "The blocktype for lily pad" + }, + E_BLOCK_LIT_FURNACE = + { + Notes = "The blocktype for lit furnace" + }, + E_BLOCK_LOG = + { + Notes = "The blocktype for log" + }, + E_BLOCK_MAGMA = + { + Notes = "The blocktype for magma" + }, + E_BLOCK_MAX_TYPE_ID = + { + Notes = "The blocktype for max type id" + }, + E_BLOCK_MELON = + { + Notes = "The blocktype for melon" + }, + E_BLOCK_MELON_STEM = + { + Notes = "The blocktype for melon stem" + }, + E_BLOCK_MINECART_TRACKS = + { + Notes = "The blocktype for minecart tracks" + }, + E_BLOCK_MOB_SPAWNER = + { + Notes = "The blocktype for mob spawner" + }, + E_BLOCK_MOSSY_COBBLESTONE = + { + Notes = "The blocktype for mossy cobblestone" + }, + E_BLOCK_MYCELIUM = + { + Notes = "The blocktype for mycelium" + }, + E_BLOCK_NETHERRACK = + { + Notes = "The blocktype for netherrack" + }, + E_BLOCK_NETHER_BRICK = + { + Notes = "The blocktype for nether brick" + }, + E_BLOCK_NETHER_BRICK_FENCE = + { + Notes = "The blocktype for nether brick fence" + }, + E_BLOCK_NETHER_BRICK_STAIRS = + { + Notes = "The blocktype for nether brick stairs" + }, + E_BLOCK_NETHER_PORTAL = + { + Notes = "The blocktype for nether portal" + }, + E_BLOCK_NETHER_QUARTZ_ORE = + { + Notes = "The blocktype for nether quartz ore" + }, + E_BLOCK_NETHER_WART = + { + Notes = "The blocktype for nether wart" + }, + E_BLOCK_NETHER_WART_BLOCK = + { + Notes = "The blocktype for nether wart block" + }, + E_BLOCK_NEW_LEAVES = + { + Notes = "The blocktype for new leaves" + }, + E_BLOCK_NEW_LOG = + { + Notes = "The blocktype for new log" + }, + E_BLOCK_NOTE_BLOCK = + { + Notes = "The blocktype for note block" + }, + E_BLOCK_NUMBER_OF_TYPES = + { + Notes = "The blocktype for number of types" + }, + E_BLOCK_OAK_DOOR = + { + Notes = "The blocktype for oak door" + }, + E_BLOCK_OAK_FENCE_GATE = + { + Notes = "The blocktype for oak fence gate" + }, + E_BLOCK_OAK_WOOD_STAIRS = + { + Notes = "The blocktype for oak wood stairs" + }, + E_BLOCK_OBSIDIAN = + { + Notes = "The blocktype for obsidian" + }, + E_BLOCK_PACKED_ICE = + { + Notes = "The blocktype for packed ice" + }, + E_BLOCK_PISTON = + { + Notes = "The blocktype for piston" + }, + E_BLOCK_PISTON_EXTENSION = + { + Notes = "The blocktype for piston extension" + }, + E_BLOCK_PISTON_MOVED_BLOCK = + { + Notes = "The blocktype for piston moved block" + }, + E_BLOCK_PLANKS = + { + Notes = "The blocktype for planks" + }, + E_BLOCK_POTATOES = + { + Notes = "The blocktype for potatoes" + }, + E_BLOCK_POWERED_RAIL = + { + Notes = "The blocktype for powered rail" + }, + E_BLOCK_PRISMARINE_BLOCK = + { + Notes = "The blocktype for prismarine block" + }, + E_BLOCK_PUMPKIN = + { + Notes = "The blocktype for pumpkin" + }, + E_BLOCK_PUMPKIN_STEM = + { + Notes = "The blocktype for pumpkin stem" + }, + E_BLOCK_PURPUR_BLOCK = + { + Notes = "The blocktype for purpur block" + }, + E_BLOCK_PURPUR_DOUBLE_SLAB = + { + Notes = "The blocktype for purpur double slab" + }, + E_BLOCK_PURPUR_PILLAR = + { + Notes = "The blocktype for purpur pillar" + }, + E_BLOCK_PURPUR_SLAB = + { + Notes = "The blocktype for purpur slab" + }, + E_BLOCK_PURPUR_STAIRS = + { + Notes = "The blocktype for purpur stairs" + }, + E_BLOCK_QUARTZ_BLOCK = + { + Notes = "The blocktype for quartz block" + }, + E_BLOCK_QUARTZ_STAIRS = + { + Notes = "The blocktype for quartz stairs" + }, + E_BLOCK_RAIL = + { + Notes = "The blocktype for rail" + }, + E_BLOCK_REDSTONE_LAMP_OFF = + { + Notes = "The blocktype for redstone lamp off" + }, + E_BLOCK_REDSTONE_LAMP_ON = + { + Notes = "The blocktype for redstone lamp on" + }, + E_BLOCK_REDSTONE_ORE = + { + Notes = "The blocktype for redstone ore" + }, + E_BLOCK_REDSTONE_ORE_GLOWING = + { + Notes = "The blocktype for redstone ore glowing" + }, + E_BLOCK_REDSTONE_REPEATER_OFF = + { + Notes = "The blocktype for redstone repeater off" + }, + E_BLOCK_REDSTONE_REPEATER_ON = + { + Notes = "The blocktype for redstone repeater on" + }, + E_BLOCK_REDSTONE_TORCH_OFF = + { + Notes = "The blocktype for redstone torch off" + }, + E_BLOCK_REDSTONE_TORCH_ON = + { + Notes = "The blocktype for redstone torch on" + }, + E_BLOCK_REDSTONE_WIRE = + { + Notes = "The blocktype for redstone wire" + }, + E_BLOCK_RED_MUSHROOM = + { + Notes = "The blocktype for red mushroom" + }, + E_BLOCK_RED_NETHER_BRICK = + { + Notes = "The blocktype for red nether brick" + }, + E_BLOCK_RED_ROSE = + { + Notes = "The blocktype for red rose" + }, + E_BLOCK_RED_SANDSTONE = + { + Notes = "The blocktype for red sandstone" + }, + E_BLOCK_RED_SANDSTONE_SLAB = + { + Notes = "The blocktype for red sandstone slab" + }, + E_BLOCK_RED_SANDSTONE_STAIRS = + { + Notes = "The blocktype for red sandstone stairs" + }, + E_BLOCK_REEDS = + { + Notes = "The blocktype for reeds" + }, + E_BLOCK_REPEATING_COMMAND_BLOCK = + { + Notes = "The blocktype for repeating command block" + }, + E_BLOCK_SAND = + { + Notes = "The blocktype for sand" + }, + E_BLOCK_SANDSTONE = + { + Notes = "The blocktype for sandstone" + }, + E_BLOCK_SANDSTONE_STAIRS = + { + Notes = "The blocktype for sandstone stairs" + }, + E_BLOCK_SAPLING = + { + Notes = "The blocktype for sapling" + }, + E_BLOCK_SEA_LANTERN = + { + Notes = "The blocktype for sea lantern" + }, + E_BLOCK_SIGN_POST = + { + Notes = "The blocktype for sign post" + }, + E_BLOCK_SILVERFISH_EGG = + { + Notes = "The blocktype for silverfish egg" + }, + E_BLOCK_SLIME_BLOCK = + { + Notes = "The blocktype for slime block" + }, + E_BLOCK_SNOW = + { + Notes = "The blocktype for snow" + }, + E_BLOCK_SNOW_BLOCK = + { + Notes = "The blocktype for snow block" + }, + E_BLOCK_SOULSAND = + { + Notes = "The blocktype for soulsand" + }, + E_BLOCK_SPONGE = + { + Notes = "The blocktype for sponge" + }, + E_BLOCK_SPRUCE_DOOR = + { + Notes = "The blocktype for spruce door" + }, + E_BLOCK_SPRUCE_FENCE = + { + Notes = "The blocktype for spruce fence" + }, + E_BLOCK_SPRUCE_FENCE_GATE = + { + Notes = "The blocktype for spruce fence gate" + }, + E_BLOCK_SPRUCE_WOOD_STAIRS = + { + Notes = "The blocktype for spruce wood stairs" + }, + E_BLOCK_STAINED_CLAY = + { + Notes = "The blocktype for stained clay" + }, + E_BLOCK_STAINED_GLASS = + { + Notes = "The blocktype for stained glass" + }, + E_BLOCK_STAINED_GLASS_PANE = + { + Notes = "The blocktype for stained glass pane" + }, + E_BLOCK_STAIRS_UPSIDE_DOWN = + { + Notes = "The blocktype for stairs upside down" + }, + E_BLOCK_STAIRS_XM = + { + Notes = "The blocktype for stairs xm" + }, + E_BLOCK_STAIRS_XP = + { + Notes = "The blocktype for stairs xp" + }, + E_BLOCK_STAIRS_ZM = + { + Notes = "The blocktype for stairs zm" + }, + E_BLOCK_STAIRS_ZP = + { + Notes = "The blocktype for stairs zp" + }, + E_BLOCK_STANDING_BANNER = + { + Notes = "The blocktype for standing banner" + }, + E_BLOCK_STATIONARY_LAVA = + { + Notes = "The blocktype for stationary lava" + }, + E_BLOCK_STATIONARY_WATER = + { + Notes = "The blocktype for stationary water" + }, + E_BLOCK_STICKY_PISTON = + { + Notes = "The blocktype for sticky piston" + }, + E_BLOCK_STONE = + { + Notes = "The blocktype for stone" + }, + E_BLOCK_STONE_BRICKS = + { + Notes = "The blocktype for stone bricks" + }, + E_BLOCK_STONE_BRICK_STAIRS = + { + Notes = "The blocktype for stone brick stairs" + }, + E_BLOCK_STONE_BUTTON = + { + Notes = "The blocktype for stone button" + }, + E_BLOCK_STONE_PRESSURE_PLATE = + { + Notes = "The blocktype for stone pressure plate" + }, + E_BLOCK_STONE_SLAB = + { + Notes = "The blocktype for stone slab" + }, + E_BLOCK_STRUCTURE_BLOCK = + { + Notes = "The blocktype for structure block" + }, + E_BLOCK_STRUCTURE_VOID = + { + Notes = "The blocktype for structure void" + }, + E_BLOCK_SUGARCANE = + { + Notes = "The blocktype for sugarcane" + }, + E_BLOCK_TALL_GRASS = + { + Notes = "The blocktype for tall grass" + }, + E_BLOCK_TNT = + { + Notes = "The blocktype for tnt" + }, + E_BLOCK_TORCH = + { + Notes = "The blocktype for torch" + }, + E_BLOCK_TRAPDOOR = + { + Notes = "The blocktype for trapdoor" + }, + E_BLOCK_TRAPPED_CHEST = + { + Notes = "The blocktype for trapped chest" + }, + E_BLOCK_TRIPWIRE = + { + Notes = "The blocktype for tripwire" + }, + E_BLOCK_TRIPWIRE_HOOK = + { + Notes = "The blocktype for tripwire hook" + }, + E_BLOCK_VINES = + { + Notes = "The blocktype for vines" + }, + E_BLOCK_WALLSIGN = + { + Notes = "The blocktype for wallsign" + }, + E_BLOCK_WALL_BANNER = + { + Notes = "The blocktype for wall banner" + }, + E_BLOCK_WATER = + { + Notes = "The blocktype for water" + }, + E_BLOCK_WOODEN_BUTTON = + { + Notes = "The blocktype for wooden button" + }, + E_BLOCK_WOODEN_DOOR = + { + Notes = "The blocktype for wooden door" + }, + E_BLOCK_WOODEN_PRESSURE_PLATE = + { + Notes = "The blocktype for wooden pressure plate" + }, + E_BLOCK_WOODEN_SLAB = + { + Notes = "The blocktype for wooden slab" + }, + E_BLOCK_WOODEN_STAIRS = + { + Notes = "The blocktype for wooden stairs" + }, + E_BLOCK_WOOL = + { + Notes = "The blocktype for wool" + }, + E_BLOCK_WORKBENCH = + { + Notes = "The blocktype for workbench" + }, + E_BLOCK_YELLOW_FLOWER = + { + Notes = "The blocktype for yellow flower" + }, + E_ITEM_11_DISC = + { + Notes = "The itemtype for 11 disc" + }, + E_ITEM_13_DISC = + { + Notes = "The itemtype for 13 disc" + }, + E_ITEM_ACACIA_DOOR = + { + Notes = "The itemtype for acacia door" + }, + E_ITEM_ARMOR_STAND = + { + Notes = "The itemtype for armor stand" + }, + E_ITEM_ARROW = + { + Notes = "The itemtype for arrow" + }, + E_ITEM_BAKED_POTATO = + { + Notes = "The itemtype for baked potato" + }, + E_ITEM_BANNER = + { + Notes = "The itemtype for banner" + }, + E_ITEM_BED = + { + Notes = "The itemtype for bed" + }, + E_ITEM_BIRCH_DOOR = + { + Notes = "The itemtype for birch door" + }, + E_ITEM_BLAZE_POWDER = + { + Notes = "The itemtype for blaze powder" + }, + E_ITEM_BLAZE_ROD = + { + Notes = "The itemtype for blaze rod" + }, + E_ITEM_BLOCKS_DISC = + { + Notes = "The itemtype for blocks disc" + }, + E_ITEM_BOAT = + { + Notes = "The itemtype for boat" + }, + E_ITEM_BONE = + { + Notes = "The itemtype for bone" + }, + E_ITEM_BOOK = + { + Notes = "The itemtype for book" + }, + E_ITEM_BOOK_AND_QUILL = + { + Notes = "The itemtype for book and quill" + }, + E_ITEM_BOTTLE_O_ENCHANTING = + { + Notes = "The itemtype for bottle o enchanting" + }, + E_ITEM_BOW = + { + Notes = "The itemtype for bow" + }, + E_ITEM_BOWL = + { + Notes = "The itemtype for bowl" + }, + E_ITEM_BREAD = + { + Notes = "The itemtype for bread" + }, + E_ITEM_BREWING_STAND = + { + Notes = "The itemtype for brewing stand" + }, + E_ITEM_BUCKET = + { + Notes = "The itemtype for bucket" + }, + E_ITEM_CAKE = + { + Notes = "The itemtype for cake" + }, + E_ITEM_CARROT = + { + Notes = "The itemtype for carrot" + }, + E_ITEM_CARROT_ON_STICK = + { + Notes = "The itemtype for carrot on stick" + }, + E_ITEM_CAT_DISC = + { + Notes = "The itemtype for cat disc" + }, + E_ITEM_CAULDRON = + { + Notes = "The itemtype for cauldron" + }, + E_ITEM_CHAIN_BOOTS = + { + Notes = "The itemtype for chain boots" + }, + E_ITEM_CHAIN_CHESTPLATE = + { + Notes = "The itemtype for chain chestplate" + }, + E_ITEM_CHAIN_HELMET = + { + Notes = "The itemtype for chain helmet" + }, + E_ITEM_CHAIN_LEGGINGS = + { + Notes = "The itemtype for chain leggings" + }, + E_ITEM_CHEST_MINECART = + { + Notes = "The itemtype for chest minecart" + }, + E_ITEM_CHIRP_DISC = + { + Notes = "The itemtype for chirp disc" + }, + E_ITEM_CLAY = + { + Notes = "The itemtype for clay" + }, + E_ITEM_CLAY_BRICK = + { + Notes = "The itemtype for clay brick" + }, + E_ITEM_CLOCK = + { + Notes = "The itemtype for clock" + }, + E_ITEM_COAL = + { + Notes = "The itemtype for coal" + }, + E_ITEM_COMPARATOR = + { + Notes = "The itemtype for comparator" + }, + E_ITEM_COMPASS = + { + Notes = "The itemtype for compass" + }, + E_ITEM_COOKED_CHICKEN = + { + Notes = "The itemtype for cooked chicken" + }, + E_ITEM_COOKED_FISH = + { + Notes = "The itemtype for cooked fish" + }, + E_ITEM_COOKED_MUTTON = + { + Notes = "The itemtype for cooked mutton" + }, + E_ITEM_COOKED_PORKCHOP = + { + Notes = "The itemtype for cooked porkchop" + }, + E_ITEM_COOKED_RABBIT = + { + Notes = "The itemtype for cooked rabbit" + }, + E_ITEM_COOKIE = + { + Notes = "The itemtype for cookie" + }, + E_ITEM_DARK_OAK_DOOR = + { + Notes = "The itemtype for dark oak door" + }, + E_ITEM_DIAMOND = + { + Notes = "The itemtype for diamond" + }, + E_ITEM_DIAMOND_AXE = + { + Notes = "The itemtype for diamond axe" + }, + E_ITEM_DIAMOND_BOOTS = + { + Notes = "The itemtype for diamond boots" + }, + E_ITEM_DIAMOND_CHESTPLATE = + { + Notes = "The itemtype for diamond chestplate" + }, + E_ITEM_DIAMOND_HELMET = + { + Notes = "The itemtype for diamond helmet" + }, + E_ITEM_DIAMOND_HOE = + { + Notes = "The itemtype for diamond hoe" + }, + E_ITEM_DIAMOND_HORSE_ARMOR = + { + Notes = "The itemtype for diamond horse armor" + }, + E_ITEM_DIAMOND_LEGGINGS = + { + Notes = "The itemtype for diamond leggings" + }, + E_ITEM_DIAMOND_PICKAXE = + { + Notes = "The itemtype for diamond pickaxe" + }, + E_ITEM_DIAMOND_SHOVEL = + { + Notes = "The itemtype for diamond shovel" + }, + E_ITEM_DIAMOND_SWORD = + { + Notes = "The itemtype for diamond sword" + }, + E_ITEM_DYE = + { + Notes = "The itemtype for dye" + }, + E_ITEM_EGG = + { + Notes = "The itemtype for egg" + }, + E_ITEM_EMERALD = + { + Notes = "The itemtype for emerald" + }, + E_ITEM_EMPTY = + { + Notes = "The itemtype for empty" + }, + E_ITEM_EMPTY_MAP = + { + Notes = "The itemtype for empty map" + }, + E_ITEM_ENCHANTED_BOOK = + { + Notes = "The itemtype for enchanted book" + }, + E_ITEM_ENDER_PEARL = + { + Notes = "The itemtype for ender pearl" + }, + E_ITEM_EYE_OF_ENDER = + { + Notes = "The itemtype for eye of ender" + }, + E_ITEM_FAR_DISC = + { + Notes = "The itemtype for far disc" + }, + E_ITEM_FEATHER = + { + Notes = "The itemtype for feather" + }, + E_ITEM_FERMENTED_SPIDER_EYE = + { + Notes = "The itemtype for fermented spider eye" + }, + E_ITEM_FIREWORK_ROCKET = + { + Notes = "The itemtype for firework rocket" + }, + E_ITEM_FIREWORK_STAR = + { + Notes = "The itemtype for firework star" + }, + E_ITEM_FIRE_CHARGE = + { + Notes = "The itemtype for fire charge" + }, + E_ITEM_FIRST = + { + Notes = "The itemtype for first" + }, + E_ITEM_FIRST_DISC = + { + Notes = "The itemtype for first disc" + }, + E_ITEM_FISHING_ROD = + { + Notes = "The itemtype for fishing rod" + }, + E_ITEM_FLINT = + { + Notes = "The itemtype for flint" + }, + E_ITEM_FLINT_AND_STEEL = + { + Notes = "The itemtype for flint and steel" + }, + E_ITEM_FLOWER_POT = + { + Notes = "The itemtype for flower pot" + }, + E_ITEM_FURNACE_MINECART = + { + Notes = "The itemtype for furnace minecart" + }, + E_ITEM_GHAST_TEAR = + { + Notes = "The itemtype for ghast tear" + }, + E_ITEM_GLASS_BOTTLE = + { + Notes = "The itemtype for glass bottle" + }, + E_ITEM_GLISTERING_MELON = + { + Notes = "The itemtype for glistering melon" + }, + E_ITEM_GLOWSTONE_DUST = + { + Notes = "The itemtype for glowstone dust" + }, + E_ITEM_GOLD = + { + Notes = "The itemtype for gold" + }, + E_ITEM_GOLDEN_APPLE = + { + Notes = "The itemtype for golden apple" + }, + E_ITEM_GOLDEN_CARROT = + { + Notes = "The itemtype for golden carrot" + }, + E_ITEM_GOLD_AXE = + { + Notes = "The itemtype for gold axe" + }, + E_ITEM_GOLD_BOOTS = + { + Notes = "The itemtype for gold boots" + }, + E_ITEM_GOLD_CHESTPLATE = + { + Notes = "The itemtype for gold chestplate" + }, + E_ITEM_GOLD_HELMET = + { + Notes = "The itemtype for gold helmet" + }, + E_ITEM_GOLD_HOE = + { + Notes = "The itemtype for gold hoe" + }, + E_ITEM_GOLD_HORSE_ARMOR = + { + Notes = "The itemtype for gold horse armor" + }, + E_ITEM_GOLD_LEGGINGS = + { + Notes = "The itemtype for gold leggings" + }, + E_ITEM_GOLD_NUGGET = + { + Notes = "The itemtype for gold nugget" + }, + E_ITEM_GOLD_PICKAXE = + { + Notes = "The itemtype for gold pickaxe" + }, + E_ITEM_GOLD_SHOVEL = + { + Notes = "The itemtype for gold shovel" + }, + E_ITEM_GOLD_SWORD = + { + Notes = "The itemtype for gold sword" + }, + E_ITEM_GUNPOWDER = + { + Notes = "The itemtype for gunpowder" + }, + E_ITEM_HEAD = + { + Notes = "The itemtype for head" + }, + E_ITEM_IRON = + { + Notes = "The itemtype for iron" + }, + E_ITEM_IRON_AXE = + { + Notes = "The itemtype for iron axe" + }, + E_ITEM_IRON_BOOTS = + { + Notes = "The itemtype for iron boots" + }, + E_ITEM_IRON_CHESTPLATE = + { + Notes = "The itemtype for iron chestplate" + }, + E_ITEM_IRON_DOOR = + { + Notes = "The itemtype for iron door" + }, + E_ITEM_IRON_HELMET = + { + Notes = "The itemtype for iron helmet" + }, + E_ITEM_IRON_HOE = + { + Notes = "The itemtype for iron hoe" + }, + E_ITEM_IRON_HORSE_ARMOR = + { + Notes = "The itemtype for iron horse armor" + }, + E_ITEM_IRON_LEGGINGS = + { + Notes = "The itemtype for iron leggings" + }, + E_ITEM_IRON_PICKAXE = + { + Notes = "The itemtype for iron pickaxe" + }, + E_ITEM_IRON_SHOVEL = + { + Notes = "The itemtype for iron shovel" + }, + E_ITEM_IRON_SWORD = + { + Notes = "The itemtype for iron sword" + }, + E_ITEM_ITEM_FRAME = + { + Notes = "The itemtype for item frame" + }, + E_ITEM_JUNGLE_DOOR = + { + Notes = "The itemtype for jungle door" + }, + E_ITEM_LAST = + { + Notes = "The itemtype for last" + }, + E_ITEM_LAST_DISC = + { + Notes = "The itemtype for last disc" + }, + E_ITEM_LAST_DISC_PLUS_ONE = + { + Notes = "The itemtype for last disc plus one" + }, + E_ITEM_LAVA_BUCKET = + { + Notes = "The itemtype for lava bucket" + }, + E_ITEM_LEAD = + { + Notes = "The itemtype for lead" + }, + E_ITEM_LEATHER = + { + Notes = "The itemtype for leather" + }, + E_ITEM_LEATHER_BOOTS = + { + Notes = "The itemtype for leather boots" + }, + E_ITEM_LEATHER_CAP = + { + Notes = "The itemtype for leather cap" + }, + E_ITEM_LEATHER_PANTS = + { + Notes = "The itemtype for leather pants" + }, + E_ITEM_LEATHER_TUNIC = + { + Notes = "The itemtype for leather tunic" + }, + E_ITEM_MAGMA_CREAM = + { + Notes = "The itemtype for magma cream" + }, + E_ITEM_MALL_DISC = + { + Notes = "The itemtype for mall disc" + }, + E_ITEM_MAP = + { + Notes = "The itemtype for map" + }, + E_ITEM_MAX_CONSECUTIVE_TYPE_ID = + { + Notes = "The itemtype for max consecutive type id" + }, + E_ITEM_MELLOHI_DISC = + { + Notes = "The itemtype for mellohi disc" + }, + E_ITEM_MELON_SEEDS = + { + Notes = "The itemtype for melon seeds" + }, + E_ITEM_MELON_SLICE = + { + Notes = "The itemtype for melon slice" + }, + E_ITEM_MILK = + { + Notes = "The itemtype for milk" + }, + E_ITEM_MINECART = + { + Notes = "The itemtype for minecart" + }, + E_ITEM_MINECART_WITH_COMMAND_BLOCK = + { + Notes = "The itemtype for minecart with command block" + }, + E_ITEM_MINECART_WITH_HOPPER = + { + Notes = "The itemtype for minecart with hopper" + }, + E_ITEM_MINECART_WITH_TNT = + { + Notes = "The itemtype for minecart with tnt" + }, + E_ITEM_MUSHROOM_SOUP = + { + Notes = "The itemtype for mushroom soup" + }, + E_ITEM_NAME_TAG = + { + Notes = "The itemtype for name tag" + }, + E_ITEM_NETHER_BRICK = + { + Notes = "The itemtype for nether brick" + }, + E_ITEM_NETHER_QUARTZ = + { + Notes = "The itemtype for nether quartz" + }, + E_ITEM_NETHER_STAR = + { + Notes = "The itemtype for nether star" + }, + E_ITEM_NETHER_WART = + { + Notes = "The itemtype for nether wart" + }, + E_ITEM_NUMBER_OF_CONSECUTIVE_TYPES = + { + Notes = "The itemtype for number of consecutive types" + }, + E_ITEM_PAINTING = + { + Notes = "The itemtype for painting" + }, + E_ITEM_PAPER = + { + Notes = "The itemtype for paper" + }, + E_ITEM_POISONOUS_POTATO = + { + Notes = "The itemtype for poisonous potato" + }, + E_ITEM_POTATO = + { + Notes = "The itemtype for potato" + }, + E_ITEM_POTION = + { + Notes = "The itemtype for potion" + }, + E_ITEM_POTIONS = + { + Notes = "The itemtype for potions" + }, + E_ITEM_PRISMARINE_CRYSTALS = + { + Notes = "The itemtype for prismarine crystals" + }, + E_ITEM_PRISMARINE_SHARD = + { + Notes = "The itemtype for prismarine shard" + }, + E_ITEM_PUMPKIN_PIE = + { + Notes = "The itemtype for pumpkin pie" + }, + E_ITEM_PUMPKIN_SEEDS = + { + Notes = "The itemtype for pumpkin seeds" + }, + E_ITEM_RABBITS_FOOT = + { + Notes = "The itemtype for rabbits foot" + }, + E_ITEM_RABBIT_HIDE = + { + Notes = "The itemtype for rabbit hide" + }, + E_ITEM_RABBIT_STEW = + { + Notes = "The itemtype for rabbit stew" + }, + E_ITEM_RAW_BEEF = + { + Notes = "The itemtype for raw beef" + }, + E_ITEM_RAW_CHICKEN = + { + Notes = "The itemtype for raw chicken" + }, + E_ITEM_RAW_FISH = + { + Notes = "The itemtype for raw fish" + }, + E_ITEM_RAW_MUTTON = + { + Notes = "The itemtype for raw mutton" + }, + E_ITEM_RAW_PORKCHOP = + { + Notes = "The itemtype for raw porkchop" + }, + E_ITEM_RAW_RABBIT = + { + Notes = "The itemtype for raw rabbit" + }, + E_ITEM_REDSTONE_DUST = + { + Notes = "The itemtype for redstone dust" + }, + E_ITEM_REDSTONE_REPEATER = + { + Notes = "The itemtype for redstone repeater" + }, + E_ITEM_RED_APPLE = + { + Notes = "The itemtype for red apple" + }, + E_ITEM_ROTTEN_FLESH = + { + Notes = "The itemtype for rotten flesh" + }, + E_ITEM_SADDLE = + { + Notes = "The itemtype for saddle" + }, + E_ITEM_SEEDS = + { + Notes = "The itemtype for seeds" + }, + E_ITEM_SHEARS = + { + Notes = "The itemtype for shears" + }, + E_ITEM_SIGN = + { + Notes = "The itemtype for sign" + }, + E_ITEM_SLIMEBALL = + { + Notes = "The itemtype for slimeball" + }, + E_ITEM_SNOWBALL = + { + Notes = "The itemtype for snowball" + }, + E_ITEM_SPAWN_EGG = + { + Notes = "The itemtype for spawn egg" + }, + E_ITEM_SPIDER_EYE = + { + Notes = "The itemtype for spider eye" + }, + E_ITEM_SPRUCE_DOOR = + { + Notes = "The itemtype for spruce door" + }, + E_ITEM_STAL_DISC = + { + Notes = "The itemtype for stal disc" + }, + E_ITEM_STEAK = + { + Notes = "The itemtype for steak" + }, + E_ITEM_STICK = + { + Notes = "The itemtype for stick" + }, + E_ITEM_STONE_AXE = + { + Notes = "The itemtype for stone axe" + }, + E_ITEM_STONE_HOE = + { + Notes = "The itemtype for stone hoe" + }, + E_ITEM_STONE_PICKAXE = + { + Notes = "The itemtype for stone pickaxe" + }, + E_ITEM_STONE_SHOVEL = + { + Notes = "The itemtype for stone shovel" + }, + E_ITEM_STONE_SWORD = + { + Notes = "The itemtype for stone sword" + }, + E_ITEM_STRAD_DISC = + { + Notes = "The itemtype for strad disc" + }, + E_ITEM_STRING = + { + Notes = "The itemtype for string" + }, + E_ITEM_SUGAR = + { + Notes = "The itemtype for sugar" + }, + E_ITEM_SUGARCANE = + { + Notes = "The itemtype for sugarcane" + }, + E_ITEM_SUGAR_CANE = + { + Notes = "The itemtype for sugar cane" + }, + E_ITEM_WAIT_DISC = + { + Notes = "The itemtype for wait disc" + }, + E_ITEM_WARD_DISC = + { + Notes = "The itemtype for ward disc" + }, + E_ITEM_WATER_BUCKET = + { + Notes = "The itemtype for water bucket" + }, + E_ITEM_WHEAT = + { + Notes = "The itemtype for wheat" + }, + E_ITEM_WOODEN_AXE = + { + Notes = "The itemtype for wooden axe" + }, + E_ITEM_WOODEN_DOOR = + { + Notes = "The itemtype for wooden door" + }, + E_ITEM_WOODEN_HOE = + { + Notes = "The itemtype for wooden hoe" + }, + E_ITEM_WOODEN_PICKAXE = + { + Notes = "The itemtype for wooden pickaxe" + }, + E_ITEM_WOODEN_SHOVEL = + { + Notes = "The itemtype for wooden shovel" + }, + E_ITEM_WOODEN_SWORD = + { + Notes = "The itemtype for wooden sword" + }, + E_ITEM_WRITTEN_BOOK = + { + Notes = "The itemtype for written book" + }, BLOCK_FACE_BOTTOM = { Notes = "Please use BLOCK_FACE_YM instead. Interacting with the bottom face of the block.", diff --git a/src/BlockID.h b/src/BlockID.h index 5af0cc4f5..bf668377c 100644 --- a/src/BlockID.h +++ b/src/BlockID.h @@ -215,10 +215,32 @@ enum BLOCKTYPE E_BLOCK_JUNGLE_DOOR = 195, E_BLOCK_ACACIA_DOOR = 196, E_BLOCK_DARK_OAK_DOOR = 197, - - // Keep these two as the last values. Update the last block value when adding another block - // IsValidBlock() depends on this - E_BLOCK_NUMBER_OF_TYPES = E_BLOCK_DARK_OAK_DOOR + 1, ///< Number of individual (different) blocktypes + E_BLOCK_END_ROD = 198, + E_BLOCK_CHORUS_PLANT = 199, + E_BLOCK_CHORUS_FLOWER = 200, + E_BLOCK_PURPUR_BLOCK = 201, + E_BLOCK_PURPUR_PILLAR = 202, + E_BLOCK_PURPUR_STAIRS = 203, + E_BLOCK_PURPUR_DOUBLE_SLAB = 204, + E_BLOCK_PURPUR_SLAB = 205, + E_BLOCK_END_BRICKS = 206, + E_BLOCK_BEETROOTS = 207, + E_BLOCK_GRASS_PATH = 208, + E_BLOCK_END_GATEWAY = 209, + E_BLOCK_REPEATING_COMMAND_BLOCK = 210, + E_BLOCK_CHAIN_COMMAND_BLOCK = 211, + E_BLOCK_FROSTED_ICE = 212, + E_BLOCK_MAGMA = 213, + E_BLOCK_NETHER_WART_BLOCK = 214, + E_BLOCK_RED_NETHER_BRICK = 215, + E_BLOCK_BONE_BLOCK = 216, + E_BLOCK_STRUCTURE_VOID = 217, + // ... + E_BLOCK_STRUCTURE_BLOCK = 255, + + // Keep these two as the last values. Update the last block value to the last block with an id less than 255 when adding another block + // IsValidBlock() depends on this (255 gets checked additionally because there is a gap. See http://minecraft.gamepedia.com/Data_values#Block_IDs + E_BLOCK_NUMBER_OF_TYPES = E_BLOCK_STRUCTURE_VOID + 1, ///< Number of individual (different) blocktypes E_BLOCK_MAX_TYPE_ID = E_BLOCK_NUMBER_OF_TYPES - 1, ///< Maximum BlockType number used // Synonym or ID compatibility diff --git a/src/BlockInfo.cpp b/src/BlockInfo.cpp index 34ccc2378..7fb6cf567 100644 --- a/src/BlockInfo.cpp +++ b/src/BlockInfo.cpp @@ -802,6 +802,205 @@ void cBlockInfo::Initialize(cBlockInfoArray & a_Info) a_Info[E_BLOCK_JUNGLE_DOOR ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_ACACIA_DOOR ].m_PlaceSound = "dig.wood"; a_Info[E_BLOCK_DARK_OAK_DOOR ].m_PlaceSound = "dig.wood"; + + a_Info[E_BLOCK_AIR ].m_Hardness = 0.0f; + a_Info[E_BLOCK_STONE ].m_Hardness = 1.5f; + a_Info[E_BLOCK_GRASS ].m_Hardness = 0.6f; + a_Info[E_BLOCK_DIRT ].m_Hardness = 0.5f; + a_Info[E_BLOCK_COBBLESTONE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_PLANKS ].m_Hardness = 2.0f; + a_Info[E_BLOCK_SAPLING ].m_Hardness = 0.0f; + a_Info[E_BLOCK_BEDROCK ].m_Hardness = -1.0f; + a_Info[E_BLOCK_WATER ].m_Hardness = 100.0f; + a_Info[E_BLOCK_STATIONARY_WATER ].m_Hardness = 100.0f; + a_Info[E_BLOCK_LAVA ].m_Hardness = 100.0f; + a_Info[E_BLOCK_STATIONARY_LAVA ].m_Hardness = 100.0f; + a_Info[E_BLOCK_SAND ].m_Hardness = 0.5f; + a_Info[E_BLOCK_GRAVEL ].m_Hardness = 0.6f; + a_Info[E_BLOCK_GOLD_ORE ].m_Hardness = 3.0f; + a_Info[E_BLOCK_IRON_ORE ].m_Hardness = 3.0f; + a_Info[E_BLOCK_COAL_ORE ].m_Hardness = 3.0f; + a_Info[E_BLOCK_LOG ].m_Hardness = 2.0f; + a_Info[E_BLOCK_LEAVES ].m_Hardness = 0.2f; + a_Info[E_BLOCK_SPONGE ].m_Hardness = 0.6f; + a_Info[E_BLOCK_GLASS ].m_Hardness = 0.3f; + a_Info[E_BLOCK_LAPIS_ORE ].m_Hardness = 3.0f; + a_Info[E_BLOCK_LAPIS_BLOCK ].m_Hardness = 3.0f; + a_Info[E_BLOCK_DISPENSER ].m_Hardness = 3.5f; + a_Info[E_BLOCK_SANDSTONE ].m_Hardness = 0.8f; + a_Info[E_BLOCK_NOTE_BLOCK ].m_Hardness = 0.8f; + a_Info[E_BLOCK_BED ].m_Hardness = 0.2f; + a_Info[E_BLOCK_POWERED_RAIL ].m_Hardness = 0.7f; + a_Info[E_BLOCK_DETECTOR_RAIL ].m_Hardness = 0.7f; + a_Info[E_BLOCK_STICKY_PISTON ].m_Hardness = 0.5f; + a_Info[E_BLOCK_COBWEB ].m_Hardness = 4.0f; + a_Info[E_BLOCK_TALL_GRASS ].m_Hardness = 0.0f; + a_Info[E_BLOCK_DEAD_BUSH ].m_Hardness = 0.0f; + a_Info[E_BLOCK_PISTON ].m_Hardness = 0.5f; + a_Info[E_BLOCK_PISTON_EXTENSION ].m_Hardness = 0.5f; + a_Info[E_BLOCK_WOOL ].m_Hardness = 0.8f; + a_Info[E_BLOCK_PISTON_MOVED_BLOCK ].m_Hardness = -1.0f; + a_Info[E_BLOCK_DANDELION ].m_Hardness = 0.0f; + a_Info[E_BLOCK_FLOWER ].m_Hardness = 0.0f; + a_Info[E_BLOCK_BROWN_MUSHROOM ].m_Hardness = 0.0f; + a_Info[E_BLOCK_RED_MUSHROOM ].m_Hardness = 0.0f; + a_Info[E_BLOCK_GOLD_BLOCK ].m_Hardness = 3.0f; + a_Info[E_BLOCK_IRON_BLOCK ].m_Hardness = 5.0f; + a_Info[E_BLOCK_DOUBLE_STONE_SLAB ].m_Hardness = 2.0f; + a_Info[E_BLOCK_STONE_SLAB ].m_Hardness = 2.0f; + a_Info[E_BLOCK_BRICK ].m_Hardness = 2.0f; + a_Info[E_BLOCK_TNT ].m_Hardness = 0.0f; + a_Info[E_BLOCK_BOOKCASE ].m_Hardness = 1.5f; + a_Info[E_BLOCK_MOSSY_COBBLESTONE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_OBSIDIAN ].m_Hardness = 50.0f; + a_Info[E_BLOCK_TORCH ].m_Hardness = 0.0f; + a_Info[E_BLOCK_FIRE ].m_Hardness = 0.0f; + a_Info[E_BLOCK_MOB_SPAWNER ].m_Hardness = 5.0f; + a_Info[E_BLOCK_OAK_WOOD_STAIRS ].m_Hardness = 2.0f; + a_Info[E_BLOCK_CHEST ].m_Hardness = 2.5f; + a_Info[E_BLOCK_REDSTONE_WIRE ].m_Hardness = 0.0f; + a_Info[E_BLOCK_DIAMOND_ORE ].m_Hardness = 3.0f; + a_Info[E_BLOCK_DIAMOND_BLOCK ].m_Hardness = 5.0f; + a_Info[E_BLOCK_CRAFTING_TABLE ].m_Hardness = 2.5f; + a_Info[E_BLOCK_CROPS ].m_Hardness = 0.0f; + a_Info[E_BLOCK_FARMLAND ].m_Hardness = 0.6f; + a_Info[E_BLOCK_FURNACE ].m_Hardness = 3.5f; + a_Info[E_BLOCK_LIT_FURNACE ].m_Hardness = 3.5f; + a_Info[E_BLOCK_SIGN_POST ].m_Hardness = 1.0f; + a_Info[E_BLOCK_OAK_DOOR ].m_Hardness = 3.0f; + a_Info[E_BLOCK_LADDER ].m_Hardness = 0.4f; + a_Info[E_BLOCK_RAIL ].m_Hardness = 0.7f; + a_Info[E_BLOCK_COBBLESTONE_STAIRS ].m_Hardness = 2.0f; + a_Info[E_BLOCK_WALLSIGN ].m_Hardness = 1.0f; + a_Info[E_BLOCK_LEVER ].m_Hardness = 0.5f; + a_Info[E_BLOCK_STONE_PRESSURE_PLATE].m_Hardness = 0.5f; + a_Info[E_BLOCK_IRON_DOOR ].m_Hardness = 5.0f; + a_Info[E_BLOCK_WOODEN_PRESSURE_PLATE].m_Hardness = 0.5f; + a_Info[E_BLOCK_REDSTONE_ORE ].m_Hardness = 3.0f; + a_Info[E_BLOCK_REDSTONE_ORE_GLOWING].m_Hardness = 0.625f; + a_Info[E_BLOCK_REDSTONE_TORCH_OFF ].m_Hardness = 0.0f; + a_Info[E_BLOCK_REDSTONE_TORCH_ON ].m_Hardness = 0.0f; + a_Info[E_BLOCK_STONE_BUTTON ].m_Hardness = 0.5f; + a_Info[E_BLOCK_SNOW ].m_Hardness = 0.1f; + a_Info[E_BLOCK_ICE ].m_Hardness = 0.5f; + a_Info[E_BLOCK_SNOW_BLOCK ].m_Hardness = 0.2f; + a_Info[E_BLOCK_CACTUS ].m_Hardness = 0.4f; + a_Info[E_BLOCK_CLAY ].m_Hardness = 0.6f; + a_Info[E_BLOCK_SUGARCANE ].m_Hardness = 0.0f; + a_Info[E_BLOCK_JUKEBOX ].m_Hardness = 2.0f; + a_Info[E_BLOCK_FENCE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_PUMPKIN ].m_Hardness = 1.0f; + a_Info[E_BLOCK_NETHERRACK ].m_Hardness = 0.4f; + a_Info[E_BLOCK_SOULSAND ].m_Hardness = 0.5f; + a_Info[E_BLOCK_GLOWSTONE ].m_Hardness = 0.3f; + a_Info[E_BLOCK_NETHER_PORTAL ].m_Hardness = -1.0f; + a_Info[E_BLOCK_JACK_O_LANTERN ].m_Hardness = 1.0f; + a_Info[E_BLOCK_CAKE ].m_Hardness = 0.5f; + a_Info[E_BLOCK_REDSTONE_REPEATER_OFF].m_Hardness = 0.0f; + a_Info[E_BLOCK_REDSTONE_REPEATER_ON].m_Hardness = 0.0f; + a_Info[E_BLOCK_STAINED_GLASS ].m_Hardness = 0.3f; + a_Info[E_BLOCK_TRAPDOOR ].m_Hardness = 3.0f; + a_Info[E_BLOCK_SILVERFISH_EGG ].m_Hardness = 0.75f; + a_Info[E_BLOCK_STONE_BRICKS ].m_Hardness = 1.5f; + a_Info[E_BLOCK_HUGE_BROWN_MUSHROOM ].m_Hardness = 0.2f; + a_Info[E_BLOCK_HUGE_RED_MUSHROOM ].m_Hardness = 0.2f; + a_Info[E_BLOCK_IRON_BARS ].m_Hardness = 5.0f; + a_Info[E_BLOCK_GLASS_PANE ].m_Hardness = 0.3f; + a_Info[E_BLOCK_MELON ].m_Hardness = 1.0f; + a_Info[E_BLOCK_PUMPKIN_STEM ].m_Hardness = 0.0f; + a_Info[E_BLOCK_MELON_STEM ].m_Hardness = 0.0f; + a_Info[E_BLOCK_VINES ].m_Hardness = 0.2f; + a_Info[E_BLOCK_OAK_FENCE_GATE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_BRICK_STAIRS ].m_Hardness = 2.0f; + a_Info[E_BLOCK_STONE_BRICK_STAIRS ].m_Hardness = 1.5f; + a_Info[E_BLOCK_MYCELIUM ].m_Hardness = 0.6f; + a_Info[E_BLOCK_LILY_PAD ].m_Hardness = 0.0f; + a_Info[E_BLOCK_NETHER_BRICK ].m_Hardness = 2.0f; + a_Info[E_BLOCK_NETHER_BRICK_FENCE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_NETHER_BRICK_STAIRS ].m_Hardness = 2.0f; + a_Info[E_BLOCK_NETHER_WART ].m_Hardness = 0.0f; + a_Info[E_BLOCK_ENCHANTMENT_TABLE ].m_Hardness = 5.0f; + a_Info[E_BLOCK_BREWING_STAND ].m_Hardness = 0.5f; + a_Info[E_BLOCK_CAULDRON ].m_Hardness = 2.0f; + a_Info[E_BLOCK_END_PORTAL ].m_Hardness = -1.0f; + a_Info[E_BLOCK_END_PORTAL_FRAME ].m_Hardness = -1.0f; + a_Info[E_BLOCK_END_STONE ].m_Hardness = 3.0f; + a_Info[E_BLOCK_DRAGON_EGG ].m_Hardness = 3.0f; + a_Info[E_BLOCK_REDSTONE_LAMP_OFF ].m_Hardness = 0.3f; + a_Info[E_BLOCK_REDSTONE_LAMP_ON ].m_Hardness = 0.3f; + a_Info[E_BLOCK_DOUBLE_WOODEN_SLAB ].m_Hardness = 2.0f; + a_Info[E_BLOCK_WOODEN_SLAB ].m_Hardness = 2.0f; + a_Info[E_BLOCK_COCOA_POD ].m_Hardness = 0.2f; + a_Info[E_BLOCK_SANDSTONE_STAIRS ].m_Hardness = 0.8f; + a_Info[E_BLOCK_EMERALD_ORE ].m_Hardness = 3.0f; + a_Info[E_BLOCK_ENDER_CHEST ].m_Hardness = 22.5f; + a_Info[E_BLOCK_TRIPWIRE_HOOK ].m_Hardness = 0.0f; + a_Info[E_BLOCK_TRIPWIRE ].m_Hardness = 0.0f; + a_Info[E_BLOCK_EMERALD_BLOCK ].m_Hardness = 5.0f; + a_Info[E_BLOCK_SPRUCE_WOOD_STAIRS ].m_Hardness = 2.0f; + a_Info[E_BLOCK_BIRCH_WOOD_STAIRS ].m_Hardness = 2.0f; + a_Info[E_BLOCK_JUNGLE_WOOD_STAIRS ].m_Hardness = 2.0f; + a_Info[E_BLOCK_COMMAND_BLOCK ].m_Hardness = -1.0f; + a_Info[E_BLOCK_BEACON ].m_Hardness = 3.0f; + a_Info[E_BLOCK_COBBLESTONE_WALL ].m_Hardness = 2.0f; + a_Info[E_BLOCK_FLOWER_POT ].m_Hardness = 0.0f; + a_Info[E_BLOCK_CARROTS ].m_Hardness = 0.0f; + a_Info[E_BLOCK_POTATOES ].m_Hardness = 0.0f; + a_Info[E_BLOCK_WOODEN_BUTTON ].m_Hardness = 0.5f; + a_Info[E_BLOCK_HEAD ].m_Hardness = 1.0f; + a_Info[E_BLOCK_ANVIL ].m_Hardness = 5.0f; + a_Info[E_BLOCK_TRAPPED_CHEST ].m_Hardness = 2.5f; + a_Info[E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE].m_Hardness = 0.5f; + a_Info[E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE].m_Hardness = 0.5f; + a_Info[E_BLOCK_INACTIVE_COMPARATOR ].m_Hardness = 0.0f; + a_Info[E_BLOCK_ACTIVE_COMPARATOR ].m_Hardness = 0.0f; + a_Info[E_BLOCK_DAYLIGHT_SENSOR ].m_Hardness = 0.2f; + a_Info[E_BLOCK_BLOCK_OF_REDSTONE ].m_Hardness = 5.0f; + a_Info[E_BLOCK_NETHER_QUARTZ_ORE ].m_Hardness = 3.0f; + a_Info[E_BLOCK_HOPPER ].m_Hardness = 3.0f; + a_Info[E_BLOCK_QUARTZ_BLOCK ].m_Hardness = 0.8f; + a_Info[E_BLOCK_QUARTZ_STAIRS ].m_Hardness = 0.8f; + a_Info[E_BLOCK_ACTIVATOR_RAIL ].m_Hardness = 0.7f; + a_Info[E_BLOCK_DROPPER ].m_Hardness = 3.5f; + a_Info[E_BLOCK_STAINED_CLAY ].m_Hardness = 1.25f; + a_Info[E_BLOCK_STAINED_GLASS_PANE ].m_Hardness = 0.3f; + a_Info[E_BLOCK_NEW_LEAVES ].m_Hardness = 0.2f; + a_Info[E_BLOCK_NEW_LOG ].m_Hardness = 2.0f; + a_Info[E_BLOCK_ACACIA_WOOD_STAIRS ].m_Hardness = 2.0f; + a_Info[E_BLOCK_DARK_OAK_WOOD_STAIRS].m_Hardness = 2.0f; + a_Info[E_BLOCK_SLIME_BLOCK ].m_Hardness = 0.0f; + a_Info[E_BLOCK_BARRIER ].m_Hardness = -1.0f; + a_Info[E_BLOCK_IRON_TRAPDOOR ].m_Hardness = 5.0f; + a_Info[E_BLOCK_PRISMARINE_BLOCK ].m_Hardness = 1.5f; + a_Info[E_BLOCK_SEA_LANTERN ].m_Hardness = 0.3f; + a_Info[E_BLOCK_HAY_BALE ].m_Hardness = 0.5f; + a_Info[E_BLOCK_CARPET ].m_Hardness = 0.1f; + a_Info[E_BLOCK_HARDENED_CLAY ].m_Hardness = 1.25f; + a_Info[E_BLOCK_BLOCK_OF_COAL ].m_Hardness = 5.0f; + a_Info[E_BLOCK_PACKED_ICE ].m_Hardness = 0.5f; + a_Info[E_BLOCK_BIG_FLOWER ].m_Hardness = 0.0f; + a_Info[E_BLOCK_STANDING_BANNER ].m_Hardness = 1.0f; + a_Info[E_BLOCK_WALL_BANNER ].m_Hardness = 1.0f; + a_Info[E_BLOCK_INVERTED_DAYLIGHT_SENSOR].m_Hardness = 0.2f; + a_Info[E_BLOCK_RED_SANDSTONE ].m_Hardness = 0.8f; + a_Info[E_BLOCK_RED_SANDSTONE_STAIRS].m_Hardness = 0.8f; + a_Info[E_BLOCK_DOUBLE_RED_SANDSTONE_SLAB].m_Hardness = 2.0f; + a_Info[E_BLOCK_RED_SANDSTONE_SLAB ].m_Hardness = 2.0f; + a_Info[E_BLOCK_SPRUCE_FENCE_GATE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_BIRCH_FENCE_GATE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_JUNGLE_FENCE_GATE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_DARK_OAK_FENCE_GATE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_ACACIA_FENCE_GATE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_SPRUCE_FENCE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_BIRCH_FENCE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_JUNGLE_FENCE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_DARK_OAK_FENCE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_ACACIA_FENCE ].m_Hardness = 2.0f; + a_Info[E_BLOCK_SPRUCE_DOOR ].m_Hardness = 3.0f; + a_Info[E_BLOCK_BIRCH_DOOR ].m_Hardness = 3.0f; + a_Info[E_BLOCK_JUNGLE_DOOR ].m_Hardness = 3.0f; + a_Info[E_BLOCK_ACACIA_DOOR ].m_Hardness = 3.0f; + a_Info[E_BLOCK_DARK_OAK_DOOR ].m_Hardness = 3.0f; } diff --git a/src/BlockInfo.h b/src/BlockInfo.h index d42987794..adf370c13 100644 --- a/src/BlockInfo.h +++ b/src/BlockInfo.h @@ -70,6 +70,9 @@ public: /** Sound when placing this block */ AString m_PlaceSound; + /** Block's hardness. The greater the value the longer the player needs to break the block. */ + float m_Hardness; + // tolua_end /** Associated block handler. */ @@ -89,6 +92,7 @@ public: inline static bool CanBeTerraformed (BLOCKTYPE a_Type) { return Get(a_Type).m_CanBeTerraformed; } inline static float GetBlockHeight (BLOCKTYPE a_Type) { return Get(a_Type).m_BlockHeight; } inline static AString GetPlaceSound (BLOCKTYPE a_Type) { return Get(a_Type).m_PlaceSound; } + inline static float GetHardness (BLOCKTYPE a_Type) { return Get(a_Type).m_Hardness; } // tolua_end @@ -112,6 +116,7 @@ protected: , m_CanBeTerraformed(false) , m_BlockHeight(1.0) , m_PlaceSound("") + , m_Hardness(0.0f) , m_Handler(nullptr) {} diff --git a/src/ClientHandle.cpp b/src/ClientHandle.cpp index fc41a4f7c..1badbdaf7 100644 --- a/src/ClientHandle.cpp +++ b/src/ClientHandle.cpp @@ -56,6 +56,7 @@ static const std::chrono::milliseconds PING_TIME_MS = std::chrono::milliseconds( int cClientHandle::s_ClientCount = 0; +float cClientHandle::FASTBREAK_PERCENTAGE; @@ -1187,6 +1188,8 @@ void cClientHandle::HandleBlockDigStarted(int a_BlockX, int a_BlockY, int a_Bloc return; } + m_BreakProgress = 0; + // Start dig animation // TODO: calculate real animation speed // TODO: Send animation packets even without receiving any other packets @@ -1243,6 +1246,22 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo } } + if (!m_Player->IsGameModeCreative() && !cBlockInfo::IsOneHitDig(a_OldBlock)) + { + // Fix for very fast tools. + m_BreakProgress += m_Player->GetPlayerRelativeBlockHardness(a_OldBlock); + if (m_BreakProgress < FASTBREAK_PERCENTAGE) + { + LOGD("Break progress of player %s was less than expected: %f < %f\n", m_Player->GetName().c_str(), m_BreakProgress * 100, FASTBREAK_PERCENTAGE * 100); + // AntiFastBreak doesn't agree with the breaking. Bail out. Send the block back to the client, so that it knows: + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // Strange bug with doors + SendPlayerPosition(); // Prevents the player from falling through the block that was temporarily broken client side. + m_Player->SendMessage("FastBreak?"); // TODO Anticheat hook + return; + } + } + cWorld * World = m_Player->GetWorld(); cItemHandler * ItemHandler = cItemHandler::GetItemHandler(m_Player->GetEquippedItem()); @@ -1250,6 +1269,7 @@ void cClientHandle::HandleBlockDigFinished(int a_BlockX, int a_BlockY, int a_Blo { // A plugin doesn't agree with the breaking. Bail out. Send the block back to the client, so that it knows: m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY, a_BlockZ, m_Player); + m_Player->GetWorld()->SendBlockTo(a_BlockX, a_BlockY + 1, a_BlockZ, m_Player); // Strange bug with doors SendPlayerPosition(); // Prevents the player from falling through the block that was temporarily broken client side. return; } @@ -1980,6 +2000,13 @@ bool cClientHandle::CheckBlockInteractionsRate(void) void cClientHandle::Tick(float a_Dt) { + // anticheat fastbreak + if (m_HasStartedDigging) + { + BLOCKTYPE Block = m_Player->GetWorld()->GetBlock(m_LastDigBlockX, m_LastDigBlockY, m_LastDigBlockZ); + m_BreakProgress += m_Player->GetPlayerRelativeBlockHardness(Block); + } + // Process received network data: AString IncomingData; { diff --git a/src/ClientHandle.h b/src/ClientHandle.h index cadce3c09..77c94db09 100644 --- a/src/ClientHandle.h +++ b/src/ClientHandle.h @@ -63,6 +63,11 @@ public: // tolua_export static const int MAX_VIEW_DISTANCE = 32; static const int MIN_VIEW_DISTANCE = 1; + /** The percentage how much a block has to be broken. + Should be a value between 0.7 (70% broken) and 1 (100% broken) depending on lag. + Can be set in settings.ini [AntiCheat] FastBreakPercentage=(from 0 to 100) */ + static float FASTBREAK_PERCENTAGE; + /** Creates a new client with the specified IP address in its description and the specified initial view distance. */ cClientHandle(const AString & a_IPString, int a_ViewDistance); @@ -519,6 +524,7 @@ private: /** Shared pointer to self, so that this instance can keep itself alive when needed. */ cClientHandlePtr m_Self; + float m_BreakProgress; /** Returns true if the rate block interactions is within a reasonable limit (bot protection) */ bool CheckBlockInteractionsRate(void); diff --git a/src/Defines.h b/src/Defines.h index b9a90cc81..f8af22ef2 100644 --- a/src/Defines.h +++ b/src/Defines.h @@ -370,8 +370,11 @@ inline AString BlockFaceToString(eBlockFace a_BlockFace) inline bool IsValidBlock(int a_BlockType) { if ( + ( (a_BlockType > -1) && (a_BlockType <= E_BLOCK_MAX_TYPE_ID) + ) || + (a_BlockType == 255) // the blocks 235-254 don't exist yet -> http://minecraft.gamepedia.com/Data_values#Block_IDs ) { return true; @@ -509,6 +512,304 @@ inline bool IsBlockFence(BLOCKTYPE a_BlockType) + +inline bool IsBlockMaterialWood(BLOCKTYPE a_BlockType) +{ + switch (a_BlockType) + { + case E_BLOCK_PLANKS: + case E_BLOCK_LOG: + case E_BLOCK_NOTE_BLOCK: + case E_BLOCK_BOOKCASE: + case E_BLOCK_OAK_WOOD_STAIRS: + case E_BLOCK_CHEST: + case E_BLOCK_CRAFTING_TABLE: + case E_BLOCK_SIGN_POST: + case E_BLOCK_OAK_DOOR: + case E_BLOCK_WALLSIGN: + case E_BLOCK_WOODEN_PRESSURE_PLATE: + case E_BLOCK_JUKEBOX: + case E_BLOCK_FENCE: + case E_BLOCK_TRAPDOOR: + case E_BLOCK_HUGE_BROWN_MUSHROOM: + case E_BLOCK_HUGE_RED_MUSHROOM: + case E_BLOCK_OAK_FENCE_GATE: + case E_BLOCK_DOUBLE_WOODEN_SLAB: + case E_BLOCK_WOODEN_SLAB: + case E_BLOCK_SPRUCE_WOOD_STAIRS: + case E_BLOCK_BIRCH_WOOD_STAIRS: + case E_BLOCK_JUNGLE_WOOD_STAIRS: + case E_BLOCK_TRAPPED_CHEST: + case E_BLOCK_DAYLIGHT_SENSOR: + case E_BLOCK_NEW_LOG: + case E_BLOCK_ACACIA_WOOD_STAIRS: + case E_BLOCK_DARK_OAK_WOOD_STAIRS: + case E_BLOCK_STANDING_BANNER: + case E_BLOCK_WALL_BANNER: + case E_BLOCK_INVERTED_DAYLIGHT_SENSOR: + case E_BLOCK_SPRUCE_FENCE_GATE: + case E_BLOCK_BIRCH_FENCE_GATE: + case E_BLOCK_JUNGLE_FENCE_GATE: + case E_BLOCK_DARK_OAK_FENCE_GATE: + case E_BLOCK_ACACIA_FENCE_GATE: + case E_BLOCK_SPRUCE_FENCE: + case E_BLOCK_BIRCH_FENCE: + case E_BLOCK_JUNGLE_FENCE: + case E_BLOCK_DARK_OAK_FENCE: + case E_BLOCK_ACACIA_FENCE: + case E_BLOCK_SPRUCE_DOOR: + case E_BLOCK_BIRCH_DOOR: + case E_BLOCK_JUNGLE_DOOR: + case E_BLOCK_ACACIA_DOOR: + case E_BLOCK_DARK_OAK_DOOR: + { + return true; + } + default: + { + return false; + } + } +} + + + + + +inline bool IsBlockMaterialPlants(BLOCKTYPE a_BlockType) +{ + switch (a_BlockType) + { + case E_BLOCK_SAPLING: + case E_BLOCK_DANDELION: + case E_BLOCK_FLOWER: + case E_BLOCK_BROWN_MUSHROOM: + case E_BLOCK_RED_MUSHROOM: + case E_BLOCK_CROPS: + case E_BLOCK_REEDS: + case E_BLOCK_PUMPKIN_STEM: + case E_BLOCK_MELON_STEM: + case E_BLOCK_LILY_PAD: + case E_BLOCK_NETHER_WART: + case E_BLOCK_COCOA_POD: + case E_BLOCK_CARROTS: + case E_BLOCK_POTATOES: + case E_BLOCK_CHORUS_PLANT: + case E_BLOCK_CHORUS_FLOWER: + case E_BLOCK_BEETROOTS: + { + return true; + } + default: + { + return false; + } + } +} + + + + + +inline bool IsBlockMaterialVine(BLOCKTYPE a_BlockType) +{ + switch (a_BlockType) + { + case E_BLOCK_TALL_GRASS: + case E_BLOCK_DEAD_BUSH: + case E_BLOCK_VINES: + case E_BLOCK_BIG_FLOWER: + { + return true; + } + default: + { + return false; + } + } +} + + + + + +inline bool IsBlockMaterialIron(BLOCKTYPE a_BlockType) +{ + switch (a_BlockType) + { + case E_BLOCK_LAPIS_BLOCK: + case E_BLOCK_GOLD_BLOCK: + case E_BLOCK_IRON_BLOCK: + case E_BLOCK_DIAMOND_BLOCK: + case E_BLOCK_IRON_DOOR: + case E_BLOCK_IRON_BARS: + case E_BLOCK_BREWING_STAND: + case E_BLOCK_CAULDRON: + case E_BLOCK_EMERALD_BLOCK: + case E_BLOCK_COMMAND_BLOCK: + case E_BLOCK_LIGHT_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_HEAVY_WEIGHTED_PRESSURE_PLATE: + case E_BLOCK_BLOCK_OF_REDSTONE: + case E_BLOCK_HOPPER: + case E_BLOCK_IRON_TRAPDOOR: + case E_BLOCK_REPEATING_COMMAND_BLOCK: + case E_BLOCK_CHAIN_COMMAND_BLOCK: + case E_BLOCK_STRUCTURE_BLOCK: + { + return true; + } + default: + { + return false; + } + } +} + + + + + +inline bool IsBlockMaterialAnvil(BLOCKTYPE a_BlockType) +{ + return (a_BlockType == E_BLOCK_ANVIL); +} + + + + + +inline bool IsBlocksWeb(BLOCKTYPE a_BlockType) +{ + return (a_BlockType == E_BLOCK_COBWEB); +} + + + + + +inline bool IsBlockMaterialLeaves(BLOCKTYPE a_BlockType) +{ + return (a_BlockType == E_BLOCK_LEAVES) || (a_BlockType == E_BLOCK_NEW_LEAVES); +} + + + + + +inline bool IsBlocksWool(BLOCKTYPE a_BlockType) +{ + return (a_BlockType == E_BLOCK_WOOL); +} + + + + + +inline bool IsBlockMaterialGourd(BLOCKTYPE a_BlockType) +{ + switch (a_BlockType) + { + case E_BLOCK_PUMPKIN: + case E_BLOCK_JACK_O_LANTERN: + case E_BLOCK_MELON: + { + return true; + } + default: + { + return false; + } + } +} + + + + + +inline bool IsBlockMaterialCoral(BLOCKTYPE a_BlockType) +{ + return false; // yes, there is no block in minecraft which belongs to this type. +} + + + + + +inline bool IsBlockMaterialRock(BLOCKTYPE a_BlockType) +{ + switch (a_BlockType) + { + case E_BLOCK_STONE: + case E_BLOCK_COBBLESTONE: + case E_BLOCK_BEDROCK: + case E_BLOCK_GOLD_ORE: + case E_BLOCK_IRON_ORE: + case E_BLOCK_COAL_ORE: + case E_BLOCK_LAPIS_ORE: + case E_BLOCK_DISPENSER: + case E_BLOCK_SANDSTONE: + case E_BLOCK_DOUBLE_STONE_SLAB: + case E_BLOCK_STONE_SLAB: + case E_BLOCK_BRICK: + case E_BLOCK_MOSSY_COBBLESTONE: + case E_BLOCK_OBSIDIAN: + case E_BLOCK_MOB_SPAWNER: + case E_BLOCK_DIAMOND_ORE: + case E_BLOCK_FURNACE: + case E_BLOCK_LIT_FURNACE: + case E_BLOCK_COBBLESTONE_STAIRS: + case E_BLOCK_STONE_PRESSURE_PLATE: + case E_BLOCK_REDSTONE_ORE: + case E_BLOCK_REDSTONE_ORE_GLOWING: + case E_BLOCK_NETHERRACK: + case E_BLOCK_STONE_BRICKS: + case E_BLOCK_BRICK_STAIRS: + case E_BLOCK_STONE_BRICK_STAIRS: + case E_BLOCK_NETHER_BRICK: + case E_BLOCK_NETHER_BRICK_FENCE: + case E_BLOCK_NETHER_BRICK_STAIRS: + case E_BLOCK_ENCHANTMENT_TABLE: + case E_BLOCK_END_PORTAL_FRAME: + case E_BLOCK_END_STONE: + case E_BLOCK_SANDSTONE_STAIRS: + case E_BLOCK_EMERALD_ORE: + case E_BLOCK_ENDER_CHEST: + case E_BLOCK_COBBLESTONE_WALL: + case E_BLOCK_NETHER_QUARTZ_ORE: + case E_BLOCK_QUARTZ_BLOCK: + case E_BLOCK_QUARTZ_STAIRS: + case E_BLOCK_DROPPER: + case E_BLOCK_STAINED_CLAY: + case E_BLOCK_PRISMARINE_BLOCK: + case E_BLOCK_HARDENED_CLAY: + case E_BLOCK_BLOCK_OF_COAL: + case E_BLOCK_RED_SANDSTONE: + case E_BLOCK_RED_SANDSTONE_STAIRS: + case E_BLOCK_DOUBLE_RED_SANDSTONE_SLAB: + case E_BLOCK_RED_SANDSTONE_SLAB: + case E_BLOCK_PURPUR_BLOCK: + case E_BLOCK_PURPUR_PILLAR: + case E_BLOCK_PURPUR_STAIRS: + case E_BLOCK_PURPUR_DOUBLE_SLAB: + case E_BLOCK_PURPUR_SLAB: + case E_BLOCK_END_BRICKS: + case E_BLOCK_MAGMA: + case E_BLOCK_RED_NETHER_BRICK: + case E_BLOCK_BONE_BLOCK: + { + return true; + } + default: + { + return false; + } + } +} + + + + + inline void AddFaceDirection(int & a_BlockX, int & a_BlockY, int & a_BlockZ, eBlockFace a_BlockFace, bool a_bInverse = false) // tolua_export { // tolua_export if (!a_bInverse) diff --git a/src/Entities/Pawn.cpp b/src/Entities/Pawn.cpp index 4b42dbb57..a073dc9a7 100644 --- a/src/Entities/Pawn.cpp +++ b/src/Entities/Pawn.cpp @@ -441,3 +441,24 @@ void cPawn::StopEveryoneFromTargetingMe() } ASSERT(m_TargetingMe.size() == 0); } + + + + + +std::map cPawn::GetEntityEffects() +{ + return m_EntityEffects; +} + + + + + +cEntityEffect *cPawn::GetEntityEffect(cEntityEffect::eType a_EffectType) +{ + return m_EntityEffects.at(a_EffectType); +} + + + diff --git a/src/Entities/Pawn.h b/src/Entities/Pawn.h index 6a7035ee6..e2444e9a0 100644 --- a/src/Entities/Pawn.h +++ b/src/Entities/Pawn.h @@ -63,6 +63,12 @@ public: /** Add the monster to the list of monsters targeting this pawn. (Does not check if already in list!) */ void TargetingMe(cMonster * a_Monster); + /** Returns all entity effects */ + std::map GetEntityEffects(); + + /** Returns the entity effect, if it is currently applied. */ + cEntityEffect *GetEntityEffect(cEntityEffect::eType a_EffectType); + protected: typedef std::map tEffectMap; tEffectMap m_EntityEffects; diff --git a/src/Entities/Player.cpp b/src/Entities/Player.cpp index db4b07553..009f1e829 100644 --- a/src/Entities/Player.cpp +++ b/src/Entities/Player.cpp @@ -2636,3 +2636,95 @@ void cPlayer::FreezeInternal(const Vector3d & a_Location, bool a_ManuallyFrozen) m_FlyingMaxSpeed = FlyingMaxpeed; m_IsFlying = IsFlying; } + + + + +float cPlayer::GetLiquidHeightPercent(NIBBLETYPE a_Meta) +{ + if (a_Meta >= 8) + { + a_Meta = 0; + } + return static_cast(a_Meta + 1) / 9.0f; +} + + + + + +bool cPlayer::IsInsideWater() +{ + BLOCKTYPE Block = m_World->GetBlock(FloorC(GetPosX()), FloorC(m_Stance), FloorC(GetPosZ())); + if ((Block != E_BLOCK_WATER) && (Block != E_BLOCK_STATIONARY_WATER)) + { + return false; + } + NIBBLETYPE Meta = GetWorld()->GetBlockMeta(FloorC(GetPosX()), FloorC(m_Stance), FloorC(GetPosZ())); + float f = GetLiquidHeightPercent(Meta) - 0.11111111f; + float f1 = static_cast(m_Stance + 1) - f; + bool flag = (m_Stance < f1); + return flag; +} + + + + + +float cPlayer::GetDigSpeed(BLOCKTYPE a_Block) +{ + float f = GetEquippedItem().GetHandler()->GetBlockBreakingStrength(a_Block); + if (f > 1.0f) + { + unsigned int efficiencyModifier = GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::eEnchantment::enchEfficiency); + if (efficiencyModifier > 0) + { + f += (efficiencyModifier * efficiencyModifier) + 1; + } + } + + if (HasEntityEffect(cEntityEffect::effHaste)) + { + int intensity = GetEntityEffect(cEntityEffect::effHaste)->GetIntensity() + 1; + f *= 1.0f + (intensity * 0.2f); + } + + if (HasEntityEffect(cEntityEffect::effMiningFatigue)) + { + int intensity = GetEntityEffect(cEntityEffect::effMiningFatigue)->GetIntensity(); + switch (intensity) + { + case 0: f *= 0.3f; break; + case 1: f *= 0.09f; break; + case 2: f *= 0.0027f; break; + default: f *= 0.00081f; break; + + } + } + + if (IsInsideWater() && !(GetEquippedItem().m_Enchantments.GetLevel(cEnchantments::eEnchantment::enchAquaAffinity) > 0)) + { + f /= 5.0f; + } + + if (!IsOnGround()) + { + f /= 5.0f; + } + + return f; +} + + + + + +float cPlayer::GetPlayerRelativeBlockHardness(BLOCKTYPE a_Block) +{ + float blockHardness = cBlockInfo::GetHardness(a_Block); + float digSpeed = GetDigSpeed(a_Block); + float canHarvestBlockDivisor = GetEquippedItem().GetHandler()->CanHarvestBlock(a_Block) ? 30.0f : 100.0f; + // LOGD("blockHardness: %f, digSpeed: %f, canHarvestBlockDivisor: %f\n", blockHardness, digSpeed, canHarvestBlockDivisor); + return (blockHardness < 0) ? 0 : ((digSpeed / blockHardness) / canHarvestBlockDivisor); +} + diff --git a/src/Entities/Player.h b/src/Entities/Player.h index cc83b1ca2..3de1a4cb5 100644 --- a/src/Entities/Player.h +++ b/src/Entities/Player.h @@ -529,6 +529,12 @@ public: The player removes its m_ClientHandle ownership so that the ClientHandle gets deleted. */ void RemoveClientHandle(void); + /** Returns the relative block hardness for the block a_Block. + The bigger it is the faster the player can break the block. + Returns zero if the block is instant breakable. + Otherwise it returns the dig speed (float GetDigSpeed(BLOCKTYPE a_Block)) divided by the block hardness (cBlockInfo::GetHardness(BLOCKTYPE a_Block)) divided by 30 if the player can harvest the block and divided by 100 if he can't. */ + float GetPlayerRelativeBlockHardness(BLOCKTYPE a_Block); + protected: typedef std::vector > AStringVectorVector; @@ -710,4 +716,19 @@ private: /** Pins the player to a_Location until Unfreeze() is called. If ManuallyFrozen is false, the player will unfreeze when the chunk is loaded. */ void FreezeInternal(const Vector3d & a_Location, bool a_ManuallyFrozen); + + /** Returns how high the liquid is in percent. Used by IsInsideWater */ + float GetLiquidHeightPercent(NIBBLETYPE a_Meta); + + /** Checks if the player is inside of water */ + bool IsInsideWater(); + + /** Returns the dig speed using the current tool on the block a_Block. + Returns one if using hand. + If the player is using a tool that is good to break the block the value is higher. + If he has an enchanted tool with efficiency or he has a haste or mining fatique effect it gets multiplied by a specific factor depending on the strength of the effect or enchantment. + In he is in water it gets divided by 5 except his tool is enchanted with aqa affinity. + If he is not on ground it also gets divided by 5. */ + float GetDigSpeed(BLOCKTYPE a_Block); + } ; // tolua_export diff --git a/src/Items/CMakeLists.txt b/src/Items/CMakeLists.txt index eacc1e53f..72858591a 100644 --- a/src/Items/CMakeLists.txt +++ b/src/Items/CMakeLists.txt @@ -55,6 +55,7 @@ SET (HDRS ItemSugarcane.h ItemSword.h ItemThrowable.h + ItemAxe.h ) if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") diff --git a/src/Items/ItemAxe.h b/src/Items/ItemAxe.h new file mode 100644 index 000000000..656497199 --- /dev/null +++ b/src/Items/ItemAxe.h @@ -0,0 +1,48 @@ + +#pragma once + +#include "ItemHandler.h" +#include "../World.h" +#include "../Entities/Player.h" + + + + + +class cItemAxeHandler : + public cItemHandler +{ + typedef cItemHandler super; +public: + cItemAxeHandler(int a_ItemType) + : cItemHandler(a_ItemType) + { + } + + + virtual float GetBlockBreakingStrength(BLOCKTYPE a_Block) + { + if (!IsBlockMaterialWood(a_Block) && !IsBlockMaterialPlants(a_Block) && !IsBlockMaterialVine(a_Block)) + { + return super::GetBlockBreakingStrength(a_Block); + } + else + { + switch (m_ItemType) + { + case E_ITEM_WOODEN_AXE: return 2.0f; + case E_ITEM_STONE_AXE: return 4.0f; + case E_ITEM_IRON_AXE: return 6.0f; + case E_ITEM_GOLD_AXE: return 12.0f; + case E_ITEM_DIAMOND_AXE: return 8.0f; + } + } + ASSERT(!"Something is wrong here... Maybe they are axes out of a new material?"); + return 1.0f; + } + +} ; + + + + diff --git a/src/Items/ItemHandler.cpp b/src/Items/ItemHandler.cpp index 8a05149b0..6984b6111 100644 --- a/src/Items/ItemHandler.cpp +++ b/src/Items/ItemHandler.cpp @@ -56,6 +56,7 @@ #include "ItemSugarcane.h" #include "ItemSword.h" #include "ItemThrowable.h" +#include "ItemAxe.h" #include "../Blocks/BlockHandler.h" @@ -180,6 +181,15 @@ cItemHandler * cItemHandler::CreateItemHandler(int a_ItemType) return new cItemShovelHandler(a_ItemType); } + case E_ITEM_WOODEN_AXE: + case E_ITEM_STONE_AXE: + case E_ITEM_IRON_AXE: + case E_ITEM_GOLD_AXE: + case E_ITEM_DIAMOND_AXE: + { + return new cItemAxeHandler(a_ItemType); + } + case E_ITEM_WOODEN_SWORD: case E_ITEM_STONE_SWORD: case E_ITEM_IRON_SWORD: @@ -866,3 +876,13 @@ cItemHandler::FoodInfo cItemHandler::GetFoodInfo() + + + + + +float cItemHandler::GetBlockBreakingStrength(BLOCKTYPE a_Block) +{ + return 1.0f; +} + diff --git a/src/Items/ItemHandler.h b/src/Items/ItemHandler.h index a2b825fb7..8141bfb23 100644 --- a/src/Items/ItemHandler.h +++ b/src/Items/ItemHandler.h @@ -154,6 +154,10 @@ public: Defaults to false unless overridden. */ virtual bool CanHarvestBlock(BLOCKTYPE a_BlockType); + /** Returns the strength to break a specific block. + Defaults to 1 unless overriden. */ + virtual float GetBlockBreakingStrength(BLOCKTYPE a_Block); + static cItemHandler * GetItemHandler(int a_ItemType); static cItemHandler * GetItemHandler(const cItem & a_Item) { return GetItemHandler(a_Item.m_ItemType); } diff --git a/src/Items/ItemPickaxe.h b/src/Items/ItemPickaxe.h index dba4926db..6e8452cd9 100644 --- a/src/Items/ItemPickaxe.h +++ b/src/Items/ItemPickaxe.h @@ -107,6 +107,29 @@ public: } return false; } + + + virtual float GetBlockBreakingStrength(BLOCKTYPE a_Block) + { + if (!IsBlockMaterialIron(a_Block) && !IsBlockMaterialAnvil(a_Block) && !IsBlockMaterialRock(a_Block)) + { + return super::GetBlockBreakingStrength(a_Block); + } + else + { + switch (m_ItemType) + { + case E_ITEM_WOODEN_PICKAXE: return 2.0f; + case E_ITEM_STONE_PICKAXE: return 4.0f; + case E_ITEM_IRON_PICKAXE: return 6.0f; + case E_ITEM_GOLD_PICKAXE: return 12.0f; + case E_ITEM_DIAMOND_PICKAXE: return 8.0f; + } + } + ASSERT(!"Something is wrong here... Maybe they are pickaxes out of a new material?"); + return 1.0f; + } + } ; diff --git a/src/Items/ItemShears.h b/src/Items/ItemShears.h index c8034b112..745432ca0 100644 --- a/src/Items/ItemShears.h +++ b/src/Items/ItemShears.h @@ -90,6 +90,28 @@ public: } } } + + + + virtual float GetBlockBreakingStrength(BLOCKTYPE a_Block) + { + if (IsBlocksWeb(a_Block) || IsBlockMaterialLeaves(a_Block)) + { + return 15.0f; + } + else + { + if (IsBlocksWool(a_Block)) + { + return 5.0f; + } + else + { + return super::GetBlockBreakingStrength(a_Block); + } + } + } + } ; diff --git a/src/Items/ItemShovel.h b/src/Items/ItemShovel.h index 739ed833e..e5aae26a7 100644 --- a/src/Items/ItemShovel.h +++ b/src/Items/ItemShovel.h @@ -59,4 +59,35 @@ public: return false; } + virtual float GetBlockBreakingStrength(BLOCKTYPE a_Block) + { + switch (a_Block) + { + case E_BLOCK_CLAY: + case E_BLOCK_DIRT: + case E_BLOCK_FARMLAND: + case E_BLOCK_GRASS: + case E_BLOCK_GRAVEL: + case E_BLOCK_MYCELIUM: + case E_BLOCK_SAND: + case E_BLOCK_SNOW: + case E_BLOCK_SNOW_BLOCK: + case E_BLOCK_SOULSAND: + case E_BLOCK_GRASS_PATH: + { + switch (m_ItemType) + { + case E_ITEM_WOODEN_SHOVEL: return 2.0f; + case E_ITEM_STONE_SHOVEL: return 4.0f; + case E_ITEM_IRON_SHOVEL: return 6.0f; + case E_ITEM_GOLD_SHOVEL: return 12.0f; + case E_ITEM_DIAMOND_SHOVEL: return 8.0f; + } + break; + } + default: return super::GetBlockBreakingStrength(a_Block); + } + ASSERT(!"Something is wrong here... Maybe they are shovels out of a new material?"); + return 1.0f; + } }; diff --git a/src/Items/ItemSword.h b/src/Items/ItemSword.h index a15a9e3db..26372cc40 100644 --- a/src/Items/ItemSword.h +++ b/src/Items/ItemSword.h @@ -56,6 +56,34 @@ public: return 0; #endif } + + + + virtual float GetBlockBreakingStrength(BLOCKTYPE a_Block) + { + if (a_Block == E_BLOCK_COBWEB) + { + return 15.0f; + } + else + { + if ( + IsBlockMaterialPlants(a_Block) || + IsBlockMaterialVine(a_Block) || + IsBlockMaterialCoral(a_Block) || + IsBlockMaterialLeaves(a_Block) || + IsBlockMaterialGourd(a_Block) + ) + { + return 1.5f; + } + else + { + return 1.0f; + } + } + } + } ; diff --git a/src/Root.cpp b/src/Root.cpp index 09c6a74d3..27277512c 100644 --- a/src/Root.cpp +++ b/src/Root.cpp @@ -150,6 +150,9 @@ void cRoot::Start(std::unique_ptr a_OverridesRepo) auto settingsRepo = cpp14::make_unique(std::move(IniFile), std::move(a_OverridesRepo)); LOG("Starting server..."); + + cClientHandle::FASTBREAK_PERCENTAGE = settingsRepo->GetValueSetI("AntiCheat", "FastBreakPercentage", 97) / 100.0f; + m_MojangAPI = new cMojangAPI; bool ShouldAuthenticate = settingsRepo->GetValueSetB("Authentication", "Authenticate", true); m_MojangAPI->Start(*settingsRepo, ShouldAuthenticate); // Mojang API needs to be started before plugins, so that plugins may use it for DB upgrades on server init -- cgit v1.2.3