Compare commits

..
11 Commits
35 changed files with 465 additions and 143 deletions

No files matched your search

@@ -25,12 +25,13 @@
package ch.andre601.advancedserverlist.bungeecord.listeners;
import ch.andre601.advancedserverlist.api.bungeecord.events.PostServerListSetEvent;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.bungeecord.BungeeCordCore;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import net.md_5.bungee.api.event.ProxyPingEvent;
import net.md_5.bungee.api.plugin.Listener;
import net.md_5.bungee.event.EventHandler;
import net.md_5.bungee.event.EventPriority;
public class PingEvent implements Listener{
@@ -41,8 +42,10 @@ public class PingEvent implements Listener{
plugin.getProxy().getPluginManager().registerListener(plugin, this);
}
@EventHandler(priority = EventPriority.LOW)
@EventHandler(priority = 90) // Maintenance has Event Priority 80, so we need to be AFTER it.
public void onProxyPing(ProxyPingEvent event){
PingEventHandler.handleEvent(new BungeeEventWrapper(plugin, event));
ProfileEntry entry = PingEventHandler.handleEvent(new BungeeEventWrapper(plugin, event));
plugin.getProxy().getPluginManager().callEvent(new PostServerListSetEvent(entry));
}
}
+2 -2
View File
@@ -41,7 +41,7 @@
<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<plugin.config.version>4</plugin.config.version>
<plugin.config.version>5</plugin.config.version>
</properties>
<repositories>
@@ -119,7 +119,7 @@
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.0.0-jre</version>
<version>33.1.0-jre</version>
<scope>provided</scope>
</dependency>
@@ -44,11 +44,11 @@ public class PingEventHandler{
private static PAPIUtil papiUtil = null;
private static MaintenanceUtil maintenanceUtil = null;
public static <F, P extends GenericPlayer> void handleEvent(GenericEventWrapper<F, P> event){
public static <F, P extends GenericPlayer> ProfileEntry handleEvent(GenericEventWrapper<F, P> event){
event.getPlugin().getPluginLogger().debug(PingEventHandler.class, "Received ping event. Handling it...");
if(event.isInvalidProtocol() || event.isMaintenanceModeActive()){
event.getPlugin().getPluginLogger().debug(PingEventHandler.class, "Not handling event. Either protocol was invalid of Maintenance is enabled.");
return;
if(event.isInvalidProtocol()){
event.getPlugin().getPluginLogger().debug(PingEventHandler.class, "Not handling event. Protocol was invalid.");
return null;
}
PluginCore<F> plugin = event.getPlugin();
@@ -70,7 +70,7 @@ public class PingEventHandler{
if(profile == null){
logger.debugWarn(PingEventHandler.class, "Server List Profile couldn't be resolved properly. Cancelling event handling...");
return;
return null;
}
logger.debug(PingEventHandler.class, "Received valid Server List Profile. Calling PreServerListSetEvent...");
@@ -78,7 +78,7 @@ public class PingEventHandler{
GenericServerListEvent e = event.callEvent(ProfileManager.merge(profile));
if(e == null || e.isCancelled()){
logger.debug(PingEventHandler.class, "PreServerListSetEvent was cancelled. Stopping ping handling...");
return;
return null;
}
logger.debug(PingEventHandler.class, "PreServerListSetEvent completed. Proceeding with ping handling...");
@@ -86,12 +86,12 @@ public class PingEventHandler{
ProfileEntry entry = e.getEntry();
if(entry.isInvalid()){
logger.debugWarn(PingEventHandler.class, "No valid ProfileEntry retrieved. Cancelling ping handling...");
return;
return null;
}
boolean extraPlayers = ProfileManager.checkOption(entry.extraPlayersEnabled());
if(extraPlayers){
if(extraPlayers && ignoreMaintenance(event, "extraPlayers")){
max = online + (entry.extraPlayersCount() == null ? 0 : entry.extraPlayersCount());
logger.debug(PingEventHandler.class, "Extra Players enabled. Applying '%d' as max player count...", max);
@@ -99,7 +99,7 @@ public class PingEventHandler{
event.setMaxPlayers(max);
}
if(ProfileManager.checkOption(entry.maxPlayersEnabled()) && !extraPlayers){
if(ProfileManager.checkOption(entry.maxPlayersEnabled()) && !extraPlayers && ignoreMaintenance(event, "maxPlayers")){
max = (entry.maxPlayersCount() == null) ? 0 : entry.maxPlayersCount();
logger.debug(PingEventHandler.class, "Max Players enabled. Applying '%d' as max player count...", max);
@@ -109,7 +109,7 @@ public class PingEventHandler{
GenericServer finalServer = event.createGenericServer(online, max, host);
if(ProfileManager.checkOption(entry.motd())){
if(ProfileManager.checkOption(entry.motd()) && ignoreMaintenance(event, "motd")){
logger.debug(PingEventHandler.class, "MOTD set. Applying '%s'...", String.join("\\n", entry.motd()));
event.setMotd(
@@ -122,13 +122,13 @@ public class PingEventHandler{
boolean hidePlayers = ProfileManager.checkOption(entry.hidePlayersEnabled());
if(hidePlayers){
if(hidePlayers && ignoreMaintenance(event, "hidePlayers")){
logger.debug(PingEventHandler.class, "Hide Players enabled. Hiding player count...");
event.hidePlayers();
}
if(ProfileManager.checkOption(entry.playerCountText()) && !hidePlayers){
if(ProfileManager.checkOption(entry.playerCountText()) && !hidePlayers && ignoreMaintenance(event, "playerCountText")){
logger.debug(PingEventHandler.class, "Player Count Text set. Applying '%s'...", entry.playerCountText());
event.setPlayerCount(
@@ -139,13 +139,13 @@ public class PingEventHandler{
);
}
if(ProfileManager.checkOption(entry.players()) && !hidePlayers){
if(ProfileManager.checkOption(entry.players()) && !hidePlayers && ignoreMaintenance(event, "playerCountHover")){
logger.debug(PingEventHandler.class, "Player Count Hover set. Applying '%s'...", String.join("\\n", entry.players()));
event.setPlayers(entry.players(), player, server);
}
if(ProfileManager.checkOption(entry.favicon())){
if(ProfileManager.checkOption(entry.favicon()) && ignoreMaintenance(event, "favicon")){
logger.debug(PingEventHandler.class, "Favicon set. Resolving '%s'...", entry.favicon());
String faviconString = StringReplacer.replace(entry.favicon(), player, server);
@@ -165,6 +165,8 @@ public class PingEventHandler{
logger.debug(PingEventHandler.class, "Event handling completed. Updating Ping data...");
event.updateEvent();
return entry;
}
public static PAPIUtil getPAPIUtil(){
@@ -180,4 +182,11 @@ public class PingEventHandler{
return (maintenanceUtil = new MaintenanceUtil());
}
private static <F, P extends GenericPlayer> boolean ignoreMaintenance(GenericEventWrapper<F, P> event, String option){
if(!event.isMaintenanceModeActive())
return true;
return !event.getPlugin().getCore().getFileHandler().getBool(true, "disableDuringMaintenance", option);
}
}
@@ -46,12 +46,29 @@ public class ConfigMigrator{
public static ConfigurationTransformation.Versioned create(){
return ConfigurationTransformation.versionedBuilder()
.versionKey("configVersion")
.addVersion(LATEST, threeToFour())
.addVersion(LATEST, fourToFive())
.addVersion(4, threeToFour())
.addVersion(3, twoToThree())
.addVersion(2, oneToTwo())
.build();
}
public static ConfigurationTransformation fourToFive(){
return ConfigurationTransformation.builder()
.addAction(NodePath.path(), (path, value) -> {
value.node("disableDuringMaintenance", "motd").set(true);
value.node("disableDuringMaintenance", "favicon").set(true);
value.node("disableDuringMaintenance", "hidePlayers").set(true);
value.node("disableDuringMaintenance", "playerCountText").set(true);
value.node("disableDuringMaintenance", "playerCountHover").set(true);
value.node("disableDuringMaintenance", "extraPlayers").set(true);
value.node("disableDuringMaintenance", "maxPlayers").set(true);
return null;
})
.build();
}
public static ConfigurationTransformation threeToFour(){
return ConfigurationTransformation.builder()
.addAction(NodePath.path(), (path, value) -> {
@@ -187,8 +187,12 @@ public class FileHandler{
return node.node(path).getString(def);
}
public boolean getBool(boolean def, Object... path){
return node.node(path).getBoolean(def);
}
public boolean getBoolean(Object... path){
return node.node(path).getBoolean();
return getBool(false, path);
}
public long getLong(long def, long limit, Object... path){
+36
View File
@@ -50,6 +50,42 @@ debug: false
#
faviconCacheTime: 1
#
# List of options that should be disabled while the Maintenance Mode of the plugin Maintenance is active.
# Any option not listed here will NOT be disabled, meaning AdvancedServerList will continue to handle it.
#
# Each option defaults to true when not present, disabling said option while Maintenance is active.
#
disableDuringMaintenance:
#
# When true (Default), disables handling of MOTD while Maintenance is enabled.
#
motd: true
#
# When true (Default), disables handling of Favicon while Maintenance is enabled.
#
favicon: true
#
# When true (Default), disables hiding of player count while Maintenance is enabled.
#
hidePlayers: true
#
# When true (Default), disables handling of player count text while Maintenance is enabled.
#
playerCountText: true
#
# When true (Default), disables handling of player count hover while Maintenance is enabled.
#
playerCountHover: true
#
# When true (Default), disables use of extra players feature while Maintenance is enabled.
#
extraPlayers: true
#
# When true (Default), disables use of max players feature while Maintenance is enabled.
#
maxPlayers: true
#
# DO NOT EDIT!
#
+3 -3
View File
@@ -23,13 +23,13 @@
Detailed object info
-->
{% if page.meta.constructors %}
{{ info.info('Constructor Detail', page.meta.constructors, defaults=page.meta.defaults) }}
{{ info.info('Constructor Detail', page.meta.constructors, 'constructor', defaults=page.meta.defaults) }}
{% endif %}
{% if page.meta.enums %}
{{ info.info('Enum Constant Detail', page.meta.enums, true, defaults=page.meta.defaults) }}
{{ info.info('Enum Constant Detail', page.meta.enums, 'enum', defaults=page.meta.defaults) }}
{% endif %}
{% if page.meta.methods %}
{{ info.info('Method Detail', page.meta.methods, defaults=page.meta.defaults)}}
{{ info.info('Method Detail', page.meta.methods, 'method', defaults=page.meta.defaults)}}
{% endif %}
{% endif %}
{% endblock %}
@@ -105,14 +105,14 @@
</div>
{%- endmacro %}
{% macro info(title, details, enum = false, defaults = []) -%}
{% macro info(title, details, details_type = 'unknown', defaults = []) -%}
<h2 id="{{ title | lower() | replace(' ', '-') | e}}">
{{ title }}
</h2>
{% for detail in details %}
<div class="api-detail">
{% set final_name = namespace(name = "") %}
{% if enum %}
{% if details_type == "enum" %}
{% set final_name.name = detail.name | upper() %}
{% else %}
{% set final_name.name = detail.name ~ "(" %}
@@ -123,7 +123,7 @@
{% if loop.revindex > 1 %}{% set final_name.name = final_name.name ~ ", " %}{% endif %}
{% endfor %}
{% if not enum %}
{% if details_type != "enum" %}
{% set final_name.name = final_name.name ~ ")" %}
{% endif %}
@@ -140,19 +140,19 @@
<api__static></api__static> <api__final></api__final>
{% endif %}
{% if detail.type %}
{% if detail.type and details_type == "method" %}
{% if detail.type.link %}
<a href="{{ detail.type.link }}" class="api-type__{{- detail.type.type | default('primitive') -}}">{{ detail.type.name | default('void') | e }}</a>
{% else %}
<span class="api-type__{{- detail.type.type | default('primitive') -}}">{{ detail.type.name | default('void') | e }}</span>
{% endif %}
{% elif defaults and defaults.type %}
{% elif defaults and defaults.type and details_type == "method" %}
{% if defaults.type.link %}
<a href="{{ defaults.type.link }}" class="api-type__{{- defaults.type.type | default('primitive') -}}">{{ defaults.type.name | default('void') | e }}</a>
{% else %}
<span class="api-type__{{- defaults.type.type | default('primitive') -}}">{{ defaults.type.name | default('void') }}</span>
{% endif %}
{% else %}
{% elif details_type == "method" %}
<span class="api-type__primitive">void</span>
{% endif %}
<code>{{ final_name.name | e }}</code><a href="#{{ final_name.name | lower() | replace(' ', '-') | e }}" class="headerlink" title="Permanent link"></a>
-10
View File
@@ -1,10 +0,0 @@
nav:
- Home: index.md
- getting-started
- commands
- profiles
- examples
- migration
- api
- addons
- PlaceholderAPI: placeholderapi
-2
View File
@@ -1,2 +0,0 @@
nav:
- ...
-6
View File
@@ -1,6 +0,0 @@
nav:
- index.md
- api: api
- platform-bukkit: platform-bukkit
- platform-bungeecord: platform-bungeecord
- platform-velocity: platform-velocity
-3
View File
@@ -1,3 +0,0 @@
nav:
- index.md
- ch.andre601.advancedserverlist.api: ch.andre601.advancedserverlist.api
@@ -8,7 +8,7 @@ constructors:
- name: 'identifier'
description: 'The identifier to use for the placeholder. Cannot be empty.'
type: String
attributes:
attribute:
- notnull
methods:
@@ -28,7 +28,7 @@ methods:
type: GenericServer
description: 'The <a href="./../objects/genericserver/"><code>GenericServer</code> instance</a> used.'
returns: 'Possibly-parsed or possibly-null String to replace the placeholder with.'
attributes:
attribute:
- nullable
- abstract
type:
@@ -1,3 +0,0 @@
nav:
- index.md
- ch.andre601.advancedserverlist.api.bukkit: ch.andre601.advancedserverlist.api.bukkit
@@ -0,0 +1,49 @@
---
template: api-doc.html
constructors:
- name: 'PostServerListSetEvent'
description: 'Constructor for creating a new PostServerListSetEvent instance.'
parameters:
- name: 'entry'
description: 'The <a href="../../../../api/ch.andre601.advancedserverlist.api/profiles/profileentry/"><code>ProfileEntry</code></a> used during the PingEvent.'
type: ProfileEntry
attribute:
- nullable
methods:
- name: 'getHandlerList'
description: 'Static <a href="https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/HandlerList.html" target="_blank" rel="nofollow"><code>HandlerList</code></a> getter. Required by Paper.'
returns: 'The static <a href="https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/HandlerList.html" target="_blank" rel="nofollow"><code>HandlerList instance</code></a> of this event.'
attributes:
- static
type:
name: 'HandlerList'
type: 'object'
- name: 'getEntry'
description: |
The <a href="../../../../api/ch.andre601.advancedserverlist.api/profiles/profileentry/"><code>ProfileEntry</code></a> that was used during the PingEvent handling.<br>
<br>
The returned value may be <code>null</code> should the PingEvent handling be cancelled at any point (i.e. due to an invalid protocol or because the <a href="../preserverlistsetevent/"><code>PreServerListSetEvent</code></a> has been cancelled).<br>
The values within the ProfileEntry also do not represent what is actually used within the Server list itself, but only the values provided for the PingEvent handling.
returns: 'Possibly-null ProfileEntry used for the PingEvent.'
attributes:
- nullable
type:
name: 'ProfileEntry'
type: 'object'
link: '../../../../api/ch.andre601.advancedserverlist.api/profiles/profileentry/'
inherits:
'org.bukkit.event.Event':
link: 'https://hub.spigotmc.org/javadocs/spigot/org/bukkit/event/Event.html'
list:
- 'getHandlers()'
---
# <api__class></api__class> PostServerListSetEvent
Called **after** the plugin has updated the Server List.
The provided [`ProfileEntry`](#getentry()) may be null due to the PingEvent handling being cancelled (i.e. due to a invalid protocol or due to the [`PreServerListSetEvent`](preserverlistsetevent.md) being cancelled).
The entry also only represents the values used during the PingEvent, not the actual content that is being displayed.
@@ -1,3 +0,0 @@
nav:
- index.md
- ch.andre601.advancedserverlist.api.bungeecord: ch.andre601.advancedserverlist.api.bungeecord
@@ -0,0 +1,35 @@
---
template: api-doc.html
constructors:
- name: 'PostServerListSetEvent'
description: 'Constructor for creating a new PostServerListSetEvent instance.'
parameters:
- name: 'entry'
description: 'The <a href="../../../../api/ch.andre601.advancedserverlist.api/profiles/profileentry/"><code>ProfileEntry</code></a> used during the PingEvent.'
type: ProfileEntry
attribute:
- nullable
methods:
- name: 'getEntry'
description: |
The <a href="../../../../api/ch.andre601.advancedserverlist.api/profiles/profileentry/"><code>ProfileEntry</code></a> that was used during the PingEvent handling.<br>
<br>
The returned value may be <code>null</code> should the PingEvent handling be cancelled at any point (i.e. due to an invalid protocol or because the <a href="../preserverlistsetevent/"><code>PreServerListSetEvent</code></a> has been cancelled).<br>
The values within the ProfileEntry also do not represent what is actually used within the Server list itself, but only the values provided for the PingEvent handling.
returns: 'Possibly-null ProfileEntry used for the PingEvent.'
attributes:
- nullable
type:
name: 'ProfileEntry'
type: 'object'
link: '../../../../api/ch.andre601.advancedserverlist.api/profiles/profileentry/'
---
# <api__class></api__class> PostServerListSetEvent
Called **after** the plugin has updated the Server List.
The provided [`ProfileEntry`](#getentry()) may be null due to the PingEvent handling being cancelled (i.e. due to a invalid protocol or due to the [`PreServerListSetEvent`](preserverlistsetevent.md) being cancelled).
The entry also only represents the values used during the PingEvent, not the actual content that is being displayed.
@@ -1,3 +0,0 @@
nav:
- index.md
- ch.andre601.advancedserverlist.api.velocity: ch.andre601.advancedserverlist.api.velocity
@@ -0,0 +1,35 @@
---
template: api-doc.html
constructors:
- name: 'PostServerListSetEvent'
description: 'Constructor for creating a new PostServerListSetEvent instance.'
parameters:
- name: 'entry'
description: 'The <a href="../../../../api/ch.andre601.advancedserverlist.api/profiles/profileentry/"><code>ProfileEntry</code></a> used during the PingEvent.'
type: ProfileEntry
attribute:
- nullable
methods:
- name: 'getEntry'
description: |
The <a href="../../../../api/ch.andre601.advancedserverlist.api/profiles/profileentry/"><code>ProfileEntry</code></a> that was used during the PingEvent handling.<br>
<br>
The returned value may be <code>null</code> should the PingEvent handling be cancelled at any point (i.e. due to an invalid protocol or because the <a href="../preserverlistsetevent/"><code>PreServerListSetEvent</code></a> has been cancelled).<br>
The values within the ProfileEntry also do not represent what is actually used within the Server list itself, but only the values provided for the PingEvent handling.
returns: 'Possibly-null ProfileEntry used for the PingEvent.'
attributes:
- nullable
type:
name: 'ProfileEntry'
type: 'object'
link: '../../../../api/ch.andre601.advancedserverlist.api/profiles/profileentry/'
---
# <api__class></api__class> PostServerListSetEvent
Called **after** the plugin has updated the Server List.
The provided [`ProfileEntry`](#getentry()) may be null due to the PingEvent handling being cancelled (i.e. due to a invalid protocol or due to the [`PreServerListSetEvent`](preserverlistsetevent.md) being cancelled).
The entry also only represents the values used during the PingEvent, not the actual content that is being displayed.
+51 -15
View File
@@ -58,18 +58,54 @@ All listed dependencies are optional.
## Pages
- [Getting started](getting-started/index.md)
- [Commands](commands/index.md)
- [Profiles](profiles/index.md)
- [Formatting](profiles/formatting.md)
- [Placeholders](profiles/placeholders.md)
- [Examples](examples/index.md)
- [Migration](migration/index.md)
- [v1.5.3 to v1.6.0](migration/v1_5_3-to-v1_6_0.md)
- [v1.9.0 to v1.10.0](migration/v1_9_0-to-v1_10_0.md)
- [API](api/index.md)
- [Changelog](api/changelog.md)
- [Javadocs](api/javadocs.md) (External site)
- [Source Code](api/source.md) (External site)
- [Reference](api/reference/index.md)
- [PlaceholderAPI](placeholderapi/index.md)
<div class="grid cards" markdown>
- [:octicons-milestone-24: **Getting Started**](getting-started/index.md)
----
A simple guide on how to get started with AdvancedServerList.
- [:octicons-rel-file-path-24: **Commands**](commands/index.md)
----
A list of all available commands in AdvancedServerList.
- [:octicons-note-24: **Profiles**](profiles/index.md)
----
Pages containing information about the Server List Profile System and all its available options.
- [:octicons-list-unordered-24: **Examples**](examples/index.md)
----
Collection of various profile examples to use for different situations.
- [:octicons-file-directory-symlink-24: **Migration**](migration/index.md)
----
Pages explaining how to migrate from one version of the plugin to another.
- [:octicons-command-palette-24: **API**](api/index.md)
----
Pages all about the API of AdvancedServerList.
- [:octicons-plus-circle-24: **Addons**](addons/index.md)
----
Pages listing 1st-party and 3rd-party add-ons for AdvancedServerList.
- [:material-percent: **PlaceholderAPI**](placeholderapi/index.md)
----
Information about available placeholders to use in PlaceholderAPI and how to use placeholders from other plugins in AdvancedServerList using PlaceholderAPI.
</div>
-7
View File
@@ -1,7 +0,0 @@
nav:
- index.md
- v3_8_0-to-v3_9_0.md
- v3_7_0-to-v3_8_0.md
- pre-v3_7_0-to-v3_7_0.md
- v1_9_0-to-v1_10_0.md
- v1_5_3-to-v1_6_0.md
+6
View File
@@ -12,6 +12,12 @@ Note that these pages only cover server list profile files. The config.yml is au
<div class="grid cards" markdown>
- [**v3.8.0 to v3.9.0**](v3_8_0-to-v3_9_0.md)
----
Migrate from version 3.8.0 to 3.9.0.
- [**v3.7.0 to v3.8.0**](v3_7_0-to-v3_8_0.md)
----
+4
View File
@@ -49,8 +49,12 @@ priority: 0
-conditions:
- - '${player protocol} >= 763'
- - '${player isWhitelisted} == true'
+# The text can all be in one line. This is only for better readability.
+condition: |
+ ${player protocol} >= 763 and
+ ${player isWhitelisted}
motd:
- 'Welcome ${player name}!'
```
///
+1 -1
View File
@@ -18,7 +18,7 @@ Here is a before and after example to help visualize the change:
```yaml
priority: 0
conditions: '${server host} <- "survival"'
condition: '${server host} <- "survival"'
motd:
- 'Welcome ${player name}!'
+1 -1
View File
@@ -18,7 +18,7 @@ Here is a before and after example to help visualize the change:
```yaml
priority: 0
conditions: '${player name} ~= "Someone"'
condition: '${player name} ~= "Someone"'
motd:
- 'Welcome ${player name}!'
+74 -3
View File
@@ -69,8 +69,6 @@ extra:
plugins:
- search
- glightbox
- awesome-pages:
filename: .pages.yml
- pagenav-generator
markdown_extensions:
@@ -107,4 +105,77 @@ markdown_extensions:
hooks:
- docs/.hooks/badges.py
- docs/.hooks/replacer.py
- docs/.hooks/replacer.py
nav:
- Home: index.md
- Getting Started: getting-started/index.md
- Commands: commands/index.md
- Profiles:
- profiles/index.md
- Expressions: profiles/expressions.md
- Formatting: profiles/formatting.md
- Placeholders: profiles/placeholders.md
- Examples: examples/index.md
- Migration:
- migration/index.md
- v3.8.0 to v3.9.0: migration/v3_8_0-to-v3_9_0.md
- v3.7.0 to v3.8.0: migration/v3_7_0-to-v3_8_0.md
- '< v3.7.0 to v3.7.0': migration/pre-v3_7_0-to-v3_7_0.md
- v1.9.0 to v1.10.0: migration/v1_9_0-to-v1_10_0.md
- v1.5.3 to v1.6.0: migration/v1_5_3-to-v1_6_0.md
- API:
- api/index.md
- Changelog: api/changelog.md
- Javadocs: api/javadocs.md
- Source Code: api/source.md
- Reference:
- api/reference/index.md
- api:
- api/reference/api/index.md
- ch.andre601.advancedserverlist.api:
- api/reference/api/ch.andre601.advancedserverlist.api/advancedserverlistapi.md
- api/reference/api/ch.andre601.advancedserverlist.api/placeholderprovider.md
- events:
- api/reference/api/ch.andre601.advancedserverlist.api/events/genericserverlistevent.md
- exceptions:
- api/reference/api/ch.andre601.advancedserverlist.api/exceptions/invalidplaceholderproviderexception.md
- objects:
- api/reference/api/ch.andre601.advancedserverlist.api/objects/genericplayer.md
- api/reference/api/ch.andre601.advancedserverlist.api/objects/genericserver.md
- api/reference/api/ch.andre601.advancedserverlist.api/objects/nullbool.md
- profiles:
- '<api__record></api__record> ProfileEntry':
- api/reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/index.md
- api/reference/api/ch.andre601.advancedserverlist.api/profiles/profileentry/builder.md
- platform-bukkit:
- api/reference/platform-bukkit/index.md
- ch.andre601.advancedserverlist.api.bukkit:
- events:
- api/reference/platform-bukkit/ch.andre601.advancedserverlist.api.bukkit/events/postserverlistsetevent.md
- api/reference/platform-bukkit/ch.andre601.advancedserverlist.api.bukkit/events/preserverlistsetevent.md
- objects:
- api/reference/platform-bukkit/ch.andre601.advancedserverlist.api.bukkit/objects/bukkitplayer.md
- api/reference/platform-bukkit/ch.andre601.advancedserverlist.api.bukkit/objects/bukkitserver.md
- platform-bungeecord:
- api/reference/platform-bungeecord/index.md
- ch.andre601.advancedserverlist.api.bungeecord:
- events:
- api/reference/platform-bungeecord/ch.andre601.advancedserverlist.api.bungeecord/events/postserverlistsetevent.md
- api/reference/platform-bungeecord/ch.andre601.advancedserverlist.api.bungeecord/events/preserverlistsetevent.md
- objects:
- api/reference/platform-bungeecord/ch.andre601.advancedserverlist.api.bungeecord/objects/bungeeplayer.md
- api/reference/platform-bungeecord/ch.andre601.advancedserverlist.api.bungeecord/objects/bungeeproxy.md
- platform-velocity:
- api/reference/platform-velocity/index.md
- ch.andre601.advancedserverlist.api.velocity:
- events:
- api/reference/platform-velocity/ch.andre601.advancedserverlist.api.velocity/events/postserverlistsetevent.md
- api/reference/platform-velocity/ch.andre601.advancedserverlist.api.velocity/events/preserverlistsetevent.md
- objects:
- api/reference/platform-velocity/ch.andre601.advancedserverlist.api.velocity/objects/velocityplayer.md
- api/reference/platform-velocity/ch.andre601.advancedserverlist.api.velocity/objects/velocityproxy.md
- Addons:
- addons/index.md
- BanPlugins: addons/banplugins.md
- PlaceholderAPI: placeholderapi/index.md
@@ -25,10 +25,13 @@
package ch.andre601.advancedserverlist.paper.listeners;
import ch.andre601.advancedserverlist.api.bukkit.events.PostServerListSetEvent;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.paper.PaperCore;
import com.destroystokyo.paper.event.server.PaperServerListPingEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
public class PingEvent implements Listener{
@@ -40,8 +43,10 @@ public class PingEvent implements Listener{
plugin.getServer().getPluginManager().registerEvents(this, plugin);
}
@EventHandler
@EventHandler(priority = EventPriority.HIGHEST) // Maintenance plugin has HIGHEST priority, so ASL needs too.
public void onPaperServerListPing(PaperServerListPingEvent event){
PingEventHandler.handleEvent(new PaperEventWrapper(plugin, event));
ProfileEntry entry = PingEventHandler.handleEvent(new PaperEventWrapper(plugin, event));
plugin.getServer().getPluginManager().callEvent(new PostServerListSetEvent(entry));
}
}
+2 -2
View File
@@ -37,10 +37,10 @@
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<plugin.version>4.4.0</plugin.version>
<plugin.version>4.6.0</plugin.version>
<plugin.description>Create multiple Server lists based on conditions.</plugin.description>
<api.version>3.2.1</api.version>
<api.version>3.3.0</api.version>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
-1
View File
@@ -1,4 +1,3 @@
mkdocs-material==9.5.13
mkdocs-glightbox==0.3.7
mkdocs-awesome-pages-plugin==2.9.2
git+https://github.com/Andre601/mkdocs-pagenav-generator
@@ -25,6 +25,8 @@
package ch.andre601.advancedserverlist.velocity.listeners;
import ch.andre601.advancedserverlist.api.profiles.ProfileEntry;
import ch.andre601.advancedserverlist.api.velocity.events.PostServerListSetEvent;
import ch.andre601.advancedserverlist.core.events.PingEventHandler;
import ch.andre601.advancedserverlist.velocity.VelocityCore;
import com.velocitypowered.api.event.PostOrder;
@@ -40,8 +42,10 @@ public class PingEvent{
plugin.getProxy().getEventManager().register(plugin, this);
}
@Subscribe(order = PostOrder.EARLY)
@Subscribe(order = PostOrder.LAST) // Maintenance has LAST priority, so ASL needs it too.
public void onProxyPing(ProxyPingEvent event){
PingEventHandler.handleEvent(new VelocityEventWrapper(plugin, event));
ProfileEntry entry = PingEventHandler.handleEvent(new VelocityEventWrapper(plugin, event));
plugin.getProxy().getEventManager().fire(new PostServerListSetEvent(entry));
}
}
@@ -35,7 +35,7 @@ public enum PlatformInfo{
"paper/target/AdvancedServerList-Paper-{{version}}.jar",
"addons/banplugins/target/AdvancedServerList-BanPlugins-Addon-{{version}}.jar"
),
"paper", "folia"
List.of("Paper", "Folia")
),
BUNGEECORD(
"bungeecord",
@@ -43,7 +43,7 @@ public enum PlatformInfo{
"bungeecord/target/AdvancedServerList-BungeeCord-{{version}}.jar",
"addons/banplugins/target/AdvancedServerList-BanPlugins-Addon-{{version}}.jar"
),
"bungeecord", "waterfall"
List.of("BungeeCord", "Waterfall")
),
VELOCITY(
"velocity",
@@ -51,17 +51,19 @@ public enum PlatformInfo{
"velocity/target/AdvancedServerList-Velocity-{{version}}.jar",
"addons/banplugins/target/AdvancedServerList-BanPlugins-Addon-{{version}}.jar"
),
"velocity"
List.of("Velocity")
);
private final String platform;
private final List<String> filePaths;
private final List<String> loaders;
private final List<String> platformNames;
PlatformInfo(String platform, List<String> filePaths, String... loaders){
PlatformInfo(String platform, List<String> filePaths, List<String> loaders){
this.platform = platform;
this.filePaths = filePaths;
this.loaders = List.of(loaders);
this.loaders = loaders.stream().map(String::toLowerCase).toList();
this.platformNames = loaders;
}
public String getPlatform(){
@@ -75,4 +77,8 @@ public enum PlatformInfo{
public List<String> getLoaders(){
return loaders;
}
public List<String> getPlatformNames(){
return platformNames;
}
}
@@ -25,18 +25,22 @@
package ch.andre601.advancedserverlist.versionuploader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class ModrinthRelease{
public class ReleaseHolder{
Map<String, String> releases = new HashMap<>();
private final List<ReleaseInfo> releases = new ArrayList<>();
public void addRelease(String platform, String id){
releases.put(platform, id);
public void addRelease(String type, String platform, String url){
releases.add(new ReleaseInfo(type, platform, url));
}
public Map<String, String> getReleases(){
public List<ReleaseInfo> getReleases(){
return releases;
}
record ReleaseInfo(String type, String platform, String url){}
}
@@ -40,8 +40,8 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.StringJoiner;
import java.util.concurrent.CompletableFuture;
public class VersionUploader{
@@ -53,7 +53,7 @@ public class VersionUploader{
if(args.length == 0){
LOGGER.warn("MISSING ARGUMENT!");
LOGGER.warn("COMMAND USAGE: java -jar VersionUploader.jar <--all|--modrinth|--hangar> [--dryrun]");
LOGGER.warn("COMMAND USAGE: java -jar VersionUploader.jar [--dryrun] --all | --modrinth | --hangar");
System.exit(1);
return;
}
@@ -72,22 +72,19 @@ public class VersionUploader{
}
CompletableFuture<?> future;
ModrinthRelease modrinthRelease = null;
ReleaseHolder releaseHolder = new ReleaseHolder();
switch(args[0].toLowerCase(Locale.ROOT)){
case "--modrinth" -> {
modrinthRelease = new ModrinthRelease();
future = new ModrinthVersionUploader().performUpload(release, modrinthRelease, dryrun);
}
case "--hangar" -> future = new HangarVersionUploader().performUpload(release, dryrun);
case "--modrinth" -> future = new ModrinthVersionUploader().performUpload(release, releaseHolder, dryrun);
case "--hangar" -> future = new HangarVersionUploader().performUpload(release, releaseHolder, dryrun);
case "--all" -> {
modrinthRelease = new ModrinthRelease();
future = CompletableFuture.allOf(
new ModrinthVersionUploader().performUpload(release, modrinthRelease, dryrun),
new HangarVersionUploader().performUpload(release, dryrun)
new ModrinthVersionUploader().performUpload(release, releaseHolder, dryrun),
new HangarVersionUploader().performUpload(release, releaseHolder, dryrun)
);
}
default -> {
LOGGER.warn("Unknown argument '{}' provided. Supported are '--all', '--modrinth' or '--hangar'", args[0]);
LOGGER.warn("Unknown argument '{}' provided.", args[0]);
LOGGER.warn("COMMAND USAGE: java -jar VersionUploader.jar [--dryrun] --all | --modrinth | --hangar");
System.exit(1);
return;
}
@@ -111,8 +108,8 @@ public class VersionUploader{
System.exit(1);
}
if(modrinthRelease == null || modrinthRelease.getReleases().isEmpty()){
LOGGER.warn("No Modrinth release info on Discord to share... Skipping.");
if(releaseHolder.getReleases().isEmpty()){
LOGGER.warn("No releases to share on Discord... Skipping.");
return;
}
@@ -124,17 +121,31 @@ public class VersionUploader{
WebhookEmbedBuilder builder = new WebhookEmbedBuilder()
.setTitle(new WebhookEmbed.EmbedTitle("New Release", null))
.setDescription("A new release of AdvancedServerList is available on Modrinth for you to download!")
.setDescription("A new release of AdvancedServerList is available on Modrinth and Hangar for you to download!")
.setColor(0x1BD96A);
for(Map.Entry<String, String> entry : modrinthRelease.getReleases().entrySet()){
builder.addField(new WebhookEmbed.EmbedField(
false,
entry.getKey(),
"https://modrinth.com/plugin/advancedserverlist/version/" + entry.getValue()
));
StringJoiner modrinthText = new StringJoiner("\n");
String hangarText = null;
for(ReleaseHolder.ReleaseInfo info : releaseHolder.getReleases()){
String text = String.format("[%s](%s)", info.platform(), info.url());
if(info.type().equalsIgnoreCase("modrinth")){
modrinthText.add(text);
}else{
hangarText = text;
}
}
builder.addField(new WebhookEmbed.EmbedField(
true,
"Modrinth:",
modrinthText.toString()
)).addField(new WebhookEmbed.EmbedField(
true,
"Hangar:",
hangarText == null ? "No download available" : hangarText
));
try(WebhookClient client = new WebhookClientBuilder(webhookUrl).build()){
CompletableFuture<ReadonlyMessage> webhookFuture = client.send(builder.build()).whenComplete((readonlyMessage, throwable) -> {
if(throwable != null){
@@ -26,6 +26,7 @@
package ch.andre601.advancedserverlist.versionuploader.hangar;
import ch.andre601.advancedserverlist.versionuploader.PlatformInfo;
import ch.andre601.advancedserverlist.versionuploader.ReleaseHolder;
import ch.andre601.advancedserverlist.versionuploader.VersionUploader;
import ch.andre601.advancedserverlist.versionuploader.data.CodebergRelease;
import ch.andre601.advancedserverlist.versionuploader.hangar.version.Dependency;
@@ -35,6 +36,7 @@ import ch.andre601.advancedserverlist.versionuploader.hangar.version.Version;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import org.apache.hc.client5.http.classic.HttpClient;
import org.apache.hc.client5.http.classic.methods.HttpPost;
import org.apache.hc.client5.http.entity.mime.FileBody;
@@ -72,7 +74,7 @@ public class HangarVersionUploader{
this.apiKey = System.getenv("HANGAR_API_TOKEN");
}
public CompletableFuture<?> performUpload(CodebergRelease release, boolean dryrun){
public CompletableFuture<?> performUpload(CodebergRelease release, ReleaseHolder releaseInfo, boolean dryrun){
LOGGER.info("Starting HangarVersionUploader...");
if((apiKey == null || apiKey.isEmpty()) && !dryrun){
@@ -145,14 +147,14 @@ public class HangarVersionUploader{
try{
HttpClient client = HttpClients.createDefault();
return uploadVersion(client, versionUpload, filePaths);
return uploadVersion(client, versionUpload, filePaths, releaseInfo);
}catch(ParseException | IOException ex){
LOGGER.warn("Encountered an exception while uploading to Hangar!", ex);
return CompletableFuture.completedFuture(ex);
}
}
private CompletableFuture<?> uploadVersion(HttpClient client, Version versionUpload, List<Path> filePaths) throws IOException, ParseException{
private CompletableFuture<?> uploadVersion(HttpClient client, Version versionUpload, List<Path> filePaths, ReleaseHolder releaseInfo) throws IOException, ParseException{
return CompletableFuture.supplyAsync(() -> {
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addPart("versionUpload", new StringBody(GSON.toJson(versionUpload), ContentType.APPLICATION_JSON));
@@ -174,7 +176,22 @@ public class HangarVersionUploader{
));
}
LOGGER.info("Successfully uploaded new release on Hangar!");
return true;
String body = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
try{
JsonObject json = GSON.fromJson(body, JsonObject.class);
if(json == null)
return true;
releaseInfo.addRelease(
"hangar",
"Paper, Waterfall, Velocity",
json.getAsJsonPrimitive("url").getAsString()
);
return true;
}catch(JsonSyntaxException ex){
return true;
}
});
}catch(IOException ex){
LOGGER.warn("Encountered IOException while perfoming upload.", ex);
@@ -25,7 +25,7 @@
package ch.andre601.advancedserverlist.versionuploader.modrinth;
import ch.andre601.advancedserverlist.versionuploader.ModrinthRelease;
import ch.andre601.advancedserverlist.versionuploader.ReleaseHolder;
import ch.andre601.advancedserverlist.versionuploader.PlatformInfo;
import ch.andre601.advancedserverlist.versionuploader.VersionUploader;
import ch.andre601.advancedserverlist.versionuploader.data.CodebergRelease;
@@ -45,7 +45,9 @@ import java.util.concurrent.CompletableFuture;
public class ModrinthVersionUploader{
private static final Logger LOGGER = LoggerFactory.getLogger(ModrinthVersionUploader.class);
private final Logger logger = LoggerFactory.getLogger(ModrinthVersionUploader.class);
private final String versionUrl = "https://modrinth.com/plugin/advancedserverlist/version/";
private final List<PlatformInfo> platforms = List.of(
PlatformInfo.PAPER,
@@ -62,11 +64,11 @@ public class ModrinthVersionUploader{
this.api = createClient();
}
public CompletableFuture<?> performUpload(CodebergRelease release, ModrinthRelease modrinthRelease, boolean dryrun){
LOGGER.info("Starting ModrinthVersionUploader...");
public CompletableFuture<?> performUpload(CodebergRelease release, ReleaseHolder releaseHolder, boolean dryrun){
logger.info("Starting ModrinthVersionUploader...");
if(api == null){
LOGGER.warn("Cannot create updates on Modrinth. API instance is null.");
logger.warn("Cannot create updates on Modrinth. API instance is null.");
return CompletableFuture.completedFuture(false);
}
@@ -74,7 +76,7 @@ public class ModrinthVersionUploader{
final String pluginVersion = VersionUploader.retrieveVersion();
if(pluginVersion == null || pluginVersion.isEmpty()){
LOGGER.warn("Retrieved null/empty plugin version.");
logger.warn("Retrieved null/empty plugin version.");
return CompletableFuture.completedFuture(false);
}
@@ -97,7 +99,7 @@ public class ModrinthVersionUploader{
);
for(int i = 0; i < platforms.size(); i++){
LOGGER.info("Creating release for platform {}...", platforms.get(i).getPlatform());
logger.info("Creating release for platform {}...", platforms.get(i).getPlatform());
List<File> files = platforms.get(i).getFilePaths().stream()
.map(path -> new File(path.replace("{{version}}", pluginVersion)))
@@ -125,7 +127,7 @@ public class ModrinthVersionUploader{
Gson gson = new GsonBuilder().setPrettyPrinting().create();
String json = gson.toJson(builder.build());
LOGGER.info("JSON Data to send: {}", json);
logger.info("JSON Data to send: {}", json);
futures[i] = CompletableFuture.completedFuture(json);
continue;
@@ -134,14 +136,20 @@ public class ModrinthVersionUploader{
final int index = i;
futures[i] = api.versions().createProjectVersion(builder.build()).whenComplete(((projectVersion, throwable) -> {
if(throwable != null){
LOGGER.warn("Encountered an exception while uploading a new release to Modrinth!", throwable);
logger.warn("Encountered an exception while uploading a new release to Modrinth!", throwable);
return;
}
LOGGER.info("Created new release!");
LOGGER.info("Link: https://modrinth.com/plugin/advancedserverlist/version/{}", projectVersion.getId());
String url = versionUrl + projectVersion.getId();
modrinthRelease.addRelease(String.join(", ", platforms.get(index).getLoaders()), projectVersion.getId());
logger.info("Created new release!");
logger.info("Link: {}", url);
releaseHolder.addRelease(
"modrinth",
String.join(", ", platforms.get(index).getPlatformNames()),
url
);
}));
}