Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions .github/workflows/compile_snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
environment:
name: development
url: https://repo.andrei1058.dev
url: https://repo.andrei1058.com
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
Expand All @@ -22,8 +22,7 @@ jobs:
distribution: 'temurin'
- name: Deploy snapshot with Maven
env:
MVN_REPO_USER: ${{ secrets.MVN_REPO_USER }}
MVN_REPO_PASS: ${{ secrets.MVN_REPO_PASS }}
MVN_REPO_TOKEN: ${{ secrets.MVN_REPO_TOKEN }}
ANDEV_RES_ID: 4
run: |
sudo apt install jq -y
Expand Down
5 changes: 2 additions & 3 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
environment:
name: production
url: https://repo.andrei1058.dev
url: https://repo.andrei1058.com
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
Expand All @@ -19,8 +19,7 @@ jobs:
distribution: 'temurin'
- name: Deploy with Maven
env:
MVN_REPO_USER: ${{ secrets.MVN_REPO_USER }}
MVN_REPO_PASS: ${{ secrets.MVN_REPO_PASS }}
MVN_REPO_TOKEN: ${{ secrets.MVN_REPO_TOKEN }}
ANDEV_API_TOKEN: ${{ secrets.ANDEV_API_TOKEN }}
J_DOCS_USER: ${{ secrets.J_DOCS_USER }}
J_DOCS_PASS: ${{ secrets.J_DOCS_PASS }}
Expand Down
5 changes: 2 additions & 3 deletions .github/workflows/deploy_snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ jobs:
runs-on: ubuntu-latest
environment:
name: development
url: https://repo.andrei1058.dev/snapshots
url: https://repo.andrei1058.com/snapshots
steps:
- uses: actions/checkout@v4
- name: Set up JDK 21
Expand All @@ -20,8 +20,7 @@ jobs:
distribution: 'temurin'
- name: Deploy snapshot with Maven
env:
MVN_REPO_USER: ${{ secrets.MVN_REPO_USER }}
MVN_REPO_PASS: ${{ secrets.MVN_REPO_PASS }}
MVN_REPO_TOKEN: ${{ secrets.MVN_REPO_TOKEN }}
ANDEV_RES_ID: 4
run: |
sudo apt install jq -y
Expand Down
39 changes: 36 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ This project is divided in several modules:
- `sidebar-v_1_21_R1` provides support for 1.21 and 1.21.1 (R1). Requires `sidebar-cmn1`.
- `sidebar-v_1_21_R2` provides support for 1.21.3 (R2). Requires `sidebar-cmn1`.
- `sidebar-v_1_21_R3` provides support for 1.21.4 (R3). Requires `sidebar-cmn1`.
- `sidebar-v26_1_2` provides support for 26.1.2. Requires `sidebar-cmn1`.

### IMPORTANT
It is really important to call Sidebar#remove(player) when a player leaves the server to avoid memory leaks.
Expand Down Expand Up @@ -86,9 +87,21 @@ public class MySidebar {
ChatColor.GREEN + "Hello {player}",
ChatColor.LIGHT_PURPLE + "Hello {player}"
}));
// a static line that rotates through multiple placeholder values
lines.add(new SidebarLine() {
@Override
public String getLine() {
return ChatColor.YELLOW + "Tip: {tip}";
}
});

List<PlaceholderProvider> placeholders = new ArrayList<>();
placeholders.add(new PlaceholderProvider("{player}", () -> receiver.getDisplayName()));
placeholders.add(new AlternatedPlaceholderProvider("{tip}",
() -> ChatColor.GOLD + "Mine blocks",
() -> ChatColor.GREEN + "Open crates",
() -> ChatColor.AQUA + "Visit spawn"
));

handle = MyPlugin.getSidebarManager().createSidebar(title, lines, placeholders);

