diff --git a/pom.xml b/pom.xml index 7f58ee11..bea9a61a 100644 --- a/pom.xml +++ b/pom.xml @@ -4,10 +4,10 @@ com.massivecraft Factions - 1.6.9.5-U0.2.1-RC-1.6.2-RC + 1.6.9.5-U0.2.1-1.0-BETA jar - SavageFactions + SavageFactionsPlus UTF-8 @@ -69,7 +69,7 @@ maven-jar-plugin 2.3.2 - Factions-${maven.build.timestamp} + SavageFactionsPlus-${maven.build.timestamp} diff --git a/src/main/java/com/massivecraft/factions/Conf.java b/src/main/java/com/massivecraft/factions/Conf.java index 47435bfb..a27e6f12 100644 --- a/src/main/java/com/massivecraft/factions/Conf.java +++ b/src/main/java/com/massivecraft/factions/Conf.java @@ -55,6 +55,7 @@ public class Conf { public static boolean newFactionsDefaultOpen = false; // when faction membership hits this limit, players will no longer be able to join using /f join; default is 0, no limit public static int factionMemberLimit = 0; + public static int factionAltMemberLimit = 0; // what faction ID to start new players in when they first join the server; default is 0, "no faction" public static String newPlayerStartingFactionID = "0"; public static boolean showMapFactionKey = true; diff --git a/src/main/java/com/massivecraft/factions/FPlayer.java b/src/main/java/com/massivecraft/factions/FPlayer.java index 359f09ba..976c67f2 100644 --- a/src/main/java/com/massivecraft/factions/FPlayer.java +++ b/src/main/java/com/massivecraft/factions/FPlayer.java @@ -26,6 +26,11 @@ import java.util.List; public interface FPlayer extends EconomyParticipator { + + public void setAlt(boolean alt); + + public boolean isAlt(); + /** * Used to know if stealth is toggled on or off * @@ -62,7 +67,7 @@ public interface FPlayer extends EconomyParticipator { * * @param faction faction to set. */ - void setFaction(Faction faction); + void setFaction(Faction faction, boolean alt); /** * Gets the faction ID of the player. diff --git a/src/main/java/com/massivecraft/factions/Faction.java b/src/main/java/com/massivecraft/factions/Faction.java index f8d69bab..ce25eeac 100644 --- a/src/main/java/com/massivecraft/factions/Faction.java +++ b/src/main/java/com/massivecraft/factions/Faction.java @@ -21,6 +21,17 @@ import java.util.*; import java.util.concurrent.ConcurrentHashMap; public interface Faction extends EconomyParticipator { + + boolean altInvited(FPlayer fplayer); + + void altInvite(FPlayer fplayer); + + boolean addAltPlayer(FPlayer fplayer); + + boolean removeAltPlayer(FPlayer fplayer); + + Set getAltPlayers(); + HashMap> getAnnouncements(); ConcurrentHashMap getWarps(); diff --git a/src/main/java/com/massivecraft/factions/SavageFactions.java b/src/main/java/com/massivecraft/factions/SavageFactions.java index 73cde51f..001eccc7 100644 --- a/src/main/java/com/massivecraft/factions/SavageFactions.java +++ b/src/main/java/com/massivecraft/factions/SavageFactions.java @@ -179,7 +179,11 @@ public class SavageFactions extends MPlugin { fPlayer.resetFactionData(false); continue; } - faction.addFPlayer(fPlayer); + if (fPlayer.isAlt()) { + faction.addAltPlayer(fPlayer); + } else { + faction.addFPlayer(fPlayer); + } } UtilFly.run(); diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdAdmin.java b/src/main/java/com/massivecraft/factions/cmd/CmdAdmin.java index 3f96623c..752b0887 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdAdmin.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdAdmin.java @@ -8,6 +8,7 @@ import com.massivecraft.factions.struct.Permission; import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.zcore.util.TL; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; public class CmdAdmin extends FCommand { @@ -40,6 +41,11 @@ public class CmdAdmin extends FCommand { boolean permAny = Permission.ADMIN_ANY.has(sender, false); Faction targetFaction = fyou.getFaction(); + if(fyou.isAlt()){ + msg(ChatColor.RED + "You can not promote alt accounts."); + return; + } + if (targetFaction != myFaction && !permAny) { msg(TL.COMMAND_ADMIN_NOTMEMBER, fyou.describeTo(fme, true)); return; diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdColeader.java b/src/main/java/com/massivecraft/factions/cmd/CmdColeader.java index 926df953..14967650 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdColeader.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdColeader.java @@ -51,6 +51,11 @@ public class CmdColeader extends FCommand { boolean permAny = Permission.COLEADER_ANY.has(sender, false); Faction targetFaction = you.getFaction(); + if(you.isAlt()){ + msg(ChatColor.RED + "You can not promote alt accounts."); + return; + } + if (targetFaction != myFaction && !permAny) { msg(TL.COMMAND_MOD_NOTMEMBER, you.describeTo(fme, true)); return; diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdCreate.java b/src/main/java/com/massivecraft/factions/cmd/CmdCreate.java index 5169c1f7..d9cadecb 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdCreate.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdCreate.java @@ -86,7 +86,7 @@ public class CmdCreate extends FCommand { // join event cannot be cancelled or you'll have an empty faction // finish setting up the FPlayer - fme.setFaction(faction); + fme.setFaction(faction, false); // We should consider adding the role just AFTER joining the faction. // That way we don't have to mess up deleting more stuff. // And prevent the user from being returned to NORMAL after deleting his old faction. diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdInviteAlt.java b/src/main/java/com/massivecraft/factions/cmd/CmdInviteAlt.java new file mode 100644 index 00000000..a1c56582 --- /dev/null +++ b/src/main/java/com/massivecraft/factions/cmd/CmdInviteAlt.java @@ -0,0 +1,96 @@ +package com.massivecraft.factions.cmd; + +import com.massivecraft.factions.Conf; +import com.massivecraft.factions.FPlayer; +import com.massivecraft.factions.SavageFactions; +import com.massivecraft.factions.struct.Permission; +import com.massivecraft.factions.struct.Role; +import com.massivecraft.factions.zcore.fperms.Access; +import com.massivecraft.factions.zcore.fperms.PermissableAction; +import com.massivecraft.factions.zcore.util.TL; +import mkremins.fanciful.FancyMessage; +import org.bukkit.ChatColor; + +public class CmdInviteAlt extends FCommand { + + public CmdInviteAlt() { + super(); + this.aliases.add("altinvite"); + this.aliases.add("altinv"); + this.aliases.add("invalt"); + this.aliases.add("invitealt"); + + this.requiredArgs.add("player name"); + // this.optionalArgs.put("", ""); + + this.permission = Permission.INVITE.node; + this.disableOnLock = true; + + senderMustBePlayer = true; + senderMustBeMember = false; + senderMustBeModerator = false; + senderMustBeColeader = false; + senderMustBeAdmin = false; + } + + @Override + public void perform() { + if(!SavageFactions.plugin.getConfig().getBoolean("f-alts.Enabled", false)){ + fme.msg(TL.GENERIC_DISABLED); + return; + } + + FPlayer target = this.argAsBestFPlayerMatch(0); + if (target == null) { + return; + } + + if (target.getFaction() == myFaction) { + msg(TL.COMMAND_INVITE_ALREADYMEMBER, target.getName(), myFaction.getTag()); + msg(TL.GENERIC_YOUMAYWANT.toString() + p.cmdBase.cmdAltKick.getUseageTemplate(false)); + return; + } + + // if economy is enabled, they're not on the bypass list, and this + // command has a cost set, make 'em pay + if (!payForCommand(Conf.econCostInvite, TL.COMMAND_INVITE_TOINVITE.toString(), TL.COMMAND_INVITE_FORINVITE.toString())) { + return; + } + + Access access = myFaction.getAccess(target, PermissableAction.INVITEALT); + if (access == Access.DENY || (access == Access.UNDEFINED && !assertMinRole(Role.MODERATOR))) { + fme.msg(TL.GENERIC_FPERM_NOPERMISSION, "invitealt"); + return; + } + + if (myFaction.isBanned(target)) { + fme.msg(TL.COMMAND_INVITE_BANNED, target.getName()); + return; + } + + myFaction.deinvite(target); + myFaction.altInvite(target); + if (!target.isOnline()) { + return; + } + + FancyMessage message = new FancyMessage(fme.describeTo(target, true)) + .tooltip(TL.COMMAND_INVITE_CLICKTOJOIN.toString()) + .command("/" + Conf.baseCommandAliases.get(0) + " join " + myFaction.getTag()) + .then(TL.COMMAND_INVITE_INVITEDYOU.toString()) + .color(ChatColor.YELLOW) + .tooltip(TL.COMMAND_INVITE_CLICKTOJOIN.toString()) + .command("/" + Conf.baseCommandAliases.get(0) + " join " + myFaction.getTag()) + .then(myFaction.describeTo(target)).tooltip(TL.COMMAND_INVITE_CLICKTOJOIN.toString()) + .command("/" + Conf.baseCommandAliases.get(0) + " join " + myFaction.getTag()); + + message.send(target.getPlayer()); + + myFaction.msg(TL.COMMAND_INVITE_INVITED, fme.describeTo(myFaction, true), target.describeTo(myFaction)); + } + + @Override + public TL getUsageTranslation() { + return TL.COMMAND_ALTINVITE_DESCRIPTION; + } +} diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdJoin.java b/src/main/java/com/massivecraft/factions/cmd/CmdJoin.java index 3688b2b4..93014472 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdJoin.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdJoin.java @@ -76,6 +76,13 @@ public class CmdJoin extends FCommand { return; } + int altLimit = Conf.factionAltMemberLimit; + + if (altLimit > 0 && faction.getAltPlayers().size() >= altLimit && !faction.altInvited(fme)) { + msg(TL.COMMAND_JOIN_ATLIMIT, faction.getTag(fme), altLimit, fplayer.describeTo(fme, false)); + return; + } + // if economy is enabled, they're not on the bypass list, and this command has a cost set, make sure they can pay if (samePlayer && !canAffordCommand(Conf.econCostJoin, TL.COMMAND_JOIN_TOJOIN.toString())) { return; @@ -107,7 +114,14 @@ public class CmdJoin extends FCommand { faction.msg(TL.COMMAND_JOIN_JOINED, fplayer.describeTo(faction, true)); fplayer.resetFactionData(); - fplayer.setFaction(faction); + + if(faction.altInvited(fplayer)){ + fplayer.setAlt(true); + fplayer.setFaction(faction, true); + } else { + fplayer.setFaction(faction, false); + } + faction.deinvite(fplayer); fme.setRole(faction.getDefaultRole()); diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdKick.java b/src/main/java/com/massivecraft/factions/cmd/CmdKick.java index 0cb144bb..8c339e76 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdKick.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdKick.java @@ -67,6 +67,11 @@ public class CmdKick extends FCommand { return; } + if(toKick.isAlt()){ + msg(TL.GENERIC_YOUMAYWANT.toString() + p.cmdBase.cmdAltKick.getUseageTemplate(false)); + return; + } + Faction toKickFaction = toKick.getFaction(); if (toKickFaction.isWilderness()) { diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdMod.java b/src/main/java/com/massivecraft/factions/cmd/CmdMod.java index 56ab092b..99d08453 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdMod.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdMod.java @@ -48,6 +48,12 @@ public class CmdMod extends FCommand { boolean permAny = Permission.MOD_ANY.has(sender, false); Faction targetFaction = you.getFaction(); + + if(you.isAlt()){ + msg(ChatColor.RED + "You can not promote alt accounts."); + return; + } + if (targetFaction != myFaction && !permAny) { msg(TL.COMMAND_MOD_NOTMEMBER, you.describeTo(fme, true)); return; diff --git a/src/main/java/com/massivecraft/factions/cmd/CmdShow.java b/src/main/java/com/massivecraft/factions/cmd/CmdShow.java index ffc547b2..2a768578 100644 --- a/src/main/java/com/massivecraft/factions/cmd/CmdShow.java +++ b/src/main/java/com/massivecraft/factions/cmd/CmdShow.java @@ -33,6 +33,7 @@ public class CmdShow extends FCommand { defaults.add("Allies({allies}/{max-allies}): {allies-list}"); defaults.add("Online: ({online}/{members}): {online-list}"); defaults.add("Offline: ({offline}/{members}): {offline-list}"); + defaults.add("Alt List: {alts}"); // this.requiredArgs.add(""); this.optionalArgs.put("faction tag", "yours"); diff --git a/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java b/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java index 6945656a..a86f4d6c 100644 --- a/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java +++ b/src/main/java/com/massivecraft/factions/cmd/FCmdRoot.java @@ -107,6 +107,9 @@ public class FCmdRoot extends FCommand { public CmdSetBanner cmdSetBanner = new CmdSetBanner(); public CmdStrike cmdStrike = new CmdStrike(); public CmdSetStrikes cmdSetStrikes = new CmdSetStrikes(); + public CmdKickAlt cmdAltKick = new CmdKickAlt(); + public CmdInviteAlt cmdAltInvite = new CmdInviteAlt(); + public FCmdRoot() { @@ -221,6 +224,11 @@ public class FCmdRoot extends FCommand { this.addSubCommand(this.cmdChest); this.addSubCommand(this.cmdSetBanner); + if(SavageFactions.plugin.getConfig().getBoolean("f-alts.Enabled")){ + this.addSubCommand(this.cmdAltInvite); + this.addSubCommand(this.cmdAltKick); + } + if (SavageFactions.plugin.getConfig().getBoolean("f-grace.Enabled")) { this.addSubCommand(this.cmdGrace); } diff --git a/src/main/java/com/massivecraft/factions/cmd/FPromoteCommand.java b/src/main/java/com/massivecraft/factions/cmd/FPromoteCommand.java index 94366584..f1037756 100644 --- a/src/main/java/com/massivecraft/factions/cmd/FPromoteCommand.java +++ b/src/main/java/com/massivecraft/factions/cmd/FPromoteCommand.java @@ -6,6 +6,7 @@ import com.massivecraft.factions.struct.Role; import com.massivecraft.factions.zcore.fperms.Access; import com.massivecraft.factions.zcore.fperms.PermissableAction; import com.massivecraft.factions.zcore.util.TL; +import org.bukkit.ChatColor; public class FPromoteCommand extends FCommand { @@ -38,6 +39,11 @@ public class FPromoteCommand extends FCommand { return; } + if(target.isAlt()){ + msg(ChatColor.RED + "You can not edit the rank of alt accounts."); + return; + } + Role current = target.getRole(); Role promotion = Role.getRelative(current, +relative); diff --git a/src/main/java/com/massivecraft/factions/skript/expressions/player/PlayerFactionExpression.java b/src/main/java/com/massivecraft/factions/skript/expressions/player/PlayerFactionExpression.java index 4c33f291..98f8d721 100644 --- a/src/main/java/com/massivecraft/factions/skript/expressions/player/PlayerFactionExpression.java +++ b/src/main/java/com/massivecraft/factions/skript/expressions/player/PlayerFactionExpression.java @@ -80,14 +80,14 @@ public class PlayerFactionExpression extends SimpleExpression { switch (mode) { case DELETE: case RESET: - fPlayer.setFaction(Factions.getInstance().getWilderness()); + fPlayer.setFaction(Factions.getInstance().getWilderness(), false); break; case SET: Faction faction = Factions.getInstance().getByTag((String) delta[0]); if (faction == null) { faction = Factions.getInstance().getWilderness(); } - fPlayer.setFaction(faction); + fPlayer.setFaction(faction, false); break; default: } diff --git a/src/main/java/com/massivecraft/factions/struct/Permission.java b/src/main/java/com/massivecraft/factions/struct/Permission.java index 1ae6952e..0b729511 100644 --- a/src/main/java/com/massivecraft/factions/struct/Permission.java +++ b/src/main/java/com/massivecraft/factions/struct/Permission.java @@ -9,6 +9,7 @@ public enum Permission { OWNERSHIP_BYPASS("ownershipbypass"), ADMIN("admin"), ADMIN_ANY("admin.any"), + INVITEALT("invitealt"), AHOME("ahome"), ANNOUNCE("announce"), AUTOCLAIM("autoclaim"), diff --git a/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java b/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java index 4f1eb1a2..68ff7cad 100644 --- a/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java +++ b/src/main/java/com/massivecraft/factions/zcore/fperms/PermissableAction.java @@ -29,6 +29,8 @@ public enum PermissableAction { INVITE("invite"), KICK("kick"), ITEM("items"), // generic for most items + INVITEALT("invitealt"), + KICKALT("kickalt"), SETHOME("sethome"), TERRITORY("territory"), ACCESS("access"), diff --git a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java index 5199d9a7..fe3edfa6 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFPlayer.java @@ -80,12 +80,22 @@ public abstract class MemoryFPlayer implements FPlayer { protected boolean isStealthEnabled = false; boolean playerAlerts = false; boolean inspectMode = false; + protected boolean isAlt = false; + + public void setAlt(boolean alt){ + this.isAlt = alt; + } + + public boolean isAlt() { + return isAlt; + } public MemoryFPlayer() { } public MemoryFPlayer(String id) { this.id = id; + this.isAlt = false; this.resetFactionData(false); this.power = Conf.powerPlayerStarting; this.lastPowerUpdateTime = System.currentTimeMillis(); @@ -109,6 +119,7 @@ public abstract class MemoryFPlayer implements FPlayer { public MemoryFPlayer(MemoryFPlayer other) { this.factionId = other.factionId; this.id = other.id; + this.isAlt = other.isAlt; this.power = other.power; this.lastLoginTime = other.lastLoginTime; this.mapAutoUpdating = other.mapAutoUpdating; @@ -154,12 +165,20 @@ public abstract class MemoryFPlayer implements FPlayer { return Factions.getInstance().getFactionById(this.factionId); } - public void setFaction(Faction faction) { + public void setFaction(Faction faction, boolean alt) { Faction oldFaction = this.getFaction(); if (oldFaction != null) { + if (this.isAlt()) { + oldFaction.removeAltPlayer(this); + } + oldFaction.removeFPlayer(this); } - faction.addFPlayer(this); + if (alt) { + faction.addAltPlayer(this); + } else { + faction.addFPlayer(this); + } this.factionId = faction.getId(); } @@ -317,6 +336,7 @@ public abstract class MemoryFPlayer implements FPlayer { this.role = Role.NORMAL; this.title = ""; this.autoClaimFor = null; + this.isAlt = false; } public void resetFactionData() { @@ -701,6 +721,12 @@ public abstract class MemoryFPlayer implements FPlayer { } myFaction.removeAnnouncements(this); + + if(this.isAlt()){ + myFaction.removeAltPlayer(this); + this.msg(TL.LEAVE_LEFT, this.describeTo(this, true), myFaction.describeTo(this)); + } + this.resetFactionData(); if (myFaction.isNormal() && !perm && myFaction.getFPlayers().isEmpty()) { diff --git a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java index 7a2ce25f..f6ae71eb 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/MemoryFaction.java @@ -56,7 +56,9 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { protected Map relationWish = new HashMap<>(); protected Map> claimOwnership = new ConcurrentHashMap<>(); protected transient Set fplayers = new HashSet<>(); + protected transient Set alts = new HashSet<>(); protected Set invites = new HashSet<>(); + protected Set altinvites = new HashSet<>(); protected HashMap> announcements = new HashMap<>(); protected ConcurrentHashMap warps = new ConcurrentHashMap<>(); protected ConcurrentHashMap warpPasswords = new ConcurrentHashMap<>(); @@ -111,6 +113,7 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { relationWish = old.relationWish; claimOwnership = old.claimOwnership; fplayers = new HashSet<>(); + alts = new HashSet<>(); invites = old.invites; announcements = old.announcements; this.defaultRole = Role.NORMAL; @@ -217,6 +220,10 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return invites; } + public Set getAltInvites() { + return altinvites; + } + public String getId() { return id; } @@ -229,12 +236,26 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { this.invites.add(fplayer.getId()); } + public void altInvite(FPlayer fplayer) { + this.altinvites.add(fplayer.getId()); + } + public void deinvite(FPlayer fplayer) { this.invites.remove(fplayer.getId()); + this.altinvites.remove(fplayer.getId()); + } + + public boolean altInvited(FPlayer fplayer) { + if (this.altinvites.contains(fplayer.getId())) + return true; + return false; } public boolean isInvited(FPlayer fplayer) { - return this.invites.contains(fplayer.getId()); + if (this.invites.contains(fplayer.getId()) || this.altinvites.contains(fplayer.getId())) { + return true; + } + return false; } public void ban(FPlayer target, FPlayer banner) { @@ -835,6 +856,9 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { for (FPlayer fplayer : fplayers) { ret += fplayer.getPower(); } + for (FPlayer fplayer : alts) { + ret += fplayer.getPower(); + } if (Conf.powerFactionMax > 0 && ret > Conf.powerFactionMax) { ret = Conf.powerFactionMax; } @@ -850,6 +874,9 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { for (FPlayer fplayer : fplayers) { ret += fplayer.getPowerMax(); } + for (FPlayer fplayer : alts) { + ret += fplayer.getPowerMax(); + } if (Conf.powerFactionMax > 0 && ret > Conf.powerFactionMax) { ret = Conf.powerFactionMax; } @@ -883,13 +910,18 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { // maintain the reference list of FPlayers in this faction public void refreshFPlayers() { fplayers.clear(); + alts.clear(); if (this.isPlayerFreeType()) { return; } for (FPlayer fplayer : FPlayers.getInstance().getAllFPlayers()) { if (fplayer.getFactionId().equalsIgnoreCase(id)) { - fplayers.add(fplayer); + if (fplayer.isAlt()) { + alts.add(fplayer); + } else { + fplayers.add(fplayer); + } } } } @@ -902,8 +934,17 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return !this.isPlayerFreeType() && fplayers.remove(fplayer); } + + public boolean addAltPlayer(FPlayer fplayer) { + return !this.isPlayerFreeType() && alts.add(fplayer); + } + + public boolean removeAltPlayer(FPlayer fplayer) { + return !this.isPlayerFreeType() && alts.remove(fplayer); + } + public int getSize() { - return fplayers.size(); + return fplayers.size() + alts.size(); } public Set getFPlayers() { @@ -912,6 +953,12 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return new HashSet<>(fplayers); } + public Set getAltPlayers() { + // return a shallow copy of the FPlayer list, to prevent tampering and + // concurrency issues + return new HashSet<>(alts); + } + public Set getFPlayersWhereOnline(boolean online) { Set ret = new HashSet<>(); if (!this.isNormal()) { @@ -987,6 +1034,7 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { return ret; } + public ArrayList getOnlinePlayers() { ArrayList ret = new ArrayList<>(); if (this.isPlayerFreeType()) { @@ -995,7 +1043,7 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { for (Player player : SavageFactions.plugin.getServer().getOnlinePlayers()) { FPlayer fplayer = FPlayers.getInstance().getByPlayer(player); - if (fplayer.getFaction() == this) { + if (fplayer.getFaction() == this && !fplayer.isAlt()) { ret.add(player); } } @@ -1251,6 +1299,11 @@ public abstract class MemoryFaction implements Faction, EconomyParticipator { for (FPlayer fPlayer : fplayers) { fPlayer.resetFactionData(false); } + + + for (FPlayer fPlayer : alts) { + fPlayer.resetFactionData(false); + } } public Set getAllClaims() { diff --git a/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFaction.java b/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFaction.java index c96e85c9..6068cde9 100644 --- a/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFaction.java +++ b/src/main/java/com/massivecraft/factions/zcore/persist/json/JSONFaction.java @@ -14,4 +14,5 @@ public class JSONFaction extends MemoryFaction { public JSONFaction(String id) { super(id); } + } diff --git a/src/main/java/com/massivecraft/factions/zcore/util/TL.java b/src/main/java/com/massivecraft/factions/zcore/util/TL.java index 0ddf6190..c2126dc0 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TL.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TL.java @@ -146,6 +146,12 @@ public enum TL { COMMAND_AUTOCLAIM_OTHERFACTION("&c&l[!]&7 You &ccan't &7claim land for &c%1$s&7."), COMMAND_AUTOCLAIM_DESCRIPTION("Auto-claim land as you walk around"), + + COMMAND_ALTINVITE_DESCRIPTION("Invite Alts to your faction."), + COMMAND_ALTKICK_DESCRIPTION("Kick alts from your faction"), + COMMAND_ALTKICK_NOTALT("&c&l[!] &7Player is not an alt."), + COMMAND_ALTKICK_NOTMEMBER("&c&l[!] &7This player is not a member of your faction."), + COMMAND_AUTOHELP_HELPFOR("Help for command \""), COMMAND_BAN_DESCRIPTION("Ban players from joining your Faction."), @@ -763,7 +769,7 @@ public enum TL { COMMAND_UNCLAIMALL_DESCRIPTION("Unclaim all of your factions land"), COMMAND_UNCLAIM_CLICKTOUNCLAIM("Click to unclaim &2(%1$d, %2$d)"), - COMMAND_VERSION_NAME("&c&l[!]&7 &c&k||| &r&4SavageFactions&7 &c&k|||&r &c» &7By ProSavage"), + COMMAND_VERSION_NAME("&c&l[!]&7 &c&k||| &r&4SavageFactions+&7 &c&k|||&r &c» &7By Driftay & ProSavage"), COMMAND_VERSION_VERSION("&7Version &c» &7%1$s"), COMMAND_VERSION_DESCRIPTION("Show plugin and translation version information"), diff --git a/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java b/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java index ff3bea5b..f49ce0ac 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TagReplacer.java @@ -26,6 +26,7 @@ public enum TagReplacer { ENEMIES_LIST(TagType.FANCY, "{enemies-list}"), TRUCES_LIST(TagType.FANCY, "{truces-list}"), OFFLINE_LIST(TagType.FANCY, "{offline-list}"), + ALTS(TagType.FANCY, "{alts}"), /** * Player variables, require a player diff --git a/src/main/java/com/massivecraft/factions/zcore/util/TagUtil.java b/src/main/java/com/massivecraft/factions/zcore/util/TagUtil.java index e0639037..6c4f1c96 100644 --- a/src/main/java/com/massivecraft/factions/zcore/util/TagUtil.java +++ b/src/main/java/com/massivecraft/factions/zcore/util/TagUtil.java @@ -233,7 +233,32 @@ public class TagUtil { } fancyMessages.add(currentOffline); return firstOffline && minimal ? null : fancyMessages; // we must return here and not outside the switch + case ALTS: + FancyMessage alts = SavageFactions.plugin.txt.parseFancy(prefix); + boolean firstAlt = true; + for (FPlayer p : target.getAltPlayers()) { + String name = p.getName(); + ChatColor color; + + if (p.isOnline()) { + color = ChatColor.GREEN; + } else { + color = ChatColor.RED; + } + + alts.then(firstAlt ? name : ", " + name); + alts.tooltip(tipPlayer(p)).color(color); + firstAlt = false; + if (alts.toJSONString().length() > ARBITRARY_LIMIT) { + fancyMessages.add(alts); + currentOffline = new FancyMessage(""); + } + + } + fancyMessages.add(alts); + return firstAlt && minimal ? null : fancyMessages; default: + break; } return null; } diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index a917f3af..8eab41fb 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -287,6 +287,7 @@ show: - '&6 * &eEnemies &c{enemies-list}' - '&6 * &eOnline Members &8(&7{online}/{members}&8) &7{online-list}' - '&6 * &eOffline Members &8(&7{offline}/{members}&8) &7{offline-list}' + - '&6 * &eAlts &8{alts}' - '&6 * &eBans &7{faction-bancount}' - '&8&m----------------------------------------' # For a /f show that does not display fancy messages that are essentially empty, use minimal-show @@ -520,6 +521,8 @@ fperm-gui: tntfill: 41 chest: 42 spawner: 38 + invitealt: 50 + kickalt: 48 home: 49 # Material to show, if the material is colorable eg: Wool, Stained Clay it will update with it's access color materials: @@ -553,6 +556,8 @@ fperm-gui: chest: STAINED_GLASS spawner: STAINED_GLASS home: STAINED_GLASS + invitealt: STAINED_GLASS + kickalt: STAINED_GLASS # Same dummy items format as above dummy-items: '0': @@ -713,6 +718,15 @@ faction-disband-broadcast: true ############################################################ See-Invisible-Faction-Members: false + +############################################################ +# +------------------------------------------------------+ # +# | Faction Alt Accounts | # +# +------------------------------------------------------+ # +############################################################ +f-alts: + Enabled: true + ############################################################ # +------------------------------------------------------+ # # | Faction Rules | # @@ -773,7 +787,6 @@ Falling-Block-Fix: # | Faction GracePeriod | # # +------------------------------------------------------+ # ############################################################ - f-grace: Enabled: true @@ -1129,6 +1142,7 @@ Tntfill: # - {enemies-list} : Lists each faction enemy with tooltips # - {online-list} : Lists all online members with tooltips # - {offline-list} : Lists all offline members with tooltips +# - {alts} : List all alts online or offline # Player variables. Can be used in tooltips.show, scoreboards, or /f show # - {group} : Players group # - {name} : Players name