com.github.rolecraftdev.guild.GuildManager.java Source code

Java tutorial

Introduction

Here is the source code for com.github.rolecraftdev.guild.GuildManager.java

Source

/*
 * This file is part of RolecraftCore.
 *
 * Copyright (c) 2014 RolecraftDev <http://rolecraftdev.github.com>
 * RolecraftCore is licensed under the Creative Commons
 * Attribution-NonCommercial-NoDerivs 3.0 Unported License. To view a copy of this
 * license, visit http://creativecommons.org/licenses/by-nc-nd/3.0
 *
 * As long as you follow the following terms, you are free to copy and redistribute
 * the material in any medium or format.
 *
 * You must give appropriate credit, provide a link to the license, and indicate
 * whether any changes were made to the material. You may do so in any reasonable
 * manner, but not in any way which suggests the licensor endorses you or your use.
 *
 * You may not use the material for commercial purposes.
 *
 * If you remix, transform, or build upon the material, you may not distribute the
 * modified material.
 *
 * You may not apply legal terms or technological measures that legally restrict
 * others from doing anything the license permits.
 *
 * DISCLAIMER: This is a human-readable summary of (and not a substitute for) the
 * license.
 */
package com.github.rolecraftdev.guild;

import org.apache.commons.lang.Validate;

import com.github.rolecraftdev.RolecraftCore;
import com.github.rolecraftdev.data.storage.DataStore;
import com.github.rolecraftdev.data.storage.YamlFile;
import com.github.rolecraftdev.event.RolecraftEventFactory;
import com.github.rolecraftdev.event.guild.GuildCreateEvent;
import com.github.rolecraftdev.event.guild.GuildDisbandEvent;

import com.traksag.channels.Channel;
import com.traksag.channels.ChannelBatch;
import com.traksag.channels.DefaultChannelBatch;

import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.scheduler.BukkitRunnable;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

/**
 * A helper class for managing {@link Guild}s and global configurable options
 * affecting them.
 *
 * @since 0.0.5
 */
public final class GuildManager {
    /**
     * The key used for metadata for when a player has been invited to join a
     * {@link Guild}.
     *
     * @since 0.0.5
     */
    public static final String GUILD_INVITE_METADATA = "guild-invite";

    /**
     * A {@link Map} of human-readable names and their related
     * {@link GuildAction}.
     *
     * @since 0.0.5
     */
    static final Map<String, GuildAction> actionMap = new HashMap<String, GuildAction>();

    /**
     * The associated {@link RolecraftCore} instance.
     */
    private final RolecraftCore plugin;
    /**
     * The linked configuration file.
     */
    private final YamlFile guildConfig;
    /**
     * The {@link ChannelBatch} that manages all {@link Channel}s for the
     * {@link Guild}s.
     */
    // DefaultChannelBatch ensures thread-safety for AsyncPlayerChatEvent
    private final ChannelBatch channelBatch = new DefaultChannelBatch();
    /**
     * All available {@link Guild}s.
     */
    private final Set<Guild> guilds;

    /**
     * Whether the data is wholly loaded.
     */
    private volatile boolean loaded;

    // Config options

    /**
     * Protect guild-halls from the environment and hostile mobs.
     */
    private final boolean protectFromEnvironment;
    /**
     * Disallow PvP in guild-halls.
     */
    private final boolean disallowHallPvp;
    /**
     * Whether to disallow block-breaks for people without guild permissions in
     * a guild hall.
     */
    private final boolean hallAntiGrief;
    /**
     * Whether to prevent piston usage in guild halls.
     */
    private final boolean hallNoPistons;

    /**
     * The price for making a new {@link Guild}.
     */
    private int creationCost;
    /**
     * The price for inviting a player to a {@link Guild}.
     */
    private int inviteCost;
    /**
     * The price for a guild-hall, which essentially is a protected area.
     */
    private int hallCost;

    /**
     * Create a new {@link GuildManager} and load the guild.yml file from the
     * given plugin's folder, or create it when nonexistent, from which the
     * configuration options will be loaded. Furthermore, this will also invoke
     * {@link DataStore#loadGuilds(GuildManager)} when all data has been loaded
     * from the used database. Registers a new {@link GuildListener}
     * automatically as well.
     *
     * @param plugin the associated {@link RolecraftCore} instance
     * @since 0.0.5
     */
    public GuildManager(final RolecraftCore plugin) {
        this.plugin = plugin;

        guilds = new HashSet<Guild>();

        // Get guild configuration options
        guildConfig = new YamlFile(plugin, "guilds.yml", false);
        creationCost = guildConfig.getInt("economy.creation-cost", 0);
        inviteCost = guildConfig.getInt("economy.invite-cost", 0);
        hallCost = guildConfig.getInt("economy.guild-hall-cost", 0);
        protectFromEnvironment = guildConfig.getBoolean("hall.protect-from-environment", true);
        disallowHallPvp = guildConfig.getBoolean("hall.disallow-pvp", true);
        hallAntiGrief = guildConfig.getBoolean("hall.anti-grief", true);
        hallNoPistons = guildConfig.getBoolean("hall.no-pistons", false);

        loaded = false;

        /*
         * Load all guilds, protection from SQL errors by not querying a table
         * that does not exist
         */
        if (plugin.isSqlLoaded()) {
            plugin.getDataStore().loadGuilds(this);
        } else {
            final GuildManager callback = this;
            new BukkitRunnable() {
                @Override
                public void run() {
                    if (plugin.isSqlLoaded()) {
                        cancel();
                        plugin.getDataStore().loadGuilds(callback);
                    }
                }
            }.runTaskTimer(plugin, 1, 5);
        }

        // Register the guild listener with Bukkit
        Bukkit.getPluginManager().registerEvents(new GuildListener(this), plugin);
    }

