Compare commits

..

29 Commits

Author SHA1 Message Date
8949ee75eb fix requested by packs
apparently some pterodactyl installations don't like short UUIDs so this changes the config to say "use long uuids, not short uuids" instead
2021-06-29 20:36:23 -06:00
d88509bf11 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>
2021-06-29 20:28:30 +10:00
f57fc56f4a Merge pull request #83 from AtlasMediaGroup/FS-239-to-FS-242
Logs even more punishment types (FS-239, FS-240, FS-241, FS-242)
2021-06-19 03:20:47 -06:00
a6ca6b122c Merge branch 'development' into FS-239-to-FS-242 2021-06-18 13:24:15 +01:00
064e73f58b ez (#77) 2021-06-18 13:16:52 +01:00
32138b2e59 Order of operations fix 2021-06-17 13:41:25 -06:00
e1c3bad4d0 Even more punishment log types
Here's what I've changed in this commit:
- Adds /blockcmd to the punishment log (FS-239)
- Adds /blockedit and /blockpvp to the punishment log (FS-240)
- Adds /cage to the punishment log (FS-241)
- Adds /orbit to the punishment log (FS-242)
- Changes the order of operations in some commands to be a bit more consistent
2021-06-17 06:56:52 -06:00
4e78027f0c Merge pull request #79 from AtlasMediaGroup/FS-307
Fixes the EntityWiper not toggling properly (FS-307)
2021-06-17 06:12:26 -06:00
721f4f9fc3 Merge branch 'development' into FS-307 2021-06-17 05:56:56 -06:00
24ad2611a9 Merge pull request #81 from AtlasMediaGroup/FS-201
Admins can now see commands of everyone, regardless of rank (FS-201)
2021-06-17 05:54:10 -06:00
c238f251f2 Merge branch 'development' into FS-201 2021-06-17 05:46:40 -06:00
02848e3439 Merge pull request #82 from AtlasMediaGroup/FS-199
Prevents entities of type PLAYER from being purged in /entitywipe (FS-199)
2021-06-17 05:46:28 -06:00
9550f54e2b Merge branch 'development' into FS-199 2021-06-17 05:37:30 -06:00
39dade78e3 Merge pull request #80 from AtlasMediaGroup/FS-24-Round-2
Code quality improvements (FS-24)
2021-06-17 05:35:55 -06:00
5b6d8b01a4 Merge branch 'development' into FS-24-Round-2 2021-06-17 05:25:42 -06:00
96bc83cead Merge pull request #78 from AtlasMediaGroup/FS-207
Two fixes, one commit (FS-207)
2021-06-17 04:58:26 -06:00
be700a90ce Simple fix 2021-06-16 22:42:45 -06:00
6d1fce1716 FS-201 2021-06-16 22:06:12 -06:00
d3665f31fe Shut up Codacy 2021-06-16 21:56:25 -06:00
4188cb80fa FS-54 2021-06-16 21:10:08 -06:00
62fe72d99b Code quality and consistency improvements
Here's all the changes I've made in this commit:
- Resolves FS-44 (AutoEject.java)
- Resolves FS-45 (BlockBlocker.java)
- Resolves FS-47 and FS-48 (InteractBlocker.java)
- Resolves FS-49 (Command_cage.java)
- Resolves FS-50 (Command_manageshop.java)
- Resolves FS-51 (Command_notes.java)
- Resolves FS-52 (Command_potion.java)
- Resolves FS-53 (Command_tag.java)
- Resolves FS-55 (ItemFun.java)
- Resolves FS-56 (Module_list.java)
- Resolves FS-57 (Module_players.java)
- Removes redundant code from InteractBlocker.java
- Misc. code consistency corrections (global)
2021-06-16 21:10:08 -06:00
f4749559d2 FS-25 2021-06-16 21:10:08 -06:00
ed815794ed FS-26 2021-06-16 21:10:08 -06:00
0c12a19d1d FS-27 2021-06-16 21:10:08 -06:00
96d47e8e0c Update EntityWiper.java 2021-06-16 17:47:09 -06:00
3027e2a18c Two fixes, one commit
To kill two birds with one stone, I've done two fixes in this commit.
- Fixes issue that caused quiet warns to behave improperly (e.g. the warnings wouldn't increment if quiet)
- Added WARN to the PunishmentType list.
2021-06-16 17:29:57 -06:00
06025b2e69 Updated permissions to re-baseline with the dev server (#75)
Updating this to be based off of the dev server as it seems this has not been updated in some time. Primary purpose is to add the crackshot bypass removal for everyone (Though allow admins to bypass) and to add a start of network manager perms in the hopes it makes it more usable going forward.
2021-06-13 19:51:27 +01:00
da7e8f64aa Continuation on that notes thing (#74)
I forgot to remove the dependency after I removed the code that used JSONMessage. This fixes that by removing both the repository and the dependency from the pom file.
2021-06-12 11:26:40 +01:00
a498104777 Merge branch 'main' of github.com:AtlasMediaGroup/TotalFreedomMod into development 2021-06-07 16:22:43 +01:00
34 changed files with 483 additions and 270 deletions

53
pom.xml
View File

@ -39,6 +39,11 @@
</scm>
<repositories>
<repository>
<id>apache-snapshots</id>
<url>https://repository.apache.org/content/repositories/snapshots/</url>
</repository>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
@ -106,13 +111,13 @@
</repository>
<repository>
<id>rayzr-repo</id>
<url>https://cdn.rawgit.com/Rayzr522/maven-repo/master/</url>
<id>ess-repo</id>
<url>https://ci.ender.zone/plugin/repository/everything/</url>
</repository>
<repository>
<id>ess-repo</id>
<url>https://ci.ender.zone/plugin/repository/everything/</url>
<id>mattmalec-repo</id>
<url>https://repo.mattmalec.com/repository/releases</url>
</repository>
</repositories>
@ -149,7 +154,7 @@
<dependency>
<groupId>org.bstats</groupId>
<artifactId>bstats-bukkit</artifactId>
<version>1.8</version>
<version>2.2.1</version>
<scope>compile</scope>
</dependency>
@ -191,21 +196,21 @@
<dependency>
<groupId>net.dv8tion</groupId>
<artifactId>JDA</artifactId>
<version>4.2.1_255</version>
<version>4.3.0_277</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>net.coreprotect</groupId>
<artifactId>coreprotect</artifactId>
<version>19.3</version>
<version>19.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.sk89q.worldguard</groupId>
<artifactId>worldguard-bukkit</artifactId>
<version>7.0.4</version>
<version>7.0.5</version>
<scope>provided</scope>
</dependency>
@ -216,13 +221,6 @@
<scope>compile</scope>
</dependency>
<dependency>
<groupId>me.rayzr522</groupId>
<artifactId>jsonmessage</artifactId>
<version>1.0.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.vexsoftware</groupId>
<artifactId>votifier</artifactId>
@ -271,12 +269,26 @@
<version>3.1.1</version>
<scope>compile</scope>
</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>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.4.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.sisu</groupId>
<artifactId>org.eclipse.sisu.inject</artifactId>
@ -311,7 +323,7 @@
<plugin>
<groupId>pl.project13.maven</groupId>
<artifactId>git-commit-id-plugin</artifactId>
<version>4.0.2</version>
<version>4.0.5</version>
<executions>
<execution>
<id>get-the-git-infos</id>
@ -424,10 +436,12 @@
</plugin>
<!-- Shade -->
<!-- NOTE: This should only be temporary. This will need to be updated when a stable build comes out
that supports Java 16 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<version>3.3.0-SNAPSHOT</version>
<executions>
<execution>
<phase>package</phase>
@ -439,8 +453,7 @@
<relocations>
<relocation>
<pattern>io.papermc.lib</pattern>
<shadedPattern>me.totalfreedom.totalfreedommod.paperlib
</shadedPattern> <!-- Replace this -->
<shadedPattern>me.totalfreedom.totalfreedommod.paperlib</shadedPattern>
</relocation>
<relocation>
<pattern>org.bstats</pattern>
@ -454,11 +467,11 @@
<include>commons-codec:commons-codec</include>
<include>org.reflections:reflections</include>
<include>org.javassist:javassist</include>
<include>me.rayzr522:jsonmessage</include>
<include>io.papermc:paperlib</include>
<include>com.github.speedxx:Mojangson</include>
<include>org.bstats:bstats-bukkit</include>
<include>org.jetbrains:annotations</include>
<include>com.mattmalec:Pterodactyl4J</include>
</includes>
</artifactSet>
</configuration>

View File

@ -85,6 +85,10 @@ public class AutoEject extends FreedomService
player.kickPlayer(kickMessage);
break;
}
default:
{
FLog.warning("Unrecognized EjectMethod " + method.name() + " found, defaulting to STRIKE_THREE");
}
case STRIKE_THREE:
{
plugin.bm.addBan(Ban.forPlayerFuzzy(player, Bukkit.getConsoleSender(), null, kickMessage));

View File

@ -25,11 +25,6 @@ public class CommandSpy extends FreedomService
{
if (plugin.al.isAdmin(player) && plugin.al.getAdmin(player).getCommandSpy())
{
if (plugin.al.isAdmin(event.getPlayer()) && !plugin.al.isSeniorAdmin(player))
{
continue;
}
if (player != event.getPlayer())
{
FUtil.playerMsg(player, event.getPlayer().getName() + ": " + event.getMessage());

View File

@ -2,6 +2,8 @@ package me.totalfreedom.totalfreedommod;
import java.util.Arrays;
import java.util.List;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.util.Groups;
import org.bukkit.Bukkit;
import org.bukkit.World;
@ -33,7 +35,10 @@ public class EntityWiper extends FreedomService
@Override
public void run()
{
wipeEntities(false);
if (ConfigEntry.AUTO_ENTITY_WIPE.getBoolean())
{
wipeEntities(false);
}
}
}.runTaskTimer(plugin, 600L, 600L); // 30 second delay after startup + run every 30 seconds
}

View File

@ -4,7 +4,6 @@ import io.papermc.lib.PaperLib;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;
import me.rayzr522.jsonmessage.JSONMessage;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.player.PlayerData;

View File

@ -1,26 +1,30 @@
package me.totalfreedom.totalfreedommod;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import com.mattmalec.pterodactyl4j.Permission;
import com.mattmalec.pterodactyl4j.PowerAction;
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 me.totalfreedom.totalfreedommod.admin.Admin;
import me.totalfreedom.totalfreedommod.config.ConfigEntry;
import me.totalfreedom.totalfreedommod.rank.Rank;
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 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 List<String> SERVER_HEADERS = Arrays.asList("Accept:Application/vnd.pterodactyl.v1+json", "Content-Type:application/json", "Authorization:Bearer " + SERVER_KEY);
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 CLIENT_KEY = ConfigEntry.PTERO_CLIENT_KEY.getString();
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);
@ -43,163 +47,60 @@ public class Pterodactyl extends FreedomService
if (!admin.isActive() || admin.getRank() != Rank.SENIOR_ADMIN)
{
FLog.debug("Disabling ptero acc");
FLog.debug("Disabling Pterodactyl account");
removeAccountFromServer(id);
return;
}
FLog.debug("Enabling ptero acc");
FLog.debug("Enabling Pterodactyl account");
addAccountToServer(id);
}
@SuppressWarnings("unchecked")
public String createAccount(String username, String password)
{
JSONObject json = new JSONObject();
json.put("username", username);
json.put("password", password);
json.put("email", username.toLowerCase() + "@" + ConfigEntry.PTERO_DEFAULT_EMAIL_DOMAIN.getString());
json.put("first_name", username);
json.put("last_name", "\u200E"); // required, so I made it appear empty
Response response;
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();
UserAction action = adminAPI.getUserManager().createUser()
.setUserName(username)
.setEmail(username.toLowerCase() + "@" + ConfigEntry.PTERO_DEFAULT_EMAIL_DOMAIN.getString())
.setFirstName(username)
.setLastName("\u200E") // Required - make it appear empty
.setPassword(password);
return action.execute().getId();
}
public boolean deleteAccount(String id)
public void 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;
}
ApplicationUser username = adminAPI.retrieveUserById(id).execute();
PteroAction<Void> action = adminAPI.getUserManager().deleteUser(username);
action.execute();
}
@SuppressWarnings("unchecked")
public void addAccountToServer(String id)
{
String url = URL + "/api/client/servers/" + ConfigEntry.PTERO_SERVER_UUID.getString() + "/users";
JSONObject userData = getUserData(id);
if (userData == null)
{
FLog.severe("The Pterodactyl user with the ID of " + id + " was not found");
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);
}
ApplicationUser username = adminAPI.retrieveUserById(id).execute();
String email = username.getEmail();
PteroAction<ClientServer> server = clientAPI.retrieveServerByIdentifier(IDENTIFIER);
server.execute().getSubuserManager().createUser()
.setEmail(email)
.setPermissions(Permission.CONTROL_PERMISSIONS).execute();
}
public void removeAccountFromServer(String id)
{
JSONObject userData = getUserData(id);
if (userData == null)
{
FLog.severe("The Pterodactyl user with the ID of " + id + " was not found");
return;
}
String url = URL + "/api/client/servers/" + ConfigEntry.PTERO_SERVER_UUID.getString() + "/users/" + userData.get("uuid");
try
{
FUtil.sendRequest(url, "DELETE", SERVER_HEADERS, null);
}
catch (IOException e)
{
FLog.severe(e);
}
ApplicationUser username = adminAPI.retrieveUserById(id).execute();
PteroAction<ClientServer> server = clientAPI.retrieveServerByIdentifier(IDENTIFIER);
ClientSubuser clientSubuser = server.execute().getSubuser(username.getUUID()).retrieve().execute();
server.execute().getSubuserManager().deleteUser(clientSubuser).execute();
}
public JSONObject getUserData(String id)
public void stopServer()
{
Response response;
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");
clientAPI.setPower(server, PowerAction.STOP).execute();
}
// 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)
public void restartServer()
{
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;
clientAPI.setPower(server, PowerAction.RESTART).execute();
}
public boolean isEnabled()

