/*******************************************************************************
* This file is part of ASkyBlock.
*
* ASkyBlock is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* ASkyBlock is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with ASkyBlock. If not, see <http://www.gnu.org/licenses/>.
*******************************************************************************/
package com.wasteofplastic.askyblock;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.entity.Player;
import com.wasteofplastic.askyblock.events.CoopJoinEvent;
import com.wasteofplastic.askyblock.events.CoopLeaveEvent;
import com.wasteofplastic.askyblock.util.Util;
/**
* Handles coop play interactions
*
* @author tastybento
*
*/
public class CoopPlay {
private static CoopPlay instance = new CoopPlay(ASkyBlock.getPlugin());
// Stores all the coop islands, the coop player, the location and the
// inviter
private HashMap<UUID, HashMap<Location, UUID>> coopPlayers = new HashMap<UUID, HashMap<Location, UUID>>();
// Defines whether a player is on a coop island or not
// private HashMap<UUID, Location> onCoopIsland = new HashMap<UUID,
// Location>();
private ASkyBlock plugin;
/**
* @param plugin
*/
private CoopPlay(ASkyBlock plugin) {
this.plugin = plugin;
}
/**
* Adds a player to an island as a coop player.
*
* @param requester
* @param newPlayer
* @return true if successful, otherwise false
*/
public boolean addCoopPlayer(Player requester, Player newPlayer) {
// plugin.getLogger().info("DEBUG: adding coop player");
// Find out which island this coop player is being requested to join
Location islandLoc = null;
if (plugin.getPlayers().inTeam(requester.getUniqueId())) {
islandLoc = plugin.getPlayers().getTeamIslandLocation(requester.getUniqueId());
// Tell the team owner
UUID leaderUUID = plugin.getPlayers().getTeamLeader(requester.getUniqueId());
// Check if only leader can coop
if(Settings.onlyLeaderCanCoop && (!requester.getUniqueId().equals(leaderUUID))){
requester.sendMessage(ChatColor.RED + plugin.myLocale(requester.getUniqueId()).cannotCoop);
return false;
}
// Tell all the team members
for (UUID member : plugin.getPlayers().getMembers(leaderUUID)) {
// plugin.getLogger().info("DEBUG: " + member.toString());
if (!member.equals(requester.getUniqueId())) {
Player player = plugin.getServer().getPlayer(member);
if (player != null) {
Util.sendMessage(player, ChatColor.GOLD
+ plugin.myLocale(player.getUniqueId()).coopInvited.replace("[name]", requester.getName()).replace("[player]", newPlayer.getName()));
Util.sendMessage(player, ChatColor.GOLD + plugin.myLocale(player.getUniqueId()).coopUseExpel);
} else {
if (member.equals(leaderUUID)) {
// offline - tell leader
plugin.getMessages().setMessage(leaderUUID,
plugin.myLocale(leaderUUID).coopInvited.replace("[name]", requester.getName()).replace("[player]", newPlayer.getName()));
}
}
}
}
} else {
islandLoc = plugin.getPlayers().getIslandLocation(requester.getUniqueId());
}
Island coopIsland = plugin.getGrid().getIslandAt(islandLoc);
// Fire event and check if it is cancelled
final CoopJoinEvent event = new CoopJoinEvent(newPlayer.getUniqueId(), coopIsland, requester.getUniqueId());
plugin.getServer().getPluginManager().callEvent(event);
if (event.isCancelled()) {
return false;
}
// Add the coop to the list. If the location already exists then the new
// requester will replace the old
if (coopPlayers.containsKey(newPlayer.getUniqueId())) {
// This is an existing player in the list
// Add this island to the set
coopPlayers.get(newPlayer.getUniqueId()).put(coopIsland.getCenter(), requester.getUniqueId());
} else {
// First time. Create the hashmap
HashMap<Location, UUID> loc = new HashMap<Location, UUID>();
loc.put(coopIsland.getCenter(), requester.getUniqueId());
coopPlayers.put(newPlayer.getUniqueId(), loc);
}
return true;
}
/**
* Removes a coop player
*
* @param requester
* @param targetPlayer
* @return true if the player was a coop player, and false if not
*/
public boolean removeCoopPlayer(Player requester, Player targetPlayer) {
return removeCoopPlayer(requester, targetPlayer.getUniqueId());
}
/**
* Returns the list of islands that this player is coop on or empty if none
*
* @param player
* @return Set of locations
*/
public Set<Location> getCoopIslands(Player player) {
if (coopPlayers.containsKey(player.getUniqueId())) {
return coopPlayers.get(player.getUniqueId()).keySet();
}
return new HashSet<Location>();
}
/**
* Gets a list of all the players that are currently coop on this island
*
* @param islandLoc
* @return List of UUID's of players that have coop rights to the island
*/
public List<UUID> getCoopPlayers(Location islandLoc) {
Island coopIsland = plugin.getGrid().getIslandAt(islandLoc);
List<UUID> result = new ArrayList<UUID>();
if (coopIsland != null) {
for (UUID player : coopPlayers.keySet()) {
if (coopPlayers.get(player).containsKey(coopIsland.getCenter())) {
result.add(player);
}
}
}
return result;
}
/**
* Removes all coop players from an island - used when doing an island reset
*
* @param player
*/
public void clearAllIslandCoops(UUID player) {
// Remove any and all islands related to requester
Island island = plugin.getGrid().getIsland(player);
if (island == null) {
return;
}
for (HashMap<Location, UUID> coopPlayer : coopPlayers.values()) {
for (UUID inviter : coopPlayer.values()) {
// Fire event
final CoopLeaveEvent event = new CoopLeaveEvent(player, inviter, island);
plugin.getServer().getPluginManager().callEvent(event);
// Cannot be cancelled
}
coopPlayer.remove(island.getCenter());
}
}
/**
* Deletes all coops from player.
* Used when player logs out.
*
* @param player
*/
public void clearMyCoops(Player player) {
//plugin.getLogger().info("DEBUG: clear my coops - clearing coops memberships of " + player.getName());
Island coopIsland = plugin.getGrid().getIsland(player.getUniqueId());
if (coopPlayers.get(player.getUniqueId()) != null) {
//plugin.getLogger().info("DEBUG: " + player.getName() + " is a member of a coop");
boolean notCancelled = false;
for (UUID inviter : coopPlayers.get(player.getUniqueId()).values()) {
// Fire event
//plugin.getLogger().info("DEBUG: removing invite from " + plugin.getServer().getPlayer(inviter).getName());
final CoopLeaveEvent event = new CoopLeaveEvent(player.getUniqueId(), inviter, coopIsland);
plugin.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
coopPlayers.get(player.getUniqueId()).remove(inviter);
} else {
notCancelled = true;
}
}
// If the event was never cancelled, then delete the entry fully just in case. May not be needed.
if (notCancelled) {
coopPlayers.remove(player.getUniqueId());
}
}
}
public void saveCoops() {
File coopFile = new File(plugin.getDataFolder(), "coops.yml");
YamlConfiguration coopConfig = new YamlConfiguration();
for (UUID playerUUID : coopPlayers.keySet()) {
coopConfig.set(playerUUID.toString(), getMyCoops(playerUUID));
}
try {
coopConfig.save(coopFile);
} catch (IOException e) {
plugin.getLogger().severe("Could not save coop.yml file!");
}
}
public void loadCoops() {
File coopFile = new File(plugin.getDataFolder(), "coops.yml");
if (!coopFile.exists()) {
return;
}
YamlConfiguration coopConfig = new YamlConfiguration();
try {
coopConfig.load(coopFile);
} catch (IOException | InvalidConfigurationException e) {
plugin.getLogger().severe("Could not load coop.yml file!");
}
// Run through players
for (String playerUUID : coopConfig.getValues(false).keySet()) {
try {
setMyCoops(UUID.fromString(playerUUID), coopConfig.getStringList(playerUUID));
} catch (Exception e) {
plugin.getLogger().severe("Could not load coops for player UUID " + playerUUID + " skipping...");
}
}
}
/**
* Gets a serialize list of all the coops for this player. Used when saving the player
* @param playerUUID
* @return List of island location | uuid of invitee
*/
private List<String> getMyCoops(UUID playerUUID) {
List<String> result = new ArrayList<String>();
if (coopPlayers.containsKey(playerUUID)) {
for (Entry<Location, UUID> entry : coopPlayers.get(playerUUID).entrySet()) {
result.add(Util.getStringLocation(entry.getKey()) + "|" + entry.getValue().toString());
}
}
return result;
}
/**
* Sets a player's coops from string. Used when loading a player.
* @param playerUUID
* @param coops
*/
private void setMyCoops(UUID playerUUID, List<String> coops) {
try {
HashMap<Location, UUID> temp = new HashMap<Location, UUID>();
for (String coop : coops) {
String[] split = coop.split("\\|");
if (split.length == 2) {
Island coopIsland = plugin.getGrid().getIslandAt(Util.getLocationString(split[0]));
if (coopIsland != null) {
temp.put(coopIsland.getCenter(), UUID.fromString(split[1]));
}
}
}
coopPlayers.put(playerUUID, temp);
} catch (Exception e) {
plugin.getLogger().severe("Could not load coops for UUID " + playerUUID);
e.printStackTrace();
}
}
/**
* Goes through all the known coops and removes any that were invited by
* clearer. Returns any inventory
* Can be used when clearer logs out or when they are kicked or leave a team
*
* @param clearer
*/
public void clearMyInvitedCoops(Player clearer) {
//plugin.getLogger().info("DEBUG: clear my invited coops - clearing coops that were invited by " + clearer.getName());
Island coopIsland = plugin.getGrid().getIsland(clearer.getUniqueId());
for (UUID playerUUID : coopPlayers.keySet()) {
Iterator<Entry<Location, UUID>> en = coopPlayers.get(playerUUID).entrySet().iterator();
while (en.hasNext()) {
Entry<Location, UUID> entry = en.next();
// Check if this invite was sent by clearer
if (entry.getValue().equals(clearer.getUniqueId())) {
// Fire event
final CoopLeaveEvent event = new CoopLeaveEvent(playerUUID, clearer.getUniqueId(), coopIsland);
plugin.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
// Yes, so get the invitee (target)
Player target = plugin.getServer().getPlayer(playerUUID);
if (target != null) {
target.sendMessage(ChatColor.RED + plugin.myLocale(playerUUID).coopRemoved.replace("[name]", clearer.getName()));
} else {
plugin.getMessages().setMessage(playerUUID, ChatColor.RED + plugin.myLocale(playerUUID).coopRemoved.replace("[name]", clearer.getName()));
}
// Mark them as no longer on a coop island
// setOnCoopIsland(players, null);
// Remove this entry
en.remove();
} // else do not remove
}
}
}
}
/**
* Removes all coop players from an island - used when doing an island reset
*
* @param island
*/
public void clearAllIslandCoops(Location island) {
if (island == null) {
return;
}
Island coopIsland = plugin.getGrid().getIslandAt(island);
// Remove any and all islands related to requester
for (HashMap<Location, UUID> coopPlayer : coopPlayers.values()) {
// Fire event
final CoopLeaveEvent event = new CoopLeaveEvent(coopPlayer.get(island), coopIsland.getOwner(), coopIsland);
plugin.getServer().getPluginManager().callEvent(event);
// Cannot be cancelled
coopPlayer.remove(island);
}
}
/**
* @return the instance
*/
public static CoopPlay getInstance() {
return instance;
}
public boolean removeCoopPlayer(Player requester, UUID targetPlayerUUID) {
boolean removed = false;
/*
plugin.getLogger().info("DEBUG: requester is " + requester.getName());
plugin.getLogger().info("DEBUG: target = " + targetPlayerUUID.toString());
for (UUID key : coopPlayers.keySet()) {
plugin.getLogger().info("DEBUG: " + key + " ==> " + coopPlayers.get(key));
}*/
// Only bother if the player is in the list
if (coopPlayers.containsKey(targetPlayerUUID)) {
Island coopIsland = plugin.getGrid().getIsland(requester.getUniqueId());
if (coopIsland != null) {
// Fire event
final CoopLeaveEvent event = new CoopLeaveEvent(targetPlayerUUID, requester.getUniqueId(), coopIsland);
plugin.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
removed = coopPlayers.get(targetPlayerUUID).remove(coopIsland.getCenter()) != null ? true: false;
}
}
}
return removed;
}
}