artemis/core/adb_handlers/campaign.py

168 lines
4.6 KiB
Python
Raw Normal View History

2024-03-22 16:22:07 +00:00
from construct import Bytes, Int32sl, Int32ul, Padding, Struct
from .base import *
2024-03-22 16:22:07 +00:00
class Campaign:
def __init__(self) -> None:
self.id = 0
self.name = ""
self.announce_date = 0
self.start_date = 0
self.end_date = 0
self.distrib_start_date = 0
self.distrib_end_date = 0
2024-03-22 16:22:07 +00:00
def make(self) -> bytes:
name_padding = bytes(128 - len(self.name))
return Struct(
"id" / Int32ul,
"name" / Bytes(128),
"announce_date" / Int32ul,
"start_date" / Int32ul,
"end_date" / Int32ul,
"distrib_start_date" / Int32ul,
"distrib_end_date" / Int32ul,
Padding(8),
2024-03-22 16:22:07 +00:00
).build(
dict(
id=self.id,
name=self.name.encode() + name_padding,
announce_date=self.announce_date,
start_date=self.start_date,
end_date=self.end_date,
distrib_start_date=self.distrib_start_date,
distrib_end_date=self.distrib_end_date,
)
)
class CampaignClear:
def __init__(self) -> None:
self.id = 0
self.entry_flag = 0
self.clear_flag = 0
2024-03-22 16:22:07 +00:00
def make(self) -> bytes:
return Struct(
"id" / Int32ul,
"entry_flag" / Int32ul,
"clear_flag" / Int32ul,
Padding(4),
2024-03-22 16:22:07 +00:00
).build(
dict(
id=self.id,
entry_flag=self.entry_flag,
clear_flag=self.clear_flag,
)
)
class ADBCampaignResponse(ADBBaseResponse):
2024-03-22 16:22:07 +00:00
def __init__(
self,
game_id: str = "SXXX",
store_id: int = 1,
keychip_id: str = "A69E01A8888",
code: int = 0x0C,
length: int = 0x200,
status: int = 1,
) -> None:
super().__init__(code, length, status, game_id, store_id, keychip_id)
self.campaigns = [Campaign(), Campaign(), Campaign()]
2024-03-22 16:22:07 +00:00
2023-08-19 05:35:37 +00:00
@classmethod
def from_req(cls, req: ADBHeader) -> "ADBCampaignResponse":
c = cls(req.game_id, req.store_id, req.keychip_id)
c.head.protocol_ver = req.protocol_ver
return c
def make(self) -> bytes:
body = b""
2024-03-22 16:22:07 +00:00
for c in self.campaigns:
body += c.make()
2024-03-22 16:22:07 +00:00
self.head.length = HEADER_SIZE + len(body)
return self.head.make() + body
2024-03-22 16:22:07 +00:00
class ADBOldCampaignRequest(ADBBaseRequest):
def __init__(self, data: bytes) -> None:
super().__init__(data)
self.campaign_id = struct.unpack_from("<I", data, 0x20)
2024-03-22 16:22:07 +00:00
class ADBOldCampaignResponse(ADBBaseResponse):
2024-03-22 16:22:07 +00:00
def __init__(
self,
game_id: str = "SXXX",
store_id: int = 1,
keychip_id: str = "A69E01A8888",
code: int = 0x0C,
length: int = 0x30,
status: int = 1,
) -> None:
super().__init__(code, length, status, game_id, store_id, keychip_id)
self.info0 = 0
self.info1 = 0
self.info2 = 0
self.info3 = 0
2024-03-22 16:22:07 +00:00
2023-08-19 05:35:37 +00:00
@classmethod
def from_req(cls, req: ADBHeader) -> "ADBCampaignResponse":
c = cls(req.game_id, req.store_id, req.keychip_id)
c.head.protocol_ver = req.protocol_ver
return c
2024-03-22 16:22:07 +00:00
def make(self) -> bytes:
resp_struct = Struct(
"info0" / Int32sl,
"info1" / Int32sl,
"info2" / Int32sl,
"info3" / Int32sl,
).build(
2024-03-22 16:22:07 +00:00
info0=self.info0,
info1=self.info1,
info2=self.info2,
info3=self.info3,
)
self.head.length = HEADER_SIZE + len(resp_struct)
return self.head.make() + resp_struct
2024-03-22 16:22:07 +00:00
class ADBCampaignClearRequest(ADBBaseRequest):
def __init__(self, data: bytes) -> None:
super().__init__(data)
self.aime_id = struct.unpack_from("<i", data, 0x20)
2024-03-22 16:22:07 +00:00
class ADBCampaignClearResponse(ADBBaseResponse):
2024-03-22 16:22:07 +00:00
def __init__(
self,
game_id: str = "SXXX",
store_id: int = 1,
keychip_id: str = "A69E01A8888",
code: int = 0x0E,
length: int = 0x50,
status: int = 1,
) -> None:
super().__init__(code, length, status, game_id, store_id, keychip_id)
self.campaign_clear_status = [CampaignClear(), CampaignClear(), CampaignClear()]
2024-03-22 16:22:07 +00:00
2023-08-19 05:35:37 +00:00
@classmethod
def from_req(cls, req: ADBHeader) -> "ADBCampaignResponse":
c = cls(req.game_id, req.store_id, req.keychip_id)
c.head.protocol_ver = req.protocol_ver
return c
2024-03-22 16:22:07 +00:00
def make(self) -> bytes:
body = b""
2024-03-22 16:22:07 +00:00
for c in self.campaign_clear_status:
body += c.make()
2024-03-22 16:22:07 +00:00
self.head.length = HEADER_SIZE + len(body)
return self.head.make() + body