diff --git a/src/main/java/io/github/hhui64/PixelmonInfoPlus/gui/ivev/IVEVGuiContainer.java b/src/main/java/io/github/hhui64/PixelmonInfoPlus/gui/ivev/IVEVGuiContainer.java index 1e6caa5..1683dc3 100644 --- a/src/main/java/io/github/hhui64/PixelmonInfoPlus/gui/ivev/IVEVGuiContainer.java +++ b/src/main/java/io/github/hhui64/PixelmonInfoPlus/gui/ivev/IVEVGuiContainer.java @@ -9,8 +9,8 @@ import com.pixelmonmod.pixelmon.entities.pixelmon.stats.StatsType; import io.github.hhui64.PixelmonInfoPlus.PixelmonInfoPlus; import io.github.hhui64.PixelmonInfoPlus.hotkey.HotKeyManager; -import io.github.hhui64.PixelmonInfoPlus.network.PixelmonInfoPlusPacketHandler; import io.github.hhui64.PixelmonInfoPlus.pixelmon.SlotApi; +import io.github.hhui64.PixelmonInfoPlus.util.PartyCache; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.entity.player.EntityPlayer; @@ -34,18 +34,7 @@ public class IVEVGuiContainer extends GuiContainer { */ public static Boolean isOpen = false; private static final ResourceLocation background = new ResourceLocation(PixelmonInfoPlus.MODID, "textures/gui/ivevgui.png"); - public Pokemon pokemon = null; - - public static List slots = new LinkedList() { - { - add(new IVStore()); - add(new IVStore()); - add(new IVStore()); - add(new IVStore()); - add(new IVStore()); - add(new IVStore()); - } - }; + public Pokemon pokemon; public int top = 0; public int left = 0; @@ -57,6 +46,12 @@ public IVEVGuiContainer(Container inventorySlotsIn) { this.pokemon = SlotApi.getSelectedPokemon(); } + @Override + public void initGui() { + this.pokemon = SlotApi.getSelectedPokemon(); + super.initGui(); + } + /** * 重写 GuiContainer#keyTyped * 处理 GUI 的 KeyInputEvent @@ -119,8 +114,8 @@ public static void open() { EntityPlayer player = Minecraft.getMinecraft().player; player.openGui(PixelmonInfoPlus.instance, IVEVGuiHandler.GUI_ID, player.getEntityWorld(), 0, 0, 0); IVEVGuiContainer.isOpen = true; - // 每次打开时,从服务器拉取 party 的 IVs - IVEVGuiContainer.getPartyIVSFromServer(); + // 尝试更新缓存 + PartyCache.updateCache(false); } /** @@ -135,16 +130,28 @@ public static void close() { } /** - * 从服务器获取宝可梦栏的所有宝可梦的 IVs + * 获取宝当前宝可梦的 IVStore 实例 + * (此方法会在绘制时一直被调用,所以应该不用手动触发更新缓存) + * + * @return IVStore */ - public static void getPartyIVSFromServer() { - PixelmonInfoPlusPacketHandler.sendGetIVSMessageRequestToServer(); - } - public IVStore getCurrentPokemonIVStore() { - return slots.size() != 6 ? this.pokemon.getIVs() : slots.get(SlotApi.getSelectedPokemonSlotId()); + if (this.pokemon != null) { + // 获取当前宝可梦自身的本地 IVStore + IVStore localIVStore = this.pokemon.getIVs(); + // 尝试根据 Pokemon UUID 从缓存处获取 IVStore + IVStore remoteIVStore = PartyCache.getPokemonIVStore(this.pokemon); + return Arrays.stream(localIVStore.getArray()).sum() == 0 ? remoteIVStore : localIVStore; + } + return new IVStore(new int[]{0, 0, 0, 0, 0, 0}); } + + /** + * 获取宝当前宝可梦的 EVStore 实例 + * + * @return EVStore + */ public EVStore getCurrentPokemonEVStore() { return this.pokemon.getEVs(); } @@ -172,8 +179,6 @@ protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, i GlStateManager.disableBlend(); GlStateManager.popMatrix(); - this.pokemon = SlotApi.getSelectedPokemon(); - // 绘制完背景后,再绘制文字,以保证文字在最上层显示 drawProgressText(); drawPokemonStatsText(); diff --git a/src/main/java/io/github/hhui64/PixelmonInfoPlus/util/PartyCache.java b/src/main/java/io/github/hhui64/PixelmonInfoPlus/util/PartyCache.java new file mode 100644 index 0000000..fea4850 --- /dev/null +++ b/src/main/java/io/github/hhui64/PixelmonInfoPlus/util/PartyCache.java @@ -0,0 +1,120 @@ +package io.github.hhui64.PixelmonInfoPlus.util; + +import com.pixelmonmod.pixelmon.api.pokemon.Pokemon; +import com.pixelmonmod.pixelmon.entities.pixelmon.stats.IVStore; +import io.github.hhui64.PixelmonInfoPlus.network.PixelmonInfoPlusPacketHandler; +import io.github.hhui64.PixelmonInfoPlus.pixelmon.SlotApi; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.util.*; + +public class PartyCache { + private static final Logger logger = LogManager.getLogger("PartyCache"); + /** + * 宝可梦的 IVStore 实例缓存 HashMap,使用 Pokemon UUID 为 key 值 + */ + public static Map pokemonsIVStore = new HashMap<>(); + + public static void addPokemonIVStore(String uuid, IVStore ivStore) { + if (!PartyCache.pokemonsIVStore.containsKey(uuid)) { + PartyCache.pokemonsIVStore.put(uuid, ivStore); + } else { + PartyCache.pokemonsIVStore.replace(uuid, ivStore); + } + } + + public static void addPokemonIVStore(UUID uuid, IVStore ivStore) { + PartyCache.addPokemonIVStore(uuid.toString(), ivStore); + } + + public static void addPokemonIVStore(Pokemon pokemon, IVStore ivStore) { + PartyCache.addPokemonIVStore(pokemon.getUUID(), ivStore); + } + + /** + * 获取指定 Pokemon UUID 的 IVStore + * + * @param uuid Pokemon UUID + * @return IVStore + */ + // TODO 应该还有优化空间,因为 6 个宝可梦槽,只要其中一个不存在缓存就会拉取整个列表... + public static IVStore getPokemonIVStore(String uuid) { + return pokemonsIVStore.containsKey(uuid) ? pokemonsIVStore.get(uuid) : new IVStore(new int[]{0, 0, 0, 0, 0, 0}); + } + + /** + * 获取指定 Pokemon UUID 的 IVStore + * + * @param uuid Pokemon UUID + * @param shouldUpdate 尚未在缓存中找到时,是否向服务器请求更新缓存 + * @return IVStore + */ + public static IVStore getPokemonIVStore(String uuid, boolean shouldUpdate) { + if (shouldUpdate && !pokemonsIVStore.containsKey(uuid)) { + PartyCache.updateCache(true); + } + return PartyCache.getPokemonIVStore(uuid); + } + + public static IVStore getPokemonIVStore(UUID uuid) { + return PartyCache.getPokemonIVStore(uuid.toString()); + } + + public static IVStore getPokemonIVStore(UUID uuid, boolean shouldUpdate) { + return PartyCache.getPokemonIVStore(uuid.toString(), shouldUpdate); + } + + public static IVStore getPokemonIVStore(Pokemon pokemon) { + return PartyCache.getPokemonIVStore(pokemon.getUUID()); + } + + public static IVStore getPokemonIVStore(Pokemon pokemon, boolean shouldUpdate) { + return PartyCache.getPokemonIVStore(pokemon.getUUID(), shouldUpdate); + } + + public static boolean hasPokemonIVStore(String uuid) { + return PartyCache.pokemonsIVStore.containsKey(uuid); + } + + public static boolean hasPokemonIVStore(UUID uuid) { + return PartyCache.hasPokemonIVStore(uuid.toString()); + } + + public static boolean hasPokemonIVStore(Pokemon pokemon) { + return PartyCache.hasPokemonIVStore(pokemon.getUUID()); + } + + public static void cleanCache() { + PartyCache.pokemonsIVStore = new HashMap<>(); + } + + public static void updateCache(boolean forceUpdate) { + String[] localPartyPokemonsUUID = SlotApi.getTeamStringUUID(); + List nonExistentPokemonUUID = new ArrayList<>(); + + if (forceUpdate) { + PixelmonInfoPlusPacketHandler.sendGetIVSMessageRequestToServer(String.join(":", localPartyPokemonsUUID)); + } else { + for (String uuid : localPartyPokemonsUUID) { + if (!PartyCache.pokemonsIVStore.containsKey(uuid)) { + nonExistentPokemonUUID.add(uuid); + } + } + + if (nonExistentPokemonUUID.size() > 0) { + PixelmonInfoPlusPacketHandler.sendGetIVSMessageRequestToServer(String.join(":", nonExistentPokemonUUID)); + } + } + } + + public static void setCache(Map pokemonsIVStore) { + PartyCache.pokemonsIVStore = pokemonsIVStore; + } + + public static void addCache(Map pokemonsIVStore) { + for (Map.Entry entry : pokemonsIVStore.entrySet()) { + PartyCache.addPokemonIVStore(entry.getKey(), entry.getValue()); + } + } +}