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.plot.flag;
020
021import com.google.common.base.Preconditions;
022import com.plotsquared.core.plot.flag.implementations.AnalysisFlag;
023import com.plotsquared.core.plot.flag.implementations.AnimalAttackFlag;
024import com.plotsquared.core.plot.flag.implementations.AnimalCapFlag;
025import com.plotsquared.core.plot.flag.implementations.AnimalInteractFlag;
026import com.plotsquared.core.plot.flag.implementations.BeaconEffectsFlag;
027import com.plotsquared.core.plot.flag.implementations.BlockBurnFlag;
028import com.plotsquared.core.plot.flag.implementations.BlockIgnitionFlag;
029import com.plotsquared.core.plot.flag.implementations.BlockedCmdsFlag;
030import com.plotsquared.core.plot.flag.implementations.BreakFlag;
031import com.plotsquared.core.plot.flag.implementations.ChatFlag;
032import com.plotsquared.core.plot.flag.implementations.ConcreteHardenFlag;
033import com.plotsquared.core.plot.flag.implementations.CopperOxideFlag;
034import com.plotsquared.core.plot.flag.implementations.CoralDryFlag;
035import com.plotsquared.core.plot.flag.implementations.CropGrowFlag;
036import com.plotsquared.core.plot.flag.implementations.DenyExitFlag;
037import com.plotsquared.core.plot.flag.implementations.DenyPortalTravelFlag;
038import com.plotsquared.core.plot.flag.implementations.DenyPortalsFlag;
039import com.plotsquared.core.plot.flag.implementations.DenyTeleportFlag;
040import com.plotsquared.core.plot.flag.implementations.DescriptionFlag;
041import com.plotsquared.core.plot.flag.implementations.DeviceInteractFlag;
042import com.plotsquared.core.plot.flag.implementations.DisablePhysicsFlag;
043import com.plotsquared.core.plot.flag.implementations.DoneFlag;
044import com.plotsquared.core.plot.flag.implementations.DropProtectionFlag;
045import com.plotsquared.core.plot.flag.implementations.EditSignFlag;
046import com.plotsquared.core.plot.flag.implementations.EntityCapFlag;
047import com.plotsquared.core.plot.flag.implementations.EntityChangeBlockFlag;
048import com.plotsquared.core.plot.flag.implementations.ExplosionFlag;
049import com.plotsquared.core.plot.flag.implementations.FarewellFlag;
050import com.plotsquared.core.plot.flag.implementations.FeedFlag;
051import com.plotsquared.core.plot.flag.implementations.FishingFlag;
052import com.plotsquared.core.plot.flag.implementations.FlyFlag;
053import com.plotsquared.core.plot.flag.implementations.ForcefieldFlag;
054import com.plotsquared.core.plot.flag.implementations.GamemodeFlag;
055import com.plotsquared.core.plot.flag.implementations.GrassGrowFlag;
056import com.plotsquared.core.plot.flag.implementations.GreetingFlag;
057import com.plotsquared.core.plot.flag.implementations.GuestGamemodeFlag;
058import com.plotsquared.core.plot.flag.implementations.HangingBreakFlag;
059import com.plotsquared.core.plot.flag.implementations.HangingPlaceFlag;
060import com.plotsquared.core.plot.flag.implementations.HealFlag;
061import com.plotsquared.core.plot.flag.implementations.HideInfoFlag;
062import com.plotsquared.core.plot.flag.implementations.HostileAttackFlag;
063import com.plotsquared.core.plot.flag.implementations.HostileCapFlag;
064import com.plotsquared.core.plot.flag.implementations.HostileInteractFlag;
065import com.plotsquared.core.plot.flag.implementations.IceFormFlag;
066import com.plotsquared.core.plot.flag.implementations.IceMeltFlag;
067import com.plotsquared.core.plot.flag.implementations.InstabreakFlag;
068import com.plotsquared.core.plot.flag.implementations.InteractionInteractFlag;
069import com.plotsquared.core.plot.flag.implementations.InvincibleFlag;
070import com.plotsquared.core.plot.flag.implementations.ItemDropFlag;
071import com.plotsquared.core.plot.flag.implementations.KeepFlag;
072import com.plotsquared.core.plot.flag.implementations.KeepInventoryFlag;
073import com.plotsquared.core.plot.flag.implementations.KelpGrowFlag;
074import com.plotsquared.core.plot.flag.implementations.LeafDecayFlag;
075import com.plotsquared.core.plot.flag.implementations.LecternReadBookFlag;
076import com.plotsquared.core.plot.flag.implementations.LiquidFlowFlag;
077import com.plotsquared.core.plot.flag.implementations.MiscBreakFlag;
078import com.plotsquared.core.plot.flag.implementations.MiscCapFlag;
079import com.plotsquared.core.plot.flag.implementations.MiscInteractFlag;
080import com.plotsquared.core.plot.flag.implementations.MiscPlaceFlag;
081import com.plotsquared.core.plot.flag.implementations.MobBreakFlag;
082import com.plotsquared.core.plot.flag.implementations.MobCapFlag;
083import com.plotsquared.core.plot.flag.implementations.MobPlaceFlag;
084import com.plotsquared.core.plot.flag.implementations.MusicFlag;
085import com.plotsquared.core.plot.flag.implementations.MycelGrowFlag;
086import com.plotsquared.core.plot.flag.implementations.NoWorldeditFlag;
087import com.plotsquared.core.plot.flag.implementations.NotifyEnterFlag;
088import com.plotsquared.core.plot.flag.implementations.NotifyLeaveFlag;
089import com.plotsquared.core.plot.flag.implementations.PlaceFlag;
090import com.plotsquared.core.plot.flag.implementations.PlayerInteractFlag;
091import com.plotsquared.core.plot.flag.implementations.PlotTitleFlag;
092import com.plotsquared.core.plot.flag.implementations.PreventCreativeCopyFlag;
093import com.plotsquared.core.plot.flag.implementations.PriceFlag;
094import com.plotsquared.core.plot.flag.implementations.ProjectileChangeBlockFlag;
095import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag;
096import com.plotsquared.core.plot.flag.implementations.WeavingDeathPlace;
097import com.plotsquared.core.plot.flag.implementations.PveFlag;
098import com.plotsquared.core.plot.flag.implementations.PvpFlag;
099import com.plotsquared.core.plot.flag.implementations.RedstoneFlag;
100import com.plotsquared.core.plot.flag.implementations.SculkSensorInteractFlag;
101import com.plotsquared.core.plot.flag.implementations.ServerPlotFlag;
102import com.plotsquared.core.plot.flag.implementations.SnowFormFlag;
103import com.plotsquared.core.plot.flag.implementations.SnowMeltFlag;
104import com.plotsquared.core.plot.flag.implementations.SoilDryFlag;
105import com.plotsquared.core.plot.flag.implementations.TamedAttackFlag;
106import com.plotsquared.core.plot.flag.implementations.TamedInteractFlag;
107import com.plotsquared.core.plot.flag.implementations.TileDropFlag;
108import com.plotsquared.core.plot.flag.implementations.TimeFlag;
109import com.plotsquared.core.plot.flag.implementations.TitlesFlag;
110import com.plotsquared.core.plot.flag.implementations.UntrustedVisitFlag;
111import com.plotsquared.core.plot.flag.implementations.UseFlag;
112import com.plotsquared.core.plot.flag.implementations.VehicleBreakFlag;
113import com.plotsquared.core.plot.flag.implementations.VehicleCapFlag;
114import com.plotsquared.core.plot.flag.implementations.VehiclePlaceFlag;
115import com.plotsquared.core.plot.flag.implementations.VehicleUseFlag;
116import com.plotsquared.core.plot.flag.implementations.VillagerInteractFlag;
117import com.plotsquared.core.plot.flag.implementations.VineGrowFlag;
118import com.plotsquared.core.plot.flag.implementations.WeatherFlag;
119import org.checkerframework.checker.nullness.qual.NonNull;
120
121import java.util.Collections;
122import java.util.HashMap;
123import java.util.Locale;
124import java.util.Map;
125
126public final class GlobalFlagContainer extends FlagContainer {
127
128    private static GlobalFlagContainer instance;
129    private static Map<String, Class<?>> stringClassMap;
130
131    private GlobalFlagContainer() {
132        super(null, (flag, type) -> {
133            if (type == PlotFlagUpdateType.FLAG_ADDED) {
134                stringClassMap.put(flag.getName().toLowerCase(Locale.ENGLISH), flag.getClass());
135            }
136        });
137        stringClassMap = new HashMap<>();
138
139        // Register all default flags here
140        // Block type list flags
141        this.addFlag(BreakFlag.BREAK_NONE);
142        this.addFlag(UseFlag.USE_NONE);
143        this.addFlag(PlaceFlag.PLACE_NONE);
144
145        // Boolean flags
146        this.addFlag(AnimalAttackFlag.ANIMAL_ATTACK_FALSE);
147        this.addFlag(AnimalInteractFlag.ANIMAL_INTERACT_FALSE);
148        this.addFlag(BlockBurnFlag.BLOCK_BURN_FALSE);
149        this.addFlag(BeaconEffectsFlag.BEACON_EFFECT_TRUE);
150        this.addFlag(BlockIgnitionFlag.BLOCK_IGNITION_TRUE);
151        this.addFlag(ChatFlag.CHAT_FLAG_TRUE);
152        this.addFlag(ConcreteHardenFlag.CONCRETE_HARDEN_TRUE);
153        this.addFlag(CopperOxideFlag.COPPER_OXIDE_FALSE);
154        this.addFlag(CoralDryFlag.CORAL_DRY_FALSE);
155        this.addFlag(CropGrowFlag.CROP_GROW_TRUE);
156        this.addFlag(DenyExitFlag.DENY_EXIT_FLAG_FALSE);
157        this.addFlag(DenyPortalsFlag.DENY_PORTALS_FALSE);
158        this.addFlag(DenyPortalTravelFlag.DENY_PORTAL_TRAVEL_FALSE);
159        this.addFlag(DeviceInteractFlag.DEVICE_INTERACT_FALSE);
160        this.addFlag(DisablePhysicsFlag.DISABLE_PHYSICS_FALSE);
161        this.addFlag(DropProtectionFlag.DROP_PROTECTION_FALSE);
162        this.addFlag(EditSignFlag.EDIT_SIGN_FALSE);
163        this.addFlag(EntityChangeBlockFlag.ENTITY_CHANGE_BLOCK_FALSE);
164        this.addFlag(ExplosionFlag.EXPLOSION_FALSE);
165        this.addFlag(FishingFlag.FISHING_FALSE);
166        this.addFlag(ForcefieldFlag.FORCEFIELD_FALSE);
167        this.addFlag(GrassGrowFlag.GRASS_GROW_TRUE);
168        this.addFlag(HangingBreakFlag.HANGING_BREAK_FALSE);
169        this.addFlag(HangingPlaceFlag.HANGING_PLACE_FALSE);
170        this.addFlag(HideInfoFlag.HIDE_INFO_FALSE);
171        this.addFlag(HostileAttackFlag.HOSTILE_ATTACK_FALSE);
172        this.addFlag(HostileInteractFlag.HOSTILE_INTERACT_FALSE);
173        this.addFlag(IceFormFlag.ICE_FORM_FALSE);
174        this.addFlag(IceMeltFlag.ICE_MELT_FALSE);
175        this.addFlag(InstabreakFlag.INSTABREAK_FALSE);
176        this.addFlag(InteractionInteractFlag.INTERACTION_INTERACT_FALSE);
177        this.addFlag(InvincibleFlag.INVINCIBLE_FALSE);
178        this.addFlag(ItemDropFlag.ITEM_DROP_TRUE);
179        this.addFlag(KeepInventoryFlag.KEEP_INVENTORY_FALSE);
180        this.addFlag(KelpGrowFlag.KELP_GROW_TRUE);
181        this.addFlag(LeafDecayFlag.LEAF_DECAY_TRUE);
182        this.addFlag(LecternReadBookFlag.LECTERN_READ_BOOK_FALSE);
183        this.addFlag(MiscBreakFlag.MISC_BREAK_FALSE);
184        this.addFlag(MobBreakFlag.MOB_BREAK_FALSE);
185        this.addFlag(MobPlaceFlag.MOB_PLACE_FALSE);
186        this.addFlag(MiscInteractFlag.MISC_INTERACT_FALSE);
187        this.addFlag(SculkSensorInteractFlag.SCULK_SENSOR_INTERACT_FALSE);
188        this.addFlag(MiscPlaceFlag.MISC_PLACE_FALSE);
189        this.addFlag(MycelGrowFlag.MYCEL_GROW_TRUE);
190        this.addFlag(NotifyEnterFlag.NOTIFY_ENTER_FALSE);
191        this.addFlag(NotifyLeaveFlag.NOTIFY_LEAVE_FALSE);
192        this.addFlag(NoWorldeditFlag.NO_WORLDEDIT_FALSE);
193        this.addFlag(PlayerInteractFlag.PLAYER_INTERACT_FALSE);
194        this.addFlag(PreventCreativeCopyFlag.PREVENT_CREATIVE_COPY_FALSE);
195        this.addFlag(ProjectileChangeBlockFlag.PROJECTILE_CHANGE_BLOCK_FALSE);
196        this.addFlag(PveFlag.PVE_FALSE);
197        this.addFlag(PvpFlag.PVP_FALSE);
198        this.addFlag(RedstoneFlag.REDSTONE_TRUE);
199        this.addFlag(ServerPlotFlag.SERVER_PLOT_FALSE);
200        this.addFlag(SnowFormFlag.SNOW_FORM_FALSE);
201        this.addFlag(SnowMeltFlag.SNOW_MELT_TRUE);
202        this.addFlag(SoilDryFlag.SOIL_DRY_FALSE);
203        this.addFlag(TamedAttackFlag.TAMED_ATTACK_FALSE);
204        this.addFlag(TamedInteractFlag.TAMED_INTERACT_FALSE);
205        this.addFlag(TileDropFlag.TILE_DROP_TRUE);
206        this.addFlag(UntrustedVisitFlag.UNTRUSTED_VISIT_FLAG_TRUE);
207        this.addFlag(VehicleBreakFlag.VEHICLE_BREAK_FALSE);
208        this.addFlag(VehiclePlaceFlag.VEHICLE_PLACE_FALSE);
209        this.addFlag(VehicleUseFlag.VEHICLE_USE_FALSE);
210        this.addFlag(VillagerInteractFlag.VILLAGER_INTERACT_FALSE);
211        this.addFlag(VineGrowFlag.VINE_GROW_TRUE);
212        this.addFlag(ProjectilesFlag.PROJECTILES_FALSE);
213        this.addFlag(WeavingDeathPlace.WEAVING_DEATH_PLACE_FALSE);
214
215        // Double flags
216        this.addFlag(PriceFlag.PRICE_NOT_BUYABLE);
217
218        // Enum Flags
219        this.addFlag(DenyTeleportFlag.DENY_TELEPORT_FLAG_NONE);
220        this.addFlag(FlyFlag.FLIGHT_FLAG_DEFAULT);
221        this.addFlag(LiquidFlowFlag.LIQUID_FLOW_DEFAULT);
222        this.addFlag(TitlesFlag.TITLES_NONE);
223        this.addFlag(WeatherFlag.PLOT_WEATHER_FLAG_OFF);
224
225        // Internal flags
226        this.addFlag(new AnalysisFlag(Collections.emptyList()));
227        this.addFlag(new DoneFlag(""));
228
229        // Integer flags
230        this.addFlag(AnimalCapFlag.ANIMAL_CAP_UNLIMITED);
231        this.addFlag(EntityCapFlag.ENTITY_CAP_UNLIMITED);
232        this.addFlag(HostileCapFlag.HOSTILE_CAP_UNLIMITED);
233        this.addFlag(MiscCapFlag.MISC_CAP_UNLIMITED);
234        this.addFlag(MobCapFlag.MOB_CAP_UNLIMITED);
235        this.addFlag(TimeFlag.TIME_DISABLED);
236        this.addFlag(VehicleCapFlag.VEHICLE_CAP_UNLIMITED);
237
238        // Misc
239        this.addFlag(BlockedCmdsFlag.BLOCKED_CMDS_FLAG_NONE);
240        this.addFlag(GamemodeFlag.GAMEMODE_FLAG_DEFAULT);
241        this.addFlag(GuestGamemodeFlag.GUEST_GAMEMODE_FLAG_DEFAULT);
242        this.addFlag(KeepFlag.KEEP_FLAG_FALSE);
243        this.addFlag(MusicFlag.MUSIC_FLAG_NONE);
244
245        // String flags
246        this.addFlag(DescriptionFlag.DESCRIPTION_FLAG_EMPTY);
247        this.addFlag(GreetingFlag.GREETING_FLAG_EMPTY);
248        this.addFlag(FarewellFlag.FAREWELL_FLAG_EMPTY);
249        this.addFlag(PlotTitleFlag.TITLE_FLAG_DEFAULT);
250
251        // Timed flags
252        this.addFlag(FeedFlag.FEED_NOTHING);
253        this.addFlag(HealFlag.HEAL_NOTHING);
254    }
255
256    public static void setup() {
257        Preconditions.checkState(instance == null, "Cannot setup the container twice");
258        instance = new GlobalFlagContainer();
259    }
260
261    public static GlobalFlagContainer getInstance() {
262        return GlobalFlagContainer.instance;
263    }
264
265    @Override
266    public PlotFlag<?, ?> getFlagErased(Class<?> flagClass) {
267        final PlotFlag<?, ?> flag = super.getFlagErased(flagClass);
268        if (flag != null) {
269            return flag;
270        } else {
271            throw new IllegalStateException(String.format("Unrecognized flag '%s'. All flag types"
272                    + " must be present in the global flag container.", flagClass.getSimpleName()));
273        }
274    }
275
276    @NonNull
277    @Override
278    public <V, T extends PlotFlag<V, ?>> T getFlag(Class<? extends T> flagClass) {
279        final PlotFlag<?, ?> flag = super.getFlag(flagClass);
280        if (flag != null) {
281            return castUnsafe(flag);
282        } else {
283            throw new IllegalStateException(String.format("Unrecognized flag '%s'. All flag types"
284                    + " must be present in the global flag container.", flagClass.getSimpleName()));
285        }
286    }
287
288    public Class<?> getFlagClassFromString(final String name) {
289        return stringClassMap.get(name.toLowerCase(Locale.ENGLISH));
290    }
291
292    public PlotFlag<?, ?> getFlagFromString(final String name) {
293        final Class<?> flagClass = this.getFlagClassFromString(name);
294        if (flagClass == null) {
295            return null;
296        }
297        return getFlagErased(flagClass);
298    }
299
300}