Skip to content

Commit 7411066

Browse files
committed
Merge branch 'master' into commandsonlevelup
# Conflicts: # Changelog.txt
2 parents ea8a5a0 + bc1bcb8 commit 7411066

65 files changed

Lines changed: 4453 additions & 168 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

Changelog.txt

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,95 @@
11
Version 2.2.055
2+
Fixed Berserk reducing damage instead of boosting it on Paper 26.1.2+ (See notes)
3+
Fixed Disarm, Rupture, Cripple, Momentum, Critical Strikes, Armor Impact, and Greater Impact activating far less often than intended on Paper 26.1.2+ (See notes)
4+
Fixed Skull Splitter dealing far less AoE damage than intended on Paper 26.1.2+ (See notes)
25
Added scoreboard support for Folia servers (Thanks albert4719) (See notes)
36
Fixed the 'mcmmo.perks.xp.25percentboost' permission and its per-skill child nodes not being registered (See notes)
47
Fixed Maces Cripple playing an extra anvil break sound that could not be disabled in sounds.yml (See notes)
58
Fixed Super Breaker and Tree Feller mishandling durability on items with a custom max_damage component (See notes)
69
Fixed Tree Feller ignoring durability damage changes made by other plugins via PlayerItemDamageEvent
10+
Fixed Acrobatics Dodge exploit prevention never limiting Dodge XP from a single mob (See notes)
11+
Fixed 'ExploitFix.Combat.XPCeiling.Damage_Limit' in experience.yml being ignored (See notes)
12+
Fixed Salvage giving nothing back for damaged items that salvage into a single material (See notes)
13+
Fixed Salvage and Repair confirmations being able to act on a different item than the one prompted (See notes)
14+
Fixed armor sometimes being equipped instead of salvaged when right-clicking a salvage anvil
15+
Fixed scoreboards for Salvage and Smelting not updating until the skill command was used again
16+
Fixed power level tags being able to get stuck showing 0 under player names (See notes)
17+
Fixed the stats scoreboard including skills hidden by missing permissions in its power level
18+
Fixed localized skill commands being blocked by command whitelist plugins (See notes)
19+
Fixed 'Database_Purging.Old_User_Cutoff' never purging inactive users (See notes)
20+
Fixed purging powerless users removing comment lines from the flatfile database
21+
Fixed inspect scoreboards not refreshing when the inspected player levels up
22+
Fixed the Leaf Blower and Catalysis guides in the en_US locale showing wrong unlock levels
23+
Added 'Feedback.ActionBarNotifications.SubSkillUnlocked.SendToActionBar' to advanced.yml, an opt-in to show skill rank unlock messages on the action bar (See notes)
24+
Fixed /inspect not checking permissions when used on offline players (See notes)
725
Improved performance when players gain skill XP (See notes)
826
Improved performance when taking smelted items out of furnaces (See notes)
927
Added support for running commands when players reach chosen skill levels or power levels (See notes)
1028
Added new config file levelupcommands.yml to set up level up commands (See notes)
29+
Added /mclevelupsound command for players to toggle the level-up sound (See notes)
30+
Added decimal XP rate support to /xprate, rates like 1.5 now work
31+
Added a no-argument /xprate that shows the current XP rate to the sender (See notes)
32+
Added 'ExploitFix.AcrobaticsDodgeXpFarming' to experience.yml (See notes)
33+
Added 'Skills.Mining.BlastMining.RemoteDetonationDistance' to advanced.yml (See notes)
34+
Added 'mcmmo.commands.mclevelupsound' permission node
35+
Added 'mcmmo.commands.xprate.show' permission node
36+
Removed the unused Leaf Blower Rank_2 and Rank_3 entries from skillranks.yml
37+
Added locale entries 'Commands.xprate.current', 'Commands.xprate.invalid', 'Commands.LevelUpSound.On', 'Commands.LevelUpSound.Off', and 'Commands.Description.mclevelupsound'
38+
Updated locale entries 'Commands.xprate.proper.0' and 'Commands.Description.xprate' for the /xprate changes
1139
(API) Added LevelUpCommandAPI so other plugins can register level up commands or their own callbacks and unregister them later (See notes)
1240
(API) McMMOScoreboardObjectiveEvent is only fired on non-Folia servers (See notes)
41+
(API) Skill rank unlock notifications now fire McMMOPlayerNotificationEvent like other notification types
1342
(Codebase) Added scoreboard-library 2.8.0 as a shaded dependency for the packet-based scoreboard implementation
1443
(Codebase) Added ViaVersion to plugin.yml softdepend
1544
(Codebase) Added unit tests covering the power level cap and skill level cap checks
45+
(Codebase) Added regression tests covering previously fixed bugs
1646

