
Better Veinminer
A Paper 1.21 Vein miner plugin that mines entire ore veins instantly.. Fully configurable via config.yml.
- Загрузки
- 719
- Подписчики
- 1
- Обновлён
- 8 июня 2026 г.
- Лицензия
- Apache-2.0
Опубликован 9 марта 2026 г.
Better Veinminer
Version: 1.5.1 | API: Paper 1.21+ | Author: Duong2012G
License: Apache-2.0 | Link: Modrinth
Mine an entire ore vein in one swing — with tier progression, persistent statistics, a custom event API, and deep configuration.
Features
Core
- 6-direction BFS — accurate face-adjacent vein detection matching vanilla ore generation; no false positives from diagonal neighbours
- Strict same-type matching — only collects blocks of the exact same material
- Fortune & Silk Touch — work automatically on every block in the vein
- Per-player toggle — each player can enable/disable independently with
/bvm toggle - Unbreaking-aware durability — matches vanilla's per-hit random probability model
- World whitelist/blacklist — restrict which worlds allow veinminer
- Hot reload —
/bvm reloadapplies config changes without a restart
Tier System
Players progress through 4 tiers as they mine more blocks:
| Tier | Blocks Required | Max Blocks (default) |
|---|---|---|
| 1 | 0 | 32 |
| 2 | 100,000 | 64 |
| 3 | 500,000 | 128 |
| 4 | 1,000,000 | 256 |
All thresholds and max-block limits are configurable. Check progress with /bvm tier.
Persistent Statistics
Stats survive server restarts. Saved per-player to
plugins/BetterVeinminer/stats/<uuid>.yml:
- Total blocks mined via veinminer
- Total veinmines performed
- Current tier
- Auto-save every 5 minutes (thread-safe snapshot) + on player quit
Daily Limits
Cap veinmines per player per day. Resets at real midnight, persisted across restarts
in data.yml. The counter itself is also persisted — a restart mid-day no longer
resets progress toward the daily cap.
Custom Event API
BetterVeinmineEvent lets other plugins hook into every veinmine:
@EventHandler
public void onVeinmine(BetterVeinmineEvent event) {
// Cancel completely (e.g. in protected regions)
if (isProtected(event.getPlayer())) {
event.setCancelled(true);
return;
}
// Double EXP on ancient debris
if (event.getOreType() == Material.ANCIENT_DEBRIS) {
event.setExpReward(event.getExpReward() * 2);
}
plugin.getLogger().info(event.getPlayer().getName()
+ " veinmined " + event.getBlocks().size() + " blocks.");
}
Protection Plugin Support
The main BlockBreakEvent listener runs at HIGH priority (ignoreCancelled = true),
so protection plugins (WorldGuard, Lands, GriefPrevention, Residence) that cancel the
event at NORMAL or LOW priority are respected — no veinmine task is ever scheduled
for a block the player cannot break. For each extra block in the vein a second
BlockBreakEvent is fired before breaking, allowing region-level per-block checks.
Per-block events are guarded by an anti-recursion lock so the plugin never triggers
itself in a loop.
Permission-Based Limits
Give VIP/Premium players special treatment via permission-levels in config.
When a player holds multiple permission nodes, the one with the highest max-blocks
value always takes precedence — no more random ordering.
Cooldown Feedback
When a player is still on cooldown, the remaining time is shown on the action bar
using the configurable cooldown message and its {remaining} placeholder.
Ore Multipliers
Configure different EXP multipliers per ore type.
Per-Ore Cooldowns
Different cooldown per ore type.
Installation
- Download
BetterVeinminer-1.5.0.jar - Drop into your server's
plugins/folder - Restart or reload the server
- Edit
plugins/BetterVeinminer/config.yml - Use
/bvm reloadto apply changes without restarting
Requirements: Paper (or any Paper fork) 1.21+, Java 21+
Permissions
| Permission | Description | Default |
|---|---|---|
betterveinminer.use |
Use veinminer + /bvm toggle/stats/tier |
true |
betterveinminer.admin |
Reload config (/bvm reload) |
op |
betterveinminer.vip |
VIP tier (custom limits via config) | false |
betterveinminer.premium |
Premium tier (best limits via config) | false |
Commands
| Command | Description | Permission |
|---|---|---|
/bvm toggle |
Enable/disable veinminer for yourself | betterveinminer.use |
/bvm stats |
View your mining statistics | betterveinminer.use |
/bvm tier |
Check your current tier & progression | betterveinminer.use |
/bvm reload |
Reload configuration file | betterveinminer.admin |
How to Use
- Hold a pickaxe from
tool-whitelist - Sneak (Shift) if
require-sneak: true - Break any ore block — the entire connected vein drops at once
Fortune and Silk Touch both work automatically on every block in the vein.
Configuration Reference
Basic Settings
enabled: true # Master on/off switch
require-sneak: true # Player must sneak to activate
require-pickaxe: true # Player must hold a whitelisted pickaxe
max-blocks: 64 # Max blocks per veinmine (fallback when tier system is off)
cooldown-ms: 200 # Cooldown between veinmines in milliseconds
damage-tool: true # Whether the pickaxe takes extra durability damage
damage-multiplier: 1.0 # Multiplier applied to the extra durability loss
Tier System
tier-system:
enabled: true
tier-2-threshold: 100000
tier-3-threshold: 500000
tier-4-threshold: 1000000
tier-1-max-blocks: 32
tier-2-max-blocks: 64
tier-3-max-blocks: 128
tier-4-max-blocks: 256
Ore Multipliers
ore-multipliers:
enabled: true
multipliers:
DIAMOND_ORE: 1.5
EMERALD_ORE: 2.0
COAL_ORE: 0.5
Per-Ore Cooldowns
per-ore-cooldowns:
enabled: false
cooldowns:
DIAMOND_ORE: 1000
COAL_ORE: 200
Permission Levels
Players with multiple permission nodes always receive the benefits of the
highest-max-blocks entry. Entries are evaluated highest-to-lowest automatically.
permission-levels:
betterveinminer.vip:
max-blocks: 128
cooldown-ms: 100
betterveinminer.premium:
max-blocks: 256
cooldown-ms: 50
Daily Limits
daily-limits:
enabled: false
limit-per-day: 10
The daily counter now persists across restarts. The count is only incremented when at least one extra block is actually broken (not when the veinmine is cancelled by another plugin or blocked by a protection plugin).
Custom Messages
All messages support § colour codes.
| Message key | Placeholders |
|---|---|
veinmine-success |
{count} |
tier-up |
{tier}, {blocks} |
stats |
{blocks}, {tier}, {uses} |
daily-limit |
— |
cooldown |
{remaining} |
The cooldown message is now actually sent to the player's action bar when they
try to veinmine before the cooldown expires.
EXP Rewards
exp-settings:
enabled: false
base-exp: 10
per-extra-block: 5
multiply-by-fortune: true
World Restrictions
whitelist-worlds: []
blacklist-worlds: []
Effects
particle-effect: true
sound-effect: true
effects:
particle-type: BLOCK
particle-color: "0xFFFFFF"
particle-speed: 1.0
completion-sound: BLOCK_STONE_BREAK
warning-sound: ENTITY_ITEM_PICKUP
Config Examples
Survival / Economy Server
tier-system:
enabled: true
tier-2-threshold: 50000
tier-3-threshold: 250000
tier-4-threshold: 500000
daily-limits:
enabled: true
limit-per-day: 5
ore-multipliers:
enabled: true
multipliers:
DIAMOND_ORE: 1.5
EMERALD_ORE: 2.0
Hardcore Mode
max-blocks: 16
cooldown-ms: 2000
tier-system:
enabled: false
damage-multiplier: 2.0
Developer API
Add as a soft dependency:
softdepend: [BetterVeinminer]
Listen to BetterVeinmineEvent:
import dev.duong2012g.bvm.BetterVeinmineEvent;
@EventHandler
public void onVeinmine(BetterVeinmineEvent event) {
Player player = event.getPlayer();
Material ore = event.getOreType();
List<Block> blocks = event.getBlocks(); // unmodifiable
int exp = event.getExpReward();
event.setExpReward(exp * 2);
event.setCancelled(true);
}
Bug Fixes by Version
v1.5.0
| # | Bug | Severity | Status |
|---|---|---|---|
| 1 | Daily-limit counter not persisted — restart bypassed the daily cap | High | ✅ Fixed |
| 2 | Blocking file I/O on async timer thread for data.yml writes |
High | ✅ Fixed |
| 3 | Cooldown message with {remaining} placeholder never sent to player |
Medium | ✅ Fixed |
| 4 | Permission priority non-deterministic — VIP+Premium received random limits | Medium | ✅ Fixed |
| 5 | Daily counter incremented before veinmine task confirmed success | Medium | ✅ Fixed |
| 6 | Cooldown cleanup evicted active entries for long per-ore cooldowns | Medium | ✅ Fixed |
| 7 | breakNaturally() used stale 1-tick-old tool snapshot for drops |
Small | ✅ Fixed |
| 8 | instance static field not cleared on disable |
Small | ✅ Fixed |
| 9 | BFS visited set unbounded on abnormally large ore clusters |
Small | ✅ Fixed |
Troubleshooting
Veinminer not activating:
- Check
enabled: truein config - Verify the ore is in
ore-types - Confirm you hold a pickaxe from
tool-whitelist - Check you are sneaking if
require-sneak: true - Verify the world is not blacklisted
Stats reset after restart:
- Check
plugins/BetterVeinminer/stats/is writable - Look for
"Failed to save stats"warnings in server logs
Daily limit resets on restart:
- Upgrade to v1.5.0 — daily usage is now persisted to
data.ymland restored on startup
Daily limit resets too early / not resetting at midnight:
- Ensure you are on v1.4.0+ — the old tick-based timer drifted and was skipped on restarts
- The system persists the last reset date to
data.ymland checks every 2 minutes
Cooldown message not showing:
- Upgrade to v1.5.0 — prior versions silently skipped cooldown feedback
Changelog
See CHANGELOG.md
License
Apache-2.0 © Duong2012G
Ченджлог
1.5.1Релиз1.21.9, 1.21.10, 1.21.11 · 3 июня 2026 г.
[1.5.1] — 2026-06-03
Fixed
[HIGH] Protection-plugin bypass — veinmine queued before WorldGuard/Lands/GriefPrevention could cancel the event —
onBlockBreaklistened atEventPriority.NORMAL. Protection plugins (WorldGuard, Lands, GriefPrevention, Residence) typically cancelBlockBreakEventatHIGHpriority, after NORMAL. When a player tried to break a protected ore, the protection plugin had not yet cancelled the event when BVM ran, soVeinmineTaskwas scheduled withrunTask(). One tick later, the task fired: the origin block was still intact (its break was cancelled), but all extra vein blocks within the protected region were broken without the player having any permission to do so. Changed toEventPriority.HIGHwithignoreCancelled = true. Protection plugins that act atNORMALorLOWstill cancel the event first; protection plugins atHIGHthat cancel before BVM now prevent the task from being queued entirely.[SMALL] BFS visited-cap
breakonly exited the inner faces loop, not the BFS while-loop — When thevisitedset reached thevisitedCap(maxBlocks × 4) sentinel, thebreakstatement inside thefor (int[] d : FACES)loop exited theforbody but left the outerwhile (!queue.isEmpty())loop running. The queue continued draining, processing each already-enqueued block and attempting to expand further neighbours on every poll (immediately re-hitting the cap check each time). For a world-gen-modded server with a very large ore deposit this was a redundant tight loop running every BFS iteration until the capped queue finally drained. Replaced with a Java labeled-break (break bfs) that exits the outer while-loop immediately when the cap is reached.[COSMETIC] Stale version comment in
config.yml— Header comment still readBetter Veinminer v1.2.0 — Configurationsince the file was not updated during the v1.4.0 or v1.5.0 releases. Updated tov1.5.1.
1.5.0Релиз1.21.9, 1.21.10, 1.21.11 · 22 мая 2026 г.
[1.5.0] — 2026-05-22
Fixed
[HIGH] Daily-limit counter not persisted — restart bypass —
dailyUsageTrackerexisted only in RAM. A server restart mid-day cleared the map to zero, allowing players who had already reached their daily cap to veinmine freely after any restart or plugin reload. The map is now saved todata.ymlvia the serialisedBVM-StatsIOexecutor on shutdown and on every daily reset. It is restored duringonEnable()before the reset check, so the data is properly cleared (not silently discarded) when a day boundary is crossed while the server was offline.[HIGH] Blocking file I/O from async timer thread —
saveLastResetDate()calledYamlConfiguration.save()directly on therunTaskTimerAsynchronouslythread, bypassing theBVM-StatsIOexecutor that serialises every other write in the plugin. This could race withonDisable()flushing the same file. The method is replaced bysaveDataYmlAsync(), which snapshots both the reset date and usage counters on the calling thread and submits the actual I/O to the existingBVM-StatsIOexecutor.[MEDIUM] Cooldown message with
{remaining}placeholder never sent — When a player triggered veinmine while still on cooldown, the listener silently returned without feedback. The config already declared acooldownmessage key with a{remaining}placeholder; it was simply never used. The remaining milliseconds are now calculated and the formatted message is sent to the player's action bar, matching the UX pattern of the success message.[MEDIUM] Permission priority non-deterministic — VIP+Premium received random limits —
getEffectiveCooldown()andgetEffectiveMaxBlocks()iteratedHashMapwhose entry order is not defined by Java. A player holding bothbetterveinminer.vipandbetterveinminer.premiumcould receive either tier's limits depending on hash collisions that vary between JVM instances and restarts. ThepermissionMaxBlocksandpermissionCooldownsmaps are nowLinkedHashMapinstances whose entries are inserted duringPluginConfig.reload()sorted bymax-blocksdescending. Iteration therefore always encounters the highest-privilege permission first.[MEDIUM] Daily counter incremented before veinmine task confirmed success —
dailyUsageTrackerwas incremented inonBlockBreak()beforeVeinmineTaskran. If theBetterVeinmineEventwas cancelled by another plugin, or all extra blocks were denied by protection plugins (extraCount == 0), the player lost one daily use without breaking anything. The increment is now deferred to insideVeinmineTask.run(), executed only afterextraCount > 0is confirmed.[MEDIUM] Cooldown cleanup evicted active entries for long per-ore cooldowns — The cleanup timer removed
cooldownsentries older thanconfig.getCooldownMs()(default 200 ms). If a per-ore cooldown (e.g.EMERALD_ORE: 1500) or a permission cooldown was longer than the base, an entry could be evicted while still within its own active window. The player's next break would findnullin the map and bypass the cooldown. The timer now callsconfig.getMaxConfiguredCooldown(), which returns the maximum of the base, all per-ore, and all permission cooldown values.[SMALL]
breakNaturally(tool)used stale 1-tick-old tool snapshot —VeinmineTaskcaptured the heldItemStackatBlockBreakEventtime and used it for everybreakNaturally()call one tick later. If a player legitimately swapped to a higher-Fortune pickaxe during that tick, all drops were calculated with the old tool's enchantments. The task now reads the item currently in the recorded slot at break time and falls back to the snapshot only if the slot is empty.[SMALL]
instancestatic field not cleared on disable —onDisable()did not setinstance = null. If a third-party plugin cached the return value ofBetterVeinminer.getInstance()and called it after the plugin was disabled (e.g. during/reload), it received a fully torn-down instance whosestatsManagerandconfigfields had already been discarded, potentially causing NPEs.instanceis now set tonullas the last action inonDisable().[SMALL] BFS
visitedset unbounded on abnormally large ore clusters — The BFS loop stopped adding totoBreakatmaxBlocks, but continued enqueuing and visiting neighbours until the queue drained. On a world-gen-modded server with a massive ore deposit,visitedcould accumulate tens of thousands of entries in a single tick. A hard cap ofmaxBlocks × 4entries is now enforced on thevisitedset; the loop breaks immediately when the cap is reached.
Changed
BetterVeinminer.onDisable()now flushesdata.yml(daily usage + reset date) viasaveDataYmlAsync()before callingstatsManager.shutdown(), ensuring all data is written to the serialised executor queue before the 5-second drain begins.StatsManager.getIoExecutor()added to expose the single-threaded executor to other components within the plugin.PluginConfig.getMaxConfiguredCooldown()added to return the longest cooldown value across all configuration sources.BetterVeinminer.getDailyUsageTracker()added to allowVeinmineTask(inner class) to increment the map after confirmed success, without requiring a public field.
1.4.0Релиз1.21.9, 1.21.10, 1.21.11 · 14 мая 2026 г.
[1.4.0] — 2026-05-14
Fixed
[CRITICAL] Async save race condition —
StatsManager.saveAll()was scheduled as an async task and readPlayerStatsfields directly while the main thread was still writing to them. A player could lose stats or receive a corrupted save file depending on thread timing. The auto-save timer now runs on the main thread to take a point-in-time snapshot via the newPlayerStats.copy(), then hands each snapshot to a single-threadedExecutorServicefor file I/O. The snapshot is fully consistent; the I/O thread never sees a half-written state.[CRITICAL] Concurrent YAML write corruption — The async auto-save timer and the
onQuitasync save could both be writing the same player's file simultaneously, producing a truncated or structurally invalid YAML file. All disk writes are now submitted to a single-threadedExecutorService(BVM-StatsIO). Only one write per file can be in progress at any time.StatsManager.shutdown()called fromonDisable()blocks up to 5 seconds to guarantee all pending writes complete before the plugin unloads.[CRITICAL] Daily reset based on server uptime, not real calendar date — The reset used
24 * 60 * 60 * 20Lticks (24 hours of server uptime). TPS lag caused the timer to drift, and a server restart before 24 hours elapsed reset the timer entirely, effectively disabling the daily limit. Replaced with aLocalDate.now()comparison: the last reset date is persisted toplugins/BetterVeinminer/data.ymland checked on startup (to catch any resets missed while the server was offline) and every 2 minutes (to detect midnight without requiring an exact timer).[HIGH] Cooldown cleanup removed entries too aggressively — The cleanup task that evicts stale entries from the
cooldownsmap used a hardcoded 60-second cutoff (System.currentTimeMillis() - 60_000L). If the configured cooldown exceeded 60 seconds, player entries were evicted while the cooldown was still active. On the next vein break the lookup returnednulland the cooldown was silently bypassed. The cutoff now usesconfig.getCooldownMs().[HIGH] Protection plugin bypass — Extra blocks in the vein were broken with
block.breakNaturally(tool)without first firing aBlockBreakEvent. WorldGuard, GriefPrevention, Lands, and Residence listen toBlockBreakEventto enforce region protection; because no event was fired, blocks in protected regions could be destroyed. ABlockBreakEventis now fired for each extra block before it is broken; if any listener cancels the event, that block is skipped.[HIGH] Missing anti-recursion guard — The protection-plugin fix above fires
BlockBreakEventprogrammatically, which caused the plugin's ownonBlockBreaklistener to trigger again for each block, scheduling a newVeinmineTaskper block and creating an infinite chain. AminingPlayersSet<UUID>marks any player whose veinmine session is currently active;onBlockBreakreturns immediately if the player's UUID is already present. The set is always cleared in afinallyblock to ensure a player can never be permanently locked out.[MEDIUM] 26-direction BFS linked separate nearby veins — The BFS scanned all 26 neighbours (3×3×3 cube), allowing diagonal connections to bridge two distinct ore veins that happened to be close together. Vanilla Minecraft generates ores using face-adjacent placement only, so diagonal connections are always false positives. Changed to 6-direction (face-adjacent) BFS. This also reduces the maximum queue size by up to 4×, improving TPS on large veins.
[MEDIUM] Unbreaking durability formula was deterministic, not vanilla-accurate — The old
calcDamage()computedMath.round(hits × multiplier × 1/(unbreaking+1))and clamped to a minimum of 1. Vanilla Minecraft independently rolls each hit: each has a1/(unbreaking+1)chance to actually apply damage. The clamped average could never produce 0 damage even with high Unbreaking levels and few hits.calcDamage()now performs a per-hit Bernoulli trial usingMath.random(), matching vanilla behaviour including the possibility of 0 damage.[MEDIUM]
PlayerStatsexposed public mutable fields — All four fields (blocksMined,totalOresCollected,currentTier,veinminesUsed) werepublic, allowing any code to set them to negative or overflowed values without validation. All fields are nowprivate. Setters clamp values to valid ranges (e.g. tier ≥ 1, counts ≥ 0). The newcopy()method supports safe async snapshotting.[MEDIUM] Config accepted invalid numeric values — Values such as
max-blocks: -1ordamage-multiplier: -100were loaded without validation, producing undefined behaviour (negative BFS limit, inverted durability, server lag). All numeric fields are now clamped on load:max-blocks→[1, 1000],cooldown-ms→[0, 300000],damage-multiplier→[0.1, 10.0],limit-per-day→[1, 100000],base-exp→[0, 10000].
Clarified (not a bug)
- Tool swap exploit (audit report #7) — The report described a tool-swap exploit
where a player could switch items during the 1-tick task delay to bypass restrictions.
This was already fixed in v1.2.1:
VeinmineTaskrecords the inventory slot and tool snapshot at event time, then re-validates withisSimilar()before applying durability. No change needed.
Changed
- Auto-save timer switched from
runTaskTimerAsynchronouslytorunTaskTimer(main thread) so snapshot collection is always synchronised with game state. The actual file I/O is still off the main thread via theBVM-StatsIOexecutor. onDisable()now callsstatsManager.shutdown()(blocking flush with 5 s timeout) instead ofsaveAll()directly, guaranteeing all pending I/O completes before the plugin unloads.
1.3.0Релиз1.21.9, 1.21.10, 1.21.11 · 25 апреля 2026 г.
[1.3.0] — 2026-04-25
Added
BetterVeinmineEvent— Custom cancellable Bukkit event fired just before extra blocks are broken. Other plugins can now:- Cancel the entire veinmine via
event.setCancelled(true) - Inspect the block list via
event.getBlocks()(unmodifiable) - Override the EXP reward via
event.setExpReward(int) - Read the ore type via
event.getOreType()
- Cancel the entire veinmine via
StatsManager— Full YAML persistence forPlayerStats. Stats are now saved toplugins/BetterVeinminer/stats/<uuid>.ymland survive server restarts.- Stats load synchronously on
PlayerJoinEvent(file is tiny, no noticeable delay) - Stats save asynchronously on
PlayerQuitEvent - Auto-save every 5 minutes (async) while the server is running
- Final synchronous flush in
onDisable()to guarantee no data loss on shutdown
- Stats load synchronously on
Fixed
- NullPointerException on missing config sections —
PluginConfig.reload()called.getKeys(false)directly on the return value ofgetConfigurationSection(...), which returnsnullwhen the section is absent fromconfig.yml. This caused an NPE crash on any server whereore-multipliers.multipliers,per-ore-cooldowns.cooldowns, orpermission-levelswere omitted or empty. All three sites now null-check the section before iterating. - Player-offline NPE in
VeinmineTask— The task is scheduled 1 tick after theBlockBreakEvent. If the player disconnects in that window (network drop, kick, crash), every subsequent field access on thePlayerobject threw aNullPointerException. Added an earlyif (!player.isOnline()) return;guard at the top ofrun(). {uses}placeholder never replaced in/bvm stats—showStats()built the message with{blocks}and{tier}substitutions but forgot{uses}, so the literal string{uses}was printed to the player.{blocks}placeholder never replaced in tier-up message — The tier-up message template"You reached Tier {tier}! New max blocks: {blocks}"only had{tier}replaced;{blocks}was left as-is in the output.sendActionBar(String)deprecated in Paper 1.21 — Replaced with the Adventure API:player.sendActionBar(LegacyComponentSerializer.legacySection().deserialize(msg)). This eliminates the deprecation warning in server logs and future-proofs the call.- Scheduler tasks not cancelled on disable —
onDisable()cleared data maps but never calledBukkit.getScheduler().cancelTasks(this). The cooldown-cleanup and daily-reset runnables could fire after the plugin was disabled (e.g. during/reload), accessing a partially torn-down plugin instance.cancelTasks(this)is now the first action inonDisable(), before any data is flushed or cleared.
Changed
onDisable()now cancels all plugin tasks before flushing data, then callsstatsManager.saveAll()as a final synchronous write to guarantee persistence.VeinmineTasknow collects extra blocks into aList<Block>(instead of iteratingSet<Block>with an origin equality check) to pass cleanly toBetterVeinmineEvent.- EXP calculation is now performed before the event is fired so listeners can read
and override the reward via
event.setExpReward(int).
1.2.2Релиз1.21.9, 1.21.10, 1.21.11 · 27 марта 2026 г.
fix bug
1.2.1Релиз1.21.9, 1.21.10, 1.21.11 · 16 марта 2026 г.
[1.2.1] — 2026-03-16
Fixed
- Critical Item Swap Bug — Fixed a bug where switching items during a veinmine task (0.05s delay) could overwrite a new item in the player's hand with the old tool, potentially causing item loss. The task now tracks the specific inventory slot and verifies the tool's identity before applying durability changes.
- UX Improvement — Success messages are now sent to the Action Bar instead of the chat to prevent spamming the chat history for active miners.
1.2.0Релиз1.21.9, 1.21.10, 1.21.11 · 14 марта 2026 г.
[1.2.0] — 2026-03-14
Added
- Tier System — Players automatically progress through 4 tiers as they mine more blocks:
- Tier 1: 32 max blocks (0 blocks mined)
- Tier 2: 64 max blocks (100k blocks mined)
- Tier 3: 128 max blocks (500k blocks mined)
- Tier 4: 256 max blocks (1M blocks mined)
- Player Statistics — Track blocks mined, veinmines used, and current tier
- New Commands:
/bvm statsand/bvm tierfor player progression tracking - Ore Multipliers — Configure different drop multipliers for different ore types (e.g., diamonds worth 1.5x)
- Per-Ore Cooldowns — Optional: Set different cooldown times per ore type
- Permission-based Limits — VIP (
betterveinminer.vip) and Premium (betterveinminer.premium) tiers - Daily Limits — Optional: Prevent abuse by limiting veinmines per player per day
- Advanced Effect Settings — Customizable particle types, colors, speeds, and sounds
- Custom Messages — Fully customizable player notifications with placeholders
- EXP Rewards — Optional custom experience points for veinmining
- PlayerStats.java — New data class for tracking individual player progress
Changed
- Version bumped to 1.2.0 with major feature expansion
- pom.xml — Fixed XML syntax errors (typo:
<n>→<n>) - PluginConfig.java — Expanded from ~90 lines to ~300+ lines with comprehensive settings
- BetterVeinminer.java — Refactored to support tier system, stats, permissions, and daily limits
- config.yml — Completely rewritten with organized sections for each feature
- plugin.yml — Added 3 new commands and 2 new permission levels
Improved
- Much better tier progression system that rewards dedicated miners
- More granular permission-based control for VIP/Premium players
- Enhanced logging and player feedback with customizable messages
- Better code organization with dedicated helper methods
1.1.2Релиз1.21.9, 1.21.10, 1.21.11 · 11 марта 2026 г.
fixed
Комментарии
Загружаем…