/** * Jobs Plugin for Bukkit * Copyright (C) 2011 Zak Ford * * This program 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. * * This program 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 this program. If not, see . */ package com.gamingmesh.jobs; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.Sound; import org.bukkit.entity.Player; import org.bukkit.permissions.Permission; import org.bukkit.permissions.PermissionDefault; import com.gamingmesh.jobs.api.JobsJoinEvent; import com.gamingmesh.jobs.api.JobsLeaveEvent; import com.gamingmesh.jobs.api.JobsLevelUpEvent; import com.gamingmesh.jobs.config.ConfigManager; import com.gamingmesh.jobs.container.Job; import com.gamingmesh.jobs.container.JobCommands; import com.gamingmesh.jobs.container.JobProgression; import com.gamingmesh.jobs.container.JobsPlayer; import com.gamingmesh.jobs.dao.JobsDAO; import com.gamingmesh.jobs.i18n.Language; import com.gamingmesh.jobs.stuff.ActionBar; import com.gamingmesh.jobs.stuff.ChatColor; import com.gamingmesh.jobs.stuff.PerformCommands; public class PlayerManager { // private Map players = Collections.synchronizedMap(new HashMap()); private Map players = new HashMap(); /** * Handles join of new player * @param playername */ public void playerJoin(final Player player) { //synchronized (players) { Thread threadd = new Thread() { public void run() { JobsPlayer jPlayer = players.get(player.getName().toLowerCase()); if (jPlayer == null) { jPlayer = JobsPlayer.loadFromDao(Jobs.getJobsDAO(), player); players.put(player.getName().toLowerCase(), jPlayer); } jPlayer.onConnect(); jPlayer.reloadHonorific(); Jobs.getPermissionHandler().recalculatePermissions(jPlayer); return; } }; threadd.start(); threadd.interrupt(); //} } /** * Handles player quit * @param playername */ public void playerQuit(Player player) { //synchronized (players) { if (ConfigManager.getJobsConfiguration().saveOnDisconnect()) { JobsPlayer jPlayer = players.remove(player.getName().toLowerCase()); if (jPlayer != null) { jPlayer.save(Jobs.getJobsDAO()); jPlayer.onDisconnect(); } } else { JobsPlayer jPlayer = players.get(player.getName().toLowerCase()); if (jPlayer != null) { jPlayer.onDisconnect(); } } //} } /** * Save all the information of all of the players in the game */ public void saveAll() { JobsDAO dao = Jobs.getJobsDAO(); /* * Saving is a three step process to minimize synchronization locks when called asynchronously. * * 1) Safely copy list for saving. * 2) Perform save on all players on copied list. * 3) Garbage collect the real list to remove any offline players with saved data */ ArrayList list = null; synchronized (players) { list = new ArrayList(players.values()); } for (JobsPlayer jPlayer : list) { jPlayer.save(dao); } synchronized (players) { Iterator iter = players.values().iterator(); while (iter.hasNext()) { JobsPlayer jPlayer = iter.next(); synchronized (jPlayer.saveLock) { if (!jPlayer.isOnline() && jPlayer.isSaved()) { iter.remove(); } } } } } /** * Get the player job info for specific player * @param player - the player who's job you're getting * @return the player job info of the player */ public JobsPlayer getJobsPlayer(Player player) { return players.get(player.getName().toLowerCase()); } /** * Get the player job info for specific player * @param player name - the player name who's job you're getting * @return the player job info of the player */ public JobsPlayer getJobsPlayer(String playerName) { return players.get(playerName.toLowerCase()); } /** * Get the player job info for specific player * @param player - the player who's job you're getting * @return the player job info of the player */ public JobsPlayer getJobsPlayerOffline(OfflinePlayer offlinePlayer) { JobsPlayer jPlayer = players.get(offlinePlayer.getName().toLowerCase()); if (jPlayer != null) return jPlayer; return JobsPlayer.loadFromDao(Jobs.getJobsDAO(), offlinePlayer); } /** * Causes player to join their job * @param jPlayer * @param job */ public void joinJob(JobsPlayer jPlayer, Job job) { synchronized (jPlayer.saveLock) { if (jPlayer.isInJob(job)) return; // let the user join the job if (!jPlayer.joinJob(job, jPlayer)) return; // JobsJoin event JobsJoinEvent jobsjoinevent = new JobsJoinEvent(jPlayer, job); Bukkit.getServer().getPluginManager().callEvent(jobsjoinevent); // If event is canceled, dont do anything if (jobsjoinevent.isCancelled()) return; Jobs.getJobsDAO().joinJob(jPlayer, job); PerformCommands.PerformCommandsOnJoin(jPlayer, job); Jobs.takeSlot(job); Signs.SignUtil.SignUpdate(job.getName()); Signs.SignUtil.SignUpdate("gtoplist"); job.updateTotalPlayers(); } } /** * Causes player to leave their job * @param jPlayer * @param job */ public void leaveJob(JobsPlayer jPlayer, Job job) { synchronized (jPlayer.saveLock) { if (!jPlayer.isInJob(job)) return; Jobs.getJobsDAO().recordToArchive(jPlayer, job); // let the user leave the job if (!jPlayer.leaveJob(job)) return; // JobsJoin event JobsLeaveEvent jobsleaveevent = new JobsLeaveEvent(jPlayer, job); Bukkit.getServer().getPluginManager().callEvent(jobsleaveevent); // If event is canceled, dont do anything if (jobsleaveevent.isCancelled()) return; Jobs.getJobsDAO().quitJob(jPlayer, job); PerformCommands.PerformCommandsOnLeave(jPlayer, job); Jobs.leaveSlot(job); Signs.SignUtil.SignUpdate(job.getName()); Signs.SignUtil.SignUpdate("gtoplist"); job.updateTotalPlayers(); } } /** * Causes player to leave all their jobs * @param jPlayer */ public void leaveAllJobs(JobsPlayer jPlayer) { synchronized (jPlayer.saveLock) { for (JobProgression job : jPlayer.getJobProgression()) { Jobs.getJobsDAO().quitJob(jPlayer, job.getJob()); PerformCommands.PerformCommandsOnLeave(jPlayer, job.getJob()); Jobs.leaveSlot(job.getJob()); Signs.SignUtil.SignUpdate(job.getJob().getName()); Signs.SignUtil.SignUpdate("gtoplist"); job.getJob().updateTotalPlayers(); } jPlayer.leaveAllJobs(); } } /** * Transfers player job * @param jPlayer * @param oldjob - the old job * @param newjob - the new job */ public void transferJob(JobsPlayer jPlayer, Job oldjob, Job newjob) { synchronized (jPlayer.saveLock) { if (!jPlayer.transferJob(oldjob, newjob, jPlayer)) return; JobsDAO dao = Jobs.getJobsDAO(); dao.quitJob(jPlayer, oldjob); oldjob.updateTotalPlayers(); dao.joinJob(jPlayer, newjob); newjob.updateTotalPlayers(); jPlayer.save(dao); } } /** * Promotes player in their job * @param jPlayer * @param job - the job * @param levels - number of levels to promote */ public void promoteJob(JobsPlayer jPlayer, Job job, int levels) { synchronized (jPlayer.saveLock) { jPlayer.promoteJob(job, levels, jPlayer); jPlayer.save(Jobs.getJobsDAO()); Signs.SignUtil.SignUpdate(job.getName()); Signs.SignUtil.SignUpdate("gtoplist"); } } /** * Demote player in their job * @param jPlayer * @param job - the job * @param levels - number of levels to demote */ public void demoteJob(JobsPlayer jPlayer, Job job, int levels) { synchronized (jPlayer.saveLock) { jPlayer.demoteJob(job, levels); jPlayer.save(Jobs.getJobsDAO()); Signs.SignUtil.SignUpdate(job.getName()); Signs.SignUtil.SignUpdate("gtoplist"); } } /** * Adds experience to the player * @param jPlayer * @param job - the job * @param experience - experience gained */ public void addExperience(JobsPlayer jPlayer, Job job, double experience) { synchronized (jPlayer.saveLock) { JobProgression prog = jPlayer.getJobProgression(job); if (prog == null) return; int oldLevel = prog.getLevel(); if (prog.addExperience(experience)) performLevelUp(jPlayer, job, oldLevel); jPlayer.save(Jobs.getJobsDAO()); Signs.SignUtil.SignUpdate(job.getName()); Signs.SignUtil.SignUpdate("gtoplist"); } } /** * Removes experience to the player * @param jPlayer * @param job - the job * @param experience - experience gained */ public void removeExperience(JobsPlayer jPlayer, Job job, double experience) { synchronized (jPlayer.saveLock) { JobProgression prog = jPlayer.getJobProgression(job); if (prog == null) return; prog.addExperience(-experience); jPlayer.save(Jobs.getJobsDAO()); Signs.SignUtil.SignUpdate(job.getName()); Signs.SignUtil.SignUpdate("gtoplist"); } } /** * Broadcasts level up about a player * @param jPlayer * @param job * @param oldLevel */ public void performLevelUp(JobsPlayer jPlayer, Job job, int oldLevel) { Player player = (Player) jPlayer.getPlayer(); JobProgression prog = jPlayer.getJobProgression(job); if (prog == null) return; // LevelUp event JobsLevelUpEvent levelUpEvent = new JobsLevelUpEvent(jPlayer, job.getName(), prog.getLevel(), ConfigManager.getJobsConfiguration().getTitleForLevel(oldLevel, job.getName()), ConfigManager.getJobsConfiguration().getTitleForLevel(prog.getLevel(), job.getName()), ConfigManager.getJobsConfiguration().SoundLevelupSound.toUpperCase(), ConfigManager.getJobsConfiguration().SoundLevelupVolume, ConfigManager.getJobsConfiguration().SoundLevelupPitch, ConfigManager.getJobsConfiguration().SoundTitleChangeSound.toUpperCase(), ConfigManager.getJobsConfiguration().SoundTitleChangeVolume, ConfigManager.getJobsConfiguration().SoundTitleChangePitch); Bukkit.getServer().getPluginManager().callEvent(levelUpEvent); // If event is canceled, dont do anything if (levelUpEvent.isCancelled()) return; if (ConfigManager.getJobsConfiguration().SoundLevelupUse) player.getWorld().playSound(player.getLocation(), Sound.valueOf(levelUpEvent.getSoundName()), levelUpEvent.getSoundVolume(), levelUpEvent.getSoundPitch()); String message; if (ConfigManager.getJobsConfiguration().isBroadcastingLevelups()) { message = Language.getMessage("message.levelup.broadcast"); } else { message = Language.getMessage("message.levelup.nobroadcast"); } message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); if (levelUpEvent.getOldTitle() != null) { message = message.replace("%titlename%", levelUpEvent.getOldTitleColor() + levelUpEvent.getOldTitleName() + ChatColor.WHITE); } if (player != null) { message = message.replace("%playername%", player.getDisplayName()); } else { message = message.replace("%playername%", jPlayer.getUserName()); } message = message.replace("%joblevel%", "" + prog.getLevel()); for (String line : message.split("\n")) { if (ConfigManager.getJobsConfiguration().isBroadcastingLevelups()) { if (ConfigManager.getJobsConfiguration().BroadcastingLevelUpLevels.contains(oldLevel + 1) || ConfigManager.getJobsConfiguration().BroadcastingLevelUpLevels.contains(0)) Bukkit.getServer().broadcastMessage(line); } else if (player != null) { if (ConfigManager.getJobsConfiguration().LevelChangeActionBar) ActionBar.send(player, line); if (ConfigManager.getJobsConfiguration().LevelChangeChat) player.sendMessage(line); } } if (levelUpEvent.getNewTitle() != null && !levelUpEvent.getNewTitle().equals(levelUpEvent.getOldTitle())) { if (ConfigManager.getJobsConfiguration().SoundTitleChangeUse) player.getWorld().playSound(player.getLocation(), Sound.valueOf(levelUpEvent.getTitleChangeSoundName()), levelUpEvent.getTitleChangeVolume(), levelUpEvent.getTitleChangePitch()); // user would skill up if (ConfigManager.getJobsConfiguration().isBroadcastingSkillups()) { message = Language.getMessage("message.skillup.broadcast"); } else { message = Language.getMessage("message.skillup.nobroadcast"); } if (player != null) { message = message.replace("%playername%", player.getDisplayName()); } else { message = message.replace("%playername%", jPlayer.getUserName()); } message = message.replace("%titlename%", levelUpEvent.getNewTitleColor() + levelUpEvent.getNewTitleName() + ChatColor.WHITE); message = message.replace("%jobname%", job.getChatColor() + job.getName() + ChatColor.WHITE); for (String line : message.split("\n")) { if (ConfigManager.getJobsConfiguration().isBroadcastingLevelups()) { Bukkit.getServer().broadcastMessage(line); } else if (player != null) { if (ConfigManager.getJobsConfiguration().TitleChangeActionBar) ActionBar.send(player, line); if (ConfigManager.getJobsConfiguration().TitleChangeChat) player.sendMessage(line); } } } jPlayer.reloadHonorific(); Jobs.getPermissionHandler().recalculatePermissions(jPlayer); performCommandOnLevelUp(jPlayer, prog.getJob(), oldLevel); Signs.SignUtil.SignUpdate(job.getName()); Signs.SignUtil.SignUpdate("gtoplist"); } /** * Performs command on level up * @param jPlayer * @param job * @param oldLevel */ public void performCommandOnLevelUp(JobsPlayer jPlayer, Job job, int oldLevel) { int newLevel = oldLevel + 1; Player player = Bukkit.getServer().getPlayer(jPlayer.getPlayerUUID()); JobProgression prog = jPlayer.getJobProgression(job); if (prog == null) return; for (JobCommands command : job.getCommands()) { if (newLevel >= command.getLevelFrom() && newLevel <= command.getLevelUntil()) { String commandString = command.getCommand(); commandString = commandString.replace("[player]", player.getName()); commandString = commandString.replace("[oldlevel]", String.valueOf(oldLevel)); commandString = commandString.replace("[newlevel]", String.valueOf(newLevel)); commandString = commandString.replace("[jobname]", job.getName()); Bukkit.dispatchCommand(Bukkit.getConsoleSender(), commandString); } } } /** * Get job exp boost * @param player * @param job * @return double of boost */ public Double GetExpBoost(Player dude, Job job) { Double ExpBoost = 1.0; if (dude == null || job.getName() == null) return 1.0; if (Perm(dude, "jobs.boost." + job.getName() + ".exp") || Perm(dude, "jobs.boost." + job.getName() + ".both") || Perm(dude, "jobs.boost.all.both") || Perm(dude, "jobs.boost.all.exp")) { ExpBoost = ConfigManager.getJobsConfiguration().BoostExp; } return ExpBoost; } /** * Get max jobs * @param player * @return True if he have permission */ public boolean getJobsLimit(Player player, Short currentCount) { if (Perm(player, "jobs.max.*")) return true; short count = (short) ConfigManager.getJobsConfiguration().getMaxJobs(); for (short ctr = 0; ctr < 255; ctr++) { if (Perm(player, "jobs.max." + ctr)) count = ctr; if (count > currentCount) return true; } return false; } private boolean Perm(Player player, String permission) { Permission p = new Permission(permission, PermissionDefault.FALSE); return player.hasPermission(p); } /** * Get job money boost * @param player * @param job * @return double of boost */ public Double GetMoneyBoost(Player dude, Job job) { Double MoneyBoost = 1.0; if (dude != null && job.getName() != null) { if (Perm(dude, "jobs.boost." + job.getName() + ".money") || Perm(dude, "jobs.boost." + job.getName() + ".both") || Perm(dude, "jobs.boost.all.both") || Perm(dude, "jobs.boost.all.money")) { MoneyBoost = ConfigManager.getJobsConfiguration().BoostMoney; } } return MoneyBoost; } /** * Perform reload */ public void reload() { synchronized (players) { for (JobsPlayer jPlayer : players.values()) { for (JobProgression progression : jPlayer.getJobProgression()) { String jobName = progression.getJob().getName(); Job job = Jobs.getJob(jobName); if (job != null) { progression.setJob(job); } } if (jPlayer.isOnline()) { jPlayer.reloadHonorific(); Jobs.getPermissionHandler().recalculatePermissions(jPlayer); } } } } }