mirror of
				https://github.com/mcMMO-Dev/mcMMO.git
				synced 2025-11-04 02:53:43 +01:00 
			
		
		
		
	More work on reducing compiler errors
This commit is contained in:
		@@ -1,11 +1,11 @@
 | 
			
		||||
package com.gmail.nossr50.config;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.database.SQLDatabaseManager.PoolIdentifier;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.SuperAbilityType;
 | 
			
		||||
import com.gmail.nossr50.party.PartyFeature;
 | 
			
		||||
import com.gmail.nossr50.util.text.StringUtils;
 | 
			
		||||
import com.neetgames.mcmmo.MobHealthBarType;
 | 
			
		||||
import com.neetgames.mcmmo.database.PoolIdentifier;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.block.data.BlockData;
 | 
			
		||||
import org.bukkit.configuration.ConfigurationSection;
 | 
			
		||||
@@ -352,24 +352,16 @@ public class Config extends AutoUpdateConfigLoader {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* Hardcore Mode */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public boolean getHardcoreStatLossEnabled(PrimarySkillType primarySkillType) { return config.getBoolean("Hardcore.Death_Stat_Loss.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), false); }
 | 
			
		||||
    public boolean getHardcoreStatLossEnabled(@NotNull PrimarySkillType primarySkillType) { return config.getBoolean("Hardcore.Death_Stat_Loss.Enabled." + primarySkillType.getRawSkillName(), false); }
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public void setHardcoreStatLossEnabled(PrimarySkillType primarySkillType, boolean enabled) { config.set("Hardcore.Death_Stat_Loss.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), enabled); }
 | 
			
		||||
    public void setHardcoreStatLossEnabled(@NotNull PrimarySkillType primarySkillType, boolean enabled) { config.set("Hardcore.Death_Stat_Loss.Enabled." + primarySkillType.getRawSkillName(), enabled); }
 | 
			
		||||
 | 
			
		||||
    public double getHardcoreDeathStatPenaltyPercentage() { return config.getDouble("Hardcore.Death_Stat_Loss.Penalty_Percentage", 75.0D); }
 | 
			
		||||
    public void setHardcoreDeathStatPenaltyPercentage(double value) { config.set("Hardcore.Death_Stat_Loss.Penalty_Percentage", value); }
 | 
			
		||||
 | 
			
		||||
    public int getHardcoreDeathStatPenaltyLevelThreshold() { return config.getInt("Hardcore.Death_Stat_Loss.Level_Threshold", 0); }
 | 
			
		||||
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public boolean getHardcoreVampirismEnabled(PrimarySkillType primarySkillType) { return config.getBoolean("Hardcore.Vampirism.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), false); }
 | 
			
		||||
    public boolean getHardcoreVampirismEnabled(@NotNull PrimarySkillType primarySkillType) { return config.getBoolean("Hardcore.Vampirism.Enabled." + primarySkillType.getRawSkillName(), false); }
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public void setHardcoreVampirismEnabled(PrimarySkillType primarySkillType, boolean enabled) { config.set("Hardcore.Vampirism.Enabled." + StringUtils.getCapitalized(primarySkillType.toString()), enabled); }
 | 
			
		||||
    public void setHardcoreVampirismEnabled(@NotNull PrimarySkillType primarySkillType, boolean enabled) { config.set("Hardcore.Vampirism.Enabled." + primarySkillType.getRawSkillName(), enabled); }
 | 
			
		||||
 | 
			
		||||
    public double getHardcoreVampirismStatLeechPercentage() { return config.getDouble("Hardcore.Vampirism.Leech_Percentage", 5.0D); }
 | 
			
		||||
    public void setHardcoreVampirismStatLeechPercentage(double value) { config.set("Hardcore.Vampirism.Leech_Percentage", value); }
 | 
			
		||||
@@ -562,13 +554,6 @@ public class Config extends AutoUpdateConfigLoader {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getLevelCap(@NotNull PrimarySkillType primarySkillType) {
 | 
			
		||||
 | 
			
		||||
        int cap = config.getInt("Skills." + StringUtils.getCapitalized(primarySkillType.getRawSkillName()) + ".Level_Cap", 0);
 | 
			
		||||
        return (cap <= 0) ? Integer.MAX_VALUE : cap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getLevelCap(@NotNull PrimarySkillType primarySkillType) {
 | 
			
		||||
 | 
			
		||||
        int cap = config.getInt("Skills." + StringUtils.getCapitalized(primarySkillType.toString()) + ".Level_Cap", 0);
 | 
			
		||||
        return (cap <= 0) ? Integer.MAX_VALUE : cap;
 | 
			
		||||
    }
 | 
			
		||||
@@ -581,12 +566,8 @@ public class Config extends AutoUpdateConfigLoader {
 | 
			
		||||
    public boolean getTruncateSkills() { return config.getBoolean("General.TruncateSkills", false); }
 | 
			
		||||
 | 
			
		||||
    /* PVP & PVE Settings */
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public boolean getPVPEnabled(PrimarySkillType skill) { return config.getBoolean("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Enabled_For_PVP", true); }
 | 
			
		||||
    public boolean getPVPEnabled(PrimarySkillType skill) { return config.getBoolean("Skills." + skill.getRawSkillName() + ".Enabled_For_PVP", true); }
 | 
			
		||||
    @Deprecated
 | 
			
		||||
    public boolean getPVEEnabled(PrimarySkillType skill) { return config.getBoolean("Skills." + StringUtils.getCapitalized(skill.toString()) + ".Enabled_For_PVE", true); }
 | 
			
		||||
    public boolean getPVEEnabled(PrimarySkillType skill) { return config.getBoolean("Skills." + skill.getRawSkillName() + ".Enabled_For_PVE", true); }
 | 
			
		||||
 | 
			
		||||
    //public float getMasterVolume() { return (float) config.getDouble("Sounds.MasterVolume", 1.0); }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ import com.gmail.nossr50.util.Misc;
 | 
			
		||||
import com.gmail.nossr50.util.skills.SkillUtils;
 | 
			
		||||
import com.neetgames.mcmmo.MobHealthBarType;
 | 
			
		||||
import com.neetgames.mcmmo.UniqueDataType;
 | 
			
		||||
import com.neetgames.mcmmo.database.PoolIdentifier;
 | 
			
		||||
import com.neetgames.mcmmo.exceptions.InvalidSkillException;
 | 
			
		||||
import com.neetgames.mcmmo.skill.SkillBossBarState;
 | 
			
		||||
import org.apache.tomcat.jdbc.pool.DataSource;
 | 
			
		||||
@@ -635,17 +636,13 @@ public final class SQLDatabaseManager implements DatabaseManager {
 | 
			
		||||
 | 
			
		||||
    public @NotNull PlayerProfile loadPlayerProfile(@NotNull UUID uuid, @Nullable String playerName) {
 | 
			
		||||
        return loadPlayerFromDB(uuid, playerName);
 | 
			
		||||
    @Override
 | 
			
		||||
    public @Nullable PlayerData queryPlayerDataByPlayer(@NotNull Player player) throws ProfileRetrievalException, NullArgumentException {
 | 
			
		||||
        return loadPlayerProfile(player, player.getName(), player.getUniqueId());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private PlayerProfile loadPlayerFromDB(@Nullable UUID uuid, @Nullable String playerName) throws RuntimeException {
 | 
			
		||||
        if(uuid == null && playerName == null) {
 | 
			
		||||
            throw new RuntimeException("Error looking up player, both UUID and playerName are null and one must not be.");
 | 
			
		||||
        }
 | 
			
		||||
    @Override
 | 
			
		||||
    public @Nullable PlayerData queryPlayerDataByUUID(@NotNull UUID uuid, @NotNull String playerName) throws ProfileRetrievalException, NullArgumentException {
 | 
			
		||||
 | 
			
		||||
        return loadPlayerProfile(null, playerName, uuid);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,9 @@
 | 
			
		||||
package com.gmail.nossr50.datatypes.experience;
 | 
			
		||||
 | 
			
		||||
import com.neetgames.mcmmo.experience.ExperienceProcessor;
 | 
			
		||||
 | 
			
		||||
//TODO: T&C Write implementation, this should be the exact same way OnlineExperienceProcessor handles stuff but without sending player messages or sounds and stuff like that
 | 
			
		||||
//TODO: Is this needed? Maybe just make OnlineExperienceProcessor handle both in a clean way
 | 
			
		||||
public class OfflineExperienceProcessor {
 | 
			
		||||
public class OfflineExperienceProcessor implements ExperienceProcessor {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -16,6 +16,7 @@ import com.gmail.nossr50.util.skills.PerksUtils;
 | 
			
		||||
import com.gmail.nossr50.util.sounds.SoundManager;
 | 
			
		||||
import com.gmail.nossr50.util.sounds.SoundType;
 | 
			
		||||
import com.neetgames.mcmmo.exceptions.UnknownSkillException;
 | 
			
		||||
import com.neetgames.mcmmo.experience.ExperienceProcessor;
 | 
			
		||||
import com.neetgames.mcmmo.experience.XPGainReason;
 | 
			
		||||
import com.neetgames.mcmmo.experience.XPGainSource;
 | 
			
		||||
import com.neetgames.mcmmo.party.Party;
 | 
			
		||||
@@ -27,18 +28,16 @@ import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
public class OnlineExperienceProcessor {
 | 
			
		||||
public class OnlineExperienceProcessor implements ExperienceProcessor {
 | 
			
		||||
 | 
			
		||||
    private boolean isUsingUnarmed = false;
 | 
			
		||||
    private boolean isUsingUnarmed = false; //Gross but it works
 | 
			
		||||
 | 
			
		||||
    private final @NotNull PlayerData mmoPlayerData;
 | 
			
		||||
    private final @NotNull MMOPlayer mmoPlayer;
 | 
			
		||||
    private final @NotNull Player playerRef;
 | 
			
		||||
    private final @NotNull PlayerData mmoPlayerData;
 | 
			
		||||
 | 
			
		||||
    public OnlineExperienceProcessor(@NotNull MMOPlayer mmoPlayer, @NotNull Player playerRef) {
 | 
			
		||||
        this.mmoPlayer = mmoPlayer;
 | 
			
		||||
    public OnlineExperienceProcessor(@NotNull Player playerRef, @NotNull PlayerData playerData) {
 | 
			
		||||
        this.playerRef = playerRef;
 | 
			
		||||
        this.mmoPlayerData = mmoPlayer.getMMOPlayerDataImpl();
 | 
			
		||||
        this.mmoPlayerData = playerData;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getPowerLevel() {
 | 
			
		||||
@@ -58,7 +57,7 @@ public class OnlineExperienceProcessor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public int getSkillXpValue(@NotNull PrimarySkillType primarySkillType) {
 | 
			
		||||
        if(PrimarySkillType.isChildSkill(primarySkillType)) {
 | 
			
		||||
        if(primarySkillType.isChildSkill()) {
 | 
			
		||||
            return 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
@@ -66,7 +65,7 @@ public class OnlineExperienceProcessor {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void setSkillXpValue(@NotNull PrimarySkillType primarySkillType, float xpLevel) {
 | 
			
		||||
        if (PrimarySkillType.isChildSkill(primarySkillType)) {
 | 
			
		||||
        if (primarySkillType.isChildSkill()) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -6,13 +6,15 @@ import com.neetgames.mcmmo.experience.ExperienceProcessor;
 | 
			
		||||
import com.neetgames.mcmmo.player.MMOPlayer;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
 | 
			
		||||
public abstract class AbstractMMOPlayer implements MMOPlayer {
 | 
			
		||||
    /* All of the persistent data for a player that gets saved and loaded from DB */
 | 
			
		||||
    protected final @NotNull PlayerData mmoPlayerData; //All persistent data is kept here
 | 
			
		||||
    protected final @NotNull PlayerData playerData; //All persistent data is kept here
 | 
			
		||||
    protected @Nullable Player player = null;
 | 
			
		||||
 | 
			
		||||
    /* Managers */
 | 
			
		||||
    protected final @NotNull ExperienceProcessor experienceProcessor;
 | 
			
		||||
    protected final @Nullable ExperienceProcessor experienceProcessor;
 | 
			
		||||
    protected final @NotNull CooldownManager cooldownManager;
 | 
			
		||||
    protected boolean isLoaded;
 | 
			
		||||
 | 
			
		||||
@@ -20,25 +22,30 @@ public abstract class AbstractMMOPlayer implements MMOPlayer {
 | 
			
		||||
     * Init for online players
 | 
			
		||||
     * This will be used for existing data
 | 
			
		||||
     *
 | 
			
		||||
     * @param mmoPlayerData player data
 | 
			
		||||
     * @param playerData player data
 | 
			
		||||
     */
 | 
			
		||||
    public AbstractMMOPlayer(@NotNull Player player, @NotNull PlayerData mmoPlayerData, boolean isLoaded) {
 | 
			
		||||
        this.mmoPlayerData = mmoPlayerData;
 | 
			
		||||
        this.experienceProcessor = new OnlineExperienceProcessor(mmoPlayerData);
 | 
			
		||||
        this.cooldownManager = new CooldownManager(mmoPlayerData);
 | 
			
		||||
    public AbstractMMOPlayer(@Nullable Player player, @NotNull PlayerData playerData, boolean isLoaded) {
 | 
			
		||||
        this.playerData = playerData;
 | 
			
		||||
 | 
			
		||||
        if(player != null)
 | 
			
		||||
            this.player = player;
 | 
			
		||||
 | 
			
		||||
        this.isLoaded = isLoaded;
 | 
			
		||||
 | 
			
		||||
        if(isLoaded) {
 | 
			
		||||
            if(player != null && player.isOnline()) {
 | 
			
		||||
                //Online Player
 | 
			
		||||
                this.experienceProcessor = new OnlineExperienceProcessor(player, playerData);
 | 
			
		||||
            } else {
 | 
			
		||||
                //Offline Player
 | 
			
		||||
                this.experienceProcessor = new OfflineExperienceProcessor(player, playerData);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            //Invalid Player (no loaded data) so experience operations are pointless
 | 
			
		||||
            this.experienceProcessor = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Init for offline players
 | 
			
		||||
     *
 | 
			
		||||
     * @param mmoPlayerData player data
 | 
			
		||||
     */
 | 
			
		||||
    public AbstractMMOPlayer(@NotNull PlayerData mmoPlayerData, boolean isLoaded) {
 | 
			
		||||
        this.mmoPlayerData = mmoPlayerData;
 | 
			
		||||
        this.experienceProcessor = new OfflineExperienceProcessor(mmoPlayerData);
 | 
			
		||||
        this.cooldownManager = new CooldownManager(mmoPlayerData);
 | 
			
		||||
        this.isLoaded = isLoaded;
 | 
			
		||||
        this.cooldownManager = new CooldownManager(playerData);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public boolean isLoaded() {
 | 
			
		||||
 
 | 
			
		||||
@@ -96,9 +96,9 @@ public class McMMOPlayer extends PlayerProfile implements OnlineMMOPlayer, Ident
 | 
			
		||||
 | 
			
		||||
        this.player = player;
 | 
			
		||||
        playerMetadata = new FixedMetadataValue(mcMMO.p, player.getName());
 | 
			
		||||
        experienceBarManager = new MMOExperienceBarManager(this, mmoPlayerData.getBarStateMap());
 | 
			
		||||
        experienceBarManager = new MMOExperienceBarManager(this, playerData.getBarStateMap());
 | 
			
		||||
 | 
			
		||||
        superSkillManagerImpl = new SuperSkillManagerImpl(this, mmoPlayerData);
 | 
			
		||||
        superSkillManagerImpl = new SuperSkillManagerImpl(this, playerData);
 | 
			
		||||
        abilityActivationProcessor = new AbilityActivationProcessor(this);
 | 
			
		||||
 | 
			
		||||
        debugMode = false; //Debug mode helps solve support issues, players can toggle it on or off
 | 
			
		||||
@@ -149,7 +149,7 @@ public class McMMOPlayer extends PlayerProfile implements OnlineMMOPlayer, Ident
 | 
			
		||||
 | 
			
		||||
        superSkillManagerImpl = new SuperSkillManagerImpl(this, mmoPlayerData);
 | 
			
		||||
        abilityActivationProcessor = new AbilityActivationProcessor(this);
 | 
			
		||||
        experienceBarManager = new MMOExperienceBarManager(this, this.mmoPlayerData.getBarStateMap());
 | 
			
		||||
        experienceBarManager = new MMOExperienceBarManager(this, this.playerData.getBarStateMap());
 | 
			
		||||
 | 
			
		||||
        debugMode = false; //Debug mode helps solve support issues, players can toggle it on or off
 | 
			
		||||
 | 
			
		||||
@@ -180,7 +180,7 @@ public class McMMOPlayer extends PlayerProfile implements OnlineMMOPlayer, Ident
 | 
			
		||||
     * Update the last login to the current system time
 | 
			
		||||
     */
 | 
			
		||||
    private void updateLastLogin() {
 | 
			
		||||
        mmoPlayerData.setLastLogin(System.currentTimeMillis());
 | 
			
		||||
        playerData.setLastLogin(System.currentTimeMillis());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public @NotNull String getPlayerName() {
 | 
			
		||||
@@ -501,14 +501,14 @@ public class McMMOPlayer extends PlayerProfile implements OnlineMMOPlayer, Ident
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isChatSpying() {
 | 
			
		||||
        return mmoPlayerData.isPartyChatSpying();
 | 
			
		||||
        return playerData.isPartyChatSpying();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Toggle this player's party chat spying flag
 | 
			
		||||
     */
 | 
			
		||||
    public void togglePartyChatSpying() {
 | 
			
		||||
        mmoPlayerData.togglePartyChatSpying();
 | 
			
		||||
        playerData.togglePartyChatSpying();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -2,6 +2,7 @@ package com.gmail.nossr50.datatypes.player;
 | 
			
		||||
 | 
			
		||||
import com.gmail.nossr50.datatypes.skills.PrimarySkillType;
 | 
			
		||||
import com.neetgames.mcmmo.exceptions.UnknownSkillException;
 | 
			
		||||
import com.neetgames.mcmmo.experience.ExperienceProcessor;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
@@ -20,12 +21,12 @@ public class PlayerProfile extends AbstractMMOPlayer {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NotNull UUID getUUID() {
 | 
			
		||||
        return mmoPlayerData.getPlayerUUID();
 | 
			
		||||
        return playerData.getPlayerUUID();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NotNull String getPlayerName() {
 | 
			
		||||
        return mmoPlayerData.getPlayerName();
 | 
			
		||||
        return playerData.getPlayerName();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -58,12 +59,11 @@ public class PlayerProfile extends AbstractMMOPlayer {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NotNull ExperienceHandler getExperienceHandler() {
 | 
			
		||||
    public @NotNull ExperienceProcessor getExperienceHandler() {
 | 
			
		||||
        return experienceProcessor;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public @NotNull PlayerData getPlayerData() {
 | 
			
		||||
        return mmoPlayerData;
 | 
			
		||||
        return playerData;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ import com.gmail.nossr50.util.Permissions;
 | 
			
		||||
import com.gmail.nossr50.util.skills.RankUtils;
 | 
			
		||||
import com.gmail.nossr50.util.text.StringUtils;
 | 
			
		||||
import com.google.common.collect.ImmutableList;
 | 
			
		||||
import com.neetgames.mcmmo.skill.CorePrimarySkillType;
 | 
			
		||||
import org.bukkit.Color;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
 
 | 
			
		||||
@@ -88,11 +88,15 @@ public final class CommandUtils {
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        PlayerProfile profile = new PlayerProfile(playerName, false);
 | 
			
		||||
        //TODO: T&C - Ancient bug spotted, look at master for this method impl
 | 
			
		||||
        //TODO: T&C Check all code that invokes this method and see if we are handling things properly
 | 
			
		||||
        //TODO: T&C Likely don't need String playerName in the signature
 | 
			
		||||
 | 
			
		||||
        if (unloadedProfile(sender, profile)) {
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
//        PlayerProfile profile = new PlayerProfile(playerName, false);
 | 
			
		||||
//
 | 
			
		||||
//        if (unloadedProfile(sender, profile)) {
 | 
			
		||||
//            return false;
 | 
			
		||||
//        }
 | 
			
		||||
 | 
			
		||||
        sender.sendMessage(LocaleLoader.getString("Commands.DoesNotExist"));
 | 
			
		||||
        return false;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user