Skip to content
This repository has been archived by the owner on Apr 9, 2024. It is now read-only.

Commit

Permalink
Merge pull request #38 from Andre601/feature/add-api
Browse files Browse the repository at this point in the history
Start with an API for custom placeholder support
  • Loading branch information
Andre601 authored Jan 23, 2023
2 parents 3f6ada4 + 125e9c0 commit 29c6930
Show file tree
Hide file tree
Showing 50 changed files with 1,997 additions and 287 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/docs-deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
name: Deploy Site

on:
push:
paths:
- 'docs/**'
- 'mkdocs.yml'
branches:
- master
tags-ignore:
- '**'

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Python 3.7
uses: actions/setup-python@v4
with:
python-version: 3.7
- name: Install dependencies
run: |
python -m pip install --upgrade pip setuptools
python -m pip install -r requirements.txt
- name: Deploy Files
run: |
git config user.name "github-actions[bot]"
git config user.email "[email protected]"
mkdocs gh-deploy --force
59 changes: 59 additions & 0 deletions api/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
~ MIT License
~
~ Copyright (c) 2022-2023 Andre_601
~
~ Permission is hereby granted, free of charge, to any person obtaining a copy
~ of this software and associated documentation files (the "Software"), to deal
~ in the Software without restriction, including without limitation the rights
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
~ copies of the Software, and to permit persons to whom the Software is
~ furnished to do so, subject to the following conditions:
~
~ The above copyright notice and this permission notice shall be included in all
~ copies or substantial portions of the Software.
~
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
~ SOFTWARE.
~
-->

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>parent</artifactId>
<groupId>ch.andre601.advancedserverlist</groupId>
<version>parent</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>api</artifactId>
<packaging>jar</packaging>
<version>${plugin.version}</version>
<description>${plugin.description}</description>

<properties>
<maven.compiler.source>16</maven.compiler.source>
<maven.compiler.target>16</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<build>
<finalName>AdvancedServerList-API-${plugin.version}</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.1</version>
</plugin>
</plugins>
</build>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* 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.api;

