Fixes POM, and moves things around

This commit is contained in:
2022-08-05 00:34:54 +02:00
parent e3ef78f8f8
commit bb0be8a3f0
613 changed files with 27424 additions and 26469 deletions

View File

@ -0,0 +1,15 @@
package com.massivecraft.factions.engine;
public enum DisallowCause {
// -------------------------------------------- //
// ENUM
// -------------------------------------------- //
PEACEFUL_LAND,
FACTIONLESS,
FRIENDLYFIRE,
OWN_TERRITORY
// END OF LIST
}

View File

@ -0,0 +1,269 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.Rel;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.event.EventFactionsPvpDisallowed;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.MUtil;
import org.bukkit.entity.Arrow;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Trident;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.AreaEffectCloudApplyEvent;
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.PotionSplashEvent;
import org.bukkit.projectiles.ProjectileSource;
import java.util.ArrayList;
import java.util.List;
public class EngineCanCombatHappen extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineCanCombatHappen i = new EngineCanCombatHappen();
public static EngineCanCombatHappen get() {
return i;
}
// -------------------------------------------- //
// CAN COMBAT DAMAGE HAPPEN
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void canCombatDamageHappen(EntityDamageByEntityEvent event) {
if (this.canCombatDamageHappen(event, true)) {
return;
}
event.setCancelled(true);
Entity damager = event.getDamager();
if (damager instanceof Arrow && !(damager instanceof Trident)) {
damager.remove();
}
}
// 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)
public void canCombatDamageHappen(EntityCombustByEntityEvent event) {
EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(event.getCombuster(), event.getEntity(), EntityDamageEvent.DamageCause.FIRE, 0D);
if (this.canCombatDamageHappen(sub, false)) {
return;
}
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void canCombatDamageHappen(PotionSplashEvent event) {
// If a harmful potion is splashing ...
if (!MUtil.isHarmfulPotion(event.getPotion())) {
return;
}
ProjectileSource projectileSource = event.getPotion().getShooter();
if (!(projectileSource instanceof Entity)) {
return;
}
Entity thrower = (Entity) projectileSource;
// ... scan through affected entities to make sure they're all valid targets.
for (LivingEntity affectedEntity : event.getAffectedEntities()) {
EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(thrower, affectedEntity, EntityDamageEvent.DamageCause.CUSTOM, 0D);
if (this.canCombatDamageHappen(sub, true)) {
continue;
}
// affected entity list doesn't accept modification (iter.remove() is a no-go), but this works
event.setIntensity(affectedEntity, 0.0);
}
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void canCombatDamageHappen(AreaEffectCloudApplyEvent event) {
// If a harmful potion effect cloud is present ...
if (!MUtil.isHarmfulPotion(event.getEntity().getBasePotionData().getType().getEffectType())) {
return;
}
ProjectileSource projectileSource = event.getEntity().getSource();
if (!(projectileSource instanceof Entity)) {
return;
}
Entity thrower = (Entity) projectileSource;
// ... create a dummy list to avoid ConcurrentModificationException ...
List<LivingEntity> affectedList = new ArrayList<>();
// ... then scan through affected entities to make sure they're all valid targets ...
for (LivingEntity affectedEntity : event.getAffectedEntities()) {
EntityDamageByEntityEvent sub = new EntityDamageByEntityEvent(thrower, affectedEntity, EntityDamageEvent.DamageCause.CUSTOM, 0D);
// Notification disabled due to the iterating nature of effect clouds.
if (EngineCanCombatHappen.get().canCombatDamageHappen(sub, false)) {
continue;
}
affectedList.add(affectedEntity);
}
// finally, remove valid targets from the affected list. (Unlike splash potions, area effect cloud's affected entities list is mutable.)
event.getAffectedEntities().removeAll(affectedList);
}
// Utility method used in "canCombatDamageHappen" below.
public static boolean falseUnlessDisallowedPvpEventCancelled(Player attacker, Player defender, DisallowCause reason, EntityDamageByEntityEvent event) {
EventFactionsPvpDisallowed dpe = new EventFactionsPvpDisallowed(attacker, defender, reason, event);
dpe.run();
return dpe.isCancelled();
}
public boolean canCombatDamageHappen(EntityDamageByEntityEvent event, boolean notify) {
boolean ret = true;
// If the defender is a player ...
Entity edefender = event.getEntity();
if (MUtil.isntPlayer(edefender)) {
return true;
}
Player defender = (Player) edefender;
MPlayer mdefender = MPlayer.get(edefender);
// ... and the attacker is someone else ...
Entity eattacker = MUtil.getLiableDamager(event);
// (we check null here since there may not be an attacker)
// (lack of attacker situations can be caused by other bukkit plugins)
if (eattacker != null && eattacker.equals(edefender)) {
return true;
}
// ... gather defender PS and faction information ...
PS defenderPs = PS.valueOf(defender.getLocation());
Faction defenderPsFaction = BoardColl.get().getFactionAt(defenderPs);
// ... fast evaluate if the attacker is overriding ...
if (MUtil.isPlayer(eattacker)) {
MPlayer mplayer = MPlayer.get(eattacker);
if (mplayer != null && mplayer.isOverriding()) {
return true;
}
}
// ... PVP flag may cause a damage block ...
if (defenderPsFaction.getFlag(MFlag.getFlagPvp()) == false) {
if (eattacker == null) {
// No attacker?
// Let's behave as if it were a player
return falseUnlessDisallowedPvpEventCancelled(null, defender, DisallowCause.PEACEFUL_LAND, event);
}
if (MUtil.isPlayer(eattacker)) {
ret = falseUnlessDisallowedPvpEventCancelled((Player) eattacker, defender, DisallowCause.PEACEFUL_LAND, event);
if (!ret && notify) {
MPlayer attacker = MPlayer.get(eattacker);
attacker.msg("<i>PVP is disabled in %s.", defenderPsFaction.describeTo(attacker));
}
return ret;
}
return defenderPsFaction.getFlag(MFlag.getFlagMonsters());
}
// ... and if the attacker is a player ...
if (MUtil.isntPlayer(eattacker)) {
return true;
}
Player attacker = (Player) eattacker;
MPlayer uattacker = MPlayer.get(attacker);
// ... does this player bypass all protection? ...
if (MConf.get().playersWhoBypassAllProtection.contains(attacker.getName())) {
return true;
}
// ... gather attacker PS and faction information ...
PS attackerPs = PS.valueOf(attacker.getLocation());
Faction attackerPsFaction = BoardColl.get().getFactionAt(attackerPs);
// ... PVP flag may cause a damage block ...
// (just checking the defender as above isn't enough. What about the attacker? It could be in a no-pvp area)
// NOTE: This check is probably not that important but we could keep it anyways.
if (attackerPsFaction.getFlag(MFlag.getFlagPvp()) == false) {
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, DisallowCause.PEACEFUL_LAND, event);
if (!ret && notify) {
uattacker.msg("<i>PVP is disabled in %s.", attackerPsFaction.describeTo(uattacker));
}
return ret;
}
// ... are PVP rules completely ignored in this world? ...
if (!MConf.get().worldsPvpRulesEnabled.contains(defenderPs.getWorld())) {
return true;
}
Faction defendFaction = mdefender.getFaction();
Faction attackFaction = uattacker.getFaction();
if (attackFaction.isNone() && MConf.get().disablePVPForFactionlessPlayers) {
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, DisallowCause.FACTIONLESS, event);
if (!ret && notify) {
uattacker.msg("<i>You can't hurt other players until you join a faction.");
}
return ret;
} else if (defendFaction.isNone()) {
if (defenderPsFaction == attackFaction && MConf.get().enablePVPAgainstFactionlessInAttackersLand) {
// Allow PVP vs. Factionless in attacker's faction territory
return true;
} else if (MConf.get().disablePVPForFactionlessPlayers) {
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, DisallowCause.FACTIONLESS, event);
if (!ret && notify) {
uattacker.msg("<i>You can't hurt players who are not currently in a faction.");
}
return ret;
} else if (attackFaction.isNone() && MConf.get().enablePVPBetweenFactionlessPlayers) {
// Allow factionless vs factionless
return true;
}
}
Rel relation = defendFaction.getRelationTo(attackFaction);
// Check the relation
if (relation.isFriend() && defenderPsFaction.getFlag(MFlag.getFlagFriendlyire()) == false) {
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, DisallowCause.FRIENDLYFIRE, event);
if (!ret && notify) {
uattacker.msg("<i>You can't hurt %s<i>.", relation.getDescPlayerMany());
}
return ret;
}
// You can not hurt neutrals in their own territory.
boolean ownTerritory = mdefender.isInOwnTerritory();
if (mdefender.hasFaction() && ownTerritory && relation == Rel.NEUTRAL) {
ret = falseUnlessDisallowedPvpEventCancelled(attacker, defender, DisallowCause.OWN_TERRITORY, event);
if (!ret && notify) {
uattacker.msg("<i>You can't hurt %s<i> in their own territory unless you declare them as an enemy.", mdefender.describeTo(uattacker));
mdefender.msg("%s<i> tried to hurt you.", uattacker.describeTo(mdefender, true));
}
return ret;
}
return true;
}
}

View File

@ -0,0 +1,166 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.Rel;
import com.massivecraft.factions.RelationParticipator;
import com.massivecraft.factions.chat.ChatFormatter;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.event.EventMassiveCorePlayerToRecipientChat;
import com.massivecraft.massivecore.util.MUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.Event;
import org.bukkit.event.EventException;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.plugin.EventExecutor;
import java.util.Iterator;
import java.util.function.Predicate;
public class EngineChat extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineChat i = new EngineChat();
public static EngineChat get() {
return i;
}
public EngineChat() {
this.setPlugin(Factions.get());
}
// -------------------------------------------- //
// OVERRIDE
// -------------------------------------------- //
@Override
public void setActiveInner(boolean active) {
if (!active) {
return;
}
if (MConf.get().chatSetFormat) {
Bukkit.getPluginManager().registerEvent(AsyncPlayerChatEvent.class, this, MConf.get().chatSetFormatAt, new SetFormatEventExecutor(), Factions.get(), true);
}
if (MConf.get().chatParseTags) {
Bukkit.getPluginManager().registerEvent(AsyncPlayerChatEvent.class, this, MConf.get().chatParseTagsAt, new ParseTagsEventExecutor(), Factions.get(), true);
}
if (MConf.get().chatParseTags) {
Bukkit.getPluginManager().registerEvent(EventMassiveCorePlayerToRecipientChat.class, this, EventPriority.NORMAL, new ParseRelcolorEventExecutor(), Factions.get(), true);
}
}
// -------------------------------------------- //
// SET FORMAT
// -------------------------------------------- //
private class SetFormatEventExecutor implements EventExecutor {
@Override
public void execute(Listener listener, Event event) throws EventException {
try {
if (!(event instanceof AsyncPlayerChatEvent)) {
return;
}
setFormat((AsyncPlayerChatEvent) event);
} catch (Throwable t) {
throw new EventException(t);
}
}
}
public static void setFormat(AsyncPlayerChatEvent event) {
event.setFormat(MConf.get().chatSetFormatTo);
}
// -------------------------------------------- //
// PARSE TAGS
// -------------------------------------------- //
private class ParseTagsEventExecutor implements EventExecutor {
@Override
public void execute(Listener listener, Event event) throws EventException {
try {
if (!(event instanceof AsyncPlayerChatEvent)) {
return;
}
parseTags((AsyncPlayerChatEvent) event);
} catch (Throwable t) {
throw new EventException(t);
}
}
}
public static void parseTags(AsyncPlayerChatEvent event) {
Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) {
return;
}
String format = event.getFormat();
format = ChatFormatter.format(format, player, null);
event.setFormat(format);
}
// -------------------------------------------- //
// PARSE RELCOLOR
// -------------------------------------------- //
private class ParseRelcolorEventExecutor implements EventExecutor {
@Override
public void execute(Listener listener, Event event) throws EventException {
try {
if (!(event instanceof EventMassiveCorePlayerToRecipientChat)) {
return;
}
parseRelcolor((EventMassiveCorePlayerToRecipientChat) event);
} catch (Throwable t) {
throw new EventException(t);
}
}
}
public static void parseRelcolor(EventMassiveCorePlayerToRecipientChat event) {
String format = event.getFormat();
format = ChatFormatter.format(format, event.getSender(), event.getRecipient());
event.setFormat(format);
}
// -------------------------------------------- //
// FILTER CHAT CHANNEL
// -------------------------------------------- //
public static Predicate<Player> getPredicateIsInFaction(RelationParticipator participator) {
return player -> MPlayer.get(player).getRelationTo(participator).isAtLeast(Rel.FACTION);
}
public static Predicate<Player> getPredicateIsAlly(RelationParticipator participator) {
return player -> MPlayer.get(player).getFaction().getRelationTo(participator).isAtLeast(Rel.ALLY);
}
public static void filterToPredicate(AsyncPlayerChatEvent event, Predicate<Player> predicate) {
Player player = event.getPlayer();
MPlayer mplayer = MPlayer.get(player);
Faction faction = mplayer.getFaction();
// Get and filter recipients
for (Iterator<Player> it = event.getRecipients().iterator(); it.hasNext(); ) {
Player recipient = it.next();
if (predicate.test(recipient)) {
continue;
}
it.remove();
}
}
}