View File

@ -43,6 +43,7 @@ public class IndefiniteBan implements IConfig
@Override
public void saveTo(ConfigurationSection cs)
{
// The indefinite ban list is only intended to be modified manually. It is not intended to save.
}
@Override

View File

@ -171,6 +171,11 @@ public class BlockBlocker extends FreedomService
}
break;
}
default:
{
// Do nothing
break;
}
}
if (Groups.BANNERS.contains(event.getBlockPlaced().getType()))

View File

@ -36,10 +36,9 @@ public class InteractBlocker extends FreedomService
break;
}
case LEFT_CLICK_AIR:
case LEFT_CLICK_BLOCK:
default:
{
//
// Do nothing
break;
}
}
@ -158,6 +157,11 @@ public class InteractBlocker extends FreedomService
event.setCancelled(true);
break;
}
default:
{
// Do nothing
break;
}
}
}
}

View File

@ -1,6 +1,8 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor;
@ -75,9 +77,11 @@ public class Command_blockcmd extends FreedomCommand
FPlayer playerdata = plugin.pl.getPlayer(player);
if (!playerdata.allCommandsBlocked())
{
playerdata.setCommandsBlocked(true);
FUtil.adminAction(sender.getName(), "Blocking all commands for " + player.getName(), true);
playerdata.setCommandsBlocked(true);
msg("Blocked commands for " + player.getName() + ".");
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.BLOCKCMD, null));
}
else
{

View File

@ -1,6 +1,8 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.ArrayUtils;
@ -128,6 +130,8 @@ public class Command_blockedit extends FreedomCommand
msg(player2, "Your block modification abilities have been blocked.", ChatColor.RED);
msg("Blocked all block modification abilities for " + player2.getName());
plugin.pul.logPunishment(new Punishment(player2.getName(), FUtil.getIp(player2), sender.getName(), PunishmentType.BLOCKEDIT, null));
}
return true;
}

