· 4 years ago · Apr 03, 2021, 04:00 PM
1package me.drawethree.ultraprisoncore.enchants;
2
3import lombok.Getter;
4import lombok.NonNull;
5import me.drawethree.ultraprisoncore.UltraPrisonCore;
6import me.drawethree.ultraprisoncore.UltraPrisonModule;
7import me.drawethree.ultraprisoncore.config.FileManager;
8import me.drawethree.ultraprisoncore.enchants.api.UltraPrisonEnchantsAPI;
9import me.drawethree.ultraprisoncore.enchants.api.UltraPrisonEnchantsAPIImpl;
10import me.drawethree.ultraprisoncore.enchants.enchants.UltraPrisonEnchantment;
11import me.drawethree.ultraprisoncore.enchants.enchants.implementations.LuckyBoosterEnchant;
12import me.drawethree.ultraprisoncore.enchants.gui.DisenchantGUI;
13import me.drawethree.ultraprisoncore.enchants.gui.EnchantGUI;
14import me.drawethree.ultraprisoncore.enchants.managers.EnchantsManager;
15import me.drawethree.ultraprisoncore.utils.compat.CompMaterial;
16import me.lucko.helper.Commands;
17import me.lucko.helper.Events;
18import me.lucko.helper.Schedulers;
19import me.lucko.helper.cooldown.Cooldown;
20import me.lucko.helper.cooldown.CooldownMap;
21import me.lucko.helper.event.filter.EventFilters;
22import me.lucko.helper.text.Text;
23import me.lucko.helper.utils.Players;
24import org.bukkit.GameMode;
25import org.bukkit.entity.Player;
26import org.bukkit.event.EventPriority;
27import org.bukkit.event.block.Action;
28import org.bukkit.event.block.BlockBreakEvent;
29import org.bukkit.event.player.PlayerInteractEvent;
30import org.bukkit.inventory.ItemStack;
31import org.codemc.worldguardwrapper.WorldGuardWrapper;
32
33import java.util.ArrayList;
34import java.util.HashMap;
35import java.util.List;
36import java.util.UUID;
37import java.util.concurrent.TimeUnit;
38
39public final class UltraPrisonEnchants implements UltraPrisonModule {
40
41    @Getter
42    private static UltraPrisonEnchants instance;
43    private final HashMap<UUID, ItemStack> currentPickaxes = new HashMap<>();
44
45    @Getter
46    private UltraPrisonEnchantsAPI api;
47
48    @Getter
49    private EnchantsManager enchantsManager;
50
51    @Getter
52    private FileManager.Config config;
53
54    @Getter
55    private UltraPrisonCore core;
56
57    private HashMap<String, String> messages;
58    private List<UUID> disabledLayer = new ArrayList<>();
59    private List<UUID> disabledExplosive = new ArrayList<>();
60    private CooldownMap<Player> valueCooldown = CooldownMap.create(Cooldown.of(30, TimeUnit.SECONDS));
61    private boolean enabled;
62
63    public UltraPrisonEnchants(UltraPrisonCore UltraPrisonCore) {
64        instance = this;
65        this.core = UltraPrisonCore;
66    }
67
68    @Override
69    public boolean isEnabled() {
70        return enabled;
71    }
72
73    @Override
74    public void reload() {
75
76        this.config.reload();
77
78        this.loadMessages();
79        this.enchantsManager.reload();
80
81        UltraPrisonEnchantment.reloadAll();
82    }
83
84    private void loadMessages() {
85        messages = new HashMap<>();
86        for (String key : getConfig().get().getConfigurationSection("messages").getKeys(false)) {
87            messages.put(key, Text.colorize(getConfig().get().getString("messages." + key)));
88        }
89    }
90
91    @Override
92    public void enable() {
93        this.enabled = true;
94
95        this.config = this.core.getFileManager().getConfig("enchants.yml").copyDefaults(true).save();
96
97        this.enchantsManager = new EnchantsManager(this);
98        this.api = new UltraPrisonEnchantsAPIImpl(enchantsManager);
99        this.loadMessages();
100
101        Schedulers.async().runRepeating(() -> {
102            Players.all().stream().forEach(player -> {
103                ItemStack inHand = player.getItemInHand();
104                ItemStack lastEquipped = currentPickaxes.get(player.getUniqueId());
105
106                if (lastEquipped == null && inHand != null && inHand.getType() == CompMaterial.DIAMOND_PICKAXE.toMaterial() && !player.getWorld().getName().equalsIgnoreCase("pvp")) {
107                    currentPickaxes.put(player.getUniqueId(), inHand);
108                    Schedulers.sync().run(() -> this.enchantsManager.handlePickaxeEquip(player, inHand));
109                    return;
110                }
111
112                if (lastEquipped != null) {
113                    if (inHand != null && inHand.getType() == CompMaterial.DIAMOND_PICKAXE.toMaterial()) {
114                        //Check if they are not the same
115                        if (!areItemsSame(lastEquipped, inHand)) {
116                            Schedulers.sync().run(() -> {
117                                this.enchantsManager.handlePickaxeUnequip(player, lastEquipped);
118                                this.enchantsManager.handlePickaxeEquip(player, inHand);
119                            });
120                            currentPickaxes.put(player.getUniqueId(), inHand);
121                        }
122                    } else if (inHand == null || inHand.getType() != CompMaterial.DIAMOND_PICKAXE.toMaterial()) {
123                        Schedulers.sync().run(() -> this.enchantsManager.handlePickaxeUnequip(player, lastEquipped));
124                        currentPickaxes.remove(player.getUniqueId());
125                    }
126                }
127            });
128        }, 20, 20);
129        this.registerCommands();
130        this.registerEvents();
131    }
132
133    @Override
134    public void disable() {
135        this.enabled = false;
136
137        for (Player p : Players.all()) {
138            p.closeInventory();
139        }
140
141    }
142
143    @Override
144    public String getName() {
145        return "Enchants";
146    }
147
148    private void registerCommands() {
149
150
151        Commands.create()
152                .assertOp()
153                .handler(c -> {
154
155                    if (c.args().size() == 0) {
156                        c.sender().sendMessage(Text.colorize("&c/givepickaxe <player> <enchant:<id>=<level>>,..."));
157                        return;
158                    }
159
160                    String input = null;
161                    Player target = null;
162
163                    if (c.args().size() == 1) {
164                        input = c.rawArg(0);
165                    } else if (c.args().size() == 2) {
166                        target = c.arg(0).parseOrFail(Player.class);
167                        input = c.rawArg(1);
168                    }
169
170                    this.enchantsManager.givePickaxe(target, input, c.sender());
171                }).registerAndBind(core, "givepickaxe");
172
173        Commands.create()
174                .assertPlayer()
175                .handler(c -> {
176                    if (LuckyBoosterEnchant.hasLuckyBoosterRunning(c.sender())) {
177                        c.sender().sendMessage(getMessage("lucky_mode_timeleft").replace("%timeleft%", LuckyBoosterEnchant.getTimeLeft(c.sender())));
178                    } else {
179                        c.sender().sendMessage(getMessage("lucky_mode_disabled"));
180                    }
181                }).registerAndBind(core, "luckybooster");
182
183        Commands.create()
184                .assertPlayer()
185                .handler(c -> {
186                    ItemStack pickAxe = c.sender().getItemInHand();
187
188                    if (pickAxe == null || pickAxe.getType() != CompMaterial.DIAMOND_PICKAXE.toMaterial()) {
189                        c.sender().sendMessage(getMessage("no_pickaxe_found"));
190                        return;
191                    }
192
193                    c.sender().setItemInHand(null);
194                    new DisenchantGUI(c.sender(), pickAxe).open();
195                }).registerAndBind(core, "disenchant", "dise", "de", "disenchantmenu", "dismenu");
196
197        Commands.create()
198                .assertPlayer()
199                .handler(c -> {
200                    ItemStack pickAxe = c.sender().getItemInHand();
201
202                    if (pickAxe == null || pickAxe.getType() != CompMaterial.DIAMOND_PICKAXE.toMaterial()) {
203                        c.sender().sendMessage(getMessage("no_pickaxe_found"));
204                        return;
205                    }
206
207                    c.sender().setItemInHand(null);
208                    new EnchantGUI(c.sender(), pickAxe).open();
209                }).registerAndBind(core, "enchantmenu", "enchmenu");
210
211        Commands.create()
212                .assertPlayer()
213                .handler(c -> {
214                    if (c.args().size() == 0) {
215                        toggleExplosive(c.sender());
216                    }
217                }).registerAndBind(core, "explosive");
218        Commands.create()
219                .assertPlayer()
220                .handler(c -> {
221                    if (c.args().size() == 0) {
222                        toggleLayer(c.sender());
223                    }
224                }).registerAndBind(core, "layer");
225        Commands.create()
226                .assertPlayer()
227                .assertPermission("ultraprison.value", this.getMessage("value_no_permission"))
228                .handler(c -> {
229                    if (!valueCooldown.test(c.sender())) {
230                        c.sender().sendMessage(this.getMessage("value_cooldown").replace("%time%", String.valueOf(valueCooldown.remainingTime(c.sender(), TimeUnit.SECONDS))));
231                        return;
232                    }
233                    ItemStack pickAxe = c.sender().getItemInHand();
234
235                    if (pickAxe == null || pickAxe.getType() != CompMaterial.DIAMOND_PICKAXE.toMaterial()) {
236                        c.sender().sendMessage(getMessage("value_no_pickaxe"));
237                        return;
238                    }
239
240                    Players.all().forEach(p -> p.sendMessage(this.getMessage("value_value").replace("%player%", c.sender().getName()).replace("%tokens%", String.format("%,d", this.enchantsManager.getPickaxeValue(pickAxe)))));
241
242                }).registerAndBind(core, "value");
243    }
244
245    private void toggleLayer(Player sender) {
246        if (disabledLayer.contains(sender.getUniqueId())) {
247            sender.sendMessage(getMessage("layer_enabled"));
248            disabledLayer.remove(sender.getUniqueId());
249        } else {
250            sender.sendMessage(getMessage("layer_disabled"));
251            disabledLayer.add(sender.getUniqueId());
252        }
253    }
254
255    private void toggleExplosive(Player sender) {
256        if (disabledExplosive.contains(sender.getUniqueId())) {
257            sender.sendMessage(getMessage("explosive_enabled"));
258            disabledExplosive.remove(sender.getUniqueId());
259        } else {
260            sender.sendMessage(getMessage("explosive_disabled"));
261            disabledExplosive.add(sender.getUniqueId());
262        }
263    }
264
265    private void registerEvents() {
266        Events.subscribe(PlayerInteractEvent.class)
267                .filter(e -> e.getItem() != null && e.getItem().getType() == CompMaterial.DIAMOND_PICKAXE.toMaterial())
268                .filter(e -> (e.getAction() == Action.RIGHT_CLICK_AIR || (e.getAction() == Action.RIGHT_CLICK_BLOCK && this.enchantsManager.isOpenEnchantMenuOnRightClickBlock())))
269                .handler(e -> {
270                    e.setCancelled(true);
271                    ItemStack pickAxe = e.getItem();
272                    e.getPlayer().setItemInHand(null);
273                    new EnchantGUI(e.getPlayer(), pickAxe).open();
274                }).bindWith(core);
275        Events.subscribe(BlockBreakEvent.class)
276                .filter(EventFilters.ignoreCancelled())
277                .filter(e -> e.getPlayer().getGameMode() == GameMode.SURVIVAL && !e.isCancelled() && e.getPlayer().getItemInHand() != null && e.getPlayer().getItemInHand().getType() == CompMaterial.DIAMOND_PICKAXE.toMaterial())
278                .filter(e -> WorldGuardWrapper.getInstance().getRegions(e.getBlock().getLocation()).stream().anyMatch(region -> region.getId().toLowerCase().startsWith("mine")))
279                .handler(e -> {
280                    enchantsManager.addBlocksBrokenToItem(e.getPlayer(), 1);
281                    enchantsManager.handleBlockBreak(e, e.getPlayer().getItemInHand());
282                }).bindWith(core);
283        Events.subscribe(BlockBreakEvent.class, EventPriority.LOWEST)
284                .filter(e -> e.getPlayer().getGameMode() == GameMode.SURVIVAL && !e.isCancelled() && e.getPlayer().getItemInHand() != null && e.getPlayer().getItemInHand().getType() == CompMaterial.DIAMOND_PICKAXE.toMaterial())
285                .filter(e -> WorldGuardWrapper.getInstance().getRegions(e.getBlock().getLocation()).stream().noneMatch(region -> region.getId().toLowerCase().startsWith("mine")))
286                .filter(e-> this.enchantsManager.hasEnchants(e.getPlayer().getItemInHand()))
287                .handler(e -> e.setCancelled(true)).bindWith(core);
288
289    }
290
291    public String getMessage(String key) {
292		return messages.getOrDefault(key.toLowerCase(), Text.colorize("&cMessage " + key + " not found."));
293    }
294
295    public boolean hasLayerDisabled(Player p) {
296        return disabledLayer.contains(p.getUniqueId());
297    }
298
299    public boolean hasExplosiveDisabled(Player p) {
300        return disabledExplosive.contains(p.getUniqueId());
301    }
302
303    private boolean areItemsSame(@NonNull ItemStack last, @NonNull ItemStack current) {
304        List<String> loreLast = last.getItemMeta().getLore();
305        List<String> loreCurrent = current.getItemMeta().getLore();
306
307        if (loreLast == null || loreCurrent == null) {
308            return false;
309        }
310
311        for (int i = 0; i < 3; i++) {
312            try {
313                loreLast.remove(0);
314                loreCurrent.remove(0);
315            } catch (Exception e) {
316                break;
317            }
318        }
319
320        return loreLast.equals(loreCurrent);
321    }
322
323}
324