Compare commits

..
96 Commits
Author SHA1 Message Date
Adrian 998828138b release: Version 2.2.1 2023-07-19 16:37:35 -05:00
Adrian 638acd9e88 fix(build): Fixed some deprecations 2023-07-19 16:13:53 -05:00
Adrian 5c0850dbdd Merge pull request #109 from MiniPlaceholders/renovate/fabric.api
fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.86.0+1.20.1
2023-07-19 15:01:03 -05:00
renovate[bot] 8a5415c37d fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.86.0+1.20.1 2023-07-18 23:04:47 +00:00
Adrian b5c6afa368 Merge pull request #105 from MiniPlaceholders/renovate/gradle-8.x
chore(deps): update dependency gradle to v8.2.1
2023-07-17 22:34:18 -05:00
Adrian 4bcf85d718 Merge pull request #107 from MiniPlaceholders/renovate/major-krypton
fix(deps): update krypton to v7796647145 (major)
2023-07-17 22:31:13 -05:00
Adrian 548187238e feat: Add more Legacy API parsing 2023-07-17 17:02:31 -05:00
Adrian c7845cec0b fix: Fixed legacy chars replacement in LegacyUtils 2023-07-17 16:07:05 -05:00
Adrian ab3316bcf1 Merge pull request #108 from MiniPlaceholders/renovate/adventurefabric
fix(deps): update dependency net.kyori:adventure-platform-fabric to v5.9.0
2023-07-16 22:48:08 -05:00
renovate[bot] 33b09e85d7 fix(deps): update dependency net.kyori:adventure-platform-fabric to v5.9.0 2023-07-16 22:42:49 +00:00
Adrian 4b6110aa2b Merge pull request #106 from MiniPlaceholders/renovate/org.gradle.toolchains.foojay-resolver-convention-0.x
chore(deps): update plugin org.gradle.toolchains.foojay-resolver-convention to v0.6.0
2023-07-15 15:34:33 -05:00
renovate[bot] e404a158e7 fix(deps): update krypton 2023-07-12 00:05:10 +00:00
renovate[bot] 981901271c chore(deps): update plugin org.gradle.toolchains.foojay-resolver-convention to v0.6.0 2023-07-10 14:06:18 +00:00
renovate[bot] 3f93840e5a chore(deps): update dependency gradle to v8.2.1 2023-07-10 14:06:14 +00:00
Adrian 4d5e45e9eb Merge pull request #102 from MiniPlaceholders/renovate/fabric-loom-1.x
chore(deps): update plugin fabric-loom to v1.3.8
2023-07-10 09:00:56 -05:00
Adrian be8e6d268e Merge pull request #103 from MiniPlaceholders/renovate/indra
fix(deps): update indra to v3.1.2
2023-07-10 09:00:48 -05:00
Adrian b89799ff75 Merge pull request #104 from MiniPlaceholders/renovate/kotlin-monorepo
fix(deps): update kotlin monorepo to v1.9.0
2023-07-08 14:55:11 -05:00
renovate[bot] 10cb91ac56 chore(deps): update plugin fabric-loom to v1.3.8 2023-07-06 16:18:47 +00:00
renovate[bot] b7d190ce7f fix(deps): update kotlin monorepo to v1.9.0 2023-07-06 07:41:06 +00:00
renovate[bot] e028a3bada fix(deps): update indra to v3.1.2 2023-07-06 04:31:53 +00:00
Adrian f339248ad3 Merge pull request #101 from MiniPlaceholders/renovate/fabric.api
fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.85.0+1.20.1
2023-07-04 07:15:33 -05:00
Adrian b8a6f9b746 Merge pull request #100 from MiniPlaceholders/renovate/fabric-loom-1.x
chore(deps): update plugin fabric-loom to v1.3.5
2023-07-04 07:15:24 -05:00
renovate[bot] 3d45362241 fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.85.0+1.20.1 2023-07-03 22:53:35 +00:00
renovate[bot] 859047762c chore(deps): update plugin fabric-loom to v1.3.5 2023-07-03 18:53:44 +00:00
Adrian 63a95961f8 Merge pull request #99 from MiniPlaceholders/renovate/fabric-loom-1.x
chore(deps): update plugin fabric-loom to v1.3.4
2023-07-03 11:30:10 -05:00
renovate[bot] f3c5540d15 chore(deps): update plugin fabric-loom to v1.3.4 2023-07-02 22:48:18 +00:00
Adrian fcbf2e9454 Merge pull request #98 from MiniPlaceholders/renovate/gradle-8.x
chore(deps): update dependency gradle to v8.2
2023-06-30 13:53:48 -05:00
renovate[bot] ae993a34e0 chore(deps): update dependency gradle to v8.2 2023-06-30 18:39:15 +00:00
Adrian eba9aa8e0e Merge pull request #97 from MiniPlaceholders/renovate/fabric-loom-1.x
chore(deps): update plugin fabric-loom to v1.3.2
2023-06-27 20:22:50 -05:00
renovate[bot] 04b86d4a56 chore(deps): update plugin fabric-loom to v1.3.2 2023-06-27 22:13:13 +00:00
Adrian 53402d3c1d Merge pull request #95 from MiniPlaceholders/renovate/pluginyml
chore(deps): update dependency net.minecrell.plugin-yml.bukkit to v0.6.0
2023-06-27 12:31:09 -05:00
Adrian 7634c37ad4 Merge pull request #93 from MiniPlaceholders/renovate/fabric.api
fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.84.0+1.20.1
2023-06-27 12:31:00 -05:00
Adrian 26125abef2 Merge pull request #94 from MiniPlaceholders/renovate/fabric-loom-1.x
chore(deps): update plugin fabric-loom to v1.2.7
2023-06-27 12:30:53 -05:00
Adrian 93182688e2 Merge pull request #92 from MiniPlaceholders/renovate/kotlin-monorepo
fix(deps): update kotlin monorepo to v1.8.22
2023-06-27 12:30:46 -05:00
renovate[bot] a67b23079d fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.84.0+1.20.1 2023-06-23 21:31:16 +00:00
renovate[bot] 79bffc2522 chore(deps): update dependency net.minecrell.plugin-yml.bukkit to v0.6.0 2023-06-19 13:34:14 +00:00
renovate[bot] 7e9aa41fdd chore(deps): update plugin fabric-loom to v1.2.7 2023-06-14 15:38:33 +00:00
renovate[bot] cc30f56c76 fix(deps): update kotlin monorepo to v1.8.22 2023-06-07 20:14:59 +00:00
Adrian b24ddb12cc Merge pull request #91 from MiniPlaceholders/renovate/adventure
fix(deps): update adventure to v4.14.0
2023-06-07 08:08:17 -05:00
renovate[bot] 2df52bf858 fix(deps): update adventure to v4.14.0 2023-06-07 11:44:20 +00:00
Adrian dd64837958 Merge pull request #89 from MiniPlaceholders/renovate/dokka
chore(deps): update dependency org.jetbrains.dokka to v1.8.20
2023-06-06 11:35:58 -05:00
Adrian ccf3045cb3 Merge pull request #90 from MiniPlaceholders/renovate/org.jetbrains.dokka
fix(deps): update dependency org.jetbrains.dokka:dokka-gradle-plugin to v1.8.20
2023-06-06 11:35:48 -05:00
renovate[bot] 34cab56b2c fix(deps): update dependency org.jetbrains.dokka:dokka-gradle-plugin to v1.8.20 2023-06-05 21:13:02 +00:00
renovate[bot] 7090497684 chore(deps): update dependency org.jetbrains.dokka to v1.8.20 2023-06-05 21:12:58 +00:00
Adrian 4fefeda34d Merge pull request #88 from MiniPlaceholders/renovate/fabric.api
fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.83.0+1.20
2023-06-04 10:08:11 -05:00
renovate[bot] 9ec693ae16 fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.83.0+1.20 2023-06-04 14:26:34 +00:00
Adrian 36039dd0f6 Merge pull request #87 from MiniPlaceholders/renovate/fabric.loader
fix(deps): update dependency net.fabricmc:fabric-loader to v0.14.21
2023-06-04 09:25:59 -05:00
renovate[bot] 7295ce2b6c fix(deps): update dependency net.fabricmc:fabric-loader to v0.14.21 2023-06-04 14:16:25 +00:00
Adrian 82987e54f1 Merge pull request #84 from MiniPlaceholders/renovate/fabric-api
fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.82.0+1.20
2023-05-25 19:46:24 -05:00
renovate[bot] 19da3e8050 fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.82.0+1.20 2023-05-25 01:16:06 +00:00
Adrian 440efc5d8a Merge pull request #83 from MiniPlaceholders/renovate/fabric-api
fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.81.3+1.20
2023-05-24 12:52:16 -05:00
renovate[bot] b8e9cf3b07 fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.81.3+1.20 2023-05-24 01:43:18 +00:00
Adrian eb34c410e0 Merge pull request #80 from MiniPlaceholders/renovate/fabric-api
fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.81.2+1.20
2023-05-23 17:19:20 -05:00
renovate[bot] 866767f08f fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.81.2+1.20 2023-05-23 01:44:45 +00:00
Adrian 9c175b8ffd Merge pull request #82 from MiniPlaceholders/renovate/fabric-loader
fix(deps): update dependency net.fabricmc:fabric-loader to v0.14.20
2023-05-22 20:44:01 -05:00
renovate[bot] f3460dbc51 fix(deps): update dependency net.fabricmc:fabric-loader to v0.14.20 2023-05-23 00:00:28 +00:00
Adrian a8671bbcd2 Merge pull request #79 from MiniPlaceholders/renovate/indra
fix(deps): update indra to v3.1.1
2023-05-17 08:36:58 -05:00
Adrian 47f17eb199 fix: Check Tag equality using String#equalsIgnoreCase 2023-05-15 22:49:23 -05:00
Adrian f92df0f0dd Merge remote-tracking branch 'origin/main' 2023-05-15 22:46:09 -05:00
Adrian 1ccf5ce3ec fix: Improved encapsulation of the Expansion class by converting it to a sealed interface 2023-05-15 22:45:50 -05:00
renovate[bot] 9dad10c46a fix(deps): update indra to v3.1.1 2023-05-14 20:42:18 +00:00
Adrian b87e7bc50f Merge pull request #78 from MiniPlaceholders/renovate/fabric-api
fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.80.3+1.20
2023-05-13 11:43:44 -05:00
Adrian 103bdf9a78 release: Version 2.2.0 2023-05-13 11:20:23 -05:00
Adrian 58391bd263 fix(ci): Fixed upload action 2023-05-13 11:16:30 -05:00
Adrian 1405925a43 fix: Fixed javadoc invalid character 2023-05-13 11:13:53 -05:00
Adrian bc6d51e07c api: Improved conditional API methods 2023-05-13 10:43:56 -05:00
Adrian 0048eb1186 perf: Reuse empty arrays 2023-05-13 10:42:27 -05:00
Adrian 3f00242d1a fix(api): Fixed possible NPE if the forwarded audience is null 2023-05-13 10:20:26 -05:00
renovate[bot] 89573967fd fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.80.3+1.20 2023-05-11 20:51:15 +00:00
Adrian 18d8538144 Merge pull request #77 from MiniPlaceholders/build/module-jars
Split platforms into separate files
2023-05-09 22:26:55 -05:00
Adrian c6a2739162 Merge branch 'main' into build/module-jars
# Conflicts:
#	fabric/build.gradle.kts
2023-05-09 21:28:57 -05:00
Adrian 42049dc7d7 fix(test): Fixed Junit Jupiter and Plain Serializer test dependencies 2023-05-09 21:22:11 -05:00
Adrian 94bd9180f7 fix(sponge): Fixed Geantyref inclusion 2023-05-09 21:11:45 -05:00
Adrian 3ea331f00a build: Split platforms into separate files 2023-05-05 17:03:20 -05:00
Adrian 98e27c85d2 Merge pull request #76 from MiniPlaceholders/renovate/fabric-loom-1.x
chore(deps): update plugin fabric-loom to v1.2.7
2023-05-05 12:27:59 -05:00
renovate[bot] c48e42c21d chore(deps): update plugin fabric-loom to v1.2.7 2023-05-05 15:27:09 +00:00
Adrian 18901c887c Merge pull request #68 from MiniPlaceholders/renovate/fabric-api
fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.80.1+1.20
2023-05-04 15:40:53 -05:00
Adrian 218bfc0bab Merge pull request #73 from MiniPlaceholders/feat/platform/sponge
Sponge Implementation
2023-05-04 13:59:31 -05:00
Adrian dba1bbe0d5 Merge pull request #72 from MiniPlaceholders/renovate/desertwell
fix(deps): update dependency net.william278:desertwell to v2.0.4
2023-05-03 21:01:33 -05:00
Adrian 6be0f99a85 feat: Initial Sponge Implementation 2023-05-03 20:43:47 -05:00
renovate[bot] b65c83eb69 fix(deps): update dependency net.william278:desertwell to v2.0.4 2023-05-04 01:22:35 +00:00
renovate[bot] 96836270d6 fix(deps): update dependency net.fabricmc.fabric-api:fabric-api to v0.80.1+1.20 2023-05-03 20:32:09 +00:00
Adrian d94c3c5bba Merge pull request #71 from MiniPlaceholders/feat/cloud
Cloud Implementation
2023-05-03 15:30:27 -05:00
Adrian c780a1bb8f [ci skip] build: Exclude Fabric/run directory 2023-05-03 15:14:55 -05:00
Adrian 9954cf36db fix: Fixed Fabric libs inclusion and Plugin relocations 2023-05-03 13:51:52 -05:00
Adrian 15aa2779c8 fix: Fixed Source suggestions 2023-05-03 12:48:44 -05:00
Adrian b1fa65d335 feat: Initial Cloud Implementation 2023-05-02 22:13:56 -05:00
Adrian dd4af51264 Merge pull request #70 from MiniPlaceholders/feat/forwarding-audience-support
Added Support for passing ForwardingAudience.Single instead of the actual instance
2023-05-02 17:02:41 -05:00
Adrian ac138706b7 feat: Added Support for passing ForwardingAudience.Single instead of the actual instance 2023-05-02 16:36:11 -05:00
Adrian 888df22b1f test: Add Empty Arguments test 2023-05-02 16:02:33 -05:00
Adrian 98048622c6 Merge pull request #69 from MiniPlaceholders/renovate/fabric-loom-1.x
chore(deps): update plugin fabric-loom to v1.2.6
2023-05-02 08:30:33 -05:00
renovate[bot] 6ba68553c6 chore(deps): update plugin fabric-loom to v1.2.6 2023-05-02 11:42:56 +00:00
Adrian 6aa65a6a95 Merge pull request #66 from MiniPlaceholders/renovate/junit5-monorepo
fix(deps): update dependency org.junit:junit-bom to v5.9.3
2023-04-26 16:32:00 -05:00
Adrian 37a7ece2d3 Merge pull request #67 from MiniPlaceholders/renovate/userdev
chore(deps): update dependency io.papermc.paperweight.userdev to v1.5.5
2023-04-26 16:30:31 -05:00
renovate[bot] 4d5f6a2928 chore(deps): update dependency io.papermc.paperweight.userdev to v1.5.5 2023-04-26 20:57:13 +00:00
renovate[bot] 65f7a9652c fix(deps): update dependency org.junit:junit-bom to v5.9.3 2023-04-26 11:41:54 +00:00
44 changed files with 884 additions and 432 deletions

