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