mirror of
https://codeberg.org/Andre601/AdvancedServerList.git
synced 2026-11-05 17:02:34 -05:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b43428e5d | ||
|
|
d34d926f9a | ||
|
|
844279b32d | ||
|
|
5916e9b495 | ||
|
|
72384488d8 | ||
|
|
11a8b07f32 | ||
|
|
cd7dfc9c15 | ||
|
|
c715ed6163 | ||
|
|
5a35ebbef4 | ||
|
|
830eee5da3 | ||
|
|
09b845e86e | ||
|
|
a2bdd5c4e5 | ||
|
|
a72c0d326a | ||
|
|
40ef2e35d4 | ||
|
|
8422d6d2de | ||
|
|
4683dab513 | ||
|
|
d5947b20e5 | ||
|
|
147f01dd1b | ||
|
|
a6eddb3828 | ||
|
|
41e11f79cc | ||
|
|
66597ce7fa | ||
|
|
77f17b202c | ||
|
|
d3673a79af | ||
|
|
29c6930ce1 | ||
|
|
125e9c0918 | ||
|
|
2ac6931f26 | ||
|
|
e301ef38f0 | ||
|
|
3f6ada4599 | ||
|
|
45d3f17faa | ||
|
|
d8fca2ca03 | ||
|
|
730b2e3aa8 | ||
|
|
e4e3543b9b | ||
|
|
a955109db5 | ||
|
|
d399c7df63 | ||
|
|
973620925d | ||
|
|
697e9e265d | ||
|
|
cabed6aa65 | ||
|
|
b408658026 | ||
|
|
15f611445c | ||
|
|
3859f2970f | ||
|
|
71079bf9d8 | ||
|
|
4fa7e92264 | ||
|
|
828d907371 | ||
|
|
986c36a334 | ||
|
|
8f9ae4a835 | ||
|
|
0dccdaf7e4 | ||
|
|
ec0dec8e7d | ||
|
|
f399ed6886 | ||
|
|
f2737f2b19 | ||
|
|
504e669ce7 | ||
|
|
0cae58c9b6 | ||
|
|
a8d6fc48bf | ||
|
|
91dcb49e81 | ||
|
|
c8a1224f53 | ||
|
|
5722700d20 | ||
|
|
1effc2574a | ||
|
|
eb7a7fa6c7 | ||
|
|
c964c942dc | ||
|
|
27c591d92c | ||
|
|
de2d43f01c | ||
|
|
3fde989eb5 | ||
|
|
c1fa8d0df1 | ||
|
|
f0446fe8f4 | ||
|
|
5509fb4380 | ||
|
|
d0f7bf9897 |
No files matched your search
@@ -0,0 +1,41 @@
|
||||
name: API support
|
||||
description: Ask for help with the API.
|
||||
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |-
|
||||
## Before opening
|
||||
Please make sure you've checked the following things first:
|
||||
|
||||
- You're using the latest release of AdvancedServerList [[Download from Modrinth](https://modrinth.com/plugin/advancedserverlist)] and the right API version.
|
||||
- You're using a supported Proxy/Server version. As of right now is only 1.19.x supported.
|
||||
- The Feature you suggest hasn't been suggested before.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Platforms
|
||||
description: On what platform(s) are you using the API?
|
||||
multiple: true
|
||||
options:
|
||||
- Proxy (BungeeCord, Waterfall, ...)
|
||||
- Proxy (Velocity)
|
||||
- Server (Spigot, Paper, ...)
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: |-
|
||||
Give a detailed description of what exactly you try to do, what steps you did and what you need help with.
|
||||
placeholder: I tried to...
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Code
|
||||
description: |-
|
||||
Provide code-snippets to help us better understand what you tried.
|
||||
The code is automatically parsed as Java Code.
|
||||
render: java
|
||||
validations:
|
||||
required: true
|
||||
@@ -76,14 +76,10 @@ You can disable this in the global bStats config file located in `/plugins/bstat
|
||||
</a>
|
||||
|
||||
<!-- Links -->
|
||||
[profiles]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles
|
||||
[conditions]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#conditions
|
||||
[placeholders]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#placeholders
|
||||
[minimessage]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#minimessage
|
||||
|
||||
[placeholderapi]: https://www.spigotmc.org/resources/6245/
|
||||
|
||||
[modrinth]: https://modrinth.com/plugin/advancedserverlist
|
||||
[profiles]: https://andre601.ch/AdvancedServerList/profiles
|
||||
[conditions]: https://andre601.ch/AdvancedServerList/profiles/#conditions
|
||||
[placeholders]: https://andre601.ch/AdvancedServerList/profiles/placeholders
|
||||
[minimessage]: https://andre601.ch/AdvancedServerList/profiles/formatting
|
||||
|
||||
[protocollib]: https://www.spigotmc.org/resources/1997/
|
||||
[placeholderapi]: https://www.spigotmc.org/resources/6245/
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
name: Deploy Site
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- 'docs/**'
|
||||
- 'mkdocs.yml'
|
||||
branches:
|
||||
- master
|
||||
tags-ignore:
|
||||
- '**'
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.7
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: 3.7
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip setuptools
|
||||
python -m pip install -r requirements.txt
|
||||
- name: Deploy Files
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "actions@github.com"
|
||||
mkdocs gh-deploy --force
|
||||
@@ -1,106 +0,0 @@
|
||||
#
|
||||
# Big thank you to @Kir-Antipov for providing this workflow file.
|
||||
# Check out his mc-publish action here: https://github.com/Kir-Antipov/mc-publish
|
||||
#
|
||||
|
||||
name: Publish Assets
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
- prereleased
|
||||
|
||||
jobs:
|
||||
buildJars:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up JDK 1.16
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '16'
|
||||
cache: 'maven'
|
||||
- name: Build Jar files
|
||||
run: mvn clean install
|
||||
- name: Save BungeeCord Jar file
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: asl-bungeecord
|
||||
path: bungeecord/target/AdvancedServerList-*.jar
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
- name: Save Paper Jar file
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: asl-paper
|
||||
path: paper/target/AdvancedServerList-*.jar
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
- name: Save Spigot Jar file
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: asl-spigot
|
||||
path: spigot/target/AdvancedServerList-*.jar
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
- name: Save Velocity Jar file
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: asl-velocity
|
||||
path: velocity/target/AdvancedServerList-*.jar
|
||||
if-no-files-found: error
|
||||
retention-days: 1
|
||||
publish:
|
||||
needs: [buildJars]
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- platforms: BungeeCord, Waterfall
|
||||
directory: bungeecord
|
||||
loaders: |
|
||||
bungeecord
|
||||
waterfall
|
||||
- platforms: Paper
|
||||
directory: paper
|
||||
loaders: paper
|
||||
- platforms: Spigot
|
||||
directory: spigot
|
||||
loaders: spigot
|
||||
- platforms: Velocity
|
||||
directory: velocity
|
||||
loaders: velocity
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Get Jar files
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: asl-${{ matrix.directory }}
|
||||
path: ${{ matrix.directory }}/target
|
||||
- name: Get Version
|
||||
id: github-release
|
||||
run: |
|
||||
version=$(echo ${{ github.event.release.tag_name }} | cut -d'v' -f2)
|
||||
echo "PLUGIN_RELEASE=$version" >> $GITHUB_OUTPUT
|
||||
- name: Upload AdvancedServerList (${{ matrix.loaders }}) to GitHub and Modrinth
|
||||
uses: Kir-Antipov/mc-publish@v3.2
|
||||
with:
|
||||
name: ${{ github.event.release.tag_name }} (${{ matrix.platforms }}) BETA
|
||||
version: ${{ steps.github-release.outputs.PLUGIN_RELEASE }}
|
||||
version-type: beta
|
||||
files: ${{ matrix.directory}}/target/AdvancedServerList-*.jar
|
||||
files-secondary: ""
|
||||
loaders: ${{ matrix.loaders }}
|
||||
version-resolver: releases
|
||||
game-versions: |
|
||||
1.19
|
||||
1.19.1
|
||||
1.19.2
|
||||
1.19.3
|
||||
java: 16
|
||||
modrinth-id: xss83sOY
|
||||
modrinth-featured: false
|
||||
modrinth-token: ${{ secrets.MODRINTH_TOKEN }}
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -9,7 +9,6 @@ on:
|
||||
release:
|
||||
types:
|
||||
- published
|
||||
- released
|
||||
|
||||
jobs:
|
||||
buildJars:
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2022 Andre_601
|
||||
Copyright (c) 2022-2023 Andre_601
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -42,6 +42,8 @@ The format is `${<target> <identifier>}` which was adopted from BungeeTabListPlu
|
||||
|
||||
When using the SpigotMC/PaperMC version can you also use placeholders from [PlaceholderAPI][placeholderapi] using its `%<identifier>_<values>%` placeholder format. PlaceholderAPI needs to be installed for that.
|
||||
|
||||
If you're a plugin dev can you even add your own custom placeholders through AdvancedServerList's own API.
|
||||
|
||||
> [*Read More*][placeholders]
|
||||
|
||||
### Formatting
|
||||
@@ -84,12 +86,10 @@ You can disable this in the global bStats config file located in `/plugins/bstat
|
||||
</a>
|
||||
|
||||
<!-- Links -->
|
||||
[profiles]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles
|
||||
[conditions]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#conditions
|
||||
[placeholders]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#placeholders
|
||||
[minimessage]: https://github.com/Andre601/AdvancedServerList/wiki/Profiles#minimessage
|
||||
|
||||
[placeholderapi]: https://www.spigotmc.org/resources/6245/
|
||||
[profiles]: https://www.andre601.ch/AdvancedServerList/profiles/
|
||||
[conditions]: https://www.andre601.ch/AdvancedServerList/profiles/#conditions
|
||||
[placeholders]: https://www.andre601.ch/AdvancedServerList/profiles/placeholders/
|
||||
[minimessage]: https://www.andre601.ch/AdvancedServerList/profiles/formatting/
|
||||
|
||||
[modrinth]: https://modrinth.com/plugin/advancedserverlist
|
||||
|
||||
|
||||
+7
-1
@@ -2,7 +2,7 @@
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022 Andre_601
|
||||
~ Copyright (c) 2022-2023 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -58,6 +58,12 @@
|
||||
<version>${plugin.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-bungeecord</artifactId>
|
||||
<version>${api.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.md-5</groupId>
|
||||
<artifactId>bungeecord-api</artifactId>
|
||||
|
||||
+5
-26
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -29,24 +29,19 @@ import ch.andre601.advancedserverlist.bungeecord.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.bungeecord.events.JoinEvent;
|
||||
import ch.andre601.advancedserverlist.bungeecord.events.PingEvent;
|
||||
import ch.andre601.advancedserverlist.bungeecord.logging.BungeeLogger;
|
||||
import ch.andre601.advancedserverlist.bungeecord.objects.BungeePlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.ProxyCore;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import net.md_5.bungee.api.Favicon;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.plugin.Plugin;
|
||||
import org.bstats.bungeecord.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeCordCore extends Plugin implements ProxyCore<Favicon, ServerPing.PlayerInfo>{
|
||||
public class BungeeCordCore extends Plugin implements PluginCore<Favicon>{
|
||||
|
||||
private AdvancedServerList core;
|
||||
private FaviconHandler<Favicon> faviconHandler = null;
|
||||
@@ -54,7 +49,7 @@ public class BungeeCordCore extends Plugin implements ProxyCore<Favicon, ServerP
|
||||
|
||||
@Override
|
||||
public void onEnable(){
|
||||
this.core = new AdvancedServerList(this);
|
||||
this.core = new AdvancedServerList(this, new BungeePlayerPlaceholders());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,20 +121,4 @@ public class BungeeCordCore extends Plugin implements ProxyCore<Favicon, ServerP
|
||||
public String getLoader(){
|
||||
return "bungeecord";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServerPing.PlayerInfo> createPlayers(List<String> lines, Placeholders... placeholders){
|
||||
List<ServerPing.PlayerInfo> players = new ArrayList<>(lines.size());
|
||||
|
||||
for(String line : lines){
|
||||
String parsed = ComponentParser.text(line)
|
||||
.replacements(placeholders[0])
|
||||
.replacements(placeholders[1])
|
||||
.toString();
|
||||
|
||||
players.add(new ServerPing.PlayerInfo(parsed, UUID.randomUUID()));
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+35
-16
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,26 +25,29 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
|
||||
import ch.andre601.advancedserverlist.bungeecord.BungeePlayer;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.bungeecord.objects.BungeePlayerImpl;
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.serializer.bungeecord.BungeeComponentSerializer;
|
||||
import net.md_5.bungee.api.Favicon;
|
||||
import net.md_5.bungee.api.ServerPing;
|
||||
import net.md_5.bungee.api.chat.TextComponent;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.ProxyPingEvent;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class BungeeEventWrapper implements GenericEventWrapper<ProxiedPlayer, Favicon>{
|
||||
public class BungeeEventWrapper implements GenericEventWrapper<Favicon, BungeePlayerImpl>{
|
||||
|
||||
private final BungeeCordCore plugin;
|
||||
private final ProxyPingEvent event;
|
||||
@@ -58,6 +61,14 @@ public class BungeeEventWrapper implements GenericEventWrapper<ProxiedPlayer, Fa
|
||||
this.ping = event.getResponse();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericServerListEvent callEvent(ProfileEntry entry){
|
||||
PreServerListSetEventImpl event = new PreServerListSetEventImpl(entry);
|
||||
plugin.getProxy().getPluginManager().callEvent(event);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxPlayers(int maxPlayers){
|
||||
ping.getPlayers().setMax(maxPlayers);
|
||||
@@ -80,12 +91,20 @@ public class BungeeEventWrapper implements GenericEventWrapper<ProxiedPlayer, Fa
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayers(List<String> players, GenericPlayer<ProxiedPlayer> player, PlayerPlaceholders playerPlaceholders, ServerPlaceholders serverPlaceholders){
|
||||
ServerPing.PlayerInfo[] playerInfos = plugin.createPlayers(players, playerPlaceholders, serverPlaceholders)
|
||||
.toArray(new ServerPing.PlayerInfo[0]);
|
||||
public void setPlayers(List<String> lines, BungeePlayerImpl player, GenericServer server){
|
||||
ServerPing.PlayerInfo[] players = new ServerPing.PlayerInfo[lines.size()];
|
||||
|
||||
if(playerInfos.length > 0)
|
||||
ping.getPlayers().setSample(playerInfos);
|
||||
for(int i = 0; i < players.length; i++){
|
||||
String parsed = ComponentParser.text(lines.get(i))
|
||||
.modifyText(text -> StringReplacer.replace(text, player, server))
|
||||
.toString();
|
||||
|
||||
ServerPing.PlayerInfo pi = new ServerPing.PlayerInfo(parsed, UUID.randomUUID());
|
||||
players[i] = pi;
|
||||
}
|
||||
|
||||
if(players.length > 0)
|
||||
ping.getPlayers().setSample(players);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -130,7 +149,7 @@ public class BungeeEventWrapper implements GenericEventWrapper<ProxiedPlayer, Fa
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePAPIPlaceholders(String text, GenericPlayer<ProxiedPlayer> player){
|
||||
public String parsePAPIPlaceholders(String text, BungeePlayerImpl player){
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -145,8 +164,8 @@ public class BungeeEventWrapper implements GenericEventWrapper<ProxiedPlayer, Fa
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericPlayer<ProxiedPlayer> createPlayer(String name, int protocol){
|
||||
return new BungeePlayer(name, protocol);
|
||||
public BungeePlayerImpl createPlayer(CachedPlayer player, int protocol){
|
||||
return new BungeePlayerImpl(player, protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+5
-2
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -26,6 +26,7 @@
|
||||
package ch.andre601.advancedserverlist.bungeecord.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import net.md_5.bungee.api.event.PostLoginEvent;
|
||||
import net.md_5.bungee.api.plugin.Listener;
|
||||
import net.md_5.bungee.event.EventHandler;
|
||||
@@ -44,6 +45,8 @@ public class JoinEvent implements Listener{
|
||||
@EventHandler
|
||||
public void onJoin(PostLoginEvent event){
|
||||
InetSocketAddress address = (InetSocketAddress)event.getPlayer().getPendingConnection().getSocketAddress();
|
||||
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getName(), address.getHostString());
|
||||
ProxiedPlayer player = event.getPlayer();
|
||||
|
||||
plugin.getCore().getPlayerHandler().addPlayer(address.getHostString(), player.getName(), player.getUniqueId());
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+8
-7
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,12 +23,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.interfaces.core;
|
||||
package ch.andre601.advancedserverlist.bungeecord.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ProxyCore<F, P> extends PluginCore<F>{
|
||||
List<P> createPlayers(List<String> lines, Placeholders... placeholders);
|
||||
public class PreServerListSetEventImpl extends PreServerListSetEvent{
|
||||
|
||||
public PreServerListSetEventImpl(ProfileEntry entry){
|
||||
super(entry);
|
||||
}
|
||||
}
|
||||
+6
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -52,4 +52,9 @@ public class BungeeLogger implements PluginLogger{
|
||||
public void warn(String msg, Throwable throwable){
|
||||
logger.log(Level.WARNING, msg, throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable, Object... args){
|
||||
logger.log(Level.WARNING, String.format(msg, args), throwable);
|
||||
}
|
||||
}
|
||||
+8
-7
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,15 +23,16 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord;
|
||||
package ch.andre601.advancedserverlist.bungeecord.objects;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import net.md_5.bungee.api.connection.ProxiedPlayer;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
|
||||
|
||||
public class BungeePlayer extends GenericPlayer<ProxiedPlayer>{
|
||||
public class BungeePlayerImpl extends GenericPlayerImpl{
|
||||
|
||||
public BungeePlayer(String name, int protocol){
|
||||
this.name = name;
|
||||
public BungeePlayerImpl(CachedPlayer player, int protocol){
|
||||
this.name = player.getName();
|
||||
this.protocol = protocol;
|
||||
this.uuid = player.getUuid();
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.bungeecord.objects;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
|
||||
import java.util.Locale;
|
||||
|
||||
public class BungeePlayerPlaceholders extends PlaceholderProvider{
|
||||
|
||||
public BungeePlayerPlaceholders(){
|
||||
super("player");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
|
||||
return switch(placeholder.toLowerCase(Locale.ROOT)){
|
||||
case "name" -> player.getName();
|
||||
case "protocol" -> String.valueOf(player.getProtocol());
|
||||
case "uuid" -> String.valueOf(player.getUUID());
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
+9
-3
@@ -2,7 +2,7 @@
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022 Andre_601
|
||||
~ Copyright (c) 2022-2023 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -51,6 +51,12 @@
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>${api.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spongepowered</groupId>
|
||||
<artifactId>configurate-yaml</artifactId>
|
||||
@@ -80,7 +86,7 @@
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.10</version>
|
||||
<version>2.10.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
@@ -90,7 +96,7 @@
|
||||
<dependency>
|
||||
<groupId>com.unascribed</groupId>
|
||||
<artifactId>flexver-java</artifactId>
|
||||
<version>1.0.2</version>
|
||||
<version>1.1.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Test dependencies -->
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,10 +25,13 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.core.check.UpdateChecker;
|
||||
import ch.andre601.advancedserverlist.core.commands.CommandHandler;
|
||||
import ch.andre601.advancedserverlist.core.file.FileHandler;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.objects.ServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.PlayerHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
@@ -42,17 +45,21 @@ public class AdvancedServerList{
|
||||
private final FileHandler fileHandler;
|
||||
private final CommandHandler commandHandler;
|
||||
private final PlayerHandler playerHandler;
|
||||
private final AdvancedServerListAPI api = AdvancedServerListAPI.get();
|
||||
|
||||
private UpdateChecker updateChecker;
|
||||
|
||||
private String version;
|
||||
|
||||
public AdvancedServerList(PluginCore<?> plugin){
|
||||
public AdvancedServerList(PluginCore<?> plugin, PlaceholderProvider player){
|
||||
this.plugin = plugin;
|
||||
this.fileHandler = new FileHandler(this);
|
||||
this.commandHandler = new CommandHandler(this);
|
||||
this.playerHandler = new PlayerHandler(this);
|
||||
|
||||
this.api.addPlaceholderProvider(player);
|
||||
this.api.addPlaceholderProvider(new ServerPlaceholders());
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
@@ -76,8 +83,12 @@ public class AdvancedServerList{
|
||||
return version;
|
||||
}
|
||||
|
||||
public AdvancedServerListAPI getApi(){
|
||||
return api;
|
||||
}
|
||||
|
||||
public void disable(){
|
||||
getPlugin().getPluginLogger().info("Saving cache.data file...");
|
||||
getPlugin().getPluginLogger().info("Saving playercache.json file...");
|
||||
getPlayerHandler().save();
|
||||
|
||||
if(updateChecker != null){
|
||||
@@ -125,7 +136,7 @@ public class AdvancedServerList{
|
||||
plugin.loadEvents();
|
||||
getPlugin().getPluginLogger().info("Events loaded!");
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading cache.data...");
|
||||
getPlugin().getPluginLogger().info("Loading playercache.json...");
|
||||
getPlayerHandler().load();
|
||||
|
||||
getPlugin().getPluginLogger().info("Loading bStats metrics. Disable it in the global config under /plugins/bstats/");
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -97,12 +97,19 @@ public class UpdateChecker{
|
||||
|
||||
public void disable(){
|
||||
executor.shutdown();
|
||||
client.dispatcher().executorService().shutdown();
|
||||
try{
|
||||
if(!executor.awaitTermination(1, TimeUnit.SECONDS)){
|
||||
executor.shutdownNow();
|
||||
if(!executor.awaitTermination(1, TimeUnit.SECONDS))
|
||||
logger.warn("Scheduler didn't terminate in time!");
|
||||
}
|
||||
|
||||
if(!client.dispatcher().executorService().awaitTermination(1, TimeUnit.SECONDS)){
|
||||
client.dispatcher().executorService().shutdownNow();
|
||||
if(!client.dispatcher().executorService().awaitTermination(1, TimeUnit.SECONDS))
|
||||
logger.warn("OkHttp's Scheduler didn't terminate in time!");
|
||||
}
|
||||
}catch(InterruptedException ex){
|
||||
executor.shutdownNow();
|
||||
Thread.currentThread().interrupt();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+36
-36
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,86 +25,86 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.core.objects.GenericServerImpl;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileManager;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileManager;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
|
||||
|
||||
public class PingEventHandler{
|
||||
|
||||
public static <P, F> void handleEvent(GenericEventWrapper<P, F> event){
|
||||
public static <F, P extends GenericPlayer> void handleEvent(GenericEventWrapper<F, P> event){
|
||||
if(event.isInvalidProtocol())
|
||||
return;
|
||||
|
||||
PluginCore<F> plugin = event.getPlugin();
|
||||
|
||||
GenericPlayer<P> player = event.createPlayer(
|
||||
plugin.getCore().getPlayerHandler().getPlayerByIp(event.getPlayerIP()),
|
||||
event.getProtocolVersion()
|
||||
);
|
||||
String host = event.getVirtualHost();
|
||||
|
||||
int online = event.getOnlinePlayers();
|
||||
int max = event.getMaxPlayers();
|
||||
|
||||
PlayerPlaceholders playerPlaceholders = new PlayerPlaceholders(player);
|
||||
ServerPlaceholders serverPlaceholders = new ServerPlaceholders(online, max, host);
|
||||
|
||||
ServerListProfile profile = ProfileManager.get(plugin.getCore())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.getProfile();
|
||||
|
||||
P player = event.createPlayer(
|
||||
plugin.getCore().getPlayerHandler().getCachedPlayer(event.getPlayerIP()),
|
||||
event.getProtocolVersion()
|
||||
);
|
||||
GenericServer server = new GenericServerImpl(online, max, host);
|
||||
|
||||
ServerListProfile profile = ProfileManager.resolveProfile(plugin.getCore(), player, server);
|
||||
|
||||
if(profile == null)
|
||||
return;
|
||||
|
||||
ProfileEntry entry = ProfileManager.merge(profile);
|
||||
|
||||
if(entry.isExtraPlayersEnabled() != null && entry.isExtraPlayersEnabled()){
|
||||
GenericServerListEvent e = event.callEvent(ProfileManager.merge(profile));
|
||||
if(e == null || e.isCancelled())
|
||||
return;
|
||||
|
||||
ProfileEntry entry = e.getEntry();
|
||||
if(entry.isInvalid())
|
||||
return;
|
||||
|
||||
if(ProfileManager.checkOption(entry.isExtraPlayersEnabled())){
|
||||
max = online + (entry.getExtraPlayersCount() == null ? 0 : entry.getExtraPlayersCount());
|
||||
event.setMaxPlayers(max);
|
||||
}
|
||||
|
||||
serverPlaceholders = new ServerPlaceholders(online, max, host);
|
||||
GenericServer finalServer = new GenericServerImpl(online, max, host);
|
||||
|
||||
if(!entry.getMOTD().isEmpty()){
|
||||
if(ProfileManager.checkOption(entry.getMotd())){
|
||||
event.setMotd(
|
||||
ComponentParser.list(entry.getMOTD())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
ComponentParser.list(entry.getMotd())
|
||||
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
|
||||
.modifyText(text -> event.parsePAPIPlaceholders(text, player))
|
||||
.toComponent()
|
||||
);
|
||||
}
|
||||
|
||||
boolean hidePlayers = entry.isHidePlayersEnabled() != null && entry.isHidePlayersEnabled();
|
||||
boolean hidePlayers = ProfileManager.checkOption(entry.isHidePlayersEnabled());
|
||||
|
||||
if(hidePlayers){
|
||||
event.hidePlayers();
|
||||
}
|
||||
|
||||
if(!entry.getPlayerCountText().isEmpty() && !hidePlayers){
|
||||
if(ProfileManager.checkOption(entry.getPlayerCountText()) && !hidePlayers){
|
||||
event.setPlayerCount(
|
||||
ComponentParser.text(entry.getPlayerCountText())
|
||||
.replacements(playerPlaceholders)
|
||||
.replacements(serverPlaceholders)
|
||||
.modifyText(text -> StringReplacer.replace(text, player, finalServer))
|
||||
.modifyText(text -> event.parsePAPIPlaceholders(text, player))
|
||||
.toString()
|
||||
);
|
||||
}
|
||||
|
||||
if(!entry.getPlayers().isEmpty() && !hidePlayers){
|
||||
event.setPlayers(entry.getPlayers(), player, playerPlaceholders, serverPlaceholders);
|
||||
if(ProfileManager.checkOption(entry.getPlayers()) && !hidePlayers){
|
||||
event.setPlayers(entry.getPlayers(), player, server);
|
||||
}
|
||||
|
||||
if(!entry.getFavicon().isEmpty()){
|
||||
String favicon = StringReplacer.replace(entry.getFavicon(), playerPlaceholders.getReplacements());
|
||||
if(ProfileManager.checkOption(entry.getFavicon())){
|
||||
String favicon = StringReplacer.replace(entry.getFavicon(), player, server);
|
||||
|
||||
F fav = plugin.getFaviconHandler().getFavicon(favicon, image -> {
|
||||
try{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -27,8 +27,8 @@ package ch.andre601.advancedserverlist.core.file;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileSerializer;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.yaml.YamlConfigurationLoader;
|
||||
@@ -130,7 +130,7 @@ public class FileHandler{
|
||||
if(tmp == null)
|
||||
continue;
|
||||
|
||||
profiles.add(ServerListProfile.Builder.resolve(tmp, logger).build());
|
||||
profiles.add(ServerListProfile.Builder.resolve(file.getName(), tmp, logger).build());
|
||||
logger.info("Loaded " + file.getName());
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -32,4 +32,6 @@ public interface PluginLogger{
|
||||
void warn(String msg, Object... args);
|
||||
|
||||
void warn(String msg, Throwable throwable);
|
||||
|
||||
void warn(String msg, Throwable throwable, Object... args);
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+12
-8
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,17 +25,21 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.interfaces.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
public interface GenericEventWrapper<P, F>{
|
||||
public interface GenericEventWrapper<F, P extends GenericPlayer>{
|
||||
|
||||
GenericServerListEvent callEvent(ProfileEntry entry);
|
||||
|
||||
void setMaxPlayers(int maxPlayers);
|
||||
|
||||
@@ -45,7 +49,7 @@ public interface GenericEventWrapper<P, F>{
|
||||
|
||||
void setPlayerCount(String name);
|
||||
|
||||
void setPlayers(List<String> players, GenericPlayer<P> player, PlayerPlaceholders playerPlaceholders, ServerPlaceholders serverPlaceholders);
|
||||
void setPlayers(List<String> players, P player, GenericServer server);
|
||||
|
||||
void setFavicon(F favicon);
|
||||
|
||||
@@ -63,13 +67,13 @@ public interface GenericEventWrapper<P, F>{
|
||||
|
||||
String getPlayerIP();
|
||||
|
||||
String parsePAPIPlaceholders(String text, GenericPlayer<P> player);
|
||||
String parsePAPIPlaceholders(String text, P player);
|
||||
|
||||
String getVirtualHost();
|
||||
|
||||
PluginCore<F> getPlugin();
|
||||
|
||||
GenericPlayer<P> createPlayer(String name, int protocol);
|
||||
P createPlayer(CachedPlayer player, int protocol);
|
||||
|
||||
F createFavicon(BufferedImage image) throws Exception;
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.objects;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
@SuppressWarnings("FieldMayBeFinal")
|
||||
public class CachedPlayer{
|
||||
|
||||
private String ip;
|
||||
private String name;
|
||||
private UUID uuid;
|
||||
|
||||
public CachedPlayer(String ip, String name, UUID uuid){
|
||||
this.ip = ip;
|
||||
this.name = name;
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
||||
public String getIp(){
|
||||
return ip;
|
||||
}
|
||||
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
|
||||
public UUID getUuid(){
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
+23
-14
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,25 +23,34 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.replacer.placeholders;
|
||||
package ch.andre601.advancedserverlist.core.objects;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
|
||||
public class ServerPlaceholders implements Placeholders{
|
||||
public class GenericServerImpl implements GenericServer{
|
||||
|
||||
private final Map<String, Object> replacements = new HashMap<>();
|
||||
private final int online;
|
||||
private final int max;
|
||||
private final String host;
|
||||
|
||||
public ServerPlaceholders(int online, int max, String host){
|
||||
this.replacements.put("${server playersOnline}", online);
|
||||
this.replacements.put("${server playersMax}", max);
|
||||
|
||||
if(host != null)
|
||||
this.replacements.put("${server host}", host);
|
||||
public GenericServerImpl(int online, int max, String host){
|
||||
this.online = online;
|
||||
this.max = max;
|
||||
this.host = host;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getReplacements(){
|
||||
return this.replacements;
|
||||
public int getPlayersOnline(){
|
||||
return online;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPlayersMax(){
|
||||
return max;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost(){
|
||||
return host;
|
||||
}
|
||||
}
|
||||
+17
-19
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,27 +23,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.replacer;
|
||||
package ch.andre601.advancedserverlist.core.objects;
|
||||
|
||||
import java.util.AbstractMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
|
||||
/*
|
||||
* Original by Imo van den Berge (aka Bergerkiller: https://github.com/Bergerkiller)
|
||||
*
|
||||
* Original Source: https://github.com/bergerhealer/BKCommonLib/blob/master/src/main/java/com/bergerkiller/bukkit/common/collections/EntryList.java
|
||||
*/
|
||||
public class EntryList<K, V> extends ArrayList<Map.Entry<K, V>>{
|
||||
public void add(K key, V value){
|
||||
add(new AbstractMap.SimpleEntry<>(key, value));
|
||||
public class ServerPlaceholders extends PlaceholderProvider{
|
||||
|
||||
public ServerPlaceholders(){
|
||||
super("server");
|
||||
}
|
||||
|
||||
public boolean containsKey(K key){
|
||||
for(Map.Entry<K, V> entry : this){
|
||||
if(entry.getKey().equals(key))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@Override
|
||||
public String parsePlaceholder(String placeholder, GenericPlayer genericPlayer, GenericServer genericServer){
|
||||
return switch(placeholder){
|
||||
case "playersOnline" -> String.valueOf(genericServer.getPlayersOnline());
|
||||
case "playersMax" -> String.valueOf(genericServer.getPlayersMax());
|
||||
case "host" -> genericServer.getHost();
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,8 +25,6 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.parsing;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import net.kyori.adventure.text.minimessage.MiniMessage;
|
||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
|
||||
@@ -58,11 +56,6 @@ public class ComponentParser{
|
||||
return new ComponentParser(String.join("\n", lines));
|
||||
}
|
||||
|
||||
public ComponentParser replacements(Placeholders placeholders){
|
||||
text = StringReplacer.replace(text, placeholders.getReplacements());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ComponentParser modifyText(Function<String, String> function){
|
||||
this.text = function.apply(text);
|
||||
return this;
|
||||
|
||||
+24
-13
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,15 +25,16 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.profiles.conditions.Expression;
|
||||
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileEntry;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
|
||||
public class ServerListProfile{
|
||||
@@ -57,12 +58,12 @@ public class ServerListProfile{
|
||||
return priority;
|
||||
}
|
||||
|
||||
public boolean evaluateConditions(Map<String, Object> replacements){
|
||||
public boolean evalConditions(GenericPlayer player, GenericServer server){
|
||||
if(expressions.isEmpty())
|
||||
return true;
|
||||
|
||||
for(Expression expression : expressions){
|
||||
if(!expression.evaluate(replacements))
|
||||
if(!expression.evaluate(player, server))
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -94,21 +95,25 @@ public class ServerListProfile{
|
||||
* ...doesn't have a favicon set.
|
||||
*/
|
||||
public boolean isInvalidProfile(){
|
||||
if(profiles.isEmpty())
|
||||
return defaultProfile.isInvalid();
|
||||
|
||||
boolean profilesValid = false;
|
||||
|
||||
for(ProfileEntry profile : profiles){
|
||||
if(profile.isInvalidProfile())
|
||||
if(profile.isInvalid())
|
||||
continue;
|
||||
|
||||
profilesValid = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return !profilesValid && defaultProfile.isInvalidProfile();
|
||||
return !profilesValid && defaultProfile.isInvalid();
|
||||
}
|
||||
|
||||
public static class Builder{
|
||||
|
||||
private final String fileName;
|
||||
private final ConfigurationNode node;
|
||||
private final int priority;
|
||||
private final List<Expression> expressions = new ArrayList<>();
|
||||
@@ -118,14 +123,15 @@ public class ServerListProfile{
|
||||
private List<ProfileEntry> profiles = new ArrayList<>();
|
||||
private ProfileEntry defaultProfile = ProfileEntry.empty();
|
||||
|
||||
private Builder(ConfigurationNode node, PluginLogger logger){
|
||||
private Builder(String fileName, ConfigurationNode node, PluginLogger logger){
|
||||
this.fileName = fileName;
|
||||
this.node = node;
|
||||
this.priority = node.node("priority").getInt();
|
||||
this.logger = logger;
|
||||
}
|
||||
|
||||
public static Builder resolve(ConfigurationNode node, PluginLogger logger){
|
||||
return new Builder(node, logger)
|
||||
public static Builder resolve(String fileName, ConfigurationNode node, PluginLogger logger){
|
||||
return new Builder(fileName, node, logger)
|
||||
.resolveExpressions()
|
||||
.resolveProfiles()
|
||||
.resolveDefaultProfile();
|
||||
@@ -136,6 +142,7 @@ public class ServerListProfile{
|
||||
try{
|
||||
temp = node.node("conditions").getList(String.class);
|
||||
}catch(SerializationException ex){
|
||||
logger.warn("Encountered a SerializationException while resolving conditions for %s", ex, fileName);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -143,7 +150,7 @@ public class ServerListProfile{
|
||||
return this;
|
||||
|
||||
for(String str : temp){
|
||||
Expression expr = new Expression(str);
|
||||
Expression expr = Expression.resolve(str);
|
||||
|
||||
if(expr.getResult() != Expression.ExpressionResult.VALID){
|
||||
logger.warn("Found invalid expression in condition '%s'! Reason: %s", str, expr.getResult().getMessage());
|
||||
@@ -159,7 +166,9 @@ public class ServerListProfile{
|
||||
private Builder resolveProfiles(){
|
||||
try{
|
||||
this.profiles = node.node("profiles").getList(ProfileEntry.class);
|
||||
}catch(SerializationException ignored){}
|
||||
}catch(SerializationException ex){
|
||||
logger.warn("Encountered a SerializationException while resolving the profiles entry for %s", ex, fileName);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -167,7 +176,9 @@ public class ServerListProfile{
|
||||
private Builder resolveDefaultProfile(){
|
||||
try{
|
||||
this.defaultProfile = node.get(ProfileEntry.class);
|
||||
}catch(SerializationException ignored){}
|
||||
}catch(SerializationException ex){
|
||||
logger.warn("Encountered a SerializationException while resolving the global profile for %s", ex, fileName);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
+37
-31
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,43 +25,40 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.conditions;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class Expression{
|
||||
|
||||
private ExpressionResult result = ExpressionResult.VALID;
|
||||
private final ExpressionResult result;
|
||||
|
||||
private String left;
|
||||
private Operator operator = Operator.UNKNOWN;
|
||||
private String right;
|
||||
private final String left;
|
||||
private final Operator operator;
|
||||
private final String right;
|
||||
|
||||
public Expression(String expression){
|
||||
resolveExpression(expression);
|
||||
private Expression(ExpressionResult result, String left, Operator operator, String right){
|
||||
this.result = result;
|
||||
this.left = left;
|
||||
this.operator = operator;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public boolean evaluate(Map<String, Object> replacements){
|
||||
String newLeft = StringReplacer.replace(left, replacements).trim();
|
||||
String newRight = StringReplacer.replace(right, replacements).trim();
|
||||
public static Expression createInvalid(ExpressionResult result){
|
||||
return new Expression(result, null, Operator.UNKNOWN, null);
|
||||
}
|
||||
|
||||
public static Expression resolve(String expression){
|
||||
Operator operator = Operator.UNKNOWN;
|
||||
|
||||
return operator.evaluate(newLeft, newRight);
|
||||
}
|
||||
|
||||
public ExpressionResult getResult(){
|
||||
return result;
|
||||
}
|
||||
|
||||
private void resolveExpression(String expression){
|
||||
if(expression == null || expression.isEmpty()){
|
||||
result = ExpressionResult.INVALID_NO_EXPRESSION;
|
||||
return;
|
||||
return Expression.createInvalid(ExpressionResult.INVALID_NO_EXPRESSION);
|
||||
}
|
||||
|
||||
char[] chars = expression.toCharArray();
|
||||
|
||||
StringBuilder left = new StringBuilder();
|
||||
StringBuilder right = new StringBuilder();
|
||||
StringBuilder leftBuilder = new StringBuilder();
|
||||
StringBuilder rightBuilder = new StringBuilder();
|
||||
|
||||
boolean foundOperator = false;
|
||||
|
||||
@@ -81,19 +78,28 @@ public class Expression{
|
||||
}
|
||||
|
||||
if(foundOperator){
|
||||
right.append(c);
|
||||
rightBuilder.append(c);
|
||||
}else{
|
||||
left.append(c);
|
||||
leftBuilder.append(c);
|
||||
}
|
||||
}
|
||||
|
||||
if(left.isEmpty() || right.isEmpty()){
|
||||
result = ExpressionResult.INVALID_EMPTY_PARTS;
|
||||
return;
|
||||
if(leftBuilder.isEmpty() || rightBuilder.isEmpty()){
|
||||
return Expression.createInvalid(ExpressionResult.INVALID_EMPTY_PARTS);
|
||||
}
|
||||
|
||||
this.left = left.toString();
|
||||
this.right = right.toString();
|
||||
return new Expression(ExpressionResult.VALID, leftBuilder.toString().trim(), operator, rightBuilder.toString().trim());
|
||||
}
|
||||
|
||||
public boolean evaluate(GenericPlayer player, GenericServer server){
|
||||
String newLeft = StringReplacer.replace(left, player, server);
|
||||
String newRight = StringReplacer.replace(right, player, server);
|
||||
|
||||
return operator.evaluate(newLeft, newRight);
|
||||
}
|
||||
|
||||
public ExpressionResult getResult(){
|
||||
return result;
|
||||
}
|
||||
|
||||
public enum Operator{
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+9
-29
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,48 +25,28 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.players;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
public abstract class GenericPlayer<T>{
|
||||
public abstract class GenericPlayerImpl implements GenericPlayer{
|
||||
|
||||
protected T player = null;
|
||||
protected String name = null;
|
||||
protected String version = null;
|
||||
protected int protocol = -1;
|
||||
protected boolean playedBefore = false;
|
||||
protected boolean banned = false;
|
||||
protected boolean whitelisted = false;
|
||||
protected int protocol = 0;
|
||||
protected UUID uuid = null;
|
||||
|
||||
public T getPlayer(){
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName(){
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getProtocol(){
|
||||
return protocol;
|
||||
}
|
||||
|
||||
public String getVersion(){
|
||||
return version;
|
||||
}
|
||||
|
||||
public boolean hasPlayedBefore(){
|
||||
return playedBefore;
|
||||
}
|
||||
|
||||
public boolean isBanned(){
|
||||
return banned;
|
||||
}
|
||||
|
||||
public boolean isWhitelisted(){
|
||||
return whitelisted;
|
||||
}
|
||||
|
||||
public UUID getUniqueId(){
|
||||
@Override
|
||||
public UUID getUUID(){
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
+81
-56
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -26,110 +26,135 @@
|
||||
package ch.andre601.advancedserverlist.core.profiles.players;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.EntryList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import com.google.gson.Gson;
|
||||
import io.leangen.geantyref.TypeToken;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringJoiner;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PlayerHandler{
|
||||
|
||||
private final AdvancedServerList core;
|
||||
private final PluginLogger logger;
|
||||
private final Path cache;
|
||||
private final EntryList<String, String> players = new EntryList<>();
|
||||
private List<CachedPlayer> cachedPlayers = new ArrayList<>();
|
||||
|
||||
private final Type listType = new TypeToken<ArrayList<CachedPlayer>>(){}.getType();
|
||||
private final Gson gson = new Gson();
|
||||
|
||||
// UUID of MHF_Question
|
||||
private final String defaultUUID = "606e2ff0-ed77-4842-9d6c-e1d3321c7838";
|
||||
|
||||
private CachedPlayer defaultPlayer = null;
|
||||
|
||||
public PlayerHandler(AdvancedServerList core){
|
||||
this.core = core;
|
||||
this.cache = core.getPlugin().getFolderPath().resolve("cache.data");
|
||||
this.logger = core.getPlugin().getPluginLogger();
|
||||
this.cache = core.getPlugin().getFolderPath().resolve("playercache.json");
|
||||
}
|
||||
|
||||
public void load(){
|
||||
if(!cache.toFile().exists()){
|
||||
core.getPlugin().getPluginLogger().info("No cache.data present. Skipping...");
|
||||
logger.info("No playercache.json file present. Skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
if(core.getFileHandler().getBoolean("disable_cache")){
|
||||
core.getPlugin().getPluginLogger().info("Cache disabled. Skipping player loading...");
|
||||
logger.info("'disable_cache' is set to true. Skipping playercache.json loading...");
|
||||
return;
|
||||
}
|
||||
|
||||
List<String> lines;
|
||||
|
||||
try{
|
||||
lines = Files.readAllLines(cache);
|
||||
Reader reader = Files.newBufferedReader(cache);
|
||||
|
||||
cachedPlayers = gson.fromJson(reader, listType);
|
||||
|
||||
reader.close();
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Encountered IOException while trying to read cache.data", ex);
|
||||
logger.warn("Encountered IOException while reading the playercache.json file!", ex);
|
||||
return;
|
||||
}
|
||||
|
||||
if(lines.isEmpty()){
|
||||
core.getPlugin().getPluginLogger().info("cache.data is empty. Skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
for(String line : lines){
|
||||
String[] parts = line.split("=", 2);
|
||||
if(parts.length < 2 || parts[0].isEmpty() || parts[1].isEmpty())
|
||||
continue;
|
||||
|
||||
if(players.containsKey(parts[0]))
|
||||
continue;
|
||||
|
||||
players.add(parts[0], parts[1]);
|
||||
}
|
||||
|
||||
core.getPlugin().getPluginLogger().info("Loaded " + players.size() + " players into cache!");
|
||||
logger.info("Loaded %d players into cache!", cachedPlayers.size());
|
||||
}
|
||||
|
||||
public void save(){
|
||||
if(players.isEmpty()){
|
||||
core.getPlugin().getPluginLogger().info("No data to save. Skipping...");
|
||||
if(cachedPlayers.isEmpty()){
|
||||
logger.info("No players in cache to save. Skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if(core.getFileHandler().getBoolean("disable_cache")){
|
||||
core.getPlugin().getPluginLogger().info("Cache disabled. Skipping player saving...");
|
||||
logger.info("'disable_cache' is set to true. Skipping saving of cached players...");
|
||||
return;
|
||||
}
|
||||
|
||||
StringJoiner joiner = new StringJoiner("\n");
|
||||
for(Map.Entry<String, String> entry : players){
|
||||
joiner.add(entry.getKey() + "=" + entry.getValue());
|
||||
}
|
||||
|
||||
try{
|
||||
BufferedWriter writer = Files.newBufferedWriter(cache, StandardCharsets.UTF_8);
|
||||
|
||||
writer.write(joiner.toString());
|
||||
writer.close();
|
||||
|
||||
core.getPlugin().getPluginLogger().info("Successfully saved cache.data file.");
|
||||
try(BufferedWriter writer = Files.newBufferedWriter(cache, StandardCharsets.UTF_8)){
|
||||
gson.toJson(cachedPlayers, listType, writer);
|
||||
logger.info("Successfully saved playercache.json file.");
|
||||
}catch(IOException ex){
|
||||
core.getPlugin().getPluginLogger().warn("Cannot save player data to cache.data file!", ex);
|
||||
logger.warn("Encountered IOException while saving cached players to playercache.json!", ex);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void addPlayer(String name, String ip){
|
||||
if(players.containsKey(name) || core.getFileHandler().getBoolean("disable_cache"))
|
||||
public void addPlayer(String ip, String name, UUID uuid){
|
||||
if(contains(ip) || core.getFileHandler().getBoolean("disable_cache"))
|
||||
return;
|
||||
|
||||
players.add(name, ip);
|
||||
cachedPlayers.add(new CachedPlayer(ip, name, uuid));
|
||||
}
|
||||
|
||||
public String getPlayerByIp(String ip){
|
||||
if(core.getFileHandler().getBoolean("disable_cache"))
|
||||
core.getFileHandler().getString("Anonymous", "unknown_player");
|
||||
public CachedPlayer getCachedPlayer(String key){
|
||||
if(!contains(key) || core.getFileHandler().getBoolean("disable_cache"))
|
||||
return getDefaultPlayer();
|
||||
|
||||
for(Map.Entry<String, String> entry : players){
|
||||
if(entry.getValue().equals(ip))
|
||||
return entry.getKey();
|
||||
for(CachedPlayer player : cachedPlayers){
|
||||
if(player.getIp().equals(key))
|
||||
return player;
|
||||
}
|
||||
|
||||
return core.getFileHandler().getString("Anonymous", "unknown_player");
|
||||
return getDefaultPlayer();
|
||||
}
|
||||
|
||||
private boolean contains(String ip){
|
||||
for(CachedPlayer player : cachedPlayers){
|
||||
if(player.getIp().equals(ip))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private CachedPlayer getDefaultPlayer(){
|
||||
if(defaultPlayer != null)
|
||||
return defaultPlayer;
|
||||
|
||||
return (defaultPlayer = new CachedPlayer(
|
||||
"0.0.0.0",
|
||||
core.getFileHandler().getString("Anonymous", "unknown_player"),
|
||||
convertToUUID(core.getFileHandler().getString(defaultUUID, "unknown_player_uuid"))
|
||||
));
|
||||
}
|
||||
|
||||
private UUID convertToUUID(String uuid){
|
||||
try{
|
||||
return UUID.fromString(uuid);
|
||||
}catch(IllegalArgumentException ex){
|
||||
// This is always a valid UUID.
|
||||
return UUID.fromString(defaultUUID);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-193
@@ -1,193 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.profile;
|
||||
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ProfileEntry{
|
||||
|
||||
private final List<String> motd;
|
||||
private final List<String> players;
|
||||
private final String playerCountText;
|
||||
private final String favicon;
|
||||
private final Boolean hidePlayersEnabled;
|
||||
private final Boolean extraPlayersEnabled;
|
||||
private final Integer extraPlayersCount;
|
||||
|
||||
public ProfileEntry(List<String> motd, List<String> players,
|
||||
String playerCountText, String favicon, Boolean hidePlayersEnabled,
|
||||
Boolean extraPlayersEnabled, Integer extraPlayersCount){
|
||||
this.motd = motd;
|
||||
this.players = players;
|
||||
this.playerCountText = playerCountText;
|
||||
this.favicon = favicon;
|
||||
this.hidePlayersEnabled = hidePlayersEnabled;
|
||||
this.extraPlayersEnabled = extraPlayersEnabled;
|
||||
this.extraPlayersCount = extraPlayersCount;
|
||||
}
|
||||
|
||||
public static ProfileEntry empty(){
|
||||
return new ProfileEntry(Collections.emptyList(), Collections.emptyList(), "", "",
|
||||
false, false, 0);
|
||||
}
|
||||
|
||||
public List<String> getMOTD(){
|
||||
return motd;
|
||||
}
|
||||
|
||||
public List<String> getPlayers(){
|
||||
return players;
|
||||
}
|
||||
|
||||
public String getPlayerCountText(){
|
||||
return playerCountText;
|
||||
}
|
||||
|
||||
public String getFavicon(){
|
||||
return favicon;
|
||||
}
|
||||
|
||||
public Boolean isHidePlayersEnabled(){
|
||||
return hidePlayersEnabled;
|
||||
}
|
||||
|
||||
public Boolean isExtraPlayersEnabled(){
|
||||
return extraPlayersEnabled;
|
||||
}
|
||||
|
||||
public Integer getExtraPlayersCount(){
|
||||
return extraPlayersCount;
|
||||
}
|
||||
|
||||
public boolean isInvalidProfile(){
|
||||
return getMOTD().isEmpty() &&
|
||||
getPlayers().isEmpty() &&
|
||||
(getPlayerCountText().isEmpty() && !isHidePlayersEnabled()) &&
|
||||
getFavicon().isEmpty();
|
||||
}
|
||||
|
||||
public static class Builder{
|
||||
|
||||
private final ConfigurationNode node;
|
||||
|
||||
private List<String> motd = new ArrayList<>();
|
||||
private List<String> players = new ArrayList<>();
|
||||
private String playerCountText = null;
|
||||
private String favicon = null;
|
||||
private Boolean hidePlayersEnabled = false;
|
||||
private Boolean extraPlayersEnabled = false;
|
||||
private Integer extraPlayersCount = 0;
|
||||
|
||||
private Builder(ConfigurationNode node){
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public static Builder resolve(ConfigurationNode node){
|
||||
return new Builder(node)
|
||||
.resolveMOTD()
|
||||
.resolvePlayers()
|
||||
.resolvePlayerCountText()
|
||||
.resolveFavicon()
|
||||
.resolveHidePlayersEnabled()
|
||||
.resolveExtraPlayersEnabled()
|
||||
.resolveExtraPlayersCount();
|
||||
}
|
||||
|
||||
public Builder resolveMOTD(){
|
||||
List<String> motd = resolveList(node, "motd");
|
||||
if(motd.size() <= 2){
|
||||
this.motd = motd;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.motd = motd.subList(0, 2);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder resolvePlayers(){
|
||||
this.players = this.resolveList(node, "playerCount", "hover");
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder resolvePlayerCountText(){
|
||||
this.playerCountText = node.node("playerCount", "text").getString("");
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder resolveFavicon(){
|
||||
this.favicon = node.node("favicon").getString("");
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder resolveHidePlayersEnabled(){
|
||||
if(node.node("playerCount", "hidePlayers").virtual()){
|
||||
this.hidePlayersEnabled = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.hidePlayersEnabled = node.node("playerCount", "hidePlayers").getBoolean();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder resolveExtraPlayersEnabled(){
|
||||
if(node.node("playerCount", "extraPlayers", "enabled").virtual()){
|
||||
this.extraPlayersEnabled = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.extraPlayersEnabled = node.node("playerCount", "extraPlayers", "enabled").getBoolean();
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder resolveExtraPlayersCount(){
|
||||
if(node.node("playerCount", "extraPlayers", "amount").virtual()){
|
||||
this.extraPlayersCount = null;
|
||||
return this;
|
||||
}
|
||||
|
||||
this.extraPlayersCount = node.node("playerCount", "extraPlayers", "amount").getInt();
|
||||
return this;
|
||||
}
|
||||
|
||||
public ProfileEntry build(){
|
||||
return new ProfileEntry(this.motd, this.players, this.playerCountText,
|
||||
this.favicon, this.hidePlayersEnabled, this.extraPlayersEnabled, this.extraPlayersCount);
|
||||
}
|
||||
|
||||
private List<String> resolveList(ConfigurationNode node, Object... path){
|
||||
try{
|
||||
return node.node(path).getList(String.class);
|
||||
}catch(SerializationException ex){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+97
-52
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,45 +25,20 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.profile;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.objects.NullBool;
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ProfileManager{
|
||||
|
||||
private final AdvancedServerList core;
|
||||
|
||||
private final Map<String, Object> replacements = new HashMap<>();
|
||||
|
||||
private ProfileManager(AdvancedServerList core){
|
||||
this.core = core;
|
||||
}
|
||||
|
||||
public static ProfileManager get(AdvancedServerList core){
|
||||
return new ProfileManager(core);
|
||||
}
|
||||
|
||||
public ProfileManager replacements(Placeholders placeholders){
|
||||
this.replacements.putAll(placeholders.getReplacements());
|
||||
return this;
|
||||
}
|
||||
|
||||
public ServerListProfile getProfile(){
|
||||
for(ServerListProfile profile : core.getFileHandler().getProfiles()){
|
||||
if(profile.isInvalidProfile())
|
||||
continue;
|
||||
|
||||
if(profile.evaluateConditions(replacements))
|
||||
return profile;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convenience method to get a ProfileEntry instance with values merged.
|
||||
* If the random profile's value is not null will it be used instead of the default one.
|
||||
@@ -76,61 +51,131 @@ public class ProfileManager{
|
||||
List<String> players = resolvePlayers(entry, defEntry);
|
||||
String playerCountText = resolvePlayerCountText(entry, defEntry);
|
||||
String favicon = resolveFavicon(entry, defEntry);
|
||||
Boolean isHidePlayersEnabled = resolveHidePlayersEnabled(entry, defEntry);
|
||||
Boolean isExtraPlayersEnabled = resolveExtraPlayersEnabled(entry, defEntry);
|
||||
boolean isHidePlayersEnabled = resolveHidePlayersEnabled(entry, defEntry);
|
||||
boolean isExtraPlayersEnabled = resolveExtraPlayersEnabled(entry, defEntry);
|
||||
Integer extraPlayersCount = resolveExtraPlayersCount(entry, defEntry);
|
||||
|
||||
return new ProfileEntry(motd, players, playerCountText, favicon, isHidePlayersEnabled, isExtraPlayersEnabled,
|
||||
extraPlayersCount);
|
||||
return new ProfileEntry(motd, players, playerCountText, favicon,
|
||||
NullBool.resolve(isHidePlayersEnabled), NullBool.resolve(isExtraPlayersEnabled), extraPlayersCount);
|
||||
}
|
||||
|
||||
public static ServerListProfile resolveProfile(AdvancedServerList core, GenericPlayer player, GenericServer server){
|
||||
for(ServerListProfile profile : core.getFileHandler().getProfiles()){
|
||||
if(profile.isInvalidProfile())
|
||||
continue;
|
||||
|
||||
if(profile.evalConditions(player, server))
|
||||
return profile;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static ProfileEntry retrieveProfileEntry(ConfigurationNode node){
|
||||
List<String> motd = resolveList(node, "motd");
|
||||
List<String> players = resolveList(node, "playerCount", "hover");
|
||||
String playerCountText = node.node("playerCount", "text").getString("");
|
||||
String favicon = node.node("favicon").getString("");
|
||||
NullBool hidePlayers = resolveNullBool(node, "playerCount", "hidePlayers");
|
||||
NullBool extraPlayersEnabled = resolveNullBool(node, "playerCount", "extraPlayers", "enabled");
|
||||
Integer extraPlayers = resolveNullableInt(node);
|
||||
|
||||
return new ProfileEntry.Builder()
|
||||
.setMotd(motd)
|
||||
.setPlayers(players)
|
||||
.setPlayerCountText(playerCountText)
|
||||
.setFavicon(favicon)
|
||||
.setHidePlayersEnabled(hidePlayers)
|
||||
.setExtraPlayersEnabled(extraPlayersEnabled)
|
||||
.setExtraPlayerCount(extraPlayers)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static boolean checkOption(Object obj){
|
||||
if(obj == null)
|
||||
return false;
|
||||
|
||||
if(obj instanceof List<?> list){
|
||||
return !list.isEmpty(); // Check if list isn't empty
|
||||
}else
|
||||
if(obj instanceof String str){
|
||||
return !str.isEmpty(); // Check if list is not empty
|
||||
}else
|
||||
if(obj instanceof NullBool nb){
|
||||
return nb.getOrDefault(false); // Return NullBool's value
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private static List<String> resolveMOTD(ProfileEntry profile, ProfileEntry defaultProfile){
|
||||
if(profile == null || profile.getMOTD().isEmpty())
|
||||
return defaultProfile.getMOTD();
|
||||
if(profile == null || !checkOption(profile.getMotd()))
|
||||
return defaultProfile.getMotd();
|
||||
|
||||
return profile.getMOTD();
|
||||
return profile.getMotd();
|
||||
}
|
||||
|
||||
private static List<String> resolvePlayers(ProfileEntry profile, ProfileEntry defaultProfile){
|
||||
if(profile == null || profile.getPlayers().isEmpty())
|
||||
if(profile == null || !checkOption(profile.getPlayers()))
|
||||
return defaultProfile.getPlayers();
|
||||
|
||||
return profile.getPlayers();
|
||||
}
|
||||
|
||||
private static String resolvePlayerCountText(ProfileEntry profile, ProfileEntry defaultProfile){
|
||||
if(profile == null || profile.getPlayerCountText().isEmpty())
|
||||
if(profile == null || !checkOption(profile.getPlayerCountText()))
|
||||
return defaultProfile.getPlayerCountText();
|
||||
|
||||
return profile.getPlayerCountText();
|
||||
}
|
||||
|
||||
private static String resolveFavicon(ProfileEntry profile, ProfileEntry defaultProfile){
|
||||
if(profile == null || profile.getFavicon().isEmpty())
|
||||
if(profile == null || !checkOption(profile.getFavicon()))
|
||||
return defaultProfile.getFavicon();
|
||||
|
||||
return profile.getFavicon();
|
||||
}
|
||||
|
||||
private static Boolean resolveHidePlayersEnabled(ProfileEntry profile, ProfileEntry defaultProfile){
|
||||
if(profile == null || profile.isHidePlayersEnabled() == null)
|
||||
return defaultProfile.isHidePlayersEnabled();
|
||||
private static boolean resolveHidePlayersEnabled(ProfileEntry profile, ProfileEntry defaultProfile){
|
||||
if(profile == null || !checkOption(profile.isHidePlayersEnabled()))
|
||||
return defaultProfile.isHidePlayersEnabled().getOrDefault(false);
|
||||
|
||||
return profile.isHidePlayersEnabled();
|
||||
return profile.isHidePlayersEnabled().getOrDefault(false);
|
||||
}
|
||||
|
||||
private static Boolean resolveExtraPlayersEnabled(ProfileEntry profile, ProfileEntry defaultProfile){
|
||||
if(profile == null || profile.isExtraPlayersEnabled() == null)
|
||||
return defaultProfile.isExtraPlayersEnabled();
|
||||
private static boolean resolveExtraPlayersEnabled(ProfileEntry profile, ProfileEntry defaultProfile){
|
||||
if(profile == null || !checkOption(profile.isExtraPlayersEnabled()))
|
||||
return defaultProfile.isExtraPlayersEnabled().getOrDefault(false);
|
||||
|
||||
return profile.isExtraPlayersEnabled();
|
||||
return profile.isExtraPlayersEnabled().getOrDefault(false);
|
||||
}
|
||||
|
||||
private static Integer resolveExtraPlayersCount(ProfileEntry profile, ProfileEntry defaultProfile){
|
||||
if(profile == null || profile.getExtraPlayersCount() == null)
|
||||
return defaultProfile.getExtraPlayersCount();
|
||||
return defaultProfile.getExtraPlayersCount() == null ? 0 : defaultProfile.getExtraPlayersCount();
|
||||
|
||||
return profile.getExtraPlayersCount();
|
||||
}
|
||||
|
||||
private static List<String> resolveList(ConfigurationNode node, Object... path){
|
||||
try{
|
||||
return node.node(path).getList(String.class);
|
||||
}catch(SerializationException ex){
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
private static NullBool resolveNullBool(ConfigurationNode node, Object... path){
|
||||
if(node.node(path).virtual())
|
||||
return NullBool.NOT_SET;
|
||||
|
||||
return NullBool.resolve(node.node(path).getBoolean());
|
||||
}
|
||||
|
||||
private static Integer resolveNullableInt(ConfigurationNode node){
|
||||
if(node.node("playerCount", "extraPlayers", "amount").virtual())
|
||||
return null;
|
||||
|
||||
return node.node("playerCount", "extraPlayers", "amount").getInt();
|
||||
}
|
||||
}
|
||||
+4
-3
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -29,6 +29,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
|
||||
import org.spongepowered.configurate.ConfigurationNode;
|
||||
import org.spongepowered.configurate.serialize.SerializationException;
|
||||
import org.spongepowered.configurate.serialize.TypeSerializer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
|
||||
@@ -37,7 +38,7 @@ public class ProfileSerializer implements TypeSerializer<ProfileEntry>{
|
||||
|
||||
@Override
|
||||
public ProfileEntry deserialize(Type type, ConfigurationNode node){
|
||||
return ProfileEntry.Builder.resolve(node).build();
|
||||
return ProfileManager.retrieveProfileEntry(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -47,7 +48,7 @@ public class ProfileSerializer implements TypeSerializer<ProfileEntry>{
|
||||
return;
|
||||
}
|
||||
|
||||
node.node("motd").set(profile.getMOTD());
|
||||
node.node("motd").set(profile.getMotd());
|
||||
node.node("playerCount", "hover").set(profile.getPlayers());
|
||||
node.node("playerCount", "text").set(profile.getPlayerCountText());
|
||||
node.node("favicon").set(profile.getFavicon());
|
||||
|
||||
+101
-11
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,20 +25,110 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.replacer;
|
||||
|
||||
import java.util.Map;
|
||||
import ch.andre601.advancedserverlist.api.AdvancedServerListAPI;
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
|
||||
public class StringReplacer{
|
||||
|
||||
public static String replace(String input, Map<String, Object> replacements){
|
||||
StringBuilder output = new StringBuilder(input);
|
||||
int index;
|
||||
for(Map.Entry<String, Object> entry : replacements.entrySet()){
|
||||
index = 0;
|
||||
while((index = output.indexOf(entry.getKey(), index)) != -1){
|
||||
output.replace(index, index + entry.getKey().length(), String.valueOf(entry.getValue()));
|
||||
index += String.valueOf(entry.getValue()).length();
|
||||
public static String replace(String input, GenericPlayer player, GenericServer server){
|
||||
if(input == null)
|
||||
return null;
|
||||
|
||||
char[] chars = input.toCharArray();
|
||||
StringBuilder builder = new StringBuilder(input.length());
|
||||
|
||||
StringBuilder identifier = new StringBuilder();
|
||||
StringBuilder placeholder = new StringBuilder();
|
||||
|
||||
AdvancedServerListAPI api = AdvancedServerListAPI.get();
|
||||
|
||||
for(int i = 0; i < chars.length; i++){
|
||||
char c = chars[i];
|
||||
char next = (i == (chars.length - 1)) ? '\0' : chars[i + 1];
|
||||
|
||||
if(c != '$' || i + 2 >= chars.length){
|
||||
builder.append(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
if(next != '{'){
|
||||
if(next == '\0')
|
||||
continue;
|
||||
|
||||
builder.append(next);
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
boolean identified = false;
|
||||
boolean invalid = true;
|
||||
|
||||
while(++i < chars.length){
|
||||
final char id = chars[i];
|
||||
|
||||
if(id == '}'){
|
||||
invalid = false;
|
||||
break;
|
||||
}
|
||||
|
||||
if(id == ' ' && !identified){
|
||||
identified = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
if(identified){
|
||||
placeholder.append(id);
|
||||
}else{
|
||||
identifier.append(id);
|
||||
}
|
||||
}
|
||||
|
||||
String identifierString = identifier.toString();
|
||||
String placeholderString = placeholder.toString();
|
||||
|
||||
identifier.setLength(0);
|
||||
placeholder.setLength(0);
|
||||
|
||||
if(invalid){
|
||||
builder.append("${").append(identifierString);
|
||||
|
||||
if(identified){
|
||||
builder.append(' ').append(placeholderString);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
PlaceholderProvider provider = api.retrievePlaceholderProvider(identifierString);
|
||||
if(provider == null){
|
||||
builder.append("${").append(identifierString);
|
||||
|
||||
if(identified){
|
||||
builder.append(' ').append(placeholderString);
|
||||
}
|
||||
|
||||
builder.append('}');
|
||||
continue;
|
||||
}
|
||||
|
||||
String replacement = provider.parsePlaceholder(placeholderString, player, server);
|
||||
if(replacement == null){
|
||||
builder.append("${").append(identifierString);
|
||||
|
||||
if(identified){
|
||||
builder.append(' ').append(placeholderString);
|
||||
}
|
||||
|
||||
builder.append('}');
|
||||
continue;
|
||||
}
|
||||
|
||||
builder.append(replacement);
|
||||
}
|
||||
return output.toString();
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
-57
@@ -1,57 +0,0 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.replacer.placeholders;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class PlayerPlaceholders implements Placeholders{
|
||||
|
||||
private final Map<String, Object> replacements = new HashMap<>();
|
||||
|
||||
public PlayerPlaceholders(GenericPlayer<?> player){
|
||||
this.replacements.put("${player name}", player.getName());
|
||||
this.replacements.put("${player protocol}", player.getProtocol());
|
||||
|
||||
if(player.getVersion() != null)
|
||||
this.replacements.put("${player version}", player.getVersion());
|
||||
|
||||
if(player.getPlayer() == null)
|
||||
return;
|
||||
|
||||
this.replacements.put("${player hasPlayedBefore}", player.hasPlayedBefore());
|
||||
this.replacements.put("${player isBanned}", player.isBanned());
|
||||
this.replacements.put("${player isWhitelisted}", player.isWhitelisted());
|
||||
this.replacements.put("${player uuid}", player.getUniqueId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> getReplacements(){
|
||||
return replacements;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,14 @@
|
||||
#
|
||||
unknown_player: "Anonymous"
|
||||
|
||||
#
|
||||
# UUID used for when AdvancedServerList doesn't have a cached player to use for the ${player uuid}
|
||||
# placeholder.
|
||||
#
|
||||
# Defaults to the UUID of MHF_Question (606e2ff0-ed77-4842-9d6c-e1d3321c7838) when not present.
|
||||
#
|
||||
unknown_player_uuid: "606e2ff0-ed77-4842-9d6c-e1d3321c7838"
|
||||
|
||||
#
|
||||
# Should the Caching of players be disabled?
|
||||
#
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# MIT License
|
||||
#
|
||||
# Copyright (c) 2022 Andre_601
|
||||
# Copyright (c) 2022-2023 Andre_601
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# Changelog
|
||||
|
||||
This page lists the recent changes made towards the AdvancedServerListAPI.
|
||||
They are ordered newest to oldest.
|
||||
|
||||
## v2.0.0
|
||||
|
||||
### :octicons-alert-24:{ .changelog-breaking title="Breaking Changes" } Breaking Changes { #v2-breaking }
|
||||
|
||||
- `platform-paper` has been removed. It used the same code as `platform-spigot` and was therefore considered duplicate code and useless.
|
||||
- `core` has been removed. The `CachedPlayer` is no longer needed in the platform-specific APIs.
|
||||
|
||||
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v2-added }
|
||||
|
||||
- `PreServerListSetEvent` to the different platform-specific APIs.
|
||||
- Called before AdvancedServerList alters the server list.
|
||||
- Allows to override the `ProfileEntry` used or even cancel the event.
|
||||
- `ProfileEntry`
|
||||
- Used for setting the different values of the server list.
|
||||
- Own instances can be made using the nested `Builder` class.
|
||||
- Has methods to create a Builder instance from itself, or make a copy from another ProfileEntry-instance.
|
||||
|
||||
### :octicons-pencil-24:{ .changelog-changed title="Changed" } Changed { #v2-changed }
|
||||
|
||||
- Converted `GenericPlayer`, `GenericServer`, `BungeePlayer`, `SpigotPlayer` and `VelocityPlayer` into interfaces.
|
||||
- `GenericPlayer` no longer has `getVersion()`, `hasPlayedBefore()`, `isBanned()` and `isWhitelisted()`. They have been moved to `VelocityPlayer` (Only `getVersion()`) and `SpigotPlayer` respectively.
|
||||
- Converted `NullBool` from a class to an enum.
|
||||
- Contains `TRUE`, `FALSE` and `NOT_SET`.
|
||||
- `isNull()` is now `isNotSet()`.
|
||||
|
||||
### :octicons-trash-24:{ .changelog-removed title="Removed" } Removed { #v2-removed }
|
||||
|
||||
- `UnsupportedAPIAccessException` as it is no longer used in the API itself.
|
||||
|
||||
## v1.0.0
|
||||
|
||||
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v1-added }
|
||||
|
||||
- `AdvancedServerListAPI`
|
||||
- Main class used to add your own `PlaceholderProvider` instances.
|
||||
- `PlaceholderProvider`
|
||||
- Abstract class used to add your own placeholders to parse in AdvancedServerList.
|
||||
|
||||
<!--
|
||||
|
||||
Templates for changelog
|
||||
|
||||
### :octicons-alert-24:{ .changelog-breaking title="Breaking Changes" } Breaking Changes { #v-breaking }
|
||||
### :octicons-plus-circle-24:{ .changelog-added title="Added" } Added { #v-added }
|
||||
### :octicons-pencil-24:{ .changelog-changed title="Changed" } Changed { #v-changed }
|
||||
### :octicons-trash-24:{ .changelog-removed title="Removed" } Removed { #v-removed }
|
||||
|
||||
-->
|
||||
@@ -0,0 +1,157 @@
|
||||
# API
|
||||
|
||||
AdvancedServerList v2 introduced a new API that plugins can hook into to use.
|
||||
As of right now is it only providing a way to add your own placeholders for it to use.
|
||||
|
||||
## Add dependency
|
||||
|
||||
Add the following to your `build.gradle` or `pom.xml` file to use the API:
|
||||
|
||||
=== ":simple-gradle: Gradle"
|
||||
|
||||
Make sure to replace `{version}` with the latest version available in the [GitHub Repository][api-repo].
|
||||
|
||||
```groovy
|
||||
repositorories {
|
||||
maven { url = 'https://jitpack.io/" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'ch.andre601.asl-api:api:{version}'
|
||||
|
||||
// Optional platform dependencies
|
||||
implementation 'ch.andre601.asl-api:platform-bungeecord:{version}'
|
||||
implementation 'ch.andre601.asl-api:platform-paper:{version}'
|
||||
implementation 'ch.andre601.asl-api:platform-spigot:{version}'
|
||||
implementation 'ch.andre601.asl-api:platform-velocity:{version}'
|
||||
}
|
||||
```
|
||||
|
||||
=== ":simple-apachemaven: Maven"
|
||||
|
||||
Make sure to replace `{version}` with the latest version available in the [GitHub Repository][api-repo].
|
||||
|
||||
```xml
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack</id>
|
||||
<url>https://jitpack.io/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>api</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- Optional platform dependencies -->
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-bungeecord</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-paper</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-spigot</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-velocity</artifactId>
|
||||
<version>{version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
```
|
||||
|
||||
[api-repo]: https://github.com/Andre601/asl-api
|
||||
|
||||
## Add own placeholders
|
||||
|
||||
To add your own placeholders will you need to do a few steps.
|
||||
|
||||
### 1) Get API instance
|
||||
|
||||
Use `AdvancedServerListAPI.get()` to retrieve an instance of the currently used AdvancedServerList API.
|
||||
It will be needed at a later point.
|
||||
|
||||
### 2) Create a Placeholder class
|
||||
|
||||
Make a new class that you want to use for the placeholders and let it extend the `PlaceholderProvider` class of AdvancedServerList.
|
||||
Your IDE should now tell you to implement/override some methods. Confirm this action and your class should look something alongside this:
|
||||
```java
|
||||
public class MyPlaceholders extends PlaceholderProvider {
|
||||
|
||||
public MyPlaceholders(String identifier) {
|
||||
super(identifier);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
It's recommended to replace your generated constructor with a no-args one and set the identifier directly in the `super()`.
|
||||
For example:
|
||||
```java
|
||||
public MyPlaceholders() {
|
||||
super("myplaceholders");
|
||||
}
|
||||
```
|
||||
|
||||
The next step now would be to handle the different placeholders. These are handled in the `parsePlaceholder` method you had to override.
|
||||
The `placeholder` String is whatever value was provided after the identifier in `${<identifier> <placeholder>}`. It can contain spaces.
|
||||
|
||||
Something to note is, that when returning `null` will AdvancedServerList understand it as an invalid placeholder and return it unchanged.
|
||||
|
||||
Here is a small example of the final class:
|
||||
```java
|
||||
public class MyPlaceholders extends PlaceholderProvider {
|
||||
|
||||
public MyPlaceholders() {
|
||||
super("myplaceholders");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server) {
|
||||
if(placeholder.equals("hello"))
|
||||
return "Hi!";
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3) Register the placeholder class
|
||||
|
||||
All that is left to do now is to register your class as a new PlaceholderProvider instance. To do this, get the API instance you retrieved earlier and use `addPlaceholderProvider` with a new instance of your class.
|
||||
|
||||
Example:
|
||||
```java
|
||||
AdvancedServerListAPI api = AdvancedServerListAPI.get();
|
||||
|
||||
api.addPlaceholderProvider(new MyPlaceholders());
|
||||
```
|
||||
|
||||
## Events
|
||||
|
||||
!!! info "Note"
|
||||
The mentioned event is only accessible through one of the platform dependencies, as those are used in the platform's respective event handler system.
|
||||
|
||||
v1.1.0 of the API adds the `PreServerListSetEvent` to the different platform dependencies to use.
|
||||
It allows you to modify the ProfileEntry used for the player pinging the server/proxy or even cancelling the event altogether.
|
||||
|
||||
### ProfileEntry
|
||||
|
||||
The ProfileEntry class has been moved to the API in v1.1.0 allowing you to create your own versions using the available Builder class.
|
||||
|
||||
The ProfileEntry is what contains the necessary data from the server list profiles. This can be an entry from the "profiles" list, the settings themselves in the file or a mix of both depending on what options are present.
|
||||
You can create a new entry or copy an existing one (i.e. from the [`PreServerListSetEvent`](#events)) to modify and use in the server list by setting it in the aforementioned `PreServerListSetEvent`.
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,24 @@
|
||||
.md-header__button.md-logo img {
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.md-header__button.md-logo {
|
||||
padding-right: unset;
|
||||
padding-left: unset;
|
||||
}
|
||||
|
||||
.changelog-added {
|
||||
color: #2ea043;
|
||||
}
|
||||
|
||||
.changelog-removed {
|
||||
color: #f85149;
|
||||
}
|
||||
|
||||
.changelog-changed {
|
||||
color: #1f6feb;
|
||||
}
|
||||
|
||||
.changelog-breaking {
|
||||
color: #9e6a03
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
## About
|
||||
|
||||
!!! warning "The below examples may only work in v1.10.0 or newer!"
|
||||
|
||||
This page lists some examples you may want to use for your proxy or server.
|
||||
|
||||
Feel free to suggest additional examples on my [Discord Server](https://discord.gg/6dazXp6) in the `#advancedserverlist` channel.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Versions](#versions)
|
||||
- [Different List for outdated Clients](#different-list-for-outdated-clients)
|
||||
- [Different MOTD for < 1.16](#different-motd-for-116)
|
||||
- [Spigot/PaperMC](#spigotpapermc)
|
||||
- [Different profile for banned Player](#different-profile-for-banned-player)
|
||||
- [Other](#other)
|
||||
- [Different profile for different host](#different-profile-for-different-host)
|
||||
- [Different profile for known player](#different-profile-for-known-player)
|
||||
- [Random MOTD but same hover](#random-motd-but-same-hover)
|
||||
|
||||
----
|
||||
## Versions
|
||||
|
||||
Some examples about version-related things.
|
||||
|
||||
### Different List for outdated Clients
|
||||
|
||||
You may want to display a separate MOTD or text for incompatible client versions.
|
||||
This example here shows a separate MOTD and player count message for when the player's client version is older than what the server supports.
|
||||
|
||||
```yaml
|
||||
priority: 1
|
||||
|
||||
# Display this profile, if the version of the player is below 760 (1.19.1)
|
||||
conditions:
|
||||
- '${player protocol} < 760'
|
||||
|
||||
motd:
|
||||
- <red>You are using an outdated client!
|
||||
- <red>Please update to 1.19.1 to join.
|
||||
|
||||
playerCount:
|
||||
text: '<red>Outdated Client!'
|
||||
```
|
||||
|
||||
### Different MOTD for < 1.16
|
||||
|
||||
This profile would display a MOTD without HEX colours if the player's version is below 735 (1.16).
|
||||
|
||||
```yaml
|
||||
priority: 1
|
||||
|
||||
# Display this profile, if the version of the player is below 735 (1.16)
|
||||
conditions:
|
||||
- '${player protocol} < 735'
|
||||
|
||||
motd:
|
||||
- <grey>Welcome to <aqua>YourServer.com</aqua>!
|
||||
- <grey>Enjoy your stay.
|
||||
```
|
||||
|
||||
----
|
||||
## Spigot/PaperMC
|
||||
|
||||
Examples that can be used with the Spigot or PaperMC version.
|
||||
|
||||
### Different profile for banned Player
|
||||
|
||||
!!! warning "Requires a cached player to work reliably."
|
||||
|
||||
Displays a separate profile for when the player has been banned from the server.
|
||||
|
||||
```yaml
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- '${player isBanned} = true'
|
||||
|
||||
motd:
|
||||
- <red>You have been <bold>BANNED</bold>!
|
||||
- <red>Go away.
|
||||
|
||||
# Don't show the player count to the banned player.
|
||||
playerCount:
|
||||
hidePlayers: true
|
||||
```
|
||||
|
||||
----
|
||||
## Other
|
||||
|
||||
Some misc examples.
|
||||
|
||||
### Different profile for different host
|
||||
|
||||
Display a different profile when the playing pings a specific domain/IP.
|
||||
|
||||
```yaml
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- '${server host} = other.example.com'
|
||||
|
||||
motd:
|
||||
- <grey>Please use <aqua>mc.example.com
|
||||
- <grey>to join our server.
|
||||
```
|
||||
|
||||
### Different profile for known player
|
||||
|
||||
Display a different profile, if the player pinging the server is "known" by AdvancedServerList (Has joined before with the same IP).
|
||||
|
||||
```yaml
|
||||
priority: 1
|
||||
|
||||
conditions:
|
||||
- `${player name} != Anonymous` # "Anonymous" should be replaced with whatever you use in 'unknown_player'
|
||||
|
||||
motd:
|
||||
- <grey>Hello there <aqua>${player name}</aqua>!
|
||||
- <grey>It's nice to see you again.
|
||||
|
||||
playerCount:
|
||||
hover:
|
||||
- '<grey>Welcome back <aqua>${player name}</aqua>!'
|
||||
- '<grey>'
|
||||
- '<grey>Come and join <aqua>${server playersOnline}'
|
||||
- '<aqua>other players</aqua> <grey>on the Server!'
|
||||
```
|
||||
|
||||
### Random MOTD but same hover
|
||||
|
||||
v1.10.0 of AdvancedServerList introduced an option called `profiles`. It allows you to create multiple variants of an MOTD, playercount, etc. while also supporting the normal (global) options as a fallback.
|
||||
|
||||
The following example will create a profile that has a randomized MOTD, but the same hover for both:
|
||||
```yaml
|
||||
priority: 1
|
||||
|
||||
profiles:
|
||||
- motd:
|
||||
- 'A randomized MOTD.'
|
||||
- 'Lines change, but hover is the same.'
|
||||
- motd: ['Different Syntax.', 'May be more readable.']
|
||||
|
||||
playerCount:
|
||||
hover:
|
||||
- 'This player count hover always'
|
||||
- 'stays the same, no matter what'
|
||||
- 'MOTD is being used here.'
|
||||
```
|
||||
@@ -0,0 +1,34 @@
|
||||
# AdvancedServerList Wiki
|
||||
|
||||
Welcome to the Wiki of AdvancedServerList!
|
||||
|
||||
On this site can you find the latest documentation for the plugin, including some useful examples.
|
||||
If you're new to the plugin is it recommended to check out the [Profiles page](./profiles) for a quick start on how to use this plugin.
|
||||
|
||||
## Platforms
|
||||
|
||||
AdvancedServerList supports the following platforms:
|
||||
|
||||
<a href="https://www.spigotmc.org" target="_blank">
|
||||
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/spigot_vector.svg" width="64" alt="platform-spigot" title="Tested on Spigot">
|
||||
</a>
|
||||
<a href="https://papermc.io" target="_blank">
|
||||
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/paper_vector.svg" width="64" alt="platform-paper" title="Tested on Paper">
|
||||
</a>
|
||||
<a href="https://www.spigotmc.org" target="_blank">
|
||||
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/bungeecord_vector.svg" width="64" alt="platform-bungeecord" title="Tested on BungeeCord">
|
||||
</a>
|
||||
<a href="https://www.papermc.io" target="_blank">
|
||||
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/waterfall_vector.svg" width="64" alt="platform-waterfall" title="Tested on Waterfall">
|
||||
</a>
|
||||
<a href="https://velocitypowered.com" target="_blank">
|
||||
<img src="https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@2/assets/minimal/supported/velocity_vector.svg" width="64" alt="platform-velocity" title="Tested on Velocity">
|
||||
</a>
|
||||
|
||||
## Pages
|
||||
|
||||
- [Profiles](./profiles)
|
||||
- [Formatting](./profiles/formatting)
|
||||
- [Placeholders](./profiles/placeholders)
|
||||
- [API](./api)
|
||||
- [Examples](./examples)
|
||||
@@ -0,0 +1,21 @@
|
||||
# Formatting
|
||||
|
||||
All text options with exception of [`Conditions`](../#conditions) allow the usage of formatting options using [MiniMessage].
|
||||
|
||||
## Unsupported options
|
||||
|
||||
The following options are **not** supported, no matter what option they are used in:
|
||||
|
||||
- Hover Actions (Show text, Show Advancement, etc)
|
||||
- Click Actions (Run command, Suggest command, etc.)
|
||||
- Custom Fonts (May work if player already has the resource pack loaded)
|
||||
|
||||
## Colors
|
||||
|
||||
Normal text colours such as `<aqua>` or `<red>` can be used in all text options.
|
||||
|
||||
## HEX Colours
|
||||
|
||||
24-Bit HEX colours such as `<#ffffff>` can be used in the [`Motd`](../#motd) option on 1.16+ servers/proxies.
|
||||
|
||||
[MiniMessage]: https://docs.adventure.kyori.net/minimessage/index.html
|
||||
@@ -0,0 +1,157 @@
|
||||
# Profiles
|
||||
|
||||
AdvancedServerList allows the creation of multiple profiles.
|
||||
A profile is a single YAML file located in the plugin's `profiles` directory containing multiple settings including [Conditions](#conditions) and [Priority](#priority).
|
||||
|
||||
!!! info "Important"
|
||||
In order for a profile to be considered "valid" by AdvancedServerList will it need to meet the following conditions:
|
||||
|
||||
- Have a [`Priority`](#priority) set to a valid, whole number (i.e. `1`)
|
||||
- Have **at least one** of the following options set:
|
||||
- [`Profiles`](#profiles) with at least one entry containing one of the below option
|
||||
- [`Motd`](#motd) set with at least one line of text
|
||||
- [`Favicon`](#favicon) set with a non-empty String
|
||||
- [`HidePlayers`](#hideplayers) set to `true`
|
||||
- [`Hover`](#hover) set with at least one line of text
|
||||
- [`Text`](#text) set with a non-empty String
|
||||
|
||||
## Priority
|
||||
|
||||
The priority option determines the order in which the profiles are checked by AdvancedServerList, starting with the highest number.
|
||||
|
||||
It will go through each file until it finds one with [`conditions`](#conditions) returning true (Default if no conditions are set).
|
||||
This means that a profile with no conditions and a priority of `1` will be used before a profile with a condition and priority `0` even if the player is meeting the condition.
|
||||
|
||||
## Conditions
|
||||
|
||||
A list of conditions can be set that need to be met in order to have this profile shown to the player.
|
||||
[Placeholders](./formatting#placeholders) can be used to further customize the conditions (PlaceholderAPI placeholders are **not** supported).
|
||||
|
||||
Only when **all** conditions defined return true will the profile be displayed.
|
||||
|
||||
You can remove this option, or set it to an empty list (`conditions: []`) to always return true.
|
||||
|
||||
### Operants
|
||||
|
||||
The following operants are available and can be used in the conditions.
|
||||
|
||||
!!! warning "Only one operant can be used per condition!"
|
||||
|
||||
| Operant | Description |
|
||||
| ------- | ------------------------------------------------------------------ |
|
||||
| `<` | Checks if the left value is less than the right one.\* |
|
||||
| `<=` | Checks if the left value is less than or equal to the right one.\* |
|
||||
| `>` | Checks if the left value is more than the right one.\* |
|
||||
| `>=` | Checks if the left value is more than or equal to the right one.\* |
|
||||
| `=` | Checks if the left value is equal to the right one. |
|
||||
| `!=` | Checks if the left value is not equal to the right one. |
|
||||
|
||||
\* In the case of the provided value not being a number will the plugin instead use the text length to compare with.
|
||||
|
||||
## Profiles
|
||||
|
||||
!!! info "Available since v1.10.0"
|
||||
|
||||
The profiles option allows you to add multiple combinations of all the other options (With the exception of [`Priority`](#priority) and [`Conditions`](#conditions)) to have randomized MOTDs, player counts, etc.
|
||||
|
||||
If an option is not present in an entry will AdvancedServerList try to use one defined in the file or use whatever default value would be for that option.
|
||||
|
||||
As an example:
|
||||
```yaml
|
||||
priority: 1
|
||||
|
||||
profiles:
|
||||
- motd:
|
||||
- Line 1
|
||||
- Line 2
|
||||
playerCount:
|
||||
text: 'Awesome!'
|
||||
- playerCount:
|
||||
text: 'Also Awesome'
|
||||
|
||||
motd:
|
||||
- Line A
|
||||
- Line B
|
||||
```
|
||||
...the above file would randomly select between a MOTD saying `Line 1\nLine 2` and a player count saying `Awesome!` or a MOTD saying `Line A\nLine B` while the player count says `Also Awesome`
|
||||
|
||||
## Motds
|
||||
|
||||
!!! warning "Only available in v1.9.0"
|
||||
|
||||
This option allows to create multiple MOTDs that AdvancedServerList should randomly select from.
|
||||
|
||||
Due to the structure of this option will you need to use `|-` to have multi-line MOTDs.
|
||||
|
||||
Example:
|
||||
```yaml
|
||||
motds:
|
||||
- |-
|
||||
Line 1
|
||||
Line 2
|
||||
- |-
|
||||
Line A
|
||||
Line B
|
||||
```
|
||||
|
||||
## Motd
|
||||
|
||||
The motd option allows to set up to two lines to be displayed in an MOTD.
|
||||
Normal colour and formatting codes such as `<aqua>` or `<bold>` are supported. On 1.16 and newer can you also use HEX colours using either `<#rrggbb>` or `<color:#rrggbb>`.
|
||||
|
||||
If you want to display multiple MOTDs will you need to use the [`Profiles` option](#profiles)
|
||||
|
||||
## Favicon
|
||||
|
||||
The favicon option allows you to customize the favicon and display one or multiple different images.
|
||||
|
||||
This option currently supports the following values:
|
||||
|
||||
- A URL pointing to a `64x64` PNG image.
|
||||
- A name with `.png` extension that matches a PNG file in the `favicons` folder.
|
||||
- `${player uuid}` (or alternatively `${player name}`) to display the head of the player. The UUID/Name resolving is handled by https://mc-heads.net
|
||||
|
||||
Please note that AdvancedServerList will rescale the image to be 64x64 pixels, so be sure to provide images at that particular scale.
|
||||
|
||||
## PlayerCount
|
||||
|
||||
The `playerCount` option contains multiple different options all about the Player count itself.
|
||||
|
||||
### HidePlayers
|
||||
|
||||
Boolean option to set whether AdvancedServerList should hide the player count or not. When set to `true` will the player count be replaced with `???`.
|
||||
Additionally will the [`Text`](#text) and [`Hover`](#hover) option be ignored.
|
||||
|
||||
### Hover
|
||||
|
||||
This option allows to override the hover text usually displaying the players on the server when hovering over the player count.
|
||||
|
||||
You can either remove this option or set to an empty list (`hover: []`) to not override the hover.
|
||||
|
||||
### Text
|
||||
|
||||
This option allows to override the text usually displaying the online players and total players that can join.
|
||||
Note that AdvancedServerList will not add the `<online>/<max>` text to the player count. Instead will you need to use [`${server playersOnline}`](./placeholders#server) and [`${server playersMax}`](./placeholders#server) respectively.
|
||||
|
||||
!!! info "Note"
|
||||
This feature works by changing the "outdated server" message followed by altering the protocol version of the server.
|
||||
Due to this will your server appear as "outdated" to the client (Have the ping icon crossed out). This is nothing that can be changed unfortunately.
|
||||
|
||||
To not override the player count, remove this option or set it to an empty String (`text: ''`).
|
||||
|
||||
### ExtraPlayers
|
||||
|
||||
Contains options to modify how the `<max>` number in the player count should look like.
|
||||
|
||||
!!! warning "Using this option will modify the `${server playersMax}` placeholder (Except in conditions)"
|
||||
|
||||
#### Enabled
|
||||
|
||||
Boolean option to set whether the extra players feature should be used or not.
|
||||
When set to `true` will the max amount of players be modified by taking the current amount of online players, add [`Amount`](#amount) more to it and use it.
|
||||
|
||||
#### Amount
|
||||
|
||||
Sets the number to add to the current online players to then use as the new max players count.
|
||||
|
||||
As an example, setting this to `1` while `10` players are online will display `11`, while `-1` would display `9`.
|
||||
@@ -0,0 +1,52 @@
|
||||
# Placeholders
|
||||
|
||||
AdvancedServerList provides a set of pre-made placeholders using the `${<identifier> <placeholder>}` format adobted from BungeeTabListPlus.
|
||||
It also has built-in [PlaceholderAPI support](#placeholderapi) for Spigot and Paper Servers and since v2 can even allow you to [add your own placeholders](#custom-placeholders) by using its [API](../../api).
|
||||
|
||||
## Built-in Placeholders
|
||||
|
||||
The following placeholders are available in AdvancedServerList itself. Please note that not all placeholders are available on all platforms.
|
||||
|
||||
### Player Placeholders
|
||||
|
||||
These placeholders use the player who pinged the server, to return values. They may require the player to be cached in order to work.
|
||||
|
||||
| Placeholder | Description | Platforms | Cached Player required?\* |
|
||||
| --------------------------- | --------------------------------------------------------------- | ------------ | ------------------------ |
|
||||
| `${player name}` | The name of the player. | All | Yes\*\* |
|
||||
| `${player protocol}` | The protocol version of the player. | All | No |
|
||||
| `${player uuid}` | The UUID of the player. | All | Yes\*\*\* |
|
||||
| `${player version}` | The protocol version of the player as readable MC version. | Velocity | No |
|
||||
| `${player hasPlayedBefore}` | Boolean for whether the player has played on the server before. | Spigot/Paper | Yes |
|
||||
| `${player isBanned}` | Boolean for whether the player has been banned from the server. | Spigot/Paper | Yes |
|
||||
| `${player isWhitelisted}` | Boolean for whether the player is whitelisted on the server. | Spigot/Paper | Yes |
|
||||
|
||||
\*Whether this placeholder requires the player to have joined before while AdvancedServerList was running. When `disable_cache` is enabled will these placeholders not work.
|
||||
\*\*Will default to whatever name has been provided in the config.yml's `unknown_player` option, when the player isn't cached yet.
|
||||
\*\*\*Will default to whatever name has been provided in the config.yml's `unknown_player_uuid` option, when the player isn't cached yet.
|
||||
|
||||
### Server
|
||||
|
||||
These placeholders use values given by the server/proxy AdvancedServerList runs on.
|
||||
|
||||
| Placeholder | Description |
|
||||
| ------------------------- | -------------------------------------------------------- |
|
||||
| `${server playersOnline}` | The number of players online on this server. |
|
||||
| `${server playersMax}` | The total number of players that can join this server.\* |
|
||||
| `${server host}` | The domain/IP the player pinged. |
|
||||
|
||||
\*This placeholder is affected by the [`Amount` option](../#amount) in a server list profile, with the exception being when used in [`Conditions`](../#conditions).
|
||||
|
||||
## PlaceholderAPI
|
||||
|
||||
The Spigot and Paper version of AdvancedServerList allow the usage of *any* placeholders provided by PlaceholderAPI by using the `%<identifier>_<values>%` placeholder format.
|
||||
Depending on the placeholder used is a cached player required (i.e. `%player_name%`). AdvancedServerList will try to get a OfflinePlayer instance based on the cached UUID from the server to manage this.
|
||||
|
||||
!!! warning "PlaceholderAPI placeholders can NOT be used in Conditions!"
|
||||
|
||||
## Custom Placeholders
|
||||
|
||||
Since version 2 of AdvancedServerList are developers able to provide their own placeholders to be used in a server list profile.
|
||||
The format follows the same one as the [built-in placeholders](#built-in-placeholders), meaning it is `${<identifier> <placeholder>}`.
|
||||
|
||||
If you're a developer and want to integrate your own placeholders into AdvancedServerList, read about it [here](../../api).
|
||||
+495
@@ -0,0 +1,495 @@
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | This is the main file used by MkDocs to build the pages. |
|
||||
# | It contains a lot of information and settings for you to read and use. |
|
||||
# | Comments may contain "Read More" URLs to more in-depth documentation about the option for you to read. |
|
||||
# | |
|
||||
# | You can check out https://www.mkdocs.org/user-guide/configuration/ for a more detailed explanation of |
|
||||
# | all the options MkDocs offers by default. |
|
||||
# | |
|
||||
# +------------------------------------------------- NOTE -------------------------------------------------+
|
||||
# | |
|
||||
# | Some of the options listed here are only available through the usage of Material for MkDocs. |
|
||||
# | Those options will usually have a link to the docs of this Theme and also mention "Material" as name. |
|
||||
# | The actual name of the theme is "Material for MkDocs" and "Material" is used for simplicity reasons. |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | Main Page Settings for MkDocs. |
|
||||
# | Those settings are site name, site description, Site author and also Site URL (Canonical URL) |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#site_name |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#site_description |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#site_author |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#site_url |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
site_name: AdvancedServerList Wiki
|
||||
site_description: 'Wiki for the AdvancedServerList plugin'
|
||||
site_author: 'Andre_601'
|
||||
site_url: 'https://www.andre601.ch/AdvancedServerList' # Uncomment to set a canonical URL
|
||||
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | This setting allows you to define your own Copyright notice. |
|
||||
# | The text is treated as HTML code so you can use things like <a> tags or © to display the |
|
||||
# | Copyright icon. |
|
||||
# | |
|
||||
# | Where or IF the Copyright is displayed depends on the theme you use. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#copyright |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
copyright: |
|
||||
© Andre_601
|
||||
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The base folder to use. |
|
||||
# | Any Markdown files you put into this folder will be turned into a static HTML page once you build or |
|
||||
# | publish your page. |
|
||||
# | |
|
||||
# | It is also used as the base directory for other settings like the "extra_css" or "extra_javascript" |
|
||||
# | option. |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
docs_dir: docs/
|
||||
|
||||
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | These options allow to define a Repository to link to. |
|
||||
# | The result will, depending on the theme, be a link somewhere shown on the page that links to the |
|
||||
# | Repository with the specified repo_name. |
|
||||
# | |
|
||||
# | This will also enable a "edit" button on the page itself that allows the direct editing of the page. |
|
||||
# | You can disable this by setting "edit_uri" to an empty String. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#repo_name |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#repo_url |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#edit_uri |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
repo_name: Andre601/AdvancedServerList
|
||||
repo_url: https://github.com/Andre601/AdvancedServerList
|
||||
#edit_uri: tree/master/docs # Uncomment to define a different URI/URL for the "edit" option
|
||||
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "nav" option is where you define the navigation to show in MkDocs. |
|
||||
# | |
|
||||
# | Depending on the theme you use will the resulting Navigation look different. |
|
||||
# | |
|
||||
# | You can set different types of navigations. Either just the path, the path with a separate title or |
|
||||
# | an external URL. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#documentation-layout |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
nav:
|
||||
- Home: index.md
|
||||
- Profiles:
|
||||
- profiles/index.md
|
||||
- Formatting: profiles/formatting.md
|
||||
- Placeholders: profiles/placeholders.md
|
||||
- API:
|
||||
- api/index.md
|
||||
- Changelog: api/changelog.md
|
||||
- Examples: examples.md
|
||||
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "theme" section allows you to define what theme to use. |
|
||||
# | It is also used for theme-specific options, but also for advanced stuff such as theme-extensions, if |
|
||||
# | the theme actually supports it. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#theme |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
theme:
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "name" option is where you define the theme to use. |
|
||||
# | |
|
||||
# | Note that not all themes are included by default and will require you to install them first. |
|
||||
# | The Material theme is one of them. See the "Read More" link for instructions on how to install it. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/getting-started/ |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
name: 'material'
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The Material theme allows "theme-extsnions", meaning that you can override parts of it by either |
|
||||
# | overriding a particular file, or only parts (blocks) of it. |
|
||||
# | |
|
||||
# | If you want to override parts of Material, uncomment the "custom_dir" option below and set the |
|
||||
# | folder (relative to the mkdocs.yml file) where your theme extensions will be located at. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#custom_dir |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/customization/#extending-the-theme |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
#custom_dir: 'theme'
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "favicon" option allows you to set your own image/icon to use in the browser-tab. |
|
||||
# | |
|
||||
# | Pretty much all image types are supported, but it's recommended to use a PNG, SVG or ICO image for |
|
||||
# | the favicon. |
|
||||
# | |
|
||||
# | The directory is relative to the "docs_dir". |
|
||||
# | |
|
||||
# | Example: Having a favicon.png in docs/assets/images will result in the "favicon" setting showing |
|
||||
# | 'assets/images/favicon.png' |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-logo-and-icons/#favicon |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
favicon: 'assets/images/favicon.png'
|
||||
logo: 'assets/images/favicon.png'
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "palette" section is a Material option and allows you to define specific style options such as |
|
||||
# | Color-Scheme, and primary and secondary Color. |
|
||||
# | |
|
||||
# | You can also define multiple palettes that can have different Color Schemses and primary and/or |
|
||||
# | secondary Colors. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/ |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-palette-toggle |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
palette:
|
||||
|
||||
# +----------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "scheme" option is used to define the Color Scheme used by Material. |
|
||||
# | |
|
||||
# | Material offers a "default" and a "slate" scheme. "default" is obviously the default (bright) |
|
||||
# | Color scheme while "slate" is the native dark theme from Material. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#color-scheme |
|
||||
# | |
|
||||
# +----------------------------------------------------------------------------------------------------+
|
||||
scheme: 'slate'
|
||||
|
||||
# +----------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | "primary" is used to set the main color of the Material Theme. |
|
||||
# | |
|
||||
# | The primary color is used on the top banner of the page but also for things like the link color. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#primary-color |
|
||||
# | |
|
||||
# +----------------------------------------------------------------------------------------------------+
|
||||
primary: 'indigo'
|
||||
|
||||
# +----------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "accent" is used for moments such as hovering over links. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#accent-color |
|
||||
# | |
|
||||
# +----------------------------------------------------------------------------------------------------+
|
||||
accent: 'indigo'
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | With the "font" option can you set a different font to use. |
|
||||
# | |
|
||||
# | Material supports all Google fonts, but you can also define your own ones if you choose so. |
|
||||
# | |
|
||||
# | The "text" option is used for the regular font while "code" is used for code blocks, inline code and |
|
||||
# | similar. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-fonts/ |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
#font:
|
||||
# text: 'Roboto'
|
||||
# code: 'Roboto Mono'
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | Material suppors more than 40 different languages which you can set using the "language" option |
|
||||
# | below. |
|
||||
# | |
|
||||
# | The default language is "en" (English). |
|
||||
# | |
|
||||
# | You can also enable/set a "selector" to allow switching between languages. |
|
||||
# | See the "alternate" option in the "extra" section below for more information on this topic. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-language/ |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
#language: 'en'
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "direction" option is commonly used together with the "language" option. |
|
||||
# | |
|
||||
# | It allows you to change the text direction from the default left-to-right (ltr) to right-to-left |
|
||||
# | (rtl) which is used in certain languages. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-language/#directionality |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
#direction: 'ltr'
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "features" option allows you to enable specific features of Material, by adding them to the |
|
||||
# | list. |
|
||||
# | |
|
||||
# | Features are in the format <category>.<name>. As an example, the feature to enable tabs is called |
|
||||
# | navigation.tabs. |
|
||||
# | |
|
||||
# | The list below contains all known features of Material. |
|
||||
# | |
|
||||
# | Features marked with a * are currently Insiders-only. (Last update: 11th December 2021) |
|
||||
# | https://squidfunk.github.io/mkdocs-material/insiders/ |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/setting-up-navigation/ |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
features:
|
||||
# Announce
|
||||
#
|
||||
#- announce.dismiss # Adds a "X" button to dismiss a news banner/mark it as read.*
|
||||
|
||||
# Header
|
||||
#
|
||||
#- header.autohide # Hide header when user scrolls past a specific point.
|
||||
|
||||
# Navigation:
|
||||
#
|
||||
#- navigation.expand # Expand all collapsable sections.
|
||||
#- navigation.instant # Instant loading pages.
|
||||
- navigation.indexes # Attach pages directly to Sections. Incompatible with "toc.integrate"
|
||||
#- navigation.sections # Render top sections as groups.
|
||||
- navigation.tabs # Render top sections as tabs at the top.
|
||||
- navigation.tabs.sticky # Tabs won't disappear when scrolling down. Requires "navigation.tabs".
|
||||
#- navigation.top # Adds a "Back to top" that is shown when scrolling up.
|
||||
#- navigation.tracking # Updates the url with highlighted section anchor.
|
||||
|
||||
# Search
|
||||
#
|
||||
#- search.highlight # Search will highlight the searched word(s) on the page.*
|
||||
#- search.share # Adds an option to share a search query link.*
|
||||
#- search.suggest # Search will suggest the likeliest completion for a word.*
|
||||
|
||||
# Table of Contents
|
||||
#
|
||||
#- toc.integrate # Include the TOC sections in the left navugation.
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "icon" section allows you to define a icon to use for the logo and/or repository. |
|
||||
# | |
|
||||
# | To use already available icons will you need to set the right path for it, depending on which you |
|
||||
# | want to use. |
|
||||
# | |
|
||||
# | Available icons: |
|
||||
# | - FontAwesome |
|
||||
# | - Brands: fontawesome/brands/... (https://fontawesome.com/icons?d=gallery&p=2&s=brands&m=free) |
|
||||
# | - Regular: fontawesome/regular/... (https://fontawesome.com/icons?d=gallery&p=2&s=regular&m=free) |
|
||||
# | - Solid: fontawesome/solid/... (https://fontawesome.com/icons?d=gallery&p=2&s=solid&m=free) |
|
||||
# | |
|
||||
# | - Material Design Icons: material/... (https://materialdesignicons.com/) |
|
||||
# | |
|
||||
# | - Octicons: octicons/... (https://primer.style/octicons/) |
|
||||
# | |
|
||||
# | You can also define your own Image for the logo. To do that, remove the "logo" option from "icon" |
|
||||
# | instead add a "logo" option on the same level as the "icon" one, where you then set the path |
|
||||
# | (relative to the "docs_dir") to the icon to use. Supported are all images types, including SVG. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-logo-and-icons/#logo |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
icon:
|
||||
repo: 'octicons/mark-github-16'
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "admonition" option allows you to set a different icon for each admonition type. |
|
||||
# | |
|
||||
# | This is currently a Insiders-only feature. (Last update: 7th October 2021) |
|
||||
# | https://squidfunk.github.io/mkdocs-material/insiders/ |
|
||||
# | |
|
||||
# | Supported are all bundled icons: |
|
||||
# | - FontAwesome |
|
||||
# | - Brands: fontawesome/brands/... (https://fontawesome.com/icons?d=gallery&p=2&s=brands&m=free) |
|
||||
# | - Regular: fontawesome/regular/... (https://fontawesome.com/icons?d=gallery&p=2&s=regular&m=free) |
|
||||
# | - Solid: fontawesome/solid/... (https://fontawesome.com/icons?d=gallery&p=2&s=solid&m=free) |
|
||||
# | |
|
||||
# | - Material Design Icons: material/... (https://materialdesignicons.com/) |
|
||||
# | |
|
||||
# | - Octicons: octicons/... (https://primer.style/octicons/) |
|
||||
# | |
|
||||
# | You can also create and use your own icons. See the documentation for more information. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/reference/admonitions/#changing-the-icons |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
admonition:
|
||||
note: 'octicons/tag-16'
|
||||
abstract: 'octicons/checklist-16'
|
||||
info: 'octicons/info-16'
|
||||
tip: 'octicons/squirrel-16'
|
||||
success: 'octicons/check-16'
|
||||
question: 'octicons/question-16'
|
||||
warning: 'octicons/alert-16'
|
||||
failure: 'octicons/x-circle-16'
|
||||
danger: 'octicons/zap-16'
|
||||
bug: 'octicons/bug-16'
|
||||
example: 'octicons/beaker-16'
|
||||
quote: 'octicons/quote-16'
|
||||
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | With the "extra_css" option can you add your own (S)CSS files to enhance the documentation. |
|
||||
# | |
|
||||
# | The path to the file is relative to the "docs_dir". |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#extra_css |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
extra_css:
|
||||
- assets/stylesheets/custom.css
|
||||
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | Similar to the "extra_css" option does the "extra_javascript" option allow you to set custom JS files |
|
||||
# | to add extra featurues. |
|
||||
# | |
|
||||
# | The path to the file is relative to the "docs_dir". |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#extra_javascript |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
#extra_javascript:
|
||||
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "extra" section contains pretty much anything you want, as long as it is a valid key-value pair. |
|
||||
# | |
|
||||
# | Material uses this section for different custom settings that wouldn't fit in the theme section. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#extra |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
extra:
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The social section allows you to set a list of entries which would be displayed in the footer of the |
|
||||
# | page. |
|
||||
# | |
|
||||
# | Each entry has the exact same options: |
|
||||
# | - icon: Path to the SVG icon to use. See "icon" section for available icon sets. |
|
||||
# | - link: URL to which the icon should link. |
|
||||
# | - name: Optional Name that would be displayed as title on hover. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/setting-up-the-footer/#social-links |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
social:
|
||||
- icon: 'fontawesome/brands/github'
|
||||
link: 'https://github.com/Andre601/asl-wiki'
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | Allows you to hide the "Made with Material for MkDocs" text in the footer of the pages by setting |
|
||||
# | this to "true". |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/setting-up-the-footer/#generator-notice |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
#generator: true
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "manifest" option allows you to define a .manifest file to use. |
|
||||
# | |
|
||||
# | A .manifest file makes the doc act like a web-application and tells it how to behave when installed. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/reference/meta-tags/#adding-a-web-app-manifest |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
#manifest: manifest.webmanifest
|
||||
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | The "alternate" option can be used to create a selector to switch languages. |
|
||||
# | |
|
||||
# | Using this requires you to create a specific, more complicated MkDocs setup. |
|
||||
# | |
|
||||
# | A Setup Guide for multi-language docs can be found here: |
|
||||
# | https://github.com/squidfunk/mkdocs-material/discussions/2346 |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://squidfunk.github.io/mkdocs-material/setup/changing-the-language/#site-language-selector |
|
||||
# | |
|
||||
# +------------------------------------------------------------------------------------------------------+
|
||||
#alternate:
|
||||
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
# | |
|
||||
# | MkDocs allows the usage of Markdown extensions which can do various things. |
|
||||
# | |
|
||||
# | Material includes the pymdownx extension which provides a lot of useful features to use. |
|
||||
# | |
|
||||
# | Note that some extensions may use specific settings that you need to set. |
|
||||
# | Please check out the official documentation of PyMdownx for more information: |
|
||||
# | https://facelessuser.github.io/pymdown-extensions/ |
|
||||
# | |
|
||||
# | Material already provides required CSS and JS values for the PyMdownX Extensions, which means you do |
|
||||
# | not need to set them up yourself. |
|
||||
# | |
|
||||
# | Read More: |
|
||||
# | - https://www.mkdocs.org/user-guide/configuration/#markdown_extensions |
|
||||
# | |
|
||||
# +--------------------------------------------------------------------------------------------------------+
|
||||
markdown_extensions:
|
||||
- markdown.extensions.admonition:
|
||||
- markdown.extensions.toc:
|
||||
permalink: true
|
||||
- markdown.extensions.attr_list:
|
||||
- pymdownx.emoji:
|
||||
emoji_index: !!python/name:materialx.emoji.twemoji
|
||||
emoji_generator: !!python/name:materialx.emoji.to_svg
|
||||
- pymdownx.highlight:
|
||||
- pymdownx.magiclink:
|
||||
- pymdownx.superfences:
|
||||
- pymdownx.tabbed:
|
||||
alternate_style: true
|
||||
+7
-2
@@ -2,7 +2,7 @@
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022 Andre_601
|
||||
~ Copyright (c) 2022-2023 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -46,7 +46,7 @@
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>papermc</id>
|
||||
<url>https://papermc.io/repo/repository/maven-public</url>
|
||||
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>placeholderapi-repo</id>
|
||||
@@ -61,6 +61,11 @@
|
||||
<version>${plugin.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-spigot</artifactId>
|
||||
<version>${api.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.papermc.paper</groupId>
|
||||
<artifactId>paper-api</artifactId>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -27,30 +27,22 @@ package ch.andre601.advancedserverlist.paper;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.ServerCore;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import ch.andre601.advancedserverlist.paper.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.paper.events.JoinEvent;
|
||||
import ch.andre601.advancedserverlist.paper.events.PingEvent;
|
||||
import ch.andre601.advancedserverlist.paper.logging.PaperLogger;
|
||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import ch.andre601.advancedserverlist.paper.objects.PaperPlayerPlaceholders;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.bukkit.util.CachedServerIcon;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PaperCore extends JavaPlugin implements ServerCore<CachedServerIcon, PlayerProfile, OfflinePlayer>{
|
||||
public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon>{
|
||||
|
||||
private final PluginLogger logger = new PaperLogger(getLogger());
|
||||
|
||||
@@ -67,18 +59,7 @@ public class PaperCore extends JavaPlugin implements ServerCore<CachedServerIcon
|
||||
Class.forName("com.destroystokyo.paper.PaperConfig");
|
||||
enable();
|
||||
}catch(ClassNotFoundException ex1){
|
||||
getPluginLogger().warn("======================================== WARNING ========================================");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("You are using the PaperMC version of AdvancedServerList on a SpigotMC server.");
|
||||
getPluginLogger().warn("The PaperMC version is ONLY compatible with PaperMC itself due to it using exclusive");
|
||||
getPluginLogger().warn("methods and events not available within SpigotMC.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("To avoid any exceptions and errors will AdvancedServerList disable itself now.");
|
||||
getPluginLogger().warn("Please stop your server and either switch to PaperMC or use the Spigot version");
|
||||
getPluginLogger().warn("of AdvancedServerList.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("======================================== WARNING ========================================");
|
||||
|
||||
printSpigotWarning();
|
||||
getServer().getPluginManager().disablePlugin(this);
|
||||
}
|
||||
}
|
||||
@@ -161,29 +142,24 @@ public class PaperCore extends JavaPlugin implements ServerCore<CachedServerIcon
|
||||
return "paper";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PlayerProfile> createPlayers(List<String> lines, OfflinePlayer player, Placeholders... placeholders){
|
||||
List<PlayerProfile> players = new ArrayList<>(lines.size());
|
||||
|
||||
for(String line : lines){
|
||||
String parsed = ComponentParser.text(line)
|
||||
.replacements(placeholders[0])
|
||||
.replacements(placeholders[1])
|
||||
.modifyText(text -> {
|
||||
if(getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player, text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.toString();
|
||||
|
||||
players.add(Bukkit.createProfile(UUID.randomUUID(), parsed));
|
||||
}
|
||||
|
||||
return players;
|
||||
private void enable(){
|
||||
this.core = new AdvancedServerList(this, new PaperPlayerPlaceholders());
|
||||
}
|
||||
|
||||
private void enable(){
|
||||
this.core = new AdvancedServerList(this);
|
||||
private void printSpigotWarning(){
|
||||
getPluginLogger().warn("======================================== WARNING ========================================");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("You are using the Paper version of AdvancedServerList on a SpigotMC server.");
|
||||
getPluginLogger().warn("The Paper version is ONLY compatible with Paper itself due to it using exclusive");
|
||||
getPluginLogger().warn("methods and events not available within SpigotMC.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("To avoid any exceptions and errors will AdvancedServerList disable itself now.");
|
||||
getPluginLogger().warn("Please stop your server and either switch to Paper or use the Spigot version");
|
||||
getPluginLogger().warn("of AdvancedServerList.");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("Paper can be downloaded here:");
|
||||
getPluginLogger().warn("https://papermc.io/downloads");
|
||||
getPluginLogger().warn("");
|
||||
getPluginLogger().warn("======================================== WARNING ========================================");
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -26,6 +26,7 @@
|
||||
package ch.andre601.advancedserverlist.paper.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.paper.PaperCore;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
@@ -46,7 +47,8 @@ public class JoinEvent implements Listener{
|
||||
InetSocketAddress address = event.getPlayer().getAddress();
|
||||
if(address == null)
|
||||
return;
|
||||
|
||||
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getName(), address.getHostString());
|
||||
|
||||
Player player = event.getPlayer();
|
||||
plugin.getCore().getPlayerHandler().addPlayer(address.getHostString(), player.getName(), player.getUniqueId());
|
||||
}
|
||||
}
|
||||
+42
-21
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,14 +25,18 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.paper.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.paper.PaperCore;
|
||||
import ch.andre601.advancedserverlist.paper.PaperPlayer;
|
||||
import ch.andre601.advancedserverlist.paper.objects.PaperPlayerImpl;
|
||||
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
|
||||
import com.destroystokyo.paper.profile.PlayerProfile;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.kyori.adventure.text.Component;
|
||||
import org.bukkit.Bukkit;
|
||||
@@ -40,9 +44,11 @@ import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.util.CachedServerIcon;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class PaperEventWrapper implements GenericEventWrapper<OfflinePlayer, CachedServerIcon>{
|
||||
public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon, PaperPlayerImpl>{
|
||||
|
||||
private final PaperCore plugin;
|
||||
private final PaperServerListPingEvent event;
|
||||
@@ -52,6 +58,14 @@ public class PaperEventWrapper implements GenericEventWrapper<OfflinePlayer, Cac
|
||||
this.event = event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericServerListEvent callEvent(ProfileEntry entry){
|
||||
PreServerListSetEventImpl event = new PreServerListSetEventImpl(entry);
|
||||
plugin.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxPlayers(int maxPlayers){
|
||||
event.setMaxPlayers(maxPlayers);
|
||||
@@ -74,12 +88,25 @@ public class PaperEventWrapper implements GenericEventWrapper<OfflinePlayer, Cac
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayers(List<String> players, GenericPlayer<OfflinePlayer> player, PlayerPlaceholders playerPlaceholders, ServerPlaceholders serverPlaceholders){
|
||||
public void setPlayers(List<String> lines, PaperPlayerImpl player, GenericServer server){
|
||||
event.getPlayerSample().clear();
|
||||
List<PlayerProfile> players = new ArrayList<>(lines.size());
|
||||
|
||||
event.getPlayerSample().addAll(
|
||||
plugin.createPlayers(players, player.getPlayer(), playerPlaceholders, serverPlaceholders)
|
||||
);
|
||||
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;
|
||||
})
|
||||
.toString();
|
||||
|
||||
players.add(Bukkit.createProfile(UUID.randomUUID(), parsed));
|
||||
}
|
||||
|
||||
event.getPlayerSample().addAll(players);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -123,7 +150,7 @@ public class PaperEventWrapper implements GenericEventWrapper<OfflinePlayer, Cac
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePAPIPlaceholders(String text, GenericPlayer<OfflinePlayer> player){
|
||||
public String parsePAPIPlaceholders(String text, PaperPlayerImpl player){
|
||||
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
|
||||
|
||||
@@ -141,16 +168,10 @@ public class PaperEventWrapper implements GenericEventWrapper<OfflinePlayer, Cac
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericPlayer<OfflinePlayer> createPlayer(String name, int protocol){
|
||||
OfflinePlayer player = Bukkit.getPlayerExact(name);
|
||||
public PaperPlayerImpl createPlayer(CachedPlayer player, int protocol){
|
||||
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
|
||||
|
||||
if(player == null){
|
||||
player = Bukkit.getOfflinePlayer(name);
|
||||
|
||||
return new PaperPlayer(player.hasPlayedBefore() ? player : null, name, protocol);
|
||||
}
|
||||
|
||||
return new PaperPlayer(player, name, protocol);
|
||||
return new PaperPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.spigot.events.PreServerListSetEvent;
|
||||
|
||||
public class PreServerListSetEventImpl extends PreServerListSetEvent{
|
||||
|
||||
public PreServerListSetEventImpl(ProfileEntry entry){
|
||||
super(entry);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -52,4 +52,9 @@ public class PaperLogger implements PluginLogger{
|
||||
public void warn(String msg, Throwable throwable){
|
||||
logger.log(Level.WARNING, msg, throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable, Object... args){
|
||||
logger.log(Level.WARNING, String.format(msg, args), throwable);
|
||||
}
|
||||
}
|
||||
+34
-7
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,18 +23,26 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper;
|
||||
package ch.andre601.advancedserverlist.paper.objects;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
|
||||
import ch.andre601.advancedserverlist.spigot.objects.SpigotPlayer;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class PaperPlayer extends GenericPlayer<OfflinePlayer>{
|
||||
public class PaperPlayerImpl extends GenericPlayerImpl implements SpigotPlayer{
|
||||
|
||||
public PaperPlayer(OfflinePlayer player, String name, int protocol){
|
||||
private final OfflinePlayer player;
|
||||
private boolean playedBefore = false;
|
||||
private boolean banned = false;
|
||||
private boolean whitelisted = false;
|
||||
|
||||
public PaperPlayerImpl(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
|
||||
this.player = player;
|
||||
|
||||
this.name = player == null ? name : player.getName();
|
||||
this.name = player == null ? cachedPlayer.getName() : player.getName();
|
||||
this.protocol = protocol;
|
||||
this.uuid = player == null ? cachedPlayer.getUuid() : player.getUniqueId();
|
||||
|
||||
if(player == null)
|
||||
return;
|
||||
@@ -42,6 +50,25 @@ public class PaperPlayer extends GenericPlayer<OfflinePlayer>{
|
||||
this.playedBefore = player.hasPlayedBefore();
|
||||
this.banned = player.isBanned();
|
||||
this.whitelisted = player.isWhitelisted();
|
||||
this.uuid = player.getUniqueId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfflinePlayer getPlayer(){
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPlayedBefore(){
|
||||
return playedBefore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBanned(){
|
||||
return banned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWhitelisted(){
|
||||
return whitelisted;
|
||||
}
|
||||
}
|
||||
+57
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.paper.objects;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.spigot.objects.SpigotPlayer;
|
||||
|
||||
public class PaperPlayerPlaceholders extends PlaceholderProvider{
|
||||
|
||||
public PaperPlayerPlaceholders(){
|
||||
super("player");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
|
||||
SpigotPlayer paperPlayer = (SpigotPlayer)player;
|
||||
|
||||
return switch(placeholder){
|
||||
case "name" -> paperPlayer.getName();
|
||||
case "protocol" -> String.valueOf(paperPlayer.getProtocol());
|
||||
case "uuid" -> String.valueOf(paperPlayer.getUUID());
|
||||
case "hasPlayedBefore" -> returnValue(paperPlayer, paperPlayer.hasPlayedBefore());
|
||||
case "isBanned" -> returnValue(paperPlayer, paperPlayer.isBanned());
|
||||
case "isWhitelisted" -> returnValue(paperPlayer, paperPlayer.isWhitelisted());
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private String returnValue(SpigotPlayer player, Object value){
|
||||
return player.getPlayer() == null ? null : String.valueOf(value);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022-2023 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in all
|
||||
~ copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
~ SOFTWARE.
|
||||
~
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
@@ -12,13 +37,22 @@
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
<plugin.version>1.10.1</plugin.version>
|
||||
<plugin.version>2.1.0</plugin.version>
|
||||
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
|
||||
|
||||
<api.version>v2.0.0</api.version>
|
||||
|
||||
<maven.compiler.source>16</maven.compiler.source>
|
||||
<maven.compiler.target>16</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>jitpack</id>
|
||||
<url>https://jitpack.io/</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
|
||||
<modules>
|
||||
<module>core</module>
|
||||
<module>bungeecord</module>
|
||||
@@ -26,5 +60,4 @@
|
||||
<module>spigot</module>
|
||||
<module>velocity</module>
|
||||
</modules>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1 @@
|
||||
mkdocs-material==9.0.6
|
||||
+7
-1
@@ -2,7 +2,7 @@
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022 Andre_601
|
||||
~ Copyright (c) 2022-2023 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -65,6 +65,12 @@
|
||||
<version>${plugin.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-spigot</artifactId>
|
||||
<version>${api.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -27,28 +27,21 @@ package ch.andre601.advancedserverlist.spigot;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.ServerCore;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import ch.andre601.advancedserverlist.spigot.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.spigot.events.LoadEvent;
|
||||
import ch.andre601.advancedserverlist.spigot.logging.SpigotLogger;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import ch.andre601.advancedserverlist.spigot.objects.SpigotPlayerPlaceholders;
|
||||
import com.comphenix.protocol.wrappers.WrappedServerPing;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import org.bstats.bukkit.Metrics;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.PluginCommand;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class SpigotCore extends JavaPlugin implements ServerCore<WrappedServerPing.CompressedImage, WrappedGameProfile, OfflinePlayer>{
|
||||
public class SpigotCore extends JavaPlugin implements PluginCore<WrappedServerPing.CompressedImage>{
|
||||
|
||||
private final PluginLogger logger = new SpigotLogger(getLogger());
|
||||
|
||||
@@ -70,7 +63,7 @@ public class SpigotCore extends JavaPlugin implements ServerCore<WrappedServerPi
|
||||
}catch(ClassNotFoundException ignored){}
|
||||
}
|
||||
|
||||
this.core = new AdvancedServerList(this);
|
||||
this.core = new AdvancedServerList(this, new SpigotPlayerPlaceholders());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -146,28 +139,6 @@ public class SpigotCore extends JavaPlugin implements ServerCore<WrappedServerPi
|
||||
return "spigot";
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<WrappedGameProfile> createPlayers(List<String> lines, OfflinePlayer player, Placeholders... placeholders){
|
||||
List<WrappedGameProfile> players = new ArrayList<>(lines.size());
|
||||
|
||||
for(String line : lines){
|
||||
String parsed = ComponentParser.text(line)
|
||||
.replacements(placeholders[0])
|
||||
.replacements(placeholders[1])
|
||||
.modifyText(text -> {
|
||||
if(getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player, text);
|
||||
|
||||
return text;
|
||||
})
|
||||
.toString();
|
||||
|
||||
players.add(new WrappedGameProfile(UUID.randomUUID(), parsed));
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
|
||||
private void printPaperInfo(){
|
||||
getPluginLogger().warn("======================================================================================");
|
||||
getPluginLogger().warn("You are using the Spigot version of AdvancedServerList on a Paper server.");
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -26,6 +26,7 @@
|
||||
package ch.andre601.advancedserverlist.spigot.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotCore;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.player.PlayerJoinEvent;
|
||||
@@ -45,7 +46,8 @@ public class JoinEvent implements Listener{
|
||||
InetSocketAddress address = event.getPlayer().getAddress();
|
||||
if(address == null)
|
||||
return;
|
||||
|
||||
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getName(), address.getHostString());
|
||||
|
||||
Player player = event.getPlayer();
|
||||
plugin.getCore().getPlayerHandler().addPlayer(address.getHostString(), player.getName(), player.getUniqueId());
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+7
-5
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,11 +23,13 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.profiles.replacer.placeholders;
|
||||
package ch.andre601.advancedserverlist.spigot.events;
|
||||
|
||||
import java.util.Map;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
|
||||
public interface Placeholders{
|
||||
public class PreServerListSetEventImpl extends PreServerListSetEvent{
|
||||
|
||||
Map<String, Object> getReplacements();
|
||||
public PreServerListSetEventImpl(ProfileEntry entry){
|
||||
super(entry);
|
||||
}
|
||||
}
|
||||
+43
-22
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,15 +25,19 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotCore;
|
||||
import ch.andre601.advancedserverlist.spigot.SpigotPlayer;
|
||||
import ch.andre601.advancedserverlist.spigot.objects.SpigotPlayerImpl;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.wrappers.AdventureComponentConverter;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.comphenix.protocol.wrappers.WrappedServerPing;
|
||||
import me.clip.placeholderapi.PlaceholderAPI;
|
||||
import net.kyori.adventure.text.Component;
|
||||
@@ -41,10 +45,12 @@ import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ProtocolLibEventWrapper implements GenericEventWrapper<OfflinePlayer, WrappedServerPing.CompressedImage>{
|
||||
public class ProtocolLibEventWrapper implements GenericEventWrapper<WrappedServerPing.CompressedImage, SpigotPlayerImpl>{
|
||||
|
||||
private final SpigotCore plugin;
|
||||
private final PacketEvent event;
|
||||
@@ -60,6 +66,14 @@ public class ProtocolLibEventWrapper implements GenericEventWrapper<OfflinePlaye
|
||||
this.hostAddresses = hostAddresses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericServerListEvent callEvent(ProfileEntry entry){
|
||||
PreServerListSetEventImpl event = new PreServerListSetEventImpl(entry);
|
||||
plugin.getServer().getPluginManager().callEvent(event);
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxPlayers(int maxPlayers){
|
||||
ping.setPlayersMaximum(maxPlayers);
|
||||
@@ -82,10 +96,24 @@ public class ProtocolLibEventWrapper implements GenericEventWrapper<OfflinePlaye
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayers(List<String> players, GenericPlayer<OfflinePlayer> player, PlayerPlaceholders playerPlaceholders, ServerPlaceholders serverPlaceholders){
|
||||
ping.setPlayers(
|
||||
plugin.createPlayers(players, player.getPlayer(), playerPlaceholders, serverPlaceholders)
|
||||
);
|
||||
public void setPlayers(List<String> lines, SpigotPlayerImpl player, GenericServer server){
|
||||
List<WrappedGameProfile> players = new ArrayList<>(lines.size());
|
||||
|
||||
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;
|
||||
})
|
||||
.toString();
|
||||
|
||||
players.add(new WrappedGameProfile(UUID.randomUUID(), parsed));
|
||||
}
|
||||
|
||||
ping.setPlayers(players);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,7 +156,7 @@ public class ProtocolLibEventWrapper implements GenericEventWrapper<OfflinePlaye
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePAPIPlaceholders(String text, GenericPlayer<OfflinePlayer> player){
|
||||
public String parsePAPIPlaceholders(String text, SpigotPlayerImpl player){
|
||||
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
|
||||
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
|
||||
|
||||
@@ -150,17 +178,10 @@ public class ProtocolLibEventWrapper implements GenericEventWrapper<OfflinePlaye
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericPlayer<OfflinePlayer> createPlayer(String name, int protocol){
|
||||
OfflinePlayer player = Bukkit.getPlayerExact(name);
|
||||
public SpigotPlayerImpl createPlayer(CachedPlayer player, int protocol){
|
||||
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
|
||||
|
||||
if(player == null){
|
||||
//noinspection deprecation
|
||||
player = Bukkit.getOfflinePlayer(name);
|
||||
|
||||
return new SpigotPlayer(player.hasPlayedBefore() ? player : null, name, protocol);
|
||||
}
|
||||
|
||||
return new SpigotPlayer(player, name, protocol);
|
||||
return new SpigotPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -52,4 +52,9 @@ public class SpigotLogger implements PluginLogger{
|
||||
public void warn(String msg, Throwable throwable){
|
||||
logger.log(Level.WARNING, msg, throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable, Object... args){
|
||||
logger.log(Level.WARNING, String.format(msg, args), throwable);
|
||||
}
|
||||
}
|
||||
+37
-10
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,25 +23,52 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot;
|
||||
package ch.andre601.advancedserverlist.spigot.objects;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
public class SpigotPlayer extends GenericPlayer<OfflinePlayer>{
|
||||
public class SpigotPlayerImpl extends GenericPlayerImpl implements SpigotPlayer{
|
||||
|
||||
public SpigotPlayer(OfflinePlayer player, String name, int protocol){
|
||||
private final OfflinePlayer player;
|
||||
private boolean playedBefore = false;
|
||||
private boolean banned = false;
|
||||
private boolean whitelisted = false;
|
||||
|
||||
public SpigotPlayerImpl(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
|
||||
this.player = player;
|
||||
|
||||
this.name = player == null ? name : player.getName();
|
||||
|
||||
this.name = player == null ? cachedPlayer.getName() : player.getName();
|
||||
this.protocol = protocol;
|
||||
|
||||
|
||||
this.uuid = player == null ? cachedPlayer.getUuid() : player.getUniqueId();
|
||||
|
||||
if(player == null)
|
||||
return;
|
||||
|
||||
|
||||
this.playedBefore = player.hasPlayedBefore();
|
||||
this.banned = player.isBanned();
|
||||
this.whitelisted = player.isWhitelisted();
|
||||
this.uuid = player.getUniqueId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public OfflinePlayer getPlayer(){
|
||||
return player;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPlayedBefore(){
|
||||
return playedBefore;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isBanned(){
|
||||
return banned;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isWhitelisted(){
|
||||
return whitelisted;
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.spigot.objects;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
|
||||
public class SpigotPlayerPlaceholders extends PlaceholderProvider{
|
||||
|
||||
public SpigotPlayerPlaceholders(){
|
||||
super("player");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
|
||||
SpigotPlayer spigotPlayer = (SpigotPlayer)player;
|
||||
|
||||
return switch(placeholder){
|
||||
case "name" -> spigotPlayer.getName();
|
||||
case "protocol" -> String.valueOf(spigotPlayer.getProtocol());
|
||||
case "uuid" -> String.valueOf(spigotPlayer.getUUID());
|
||||
case "hasPlayedBefore" -> returnValue(spigotPlayer, spigotPlayer.hasPlayedBefore());
|
||||
case "isBanned" -> returnValue(spigotPlayer, spigotPlayer.isBanned());
|
||||
case "isWhitelisted" -> returnValue(spigotPlayer, spigotPlayer.isWhitelisted());
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
|
||||
private String returnValue(SpigotPlayer player, Object value){
|
||||
return player.getPlayer() == null ? null : String.valueOf(value);
|
||||
}
|
||||
}
|
||||
+7
-1
@@ -2,7 +2,7 @@
|
||||
<!--
|
||||
~ MIT License
|
||||
~
|
||||
~ Copyright (c) 2022 Andre_601
|
||||
~ Copyright (c) 2022-2023 Andre_601
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -57,6 +57,12 @@
|
||||
<version>${plugin.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>ch.andre601.asl-api</groupId>
|
||||
<artifactId>platform-velocity</artifactId>
|
||||
<version>${api.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.velocitypowered</groupId>
|
||||
<artifactId>velocity-api</artifactId>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -27,14 +27,13 @@ package ch.andre601.advancedserverlist.velocity;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.AdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.ProxyCore;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import ch.andre601.advancedserverlist.velocity.commands.CmdAdvancedServerList;
|
||||
import ch.andre601.advancedserverlist.velocity.events.JoinEvent;
|
||||
import ch.andre601.advancedserverlist.velocity.events.PingEvent;
|
||||
import ch.andre601.advancedserverlist.velocity.logging.VelocityLogger;
|
||||
import ch.andre601.advancedserverlist.velocity.objects.VelocityPlayerPlaceholders;
|
||||
import com.google.inject.Inject;
|
||||
import com.velocitypowered.api.command.CommandMeta;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
@@ -42,18 +41,14 @@ import com.velocitypowered.api.event.proxy.ProxyInitializeEvent;
|
||||
import com.velocitypowered.api.event.proxy.ProxyShutdownEvent;
|
||||
import com.velocitypowered.api.plugin.annotation.DataDirectory;
|
||||
import com.velocitypowered.api.proxy.ProxyServer;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.api.util.Favicon;
|
||||
import org.bstats.charts.SimplePie;
|
||||
import org.bstats.velocity.Metrics;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
public class VelocityCore implements ProxyCore<Favicon, ServerPing.SamplePlayer>{
|
||||
public class VelocityCore implements PluginCore<Favicon>{
|
||||
|
||||
private final PluginLogger logger;
|
||||
private final ProxyServer proxy;
|
||||
@@ -74,7 +69,7 @@ public class VelocityCore implements ProxyCore<Favicon, ServerPing.SamplePlayer>
|
||||
|
||||
@Subscribe
|
||||
public void init(ProxyInitializeEvent event){
|
||||
this.core = new AdvancedServerList(this);
|
||||
this.core = new AdvancedServerList(this, new VelocityPlayerPlaceholders());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
@@ -136,22 +131,6 @@ public class VelocityCore implements ProxyCore<Favicon, ServerPing.SamplePlayer>
|
||||
return faviconHandler;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServerPing.SamplePlayer> createPlayers(List<String> lines, Placeholders... placeholders){
|
||||
List<ServerPing.SamplePlayer> players = new ArrayList<>(lines.size());
|
||||
|
||||
for(String line : lines){
|
||||
String parsed = ComponentParser.text(line)
|
||||
.replacements(placeholders[0])
|
||||
.replacements(placeholders[1])
|
||||
.toString();
|
||||
|
||||
players.add(new ServerPing.SamplePlayer(parsed, UUID.randomUUID()));
|
||||
}
|
||||
|
||||
return players;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPlatformName(){
|
||||
return getProxy().getVersion().getName();
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+5
-2
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -28,6 +28,7 @@ package ch.andre601.advancedserverlist.velocity.events;
|
||||
import ch.andre601.advancedserverlist.velocity.VelocityCore;
|
||||
import com.velocitypowered.api.event.Subscribe;
|
||||
import com.velocitypowered.api.event.connection.PostLoginEvent;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
@@ -43,6 +44,8 @@ public class JoinEvent{
|
||||
@Subscribe
|
||||
public void onJoin(PostLoginEvent event){
|
||||
InetSocketAddress address = event.getPlayer().getRemoteAddress();
|
||||
plugin.getCore().getPlayerHandler().addPlayer(event.getPlayer().getUsername(), address.getHostString());
|
||||
Player player = event.getPlayer();
|
||||
|
||||
plugin.getCore().getPlayerHandler().addPlayer(address.getHostString(), player.getUsername(), player.getUniqueId());
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
+7
-7
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,12 +23,12 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.core.interfaces.core;
|
||||
package ch.andre601.advancedserverlist.velocity.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ServerCore<F, P, P2> extends PluginCore<F>{
|
||||
List<P> createPlayers(List<String> lines, P2 player, Placeholders... placeholders);
|
||||
public class PreServerListSetEventImpl extends PreServerListSetEvent{
|
||||
public PreServerListSetEventImpl(ProfileEntry entry){
|
||||
super(entry);
|
||||
}
|
||||
}
|
||||
+38
-15
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -25,23 +25,27 @@
|
||||
|
||||
package ch.andre601.advancedserverlist.velocity.events;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.events.GenericServerListEvent;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
|
||||
import ch.andre601.advancedserverlist.core.interfaces.events.GenericEventWrapper;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.PlayerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.ServerPlaceholders;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
|
||||
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
|
||||
import ch.andre601.advancedserverlist.velocity.VelocityCore;
|
||||
import ch.andre601.advancedserverlist.velocity.VelocityPlayer;
|
||||
import ch.andre601.advancedserverlist.velocity.objects.VelocityPlayerImpl;
|
||||
import com.velocitypowered.api.event.proxy.ProxyPingEvent;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
import com.velocitypowered.api.proxy.server.ServerPing;
|
||||
import com.velocitypowered.api.util.Favicon;
|
||||
import net.kyori.adventure.text.Component;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
public class VelocityEventWrapper implements GenericEventWrapper<Player, Favicon>{
|
||||
public class VelocityEventWrapper implements GenericEventWrapper<Favicon, VelocityPlayerImpl>{
|
||||
|
||||
private final VelocityCore plugin;
|
||||
private final ProxyPingEvent event;
|
||||
@@ -55,6 +59,18 @@ public class VelocityEventWrapper implements GenericEventWrapper<Player, Favicon
|
||||
this.protocol = event.getPing().getVersion();
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericServerListEvent callEvent(ProfileEntry entry){
|
||||
PreServerListSetEventImpl event = new PreServerListSetEventImpl(entry);
|
||||
try{
|
||||
plugin.getProxy().getEventManager().fire(event).get();
|
||||
}catch(InterruptedException | ExecutionException ignored){
|
||||
return null;
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxPlayers(int maxPlayers){
|
||||
builder.maximumPlayers(maxPlayers);
|
||||
@@ -76,12 +92,19 @@ public class VelocityEventWrapper implements GenericEventWrapper<Player, Favicon
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setPlayers(List<String> players, GenericPlayer<Player> player, PlayerPlaceholders playerPlaceholders, ServerPlaceholders serverPlaceholders){
|
||||
ServerPing.SamplePlayer[] playerSamples = plugin.createPlayers(players, playerPlaceholders, serverPlaceholders)
|
||||
.toArray(new ServerPing.SamplePlayer[0]);
|
||||
public void setPlayers(List<String> lines, VelocityPlayerImpl player, GenericServer server){
|
||||
ServerPing.SamplePlayer[] players = new ServerPing.SamplePlayer[lines.size()];
|
||||
|
||||
if(playerSamples.length > 0)
|
||||
builder.clearSamplePlayers().samplePlayers(playerSamples);
|
||||
for(int i = 0; i < players.length; i++){
|
||||
String parsed = ComponentParser.text(lines.get(i))
|
||||
.modifyText(text -> StringReplacer.replace(text, player, server))
|
||||
.toString();
|
||||
|
||||
players[i] = new ServerPing.SamplePlayer(parsed, UUID.randomUUID());
|
||||
}
|
||||
|
||||
if(players.length > 0)
|
||||
builder.clearSamplePlayers().samplePlayers(players);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -124,7 +147,7 @@ public class VelocityEventWrapper implements GenericEventWrapper<Player, Favicon
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePAPIPlaceholders(String text, GenericPlayer<Player> player){
|
||||
public String parsePAPIPlaceholders(String text, VelocityPlayerImpl player){
|
||||
return text;
|
||||
}
|
||||
|
||||
@@ -139,8 +162,8 @@ public class VelocityEventWrapper implements GenericEventWrapper<Player, Favicon
|
||||
}
|
||||
|
||||
@Override
|
||||
public GenericPlayer<Player> createPlayer(String name, int protocol){
|
||||
return new VelocityPlayer(name, protocol);
|
||||
public VelocityPlayerImpl createPlayer(CachedPlayer player, int protocol){
|
||||
return new VelocityPlayerImpl(player, protocol);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
+6
-1
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -50,4 +50,9 @@ public class VelocityLogger implements PluginLogger{
|
||||
public void warn(String msg, Throwable throwable){
|
||||
logger.warn(msg, throwable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warn(String msg, Throwable throwable, Object... args){
|
||||
logger.warn(String.format(msg, args), throwable);
|
||||
}
|
||||
}
|
||||
+15
-7
@@ -1,7 +1,7 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022 Andre_601
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -23,17 +23,25 @@
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.velocity;
|
||||
package ch.andre601.advancedserverlist.velocity.objects;
|
||||
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
|
||||
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
|
||||
import com.velocitypowered.api.network.ProtocolVersion;
|
||||
import com.velocitypowered.api.proxy.Player;
|
||||
|
||||
public class VelocityPlayer extends GenericPlayer<Player>{
|
||||
public class VelocityPlayerImpl extends GenericPlayerImpl implements VelocityPlayer{
|
||||
|
||||
public VelocityPlayer(String name, int protocol){
|
||||
this.name = name;
|
||||
private final String version;
|
||||
|
||||
public VelocityPlayerImpl(CachedPlayer player, int protocol){
|
||||
this.name = player.getName();
|
||||
this.protocol = protocol;
|
||||
this.uuid = player.getUuid();
|
||||
this.version = ProtocolVersion.getProtocolVersion(protocol).getVersionIntroducedIn();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion(){
|
||||
return version;
|
||||
}
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* MIT License
|
||||
*
|
||||
* Copyright (c) 2022-2023 Andre_601
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
package ch.andre601.advancedserverlist.velocity.objects;
|
||||
|
||||
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
|
||||
import ch.andre601.advancedserverlist.api.objects.GenericServer;
|
||||
|
||||
public class VelocityPlayerPlaceholders extends PlaceholderProvider{
|
||||
|
||||
public VelocityPlayerPlaceholders(){
|
||||
super("player");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
|
||||
return switch(placeholder){
|
||||
case "name" -> player.getName();
|
||||
case "protocol" -> String.valueOf(player.getProtocol());
|
||||
case "uuid" -> String.valueOf(player.getUUID());
|
||||
case "version" -> ((VelocityPlayerImpl)player).getVersion();
|
||||
default -> null;
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user