Merge pull request 'Remove Spigot support' (#183) from feature/remove-spigot-support into master

Reviewed-on: https://codeberg.org/Andre601/AdvancedServerList/pulls/183
This commit is contained in:
Andre601 committed 2023-12-02 12:42:30 +00:00
commit a0ee2a4322
31 files changed
+228 -858

No files matched your search

+1 -3
View File
@@ -8,8 +8,6 @@ steps:
secrets:
- source: cb_token
target: codeberg_api_token
- source: gh_token
target: github_api_token
- source: modrinth_api_token
target: modrinth_api_token
- source: hangar_api_token
@@ -28,8 +26,8 @@ steps:
settings:
base_url: https://codeberg.org
files:
- "bukkit/target/AdvancedServerList-*.jar"
- "bungeecord/target/AdvancedServerList-*.jar"
- "paper/target/AdvancedServerList-*.jar"
- "velocity/target/AdvancedServerList-*.jar"
api_key:
from_secret: CB_TOKEN
+8 -11
View File
@@ -16,9 +16,6 @@ AdvancedServerList is a plugin that allowys you to customize your server's MOTD,
## Supported Platforms
<a href="https://www.spigotmc.org" target="_blank">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/spigot_vector.svg" height="64" alt="platform-spigot" title="Tested on Spigot">
</a>
<a href="https://papermc.io" target="_blank">
<img src="https://cdn.jsdelivr.net/gh/Andre601/devins-badges@13e0142/assets/compact-minimal/supported/paper_vector.svg" height="64" alt="platform-paper" title="Tested on Paper">
</a>
@@ -63,13 +60,14 @@ Only certain options are usable for each option. As an example does motd support
## Dependencies
| Dependency | Platforms | Required? |
|-------------------|----------------------|-----------|
| [ProtocolLib] | Spigot | Yes |
| [PlaceholderAPI] | Spigot, Paper | No |
| [ViaVersion] | Spigot, Paper | No |
| [PAPIProxyBridge] | BungeeCord, Velocity | No |
| [Maintenance] | All | No |
All listed dependencies are optional.
| Dependency | Platforms |
|-------------------|----------------------|
| [PlaceholderAPI] | Paper |
| [ViaVersion] | Paper |
| [PAPIProxyBridge] | BungeeCord, Velocity |
| [Maintenance] | All |
## Statistics
@@ -106,7 +104,6 @@ You can disable this in the global bStats config file located in `/plugins/bstat
[modrinth]: https://modrinth.com/plugin/advancedserverlist
[protocollib]: https://hangar.papermc.io/dmulloy2/ProtocolLib
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
[papiproxybridge]: https://hangar.papermc.io/William278/PAPIProxyBridge
@@ -1,75 +0,0 @@
/*
* 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.bukkit.commands;
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.paper.commands.PaperCmdSender;
import ch.andre601.advancedserverlist.spigot.commands.SpigotCmdSender;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.Collections;
public class CmdAdvancedServerList extends Command implements CommandExecutor{
private final PluginCore<?> plugin;
private final BukkitAudiences audiences;
public CmdAdvancedServerList(PluginCore<?> plugin){
this(plugin, null);
}
public CmdAdvancedServerList(PluginCore<?> plugin, BukkitAudiences audiences){
super(
"advancedserverlist",
"Main command of the plugin",
"/asl [reload|help|clearCache]",
Collections.singletonList("asl")
);
this.plugin = plugin;
this.audiences = audiences;
}
public boolean execute(@NotNull CommandSender sender, @NotNull String s, @NotNull String[] args){
plugin.getCore().getCommandHandler().handle(getSender(sender), args);
return true;
}
@Override
public boolean onCommand(@NotNull CommandSender sender, @NotNull Command cmd, @NotNull String label, @NotNull String[] args){
plugin.getCore().getCommandHandler().handle(getSender(sender), args);
return true;
}
private CmdSender getSender(CommandSender sender){
return audiences == null ? new PaperCmdSender(sender) : new SpigotCmdSender(sender, audiences);
}
}
@@ -1,74 +0,0 @@
/*
* 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.bukkit.listeners;
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.PAPIPlaceholders;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.spigot.listeners.ProtocolLibEvents;
import com.comphenix.protocol.ProtocolLibrary;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerLoadEvent;
public class LoadEvent implements Listener{
private final BukkitCore<?> plugin;
private LoadEvent(BukkitCore<?> plugin){
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public static void init(BukkitCore<?> plugin){
new LoadEvent(plugin);
}
@EventHandler
public void onServerLoad(ServerLoadEvent event){
JoinEvent.init(plugin);
WorldEvents.init(plugin);
// Populate WorldCache with all loaded worlds
Bukkit.getWorlds().forEach(world -> plugin.getWorldCache().addWorld(world.getName(), world));
if(!(plugin instanceof SpigotCore spigotCore))
return;
if(!Bukkit.getPluginManager().isPluginEnabled("ProtocolLib")){
plugin.getCore().getPlugin().getPluginLogger().warn("ProtocolLib not found! AdvancedServerList requires it to work on Spigot!");
Bukkit.getPluginManager().disablePlugin(plugin);
return;
}
ProtocolLibEvents.init(spigotCore, ProtocolLibrary.getProtocolManager());
if(Bukkit.getPluginManager().isPluginEnabled("PlaceholderAPI"))
spigotCore.setPapiPlaceholders(PAPIPlaceholders.init(spigotCore));
}
}
@@ -1,178 +0,0 @@
/*
* 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;
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.bukkit.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.bukkit.logging.BukkitLogger;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.BukkitPlayerPlaceholders;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.BukkitServerPlaceholders;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.PAPIPlaceholders;
import ch.andre601.advancedserverlist.bukkit.objects.WorldCache;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.bukkit.listeners.LoadEvent;
import com.comphenix.protocol.wrappers.WrappedServerPing;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bukkit.command.PluginCommand;
import java.nio.file.Path;
public class SpigotCore extends BukkitCore<WrappedServerPing.CompressedImage>{
private final PluginLogger logger = new BukkitLogger(getLogger());
private AdvancedServerList<WrappedServerPing.CompressedImage> core;
private FaviconHandler<WrappedServerPing.CompressedImage> faviconHandler = null;
private PAPIPlaceholders<WrappedServerPing.CompressedImage> papiPlaceholders = null;
private WorldCache worldCache = null;
@Override
public void onEnable(){
try{
Class.forName("io.papermc.paper.configuration.ConfigurationLoaders");
printPaperInfo();
}catch(ClassNotFoundException ex){
try{
// Above class only exists since 1.19+, so this is a fallback for older versions.
Class.forName("com.destroystokyo.paper.PaperConfig");
printPaperInfo();
}catch(ClassNotFoundException ignored){}
}
this.core = AdvancedServerList.init(this, BukkitPlayerPlaceholders.init(), BukkitServerPlaceholders.init());
}
@Override
public void onDisable(){
if(papiPlaceholders != null){
papiPlaceholders.unregister();
papiPlaceholders = null;
}
if(worldCache != null)
worldCache = null;
getCore().disable();
}
@Override
public void loadCommands(){
PluginCommand cmd = getServer().getPluginCommand("advancedserverlist");
if(cmd == null){
getPluginLogger().warn("Unable to register command /advancedserverlist");
return;
}
cmd.setExecutor(new CmdAdvancedServerList(this, BukkitAudiences.create(this)));
}
@Override
public void loadEvents(){
LoadEvent.init(this);
}
@Override
public void loadMetrics(){
new Metrics(this, 15584).addCustomChart(new SimplePie("profiles",
() -> String.valueOf(core.getFileHandler().getProfiles().size())
));
}
@Override
public void clearFaviconCache(){
if(faviconHandler == null)
return;
faviconHandler.clearCache();
}
@Override
public AdvancedServerList<WrappedServerPing.CompressedImage> getCore(){
return core;
}
@Override
public Path getFolderPath(){
return getDataFolder().toPath();
}
@Override
public PluginLogger getPluginLogger(){
return logger;
}
@Override
public FaviconHandler<WrappedServerPing.CompressedImage> getFaviconHandler(){
if(faviconHandler == null)
faviconHandler = new FaviconHandler<>(core);
return faviconHandler;
}
@Override
public String getPlatformName(){
return getServer().getName();
}
@Override
public String getPlatformVersion(){
return getServer().getVersion();
}
@Override
public String getLoader(){
return "spigot";
}
@Override
public WorldCache getWorldCache(){
if(worldCache != null)
return worldCache;
return (worldCache = new WorldCache());
}
public void setPapiPlaceholders(PAPIPlaceholders<WrappedServerPing.CompressedImage> papiPlaceholders){
this.papiPlaceholders = papiPlaceholders;
}
private void printPaperInfo(){
getPluginLogger().warn("======================================================================================");
getPluginLogger().warn("You are using the Spigot version of AdvancedServerList on a Paper server.");
getPluginLogger().warn("It is recommended to use the dedicated Paper version, to benefit from the");
getPluginLogger().warn("following improvements:");
getPluginLogger().warn(" - No downloading of external Libraries already provided by Paper (i.e. Adventure).");
getPluginLogger().warn(" - No dependency on ProtocolLib thanks to provided Events.");
getPluginLogger().warn("");
getPluginLogger().warn("AdvancedServerList may work as normal, but consider using the PaperMC version instead!");
getPluginLogger().warn("======================================================================================");
}
}
@@ -1,203 +0,0 @@
/*
* 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.listeners;
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.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.bukkit.listeners.PreServerListSetEventImpl;
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitServerImpl;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
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.bukkit.objects.impl.BukkitPlayerImpl;
import com.comphenix.protocol.events.PacketEvent;
import com.comphenix.protocol.wrappers.WrappedChatComponent;
import com.comphenix.protocol.wrappers.WrappedGameProfile;
import com.comphenix.protocol.wrappers.WrappedServerPing;
import me.clip.placeholderapi.PlaceholderAPI;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.gson.GsonComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import java.awt.image.BufferedImage;
import java.util.*;
public class ProtocolLibEventWrapper implements GenericEventWrapper<WrappedServerPing.CompressedImage, BukkitPlayerImpl>{
private final SpigotCore plugin;
private final PacketEvent event;
private final WrappedServerPing ping;
public ProtocolLibEventWrapper(SpigotCore plugin, PacketEvent event){
this.plugin = plugin;
this.event = event;
this.ping = event.getPacket().getServerPings().read(0);
}
@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);
}
@Override
public void setMotd(Component component){
ping.setMotD(WrappedChatComponent.fromJson(GsonComponentSerializer.gson().serialize(component)));
}
@Override
public void hidePlayers(){
ping.setPlayersVisible(false);
}
@Override
public void setPlayerCount(String name){
ping.setVersionName(name);
ping.setVersionProtocol(-1);
}
@Override
public void setPlayers(List<String> lines, BukkitPlayerImpl 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
public void setFavicon(WrappedServerPing.CompressedImage favicon){
ping.setFavicon(favicon);
}
@Override
public void setDefaultFavicon(){
ping.setFavicon(ping.getFavicon());
}
// Not used in ProtocolLib
@Override
public void updateEvent(){
event.getPacket().getServerPings().write(0, ping);
}
@Override
public boolean isInvalidProtocol(){
return event.getPlayer().getAddress() == null;
}
@Override
public boolean isMaintenanceModeActive(){
if(!Bukkit.getPluginManager().isPluginEnabled("Maintenance"))
return false;
return PingEventHandler.getMaintenanceUtil().isMaintenanceEnabled();
}
@Override
public int getProtocolVersion(){
return ping.getVersionProtocol();
}
@Override
public int getOnlinePlayers(){
return ping.getPlayersOnline();
}
@Override
public int getMaxPlayers(){
return ping.getPlayersMaximum();
}
@Override
public String getPlayerIP(){
return event.getPlayer().getAddress() == null ? "UNKNOWN" : event.getPlayer().getAddress().getHostString();
}
@Override
public String parsePAPIPlaceholders(String text, BukkitPlayerImpl player){
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
return text;
}
@Override
public String getVirtualHost(){
String host = this.resolveHost(event.getPlayer().getAddress());
if(host == null)
return null;
return ProtocolLibEvents.getHostAddresses().get(host);
}
@Override
public BukkitCore<WrappedServerPing.CompressedImage> getPlugin(){
return plugin;
}
@Override
public BukkitPlayerImpl createPlayer(CachedPlayer player, int protocol){
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
return new BukkitPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
}
@Override
public GenericServer createGenericServer(int playersOnline, int playersMax, String host){
return new BukkitServerImpl(plugin.getWorldCache().worlds(), playersOnline, playersMax, host);
}
@Override
public WrappedServerPing.CompressedImage createFavicon(BufferedImage image) throws Exception{
return WrappedServerPing.CompressedImage.fromPng(image);
}
}
@@ -1,84 +0,0 @@
/*
* 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.listeners;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import com.comphenix.protocol.PacketType;
import com.comphenix.protocol.ProtocolManager;
import com.comphenix.protocol.events.ListenerPriority;
import com.comphenix.protocol.events.PacketAdapter;
import com.comphenix.protocol.events.PacketEvent;
import org.bukkit.Bukkit;
import org.bukkit.event.Listener;
import java.net.InetSocketAddress;
import java.util.Map;
import java.util.TreeMap;
public class ProtocolLibEvents implements Listener{
private final ProtocolManager protocolManager;
private static final Map<String, String> hostAddresses = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
private ProtocolLibEvents(SpigotCore plugin, ProtocolManager protocolManager){
this.protocolManager = protocolManager;
loadPacketListener(plugin);
Bukkit.getPluginManager().registerEvents(this, plugin);
}
public static void init(SpigotCore plugin, ProtocolManager protocolManager){
new ProtocolLibEvents(plugin, protocolManager);
}
public static Map<String, String> getHostAddresses(){
return hostAddresses;
}
private void loadPacketListener(SpigotCore spigotPlugin){
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Handshake.Client.SET_PROTOCOL){
@Override
public void onPacketReceiving(PacketEvent event){
InetSocketAddress address = event.getPlayer().getAddress();
if(address == null)
return;
String host = event.getPacket().getStrings().read(0);
hostAddresses.put(address.getHostString(), host);
}
});
protocolManager.addPacketListener(new PacketAdapter(spigotPlugin, ListenerPriority.LOW, PacketType.Status.Server.SERVER_INFO){
@Override
public void onPacketSending(PacketEvent event){
PingEventHandler.handleEvent(new ProtocolLibEventWrapper(spigotPlugin, event));
}
});
}
}
+13 -15
View File
@@ -5,7 +5,7 @@ icon: octicons/milestone-24
# Getting Started
This page will explain how to set up AdvancedServerList and make it work for your server.
It tries to be a easy to understand as possible. But if you still have problems, consider joining the [Discord Server](https://discord.gg/6dazXp6) for help.
It tries to be an easy to understand as possible. But if you still have problems, consider joining the [Discord Server](https://discord.gg/6dazXp6) for help.
## 1. Download the plugin { #download-the-plugin }
@@ -29,15 +29,13 @@ The plugin is available for Spigot, Paper, BungeeCord, Waterfall and Velocity, a
The plugin also supports these additional plugins. Depending on the platform they are used in is the plugin required.
- [ProtocolLib] - Only used and required on Spigot due to missing API features.
- [PlaceholderAPI] - Used on the Spigot and Paper server for additional Placeholder parsing. Optional.
- [ViaVersion] - Used on the Spigot and Paper server for additional protocol version handling. Optional.
- [PAPIProxyBridge] - Used on BungeeCord, Waterfall and Velocity for PlaceholderAPI support. Optional.
- [Maintenance] - Used to disable server list handling while maintenance is active. Optional.
- [PlaceholderAPI] - Used on the Spigot and Paper server for additional Placeholder parsing.
- - [ViaVersion] - Used on the Spigot and Paper server for additional protocol version handling.
- [PAPIProxyBridge] - Used on BungeeCord, Waterfall and Velocity for PlaceholderAPI support.
- [Maintenance] - Used to disable server list handling while maintenance is active.
[protocollib]: https://www.spigotmc.org/resources/1997/
[placeholderapi]: https://www.spigotmc.org/resources/6245/
[viaversion]: https://www.spigotmc.org/resources/19254/
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
[papiproxybridge]: https://hangar.papermc.io/William278/PAPIProxyBridge
[maintenance]: https://hangar.papermc.io/kennytv/Maintenance
@@ -48,7 +46,7 @@ Here is a quick table showing the jar file name with the platforms it is made fo
| Jar file name | Platforms |
|-----------------------------------------------|-----------------------|
| `AdvancedServerList-Bukkit-{version}.jar` | Spigot, Paper |
| `AdvancedServerList-Paper-{version}.jar` | Spigot, Paper |
| `AdvancedServerList-BungeeCord-{version}.jar` | BungeeCord, Waterfall |
| `AdvancedServerList-Velocity-{version}.jar` | Velocity |
@@ -251,16 +249,16 @@ playerCount:
#### Config.yml
The config.yml file contains settinsg related to the plugin itself and some of its functionality.
The config.yml file contains settings related to the plugin itself and some of its functionality.
These functions include, but aren't limited to:
- Setting the default name and UUID used for an unknown (Not cached) player.
- Disabling/Enabling caching of players.
- Disabling/Enabling checking for updates
- The config version used for migration. Don't touch this or it may reset your config.
- The config version used for migration. Don't touch this, or it may reset your config.
Similar to the default.yml is this file containing comments to try and explain the settings in questions.
Do note that if the config gets migrated from an older version, that the comments will be discarded in the process unfortunately.
Do note that if the config gets migrated from an older version, that the comments will be discarded in the process, unfortunately.
/// details | default config.yml content
```yaml
@@ -321,7 +319,7 @@ There are certain files and folders that get created when certain events happen:
Creating your first profile is relatively simple.
To start, open the `default.yml` file located inside the `profiles` folder using a file editor of your choice (VSCode or Notepad++ are recommendet). It should contain all the available options for a server list profile.
To start, open the `default.yml` file located inside the `profiles` folder using a file editor of your choice (VSCode or Notepad++ are recommended). It should contain all the available options for a server list profile.
Next can you edit the options available to whatever you like. All text options (Except [conditions](../profiles/index.md#conditions)) support [MiniMessage formatting](../profiles/formatting.md).
If you're unsure how a specific option should look like, head over to the [Profiles page](../profiles/index.md) for more information about the general structure.
@@ -338,7 +336,7 @@ motd:
### Additional profiles
To add additional profiles, create a new YAML file inside the `profiles` folder. The name doesn't matter, but it is recommended to keep it lowercased, use alphanummeric characters (`a-z, 0-9`), hyphens (`-`), underscores (`_`) and avoid spaces.
To add additional profiles, create a new YAML file inside the `profiles` folder. The name doesn't matter, but it is recommended to keep it lowercase, use alphanumeric characters (`a-z, 0-9`), hyphens (`-`), underscores (`_`) and avoid spaces.
Inside the file, add a priority and at least one setting, similar to the above shown example.
This would already be enough and AdvancedServerList would use it. If you however want to only show it when certain conditions are met, should you set the priority to a higher value and add conditions.
+12 -12
View File
@@ -24,13 +24,11 @@ If you're new to the plugin is it recommended to check out the [Profiles page](p
AdvancedServerList supports the following platforms:
[![spigot-img]{ width="64" loading="lazy" }][spigot]
[![paper-img]{ width="64" loading="lazy" }][paper]
[![bungeecord-img]{ width="64" loading="lazy" }][spigot]
[![waterfall-img]{ width="64" loading="lazy" }][paper]
[![velocity-img]{ width="64" loading="lazy" }][velocity]
[spigot-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/spigot_vector.svg "Tested on Spigot"
[paper-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/paper_vector.svg "Tested on Paper"
[bungeecord-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/bungeecord_vector.svg "Tested on BungeeCord"
[waterfall-img]: https://cdn.jsdelivr.net/npm/@intergrav/devins-badges@3/assets/compact-minimal/supported/waterfall_vector.svg "Tested on Waterfall"
@@ -42,17 +40,19 @@ AdvancedServerList supports the following platforms:
## Dependencies
| Dependency | Platforms | Required? |
|-------------------------------------------------------------------------|----------------------|-----------|
| [ProtocolLib]{ target="_blank" rel="noreferrer nofollow noopener" } | Spigot | Yes |
| [PlaceholderAPI]{ target="_blank" rel="noreferrer nofollow noopener" } | Spigot, Paper | No |
| [ViaVersion]{ target="_blank" rel="noreferrer nofollow noopener" } | Spigot, Paper | No |
| [PAPIProxyBridge]{ target="_blank" rel="noreferrer nofollow noopener" } | BungeeCord, Velocity | No |
| [Maintenance]{ target="_blank" rel="noreferrer nofollow noopener" } | All | No |
/// info
All listed dependencies are optional.
///
[protocollib]: https://www.spigotmc.org/resources/1997/
[placeholderapi]: https://www.spigotmc.org/resources/6245/
[viaversion]: https://www.spigotmc.org/resources/19254/
| Dependency | Platforms |
|-------------------------------------------------------------------------|----------------------|
| [PlaceholderAPI]{ target="_blank" rel="noreferrer nofollow noopener" } | Paper |
| [ViaVersion]{ target="_blank" rel="noreferrer nofollow noopener" } | Paper |
| [PAPIProxyBridge]{ target="_blank" rel="noreferrer nofollow noopener" } | BungeeCord, Velocity |
| [Maintenance]{ target="_blank" rel="noreferrer nofollow noopener" } | All |
[placeholderapi]: https://hangar.papermc.io/HelpChat/PlaceholderAPI
[viaversion]: https://hangar.papermc.io/ViaVersion/ViaVersion
[papiproxybridge]: https://hangar.papermc.io/William278/PAPIProxyBridge
[maintenance]: https://hangar.papermc.io/kennytv/Maintenance
+2 -2
View File
@@ -34,7 +34,7 @@
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>bukkit</artifactId>
<artifactId>paper</artifactId>
<packaging>jar</packaging>
<version>${plugin.version}</version>
@@ -124,7 +124,7 @@
</dependencies>
<build>
<finalName>AdvancedServerList-Bukkit-${plugin.version}</finalName>
<finalName>AdvancedServerList-Paper-${plugin.version}</finalName>
<resources>
<resource>
<filtering>true</filtering>
@@ -25,7 +25,6 @@
package ch.andre601.advancedserverlist.paper;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import io.papermc.paper.plugin.loader.PluginClasspathBuilder;
import io.papermc.paper.plugin.loader.PluginLoader;
import io.papermc.paper.plugin.loader.library.impl.MavenLibraryResolver;
@@ -25,41 +25,52 @@
package ch.andre601.advancedserverlist.paper;
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.bukkit.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.bukkit.listeners.JoinEvent;
import ch.andre601.advancedserverlist.bukkit.listeners.LoadEvent;
import ch.andre601.advancedserverlist.bukkit.listeners.WorldEvents;
import ch.andre601.advancedserverlist.bukkit.logging.BukkitLogger;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.BukkitPlayerPlaceholders;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.BukkitServerPlaceholders;
import ch.andre601.advancedserverlist.bukkit.objects.placeholders.PAPIPlaceholders;
import ch.andre601.advancedserverlist.bukkit.objects.WorldCache;
import ch.andre601.advancedserverlist.core.AdvancedServerList;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import ch.andre601.advancedserverlist.core.profiles.favicon.FaviconHandler;
import ch.andre601.advancedserverlist.paper.listeners.PaperPingEvent;
import ch.andre601.advancedserverlist.paper.commands.CmdAdvancedServerList;
import ch.andre601.advancedserverlist.paper.listeners.LoadEvent;
import ch.andre601.advancedserverlist.paper.logging.PaperLogger;
import ch.andre601.advancedserverlist.paper.objects.WorldCache;
import ch.andre601.advancedserverlist.paper.objects.placeholders.PAPIPlaceholders;
import ch.andre601.advancedserverlist.paper.objects.placeholders.PaperPlayerPlaceholders;
import ch.andre601.advancedserverlist.paper.objects.placeholders.PaperServerPlaceholders;
import org.bstats.bukkit.Metrics;
import org.bstats.charts.SimplePie;
import org.bukkit.Bukkit;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.util.CachedServerIcon;
import java.nio.file.Path;
public class PaperCore extends BukkitCore<CachedServerIcon>{
public class PaperCore extends JavaPlugin implements PluginCore<CachedServerIcon>{
private final PluginLogger logger = new BukkitLogger(getLogger());
private final PluginLogger logger = new PaperLogger(this.getLogger());
private AdvancedServerList<CachedServerIcon> core;
private FaviconHandler<CachedServerIcon> faviconHandler = null;
private PAPIPlaceholders<CachedServerIcon> papiPlaceholders = null;
private PAPIPlaceholders papiPlaceholders = null;
private WorldCache worldCache = null;
@Override
public void onEnable(){
this.core = AdvancedServerList.init(this, BukkitPlayerPlaceholders.init(), BukkitServerPlaceholders.init());
try{
Class.forName("io.papermc.paper.configuration.ConfigurationLoaders");
}catch(ClassNotFoundException ignored){
try{
// Above class only exists since 1.19+. This is a fallback to see if an older version is used.
Class.forName("com.destroystokyo.paper.PaperConfig");
}catch(ClassNotFoundException ex){
printNoPaperWarning();
return;
}
}
this.core = AdvancedServerList.init(this, new PaperPlayerPlaceholders(), new PaperServerPlaceholders());
if(getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
papiPlaceholders = PAPIPlaceholders.init(this);
papiPlaceholders = new PAPIPlaceholders(this);
}
@Override
@@ -86,8 +97,7 @@ public class PaperCore extends BukkitCore<CachedServerIcon>{
@Override
public void loadEvents(){
LoadEvent.init(this);
PaperPingEvent.init(this);
new LoadEvent(this);
}
@Override
@@ -143,11 +153,31 @@ public class PaperCore extends BukkitCore<CachedServerIcon>{
return "paper";
}
@Override
public WorldCache getWorldCache(){
if(worldCache != null)
return worldCache;
return (worldCache = new WorldCache());
}
private void printNoPaperWarning(){
getPluginLogger().warn("======================================================================================");
getPluginLogger().warn("THIS SERVER DOES NOT USE PAPER OR A COMPATIBLE FORK!");
getPluginLogger().warn("");
getPluginLogger().warn("AdvancedServerList 3.6.0 has dropped support for Spigot-based servers.");
getPluginLogger().warn("This means that only servers using Paper or a Paper-compatible fork may work.");
getPluginLogger().warn("");
getPluginLogger().warn("Reasons for this removal:");
getPluginLogger().warn(" - Reliance on a different plugin for core functionalities.");
getPluginLogger().warn(" - Bad dependency loading limited to MavenCentral only.");
getPluginLogger().warn("");
getPluginLogger().warn("Please consider switching to Paper or one of the Paper-compatible forks to benefit from");
getPluginLogger().warn("overall performance improvements amongst other things.");
getPluginLogger().warn("");
getPluginLogger().warn("AdvancedServerList will now disable itself. If you believe this was a mistake, report");
getPluginLogger().warn("this on Codeberg: https://codeberg.org/Andre601/AdvancedServerList");
getPluginLogger().warn("======================================================================================");
Bukkit.getPluginManager().disablePlugin(this);
}
}
@@ -23,30 +23,32 @@
*
*/
package ch.andre601.advancedserverlist.spigot.commands;
package ch.andre601.advancedserverlist.paper.commands;
import ch.andre601.advancedserverlist.core.interfaces.commands.CmdSender;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
import ch.andre601.advancedserverlist.paper.PaperCore;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
public class SpigotCmdSender implements CmdSender{
import java.util.Collections;
public class CmdAdvancedServerList extends Command{
private final CommandSender sender;
private final BukkitAudiences bukkitAudiences;
private final PaperCore plugin;
public SpigotCmdSender(CommandSender sender, BukkitAudiences bukkitAudiences){
this.sender = sender;
this.bukkitAudiences = bukkitAudiences;
public CmdAdvancedServerList(PaperCore plugin){
super(
"advancedserverlist",
"Main command of the plugin",
"/asl [reload|help|clearCache]",
Collections.singletonList("asl")
);
this.plugin = plugin;
}
@Override
public boolean hasPermission(String permission){
return sender.hasPermission(permission) || sender.hasPermission("advancedserverlist.admin");
}
@Override
public void sendMsg(String msg, Object... args){
bukkitAudiences.sender(sender).sendMessage(ComponentParser.text(String.format(msg, args)).toComponent());
public boolean execute(@NotNull CommandSender sender, @NotNull String s, @NotNull String[] args){
plugin.getCore().getCommandHandler().handle(new PaperCmdSender(sender), args);
return true;
}
}
@@ -23,9 +23,9 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.listeners;
package ch.andre601.advancedserverlist.paper.listeners;
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.paper.PaperCore;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
@@ -34,19 +34,15 @@ import org.bukkit.event.player.PlayerJoinEvent;
import java.net.InetSocketAddress;
public class JoinEvent<F> implements Listener{
public class JoinEvent implements Listener{
private final BukkitCore<F> plugin;
private final PaperCore plugin;
private JoinEvent(BukkitCore<F> plugin){
public JoinEvent(PaperCore plugin){
this.plugin = plugin;
Bukkit.getPluginManager().registerEvents(this, plugin);
}
public static <F> void init(BukkitCore<F> plugin){
new JoinEvent<>(plugin);
}
@EventHandler
public void onJoin(PlayerJoinEvent event){
InetSocketAddress address = event.getPlayer().getAddress();
@@ -23,17 +23,30 @@
*
*/
package ch.andre601.advancedserverlist.bukkit;
package ch.andre601.advancedserverlist.paper.listeners;
import ch.andre601.advancedserverlist.bukkit.objects.WorldCache;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
import org.bukkit.plugin.java.JavaPlugin;
import ch.andre601.advancedserverlist.paper.PaperCore;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.server.ServerLoadEvent;
/*
* Small convenience class to "merge" the PluginCore and JavaPlugin classes.
* Allows me to have BukkitCore<?> for whenever I also need a JavaPlugin (i.e. registering events).
* See JoinEvent class for an example.
*/
public abstract class BukkitCore<F> extends JavaPlugin implements PluginCore<F>{
public abstract WorldCache getWorldCache();
}
public class LoadEvent implements Listener{
private final PaperCore plugin;
public LoadEvent(PaperCore plugin){
this.plugin = plugin;
Bukkit.getPluginManager().registerEvents(this, plugin);
}
@EventHandler
public void onLoad(ServerLoadEvent event){
new JoinEvent(plugin);
new PingEvent(plugin);
new WorldEvents(plugin);
// Load currently loaded worlds into the WorldCache
Bukkit.getWorlds().forEach(world -> plugin.getWorldCache().addWorld(world));
}
}
@@ -28,16 +28,15 @@ package ch.andre601.advancedserverlist.paper.listeners;
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.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.bukkit.listeners.PreServerListSetEventImpl;
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitServerImpl;
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitPlayerImpl;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.core.interfaces.core.PluginCore;
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.objects.impl.PaperPlayerImpl;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperServerImpl;
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import com.destroystokyo.paper.profile.PlayerProfile;
import me.clip.placeholderapi.PlaceholderAPI;
@@ -49,7 +48,7 @@ import org.bukkit.util.CachedServerIcon;
import java.awt.image.BufferedImage;
import java.util.*;
public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon, BukkitPlayerImpl>{
public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon, PaperPlayerImpl>{
private final PaperCore plugin;
private final PaperServerListPingEvent event;
@@ -89,7 +88,7 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
}
@Override
public void setPlayers(List<String> lines, BukkitPlayerImpl player, GenericServer server){
public void setPlayers(List<String> lines, PaperPlayerImpl player, GenericServer server){
event.getPlayerSample().clear();
List<PlayerProfile> players = new ArrayList<>(lines.size());
@@ -159,7 +158,7 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
}
@Override
public String parsePAPIPlaceholders(String text, BukkitPlayerImpl player){
public String parsePAPIPlaceholders(String text, PaperPlayerImpl player){
if(plugin.getServer().getPluginManager().isPluginEnabled("PlaceholderAPI"))
return PlaceholderAPI.setPlaceholders(player.getPlayer(), text);
@@ -172,20 +171,20 @@ public class PaperEventWrapper implements GenericEventWrapper<CachedServerIcon,
}
@Override
public BukkitCore<CachedServerIcon> getPlugin(){
public PluginCore<CachedServerIcon> getPlugin(){
return plugin;
}
@Override
public BukkitPlayerImpl createPlayer(CachedPlayer player, int protocol){
public PaperPlayerImpl createPlayer(CachedPlayer player, int protocol){
OfflinePlayer pl = Bukkit.getOfflinePlayer(player.getUuid());
return new BukkitPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
return new PaperPlayerImpl(pl.hasPlayedBefore() ? pl : null, player, protocol);
}
@Override
public GenericServer createGenericServer(int playersOnline, int playersMax, String host){
return new BukkitServerImpl(plugin.getWorldCache().worlds(), playersOnline, playersMax, host);
return new PaperServerImpl(plugin.getWorldCache().worlds(), playersOnline, playersMax, host);
}
@Override
@@ -31,19 +31,15 @@ import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class PaperPingEvent implements Listener{
public class PingEvent implements Listener{
private final PaperCore plugin;
private PaperPingEvent(PaperCore plugin){
public PingEvent(PaperCore plugin){
this.plugin = plugin;
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
public static void init(PaperCore plugin){
new PaperPingEvent(plugin);
}
@EventHandler
public void onPaperServerListPing(PaperServerListPingEvent event){
PingEventHandler.handleEvent(new PaperEventWrapper(plugin, event));
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.listeners;
package ch.andre601.advancedserverlist.paper.listeners;
import ch.andre601.advancedserverlist.api.bukkit.events.PreServerListSetEvent;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
@@ -23,10 +23,9 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.listeners;
package ch.andre601.advancedserverlist.paper.listeners;
import ch.andre601.advancedserverlist.bukkit.BukkitCore;
import org.bukkit.Bukkit;
import ch.andre601.advancedserverlist.paper.PaperCore;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldLoadEvent;
@@ -34,20 +33,15 @@ import org.bukkit.event.world.WorldUnloadEvent;
public class WorldEvents implements Listener{
private final BukkitCore<?> plugin;
private final PaperCore plugin;
private WorldEvents(BukkitCore<?> plugin){
public WorldEvents(PaperCore plugin){
this.plugin = plugin;
Bukkit.getPluginManager().registerEvents(this, plugin);
}
public static void init(BukkitCore<?> plugin){
new WorldEvents(plugin);
}
@EventHandler
public void onWorldLoad(WorldLoadEvent event){
plugin.getWorldCache().addWorld(event.getWorld().getName(), event.getWorld());
plugin.getWorldCache().addWorld(event.getWorld());
}
@EventHandler
@@ -23,18 +23,18 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.logging;
package ch.andre601.advancedserverlist.paper.logging;
import ch.andre601.advancedserverlist.core.interfaces.PluginLogger;
import java.util.logging.Level;
import java.util.logging.Logger;
public class BukkitLogger implements PluginLogger{
public class PaperLogger implements PluginLogger{
private final Logger logger;
public BukkitLogger(Logger logger){
public PaperLogger(Logger logger){
this.logger = logger;
}
@@ -23,7 +23,7 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects;
package ch.andre601.advancedserverlist.paper.objects;
import org.bukkit.World;
@@ -36,15 +36,15 @@ public record WorldCache(Map<String, World> worlds){
this(new HashMap<>());
}
public boolean containsWorld(String key){
return worlds().containsKey(key);
public boolean containsWorld(String name){
return this.worlds.containsKey(name);
}
public void addWorld(String key, World world){
worlds().put(key, world);
public void addWorld(World world){
this.worlds.put(world.getName(), world);
}
public void removeWorld(String key){
worlds().remove(key);
public void removeWorld(String name){
this.worlds.remove(name);
}
}
@@ -23,31 +23,30 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.impl;
package ch.andre601.advancedserverlist.paper.objects.impl;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitPlayer;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.profiles.players.GenericPlayerImpl;
import org.bukkit.OfflinePlayer;
public class BukkitPlayerImpl extends GenericPlayerImpl implements BukkitPlayer{
public class PaperPlayerImpl extends GenericPlayerImpl implements BukkitPlayer{
private final OfflinePlayer player;
private boolean playedBefore = false;
private boolean banned = false;
private boolean whitelisted = false;
public BukkitPlayerImpl(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
public PaperPlayerImpl(OfflinePlayer player, CachedPlayer cachedPlayer, int protocol){
this.player = player;
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();
@@ -23,15 +23,14 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.impl;
package ch.andre601.advancedserverlist.paper.objects.impl;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitServer;
import org.bukkit.World;
import java.util.Map;
public record BukkitServerImpl(Map<String, World> worlds, int playersOnline, int playersMax, String host) implements BukkitServer{
public record PaperServerImpl(Map<String, World> worlds, int playersOnline, int playersMax, String host) implements BukkitServer {
@Override
public Map<String, World> getWorlds(){
return worlds;
@@ -23,23 +23,19 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.placeholders;
package ch.andre601.advancedserverlist.paper.objects.placeholders;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitPlayer;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitServer;
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.bukkit.BukkitCore;
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitPlayerImpl;
import ch.andre601.advancedserverlist.bukkit.objects.impl.BukkitServerImpl;
import ch.andre601.advancedserverlist.core.objects.CachedPlayer;
import ch.andre601.advancedserverlist.core.parsing.ComponentParser;
import ch.andre601.advancedserverlist.core.profiles.ServerListProfile;
import ch.andre601.advancedserverlist.core.profiles.profile.ProfileManager;
import ch.andre601.advancedserverlist.core.profiles.replacer.StringReplacer;
import ch.andre601.advancedserverlist.spigot.SpigotCore;
import ch.andre601.advancedserverlist.spigot.listeners.ProtocolLibEvents;
import com.comphenix.protocol.ProtocolLibrary;
import ch.andre601.advancedserverlist.paper.PaperCore;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperPlayerImpl;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperServerImpl;
import com.viaversion.viaversion.api.Via;
import me.clip.placeholderapi.PlaceholderAPI;
import me.clip.placeholderapi.expansion.PlaceholderExpansion;
@@ -48,21 +44,19 @@ import org.bukkit.entity.Player;
import org.jetbrains.annotations.NotNull;
import java.net.InetSocketAddress;
import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
public class PAPIPlaceholders<F> extends PlaceholderExpansion{
public class PAPIPlaceholders extends PlaceholderExpansion{
private final BukkitCore<F> plugin;
private final PaperCore plugin;
private PAPIPlaceholders(BukkitCore<F> plugin){
public PAPIPlaceholders(PaperCore plugin){
this.plugin = plugin;
this.register();
}
public static <F> PAPIPlaceholders<F> init(BukkitCore<F> plugin){
return new PAPIPlaceholders<>(plugin);
}
@Override
public @NotNull String getIdentifier(){
return "asl";
@@ -85,16 +79,15 @@ public class PAPIPlaceholders<F> extends PlaceholderExpansion{
@Override
public String onPlaceholderRequest(Player pl, @NotNull String identifier){
InetSocketAddress address = pl.getAddress();
String host = resolveVirtualHost(pl, address);
String host = pl.getVirtualHost() == null ? null : pl.getVirtualHost().getHostString();
CachedPlayer cached = plugin.getCore().getPlayerHandler().getCachedPlayer(pl.getUniqueId());
int protocol = resolveProtocol(pl);
int online = Bukkit.getOnlinePlayers().size();
int max = Bukkit.getMaxPlayers();
BukkitServer server = new BukkitServerImpl(plugin.getWorldCache().worlds(), online, max, host);
GenericPlayer player = new BukkitPlayerImpl(pl, cached, protocol);
BukkitServer server = new PaperServerImpl(plugin.getWorldCache().worlds(), online, max, host);
BukkitPlayer player = new PaperPlayerImpl(pl, cached, protocol);
ServerListProfile profile = ProfileManager.resolveProfile(plugin.getCore(), player, server);
if(profile == null)
@@ -114,56 +107,36 @@ public class PAPIPlaceholders<F> extends PlaceholderExpansion{
extraPlayers = entry.extraPlayersCount();
}
BukkitServer finalServer = new BukkitServerImpl(plugin.getWorldCache().worlds(), online, max, host);
BukkitServer finalServer = new PaperServerImpl(plugin.getWorldCache().worlds(), online, max, host);
return switch(identifier.toLowerCase(Locale.ROOT)){
case "motd" -> getOption(entry.motd(), pl, player, finalServer);
case "favicon" -> getOption(entry.favicon(), pl, player, finalServer);
case "playercount_hover" -> getOption(entry.players(), pl, player, finalServer);
case "playercount_text" -> getOption(entry.playerCountText(), pl, player, finalServer);
// TODO: Remove extra_players_max in future release
case "extra_players_max", "playercount_extraplayers" -> extraPlayers == null ? "null" : String.valueOf(extraPlayers);
case "playercount_extraplayers" -> extraPlayers == null ? "null" : String.valueOf(extraPlayers);
case "playercount_maxplayers" -> maxPlayers == null ? "null" : String.valueOf(maxPlayers);
case "server_playersmax" -> String.valueOf(max);
default -> null;
};
}
private String getOption(String str, Player pl, GenericPlayer player, GenericServer server){
private int resolveProtocol(Player player){
if(Bukkit.getPluginManager().isPluginEnabled("ViaVersion"))
return Via.getAPI().getPlayerVersion(player.getUniqueId());
// Since ViaVersion isn't installed is the player's protocol version the same as the server.
//noinspection deprecation
return Bukkit.getUnsafe().getProtocolVersion();
}
private String getOption(String str, Player pl, BukkitPlayer player, BukkitServer server){
return getOption(Collections.singletonList(str), pl, player, server);
}
private String getOption(List<String> list, Player pl, GenericPlayer player, GenericServer server){
private String getOption(List<String> list, Player pl, BukkitPlayer player, BukkitServer server){
return ComponentParser.list(list)
.modifyText(text -> PlaceholderAPI.setPlaceholders(pl, text))
.modifyText(text -> StringReplacer.replace(text, player, server))
.toString();
}
private int resolveProtocol(Player player){
if(Bukkit.getPluginManager().isPluginEnabled("ViaVersion"))
return Via.getAPI().getPlayerVersion(player.getUniqueId());
// Since Spigot version requires ProtocolLib can we use it here safely if the plugin instance is SpigotCore.
if(plugin instanceof SpigotCore)
return ProtocolLibrary.getProtocolManager().getProtocolVersion(player);
// getProtocolVersion is only in Paper, so this is only called when main class isn't SpigotCore.
// Also, ViaVersion is not present, so the player protocol *should* be the same as the server.
//noinspection deprecation
return Bukkit.getUnsafe().getProtocolVersion();
}
private String resolveVirtualHost(Player player, InetSocketAddress address){
try {
// Server is a Paper Server with Player#getVirtualHost()
Class.forName("com.destroystokyo.paper.network.NetworkClient");
return player.getVirtualHost() == null ? null : player.getVirtualHost().getHostString();
}catch(ClassNotFoundException ignored){}
if(address == null)
return null;
return ProtocolLibEvents.getHostAddresses().get(address.getHostString());
}
}
@@ -23,40 +23,32 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.placeholders;
package ch.andre601.advancedserverlist.paper.objects.placeholders;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperPlayerImpl;
public class BukkitPlayerPlaceholders extends PlaceholderProvider{
public class PaperPlayerPlaceholders extends PlaceholderProvider{
private BukkitPlayerPlaceholders(){
public PaperPlayerPlaceholders(){
super("player");
}
public static BukkitPlayerPlaceholders init(){
return new BukkitPlayerPlaceholders();
}
@Override
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
if(!(player instanceof BukkitPlayer bukkitPlayer))
if(!(player instanceof PaperPlayerImpl paperPlayer))
return null;
return switch(placeholder){
case "name" -> bukkitPlayer.getName();
case "protocol" -> String.valueOf(bukkitPlayer.getProtocol());
case "uuid" -> bukkitPlayer.getUUID().toString();
case "hasPlayedBefore" -> returnValue(bukkitPlayer, bukkitPlayer.hasPlayedBefore());
case "isBanned" -> returnValue(bukkitPlayer, bukkitPlayer.isBanned());
case "isWhitelisted" -> returnValue(bukkitPlayer, bukkitPlayer.isWhitelisted());
case "name" -> paperPlayer.getName();
case "protocol" -> String.valueOf(paperPlayer.getProtocol());
case "uuid" -> paperPlayer.getUUID().toString();
case "hasPlayedBefore" -> String.valueOf(paperPlayer.hasPlayedBefore());
case "isBanned" -> String.valueOf(paperPlayer.isBanned());
case "isWhitelisted" -> String.valueOf(paperPlayer.isWhitelisted());
default -> null;
};
}
private String returnValue(BukkitPlayer player, Object value){
return player.getPlayer() == null ? null : String.valueOf(value);
}
}
@@ -23,38 +23,33 @@
*
*/
package ch.andre601.advancedserverlist.bukkit.objects.placeholders;
package ch.andre601.advancedserverlist.paper.objects.placeholders;
import ch.andre601.advancedserverlist.api.bukkit.objects.BukkitServer;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;
import ch.andre601.advancedserverlist.paper.objects.impl.PaperServerImpl;
import org.bukkit.Bukkit;
import org.bukkit.World;
public class BukkitServerPlaceholders extends PlaceholderProvider{
public class PaperServerPlaceholders extends PlaceholderProvider{
private BukkitServerPlaceholders(){
public PaperServerPlaceholders(){
super("server");
}
public static BukkitServerPlaceholders init(){
return new BukkitServerPlaceholders();
}
@Override
public String parsePlaceholder(String placeholders, GenericPlayer player, GenericServer server){
if(!(server instanceof BukkitServer bukkitServer))
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
if(!(server instanceof PaperServerImpl paperServer))
return null;
String[] args = placeholders.split("\\s", 2);
String[] args = placeholder.split("\\s");
return switch(args[0]){
case "playersOnline" -> {
if(args.length >= 2){
int players = 0;
for(int i = 1; i < args.length; i++){
World world = bukkitServer.getWorlds().get(args[i]);
World world = paperServer.worlds().get(args[i]);
if(world == null)
continue;
@@ -64,19 +59,19 @@ public class BukkitServerPlaceholders extends PlaceholderProvider{
yield String.valueOf(players);
}
yield String.valueOf(bukkitServer.getPlayersOnline());
yield String.valueOf(paperServer.playersOnline());
}
case "playersMax" -> {
if(args.length >= 2)
yield null;
yield String.valueOf(bukkitServer.getPlayersMax());
yield String.valueOf(paperServer.getPlayersMax());
}
case "host" -> {
if(args.length >= 2)
yield null;
yield bukkitServer.getHost();
yield paperServer.getHost();
}
case "whitelistEnabled" -> {
if(args.length >= 2)
@@ -1,11 +1,15 @@
#
# This file is kept for Folia support.
#
name: 'AdvancedServerList'
author: 'Andre_601'
version: '${plugin.version}'
description: '${plugin.description}'
main: 'ch.andre601.advancedserverlist.spigot.SpigotCore'
main: 'ch.andre601.advancedserverlist.paper.PaperCore'
api-version: 1.19
api-version: '1.19'
folia-supported: true
+1 -1
View File
@@ -57,7 +57,7 @@
<modules>
<module>core</module>
<module>bungeecord</module>
<module>bukkit</module>
<module>paper</module>
<module>velocity</module>
<module>version-uploader</module>
</modules>
@@ -32,7 +32,7 @@ public enum PlatformInfo{
BUKKIT(
"bukkit",
"bukkit/target/AdvancedServerList-Bukkit-{{version}}.jar",
"spigot", "paper", "folia"
"paper", "folia"
),
BUNGEECORD(
"bungeecord",