Skip to content

Commit 749c188

Browse files
WunderoWundero
Wundero
authored and
Wundero
committed
Some fixes + changes.
I'm going to push this as version 4.2 but I am still working on the @requires annotation (which will nicely fix the issues with statistics placeholders in SpongeAPI 5.2 by not letting people use that placeholder).
1 parent 91bfd07 commit 749c188

File tree

7 files changed

+185
-116
lines changed

7 files changed

+185
-116
lines changed

src/main/java/me/rojo8399/placeholderapi/PlaceholderService.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ public interface PlaceholderService {
5555
*
5656
* @return the expansion builder.
5757
*/
58-
public <S, O, V> ExpansionBuilder<S, O, V, ?> builder(Class<? extends S> source, Class<? extends O> observer,
59-
Class<? extends V> value);
58+
public <S, O, V> ExpansionBuilder<S, O, V, ? extends ExpansionBuilder<S, O, V, ?>> builder(
59+
Class<? extends S> source, Class<? extends O> observer, Class<? extends V> value);
6060

6161
/**
6262
* Fill a map with placeholders from a template.
@@ -110,7 +110,7 @@ public default Pattern getDefaultPattern() {
110110
*
111111
* @return the expansion builder.
112112
*/
113-
public ExpansionBuilder<?, ?, ?, ?> load(Object handle, String id, Object plugin);
113+
public ExpansionBuilder<?, ?, ?, ? extends ExpansionBuilder<?, ?, ?, ?>> load(Object handle, String id, Object plugin);
114114

115115
/**
116116
* Create new ExpansionBuilders for all methods annotated with '@Placeholder' in
@@ -136,7 +136,7 @@ public default Pattern getDefaultPattern() {
136136
* The plugin which holds the placeholders.
137137
* @return The list of builders matching the methods.
138138
*/
139-
public List<? extends ExpansionBuilder<?, ?, ?, ?>> loadAll(Object handle, Object plugin);
139+
public List<? extends ExpansionBuilder<?, ?, ?, ? extends ExpansionBuilder<?, ?, ?, ?>>> loadAll(Object handle, Object plugin);
140140

141141
/**
142142
* Parse a placeholder.

src/main/java/me/rojo8399/placeholderapi/Token.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,20 @@ of this software and associated documentation files (the "Software"), to deal
3030
import java.lang.annotation.Retention;
3131
import java.lang.annotation.Target;
3232

33-
@Documented
34-
@Retention(RUNTIME)
35-
@Target(PARAMETER)
3633
/**
3734
* This annotation denotes the token which will hold more intricate details
38-
* about the placeholders needed. Supported types: Optional<String>, String.
35+
* about the placeholders needed. The plugin will <b>TRY</b> to parse it into
36+
* the given type of the parameter, but there are no guarantees beyond the basic
37+
* primitives (and their box class), String and Optional<\String>.
3938
*/
39+
@Documented
40+
@Retention(RUNTIME)
41+
@Target(PARAMETER)
4042
public @interface Token {
4143

4244
/**
43-
* 'Fix' the input token to be more useful. This will call toLowerCase and trim
44-
* on the string value of the token. This does nothing if the token is optional.
45+
* 'Fix' the input token to be more useful. This will call toLowerCase on the
46+
* string value of the token. This does nothing if the token is optional.
4547
*
4648
* @return whether or not to fix the token
4749
*/

src/main/java/me/rojo8399/placeholderapi/impl/PlaceholderServiceImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ private PlaceholderServiceImpl() {
7676
* @see me.rojo8399.placeholderapi.PlaceholderService#builder()
7777
*/
7878
@Override
79-
public <S, O, V> ExpansionBuilder<S, O, V, ?> builder(Class<? extends S> s, Class<? extends O> o,
79+
public <S, O, V> ExpansionBuilder<S, O, V, ? extends ExpansionBuilder<S, O, V, ?>> builder(Class<? extends S> s, Class<? extends O> o,
8080
Class<? extends V> v) {
8181
return ExpansionBuilderImpl.builder(s, o, v);
8282
}

src/main/java/me/rojo8399/placeholderapi/impl/placeholder/Defaults.java

Lines changed: 52 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,7 @@ private void calculateBalTop(Currency cur) {
354354
List<UniqueAccount> baltop = new ArrayList<>();
355355
baltop = this.users.stream().map(u -> u.getUniqueId()).filter(service::hasAccount)
356356
.map(service::getOrCreateAccount).filter(Optional::isPresent).map(Optional::get)
357-
.sorted((a, b) -> a.getBalance(cur).compareTo(b.getBalance(cur))).collect(Collectors.toList());
357+
.sorted((a, b) -> -a.getBalance(cur).compareTo(b.getBalance(cur))).collect(Collectors.toList());
358358
balTop.put(cur, baltop);
359359
lastUpdate.put(cur, System.currentTimeMillis());
360360
}
@@ -422,76 +422,79 @@ public Object economy(@Token(fix = true) @Nullable String token, @Nullable @Sour
422422
String c = a[a.length - 1];
423423
if (currencies.containsKey(c)) {
424424
toUse = currencies.get(c);
425+
} else {
426+
t += "_" + c;
425427
}
426428
}
427429
final Currency toUseFinal = toUse;
428-
if (player == null) {
429-
// fix t for baltop
430-
int baltop = 0;
431-
if (t.startsWith("baltop")) {
432-
if (t.contains("_")) {
433-
String aft = t.substring(t.indexOf("_") + 1);
434-
t = t.substring(0, t.indexOf("_"));
435-
try {
436-
baltop = Integer.parseInt(aft);
437-
} catch (Exception e) {
438-
baltop = 5;
430+
// fix t for baltop
431+
int baltop = 0;
432+
if (t.startsWith("baltop")) {
433+
if (t.contains("_")) {
434+
String aft = t.substring(t.indexOf("_") + 1);
435+
t = t.substring(0, t.indexOf("_"));
436+
try {
437+
baltop = Integer.parseInt(aft);
438+
} catch (Exception e) {
439+
if (aft.contains("_")) {
440+
String cur = aft.split("_")[1];
441+
throw new NoValueException("That is not a valid currency!", currencies.keySet().stream()
442+
.filter(s -> TypeUtils.closeTo(cur, s)).collect(Collectors.toList()));
443+
} else {
444+
throw new NoValueException("That is not a valid currency!", currencies.keySet().stream()
445+
.filter(s -> TypeUtils.closeTo(aft, s)).collect(Collectors.toList()));
439446
}
440-
} else {
441-
baltop = 5;
442-
}
443-
if (baltop <= 0) {
444-
baltop = 1;
445-
}
446-
calculateBalTop(toUse);
447-
List<UniqueAccount> baltop2 = balTop.get(toUse).subList(0, baltop);
448-
if (t.startsWith("baltopf")) {
449-
return Text.joinWith(Text.of(", "), baltop2.stream()
450-
.map(a -> Text.of(a.getDisplayName(), ": " + toUseFinal.format(a.getBalance(toUseFinal))))
451-
.collect(Collectors.toList()));
452447
}
448+
} else {
449+
baltop = 5;
450+
}
451+
if (baltop <= 0) {
452+
baltop = 1;
453+
}
454+
calculateBalTop(toUse);
455+
List<UniqueAccount> baltop2 = balTop.get(toUse).stream().limit(baltop).collect(Collectors.toList());
456+
if (t.startsWith("baltopf")) {
453457
return Text.joinWith(Text.of(", "),
454-
baltop2.stream()
455-
.map(a -> Text.of(a.getDisplayName(), ": " + a.getBalance(toUseFinal).toPlainString()))
458+
baltop2.stream().map(
459+
a -> Text.of(a.getDisplayName(), ": " + toUseFinal.format(a.getBalance(toUseFinal))))
456460
.collect(Collectors.toList()));
457461
}
458-
switch (t) {
459-
case "display":
460-
return toUse.getDisplayName();
461-
case "plural_display":
462-
return toUse.getPluralDisplayName();
463-
case "symbol":
464-
return toUse.getSymbol();
465-
}
466-
if (currencies.containsKey(t)) {
467-
toUse = currencies.get(t);
468-
Text amt = toUse.format(BigDecimal.valueOf(1234.56));
469-
Text v = Text.of(toUse.getName() + " (" + toUse.getId() + ") - ");
470-
return v.concat(amt);
471-
}
472-
throw new NoValueException();
462+
return Text.joinWith(Text.of(", "),
463+
baltop2.stream()
464+
.map(a -> Text.of(a.getDisplayName(), ": " + a.getBalance(toUseFinal).toPlainString()))
465+
.collect(Collectors.toList()));
473466
}
474-
// Don't handle nonexistent accounts here, instead throw error
475-
UniqueAccount acc = service.getOrCreateAccount(player.getUniqueId()).get();
476467
switch (t) {
477-
case "balance":
478-
return acc.getBalance(toUse).toPlainString();
479-
case "bal_format":
480-
return toUse.format(acc.getBalance(toUse));
481468
case "display":
482469
return toUse.getDisplayName();
483470
case "plural_display":
484471
return toUse.getPluralDisplayName();
485472
case "symbol":
486473
return toUse.getSymbol();
487474
}
475+
if (player != null) {
476+
// Don't handle nonexistent accounts here, instead throw error
477+
UniqueAccount acc = service.getOrCreateAccount(player.getUniqueId()).get();
478+
switch (t) {
479+
case "balance":
480+
return acc.getBalance(toUse).toPlainString();
481+
case "bal_format":
482+
return toUse.format(acc.getBalance(toUse));
483+
}
484+
}
488485
if (currencies.containsKey(t)) {
489486
toUse = currencies.get(t);
490487
Text amt = toUse.format(BigDecimal.valueOf(1234.56));
491488
Text v = Text.of(toUse.getName() + " (" + toUse.getId() + ") - ");
492489
return v.concat(amt);
493490
}
494-
throw new NoValueException();
491+
if (t.contains("_")) {
492+
String[] arr = t.split("_");
493+
t = arr[arr.length - 1];
494+
}
495+
final String ft = t;
496+
throw new NoValueException("That is not a valid currency!",
497+
currencies.keySet().stream().filter(s -> TypeUtils.closeTo(ft, s)).collect(Collectors.toList()));
495498
}
496499

497500
private long getDowntimeMillis() {
@@ -931,6 +934,7 @@ public Text sound(@Nullable @Source Player p, @Token(fix = true) String identifi
931934
}
932935

933936
@Placeholder(id = "statistic")
937+
// @Requires(spongeVersion = "[6.0)")
934938
public Long stat(@Source Player player, @Token(fix = true) String t) {
935939
return player.getOrNull(Keys.STATISTICS).entrySet().stream().filter(e -> {
936940
String s = e.getKey().getId().replace("._", ".").toLowerCase();

src/main/java/me/rojo8399/placeholderapi/impl/placeholder/Expansion.java

Lines changed: 15 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ of this software and associated documentation files (the "Software"), to deal
2323
*/
2424
package me.rojo8399.placeholderapi.impl.placeholder;
2525

26-
import java.lang.reflect.Method;
2726
import java.lang.reflect.Type;
2827
import java.net.URL;
2928
import java.util.ArrayList;
@@ -68,15 +67,27 @@ private static final boolean verifySource(Class<?> param) {
6867
private String desc;
6968
private boolean enabled = true;
7069
private String id;
71-
private Class<? extends O> observerClass;
70+
private final Class<? extends O> observerClass;
7271
private Object plugin;
7372
private boolean relational = false;
7473
private Runnable reloadListeners;
75-
private Class<? extends S> sourceClass;
74+
private final Class<? extends S> sourceClass;
7675
private List<String> tokens;
7776
private URL url;
7877

79-
private Class<? extends V> valueClass;
78+
private final Class<? extends V> valueClass;
79+
80+
public Class<? extends V> getValueClass() {
81+
return valueClass;
82+
}
83+
84+
public Class<? extends S> getSourceClass() {
85+
return sourceClass;
86+
}
87+
88+
public Class<? extends O> getObserverClass() {
89+
return observerClass;
90+
}
8091

8192
private String ver;
8293

@@ -209,7 +220,6 @@ public Expansion(String id, Object plugin, String author, String desc, String ve
209220
this.valueClass = value;
210221
this.observerClass = observer;
211222
this.relational = relational;
212-
this.checkClasses();
213223
}
214224

215225
/**
@@ -244,21 +254,6 @@ public final String author() {
244254
return author;
245255
}
246256

247-
private final void checkClasses() {
248-
Class<? extends V> v = getValueClass();
249-
if (this.valueClass == null || !v.isAssignableFrom(this.valueClass)) {
250-
this.valueClass = v;
251-
}
252-
Class<? extends S> s = getSourceClass();
253-
if (this.sourceClass == null || !s.isAssignableFrom(this.sourceClass)) {
254-
this.sourceClass = s;
255-
}
256-
Class<? extends O> o = getObserverClass();
257-
if (this.observerClass == null || !o.isAssignableFrom(this.observerClass)) {
258-
this.observerClass = o;
259-
}
260-
}
261-
262257
/**
263258
* Attempt to cast an object to the Observer type. Returns null if it fails.
264259
*
@@ -331,39 +326,13 @@ public <T> T getConfiguration() {
331326
}
332327
}
333328

334-
/**
335-
* @return The class representing the observer type.
336-
*/
337-
@SuppressWarnings("unchecked")
338-
public final Class<? extends O> getObserverClass() {
339-
Method m = getParseMethod();
340-
return (Class<? extends O>) m.getParameterTypes()[1];
341-
}
342-
343-
private final Method getParseMethod() {
344-
Class<?> clazz = this.getClass();
345-
return Arrays.asList(clazz.getDeclaredMethods()).stream()
346-
.filter(m -> m.getName().equalsIgnoreCase("parse") && Arrays.asList(m.getGenericParameterTypes())
347-
.stream().map(Type::getTypeName).anyMatch(s -> s.contains("java.util.Optional")))
348-
.findAny().get(); // we know it exists ;)
349-
}
350-
351329
/**
352330
* @return The holding plugin.
353331
*/
354332
public Object getPlugin() {
355333
return plugin;
356334
}
357335

358-
/**
359-
* @return The class representing the source type.
360-
*/
361-
@SuppressWarnings("unchecked")
362-
public final Class<? extends S> getSourceClass() {
363-
Method m = getParseMethod();
364-
return (Class<? extends S>) m.getParameterTypes()[0];
365-
}
366-
367336
public List<String> getSuggestions(String token) {
368337
if (this.tokens.isEmpty()) {
369338
return new ArrayList<>();
@@ -374,15 +343,6 @@ public List<String> getSuggestions(String token) {
374343
return tokens.stream().filter(s -> TypeUtils.closeTo(s, token)).collect(Collectors.toList());
375344
}
376345

377-
/**
378-
* @return The class representing the return type.
379-
*/
380-
@SuppressWarnings("unchecked")
381-
public final Class<? extends V> getValueClass() {
382-
Method m = getParseMethod();
383-
return (Class<? extends V>) m.getReturnType();
384-
}
385-
386346
/**
387347
* @return The id of the expansion.
388348
*/

src/main/java/me/rojo8399/placeholderapi/impl/placeholder/ExpansionBuilderImpl.java

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ private static <S, O, V> ExpansionBuilderImpl<S, O, V> from(ExpansionBuilderImpl
7979
return (ExpansionBuilderImpl<S, O, V>) builder;
8080
}
8181
ExpansionBuilderImpl<?, ?, ?> b = builder;
82-
ExpansionBuilderImpl<S, O, V> n = unverified(exp.getSourceClass(), exp.getObserverClass(), exp.getValueClass());
82+
ExpansionBuilderImpl<S, O, V> n = unverified(src(exp, builder), obs(exp, builder), val(exp, builder));
8383
n.relational(b.relational).id(b.id).author(b.auth).description(b.desc).config(b.config).tokens(b.tokens)
8484
.version(b.ver);
8585
try {
@@ -96,6 +96,30 @@ private static <S, O, V> ExpansionBuilderImpl<S, O, V> from(ExpansionBuilderImpl
9696
return n;
9797
}
9898

99+
@SuppressWarnings("unchecked")
100+
private static <O> Class<? extends O> obs(Expansion<?, O, ?> e, ExpansionBuilderImpl<?, ?, ?> b) {
101+
if (e.getObserverClass() == null) {
102+
return (Class<? extends O>) b.getObserverClass();
103+
}
104+
return e.getObserverClass();
105+
}
106+
107+
@SuppressWarnings("unchecked")
108+
private static <V> Class<? extends V> val(Expansion<?, ?, V> e, ExpansionBuilderImpl<?, ?, ?> b) {
109+
if (e.getValueClass() == null) {
110+
return (Class<? extends V>) b.getValueClass();
111+
}
112+
return e.getValueClass();
113+
}
114+
115+
@SuppressWarnings("unchecked")
116+
private static <S> Class<? extends S> src(Expansion<S, ?, ?> e, ExpansionBuilderImpl<?, ?, ?> b) {
117+
if (e.getSourceClass() == null) {
118+
return (Class<? extends S>) b.getSourceClass();
119+
}
120+
return e.getSourceClass();
121+
}
122+
99123
private static ExpansionBuilderImpl<?, ?, ?> lfm(Object o, Method m, Object p, boolean rel) {
100124
Store s = Store.get();
101125
return unverified(s.getSourceType(m).orElse(Locatable.class), s.getObserverType(m).orElse(Locatable.class),
@@ -221,7 +245,9 @@ public Expansion<S, O, V> build() throws Exception {
221245
if (verify) {
222246
Preconditions.checkArgument(verify());
223247
}
224-
Expansion<S, O, V> exp = new Expansion<S, O, V>(id, plugin, auth, desc, ver, url, relational, tokens) {
248+
Expansion<S, O, V> exp = new Expansion<S, O, V>(id, plugin, auth, desc, ver,
249+
(url == null || url.isEmpty()) ? null : new URL(url), relational, tokens, this.sourceClass,
250+
this.observerClass, this.returnClass) {
225251
@Override
226252
public V parse(S source, O observer, Optional<String> token) throws Exception {
227253
return func.parse(source, observer, token);
@@ -241,6 +267,7 @@ public boolean reload() {
241267
PlaceholderAPIPlugin.getInstance().registerListeners(listeners, plugin);
242268
});
243269
}
270+
id = null;
244271
return exp;
245272
}
246273

0 commit comments

Comments
 (0)