diff --git a/providers/miruro.js b/providers/miruro.js index 720d312..0e814e5 100644 --- a/providers/miruro.js +++ b/providers/miruro.js @@ -816,6 +816,19 @@ async function resolveSeasonEpisode(seed, mapping, identifier, season, episode) if (fromTags) { return { anime: seed, episode: fromTags }; } + const continuation = related.filter((anime) => !isMovieFormat(anime) && seasonOf(anime) != null && seasonOf(anime) >= requestedSeason && entryBelongsToRequest(anime, mapping, identifier)).sort((first, second) => seasonOf(first) - seasonOf(second) || clusterPosition(first) - clusterPosition(second)); + let offset = 0; + for (const anime of continuation) { + const episodes = anime.id === seed.id ? seedEpisodes : await listEpisodes(anime.id); + if (episodes.length === 0) { + continue; + } + const index = requestedEpisode - 1 - offset; + if (index >= 0 && index < episodes.length) { + return { anime, episode: episodes[index] }; + } + offset += episodes.length; + } const local = seedEpisodes.find((item) => Number(item.episode_number) === requestedEpisode); return local ? { anime: seed, episode: local } : null; } diff --git a/src/miruro/extractor.js b/src/miruro/extractor.js index c74769e..860648a 100644 --- a/src/miruro/extractor.js +++ b/src/miruro/extractor.js @@ -446,6 +446,39 @@ async function resolveSeasonEpisode(seed, mapping, identifier, season, episode) return { anime: seed, episode: fromTags }; } + // TMDB sometimes keeps one season while the catalog splits the same run + // into several seasons (The Ramparts of Ice: TMDB S1 episode 15 is catalog + // season 2 episode 1). Walk catalog seasons at or after the requested one + // in order, carrying an episode offset, so those episodes stay reachable. + const continuation = related + .filter((anime) => ( + !isMovieFormat(anime) && + seasonOf(anime) != null && + seasonOf(anime) >= requestedSeason && + entryBelongsToRequest(anime, mapping, identifier) + )) + .sort((first, second) => ( + seasonOf(first) - seasonOf(second) || + clusterPosition(first) - clusterPosition(second) + )); + let offset = 0; + + for (const anime of continuation) { + const episodes = anime.id === seed.id ? seedEpisodes : await listEpisodes(anime.id); + + if (episodes.length === 0) { + continue; + } + + const index = requestedEpisode - 1 - offset; + + if (index >= 0 && index < episodes.length) { + return { anime, episode: episodes[index] }; + } + + offset += episodes.length; + } + const local = seedEpisodes.find((item) => Number(item.episode_number) === requestedEpisode); return local ? { anime: seed, episode: local } : null;