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.player;
020
021import com.google.inject.Inject;
022import com.plotsquared.core.PlotSquared;
023import com.plotsquared.core.command.RequiredType;
024import com.plotsquared.core.configuration.caption.Caption;
025import com.plotsquared.core.configuration.caption.CaptionUtility;
026import com.plotsquared.core.configuration.caption.TranslatableCaption;
027import com.plotsquared.core.database.DBFunc;
028import com.plotsquared.core.events.TeleportCause;
029import com.plotsquared.core.inject.annotations.ConsoleActor;
030import com.plotsquared.core.location.Location;
031import com.plotsquared.core.permissions.PermissionHandler;
032import com.plotsquared.core.plot.Plot;
033import com.plotsquared.core.plot.PlotArea;
034import com.plotsquared.core.plot.PlotWeather;
035import com.plotsquared.core.plot.world.PlotAreaManager;
036import com.plotsquared.core.plot.world.SinglePlotAreaManager;
037import com.plotsquared.core.util.EventDispatcher;
038import com.sk89q.worldedit.extension.platform.Actor;
039import com.sk89q.worldedit.regions.CuboidRegion;
040import com.sk89q.worldedit.world.gamemode.GameMode;
041import com.sk89q.worldedit.world.gamemode.GameModes;
042import com.sk89q.worldedit.world.item.ItemType;
043import net.kyori.adventure.audience.Audience;
044import net.kyori.adventure.text.minimessage.MiniMessage;
045import net.kyori.adventure.text.minimessage.Template;
046import org.checkerframework.checker.nullness.qual.NonNull;
047
048import java.util.UUID;
049
050public class ConsolePlayer extends PlotPlayer<Actor> {
051
052    private static final MiniMessage MINI_MESSAGE = MiniMessage.builder().build();
053    private static ConsolePlayer instance;
054
055    private final Actor actor;
056
057    @Inject
058    private ConsolePlayer(
059            final @NonNull PlotAreaManager plotAreaManager,
060            final @NonNull EventDispatcher eventDispatcher,
061            @ConsoleActor final @NonNull Actor actor,
062            final @NonNull PermissionHandler permissionHandler
063    ) {
064        super(plotAreaManager, eventDispatcher, permissionHandler);
065        this.actor = actor;
066        this.setupPermissionProfile();
067        final PlotArea[] areas = plotAreaManager.getAllPlotAreas();
068        final PlotArea area;
069        if (areas.length > 0) {
070            area = areas[0];
071        } else {
072            area = null;
073        }
074        Location location;
075        if (area != null && !(plotAreaManager instanceof SinglePlotAreaManager)) {
076            CuboidRegion region = area.getRegion();
077            location = Location.at(area.getWorldName(),
078                    region.getMinimumPoint().getX() + region.getMaximumPoint().getX() / 2, 0,
079                    region.getMinimumPoint().getZ() + region.getMaximumPoint().getZ() / 2
080            );
081        } else {
082            location = Location.at("", 0, 0, 0);
083        }
084        setMeta("location", location);
085    }
086
087    public static ConsolePlayer getConsole() {
088        if (instance == null) {
089            instance = PlotSquared.platform().injector().getInstance(ConsolePlayer.class);
090            instance.teleport(instance.getLocation());
091        }
092        return instance;
093    }
094
095    @Override
096    public Actor toActor() {
097        return this.actor;
098    }
099
100    @Override
101    public Actor getPlatformPlayer() {
102        return this.toActor();
103    }
104
105    @Override
106    public boolean canTeleport(@NonNull Location location) {
107        return true;
108    }
109
110    @Override
111    public void sendTitle(
112            final @NonNull Caption title, final @NonNull Caption subtitle,
113            final int fadeIn, final int stay, final int fadeOut, final @NonNull Template... replacements
114    ) {
115    }
116
117    @NonNull
118    @Override
119    public Location getLocation() {
120        return this.getMeta("location");
121    }
122
123    @Override
124    public Location getLocationFull() {
125        return getLocation();
126    }
127
128    @NonNull
129    @Override
130    public UUID getUUID() {
131        return DBFunc.EVERYONE;
132    }
133
134    @Override
135    public long getLastPlayed() {
136        return System.currentTimeMillis();
137    }
138
139    @Override
140    public boolean hasPermission(@NonNull String permission) {
141        return true;
142    }
143
144    @Override
145    public void sendMessage(
146            final @NonNull Caption caption,
147            final @NonNull Template... replacements
148    ) {
149        String message = caption.getComponent(this);
150        if (message.isEmpty()) {
151            return;
152        }
153        message = CaptionUtility.format(this, message)
154                .replace('\u2010', '%').replace('\u2020', '&').replace('\u2030', '&')
155                .replace("<prefix>", TranslatableCaption.of("core.prefix").getComponent(this));
156        // Parse the message
157        PlotSquared.platform().consoleAudience().sendMessage(MINI_MESSAGE.parse(message, replacements));
158    }
159
160    @Override
161    public void teleport(Location location, TeleportCause cause) {
162        try (final MetaDataAccess<Plot> lastPlot = accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
163            if (location.getPlot() == null) {
164                lastPlot.remove();
165            } else {
166                lastPlot.set(location.getPlot());
167            }
168        }
169        try (final MetaDataAccess<Location> locationMetaDataAccess = accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LOCATION)) {
170            locationMetaDataAccess.set(location);
171        }
172    }
173
174    @Override
175    public String getName() {
176        return "*";
177    }
178
179    @Override
180    public void setCompassTarget(Location location) {
181    }
182
183    @Override
184    public void setAttribute(String key) {
185    }
186
187    @Override
188    public boolean getAttribute(String key) {
189        return false;
190    }
191
192    @Override
193    public void removeAttribute(String key) {
194    }
195
196    @Override
197    public @NonNull RequiredType getSuperCaller() {
198        return RequiredType.CONSOLE;
199    }
200
201    @Override
202    public void setWeather(@NonNull PlotWeather weather) {
203    }
204
205    @Override
206    public @NonNull GameMode getGameMode() {
207        return GameModes.SPECTATOR;
208    }
209
210    @Override
211    public void setGameMode(@NonNull GameMode gameMode) {
212    }
213
214    @Override
215    public void setTime(long time) {
216    }
217
218    @Override
219    public boolean getFlight() {
220        return true;
221    }
222
223    @Override
224    public void setFlight(boolean fly) {
225    }
226
227    @Override
228    public void playMusic(@NonNull Location location, @NonNull ItemType id) {
229    }
230
231    @Override
232    public void kick(String message) {
233    }
234
235    @Override
236    public void stopSpectating() {
237    }
238
239    @Override
240    public boolean isBanned() {
241        return false;
242    }
243
244    @Override
245    public @NonNull Audience getAudience() {
246        return PlotSquared.platform().consoleAudience();
247    }
248
249    @Override
250    public void removeEffect(@NonNull String name) {
251    }
252
253    @Override
254    public boolean canSee(final PlotPlayer<?> other) {
255        return true;
256    }
257
258}