View File

@ -1,6 +1,8 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang3.ArrayUtils;
@ -125,6 +127,7 @@ public class Command_blockpvp extends FreedomCommand
{
Command_smite.smite(sender, p, reason);
}
plugin.pul.logPunishment(new Punishment(p.getName(), FUtil.getIp(p), sender.getName(), PunishmentType.BLOCKPVP, null));
msg(p, "Your PVP has been disabled.", ChatColor.RED);
msg("Disabled PVP for " + p.getName());

View File

@ -5,6 +5,8 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor;
@ -83,9 +85,22 @@ public class Command_cage extends FreedomCommand
msg("Invalid block!", ChatColor.RED);
break;
}
default:
{
return false;
}
}
}
if (outerMaterial == Material.PLAYER_HEAD)
{
FUtil.adminAction(sender.getName(), "Caging " + player.getName() + " in " + skullName, true);
}
else
{
FUtil.adminAction(sender.getName(), "Caging " + player.getName(), true);
}
Location location = player.getLocation().clone().add(0.0, 1.0, 0.0);
if (skullName != null)
@ -96,17 +111,9 @@ public class Command_cage extends FreedomCommand
{
fPlayer.getCageData().cage(location, outerMaterial, innerMaterial);
}
player.setGameMode(GameMode.SURVIVAL);
if (outerMaterial == Material.PLAYER_HEAD)
{
FUtil.adminAction(sender.getName(), "Caging " + player.getName() + " in " + skullName, true);
}
else
{
FUtil.adminAction(sender.getName(), "Caging " + player.getName(), true);
}
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.CAGE, null));
return true;
}

