/*
* Copyright (C) 2022-2024 NotEnoughUpdates contributors
*
* This file is part of NotEnoughUpdates.
*
* NotEnoughUpdates is free software: you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation, either
* version 3 of the License, or (at your option) any later version.
*
* NotEnoughUpdates is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with NotEnoughUpdates. If not, see .
*/
package io.github.moulberry.notenoughupdates.util;
import com.google.common.reflect.TypeToken;
import com.google.gson.JsonObject;
import com.google.gson.JsonSyntaxException;
import io.github.moulberry.notenoughupdates.NotEnoughUpdates;
import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe;
import io.github.moulberry.notenoughupdates.events.SidebarChangeEvent;
import io.github.moulberry.notenoughupdates.miscfeatures.CookieWarning;
import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent;
import io.github.moulberry.notenoughupdates.miscfeatures.tablisttutorial.TablistAPI;
import io.github.moulberry.notenoughupdates.miscgui.minionhelper.MinionHelperManager;
import io.github.moulberry.notenoughupdates.overlays.OverlayManager;
import io.github.moulberry.notenoughupdates.overlays.SlayerOverlay;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiChest;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.ContainerChest;
import net.minecraft.inventory.Slot;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.IChatComponent;
import net.minecraftforge.client.event.ClientChatReceivedEvent;
import net.minecraftforge.client.event.GuiOpenEvent;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.world.WorldEvent;
import net.minecraftforge.fml.common.eventhandler.EventPriority;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@NEUAutoSubscribe
public class SBInfo {
private static final SBInfo INSTANCE = new SBInfo();
public static SBInfo getInstance() {
return INSTANCE;
}
private static final Pattern timePattern = Pattern.compile(".+(am|pm)");
public IChatComponent footer;
public IChatComponent header;
public @NotNull String location = "";
public @NotNull String lastLocation = "";
public String date = "";
public String time = "";
public String objective = "";
public String slayer = "";
public boolean stranded = false;
public boolean bingo = false;
public @Nullable String mode = null;
public Date currentTimeDate = null;
private JsonObject mayorJson = new JsonObject();
/**
* Use Utils.getOpenChestName() instead
*/
@Deprecated
public String currentlyOpenChestName = "";
public String lastOpenChestName = "";
private long lastManualLocRaw = -1;
private long lastLocRaw = -1;
public long joinedWorld = -1;
private long lastMayorUpdate;
public long unloadedWorld = -1;
private JsonObject locraw = null;
public boolean isInDungeon = false;
public enum Gamemode {
NORMAL("", ""), IRONMAN("Ironman", "♲"), STRANDED("Stranded", "☀");
private final String name;
private final String emoji;
Gamemode(String name, String emoji) {
this.name = name;
this.emoji = emoji;
}
public static Gamemode find(String type) {
for (Gamemode gamemode : values()) {
if (type.contains(gamemode.name))
return gamemode;
}
return null;
}
}
private Map gamemodes = new HashMap<>();
private boolean areGamemodesLoaded = false;
private int tickCount = 0;
public String currentProfile = null;
//Set the priority HIGH to allow other GuiOpenEvent's to use the new currentlyOpenChestName data
@SubscribeEvent(priority = EventPriority.HIGH)
public void onGuiOpen(GuiOpenEvent event) {
if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) return;
if (event.gui instanceof GuiChest) {
GuiChest chest = (GuiChest) event.gui;
ContainerChest container = (ContainerChest) chest.inventorySlots;
currentlyOpenChestName = container.getLowerChestInventory().getDisplayName().getUnformattedText();
lastOpenChestName = currentlyOpenChestName;
} else {
currentlyOpenChestName = "";
}
}
@SubscribeEvent
public void onGuiTick(TickEvent event) {
if (tickCount++ % 10 != 0) return;
if (Utils.getOpenChestName().equals("Profile Management")) {
ContainerChest container = (ContainerChest) ((GuiChest) Minecraft.getMinecraft().currentScreen).inventorySlots;
updateProfileInformation(container);
}
}
public boolean checkForSkyblockLocation() {
if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() || getLocation() == null) {
Utils.addChatMessage(EnumChatFormatting.RED + "[NEU] This command is not available outside SkyBlock");
return false;
}
return true;
}
private static final Pattern PROFILE_PATTERN =
Pattern.compile("(?(♲ Ironman)|(☀ Stranded)|()) *Profile: (?[^ ]+)");
private void updateProfileInformation(ContainerChest container) {
for (int i = 11; i < 16; i = -~i) {
Slot slot = container.getSlot(i);
if (slot == null || !slot.getHasStack()) continue;
ItemStack item = slot.getStack();
if (item == null || item.getItem() == Item.getItemFromBlock(Blocks.bedrock)) continue;
String displayName = Utils.cleanColour(item.getDisplayName());
Matcher matcher = PROFILE_PATTERN.matcher(displayName);
if (!matcher.matches()) continue;
String type = matcher.group("type");
String name = matcher.group("name");
Gamemode gamemode = Gamemode.find(type);
gamemodes.put(name, gamemode);
}
areGamemodesLoaded = true;
saveGameModes();
}
private Path getProfilesFile() {
return new File(NotEnoughUpdates.INSTANCE.manager.configLocation, "profiles.json").toPath();
}
public Map getAllGamemodes() {
if (!areGamemodesLoaded)
loadGameModes();
return gamemodes;
}
public void saveGameModes() {
try {
Files.write(
getProfilesFile(),
NotEnoughUpdates.INSTANCE.manager.gson.toJson(gamemodes).getBytes(StandardCharsets.UTF_8)
);
} catch (IOException e) {
e.printStackTrace();
}
}
public Gamemode getGamemodeForProfile(String profiles) {
return getAllGamemodes().get(profiles);
}
public Gamemode getCurrentMode() {
return getGamemodeForProfile(currentProfile);
}
public void loadGameModes() {
try {
gamemodes = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(
Files.newBufferedReader(getProfilesFile()),
new TypeToken