Merge branch 'master' of github.com:mcMMO-Dev/mcMMO into configurable

This commit is contained in:
nossr50 2019-06-17 10:37:57 -07:00
commit 8b2d1eb1d8
19 changed files with 120 additions and 79 deletions

View File

@ -170,6 +170,18 @@ Version 2.2.0
Added API method to grab the level cap of a skill by its PrimarySkillType ENUM definition Added API method to grab the level cap of a skill by its PrimarySkillType ENUM definition
Added API method to check if a skill was being level capped Added API method to check if a skill was being level capped
Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill Added 'UndefinedSkillBehaviour' for trying to use a method that has no behaviour defined for the provided skill
Version 2.1.82
Added new WG flag 'mcmmo-hardcore' if set to negative players will not be penalized by hardcore mode (if hardcore mode is enabled) it defaults to true
Added proper error handling when loading parties file
Fixed an error that could occur when using mcrank on an offline player
You can now use mcrank on offline players by default
You can now use inspect on offline players by default
Removed the offline inspect/mcrank permissions
Updated Chinese locale (thanks to the user named 89009332 from github)
Added some redundancy checks when loading profiles (NPC checks to be specific)
NOTES:
There were reasons to prevent inspecting offline players in the past, I don't see any reason for them anymore so I've removed the restriction.
Version 2.1.81 Version 2.1.81
Fixed a bug where Arrow Deflect would never trigger outside of PVP Fixed a bug where Arrow Deflect would never trigger outside of PVP

View File