View File

@ -64,6 +64,12 @@ public class Command_entitywipe extends FreedomCommand
return true;
}
if (type == EntityType.PLAYER)
{
msg("Player entities cannot be purged.", ChatColor.RED);
return true;
}
if (!getAllEntities().contains(type))
{
msg(FUtil.formatName(type.name()) + " is an entity, however: it is a mob.", ChatColor.RED);

View File

@ -23,12 +23,12 @@ public class Command_freeze extends FreedomCommand
if (!gFreeze)
{
FUtil.adminAction(sender.getName(), "Disabling global player freeze", false);
FUtil.adminAction(sender.getName(), "Unfreezing all players", false);
msg("Players are now free to move.");
return true;
}
FUtil.adminAction(sender.getName(), "Enabling global player freeze", false);
FUtil.adminAction(sender.getName(), "Freezing all players", false);
for (Player player : server.getOnlinePlayers())
{
if (!isAdmin(player))

View File

@ -35,8 +35,8 @@ public class Command_manageshop extends FreedomCommand
}
switch (args[1])
{
case "add":
{
try
{
int amount = Math.max(0, Math.min(1000000, Integer.parseInt(args[2])));
@ -75,7 +75,9 @@ public class Command_manageshop extends FreedomCommand
msg("Invalid number: " + args[2], ChatColor.RED);
return true;
}
}
case "remove":
{
try
{
int amount = Math.max(0, Math.min(1000000, Integer.parseInt(args[2])));
@ -122,7 +124,9 @@ public class Command_manageshop extends FreedomCommand
msg("Invalid number: " + args[2], ChatColor.RED);
return true;
}
}
case "set":
{
try
{
int amount = Math.max(0, Math.min(1000000, Integer.parseInt(args[2])));
@ -147,6 +151,11 @@ public class Command_manageshop extends FreedomCommand
msg("Invalid number: " + args[2], ChatColor.RED);
return true;
}
}
default:
{
return false;
}
}
}
else if (args[0].equals("items"))

