Rewrite Pterodactyl integration (#86)

* Update Command_ride.java

* ok, done (FS-156)

* Fixes FS-137

* grammar fix

* Remove a number of wipe commands we don't want anyway

We shouldn't be wiping any of this data within the server now anyway so let's not tempt fate again.

* Why overcomplicating things is a horrifically bad idea (#55)

The longer I look into this plugin's code, the angrier I will become.

This fixes 2 bugs in the /potion command:
- Fixes non-admins being able to clear other players
- Fixes NPE caused when trying to add potion effects to players who are not on the server as a non-admin.

Both of these issues are caused by overcomplicating seemingly simple solutions, hence the name of this commit.

Co-authored-by: Ryan <Wild1145@users.noreply.github.com>
Co-authored-by: Nathan Curran <30569566+Focusvity@users.noreply.github.com>

* Bug fixes, improvements, and removals (FS-192) (#46)

* Three fixes

* Fixes /tempban throwing a NullPointerException when trying to get a player who isn't on the server but was in the past
* Fixes /tempban banning players for 24 hours regardless of the duration defined
* Fixes /list -t throwing a NullPointerException when performed from a non-player source (such as Telnet)

* Removes hubworld entriely

* Configurable blacklists for tag, muted commands, and wildcard

Changes:
* Moves globally blocked commands to the `global` subsection of the original `blocked_commands` section. You *will* need to update your configurations
* /wildcard's command blacklist is now configurable under the `wildcard` section in `blocked_commands`.
* The commands muted players can't use are now configurable under the `muted` section in `blocked_commands`.
* Removes some commented-out globally blocked command entries.

Co-authored-by: Ryan <Wild1145@users.noreply.github.com>

* Switched from -c to -ci (#63)

Resolves FS-219

* Added new dependency to allow TFM to compile (#65)

* Name change for Fleek (#64)

* Add //g to blocked commands (#62)

Co-authored-by: Nathan Curran <30569566+Focusvity@users.noreply.github.com>

* Small modification to new TFGuilds (FS-255) (#67)

* Calculate the player count without offline players (FS-247) (#68)

Co-authored-by: Ryan <Wild1145@users.noreply.github.com>

* Use long instead of int and use offset to check time (FS-181) (#69)

* Use long instead of int and use offset to check time (FS-181)

* Remove star import

* Addresses FS-224 (#70)

* Bump version

* TotalFreedomMod May Update

* Retired support for 2021.02 fully. (#72)

* Rewrite Pterodactyl integration

- Rewrite Pterodactyl integration
- Bring back the restart command and fix the stop command to gracefully stop the server now
- I had to update for Java 16, sorry. I can't get it to compile on 11 anymore anyway

* Codacy

* Actually document how you set it up

Also, rename server key to client key. That was from the old API, renamed it to be consistent with 1.x API

* Be even clearer

* Update Command_restart.java

* Update pom.xml

Co-authored-by: Video <videogamesm12@gmail.com>
Co-authored-by: Elmon11 <elmon11bussiness@gmail.com>
Co-authored-by: Ryan <Wild1145@users.noreply.github.com>
Co-authored-by: Nathan Curran <30569566+Focusvity@users.noreply.github.com>
This commit is contained in:
Telesphoreo 2021-06-29 03:28:30 -07:00 committed by GitHub
parent f57fc56f4a
commit d88509bf11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 176 additions and 174 deletions

View File

@ -19,13 +19,13 @@ These versions are no longer under active development, however we will look to r
| Version | Supported | Support End: | | Version | Supported | Support End: |
| ------------------- | ------------------ | ------------ | | ------------------- | ------------------ | ------------ |
| 2021.04 | :white_check_mark: | July 2021 | | 2021.04 | :white_check_mark: | July 2021 |
| 2021.02 | :white_check_mark: | June 2021 |
### No Longer Supported ### No Longer Supported
These versions are no longer supported at all. It is strongly advised to update if you are running any of these versions. These versions are no longer supported at all. It is strongly advised to update if you are running any of these versions.
| Version | Supported | Support Ended: | | Version | Supported | Support Ended: |
| ------------------- | ------------------ | ------------------- | | ------------------- | ------------------ | ------------------- |
| 2021.02 | :x: | 6 June 2021 |
| 2020.11 | :x: | 3 May 2021 | | 2020.11 | :x: | 3 May 2021 |
| 6.0.x (Pre-Release) | :x: | December 2020 | | 6.0.x (Pre-Release) | :x: | December 2020 |
| < 2020.11 | :x: | December 2020 | | < 2020.11 | :x: | December 2020 |

44
pom.xml
View File

@ -5,7 +5,7 @@
<groupId>me.totalfreedom</groupId> <groupId>me.totalfreedom</groupId>
<artifactId>TotalFreedomMod</artifactId> <artifactId>TotalFreedomMod</artifactId>
<version>2021.04</version> <version>2021.05</version>
<packaging>jar</packaging> <packaging>jar</packaging>
<properties> <properties>
@ -39,6 +39,11 @@
</scm> </scm>
<repositories> <repositories>
<repository>
<id>apache-snapshots</id>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
</repository>
<repository> <repository>
<id>jitpack.io</id> <id>jitpack.io</id>
<url>https://jitpack.io</url> <url>https://jitpack.io</url>
@ -109,6 +114,11 @@
<id>ess-repo</id> <id>ess-repo</id>
<url>https://ci.ender.zone/plugin/repository/everything/</url> <url>https://ci.ender.zone/plugin/repository/everything/</url>
</repository> </repository>
<repository>
<id>mattmalec-repo</id>
<url>https://repo.mattmalec.com/repository/releases</url>
</repository>
</repositories> </repositories>
<dependencies> <dependencies>
@ -144,7 +154,7 @@
<dependency> <dependency>
<groupId>org.bstats</groupId> <groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId> <artifactId>bstats-bukkit</artifactId>
<version>1.8</version> <version>2.2.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
@ -186,21 +196,21 @@
<dependency> <dependency>
<groupId>net.dv8tion</groupId> <groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId> <artifactId>JDA</artifactId>
<version>4.2.1_255</version> <version>4.3.0_277</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>net.coreprotect</groupId> <groupId>net.coreprotect</groupId>
<artifactId>coreprotect</artifactId> <artifactId>coreprotect</artifactId>
<version>19.3</version> <version>19.5</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.sk89q.worldguard</groupId> <groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId> <artifactId>worldguard-bukkit</artifactId>
<version>7.0.4</version> <version>7.0.5</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
@ -259,12 +269,26 @@
<version>3.1.1</version> <version>3.1.1</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.mattmalec</groupId>
<artifactId>Pterodactyl4J</artifactId>
<version>2.BETA_47</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.3.0-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.junit.jupiter</groupId> <groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId> <artifactId>junit-jupiter</artifactId>
<version>5.4.2</version> <version>5.4.2</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipse.sisu</groupId> <groupId>org.eclipse.sisu</groupId>
<artifactId>org.eclipse.sisu.inject</artifactId> <artifactId>org.eclipse.sisu.inject</artifactId>
@ -299,7 +323,7 @@
<plugin> <plugin>
<groupId>pl.project13.maven</groupId> <groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId> <artifactId>git-commit-id-plugin</artifactId>
<version>4.0.2</version> <version>4.0.5</version>
<executions> <executions>
<execution> <execution>
<id>get-the-git-infos</id> <id>get-the-git-infos</id>
@ -412,10 +436,12 @@
</plugin> </plugin>
<!-- Shade --> <!-- Shade -->
<!-- NOTE: This should only be temporary. This will need to be updated when a stable build comes out
that supports Java 16 -->
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId> <artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version> <version>3.3.0-SNAPSHOT</version>
<executions> <executions>
<execution> <execution>
<phase>package</phase> <phase>package</phase>
@ -427,8 +453,7 @@
<relocations> <relocations>
<relocation> <relocation>
<pattern>io.papermc.lib</pattern> <pattern>io.papermc.lib</pattern>
<shadedPattern>me.totalfreedom.totalfreedommod.paperlib <shadedPattern>me.totalfreedom.totalfreedommod.paperlib</shadedPattern>
</shadedPattern> <!-- Replace this -->
</relocation> </relocation>
<relocation> <relocation>
<pattern>org.bstats</pattern> <pattern>org.bstats</pattern>
@ -446,6 +471,7 @@
<include>com.github.speedxx:Mojangson</include> <include>com.github.speedxx:Mojangson</include>
<include>org.bstats:bstats-bukkit</include> <include>org.bstats:bstats-bukkit</include>
<include>org.jetbrains:annotations</include> <include>org.jetbrains:annotations</include>
<include>com.mattmalec:Pterodactyl4J</include>
</includes> </includes>
</artifactSet> </artifactSet>
</configuration> </configuration>

View File

@ -1,26 +1,30 @@
package me.totalfreedom.totalfreedommod; package me.totalfreedom.totalfreedommod;
import java.io.IOException; import com.mattmalec.pterodactyl4j.Permission;
import java.util.Arrays; import com.mattmalec.pterodactyl4j.PowerAction;
import java.util.List; import com.mattmalec.pterodactyl4j.PteroAction;
import com.mattmalec.pterodactyl4j.PteroBuilder;
import com.mattmalec.pterodactyl4j.application.entities.ApplicationUser;
import com.mattmalec.pterodactyl4j.application.entities.PteroApplication;
import com.mattmalec.pterodactyl4j.application.managers.UserAction;
import com.mattmalec.pterodactyl4j.client.entities.ClientServer;
import com.mattmalec.pterodactyl4j.client.entities.ClientSubuser;
import com.mattmalec.pterodactyl4j.client.entities.PteroClient;
import joptsimple.internal.Strings; import joptsimple.internal.Strings;
import me.totalfreedom.totalfreedommod.admin.Admin; import me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.config.ConfigEntry; import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank; import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FLog; import me.totalfreedom.totalfreedommod.util.FLog;
import me.totalfreedom.totalfreedommod.util.FUtil;
import me.totalfreedom.totalfreedommod.util.Response;
import org.json.simple.JSONObject;
import org.json.simple.parser.ParseException;
public class Pterodactyl extends FreedomService public class Pterodactyl extends FreedomService
{ {
public final String URL = ConfigEntry.PTERO_URL.getString(); public final String URL = ConfigEntry.PTERO_URL.getString();
private final String SERVER_KEY = ConfigEntry.PTERO_SERVER_KEY.getString();
private final String ADMIN_KEY = ConfigEntry.PTERO_ADMIN_KEY.getString(); private final String ADMIN_KEY = ConfigEntry.PTERO_ADMIN_KEY.getString();
private final List<String> SERVER_HEADERS = Arrays.asList("Accept:Application/vnd.pterodactyl.v1+json", "Content-Type:application/json", "Authorization:Bearer " + SERVER_KEY); private final String CLIENT_KEY = ConfigEntry.PTERO_CLIENT_KEY.getString();
private final List<String> ADMIN_HEADERS = Arrays.asList("Accept:Application/vnd.pterodactyl.v1+json", "Content-Type:application/json", "Authorization:Bearer " + ADMIN_KEY); private final String IDENTIFIER = ConfigEntry.PTERO_SERVER_UUID.getString();
private final PteroApplication adminAPI = PteroBuilder.createApplication(URL, ADMIN_KEY);
private final PteroClient clientAPI = PteroBuilder.createClient(URL, CLIENT_KEY);
private final ClientServer server = clientAPI.retrieveServerByIdentifier(IDENTIFIER).execute();
private boolean enabled = !Strings.isNullOrEmpty(URL); private boolean enabled = !Strings.isNullOrEmpty(URL);
@ -43,163 +47,60 @@ public class Pterodactyl extends FreedomService
if (!admin.isActive() || admin.getRank() != Rank.SENIOR_ADMIN) if (!admin.isActive() || admin.getRank() != Rank.SENIOR_ADMIN)
{ {
FLog.debug("Disabling ptero acc"); FLog.debug("Disabling Pterodactyl account");
removeAccountFromServer(id); removeAccountFromServer(id);
return; return;
} }
FLog.debug("Enabling ptero acc"); FLog.debug("Enabling Pterodactyl account");
addAccountToServer(id); addAccountToServer(id);
} }
@SuppressWarnings("unchecked")
public String createAccount(String username, String password) public String createAccount(String username, String password)
{ {
JSONObject json = new JSONObject(); UserAction action = adminAPI.getUserManager().createUser()
json.put("username", username); .setUserName(username)
json.put("password", password); .setEmail(username.toLowerCase() + "@" + ConfigEntry.PTERO_DEFAULT_EMAIL_DOMAIN.getString())
json.put("email", username.toLowerCase() + "@" + ConfigEntry.PTERO_DEFAULT_EMAIL_DOMAIN.getString()); .setFirstName(username)
json.put("first_name", username); .setLastName("\u200E") // Required - make it appear empty
json.put("last_name", "\u200E"); // required, so I made it appear empty .setPassword(password);
Response response; return action.execute().getId();
JSONObject jsonResponse;
try
{
response = FUtil.sendRequest(URL + "/api/application/users", "POST", ADMIN_HEADERS, json.toJSONString());
jsonResponse = response.getJSONMessage();
}
catch (IOException | ParseException e)
{
FLog.severe(e);
return null;
} }
return ((JSONObject)jsonResponse.get("attributes")).get("id").toString(); public void deleteAccount(String id)
{
ApplicationUser username = adminAPI.retrieveUserById(id).execute();
PteroAction<Void> action = adminAPI.getUserManager().deleteUser(username);
action.execute();
} }
public boolean deleteAccount(String id)
{
JSONObject json = new JSONObject();
try
{
return FUtil.sendRequest(URL + "/api/application/users/" + id, "DELETE", ADMIN_HEADERS, json.toJSONString()).getCode() == 204;
}
catch (IOException e)
{
FLog.severe(e);
return false;
}
}
@SuppressWarnings("unchecked")
public void addAccountToServer(String id) public void addAccountToServer(String id)
{ {
String url = URL + "/api/client/servers/" + ConfigEntry.PTERO_SERVER_UUID.getString() + "/users"; ApplicationUser username = adminAPI.retrieveUserById(id).execute();
String email = username.getEmail();
JSONObject userData = getUserData(id); PteroAction<ClientServer> server = clientAPI.retrieveServerByIdentifier(IDENTIFIER);
if (userData == null) server.execute().getSubuserManager().createUser()
{ .setEmail(email)
FLog.severe("The Pterodactyl user with the ID of " + id + " was not found"); .setPermissions(Permission.CONTROL_PERMISSIONS).execute();
return;
}
JSONObject json = new JSONObject();
json.put("email", userData.get("email").toString());
json.put("permissions", Arrays.asList("control.console", "control.start", "control.restart", "control.stop", "control.kill"));
try
{
FUtil.sendRequest(url, "POST", SERVER_HEADERS, json.toJSONString());
}
catch (IOException e)
{
FLog.severe(e);
}
} }
public void removeAccountFromServer(String id) public void removeAccountFromServer(String id)
{ {
JSONObject userData = getUserData(id); ApplicationUser username = adminAPI.retrieveUserById(id).execute();
if (userData == null) PteroAction<ClientServer> server = clientAPI.retrieveServerByIdentifier(IDENTIFIER);
{ ClientSubuser clientSubuser = server.execute().getSubuser(username.getUUID()).retrieve().execute();
FLog.severe("The Pterodactyl user with the ID of " + id + " was not found"); server.execute().getSubuserManager().deleteUser(clientSubuser).execute();
return;
} }
String url = URL + "/api/client/servers/" + ConfigEntry.PTERO_SERVER_UUID.getString() + "/users/" + userData.get("uuid"); public void stopServer()
try
{ {
FUtil.sendRequest(url, "DELETE", SERVER_HEADERS, null); clientAPI.setPower(server, PowerAction.STOP).execute();
}
catch (IOException e)
{
FLog.severe(e);
}
} }
public JSONObject getUserData(String id) public void restartServer()
{ {
Response response; clientAPI.setPower(server, PowerAction.RESTART).execute();
JSONObject jsonResponse;
try
{
response = FUtil.sendRequest(URL + "/api/application/users/" + id, "GET", ADMIN_HEADERS, null);
jsonResponse = response.getJSONMessage();
}
catch (IOException | ParseException e)
{
FLog.severe(e);
return null;
}
return (JSONObject)jsonResponse.get("attributes");
}
// API patch function on users doesnt work rn, it throws 500 errors, so it's probably not written yet
@SuppressWarnings("unchecked")
public void setPassword(String id, String password)
{
JSONObject json = new JSONObject();
json.put("password", password);
try
{
FUtil.sendRequest(URL + "/api/application/users/" + id, "PATCH", ADMIN_HEADERS, json.toJSONString());
}
catch (IOException e)
{
FLog.severe(e);
}
}
public String getURL()
{
return URL;
}
public String getServerKey()
{
return SERVER_KEY;
}
public String getAdminKey()
{
return ADMIN_KEY;
}
public List<String> getServerHeaders()
{
return SERVER_HEADERS;
}
public List<String> getAdminHeaders()
{
return ADMIN_HEADERS;
} }
public boolean isEnabled() public boolean isEnabled()

View File

@ -17,11 +17,9 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Manage your Pterodactyl panel account", usage = "/<command> <create | delete>") @CommandParameters(description = "Manage your Pterodactyl panel account", usage = "/<command> <create | delete>")
public class Command_panel extends FreedomCommand public class Command_panel extends FreedomCommand
{ {
@Override @Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{ {
if (!plugin.ptero.isEnabled()) if (!plugin.ptero.isEnabled())
{ {
msg("Pterodactyl integration is currently disabled.", ChatColor.RED); msg("Pterodactyl integration is currently disabled.", ChatColor.RED);
@ -32,7 +30,7 @@ public class Command_panel extends FreedomCommand
if (playerData.getDiscordID() == null) if (playerData.getDiscordID() == null)
{ {
msg("You must have a linked discord account.", ChatColor.RED); msg("You must have a linked Discord account.", ChatColor.RED);
return true; return true;
} }
@ -63,13 +61,11 @@ public class Command_panel extends FreedomCommand
} }
plugin.ptero.addAccountToServer(id); plugin.ptero.addAccountToServer(id);
admin.setPteroID(id); admin.setPteroID(id);
plugin.al.save(admin); plugin.al.save(admin);
plugin.al.updateTables(); plugin.al.updateTables();
plugin.dc.sendPteroInfo(playerData, username, password); plugin.dc.sendPteroInfo(playerData, username, password);
msg("Successfully created your Pterodactyl account. Check your DMs from " + plugin.dc.formatBotTag() + " on discord to get your credentials.", ChatColor.GREEN); msg("Successfully created your Pterodactyl account. Check your DMs from " + plugin.dc.formatBotTag() + " on Discord to get your credentials.", ChatColor.GREEN);
return true; return true;
} }
else if (args[0].equalsIgnoreCase("delete")) else if (args[0].equalsIgnoreCase("delete"))
@ -83,18 +79,10 @@ public class Command_panel extends FreedomCommand
return true; return true;
} }
boolean deleted = plugin.ptero.deleteAccount(admin.getPteroID()); plugin.ptero.deleteAccount(admin.getPteroID());
if (!deleted)
{
msg("Failed to delete your Pterodactyl account.", ChatColor.RED);
return true;
}
admin.setPteroID(null); admin.setPteroID(null);
plugin.al.save(admin); plugin.al.save(admin);
plugin.al.updateTables(); plugin.al.updateTables();
msg("Successfully deleted your Pterodactyl account.", ChatColor.GREEN); msg("Successfully deleted your Pterodactyl account.", ChatColor.GREEN);
return true; return true;
} }

View File

@ -0,0 +1,77 @@
package me.totalfreedom.totalfreedommod.command;
import java.util.HashMap;
import java.util.Map;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitRunnable;
@CommandPermissions(level = Rank.ADMIN, source = SourceType.BOTH)
@CommandParameters(description = "Restart the server", usage = "/<command> [reason]")
public class Command_restart extends FreedomCommand
{
private static final Map<CommandSender, String> RESTART_CONFIRM = new HashMap<>();
@Override
public boolean run(final CommandSender sender, final Player playerSender, final Command cmd, final String commandLabel, final String[] args, final boolean senderIsConsole)
{
if (!plugin.ptero.isEnabled())
{
msg("Pterodactyl integration is currently disabled.", ChatColor.RED);
return true;
}
String reason = "Server is restarting!";
if (args.length != 0)
{
reason = StringUtils.join(args, " ");
}
if (sender.getName().equals("CONSOLE"))
{
restart(reason);
return true;
}
else if (RESTART_CONFIRM.containsKey(sender))
{
restart(RESTART_CONFIRM.get(sender));
return true;
}
msg("Warning: You're about to restart the server. Type /restart again to confirm you want to do this.");
RESTART_CONFIRM.put(sender, reason);
new BukkitRunnable()
{
@Override
public void run()
{
if (RESTART_CONFIRM.containsKey(sender))
{
RESTART_CONFIRM.remove(sender);
msg("Restart request expired.");
}
}
}.runTaskLater(plugin, 15 * 20);
return true;
}
public void restart(String reason)
{
FUtil.bcastMsg("Server is restarting!", ChatColor.LIGHT_PURPLE);
for (Player player : server.getOnlinePlayers())
{
player.kickPlayer(ChatColor.LIGHT_PURPLE + reason);
}
RESTART_CONFIRM.remove(sender);
plugin.ptero.restartServer();
}
}

View File

@ -20,7 +20,6 @@ public class Command_stop extends FreedomCommand
@Override @Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole) public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
{ {
String reason = "Server is going offline, come back in about 20 seconds."; String reason = "Server is going offline, come back in about 20 seconds.";
if (args.length != 0) if (args.length != 0)
@ -39,7 +38,6 @@ public class Command_stop extends FreedomCommand
return true; return true;
} }
msg("Warning: You're about to stop the server. Type /stop again to confirm you want to do this."); msg("Warning: You're about to stop the server. Type /stop again to confirm you want to do this.");
STOP_CONFIRM.put(sender, reason); STOP_CONFIRM.put(sender, reason);
@ -69,6 +67,13 @@ public class Command_stop extends FreedomCommand
STOP_CONFIRM.remove(sender); STOP_CONFIRM.remove(sender);
if (plugin.ptero.isEnabled())
{
plugin.ptero.stopServer();
}
else
{
server.shutdown(); server.shutdown();
} }
} }
}

View File

@ -91,7 +91,7 @@ public enum ConfigEntry
PTERO_DEFAULT_EMAIL_DOMAIN(String.class, "ptero.default_email_domain"), PTERO_DEFAULT_EMAIL_DOMAIN(String.class, "ptero.default_email_domain"),
PTERO_SERVER_UUID(String.class, "ptero.server_uuid"), PTERO_SERVER_UUID(String.class, "ptero.server_uuid"),
PTERO_ADMIN_KEY(String.class, "ptero.admin_key"), PTERO_ADMIN_KEY(String.class, "ptero.admin_key"),
PTERO_SERVER_KEY(String.class, "ptero.server_key"), PTERO_CLIENT_KEY(String.class, "ptero.client_key"),
// //
SHOP_ENABLED(Boolean.class, "shop.enabled"), SHOP_ENABLED(Boolean.class, "shop.enabled"),
SHOP_TITLE(String.class, "shop.title"), SHOP_TITLE(String.class, "shop.title"),

View File

@ -85,18 +85,23 @@ discord:
# Owner role ID # Owner role ID
server_owner_role_id: '' server_owner_role_id: ''
# Pterodactyl # Pterodactyl (requires Discord verification to be enabled)
ptero: ptero:
# URL - do not leave a trailing forward slash # URL - do not leave a trailing forward slash
url: '' url: ''
# The default email domain used to set email addresses for new users - do not include the @ # The default email domain used to set email addresses for new users - do not include the @
default_email_domain: 'example.com' default_email_domain: 'example.com'
# Server UUID # Short Server UUID (for example: a538a220)
# Do NOT give the long Server UUID
server_uuid: '' server_uuid: ''
# Admin panel API key # Admin panel API key
# Create this key by going to Settings > Application API > Create New
# Make sure you give it Users and Servers permissions
admin_key: '' admin_key: ''
# Server API key # Client API key
server_key: '' # Create a new user and add them as a subuser to the server with all control privileges.
# Then, login to the new user account and go to User Settings. Click on API Credentials and create a new one.
client_key: ''
# The shop # The shop
shop: shop: