Permit /questadmin commands on offline players, part 1. Per #1040

This commit is contained in:
PikaMug 2020-01-21 02:29:14 -05:00
parent 3e42dcbc33
commit 83f39e487b
3 changed files with 197 additions and 168 deletions

View File

@ -20,6 +20,7 @@ import java.util.Map.Entry;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Location; import org.bukkit.Location;
import org.bukkit.OfflinePlayer;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemFlag; import org.bukkit.inventory.ItemFlag;
@ -289,7 +290,7 @@ public class Quest {
* *
* Method may be called as often as needed. * Method may be called as often as needed.
* *
* @param quester The quester to have their compass updated * @param quester The online quester to have their compass updated
* @param nextStage The stage to process for targets * @param nextStage The stage to process for targets
* @return true if successful * @return true if successful
*/ */
@ -303,6 +304,9 @@ public class Quest {
if (nextStage == null) { if (nextStage == null) {
return false; return false;
} }
if (!quester.getOfflinePlayer().isOnline()) {
return false;
}
Location targetLocation = null; Location targetLocation = null;
if (nextStage.citizensToInteract != null && nextStage.citizensToInteract.size() > 0) { if (nextStage.citizensToInteract != null && nextStage.citizensToInteract.size() > 0) {
targetLocation = plugin.getDependencies().getNPCLocation(nextStage.citizensToInteract.getFirst()); targetLocation = plugin.getDependencies().getNPCLocation(nextStage.citizensToInteract.getFirst());
@ -324,53 +328,36 @@ public class Quest {
} }
/** /**
* Check that a quester has met all Requirements to accept this quest * Check that a quester has met all Requirements to accept this quest<p>
*
* Item, permission and custom Requirements are only checked for online players
* *
* @param quester The quester to check * @param quester The quester to check
* @return true if all Requirements have been met * @return true if all Requirements have been met
*/ */
public boolean testRequirements(Quester quester) { public boolean testRequirements(Quester quester) {
return testRequirements(quester.getPlayer()); return testRequirements(quester.getOfflinePlayer());
} }
/** /**
* Check that a player has met all Requirements to accept this quest * Check that a player has met all Requirements to accept this quest<p>
*
* Item, permission and custom Requirements are only checked for online players
* *
* @param player The player to check * @param player The player to check
* @return true if all Requirements have been met * @return true if all Requirements have been met
*/ */
protected boolean testRequirements(Player player) { protected boolean testRequirements(OfflinePlayer player) {
Quester quester = plugin.getQuester(player.getUniqueId()); Quester quester = plugin.getQuester(player.getUniqueId());
if (reqs.getMoney() != 0 && plugin.getDependencies().getVaultEconomy() != null) { if (reqs.getMoney() != 0 && plugin.getDependencies().getVaultEconomy() != null) {
if (plugin.getDependencies().getVaultEconomy().getBalance(Bukkit.getOfflinePlayer(player.getUniqueId())) if (plugin.getDependencies().getVaultEconomy().getBalance(player) < reqs.getMoney()) {
< reqs.getMoney()) {
return false;
}
}
PlayerInventory inventory = player.getInventory();
int num = 0;
for (ItemStack is : reqs.getItems()) {
for (ItemStack stack : inventory.getContents()) {
if (stack != null) {
if (ItemUtil.compareItems(is, stack, true) == 0) {
num += stack.getAmount();
}
}
}
if (num < is.getAmount()) {
return false;
}
num = 0;
}
for (String s : reqs.getPermissions()) {
if (player.hasPermission(s) == false) {
return false; return false;
} }
} }
for (String s : reqs.getMcmmoSkills()) { for (String s : reqs.getMcmmoSkills()) {
final SkillType st = Quests.getMcMMOSkill(s); final SkillType st = Quests.getMcMMOSkill(s);
final int lvl = reqs.getMcmmoAmounts().get(reqs.getMcmmoSkills().indexOf(s)); final int lvl = reqs.getMcmmoAmounts().get(reqs.getMcmmoSkills().indexOf(s));
if (UserManager.getPlayer(player).getProfile().getSkillLevel(st) < lvl) { if (UserManager.getOfflinePlayer(player).getProfile().getSkillLevel(st) < lvl) {
return false; return false;
} }
} }
@ -386,23 +373,6 @@ public class Quest {
return false; return false;
} }
} }
for (String s : reqs.getCustomRequirements().keySet()) {
CustomRequirement found = null;
for (CustomRequirement cr : plugin.getCustomRequirements()) {
if (cr.getName().equalsIgnoreCase(s)) {
found = cr;
break;
}
}
if (found != null) {
if (found.testRequirement(player, reqs.getCustomRequirements().get(s)) == false) {
return false;
}
} else {
plugin.getLogger().warning("Quester \"" + player.getName() + "\" attempted to take Quest \"" + name
+ "\", but the Custom Requirement \"" + s + "\" could not be found. Does it still exist?");
}
}
if (quester.questPoints < reqs.getQuestPoints()) { if (quester.questPoints < reqs.getQuestPoints()) {
return false; return false;
} }
@ -416,6 +386,46 @@ public class Quest {
return false; return false;
} }
} }
if (player.isOnline()) {
Player p = (Player)player;
PlayerInventory inventory = p.getInventory();
int num = 0;
for (ItemStack is : reqs.getItems()) {
for (ItemStack stack : inventory.getContents()) {
if (stack != null) {
if (ItemUtil.compareItems(is, stack, true) == 0) {
num += stack.getAmount();
}
}
}
if (num < is.getAmount()) {
return false;
}
num = 0;
}
for (String s : reqs.getPermissions()) {
if (p.hasPermission(s) == false) {
return false;
}
}
for (String s : reqs.getCustomRequirements().keySet()) {
CustomRequirement found = null;
for (CustomRequirement cr : plugin.getCustomRequirements()) {
if (cr.getName().equalsIgnoreCase(s)) {
found = cr;
break;
}
}
if (found != null) {
if (found.testRequirement(p, reqs.getCustomRequirements().get(s)) == false) {
return false;
}
} else {
plugin.getLogger().warning("Quester \"" + p.getName() + "\" attempted to take Quest \"" + name
+ "\", but the Custom Requirement \"" + s + "\" could not be found. Does it still exist?");
}
}
}
return true; return true;
} }

View File

@ -412,73 +412,76 @@ public class Quester {
if (preEvent.isCancelled()) { if (preEvent.isCancelled()) {
return; return;
} }
Player player = getPlayer(); OfflinePlayer player = getOfflinePlayer();
Planner pln = q.getPlanner(); if (player.isOnline()) {
long start = pln.getStartInMillis(); // Start time in milliseconds since UTC epoch Player p = getPlayer();
long end = pln.getEndInMillis(); // End time in milliseconds since UTC epoch Planner pln = q.getPlanner();
long duration = end - start; // How long the quest can be active for long start = pln.getStartInMillis(); // Start time in milliseconds since UTC epoch
long repeat = pln.getRepeat(); // Length to wait in-between start times long end = pln.getEndInMillis(); // End time in milliseconds since UTC epoch
if (start != -1) { long duration = end - start; // How long the quest can be active for
if (System.currentTimeMillis() < start) { long repeat = pln.getRepeat(); // Length to wait in-between start times
String early = Lang.get("plnTooEarly"); if (start != -1) {
early = early.replace("<quest>", ChatColor.AQUA + q.getName() + ChatColor.YELLOW); if (System.currentTimeMillis() < start) {
early = early.replace("<time>", ChatColor.DARK_PURPLE
+ MiscUtil.getTime(start - System.currentTimeMillis()) + ChatColor.YELLOW);
player.sendMessage(ChatColor.YELLOW + early);
return;
}
}
if (end != -1 && repeat == -1) {
if (System.currentTimeMillis() > end) {
String late = Lang.get("plnTooLate");
late = late.replace("<quest>", ChatColor.AQUA + q.getName() + ChatColor.RED);
late = late.replace("<time>", ChatColor.DARK_PURPLE
+ MiscUtil.getTime(System.currentTimeMillis() - end) + ChatColor.RED);
player.sendMessage(ChatColor.RED + late);
return;
}
}
if (repeat != -1 && start != -1 && end != -1) {
// Ensure that we're past the initial duration
if (System.currentTimeMillis() > end) {
final int maxSize = 2;
final LinkedHashMap<Long, Long> cache = new LinkedHashMap<Long, Long>() {
private static final long serialVersionUID = 1L;
@Override
protected boolean removeEldestEntry(final Map.Entry<Long, Long> eldest) {
return size() > maxSize;
}
};
// Store both the upcoming and most recent period of activity
long nextStart = start;
long nextEnd = end;
while (System.currentTimeMillis() >= nextStart) {
nextStart += repeat;
nextEnd = nextStart + duration;
cache.put(nextStart, nextEnd);
}
// Check whether the quest is currently active
boolean active = false;
for (Entry<Long, Long> startEnd : cache.entrySet()) {
if (startEnd.getKey() <= System.currentTimeMillis() && System.currentTimeMillis()
< startEnd.getValue()) {
active = true;
}
}
// If quest is not active, inform user of wait time
if (!active) {
String early = Lang.get("plnTooEarly"); String early = Lang.get("plnTooEarly");
early = early.replace("<quest>", ChatColor.AQUA + q.getName() + ChatColor.YELLOW); early = early.replace("<quest>", ChatColor.AQUA + q.getName() + ChatColor.YELLOW);
early = early.replace("<time>", ChatColor.DARK_PURPLE early = early.replace("<time>", ChatColor.DARK_PURPLE
+ MiscUtil.getTime(nextStart - System.currentTimeMillis()) + ChatColor.YELLOW); + MiscUtil.getTime(start - System.currentTimeMillis()) + ChatColor.YELLOW);
player.sendMessage(ChatColor.YELLOW + early); p.sendMessage(ChatColor.YELLOW + early);
return; return;
} }
} }
if (end != -1 && repeat == -1) {
if (System.currentTimeMillis() > end) {
String late = Lang.get("plnTooLate");
late = late.replace("<quest>", ChatColor.AQUA + q.getName() + ChatColor.RED);
late = late.replace("<time>", ChatColor.DARK_PURPLE
+ MiscUtil.getTime(System.currentTimeMillis() - end) + ChatColor.RED);
p.sendMessage(ChatColor.RED + late);
return;
}
}
if (repeat != -1 && start != -1 && end != -1) {
// Ensure that we're past the initial duration
if (System.currentTimeMillis() > end) {
final int maxSize = 2;
final LinkedHashMap<Long, Long> cache = new LinkedHashMap<Long, Long>() {
private static final long serialVersionUID = 1L;
@Override
protected boolean removeEldestEntry(final Map.Entry<Long, Long> eldest) {
return size() > maxSize;
}
};
// Store both the upcoming and most recent period of activity
long nextStart = start;
long nextEnd = end;
while (System.currentTimeMillis() >= nextStart) {
nextStart += repeat;
nextEnd = nextStart + duration;
cache.put(nextStart, nextEnd);
}
// Check whether the quest is currently active
boolean active = false;
for (Entry<Long, Long> startEnd : cache.entrySet()) {
if (startEnd.getKey() <= System.currentTimeMillis() && System.currentTimeMillis()
< startEnd.getValue()) {
active = true;
}
}
// If quest is not active, inform user of wait time
if (!active) {
String early = Lang.get("plnTooEarly");
early = early.replace("<quest>", ChatColor.AQUA + q.getName() + ChatColor.YELLOW);
early = early.replace("<time>", ChatColor.DARK_PURPLE
+ MiscUtil.getTime(nextStart - System.currentTimeMillis()) + ChatColor.YELLOW);
p.sendMessage(ChatColor.YELLOW + early);
return;
}
}
}
} }
if (q.testRequirements(player) == true || override) { if (q.testRequirements(player) == true || override) {
addEmptiesFor(q, 0); addEmptiesFor(q, 0);
@ -496,32 +499,38 @@ public class Quester {
plugin.getDependencies().getVaultEconomy().withdrawPlayer(getOfflinePlayer(), reqs.getMoney()); plugin.getDependencies().getVaultEconomy().withdrawPlayer(getOfflinePlayer(), reqs.getMoney());
} }
} }
for (ItemStack is : reqs.getItems()) { if (player.isOnline()) {
if (reqs.getRemoveItems().get(reqs.getItems().indexOf(is)) == true) { Player p = getPlayer();
InventoryUtil.removeItem(player.getInventory(), is); for (ItemStack is : reqs.getItems()) {
if (reqs.getRemoveItems().get(reqs.getItems().indexOf(is)) == true) {
InventoryUtil.removeItem(p.getInventory(), is);
}
}
String accepted = Lang.get(getPlayer(), "questAccepted");
accepted = accepted.replace("<quest>", q.getName());
p.sendMessage(ChatColor.GREEN + accepted);
p.sendMessage("");
if (plugin.getSettings().canShowQuestTitles()) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "title "
+ player.getName() + " title " + "{\"text\":\"" + Lang.get(getPlayer(), "quest") + " "
+ Lang.get(getPlayer(), "accepted") + "\",\"color\":\"gold\"}");
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "title "
+ player.getName() + " subtitle " + "{\"text\":\"" + q.getName()
+ "\",\"color\":\"yellow\"}");
} }
} }
String accepted = Lang.get(getPlayer(), "questAccepted");
accepted = accepted.replace("<quest>", q.getName());
player.sendMessage(ChatColor.GREEN + accepted);
player.sendMessage("");
if (plugin.getSettings().canShowQuestTitles()) {
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "title "
+ player.getName() + " title " + "{\"text\":\"" + Lang.get(getPlayer(), "quest") + " "
+ Lang.get(getPlayer(), "accepted") + "\",\"color\":\"gold\"}");
Bukkit.getServer().dispatchCommand(Bukkit.getServer().getConsoleSender(), "title "
+ player.getName() + " subtitle " + "{\"text\":\"" + q.getName()
+ "\",\"color\":\"yellow\"}");
}
} }
String msg = Lang.get(getPlayer(), "questObjectivesTitle"); if (player.isOnline()) {
msg = msg.replace("<quest>", q.getName()); Player p = getPlayer();
getPlayer().sendMessage(ChatColor.GOLD + msg); String msg = Lang.get(p, "questObjectivesTitle");
plugin.showObjectives(q, this, false); msg = msg.replace("<quest>", q.getName());
String stageStartMessage = stage.startMessage; p.sendMessage(ChatColor.GOLD + msg);
if (stageStartMessage != null) { plugin.showObjectives(q, this, false);
getPlayer().sendMessage(ConfigUtil String stageStartMessage = stage.startMessage;
.parseStringWithPossibleLineBreaks(stageStartMessage, q, getPlayer())); if (stageStartMessage != null) {
p.sendMessage(ConfigUtil
.parseStringWithPossibleLineBreaks(stageStartMessage, q, getPlayer()));
}
} }
if (stage.chatActions.isEmpty() == false) { if (stage.chatActions.isEmpty() == false) {
for (String chatTrigger : stage.chatActions.keySet()) { for (String chatTrigger : stage.chatActions.keySet()) {
@ -542,7 +551,9 @@ public class Quester {
q.updateCompass(this, stage); q.updateCompass(this, stage);
saveData(); saveData();
} else { } else {
player.sendMessage(q.getRequirements().getFailRequirements()); if (player.isOnline()) {
((Player)player).sendMessage(q.getRequirements().getFailRequirements());
}
} }
QuesterPostStartQuestEvent postEvent = new QuesterPostStartQuestEvent(this, q); QuesterPostStartQuestEvent postEvent = new QuesterPostStartQuestEvent(this, q);
plugin.getServer().getPluginManager().callEvent(postEvent); plugin.getServer().getPluginManager().callEvent(postEvent);

View File

@ -42,6 +42,7 @@ import me.blackvein.quests.util.MiscUtil;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.Command; import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor; import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender; import org.bukkit.command.CommandSender;
@ -986,51 +987,58 @@ public class CmdExecutor implements CommandExecutor {
private void adminGive(final CommandSender cs, String[] args) { private void adminGive(final CommandSender cs, String[] args) {
if (cs.hasPermission("quests.admin.*") || cs.hasPermission("quests.admin.give")) { if (cs.hasPermission("quests.admin.*") || cs.hasPermission("quests.admin.give")) {
Player target = getPlayer(args[1]); OfflinePlayer target = getPlayer(args[1]);
if (target == null) { if (target == null) {
cs.sendMessage(ChatColor.YELLOW + Lang.get("playerNotFound")); try {
target = Bukkit.getOfflinePlayer(UUID.fromString(args[1]));
} catch (IllegalArgumentException e) {
cs.sendMessage(ChatColor.YELLOW + Lang.get("playerNotFound"));
return;
}
}
Quest questToGive;
String name = "";
if (args.length == 3) {
name = args[2].toLowerCase();
} else { } else {
Quest questToGive; for (int i = 2; i < args.length; i++) {
String name = ""; int lastIndex = args.length - 1;
if (args.length == 3) { if (i == lastIndex) {
name = args[2].toLowerCase(); name = name + args[i].toLowerCase();
} else { } else {
for (int i = 2; i < args.length; i++) { name = name + args[i].toLowerCase() + " ";
int lastIndex = args.length - 1;
if (i == lastIndex) {
name = name + args[i].toLowerCase();
} else {
name = name + args[i].toLowerCase() + " ";
}
} }
} }
questToGive = plugin.getQuest(name); }
if (questToGive == null) { questToGive = plugin.getQuest(name);
cs.sendMessage(ChatColor.YELLOW + Lang.get("questNotFound")); if (questToGive == null) {
} else { cs.sendMessage(ChatColor.YELLOW + Lang.get("questNotFound"));
Quester quester = plugin.getQuester(target.getUniqueId()); } else {
for (Quest q : quester.getCurrentQuests().keySet()) { Quester quester = plugin.getQuester(target.getUniqueId());
if (q.getName().equalsIgnoreCase(questToGive.getName())) { for (Quest q : quester.getCurrentQuests().keySet()) {
String msg = Lang.get("questsPlayerHasQuestAlready"); if (q.getName().equalsIgnoreCase(questToGive.getName())) {
msg = msg.replace("<player>", ChatColor.ITALIC + "" + ChatColor.GREEN + target.getName() String msg = Lang.get("questsPlayerHasQuestAlready");
+ ChatColor.RESET + ChatColor.YELLOW); msg = msg.replace("<player>", ChatColor.ITALIC + "" + ChatColor.GREEN + target.getName()
msg = msg.replace("<quest>", ChatColor.ITALIC + "" + ChatColor.DARK_PURPLE + ChatColor.RESET + ChatColor.YELLOW);
+ questToGive.getName() + ChatColor.RESET + ChatColor.YELLOW); msg = msg.replace("<quest>", ChatColor.ITALIC + "" + ChatColor.DARK_PURPLE
cs.sendMessage(ChatColor.YELLOW + msg); + questToGive.getName() + ChatColor.RESET + ChatColor.YELLOW);
return; cs.sendMessage(ChatColor.YELLOW + msg);
} return;
} }
quester.hardQuit(questToGive); }
String msg1 = Lang.get("questForceTake"); quester.hardQuit(questToGive);
msg1 = msg1.replace("<player>", ChatColor.GREEN + target.getName() + ChatColor.GOLD); String msg1 = Lang.get("questForceTake");
msg1 = msg1.replace("<quest>", ChatColor.DARK_PURPLE + questToGive.getName() + ChatColor.GOLD); msg1 = msg1.replace("<player>", ChatColor.GREEN + target.getName() + ChatColor.GOLD);
cs.sendMessage(ChatColor.GOLD + msg1); msg1 = msg1.replace("<quest>", ChatColor.DARK_PURPLE + questToGive.getName() + ChatColor.GOLD);
String msg2 = Lang.get(target, "questForcedTake"); cs.sendMessage(ChatColor.GOLD + msg1);
if (target.isOnline()) {
Player p = (Player)target;
String msg2 = Lang.get(p, "questForcedTake");
msg2 = msg2.replace("<player>", ChatColor.GREEN + cs.getName() + ChatColor.GOLD); msg2 = msg2.replace("<player>", ChatColor.GREEN + cs.getName() + ChatColor.GOLD);
msg2 = msg2.replace("<quest>", ChatColor.DARK_PURPLE + questToGive.getName() + ChatColor.GOLD); msg2 = msg2.replace("<quest>", ChatColor.DARK_PURPLE + questToGive.getName() + ChatColor.GOLD);
target.sendMessage(ChatColor.GREEN + msg2); p.sendMessage(ChatColor.GREEN + msg2);
quester.takeQuest(questToGive, true);
} }
quester.takeQuest(questToGive, true);
} }
} else { } else {
cs.sendMessage(ChatColor.RED + Lang.get("noPermission")); cs.sendMessage(ChatColor.RED + Lang.get("noPermission"));
@ -1474,7 +1482,7 @@ public class CmdExecutor implements CommandExecutor {
} }
/** /**
* Get a Player by name * Get an online Player by name
* *
* @param name Name of the player * @param name Name of the player
* @return Player or null if not found * @return Player or null if not found