Expand Down Expand Up @@ -139,6 +152,26 @@ public class MySidebar {
}
}
```

## Alternated placeholders
`AlternatedPlaceholderProvider` works like `PlaceholderProvider`, but rotates through multiple replacements.
It accepts both static `String[]` values and lazy `Callable<String>` replacements, so you can compute each value right before it is rendered.

The next value is selected every time the placeholder is parsed, which means it can be used anywhere internal placeholders are supported: sidebar titles, regular lines, animated lines, player tab formatting, and tab header/footer content.

```java
var tips = new AlternatedPlaceholderProvider("{tip}",
() -> "Mine blocks",
() -> "Open crates",
() -> "Visit spawn"
);
```

Refresh guidance:
- `Sidebar#refreshPlaceholders()` updates alternated placeholders in non-animated sidebar lines.
- `Sidebar#refreshAnimatedLines()` also advances alternated placeholders used inside `SidebarLineAnimated`.
- Re-sending tab header/footer or refreshing titles/tab animations re-parses alternated placeholders there as well.

An example of how you can refresh and manage your sidebar.

```java
Expand Down Expand Up @@ -261,11 +294,11 @@ Since 1.20.3 we can replace sidebar score numbers with string placeholders. You
<repositories>
<repository>
<id>andrei1058-snapshots</id>
<url>https://repo.andrei1058.dev/snapshots/</url>
<url>https://repo.andrei1058.com/snapshots/</url>
</repository>
<repository>
<id>andrei1058-releases</id>
<url>https://repo.andrei1058.dev/releases/</url>
<url>https://repo.andrei1058.com/releases/</url>
</repository>
</repositories>
```
Expand All @@ -275,7 +308,7 @@ Since 1.20.3 we can replace sidebar score numbers with string placeholders. You
<dependency>
<groupId>com.andrei1058.spigot.sidebar</groupId>
<artifactId>sidebar-base</artifactId>
<version>24.8</version> // make sure this is the latest
<version>26.5-SNAPSHOT</version> // make sure this is the latest
<scope>compile</scope>
</dependency>

Expand Down
6 changes: 3 additions & 3 deletions ci_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
</configuration>
</server>
<server>
<id>ftp-repo</id>
<username>${env.MVN_REPO_USER}</username>
<password>${env.MVN_REPO_PASS}</password>
<id>andrei1058-repo</id>
<username>token</username>
<password>${env.MVN_REPO_TOKEN}</password>
</server>
</servers>
</settings>
26 changes: 11 additions & 15 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
<groupId>com.andrei1058.spigot.sidebar</groupId>
<artifactId>sidebar-pom</artifactId>
<packaging>pom</packaging>
<version>25.2.2-SNAPSHOT</version>
<version>26.6-SNAPSHOT</version>
<modules>
<module>sidebar-base</module>
<module>sidebar-v26_1_2</module>
<module>sidebar-v1_21_R3</module>
<module>sidebar-v1_21_R2</module>
<module>sidebar-v1_21_R1</module>
Expand All @@ -36,6 +37,10 @@
<id>placeholderapi</id>
<url>https://repo.extendedclip.com/content/repositories/placeholderapi/</url>
</repository>
<repository>
<id>nms</id>
<url>https://repo.codemc.io/repository/nms/</url>
</repository>
</repositories>

<dependencies>
Expand All @@ -54,24 +59,15 @@
</dependencies>


<build>
<extensions>
<extension>
<groupId>org.apache.maven.wagon</groupId>
<artifactId>wagon-ftp</artifactId>
<version>3.5.3</version>
</extension>
</extensions>
</build>

<distributionManagement>
<repository>
<id>ftp-repo</id>
<url>ftp://andrei1058.dev/releases</url>
<id>andrei1058-repo</id>
<url>https://repo.andrei1058.com/releases</url>
</repository>
<snapshotRepository>
<id>ftp-repo</id>
<url>ftp://andrei1058.dev/snapshots</url>
<id>andrei1058-repo</id>
<url>https://repo.andrei1058.com/snapshots</url>
</snapshotRepository>
</distributionManagement>
</project>
</project>
15 changes: 13 additions & 2 deletions sidebar-base/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<parent>
<artifactId>sidebar-pom</artifactId>
<groupId>com.andrei1058.spigot.sidebar</groupId>
<version>25.2.2-SNAPSHOT</version>
<version>26.6-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