    /**
     * Get the {@link ChannelBatch} that is used for handling the
     * {@link Channel}s of the {@link Guild}s.
     *
     * @return the used {@link ChannelBatch}
     * @since 0.0.5
     */
    public ChannelBatch getChannelBatch() {
        return channelBatch;
    }

    /**
     * Get the linked {@link YamlFile} that is used for global {@link Guild}
     * configuration.
     *
     * @return the linked {@link YamlFile}
     * @since 0.0.5
     */
    public YamlFile getGuildConfig() {
        return guildConfig;
    }

    /**
     * Add the given {@link Guild} to this {@link GuildManager}. The new
     * {@link Guild} cannot be added when its name equals, ignoring case, the
     * name of another {@link Guild} in this {@link GuildManager}. This will
     * also call a new {@link GuildCreateEvent} and continue upon its final
     * status. Note that adding a {@link Guild} from DAOs will avoid the
     * aforementioned statements.
     *
     * @param guild the {@link Guild} that will be added
     * @param fromDatabase whether the specified {@link Guild} is added by a
     *        DAO, or in other words, for initialisation
     * @return {@code true} if the {@link Guild} is added; {@code false}
     *         otherwise
     * @since 0.0.5
     */
    public boolean addGuild(@Nonnull final Guild guild, final boolean fromDatabase) {
        // If a Guild is constructed with a null GuildManager, every getter
        // method will return null - make sure there isn't a 'null' guild given
        final String name = guild.getName();
        Validate.notNull(name);

        if (fromDatabase) {
            guilds.add(guild);
            channelBatch.addChannel(guild.getChannel());
            return true;
        }

        for (final Guild cur : guilds) {
            if (name.equalsIgnoreCase(cur.getName())) {
                Bukkit.getPlayer(guild.getLeader())
                        .sendMessage(ChatColor.DARK_RED + "A guild by that name already exists!");
                return false;
            }
        }

        final GuildCreateEvent event = RolecraftEventFactory.guildCreated(guild);
        if (event.isCancelled()) {
            event.getFounder().sendMessage(ChatColor.DARK_RED + event.getCancelMessage());
            return false;
        } else {
            guilds.add(guild);
            channelBatch.addChannel(guild.getChannel());
            plugin.getDataStore().createGuild(guild);
            return true;
        }
    }

    /**
     * Deletes the specified {@link Guild} when this is fully loaded. Gets rid
     * of all the {@link Guild}'s associated properties that are stored within
     * this {@link GuildManager} and calls a new {@link GuildDisbandEvent}.
     *
     * @param guild the {@link Guild} to remove
     * @return only {@code true} if the {@link Guild} has truly been removed
     * @since 0.0.5
     */
    public boolean removeGuild(@Nonnull final Guild guild) {
        if (loaded) {
            RolecraftEventFactory.guildDisbanded(guild);
            plugin.getDataStore().deleteGuild(guild);
            channelBatch.removeChannel(guild.getChannel());
            return guilds.remove(guild);
        } else {
            return false;
        }
    }

    /**
     * Retrieve the registered {@link Guild} with the specified name. Note that
     * {@code null} will automatically be returned when this isn't loaded.
     *
     * @param name the name of the wanted {@link Guild}
     * @return the {@link Guild} with the given name
     * @since 0.0.5
     */
    @Nullable
    public Guild getGuild(@Nonnull final String name) {
        Validate.notNull(name);
        if (loaded) {
            for (final Guild guild : guilds) {
                if (name.equalsIgnoreCase(guild.getName())) {
                    return guild;
                }
            }
        }
        return null;
    }