1747
NOTES:
48+
-- Combat abilities on Paper 26.1.2+ --
49+
Paper 26.1.2 changed when the attack cooldown ticker resets during melee hits, which made the cooldown API report roughly zero while mcMMO was processing a hit. Version 2.2.053 fixed most damage bonuses, but several effects still read the cooldown directly and were silently crippled: Berserk actively reduced damage (its +50% bonus math turned negative), Skull Splitter dealt roughly a tenth of its intended AoE damage, and the on-hit activation odds for Disarm, Rupture (including Serrated Strikes), Cripple, Momentum, Critical Strikes, Armor Impact, and Greater Impact were scaled down to roughly a tenth of their configured rates. All of these now use the attack strength derived from the damage event itself. No config changes required.
50+
(API) UnarmedManager#berserkDamage/disarmCheck, AxesManager#criticalHit/impactCheck/greaterImpact/skullSplitterCheck, SwordsManager#processRupture/serratedStrikes, MacesManager#processCripple, SpearsManager#potentiallyApplyMomentum, CombatUtils#applyAbilityAoE, and McMMOPlayer#getAttackStrength are deprecated in favor of overloads that take an attack strength scale.
51+
52+
-- Scoreboards and power level tags --
1853
Scoreboards on Folia (and Folia forks like Canvas) now use a packet-based implementation, since the Bukkit scoreboard API is not safe to use there. Paper and Spigot servers keep the existing Bukkit scoreboard implementation and are unaffected.
1954
If a Folia server runs a newer Minecraft version than this mcMMO build supports for packet scoreboards (currently the 26.2.x line), scoreboards are disabled with a startup warning until mcMMO updates.
2055
(API) The packet-based implementation still fires McMMOScoreboardMakeboardEvent and McMMOScoreboardRevertEvent, but there is no Bukkit Objective on Folia so McMMOScoreboardObjectiveEvent is not fired there.
56+
Power level tags could get stuck showing 0 for players whose data was still loading. Servers that ran older builds with 'Power_Level_Tags' enabled could also have an old power level display saved in world data that kept showing stale numbers; leftovers are now cleaned up automatically on startup. On Minecraft 26.1 clients the power level can still render on holograms and pets due to a client bug that Mojang fixed in 26.2.
57+
58+
-- Salvage and Repair --
59+
Items that only salvage into a single material (such as wooden shovels with the default salvage.vanilla.yml) previously could not be salvaged at all unless they were at full durability. Damaged items now always return at least one material unless the item is completely broken.
60+
The Salvage/Repair confirm click now has to be made with the same item that triggered the prompt; if the held item changes during the confirmation window you get a new prompt instead of the new item being instantly salvaged or repaired. While a confirmation is pending the prompted item also can't be used, which stops vanilla armor quick-swap from equipping or swapping armor mid-confirmation.
61+
62+
-- XP and exploit fixes --
2163
The mcmmo.perks.xp.25percentboost permission family now behaves like the 10, 50, and 150 percent variants; previously only mcmmo.perks.xp.25percentboost.all had any effect.
22-
Gaining XP now does much less repeated work per gain, which reduces mcMMO's share of server thread time on busy servers; no behavior or config changes are involved.
23-
Taking smelted items out of a furnace no longer searches the full server recipe list every time.
64+
Dodge XP farming prevention now has its own 'ExploitFix.AcrobaticsDodgeXpFarming' setting in experience.yml; it is enabled by default and existing config files do not need to be updated. A single mob stops handing out Dodge XP after a handful of dodges, and the limit clears once that mob has gone about a minute without being dodged. 'ExploitFix.Acrobatics' continues to control the Roll anti-exploit checks.
65+
'ExploitFix.Combat.XPCeiling.Damage_Limit' in experience.yml now works; before this fix the combat XP damage ceiling was always 100 no matter what the config said. Servers that customized this value will see it take effect after updating, no config changes are needed.
66+
67+
-- Commands --
68+
Localized skill commands (for example /faustkampf for /unarmed on a German locale) are now handed to other plugins in a way that lets command whitelist and command blocking plugins see the command exactly as the player typed it. If you use such a plugin, whitelist the localized command name.
69+
Using /inspect on offline players now requires the 'mcmmo.commands.inspect.far' permission, the same node that gates inspecting far away players. If non-op players on your server relied on inspecting offline players, grant them that node.
70+
The /mclevelupsound toggle (alias /levelupsound) only affects the level-up sound, not level-up messages. Like /mcnotify, the toggle lasts until the player logs out.
71+
/xprate without arguments shows the current XP rate. Players get this through the new 'mcmmo.commands.xprate.show' node, which is granted by default since the rate is already broadcast at event start and shown on join.
72+
73+
-- Sounds and abilities --
2474
Cripple now plays a single sound which can be adjusted or disabled with the CRIPPLE entry in sounds.yml.
2575
Items with a custom maximum durability (set through the max_damage item component by data packs or item plugins) previously could make super abilities stop working or appear to restore durability; ability durability loss now always uses the item's own maximum.
76+
77+
-- Level up commands --
2678
Level up commands are configured in the new levelupcommands.yml file; each entry lists the commands to run plus a trigger, either skills with levels or power_levels, and an optional run_as of CONSOLE (default) or PLAYER. The shipped example entries are disabled by default.
2779
Level up commands support placeholders: {@player}, {@skill}, {@level}, {@power_level}, and current-level placeholders like {@mining_level}. Commands run once per milestone reached, even when several levels are gained at once.
2880
(API) LevelUpCommandAPI registrations return an id that can be used to unregister them later; registrations made by other plugins survive mcMMO config reloads.
2981