View File

@ -0,0 +1,270 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.Rel;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.FactionColl;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.factions.entity.MPerm;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.event.EventFactionsChunksChange;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.collections.MassiveSet;
import com.massivecraft.massivecore.mixin.MixinWorld;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.Txt;
import org.bukkit.ChatColor;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
public class EngineChunkChange extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineChunkChange i = new EngineChunkChange();
public static EngineChunkChange get() {
return i;
}
// -------------------------------------------- //
// CHUNK CHANGE: ALLOWED
// -------------------------------------------- //
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onChunksChange(EventFactionsChunksChange event) {
// For security reasons we block the chunk change on any error since an error might block security checks from happening.
try {
onChunksChangeInner(event);
} catch (Throwable throwable) {
event.setCancelled(true);
throwable.printStackTrace();
}
}
public void onChunksChangeInner(EventFactionsChunksChange event) {
// Args
final MPlayer mplayer = event.getMPlayer();
final Faction newFaction = event.getNewFaction();
final Map<Faction, Set<PS>> currentFactionChunks = event.getOldFactionChunks();
final Set<Faction> currentFactions = currentFactionChunks.keySet();
final Set<PS> chunks = event.getChunks();
// Override Mode? Sure!
if (mplayer.isOverriding()) {
return;
}
// CALC: Is there at least one normal faction among the current ones?
boolean currentFactionsContainsAtLeastOneNormal = false;
for (Faction currentFaction : currentFactions) {
if (currentFaction.isNormal()) {
currentFactionsContainsAtLeastOneNormal = true;
break;
}
}
// If the new faction is normal (not wilderness/none), meaning if we are claiming for a faction ...
if (newFaction.isNormal()) {
// ... ensure claiming is enabled for the worlds of all chunks ...
for (PS chunk : chunks) {
String worldId = chunk.getWorld();
if (!MConf.get().worldsClaimingEnabled.contains(worldId)) {
String worldName = MixinWorld.get().getWorldDisplayName(worldId);
mplayer.msg("<b>Land claiming is disabled in <h>%s<b>.", worldName);
event.setCancelled(true);
return;
}
}
// ... ensure we have permission to alter the territory of the new faction ...
if (!MPerm.getPermTerritory().has(mplayer, newFaction, true)) {
// NOTE: No need to send a message. We send message from the permission check itself.
event.setCancelled(true);
return;
}
// ... ensure the new faction has enough players to claim ...
if (newFaction.getMPlayers().size() < MConf.get().claimsRequireMinFactionMembers) {
mplayer.msg("<b>Factions must have at least <h>%s<b> members to claim land.", MConf.get().claimsRequireMinFactionMembers);
event.setCancelled(true);
return;
}
int claimedLandCount = newFaction.getLandCount();
if (!newFaction.getFlag(MFlag.getFlagInfpower())) {
// ... ensure the claim would not bypass the global max limit ...
if (MConf.get().claimedLandsMax != 0 && claimedLandCount + chunks.size() > MConf.get().claimedLandsMax) {
mplayer.msg("<b>Limit reached. You can't claim more land.");
event.setCancelled(true);
return;
}
// ... ensure the claim would not bypass the global world limit ...
if (MConf.get().claimedWorldsMax >= 0) {
Set<String> oldWorlds = newFaction.getClaimedWorlds();
Set<String> newWorlds = PS.getDistinctWorlds(chunks);
Set<String> worlds = new MassiveSet<>();
worlds.addAll(oldWorlds);
worlds.addAll(newWorlds);
if (!oldWorlds.containsAll(newWorlds) && worlds.size() > MConf.get().claimedWorldsMax) {
List<String> worldNames = new MassiveList<>();
for (String world : oldWorlds) {
worldNames.add(MixinWorld.get().getWorldDisplayName(world));
}
String worldsMax = MConf.get().claimedWorldsMax == 1 ? "world" : "worlds";
String worldsAlready = oldWorlds.size() == 1 ? "world" : "worlds";
mplayer.msg("<b>A faction may only be present on <h>%d<b> different %s.", MConf.get().claimedWorldsMax, worldsMax);
mplayer.msg("%s<i> is already present on <h>%d<i> %s:", newFaction.describeTo(mplayer), oldWorlds.size(), worldsAlready);
mplayer.message(Txt.implodeCommaAndDot(worldNames, ChatColor.YELLOW.toString()));
mplayer.msg("<i>Please unclaim bases on other worlds to claim here.");
event.setCancelled(true);
return;
}
}
}
// ... ensure the claim would not bypass the faction power ...
if (claimedLandCount + chunks.size() > newFaction.getPowerRounded()) {
mplayer.msg("<b>You don't have enough power to claim that land.");
event.setCancelled(true);
return;
}
// ... ensure the claim would not violate distance to neighbors ...
// HOW: Calculate the factions nearby, excluding the chunks themselves, the faction itself and the wilderness faction.
// HOW: The chunks themselves will be handled in the "if (oldFaction.isNormal())" section below.
Set<PS> nearbyChunks = BoardColl.getNearbyChunks(chunks, MConf.get().claimMinimumChunksDistanceToOthers);
nearbyChunks.removeAll(chunks);
Set<Faction> nearbyFactions = BoardColl.getDistinctFactions(nearbyChunks);
nearbyFactions.remove(FactionColl.get().getNone());
nearbyFactions.remove(newFaction);
// HOW: Next we check if the new faction has permission to claim nearby the nearby factions.
MPerm claimnear = MPerm.getPermClaimnear();
for (Faction nearbyFaction : nearbyFactions) {
if (claimnear.has(mplayer, nearbyFaction, true)) {
continue;
}
event.setCancelled(true);
return;
}
// ... ensure claims are properly connected ...
if
(
// If claims must be connected ...
MConf.get().claimsMustBeConnected
// ... and this faction already has claimed something on this map (meaning it's not their first claim) ...
&&
newFaction.getLandCountInWorld(chunks.iterator().next().getWorld()) > 0
// ... and none of the chunks are connected to an already claimed chunk for the faction ...
&&
!BoardColl.get().isAnyConnectedPs(chunks, newFaction)
// ... and either claims must always be connected or there is at least one normal faction among the old factions ...
&&
(!MConf.get().claimsCanBeUnconnectedIfOwnedByOtherFaction || currentFactionsContainsAtLeastOneNormal)
) {
if (MConf.get().claimsCanBeUnconnectedIfOwnedByOtherFaction) {
mplayer.msg("<b>You can only claim additional land which is connected to your first claim or controlled by another faction!");
} else {
mplayer.msg("<b>You can only claim additional land which is connected to your first claim!");
}
event.setCancelled(true);
return;
}
}
// Ensure claims are properly connected when unclaiming
if (newFaction.isNone() && MConf.get().claimsMustBeConnected && MConf.get().claimsMustBeConnectedStrict) {
for (Entry<Faction, Set<PS>> entry : currentFactionChunks.entrySet()) {
Faction faction = entry.getKey();
Set<PS> factionRemovedChunks = entry.getValue();
Set<PS> pssBefore = BoardColl.get().getChunks(faction);
// Get how many "forests" of claims there are right now
List<Collection<PS>> forestsBefore = BoardColl.getForests(pssBefore);
Set<PS> pssAfter = new MassiveSet<>(pssBefore);
pssAfter.removeAll(factionRemovedChunks);
List<Collection<PS>> forestsAfter = BoardColl.getForests(pssAfter);
if (forestsAfter.size() > forestsBefore.size()) {
mplayer.msg("<b>Claims must be connected. You can't make them disconnected by unclaiming.");
event.setCancelled(true);
return;
}
}
}
// For each of the old factions ...
for (Entry<Faction, Set<PS>> entry : currentFactionChunks.entrySet()) {
Faction oldFaction = entry.getKey();
Set<PS> oldChunks = entry.getValue();
// ... that is an actual faction ...
if (oldFaction.isNone()) {
continue;
}
// ... for which the mplayer lacks permission ...
if (MPerm.getPermTerritory().has(mplayer, oldFaction, false)) {
continue;
}
// ... consider all reasons to forbid "overclaiming/warclaiming" ...
// ... claiming from others may be forbidden ...
if (!MConf.get().claimingFromOthersAllowed) {
mplayer.msg("<b>You may not claim land from others.");
event.setCancelled(true);
return;
}
// ... and they must actually be claiming ...
if (newFaction.isNone()) {
mplayer.msg("<b>You can't unclaim land belonging to others.");
event.setCancelled(true);
return;
}
// ... the relation may forbid ...
if (oldFaction.getRelationTo(newFaction).isAtLeast(Rel.TRUCE)) {
mplayer.msg("<b>You can't claim this land due to your relation with the current owner.");
event.setCancelled(true);
return;
}
// ... the old faction might not be inflated enough ...
if (oldFaction.getPowerRounded() > oldFaction.getLandCount() - oldChunks.size() && MConf.get().claimingFromOthersMustBeInflated) {
mplayer.msg("%s<i> owns this land and is strong enough to keep it.", oldFaction.getName(mplayer));
event.setCancelled(true);
return;
}
// ... and you might be trying to claim without starting at the border ...
if (!BoardColl.get().isAnyBorderPs(chunks)) {
mplayer.msg("<b>You must start claiming land at the border of the territory.");
event.setCancelled(true);
return;
}
// ... otherwise you may claim from this old faction even though you lack explicit permission from them.
}
}
}

View File

@ -0,0 +1,103 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.entity.MPlayerColl;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.event.EventMassiveCorePlayerCleanInactivityToleranceMillis;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import java.util.Map;
import java.util.Map.Entry;
public class EngineCleanInactivity extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineCleanInactivity i = new EngineCleanInactivity();
public static EngineCleanInactivity get() {
return i;
}
// -------------------------------------------- //
// REMOVE PLAYER MILLIS
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void ageBonus(EventMassiveCorePlayerCleanInactivityToleranceMillis event) {
if (event.getColl() != MPlayerColl.get()) {
return;
}
applyPlayerAgeBonus(event);
applyFactionAgeBonus(event);
}
public void applyPlayerAgeBonus(EventMassiveCorePlayerCleanInactivityToleranceMillis event) {
// Calculate First Played
Long firstPlayed = event.getEntity().getFirstPlayed();
Long age = 0L;
if (firstPlayed != null) {
age = System.currentTimeMillis() - firstPlayed;
}
// Calculate the Bonus!
Long bonus = calculateBonus(age, MConf.get().cleanInactivityToleranceMillisPlayerAgeToBonus);
if (bonus == null) {
return;
}
// Apply
event.getToleranceCauseMillis().put("Player Age Bonus", bonus);
}
public void applyFactionAgeBonus(EventMassiveCorePlayerCleanInactivityToleranceMillis event) {
// Calculate Faction Age
Faction faction = ((MPlayer) event.getEntity()).getFaction();
long age = 0L;
if (!faction.isNone()) {
age = faction.getAge();
}
// Calculate the Bonus!
Long bonus = calculateBonus(age, MConf.get().cleanInactivityToleranceMillisFactionAgeToBonus);
if (bonus == null) {
return;
}
// Apply
event.getToleranceCauseMillis().put("Faction Age Bonus", bonus);
}
private Long calculateBonus(long age, Map<Long, Long> ageToBonus) {
if (ageToBonus.isEmpty()) {
return null;
}
Long bonus = 0L;
for (Entry<Long, Long> entry : ageToBonus.entrySet()) {
Long key = entry.getKey();
if (key == null) {
continue;
}
Long value = entry.getValue();
if (value == null) {
continue;
}
if (age >= key) {
bonus = value;
break;
}
}
return bonus;
}
}

View File

@ -0,0 +1,114 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.Rel;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.Txt;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerCommandPreprocessEvent;
import java.util.List;
public class EngineDenyCommands extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineDenyCommands i = new EngineDenyCommands();
public static EngineDenyCommands get() {
return i;
}
// -------------------------------------------- //
// DENY COMMANDS
// -------------------------------------------- //
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void denyCommands(PlayerCommandPreprocessEvent event) {
// If a player is trying to run a command ...
Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) {
return;
}
MPlayer mplayer = MPlayer.get(player);
// ... and the player is not overriding ...
if (mplayer.isOverriding()) {
return;
}
// ... clean up the command ...
String command = event.getMessage();
command = Txt.removeLeadingCommandDust(command);
command = command.toLowerCase();
command = command.trim();
// ... the command may be denied for members of permanent factions ...
if (mplayer.hasFaction() && mplayer.getFaction().getFlag(MFlag.getFlagPermanent()) && MUtil.containsCommand(command, MConf.get().denyCommandsPermanentFactionMember)) {
mplayer.msg("<b>You can't use \"<h>/%s<b>\" as member of a permanent faction.", command);
event.setCancelled(true);
return;
}
// ... if there is a faction at the players location we fetch the relation now ...
PS ps = PS.valueOf(player.getLocation()).getChunk(true);
Faction factionAtPs = BoardColl.get().getFactionAt(ps);
Rel factionAtRel = null;
if (factionAtPs != null && !factionAtPs.isNone()) {
factionAtRel = factionAtPs.getRelationTo(mplayer);
}
// ... there maybe be a player in the distance that denies the command ...
if (MConf.get().denyCommandsDistance > -1 && !MConf.get().denyCommandsDistanceBypassIn.contains(factionAtRel)) {
for (Player otherplayer : player.getWorld().getPlayers()) {
MPlayer othermplayer = MPlayer.get(otherplayer);
if (othermplayer == mplayer) {
continue;
}
double distance = player.getLocation().distance(otherplayer.getLocation());
if (MConf.get().denyCommandsDistance > distance) {
continue;
}
Rel playerRel = mplayer.getRelationTo(othermplayer);
if (!MConf.get().denyCommandsDistanceRelation.containsKey(playerRel)) {
continue;
}
String desc = playerRel.getDescPlayerOne();
mplayer.msg("<b>You can't use \"<h>/%s<b>\" as there is <h>%s<b> nearby.", command, desc);
event.setCancelled(true);
return;
}
}
// ... if there is no relation here then there are no further checks ...
if (factionAtRel == null) {
return;
}
List<String> deniedCommands = MConf.get().denyCommandsTerritoryRelation.get(factionAtRel);
if (deniedCommands == null) {
return;
}
if (!MUtil.containsCommand(command, deniedCommands)) {
return;
}
mplayer.msg("<b>You can't use \"<h>/%s<b>\" in %s territory.", command, Txt.getNicedEnum(factionAtRel));
event.setCancelled(true);
}
}

