Stop console spam when other plugins check skill names through the API

Unmatched skill name lookups logged an 'Invalid mcMMO skill' warning on
every call, so plugins validating names through ExperienceAPI flooded the
console. The message is now debug output shown only with Verbose_Logging.
This commit is contained in:
nossr50
2026-07-10 23:48:01 -07:00
parent ce2ae27ae1
commit 2b85a6fc72
3 changed files with 43 additions and 2 deletions

View File

@ -57,6 +57,7 @@ Version 2.3.000
Fixed an error when another plugin fires a fish catch carrying a non-item entity
Fixed an error when adding levels to Salvage or Smelting (See notes)
Fixed an error when another plugin reads raw skill XP for Salvage or Smelting
Fixed 'Invalid mcMMO skill' console spam when other plugins check skill names through the API (See notes)
Fixed an error when reading XP requirements for offline players while 'Experience_Formula.Cumulative_Curve' is enabled
Fixed a memory leak from Call of the Wild summons that died before their duration ended
Fixed an error when players below 11 HP used a Chimaera Wing underground
@ -135,6 +136,9 @@ Version 2.3.000
-- Level change events --
Only matters on servers running plugins that cancel mcMMO level change events. A cancelled /mmoedit change could reset the skill to level 0 or the wrong level instead of restoring the old one, and cancelling a change for a player whose data was not loaded threw an error; mcMMO now logs a warning instead.
-- Invalid skill name messages --
Skill name lookups that do not match any skill (usually other plugins validating names through the API, but also command typos) no longer print an 'Invalid mcMMO skill' warning to the console. The message is now debug output, visible by enabling 'General.Verbose_Logging' in config.yml.
-- Potions --
REGENERATION potion entries and their long/strong variants in potions.yml, treasures.yml, and fishing_treasures.yml could fail to load. Old names like REGEN still convert correctly, no config changes are needed.

View File

@ -7,6 +7,7 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.datatypes.skills.ToolType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import com.gmail.nossr50.util.Permissions;
import com.gmail.nossr50.util.text.StringUtils;
import com.google.common.collect.ImmutableList;
@ -380,8 +381,9 @@ public class SkillTools {
}
if (!skillName.equalsIgnoreCase("all")) {
pluginRef.getLogger()
.warning("Invalid mcMMO skill (" + skillName + ")"); // TODO: Localize
// Debug rather than warning: other plugins probe arbitrary names through the API
// (ExperienceAPI.isValidSkillType and friends), which must stay quiet on console
LogUtils.debug(pluginRef.getLogger(), "Invalid mcMMO skill (" + skillName + ")");
}
return null;

View File

@ -3,7 +3,10 @@ package com.gmail.nossr50.util.skills;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import com.gmail.nossr50.config.GeneralConfig;
@ -13,6 +16,7 @@ import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
import com.gmail.nossr50.datatypes.skills.ToolType;
import com.gmail.nossr50.locale.LocaleLoader;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import com.gmail.nossr50.util.platform.MinecraftGameVersion;
import java.util.ArrayList;
import java.util.Arrays;
@ -348,6 +352,37 @@ class SkillToolsTest {
assertThat(names).isEqualTo(sorted);
}
// ------------------------------------------------------------------------
// matchSkill logging behavior
// ------------------------------------------------------------------------
/**
* Other plugins validate arbitrary strings through the API (ExperienceAPI.isValidSkillType
* and friends), which lands in matchSkill. A non-matching name must not write to the
* console at default log levels, otherwise API users spam server logs on every lookup.
* Debug-prefixed output is fine; LogFilter hides it unless Verbose_Logging is enabled.
*/
@Test
void matchSkillShouldStayQuietOnConsoleWhenNameDoesNotMatch() throws Exception {
// Given - a SkillTools and a plugin logger we can observe
SkillTools skillTools = newSkillToolsForVersion(1, 21, 11);
Logger observedLogger = mock(Logger.class);
when(mcMMO.p.getLogger()).thenReturn(observedLogger);
try {
// When - an unknown skill name is looked up, as API validation does
PrimarySkillType match = skillTools.matchSkill("notARealSkill");
// Then - no skill matches and nothing reaches the console at default levels
assertThat(match).isNull();
verify(observedLogger, never()).warning(anyString());
verify(observedLogger, never()).info(argThat((String message) ->
!message.startsWith(LogUtils.DEBUG_STR)));
} finally {
when(mcMMO.p.getLogger()).thenReturn(logger);
}
}
/**
* The list feeds tab completion across commands, where lowercase suggestions read like
* the other completion keywords instead of shouting the en_US all-caps skill names.