import ch.andre601.advancedserverlist.api.internal.CheckUtil;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
* Core class of the API for AdvancedServerList.
* <br>Use {@link #get() get()} to retrieve the instance currently used.
*/
public class AdvancedServerListAPI{

private static AdvancedServerListAPI instance;
private final Map<String, PlaceholderProvider> placeholderProviders = new HashMap<>();

private AdvancedServerListAPI(){}

/**
* Retrieves the instance used of this API.
* <br>If no instance has been made so far will a new one be created.
*
* @return Instance of this API.
*/
public static AdvancedServerListAPI get(){
if(instance != null)
return instance;

return (instance = new AdvancedServerListAPI());
}

/**
* Adds the provided {@link PlaceholderProvider PlaceholderProvider} to the list, if it passes the following checks:
* <ul>
* <li>The identifier is not null or empty.</li>
* <li>The identifier does not contain any spaces.</li>
* <li>A PlaceholderProvider with the same identifier doesn't exist already.</li>
* </ul>
* Not passing any of the above checks results in a
* {@link ch.andre601.advancedserverlist.api.exceptions.InvalidPlaceholderProviderException InvalidPlaceholderProviderException}
* being thrown.
*
* @param placeholderProvider
* The {@link PlaceholderProvider PlaceholderProvider} to add.
*
* @throws ch.andre601.advancedserverlist.api.exceptions.InvalidPlaceholderProviderException
* When the provided {@link PlaceholderProvider PlaceholderProvider instance} has a null or empty identifier,
* the identifier contains spaces or another provider with the same identifier is already loaded.
*/
public void addPlaceholderProvider(PlaceholderProvider placeholderProvider){
CheckUtil.notEmpty(placeholderProvider.getIdentifier(), "Identifier");

String identifier = placeholderProvider.getIdentifier().toLowerCase(Locale.ROOT);
CheckUtil.check(identifier.contains(" "), "Identifier may not contain spaces.");
CheckUtil.check(placeholderProviders.containsKey(identifier), "A PlaceholderProvider with name " + identifier + " already exists.");

placeholderProviders.put(identifier, placeholderProvider);
}

/**
* Retrieves the {@link PlaceholderProvider PlaceholderProvider} associated with the given identifier, or {@code null}
* should no such entry exist.
*
* @param identifier
* The identifier to find a matching {@link PlaceholderProvider PlaceholderProvider} for.
*
* @return Possibly-null {@link PlaceholderProvider PlaceholderProvider instance}.
*/
public PlaceholderProvider retrievePlaceholderProvider(String identifier){
return placeholderProviders.get(identifier.toLowerCase(Locale.ROOT));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* 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.api;

import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;

/**
* Abstract class that is used to provide your own Placeholder patterns for AdvancedServerList to parse.
*
* <p>In order for your class to be considered a valid PlaceholderProvider will you need to set the
* {@link #identifier identifier} to a non-null, non-empty value without having any spaces in it.
* <br>Once set, use {@link ch.andre601.advancedserverlist.api.AdvancedServerListAPI#addPlaceholderProvider(PlaceholderProvider) AdvancedServerListAPI#addPlaceholderProvider(PlaceholderProvider)}
* to register your class for AdvancedServerList to use.
*/
public abstract class PlaceholderProvider{

private final String identifier;

/**
* Constructor used to set the identifier for the class extending the PlaceholderProvider class.
*
* <h2>Example</h2>
* <pre>{@code
* public class MyPlaceholders extends PlaceholderProvider {
*
* public MyPlaceholders() {
* super("myplaceholders");
* }
*
* @Override
* public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server) {
* if(placeholder.equals("hello")
* return "Hi!";
*
* return null;
* }
* }
* }</pre>
*
* @param identifier
* The identifier to use for the placeholder. Shouldn't be null nor empty.
*/
public PlaceholderProvider(String identifier){
this.identifier = identifier;
}

/**
* Method called by AdvancedServerList's StringReplacer class to replace any appearances of
* {@code ${<identifier> <placeholder>}} with whatever value a PlaceholderProvider may return.
*
* <p>Returning {@code null} will be treated as an invalid placeholder, returning the full placeholder as-is without
* any changes made.
*
* @param placeholder
* The part of the placeholder after the identifier ({@code ${<identifier> <placeholder>}}
* @param player
* The {@link GenericPlayer GenericPlayer instance} used.
* @param server
* The {@link GenericServer GenericServer instance} used.
*
* @return Parsed String based on the PlaceholderProvider or {@code null} for invalid placeholders.
*/
public abstract String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server);

/**
* Returns the identifier used by this instance.
*
* @return String containing the identifier used by this instance.
*/
public String getIdentifier(){
return identifier;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@
*
*/

package ch.andre601.advancedserverlist.core.profiles.replacer.placeholders;
package ch.andre601.advancedserverlist.api.exceptions;

import java.util.Map;

public interface Placeholders{
/**
* RuntimeException thrown whenever an invalid {@link ch.andre601.advancedserverlist.api.PlaceholderProvider PlaceholderProvider}
* has been given.
*/
public class InvalidPlaceholderProviderException extends RuntimeException{

Map<String, Object> getReplacements();
public InvalidPlaceholderProviderException(String msg){
super(msg);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,18 @@
*
*/

package ch.andre601.advancedserverlist.core.interfaces.core;
package ch.andre601.advancedserverlist.api.internal;

import ch.andre601.advancedserverlist.core.profiles.replacer.placeholders.Placeholders;
import ch.andre601.advancedserverlist.api.exceptions.InvalidPlaceholderProviderException;

import java.util.List;

public interface ProxyCore<F, P> extends PluginCore<F>{
List<P> createPlayers(List<String> lines, Placeholders... placeholders);
public class CheckUtil{

public static void notEmpty(String text, String name){
check(text == null || text.isEmpty(), name + " may not be null or empty.");
}

public static void check(boolean condition, String msg){
if(condition)
throw new InvalidPlaceholderProviderException(msg);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,25 +23,25 @@
*
*/

package ch.andre601.advancedserverlist.core.profiles.replacer.placeholders;
package ch.andre601.advancedserverlist.api.internal;

import java.util.HashMap;
import java.util.Map;
import ch.andre601.advancedserverlist.api.PlaceholderProvider;
import ch.andre601.advancedserverlist.api.objects.GenericPlayer;
import ch.andre601.advancedserverlist.api.objects.GenericServer;

public class ServerPlaceholders implements Placeholders{
public class ServerPlaceholders extends PlaceholderProvider{

private final Map<String, Object> replacements = new HashMap<>();

public ServerPlaceholders(int online, int max, String host){
this.replacements.put("${server playersOnline}", online);
this.replacements.put("${server playersMax}", max);

if(host != null)
this.replacements.put("${server host}", host);
public ServerPlaceholders(){
super("server");
}

@Override
public Map<String, Object> getReplacements(){
return this.replacements;
public String parsePlaceholder(String placeholder, GenericPlayer player, GenericServer server){
return switch(placeholder){
case "playersOnline" -> String.valueOf(server.getPlayersOnline());
case "playersMax" -> String.valueOf(server.getPlayersMax());
case "host" -> server.getHost();
default -> null;
};
}
}
Loading

0 comments on commit 29c6930

Please sign in to comment.