View File

@ -0,0 +1,149 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.Rel;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.massivecore.Couple;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.mixin.MixinMessage;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.Txt;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.util.List;
import java.util.Map.Entry;
public class EngineDenyTeleport extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineDenyTeleport i = new EngineDenyTeleport();
public static EngineDenyTeleport get() {
return i;
}
// -------------------------------------------- //
// CAN COMBAT DAMAGE HAPPEN
// -------------------------------------------- //
private enum TerritoryType {
ENEMY,
WILDERNESS,
OWN,
OTHER
}
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void canTeleportHappen(PlayerTeleportEvent event) {
Entry<TeleportCause, TerritoryType> entry = shouldBeCancelled(event);
if (entry == null) {
return;
}
event.setCancelled(true);
TeleportCause cause = entry.getKey();
TerritoryType deny = entry.getValue();
String teleportDesc = Txt.getNicedEnum(cause);
String denyDesc = "";
if (deny == TerritoryType.ENEMY) {
denyDesc = "enemy";
}
if (deny == TerritoryType.WILDERNESS) {
denyDesc = "wilderness";
}
if (deny == TerritoryType.OWN) {
denyDesc = "your own";
}
if (deny == TerritoryType.OTHER) {
denyDesc = "other faction's";
}
Player player = event.getPlayer();
MixinMessage.get().msgOne(player, "<b>Teleportation with %s is not allowed in %s territory.", teleportDesc, denyDesc);
}
private Entry<TeleportCause, TerritoryType> shouldBeCancelled(PlayerTeleportEvent event) {
Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) {
return null;
}
MPlayer mplayer = MPlayer.get(player);
PS from = PS.valueOf(event.getFrom());
PS to = PS.valueOf(event.getTo());
TerritoryType typeFrom = getTerritoryType(mplayer, from);
TerritoryType typeTo = getTerritoryType(mplayer, to);
List<TerritoryType> types = MUtil.list(typeFrom, typeTo);
TeleportCause cause = event.getCause();
MConf mconf = MConf.get();
if (cause == TeleportCause.CHORUS_FRUIT) {
if (!mconf.allowChorusFruitInEnemyTerritory && types.contains(TerritoryType.ENEMY)) {
return Couple.valueOf(cause, TerritoryType.ENEMY);
}
if (!mconf.allowChorusFruitInWildernessTerritory && types.contains(TerritoryType.WILDERNESS)) {
return Couple.valueOf(cause, TerritoryType.WILDERNESS);
}
if (!mconf.allowChorusFruitInOwnTerritory && types.contains(TerritoryType.OWN)) {
return Couple.valueOf(cause, TerritoryType.OWN);
}
if (!mconf.allowChorusFruitInOtherTerritory && types.contains(TerritoryType.OTHER)) {
return Couple.valueOf(cause, TerritoryType.OTHER);
}
} else if (cause == TeleportCause.ENDER_PEARL) {
if (!mconf.allowEnderPearlInEnemyTerritory && types.contains(TerritoryType.ENEMY)) {
return Couple.valueOf(cause, TerritoryType.ENEMY);
}
if (!mconf.allowEnderPearlInWildernessTerritory && types.contains(TerritoryType.WILDERNESS)) {
return Couple.valueOf(cause, TerritoryType.WILDERNESS);
}
if (!mconf.allowEnderPearlInOwnTerritory && types.contains(TerritoryType.OWN)) {
return Couple.valueOf(cause, TerritoryType.OWN);
}
if (!mconf.allowEnderPearlInOtherTerritory && types.contains(TerritoryType.OTHER)) {
return Couple.valueOf(cause, TerritoryType.OTHER);
}
} else {
// Don't cancel other kinds of teleports
}
return null;
}
private TerritoryType getTerritoryType(MPlayer mplayer, PS territory) {
Faction territoryFaction = BoardColl.get().getFactionAt(territory);
Rel relation = territoryFaction.getRelationTo(mplayer);
if (territoryFaction.isNone()) {
return TerritoryType.WILDERNESS;
}
if (relation == Rel.ENEMY) {
return TerritoryType.ENEMY;
}
if (relation == Rel.FACTION) {
return TerritoryType.OWN;
}
return TerritoryType.OTHER;
}
}

View File

