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.Templates; 024import com.plotsquared.core.configuration.caption.TranslatableCaption; 025import com.plotsquared.core.database.DBFunc; 026import com.plotsquared.core.permissions.Permission; 027import com.plotsquared.core.player.PlotPlayer; 028import com.plotsquared.core.plot.Plot; 029import com.plotsquared.core.util.EventDispatcher; 030import com.plotsquared.core.util.PlayerManager; 031import com.plotsquared.core.util.TabCompletions; 032import com.plotsquared.core.util.task.RunnableVal2; 033import com.plotsquared.core.util.task.RunnableVal3; 034import net.kyori.adventure.text.minimessage.Template; 035import org.checkerframework.checker.nullness.qual.NonNull; 036 037import java.util.Collection; 038import java.util.Collections; 039import java.util.Iterator; 040import java.util.UUID; 041import java.util.concurrent.CompletableFuture; 042import java.util.concurrent.TimeoutException; 043 044@CommandDeclaration(command = "trust", 045 aliases = {"t"}, 046 requiredType = RequiredType.PLAYER, 047 usage = "/plot trust <player | *>", 048 category = CommandCategory.SETTINGS) 049public class Trust extends Command { 050 051 private final EventDispatcher eventDispatcher; 052 053 @Inject 054 public Trust(final @NonNull EventDispatcher eventDispatcher) { 055 super(MainCommand.getInstance(), true); 056 this.eventDispatcher = eventDispatcher; 057 } 058 059 @Override 060 public CompletableFuture<Boolean> execute( 061 final PlotPlayer<?> player, String[] args, 062 RunnableVal3<Command, Runnable, Runnable> confirm, 063 RunnableVal2<Command, CommandResult> whenDone 064 ) throws CommandException { 065 final Plot currentPlot = player.getCurrentPlot(); 066 if (currentPlot == null) { 067 throw new CommandException(TranslatableCaption.of("errors.not_in_plot")); 068 } 069 checkTrue(currentPlot.hasOwner(), TranslatableCaption.of("info.plot_unowned")); 070 checkTrue( 071 currentPlot.isOwner(player.getUUID()) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST), 072 TranslatableCaption.of("permission.no_plot_perms") 073 ); 074 075 checkTrue(args.length == 1, TranslatableCaption.of("commandconfig.command_syntax"), 076 Templates.of("value", getUsage()) 077 ); 078 079 final CompletableFuture<Boolean> future = new CompletableFuture<>(); 080 PlayerManager.getUUIDsFromString(args[0], (uuids, throwable) -> { 081 if (throwable != null) { 082 if (throwable instanceof TimeoutException) { 083 player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout")); 084 } else { 085 player.sendMessage( 086 TranslatableCaption.of("errors.invalid_player"), 087 Template.of("value", args[0]) 088 ); 089 } 090 future.completeExceptionally(throwable); 091 return; 092 } else { 093 checkTrue(!uuids.isEmpty(), TranslatableCaption.of("errors.invalid_player"), 094 Templates.of("value", args[0]) 095 ); 096 097 Iterator<UUID> iterator = uuids.iterator(); 098 int size = currentPlot.getTrusted().size() + currentPlot.getMembers().size(); 099 while (iterator.hasNext()) { 100 UUID uuid = iterator.next(); 101 if (uuid == DBFunc.EVERYONE && !( 102 player.hasPermission(Permission.PERMISSION_TRUST_EVERYONE) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST))) { 103 player.sendMessage( 104 TranslatableCaption.of("errors.invalid_player"), 105 Template.of("value", PlayerManager.resolveName(uuid).getComponent(player)) 106 ); 107 iterator.remove(); 108 continue; 109 } 110 if (currentPlot.isOwner(uuid)) { 111 player.sendMessage( 112 TranslatableCaption.of("member.already_added"), 113 Template.of("value", PlayerManager.resolveName(uuid).getComponent(player)) 114 ); 115 iterator.remove(); 116 continue; 117 } 118 if (currentPlot.getTrusted().contains(uuid)) { 119 player.sendMessage( 120 TranslatableCaption.of("member.already_added"), 121 Template.of("value", PlayerManager.resolveName(uuid).getComponent(player)) 122 ); 123 iterator.remove(); 124 continue; 125 } 126 size += currentPlot.getMembers().contains(uuid) ? 0 : 1; 127 } 128 checkTrue(!uuids.isEmpty(), null); 129 int localTrustSize = currentPlot.getTrusted().size(); 130 int maxTrustSize = player.hasPermissionRange(Permission.PERMISSION_TRUST, Settings.Limit.MAX_PLOTS); 131 if (localTrustSize >= maxTrustSize) { 132 player.sendMessage( 133 TranslatableCaption.of("members.plot_max_members_trusted"), 134 Template.of("amount", String.valueOf(localTrustSize)) 135 ); 136 return; 137 } 138 // Success 139 confirm.run(this, () -> { 140 for (UUID uuid : uuids) { 141 if (uuid != DBFunc.EVERYONE) { 142 if (!currentPlot.removeMember(uuid)) { 143 if (currentPlot.getDenied().contains(uuid)) { 144 currentPlot.removeDenied(uuid); 145 } 146 } 147 } 148 currentPlot.addTrusted(uuid); 149 this.eventDispatcher.callTrusted(player, currentPlot, uuid, true); 150 player.sendMessage(TranslatableCaption.of("trusted.trusted_added")); 151 } 152 }, null); 153 } 154 future.complete(true); 155 }); 156 return CompletableFuture.completedFuture(true); 157 } 158 159 @Override 160 public Collection<Command> tab(final PlotPlayer<?> player, final String[] args, final boolean space) { 161 return TabCompletions.completePlayers(player, String.join(",", args).trim(), Collections.emptyList()); 162 } 163 164}