Expand All @@ -30,6 +30,12 @@
<version>2.11.6</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
<scope>test</scope>
</dependency>
</dependencies>


Expand All @@ -55,6 +61,11 @@
<target>20</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.5</version>
</plugin>
</plugins>
</build>
</project>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package com.andrei1058.spigot.sidebar;

import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;

public class AlternatedPlaceholderProvider extends PlaceholderProvider {

private final List<Callable<String>> replacements;
private int pos = -1;

/**
* Create an alternated placeholder provider.
* Every replacement will get the next value and then will repeat.
*
* @param placeholder placeholder with brackets.
* @param replacements replacement values.
*/
@SafeVarargs
public AlternatedPlaceholderProvider(String placeholder, Callable<String>... replacements) {
this(placeholder, null == replacements ? Collections.emptyList() : Arrays.asList(replacements.clone()));
}

/**
* Create an alternated placeholder provider.
* Every replacement will get the next value and then will repeat.
*
* @param placeholder placeholder with brackets.
* @param replacements replacement values.
*/
public AlternatedPlaceholderProvider(String placeholder, String[] replacements) {
this(placeholder, toCallables(replacements));
}

private AlternatedPlaceholderProvider(String placeholder, Collection<Callable<String>> replacements) {
super(placeholder, () -> null);
this.replacements = Collections.unmodifiableList(new ArrayList<>(replacements));
}

private static List<Callable<String>> toCallables(String[] replacements) {
if (null == replacements || replacements.length == 0) {
return Collections.emptyList();
}

List<Callable<String>> callables = new ArrayList<>(replacements.length);
for (String replacement : replacements) {
callables.add(() -> replacement);
}
return callables;
}

/**
* @return replacement.
*/
@NotNull
@Override
public String getReplacement() {
if (replacements.isEmpty()) {
return "";
}
Callable<String> replacement = replacements.get(++pos == replacements.size() ? pos = 0 : pos);
try {
String rep = null == replacement ? null : replacement.call();
return null == rep ? "null" : rep;
} catch (Exception e) {
return "-";
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package com.andrei1058.spigot.sidebar;

import java.util.*;

/**
* Pre-compiled placeholders for faster replacement.
*/
public class CompiledPlaceholders {
private final Map<Character, List<PlaceholderProvider>> map;
private final char[] startChars;

public CompiledPlaceholders(Collection<PlaceholderProvider> replacements) {
if (replacements == null || replacements.isEmpty()) {
this.map = Collections.emptyMap();
this.startChars = new char[0];
return;
}
this.map = new HashMap<>();
for (PlaceholderProvider provider : replacements) {
String placeholder = provider.getPlaceholder();
if (placeholder != null && !placeholder.isEmpty()) {
map.computeIfAbsent(placeholder.charAt(0), k -> new ArrayList<>()).add(provider);
}
}

Set<Character> startCharsSet = map.keySet();
this.startChars = new char[startCharsSet.size()];
int idx = 0;
for (char c : startCharsSet) {
startChars[idx++] = c;
}
}

public Map<Character, List<PlaceholderProvider>> getMap() {
return map;
}

public char[] getStartChars() {
return startChars;
}

public boolean isEmpty() {
return startChars.length == 0;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.andrei1058.spigot.sidebar;

import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.jetbrains.annotations.Nullable;

Expand All @@ -12,12 +13,26 @@ public interface PlayerTab {
@SuppressWarnings("unused")
void add(Player player);

/**
* Add an entity to the tab-list formatting.
*
* @param entity the entity to be formatted.
*/
void add(Entity entity);

/**
* Remove the given player from tab-list formatting.
* @param player to be removed.
*/
void remove(Player player);

/**
* Removes the given entity from the tab-list formatting.
*
* @param entity the entity to be removed.
*/
void remove(Entity entity);

/**
* PAPI subject.
* @param player papi target for placeholders.
Expand Down
Loading
Loading