View File

@ -116,8 +116,12 @@ public class Command_notes extends FreedomCommand
msg("Cleared " + count + " notes.", ChatColor.GREEN);
return true;
}
default:
{
return false;
}
}
return false;
}
@Override

View File

@ -1,6 +1,8 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.player.FPlayer;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.bukkit.ChatColor;
@ -56,11 +58,13 @@ public class Command_orbit extends FreedomCommand
}
}
FUtil.adminAction(sender.getName(), "Orbiting " + player.getName(), false);
player.setGameMode(GameMode.SURVIVAL);
playerdata.startOrbiting(strength);
player.setVelocity(new Vector(0, strength, 0));
FUtil.adminAction(sender.getName(), "Orbiting " + player.getName(), false);
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.ORBIT, null));
return true;
}
}

View File

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

View File

@ -29,6 +29,7 @@ public class Command_potion extends FreedomCommand
switch (args.length)
{
case 1:
{
if (args[0].equalsIgnoreCase("list"))
{
List<String> potionEffectTypeNames = new ArrayList<>();
@ -58,8 +59,10 @@ public class Command_potion extends FreedomCommand
}
}
}
}
case 2:
{
if (args[0].equalsIgnoreCase("clear"))
{
Player target = playerSender;
@ -95,9 +98,11 @@ public class Command_potion extends FreedomCommand
msg("Cleared all active potion effects " + (!target.equals(playerSender) ? "from player " + target.getName() + "." : "from yourself."), ChatColor.AQUA);
}
break;
}
case 4:
case 5:
{
if (args[0].equalsIgnoreCase("add"))
{
Player target = playerSender;
@ -167,8 +172,11 @@ public class Command_potion extends FreedomCommand
+ (!target.equals(playerSender) ? " to player " + target.getName() + "." : " to yourself."), ChatColor.AQUA);
}
break;
}
default:
{
return false;
}
}
return true;
}
@ -179,14 +187,17 @@ public class Command_potion extends FreedomCommand
switch (args.length)
{
case 1:
{
List<String> arguments = new ArrayList<>(Arrays.asList("list", "clear", "add"));
if (plugin.al.isAdmin(sender))
{
arguments.add("clearall");
}
return arguments;
}
case 2:
{
if (args[0].equals("clear"))
{
if (plugin.al.isAdmin(sender))
@ -199,22 +210,28 @@ public class Command_potion extends FreedomCommand
return getAllPotionTypes();
}
break;
}
case 3:
{
if (args[0].equals("add"))
{
return Collections.singletonList("<duration>");
}
break;
}
case 4:
{
if (args[0].equals("add"))
{
return Collections.singletonList("<amplifier>");
}
break;
}
case 5:
{
if (plugin.al.isAdmin(sender))
{
if (args[0].equals("add"))
@ -223,6 +240,12 @@ public class Command_potion extends FreedomCommand
}
}
break;
}
default:
{
break;
}
}
return Collections.emptyList();

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
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.";
if (args.length != 0)
@ -39,7 +38,6 @@ public class Command_stop extends FreedomCommand
return true;
}
msg("Warning: You're about to stop the server. Type /stop again to confirm you want to do this.");
STOP_CONFIRM.put(sender, reason);
@ -69,6 +67,13 @@ public class Command_stop extends FreedomCommand
STOP_CONFIRM.remove(sender);
server.shutdown();
if (plugin.ptero.isEnabled())
{
plugin.ptero.stopServer();
}
else
{
server.shutdown();
}
}
}

