diff --git a/data b/data index 2934e41..ad3bfdc 160000 --- a/data +++ b/data @@ -1 +1 @@ -Subproject commit 2934e4126602be0fa6e6265f04dac505a0d80ce4 +Subproject commit ad3bfdc228d636434d820046cf0141a80b93efdc diff --git a/data_model/actual_data/character.py b/data_model/actual_data/character.py index ba586f8..9a57470 100644 --- a/data_model/actual_data/character.py +++ b/data_model/actual_data/character.py @@ -2,11 +2,12 @@ from .used_by import BaseUsedBy, OrderedDictWithCounter, UsedByToJsonMixin, UsedByRegisterMixin from .related_to import BaseRelatedTo, RelatedToJsonMixin, RelatedToRegisterMixin from ..constant.file_type import FILETYPES_STORY, FILETYPES_TRACK, FILE_STORY_EVENT, FILE_BATTLE_EVENT, \ - FILETYPES_CHARACTER, FILETYPES_BACKGROUND, FILE_BACKGROUND_INFO + FILETYPES_CHARACTER, FILETYPES_BACKGROUND, FILE_BACKGROUND_INFO, FILE_BACKGROUND_INFO_DIRECT, \ + FILE_BACKGROUND_INFO_INDIRECT_COMMS from ..types.metatype.base_model import BaseDataModelListManager from ..types.url import UrlModel from ..tool.interpage import InterpageMixin -from ..tool.tool import counter_dict_sorter, PostExecutionManager +from ..tool.tool import counter_dict_sorter, PostExecutionManager, ObjectAccessProxier class CharacterRelatedTo(BaseRelatedTo, RelatedToJsonMixin): @@ -50,13 +51,16 @@ def register(self, file_loader: FileLoader, related_to_keyname: str, auto_regist class CharacterUsedBy(BaseUsedBy, UsedByToJsonMixin): SUPPORTED_FILETYPE = [*FILETYPES_STORY, *FILETYPES_TRACK, *FILETYPES_BACKGROUND, *FILETYPES_CHARACTER, FILE_STORY_EVENT] - _components = ["data_story", "data_track", "data_background", "data_background_direct", "data_character"] + _components = ["data_story", "data_track", "data_background", "data_background_direct", "data_background_by_comm", + "data_character"] def __init__(self): self.data_story = OrderedDictWithCounter() self.data_track = OrderedDictWithCounter() self.data_background = OrderedDictWithCounter() self.data_background_direct = OrderedDictWithCounter() + # by_comm 指的就是,只是在通讯过程中出现在这个背景里,而并不实际在背景里出现 + self.data_background_by_comm = OrderedDictWithCounter() self.data_character = OrderedDictWithCounter() def register(self, file_loader: FileLoader, count_increase=True): @@ -77,8 +81,10 @@ def register(self, file_loader: FileLoader, count_increase=True): self.data_background[instance_id] = file_loader if not count_increase: self.data_background.counter_adjust(instance_id, -1) - else: + elif filetype == FILE_BACKGROUND_INFO_DIRECT: self.data_background_direct[instance_id] = file_loader + elif filetype == FILE_BACKGROUND_INFO_INDIRECT_COMMS: + self.data_background_by_comm[instance_id] = file_loader elif filetype in FILETYPES_CHARACTER: self.data_character[instance_id] = file_loader if not count_increase: @@ -93,6 +99,9 @@ def to_json(self, no_used_by: bool = True): d["data_background_direct"] = counter_dict_sorter( self.data_background_direct.get_counter_with_data_sorted_by_counter(), ["filename"]) + d["data_background_by_comm"] = counter_dict_sorter( + self.data_background_by_comm.get_counter_with_data_sorted_by_counter(), + ["filename"]) d["data_character"] = counter_dict_sorter(self.data_character.get_counter_with_data_sorted_by_counter(), [["name", "path_name"], ["name", "en"]]) d["data_background"] = counter_dict_sorter(self.data_background.get_counter_with_data_sorted_by_counter(), @@ -100,12 +109,71 @@ def to_json(self, no_used_by: bool = True): return d +class CharacterInfoIndirectProxy: + """ + 这个类干的东西基本上就是:接管原对象的 `used_by.register` 方法,然后把背景数据的filetype改一下实现特殊注册。 + """ + + class UsedByHandler(BaseUsedBy): + def __init__(self, real_obj): + self.real_obj = real_obj.used_by + + def register(self, file_loader: FileLoader, count_increase=True): + if file_loader.filetype in FILETYPES_BACKGROUND: + if file_loader.filetype != FILE_BACKGROUND_INFO_DIRECT: + self.real_obj.register( + ObjectAccessProxier(file_loader, {"filetype": FILE_BACKGROUND_INFO_INDIRECT_COMMS}), + count_increase) + else: + self.real_obj.register(file_loader, count_increase) + + def __init__(self, real_obj: "NpcInfo" or "StudentInfo"): + self.real_obj = real_obj + self._used_by_handler = self.UsedByHandler(real_obj) + + @property + def used_by(self): + return self._used_by_handler + + def register(self, file_loader: FileLoader, count_increase=True): + self.used_by.register(file_loader, count_increase) + + def __getattr__(self, item): + return getattr(self.real_obj, item) + + +class CharacterInfoProxyComm(CharacterInfoIndirectProxy): + pass + + +class CharacterInfoProxyNarrative(CharacterInfoIndirectProxy): + pass + + class CharacterInfo(FileLoader, InterpageMixin, UsedByRegisterMixin, RelatedToRegisterMixin): _instance = {} @classmethod def get_instance(cls, instance_id): + def return_instance(instance): + if is_comm: + return CharacterInfoProxyComm(instance) + elif is_narrative: + return CharacterInfoProxyNarrative(instance) + return instance + instance_id = instance_id.upper() + is_comm, is_narrative = False, False + + # 考虑是不是comm特殊例 + if instance_id.endswith("(COMM)") or instance_id.endswith("_COMM"): + # 清除特殊标记 + instance_id = instance_id.replace("_COMM", "").replace("(COMM)", "") + is_comm = True + elif instance_id.endswith("(NARR)") or instance_id.endswith("_NARR"): + instance_id = instance_id.replace("_NARR", "").replace("(NARR)", "") + is_narrative = True + try: # If it's a student temp = super().get_instance(instance_id="STU_" + instance_id) @@ -123,11 +191,11 @@ def get_instance(cls, instance_id): # 还没有的话建议直接raise raise e else: - return temp + return return_instance(temp) else: - return temp + return return_instance(temp) else: - return temp + return return_instance(temp) def _get_instance_offset(self, offset: int): keys = list(self._instance.keys()) @@ -426,7 +494,22 @@ def load(self, data: list): self.character.append(StudentInfo.get_instance(i)) def to_json(self): - t = [i.to_json_basic() for i in self.character] + t = [] + for i in self.character: + temp = i.to_json_basic() + + if isinstance(i, CharacterInfoProxyComm): + temp["is_comm"] = True + temp["is_narrative"] = False + elif isinstance(i, CharacterInfoProxyNarrative): + temp["is_comm"] = False + temp["is_narrative"] = True + else: + temp["is_comm"] = False + temp["is_narrative"] = False + + t.append(temp) + return t def to_json_basic(self): diff --git a/data_model/actual_data/story.py b/data_model/actual_data/story.py index 7b22237..091599d 100644 --- a/data_model/actual_data/story.py +++ b/data_model/actual_data/story.py @@ -158,6 +158,7 @@ def to_json(self): t = { "uuid": self.uuid, "filetype": self.filetype, + "namespace": self.namespace, "name": self.name.to_json_basic(), "desc": [i for i in self.desc.to_json_basic()], @@ -214,6 +215,26 @@ def _get_instance_offset(self, offset: int): return instance + @staticmethod + def process_reference_data(data: dict): + try: + if data["module_name"] == "": + module_name = "data_model.actual_data.story" + else: + module_name = data["module_name"] + except KeyError: + module_name = "data_model.actual_data.story" + + try: + if data["model_name"] == "": + model_name = "StoryInfo" + else: + model_name = data["model_name"] + except KeyError: + model_name = "StoryInfo" + + return (module_name, model_name, data["instance_id"]) + @property def interpage_prev(self): try: @@ -222,7 +243,7 @@ def interpage_prev(self): return super().interpage_prev else: ref_data = self.data["interpage"]["prev"] - return ReferenceData(ref_data["module_name"], ref_data["model_name"], ref_data["instance_id"]).ref_instance + return ReferenceData(*self.process_reference_data(ref_data)).ref_instance @property def interpage_next(self): @@ -232,7 +253,7 @@ def interpage_next(self): return super().interpage_next else: ref_data = self.data["interpage"]["next"] - return ReferenceData(ref_data["module_name"], ref_data["model_name"], ref_data["instance_id"]).ref_instance + return ReferenceData(*self.process_reference_data(ref_data)).ref_instance class StoryInfoBond(FileLoader, IParentData, InterpageMixin): @@ -297,6 +318,7 @@ def to_json(self): t = { "uuid": self.uuid, "filetype": self.filetype, + "namespace": self.namespace, "name": self.name.to_json_basic(), "desc": [i for i in self.desc.to_json_basic()], diff --git a/data_model/constant/file_type.py b/data_model/constant/file_type.py index 7628d13..873af26 100644 --- a/data_model/constant/file_type.py +++ b/data_model/constant/file_type.py @@ -36,6 +36,7 @@ FILE_BACKGROUND_INFO = 71 FILE_BACKGROUND_INFO_DIRECT = 72 +FILE_BACKGROUND_INFO_INDIRECT_COMMS = 73 FILE_VIRTUAL_DATA = 81 FILE_REFERENCE_DATA = 82 @@ -89,7 +90,7 @@ FILETYPES_STORY = [FILE_STORY_MAIN, FILE_STORY_SIDE, FILE_STORY_SHORT, FILE_STORY_BOND, FILE_STORY_OTHER] FILETYPES_BATTLE = [FILE_BATTLE_MAIN, FILE_BATTLE_ARENA, FILE_BATTLE_TOTAL_ASSAULT, FILE_BATTLE_BOUNTY_HUNT, FILE_BATTLE_SCHOOL_EXCHANGE, FILE_BATTLE_SPECIAL_COMMISSION, FILE_BATTLE_WORLD_RAID] -FILETYPES_BACKGROUND = [FILE_BACKGROUND_INFO, FILE_BACKGROUND_INFO_DIRECT] +FILETYPES_BACKGROUND = [FILE_BACKGROUND_INFO, FILE_BACKGROUND_INFO_DIRECT, FILE_BACKGROUND_INFO_INDIRECT_COMMS] FILETYPES_CHARACTER = [FILE_STUDENT_INFO, FILE_CHARACTER_INFO] FILETYPES_TRACK_DIR = [FILE_DIR_TRACK_ALL, FILE_DIR_TRACK_CATEGORY] diff --git a/data_model/loader/_loader.py b/data_model/loader/_loader.py index 09a1a66..4884006 100644 --- a/data_model/loader/_loader.py +++ b/data_model/loader/_loader.py @@ -81,7 +81,10 @@ def auto_include(self): @staticmethod def sort_by_int(item): - return int(item[:-5]) + try: + return str(int(item[:-5])).rjust(3, "0") + except ValueError: + return item def process(self): from .loader_detect import get_loader_by_filepath diff --git a/data_model/loader/folder_loader.py b/data_model/loader/folder_loader.py index a32c469..1422948 100644 --- a/data_model/loader/folder_loader.py +++ b/data_model/loader/folder_loader.py @@ -239,6 +239,11 @@ def to_json_basic(self): pass return d + def auto_include(self): + temp = super().auto_include() + temp.sort(key=self.sort_by_int) + return temp + class AlbumLoader(GenericFolder): def __init__(self, namespace: list, basepath, json_data=None, parent_data=None):