feat: wrap all objects on /resource endpoint
This commit is contained in:
parent
891cf71aa7
commit
69a53da8ae
@ -4,11 +4,35 @@ Class wrapper for API endpoint /resource
|
|||||||
|
|
||||||
|
|
||||||
class Segment:
|
class Segment:
|
||||||
|
"""
|
||||||
|
A segment of the game archive.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
path (str): Segment download path.
|
||||||
|
md5 (str): Segment md5 checksum.
|
||||||
|
package_size (int | None): Segment package size.
|
||||||
|
"""
|
||||||
|
|
||||||
path: str
|
path: str
|
||||||
md5: str
|
md5: str
|
||||||
# str -> int and checked if int is 0 then None
|
# str -> int and checked if int is 0 then None
|
||||||
package_size: int | None
|
package_size: int | None
|
||||||
|
|
||||||
|
def __init__(self, path: str, md5: str, package_size: int | None) -> None:
|
||||||
|
self.path = path
|
||||||
|
self.md5 = md5
|
||||||
|
self.package_size = package_size
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_dict(data: dict) -> "Segment":
|
||||||
|
return Segment(
|
||||||
|
data["path"],
|
||||||
|
data["md5"],
|
||||||
|
int(data["package_size"])
|
||||||
|
if data["package_size"] and data["package_size"] != "0"
|
||||||
|
else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class VoicePack:
|
class VoicePack:
|
||||||
"""
|
"""
|
||||||
@ -17,7 +41,12 @@ class VoicePack:
|
|||||||
`name` maybe converted from `path` if the server returns empty string.
|
`name` maybe converted from `path` if the server returns empty string.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
TODO
|
language (str): Language of the voice pack.
|
||||||
|
name (str): Voice pack archive name.
|
||||||
|
path (str): Voice pack download path.
|
||||||
|
size (int): Voice pack size.
|
||||||
|
md5 (str): Voice pack md5 checksum.
|
||||||
|
package_size (int): Voice pack package size.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
language: str
|
language: str
|
||||||
@ -29,6 +58,33 @@ class VoicePack:
|
|||||||
# str -> int
|
# str -> int
|
||||||
package_size: int
|
package_size: int
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
language: str,
|
||||||
|
name: str,
|
||||||
|
path: str,
|
||||||
|
size: int,
|
||||||
|
md5: str,
|
||||||
|
package_size: int,
|
||||||
|
) -> None:
|
||||||
|
self.language = language
|
||||||
|
self.name = name
|
||||||
|
self.path = path
|
||||||
|
self.size = size
|
||||||
|
self.md5 = md5
|
||||||
|
self.package_size = package_size
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_dict(data: dict) -> "VoicePack":
|
||||||
|
return VoicePack(
|
||||||
|
data["language"],
|
||||||
|
data["name"],
|
||||||
|
data["path"],
|
||||||
|
int(data["size"]),
|
||||||
|
data["md5"],
|
||||||
|
int(data["package_size"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Diff:
|
class Diff:
|
||||||
"""
|
"""
|
||||||
@ -49,6 +105,39 @@ class Diff:
|
|||||||
# str -> int
|
# str -> int
|
||||||
package_size: int
|
package_size: int
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name: str,
|
||||||
|
version: str,
|
||||||
|
path: str,
|
||||||
|
size: int,
|
||||||
|
md5: str,
|
||||||
|
is_recommended_update: bool,
|
||||||
|
voice_packs: list[VoicePack],
|
||||||
|
package_size: int,
|
||||||
|
) -> None:
|
||||||
|
self.name = name
|
||||||
|
self.version = version
|
||||||
|
self.path = path
|
||||||
|
self.size = size
|
||||||
|
self.md5 = md5
|
||||||
|
self.is_recommended_update = is_recommended_update
|
||||||
|
self.voice_packs = voice_packs
|
||||||
|
self.package_size = package_size
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_dict(data: dict) -> "Diff":
|
||||||
|
return Diff(
|
||||||
|
data["name"],
|
||||||
|
data["version"],
|
||||||
|
data["path"],
|
||||||
|
int(data["size"]),
|
||||||
|
data["md5"],
|
||||||
|
data["is_recommended_update"],
|
||||||
|
[VoicePack.from_dict(i) for i in data["voice_packs"]],
|
||||||
|
int(data["package_size"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class Latest:
|
class Latest:
|
||||||
"""
|
"""
|
||||||
@ -58,13 +147,35 @@ class Latest:
|
|||||||
and if `path` is empty too then it'll convert the name from the first
|
and if `path` is empty too then it'll convert the name from the first
|
||||||
segment of `segments` list.
|
segment of `segments` list.
|
||||||
|
|
||||||
|
`path` maybe None if the server returns empty string, in that case
|
||||||
|
you'll have to download the game using `segments` list and merge them.
|
||||||
|
|
||||||
|
`voice_packs` will be empty for Star Rail, they force you to download
|
||||||
|
in-game instead.
|
||||||
|
|
||||||
|
`decompressed_path` is useful for repairing game files by only having
|
||||||
|
to re-download the corrupted files.
|
||||||
|
|
||||||
|
`segments` is a list of game archive segments, you'll have to download
|
||||||
|
them and merge them together to get the full game archive. Not available
|
||||||
|
on Star Rail.
|
||||||
|
|
||||||
Attributes:
|
Attributes:
|
||||||
TODO
|
name (str): Game archive name.
|
||||||
|
version (str): Game version in the archive.
|
||||||
|
path (str | None): Game archive download path.
|
||||||
|
size (int): Game archive size in bytes.
|
||||||
|
md5 (str): Game archive MD5 checksum.
|
||||||
|
entry (str): Game entry file (e.g. GenshinImpact.exe).
|
||||||
|
voice_packs (list[VoicePack]): Game voice packs.
|
||||||
|
decompressed_path (str | None): Game archive decompressed path.
|
||||||
|
segments (list[Segment]): Game archive segments.
|
||||||
|
package_size (int): Game archive package size in bytes.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
version: str
|
version: str
|
||||||
path: str
|
path: str | None
|
||||||
# str -> int
|
# str -> int
|
||||||
size: int
|
size: int
|
||||||
md5: str
|
md5: str
|
||||||
@ -110,14 +221,14 @@ class Latest:
|
|||||||
return Latest(
|
return Latest(
|
||||||
data["name"],
|
data["name"],
|
||||||
data["version"],
|
data["version"],
|
||||||
data["path"],
|
data["path"] if data["path"] != "" else None,
|
||||||
data["size"],
|
int(data["size"]),
|
||||||
data["md5"],
|
data["md5"],
|
||||||
data["entry"],
|
data["entry"],
|
||||||
[VoicePack.from_dict(i) for i in data["voice_packs"]],
|
[VoicePack.from_dict(i) for i in data["voice_packs"]],
|
||||||
data["decompressed_path"],
|
data["decompressed_path"] if data["decompressed_path"] != "" else None,
|
||||||
[Segment.from_dict(i) for i in data["segments"]],
|
[Segment.from_dict(i) for i in data["segments"]],
|
||||||
data["package_size"],
|
int(data["package_size"]),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -149,27 +260,96 @@ class Plugin:
|
|||||||
# str -> int
|
# str -> int
|
||||||
package_size: int
|
package_size: int
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
name: str,
|
||||||
|
version: str | None,
|
||||||
|
path: str,
|
||||||
|
size: int,
|
||||||
|
md5: str,
|
||||||
|
entry: str | None,
|
||||||
|
package_size: int,
|
||||||
|
) -> None:
|
||||||
|
self.name = name
|
||||||
|
self.version = version
|
||||||
|
self.path = path
|
||||||
|
self.size = size
|
||||||
|
self.md5 = md5
|
||||||
|
self.entry = entry
|
||||||
|
self.package_size = package_size
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_dict(data: dict) -> "Plugin":
|
||||||
|
return Plugin(
|
||||||
|
data["name"],
|
||||||
|
data["version"] if data["version"] != "" else None,
|
||||||
|
data["path"],
|
||||||
|
int(data["size"]),
|
||||||
|
data["md5"],
|
||||||
|
data["entry"] if data["entry"] != "" else None,
|
||||||
|
int(data["package_size"]),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class LauncherPlugin:
|
class LauncherPlugin:
|
||||||
plugins: list[Plugin]
|
plugins: list[Plugin]
|
||||||
# str -> int
|
# str -> int
|
||||||
version: int
|
version: int
|
||||||
|
|
||||||
|
def __init__(self, plugins: list[Plugin], version: int) -> None:
|
||||||
|
self.plugins = plugins
|
||||||
|
self.version = version
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_dict(data: dict) -> "LauncherPlugin":
|
||||||
|
return LauncherPlugin(
|
||||||
|
[Plugin.from_dict(i) for i in data["plugins"]], int(data["version"])
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class DeprecatedPackage:
|
class DeprecatedPackage:
|
||||||
name: str
|
name: str
|
||||||
md5: str
|
md5: str
|
||||||
|
|
||||||
|
def __init__(self, name: str, md5: str) -> None:
|
||||||
|
self.name = name
|
||||||
|
self.md5 = md5
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_dict(data: dict) -> "DeprecatedPackage":
|
||||||
|
return DeprecatedPackage(data["name"], data["md5"])
|
||||||
|
|
||||||
|
|
||||||
class DeprecatedFile:
|
class DeprecatedFile:
|
||||||
path: str
|
path: str
|
||||||
# str but checked for empty string
|
# str but checked for empty string
|
||||||
md5: str | None
|
md5: str | None
|
||||||
|
|
||||||
|
def __init__(self, path: str, md5: str | None) -> None:
|
||||||
|
self.path = path
|
||||||
|
self.md5 = md5
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_dict(data: dict) -> "DeprecatedFile":
|
||||||
|
return DeprecatedFile(data["path"], data["md5"] if data["md5"] != "" else None)
|
||||||
|
|
||||||
|
|
||||||
class Resource:
|
class Resource:
|
||||||
"""
|
"""
|
||||||
Data class for /resource endpoint
|
Data class for /resource endpoint
|
||||||
|
|
||||||
|
I'm still unclear about `force_update` and `sdk` attributes, so I'll
|
||||||
|
leave them as None for now.
|
||||||
|
|
||||||
|
Attributes:
|
||||||
|
game (Game): Game resource information.
|
||||||
|
plugin (LauncherPlugin): Launcher plugin information.
|
||||||
|
web_url (str): Game official launcher web URL.
|
||||||
|
force_update (None): Not used by official launcher I guess?
|
||||||
|
pre_download_game (Game | None): Pre-download game resource information.
|
||||||
|
deprecated_packages (list[DeprecatedPackage]): Deprecated game packages.
|
||||||
|
sdk (None): Maybe for Bilibili version of Genshin?
|
||||||
|
deprecated_files (list[DeprecatedFile]): Deprecated game files.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# I'm generous enough to convert the string into int
|
# I'm generous enough to convert the string into int
|
||||||
@ -198,14 +378,6 @@ class Resource:
|
|||||||
sdk: None,
|
sdk: None,
|
||||||
deprecated_files: list[DeprecatedFile],
|
deprecated_files: list[DeprecatedFile],
|
||||||
) -> None:
|
) -> None:
|
||||||
# Fixups
|
|
||||||
game_latest_path = game.latest.path
|
|
||||||
if game.latest.name == "":
|
|
||||||
print("A")
|
|
||||||
if game_latest_path == "":
|
|
||||||
game.latest.name = game.latest.segments[0].path.split("/")[-1]
|
|
||||||
else:
|
|
||||||
game.latest.name = game_latest_path.split("/")[-1]
|
|
||||||
self.game = game
|
self.game = game
|
||||||
self.plugin = plugin
|
self.plugin = plugin
|
||||||
self.web_url = web_url
|
self.web_url = web_url
|
||||||
|
@ -10,7 +10,7 @@ def get_resource(channel: GameChannel = GameChannel.Overseas) -> Resource:
|
|||||||
Get game resource information from the launcher API.
|
Get game resource information from the launcher API.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
channel: Game channel to get the resource information from. (os, cn)
|
channel: Game channel to get the resource information from.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Resource: Game resource information.
|
Resource: Game resource information.
|
||||||
|
Loading…
Reference in New Issue
Block a user