@ -0,0 +1,268 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.cmd.CmdFactions;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.event.EventFactionsAbstractSender;
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
import com.massivecraft.factions.event.EventFactionsChunksChange;
import com.massivecraft.factions.event.EventFactionsCreate;
import com.massivecraft.factions.event.EventFactionsDescriptionChange;
import com.massivecraft.factions.event.EventFactionsDisband;
import com.massivecraft.factions.event.EventFactionsFlagChange;
import com.massivecraft.factions.event.EventFactionsInvitedChange;
import com.massivecraft.factions.event.EventFactionsMembershipChange;
import com.massivecraft.factions.event.EventFactionsMembershipChange.MembershipChangeReason;
import com.massivecraft.factions.event.EventFactionsNameChange;
import com.massivecraft.factions.event.EventFactionsRelationChange;
import com.massivecraft.factions.event.EventFactionsTitleChange;
import com.massivecraft.factions.event.EventFactionsWarpAdd;
import com.massivecraft.factions.event.EventFactionsWarpRemove;
import com.massivecraft.factions.event.EventFactionsWarpTeleport;
import com.massivecraft.factions.integration.Econ;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.money.Money;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.Txt;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
public class EngineEcon extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineEcon i = new EngineEcon();
public static EngineEcon get() {
return i;
}
// -------------------------------------------- //
// TAKE ON LEAVE
// -------------------------------------------- //
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void takeOnLeave(EventFactionsMembershipChange event) {
if (!Econ.isEnabled()) {
return;
}
// If a player is leaving the faction ...
if (event.getReason() != MembershipChangeReason.LEAVE) {
return;
}
// ... and that player was the last one in the faction ...
MPlayer mplayer = event.getMPlayer();
Faction oldFaction = mplayer.getFaction();
if (oldFaction.getMPlayers().size() > 1) {
return;
}
// ... then transfer all money to the player.
double money = Econ.getMoney(oldFaction);
if (money == 0) {
return;
}
Econ.transferMoney(mplayer, oldFaction, mplayer, money);
}
// -------------------------------------------- //
// TAKE ON DISBAND
// -------------------------------------------- //
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void takeOnDisband(EventFactionsDisband event) {
// If there is a mplayer ...
MPlayer mplayer = event.getMPlayer();
if (mplayer == null) {
return;
}
// ... and economy is enabled ...
if (!Econ.isEnabled()) {
return;
}
// ... then transfer all the faction money to the sender.
Faction faction = event.getFaction();
double amount = Econ.getMoney(faction);
// Check that there is an amount
if (amount == 0) {
return;
}
String amountString = Money.format(amount);
Econ.transferMoney(faction, mplayer, mplayer, amount, true);
mplayer.msg("<i>You have been given the disbanded faction's bank, totaling %s.", amountString);
Factions.get().log(mplayer.getName() + " has been given bank holdings of " + amountString + " from disbanding " + faction.getName() + ".");
}
// -------------------------------------------- //
// PAY FOR ACTION
// -------------------------------------------- //
public static void payForAction(EventFactionsAbstractSender event, Double cost, String desc) {
// If there is an mplayer ...
MPlayer mplayer = event.getMPlayer();
if (mplayer == null) {
return;
}
// ... and there is a cost ...
if (cost == null) {
return;
}
if (cost == 0) {
return;
}
// ... that the sender can't afford ...
if (Econ.payForAction(cost, mplayer, desc)) {
return;
}
// ... then cancel.
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForAction(EventFactionsChunksChange event) {
double cost = 0;
List<String> typeNames = new ArrayList<>();
for (Entry<EventFactionsChunkChangeType, Set<PS>> typeChunks : event.getTypeChunks().entrySet()) {
final EventFactionsChunkChangeType type = typeChunks.getKey();
final Set<PS> chunks = typeChunks.getValue();
Double typeCost = MConf.get().econChunkCost.get(type);
if (typeCost == null) {
continue;
}
if (typeCost == 0) {
continue;
}
typeCost *= chunks.size();
cost += typeCost;
typeNames.add(type.now);
}
String desc = Txt.implodeCommaAnd(typeNames) + " this land";
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForAction(EventFactionsMembershipChange event) {
Double cost = null;
String desc = null;
if (event.getReason() == MembershipChangeReason.JOIN) {
cost = MConf.get().econCostJoin;
desc = "join a faction";
} else if (event.getReason() == MembershipChangeReason.LEAVE) {
cost = MConf.get().econCostLeave;
desc = "leave a faction";
} else if (event.getReason() == MembershipChangeReason.KICK) {
cost = MConf.get().econCostKick;
desc = "kick someone from a faction";
} else {
return;
}
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForCommand(EventFactionsRelationChange event) {
Double cost = MConf.get().econRelCost.get(event.getNewRelation());
String desc = CmdFactions.get().cmdFactionsRelation.cmdFactionsRelationSet.getDesc();
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForCommand(EventFactionsWarpAdd event) {
Double cost = MConf.get().econCostWarpAdd;
String desc = CmdFactions.get().cmdFactionsWarp.cmdFactionWarpAdd.getDesc();
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForCommand(EventFactionsWarpRemove event) {
Double cost = MConf.get().econCostWarpRemove;
String desc = CmdFactions.get().cmdFactionsWarp.cmdFactionWarpRemove.getDesc();
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForCommand(EventFactionsCreate event) {
Double cost = MConf.get().econCostCreate;
String desc = CmdFactions.get().cmdFactionsCreate.getDesc();
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForCommand(EventFactionsDescriptionChange event) {
Double cost = MConf.get().econCostDescription;
String desc = CmdFactions.get().cmdFactionsDescription.getDesc();
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForCommand(EventFactionsNameChange event) {
Double cost = MConf.get().econCostName;
String desc = CmdFactions.get().cmdFactionsName.getDesc();
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForCommand(EventFactionsTitleChange event) {
Double cost = MConf.get().econCostTitle;
String desc = CmdFactions.get().cmdFactionsTitle.getDesc();
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForCommand(EventFactionsFlagChange event) {
Double cost = MConf.get().econCostFlag;
String desc = CmdFactions.get().cmdFactionsFlag.getDesc();
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForCommand(EventFactionsInvitedChange event) {
Double cost = event.isNewInvited() ? MConf.get().econCostInvite : MConf.get().econCostDeinvite;
String desc = CmdFactions.get().cmdFactionsInvite.getDesc();
payForAction(event, cost, desc);
}
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void payForCommand(EventFactionsWarpTeleport event) {
Double cost = MConf.get().econCostWarpGo;
String desc = CmdFactions.get().cmdFactionsWarp.cmdFactionsWarpGo.getDesc();
payForAction(event, cost, desc);
}
}

View File

@ -0,0 +1,226 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.collections.MassiveList;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.MUtil;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import org.bukkit.event.player.PlayerTeleportEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
public class EngineExploit extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineExploit i = new EngineExploit();
public static EngineExploit get() {
return i;
}
// -------------------------------------------- //
// OBSIDIAN GENERATORS
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void obsidianGenerators(BlockFromToEvent event) {
if (!MConf.get().handleExploitObsidianGenerators) {
return;
}
// thanks to ObGenBlocker and WorldGuard for this method
Block block = event.getToBlock();
Material source = event.getBlock().getType();
Material target = block.getType();
if ((target == Material.REDSTONE_WIRE || target == Material.TRIPWIRE) && (source == Material.AIR || source == Material.LAVA)) {
block.setType(Material.AIR);
}
}
// -------------------------------------------- //
// ENDER PEARL CLIPPING
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void enderPearlClipping(PlayerTeleportEvent event) {
if (!MConf.get().handleExploitEnderPearlClipping) {
return;
}
if (event.getCause() != PlayerTeleportEvent.TeleportCause.ENDER_PEARL) {
return;
}
// this exploit works when the target location is within 0.31 blocks or so of a door or glass block or similar...
Location target = event.getTo();
Location from = event.getFrom();
// blocks who occupy less than 1 block width or length wise need to be handled differently
Material mat = event.getTo().getBlock().getType();
if (
((mat == Material.GLASS_PANE || mat == Material.IRON_BARS) && clippingThrough(target, from, 0.65))
|| ((MUtil.list(Material.ACACIA_FENCE, Material.BIRCH_FENCE, Material.DARK_OAK_FENCE, Material.JUNGLE_FENCE, Material.NETHER_BRICK_FENCE, Material.OAK_FENCE, Material.SPRUCE_FENCE).contains(mat)) && clippingThrough(target, from, 0.45))
) {
event.setTo(from);
return;
}
// simple fix otherwise: ender pearl target locations are standardized to be in the center (X/Z) of the target block, not at the edges
target.setX(target.getBlockX() + 0.5);
target.setZ(target.getBlockZ() + 0.5);
event.setTo(target);
}
public static boolean clippingThrough(Location target, Location from, double thickness) {
return
(
(from.getX() > target.getX() && (from.getX() - target.getX() < thickness))
|| (target.getX() > from.getX() && (target.getX() - from.getX() < thickness))
|| (from.getZ() > target.getZ() && (from.getZ() - target.getZ() < thickness))
|| (target.getZ() > from.getZ() && (target.getZ() - from.getZ() < thickness))
);
}
// -------------------------------------------- //
// NETHER PORTAL TRAP
// -------------------------------------------- //
// A nether portal trap can be created by the destination portal being enclosed (trapped) - resulting in the player not being able to run commands.
// This fix removes the portal blocks (client side) from the destination until they are away from the portal.
private static final int NETHER_TRAP_RADIUS_CHECK = 5;
private static final int NETHER_TRAP_RESET_RADIUS_SQUARED = 9;
private HashMap<UUID, List<Block>> portalTraps = new HashMap<>();
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void portalTrapRemoveAnimation(PlayerTeleportEvent event) {
// If there is a teleport caused by a nether portal ...
if (!MConf.get().handleNetherPortalTrap || event.getCause() != TeleportCause.NETHER_PORTAL) {
return;
}
Player player = event.getPlayer();
Block from = event.getTo().getBlock();
// ... and the player can't build at the destination ...
if (EnginePermBuild.canPlayerBuildAt(player, PS.valueOf(from), false)) {
return;
}
// ... reset the old portal blocks stored ...
this.portalReset(player);
// ... get all the portal blocks belonging to the new portal at the destination ...
List<Block> portalTrap = getPortal(from);
if (portalTrap.isEmpty()) {
return;
}
// ... and then store those blocks and send an update as if they were air.
this.portalTraps.put(player.getUniqueId(), portalTrap);
portalUpdateAir(player, portalTrap);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void portalUpdate(PlayerMoveEvent event) {
// If a player moves ...
if (!MConf.get().handleNetherPortalTrap || MUtil.isSameBlock(event)) {
return;
}
Player player = event.getPlayer();
UUID uuid = player.getUniqueId();
// ... and he recently used a portal ...
List<Block> portalTrap = this.portalTraps.get(uuid);
if (portalTrap == null) {
return;
}
Location locationTo = event.getTo();
Location locationFrom = portalTrap.get(0).getLocation();
World worldTo = locationTo.getWorld();
World worldFrom = locationFrom.getWorld();
// ... update reset the portal near them, if they have moved away too far ...
if (!worldTo.equals(worldFrom) || locationTo.distanceSquared(locationFrom) > NETHER_TRAP_RESET_RADIUS_SQUARED) {
portalUpdateReset(player, portalTrap);
return;
}
// ... or send an update as if the portal blocks were air.
portalUpdateAir(player, portalTrap);
}
public void portalReset(Player player) {
UUID uuid = player.getUniqueId();
// If a player has already a portal registered to him ...
List<Block> portalTrap = this.portalTraps.get(uuid);
if (portalTrap == null) {
return;
}
// ... remove them from the registry ...
this.portalTraps.remove(uuid);
// ... and send updates if the player and portal are in the same world.
if (!player.getWorld().equals(portalTrap.get(0).getWorld())) {
return;
}
portalUpdateReset(player, portalTrap);
}
public static void portalUpdateReset(Player player, List<Block> portal) {
portalUpdate(player, portal, null, null);
}
public static void portalUpdateAir(Player player, List<Block> portal) {
portalUpdate(player, portal, Material.AIR, (byte) 0);
}
@SuppressWarnings("deprecation")
private static void portalUpdate(Player player, List<Block> portal, Material material, Byte data) {
boolean usingDefault = material == null && data == null;
for (Block block : portal) {
Material updateMaterial = usingDefault ? block.getType() : material;
byte updateData = usingDefault ? block.getData() : data;
player.sendBlockChange(block.getLocation(), updateMaterial, updateData);
}
}
public static List<Block> getPortal(Block from) {
// Create
List<Block> ret = new MassiveList<>();
// Fill - Check in a radius of the block to find the portal blocks
for (int x = -(NETHER_TRAP_RADIUS_CHECK); x <= NETHER_TRAP_RADIUS_CHECK; x++) {
for (int y = -(NETHER_TRAP_RADIUS_CHECK); y <= NETHER_TRAP_RADIUS_CHECK; y++) {
for (int z = -(NETHER_TRAP_RADIUS_CHECK); z <= NETHER_TRAP_RADIUS_CHECK; z++) {
if (from.getRelative(x, y, z).getType() == Material.NETHER_PORTAL) {
ret.add(from.getRelative(x, y, z));
}
}
}
}
// Return
return ret;
}
}

View File

@ -0,0 +1,48 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.ps.PS;
import org.bukkit.entity.Enderman;
import org.bukkit.entity.Entity;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityChangeBlockEvent;
public class EngineFlagEndergrief extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineFlagEndergrief i = new EngineFlagEndergrief();
public static EngineFlagEndergrief get() {
return i;
}
// -------------------------------------------- //
// FLAG: ENDERGRIEF
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockEndergrief(EntityChangeBlockEvent event) {
// If an enderman is changing a block ...
Entity entity = event.getEntity();
if (!(entity instanceof Enderman)) {
return;
}
// ... and the faction there has endergrief disabled ...
PS ps = PS.valueOf(event.getBlock());
Faction faction = BoardColl.get().getFactionAt(ps);
if (faction.getFlag(MFlag.getFlagEndergrief())) {
return;
}
// ... stop the block alteration.
event.setCancelled(true);
}
}

View File

@ -0,0 +1,155 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.util.EnumerationUtil;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.ps.PS;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Wither;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockExplodeEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.entity.EntityDamageEvent.DamageCause;
import org.bukkit.event.entity.EntityExplodeEvent;
import org.bukkit.event.hanging.HangingBreakEvent;
import org.bukkit.event.hanging.HangingBreakEvent.RemoveCause;
import java.util.Collection;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
public class EngineFlagExplosion extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineFlagExplosion i = new EngineFlagExplosion();
public static EngineFlagExplosion get() {
return i;
}
// -------------------------------------------- //
// FLAG: EXPLOSIONS
// -------------------------------------------- //
protected Set<DamageCause> DAMAGE_CAUSE_EXPLOSIONS = EnumSet.of(DamageCause.BLOCK_EXPLOSION, DamageCause.ENTITY_EXPLOSION);
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockExplosion(HangingBreakEvent event) {
// If a hanging entity was broken by an explosion ...
if (event.getCause() != RemoveCause.EXPLOSION) {
return;
}
Entity entity = event.getEntity();
// ... and the faction there has explosions disabled ...
Faction faction = BoardColl.get().getFactionAt(PS.valueOf(entity.getLocation()));
if (faction.isExplosionsAllowed()) {
return;
}
// ... then cancel.
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockExplosion(EntityDamageEvent event) {
// If an explosion damages ...
if (!DAMAGE_CAUSE_EXPLOSIONS.contains(event.getCause())) {
return;
}
// ... an entity that is modified on damage ...
if (!EnumerationUtil.isEntityTypeEditOnDamage(event.getEntityType())) {
return;
}
// ... and the faction has explosions disabled ...
if (BoardColl.get().getFactionAt(PS.valueOf(event.getEntity())).isExplosionsAllowed()) {
return;
}
// ... then cancel!
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockExplosion(EntityExplodeEvent event) {
Location location = event.getLocation();
Cancellable cancellable = event;
Collection<Block> blocks = event.blockList();
blockExplosion(location, cancellable, blocks);
}
// Note that this method is used by EngineV18 for the BlockExplodeEvent
public void blockExplosion(Location location, Cancellable cancellable, Collection<Block> blocks) {
// Caching to speed things up.
Map<Faction, Boolean> faction2allowed = new HashMap<>();
// Check the entity. Are explosions disabled there?
Faction faction = BoardColl.get().getFactionAt(PS.valueOf(location));
Boolean allowed = faction.isExplosionsAllowed();
if (!allowed) {
cancellable.setCancelled(true);
return;
}
faction2allowed.put(faction, allowed);
// Individually check the flag state for each block
Iterator<Block> iterator = blocks.iterator();
while (iterator.hasNext()) {
Block block = iterator.next();
faction = BoardColl.get().getFactionAt(PS.valueOf(block));
allowed = faction2allowed.get(faction);
if (allowed == null) {
allowed = faction.isExplosionsAllowed();
faction2allowed.put(faction, allowed);
}
if (!allowed) {
iterator.remove();
}
}
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockExplosion(EntityChangeBlockEvent event) {
// If a wither is changing a block ...
Entity entity = event.getEntity();
if (!(entity instanceof Wither)) {
return;
}
// ... and the faction there has explosions disabled ...
PS ps = PS.valueOf(event.getBlock());
Faction faction = BoardColl.get().getFactionAt(ps);
if (faction.isExplosionsAllowed()) {
return;
}
// ... stop the block alteration.
event.setCancelled(true);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockExplosion(BlockExplodeEvent event) {
Location location = event.getBlock().getLocation();
Cancellable cancellable = event;
Collection<Block> blocks = event.blockList();
EngineFlagExplosion.get().blockExplosion(location, cancellable, blocks);
}
}

View File

@ -0,0 +1,77 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.ps.PS;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.Cancellable;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBurnEvent;
import org.bukkit.event.block.BlockIgniteEvent;
import org.bukkit.event.block.BlockIgniteEvent.IgniteCause;
import org.bukkit.event.block.BlockSpreadEvent;
public class EngineFlagFireSpread extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineFlagFireSpread i = new EngineFlagFireSpread();
public static EngineFlagFireSpread get() {
return i;
}
// -------------------------------------------- //
// FLAG: FIRE SPREAD
// -------------------------------------------- //
public void blockFireSpread(Block block, Cancellable cancellable) {
// If the faction at the block has firespread disabled ...
PS ps = PS.valueOf(block);
Faction faction = BoardColl.get().getFactionAt(ps);
if (faction.getFlag(MFlag.getFlagFirespread())) {
return;
}
// then cancel the event.
cancellable.setCancelled(true);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockFireSpread(BlockIgniteEvent event) {
// If fire is spreading ...
if (event.getCause() != IgniteCause.SPREAD && event.getCause() != IgniteCause.LAVA) {
return;
}
// ... consider blocking it.
blockFireSpread(event.getBlock(), event);
}
// TODO: Is use of this event deprecated?
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockFireSpread(BlockSpreadEvent event) {
// If fire is spreading ...
if (event.getNewState().getType() != Material.FIRE) {
return;
}
// ... consider blocking it.
blockFireSpread(event.getBlock(), event);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockFireSpread(BlockBurnEvent event) {
// If a block is burning ...
// ... consider blocking it.
blockFireSpread(event.getBlock(), event);
}
}

View File

@ -0,0 +1,94 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.factions.util.EnumerationUtil;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.collections.BackstringSet;
import com.massivecraft.massivecore.ps.PS;
import org.bukkit.Location;
import org.bukkit.entity.EntityType;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.CreatureSpawnEvent;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import java.util.Set;
public class EngineFlagSpawn extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineFlagSpawn i = new EngineFlagSpawn();
public static EngineFlagSpawn get() {
return i;
}
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
public static final Set<SpawnReason> NATURAL_SPAWN_REASONS = new BackstringSet<>(SpawnReason.class,
"NATURAL",
"JOCKEY",
"CHUNK_GEN",
"OCELOT_BABY",
"NETHER_PORTAL",
"MOUNT",
"REINFORCEMENTS",
"VILLAGE_DEFENSE",
"VILLAGE_INVASION",
"RAID",
"PATROL"
);
// -------------------------------------------- //
// FLAG: MONSTERS & ANIMALS
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockMonstersAndAnimals(CreatureSpawnEvent event) {
// If this is a natural spawn ..
if (!NATURAL_SPAWN_REASONS.contains(event.getSpawnReason())) {
return;
}
// ... get the spawn location ...
Location location = event.getLocation();
PS ps = PS.valueOf(location);
// ... get the faction there ...
Faction faction = BoardColl.get().getFactionAt(ps);
if (faction == null) {
return;
}
// ... get the entity type ...
EntityType type = event.getEntityType();
// ... and if this type can't spawn in the faction ...
if (canSpawn(faction, type)) {
return;
}
// ... then cancel.
event.setCancelled(true);
}
public static boolean canSpawn(Faction faction, EntityType type) {
if (EnumerationUtil.isEntityTypeMonster(type)) {
// Monster
return faction.getFlag(MFlag.getFlagMonsters());
} else if (EnumerationUtil.isEntityTypeAnimal(type)) {
// Animal
return faction.getFlag(MFlag.getFlagAnimals());
} else {
// Other
return true;
}
}
}

View File

@ -0,0 +1,48 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.ps.PS;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Zombie;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityBreakDoorEvent;
public class EngineFlagZombiegrief extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineFlagZombiegrief i = new EngineFlagZombiegrief();
public static EngineFlagZombiegrief get() {
return i;
}
// -------------------------------------------- //
// FLAG: ZOMBIEGRIEF
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void denyZombieGrief(EntityBreakDoorEvent event) {
// If a zombie is breaking a door ...
Entity entity = event.getEntity();
if (!(entity instanceof Zombie)) {
return;
}
// ... and the faction there has zombiegrief disabled ...
PS ps = PS.valueOf(event.getBlock());
Faction faction = BoardColl.get().getFactionAt(ps);
if (faction.getFlag(MFlag.getFlagZombiegrief())) {
return;
}
// ... stop the door breakage.
event.setCancelled(true);
}
}

View File

@ -0,0 +1,239 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.Perm;
import com.massivecraft.factions.cmd.CmdFactions;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.factions.entity.MFlagColl;
import com.massivecraft.factions.entity.MPerm;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.event.EventFactionsFlagChange;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.MassiveException;
import com.massivecraft.massivecore.event.EventMassiveCorePlayerUpdate;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.store.DriverFlatfile;
import com.massivecraft.massivecore.util.MUtil;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.player.PlayerMoveEvent;
import java.io.File;
public class EngineFly extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineFly i = new EngineFly();
public static EngineFly get() {
return i;
}
// -------------------------------------------- //
// LISTENER
// -------------------------------------------- //
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
public void onMassiveCorePlayerUpdate(EventMassiveCorePlayerUpdate event) {
// If we are updating a player ...
Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) {
return;
}
// ... and that player isn't in creative or spectator mode ...
if (EventMassiveCorePlayerUpdate.isFlyAllowed(player, false)) {
return;
}
// ... and the player is alive ...
if (player.isDead()) {
return;
}
MPlayer mplayer = MPlayer.get(player);
// ... and the player enables flying ...
if (!mplayer.isFlying()) {
return;
}
// ... and the player can fly here...
if (!canFlyInTerritory(mplayer, PS.valueOf(player))) {
return;
}
// ... set allowed ...
event.setAllowed(true);
// ... set speed ...
event.setFlySpeed(MConf.get().flySpeed);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void moveChunkDetect(PlayerMoveEvent event) {
// If the player is moving from one chunk to another ...
if (MUtil.isSameChunk(event)) {
return;
}
Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) {
return;
}
// ... gather info on the player and the move ...
MPlayer mplayer = MPlayer.get(player);
PS chunkTo = PS.valueOf(event.getTo()).getChunk(true);
// ... and they are currently flying ...
if (!mplayer.isFlying()) {
return;
}
// ... but can't fly at the new place ...
if (canFlyInTerritory(mplayer, chunkTo)) {
return;
}
// ... then perhaps they should not be
mplayer.setFlying(false);
deactivateForPlayer(player);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void flagUpdate(EventFactionsFlagChange event) {
if (event.getFlag() != MFlag.getFlagFly()) {
return;
}
if (event.isNewValue() == true) {
return;
}
// Disable for all players when disabled
event.getFaction().getOnlinePlayers().forEach(EngineFly::deactivateForPlayer);
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void territoryShield(EntityDamageByEntityEvent event) {
// If flying is diabled on PVP ...
if (!MConf.get().flyDisableOnPvp) {
return;
}
// ... and the defender is a player ...
Entity entity = event.getEntity();
if (MUtil.isntPlayer(entity)) {
return;
}
Player defender = (Player) entity;
MPlayer mdefender = MPlayer.get(defender);
// ... and the attacker is a player ...
Entity eattacker = MUtil.getLiableDamager(event);
if (!(eattacker instanceof Player)) {
return;
}
Player attacker = (Player) eattacker;
MPlayer mattacker = MPlayer.get(attacker);
// ... disable flying for both
if (mdefender.isFlying()) {
mdefender.setFlying(false);
deactivateForPlayer(defender);
mdefender.msg("<i>Flying is disabled in combat.");
}
if (mattacker.isFlying()) {
mattacker.setFlying(false);
deactivateForPlayer(attacker);
mattacker.msg("<i>Flying is disabled in combat.");
}
}
public static boolean canFlyInTerritory(MPlayer mplayer, PS ps) {
try {
canFlyInTerritoryOrThrow(mplayer, ps);
return true;
} catch (MassiveException ex) {
return false;
}
}
public static void canFlyInTerritoryOrThrow(MPlayer mplayer, PS ps) throws MassiveException {
if (!mplayer.isPlayer()) {
throw new MassiveException().addMsg("<b>Only players can fly.");
}
Faction faction = mplayer.getFaction();
Faction locationFaction = BoardColl.get().getFactionAt(ps.getChunk(true));
if (faction != locationFaction) {
throw new MassiveException().addMsg("<b>You can only fly within your own faction.");
}
// If the faction does not have the flag ...
if (!faction.getFlag(MFlag.getFlagFly())) {
MFlag flag = MFlag.getFlagFly();
MassiveException ex = new MassiveException()
.addMsg("<b>Flying requires that the <h>%s <b>flag is enabled for your faction.", flag.getName());
// ... but they can change ...
if (flag.isEditable()) {
boolean canEdit = MPerm.getPermFlags().has(mplayer, faction, false);
// ... and the player can edit it themselves ...
if (canEdit) {
// ... tell them to edit.
ex.addMsg("<i>You can edit the flag with: ");
ex.addMessage(CmdFactions.get().cmdFactionsFlag.cmdFactionsFlagSet.getTemplate(false, true, mplayer.getSender()));
}
// ... otherwise ...
else {
// .. tell them to have someone else edit it ...
ex.addMsg("<i>You can ask a faction admin to change the flag.");
}
}
// ... or only server admins can change it ...
else {
boolean isAdmin = Perm.OVERRIDE.has(mplayer.getSender());
boolean isDefault = flag.isDefault();
if (isAdmin) {
boolean overriding = mplayer.isOverriding();
ex.addMsg("<i>You can change the flag if you are overriding.");
if (overriding) {
ex.addMsg("<i>You are already overriding.");
} else {
ex.addMsg("<i>You can enable override with:");
ex.addMessage(CmdFactions.get().cmdFactionsOverride.getTemplate(false, true, mplayer.getSender()));
}
if (!isDefault) {
ex.addMsg("<i>You can also ask someone with access to the configuration files to make flying enabled by default.");
if (MFlagColl.get().getDb().getDriver() instanceof DriverFlatfile) {
File file = DriverFlatfile.getDirectory(MFlagColl.get());
ex.addMsg("<i>Configuring the flags can be done by editing the files in <h>%s<i>.", file.getAbsoluteFile());
}
}
} else {
ex.addMsg("<b>Only server admins can change the flag. Per default flying is %s.", isDefault ? "enabled" : "disabled");
}
}
throw ex;
}
}
public static void deactivateForPlayer(Player player) {
EventMassiveCorePlayerUpdate.resetFlyAllowed(player);
EventMassiveCorePlayerUpdate.resetFlyActive(player);
EventMassiveCorePlayerUpdate.resetFlySpeed(player);
EventMassiveCorePlayerUpdate.run(player);
}
}

View File

@ -0,0 +1,65 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave;
import com.massivecraft.massivecore.util.MUtil;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
public class EngineLastActivity extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineLastActivity i = new EngineLastActivity();
public static EngineLastActivity get() {
return i;
}
// -------------------------------------------- //
// UPDATE LAST ACTIVITY
// -------------------------------------------- //
public static void updateLastActivity(CommandSender sender) {
if (sender == null) {
throw new RuntimeException("sender");
}
if (MUtil.isntSender(sender)) {
return;
}
MPlayer mplayer = MPlayer.get(sender);
mplayer.setLastActivityMillis();
}
public static void updateLastActivitySoon(final CommandSender sender) {
if (sender == null) {
throw new RuntimeException("sender");
}
Bukkit.getScheduler().scheduleSyncDelayedTask(Factions.get(), () -> updateLastActivity(sender));
}
// Can't be cancelled
@EventHandler(priority = EventPriority.LOWEST)
public void updateLastActivity(PlayerJoinEvent event) {
// During the join event itself we want to be able to reach the old data.
// That is also the way the underlying fallback Mixin system does it and we do it that way for the sake of symmetry.
// For that reason we wait till the next tick with updating the value.
updateLastActivitySoon(event.getPlayer());
}
// Can't be cancelled
@EventHandler(priority = EventPriority.LOWEST)
public void updateLastActivity(EventMassiveCorePlayerLeave event) {
// Here we do however update immediately.
// The player data should be fully updated before leaving the server.
updateLastActivity(event.getPlayer());
}
}

View File

@ -0,0 +1,105 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.mixin.MixinActual;
import com.massivecraft.massivecore.mixin.MixinMessage;
import com.massivecraft.massivecore.util.MUtil;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerJoinEvent;
import java.util.List;
public class EngineMotd extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineMotd i = new EngineMotd();
public static EngineMotd get() {
return i;
}
// -------------------------------------------- //
// MOTD
// -------------------------------------------- //
public static void motd(PlayerJoinEvent event, EventPriority currentPriority) {
// Gather info ...
final Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) {
return;
}
final MPlayer mplayer = MPlayer.get(player);
final Faction faction = mplayer.getFaction();
// ... if there is a motd ...
if (!faction.hasMotd()) {
return;
}
// ... and this is the priority we are supposed to act on ...
if (currentPriority != MConf.get().motdPriority) {
return;
}
// ... and this is an actual join ...
if (!MixinActual.get().isActualJoin(event)) {
return;
}
// ... then prepare the messages ...
final List<Object> messages = faction.getMotdMessages();
// ... and send to the player.
if (MConf.get().motdDelayTicks < 0) {
MixinMessage.get().messageOne(player, messages);
} else {
Bukkit.getScheduler().scheduleSyncDelayedTask(Factions.get(), () -> MixinMessage.get().messageOne(player, messages), MConf.get().motdDelayTicks);
}
}
// Can't be cancelled
@EventHandler(priority = EventPriority.LOWEST)
public void motdLowest(PlayerJoinEvent event) {
motd(event, EventPriority.LOWEST);
}
// Can't be cancelled
@EventHandler(priority = EventPriority.LOW)
public void motdLow(PlayerJoinEvent event) {
motd(event, EventPriority.LOW);
}
// Can't be cancelled
@EventHandler(priority = EventPriority.NORMAL)
public void motdNormal(PlayerJoinEvent event) {
motd(event, EventPriority.NORMAL);
}
// Can't be cancelled
@EventHandler(priority = EventPriority.HIGH)
public void motdHigh(PlayerJoinEvent event) {
motd(event, EventPriority.HIGH);
}
// Can't be cancelled
@EventHandler(priority = EventPriority.HIGHEST)
public void motdHighest(PlayerJoinEvent event) {
motd(event, EventPriority.HIGHEST);
}
// Can't be cancelled
@EventHandler(priority = EventPriority.MONITOR)
public void motdMonitor(PlayerJoinEvent event) {
motd(event, EventPriority.MONITOR);
}
}

View File

@ -0,0 +1,149 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.AccessStatus;
import com.massivecraft.factions.TerritoryAccess;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.util.AsciiMap;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.mixin.MixinTitle;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.Txt;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerMoveEvent;
import java.util.Collections;
public class EngineMoveChunk extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineMoveChunk i = new EngineMoveChunk();
public static EngineMoveChunk get() {
return i;
}
// -------------------------------------------- //
// MOVE CHUNK: DETECT
// -------------------------------------------- //
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void moveChunkDetect(PlayerMoveEvent event) {
// If the player is moving from one chunk to another ...
if (MUtil.isSameChunk(event)) {
return;
}
Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) {
return;
}
// ... gather info on the player and the move ...
MPlayer mplayer = MPlayer.get(player);
PS psFrom = PS.valueOf(event.getFrom());
PS psTo = PS.valueOf(event.getTo());
// ... send info onwards and try auto-claiming.
sendChunkInfo(mplayer, player, psFrom, psTo);
tryAutoClaim(mplayer, psTo);
}
// -------------------------------------------- //
// MOVE CHUNK: SEND CHUNK INFO
// -------------------------------------------- //
private static void sendChunkInfo(MPlayer mplayer, Player player, PS psFrom, PS psTo) {
sendAutoMapUpdate(mplayer, psTo);
sendFactionTerritoryInfo(mplayer, player, psFrom, psTo);
sendTerritoryAccessMessage(mplayer, psFrom, psTo);
}
private static void sendAutoMapUpdate(MPlayer mplayer, PS ps) {
if (!mplayer.isMapAutoUpdating()) {
return;
}
AsciiMap map = new AsciiMap(mplayer, ps, false);
mplayer.message(map.render());
}
private static void sendFactionTerritoryInfo(MPlayer mplayer, Player player, PS psFrom, PS psTo) {
Faction factionFrom = BoardColl.get().getFactionAt(psFrom);
Faction factionTo = BoardColl.get().getFactionAt(psTo);
if (factionFrom == factionTo) {
return;
}
if (mplayer.isTerritoryInfoTitles()) {
String titleMain = parseTerritoryInfo(MConf.get().territoryInfoTitlesMain, mplayer, factionTo);
String titleSub = parseTerritoryInfo(MConf.get().territoryInfoTitlesSub, mplayer, factionTo);
int ticksIn = MConf.get().territoryInfoTitlesTicksIn;
int ticksStay = MConf.get().territoryInfoTitlesTicksStay;
int ticksOut = MConf.get().territoryInfoTitleTicksOut;
MixinTitle.get().sendTitleMessage(player, ticksIn, ticksStay, ticksOut, titleMain, titleSub);
} else {
String message = parseTerritoryInfo(MConf.get().territoryInfoChat, mplayer, factionTo);
player.sendMessage(message);
}
}
private static String parseTerritoryInfo(String string, MPlayer mplayer, Faction faction) {
if (string == null) {
throw new NullPointerException("string");
}
if (faction == null) {
throw new NullPointerException("faction");
}
string = Txt.parse(string);
string = string.replace("{name}", faction.getName());
string = string.replace("{relcolor}", faction.getColorTo(mplayer).toString());
string = string.replace("{desc}", faction.getDescriptionDesc());
return string;
}
private static void sendTerritoryAccessMessage(MPlayer mplayer, PS psFrom, PS psTo) {
if (!MConf.get().territoryAccessShowMessage) {
return;
}
// Get TerritoryAccess for from & to chunks
TerritoryAccess accessFrom = BoardColl.get().getTerritoryAccessAt(psFrom);
TerritoryAccess accessTo = BoardColl.get().getTerritoryAccessAt(psTo);
// See if the status has changed
AccessStatus statusFrom = accessFrom.getTerritoryAccess(mplayer);
AccessStatus statusTo = accessTo.getTerritoryAccess(mplayer);
if (statusFrom == statusTo) {
return;
}
// Inform
mplayer.message(statusTo.getStatusMessage());
}
// -------------------------------------------- //
// MOVE CHUNK: TRY AUTO CLAIM
// -------------------------------------------- //
private static void tryAutoClaim(MPlayer mplayer, PS chunkTo) {
// If the player is auto claiming ...
Faction autoClaimFaction = mplayer.getAutoClaimFaction();
if (autoClaimFaction == null) {
return;
}
// ... try claim.
mplayer.tryClaim(autoClaimFaction, Collections.singletonList(chunkTo));
}
}

View File

@ -0,0 +1,506 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.Factions;
import com.massivecraft.factions.TerritoryAccess;
import com.massivecraft.factions.entity.Board;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.FactionColl;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MPerm;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.util.EnumerationUtil;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.MUtil;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.event.Cancellable;
import org.bukkit.event.Event;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.Action;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockPistonExtendEvent;
import org.bukkit.event.block.BlockPistonRetractEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import org.bukkit.event.block.SignChangeEvent;
import org.bukkit.event.entity.EntityChangeBlockEvent;
import org.bukkit.event.entity.EntityCombustByEntityEvent;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import org.bukkit.event.hanging.HangingBreakByEntityEvent;
import org.bukkit.event.hanging.HangingPlaceEvent;
import org.bukkit.event.player.PlayerBucketEmptyEvent;
import org.bukkit.event.player.PlayerBucketFillEvent;
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.player.PlayerInteractEvent;
import org.bukkit.projectiles.ProjectileSource;
import java.util.List;
import java.util.Map;
public class EnginePermBuild extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EnginePermBuild i = new EnginePermBuild();
public static EnginePermBuild get() {
return i;
}
// -------------------------------------------- //
// LOGIC > PROTECT
// -------------------------------------------- //
public static Boolean isProtected(ProtectCase protectCase, boolean verboose, MPlayer mplayer, PS ps, Object object) {
if (mplayer == null) {
return null;
}
if (protectCase == null) {
return null;
}
String name = mplayer.getName();
if (MConf.get().playersWhoBypassAllProtection.contains(name)) {
return false;
}
if (mplayer.isOverriding()) {
return false;
}
MPerm perm = protectCase.getPerm(object);
if (perm == null) {
return null;
}
if (protectCase != ProtectCase.BUILD) {
return !perm.has(mplayer, ps, verboose);
}
if (!perm.has(mplayer, ps, false) && MPerm.getPermPainbuild().has(mplayer, ps, false)) {
if (!verboose) {
return false;
}
Faction hostFaction = BoardColl.get().getFactionAt(ps);
mplayer.msg("<b>It is painful to build in the territory of %s<b>.", hostFaction.describeTo(mplayer));
Player player = mplayer.getPlayer();
if (player != null) {
player.damage(MConf.get().actionDeniedPainAmount);
}
}
return !perm.has(mplayer, ps, verboose);
}
public static Boolean protect(ProtectCase protectCase, boolean verboose, Player player, PS ps, Object object, Cancellable cancellable) {
Boolean ret = isProtected(protectCase, verboose, MPlayer.get(player), ps, object);
if (Boolean.TRUE.equals(ret) && cancellable != null) {
cancellable.setCancelled(true);
}
return ret;
}
public static Boolean build(Entity entity, Block block, Event event) {
if (!(event instanceof Cancellable)) {
return true;
}
if (MUtil.isntPlayer(entity)) {
return false;
}
Player player = (Player) entity;
boolean verboose = !isFake(event);
return protect(ProtectCase.BUILD, verboose, player, PS.valueOf(block), block, (Cancellable) event);
}
public static Boolean useItem(Player player, Block block, Material material, Cancellable cancellable) {
return protect(ProtectCase.USE_ITEM, true, player, PS.valueOf(block), material, cancellable);
}
public static Boolean useEntity(Player player, Entity entity, boolean verboose, Cancellable cancellable) {
return protect(ProtectCase.USE_ENTITY, verboose, player, PS.valueOf(entity), entity, cancellable);
}
public static Boolean useBlock(Player player, Block block, boolean verboose, Cancellable cancellable) {
return protect(ProtectCase.USE_BLOCK, verboose, player, PS.valueOf(block), block.getType(), cancellable);
}
// -------------------------------------------- //
// LOGIC > PROTECT > BUILD
// -------------------------------------------- //
public static boolean canPlayerBuildAt(Object senderObject, PS ps, boolean verboose) {
MPlayer mplayer = MPlayer.get(senderObject);
if (mplayer == null) {
return false;
}
Boolean ret = isProtected(ProtectCase.BUILD, verboose, mplayer, ps, null);
return !Boolean.TRUE.equals(ret);
}
// -------------------------------------------- //
// BUILD > BLOCK
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL)
public void build(BlockPlaceEvent event) {
build(event.getPlayer(), event.getBlock(), event);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void build(BlockBreakEvent event) {
build(event.getPlayer(), event.getBlock(), event);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void build(SignChangeEvent event) {
build(event.getPlayer(), event.getBlock(), event);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void build(HangingPlaceEvent event) {
build(event.getPlayer(), event.getBlock(), event);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void build(HangingBreakByEntityEvent event) {
build(event.getRemover(), event.getEntity().getLocation().getBlock(), event);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void build(EntityChangeBlockEvent event) {
// Handling lilypads being broken by boats
Entity entity = event.getEntity();
if (entity.getType() != EntityType.BOAT || entity.getPassengers().size() <= 0) {
return;
}
Entity player = entity.getPassengers().stream().filter(MUtil::isPlayer).findAny().orElse(entity);
build(player, event.getBlock(), event);
}
// -------------------------------------------- //
// USE > ITEM
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void useBlockItem(PlayerInteractEvent event) {
// If the player right clicks (or is physical with) a block ...
if (event.getAction() != Action.RIGHT_CLICK_BLOCK && event.getAction() != Action.PHYSICAL) {
return;
}
Block block = event.getClickedBlock();
Player player = event.getPlayer();
if (block == null) {
return;
}
// ... and we are either allowed to use this block ...
Boolean ret = useBlock(player, block, true, event);
if (Boolean.TRUE.equals(ret)) {
return;
}
// ... or are allowed to right click with the item, this event is safe to perform.
if (event.getAction() != Action.RIGHT_CLICK_BLOCK) {
return;
}
useItem(player, block, event.getMaterial(), event);
}
// For some reason onPlayerInteract() sometimes misses bucket events depending on distance
// (something like 2-3 blocks away isn't detected), but these separate bucket events below always fire without fail
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void useItem(PlayerBucketEmptyEvent event) {
useItem(event.getPlayer(), event.getBlockClicked().getRelative(event.getBlockFace()), event.getBucket(), event);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void useItem(PlayerBucketFillEvent event) {
useItem(event.getPlayer(), event.getBlockClicked(), event.getBucket(), event);
}
// -------------------------------------------- //
// USE > ENTITY
// -------------------------------------------- //
// This event will not fire for Minecraft 1.8 armor stands.
// Armor stands are handled in EngineSpigot instead.
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void useEntity(PlayerInteractEntityEvent event) {
// Ignore Off Hand
if (isOffHand(event)) {
return;
}
useEntity(event.getPlayer(), event.getRightClicked(), true, event);
}
// This is a special Spigot event that fires for Minecraft 1.8 armor stands.
// It also fires for other entity types but for those the event is buggy.
// It seems we can only cancel interaction with armor stands from here.
// Thus we only handle armor stands from here and handle everything else in EngineMain.
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void handleArmorStand(PlayerInteractAtEntityEvent event) {
// Ignore Off Hand
if (isOffHand(event)) {
return;
}
// Gather Info
final Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) {
return;
}
final Entity entity = event.getRightClicked();
final boolean verboose = true;
// Only care for armor stands.
if (entity.getType() != EntityType.ARMOR_STAND) {
return;
}
// If we can't use, block it
EnginePermBuild.useEntity(player, entity, verboose, event);
}
// -------------------------------------------- //
// BUILD > ENTITY
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void buildEntity(EntityDamageByEntityEvent event) {
// If a player ...
Entity damager = MUtil.getLiableDamager(event);
if (MUtil.isntPlayer(damager)) {
return;
}
Player player = (Player) damager;
// ... damages an entity which is edited on damage ...
Entity entity = event.getEntity();
if (entity == null || !EnumerationUtil.isEntityTypeEditOnDamage(entity.getType())) {
return;
}
// ... and the player can't build there, cancel the event
build(player, entity.getLocation().getBlock(), event);
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void combustEntity(EntityCombustByEntityEvent event) {
// If a burning projectile ...
if (!(event.getCombuster() instanceof Projectile)) {
return;
}
Projectile entityProjectile = (Projectile) event.getCombuster();
// ... fired by a player ...
ProjectileSource projectileSource = entityProjectile.getShooter();
if (MUtil.isntPlayer(projectileSource)) {
return;
}
Player player = (Player) projectileSource;
// ... and hits an entity which is edited on damage (and thus likely to burn) ...
Entity entityTarget = event.getEntity();
if (entityTarget == null || !EnumerationUtil.isEntityTypeEditOnDamage(entityTarget.getType())) {
return;
}
// ... and the player can't build there, cancel the event
Block block = entityTarget.getLocation().getBlock();
protect(ProtectCase.BUILD, false, player, PS.valueOf(block), block, event);
}
// -------------------------------------------- //
// BUILD > PISTON
// -------------------------------------------- //
/*
* Note: With 1.8 and the slime blocks, retracting and extending pistons
* became more of a problem. Blocks located on the border of a chunk
* could have easily been stolen. That is the reason why every block
* needs to be checked now, whether he moved into a territory which
* he actually may not move into.
*/
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockBuild(BlockPistonExtendEvent event) {
// Is checking deactivated by MConf?
if (!MConf.get().handlePistonProtectionThroughDenyBuild) {
return;
}
Faction pistonFaction = BoardColl.get().getFactionAt(PS.valueOf(event.getBlock()));
List<Block> blocks = event.getBlocks();
// Check for all extended blocks
for (Block block : blocks) {
// Block which is being pushed into
Block targetBlock = block.getRelative(event.getDirection());
// Members of a faction might not have build rights in their own territory, but pistons should still work regardless
Faction targetFaction = BoardColl.get().getFactionAt(PS.valueOf(targetBlock));
if (targetFaction == pistonFaction) {
continue;
}
// Perm check
if (MPerm.getPermBuild().has(pistonFaction, targetFaction)) {
continue;
}
event.setCancelled(true);
return;
}
}
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void blockBuild(BlockPistonRetractEvent event) {
// Is checking deactivated by MConf?
if (!MConf.get().handlePistonProtectionThroughDenyBuild) {
return;
}
Faction pistonFaction = BoardColl.get().getFactionAt(PS.valueOf(event.getBlock()));
List<Block> blocks = event.getBlocks();
// Check for all retracted blocks
for (Block block : blocks) {
// Is the retracted block air/water/lava? Don't worry about it
if (block.isEmpty() || block.isLiquid()) {
return;
}
// Members of a faction might not have build rights in their own territory, but pistons should still work regardless
Faction targetFaction = BoardColl.get().getFactionAt(PS.valueOf(block));
if (targetFaction == pistonFaction) {
continue;
}
// Perm check
if (MPerm.getPermBuild().has(pistonFaction, targetFaction)) {
continue;
}
event.setCancelled(true);
return;
}
}
// -------------------------------------------- //
// BUILD > FIRE
// -------------------------------------------- //
@SuppressWarnings("deprecation")
@EventHandler(priority = EventPriority.NORMAL)
public void buildFire(PlayerInteractEvent event) {
// If it is a left click on block and the clicked block is not null...
if (event.getAction() != Action.LEFT_CLICK_BLOCK || event.getClickedBlock() == null) {
return;
}
// ... and the potential block is not null either ...
Block potentialBlock = event.getClickedBlock().getRelative(BlockFace.UP, 1);
if (potentialBlock == null) {
return;
}
Material blockType = potentialBlock.getType();
// ... and we're only going to check for fire ... (checking everything else would be bad performance wise)
if (blockType != Material.FIRE) {
return;
}
// ... check if they can't build, cancel the event ...
if (!Boolean.FALSE.equals(build(event.getPlayer(), potentialBlock, event))) {
return;
}
// ... and compensate for client side prediction
event.getPlayer().sendBlockChange(potentialBlock.getLocation(), blockType, potentialBlock.getState().getRawData());
}
// -------------------------------------------- //
// BUILD > MOVE
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void buildMove(BlockFromToEvent event) {
if (!MConf.get().protectionLiquidFlowEnabled) {
return;
}
// Prepare fields
Block fromBlock = event.getBlock();
int chunkFromX = fromBlock.getX() >> 4;
int chunkFromZ = fromBlock.getZ() >> 4;
BlockFace face = event.getFace();
int chunkToX = (fromBlock.getX() + face.getModX()) >> 4;
int chunkToZ = (fromBlock.getZ() + face.getModZ()) >> 4;
// If a liquid (or dragon egg) moves from one chunk to another ...
if (chunkToX == chunkFromX && chunkToZ == chunkFromZ) {
return;
}
// ... get the correct board for this block ...
Board board = BoardColl.get().getFixed(fromBlock.getWorld().getName().toLowerCase(), false);
if (board == null) {
return;
}
// ... get the access map ...
Map<PS, TerritoryAccess> map = board.getMapRaw();
if (map.isEmpty()) {
return;
}
// ... get the faction ids from and to ...
PS fromPs = PS.valueOf(chunkFromX, chunkFromZ);
PS toPs = PS.valueOf(chunkToX, chunkToZ);
TerritoryAccess fromTa = map.get(fromPs);
TerritoryAccess toTa = map.get(toPs);
// Null checks are needed here since automatic board cleaning can be undesired sometimes
String fromId = fromTa != null ? fromTa.getHostFactionId() : Factions.ID_NONE;
String toId = toTa != null ? toTa.getHostFactionId() : Factions.ID_NONE;
// ... and the chunks belong to different factions ...
if (toId.equals(fromId)) {
return;
}
// ... and the faction "from" can not build at "to" ...
Faction fromFac = FactionColl.get().getFixed(fromId);
if (fromFac == null) {
fromFac = FactionColl.get().getNone();
}
Faction toFac = FactionColl.get().getFixed(toId);
if (toFac == null) {
toFac = FactionColl.get().getNone();
}
if (MPerm.getPermBuild().has(fromFac, toFac)) {
return;
}
// ... cancel the event!
event.setCancelled(true);
}
}

View File

@ -0,0 +1,57 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.entity.MPlayerColl;
import com.massivecraft.massivecore.Engine;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerKickEvent;
public class EnginePlayerData extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EnginePlayerData i = new EnginePlayerData();
public static EnginePlayerData get() {
return i;
}
// -------------------------------------------- //
// REMOVE PLAYER DATA WHEN BANNED
// -------------------------------------------- //
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerKick(PlayerKickEvent event) {
// If a player was kicked from the server ...
Player player = event.getPlayer();
// ... and if the if player was banned (not just kicked) ...
//if (!event.getReason().equals("Banned by admin.")) return;
if (!player.isBanned()) {
return;
}
// ... and we remove player data when banned ...
if (!MConf.get().removePlayerWhenBanned) {
return;
}
// ... get rid of their stored info.
MPlayer mplayer = MPlayerColl.get().get(player, false);
if (mplayer == null) {
return;
}
if (mplayer.getRank().isLeader()) {
mplayer.getFaction().promoteNewLeader();
}
mplayer.leave();
mplayer.detach();
}
}

View File

@ -0,0 +1,80 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.BoardColl;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.event.EventFactionsPowerChange;
import com.massivecraft.factions.event.EventFactionsPowerChange.PowerChangeReason;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.PlayerUtil;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.PlayerDeathEvent;
public class EnginePower extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EnginePower i = new EnginePower();
public static EnginePower get() {
return i;
}
// -------------------------------------------- //
// POWER LOSS ON DEATH
// -------------------------------------------- //
@EventHandler(priority = EventPriority.NORMAL)
public void powerLossOnDeath(PlayerDeathEvent event) {
// If a player dies ...
Player player = event.getEntity();
if (MUtil.isntPlayer(player)) {
return;
}
// ... and this is the first death event this tick ...
// (yeah other plugins can case death event to fire twice the same tick)
if (PlayerUtil.isDuplicateDeathEvent(event)) {
return;
}
MPlayer mplayer = MPlayer.get(player);
// ... and powerloss can happen here ...
Faction faction = BoardColl.get().getFactionAt(PS.valueOf(player.getLocation()));
if (!faction.getFlag(MFlag.getFlagPowerloss())) {
mplayer.msg("<i>You didn't lose any power since the territory you died in works that way.");
return;
}
if (!MConf.get().worldsPowerLossEnabled.contains(player.getWorld())) {
mplayer.msg("<i>You didn't lose any power due to the world you died in.");
return;
}
// ... alter the power ...
double newPower = mplayer.getPower() + mplayer.getPowerPerDeath();
EventFactionsPowerChange powerChangeEvent = new EventFactionsPowerChange(null, mplayer, PowerChangeReason.DEATH, newPower);
powerChangeEvent.run();
if (powerChangeEvent.isCancelled()) {
return;
}
newPower = powerChangeEvent.getNewPower();
mplayer.setPower(newPower);
// ... and inform the player.
// TODO: A progress bar here would be epic :)
mplayer.msg("<i>Your power is now <h>%.2f / %.2f", newPower, mplayer.getPowerMax());
}
}

View File

@ -0,0 +1,192 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.event.EventMassiveCorePlayerLeave;
import com.massivecraft.massivecore.ps.PS;
import com.massivecraft.massivecore.util.MUtil;
import com.massivecraft.massivecore.util.PeriodUtil;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Particle;
import org.bukkit.World;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerChangedWorldEvent;
import java.security.InvalidParameterException;
import java.util.ArrayList;
import java.util.List;
public class EngineSeeChunk extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineSeeChunk i = new EngineSeeChunk();
public static EngineSeeChunk get() {
return i;
}
public EngineSeeChunk() {
this.setPeriod(1L);
}
// -------------------------------------------- //
// LEAVE AND WORLD CHANGE REMOVAL
// -------------------------------------------- //
public static void leaveAndWorldChangeRemoval(Player player) {
if (MUtil.isntPlayer(player)) {
return;
}
final MPlayer mplayer = MPlayer.get(player);
mplayer.setSeeingChunk(false);
}
// Can't be cancelled
@EventHandler(priority = EventPriority.NORMAL)
public void leaveAndWorldChangeRemoval(EventMassiveCorePlayerLeave event) {
leaveAndWorldChangeRemoval(event.getPlayer());
}
// Can't be cancelled
@EventHandler(priority = EventPriority.NORMAL)
public void leaveAndWorldChangeRemoval(PlayerChangedWorldEvent event) {
leaveAndWorldChangeRemoval(event.getPlayer());
}
// -------------------------------------------- //
// MODULO REPEAT TASK
// -------------------------------------------- //
@Override
public void run() {
// Do we have a new period?
final long now = System.currentTimeMillis();
final long length = 500;
if (!PeriodUtil.isNewPeriod(this, length, now)) {
return;
}
// Get the period number
final long period = PeriodUtil.getPeriod(length, now);
// Calculate the "step" from the period number
final int steps = 1; // Example: 4
final int step = (int) (period % steps); // Example: 0, 1, 2, 3
// Load other related config options
final float offsetX = 0.0f;
final float offsetY = 2;
final float offsetZ = 0.0f;
final float speed = 0;
final int amount = 30;
// For each player
for (Player player : Bukkit.getOnlinePlayers()) {
// Hide for dead players since the death screen looks better without.
if (player.isDead()) {
continue;
}
// The player must obviously have the feature activated.
MPlayer mplayer = MPlayer.get(player);
if (!mplayer.isSeeingChunk()) {
continue;
}
// Calculate locations and play the effect there.
List<Location> locations = getLocations(player, steps, step);
for (Location location : locations) {
location.getWorld().spawnParticle(Particle.EXPLOSION_NORMAL, location, amount, offsetX, offsetY, offsetZ, speed);
//ParticleEffect.EXPLOSION_NORMAL.display(location, offsetX, offsetY, offsetZ, speed, amount, player);
}
}
}
public static List<Location> getLocations(Player player, int steps, int step) {
// Clean Args
if (player == null) {
throw new NullPointerException("player");
}
if (steps < 1) {
throw new InvalidParameterException("steps must be larger than 0");
}
if (step < 0) {
throw new InvalidParameterException("step must at least be 0");
}
if (step >= steps) {
throw new InvalidParameterException("step must be less than steps");
}
// Create Ret
List<Location> ret = new ArrayList<>();
final Location location = player.getLocation();
final World world = location.getWorld();
PS chunk = PS.valueOf(location).getChunk(true);
final int xmin = chunk.getChunkX() * 16;
final int xmax = xmin + 15;
final double y = location.getBlockY() + 2;
final int zmin = chunk.getChunkZ() * 16;
final int zmax = zmin + 15;
int keepEvery = 5;
if (keepEvery <= 0) {
keepEvery = Integer.MAX_VALUE;
}
int skipEvery = 0;
if (skipEvery <= 0) {
skipEvery = Integer.MAX_VALUE;
}
int x = xmin;
int z = zmin;
int i = 0;
// Add #1
while (x + 1 <= xmax) {
x++;
i++;
if (i % steps == step && (i % keepEvery == 0 && i % skipEvery != 0)) {
ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
}
}
// Add #2
while (z + 1 <= zmax) {
z++;
i++;
if (i % steps == step && (i % keepEvery == 0 && i % skipEvery != 0)) {
ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
}
}
// Add #3
while (x - 1 >= xmin) {
x--;
i++;
if (i % steps == step && (i % keepEvery == 0 && i % skipEvery != 0)) {
ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
}
}
// Add #4
while (z - 1 >= zmin) {
z--;
i++;
if (i % steps == step && (i % keepEvery == 0 && i % skipEvery != 0)) {
ret.add(new Location(world, x + 0.5, y + 0.5, z + 0.5));
}
}
// Return Ret
return ret;
}
}

View File

@ -0,0 +1,238 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.comparator.ComparatorMPlayerRole;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MFlag;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.event.EventFactionsChunkChangeType;
import com.massivecraft.factions.event.EventFactionsFactionShowAsync;
import com.massivecraft.factions.integration.Econ;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.PriorityLines;
import com.massivecraft.massivecore.money.Money;
import com.massivecraft.massivecore.util.TimeDiffUtil;
import com.massivecraft.massivecore.util.TimeUnit;
import com.massivecraft.massivecore.util.Txt;
import org.bukkit.command.CommandSender;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class EngineShow extends Engine {
// -------------------------------------------- //
// CONSTANTS
// -------------------------------------------- //
public static final String BASENAME = "factions";
public static final String BASENAME_ = BASENAME + "_";
public static final String SHOW_ID_FACTION_ID = BASENAME_ + "id";
public static final String SHOW_ID_FACTION_DESCRIPTION = BASENAME_ + "description";
public static final String SHOW_ID_FACTION_AGE = BASENAME_ + "age";
public static final String SHOW_ID_FACTION_FLAGS = BASENAME_ + "flags";
public static final String SHOW_ID_FACTION_POWER = BASENAME_ + "power";
public static final String SHOW_ID_FACTION_LANDVALUES = BASENAME_ + "landvalue";
public static final String SHOW_ID_FACTION_BANK = BASENAME_ + "bank";
public static final String SHOW_ID_FACTION_FOLLOWERS = BASENAME_ + "followers";
public static final int SHOW_PRIORITY_FACTION_ID = 1000;
public static final int SHOW_PRIORITY_FACTION_DESCRIPTION = 2000;
public static final int SHOW_PRIORITY_FACTION_AGE = 3000;
public static final int SHOW_PRIORITY_FACTION_FLAGS = 4000;
public static final int SHOW_PRIORITY_FACTION_POWER = 5000;
public static final int SHOW_PRIORITY_FACTION_LANDVALUES = 6000;
public static final int SHOW_PRIORITY_FACTION_BANK = 7000;
public static final int SHOW_PRIORITY_FACTION_FOLLOWERS = 9000;
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineShow i = new EngineShow();
public static EngineShow get() {
return i;
}
// -------------------------------------------- //
// FACTION SHOW
// -------------------------------------------- //
@EventHandler(priority = EventPriority.LOW, ignoreCancelled = true)
public void onFactionShow(EventFactionsFactionShowAsync event) {
final int tableCols = 4;
final CommandSender sender = event.getSender();
final MPlayer mplayer = event.getMPlayer();
final Faction faction = event.getFaction();
final boolean normal = faction.isNormal();
final Map<String, PriorityLines> idPriorityLiness = event.getIdPriorityLiness();
String none = Txt.parse("<silver><italic>none");
// ID
if (mplayer.isOverriding()) {
show(idPriorityLiness, SHOW_ID_FACTION_ID, SHOW_PRIORITY_FACTION_ID, "ID", faction.getId());
}
// DESCRIPTION
show(idPriorityLiness, SHOW_ID_FACTION_DESCRIPTION, SHOW_PRIORITY_FACTION_DESCRIPTION, "Description", faction.getDescriptionDesc());
// SECTION: NORMAL
if (normal) {
// AGE
long ageMillis = faction.getCreatedAtMillis() - System.currentTimeMillis();
LinkedHashMap<TimeUnit, Long> ageUnitcounts = TimeDiffUtil.limit(TimeDiffUtil.unitcounts(ageMillis, TimeUnit.getAllButMillis()), 3);
String ageDesc = TimeDiffUtil.formatedVerboose(ageUnitcounts, "<i>");
show(idPriorityLiness, SHOW_ID_FACTION_AGE, SHOW_PRIORITY_FACTION_AGE, "Age", ageDesc);
// FLAGS
// We display all editable and non default ones. The rest we skip.
List<String> flagDescs = new LinkedList<>();
for (Entry<MFlag, Boolean> entry : faction.getFlags().entrySet()) {
final MFlag mflag = entry.getKey();
if (mflag == null) {
continue;
}
final Boolean value = entry.getValue();
if (value == null) {
continue;
}
if (!mflag.isInteresting(value)) {
continue;
}
String flagDesc = Txt.parse(value ? "<g>" : "<b>") + mflag.getName();
flagDescs.add(flagDesc);
}
String flagsDesc = Txt.parse("<silver><italic>default");
if (!flagDescs.isEmpty()) {
flagsDesc = Txt.implode(flagDescs, Txt.parse(" <i>| "));
}
show(idPriorityLiness, SHOW_ID_FACTION_FLAGS, SHOW_PRIORITY_FACTION_FLAGS, "Flags", flagsDesc);
// POWER
double powerBoost = faction.getPowerBoost();
String boost = (powerBoost == 0.0) ? "" : (powerBoost > 0.0 ? " (bonus: " : " (penalty: ") + powerBoost + ")";
String powerDesc = Txt.parse("%d/%d/%d%s", faction.getLandCount(), faction.getPowerRounded(), faction.getPowerMaxRounded(), boost);
show(idPriorityLiness, SHOW_ID_FACTION_POWER, SHOW_PRIORITY_FACTION_POWER, "Land / Power / Maxpower", powerDesc);
// SECTION: ECON
if (Econ.isEnabled()) {
// LANDVALUES
List<String> landvalueLines = new LinkedList<>();
long landCount = faction.getLandCount();
for (EventFactionsChunkChangeType type : EventFactionsChunkChangeType.values()) {
Double money = MConf.get().econChunkCost.get(type);
if (money == null) {
continue;
}
if (money == 0) {
continue;
}
money *= landCount;
String word = "Cost";
if (money <= 0) {
word = "Reward";
money *= -1;
}
String key = Txt.parse("Total Land %s %s", type.toString().toLowerCase(), word);
String value = Txt.parse("<h>%s", Money.format(money));
String line = show(key, value);
landvalueLines.add(line);
}
idPriorityLiness.put(SHOW_ID_FACTION_LANDVALUES, new PriorityLines(SHOW_PRIORITY_FACTION_LANDVALUES, landvalueLines));
// BANK
if (MConf.get().bankEnabled) {
double bank = Econ.getMoney(faction);
String bankDesc = Txt.parse("<h>%s", Money.format(bank, true));
show(idPriorityLiness, SHOW_ID_FACTION_BANK, SHOW_PRIORITY_FACTION_BANK, "Bank", bankDesc);
}
}
}
// FOLLOWERS
List<String> followerLines = new ArrayList<>();
List<String> followerNamesOnline = new ArrayList<>();
List<String> followerNamesOffline = new ArrayList<>();
List<MPlayer> followers = faction.getMPlayers();
followers.sort(ComparatorMPlayerRole.get());
for (MPlayer follower : followers) {
if (follower.isOnline(sender)) {
followerNamesOnline.add(follower.getNameAndTitle(mplayer));
} else if (normal) {
// For the non-faction we skip the offline members since they are far to many (infinite almost)
followerNamesOffline.add(follower.getNameAndTitle(mplayer));
}
}
String headerOnline = Txt.parse("<a>Followers Online (%s):", followerNamesOnline.size());
followerLines.add(headerOnline);
if (followerNamesOnline.isEmpty()) {
followerLines.add(none);
} else {
followerLines.addAll(table(followerNamesOnline, tableCols));
}
if (normal) {
String headerOffline = Txt.parse("<a>Followers Offline (%s):", followerNamesOffline.size());
followerLines.add(headerOffline);
if (followerNamesOffline.isEmpty()) {
followerLines.add(none);
} else {
followerLines.addAll(table(followerNamesOffline, tableCols));
}
}
idPriorityLiness.put(SHOW_ID_FACTION_FOLLOWERS, new PriorityLines(SHOW_PRIORITY_FACTION_FOLLOWERS, followerLines));
}
public static String show(String key, String value) {
return Txt.parse("<a>%s: <i>%s", key, value);
}
public static PriorityLines show(int priority, String key, String value) {
return new PriorityLines(priority, show(key, value));
}
public static void show(Map<String, PriorityLines> idPriorityLiness, String id, int priority, String key, String value) {
idPriorityLiness.put(id, show(priority, key, value));
}
public static List<String> table(List<String> strings, int cols) {
List<String> ret = new ArrayList<>();
StringBuilder row = new StringBuilder();
int count = 0;
Iterator<String> iter = strings.iterator();
while (iter.hasNext()) {
String string = iter.next();
row.append(string);
count++;
if (iter.hasNext() && count != cols) {
row.append(Txt.parse(" <i>| "));
} else {
ret.add(row.toString());
row = new StringBuilder();
count = 0;
}
}
return ret;
}
}

View File

@ -0,0 +1,108 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.Faction;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.factions.entity.Warp;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.util.MUtil;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerRespawnEvent;
import java.util.List;
public class EngineTeleportHomeOnDeath extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineTeleportHomeOnDeath i = new EngineTeleportHomeOnDeath();
public static EngineTeleportHomeOnDeath get() {
return i;
}
// -------------------------------------------- //
// TELEPORT TO HOME ON DEATH
// -------------------------------------------- //
public void teleportToHomeOnDeath(PlayerRespawnEvent event, EventPriority priority) {
// If a player is respawning ...
final Player player = event.getPlayer();
if (MUtil.isntPlayer(player)) {
return;
}
final MPlayer mplayer = MPlayer.get(player);
// ... homes are enabled, active and at this priority ...
if (!MConf.get().warpsEnabled) {
return;
}
if (!MConf.get().warpsTeleportToOnDeathActive) {
return;
}
if (MConf.get().warpsTeleportToOnDeathPriority != priority) {
return;
}
// ... and the player has a faction ...
final Faction faction = mplayer.getFaction();
if (faction.isNone()) {
return;
}
// ... and the faction has a home ...
List<Warp> warps = faction.getWarps().getAll((java.util.function.Predicate<Warp>) (warp -> warp.getName().equalsIgnoreCase(MConf.get().warpsTeleportToOnDeathName)));
if (warps.isEmpty()) {
return;
}
Warp warp = warps.get(0);
// ... and the home is translatable ...
Location respawnLocation = null;
try {
respawnLocation = warp.getLocation().asBukkitLocation(true);
} catch (Exception e) {
// The home location map may have been deleted
return;
}
// ... then use it for the respawn location.
event.setRespawnLocation(respawnLocation);
}
@EventHandler(priority = EventPriority.LOWEST)
public void teleportToHomeOnDeathLowest(PlayerRespawnEvent event) {
this.teleportToHomeOnDeath(event, EventPriority.LOWEST);
}
@EventHandler(priority = EventPriority.LOW)
public void teleportToHomeOnDeathLow(PlayerRespawnEvent event) {
this.teleportToHomeOnDeath(event, EventPriority.LOW);
}
@EventHandler(priority = EventPriority.NORMAL)
public void teleportToHomeOnDeathNormal(PlayerRespawnEvent event) {
this.teleportToHomeOnDeath(event, EventPriority.NORMAL);
}
@EventHandler(priority = EventPriority.HIGH)
public void teleportToHomeOnDeathHigh(PlayerRespawnEvent event) {
this.teleportToHomeOnDeath(event, EventPriority.HIGH);
}
@EventHandler(priority = EventPriority.HIGHEST)
public void teleportToHomeOnDeathHighest(PlayerRespawnEvent event) {
this.teleportToHomeOnDeath(event, EventPriority.HIGHEST);
}
@EventHandler(priority = EventPriority.MONITOR)
public void teleportToHomeOnDeathMonitor(PlayerRespawnEvent event) {
this.teleportToHomeOnDeath(event, EventPriority.MONITOR);
}
}

View File

@ -0,0 +1,70 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.MConf;
import com.massivecraft.factions.entity.MPlayer;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.util.MUtil;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.entity.EntityDamageByEntityEvent;
import java.text.MessageFormat;
public class EngineTerritoryShield extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineTerritoryShield i = new EngineTerritoryShield();
public static EngineTerritoryShield get() {
return i;
}
// -------------------------------------------- //
// TERRITORY SHIELD
// -------------------------------------------- //
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void territoryShield(EntityDamageByEntityEvent event) {
// If the entity is a player ...
Entity entity = event.getEntity();
if (MUtil.isntPlayer(entity)) {
return;
}
Player player = (Player) entity;
MPlayer mplayer = MPlayer.get(player);
// ... and the attacker is a player ...
Entity attacker = MUtil.getLiableDamager(event);
if (!(attacker instanceof Player)) {
return;
}
// ... and that player has a faction ...
if (!mplayer.hasFaction()) {
return;
}
// ... and that player is in their own territory ...
if (!mplayer.isInOwnTerritory()) {
return;
}
// ... and a territoryShieldFactor is configured ...
if (MConf.get().territoryShieldFactor <= 0) {
return;
}
// ... then scale the damage ...
double factor = 1D - MConf.get().territoryShieldFactor;
MUtil.scaleDamage(event, factor);
// ... and inform.
String perc = MessageFormat.format("{0,number,#%}", (MConf.get().territoryShieldFactor));
mplayer.msg("<i>Enemy damage reduced by <rose>%s<i>.", perc);
}
}

View File

@ -0,0 +1,34 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.util.VisualizeUtil;
import com.massivecraft.massivecore.Engine;
import com.massivecraft.massivecore.util.MUtil;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.player.PlayerMoveEvent;
public class EngineVisualizations extends Engine {
// -------------------------------------------- //
// INSTANCE & CONSTRUCT
// -------------------------------------------- //
private static EngineVisualizations i = new EngineVisualizations();
public static EngineVisualizations get() {
return i;
}
// -------------------------------------------- //
// VISUALIZE UTIL
// -------------------------------------------- //
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onPlayerMoveClearVisualizations(PlayerMoveEvent event) {
if (MUtil.isSameBlock(event)) {
return;
}
VisualizeUtil.clear(event.getPlayer());
}
}

View File

@ -0,0 +1,79 @@
package com.massivecraft.factions.engine;
import com.massivecraft.factions.entity.MPerm;
import com.massivecraft.factions.util.EnumerationUtil;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
public enum ProtectCase {
// -------------------------------------------- //
// ENUM
// -------------------------------------------- //
BUILD,
USE_BLOCK,
USE_ITEM,
USE_ENTITY,
// END OF LIST
;
// -------------------------------------------- //
// PERM
// -------------------------------------------- //
public MPerm getPerm(Object object) {
switch (this) {
case BUILD:
return MPerm.getPermBuild();
case USE_ITEM:
if (!(object instanceof Material)) {
return null;
}
if (!EnumerationUtil.isMaterialEditTool((Material) object)) {
return null;
}
return MPerm.getPermBuild();
case USE_ENTITY:
if (!(object instanceof Entity)) {
return null;
}
Entity entity = (Entity) object;
EntityType type = entity.getType();
if (EnumerationUtil.isEntityTypeContainer(type)) {
return MPerm.getPermContainer();
}
if (EnumerationUtil.isEntityTypeEditOnInteract(type)) {
return MPerm.getPermBuild();
}
case USE_BLOCK:
if (!(object instanceof Material)) {
return null;
}
Material material = (Material) object;
if (EnumerationUtil.isMaterialEditOnInteract(material)) {
return MPerm.getPermBuild();
}
if (EnumerationUtil.isMaterialContainer(material)) {
return MPerm.getPermContainer();
}
if (EnumerationUtil.isMaterialDoor(material)) {
return MPerm.getPermDoor();
}
if (material == Material.STONE_BUTTON) {
return MPerm.getPermButton();
}
if (material == Material.LEVER) {
return MPerm.getPermLever();
}
default:
return null;
}
}
}