View File

@ -105,6 +105,11 @@ public class Command_tag extends FreedomCommand
}
return true;
}
default:
{
return false;
}
}
}
else if (args.length >= 2)
@ -279,6 +284,11 @@ public class Command_tag extends FreedomCommand
msg("Tag set to '" + outputTag + ChatColor.GRAY + "'." + (save ? " (Saved)" : "") + from + to);
return true;
}
default:
{
return false;
}
}
}
return false;

View File

@ -16,6 +16,12 @@ import org.bukkit.entity.Player;
@CommandParameters(description = "Toggles TotalFreedomMod settings", usage = "/<command> [option] [value] [value]")
public class Command_toggle extends FreedomCommand
{
private final List<String> toggles = Arrays.asList(
"waterplace", "fireplace", "lavaplace", "fluidspread", "lavadmg", "firespread", "frostwalk",
"firework", "prelog", "lockdown", "petprotect", "entitywipe", "nonuke [range] [count]",
"explosives [radius]", "unsafeenchs", "bells", "armorstands", "structureblocks", "jigsaws", "grindstones",
"jukeboxes", "spawners", "4chan", "beehives", "respawnanchors", "autotp", "autoclear", "minecarts", "mp44",
"landmines", "tossmob", "gravity");
@Override
public boolean run(CommandSender sender, Player playerSender, Command cmd, String commandLabel, String[] args, boolean senderIsConsole)
@ -23,38 +29,10 @@ public class Command_toggle extends FreedomCommand
if (args.length == 0)
{
msg("Available toggles: ");
msg("- waterplace");
msg("- fireplace");
msg("- lavaplace");
msg("- fluidspread");
msg("- lavadmg");
msg("- firespread");
msg("- frostwalk");
msg("- firework");
msg("- prelog");
msg("- lockdown");
msg("- petprotect");
msg("- entitywipe");
msg("- nonuke [range] [count]");
msg("- explosives [radius]");
msg("- unsafeenchs");
msg("- bells");
msg("- armorstands");
msg("- structureblocks");
msg("- jigsaws");
msg("- grindstones");
msg("- jukeboxes");
msg("- spawners");
msg("- 4chan");
msg("- beehives");
msg("- respawnanchors");
msg("- autotp");
msg("- autoclear");
msg("- minecarts");
msg("- landmines");
msg("- mp44");
msg("- tossmob");
msg("- gravity");
for (String toggle : toggles)
{
msg("- " + toggle);
}
return false;
}
@ -304,6 +282,16 @@ public class Command_toggle extends FreedomCommand
toggle("Block gravity is", ConfigEntry.ALLOW_GRAVITY);
break;
}
default:
{
msg("Available toggles: ");
for (String toggle : toggles)
{
msg("- " + toggle);
}
return false;
}
}
return true;
}

View File

@ -1,6 +1,9 @@
package me.totalfreedom.totalfreedommod.command;
import me.totalfreedom.totalfreedommod.punishments.Punishment;
import me.totalfreedom.totalfreedommod.punishments.PunishmentType;
import me.totalfreedom.totalfreedommod.rank.Rank;
import me.totalfreedom.totalfreedommod.util.FUtil;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.bukkit.ChatColor;
@ -53,25 +56,28 @@ public class Command_warn extends FreedomCommand
String warnReason = StringUtils.join(ArrayUtils.subarray(args, 1, args.length), " ");
player.sendTitle(ChatColor.RED + "You've been warned.", ChatColor.YELLOW + "Reason: " + warnReason, 20, 100, 60);
msg(ChatColor.GREEN + "You have successfully warned " + player.getName());
msg(player, ChatColor.RED + "[WARNING] You received a warning from " + sender.getName() + ": " + warnReason);
plugin.pl.getPlayer(player).incrementWarnings(quiet);
plugin.pul.logPunishment(new Punishment(player.getName(), FUtil.getIp(player), sender.getName(), PunishmentType.WARN, warnReason));
if (quiet)
{
msg("Warned " + player.getName() + " quietly");
return true;
msg("You have successfully warned " + player.getName() + " quietly.");
}
else
{
String adminNotice = ChatColor.RED +
sender.getName() +
" - " +
"Warning: " +
player.getName() +
" - Reason: " +
ChatColor.YELLOW +
warnReason;
plugin.al.messageAllAdmins(adminNotice);
msg(player, ChatColor.RED + "[WARNING] You received a warning from " + sender.getName() + ": " + warnReason);
String adminNotice = ChatColor.RED +
sender.getName() +
" - " +
"Warning: " +
player.getName() +
" - Reason: " +
ChatColor.YELLOW +
warnReason;
plugin.al.messageAllAdmins(adminNotice);
plugin.pl.getPlayer(player).incrementWarnings();
msg("You have successfully warned " + player.getName() + ".");
}
return true;
}
}

