mirror of
https://github.com/BentoBoxWorld/Level.git
synced 2024-11-27 20:46:19 +01:00
Merge remote-tracking branch 'origin/bentobox' into develop
This commit is contained in:
commit
8f0209c18a
37
addon.yml
Executable file
37
addon.yml
Executable file
@ -0,0 +1,37 @@
|
|||||||
|
name: BSkyBlock-Level
|
||||||
|
main: bskyblock.addon.level.Level
|
||||||
|
version: 0.1
|
||||||
|
|
||||||
|
authors: tastybento
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
bskyblock.intopten:
|
||||||
|
description: Player is in the top ten.
|
||||||
|
default: true
|
||||||
|
bskyblock.island.level:
|
||||||
|
description: Player can use level command
|
||||||
|
default: true
|
||||||
|
bskyblock.island.top:
|
||||||
|
description: Player can use top ten command
|
||||||
|
default: true
|
||||||
|
bskyblock.admin.level:
|
||||||
|
description: Player can use admin level command
|
||||||
|
default: true
|
||||||
|
bskyblock.admin.topten:
|
||||||
|
description: Player can use admin top ten command
|
||||||
|
default: true
|
||||||
|
acidisland.intopten:
|
||||||
|
description: Player is in the top ten.
|
||||||
|
default: true
|
||||||
|
acidisland.island.level:
|
||||||
|
description: Player can use level command
|
||||||
|
default: true
|
||||||
|
acidisland.island.top:
|
||||||
|
description: Player can use top ten command
|
||||||
|
default: true
|
||||||
|
acidisland.admin.level:
|
||||||
|
description: Player can use admin level command
|
||||||
|
default: true
|
||||||
|
acidisland.admin.topten:
|
||||||
|
description: Player can use admin top ten command
|
||||||
|
default: true
|
648
config.yml
648
config.yml
@ -35,271 +35,613 @@ teamjoindeathreset: true
|
|||||||
# This section lists the limits for any particular block. Blocks over this amount
|
# This section lists the limits for any particular block. Blocks over this amount
|
||||||
# are not counted.
|
# are not counted.
|
||||||
# Format:
|
# Format:
|
||||||
# MATERIAL: limit or MATERIAL:DATA: limit.
|
# MATERIAL: limit
|
||||||
# If DATA is used, there MUST be a corresponding block:data value in the blocks list.
|
|
||||||
# For example, if you limit Jungle Logs LOG:3, then there must be a value for LOG:3
|
|
||||||
# in the blocks section. If there is not, then LOG:3 would have no value.
|
|
||||||
limits:
|
limits:
|
||||||
COBBLESTONE: 10000
|
COBBLESTONE: 10000
|
||||||
NETHERRACK: 1000
|
NETHERRACK: 1000
|
||||||
#LOG:3: 10
|
|
||||||
|
|
||||||
# This section lists the value of a block. Value must be an integer.
|
# This section lists the value of a block. Value must be an integer.
|
||||||
# Any blocks not listed will have a value of zero.
|
# Any blocks not listed will have a value of 1. AIR is always zero.
|
||||||
# Format is MATERIAL: value or MATERIAL:DATA: value.
|
# Format is MATERIAL: value
|
||||||
|
|
||||||
blocks:
|
blocks:
|
||||||
|
ACACIA_BUTTON: 1
|
||||||
ACACIA_DOOR: 1
|
ACACIA_DOOR: 1
|
||||||
ACACIA_STAIRS: 1
|
ACACIA_FENCE: 2
|
||||||
ACACIA_FENCE: 1
|
|
||||||
ACACIA_FENCE_GATE: 1
|
ACACIA_FENCE_GATE: 1
|
||||||
|
ACACIA_LEAVES: 0
|
||||||
|
ACACIA_LOG: 0
|
||||||
|
ACACIA_PLANKS: 1
|
||||||
|
ACACIA_PRESSURE_PLATE: 1
|
||||||
|
ACACIA_SAPLING: 1
|
||||||
|
ACACIA_SLAB: 1
|
||||||
ACACIA_STAIRS: 2
|
ACACIA_STAIRS: 2
|
||||||
ACTIVATOR_RAIL: 10
|
ACACIA_TRAPDOOR: 1
|
||||||
AIR: 0
|
ACACIA_WOOD: 1
|
||||||
|
ACTIVATOR_RAIL: 1
|
||||||
|
ALLIUM: 1
|
||||||
|
ANDESITE: 1
|
||||||
ANVIL: 10
|
ANVIL: 10
|
||||||
ARMOR_STAND: 2
|
ATTACHED_MELON_STEM: 1
|
||||||
BANNER: 2
|
ATTACHED_PUMPKIN_STEM: 1
|
||||||
BEACON: 100
|
AZURE_BLUET: 1
|
||||||
BED_BLOCK: 1
|
BARRIER: 0
|
||||||
|
BEACON: 500
|
||||||
BEDROCK: 0
|
BEDROCK: 0
|
||||||
BEETROOT_BLOCK: 1
|
BEETROOTS: 1
|
||||||
|
BIRCH_BUTTON: 1
|
||||||
BIRCH_DOOR: 1
|
BIRCH_DOOR: 1
|
||||||
BIRCH_FENCE: 1
|
BIRCH_FENCE: 2
|
||||||
BIRCH_FENCE_GATE: 1
|
BIRCH_FENCE_GATE: 1
|
||||||
BIRCH_WOOD_STAIRS: 1
|
BIRCH_LEAVES: 0
|
||||||
|
BIRCH_LOG: 0
|
||||||
|
BIRCH_PLANKS: 1
|
||||||
|
BIRCH_PRESSURE_PLATE: 1
|
||||||
|
BIRCH_SAPLING: 1
|
||||||
|
BIRCH_SLAB: 1
|
||||||
|
BIRCH_STAIRS: 2
|
||||||
|
BIRCH_TRAPDOOR: 1
|
||||||
|
BIRCH_WOOD: 1
|
||||||
|
BLACK_BANNER: 2
|
||||||
|
BLACK_BED: 2
|
||||||
|
BLACK_CARPET: 1
|
||||||
|
BLACK_CONCRETE: 1
|
||||||
|
BLACK_CONCRETE_POWDER: 1
|
||||||
BLACK_GLAZED_TERRACOTTA: 1
|
BLACK_GLAZED_TERRACOTTA: 1
|
||||||
BLACK_SHULKER_BOX: 1
|
BLACK_SHULKER_BOX: 1
|
||||||
|
BLACK_STAINED_GLASS: 2
|
||||||
|
BLACK_STAINED_GLASS_PANE: 1
|
||||||
|
BLACK_TERRACOTTA: 1
|
||||||
|
BLACK_WALL_BANNER: 2
|
||||||
|
BLACK_WOOL: 1
|
||||||
|
BLUE_BANNER: 2
|
||||||
|
BLUE_BED: 2
|
||||||
|
BLUE_CARPET: 1
|
||||||
|
BLUE_CONCRETE: 1
|
||||||
|
BLUE_CONCRETE_POWDER: 1
|
||||||
BLUE_GLAZED_TERRACOTTA: 1
|
BLUE_GLAZED_TERRACOTTA: 1
|
||||||
|
BLUE_ICE: 1
|
||||||
|
BLUE_ORCHID: 1
|
||||||
BLUE_SHULKER_BOX: 1
|
BLUE_SHULKER_BOX: 1
|
||||||
BOAT: 2
|
BLUE_STAINED_GLASS: 2
|
||||||
BOAT_ACACIA: 2
|
BLUE_STAINED_GLASS_PANE: 1
|
||||||
BOAT_BIRCH: 2
|
BLUE_TERRACOTTA: 1
|
||||||
BOAT_DARK_OAK: 2
|
BLUE_WALL_BANNER: 2
|
||||||
BOAT_JUNGLE: 2
|
BLUE_WOOL: 1
|
||||||
BOAT_SPRUCE: 2
|
|
||||||
BONE_BLOCK: 1
|
BONE_BLOCK: 1
|
||||||
BOOKSHELF: 5
|
BOOKSHELF: 5
|
||||||
|
BRAIN_CORAL: 1
|
||||||
|
BRAIN_CORAL_BLOCK: 1
|
||||||
|
BRAIN_CORAL_FAN: 1
|
||||||
|
BRAIN_CORAL_WALL_FAN: 1
|
||||||
BREWING_STAND: 20
|
BREWING_STAND: 20
|
||||||
BRICK: 5
|
BRICKS: 5
|
||||||
|
BRICK_SLAB: 3
|
||||||
BRICK_STAIRS: 5
|
BRICK_STAIRS: 5
|
||||||
|
BROWN_BANNER: 2
|
||||||
|
BROWN_BED: 2
|
||||||
|
BROWN_CARPET: 1
|
||||||
|
BROWN_CONCRETE: 1
|
||||||
|
BROWN_CONCRETE_POWDER: 1
|
||||||
BROWN_GLAZED_TERRACOTTA: 1
|
BROWN_GLAZED_TERRACOTTA: 1
|
||||||
|
BROWN_MUSHROOM: 1
|
||||||
|
BROWN_MUSHROOM_BLOCK: 1
|
||||||
BROWN_SHULKER_BOX: 1
|
BROWN_SHULKER_BOX: 1
|
||||||
BURNING_FURNACE: 10
|
BROWN_STAINED_GLASS: 2
|
||||||
|
BROWN_STAINED_GLASS_PANE: 1
|
||||||
|
BROWN_TERRACOTTA: 1
|
||||||
|
BROWN_WALL_BANNER: 2
|
||||||
|
BROWN_WOOL: 1
|
||||||
|
BUBBLE_COLUMN: 1
|
||||||
|
BUBBLE_CORAL: 1
|
||||||
|
BUBBLE_CORAL_BLOCK: 1
|
||||||
|
BUBBLE_CORAL_FAN: 1
|
||||||
|
BUBBLE_CORAL_WALL_FAN: 1
|
||||||
CACTUS: 1
|
CACTUS: 1
|
||||||
CAKE_BLOCK: 1
|
CAKE: 1
|
||||||
CARPET: 1
|
CARROTS: 1
|
||||||
|
CARVED_PUMPKIN: 1
|
||||||
CAULDRON: 10
|
CAULDRON: 10
|
||||||
|
CAVE_AIR: 1
|
||||||
|
CHAIN_COMMAND_BLOCK: 1
|
||||||
CHEST: 2
|
CHEST: 2
|
||||||
|
CHIPPED_ANVIL: 9
|
||||||
|
CHISELED_QUARTZ_BLOCK: 1
|
||||||
|
CHISELED_RED_SANDSTONE: 1
|
||||||
|
CHISELED_SANDSTONE: 1
|
||||||
|
CHISELED_STONE_BRICKS: 2
|
||||||
CHORUS_FLOWER: 1
|
CHORUS_FLOWER: 1
|
||||||
CHORUS_PLANT: 1
|
CHORUS_PLANT: 1
|
||||||
CLAY: 2
|
CLAY: 2
|
||||||
COAL_BLOCK: 9
|
COAL_BLOCK: 9
|
||||||
COAL_ORE: 0
|
COAL_ORE: 1
|
||||||
COBBLE_WALL: 1
|
COARSE_DIRT: 1
|
||||||
COBBLESTONE: 1
|
COBBLESTONE: 1
|
||||||
COBBLESTONE_STAIRS: 1
|
COBBLESTONE_SLAB: 1
|
||||||
|
COBBLESTONE_STAIRS: 2
|
||||||
|
COBBLESTONE_WALL: 1
|
||||||
|
COBWEB: 10
|
||||||
COCOA: 1
|
COCOA: 1
|
||||||
CONCRETE: 1
|
COMMAND_BLOCK: 1
|
||||||
CONCRETE_POWDER: 1
|
COMPARATOR: 10
|
||||||
|
CONDUIT: 1
|
||||||
|
CRACKED_STONE_BRICKS: 2
|
||||||
|
CRAFTING_TABLE: 1
|
||||||
|
CREEPER_HEAD: 1
|
||||||
|
CREEPER_WALL_HEAD: 1
|
||||||
|
CUT_RED_SANDSTONE: 1
|
||||||
|
CUT_SANDSTONE: 1
|
||||||
|
CYAN_BANNER: 2
|
||||||
|
CYAN_BED: 2
|
||||||
|
CYAN_CARPET: 1
|
||||||
|
CYAN_CONCRETE: 1
|
||||||
|
CYAN_CONCRETE_POWDER: 1
|
||||||
CYAN_GLAZED_TERRACOTTA: 1
|
CYAN_GLAZED_TERRACOTTA: 1
|
||||||
CYAN_SHULKER_BOX: 1
|
CYAN_SHULKER_BOX: 1
|
||||||
|
CYAN_STAINED_GLASS: 2
|
||||||
|
CYAN_STAINED_GLASS_PANE: 1
|
||||||
|
CYAN_TERRACOTTA: 1
|
||||||
|
CYAN_WALL_BANNER: 2
|
||||||
|
CYAN_WOOL: 1
|
||||||
|
DAMAGED_ANVIL: 5
|
||||||
|
DANDELION: 1
|
||||||
|
DARK_OAK_BUTTON: 1
|
||||||
DARK_OAK_DOOR: 1
|
DARK_OAK_DOOR: 1
|
||||||
DARK_OAK_FENCE: 1
|
DARK_OAK_FENCE: 2
|
||||||
DARK_OAK_FENCE_GATE: 1
|
DARK_OAK_FENCE_GATE: 1
|
||||||
DARK_OAK_STAIRS: 1
|
DARK_OAK_LEAVES: 0
|
||||||
|
DARK_OAK_LOG: 0
|
||||||
|
DARK_OAK_PLANKS: 1
|
||||||
|
DARK_OAK_PRESSURE_PLATE: 1
|
||||||
|
DARK_OAK_SAPLING: 1
|
||||||
|
DARK_OAK_SLAB: 1
|
||||||
|
DARK_OAK_STAIRS: 2
|
||||||
|
DARK_OAK_TRAPDOOR: 1
|
||||||
|
DARK_OAK_WOOD: 1
|
||||||
|
DARK_PRISMARINE: 1
|
||||||
|
DARK_PRISMARINE_SLAB: 1
|
||||||
|
DARK_PRISMARINE_STAIRS: 2
|
||||||
DAYLIGHT_DETECTOR: 10
|
DAYLIGHT_DETECTOR: 10
|
||||||
DAYLIGHT_DETECTOR_INVERTED: 10
|
DEAD_BRAIN_CORAL_BLOCK: 1
|
||||||
|
DEAD_BRAIN_CORAL_FAN: 1
|
||||||
|
DEAD_BRAIN_CORAL_WALL_FAN: 1
|
||||||
|
DEAD_BUBBLE_CORAL_BLOCK: 1
|
||||||
|
DEAD_BUBBLE_CORAL_FAN: 1
|
||||||
|
DEAD_BUBBLE_CORAL_WALL_FAN: 1
|
||||||
DEAD_BUSH: 1
|
DEAD_BUSH: 1
|
||||||
|
DEAD_FIRE_CORAL_BLOCK: 1
|
||||||
|
DEAD_FIRE_CORAL_FAN: 1
|
||||||
|
DEAD_FIRE_CORAL_WALL_FAN: 1
|
||||||
|
DEAD_HORN_CORAL_BLOCK: 1
|
||||||
|
DEAD_HORN_CORAL_FAN: 1
|
||||||
|
DEAD_HORN_CORAL_WALL_FAN: 1
|
||||||
|
DEAD_TUBE_CORAL_BLOCK: 1
|
||||||
|
DEAD_TUBE_CORAL_FAN: 1
|
||||||
|
DEAD_TUBE_CORAL_WALL_FAN: 1
|
||||||
DETECTOR_RAIL: 10
|
DETECTOR_RAIL: 10
|
||||||
DIAMOND_BLOCK: 300
|
DIAMOND_BLOCK: 300
|
||||||
DIODE: 5
|
DIAMOND_ORE: 1
|
||||||
DIODE_BLOCK_OFF: 5
|
DIORITE: 1
|
||||||
DIODE_BLOCK_ON: 5
|
DIRT: 1
|
||||||
DIRT: 2
|
|
||||||
DISPENSER: 5
|
DISPENSER: 5
|
||||||
DOUBLE_PLANT: 2
|
|
||||||
DOUBLE_STEP: 1
|
|
||||||
DOUBLE_STONE_SLAB2: 1
|
|
||||||
DRAGON_EGG: 150
|
DRAGON_EGG: 150
|
||||||
|
DRAGON_HEAD: 1
|
||||||
|
DRAGON_WALL_HEAD: 1
|
||||||
|
DRIED_KELP_BLOCK: 1
|
||||||
DROPPER: 5
|
DROPPER: 5
|
||||||
EMERALD_BLOCK: 150
|
EMERALD_BLOCK: 150
|
||||||
EMERALD_ORE: 0
|
EMERALD_ORE: 1
|
||||||
ENCHANTMENT_TABLE: 150
|
ENCHANTING_TABLE: 150
|
||||||
END_BRICKS: 2
|
|
||||||
ENDER_CHEST: 150
|
ENDER_CHEST: 150
|
||||||
ENDER_PORTAL_FRAME: 0
|
END_GATEWAY: 0
|
||||||
ENDER_PORTAL: 0
|
END_PORTAL: 0
|
||||||
ENDER_STONE: 2
|
END_PORTAL_FRAME: 0
|
||||||
EXPLOSIVE_MINECART: 10
|
END_ROD: 1
|
||||||
FENCE: 1
|
END_STONE: 1
|
||||||
FENCE_GATE: 1
|
END_STONE_BRICKS: 2
|
||||||
|
FARMLAND: 1
|
||||||
|
FERN: 1
|
||||||
FIRE: 0
|
FIRE: 0
|
||||||
FLOWER_POT: 5
|
FIRE_CORAL: 1
|
||||||
|
FIRE_CORAL_BLOCK: 1
|
||||||
|
FIRE_CORAL_FAN: 1
|
||||||
|
FIRE_CORAL_WALL_FAN: 1
|
||||||
|
FLOWER_POT: 1
|
||||||
FROSTED_ICE: 1
|
FROSTED_ICE: 1
|
||||||
FURNACE: 10
|
FURNACE: 8
|
||||||
GLASS: 2
|
GLASS: 2
|
||||||
|
GLASS_PANE: 1
|
||||||
GLOWSTONE: 1
|
GLOWSTONE: 1
|
||||||
GOLD_BLOCK: 150
|
GOLD_BLOCK: 150
|
||||||
GOLD_ORE: 0
|
GOLD_ORE: 1
|
||||||
GRASS: 5
|
GRANITE: 1
|
||||||
GRASS_PATH: 5
|
GRASS: 1
|
||||||
|
GRASS_BLOCK: 1
|
||||||
|
GRASS_PATH: 1
|
||||||
|
GRAVEL: 1
|
||||||
|
GRAY_BANNER: 2
|
||||||
|
GRAY_BED: 2
|
||||||
|
GRAY_CARPET: 1
|
||||||
|
GRAY_CONCRETE: 1
|
||||||
|
GRAY_CONCRETE_POWDER: 1
|
||||||
GRAY_GLAZED_TERRACOTTA: 1
|
GRAY_GLAZED_TERRACOTTA: 1
|
||||||
GRAY_SHULKER_BOX: 1
|
GRAY_SHULKER_BOX: 1
|
||||||
GRAVEL: 1
|
GRAY_STAINED_GLASS: 2
|
||||||
|
GRAY_STAINED_GLASS_PANE: 1
|
||||||
|
GRAY_TERRACOTTA: 1
|
||||||
|
GRAY_WALL_BANNER: 2
|
||||||
|
GRAY_WOOL: 1
|
||||||
|
GREEN_BANNER: 2
|
||||||
|
GREEN_BED: 2
|
||||||
|
GREEN_CARPET: 1
|
||||||
|
GREEN_CONCRETE: 1
|
||||||
|
GREEN_CONCRETE_POWDER: 1
|
||||||
GREEN_GLAZED_TERRACOTTA: 1
|
GREEN_GLAZED_TERRACOTTA: 1
|
||||||
GREEN_SHULKER_BOX: 1
|
GREEN_SHULKER_BOX: 1
|
||||||
HARD_CLAY: 2
|
GREEN_STAINED_GLASS: 2
|
||||||
|
GREEN_STAINED_GLASS_PANE: 1
|
||||||
|
GREEN_TERRACOTTA: 1
|
||||||
|
GREEN_WALL_BANNER: 2
|
||||||
|
GREEN_WOOL: 1
|
||||||
HAY_BLOCK: 2
|
HAY_BLOCK: 2
|
||||||
HOPPER: 10
|
HEAVY_WEIGHTED_PRESSURE_PLATE: 1
|
||||||
HOPPER_MINECART: 20
|
HOPPER: -10
|
||||||
HUGE_MUSHROOM_1: 1
|
HORN_CORAL: 1
|
||||||
HUGE_MUSHROOM_2: 1
|
HORN_CORAL_BLOCK: 1
|
||||||
|
HORN_CORAL_FAN: 1
|
||||||
|
HORN_CORAL_WALL_FAN: 1
|
||||||
ICE: 5
|
ICE: 5
|
||||||
|
INFESTED_CHISELED_STONE_BRICKS: 2
|
||||||
|
INFESTED_COBBLESTONE: 1
|
||||||
|
INFESTED_CRACKED_STONE_BRICKS: 2
|
||||||
|
INFESTED_MOSSY_STONE_BRICKS: 2
|
||||||
|
INFESTED_STONE: 1
|
||||||
|
INFESTED_STONE_BRICKS: 2
|
||||||
|
IRON_BARS: 1
|
||||||
IRON_BLOCK: 10
|
IRON_BLOCK: 10
|
||||||
IRON_DOOR_BLOCK: 5
|
IRON_DOOR: 5
|
||||||
IRON_FENCE: 5
|
IRON_ORE: 1
|
||||||
IRON_ORE: 0
|
|
||||||
IRON_PLATE: 5
|
|
||||||
IRON_TRAPDOOR: 1
|
IRON_TRAPDOOR: 1
|
||||||
ITEM_FRAME: 2
|
|
||||||
JACK_O_LANTERN: 1
|
JACK_O_LANTERN: 1
|
||||||
JUKEBOX: 10
|
JUKEBOX: 10
|
||||||
|
JUNGLE_BUTTON: 1
|
||||||
JUNGLE_DOOR: 1
|
JUNGLE_DOOR: 1
|
||||||
JUNGLE_FENCE: 1
|
JUNGLE_FENCE: 2
|
||||||
JUNGLE_FENCE_GATE: 1
|
JUNGLE_FENCE_GATE: 1
|
||||||
JUNGLE_WOOD_STAIRS: 1
|
JUNGLE_LEAVES: 0
|
||||||
|
JUNGLE_LOG: 0
|
||||||
|
JUNGLE_PLANKS: 1
|
||||||
|
JUNGLE_PRESSURE_PLATE: 1
|
||||||
|
JUNGLE_SAPLING: 1
|
||||||
|
JUNGLE_SLAB: 1
|
||||||
|
JUNGLE_STAIRS: 2
|
||||||
|
JUNGLE_TRAPDOOR: 1
|
||||||
|
JUNGLE_WOOD: 1
|
||||||
|
KELP: 1
|
||||||
|
KELP_PLANT: 1
|
||||||
LADDER: 1
|
LADDER: 1
|
||||||
LAPIS_BLOCK: 10
|
LAPIS_BLOCK: 10
|
||||||
LAPIS_ORE: 0
|
LAPIS_ORE: 1
|
||||||
|
LARGE_FERN: 1
|
||||||
LAVA: 0
|
LAVA: 0
|
||||||
LEAVES_2: 1
|
|
||||||
LEAVES: 1
|
|
||||||
LEVER: 1
|
LEVER: 1
|
||||||
|
LIGHT_BLUE_BANNER: 2
|
||||||
|
LIGHT_BLUE_BED: 2
|
||||||
|
LIGHT_BLUE_CARPET: 1
|
||||||
|
LIGHT_BLUE_CONCRETE: 1
|
||||||
|
LIGHT_BLUE_CONCRETE_POWDER: 1
|
||||||
LIGHT_BLUE_GLAZED_TERRACOTTA: 1
|
LIGHT_BLUE_GLAZED_TERRACOTTA: 1
|
||||||
LIGHT_BLUE_SHULKER_BOX: 1
|
LIGHT_BLUE_SHULKER_BOX: 1
|
||||||
|
LIGHT_BLUE_STAINED_GLASS: 2
|
||||||
|
LIGHT_BLUE_STAINED_GLASS_PANE: 1
|
||||||
|
LIGHT_BLUE_TERRACOTTA: 1
|
||||||
|
LIGHT_BLUE_WALL_BANNER: 2
|
||||||
|
LIGHT_BLUE_WOOL: 1
|
||||||
|
LIGHT_GRAY_BANNER: 2
|
||||||
|
LIGHT_GRAY_BED: 2
|
||||||
|
LIGHT_GRAY_CARPET: 1
|
||||||
|
LIGHT_GRAY_CONCRETE: 1
|
||||||
|
LIGHT_GRAY_CONCRETE_POWDER: 1
|
||||||
|
LIGHT_GRAY_GLAZED_TERRACOTTA: 1
|
||||||
|
LIGHT_GRAY_SHULKER_BOX: 1
|
||||||
|
LIGHT_GRAY_STAINED_GLASS: 2
|
||||||
|
LIGHT_GRAY_STAINED_GLASS_PANE: 1
|
||||||
|
LIGHT_GRAY_TERRACOTTA: 1
|
||||||
|
LIGHT_GRAY_WALL_BANNER: 2
|
||||||
|
LIGHT_GRAY_WOOL: 1
|
||||||
|
LIGHT_WEIGHTED_PRESSURE_PLATE: 1
|
||||||
|
LILAC: 1
|
||||||
|
LILY_PAD: 5
|
||||||
|
LIME_BANNER: 2
|
||||||
|
LIME_BED: 2
|
||||||
|
LIME_CARPET: 1
|
||||||
|
LIME_CONCRETE: 1
|
||||||
|
LIME_CONCRETE_POWDER: 1
|
||||||
LIME_GLAZED_TERRACOTTA: 1
|
LIME_GLAZED_TERRACOTTA: 1
|
||||||
LIME_SHULKER_BOX: 1
|
LIME_SHULKER_BOX: 1
|
||||||
LOG: 1
|
LIME_STAINED_GLASS: 2
|
||||||
#Other log types - examples
|
LIME_STAINED_GLASS_PANE: 1
|
||||||
#LOG:3: 2
|
LIME_TERRACOTTA: 1
|
||||||
LOG_2: 1
|
LIME_WALL_BANNER: 2
|
||||||
LONG_GRASS: 1
|
LIME_WOOL: 1
|
||||||
|
MAGENTA_BANNER: 2
|
||||||
|
MAGENTA_BED: 2
|
||||||
|
MAGENTA_CARPET: 1
|
||||||
|
MAGENTA_CONCRETE: 1
|
||||||
|
MAGENTA_CONCRETE_POWDER: 1
|
||||||
MAGENTA_GLAZED_TERRACOTTA: 1
|
MAGENTA_GLAZED_TERRACOTTA: 1
|
||||||
MAGENTA_SHULKER_BOX: 1
|
MAGENTA_SHULKER_BOX: 1
|
||||||
MAGMA: 1
|
MAGENTA_STAINED_GLASS: 2
|
||||||
MELON_BLOCK: 1
|
MAGENTA_STAINED_GLASS_PANE: 1
|
||||||
|
MAGENTA_TERRACOTTA: 1
|
||||||
|
MAGENTA_WALL_BANNER: 2
|
||||||
|
MAGENTA_WOOL: 1
|
||||||
|
MAGMA_BLOCK: 1
|
||||||
|
MELON: 1
|
||||||
MELON_STEM: 1
|
MELON_STEM: 1
|
||||||
MINECART: 10
|
MOSSY_COBBLESTONE: 1
|
||||||
MOB_SPAWNER: 0
|
MOSSY_COBBLESTONE_WALL: 1
|
||||||
MOSSY_COBBLESTONE: 2
|
MOSSY_STONE_BRICKS: 2
|
||||||
MYCEL: 5
|
MOVING_PISTON: 1
|
||||||
NETHER_BRICK: 2
|
MUSHROOM_STEM: 1
|
||||||
NETHER_BRICK_STAIRS: 2
|
MYCELIUM: 5
|
||||||
NETHER_FENCE: 2
|
|
||||||
NETHER_STALK: 1
|
|
||||||
NETHER_WART_BLOCK: 2
|
|
||||||
NETHERRACK: 1
|
NETHERRACK: 1
|
||||||
|
NETHER_BRICKS: 2
|
||||||
|
NETHER_BRICK_FENCE: 2
|
||||||
|
NETHER_BRICK_SLAB: 1
|
||||||
|
NETHER_BRICK_STAIRS: 2
|
||||||
|
NETHER_PORTAL: 1
|
||||||
|
NETHER_QUARTZ_ORE: 1
|
||||||
|
NETHER_WART: 1
|
||||||
|
NETHER_WART_BLOCK: 2
|
||||||
NOTE_BLOCK: 10
|
NOTE_BLOCK: 10
|
||||||
|
OAK_BUTTON: 1
|
||||||
|
OAK_DOOR: 1
|
||||||
|
OAK_FENCE: 2
|
||||||
|
OAK_FENCE_GATE: 1
|
||||||
|
OAK_LEAVES: 0
|
||||||
|
OAK_LOG: 0
|
||||||
|
OAK_PLANKS: 1
|
||||||
|
OAK_PRESSURE_PLATE: 1
|
||||||
|
OAK_SAPLING: 1
|
||||||
|
OAK_SLAB: 1
|
||||||
|
OAK_STAIRS: 2
|
||||||
|
OAK_TRAPDOOR: 1
|
||||||
|
OAK_WOOD: 1
|
||||||
OBSERVER: 1
|
OBSERVER: 1
|
||||||
OBSIDIAN: 10
|
OBSIDIAN: 10
|
||||||
|
ORANGE_BANNER: 2
|
||||||
|
ORANGE_BED: 2
|
||||||
|
ORANGE_CARPET: 1
|
||||||
|
ORANGE_CONCRETE: 1
|
||||||
|
ORANGE_CONCRETE_POWDER: 1
|
||||||
ORANGE_GLAZED_TERRACOTTA: 1
|
ORANGE_GLAZED_TERRACOTTA: 1
|
||||||
ORANGE_SHULKER_BOX: 1
|
ORANGE_SHULKER_BOX: 1
|
||||||
|
ORANGE_STAINED_GLASS: 2
|
||||||
|
ORANGE_STAINED_GLASS_PANE: 1
|
||||||
|
ORANGE_TERRACOTTA: 1
|
||||||
|
ORANGE_TULIP: 1
|
||||||
|
ORANGE_WALL_BANNER: 2
|
||||||
|
ORANGE_WOOL: 1
|
||||||
|
OXEYE_DAISY: 1
|
||||||
PACKED_ICE: 5
|
PACKED_ICE: 5
|
||||||
PAINTING: 2
|
PEONY: 1
|
||||||
|
PETRIFIED_OAK_SLAB: 1
|
||||||
|
PINK_BANNER: 2
|
||||||
|
PINK_BED: 2
|
||||||
|
PINK_CARPET: 1
|
||||||
|
PINK_CONCRETE: 1
|
||||||
|
PINK_CONCRETE_POWDER: 1
|
||||||
PINK_GLAZED_TERRACOTTA: 1
|
PINK_GLAZED_TERRACOTTA: 1
|
||||||
PINK_SHULKER_BOX: 1
|
PINK_SHULKER_BOX: 1
|
||||||
PISTON_BASE: 2
|
PINK_STAINED_GLASS: 2
|
||||||
PISTON_STICKY_BASE: 2
|
PINK_STAINED_GLASS_PANE: 1
|
||||||
PORTAL: 0
|
PINK_TERRACOTTA: 1
|
||||||
POWERED_MINECART: 10
|
PINK_TULIP: 1
|
||||||
POWERED_RAIL: 10
|
PINK_WALL_BANNER: 2
|
||||||
PRISMARINE: 10
|
PINK_WOOL: 1
|
||||||
PUMPKIN_STEM: 1
|
PISTON: 2
|
||||||
|
PISTON_HEAD: 1
|
||||||
|
PLAYER_HEAD: 1
|
||||||
|
PLAYER_WALL_HEAD: 1
|
||||||
|
PODZOL: 1
|
||||||
|
POLISHED_ANDESITE: 1
|
||||||
|
POLISHED_DIORITE: 1
|
||||||
|
POLISHED_GRANITE: 1
|
||||||
|
POPPY: 1
|
||||||
|
POTATOES: 1
|
||||||
|
POTTED_ACACIA_SAPLING: 1
|
||||||
|
POTTED_ALLIUM: 1
|
||||||
|
POTTED_AZURE_BLUET: 1
|
||||||
|
POTTED_BIRCH_SAPLING: 1
|
||||||
|
POTTED_BLUE_ORCHID: 1
|
||||||
|
POTTED_BROWN_MUSHROOM: 1
|
||||||
|
POTTED_CACTUS: 1
|
||||||
|
POTTED_DANDELION: 1
|
||||||
|
POTTED_DARK_OAK_SAPLING: 1
|
||||||
|
POTTED_DEAD_BUSH: 1
|
||||||
|
POTTED_FERN: 1
|
||||||
|
POTTED_JUNGLE_SAPLING: 1
|
||||||
|
POTTED_OAK_SAPLING: 1
|
||||||
|
POTTED_ORANGE_TULIP: 1
|
||||||
|
POTTED_OXEYE_DAISY: 1
|
||||||
|
POTTED_PINK_TULIP: 1
|
||||||
|
POTTED_POPPY: 1
|
||||||
|
POTTED_RED_MUSHROOM: 1
|
||||||
|
POTTED_RED_TULIP: 1
|
||||||
|
POTTED_SPRUCE_SAPLING: 1
|
||||||
|
POTTED_WHITE_TULIP: 1
|
||||||
|
POWERED_RAIL: 1
|
||||||
|
PRISMARINE: 1
|
||||||
|
PRISMARINE_BRICKS: 2
|
||||||
|
PRISMARINE_BRICK_SLAB: 1
|
||||||
|
PRISMARINE_BRICK_STAIRS: 2
|
||||||
|
PRISMARINE_SLAB: 1
|
||||||
|
PRISMARINE_STAIRS: 2
|
||||||
PUMPKIN: 1
|
PUMPKIN: 1
|
||||||
|
PUMPKIN_STEM: 1
|
||||||
|
PURPLE_BANNER: 2
|
||||||
|
PURPLE_BED: 2
|
||||||
|
PURPLE_CARPET: 1
|
||||||
|
PURPLE_CONCRETE: 1
|
||||||
|
PURPLE_CONCRETE_POWDER: 1
|
||||||
PURPLE_GLAZED_TERRACOTTA: 1
|
PURPLE_GLAZED_TERRACOTTA: 1
|
||||||
PURPLE_SHULKER_BOX: 1
|
PURPLE_SHULKER_BOX: 1
|
||||||
|
PURPLE_STAINED_GLASS: 2
|
||||||
|
PURPLE_STAINED_GLASS_PANE: 1
|
||||||
|
PURPLE_TERRACOTTA: 1
|
||||||
|
PURPLE_WALL_BANNER: 2
|
||||||
|
PURPLE_WOOL: 1
|
||||||
PURPUR_BLOCK: 1
|
PURPUR_BLOCK: 1
|
||||||
PURPUR_DOUBLE_SLAB: 1
|
|
||||||
PURPUR_PILLAR: 1
|
PURPUR_PILLAR: 1
|
||||||
PURPUR_SLAB: 1
|
PURPUR_SLAB: 1
|
||||||
PURPUR_STAIRS: 1
|
PURPUR_STAIRS: 2
|
||||||
QUARTZ_BLOCK: 1
|
QUARTZ_BLOCK: 1
|
||||||
QUARTZ_ORE: 0
|
QUARTZ_PILLAR: 1
|
||||||
QUARTZ_STAIRS: 1
|
QUARTZ_SLAB: 1
|
||||||
QUARTZ: 1
|
QUARTZ_STAIRS: 2
|
||||||
RAILS: 1
|
RAIL: 1
|
||||||
|
REDSTONE_BLOCK: 10
|
||||||
|
REDSTONE_LAMP: 10
|
||||||
|
REDSTONE_ORE: 1
|
||||||
|
REDSTONE_TORCH: 5
|
||||||
|
REDSTONE_WALL_TORCH: 5
|
||||||
|
REDSTONE_WIRE: 1
|
||||||
|
RED_BED: 2
|
||||||
|
RED_CARPET: 1
|
||||||
|
RED_CONCRETE: 1
|
||||||
|
RED_CONCRETE_POWDER: 1
|
||||||
RED_GLAZED_TERRACOTTA: 1
|
RED_GLAZED_TERRACOTTA: 1
|
||||||
RED_MUSHROOM: 1
|
RED_MUSHROOM: 1
|
||||||
RED_NETHER_BRICK: 2
|
RED_MUSHROOM_BLOCK: 1
|
||||||
RED_ROSE: 1
|
RED_NETHER_BRICKS: 2
|
||||||
|
RED_SAND: 1
|
||||||
RED_SANDSTONE: 1
|
RED_SANDSTONE: 1
|
||||||
RED_SANDSTONE_STAIRS: 1
|
RED_SANDSTONE_SLAB: 1
|
||||||
|
RED_SANDSTONE_STAIRS: 2
|
||||||
RED_SHULKER_BOX: 1
|
RED_SHULKER_BOX: 1
|
||||||
REDSTONE_BLOCK: 10
|
RED_STAINED_GLASS: 2
|
||||||
REDSTONE_COMPARATOR_OFF: 10
|
RED_STAINED_GLASS_PANE: 1
|
||||||
REDSTONE_COMPARATOR_ON: 10
|
RED_TERRACOTTA: 1
|
||||||
REDSTONE_COMPARATOR: 10
|
RED_TULIP: 1
|
||||||
REDSTONE_LAMP_OFF: 10
|
RED_WALL_BANNER: 2
|
||||||
REDSTONE_LAMP_ON: 10
|
RED_WOOL: 1
|
||||||
REDSTONE_ORE: 0
|
REPEATER: 1
|
||||||
REDSTONE_TORCH_OFF: 5
|
REPEATING_COMMAND_BLOCK: 1
|
||||||
REDSTONE_TORCH_ON: 5
|
ROSE_BUSH: 1
|
||||||
REDSTONE_WIRE: 1
|
|
||||||
SAND: 1
|
SAND: 1
|
||||||
SANDSTONE: 1
|
SANDSTONE: 1
|
||||||
SANDSTONE_STAIRS: 1
|
SANDSTONE_SLAB: 1
|
||||||
|
SANDSTONE_STAIRS: 2
|
||||||
|
SEAGRASS: 1
|
||||||
SEA_LANTERN: 1
|
SEA_LANTERN: 1
|
||||||
SIGN_POST: 1
|
SEA_PICKLE: 1
|
||||||
SILVER_GLAZED_TERRACOTTA: 1
|
SHULKER_BOX: 1
|
||||||
SILVER_SHULKER_BOX: 1
|
SIGN: 1
|
||||||
SKULL: 10
|
SKELETON_SKULL: 10
|
||||||
|
SKELETON_WALL_SKULL: 100
|
||||||
SLIME_BLOCK: 10
|
SLIME_BLOCK: 10
|
||||||
SMOOTH_BRICK: 2
|
SMOOTH_QUARTZ: 1
|
||||||
SMOOTH_STAIRS: 2
|
SMOOTH_RED_SANDSTONE: 1
|
||||||
|
SMOOTH_SANDSTONE: 1
|
||||||
|
SMOOTH_STONE: 1
|
||||||
|
SNOW: 1
|
||||||
SNOW_BLOCK: 1
|
SNOW_BLOCK: 1
|
||||||
SOIL: 2
|
|
||||||
SOUL_SAND: 2
|
SOUL_SAND: 2
|
||||||
|
SPAWNER: 1
|
||||||
SPONGE: 10
|
SPONGE: 10
|
||||||
|
SPRUCE_BUTTON: 1
|
||||||
SPRUCE_DOOR: 1
|
SPRUCE_DOOR: 1
|
||||||
SPRUCE_FENCE: 1
|
SPRUCE_FENCE: 2
|
||||||
SPRUCE_FENCE_GATE: 1
|
SPRUCE_FENCE_GATE: 1
|
||||||
SPRUCE_WOOD_STAIRS: 1
|
SPRUCE_LEAVES: 0
|
||||||
STAINED_CLAY: 2
|
SPRUCE_LOG: 0
|
||||||
STAINED_GLASS: 2
|
SPRUCE_PLANKS: 1
|
||||||
STAINED_GLASS_PANE: 1
|
SPRUCE_PRESSURE_PLATE: 1
|
||||||
STATIONARY_LAVA: 0
|
SPRUCE_SAPLING: 1
|
||||||
STATIONARY_WATER: 0
|
SPRUCE_SLAB: 1
|
||||||
STEP: 1
|
SPRUCE_STAIRS: 2
|
||||||
|
SPRUCE_TRAPDOOR: 1
|
||||||
|
SPRUCE_WOOD: 1
|
||||||
|
STICKY_PISTON: 1
|
||||||
STONE: 1
|
STONE: 1
|
||||||
|
STONE_BRICKS: 2
|
||||||
|
STONE_BRICK_SLAB: 1
|
||||||
|
STONE_BRICK_STAIRS: 2
|
||||||
STONE_BUTTON: 1
|
STONE_BUTTON: 1
|
||||||
STONE_PLATE: 2
|
STONE_PRESSURE_PLATE: 1
|
||||||
STORAGE_MINECART: 10
|
STONE_SLAB: 1
|
||||||
SUGAR_CANE_BLOCK: 1
|
STRIPPED_ACACIA_LOG: 0
|
||||||
THIN_GLASS: 1
|
STRIPPED_ACACIA_WOOD: 1
|
||||||
|
STRIPPED_BIRCH_LOG: 0
|
||||||
|
STRIPPED_BIRCH_WOOD: 1
|
||||||
|
STRIPPED_DARK_OAK_LOG: 0
|
||||||
|
STRIPPED_DARK_OAK_WOOD: 1
|
||||||
|
STRIPPED_JUNGLE_LOG: 0
|
||||||
|
STRIPPED_JUNGLE_WOOD: 1
|
||||||
|
STRIPPED_OAK_LOG: 0
|
||||||
|
STRIPPED_OAK_WOOD: 1
|
||||||
|
STRIPPED_SPRUCE_LOG: 0
|
||||||
|
STRIPPED_SPRUCE_WOOD: 1
|
||||||
|
SUGAR_CANE: 1
|
||||||
|
SUNFLOWER: 1
|
||||||
|
TALL_GRASS: 1
|
||||||
|
TALL_SEAGRASS: 1
|
||||||
|
TERRACOTTA: 1
|
||||||
TNT: 5
|
TNT: 5
|
||||||
TORCH: 2
|
TORCH: 1
|
||||||
TRAP_DOOR: 5
|
TRAPPED_CHEST: 5
|
||||||
TRAPPED_CHEST: 10
|
|
||||||
TRIPWIRE_HOOK: 2
|
|
||||||
TRIPWIRE: 2
|
TRIPWIRE: 2
|
||||||
|
TRIPWIRE_HOOK: 2
|
||||||
|
TUBE_CORAL: 1
|
||||||
|
TUBE_CORAL_BLOCK: 1
|
||||||
|
TUBE_CORAL_FAN: 1
|
||||||
|
TUBE_CORAL_WALL_FAN: 1
|
||||||
|
TURTLE_EGG: 1
|
||||||
VINE: 1
|
VINE: 1
|
||||||
|
VOID_AIR: 1
|
||||||
WALL_SIGN: 1
|
WALL_SIGN: 1
|
||||||
WATER_LILY: 5
|
WALL_TORCH: 1
|
||||||
WEB: 10
|
WATER: 0
|
||||||
|
WET_SPONGE: 10
|
||||||
WHEAT: 1
|
WHEAT: 1
|
||||||
|
WHITE_BANNER: 2
|
||||||
|
WHITE_BED: 2
|
||||||
|
WHITE_CARPET: 1
|
||||||
|
WHITE_CONCRETE: 1
|
||||||
|
WHITE_CONCRETE_POWDER: 1
|
||||||
WHITE_GLAZED_TERRACOTTA: 1
|
WHITE_GLAZED_TERRACOTTA: 1
|
||||||
WHITE_SHULKER_BOX: 1
|
WHITE_SHULKER_BOX: 1
|
||||||
WOOD: 1
|
WHITE_STAINED_GLASS: 2
|
||||||
WOOD_BUTTON: 1
|
WHITE_STAINED_GLASS_PANE: 1
|
||||||
WOOD_DOOR: 1
|
WHITE_TERRACOTTA: 1
|
||||||
WOOD_DOUBLE_STEP: 1
|
WHITE_TULIP: 1
|
||||||
WOOD_PLATE: 1
|
WHITE_WALL_BANNER: 2
|
||||||
WOOD_STAIRS: 1
|
WHITE_WOOL: 1
|
||||||
WOOD_STEP: 1
|
WITHER_SKELETON_SKULL: 10
|
||||||
WOODEN_DOOR: 1
|
WITHER_SKELETON_WALL_SKULL: 10
|
||||||
WOOL: 1
|
YELLOW_BANNER: 2
|
||||||
WORKBENCH: 1
|
YELLOW_BED: 2
|
||||||
YELLOW_FLOWER: 1
|
YELLOW_CARPET: 1
|
||||||
|
YELLOW_CONCRETE: 1
|
||||||
|
YELLOW_CONCRETE_POWDER: 1
|
||||||
YELLOW_GLAZED_TERRACOTTA: 1
|
YELLOW_GLAZED_TERRACOTTA: 1
|
||||||
YELLOW_SHULKER_BOX: 1
|
YELLOW_SHULKER_BOX: 1
|
||||||
|
YELLOW_STAINED_GLASS: 2
|
||||||
|
YELLOW_STAINED_GLASS_PANE: 1
|
||||||
|
YELLOW_TERRACOTTA: 1
|
||||||
|
YELLOW_WALL_BANNER: 2
|
||||||
|
YELLOW_WOOL: 1
|
||||||
|
ZOMBIE_HEAD: 1
|
||||||
|
ZOMBIE_WALL_HEAD: 1
|
||||||
|
|
||||||
|
# World differences
|
||||||
|
# List any blocks that have a different value in a specific world
|
||||||
|
# If a block is not listed, the default value will be used
|
||||||
|
# Prefix with world name
|
||||||
|
worlds:
|
||||||
|
AcidIsland_world:
|
||||||
|
SAND: 0
|
||||||
|
SANDSTONE: 0
|
||||||
|
ICE: 0
|
||||||
|
|
@ -1,20 +0,0 @@
|
|||||||
###########################################################################################
|
|
||||||
# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
|
|
||||||
# the one at http://yaml-online-parser.appspot.com #
|
|
||||||
###########################################################################################
|
|
||||||
|
|
||||||
### Credits ###
|
|
||||||
# Tastybento: maintainer
|
|
||||||
# Poslovitch: maintainer
|
|
||||||
#
|
|
||||||
# This translation is adapted to version : [alpha-0.0.1]
|
|
||||||
|
|
||||||
island:
|
|
||||||
islandLevelIs: "Island level is"
|
|
||||||
requiredPointsToNextLevel: "[points] points required until the next level"
|
|
||||||
levelDeaths: "([number] deaths)"
|
|
||||||
topten:
|
|
||||||
guiTitle: "Top Ten"
|
|
||||||
guiHeading: "[name]:[rank]"
|
|
||||||
islandLevel: "Level [level]"
|
|
||||||
|
|
30
locales/en-US.yml
Executable file
30
locales/en-US.yml
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
###########################################################################################
|
||||||
|
# This is a YML file. Be careful when editing. Check your edits in a YAML checker like #
|
||||||
|
# the one at http://yaml-online-parser.appspot.com #
|
||||||
|
###########################################################################################
|
||||||
|
|
||||||
|
admin:
|
||||||
|
level:
|
||||||
|
parameters: "<player>"
|
||||||
|
description: "calculate the island level for player"
|
||||||
|
top:
|
||||||
|
description: "show the top ten list"
|
||||||
|
unknown-world: "&cUnknown world!"
|
||||||
|
|
||||||
|
island:
|
||||||
|
level:
|
||||||
|
parameters: "[player]"
|
||||||
|
description: "calculate your island level or show the level of [player]"
|
||||||
|
calculating: "&aCalculating level..."
|
||||||
|
island-level-is: "&aIsland level is &b[level]"
|
||||||
|
required-points-to-next-level: "&a[points] points required until the next level"
|
||||||
|
deaths: "&c([number] deaths)"
|
||||||
|
cooldown: "&cYou must wait &b[time] &cseconds until you can do that again"
|
||||||
|
|
||||||
|
top:
|
||||||
|
description: "show the Top Ten"
|
||||||
|
gui-title: "&aTop Ten"
|
||||||
|
gui-heading: "&6[name]: &B[rank]"
|
||||||
|
island-level: "&BLevel [level]"
|
||||||
|
warp-to: "&AWarping to [name]'s island"
|
||||||
|
|
24
plugin.yml
24
plugin.yml
@ -1,24 +0,0 @@
|
|||||||
name: BSkyBlock-Level
|
|
||||||
main: bskyblock.addin.level.Level
|
|
||||||
version: 0.1
|
|
||||||
|
|
||||||
authors: [tastybento]
|
|
||||||
|
|
||||||
depend: [BSkyBlock]
|
|
||||||
|
|
||||||
permissions:
|
|
||||||
bskyblock.intopten:
|
|
||||||
description: Player is in the top ten.
|
|
||||||
default: true
|
|
||||||
bskyblock.island.level:
|
|
||||||
description: Player can use level command
|
|
||||||
default: true
|
|
||||||
bskyblock.island.topten:
|
|
||||||
description: Player can use top ten command
|
|
||||||
default: true
|
|
||||||
bskyblock.admin.level:
|
|
||||||
description: Player can use admin level command
|
|
||||||
default: true
|
|
||||||
bskyblock.admin.topten:
|
|
||||||
description: Player can use admin top ten command
|
|
||||||
default: true
|
|
21
pom.xml
21
pom.xml
@ -1,7 +1,6 @@
|
|||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
<groupId>Level</groupId>
|
|
||||||
<artifactId>Level</artifactId>
|
<artifactId>Level</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
@ -41,16 +40,23 @@
|
|||||||
</plugins>
|
</plugins>
|
||||||
</build>
|
</build>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.spigotmc</groupId>
|
||||||
|
<artifactId>spigot-api</artifactId>
|
||||||
|
<version>1.13-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.bukkit</groupId>
|
<groupId>world.bentobox</groupId>
|
||||||
<artifactId>bukkit</artifactId>
|
<artifactId>bentobox</artifactId>
|
||||||
<version>1.12.2-R0.1-SNAPSHOT</version>
|
<version>LATEST</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>us.tastybento</groupId>
|
<groupId>bskyblock.addon</groupId>
|
||||||
<artifactId>bskyblock</artifactId>
|
<artifactId>WelcomeWarpSigns</artifactId>
|
||||||
<version>LATEST</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<repositories>
|
<repositories>
|
||||||
@ -59,4 +65,5 @@
|
|||||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
</repository>
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
<groupId>bskyblock.addon</groupId>
|
||||||
</project>
|
</project>
|
@ -1,342 +0,0 @@
|
|||||||
package bskyblock.addin.level;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.bukkit.Chunk;
|
|
||||||
import org.bukkit.ChunkSnapshot;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.material.MaterialData;
|
|
||||||
|
|
||||||
import com.google.common.collect.HashMultiset;
|
|
||||||
import com.google.common.collect.Multiset;
|
|
||||||
import com.google.common.collect.Multiset.Entry;
|
|
||||||
import com.google.common.collect.Multisets;
|
|
||||||
|
|
||||||
import bskyblock.addin.level.config.Settings;
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A class that calculates the level of an island very quickly by copying island
|
|
||||||
* chunks to a list and then processing asynchronously.
|
|
||||||
*
|
|
||||||
* @author tastybento
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class ChunkScanner {
|
|
||||||
private static final boolean DEBUG = false;
|
|
||||||
protected static final boolean LEVEL_LOGGING = false;
|
|
||||||
private final Level plugin;
|
|
||||||
private final Set<ChunkSnapshot> finalChunk;
|
|
||||||
private final Results result;
|
|
||||||
private final Optional<User> asker;
|
|
||||||
|
|
||||||
|
|
||||||
public ChunkScanner(Level plugin, Island island) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
// Get the chunks to scan
|
|
||||||
finalChunk = getIslandChunks(island);
|
|
||||||
this.asker = Optional.empty();
|
|
||||||
// Create new level result
|
|
||||||
result = new Results();
|
|
||||||
runAsyncCount(island);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the level of an island
|
|
||||||
* @param plugin
|
|
||||||
* @param island - island that is being calculated
|
|
||||||
* @param asker - the user who wants the report
|
|
||||||
*/
|
|
||||||
public ChunkScanner(Level plugin, Island island, User asker) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
// Get the chunks to scan
|
|
||||||
finalChunk = getIslandChunks(island);
|
|
||||||
this.asker = Optional.of(asker);
|
|
||||||
// Create new level result
|
|
||||||
result = new Results();
|
|
||||||
runAsyncCount(island);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runAsyncCount(Island island) {
|
|
||||||
// Run AsyncTask to count blocks in the chunk snapshots
|
|
||||||
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Copy the limits hashmap
|
|
||||||
HashMap<MaterialData, Integer> limitCount = new HashMap<MaterialData, Integer>(Settings.blockLimits);
|
|
||||||
// Calculate the island score
|
|
||||||
for (ChunkSnapshot chunk: finalChunk) {
|
|
||||||
for (int x = 0; x< 16; x++) {
|
|
||||||
// Check if the block coord is inside the protection zone and if not, don't count it
|
|
||||||
if (chunk.getX() * 16 + x < island.getMinProtectedX() || chunk.getX() * 16 + x >= island.getMinProtectedX() + (island.getProtectionRange() * 2)) {
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("Block is outside protected area - x = " + (chunk.getX() * 16 + x));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
for (int z = 0; z < 16; z++) {
|
|
||||||
// Check if the block coord is inside the protection zone and if not, don't count it
|
|
||||||
if (chunk.getZ() * 16 + z < island.getMinProtectedZ() || chunk.getZ() * 16 + z >= island.getMinProtectedZ() + (island.getProtectionRange() * 2)) {
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("Block is outside protected area - z = " + (chunk.getZ() * 16 + z));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int y = 0; y < island.getWorld().getMaxHeight(); y++) {
|
|
||||||
Material type = chunk.getBlockType(x, y, z);
|
|
||||||
// Currently, there is no alternative to using block data (Dec 2017)
|
|
||||||
MaterialData md = new MaterialData(type, (byte) chunk.getBlockData(x, y, z));
|
|
||||||
MaterialData generic = new MaterialData(type);
|
|
||||||
if (!type.equals(Material.AIR)) { // AIR
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("Block is inside protected area " + (chunk.getX() * 16) + "," + (chunk.getZ() * 16 + z));
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("Block is " + md + "[" + generic +"]");
|
|
||||||
if (limitCount.containsKey(md) && Settings.blockValues.containsKey(md)) {
|
|
||||||
int count = limitCount.get(md);
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: Count for non-generic " + md + " is " + count);
|
|
||||||
if (count > 0) {
|
|
||||||
limitCount.put(md, --count);
|
|
||||||
if (Settings.seaHeight > 0 && y<=Settings.seaHeight) {
|
|
||||||
result.underWaterBlockCount += Settings.blockValues.get(md);
|
|
||||||
result.uwCount.add(md);
|
|
||||||
} else {
|
|
||||||
result.rawBlockCount += Settings.blockValues.get(md);
|
|
||||||
result.mdCount.add(md);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.ofCount.add(md);
|
|
||||||
}
|
|
||||||
} else if (limitCount.containsKey(generic) && Settings.blockValues.containsKey(generic)) {
|
|
||||||
int count = limitCount.get(generic);
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: Count for generic " + generic + " is " + count);
|
|
||||||
if (count > 0) {
|
|
||||||
limitCount.put(generic, --count);
|
|
||||||
if (Settings.seaHeight > 0 && y<=Settings.seaHeight) {
|
|
||||||
result.underWaterBlockCount += Settings.blockValues.get(generic);
|
|
||||||
result.uwCount.add(md);
|
|
||||||
} else {
|
|
||||||
result.rawBlockCount += Settings.blockValues.get(generic);
|
|
||||||
result.mdCount.add(md);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.ofCount.add(md);
|
|
||||||
}
|
|
||||||
} else if (Settings.blockValues.containsKey(md)) {
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: Adding " + md + " = " + Settings.blockValues.get(md));
|
|
||||||
if (Settings.seaHeight > 0 && y<=Settings.seaHeight) {
|
|
||||||
result.underWaterBlockCount += Settings.blockValues.get(md);
|
|
||||||
result.uwCount.add(md);
|
|
||||||
} else {
|
|
||||||
result.rawBlockCount += Settings.blockValues.get(md);
|
|
||||||
result.mdCount.add(md);
|
|
||||||
}
|
|
||||||
} else if (Settings.blockValues.containsKey(generic)) {
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: Adding " + generic + " = " + Settings.blockValues.get(generic));
|
|
||||||
if (Settings.seaHeight > 0 && y<=Settings.seaHeight) {
|
|
||||||
result.underWaterBlockCount += Settings.blockValues.get(generic);
|
|
||||||
result.uwCount.add(md);
|
|
||||||
} else {
|
|
||||||
result.rawBlockCount += Settings.blockValues.get(generic);
|
|
||||||
result.mdCount.add(md);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result.ncCount.add(md);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result.rawBlockCount += (long)((double)result.underWaterBlockCount * Settings.underWaterMultiplier);
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: block count = "+result.rawBlockCount);
|
|
||||||
// Set the death penalty
|
|
||||||
result.deathHandicap = BSkyBlock.getPlugin().getPlayers().getDeaths(island.getOwner()) * Settings.deathpenalty;
|
|
||||||
// Set final score
|
|
||||||
result.score = (result.rawBlockCount / Settings.levelCost) - result.deathHandicap;
|
|
||||||
|
|
||||||
// Return to main thread
|
|
||||||
plugin.getServer().getScheduler().runTask(plugin, new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
// Run any modifications
|
|
||||||
|
|
||||||
// All done.
|
|
||||||
if (asker.isPresent()) {
|
|
||||||
// Tell the asker the result
|
|
||||||
if (asker.get().isPlayer() && asker.get().isOnline()) {
|
|
||||||
asker.get().sendLegacyMessage("Your level is " + result.score);
|
|
||||||
} else {
|
|
||||||
// Console
|
|
||||||
sendConsoleReport(asker);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void sendConsoleReport(Optional<User> asker) {
|
|
||||||
List<String> reportLines = new ArrayList<>();
|
|
||||||
// provide counts
|
|
||||||
reportLines.add("Level Log for island at " + island.getCenter());
|
|
||||||
reportLines.add("Island owner UUID = " + island.getOwner());
|
|
||||||
reportLines.add("Total block value count = " + String.format("%,d",result.rawBlockCount));
|
|
||||||
reportLines.add("Level cost = " + Settings.levelCost);
|
|
||||||
//reportLines.add("Level multiplier = " + levelMultiplier + " (Player must be online to get a permission multiplier)");
|
|
||||||
//reportLines.add("Schematic level handicap = " + levelHandicap + " (level is reduced by this amount)");
|
|
||||||
reportLines.add("Deaths handicap = " + result.deathHandicap);
|
|
||||||
reportLines.add("Level calculated = " + result.score);
|
|
||||||
reportLines.add("==================================");
|
|
||||||
int total = 0;
|
|
||||||
if (!result.uwCount.isEmpty()) {
|
|
||||||
reportLines.add("Underwater block count (Multiplier = x" + Settings.underWaterMultiplier + ") value");
|
|
||||||
reportLines.add("Total number of underwater blocks = " + String.format("%,d",result.uwCount.size()));
|
|
||||||
Iterable<Multiset.Entry<MaterialData>> entriesSortedByCount =
|
|
||||||
Multisets.copyHighestCountFirst(result.uwCount).entrySet();
|
|
||||||
Iterator<Entry<MaterialData>> it = entriesSortedByCount.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Entry<MaterialData> en = it.next();
|
|
||||||
MaterialData type = en.getElement();
|
|
||||||
|
|
||||||
int value = 0;
|
|
||||||
if (Settings.blockValues.containsKey(type)) {
|
|
||||||
// Specific
|
|
||||||
value = Settings.blockValues.get(type);
|
|
||||||
} else if (Settings.blockValues.containsKey(new MaterialData(type.getItemType()))) {
|
|
||||||
// Generic
|
|
||||||
value = Settings.blockValues.get(new MaterialData(type.getItemType()));
|
|
||||||
}
|
|
||||||
if (value > 0) {
|
|
||||||
reportLines.add(type.toString() + ":"
|
|
||||||
+ String.format("%,d",en.getCount()) + " blocks x " + value + " = " + (value * en.getCount()));
|
|
||||||
total += (value * en.getCount());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reportLines.add("Subtotal = " + total);
|
|
||||||
reportLines.add("==================================");
|
|
||||||
}
|
|
||||||
reportLines.add("Regular block count");
|
|
||||||
reportLines.add("Total number of blocks = " + String.format("%,d",result.mdCount.size()));
|
|
||||||
//Iterable<Multiset.Entry<MaterialData>> entriesSortedByCount =
|
|
||||||
// Multisets.copyHighestCountFirst(mdCount).entrySet();
|
|
||||||
Iterable<Multiset.Entry<MaterialData>> entriesSortedByCount =
|
|
||||||
result.mdCount.entrySet();
|
|
||||||
Iterator<Entry<MaterialData>> it = entriesSortedByCount.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Entry<MaterialData> en = it.next();
|
|
||||||
MaterialData type = en.getElement();
|
|
||||||
int value = 0;
|
|
||||||
if (Settings.blockValues.containsKey(type)) {
|
|
||||||
// Specific
|
|
||||||
value = Settings.blockValues.get(type);
|
|
||||||
} else if (Settings.blockValues.containsKey(new MaterialData(type.getItemType()))) {
|
|
||||||
// Generic
|
|
||||||
value = Settings.blockValues.get(new MaterialData(type.getItemType()));
|
|
||||||
}
|
|
||||||
if (value > 0) {
|
|
||||||
reportLines.add(type.toString() + ":"
|
|
||||||
+ String.format("%,d",en.getCount()) + " blocks x " + value + " = " + (value * en.getCount()));
|
|
||||||
total += (value * en.getCount());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
reportLines.add("Total = " + total);
|
|
||||||
reportLines.add("==================================");
|
|
||||||
reportLines.add("Blocks not counted because they exceeded limits: " + String.format("%,d",result.ofCount.size()));
|
|
||||||
//entriesSortedByCount = Multisets.copyHighestCountFirst(ofCount).entrySet();
|
|
||||||
entriesSortedByCount = result.ofCount.entrySet();
|
|
||||||
it = entriesSortedByCount.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Entry<MaterialData> type = it.next();
|
|
||||||
Integer limit = Settings.blockLimits.get(type.getElement());
|
|
||||||
String explain = ")";
|
|
||||||
if (limit == null) {
|
|
||||||
MaterialData generic = new MaterialData(type.getElement().getItemType());
|
|
||||||
limit = Settings.blockLimits.get(generic);
|
|
||||||
explain = " - All types)";
|
|
||||||
}
|
|
||||||
reportLines.add(type.getElement().toString() + ": " + String.format("%,d",type.getCount()) + " blocks (max " + limit + explain);
|
|
||||||
}
|
|
||||||
reportLines.add("==================================");
|
|
||||||
reportLines.add("Blocks on island that are not in config.yml");
|
|
||||||
reportLines.add("Total number = " + String.format("%,d",result.ncCount.size()));
|
|
||||||
//entriesSortedByCount = Multisets.copyHighestCountFirst(ncCount).entrySet();
|
|
||||||
entriesSortedByCount = result.ncCount.entrySet();
|
|
||||||
it = entriesSortedByCount.iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Entry<MaterialData> type = it.next();
|
|
||||||
reportLines.add(type.getElement().toString() + ": " + String.format("%,d",type.getCount()) + " blocks");
|
|
||||||
}
|
|
||||||
reportLines.add("=================================");
|
|
||||||
|
|
||||||
for (String line : reportLines) {
|
|
||||||
asker.get().sendLegacyMessage(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private Set<ChunkSnapshot> getIslandChunks(Island island) {
|
|
||||||
// Check if player's island world is the nether or overworld and adjust accordingly
|
|
||||||
final World world = island.getWorld();
|
|
||||||
// Get the chunks
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: Getting chunks. Protection range = " + island.getProtectionRange());
|
|
||||||
//long nano = System.nanoTime();
|
|
||||||
Set<ChunkSnapshot> chunkSnapshot = new HashSet<ChunkSnapshot>();
|
|
||||||
for (int x = island.getMinProtectedX(); x < (island.getMinProtectedX() + (island.getProtectionRange() *2) + 16); x += 16) {
|
|
||||||
for (int z = island.getMinProtectedZ(); z < (island.getMinProtectedZ() + (island.getProtectionRange() * 2) + 16); z += 16) {
|
|
||||||
if (!world.isChunkLoaded((int)((double)x/16), (int)((double)z/16))) {
|
|
||||||
// If the chunk isn't already generated, load it but don't try and generate it
|
|
||||||
world.loadChunk((int)((double)x/16), (int)((double)z/16), false);
|
|
||||||
}
|
|
||||||
// chunk is loaded
|
|
||||||
chunkSnapshot.add(world.getBlockAt(x, 0, z).getChunk().getChunkSnapshot());
|
|
||||||
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: getting chunk at " + x + ", " + z);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: size of chunk snapshot = " + chunkSnapshot.size());
|
|
||||||
return chunkSnapshot;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Results class
|
|
||||||
* @author ben
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class Results {
|
|
||||||
Multiset<MaterialData> mdCount = HashMultiset.create();
|
|
||||||
Multiset<MaterialData> uwCount = HashMultiset.create();
|
|
||||||
Multiset<MaterialData> ncCount = HashMultiset.create();
|
|
||||||
Multiset<MaterialData> ofCount = HashMultiset.create();
|
|
||||||
long rawBlockCount;
|
|
||||||
Island island;
|
|
||||||
long underWaterBlockCount = 0;
|
|
||||||
long score;
|
|
||||||
int deathHandicap;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,179 +0,0 @@
|
|||||||
package bskyblock.addin.level;
|
|
||||||
|
|
||||||
import java.beans.IntrospectionException;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.bukkit.plugin.java.JavaPlugin;
|
|
||||||
import org.bukkit.scheduler.BukkitTask;
|
|
||||||
|
|
||||||
import bskyblock.addin.level.commands.AdminLevel;
|
|
||||||
import bskyblock.addin.level.commands.AdminTop;
|
|
||||||
import bskyblock.addin.level.commands.IslandLevel;
|
|
||||||
import bskyblock.addin.level.commands.IslandTop;
|
|
||||||
import bskyblock.addin.level.config.PluginConfig;
|
|
||||||
import bskyblock.addin.level.database.object.Levels;
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
|
||||||
import us.tastybento.bskyblock.api.commands.CompositeCommand;
|
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
|
||||||
import us.tastybento.bskyblock.config.Settings;
|
|
||||||
import us.tastybento.bskyblock.database.BSBDatabase;
|
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Addin to BSkyBlock that enables island level scoring and top ten functionality
|
|
||||||
* @author tastybento
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class Level extends JavaPlugin {
|
|
||||||
|
|
||||||
|
|
||||||
// The BSkyBlock plugin instance.
|
|
||||||
private BSkyBlock bSkyBlock;
|
|
||||||
|
|
||||||
// Level calc checker
|
|
||||||
BukkitTask checker = null;
|
|
||||||
|
|
||||||
// Database handler for level data
|
|
||||||
private AbstractDatabaseHandler<Levels> handler;
|
|
||||||
|
|
||||||
// The BSkyBlock database object
|
|
||||||
private BSBDatabase database;
|
|
||||||
|
|
||||||
// A cache of island levels. Island levels are not kept in memory unless required.
|
|
||||||
// The cache is saved when the server shuts down and the plugin is disabled.
|
|
||||||
// TODO: Save regularly to avoid crash issues.
|
|
||||||
private HashMap<UUID, Long> levelsCache;
|
|
||||||
|
|
||||||
// The Top Ten object
|
|
||||||
private TopTen topTen;
|
|
||||||
|
|
||||||
// Level calculator
|
|
||||||
private LevelPresenter levelCalc;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
@Override
|
|
||||||
public void onEnable() {
|
|
||||||
// Load the plugin's config
|
|
||||||
new PluginConfig(this);
|
|
||||||
// Get the BSkyBlock plugin. This will be available because this plugin depends on it in plugin.yml.
|
|
||||||
bSkyBlock = BSkyBlock.getPlugin();
|
|
||||||
// Check if it is enabled - it might be loaded, but not enabled.
|
|
||||||
if (!bSkyBlock.isEnabled()) {
|
|
||||||
this.setEnabled(false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Get the BSkyBlock database
|
|
||||||
database = BSBDatabase.getDatabase();
|
|
||||||
// Set up the database handler to store and retrieve Island classes
|
|
||||||
// Note that these are saved by the BSkyBlock database
|
|
||||||
handler = (AbstractDatabaseHandler<Levels>) database.getHandler(bSkyBlock, Levels.class);
|
|
||||||
// Initialize the cache
|
|
||||||
levelsCache = new HashMap<>();
|
|
||||||
// Load the calculator
|
|
||||||
levelCalc = new LevelPresenter(this);
|
|
||||||
// Start the top ten and register it for clicks
|
|
||||||
topTen = new TopTen(this);
|
|
||||||
getServer().getPluginManager().registerEvents(topTen, this);
|
|
||||||
// Local locales
|
|
||||||
//localeManager = new LocaleManager(this);
|
|
||||||
// Register commands
|
|
||||||
CompositeCommand bsbIslandCmd = (CompositeCommand) BSkyBlock.getPlugin().getCommandsManager().getCommand(Settings.ISLANDCOMMAND);
|
|
||||||
new IslandLevel(this, bsbIslandCmd);
|
|
||||||
new IslandTop(this, bsbIslandCmd);
|
|
||||||
CompositeCommand bsbAdminCmd = (CompositeCommand) BSkyBlock.getPlugin().getCommandsManager().getCommand(Settings.ADMINCOMMAND);
|
|
||||||
new AdminLevel(this, bsbAdminCmd);
|
|
||||||
new AdminTop(this, bsbAdminCmd);
|
|
||||||
// Done
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onDisable(){
|
|
||||||
// Save the cache
|
|
||||||
if (levelsCache != null) {
|
|
||||||
save(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save the levels to the database
|
|
||||||
* @param async - if true, saving will be done async
|
|
||||||
*/
|
|
||||||
public void save(boolean async){
|
|
||||||
Runnable save = () -> {
|
|
||||||
try {
|
|
||||||
for (Entry<UUID, Long> en : levelsCache.entrySet()) {
|
|
||||||
Levels lv = new Levels();
|
|
||||||
lv.setLevel(en.getValue());
|
|
||||||
lv.setUniqueId(en.getKey().toString());
|
|
||||||
handler.saveObject(lv);
|
|
||||||
}
|
|
||||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException
|
|
||||||
| InstantiationException | NoSuchMethodException | IntrospectionException | SQLException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if(async){
|
|
||||||
getServer().getScheduler().runTaskAsynchronously(this, save);
|
|
||||||
} else {
|
|
||||||
save.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get level from cache for a player
|
|
||||||
* @param targetPlayer
|
|
||||||
* @return Level of player
|
|
||||||
*/
|
|
||||||
public long getIslandLevel(UUID targetPlayer) {
|
|
||||||
//getLogger().info("DEBUG: getting island level for " + bSkyBlock.getPlayers().getName(targetPlayer));
|
|
||||||
if (levelsCache.containsKey(targetPlayer)) {
|
|
||||||
return levelsCache.get(targetPlayer);
|
|
||||||
}
|
|
||||||
// Get from database
|
|
||||||
Levels level;
|
|
||||||
try {
|
|
||||||
level = handler.loadObject(targetPlayer.toString());
|
|
||||||
if (level == null) {
|
|
||||||
// We do not know this player, set to zero
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
levelsCache.put(targetPlayer, level.getLevel());
|
|
||||||
return level.getLevel();
|
|
||||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
|
||||||
| SecurityException | ClassNotFoundException | IntrospectionException | SQLException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Save the player's level
|
|
||||||
* @param targetPlayer
|
|
||||||
* @param level
|
|
||||||
*/
|
|
||||||
public void setIslandLevel(UUID targetPlayer, long level) {
|
|
||||||
//getLogger().info("DEBUG: set island level to " + level + " for " + bSkyBlock.getPlayers().getName(targetPlayer));
|
|
||||||
// Add to cache
|
|
||||||
levelsCache.put(targetPlayer, level);
|
|
||||||
topTen.addEntry(targetPlayer, level);
|
|
||||||
}
|
|
||||||
|
|
||||||
public AbstractDatabaseHandler<Levels> getHandler() {
|
|
||||||
return handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TopTen getTopTen() {
|
|
||||||
return topTen;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void calculateIslandLevel(User user, UUID playerUUID, boolean b) {
|
|
||||||
levelCalc.calculateIslandLevel(user, playerUUID, b);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
package bskyblock.addin.level;
|
|
||||||
|
|
||||||
import java.util.logging.Logger;
|
|
||||||
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Makes code look nicer
|
|
||||||
* @author ben
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public abstract class LevelPlugin {
|
|
||||||
protected final Level plugin;
|
|
||||||
protected final BSkyBlock bSkyBlock;
|
|
||||||
|
|
||||||
public LevelPlugin(Level plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.bSkyBlock = BSkyBlock.getPlugin();
|
|
||||||
}
|
|
||||||
|
|
||||||
public final Logger getLogger() {
|
|
||||||
return plugin.getLogger();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
package bskyblock.addin.level;
|
|
||||||
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
|
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
|
||||||
import us.tastybento.bskyblock.config.Settings;
|
|
||||||
|
|
||||||
public class LevelPresenter extends LevelPlugin {
|
|
||||||
|
|
||||||
private int levelWait;
|
|
||||||
// Level calc cool down
|
|
||||||
private HashMap<UUID, Long> levelWaitTime = new HashMap<UUID, Long>();
|
|
||||||
|
|
||||||
public LevelPresenter(Level plugin) {
|
|
||||||
super(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the island level
|
|
||||||
*
|
|
||||||
* @param sender
|
|
||||||
* - Player object of player who is asking
|
|
||||||
* @param targetPlayer
|
|
||||||
* - UUID of the player's island that is being requested
|
|
||||||
* @return - true if successful.
|
|
||||||
*/
|
|
||||||
public boolean calculateIslandLevel(final User sender, final UUID targetPlayer) {
|
|
||||||
return calculateIslandLevel(sender, targetPlayer, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the island level
|
|
||||||
* @param sender - asker of the level info
|
|
||||||
* @param targetPlayer
|
|
||||||
* @param report - if true, a detailed report will be provided
|
|
||||||
* @return - false if this is cannot be done
|
|
||||||
*/
|
|
||||||
public boolean calculateIslandLevel(final User sender, final UUID targetPlayer, boolean report) {
|
|
||||||
// Check if sender has island
|
|
||||||
if (!bSkyBlock.getIslands().hasIsland(targetPlayer)) {
|
|
||||||
sender.sendLegacyMessage("Target does not have an island");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Player asking for their own island calc
|
|
||||||
if (!sender.isPlayer() || sender.getUniqueId().equals(targetPlayer) || sender.isOp() || sender.hasPermission(Settings.PERMPREFIX + "mod.info")) {
|
|
||||||
// Newer better system - uses chunks
|
|
||||||
if (!onLevelWaitTime(sender) || levelWait <= 0 || sender.isOp() || sender.hasPermission(Settings.PERMPREFIX + "mod.info")) {
|
|
||||||
sender.sendLegacyMessage(ChatColor.GREEN + "Calculating level, please wait...");
|
|
||||||
setLevelWaitTime(sender);
|
|
||||||
new ChunkScanner(plugin, bSkyBlock.getIslands().getIsland(targetPlayer), sender);
|
|
||||||
} else {
|
|
||||||
sender.sendLegacyMessage( ChatColor.YELLOW + String.valueOf(getLevelWaitTime(sender)));
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Asking for the level of another player
|
|
||||||
sender.sendMessage("island.islandLevelIs","[level]", String.valueOf(plugin.getIslandLevel(targetPlayer)));
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets cool down for the level command
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
*/
|
|
||||||
private void setLevelWaitTime(final User player) {
|
|
||||||
levelWaitTime.put(player.getUniqueId(), Long.valueOf(Calendar.getInstance().getTimeInMillis() + levelWait * 1000));
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean onLevelWaitTime(final User sender) {
|
|
||||||
if (levelWaitTime.containsKey(sender.getUniqueId())) {
|
|
||||||
if (levelWaitTime.get(sender.getUniqueId()).longValue() > Calendar.getInstance().getTimeInMillis()) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private long getLevelWaitTime(final User sender) {
|
|
||||||
if (levelWaitTime.containsKey(sender.getUniqueId())) {
|
|
||||||
if (levelWaitTime.get(sender.getUniqueId()).longValue() > Calendar.getInstance().getTimeInMillis()) {
|
|
||||||
return (levelWaitTime.get(sender.getUniqueId()).longValue() - Calendar.getInstance().getTimeInMillis()) / 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0L;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,289 +0,0 @@
|
|||||||
/*******************************************************************************
|
|
||||||
* This file is part of ASkyBlock.
|
|
||||||
*
|
|
||||||
* ASkyBlock is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation, either version 3 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* ASkyBlock is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with ASkyBlock. If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
package bskyblock.addin.level;
|
|
||||||
|
|
||||||
import java.beans.IntrospectionException;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.sql.SQLException;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.ChatColor;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.event.EventHandler;
|
|
||||||
import org.bukkit.event.EventPriority;
|
|
||||||
import org.bukkit.event.Listener;
|
|
||||||
import org.bukkit.event.inventory.ClickType;
|
|
||||||
import org.bukkit.event.inventory.InventoryClickEvent;
|
|
||||||
import org.bukkit.event.inventory.InventoryType.SlotType;
|
|
||||||
import org.bukkit.inventory.Inventory;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import org.bukkit.inventory.meta.SkullMeta;
|
|
||||||
|
|
||||||
import bskyblock.addin.level.database.object.Levels;
|
|
||||||
import bskyblock.addin.level.database.object.TopTenList;
|
|
||||||
import bskyblock.addin.level.event.TopTenClick;
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
|
||||||
import us.tastybento.bskyblock.config.Settings;
|
|
||||||
import us.tastybento.bskyblock.database.BSBDatabase;
|
|
||||||
import us.tastybento.bskyblock.database.managers.AbstractDatabaseHandler;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles all Top Ten List functions
|
|
||||||
*
|
|
||||||
* @author tastybento
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class TopTen implements Listener {
|
|
||||||
private Level plugin;
|
|
||||||
// Top ten list of players
|
|
||||||
private TopTenList topTenList;
|
|
||||||
private final int GUISIZE = 27; // Must be a multiple of 9
|
|
||||||
private final int[] SLOTS = new int[] {4, 12, 14, 19, 20, 21, 22, 23, 24, 25};
|
|
||||||
private final boolean DEBUG = false;
|
|
||||||
// Store this as a because it's the same for everyone and saves memory cleanup
|
|
||||||
private Inventory gui;
|
|
||||||
private BSBDatabase database;
|
|
||||||
private AbstractDatabaseHandler<TopTenList> handler;
|
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public TopTen(Level plugin) {
|
|
||||||
this.plugin = plugin;
|
|
||||||
// Set up database
|
|
||||||
database = BSBDatabase.getDatabase();
|
|
||||||
// Set up the database handler to store and retrieve the TopTenList class
|
|
||||||
// Note that these are saved in the BSkyBlock database
|
|
||||||
handler = (AbstractDatabaseHandler<TopTenList>) database.getHandler(BSkyBlock.getPlugin(), TopTenList.class);
|
|
||||||
loadTopTen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a player to the top ten, if the level is good enough
|
|
||||||
*
|
|
||||||
* @param ownerUUID
|
|
||||||
* @param l
|
|
||||||
*/
|
|
||||||
public void addEntry(UUID ownerUUID, long l) {
|
|
||||||
// Try and see if the player is online
|
|
||||||
Player player = plugin.getServer().getPlayer(ownerUUID);
|
|
||||||
if (player != null) {
|
|
||||||
// Online
|
|
||||||
if (!player.hasPermission(Settings.PERMPREFIX + "intopten")) {
|
|
||||||
topTenList.remove(ownerUUID);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
topTenList.addLevel(ownerUUID, l);
|
|
||||||
saveTopTen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the top ten list from scratch. Does not get the level of each island. Just
|
|
||||||
* takes the level from the player's file.
|
|
||||||
* Runs asynchronously from the main thread.
|
|
||||||
*/
|
|
||||||
public void create() {
|
|
||||||
// Obtain all the levels for each known player
|
|
||||||
AbstractDatabaseHandler<Levels> levelHandler = plugin.getHandler();
|
|
||||||
try {
|
|
||||||
long index = 0;
|
|
||||||
for (Levels lv : levelHandler.loadObjects()) {
|
|
||||||
if (index++ % 1000 == 0) {
|
|
||||||
plugin.getLogger().info("Processed " + index + " players for top ten");
|
|
||||||
}
|
|
||||||
// Convert to UUID
|
|
||||||
UUID playerUUID = UUID.fromString(lv.getUniqueId());
|
|
||||||
// Check if the player is an owner or team leader
|
|
||||||
if (BSkyBlock.getPlugin().getIslands().isOwner(playerUUID)) {
|
|
||||||
topTenList.addLevel(playerUUID, lv.getLevel());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
|
||||||
| SecurityException | ClassNotFoundException | IntrospectionException | SQLException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
saveTopTen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Displays the Top Ten list if it exists in chat
|
|
||||||
*
|
|
||||||
* @param player
|
|
||||||
* - the requesting player
|
|
||||||
* @return - true if successful, false if no Top Ten list exists
|
|
||||||
*/
|
|
||||||
public boolean getGUI(final Player player) {
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: GUI display");
|
|
||||||
// New GUI display (shown by default)
|
|
||||||
if (topTenList == null) create();
|
|
||||||
// Create the top ten GUI if it does not exist
|
|
||||||
if (gui == null) {
|
|
||||||
gui = Bukkit.createInventory(null, GUISIZE, "topten.guiTitle");
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: creating GUI for the first time");
|
|
||||||
}
|
|
||||||
// Reset
|
|
||||||
gui.clear();
|
|
||||||
int i = 1;
|
|
||||||
Iterator<Entry<UUID, Long>> it = topTenList.getTopTen().entrySet().iterator();
|
|
||||||
while (it.hasNext()) {
|
|
||||||
Map.Entry<UUID, Long> m = it.next();
|
|
||||||
UUID playerUUID = m.getKey();
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: " + i + ": " + playerUUID);
|
|
||||||
// Remove from TopTen if the player is online and has the permission
|
|
||||||
Player entry = plugin.getServer().getPlayer(playerUUID);
|
|
||||||
boolean show = true;
|
|
||||||
if (entry != null) {
|
|
||||||
if (!entry.hasPermission(Settings.PERMPREFIX + "intopten")) {
|
|
||||||
it.remove();
|
|
||||||
show = false;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: player not online, so no per check");
|
|
||||||
|
|
||||||
}
|
|
||||||
if (show) {
|
|
||||||
gui.setItem(SLOTS[i-1], getSkull(i, m.getValue(), playerUUID));
|
|
||||||
if (i++ == 10) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
player.openInventory(gui);
|
|
||||||
player.updateInventory();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ItemStack getSkull(int rank, Long long1, UUID player){
|
|
||||||
if (DEBUG)
|
|
||||||
plugin.getLogger().info("DEBUG: Getting the skull");
|
|
||||||
String playerName = BSkyBlock.getPlugin().getPlayers().getName(player);
|
|
||||||
if (DEBUG) {
|
|
||||||
plugin.getLogger().info("DEBUG: playername = " + playerName);
|
|
||||||
|
|
||||||
plugin.getLogger().info("DEBUG: second chance = " + BSkyBlock.getPlugin().getPlayers().getName(player));
|
|
||||||
}
|
|
||||||
ItemStack playerSkull = new ItemStack(Material.SKULL_ITEM, 1, (short) 3);
|
|
||||||
if (playerName == null) return null;
|
|
||||||
SkullMeta meta = (SkullMeta) playerSkull.getItemMeta();
|
|
||||||
//meta.setOwningPlayer(plugin.getServer().getOfflinePlayer(player));
|
|
||||||
meta.setOwner(playerName);
|
|
||||||
meta.setDisplayName(("topten.guiHeading".replace("[name]", BSkyBlock.getPlugin().getIslands().getIslandName(player))).replace("[rank]", String.valueOf(rank)));
|
|
||||||
//meta.setDisplayName(ChatColor.YELLOW + "" + ChatColor.BOLD + "<!> " + ChatColor.YELLOW + "Island: " + ChatColor.GOLD + ChatColor.UNDERLINE + plugin.getGrid().getIslandName(player) + ChatColor.GRAY + " (#" + rank + ")");
|
|
||||||
List<String> lore = new ArrayList<String>();
|
|
||||||
lore.add(ChatColor.YELLOW + "topten.islandLevel".replace("[level]", String.valueOf(long1)));
|
|
||||||
if (BSkyBlock.getPlugin().getPlayers().inTeam(player)) {
|
|
||||||
List<String> memberList = new ArrayList<>();
|
|
||||||
for (UUID members : BSkyBlock.getPlugin().getIslands().getMembers(player)) {
|
|
||||||
memberList.add(ChatColor.AQUA + BSkyBlock.getPlugin().getPlayers().getName(members));
|
|
||||||
}
|
|
||||||
lore.addAll(memberList);
|
|
||||||
}
|
|
||||||
//else lore.add(ChatColor.AQUA + playerName);
|
|
||||||
|
|
||||||
meta.setLore(lore);
|
|
||||||
playerSkull.setItemMeta(meta);
|
|
||||||
return playerSkull;
|
|
||||||
}
|
|
||||||
|
|
||||||
public TopTenList getTopTenList() {
|
|
||||||
return topTenList;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the top ten from the database
|
|
||||||
*/
|
|
||||||
public void loadTopTen() {
|
|
||||||
try {
|
|
||||||
topTenList = handler.loadObject("topten");
|
|
||||||
if (topTenList == null) {
|
|
||||||
topTenList = new TopTenList();
|
|
||||||
}
|
|
||||||
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException
|
|
||||||
| SecurityException | ClassNotFoundException | IntrospectionException | SQLException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled=true)
|
|
||||||
public void onInventoryClick(InventoryClickEvent event) {
|
|
||||||
Inventory inventory = event.getInventory(); // The inventory that was clicked in
|
|
||||||
if (inventory.getName() == null) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// The player that clicked the item
|
|
||||||
Player player = (Player) event.getWhoClicked();
|
|
||||||
if (!inventory.getTitle().equals("topten.guiTitle")) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
event.setCancelled(true);
|
|
||||||
player.updateInventory();
|
|
||||||
if(event.getCurrentItem() != null && event.getCurrentItem().getType().equals(Material.SKULL_ITEM) && event.getCurrentItem().hasItemMeta()){
|
|
||||||
player.closeInventory();
|
|
||||||
// Fire click event
|
|
||||||
TopTenClick clickEvent = new TopTenClick(((SkullMeta)event.getCurrentItem().getItemMeta()).getOwningPlayer().getName());
|
|
||||||
plugin.getServer().getPluginManager().callEvent(clickEvent);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getSlotType().equals(SlotType.OUTSIDE)) {
|
|
||||||
player.closeInventory();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (event.getClick().equals(ClickType.SHIFT_RIGHT)) {
|
|
||||||
player.closeInventory();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes ownerUUID from the top ten list
|
|
||||||
*
|
|
||||||
* @param ownerUUID
|
|
||||||
*/
|
|
||||||
public void removeEntry(UUID ownerUUID) {
|
|
||||||
topTenList.remove(ownerUUID);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void saveTopTen() {
|
|
||||||
//plugin.getLogger().info("Saving top ten list");
|
|
||||||
if (topTenList == null) {
|
|
||||||
//plugin.getLogger().info("DEBUG: toptenlist = null!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
handler.saveObject(topTenList);
|
|
||||||
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException | SecurityException
|
|
||||||
| InstantiationException | NoSuchMethodException | IntrospectionException | SQLException e) {
|
|
||||||
// TODO Auto-generated catch block
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
package bskyblock.addin.level.commands;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import bskyblock.addin.level.Level;
|
|
||||||
import us.tastybento.bskyblock.api.commands.CompositeCommand;
|
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
|
||||||
import us.tastybento.bskyblock.config.Settings;
|
|
||||||
|
|
||||||
public class AdminLevel extends CompositeCommand {
|
|
||||||
|
|
||||||
private final Level levelPlugin;
|
|
||||||
|
|
||||||
public AdminLevel(Level levelPlugin, CompositeCommand parent) {
|
|
||||||
super(parent, "level");
|
|
||||||
this.levelPlugin = levelPlugin;
|
|
||||||
this.setPermission(Settings.PERMPREFIX + "admin.level");
|
|
||||||
this.setOnlyPlayer(false);
|
|
||||||
this.setUsage("admin.level.usage");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean execute(User user, List<String> args) {
|
|
||||||
if (!args.isEmpty()) {
|
|
||||||
// Asking for another player's level?
|
|
||||||
// Convert name to a UUID
|
|
||||||
final UUID playerUUID = getPlugin().getPlayers().getUUID(args.get(0), true);
|
|
||||||
//getLogger().info("DEBUG: console player info UUID = " + playerUUID);
|
|
||||||
if (playerUUID == null) {
|
|
||||||
user.sendMessage("error.UnknownPlayer");
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
if (user.isPlayer()) {
|
|
||||||
levelPlugin.calculateIslandLevel(user, playerUUID, false);
|
|
||||||
} else {
|
|
||||||
levelPlugin.calculateIslandLevel(user, playerUUID, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
package bskyblock.addin.level.commands;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import bskyblock.addin.level.Level;
|
|
||||||
import us.tastybento.bskyblock.BSkyBlock;
|
|
||||||
import us.tastybento.bskyblock.api.commands.CompositeCommand;
|
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
|
||||||
import us.tastybento.bskyblock.config.Settings;
|
|
||||||
|
|
||||||
public class AdminTop extends CompositeCommand {
|
|
||||||
|
|
||||||
private final Level levelPlugin;
|
|
||||||
|
|
||||||
public AdminTop(Level levelPlugin, CompositeCommand parent) {
|
|
||||||
super(parent, "top", "topten");
|
|
||||||
this.levelPlugin = levelPlugin;
|
|
||||||
this.setPermission(Settings.PERMPREFIX + "admin.top");
|
|
||||||
this.setOnlyPlayer(false);
|
|
||||||
this.setUsage("admin.top.usage");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean execute(User user, List<String> args) {
|
|
||||||
int rank = 0;
|
|
||||||
for (Entry<UUID, Long> topTen : levelPlugin.getTopTen().getTopTenList().getTopTen().entrySet()) {
|
|
||||||
UUID player = topTen.getKey();
|
|
||||||
rank++;
|
|
||||||
String item = String.valueOf(rank) + ":" + BSkyBlock.getPlugin().getIslands().getIslandName(player) + " "
|
|
||||||
+ "topten.islandLevel" + String.valueOf(topTen.getValue());
|
|
||||||
user.sendLegacyMessage(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,27 +0,0 @@
|
|||||||
package bskyblock.addin.level.commands;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import bskyblock.addin.level.Level;
|
|
||||||
import us.tastybento.bskyblock.api.commands.CompositeCommand;
|
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
|
||||||
import us.tastybento.bskyblock.config.Settings;
|
|
||||||
|
|
||||||
public class IslandTop extends CompositeCommand {
|
|
||||||
|
|
||||||
private final Level plugin;
|
|
||||||
|
|
||||||
public IslandTop(Level plugin, CompositeCommand parent) {
|
|
||||||
super(parent, "top", "topten");
|
|
||||||
this.plugin = plugin;
|
|
||||||
this.setPermission(Settings.PERMPREFIX + "island.top");
|
|
||||||
this.setUsage("island.top.usage");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean execute(User user, List<String> list) {
|
|
||||||
plugin.getTopTen().getGUI(user.getPlayer());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,95 +0,0 @@
|
|||||||
package bskyblock.addin.level.config;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.StringUtils;
|
|
||||||
import org.bukkit.Material;
|
|
||||||
import org.bukkit.material.MaterialData;
|
|
||||||
|
|
||||||
import bskyblock.addin.level.Level;
|
|
||||||
|
|
||||||
public class PluginConfig {
|
|
||||||
private static final boolean DEBUG = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the various settings from the config.yml file into the plugin
|
|
||||||
*/
|
|
||||||
public PluginConfig(Level plugin) {
|
|
||||||
plugin.saveDefaultConfig();
|
|
||||||
|
|
||||||
// Island level cool down time
|
|
||||||
Settings.levelWait = plugin.getConfig().getInt("levelwait", 60);
|
|
||||||
if (Settings.levelWait < 0) {
|
|
||||||
Settings.levelWait = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the under water multiplier
|
|
||||||
Settings.deathpenalty = plugin.getConfig().getInt("deathpenalty", 0);
|
|
||||||
Settings.sumTeamDeaths = plugin.getConfig().getBoolean("sumteamdeaths");
|
|
||||||
Settings.maxDeaths = plugin.getConfig().getInt("maxdeaths", 10);
|
|
||||||
Settings.islandResetDeathReset = plugin.getConfig().getBoolean("islandresetdeathreset", true);
|
|
||||||
Settings.teamJoinDeathReset = plugin.getConfig().getBoolean("teamjoindeathreset", true);
|
|
||||||
Settings.underWaterMultiplier = plugin.getConfig().getDouble("underwater", 1D);
|
|
||||||
Settings.levelCost = plugin.getConfig().getInt("levelcost", 100);
|
|
||||||
if (Settings.levelCost < 1) {
|
|
||||||
Settings.levelCost = 1;
|
|
||||||
plugin.getLogger().warning("levelcost in blockvalues.yml cannot be less than 1. Setting to 1.");
|
|
||||||
}
|
|
||||||
Settings.blockLimits = new HashMap<MaterialData, Integer>();
|
|
||||||
if (plugin.getConfig().isSet("limits")) {
|
|
||||||
for (String material : plugin.getConfig().getConfigurationSection("limits").getKeys(false)) {
|
|
||||||
try {
|
|
||||||
String[] split = material.split(":");
|
|
||||||
byte data = 0;
|
|
||||||
if (split.length>1) {
|
|
||||||
data = Byte.valueOf(split[1]);
|
|
||||||
}
|
|
||||||
Material mat;
|
|
||||||
if (StringUtils.isNumeric(split[0])) {
|
|
||||||
mat = Material.getMaterial(Integer.parseInt(split[0]));
|
|
||||||
} else {
|
|
||||||
mat = Material.valueOf(split[0].toUpperCase());
|
|
||||||
}
|
|
||||||
MaterialData materialData = new MaterialData(mat);
|
|
||||||
materialData.setData(data);
|
|
||||||
Settings.blockLimits.put(materialData, plugin.getConfig().getInt("limits." + material, 0));
|
|
||||||
if (DEBUG) {
|
|
||||||
plugin.getLogger().info("Maximum number of " + materialData + " will be " + Settings.blockLimits.get(materialData));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
plugin.getLogger().warning("Unknown material (" + material + ") in blockvalues.yml Limits section. Skipping...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Settings.blockValues = new HashMap<MaterialData, Integer>();
|
|
||||||
if (plugin.getConfig().isSet("blocks")) {
|
|
||||||
for (String material : plugin.getConfig().getConfigurationSection("blocks").getKeys(false)) {
|
|
||||||
try {
|
|
||||||
String[] split = material.split(":");
|
|
||||||
byte data = 0;
|
|
||||||
if (split.length>1) {
|
|
||||||
data = Byte.valueOf(split[1]);
|
|
||||||
}
|
|
||||||
MaterialData materialData = null;
|
|
||||||
if (StringUtils.isNumeric(split[0])) {
|
|
||||||
materialData = new MaterialData(Integer.parseInt(split[0]));
|
|
||||||
} else {
|
|
||||||
materialData = new MaterialData(Material.valueOf(split[0].toUpperCase()));
|
|
||||||
}
|
|
||||||
|
|
||||||
materialData.setData(data);
|
|
||||||
Settings.blockValues.put(materialData, plugin.getConfig().getInt("blocks." + material, 0));
|
|
||||||
if (DEBUG) {
|
|
||||||
plugin.getLogger().info(materialData.toString() + " value = " + Settings.blockValues.get(materialData));
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
// e.printStackTrace();
|
|
||||||
plugin.getLogger().warning("Unknown material (" + material + ") in blockvalues.yml blocks section. Skipping...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
plugin.getLogger().severe("No block values in blockvalues.yml! All island levels will be zero!");
|
|
||||||
}
|
|
||||||
// All done
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,22 +0,0 @@
|
|||||||
package bskyblock.addin.level.config;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
import org.bukkit.material.MaterialData;
|
|
||||||
|
|
||||||
public class Settings {
|
|
||||||
|
|
||||||
public static boolean sumTeamDeaths;
|
|
||||||
public static int seaHeight;
|
|
||||||
public static HashMap<MaterialData, Integer> blockLimits;
|
|
||||||
public static HashMap<MaterialData, Integer> blockValues;
|
|
||||||
public static double underWaterMultiplier;
|
|
||||||
public static int deathpenalty;
|
|
||||||
public static long levelCost;
|
|
||||||
public static Object defaultLanguage;
|
|
||||||
public static int levelWait;
|
|
||||||
public static int maxDeaths;
|
|
||||||
public static boolean islandResetDeathReset;
|
|
||||||
public static boolean teamJoinDeathReset;
|
|
||||||
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
package bskyblock.addin.level.database.object;
|
|
||||||
|
|
||||||
import us.tastybento.bskyblock.database.objects.DataObject;
|
|
||||||
|
|
||||||
public class Levels extends DataObject {
|
|
||||||
|
|
||||||
private String uniqueId = "";
|
|
||||||
private long level = 0;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUniqueId() {
|
|
||||||
return uniqueId;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setUniqueId(String uniqueId) {
|
|
||||||
this.uniqueId = uniqueId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLevel() {
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLevel(long level) {
|
|
||||||
this.level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
package bskyblock.addin.level.event;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import us.tastybento.bskyblock.api.events.IslandBaseEvent;
|
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This event is fired after ASkyBlock calculates an island level and when it sends notification to the player.
|
|
||||||
* Use getLevel() to see the level calculated and getPointsToNextLevel() to see how much points are needed to reach next level.
|
|
||||||
* Canceling this event will result in no notifications to the player.
|
|
||||||
*
|
|
||||||
* @author Poslovitch, tastybento
|
|
||||||
*/
|
|
||||||
public class IslandPostLevelEvent extends IslandBaseEvent {
|
|
||||||
private long level;
|
|
||||||
private long pointsToNextLevel;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param player
|
|
||||||
* @param island
|
|
||||||
* @param l
|
|
||||||
*/
|
|
||||||
public IslandPostLevelEvent(UUID player, Island island, long l, long m) {
|
|
||||||
super(island);
|
|
||||||
this.level = l;
|
|
||||||
this.pointsToNextLevel = m;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLevel() {
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLevel(long level) {
|
|
||||||
this.level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getPointsToNextLevel() {
|
|
||||||
return pointsToNextLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPointsToNextLevel(long pointsToNextLevel) {
|
|
||||||
this.pointsToNextLevel = pointsToNextLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
@ -1,45 +0,0 @@
|
|||||||
package bskyblock.addin.level.event;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import us.tastybento.bskyblock.api.events.IslandBaseEvent;
|
|
||||||
import us.tastybento.bskyblock.database.objects.Island;
|
|
||||||
|
|
||||||
public class IslandPreLevelEvent extends IslandBaseEvent {
|
|
||||||
|
|
||||||
private UUID targetPlayer;
|
|
||||||
private long level;
|
|
||||||
private long pointsToNextLevel;
|
|
||||||
|
|
||||||
|
|
||||||
public IslandPreLevelEvent(UUID targetPlayer, Island island, long level) {
|
|
||||||
super(island);
|
|
||||||
this.targetPlayer = targetPlayer;
|
|
||||||
this.level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getPointsToNextLevel() {
|
|
||||||
return pointsToNextLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPointsToNextLevel(long pointsToNextLevel) {
|
|
||||||
this.pointsToNextLevel = pointsToNextLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UUID getTargetPlayer() {
|
|
||||||
return targetPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTargetPlayer(UUID targetPlayer) {
|
|
||||||
this.targetPlayer = targetPlayer;
|
|
||||||
}
|
|
||||||
|
|
||||||
public long getLevel() {
|
|
||||||
return level;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setLevel(long level) {
|
|
||||||
this.level = level;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
191
src/main/java/bskyblock/addon/level/Level.java
Normal file
191
src/main/java/bskyblock/addon/level/Level.java
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
package bskyblock.addon.level;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.commands.AdminLevel;
|
||||||
|
import bskyblock.addon.level.commands.AdminTop;
|
||||||
|
import bskyblock.addon.level.commands.IslandLevel;
|
||||||
|
import bskyblock.addon.level.commands.IslandTop;
|
||||||
|
import bskyblock.addon.level.config.Settings;
|
||||||
|
import bskyblock.addon.level.database.object.LevelsData;
|
||||||
|
import bskyblock.addon.level.listeners.NewIslandListener;
|
||||||
|
import world.bentobox.bentobox.api.addons.Addon;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.database.BSBDatabase;
|
||||||
|
import world.bentobox.bentobox.database.objects.Island;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Addon to BSkyBlock that enables island level scoring and top ten functionality
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Level extends Addon {
|
||||||
|
|
||||||
|
// Settings
|
||||||
|
private Settings settings;
|
||||||
|
|
||||||
|
// Database handler for level data
|
||||||
|
private BSBDatabase<LevelsData> handler;
|
||||||
|
|
||||||
|
// A cache of island levels.
|
||||||
|
private Map<UUID, LevelsData> levelsCache;
|
||||||
|
|
||||||
|
// The Top Ten object
|
||||||
|
private TopTen topTen;
|
||||||
|
|
||||||
|
// Level calculator
|
||||||
|
private LevelPresenter levelCalc;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates a user's island
|
||||||
|
* @param world - the world where this island is
|
||||||
|
* @param user - the user who is asking, or null if none
|
||||||
|
* @param playerUUID - the target island member's UUID
|
||||||
|
*/
|
||||||
|
public void calculateIslandLevel(World world, User user, UUID playerUUID) {
|
||||||
|
levelCalc.calculateIslandLevel(world, user, playerUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get level from cache for a player
|
||||||
|
* @param targetPlayer
|
||||||
|
* @return Level of player
|
||||||
|
*/
|
||||||
|
public long getIslandLevel(World world, UUID targetPlayer) {
|
||||||
|
LevelsData ld = getLevelsData(targetPlayer);
|
||||||
|
return ld == null ? 0L : ld.getLevel(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LevelsData getLevelsData(UUID targetPlayer) {
|
||||||
|
// Load player
|
||||||
|
return levelsCache.getOrDefault(targetPlayer, handler.loadObject(targetPlayer.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the settings
|
||||||
|
*/
|
||||||
|
public final Settings getSettings() {
|
||||||
|
return settings;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TopTen getTopTen() {
|
||||||
|
return topTen;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDisable(){
|
||||||
|
// Save the cache
|
||||||
|
if (levelsCache != null) {
|
||||||
|
save(false);
|
||||||
|
}
|
||||||
|
if (topTen != null) {
|
||||||
|
topTen.saveTopTen();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onEnable() {
|
||||||
|
// Check if it is enabled - it might be loaded, but not enabled.
|
||||||
|
if (getPlugin() == null || !getPlugin().isEnabled()) {
|
||||||
|
getLogger().severe("BSkyBlock does not exist or is not enabled. Stopping.");
|
||||||
|
this.setEnabled(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Load the plugin's config
|
||||||
|
settings = new Settings(this);
|
||||||
|
// Get the BSkyBlock database
|
||||||
|
// Set up the database handler to store and retrieve Island classes
|
||||||
|
// Note that these are saved by the BSkyBlock database
|
||||||
|
handler = new BSBDatabase<>(this, LevelsData.class);
|
||||||
|
// Initialize the cache
|
||||||
|
levelsCache = new HashMap<>();
|
||||||
|
// Load the calculator
|
||||||
|
levelCalc = new LevelPresenter(this, this.getPlugin());
|
||||||
|
// Start the top ten and register it for clicks
|
||||||
|
topTen = new TopTen(this);
|
||||||
|
registerListener(topTen);
|
||||||
|
// Register commands - run one tick later to allow all addons to load
|
||||||
|
// AcidIsland hook in
|
||||||
|
getServer().getScheduler().runTask(getPlugin(), () -> {
|
||||||
|
this.getPlugin().getAddonsManager().getAddonByName("AcidIsland").ifPresent(a -> {
|
||||||
|
CompositeCommand acidIslandCmd = getPlugin().getCommandsManager().getCommand("ai");
|
||||||
|
if (acidIslandCmd != null) {
|
||||||
|
new IslandLevel(this, acidIslandCmd);
|
||||||
|
new IslandTop(this, acidIslandCmd);
|
||||||
|
CompositeCommand acidCmd = getPlugin().getCommandsManager().getCommand("acid");
|
||||||
|
new AdminLevel(this, acidCmd);
|
||||||
|
new AdminTop(this, acidCmd);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// BSkyBlock hook in
|
||||||
|
this.getPlugin().getAddonsManager().getAddonByName("BSkyBlock").ifPresent(a -> {
|
||||||
|
CompositeCommand bsbIslandCmd = getPlugin().getCommandsManager().getCommand("island");
|
||||||
|
if (bsbIslandCmd != null) {
|
||||||
|
new IslandLevel(this, bsbIslandCmd);
|
||||||
|
new IslandTop(this, bsbIslandCmd);
|
||||||
|
CompositeCommand bsbAdminCmd = getPlugin().getCommandsManager().getCommand("bsbadmin");
|
||||||
|
new AdminLevel(this, bsbAdminCmd);
|
||||||
|
new AdminTop(this, bsbAdminCmd);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register new island listener
|
||||||
|
registerListener(new NewIslandListener(this));
|
||||||
|
// Done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the levels to the database
|
||||||
|
* @param async - if true, saving will be done async
|
||||||
|
*/
|
||||||
|
public void save(boolean async){
|
||||||
|
Runnable save = () -> levelsCache.values().forEach(handler::saveObject);
|
||||||
|
if(async){
|
||||||
|
getServer().getScheduler().runTaskAsynchronously(getPlugin(), save);
|
||||||
|
} else {
|
||||||
|
save.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the player's level to a value
|
||||||
|
* @param world
|
||||||
|
* @param targetPlayer
|
||||||
|
* @param level
|
||||||
|
*/
|
||||||
|
public void setIslandLevel(World world, UUID targetPlayer, long level) {
|
||||||
|
LevelsData ld = getLevelsData(targetPlayer);
|
||||||
|
if (ld == null) {
|
||||||
|
ld = new LevelsData(targetPlayer, level, world);
|
||||||
|
} else {
|
||||||
|
ld.setLevel(world, level);
|
||||||
|
}
|
||||||
|
// Add to cache
|
||||||
|
levelsCache.put(targetPlayer, ld);
|
||||||
|
topTen.addEntry(world, targetPlayer, getIslandLevel(world, targetPlayer));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the initial island level
|
||||||
|
* @param island - island
|
||||||
|
* @param level - initial calculated island level
|
||||||
|
*/
|
||||||
|
public void setInitialIslandLevel(Island island, long level) {
|
||||||
|
setIslandLevel(island.getWorld(), island.getOwner(), level);
|
||||||
|
levelsCache.get(island.getOwner()).setInitialIslandLevel(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public BSBDatabase<LevelsData> getHandler() {
|
||||||
|
return handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
100
src/main/java/bskyblock/addon/level/LevelPresenter.java
Normal file
100
src/main/java/bskyblock/addon/level/LevelPresenter.java
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
package bskyblock.addon.level;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.calculators.PlayerLevel;
|
||||||
|
import world.bentobox.bentobox.BentoBox;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
public class LevelPresenter {
|
||||||
|
|
||||||
|
private int levelWait;
|
||||||
|
private final Level addon;
|
||||||
|
private final BentoBox plugin;
|
||||||
|
|
||||||
|
// Level calc cool down
|
||||||
|
private HashMap<UUID, Long> levelWaitTime = new HashMap<UUID, Long>();
|
||||||
|
|
||||||
|
public LevelPresenter(Level addon, BentoBox plugin) {
|
||||||
|
this.addon = addon;
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the island level
|
||||||
|
* @param world - world to check
|
||||||
|
* @param sender - asker of the level info
|
||||||
|
* @param targetPlayer
|
||||||
|
* @return - false if this is cannot be done
|
||||||
|
*/
|
||||||
|
public boolean calculateIslandLevel(World world, final User sender, UUID targetPlayer) {
|
||||||
|
// Get permission prefix for this world
|
||||||
|
String permPrefix = plugin.getIWM().getPermissionPrefix(world);
|
||||||
|
// Check if target has island
|
||||||
|
boolean inTeam = false;
|
||||||
|
if (!plugin.getIslands().hasIsland(world, targetPlayer)) {
|
||||||
|
// Player may be in a team
|
||||||
|
if (plugin.getIslands().inTeam(world, targetPlayer)) {
|
||||||
|
targetPlayer = plugin.getIslands().getTeamLeader(world, targetPlayer);
|
||||||
|
inTeam = true;
|
||||||
|
} else {
|
||||||
|
sender.sendMessage("general.errors.player-has-no-island");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Player asking for their own island calc
|
||||||
|
if (inTeam || !sender.isPlayer() || sender.getUniqueId().equals(targetPlayer) || sender.isOp() || sender.hasPermission(permPrefix + "mod.info")) {
|
||||||
|
// Newer better system - uses chunks
|
||||||
|
if (!onLevelWaitTime(sender) || levelWait <= 0 || sender.isOp() || sender.hasPermission(permPrefix + "mod.info")) {
|
||||||
|
sender.sendMessage("island.level.calculating");
|
||||||
|
setLevelWaitTime(sender);
|
||||||
|
new PlayerLevel(addon, plugin.getIslands().getIsland(world, targetPlayer), targetPlayer, sender);
|
||||||
|
} else {
|
||||||
|
// Cooldown
|
||||||
|
sender.sendMessage("island.level.cooldown", "[time]", String.valueOf(getLevelWaitTime(sender)));
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Asking for the level of another player
|
||||||
|
sender.sendMessage("island.level.island-level-is","[level]", String.valueOf(addon.getIslandLevel(world, targetPlayer)));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets cool down for the level command
|
||||||
|
*
|
||||||
|
* @param player
|
||||||
|
*/
|
||||||
|
private void setLevelWaitTime(final User player) {
|
||||||
|
levelWaitTime.put(player.getUniqueId(), Long.valueOf(Calendar.getInstance().getTimeInMillis() + levelWait * 1000));
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean onLevelWaitTime(final User sender) {
|
||||||
|
if (levelWaitTime.containsKey(sender.getUniqueId())) {
|
||||||
|
if (levelWaitTime.get(sender.getUniqueId()).longValue() > Calendar.getInstance().getTimeInMillis()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long getLevelWaitTime(final User sender) {
|
||||||
|
if (levelWaitTime.containsKey(sender.getUniqueId())) {
|
||||||
|
if (levelWaitTime.get(sender.getUniqueId()).longValue() > Calendar.getInstance().getTimeInMillis()) {
|
||||||
|
return (levelWaitTime.get(sender.getUniqueId()).longValue() - Calendar.getInstance().getTimeInMillis()) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0L;
|
||||||
|
}
|
||||||
|
}
|
216
src/main/java/bskyblock/addon/level/TopTen.java
Normal file
216
src/main/java/bskyblock/addon/level/TopTen.java
Normal file
@ -0,0 +1,216 @@
|
|||||||
|
package bskyblock.addon.level;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChatColor;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.database.object.LevelsData;
|
||||||
|
import bskyblock.addon.level.database.object.TopTenData;
|
||||||
|
import world.bentobox.bentobox.api.panels.PanelItem;
|
||||||
|
import world.bentobox.bentobox.api.panels.builders.PanelBuilder;
|
||||||
|
import world.bentobox.bentobox.api.panels.builders.PanelItemBuilder;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.database.BSBDatabase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles all Top Ten List functions
|
||||||
|
*
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TopTen implements Listener {
|
||||||
|
private Level addon;
|
||||||
|
// Top ten list of players
|
||||||
|
private Map<World,TopTenData> topTenList;
|
||||||
|
private final int[] SLOTS = new int[] {4, 12, 14, 19, 20, 21, 22, 23, 24, 25};
|
||||||
|
private final boolean DEBUG = false;
|
||||||
|
private BSBDatabase<TopTenData> handler;
|
||||||
|
|
||||||
|
public TopTen(Level addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
// Set up the database handler to store and retrieve the TopTenList class
|
||||||
|
// Note that these are saved in the BSkyBlock database
|
||||||
|
handler = new BSBDatabase<>(addon, TopTenData.class);
|
||||||
|
loadTopTen();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a player to the top ten, if the level is good enough
|
||||||
|
*
|
||||||
|
* @param ownerUUID
|
||||||
|
* @param l
|
||||||
|
*/
|
||||||
|
public void addEntry(World world, UUID ownerUUID, long l) {
|
||||||
|
// Check if player is an island owner or not
|
||||||
|
if (!addon.getIslands().isOwner(world, ownerUUID)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Set up world data
|
||||||
|
topTenList.putIfAbsent(world, new TopTenData());
|
||||||
|
topTenList.get(world).setUniqueId(world.getName());
|
||||||
|
|
||||||
|
// Try and see if the player is online
|
||||||
|
Player player = addon.getServer().getPlayer(ownerUUID);
|
||||||
|
if (player != null) {
|
||||||
|
// Online
|
||||||
|
if (!player.hasPermission(addon.getPlugin().getIWM().getPermissionPrefix(world) + ".intopten")) {
|
||||||
|
topTenList.get(world).remove(ownerUUID);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
topTenList.get(world).addLevel(ownerUUID, l);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates the top ten list from scratch. Does not get the level of each island. Just
|
||||||
|
* takes the level from the player's file.
|
||||||
|
* Runs asynchronously from the main thread.
|
||||||
|
*/
|
||||||
|
public void create(String permPrefix) {
|
||||||
|
// Obtain all the levels for each known player
|
||||||
|
BSBDatabase<LevelsData> levelHandler = addon.getHandler();
|
||||||
|
long index = 0;
|
||||||
|
for (LevelsData lv : levelHandler.loadObjects()) {
|
||||||
|
if (index++ % 1000 == 0) {
|
||||||
|
addon.getLogger().info("Processed " + index + " players for top ten");
|
||||||
|
}
|
||||||
|
// Convert to UUID
|
||||||
|
UUID playerUUID = UUID.fromString(lv.getUniqueId());
|
||||||
|
// Get the world
|
||||||
|
lv.getLevels().forEach((k,v) -> addEntry(Bukkit.getWorld(k), playerUUID, v));
|
||||||
|
}
|
||||||
|
saveTopTen();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the Top Ten list
|
||||||
|
* @param world
|
||||||
|
*
|
||||||
|
* @param user
|
||||||
|
* - the requesting player
|
||||||
|
* @return - true if successful, false if no Top Ten list exists
|
||||||
|
*/
|
||||||
|
public boolean getGUI(World world, final User user, String permPrefix) {
|
||||||
|
// Check world
|
||||||
|
topTenList.putIfAbsent(world, new TopTenData());
|
||||||
|
topTenList.get(world).setUniqueId(world.getName());
|
||||||
|
if (DEBUG)
|
||||||
|
addon.getLogger().info("DEBUG: GUI display");
|
||||||
|
|
||||||
|
PanelBuilder panel = new PanelBuilder()
|
||||||
|
.name(user.getTranslation("island.top.gui-title"))
|
||||||
|
.user(user);
|
||||||
|
|
||||||
|
int i = 1;
|
||||||
|
Iterator<Entry<UUID, Long>> it = topTenList.get(world).getTopTen().entrySet().iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Map.Entry<UUID, Long> m = it.next();
|
||||||
|
UUID topTenUUID = m.getKey();
|
||||||
|
if (DEBUG)
|
||||||
|
addon.getLogger().info("DEBUG: " + i + ": " + topTenUUID);
|
||||||
|
// Remove from TopTen if the player is online and has the permission
|
||||||
|
Player entry = addon.getServer().getPlayer(topTenUUID);
|
||||||
|
boolean show = true;
|
||||||
|
if (entry != null) {
|
||||||
|
if (DEBUG)
|
||||||
|
addon.getLogger().info("DEBUG: removing from topten");
|
||||||
|
if (!entry.hasPermission(permPrefix + "intopten")) {
|
||||||
|
it.remove();
|
||||||
|
show = false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (DEBUG)
|
||||||
|
addon.getLogger().info("DEBUG: player not online, so no per check");
|
||||||
|
|
||||||
|
}
|
||||||
|
if (show) {
|
||||||
|
panel.item(SLOTS[i-1], getHead(i, m.getValue(), topTenUUID, user, world));
|
||||||
|
if (i++ == 10) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
panel.build();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the head panel item
|
||||||
|
* @param rank - the top ten rank of this player/team. Can be used in the name of the island for vanity.
|
||||||
|
* @param level - the level of the island
|
||||||
|
* @param playerUUID - the UUID of the top ten player
|
||||||
|
* @param asker - the asker of the top ten
|
||||||
|
* @return PanelItem
|
||||||
|
*/
|
||||||
|
private PanelItem getHead(int rank, Long level, UUID playerUUID, User asker, World world) {
|
||||||
|
final String name = addon.getPlayers().getName(playerUUID);
|
||||||
|
List<String> description = new ArrayList<>();
|
||||||
|
if (name != null) {
|
||||||
|
description.add(asker.getTranslation("island.top.gui-heading", "[name]", name, "[rank]", String.valueOf(rank)));
|
||||||
|
description.add(asker.getTranslation("island.top.island-level","[level]", String.valueOf(level)));
|
||||||
|
if (addon.getIslands().inTeam(world, playerUUID)) {
|
||||||
|
List<String> memberList = new ArrayList<>();
|
||||||
|
for (UUID members : addon.getIslands().getMembers(world, playerUUID)) {
|
||||||
|
memberList.add(ChatColor.AQUA + addon.getPlayers().getName(members));
|
||||||
|
}
|
||||||
|
description.addAll(memberList);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PanelItemBuilder builder = new PanelItemBuilder()
|
||||||
|
.icon(name)
|
||||||
|
.name(name)
|
||||||
|
.description(description);
|
||||||
|
|
||||||
|
// If welcome warps is present then add warping
|
||||||
|
/*
|
||||||
|
addon.getAddonByName("BSkyBlock-WelcomeWarps").ifPresent(warp -> {
|
||||||
|
|
||||||
|
if (((Warp)warp).getWarpSignsManager().hasWarp(world, playerUUID)) {
|
||||||
|
builder.clickHandler((panel, user, click, slot) -> {
|
||||||
|
if (click.equals(ClickType.LEFT)) {
|
||||||
|
user.sendMessage("island.top.warp-to", "[name]", name);
|
||||||
|
((Warp)warp).getWarpSignsManager().warpPlayer(world, user, playerUUID);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public TopTenData getTopTenList(World world) {
|
||||||
|
return topTenList.get(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads all the top tens from the database
|
||||||
|
*/
|
||||||
|
public void loadTopTen() {
|
||||||
|
topTenList = new HashMap<>();
|
||||||
|
handler.loadObjects().forEach(tt -> topTenList.put(Bukkit.getWorld(tt.getUniqueId()), tt));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes ownerUUID from the top ten list
|
||||||
|
*
|
||||||
|
* @param ownerUUID
|
||||||
|
*/
|
||||||
|
public void removeEntry(World world, UUID ownerUUID) {
|
||||||
|
topTenList.putIfAbsent(world, new TopTenData());
|
||||||
|
topTenList.get(world).setUniqueId(world.getName());
|
||||||
|
topTenList.get(world).remove(ownerUUID);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveTopTen() {
|
||||||
|
topTenList.values().forEach(handler::saveObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,364 @@
|
|||||||
|
package bskyblock.addon.level.calculators;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.ChunkSnapshot;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.scheduler.BukkitTask;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultiset;
|
||||||
|
import com.google.common.collect.Multiset;
|
||||||
|
import com.google.common.collect.Multiset.Entry;
|
||||||
|
import com.google.common.collect.Multisets;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.Level;
|
||||||
|
import world.bentobox.bentobox.database.objects.Island;
|
||||||
|
import world.bentobox.bentobox.util.Pair;
|
||||||
|
import world.bentobox.bentobox.util.Util;
|
||||||
|
|
||||||
|
|
||||||
|
public class CalcIslandLevel {
|
||||||
|
|
||||||
|
private static final int MAX_CHUNKS = 200;
|
||||||
|
private static final long SPEED = 1;
|
||||||
|
private boolean checking = true;
|
||||||
|
private BukkitTask task;
|
||||||
|
|
||||||
|
private Level addon;
|
||||||
|
|
||||||
|
private Set<Pair<Integer, Integer>> chunksToScan;
|
||||||
|
private Island island;
|
||||||
|
private World world;
|
||||||
|
private Results result;
|
||||||
|
private Runnable onExit;
|
||||||
|
|
||||||
|
// Copy the limits hashmap
|
||||||
|
HashMap<Material, Integer> limitCount;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate the island's level
|
||||||
|
* Results are available in {@link CalcIslandLevel.Results}
|
||||||
|
* @param addon - Level addon
|
||||||
|
* @param island - island to be calculated
|
||||||
|
* @param onExit - what to run when done
|
||||||
|
*/
|
||||||
|
public CalcIslandLevel(final Level addon, final Island island, final Runnable onExit) {
|
||||||
|
this.addon = addon;
|
||||||
|
this.island = island;
|
||||||
|
this.world = island != null ? island.getCenter().getWorld() : null;
|
||||||
|
this.limitCount = new HashMap<>(addon.getSettings().getBlockLimits());
|
||||||
|
this.onExit = onExit;
|
||||||
|
|
||||||
|
// Results go here
|
||||||
|
result = new Results();
|
||||||
|
|
||||||
|
// Get chunks to scan
|
||||||
|
chunksToScan = getChunksToScan(island);
|
||||||
|
|
||||||
|
// Start checking
|
||||||
|
checking = true;
|
||||||
|
|
||||||
|
// Start a recurring task until done or cancelled
|
||||||
|
task = addon.getServer().getScheduler().runTaskTimer(addon.getPlugin(), () -> {
|
||||||
|
Set<ChunkSnapshot> chunkSnapshot = new HashSet<>();
|
||||||
|
if (checking) {
|
||||||
|
Iterator<Pair<Integer, Integer>> it = chunksToScan.iterator();
|
||||||
|
if (!it.hasNext()) {
|
||||||
|
// Nothing left
|
||||||
|
tidyUp();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Add chunk snapshots to the list
|
||||||
|
while (it.hasNext() && chunkSnapshot.size() < MAX_CHUNKS) {
|
||||||
|
Pair<Integer, Integer> pair = it.next();
|
||||||
|
if (!world.isChunkLoaded(pair.x, pair.z)) {
|
||||||
|
world.loadChunk(pair.x, pair.z);
|
||||||
|
chunkSnapshot.add(world.getChunkAt(pair.x, pair.z).getChunkSnapshot());
|
||||||
|
world.unloadChunk(pair.x, pair.z);
|
||||||
|
} else {
|
||||||
|
chunkSnapshot.add(world.getChunkAt(pair.x, pair.z).getChunkSnapshot());
|
||||||
|
}
|
||||||
|
it.remove();
|
||||||
|
}
|
||||||
|
// Move to next step
|
||||||
|
checking = false;
|
||||||
|
checkChunksAsync(chunkSnapshot);
|
||||||
|
}
|
||||||
|
}, 0L, SPEED);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkChunksAsync(final Set<ChunkSnapshot> chunkSnapshot) {
|
||||||
|
// Run async task to scan chunks
|
||||||
|
addon.getServer().getScheduler().runTaskAsynchronously(addon.getPlugin(), () -> {
|
||||||
|
for (ChunkSnapshot chunk: chunkSnapshot) {
|
||||||
|
scanChunk(chunk);
|
||||||
|
}
|
||||||
|
// Nothing happened, change state
|
||||||
|
checking = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scanChunk(ChunkSnapshot chunk) {
|
||||||
|
for (int x = 0; x< 16; x++) {
|
||||||
|
// Check if the block coord is inside the protection zone and if not, don't count it
|
||||||
|
if (chunk.getX() * 16 + x < island.getMinProtectedX() || chunk.getX() * 16 + x >= island.getMinProtectedX() + island.getProtectionRange() * 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int z = 0; z < 16; z++) {
|
||||||
|
// Check if the block coord is inside the protection zone and if not, don't count it
|
||||||
|
if (chunk.getZ() * 16 + z < island.getMinProtectedZ() || chunk.getZ() * 16 + z >= island.getMinProtectedZ() + island.getProtectionRange() * 2) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int y = 0; y < island.getCenter().getWorld().getMaxHeight(); y++) {
|
||||||
|
Material blockData = chunk.getBlockType(x, y, z);
|
||||||
|
boolean belowSeaLevel = (addon.getSettings().getSeaHeight() > 0 && y<=addon.getSettings().getSeaHeight()) ? true : false;
|
||||||
|
// Air is free
|
||||||
|
if (!blockData.equals(Material.AIR)) {
|
||||||
|
checkBlock(blockData, belowSeaLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkBlock(Material md, boolean belowSeaLevel) {
|
||||||
|
int count = limitCount(md);
|
||||||
|
if (belowSeaLevel) {
|
||||||
|
result.underWaterBlockCount += count;
|
||||||
|
result.uwCount.add(md);
|
||||||
|
} else {
|
||||||
|
result.rawBlockCount += count;
|
||||||
|
result.mdCount.add(md);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if a block has been limited or not and whether a block has any value or not
|
||||||
|
* @param md
|
||||||
|
* @return value of the block if can be counted
|
||||||
|
*/
|
||||||
|
private int limitCount(Material md) {
|
||||||
|
if (limitCount.containsKey(md)) {
|
||||||
|
int count = limitCount.get(md);
|
||||||
|
if (count > 0) {
|
||||||
|
limitCount.put(md, --count);
|
||||||
|
return getValue(md);
|
||||||
|
} else {
|
||||||
|
result.ofCount.add(md);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else if (addon.getSettings().getBlockValues().containsKey(md)) {
|
||||||
|
return getValue(md);
|
||||||
|
} else {
|
||||||
|
result.ncCount.add(md);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get value of a material
|
||||||
|
* World blocks trump regular block values
|
||||||
|
* @param md
|
||||||
|
* @return value of a material
|
||||||
|
*/
|
||||||
|
private int getValue(Material md) {
|
||||||
|
if (addon.getSettings().getWorldBlockValues().containsKey(world) && addon.getSettings().getWorldBlockValues().get(world).containsKey(md)) {
|
||||||
|
return addon.getSettings().getWorldBlockValues().get(world).get(md);
|
||||||
|
}
|
||||||
|
return addon.getSettings().getBlockValues().getOrDefault(md, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a set of all the chunks in island
|
||||||
|
* @param island
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Set<Pair<Integer, Integer>> getChunksToScan(Island island) {
|
||||||
|
Set<Pair<Integer, Integer>> chunkSnapshot = new HashSet<>();
|
||||||
|
for (int x = island.getMinProtectedX(); x < (island.getMinProtectedX() + island.getProtectionRange() * 2 + 16); x += 16) {
|
||||||
|
for (int z = island.getMinProtectedZ(); z < (island.getMinProtectedZ() + island.getProtectionRange() * 2 + 16); z += 16) {
|
||||||
|
Pair<Integer, Integer> pair = new Pair<>(world.getBlockAt(x, 0, z).getChunk().getX(), world.getBlockAt(x, 0, z).getChunk().getZ());
|
||||||
|
chunkSnapshot.add(pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return chunkSnapshot;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void tidyUp() {
|
||||||
|
// Cancel
|
||||||
|
task.cancel();
|
||||||
|
// Finalize calculations
|
||||||
|
result.rawBlockCount += (long)(result.underWaterBlockCount * addon.getSettings().getUnderWaterMultiplier());
|
||||||
|
// Set the death penalty
|
||||||
|
result.deathHandicap = addon.getPlayers().getDeaths(world, island.getOwner());
|
||||||
|
// Set final score
|
||||||
|
result.level = (result.rawBlockCount / addon.getSettings().getLevelCost()) - result.deathHandicap - island.getLevelHandicap();
|
||||||
|
// Calculate how many points are required to get to the next level
|
||||||
|
result.pointsToNextLevel = (addon.getSettings().getLevelCost() * (result.level + 1 + island.getLevelHandicap())) - (result.rawBlockCount - (result.deathHandicap * addon.getSettings().getDeathPenalty()));
|
||||||
|
// Sometimes it will return 0, so calculate again to make sure it will display a good value
|
||||||
|
if(result.pointsToNextLevel == 0) result.pointsToNextLevel = (addon.getSettings().getLevelCost() * (result.level + 2 + island.getLevelHandicap()) - (result.rawBlockCount - (result.deathHandicap * addon.getSettings().getDeathPenalty())));
|
||||||
|
// Report
|
||||||
|
result.report = getReport();
|
||||||
|
// All done.
|
||||||
|
if (onExit != null) {
|
||||||
|
Bukkit.getScheduler().runTask(addon.getPlugin(), onExit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private List<String> getReport() {
|
||||||
|
List<String> reportLines = new ArrayList<>();
|
||||||
|
// provide counts
|
||||||
|
reportLines.add("Level Log for island in " + addon.getPlugin().getIWM().getFriendlyName(island.getWorld()) + " at " + Util.xyz(island.getCenter().toVector()));
|
||||||
|
reportLines.add("Island owner UUID = " + island.getOwner());
|
||||||
|
reportLines.add("Total block value count = " + String.format("%,d",result.rawBlockCount));
|
||||||
|
reportLines.add("Level cost = " + addon.getSettings().getLevelCost());
|
||||||
|
reportLines.add("Deaths handicap = " + result.deathHandicap);
|
||||||
|
reportLines.add("Level calculated = " + result.level);
|
||||||
|
reportLines.add("==================================");
|
||||||
|
int total = 0;
|
||||||
|
if (!result.uwCount.isEmpty()) {
|
||||||
|
reportLines.add("Underwater block count (Multiplier = x" + addon.getSettings().getUnderWaterMultiplier() + ") value");
|
||||||
|
reportLines.add("Total number of underwater blocks = " + String.format("%,d",result.uwCount.size()));
|
||||||
|
reportLines.addAll(sortedReport(total, result.uwCount));
|
||||||
|
}
|
||||||
|
reportLines.add("Regular block count");
|
||||||
|
reportLines.add("Total number of blocks = " + String.format("%,d",result.mdCount.size()));
|
||||||
|
reportLines.addAll(sortedReport(total, result.mdCount));
|
||||||
|
|
||||||
|
reportLines.add("Blocks not counted because they exceeded limits: " + String.format("%,d",result.ofCount.size()));
|
||||||
|
//entriesSortedByCount = Multisets.copyHighestCountFirst(ofCount).entrySet();
|
||||||
|
Iterable<Multiset.Entry<Material>> entriesSortedByCount = result.ofCount.entrySet();
|
||||||
|
Iterator<Entry<Material>> it = entriesSortedByCount.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Entry<Material> type = it.next();
|
||||||
|
Integer limit = addon.getSettings().getBlockLimits().get(type.getElement());
|
||||||
|
String explain = ")";
|
||||||
|
if (limit == null) {
|
||||||
|
Material generic = type.getElement();
|
||||||
|
limit = addon.getSettings().getBlockLimits().get(generic);
|
||||||
|
explain = " - All types)";
|
||||||
|
}
|
||||||
|
reportLines.add(type.getElement().toString() + ": " + String.format("%,d",type.getCount()) + " blocks (max " + limit + explain);
|
||||||
|
}
|
||||||
|
reportLines.add("==================================");
|
||||||
|
reportLines.add("Blocks on island that are not in config.yml");
|
||||||
|
reportLines.add("Total number = " + String.format("%,d",result.ncCount.size()));
|
||||||
|
//entriesSortedByCount = Multisets.copyHighestCountFirst(ncCount).entrySet();
|
||||||
|
entriesSortedByCount = result.ncCount.entrySet();
|
||||||
|
it = entriesSortedByCount.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Entry<Material> type = it.next();
|
||||||
|
reportLines.add(type.getElement().toString() + ": " + String.format("%,d",type.getCount()) + " blocks");
|
||||||
|
}
|
||||||
|
reportLines.add("=================================");
|
||||||
|
|
||||||
|
return reportLines;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Collection<String> sortedReport(int total, Multiset<Material> MaterialCount) {
|
||||||
|
Collection<String> result = new ArrayList<>();
|
||||||
|
Iterable<Multiset.Entry<Material>> entriesSortedByCount = Multisets.copyHighestCountFirst(MaterialCount).entrySet();
|
||||||
|
Iterator<Entry<Material>> it = entriesSortedByCount.iterator();
|
||||||
|
while (it.hasNext()) {
|
||||||
|
Entry<Material> en = it.next();
|
||||||
|
Material type = en.getElement();
|
||||||
|
|
||||||
|
int value = 0;
|
||||||
|
if (addon.getSettings().getBlockValues().containsKey(type)) {
|
||||||
|
// Specific
|
||||||
|
value = addon.getSettings().getBlockValues().get(type);
|
||||||
|
}
|
||||||
|
result.add(type.toString() + ":"
|
||||||
|
+ String.format("%,d",en.getCount()) + " blocks x " + value + " = " + (value * en.getCount()));
|
||||||
|
total += (value * en.getCount());
|
||||||
|
}
|
||||||
|
result.add("Subtotal = " + total);
|
||||||
|
result.add("==================================");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the result
|
||||||
|
*/
|
||||||
|
public Results getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Results class
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class Results {
|
||||||
|
private List<String> report;
|
||||||
|
private Multiset<Material> mdCount = HashMultiset.create();
|
||||||
|
private Multiset<Material> uwCount = HashMultiset.create();
|
||||||
|
private Multiset<Material> ncCount = HashMultiset.create();
|
||||||
|
private Multiset<Material> ofCount = HashMultiset.create();
|
||||||
|
private long rawBlockCount = 0;
|
||||||
|
private long underWaterBlockCount = 0;
|
||||||
|
private long level = 0;
|
||||||
|
private int deathHandicap = 0;
|
||||||
|
private long pointsToNextLevel = 0;
|
||||||
|
/**
|
||||||
|
* @return the deathHandicap
|
||||||
|
*/
|
||||||
|
public int getDeathHandicap() {
|
||||||
|
return deathHandicap;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param deathHandicap the deathHandicap to set
|
||||||
|
*/
|
||||||
|
public void setDeathHandicap(int deathHandicap) {
|
||||||
|
this.deathHandicap = deathHandicap;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the report
|
||||||
|
*/
|
||||||
|
public List<String> getReport() {
|
||||||
|
return report;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the level
|
||||||
|
*/
|
||||||
|
public long getLevel() {
|
||||||
|
return level;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the pointsToNextLevel
|
||||||
|
*/
|
||||||
|
public long getPointsToNextLevel() {
|
||||||
|
return pointsToNextLevel;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param report the report to set
|
||||||
|
*/
|
||||||
|
public void setReport(List<String> report) {
|
||||||
|
this.report = report;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param level the level to set
|
||||||
|
*/
|
||||||
|
public void setLevel(long level) {
|
||||||
|
this.level = level;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param pointsToNextLevel the pointsToNextLevel to set
|
||||||
|
*/
|
||||||
|
public void setPointsToNextLevel(long pointsToNextLevel) {
|
||||||
|
this.pointsToNextLevel = pointsToNextLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,88 @@
|
|||||||
|
package bskyblock.addon.level.calculators;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.Level;
|
||||||
|
import bskyblock.addon.level.calculators.CalcIslandLevel.Results;
|
||||||
|
import bskyblock.addon.level.event.IslandLevelCalculatedEvent;
|
||||||
|
import bskyblock.addon.level.event.IslandPreLevelEvent;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.database.objects.Island;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the player's island level. For admin or players
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class PlayerLevel {
|
||||||
|
|
||||||
|
private Level addon;
|
||||||
|
|
||||||
|
private Island island;
|
||||||
|
private World world;
|
||||||
|
private User asker;
|
||||||
|
private UUID targetPlayer;
|
||||||
|
|
||||||
|
private long oldLevel;
|
||||||
|
|
||||||
|
private CalcIslandLevel calc;
|
||||||
|
|
||||||
|
|
||||||
|
public PlayerLevel(final Level addon, final Island island, final UUID targetPlayer, final User asker) {
|
||||||
|
this.addon = addon;
|
||||||
|
this.island = island;
|
||||||
|
this.world = island != null ? island.getCenter().getWorld() : null;
|
||||||
|
this.asker = asker;
|
||||||
|
this.targetPlayer = targetPlayer;
|
||||||
|
this.oldLevel = addon.getIslandLevel(world, targetPlayer);
|
||||||
|
|
||||||
|
// Fire pre-level calc event
|
||||||
|
IslandPreLevelEvent e = new IslandPreLevelEvent(targetPlayer, island);
|
||||||
|
addon.getServer().getPluginManager().callEvent(e);
|
||||||
|
if (!e.isCancelled()) {
|
||||||
|
// Calculate if not cancelled
|
||||||
|
calc = new CalcIslandLevel(addon, island, ()-> informPlayers());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void informPlayers() {
|
||||||
|
// Fire post calculation event
|
||||||
|
IslandLevelCalculatedEvent ilce = new IslandLevelCalculatedEvent(targetPlayer, island, calc.getResult());
|
||||||
|
addon.getServer().getPluginManager().callEvent(ilce);
|
||||||
|
Results results = ilce.getResults();
|
||||||
|
// Save the results
|
||||||
|
island.getMemberSet().forEach(m -> addon.setIslandLevel(world, m, results.getLevel()));
|
||||||
|
// Display result
|
||||||
|
if (!ilce.isCancelled()) {
|
||||||
|
// Tell the asker
|
||||||
|
asker.sendMessage("island.level.island-level-is", "[level]", String.valueOf(addon.getIslandLevel(world, targetPlayer)));
|
||||||
|
// Console
|
||||||
|
if (!asker.isPlayer()) {
|
||||||
|
results.getReport().forEach(asker::sendRawMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Player
|
||||||
|
if (addon.getSettings().getDeathPenalty() != 0) {
|
||||||
|
asker.sendMessage("island.level.deaths", "[number]", String.valueOf(results.getDeathHandicap()));
|
||||||
|
}
|
||||||
|
// Send player how many points are required to reach next island level
|
||||||
|
if (results.getPointsToNextLevel() >= 0) {
|
||||||
|
asker.sendMessage("island.level.required-points-to-next-level", "[points]", String.valueOf(addon.getIslandLevel(world, targetPlayer)));
|
||||||
|
}
|
||||||
|
// Tell other team members
|
||||||
|
if (addon.getIslandLevel(world, targetPlayer) != oldLevel) {
|
||||||
|
for (UUID member : island.getMemberSet()) {
|
||||||
|
if (!member.equals(asker.getUniqueId())) {
|
||||||
|
User.getInstance(member).sendMessage("island.level.island-level-is", "[level]", String.valueOf(addon.getIslandLevel(world, targetPlayer)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
48
src/main/java/bskyblock/addon/level/commands/AdminLevel.java
Normal file
48
src/main/java/bskyblock/addon/level/commands/AdminLevel.java
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
package bskyblock.addon.level.commands;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.Level;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
public class AdminLevel extends CompositeCommand {
|
||||||
|
|
||||||
|
private final Level levelPlugin;
|
||||||
|
|
||||||
|
public AdminLevel(Level levelPlugin, CompositeCommand parent) {
|
||||||
|
super(parent, "level");
|
||||||
|
this.levelPlugin = levelPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
|
if (args.size() == 1) {
|
||||||
|
// Asking for another player's level?
|
||||||
|
// Convert name to a UUID
|
||||||
|
final UUID playerUUID = getPlugin().getPlayers().getUUID(args.get(0));
|
||||||
|
//getLogger().info("DEBUG: console player info UUID = " + playerUUID);
|
||||||
|
if (playerUUID == null) {
|
||||||
|
user.sendMessage("general.errors.unknown-player");
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
levelPlugin.calculateIslandLevel(getWorld(), user, playerUUID);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
showHelp(this, user);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission("admin.level");
|
||||||
|
this.setOnlyPlayer(false);
|
||||||
|
this.setParameters("admin.level.parameters");
|
||||||
|
this.setDescription("admin.level.description");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
64
src/main/java/bskyblock/addon/level/commands/AdminTop.java
Normal file
64
src/main/java/bskyblock/addon/level/commands/AdminTop.java
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
package bskyblock.addon.level.commands;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.Level;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
import world.bentobox.bentobox.database.objects.Island;
|
||||||
|
|
||||||
|
public class AdminTop extends CompositeCommand {
|
||||||
|
|
||||||
|
private final Level levelPlugin;
|
||||||
|
|
||||||
|
public AdminTop(Level levelPlugin, CompositeCommand parent) {
|
||||||
|
super(parent, "top", "topten");
|
||||||
|
this.levelPlugin = levelPlugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
|
// Get world
|
||||||
|
World world = null;
|
||||||
|
if (args.isEmpty()) {
|
||||||
|
if (getPlugin().getIWM().getOverWorlds().size() == 1) {
|
||||||
|
world = getPlugin().getIWM().getOverWorlds().get(0);
|
||||||
|
} else {
|
||||||
|
showHelp(this, user);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (getPlugin().getIWM().isOverWorld(args.get(0))) {
|
||||||
|
world = getPlugin().getIWM().getIslandWorld(args.get(0));
|
||||||
|
} else {
|
||||||
|
user.sendMessage("commands.admin.top.unknown-world");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
int rank = 0;
|
||||||
|
for (Entry<UUID, Long> topTen : levelPlugin.getTopTen().getTopTenList(world).getTopTen().entrySet()) {
|
||||||
|
Island island = getPlugin().getIslands().getIsland(world, topTen.getKey());
|
||||||
|
if (island != null) {
|
||||||
|
rank++;
|
||||||
|
String item = String.valueOf(rank) + ":" + island.getName() + " "
|
||||||
|
+ user.getTranslation("topten.islandLevel", "[level]", String.valueOf(topTen.getValue()));
|
||||||
|
user.sendRawMessage(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission("admin.top");
|
||||||
|
this.setOnlyPlayer(false);
|
||||||
|
this.setDescription("admin.top.description");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,48 +1,51 @@
|
|||||||
package bskyblock.addin.level.commands;
|
package bskyblock.addon.level.commands;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import bskyblock.addin.level.Level;
|
import bskyblock.addon.level.Level;
|
||||||
import us.tastybento.bskyblock.api.commands.CompositeCommand;
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
import us.tastybento.bskyblock.api.commands.User;
|
import world.bentobox.bentobox.api.user.User;
|
||||||
import us.tastybento.bskyblock.config.Settings;
|
|
||||||
|
|
||||||
public class IslandLevel extends CompositeCommand {
|
public class IslandLevel extends CompositeCommand {
|
||||||
|
|
||||||
private final Level levelPlugin;
|
private final Level levelPlugin;
|
||||||
|
|
||||||
public IslandLevel(Level levelPlugin, CompositeCommand parent) {
|
public IslandLevel(Level levelPlugin, CompositeCommand parent) {
|
||||||
super(parent, "level");
|
super(parent, "level");
|
||||||
this.levelPlugin = levelPlugin;
|
this.levelPlugin = levelPlugin;
|
||||||
this.setPermission(Settings.PERMPREFIX + "island.level");
|
|
||||||
this.setUsage("island.level.usage");
|
|
||||||
this.setOnlyPlayer(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean execute(User user, List<String> args) {
|
public boolean execute(User user, String label, List<String> args) {
|
||||||
if (!args.isEmpty()) {
|
if (!args.isEmpty()) {
|
||||||
// Asking for another player's level?
|
// Asking for another player's level?
|
||||||
// Convert name to a UUID
|
// Convert name to a UUID
|
||||||
final UUID playerUUID = getPlugin().getPlayers().getUUID(args.get(0), true);
|
final UUID playerUUID = getPlugin().getPlayers().getUUID(args.get(0));
|
||||||
//getLogger().info("DEBUG: console player info UUID = " + playerUUID);
|
//getLogger().info("DEBUG: console player info UUID = " + playerUUID);
|
||||||
if (playerUUID == null) {
|
if (playerUUID == null) {
|
||||||
user.sendMessage("error.UnknownPlayer");
|
user.sendMessage("general.errors.unknown-player");
|
||||||
return true;
|
return true;
|
||||||
} else if (user.getUniqueId().equals(playerUUID) ) {
|
} else if (user.getUniqueId().equals(playerUUID) ) {
|
||||||
// Self level request
|
// Self level request
|
||||||
levelPlugin.calculateIslandLevel(user, user.getUniqueId(), false);
|
levelPlugin.calculateIslandLevel(getWorld(), user, user.getUniqueId());
|
||||||
} else {
|
} else {
|
||||||
user.sendMessage("addon.level.level-is", "[level]", String.valueOf(levelPlugin.getIslandLevel(playerUUID)));
|
user.sendMessage("island.level.island-level-is", "[level]", String.valueOf(levelPlugin.getIslandLevel(getWorld(), playerUUID)));
|
||||||
user.sendLegacyMessage("Level = " + String.valueOf(levelPlugin.getIslandLevel(playerUUID)));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Self level request
|
// Self level request
|
||||||
levelPlugin.calculateIslandLevel(user, user.getUniqueId(), false);
|
levelPlugin.calculateIslandLevel(getWorld(), user, user.getUniqueId());
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission("island.level");
|
||||||
|
this.setParameters("island.level.parameters");
|
||||||
|
this.setDescription("island.level.description");
|
||||||
|
this.setOnlyPlayer(true);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
32
src/main/java/bskyblock/addon/level/commands/IslandTop.java
Normal file
32
src/main/java/bskyblock/addon/level/commands/IslandTop.java
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
package bskyblock.addon.level.commands;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.Level;
|
||||||
|
import world.bentobox.bentobox.api.commands.CompositeCommand;
|
||||||
|
import world.bentobox.bentobox.api.user.User;
|
||||||
|
|
||||||
|
public class IslandTop extends CompositeCommand {
|
||||||
|
|
||||||
|
private final Level plugin;
|
||||||
|
|
||||||
|
public IslandTop(Level plugin, CompositeCommand parent) {
|
||||||
|
super(parent, "top", "topten");
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean execute(User user, String label, List<String> list) {
|
||||||
|
plugin.getTopTen().getGUI(getWorld(), user, getPermissionPrefix());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setup() {
|
||||||
|
this.setPermission("island.top");
|
||||||
|
this.setDescription("island.top.description");
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
250
src/main/java/bskyblock/addon/level/config/Settings.java
Normal file
250
src/main/java/bskyblock/addon/level/config/Settings.java
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
package bskyblock.addon.level.config;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Material;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.Level;
|
||||||
|
|
||||||
|
public class Settings {
|
||||||
|
|
||||||
|
private boolean sumTeamDeaths;
|
||||||
|
private int seaHeight;
|
||||||
|
private Map<Material, Integer> blockLimits = new HashMap<>();
|
||||||
|
private Map<Material, Integer> blockValues = new HashMap<>();
|
||||||
|
private Map<World, Map<Material, Integer>> worldBlockValues = new HashMap<>();
|
||||||
|
private double underWaterMultiplier;
|
||||||
|
private int deathpenalty;
|
||||||
|
private long levelCost;
|
||||||
|
private Object defaultLanguage;
|
||||||
|
private int levelWait;
|
||||||
|
private int maxDeaths;
|
||||||
|
private boolean islandResetDeathReset;
|
||||||
|
private boolean teamJoinDeathReset;
|
||||||
|
|
||||||
|
public Settings(Level level) {
|
||||||
|
|
||||||
|
level.saveDefaultConfig();
|
||||||
|
|
||||||
|
setLevelWait(level.getConfig().getInt("levelwait", 60));
|
||||||
|
if (getLevelWait() < 0) {
|
||||||
|
setLevelWait(0);
|
||||||
|
}
|
||||||
|
setDeathpenalty(level.getConfig().getInt("deathpenalty", 0));
|
||||||
|
setSumTeamDeaths(level.getConfig().getBoolean("sumteamdeaths"));
|
||||||
|
setMaxDeaths(level.getConfig().getInt("maxdeaths", 10));
|
||||||
|
setIslandResetDeathReset(level.getConfig().getBoolean("islandresetdeathreset", true));
|
||||||
|
setTeamJoinDeathReset(level.getConfig().getBoolean("teamjoindeathreset", true));
|
||||||
|
setUnderWaterMultiplier(level.getConfig().getDouble("underwater", 1D));
|
||||||
|
setLevelCost(level.getConfig().getInt("levelcost", 100));
|
||||||
|
if (getLevelCost() < 1) {
|
||||||
|
setLevelCost(1);
|
||||||
|
level.getLogger().warning("levelcost in blockvalues.yml cannot be less than 1. Setting to 1.");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (level.getConfig().isSet("limits")) {
|
||||||
|
HashMap<Material, Integer> blockLimits = new HashMap<>();
|
||||||
|
for (String material : level.getConfig().getConfigurationSection("limits").getKeys(false)) {
|
||||||
|
try {
|
||||||
|
Material mat = Material.valueOf(material);
|
||||||
|
blockLimits.put(mat, level.getConfig().getInt("limits." + material, 0));
|
||||||
|
} catch (Exception e) {
|
||||||
|
level.getLogger().warning("Unknown material (" + material + ") in blockvalues.yml Limits section. Skipping...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setBlockLimits(blockLimits);
|
||||||
|
}
|
||||||
|
if (level.getConfig().isSet("blocks")) {
|
||||||
|
Map<Material, Integer> blockValues = new HashMap<>();
|
||||||
|
for (String material : level.getConfig().getConfigurationSection("blocks").getKeys(false)) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
Material mat = Material.valueOf(material);
|
||||||
|
blockValues.put(mat, level.getConfig().getInt("blocks." + material, 0));
|
||||||
|
} catch (Exception e) {
|
||||||
|
// e.printStackTrace();
|
||||||
|
level.getLogger().warning("Unknown material (" + material + ") in config.yml blocks section. Skipping...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setBlockValues(blockValues);
|
||||||
|
} else {
|
||||||
|
level.getLogger().severe("No block values in config.yml! All island levels will be zero!");
|
||||||
|
}
|
||||||
|
// Worlds
|
||||||
|
if (level.getConfig().isSet("worlds")) {
|
||||||
|
ConfigurationSection worlds = level.getConfig().getConfigurationSection("worlds");
|
||||||
|
for (String world : worlds.getKeys(false)) {
|
||||||
|
World bWorld = Bukkit.getWorld(world);
|
||||||
|
if (bWorld != null) {
|
||||||
|
ConfigurationSection worldValues = worlds.getConfigurationSection(world);
|
||||||
|
for (String material : worldValues.getKeys(false)) {
|
||||||
|
Material mat = Material.valueOf(material);
|
||||||
|
Map<Material, Integer> values = worldBlockValues.getOrDefault(bWorld, new HashMap<>());
|
||||||
|
values.put(mat, worldValues.getInt("blocks." + material, 0));
|
||||||
|
worldBlockValues.put(bWorld, values);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
level.getLogger().severe("Level Addon: No such world : " + world);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// All done
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the sumTeamDeaths
|
||||||
|
*/
|
||||||
|
public final boolean isSumTeamDeaths() {
|
||||||
|
return sumTeamDeaths;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param sumTeamDeaths the sumTeamDeaths to set
|
||||||
|
*/
|
||||||
|
public final void setSumTeamDeaths(boolean sumTeamDeaths) {
|
||||||
|
this.sumTeamDeaths = sumTeamDeaths;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the seaHeight
|
||||||
|
*/
|
||||||
|
public final int getSeaHeight() {
|
||||||
|
return seaHeight;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param seaHeight the seaHeight to set
|
||||||
|
*/
|
||||||
|
public final void setSeaHeight(int seaHeight) {
|
||||||
|
this.seaHeight = seaHeight;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the blockLimits
|
||||||
|
*/
|
||||||
|
public final Map<Material, Integer> getBlockLimits() {
|
||||||
|
return blockLimits;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param blockLimits2 the blockLimits to set
|
||||||
|
*/
|
||||||
|
public final void setBlockLimits(HashMap<Material, Integer> blockLimits2) {
|
||||||
|
this.blockLimits = blockLimits2;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the blockValues
|
||||||
|
*/
|
||||||
|
public final Map<Material, Integer> getBlockValues() {
|
||||||
|
return blockValues;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param blockValues2 the blockValues to set
|
||||||
|
*/
|
||||||
|
public final void setBlockValues(Map<Material, Integer> blockValues2) {
|
||||||
|
this.blockValues = blockValues2;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the underWaterMultiplier
|
||||||
|
*/
|
||||||
|
public final double getUnderWaterMultiplier() {
|
||||||
|
return underWaterMultiplier;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param underWaterMultiplier the underWaterMultiplier to set
|
||||||
|
*/
|
||||||
|
public final void setUnderWaterMultiplier(double underWaterMultiplier) {
|
||||||
|
this.underWaterMultiplier = underWaterMultiplier;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the deathpenalty
|
||||||
|
*/
|
||||||
|
public final int getDeathPenalty() {
|
||||||
|
return deathpenalty;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param deathpenalty the deathpenalty to set
|
||||||
|
*/
|
||||||
|
public final void setDeathpenalty(int deathpenalty) {
|
||||||
|
this.deathpenalty = deathpenalty;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the levelCost
|
||||||
|
*/
|
||||||
|
public final long getLevelCost() {
|
||||||
|
return levelCost;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param levelCost the levelCost to set
|
||||||
|
*/
|
||||||
|
public final void setLevelCost(long levelCost) {
|
||||||
|
this.levelCost = levelCost;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the defaultLanguage
|
||||||
|
*/
|
||||||
|
public final Object getDefaultLanguage() {
|
||||||
|
return defaultLanguage;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param defaultLanguage the defaultLanguage to set
|
||||||
|
*/
|
||||||
|
public final void setDefaultLanguage(Object defaultLanguage) {
|
||||||
|
this.defaultLanguage = defaultLanguage;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the levelWait
|
||||||
|
*/
|
||||||
|
public final int getLevelWait() {
|
||||||
|
return levelWait;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param levelWait the levelWait to set
|
||||||
|
*/
|
||||||
|
public final void setLevelWait(int levelWait) {
|
||||||
|
this.levelWait = levelWait;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the maxDeaths
|
||||||
|
*/
|
||||||
|
public final int getMaxDeaths() {
|
||||||
|
return maxDeaths;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param maxDeaths the maxDeaths to set
|
||||||
|
*/
|
||||||
|
public final void setMaxDeaths(int maxDeaths) {
|
||||||
|
this.maxDeaths = maxDeaths;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the islandResetDeathReset
|
||||||
|
*/
|
||||||
|
public final boolean isIslandResetDeathReset() {
|
||||||
|
return islandResetDeathReset;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param islandResetDeathReset the islandResetDeathReset to set
|
||||||
|
*/
|
||||||
|
public final void setIslandResetDeathReset(boolean islandResetDeathReset) {
|
||||||
|
this.islandResetDeathReset = islandResetDeathReset;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @return the teamJoinDeathReset
|
||||||
|
*/
|
||||||
|
public final boolean isTeamJoinDeathReset() {
|
||||||
|
return teamJoinDeathReset;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param teamJoinDeathReset the teamJoinDeathReset to set
|
||||||
|
*/
|
||||||
|
public final void setTeamJoinDeathReset(boolean teamJoinDeathReset) {
|
||||||
|
this.teamJoinDeathReset = teamJoinDeathReset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the worldBlockValues
|
||||||
|
*/
|
||||||
|
public Map<World, Map<Material, Integer>> getWorldBlockValues() {
|
||||||
|
return worldBlockValues;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
package bskyblock.addon.level.database.object;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.World;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.database.objects.DataObject;
|
||||||
|
|
||||||
|
public class LevelsData implements DataObject {
|
||||||
|
|
||||||
|
// uniqueId is the player's UUID
|
||||||
|
@Expose
|
||||||
|
private String uniqueId = "";
|
||||||
|
|
||||||
|
// Map - world name, level
|
||||||
|
@Expose
|
||||||
|
private Map<String, Long> levels = new HashMap<>();
|
||||||
|
@Expose
|
||||||
|
private long initialIslandLevel = 0;
|
||||||
|
|
||||||
|
public LevelsData() {} // For Bean loading
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a level entry for target player
|
||||||
|
* @param targetPlayer
|
||||||
|
* @param level
|
||||||
|
* @param world
|
||||||
|
*/
|
||||||
|
public LevelsData(UUID targetPlayer, long level, World world) {
|
||||||
|
uniqueId = targetPlayer.toString();
|
||||||
|
levels.put(world.getName(), level);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see world.bentobox.bbox.database.objects.DataObject#getUniqueId()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getUniqueId() {
|
||||||
|
return uniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see world.bentobox.bbox.database.objects.DataObject#setUniqueId(java.lang.String)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setUniqueId(String uniqueId) {
|
||||||
|
this.uniqueId = uniqueId;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the island level for this world
|
||||||
|
* @param world - world
|
||||||
|
* @return island level, less the initialIslandLevel
|
||||||
|
*/
|
||||||
|
public Long getLevel(World world) {
|
||||||
|
return world == null ? -initialIslandLevel : levels.getOrDefault(world.getName(), 0L) - initialIslandLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the levels
|
||||||
|
*/
|
||||||
|
public Map<String, Long> getLevels() {
|
||||||
|
return levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param levels the levels to set
|
||||||
|
*/
|
||||||
|
public void setLevels(Map<String, Long> levels) {
|
||||||
|
this.levels = levels;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLevel(World world, Long lv) {
|
||||||
|
levels.put(world.getName(),lv);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the initialIslandLevel
|
||||||
|
*/
|
||||||
|
public long getInitialIslandLevel() {
|
||||||
|
return initialIslandLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param initialIslandLevel the initialIslandLevel to set
|
||||||
|
*/
|
||||||
|
public void setInitialIslandLevel(long initialIslandLevel) {
|
||||||
|
this.initialIslandLevel = initialIslandLevel;
|
||||||
|
}
|
||||||
|
}
|
@ -1,28 +1,38 @@
|
|||||||
package bskyblock.addin.level.database.object;
|
package bskyblock.addon.level.database.object;
|
||||||
|
|
||||||
import java.util.Comparator;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.LinkedHashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import us.tastybento.bskyblock.database.objects.DataObject;
|
import com.google.gson.annotations.Expose;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.database.objects.DataObject;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class stores and sorts the top ten.
|
* This class stores and sorts the top ten.
|
||||||
* @author ben
|
* @author ben
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class TopTenList extends DataObject {
|
public class TopTenData implements DataObject {
|
||||||
|
|
||||||
private String uniqueId = "topten";
|
// UniqueId is the world name
|
||||||
private HashMap<UUID, Long> topTen = new HashMap<>();
|
@Expose
|
||||||
|
private String uniqueId = "";
|
||||||
|
@Expose
|
||||||
|
private Map<UUID, Long> topTen = new LinkedHashMap<>();
|
||||||
|
|
||||||
|
public TopTenData() {}
|
||||||
|
|
||||||
public HashMap<UUID, Long> getTopTen() {
|
public Map<UUID, Long> getTopTen() {
|
||||||
return topTen;
|
return topTen.entrySet().stream()
|
||||||
|
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue())).limit(10)
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTopTen(HashMap<UUID, Long> topTen) {
|
public void setTopTen(Map<UUID, Long> topTen) {
|
||||||
this.topTen = topTen;
|
this.topTen = topTen;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,7 +53,6 @@ public class TopTenList extends DataObject {
|
|||||||
*/
|
*/
|
||||||
public void addLevel(UUID uuid, Long level) {
|
public void addLevel(UUID uuid, Long level) {
|
||||||
this.topTen.put(uuid, level);
|
this.topTen.put(uuid, level);
|
||||||
sortTopTen();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -65,13 +74,4 @@ public class TopTenList extends DataObject {
|
|||||||
this.topTen.remove(ownerUUID);
|
this.topTen.remove(ownerUUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Sorts the top ten and limits it to 10 entries
|
|
||||||
*/
|
|
||||||
void sortTopTen() {
|
|
||||||
topTen = (HashMap<UUID, Long>) topTen.entrySet().stream()
|
|
||||||
.sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
|
|
||||||
.limit(10)
|
|
||||||
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
|
|
||||||
}
|
|
||||||
}
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
package bskyblock.addon.level.event;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.calculators.CalcIslandLevel.Results;
|
||||||
|
import world.bentobox.bentobox.api.events.IslandBaseEvent;
|
||||||
|
import world.bentobox.bentobox.database.objects.Island;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This event is fired after the island level is calculated and before the results are saved.
|
||||||
|
* If this event is cancelled, results will saved, but not communicated. i.e., the result will be silent.
|
||||||
|
*
|
||||||
|
* @author tastybento
|
||||||
|
*/
|
||||||
|
public class IslandLevelCalculatedEvent extends IslandBaseEvent {
|
||||||
|
private Results results;
|
||||||
|
|
||||||
|
private UUID targetPlayer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param targetPlayer
|
||||||
|
* @param island
|
||||||
|
* @param results
|
||||||
|
*/
|
||||||
|
public IslandLevelCalculatedEvent(UUID targetPlayer, Island island, Results results) {
|
||||||
|
super(island);
|
||||||
|
this.targetPlayer = targetPlayer;
|
||||||
|
this.results = results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the results
|
||||||
|
*/
|
||||||
|
public Results getResults() {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the targetPlayer
|
||||||
|
*/
|
||||||
|
public UUID getTargetPlayer() {
|
||||||
|
return targetPlayer;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param results the results to set
|
||||||
|
*/
|
||||||
|
public void setResults(Results results) {
|
||||||
|
this.results = results;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param targetPlayer the targetPlayer to set
|
||||||
|
*/
|
||||||
|
public void setTargetPlayer(UUID targetPlayer) {
|
||||||
|
this.targetPlayer = targetPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
package bskyblock.addon.level.event;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import world.bentobox.bentobox.api.events.IslandBaseEvent;
|
||||||
|
import world.bentobox.bentobox.database.objects.Island;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an island level is going to be calculated
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class IslandPreLevelEvent extends IslandBaseEvent {
|
||||||
|
|
||||||
|
private UUID targetPlayer;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when an island level is going to be calculated
|
||||||
|
* @param targetPlayer - the player who is being tagetted (owner or team member)
|
||||||
|
* @param island - the island
|
||||||
|
*/
|
||||||
|
public IslandPreLevelEvent(UUID targetPlayer, Island island) {
|
||||||
|
super(island);
|
||||||
|
this.targetPlayer = targetPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UUID getTargetPlayer() {
|
||||||
|
return targetPlayer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package bskyblock.addin.level.event;
|
package bskyblock.addon.level.event;
|
||||||
|
|
||||||
import org.bukkit.event.Cancellable;
|
import org.bukkit.event.Cancellable;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
@ -0,0 +1,50 @@
|
|||||||
|
package bskyblock.addon.level.listeners;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.bukkit.event.EventHandler;
|
||||||
|
import org.bukkit.event.EventPriority;
|
||||||
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
import bskyblock.addon.level.Level;
|
||||||
|
import bskyblock.addon.level.calculators.CalcIslandLevel;
|
||||||
|
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandCreatedEvent;
|
||||||
|
import world.bentobox.bentobox.api.events.island.IslandEvent.IslandResettedEvent;
|
||||||
|
import world.bentobox.bentobox.database.objects.Island;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listens for new islands and sets the level to zero automatically
|
||||||
|
* @author tastybento
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class NewIslandListener implements Listener {
|
||||||
|
|
||||||
|
private Level addon;
|
||||||
|
private Map<Island, CalcIslandLevel> cil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param addon
|
||||||
|
*/
|
||||||
|
public NewIslandListener(Level addon) {
|
||||||
|
this.addon = addon;
|
||||||
|
cil = new HashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
|
public void onNewIsland(IslandCreatedEvent e) {
|
||||||
|
cil.putIfAbsent(e.getIsland(), new CalcIslandLevel(addon, e.getIsland(), () -> zeroLevel(e.getIsland())));
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
|
||||||
|
public void onNewIsland(IslandResettedEvent e) {
|
||||||
|
cil.putIfAbsent(e.getIsland(), new CalcIslandLevel(addon, e.getIsland(), () -> zeroLevel(e.getIsland())));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void zeroLevel(Island island) {
|
||||||
|
if (cil.containsKey(island)) {
|
||||||
|
addon.setInitialIslandLevel(island, cil.get(island).getResult().getLevel());
|
||||||
|
cil.remove(island);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user