- add /pru playtime add
- add dutch locale
- add quotient option for requirements
This commit is contained in:
okx-code
2021-06-22 02:59:47 +01:00
parent 240b83f43f
commit 98a0dec122
11 changed files with 219 additions and 17 deletions
+1 -1
View File
@@ -5,7 +5,7 @@ plugins {
} }
group 'sh.okx' group 'sh.okx'
version '3.12' version '3.12.1'
java { java {
sourceCompatibility = JavaVersion.VERSION_1_8 sourceCompatibility = JavaVersion.VERSION_1_8
@@ -335,6 +335,7 @@ public class RankupPlugin extends JavaPlugin {
saveLocale("fr"); saveLocale("fr");
saveLocale("it"); saveLocale("it");
saveLocale("es"); saveLocale("es");
saveLocale("nl");
} }
private void saveLocale(String locale) { private void saveLocale(String locale) {
@@ -264,6 +264,39 @@ public class InfoCommand implements TabExecutor {
player.setStatistic(playOneTick, minutes * 20 * 60); player.setStatistic(playOneTick, minutes * 20 * 60);
player.sendMessage(ChatColor.LIGHT_PURPLE + "Updated playtime for " + player.getName() + " to " + minutes + " minutes"); player.sendMessage(ChatColor.LIGHT_PURPLE + "Updated playtime for " + player.getName() + " to " + minutes + " minutes");
return true; return true;
} else if (args[1].equalsIgnoreCase("add") && sender.hasPermission("rankup.playtime.set")) {
if (args.length < 4) {
sender.sendMessage(ChatColor.GREEN + "/" + label + " " + args[0] + " add <player> <minutes>" + ChatColor.YELLOW + " Increase the playtime statistic for a player");
return true;
}
Player player = Bukkit.getPlayer(args[2]);
if (player == null) {
sender.sendMessage(ChatColor.GRAY + "Player not found");
return true;
}
int minutes;
try {
minutes = Integer.parseInt(args[3]);
} catch (NumberFormatException e) {
sender.sendMessage(ChatColor.GRAY + "Invalid number: " + args[3]);
return true;
}
int oldMinutes = player.getStatistic(playOneTick) / 20 / 60;
if (minutes > 0) {
player.incrementStatistic(playOneTick, minutes * 20 * 60);
} else if (minutes < 0) {
if (oldMinutes + minutes < 0) {
player.sendMessage(ChatColor.GRAY + "Playtime cannot be negative");
return true;
}
player.decrementStatistic(playOneTick, -minutes * 20 * 60);
}
int newMinutes = oldMinutes + minutes;
player.sendMessage(ChatColor.LIGHT_PURPLE + "Increased playtime for " + player.getName() + " to " + oldMinutes + (minutes >= 0 ? "+" : "") + minutes + "=" + newMinutes + " minutes");
return true;
} }
} }
if (sender.hasPermission("rankup.playtime.get")) { if (sender.hasPermission("rankup.playtime.get")) {
@@ -275,13 +308,14 @@ public class InfoCommand implements TabExecutor {
sender.sendMessage( sender.sendMessage(
ChatColor.GREEN + "/" + label + " " + args[0] + " set <player> <minutes>" ChatColor.GREEN + "/" + label + " " + args[0] + " set <player> <minutes>"
+ ChatColor.YELLOW + " Update the playtime statistic for a player"); + ChatColor.YELLOW + " Update the playtime statistic for a player");
sender.sendMessage(
ChatColor.GREEN + "/" + label + " " + args[0] + " add <player> <minutes>"
+ ChatColor.YELLOW + " Increase the playtime statistic for a player");
} }
return true; return true;
} }
} }
// Set playtime & get playtime for other players?
PluginDescriptionFile description = plugin.getDescription(); PluginDescriptionFile description = plugin.getDescription();
String version = description.getVersion(); String version = description.getVersion();
sender.sendMessage( sender.sendMessage(
@@ -322,7 +356,7 @@ public class InfoCommand implements TabExecutor {
list.add("forceprestige"); list.add("forceprestige");
list.add("rankdown"); list.add("rankdown");
} }
if (sender.hasPermission("rankup.playtime")) { if (sender.hasPermission("rankup.playtime.get") || sender.hasPermission("rankup.playtime.set")) {
list.add("playtime"); list.add("playtime");
} }
return StringUtil.copyPartialMatches(args[0], list, new ArrayList<>()); return StringUtil.copyPartialMatches(args[0], list, new ArrayList<>());
@@ -333,6 +367,16 @@ public class InfoCommand implements TabExecutor {
return StringUtil.copyPartialMatches(args[1], players(), new ArrayList<>()); return StringUtil.copyPartialMatches(args[1], players(), new ArrayList<>());
} else if (args[0].equalsIgnoreCase("rankdown") && sender.hasPermission("rankup.force")) { } else if (args[0].equalsIgnoreCase("rankdown") && sender.hasPermission("rankup.force")) {
return StringUtil.copyPartialMatches(args[1], players(), new ArrayList<>()); return StringUtil.copyPartialMatches(args[1], players(), new ArrayList<>());
} else if (args[0].equalsIgnoreCase("playtime")) {
List<String> options = new ArrayList<>();
if (sender.hasPermission("rankup.playtime.get")) {
options.add("get");
}
if (sender.hasPermission("rankup.playtime.set")) {
options.add("set");
options.add("add");
}
return StringUtil.copyPartialMatches(args[1], options, new ArrayList<>());
} }
} }
return Collections.emptyList(); return Collections.emptyList();
@@ -33,10 +33,14 @@ public class RequirementContext {
return requirement.getName(); return requirement.getName();
} }
public double getPercent() { public double getQuotient() {
return getProgress() / getTotal(); return getProgress() / getTotal();
} }
public double getPercent() {
return getProgress() / getTotal() * 100;
}
public String toString() { public String toString() {
return "Requirement[" + requirement.getFullName() + "]"; return "Requirement[" + requirement.getFullName() + "]";
} }
@@ -49,7 +49,6 @@ public class RankupExpansion implements Expansion {
String[] parts = params.split("_", 5); String[] parts = params.split("_", 5);
return getPlaceholderRequirement(player, rankups.getRankByName(parts[2]), return getPlaceholderRequirement(player, rankups.getRankByName(parts[2]),
replacePattern(parts[3]), parts.length > 4 ? parts[4] : ""); replacePattern(parts[3]), parts.length > 4 ? parts[4] : "");
// return placeholders.getSimpleFormat().format(orElse(rankups.getByName(parts[2]).getRequirement(parts[3]), Requirement::getValueDouble, 0));
} else if (params.startsWith("rank_money_")) { } else if (params.startsWith("rank_money_")) {
String[] parts = params.split("_", 4); String[] parts = params.split("_", 4);
double amount = Objects.requireNonNull(rankups.getRankByName(parts[2]), "Rankup " + parts[2] + " does not exist").getRequirement(player, "money").getValueDouble(); double amount = Objects.requireNonNull(rankups.getRankByName(parts[2]), "Rankup " + parts[2] + " does not exist").getRequirement(player, "money").getValueDouble();
@@ -28,6 +28,8 @@ public class PlaceholderRequirement extends ProgressiveRequirement {
switch (parts[1]) { switch (parts[1]) {
case "=": case "=":
return parsed.equals(value) ? 1 : 0; return parsed.equals(value) ? 1 : 0;
case "!=":
return parsed.equals(value) ? 0 : 1;
} }
// numeric operations // numeric operations
@@ -35,15 +37,15 @@ public class PlaceholderRequirement extends ProgressiveRequirement {
double v = Double.parseDouble(value.replace(",", "")); double v = Double.parseDouble(value.replace(",", ""));
switch (parts[1]) { switch (parts[1]) {
case ">": case ">":
return p > v ? v : 0; return p > v ? 1 : 0;
case ">=": case ">=":
return Math.min(p, v); return Math.min(p, v);
case "<": case "<":
return p < v ? v : 0; return p < v ? 1 : 0;
case "<=": case "<=":
return p <= v ? 1 : 0; return p <= v ? 1 : 0;
case "==": case "==":
return p == v ? v : 0; return p == v ? 1 : 0;
} }
throw new IllegalArgumentException("Invalid operation: " + parts[1]); throw new IllegalArgumentException("Invalid operation: " + parts[1]);
} }
@@ -52,17 +54,19 @@ public class PlaceholderRequirement extends ProgressiveRequirement {
public double getTotal(Player player) { public double getTotal(Player player) {
String[] parts = getParts(player); String[] parts = getParts(player);
if (parts[1].equalsIgnoreCase("=")) { switch (parts[1]) {
return 1; case ">=":
} else {
return Double.parseDouble(parts[2]); return Double.parseDouble(parts[2]);
default:
return 1;
} }
} }
private String[] getParts(Player player) { private String[] getParts(Player player) {
String[] parts = getValueString().split(" "); String[] parts = getValueString().split(" ");
if (parts.length < 3) { if (parts.length < 3) {
throw new IllegalArgumentException("Placeholder requirements must be in the form %placeholder% <operation> string"); throw new IllegalArgumentException(
"Placeholder requirements must be in the form %placeholder% <operation> string");
} }
String parsed = PlaceholderAPI.setPlaceholders(player, parts[0]); String parsed = PlaceholderAPI.setPlaceholders(player, parts[0]);
if (!PlaceholderAPI.containsPlaceholders(parts[0]) || parsed.equals(parts[0])) { if (!PlaceholderAPI.containsPlaceholders(parts[0]) || parsed.equals(parts[0])) {
@@ -82,11 +82,11 @@ public class LegacyTextProcessor implements TextProcessor {
} else if (p.toLowerCase().startsWith("percent_done ")) { } else if (p.toLowerCase().startsWith("percent_done ")) {
String requirement = p.substring("percent_done ".length()); String requirement = p.substring("percent_done ".length());
return get("rank", p, o -> this.options.getPercentFormat() return get("rank", p, o -> this.options.getPercentFormat()
.format(((RankContext) o).getReq(requirement).getPercent() * 100)); .format(((RankContext) o).getReq(requirement).getPercent()));
} else if (p.toLowerCase().startsWith("percent_left ")) { } else if (p.toLowerCase().startsWith("percent_left ")) {
String requirement = p.substring("percent_left ".length()); String requirement = p.substring("percent_left ".length());
return get("rank", p, o -> this.options.getPercentFormat() return get("rank", p, o -> this.options.getPercentFormat()
.format(100 - ((RankContext) o).getReq(requirement).getPercent() * 100)); .format(100 - ((RankContext) o).getReq(requirement).getPercent()));
} }
return get(p, "{" + p + "}"); return get(p, "{" + p + "}");
+119
View File
@@ -0,0 +1,119 @@
# De berichten in deze afdeling kunnen worden aangepast voor elke Rankup in rankups.yml
rankup:
requirements-not-met: "&cJe hebt {{rank.requirement('money').total | simple }} geld nodig om te ranken."
no-rankup: "&eJe bent op de hoogste rang."
# Zet de string leeg, bijvoorbeeld: success-public: ""
# Om het bericht te verbergen.
success-public: "&a{{player}} &eis gerankt naar: &d{{next.rank}}"
success-private: "&aJe bent gerankt naar: &d{{next.rank}}"
# Gebruikt voor tekst bevestiging.
confirmation: |-
&eWeet je zeker dat je de volgende rang &a{{next.rank}} &ewilt?
&eType nogmaals &c/rankup &eom te bevestigen.
must-prestige: "&cJe moet prestigen om verder te ranken!"
gui:
rows: 1
title: "Rank naar {{next.rank}}"
rankup:
material: EMERALD_BLOCK
# "index" kan worden verdeeld tot groupen door spaties te gebruiken.
# Bijvoorbeeld: 0-3 9-12 18-21
# Je kan ook apparte getallen gebruiken in plaats van een bereik.
index: 0-3
name: '&a&lBevestigen'
# "lore" is optioneel.
lore: '&6Rank naar &b{{next.rank}}'
cancel:
material: REDSTONE_BLOCK
index: 5-8
name: '&c&lAnnuleren'
fill:
name: ' '
# Als je versies 1.8-1.12 gebruikt en je wilt dit veranderen,
# moet je <MATERIAL:data> gebruiken, bijvoorbeeld STAINED_GLASS_PANE:8
# Dit werkt voor zowel "rankup" als "cancel".
material: BLACK_STAINED_GLASS_PANE
ranksgui:
title: "Rangen"
rows: 3
offset: 10
width: 7
complete:
material: GREEN_STAINED_GLASS_PANE
name: "&aRang &7{{next.rank}} &a(compleet)"
current:
material: ORANGE_STAINED_GLASS_PANE
name: "&dRank naar &7{{next.rank}}"
incomplete:
material: RED_STAINED_GLASS_PANE
name: "&cRang &7{{next.rank}} &c(vereist hogere rang)"
fill:
material: BLACK_STAINED_GLASS_PANE
name: ' '
# Je kan (en waarschijnlijk moet) deze overschrijven in de rankups.yml.
# Om specifieke eisen te weergeven voor elke rang.
# Hoewel als je de "money" eis gebruikt, hoef je niet het bericht te veranderen voor elke rang. Je kan een combinatie gebruiken van:
# {{rank.requirement('money').total | simple}} {MONEY_NEEDED} {PERCENT_DONE <requirement>} {PERCENT_LEFT <requirement>} {AMOUNT <requirement>} {AMOUNT_NEEDED <requirement>}
# {{rank.requirement('money').total | simple}} en {MONEY_NEEDED} zijn anders dan {AMOUNT money} en {AMOUNT_NEEDED money} want ze gebruiken een verschillend formaat.
# Hier is een voorbeeld met alleen de "money" eis:
#list:
# complete: "&7{{rank.rank}} &8\xbb &7{{next.rank}} &evoor &7${{rank.requirement('money').total | simple}}"
# current: "&c{{rank.rank}} &e\xbb &c{{next.rank}} &evoor &a${{rank.requirement('money').total | simple}} &e{PERCENT_DONE money}%"
# incomplete: "&r{{rank.rank}} &e\xbb &r{{next.rank}} &evoor &a${{rank.requirement('money').total | simple}}"
list:
complete: "&7{{rank.rank}} &8\xbb &7{{next.rank}}"
current: "&c{{rank.rank}} &e\xbb &c{{next.rank}}"
incomplete: "&r{{rank.rank}} &e\xbb &r{{next.rank}}"
# Een lege string ("") schakelt het bericht uit.
header: ""
footer: ""
# Verzonden wanneer een speler probeert te ranken terwijl ze in cooldown zitten.
cooldown:
singular: "&cJe moet {{seconds_left}} seconde wachten om weer te ranken."
plural: "&cJe moet {{seconds_left}} secondes wachten om weer te ranken."
# Prestige berichten kunnen ook worden aangepast.
prestige:
requirements-not-met: "&cJe hebt {{rank.requirement('money').total | simple}} geld nodig om te prestigen."
no-prestige: "&eJe bent op de hoogste prestige."
success-public: "&a{{player}} &eis geprestiged naar: &d{{next.rank}}"
success-private: "&aJe bent geprestiged naar: &d{{next.rank}}"
confirmation: |-
&eWeet je zeker dat je wilt prestigen naar &a{{next.rank}}&e?
&eType nogmaals &c/prestige &eom te bevestigen.
gui:
title: "Prestige naar {{next.rank}}"
rankup:
material: GOLD_BLOCK
index: 0-3
name: '&a&lBevestigen'
lore: '&6Prestige naar &b{{next.rank}}'
cancel:
material: REDSTONE_BLOCK
index: 5-8
name: '&c&lAnnuleren'
fill:
name: ' '
# Als je versies 1.8-1.12 gebruikt en je wilt dit veranderen,
# moet je <MATERIAL:data> gebruiken, bijvoorbeeld STAINED_GLASS_PANE:8
# Dit werkt voor zowel "rankup" als "cancel".
material: BLACK_STAINED_GLASS_PANE
list:
complete: "&7{{rank.rank}} &8\xbb &7{{next.rank}}"
current: "&c{{rank.rank}} &e\xbb &c{{next.rank}}"
incomplete: "&r{{rank.rank}} &e\xbb &r{{next.rank}}"
header: ""
footer: ""
cooldown:
singular: "&cJe moet {{seconds_left}} seconde wachten om weer te prestigen."
plural: "&cJe moet {{seconds_left}} secondes wachten om weer te prestigen."
not-high-enough: "&cJe kan niet prestigen in jouw rang!"
not-in-ladder: "&cSorry, maar we konden geen rangen vinden voor de group(en) waar jij in zit. Gebruik /ranks om de lijst van rangen te weergeven."
invalid-rankup: "&cOngeldige rang gedefinieerd in de configuratie, check AUB het bedieningspaneel."
@@ -20,5 +20,6 @@ public class LegacyPlaceholderTest extends RankupTest {
plugin.getHelper().rankup(player); plugin.getHelper().rankup(player);
player.assertSaid("testPlayer A B A-display last rank 1,000 900 4 1 3 25 75"); player.assertSaid("testPlayer A B A-display last rank 1,000 900 4 1 3 25 75");
player.assertNoMoreSaid();
} }
} }
@@ -1,12 +1,19 @@
package sh.okx.rankup.messages; package sh.okx.rankup.messages;
import static org.junit.Assert.assertNotNull;
import be.seeseemelk.mockbukkit.entity.PlayerMock; import be.seeseemelk.mockbukkit.entity.PlayerMock;
import org.junit.Test; import org.junit.Test;
import sh.okx.rankup.RankupTest; import sh.okx.rankup.RankupTest;
public class RankupPlaceholderTest extends RankupTest { public class RankupPlaceholderTest extends RankupTest {
public RankupPlaceholderTest() {
super("placeholder");
}
@Test @Test
public void testSuccessPublicIsSame() { public void testReceivesSuccessMessages() {
PlayerMock player = server.addPlayer(); PlayerMock player = server.addPlayer();
PlayerMock receiver = server.addPlayer(); PlayerMock receiver = server.addPlayer();
@@ -20,5 +27,21 @@ public class RankupPlaceholderTest extends RankupTest {
// receiver does not receive success-private // receiver does not receive success-private
receiver.assertNoMoreSaid(); receiver.assertNoMoreSaid();
// player receives success-private and nothing else
assertNotNull(player.nextMessage());
player.assertNoMoreSaid();
}
@Test
public void testQuotientAndPercent() {
PlayerMock player = server.addPlayer();
plugin.getEconomy().setPlayer(player, 100);
groupProvider.addGroup(player.getUniqueId(), "A");
plugin.getHelper().rankup(player);
player.assertSaid("0.1 10");
} }
} }
@@ -0,0 +1,7 @@
A:
rank: 'A'
next: 'B'
requirements:
- 'money 1000'
rankup:
requirements-not-met: '{{rank.requirement("money").quotient | simple}} {{rank.requirement("money").percent | simple}}'