View File

@ -91,7 +91,7 @@ public enum ConfigEntry
PTERO_DEFAULT_EMAIL_DOMAIN(String.class, "ptero.default_email_domain"),
PTERO_SERVER_UUID(String.class, "ptero.server_uuid"),
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_TITLE(String.class, "shop.title"),

View File

@ -128,7 +128,7 @@ public class ItemFun extends FreedomService
LivingEntity livingEntity = (LivingEntity)event.getRightClicked();
EntityType entityType = livingEntity.getType();
if (!(entityType == fPlayer.mobThrowerCreature()))
if (entityType != fPlayer.mobThrowerCreature())
{
return;
}
@ -304,6 +304,11 @@ public class ItemFun extends FreedomService
}
break;
}
default:
{
// Do nothing
break;
}
}
}

View File

@ -73,7 +73,7 @@ public class Landminer extends FreedomService
continue;
}
if (!(player.getLocation().distanceSquared(location) <= (landmine.radius * landmine.radius)))
if (player.getLocation().distanceSquared(location) > (landmine.radius * landmine.radius))
{
break;
}

View File

@ -79,11 +79,20 @@ public class Module_list extends HTTPDModule
switch (admin.getRank())
{
case ADMIN:
{
admins.add(player.getName());
break;
}
case SENIOR_ADMIN:
{
senioradmins.add(player.getName());
break;
}
default:
{
// Do nothing
break;
}
}
}
}

View File

@ -51,11 +51,20 @@ public class Module_players extends HTTPDModule
switch (admin.getRank())
{
case ADMIN:
{
admins.add(username);
break;
}
case SENIOR_ADMIN:
{
senioradmins.add(username);
break;
}
default:
{
// Do nothing
break;
}
}
}

View File

@ -429,14 +429,19 @@ public class FPlayer
this.warningCount = warningCount;
}
public void incrementWarnings()
public void incrementWarnings(boolean quiet)
{
this.warningCount++;
if (this.warningCount % 2 == 0)
{
Player p = getPlayer();
p.getWorld().strikeLightning(p.getLocation());
if (!quiet)
{
p.getWorld().strikeLightning(p.getLocation());
}
FUtil.playerMsg(p, ChatColor.RED + "You have been warned at least twice now, make sure to read the rules at " + ConfigEntry.SERVER_BAN_URL.getString());
}
}

View File

@ -7,5 +7,11 @@ public enum PunishmentType
KICK,
TEMPBAN,
BAN,
DOOM
DOOM,
WARN,
CAGE,
BLOCKEDIT,
BLOCKPVP,
BLOCKCMD,
ORBIT
}

View File

@ -85,18 +85,23 @@ discord:
# Owner role ID
server_owner_role_id: ''
# Pterodactyl
# Pterodactyl (requires Discord verification to be enabled)
ptero:
# URL - do not leave a trailing forward slash
url: ''
# The default email domain used to set email addresses for new users - do not include the @
default_email_domain: 'example.com'
# Server UUID
# Long Server UUID (for example: abf9a712-6c5a-4504-b4bc-37f1061b8801)
# Do NOT give the short Server UUID
server_uuid: ''
# 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: ''
# Server API key
server_key: ''
# Client API 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
shop:

View File