82+
-- Config --
83+
Skill rank unlock messages can now be shown on the action bar by setting 'Feedback.ActionBarNotifications.SubSkillUnlocked.SendToActionBar' to true in advanced.yml, with 'SendCopyOfMessageToChat' deciding whether the chat still gets a copy. This is a deliberate opt-in and nothing changes unless you enable it; unlock messages stay in chat by default. Unlike the other action bar sections this one is controlled by 'SendToActionBar' instead of 'Enabled', because configs from older versions already contain 'Enabled: true' for SubSkillUnlocked from back when the setting had no effect; that key is ignored for this section so updating cannot silently change behavior. advanced.yml auto-updates on startup, so the new key is added automatically.
84+
'Skills.Mining.BlastMining.RemoteDetonationDistance' in advanced.yml controls how far away Blast Mining can remotely detonate TNT. It defaults to 100, which matches the old fixed distance, and advanced.yml auto-updates on startup so no manual config changes are needed.
85+
86+
-- Database --
87+
'Database_Purging.Old_User_Cutoff' now actually removes inactive users on both FlatFile and SQL databases. If you have purging enabled, expect the first purge after updating to remove old users that should have been purged before. Users whose last login can't be determined are kept.
88+
89+
-- Performance --
90+
Gaining XP now does much less repeated work per gain, which reduces mcMMO's share of server thread time on busy servers; no behavior or config changes are involved.
91+
Taking smelted items out of a furnace no longer searches the full server recipe list every time.
92+
3093
Version 2.2.054
3194
Added compatibility for new blocks and items from Chaos Cubed (Minecraft 26.2) to mcMMO
3295
Fixed party/admin chat allowing players to use color codes without the 'mcmmo.chat.colors' permission
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
package com.gmail.nossr50.commands;
2+
3+
import com.gmail.nossr50.datatypes.player.McMMOPlayer;
4+
import com.gmail.nossr50.locale.LocaleLoader;
5+
import com.gmail.nossr50.util.commands.CommandUtils;
6+
import com.gmail.nossr50.util.player.UserManager;
7+
import com.google.common.collect.ImmutableList;
8+
import java.util.List;
9+
import org.bukkit.command.Command;
10+
import org.bukkit.command.CommandSender;
11+
import org.bukkit.command.TabExecutor;
12+
import org.bukkit.entity.Player;
13+
import org.jetbrains.annotations.NotNull;
14+
15+
public class McLevelUpSoundCommand implements TabExecutor {
16+
@Override
17+
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command,
18+
@NotNull String label, String[] args) {
19+
if (CommandUtils.noConsoleUsage(sender)) {
20+
return true;
21+
}
22+
23+
if (args.length == 0) {
24+
final McMMOPlayer mmoPlayer = UserManager.getPlayer((Player) sender);
25+
26+
//Not Loaded yet
27+
if (mmoPlayer == null) {
28+
sender.sendMessage(LocaleLoader.getString("Profile.PendingLoad"));
29+
return true;
30+
}
31+
32+
sender.sendMessage(LocaleLoader.getString(
33+
"Commands.LevelUpSound." + (mmoPlayer.useLevelUpSounds() ? "Off" : "On")));
34+
mmoPlayer.toggleLevelUpSounds();
35+
return true;
36+
}
37+
return false;
38+
}
39+
40+
@Override
41+
public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Command command,
42+
@NotNull String alias, String[] args) {
43+
return ImmutableList.of();
44+
}
45+
}

