From 04e6a804965f42ce2e12e57633b535e832e68777 Mon Sep 17 00:00:00 2001 From: Samuel Elliott Date: Thu, 20 Oct 2022 22:57:35 +0100 Subject: [PATCH] Use SplatNet 3 types from splatnet3-types --- package-lock.json | 11 + package.json | 1 + src/api/splatnet3-types.ts | 1227 ---------------------- src/api/splatnet3.ts | 57 +- src/cli/presence-server.ts | 55 +- src/cli/splatnet3/battles.ts | 2 +- src/cli/splatnet3/festival.ts | 2 +- src/cli/splatnet3/friends.ts | 2 +- src/discord/titles/nintendo/splatoon3.ts | 39 +- src/exports/splatnet3.ts | 2 +- 10 files changed, 85 insertions(+), 1313 deletions(-) diff --git a/package-lock.json b/package-lock.json index 68f053f..95fea7e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "node-notifier": "^10.0.1", "node-persist": "^3.1.0", "read": "^1.0.7", + "splatnet3-types": "^0.1.20221020213035", "supports-color": "^8.1.1", "tslib": "^2.4.0", "uuid": "^8.3.2", @@ -4360,6 +4361,11 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "node_modules/splatnet3-types": { + "version": "0.1.20221020213035", + "resolved": "https://registry.npmjs.org/splatnet3-types/-/splatnet3-types-0.1.20221020213035.tgz", + "integrity": "sha512-IjetRtZCcr4kKVdKGVsmiqAHt8b6WqyOJB+8+2pj5imDiAXBWqTKeKp9++CkdIpNPRBO4BLpWUwM5wHaYI0YGA==" + }, "node_modules/sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", @@ -8386,6 +8392,11 @@ "integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==", "dev": true }, + "splatnet3-types": { + "version": "0.1.20221020213035", + "resolved": "https://registry.npmjs.org/splatnet3-types/-/splatnet3-types-0.1.20221020213035.tgz", + "integrity": "sha512-IjetRtZCcr4kKVdKGVsmiqAHt8b6WqyOJB+8+2pj5imDiAXBWqTKeKp9++CkdIpNPRBO4BLpWUwM5wHaYI0YGA==" + }, "sprintf-js": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", diff --git a/package.json b/package.json index b47eb3f..239f782 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "node-notifier": "^10.0.1", "node-persist": "^3.1.0", "read": "^1.0.7", + "splatnet3-types": "^0.1.20221020213035", "supports-color": "^8.1.1", "tslib": "^2.4.0", "uuid": "^8.3.2", diff --git a/src/api/splatnet3-types.ts b/src/api/splatnet3-types.ts index 7cb41f1..5a94a6a 100644 --- a/src/api/splatnet3-types.ts +++ b/src/api/splatnet3-types.ts @@ -4,1230 +4,3 @@ export interface BulletToken { lang: string; is_noe_country: 'true' | 'false'; } - -/** /graphql */ -export interface GraphQLRequest { - variables: Variables; - extensions: { - persistedQuery: { - version: 1; - sha256Hash: RequestParameters['id']; - }; - }; -} - -export interface RequestParameters { - id: string; - // ... -} - -export interface GraphQLResponse { - data: T; -} - -export enum RequestId { - SupportButton_SupportChallengeMutation = '30aa261475d43bd765b4200fc67003c8', - CheckinWithQRCodeMutation = '8e3fecf7cfce83f6831b17e9052791d0', - CoopPagerLatestCoopQuery = '82385ab3c3444c857bd35a8d87dbc700', - VotesUpdateFestVoteMutation = 'a2c742c840718f37488e0394cd6e1e08', - CreateMyOutfitMutation = '31ff008ea218ffbe11d958a52c6f959f', - UpdateMyOutfitMutation = 'bb809066282e7d659d3b9e9d4e46b43b', - DownloadSearchReplayQuery = 'b461048f9ffc414b3967a3cdad0805dd', - ReplayModalReserveReplayDownloadMutation = '87bff2b854168b496c2da8c0e7f3e5bc', - PagerLatestVsDetailQuery = '0329c535a32f914fd44251be1f489e24', - PagerUpdateBattleHistoriesByVsModeQuery = '000afbc113f5653d2c2cee42ff6cdeab', - ConfigureAnalyticsQuery = 'f8ae00773cc412a50dd41a6d9a159ddd', - CurrentFestQuery = 'c0429fd738d829445e994d3370999764', - BankaraBattleHistoriesQuery = 'c1553ac75de0a3ea497cdbafaa93e95b', - BankaraBattleHistoriesRefetchQuery = 'd8a8662345593bbbcd63841c91d4c6f5', - LatestBattleHistoriesQuery = '7d8b560e31617e981cf7c8aa1ca13a00', - LatestBattleHistoriesRefetchQuery = '80585ad4e4ecb674c3d8cd278adb1d21', - PrivateBattleHistoriesQuery = '38e0529de8bc77189504d26c7a14e0b8', - PrivateBattleHistoriesRefetchQuery = 'b304e707648f0669a939943d46febce1', - RegularBattleHistoriesQuery = 'f6e7e0277e03ff14edfef3b41f70cd33', - RegularBattleHistoriesRefetchQuery = '333d0a48071b0036449e35ece577b06f', - BattleHistoryCurrentPlayerQuery = '49dd00428fb8e9b4dde62f585c8de1e0', - ChallengeQuery = '8a079214500148bf88a8fce1d7209b90', - ChallengeRefetchQuery = '34aedc79f96b8613501bba465295f779', - JourneyChallengeDetailQuery = '38e58b84376a2ad49ddbe4061b948455', - JourneyChallengeDetailRefetchQuery = '8dc246933b1f4e26a6dfd251878cf786', - JourneyQuery = 'bc71fc0264f3f72256724b069f7a4097', - JourneyRefetchQuery = '09eee118fa16415d6bc3846bc6e5d8e5', - CheckinQuery = 'af8cac2c2554e22e2bbada19392083a2', - CoopHistoryDetailQuery = 'f3799a033f0a7ad4b1b396f9a3bafb1e', - CoopHistoryDetailRefetchQuery = 'd3188df2fd4436870936b109675e2849', - CoopHistoryQuery = '817618ce39bcf5570f52a97d73301b30', - RefetchableCoopHistory_CoopResultQuery = 'a5692cf290ffb26f14f0f7b6e5023b07', - DetailFestRecordDetailQuery = '2d661988c055d843b3be290f04fb0db9', - DetailFestRefethQuery = '0eb7bac3d8aabcad0e9d663ee5b90846', - DetailFestVotingStatusRefethQuery = '92f51ed1ab462bbf1ab64cad49d36f79', - DetailRankingQuery = '58bdd28e3cf71c3bf38bc45836ee1e96', - DetailVotingStatusQuery = '53ee6b6e2acc3859bf42454266d671fc', - FestRecordQuery = '44c76790b68ca0f3da87f2a3452de986', - FestRecordRefetchQuery = '73b9837d0e4dd29bfa2f1a7d7ee0814a', - FriendListQuery = '7a0e05c28c7d3f7e5a06def87ab8cd2d', - FriendListRefetchQuery = 'c1afed6111887347e244c639e7d35c69', - GesotownQuery = 'a43dd44899a09013bcfd29b4b13314ff', - GesotownRefetchQuery = '951cab295eafdbeccfc2e718d7a98646', - SaleGearDetailOrderGesotownGearMutation = 'b79b7a101a243912754f72437e2ad7e5', - SaleGearDetailQuery = '6eb1b255b2cf04c08041567148c883ad', - HeroHistoryQuery = 'fbee1a882371d4e3becec345636d7d1c', - HeroHistoryRefetchQuery = '4f9ae2b8f1d209a5f20302111b28f975', - HistoryRecordQuery = '29957cf5d57b893934de857317cd46d8', - HistoryRecordRefetchQuery = '5e1d0bb4b52e2a99049df6e17117f363', - MyOutfitDetailQuery = 'd935d9e9ba7a5b6b5d6ece7f253304fc', - MyOutfitsQuery = '81d9a6849467d2aa6b1603ebcedbddbe', - MyOutfitsRefetchQuery = '10db4e349f3123c56df14e3adec2ee6f', - MyOutfitCommonDataEquipmentsQuery = 'd29cd0c2b5e6bac90dd5b817914832f8', - MyOutfitCommonDataFilteringConditionQuery = 'd02ab22c9dccc440076055c8baa0fa7a', - PhotoAlbumQuery = '7e950e4f69a5f50013bba8a8fb6a3807', - PhotoAlbumRefetchQuery = '53fb0ad32c13dd9a6e617b1158cc2d41', - ReplayQuery = 'f98cc8326d0d17b07a5785096b0f3517', - ReplayUploadedReplayListRefetchQuery = 'dd56e76c75cda6af077a223c351ad61d', - SettingQuery = '61228d553e7463c203e05e7810dd79a7', - StageRecordQuery = '56c46bdbdfa4519eaf7845ce9f3cd67a', - StageRecordsRefetchQuery = 'fe965bef54377d20e9133087cc6cdf3f', - StageScheduleQuery = '7d4bb0565342b7385ceb97d109e14897', - WeaponRecordQuery = 'a0c277c719b758a926772879d8e53ef8', - WeaponRecordsRefetchQuery = '23c9b2b4ad878c2d91a68859be928dea', - CatalogQuery = 'aead379b98c14798df81f0dd3ebe6121', - CatalogRefetchQuery = '02d2de8967f4ad2ce4f67a3c6c7c4d48', - HomeQuery = 'dba47124d5ec3090c97ba17db5d2f4b3', - VsHistoryDetailPagerRefetchQuery = '994cf141e55213e6923426caf37a1934', - VsHistoryDetailQuery = '2b085984f729cd51938fc069ceef784a', -} - -interface _NodeList { - nodes: T[]; - totalCount: number; -} -type NodeList = - C extends true ? _NodeList : Pick<_NodeList, 'nodes'>; -type NodeListTotal = Pick<_NodeList, 'totalCount'>; - -interface Colour { - a: number; - b: number; - g: number; - r: number; -} - -interface Weapon { - name: string; - image: { - url: string; - }; - id: string; -} -interface SubWeapon { - name: string; - image: { - url: string; - }; - id: string; -} -interface SpecialWeapon { - name: string; - image: { - url: string; - }; - id: string; -} -interface WeaponSet extends Weapon { - subWeapon: SubWeapon; - specialWeapon: SpecialWeapon; -} - -interface ExtendedSpecialWeapon extends SpecialWeapon { - maskingImage: { - width: number; - height: number; - maskImageUrl: string; - overlayImageUrl: string; - }; -} -interface ExtendedWeapon extends Weapon { - image3d: { - url: string; - }; - image2d: { - url: string; - }; - image3dThumbnail: { - url: string; - }; - image2dThumbnail: { - url: string; - }; -} -interface ExtendedWeaponSet extends ExtendedWeapon { - subWeapon: SubWeapon; - specialWeapon: ExtendedSpecialWeapon; -} - -interface VsMode { - mode: string; // "REGULAR" - id: string; // "VnNNb2RlLTE=" -} - -interface Nameplate { - badges: [NameplateBadge | null, NameplateBadge | null, NameplateBadge | null]; - background: NameplateBackground; -} -interface NameplateBadge { - id: string; - image: { - url: string; - }; -} -interface NameplateBackground { - textColor: Colour; - image: { - url: string; - }; - id: string; -} - -export enum Judgement { - WIN = 'WIN', - LOSE = 'LOSE', - EXEMPTED_LOSE = 'EXEMPTED_LOSE', // exemption - DEEMED_LOSE = 'DEEMED_LOSE', // penalty - DRAW = 'DRAW', // no contest -} -export enum JudgementKnockout { - NEITHER = 'NEITHER', - WIN = 'WIN', - LOSE = 'LOSE', -} -export enum Species { - INKLINK = 'INKLING', - OCTOLING = 'OCTOLING', -} - -interface HeadGear { - __isGear: 'HeadGear'; - name: string; - image: { - url: string; - }; - primaryGearPower: GearPower; - additionalGearPowers: GearPower[]; -} -interface ClothingGear { - __isGear: 'ClothingGear'; - name: string; - image: { - url: string; - }; - primaryGearPower: GearPower; - additionalGearPowers: GearPower[]; -} -interface ShoesGear { - __isGear: 'ShoesGear'; - name: string; - image: { - url: string; - }; - primaryGearPower: GearPower; - additionalGearPowers: GearPower[]; -} -interface GearPower { - name: string; // "Ink Recovery Up", "Unknown" - image: { - url: string; - }; -} - -export enum FestState { - SCHEDULED = 'SCHEDULED', - FIRST_HALF = 'FIRST_HALF', - SECOND_HALF = 'SECOND_HALF', - CLOSED = 'CLOSED', -} -export enum FestVoteState { - VOTED = 'VOTED', - PRE_VOTED = 'PRE_VOTED', -} -export enum FestTeamRole { - ATTACK = 'ATTACK', - DEFENSE = 'DEFENSE', -} -export enum TricolourRole { - ATTACK_1 = 'ATTACK1', - ATTACK_2 = 'ATTACK2', - DEFENSE = 'DEFENSE', -} -export enum DragonMatchType { - NORMAL = 'NORMAL', - DECUPLE = 'DECUPLE', // 10x - DRAGON = 'DRAGON', // 100x - DOUBLE_DRAGON = 'DOUBLE_DRAGON', // 333x -} -export enum FestDragonCert { - NONE = 'NONE', - DRAGON = 'DRAGON', // 100x - DOUBLE_DRAGON = 'DOUBLE_DRAGON', // 333x -} - -/** a2c742c840718f37488e0394cd6e1e08 VotesUpdateFestVoteMutation */ -export interface VotesUpdateFestVoteResult { - updateFestVote: { - fest: { - id: string; - teams: DetailVotingStatusTeam>[]; - isVotable: boolean; - undecidedVotes: NodeList; - }; - userErrors: null; - }; -} - -/** f8ae00773cc412a50dd41a6d9a159ddd ConfigureAnalyticsQuery */ -export interface ConfigureAnalyticsResult { - playHistory: { - udemaeMax: string; - paintPointTotal: number; - gameStartTime: string; - battleNumTotal: number; - xMatchMaxAr: { - rank: string | null; - }; - xMatchMaxCl: { - rank: string | null; - }; - xMatchMaxGl: { - rank: string | null; - }; - xMatchMaxLf: { - rank: string | null; - }; - } -} - -/** c0429fd738d829445e994d3370999764 useCurrentFestQuery */ -export interface CurrentFestResult { - currentFest: CurrentFest | null; -} - -interface CurrentFest { - id: string; - state: FestState; - teams: CurrentFestTeam[]; -} -interface CurrentFestTeam { - color: Colour; - id: string; -} - -/** c1553ac75de0a3ea497cdbafaa93e95b BankaraBattleHistoriesQuery */ -export type BankaraBattleHistoriesResult = unknown; - -/** 817618ce39bcf5570f52a97d73301b30 CoopHistoryQuery */ -export interface CoopHistoryResult { - coopResult: { - historyGroups: NodeList; - historyGroupsOnlyFirst: unknown; - monthlyGear: unknown; - pointCard: unknown; - regularAverageClearWave: unknown; - regularGrade: unknown; - regularGradePoint: unknown; - scale: unknown; - } -} -interface CoopHistoryGroup { - historyDetails: NodeList; -} -interface CoopHistoryDetail { - afterGrade: unknown; - afterGradePoint: unknown; - bossResult: unknown; - coopStage: unknown; - gradePointDiff: unknown; - id: string; - memberResults: unknown; - myResult: unknown; - nextHistoryDetail: { - id: string; - } | null; - previousHistoryDetail: { - id: string; - } | null; - resultWave: unknown; - waveResults: unknown; - weapons: unknown; -} - -/** f3799a033f0a7ad4b1b396f9a3bafb1e CoopHistoryDetailQuery */ -export interface CoopHistoryDetailResult { - coopHistoryDetail: unknown; -} - -/** 7d8b560e31617e981cf7c8aa1ca13a00 LatestBattleHistoriesQuery */ -export interface LatestBattleHistoriesResult { - latestBattleHistories: { - summary: latestBattleHistoriesSummary; - historyGroupsOnlyFirst: NodeList; - historyGroups: NodeList; - }; - currentFest: CurrentFest | null; -} -interface latestBattleHistoriesSummary { - assistAverage: number; - deathAverage: number; - killAverage: number; - lose: number; - perUnitTimeMinute: number; - specialAverage: number; - win: number; -} -interface LatestBattleHistoryGroupOnlyFirst { - historyDetails: NodeList>; -} -interface LatestBattleHistoryGroupOnlyFirstDetails { - player: { - weapon: { - specialWeapon: { - maskingImage: { - width: number; - height: number; - maskImageUrl: string; - overlayImageUrl: HasOverlayImage extends true ? string : never; - }; - id: string; - }; - id: string; - }; - id: string; - }; - id: string; -} -interface LatestBattleHistoryGroup { - historyDetails: NodeList; -} -interface LatestBattleHistoryDetails { - id: string; - vsMode: VsMode; - vsRule: { - name: string; // "Turf War" - id: string; // "VnNSdWxlLTA=" - }; - vsStage: { - name: string; // "Mincemeat Metalworks" - id: string; // "VnNTdGFnZS02" - image: { - url: string; - }; - }; - judgement: Judgement; - player: { - weapon: Weapon; - id: string; - festGrade: string | null; - }; - knockout: JudgementKnockout; - myTeam: { - result: { - paintPoint: number; - paintRatio: number; - score: number | null; - }; - }; - nextHistoryDetail: { - id: string; - } | null; - previousHistoryDetail: { - id: string; - } | null; -} -interface AnyLatestBattleHistoryDetails extends LatestBattleHistoryDetails { - udemae: unknown | null; - bankaraMatch: unknown | null; - leagueMatch: unknown | null; -} - -/** 51981299595060692440e0ca66c475a1 PrivateBattleHistoriesQuery */ -export type PrivateBattleHistoriesResult = unknown; - -/** 819b680b0c7962b6f7dc2a777cd8c5e4 RegularBattleHistoriesQuery */ -export interface RegularBattleHistoriesResult { - regularBattleHistories: { - summary: latestBattleHistoriesSummary; - historyGroupsOnlyFirst: NodeList>; - historyGroups: NodeList; - }; -} -interface RegularBattleHistoryGroup { - lastPlayedTime: string; - historyDetails: NodeList; -} - -/** 49dd00428fb8e9b4dde62f585c8de1e0 BattleHistoryCurrentPlayerQuery */ -export interface BattleHistoryCurrentPlayerResult { - currentPlayer: { - species: Species; - weapon: { - specialWeapon: { - maskingImage: { - width: number; - height: number; - maskImageUrl: string; - overlayImageUrl: string; - }; - id: string; - }; - id: string; - }; - }; -} - -/** 7a0e05c28c7d3f7e5a06def87ab8cd2d FriendListQuery */ -export interface FriendListResult { - /** Only includes friends that have played Splatoon 3 */ - friends: NodeList; - currentFest: CurrentFest | null; -} - -/** c1afed6111887347e244c639e7d35c69 FriendListRefetchQuery */ -export type FriendListRefetchResult = FriendListResult; - -interface Friend { - id: string; - onlineState: FriendOnlineState; - /** Switch user name */ - nickname: string; - /** Splatoon 3 name, if the user has one set and is currently playing Splatoon 3 */ - playerName: string | null; - userIcon: { - url: string; - width: number; - height: number; - }; - vsMode: { - id: string; // "VnNNb2RlLTI=" (2 == Anarchy Series), "VnNNb2RlLTUx" (51 == Anarchy Open) - mode: string; // "BANKARA" - name: string; // "Anarchy Battle" - } | null; - isFavorite: boolean; - isLocked: boolean | null; - isVcEnabled: boolean | null; -} - -export enum FriendOnlineState { - OFFLINE = 'OFFLINE', - /** - * The user is online and selected in *any* game, not just Splatoon 3. - * Coral may be used to check which game the user is playing. - */ - ONLINE = 'ONLINE', - VS_MODE_MATCHING = 'VS_MODE_MATCHING', - COOP_MODE_MATCHING = 'COOP_MODE_MATCHING', - VS_MODE_FIGHTING = 'VS_MODE_FIGHTING', - COOP_MODE_FIGHTING = 'COOP_MODE_FIGHTING', -} - -/** 29957cf5d57b893934de857317cd46d8 HistoryRecordQuery */ -export interface HistoryRecordResult { - currentPlayer: CurrentPlayer; - playHistory: PlayHistory; -} - -interface CurrentPlayer { - __isPlayer: 'CurrentPlayer'; - byname: string; // "Splatlandian Youth" - name: string; - nameId: string; - nameplate: Nameplate; - weapon: WeaponSet; - headGear: HeadGear; - clothingGear: ClothingGear; - shoesGear: ShoesGear; -} - -interface PlayHistory { - currentTime: string; - gameStartTime: string; - udemaeMax: string; // "B-" - xMatchMaxAr: XMatchMax; - xMatchMaxCl: XMatchMax; - xMatchMaxGl: XMatchMax; - xMatchMaxLf: XMatchMax; - winCountTotal: number; - frequentlyUsedWeapons: Weapon[]; - paintPointTotal: number; - badges: HistoryBadgeId[]; - weaponHistory: NodeList; - recentBadges: HistoryBadge[]; - allBadges: HistoryBadge[]; -} -interface HistoryBadgeId { - id: string; -} -interface HistoryBadge { - description: string; - id: string; - image: { - url: string; - }; -} -interface XMatchMax { - power: null; - rank: null; - rankUpdateSeasonName: null; - powerUpdateTime: null; -} -interface WeaponHistorySeason { - seasonName: string; // "Drizzle Season 2022" - isMonthly: boolean; - startTime: string; // "2022-09-01T00:00:00Z" - endTime: string; // "2022-09-09T10:13:36Z" - weaponCategories: WeaponHistoryCategory[]; - weapons: WeaponHistoryRecord[]; -} -interface WeaponHistoryRecord { - weapon: WeaponHistoryWeapon; - utilRatio: number; -} -interface WeaponHistoryWeapon extends Weapon { - weaponId: number; -} -interface WeaponHistoryCategory { - weaponCategory: WeaponCategory; - utilRatio: number; - weapons: WeaponHistoryCategoryRecord[]; -} -interface WeaponCategory { - name: string; // "Shooters" - category: string; // "Shooter" - id: string; // "V2VhcG9uQ2F0ZWdvcnktMA==" -} -interface WeaponHistoryCategoryRecord { - weapon: WeaponHistoryCategoryWeapon; - utilRatio: number; -} -interface WeaponHistoryCategoryWeapon extends WeaponHistoryWeapon { - weaponCategory: { - category: string; // "Shooter" - id: string; // "V2VhcG9uQ2F0ZWdvcnktMA==" - }; -} - -/** 2d661988c055d843b3be290f04fb0db9 DetailFestRecordDetailQuery */ -export interface DetailFestRecordDetailResult { - fest: { - __typename: 'Fest'; - id: string; - title: string; - lang: string; - startTime: string; - endTime: string; - state: FestState; - image: { - url: string; - }; - teams: DetailFestTeam[]; - playerResult: FestPlayerResult | null; - myTeam: { - color: Colour; - teamName: string; - id: string; - } | null; - isVotable: boolean; - undecidedVotes: NodeListTotal | null; - }; - currentPlayer: { - name: string; - userIcon: { - url: string; - }; - }; -} - -interface DetailFestTeam { - result: FestTeamResult | null; - id: string; - teamName: string; - color: Colour; - image: { - url: string; - }; - myVoteState: FestVoteState | null; - preVotes: Votes | null; - votes: Votes | null; - role: FestTeamRole | null; -} - -interface FestTeamResult { - __typename: 'FestTeamResult'; - isWinner: boolean; - horagaiRatio: number; - isHoragaiRatioTop: boolean; - voteRatio: number; - isVoteRatioTop: boolean; - regularContributionRatio: number; - isRegularContributionRatioTop: boolean; - challengeContributionRatio: number; - isChallengeContributionRatioTop: boolean; -} - -interface FestPlayerResult { - grade: string; // "Gear Ruler" - horagai: number; - regularContributionAverage: number; - regularContributionTotal: number; - challengeContributionAverage: number | null; - challengeContributionTotal: number | null; - maxFestPower: number | null; -} - -/** 0eb7bac3d8aabcad0e9d663ee5b90846 DetailFestRefethQuery */ -export type DetailFestRefetchResult = DetailFestRecordDetailResult; - -/** 92f51ed1ab462bbf1ab64cad49d36f79 DetailFestVotingStatusRefethQuery */ -export type DetailFestVotingStatusRefetchResult = DetailVotingStatusResult; - -/** 58bdd28e3cf71c3bf38bc45836ee1e96 DetailRankingQuery */ -export interface DetailRankingResult { - fest: DetailRankingFest; -} - -interface DetailRankingFest { - id: string; - lang: string; - teams: DetailRankingTeam[]; - __typename: 'Fest'; -} - -interface DetailRankingTeam { - color: Colour; - id: string; - image: { - url: string; - }; - result: { - rankingHolders: NodeList; - }; - teamName: string; -} - -interface FestRankingHolder { - byname: string; - festPower: number; - id: string; - name: string; - nameId: string; - nameplate: Nameplate; - rank: number; - weapon: FestRankingHolderWeapon; - __isPlayer: 'FestRankingHolder'; -} - -interface FestRankingHolderWeapon extends ExtendedWeapon { - originalImage: { - url: string; - }; - subWeapon: SubWeapon; - specialWeapon: SpecialWeapon; -} - -/** 53ee6b6e2acc3859bf42454266d671fc DetailVotingStatusQuery */ -export interface DetailVotingStatusResult { - fest: DetailVotingStatusFest; -} - -interface DetailVotingStatusFest { - __typename: 'Fest'; - id: string; - lang: string; - teams: DetailVotingStatusTeam[]; - undecidedVotes: NodeList | null; -} - -interface DetailVotingStatusTeam | null> { - id: string; - teamName: string; - image: { - url: string; - }; - color: Colour; - /** undefined = not voted, null = not voted for this team */ - myVoteState?: FestVoteState | null; - preVotes: Votes; - votes: Votes; -} - -interface FestVotePlayer { - playerName: string; - userIcon: { - url: string; - }; -} - -/** 44c76790b68ca0f3da87f2a3452de986 FestRecordQuery */ -export interface FestRecordResult { - festRecords: NodeList; - currentPlayer: { - name: string; - userIcon: { - url: string; - }; - }; -} - -interface FestRecord { - id: string; - state: FestState; - startTime: string; - endTime: string; - title: string; - lang: string; - image: { - url: string; - }; - playerResult: Pick | null; - teams: FestRecordTeam[]; - myTeam: Pick | null; -} - -interface FestRecordTeam { - id: string; - teamName: string; - result: { - isWinner: boolean; - } | null; -} - -/** 73b9837d0e4dd29bfa2f1a7d7ee0814a FestRecordRefetchQuery */ -export type FestRecordRefetchResult = FestRecordResult; - -/** 61228d553e7463c203e05e7810dd79a7 SettingQuery */ -export interface SettingResult { - currentPlayer: { - name: string; - userIcon: { - url: string; - }; - }; -} - -/** 10e1d424391e78d21670227550b3509f StageScheduleQuery */ -export interface StageScheduleResult { - regularSchedules: NodeList>; - bankaraSchedules: NodeList>; - xSchedules: NodeList>; - leagueSchedules: NodeList>; - coopGroupingSchedule: { - regularSchedules: NodeList; - bigRunSchedules: NodeList; - }; - festSchedules: NodeList; - currentFest: SchedulesCurrentFest | null; - currentPlayer: { - userIcon: { - url: string; - }; - }; - vsStages: NodeList; -} - -interface Schedule { - startTime: string; // "2022-09-09T08:00:00Z" - endTime: string; // "2022-09-09T10:00:00Z" -} - -type ScheduleResult = NormalSchedule | FestActiveSchedule; -type NormalSchedule = T & { - festMatchSetting: null; -}; -type FestActiveSchedule = { - [K in keyof T]: - K extends `festMatchSetting` ? FestActiveSetting : - K extends `${string}MatchSetting${'' | 's'}` ? null : T[K]; -} & { - festMatchSetting: FestActiveSetting; -}; - -interface RegularSchedule extends Schedule { - regularMatchSetting: RegularMatchSetting; -} -interface RegularMatchSetting { - __isVsSetting: 'RegularMatchSetting'; - __typename: 'RegularMatchSetting'; - vsStages: VsStage[]; - vsRule: VsRule; -} - -interface BankaraSchedule extends Schedule { - bankaraMatchSettings: BankaraMatchSetting[]; -} -interface BankaraMatchSetting { - __isVsSetting: 'BankaraMatchSetting'; - __typename: 'BankaraMatchSetting'; - vsStages: VsStage[]; - vsRule: VsRule; - mode: BankaraMatchMode; -} - -export enum BankaraMatchMode { - CHALLENGE = 'CHALLENGE', - OPEN = 'OPEN', -} - -interface XSchedule extends Schedule { - xMatchSetting: XMatchSetting; -} -interface XMatchSetting { - __isVsSetting: 'XMatchSetting'; - __typename: 'XMatchSetting'; - vsStages: VsStage[]; - vsRule: VsRule; -} - -interface LeagueSchedule extends Schedule { - leagueMatchSetting: LeagueMatchSetting; -} -interface LeagueMatchSetting { - __isVsSetting: 'LeagueMatchSetting'; - __typename: 'LeagueMatchSetting'; - vsStages: VsStage[]; - vsRule: VsRule; -} - -interface VsStage { - id: string; // "VnNTdGFnZS0xMQ==" - vsStageId: number; // 11 - name: string; // "Museum d'Alfonsino" - image: { - url: string; - }; -} - -interface VsRule { - name: string; // "Turf War", "Rainmaker", "Tower Control", "Splat Zones", "Clam Blitz" - rule: string; // "TURF_WAR", "GOAL", "LOFT", "AREA", "CLAM" - id: string; // "VnNSdWxlLTA=", "VnNSdWxlLTM=", "VnNSdWxlLTI=", "VnNSdWxlLTE=", "VnNSdWxlLTQ=" -} - -interface CoopRegularSchedule { - startTime: string; // "2022-09-08T08:00:00Z" - endTime: string; // "2022-09-10T00:00:00Z" - setting: CoopNormalSetting; -} - -interface CoopNormalSetting { - __typename: 'CoopNormalSetting'; - coopStage: CoopStage; - weapons: CoopWeapon[]; -} - -interface CoopStage { - name: string; // "Sockeye Station" - coopStageId: number; // 2 - thumbnailImage: { - url: string; - }; - image: { - url: string; - }; - id: string; // "Q29vcFN0YWdlLTI=" -} - -interface CoopWeapon { - name: string; // "Splattershot Jr." - image: { - url: string; - }; -} - -interface SchedulesCurrentFest { - id: string; - title: string; - startTime: string; - endTime: string; - midtermTime: string; - state: FestState; - teams: SchedulesCurrentFestTeam[]; - tricolorStage: Omit; -} -interface SchedulesCurrentFestTeam { - id: string; - color: Colour; - /** null = not voted or not voted for this team */ - myVoteState: FestVoteState | null; - role: FestTeamRole | null; -} - -interface FestSchedule extends Schedule { - festMatchSetting: FestMatchSetting | null; -} -interface FestMatchSetting { - __isVsSetting: 'FestMatchSetting'; - __typename: 'FestMatchSetting'; - vsStages: VsStage[]; - vsRule: VsRule; - // ... -} - -interface FestActiveSetting { - __typename: 'FestMatchSetting'; -} - -interface VsStageDetail { - stageId: number; // 1 - id: string; // "VnNTdGFnZS0x" - originalImage: { - url: string; - }; - name: string; // "Scorch Gorge" - stats: VsStageStats | null; -} - -interface VsStageStats { - winRateAr: null; - winRateLf: null; - winRateGl: null; - winRateCl: null; -} - -/** dba47124d5ec3090c97ba17db5d2f4b3 HomeQuery */ -export interface HomeResult { - currentPlayer: { - weapon: { - image: { - url: string; - }; - id: string; - }; - }; - banners: HomeBanner[]; - /** - * Only includes up to 3 online friends that have played Splatoon 3, even if they are currently - * playing a different game. `totalCount` also only counts online friends. - */ - friends: NodeList; - footerMessages: HomeFooterMessage[]; -} - -interface HomeBanner { - image: { - url: string; - width: number; - height: number; - }; - message: string; - jumpTo: string; -} - -interface HomeFriend { - id: string; - nickname: string; - userIcon: { - height: number; - url: string; - width: number; - }; -} - -type HomeFooterMessage = FooterBigRunMessage | FooterFestMessage | FooterSeasonMessage; - -interface FooterBigRunMessage { - __typename: 'FooterBigRunMessage'; - bigRunState: 'SCHEDULED' | unknown; -} -interface FooterFestMessage { - __typename: 'FooterFestMessage'; - festState: FestState; - festTitle: string; -} -interface FooterSeasonMessage { - __typename: 'FooterSeasonMessage'; - seasonName: string; -} - -/** 994cf141e55213e6923426caf37a1934 VsHistoryDetailPagerRefetchQuery */ -export interface VsHistoryDetailPagerRefetchResult { - vsHistoryDetail: { - __typename: 'VsHistoryDetail'; - nextHistoryDetail: { - id: string; - } | null; - previousHistoryDetail: { - id: string; - } | null; - id: string; - }; -} - -/** cd82f2ade8aca7687947c5f3210805a6 VsHistoryDetailQuery */ -export interface VsHistoryDetailResult { - vsHistoryDetail: VsHistoryDetail; -} - -interface VsHistoryDetail { - __typename: 'VsHistoryDetail'; - id: string; - vsRule: VsRule; - vsMode: VsMode; - player: VsHistoryDetailPlayer; - judgement: Judgement; - myTeam: VsHistoryDetailTeam; - vsStage: { - name: string; // "Mincemeat Metalworks" - image: { - url: string; - }; - id: string; // "VnNTdGFnZS02" - }; - festMatch: FestMatchDetail | null; - knockout: JudgementKnockout; - otherTeams: VsHistoryDetailTeam[]; - bankaraMatch: BankaraMatchDetail | null; - xMatch: XMatchDetail | null; - duration: number; - playedTime: string; - awards: Award[]; - leagueMatch: unknown | null; - nextHistoryDetail: { - id: string; - } | null; - previousHistoryDetail: { - id: string; - } | null; -} - -interface FestMatchDetail { - myFestPower: number; - contribution: number; - jewel: number; - dragonMatchType: DragonMatchType; - // ... -} -interface BankaraMatchDetail { - earnedUdemaePoint: number; - mode: BankaraMatchMode; - // ... -} -interface XMatchDetail { - lastXPower: number; - entireXPower: number; - // ... -} - -interface BaseVsPlayer { - __isPlayer: 'VsPlayer'; - byname: string; // "Splatlandian Youth" - name: string; - nameId: string; - nameplate: Nameplate; - id: string; - paint: number; -} - -interface VsHistoryDetailPlayer extends BaseVsPlayer { - headGear: VsHistoryDetailPlayerHeadGear; - clothingGear: VsHistoryDetailPlayerClothingGear; - shoesGear: VsHistoryDetailPlayerShoesGear; -} -interface VsHistoryDetailPlayerHeadGear extends HeadGear { - originalImage: { - url: string; - }; - brand: GearBrand; -} -interface VsHistoryDetailPlayerClothingGear extends ClothingGear { - originalImage: { - url: string; - }; - brand: GearBrand; -} -interface VsHistoryDetailPlayerShoesGear extends ShoesGear { - originalImage: { - url: string; - }; - brand: GearBrand; -} - -interface VsHistoryDetailTeam { - color: Colour; - judgement: Judgement; - result: { - paintRatio: number; - score: number | null; - noroshi: number | null; - }; - tricolorRole: TricolourRole | null; - festTeamName: string | null; - players: VsPlayer[]; - order: number; -} - -interface VsPlayer extends BaseVsPlayer { - __typename: 'VsPlayer'; - isMyself: boolean; - weapon: ExtendedWeaponSet; - headGear: VsPlayerHeadGear; - clothingGear: VsPlayerClothingGear; - shoesGear: VsPlayerShoesGear; - species: Species; - result: { - kill: number; - death: number; - assist: number; - special: number; - noroshiTry: number | null; - }; - festDragonCert: FestDragonCert; -} - -interface GearBrand { - name: string; // "Forge" - image: { - url: string; - }; - id: string; // "QnJhbmQtNQ==" -} -interface VsPlayerHeadGear { - __isGear: 'HeadGear'; - name: string; - primaryGearPower: GearPower; - additionalGearPowers: GearPower[]; - originalImage: { - url: string; - }; - thumbnailImage: { - url: string; - }; - brand: GearBrand; -} -interface VsPlayerClothingGear { - __isGear: 'ClothingGear'; - name: string; - primaryGearPower: GearPower; - additionalGearPowers: GearPower[]; - originalImage: { - url: string; - }; - thumbnailImage: { - url: string; - }; - brand: GearBrand; -} -interface VsPlayerShoesGear { - __isGear: 'ShoesGear'; - name: string; - primaryGearPower: GearPower; - additionalGearPowers: GearPower[]; - originalImage: { - url: string; - }; - thumbnailImage: { - url: string; - }; - brand: GearBrand; -} - -interface Award { - name: string; // "#1 Turf Inker" - rank: string; // "GOLD" -} diff --git a/src/api/splatnet3.ts b/src/api/splatnet3.ts index 1d72428..bd2e7e9 100644 --- a/src/api/splatnet3.ts +++ b/src/api/splatnet3.ts @@ -1,11 +1,12 @@ import fetch, { Response } from 'node-fetch'; import createDebug from 'debug'; +import { GraphQLRequest, GraphQLResponse, KnownRequestId, RequestId, RequestParametersFor, RequestResultFor } from 'splatnet3-types/splatnet3'; import { WebServiceToken } from './coral-types.js'; import { NintendoAccountUser } from './na.js'; import { defineResponse, ErrorResponse, HasResponse } from './util.js'; import CoralApi from './coral.js'; import { timeoutSignal } from '../util/misc.js'; -import { BankaraBattleHistoriesResult, BattleHistoryCurrentPlayerResult, BulletToken, CurrentFestResult, FriendListResult, GraphQLRequest, GraphQLResponse, HistoryRecordResult, HomeResult, LatestBattleHistoriesResult, PrivateBattleHistoriesResult, RegularBattleHistoriesResult, RequestId, SettingResult, StageScheduleResult, VsHistoryDetailResult, CoopHistoryResult, CoopHistoryDetailResult, FestRecordResult, FestRecordRefetchResult, DetailFestRecordDetailResult, DetailVotingStatusResult, DetailFestVotingStatusRefetchResult, VotesUpdateFestVoteResult, VsHistoryDetailPagerRefetchResult } from './splatnet3-types.js'; +import { BulletToken } from './splatnet3-types.js'; const debug = createDebug('nxapi:api:splatnet3'); @@ -107,7 +108,11 @@ export default class SplatNet3Api { return defineResponse(data, response); } - async persistedQuery(id: string, variables: V) { + async persistedQuery< + I extends string, + T = I extends KnownRequestId ? RequestResultFor : unknown, + V = I extends KnownRequestId ? RequestParametersFor : unknown, + >(id: I, variables: V) { const req: GraphQLRequest = { variables, extensions: { @@ -125,11 +130,11 @@ export default class SplatNet3Api { } async getHome() { - return this.persistedQuery(RequestId.HomeQuery, {}); + return this.persistedQuery(RequestId.HomeQuery, {}); } async getCurrentFest() { - return this.persistedQuery(RequestId.CurrentFestQuery, {}); + return this.persistedQuery(RequestId.CurrentFestQuery, {}); } async getConfigureAnalytics() { @@ -137,102 +142,102 @@ export default class SplatNet3Api { } async getSettings() { - return this.persistedQuery(RequestId.SettingQuery, {}); + return this.persistedQuery(RequestId.SettingQuery, {}); } async getFestRecords() { - return this.persistedQuery(RequestId.FestRecordQuery, {}); + return this.persistedQuery(RequestId.FestRecordQuery, {}); } async getFestRecordsRefetch() { - return this.persistedQuery(RequestId.FestRecordRefetchQuery, {}); + return this.persistedQuery(RequestId.FestRecordRefetchQuery, {}); } async getFestDetail(id: string) { - return this.persistedQuery(RequestId.DetailFestRecordDetailQuery, { + return this.persistedQuery(RequestId.DetailFestRecordDetailQuery, { festId: id, }); } async getFestDetailRefetch(id: string) { - return this.persistedQuery(RequestId.DetailFestRefethQuery, { + return this.persistedQuery(RequestId.DetailFestRefethQuery, { festId: id, }); } async getFestVotingStatus(id: string) { - return this.persistedQuery(RequestId.DetailVotingStatusQuery, { + return this.persistedQuery(RequestId.DetailVotingStatusQuery, { festId: id, }); } async getFestVotingStatusRefetch(id: string) { - return this.persistedQuery(RequestId.DetailFestVotingStatusRefethQuery, { + return this.persistedQuery(RequestId.DetailFestVotingStatusRefethQuery, { festId: id, }); } async updateFestPoll(id: string) { - return this.persistedQuery(RequestId.VotesUpdateFestVoteMutation, { + return this.persistedQuery(RequestId.VotesUpdateFestVoteMutation, { teamId: id, }); } async getFriends() { - return this.persistedQuery(RequestId.FriendListQuery, {}); + return this.persistedQuery(RequestId.FriendListQuery, {}); } async getFriendsRefetch() { - return this.persistedQuery(RequestId.FriendListRefetchQuery, {}); + return this.persistedQuery(RequestId.FriendListRefetchQuery, {}); } async getHistoryRecords() { - return this.persistedQuery(RequestId.HistoryRecordQuery, {}); + return this.persistedQuery(RequestId.HistoryRecordQuery, {}); } async getSchedules() { - return this.persistedQuery(RequestId.StageScheduleQuery, {}); + return this.persistedQuery(RequestId.StageScheduleQuery, {}); } async getBattleHistoryCurrentPlayer() { - return this.persistedQuery(RequestId.BattleHistoryCurrentPlayerQuery, {}); + return this.persistedQuery(RequestId.BattleHistoryCurrentPlayerQuery, {}); } async getLatestBattleHistories() { - return this.persistedQuery(RequestId.LatestBattleHistoriesQuery, {}); + return this.persistedQuery(RequestId.LatestBattleHistoriesQuery, {}); } async getRegularBattleHistories() { - return this.persistedQuery(RequestId.RegularBattleHistoriesQuery, {}); + return this.persistedQuery(RequestId.RegularBattleHistoriesQuery, {}); } async getBankaraBattleHistories() { - return this.persistedQuery(RequestId.BankaraBattleHistoriesQuery, {}); + return this.persistedQuery(RequestId.BankaraBattleHistoriesQuery, {}); } async getPrivateBattleHistories() { - return this.persistedQuery(RequestId.PrivateBattleHistoriesQuery, {}); + return this.persistedQuery(RequestId.PrivateBattleHistoriesQuery, {}); } async getBattleHistoryDetail(id: string) { - return this.persistedQuery(RequestId.VsHistoryDetailQuery, { + return this.persistedQuery(RequestId.VsHistoryDetailQuery, { vsResultId: id, }); } async getBattleHistoryDetailPagerRefetch(id: string) { - return this.persistedQuery(RequestId.VsHistoryDetailPagerRefetchQuery, { + return this.persistedQuery(RequestId.VsHistoryDetailPagerRefetchQuery, { vsResultId: id, }); } async getCoopHistory() { - return this.persistedQuery(RequestId.CoopHistoryQuery, {}); + return this.persistedQuery(RequestId.CoopHistoryQuery, {}); } async getCoopHistoryDetail(id: string) { - return this.persistedQuery(RequestId.CoopHistoryDetailQuery, { - coopHistoryDetailId: id + return this.persistedQuery(RequestId.CoopHistoryDetailQuery, { + coopHistoryDetailId: id, }); } diff --git a/src/cli/presence-server.ts b/src/cli/presence-server.ts index b449954..3313114 100644 --- a/src/cli/presence-server.ts +++ b/src/cli/presence-server.ts @@ -1,11 +1,11 @@ import * as net from 'node:net'; import createDebug from 'debug'; -import express, { Request, Response } from 'express'; +import express from 'express'; import * as persist from 'node-persist'; +import { BankaraMatchMode, BankaraMatchSetting, CoopSetting, DetailVotingStatusResult, FestMatchSetting, FestState, FestTeam_schedule, FestTeam_votingStatus, FestVoteState, Fest_schedule, Friend as SplatNetFriend, FriendListResult, FriendOnlineState, GraphQLResponse, LeagueMatchSetting, RegularMatchSetting, StageScheduleResult, XMatchSetting } from 'splatnet3-types/splatnet3'; import type { Arguments as ParentArguments } from '../cli.js'; import { ArgumentsCamelCase, Argv, YargsArguments } from '../util/yargs.js'; import { initStorage } from '../util/storage.js'; -import { SavedToken } from '../common/auth/coral.js'; import { addCliFeatureUserAgent } from '../util/useragent.js'; import { parseListenAddress } from '../util/net.js'; import { product } from '../util/product.js'; @@ -13,7 +13,6 @@ import Users, { CoralUser } from '../common/users.js'; import { Friend } from '../api/coral-types.js'; import { getBulletToken, SavedBulletToken } from '../common/auth/splatnet3.js'; import SplatNet3Api from '../api/splatnet3.js'; -import { BankaraMatchMode, DetailVotingStatusResult, FestState, FestVoteState, FriendListResult, FriendOnlineState, GraphQLResponse, StageScheduleResult } from '../api/splatnet3-types.js'; const debug = createDebug('cli:presence-server'); @@ -131,12 +130,12 @@ export class SplatNet3User { } } - async getFriends(): Promise { + async getFriends(): Promise { await this.update('friends', async () => { this.friends = await this.splatnet.getFriendsRefetch(); }, this.update_interval); - return this.friends.data.friends; + return this.friends.data.friends.nodes; } async getSchedules(): Promise { @@ -145,7 +144,7 @@ export class SplatNet3User { if (this.schedules && this.schedules.data.currentFest) { const tricolour_open = new Date(this.schedules.data.currentFest.midtermTime).getTime() <= Date.now(); const should_refresh_fest = tricolour_open && - ![FestState.SECOND_HALF, FestState.CLOSED].includes(this.schedules.data.currentFest.state); + ![FestState.SECOND_HALF, FestState.CLOSED].includes(this.schedules.data.currentFest.state as FestState); if (should_refresh_fest) update_interval = this.update_interval; } @@ -207,8 +206,8 @@ function createApp( const include_splatnet3 = splatnet3_users && req.query['include-splatoon3'] === '1'; const result: (Friend & { - splatoon3?: FriendListResult['friends']['nodes'][0] | null; - splatoon3_fest_team?: Exclude['teams'][0] | null; + splatoon3?: SplatNetFriend | null; + splatoon3_fest_team?: FestTeam_votingStatus | null; })[] = []; const users = await Promise.all(user_ids.map(async id => { @@ -248,7 +247,7 @@ function createApp( const friends = await user.getFriends(); const fest_vote_status = await user.getCurrentFestVotes(); - for (const friend of friends.nodes) { + for (const friend of friends) { const friend_nsaid = Buffer.from(friend.id, 'base64').toString() .replace(/^Friend-([0-9a-f]{16})$/, '$1'); const match = result.find(f => f.nsaId === friend_nsaid); @@ -303,23 +302,16 @@ function createApp( let match_coral: Friend | null = null; let match_user_id: string | null = null; - let match_splatnet3: FriendListResult['friends']['nodes'][0] | null = null; - let match_splatnet3_fest_team: - Exclude['teams'][0] | null | undefined = undefined; - let match_splatnet3_fest_team_vote_status: - Exclude['teams'][0] | null | undefined = undefined; + let match_splatnet3: SplatNetFriend | null = null; + let match_splatnet3_fest_team: FestTeam_schedule | null | undefined = undefined; + let match_splatnet3_fest_team_vote_status: FestTeam_votingStatus | null | undefined = undefined; const additional_response_data: { splatoon3_vs_setting?: - StageScheduleResult['regularSchedules']['nodes'][0]['regularMatchSetting'] | - Exclude[0] | - StageScheduleResult['festSchedules']['nodes'][0]['festMatchSetting'] | - StageScheduleResult['leagueSchedules']['nodes'][0]['leagueMatchSetting'] | - StageScheduleResult['xSchedules']['nodes'][0]['xMatchSetting'] | - null; - splatoon3_coop_setting?: - StageScheduleResult['coopGroupingSchedule']['regularSchedules']['nodes'][0]['setting'] | null; - splatoon3_fest?: StageScheduleResult['currentFest'] | null; + RegularMatchSetting | BankaraMatchSetting | FestMatchSetting | + LeagueMatchSetting | XMatchSetting | null; + splatoon3_coop_setting?: CoopSetting | null; + splatoon3_fest?: Fest_schedule | null; } = {}; for (const user_naid of user_ids) { @@ -356,7 +348,7 @@ function createApp( const friends = await user.getFriends(); const fest_vote_status = await user.getCurrentFestVotes(); - for (const friend of friends.nodes) { + for (const friend of friends) { const friend_nsaid = Buffer.from(friend.id, 'base64').toString() .replace(/^Friend-([0-9a-f]{16})$/, '$1'); if (match_coral.nsaId !== friend_nsaid) continue; @@ -462,9 +454,8 @@ function createApp( } function createScheduleFest( - fest: Exclude, - vote_team?: string, state?: FestVoteState | null -): Exclude { + fest: Fest_schedule, vote_team?: string, state?: FestVoteState | null +): Fest_schedule { return { ...fest, teams: fest.teams.map(t => createFestScheduleTeam(t, t.id === vote_team ? state : null)), @@ -472,9 +463,8 @@ function createScheduleFest( } function createFestScheduleTeam( - team: Exclude['teams'][0], - state: FestVoteState | null = null -): Exclude['teams'][0] { + team: FestTeam_schedule, state: FestVoteState | null = null +): FestTeam_schedule { return { id: team.id, color: team.color, @@ -484,9 +474,8 @@ function createFestScheduleTeam( } function createFestVoteTeam( - team: Exclude['teams'][0], - state?: FestVoteState | null -): Exclude['teams'][0] { + team: FestTeam_votingStatus, state: FestVoteState | null +): FestTeam_votingStatus { return { id: team.id, teamName: team.teamName, diff --git a/src/cli/splatnet3/battles.ts b/src/cli/splatnet3/battles.ts index a9d6791..faaece5 100644 --- a/src/cli/splatnet3/battles.ts +++ b/src/cli/splatnet3/battles.ts @@ -1,10 +1,10 @@ import createDebug from 'debug'; +import { Judgement } from 'splatnet3-types/splatnet3'; import Table from '../util/table.js'; import type { Arguments as ParentArguments } from '../splatnet3.js'; import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js'; import { initStorage } from '../../util/storage.js'; import { getBulletToken } from '../../common/auth/splatnet3.js'; -import { Judgement } from '../../api/splatnet3-types.js'; const debug = createDebug('cli:splatnet3:battles'); diff --git a/src/cli/splatnet3/festival.ts b/src/cli/splatnet3/festival.ts index c2fae27..0867ac4 100644 --- a/src/cli/splatnet3/festival.ts +++ b/src/cli/splatnet3/festival.ts @@ -1,10 +1,10 @@ import createDebug from 'debug'; +import { FestState } from 'splatnet3-types/splatnet3'; import Table from '../util/table.js'; import type { Arguments as ParentArguments } from '../splatnet3.js'; import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js'; import { initStorage } from '../../util/storage.js'; import { getBulletToken } from '../../common/auth/splatnet3.js'; -import { FestState } from '../../api/splatnet3-types.js'; const debug = createDebug('cli:splatnet3:festival'); diff --git a/src/cli/splatnet3/friends.ts b/src/cli/splatnet3/friends.ts index 107251e..f9ce377 100644 --- a/src/cli/splatnet3/friends.ts +++ b/src/cli/splatnet3/friends.ts @@ -1,10 +1,10 @@ import createDebug from 'debug'; +import { FriendOnlineState } from 'splatnet3-types/splatnet3'; import Table from '../util/table.js'; import type { Arguments as ParentArguments } from '../splatnet3.js'; import { ArgumentsCamelCase, Argv, YargsArguments } from '../../util/yargs.js'; import { initStorage } from '../../util/storage.js'; import { getBulletToken } from '../../common/auth/splatnet3.js'; -import { FriendOnlineState } from '../../api/splatnet3-types.js'; const debug = createDebug('cli:splatnet3:friends'); diff --git a/src/discord/titles/nintendo/splatoon3.ts b/src/discord/titles/nintendo/splatoon3.ts index d4247fd..e7c2e8a 100644 --- a/src/discord/titles/nintendo/splatoon3.ts +++ b/src/discord/titles/nintendo/splatoon3.ts @@ -1,8 +1,8 @@ import createDebug from 'debug'; import persist from 'node-persist'; import DiscordRPC from 'discord-rpc'; +import { BankaraMatchMode, BankaraMatchSetting, CoopSchedule, CoopSetting, DetailVotingStatusResult, FestMatchSetting, FestState, FestTeamRole, FestTeam_schedule, FestTeam_votingStatus, Fest_schedule, FriendListResult, FriendOnlineState, GraphQLResponse, LeagueMatchSetting, RegularMatchSetting, StageScheduleResult, VsSchedule_bankara, VsSchedule_fest, VsSchedule_league, VsSchedule_regular, VsSchedule_xMatch, XMatchSetting } from 'splatnet3-types/splatnet3'; import { Game } from '../../../api/coral-types.js'; -import { BankaraMatchMode, DetailVotingStatusResult, FestState, FestTeamRole, FriendListResult, FriendOnlineState, GraphQLResponse, StageScheduleResult } from '../../../api/splatnet3-types.js'; import SplatNet3Api from '../../../api/splatnet3.js'; import { DiscordPresenceExternalMonitorsConfiguration } from '../../../app/common/types.js'; import { Arguments } from '../../../cli/nso/presence.js'; @@ -27,15 +27,15 @@ export default class SplatNet3Monitor extends EmbeddedLoop { friend: FriendListResult['friends']['nodes'][0] | null = null; - regular_schedule: StageScheduleResult['regularSchedules']['nodes'][0] | null = null; - anarchy_schedule: StageScheduleResult['bankaraSchedules']['nodes'][0] | null = null; - fest_schedule: StageScheduleResult['festSchedules']['nodes'][0] | null = null; - league_schedule: StageScheduleResult['leagueSchedules']['nodes'][0] | null = null; - x_schedule: StageScheduleResult['xSchedules']['nodes'][0] | null = null; - coop_schedule: StageScheduleResult['coopGroupingSchedule']['regularSchedules']['nodes'][0] | null = null; - fest: StageScheduleResult['currentFest'] | null = null; - fest_team_voting_status: Exclude['teams'][0] | null = null; - fest_team: Exclude['teams'][0] | null = null; + regular_schedule: VsSchedule_regular | null = null; + anarchy_schedule: VsSchedule_bankara | null = null; + fest_schedule: VsSchedule_fest | null = null; + league_schedule: VsSchedule_league | null = null; + x_schedule: VsSchedule_xMatch | null = null; + coop_schedule: CoopSchedule | null = null; + fest: Fest_schedule | null = null; + fest_team_voting_status: FestTeam_votingStatus | null = null; + fest_team: FestTeam_schedule | null = null; constructor( readonly discord_presence: ExternalMonitorPresenceInterface, @@ -119,7 +119,7 @@ export default class SplatNet3Monitor extends EmbeddedLoop { // to check if the player may join a Tricolour battle const tricolour_open = this.fest && new Date(this.fest.midtermTime).getTime() < Date.now(); const should_refresh_fest = this.fest && tricolour_open && - ![FestState.SECOND_HALF, FestState.CLOSED].includes(this.fest.state); + ![FestState.SECOND_HALF, FestState.CLOSED].includes(this.fest.state as FestState); this.regular_schedule = this.getSchedule(this.cached_schedules?.data.regularSchedules.nodes ?? []); @@ -220,19 +220,12 @@ export function getConfigFromAppConfig( interface PresenceUrlResponse { splatoon3?: FriendListResult['friends']['nodes'][0] | null; - splatoon3_fest_team?: - (Exclude['teams'][0] & - Exclude['teams'][0]) | null; + splatoon3_fest_team?: (FestTeam_votingStatus & FestTeam_schedule) | null; splatoon3_vs_setting?: - StageScheduleResult['regularSchedules']['nodes'][0]['regularMatchSetting'] | - Exclude[0] | - StageScheduleResult['festSchedules']['nodes'][0]['festMatchSetting'] | - StageScheduleResult['leagueSchedules']['nodes'][0]['leagueMatchSetting'] | - StageScheduleResult['xSchedules']['nodes'][0]['xMatchSetting'] | - null; - splatoon3_coop_setting?: - StageScheduleResult['coopGroupingSchedule']['regularSchedules']['nodes'][0]['setting'] | null; - splatoon3_fest?: StageScheduleResult['currentFest'] | null; + RegularMatchSetting | BankaraMatchSetting | FestMatchSetting | + LeagueMatchSetting | XMatchSetting | null; + splatoon3_coop_setting?: CoopSetting | null; + splatoon3_fest?: Fest_schedule | null; } export function callback(activity: DiscordRPC.Presence, game: Game, context?: DiscordPresenceContext) { diff --git a/src/exports/splatnet3.ts b/src/exports/splatnet3.ts index f394c3c..18c07f5 100644 --- a/src/exports/splatnet3.ts +++ b/src/exports/splatnet3.ts @@ -3,4 +3,4 @@ export { SplatNet3AuthData, } from '../api/splatnet3.js'; -export * from '../api/splatnet3-types.js'; +// export * from '../api/splatnet3-types.js';