    /**
     * Retrieve the registered {@link Guild} with the specified {@link UUID}.
     * Note that {@code null} will automatically be returned when this isn't
     * loaded.
     *
     * @param uuid the {@link UUID} of the wanted {@link Guild}
     * @return the {@link Guild} with the given {@link UUID}
     * @since 0.0.5
     */
    @Nullable
    public Guild getGuild(final UUID uuid) {
        Validate.notNull(uuid);
        if (loaded) {
            for (final Guild guild : guilds) {
                if (uuid.equals(guild.getId())) {
                    return guild;
                }
            }
        }
        return null;
    }

    /**
     * Retrieve the registered {@link Guild} in which the given player is. Note
     * that {@code null} will automatically be returned when this isn't loaded.
     *
     * @param player the {@link UUID} of the player of which the {@link Guild}
     *        is wanted
     * @return the {@link Guild} of the given player
     * @since 0.0.5
     */
    @Nullable
    public Guild getPlayerGuild(@Nonnull final UUID player) {
        Validate.notNull(player);
        if (loaded) {
            for (final Guild guild : guilds) {
                if (guild.isMember(player)) {
                    return guild;
                }
            }
        }
        return null;
    }

    /**
     * Get all registered {@link Guild}s in this {@link GuildManager}. Note that
     * {@code null} will automatically be returned when this isn't loaded.
     *
     * @return all available {@link Guild}s
     * @since 0.0.5
     */
    @Nullable
    public Set<Guild> getGuilds() {
        if (loaded) {
            return new HashSet<Guild>(guilds);
        }
        return null;
    }

    /**
     * Obtain the price for creating a new {@link Guild}.
     *
     * @return the {@link Guild} creation price
     * @since 0.0.5
     */
    public int getCreationCost() {
        return creationCost;
    }

    /**
     * Get the price for inviting a player to a {@link Guild}.
     *
     * @return the {@link Guild} invitation price
     * @since 0.0.5
     */
    public int getInvitationCost() {
        return inviteCost;
    }

    /**
     * Get the price for a guild-hall.
     *
     * @return the guild-hall price
     * @since 0.0.5
     */
    public int getGuildHallCost() {
        return hallCost;
    }

    /**
     * Check whether guild-halls are protected from the environment and hostile
     * mobs.
     *
     * @return the state of guild-hall protection
     * @since 0.0.5
     */
    public boolean protectFromEnvironment() {
        return protectFromEnvironment;
    }

    /**
     * Check whether PvP is disallowed in guild-halls.
     *
     * @return the state of disallowance of PvP in guild-halls
     * @since 0.0.5
     */
    public boolean disallowHallPvp() {
        return disallowHallPvp;
    }

    /**
     * Check whether griefing is disallowed in guild-halls
     *
     * @return the state of disallowance of griefing in guild-halls
     * @since 0.0.5
     */
    public boolean hallAntiGrief() {
        return hallAntiGrief;
    }

    /**
     * Check whether pistons are disallowed in guild-halls
     *
     * @return the state of disallowance of pistons in guild-halls
     * @since 0.0.5
     */
    public boolean disallowHallPistons() {
        return hallNoPistons;
    }

    /**
     * Returns the associated {@link RolecraftCore} instance.
     *
     * @return the associated {@link RolecraftCore} instance
     * @since 0.0.5
     */
    public RolecraftCore getPlugin() {
        return plugin;
    }

    /**
     * Check if the data in this object has been fully loaded.
     *
     * @return {@code true} when the data is completely loaded; {@code false}
     *         otherwise
     * @since 0.0.5
     */
    public boolean isLoaded() {
        return loaded;
    }

    /**
     * Set the price for inviting a player to a {@link Guild}.
     *
     * @param inviteCost the new {@link Guild} invitation price
     * @since 0.0.5
     */
    public void setInviteCost(final int inviteCost) {
        this.inviteCost = inviteCost;
    }

    /**
     * Set the price for creating a new {@link Guild}.
     *
     * @param creationCost the new {@link Guild} creation price
     * @since 0.0.5
     */
    public void setCreationCost(final int creationCost) {
        this.creationCost = creationCost;
    }

    /**
     * Set the price for a guild-hall.
     *
     * @param hallCost the new guild-hall price
     * @since 0.0.5
     */
    public void setHallCost(final int hallCost) {
        this.hallCost = hallCost;
    }

    /**
     * Complete the loading phase. This should only be called by DAOs after this
     * {@link GuildManager} has been populated with all stored {@link Guild}s.
     *
     * @since 0.0.5
     * @deprecated for internal use only
     */
    @Deprecated
    public void completeLoad() {
        loaded = true;
    }

    /**
     * Get the {@link GuildAction} associated to the given human-readable
     * string.
     *
     * @param humanReadable the human-readable string that represents the wanted
     *        {@link GuildAction}
     * @return the appropriate {@link GuildAction}
     * @since 0.0.5
     */
    @Nullable
    public static GuildAction fromHumanReadable(@Nonnull final String humanReadable) {
        Validate.notNull(humanReadable);
        return actionMap.get(humanReadable);
    }
}