From 7eb3190b57722c970e47d86c4cdb07fe1c4ba2d7 Mon Sep 17 00:00:00 2001 From: Patric Stout Date: Thu, 13 Mar 2025 19:25:03 +0100 Subject: [PATCH] chore: switch to ESI's v2 version of characters/fitting (#160) I got a nice mail from CCP that I shouldn't be using v1 anymore. --- src/hooks/ImportEsiFitting/EsiFlags.tsx | 86 +++++++++++++++++++ .../ImportEsiFitting/ImportEsiFitting.tsx | 17 ++-- src/hooks/ImportEsiFitting/index.ts | 1 + src/hooks/ImportEveShipFit/DecodeEsfFitV1.tsx | 13 +-- src/hooks/ImportEveShipFit/DecodeEsfFitV2.tsx | 13 +-- src/hooks/ImportEveShipFit/DecodeKillMail.tsx | 14 +-- src/hooks/ImportEveShipFit/EsiFlags.tsx | 35 -------- src/hooks/ImportEveShipFit/index.ts | 1 - .../EsiCharactersProvider/EsiGetFittings.tsx | 2 +- src/providers/LocalFitsProvider/ConvertV2.tsx | 13 +-- 10 files changed, 130 insertions(+), 65 deletions(-) create mode 100644 src/hooks/ImportEsiFitting/EsiFlags.tsx delete mode 100644 src/hooks/ImportEveShipFit/EsiFlags.tsx diff --git a/src/hooks/ImportEsiFitting/EsiFlags.tsx b/src/hooks/ImportEsiFitting/EsiFlags.tsx new file mode 100644 index 0000000..5029a53 --- /dev/null +++ b/src/hooks/ImportEsiFitting/EsiFlags.tsx @@ -0,0 +1,86 @@ +import { EsfSlot } from "@/providers/CurrentFitProvider"; + +export interface EsiSlot { + type: "Module" | "CargoBay" | "DroneBay"; + module?: EsfSlot; +} + +const esiFlagIdToName: Record = { + 5: "Cargo", + 11: "LoSlot0", + 12: "LoSlot1", + 13: "LoSlot2", + 14: "LoSlot3", + 15: "LoSlot4", + 16: "LoSlot5", + 17: "LoSlot6", + 18: "LoSlot7", + 19: "MedSlot0", + 20: "MedSlot1", + 21: "MedSlot2", + 22: "MedSlot3", + 23: "MedSlot4", + 24: "MedSlot5", + 25: "MedSlot6", + 26: "MedSlot7", + 27: "HiSlot0", + 28: "HiSlot1", + 29: "HiSlot2", + 30: "HiSlot3", + 31: "HiSlot4", + 32: "HiSlot5", + 33: "HiSlot6", + 34: "HiSlot7", + 87: "DroneBay", + 92: "RigSlot0", + 93: "RigSlot1", + 94: "RigSlot2", + 125: "SubSystemSlot0", + 126: "SubSystemSlot1", + 127: "SubSystemSlot2", + 128: "SubSystemSlot3", +}; + +const esiFlagNameToEsiSlot: Record = { + Cargo: { type: "CargoBay" }, + LoSlot0: { type: "Module", module: { type: "Low", index: 1 } }, + LoSlot1: { type: "Module", module: { type: "Low", index: 2 } }, + LoSlot2: { type: "Module", module: { type: "Low", index: 3 } }, + LoSlot3: { type: "Module", module: { type: "Low", index: 4 } }, + LoSlot4: { type: "Module", module: { type: "Low", index: 5 } }, + LoSlot5: { type: "Module", module: { type: "Low", index: 6 } }, + LoSlot6: { type: "Module", module: { type: "Low", index: 7 } }, + LoSlot7: { type: "Module", module: { type: "Low", index: 8 } }, + MedSlot0: { type: "Module", module: { type: "Medium", index: 1 } }, + MedSlot1: { type: "Module", module: { type: "Medium", index: 2 } }, + MedSlot2: { type: "Module", module: { type: "Medium", index: 3 } }, + MedSlot3: { type: "Module", module: { type: "Medium", index: 4 } }, + MedSlot4: { type: "Module", module: { type: "Medium", index: 5 } }, + MedSlot5: { type: "Module", module: { type: "Medium", index: 6 } }, + MedSlot6: { type: "Module", module: { type: "Medium", index: 7 } }, + MedSlot7: { type: "Module", module: { type: "Medium", index: 8 } }, + HiSlot0: { type: "Module", module: { type: "High", index: 1 } }, + HiSlot1: { type: "Module", module: { type: "High", index: 2 } }, + HiSlot2: { type: "Module", module: { type: "High", index: 3 } }, + HiSlot3: { type: "Module", module: { type: "High", index: 4 } }, + HiSlot4: { type: "Module", module: { type: "High", index: 5 } }, + HiSlot5: { type: "Module", module: { type: "High", index: 6 } }, + HiSlot6: { type: "Module", module: { type: "High", index: 7 } }, + HiSlot7: { type: "Module", module: { type: "High", index: 8 } }, + DroneBay: { type: "DroneBay" }, + RigSlot0: { type: "Module", module: { type: "Rig", index: 1 } }, + RigSlot1: { type: "Module", module: { type: "Rig", index: 2 } }, + RigSlot2: { type: "Module", module: { type: "Rig", index: 3 } }, + SubSystemSlot0: { type: "Module", module: { type: "SubSystem", index: 1 } }, + SubSystemSlot1: { type: "Module", module: { type: "SubSystem", index: 2 } }, + SubSystemSlot2: { type: "Module", module: { type: "SubSystem", index: 3 } }, + SubSystemSlot3: { type: "Module", module: { type: "SubSystem", index: 4 } }, +}; + +export const esiFlagToEsiSlot = (flag: number | string): EsiSlot | undefined => { + if (typeof flag === "number") { + flag = esiFlagIdToName[flag]; + } + + return esiFlagNameToEsiSlot[flag]; +}; diff --git a/src/hooks/ImportEsiFitting/ImportEsiFitting.tsx b/src/hooks/ImportEsiFitting/ImportEsiFitting.tsx index 08be95a..c120b40 100644 --- a/src/hooks/ImportEsiFitting/ImportEsiFitting.tsx +++ b/src/hooks/ImportEsiFitting/ImportEsiFitting.tsx @@ -2,9 +2,10 @@ import React from "react"; import { EsfCargo, EsfDrone, EsfFit, EsfModule } from "@/providers/CurrentFitProvider"; import { useEveData } from "@/providers/EveDataProvider"; -import { esiFlagToEsfSlot } from "@/hooks/ImportEveShipFit"; import { useCleanImportFit } from "@/hooks/CleanImportFit"; +import { esiFlagToEsiSlot } from "./EsiFlags"; + export interface EsiFit { name: string; description: string; @@ -12,7 +13,7 @@ export interface EsiFit { items: { item_id: number; type_id: number; - flag: number; + flag: number | string; quantity: number; }[]; } @@ -29,12 +30,12 @@ export function useImportEsiFitting() { const modules = esiFit.items .map((item): EsfModule | undefined => { - const slot = esiFlagToEsfSlot[item.flag]; - if (slot === undefined) return undefined; + const slot = esiFlagToEsiSlot(item.flag); + if (slot === undefined || slot.type !== "Module") return undefined; return { typeId: item.type_id, - slot, + slot: slot.module!, state: "Active", }; }) @@ -42,7 +43,8 @@ export function useImportEsiFitting() { const drones = esiFit.items .map((item): EsfDrone | undefined => { - if (item.flag !== 87) return undefined; + const slot = esiFlagToEsiSlot(item.flag); + if (slot === undefined || slot.type !== "DroneBay") return undefined; return { typeId: item.type_id, @@ -56,7 +58,8 @@ export function useImportEsiFitting() { const cargo = esiFit.items .map((item): EsfCargo | undefined => { - if (item.flag !== 5) return undefined; + const slot = esiFlagToEsiSlot(item.flag); + if (slot === undefined || slot.type !== "CargoBay") return undefined; return { typeId: item.type_id, diff --git a/src/hooks/ImportEsiFitting/index.ts b/src/hooks/ImportEsiFitting/index.ts index 0dd4737..3bb2020 100644 --- a/src/hooks/ImportEsiFitting/index.ts +++ b/src/hooks/ImportEsiFitting/index.ts @@ -1,2 +1,3 @@ export { useImportEsiFitting } from "./ImportEsiFitting"; export type { EsiFit } from "./ImportEsiFitting"; +export { esiFlagToEsiSlot } from "./EsiFlags"; diff --git a/src/hooks/ImportEveShipFit/DecodeEsfFitV1.tsx b/src/hooks/ImportEveShipFit/DecodeEsfFitV1.tsx index ff78b2d..d7c3ee7 100644 --- a/src/hooks/ImportEveShipFit/DecodeEsfFitV1.tsx +++ b/src/hooks/ImportEveShipFit/DecodeEsfFitV1.tsx @@ -1,7 +1,7 @@ import { EsfCargo, EsfDrone, EsfFit, EsfModule } from "@/providers/CurrentFitProvider"; +import { esiFlagToEsiSlot } from "@/hooks/ImportEsiFitting"; import { decompress } from "./Decompress"; -import { esiFlagToEsfSlot } from "./EsiFlags"; export async function decodeEsfFitV1(fitCompressed: string): Promise { const fitEncoded = await decompress(fitCompressed); @@ -14,10 +14,11 @@ export async function decodeEsfFitV1(fitCompressed: string): Promise { const item = line.split(","); const flag = parseInt(item[0]); - if (esiFlagToEsfSlot[flag] === undefined) return undefined; // Skip anything not modules. + const slot = esiFlagToEsiSlot(flag); + if (slot === undefined || slot.type !== "Module") return undefined; // Skip anything not modules. return { - slot: esiFlagToEsfSlot[flag], + slot: slot.module!, typeId: parseInt(item[1]), state: "Active", }; @@ -29,7 +30,8 @@ export async function decodeEsfFitV1(fitCompressed: string): Promise { const item = line.split(","); const flag = parseInt(item[0]); - if (flag != 87) return undefined; // Skip anything not drones. + const slot = esiFlagToEsiSlot(flag); + if (slot === undefined || slot.type !== "DroneBay") return undefined; // Skip anything not drones. return { typeId: parseInt(item[1]), @@ -46,7 +48,8 @@ export async function decodeEsfFitV1(fitCompressed: string): Promise { const item = line.split(","); const flag = parseInt(item[0]); - if (flag != 5) return undefined; // Skip anything not cargo. + const slot = esiFlagToEsiSlot(flag); + if (slot === undefined || slot.type !== "CargoBay") return undefined; // Skip anything not cargo. return { typeId: parseInt(item[1]), diff --git a/src/hooks/ImportEveShipFit/DecodeEsfFitV2.tsx b/src/hooks/ImportEveShipFit/DecodeEsfFitV2.tsx index f7ddb6b..8113cfb 100644 --- a/src/hooks/ImportEveShipFit/DecodeEsfFitV2.tsx +++ b/src/hooks/ImportEveShipFit/DecodeEsfFitV2.tsx @@ -1,7 +1,7 @@ import { EsfCargo, EsfDrone, EsfFit, EsfModule, EsfState } from "@/providers/CurrentFitProvider"; import { decompress } from "./Decompress"; -import { esiFlagToEsfSlot } from "./EsiFlags"; +import { esiFlagToEsiSlot } from "@/hooks/ImportEsiFitting"; export async function decodeEsfFitV2(fitCompressed: string): Promise { const fitEncoded = await decompress(fitCompressed); @@ -14,7 +14,8 @@ export async function decodeEsfFitV2(fitCompressed: string): Promise { const item = line.split(","); const flag = parseInt(item[0]); - if (esiFlagToEsfSlot[flag] === undefined) return undefined; // Skip anything not modules. + const slot = esiFlagToEsiSlot(flag); + if (slot === undefined || slot.type !== "Module") return undefined; // Skip anything not modules. let charge = undefined; if (item[3]) { @@ -24,7 +25,7 @@ export async function decodeEsfFitV2(fitCompressed: string): Promise { const item = line.split(","); const flag = parseInt(item[0]); - if (flag != 87) return undefined; // Skip anything not drones. + const slot = esiFlagToEsiSlot(flag); + if (slot === undefined || slot.type !== "DroneBay") return undefined; // Skip anything not drones. const quantity = parseInt(item[2]); @@ -66,7 +68,8 @@ export async function decodeEsfFitV2(fitCompressed: string): Promise { const item = line.split(","); const flag = parseInt(item[0]); - if (flag != 5) return undefined; // Skip anything not cargo. + const slot = esiFlagToEsiSlot(flag); + if (slot === undefined || slot.type !== "CargoBay") return undefined; // Skip anything not cargo. return { typeId: parseInt(item[1]), diff --git a/src/hooks/ImportEveShipFit/DecodeKillMail.tsx b/src/hooks/ImportEveShipFit/DecodeKillMail.tsx index 1b50051..ed27a92 100644 --- a/src/hooks/ImportEveShipFit/DecodeKillMail.tsx +++ b/src/hooks/ImportEveShipFit/DecodeKillMail.tsx @@ -1,7 +1,6 @@ import { EsfCargo, EsfDrone, EsfFit, EsfModule } from "@/providers/CurrentFitProvider"; import { useEveData } from "@/providers/EveDataProvider"; - -import { esiFlagToEsfSlot } from "./EsiFlags"; +import { esiFlagToEsiSlot } from "@/hooks/ImportEsiFitting"; export function useFetchKillMail() { const eveData = useEveData(); @@ -37,10 +36,11 @@ export function useFetchKillMail() { /* Find the modules from the item-list. */ let modules = items .map((item): EsfModule | undefined => { - if (esiFlagToEsfSlot[item.flag] === undefined) return undefined; // Skip anything not modules. + const slot = esiFlagToEsiSlot(item.flag); + if (slot === undefined || slot.type !== "Module") return undefined; // Skip anything not modules. return { - slot: esiFlagToEsfSlot[item.flag], + slot: slot.module!, typeId: item.type_id, charge: undefined, state: "Active", @@ -51,7 +51,8 @@ export function useFetchKillMail() { /* Find the drones from the item-list. */ const drones = items .map((item): EsfDrone | undefined => { - if (item.flag !== 87) return undefined; // Skip anything not drones. + const slot = esiFlagToEsiSlot(item.flag); + if (slot === undefined || slot.type !== "DroneBay") return undefined; // Skip anything not drones. return { typeId: item.type_id, @@ -66,7 +67,8 @@ export function useFetchKillMail() { /* Find the cargo from the item-list. */ const cargo = items .map((item): EsfCargo | undefined => { - if (item.flag !== 5) return undefined; // Skip anything not cargo. + const slot = esiFlagToEsiSlot(item.flag); + if (slot === undefined || slot.type !== "CargoBay") return undefined; // Skip anything not cargo. return { typeId: item.type_id, diff --git a/src/hooks/ImportEveShipFit/EsiFlags.tsx b/src/hooks/ImportEveShipFit/EsiFlags.tsx deleted file mode 100644 index 604e02e..0000000 --- a/src/hooks/ImportEveShipFit/EsiFlags.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { EsfSlot } from "@/providers/CurrentFitProvider"; - -export const esiFlagToEsfSlot: Record = { - 11: { type: "Low", index: 1 }, - 12: { type: "Low", index: 2 }, - 13: { type: "Low", index: 3 }, - 14: { type: "Low", index: 4 }, - 15: { type: "Low", index: 5 }, - 16: { type: "Low", index: 6 }, - 17: { type: "Low", index: 7 }, - 18: { type: "Low", index: 8 }, - 19: { type: "Medium", index: 1 }, - 20: { type: "Medium", index: 2 }, - 21: { type: "Medium", index: 3 }, - 22: { type: "Medium", index: 4 }, - 23: { type: "Medium", index: 5 }, - 24: { type: "Medium", index: 6 }, - 25: { type: "Medium", index: 7 }, - 26: { type: "Medium", index: 8 }, - 27: { type: "High", index: 1 }, - 28: { type: "High", index: 2 }, - 29: { type: "High", index: 3 }, - 30: { type: "High", index: 4 }, - 31: { type: "High", index: 5 }, - 32: { type: "High", index: 6 }, - 33: { type: "High", index: 7 }, - 34: { type: "High", index: 8 }, - 92: { type: "Rig", index: 1 }, - 93: { type: "Rig", index: 2 }, - 94: { type: "Rig", index: 3 }, - 125: { type: "SubSystem", index: 1 }, - 126: { type: "SubSystem", index: 2 }, - 127: { type: "SubSystem", index: 3 }, - 128: { type: "SubSystem", index: 4 }, -}; diff --git a/src/hooks/ImportEveShipFit/index.ts b/src/hooks/ImportEveShipFit/index.ts index 54c163a..2d09005 100644 --- a/src/hooks/ImportEveShipFit/index.ts +++ b/src/hooks/ImportEveShipFit/index.ts @@ -1,2 +1 @@ export { useImportEveShipFit } from "./ImportEveShipFit"; -export { esiFlagToEsfSlot } from "./EsiFlags"; diff --git a/src/providers/Characters/EsiCharactersProvider/EsiGetFittings.tsx b/src/providers/Characters/EsiCharactersProvider/EsiGetFittings.tsx index e3c7dd3..bdd1a73 100644 --- a/src/providers/Characters/EsiCharactersProvider/EsiGetFittings.tsx +++ b/src/providers/Characters/EsiCharactersProvider/EsiGetFittings.tsx @@ -3,7 +3,7 @@ import { EsiFit } from "@/hooks/ImportEsiFitting"; export async function getCharFittings(characterId: string, accessToken: string): Promise { let response; try { - response = await fetch(`https://esi.evetech.net/v1/characters/${characterId}/fittings/`, { + response = await fetch(`https://esi.evetech.net/v2/characters/${characterId}/fittings/`, { headers: { authorization: `Bearer ${accessToken}`, "content-type": "application/json", diff --git a/src/providers/LocalFitsProvider/ConvertV2.tsx b/src/providers/LocalFitsProvider/ConvertV2.tsx index 33e12b9..c891897 100644 --- a/src/providers/LocalFitsProvider/ConvertV2.tsx +++ b/src/providers/LocalFitsProvider/ConvertV2.tsx @@ -1,4 +1,4 @@ -import { esiFlagToEsfSlot } from "@/hooks/ImportEveShipFit"; +import { esiFlagToEsiSlot } from "@/hooks/ImportEsiFitting"; import { EsfCargo, EsfDrone, EsfFit, EsfModule } from "../CurrentFitProvider/CurrentFitProvider"; // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -6,11 +6,12 @@ export const ConvertV2 = (fit: any) => { const modules = fit.items // eslint-disable-next-line @typescript-eslint/no-explicit-any .map((item: any): EsfModule | undefined => { - if (esiFlagToEsfSlot[item.flag] === undefined) return undefined; + const slot = esiFlagToEsiSlot(item.flag); + if (slot === undefined || slot.type !== "Module") return undefined; return { typeId: item.type_id, - slot: esiFlagToEsfSlot[item.flag], + slot: slot.module!, state: item.state ?? "Active", charge: item.charge === undefined @@ -25,7 +26,8 @@ export const ConvertV2 = (fit: any) => { const drones = fit.items // eslint-disable-next-line @typescript-eslint/no-explicit-any .map((item: any): EsfDrone | undefined => { - if (item.flag !== 87) return undefined; + const slot = esiFlagToEsiSlot(item.flag); + if (slot === undefined || slot.type !== "DroneBay") return undefined; return { typeId: item.type_id, @@ -50,7 +52,8 @@ export const ConvertV2 = (fit: any) => { const cargo = fit.items // eslint-disable-next-line @typescript-eslint/no-explicit-any .map((item: any): EsfCargo | undefined => { - if (item.flag !== 5) return undefined; + const slot = esiFlagToEsiSlot(item.flag); + if (slot === undefined || slot.type !== "CargoBay") return undefined; return { typeId: item.type_id,