001/* 002 * PlotSquared, a land and world management plugin for Minecraft. 003 * Copyright (C) IntellectualSites <https://intellectualsites.com> 004 * Copyright (C) IntellectualSites team and contributors 005 * 006 * This program is free software: you can redistribute it and/or modify 007 * it under the terms of the GNU General Public License as published by 008 * the Free Software Foundation, either version 3 of the License, or 009 * (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, 012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 014 * GNU General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program. If not, see <https://www.gnu.org/licenses/>. 018 */ 019package com.plotsquared.core.command; 020 021import com.google.inject.Inject; 022import com.plotsquared.core.configuration.Settings; 023import com.plotsquared.core.configuration.caption.TranslatableCaption; 024import com.plotsquared.core.database.DBFunc; 025import com.plotsquared.core.events.PlayerClaimPlotEvent; 026import com.plotsquared.core.events.PlotMergeEvent; 027import com.plotsquared.core.events.Result; 028import com.plotsquared.core.location.Direction; 029import com.plotsquared.core.location.Location; 030import com.plotsquared.core.permissions.Permission; 031import com.plotsquared.core.player.MetaDataAccess; 032import com.plotsquared.core.player.PlayerMetaDataKeys; 033import com.plotsquared.core.player.PlotPlayer; 034import com.plotsquared.core.plot.Plot; 035import com.plotsquared.core.plot.PlotArea; 036import com.plotsquared.core.util.EconHandler; 037import com.plotsquared.core.util.EventDispatcher; 038import com.plotsquared.core.util.PlotExpression; 039import com.plotsquared.core.util.task.TaskManager; 040import net.kyori.adventure.text.minimessage.Template; 041import org.apache.logging.log4j.LogManager; 042import org.apache.logging.log4j.Logger; 043import org.checkerframework.checker.nullness.qual.NonNull; 044 045@CommandDeclaration( 046 command = "claim", 047 aliases = "c", 048 category = CommandCategory.CLAIMING, 049 requiredType = RequiredType.PLAYER, permission = "plots.claim", 050 usage = "/plot claim") 051public class Claim extends SubCommand { 052 053 private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Claim.class.getSimpleName()); 054 055 private final EventDispatcher eventDispatcher; 056 private final EconHandler econHandler; 057 058 @Inject 059 public Claim( 060 final @NonNull EventDispatcher eventDispatcher, 061 final @NonNull EconHandler econHandler 062 ) { 063 this.eventDispatcher = eventDispatcher; 064 this.econHandler = econHandler; 065 } 066 067 @Override 068 public boolean onCommand(final PlotPlayer<?> player, String[] args) { 069 String schematic = null; 070 if (args.length >= 1) { 071 schematic = args[0]; 072 } 073 Location location = player.getLocation(); 074 Plot plot = location.getPlotAbs(); 075 if (plot == null) { 076 player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); 077 return false; 078 } 079 final PlayerClaimPlotEvent event = this.eventDispatcher.callClaim(player, plot, schematic); 080 schematic = event.getSchematic(); 081 if (event.getEventResult() == Result.DENY) { 082 player.sendMessage( 083 TranslatableCaption.of("events.event_denied"), 084 Template.of("value", "Claim") 085 ); 086 return true; 087 } 088 boolean force = event.getEventResult() == Result.FORCE; 089 int currentPlots = Settings.Limit.GLOBAL ? 090 player.getPlotCount() : 091 player.getPlotCount(location.getWorldName()); 092 093 final PlotArea area = plot.getArea(); 094 095 try (final MetaDataAccess<Integer> metaDataAccess = player.accessPersistentMetaData(PlayerMetaDataKeys.PERSISTENT_GRANTED_PLOTS)) { 096 int grants = 0; 097 if (currentPlots >= player.getAllowedPlots() && !force) { 098 if (metaDataAccess.isPresent()) { 099 grants = metaDataAccess.get().orElse(0); 100 if (grants <= 0) { 101 player.sendMessage( 102 TranslatableCaption.of("permission.cant_claim_more_plots"), 103 Template.of("amount", String.valueOf(grants)) 104 ); 105 metaDataAccess.remove(); 106 } 107 } else { 108 player.sendMessage( 109 TranslatableCaption.of("permission.cant_claim_more_plots"), 110 Template.of("amount", String.valueOf(player.getAllowedPlots())) 111 ); 112 return false; 113 } 114 } 115 116 if (!plot.canClaim(player)) { 117 player.sendMessage(TranslatableCaption.of("working.plot_is_claimed")); 118 return false; 119 } 120 if (schematic != null && !schematic.isEmpty()) { 121 if (area.isSchematicClaimSpecify()) { 122 if (!area.hasSchematic(schematic)) { 123 player.sendMessage( 124 TranslatableCaption.of("schematics.schematic_invalid_named"), 125 Template.of("schemname", schematic), 126 Template.of("reason", "non-existent") 127 ); 128 } 129 if (!player.hasPermission(Permission.PERMISSION_CLAIM_SCHEMATIC 130 .format(schematic)) && !player.hasPermission( 131 "plots.admin.command.schematic" 132 ) && !force) { 133 player.sendMessage( 134 TranslatableCaption.of("permission.no_schematic_permission"), 135 Template.of("value", schematic) 136 ); 137 } 138 } 139 } 140 if (this.econHandler.isEnabled(area) && !force) { 141 PlotExpression costExr = area.getPrices().get("claim"); 142 double cost = costExr.evaluate(currentPlots); 143 if (cost > 0d) { 144 if (!this.econHandler.isSupported()) { 145 player.sendMessage(TranslatableCaption.of("economy.vault_or_consumer_null")); 146 return false; 147 } 148 if (this.econHandler.getMoney(player) < cost) { 149 player.sendMessage( 150 TranslatableCaption.of("economy.cannot_afford_plot"), 151 Template.of("money", this.econHandler.format(cost)), 152 Template.of("balance", this.econHandler.format(this.econHandler.getMoney(player))) 153 ); 154 return false; 155 } 156 this.econHandler.withdrawMoney(player, cost); 157 player.sendMessage( 158 TranslatableCaption.of("economy.removed_balance"), 159 Template.of("money", this.econHandler.format(cost)), 160 Template.of("balance", this.econHandler.format(this.econHandler.getMoney(player))) 161 ); 162 } 163 } 164 if (grants > 0) { 165 if (grants == 1) { 166 metaDataAccess.remove(); 167 } else { 168 metaDataAccess.set(grants - 1); 169 } 170 player.sendMessage( 171 TranslatableCaption.of("economy.removed_granted_plot"), 172 Template.of("usedGrants", String.valueOf((grants - 1))), 173 Template.of("remainingGrants", String.valueOf(grants)) 174 ); 175 } 176 } 177 if (!player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) { 178 int border = area.getBorder(); 179 if (border != Integer.MAX_VALUE && plot.getDistanceFromOrigin() > border && !force) { 180 player.sendMessage(TranslatableCaption.of("border.denied")); 181 return false; 182 } 183 } 184 plot.setOwnerAbs(player.getUUID()); 185 final String finalSchematic = schematic; 186 DBFunc.createPlotSafe(plot, () -> { 187 try { 188 TaskManager.getPlatformImplementation().sync(() -> { 189 if (!plot.claim(player, true, finalSchematic, false, false)) { 190 LOGGER.info("Failed to claim plot {}", plot.getId().toCommaSeparatedString()); 191 player.sendMessage(TranslatableCaption.of("working.plot_not_claimed")); 192 plot.setOwnerAbs(null); 193 } else if (area.isAutoMerge()) { 194 PlotMergeEvent mergeEvent = Claim.this.eventDispatcher 195 .callMerge(plot, Direction.ALL, Integer.MAX_VALUE, player); 196 if (mergeEvent.getEventResult() == Result.DENY) { 197 player.sendMessage( 198 TranslatableCaption.of("events.event_denied"), 199 Template.of("value", "Auto merge on claim") 200 ); 201 } else { 202 if (plot.getPlotModificationManager().autoMerge( 203 mergeEvent.getDir(), 204 mergeEvent.getMax(), 205 player.getUUID(), 206 player, 207 true 208 )) { 209 eventDispatcher.callPostMerge(player, plot); 210 } 211 } 212 } 213 return null; 214 }); 215 } catch (final Exception e) { 216 e.printStackTrace(); 217 } 218 }, () -> { 219 LOGGER.info("Failed to add plot to database: {}", plot.getId().toCommaSeparatedString()); 220 player.sendMessage(TranslatableCaption.of("working.plot_not_claimed")); 221 plot.setOwnerAbs(null); 222 }); 223 return true; 224 } 225 226}