Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/main/java/com/gmail/nossr50/api/ExperienceAPI.java
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,7 @@ public static void removeXPOffline(UUID uuid, String skillType, int xp) {
* @throws InvalidFormulaTypeException if the given formulaType is not valid
*/
public static int getXpNeededToLevel(int level) {
return mcMMO.getFormulaManager()
return mcMMO.p.getFormulaManager()
.getXPtoNextLevel(level, ExperienceConfig.getInstance().getFormulaType());
}

Expand All @@ -1123,7 +1123,7 @@ public static int getXpNeededToLevel(int level) {
* @throws InvalidFormulaTypeException if the given formulaType is not valid
*/
public static int getXpNeededToLevel(int level, String formulaType) {
return mcMMO.getFormulaManager().getXPtoNextLevel(level, getFormulaType(formulaType));
return mcMMO.p.getFormulaManager().getXPtoNextLevel(level, getFormulaType(formulaType));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class ConvertExperienceCommand implements CommandExecutor {
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command command,
@NotNull String label, String[] args) {
if (args.length == 2) {
FormulaType previousType = mcMMO.getFormulaManager().getPreviousFormulaType();
FormulaType previousType = mcMMO.p.getFormulaManager().getPreviousFormulaType();
FormulaType newType = FormulaType.getFormulaType(args[1].toUpperCase(Locale.ENGLISH));

if (newType == FormulaType.UNKNOWN) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.gmail.nossr50.commands.levelup;

public interface CommandsOnLevel {
}
126 changes: 126 additions & 0 deletions src/main/java/com/gmail/nossr50/commands/levelup/LevelUpCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package com.gmail.nossr50.commands.levelup;

import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import java.util.LinkedList;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import org.bukkit.Bukkit;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.VisibleForTesting;

public class LevelUpCommand implements CommandsOnLevel {
private final @Nullable List<BiPredicate<PrimarySkillType, Integer>> conditions;
private final @Nullable Predicate<Integer> powerLevelCondition;
private final boolean logInfo;
private final @NotNull LinkedList<String> commands;

public LevelUpCommand(@Nullable List<BiPredicate<PrimarySkillType, Integer>> conditions,
@Nullable Predicate<Integer> powerLevelCondition,
@NotNull LinkedList<String> commands, boolean logInfo) {
this.conditions = conditions;
this.powerLevelCondition = powerLevelCondition;
if (conditions == null && powerLevelCondition == null) {
throw new IllegalArgumentException("At least one condition must be set");
}
this.commands = commands;
this.logInfo = logInfo;
}

public void process(@NotNull McMMOPlayer player, @NotNull PrimarySkillType primarySkillType,
@NotNull Set<Integer> levelsGained,
@NotNull Set<Integer> powerLevelsGained) {
// each predicate has to pass at least once
// we check the predicates against all levels gained to see if they pass at least once
// if all predicates pass at least once, we execute the command
boolean allConditionsPass = (conditions == null) || conditions.stream().allMatch(
predicate -> levelsGained.stream()
.anyMatch(level -> predicate.test(primarySkillType, level)));
// we also check the power level predicate to see if it passes at least once, if this predicate is null, we mark it as passed
boolean powerLevelConditionPass =
(powerLevelCondition == null) || powerLevelsGained.stream()
.anyMatch(powerLevelCondition);
if (allConditionsPass && powerLevelConditionPass) {
executeCommand(player);
}
}

@VisibleForTesting
void executeCommand(@NotNull McMMOPlayer player) {
LogUtils.debug(mcMMO.p.getLogger(), "Executing level up commands: " + commands);
for (String command : commands) {
LogUtils.debug(mcMMO.p.getLogger(), "Executing command: " + command);
String injectedCommand = injectedCommand(command, player);
if (!injectedCommand.equalsIgnoreCase(command)) {
LogUtils.debug(mcMMO.p.getLogger(),
("Command has been injected with new values: " + injectedCommand));
}
Bukkit.dispatchCommand(Bukkit.getConsoleSender(), injectedCommand);
}
}

@VisibleForTesting
String injectedCommand(String command, McMMOPlayer player) {
// TODO: unit tests
StringBuilder commandBuilder = new StringBuilder(command);

// Replace %player% with player name
replaceAll(commandBuilder, "{@player}", player.getPlayer().getName());

// Replace each skill level
for (PrimarySkillType primarySkillType : PrimarySkillType.values()) {
if (primarySkillType == PrimarySkillType.SMELTING
|| primarySkillType == PrimarySkillType.SALVAGE) {
continue;
}
replaceAll(commandBuilder, "{@" + primarySkillType.name().toLowerCase() + "_level}",
String.valueOf(player.getSkillLevel(primarySkillType)));
}

// Replace power level
replaceAll(commandBuilder, "{@power_level}", String.valueOf(player.getPowerLevel()));

return commandBuilder.toString();
}

private void replaceAll(StringBuilder builder, String from, String to) {
int index = builder.indexOf(from);
while (index != -1) {
builder.replace(index, index + from.length(), to);
index = builder.indexOf(from, index + to.length());
}
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LevelUpCommand that = (LevelUpCommand) o;
return logInfo == that.logInfo && Objects.equals(conditions, that.conditions)
&& Objects.equals(commands, that.commands);
}

@Override
public int hashCode() {
return Objects.hash(conditions, logInfo, commands);
}

@Override
public String toString() {
return "SkillLevelUpCommand{" +
"conditions=" + conditions +
", logInfo=" + logInfo +
", commands=" + commands +
'}';
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package com.gmail.nossr50.commands.levelup;

import static java.util.Objects.requireNonNull;

import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Predicate;
import org.jetbrains.annotations.NotNull;

public class LevelUpCommandBuilder {
private LinkedList<String> commands = null;
private List<BiPredicate<PrimarySkillType, Integer>> conditions = null;
private Predicate<Integer> powerLevelCondition = null;
private boolean logInfo;

public LevelUpCommandBuilder() {
this.logInfo = false;
}

public LevelUpCommandBuilder withPredicate(BiPredicate<PrimarySkillType, Integer> condition) {
if (this.conditions == null) {
this.conditions = new LinkedList<>();
}

conditions.add(condition);
return this;
}

public LevelUpCommandBuilder withPowerLevelCondition(Predicate<Integer> powerLevelCondition) {
if (this.powerLevelCondition != null) {
throw new IllegalStateException("power level condition already set");
}

this.powerLevelCondition = powerLevelCondition;
return this;
}

public LevelUpCommandBuilder withConditions(
@NotNull Collection<BiPredicate<PrimarySkillType, Integer>> conditions) {
if (this.conditions == null) {
this.conditions = new LinkedList<>();
} else {
throw new IllegalStateException("conditions already set");
}

this.conditions.addAll(conditions);
return this;
}

public LevelUpCommandBuilder withLogInfo(boolean logInfo) {
this.logInfo = logInfo;
return this;
}

public LevelUpCommandBuilder command(@NotNull String command) {
this.commands = new LinkedList<>();
this.commands.add(command);
return this;
}

public LevelUpCommandBuilder commands(@NotNull Collection<String> command) {
this.commands = new LinkedList<>(command);
return this;
}

public LevelUpCommand build() {
if (conditions == null && powerLevelCondition == null) {
throw new IllegalStateException("no conditions found for level up command");
}
requireNonNull(commands, "no commands found for level up command");

return new LevelUpCommand(conditions, powerLevelCondition, commands, logInfo);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package com.gmail.nossr50.commands.levelup;

import static java.util.Objects.requireNonNull;

import com.gmail.nossr50.datatypes.player.McMMOPlayer;
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
import com.gmail.nossr50.mcMMO;
import com.gmail.nossr50.util.LogUtils;
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
import org.jetbrains.annotations.NotNull;

/**
* Manages commands to be executed on level up
*/
public class LevelUpCommandManager {
private final @NotNull Set<LevelUpCommand> levelUpCommands;
private final @NotNull mcMMO plugin;

public LevelUpCommandManager(@NotNull mcMMO plugin) {
this.plugin = requireNonNull(plugin, "plugin cannot be null");
this.levelUpCommands = new HashSet<>();
}

public void registerCommand(@NotNull LevelUpCommand levelUpCommand) {
requireNonNull(levelUpCommand, "skillLevelUpCommand cannot be null");
levelUpCommands.add(levelUpCommand);
LogUtils.debug(mcMMO.p.getLogger(),
"Registered level up command - SkillLevelUpCommand: " + levelUpCommand);
}

/**
* Apply the level up commands to the player
*
* @param mmoPlayer the player
* @param primarySkillType the skill type
* @param levelsGained the levels gained
*/
public void applySkillLevelUp(@NotNull McMMOPlayer mmoPlayer,
@NotNull PrimarySkillType primarySkillType,
Set<Integer> levelsGained, Set<Integer> powerLevelsGained) {
if (!mmoPlayer.getPlayer().isOnline()) {
return;
}

for (LevelUpCommand command : levelUpCommands) {
command.process(mmoPlayer, primarySkillType, levelsGained, powerLevelsGained);
}
}

public @NotNull Set<LevelUpCommand> getLevelUpCommands() {
return levelUpCommands;
}

/**
* Clear all registered commands
*/
public void clear() {
mcMMO.p.getLogger().info("Clearing registered commands on level up");
levelUpCommands.clear();
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
LevelUpCommandManager that = (LevelUpCommandManager) o;
return Objects.equals(levelUpCommands, that.levelUpCommands) && Objects.equals(plugin,
that.plugin);
}

@Override
public int hashCode() {
return Objects.hash(levelUpCommands, plugin);
}

@Override
public String toString() {
return "LevelUpCommandManager{" +
"levelUpCommands=" + levelUpCommands +
", plugin=" + plugin +
'}';
}
}
Loading