mirror of
https://codeberg.org/Andre601/AdvancedServerList.git
synced 2026-11-05 17:02:34 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
571f9f6b38 | ||
|
|
6d7fbb8c25 | ||
|
|
d3d83e5e11 | ||
|
|
82fb9c90f4 | ||
|
|
6841a5a6e0 | ||
|
|
6f41cd4e3a | ||
|
|
379f36832e | ||
|
|
5d8a39cd22 | ||
|
|
9dba820840 | ||
|
|
58712ca5c5 | ||
|
|
e19e942799 | ||
|
|
03434130c4 | ||
|
|
99df25551a | ||
|
|
4f31e4ce6f | ||
|
|
ba097c538d | ||
|
|
aa52435591 | ||
|
|
f44194d24f | ||
|
|
0e2d760ea6 | ||
|
|
c1e7e6b3ff | ||
|
|
96d383a5a1 | ||
|
|
79ba7877bf | ||
|
|
86b9aaa7c6 | ||
|
|
0cb3c036af | ||
|
|
b1f7b75e2d | ||
|
|
e9bc72c165 | ||
|
|
93203249fe | ||
|
|
2523ccb425 | ||
|
|
94972dad31 | ||
|
|
f8ac310259 | ||
|
|
5d8f5d81ed | ||
|
|
3111d7933d | ||
|
|
55f7e17d34 | ||
|
|
0e88a50deb | ||
|
|
83f351de6d | ||
|
|
b96d1cb1a9 | ||
|
|
517ff1df82 | ||
|
|
e8c7c4ee18 | ||
|
|
da44eac70e | ||
|
|
e85c121ee4 | ||
|
|
0c175999fc | ||
|
|
9c3f237f6d | ||
|
|
777545c94f | ||
|
|
dd197609e1 | ||
|
|
14ee306463 | ||
|
|
a635aa8c91 | ||
|
|
050ac3262a | ||
|
|
89aa309c90 | ||
|
|
e9b004c3f2 | ||
|
|
3ecca64a3d | ||
|
|
96dcea4e5b | ||
|
|
400f4709f5 | ||
|
|
5d4307128b | ||
|
|
65c96690f6 | ||
|
|
483d582cd1 | ||
|
|
6f14e17ae7 | ||
|
|
ff32cc1005 | ||
|
|
bcc18d7738 | ||
|
|
629079b438 | ||
|
|
bce03b68a8 | ||
|
|
841c32de0d | ||
|
|
f321ef0162 | ||
|
|
eca32d1858 | ||
|
|
f2c1f6e491 | ||
|
|
af31aac07e | ||
|
|
f8db3e7706 | ||
|
|
3d3ea2913c | ||
|
|
7b7042a856 | ||
|
|
c66c4f21f3 | ||
|
|
890a3f7b46 | ||
|
|
73b969bc51 | ||
|
|
55c93d8d59 | ||
|
|
e1ed8c1cb2 | ||
|
|
e2a91a461a | ||
|
|
8a454004a4 | ||
|
|
8df862530d | ||
|
|
4a1c93fb1b | ||
|
|
e795cf31eb | ||
|
|
e8d93d064f | ||
|
|
6a2a90b868 | ||
|
|
9cea1d3841 | ||
|
|
7453b43d6b | ||
|
|
7e30f937bd | ||
|
|
176a8ac42e | ||
|
|
f480ff51e1 | ||
|
|
e72b772cb9 | ||
|
|
c91faa899e | ||
|
|
e5c6d77e3d | ||
|
|
e8ad2c8266 | ||
|
|
d244f2816a | ||
|
|
73f3172504 | ||
|
|
d7c9f73898 | ||
|
|
2b6818180f | ||
|
|
c7c14799e3 | ||
|
|
59774347f6 | ||
|
|
e45f9a1e73 | ||
|
|
a44235dc10 | ||
|
|
52569a3588 | ||
|
|
602a8e27ea | ||
|
|
81a23953e5 | ||
|
|
9daf8f3a3e | ||
|
|
3d5b4501e3 | ||
|
|
67047e9877 | ||
|
|
7fcb0e78e3 | ||
|
|
8b8018245e | ||
|
|
b34143d4f5 | ||
|
|
a33c096cf4 | ||
|
|
0957edbcd8 | ||
|
|
70adf4e216 | ||
|
|
da42e8c137 | ||
|
|
f4eecda209 | ||
|
|
b934d1a856 | ||
|
|
bbec0aa064 | ||
|
|
ba1f620eee | ||
|
|
f0281adf8a | ||
|
|
c702f61c21 | ||
|
|
dec23e0412 | ||
|
|
782dcb8382 | ||
|
|
e401d1f8c1 | ||
|
|
5e6654b3ef | ||
|
|
25a9e8ef63 | ||
|
|
558e47a7da | ||
|
|
740896c304 | ||
|
|
62d9aa81a3 | ||
|
|
7220b633cf | ||
|
|
0908ddad5e | ||
|
|
d1549b1441 | ||
|
|
57f618e7e2 | ||
|
|
911c64f7ad | ||
|
|
fdeeb35fa9 | ||
|
|
c2c653e613 | ||
|
|
8fa7c1593d | ||
|
|
b2dc74951f | ||
|
|
099c45e4c4 | ||
|
|
e38f6648ee | ||
|
|
2d701aa8a8 | ||
|
|
1f32c22ebf | ||
|
|
610d86ad1b | ||
|
|
658ec8dd74 | ||
|
|
85b7210e7c | ||
|
|
98b99b37de | ||
|
|
bc3aaa4d28 | ||
|
|
a3d0342f28 | ||
|
|
6e057422b6 | ||
|
|
7ee65c6c21 | ||
|
|
b4b754e483 | ||
|
|
b7c0c8a312 | ||
|
|
cf6006f9d6 | ||
|
|
6bf44f6208 | ||
|
|
428dd3cd06 | ||
|
|
871e2efbe2 | ||
|
|
a5b45e2c82 | ||
|
|
9feb3dfac6 | ||
|
|
5961d0dca0 | ||
|
|
ea0f0f09f4 |
No files matched your search
@@ -0,0 +1,43 @@
|
||||
name: "Deploy Wiki"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
tags-ignore:
|
||||
- "**"
|
||||
paths:
|
||||
- ".forgejo/workflows/deploy_wiki.yml"
|
||||
- "docs/**"
|
||||
- "domains"
|
||||
- "mkdocs.yml"
|
||||
- "requirements.txt"
|
||||
|
||||
jobs:
|
||||
deployWiki:
|
||||
runs-on: codeberg-tiny
|
||||
steps:
|
||||
- name: "Checkout Source Repository"
|
||||
uses: https://code.forgejo.org/actions/checkout@v4
|
||||
with:
|
||||
token: "${{ secrets.BOT_TOKEN }}"
|
||||
- name: "Checkout Target Repository"
|
||||
run: "git clone -b pages https://codeberg.org/Andre601/asl-docs site"
|
||||
- name: "Setup Python 3.x"
|
||||
uses: https://code.forgejo.org/actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: "Install Dependencies"
|
||||
run: "pip install -r requirements.txt"
|
||||
- name: "Build Website"
|
||||
run: "mkdocs build"
|
||||
- name: "Commit and Push"
|
||||
run: |
|
||||
git config --global user.email "andre_601-bot@noreply.codeberg.org"
|
||||
git config --global user.name "ASL Wiki Builder"
|
||||
mv domains site/.domains
|
||||
cd site
|
||||
git remote set-url origin https://${{ secrets.BOT_TOKEN }}@codeberg.org/Andre601/asl-docs
|
||||
git add --all
|
||||
git commit -m "Update Wiki ($( env TZ=Europe/Zurich date +"%d.%m.%Y %Z" ))"
|
||||
git push
|
||||
@@ -0,0 +1,116 @@
|
||||
name: Pull Request Preview
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types:
|
||||
- opened
|
||||
- reopened
|
||||
- synchronize
|
||||
paths:
|
||||
- ".forgejo/workflows/pr_preview.yml"
|
||||
- "docs/**"
|
||||
- "mkdocs.yml"
|
||||
- "preview_domains"
|
||||
- "requirements.txt"
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
BRANCH_NAME: "${{ github.event.repository.name }}/${{ github.event.pull_request.number }}"
|
||||
RUN_URL: "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_number }}"
|
||||
|
||||
jobs:
|
||||
createPreview:
|
||||
runs-on: codeberg-tiny
|
||||
steps:
|
||||
#
|
||||
# Finding and updating comment in Pull request.
|
||||
# If not found, have one created instead.
|
||||
#
|
||||
- name: "Find Comment"
|
||||
id: find-comment
|
||||
uses: https://github.com/peter-evans/find-comment@v3
|
||||
with:
|
||||
issue-number: "${{ github.event.pull_request.number }}"
|
||||
comment-author: "Andre_601-Bot"
|
||||
- name: "Create or update Comment"
|
||||
id: comment
|
||||
uses: https://github.com/peter-evans/create-or-update-comment@v4
|
||||
with:
|
||||
body: |-
|
||||
## Pull request Preview
|
||||
|
||||
Creating Preview for Pull request. Please wait...
|
||||
comment-id: "${{ steps.find-comment.outputs.comment-id }}"
|
||||
issue-number: "${{ github.event.pull_request.number }}"
|
||||
token: "${{ secrets.BOT_TOKEN }}"
|
||||
edit-mode: replace
|
||||
#
|
||||
# Setup source and target repository.
|
||||
# Build website and push.
|
||||
#
|
||||
- name: "Checkout Source Repository"
|
||||
uses: https://code.forgejo.org/actions/checkout@v4
|
||||
with:
|
||||
token: ${{ secrets.BOT_TOKEN }}
|
||||
fetch-depth: 0
|
||||
ref: "${{ github.event.pull_request.head.sha }}"
|
||||
- name: "Checkout Target Repository"
|
||||
run: |
|
||||
git clone https://codeberg.org/Andre601/preview site
|
||||
cd site
|
||||
git switch ${{ env.BRANCH_NAME }} 2>/dev/null || git switch -c ${{ env.BRANCH_NAME }}
|
||||
- name: "Setup Python 3.x"
|
||||
uses: https://code.forgejo.org/actions/setup-python@v5
|
||||
with:
|
||||
python-version: 3.x
|
||||
- name: "Install Dependencies"
|
||||
run: "pip install -r requirements.txt"
|
||||
- name: "Build Website"
|
||||
run: "mkdocs build"
|
||||
- name: "Commit and Push"
|
||||
run: |
|
||||
git config --global user.email "andre_601-bot@noreply.codeberg.org"
|
||||
git config --global user.name "PR Docs Preview Builder"
|
||||
mv preview_domains site/.domains
|
||||
cd site
|
||||
git remote add upstream https://${{ secrets.BOT_TOKEN }}@codeberg.org/Andre601/preview.git
|
||||
git add --all
|
||||
git commit -m "Update Preview for ${{ env.BRANCH_NAME }} ($( env TZ=Europe/Zurich date +"%d.%m.%Y %Z" ))"
|
||||
git push --set-upstream upstream ${{ env.BRANCH_NAME }} -f
|
||||
#
|
||||
# Update comment on success or failure.
|
||||
#
|
||||
- name: "Comment Success"
|
||||
uses: https://github.com/peter-evans/create-or-update-comment@v4
|
||||
with:
|
||||
body: |-
|
||||
## Pull request Preview
|
||||
|
||||
Pull request Preview created successfully!
|
||||
|
||||
| Name | Link |
|
||||
|---------|----------------------------------------------------------------------------------------------------------|
|
||||
| Commit | ${{ github.event.pull_request.head.sha }} |
|
||||
| Preview | https://preview.andre601.ch/@${{ github.event.repository.name }}~${{ github.event.pull_request.number }} |
|
||||
| Logs | ${{ env.RUN_URL }} |
|
||||
comment-id: "${{ steps.comment.outputs.comment-id }}"
|
||||
issue-number: "${{ github.event.pull_request.number }}"
|
||||
token: "${{ secrets.BOT_TOKEN }}"
|
||||
edit-mode: replace
|
||||
- name: "Comment Failure"
|
||||
if: ${{ failure() }}
|
||||
uses: https://github.com/peter-evans/create-or-update-comment@v4
|
||||
with:
|
||||
body: |-
|
||||
## Pull request Preview
|
||||
|
||||
Pull request Preview failed! Check the logs for details.
|
||||
|
||||
| Name | Link |
|
||||
|---------|-------------------------------------------|
|
||||
| Commit | ${{ github.event.pull_request.head.sha }} |
|
||||
| Logs | ${{ RUN_URL }} |
|
||||
comment-id: "${{ steps.comment.outputs.comment-id }}"
|
||||
issue-number: "${{ github.event.pull_request.number }}"
|
||||
token: "${{ secrets.BOT_TOKEN }}"
|
||||
edit-mode: replace
|
||||
@@ -98,6 +98,6 @@ Spanish Video by Ajneb97
|
||||
<img src="https://wsrv.nl/?url=https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/social/revolt-singular_vector.svg&h=48" alt="revolt" title="Join my Revolt Server">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://blobfox.coffee/@andre_601" target="_blank">
|
||||
<a href="https://swiss.social/@andre_601" target="_blank">
|
||||
<img src="https://wsrv.nl/?url=https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/social/mastodon-singular_vector.svg&h=48" alt="revolt" title="Chat with me on Mastodon">
|
||||
</a>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 71 KiB |
File renamed without changes.
@@ -5,20 +5,22 @@ when:
|
||||
steps:
|
||||
- name: "Build Jar and Upload"
|
||||
image: maven:3.9.9-eclipse-temurin-21
|
||||
secrets:
|
||||
- modrinth_api_token
|
||||
- hangar_api_token
|
||||
- discord_webhook_url
|
||||
environment:
|
||||
CODEBERG_API_TOKEN:
|
||||
from_secret: cb_token
|
||||
MODRINTH_API_TOKEN:
|
||||
from_secret: modrinth_api_token
|
||||
HANGAR_API_TOKEN:
|
||||
from_secret: hangar_api_token
|
||||
DISCORD_WEBHOOK_URL:
|
||||
from_secret: discord_webhook_url
|
||||
commands:
|
||||
- mvn clean install
|
||||
- cd version-uploader/target
|
||||
- mv VersionUploader.jar ../../
|
||||
- cd ../../
|
||||
- java -jar VersionUploader.jar --all
|
||||
- name: "Upload Jars to Codeber"
|
||||
- name: "Upload Jars to Codeberg"
|
||||
image: woodpeckerci/plugin-gitea-release
|
||||
settings:
|
||||
base_url: https://codeberg.org
|
||||
|
||||
File renamed without changes.
@@ -86,6 +86,9 @@ Below can you find a collection of videos made for my plugin. If you made a vide
|
||||
<details><summary>Click to show/hide Videos</summary>
|
||||
<p>
|
||||
|
||||
English Video by KasaiSora
|
||||
[](https://youtube.com/watch?v=9cU0uUWHOO0)
|
||||
|
||||
Spanish Video by Ajneb97
|
||||
[](https://youtube.com/watch?v=rIbljm_4HVI)
|
||||
|
||||
@@ -108,6 +111,6 @@ Spanish Video by Ajneb97
|
||||
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/social/revolt-singular_vector.svg" height="48" alt="revolt" title="Join my Revolt Server">
|
||||
</a>
|
||||
<br>
|
||||
<a href="https://blobfox.coffee/@andre_601" target="_blank">
|
||||
<a href="https://swiss.social/@andre_601" target="_blank">
|
||||
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact/social/mastodon-singular_vector.svg" height="48" alt="revolt" title="Chat with me on Mastodon">
|
||||
</a>
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
# Supported Versions
|
||||
|
||||
To ensure proper safety and support are only certain versions and Platforms of AdvancedServerList maintained and supported.
|
||||
|
||||
## Supported Plugin Versions
|
||||
|
||||
| Major Version | Supported |
|
||||
|---------------|-----------|
|
||||
| v5 | Yes |
|
||||
| v4 | Yes* |
|
||||
| v3 | Yes** |
|
||||
| v2 | No |
|
||||
| v1 | No |
|
||||
|
||||
\*Only receives support but no updates or bug fixes.
|
||||
\*\*Support ends at the end of 2024.
|
||||
|
||||
## Supported Server/Proxy Versions
|
||||
|
||||
| Server/Proxy Version* | Supported |
|
||||
|-----------------------|-----------|
|
||||
| 1.21.x | Yes |
|
||||
| 1.20.x | Yes |
|
||||
| 1.19.x | No |
|
||||
| 1.18.x | No |
|
||||
| 1.17.x | No |
|
||||
| 1.16.x | No |
|
||||
| 1.15.x | No |
|
||||
| 1.14.x | No |
|
||||
| 1.13.x | No |
|
||||
| 1.12.x | No |
|
||||
| 1.11.x | No |
|
||||
| 1.10.x | No |
|
||||
| 1.19.x | No |
|
||||
| 1.8.x | No |
|
||||
|
||||
\*Only the latest patch version is actively supported should "Supported" have "Yes".
|
||||
|
||||
## Supported Platforms
|
||||
|
||||
### Servers
|
||||
|
||||
| Server | Supported |
|
||||
|--------|-----------|
|
||||
| Spigot | No |
|
||||
| Paper | Yes |
|
||||
| Purpur | Yes* |
|
||||
| Mohist | No |
|
||||
|
||||
\*Support hasn't actively been tested, but should work without issues.
|
||||
|
||||
### Proxies
|
||||
|
||||
| Proxy | Supported |
|
||||
|------------|-----------|
|
||||
| BungeeCord | Yes** |
|
||||
| Waterfall | Yes** |
|
||||
| Velocity | Yes |
|
||||
|
||||
\*\*Platform version of this plugin is maintenance only, not receiving any bug fixes for major breaking changes anymore.
|
||||
+20
-22
@@ -31,32 +31,10 @@ import com.google.common.primitives.UnsignedLongs;
|
||||
import me.leoko.advancedban.manager.PunishmentManager;
|
||||
import me.leoko.advancedban.utils.Punishment;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.UUID;
|
||||
|
||||
public class AdvancedBanProvider implements PunishmentProvider{
|
||||
|
||||
private static PunishmentManager getAPI(){
|
||||
return PunishmentManager.get();
|
||||
}
|
||||
|
||||
private static String noDashesUUID(UUID uuid){
|
||||
return hexString(uuid.getMostSignificantBits()) + hexString(uuid.getLeastSignificantBits());
|
||||
}
|
||||
|
||||
private static Punishment mute(GenericPlayer player){
|
||||
return getAPI().getMute(noDashesUUID(player.getUUID()));
|
||||
}
|
||||
|
||||
private static Punishment ban(GenericPlayer player){
|
||||
return getAPI().getBan(noDashesUUID(player.getUUID()));
|
||||
}
|
||||
|
||||
private static String hexString(long unsigned){
|
||||
return Strings.padStart(UnsignedLongs.toString(unsigned, 16), 16, '0');
|
||||
}
|
||||
|
||||
@Override
|
||||
public String muted(GenericPlayer player){
|
||||
return String.valueOf(getAPI().isMuted(noDashesUUID(player.getUUID())));
|
||||
@@ -136,4 +114,24 @@ public class AdvancedBanProvider implements PunishmentProvider{
|
||||
|
||||
return ban.getDuration(fromStart);
|
||||
}
|
||||
|
||||
private PunishmentManager getAPI(){
|
||||
return PunishmentManager.get();
|
||||
}
|
||||
|
||||
private String noDashesUUID(UUID uuid){
|
||||
return hexString(uuid.getMostSignificantBits()) + hexString(uuid.getLeastSignificantBits());
|
||||
}
|
||||
|
||||
private Punishment mute(GenericPlayer player){
|
||||
return getAPI().getMute(noDashesUUID(player.getUUID()));
|
||||
}
|
||||
|
||||
private Punishment ban(GenericPlayer player){
|
||||
return getAPI().getBan(noDashesUUID(player.getUUID()));
|
||||
}
|
||||
|
||||
private String hexString(long unsigned){
|
||||
return Strings.padStart(UnsignedLongs.toString(unsigned, 16), 16, '0');
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,10 @@
|
||||
<id>sonatype</id>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>repo-sayandevelopment</id>
|
||||
<url>https://repo.sayandev.org/snapshots</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
@@ -124,6 +128,18 @@
|
||||
<version>2.9.0-4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sayandev</groupId>
|
||||
<artifactId>sayanvanish-api</artifactId>
|
||||
<version>1.6.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sayandev</groupId>
|
||||
<artifactId>sayanvanish-proxy-bungeecord</artifactId>
|
||||
<version>1.6.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Other -->
|
||||
<dependency>
|
||||
|
||||
+38
-5
@@ -41,20 +41,27 @@ import com.alessiodp.libby.Library;
|
||||
import de.myzelyam.api.vanish.BungeeVanishAPI;
|
||||
import net.kyori.adventure.platform.bungeecord.BungeeAudiences;
|
||||
import net.md_5.bungee.api.Favicon;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.config.ServerInfo;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import org.bstats.bungeecord.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.sayandev.sayanvanish.bungeecord.api.SayanVanishBungeeAPI;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
|
||||
private final PluginLogger logger = new BungeeLogger(this);
|
||||
private final Map<String, ServerPing> fetchedServers = new ConcurrentHashMap<>();
|
||||
|
||||
private boolean successfulLoad = false;
|
||||
|
||||
@@ -66,12 +73,13 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
|
||||
@Override
|
||||
public void onLoad(){
|
||||
logger.info("Loading libraries. This may take a while...");
|
||||
// Using getLogger() here, because PluginLogger requires MiniMessage, which isn't loaded at this stage.
|
||||
getLogger().info("Loading libraries. This may take a while...");
|
||||
successfulLoad = loadLibs();
|
||||
if(successfulLoad){
|
||||
logger.info("Library loading completed successfully!");
|
||||
getLogger().info("Library loading completed successfully!");
|
||||
}else{
|
||||
logger.warn("Library loading completed with errors!");
|
||||
getLogger().warning("Library loading completed with errors!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +87,7 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
public void onEnable(){
|
||||
if(!successfulLoad){
|
||||
logger.warn("There were issues during the plugins Loading-phase! Please see the console for possible reasons.");
|
||||
logger.warn("The plugin won't be enabled to avoid problems.");
|
||||
logger.warn("Aborting further enabling of the plugin to avoid errors.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -91,11 +99,14 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
@Override
|
||||
public void onDisable(){
|
||||
core.disable();
|
||||
getProxy().getScheduler().cancel(this);
|
||||
audiences.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadCommands(){
|
||||
getProxy().getPluginManager().registerCommand(this, new CmdAdvancedServerList(this));
|
||||
getPluginLogger().success("Registered <white>/advancedserverlist</white>!");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,6 +153,11 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
libraryManager.loadLibrary(lib);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScheduler(){
|
||||
getProxy().getScheduler().schedule(this, this::fetchServers, 0, 10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancedServerList<Favicon> getCore(){
|
||||
return core;
|
||||
@@ -195,11 +211,18 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
// Exclude players when PremiumVanish is enabled and player is hidden.
|
||||
if(getProxy().getPluginManager().getPlugin("PremiumVanish") != null){
|
||||
players.removeIf(BungeeVanishAPI::isInvisible);
|
||||
}else // Do the same if SayanVanish is enabled.
|
||||
if(getProxy().getPluginManager().getPlugin("SayanVanish") != null){
|
||||
players.removeIf(player -> SayanVanishBungeeAPI.getInstance().isVanished(player.getUniqueId()));
|
||||
}
|
||||
|
||||
return players.size();
|
||||
}
|
||||
|
||||
public Map<String, ServerPing> getFetchedServers(){
|
||||
return fetchedServers;
|
||||
}
|
||||
|
||||
private boolean loadLibs(){
|
||||
try{
|
||||
if(libraryManager == null){
|
||||
@@ -211,8 +234,18 @@ public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
|
||||
return true;
|
||||
}catch(Exception ex){
|
||||
logger.warn("Encountered an Exception while trying to load dependencies.", ex);
|
||||
getLogger().log(Level.WARNING, "Encountered an Exception while trying to load dependencies.", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void fetchServers(){
|
||||
fetchedServers.clear();
|
||||
getProxy().getServers().forEach((name, server) -> server.ping((ping, throwable) -> {
|
||||
if(throwable != null)
|
||||
return;
|
||||
|
||||
fetchedServers.put(name, ping);
|
||||
}));
|
||||
}
|
||||
}
|
||||
+1
@@ -107,6 +107,7 @@ public class BungeeEventWrapper implements GenericEventWrapper<Favicon, BungeePl
|
||||
for(int i = 0; i < players.length; i++){
|
||||
String parsed = ComponentParser.text(lines.get(i))
|
||||
.modifyText(text -> StringReplacer.replace(text, player, server))
|
||||
.modifyText(text -> parsePAPIPlaceholders(text, player))
|
||||
.toString();
|
||||
|
||||
ServerPing.PlayerInfo pi = new ServerPing.PlayerInfo(parsed, UUID.randomUUID());
|
||||
|
||||
+5
-4
@@ -27,6 +27,7 @@ package ch.andre601.advancedserverlist.bungeecord.logging;
|
||||
|
||||
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
@@ -55,21 +56,21 @@ public class BungeeLogger implements PluginLogger{
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... args){
|
||||
logger.info(String.format(msg, args));
|
||||
logger.info(ComponentParser.textFormatted(msg, args).toStringStriped());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... args){
|
||||
logger.warning(String.format(msg, args));
|
||||
logger.warning(ComponentParser.textFormatted(msg, args).toStringStriped());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable){
|
||||
logger.log(Level.WARNING, msg, throwable);
|
||||
logger.log(Level.WARNING, ComponentParser.text(msg).toStringStriped(), throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable, Object... args){
|
||||
logger.log(Level.WARNING, String.format(msg, args), throwable);
|
||||
logger.log(Level.WARNING, ComponentParser.textFormatted(msg, args).toStringStriped(), throwable);
|
||||
}
|
||||
}
|
||||
+1
-19
@@ -10,20 +10,14 @@ import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.chat.BaseComponent;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class BungeeProxyPlaceholders extends PlaceholderProvider{
|
||||
|
||||
private final Map<String, ServerPing> serverStates = new ConcurrentHashMap<>();
|
||||
private final BungeeCordCore plugin;
|
||||
|
||||
private BungeeProxyPlaceholders(BungeeCordCore plugin){
|
||||
super("proxy");
|
||||
|
||||
this.plugin = plugin;
|
||||
plugin.getProxy().getScheduler().schedule(plugin, this::fetchServerStates, 0, 10, TimeUnit.SECONDS);
|
||||
}
|
||||
|
||||
public static BungeeProxyPlaceholders init(BungeeCordCore plugin){
|
||||
@@ -36,7 +30,7 @@ public class BungeeProxyPlaceholders extends PlaceholderProvider{
|
||||
if(args.length < 2)
|
||||
return null;
|
||||
|
||||
ServerPing ping = serverStates.get(args[1]);
|
||||
ServerPing ping = plugin.getFetchedServers().get(args[1]);
|
||||
|
||||
return switch(args[0]){
|
||||
case "status" -> ping == null ? "offline" : "online";
|
||||
@@ -64,16 +58,4 @@ public class BungeeProxyPlaceholders extends PlaceholderProvider{
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private void fetchServerStates(){
|
||||
serverStates.clear();
|
||||
plugin.getProxy().getServers().forEach((name, server) -> server.ping((ping, throwable) -> {
|
||||
if(throwable != null){
|
||||
plugin.getPluginLogger().warn("Encountered an exception while fetching status of Server %s", throwable, name);
|
||||
return;
|
||||
}
|
||||
|
||||
serverStates.put(name, ping);
|
||||
}));
|
||||
}
|
||||
}
|
||||
+17
-5
@@ -41,7 +41,7 @@
|
||||
<properties>
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
<plugin.config.version>6</plugin.config.version>
|
||||
<plugin.config.version>7</plugin.config.version>
|
||||
</properties>
|
||||
|
||||
<repositories>
|
||||
@@ -77,9 +77,11 @@
|
||||
<dependency>
|
||||
<groupId>ch.andre601</groupId>
|
||||
<artifactId>expressionparser</artifactId>
|
||||
<version>1.4.3</version>
|
||||
<version>1.5.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Configuration -->
|
||||
<dependency>
|
||||
<groupId>org.spongepowered</groupId>
|
||||
<artifactId>configurate-yaml</artifactId>
|
||||
@@ -129,7 +131,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>33.3.1-jre</version>
|
||||
<version>33.4.0-jre</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -137,7 +139,7 @@
|
||||
<dependency>
|
||||
<groupId>net.william278</groupId>
|
||||
<artifactId>papiproxybridge</artifactId>
|
||||
<version>1.6.2</version>
|
||||
<version>1.7.2</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
@@ -157,7 +159,7 @@
|
||||
<dependency>
|
||||
<groupId>org.junit.jupiter</groupId>
|
||||
<artifactId>junit-jupiter-engine</artifactId>
|
||||
<version>5.11.1</version>
|
||||
<version>5.11.4</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
@@ -168,6 +170,16 @@
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>char-widths.json.gz</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<filtering>false</filtering>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
<includes>
|
||||
<include>char-widths.json.gz</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
|
||||
@@ -32,6 +32,7 @@ import ch.andre601.advancedserverlist.core.commands.CommandHandler;
|
||||
import ch.andre601.advancedserverlist.core.compat.maintenance.MaintenancePlaceholder;
|
||||
import ch.andre601.advancedserverlist.core.file.FileHandler;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.parsing.TextCenterUtil;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.ProfileConditionParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.handlers.PlayerHandler;
|
||||
|
||||
@@ -47,6 +48,8 @@ public class AdvancedServerList<F>{
|
||||
private final FileHandler fileHandler;
|
||||
private final CommandHandler commandHandler;
|
||||
private final PlayerHandler playerHandler;
|
||||
private final TextCenterUtil textCenterUtil;
|
||||
|
||||
private static final AdvancedServerListAPI api = AdvancedServerListAPI.get();
|
||||
private final ProfileConditionParser parser = ProfileConditionParser.create();
|
||||
|
||||
@@ -59,18 +62,18 @@ public class AdvancedServerList<F>{
|
||||
this.fileHandler = new FileHandler(this);
|
||||
this.commandHandler = new CommandHandler(this);
|
||||
this.playerHandler = new PlayerHandler(this);
|
||||
this.textCenterUtil = new TextCenterUtil(this);
|
||||
|
||||
plugin.getPluginLogger().info("Registering internal Placeholders...");
|
||||
|
||||
placeholders.forEach(this::addPlaceholder);
|
||||
|
||||
if(plugin.isPluginEnabled("Maintenance")){
|
||||
plugin.getPluginLogger().info("Found Maintenance Plugin. Registering extra Placeholder...");
|
||||
addPlaceholder(new MaintenancePlaceholder(this));
|
||||
}
|
||||
|
||||
plugin.getPluginLogger().info("Completed internal Placeholder registration!");
|
||||
|
||||
resolveVersion();
|
||||
getPlugin().getPluginLogger().info("Starting <white>AdvancedServerList v%s</white>...", version);
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -110,16 +113,20 @@ public class AdvancedServerList<F>{
|
||||
return updateChecker;
|
||||
}
|
||||
|
||||
public TextCenterUtil getTextCenterUtil(){
|
||||
return textCenterUtil;
|
||||
}
|
||||
|
||||
public void disable(){
|
||||
getPlugin().getPluginLogger().info("Saving playercache.json file...");
|
||||
getPlugin().getPluginLogger().info("[-] Saving <white>playercache.json</white> file...");
|
||||
getPlayerHandler().save();
|
||||
|
||||
if(updateChecker != null){
|
||||
getPlugin().getPluginLogger().info("Disabling Update Checker...");
|
||||
getPlugin().getPluginLogger().info("[-] Disabling Update Checker...");
|
||||
updateChecker.disable();
|
||||
}
|
||||
|
||||
getPlugin().getPluginLogger().info("AdvancedServerList disabled!");
|
||||
getPlugin().getPluginLogger().success("AdvancedServerList disabled!");
|
||||
}
|
||||
|
||||
public void clearFaviconCache(){
|
||||
@@ -131,66 +138,56 @@ public class AdvancedServerList<F>{
|
||||
}
|
||||
|
||||
private void load(){
|
||||
printBanner();
|
||||
resolveVersion();
|
||||
|
||||
getPlugin().getPluginLogger().info("Starting AdvancedServerList v%s...", version);
|
||||
getPlugin().getPluginLogger().info("Platform: %s", plugin.getPlatformInfo());
|
||||
|
||||
if(getFileHandler().loadConfig()){
|
||||
getPlugin().getPluginLogger().info("Successfully loaded config.yml!");
|
||||
}else{
|
||||
getPlugin().getPluginLogger().warn("Unable to load config.yml! Check previous lines for errors.");
|
||||
if(!getFileHandler().loadConfig()){
|
||||
getPlugin().getPluginLogger().failure("Unable to load <white>config.yml</white>! Check previous lines for errors.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(getFileHandler().isOldConfig()){
|
||||
getPlugin().getPluginLogger().info("Detected old config.yml. Attempting to migrate...");
|
||||
getPlugin().getPluginLogger().info("[-] Detected old <white>config.yml</white>. Attempting to migrate...");
|
||||
if(getFileHandler().migrateConfig()){
|
||||
getPlugin().getPluginLogger().info("Migration completed successfully!");
|
||||
getPlugin().getPluginLogger().success("Migration completed successfully!");
|
||||
}else{
|
||||
getPlugin().getPluginLogger().warn("Couldn't migrate config.yml! Check previous lines for errors.");
|
||||
getPlugin().getPluginLogger().failure("Couldn't migrate <white>config.yml</white>! Check previous lines for errors.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if(getFileHandler().getBool(true, "printBanner")){
|
||||
printBanner();
|
||||
}
|
||||
|
||||
getPlugin().getPluginLogger().info("Platform: <white>%s</white>", plugin.getPlatformInfo());
|
||||
getPlugin().getPluginLogger().info("");
|
||||
|
||||
if(getFileHandler().loadProfiles()){
|
||||
getPlugin().getPluginLogger().info("Successfully loaded %d profile(s)!", getFileHandler().getProfiles().size());
|
||||
getPlugin().getPluginLogger().success("Successfully loaded <white>%d</white> profile(s)!", getFileHandler().getProfiles().size());
|
||||
}else{
|
||||
getPlugin().getPluginLogger().warn("Unable to load profiles! Check previous lines for errors.");
|
||||
getPlugin().getPluginLogger().failure("Unable to load profiles! Check previous lines for errors.");
|
||||
return;
|
||||
}
|
||||
|
||||
getPlugin().loadFaviconHandler(this);
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading Commands...");
|
||||
plugin.loadCommands();
|
||||
getPlugin().getPluginLogger().info("Commands loaded!");
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading events...");
|
||||
plugin.loadEvents();
|
||||
getPlugin().getPluginLogger().info("Events loaded!");
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading playercache.json...");
|
||||
getPlayerHandler().load();
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading bStats metrics. Disable it in the global config under /plugins/bstats/");
|
||||
plugin.loadMetrics();
|
||||
getPlugin().getPluginLogger().info("Metrics loaded!");
|
||||
plugin.startScheduler();
|
||||
|
||||
getPlugin().getPluginLogger().info("AdvancedServerList is ready!");
|
||||
getPlugin().getPluginLogger().success("<green>AdvancedServerList is ready!");
|
||||
|
||||
if(getFileHandler().getBoolean("checkUpdates"))
|
||||
this.updateChecker = new UpdateChecker(this);
|
||||
}
|
||||
|
||||
private void printBanner(){
|
||||
getPlugin().getPluginLogger().info(" _____ _");
|
||||
getPlugin().getPluginLogger().info(" /\\ / ____| |");
|
||||
getPlugin().getPluginLogger().info(" / \\ | (___ | |");
|
||||
getPlugin().getPluginLogger().info(" / /\\ \\ \\___ \\| |");
|
||||
getPlugin().getPluginLogger().info(" / ____ \\ ____) | |____");
|
||||
getPlugin().getPluginLogger().info("/_/ \\_\\_____/|______|");
|
||||
getPlugin().getPluginLogger().info("<#3b90ff> __ _______ ___");
|
||||
getPlugin().getPluginLogger().info("<#3b90ff> /\\ \\ / ____|_| | |");
|
||||
getPlugin().getPluginLogger().info("<#3b90ff> / \\ \\ | (_(___ | | |");
|
||||
getPlugin().getPluginLogger().info("<#3b90ff> / /\\ \\ \\ \\___ \\ \\| | |");
|
||||
getPlugin().getPluginLogger().info("<#3b90ff> / ____ \\ \\ ____) | | |_|____");
|
||||
getPlugin().getPluginLogger().info("<#3b90ff>/_/_/ \\_\\_\\_____/_/|______|_|");
|
||||
getPlugin().getPluginLogger().info("");
|
||||
}
|
||||
|
||||
@@ -207,7 +204,6 @@ public class AdvancedServerList<F>{
|
||||
}
|
||||
|
||||
private void addPlaceholder(PlaceholderProvider placeholderProvider){
|
||||
getPlugin().getPluginLogger().info("Registering %s Placeholders...", placeholderProvider.getIdentifier());
|
||||
AdvancedServerList.getApi().addPlaceholderProvider(placeholderProvider);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,7 @@ package ch.andre601.advancedserverlist.core.check;
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
|
||||
import ch.andre601.advancedserverlist.core.objects.CacheUtil;
|
||||
import ch.andre601.advancedserverlist.core.objects.ValueCache;
|
||||
import com.google.gson.FieldNamingPolicy;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
@@ -59,7 +59,7 @@ public class UpdateChecker{
|
||||
|
||||
private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(new UpdateCheckThread());
|
||||
|
||||
private final CacheUtil<CompletableFuture<ModrinthVersion>> cache = new CacheUtil<>(Duration.ofMinutes(5));
|
||||
private final ValueCache<CompletableFuture<ModrinthVersion>> cache = new ValueCache<>(Duration.ofMinutes(5));
|
||||
|
||||
private final AdvancedServerList<?> core;
|
||||
private final PluginLogger logger;
|
||||
@@ -123,11 +123,11 @@ public class UpdateChecker{
|
||||
|
||||
private void startUpdateChecker(){
|
||||
executor.scheduleAtFixedRate(() -> {
|
||||
logger.info("Looking for an update...");
|
||||
logger.info("[-] Looking for an update...");
|
||||
|
||||
performUpdateCheck().whenComplete((version, throwable) -> {
|
||||
if(version == null || throwable != null){
|
||||
logger.warn("Failed to look for any updates. Check previous messages for causes.");
|
||||
logger.failure("Failed to look for any updates. Check previous messages for causes.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -136,9 +136,9 @@ public class UpdateChecker{
|
||||
int result = version.compare(core.getVersion());
|
||||
switch(result){
|
||||
case -1 -> printUpdateBanner(version);
|
||||
case 0 -> logger.info("You are running the latest version!");
|
||||
case 0 -> logger.success("You are running the latest version!");
|
||||
case 1 -> logger.info(
|
||||
"Your version (%s) seems to be newer than the latest release (%s). Are you running a dev build?",
|
||||
"[?] Your version (<white>%s</white>) seems to be newer than the latest release (<white>%s</white>). Are you running a dev build?",
|
||||
core.getVersion(), version.versionNumber()
|
||||
);
|
||||
}
|
||||
@@ -185,18 +185,18 @@ public class UpdateChecker{
|
||||
logger.warn("=======================================================================");
|
||||
logger.warn("You are running an outdated version of AdvancedServerList!");
|
||||
logger.warn("");
|
||||
logger.warn("Your version: %s", core.getVersion());
|
||||
logger.warn("Modrinth: %s", version.versionNumber());
|
||||
logger.warn("Your version: <white>%s</white>", core.getVersion());
|
||||
logger.warn("Modrinth: <white>%s</white>", version.versionNumber());
|
||||
logger.warn("");
|
||||
|
||||
if(!version.isRelease()){
|
||||
logger.warn("WARNING!");
|
||||
logger.warn("<bold>WARNING!</bold>");
|
||||
logger.warn("This is a %s version and may contain breaking changes and/or bugs!", version.versionType());
|
||||
logger.warn("");
|
||||
}
|
||||
|
||||
logger.warn("Download the latest version from here:");
|
||||
logger.warn("https://modrinth.com/plugin/advancedserverlist/version/%s", version.id());
|
||||
logger.warn("<white>https://modrinth.com/plugin/advancedserverlist/version/%s</white>", version.id());
|
||||
logger.warn("=======================================================================");
|
||||
}
|
||||
|
||||
|
||||
@@ -360,7 +360,7 @@ public class CommandHandler{
|
||||
sender.sendErrorMsg("<red>There was an error while creating the file</red> %s<red>!", copy);
|
||||
sender.sendErrorMsg("<red>Check console for further details.");
|
||||
|
||||
core.getPlugin().getPluginLogger().warn("Encountered IOException while creating file %s", ex, copy);
|
||||
core.getPlugin().getPluginLogger().warn("Encountered IOException while creating file <white>%s</white>", ex, copy);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -378,7 +378,7 @@ public class CommandHandler{
|
||||
sender.sendErrorMsg("<red>There was an error while loading the file</red> %s<red>!", copy);
|
||||
sender.sendErrorMsg("<red>Check console for further details.");
|
||||
|
||||
core.getPlugin().getPluginLogger().warn("Encountered IOException while loading file %s", ex, copy);
|
||||
core.getPlugin().getPluginLogger().warn("Encountered IOException while loading file <white>%s</white>", ex, copy);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -398,7 +398,7 @@ public class CommandHandler{
|
||||
sender.sendErrorMsg("<red>There was an Error while copying values from</red> %s <red>to</red> %s<red>.", name, copy);
|
||||
sender.sendErrorMsg("<red>Check console for details.");
|
||||
|
||||
core.getPlugin().getPluginLogger().warn("Encountered SerializationException while set values for %s!", ex, copy);
|
||||
core.getPlugin().getPluginLogger().warn("Encountered SerializationException while set values for <white>%s</white>!", ex, copy);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -410,7 +410,7 @@ public class CommandHandler{
|
||||
sender.sendErrorMsg("<red>There was an Error while trying to save</red> %s<red>!", copy);
|
||||
sender.sendErrorMsg("<red>Check console for details.");
|
||||
|
||||
core.getPlugin().getPluginLogger().warn("Encountered IOException while saving ConfigurationNode for %s!", ex, copy);
|
||||
core.getPlugin().getPluginLogger().warn("Encountered IOException while saving ConfigurationNode for <white>%s</white>!", ex, copy);
|
||||
}
|
||||
}
|
||||
default -> {
|
||||
|
||||
@@ -25,22 +25,24 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.compat.papi;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.objects.CacheUtil;
|
||||
import ch.andre601.advancedserverlist.core.objects.ValueCache;
|
||||
import com.google.common.cache.Cache;
|
||||
import com.google.common.cache.CacheBuilder;
|
||||
import net.william278.papiproxybridge.api.PlaceholderAPI;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.CompletionException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class PAPIUtil{
|
||||
|
||||
private static PAPIUtil instance;
|
||||
|
||||
private final CacheUtil<String> cache = new CacheUtil<>(Duration.ofSeconds(5));
|
||||
private final ValueCache<CompletableFuture<Set<String>>> serversCache = new ValueCache<>(Duration.ofSeconds(10));
|
||||
private final Cache<UUID, CompletableFuture<String>> textCache = CacheBuilder.newBuilder()
|
||||
.expireAfterWrite(Duration.ofSeconds(10))
|
||||
.build();
|
||||
private final PlaceholderAPI papi;
|
||||
|
||||
private PAPIUtil(){
|
||||
@@ -66,24 +68,11 @@ public class PAPIUtil{
|
||||
}
|
||||
|
||||
public String getServer(){
|
||||
return cache.get(() -> {
|
||||
List<String> servers;
|
||||
|
||||
try{
|
||||
Set<String> value = papi.getServers().getNow(null);
|
||||
if(value == null)
|
||||
return null;
|
||||
|
||||
servers = List.copyOf(value);
|
||||
}catch(CancellationException | CompletionException ex){
|
||||
return null;
|
||||
}
|
||||
|
||||
if(servers == null || servers.isEmpty())
|
||||
return null;
|
||||
|
||||
return servers.get(0);
|
||||
});
|
||||
Set<String> values = serversCache.get(papi::getServers).getNow(Collections.emptySet());
|
||||
if(values.isEmpty())
|
||||
return null;
|
||||
|
||||
return List.copyOf(values).get(0);
|
||||
}
|
||||
|
||||
public <P> P getPlayer(Collection<P> players){
|
||||
@@ -95,8 +84,8 @@ public class PAPIUtil{
|
||||
|
||||
public String parse(String text, UUID carrier, UUID player){
|
||||
try{
|
||||
return papi.formatPlaceholders(text, carrier, player).getNow(text);
|
||||
}catch(IllegalArgumentException | CancellationException | CompletionException ex){
|
||||
return textCache.get(player, () -> papi.formatPlaceholders(text, carrier, player)).getNow(text);
|
||||
}catch(ExecutionException ex){
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
+13
-5
@@ -36,6 +36,10 @@ import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileManager;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.JoinConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class PingEventHandler{
|
||||
|
||||
@@ -138,14 +142,18 @@ public class PingEventHandler{
|
||||
GenericServer finalServer = event.createGenericServer(online, max, host);
|
||||
|
||||
if(ProfileManager.checkOption(entry.motd()) && ignoreMaintenance(event, "motd")){
|
||||
logger.debug(PingEventHandler.class, "'motd' option present. Applying '%s'...", String.join("\\n", entry.motd()));
|
||||
logger.debug(PingEventHandler.class, "'motd' option present. Applying ['%s']...", String.join("', '", entry.motd()));
|
||||
|
||||
event.setMotd(
|
||||
ComponentParser.list(entry.motd())
|
||||
List<Component> motd = entry.motd().stream()
|
||||
.map(line -> ComponentParser.text(line)
|
||||
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
|
||||
.modifyText(text -> event.parsePAPIPlaceholders(text, player))
|
||||
.modifyText(text -> plugin.getCore().getTextCenterUtil().getCenteredText(text))
|
||||
.toComponent()
|
||||
);
|
||||
)
|
||||
.toList();
|
||||
|
||||
event.setMotd(Component.join(JoinConfiguration.separator(Component.newline()), motd));
|
||||
}
|
||||
|
||||
boolean hidePlayers = ProfileManager.checkOption(entry.hidePlayersEnabled());
|
||||
@@ -168,7 +176,7 @@ public class PingEventHandler{
|
||||
}
|
||||
|
||||
if(ProfileManager.checkOption(entry.players()) && !hidePlayers && ignoreMaintenance(event, "playerCountHover")){
|
||||
logger.debug(PingEventHandler.class, "'playerCount -> hover' option set. Applying '%s'...", String.join("\\n", entry.players()));
|
||||
logger.debug(PingEventHandler.class, "'playerCount -> hover' option set. Applying ['%s']...", String.join("', '", entry.players()));
|
||||
|
||||
event.setPlayers(entry.players(), player, server);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,8 @@ public class ConfigMigrator{
|
||||
public static ConfigurationTransformation.Versioned create(){
|
||||
return ConfigurationTransformation.versionedBuilder()
|
||||
.versionKey("configVersion")
|
||||
.addVersion(LATEST, fiveToSix())
|
||||
.addVersion(LATEST, sixToSeven())
|
||||
.addVersion(6, fiveToSix())
|
||||
.addVersion(5, fourToFive())
|
||||
.addVersion(4, threeToFour())
|
||||
.addVersion(3, twoToThree())
|
||||
@@ -54,6 +55,16 @@ public class ConfigMigrator{
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ConfigurationTransformation sixToSeven(){
|
||||
return ConfigurationTransformation.builder()
|
||||
.addAction(NodePath.path(), (path, value) -> {
|
||||
value.node("printBanner").set(true);
|
||||
|
||||
return null;
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ConfigurationTransformation fiveToSix(){
|
||||
return ConfigurationTransformation.builder()
|
||||
.addAction(NodePath.path("disableDuringMaintenance"), (path, value) -> {
|
||||
@@ -122,7 +133,7 @@ public class ConfigMigrator{
|
||||
versioned.apply(node);
|
||||
final int endVersion = versioned.version(node);
|
||||
if(startVersion < endVersion)
|
||||
logger.info("Migrated config.yml from v" + startVersion + " to v" + endVersion);
|
||||
logger.success("Successfully migrated config from <white>v%d</white> to <white>v%d</white>", startVersion, endVersion);
|
||||
}
|
||||
|
||||
return node;
|
||||
|
||||
@@ -72,7 +72,6 @@ public class FileHandler{
|
||||
}
|
||||
|
||||
public boolean loadConfig(){
|
||||
logger.info("Loading config.yml...");
|
||||
File folder = plugin.getPlugin().getFolderPath().toFile();
|
||||
if(!folder.exists() && !folder.mkdirs()){
|
||||
logger.warn("Couldn't create folder for plugin. Is it missing Write permissions?");
|
||||
@@ -87,7 +86,7 @@ public class FileHandler{
|
||||
}
|
||||
|
||||
Files.copy(stream, config);
|
||||
logger.info("Created new config.yml!");
|
||||
logger.success("Created new config.yml!");
|
||||
}catch(IOException ex){
|
||||
logger.warn("Cannot create config.yml for plugin.", ex);
|
||||
return false;
|
||||
@@ -98,7 +97,7 @@ public class FileHandler{
|
||||
}
|
||||
|
||||
public boolean loadProfiles(){
|
||||
logger.info("Loading profiles...");
|
||||
logger.info("[-] Loading profiles...");
|
||||
|
||||
if(createFile("default.yml")){
|
||||
return reloadProfiles();
|
||||
@@ -109,7 +108,7 @@ public class FileHandler{
|
||||
|
||||
public boolean createFile(String name){
|
||||
if(Files.notExists(profilesFolder) && profilesFolder.toFile().mkdirs()){
|
||||
logger.info("Successfully created profiles folder.");
|
||||
logger.debugSuccess(FileHandler.class, "Successfully created profiles folder.");
|
||||
}
|
||||
|
||||
File file = new File(profilesFolder.toFile(), name);
|
||||
@@ -126,7 +125,7 @@ public class FileHandler{
|
||||
Files.copy(stream, profilesFolder.resolve(name));
|
||||
return true;
|
||||
}catch(IOException ex){
|
||||
logger.warn("Encountered IOException while trying to create file %s", ex, name);
|
||||
logger.warn("Encountered IOException while trying to create file <white>%s</white>", ex, name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -160,7 +159,7 @@ public class FileHandler{
|
||||
|
||||
File[] files = profilesFolder.toFile().listFiles(((dir, name) -> name.endsWith(".yml")));
|
||||
if(files == null || files.length == 0){
|
||||
logger.warn("Cannot load files from profiles folder! No valid YAML files present.");
|
||||
logger.failure("Cannot load files from profiles folder! No valid YAML files present.");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -170,11 +169,11 @@ public class FileHandler{
|
||||
continue;
|
||||
|
||||
profiles.add(ServerListProfile.Builder.resolve(file.getName(), tmp, logger).build());
|
||||
logger.info("Loaded '%s'!", file.getName());
|
||||
logger.debugSuccess(FileHandler.class, "Loaded '<white>%s</white>'!", file.getName());
|
||||
}
|
||||
|
||||
if(profiles.isEmpty()){
|
||||
logger.warn("Couldn't load any profile from profiles folder!");
|
||||
logger.failure("Couldn't load any profile from profiles folder!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -191,7 +190,7 @@ public class FileHandler{
|
||||
try{
|
||||
return loader.load();
|
||||
}catch(IOException ex){
|
||||
logger.warn("Cannot load '%s' due to an IOException!", ex, path.toFile().getName());
|
||||
logger.warn("Cannot load '<white>%s</white>' due to an IOException!", ex, path.toFile().getName());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -218,11 +217,11 @@ public class FileHandler{
|
||||
}
|
||||
|
||||
private boolean makeBackup(){
|
||||
logger.info("Making backup of old config.yml...");
|
||||
logger.info("[-] Making backup of old config.yml...");
|
||||
|
||||
File backups = plugin.getPlugin().getFolderPath().resolve("backups").toFile();
|
||||
if(!backups.exists() && !backups.mkdirs()){
|
||||
logger.warn("Cannot create backups folder for migration!");
|
||||
logger.failure("Cannot create backups folder for migration!");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -231,16 +230,16 @@ public class FileHandler{
|
||||
File configBackup = new File(backups, "config_" + date.replace(":", "_") + ".yml");
|
||||
try{
|
||||
if(!configBackup.exists() && !configBackup.createNewFile()){
|
||||
logger.warn("Cannot create backup file for config.yml!");
|
||||
logger.failure("Cannot create backup file for config.yml!");
|
||||
return false;
|
||||
}
|
||||
|
||||
Files.copy(config, configBackup.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
logger.info("Saved backup as '%s'!", configBackup.getName());
|
||||
logger.success("Saved backup as '<white>%s</white>'!", configBackup.getName());
|
||||
|
||||
return true;
|
||||
}catch(IOException ex){
|
||||
logger.warn("Encountered IOException while trying to create a backup.", ex);
|
||||
logger.failure("Encountered IOException while trying to create a backup.", ex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,10 +27,18 @@ package ch.andre601.advancedserverlist.core.interfaces;
|
||||
|
||||
public interface PluginLogger{
|
||||
|
||||
default void debugSuccess(Class<?> clazz, String msg, Object... args){
|
||||
debug(clazz, "[<green>✓</green>] " + msg, args);
|
||||
}
|
||||
|
||||
void debug(Class<?> clazz, String msg, Object... args);
|
||||
|
||||
void debugWarn(Class<?> clazz, String msg, Object... args);
|
||||
|
||||
default void success(String msg, Object... args){
|
||||
info("[<green>✓</green>] " + msg, args);
|
||||
}
|
||||
|
||||
void info(String msg, Object... args);
|
||||
|
||||
void warn(String msg, Object... args);
|
||||
@@ -38,4 +46,8 @@ public interface PluginLogger{
|
||||
void warn(String msg, Throwable throwable);
|
||||
|
||||
void warn(String msg, Throwable throwable, Object... args);
|
||||
|
||||
default void failure(String msg, Object... args){
|
||||
warn("[<red>x</red>] " + msg, args);
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -29,14 +29,14 @@ import java.util.Locale;
|
||||
|
||||
public abstract class PluginCommand{
|
||||
|
||||
private final String argument;
|
||||
private final String name;
|
||||
|
||||
public PluginCommand(String argument){
|
||||
this.argument = argument;
|
||||
public PluginCommand(String name){
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String name(){
|
||||
return argument;
|
||||
return name;
|
||||
}
|
||||
|
||||
public String permission(){
|
||||
|
||||
@@ -46,6 +46,8 @@ public interface PluginCore<F>{
|
||||
|
||||
void downloadLibrary(String groupId, String artifactId, String version);
|
||||
|
||||
void startScheduler();
|
||||
|
||||
AdvancedServerList<F> getCore();
|
||||
|
||||
Path getFolderPath();
|
||||
|
||||
+12
-12
@@ -56,7 +56,7 @@ public class MiniMOTDConfigMigrator{
|
||||
|
||||
Path mainConf = core.getPlugin().getFolderPath().getParent().resolve(folder).resolve("main.conf");
|
||||
if(!Files.exists(mainConf)){
|
||||
logger.warn("[Migrator - MiniMOTD] Cannot find a main.conf file in /plugins/%s/ folder.", folder);
|
||||
logger.warn("[<white>Migrator - MiniMOTD</white>] Cannot find a main.conf file in <white>/plugins/%s/</white> folder.", folder);
|
||||
sender.sendErrorMsg(" -> <red>No main.conf file found.");
|
||||
return false;
|
||||
}
|
||||
@@ -76,13 +76,13 @@ public class MiniMOTDConfigMigrator{
|
||||
|
||||
config = node.get(MiniMOTDConfig.class);
|
||||
}catch(IOException ex){
|
||||
logger.warn("[Migrator - MiniMOTD] Encountered IOException while loading main.conf file.", ex);
|
||||
logger.warn("[<white>Migrator - MiniMOTD</white>] Encountered IOException while loading main.conf file.", ex);
|
||||
sender.sendErrorMsg(" -> <red>IOException while loading</red> main.conf <red>file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(config == null){
|
||||
logger.warn("[Migrator - MiniMOTD] Retrieved main.conf file returned null.");
|
||||
logger.warn("[<white>Migrator - MiniMOTD</white>] Retrieved main.conf file returned null.");
|
||||
sender.sendErrorMsg(" -> <red>Received invalid</red> main.conf <red>file.");
|
||||
return false;
|
||||
}
|
||||
@@ -110,14 +110,14 @@ public class MiniMOTDConfigMigrator{
|
||||
if(config.iconEnabled()){
|
||||
if(config.motds().size() == 1){
|
||||
MiniMOTDConfig.Motd motd = config.motds().get(0);
|
||||
if(!motd.icon().isEmpty() && !motd.icon().equalsIgnoreCase("random")){
|
||||
if(!motd.icon().isEmpty()){
|
||||
profileBuilder.favicon(motd.icon());
|
||||
}
|
||||
}else
|
||||
if(config.motds().size() > 1){
|
||||
for(int i = 0; i < config.motds().size(); i++){
|
||||
MiniMOTDConfig.Motd motd = config.motds().get(i);
|
||||
if(!motd.icon().isEmpty() && !motd.icon().equalsIgnoreCase("random")){
|
||||
if(!motd.icon().isEmpty()){
|
||||
profilesBuilders.get(i).favicon(motd.icon());
|
||||
}
|
||||
}
|
||||
@@ -147,14 +147,14 @@ public class MiniMOTDConfigMigrator{
|
||||
|
||||
boolean profilesInvalid = profiles.isEmpty() || profiles.stream().allMatch(ProfileEntry::isInvalid);
|
||||
if(entry.isInvalid() && profilesInvalid){
|
||||
logger.warn("[Migrator - MiniMOTD] Main ProfileEntry was invalid and profiles were empty.");
|
||||
logger.warn("[<white>Migrator - MiniMOTD</white>] Main ProfileEntry was invalid and profiles were empty.");
|
||||
sender.sendErrorMsg(" -> <red>Received invalid configuration.");
|
||||
return false;
|
||||
}
|
||||
|
||||
Path profile = core.getPlugin().getFolderPath().resolve("profiles").resolve("minimotd_migrated.yml");
|
||||
if(Files.exists(profile)){
|
||||
logger.warn("[Migrator - MiniMOTD] Cannot create new file minimotd_migrated.yml. One with the same name is already present.");
|
||||
logger.warn("[<white>Migrator - MiniMOTD</white>] Cannot create new file minimotd_migrated.yml. One with the same name is already present.");
|
||||
sender.sendErrorMsg(" -> <red>File</red> minimotd_migrated.yml <red>already present.");
|
||||
|
||||
return false;
|
||||
@@ -163,7 +163,7 @@ public class MiniMOTDConfigMigrator{
|
||||
try{
|
||||
Files.createFile(profile);
|
||||
}catch(IOException ex){
|
||||
logger.warn("[Migrator - MiniMOTD] Encountered an IOException while trying to create file minimotd_migrated.yml.", ex);
|
||||
logger.warn("[<white>Migrator - MiniMOTD</white>] Encountered an IOException while trying to create file minimotd_migrated.yml.", ex);
|
||||
sender.sendErrorMsg(" -> <red>File creation error.");
|
||||
|
||||
return false;
|
||||
@@ -180,14 +180,14 @@ public class MiniMOTDConfigMigrator{
|
||||
try{
|
||||
migrated = yamlLoader.load();
|
||||
}catch(IOException ex){
|
||||
logger.warn("[Migrator - MiniMOTD] Encountered an IOException while trying to load file minimotd_migrated.yml.", ex);
|
||||
logger.warn("[<white>Migrator - MiniMOTD</white>] Encountered an IOException while trying to load file minimotd_migrated.yml.", ex);
|
||||
sender.sendErrorMsg(" -> <red>File loading error.");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if(migrated == null){
|
||||
logger.warn("[Migrator - MiniMOTD] Cannot migrate Configuration. ConfigurationNode was null.");
|
||||
logger.warn("[<white>Migrator - MiniMOTD</white>] Cannot migrate Configuration. ConfigurationNode was null.");
|
||||
sender.sendErrorMsg(" -> <red>File loading error.");
|
||||
|
||||
return false;
|
||||
@@ -202,7 +202,7 @@ public class MiniMOTDConfigMigrator{
|
||||
|
||||
migrated.set(entry);
|
||||
}catch(SerializationException ex){
|
||||
logger.warn("[Migrator - MiniMOTD] Encountered a SerializationException while setting values.", ex);
|
||||
logger.warn("[<white>Migrator - MiniMOTD</white>] Encountered a SerializationException while setting values.", ex);
|
||||
sender.sendErrorMsg(" -> <red>Error while updating file</red> minimotd_migrated.yml<red>.");
|
||||
|
||||
return false;
|
||||
@@ -214,7 +214,7 @@ public class MiniMOTDConfigMigrator{
|
||||
|
||||
return true;
|
||||
}catch(IOException ex){
|
||||
logger.warn("[Migrator - MiniMOTD] Encountered an IOException while trying to save new file minimotd_migrated.yml.", ex);
|
||||
logger.warn("[<white>Migrator - MiniMOTD</white>] Encountered an IOException while trying to save new file minimotd_migrated.yml.", ex);
|
||||
sender.sendErrorMsg(" -> <red>File saving error.");
|
||||
|
||||
return false;
|
||||
|
||||
+47
-41
@@ -59,26 +59,55 @@ public class SLPConfigMigrator{
|
||||
"(?<end>#[a-fA-F0-9]{6})" + // Ending color
|
||||
"%" +
|
||||
"(?<text>.+?)" + // Text
|
||||
"%gradient%");
|
||||
"%gradient%"
|
||||
);
|
||||
|
||||
private static final Map<String, String> STATIC_REPLACEMENTS = Map.of(
|
||||
"%player%", "${player name}",
|
||||
"%uuid%", "${player uuid}",
|
||||
"%_uuid_%", "${player uuid}",
|
||||
"%online%", "${server playersOnline}",
|
||||
"%max%", "${server playersMax}");
|
||||
"%max%", "${server playersMax}"
|
||||
);
|
||||
private static final Map<String, String> COLOR_TO_MINIMESSAGE_TAG = new HashMap<>(){{
|
||||
// Color Codes.
|
||||
put("a", "<green>");
|
||||
put("b", "<aqua>");
|
||||
put("c", "<red>");
|
||||
put("d", "<light_purple>");
|
||||
put("e", "<yellow>");
|
||||
put("f", "<white>");
|
||||
put("0", "<black>");
|
||||
put("1", "<dark_blue>");
|
||||
put("2", "<dark_green>");
|
||||
put("3", "<dark_aqua>");
|
||||
put("4", "<dark_red>");
|
||||
put("5", "<dark_purple>");
|
||||
put("6", "<gold>");
|
||||
put("7", "<grey>");
|
||||
put("8", "<dark_grey>");
|
||||
put("9", "<blue>");
|
||||
|
||||
// Formatting Codes
|
||||
put("k", "<obfuscated>");
|
||||
put("l", "<bold>");
|
||||
put("m", "<strikethrough>");
|
||||
put("n", "<underlined>");
|
||||
put("o", "<italic>");
|
||||
put("r", "<reset>");
|
||||
}};
|
||||
|
||||
public static int migrate(AdvancedServerList<?> core, CmdSender sender){
|
||||
ServerListPlusCore slpCore = ServerListPlusCore.getInstance();
|
||||
PluginLogger logger = core.getPlugin().getPluginLogger();
|
||||
if(slpCore == null){
|
||||
logger.warn("[Migrator - ServerListPlus] Cannot migrate ServerListPlus config. ServerListPlus is not active!");
|
||||
logger.warn("[<white>Migrator - ServerListPlus</white>] Cannot migrate ServerListPlus config. ServerListPlus is not active!");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ServerStatusConf conf = slpCore.getConf(ServerStatusConf.class);
|
||||
if(conf == null){
|
||||
logger.warn("[Migrator - ServerListPlus] Cannot migrate ServerListPlus configuration. Received configuration was null.");
|
||||
logger.warn("[<white>Migrator - ServerListPlus</white>] Cannot migrate ServerListPlus configuration. Received configuration was null.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -101,7 +130,7 @@ public class SLPConfigMigrator{
|
||||
private static int parseConf(AdvancedServerList<?> core, CmdSender sender, PersonalizedStatusConf.StatusConf conf, Type type){
|
||||
PluginLogger logger = core.getPlugin().getPluginLogger();
|
||||
if(conf == null){
|
||||
logger.info("[Migrator - ServerListPlus] No StatusConf found for type %s. Skipping...", type.getName());
|
||||
logger.info("[<white>Migrator - ServerListPlus</white>] No StatusConf found for type <white>%s</white>. Skipping...", type.getName());
|
||||
sender.sendPrefixedMsg(" -> Not found! Skipping...");
|
||||
|
||||
return 0;
|
||||
@@ -141,7 +170,7 @@ public class SLPConfigMigrator{
|
||||
|
||||
boolean profilesInvalid = profileEntries.isEmpty() || profileEntries.stream().anyMatch(ProfileEntry::isInvalid);
|
||||
if(entry.isInvalid() && profilesInvalid){
|
||||
logger.warn("[Migrator - ServerListPlus] Unable to parse ServerListPlus configuration of type %s. Generated ProfileEntry was invalid.", type.getName());
|
||||
logger.warn("[<white>Migrator - ServerListPlus</white>] Unable to parse ServerListPlus configuration of type <white>%s</white>. Generated ProfileEntry was invalid.", type.getName());
|
||||
sender.sendErrorMsg(" -> <red>Received invalid Configuration.");
|
||||
|
||||
return 0;
|
||||
@@ -149,7 +178,7 @@ public class SLPConfigMigrator{
|
||||
|
||||
Path profile = core.getPlugin().getFolderPath().resolve("profiles").resolve(type.getFile());
|
||||
if(Files.exists(profile)){
|
||||
logger.warn("[Migrator - ServerListPlus] Cannot create new file %s. One with the same name is already present", type.getFile());
|
||||
logger.warn("[<white>Migrator - ServerListPlus</white>] Cannot create new file <white>%s</white>. One with the same name is already present", type.getFile());
|
||||
sender.sendErrorMsg(" -> <red>File</red> %s <red>already present.", type.getFile());
|
||||
|
||||
return 0;
|
||||
@@ -158,7 +187,7 @@ public class SLPConfigMigrator{
|
||||
try{
|
||||
Files.createFile(profile);
|
||||
}catch(IOException ex){
|
||||
logger.warn("[Migrator - ServerListPlus] Encountered an IOException while trying to create file %s.", ex, type.getFile());
|
||||
logger.warn("[<white>Migrator - ServerListPlus</white>] Encountered an IOException while trying to create file <white>%s</white>.", ex, type.getFile());
|
||||
sender.sendErrorMsg(" -> <red>File creation error.");
|
||||
|
||||
return 0;
|
||||
@@ -175,14 +204,14 @@ public class SLPConfigMigrator{
|
||||
try{
|
||||
node = loader.load();
|
||||
}catch(IOException ex){
|
||||
logger.warn("[Migrator - ServerListPlus] Encountered an IOException while trying to load file %s.", ex, type.getFile());
|
||||
logger.warn("[<white>Migrator - ServerListPlus</white>] Encountered an IOException while trying to load file <white>%s</white>.", ex, type.getFile());
|
||||
sender.sendErrorMsg(" -> <red>File loading error.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(node == null){
|
||||
logger.warn("[Migrator - ServerListPlus] Cannot migrate Configuration of type %s. ConfigurationNode was null.", type.getName());
|
||||
logger.warn("[<white>Migrator - ServerListPlus</white>] Cannot migrate Configuration of type <white>%s</white>. ConfigurationNode was null.", type.getName());
|
||||
sender.sendErrorMsg(" -> <red>File loading error.");
|
||||
|
||||
return 0;
|
||||
@@ -194,9 +223,7 @@ public class SLPConfigMigrator{
|
||||
|
||||
if(type == Type.PERSONALIZED){
|
||||
node.node("condition")
|
||||
.set("${player name} != \"" +
|
||||
core.getFileHandler().getString("Anonymous", "unknownPlayer", "name") +
|
||||
"\"");
|
||||
.set("${player name} != \"" + core.getFileHandler().getString("Anonymous", "unknownPlayer", "name") + "\"");
|
||||
}else
|
||||
if(type == Type.BANNED){
|
||||
node.node("condition")
|
||||
@@ -209,7 +236,7 @@ public class SLPConfigMigrator{
|
||||
|
||||
node.set(entry);
|
||||
}catch(SerializationException ex){
|
||||
logger.warn("[Migrator - ServerListPlus] Encountered a SerializationException while setting values.", ex);
|
||||
logger.warn("[<white>Migrator - ServerListPlus</white>] Encountered a SerializationException while setting values.", ex);
|
||||
sender.sendErrorMsg(" -> <red>Error while updating file</red> %s<red>.", type.getFile());
|
||||
|
||||
return 0;
|
||||
@@ -221,7 +248,7 @@ public class SLPConfigMigrator{
|
||||
|
||||
return 1;
|
||||
}catch(IOException ex){
|
||||
logger.warn("[Migrator - ServerListPlus] Encountered an IOException while trying to save new file %s.", ex, type.getFile());
|
||||
logger.warn("[<white>Migrator - ServerListPlus</white>] Encountered an IOException while trying to save new file <white>%s</white>.", ex, type.getFile());
|
||||
sender.sendErrorMsg(" -> <red>File saving error.");
|
||||
|
||||
return 0;
|
||||
@@ -372,32 +399,11 @@ public class SLPConfigMigrator{
|
||||
if(colorCodeMatcher.find()){
|
||||
builder.setLength(0);
|
||||
do{
|
||||
String color = colorCodeMatcher.group("color").toLowerCase(Locale.ROOT);
|
||||
switch(color){
|
||||
case "a" -> colorCodeMatcher.appendReplacement(builder, "<green>");
|
||||
case "b" -> colorCodeMatcher.appendReplacement(builder, "<aqua>");
|
||||
case "c" -> colorCodeMatcher.appendReplacement(builder, "<red>");
|
||||
case "d" -> colorCodeMatcher.appendReplacement(builder, "<light_purple>");
|
||||
case "e" -> colorCodeMatcher.appendReplacement(builder, "<yellow>");
|
||||
case "f" -> colorCodeMatcher.appendReplacement(builder, "<white>");
|
||||
case "k" -> colorCodeMatcher.appendReplacement(builder, "<obfuscated>");
|
||||
case "l" -> colorCodeMatcher.appendReplacement(builder, "<bold>");
|
||||
case "m" -> colorCodeMatcher.appendReplacement(builder, "<strikethrough>");
|
||||
case "n" -> colorCodeMatcher.appendReplacement(builder, "<underlined>");
|
||||
case "o" -> colorCodeMatcher.appendReplacement(builder, "<italic>");
|
||||
case "r" -> colorCodeMatcher.appendReplacement(builder, "<reset>");
|
||||
case "0" -> colorCodeMatcher.appendReplacement(builder, "<black>");
|
||||
case "1" -> colorCodeMatcher.appendReplacement(builder, "<dark_blue>");
|
||||
case "2" -> colorCodeMatcher.appendReplacement(builder, "<dark_green>");
|
||||
case "3" -> colorCodeMatcher.appendReplacement(builder, "<dark_aqua>");
|
||||
case "4" -> colorCodeMatcher.appendReplacement(builder, "<dark_red>");
|
||||
case "5" -> colorCodeMatcher.appendReplacement(builder, "<dark_purple>");
|
||||
case "6" -> colorCodeMatcher.appendReplacement(builder, "<gold>");
|
||||
case "7" -> colorCodeMatcher.appendReplacement(builder, "<grey>");
|
||||
case "8" -> colorCodeMatcher.appendReplacement(builder, "<dark_grey>");
|
||||
case "9" -> colorCodeMatcher.appendReplacement(builder, "<blue>");
|
||||
// This one shouldn't be reachable given the pattern, but you never know...
|
||||
default -> colorCodeMatcher.appendReplacement(builder, "&" + color);
|
||||
for(Map.Entry<String, String> colorCodes : COLOR_TO_MINIMESSAGE_TAG.entrySet()){
|
||||
if(!colorCodeMatcher.group("color").equalsIgnoreCase(colorCodes.getKey()))
|
||||
continue;
|
||||
|
||||
colorCodeMatcher.appendReplacement(builder, colorCodes.getValue());
|
||||
}
|
||||
}while(colorCodeMatcher.find());
|
||||
|
||||
|
||||
+2
-2
@@ -28,12 +28,12 @@ package ch.andre601.advancedserverlist.core.objects;
|
||||
import java.time.Duration;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class CacheUtil<T>{
|
||||
public class ValueCache<T>{
|
||||
|
||||
private final Duration duration;
|
||||
private CacheValue<T> cache = null;
|
||||
|
||||
public CacheUtil(Duration duration){
|
||||
public ValueCache(Duration duration){
|
||||
this.duration = duration;
|
||||
}
|
||||
|
||||
@@ -29,7 +29,6 @@ import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.Function;
|
||||
|
||||
public class ComponentParser{
|
||||
@@ -52,12 +51,13 @@ public class ComponentParser{
|
||||
return new ComponentParser(text);
|
||||
}
|
||||
|
||||
public static ComponentParser list(List<String> lines){
|
||||
return new ComponentParser(String.join("\n", lines));
|
||||
public static ComponentParser textFormatted(String text, Object... args){
|
||||
return text(String.format(text, args));
|
||||
}
|
||||
|
||||
public ComponentParser modifyText(Function<String, String> function){
|
||||
this.text = function.apply(text);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -73,4 +73,8 @@ public class ComponentParser{
|
||||
public String toString(){
|
||||
return legacy.serialize(toComponent());
|
||||
}
|
||||
|
||||
public String toStringStriped(){
|
||||
return mm.stripTags(text);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
package ch.andre601.advancedserverlist.core.parsing;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import net.kyori.adventure.text.flattener.ComponentFlattener;
|
||||
import net.kyori.adventure.text.flattener.FlattenerListener;
|
||||
import net.kyori.adventure.text.format.Style;
|
||||
import net.kyori.adventure.text.format.TextDecoration;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class TextCenterUtil{
|
||||
private final ComponentFlattener COMPONENT_FLATTENER = ComponentFlattener.textOnly();
|
||||
|
||||
private final double MAX_WIDTH = 270.0; // Max width of the MOTD
|
||||
private final int SPACE_WIDTH = 4;
|
||||
|
||||
private final Map<String, FontInfo> charWidths;
|
||||
|
||||
public TextCenterUtil(AdvancedServerList<?> plugin){
|
||||
charWidths = loadFontWidths(plugin);
|
||||
}
|
||||
|
||||
public String getCenteredText(String text){
|
||||
if(!text.toLowerCase(Locale.ROOT).startsWith("<center>"))
|
||||
return text;
|
||||
|
||||
if(getDefault() == null)
|
||||
return text;
|
||||
|
||||
text = text.substring("<center>".length());
|
||||
TextFlattenerListener listener = new TextFlattenerListener(this);
|
||||
|
||||
COMPONENT_FLATTENER.flatten(ComponentParser.text(text).toComponent(), listener);
|
||||
|
||||
double width = listener.getWidth();
|
||||
if(width >= MAX_WIDTH)
|
||||
return text;
|
||||
|
||||
return createSpaces(width) + text;
|
||||
}
|
||||
|
||||
private double getCharWidth(int codePoint, boolean isBold, String fontName){
|
||||
FontInfo font = charWidths.getOrDefault(fontName, getDefault());
|
||||
if(font == null)
|
||||
return -1.0;
|
||||
|
||||
int index = Arrays.binarySearch(font.codePoints, codePoint);
|
||||
if(index < 0){
|
||||
return isBold ? 7.0 : 6.0;
|
||||
}else{
|
||||
return isBold ? font.advanceBf[index] : font.advance[index];
|
||||
}
|
||||
}
|
||||
|
||||
private FontInfo getDefault(){
|
||||
return charWidths.get("minecraft:default");
|
||||
}
|
||||
|
||||
private String createSpaces(double length){
|
||||
double remainder = MAX_WIDTH - length;
|
||||
int padding = (int)Math.max(0, Math.floor(remainder / 2.0) - 1);
|
||||
|
||||
return " ".repeat(Math.floorDiv(padding, SPACE_WIDTH));
|
||||
}
|
||||
|
||||
private Map<String, FontInfo> loadFontWidths(AdvancedServerList<?> plugin){
|
||||
try(InputStream stream = plugin.getClass().getResourceAsStream("/char-widths.json.gz")){
|
||||
if(stream == null){
|
||||
plugin.getPlugin().getPluginLogger().warn("Internal char-widths.json.gz couldn't be retrieved.");
|
||||
plugin.getPlugin().getPluginLogger().warn("The <center> Placeholder won't work.");
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
GZIPInputStream gzipStream = new GZIPInputStream(stream);
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(gzipStream));
|
||||
|
||||
return new Gson().fromJson(reader, new TypeToken<Map<String, FontInfo>>(){}.getType());
|
||||
}catch(IOException ex){
|
||||
plugin.getPlugin().getPluginLogger().warn("Encountered IOException while loading font widths.");
|
||||
plugin.getPlugin().getPluginLogger().warn("The <center> Placeholder won't work.");
|
||||
plugin.getPlugin().getPluginLogger().warn("Cause: <white>%s</white>", ex.getMessage());
|
||||
return new HashMap<>();
|
||||
}
|
||||
}
|
||||
|
||||
private static class TextFlattenerListener implements FlattenerListener{
|
||||
private double width = 0.0;
|
||||
private boolean isBold = false;
|
||||
private String font = "minecraft:default";
|
||||
|
||||
private final TextCenterUtil instance;
|
||||
|
||||
public TextFlattenerListener(TextCenterUtil instance){
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void pushStyle(@NotNull Style style){
|
||||
if(style.hasDecoration(TextDecoration.BOLD))
|
||||
isBold = true;
|
||||
|
||||
if(style.font() != null)
|
||||
font = style.font().asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void component(@NotNull String text){
|
||||
for(int i = 0; i < text.length(); i++){
|
||||
width += instance.getCharWidth(text.codePointAt(i), isBold, font);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void popStyle(@NotNull Style style){
|
||||
if(style.hasDecoration(TextDecoration.BOLD))
|
||||
isBold = false;
|
||||
}
|
||||
|
||||
public double getWidth(){
|
||||
return width;
|
||||
}
|
||||
}
|
||||
|
||||
private record FontInfo(int[] codePoints, float[] advance, float[] advanceBf){}
|
||||
}
|
||||
+7
-7
@@ -51,13 +51,13 @@ public record ServerListProfile(int priority, String condition, ProfileEntry def
|
||||
boolean result = core.getParser().evaluate(condition, player, server, collector);
|
||||
|
||||
if(collector.hasWarnings()){
|
||||
logger.warn("Encountered %d Error(s) while parsing condition for file '%s':", collector.getWarnings().size(), file);
|
||||
logger.warn("Encountered <white>%d</white> Error(s) while parsing condition for file '<white>%s</white>':", collector.getWarnings().size(), file);
|
||||
|
||||
for(ParseWarnCollector.Context context : collector.getWarnings()){
|
||||
logger.warn(" - At position %s:", context.position() == -1 ? "Unknown" : context.position());
|
||||
logger.warn(" %s", condition);
|
||||
logger.warn(" ".repeat(context.position() + 4) + "^");
|
||||
logger.warn(" -> %s", context.message());
|
||||
logger.warn(" - At position <white>%s</white>:", context.position() == -1 ? "<italic>Unknown</italic>" : context.position());
|
||||
logger.warn(" <white>%s</white>", condition);
|
||||
logger.warn(" ".repeat(context.position() + 3) + "<red>^</red>");
|
||||
logger.warn(" <grey>-></grey> %s", context.message());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ public record ServerListProfile(int priority, String condition, ProfileEntry def
|
||||
try{
|
||||
this.profiles = node.node("profiles").getList(ProfileEntry.class);
|
||||
}catch(SerializationException ex){
|
||||
logger.warn("Encountered a SerializationException while resolving the profiles entry for %s", ex, fileName);
|
||||
logger.warn("Encountered a SerializationException while resolving the profiles entry for <white>%s</white>", ex, fileName);
|
||||
}
|
||||
|
||||
return this;
|
||||
@@ -159,7 +159,7 @@ public record ServerListProfile(int priority, String condition, ProfileEntry def
|
||||
try{
|
||||
this.defaultProfile = node.get(ProfileEntry.class);
|
||||
}catch(SerializationException ex){
|
||||
logger.warn("Encountered a SerializationException while resolving the global profile for %s", ex, fileName);
|
||||
logger.warn("Encountered a SerializationException while resolving the global profile for <white>%s</white>", ex, fileName);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
+8
-1
@@ -76,7 +76,14 @@ public class CustomExpressionTokenizer{
|
||||
}
|
||||
}
|
||||
|
||||
collector.appendWarningFormatted(position.getIndex(), "Illegal Token '%c'.", text.charAt(position.getIndex()));
|
||||
if(position.getIndex() >= text.length()){
|
||||
collector.appendWarningFormatted(
|
||||
"Current index position (%d) is larger or equal to Text length (%d) for condition '%s'",
|
||||
position.getIndex(), text.length(), text
|
||||
);
|
||||
}else{
|
||||
collector.appendWarningFormatted(position.getIndex(), "Illegal Token '%c'.", text.charAt(position.getIndex()));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
+39
-13
@@ -42,9 +42,8 @@ import java.net.http.HttpRequest;
|
||||
import java.net.http.HttpResponse;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@@ -57,6 +56,7 @@ public class FaviconHandler<F>{
|
||||
|
||||
private final Map<String, F> localFavicons = new HashMap<>();
|
||||
private final HttpClient client = HttpClient.newHttpClient();
|
||||
private final Random random = new Random();
|
||||
|
||||
public FaviconHandler(AdvancedServerList<F> core){
|
||||
this.core = core;
|
||||
@@ -77,6 +77,11 @@ public class FaviconHandler<F>{
|
||||
}
|
||||
}
|
||||
|
||||
if(input.equalsIgnoreCase("random")){
|
||||
logger.debug(FaviconHandler.class, "Input matches 'random'. Returning random Favicon...");
|
||||
return getRandomized();
|
||||
}
|
||||
|
||||
if(localFavicons.containsKey(input.toLowerCase(Locale.ROOT))){
|
||||
logger.debug(FaviconHandler.class, "Input matches local favicon Image. Returning it...");
|
||||
return localFavicons.get(input.toLowerCase(Locale.ROOT));
|
||||
@@ -86,7 +91,7 @@ public class FaviconHandler<F>{
|
||||
logger.debug(FaviconHandler.class, "Getting Favicon image from cache...");
|
||||
return faviconCache.get(input, () -> getFuture(input)).getNow(null);
|
||||
}catch(ExecutionException ex){
|
||||
logger.warn("Received ExecutionException while retrieving Favicon for '%s'.", ex, input);
|
||||
logger.warn("Received ExecutionException while retrieving Favicon for '<white>%s</white>'.", ex, input);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -101,6 +106,9 @@ public class FaviconHandler<F>{
|
||||
logger.debug(FaviconHandler.class, "Resolving URL '%s'...", input);
|
||||
return CompletableFuture.supplyAsync(() -> fromURL(core, input), this.faviconThreadPool);
|
||||
}else
|
||||
if(input.equalsIgnoreCase("random")){
|
||||
return CompletableFuture.completedFuture(getRandomized());
|
||||
}else
|
||||
if(input.toLowerCase(Locale.ROOT).endsWith(".png")){
|
||||
logger.debug(FaviconHandler.class, "Resolving image file '%s'...", input);
|
||||
return CompletableFuture.completedFuture(localFavicons.get(input.toLowerCase(Locale.ROOT)));
|
||||
@@ -110,18 +118,34 @@ public class FaviconHandler<F>{
|
||||
}
|
||||
}
|
||||
|
||||
private F getRandomized(){
|
||||
logger.debug(FaviconHandler.class, "Obtaining random Favicon...");
|
||||
if(localFavicons.isEmpty())
|
||||
return null;
|
||||
|
||||
List<F> faviconList = List.copyOf(localFavicons.values());
|
||||
|
||||
// Don't use Random for just one entry.
|
||||
if(faviconList.size() == 1)
|
||||
return faviconList.get(0);
|
||||
|
||||
synchronized(random){
|
||||
return faviconList.get(random.nextInt(faviconList.size()));
|
||||
}
|
||||
}
|
||||
|
||||
private void loadLocalFavicons(){
|
||||
this.localFavicons.clear();
|
||||
|
||||
logger.info("Loading local image files as Favicons...");
|
||||
logger.info("[-] Loading local image files as Favicons...");
|
||||
|
||||
Path folder = core.getPlugin().getFolderPath().resolve("favicons");
|
||||
if(!Files.exists(folder)){
|
||||
try{
|
||||
Files.createDirectories(folder);
|
||||
logger.info("Created favicons folder.");
|
||||
logger.debugSuccess(FaviconHandler.class, "Created favicons folder.");
|
||||
}catch(IOException ex){
|
||||
logger.warn("Cannot create favicons folder. Encountered an IOException.", ex);
|
||||
logger.failure("Cannot create favicons folder. Encountered an IOException.", ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -130,8 +154,10 @@ public class FaviconHandler<F>{
|
||||
pathStream.filter(Files::isRegularFile)
|
||||
.filter(file -> file.getFileName().toString().endsWith(".png"))
|
||||
.forEach(this::loadFile);
|
||||
|
||||
logger.success("Loaded <white>%d</white> local Favicons.", localFavicons.size());
|
||||
}catch(IOException ex){
|
||||
logger.warn("Cannot load files from Favicons folder.", ex);
|
||||
logger.failure("Cannot load files from favicons folder.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,14 +165,14 @@ public class FaviconHandler<F>{
|
||||
try(InputStream stream = Files.newInputStream(path)){
|
||||
F favicon = createFavicon(stream);
|
||||
if(favicon == null){
|
||||
logger.warn("Cannot create Favicon from file '%s'. Received Favicon was null.", path.getFileName().toString());
|
||||
logger.failure("Cannot create Favicon from file '<white>%s</white>'. Received Favicon was null.", path.getFileName().toString());
|
||||
return;
|
||||
}
|
||||
|
||||
localFavicons.put(path.getFileName().toString().toLowerCase(Locale.ROOT), favicon);
|
||||
logger.info("Loaded file '%s' as Favicon.", path.getFileName().toString());
|
||||
logger.debugSuccess(FaviconHandler.class, "Loaded file '<white>%s</white>' as Favicon.", path.getFileName().toString());
|
||||
}catch(IOException ex){
|
||||
logger.warn("Cannot create Favicon from file '%s'. Encountered IOException.", ex);
|
||||
logger.failure("Cannot create Favicon from file '<white>%s</white>'. Encountered IOException.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,11 +187,11 @@ public class FaviconHandler<F>{
|
||||
try(InputStream stream = client.send(request, HttpResponse.BodyHandlers.ofInputStream()).body()){
|
||||
return createFavicon(stream);
|
||||
}catch(InterruptedException | IOException ex){
|
||||
logger.warn("Cannot create Favicon from URL '%s'. Encountered an Exception.", ex, url);
|
||||
logger.warn("Cannot create Favicon from URL '<white>%s</white>'. Encountered an Exception.", ex, url);
|
||||
return null;
|
||||
}
|
||||
}catch(URISyntaxException ex){
|
||||
logger.warn("Cannot create Favicon from URL '%s'. Encountered an IOException.", ex, url);
|
||||
logger.warn("Cannot create Favicon from URL '<white>%s</white>'. Encountered a URISyntaxException.", ex, url);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
+8
-10
@@ -79,43 +79,41 @@ public class PlayerHandler{
|
||||
try(BufferedReader reader = Files.newBufferedReader(cache)){
|
||||
cachedPlayers = gson.fromJson(reader, listType);
|
||||
}catch(IOException ex){
|
||||
logger.warn("Encountered IOException while reading the playercache.json file!", ex);
|
||||
logger.warn("Encountered IOException while reading the <white>playercache.json</white> file!", ex);
|
||||
return;
|
||||
}catch(JsonIOException | JsonSyntaxException ex){
|
||||
logger.warn("Encountered JsonSyntaxException while parsing playercache.json file!", ex);
|
||||
logger.warn("Encountered JsonSyntaxException while parsing <white>playercache.json</white> file!", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
// In case Gson messes up... I guess.
|
||||
if(cachedPlayers == null){
|
||||
logger.warn("Couldn't load players from playercache.json file. Is the JSON valid?");
|
||||
logger.warn("Couldn't load players from <white>playercache.json</white> file. Is the JSON valid?");
|
||||
// Create new ArrayList instance to avoid further issues.
|
||||
cachedPlayers = new ArrayList<>();
|
||||
return;
|
||||
}
|
||||
|
||||
logger.info("Loaded %d players into cache!", cachedPlayers.size());
|
||||
logger.success("Loaded <white>%d</white> players into cache!", cachedPlayers.size());
|
||||
}
|
||||
|
||||
public void save(){
|
||||
if(cachedPlayers.isEmpty()){
|
||||
logger.info("No players in cache to save. Skipping...");
|
||||
logger.debug(PlayerHandler.class, "No players in cache to save. Skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
if(core.getFileHandler().getBoolean("disableCache")){
|
||||
logger.info("'disable_cache' is set to true. Skipping saving of cached players...");
|
||||
logger.debug(PlayerHandler.class, "[-] 'disable_cache' is set to true. Not saving cached players.");
|
||||
return;
|
||||
}
|
||||
|
||||
try(BufferedWriter writer = Files.newBufferedWriter(cache, StandardCharsets.UTF_8)){
|
||||
gson.toJson(cachedPlayers, listType, writer);
|
||||
logger.info("Successfully saved playercache.json file.");
|
||||
logger.success("Successfully saved <white>playercache.json</white> file.");
|
||||
}catch(IOException ex){
|
||||
logger.warn("Encountered IOException while saving cached players to playercache.json!", ex);
|
||||
logger.failure("Encountered IOException while saving cached players to <white>playercache.json</white>!", ex);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void addPlayer(String ip, String name, UUID uuid){
|
||||
|
||||
+13
-2
@@ -60,8 +60,19 @@ public class ProfileManager{
|
||||
String maxPlayersCount = resolve(defEntry, entry, ProfileEntry::maxPlayersCount);
|
||||
String onlinePlayersCount = resolve(defEntry, entry, ProfileEntry::onlinePlayersCount);
|
||||
|
||||
return new ProfileEntry(motd, players, playerCountText, favicon, hidePlayersEnabled, extraPlayersEnabled,
|
||||
maxPlayersEnabled, onlinePlayersEnabled, extraPlayersCount, maxPlayersCount, onlinePlayersCount);
|
||||
return new ProfileEntry.Builder()
|
||||
.motd(motd)
|
||||
.players(players)
|
||||
.playerCountText(playerCountText)
|
||||
.favicon(favicon)
|
||||
.hidePlayersEnabled(hidePlayersEnabled)
|
||||
.extraPlayersEnabled(extraPlayersEnabled)
|
||||
.maxPlayersEnabled(maxPlayersEnabled)
|
||||
.onlinePlayersEnabled(onlinePlayersEnabled)
|
||||
.extraPlayersCount(extraPlayersCount)
|
||||
.maxPlayersCount(maxPlayersCount)
|
||||
.onlinePlayersCount(onlinePlayersCount)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ServerListProfile resolveProfile(AdvancedServerList<?> core, GenericPlayer player, GenericServer server){
|
||||
|
||||
+7
-7
@@ -72,6 +72,9 @@ public class StringReplacer{
|
||||
boolean identified = false;
|
||||
boolean invalid = true;
|
||||
|
||||
int placeholderStart = position.getIndex() - 1;
|
||||
int valueStart = position.getIndex() - 1;
|
||||
|
||||
char[] chars = input.substring(index).toCharArray();
|
||||
for(final char c : chars){
|
||||
index++;
|
||||
@@ -83,6 +86,7 @@ public class StringReplacer{
|
||||
|
||||
if(c == ' ' && !identified){
|
||||
identified = true;
|
||||
valueStart = index + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -98,10 +102,6 @@ public class StringReplacer{
|
||||
|
||||
StringBuilder raw = new StringBuilder();
|
||||
|
||||
// Condition parsing needs one extra increase of index... for some reason
|
||||
if(collector != null)
|
||||
index++;
|
||||
|
||||
position.setIndex(index);
|
||||
|
||||
if(invalid){
|
||||
@@ -111,7 +111,7 @@ public class StringReplacer{
|
||||
raw.append(' ').append(valuesStr);
|
||||
|
||||
if(collector != null)
|
||||
collector.appendWarningFormatted(index, "Placeholder '%s' does not have a closing bracket (})", raw.toString());
|
||||
collector.appendWarningFormatted(index, "Placeholder '<white>%s</white>' does not have a closing bracket (})", raw.toString());
|
||||
|
||||
return raw.toString();
|
||||
}
|
||||
@@ -126,7 +126,7 @@ public class StringReplacer{
|
||||
raw.append('}');
|
||||
|
||||
if(collector != null)
|
||||
collector.appendWarningFormatted(index, "Placeholder '%s' does not have any available PlaceholderProvider", raw.toString());
|
||||
collector.appendWarningFormatted(placeholderStart, "Placeholder '<white>%s</white>' does not have any available PlaceholderProvider", raw.toString());
|
||||
|
||||
return raw.toString();
|
||||
}
|
||||
@@ -141,7 +141,7 @@ public class StringReplacer{
|
||||
raw.append('}');
|
||||
|
||||
if(collector != null)
|
||||
collector.appendWarningFormatted(index, "Placeholder '%s' has an invalid value String '%s'", raw.toString(), valuesStr);
|
||||
collector.appendWarningFormatted(valueStart, "Placeholder '<white>%s</white>' has an invalid value String '<white>%s</white>'", raw.toString(), valuesStr);
|
||||
|
||||
return raw.toString();
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -48,6 +48,14 @@ checkUpdates: true
|
||||
#
|
||||
debug: false
|
||||
|
||||
#
|
||||
# Should the "ASL" ASCI art be displayed on plugin startup?
|
||||
# Setting this to false will hide the banner.
|
||||
#
|
||||
# Default: true
|
||||
#
|
||||
printBanner: true
|
||||
|
||||
#
|
||||
# Sets how long Favicons should be cached. Value is in minutes with the lowest possible value being 1.
|
||||
#
|
||||
|
||||
@@ -58,12 +58,17 @@ motd:
|
||||
# This option supports three types of inputs:
|
||||
#
|
||||
# 1. Name, including .png extension, pointing to an image located in the plugin's favicons folder.
|
||||
# 2. URL pointing to an image.*
|
||||
# 3. Player name, UUID or placeholders returning one of these.*
|
||||
# 2. "random" to display a random PNG from the favicons folder.
|
||||
# 3. URL pointing to an image.
|
||||
# 4. Player name, UUID or placeholders returning one of these.
|
||||
# https://mc-heads.net will be used to retrieve an image of the provided name/UUID.
|
||||
#
|
||||
# * These images are loaded asynchronously, meaning they may not yet be "ready" when AdvancedServerList is done with
|
||||
# the event, requiring a refresh of the server list by the player to have it shown.
|
||||
# Note on favicons not showing:
|
||||
# AdvancedServerList has to create a Favicon object for the Proxy/Server to use which takes time to do so.
|
||||
# To not delay the Proxy/Server from being displayed (increase the loading time on the player end) is this creation
|
||||
# done asynchronously for URL/Player name/UUID. This has the downside that the Proxy/Server may be done handling the
|
||||
# ping before the Favicon is created, causing none to be displayed.
|
||||
# Note that this won't happen with local favicons, as those are created during the plugin's startup.
|
||||
#
|
||||
# Any images above or below 64x64 pixels will be automatically resized to these dimensions.
|
||||
#
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.test;
|
||||
package ch.andre601.advancedserverlist.core;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.test;
|
||||
package ch.andre601.advancedserverlist.core;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.ProfileConditionParser;
|
||||
import ch.andre601.expressionparser.ParseWarnCollector;
|
||||
+1
-1
@@ -23,7 +23,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.test;
|
||||
package ch.andre601.advancedserverlist.core;
|
||||
|
||||
import com.unascribed.flexver.FlexVerComparator;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@@ -17,7 +17,7 @@
|
||||
import re
|
||||
|
||||
from mkdocs.config.defaults import MkDocsConfig
|
||||
from mkdocs.structure.files import File, Files
|
||||
from mkdocs.structure.files import Files
|
||||
from mkdocs.structure.pages import Page
|
||||
|
||||
def on_page_markdown(
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
{% extends "base.html" %}
|
||||
|
||||
{% block announce %}
|
||||
<span class="twemoji">{% include ".icons/material/party-popper.svg" %}</span>
|
||||
Celebrating <a href="https://andre601.ch/blog/2024/12-13-history-of-asl/" target="_blank" rel="nofollow"><b>25,000 downloads!</b></a> Thank you!
|
||||
<span class="twemoji">{% include ".icons/material/party-popper.svg" %}</span>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,10 @@
|
||||
[discord]: https://discord.gg/MyPTjpsgGH
|
||||
|
||||
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
|
||||
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
|
||||
[papiproxybridge]: https://hangar.papermc.io/William278/PAPIProxyBridge
|
||||
[maintenance]: https://hangar.papermc.io/kennytv/Maintenance
|
||||
|
||||
[modrinth]: https://modrinth.com/plugin/advancedserverlist
|
||||
[hangar]: https://hangar.papermc.io/Andre_601/AdvancedServerList
|
||||
[codeberg]: https://codeberg.org/Andre601/AdvancedServerList
|
||||
@@ -1,7 +1,14 @@
|
||||
---
|
||||
icon: octicons/stop-24
|
||||
---
|
||||
# BanPlugins Addon
|
||||
|
||||
The BanPlugins Addon was made to provide placeholders for different punishment plugins to use in AdvancedServerList.
|
||||
|
||||
/// info
|
||||
The BanPlugins Addon is available in downloads of AdvancedServerList on [:simple-modrinth: Modrinth](https://modrinth.com/plugin/advancedserverlist) and in [Releases on :simple-codeberg: Codeberg](https://codeberg.org/Andre601/AdvancedServerList/releases).
|
||||
///
|
||||
|
||||
## Placeholders
|
||||
|
||||
/// tab | AdvancedBan
|
||||
|
||||
@@ -17,7 +17,7 @@ They are ordered newest to oldest.
|
||||
|
||||
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v4.0.0-added }
|
||||
|
||||
- New setter methods added to [`ProfileEntry.Builder`][profilentry.builder] class:
|
||||
- New setter methods added to [`ProfileEntry.Builder`][profileentry.builder] class:
|
||||
- [`onlinePlayersCount(String)`][onlinePlayersCount]
|
||||
- [`onlinePlayersEnabled(NullBool)`][onlinePlayersEnabled]
|
||||
|
||||
|
||||
+12
-14
@@ -11,7 +11,7 @@ AdvancedServerList offers an API that other plugins can use to add their own pla
|
||||
Add the following to your `pom.xml`, `build.gradle` or `build.gradle.kts` depending on what you use:
|
||||
|
||||
/// tab | :simple-apachemaven: Maven
|
||||
```xml title="pom.xml"
|
||||
```xml { data-md-component="api-version" title="pom.xml" }
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>codeberg</id>
|
||||
@@ -51,7 +51,7 @@ Add the following to your `pom.xml`, `build.gradle` or `build.gradle.kts` depend
|
||||
///
|
||||
|
||||
/// tab | :simple-gradle: Gradle
|
||||
```groovy title="build.gradle"
|
||||
```groovy { data-md-component="api-version" title="build.gradle" }
|
||||
repositorories {
|
||||
maven { url = 'https://codeberg.org/api/packages/Andre601/maven/' }
|
||||
}
|
||||
@@ -68,7 +68,7 @@ dependencies {
|
||||
///
|
||||
|
||||
/// tab | :simple-gradle: Gradle (KTS)
|
||||
```kotlin title="build.gradle.kts"
|
||||
```kotlin { data-md-component="api-version" title="build.gradle.kts" }
|
||||
repositories {
|
||||
maven("https://codeberg.org/api/packages/Andre601/maven/")
|
||||
}
|
||||
@@ -96,11 +96,11 @@ To add your own placeholders, follow these steps:
|
||||
|
||||
You should first create a new class and make it extend the abstract [`PlaceholderProvider`][placeholderprovider]. This class includes a constructor and a method you need to add, so do that:
|
||||
|
||||
```java
|
||||
```java { .annotate title="Creating PlaceholderProvider class" }
|
||||
public class MyPlaceholders extends PlaceholderProvider {
|
||||
|
||||
public MyPlaceholders(String identifier) {
|
||||
super(identifier);
|
||||
super(identifier); // (1)
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -110,14 +110,12 @@ public class MyPlaceholders extends PlaceholderProvider {
|
||||
}
|
||||
```
|
||||
|
||||
/// tip
|
||||
You can replace the Constructor with a String argument with a no-args constructor and set the identifier directly in the `super`:
|
||||
```java
|
||||
public MyPlaceholders() {
|
||||
super("myplaceholders");
|
||||
}
|
||||
```
|
||||
///
|
||||
1. It is recommended to replace this constructor with a no-args Constructor and have the placeholder name set in the `super` directly:
|
||||
```java
|
||||
public MyPlaceholders() {
|
||||
super("myplaceholders");
|
||||
}
|
||||
```
|
||||
|
||||
The [`parsePlaceholder(String, GenericPlayer, GenericServer)`][parseplaceholder] method is used by AdvancedServerList to replace a matching placeholder with a value.
|
||||
What you return is completely up to you. Just keep in mind that returning `null` will be treated as an invalid placeholder by AdvancedServerList, resulting in the placeholder being returned as-is without any changes.
|
||||
@@ -128,7 +126,7 @@ What you return is completely up to you. Just keep in mind that returning `null`
|
||||
/// details | Example of final class
|
||||
type: example
|
||||
|
||||
```java
|
||||
```java title="MyPlaceholders.java"
|
||||
public class MyPlaceholders extends PlaceholderProvider {
|
||||
|
||||
public MyPlaceholders() {
|
||||
|
||||
+13
-5
@@ -13,14 +13,16 @@ constructors:
|
||||
methods:
|
||||
- name: 'extraPlayersCount'
|
||||
description: |
|
||||
Sets the number of players to add to the online players to use as the new max players value.<br>
|
||||
Sets the value to resolve into a number by AdvancedServerList.<br>
|
||||
Strings not resolving into valid numbers will be treated as this option not being set.<br>
|
||||
<br>
|
||||
This option has no effect when <a href="../#extraplayersenabled()"><code>extraPlayersEnabled</code></a> is set to <a href="../../../objects/nullbool/#false"><code>NullBool.FALSE</code></a> or <a href="../../objects/nullbool/#not_set"><code>NullBool.NOT_SET</code></a>.<br>
|
||||
<br>
|
||||
Set this to <code>null</code> to not alter the max player count. Alternatively, set <a href="#setextraplayersenabled(nullbool)"><code>setExtraPlayersEnabled(NullBool)</code></a> to <a href="../../../objects/nullbool/#false"><code>NullBool.FALSE</code></a>.
|
||||
Set this to <code>null</code> to not alter the max player count. Alternatively <a href="#setextraplayersenabled(nullbool)"><code>disable extra Players</code></a>.
|
||||
parameters:
|
||||
- name: 'extraPlayersCount'
|
||||
description: 'The number of extra players to add.'
|
||||
type: 'Integer'
|
||||
type: 'String'
|
||||
attribute:
|
||||
- 'nullable'
|
||||
returns: 'This Builder after the extra player count has been set. Useful for chaining.'
|
||||
@@ -73,7 +75,9 @@ methods:
|
||||
description: 'Thrown by the <code>CheckUtil</code> in case <code>null</code> has been provided as parameter.'
|
||||
- name: 'maxPlayersCount'
|
||||
description: |
|
||||
Sets the number of max players allowed to join this server.<br>
|
||||
Sets the value to resolve into a number by AdvancedServerList.<br>
|
||||
Strings not resolving into valid numbers will be treated as this option not being set.<br>
|
||||
<br>
|
||||
This option has no effect when <a href="#maxplayersenabled(nullbool)">maxPlayersEnabled</a> is set to <a href="../../../objects/nullbool/#false"><code>NullBool.FALSE</code></a> or <a href="../../../objects/nullbool/#not_set"><code>NullBool.NOT_SET</code></a>.<br>
|
||||
<br>
|
||||
Set this to <code>null</code> to not alter the max player count. Alternatively <a href="#maxplayersenabled(nullbool)">disable max Players</a>.
|
||||
@@ -122,7 +126,11 @@ methods:
|
||||
- name: 'onlinePlayersCount'
|
||||
description: |
|
||||
Sets the value to resolve into a number by AdvancedServerList.<br>
|
||||
Strings not resolving into valid numbers will be treated as this option not being set.
|
||||
Strings not resolving into valid numbers will be treated as this option not being set.<br>
|
||||
<br>
|
||||
This option has no effect when <a href="#onlineplayersenabled(nullbool)">maxPlayersEnabled</a> is set to <a href="../../../objects/nullbool/#false"><code>NullBool.FALSE</code></a> or <a href="../../../objects/nullbool/#not_set"><code>NullBool.NOT_SET</code></a>.<br>
|
||||
<br>
|
||||
Set this to <code>null</code> to not alter the online player count. Alternatively <a href="#onlineplayersenabled(nullbool)">disable online Players</a>.
|
||||
parameters:
|
||||
- name: 'onlinePlayersCount'
|
||||
description: 'The number of online players to set.'
|
||||
|
||||
+22
-8
@@ -43,13 +43,18 @@ constructors:
|
||||
attributes:
|
||||
- notnull
|
||||
- name: 'extraPlayersCount'
|
||||
description: 'The number to add to the online players for the max players number.'
|
||||
type: Integer
|
||||
description: 'The number to add to the online Players for the extra Players.'
|
||||
type: String
|
||||
attributes:
|
||||
- nullable
|
||||
- name: 'maxPlayersCount'
|
||||
description: 'The number to use for the max players count.'
|
||||
type: Integer
|
||||
description: 'The number to set for the max Players count.'
|
||||
type: String
|
||||
attributes:
|
||||
- nullable
|
||||
- name: 'onlinePlayersCount'
|
||||
description: 'The number to set for the Online Players count.'
|
||||
type: String
|
||||
attributes:
|
||||
- nullable
|
||||
seealso:
|
||||
@@ -76,6 +81,7 @@ methods:
|
||||
<li><a href="#maxplayersenabled()"><code>maxPlayersEnabled</code></a>: <a href="../../objects/nullbool/#not_set"><code>NullBoo.NOT_SET</code></a></li>
|
||||
<li><a href="#extraplayerscount()"><code>extraPlayersCount</code></a>: <code>null</code></li>
|
||||
<li><a href="#maxplayerscount()"><code>maxPlayersCount</code></a>: <code>null</code></li>
|
||||
<li><a href="#onlineplayerscount()"><code>onlinePlayersCount</code></a>: <code>null</code></li>
|
||||
</ul>
|
||||
returns: 'New ProfileEntry instance with empty/null values defined'
|
||||
attributes:
|
||||
@@ -164,12 +170,12 @@ methods:
|
||||
type: 'object'
|
||||
link: '../../objects/nullbool/'
|
||||
- name: 'extraPlayersCount'
|
||||
description: 'Gets the currently set number of extra players to use by this ProfileEntry. May be <code>null</code>.'
|
||||
returns: 'Possibly-null integer number of extra players used by this ProfileEntry.'
|
||||
description: 'Gets the currently set number of extra players of this ProfileEntry.'
|
||||
returns: 'The current number of extra players used by this ProfileEntry.'
|
||||
attributes:
|
||||
- nullable
|
||||
type:
|
||||
name: 'Integer'
|
||||
name: 'String'
|
||||
type: 'object'
|
||||
- name: 'maxPlayersCount'
|
||||
description: 'Gets the currently set number of max players of this ProfileEntry.'
|
||||
@@ -177,7 +183,15 @@ methods:
|
||||
attributes:
|
||||
- nullable
|
||||
type:
|
||||
name: 'Integer'
|
||||
name: 'String'
|
||||
type: 'object'
|
||||
- name: 'onlinePlayersCount'
|
||||
description: 'Gets the currently set number of online players of this ProfileEntry.'
|
||||
returns: 'The current number of online players used by this ProfileEntry.'
|
||||
attributes:
|
||||
- nullable
|
||||
type:
|
||||
name: 'String'
|
||||
type: 'object'
|
||||
- name: 'isInvalid'
|
||||
description: |
|
||||
|
||||
@@ -4,7 +4,7 @@ document$.subscribe(async () => {
|
||||
|
||||
const repo_stats = document.querySelector('[data-md-component="source"] .md-source__repository');
|
||||
|
||||
function loadCodebergInfo(data) {
|
||||
async function loadCodebergInfo(data) {
|
||||
const facts = document.createElement("ul");
|
||||
facts.className = "md-source__facts";
|
||||
|
||||
@@ -28,22 +28,36 @@ document$.subscribe(async () => {
|
||||
repo_stats.appendChild(facts);
|
||||
}
|
||||
|
||||
function loadApiInfo(data) {
|
||||
async function loadApiInfo(data) {
|
||||
const codeBlocks = document.querySelectorAll('[data-md-component="api-version"] pre code')
|
||||
if (codeBlocks === null)
|
||||
return;
|
||||
|
||||
const version = data["version"];
|
||||
const versionToken = '{apiVersion}';
|
||||
const codeBlocks = document.querySelectorAll('.md-content pre code');
|
||||
for(const codeBlock of codeBlocks) {
|
||||
codeBlock.innerHTML = codeBlock.innerHTML.replace(new RegExp(versionToken, 'g'), version.substring(1));
|
||||
}
|
||||
const regex = new RegExp('{apiVersion}', 'g');
|
||||
codeBlocks.forEach((codeBlock) => {
|
||||
var walker = document.createTreeWalker(codeBlock, NodeFilter.SHOW_TEXT);
|
||||
var node;
|
||||
while (node = walker.nextNode()) {
|
||||
node.nodeValue = node.nodeValue.replace(regex, version.substring(1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function loadPluginVersion(data) {
|
||||
async function loadPluginVersion(data) {
|
||||
const entries = document.querySelectorAll('code[data-md-component="plugin-version"]');
|
||||
if(entries === null)
|
||||
return;
|
||||
|
||||
const version = data["version"];
|
||||
const versionToken = '{version}'
|
||||
const entries = document.querySelectorAll('.md-content code');
|
||||
for(const entry of entries) {
|
||||
entry.innerHTML = entry.innerHTML.replace(new RegExp(versionToken, 'g'), version.substring(1));
|
||||
}
|
||||
const regex = new RegExp('{version}', 'g');
|
||||
entries.forEach((entry) => {
|
||||
var walker = document.createTreeWalker(entry, NodeFilter.SHOW_TEXT);
|
||||
var node;
|
||||
while (node = walker.nextNode()) {
|
||||
node.nodeValue = node.nodeValue.replace(regex, version.substring(1));
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async function fetchApiInfo() {
|
||||
|
||||
@@ -44,4 +44,15 @@
|
||||
|
||||
.md-source__repository .md-source__facts {
|
||||
animation: facts .25s ease-in;
|
||||
}
|
||||
|
||||
.md-nav--secondary li.md-nav__item > .md-nav__link {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.md-banner__inner.md-grid.md-typeset {
|
||||
text-align: center;
|
||||
}
|
||||
@@ -10,7 +10,7 @@ icon: octicons/list-unordered-24
|
||||
|
||||
This page lists some examples you may want to use for your proxy or server.
|
||||
|
||||
Feel free to suggest additional examples in the `advancedserverlist` category on the [M.O.S.S. Discord Server](https://discord.gg/MyPTjpsgGH){ target="_blank" rel="nofollow" }.
|
||||
Feel free to suggest additional examples in the `advancedserverlist` category on the [M.O.S.S. Discord Server][discord]{ target="_blank" rel="nofollow" }.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ icon: octicons/milestone-24
|
||||
# Getting Started
|
||||
|
||||
This page will explain how to set up AdvancedServerList and make it work for your server.
|
||||
The guide is designed to be as easy to understand as possible. If you still have problems or questions, join the [M.O.S.S Discord Server](https://discord.gg/MyPTjpsgGH){ target="_blank" rel="nofollow" } for more help.
|
||||
The guide is designed to be as easy to understand as possible. If you still have problems or questions, join the [M.O.S.S Discord Server][discord]{ target="_blank" rel="nofollow" } for more help.
|
||||
|
||||
## 1. Download the plugin { #download-the-plugin }
|
||||
|
||||
@@ -41,10 +41,7 @@ AdvancedServerList is available on the following places (Please note the current
|
||||
|
||||
</div>
|
||||
|
||||
[modrinth]: https://modrinth.com/plugin/advancedserverlist
|
||||
[codeberg]: https://codeberg.org/Andre601/AdvancedServerList
|
||||
[spigot]: https://www.spigotmc.org/resources/102910/
|
||||
[hangar]: https://hangar.papermc.io/Andre_601/AdvancedServerList
|
||||
|
||||
The plugin is available for Paper, BungeeCord, Waterfall and Velocity, and has been tested on these platforms. It may support additional forks, but this is not guaranteed.
|
||||
|
||||
@@ -109,10 +106,6 @@ The plugin also supports these additional plugins. They are all optional.
|
||||
|
||||
</div>
|
||||
|
||||
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
|
||||
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
|
||||
[papiproxybridge]: https://hangar.papermc.io/William278/PAPIProxyBridge
|
||||
[maintenance]: https://hangar.papermc.io/kennytv/Maintenance
|
||||
[addon]: ../addons/banplugins.md
|
||||
|
||||
## 2. Installation { #installation }
|
||||
@@ -120,11 +113,11 @@ The plugin also supports these additional plugins. They are all optional.
|
||||
Installing the plugin is as simple as moving the jar file into the `plugins` folder. Just make sure to download the right version of AdvancedServerList for the right platform.
|
||||
Here is a quick table showing the jar file name with the platforms it is made for:
|
||||
|
||||
| Jar file name | Platforms |
|
||||
|-----------------------------------------------|-----------------------|
|
||||
| `AdvancedServerList-Paper-{version}.jar` | Paper |
|
||||
| `AdvancedServerList-BungeeCord-{version}.jar` | BungeeCord, Waterfall |
|
||||
| `AdvancedServerList-Velocity-{version}.jar` | Velocity |
|
||||
| Jar file name | Platforms |
|
||||
|-------------------------------------------------------------------------------------|-----------------------|
|
||||
| `AdvancedServerList-Paper-{version}.jar`{ data-md-component="plugin-version" } | Paper |
|
||||
| `AdvancedServerList-BungeeCord-{version}.jar`{ data-md-component="plugin-version" } | BungeeCord, Waterfall |
|
||||
| `AdvancedServerList-Velocity-{version}.jar`{ data-md-component="plugin-version" } | Velocity |
|
||||
|
||||
After you added it to your plugins folder - alongside any other dependency you may want - (re)start your server or proxy to enable the plugin.
|
||||
If everything goes well should AdvancedServerList create a folder named `AdvancedServerList` (`advancedserverlist` on Velocity) with additional files and folders inside of it.
|
||||
@@ -214,12 +207,17 @@ motd:
|
||||
# This option supports three types of inputs:
|
||||
#
|
||||
# 1. Name, including .png extension, pointing to an image located in the plugin's favicons folder.
|
||||
# 2. URL pointing to an image.*
|
||||
# 3. Player name, UUID or placeholders returning one of these.*
|
||||
# 2. "random" to display a random PNG from the favicons folder.
|
||||
# 3. URL pointing to an image.
|
||||
# 4. Player name, UUID or placeholders returning one of these.
|
||||
# https://mc-heads.net will be used to retrieve an image of the provided name/UUID.
|
||||
#
|
||||
# * These images are loaded asynchronously, meaning they may not yet be "ready" when AdvancedServerList is done with
|
||||
# the event, requiring a refresh of the server list by the player to have it shown.
|
||||
# Note on favicons not showing:
|
||||
# AdvancedServerList has to create a Favicon object for the Proxy/Server to use which takes time to do so.
|
||||
# To not delay the Proxy/Server from being displayed (increase the loading time on the player end) is this creation
|
||||
# done asynchronously for URL/Player name/UUID. This has the downside that the Proxy/Server may be done handling the
|
||||
# ping before the Favicon is created, causing none to be displayed.
|
||||
# Note that this won't happen with local favicons, as those are created during the plugin's startup.
|
||||
#
|
||||
# Any images above or below 64x64 pixels will be automatically resized to these dimensions.
|
||||
#
|
||||
@@ -290,6 +288,7 @@ playerCount:
|
||||
enabled: false
|
||||
#
|
||||
# Set the number that should be added to the online player count to then use as the new max player count.
|
||||
# Placeholders resolving to numbers can be used here.
|
||||
#
|
||||
# Example: Setting this to 1 will result in ${server playersMax} displaying 11 while 10 players are online,
|
||||
# 9 when 8 are online and so on.
|
||||
@@ -318,12 +317,37 @@ playerCount:
|
||||
enabled: false
|
||||
#
|
||||
# Set the number that should be used as the new max players count.
|
||||
# Placeholders resolving to numbers can be used here.
|
||||
#
|
||||
# If not present, defaults to 0.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#maxplayers-amount
|
||||
#
|
||||
amount: 0
|
||||
#
|
||||
# The onlinePlayers feature allows to set a number to use as the online player count to display.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#onlineplayers
|
||||
#
|
||||
onlinePlayers:
|
||||
#
|
||||
# Set whether the onlinePlayers feature should be enabled or not.
|
||||
# When set to true, the max player count will be set to the 'amount' value.
|
||||
#
|
||||
# If not present, defaults to false.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#onlineplayers-enabled
|
||||
#
|
||||
enabled: false
|
||||
#
|
||||
# Set the number that should be used as the new online players count.
|
||||
# Placeholders resolving to numbers can be used here.
|
||||
#
|
||||
# If not present, defaults to current online player count.
|
||||
#
|
||||
# Read more: https://asl.andre601.ch/profiles/#onlineplayers-amount
|
||||
#
|
||||
amount: 0
|
||||
```
|
||||
///
|
||||
|
||||
@@ -397,6 +421,14 @@ checkUpdates: true
|
||||
#
|
||||
debug: false
|
||||
|
||||
#
|
||||
# Should the "ASL" ASCI art be displayed on plugin startup?
|
||||
# Setting this to false will hide the banner.
|
||||
#
|
||||
# Default: true
|
||||
#
|
||||
printBanner: true
|
||||
|
||||
#
|
||||
# Sets how long Favicons should be cached. Value is in minutes with the lowest possible value being 1.
|
||||
#
|
||||
@@ -456,6 +488,12 @@ disableDuringMaintenance:
|
||||
# Default: true
|
||||
#
|
||||
maxPlayers: true
|
||||
#
|
||||
# Whether the online players feature should be disabled while Maintenance mode is active.
|
||||
#
|
||||
# Default: true
|
||||
#
|
||||
onlinePlayers: true
|
||||
|
||||
#
|
||||
# DO NOT EDIT!
|
||||
@@ -463,7 +501,7 @@ disableDuringMaintenance:
|
||||
# This is used internally to determine if the config needs to be migrated.
|
||||
# Changing or even removing this option could result in your config being broken.
|
||||
#
|
||||
config-version: 5
|
||||
configVersion: 7
|
||||
```
|
||||
///
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
---
|
||||
icon: octicons/project-roadmap-24
|
||||
---
|
||||
|
||||
# Tutorials
|
||||
|
||||
This page lists tutorials made by the community of AdvancedServerList.
|
||||
Be aware that any info shown may be outdated.
|
||||
|
||||
Can't find a tutorial that exists? Join the [M.O.S.S. Discord][discord]{ target="_blank" rel="nofollow" } and suggest it in `#asl-support` to be added.
|
||||
|
||||
## Video Tutorials
|
||||
|
||||
Below is a collection of video tutorials made.
|
||||
|
||||
/// note
|
||||
For privacy reasons are only thumbnails of the videos displayed, as otherwise sensitive data would be sent via embedding the videos themself.
|
||||
you can click the image to be sent to the actual video.
|
||||
///
|
||||
|
||||
### KasaiSora
|
||||
|
||||
**Video Language:** :flag_gb: English
|
||||
|
||||
[](https://youtube.com/watch?v=9cU0uUWHOO0){ target="_blank" rel="nofollow" }
|
||||
|
||||
### Ajneb97
|
||||
|
||||
**Video Language:** :flag_es: Spanish
|
||||
|
||||
[](https://youtube.com/watch?v=rIbljm_4HVI){ target="_blank" rel="nofollow" }
|
||||
|
||||
## Text Tutorials
|
||||
|
||||
Text-based tutorials (Forum Posts, Blog Posts, etc).
|
||||
|
||||
*No entries yet*
|
||||
@@ -50,6 +50,12 @@ AdvancedServerList supports the following platforms:
|
||||
----
|
||||
|
||||
A simple guide on how to get started with AdvancedServerList.
|
||||
|
||||
----
|
||||
|
||||
**Other Pages:**
|
||||
|
||||
- [:octicons-project-roadmap-24: Tutorials](getting-started/tutorials.md)
|
||||
|
||||
- [:octicons-rel-file-path-24: **Commands**](commands/index.md)
|
||||
|
||||
@@ -62,6 +68,14 @@ AdvancedServerList supports the following platforms:
|
||||
----
|
||||
|
||||
Pages containing information about the Server List Profile System and all its available options.
|
||||
|
||||
----
|
||||
|
||||
**Other Pages:**
|
||||
|
||||
- [:octicons-file-code-24: Expressions](profiles/expressions.md)
|
||||
- [:octicons-pencil-24: Formatting](profiles/formatting.md)
|
||||
- [:material-percent: Placeholders](profiles/placeholders.md)
|
||||
|
||||
- [:octicons-list-unordered-24: **Examples**](examples/index.md)
|
||||
|
||||
@@ -74,12 +88,35 @@ AdvancedServerList supports the following platforms:
|
||||
----
|
||||
|
||||
Pages explaining how to migrate from one version of the plugin to another.
|
||||
|
||||
----
|
||||
|
||||
**Other Pages:**
|
||||
|
||||
- Plugins
|
||||
- [:octicons-arrow-right-24: MiniMOTD](migration/plugins/minimotd.md)
|
||||
- [:octicons-arrow-right-24: ServerListPlus](migration/plugins/serverlistplus.md)
|
||||
- Versions
|
||||
- [:octicons-arrow-right-24: v3.8.0 to v3.9.0](migration/versions/v3.8.0-to-v3.9.0.md)
|
||||
- [:octicons-arrow-right-24: v3.7.0 to v3.8.0](migration/versions/v3.7.0-to-v3.8.0.md)
|
||||
- [:octicons-arrow-right-24: < v3.7.0 to v3.7.0](migration/versions/pre-v3.7.0-to-v3.7.0.md)
|
||||
- [:octicons-arrow-right-24: v1.9.0 to v1.10.0](migration/versions/v1.9.0-to-v1.10.0.md)
|
||||
- [:octicons-arrow-right-24: v1.5.3 to v1.6.0](migration/versions/v1.5.3-to-v1.6.0.md)
|
||||
|
||||
- [:octicons-command-palette-24: **API**](api/index.md)
|
||||
|
||||
----
|
||||
|
||||
Pages all about the API of AdvancedServerList.
|
||||
|
||||
----
|
||||
|
||||
**Other Pages:**
|
||||
|
||||
- [:octicons-log-24: Changelog](api/changelog.md)
|
||||
- [:octicons-link-external-24: Javadocs](api/javadocs.md)
|
||||
- [:simple-codeberg: Source Code](api/source.md)
|
||||
- [:octicons-file-code-24: Reference](api/reference/index.md)
|
||||
|
||||
- [:octicons-plus-circle-24: **Addons**](addons/index.md)
|
||||
|
||||
@@ -87,6 +124,12 @@ AdvancedServerList supports the following platforms:
|
||||
|
||||
Pages listing 1st-party and 3rd-party add-ons for AdvancedServerList.
|
||||
|
||||
----
|
||||
|
||||
**Other Pages:**
|
||||
|
||||
- [:octicons-stop-24: BanPlugins Addon](addons/banplugins.md)
|
||||
|
||||
- [:material-percent: **PlaceholderAPI**](placeholderapi/index.md)
|
||||
|
||||
----
|
||||
|
||||
@@ -11,13 +11,13 @@ These pages may include important information about the migration process and wh
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [**MiniMOTD**](minimotd.md)
|
||||
- [**MiniMOTD**](plugins/minimotd.md)
|
||||
|
||||
----
|
||||
|
||||
Migrate from the Plugin [MiniMOTD](https://github.com/jpenilla/MiniMOTD){ target="_blank" rel="nofollow" }
|
||||
|
||||
- [**ServerListPlus**](serverlistplus.md)
|
||||
- [**ServerListPlus**](plugins/serverlistplus.md)
|
||||
|
||||
----
|
||||
|
||||
@@ -32,31 +32,31 @@ These guides are only for the Server List Profile files, as the config.yml gets
|
||||
|
||||
<div class="grid cards" markdown>
|
||||
|
||||
- [**v3.8.0 to v3.9.0**](v3_8_0-to-v3_9_0.md)
|
||||
- [**v3.8.0 to v3.9.0**](versions/v3.8.0-to-v3.9.0.md)
|
||||
|
||||
----
|
||||
|
||||
Migrate from version 3.8.0 to 3.9.0.
|
||||
|
||||
- [**v3.7.0 to v3.8.0**](v3_7_0-to-v3_8_0.md)
|
||||
- [**v3.7.0 to v3.8.0**](versions/v3.7.0-to-v3.8.0.md)
|
||||
|
||||
----
|
||||
|
||||
Migrating from version 3.7.0 to 3.8.0.
|
||||
|
||||
- [**< v3.7.0 to v3.7.0**](pre-v3_7_0-to-v3_7_0.md)
|
||||
- [**< v3.7.0 to v3.7.0**](versions/pre-v3.7.0-to-v3.7.0.md)
|
||||
|
||||
----
|
||||
|
||||
Migrate from any version prior to 3.7.0 to 3.7.0 or newer.
|
||||
|
||||
- [**v1.9.0 to v1.10.0**](v1_9_0-to-v1_10_0.md)
|
||||
- [**v1.9.0 to v1.10.0**](versions/v1.9.0-to-v1.10.0.md)
|
||||
|
||||
----
|
||||
|
||||
Migrate from version 1.9.0 to 1.10.0.
|
||||
|
||||
- [**v1.5.3 to v1.6.0**](v1_5_3-to-v1_6_0.md)
|
||||
- [**v1.5.3 to v1.6.0**](versions/v1.5.3-to-v1.6.0.md)
|
||||
|
||||
----
|
||||
|
||||
|
||||
@@ -11,14 +11,14 @@ Version `4.10.0` added support for migrating your existing `main.conf` configura
|
||||
|
||||
## How to Migrate
|
||||
|
||||
Execute the command [`/asl migrate minimotd`](../commands/index.md#migrate) to start the migration process. Make sure the `main.conf` file is present in `/plugins/MiniMOTD/` (`minimotd-velocity` on Velocity).
|
||||
Execute the command [`/asl migrate minimotd`](../../commands/index.md#migrate) to start the migration process. Make sure the `main.conf` file is present in `/plugins/MiniMOTD/` (`minimotd-velocity` on Velocity).
|
||||
|
||||
## Example
|
||||
|
||||
Below can you find a full example of a `main.conf` file and the corresponding migrated files from AdvancedServerList:
|
||||
|
||||
/// tab | :octicons-file-code-24: main.conf
|
||||
```conf
|
||||
```ruby
|
||||
icon-enabled=true
|
||||
motd-enabled=true
|
||||
motds=[
|
||||
@@ -48,7 +48,7 @@ The following Favicon options get converted into an equivalent one:
|
||||
|
||||
## How to Migrate
|
||||
|
||||
Execute the command [`/asl migrate serverlistplus`](../commands/index.md#migrate) to start the migration process. Make sure that ServerListPlus is present and enabled.
|
||||
Execute the command [`/asl migrate serverlistplus`](../../commands/index.md#migrate) to start the migration process. Make sure that ServerListPlus is present and enabled.
|
||||
|
||||
## Example
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ icon: octicons/arrow-right-24
|
||||
# < v3.7.0 to v3.7.0
|
||||
|
||||
Version 3.7.0 of AdvancedServerList brought significant changes to its conditions system.
|
||||
Namely, the `conditions` option is now deprecated and planned for removal in a future release of the Plugin, and the new [`condition`](../profiles/index.md#condition) option should now be used instead.
|
||||
Namely, the `conditions` option is now deprecated and planned for removal in a future release of the Plugin, and the new [`condition`](../../profiles/index.md#condition) option should now be used instead.
|
||||
|
||||
## Migration
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -6,8 +6,6 @@ icon: material/percent
|
||||
|
||||
AdvancedServerList provides support for [PlaceholderAPI] placeholders to be used, while also providing its own set of placeholders.
|
||||
|
||||
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
|
||||
|
||||
## Own placeholders
|
||||
|
||||
The below listed placeholders can be used through PlaceholderAPI in other plugins.
|
||||
|
||||
+22
-7
@@ -91,6 +91,8 @@ motd:
|
||||
|
||||
## Motd
|
||||
|
||||
<!-- admo:tip Start a line with <code><center></code> to have it centered. -->
|
||||
|
||||
The `motd` option allows you to alter the "Message of the day" that is being displayed on a server in the multiplayer screen.
|
||||
Please see the [Formatting](formatting.md) for all supported formatting options.
|
||||
|
||||
@@ -119,14 +121,27 @@ motd:
|
||||
|
||||
The `favicon` option can be used to define an image to display in the server list.
|
||||
|
||||
The Value can be one of three possible options, each being checked for in order:
|
||||
The Value can be one of the following:
|
||||
|
||||
- A URL pointing to an image file. The URL needs to start with `https://` to work.
|
||||
- A PNG filename, including `.png` file extension, matching a PNG file in the `favicons` folder.
|
||||
- A player name or UUID, or a [placeholder](placeholders.md) that resolves into one.
|
||||
- A URL pointing to a Image file. The URL needs to start with `https://` for it to work.
|
||||
- A filename matching a pre-existing file in the `favicons` folder of the Plugin.
|
||||
- Only PNG files are supported for now and the provided filename needs to end with `.png`
|
||||
- `random` can be used to have the plugin select a random image from the Favicons folder.
|
||||
- A player name or UUID.
|
||||
- `${player name}`, `${player uuid}` or any [placeholder](placeholders.md) that resolves into a player name/UUID can be used.
|
||||
- Uses [mc-heads.net](https://mc-heads.net) to resolve the Player Name/UUID.
|
||||
|
||||
Note that for the name/UUID, the site https://mc-heads.net is being used.
|
||||
Use the URL option with the `${player uuid}` placeholder if you want to use another service.
|
||||
/// details | Why is the favicon from URL/Placeholder not showing?
|
||||
type: question
|
||||
|
||||
AdvancedServerList has to create a Favicon instance to use, as the Proxy/Server doesn't directly use PNG images.
|
||||
This action takes time, so to not unnecessarely delay the Pinged Proxy/Server from showing is this done asynchrnously.
|
||||
This has the issue that the Proxy/Server may be done with handling the Ping before AdvancedServerList is done creating the Favicon, resulting in no favicon being displayed.
|
||||
|
||||
This issue is only present for when using either a URL or a Player name/uuid and not for local favicons, as those are created when the plugin loads.
|
||||
|
||||
Favicons *should* display on the second ping, if pinged within the configured favicon cache time (Default: 1 minute).
|
||||
///
|
||||
|
||||
/// details | Example
|
||||
type: example
|
||||
@@ -356,7 +371,7 @@ You can use placeholders that resolve into numbers for this option.
|
||||
/// details | Example
|
||||
type: example
|
||||
|
||||
```yaml title="YAML file
|
||||
```yaml title="YAML file"
|
||||
priority: 0
|
||||
|
||||
# Hides the MOTD for demonstration purposes
|
||||
|
||||
+24
-8
@@ -68,6 +68,18 @@ extra:
|
||||
plugins:
|
||||
- search
|
||||
- glightbox
|
||||
- redirects:
|
||||
redirect_maps:
|
||||
# Plugin Migration Pages
|
||||
'migration/minimotd.md': 'migration/plugins/minimotd.md'
|
||||
'migration/serverlistplus.md': 'migration/plugins/serverlistplus.md'
|
||||
#
|
||||
# Version Migration Pages
|
||||
'migration/v3_8_0-to-v3_9_0.md': 'migration/versions/v3.8.0-to-v3.9.0.md'
|
||||
'migration/v3_7_0-to-v3_8_0.md': 'migration/versions/v3.7.0-to-v3.8.0.md'
|
||||
'migration/pre-v3_7_0-to-v3_7_0.md': 'migration/versions/pre-v3.7.0-to-v3.7.0.md'
|
||||
'migration/v1_9_0-to-v1_10_0.md': 'migration/versions/v1.9.0-to-v1.10.0.md'
|
||||
'migration/v1_5_3-to-v1_6_0.md': 'migration/versions/v1.5.3-to-v1.6.0.md'
|
||||
- pagenav-generator
|
||||
|
||||
markdown_extensions:
|
||||
@@ -84,6 +96,8 @@ markdown_extensions:
|
||||
- pymdownx.superfences:
|
||||
- pymdownx.snippets:
|
||||
base_path: docs/.snippets
|
||||
auto_append:
|
||||
- links.md
|
||||
- pymdownx.blocks.admonition:
|
||||
types:
|
||||
- note
|
||||
@@ -108,7 +122,9 @@ hooks:
|
||||
|
||||
nav:
|
||||
- Home: index.md
|
||||
- Getting Started: getting-started/index.md
|
||||
- Getting Started:
|
||||
- getting-started/index.md
|
||||
- Tutorials: getting-started/tutorials.md
|
||||
- Commands: commands/index.md
|
||||
- Profiles:
|
||||
- profiles/index.md
|
||||
@@ -119,14 +135,14 @@ nav:
|
||||
- Migration:
|
||||
- migration/index.md
|
||||
- Other Plugins:
|
||||
- MiniMOTD: migration/minimotd.md
|
||||
- ServerListPlus: migration/serverlistplus.md
|
||||
- MiniMOTD: migration/plugins/minimotd.md
|
||||
- ServerListPlus: migration/plugins/serverlistplus.md
|
||||
- AdvancedServerList:
|
||||
- v3.8.0 to v3.9.0: migration/v3_8_0-to-v3_9_0.md
|
||||
- v3.7.0 to v3.8.0: migration/v3_7_0-to-v3_8_0.md
|
||||
- '< v3.7.0 to v3.7.0': migration/pre-v3_7_0-to-v3_7_0.md
|
||||
- v1.9.0 to v1.10.0: migration/v1_9_0-to-v1_10_0.md
|
||||
- v1.5.3 to v1.6.0: migration/v1_5_3-to-v1_6_0.md
|
||||
- v3.8.0 to v3.9.0: migration/versions/v3.8.0-to-v3.9.0.md
|
||||
- v3.7.0 to v3.8.0: migration/versions/v3.7.0-to-v3.8.0.md
|
||||
- '< v3.7.0 to v3.7.0': migration/versions/pre-v3.7.0-to-v3.7.0.md
|
||||
- v1.9.0 to v1.10.0: migration/versions/v1.9.0-to-v1.10.0.md
|
||||
- v1.5.3 to v1.6.0: migration/versions/v1.5.3-to-v1.6.0.md
|
||||
- API:
|
||||
- api/index.md
|
||||
- Changelog: api/changelog.md
|
||||
|
||||
+11
-1
@@ -99,7 +99,7 @@
|
||||
<dependency>
|
||||
<groupId>com.viaversion</groupId>
|
||||
<artifactId>viaversion-api</artifactId>
|
||||
<version>5.0.3</version>
|
||||
<version>5.2.0</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -118,6 +118,16 @@
|
||||
<resource>
|
||||
<filtering>true</filtering>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
<excludes>
|
||||
<exclude>char-widths.json.gz</exclude>
|
||||
</excludes>
|
||||
</resource>
|
||||
<resource>
|
||||
<filtering>false</filtering>
|
||||
<directory>${project.basedir}/src/main/resources</directory>
|
||||
<includes>
|
||||
<include>char-widths.json.gz</include>
|
||||
</includes>
|
||||
</resource>
|
||||
</resources>
|
||||
<plugins>
|
||||
|
||||
@@ -67,18 +67,6 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
try{
|
||||
Class.forName("io.papermc.paper.configuration.ConfigurationLoaders");
|
||||
}catch(ClassNotFoundException ignored){
|
||||
try{
|
||||
// Above class only exists since 1.19+. This is a fallback to see if an older version is used.
|
||||
Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||
}catch(ClassNotFoundException ex){
|
||||
printNoPaperWarning();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.core = AdvancedServerList.init(this, new PaperPlayerPlaceholders(), new PaperServerPlaceholders(this));
|
||||
|
||||
if(getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
@@ -101,9 +89,9 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
|
||||
@Override
|
||||
public void loadCommands(){
|
||||
if(getServer().getCommandMap().register("asl", new CmdAdvancedServerList(this))){
|
||||
getPluginLogger().info("Registered /advancedserverlist:advancedserverlist");
|
||||
getPluginLogger().success("Registered <white>/advancedserverlist:advancedserverlist</white>!");
|
||||
}else{
|
||||
getPluginLogger().info("Registered /asl:advancedserverlist");
|
||||
getPluginLogger().success("Registered <white>/asl:advancedserverlist</white>!");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -149,6 +137,11 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
|
||||
libraryManager.loadLibrary(lib);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScheduler(){
|
||||
// Unused
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancedServerList<CachedServerIcon> getCore(){
|
||||
return core;
|
||||
@@ -220,27 +213,6 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
|
||||
return players.size();
|
||||
}
|
||||
|
||||
private void printNoPaperWarning(){
|
||||
getPluginLogger().warn("======================================================================================");
|
||||
getPluginLogger().warn("THIS SERVER DOES NOT USE PAPER OR A COMPATIBLE FORK!");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("AdvancedServerList 3.6.0 has dropped support for Spigot-based servers.");
|
||||
getPluginLogger().warn("This means that only servers using Paper or a Paper-compatible fork may work.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("Reasons for this removal:");
|
||||
getPluginLogger().warn(" - Reliance on a different plugin for core functionalities.");
|
||||
getPluginLogger().warn(" - Bad dependency loading limited to MavenCentral only.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("Please consider switching to Paper or one of the Paper-compatible forks to benefit");
|
||||
getPluginLogger().warn("from overall performance improvements amongst other things.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("Disabling AdvancedServerList. If you believe this is an error, report it on");
|
||||
getPluginLogger().warn("Codeberg: https://codeberg.org/Andre601/AdvancedServerList");
|
||||
getPluginLogger().warn("======================================================================================");
|
||||
|
||||
Bukkit.getPluginManager().disablePlugin(this);
|
||||
}
|
||||
|
||||
private String getNewVersion(){
|
||||
ServerBuildInfo info = ServerBuildInfo.buildInfo();
|
||||
|
||||
@@ -250,7 +222,7 @@ public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon
|
||||
|
||||
OptionalInt build = info.buildNumber();
|
||||
if(build.isEmpty())
|
||||
return String.format("%s (%s, Version: %s)", name, id, version);
|
||||
return String.format("%s (ID: %s, Version: %s)", name, id, version);
|
||||
|
||||
return String.format("%s (ID: %s, Version: %s, Build: %d)", name, id, version, build.getAsInt());
|
||||
}
|
||||
|
||||
@@ -48,5 +48,20 @@ public class LoadEvent implements Listener{
|
||||
|
||||
// Load currently loaded worlds into the WorldCache
|
||||
Bukkit.getWorlds().forEach(world -> plugin.getWorldCache().addWorld(world));
|
||||
|
||||
// Print a warning if server load was after a reload.
|
||||
if(event.getType() != ServerLoadEvent.LoadType.RELOAD)
|
||||
return;
|
||||
|
||||
plugin.getPluginLogger().warn("======================================================================================");
|
||||
plugin.getPluginLogger().warn("SERVER RELOAD DETECTED!");
|
||||
plugin.getPluginLogger().warn("");
|
||||
plugin.getPluginLogger().warn("A server reload has been detected by AdvancedServerList, meaning either the /reload");
|
||||
plugin.getPluginLogger().warn("command or Bukkit.reload() was executed.");
|
||||
plugin.getPluginLogger().warn("");
|
||||
plugin.getPluginLogger().warn("YOU WILL GET NO SUPPORT FOR THE PLUGIN FOR ANY ISSUES YOU ENCOUNTER AFTER A SERVER");
|
||||
plugin.getPluginLogger().warn("RELOAD!");
|
||||
plugin.getPluginLogger().warn("ALWAYS RESTART YOUR SERVER. NEVER RELOAD IT!");
|
||||
plugin.getPluginLogger().warn("======================================================================================");
|
||||
}
|
||||
}
|
||||
+1
-6
@@ -205,12 +205,7 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
|
||||
for(String line : lines){
|
||||
String parsed = ComponentParser.text(line)
|
||||
.modifyText(text -> StringReplacer.replace(text, player, server))
|
||||
.modifyText(text -> {
|
||||
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.modifyText(text -> parsePAPIPlaceholders(text, player))
|
||||
.toString();
|
||||
|
||||
playerList.add(function.apply(parsed));
|
||||
|
||||
@@ -26,19 +26,18 @@
|
||||
package ch.andre601.advancedserverlist.paper.logging;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.paper.PaperCore;
|
||||
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||
|
||||
public class PaperLogger implements PluginLogger{
|
||||
|
||||
private final PaperCore plugin;
|
||||
private final Logger logger;
|
||||
private final ComponentLogger logger;
|
||||
|
||||
public PaperLogger(PaperCore plugin){
|
||||
this.plugin = plugin;
|
||||
this.logger = plugin.getLogger();
|
||||
this.logger = plugin.getComponentLogger();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -55,21 +54,21 @@ public class PaperLogger implements PluginLogger{
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... args){
|
||||
logger.info(String.format(msg, args));
|
||||
logger.info(ComponentParser.textFormatted("<grey>" + msg, args).toComponent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... args){
|
||||
logger.warning(String.format(msg, args));
|
||||
logger.warn(ComponentParser.textFormatted("<yellow>" + msg, args).toComponent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable){
|
||||
logger.log(Level.WARNING, msg, throwable);
|
||||
logger.warn(ComponentParser.text("<yellow>" + msg).toComponent(), throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable, Object... args){
|
||||
logger.log(Level.WARNING, String.format(msg, args), throwable);
|
||||
logger.warn(ComponentParser.textFormatted("<yellow>" + msg, args).toComponent(), throwable);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -36,7 +36,7 @@ public class PaperPlayerImpl implements BukkitPlayer{
|
||||
private final OfflinePlayer player;
|
||||
|
||||
private final String name;
|
||||
private int protocol;
|
||||
private final int protocol;
|
||||
private final UUID uuid;
|
||||
|
||||
private boolean playedBefore = false;
|
||||
|
||||
+18
-8
@@ -46,6 +46,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PAPIPlaceholders extends PlaceholderExpansion{
|
||||
|
||||
@@ -114,9 +115,9 @@ public class PAPIPlaceholders extends PlaceholderExpansion{
|
||||
|
||||
BukkitServer finalServer = new PaperServerImpl(plugin.getWorldCache().worlds(), online, max, host);
|
||||
return switch(identifier.toLowerCase(Locale.ROOT)){
|
||||
case "motd" -> getOption(entry.motd(), pl, player, finalServer);
|
||||
case "motd" -> getOption(entry.motd(), pl, player, finalServer, true);
|
||||
case "favicon" -> getOption(entry.favicon(), pl, player, finalServer);
|
||||
case "playercount_hover" -> getOption(entry.players(), pl, player, finalServer);
|
||||
case "playercount_hover" -> getOption(entry.players(), pl, player, finalServer, false);
|
||||
case "playercount_text" -> getOption(entry.playerCountText(), pl, player, finalServer);
|
||||
case "playercount_extraplayers" -> extraPlayers == null ? "null" : String.valueOf(extraPlayers);
|
||||
case "playercount_maxplayers" -> maxPlayers == null ? "null" : String.valueOf(maxPlayers);
|
||||
@@ -136,14 +137,23 @@ public class PAPIPlaceholders extends PlaceholderExpansion{
|
||||
}
|
||||
|
||||
private String getOption(String str, Player pl, BukkitPlayer player, BukkitServer server){
|
||||
return getOption(Collections.singletonList(str), pl, player, server);
|
||||
return getOption(Collections.singletonList(str), pl, player, server, false);
|
||||
}
|
||||
|
||||
private String getOption(List<String> list, Player pl, BukkitPlayer player, BukkitServer server){
|
||||
return ComponentParser.list(list)
|
||||
.modifyText(text -> StringReplacer.replace(text, player, server))
|
||||
.modifyText(text -> PlaceholderAPI.setPlaceholders(pl, text))
|
||||
.toString();
|
||||
private String getOption(List<String> list, Player pl, BukkitPlayer player, BukkitServer server, boolean isMotd){
|
||||
return list.stream()
|
||||
.map(line -> ComponentParser.text(line)
|
||||
.modifyText(text -> StringReplacer.replace(text, player, server))
|
||||
.modifyText(text -> PlaceholderAPI.setPlaceholders(pl, text))
|
||||
.modifyText(text -> {
|
||||
if(isMotd)
|
||||
return plugin.getCore().getTextCenterUtil().getCenteredText(text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.toString()
|
||||
)
|
||||
.collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
private Integer parseNumberOption(String option, Player pl, BukkitPlayer player, BukkitServer server){
|
||||
|
||||
@@ -5,7 +5,7 @@ description: '${plugin.description}'
|
||||
|
||||
main: 'ch.andre601.advancedserverlist.paper.PaperCore'
|
||||
|
||||
api-version: '1.19'
|
||||
api-version: '1.20'
|
||||
|
||||
folia-supported: true
|
||||
|
||||
@@ -24,15 +24,6 @@ dependencies:
|
||||
load: BEFORE
|
||||
required: false
|
||||
|
||||
# The below stuff is NOT used by Paper plugin.
|
||||
commands:
|
||||
advancedserverlist:
|
||||
description: 'Main command of AdvancedServerList'
|
||||
usage: '/<command> [help|reload]'
|
||||
aliases:
|
||||
- 'asl'
|
||||
permission: 'advancedserverlist.admin'
|
||||
|
||||
# This is actually supported(?)
|
||||
permissions:
|
||||
advancedserverlist.*:
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
#
|
||||
# This file is kept for Folia support.
|
||||
#
|
||||
|
||||
name: 'AdvancedServerList'
|
||||
author: 'Andre_601'
|
||||
version: '${plugin.version}'
|
||||
description: '${plugin.description}'
|
||||
|
||||
main: 'ch.andre601.advancedserverlist.paper.PaperCore'
|
||||
|
||||
api-version: '1.19'
|
||||
|
||||
folia-supported: true
|
||||
|
||||
libraries:
|
||||
- 'org.spongepowered:configurate-yaml:4.1.2'
|
||||
- 'net.kyori:adventure-text-serializer-legacy:4.12.0'
|
||||
- 'com.squareup.okhttp3:okhttp:4.10.0'
|
||||
|
||||
softdepend:
|
||||
- 'PlaceholderAPI'
|
||||
- 'Maintenance'
|
||||
|
||||
commands:
|
||||
advancedserverlist:
|
||||
description: 'Main command of AdvancedServerList'
|
||||
usage: '/<command> [help|reload|clearCache]'
|
||||
aliases:
|
||||
- 'asl'
|
||||
permission: 'advancedserverlist.admin'
|
||||
|
||||
permissions:
|
||||
advancedserverlist.*:
|
||||
description: 'Grants access to all permissions'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.admin'
|
||||
advancedserverlist.admin:
|
||||
description: 'Grants access to all permissions'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.command.*'
|
||||
advancedserverlist.command.*:
|
||||
description: 'Grants access to all commands'
|
||||
default: op
|
||||
children:
|
||||
- 'advancedserverlist.command.help'
|
||||
- 'advancedserverlist.command.reload'
|
||||
advancedserverlist.command.help:
|
||||
description: 'Grants access to /asl help'
|
||||
default: op
|
||||
advancedserverlist.command.reload:
|
||||
description: 'Grants access to /asl reload'
|
||||
default: op
|
||||
advancedserverlist.command.clearcache:
|
||||
description: 'Clears the Player and Favicon cache'
|
||||
default: op
|
||||
@@ -37,14 +37,14 @@
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<plugin.version>5.0.2</plugin.version>
|
||||
<plugin.version>5.3.0</plugin.version>
|
||||
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
|
||||
|
||||
<api.version>4.0.0</api.version>
|
||||
|
||||
<dependency.adventure-api>4.17.0</dependency.adventure-api>
|
||||
<dependency.adventure-text-minimessage>4.17.0</dependency.adventure-text-minimessage>
|
||||
<dependency.adventure-text-serializer-legacy>4.17.0</dependency.adventure-text-serializer-legacy>
|
||||
<dependency.adventure-api>4.18.0</dependency.adventure-api>
|
||||
<dependency.adventure-text-minimessage>4.18.0</dependency.adventure-text-minimessage>
|
||||
<dependency.adventure-text-serializer-legacy>4.18.0</dependency.adventure-text-serializer-legacy>
|
||||
<dependency.adventure-platform-bungeecord>4.3.4</dependency.adventure-platform-bungeecord>
|
||||
<dependency.configurate-yaml>4.1.2</dependency.configurate-yaml>
|
||||
|
||||
|
||||
File renamed without changes.
+2
-1
@@ -1,3 +1,4 @@
|
||||
mkdocs-material==9.5.39
|
||||
mkdocs-material==9.5.49
|
||||
mkdocs-glightbox==0.4.0
|
||||
mkdocs-redirects==1.2.2
|
||||
git+https://github.com/Andre601/mkdocs-pagenav-generator
|
||||
+17
-1
@@ -48,6 +48,10 @@
|
||||
<id>velocity-repo</id>
|
||||
<url>https://repo.papermc.io/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>repo-sayandevelopment</id>
|
||||
<url>https://repo.sayandev.org/snapshots</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
@@ -68,7 +72,7 @@
|
||||
<dependency>
|
||||
<groupId>com.velocitypowered</groupId>
|
||||
<artifactId>velocity-api</artifactId>
|
||||
<version>3.1.2-SNAPSHOT</version>
|
||||
<version>3.4.0-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -95,6 +99,18 @@
|
||||
<version>2.9.0-4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sayandev</groupId>
|
||||
<artifactId>sayanvanish-api</artifactId>
|
||||
<version>1.6.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sayandev</groupId>
|
||||
<artifactId>sayanvanish-proxy-velocity</artifactId>
|
||||
<version>1.6.1</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- Other -->
|
||||
<dependency>
|
||||
|
||||
@@ -47,24 +47,31 @@ import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.proxy.server.RegisteredServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.api.scheduler.ScheduledTask;
|
||||
import com.velocitypowered.api.util.Favicon;
|
||||
import de.myzelyam.api.vanish.VelocityVanishAPI;
|
||||
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bstats.velocity.Metrics;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.sayandev.sayanvanish.velocity.api.SayanVanishVelocityAPI;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class VelocityCore implements PluginCore<Favicon>{
|
||||
|
||||
private final Logger logger = LoggerFactory.getLogger("AdvancedServerList");
|
||||
private final Map<String, ServerPing> fetchedServers = new ConcurrentHashMap<>();
|
||||
|
||||
private final PluginLogger pluginLogger;
|
||||
private final ComponentLogger logger;
|
||||
|
||||
private final ProxyServer proxy;
|
||||
private final Path path;
|
||||
private final Metrics.Factory metrics;
|
||||
@@ -74,9 +81,13 @@ public class VelocityCore implements PluginCore<Favicon>{
|
||||
|
||||
private VelocityLibraryManager<VelocityCore> libraryManager = null;
|
||||
|
||||
private ScheduledTask scheduledTask = null;
|
||||
|
||||
@Inject
|
||||
public VelocityCore(ProxyServer proxy, @DataDirectory Path path, Metrics.Factory metrics){
|
||||
this.pluginLogger = new VelocityLogger(this, this.logger);
|
||||
ComponentLogger logger = ComponentLogger.logger("AdvancedServerList");
|
||||
this.pluginLogger = new VelocityLogger(this, logger);
|
||||
this.logger = logger;
|
||||
|
||||
this.proxy = proxy;
|
||||
this.path = path;
|
||||
@@ -92,6 +103,8 @@ public class VelocityCore implements PluginCore<Favicon>{
|
||||
@Subscribe
|
||||
public void pluginDisable(ProxyShutdownEvent event){
|
||||
core.disable();
|
||||
if(scheduledTask != null)
|
||||
scheduledTask.cancel();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -102,6 +115,7 @@ public class VelocityCore implements PluginCore<Favicon>{
|
||||
.build();
|
||||
|
||||
getProxy().getCommandManager().register(command, new CmdAdvancedServerList(this));
|
||||
getPluginLogger().success("Registered <white>/advancedserverlist</white>!");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -147,6 +161,13 @@ public class VelocityCore implements PluginCore<Favicon>{
|
||||
libraryManager.loadLibrary(lib);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startScheduler(){
|
||||
scheduledTask = getProxy().getScheduler().buildTask(this, this::fetchServers)
|
||||
.repeat(10, TimeUnit.SECONDS)
|
||||
.schedule();
|
||||
}
|
||||
|
||||
@Override
|
||||
public AdvancedServerList<Favicon> getCore(){
|
||||
return core;
|
||||
@@ -206,8 +227,25 @@ public class VelocityCore implements PluginCore<Favicon>{
|
||||
// Exclude players when PremiumVanish is enabled and player is hidden.
|
||||
if(getProxy().getPluginManager().isLoaded("premiumvanish")){
|
||||
players.removeIf(VelocityVanishAPI::isInvisible);
|
||||
}else // Do the same if SayanVanish is enabled.
|
||||
if(getProxy().getPluginManager().isLoaded("sayanvanish")){
|
||||
players.removeIf(player -> SayanVanishVelocityAPI.getInstance().isVanished(player.getUniqueId()));
|
||||
}
|
||||
|
||||
return players.size();
|
||||
}
|
||||
|
||||
public Map<String, ServerPing> getFetchedServers(){
|
||||
return fetchedServers;
|
||||
}
|
||||
|
||||
private void fetchServers(){
|
||||
fetchedServers.clear();
|
||||
getProxy().getAllServers().forEach(server -> server.ping().whenComplete((ping, throwable) -> {
|
||||
if(throwable != null)
|
||||
return;
|
||||
|
||||
fetchedServers.put(server.getServerInfo().getName(), ping);
|
||||
}));
|
||||
}
|
||||
}
|
||||
+1
@@ -109,6 +109,7 @@ public class VelocityEventWrapper implements GenericEventWrapper<Favicon, Veloci
|
||||
for(int i = 0; i < players.length; i++){
|
||||
String parsed = ComponentParser.text(lines.get(i))
|
||||
.modifyText(text -> StringReplacer.replace(text, player, server))
|
||||
.modifyText(text -> parsePAPIPlaceholders(text, player))
|
||||
.toString();
|
||||
|
||||
players[i] = new ServerPing.SamplePlayer(parsed, UUID.randomUUID());
|
||||
|
||||
+8
-7
@@ -26,15 +26,16 @@
|
||||
package ch.andre601.advancedserverlist.velocity.logging;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.velocity.VelocityCore;
|
||||
import org.slf4j.Logger;
|
||||
import net.kyori.adventure.text.logger.slf4j.ComponentLogger;
|
||||
|
||||
public class VelocityLogger implements PluginLogger{
|
||||
|
||||
private final VelocityCore plugin;
|
||||
private final Logger logger;
|
||||
private final ComponentLogger logger;
|
||||
|
||||
public VelocityLogger(VelocityCore plugin, Logger logger){
|
||||
public VelocityLogger(VelocityCore plugin, ComponentLogger logger){
|
||||
this.plugin = plugin;
|
||||
this.logger = logger;
|
||||
}
|
||||
@@ -53,21 +54,21 @@ public class VelocityLogger implements PluginLogger{
|
||||
|
||||
@Override
|
||||
public void info(String msg, Object... args){
|
||||
logger.info(String.format(msg, args));
|
||||
logger.info(ComponentParser.textFormatted("<grey>" + msg, args).toComponent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Object... args){
|
||||
logger.warn(String.format(msg, args));
|
||||
logger.warn(ComponentParser.textFormatted(msg, args).toComponent());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable){
|
||||
logger.warn(msg, throwable);
|
||||
logger.warn(ComponentParser.text(msg).toComponent(), throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable, Object... args){
|
||||
logger.warn(String.format(msg, args), throwable);
|
||||
logger.warn(ComponentParser.textFormatted(msg, args).toComponent(), throwable);
|
||||
}
|
||||
}
|
||||
+1
-21
@@ -7,22 +7,14 @@ import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.velocity.VelocityCore;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
public class VelocityProxyPlaceholders extends PlaceholderProvider{
|
||||
|
||||
private final Map<String, ServerPing> serverStates = new ConcurrentHashMap<>();
|
||||
private final VelocityCore plugin;
|
||||
|
||||
private VelocityProxyPlaceholders(VelocityCore plugin){
|
||||
super("proxy");
|
||||
|
||||
this.plugin = plugin;
|
||||
plugin.getProxy().getScheduler().buildTask(plugin, this::fetchServerStates)
|
||||
.repeat(Duration.ofSeconds(10))
|
||||
.schedule();
|
||||
}
|
||||
|
||||
public static VelocityProxyPlaceholders init(VelocityCore plugin){
|
||||
@@ -35,7 +27,7 @@ public class VelocityProxyPlaceholders extends PlaceholderProvider{
|
||||
if(args.length < 2)
|
||||
return null;
|
||||
|
||||
ServerPing ping = serverStates.get(args[1]);
|
||||
ServerPing ping = plugin.getFetchedServers().get(args[1]);
|
||||
return switch(args[0]){
|
||||
case "status" -> ping == null ? "offline" : "online";
|
||||
case "motd" -> {
|
||||
@@ -67,16 +59,4 @@ public class VelocityProxyPlaceholders extends PlaceholderProvider{
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private void fetchServerStates(){
|
||||
serverStates.clear();
|
||||
plugin.getProxy().getAllServers().forEach(server -> server.ping().whenComplete((ping, throwable) -> {
|
||||
if(throwable != null){
|
||||
plugin.getPluginLogger().warn("Encountered an exception while fetching status of Server %s", throwable, server.getServerInfo().getName());
|
||||
return;
|
||||
}
|
||||
|
||||
serverStates.put(server.getServerInfo().getName(), ping);
|
||||
}));
|
||||
}
|
||||
}
|
||||
@@ -52,13 +52,13 @@
|
||||
<dependency>
|
||||
<groupId>ch.qos.logback</groupId>
|
||||
<artifactId>logback-classic</artifactId>
|
||||
<version>1.5.8</version>
|
||||
<version>1.5.15</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents.client5</groupId>
|
||||
<artifactId>httpclient5</artifactId>
|
||||
<version>5.4</version>
|
||||
<version>5.4.1</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
||||
+2
-2
@@ -53,7 +53,7 @@ public class VersionUploader{
|
||||
|
||||
if(args.length == 0){
|
||||
LOGGER.warn("MISSING ARGUMENT!");
|
||||
LOGGER.warn("COMMAND USAGE: java -jar VersionUploader.jar [--dryrun] --all | --modrinth | --hangar");
|
||||
LOGGER.warn("COMMAND USAGE: java -jar VersionUploader.jar --all | --modrinth | --hangar [--dryrun]");
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public class VersionUploader{
|
||||
}
|
||||
default -> {
|
||||
LOGGER.warn("Unknown argument '{}' provided.", args[0]);
|
||||
LOGGER.warn("COMMAND USAGE: java -jar VersionUploader.jar [--dryrun] --all | --modrinth | --hangar");
|
||||
LOGGER.warn("COMMAND USAGE: java -jar VersionUploader.jar --all | --modrinth | --hangar [--dryrun]");
|
||||
System.exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
+3
-3
@@ -50,9 +50,9 @@ public class CodebergReleaseFetcher{
|
||||
|
||||
public static CodebergRelease fetch(){
|
||||
String tag = System.getenv("CI_COMMIT_TAG");
|
||||
String codbergToken = System.getenv("CODEBERG_API_TOKEN");
|
||||
String codebergToken = System.getenv("CODEBERG_API_TOKEN");
|
||||
|
||||
if(tag == null || codbergToken == null || tag.isEmpty() || codbergToken.isEmpty()){
|
||||
if(tag == null || codebergToken == null || tag.isEmpty() || codebergToken.isEmpty()){
|
||||
LOGGER.warn("Cannot fetch release data. Either Tag or Codeberg token was null/empty.");
|
||||
return null;
|
||||
}
|
||||
@@ -64,7 +64,7 @@ public class CodebergReleaseFetcher{
|
||||
.url(url)
|
||||
.header("User-Agent", "VersionUploader-CodebergReleaseFetcher/v1.0.0")
|
||||
.header("Accept", "application/json")
|
||||
.header("Authorization", "token " + codbergToken)
|
||||
.header("Authorization", "token " + codebergToken)
|
||||
.build();
|
||||
|
||||
try(Response response = CLIENT.newCall(request).execute()){
|
||||
|
||||
+1
-1
@@ -130,7 +130,7 @@ public class HangarVersionUploader{
|
||||
Platform.VELOCITY, velocityDependencies
|
||||
),
|
||||
Map.of(
|
||||
Platform.PAPER, List.of("1.20.x", "1.21"),
|
||||
Platform.PAPER, List.of("1.20.x", "1.21.x"),
|
||||
Platform.WATERFALL, List.of("1.19.x", "1.20.x", "1.21"),
|
||||
Platform.VELOCITY, Collections.singletonList("3.2")
|
||||
),
|
||||
|
||||
+5
-3
@@ -25,8 +25,8 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.versionuploader.modrinth;
|
||||
|
||||
import ch.andre601.advancedserverlist.versionuploader.ReleaseHolder;
|
||||
import ch.andre601.advancedserverlist.versionuploader.PlatformInfo;
|
||||
import ch.andre601.advancedserverlist.versionuploader.ReleaseHolder;
|
||||
import ch.andre601.advancedserverlist.versionuploader.VersionUploader;
|
||||
import ch.andre601.advancedserverlist.versionuploader.data.CodebergRelease;
|
||||
import com.google.gson.Gson;
|
||||
@@ -55,7 +55,8 @@ public class ModrinthVersionUploader{
|
||||
PlatformInfo.VELOCITY
|
||||
);
|
||||
private final List<String> versions = List.of(
|
||||
"1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4", "1.20.5", "1.20.6", "1.21"
|
||||
"1.20", "1.20.1", "1.20.2", "1.20.3", "1.20.4", "1.20.5", "1.20.6",
|
||||
"1.21", "1.21.1", "1.21.2", "1.21.3", "1.21.4"
|
||||
);
|
||||
|
||||
private final ModrinthAPI api;
|
||||
@@ -143,7 +144,8 @@ public class ModrinthVersionUploader{
|
||||
String url = versionUrl + projectVersion.getId();
|
||||
|
||||
logger.info("Created new release!");
|
||||
logger.info("Link: {}", url);
|
||||
logger.info("Link: {}", url);
|
||||
logger.info("Platform: {}", platforms.get(index).getPlatform());
|
||||
|
||||
releaseHolder.addRelease(
|
||||
"modrinth",
|
||||
|
||||
Reference in new issue
Block a user