src/main/java/com/gmail/nossr50/commands/XprateCommand.java

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,11 @@
99
import com.gmail.nossr50.util.player.NotificationManager;
1010
import com.gmail.nossr50.util.text.StringUtils;
1111
import com.google.common.collect.ImmutableList;
12+
import java.text.DecimalFormat;
13+
import java.text.DecimalFormatSymbols;
1214
import java.util.ArrayList;
1315
import java.util.List;
16+
import java.util.Locale;
1417
import org.bukkit.ChatColor;
1518
import org.bukkit.command.Command;
1619
import org.bukkit.command.CommandSender;
@@ -19,13 +22,37 @@
1922
import org.jetbrains.annotations.NotNull;
2023

2124
public class XprateCommand implements TabExecutor {
25+
// Matches how MessageFormat renders doubles in locale strings: no trailing ".0" on
26+
// whole numbers, grouping separators, up to three decimal places
27+
private static final String XP_RATE_FORMAT_PATTERN = "#,##0.###";
28+
2229
private final double ORIGINAL_XP_RATE = ExperienceConfig.getInstance()
2330
.getExperienceGainsGlobalMultiplier();
2431

32+
/**
33+
* Formats an XP rate for display. Creates a new format per call because DecimalFormat is
34+
* not thread safe and regionized servers run player commands on multiple threads.
35+
*/
36+
static String formatXpRate(double xpRate) {
37+
return new DecimalFormat(XP_RATE_FORMAT_PATTERN,
38+
DecimalFormatSymbols.getInstance(Locale.US)).format(xpRate);
39+
}
40+
2541
@Override
2642
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command,
2743
@NotNull String label, String[] args) {
2844
switch (args.length) {
45+
case 0:
46+
if (!Permissions.xprateShow(sender)) {
47+
sender.sendMessage(command.getPermissionMessage());
48+
return true;
49+
}
50+
51+
sender.sendMessage(LocaleLoader.getString("Commands.xprate.current",
52+
formatXpRate(ExperienceConfig.getInstance()
53+
.getExperienceGainsGlobalMultiplier())));
54+
return true;
55+
2956
case 1:
3057
if (!args[0].equalsIgnoreCase("reset") && !args[0].equalsIgnoreCase("clear")) {
3158
return false;
@@ -63,7 +90,7 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
6390
return true;
6491

6592
case 2:
66-
if (CommandUtils.isInvalidInteger(sender, args[0])) {
93+
if (CommandUtils.isInvalidDouble(sender, args[0])) {
6794
return true;
6895
}
6996

@@ -72,6 +99,20 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
7299
return true;
73100
}
74101

102+
final double newXpRate = Double.parseDouble(args[0]);
103+
104+
if (newXpRate < 0) {
105+
sender.sendMessage(
106+
ChatColor.RED + LocaleLoader.getString("Commands.NegativeNumberWarn"));
107+
return true;
108+
}
109+
110+
if (newXpRate == 0 || !Double.isFinite(newXpRate)) {
111+
sender.sendMessage(
112+
ChatColor.RED + LocaleLoader.getString("Commands.xprate.invalid"));
113+
return true;
114+
}
115+
75116
if (CommandUtils.shouldDisableToggle(args[1])) {
76117
mcMMO.p.setXPEventEnabled(false);
77118
} else if (CommandUtils.shouldEnableToggle(args[1])) {
@@ -80,33 +121,27 @@ public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command
80121
return false;
81122
}
82123

83-
int newXpRate = Integer.parseInt(args[0]);
84-
85-
if (newXpRate < 0) {
86-
sender.sendMessage(
87-
ChatColor.RED + LocaleLoader.getString("Commands.NegativeNumberWarn"));
88-
return true;
89-
}
90-
91124
ExperienceConfig.getInstance().setExperienceGainsGlobalMultiplier(newXpRate);
92125

126+
final String displayRate = formatXpRate(newXpRate);
127+
93128
if (mcMMO.p.getAdvancedConfig().useTitlesForXPEvent()) {
94129
NotificationManager.broadcastTitle(mcMMO.p.getServer(),
95130
LocaleLoader.getString("Commands.Event.Start"),
96-
LocaleLoader.getString("Commands.Event.XP", newXpRate),
131+
LocaleLoader.getString("Commands.Event.XP", displayRate),
97132
10, 10 * 20, 20);
98133
}
99134

100135
if (mcMMO.p.getGeneralConfig().broadcastEventMessages()) {
101136
mcMMO.p.getServer()
102137
.broadcastMessage(LocaleLoader.getString("Commands.Event.Start"));
103138
mcMMO.p.getServer().broadcastMessage(
104-
LocaleLoader.getString("Commands.Event.XP", newXpRate));
139+
LocaleLoader.getString("Commands.Event.XP", displayRate));
105140
}
106141

107142
//Admin notification
108143
NotificationManager.processSensitiveCommandNotification(sender,
109-
SensitiveCommandType.XPRATE_MODIFY, String.valueOf(newXpRate));
144+
SensitiveCommandType.XPRATE_MODIFY, displayRate);
110145

111146
return true;
112147

@@ -120,7 +155,7 @@ public List<String> onTabComplete(@NotNull CommandSender sender, @NotNull Comman
120155
@NotNull String alias, String[] args) {
121156
switch (args.length) {
122157
case 1:
123-
if (StringUtils.isInt(args[0])) {
158+
if (StringUtils.isDouble(args[0])) {
124159
return ImmutableList.of();
125160
}
126161

0 commit comments

Comments
 (0)