No files matched your search

+1 -3
View File
@@ -28,6 +28,4 @@ jobs:
uses: actions/upload-artifact@v3
with:
name: MiniPlaceholders
path: |-
build/libs/MiniPlaceholders-*.jar
fabric/build/libs/MiniPlaceholders-Fabric-mc*.jar
path: jar/MiniPlaceholders-*.jar
+1
View File
@@ -2,6 +2,7 @@
/.idea/
build/
bin/
jar/
# Visual Studio Code
+4 -3
View File
@@ -5,13 +5,14 @@
![Modrinth Downloads](https://img.shields.io/modrinth/dt/HQyibRsN?logo=Modrinth&style=flat-square)
![GitHub Downloads](https://img.shields.io/github/downloads/MiniPlaceholders/MiniPlaceholders/total?logo=GitHub&style=flat-square)
MiniMessage Component-based Placeholders for PaperMC, Folia, Fabric, Krypton and Velocity platforms
MiniMessage Component-based Placeholders for PaperMC, Folia, Fabric, Sponge, Krypton and Velocity platforms
## Compatibility
- Paper 1.19.4+
- Paper 1.19.3, 1.19.4+
- Folia 1.19.4
- Velocity 3.1.2+
- Fabric
- Fabric 1.19.4+
- Sponge API 8, 9, 10
- Krypton
## Commands
+16 -18
View File
@@ -1,28 +1,22 @@
plugins {
id("miniplaceholders.base")
alias(libs.plugins.jmh)
id("miniplaceholders.publish")
}
dependencies {
compileOnly(libs.adventure.api)
compileOnly(libs.adventure.minimesssage)
compileOnly("net.kyori:adventure-text-serializer-legacy:4.13.1")
compileOnly(libs.adventure.serializer.legacy)
compileOnly(projects.miniplaceholdersConnect)
testImplementation(platform("org.junit:junit-bom:5.9.2"))
testImplementation(platform(libs.junit.bom))
testImplementation("org.junit.jupiter:junit-jupiter")
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
testImplementation(libs.adventure.api)
testImplementation(libs.adventure.minimesssage)
testImplementation("net.kyori:adventure-text-serializer-plain:4.13.1")
}
tasks {
test {
useJUnitPlatform()
testLogging {
events("passed", "failed")
}
}
testImplementation(libs.adventure.serializer.plain)
testImplementation(libs.adventure.serializer.legacy)
}
jmh {
@@ -33,14 +27,9 @@ jmh {
java {
withJavadocJar()
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
tasks {
compileJava {
options.encoding = Charsets.UTF_8.name()
options.release.set(17)
}
processResources {
filteringCharset = Charsets.UTF_8.name()
}
@@ -51,4 +40,13 @@ tasks {
"https://jd.advntr.dev/text-minimessage/${libs.versions.adventure.get()}/"
)
}
compileTestJava {
options.encoding = Charsets.UTF_8.name()
}
test {
useJUnitPlatform()
testLogging {
events("passed", "failed")
}
}
}
@@ -35,7 +35,7 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
*
* @since 1.0.0
*/
public interface Expansion {
public sealed interface Expansion permits ExpansionImpl {
/**
* Get the expansion name
* @return the expansion name
@@ -134,6 +134,7 @@ public interface Expansion {
*
* <p>The content of this Placeholder is cached
* and can mutate depending on when it is invoked</p>
*
* @param key the placeholder key, cannot be an empty or black string
* @param audiencePlaceholder the single placeholder
* @return the {@link Builder} itself
@@ -152,6 +153,7 @@ public interface Expansion {
*
* <p>The content of this Placeholder is cached
* and can mutate depending on when it is invoked</p>
*
* @param key the placeholder key, cannot be an empty or black string
* @param relationalPlaceholder the relational placeholder
* @return the {@link Builder} itself
@@ -191,6 +193,7 @@ public interface Expansion {
*
* <p>This eliminates the need to perform a manual
* <pre>if(!(audience instanceof Player)) return TagResolver.empty();</pre>
*
* @param clazz the class to filter
* @return the {@link Builder} itself
* @since 1.0.0
@@ -202,15 +205,17 @@ public interface Expansion {
* Filters the audiences that this expansion can receive through a Predicate
* <p>Example:</p>
* <pre>
* Expansion.builder("example").filter(Player.class).filter(aud -> isInProtectedServer((Player)aud))
* Expansion.builder("example")
* .filter(aud -> aud instanceof Player player{@literal &&} isInProtectedServer(player)
* .audiencePlaceholder("hello", (aud, queue, ctx) -> Tag.selfInsertingClosing(Component.text("you are in protected server")))
* .build();
* </pre>
*
* @param predicate the check to realize
* @return the {@link Builder} itself
* @since 1.0.0
*/
@Contract("_ -> this")
@NotNull Builder filter(final @Nullable Predicate<Audience> predicate);
@NotNull Builder filter(final @Nullable Predicate<@NotNull Audience> predicate);
}
}
@@ -1,27 +1,26 @@
package io.github.miniplaceholders.api;
import java.util.Collection;
import java.util.HashSet;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import io.github.miniplaceholders.api.placeholder.AudiencePlaceholder;
import io.github.miniplaceholders.api.placeholder.RelationalPlaceholder;
import io.github.miniplaceholders.api.utils.Conditions;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.audience.ForwardingAudience;
import net.kyori.adventure.text.minimessage.Context;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Predicate;
import static io.github.miniplaceholders.api.utils.Conditions.nonNullOrEmptyString;
import static java.util.Objects.requireNonNull;
final class ExpansionImpl implements Expansion {
private static final Tags.Single[] EMPTY_SINGLE_AUDIENCE = new Tags.Single[0];
private static final Tags.Relational[] EMPTY_RELATIONAL_AUDIENCE = new Tags.Relational[0];
private final String name;
private final Tags.Single[] audiencePlaceholders;
private final Tags.Relational[] relationalPlaceholders;
@@ -38,14 +37,12 @@ final class ExpansionImpl implements Expansion {
@Nullable final Predicate<Audience> predicateFilter){
this.name = expansionName+"-";
this.audiencePlaceholders = audiencePlaceholders != null
? audiencePlaceholders.toArray(Tags.Single[]::new)
: new Tags.Single[0];
? audiencePlaceholders.toArray(EMPTY_SINGLE_AUDIENCE)
: EMPTY_SINGLE_AUDIENCE;
this.relationalPlaceholders = relationalPlaceholders != null
? relationalPlaceholders.toArray(Tags.Relational[]::new)
: new Tags.Relational[0];
this.globalPlaceholders = globalPlaceholders == null
? TagResolver.empty()
: globalPlaceholders;
? relationalPlaceholders.toArray(EMPTY_RELATIONAL_AUDIENCE)
: EMPTY_RELATIONAL_AUDIENCE;
this.globalPlaceholders = globalPlaceholders;
this.filterClass = filterClass;
this.predicateFilter = predicateFilter;
}
@@ -56,46 +53,56 @@ final class ExpansionImpl implements Expansion {
}
@Override
public @NotNull TagResolver audiencePlaceholders(@NotNull final Audience audience){
if(audiencePlaceholders.length == 0) return TagResolver.empty();
public @NotNull TagResolver audiencePlaceholders(@NotNull Audience audience) {
if (audiencePlaceholders.length == 0) return TagResolver.empty();
Objects.requireNonNull(audience, "the audience cannot be null");
requireNonNull(audience, "the audience cannot be null");
if(this.singleFilter(audience)) return TagResolver.empty();
if ((audience = expansionFilter(audience)) == null) return TagResolver.empty();
final TagResolver.Builder placeholders = TagResolver.builder();
for(final Tags.Single pl : this.audiencePlaceholders){
for (final Tags.Single pl : this.audiencePlaceholders) {
placeholders.resolver(pl.of(audience));
}
return placeholders.build();
}
private boolean singleFilter(final Audience audience){
return filterClass != null && !filterClass.isInstance(audience)
|| predicateFilter != null && predicateFilter.test(audience);
@SuppressWarnings("OverrideOnly")
private Audience expansionFilter(final Audience audience) {
if (audience == null || filterClass == null && predicateFilter == null) {
return audience;
}
final boolean eligible = filterClass != null && filterClass.isInstance(audience)
|| predicateFilter != null && predicateFilter.test(audience);
if (eligible) {
return audience;
}
if (audience instanceof final ForwardingAudience.Single forward) {
return expansionFilter(forward.audience());
}
return null;
}
@Override
public @NotNull TagResolver relationalPlaceholders(@NotNull final Audience audience, @NotNull final Audience otherAudience){
if(relationalPlaceholders.length == 0) return TagResolver.empty();
public @NotNull TagResolver relationalPlaceholders(@NotNull Audience audience, @NotNull Audience otherAudience){
if (relationalPlaceholders.length == 0) return TagResolver.empty();
Objects.requireNonNull(audience, "the audience cannot be null");
Objects.requireNonNull(otherAudience, "the other audience cannot be null");
requireNonNull(audience, "the audience cannot be null");
requireNonNull(otherAudience, "the other audience cannot be null");
if (this.relationalFilter(audience, otherAudience)) return TagResolver.empty();
audience = expansionFilter(audience);
otherAudience = expansionFilter(otherAudience);
if (audience == null || otherAudience == null) {
return TagResolver.empty();
}
final TagResolver.Builder placeholders = TagResolver.builder();
for (final Tags.Relational pl : this.relationalPlaceholders){
for (final Tags.Relational pl : this.relationalPlaceholders) {
placeholders.resolver(pl.of(audience, otherAudience));
}
return placeholders.build();
}
private boolean relationalFilter(final Audience audience, final Audience otherAudience){
return filterClass != null && (!filterClass.isInstance(audience) || !filterClass.isInstance(otherAudience))
|| predicateFilter != null && (!predicateFilter.test(audience) || !predicateFilter.test(otherAudience));
}
@Override
public @NotNull TagResolver globalPlaceholders(){
return this.globalPlaceholders;
@@ -131,16 +138,16 @@ final class ExpansionImpl implements Expansion {
private Predicate<Audience> predicateFilter;
Builder(@NotNull final String name){
this.expansionName = Conditions.nonNullOrEmptyString(name, () -> "expansion name")
this.expansionName = nonNullOrEmptyString(name, "Expansion name")
.toLowerCase(Locale.ROOT).concat("_");
}
@Override
public @NotNull Builder audiencePlaceholder(@NotNull final String key, @NotNull final AudiencePlaceholder audiencePlaceholder){
Conditions.nonNullOrEmptyString(key, () -> "placeholder key");
Objects.requireNonNull(audiencePlaceholder, "the audience placeholder cannot be null");
nonNullOrEmptyString(key, "Placeholder key");
requireNonNull(audiencePlaceholder, "the audience placeholder cannot be null");
if (this.audiencePlaceholders == null) this.audiencePlaceholders = new HashSet<>(5);
if (this.audiencePlaceholders == null) this.audiencePlaceholders = new HashSet<>();
this.audiencePlaceholders.add(Tags.single(expansionName+key, audiencePlaceholder));
return this;
@@ -148,10 +155,10 @@ final class ExpansionImpl implements Expansion {
@Override
public @NotNull Builder relationalPlaceholder(@NotNull final String key, @NotNull final RelationalPlaceholder relationalPlaceholder){
Conditions.nonNullOrEmptyString(key, () -> "placeholder key");
Objects.requireNonNull(relationalPlaceholder, "the relational placeholder cannot be null");
nonNullOrEmptyString(key, "Placeholder key");
requireNonNull(relationalPlaceholder, "the relational placeholder cannot be null");
if (this.relationalPlaceholders == null) this.relationalPlaceholders = new HashSet<>(4);
if (this.relationalPlaceholders == null) this.relationalPlaceholders = new HashSet<>();
this.relationalPlaceholders.add(Tags.relational(expansionName+"rel_"+key, relationalPlaceholder));
return this;
@@ -159,10 +166,10 @@ final class ExpansionImpl implements Expansion {
@Override
public @NotNull Builder globalPlaceholder(@NotNull final String key, @NotNull final BiFunction<ArgumentQueue, Context, Tag> function){
Conditions.nonNullOrEmptyString(key, () -> "placeholder key");
Objects.requireNonNull(function, "the global placeholder cannot be null");
nonNullOrEmptyString(key, "Placeholder key");
requireNonNull(function, "the global placeholder cannot be null");
if(this.globalPlaceholders == null) this.globalPlaceholders = TagResolver.builder();
if (this.globalPlaceholders == null) this.globalPlaceholders = TagResolver.builder();
this.globalPlaceholders.tag(expansionName+key, function);
return this;
@@ -170,10 +177,10 @@ final class ExpansionImpl implements Expansion {
@Override
public @NotNull Builder globalPlaceholder(@NotNull final String key, @NotNull final Tag tag){
Conditions.nonNullOrEmptyString(key, () -> "placeholder key");
Objects.requireNonNull(tag, "the tag cannot be null");
nonNullOrEmptyString(key, "Placeholder key");
requireNonNull(tag, "the tag cannot be null");
if(this.globalPlaceholders == null) this.globalPlaceholders = TagResolver.builder();
if (this.globalPlaceholders == null) this.globalPlaceholders = TagResolver.builder();
this.globalPlaceholders.tag(expansionName+key, tag);
return this;
@@ -197,7 +204,7 @@ final class ExpansionImpl implements Expansion {
this.expansionName,
this.audiencePlaceholders,
this.relationalPlaceholders,
this.globalPlaceholders != null ? this.globalPlaceholders.build() : null,
this.globalPlaceholders != null ? this.globalPlaceholders.build() : TagResolver.empty(),
this.filterClass,
this.predicateFilter
);
@@ -205,10 +212,11 @@ final class ExpansionImpl implements Expansion {
}
@Override
public boolean equals(Object o){
if (this==o) return true;
if (o == null || o.getClass() != ExpansionImpl.class) return false;
return ((ExpansionImpl)o).name.equals(this.name);
public boolean equals(final Object o) {
if (this == o) return true;
if (!(o instanceof Expansion that)) return false;
return that.name().equalsIgnoreCase(this.name());
}
@Override
@@ -1,17 +1,16 @@
package io.github.miniplaceholders.api;
import io.github.miniplaceholders.api.enums.Platform;
import io.github.miniplaceholders.connect.InternalPlatform;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import io.github.miniplaceholders.api.enums.Platform;
import org.jetbrains.annotations.NotNull;
import io.github.miniplaceholders.connect.InternalPlatform;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.jetbrains.annotations.Nullable;
import static io.github.miniplaceholders.api.utils.Resolvers.applyIfNotEmpty;
import static java.util.Objects.requireNonNull;
@@ -42,6 +41,7 @@ public final class MiniPlaceholders {
case VELOCITY -> Platform.VELOCITY;
case KRYPTON -> Platform.KRYPTON;
case FABRIC -> Platform.FABRIC;
case SPONGE -> Platform.SPONGE;
};
}
@@ -200,7 +200,7 @@ public final class MiniPlaceholders {
* @see Expansion#builder(String)
* @since 2.1.0
*/
public @Nullable Expansion getExpansionByName(final @NotNull String name) {
public static @Nullable Expansion getExpansionByName(final @NotNull String name) {
for (final Expansion expansion : expansions) {
if (Objects.equals(expansion.name(), name)) {
return expansion;
@@ -15,7 +15,7 @@ import net.kyori.adventure.text.minimessage.tag.resolver.ArgumentQueue;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
final class Tags {
private Tags(){}
private Tags() {}
static Relational relational(@NotNull final String name, @NotNull final RelationalPlaceholder relationalPlaceholder){
return new Tags.Relational(name, relationalPlaceholder);
@@ -35,7 +35,7 @@ final class Tags {
}
TagResolver of(@NotNull final Audience audience, @NotNull final Audience otherAudience){
return new TagResolver(){
return new TagResolver() {
@Override
public @Nullable Tag resolve(@NotNull String name, @NotNull ArgumentQueue arguments,
@NotNull Context ctx) throws ParsingException {
@@ -53,10 +53,10 @@ final class Tags {
}
@Override
public boolean equals(Object o){
if(o == this) return true;
if(!(o instanceof Relational)) return false;
return ((Relational)o).key.equals(this.key);
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof final Relational that)) return false;
return that.key.equalsIgnoreCase(this.key);
}
@Override
@@ -93,10 +93,10 @@ final class Tags {
}
@Override
public boolean equals(Object o){
if(o == this) return true;
if(!(o instanceof Single)) return false;
return ((Single)o).key.equals(this.key);
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof final Single that)) return false;
return that.key.equalsIgnoreCase(this.key);
}
@Override
@@ -9,5 +9,7 @@ public enum Platform {
/**Krypton Platform */
KRYPTON,
/**Fabric Platform */
FABRIC
FABRIC,
/**Sponge Platform */
SPONGE
}
@@ -1,36 +1,73 @@
package io.github.miniplaceholders.api.utils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.function.Supplier;
/** Checks required for the correct operation of the expansions*/
public final class Conditions {
private Conditions(){}
private Conditions() {}
/**
* Checks if a string is null or empty or consists of whitespace characters only
* Checks if a string is null or empty or consists of whitespace characters only.
*
* @param string the string
* @param name the name supplier
* @return the string if it is not null or empty
* @since 1.0.0
* @throws IllegalStateException if the provided string is empty
*/
public static String nonNullOrEmptyString(String string, Supplier<String> name){
public static String nonNullOrEmptyString(@Nullable String string, @NotNull Supplier<@NotNull String> name){
if (string == null)
throw new NullPointerException("the " + name.get() + " cannot be null");
throw new NullPointerException(name.get() + " cannot be null");
if (string.isBlank())
throw new IllegalStateException("the " + name.get() + "cannot be an empty string");
throw new IllegalStateException(name.get() + "cannot be an empty string");
return string;
}
/**
* Check if a string is empty or consists of whitespace characters only
* Checks if a string is null or empty or consists of whitespace characters only.
*
* @param string the string
* @param name the name
* @return the string if it is not null or empty
* @since 2.2.0
* @throws IllegalStateException if the provided string is empty
*/
public static String nonNullOrEmptyString(@Nullable String string, @NotNull String name){
if (string == null)
throw new NullPointerException(name + " cannot be null");
if (string.isBlank())
throw new IllegalStateException(name + "cannot be an empty string");
return string;
}
/**
* Check if a string is empty or consists of whitespace characters only.
*
* @param string the string
* @param reason the reason supplier
* @return the string if it not empty
* @since 1.0.0
* @throws IllegalStateException if the provided string is empty
*/
public static String nonEmptyString(String string, Supplier<String> reason){
if (string.isBlank())
throw new IllegalStateException(reason.get());
public static String nonEmptyString(@NotNull String string, @NotNull Supplier<@NotNull String> reason){
if (string.isBlank()) throw new IllegalStateException(reason.get());
return string;
}
/**
* Check if a string is empty or consists of whitespace characters only.
*
* @param string the string
* @param reason the reason
* @return the string if it not empty
* @since 2.2.0
* @throws IllegalStateException if the provided string is empty
*/
public static String nonEmptyString(@NotNull String string, @NotNull String reason){
if (string.isBlank()) throw new IllegalStateException(reason);
return string;
}
@@ -1,6 +1,8 @@
package io.github.miniplaceholders.api.utils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.Context;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -25,20 +27,89 @@ public final class LegacyUtils {
.build();
/**
* Parse a string with possible legacy symbols
* Parse a string with possible legacy Ampersand/Section symbols
* <br>
* <p><b>
* This method should only be used in case a String is provided from a legacy plugin/mod
* or legacy source, where it is very likely to get a legacy string.
* It is not recommended to use this method regularly in any sense
* </b></p>
*
* @param string the string
* @return a parsed string
* @since 1.0.0
*/
public static @NotNull Component parsePossibleLegacy(@Nullable String string) {
if (string == null || string.isBlank()) return Component.empty();
if (string.indexOf('&') != 0) {
return miniMessage().deserialize(
miniMessage().serialize(LEGACY_HEX_SERIALIZER.deserialize(string))
);
} else {
if (string == null || string.isEmpty()) return Component.empty();
if (string.indexOf(LegacyComponentSerializer.SECTION_CHAR) != -1) {
string = string.replace(LegacyComponentSerializer.SECTION_CHAR, LegacyComponentSerializer.AMPERSAND_CHAR);
}
if (string.indexOf(LegacyComponentSerializer.AMPERSAND_CHAR) == -1) {
return miniMessage().deserialize(string);
}
return miniMessage().deserialize(
miniMessage().serialize(LEGACY_HEX_SERIALIZER.deserialize(string))
.replace("\\<", "<")
.replace("\\>", ">")
);
}
/**
* Parse a string with possible legacy Ampersand/Section symbols
* using a parsing Context
* <p><b>
* This method should only be used in case a String is provided from a legacy plugin/mod
* or legacy source, where it is very likely to get a legacy string.
* It is not recommended to use this method regularly in any sense
* </b></p>
*
* @param string the string
* @param context the provided parsing context
* @return a parsed string
* @since 2.2.1
*/
public static @NotNull Component parsePossibleLegacy(@Nullable String string, @NotNull final Context context) {
if (string == null || string.isEmpty()) return Component.empty();
if (string.indexOf(LegacyComponentSerializer.SECTION_CHAR) != -1) {
string = string.replace(LegacyComponentSerializer.SECTION_CHAR, LegacyComponentSerializer.AMPERSAND_CHAR);
}
if (string.indexOf(LegacyComponentSerializer.AMPERSAND_CHAR) == -1) {
return context.deserialize(string);
}
return context.deserialize(
miniMessage().serialize(LEGACY_HEX_SERIALIZER.deserialize(string))
.replace("\\<", "<")
.replace("\\>", ">")
);
}
/**
* Parse a string with possible legacy Ampersand/Section symbols
* using the provided resolver
* <p><b>
* This method should only be used in case a String is provided from a legacy plugin/mod
* or legacy source, where it is very likely to get a legacy string.
* It is not recommended to use this method regularly in any sense
* </b></p>
*
* @param string the string
* @param resolver a resolver
* @return a parsed string
* @since 2.2.1
*/
public static @NotNull Component parsePossibleLegacy(@Nullable String string, @NotNull final TagResolver resolver) {
if (string == null || string.isEmpty()) return Component.empty();
if (string.indexOf(LegacyComponentSerializer.SECTION_CHAR) != -1) {
string = string.replace(LegacyComponentSerializer.SECTION_CHAR, LegacyComponentSerializer.AMPERSAND_CHAR);
}
if (string.indexOf(LegacyComponentSerializer.AMPERSAND_CHAR) == -1) {
return miniMessage().deserialize(string, resolver);
}
return miniMessage().deserialize(
miniMessage().serialize(LEGACY_HEX_SERIALIZER.deserialize(string))
.replace("\\<", "<")
.replace("\\>", ">"),
resolver
);
}
}
+5 -3
View File
@@ -1,11 +1,13 @@
/** MiniPlaceholders API Module */
open module io.github.miniplaceholders.api {
requires io.github.miniplaceholders.connect;
requires net.kyori.adventure;
requires net.kyori.adventure.text.minimessage;
requires net.kyori.examination.api;
requires static org.jetbrains.annotations;
requires io.github.miniplaceholders.connect;
requires net.kyori.adventure.text.serializer.legacy;
requires net.kyori.examination.api;
requires static org.jetbrains.annotations;
exports io.github.miniplaceholders.api;
exports io.github.miniplaceholders.api.enums;
@@ -1,12 +1,17 @@
package io.github.miniplaceholders.test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import io.github.miniplaceholders.api.Expansion;
import io.github.miniplaceholders.api.utils.TagsUtils;
import io.github.miniplaceholders.test.testobjects.TestAudienceHolder;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import static io.github.miniplaceholders.test.PlaceholderTest.assertContentEquals;
import static net.kyori.adventure.text.minimessage.MiniMessage.miniMessage;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
class ExpansionsTest {
@Test
@@ -21,4 +26,20 @@ class ExpansionsTest {
assertEquals(firstExpansion, secondExpansion);
}
@Test
void nullForwardedAudience() {
TestAudienceHolder audience = new TestAudienceHolder(null);
final Expansion expansion = Expansion.builder("test")
.filter(aud -> aud.toString().isBlank())
.audiencePlaceholder("testing", (aud, queue, ctx) -> Tag.selfClosingInserting(Component.text(aud.toString())))
.build();
Component result = assertDoesNotThrow(
() -> miniMessage().deserialize("<test_testing>", expansion.audiencePlaceholders(audience))
);
assertContentEquals(result, Component.text("<test_testing>"));
}
}
@@ -0,0 +1,20 @@
package io.github.miniplaceholders.test;
import io.github.miniplaceholders.api.utils.LegacyUtils;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.plain.PlainTextComponentSerializer;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
class LegacyTest {
@Test
void testLegacyParsing() {
final String string = "<rainbow>hello... i &8hate legacy format §bso much";
final Component parsed = LegacyUtils.parsePossibleLegacy(string);
final String result = PlainTextComponentSerializer.plainText().serialize(parsed);
final String expected = "hello... i hate legacy format so much";
assertEquals(expected, result);
}
}
@@ -1,8 +1,10 @@
package io.github.miniplaceholders.test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static net.kyori.adventure.text.minimessage.MiniMessage.miniMessage;
import static org.junit.jupiter.api.Assertions.*;
import io.github.miniplaceholders.test.testobjects.TestAudience;
import io.github.miniplaceholders.test.testobjects.TestAudienceHolder;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.DisplayName;
@@ -23,12 +25,15 @@ class PlaceholderTest {
TestAudience player = new TestAudience("4drian3d");
Expansion expansion = Expansion.builder("example")
.audiencePlaceholder("name", (aud, queue, ctx) -> Tag.selfClosingInserting(Component.text(((TestAudience)aud).name()))).build();
.audiencePlaceholder("name", (aud, queue, ctx) -> {
TestAudience audience = (TestAudience) aud;
return Tag.selfClosingInserting(Component.text(audience.name()));
}).build();
final Component expected = Component.text("Player Name: 4drian3d");
final Component result = MiniMessage.miniMessage().deserialize("Player Name: <example_name>", expansion.audiencePlaceholders(player));
final Component result = miniMessage().deserialize("Player Name: <example_name>", expansion.audiencePlaceholders(player));
assertEquals(expected, result);
assertContentEquals(expected, result);
}
@Test
@@ -59,7 +64,7 @@ class PlaceholderTest {
final Component expected = Component.text("Online players: 1305 | Servers: 7");
final Component actual = MiniMessage.miniMessage().deserialize("Online players: <global_players> | Servers: <global_servers>", expansion.globalPlaceholders());
assertEquals(expected, actual);
assertContentEquals(expected, actual);
}
@Test
@@ -92,13 +97,50 @@ class PlaceholderTest {
Component playerExpected = Component.text("Player Name: TestPlayer04");
Component emptyExpected = Component.text("Player Name: <filter_name>");
assertEquals(playerExpected, MiniMessage.miniMessage().deserialize(string, expansion.audiencePlaceholders(player)));
assertEquals(emptyExpected, MiniMessage.miniMessage().deserialize(string, expansion.audiencePlaceholders(emptyAudience)));
assertContentEquals(playerExpected, MiniMessage.miniMessage().deserialize(string, expansion.audiencePlaceholders(player)));
assertContentEquals(emptyExpected, MiniMessage.miniMessage().deserialize(string, expansion.audiencePlaceholders(emptyAudience)));
}
void assertContentEquals(Component first, Component second){
@Test
@DisplayName("Empty Arguments")
void testEmptyArguments() {
final Expansion expansion = Expansion.builder("test")
.globalPlaceholder("testing", (queue, ctx) -> {
int arguments = 0;
while (queue.hasNext()) {
arguments++;
Tag.Argument argument = queue.pop();
assertTrue(argument.value().isBlank());
}
return Tag.selfClosingInserting(Component.text("Arguments: "+arguments));
})
.build();
Component parsed = miniMessage().deserialize("<test_testing::>", expansion.globalPlaceholders());
assertContentEquals(parsed, Component.text("Arguments: 2"));
}
@Test
@DisplayName("Forwarding Audience Parsing Test")
void forwardingAudienceTest() {
Expansion expansion = Expansion.builder("test")
.filter(TestAudience.class)
.audiencePlaceholder("testing", (audience, queue, ctx) -> {
TestAudience testAudience = (TestAudience) audience;
return Tag.selfClosingInserting(Component.text("Name: "+testAudience.name()));
}).build();
TestAudience testAudience = new TestAudience("4drian3d");
Audience forward = new TestAudienceHolder(testAudience);
Component parsed = miniMessage().deserialize("<test_testing>.", expansion.audiencePlaceholders(forward));
Component expected = Component.text("Name: 4drian3d.");
assertContentEquals(parsed, expected);
}
static void assertContentEquals(Component first, Component second){
String firstSerialized = PlainTextComponentSerializer.plainText().serialize(first);
String secondSerialized = PlainTextComponentSerializer.plainText().serialize(second);
@@ -0,0 +1,11 @@
package io.github.miniplaceholders.test.testobjects;
import net.kyori.adventure.audience.ForwardingAudience;
import org.jetbrains.annotations.NotNull;
public record TestAudienceHolder(TestAudience audience) implements ForwardingAudience.Single {
@Override
public @NotNull TestAudience audience() {
return audience;
}
}
+4
View File
@@ -12,4 +12,8 @@ dependencyResolutionManagement {
from(files("../gradle/libs.versions.toml"))
}
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.6.0"
}
@@ -0,0 +1,7 @@
import org.gradle.api.Project
import org.gradle.configurationcache.extensions.capitalized
val Project.capitalizeName: String
get() = this.name.substring(17).capitalized()
fun Project.simpleName(): String = this.name.substring(17)
@@ -0,0 +1,11 @@
plugins {
id("miniplaceholders.base")
}
tasks {
jar {
manifest {
attributes("Automatic-Module-Name" to "io.github.miniplaceholders.${project.simpleName()}")
}
}
}
@@ -0,0 +1,28 @@
import java.util.Date
plugins {
java
}
tasks {
compileJava {
options.encoding = Charsets.UTF_8.name()
options.release.set(17)
}
jar {
manifest {
attributes(
"Specification-Version" to project.version,
"Specification-Vendor" to "MiniPlaceholders",
"Implementation-Build-Date" to Date()
)
}
}
}
java{
toolchain{
languageVersion.set(JavaLanguageVersion.of(17))
vendor.set(JvmVendorSpec.ADOPTIUM)
}
}
@@ -0,0 +1,21 @@
plugins {
id("miniplaceholders.base")
id("com.github.johnrengelman.shadow")
}
tasks {
shadowJar {
archiveBaseName.set("MiniPlaceholders-${project.capitalizeName}")
archiveClassifier.set("")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
relocate("net.william278.desertwell", "io.github.miniplaceholders.libs.desertwell")
relocate("cloud.commandframework", "io.github.miniplaceholders.libs.cloud")
if (project.simpleName() != "sponge") {
relocate("io.leangen.geantyref", "io.github.miniplaceholders.libs.geantyref")
}
destinationDirectory.set(file("${project.rootDir}/jar"))
}
build {
dependsOn(shadowJar)
}
}
+3 -29
View File
@@ -1,35 +1,9 @@
plugins {
java
alias(libs.plugins.shadow)
kotlin("jvm") version "1.8.21" apply false
}
allprojects {
apply<JavaPlugin>()
repositories {
maven("https://papermc.io/repo/repository/maven-public/")
maven("https://repo.maven.apache.org/maven2/")
maven("https://jitpack.io") {
mavenContent {
includeGroup("net.william278")
}
}
}
}
dependencies {
implementation(projects.miniplaceholdersVelocity)
implementation(project(":miniplaceholders-paper", "reobf"))
implementation(projects.miniplaceholdersKrypton)
kotlin("jvm") version "1.9.0" apply false
}
tasks {
shadowJar {
archiveFileName.set("MiniPlaceholders-${project.version}.jar")
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
relocate("net.william278.desertwell", "io.github.miniplaceholders.libs.desertwell")
}
build {
dependsOn(shadowJar)
delete {
delete("jar")
}
}
+6 -22
View File
@@ -1,38 +1,22 @@
plugins {
id("miniplaceholders.auto.module")
alias(libs.plugins.blossom)
}
repositories {
maven("https://libraries.minecraft.net") {
mavenContent {
includeGroup("com.mojang")
}
}
}
dependencies {
implementation(projects.miniplaceholdersApi)
implementation(libs.desertwell) {
exclude("org.json")
}
implementation(libs.cloud.core)
implementation(libs.cloud.extras) {
isTransitive = false
}
compileOnly(libs.adventure.api)
compileOnly(libs.adventure.minimesssage)
compileOnly(libs.brigadier)
}
blossom{
blossom {
replaceToken("{version}", project.version)
replaceTokenIn("src/main/java/io/github/miniplaceholders/common/PluginConstants.java")
}
tasks {
compileJava {
options.encoding = Charsets.UTF_8.name()
options.release.set(17)
}
jar {
manifest {
attributes("Automatic-Module-Name" to "io.github.miniplaceholders.common")
}
}
}
@@ -1,76 +1,75 @@
package io.github.miniplaceholders.common;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import cloud.commandframework.ArgumentDescription;
import cloud.commandframework.Command;
import cloud.commandframework.CommandManager;
import cloud.commandframework.arguments.CommandArgument;
import cloud.commandframework.arguments.standard.StringArgument;
import cloud.commandframework.minecraft.extras.AudienceProvider;
import cloud.commandframework.minecraft.extras.MinecraftExceptionHandler;
import io.github.miniplaceholders.api.MiniPlaceholders;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.builder.AbstractBuilder;
import net.kyori.adventure.permission.PermissionChecker;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.format.TextColor;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import net.kyori.adventure.text.minimessage.tag.resolver.Placeholder;
import net.kyori.adventure.util.TriState;
import net.william278.desertwell.about.AboutMenu;
import net.william278.desertwell.util.Version;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Collection;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Supplier;
import static com.mojang.brigadier.arguments.StringArgumentType.*;
import static java.util.Objects.requireNonNull;
import static java.util.concurrent.CompletableFuture.supplyAsync;
import static net.kyori.adventure.text.Component.*;
import static net.kyori.adventure.text.Component.newline;
import static net.kyori.adventure.text.Component.text;
import static net.kyori.adventure.text.format.NamedTextColor.RED;
import static net.kyori.adventure.text.minimessage.MiniMessage.miniMessage;
public final class PlaceholdersCommand<A> {
private final Supplier<Collection<String>> playersSuggestions;
public final class PlaceholdersCommand<A extends Audience> {
private final Supplier<ArrayList<String>> playersSuggestions;
private final Function<String, Audience> toAudience;
private final Function<A, Audience> sourceToAudience;
private final BiPredicate<A, String> hasPermission;
private final String command;
private final CommandManager<A> commandManager;
private PlaceholdersCommand(
final Supplier<Collection<String>> playersSuggestions,
final Supplier<ArrayList<String>> playersSuggestions,
final Function<String, Audience> toAudience,
final Function<A, Audience> sourceToAudience,
final BiPredicate<A, String> hasPermission
final BiPredicate<A, String> hasPermission,
final String command,
final CommandManager<A> commandManager
) {
this.playersSuggestions = playersSuggestions;
this.toAudience = toAudience;
this.sourceToAudience = sourceToAudience;
this.hasPermission = hasPermission;
this.command = command;
this.commandManager = commandManager;
}
private static final Component TITLE = miniMessage().deserialize("<gradient:#4d8bff:#a4ff96>MiniPlaceholders</gradient>");
private static final Component HELP = text()
.append(newline())
.append(miniMessage()
.deserialize("<gradient:aqua:white:aqua><st><b> </st> <gradient:#4d8bff:#a4ff96>MiniPlaceholders</gradient> <st><b> </st>"))
.append(newline())
.append(miniMessage()
.deserialize(
"<gradient:#9694ff:#5269ff>Commands:</gradient>"))
.append(newline())
.append(miniMessage()
.deserialize(
"<gradient:aqua:#94d1ff>/miniplaceholders</gradient> <aqua>help</aqua>"))
.append(newline())
.append(miniMessage()
.deserialize(
"<gradient:aqua:#94d1ff>/miniplaceholders</gradient> <aqua>parse</aqua> <#8fadff><player | me></#8fadff> <#99ffb6><player></#99ffb6>"))
.append(newline())
.append(miniMessage()
.deserialize("<gradient:aqua:white:aqua><st><b> "))
.append(newline(), miniMessage().deserialize(
"<gradient:aqua:white:aqua><st><b> </st> <title> <st><b> </st>", Placeholder.component("title", TITLE)))
.append(newline(), miniMessage().deserialize(
"<gradient:#9694ff:#5269ff>Commands:</gradient>"))
.append(newline(), miniMessage().deserialize(
"<gradient:aqua:#94d1ff>/miniplaceholders</gradient> <aqua>help</aqua>"))
.append(newline(), miniMessage().deserialize(
"<gradient:aqua:#94d1ff>/miniplaceholders</gradient> <aqua>parse</aqua> <#8fadff><player | me></#8fadff> <#99ffb6><player></#99ffb6>"))
.append(newline(), miniMessage().deserialize(
"<gradient:aqua:white:aqua><st><b> "))
.build();
private static final Component INFO = AboutMenu.builder()
.title(miniMessage().deserialize("<gradient:#4d8bff:#a4ff96>MiniPlaceholders</gradient>"))
.description(text("MiniMessage Component-based Placeholders for PaperMC, Folia, Fabric, Velocity and Krypton platforms"))
.title(TITLE)
.description(text("MiniMessage Component-based Placeholders for Paper, Folia, Fabric, Velocity, Sponge and Krypton platforms"))
.credits("Author", AboutMenu.Credit.of("4drian3d").url("https://github.com/4drian3d"))
.credits("Contributors", AboutMenu.Credit.of("Sliman4"))
.buttons(
@@ -81,105 +80,86 @@ public final class PlaceholdersCommand<A> {
.build()
.toComponent();
public LiteralArgumentBuilder<A> asBuilder(String commandName){
return LiteralArgumentBuilder.<A>literal(commandName)
.requires(a -> permissionValue(a, "miniplaceholders.command") != TriState.FALSE)
.executes(cmd -> {
Audience source = getAudience(cmd.getSource());
source.sendMessage(INFO);
return Command.SINGLE_SUCCESS;
})
.then(LiteralArgumentBuilder.<A>literal("help")
.requires(src -> permissionValue(src, "miniplaceholders.command.help").toBooleanOrElse(false))
.executes(cmd -> {
getAudience(cmd.getSource()).sendMessage(HELP);
return Command.SINGLE_SUCCESS;
private Command.Builder<A> rootBuilder() {
return commandManager.commandBuilder(command);
}
public void register() {
new MinecraftExceptionHandler<A>()
.withDefaultHandlers()
.withDecorator(component -> Component.text().append(TITLE).appendSpace().append(component).build())
.apply(commandManager, AudienceProvider.nativeAudience());
commandManager.command(rootBuilder()
.permission(src -> {
if (hasPermission != null) {
return hasPermission.test(src, "miniplaceholders.command");
}
return src
.get(PermissionChecker.POINTER)
.map(checker -> checker.value("miniplaceholders.command"))
.orElse(TriState.FALSE) != TriState.FALSE;
})
)
.then(LiteralArgumentBuilder.<A>literal("parse")
.requires(cmd -> permissionValue(cmd, "miniplaceholders.command.parse").toBooleanOrElse(false))
.then(LiteralArgumentBuilder.<A>literal("me")
.requires(cmd -> permissionValue(cmd, "miniplaceholders.command.parse.me").toBooleanOrElse(false))
.then(RequiredArgumentBuilder.<A, String>argument("string", string())
.executes(cmd -> {
final String toParse = getString(cmd, "string");
final Component parsed = parseGlobal(toParse, getAudience(cmd.getSource()));
getAudience(cmd.getSource()).sendMessage(parsed);
return Command.SINGLE_SUCCESS;
.handler(handler -> handler.getSender().sendMessage(INFO)));
final CommandArgument<A, String> sourceArgument = StringArgument.<A>builder("source")
.single()
.withDefaultDescription(ArgumentDescription.of("The source from which the message will be parsed"))
.withSuggestionsProvider((ctx, st) -> {
final List<String> suggestions = playersSuggestions.get();
suggestions.add("me");
return suggestions;
})
.build();
final CommandArgument<A, String> stringArgument = StringArgument.<A>builder("message")
.greedy()
.withDefaultDescription(ArgumentDescription.of("Message to be parsed"))
.build();
commandManager.command(
rootBuilder().literal("parse")
.argument(sourceArgument)
.argument(stringArgument)
.permission("miniplaceholders.command.parse")
.handler(handler -> {
final String source = handler.get(sourceArgument);
final Audience objective = "me".equals(source)
? handler.getSender()
: toAudience.apply(source);
if (objective == null){
handler.getSender().sendMessage(text("You must specify a valid player", RED));
return;
}
final String toParse = handler.get(stringArgument);
final Component parsed = miniMessage().deserialize(
toParse,
MiniPlaceholders.getAudienceGlobalPlaceholders(objective)
);
handler.getSender().sendMessage(parsed);
})
)
)
.then(LiteralArgumentBuilder.<A>literal("player")
.requires(cmd -> permissionValue(cmd, "miniplaceholders.command.parse.player").toBooleanOrElse(false))
.then(RequiredArgumentBuilder.<A, String>argument("source", word())
.suggests((argument, builder) -> supplyAsync(() -> {
playersSuggestions.get().forEach(builder::suggest);
return builder.build();
}))
.then(RequiredArgumentBuilder.<A, String>argument("string", string())
.executes(cmd -> {
final Audience objective = toAudience.apply(getString(cmd, "source"));
if (objective == null){
getAudience(cmd.getSource()).sendMessage(text("You must specify a valid player", RED));
return -1;
}
final String toParse = cmd.getArgument("string", String.class);
final Component parsed = parseGlobal(toParse, objective);
getAudience(cmd.getSource()).sendMessage(parsed);
return Command.SINGLE_SUCCESS;
})
)
)
)
);
}
public LiteralCommandNode<A> asNode(String command) {
return asBuilder(command).build();
}
private Component parseGlobal(final String string, final Audience audience) {
return miniMessage().deserialize(
string,
TagResolver.resolver(
MiniPlaceholders.getGlobalPlaceholders(),
MiniPlaceholders.getAudiencePlaceholders(audience)
)
);
commandManager.command(
rootBuilder().literal("help")
.permission("miniplaceholders.command.help")
.handler(handler -> handler.getSender().sendMessage(HELP))
);
}
private Audience getAudience(final A possibleAudience) {
if (possibleAudience instanceof Audience audience) {
return audience;
}
final Audience audience = sourceToAudience.apply(possibleAudience);
return audience != null ? audience : Audience.empty();
}
private TriState permissionValue(final A source, final String permission) {
if (hasPermission != null) {
return TriState.byBoolean(hasPermission.test(source, permission));
}
return getAudience(source)
.get(PermissionChecker.POINTER)
.map(checker -> checker.value(permission))
.orElse(TriState.FALSE);
}
public static <A> Builder<A> builder() {
public static <A extends Audience> Builder<A> builder() {
return new Builder<>();
}
public final static class Builder<A> implements AbstractBuilder<PlaceholdersCommand<A>> {
private Supplier<Collection<String>> playersSuggestions;
public final static class Builder<A extends Audience> implements AbstractBuilder<PlaceholdersCommand<A>> {
private Supplier<ArrayList<String>> playersSuggestions;
private Function<String, Audience> toAudience;
private Function<A, Audience> fromAToAudience = a -> Audience.empty();
private BiPredicate<A, String> hasPermission;
private String command;
private CommandManager<A> commandManager;
private Builder() {}
public Builder<A> playerSuggestions(final Supplier<@NotNull Collection<@NotNull String>> playersSuggestions) {
public Builder<A> playerSuggestions(final Supplier<@NotNull ArrayList<@NotNull String>> playersSuggestions) {
this.playersSuggestions = playersSuggestions;
return this;
}
@@ -189,13 +169,18 @@ public final class PlaceholdersCommand<A> {
return this;
}
public Builder<A> fromSourceToAudience(final @NotNull Function<@NotNull A, @Nullable Audience> sourceToAudience) {
this.fromAToAudience = sourceToAudience;
public Builder<A> hasPermissionCheck(final @NotNull BiPredicate<@NotNull A, @NotNull String> hasPermission) {
this.hasPermission = hasPermission;
return this;
}
public Builder<A> hasPermissionCheck(final @NotNull BiPredicate<@NotNull A, @NotNull String> hasPermission) {
this.hasPermission = hasPermission;
public Builder<A> command(final String command) {
this.command = command;
return this;
}
public Builder<A> manager(CommandManager<A> commandManager) {
this.commandManager = commandManager;
return this;
}
@@ -204,8 +189,9 @@ public final class PlaceholdersCommand<A> {
return new PlaceholdersCommand<>(
requireNonNull(playersSuggestions),
requireNonNull(toAudience),
requireNonNull(fromAToAudience),
hasPermission
hasPermission,
command,
commandManager
);
}
}
+2 -6
View File
@@ -1,7 +1,3 @@
java.toolchain.languageVersion.set(JavaLanguageVersion.of(11))
tasks.compileJava {
options.encoding = Charsets.UTF_8.name()
options.release.set(11)
plugins {
id("miniplaceholders.base")
}
@@ -2,7 +2,7 @@ package io.github.miniplaceholders.connect;
public enum InternalPlatform {
PAPER, VELOCITY, KRYPTON, FABRIC;
PAPER, VELOCITY, KRYPTON, FABRIC, SPONGE;
private static InternalPlatform actualPlatform;
+1
View File
@@ -0,0 +1 @@
/run
+24 -18
View File
@@ -1,12 +1,9 @@
plugins {
id("fabric-loom") version "1.2.5"
id("miniplaceholders.auto.module")
id("fabric-loom")
alias(libs.plugins.shadow)
}
repositories {
maven("https://oss.sonatype.org/content/repositories/snapshots")
}
val shade: Configuration by configurations.creating
dependencies {
@@ -14,18 +11,31 @@ dependencies {
mappings(loom.officialMojangMappings())
modImplementation(libs.fabric.loader)
modImplementation(libs.fabric.api)
modImplementation(libs.adventure.platform.fabric)
include(libs.adventure.platform.fabric)
modImplementation(libs.luckopermissionsapi)
include(libs.luckopermissionsapi)
shadeModule(projects.miniplaceholdersCommon)
includeDependency(libs.adventure.platform.fabric)
includeDependency(libs.luckopermissionsapi)
includeDependency(libs.cloud.fabric)
includeDependency(libs.cloud.core)
includeDependency(libs.cloud.extras)
includeDependency(libs.desertwell)
shadeModule(projects.miniplaceholdersApi)
shadeModule(projects.miniplaceholdersCommon)
shadeModule(projects.miniplaceholdersConnect)
}
fun DependencyHandlerScope.shadeModule(module: ProjectDependency) {
shade(module)
implementation(module)
shade(module) {
isTransitive = false
}
implementation(module) {
isTransitive = false
}
}
fun DependencyHandlerScope.includeDependency(dependency: Any) {
modImplementation(dependency)
include(dependency)
}
tasks {
@@ -35,13 +45,10 @@ tasks {
expand("version" to project.version)
}
}
compileJava {
options.encoding = Charsets.UTF_8.name()
options.release.set(17)
}
remapJar {
inputFile.set(shadowJar.get().archiveFile)
archiveFileName.set("MiniPlaceholders-Fabric-mc${libs.versions.minecraft.get()}-v${project.version}.jar")
archiveFileName.set("MiniPlaceholders-Fabric-${project.version}.jar")
destinationDirectory.set(file("${project.rootDir}/jar"))
}
shadowJar {
configurations = listOf(shade)
@@ -50,5 +57,4 @@ tasks {
java {
withSourcesJar()
toolchain.languageVersion.set(JavaLanguageVersion.of(17))
}
@@ -1,12 +1,13 @@
package io.github.miniplaceholders.fabric;
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
import cloud.commandframework.fabric.FabricServerCommandManager;
import io.github.miniplaceholders.api.Expansion;
import io.github.miniplaceholders.common.PlaceholdersCommand;
import io.github.miniplaceholders.common.PlaceholdersPlugin;
import io.github.miniplaceholders.connect.InternalPlatform;
import me.lucko.fabric.api.permissions.v0.Permissions;
import net.fabricmc.api.ModInitializer;
import net.fabricmc.fabric.api.command.v2.CommandRegistrationCallback;
import net.fabricmc.fabric.api.event.lifecycle.v1.ServerLifecycleEvents;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
@@ -19,7 +20,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
public class FabricMod implements ModInitializer, PlaceholdersPlugin {
private final Logger logger = LoggerFactory.getLogger("miniplaceholders");
@@ -93,13 +96,18 @@ public class FabricMod implements ModInitializer, PlaceholdersPlugin {
@Override
public void registerPlatformCommand() {
CommandRegistrationCallback.EVENT.register((dispatcher, commandBuildContext, commandSelection) ->
dispatcher.register(PlaceholdersCommand.<CommandSourceStack>builder()
.hasPermissionCheck((source, permission) -> Permissions.check(source, permission, 4))
.toAudience(string -> this.minecraftServer.getPlayerList().getPlayerByName(string))
.playerSuggestions(() -> Arrays.asList(this.minecraftServer.getPlayerNames()))
.build()
.asBuilder("miniplaceholders"))
final FabricServerCommandManager<CommandSourceStack> commandManager = new FabricServerCommandManager<>(
AsynchronousCommandExecutionCoordinator.simpleCoordinator(),
Function.identity(),
Function.identity()
);
PlaceholdersCommand.<CommandSourceStack>builder()
.hasPermissionCheck((source, permission) -> Permissions.check(source, permission, 4))
.toAudience(string -> this.minecraftServer.getPlayerList().getPlayerByName(string))
.playerSuggestions(() -> new ArrayList<>(List.of(this.minecraftServer.getPlayerNames())))
.manager(commandManager)
.command("miniplaceholders")
.build()
.register();
}
}
+1 -1
View File
@@ -23,7 +23,7 @@
"fabricloader": ">=0.14.19",
"fabric": "*",
"java": ">=17",
"minecraft": "~1.19.4",
"minecraft": ">=1.19.4",
"fabric-permissions-api-v0": "*"
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
group = io.github.miniplaceholders
version = 2.1.0
description = MiniMessage Component-based Placeholders for PaperMC, Krypton and Velocity platforms
version = 2.2.1
description = MiniMessage Component-based Placeholders for Paper, Folia, Fabric, Sponge, velocity and Krypton platforms
org.gradle.jvmargs=-Xmx2G
+27 -14
View File
@@ -3,28 +3,29 @@ metadata.format.version = "1.1"
[versions]
velocity = "3.2.0-SNAPSHOT"
paper = "1.19.4-R0.1-SNAPSHOT"
krypton = "cbfaff4aa4"
minecraft = "1.19.4"
paper = "1.20.1-R0.1-SNAPSHOT"
krypton = "7796647145"
minecraft = "1.20.1"
runtask = "2.1.0"
pluginyml = "0.5.3"
userdev = "1.5.4"
pluginyml = "0.6.0"
userdev = "1.5.5"
blossom = "1.3.1"
indra = "3.0.1"
indra = "3.1.2"
shadow = "8.1.1"
jmh = "0.7.1"
dokka = "1.8.10"
dokka = "1.8.20"
adventure = "4.13.1"
adventurefabric = "5.8.0"
cloud = "1.8.3"
adventure = "4.14.0"
adventurefabric = "5.9.0"
brigadier = "1.0.500"
kotlin="1.8.21"
kotlin="1.9.0"
fabric-api = "0.79.0+1.20"
fabric-loader = "0.14.19"
fabric-api = "0.86.0+1.20.1"
fabric-loader = "0.14.21"
desertwell = "2.0.2"
desertwell = "2.0.4"
[libraries]
@@ -40,6 +41,16 @@ luckopermissionsapi = { group = "me.lucko", name = "fabric-permissions-api", ver
adventure-api = { group = "net.kyori", name = "adventure-api", version.ref = "adventure" }
adventure-minimesssage = { group = "net.kyori", name = "adventure-text-minimessage", version.ref = "adventure" }
adventure-platform-fabric = { group = "net.kyori", name = "adventure-platform-fabric", version.ref = "adventurefabric" }
adventure-serializer-legacy = { group = "net.kyori", name = "adventure-text-serializer-legacy", version.ref = "adventure" }
adventure-serializer-plain = { group = "net.kyori", name = "adventure-text-serializer-plain", version.ref = "adventure" }
cloud-core = { group = "cloud.commandframework", name = "cloud-core", version.ref = "cloud" }
cloud-annotations = { group = "cloud.commandframework", name = "cloud-annotations", version.ref = "cloud" }
cloud-velocity = { group = "cloud.commandframework", name = "cloud-velocity", version.ref = "cloud" }
cloud-paper = { group = "cloud.commandframework", name = "cloud-paper", version.ref = "cloud" }
cloud-fabric = { group = "cloud.commandframework", name = "cloud-fabric", version.ref = "cloud" }
cloud-sponge = { group = "cloud.commandframework", name = "cloud-sponge", version = "1.8.0-SNAPSHOT" }
cloud-extras = { group = "cloud.commandframework", name = "cloud-minecraft-extras", version.ref = "cloud" }
brigadier = { group = "com.mojang", name = "brigadier", version.ref = "brigadier" }
@@ -49,10 +60,12 @@ plugin-shadow = { group = "com.github.johnrengelman", name = "shadow", version.r
plugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
plugin-indra-common = { module = "net.kyori:indra-common", version.ref = "indra" }
plugin-indra-spotless = { module = "net.kyori:indra-licenser-spotless", version.ref = "indra" }
plugin-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:1.8.10"
plugin-dokka = "org.jetbrains.dokka:dokka-gradle-plugin:1.8.20"
desertwell = { group = "net.william278", name = "DesertWell", version.ref = "desertwell" }
junit-bom = "org.junit:junit-bom:5.9.3"
[plugins]
pluginyml = { id = "net.minecrell.plugin-yml.bukkit", version.ref = "pluginyml" }
Binary file not shown.
+2 -1
View File
@@ -1,6 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Vendored
+4 -1
View File
@@ -130,10 +130,13 @@ location of your Java installation."
fi
else
JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
if ! command -v java >/dev/null 2>&1
then
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
fi
# Increase the maximum file descriptors if we can.
@@ -73,13 +73,13 @@ class KotlinKryptonPlugin @Inject constructor(
}
override fun registerPlatformCommand() {
val command = PlaceholdersCommand.builder<CommandExecutionContext>()
/*val command = PlaceholdersCommand.builder<CommandExecutionContext>()
.fromSourceToAudience { it.sender }
.playerSuggestions { server.players.map { it.name } }
.toAudience { server.getPlayer(it) }
.build()
val brigadierCMD = BrigadierCommand.of(command.asNode("miniplaceholders"))
val meta = KryptonCommandMeta.Builder("miniplaceholders").build()
server.commandManager.register(brigadierCMD, meta)
server.commandManager.register(brigadierCMD, meta)*/
}
}
+5 -19
View File
@@ -1,34 +1,20 @@
plugins {
alias(libs.plugins.userdev)
id("miniplaceholders.auto.module")
id("miniplaceholders.shadow")
alias(libs.plugins.runpaper)
alias(libs.plugins.shadow)
}
dependencies {
paperweight.paperDevBundle(libs.versions.paper.get())
compileOnly(libs.paper)
implementation(projects.miniplaceholdersCommon)
implementation(projects.miniplaceholdersApi)
implementation(projects.miniplaceholdersConnect)
implementation(libs.cloud.paper)
}
java.toolchain.languageVersion.set(JavaLanguageVersion.of(17))
tasks {
assemble {
dependsOn(reobfJar)
}
compileJava {
options.encoding = Charsets.UTF_8.name()
options.release.set(17)
}
runServer {
minecraftVersion("1.19.4")
}
jar {
manifest {
attributes("Automatic-Module-Name" to "io.github.miniplaceholders.paper")
}
minecraftVersion("1.20.1")
}
processResources {
filesMatching("paper-plugin.yml") {
@@ -1,5 +1,7 @@
package io.github.miniplaceholders.paper;
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
import cloud.commandframework.paper.PaperCommandManager;
import io.github.miniplaceholders.api.Expansion;
import io.github.miniplaceholders.api.utils.TagsUtils;
import io.github.miniplaceholders.common.PlaceholdersCommand;
@@ -9,14 +11,17 @@ import io.papermc.paper.datapack.Datapack;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.TextComponent;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.minecraft.commands.CommandSourceStack;
import net.minecraft.server.MinecraftServer;
import org.bukkit.World;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.permissions.Permissible;
import org.bukkit.plugin.java.JavaPlugin;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.function.Function;
import java.util.stream.Collectors;
@SuppressWarnings("unused")
public final class PaperPlugin extends JavaPlugin implements PlaceholdersPlugin {
@@ -78,19 +83,28 @@ public final class PaperPlugin extends JavaPlugin implements PlaceholdersPlugin
@Override
@SuppressWarnings({"sonarlint(java:s1874)"})
public void registerPlatformCommand() {
MinecraftServer.getServer()
.getCommands()
.getDispatcher()
.register(PlaceholdersCommand.<CommandSourceStack>builder()
try {
PaperCommandManager<CommandSender> commandManager = new PaperCommandManager<>(
this,
AsynchronousCommandExecutionCoordinator.simpleCoordinator(),
Function.identity(),
Function.identity()
);
commandManager.registerBrigadier();
PlaceholdersCommand.<CommandSender>builder()
.playerSuggestions(() -> getServer().getOnlinePlayers()
.stream()
.map(Player::getName)
.toList())
.collect(Collectors.toCollection(ArrayList::new)))
.toAudience(st -> getServer().getPlayer(st))
.hasPermissionCheck((source, permission) -> source.getBukkitSender().hasPermission(permission))
.fromSourceToAudience(CommandSourceStack::getBukkitSender)
.hasPermissionCheck(Permissible::hasPermission)
.manager(commandManager)
.command("miniplaceholders")
.build()
.asBuilder("miniplaceholders")
);
.register();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
+23 -3
View File
@@ -1,3 +1,5 @@
@file:Suppress("UnstableApiUsage")
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
rootProject.name = "miniplaceholders-parent"
@@ -12,8 +14,25 @@ pluginManagement {
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven("https://papermc.io/repo/repository/maven-public/")
maven("https://repo.maven.apache.org/maven2/")
maven("https://jitpack.io") {
mavenContent {
includeGroup("net.william278")
}
}
maven("https://oss.sonatype.org/content/repositories/snapshots")
maven("https://repo.jpenilla.xyz/snapshots/")
}
}
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "0.5.0"
id("fabric-loom") version "1.3.8"
id("org.spongepowered.gradle.plugin") version "2.1.1"
id("org.gradle.toolchains.foojay-resolver-convention") version "0.6.0"
}
arrayOf(
@@ -23,8 +42,9 @@ arrayOf(
"common",
"paper",
"velocity",
"krypton",
"fabric"
//"krypton",
"fabric",
"sponge"
).forEach {
include("miniplaceholders-$it")
project(":miniplaceholders-$it").projectDir = file(it)
+2
View File
@@ -0,0 +1,2 @@
# run-paper files
/run
+47
View File
@@ -0,0 +1,47 @@
import org.spongepowered.gradle.plugin.config.PluginLoaders
import org.spongepowered.plugin.metadata.model.PluginDependency
plugins {
id("miniplaceholders.auto.module")
id("miniplaceholders.shadow")
id("org.spongepowered.gradle.plugin")
}
dependencies {
implementation(projects.miniplaceholdersCommon)
implementation(projects.miniplaceholdersApi)
implementation(projects.miniplaceholdersConnect)
implementation(libs.cloud.sponge)
}
sponge {
apiVersion("8.1.0")
license("GPL-3")
loader {
name(PluginLoaders.JAVA_PLAIN)
version("1.0")
}
plugin("miniplaceholders") {
displayName("MiniPlaceholders")
entrypoint("io.github.miniplaceholders.sponge.SpongePlugin")
description(project.description)
links {
homepage("https://github.com/MiniPlaceholders/MiniPlaceholders")
source("https://github.com/MiniPlaceholders/MiniPlaceholders")
issues("https://github.com/MiniPlaceholders/MiniPlaceholders/issues")
}
contributor("4drian3d") {
description("Lead Developer")
}
dependency("spongeapi") {
loadOrder(PluginDependency.LoadOrder.AFTER)
optional(false)
}
}
}
tasks {
shadowJar {
exclude("io/leangen/geantyref/**")
}
}
@@ -0,0 +1,116 @@
package io.github.miniplaceholders.sponge;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.sponge.SpongeCommandManager;
import com.google.inject.Inject;
import io.github.miniplaceholders.api.Expansion;
import io.github.miniplaceholders.api.utils.TagsUtils;
import io.github.miniplaceholders.common.PlaceholdersCommand;
import io.github.miniplaceholders.common.PlaceholdersPlugin;
import io.github.miniplaceholders.connect.InternalPlatform;
import net.kyori.adventure.audience.Audience;
import net.kyori.adventure.audience.ForwardingAudience;
import net.kyori.adventure.text.Component;
import org.apache.logging.log4j.Logger;
import org.jetbrains.annotations.NotNull;
import org.spongepowered.api.Server;
import org.spongepowered.api.command.Command;
import org.spongepowered.api.command.CommandCause;
import org.spongepowered.api.entity.living.player.server.ServerPlayer;
import org.spongepowered.api.event.Listener;
import org.spongepowered.api.event.lifecycle.RegisterCommandEvent;
import org.spongepowered.api.event.lifecycle.StartingEngineEvent;
import org.spongepowered.api.world.server.ServerWorld;
import org.spongepowered.plugin.PluginContainer;
import org.spongepowered.plugin.builtin.jvm.Plugin;
import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
@Plugin("miniplaceholders")
public class SpongePlugin implements PlaceholdersPlugin {
@Inject
private PluginContainer pluginContainer;
@Inject
private Logger logger;
private Server server;
@Listener
public void onServerStart(final StartingEngineEvent<Server> event) {
this.server = event.engine();
logger.info("Starting MiniPlaceholders Sponge");
InternalPlatform.platform(InternalPlatform.SPONGE);
this.loadDefaultExpansions();
}
private final AtomicInteger registration = new AtomicInteger(0);
@Listener
public void onCommandRegister(final RegisterCommandEvent<Command.Parameterized> event) {
if (registration.getAndIncrement() == 0) {
this.registerPlatformCommand();
}
}
@Override
public void loadDefaultExpansions() {
Expansion.builder("server")
.globalPlaceholder("name", TagsUtils.staticTag("Sponge"))
.globalPlaceholder("online", (queue, ctx) -> TagsUtils.staticTag(Component.text(server.onlinePlayers().size())))
.globalPlaceholder("max_players", (queue, ctx) -> TagsUtils.staticTag(Component.text(server.maxPlayers())))
.globalPlaceholder("unique_joins", (queue, ctx) -> TagsUtils.staticTag(Component.text(server.userManager().streamAll().count())))
.globalPlaceholder("has_whitelist", (queue, ctx) -> TagsUtils.staticTag(Component.text(server.isWhitelistEnabled())))
.globalPlaceholder("total_chunks", (queue, ctx) -> {
int chunkCount = 0;
for (ServerWorld world : server.worldManager().worlds()){
chunkCount += world.entities().size();
}
return TagsUtils.staticTag(Component.text(chunkCount));
})
.globalPlaceholder("total_entities", (queue, ctx) -> {
int entityCount = 0;
for (ServerWorld world : server.worldManager().worlds()){
entityCount += world.entities().size();
}
return TagsUtils.staticTag(Component.text(entityCount));
})
.globalPlaceholder("mspt", (queue, ctx) -> TagsUtils.staticTag(Component.text(server.averageTickTime())))
.build()
.register();
}
@Override
public void registerPlatformCommand() {
final SpongeCommandManager<AudienceHolder> commandManager = new SpongeCommandManager<>(
pluginContainer,
CommandExecutionCoordinator.simpleCoordinator(),
AudienceHolder::cause,
AudienceHolder::new
);
PlaceholdersCommand.<AudienceHolder>builder()
.manager(commandManager)
.command("miniplaceholders")
.playerSuggestions(() -> server.onlinePlayers()
.stream()
.map(ServerPlayer::name)
.collect(Collectors.toCollection(ArrayList::new)))
.toAudience(st -> server.player(st).orElse(null))
.hasPermissionCheck((holder, permission) -> holder.cause.hasPermission(permission))
.build()
.register();
}
record AudienceHolder(@NotNull CommandCause cause) implements ForwardingAudience.Single {
@Override
public @NotNull Audience audience() {
return cause.audience();
}
}
}
+3 -15
View File
@@ -1,6 +1,7 @@
plugins {
id("miniplaceholders.shadow")
id("miniplaceholders.auto.module")
alias(libs.plugins.runvelocity)
alias(libs.plugins.shadow)
}
dependencies {
@@ -9,23 +10,10 @@ dependencies {
implementation(projects.miniplaceholdersCommon)
implementation(projects.miniplaceholdersApi)
implementation(projects.miniplaceholdersConnect)
implementation(libs.cloud.velocity)
}
java.toolchain.languageVersion.set(JavaLanguageVersion.of(17))
tasks {
compileJava {
options.encoding = Charsets.UTF_8.name()
options.release.set(17)
}
jar {
manifest {
attributes("Automatic-Module-Name" to "io.github.miniplaceholders.velocity")
}
}
runVelocity {
velocityVersion(libs.versions.velocity.get())
}
@@ -1,7 +1,12 @@
package io.github.miniplaceholders.velocity;
import cloud.commandframework.execution.CommandExecutionCoordinator;
import cloud.commandframework.velocity.CloudInjectionModule;
import cloud.commandframework.velocity.VelocityCommandManager;
import com.google.inject.Inject;
import com.velocitypowered.api.command.BrigadierCommand;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.TypeLiteral;
import com.velocitypowered.api.command.CommandSource;
import com.velocitypowered.api.event.Subscribe;
import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
@@ -19,6 +24,10 @@ import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import org.slf4j.Logger;
import java.util.ArrayList;
import java.util.function.Function;
import java.util.stream.Collectors;
@Plugin(
name = "MiniPlaceholders",
id = "miniplaceholders",
@@ -28,6 +37,8 @@ import org.slf4j.Logger;
public final class VelocityPlugin implements PlaceholdersPlugin {
private final Logger logger;
private final ProxyServer proxy;
@Inject
private Injector injector;
@Inject
public VelocityPlugin(final Logger logger, final ProxyServer proxy) {
@@ -67,17 +78,25 @@ public final class VelocityPlugin implements PlaceholdersPlugin {
@Override
public void registerPlatformCommand() {
final BrigadierCommand brigadierCMD = new BrigadierCommand(
PlaceholdersCommand.<CommandSource>builder()
.playerSuggestions(() -> proxy.getAllPlayers()
.stream()
.map(Player::getUsername)
.toList())
.toAudience(st -> proxy.getPlayer(st).orElse(null))
.build()
.asNode("vminiplaceholders")
injector = injector.createChildInjector(
new CloudInjectionModule<>(
CommandSource.class,
CommandExecutionCoordinator.simpleCoordinator(),
Function.identity(),
Function.identity()
)
);
proxy.getCommandManager().register(brigadierCMD);
final VelocityCommandManager<CommandSource> commandManager = injector.getInstance(
Key.get(new TypeLiteral<>() {})
);
PlaceholdersCommand.<CommandSource>builder()
.playerSuggestions(() -> proxy.getAllPlayers()
.stream()
.map(Player::getUsername)
.collect(Collectors.toCollection(ArrayList::new)))
.toAudience(st -> proxy.getPlayer(st).orElse(null))
.command("vminiplaceholders")
.manager(commandManager)
.build().register();
}
}