@ -35,9 +35,6 @@ public class InspectCommand implements TabExecutor {
return true; return true;
} }
if (CommandUtils.inspectOffline(sender, profile, Permissions.inspectOffline(sender))) {
return true;
}
if (mcMMO.getScoreboardSettings().getScoreboardsEnabled() && sender instanceof Player if (mcMMO.getScoreboardSettings().getScoreboardsEnabled() && sender instanceof Player
&& mcMMO.getScoreboardSettings().getConfigSectionScoreboardTypes().getConfigSectionInspectBoard().isUseThisBoard()) { && mcMMO.getScoreboardSettings().getConfigSectionScoreboardTypes().getConfigSectionInspectBoard().isUseThisBoard()) {

View File

@ -63,8 +63,6 @@ public class McrankCommand implements TabExecutor {
if (CommandUtils.tooFar(sender, player, Permissions.mcrankFar(sender))) { if (CommandUtils.tooFar(sender, player, Permissions.mcrankFar(sender))) {
return true; return true;
} }
} else if (CommandUtils.inspectOffline(sender, mcMMO.getDatabaseManager().loadPlayerProfile(playerName, false), Permissions.mcrankOffline(sender))) {
return true;
} }
display(sender, playerName); display(sender, playerName);

View File

@ -23,6 +23,7 @@ import com.gmail.nossr50.util.StringUtils;
import com.gmail.nossr50.util.skills.RankUtils; import com.gmail.nossr50.util.skills.RankUtils;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.bukkit.Color; import org.bukkit.Color;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.entity.Tameable; import org.bukkit.entity.Tameable;

View File

@ -306,7 +306,7 @@ public class EntityListener implements Listener {
} }
*/ */
if (Misc.isNPCEntity(defender) || !defender.isValid() || !(defender instanceof LivingEntity)) { if (Misc.isNPCEntityExcludingVillagers(defender) || !defender.isValid() || !(defender instanceof LivingEntity)) {
return; return;
} }
@ -316,7 +316,7 @@ public class EntityListener implements Listener {
return; return;
} }
if (Misc.isNPCEntity(attacker)) { if (Misc.isNPCEntityExcludingVillagers(attacker)) {
return; return;
} }
@ -440,7 +440,7 @@ public class EntityListener implements Listener {
} }
*/ */
if (Misc.isNPCEntity(entity) || !entity.isValid() || !(entity instanceof LivingEntity)) { if (Misc.isNPCEntityExcludingVillagers(entity) || !entity.isValid() || !(entity instanceof LivingEntity)) {
return; return;
} }
@ -570,7 +570,7 @@ public class EntityListener implements Listener {
LivingEntity entity = event.getEntity(); LivingEntity entity = event.getEntity();
if (Misc.isNPCEntity(entity)) { if (Misc.isNPCEntityExcludingVillagers(entity)) {
return; return;
} }
@ -602,7 +602,7 @@ public class EntityListener implements Listener {
LivingEntity entity = event.getEntity(); LivingEntity entity = event.getEntity();
if (Misc.isNPCEntity(entity)) { if (Misc.isNPCEntityExcludingVillagers(entity)) {
return; return;
} }
@ -885,7 +885,7 @@ public class EntityListener implements Listener {
LivingEntity entity = event.getEntity(); LivingEntity entity = event.getEntity();
if (!UserManager.hasPlayerDataKey(player) || Misc.isNPCEntity(entity) || entity.hasMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY)) { if (!UserManager.hasPlayerDataKey(player) || Misc.isNPCEntityExcludingVillagers(entity) || entity.hasMetadata(MetadataConstants.UNNATURAL_MOB_METAKEY)) {
return; return;
} }

View File

@ -511,10 +511,6 @@ public class PlayerListener implements Listener {
public void onPlayerJoin(PlayerJoinEvent event) { public void onPlayerJoin(PlayerJoinEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (Misc.isNPCEntity(player)) {
return;
}
//Delay loading for 3 seconds in case the player has a save task running, its hacky but it should do the trick //Delay loading for 3 seconds in case the player has a save task running, its hacky but it should do the trick
new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 60); new PlayerProfileLoadingTask(player).runTaskLaterAsynchronously(mcMMO.p, 60);
@ -840,7 +836,7 @@ public class PlayerListener implements Listener {
public void onPlayerChat(AsyncPlayerChatEvent event) { public void onPlayerChat(AsyncPlayerChatEvent event) {
Player player = event.getPlayer(); Player player = event.getPlayer();
if (Misc.isNPCEntity(player) || !UserManager.hasPlayerDataKey(player)) { if (Misc.isNPCEntityExcludingVillagers(player) || !UserManager.hasPlayerDataKey(player)) {
return; return;
} }

View File

@ -610,9 +610,11 @@ public final class PartyManager {
return; return;
}*/ }*/
YamlConfiguration partiesFile = YamlConfiguration.loadConfiguration(partyFile); try {
YamlConfiguration partiesFile;
partiesFile = YamlConfiguration.loadConfiguration(partyFile);
ArrayList<Party> hasAlly = new ArrayList<>(); ArrayList<Party> hasAlly = new ArrayList<Party>();
for (String partyName : partiesFile.getConfigurationSection("").getKeys(false)) { for (String partyName : partiesFile.getConfigurationSection("").getKeys(false)) {
Party party = new Party(partyName); Party party = new Party(partyName);
@ -644,11 +646,17 @@ public final class PartyManager {
parties.add(party); parties.add(party);
} }
mcMMO.p.debug("Loaded (" + parties.size() + ") Parties..."); mcMMO.p.debug("Loaded (" + parties.size() + ") Parties...");
for (Party party : hasAlly) { for (Party party : hasAlly) {
party.setAlly(PartyManager.getParty(partiesFile.getString(party.getName() + ".Ally"))); party.setAlly(PartyManager.getParty(partiesFile.getString(party.getName() + ".Ally")));
} }
} catch (Exception e) {
e.printStackTrace();
}
} }
/** /**

View File

@ -41,16 +41,16 @@ public class McrankCommandDisplayTask extends BukkitRunnable {
} }
private void displayChat() { private void displayChat() {
Player player = mcMMO.p.getServer().getPlayerExact(playerName); // Player player = mcMMO.p.getServer().getPlayerExact(playerName);
Integer rank; Integer rank;
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Heading")); sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Heading"));
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName)); sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Player", playerName));
for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) { for (PrimarySkillType skill : PrimarySkillType.NON_CHILD_SKILLS) {
if (!skill.getPermissions(player)) { // if (!skill.getPermissions(player)) {
continue; // continue;
} // }
rank = skills.get(skill); rank = skills.get(skill);
sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", skill.getName(), (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank))); sender.sendMessage(LocaleLoader.getString("Commands.mcrank.Skill", skill.getName(), (rank == null ? LocaleLoader.getString("Commands.mcrank.Unranked") : rank)));

View File

@ -29,6 +29,11 @@ public class PlayerProfileLoadingTask extends BukkitRunnable {
// DO NOT MODIFY THE McMMOPLAYER FROM THIS CODE // DO NOT MODIFY THE McMMOPLAYER FROM THIS CODE
@Override @Override
public void run() { public void run() {
if (Misc.isNPCIncludingVillagers(player)) {
return;
}
// Quit if they logged out // Quit if they logged out
if (!player.isOnline()) { if (!player.isOnline()) {
mcMMO.p.getLogger().info("Aborting profile loading recovery for " + player.getName() + " - player logged out"); mcMMO.p.getLogger().info("Aborting profile loading recovery for " + player.getName() + " - player logged out");

View File

@ -169,7 +169,7 @@ public class UnarmedManager extends SkillManager {
* @return true if the defender was not disarmed, false otherwise * @return true if the defender was not disarmed, false otherwise
*/ */
private boolean hasIronGrip(Player defender) { private boolean hasIronGrip(Player defender) {
if (!Misc.isNPCEntity(defender) && Permissions.isSubSkillEnabled(defender, SubSkillType.UNARMED_IRON_GRIP) if (!Misc.isNPCEntityExcludingVillagers(defender) && Permissions.isSubSkillEnabled(defender, SubSkillType.UNARMED_IRON_GRIP)
&& RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.UNARMED_IRON_GRIP, getPlayer())) { && RandomChanceUtil.isActivationSuccessful(SkillActivationType.RANDOM_LINEAR_100_SCALE_WITH_CAP, SubSkillType.UNARMED_IRON_GRIP, getPlayer())) {
mcMMO.getNotificationManager().sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Unarmed.Ability.IronGrip.Defender"); mcMMO.getNotificationManager().sendPlayerInformation(defender, NotificationType.SUBSKILL_MESSAGE, "Unarmed.Ability.IronGrip.Defender");
mcMMO.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Unarmed.Ability.IronGrip.Attacker"); mcMMO.getNotificationManager().sendPlayerInformation(getPlayer(), NotificationType.SUBSKILL_MESSAGE, "Unarmed.Ability.IronGrip.Attacker");

View File

@ -123,7 +123,7 @@ public class EventUtils {
Entity entity = entityDamageEvent.getEntity(); Entity entity = entityDamageEvent.getEntity();
//Check to make sure the entity is not an NPC //Check to make sure the entity is not an NPC
if (Misc.isNPCEntity(entity)) if(Misc.isNPCEntityExcludingVillagers(entity))
return false; return false;
if (!entity.isValid() || !(entity instanceof LivingEntity)) { if (!entity.isValid() || !(entity instanceof LivingEntity)) {

View File

@ -5,6 +5,8 @@ import com.gmail.nossr50.datatypes.player.PlayerProfile;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType; import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO; import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.player.UserManager; import com.gmail.nossr50.util.player.UserManager;
import com.gmail.nossr50.worldguard.WorldGuardManager;
import com.gmail.nossr50.worldguard.WorldGuardUtils;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.HashMap; import java.util.HashMap;
@ -14,6 +16,13 @@ public final class HardcoreManager {
} }
public static void invokeStatPenalty(Player player) { public static void invokeStatPenalty(Player player) {
if(WorldGuardUtils.isWorldGuardLoaded()) {
if(!WorldGuardManager.getInstance().hasHardcoreFlag(player)) {
return;
}
}
double statLossPercentage = mcMMO.getConfigManager().getConfigHardcore().getDeathPenalty().getPenaltyPercentage(); double statLossPercentage = mcMMO.getConfigManager().getConfigHardcore().getDeathPenalty().getPenaltyPercentage();
int levelThreshold = mcMMO.getConfigManager().getConfigHardcore().getDeathPenalty().getLevelThreshold(); int levelThreshold = mcMMO.getConfigManager().getConfigHardcore().getDeathPenalty().getLevelThreshold();
@ -59,6 +68,13 @@ public final class HardcoreManager {
} }
public static void invokeVampirism(Player killer, Player victim) { public static void invokeVampirism(Player killer, Player victim) {
if(WorldGuardUtils.isWorldGuardLoaded()) {
if(!WorldGuardManager.getInstance().hasHardcoreFlag(killer) || !WorldGuardManager.getInstance().hasHardcoreFlag(victim)) {
return;
}
}
double vampirismStatLeechPercentage = mcMMO.getConfigManager().getConfigHardcore().getVampirism().getPenaltyPercentage(); double vampirismStatLeechPercentage = mcMMO.getConfigManager().getConfigHardcore().getVampirism().getPenaltyPercentage();
int levelThreshold = mcMMO.getConfigManager().getConfigHardcore().getVampirism().getLevelThreshold(); int levelThreshold = mcMMO.getConfigManager().getConfigHardcore().getVampirism().getLevelThreshold();

View File

@ -37,13 +37,20 @@ public final class Misc {
private Misc() { private Misc() {
} }
public static boolean isNPCEntity(Entity entity) { public static boolean isNPCEntityExcludingVillagers(Entity entity) {
return (entity == null return (entity == null
|| (entity.hasMetadata("NPC") && !(entity instanceof Villager)) || (entity.hasMetadata("NPC") && !(entity instanceof Villager))
|| (entity instanceof NPC && !(entity instanceof Villager)) || (entity instanceof NPC && !(entity instanceof Villager))
|| entity.getClass().getName().equalsIgnoreCase("cofh.entity.PlayerFake")); || entity.getClass().getName().equalsIgnoreCase("cofh.entity.PlayerFake"));
} }
public static boolean isNPCIncludingVillagers(Player entity) {
return (entity == null
|| (entity.hasMetadata("NPC"))
|| (entity instanceof NPC)
|| entity.getClass().getName().equalsIgnoreCase("cofh.entity.PlayerFake"));
}
/** /**
* Determine if two locations are near each other. * Determine if two locations are near each other.
* *

View File

@ -34,19 +34,6 @@ public final class CommandUtils {
return true; return true;
} }
public static boolean inspectOffline(CommandSender sender, PlayerProfile profile, boolean hasPermission) {
if (unloadedProfile(sender, profile)) {
return true;
}
if (!hasPermission && !mcMMO.getConfigManager().getConfigCommands().isAllowInspectOnOfflinePlayers()) {
sender.sendMessage(LocaleLoader.getString("Inspect.Offline"));
return true;
}
return false;
}
public static boolean tooFar(CommandSender sender, Player target, boolean hasPermission) { public static boolean tooFar(CommandSender sender, Player target, boolean hasPermission) {
if (sender instanceof Player if (sender instanceof Player
&& mcMMO.getConfigManager().getConfigCommands().isLimitInspectRange() && mcMMO.getConfigManager().getConfigCommands().isLimitInspectRange()

View File

@ -240,7 +240,7 @@ public final class CombatUtils {
EntityType entityType = damager.getType(); EntityType entityType = damager.getType();
if (target instanceof Player) { if (target instanceof Player) {
if (Misc.isNPCEntity(target)) { if (Misc.isNPCEntityExcludingVillagers(target)) {
return; return;
} }
@ -325,7 +325,7 @@ public final class CombatUtils {
if (tamer instanceof Player && PrimarySkillType.TAMING.shouldProcess(target)) { if (tamer instanceof Player && PrimarySkillType.TAMING.shouldProcess(target)) {
Player master = (Player) tamer; Player master = (Player) tamer;
if (!Misc.isNPCEntity(master) && PrimarySkillType.TAMING.getPermissions(master)) { if (!Misc.isNPCEntityExcludingVillagers(master) && PrimarySkillType.TAMING.getPermissions(master)) {
processTamingCombat(target, master, wolf, event); processTamingCombat(target, master, wolf, event);
} }
} }
@ -336,11 +336,11 @@ public final class CombatUtils {
if (projectileSource instanceof Player && PrimarySkillType.ARCHERY.shouldProcess(target)) { if (projectileSource instanceof Player && PrimarySkillType.ARCHERY.shouldProcess(target)) {
Player player = (Player) projectileSource; Player player = (Player) projectileSource;
if (!Misc.isNPCEntity(player) && PrimarySkillType.ARCHERY.getPermissions(player)) { if (!Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.ARCHERY.getPermissions(player)) {
processArcheryCombat(target, player, event, arrow); processArcheryCombat(target, player, event, arrow);
} }
if (target.getType() != EntityType.CREEPER && !Misc.isNPCEntity(player) && PrimarySkillType.TAMING.getPermissions(player)) { if (target.getType() != EntityType.CREEPER && !Misc.isNPCEntityExcludingVillagers(player) && PrimarySkillType.TAMING.getPermissions(player)) {
McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player); McMMOPlayer mcMMOPlayer = UserManager.getPlayer(player);
TamingManager tamingManager = mcMMOPlayer.getTamingManager(); TamingManager tamingManager = mcMMOPlayer.getTamingManager();
tamingManager.attackTarget(target); tamingManager.attackTarget(target);
@ -508,7 +508,7 @@ public final class CombatUtils {
break; break;
} }
if (Misc.isNPCEntity(entity) || !(entity instanceof LivingEntity) || !shouldBeAffected(attacker, entity)) { if (Misc.isNPCEntityExcludingVillagers(entity) || !(entity instanceof LivingEntity) || !shouldBeAffected(attacker, entity)) {
continue; continue;
} }
@ -830,7 +830,7 @@ public final class CombatUtils {
Player player = (Player) attacker; Player player = (Player) attacker;
if (Misc.isNPCEntity(player) || Misc.isNPCEntity(target)) { if (Misc.isNPCEntityExcludingVillagers(player) || Misc.isNPCEntityExcludingVillagers(target)) {
return; return;
} }

View File

@ -6,4 +6,5 @@ public class WorldGuardFlags {
// StateFlag with the name "my-custom-flag", which defaults to "allow" // StateFlag with the name "my-custom-flag", which defaults to "allow"
public static final StateFlag MCMMO_ENABLE_WG_FLAG = new StateFlag("mcmmo", true); public static final StateFlag MCMMO_ENABLE_WG_FLAG = new StateFlag("mcmmo", true);
public static final StateFlag MCMMO_XP_WG_FLAG = new StateFlag("mcmmo-xp", true); public static final StateFlag MCMMO_XP_WG_FLAG = new StateFlag("mcmmo-xp", true);
public static final StateFlag MCMMO_HARDCORE_WG_FLAG = new StateFlag("mcmmo-hardcore", true);
} }

View File

@ -61,6 +61,23 @@ public class WorldGuardManager {
return query.testState(loc, WorldGuardPlugin.inst().wrapPlayer(player), WorldGuardFlags.MCMMO_XP_WG_FLAG); return query.testState(loc, WorldGuardPlugin.inst().wrapPlayer(player), WorldGuardFlags.MCMMO_XP_WG_FLAG);
} }
public boolean hasHardcoreFlag(Player player)
{
if(player == null)
return false;
BukkitPlayer localPlayer = BukkitAdapter.adapt(player);
com.sk89q.worldedit.util.Location loc = localPlayer.getLocation();
//WorldGuardPlugin worldGuard = getWorldGuard();
RegionContainer container = WorldGuard.getInstance().getPlatform().getRegionContainer();
RegionQuery query = container.createQuery();
//ApplicableRegionSet set = query.getApplicableRegions(loc);
return query.testState(loc, WorldGuardPlugin.inst().wrapPlayer(player), WorldGuardFlags.MCMMO_HARDCORE_WG_FLAG);
}
private WorldGuardPlugin getWorldGuard() { private WorldGuardPlugin getWorldGuard() {
Plugin plugin = getServer().getPluginManager().getPlugin("WorldGuard"); Plugin plugin = getServer().getPluginManager().getPlugin("WorldGuard");
@ -84,6 +101,7 @@ public class WorldGuardManager {
registry.register(WorldGuardFlags.MCMMO_XP_WG_FLAG);*/ registry.register(WorldGuardFlags.MCMMO_XP_WG_FLAG);*/
registry.register(WorldGuardFlags.MCMMO_ENABLE_WG_FLAG); registry.register(WorldGuardFlags.MCMMO_ENABLE_WG_FLAG);
registry.register(WorldGuardFlags.MCMMO_XP_WG_FLAG); registry.register(WorldGuardFlags.MCMMO_XP_WG_FLAG);
registry.register(WorldGuardFlags.MCMMO_HARDCORE_WG_FLAG);
System.out.println("mcMMO has registered WG flags successfully!"); System.out.println("mcMMO has registered WG flags successfully!");
} catch (FlagConflictException e) { } catch (FlagConflictException e) {
e.printStackTrace(); e.printStackTrace();

View File

@ -219,7 +219,7 @@ Excavation.Skills.GigaDrillBreaker.Refresh=[[GREEN]]\u4f60\u7684 [[YELLOW]]\u66b
Excavation.Skills.GigaDrillBreaker.Other.Off=\u66b4\u8d70\u94bb\u5934[[GREEN]] \u7ed3\u675f\u4e86,\u8fdb\u5165\u51b7\u5374 [[YELLOW]]{0} Excavation.Skills.GigaDrillBreaker.Other.Off=\u66b4\u8d70\u94bb\u5934[[GREEN]] \u7ed3\u675f\u4e86,\u8fdb\u5165\u51b7\u5374 [[YELLOW]]{0}
Excavation.Skills.GigaDrillBreaker.Other.On=[[GREEN]]{0}[[DARK_GREEN]] \u4f7f\u7528\u4e86 [[RED]]\u66b4\u8d70\u94bb\u5934! Excavation.Skills.GigaDrillBreaker.Other.On=[[GREEN]]{0}[[DARK_GREEN]] \u4f7f\u7528\u4e86 [[RED]]\u66b4\u8d70\u94bb\u5934!
#\u9493\u9c7c #\u9493\u9c7c
Fishing.Scarcity=[[YELLOW]]&o\u8be5\u533a\u57df\u5df2\u7ecf\u8fc7\u5ea6\u6355\u635e, \u8bf7\u6362\u4e00\u4e2a\u65b0\u533a\u57df\u518d\u5c1d\u8bd5. Fishing.ScarcityTip=[[YELLOW]]&o\u8be5\u533a\u57df\u5df2\u7ecf\u8fc7\u5ea6\u6355\u635e, \u8bf7\u6362\u4e00\u4e2a\u65b0\u533a\u57df\u518d\u5c1d\u8bd5,\u8bf7\u5230\u81f3\u5c11 {0} \u7684\u65b9\u5757\u4ee5\u5916.
Fishing.Scared=[[GRAY]]&o\u4e71\u52a8\u4f1a\u5413\u8dd1\u9c7c! Fishing.Scared=[[GRAY]]&o\u4e71\u52a8\u4f1a\u5413\u8dd1\u9c7c!
Fishing.Exhausting=[[RED]]&o\u4e0d\u6b63\u5f53\u4f7f\u7528\u9c7c\u7aff\u4f1a\u52a0\u5267\u8010\u4e45\u7684\u635f\u8017! Fishing.Exhausting=[[RED]]&o\u4e0d\u6b63\u5f53\u4f7f\u7528\u9c7c\u7aff\u4f1a\u52a0\u5267\u8010\u4e45\u7684\u635f\u8017!
Fishing.LowResources=[[GRAY]]\u4f60\u89c9\u5f97\u8fd9\u5757\u533a\u57df\u4f3c\u4e4e\u6ca1\u6709\u591a\u5c11\u9c7c\u4e86. Fishing.LowResources=[[GRAY]]\u4f60\u89c9\u5f97\u8fd9\u5757\u533a\u57df\u4f3c\u4e4e\u6ca1\u6709\u591a\u5c11\u9c7c\u4e86.
@ -365,6 +365,9 @@ Repair.Arcane.Perfect=[[GREEN]]\u4f60\u6210\u529f\u5730\u4fdd\u7559\u4e86\u8fd9\
Salvage.Pretty.Name=\u5206\u89e3 Salvage.Pretty.Name=\u5206\u89e3
Salvage.SubSkill.UnderstandingTheArt.Name=\u5206\u89e3\u7cbe\u901a Salvage.SubSkill.UnderstandingTheArt.Name=\u5206\u89e3\u7cbe\u901a
Salvage.SubSkill.UnderstandingTheArt.Description=\u4f60\u4e0d\u53ea\u662f\u518d\u7ffb\u90bb\u5c45\u7684\u5783\u573e, \u4f60\u662f\u5728\u4fdd\u62a4\u73af\u5883.\n\u589e\u5f3a\u5206\u89e3\u7684\u5404\u79cd\u5c5e\u6027. Salvage.SubSkill.UnderstandingTheArt.Description=\u4f60\u4e0d\u53ea\u662f\u518d\u7ffb\u90bb\u5c45\u7684\u5783\u573e, \u4f60\u662f\u5728\u4fdd\u62a4\u73af\u5883.\n\u589e\u5f3a\u5206\u89e3\u7684\u5404\u79cd\u5c5e\u6027.
Salvage.SubSkill.ScrapCollector.Name=\u5e9f\u6599\u56de\u6536
Salvage.SubSkill.ScrapCollector.Description=\u4ece\u7269\u54c1\u4e2d\u5206\u89e3\u51fa\u6750\u6599, \u5b8c\u7f8e\u5206\u89e3\u53d6\u51b3\u4e8e\u6280\u80fd\u548c\u8fd0\u6c14.
Salvage.SubSkill.ScrapCollector.Stat=\u5e9f\u6599\u56de\u6536: [[GREEN]]\u6700\u591a\u5206\u89e3\u51fa [[YELLOW]]{0}[[GREEN]] \u4e2a\u7269\u54c1. \u5360\u4e00\u4e9b\u8fd0\u6c14\u6210\u5206.
Salvage.SubSkill.AdvancedSalvage.Name=\u8fdb\u9636\u5206\u89e3 Salvage.SubSkill.AdvancedSalvage.Name=\u8fdb\u9636\u5206\u89e3
Salvage.SubSkill.AdvancedSalvage.Description=\u5206\u89e3\u635f\u574f\u7684\u7269\u54c1 Salvage.SubSkill.AdvancedSalvage.Description=\u5206\u89e3\u635f\u574f\u7684\u7269\u54c1
Salvage.SubSkill.ArcaneSalvage.Name=\u5965\u6570\u5206\u89e3 Salvage.SubSkill.ArcaneSalvage.Name=\u5965\u6570\u5206\u89e3

View File

@ -707,7 +707,6 @@ permissions:
mcmmo.bypass.hardcoremode: true mcmmo.bypass.hardcoremode: true
mcmmo.commands.inspect.far: true mcmmo.commands.inspect.far: true
mcmmo.commands.inspect.hidden: true mcmmo.commands.inspect.hidden: true
mcmmo.commands.inspect.offline: true
mcmmo.bypass.partylimit: mcmmo.bypass.partylimit:
default: false default: false
description: Allows user to bypass party size limitations if present on the server description: Allows user to bypass party size limitations if present on the server
@ -782,7 +781,6 @@ permissions:
mcmmo.commands.defaults: true mcmmo.commands.defaults: true
mcmmo.commands.inspect.far: true mcmmo.commands.inspect.far: true
mcmmo.commands.inspect.hidden: true mcmmo.commands.inspect.hidden: true
mcmmo.commands.inspect.offline: true
mcmmo.commands.mcability.others: true mcmmo.commands.mcability.others: true
mcmmo.commands.mcconvert.all: true mcmmo.commands.mcconvert.all: true
mcmmo.commands.mcchatspy: true mcmmo.commands.mcchatspy: true
@ -837,15 +835,12 @@ permissions:
mcmmo.commands.inspect: true mcmmo.commands.inspect: true
mcmmo.commands.inspect.far: true mcmmo.commands.inspect.far: true
mcmmo.commands.inspect.hidden: true mcmmo.commands.inspect.hidden: true
mcmmo.commands.inspect.offline: true
mcmmo.commands.inspect: mcmmo.commands.inspect:
description: Allows access to the inspect command description: Allows access to the inspect command
mcmmo.commands.inspect.far: mcmmo.commands.inspect.far:
description: Allows access to the inspect command for far players description: Allows access to the inspect command for far players
mcmmo.commands.inspect.hidden: mcmmo.commands.inspect.hidden:
description: Allows access to the inspect command for hidden players description: Allows access to the inspect command for hidden players
mcmmo.commands.inspect.offline:
description: Allows access to the inspect command for offline players
mcmmo.commands.mcability: mcmmo.commands.mcability:
description: Allows access to the mcability command description: Allows access to the mcability command
mcmmo.commands.mcability.others: mcmmo.commands.mcability.others:
@ -906,13 +901,10 @@ permissions:
children: children:
mcmmo.commands.mcrank.others: true mcmmo.commands.mcrank.others: true
mcmmo.commands.mcrank.others.far: true mcmmo.commands.mcrank.others.far: true
mcmmo.commands.mcrank.others.offline: true
mcmmo.commands.mcrank.others: mcmmo.commands.mcrank.others:
description: Allows access to the mcrank command for other players description: Allows access to the mcrank command for other players
mcmmo.commands.mcrank.others.far: mcmmo.commands.mcrank.others.far:
description: Allows access to the mcrank command for far players description: Allows access to the mcrank command for far players
mcmmo.commands.mcrank.others.offline:
description: Allows access to the mcrank command for offline players
mcmmo.commands.mcrefresh: mcmmo.commands.mcrefresh:
description: Allows access to the mcrefresh command description: Allows access to the mcrefresh command
mcmmo.commands.mcrefresh.others: mcmmo.commands.mcrefresh.others: