/* * CommandBook * Copyright (C) 2012 sk89q <http://www.sk89q.com> * * 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 <http://www.gnu.org/licenses/>. */ package com.sk89q.commandbook; import com.google.common.collect.Lists; import com.sk89q.commandbook.util.ChatUtil; import com.sk89q.commandbook.util.InputUtil; import com.sk89q.commandbook.util.entity.player.PlayerUtil; import com.sk89q.minecraft.util.commands.Command; import com.sk89q.minecraft.util.commands.CommandContext; import com.sk89q.minecraft.util.commands.CommandException; import com.zachsthings.libcomponents.ComponentInformation; import com.zachsthings.libcomponents.bukkit.BukkitComponent; import com.zachsthings.libcomponents.config.ConfigurationBase; import com.zachsthings.libcomponents.config.Setting; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; import org.bukkit.event.entity.EntityCombustEvent; import org.bukkit.event.entity.EntityDamageEvent; import org.bukkit.event.entity.FoodLevelChangeEvent; import org.bukkit.event.player.PlayerChangedWorldEvent; import org.bukkit.event.player.PlayerJoinEvent; import org.bukkit.metadata.FixedMetadataValue; import org.bukkit.metadata.MetadataValue; import java.util.List; @ComponentInformation(friendlyName = "God", desc = "God mode support") public class GodComponent extends BukkitComponent implements Listener { /** * God status is stored in player metadata with this key */ public static final String METADATA_KEY = "god"; private LocalConfiguration config; @Override public void enable() { config = configure(new LocalConfiguration()); registerCommands(Commands.class); // Check god mode for existing players, if any for (Player player : CommandBook.server().getOnlinePlayers()) { checkAutoEnable(player); } CommandBook.registerEvents(this); } @Override public void reload() { super.reload(); config = configure(config); // Check god mode for existing players, if any for (Player player : CommandBook.server().getOnlinePlayers()) { checkAutoEnable(player); } } private static class LocalConfiguration extends ConfigurationBase { @Setting("auto-enable") public boolean autoEnable = false; } /** * Enable god mode for a player. * * @param player The player to enable godmode for */ public void enableGodMode(Player player) { if (!hasGodMode(player)) { player.setMetadata(METADATA_KEY, new FixedMetadataValue(CommandBook.inst(), true)); } } /** * Disable god mode for a player. * * @param player The player to disable godmode for */ public void disableGodMode(Player player) { player.removeMetadata(METADATA_KEY, CommandBook.inst()); } /** * Check to see if god mode is enabled for a player. * * @param player The player to check * @return Whether the player has godmode */ public boolean hasGodMode(Player player) { List<MetadataValue> values = player.getMetadata(METADATA_KEY); switch (values.size()) { case 0: return false; case 1: return values.get(0).asBoolean(); default: for (MetadataValue val : values) { if (val.asBoolean()) { return true; } } return false; } } @EventHandler public void onJoin(PlayerJoinEvent event) { checkAutoEnable(event.getPlayer()); } private boolean checkAutoEnable(Player player) { if (config.autoEnable && (CommandBook.inst().getPermissionsResolver() .inGroup(player, "cb-invincible") || CommandBook.inst().hasPermission(player, "commandbook.god.auto-invincible"))) { enableGodMode(player); return true; } return false; } /** * Called on entity combust. */ @EventHandler public void onCombust(EntityCombustEvent event) { if (event.isCancelled()) { return; } if (event.getEntity() instanceof Player) { Player player = (Player) event.getEntity(); if (hasGodMode(player)) { event.setCancelled(true); player.setFireTicks(0); } } } @EventHandler public void onDamage(EntityDamageEvent event) { if (event.isCancelled()) { return; } if (event.getEntity() instanceof Player) { Player player = (Player) event.getEntity(); if (hasGodMode(player)) { event.setCancelled(true); player.setFireTicks(0); } } } @EventHandler public void playerChangedWorld(PlayerChangedWorldEvent event) { if (!CommandBook.inst().hasPermission(event.getPlayer(), "commandbook.god")) { disableGodMode(event.getPlayer()); } } @EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true) public void foodLevelChange(FoodLevelChangeEvent event) { if (event.getEntity() instanceof Player) { Player player = (Player) event.getEntity(); if (event.getFoodLevel() < player.getFoodLevel() && hasGodMode(player)) { event.setCancelled(true); } } } @EventHandler public void playerWhois(InfoComponent.PlayerWhoisEvent event) { if (event.getPlayer() instanceof Player) { if (CommandBook.inst().hasPermission(event.getSource(), "commandbook.god.check")) { event.addWhoisInformation(null, "Player " + (hasGodMode((Player) event.getPlayer()) ? "has" : "does not have") + " god mode"); } } } public class Commands { @Command(aliases = {"god"}, usage = "[player]", desc = "Enable godmode on a player", flags = "s", max = 1) public void god(CommandContext args, CommandSender sender) throws CommandException { Iterable<Player> targets = null; boolean included = false; // Detect arguments based on the number of arguments provided if (args.argsLength() == 0) { targets = Lists.newArrayList(PlayerUtil.checkPlayer(sender)); } else if (args.argsLength() == 1) { targets = InputUtil.PlayerParser.matchPlayers(sender, args.getString(0)); } // Check permissions! for (Player player : targets) { if (player == sender) { CommandBook.inst().checkPermission(sender, "commandbook.god"); } else { CommandBook.inst().checkPermission(sender, "commandbook.god.other"); break; } } for (Player player : targets) { if (!hasGodMode(player)) { enableGodMode(player); player.setFireTicks(0); } else { if (player == sender) { player.sendMessage(ChatColor.RED + "You already have god mode!"); included = true; } else { sender.sendMessage(ChatColor.RED + player.getName() + " already has god mode!"); } continue; } // Tell the user if (player.equals(sender)) { player.sendMessage(ChatColor.YELLOW + "God mode enabled! Use /ungod to disable."); // Keep track of this included = true; } else { if (!args.hasFlag('s')) player.sendMessage(ChatColor.YELLOW + "God enabled by " + ChatUtil.toColoredName(sender, ChatColor.YELLOW) + "."); } } // The player didn't receive any items, then we need to send the // user a message so s/he know that something is indeed working if (!included) { sender.sendMessage(ChatColor.YELLOW.toString() + "Players now have god mode."); } } @Command(aliases = {"ungod"}, usage = "[player]", desc = "Disable godmode on a player", flags = "s", max = 1) public void ungod(CommandContext args, CommandSender sender) throws CommandException { Iterable<Player> targets = null; boolean included = false; // Detect arguments based on the number of arguments provided if (args.argsLength() == 0) { targets = Lists.newArrayList(PlayerUtil.checkPlayer(sender)); } else if (args.argsLength() == 1) { targets = InputUtil.PlayerParser.matchPlayers(sender, args.getString(0)); } // Check permissions! for (Player player : targets) { if (player == sender) { CommandBook.inst().checkPermission(sender, "commandbook.god"); } else { CommandBook.inst().checkPermission(sender, "commandbook.god.other"); break; } } for (Player player : targets) { if (hasGodMode(player)) { disableGodMode(player); } else { if (player == sender) { player.sendMessage(ChatColor.RED + "You do not have god mode enabled!"); included = true; } else { sender.sendMessage(ChatColor.RED + player.getName() + " did not have god mode enabled!"); } continue; } // Tell the user if (player.equals(sender)) { player.sendMessage(ChatColor.YELLOW + "God mode disabled!"); // Keep track of this included = true; } else { player.sendMessage(ChatColor.YELLOW + "God disabled by " + ChatUtil.toColoredName(sender, ChatColor.YELLOW) + "."); } } // The player didn't receive any items, then we need to send the // user a message so s/he know that something is indeed working if (!included) { sender.sendMessage(ChatColor.YELLOW.toString() + "Players no longer have god mode."); } } } }