mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2025-01-04 23:17:35 +01:00
- Move docs from src/tools to a root subfolder - Add tag for displaying a "generated page" footer - Create task to run all doc tasks - Remove map builder in favor of Guava's
This commit is contained in:
parent
76e7728b37
commit
7f3246e416
docs
src/tools
@ -1,12 +1,11 @@
|
||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||
<!-- File auto-generated on Sat Dec 26 14:05:00 CET 2015. See commands/commands.tpl.md -->
|
||||
<!-- File auto-generated on Sun Feb 14 19:00:30 CET 2016. See commands/commands.tpl.md -->
|
||||
|
||||
## AuthMe Commands
|
||||
You can use the following commands to use the features of AuthMe. Mandatory arguments are marked with `< >`
|
||||
brackets; optional arguments are enclosed in square brackets (`[ ]`).
|
||||
|
||||
- **/authme**: The main AuthMeReloaded command. The root for all admin commands.
|
||||
- **/authme help** [query]: View detailed help pages about AuthMeReloaded commands.
|
||||
- **/authme register** <player> <password>: Register the specified player with the specified password.
|
||||
<br />Requires `authme.admin.register`
|
||||
- **/authme unregister** <player>: Unregister the specified player.
|
||||
@ -19,9 +18,9 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
|
||||
<br />Requires `authme.admin.lastlogin`
|
||||
- **/authme accounts** [player]: Display all accounts of a player by his player name or IP.
|
||||
<br />Requires `authme.admin.accounts`
|
||||
- **/authme getemail** [player]: Display the email address of the specified player if set.
|
||||
- **/authme email** [player]: Display the email address of the specified player if set.
|
||||
<br />Requires `authme.admin.getemail`
|
||||
- **/authme chgemail** <player> <email>: Change the email address of the specified player.
|
||||
- **/authme setemail** <player> <email>: Change the email address of the specified player.
|
||||
<br />Requires `authme.admin.changemail`
|
||||
- **/authme getip** <player>: Get the IP address of the specified online player.
|
||||
<br />Requires `authme.admin.getip`
|
||||
@ -35,7 +34,7 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
|
||||
<br />Requires `authme.admin.setfirstspawn`
|
||||
- **/authme purge** <days>: Purge old AuthMeReloaded data longer than the specified amount of days ago.
|
||||
<br />Requires `authme.admin.purge`
|
||||
- **/authme resetpos** <player>: Purge the last know position of the specified player.
|
||||
- **/authme resetpos** <player/*>: Purge the last know position of the specified player or all of them.
|
||||
<br />Requires `authme.admin.purgelastpos`
|
||||
- **/authme purgebannedplayers**: Purge all AuthMeReloaded data for banned players.
|
||||
<br />Requires `authme.admin.purgebannedplayers`
|
||||
@ -44,33 +43,38 @@ brackets; optional arguments are enclosed in square brackets (`[ ]`).
|
||||
- **/authme reload**: Reload the AuthMeReloaded plugin.
|
||||
<br />Requires `authme.admin.reload`
|
||||
- **/authme version**: Show detailed information about the installed AuthMeReloaded version, the developers, contributors, and license.
|
||||
- **/authme help** [query]: View detailed help for /authme commands.
|
||||
- **/login** <password>: Command to log in using AuthMeReloaded.
|
||||
<br />Requires `authme.player.login`
|
||||
- **/login help** [query]: View detailed help pages about AuthMeReloaded login commands.
|
||||
- **/login help** [query]: View detailed help for /login commands.
|
||||
- **/logout**: Command to logout using AuthMeReloaded.
|
||||
<br />Requires `authme.player.logout`
|
||||
- **/logout help** [query]: View detailed help pages about AuthMeReloaded logout commands.
|
||||
- **/register** <password> [verifyPassword]: Command to register using AuthMeReloaded.
|
||||
- **/logout help** [query]: View detailed help for /logout commands.
|
||||
- **/register** [password] [verifyPassword]: Command to register using AuthMeReloaded.
|
||||
<br />Requires `authme.player.register`
|
||||
- **/register help** [query]: View detailed help pages about AuthMeReloaded register commands.
|
||||
- **/register help** [query]: View detailed help for /register commands.
|
||||
- **/unreg** <password>: Command to unregister using AuthMeReloaded.
|
||||
<br />Requires `authme.player.unregister`
|
||||
- **/unreg help** [query]: View detailed help pages about AuthMeReloaded unregister commands.
|
||||
- **/unreg help** [query]: View detailed help for /unreg commands.
|
||||
- **/changepassword** <oldPassword> <newPassword>: Command to change your password using AuthMeReloaded.
|
||||
<br />Requires `authme.player.changepassword`
|
||||
- **/changepassword help** [query]: View detailed help pages about AuthMeReloaded changepassword commands.
|
||||
- **/changepassword help** [query]: View detailed help for /changepassword commands.
|
||||
- **/email**: The AuthMeReloaded Email command base.
|
||||
- **/email help** [query]: View detailed help pages about AuthMeReloaded email commands.
|
||||
- **/email add** <email> <verifyEmail>: Add a new email address to your account.
|
||||
<br />Requires `authme.player.email.add`
|
||||
- **/email change** <oldEmail> <newEmail>: Change an email address of your account.
|
||||
<br />Requires `authme.player.email.change`
|
||||
- **/email recover** <email>: Recover your account using an Email address by sending a mail containing a new password.
|
||||
<br />Requires `authme.player.email.recover`
|
||||
- **/email help** [query]: View detailed help for /email commands.
|
||||
- **/captcha** <captcha>: Captcha command for AuthMeReloaded.
|
||||
<br />Requires `authme.player.captcha`
|
||||
- **/captcha help** [query]: View detailed help pages about AuthMeReloaded captcha commands.
|
||||
- **/captcha help** [query]: View detailed help for /captcha commands.
|
||||
- **/converter** <job>: Converter command for AuthMeReloaded.
|
||||
<br />Requires `authme.admin.converter`
|
||||
- **/converter help** [query]: View detailed help pages about AuthMeReloaded converter commands.
|
||||
- **/converter help** [query]: View detailed help for /converter commands.
|
||||
|
||||
|
||||
---
|
||||
|
||||
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Sun Feb 14 19:00:30 CET 2016
|
@ -1,5 +1,5 @@
|
||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||
<!-- File auto-generated on Thu Dec 31 13:41:44 CET 2015. See hashmethods/hash_algorithms.tpl.md -->
|
||||
<!-- File auto-generated on Sun Feb 14 19:00:32 CET 2016. See hashmethods/hash_algorithms.tpl.md -->
|
||||
|
||||
## Hash Algorithms
|
||||
AuthMe supports the following hash algorithms for storing your passwords safely.
|
||||
@ -12,6 +12,7 @@ BCRYPT2Y | Recommended | 60 | | | Text | 22 |
|
||||
CRAZYCRYPT1 | Do not use | 128 | | | Username | |
|
||||
DOUBLEMD5 | Do not use | 32 | | | None | |
|
||||
IPB3 | Acceptable | 32 | | | Text | 5 | Y
|
||||
IPB4 | Does not work | 60 | | | Text | 22 | Y
|
||||
JOOMLA | Recommended | 65 | | | Text | 32 |
|
||||
MD5 | Do not use | 32 | | | None | |
|
||||
MD5VB | Acceptable | 56 | | | Text | 16 |
|
||||
@ -27,11 +28,13 @@ SHA1 | Do not use | 40 | | | None | |
|
||||
SHA256 | Recommended | 86 | | | Text | 16 |
|
||||
SHA512 | Do not use | 128 | | | None | |
|
||||
SMF | Do not use | 40 | | | Username | |
|
||||
TWO_FACTOR | Does not work | 16 | | | None | |
|
||||
WBB3 | Acceptable | 40 | | | Text | 40 | Y
|
||||
WBB4 | Does not work | 60 | | | Text | 8 |
|
||||
WBB4 | Recommended | 60 | | | Text | 8 |
|
||||
WHIRLPOOL | Do not use | 128 | | | None | |
|
||||
WORDPRESS | Do not use | 34 | | | Text | 9 |
|
||||
WORDPRESS | Acceptable | 34 | | | Text | 9 |
|
||||
XAUTH | Recommended | 140 | | | Text | 12 |
|
||||
XFBCRYPT | | 60 | | | | |
|
||||
CUSTOM | | | | | | | |
|
||||
|
||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||
@ -76,3 +79,7 @@ If this column is empty when the salt type is "Text", it typically means the sal
|
||||
##### Separate
|
||||
If denoted with a **y**, it means that the salt is stored in a separate column in the database. This is neither good
|
||||
or bad.
|
||||
|
||||
---
|
||||
|
||||
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Sun Feb 14 19:00:32 CET 2016
|
@ -1,5 +1,5 @@
|
||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||
<!-- File auto-generated on Sun Feb 14 14:11:28 CET 2016. See permissions/permission_nodes.tpl.md -->
|
||||
<!-- File auto-generated on Sun Feb 14 19:00:34 CET 2016. See permissions/permission_nodes.tpl.md -->
|
||||
|
||||
## AuthMe Permission Nodes
|
||||
The following are the permission nodes that are currently supported by the latest dev builds.
|
||||
@ -42,3 +42,7 @@ The following are the permission nodes that are currently supported by the lates
|
||||
- **authme.player.unregister** – Command permission to unregister.
|
||||
- **authme.vip** – Permission node to identify VIP users.
|
||||
|
||||
|
||||
---
|
||||
|
||||
This page was automatically generated on the [AuthMe-Team/AuthMeReloaded repository](https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/) on Sun Feb 14 19:00:34 CET 2016
|
@ -5,9 +5,9 @@ import java.io.File;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Scanner;
|
||||
import java.util.TreeMap;
|
||||
|
||||
/**
|
||||
* Runner for executing tool tasks.
|
||||
@ -25,7 +25,7 @@ public final class ToolsRunner {
|
||||
public static void main(String... args) {
|
||||
// Collect tasks and show them
|
||||
File toolsFolder = new File(ToolsConstants.TOOLS_SOURCE_ROOT);
|
||||
Map<String, ToolTask> tasks = new HashMap<>();
|
||||
Map<String, ToolTask> tasks = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||
collectTasksInDirectory(toolsFolder, tasks);
|
||||
listAllTasks(tasks);
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
package commands;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import fr.xephi.authme.command.CommandArgumentDescription;
|
||||
import fr.xephi.authme.command.CommandDescription;
|
||||
import fr.xephi.authme.command.CommandInitializer;
|
||||
import fr.xephi.authme.command.CommandPermissions;
|
||||
import fr.xephi.authme.command.CommandUtils;
|
||||
import fr.xephi.authme.permission.PermissionNode;
|
||||
import utils.ANewMap;
|
||||
import utils.FileUtils;
|
||||
import utils.TagReplacer;
|
||||
import utils.ToolTask;
|
||||
@ -38,19 +38,18 @@ public class CommandPageCreater implements ToolTask {
|
||||
FileUtils.generateFileFromTemplate(
|
||||
ToolsConstants.TOOLS_SOURCE_ROOT + "commands/commands.tpl.md",
|
||||
OUTPUT_FILE,
|
||||
ANewMap.with("commands", commandsResult.toString()).build());
|
||||
ImmutableMap.of("commands", commandsResult.toString()));
|
||||
System.out.println("Wrote to '" + OUTPUT_FILE + "' with " + baseCommands.size() + " base commands.");
|
||||
}
|
||||
|
||||
private static void addCommandsInfo(StringBuilder sb, Collection<CommandDescription> commands,
|
||||
final String template) {
|
||||
for (CommandDescription command : commands) {
|
||||
Map<String, String> tags = ANewMap
|
||||
.with("command", CommandUtils.constructCommandPath(command))
|
||||
.and("description", command.getDetailedDescription())
|
||||
.and("arguments", formatArguments(command.getArguments()))
|
||||
.and("permissions", formatPermissions(command.getCommandPermissions()))
|
||||
.build();
|
||||
Map<String, String> tags = ImmutableMap.of(
|
||||
"command", CommandUtils.constructCommandPath(command),
|
||||
"description", command.getDetailedDescription(),
|
||||
"arguments", formatArguments(command.getArguments()),
|
||||
"permissions", formatPermissions(command.getCommandPermissions()));
|
||||
sb.append(TagReplacer.applyReplacements(template, tags));
|
||||
|
||||
if (!command.getChildren().isEmpty()) {
|
||||
|
@ -6,3 +6,5 @@ You can use the following commands to use the features of AuthMe. Mandatory argu
|
||||
brackets; optional arguments are enclosed in square brackets (`[ ]`).
|
||||
|
||||
{commands}
|
||||
|
||||
{gen_footer}
|
||||
|
46
src/tools/docs/UpdateDocsTask.java
Normal file
46
src/tools/docs/UpdateDocsTask.java
Normal file
@ -0,0 +1,46 @@
|
||||
package docs;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import commands.CommandPageCreater;
|
||||
import hashmethods.HashAlgorithmsDescriptionTask;
|
||||
import permissions.PermissionsListWriter;
|
||||
import utils.ToolTask;
|
||||
|
||||
import java.util.Scanner;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Task that runs all tasks which update files in the docs folder.
|
||||
*/
|
||||
public class UpdateDocsTask implements ToolTask {
|
||||
|
||||
private final Set<Class<? extends ToolTask>> TASKS = ImmutableSet.of(
|
||||
CommandPageCreater.class, HashAlgorithmsDescriptionTask.class, PermissionsListWriter.class);
|
||||
|
||||
@Override
|
||||
public String getTaskName() {
|
||||
return "updateDocs";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Scanner scanner) {
|
||||
for (Class<? extends ToolTask> taskClass : TASKS) {
|
||||
try {
|
||||
ToolTask task = instantiateTask(taskClass);
|
||||
System.out.println("\nRunning " + task.getTaskName() + "\n-------------------");
|
||||
task.execute(scanner);
|
||||
} catch (UnsupportedOperationException e) {
|
||||
System.err.println("Error running task of class '" + taskClass + "'");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static ToolTask instantiateTask(Class<? extends ToolTask> clazz) {
|
||||
try {
|
||||
return clazz.newInstance();
|
||||
} catch (IllegalAccessException | InstantiationException e) {
|
||||
throw new UnsupportedOperationException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -16,7 +16,7 @@ import java.util.Set;
|
||||
import static com.google.common.collect.Sets.newHashSet;
|
||||
|
||||
/**
|
||||
* Gathers information on {@link fr.xephi.authme.security.crypts.EncryptionMethod} implementations based on
|
||||
* Gathers information on {@link EncryptionMethod} implementations based on
|
||||
* the annotations in {@link fr.xephi.authme.security.crypts.description}.
|
||||
*/
|
||||
public class EncryptionMethodInfoGatherer {
|
||||
|
@ -1,9 +1,9 @@
|
||||
package hashmethods;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import utils.ANewMap;
|
||||
import utils.FileUtils;
|
||||
import utils.TagReplacer;
|
||||
import utils.ToolTask;
|
||||
@ -36,7 +36,7 @@ public class HashAlgorithmsDescriptionTask implements ToolTask {
|
||||
final String methodRows = constructMethodRows(descriptions);
|
||||
|
||||
// Write to the docs file
|
||||
Map<String, String> tags = ANewMap.with("method_rows", methodRows).build();
|
||||
Map<String, String> tags = ImmutableMap.of("method_rows", methodRows);
|
||||
FileUtils.generateFileFromTemplate(CUR_FOLDER + "hash_algorithms.tpl.md", OUTPUT_FILE, tags);
|
||||
}
|
||||
|
||||
@ -45,14 +45,14 @@ public class HashAlgorithmsDescriptionTask implements ToolTask {
|
||||
StringBuilder result = new StringBuilder();
|
||||
for (Map.Entry<HashAlgorithm, MethodDescription> entry : descriptions.entrySet()) {
|
||||
MethodDescription description = entry.getValue();
|
||||
Map<String, String> tags = ANewMap
|
||||
.with("name", asString(entry.getKey()))
|
||||
.and("recommendation", asString(description.getUsage()))
|
||||
.and("hash_length", asString(description.getHashLength()))
|
||||
.and("ascii_restricted", asString(description.isAsciiRestricted()))
|
||||
.and("salt_type", asString(description.getSaltType()))
|
||||
.and("salt_length", asString(description.getSaltLength()))
|
||||
.and("separate_salt", asString(description.hasSeparateSalt()))
|
||||
Map<String, String> tags = ImmutableMap.<String, String>builder()
|
||||
.put("name", asString(entry.getKey()))
|
||||
.put("recommendation", asString(description.getUsage()))
|
||||
.put("hash_length", asString(description.getHashLength()))
|
||||
.put("ascii_restricted", asString(description.isAsciiRestricted()))
|
||||
.put("salt_type", asString(description.getSaltType()))
|
||||
.put("salt_length", asString(description.getSaltLength()))
|
||||
.put("separate_salt", asString(description.hasSeparateSalt()))
|
||||
.build();
|
||||
result.append(TagReplacer.applyReplacements(rowTemplate, tags));
|
||||
}
|
||||
|
@ -51,3 +51,5 @@ If this column is empty when the salt type is "Text", it typically means the sal
|
||||
##### Separate
|
||||
If denoted with a **y**, it means that the salt is stored in a separate column in the database. This is neither good
|
||||
or bad.
|
||||
|
||||
{gen_footer}
|
||||
|
@ -1,6 +1,6 @@
|
||||
package permissions;
|
||||
|
||||
import utils.ANewMap;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import utils.FileUtils;
|
||||
import utils.TagReplacer;
|
||||
import utils.ToolTask;
|
||||
@ -31,8 +31,8 @@ public class PermissionsListWriter implements ToolTask {
|
||||
|
||||
boolean writeToFile = false;
|
||||
if (includeDescription) {
|
||||
System.out.println("Write to file? [Enter 'y' for yes]");
|
||||
writeToFile = matches("y", scanner);
|
||||
System.out.println("Write to file? [Enter 'n' for no]");
|
||||
writeToFile = !matches("n", scanner);
|
||||
}
|
||||
|
||||
if (!includeDescription) {
|
||||
@ -47,7 +47,7 @@ public class PermissionsListWriter implements ToolTask {
|
||||
private static void generateAndWriteFile() {
|
||||
final String permissionsTagValue = generatePermissionsList();
|
||||
|
||||
Map<String, String> tags = ANewMap.with("permissions", permissionsTagValue).build();
|
||||
Map<String, String> tags = ImmutableMap.of("permissions", permissionsTagValue);
|
||||
FileUtils.generateFileFromTemplate(
|
||||
ToolsConstants.TOOLS_SOURCE_ROOT + "permissions/permission_nodes.tpl.md", PERMISSIONS_OUTPUT_FILE, tags);
|
||||
System.out.println("Wrote to '" + PERMISSIONS_OUTPUT_FILE + "'");
|
||||
@ -62,10 +62,9 @@ public class PermissionsListWriter implements ToolTask {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
for (Map.Entry<String, String> entry : permissions.entrySet()) {
|
||||
Map<String, String> tags = ANewMap
|
||||
.with("node", entry.getKey())
|
||||
.and("description", entry.getValue())
|
||||
.build();
|
||||
Map<String, String> tags = ImmutableMap.of(
|
||||
"node", entry.getKey(),
|
||||
"description", entry.getValue());
|
||||
sb.append(TagReplacer.applyReplacements(template, tags));
|
||||
}
|
||||
return sb.toString();
|
||||
|
@ -5,3 +5,5 @@
|
||||
The following are the permission nodes that are currently supported by the latest dev builds.
|
||||
|
||||
{permissions}
|
||||
|
||||
{gen_footer}
|
||||
|
@ -1,36 +0,0 @@
|
||||
package utils;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* A map builder for the lazy.
|
||||
* <p />
|
||||
* Sample usage:
|
||||
* <code>
|
||||
* Map<String, Integer> map = ANewMap
|
||||
* .with("test", 123)
|
||||
* .and("text", 938)
|
||||
* .and("abc", 456)
|
||||
* .build();
|
||||
* </code>
|
||||
*/
|
||||
public class ANewMap<K, V> {
|
||||
|
||||
private Map<K, V> map = new HashMap<>();
|
||||
|
||||
public static <K, V> ANewMap<K, V> with(K key, V value) {
|
||||
ANewMap<K, V> instance = new ANewMap<>();
|
||||
return instance.and(key, value);
|
||||
}
|
||||
|
||||
public ANewMap<K, V> and(K key, V value) {
|
||||
map.put(key, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Map<K, V> build() {
|
||||
return map;
|
||||
}
|
||||
|
||||
}
|
@ -11,8 +11,10 @@ import java.util.regex.Pattern;
|
||||
* Class responsible for replacing template tags to actual content.
|
||||
* For all files, the following tags are defined:
|
||||
* <ul>
|
||||
* <li>{gen_date} – the generation date</li>
|
||||
* <li>{gen_date} – the generation date</li>
|
||||
* <li>{gen_warning} - warning not to edit the generated file directly</li>
|
||||
* <li>{gen_footer} - info footer with a link to the dev repo so users can find the most up-to-date
|
||||
* version (in case the page is viewed on a fork)</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class TagReplacer {
|
||||
@ -47,9 +49,13 @@ public class TagReplacer {
|
||||
* @return The filled template
|
||||
*/
|
||||
public static String applyReplacements(String template) {
|
||||
String curDate = new Date().toString();
|
||||
return template
|
||||
.replace("{gen_date}", new Date().toString())
|
||||
.replace("{gen_warning}", "AUTO-GENERATED FILE! Do not edit this directly");
|
||||
.replace("{gen_date}", curDate)
|
||||
.replace("{gen_warning}", "AUTO-GENERATED FILE! Do not edit this directly")
|
||||
.replace("{gen_footer}", "---\n\nThis page was automatically generated on the"
|
||||
+ " [AuthMe-Team/AuthMeReloaded repository](" + ToolsConstants.DOCS_FOLDER_URL + ")"
|
||||
+ " on " + curDate);
|
||||
}
|
||||
|
||||
private static String replaceOptionalTag(String text, String tagName, String tagValue) {
|
||||
|
@ -14,6 +14,8 @@ public final class ToolsConstants {
|
||||
|
||||
public static final String TOOLS_SOURCE_ROOT = "src/tools/";
|
||||
|
||||
public static final String DOCS_FOLDER = TOOLS_SOURCE_ROOT + "docs/";
|
||||
public static final String DOCS_FOLDER = "docs/";
|
||||
|
||||
public static final String DOCS_FOLDER_URL = "https://github.com/AuthMe-Team/AuthMeReloaded/tree/master/docs/";
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user