configurable enemy check radius for fly, option added in conf.json
Added a system faction check to neutral
Added a enderpearl disable while flying option to conf.json
Added my own repository to maven along with coreprotect for shading.
--Factions Inspect Added--
This commit is contained in:
Naman 2018-04-08 22:13:41 -05:00
parent a0eca2d5dd
commit efee66071b
15 changed files with 236 additions and 40 deletions

10
pom.xml
View File

@ -318,6 +318,12 @@
</exclusion> </exclusion>
</exclusions> </exclusions>
</dependency> </dependency>
<dependency>
<groupId>net.coreprotect</groupId>
<artifactId>CoreProtect</artifactId>
<version>2</version>
<scope>provided</scope>
</dependency>
</dependencies> </dependencies>
<repositories> <repositories>
@ -349,5 +355,9 @@
<id>mvdw-software</id> <id>mvdw-software</id>
<url>http://repo.mvdw-software.be/content/groups/public/</url> <url>http://repo.mvdw-software.be/content/groups/public/</url>
</repository> </repository>
<repository>
<id>ProSavage</id>
<url>https://www.myget.org/F/prosavage/maven/</url>
</repository>
</repositories> </repositories>
</project> </project>

View File

@ -79,6 +79,9 @@ public class Conf {
public static String truceChatFormat = ChatColor.DARK_PURPLE + "%s:" + ChatColor.WHITE + " %s"; public static String truceChatFormat = ChatColor.DARK_PURPLE + "%s:" + ChatColor.WHITE + " %s";
public static String modChatFormat = ChatColor.RED + "%s:" + ChatColor.WHITE + " %s"; public static String modChatFormat = ChatColor.RED + "%s:" + ChatColor.WHITE + " %s";
public static int enemyFlyCheckRadius = 16;
public static boolean noEnderpearlsInFly = false;
public static boolean broadcastDescriptionChanges = false; public static boolean broadcastDescriptionChanges = false;
public static boolean broadcastTagChanges = false; public static boolean broadcastTagChanges = false;

View File

@ -159,6 +159,12 @@ public interface FPlayer extends EconomyParticipator {
public boolean hasMoney(int amt); public boolean hasMoney(int amt);
//inspect Stuff
public boolean isInspectMode();
public void setInspectMode(boolean status);
// Fly Checks // Fly Checks

View File

@ -21,6 +21,8 @@ import com.massivecraft.factions.zcore.fupgrades.EXPUpgrade;
import com.massivecraft.factions.zcore.fupgrades.FUpgradesGUI; import com.massivecraft.factions.zcore.fupgrades.FUpgradesGUI;
import com.massivecraft.factions.zcore.fupgrades.SpawnerUpgrades; import com.massivecraft.factions.zcore.fupgrades.SpawnerUpgrades;
import com.massivecraft.factions.zcore.util.TextUtil; import com.massivecraft.factions.zcore.util.TextUtil;
import net.coreprotect.CoreProtect;
import net.coreprotect.CoreProtectAPI;
import net.milkbowl.vault.economy.Economy; import net.milkbowl.vault.economy.Economy;
import net.milkbowl.vault.permission.Permission; import net.milkbowl.vault.permission.Permission;
import org.bukkit.*; import org.bukkit.*;
@ -48,6 +50,8 @@ public class P extends MPlugin {
public static P p; public static P p;
public static Permission perms = null; public static Permission perms = null;
// Persistence related // Persistence related
private boolean locked = false; private boolean locked = false;
@ -123,6 +127,11 @@ public class P extends MPlugin {
Board.getInstance().load(); Board.getInstance().load();
Board.getInstance().clean(); Board.getInstance().clean();
//inspect stuff
if (!initCoreProtect()){
P.p.log("Inspect will be disabled, you need coreprotect installed for it to function!");
}
// Add Base Commands // Add Base Commands
this.cmdBase = new FCmdRoot(); this.cmdBase = new FCmdRoot();
this.cmdAutoHelp = new CmdAutoHelp(); this.cmdAutoHelp = new CmdAutoHelp();
@ -162,6 +171,10 @@ public class P extends MPlugin {
// since some other plugins execute commands directly through this command interface, provide it // since some other plugins execute commands directly through this command interface, provide it
this.getCommand(this.refCommand).setExecutor(this); this.getCommand(this.refCommand).setExecutor(this);
setupPlaceholderAPI(); setupPlaceholderAPI();
postEnable(); postEnable();
this.loadSuccessful = true; this.loadSuccessful = true;
@ -335,6 +348,20 @@ public class P extends MPlugin {
return event != null && (isPlayerFactionChatting(event.getPlayer()) || isFactionsCommand(event.getMessage())); return event != null && (isPlayerFactionChatting(event.getPlayer()) || isFactionsCommand(event.getMessage()));
} }
//Inspect stuff
private boolean initCoreProtect()
{
if (!getServer().getPluginManager().isPluginEnabled("CoreProtect")) {
return false;
}
CoreProtectAPI coreProtectAPI = CoreProtect.getInstance().getAPI();
return true;
}
// Does player have Faction Chat enabled? If so, chat plugins should preferably not do channels, // Does player have Faction Chat enabled? If so, chat plugins should preferably not do channels,
// local chat, or anything else which targets individual recipients, so Faction Chat can be done // local chat, or anything else which targets individual recipients, so Faction Chat can be done
public boolean isPlayerFactionChatting(Player player) { public boolean isPlayerFactionChatting(Player player) {

View File

@ -14,6 +14,7 @@ import org.bukkit.GameMode;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import java.util.ConcurrentModificationException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@ -60,48 +61,48 @@ public class CmdFly extends FCommand {
public static void startFlyCheck() { public static void startFlyCheck() {
flyid = Bukkit.getScheduler().scheduleSyncRepeatingTask(P.p, new Runnable() { flyid = Bukkit.getScheduler().scheduleSyncRepeatingTask(P.p, new Runnable() {
@Override @Override
public void run() { public void run() throws ConcurrentModificationException { //threw the exception for now, until I recode fly :( Cringe.
checkTaskState(); checkTaskState();
if (flyMap.keySet().size() != 0) { if (flyMap.keySet().size() != 0) {
for (String name : flyMap.keySet()) { for (String name : flyMap.keySet()) {
if (name == null) { if (name == null) {
continue; continue;
} }
Player player = Bukkit.getPlayer(name); Player player = Bukkit.getPlayer(name);
if (player == null) { if (player == null) {
continue; continue;
} }
if (!player.isFlying()) { if (!player.isFlying()) {
continue; continue;
} }
FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player); FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player);
if (fPlayer == null) { if (fPlayer == null) {
continue; continue;
} }
if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) { if (player.getGameMode() == GameMode.CREATIVE || player.getGameMode() == GameMode.SPECTATOR) {
continue; continue;
} }
Faction myFaction = fPlayer.getFaction(); Faction myFaction = fPlayer.getFaction();
if (myFaction.isWilderness()) { if (myFaction.isWilderness()) {
fPlayer.setFlying(false);
flyMap.remove(name);
continue;
}
if (fPlayer.checkIfNearbyEnemies()) {
continue;
}
FLocation myFloc = new FLocation(player.getLocation());
Faction toFac = Board.getInstance().getFactionAt(myFloc);
if (Board.getInstance().getFactionAt(myFloc) != myFaction) {
if (!checkBypassPerms(fPlayer, player, toFac)) {
fPlayer.setFlying(false); fPlayer.setFlying(false);
flyMap.remove(name); flyMap.remove(name);
continue; continue;
} }
} if (fPlayer.checkIfNearbyEnemies()) {
continue;
}
FLocation myFloc = new FLocation(player.getLocation());
Faction toFac = Board.getInstance().getFactionAt(myFloc);
if (Board.getInstance().getFactionAt(myFloc) != myFaction) {
if (!checkBypassPerms(fPlayer, player, toFac)) {
fPlayer.setFlying(false);
flyMap.remove(name);
continue;
}
}
} }
} }
} }

View File

@ -0,0 +1,40 @@
package com.massivecraft.factions.cmd;
import com.massivecraft.factions.struct.Permission;
import com.massivecraft.factions.zcore.util.TL;
public class CmdInspect extends FCommand
{
public CmdInspect(){
super();
this.aliases.add("inspect");
this.aliases.add("ins");
this.permission = Permission.INSPECT.node;
this.disableOnLock = true;
senderMustBePlayer = true;
senderMustBeMember = true;
senderMustBeModerator = false;
senderMustBeColeader = false;
senderMustBeAdmin = false;
}
@Override
public void perform(){
if (fme.isInspectMode()){
fme.setInspectMode(false);
msg(TL.COMMAND_INSPECT_DISABLED);
} else {
fme.setInspectMode(true);
msg(TL.COMMAND_INSPECT_ENABLED);
}
}
@Override
public TL getUsageTranslation() {
return TL.COMMAND_INSPECT_DESCRIPTION;
}
}

View File

@ -25,6 +25,7 @@ public class CmdVersion extends FCommand {
@Override @Override
public void perform() { public void perform() {
msg(TL.COMMAND_VERSION_NAME); // Did this so people can differentiate between SavageFactions and FactionsUUID (( Requested Feature ))
msg(TL.COMMAND_VERSION_VERSION, P.p.getDescription().getFullName()); msg(TL.COMMAND_VERSION_VERSION, P.p.getDescription().getFullName());
} }

View File

@ -3,6 +3,7 @@ package com.massivecraft.factions.cmd;
import com.massivecraft.factions.Conf; import com.massivecraft.factions.Conf;
import com.massivecraft.factions.P; import com.massivecraft.factions.P;
import com.massivecraft.factions.zcore.util.TL; import com.massivecraft.factions.zcore.util.TL;
import net.coreprotect.CoreProtect;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import java.util.Collections; import java.util.Collections;
@ -93,6 +94,10 @@ public class FCmdRoot extends FCommand {
public CmdBanner cmdBanner = new CmdBanner(); public CmdBanner cmdBanner = new CmdBanner();
public CmdTpBanner cmdTpBanner = new CmdTpBanner(); public CmdTpBanner cmdTpBanner = new CmdTpBanner();
public CmdKillHolograms cmdKillHolograms = new CmdKillHolograms(); public CmdKillHolograms cmdKillHolograms = new CmdKillHolograms();
public CmdInspect cmdInspect = new CmdInspect();
public FCmdRoot() { public FCmdRoot() {
super(); super();
this.aliases.addAll(Conf.baseCommandAliases); this.aliases.addAll(Conf.baseCommandAliases);
@ -197,7 +202,12 @@ public class FCmdRoot extends FCommand {
this.addSubCommand(this.cmdTpBanner); this.addSubCommand(this.cmdTpBanner);
this.addSubCommand(this.cmdKillHolograms); this.addSubCommand(this.cmdKillHolograms);
if (CoreProtect.getInstance() != null){
P.p.log("Found CoreProtect, enabling Inspect");
this.addSubCommand(this.cmdInspect);
} else {
P.p.log("CoreProtect not found, disabling Inspect");
}
if (P.p.getConfig().getBoolean("enable-faction-flight", false)) { if (P.p.getConfig().getBoolean("enable-faction-flight", false)) {
this.addSubCommand(this.cmdFly); this.addSubCommand(this.cmdFly);

View File

@ -7,6 +7,7 @@ import com.massivecraft.factions.util.MiscUtil;
import com.massivecraft.factions.zcore.util.TL; import com.massivecraft.factions.zcore.util.TL;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.TravelAgent; import org.bukkit.TravelAgent;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.entity.*; import org.bukkit.entity.*;
@ -19,6 +20,7 @@ import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.hanging.HangingBreakEvent; import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.hanging.HangingBreakEvent.RemoveCause; import org.bukkit.event.hanging.HangingBreakEvent.RemoveCause;
import org.bukkit.event.hanging.HangingPlaceEvent; import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.event.player.PlayerPortalEvent; import org.bukkit.event.player.PlayerPortalEvent;
import org.bukkit.potion.PotionEffect; import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType; import org.bukkit.potion.PotionEffectType;
@ -252,6 +254,21 @@ public class FactionsEntityListener implements Listener {
} }
} }
//For disabling enderpearl throws
@EventHandler
public void onPearl(PlayerInteractEvent e) {
Player player = e.getPlayer();
if (player.getItemInHand().getType() == Material.ENDER_PEARL) {
FPlayer fPlayer = FPlayers.getInstance().getByPlayer(player);
if (fPlayer.isFlying()){
if (!Conf.noEnderpearlsInFly){
fPlayer.msg(TL.COMMAND_FLY_NO_EPEARL);
e.setCancelled(true);
}
}
}
}
// mainly for flaming arrows; don't want allies or people in safe zones to be ignited even after damage event is cancelled // mainly for flaming arrows; don't want allies or people in safe zones to be ignited even after damage event is cancelled
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true) @EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)

View File

@ -21,6 +21,8 @@ import com.massivecraft.factions.zcore.fperms.PermissableAction;
import com.massivecraft.factions.zcore.persist.MemoryFPlayer; import com.massivecraft.factions.zcore.persist.MemoryFPlayer;
import com.massivecraft.factions.zcore.util.TL; import com.massivecraft.factions.zcore.util.TL;
import com.massivecraft.factions.zcore.util.TextUtil; import com.massivecraft.factions.zcore.util.TextUtil;
import net.coreprotect.CoreProtect;
import net.coreprotect.CoreProtectAPI;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.Material; import org.bukkit.Material;
@ -257,6 +259,51 @@ public class FactionsPlayerListener implements Listener {
} }
} }
//inspect
@EventHandler
public void onInspect(PlayerInteractEvent e){
if (e.getAction().name().contains("BLOCK")){
FPlayer fplayer = FPlayers.getInstance().getByPlayer(e.getPlayer());
if (!fplayer.isInspectMode()){
return;
}
if (!fplayer.isAdminBypassing()){
if (fplayer.getFaction() != Board.getInstance().getFactionAt(new FLocation(e.getPlayer().getLocation()))){
fplayer.msg(TL.COMMAND_INSPECT_NOTINCLAIM);
return;
}
} else {
fplayer.msg(TL.COMMAND_INSPECT_BYPASS);
}
List<String[]> info = CoreProtect.getInstance().getAPI().blockLookup(e.getClickedBlock(),0);
if (info.size() == 0) {
e.getPlayer().sendMessage(TL.COMMAND_INSPECT_NODATA.toString());
return;
}
Player player = e.getPlayer();
CoreProtectAPI coAPI = CoreProtect.getInstance().getAPI();
player.sendMessage(TL.COMMAND_INSPECT_HEADER.toString().replace("{x}",e.getClickedBlock().getX() + "")
.replace("{y}",e.getClickedBlock().getY() + "")
.replace("{z}",e.getClickedBlock().getZ() + ""));
String rowFormat = TL.COMMAND_INSPECT_ROW.toString();
for (int i = 0; i < info.size(); i++){
CoreProtectAPI.ParseResult row = coAPI.parseResult((String[])info.get(0));
player.sendMessage(rowFormat
.replace("{time}",convertTime(row.getTime()))
.replace("{action}",row.getActionString())
.replace("{player}",row.getPlayer())
.replace("{block-type}",row.getType().toString().toLowerCase()));
}
}
}
private String convertTime(int time)
{
String result = String.valueOf(Math.round((System.currentTimeMillis() / 1000L - time) / 36.0D) / 100.0D);
return (result.length() == 3 ? result + "0" : result) + "/hrs ago";
}
// Holds the next time a player can have a map shown. // Holds the next time a player can have a map shown.
private HashMap<UUID, Long> showTimes = new HashMap<>(); private HashMap<UUID, Long> showTimes = new HashMap<>();
@ -318,7 +365,7 @@ public class FactionsPlayerListener implements Listener {
(relationTo == Relation.ENEMY && me.canflyinEnemy()) || (relationTo == Relation.ENEMY && me.canflyinEnemy()) ||
(relationTo == Relation.ALLY && me.canflyinAlly()) || (relationTo == Relation.ALLY && me.canflyinAlly()) ||
(relationTo == Relation.TRUCE && me.canflyinTruce()) || (relationTo == Relation.TRUCE && me.canflyinTruce()) ||
(relationTo == Relation.NEUTRAL && me.canflyinNeutral())) { (relationTo == Relation.NEUTRAL && me.canflyinNeutral() && !isSystemFaction(factionTo))) {
enableFly(me); enableFly(me);
} }
@ -390,6 +437,12 @@ public class FactionsPlayerListener implements Listener {
} }
public static Boolean isSystemFaction(Faction faction) {
return faction.isSafeZone() ||
faction.isWarZone() ||
faction.isWilderness();
}
HashMap<String,Boolean> bannerCooldownMap = new HashMap<>(); HashMap<String,Boolean> bannerCooldownMap = new HashMap<>();
public static HashMap<String,Location> bannerLocations = new HashMap<>(); public static HashMap<String,Location> bannerLocations = new HashMap<>();

View File

@ -98,6 +98,7 @@ public enum Permission {
BANNER("banner"), BANNER("banner"),
TPBANNER("tpbanner"), TPBANNER("tpbanner"),
KILLHOLOS("killholos"), KILLHOLOS("killholos"),
INSPECT("inspect"),
WARP("warp"); WARP("warp");
public final String node; public final String node;

View File

@ -38,6 +38,9 @@ public class ClipPlaceholderAPIManager extends PlaceholderExpansion implements R
return P.p.getDescription().getVersion(); return P.p.getDescription().getVersion();
} }
// Relational placeholders // Relational placeholders
@Override @Override
public String onPlaceholderRequest(Player p1, Player p2, String placeholder) { public String onPlaceholderRequest(Player p1, Player p2, String placeholder) {

View File

@ -1103,7 +1103,8 @@ public abstract class MemoryFPlayer implements FPlayer {
@Override @Override
public boolean checkIfNearbyEnemies(){ public boolean checkIfNearbyEnemies(){
Player me = this.getPlayer(); Player me = this.getPlayer();
for (Entity e : me.getNearbyEntities(16, 255, 16)) { int radius = Conf.enemyFlyCheckRadius;
for (Entity e : me.getNearbyEntities(radius, 255, radius)) {
if (e == null) { continue; } if (e == null) { continue; }
if (e instanceof Player) { if (e instanceof Player) {
Player eplayer = (((Player) e).getPlayer()); Player eplayer = (((Player) e).getPlayer());
@ -1125,7 +1126,6 @@ public abstract class MemoryFPlayer implements FPlayer {
@Override @Override
public Boolean canflyinWilderness() { public Boolean canflyinWilderness() {
return getPlayer().hasPermission("factions.fly.wilderness"); return getPlayer().hasPermission("factions.fly.wilderness");
} }
@Override @Override
@ -1165,6 +1165,19 @@ public abstract class MemoryFPlayer implements FPlayer {
} }
boolean inspectMode = false;
@Override
public boolean isInspectMode(){
return inspectMode;
}
@Override
public void setInspectMode( boolean status){
inspectMode = status;
}

View File

@ -285,6 +285,7 @@ public enum TL {
COMMAND_FLY_NO_ACCESS("&c&l[!]&7 &cCannot fly &7in territory of %1$s"), COMMAND_FLY_NO_ACCESS("&c&l[!]&7 &cCannot fly &7in territory of %1$s"),
COMMAND_FLY_ENEMY_NEAR("&c&l[!]&7 Flight has been&c disabled&7 an enemy is nearby"), COMMAND_FLY_ENEMY_NEAR("&c&l[!]&7 Flight has been&c disabled&7 an enemy is nearby"),
COMMAND_FLY_CHECK_ENEMY("&c&l[!]&7 Cannot fly here, an enemy is &cnearby"), COMMAND_FLY_CHECK_ENEMY("&c&l[!]&7 Cannot fly here, an enemy is &cnearby"),
COMMAND_FLY_NO_EPEARL("&c&l[!] &7You &ccannot&7 throw enderpearls while flying!"),
COMMAND_FWARP_CLICKTOWARP("&c&l[!]&7 Click to &cwarp!"), COMMAND_FWARP_CLICKTOWARP("&c&l[!]&7 Click to &cwarp!"),
COMMAND_FWARP_COMMANDFORMAT("&c&l[!]&7 /f warp <warpname> &c[password]"), COMMAND_FWARP_COMMANDFORMAT("&c&l[!]&7 /f warp <warpname> &c[password]"),
@ -308,6 +309,15 @@ public enum TL {
COMMAND_HOME_FORTELEPORT("for teleporting to your faction home"), COMMAND_HOME_FORTELEPORT("for teleporting to your faction home"),
COMMAND_HOME_DESCRIPTION("Teleport to the faction home"), COMMAND_HOME_DESCRIPTION("Teleport to the faction home"),
COMMAND_INSPECT_DISABLED("&c&l[!]&7 Inspect mode is now &cdisabled."),
COMMAND_INSPECT_ENABLED("&c&l[!]&7 Inspect mode is now &aEnabled."),
COMMAND_INSPECT_HEADER("&c&m---&7Inspect Data&c&m---&c//&7x:{x},y:{y},z:{z}"),
COMMAND_INSPECT_ROW("&c{time} &7// &c{action} &7// &c{player} &7// &c{block-type}"),
COMMAND_INSPECT_NODATA("&c&l[!]&7 &7No Data was found!"),
COMMAND_INSPECT_NOTINCLAIM("&c&l[!]&7 &7You can &conly&7 inspect in &cyour &7claims!"),
COMMAND_INSPECT_BYPASS("&c&l[!]&7 Inspecting in &cbypass&7 mode"),
COMMAND_INSPECT_DESCRIPTION("Inspect blocks!"),
COMMAND_INVITE_TOINVITE("to invite someone"), COMMAND_INVITE_TOINVITE("to invite someone"),
COMMAND_INVITE_FORINVITE("for inviting someone"), COMMAND_INVITE_FORINVITE("for inviting someone"),
COMMAND_INVITE_CLICKTOJOIN("Click to join!"), COMMAND_INVITE_CLICKTOJOIN("Click to join!"),
@ -675,7 +685,8 @@ public enum TL {
COMMAND_UNCLAIMALL_DESCRIPTION("Unclaim all of your factions land"), COMMAND_UNCLAIMALL_DESCRIPTION("Unclaim all of your factions land"),
COMMAND_UNCLAIM_CLICKTOUNCLAIM("Click to unclaim &2(%1$d, %2$d)"), COMMAND_UNCLAIM_CLICKTOUNCLAIM("Click to unclaim &2(%1$d, %2$d)"),
COMMAND_VERSION_VERSION("<i>You are running %1$s"), COMMAND_VERSION_NAME("&c&l[!]&7 SavageFactions &c» &7By ProSavage"),
COMMAND_VERSION_VERSION("&7Version &c» &7%1$s"),
COMMAND_VERSION_DESCRIPTION("Show plugin and translation version information"), COMMAND_VERSION_DESCRIPTION("Show plugin and translation version information"),
COMMAND_WARUNCLAIMALL_DESCRIPTION("Unclaim all warzone land"), COMMAND_WARUNCLAIMALL_DESCRIPTION("Unclaim all warzone land"),

View File

@ -2,7 +2,7 @@ name: Factions
version: ${project.version}-SF-1.0.23-BETA version: ${project.version}-SF-1.0.23-BETA
main: com.massivecraft.factions.P main: com.massivecraft.factions.P
authors: [Olof Larsson, Brett Flannigan, drtshock, ProSavage] authors: [Olof Larsson, Brett Flannigan, drtshock, ProSavage]
softdepend: [PlayerVaults, PlaceholderAPI, MVdWPlaceholderAPI, PermissionsEx, Permissions, Essentials, EssentialsChat, HeroChat, iChat, LocalAreaChat, LWC, nChat, ChatManager, CAPI, AuthMe, Vault, Spout, WorldEdit, WorldGuard, AuthDB, CaptureThePoints, CombatTag, dynmap, FactionsTop] softdepend: [CoreProtect, PlayerVaults, PlaceholderAPI, MVdWPlaceholderAPI, PermissionsEx, Permissions, Essentials, EssentialsChat, HeroChat, iChat, LocalAreaChat, LWC, nChat, ChatManager, CAPI, AuthMe, Vault, Spout, WorldEdit, WorldGuard, AuthDB, CaptureThePoints, CombatTag, dynmap, FactionsTop]
commands: commands:
factions: factions:
description: Reference command for Factions. description: Reference command for Factions.