@ -1,16 +1,50 @@
#
# TotalFreedomMod Permissions
# TotalFreedomMod 5.5 Permissions
# by ZeroEpoch1969
#
# Note that every group inherits the previous groups' permissions
# Meaning Senior Admins have the permissions of Operators and Admins, and etc
# Meaning Telnet Admins have the permissions of Operators and Super Admins, and etc
# This is used to remove all permission begging with the root node
# This is useful when a plugin gives all permissions to a player because they are opped
remove:
- "voxelsniper"
- "bending"
- "bending.admin"
- "bending.ability.Cleanse"
- "worldedit.brush.apply"
- "essentials.near.exclude"
- "plots.admin"
- "plots.debugroadregen"
- "plots.debugclaimtest"
- "plots.debugpaste"
- "plots.debugallowunsafe"
- "plots.debugloadtest"
- "plots.debugsavetest"
- "plots.cluster"
#Crackshot
- "crackshot.bypass.all"
#NetworkManager
- "networkmanager.*"
- "networkmanager.notify.joinbanned"
- "networkmanager.notify.*"
- "networkmanager.announce.global"
- "networkmanager.announce"
- "networkmanager.chatlock"
- "networkmanager.clearchat.bypass"
- "networkmanager.clearchat.*"
- "networkmanager.notify.ticket.new"
- "networkmanager.lookup"
- "networkmanager.maintenance.*"
- "networkmanager.permissions"
- "networkmanager.reports"
- "networkmanager.tickets"
- "networkmanager.chatlock.bypass"
- "networkmanager.anticaps.bypass"
- "networkmanager.antispam.bypass"
- "networkmanager.commandblocker.bypass"
- "networkmanager.tags.*"
# Operator permission nodes
operators:
@ -36,16 +70,79 @@ operators:
- "worldedit.removebelow"
- "worldedit.removenear"
- "worldedit.replacenear"
- "worldedit.brush.*"
- "worldedit.global-mask"
- "worldedit.fill"
- "worldedit.fill.recursive"
# LibsDisguises
- "libsdisguises.noactionbar"
# WorldGuard
- "worldguard.region.list.own"
- "worldguard.region.addmember.own.*"
- "worldguard.region.removemember.own.*"
- "worldguard.region.info.*"
# Bending
- "bending.command.add"
- "bending.command.bind"
- "bending.command.check"
- "bending.command.choose"
- "bending.command.rechoose"
- "bending.command.clear"
- "bending.command.copy"
- "bending.command.display"
- "bending.command.help"
- "bending.command.invincible"
- "bending.command.preset"
- "bending.command.preset.list"
- "bending.command.preset.create"
- "bending.command.preset.delete"
- "bending.command.preset.bind"
- "bending.command.preset.bind.assign"
- "bending.command.preset.bind.external"
- "bending.command.toggle"
- "bending.command.version"
- "bending.command.who"
- "bending.earth"
- "bending.air"
- "bending.fire"
- "bending.water"
- "bending.water.bloodbending.anytime"
- "bending.ability.AvatarState"
- "bending.command.add.chi"
- "bending.command.choose.chi"
- "bending.ability.Paralyze"
- "bending.ability.RapidPunch"
- "bending.ability.Smokescreen"
- "bending.ability.WarriorStance"
- "bending.ability.AcrobatStance"
- "bending.ability.QuickStrike"
- "bending.ability.SwiftKick"
- "bending.ability.ChiCombo"
- "bending.chi.passive"
- "bending.ability.MetalClips.throw"
- "bending.ability.AirCombo"
- "bending.ability.Flight"
- "bending.ability.WaterCombo"
- "bending.ability.EarthCombo"
- "bending.ability.FireCombo"
- "bending.ability.ChiCombo"
- "bending.air.passive"
- "bending.chi.passive"
- "bending.earth.passive"
- "bending.fire.passive"
- "bending.water.passive"
# NetworkManager
- "networkmanager.chatlog"
- "networkmanager.find"
- "networkmanager.gtps"
- "networkmanager.lookup"
- "networkmanager.slashserver.*"
- "networkmanager.notification.join"
- "networkmanager.party.nolimit"
- "networkmanager.tabcompletechat"
# Master Builder permission nodes
master_builders:
- "worldedit.tool.*"
@ -59,13 +156,25 @@ master_builders:
- "voxelsniper.sniper"
- "voxelsniper.goto"
- "voxelsniper.brush.*"
# Admin permission nodes
admins:
- "coreprotect.*"
- "worldedit.*"
- "worldguard.*"
- "bending.*"
- "bending.admin.remove"
- "bending.command.toggle.all"
- "bending.admin.toggle"
- "bending.command.reload"
- "plots.cluster"
- "networkmanager.adminchat"
- "networkmanager.announce.server"
- "networkmanager.socialspy"
- "networkmanager.fullproxy.bypass"
- "networkmanager.lookup.ip"
#Crackshot
- "crackshot.bypass.all"
# Senior Admin permission nodes
senior_admins: []
senior_admins:
- "bending.admin.permaremove"
- "bending.ability.Cleanse"