Added /SoftMute
This commit is contained in:
parent
5865dc354b
commit
9c1094b95b
10
plugin.yml
10
plugin.yml
|
|
@ -129,6 +129,10 @@ commands:
|
||||||
claimexplosions:
|
claimexplosions:
|
||||||
description: Toggles whether explosives may be used in a specific land claim.
|
description: Toggles whether explosives may be used in a specific land claim.
|
||||||
usage: /ClaimExplosions
|
usage: /ClaimExplosions
|
||||||
|
softmute:
|
||||||
|
description: Toggles whether a player's messages will only reach other soft-muted players.
|
||||||
|
usage: /SoftMute <player>
|
||||||
|
permission: griefprevention.softmute
|
||||||
permissions:
|
permissions:
|
||||||
griefprevention.createclaims:
|
griefprevention.createclaims:
|
||||||
description: Grants permission to create claims.
|
description: Grants permission to create claims.
|
||||||
|
|
@ -146,6 +150,7 @@ permissions:
|
||||||
griefprevention.lava: true
|
griefprevention.lava: true
|
||||||
griefprevention.eavesdrop: true
|
griefprevention.eavesdrop: true
|
||||||
griefprevention.deathblow: true
|
griefprevention.deathblow: true
|
||||||
|
griefprevention.softmute: true
|
||||||
griefprevention.restorenature:
|
griefprevention.restorenature:
|
||||||
description: Grants permission to use /RestoreNature.
|
description: Grants permission to use /RestoreNature.
|
||||||
default: op
|
default: op
|
||||||
|
|
@ -168,7 +173,7 @@ permissions:
|
||||||
description: Grants permission to place lava near the surface and outside of claims.
|
description: Grants permission to place lava near the surface and outside of claims.
|
||||||
default: op
|
default: op
|
||||||
griefprevention.eavesdrop:
|
griefprevention.eavesdrop:
|
||||||
description: Allows a player to see whispered chat messages (/tell).
|
description: Allows a player to see whispered chat messages (/tell) and softmuted messages.
|
||||||
default: op
|
default: op
|
||||||
griefprevention.restorenatureaggressive:
|
griefprevention.restorenatureaggressive:
|
||||||
description: Grants access to /RestoreNatureAggressive and /RestoreNatureFill.
|
description: Grants access to /RestoreNatureAggressive and /RestoreNatureFill.
|
||||||
|
|
@ -176,6 +181,9 @@ permissions:
|
||||||
griefprevention.deathblow:
|
griefprevention.deathblow:
|
||||||
description: Grants access to /DeathBlow.
|
description: Grants access to /DeathBlow.
|
||||||
default: op
|
default: op
|
||||||
|
griefprevention.softmute:
|
||||||
|
description: Grants access to /SoftMute.
|
||||||
|
default: op
|
||||||
griefprevention.claims:
|
griefprevention.claims:
|
||||||
description: Grants access to claim-related slash commands.
|
description: Grants access to claim-related slash commands.
|
||||||
default: true
|
default: true
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ public abstract class DataStore
|
||||||
protected final static String dataLayerFolderPath = "plugins" + File.separator + "GriefPreventionData";
|
protected final static String dataLayerFolderPath = "plugins" + File.separator + "GriefPreventionData";
|
||||||
final static String configFilePath = dataLayerFolderPath + File.separator + "config.yml";
|
final static String configFilePath = dataLayerFolderPath + File.separator + "config.yml";
|
||||||
final static String messagesFilePath = dataLayerFolderPath + File.separator + "messages.yml";
|
final static String messagesFilePath = dataLayerFolderPath + File.separator + "messages.yml";
|
||||||
|
final static String softMuteFilePath = dataLayerFolderPath + File.separator + "softMute.txt";
|
||||||
|
|
||||||
//the latest version of the data schema implemented here
|
//the latest version of the data schema implemented here
|
||||||
protected static final int latestSchemaVersion = 1;
|
protected static final int latestSchemaVersion = 1;
|
||||||
|
|
@ -71,6 +72,9 @@ public abstract class DataStore
|
||||||
static final String CREATIVE_VIDEO_URL = "http://bit.ly/mcgpcrea";
|
static final String CREATIVE_VIDEO_URL = "http://bit.ly/mcgpcrea";
|
||||||
static final String SUBDIVISION_VIDEO_URL = "http://bit.ly/mcgpsub";
|
static final String SUBDIVISION_VIDEO_URL = "http://bit.ly/mcgpsub";
|
||||||
|
|
||||||
|
//list of UUIDs which are soft-muted
|
||||||
|
ConcurrentHashMap<UUID, Boolean> softMuteMap = new ConcurrentHashMap<UUID, Boolean>();
|
||||||
|
|
||||||
protected int getSchemaVersion()
|
protected int getSchemaVersion()
|
||||||
{
|
{
|
||||||
if(this.currentSchemaVersion >= 0)
|
if(this.currentSchemaVersion >= 0)
|
||||||
|
|
@ -118,11 +122,124 @@ public abstract class DataStore
|
||||||
GriefPrevention.AddLogEntry("Update finished.");
|
GriefPrevention.AddLogEntry("Update finished.");
|
||||||
}
|
}
|
||||||
|
|
||||||
//make a note of the data store schema version
|
//load list of soft mutes
|
||||||
|
this.loadSoftMutes();
|
||||||
|
|
||||||
|
//make a note of the data store schema version
|
||||||
this.setSchemaVersion(latestSchemaVersion);
|
this.setSchemaVersion(latestSchemaVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
//removes cached player data from memory
|
private void loadSoftMutes()
|
||||||
|
{
|
||||||
|
File softMuteFile = new File(softMuteFilePath);
|
||||||
|
if(softMuteFile.exists())
|
||||||
|
{
|
||||||
|
BufferedReader inStream = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//open the file
|
||||||
|
inStream = new BufferedReader(new FileReader(softMuteFile.getAbsolutePath()));
|
||||||
|
|
||||||
|
//while there are lines left
|
||||||
|
String nextID = inStream.readLine();
|
||||||
|
while(nextID != null)
|
||||||
|
{
|
||||||
|
//parse line into a UUID
|
||||||
|
UUID playerID;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
playerID = UUID.fromString(nextID);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
playerID = null;
|
||||||
|
GriefPrevention.AddLogEntry("Failed to parse soft mute entry as a UUID: " + nextID);
|
||||||
|
}
|
||||||
|
|
||||||
|
//push it into the map
|
||||||
|
if(playerID != null)
|
||||||
|
{
|
||||||
|
this.softMuteMap.put(playerID, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//move to the next
|
||||||
|
nextID = inStream.readLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
GriefPrevention.AddLogEntry("Failed to read from the soft mute data file: " + e.toString());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(inStream != null) inStream.close();
|
||||||
|
}
|
||||||
|
catch(IOException exception) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//updates soft mute map and data file
|
||||||
|
boolean toggleSoftMute(UUID playerID)
|
||||||
|
{
|
||||||
|
boolean newValue = !this.isSoftMuted(playerID);
|
||||||
|
|
||||||
|
this.softMuteMap.put(playerID, newValue);
|
||||||
|
this.saveSoftMutes();
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isSoftMuted(UUID playerID)
|
||||||
|
{
|
||||||
|
Boolean mapEntry = this.softMuteMap.get(playerID);
|
||||||
|
if(mapEntry == null || mapEntry == Boolean.FALSE)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void saveSoftMutes()
|
||||||
|
{
|
||||||
|
BufferedWriter outStream = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//open the file and write the new value
|
||||||
|
File softMuteFile = new File(softMuteFilePath);
|
||||||
|
softMuteFile.createNewFile();
|
||||||
|
outStream = new BufferedWriter(new FileWriter(softMuteFile));
|
||||||
|
|
||||||
|
for(Map.Entry<UUID, Boolean> entry : softMuteMap.entrySet())
|
||||||
|
{
|
||||||
|
if(entry.getValue().booleanValue())
|
||||||
|
{
|
||||||
|
outStream.write(entry.getKey().toString());
|
||||||
|
outStream.newLine();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
//if any problem, log it
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
GriefPrevention.AddLogEntry("Unexpected exception saving soft mute data: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
//close the file
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(outStream != null) outStream.close();
|
||||||
|
}
|
||||||
|
catch(IOException exception) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
//removes cached player data from memory
|
||||||
synchronized void clearCachedPlayerData(UUID playerID)
|
synchronized void clearCachedPlayerData(UUID playerID)
|
||||||
{
|
{
|
||||||
this.playerNameToPlayerDataMap.remove(playerID);
|
this.playerNameToPlayerDataMap.remove(playerID);
|
||||||
|
|
@ -557,13 +674,15 @@ public abstract class DataStore
|
||||||
//saves changes to player data to secondary storage. MUST be called after you're done making changes, otherwise a reload will lose them
|
//saves changes to player data to secondary storage. MUST be called after you're done making changes, otherwise a reload will lose them
|
||||||
public void savePlayerDataSync(UUID playerID, PlayerData playerData)
|
public void savePlayerDataSync(UUID playerID, PlayerData playerData)
|
||||||
{
|
{
|
||||||
|
//ensure player data is already read from file before trying to save
|
||||||
|
playerData.getAccruedClaimBlocks();
|
||||||
|
playerData.getClaims();
|
||||||
this.asyncSavePlayerData(playerID, playerData);
|
this.asyncSavePlayerData(playerID, playerData);
|
||||||
}
|
}
|
||||||
|
|
||||||
//saves changes to player data to secondary storage. MUST be called after you're done making changes, otherwise a reload will lose them
|
//saves changes to player data to secondary storage. MUST be called after you're done making changes, otherwise a reload will lose them
|
||||||
public void savePlayerData(UUID playerID, PlayerData playerData)
|
public void savePlayerData(UUID playerID, PlayerData playerData)
|
||||||
{
|
{
|
||||||
//thread won't have access to read from files (silent failure - all readlines() return null)
|
|
||||||
//ensure player data is already read from file before trying to save
|
//ensure player data is already read from file before trying to save
|
||||||
playerData.getAccruedClaimBlocks();
|
playerData.getAccruedClaimBlocks();
|
||||||
playerData.getClaims();
|
playerData.getClaims();
|
||||||
|
|
@ -1048,6 +1167,8 @@ public abstract class DataStore
|
||||||
this.addDefault(defaults, Messages.ClaimExplosivesAdvertisement, "To allow explosives to destroy blocks in this land claim, use /ClaimExplosions.", null);
|
this.addDefault(defaults, Messages.ClaimExplosivesAdvertisement, "To allow explosives to destroy blocks in this land claim, use /ClaimExplosions.", null);
|
||||||
this.addDefault(defaults, Messages.PlayerInPvPSafeZone, "That player is in a PvP safe zone.", null);
|
this.addDefault(defaults, Messages.PlayerInPvPSafeZone, "That player is in a PvP safe zone.", null);
|
||||||
this.addDefault(defaults, Messages.NoPistonsOutsideClaims, "Warning: Pistons won't move blocks outside land claims.", null);
|
this.addDefault(defaults, Messages.NoPistonsOutsideClaims, "Warning: Pistons won't move blocks outside land claims.", null);
|
||||||
|
this.addDefault(defaults, Messages.SoftMuted, "Soft-muted {0}.", "The changed player's name.");
|
||||||
|
this.addDefault(defaults, Messages.UnSoftMuted, "Un-soft-muted {0}.", "The changed player's name.");
|
||||||
|
|
||||||
//load the config file
|
//load the config file
|
||||||
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath));
|
FileConfiguration config = YamlConfiguration.loadConfiguration(new File(messagesFilePath));
|
||||||
|
|
|
||||||
|
|
@ -1910,6 +1910,32 @@ public class GriefPrevention extends JavaPlugin
|
||||||
GriefPrevention.sendMessage(defender, TextMode.Warn, Messages.SiegeAlert, attacker.getName());
|
GriefPrevention.sendMessage(defender, TextMode.Warn, Messages.SiegeAlert, attacker.getName());
|
||||||
GriefPrevention.sendMessage(player, TextMode.Success, Messages.SiegeConfirmed, defender.getName());
|
GriefPrevention.sendMessage(player, TextMode.Success, Messages.SiegeConfirmed, defender.getName());
|
||||||
}
|
}
|
||||||
|
else if(cmd.getName().equalsIgnoreCase("softmute"))
|
||||||
|
{
|
||||||
|
//requires one parameter
|
||||||
|
if(args.length != 1) return false;
|
||||||
|
|
||||||
|
//find the specified player
|
||||||
|
OfflinePlayer targetPlayer = this.resolvePlayerByName(args[0], true);
|
||||||
|
if(targetPlayer == null)
|
||||||
|
{
|
||||||
|
GriefPrevention.sendMessage(player, TextMode.Err, Messages.PlayerNotFound);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//toggle mute for player
|
||||||
|
boolean isMuted = this.dataStore.toggleSoftMute(targetPlayer.getUniqueId());
|
||||||
|
if(isMuted)
|
||||||
|
{
|
||||||
|
GriefPrevention.sendMessage(player, TextMode.Success, Messages.SoftMuted, targetPlayer.getName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GriefPrevention.sendMessage(player, TextMode.Success, Messages.UnSoftMuted, targetPlayer.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,5 @@ package me.ryanhamshire.GriefPrevention;
|
||||||
|
|
||||||
public enum Messages
|
public enum Messages
|
||||||
{
|
{
|
||||||
RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionVideo, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, RescuePending, NonSiegeWorld, AlreadySieging, NotSiegableThere, SiegeTooFarAway, NoSiegeDefenseless, AlreadyUnderSiegePlayer, AlreadyUnderSiegeArea, NoSiegeAdminClaim, SiegeOnCooldown, SiegeAlert, SiegeConfirmed, AbandonClaimMissing, NotYourClaim, DeleteTopLevelClaim, AbandonSuccess, CantGrantThatPermission, GrantPermissionNoClaim, GrantPermissionConfirmation, ManageUniversalPermissionsInstruction, ManageOneClaimPermissionsInstruction, CollectivePublic, BuildPermission, ContainersPermission, AccessPermission, PermissionsPermission, LocationCurrentClaim, LocationAllClaims, PvPImmunityStart, SiegeNoDrop, DonateItemsInstruction, ChestFull, DonationSuccess, PlayerTooCloseForFire, TooDeepToClaim, ChestClaimConfirmation, AutomaticClaimNotification, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsVideo, SurvivalBasicsVideo, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeClaimTooSmall, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooSmall, CreateClaimInsufficientBlocks, AbandonClaimAdvertisement, CreateClaimFailOverlapShort, CreateClaimSuccess, SiegeWinDoorsOpen, RescueAbortedMoved, SiegeDoorsLockedEjection, NoModifyDuringSiege, OnlyOwnersModifyClaims, NoBuildUnderSiege, NoBuildPvP, NoBuildPermission, NonSiegeMaterial, NoOwnerBuildUnderSiege, NoAccessPermission, NoContainersSiege, NoContainersPermission, OwnerNameForAdminClaims, ClaimTooSmallForEntities, TooManyEntitiesInClaim, YouHaveNoClaims, ConfirmFluidRemoval, AutoBanNotify, AdjustGroupBlocksSuccess, InvalidPermissionID, UntrustOwnerOnly, HowToClaimRegex, NoBuildOutsideClaims, PlayerOfflineTime, BuildingOutsideClaims, TrappedWontWorkHere, CommandBannedInPvP, UnclaimCleanupWarning, BuySellNotConfigured, NoTeleportPvPCombat, NoTNTDamageAboveSeaLevel, NoTNTDamageClaims, IgnoreClaimsAdvertisement, NoPermissionForCommand, ClaimsListNoPermission, ExplosivesDisabled, ExplosivesEnabled, ClaimExplosivesAdvertisement, PlayerInPvPSafeZone, NoPistonsOutsideClaims
|
RespectingClaims, IgnoringClaims, SuccessfulAbandon, RestoreNatureActivate, RestoreNatureAggressiveActivate, FillModeActive, TransferClaimPermission, TransferClaimMissing, TransferClaimAdminOnly, PlayerNotFound, TransferTopLevel, TransferSuccess, TrustListNoClaim, ClearPermsOwnerOnly, UntrustIndividualAllClaims, UntrustEveryoneAllClaims, NoPermissionTrust, ClearPermissionsOneClaim, UntrustIndividualSingleClaim, OnlySellBlocks, BlockPurchaseCost, ClaimBlockLimit, InsufficientFunds, PurchaseConfirmation, OnlyPurchaseBlocks, BlockSaleValue, NotEnoughBlocksForSale, BlockSaleConfirmation, AdminClaimsMode, BasicClaimsMode, SubdivisionMode, SubdivisionVideo, DeleteClaimMissing, DeletionSubdivisionWarning, DeleteSuccess, CantDeleteAdminClaim, DeleteAllSuccess, NoDeletePermission, AllAdminDeleted, AdjustBlocksSuccess, NotTrappedHere, RescuePending, NonSiegeWorld, AlreadySieging, NotSiegableThere, SiegeTooFarAway, NoSiegeDefenseless, AlreadyUnderSiegePlayer, AlreadyUnderSiegeArea, NoSiegeAdminClaim, SiegeOnCooldown, SiegeAlert, SiegeConfirmed, AbandonClaimMissing, NotYourClaim, DeleteTopLevelClaim, AbandonSuccess, CantGrantThatPermission, GrantPermissionNoClaim, GrantPermissionConfirmation, ManageUniversalPermissionsInstruction, ManageOneClaimPermissionsInstruction, CollectivePublic, BuildPermission, ContainersPermission, AccessPermission, PermissionsPermission, LocationCurrentClaim, LocationAllClaims, PvPImmunityStart, SiegeNoDrop, DonateItemsInstruction, ChestFull, DonationSuccess, PlayerTooCloseForFire, TooDeepToClaim, ChestClaimConfirmation, AutomaticClaimNotification, UnprotectedChestWarning, ThatPlayerPvPImmune, CantFightWhileImmune, NoDamageClaimedEntity, ShovelBasicClaimMode, RemainingBlocks, CreativeBasicsVideo, SurvivalBasicsVideo, TrappedChatKeyword, TrappedInstructions, PvPNoDrop, SiegeNoTeleport, BesiegedNoTeleport, SiegeNoContainers, PvPNoContainers, PvPImmunityEnd, NoBedPermission, NoWildernessBuckets, NoLavaNearOtherPlayer, TooFarAway, BlockNotClaimed, BlockClaimed, SiegeNoShovel, RestoreNaturePlayerInChunk, NoCreateClaimPermission, ResizeClaimTooSmall, ResizeNeedMoreBlocks, NoCreativeUnClaim, ClaimResizeSuccess, ResizeFailOverlap, ResizeStart, ResizeFailOverlapSubdivision, SubdivisionStart, CreateSubdivisionOverlap, SubdivisionSuccess, CreateClaimFailOverlap, CreateClaimFailOverlapOtherPlayer, ClaimsDisabledWorld, ClaimStart, NewClaimTooSmall, CreateClaimInsufficientBlocks, AbandonClaimAdvertisement, CreateClaimFailOverlapShort, CreateClaimSuccess, SiegeWinDoorsOpen, RescueAbortedMoved, SiegeDoorsLockedEjection, NoModifyDuringSiege, OnlyOwnersModifyClaims, NoBuildUnderSiege, NoBuildPvP, NoBuildPermission, NonSiegeMaterial, NoOwnerBuildUnderSiege, NoAccessPermission, NoContainersSiege, NoContainersPermission, OwnerNameForAdminClaims, ClaimTooSmallForEntities, TooManyEntitiesInClaim, YouHaveNoClaims, ConfirmFluidRemoval, AutoBanNotify, AdjustGroupBlocksSuccess, InvalidPermissionID, UntrustOwnerOnly, HowToClaimRegex, NoBuildOutsideClaims, PlayerOfflineTime, BuildingOutsideClaims, TrappedWontWorkHere, CommandBannedInPvP, UnclaimCleanupWarning, BuySellNotConfigured, NoTeleportPvPCombat, NoTNTDamageAboveSeaLevel, NoTNTDamageClaims, IgnoreClaimsAdvertisement, NoPermissionForCommand, ClaimsListNoPermission, ExplosivesDisabled, ExplosivesEnabled, ClaimExplosivesAdvertisement, PlayerInPvPSafeZone, NoPistonsOutsideClaims, SoftMuted, UnSoftMuted
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
|
|
@ -92,7 +93,34 @@ class PlayerEventHandler implements Listener
|
||||||
|
|
||||||
String message = event.getMessage();
|
String message = event.getMessage();
|
||||||
|
|
||||||
event.setCancelled(this.handlePlayerChat(player, message, event));
|
boolean muted = this.handlePlayerChat(player, message, event);
|
||||||
|
Set<Player> recipients = event.getRecipients();
|
||||||
|
|
||||||
|
//muted messages go out to only the sender
|
||||||
|
if(muted)
|
||||||
|
{
|
||||||
|
recipients.clear();
|
||||||
|
recipients.add(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
//soft muted messages go out to all soft muted players
|
||||||
|
else if(this.dataStore.isSoftMuted(player.getUniqueId()))
|
||||||
|
{
|
||||||
|
Set<Player> recipientsToKeep = new HashSet<Player>();
|
||||||
|
for(Player recipient : recipients)
|
||||||
|
{
|
||||||
|
if(this.dataStore.isSoftMuted(recipient.getUniqueId()))
|
||||||
|
{
|
||||||
|
recipientsToKeep.add(recipient);
|
||||||
|
}
|
||||||
|
else if(recipient.hasPermission("griefprevention.eavesdrop"))
|
||||||
|
{
|
||||||
|
recipient.sendMessage("(Muted)" + player.getName() + ": " + message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
recipients.clear();
|
||||||
|
recipients.addAll(recipientsToKeep);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//last chat message shown, regardless of who sent it
|
//last chat message shown, regardless of who sent it
|
||||||
|
|
@ -292,10 +320,6 @@ class PlayerEventHandler implements Listener
|
||||||
//make a log entry
|
//make a log entry
|
||||||
GriefPrevention.AddLogEntry("Muted spam from " + player.getName() + ": " + message);
|
GriefPrevention.AddLogEntry("Muted spam from " + player.getName() + ": " + message);
|
||||||
|
|
||||||
//send a fake message so the player doesn't realize he's muted
|
|
||||||
//less information for spammers = less effective spam filter dodging
|
|
||||||
player.sendMessage("<" + player.getName() + "> " + message);
|
|
||||||
|
|
||||||
//cancelling the event guarantees other players don't receive the message
|
//cancelling the event guarantees other players don't receive the message
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user