From e91f84fecc7c6136fb05249cca3cf706cc973c62 Mon Sep 17 00:00:00 2001 From: Kevin Trocolli Date: Tue, 25 Jun 2024 14:02:53 -0400 Subject: [PATCH] sao: backport changes from diana --- .../versions/a616fd164e40_sao_backport.py | 723 + core/data/schema/card.py | 8 + example_config/sao.yaml | 11 +- titles/sao/__init__.py | 2 + titles/sao/base.py | 3153 +++- titles/sao/config.py | 44 +- titles/sao/const.py | 657 +- titles/sao/data/1/AcLoginBonuses.csv | Bin 0 -> 283 bytes titles/sao/data/1/AdBanners.csv | Bin 0 -> 59 bytes titles/sao/data/1/AppointLeaderEffect.csv | Bin 0 -> 925 bytes titles/sao/data/1/AppointLeaderEffectType.csv | Bin 0 -> 500 bytes titles/sao/data/1/AppointLeaderParam.csv | Bin 0 -> 166 bytes titles/sao/data/1/Awakening.csv | Bin 0 -> 159 bytes titles/sao/data/1/BattleCamera.csv | Bin 0 -> 162 bytes .../sao/data/1/BeginnerMissionConditions.csv | Bin 0 -> 2079 bytes titles/sao/data/1/BeginnerMissionRewards.csv | Bin 0 -> 812 bytes .../data/1/BeginnerMissionSeatConditions.csv | Bin 0 -> 419 bytes .../sao/data/1/BeginnerMissionSeatRewards.csv | Bin 0 -> 401 bytes titles/sao/data/1/BeginnerMissions.csv | Bin 0 -> 121 bytes titles/sao/data/1/BnidSerialCodeRewards.csv | Bin 0 -> 301 bytes titles/sao/data/1/BnidSerialCodes.csv | Bin 0 -> 92 bytes titles/sao/data/1/BossAttack.csv | Bin 0 -> 404017 bytes titles/sao/data/1/BuffItem.csv | Bin 0 -> 417 bytes titles/sao/data/1/BuyTicket.csv | Bin 0 -> 300 bytes titles/sao/data/1/Cap.csv | Bin 0 -> 27 bytes titles/sao/data/1/Chara.csv | Bin 0 -> 945 bytes titles/sao/data/1/CharaAttack.csv | Bin 0 -> 163449 bytes titles/sao/data/1/CharaComment.csv | Bin 0 -> 35771 bytes titles/sao/data/1/CharaFriendlyRank.csv | Bin 0 -> 913 bytes titles/sao/data/1/ChatEventStory.csv | Bin 0 -> 5154 bytes titles/sao/data/1/ChatMainStory.csv | Bin 0 -> 2392 bytes titles/sao/data/1/ChatSideStory.csv | Bin 0 -> 122156 bytes titles/sao/data/1/ComebackEvent.csv | Bin 0 -> 417 bytes titles/sao/data/1/CompositionEvent.csv | Bin 0 -> 129 bytes titles/sao/data/1/CompositionParam.csv | Bin 0 -> 104 bytes titles/sao/data/1/CostumeType.csv | Bin 0 -> 209 bytes titles/sao/data/1/DebugValidator.csv | Bin 0 -> 356 bytes titles/sao/data/1/DefragMatchAIPattern.csv | Bin 0 -> 274 bytes titles/sao/data/1/DefragMatchBossTable.csv | Bin 0 -> 8889 bytes titles/sao/data/1/DefragMatchChat.csv | Bin 0 -> 760 bytes .../sao/data/1/DefragMatchCpuSupportLogs.csv | Bin 0 -> 726 bytes titles/sao/data/1/DefragMatchCpuUnits.csv | Bin 0 -> 11687 bytes titles/sao/data/1/DefragMatchGrade.csv | Bin 0 -> 22852 bytes .../sao/data/1/DefragMatchPeriodBonuses.csv | Bin 0 -> 134736 bytes titles/sao/data/1/DefragMatchQuest.csv | Bin 0 -> 2205 bytes .../1/DefragMatchRandomBonusConditions.csv | Bin 0 -> 965 bytes .../data/1/DefragMatchRandomBonusTables.csv | Bin 0 -> 10097 bytes titles/sao/data/1/DefragMatchRareDrops.csv | Bin 0 -> 100597 bytes titles/sao/data/1/DefragMatchSeed.csv | Bin 0 -> 1372 bytes .../sao/data/1/DefragMatchSpecialEffects.csv | Bin 0 -> 1086 bytes titles/sao/data/1/DefragMatchs.csv | Bin 0 -> 1235 bytes titles/sao/data/1/Enemy.csv | Bin 0 -> 3606 bytes titles/sao/data/1/EnemyKind.csv | Bin 0 -> 49181 bytes titles/sao/data/1/EnemySet.csv | Bin 0 -> 1580 bytes titles/sao/data/1/Episode.csv | Bin 0 -> 12568 bytes titles/sao/data/1/EpisodeAppends.csv | Bin 0 -> 231 bytes titles/sao/data/1/EpisodeChapter.csv | Bin 0 -> 227 bytes titles/sao/data/1/EpisodePart.csv | Bin 0 -> 50 bytes titles/sao/data/{ => 1}/Equipment.csv | Bin 30612 -> 30498 bytes titles/sao/data/1/EquipmentLevel.csv | Bin 0 -> 2047 bytes titles/sao/data/1/Event.csv | Bin 0 -> 328 bytes titles/sao/data/1/EventItems.csv | Bin 0 -> 1656 bytes titles/sao/data/1/EventMonsters.csv | Bin 0 -> 548 bytes titles/sao/data/1/EventScenes.csv | Bin 0 -> 9002 bytes titles/sao/data/1/ExBonusCondition.csv | Bin 0 -> 740 bytes titles/sao/data/1/ExBonusTable.csv | Bin 0 -> 44094 bytes titles/sao/data/1/ExTowerQuests.csv | Bin 0 -> 4729 bytes titles/sao/data/1/ExTowers.csv | Bin 0 -> 472 bytes .../data/1/FirstTicketPurchaseCampaigns.csv | Bin 0 -> 278 bytes titles/sao/data/1/FixedFormChat.csv | Bin 0 -> 1545 bytes titles/sao/data/1/FixedFormChatText.csv | Bin 0 -> 15572 bytes titles/sao/data/1/Fragment.csv | Bin 0 -> 144 bytes titles/sao/data/1/GamePlayPrice.csv | Bin 0 -> 240 bytes titles/sao/data/1/GashaFreeCampaigns.csv | Bin 0 -> 139 bytes titles/sao/data/1/GashaMedalBonuses.csv | Bin 0 -> 317 bytes titles/sao/data/1/GashaMedalSettings.csv | Bin 0 -> 2700 bytes titles/sao/data/1/GashaMedalShopItems.csv | Bin 0 -> 47802 bytes titles/sao/data/{ => 1}/GashaMedalShops.csv | Bin 84824 -> 85709 bytes titles/sao/data/1/GashaMedalTypes.csv | Bin 0 -> 280 bytes titles/sao/data/1/GashaMedals.csv | Bin 0 -> 3172 bytes titles/sao/data/1/GenericCampaignPeriods.csv | Bin 0 -> 210 bytes titles/sao/data/1/GimmickAttack.csv | Bin 0 -> 18790 bytes titles/sao/data/{ => 1}/HeroLog.csv | Bin 306201 -> 305719 bytes titles/sao/data/1/HeroLogLevel.csv | Bin 0 -> 2141 bytes titles/sao/data/1/HeroLogRole.csv | Bin 0 -> 98 bytes titles/sao/data/1/HeroLogTrustRank.csv | Bin 0 -> 912 bytes titles/sao/data/{ => 1}/Item.csv | Bin 43814 -> 43610 bytes titles/sao/data/1/ItemType.csv | Bin 0 -> 412 bytes .../data/1/LinkedSiteRegCampaignRewards.csv | Bin 0 -> 371 bytes titles/sao/data/1/LinkedSiteRegCampaigns.csv | Bin 0 -> 269 bytes titles/sao/data/1/MenuDisplayEnemy.csv | Bin 0 -> 18768 bytes titles/sao/data/1/Mission.csv | Bin 0 -> 3747 bytes titles/sao/data/1/MissionClearText.csv | Bin 0 -> 1716 bytes titles/sao/data/1/MissionDifficulty.csv | Bin 0 -> 92 bytes titles/sao/data/1/MissionTable.csv | Bin 0 -> 830 bytes titles/sao/data/1/MonsterAction.csv | Bin 0 -> 738612 bytes titles/sao/data/1/MonsterAttack.csv | Bin 0 -> 76672 bytes titles/sao/data/1/NavigatorChara.csv | Bin 0 -> 103 bytes titles/sao/data/1/NavigatorComment.csv | Bin 0 -> 25795 bytes titles/sao/data/1/PayingYuiMedalBonuses.csv | Bin 0 -> 241 bytes titles/sao/data/1/PlayCampaignRewards.csv | Bin 0 -> 451 bytes titles/sao/data/1/PlayCampaigns.csv | Bin 0 -> 243 bytes titles/sao/data/1/PlayerRank.csv | Bin 0 -> 5656 bytes titles/sao/data/1/PlayerTraceTable.csv | Bin 0 -> 554 bytes titles/sao/data/1/Property.csv | Bin 0 -> 19611 bytes titles/sao/data/1/PropertyTable.csv | Bin 0 -> 155348 bytes titles/sao/data/1/PropertyType.csv | Bin 0 -> 5947 bytes titles/sao/data/1/QuestDropBoostCampaigns.csv | Bin 0 -> 204 bytes .../sao/data/1/QuestEpisodeAppendRewards.csv | Bin 0 -> 4996 bytes titles/sao/data/1/QuestExistUnit.csv | Bin 0 -> 173760 bytes titles/sao/data/1/QuestParam.csv | Bin 0 -> 91 bytes titles/sao/data/1/QuestRareDrop.csv | Bin 0 -> 40609 bytes titles/sao/data/{ => 1}/QuestScene.csv | Bin 68974 -> 68734 bytes .../data/1/QuestSpecialRareDropSettings.csv | Bin 0 -> 394 bytes titles/sao/data/1/QuestSpecialRareDrops.csv | Bin 0 -> 249 bytes titles/sao/data/1/QuestTutorial.csv | Bin 0 -> 6441 bytes titles/sao/data/1/Rarity.csv | Bin 0 -> 177 bytes .../sao/data/1/ResEarnCampaignShopItems.csv | Bin 0 -> 640 bytes titles/sao/data/1/ResEarnCampaignShops.csv | Bin 0 -> 826 bytes titles/sao/data/1/RewardSet.csv | Bin 0 -> 1241 bytes titles/sao/data/1/RewardTable.csv | Bin 0 -> 820935 bytes titles/sao/data/1/SideQuest.csv | Bin 0 -> 2554 bytes titles/sao/data/1/Skill.csv | Bin 0 -> 153697 bytes titles/sao/data/1/SkillCutInTextIndex.csv | Bin 0 -> 37061 bytes titles/sao/data/1/SkillCutin.csv | Bin 0 -> 63707 bytes titles/sao/data/1/SkillLevel.csv | Bin 0 -> 96 bytes titles/sao/data/1/SkillTable.csv | Bin 0 -> 226670 bytes titles/sao/data/1/SoundBgm.csv | Bin 0 -> 2890 bytes titles/sao/data/1/SoundSe.csv | Bin 0 -> 146198 bytes titles/sao/data/1/SoundUi.csv | Bin 0 -> 14151 bytes titles/sao/data/1/SoundVoice.csv | Bin 0 -> 364166 bytes titles/sao/data/1/Sound_SkillCutinVoice.csv | Bin 0 -> 12145 bytes titles/sao/data/1/SubStateMonster.csv | Bin 0 -> 17087 bytes titles/sao/data/{ => 1}/SupportLog.csv | Bin 379372 -> 378891 bytes titles/sao/data/1/SupportLogType.csv | Bin 0 -> 62 bytes titles/sao/data/1/SynchroSkill.csv | Bin 0 -> 5631 bytes titles/sao/data/1/Tips.csv | Bin 0 -> 30535 bytes titles/sao/data/1/Title.csv | Bin 0 -> 15959 bytes titles/sao/data/1/TreasureHuntTaskText.csv | Bin 0 -> 1014 bytes titles/sao/data/1/TrialTower.csv | Bin 0 -> 2116 bytes titles/sao/data/1/UnanalyzedLogGrade.csv | Bin 0 -> 170 bytes titles/sao/data/1/Unit.csv | Bin 0 -> 561120 bytes titles/sao/data/1/UnitCollision.csv | Bin 0 -> 365911 bytes titles/sao/data/1/UnitGimmick.csv | Bin 0 -> 15582 bytes titles/sao/data/1/UnitPower.csv | Bin 0 -> 104626 bytes titles/sao/data/1/WeaponType.csv | Bin 0 -> 843 bytes titles/sao/data/1/YuiMedalBonus.csv | Bin 0 -> 172 bytes titles/sao/data/1/YuiMedalBonusCondition.csv | Bin 0 -> 174 bytes titles/sao/data/1/YuiMedalGetCondition.csv | Bin 0 -> 864 bytes titles/sao/data/1/YuiMedalShopItems.csv | Bin 0 -> 41960 bytes titles/sao/data/{ => 1}/YuiMedalShops.csv | Bin 94750 -> 95542 bytes titles/sao/data/EquipmentLevel.csv | Bin 1211 -> 0 bytes titles/sao/data/GashaMedalShopItems.csv | Bin 46917 -> 0 bytes titles/sao/data/HeroLogLevel.csv | Bin 1249 -> 0 bytes titles/sao/data/PlayerRank.csv | Bin 3548 -> 0 bytes titles/sao/data/RareDropTable.csv | Bin 11849 -> 0 bytes titles/sao/data/ResEarnCampaignShopItems.csv | Bin 630 -> 0 bytes titles/sao/data/ResEarnCampaignShops.csv | Bin 816 -> 0 bytes titles/sao/data/RewardTable.csv | Bin 323785 -> 0 bytes titles/sao/data/Title.csv | Bin 16225 -> 0 bytes titles/sao/data/YuiMedalShopItems.csv | Bin 41168 -> 0 bytes titles/sao/frontend.py | 264 + titles/sao/handlers/base.py | 6277 ++++---- titles/sao/handlers/helpers.py | 12321 +++++++++++++++- titles/sao/index.py | 83 +- titles/sao/read.py | 400 +- titles/sao/schema/item.py | 429 +- titles/sao/schema/profile.py | 264 +- titles/sao/schema/static.py | 924 +- titles/sao/templates/sao_index.jinja | 182 + 170 files changed, 21389 insertions(+), 4353 deletions(-) create mode 100644 core/data/alembic/versions/a616fd164e40_sao_backport.py create mode 100644 titles/sao/data/1/AcLoginBonuses.csv create mode 100644 titles/sao/data/1/AdBanners.csv create mode 100644 titles/sao/data/1/AppointLeaderEffect.csv create mode 100644 titles/sao/data/1/AppointLeaderEffectType.csv create mode 100644 titles/sao/data/1/AppointLeaderParam.csv create mode 100644 titles/sao/data/1/Awakening.csv create mode 100644 titles/sao/data/1/BattleCamera.csv create mode 100644 titles/sao/data/1/BeginnerMissionConditions.csv create mode 100644 titles/sao/data/1/BeginnerMissionRewards.csv create mode 100644 titles/sao/data/1/BeginnerMissionSeatConditions.csv create mode 100644 titles/sao/data/1/BeginnerMissionSeatRewards.csv create mode 100644 titles/sao/data/1/BeginnerMissions.csv create mode 100644 titles/sao/data/1/BnidSerialCodeRewards.csv create mode 100644 titles/sao/data/1/BnidSerialCodes.csv create mode 100644 titles/sao/data/1/BossAttack.csv create mode 100644 titles/sao/data/1/BuffItem.csv create mode 100644 titles/sao/data/1/BuyTicket.csv create mode 100644 titles/sao/data/1/Cap.csv create mode 100644 titles/sao/data/1/Chara.csv create mode 100644 titles/sao/data/1/CharaAttack.csv create mode 100644 titles/sao/data/1/CharaComment.csv create mode 100644 titles/sao/data/1/CharaFriendlyRank.csv create mode 100644 titles/sao/data/1/ChatEventStory.csv create mode 100644 titles/sao/data/1/ChatMainStory.csv create mode 100644 titles/sao/data/1/ChatSideStory.csv create mode 100644 titles/sao/data/1/ComebackEvent.csv create mode 100644 titles/sao/data/1/CompositionEvent.csv create mode 100644 titles/sao/data/1/CompositionParam.csv create mode 100644 titles/sao/data/1/CostumeType.csv create mode 100644 titles/sao/data/1/DebugValidator.csv create mode 100644 titles/sao/data/1/DefragMatchAIPattern.csv create mode 100644 titles/sao/data/1/DefragMatchBossTable.csv create mode 100644 titles/sao/data/1/DefragMatchChat.csv create mode 100644 titles/sao/data/1/DefragMatchCpuSupportLogs.csv create mode 100644 titles/sao/data/1/DefragMatchCpuUnits.csv create mode 100644 titles/sao/data/1/DefragMatchGrade.csv create mode 100644 titles/sao/data/1/DefragMatchPeriodBonuses.csv create mode 100644 titles/sao/data/1/DefragMatchQuest.csv create mode 100644 titles/sao/data/1/DefragMatchRandomBonusConditions.csv create mode 100644 titles/sao/data/1/DefragMatchRandomBonusTables.csv create mode 100644 titles/sao/data/1/DefragMatchRareDrops.csv create mode 100644 titles/sao/data/1/DefragMatchSeed.csv create mode 100644 titles/sao/data/1/DefragMatchSpecialEffects.csv create mode 100644 titles/sao/data/1/DefragMatchs.csv create mode 100644 titles/sao/data/1/Enemy.csv create mode 100644 titles/sao/data/1/EnemyKind.csv create mode 100644 titles/sao/data/1/EnemySet.csv create mode 100644 titles/sao/data/1/Episode.csv create mode 100644 titles/sao/data/1/EpisodeAppends.csv create mode 100644 titles/sao/data/1/EpisodeChapter.csv create mode 100644 titles/sao/data/1/EpisodePart.csv rename titles/sao/data/{ => 1}/Equipment.csv (86%) create mode 100644 titles/sao/data/1/EquipmentLevel.csv create mode 100644 titles/sao/data/1/Event.csv create mode 100644 titles/sao/data/1/EventItems.csv create mode 100644 titles/sao/data/1/EventMonsters.csv create mode 100644 titles/sao/data/1/EventScenes.csv create mode 100644 titles/sao/data/1/ExBonusCondition.csv create mode 100644 titles/sao/data/1/ExBonusTable.csv create mode 100644 titles/sao/data/1/ExTowerQuests.csv create mode 100644 titles/sao/data/1/ExTowers.csv create mode 100644 titles/sao/data/1/FirstTicketPurchaseCampaigns.csv create mode 100644 titles/sao/data/1/FixedFormChat.csv create mode 100644 titles/sao/data/1/FixedFormChatText.csv create mode 100644 titles/sao/data/1/Fragment.csv create mode 100644 titles/sao/data/1/GamePlayPrice.csv create mode 100644 titles/sao/data/1/GashaFreeCampaigns.csv create mode 100644 titles/sao/data/1/GashaMedalBonuses.csv create mode 100644 titles/sao/data/1/GashaMedalSettings.csv create mode 100644 titles/sao/data/1/GashaMedalShopItems.csv rename titles/sao/data/{ => 1}/GashaMedalShops.csv (65%) create mode 100644 titles/sao/data/1/GashaMedalTypes.csv create mode 100644 titles/sao/data/1/GashaMedals.csv create mode 100644 titles/sao/data/1/GenericCampaignPeriods.csv create mode 100644 titles/sao/data/1/GimmickAttack.csv rename titles/sao/data/{ => 1}/HeroLog.csv (94%) create mode 100644 titles/sao/data/1/HeroLogLevel.csv create mode 100644 titles/sao/data/1/HeroLogRole.csv create mode 100644 titles/sao/data/1/HeroLogTrustRank.csv rename titles/sao/data/{ => 1}/Item.csv (79%) create mode 100644 titles/sao/data/1/ItemType.csv create mode 100644 titles/sao/data/1/LinkedSiteRegCampaignRewards.csv create mode 100644 titles/sao/data/1/LinkedSiteRegCampaigns.csv create mode 100644 titles/sao/data/1/MenuDisplayEnemy.csv create mode 100644 titles/sao/data/1/Mission.csv create mode 100644 titles/sao/data/1/MissionClearText.csv create mode 100644 titles/sao/data/1/MissionDifficulty.csv create mode 100644 titles/sao/data/1/MissionTable.csv create mode 100644 titles/sao/data/1/MonsterAction.csv create mode 100644 titles/sao/data/1/MonsterAttack.csv create mode 100644 titles/sao/data/1/NavigatorChara.csv create mode 100644 titles/sao/data/1/NavigatorComment.csv create mode 100644 titles/sao/data/1/PayingYuiMedalBonuses.csv create mode 100644 titles/sao/data/1/PlayCampaignRewards.csv create mode 100644 titles/sao/data/1/PlayCampaigns.csv create mode 100644 titles/sao/data/1/PlayerRank.csv create mode 100644 titles/sao/data/1/PlayerTraceTable.csv create mode 100644 titles/sao/data/1/Property.csv create mode 100644 titles/sao/data/1/PropertyTable.csv create mode 100644 titles/sao/data/1/PropertyType.csv create mode 100644 titles/sao/data/1/QuestDropBoostCampaigns.csv create mode 100644 titles/sao/data/1/QuestEpisodeAppendRewards.csv create mode 100644 titles/sao/data/1/QuestExistUnit.csv create mode 100644 titles/sao/data/1/QuestParam.csv create mode 100644 titles/sao/data/1/QuestRareDrop.csv rename titles/sao/data/{ => 1}/QuestScene.csv (89%) create mode 100644 titles/sao/data/1/QuestSpecialRareDropSettings.csv create mode 100644 titles/sao/data/1/QuestSpecialRareDrops.csv create mode 100644 titles/sao/data/1/QuestTutorial.csv create mode 100644 titles/sao/data/1/Rarity.csv create mode 100644 titles/sao/data/1/ResEarnCampaignShopItems.csv create mode 100644 titles/sao/data/1/ResEarnCampaignShops.csv create mode 100644 titles/sao/data/1/RewardSet.csv create mode 100644 titles/sao/data/1/RewardTable.csv create mode 100644 titles/sao/data/1/SideQuest.csv create mode 100644 titles/sao/data/1/Skill.csv create mode 100644 titles/sao/data/1/SkillCutInTextIndex.csv create mode 100644 titles/sao/data/1/SkillCutin.csv create mode 100644 titles/sao/data/1/SkillLevel.csv create mode 100644 titles/sao/data/1/SkillTable.csv create mode 100644 titles/sao/data/1/SoundBgm.csv create mode 100644 titles/sao/data/1/SoundSe.csv create mode 100644 titles/sao/data/1/SoundUi.csv create mode 100644 titles/sao/data/1/SoundVoice.csv create mode 100644 titles/sao/data/1/Sound_SkillCutinVoice.csv create mode 100644 titles/sao/data/1/SubStateMonster.csv rename titles/sao/data/{ => 1}/SupportLog.csv (95%) create mode 100644 titles/sao/data/1/SupportLogType.csv create mode 100644 titles/sao/data/1/SynchroSkill.csv create mode 100644 titles/sao/data/1/Tips.csv create mode 100644 titles/sao/data/1/Title.csv create mode 100644 titles/sao/data/1/TreasureHuntTaskText.csv create mode 100644 titles/sao/data/1/TrialTower.csv create mode 100644 titles/sao/data/1/UnanalyzedLogGrade.csv create mode 100644 titles/sao/data/1/Unit.csv create mode 100644 titles/sao/data/1/UnitCollision.csv create mode 100644 titles/sao/data/1/UnitGimmick.csv create mode 100644 titles/sao/data/1/UnitPower.csv create mode 100644 titles/sao/data/1/WeaponType.csv create mode 100644 titles/sao/data/1/YuiMedalBonus.csv create mode 100644 titles/sao/data/1/YuiMedalBonusCondition.csv create mode 100644 titles/sao/data/1/YuiMedalGetCondition.csv create mode 100644 titles/sao/data/1/YuiMedalShopItems.csv rename titles/sao/data/{ => 1}/YuiMedalShops.csv (60%) delete mode 100644 titles/sao/data/EquipmentLevel.csv delete mode 100644 titles/sao/data/GashaMedalShopItems.csv delete mode 100644 titles/sao/data/HeroLogLevel.csv delete mode 100644 titles/sao/data/PlayerRank.csv delete mode 100644 titles/sao/data/RareDropTable.csv delete mode 100644 titles/sao/data/ResEarnCampaignShopItems.csv delete mode 100644 titles/sao/data/ResEarnCampaignShops.csv delete mode 100644 titles/sao/data/RewardTable.csv delete mode 100644 titles/sao/data/Title.csv delete mode 100644 titles/sao/data/YuiMedalShopItems.csv create mode 100644 titles/sao/frontend.py create mode 100644 titles/sao/templates/sao_index.jinja diff --git a/core/data/alembic/versions/a616fd164e40_sao_backport.py b/core/data/alembic/versions/a616fd164e40_sao_backport.py new file mode 100644 index 0000000..c4b885b --- /dev/null +++ b/core/data/alembic/versions/a616fd164e40_sao_backport.py @@ -0,0 +1,723 @@ +"""sao_backport + +Revision ID: a616fd164e40 +Revises: 48f4acc43a7e +Create Date: 2024-06-24 20:28:34.471282 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import mysql + +# revision identifiers, used by Alembic. +revision = 'a616fd164e40' +down_revision = '48f4acc43a7e' +branch_labels = None +depends_on = None + + +def upgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index('sao_static_quest_uk', table_name='sao_static_quest') + op.drop_column('sao_static_quest', 'questSceneId') + op.drop_column('sao_static_quest', 'name') + op.drop_column('sao_static_quest', 'sortNo') + op.drop_column('sao_static_quest', 'id') + op.drop_column('sao_static_quest', 'enabled') + op.add_column('sao_static_quest', sa.Column('QuestSceneId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('SortNo', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('Tutorial', sa.BOOLEAN(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('ColRate', sa.DECIMAL(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('LimitDefault', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('LimitResurrection', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('RewardTableSubId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('PlayerTraceTableSubId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('SuccessPlayerExp', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('FailedPlayerExp', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('PairExpRate', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('TrioExpRate', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('SingleRewardVp', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('PairRewardVp', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_quest', sa.Column('TrioRewardVp', sa.INTEGER(), nullable=False)) + op.create_primary_key(None, "sao_static_quest", ['QuestSceneId']) + op.drop_column('sao_static_quest', 'version') + op.create_table('sao_player_resource_card', + sa.Column('id', sa.BIGINT(), nullable=False), + sa.Column('user', sa.INTEGER(), nullable=False), + sa.Column('common_reward_type', sa.INTEGER(), nullable=False), + sa.Column('common_reward_id', sa.INTEGER(), nullable=False), + sa.Column('holographic_flag', sa.BOOLEAN(), server_default='0', nullable=False), + sa.Column('serial', sa.VARCHAR(length=20), nullable=True), + sa.ForeignKeyConstraint(['user'], ['aime_user.id'], onupdate='cascade', ondelete='cascade'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('serial'), + mysql_charset='utf8mb4' + ) + op.create_table('sao_player_tutorial', + sa.Column('id', sa.BIGINT(), nullable=False), + sa.Column('user', sa.INTEGER(), nullable=False), + sa.Column('tutorial_byte', sa.INTEGER(), nullable=False), + sa.ForeignKeyConstraint(['user'], ['aime_user.id'], onupdate='cascade', ondelete='cascade'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('user', 'tutorial_byte', name='sao_player_tutorial_uk'), + mysql_charset='utf8mb4' + ) + op.create_table('sao_static_episode', + sa.Column('EpisodeId', sa.BIGINT(), nullable=False), + sa.Column('EpisodeChapterId', sa.INTEGER(), nullable=False), + sa.Column('ReleaseEpisodeId', sa.INTEGER(), nullable=False), + sa.Column('Title', sa.VARCHAR(length=255), nullable=False), + sa.Column('CommentSummary', sa.VARCHAR(length=255), nullable=False), + sa.Column('ExBonusTableSubId', sa.INTEGER(), nullable=False), + sa.Column('QuestSceneId', sa.BIGINT(), nullable=True), + sa.ForeignKeyConstraint(['QuestSceneId'], ['sao_static_quest.QuestSceneId'], onupdate='cascade', ondelete='cascade'), + sa.PrimaryKeyConstraint('EpisodeId'), + mysql_charset='utf8mb4' + ) + op.create_table('sao_static_ex_bonus', + sa.Column('ExBonusTableId', sa.BIGINT(), nullable=False), + sa.Column('ExBonusTableSubId', sa.INTEGER(), nullable=False), + sa.Column('ExBonusConditionId', sa.INTEGER(), nullable=False), + sa.Column('ConditionValue1', sa.INTEGER(), nullable=False), + sa.Column('ConditionValue2', sa.INTEGER(), nullable=False), + sa.Column('CommonRewardType', sa.INTEGER(), nullable=False), + sa.Column('CommonRewardId', sa.INTEGER(), nullable=False), + sa.Column('CommonRewardNum', sa.INTEGER(), nullable=False), + sa.Column('Strength', sa.INTEGER(), nullable=False), + sa.Column('Property1PropertyId', sa.BIGINT(), nullable=False), + sa.Column('Property1Value1', sa.INTEGER(), nullable=False), + sa.Column('Property1Value2', sa.INTEGER(), nullable=False), + sa.Column('Property2PropertyId', sa.BIGINT(), nullable=False), + sa.Column('Property2Value1', sa.INTEGER(), nullable=False), + sa.Column('Property2Value2', sa.INTEGER(), nullable=False), + sa.Column('Property3PropertyId', sa.BIGINT(), nullable=False), + sa.Column('Property3Value1', sa.INTEGER(), nullable=False), + sa.Column('Property3Value2', sa.INTEGER(), nullable=False), + sa.Column('Property4PropertyId', sa.BIGINT(), nullable=False), + sa.Column('Property4Value1', sa.INTEGER(), nullable=False), + sa.Column('Property4Value2', sa.INTEGER(), nullable=False), + sa.ForeignKeyConstraint(['Property1PropertyId'], ['sao_static_property.PropertyId'], onupdate='cascade', ondelete='cascade'), + sa.ForeignKeyConstraint(['Property2PropertyId'], ['sao_static_property.PropertyId'], onupdate='cascade', ondelete='cascade'), + sa.ForeignKeyConstraint(['Property3PropertyId'], ['sao_static_property.PropertyId'], onupdate='cascade', ondelete='cascade'), + sa.ForeignKeyConstraint(['Property4PropertyId'], ['sao_static_property.PropertyId'], onupdate='cascade', ondelete='cascade'), + sa.PrimaryKeyConstraint('ExBonusTableId'), + mysql_charset='utf8mb4' + ) + op.create_table('sao_static_ex_tower', + sa.Column('ExTowerQuestId', sa.BIGINT(), nullable=False), + sa.Column('ExTowerId', sa.INTEGER(), nullable=False), + sa.Column('ReleaseExTowerQuestId', sa.INTEGER(), nullable=False), + sa.Column('Title', sa.VARCHAR(length=255), nullable=False), + sa.Column('Title_en', sa.VARCHAR(length=255), nullable=True), + sa.Column('ExBonusTableSubId', sa.INTEGER(), nullable=False), + sa.Column('QuestSceneId', sa.BIGINT(), nullable=False), + sa.ForeignKeyConstraint(['QuestSceneId'], ['sao_static_quest.QuestSceneId'], onupdate='cascade', ondelete='cascade'), + sa.PrimaryKeyConstraint('ExTowerQuestId'), + mysql_charset='utf8mb4' + ) + op.create_table('sao_static_side_quest', + sa.Column('SideQuestId', sa.BIGINT(), nullable=False), + sa.Column('DisplayName', sa.VARCHAR(length=255), nullable=False), + sa.Column('DisplayName_en', sa.VARCHAR(length=255), nullable=True), + sa.Column('EpisodeNum', sa.INTEGER(), nullable=False), + sa.Column('ExBonusTableSubId', sa.INTEGER(), nullable=False), + sa.Column('QuestSceneId', sa.BIGINT(), nullable=False), + sa.ForeignKeyConstraint(['QuestSceneId'], ['sao_static_quest.QuestSceneId'], onupdate='cascade', ondelete='cascade'), + sa.PrimaryKeyConstraint('SideQuestId'), + sa.UniqueConstraint('SideQuestId'), + mysql_charset='utf8mb4' + ) + op.create_table('sao_static_skill_table', + sa.Column('SkillTableId', sa.BIGINT(), nullable=False), + sa.Column('SkillId', sa.BIGINT(), nullable=False), + sa.Column('SkillTableSubId', sa.INTEGER(), nullable=False), + sa.Column('LevelObtained', sa.INTEGER(), nullable=False), + sa.Column('AwakeningId', sa.INTEGER(), nullable=False), + sa.ForeignKeyConstraint(['SkillId'], ['sao_static_skill.SkillId'], onupdate='cascade', ondelete='cascade'), + sa.PrimaryKeyConstraint('SkillTableId'), + mysql_charset='utf8mb4' + ) + op.create_table('sao_static_tower', + sa.Column('TowerId', sa.BIGINT(), nullable=False), + sa.Column('ReleaseTowerId', sa.INTEGER(), nullable=False), + sa.Column('ExBonusTableSubId', sa.INTEGER(), nullable=False), + sa.Column('QuestSceneId', sa.BIGINT(), nullable=False), + sa.ForeignKeyConstraint(['QuestSceneId'], ['sao_static_quest.QuestSceneId'], onupdate='cascade', ondelete='cascade'), + sa.PrimaryKeyConstraint('TowerId'), + mysql_charset='utf8mb4' + ) + op.create_table('sao_player_ex_bonus', + sa.Column('id', sa.BIGINT(), nullable=False), + sa.Column('user', sa.INTEGER(), nullable=False), + sa.Column('quest_scene_id', sa.BIGINT(), nullable=False), + sa.Column('ex_bonus_table_id', sa.BIGINT(), nullable=False), + sa.Column('quest_clear_flag', sa.BOOLEAN(), server_default='0', nullable=False), + sa.ForeignKeyConstraint(['ex_bonus_table_id'], ['sao_static_ex_bonus.ExBonusTableId'], onupdate='cascade', ondelete='cascade'), + sa.ForeignKeyConstraint(['quest_scene_id'], ['sao_static_quest.QuestSceneId'], onupdate='cascade', ondelete='cascade'), + sa.ForeignKeyConstraint(['user'], ['aime_user.id'], onupdate='cascade', ondelete='cascade'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('user', 'quest_scene_id', 'ex_bonus_table_id', name='sao_player_ex_bonus_uk'), + mysql_charset='utf8mb4' + ) + op.alter_column('sao_end_sessions', 'play_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('now()'), + existing_nullable=False) + op.alter_column("sao_equipment_data", "equipment_id", existing_type=sa.Integer(), type_=sa.BIGINT()) + op.add_column('sao_equipment_data', sa.Column('is_shop_purchase', sa.BOOLEAN(), server_default='0', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('is_protect', sa.BOOLEAN(), server_default='0', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property1_property_id', sa.BIGINT(), server_default='2', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property1_value1', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property1_value2', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property2_property_id', sa.BIGINT(), server_default='2', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property2_value1', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property2_value2', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property3_property_id', sa.BIGINT(), server_default='2', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property3_value1', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property3_value2', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property4_property_id', sa.BIGINT(), server_default='2', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property4_value1', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('property4_value2', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_equipment_data', sa.Column('converted_card_num', sa.INTEGER(), server_default='0', nullable=False)) + op.alter_column('sao_equipment_data', 'get_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('now()'), + existing_nullable=False) + op.drop_column('sao_static_equipment_list', 'id') + op.drop_column('sao_static_equipment_list', 'name') + op.drop_column('sao_static_equipment_list', 'flavorText') + op.drop_column('sao_static_equipment_list', 'equipmentId') + op.drop_column('sao_static_equipment_list', 'rarity') + op.drop_column('sao_static_equipment_list', 'enabled') + op.drop_column('sao_static_equipment_list', 'weaponTypeId') + op.drop_column('sao_static_equipment_list', 'equipmentType') + op.add_column('sao_static_equipment_list', sa.Column('EquipmentId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('EquipmentType', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('WeaponTypeId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Name', sa.VARCHAR(length=255), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Name_en', sa.VARCHAR(length=255), nullable=True)) + op.add_column('sao_static_equipment_list', sa.Column('Rarity', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Power', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('StrengthIncrement', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('SkillCondition', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property1PropertyId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property1Value1', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property1Value2', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property2PropertyId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property2Value1', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property2Value2', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property3PropertyId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property3Value1', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property3Value2', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property4PropertyId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property4Value1', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('Property4Value2', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('SalePrice', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('CompositionExp', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('AwakeningExp', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('FlavorText', sa.VARCHAR(length=255), nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('FlavorText_en', sa.VARCHAR(length=255), nullable=True)) + op.create_primary_key(None, "sao_static_equipment_list", ['EquipmentId']) + op.drop_index('sao_static_equipment_list_uk', table_name='sao_static_equipment_list') + op.create_foreign_key(None, 'sao_static_equipment_list', 'sao_static_property', ['Property1PropertyId'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_static_equipment_list', 'sao_static_property', ['Property2PropertyId'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_static_equipment_list', 'sao_static_property', ['Property3PropertyId'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_static_equipment_list', 'sao_static_property', ['Property4PropertyId'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.drop_column('sao_static_equipment_list', 'version') + op.create_foreign_key(None, 'sao_equipment_data', 'sao_static_equipment_list', ['equipment_id'], ['EquipmentId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_equipment_data', 'sao_static_property', ['property1_property_id'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_equipment_data', 'sao_static_property', ['property4_property_id'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_equipment_data', 'sao_static_property', ['property2_property_id'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_equipment_data', 'sao_static_property', ['property3_property_id'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.add_column('sao_hero_log_data', sa.Column('hero_log_id', sa.BIGINT(), nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('max_level_extend_num', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('is_awakenable', sa.BOOLEAN(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('awakening_stage', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('awakening_exp', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('is_shop_purchase', sa.BOOLEAN(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('is_protect', sa.BOOLEAN(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property1_property_id', sa.BIGINT(), server_default='2', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property1_value1', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property1_value2', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property2_property_id', sa.BIGINT(), server_default='2', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property2_value1', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property2_value2', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property3_property_id', sa.BIGINT(), server_default='2', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property3_value1', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property3_value2', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property4_property_id', sa.BIGINT(), server_default='2', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property4_value1', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('property4_value2', sa.INTEGER(), server_default='0', nullable=False)) + op.add_column('sao_hero_log_data', sa.Column('converted_card_num', sa.INTEGER(), server_default='0', nullable=False)) + op.alter_column('sao_hero_log_data', 'main_weapon', + existing_type=mysql.INTEGER(display_width=11), + nullable=True) + op.alter_column('sao_hero_log_data', 'sub_equipment', + existing_type=mysql.INTEGER(display_width=11), + nullable=True) + op.alter_column('sao_hero_log_data', 'skill_slot1_skill_id', + existing_type=mysql.INTEGER(display_width=11), + type_=sa.BIGINT(), + nullable=True) + op.alter_column('sao_hero_log_data', 'skill_slot2_skill_id', + existing_type=mysql.INTEGER(display_width=11), + type_=sa.BIGINT(), + nullable=True) + op.alter_column('sao_hero_log_data', 'skill_slot3_skill_id', + existing_type=mysql.INTEGER(display_width=11), + type_=sa.BIGINT(), + nullable=True) + op.alter_column('sao_hero_log_data', 'skill_slot4_skill_id', + existing_type=mysql.INTEGER(display_width=11), + type_=sa.BIGINT(), + nullable=True) + op.alter_column('sao_hero_log_data', 'skill_slot5_skill_id', + existing_type=mysql.INTEGER(display_width=11), + type_=sa.BIGINT(), + nullable=True) + op.alter_column('sao_hero_log_data', 'get_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('now()'), + existing_nullable=False) + op.drop_constraint('sao_hero_log_data_ibfk_1', 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint('sao_hero_log_data_uk', 'sao_hero_log_data', type_='unique') + op.create_unique_constraint('sao_hero_log_data_uk', 'sao_hero_log_data', ['user', 'hero_log_id']) + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_static_property', ['property2_property_id'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_static_skill', ['skill_slot2_skill_id'], ['SkillId'], onupdate='set null', ondelete='set null') + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_static_property', ['property1_property_id'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_static_skill', ['skill_slot1_skill_id'], ['SkillId'], onupdate='set null', ondelete='set null') + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_equipment_data', ['main_weapon'], ['id'], onupdate='set null', ondelete='set null') + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_static_property', ['property4_property_id'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_static_skill', ['skill_slot4_skill_id'], ['SkillId'], onupdate='set null', ondelete='set null') + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_static_skill', ['skill_slot3_skill_id'], ['SkillId'], onupdate='set null', ondelete='set null') + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_static_property', ['property3_property_id'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_equipment_data', ['sub_equipment'], ['id'], onupdate='set null', ondelete='set null') + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_static_skill', ['skill_slot5_skill_id'], ['SkillId'], onupdate='set null', ondelete='set null') + op.drop_index('sao_static_hero_list_uk', table_name='sao_static_hero_list') + op.drop_column('sao_static_hero_list', 'name') + op.drop_column('sao_static_hero_list', 'skillTableSubId') + op.drop_column('sao_static_hero_list', 'awakeningExp') + op.drop_column('sao_static_hero_list', 'flavorText') + op.drop_column('sao_static_hero_list', 'heroLogId') + op.drop_column('sao_static_hero_list', 'id') + op.drop_column('sao_static_hero_list', 'rarity') + op.drop_column('sao_static_hero_list', 'version') + op.drop_column('sao_static_hero_list', 'nickname') + op.add_column('sao_static_hero_list', sa.Column('HeroLogId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('CharaId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Name', sa.VARCHAR(length=255), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Nickname', sa.VARCHAR(length=255), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Name_en', sa.VARCHAR(length=255), nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('Nickname_en', sa.VARCHAR(length=255), nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('Rarity', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('WeaponTypeId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('HeroLogRoleId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('CostumeTypeId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('UnitId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('DefaultEquipmentId1', sa.BIGINT(), nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('DefaultEquipmentId2', sa.BIGINT(), nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('SkillTableSubId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('HpMin', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('HpMax', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('StrMin', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('StrMax', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('VitMin', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('VitMax', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('IntMin', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('IntMax', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property1PropertyId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property1Value1', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property1Value2', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property2PropertyId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property2Value1', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property2Value2', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property3PropertyId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property3Value1', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property3Value2', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property4PropertyId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property4Value1', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Property4Value2', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('FlavorText', sa.VARCHAR(length=255), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('FlavorText_en', sa.VARCHAR(length=255), nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('SalePrice', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('CompositionExp', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('AwakeningExp', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Slot4UnlockLevel', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('Slot5UnlockLevel', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('CollectionEmptyFrameDisplayFlag', sa.BOOLEAN(), nullable=False)) + op.create_foreign_key(None, 'sao_static_hero_list', 'sao_static_equipment_list', ['DefaultEquipmentId1'], ['EquipmentId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_static_hero_list', 'sao_static_equipment_list', ['DefaultEquipmentId2'], ['EquipmentId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_static_hero_list', 'sao_static_property', ['Property2PropertyId'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_static_hero_list', 'sao_static_property', ['Property3PropertyId'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_static_hero_list', 'sao_static_property', ['Property4PropertyId'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_static_hero_list', 'sao_static_property', ['Property1PropertyId'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.drop_column('sao_static_hero_list', 'enabled') + op.create_primary_key(None, "sao_static_hero_list", ["HeroLogId"]) + op.create_foreign_key(None, 'sao_hero_log_data', 'sao_static_hero_list', ['hero_log_id'], ['HeroLogId'], onupdate='cascade', ondelete='cascade') + op.drop_column('sao_hero_log_data', 'user_hero_log_id') + op.create_foreign_key(None, 'sao_hero_log_data', 'aime_user', ['user'], ['id'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_hero_party', 'sao_hero_log_data', ['user_hero_log_id_3'], ['id'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_hero_party', 'sao_hero_log_data', ['user_hero_log_id_1'], ['id'], onupdate='cascade', ondelete='cascade') + op.create_foreign_key(None, 'sao_hero_party', 'sao_hero_log_data', ['user_hero_log_id_2'], ['id'], onupdate='cascade', ondelete='cascade') + op.create_table('sao_player_hero_card', + sa.Column('id', sa.BIGINT(), nullable=False), + sa.Column('user', sa.INTEGER(), nullable=False), + sa.Column('user_hero_id', sa.INTEGER(), nullable=False), + sa.Column('holographic_flag', sa.BOOLEAN(), server_default='0', nullable=False), + sa.Column('serial', sa.VARCHAR(length=20), nullable=True), + sa.ForeignKeyConstraint(['user'], ['aime_user.id'], onupdate='cascade', ondelete='cascade'), + sa.ForeignKeyConstraint(['user_hero_id'], ['sao_hero_log_data.id'], onupdate='cascade', ondelete='cascade'), + sa.PrimaryKeyConstraint('id'), + sa.UniqueConstraint('serial'), + mysql_charset='utf8mb4' + ) + op.alter_column('sao_item_data', 'get_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('now()'), + existing_nullable=False) + op.alter_column('sao_play_sessions', 'play_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('now()'), + existing_nullable=False) + op.add_column('sao_player_quest', sa.Column('quest_type', sa.INTEGER(), server_default='1', nullable=False)) + op.add_column('sao_player_quest', sa.Column('quest_scene_id', sa.BIGINT(), nullable=False)) + op.alter_column('sao_player_quest', 'play_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('now()'), + existing_nullable=False) + op.drop_constraint('sao_player_quest_ibfk_1', 'sao_player_quest', type_='foreignkey') + op.drop_constraint('sao_player_quest_uk', 'sao_player_quest', type_='unique') + op.create_unique_constraint('sao_player_quest_uk', 'sao_player_quest', ['user', 'quest_scene_id']) + op.create_foreign_key(None, "sao_player_quest", "aime_user", ['user'], ['id']) + op.create_foreign_key(None, 'sao_player_quest', 'sao_static_quest', ['quest_scene_id'], ['QuestSceneId'], onupdate='cascade', ondelete='cascade') + op.drop_column('sao_player_quest', 'episode_id') + op.add_column('sao_profile', sa.Column('my_shop', sa.INTEGER(), nullable=True)) + op.add_column('sao_profile', sa.Column('fav_hero', sa.INTEGER(), nullable=True)) + op.add_column('sao_profile', sa.Column('when_register', sa.TIMESTAMP(), server_default=sa.text('now()'), nullable=True)) + op.add_column('sao_profile', sa.Column('last_login_date', sa.TIMESTAMP(), nullable=True)) + op.add_column('sao_profile', sa.Column('last_yui_medal_date', sa.TIMESTAMP(), nullable=True)) + op.add_column('sao_profile', sa.Column('last_bonus_yui_medal_date', sa.TIMESTAMP(), nullable=True)) + op.add_column('sao_profile', sa.Column('last_comeback_date', sa.TIMESTAMP(), nullable=True)) + op.add_column('sao_profile', sa.Column('last_login_bonus_date', sa.TIMESTAMP(), nullable=True)) + op.add_column('sao_profile', sa.Column('ad_confirm_date', sa.TIMESTAMP(), nullable=True)) + op.add_column('sao_profile', sa.Column('login_ct', sa.INTEGER(), server_default='0', nullable=True)) + op.alter_column('sao_profile', 'own_vp', + existing_type=mysql.INTEGER(display_width=11), + server_default='0', + existing_nullable=True) + op.create_foreign_key(None, 'sao_profile', 'sao_hero_log_data', ['fav_hero'], ['id'], onupdate='cascade', ondelete='set null') + op.drop_column('sao_static_item_list', 'name') + op.drop_column('sao_static_item_list', 'itemId') + op.drop_column('sao_static_item_list', 'itemTypeId') + op.drop_column('sao_static_item_list', 'flavorText') + op.drop_column('sao_static_item_list', 'id') + op.drop_column('sao_static_item_list', 'rarity') + op.drop_column('sao_static_item_list', 'enabled') + op.add_column('sao_static_item_list', sa.Column('ItemId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('ItemTypeId', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('Name', sa.VARCHAR(length=255), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('Name_en', sa.VARCHAR(length=255), nullable=True)) + op.add_column('sao_static_item_list', sa.Column('Rarity', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('Value', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('PropertyId', sa.BIGINT(), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('PropertyValue1Min', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('PropertyValue1Max', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('PropertyValue2Min', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('PropertyValue2Max', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('FlavorText', sa.VARCHAR(length=255), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('FlavorText_en', sa.VARCHAR(length=255), nullable=True)) + op.add_column('sao_static_item_list', sa.Column('SalePrice', sa.INTEGER(), nullable=False)) + op.add_column('sao_static_item_list', sa.Column('ItemIcon', sa.VARCHAR(length=255), nullable=False)) + op.drop_index('sao_static_item_list_uk', table_name='sao_static_item_list') + op.create_foreign_key(None, 'sao_static_item_list', 'sao_static_property', ['PropertyId'], ['PropertyId'], onupdate='cascade', ondelete='cascade') + op.drop_column('sao_static_item_list', 'version') + # ### end Alembic commands ### + + +def downgrade(): + # ### commands auto generated by Alembic - please adjust! ### + op.drop_constraint("sao_static_item_list_ibfk_1", 'sao_static_item_list', type_='foreignkey') + op.drop_column('sao_static_item_list', 'ItemIcon') + op.drop_column('sao_static_item_list', 'SalePrice') + op.drop_column('sao_static_item_list', 'FlavorText_en') + op.drop_column('sao_static_item_list', 'FlavorText') + op.drop_column('sao_static_item_list', 'PropertyValue2Max') + op.drop_column('sao_static_item_list', 'PropertyValue2Min') + op.drop_column('sao_static_item_list', 'PropertyValue1Max') + op.drop_column('sao_static_item_list', 'PropertyValue1Min') + op.drop_column('sao_static_item_list', 'PropertyId') + op.drop_column('sao_static_item_list', 'Value') + op.drop_column('sao_static_item_list', 'Rarity') + op.drop_column('sao_static_item_list', 'Name') + op.drop_column('sao_static_item_list', 'ItemTypeId') + op.drop_column('sao_static_item_list', 'ItemId') + op.add_column('sao_static_item_list', sa.Column('version', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_item_list', sa.Column('enabled', mysql.TINYINT(display_width=1), autoincrement=False, nullable=True)) + op.add_column('sao_static_item_list', sa.Column('rarity', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_item_list', sa.Column('id', mysql.INTEGER(display_width=11), autoincrement=True, nullable=False)) + op.add_column('sao_static_item_list', sa.Column('flavorText', mysql.VARCHAR(length=255), nullable=True)) + op.add_column('sao_static_item_list', sa.Column('itemTypeId', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_item_list', sa.Column('itemId', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_item_list', sa.Column('name', mysql.VARCHAR(length=255), nullable=True)) + op.add_column('sao_hero_log_data', sa.Column('user_hero_log_id', mysql.INTEGER(display_width=11), autoincrement=False, nullable=False)) + op.drop_column('sao_static_item_list', 'Name_en') + op.create_index('sao_static_item_list_uk', 'sao_static_item_list', ['version', 'itemId'], unique=True) + op.drop_constraint("sao_hero_log_data_ibfk_1", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_2", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_3", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_4", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_5", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_6", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_7", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_8", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_9", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_10", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_11", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_12", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint("sao_hero_log_data_ibfk_13", 'sao_hero_log_data', type_='foreignkey') + op.drop_constraint('sao_hero_log_data_uk', 'sao_hero_log_data', type_='unique') + op.create_foreign_key("sao_hero_log_data_ibfk_1", 'sao_hero_log_data', "aime_user", ['user'], ['id']) + op.drop_column('sao_hero_log_data', 'converted_card_num') + op.drop_column('sao_hero_log_data', 'property4_value2') + op.drop_column('sao_hero_log_data', 'property4_value1') + op.drop_column('sao_hero_log_data', 'property4_property_id') + op.drop_column('sao_hero_log_data', 'property3_value2') + op.drop_column('sao_hero_log_data', 'property3_value1') + op.drop_column('sao_hero_log_data', 'property3_property_id') + op.drop_column('sao_hero_log_data', 'property2_value2') + op.drop_column('sao_hero_log_data', 'property2_value1') + op.drop_column('sao_hero_log_data', 'property2_property_id') + op.drop_column('sao_hero_log_data', 'property1_value2') + op.drop_column('sao_hero_log_data', 'property1_value1') + op.drop_column('sao_hero_log_data', 'property1_property_id') + op.drop_column('sao_hero_log_data', 'is_protect') + op.drop_column('sao_hero_log_data', 'is_shop_purchase') + op.drop_column('sao_hero_log_data', 'awakening_exp') + op.drop_column('sao_hero_log_data', 'awakening_stage') + op.drop_column('sao_hero_log_data', 'is_awakenable') + op.drop_column('sao_hero_log_data', 'max_level_extend_num') + op.drop_column('sao_hero_log_data', 'hero_log_id') + op.alter_column('sao_hero_log_data', 'get_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('CURRENT_TIMESTAMP'), + existing_nullable=False) + op.alter_column('sao_hero_log_data', 'skill_slot5_skill_id', + existing_type=mysql.INTEGER(display_width=11), + nullable=False) + op.alter_column('sao_hero_log_data', 'skill_slot4_skill_id', + existing_type=mysql.INTEGER(display_width=11), + nullable=False) + op.alter_column('sao_hero_log_data', 'skill_slot3_skill_id', + existing_type=mysql.INTEGER(display_width=11), + nullable=False) + op.alter_column('sao_hero_log_data', 'skill_slot2_skill_id', + existing_type=mysql.INTEGER(display_width=11), + nullable=False) + op.alter_column('sao_hero_log_data', 'skill_slot1_skill_id', + existing_type=mysql.INTEGER(display_width=11), + nullable=False) + op.alter_column('sao_hero_log_data', 'sub_equipment', + existing_type=mysql.INTEGER(display_width=11), + nullable=False) + op.alter_column('sao_hero_log_data', 'main_weapon', + existing_type=mysql.INTEGER(display_width=11), + nullable=False) + op.create_unique_constraint('sao_hero_log_data_uk', 'sao_hero_log_data', ['user', 'user_hero_log_id']) + op.drop_constraint("sao_static_hero_list_ibfk_1", 'sao_static_hero_list', type_='foreignkey') + op.drop_constraint("sao_static_hero_list_ibfk_2", 'sao_static_hero_list', type_='foreignkey') + op.drop_constraint("sao_static_hero_list_ibfk_3", 'sao_static_hero_list', type_='foreignkey') + op.drop_constraint("sao_static_hero_list_ibfk_4", 'sao_static_hero_list', type_='foreignkey') + op.drop_constraint("sao_static_hero_list_ibfk_5", 'sao_static_hero_list', type_='foreignkey') + op.drop_constraint("sao_static_hero_list_ibfk_6", 'sao_static_hero_list', type_='foreignkey') + op.drop_column('sao_static_hero_list', 'CollectionEmptyFrameDisplayFlag') + op.drop_column('sao_static_hero_list', 'Slot5UnlockLevel') + op.drop_column('sao_static_hero_list', 'Slot4UnlockLevel') + op.drop_column('sao_static_hero_list', 'AwakeningExp') + op.drop_column('sao_static_hero_list', 'CompositionExp') + op.drop_column('sao_static_hero_list', 'SalePrice') + op.drop_column('sao_static_hero_list', 'FlavorText_en') + op.drop_column('sao_static_hero_list', 'FlavorText') + op.drop_column('sao_static_hero_list', 'Property4Value2') + op.drop_column('sao_static_hero_list', 'Property4Value1') + op.drop_column('sao_static_hero_list', 'Property4PropertyId') + op.drop_column('sao_static_hero_list', 'Property3Value2') + op.drop_column('sao_static_hero_list', 'Property3Value1') + op.drop_column('sao_static_hero_list', 'Property3PropertyId') + op.drop_column('sao_static_hero_list', 'Property2Value2') + op.drop_column('sao_static_hero_list', 'Property2Value1') + op.drop_column('sao_static_hero_list', 'Property2PropertyId') + op.drop_column('sao_static_hero_list', 'Property1Value2') + op.drop_column('sao_static_hero_list', 'Property1Value1') + op.drop_column('sao_static_hero_list', 'Property1PropertyId') + op.drop_column('sao_static_hero_list', 'IntMax') + op.drop_column('sao_static_hero_list', 'IntMin') + op.drop_column('sao_static_hero_list', 'VitMax') + op.drop_column('sao_static_hero_list', 'VitMin') + op.drop_column('sao_static_hero_list', 'StrMax') + op.drop_column('sao_static_hero_list', 'StrMin') + op.drop_column('sao_static_hero_list', 'HpMax') + op.drop_column('sao_static_hero_list', 'SkillTableSubId') + op.drop_column('sao_static_hero_list', 'DefaultEquipmentId2') + op.drop_column('sao_static_hero_list', 'DefaultEquipmentId1') + op.drop_column('sao_static_hero_list', 'UnitId') + op.drop_column('sao_static_hero_list', 'CostumeTypeId') + op.drop_column('sao_static_hero_list', 'HeroLogRoleId') + op.drop_column('sao_static_hero_list', 'WeaponTypeId') + op.drop_column('sao_static_hero_list', 'Rarity') + op.drop_column('sao_static_hero_list', 'Nickname_en') + op.drop_column('sao_static_hero_list', 'Name_en') + op.drop_column('sao_static_hero_list', 'Nickname') + op.drop_column('sao_static_hero_list', 'Name') + op.drop_column('sao_static_hero_list', 'CharaId') + op.drop_column('sao_static_hero_list', 'HeroLogId') + op.add_column('sao_static_hero_list', sa.Column('nickname', mysql.VARCHAR(length=255), nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('version', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('enabled', mysql.TINYINT(display_width=1), autoincrement=False, nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('rarity', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('id', mysql.INTEGER(display_width=11), autoincrement=True, nullable=False)) + op.add_column('sao_static_hero_list', sa.Column('heroLogId', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('flavorText', mysql.VARCHAR(length=255), nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('awakeningExp', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('skillTableSubId', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_hero_list', sa.Column('name', mysql.VARCHAR(length=255), nullable=True)) + op.drop_column('sao_static_hero_list', 'HpMin') + op.create_index('sao_static_hero_list_uk', 'sao_static_hero_list', ['version', 'heroLogId'], unique=True) + op.drop_constraint("sao_equipment_data_ibfk_2", 'sao_equipment_data', type_='foreignkey') + op.drop_constraint("sao_equipment_data_ibfk_3", 'sao_equipment_data', type_='foreignkey') + op.drop_constraint("sao_equipment_data_ibfk_4", 'sao_equipment_data', type_='foreignkey') + op.drop_constraint("sao_equipment_data_ibfk_5", 'sao_equipment_data', type_='foreignkey') + op.drop_constraint("sao_equipment_data_ibfk_6", 'sao_equipment_data', type_='foreignkey') + op.alter_column('sao_equipment_data', 'get_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('CURRENT_TIMESTAMP'), + existing_nullable=False) + op.drop_column('sao_equipment_data', 'converted_card_num') + op.drop_column('sao_equipment_data', 'property4_value2') + op.drop_column('sao_equipment_data', 'property4_value1') + op.drop_column('sao_equipment_data', 'property4_property_id') + op.drop_column('sao_equipment_data', 'property3_value2') + op.drop_column('sao_equipment_data', 'property3_value1') + op.drop_column('sao_equipment_data', 'property3_property_id') + op.drop_column('sao_equipment_data', 'property2_value2') + op.drop_column('sao_equipment_data', 'property2_value1') + op.drop_column('sao_equipment_data', 'property2_property_id') + op.drop_column('sao_equipment_data', 'property1_value2') + op.drop_column('sao_equipment_data', 'property1_value1') + op.drop_column('sao_equipment_data', 'property1_property_id') + op.drop_column('sao_equipment_data', 'is_protect') + op.drop_column('sao_equipment_data', 'is_shop_purchase') + op.drop_constraint("sao_static_equipment_list_ibfk_1", 'sao_static_equipment_list', type_='foreignkey') + op.drop_constraint("sao_static_equipment_list_ibfk_2", 'sao_static_equipment_list', type_='foreignkey') + op.drop_constraint("sao_static_equipment_list_ibfk_3", 'sao_static_equipment_list', type_='foreignkey') + op.drop_constraint("sao_static_equipment_list_ibfk_4", 'sao_static_equipment_list', type_='foreignkey') + op.drop_column('sao_static_equipment_list', 'FlavorText_en') + op.drop_column('sao_static_equipment_list', 'FlavorText') + op.drop_column('sao_static_equipment_list', 'AwakeningExp') + op.drop_column('sao_static_equipment_list', 'CompositionExp') + op.drop_column('sao_static_equipment_list', 'SalePrice') + op.drop_column('sao_static_equipment_list', 'Property4Value2') + op.drop_column('sao_static_equipment_list', 'Property4Value1') + op.drop_column('sao_static_equipment_list', 'Property4PropertyId') + op.drop_column('sao_static_equipment_list', 'Property3Value2') + op.drop_column('sao_static_equipment_list', 'Property3Value1') + op.drop_column('sao_static_equipment_list', 'Property3PropertyId') + op.drop_column('sao_static_equipment_list', 'Property2Value2') + op.drop_column('sao_static_equipment_list', 'Property2Value1') + op.drop_column('sao_static_equipment_list', 'Property2PropertyId') + op.drop_column('sao_static_equipment_list', 'Property1Value2') + op.drop_column('sao_static_equipment_list', 'Property1Value1') + op.drop_column('sao_static_equipment_list', 'Property1PropertyId') + op.drop_column('sao_static_equipment_list', 'SkillCondition') + op.drop_column('sao_static_equipment_list', 'StrengthIncrement') + op.drop_column('sao_static_equipment_list', 'Power') + op.drop_column('sao_static_equipment_list', 'Rarity') + op.drop_column('sao_static_equipment_list', 'Name') + op.drop_column('sao_static_equipment_list', 'WeaponTypeId') + op.drop_column('sao_static_equipment_list', 'EquipmentType') + op.drop_column('sao_static_equipment_list', 'EquipmentId') + op.add_column('sao_static_equipment_list', sa.Column('equipmentType', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_equipment_list', sa.Column('version', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_equipment_list', sa.Column('weaponTypeId', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_equipment_list', sa.Column('enabled', mysql.TINYINT(display_width=1), autoincrement=False, nullable=True)) + op.add_column('sao_static_equipment_list', sa.Column('rarity', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_equipment_list', sa.Column('equipmentId', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_equipment_list', sa.Column('id', mysql.INTEGER(display_width=11), autoincrement=True, nullable=False)) + op.add_column('sao_static_equipment_list', sa.Column('flavorText', mysql.VARCHAR(length=255), nullable=True)) + op.add_column('sao_static_equipment_list', sa.Column('name', mysql.VARCHAR(length=255), nullable=True)) + op.drop_column('sao_static_equipment_list', 'Name_en') + op.create_index('sao_static_equipment_list_uk', 'sao_static_equipment_list', ['version', 'equipmentId'], unique=True) + op.drop_constraint("sao_profile_ibfk_2", 'sao_profile', type_='foreignkey') + op.alter_column('sao_profile', 'own_vp', + existing_type=mysql.INTEGER(display_width=11), + server_default=sa.text("'300'"), + existing_nullable=True) + op.drop_column('sao_profile', 'login_ct') + op.drop_column('sao_profile', 'ad_confirm_date') + op.drop_column('sao_profile', 'last_login_bonus_date') + op.drop_column('sao_profile', 'last_comeback_date') + op.drop_column('sao_profile', 'last_bonus_yui_medal_date') + op.drop_column('sao_profile', 'last_yui_medal_date') + op.drop_column('sao_profile', 'last_login_date') + op.drop_column('sao_profile', 'when_register') + op.drop_column('sao_profile', 'fav_hero') + op.drop_column('sao_profile', 'my_shop') + op.add_column('sao_player_quest', sa.Column('episode_id', mysql.INTEGER(display_width=11), autoincrement=False, nullable=False)) + op.drop_constraint("sao_player_quest_ibfk_2", 'sao_player_quest', type_='foreignkey') + op.drop_constraint("sao_player_quest_ibfk_1", 'sao_player_quest', type_='foreignkey') + op.drop_constraint('sao_player_quest_uk', 'sao_player_quest', type_='unique') + op.create_foreign_key("sao_player_quest_ibfk_1", "sao_player_quest", "aime_user", ['user'], ['id']) + op.create_unique_constraint('sao_player_quest_uk', 'sao_player_quest', ['user', 'episode_id']) + op.alter_column('sao_player_quest', 'play_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('CURRENT_TIMESTAMP'), + existing_nullable=False) + op.drop_column('sao_player_quest', 'quest_scene_id') + op.drop_column('sao_player_quest', 'quest_type') + op.alter_column('sao_play_sessions', 'play_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('CURRENT_TIMESTAMP'), + existing_nullable=False) + op.alter_column('sao_item_data', 'get_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('CURRENT_TIMESTAMP'), + existing_nullable=False) + op.drop_constraint("sao_hero_party_ibfk_2", 'sao_hero_party', type_='foreignkey') + op.drop_constraint("sao_hero_party_ibfk_3", 'sao_hero_party', type_='foreignkey') + op.drop_constraint("sao_hero_party_ibfk_4", 'sao_hero_party', type_='foreignkey') + op.alter_column('sao_end_sessions', 'play_date', + existing_type=mysql.TIMESTAMP(), + server_default=sa.text('CURRENT_TIMESTAMP'), + existing_nullable=False) + op.drop_table('sao_player_hero_card') + op.drop_table('sao_player_ex_bonus') + op.drop_table('sao_static_tower') + op.drop_table('sao_static_skill_table') + op.drop_table('sao_static_side_quest') + op.drop_table('sao_static_ex_tower') + op.drop_table('sao_static_ex_bonus') + op.drop_table('sao_static_episode') + op.drop_table('sao_player_tutorial') + op.drop_table('sao_player_resource_card') + op.add_column('sao_static_quest', sa.Column('version', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.drop_column('sao_static_quest', 'TrioRewardVp') + op.drop_column('sao_static_quest', 'PairRewardVp') + op.drop_column('sao_static_quest', 'SingleRewardVp') + op.drop_column('sao_static_quest', 'TrioExpRate') + op.drop_column('sao_static_quest', 'PairExpRate') + op.drop_column('sao_static_quest', 'FailedPlayerExp') + op.drop_column('sao_static_quest', 'SuccessPlayerExp') + op.drop_column('sao_static_quest', 'PlayerTraceTableSubId') + op.drop_column('sao_static_quest', 'RewardTableSubId') + op.drop_column('sao_static_quest', 'LimitResurrection') + op.drop_column('sao_static_quest', 'LimitDefault') + op.drop_column('sao_static_quest', 'ColRate') + op.drop_column('sao_static_quest', 'Tutorial') + op.drop_column('sao_static_quest', 'SortNo') + op.drop_column('sao_static_quest', 'QuestSceneId') + op.add_column('sao_static_quest', sa.Column('enabled', mysql.TINYINT(display_width=1), autoincrement=False, nullable=True)) + op.add_column('sao_static_quest', sa.Column('id', mysql.INTEGER(display_width=11), autoincrement=True, nullable=False)) + op.add_column('sao_static_quest', sa.Column('questSceneId', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_quest', sa.Column('sortNo', mysql.INTEGER(display_width=11), autoincrement=False, nullable=True)) + op.add_column('sao_static_quest', sa.Column('name', mysql.VARCHAR(length=255), nullable=True)) + op.create_index('sao_static_quest_uk', 'sao_static_quest', ['version', 'questSceneId'], unique=True) + # ### end Alembic commands ### diff --git a/core/data/schema/card.py b/core/data/schema/card.py index 798dd03..6205b4c 100644 --- a/core/data/schema/card.py +++ b/core/data/schema/card.py @@ -25,6 +25,9 @@ aime_card = Table( class CardData(BaseData): + moble_os_codes = set([0x06, 0x07, 0x10, 0x12, 0x13, 0x14, 0x15, 0x17, 0x18]) + card_os_codes = set([0x20, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7]) + async def get_card_by_access_code(self, access_code: str) -> Optional[Row]: sql = aime_card.select(aime_card.c.access_code == access_code) @@ -140,6 +143,11 @@ class CardData(BaseData): if not result: self.logger.error(f"Failed to update IDm to {idm} for {access_code}") + async def set_access_code_by_access_code(self, old_ac: str, new_ac: str) -> None: + result = await self.execute(aime_card.update(aime_card.c.access_code == old_ac).values(access_code=new_ac)) + if not result: + self.logger.error(f"Failed to change card access code from {old_ac} to {new_ac}") + def to_access_code(self, luid: str) -> str: """ Given a felica cards internal 16 hex character luid, convert it to a 0-padded 20 digit access code as a string diff --git a/example_config/sao.yaml b/example_config/sao.yaml index 0209ffe..d405461 100644 --- a/example_config/sao.yaml +++ b/example_config/sao.yaml @@ -2,12 +2,19 @@ server: enable: True loglevel: "info" auto_register: True + photon_app_id: "7df3a2f6-d69d-4073-aafe-810ee61e1cea" + data_version: 1 + game_version: 33 crypt: enable: False key: "" - iv: "" hash: verify_hash: False - hash_base: "" \ No newline at end of file + hash_base: "" + +card: + enable: True + crypt_password: "" + crypt_salt: "" diff --git a/titles/sao/__init__.py b/titles/sao/__init__.py index b6943e6..501af9b 100644 --- a/titles/sao/__init__.py +++ b/titles/sao/__init__.py @@ -1,9 +1,11 @@ from .index import SaoServlet from .const import SaoConstants from .database import SaoData +from .frontend import SaoFrontend from .read import SaoReader index = SaoServlet database = SaoData +frontend = SaoFrontend reader = SaoReader game_codes = [SaoConstants.GAME_CODE] diff --git a/titles/sao/base.py b/titles/sao/base.py index 8d5650d..a589778 100644 --- a/titles/sao/base.py +++ b/titles/sao/base.py @@ -1,448 +1,1173 @@ import logging from csv import * -from random import choice +from random import choice, randint from typing import Dict, List from os import path +import re +from sqlalchemy.engine import Row -from core.data import Data from core import CoreConfig from .config import SaoConfig from .database import SaoData +from .const import GameconnectCmd, RewardType, ExBonusCondition, QuestType from titles.sao.handlers.base import * +import csv class SaoBase: + DATA_LIST = {} def __init__(self, core_cfg: CoreConfig, game_cfg: SaoConfig) -> None: self.core_cfg = core_cfg self.game_cfg = game_cfg self.data = SaoData(core_cfg) - self.version = 0 self.logger = logging.getLogger("sao") - def load_data_csv(self, file: str) -> List[Dict]: - ret = [] - if path.exists(f"titles/sao/data/{file}.csv"): - with open(f"titles/sao/data/{file}.csv", "r", encoding="utf8") as f: - data = csv.DictReader(f, delimiter=',') - for x in data: - ret.append(x) - + def load_data_csv(self, file: str, version: int = 1, base_ver: int = 1) -> List[Dict]: + if base_ver > version: + self.logger.warning(f"load_data_csv: Cannot use base version higher then requested version ({base_ver} > {version})") + return [] + + for x in range(version, base_ver - 1, -1): + ret = self.DATA_LIST.get(x, {}).get(file, []) + if ret: + break + + if not ret and base_ver != 1: + ret = self.DATA_LIST.get(1, {}).get(file, []) + + if ret: return ret - self.logger.warning(f"Failed to find csv file {file}.csv") + found = False + for x in range(version, base_ver - 1, -1): + fname = f"./titles/sao/data/{x}/{file}.csv" + if path.exists(fname): + found_ver = x + found = True + break + + if not found and base_ver != 1: # v1 will always be fallback if it isn't already + fname = f"./titles/sao/data/1/{file}.csv" + if path.exists(fname): + found_ver = 1 + found = True + + if not found: + self.logger.warning(f"load_data_csv: Failed to find v{version} csv file {fname}") + return [] + + ret = [] + with open(fname, "r", encoding="utf8") as f: + data = csv.DictReader(f, delimiter=',') + for x in data: + newdict = {} + for k, v in x.items(): + newkey = k + if k.startswith("// "): + newkey = k.replace("// ", "") + + if v.isdigit(): + newdict[newkey] = int(v) + elif v.lower() == "true": + newdict[newkey] = True + elif v.lower() == "false": + newdict[newkey] = False + elif re.match(r"^\d\d\d\d\/\d\d\/\d\d \d{1,2}:\d\d:\d\d$", v): + newdict[newkey] = datetime.strptime(v, "%Y/%m/%d %H:%M:%S") + elif re.match(r"^\d\d\d\d\/\d\d\/\d\d$", v): + newdict[newkey] = datetime.strptime(v, "%Y/%m/%d") + else: + newdict[newkey] = v + ret.append(newdict) + + # Cache the CSV data in memory + if found_ver not in self.DATA_LIST: + self.DATA_LIST[found_ver] = {} + self.DATA_LIST[found_ver][file] = ret + return ret - async def handle_noop(self, header: SaoRequestHeader, request: bytes) -> bytes: - self.logger.info(f"Using Generic handler") - resp_thing = SaoNoopResponse(header.cmd + 1) - return resp_thing.make() + async def add_reward(self, reward: Dict, user_id: int): + reward_type = int(reward.get("CommonRewardType", "0")) + if reward_type == RewardType.HeroLog: + reward_hero_data = await self.data.static.get_hero_by_id(reward['CommonRewardId']) + now_have_skills = await self.hero_default_skills(reward_hero_data['SkillTableSubId']) + + new_hero_id = await self.data.item.put_hero_log( + user_id, + reward['CommonRewardId'], + 1, + 0, + None, + None, + now_have_skills[0], + now_have_skills[1], + now_have_skills[2], + now_have_skills[3], + now_have_skills[4], + ) + self.logger.info(f"Rewarded user {user_id} with hero {reward['CommonRewardId']} (ID {new_hero_id})") + # TODO: add properties + + elif reward_type == RewardType.Equipment: + new_equip_id = await self.data.item.put_equipment(user_id, reward['CommonRewardId']) + self.logger.info(f"Rewarded user {user_id} with equipment {reward['CommonRewardId']} (ID {new_equip_id})") + + elif reward_type == RewardType.Item: + new_item_id = await self.data.item.put_item(user_id, reward['CommonRewardId']) + self.logger.info(f"Rewarded user {user_id} with item {reward['CommonRewardId']} (ID {new_item_id})") + + elif reward_type == RewardType.Col: + col_num = int(reward['CommonRewardNum']) + self.logger.info(f"Rewarded user {user_id} with {col_num} Col") + await self.data.profile.add_col(user_id, col_num) - async def handle_c122(self, header: SaoRequestHeader, request: bytes) -> bytes: - #common/get_maintenance_info - resp = SaoGetMaintResponse(header.cmd +1) - return resp.make() + elif reward_type == RewardType.VP: + vp_num = int(reward['CommonRewardNum']) + self.logger.info(f"Rewarded user {user_id} with {vp_num} VP") + await self.data.profile.add_vp(user_id, vp_num) - async def handle_c12a(self, header: SaoRequestHeader, request: bytes) -> bytes: - #common/give_free_ticket - req = SaoGiveFreeTicketRequest(header, request) - self.logger.info(f"Give {req.give_num} free tickets (id {req.ticket_id}) to user {req.user_id}") - resp = SaoGiveFreeTicketResponse(header.cmd +1) - return resp.make() + elif reward_type == RewardType.YuiMadal: + medal_num = int(reward['CommonRewardNum']) + self.logger.info(f"Rewarded user {user_id} with {medal_num} Yui Medals") + await self.data.profile.add_yui_medals(user_id, medal_num) + + else: + self.logger.warn(f"User {user_id} Unhandled reward type {reward_type} -> {reward}") - async def handle_c12e(self, header: SaoRequestHeader, request: bytes) -> bytes: - #common/ac_cabinet_boot_notification - resp = SaoCommonAcCabinetBootNotificationResponse(header.cmd +1) - return resp.make() + async def hero_default_skills(self, skill_table_id: int) -> List[int]: + skills = await self.data.static.get_skill_table_by_subid(skill_table_id) + if not skills: + self.logger.error(f"Failed to find skill table {skill_table_id}! Please run the reader") + return [None, None, None, None, None] - async def handle_c100(self, header: SaoRequestHeader, request: bytes) -> bytes: + default_skills = [] + now_have_skills = [None, None, None, None, None] + for skill in skills: + if skill['LevelObtained'] == 1 and skill['AwakeningId'] == 0: + default_skills.append(skill['SkillId']) + + for skill in default_skills: + skill_info = await self.data.static.get_skill_by_id(skill) + skill_slot = skill_info['Level'] - 1 + if now_have_skills[skill_slot] is not None: + now_have_skills[skill] + + return now_have_skills + + async def handle_noop(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + return SaoNoopResponse(header.cmd + 1).make() + + async def handle_c000(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #ticket/ticket + req = SaoTicketRequest(header, request) + return SaoTicketResponse().make() + + async def handle_c100(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #common/get_app_versions - resp = SaoCommonGetAppVersionsRequest(header.cmd +1) + resp = SaoGetAppVersionsResponse() + resp.data_list.append(AppVersionData.from_args(self.game_cfg.server.game_version, datetime.fromtimestamp(0))) return resp.make() - async def handle_c102(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_c102(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #common/master_data_version_check - resp = SaoMasterDataVersionCheckResponse(header.cmd +1) - return resp.make() + req = SaoMasterDataVersionCheckRequest(header, request) + self.logger.info(f"Cab at {src_ip} checked in with master data v{req.current_data_version}") + return SaoMasterDataVersionCheckResponse(self.game_cfg.server.data_version, req.current_data_version).make() - async def handle_c10a(self, header: SaoRequestHeader, request: bytes) -> bytes: - #common/paying_play_start - resp = SaoCommonPayingPlayStartRequest(header.cmd +1) - return resp.make() + async def handle_c104(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #common/login + req = SaoLoginRequest(header, request) - async def handle_ca02(self, header: SaoRequestHeader, request: bytes) -> bytes: - #quest_multi_play_room/get_quest_scene_multi_play_photon_server - resp = SaoGetQuestSceneMultiPlayPhotonServerResponse(header.cmd +1) - return resp.make() - - async def handle_c11e(self, header: SaoRequestHeader, request: bytes) -> bytes: - #common/get_auth_card_data - req = SaoGetAuthCardDataRequest(header, request) - - #Check authentication user_id = await self.data.card.get_user_id_from_card( req.access_code ) - if not user_id: - user_id = await self.data.user.create_user() #works - card_id = await self.data.card.create_card(user_id, req.access_code) - if req.access_code.startswith("5"): - await self.data.card.set_idm_by_access_code(card_id, req.chip_id[:16]) - elif (req.access_code.startswith("010") or req.access_code.startswith("3")) and int(req.chip_id[:8], 16) != 0x04030201: - await self.data.card.set_chip_id_by_access_code(card_id, int(req.chip_id[:8], 16)) + card = await self.data.card.get_card_by_idm(req.chip_id[:16]) + if card: + user_id = card['user'] + card_id = card['id'] + await self.data.card.set_access_code_by_access_code(card['access_code'], req.access_code) + + else: + user_id = await self.data.user.create_user() #works + card_id = await self.data.card.create_card(user_id, req.access_code) if card_id is None: user_id = -1 self.logger.error("Failed to register card!") - - # Create profile with 3 basic heroes - profile_id = await self.data.profile.create_profile(user_id) - await self.data.item.put_hero_log(user_id, 101000010, 1, 0, 201000000, 0, 1002, 1003, 1014, 30001, 30310) - await self.data.item.put_hero_log(user_id, 102000010, 1, 0, 202000000, 0, 3001, 3002, 3004, 30007, 3011) - await self.data.item.put_hero_log(user_id, 105000010, 1, 0, 209000000, 0, 10005, 10002, 10004, 30006, 10003) - await self.data.item.put_hero_log(user_id, 101000110, 1, 0, 201000000, 101000110, 2002, 2001, 2014, 0, 0) - await self.data.item.put_hero_party(user_id, 0, 101000010, 102000010, 105000010) - await self.data.item.put_equipment_data(user_id, 201000000, 1, 200, 0, 0, 0) - await self.data.item.put_equipment_data(user_id, 202000000, 1, 200, 0, 0, 0) - await self.data.item.put_equipment_data(user_id, 209000000, 1, 200, 0, 0, 0) - await self.data.item.put_equipment_data(user_id, 101000110, 1, 200, 0, 0, 0) - await self.data.item.put_player_quest(user_id, 1001, True, 300, 0, 0, 1) - - # Force the tutorial stage to be completed due to potential crash in-game + self.logger.info(f"Registered card {req.access_code} to user {user_id} from {req.serial_no}") + + if req.access_code.startswith("5"): + await self.data.card.set_idm_by_access_code(req.access_code, req.chip_id[:16]) + elif (req.access_code.startswith("010") or req.access_code.startswith("3")) and int(req.chip_id[:8], 16) != 0x04030201: + await self.data.card.set_chip_id_by_access_code(req.access_code, int(req.chip_id[:8], 16)) + + profile_data = await self.data.profile.get_profile(user_id) - self.logger.info(f"User Authenticated: { req.access_code } | { user_id }") + if not profile_data: + profile_id = await self.data.profile.create_profile(user_id) + if profile_id: + equip1 = await self.data.item.put_equipment(user_id, 101000000) + equip2 = await self.data.item.put_equipment(user_id, 102000000) + equip3 = await self.data.item.put_equipment(user_id, 109000000) + if not equip1 or not equip2 or not equip3: + self.logger.error(f"Failed to create profile for user {user_id} from {req.serial_no} (could not add equipment)") + return SaoNoopResponse(GameconnectCmd.LOGIN_RESPONSE).make() + + hero1 = await self.data.item.put_hero_log(user_id, 101000010, 1, 0, equip1, None, 1002, 1003, 1014, None, None) + hero2 = await self.data.item.put_hero_log(user_id, 102000010, 1, 0, equip2, None, 3001, 3002, 3004, None, None) + hero3 = await self.data.item.put_hero_log(user_id, 105000010, 1, 0, equip3, None, 10005, 10002, 10004, None, None) + if not hero1 or not hero2 or not hero3: + self.logger.error(f"Failed to create profile for user {user_id} from {req.serial_no} (could not add heros)") + return SaoNoopResponse(GameconnectCmd.LOGIN_RESPONSE).make() + + await self.data.item.put_hero_party(user_id, 0, hero1, hero2, hero3) + self.logger.info(f"Create profile {profile_id} for user {user_id} from {req.serial_no}") + else: + self.logger.error(f"Failed to create profile for user {user_id} from {req.serial_no}") + return SaoNoopResponse(GameconnectCmd.LOGIN_RESPONSE).make() + resp = SaoLoginResponse(user_id, True, False) + + else: + is_login_today = False + + if profile_data['last_login_date']: + last_login_time = int(profile_data["last_login_date"].timestamp()) + midnight_today_ts = int( + datetime.now() + .replace(hour=0, minute=0, second=0, microsecond=0) + .timestamp() + ) + + if last_login_time > midnight_today_ts: + is_login_today = True + + if not is_login_today: + await self.data.profile.add_vp(user_id, 100) + + resp = SaoLoginResponse(user_id, profile_data['login_ct'] < 1, is_login_today) + + await self.data.profile.user_login(user_id) + return resp.make() + + async def handle_c106(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/logout + req = SaoLogoutRequest(header, request) + self.logger.info(f"User {req.user_id} Logout from {'game' if req.cabinet_type == 0 else 'terminal'} @ {src_ip} with {req.remaining_ticket_num} tickets remaining") + return SaoNoopResponse(GameconnectCmd.LOGOUT_RESPONSE).make() + + async def handle_c108(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/logout_ticket_unpurchased + req = SaoLogoutTicketUnpurchasedRequest(header, request) + self.logger.info(f"User {req.user_id} Logout from {'game' if req.cabinet_type == 0 else 'terminal'} @ {src_ip} without buying a ticket") + return SaoNoopResponse(GameconnectCmd.LOGOUT_TICKET_UNPURCHASED_RESPONSE).make() + + async def handle_c10a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/paying_play_start + req = SaoPayingPlayStartRequest(header, request) + self.logger.info(f"User {req.paying_user_id} started paying session @ {req.store_name} ({src_ip}) on cab {req.serial_no}") + resp = SaoPayingPlayStartResponse() + # TODO: session management + return resp.make() + + async def handle_c10c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/paying_play_end + req = SaoPayingPlayEndRequest(header, request) + self.logger.info(f"User {req.paying_user_id} ended paying session {req.paying_session_id} @ {req.store_name} ({src_ip}) on cab {req.serial_no} after {req.played_amount} {req.played_type} type games") + return SaoNoopResponse(GameconnectCmd.PAYING_PLAY_END_RESPONSE).make() + + async def handle_c10e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/purchase_ticket + req = SaoPurchaseTicketRequest(header, request) + self.logger.info(f"User {req.user_id} pruchased {req.purchase_num} tickets (ID {req.ticket_id}) @ {src_ip} with discout type {req.discount_type}") + return SaoNoopResponse(GameconnectCmd.PURCHASE_TICKET_RESPONSE).make() + + async def handle_c110(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/consume_ticket + req = SaoConsumeTicketRequest(header, request) + self.logger.info(f"User {req.user_id} consumed {req.consume_num} tickets (ID {req.ticket_id}) @ {src_ip} with discout type {req.discount_type} on {req.act_type}") + return SaoNoopResponse(GameconnectCmd.CONSUME_TICKET_RESPONSE).make() + + async def handle_c112(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/add_credit + req = SaoAddCreditRequest(header, request) + self.logger.info(f"User {req.user_id} added {req.add_num} credits to a {'game' if req.cabinet_type == 0 else 'terminal'} @ {src_ip}") + return SaoNoopResponse(GameconnectCmd.ADD_CREDIT_RESPONSE).make() + + async def handle_c114(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/consume_credit + req = SaoConsumeCreditRequest(header, request) + self.logger.info(f"User {req.user_id} consumed {req.consume_num} credits on a {'game' if req.cabinet_type == 0 else 'terminal'} @ {req.store_id} ({src_ip}) on {req.act_type}") + return SaoNoopResponse(GameconnectCmd.CONSUME_CREDIT_RESPONSE).make() + + async def handle_c116(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/purchase_ticket_guest + req = SaoPurchaseTicketGuestRequest(header, request) + self.logger.info(f"Guest purchased {req.purchase_num} tickets on a {'game' if req.cabinet_type == 0 else 'terminal'} @ {req.store_id} ({src_ip} | SN {req.serial_no})") + return SaoNoopResponse(GameconnectCmd.PURCHASE_TICKET_GUEST_RESPONSE).make() + + async def handle_c118(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/consume_ticket_guest + req = SaoConsumeTicketGuestRequest(header, request) + self.logger.info(f"Guest consumed {req.consume_num} tickets @ {req.store_id} ({src_ip} | SN {req.serial_no}) with discout type {req.discount_type} on {req.act_type}") + return SaoNoopResponse(GameconnectCmd.CONSUME_TICKET_GUEST_RESPONSE).make() + + async def handle_c11a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/add_credit_guest + req = SaoAddCreditGuestRequest(header, request) + self.logger.info(f"Guest added {req.add_num} credits to a {'game' if req.cabinet_type == 0 else 'terminal'} @ {req.store_id} ({src_ip} | SN {req.serial_no})") + return SaoNoopResponse(GameconnectCmd.ADD_CREDIT_GUEST_RESPONSE).make() + + async def handle_c11c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/consume_credit_guest + req = SaoConsumeCreditGuestRequest(header, request) + self.logger.info(f"Guest consumed {req.consume_num} credits on a {'game' if req.cab_type == 0 else 'terminal'} @ {req.shop_id} ({src_ip} | SN {req.serial_num}) on {req.act_type}") + return SaoNoopResponse(GameconnectCmd.CONSUME_CREDIT_GUEST_RESPONSE).make() + + async def handle_c11e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #common/get_auth_card_data + req = SaoGetAuthCardDataRequest(header, request) + + #Check authentication + card = await self.data.card.get_card_by_access_code( req.access_code ) + + if not card: + card = await self.data.card.get_card_by_idm(req.chip_id[:16]) + if not card: + self.logger.info(f"Unregistered card {req.access_code} authenticated from {req.serial_no}") + return SaoGetAuthCardDataResponse("NEW PLAYER", 0).make() + + await self.data.card.set_access_code_by_access_code(card['access_code'], req.access_code) + + else: + user_id = card['user'] + card_id = card['id'] + + if req.access_code.startswith("5") and not card['idm']: + await self.data.card.set_idm_by_access_code(card_id, req.chip_id[:16]) + elif (req.access_code.startswith("010") or req.access_code.startswith("3")) and not card['chip_id'] and int(req.chip_id[:8], 16) != 0x04030201: + await self.data.card.set_chip_id_by_access_code(card_id, int(req.chip_id[:8], 16)) + + self.logger.info(f"User Authenticated from {req.serial_no}: { req.access_code } | { user_id }") #Grab values from profile profile_data = await self.data.profile.get_profile(user_id) - if user_id and not profile_data: - profile_id = await self.data.profile.create_profile(user_id) - await self.data.item.put_hero_log(user_id, 101000010, 1, 0, 201000000, 0, 1002, 1003, 1014, 30001, 30310) - await self.data.item.put_hero_log(user_id, 102000010, 1, 0, 202000000, 0, 3001, 3002, 3004, 30007, 3011) - await self.data.item.put_hero_log(user_id, 105000010, 1, 0, 209000000, 0, 10005, 10002, 10004, 30006, 10003) - await self.data.item.put_hero_log(user_id, 101000110, 1, 0, 201000000, 101000110, 2002, 2001, 2014, 0, 0) - await self.data.item.put_hero_party(user_id, 0, 101000010, 102000010, 105000010) - await self.data.item.put_equipment_data(user_id, 201000000, 1, 200, 0, 0, 0) - await self.data.item.put_equipment_data(user_id, 202000000, 1, 200, 0, 0, 0) - await self.data.item.put_equipment_data(user_id, 209000000, 1, 200, 0, 0, 0) - await self.data.item.put_equipment_data(user_id, 101000110, 1, 200, 0, 0, 0) - await self.data.item.put_player_quest(user_id, 1001, True, 300, 0, 0, 1) + if not profile_data: + self.logger.info(f"Unregistered user {user_id} with card {req.access_code} authenticated from {req.serial_no}") + return SaoGetAuthCardDataResponse("NEW PLAYER", user_id).make() - # Force the tutorial stage to be completed due to potential crash in-game + return SaoGetAuthCardDataResponse(profile_data['nick_name'], user_id).make() + async def handle_c120(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/get_access_code_by_keitai + req = SaoGetAccessCodeByKeitaiRequest(header, request) + cid = req.chip_id + idm = cid[:16] + pmm = cid[16:] + card = await self.data.card.get_card_by_idm(idm) + + # If we don't have that card saved locally, check aimedb + if not card: + # Validate that we're talking to a phone + if not int(pmm[2:4], 16) in self.data.card.moble_os_codes: + self.logger.warn(f"{req.serial_no} looked up non-moble chip ID {cid}!") + return SaoGetAccessCodeByKeitaiResponse("").make() + + # TODO: Actual felica moble registration + return SaoGetAccessCodeByKeitaiResponse("").make() + #ac = await self.data.card.register_felica_moble_ac(idm, pmm) + # if we didn't get an access code, fail hard + if not ac: + self.logger.warn(f"Failed to register access code for chip ID {cid} requested by {req.serial_no}") + return SaoGetAccessCodeByKeitaiResponse("").make() + + self.logger.info(f"Successfully registered moble felica access code {ac} for chip ID {cid} requested by {req.serial_no}") + + uid = await self.data.user.create_user() + if not uid: + self.logger.error(f"Failed to create user for chip ID {cid} (access code {ac}) @ LoadAccessCode request from {req.serial_no}") + return SaoGetAccessCodeByKeitaiResponse("").make() + + cardid = await self.data.card.create_card(uid, ac) + if not cardid: + self.logger.error(f"Failed to create card for user {uid} with chip ID {cid} (access code {ac}) @ LoadAccessCode request from {req.serial_no}") + await self.data.user.delete_user(uid) + return SaoGetAccessCodeByKeitaiResponse("").make() + + self.logger.info(f"Moble Felica access code lookup for {cid} -> {ac} (user {uid}) requested by {req.serial_no}") + + else: + ac = card['access_code'] + uid = card['user'] + self.logger.info(f"Moble Felica access code for {cid} -> {ac} (user {uid}) requested by {req.serial_no}") + + return SaoGetAccessCodeByKeitaiResponse(ac).make() - profile_data = await self.data.profile.get_profile(user_id) - - resp = SaoGetAuthCardDataResponse(header.cmd +1, profile_data) + async def handle_c122(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #common/get_maintenance_info + resp = SaoGetMaintenanceInfoResponse() return resp.make() - async def handle_c40c(self, header: SaoRequestHeader, request: bytes) -> bytes: - #home/check_ac_login_bonus - resp = SaoHomeCheckAcLoginBonusResponse(header.cmd +1) + async def handle_c124(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #common/get_resource_path_info + resp = SaoGetResourcePathInfoResponse(f"https://{self.core_cfg.server.hostname}/saoresource/") return resp.make() - async def handle_c104(self, header: SaoRequestHeader, request: bytes) -> bytes: - #common/login - req = SaoCommonLoginRequest(header, request) + async def handle_c126(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/validation_error_notification + req = SaoValidationErrorNotificationRequest(header, request) + self.logger.warn(f"User {req.user_id} on {'game' if req.cabinet_type == 0 else 'terminal'} {req.serial_no} @ {req.store_name} ({src_ip} | Place ID {req.place_id}) " \ + + f"Validation error: {req.send_protocol_name} || {req.send_data_to_fraud_value} || {req.send_data_to_modification_value}") + return SaoNoopResponse(GameconnectCmd.VALIDATION_ERROR_NOTIFICATION_RESPONSE).make() - user_id = await self.data.card.get_user_id_from_card( req.access_code ) - profile_data = await self.data.profile.get_profile(user_id) + async def handle_c128(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/power_cutting_return_notification + req = SaoPowerCuttingReturnNotification(header, request) + self.logger.warn(f"User {req.user_id} on {'game' if req.cabinet_type == 0 else 'terminal'} {req.serial_no} @ {req.store_name} ({src_ip} | Place ID {req.place_id}) " \ + + f"Power outage return: Act Type {req.last_act_type} || {req.remaining_ticket_num} Remaining Tickets || {req.remaining_credit_num} Remaining Credits") + return SaoNoopResponse(GameconnectCmd.POWER_CUTTING_RETURN_NOTIFICATION_RESPONSE).make() - resp = SaoCommonLoginResponse(header.cmd +1, profile_data) + async def handle_c12a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #common/give_free_ticket + req = SaoGiveFreeTicketRequest(header, request) + self.logger.info(f"Give {req.give_num} free tickets (id {req.ticket_id}) to user {req.user_id}") + resp = SaoNoopResponse(GameconnectCmd.GIVE_FREE_TICKET_RESPONSE) return resp.make() - async def handle_c404(self, header: SaoRequestHeader, request: bytes) -> bytes: - #home/check_comeback_event - resp = SaoCheckComebackEventRequest(header.cmd +1) + async def handle_c12c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # common/matching_error_notification + req = SaoMatchingErrorNotificationRequest(header, request) + self.logger.warn(f"{'game' if req.cabinet_type == 0 else 'terminal'} {req.serial_no} @ {req.store_name} ({src_ip} | Place ID {req.place_id}) " \ + + f"Matching error: {req.matching_error_data_list[0]}") + return SaoNoopResponse(GameconnectCmd.MATCHING_ERROR_NOTIFICATION_RESPONSE).make() + + async def handle_c12e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #common/ac_cabinet_boot_notification + req = SaoCommonAcCabinetBootNotificationRequest(header, request) + + if req.current_version_app_id < self.game_cfg.server.game_version: + self.logger.info(f"!!OUTDATED!! {'Game' if req.cabinet_type == 0 else 'Terminal'} {req.serial_no} Booted v{req.current_version_app_id} (Master data v{req.current_master_data_version}): {req.store_name} ({src_ip} | Place/Shop ID {req.place_id}/{req.store_id})") + + if req.current_version_app_id > self.game_cfg.server.game_version: + self.logger.info(f"!!TOO NEW!! {'Game' if req.cabinet_type == 0 else 'Terminal'} {req.serial_no} Booted v{req.current_version_app_id} (Master data v{req.current_master_data_version}): {req.store_name} ({src_ip} | Place/Shop ID {req.place_id}/{req.store_id})") + + self.logger.info(f"{'Game' if req.cabinet_type == 0 else 'Terminal'} {req.serial_no} Booted v{req.current_version_app_id} (Master data v{req.current_master_data_version}): {req.store_name} ({src_ip} | Place/Shop ID {req.place_id}/{req.store_id})") + resp = SaoNoopResponse(GameconnectCmd.AC_CABINET_BOOT_NOTIFICATION_RESPONSE) return resp.make() - async def handle_c000(self, header: SaoRequestHeader, request: bytes) -> bytes: - #ticket/ticket - resp = SaoTicketResponse(header.cmd +1) + async def handle_c200(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # tutorial/first_tutorial_end + req = SaoGenericUserTicketRequest(header, request) + self.logger.info(f"User {req.user_id} (ticket {req.ticket_id}) finished first tutorial") + return SaoNoopResponse(GameconnectCmd.FIRST_TUTORIAL_END_RESPONSE).make() + + async def handle_c202(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # tutorial/various_tutorial_end + req = SaoVariousTutorialEndRequest(header, request) + await self.data.profile.add_tutorial_byte(int(req.user_id), req.tutorial_type) + return SaoNoopResponse(GameconnectCmd.VARIOUS_TUTORIAL_END_RESPONSE).make() + + async def handle_c204(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # tutorial/get_various_tutorial_data_list + req = SaoGenericUserRequest(header, request) + tuts = await self.data.profile.get_tutorial_bytes(int(req.user_id)) + resp = SaoGetVariousTutorialDataListResponse() + if tuts: + for t in tuts: + resp.end_tutorial_type_list.append(t['tutorial_byte']) + return resp.make() - async def handle_c500(self, header: SaoRequestHeader, request: bytes) -> bytes: - #user_info/get_user_basic_data + async def handle_c300(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # card/discharge_profile_card + req = SaoDischargeProfileCardRequest(header, request) + # Real cards seem to start with 10-17 as the first 2 digits, so we'll anchor ours with 2 to ensure no overlap + sn = f"2{str(randint(1, 999999999999999999)).zfill(18)}" + while await self.data.profile.get_hero_card(sn): + sn = f"2{str(randint(1, 999999999999999999)).zfill(18)}" + resp = SaoDischargeProfileCardResponse(sn) + + db_hero = await self.data.item.get_hero_log(req.user_id, req.hero_log_user_hero_log_id) + if not db_hero: + hero_statc = await self.data.static.get_hero_by_id(db_hero['hero_log_id']) + if not hero_statc: + self.logger.error(f"Failed to find hero log {db_hero['hero_log_id']}! Please run the reader") + resp.header.error_type = ProtocolErrorNum.RESOURCE_CARD_ERR1 + return resp.make() + + now_have_skills = await self.hero_default_skills(hero_statc['SkillTableSubId']) + + db_hero_id = await self.data.item.put_hero_log( + req.user_id, + db_hero['hero_log_id'], + 1, + 0, + None, + None, + now_have_skills[0], + now_have_skills[1], + now_have_skills[2], + now_have_skills[3], + now_have_skills[4] + ) + if not db_hero_id: + self.logger.error(f"Failed to give user {req.user_id} hero {db_hero['hero_log_id']}!") + resp.header.error_type = ProtocolErrorNum.RESOURCE_CARD_ERR6 + return resp.make() + + else: + db_hero_id = db_hero['id'] + + await self.data.profile.put_hero_card(req.user_id, sn, db_hero_id, req.holographic_flag) + + self.logger.info(f"User {req.user_id} printed {'holo ' if req.holographic_flag == 1 else ''}profile card {req.hero_log_user_hero_log_id} {req.execute_print_type}, code {sn}") + return resp.make() + + async def handle_c302(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # card/discharge_resource_card + req = SaoDischargeResourceCardRequest(header, request) + + for x in req.common_reward_user_data: + sn = f"2{str(randint(1, 999999999999999999)).zfill(18)}" + self.logger.info(f"User {req.user_id} printed {'holo ' if req.holographic_flag == 1 else ''}resource card {x.user_common_reward_id} {req.execute_print_type}, code {sn}") + await self.data.profile.put_resource_card(req.user_id, sn, x.common_reward_type, x.user_common_reward_id, req.holographic_flag) + + return SaoDischargeProfileCardResponse(sn).make() + + async def handle_c304(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # card/discharge_resource_card_complete + req = SaoDischargeResourceCardCompleteRequest(header, request) + self.logger.info(f"User {req.user_id} finished printing resource card {req.resource_card_code}") + return SaoNoopResponse(GameconnectCmd.DISCHARGE_RESOURCE_CARD_COMPLETE_RESPONSE).make() + + async def handle_c306(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #card/scan_qr_quest_profile_card + req = SaoScanQrQuestProfileCardRequest(header, request) + resp = SaoScanQrQuestProfileCardResponse() + + card = await self.data.profile.get_hero_card(req.profile_card_code) + if not card: + self.logger.warn(f"User {req.user_id} scanned unregistered QR code {req.profile_card_code}") + return resp.make() + + hero = await self.data.item.get_hero_log_by_id(card['user_hero_id']) + if not hero: # Shouldn't happen + self.logger.warn(f"User {req.user_id} scanned QR code {req.profile_card_code} but does not have hero entry {card['user_hero_id']}") + return resp.make() + + hero_static_data = await self.data.static.get_hero_by_id(hero['hero_log_id']) + if not hero_static_data: # Shouldn't happen + self.logger.warn(f"No entry for hero {hero['hero_log_id']}, please run read.py") + return resp.make() + + profile = await self.data.profile.get_profile(card['user']) + if not profile: # Shouldn't happen + self.logger.warn(f"No profile for user {card['user']}, something broke") + return resp.make() + + self.logger.info(f"User {req.user_id} scanned QR code {req.profile_card_code}") + card_resp = ReadProfileCard.from_args(req.profile_card_code, profile['nick_name']) + card_resp.rank_num = profile['rank_num'] + card_resp.setting_title_id = profile['setting_title_id'] + card_resp.skill_id = hero['skill_slot1_skill_id'] + card_resp.hero_log_hero_log_id = hero['hero_log_id'] + card_resp.hero_log_log_level = hero['log_level'] + #TODO: Awakening + #card_resp.hero_log_awakening_stage = hero['log_level'] + + resp.profile_card_data.append(card_resp) + return resp.make() + + async def handle_c308(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # card/scan_qr_shop_resource_card + req = SaoScanQrShopResourceCardRequest(header, request) + self.logger.info(f"User {req.user_id} scanned shop resource card {req.resource_card_code}") + resp = SaoNoopResponse(GameconnectCmd.SCAN_QR_SHOP_RESOURCE_CARD_RESPONSE) + # On official, resource cards have limited uses, but we don't track that currently (tho we should) + + card = await self.data.profile.get_resource_card(req.resource_card_code) # TODO: use count + if not card: + self.logger.warn(f"No resource card with serial {req.resource_card_code} exists!") + resp.header.err_status = 4832 # Theres a few error codes but none seem to do anything? + # Also not sure if it should be this or result + + return resp.make() + + async def handle_c30a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # card/scan_qr_quest_resource_card + req = SaoScanQrQuestResourceCardRequest(header, request) + self.logger.info(f"User {req.user_id} scanned quest resource card {req.resource_card_code}") + + card = await self.data.profile.get_resource_card(req.resource_card_code) + if not card: + resp = SaoScanQrQuestResourceCardResponse(card['common_reward_type'], card['common_reward_id'], card['holographic_flag']) + + else: + self.logger.warn(f"No resource card with serial {req.resource_card_code} exists!") + resp = SaoScanQrQuestResourceCardResponse() + resp.header.err_status = 4832 # Theres a few error codes but none seem to do anything? + # Also not sure if it should be this or result + + return resp.make() + + async def handle_c400(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #home/check_yui_medal_get_condition + req = SaoCheckYuiMedalGetConditionRequest(header, request) + profile = await self.data.profile.get_profile(req.user_id) + if profile['last_yui_medal_date']: + last_check_ts = int(profile['last_yui_medal_date'].timestamp()) + day_ts = int(datetime.now().replace(hour=0, minute=0, second=0, microsecond=0).timestamp()) + diff_ts = day_ts - last_check_ts + if diff_ts > 0: + num_days = diff_ts / 86400 + else: + num_days = 0 + else: + num_days = 1 + + if num_days > 1: + await self.data.profile.add_yui_medals(req.user_id) + + await self.data.profile.update_yui_medal_date(req.user_id) + return SaoCheckYuiMedalGetConditionResponse(num_days, 1 if num_days > 1 else 0).make() + + async def handle_c402(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #home/get_yui_medal_bonus_user_data + req = SaoGetYuiMedalBonusUserDataRequest(header, request) + resp = SaoGetYuiMedalBonusUserDataResponse() # TODO: Track yui login bonus + return resp.make() + + async def handle_c404(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # home/check_comeback_event + req = SaoGenericUserTicketRequest(header, request) + resp = SaoCheckComebackEventResponse() + #resp.get_comeback_event_id_list += [1,2,3,4] # TODO: track comeback date + return resp.make() + + async def handle_c406(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # home/change_my_store + req = SaoChangeMyStoreRequest(header, request) + self.logger.info(f"User {req.user_id} changed My Store to {req.store_id}") + shop_id = int(req.store_id[3:], 16) + await self.data.profile.set_my_shop(req.user_id, shop_id) + return SaoNoopResponse(GameconnectCmd.CHANGE_MY_STORE_RESPONSE).make() + + async def handle_c408(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # home/check_title_get_decision + req = SaoCheckTitleGetDecisionRequest(header, request) + resp = SaoCheckTitleGetDecisionResponse() # TODO: titles + return resp.make() + + async def handle_c40a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # home/check_profile_card_used_reward + req = SaoCheckProfileCardUsedRewardRequest(header, request) + resp = SaoCheckProfileCardUsedRewardResponse() # TODO: check_profile_card_used_reward + return resp.make() + + async def handle_c40c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # home/check_ac_login_bonus + req = SaoGenericUserTicketRequest(header, request) + resp = SaoCheckAcLoginBonusResponse() + #resp.get_ac_login_bonus_id_list.append(1) # TODO: track login bonus date + #resp.get_ac_login_bonus_id_list.append(2) + return resp.make() + + async def handle_c500(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # user_info/get_user_basic_data req = SaoGetUserBasicDataRequest(header, request) profile_data = await self.data.profile.get_profile(req.user_id) + player_rank_data = self.load_data_csv("PlayerRank") - resp = SaoGetUserBasicDataResponse(header.cmd +1, profile_data) - return resp.make() + resp = SaoGetUserBasicDataResponse(profile_data) + for e in player_rank_data: + if resp.user_basic_data[0].rank_num == int(e['PlayerRankId']): + resp.user_basic_data[0].rank_exp = resp.user_basic_data[0].rank_exp - int(e["TotalExp"]) + break - async def handle_c600(self, header: SaoRequestHeader, request: bytes) -> bytes: - #have_object/get_hero_log_user_data_list - req = SaoGetHeroLogUserDataListRequest(header, request) + if profile_data['my_shop']: + ac = await self.data.arcade.get_arcade(profile_data['my_shop']) + if ac: + resp.user_basic_data[0].my_store_name = ac['name'] + + return resp.make() + + async def handle_c502(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # user_info/get_vp_gasha_ticket_data_list + req = SaoGetVpGashaTicketDataListRequest(header, request) + # TODO: gasha tickets + resp = SaoGetVpGashaTicketDataListResponse() + return resp.make() + + async def handle_c504(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # user_info/get_present_box_num + req = SaoGenericUserRequest(header, request) + # TODO: presents + return SaoGetPresentBoxNumResponse().make() + + async def handle_c600(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # have_object/get_hero_log_user_data_list + req = SaoGenericUserRequest(header, request) + hero_level_data = self.load_data_csv("HeroLogLevel") hero_data = await self.data.item.get_hero_logs(req.user_id) - resp = SaoGetHeroLogUserDataListResponse(header.cmd +1, hero_data) + resp = SaoGetHeroLogUserDataListResponse() + for hero in hero_data: + append = HeroLogUserData.from_args(hero) + hero_static = await self.data.static.get_hero_by_id(hero['hero_log_id']) + if not hero_static: + self.logger.warn(f"No hero for id {hero['hero_log_id']}, please run reader") + resp.hero_log_user_data_list.append(append) + continue + + append.property1_property_id = hero_static['Property1PropertyId'] if hero_static['Property1PropertyId'] else 0 + append.property1_value1 = hero_static['Property1Value1'] if hero_static['Property1Value1'] else 0 + append.property1_value2 = hero_static['Property1Value2'] if hero_static['Property1Value2'] else 0 + append.property2_property_id = hero_static['Property2PropertyId'] if hero_static['Property2PropertyId'] else 0 + append.property2_value1 = hero_static['Property2Value1'] if hero_static['Property2Value1'] else 0 + append.property2_value2 = hero_static['Property2Value2'] if hero_static['Property2Value2'] else 0 + append.property3_property_id = hero_static['Property3PropertyId'] if hero_static['Property3PropertyId'] else 0 + append.property3_value1 = hero_static['Property3Value1'] if hero_static['Property3Value1'] else 0 + append.property3_value2 = hero_static['Property3Value2'] if hero_static['Property3Value2'] else 0 + append.property4_property_id = hero_static['Property4PropertyId'] if hero_static['Property4PropertyId'] else 0 + append.property4_value1 = hero_static['Property4Value1'] if hero_static['Property4Value1'] else 0 + append.property4_value2 = hero_static['Property4Value2'] if hero_static['Property4Value2'] else 0 + + for e in hero_level_data: + if hero['log_level'] == int(e['HeroLogLevelId']): + append.log_exp = hero['log_exp'] - int(e["TotalExp"]) + break + resp.hero_log_user_data_list.append(append) + return resp.make() - - async def handle_c602(self, header: SaoRequestHeader, request: bytes) -> bytes: - #have_object/get_equipment_user_data_list - req = SaoGetEquipmentUserDataListRequest(header, request) + + async def handle_c602(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # have_object/get_equipment_user_data_list + req = SaoGenericUserRequest(header, request) + resp = SaoGetEquipmentUserDataListResponse() + equip_level_data = self.load_data_csv("EquipmentLevel") equipment_data = await self.data.item.get_user_equipments(req.user_id) + + if equipment_data: + for equipment in equipment_data: + e = EquipmentUserData.from_args(equipment) + weapon_static = await self.data.static.get_equipment_by_id(equipment['equipment_id']) + if not weapon_static: + self.logger.warn(f"No equipment for id {equipment['equipment_id']}, please run reader") + resp.equipment_user_data_list.append(e) + continue + + if not e.property1_property_id: + e.property1_property_id = weapon_static['Property1PropertyId'] if weapon_static['Property1PropertyId'] else 0 + e.property1_value1 = weapon_static['Property1Value1'] if weapon_static['Property1Value1'] else 0 + e.property1_value2 = weapon_static['Property1Value2'] if weapon_static['Property1Value2'] else 0 + + if not e.property2_property_id: + e.property2_property_id = weapon_static['Property2PropertyId'] if weapon_static['Property2PropertyId'] else 0 + e.property2_value1 = weapon_static['Property2Value1'] if weapon_static['Property2Value1'] else 0 + e.property2_value2 = weapon_static['Property2Value2'] if weapon_static['Property2Value2'] else 0 + + if e.property3_property_id: + e.property3_property_id = weapon_static['Property3PropertyId'] if weapon_static['Property3PropertyId'] else 0 + e.property3_value1 = weapon_static['Property3Value1'] if weapon_static['Property3Value1'] else 0 + e.property3_value2 = weapon_static['Property3Value2'] if weapon_static['Property3Value2'] else 0 + + if e.property4_property_id: + e.property4_property_id = weapon_static['Property4PropertyId'] if weapon_static['Property4PropertyId'] else 0 + e.property4_value1 = weapon_static['Property4Value1'] if weapon_static['Property4Value1'] else 0 + e.property4_value2 = weapon_static['Property4Value2'] if weapon_static['Property4Value2'] else 0 + + for f in equip_level_data: + if equipment['enhancement_value'] == int(f['EquipmentLevelId']): + e.enhancement_exp = equipment['enhancement_exp'] - int(f["TotalExp"]) + break + resp.equipment_user_data_list.append(e) - resp = SaoGetEquipmentUserDataListResponse(header.cmd +1, equipment_data) return resp.make() - - async def handle_c604(self, header: SaoRequestHeader, request: bytes) -> bytes: - #have_object/get_item_user_data_list - req = SaoGetItemUserDataListRequest(header, request) + + async def handle_c604(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # have_object/get_item_user_data_list + req = SaoGenericUserRequest(header, request) item_data = await self.data.item.get_user_items(req.user_id) - resp = SaoGetItemUserDataListResponse(header.cmd +1, item_data) + resp = SaoGetItemUserDataListResponse(item_data) return resp.make() + + async def handle_c606(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # have_object/get_support_log_user_data_list + req = SaoGenericUserRequest(header, request) + resp = SaoGetSupportLogUserDataListResponse() + supports = self.load_data_csv("SupportLog") + # TODO: Save supports - async def handle_c606(self, header: SaoRequestHeader, request: bytes) -> bytes: - #have_object/get_support_log_user_data_list - supportIdsData = await self.data.static.get_support_log_ids(0, True) - - resp = SaoGetSupportLogUserDataListResponse(header.cmd +1, supportIdsData) + for x in range(len(supports)): + tmp = SupportLogUserData.from_args(f"{req.user_id}{x}", supports[x]['SupportLogId']) + resp.support_log_user_data_list.append(tmp) + return resp.make() + + async def handle_c608(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #have_object/get_episode_append_data_list + req = SaoGenericUserRequest(header, request) + # TODO: Appends + resp = SaoGetEpisodeAppendDataListResponse() return resp.make() - async def handle_c800(self, header: SaoRequestHeader, request: bytes) -> bytes: - #custom/get_title_user_data_list + async def handle_c60a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # have_object/get_event_item_data_list + req = SaoGenericUserRequest(header, request) + res = SaoGetEventItemDataListResponse() + # TODO: Event items maybe + return res.make() + + async def handle_c60c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # have_object/get_gasha_medal_user_data_list + req = SaoGenericUserRequest(header, request) + res = SaoGetGashaMedalUserDataListResponse() + # TODO: Gasha Medal data + return res.make() + + async def handle_c700(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # shop/get_shop_resource_sales_data_list + # TODO: Get user shop data + req = SaoGenericUserRequest(header, request) + resp = SaoGetShopResourceSalesDataListResponse() + return resp.make() + + async def handle_c702(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # shop/purchase_shop_resource + req = SaoPurchaseShopResourceRequest(header, request) + self.logger.infof(f"User {req.user_id} (ticket {req.ticket_id}) purchased shop resourse {req.user_shop_resource_id}") + # TODO: Shop purchases + return SaoNoopResponse(GameconnectCmd.PURCHASE_SHOP_RESOURCE_RESPONSE).make() + + async def handle_c704(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # shop/discard_shop_resource + req = SaoPurchaseShopResourceRequest(header, request) + self.logger.infof(f"User {req.user_id} (ticket {req.ticket_id}) discarded shop resourse {req.user_shop_resource_id}") + return SaoNoopResponse(GameconnectCmd.DISCARD_SHOP_RESOURCE_RESPONSE).make() + + async def handle_c800(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # custom/get_title_user_data_list + req = SaoGenericUserRequest(header, request) titleIdsData = await self.data.static.get_title_ids(0, True) + # TODO: Save titles - resp = SaoGetTitleUserDataListResponse(header.cmd +1, titleIdsData) + resp = SaoGetTitleUserDataListResponse(req.user_id, titleIdsData) return resp.make() + + async def handle_c802(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # custom/change_title + req = SaoChangeTitleRequest(header, request) + self.logger.info(f"User {req.user_id} (ticket {req.ticket_id}) changed their title to {req.user_title_id}") + await self.data.profile.set_title(req.user_id, req.user_title_id) - async def handle_c608(self, header: SaoRequestHeader, request: bytes) -> bytes: - #have_object/get_episode_append_data_list - req = SaoGetEpisodeAppendDataListRequest(header, request) + return SaoNoopResponse(GameconnectCmd.CHANGE_TITLE_RESPONSE).make() - profile_data = await self.data.profile.get_profile(req.user_id) + async def handle_c804(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # custom/get_party_data_list + req = SaoGenericUserRequest(header, request) + resp = SaoGetPartyDataListResponse() + + hero_parties = await self.data.item.get_hero_party(req.user_id) + for party in hero_parties: + hero1_data = await self.data.item.get_user_hero_by_id(party['user_hero_log_id_1']) + hero2_data = await self.data.item.get_user_hero_by_id(party['user_hero_log_id_2']) + hero3_data = await self.data.item.get_user_hero_by_id(party['user_hero_log_id_3']) + + resp.party_data_list.append(PartyData.from_args(party['id'], party['user_party_team_id'], hero1_data._asdict(), hero2_data._asdict(), hero3_data._asdict())) - resp = SaoGetEpisodeAppendDataListResponse(header.cmd +1, profile_data) return resp.make() - async def handle_c804(self, header: SaoRequestHeader, request: bytes) -> bytes: - #custom/get_party_data_list - req = SaoGetPartyDataListRequest(header, request) - - hero_party = await self.data.item.get_hero_party(req.user_id, 0) - hero1_data = await self.data.item.get_hero_log(req.user_id, hero_party[3]) - hero2_data = await self.data.item.get_hero_log(req.user_id, hero_party[4]) - hero3_data = await self.data.item.get_hero_log(req.user_id, hero_party[5]) - - resp = SaoGetPartyDataListResponse(header.cmd +1, hero1_data, hero2_data, hero3_data) + async def handle_c808(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # custom/get_support_log_party_data_list + req = SaoGenericUserRequest(header, request) + resp = SaoGetSupportLogPartyDataListResponse() + # TODO: Support logs return resp.make() - async def handle_c902(self, header: SaoRequestHeader, request: bytes) -> bytes: # for whatever reason, having all entries empty or filled changes nothing - #quest/get_quest_scene_prev_scan_profile_card - resp = SaoGetQuestScenePrevScanProfileCardResponse(header.cmd +1) - return resp.make() + async def handle_c812(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # custom/disposal_resource + req = SaoDisposalResourceRequest(header, request) + get_col = 0 + for disposal in req.disposal_common_reward_user_data_list: + if disposal.common_reward_type == RewardType.HeroLog: + removed_hero = await self.data.item.remove_hero_log(disposal.user_common_reward_id) + if removed_hero: + static_hero = await self.data.static.get_hero_by_id(removed_hero) + get_col += static_hero['SalePrice'] + + elif disposal.common_reward_type == RewardType.Equipment: + removed_equip = await self.data.item.remove_equipment(disposal.user_common_reward_id) + if removed_equip: + static_equip = await self.data.static.get_equipment_by_id(removed_equip) + get_col += static_equip['SalePrice'] - async def handle_c124(self, header: SaoRequestHeader, request: bytes) -> bytes: - #common/get_resource_path_info - resp = SaoGetResourcePathInfoResponse(header.cmd +1) - return resp.make() + elif disposal.common_reward_type == RewardType.Item: + removed_equip = await self.data.item.remove_item(disposal.user_common_reward_id) + if removed_equip: + static_equip = await self.data.static.get_equipment_by_id(removed_equip) + get_col += static_equip['SalePrice'] - async def handle_c900(self, header: SaoRequestHeader, request: bytes) -> bytes: - #quest/get_quest_scene_user_data_list // QuestScene.csv - req = SaoGetQuestSceneUserDataListRequest(header, request) + elif disposal.common_reward_type == RewardType.SupportLog: + continue - quest_data = await self.data.item.get_quest_logs(req.user_id) + else: + self.logger.warn(f"Unhandled disposal type {disposal.common_reward_type}") - resp = SaoGetQuestSceneUserDataListResponse(header.cmd +1, quest_data) - return resp.make() + await self.data.profile.add_col(req.user_id, get_col) + return SaoDisposalResourceResponse(get_col).make() - async def handle_c400(self, header: SaoRequestHeader, request: bytes) -> bytes: - #home/check_yui_medal_get_condition - resp = SaoCheckYuiMedalGetConditionResponse(header.cmd +1) - return resp.make() - - async def handle_c402(self, header: SaoRequestHeader, request: bytes) -> bytes: - #home/get_yui_medal_bonus_user_data - resp = SaoGetYuiMedalBonusUserDataResponse(header.cmd +1) - return resp.make() - - async def handle_c40a(self, header: SaoRequestHeader, request: bytes) -> bytes: - #home/check_profile_card_used_reward - resp = SaoCheckProfileCardUsedRewardResponse(header.cmd +1) - return resp.make() - - async def handle_c814(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_c814(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #custom/synthesize_enhancement_hero_log req = SaoSynthesizeEnhancementHeroLogRequest(header, request) - - synthesize_hero_log_data = await self.data.item.get_hero_log(req.user_id, req.origin_user_hero_log_id) + resp = SaoSynthesizeEnhancementHeroLogResponse() + hero_level_data = self.load_data_csv("HeroLogLevel") + equip_level_data = self.load_data_csv("EquipmentLevel") + hero_exp = 0 + col_cost = 0 for x in req.material_common_reward_user_data_list: - hero_exp = 0 - itemList = await self.data.static.get_item_id(x.user_common_reward_id) - heroList = await self.data.static.get_hero_id(x.user_common_reward_id) - equipmentList = await self.data.static.get_equipment_id(x.user_common_reward_id) + if x.common_reward_type == RewardType.Item: + user_item = await self.data.item.get_user_item_by_id(x.user_common_reward_id) + static_item = await self.data.static.get_item_id(user_item['item_id']) + + if int(static_item['ItemTypeId']) == 7: + hero_exp += int(static_item['Value']) + self.logger.info(f"Remove item {x.user_common_reward_id} and add {int(static_item['Value'])} XP (running {hero_exp})") + await self.data.item.remove_item(x.user_common_reward_id) - if itemList: - hero_exp = 2000 + int(synthesize_hero_log_data["log_exp"]) - await self.data.item.remove_item(req.user_id, x.user_common_reward_id) - - if equipmentList: - equipment_data = await self.data.item.get_user_equipment(req.user_id, x.user_common_reward_id) + elif x.common_reward_type == RewardType.Equipment: + equipment_data = await self.data.item.get_user_equipment_by_id(x.user_common_reward_id) if equipment_data is None: self.logger.error(f"Failed to find equipment {x.user_common_reward_id} for user {req.user_id}!") continue - hero_exp = int(equipment_data["enhancement_exp"]) + int(synthesize_hero_log_data["log_exp"]) - await self.data.item.remove_equipment(req.user_id, x.user_common_reward_id) + req_exp = 0 + for e in range(len(equip_level_data)): + if equipment_data['enhancement_value'] == int(equip_level_data[e]['EquipmentLevelId']): + req_exp = equip_level_data[e + 1]['RequireExp'] + break + + static_equip_data = await self.data.static.get_equipment_by_id(equipment_data['equipment_id']) + + hero_exp += int(static_equip_data['CompositionExp']) + req_exp + self.logger.info(f"Remove equipment {x.user_common_reward_id} and add {int(static_equip_data['CompositionExp']) + req_exp} XP (running {hero_exp})") + await self.data.item.remove_equipment(x.user_common_reward_id) - if heroList: - hero_data = await self.data.item.get_hero_log(req.user_id, x.user_common_reward_id) + elif x.common_reward_type == RewardType.HeroLog: + hero_data = await self.data.item.get_hero_log_by_id(x.user_common_reward_id) if hero_data is None: self.logger.error(f"Failed to find hero {x.user_common_reward_id} for user {req.user_id}!") continue + + req_exp = 0 + for e in range(len(hero_level_data)): + if hero_data['log_level'] == int(hero_level_data[e]['HeroLogLevelId']): + req_exp = hero_level_data[e + 1]['RequireExp'] + break - hero_exp = int(hero_data["log_exp"]) + int(synthesize_hero_log_data["log_exp"]) - await self.data.item.remove_hero_log(req.user_id, x.user_common_reward_id) + static_hero_data = await self.data.static.get_hero_by_id(hero_data['hero_log_id']) + + hero_exp += int(static_hero_data['CompositionExp']) + req_exp + self.logger.info(f"Remove hero {x.user_common_reward_id} and add {int(static_hero_data['CompositionExp']) + req_exp} XP (running {hero_exp})") + await self.data.item.remove_hero_log(x.user_common_reward_id) - if hero_exp == 0: - self.logger.warn(f"Hero {x.user_common_reward_id} (type {x.common_reward_type}) not found!") + else: + self.logger.warn(f"Unhandled ype {x.common_reward_type}! (running {hero_exp})") + + hero_exp = int(hero_exp * 1.5) + await self.data.item.add_hero_xp(req.origin_user_hero_log_id, hero_exp) + log_exp = await self.data.item.get_hero_xp(req.origin_user_hero_log_id) + pre_synth_xp = log_exp - hero_exp + pre_synth_level = 1 + + for e in range(len(hero_level_data)): + if log_exp>=int(hero_level_data[e]["TotalExp"]) and log_exp=int(hero_level_data[e]["TotalExp"]) and pre_synth_xp= 100: + col_cost = col_cost * 10 + + col_cost = col_cost * 1000 + col_cost = max(100, int(col_cost / 1000)) + + self.logger.info(f"Synthesize {hero_exp} exp for hero {req.origin_user_hero_log_id}, costing {col_cost} col") + + await self.data.profile.add_col(req.user_id, -col_cost) + if synthesize_hero_log_data is not None: + resp.after_hero_log_user_data.append(HeroLogUserData.from_args(synthesize_hero_log_data)) + resp.after_hero_log_user_data[0].log_exp = remain_exp return resp.make() - async def handle_c816(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_c816(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #custom/synthesize_enhancement_equipment req_data = SaoSynthesizeEnhancementEquipmentRequest(header, request) - synthesize_equipment_data = await self.data.item.get_user_equipment(req_data.user_id, req_data.origin_user_equipment_id) + resp = SaoSynthesizeEnhancementEquipmentResponse() + hero_level_data = self.load_data_csv("HeroLogLevel") + equip_level_data = self.load_data_csv("EquipmentLevel") + equipment_exp = 0 + col_cost = 0 for x in req_data.material_common_reward_user_data_list: - equipment_exp = 0 - itemList = await self.data.static.get_item_id(x.user_common_reward_id) - heroList = await self.data.static.get_hero_id(x.user_common_reward_id) - equipmentList = await self.data.static.get_equipment_id(x.user_common_reward_id) + if x.common_reward_type == RewardType.Item: + user_item = await self.data.item.get_user_item_by_id(x.user_common_reward_id) + static_item = await self.data.static.get_item_id(user_item['item_id']) + + if int(static_item['ItemTypeId']) == 7: + equipment_exp += int(static_item['Value']) + self.logger.info(f"Remove item {x.user_common_reward_id} and add {int(static_item['Value'])} XP (running {equipment_exp})") + await self.data.item.remove_item(x.user_common_reward_id) - if itemList: - equipment_exp = 2000 + int(synthesize_equipment_data["enhancement_exp"]) - await self.data.item.remove_item(req_data.user_id, x.user_common_reward_id) - - if equipmentList: - equipment_data = await self.data.item.get_user_equipment(req_data.user_id, x.user_common_reward_id) + elif x.common_reward_type == RewardType.Equipment: + equipment_data = await self.data.item.get_user_equipment_by_id(x.user_common_reward_id) if equipment_data is None: self.logger.error(f"Failed to find equipment {x.user_common_reward_id} for user {req_data.user_id}!") continue + + req_exp = 0 + for e in range(len(equip_level_data)): + if equipment_data['enhancement_value'] == int(equip_level_data[e]['EquipmentLevelId']): + req_exp = equip_level_data[e + 1]['RequireExp'] + break + + static_equip_data = await self.data.static.get_equipment_by_id(equipment_data['equipment_id']) + + equipment_exp += int(static_equip_data['CompositionExp']) + req_exp + self.logger.info(f"Remove equipment {x.user_common_reward_id} and add {int(static_equip_data['CompositionExp']) + req_exp} XP (running {equipment_exp})") + await self.data.item.remove_equipment(x.user_common_reward_id) - equipment_exp = int(equipment_data["enhancement_exp"]) + int(synthesize_equipment_data["enhancement_exp"]) - await self.data.item.remove_equipment(req_data.user_id, x.user_common_reward_id) - - if heroList: - hero_data = await self.data.item.get_hero_log(req_data.user_id, x.user_common_reward_id) + elif x.common_reward_type == RewardType.HeroLog: + hero_data = await self.data.item.get_hero_log_by_id(x.user_common_reward_id) if hero_data is None: self.logger.error(f"Failed to find hero {x.user_common_reward_id} for user {req_data.user_id}!") continue - equipment_exp = int(hero_data["log_exp"]) + int(synthesize_equipment_data["enhancement_exp"]) - await self.data.item.remove_hero_log(req_data.user_id, x.user_common_reward_id) - - if equipment_exp == 0: - self.logger.warn(f"Common reward {x.user_common_reward_id} (type {x.common_reward_type}) not found!") - continue + req_exp = 0 + for e in range(len(hero_level_data)): + if hero_data['log_level'] == int(hero_level_data[e]['HeroLogLevelId']): + req_exp = hero_level_data[e + 1]['RequireExp'] + break + + static_hero_data = await self.data.static.get_hero_by_id(hero_data['hero_log_id']) + + equipment_exp += int(static_hero_data['CompositionExp']) + req_exp + self.logger.info(f"Remove hero {x.user_common_reward_id} and add {int(static_hero_data['CompositionExp']) + req_exp} XP (running {equipment_exp})") + await self.data.item.remove_hero_log(x.user_common_reward_id) - await self.data.item.put_equipment_data(req_data.user_id, int(req_data.origin_user_equipment_id), synthesize_equipment_data["enhancement_value"], equipment_exp, 0, 0, 0) - - profile = await self.data.profile.get_profile(req_data.user_id) - new_col = int(profile["own_col"]) - 100 - - # Update profile - - await self.data.profile.put_profile( - req_data.user_id, - profile["user_type"], - profile["nick_name"], - profile["rank_num"], - profile["rank_exp"], - new_col, - profile["own_vp"], - profile["own_yui_medal"], - profile["setting_title_id"] - ) + else: + self.logger.warn(f"Unhandled ype {x.common_reward_type}! (running {equipment_exp})") + + equipment_exp = int(equipment_exp * 1.5) + await self.data.item.add_equipment_enhancement_exp(req_data.origin_user_equipment_id, equipment_exp) + synthesize_equipment_data = await self.data.item.get_user_equipment(req_data.user_id, req_data.origin_user_equipment_id) + equip_exp_new = synthesize_equipment_data['enhancement_exp'] + pre_synth_level = synthesize_equipment_data['enhancement_value'] + new_synth_level = 1 + + for e in range(len(equip_level_data)): + if equip_exp_new>=int(equip_level_data[e]["TotalExp"]) and equip_exp_new= 100: + col_cost = col_cost * 10 + + col_cost = col_cost * 1000 + col_cost = max(100, int(col_cost / 1000)) + + self.logger.info(f"Synthesize {equipment_exp} exp for equipment {req_data.origin_user_equipment_id}, costing {col_cost} col") + + await self.data.profile.add_col(req_data.user_id, -col_cost) + if synthesize_equipment_data is not None: + resp.after_equipment_user_data.append(EquipmentUserData.from_args(synthesize_equipment_data)) + resp.after_equipment_user_data[0].enhancement_exp = remain_exp + resp.after_equipment_user_data[0].enhancement_value = new_synth_level return resp.make() - async def handle_c806(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_c806(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #custom/change_party req_data = SaoChangePartyRequest(header, request) - party_hero_list = [] - for party_team in req_data.party_data_list[0].party_team_data_list: - hero_data = await self.data.item.get_hero_log(req_data.user_id, party_team.user_hero_log_id) - hero_level = 1 - hero_exp = 0 + for party_team in req_data.party_data_list: + for hero in party_team.party_team_data_list: + await self.data.item.set_user_hero_weapons( + int(hero.user_hero_log_id), + int(hero.main_weapon_user_equipment_id) if hero.main_weapon_user_equipment_id and int(hero.main_weapon_user_equipment_id) > 0 else None, + int(hero.sub_equipment_user_equipment_id) if hero.sub_equipment_user_equipment_id and int(hero.sub_equipment_user_equipment_id) > 0 else None + ) + await self.data.item.set_user_hero_skills( + int(hero.user_hero_log_id), + hero.skill_slot1_skill_id if hero.skill_slot1_skill_id > 0 else None, + hero.skill_slot2_skill_id if hero.skill_slot2_skill_id > 0 else None, + hero.skill_slot3_skill_id if hero.skill_slot3_skill_id > 0 else None, + hero.skill_slot4_skill_id if hero.skill_slot4_skill_id > 0 else None, + hero.skill_slot5_skill_id if hero.skill_slot5_skill_id > 0 else None + ) - if hero_data: - hero_level = hero_data["log_level"] - hero_exp = hero_data["log_exp"] - await self.data.item.put_hero_log( + await self.data.item.put_hero_party( req_data.user_id, - party_team.user_hero_log_id, - hero_level, - hero_exp, - party_team.main_weapon_user_equipment_id, - party_team.sub_equipment_user_equipment_id, - party_team.skill_slot1_skill_id, - party_team.skill_slot2_skill_id, - party_team.skill_slot3_skill_id, - party_team.skill_slot4_skill_id, - party_team.skill_slot5_skill_id + party_team.team_no, + party_team.party_team_data_list[0].user_hero_log_id, + party_team.party_team_data_list[1].user_hero_log_id, + party_team.party_team_data_list[2].user_hero_log_id, ) - party_hero_list.append(party_team.user_hero_log_id) - - await self.data.item.put_hero_party(req_data.user_id, req_data.party_data_list[0].party_team_data_list[0].user_party_team_id, party_hero_list[0], party_hero_list[1], party_hero_list[2]) - - resp = SaoNoopResponse(header.cmd +1) + resp = SaoNoopResponse(GameconnectCmd.CHANGE_PARTY_RESPONSE) return resp.make() - async def handle_c904(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_c900(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #quest/get_quest_scene_user_data_list + req = SaoGenericUserRequest(header, request) + + quest_data = await self.data.item.get_quest_logs(req.user_id) + + resp = SaoGetQuestSceneUserDataListResponse() + for quest in quest_data: + ex_bonus_data = await self.data.item.get_player_ex_bonus_by_quest(req.user_id, quest["quest_scene_id"]) + tmp = QuestSceneUserData.from_args(quest) + + for ex_bonus in ex_bonus_data: + tmp.quest_scene_ex_bonus_user_data_list.append(QuestSceneExBonusUserData.from_args(ex_bonus['ex_bonus_table_id'], ex_bonus['quest_clear_flag'])) + + resp.quest_scene_user_data_list.append(tmp) + return resp.make() + + async def handle_c902(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: # for whatever reason, having all entries empty or filled changes nothing + #quest/get_quest_scene_prev_scan_profile_card + resp = SaoGetQuestScenePrevScanProfileCardResponse() + resp.profile_card_data.append(ReadProfileCardData.from_args({}, {})) + return resp.make() + + async def handle_c904(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #quest/episode_play_start req_data = SaoEpisodePlayStartRequest(header, request) user_id = req_data.user_id profile_data = await self.data.profile.get_profile(user_id) - await self.data.item.create_session( + sesh_id = await self.data.item.create_session( user_id, int(req_data.play_start_request_data[0].user_party_id), req_data.episode_id, @@ -450,178 +1175,228 @@ class SaoBase: req_data.play_start_request_data[0].quest_drop_boost_apply_flag ) - resp = SaoEpisodePlayStartResponse(header.cmd +1, profile_data) + resp = SaoEpisodePlayStartResponse() + resp.play_start_response_data.append(QuestScenePlayStartResponseData.from_args(sesh_id, profile_data['nick_name'])) + resp.multi_play_start_response_data.append(QuestSceneMultiPlayStartResponseData.from_args()) return resp.make() - async def handle_c908(self, header: SaoRequestHeader, request: bytes) -> bytes: # Level calculation missing for the profile and heroes + async def handle_c908(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: # Level calculation missing for the profile and heroes #quest/episode_play_end - req_data = SaoEpisodePlayEndRequest(header, request) + resp = SaoEpisodePlayEndResponse() - # Add stage progression to database user_id = req_data.user_id episode_id = req_data.episode_id - quest_clear_flag = bool(req_data.play_end_request_data_list[0].score_data_list[0].boss_destroying_num) - clear_time = req_data.play_end_request_data_list[0].score_data_list[0].clear_time - combo_num = req_data.play_end_request_data_list[0].score_data_list[0].combo_num - total_damage = req_data.play_end_request_data_list[0].score_data_list[0].total_damage - concurrent_destroying_num = req_data.play_end_request_data_list[0].score_data_list[0].concurrent_destroying_num + play_end = req_data.play_end_request_data[0] + base_get_data = play_end.base_get_data[0] + score_data = play_end.score_data[0] + exp = 0 + cleared_mission_ct = 0 + highest_mission_diff_cleared = 0 + num_monsters_defeated = 0 + monsters_defeated_data = {} + json_data = {"data": []} + + ep_data = await self.data.static.get_episode_by_id(req_data.episode_id) + quest_scene = await self.data.static.get_quest_by_id(int(ep_data['QuestSceneId'])) + reward_table = await self.data.static.get_rewards_by_subtable(int(quest_scene['RewardTableSubId'])) + ex_bonus_table = await self.data.static.get_ex_bonuses_by_subtable(int(ep_data['ExBonusTableSubId'])) - profile = await self.data.profile.get_profile(user_id) - vp = int(profile["own_vp"]) - exp = int(profile["rank_exp"]) + 100 #always 100 extra exp for some reason - col = int(profile["own_col"]) + int(req_data.play_end_request_data_list[0].base_get_data_list[0].get_col) + await self.data.profile.add_col(user_id, base_get_data.get_col) + quest_clear_flag = score_data.clear_time > 0 + clear_time = score_data.clear_time + combo_num = score_data.combo_num + total_damage = score_data.total_damage + concurrent_destroying_num = score_data.concurrent_destroying_num + if quest_clear_flag is True: - # Save stage progression - to be revised to avoid saving worse score - - # Reference Episode.csv but Chapter 2,3,4 and 5 reports id -1, match using /10 + last digits - if episode_id > 10000 and episode_id < 11000: - # Starts at 1001 - episode_id = episode_id - 9000 - elif episode_id > 20000: - # Starts at 2001 - stage_id = str(episode_id)[-2:] - episode_id = episode_id / 10 - episode_id = int(episode_id) + int(stage_id) - - # Match episode_id with the questSceneId saved in the DB through sortNo - questId = await self.data.static.get_quests_id(episode_id) - episode_id = questId[2] - - await self.data.item.put_player_quest(user_id, episode_id, quest_clear_flag, clear_time, combo_num, total_damage, concurrent_destroying_num) - - vp = int(profile["own_vp"]) + 10 #always 10 VP per cleared stage - - + await self.data.profile.add_vp(user_id, quest_scene['SingleRewardVp']) + await self.data.profile.add_exp(user_id, quest_scene['SuccessPlayerExp']) + exp = await self.data.profile.get_exp(user_id) + + else: + await self.data.profile.add_exp(user_id, quest_scene['FailedPlayerExp']) + exp = await self.data.profile.get_exp(user_id) + # Calculate level based off experience and the CSV list - with open(r'titles/sao/data/PlayerRank.csv') as csv_file: - csv_reader = csv.reader(csv_file, delimiter=',') - line_count = 0 - data = [] - rowf = False - for row in csv_reader: - if rowf==False: - rowf=True - else: - data.append(row) + player_level_data = self.load_data_csv("PlayerRank") - for i in range(0,len(data)): - if exp>=int(data[i][1]) and exp=int(player_level_data[i]["TotalExp"]) and exp highest_mission_diff_cleared: + highest_mission_diff_cleared = mission.mission_difficulty_id + + for monster_data in play_end.discovery_enemy_data_list: + num_monsters_defeated += monster_data.destroy_num + monsters_defeated_data[monster_data.enemy_kind_id] = monster_data.destroy_num + + for bonus in ex_bonus_table: + table_id = int(bonus['ExBonusTableId']) + ach_thing = 0 + condition = int(bonus['ExBonusConditionId']) + val1 = int(bonus['ConditionValue1']) + val2 = int(bonus['ConditionValue2']) + if condition == ExBonusCondition.CLEAR_UNDER_X_SECS: + if quest_clear_flag and int(score_data.clear_time / 1000) < val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.DEFEAT_X_MONSTER_Y_TIMES: + if monsters_defeated_data.get(val1, 0) >= val2: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.DEFEAT_X_MONSTERS: + if num_monsters_defeated >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.CLEAR_X_MISSIONS: + if cleared_mission_ct >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.CLEAR_MISSION_DIFFICULTY_X: + if highest_mission_diff_cleared >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.COLLECT_X_LOGS: + if len(play_end.get_unanalyzed_log_tmp_reward_data_list) >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.CLEAR_SKILL_LEVEL_X: + if score_data.reaching_skill_level >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.NO_LOSSES: + if score_data.total_loss_num == 0: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.ACCEL_X_TIMES: + if score_data.acceleration_invocation_num >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.MAX_COMBO_X: + if score_data.combo_num >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.MULTIPLAYER_CLEAR_X: + # TODO + pass + else: + self.logger.warn(f"Unhandled EX Bonus condition {condition}") + + resp.play_end_response_data[0].ex_bonus_data_list.append(QuestScenePlayEndExBonusData.from_args(table_id, ach_thing)) + + self.logger.info(f"User {user_id} {'cleared' if quest_clear_flag else 'ended'} episode {episode_id}") + + for rare_drop in play_end.get_rare_drop_data_list: + rewardList = self.load_data_csv("QuestRareDrop") + for drop in rewardList: + if int(drop['QuestRareDropId']) == rare_drop.quest_rare_drop_id: + await self.add_reward(drop, user_id) + break + + for unanalyzed_log in play_end.get_unanalyzed_log_tmp_reward_data_list: + able_rewards: List[Row] = [] + for reward in reward_table: + if int(reward['UnanalyzedLogGradeId']) == unanalyzed_log.unanalyzed_log_grade_id: + able_rewards.append(reward) + randomized_unanalyzed_id = choice(able_rewards) + + await self.add_reward(randomized_unanalyzed_id._asdict(), user_id) + json_data["data"].append(randomized_unanalyzed_id._asdict()) + + + trace_table = await self.data.static.get_player_trace_by_subid(quest_scene['PlayerTraceTableSubId']) + + for trace in play_end.get_player_trace_data_list: + self.logger.info(f"User {user_id} obtained trace {trace.user_quest_scene_player_trace_id}") + resp.play_end_response_data[0].play_end_player_trace_reward_data_list.append(QuestScenePlayEndPlayerTraceRewardData.from_args(choice(trace_table)._asdict())) + + await self.data.item.create_end_session(user_id, ep_data['QuestSceneId'], play_end.play_result_flag, json_data["data"]) # Update heroes from the used party play_session = await self.data.item.get_session(user_id) - session_party = await self.data.item.get_hero_party(user_id, play_session["user_party_team_id"]) + session_party = await self.data.item.get_hero_party_by_id(play_session["user_party_team_id"]) + if session_party: + hero_level_data = self.load_data_csv("HeroLogLevel") + hero_list = [] + hero_list.append(session_party["user_hero_log_id_1"]) + hero_list.append(session_party["user_hero_log_id_2"]) + hero_list.append(session_party["user_hero_log_id_3"]) - hero_list = [] - hero_list.append(session_party["user_hero_log_id_1"]) - hero_list.append(session_party["user_hero_log_id_2"]) - hero_list.append(session_party["user_hero_log_id_3"]) + for i in range(0,3): + await self.data.item.add_hero_xp(hero_list[i], base_get_data.get_hero_log_exp) + log_exp = await self.data.item.get_hero_xp(hero_list[i]) - for i in range(0,len(hero_list)): - hero_data = await self.data.item.get_hero_log(user_id, hero_list[i]) + # Calculate hero level based off experience and the CSV list + if log_exp: + for e in range(0,len(hero_level_data)): + if log_exp>=int(hero_level_data[e]["TotalExp"]) and log_exp=int(data[e][1]) and log_exp bytes: + async def handle_c90a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #quest/episode_play_end_unanalyzed_log_fixed + req = SaoEpisodePlayEndUnanalyzedLogFixedRequest(header, request) + resp = SaoEpisodePlayEndUnanalyzedLogFixedResponse() + + end_session_data = await self.data.item.get_end_session(req.user_id) + for data in end_session_data['reward_data']: + resp.play_end_unanalyzed_log_reward_data_list.append(QuestScenePlayEndUnanalyzedLogRewardData.from_args(data['UnanalyzedLogGradeId'], data)) + + return resp.make() + + async def handle_c914(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #quest/trial_tower_play_start req_data = SaoTrialTowerPlayStartRequest(header, request) user_id = req_data.user_id - floor_id = req_data.trial_tower_id profile_data = await self.data.profile.get_profile(user_id) - await self.data.item.create_session( + sesh_id = await self.data.item.create_session( user_id, int(req_data.play_start_request_data[0].user_party_id), req_data.trial_tower_id, @@ -629,374 +1404,1222 @@ class SaoBase: req_data.play_start_request_data[0].quest_drop_boost_apply_flag ) - resp = SaoEpisodePlayStartResponse(header.cmd +1, profile_data) + self.logger.info(f"User {req_data.user_id} started trial tower on floor {req_data.trial_tower_id}") + resp = SaoTrialTowerPlayStartResponse(sesh_id, profile_data['nick_name']) return resp.make() - async def handle_c918(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_c918(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #quest/trial_tower_play_end req_data = SaoTrialTowerPlayEndRequest(header, request) + resp = SaoTrialTowerPlayEndResponse() - # Add tower progression to database user_id = req_data.user_id trial_tower_id = req_data.trial_tower_id - next_tower_id = 0 - quest_clear_flag = bool(req_data.play_end_request_data_list[0].score_data_list[0].boss_destroying_num) - clear_time = req_data.play_end_request_data_list[0].score_data_list[0].clear_time - combo_num = req_data.play_end_request_data_list[0].score_data_list[0].combo_num - total_damage = req_data.play_end_request_data_list[0].score_data_list[0].total_damage - concurrent_destroying_num = req_data.play_end_request_data_list[0].score_data_list[0].concurrent_destroying_num - - if quest_clear_flag is True: - # Save tower progression - to be revised to avoid saving worse score - if trial_tower_id == 9: - next_tower_id = 10001 - elif trial_tower_id == 10: - trial_tower_id = 10001 - next_tower_id = 3011 - elif trial_tower_id == 19: - next_tower_id = 10002 - elif trial_tower_id == 20: - trial_tower_id = 10002 - next_tower_id = 3021 - elif trial_tower_id == 29: - next_tower_id = 10003 - elif trial_tower_id == 30: - trial_tower_id = 10003 - next_tower_id = 3031 - elif trial_tower_id == 39: - next_tower_id = 10004 - elif trial_tower_id == 40: - trial_tower_id = 10004 - next_tower_id = 3041 - elif trial_tower_id == 49: - next_tower_id = 10005 - elif trial_tower_id == 50: - trial_tower_id = 10005 - next_tower_id = 3051 - else: - trial_tower_id = trial_tower_id + 3000 - next_tower_id = trial_tower_id + 1 - - await self.data.item.put_player_quest(user_id, trial_tower_id, quest_clear_flag, clear_time, combo_num, total_damage, concurrent_destroying_num) - - # Check if next stage is already done - checkQuest = await self.data.item.get_quest_log(user_id, next_tower_id) - if not checkQuest: - if next_tower_id != 3101: - await self.data.item.put_player_quest(user_id, next_tower_id, 0, 0, 0, 0, 0) - - # Update the profile - profile = await self.data.profile.get_profile(user_id) + play_end = req_data.play_end_request_data[0] + base_get_data = play_end.base_get_data[0] + score_data = play_end.score_data[0] + exp = 0 + cleared_mission_ct = 0 + highest_mission_diff_cleared = 0 + num_monsters_defeated = 0 + monsters_defeated_data = {} + json_data = {"data": []} - exp = int(profile["rank_exp"]) + 100 #always 100 extra exp for some reason - col = int(profile["own_col"]) + int(req_data.play_end_request_data_list[0].base_get_data_list[0].get_col) + ep_data = await self.data.static.get_tower_by_id(trial_tower_id) + quest_scene = await self.data.static.get_quest_by_id(int(ep_data['QuestSceneId'])) + reward_table = await self.data.static.get_rewards_by_subtable(int(quest_scene['RewardTableSubId'])) + ex_bonus_table = await self.data.static.get_ex_bonuses_by_subtable(int(ep_data['ExBonusTableSubId'])) + await self.data.profile.add_col(user_id, base_get_data.get_col) + + quest_clear_flag = score_data.clear_time > 0 + clear_time = score_data.clear_time + combo_num = score_data.combo_num + total_damage = score_data.total_damage + concurrent_destroying_num = score_data.concurrent_destroying_num + + if quest_clear_flag is True: + await self.data.profile.add_vp(user_id, quest_scene['SingleRewardVp']) + await self.data.profile.add_exp(user_id, quest_scene['SuccessPlayerExp']) + exp = await self.data.profile.get_exp(user_id) + + else: + await self.data.profile.add_exp(user_id, quest_scene['FailedPlayerExp']) + exp = await self.data.profile.get_exp(user_id) + # Calculate level based off experience and the CSV list - with open(r'titles/sao/data/PlayerRank.csv') as csv_file: - csv_reader = csv.reader(csv_file, delimiter=',') - line_count = 0 - data = [] - rowf = False - for row in csv_reader: - if rowf==False: - rowf=True - else: - data.append(row) + player_level_data = self.load_data_csv("PlayerRank") - for i in range(0,len(data)): - if exp>=int(data[i][1]) and exp=int(player_level_data[i]["TotalExp"]) and exp highest_mission_diff_cleared: + highest_mission_diff_cleared = mission.mission_difficulty_id + + for monster_data in play_end.discovery_enemy_data_list: + num_monsters_defeated += monster_data.destroy_num + monsters_defeated_data[monster_data.enemy_kind_id] = monster_data.destroy_num + + for bonus in ex_bonus_table: + table_id = int(bonus['ExBonusTableId']) + ach_thing = 0 + condition = int(bonus['ExBonusConditionId']) + val1 = int(bonus['ConditionValue1']) + val2 = int(bonus['ConditionValue2']) + if condition == ExBonusCondition.CLEAR_UNDER_X_SECS: + if quest_clear_flag and int(score_data.clear_time / 1000) < val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.DEFEAT_X_MONSTER_Y_TIMES: + if monsters_defeated_data.get(val1, 0) >= val2: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.DEFEAT_X_MONSTERS: + if num_monsters_defeated >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.CLEAR_X_MISSIONS: + if cleared_mission_ct >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.CLEAR_MISSION_DIFFICULTY_X: + if highest_mission_diff_cleared >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.COLLECT_X_LOGS: + if len(play_end.get_unanalyzed_log_tmp_reward_data_list) >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.CLEAR_SKILL_LEVEL_X: + if score_data.reaching_skill_level >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.NO_LOSSES: + if score_data.total_loss_num == 0: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.ACCEL_X_TIMES: + if score_data.acceleration_invocation_num >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.MAX_COMBO_X: + if score_data.combo_num >= val1: + await self.add_reward(bonus._asdict(), user_id) + await self.data.item.put_ex_bonus(user_id, int(ep_data['QuestSceneId']), table_id, True) + ach_thing = 2 + elif condition == ExBonusCondition.MULTIPLAYER_CLEAR_X: + # TODO + pass + else: + self.logger.warn(f"Unhandled EX Bonus condition {condition}") + + resp.play_end_response_data[0].ex_bonus_data_list.append(QuestScenePlayEndExBonusData.from_args(table_id, ach_thing)) + + self.logger.info(f"User {user_id} {'cleared' if quest_clear_flag else 'ended'} trial tower {trial_tower_id}") + + for rare_drop in play_end.get_rare_drop_data_list: + rewardList = self.load_data_csv("QuestRareDrop") + for drop in rewardList: + if int(drop['QuestRareDropId']) == rare_drop.quest_rare_drop_id: + await self.add_reward(drop, user_id) + break + + for unanalyzed_log in play_end.get_unanalyzed_log_tmp_reward_data_list: + able_rewards: List[Row] = [] + for reward in reward_table: + if int(reward['UnanalyzedLogGradeId']) == unanalyzed_log.unanalyzed_log_grade_id: + able_rewards.append(reward) + randomized_unanalyzed_id = choice(able_rewards) + + await self.add_reward(randomized_unanalyzed_id._asdict(), user_id) + json_data["data"].append(randomized_unanalyzed_id._asdict()) + + + trace_table = await self.data.static.get_player_trace_by_subid(quest_scene['PlayerTraceTableSubId']) + + for trace in play_end.get_player_trace_data_list: + self.logger.info(f"User {user_id} obtained trace {trace.user_quest_scene_player_trace_id}") + resp.play_end_response_data[0].play_end_player_trace_reward_data_list.append(QuestScenePlayEndPlayerTraceRewardData.from_args(choice(trace_table)._asdict())) + + await self.data.item.create_end_session(user_id, ep_data['QuestSceneId'], play_end.play_result_flag, json_data["data"]) # Update heroes from the used party play_session = await self.data.item.get_session(user_id) - session_party = await self.data.item.get_hero_party(user_id, play_session["user_party_team_id"]) + session_party = await self.data.item.get_hero_party_by_id(play_session["user_party_team_id"]) + if session_party: + hero_level_data = self.load_data_csv("HeroLogLevel") + hero_list = [] + hero_list.append(session_party["user_hero_log_id_1"]) + hero_list.append(session_party["user_hero_log_id_2"]) + hero_list.append(session_party["user_hero_log_id_3"]) - hero_list = [] - hero_list.append(session_party["user_hero_log_id_1"]) - hero_list.append(session_party["user_hero_log_id_2"]) - hero_list.append(session_party["user_hero_log_id_3"]) + for i in range(0,3): + self.logger.info(f"Give hero {hero_list[i]} {base_get_data.get_hero_log_exp}") + await self.data.item.add_hero_xp(hero_list[i], base_get_data.get_hero_log_exp) + log_exp = await self.data.item.get_hero_xp(hero_list[i]) - for i in range(0,len(hero_list)): - hero_data = await self.data.item.get_hero_log(user_id, hero_list[i]) + # Calculate hero level based off experience and the CSV list + if log_exp: + for e in range(0,len(hero_level_data)): + if log_exp>=int(hero_level_data[e]["TotalExp"]) and log_exp=int(data[e][1]) and log_exp bytes: - #quest/episode_play_end_unanalyzed_log_fixed - - req = SaoEpisodePlayEndUnanalyzedLogFixedRequest(header, request) - - end_session_data = await self.data.item.get_end_session(req.user_id) - - resp = SaoEpisodePlayEndUnanalyzedLogFixedResponse(header.cmd +1, end_session_data[4]) - return resp.make() - - async def handle_c91a(self, header: SaoRequestHeader, request: bytes) -> bytes: # handler is identical to the episode + async def handle_c91a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: # handler is identical to the episode #quest/trial_tower_play_end_unanalyzed_log_fixed - req = TrialTowerPlayEndUnanalyzedLogFixed(header, request) - + req = SaoTrialTowerPlayEndUnanalyzedLogFixedRequest(header, request) + resp = SaoTrialTowerPlayEndUnanalyzedLogFixedResponse() + end_session_data = await self.data.item.get_end_session(req.user_id) + for data in end_session_data['reward_data']: + resp.play_end_unanalyzed_log_reward_data_list.append(QuestScenePlayEndUnanalyzedLogRewardData.from_args(data['UnanalyzedLogGradeId'], data)) - resp = SaoEpisodePlayEndUnanalyzedLogFixedResponse(header.cmd +1, end_session_data[4]) return resp.make() - async def handle_cd00(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_c930(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # quest/get_chat_side_story_user_data_list + req = SaoGenericUserRequest(header, request) + resp = SaoGetChatSideStoryUserDataListResponse() + + return resp.make() + + async def handle_ca02(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + #quest_multi_play_room/get_quest_scene_multi_play_photon_server + resp = SaoGetQuestSceneMultiPlayPhotonServerResponse(self.game_cfg.server.photon_app_id) + return resp.make() + + async def handle_cb02(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # quest_ranking/get_quest_hierarchy_progress_degrees_ranking_list + req = SaoGetQuestHierarchyProgressDegreesRankingListRequest(header, request) + return SaoGetQuestHierarchyProgressDegreesRankingListResponse(GameconnectCmd.GET_QUEST_HIERARCHY_PROGRESS_DEGREES_RANKING_LIST_RESPONSE).make() + + async def handle_cb04(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # quest_ranking/get_quest_popular_hero_log_ranking_list + req = SaoGetQuestPopularHeroLogRankingListRequest(header, request) + return SaoGetQuestPopularHeroLogRankingListResponse(GameconnectCmd.GET_QUEST_POPULAR_HERO_LOG_RANKING_LIST_RESPONSE).make() + + async def handle_cd00(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #defrag_match/get_defrag_match_basic_data - resp = SaoGetDefragMatchBasicDataResponse(header.cmd +1) + resp = SaoGetDefragMatchBasicDataResponse() + data = DefragMatchBasicUserData.from_args() return resp.make() - async def handle_cd02(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_cd02(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #defrag_match/get_defrag_match_ranking_user_data - resp = SaoGetDefragMatchRankingUserDataResponse(header.cmd +1) + # TODO: League points + req = SaoGetDefragMatchRankingUserDataRequest(header, request) + profile = await self.data.profile.get_profile(req.user_id) + resp = SaoGetDefragMatchRankingUserDataResponse(profile._asdict()) return resp.make() - async def handle_cd04(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_cd04(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #defrag_match/get_defrag_match_league_point_ranking_list - resp = SaoGetDefragMatchLeaguePointRankingListResponse(header.cmd +1) + resp = SaoGetDefragMatchLeaguePointRankingListResponse() return resp.make() - async def handle_cd06(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_cd06(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: #defrag_match/get_defrag_match_league_score_ranking_list - resp = SaoGetDefragMatchLeagueScoreRankingListResponse(header.cmd +1) + resp = SaoGetDefragMatchLeagueScoreRankingListResponse() return resp.make() - async def handle_d404(self, header: SaoRequestHeader, request: bytes) -> bytes: - #other/bnid_serial_code_check - resp = SaoBnidSerialCodeCheckResponse(header.cmd +1) - return resp.make() - - async def handle_c306(self, header: SaoRequestHeader, request: bytes) -> bytes: - #card/scan_qr_quest_profile_card - resp = SaoScanQrQuestProfileCardResponse(header.cmd +1) - return resp.make() - - async def handle_c700(self, header: SaoRequestHeader, request: bytes) -> bytes: - # shop/get_shop_resource_sales_data_list - # TODO: Get user shop data - req = GetShopResourceSalesDataListRequest(header, request) - resp = GetShopResourceSalesDataListResponse(header.cmd + 1) - return resp.make() - - async def handle_d100(self, header: SaoRequestHeader, request: bytes) -> bytes: - # shop/get_yui_medal_shop_user_data_list - # TODO: Get user shop data - req = GetYuiMedalShopUserDataListRequest(header, request) - resp = GetYuiMedalShopUserDataListResponse(header.cmd + 1) - return resp.make() - - async def handle_cf0e(self, header: SaoRequestHeader, request: bytes) -> bytes: + async def handle_cf0e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: # gasha/get_gasha_medal_shop_user_data_list # TODO: Get user shop data req = GetGashaMedalShopUserDataListRequest(header, request) - resp = GetGashaMedalShopUserDataListResponse(header.cmd + 1) + resp = GetGashaMedalShopUserDataListResponse(GameconnectCmd.GET_GASHA_MEDAL_SHOP_USER_DATA_LIST_RESPONSE) return resp.make() - - async def handle_d5da(self, header: SaoRequestHeader, request: bytes) -> bytes: + + async def handle_d000(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + req = SaoGenericUserRequest(header, request) + resp = SaoGetAdventureExecUserDataResponse() + return resp.make() + + async def handle_d100(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # shop/get_yui_medal_shop_user_data_list + # TODO: Get user shop data + req = GetYuiMedalShopUserDataListRequest(header, request) + resp = GetYuiMedalShopUserDataListResponse(GameconnectCmd.GET_YUI_MEDAL_SHOP_USER_DATA_LIST_RESPONSE) + return resp.make() + + async def handle_d200(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # mission/get_beginner_mission_user_data + req = SaoGetBeginnerMissionUserDataRequest(header, request) + resp = SaoGetBeginnerMissionUserDataResponse() + profile = await self.data.profile.get_profile(req.user_id) + if profile: + if profile['ad_confirm_date']: + resp.data[0].ad_confirm_date = profile['ad_confirm_date'] + resp.data[0].ad_confirm_flag = 1 + + return resp.make() + + async def handle_d202(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # mission/get_beginner_mission_progresses_user_data_list + req = SaoGetBeginnerMissionProgressesUserDataListRequest(header, request) + resp = SaoGetBeginnerMissionProgressesUserDataListResponse() + + return resp.make() + + async def handle_d204(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # mission/get_beginner_mission_seat_progresses_user_data_list + req = SaoGetBeginnerMissionSeatProgressesUserDataListRequest(header, request) + resp = SaoGetBeginnerMissionSeatProgressesUserDataListResponse() + + return resp.make() + + async def handle_d206(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # mission/beginner_mission_ad_confirm_notification + req = SaoBeginnerMissionAdConfirmNotificationRequest(header, request) + self.logger.info(f"User {req.user_id} confirmed ad for beginner mission {req.beginner_mission_id}") + await self.data.profile.update_beginner_mission_date(req.user_id) + + return SaoNoopResponse(GameconnectCmd.BEGINNER_MISSION_AD_CONFIRM_NOTIFICATION_RESPONSE).make() + + async def handle_d312(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # campaign/get_linked_site_reg_campaign_user_data + req = SaoGetLinkedSiteRegCampaignUserDataRequest(header, request) + resp = SaoGetLinkedSiteRegCampaignUserDataResponse() + + return resp.make() + + async def handle_d400(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # other/get_hero_log_unit_user_data_list + req = SaoGenericUserRequest(header, request) + resp = SaoGetHeroLogUnitUserDataListResponse() + + return resp.make() + + async def handle_d402(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # other/get_chara_unit_user_data_list + req = SaoGenericUserRequest(header, request) + resp = SaoGetCharaUnitUserDataListResponse() + + return resp.make() + + async def handle_d404(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # other/bnid_serial_code_check + req = SaoBnidSerialCodeCheckRequest() + resp = SaoBnidSerialCodeCheckResponse() + return resp.make() + + async def handle_d404(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # other/bnid_serial_code_entry_by_appendix_card + req = SaoBnidSerialCodeEntryByAppendixCardRequest() + resp = SaoBnidSerialCodeEntryByAppendixCardResponse() + return resp.make() + + async def handle_d500(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_player_ranks + tbl = self.load_data_csv('PlayerRank') + resp = SaoGetMPlayerRanksResponse(tbl) + return resp.make() + + async def handle_d502(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_titles + tbl = self.load_data_csv('Title') + resp = SaoGetMTitlesResponse(tbl) + return resp.make() + + async def handle_d504(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_fragments + tbl = self.load_data_csv('Fragment') + resp = SaoGetMFragmentsResponse(tbl) + return resp.make() + + async def handle_d506(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_reward_tables + tbl = self.load_data_csv('RewardTable') + resp = SaoGetMRewardTablesResponse(tbl) + return resp.make() + + async def handle_d508(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_reward_sets + tbl = self.load_data_csv('RewardSet') + resp = SaoGetMRewardSetsResponse(tbl) + return resp.make() + + async def handle_d50a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_unanalyzed_log_grades + tbl = self.load_data_csv('UnanalyzedLogGrade') + resp = SaoGetMUnanalyzedLogGradesResponse(tbl) + return resp.make() + + async def handle_d50c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_appoint_leader_params + tbl = self.load_data_csv('AppointLeaderParam') + resp = SaoGetMAppointLeaderParamsResponse(tbl) + return resp.make() + + async def handle_d50e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_appoint_leader_effects + tbl = self.load_data_csv('AppointLeaderEffect') + resp = SaoGetMAppointLeaderEffectsResponse(tbl) + return resp.make() + + async def handle_d510(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_appoint_leader_effect_types + tbl = self.load_data_csv('AppointLeaderEffectType') + resp = SaoGetMAppointLeaderEffectTypesResponse(tbl) + return resp.make() + + async def handle_d512(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_rarities + tbl = self.load_data_csv('Rarity') + resp = SaoGetMRaritiesResponse(tbl) + return resp.make() + + async def handle_d514(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_composition_events + tbl = self.load_data_csv('CompositionEvent') + resp = SaoGetMCompositionEventsResponse(tbl) + return resp.make() + + async def handle_d516(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_composition_params + tbl = self.load_data_csv('CompositionParam') + resp = SaoGetMCompositionParamsResponse(tbl) + return resp.make() + + async def handle_d518(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_game_play_prices + tbl = self.load_data_csv('GamePlayPrice') + resp = SaoGetMGamePlayPricesResponse(tbl) + return resp.make() + + async def handle_d51a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_buy_tickets + tbl = self.load_data_csv('BuyTicket') + resp = SaoGetMBuyTicketsResponse(tbl) + return resp.make() + + async def handle_d51c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_tips + tbl = self.load_data_csv('Tips') + resp = SaoGetMTipsResponse(tbl) + return resp.make() + + async def handle_d51e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_caps + tbl = self.load_data_csv('Cap') + resp = SaoGetMCapsResponse(tbl) + return resp.make() + + async def handle_d520(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_hero_log + tbl = self.load_data_csv('HeroLog') + resp = SaoGetMHeroLogResponse(tbl) + return resp.make() + + async def handle_d522(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_hero_log_levels + tbl = self.load_data_csv('HeroLogLevel') + resp = SaoGetMHeroLogLevelsResponse(tbl) + return resp.make() + + async def handle_d524(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_hero_log_roles + tbl = self.load_data_csv('HeroLogRole') + resp = SaoGetMHeroLogRolesResponse(tbl) + return resp.make() + + async def handle_d526(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_hero_log_trust_ranks + tbl = self.load_data_csv('HeroLogTrustRank') + resp = SaoGetMHeroLogTrustRanksResponse(tbl) + return resp.make() + + async def handle_d528(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_charas + tbl = self.load_data_csv('Chara') + resp = SaoGetMCharasResponse(tbl) + return resp.make() + + async def handle_d52a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_chara_friendly_ranks + tbl = self.load_data_csv('CharaFriendlyRank') + resp = SaoGetMCharaFriendlyRanksResponse(tbl) + return resp.make() + + async def handle_d52c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_equipments + tbl = self.load_data_csv('Equipment') + resp = SaoGetMEquipmentsResponse(tbl) + return resp.make() + + async def handle_d52e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_equipment_levels + tbl = self.load_data_csv('EquipmentLevel') + resp = SaoGetMEquipmentLevelsResponse(tbl) + return resp.make() + + async def handle_d530(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_weapon_types + tbl = self.load_data_csv('WeaponType') + resp = SaoGetMWeaponTypesResponse(tbl) + return resp.make() + + async def handle_d532(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_items + tbl = self.load_data_csv('Item') + resp = SaoGetMItemsResponse(tbl) + return resp.make() + + async def handle_d534(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_item_types + tbl = self.load_data_csv('ItemType') + resp = SaoGetMItemTypesResponse(tbl) + return resp.make() + + async def handle_d536(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_buff_items + tbl = self.load_data_csv('BuffItem') + resp = SaoGetMBuffItemsResponse(tbl) + return resp.make() + + async def handle_d538(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_enemies + tbl = self.load_data_csv('Enemy') + resp = SaoGetMEnemiesResponse(tbl) + return resp.make() + + async def handle_d53a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_enemy_sets + tbl = self.load_data_csv('EnemySet') + resp = SaoGetMEnemySetsResponse(tbl) + return resp.make() + + async def handle_d53c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_enemy_kinds + tbl = self.load_data_csv('EnemyKind') + resp = SaoGetMEnemyKindsResponse(tbl) + return resp.make() + + async def handle_d53e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_enemy_categories + tbl = self.load_data_csv('EnemyCategory') + resp = SaoGetMEnemyCategoriesResponse(tbl) + return resp.make() + + async def handle_d540(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_units + tbl = self.load_data_csv('Unit') + resp = SaoGetMUnitsResponse(tbl) + return resp.make() + + async def handle_d542(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_unit_gimmicks + tbl = self.load_data_csv('UnitGimmick') + resp = SaoGetMUnitGimmicksResponse(tbl) + return resp.make() + + async def handle_d544(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_unit_collisions + tbl = self.load_data_csv('UnitCollision') + resp = SaoGetMUnitCollisionsResponse(tbl) + return resp.make() + + async def handle_d546(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_unit_powers + tbl = self.load_data_csv('UnitPower') + resp = SaoGetMUnitPowersResponse(tbl) + return resp.make() + + async def handle_d548(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_gimmick_attacks + tbl = self.load_data_csv('GimmickAttack') + resp = SaoGetMGimmickAttacksResponse(tbl) + return resp.make() + + async def handle_d54a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_chara_attacks + tbl = self.load_data_csv('CharaAttack') + resp = SaoGetMCharaAttacksResponse(tbl) + return resp.make() + + async def handle_d54c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_boss_attacks + tbl = self.load_data_csv('BossAttack') + resp = SaoGetMBossAttacksResponse(tbl) + return resp.make() + + async def handle_d54e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_monster_attacks + tbl = self.load_data_csv('MonsterAttack') + resp = SaoGetMMonsterAttacksResponse(tbl) + return resp.make() + + async def handle_d550(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_monster_actions + tbl = self.load_data_csv('MonsterAction') + resp = SaoGetMMonsterActionsResponse(tbl) + return resp.make() + + async def handle_d552(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_properties + tbl = self.load_data_csv('Property') + resp = SaoGetMPropertiesResponse(tbl) + return resp.make() + + async def handle_d554(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_property_tables + tbl = self.load_data_csv('PropertyTable') + resp = SaoGetMPropertyTablesResponse(tbl) + return resp.make() + + async def handle_d556(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_property_types + tbl = self.load_data_csv('PropertyType') + resp = SaoGetMPropertyTypesResponse(tbl) + return resp.make() + + async def handle_d558(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_skills + tbl = self.load_data_csv('Skill') + resp = SaoGetMSkillsResponse(tbl) + return resp.make() + + async def handle_d55a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_skill_tables + tbl = self.load_data_csv('SkillTable') + resp = SaoGetMSkillTablesResponse(tbl) + return resp.make() + + async def handle_d55c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_skill_levels + tbl = self.load_data_csv('SkillLevel') + resp = SaoGetMSkillLevelsResponse(tbl) + return resp.make() + + async def handle_d55e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_awakenings + tbl = self.load_data_csv('Awakening') + resp = SaoGetMAwakeningsResponse(tbl) + return resp.make() + + async def handle_d560(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_synchro_skills + tbl = self.load_data_csv('SynchroSkill') + resp = SaoGetMSynchroSkillsResponse(tbl) + return resp.make() + + async def handle_d562(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_sound_skill_cut_in_voices + tbl = self.load_data_csv('Sound_SkillCutInVoice') + resp = SaoGetMSoundSkillCutInVoicesResponse(tbl) + return resp.make() + + async def handle_d564(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_scenes + tbl = self.load_data_csv('QuestScene') + resp = SaoGetMQuestScenesResponse(tbl) + return resp.make() + + async def handle_d566(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_exist_units + tbl = self.load_data_csv('QuestExistUnit') + resp = SaoGetMQuestExistUnitsResponse(tbl) + return resp.make() + + async def handle_d568(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_episode_append_rewards + tbl = self.load_data_csv('QuestEpisodeAppendRewards') + resp = SaoGetMQuestEpisodeAppendRewardsResponse(tbl) + return resp.make() + + async def handle_d56a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_side_quests + tbl = self.load_data_csv('SideQuest') + resp = SaoGetMSideQuestsResponse(tbl) + return resp.make() + + async def handle_d56c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_episodes + tbl = self.load_data_csv('Episode') + resp = SaoGetMEpisodesResponse(tbl) + return resp.make() + + async def handle_d56e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_episode_chapters + tbl = self.load_data_csv('EpisodeChapter') + resp = SaoGetMEpisodeChaptersResponse(tbl) + return resp.make() + + async def handle_d570(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_episode_parts + tbl = self.load_data_csv('EpisodePart') + resp = SaoGetMEpisodePartsResponse(tbl) + return resp.make() + + async def handle_d572(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_trial_towers + tbl = self.load_data_csv('TrialTower') + resp = SaoGetMTrialTowersResponse(tbl) + return resp.make() + + async def handle_d574(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_ex_towers + req = SaoGetMExTowersRequest(header, request) + tbl = self.load_data_csv('ExTowers') + resp = SaoGetMExTowersResponse(tbl) + return resp.make() + + async def handle_d576(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_ex_tower_quests + req = SaoGetMExTowerQuestsRequest(header, request) + tbl = self.load_data_csv('ExTowerQuests') + resp = SaoGetMExTowerQuestsResponse(tbl) + return resp.make() + + async def handle_d578(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_menu_display_enemies + tbl = self.load_data_csv('MenuDisplayEnemy') + resp = SaoGetMMenuDisplayEnemiesResponse(tbl) + return resp.make() + + async def handle_d57a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_missions + tbl = self.load_data_csv('Mission') + resp = SaoGetMMissionsResponse(tbl) + return resp.make() + + async def handle_d57c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_mission_tables + tbl = self.load_data_csv('MissionTable') + resp = SaoGetMMissionTablesResponse(tbl) + return resp.make() + + async def handle_d57e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_mission_difficulties + tbl = self.load_data_csv('MissionDifficulty') + resp = SaoGetMMissionDifficultiesResponse(tbl) + return resp.make() + + async def handle_d580(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_battle_cameras + tbl = self.load_data_csv('BattleCamera') + resp = SaoGetMBattleCamerasResponse(tbl) + return resp.make() + + async def handle_d582(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_chat_main_stories + tbl = self.load_data_csv('ChatMainStory') + resp = SaoGetMChatMainStoriesResponse(tbl) + return resp.make() + + async def handle_d584(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_chat_side_stories + tbl = self.load_data_csv('ChatSideStory') + resp = SaoGetMChatSideStoriesResponse(tbl) + return resp.make() + + async def handle_d586(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_chat_event_stories + req = SaoGetMChatEventStoriesRequest(header, request) + tbl = self.load_data_csv('ChatEventStory') + resp = SaoGetMChatEventStoriesResponse(tbl) + return resp.make() + + async def handle_d588(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_navigator_charas + tbl = self.load_data_csv('NavigatorChara') + resp = SaoGetMNavigatorCharasResponse(tbl) + return resp.make() + + async def handle_d58a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_navigator_comments + tbl = self.load_data_csv('NavigatorComment') + resp = SaoGetMNavigatorCommentsResponse(tbl) + return resp.make() + + async def handle_d58c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_ex_bonus_tables + tbl = self.load_data_csv('ExBonusTable') + resp = SaoGetMExBonusTablesResponse(tbl) + return resp.make() + + async def handle_d58e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_ex_bonus_conditions + tbl = self.load_data_csv('ExBonusCondition') + resp = SaoGetMExBonusConditionsResponse(tbl) + return resp.make() + + async def handle_d590(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_rare_drops + tbl = self.load_data_csv('QuestRareDrop') + resp = SaoGetMQuestRareDropsResponse(tbl) + return resp.make() + + async def handle_d592(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_special_rare_drop_settings + tbl = self.load_data_csv('QuestSpecialRareDropSettings') + resp = SaoGetMQuestSpecialRareDropSettingsResponse(tbl) + return resp.make() + + async def handle_d594(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_special_rare_drops + tbl = self.load_data_csv('QuestSpecialRareDrops') + resp = SaoGetMQuestSpecialRareDropsResponse(tbl) + return resp.make() + + async def handle_d596(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_tutorials + tbl = self.load_data_csv('QuestTutorial') + resp = SaoGetMQuestTutorialsResponse(tbl) + return resp.make() + + async def handle_d598(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_player_trace_tables + tbl = self.load_data_csv('PlayerTraceTable') + resp = SaoGetMQuestPlayerTraceTablesResponse(tbl) + return resp.make() + + async def handle_d59a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_stills + tbl = self.load_data_csv('QuestStill') + resp = SaoGetMQuestStillsResponse(tbl) + return resp.make() + + async def handle_d59c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_gashas + tbl = self.load_data_csv('Gasha') + resp = SaoGetMGashasResponse(tbl) + return resp.make() + + async def handle_d59e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_gasha_headers + tbl = self.load_data_csv('GashaHeader') + resp = SaoGetMGashaHeadersResponse(tbl) + return resp.make() + + async def handle_d5a0(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_gasha_lottery_rarities + tbl = self.load_data_csv('GashaLotteryRarity') + resp = SaoGetMGashaLotteryRaritiesResponse(tbl) + return resp.make() + + async def handle_d5a2(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_gasha_prizes + tbl = self.load_data_csv('GashaPrize') + resp = SaoGetMGashaPrizesResponse(tbl) + return resp.make() + + async def handle_d5a4(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_comeback_events + tbl = self.load_data_csv('ComebackEvent') + resp = SaoGetMComebackEventsResponse(tbl) + return resp.make() + + async def handle_d5a6(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_ad_banners + tbl = self.load_data_csv('AdBanners') + resp = SaoGetMAdBannersResponse(tbl) + return resp.make() + + async def handle_d5a8(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_events + tbl = self.load_data_csv('Event') + resp = SaoGetMEventsResponse(tbl) + return resp.make() + + async def handle_d5aa(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_treasure_hunts + req = SaoGetMTreasureHuntsRequest(header, request) + tbl = self.load_data_csv('TreasureHunt') + resp = SaoGetMTreasureHuntsResponse(tbl) + return resp.make() + + async def handle_d5ac(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_treasure_hunt_whole_tasks + req = SaoGetMTreasureHuntWholeTasksRequest(header, request) + tbl = self.load_data_csv('TreasureHuntWholeTask') + resp = SaoGetMTreasureHuntWholeTasksResponse(tbl) + return resp.make() + + async def handle_d5ae(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_treasure_hunt_individual_tasks + req = SaoGetMTreasureHuntIndividualTasksRequest(header, request) + tbl = self.load_data_csv('TreasureHuntIndividualTask') + resp = SaoGetMTreasureHuntIndividualTasksResponse(tbl) + return resp.make() + + async def handle_d5b0(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_treasure_hunt_special_effects + req = SaoGetMTreasureHuntSpecialEffectsRequest(header, request) + tbl = self.load_data_csv('TreasureHuntSpecialEffect') + resp = SaoGetMTreasureHuntSpecialEffectsResponse(tbl) + return resp.make() + + async def handle_d5b2(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_treasure_hunt_event_point_reward_common_rewards + req = SaoGetMTreasureHuntEventPointRewardCommonRewardsRequest(header, request) + tbl = self.load_data_csv('TreasureHuntEventPointRewardCommonReward') + resp = SaoGetMTreasureHuntEventPointRewardCommonRewardsResponse(tbl) + return resp.make() + + async def handle_d5b4(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_treasure_hunt_event_point_reward_titles + req = SaoGetMTreasureHuntEventPointRewardTitlesRequest(header, request) + tbl = self.load_data_csv('TreasureHuntEventPointRewardTitle') + resp = SaoGetMTreasureHuntEventPointRewardTitlesResponse(tbl) + return resp.make() + + async def handle_d5b6(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_treasure_hunt_task_texts + tbl = self.load_data_csv('TreasureHuntTaskText') + resp = SaoGetMTreasureHuntTaskTextsResponse(tbl) + return resp.make() + + async def handle_d5b8(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_bnid_serial_codes + tbl = self.load_data_csv('BnidSerialCodes') + resp = SaoGetMBnidSerialCodesResponse(tbl) + return resp.make() + + async def handle_d5ba(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_bnid_serial_code_rewards + tbl = self.load_data_csv('BnidSerialCodeRewards') + resp = SaoGetMBnidSerialCodeRewardsResponse(tbl) + return resp.make() + + async def handle_d5bc(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_support_log + tbl = self.load_data_csv('SupportLog') + resp = SaoGetMSupportLogResponse(tbl) + return resp.make() + + async def handle_d5be(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_support_log_types + tbl = self.load_data_csv('SupportLogType') + resp = SaoGetMSupportLogTypesResponse(tbl) + return resp.make() + + async def handle_d5c0(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_episode_appends + tbl = self.load_data_csv('EpisodeAppends') + resp = SaoGetMEpisodeAppendsResponse(tbl) + return resp.make() + + async def handle_d5c2(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_defrag_match_quests + tbl = self.load_data_csv('DefragMatchQuest') + resp = SaoGetMQuestDefragMatchQuestsResponse(tbl) + return resp.make() + + async def handle_d5c4(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_quest_defrag_match_quest_boss_tables + tbl = self.load_data_csv('DefragMatchBossTable') + resp = SaoGetMQuestDefragMatchQuestBossTablesResponse(tbl) + return resp.make() + + async def handle_d5c6(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_defrag_matches + req = SaoGetMDefragMatchesRequest(header, request) + tbl = self.load_data_csv('DefragMatchs') + resp = SaoGetMDefragMatchesResponse(tbl) + return resp.make() + + async def handle_d5c8(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_defrag_match_seed + req = SaoGetMDefragMatchSeedRequest(header, request) + tbl = self.load_data_csv('DefragMatchSeed') + resp = SaoGetMDefragMatchSeedResponse(tbl) + return resp.make() + + async def handle_d5ca(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_defrag_match_special_effects + req = SaoGetMDefragMatchSpecialEffectsRequest(header, request) + tbl = self.load_data_csv('DefragMatchSpecialEffects') + resp = SaoGetMDefragMatchSpecialEffectsResponse(tbl) + return resp.make() + + async def handle_d5cc(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_defrag_match_grades + req = SaoGetMDefragMatchGradesRequest(header, request) + tbl = self.load_data_csv('DefragMatchGrade') + resp = SaoGetMDefragMatchGradesResponse(tbl) + return resp.make() + + async def handle_d5ce(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_defrag_match_cpu_units + tbl = self.load_data_csv('DefragMatchCpuUnits') + resp = SaoGetMDefragMatchCpuUnitsResponse(tbl) + return resp.make() + + async def handle_d5d0(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_defrag_match_cpu_support_logs + tbl = self.load_data_csv('DefragMatchCpuSupportLogs') + resp = SaoGetMDefragMatchCpuSupportLogsResponse(tbl) + return resp.make() + + async def handle_d5d2(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_defrag_match_period_bonuses + req = SaoGetMDefragMatchPeriodBonusesRequest(header, request) + tbl = self.load_data_csv('DefragMatchPeriodBonuses') + resp = SaoGetMDefragMatchPeriodBonusesResponse(tbl) + return resp.make() + + async def handle_d5d4(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_defrag_match_random_bonus_tables + req = SaoGetMDefragMatchRandomBonusTablesRequest(header, request) + tbl = self.load_data_csv('DefragMatchRandomBonusTables') + resp = SaoGetMDefragMatchRandomBonusTablesResponse(tbl) + return resp.make() + + async def handle_d5d6(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_defrag_match_random_bonus_conditions + tbl = self.load_data_csv('DefragMatchRandomBonusConditions') + resp = SaoGetMDefragMatchRandomBonusConditionsResponse(tbl) + return resp.make() + + async def handle_d5d8(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_defrag_match_rare_drops + req = SaoGetMDefragMatchRareDropsRequest(header, request) + tbl = self.load_data_csv('DefragMatchRareDrops') + resp = SaoGetMDefragMatchRareDropsResponse(tbl) + return resp.make() + + async def handle_d5da(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: # master_data/get_m_yui_medal_shops - req = GetMYuiMedalShopDataRequest(header, request) - resp = GetMYuiMedalShopDataResponse(header.cmd + 1) - - shops = self.load_data_csv("YuiMedalShops") - for shop in shops: - tmp = YuiMedalShopData.from_args(int(shop['YuiMedalShopId']), shop['Name'], shop['Description']) - tmp.selling_yui_medal = int(shop['SellingYuiMedal']) - tmp.selling_col = int(shop['SellingCol']) - tmp.selling_event_item_id = int(shop['SellingEventItemId']) - tmp.selling_event_item_num = int(shop['SellingEventItemNum']) - tmp.selling_ticket_num = int(shop['SellingTicketNum']) - tmp.purchase_limit = int(shop['PurchaseLimit']) - tmp.pick_up_flag = 1 if shop['PickUpFlag'] == "True" else 0 - tmp.product_category = int(shop['ProductCategory']) - tmp.sales_type = int(shop['SalesType']) - tmp.target_days = int(shop['TargetDays']) - tmp.target_hour = int(shop['TargetHour']) - tmp.interval_hour = int(shop['IntervalHour']) - tmp.sort = int(shop['Sort']) - - tmp.sales_end_date = datetime(2121, 1, 1, 0, 0, 0, 0) # always open - - resp.data_list.append(tmp) - self.logger.debug(f"Load {len(resp.data_list)} Yui Medal Shops") + tbl = self.load_data_csv('YuiMedalShops') + resp = SaoGetMYuiMedalShopsResponse(tbl) return resp.make() - - async def handle_d5dc(self, header: SaoRequestHeader, request: bytes) -> bytes: + + async def handle_d5dc(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: # master_data/get_m_yui_medal_shop_items - req = GetMYuiMedalShopItemsRequest(header, request) - resp = GetMYuiMedalShopItemsResponse(header.cmd + 1) - - shops = self.load_data_csv("YuiMedalShopItems") - for shop in shops: - tmp = YuiMedalShopItemData.from_args(int(shop['YuiMedalShopItemId']), int(shop['YuiMedalShopId']), int(shop['CommonRewardType']), int(shop['CommonRewardId']), int(shop['CommonRewardNum']), int(shop['Strength'])) - - tmp.property1_property_id = int(shop['Property1PropertyId']) - tmp.property1_value1 = int(shop['Property1Value1']) - tmp.property1_value2 = int(shop['Property1Value2']) - - tmp.property2_property_id = int(shop['Property2PropertyId']) - tmp.property2_value1 = int(shop['Property2Value1']) - tmp.property2_value2 = int(shop['Property2Value2']) - - tmp.property3_property_id = int(shop['Property3PropertyId']) - tmp.property3_value1 = int(shop['Property3Value1']) - tmp.property3_value2 = int(shop['Property3Value2']) - - tmp.property4_property_id = int(shop['Property4PropertyId']) - tmp.property4_value1 = int(shop['Property4Value1']) - tmp.property4_value2 = int(shop['Property4Value2']) - - resp.data_list.append(tmp) - - self.logger.debug(f"Load {len(resp.data_list)} Yui Medal Shop Items") + tbl = self.load_data_csv('YuiMedalShopItems') + resp = SaoGetMYuiMedalShopItemsResponse(tbl) return resp.make() - - async def handle_d5fc(self, header: SaoRequestHeader, request: bytes) -> bytes: + + async def handle_d5de(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_event_scenes + req = SaoGetMEventScenesRequest(header, request) + tbl = self.load_data_csv('EventScenes') + resp = SaoGetMEventScenesResponse(tbl) + return resp.make() + + async def handle_d5e0(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_generic_campaign_periods + tbl = self.load_data_csv('GenericCampaignPeriods') + resp = SaoGetMGenericCampaignPeriodsResponse(tbl) + return resp.make() + + async def handle_d5e2(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_beginner_missions + tbl = self.load_data_csv('BeginnerMissions') + resp = SaoGetMBeginnerMissionsResponse(tbl) + return resp.make() + + async def handle_d5e4(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_beginner_mission_conditions + req = SaoGetMBeginnerMissionConditionsRequest(header, request) + tbl = self.load_data_csv('BeginnerMissionConditions') + resp = SaoGetMBeginnerMissionConditionsResponse(tbl) + return resp.make() + + async def handle_d5e6(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_beginner_mission_rewards + req = SaoGetMBeginnerMissionRewardsRequest(header, request) + tbl = self.load_data_csv('BeginnerMissionRewards') + resp = SaoGetMBeginnerMissionRewardsResponse(tbl) + return resp.make() + + async def handle_d5e8(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_beginner_mission_seat_conditions + req = SaoGetMBeginnerMissionSeatConditionsRequest(header, request) + tbl = self.load_data_csv('BeginnerMissionSeatConditions') + resp = SaoGetMBeginnerMissionSeatConditionsResponse(tbl) + return resp.make() + + async def handle_d5ea(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_beginner_mission_seat_rewards + req = SaoGetMBeginnerMissionSeatRewardsRequest(header, request) + tbl = self.load_data_csv('BeginnerMissionSeatRewards') + resp = SaoGetMBeginnerMissionSeatRewardsResponse(tbl) + return resp.make() + + async def handle_d5ec(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_event_items + tbl = self.load_data_csv('EventItems') + resp = SaoGetMEventItemsResponse(tbl) + return resp.make() + + async def handle_d5ee(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_event_monsters + req = SaoGetMEventMonstersRequest(header, request) + tbl = self.load_data_csv('EventMonsters') + resp = SaoGetMEventMonstersResponse(tbl) + return resp.make() + + async def handle_d5f0(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_yui_medal_bonuses + tbl = self.load_data_csv('YuiMedalBonus') + resp = SaoGetMYuiMedalBonusesResponse(tbl) + return resp.make() + + async def handle_d5f2(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_yui_medal_bonus_conditions + tbl = self.load_data_csv('YuiMedalBonusCondition') + resp = SaoGetMYuiMedalBonusConditionsResponse(tbl) + return resp.make() + + async def handle_d5f4(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_gasha_medals + tbl = self.load_data_csv('GashaMedals') + resp = SaoGetMGashaMedalsResponse(tbl) + return resp.make() + + async def handle_d5f6(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_gasha_medal_types + tbl = self.load_data_csv('GashaMedalTypes') + resp = SaoGetMGashaMedalTypesResponse(tbl) + return resp.make() + + async def handle_d5f8(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_gasha_medal_settings + req = SaoGetMGashaMedalSettingsRequest(header, request) + tbl = self.load_data_csv('GashaMedalSettings') + resp = SaoGetMGashaMedalSettingsResponse(tbl) + return resp.make() + + async def handle_d5fa(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_gasha_medal_bonuses + tbl = self.load_data_csv('GashaMedalBonuses') + resp = SaoGetMGashaMedalBonusesResponse(tbl) + return resp.make() + + async def handle_d5fc(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: # master_data/get_m_gasha_medal_shops - req = GetMGashaMedalShopsRequest(header, request) - resp = GetMGashaMedalShopsResponse(header.cmd + 1) - - shops = self.load_data_csv("GashaMedalShops") - for shop in shops: - tmp = GashaMedalShop.from_args(int(shop['GashaMedalShopId']), shop['Name'], int(shop['GashaMedalId']), int(shop['UseGashaMedalNum']), int(shop['PurchaseLimit'])) - tmp.sales_end_date = datetime(2121, 1, 1, 0, 0, 0, 0) # always open - - resp.data_list.append(tmp) - - self.logger.debug(f"Load {len(resp.data_list)} Gasha Medal Shops") + tbl = self.load_data_csv('GashaMedalShops') + resp = SaoGetMGashaMedalShopsResponse(tbl) return resp.make() - - async def handle_d5fe(self, header: SaoRequestHeader, request: bytes) -> bytes: - # master_data/get_m_gasha_medal_shop_items - return SaoNoopResponse(header.cmd + 1).make() - - async def handle_d604(self, header: SaoRequestHeader, request: bytes) -> bytes: - # master_data_2/get_m_res_earn_campaign_shops - req = GetMResEarnCampaignShopsRequest(header, request) - resp = GetMResEarnCampaignShopsResponse(header.cmd + 1) - - shops = self.load_data_csv("ResEarnCampaignShops") - for shop in shops: - tmp = ResEarnCampaignShop.from_args(int(shop['ResEarnCampaignShopId']), int(shop['ResEarnCampaignApplicationId']), shop['Name']) - tmp.selling_yui_medal = int(shop['SellingYuiMedal']) - tmp.selling_col = int(shop['SellingCol']) - tmp.selling_event_item_id = int(shop['SellingEventItemId']) - tmp.selling_event_item_num = int(shop['SellingEventItemNum']) - tmp.purchase_limit = int(shop['PurchaseLimit']) - tmp.get_application_point = int(shop['GetApplicationPoint']) - - tmp.sales_end_date = datetime(2121, 1, 1, 0, 0, 0, 0) # always open - - resp.data_list.append(tmp) - #self.logger.debug(f"Load {len(resp.data_list)} Res Earn Campaign Shops") - return SaoNoopResponse(header.cmd + 1).make() - - async def handle_d606(self, header: SaoRequestHeader, request: bytes) -> bytes: - # master_data_2/get_m_res_earn_campaign_shop_items - return SaoNoopResponse(header.cmd + 1).make() - - async def handle_c108(self, header: SaoRequestHeader, request: bytes) -> bytes: - # common/logout_ticket_unpurchased - req = SaoLogoutTicketUnpurchasedRequest(header, request) - return SaoLogoutTicketUnpurchasedResponse(header.cmd + 1).make() - - async def handle_cb02(self, header: SaoRequestHeader, request: bytes) -> bytes: - # quest_ranking/get_quest_hierarchy_progress_degrees_ranking_list - req = SaoGetQuestHierarchyProgressDegreesRankingListRequest(header, request) - return SaoGetQuestHierarchyProgressDegreesRankingListResponse(header.cmd + 1).make() - - async def handle_cb04(self, header: SaoRequestHeader, request: bytes) -> bytes: - # quest_ranking/get_quest_popular_hero_log_ranking_list - req = SaoGetQuestPopularHeroLogRankingListRequest(header, request) - return SaoGetQuestPopularHeroLogRankingListResponse(header.cmd + 1).make() + async def handle_d5fe(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data/get_m_gasha_medal_shop_items + req = SaoGetMGashaMedalShopItemsRequest(header, request) + tbl = self.load_data_csv('GashaMedalShopItems') + resp = SaoGetMGashaMedalShopItemsResponse(tbl) + return resp.make() + + async def handle_d600(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mres_earn_campaign_applications + tbl = self.load_data_csv('ResEarnCampaignApplications') + resp = SaoGetMResEarnCampaignApplicationsResponse(tbl) + return resp.make() + + async def handle_d602(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mres_earn_campaign_application_products + req = SaoGetMResEarnCampaignApplicationProductsRequest(header, request) + tbl = self.load_data_csv('ResEarnCampaignApplicationProducts') + resp = SaoGetMResEarnCampaignApplicationProductsResponse(tbl) + return resp.make() + + async def handle_d604(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mres_earn_campaign_shops + tbl = self.load_data_csv('ResEarnCampaignShops') + resp = SaoGetMResEarnCampaignShopsResponse(tbl) + return resp.make() + + async def handle_d606(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mres_earn_campaign_shop_items + req = SaoGetMResEarnCampaignShopItemsRequest(header, request) + tbl = self.load_data_csv('ResEarnCampaignShopItems') + resp = SaoGetMResEarnCampaignShopItemsResponse(tbl) + return resp.make() + + async def handle_d608(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mpaying_yui_medal_bonuses + tbl = self.load_data_csv('PayingYuiMedalBonuses') + resp = SaoGetMPayingYuiMedalBonusesResponse(tbl) + return resp.make() + + async def handle_d60a(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mac_login_bonuses + tbl = self.load_data_csv('AcLoginBonuses') + resp = SaoGetMAcLoginBonusesResponse(tbl) + return resp.make() + + async def handle_d60c(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mplay_campaigns + tbl = self.load_data_csv('PlayCampaigns') + resp = SaoGetMPlayCampaignsResponse(tbl) + return resp.make() + + async def handle_d60e(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mplay_campaign_rewards + req = SaoGetMPlayCampaignRewardsRequest(header, request) + tbl = self.load_data_csv('PlayCampaignRewards') + resp = SaoGetMPlayCampaignRewardsResponse(tbl) + return resp.make() + + async def handle_d610(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mgasha_free_campaigns + tbl = self.load_data_csv('GashaFreeCampaigns') + resp = SaoGetMGashaFreeCampaignsResponse(tbl) + return resp.make() + + async def handle_d612(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mquest_drop_boost_campaigns + tbl = self.load_data_csv('QuestDropBoostCampaigns') + resp = SaoGetMQuestDropBoostCampaignsResponse(tbl) + return resp.make() + + async def handle_d614(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mfirst_ticket_purchase_campaigns + tbl = self.load_data_csv('FirstTicketPurchaseCampaigns') + resp = SaoGetMFirstTicketPurchaseCampaignsResponse(tbl) + return resp.make() + + async def handle_d616(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mlinked_site_reg_campaigns + tbl = self.load_data_csv('LinkedSiteRegCampaigns') + resp = SaoGetMLinkedSiteRegCampaignsResponse(tbl) + return resp.make() + + async def handle_d618(self, header: SaoRequestHeader, request: bytes, src_ip: str) -> bytes: + # master_data2/get_mlinked_site_reg_campaign_rewards + req = SaoGetMLinkedSiteRegCampaignRewardsRequest(header, request) + tbl = self.load_data_csv('LinkedSiteRegCampaignRewards') + resp = SaoGetMLinkedSiteRegCampaignRewardsResponse(tbl) + return resp.make() diff --git a/titles/sao/config.py b/titles/sao/config.py index dfae3c0..892fdca 100644 --- a/titles/sao/config.py +++ b/titles/sao/config.py @@ -30,9 +30,21 @@ class SaoServerConfig: ) @property - def use_https(self) -> bool: + def photon_app_id(self) -> str: return CoreConfig.get_config_field( - self.__config, "sao", "server", "use_https", default=False + self.__config, "sao", "server", "photon_app_id", default="7df3a2f6-d69d-4073-aafe-810ee61e1cea" + ) + + @property + def data_version(self) -> int: + return CoreConfig.get_config_field( + self.__config, "sao", "server", "data_version", default=1 + ) + + @property + def game_version(self) -> int: + return CoreConfig.get_config_field( + self.__config, "sao", "server", "game_version", default=33 ) class SaoCryptConfig: @@ -50,12 +62,6 @@ class SaoCryptConfig: return CoreConfig.get_config_field( self.__config, "sao", "crypt", "key", default="" ) - - @property - def iv(self) -> str: - return CoreConfig.get_config_field( - self.__config, "sao", "crypt", "iv", default="" - ) class SaoHashConfig: def __init__(self, parent_config: "SaoConfig"): @@ -73,9 +79,31 @@ class SaoHashConfig: self.__config, "sao", "hash", "hash_base", default="" ) +class SaoCardConfig: + def __init__(self, parent_config: "SaoConfig"): + self.__config = parent_config + + @property + def enable(self) -> bool: + return CoreConfig.get_config_field( + self.__config, "sao", "card", "enable", default=True + ) + + @property + def crypt_password(self) -> str: + return CoreConfig.get_config_field( + self.__config, "sao", "card", "crypt_password", default="" + ) + + @property + def crypt_salt(self) -> str: + return CoreConfig.get_config_field( + self.__config, "sao", "card", "crypt_salt", default="" + ) class SaoConfig(dict): def __init__(self) -> None: self.server = SaoServerConfig(self) self.crypt = SaoCryptConfig(self) self.hash = SaoHashConfig(self) + self.card = SaoCardConfig(self) diff --git a/titles/sao/const.py b/titles/sao/const.py index d181556..d687c64 100644 --- a/titles/sao/const.py +++ b/titles/sao/const.py @@ -1,5 +1,4 @@ -from enum import Enum - +from enum import IntEnum class SaoConstants: GAME_CODE = "SDEW" @@ -9,8 +8,8 @@ class SaoConstants: VER_SAO = 0 - VERSION_NAMES = ("Sword Art Online Arcade") - + VERSION_NAMES = ("Sword Art Online Arcade",) + SERIAL_IDENT_SATALITE = 4 SERIAL_IDENT_TERMINAL = 5 @@ -23,3 +22,653 @@ class SaoConstants: @classmethod def game_ver_to_string(cls, ver: int): return cls.VERSION_NAMES[ver] + +class RewardType(IntEnum): + None_ = 0 + HeroLog = 1 + Equipment = 2 + Item = 3 + Col = 4 + VP = 5 + YuiMadal = 6 + VPGashaTicket = 7 + SupportLog = 8 + EpisodeAppend = 9 + EventItem = 10 + Ticket = 11 + +class ItemType(IntEnum): + ADD_HERO_PROPERTY = 1 + ADD_WEAPON_PROPERTY = 2 + ADD_ARMOR_PROPERTY = 3 + UNLOCK_PROPERTY = 4 + REMOVE_PROPERTY = 5 + ADD_SKILL_SLOT = 6 + ADD_XP = 7 + REDEMPTION = 8 + HERO_LEVEL_LIMIT_BREAK = 9 + WEAPON_LEVEL_LIMIT_BREAK = 10 + ARMOR_LEVEL_LIMIT_BREAK = 11 + ADD_AWAKENING_XP = 12 + +class ExBonusCondition(IntEnum): + CLEAR_UNDER_X_SECS = 1 + DEFEAT_X_MONSTER_Y_TIMES = 2 + DEFEAT_X_MONSTERS = 3 + CLEAR_X_MISSIONS = 4 + CLEAR_MISSION_DIFFICULTY_X = 5 + COLLECT_X_LOGS = 6 + CLEAR_SKILL_LEVEL_X = 7 + NO_LOSSES = 8 + ACCEL_X_TIMES = 9 + MAX_COMBO_X = 10 + MULTIPLAYER_CLEAR_X = 11 + +class UnanalyzedLogGrade(IntEnum): + WHITE = 1 + COPPER = 2 + SILVER = 3 + GOLD = 4 + RAINBOW = 5 + +class QuestType(IntEnum): + EPISODE = 1 + TRIAL_TOWER = 2 + SIDE = 3 + VERSUS = 4 + EX_TOWER = 5 + EPISODE_CHAPTER = 6 # Unused + +class GameconnectCmd(IntEnum): + TICKET_REQUEST = 0xC000 + TICKET_RESPONSE = 0xC001 + GET_APP_VERSIONS_REQUEST = 0xC100 + GET_APP_VERSIONS_RESPONSE = 0xC101 + MASTER_DATA_VERSION_CHECK_REQUEST = 0xC102 + MASTER_DATA_VERSION_CHECK_RESPONSE = 0xC103 + LOGIN_REQUEST = 0xC104 + LOGIN_RESPONSE = 0xC105 + LOGOUT_REQUEST = 0xC106 + LOGOUT_RESPONSE = 0xC107 + LOGOUT_TICKET_UNPURCHASED_REQUEST = 0xC108 + LOGOUT_TICKET_UNPURCHASED_RESPONSE = 0xC109 + PAYING_PLAY_START_REQUEST = 0xC10A + PAYING_PLAY_START_RESPONSE = 0xC10B + PAYING_PLAY_END_REQUEST = 0xC10C + PAYING_PLAY_END_RESPONSE = 0xC10D + PURCHASE_TICKET_REQUEST = 0xC10E + PURCHASE_TICKET_RESPONSE = 0xC10F + CONSUME_TICKET_REQUEST = 0xC110 + CONSUME_TICKET_RESPONSE = 0xC111 + ADD_CREDIT_REQUEST = 0xC112 + ADD_CREDIT_RESPONSE = 0xC113 + CONSUME_CREDIT_REQUEST = 0xC114 + CONSUME_CREDIT_RESPONSE = 0xC115 + PURCHASE_TICKET_GUEST_REQUEST = 0xC116 + PURCHASE_TICKET_GUEST_RESPONSE = 0xC117 + CONSUME_TICKET_GUEST_REQUEST = 0xC118 + CONSUME_TICKET_GUEST_RESPONSE = 0xC119 + ADD_CREDIT_GUEST_REQUEST = 0xC11A + ADD_CREDIT_GUEST_RESPONSE = 0xC11B + CONSUME_CREDIT_GUEST_REQUEST = 0xC11C + CONSUME_CREDIT_GUEST_RESPONSE = 0xC11D + GET_AUTH_CARD_DATA_REQUEST = 0xC11E + GET_AUTH_CARD_DATA_RESPONSE = 0xC11F + GET_ACCESS_CODE_BY_KEITAI_REQUEST = 0xC120 + GET_ACCESS_CODE_BY_KEITAI_RESPONSE = 0xC121 + GET_MAINTENANCE_INFO_REQUEST = 0xC122 + GET_MAINTENANCE_INFO_RESPONSE = 0xC123 + GET_RESOURCE_PATH_INFO_REQUEST = 0xC124 + GET_RESOURCE_PATH_INFO_RESPONSE = 0xC125 + VALIDATION_ERROR_NOTIFICATION_REQUEST = 0xC126 + VALIDATION_ERROR_NOTIFICATION_RESPONSE = 0xC127 + POWER_CUTTING_RETURN_NOTIFICATION_REQUEST = 0xC128 + POWER_CUTTING_RETURN_NOTIFICATION_RESPONSE = 0xC129 + GIVE_FREE_TICKET_REQUEST = 0xC12A + GIVE_FREE_TICKET_RESPONSE = 0xC12B + MATCHING_ERROR_NOTIFICATION_REQUEST = 0xC12C + MATCHING_ERROR_NOTIFICATION_RESPONSE = 0xC12D + AC_CABINET_BOOT_NOTIFICATION_REQUEST = 0xC12E + AC_CABINET_BOOT_NOTIFICATION_RESPONSE = 0xC12F + FIRST_TUTORIAL_END_REQUEST = 0xC200 + FIRST_TUTORIAL_END_RESPONSE = 0xC201 + VARIOUS_TUTORIAL_END_REQUEST = 0xC202 + VARIOUS_TUTORIAL_END_RESPONSE = 0xC203 + GET_VARIOUS_TUTORIAL_DATA_LIST_REQUEST = 0xC204 + GET_VARIOUS_TUTORIAL_DATA_LIST_RESPONSE = 0xC205 + DISCHARGE_PROFILE_CARD_REQUEST = 0xC300 + DISCHARGE_PROFILE_CARD_RESPONSE = 0xC301 + DISCHARGE_RESOURCE_CARD_REQUEST = 0xC302 + DISCHARGE_RESOURCE_CARD_RESPONSE = 0xC303 + DISCHARGE_RESOURCE_CARD_COMPLETE_REQUEST = 0xC304 + DISCHARGE_RESOURCE_CARD_COMPLETE_RESPONSE = 0xC305 + SCAN_QR_QUEST_PROFILE_CARD_REQUEST = 0xC306 + SCAN_QR_QUEST_PROFILE_CARD_RESPONSE = 0xC307 + SCAN_QR_SHOP_RESOURCE_CARD_REQUEST = 0xC308 + SCAN_QR_SHOP_RESOURCE_CARD_RESPONSE = 0xC309 + SCAN_QR_QUEST_RESOURCE_CARD_REQUEST = 0xC30A + SCAN_QR_QUEST_RESOURCE_CARD_RESPONSE = 0xC30B + CHECK_YUI_MEDAL_GET_CONDITION_REQUEST = 0xC400 + CHECK_YUI_MEDAL_GET_CONDITION_RESPONSE = 0xC401 + GET_YUI_MEDAL_BONUS_USER_DATA_REQUEST = 0xC402 + GET_YUI_MEDAL_BONUS_USER_DATA_RESPONSE = 0xC403 + CHECK_COMEBACK_EVENT_REQUEST = 0xC404 + CHECK_COMEBACK_EVENT_RESPONSE = 0xC405 + CHANGE_MY_STORE_REQUEST = 0xC406 + CHANGE_MY_STORE_RESPONSE = 0xC407 + CHECK_TITLE_GET_DECISION_REQUEST = 0xC408 + CHECK_TITLE_GET_DECISION_RESPONSE = 0xC409 + CHECK_PROFILE_CARD_USED_REWARD_REQUEST = 0xC40A + CHECK_PROFILE_CARD_USED_REWARD_RESPONSE = 0xC40B + CHECK_AC_LOGIN_BONUS_REQUEST = 0xC40C + CHECK_AC_LOGIN_BONUS_RESPONSE = 0xC40D + GET_USER_BASIC_DATA_REQUEST = 0xC500 + GET_USER_BASIC_DATA_RESPONSE = 0xC501 + GET_VP_GASHA_TICKET_DATA_LIST_REQUEST = 0xC502 + GET_VP_GASHA_TICKET_DATA_LIST_RESPONSE = 0xC503 + GET_PRESENT_BOX_NUM_REQUEST = 0xC504 + GET_PRESENT_BOX_NUM_RESPONSE = 0xC505 + GET_HERO_LOG_USER_DATA_LIST_REQUEST = 0xC600 + GET_HERO_LOG_USER_DATA_LIST_RESPONSE = 0xC601 + GET_EQUIPMENT_USER_DATA_LIST_REQUEST = 0xC602 + GET_EQUIPMENT_USER_DATA_LIST_RESPONSE = 0xC603 + GET_ITEM_USER_DATA_LIST_REQUEST = 0xC604 + GET_ITEM_USER_DATA_LIST_RESPONSE = 0xC605 + GET_SUPPORT_LOG_USER_DATA_LIST_REQUEST = 0xC606 + GET_SUPPORT_LOG_USER_DATA_LIST_RESPONSE = 0xC607 + GET_EPISODE_APPEND_DATA_LIST_REQUEST = 0xC608 + GET_EPISODE_APPEND_DATA_LIST_RESPONSE = 0xC609 + GET_EVENT_ITEM_DATA_LIST_REQUEST = 0xC60A + GET_EVENT_ITEM_DATA_LIST_RESPONSE = 0xC60B + GET_GASHA_MEDAL_USER_DATA_LIST_REQUEST = 0xC60C + GET_GASHA_MEDAL_USER_DATA_LIST_RESPONSE = 0xC60D + GET_SHOP_RESOURCE_SALES_DATA_LIST_REQUEST = 0xC700 + GET_SHOP_RESOURCE_SALES_DATA_LIST_RESPONSE = 0xC701 + PURCHASE_SHOP_RESOURCE_REQUEST = 0xC702 + PURCHASE_SHOP_RESOURCE_RESPONSE = 0xC703 + DISCARD_SHOP_RESOURCE_REQUEST = 0xC704 + DISCARD_SHOP_RESOURCE_RESPONSE = 0xC705 + GET_TITLE_USER_DATA_LIST_REQUEST = 0xC800 + GET_TITLE_USER_DATA_LIST_RESPONSE = 0xC801 + CHANGE_TITLE_REQUEST = 0xC802 + CHANGE_TITLE_RESPONSE = 0xC803 + GET_PARTY_DATA_LIST_REQUEST = 0xC804 + GET_PARTY_DATA_LIST_RESPONSE = 0xC805 + CHANGE_PARTY_REQUEST = 0xC806 + CHANGE_PARTY_RESPONSE = 0xC807 + GET_SUPPORT_LOG_PARTY_DATA_LIST_REQUEST = 0xC808 + GET_SUPPORT_LOG_PARTY_DATA_LIST_RESPONSE = 0xC809 + CHANGE_SUPPORT_LOG_PARTY_REQUEST = 0xC80A + CHANGE_SUPPORT_LOG_PARTY_RESPONSE = 0xC80B + CHANGE_HERO_LOG_LAST_SETTING_SKILL_REQUEST = 0xC80C + CHANGE_HERO_LOG_LAST_SETTING_SKILL_RESPONSE = 0xC80D + LOCK_RESOURCE_REQUEST = 0xC80E + LOCK_RESOURCE_RESPONSE = 0xC80F + UNLOCK_RESOURCE_REQUEST = 0xC810 + UNLOCK_RESOURCE_RESPONSE = 0xC811 + DISPOSAL_RESOURCE_REQUEST = 0xC812 + DISPOSAL_RESOURCE_RESPONSE = 0xC813 + SYNTHESIZE_ENHANCEMENT_HERO_LOG_REQUEST = 0xC814 + SYNTHESIZE_ENHANCEMENT_HERO_LOG_RESPONSE = 0xC815 + SYNTHESIZE_ENHANCEMENT_EQUIPMENT_REQUEST = 0xC816 + SYNTHESIZE_ENHANCEMENT_EQUIPMENT_RESPONSE = 0xC817 + SYNTHESIZE_ENHANCEMENT_SUPPORT_LOG_REQUEST = 0xC818 + SYNTHESIZE_ENHANCEMENT_SUPPORT_LOG_RESPONSE = 0xC819 + SYNTHESIZE_ABILITY_HERO_LOG_REQUEST = 0xC81A + SYNTHESIZE_ABILITY_HERO_LOG_RESPONSE = 0xC81B + SYNTHESIZE_ABILITY_EQUIPMENT_REQUEST = 0xC81C + SYNTHESIZE_ABILITY_EQUIPMENT_RESPONSE = 0xC81D + SYNTHESIZE_ABILITY_SUPPORT_LOG_REQUEST = 0xC81E + SYNTHESIZE_ABILITY_SUPPORT_LOG_RESPONSE = 0xC820 + GET_QUEST_SCENE_USER_DATA_LIST_REQUEST = 0xC900 + GET_QUEST_SCENE_USER_DATA_LIST_RESPONSE = 0xC901 + GET_QUEST_SCENE_PREV_SCAN_PROFILE_CARD_REQUEST = 0xC902 + GET_QUEST_SCENE_PREV_SCAN_PROFILE_CARD_RESPONSE = 0xC903 + EPISODE_PLAY_START_REQUEST = 0xC904 + EPISODE_PLAY_START_RESPONSE = 0xC905 + EPISODE_PLAY_CONTINUE_REQUEST = 0xC906 + EPISODE_PLAY_CONTINUE_RESPONSE = 0xC907 + EPISODE_PLAY_END_REQUEST = 0xC908 + EPISODE_PLAY_END_RESPONSE = 0xC909 + EPISODE_PLAY_END_UNANALYZED_LOG_FIXED_REQUEST = 0xC90A + EPISODE_PLAY_END_UNANALYZED_LOG_FIXED_RESPONSE = 0xC90B + SIDE_QUEST_PLAY_START_REQUEST = 0xC90C + SIDE_QUEST_PLAY_START_RESPONSE = 0xC90D + SIDE_QUEST_PLAY_CONTINUE_REQUEST = 0xC90E + SIDE_QUEST_PLAY_CONTINUE_RESPONSE = 0xC90F + SIDE_QUEST_PLAY_END_REQUEST = 0xC910 + SIDE_QUEST_PLAY_END_RESPONSE = 0xC911 + SIDE_QUEST_PLAY_END_UNANALYZED_LOG_FIXED_REQUEST = 0xC912 + SIDE_QUEST_PLAY_END_UNANALYZED_LOG_FIXED_RESPONSE = 0xC913 + TRIAL_TOWER_PLAY_START_REQUEST = 0xC914 + TRIAL_TOWER_PLAY_START_RESPONSE = 0xC915 + TRIAL_TOWER_PLAY_CONTINUE_REQUEST = 0xC916 + TRIAL_TOWER_PLAY_CONTINUE_RESPONSE = 0xC917 + TRIAL_TOWER_PLAY_END_REQUEST = 0xC918 + TRIAL_TOWER_PLAY_END_RESPONSE = 0xC919 + TRIAL_TOWER_PLAY_END_UNANALYZED_LOG_FIXED_REQUEST = 0xC91A + TRIAL_TOWER_PLAY_END_UNANALYZED_LOG_FIXED_RESPONSE = 0xC91B + DEFRAG_MATCH_QUEST_PLAY_START_REQUEST = 0xC91C + DEFRAG_MATCH_QUEST_PLAY_START_RESPONSE = 0xC91D + DEFRAG_MATCH_QUEST_PLAY_END_REQUEST = 0xC91E + DEFRAG_MATCH_QUEST_PLAY_END_RESPONSE = 0xC91F + DEFRAG_MATCH_QUEST_PLAY_END_UNANALYZED_LOG_FIXED_REQUEST = 0xC920 + DEFRAG_MATCH_QUEST_PLAY_END_UNANALYZED_LOG_FIXED_RESPONSE = 0xC921 + EX_TOWER_QUEST_PLAY_START_REQUEST = 0xC922 + EX_TOWER_QUEST_PLAY_START_RESPONSE = 0xC923 + EX_TOWER_QUEST_PLAY_CONTINUE_REQUEST = 0xC924 + EX_TOWER_QUEST_PLAY_CONTINUE_RESPONSE = 0xC925 + EX_TOWER_QUEST_PLAY_END_REQUEST = 0xC926 + EX_TOWER_QUEST_PLAY_END_RESPONSE = 0xC927 + EX_TOWER_QUEST_PLAY_END_UNANALYZED_LOG_FIXED_REQUEST = 0xC928 + EX_TOWER_QUEST_PLAY_END_UNANALYZED_LOG_FIXED_RESPONSE = 0xC929 + GET_EX_TOWER_USER_DATA_REQUEST = 0xC92A + GET_EX_TOWER_USER_DATA_RESPONSE = 0xC92B + REG_EX_TOWER_HALL_OF_FAME_CONFIRM_FLAG_REQUEST = 0xC92C + REG_EX_TOWER_HALL_OF_FAME_CONFIRM_FLAG_RESPONSE = 0xC92D + REG_EX_TOWER_CONFIRM_FLAG_REQUEST = 0xC92E + REG_EX_TOWER_CONFIRM_FLAG_RESPONSE = 0xC92F + GET_CHAT_SIDE_STORY_USER_DATA_LIST_REQUEST = 0xC930 + GET_CHAT_SIDE_STORY_USER_DATA_LIST_RESPONSE = 0xC931 + GET_USER_QUEST_EPISODE_STATUS_DATA_LIST_REQUEST = 0xC932 + GET_USER_QUEST_EPISODE_STATUS_DATA_LIST_RESPONSE = 0xC933 + APPLY_QUEST_DROP_BOOST_REQUEST = 0xC934 + APPLY_QUEST_DROP_BOOST_RESPONSE = 0xC935 + CREATE_QUEST_SCENE_MULTI_PLAY_ROOM_ID_REQUEST = 0xCA00 + CREATE_QUEST_SCENE_MULTI_PLAY_ROOM_ID_RESPONSE = 0xCA01 + GET_QUEST_SCENE_MULTI_PLAY_PHOTON_SERVER_REQUEST = 0xCA02 + GET_QUEST_SCENE_MULTI_PLAY_PHOTON_SERVER_RESPONSE = 0xCA03 + GET_QUEST_SCENE_MULTI_PLAY_PHOTON_SERVER_BY_ROOM_REQUEST = 0xCA04 + GET_QUEST_SCENE_MULTI_PLAY_PHOTON_SERVER_BY_ROOM_RESPONSE = 0xCA05 + GET_QUEST_BEST_SOCRE_RANKING_LIST_REQUEST = 0xCB00 + GET_QUEST_BEST_SOCRE_RANKING_LIST_RESPONSE = 0xCB01 + GET_QUEST_HIERARCHY_PROGRESS_DEGREES_RANKING_LIST_REQUEST = 0xCB02 + GET_QUEST_HIERARCHY_PROGRESS_DEGREES_RANKING_LIST_RESPONSE = 0xCB03 + GET_QUEST_POPULAR_HERO_LOG_RANKING_LIST_REQUEST = 0xCB04 + GET_QUEST_POPULAR_HERO_LOG_RANKING_LIST_RESPONSE = 0xCB05 + GET_QUEST_EX_TOWER_HIERARCHY_PROGRESS_DEGREES_STORE_RANKING_LIST_REQUEST = 0xCB06 + GET_QUEST_EX_TOWER_HIERARCHY_PROGRESS_DEGREES_STORE_RANKING_LIST_RESPONSE = 0xCB07 + GET_QUEST_EX_TOWER_HIERARCHY_PROGRESS_DEGREES_NATIONAL_RANKING_LIST_REQUEST = 0xCB08 + GET_QUEST_EX_TOWER_HIERARCHY_PROGRESS_DEGREES_NATIONAL_RANKING_LIST_RESPONSE = 0xCB09 + GET_TREASURE_HUNT_BASIC_DATA_REQUEST = 0xCC00 + GET_TREASURE_HUNT_BASIC_DATA_RESPONSE = 0xCC01 + GET_TREASURE_HUNT_WHOLE_TASK_DATA_LIST_REQUEST = 0xCC02 + GET_TREASURE_HUNT_WHOLE_TASK_DATA_LIST_RESPONSE = 0xCC03 + GET_TREASURE_HUNT_INDIVIDUAL_TASK_DATA_LIST_REQUEST = 0xCC04 + GET_TREASURE_HUNT_INDIVIDUAL_TASK_DATA_LIST_RESPONSE = 0xCC05 + TREASURE_HUNT_AD_CONFIRM_NOTIFICATION_REQUEST = 0xCC06 + TREASURE_HUNT_AD_CONFIRM_NOTIFICATION_RESPONSE = 0xCC07 + GET_TREASURE_HUNT_EVENT_POINT_RANKING_USER_DATA_REQUEST = 0xCC08 + GET_TREASURE_HUNT_EVENT_POINT_RANKING_USER_DATA_RESPONSE = 0xCC09 + GET_TREASURE_HUNT_EVENT_POINT_STORE_RANKING_LIST_REQUEST = 0xCC0A + GET_TREASURE_HUNT_EVENT_POINT_STORE_RANKING_LIST_RESPONSE = 0xCC0B + GET_TREASURE_HUNT_EVENT_POINT_NATIONAL_RANKING_LIST_REQUEST = 0xCC0C + GET_TREASURE_HUNT_EVENT_POINT_NATIONAL_RANKING_LIST_RESPONSE = 0xCC0D + GET_DEFRAG_MATCH_BASIC_DATA_REQUEST = 0xCD00 + GET_DEFRAG_MATCH_BASIC_DATA_RESPONSE = 0xCD01 + GET_DEFRAG_MATCH_RANKING_USER_DATA_REQUEST = 0xCD02 + GET_DEFRAG_MATCH_RANKING_USER_DATA_RESPONSE = 0xCD03 + GET_DEFRAG_MATCH_LEAGUE_POINT_RANKING_LIST_REQUEST = 0xCD04 + GET_DEFRAG_MATCH_LEAGUE_POINT_RANKING_LIST_RESPONSE = 0xCD05 + GET_DEFRAG_MATCH_LEAGUE_SCORE_RANKING_LIST_REQUEST = 0xCD06 + GET_DEFRAG_MATCH_LEAGUE_SCORE_RANKING_LIST_RESPONSE = 0xCD07 + DEFRAG_MATCH_AD_CONFIRM_NOTIFICATION_REQUEST = 0xCD08 + DEFRAG_MATCH_AD_CONFIRM_NOTIFICATION_RESPONSE = 0xCD09 + CHECK_GET_SEED_DEFRAG_MATCH_REQUEST = 0xCD0A + CHECK_GET_SEED_DEFRAG_MATCH_RESPONSE = 0xCD0B + REG_DEFRAG_MATCH_HALL_OF_FAME_CONFIRM_FLAG_REQUEST = 0xCD0C + REG_DEFRAG_MATCH_HALL_OF_FAME_CONFIRM_FLAG_RESPONSE = 0xCD0D + GET_EVENT_SCENE_USER_DATA_LIST_REQUEST = 0xCE00 + GET_EVENT_SCENE_USER_DATA_LIST_RESPONSE = 0xCE01 + REG_PLAYED_EVENT_SCENE_USER_DATA_LIST_REQUEST = 0xCE02 + REG_PLAYED_EVENT_SCENE_USER_DATA_LIST_RESPONSE = 0xCE03 + GET_GASHA_LIST_REQUEST = 0xCF00 + GET_GASHA_LIST_RESPONSE = 0xCF01 + EXEC_GASHA_REQUEST = 0xCF02 + EXEC_GASHA_RESPONSE = 0xCF03 + EXEC_CREDIT_GASHA_START_REQUEST = 0xCF04 + EXEC_CREDIT_GASHA_START_RESPONSE = 0xCF05 + EXEC_CREDIT_GASHA_EXTRA_PAYING_REQUEST = 0xCF06 + EXEC_CREDIT_GASHA_EXTRA_PAYING_RESPONSE = 0xCF07 + EXEC_CREDIT_GASHA_END_REQUEST = 0xCF08 + EXEC_CREDIT_GASHA_END_RESPONSE = 0xCF09 + EXEC_CREDIT_GASHA_CARD_DISCHARGE_STATE_MIGRATION_REQUEST = 0xCF0A + EXEC_CREDIT_GASHA_CARD_DISCHARGE_STATE_MIGRATION_RESPONSE = 0xCF0B + EXEC_CREDIT_GASHA_CARD_DISCHARGE_END_REQUEST = 0xCF0C + EXEC_CREDIT_GASHA_CARD_DISCHARGE_END_RESPONSE = 0xCF0D + GET_GASHA_MEDAL_SHOP_USER_DATA_LIST_REQUEST = 0xCF0E + GET_GASHA_MEDAL_SHOP_USER_DATA_LIST_RESPONSE = 0xCF0F + PURCHASE_GASHA_MEDAL_SHOP_ITEM_REQUEST = 0xCF10 + PURCHASE_GASHA_MEDAL_SHOP_ITEM_RESPONSE = 0xCF11 + GET_GASHA_FREE_CAMPAIGN_USER_DATA_REQUEST = 0xCF12 + GET_GASHA_FREE_CAMPAIGN_USER_DATA_RESPONSE = 0xCF13 + GET_ADVENTURE_EXEC_USER_DATA_REQUEST = 0xD000 + GET_ADVENTURE_EXEC_USER_DATA_RESPONSE = 0xD001 + GET_ADVENTURE_PARTY_DATA_LIST_REQUEST = 0xD002 + GET_ADVENTURE_PARTY_DATA_LIST_RESPONSE = 0xD003 + GET_YUI_MEDAL_SHOP_USER_DATA_LIST_REQUEST = 0xD100 + GET_YUI_MEDAL_SHOP_USER_DATA_LIST_RESPONSE = 0xD101 + PURCHASE_YUI_MEDAL_SHOP_ITEM_REQUEST = 0xD102 + PURCHASE_YUI_MEDAL_SHOP_ITEM_RESPONSE = 0xD103 + PURCHASE_EVENT_SHOP_ITEM_REQUEST = 0xD104 + PURCHASE_EVENT_SHOP_ITEM_RESPONSE = 0xD105 + GET_BEGINNER_MISSION_USER_DATA_REQUEST = 0xD200 + GET_BEGINNER_MISSION_USER_DATA_RESPONSE = 0xD201 + GET_BEGINNER_MISSION_PROGRESSES_USER_DATA_LIST_REQUEST = 0xD202 + GET_BEGINNER_MISSION_PROGRESSES_USER_DATA_LIST_RESPONSE = 0xD203 + GET_BEGINNER_MISSION_SEAT_PROGRESSES_USER_DATA_LIST_REQUEST = 0xD204 + GET_BEGINNER_MISSION_SEAT_PROGRESSES_USER_DATA_LIST_RESPONSE = 0xD205 + BEGINNER_MISSION_AD_CONFIRM_NOTIFICATION_REQUEST = 0xD206 + BEGINNER_MISSION_AD_CONFIRM_NOTIFICATION_RESPONSE = 0xD207 + RECEIVE_BEGINNER_MISSION_REWARD_REQUEST = 0xD208 + RECEIVE_BEGINNER_MISSION_REWARD_RESPONSE = 0xD209 + GET_RES_EARN_CAMPAIGN_SHOP_USER_DATA_LIST_REQUEST = 0xD300 + GET_RES_EARN_CAMPAIGN_SHOP_USER_DATA_LIST_RESPONSE = 0xD301 + PURCHASE_RES_EARN_CAMPAIGN_SHOP_ITEM_REQUEST = 0xD302 + PURCHASE_RES_EARN_CAMPAIGN_SHOP_ITEM_RESPONSE = 0xD303 + PAYING_YUI_MEDAL_BONUS_GET_CHECK_REQUEST = 0xD304 + PAYING_YUI_MEDAL_BONUS_GET_CHECK_RESPONSE = 0xD305 + PAYING_YUI_MEDAL_BONUS_AD_CONFIRM_NOTIFICATION_REQUEST = 0xD306 + PAYING_YUI_MEDAL_BONUS_AD_CONFIRM_NOTIFICATION_RESPONSE = 0xD307 + GET_PLAY_CAMPAIGN_USER_DATA_LIST_REQUEST = 0xD308 + GET_PLAY_CAMPAIGN_USER_DATA_LIST_RESPONSE = 0xD309 + GET_PLAY_CAMPAIGN_STORE_USER_DATA_LIST_REQUEST = 0xD30A + GET_PLAY_CAMPAIGN_STORE_USER_DATA_LIST_RESPONSE = 0xD30B + GET_PLAY_CAMPAIGN_REWARD_USER_DATA_LIST_REQUEST = 0xD30C + GET_PLAY_CAMPAIGN_REWARD_USER_DATA_LIST_RESPONSE = 0xD30D + APPLY_FIRST_TICKET_PURCHASE_CAMPAIGN_REQUEST = 0xD30E + APPLY_FIRST_TICKET_PURCHASE_CAMPAIGN_RESPONSE = 0xD30F + GET_FIRST_TICKET_PURCHASE_CAMPAIGN_USER_DATA_REQUEST = 0xD310 + GET_FIRST_TICKET_PURCHASE_CAMPAIGN_USER_DATA_RESPONSE = 0xD311 + GET_LINKED_SITE_REG_CAMPAIGN_USER_DATA_REQUEST = 0xD312 + GET_LINKED_SITE_REG_CAMPAIGN_USER_DATA_RESPONSE = 0xD313 + GET_HERO_LOG_UNIT_USER_DATA_LIST_REQUEST = 0xD400 + GET_HERO_LOG_UNIT_USER_DATA_LIST_RESPONSE = 0xD401 + GET_CHARA_UNIT_USER_DATA_LIST_REQUEST = 0xD402 + GET_CHARA_UNIT_USER_DATA_LIST_RESPONSE = 0xD403 + BNID_SERIAL_CODE_CHECK_REQUEST = 0xD404 + BNID_SERIAL_CODE_CHECK_RESPONSE = 0xD405 + BNID_SERIAL_CODE_ENTRY_BY_APPENDIX_CARD_REQUEST = 0xD406 + BNID_SERIAL_CODE_ENTRY_BY_APPENDIX_CARD_RESPONSE = 0xD407 + GET_M_PLAYER_RANKS_REQUEST = 0xD500 + GET_M_PLAYER_RANKS_RESPONSE = 0xD501 + GET_M_TITLES_REQUEST = 0xD502 + GET_M_TITLES_RESPONSE = 0xD503 + GET_M_FRAGMENTS_REQUEST = 0xD504 + GET_M_FRAGMENTS_RESPONSE = 0xD505 + GET_M_REWARD_TABLES_REQUEST = 0xD506 + GET_M_REWARD_TABLES_RESPONSE = 0xD507 + GET_M_REWARD_SETS_REQUEST = 0xD508 + GET_M_REWARD_SETS_RESPONSE = 0xD509 + GET_M_UNANALYZED_LOG_GRADES_REQUEST = 0xD50A + GET_M_UNANALYZED_LOG_GRADES_RESPONSE = 0xD50B + GET_M_APPOINT_LEADER_PARAMS_REQUEST = 0xD50C + GET_M_APPOINT_LEADER_PARAMS_RESPONSE = 0xD50D + GET_M_APPOINT_LEADER_EFFECTS_REQUEST = 0xD50E + GET_M_APPOINT_LEADER_EFFECTS_RESPONSE = 0xD50F + GET_M_APPOINT_LEADER_EFFECT_TYPES_REQUEST = 0xD510 + GET_M_APPOINT_LEADER_EFFECT_TYPES_RESPONSE = 0xD511 + GET_M_RARITIES_REQUEST = 0xD512 + GET_M_RARITIES_RESPONSE = 0xD513 + GET_M_COMPOSITION_EVENTS_REQUEST = 0xD514 + GET_M_COMPOSITION_EVENTS_RESPONSE = 0xD515 + GET_M_COMPOSITION_PARAMS_REQUEST = 0xD516 + GET_M_COMPOSITION_PARAMS_RESPONSE = 0xD517 + GET_M_GAME_PLAY_PRICES_REQUEST = 0xD518 + GET_M_GAME_PLAY_PRICES_RESPONSE = 0xD519 + GET_M_BUY_TICKETS_REQUEST = 0xD51A + GET_M_BUY_TICKETS_RESPONSE = 0xD51B + GET_M_TIPS_REQUEST = 0xD51C + GET_M_TIPS_RESPONSE = 0xD51D + GET_M_CAPS_REQUEST = 0xD51E + GET_M_CAPS_RESPONSE = 0xD51F + GET_M_HERO_LOG_REQUEST = 0xD520 + GET_M_HERO_LOG_RESPONSE = 0xD521 + GET_M_HERO_LOG_LEVELS_REQUEST = 0xD522 + GET_M_HERO_LOG_LEVELS_RESPONSE = 0xD523 + GET_M_HERO_LOG_ROLES_REQUEST = 0xD524 + GET_M_HERO_LOG_ROLES_RESPONSE = 0xD525 + GET_M_HERO_LOG_TRUST_RANKS_REQUEST = 0xD526 + GET_M_HERO_LOG_TRUST_RANKS_RESPONSE = 0xD527 + GET_M_CHARAS_REQUEST = 0xD528 + GET_M_CHARAS_RESPONSE = 0xD529 + GET_M_CHARA_FRIENDLY_RANKS_REQUEST = 0xD52A + GET_M_CHARA_FRIENDLY_RANKS_RESPONSE = 0xD52B + GET_M_EQUIPMENTS_REQUEST = 0xD52C + GET_M_EQUIPMENTS_RESPONSE = 0xD52D + GET_M_EQUIPMENT_LEVELS_REQUEST = 0xD52E + GET_M_EQUIPMENT_LEVELS_RESPONSE = 0xD52F + GET_M_WEAPON_TYPES_REQUEST = 0xD530 + GET_M_WEAPON_TYPES_RESPONSE = 0xD531 + GET_M_ITEMS_REQUEST = 0xD532 + GET_M_ITEMS_RESPONSE = 0xD533 + GET_M_ITEM_TYPES_REQUEST = 0xD534 + GET_M_ITEM_TYPES_RESPONSE = 0xD535 + GET_M_BUFF_ITEMS_REQUEST = 0xD536 + GET_M_BUFF_ITEMS_RESPONSE = 0xD537 + GET_M_ENEMIES_REQUEST = 0xD538 + GET_M_ENEMIES_RESPONSE = 0xD539 + GET_M_ENEMY_SETS_REQUEST = 0xD53A + GET_M_ENEMY_SETS_RESPONSE = 0xD53B + GET_M_ENEMY_KINDS_REQUEST = 0xD53C + GET_M_ENEMY_KINDS_RESPONSE = 0xD53D + GET_M_ENEMY_CATEGORIES_REQUEST = 0xD53E + GET_M_ENEMY_CATEGORIES_RESPONSE = 0xD53F + GET_M_UNITS_REQUEST = 0xD540 + GET_M_UNITS_RESPONSE = 0xD541 + GET_M_UNIT_GIMMICKS_REQUEST = 0xD542 + GET_M_UNIT_GIMMICKS_RESPONSE = 0xD543 + GET_M_UNIT_COLLISIONS_REQUEST = 0xD544 + GET_M_UNIT_COLLISIONS_RESPONSE = 0xD545 + GET_M_UNIT_POWERS_REQUEST = 0xD546 + GET_M_UNIT_POWERS_RESPONSE = 0xD547 + GET_M_GIMMICK_ATTACKS_REQUEST = 0xD548 + GET_M_GIMMICK_ATTACKS_RESPONSE = 0xD549 + GET_M_CHARA_ATTACKS_REQUEST = 0xD54A + GET_M_CHARA_ATTACKS_RESPONSE = 0xD54B + GET_M_BOSS_ATTACKS_REQUEST = 0xD54C + GET_M_BOSS_ATTACKS_RESPONSE = 0xD54D + GET_M_MONSTER_ATTACKS_REQUEST = 0xD54E + GET_M_MONSTER_ATTACKS_RESPONSE = 0xD54F + GET_M_MONSTER_ACTIONS_REQUEST = 0xD550 + GET_M_MONSTER_ACTIONS_RESPONSE = 0xD551 + GET_M_PROPERTIES_REQUEST = 0xD552 + GET_M_PROPERTIES_RESPONSE = 0xD553 + GET_M_PROPERTY_TABLES_REQUEST = 0xD554 + GET_M_PROPERTY_TABLES_RESPONSE = 0xD555 + GET_M_PROPERTY_TYPES_REQUEST = 0xD556 + GET_M_PROPERTY_TYPES_RESPONSE = 0xD557 + GET_M_SKILLS_REQUEST = 0xD558 + GET_M_SKILLS_RESPONSE = 0xD559 + GET_M_SKILL_TABLES_REQUEST = 0xD55A + GET_M_SKILL_TABLES_RESPONSE = 0xD55B + GET_M_SKILL_LEVELS_REQUEST = 0xD55C + GET_M_SKILL_LEVELS_RESPONSE = 0xD55D + GET_M_AWAKENINGS_REQUEST = 0xD55E + GET_M_AWAKENINGS_RESPONSE = 0xD55F + GET_M_SYNCHRO_SKILLS_REQUEST = 0xD560 + GET_M_SYNCHRO_SKILLS_RESPONSE = 0xD561 + GET_M_SOUND_SKILL_CUT_IN_VOICES_REQUEST = 0xD562 + GET_M_SOUND_SKILL_CUT_IN_VOICES_RESPONSE = 0xD563 + GET_M_QUEST_SCENES_REQUEST = 0xD564 + GET_M_QUEST_SCENES_RESPONSE = 0xD565 + GET_M_QUEST_EXIST_UNITS_REQUEST = 0xD566 + GET_M_QUEST_EXIST_UNITS_RESPONSE = 0xD567 + GET_M_QUEST_EPISODE_APPEND_REWARDS_REQUEST = 0xD568 + GET_M_QUEST_EPISODE_APPEND_REWARDS_RESPONSE = 0xD569 + GET_M_SIDE_QUESTS_REQUEST = 0xD56A + GET_M_SIDE_QUESTS_RESPONSE = 0xD56B + GET_M_EPISODES_REQUEST = 0xD56C + GET_M_EPISODES_RESPONSE = 0xD56D + GET_M_EPISODE_CHAPTERS_REQUEST = 0xD56E + GET_M_EPISODE_CHAPTERS_RESPONSE = 0xD56F + GET_M_EPISODE_PARTS_REQUEST = 0xD570 + GET_M_EPISODE_PARTS_RESPONSE = 0xD571 + GET_M_TRIAL_TOWERS_REQUEST = 0xD572 + GET_M_TRIAL_TOWERS_RESPONSE = 0xD573 + GET_M_EX_TOWERS_REQUEST = 0xD574 + GET_M_EX_TOWERS_RESPONSE = 0xD575 + GET_M_EX_TOWER_QUESTS_REQUEST = 0xD576 + GET_M_EX_TOWER_QUESTS_RESPONSE = 0xD577 + GET_M_MENU_DISPLAY_ENEMIES_REQUEST = 0xD578 + GET_M_MENU_DISPLAY_ENEMIES_RESPONSE = 0xD579 + GET_M_MISSIONS_REQUEST = 0xD57A + GET_M_MISSIONS_RESPONSE = 0xD57B + GET_M_MISSION_TABLES_REQUEST = 0xD57C + GET_M_MISSION_TABLES_RESPONSE = 0xD57D + GET_M_MISSION_DIFFICULTIES_REQUEST = 0xD57E + GET_M_MISSION_DIFFICULTIES_RESPONSE = 0xD57F + GET_M_BATTLE_CAMERAS_REQUEST = 0xD580 + GET_M_BATTLE_CAMERAS_RESPONSE = 0xD581 + GET_M_CHAT_MAIN_STORIES_REQUEST = 0xD582 + GET_M_CHAT_MAIN_STORIES_RESPONSE = 0xD583 + GET_M_CHAT_SIDE_STORIES_REQUEST = 0xD584 + GET_M_CHAT_SIDE_STORIES_RESPONSE = 0xD585 + GET_M_CHAT_EVENT_STORIES_REQUEST = 0xD586 + GET_M_CHAT_EVENT_STORIES_RESPONSE = 0xD587 + GET_M_NAVIGATOR_CHARAS_REQUEST = 0xD588 + GET_M_NAVIGATOR_CHARAS_RESPONSE = 0xD589 + GET_M_NAVIGATOR_COMMENTS_REQUEST = 0xD58A + GET_M_NAVIGATOR_COMMENTS_RESPONSE = 0xD58B + GET_M_EX_BONUS_TABLES_REQUEST = 0xD58C + GET_M_EX_BONUS_TABLES_RESPONSE = 0xD58D + GET_M_EX_BONUS_CONDITIONS_REQUEST = 0xD58E + GET_M_EX_BONUS_CONDITIONS_RESPONSE = 0xD58F + GET_M_QUEST_RARE_DROPS_REQUEST = 0xD590 + GET_M_QUEST_RARE_DROPS_RESPONSE = 0xD591 + GET_M_QUEST_SPECIAL_RARE_DROP_SETTINGS_REQUEST = 0xD592 + GET_M_QUEST_SPECIAL_RARE_DROP_SETTINGS_RESPONSE = 0xD593 + GET_M_QUEST_SPECIAL_RARE_DROPS_REQUEST = 0xD594 + GET_M_QUEST_SPECIAL_RARE_DROPS_RESPONSE = 0xD595 + GET_M_QUEST_TUTORIALS_REQUEST = 0xD596 + GET_M_QUEST_TUTORIALS_RESPONSE = 0xD597 + GET_M_QUEST_PLAYER_TRACE_TABLES_REQUEST = 0xD598 + GET_M_QUEST_PLAYER_TRACE_TABLES_RESPONSE = 0xD599 + GET_M_QUEST_STILLS_REQUEST = 0xD59A + GET_M_QUEST_STILLS_RESPONSE = 0xD59B + GET_M_GASHAS_REQUEST = 0xD59C + GET_M_GASHAS_RESPONSE = 0xD59D + GET_M_GASHA_HEADERS_REQUEST = 0xD59E + GET_M_GASHA_HEADERS_RESPONSE = 0xD59F + GET_M_GASHA_LOTTERY_RARITIES_REQUEST = 0xD5A0 + GET_M_GASHA_LOTTERY_RARITIES_RESPONSE = 0xD5A1 + GET_M_GASHA_PRIZES_REQUEST = 0xD5A2 + GET_M_GASHA_PRIZES_RESPONSE = 0xD5A3 + GET_M_COMEBACK_EVENTS_REQUEST = 0xD5A4 + GET_M_COMEBACK_EVENTS_RESPONSE = 0xD5A5 + GET_M_AD_BANNERS_REQUEST = 0xD5A6 + GET_M_AD_BANNERS_RESPONSE = 0xD5A7 + GET_M_EVENTS_REQUEST = 0xD5A8 + GET_M_EVENTS_RESPONSE = 0xD5A9 + GET_M_TREASURE_HUNTS_REQUEST = 0xD5AA + GET_M_TREASURE_HUNTS_RESPONSE = 0xD5AB + GET_M_TREASURE_HUNT_WHOLE_TASKS_REQUEST = 0xD5AC + GET_M_TREASURE_HUNT_WHOLE_TASKS_RESPONSE = 0xD5AD + GET_M_TREASURE_HUNT_INDIVIDUAL_TASKS_REQUEST = 0xD5AE + GET_M_TREASURE_HUNT_INDIVIDUAL_TASKS_RESPONSE = 0xD5AF + GET_M_TREASURE_HUNT_SPECIAL_EFFECTS_REQUEST = 0xD5B0 + GET_M_TREASURE_HUNT_SPECIAL_EFFECTS_RESPONSE = 0xD5B1 + GET_M_TREASURE_HUNT_EVENT_POINT_REWARD_COMMON_REWARDS_REQUEST = 0xD5B2 + GET_M_TREASURE_HUNT_EVENT_POINT_REWARD_COMMON_REWARDS_RESPONSE = 0xD5B3 + GET_M_TREASURE_HUNT_EVENT_POINT_REWARD_TITLES_REQUEST = 0xD5B4 + GET_M_TREASURE_HUNT_EVENT_POINT_REWARD_TITLES_RESPONSE = 0xD5B5 + GET_M_TREASURE_HUNT_TASK_TEXTS_REQUEST = 0xD5B6 + GET_M_TREASURE_HUNT_TASK_TEXTS_RESPONSE = 0xD5B7 + GET_M_BNID_SERIAL_CODES_REQUEST = 0xD5B8 + GET_M_BNID_SERIAL_CODES_RESPONSE = 0xD5B9 + GET_M_BNID_SERIAL_CODE_REWARDS_REQUEST = 0xD5BA + GET_M_BNID_SERIAL_CODE_REWARDS_RESPONSE = 0xD5BB + GET_M_SUPPORT_LOG_REQUEST = 0xD5BC + GET_M_SUPPORT_LOG_RESPONSE = 0xD5BD + GET_M_SUPPORT_LOG_TYPES_REQUEST = 0xD5BE + GET_M_SUPPORT_LOG_TYPES_RESPONSE = 0xD5BF + GET_M_EPISODE_APPENDS_REQUEST = 0xD5C0 + GET_M_EPISODE_APPENDS_RESPONSE = 0xD5C1 + GET_M_QUEST_DEFRAG_MATCH_QUESTS_REQUEST = 0xD5C2 + GET_M_QUEST_DEFRAG_MATCH_QUESTS_RESPONSE = 0xD5C3 + GET_M_QUEST_DEFRAG_MATCH_QUEST_BOSS_TABLES_REQUEST = 0xD5C4 + GET_M_QUEST_DEFRAG_MATCH_QUEST_BOSS_TABLES_RESPONSE = 0xD5C5 + GET_M_DEFRAG_MATCHES_REQUEST = 0xD5C6 + GET_M_DEFRAG_MATCHES_RESPONSE = 0xD5C7 + GET_M_DEFRAG_MATCH_SEED_REQUEST = 0xD5C8 + GET_M_DEFRAG_MATCH_SEED_RESPONSE = 0xD5C9 + GET_M_DEFRAG_MATCH_SPECIAL_EFFECTS_REQUEST = 0xD5CA + GET_M_DEFRAG_MATCH_SPECIAL_EFFECTS_RESPONSE = 0xD5CB + GET_M_DEFRAG_MATCH_GRADES_REQUEST = 0xD5CC + GET_M_DEFRAG_MATCH_GRADES_RESPONSE = 0xD5CD + GET_M_DEFRAG_MATCH_CPU_UNITS_REQUEST = 0xD5CE + GET_M_DEFRAG_MATCH_CPU_UNITS_RESPONSE = 0xD5CF + GET_M_DEFRAG_MATCH_CPU_SUPPORT_LOGS_REQUEST = 0xD5D0 + GET_M_DEFRAG_MATCH_CPU_SUPPORT_LOGS_RESPONSE = 0xD5D1 + GET_M_DEFRAG_MATCH_PERIOD_BONUSES_REQUEST = 0xD5D2 + GET_M_DEFRAG_MATCH_PERIOD_BONUSES_RESPONSE = 0xD5D3 + GET_M_DEFRAG_MATCH_RANDOM_BONUS_TABLES_REQUEST = 0xD5D4 + GET_M_DEFRAG_MATCH_RANDOM_BONUS_TABLES_RESPONSE = 0xD5D5 + GET_M_DEFRAG_MATCH_RANDOM_BONUS_CONDITIONS_REQUEST = 0xD5D6 + GET_M_DEFRAG_MATCH_RANDOM_BONUS_CONDITIONS_RESPONSE = 0xD5D7 + GET_M_DEFRAG_MATCH_RARE_DROPS_REQUEST = 0xD5D8 + GET_M_DEFRAG_MATCH_RARE_DROPS_RESPONSE = 0xD5D9 + GET_M_YUI_MEDAL_SHOPS_REQUEST = 0xD5DA + GET_M_YUI_MEDAL_SHOPS_RESPONSE = 0xD5DB + GET_M_YUI_MEDAL_SHOP_ITEMS_REQUEST = 0xD5DC + GET_M_YUI_MEDAL_SHOP_ITEMS_RESPONSE = 0xD5DD + GET_M_EVENT_SCENES_REQUEST = 0xD5DE + GET_M_EVENT_SCENES_RESPONSE = 0xD5DF + GET_M_GENERIC_CAMPAIGN_PERIODS_REQUEST = 0xD5E0 + GET_M_GENERIC_CAMPAIGN_PERIODS_RESPONSE = 0xD5E1 + GET_M_BEGINNER_MISSIONS_REQUEST = 0xD5E2 + GET_M_BEGINNER_MISSIONS_RESPONSE = 0xD5E3 + GET_M_BEGINNER_MISSION_CONDITIONS_REQUEST = 0xD5E4 + GET_M_BEGINNER_MISSION_CONDITIONS_RESPONSE = 0xD5E5 + GET_M_BEGINNER_MISSION_REWARDS_REQUEST = 0xD5E6 + GET_M_BEGINNER_MISSION_REWARDS_RESPONSE = 0xD5E7 + GET_M_BEGINNER_MISSION_SEAT_CONDITIONS_REQUEST = 0xD5E8 + GET_M_BEGINNER_MISSION_SEAT_CONDITIONS_RESPONSE = 0xD5E9 + GET_M_BEGINNER_MISSION_SEAT_REWARDS_REQUEST = 0xD5EA + GET_M_BEGINNER_MISSION_SEAT_REWARDS_RESPONSE = 0xD5EB + GET_M_EVENT_ITEMS_REQUEST = 0xD5EC + GET_M_EVENT_ITEMS_RESPONSE = 0xD5ED + GET_M_EVENT_MONSTERS_REQUEST = 0xD5EE + GET_M_EVENT_MONSTERS_RESPONSE = 0xD5EF + GET_M_YUI_MEDAL_BONUSES_REQUEST = 0xD5F0 + GET_M_YUI_MEDAL_BONUSES_RESPONSE = 0xD5F1 + GET_M_YUI_MEDAL_BONUS_CONDITIONS_REQUEST = 0xD5F2 + GET_M_YUI_MEDAL_BONUS_CONDITIONS_RESPONSE = 0xD5F3 + GET_M_GASHA_MEDALS_REQUEST = 0xD5F4 + GET_M_GASHA_MEDALS_RESPONSE = 0xD5F5 + GET_M_GASHA_MEDAL_TYPES_REQUEST = 0xD5F6 + GET_M_GASHA_MEDAL_TYPES_RESPONSE = 0xD5F7 + GET_M_GASHA_MEDAL_SETTINGS_REQUEST = 0xD5F8 + GET_M_GASHA_MEDAL_SETTINGS_RESPONSE = 0xD5F9 + GET_M_GASHA_MEDAL_BONUSES_REQUEST = 0xD5FA + GET_M_GASHA_MEDAL_BONUSES_RESPONSE = 0xD5FB + GET_M_GASHA_MEDAL_SHOPS_REQUEST = 0xD5FC + GET_M_GASHA_MEDAL_SHOPS_RESPONSE = 0xD5FD + GET_M_GASHA_MEDAL_SHOP_ITEMS_REQUEST = 0xD5FE + GET_M_GASHA_MEDAL_SHOP_ITEMS_RESPONSE = 0xD5FF + GET_M_RES_EARN_CAMPAIGN_APPLICATIONS_REQUEST = 0xD600 + GET_M_RES_EARN_CAMPAIGN_APPLICATIONS_RESPONSE = 0xD601 + GET_M_RES_EARN_CAMPAIGN_APPLICATION_PRODUCTS_REQUEST = 0xD602 + GET_M_RES_EARN_CAMPAIGN_APPLICATION_PRODUCTS_RESPONSE = 0xD603 + GET_M_RES_EARN_CAMPAIGN_SHOPS_REQUEST = 0xD604 + GET_M_RES_EARN_CAMPAIGN_SHOPS_RESPONSE = 0xD605 + GET_M_RES_EARN_CAMPAIGN_SHOP_ITEMS_REQUEST = 0xD606 + GET_M_RES_EARN_CAMPAIGN_SHOP_ITEMS_RESPONSE = 0xD607 + GET_M_PAYING_YUI_MEDAL_BONUSES_REQUEST = 0xD608 + GET_M_PAYING_YUI_MEDAL_BONUSES_RESPONSE = 0xD609 + GET_M_AC_LOGIN_BONUSES_REQUEST = 0xD60A + GET_M_AC_LOGIN_BONUSES_RESPONSE = 0xD60B + GET_M_PLAY_CAMPAIGNS_REQUEST = 0xD60C + GET_M_PLAY_CAMPAIGNS_RESPONSE = 0xD60D + GET_M_PLAY_CAMPAIGN_REWARDS_REQUEST = 0xD60E + GET_M_PLAY_CAMPAIGN_REWARDS_RESPONSE = 0xD60F + GET_M_GASHA_FREE_CAMPAIGNS_REQUEST = 0xD610 + GET_M_GASHA_FREE_CAMPAIGNS_RESPONSE = 0xD611 + GET_M_QUEST_DROP_BOOST_CAMPAIGNS_REQUEST = 0xD612 + GET_M_QUEST_DROP_BOOST_CAMPAIGNS_RESPONSE = 0xD613 + GET_M_FIRST_TICKET_PURCHASE_CAMPAIGNS_REQUEST = 0xD614 + GET_M_FIRST_TICKET_PURCHASE_CAMPAIGNS_RESPONSE = 0xD615 + GET_M_LINKED_SITE_REG_CAMPAIGNS_REQUEST = 0xD616 + GET_M_LINKED_SITE_REG_CAMPAIGNS_RESPONSE = 0xD617 + GET_M_LINKED_SITE_REG_CAMPAIGN_REWARDS_REQUEST = 0xD618 + GET_M_LINKED_SITE_REG_CAMPAIGN_REWARDS_RESPONSE = 0xD619 diff --git a/titles/sao/data/1/AcLoginBonuses.csv b/titles/sao/data/1/AcLoginBonuses.csv new file mode 100644 index 0000000000000000000000000000000000000000..166c5b2816a132de06030b4b07b98943e2b9b430 GIT binary patch literal 283 zcmdPbS8z=B$xqMBbIQ*vE%r>&3CS$UN!1BTEl(^;2~I5uE=>Xo`WK|;1(zfimAE99 zq=I>_c_|<^FPEW?l97Rt!PA{v%%9EauzWUs>HEF&-tXyn+_dO%bNA!sh41&YJ#Jq0 zxM?$(-1%a~jHmmzzTeZSq+sN53qT*4Cr}XOE$Ihh`ty6~Ab5tMe-Unm2YO`cF?RNh?K55d|4!kocPmFP^w^!exyI+ z>!&JWMDLMiAq&!|al~zVJln~UX2WakGXXj&g3bP9%{1G1a+OL$SP#5(aGMh-5R#Hu}NLtLGzt^d+6RCA!{Hz l^ZjOrDLkLaWGxzUg4#fBx_74Ut#tq4WNpu(9_ zrXO=U^Y|BC#~MV)-Qk??e2;SyiG?ji$se8+cI9+dK27Fwa;C6PJ+`gH(iE5j;-SZyOWLb_$Jqbh<&YiJ#9AYLyc2;uW2`SOxX~oCB{57i*LN*MO_j z^kMxnHpP3PuP5LwuW5RAU#zTC;t$F*;eh>%-}sZxr zqS}p8&(V;?xq(^0-$IZX?ci__Tv@`kB<>yD)qGv^^$LzGtm@;gF!%d~@JDkbegGcb B9%ldm literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/AppointLeaderParam.csv b/titles/sao/data/1/AppointLeaderParam.csv new file mode 100644 index 0000000000000000000000000000000000000000..173f312b6467eaa121bd7277005b17d2a6e49d0a GIT binary patch literal 166 zcmdPbS8yyS$j{6x@kvcgNi7OUEK1DvOwsYo%Ph%E%n7c{OU@|D4@xXa)j?6`nU`FY znwy$ef})~4F*`LcGcO&htXqC&j$=v+iUwq>LyAg^OPuoaN{e~940VhRbPRP&bqs+N GFBbrY7CbZn literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/Awakening.csv b/titles/sao/data/1/Awakening.csv new file mode 100644 index 0000000000000000000000000000000000000000..05d1bd0fec4015c519f38e7d49e9c2d44254d2f9 GIT binary patch literal 159 zcmXAfO$viR3`X~X+`$8cI==@{5GuGVbUn~PO6x?%iXPu)X7NJ4$7|cBJHjWXcbdl+ zJ@^;C!?{w=Y2WTK^Tcx<&lpxt_3!e+89|d)iquW{|Iq@1Ayb@8BOq9^RY_(A1V^qo ONt}S-$yX&=0pS8r9wxs4 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/BattleCamera.csv b/titles/sao/data/1/BattleCamera.csv new file mode 100644 index 0000000000000000000000000000000000000000..d4410da105dd84c055d38bf12d78c3bd5ec99a88 GIT binary patch literal 162 zcmdPbS8z%!DalE7PRva$O7u+8@lQ)DPA!Rm(veU)N+&44!~;Zx>9}MTmn7yTr|S5n zCKlXFo=*{Eh87LWIhWc*cR4&O`Zv6Qo%GU7?ijWsnF*DqI(BZ){f z*tZV#t;5!LRutz5LXeoYE6Oe*#+o)&$xBRswbi>32YCKr3R4o&npz<*jFl+rT!&IXq3x zPNUq;WPy|*O@LN`nZUjQt;-jhKq}$|PyS6Hc?SaG3m_2t6YRndx$r}ppD)#I;Qx)m zAP6c6MCm0Fc1eVhM6 zXIDDqo~8<;bjQKvJVsbv)Z;GdaYW5pd^!K`=SWXn&m2LlZFPY3QAEKqoc(w$h&urf zpPzg@KVDNbg2=tZCR}0@Vwj*O@aiZC(v{s|c~vfi*~{V=a)oWx literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/BeginnerMissionRewards.csv b/titles/sao/data/1/BeginnerMissionRewards.csv new file mode 100644 index 0000000000000000000000000000000000000000..8e24ce5f92a0030feb9c00430334e70cb4bf706e GIT binary patch literal 812 zcma)&!EVAZ42JKK@(z0dOVn(G-Ou#M{p$YU729QK^=H$De;E zv)S9y9%|>T-_+-G-MXEL}Q%KG~E)9Hk-nv8g z16$votnY3(B-}it_`N?~EGC*pO+%w#C}Dz*Og_Qn2@`Z=%miZ+CTP+M0W<#Y5g`XG zSs6g!68{rXD-sMvhNim16s>sj=)*ayUQ-?nq*XsAgL~A9HyJS#t)8wo7tA~|PuE)r kX3;an|Ibhersx^W$UNRh+)b-eFy)Ir?}Fi+)k{zJ3p7a7(f|Me literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/BeginnerMissionSeatConditions.csv b/titles/sao/data/1/BeginnerMissionSeatConditions.csv new file mode 100644 index 0000000000000000000000000000000000000000..ad97ac70f60d81e53fe8d5863862f7c65a9e2a31 GIT binary patch literal 419 zcmdPbS8z&A&&5UB(tDc2X0jb41mSz^ErZ^^NWTuv- z<^oLz+Q-XfXlP(yr~@Pn40J%Wj*{i$#wCv%*FEi+`*eTvi-y+6&GR2OH$QIL{nB{N;*o98|OZ5>UrEa4@|B@ z*Wb7rr2oaj70;LKdfYe_tZ3Qe#+JuT-5`Gg&41e8^rE5pF+?FAcc9n~bPUjp#>rqe P80sh)09^vbhP+$=LfOb$ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/BeginnerMissionSeatRewards.csv b/titles/sao/data/1/BeginnerMissionSeatRewards.csv new file mode 100644 index 0000000000000000000000000000000000000000..c306a39b3cee9e42c66d0534c101523f9913af0f GIT binary patch literal 401 zcmZvT!3x4K42JK6y@L-B*xK$1+{uF?PP`WyX2G_j>yW*@nWawa3Qh7Q|5sJJJ@(pK z^hZ68+Sv|exZqQIbx@Gq{x?gybyn#>DxF(rjI+_d&IA4|vioT=&;^gS4|h0wH=qwQ zO9O?|$Zqm6AE!!sxH>WB?TWKQJOX*QfDb0YJyV8Cj6z^Ktov@jR6f%sG9 K#5KHYS-b$G%#7dw literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/BeginnerMissions.csv b/titles/sao/data/1/BeginnerMissions.csv new file mode 100644 index 0000000000000000000000000000000000000000..56cbf191ab3241eac5b6ed7a7da7d8d18396185b GIT binary patch literal 121 zcmdPbS8z&A&&;E9od185mmX8ye^v7%G@s85jT&SkM?G0unTW I3i5IR0K;!6{Qv*} literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/BnidSerialCodeRewards.csv b/titles/sao/data/1/BnidSerialCodeRewards.csv new file mode 100644 index 0000000000000000000000000000000000000000..556883d91ce130675883d6f214320f6991f0a7f7 GIT binary patch literal 301 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 SE+HW#Kw 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
    tQ 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/BuffItem.csv b/titles/sao/data/1/BuffItem.csv new file mode 100644 index 0000000000000000000000000000000000000000..b4f3fcdb03e74bebec7e4b2b697930570bbe4750 GIT binary patch literal 417 zcmdPbS8ys#OYT;KchTeK=Eu#` zA2-efN-6Pj83DC7Pkr3H@^RCK$IS~LH*W@-`Mh@%(1e%m{c!aJZNW4Iq#c`$#yUz* zJLW!{GauyOrnQfoS3hoE^SF5?hyimRnsqOybw6F+{kX9k>?sUgjXm%8Oa}V;apNk8 jr%ZsJ0P}Agz literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/BuyTicket.csv b/titles/sao/data/1/BuyTicket.csv new file mode 100644 index 0000000000000000000000000000000000000000..58f0c48fa6302b400f7e13b279c3666b5f80951e GIT binary patch literal 300 zcmYL@u@1r@5QcXW-oXdBq});3y0(LHb1?44GBhS=S~~dl-T`75_BZu+&|al z@$~ULL*>goM!yD_RzELs3K32|X03$r7544+)(XJ@@-bQwBk^Ihj1D?L!=X(=QXFGZ zc*shh6}ghd`XEfe6YB0ggP literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/Cap.csv b/titles/sao/data/1/Cap.csv new file mode 100644 index 0000000000000000000000000000000000000000..2d577429d71e3926110591040d3ead1954708eb4 GIT binary patch literal 27 gcmdPbS8z@&@J!JODJm^4F$A)CxeRp-4Geg>0Bk-6?*IS* literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/Chara.csv b/titles/sao/data/1/Chara.csv new file mode 100644 index 0000000000000000000000000000000000000000..00ae23ee17bdb3819b25903ad43584513c0f7944 GIT binary patch literal 945 zcmZ9L-*3`T6vy9}?0+zQZZh%rd?SQl(*~0g9`MD~t+ECv38ODQjo#?k#14(iB(ljI z%+Zap2r{UP{xO%9_P_9)Uc|(NhvwY-x!>>kp2Nz@t=NWAQiOFrsT5RRE*2C%q3Y{u ziI-I+9~NW9LP6Eb%S#cSqh^m1o02NWbD~z#%0-U9&2!#yosyA%b?ttrO&tdgV^5xo zg3K*1-9hLpH7AtpLOr@^=nBWfQ?nm+_lxCyvb=+i+rbBciKf!P+yw?zZYbHO<}n;e zs`8Ry3#r-Xq5pn|VNyH_*gcfGro^IT0QHon7xhreYaY%%UisbbbV3-A5|RMiXF8@s zNrMu?+LE-*7ixKfdF;2`p%rY`g44!aNk{?sV6J3S^E_0_YiskaM!$k>Yqn>*z4~7% z35bVC^eO35v(4;@c~t{@ke++uOr8Cpa^tq`fLII@r8r=Z5IdvhB_${n&1(4&!AQw~ zlASQ84n)PMXhHyL75h4+Cj5F(&lpBdWBm*raOXA8W~1M3?}Ra#G-e(FBjKy()EuHz zDGRfOIl1FE?xE>5-_8}}1l|sJ0X#qg6TA%psNwbSjd>LZDxskWZUH!giJD_-+CapO ztjd<>zXO2c=}-fkCl`yrWCimAVee?*UHE>w?swckQOg;{91IymSkbpzQ>XTCV1kGY?i4IL z?$kTLQpPJoXUPPuD&2Yw;k*5B@BxRQluAECY86H{9dG&73oOGQ4mTIuso1n~0JY@P HB<{l>yqb+D literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/CharaAttack.csv b/titles/sao/data/1/CharaAttack.csv new file mode 100644 index 0000000000000000000000000000000000000000..95d3fe490f2936b5e9b3522f30bd5af049bc0ac0 GIT binary patch literal 163449 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/CharaComment.csv b/titles/sao/data/1/CharaComment.csv new file mode 100644 index 0000000000000000000000000000000000000000..28363831fafb602862315504601a539c4caab6e3 GIT binary patch literal 35771 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/CharaFriendlyRank.csv b/titles/sao/data/1/CharaFriendlyRank.csv new file mode 100644 index 0000000000000000000000000000000000000000..0e39ed18a16b8c214264ab6c4f6aec06df017d93 GIT binary patch literal 913 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/ChatMainStory.csv b/titles/sao/data/1/ChatMainStory.csv new file mode 100644 index 0000000000000000000000000000000000000000..542d3b61aeef82a56777ec0faf0efb10db1f555a GIT binary patch literal 2392 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/ComebackEvent.csv b/titles/sao/data/1/ComebackEvent.csv new file mode 100644 index 0000000000000000000000000000000000000000..2c8e775e37d3edf810cd0ff6e1165fe81a516714 GIT binary patch literal 417 zcmdPbS8&eHO-)Kn&UP(J%`5Rt(Lvz{mnH#)Tr!IbauO^35_3~^f>O&9i&BD9OCVA~ zsfDGPMX4@{mBl*2C5c5PE{P?nC7D2lu6ZdiHZPZ{e%w3@?7q!PI>tK2#2IKpq=6>H`W66*l$qoJ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/CompositionEvent.csv b/titles/sao/data/1/CompositionEvent.csv new file mode 100644 index 0000000000000000000000000000000000000000..a221ad538b681425c6f5e74966e1518025742be4 GIT binary patch literal 129 zcmdPbS8&eHEyyph($ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/CompositionParam.csv b/titles/sao/data/1/CompositionParam.csv new file mode 100644 index 0000000000000000000000000000000000000000..7314322e50d3ad7429a8ce3f6769c72ddca728e0 GIT binary patch literal 104 zcmdPbS8&eHEyyp5yR smM3PX=4IxkgLyEO!KDQS`9&o@`RTk|hB}4@20*N1pa*6e81Qld0JRAsXaE2J literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/CostumeType.csv b/titles/sao/data/1/CostumeType.csv new file mode 100644 index 0000000000000000000000000000000000000000..bd1ce898c09687eac9d4c2d62e6753ac76cb8773 GIT binary patch literal 209 zcmZX}y9$6H6adgY=pUjv=-qxv2M2q3qfvq!r6?Qv`)uv5=cH-W?w7l*!RIhyOUBz= zPPz4T%-B5)vLqg7t`)+BnsM33VUYh#t3}9#!{oD|Ie_<)I&}C=MWzMxUK3Y1Gv0mI Jkdq*oj~Dc*I!*up literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/DebugValidator.csv b/titles/sao/data/1/DebugValidator.csv new file mode 100644 index 0000000000000000000000000000000000000000..edaaf662823e0f03a21b6abc3989dbaec3b46920 GIT binary patch literal 356 zcmZ9H%L>9U5JmTb{~)uzU=pjMy?bO``?8(?2upxM2)6*e zxf-m_Yu6AqAVuMQ2Ot$7jewa0`v@HV>u+3CcH%H9RJ=xa?n;6NX{C%3lhIKyP7ub` r@@__f*-XECDbM?%h()0#O@vRTm{@k85QZbE>^YkuXpBn6G;aF^Oxdw3XdemDN|Y7Yf>8D@+{L3#teEIS3Uw`xG+y8@q|L-5c{PD|wzTSTL z??1oZ{_u~#eFN~jFW9CWSZbmnkEp200dS9s1cn^&(jFBpka7@=iU^h*dsIZQb@W|?7~!sCwRaS-Yl z9uI??57)tp*5R_m2P-m|zs`yl80UyvVnqSgF+5mNfWyb|U`6O=2?sS#Ruo_z!*d-2 zJXy!^jEcDY@G(4DkzSC;5W1hNXn{V4Co3|zj^W9Q0$jSIqLUQ`xO69Y-FQ0L!zIzAaL_S-W??9eNv~J&VXKim9BT*z;V|*Y|7%h#FDU5oM4}^-i zUV5M!NEJps$_HXaLsMhqibR{n2o{OfsUAoc=ex#;7EFaN8Y5d6EsYT_5^WkIT@fR=U`CW{Y92uN? zGj*+#fmgsRXP_S_gC`FRzCq3O`~AUBYcu#pTUi|#?#E)<7dDva!TOz^0QjX{Z^Q3n z2gr(iTl65-RN^BOJqV^^ADQUEo6EpN4}xh<1Cu?VGb{b`ZP^1c<+$y^k8$jJO^Zqh zV4??}BbgGwL=ViQ`@lpGf@ux}6Fmr~xe!eBprr=9o_#yz#JtPv(}4_kkW6>tiCT)m zII;?-oS196cTPDmneN0>PBhb;c*=>%bjP1^B5!HUNq=2%*Hj^yH5KKMQ%*D!?p+L3 zFw;DG%86#06HhtOOmpHXCnnRKc*=>%bSIv2A{lz8{Sjz8<-}yV6HhtOOwB#4$sW8q z@stxYZ$LMm;OK#zXr^Z1cFKv3u@g@@F`4efQ%+2#JMokgKV+NbME(hoS^Rw_PB}4| z?!+l4Ces}<Cu9|XUGTl{EPBhb8HRZ%)+SkuE<-|-l-BnXgG}Bx) z<;2F=RZ~t(rn_p&iOF9*A>H@=)l}t-s zV4?@HgOrP`$#m~ra#b?jJC|JbA*G=-I0T=EsE~b#TPE%~DhCFSm}wIU44yaBCK4Fj&c)P3 z0t4@uX%h(yZogvcZUh7Gn1L;Fl7oSFz`V^WFz}9AW6P40xP2Hzh6Fqo$qEedIwEGlm=)_E1-HA$RX4-v>qEedIbSEmMfq8eLQX0?Q z+e}nSGt-@@lxC(oL@BM9HWQW7%ycIzrJ3pORZ0W1d=TEzyjDsx(3{=X?mNcOQkfdi5|q7K9Q8tYE8QvmD0exdq*j)nC2a&w9eQ&N@-@gca+l1 NbnhsofqC`L{{UG~I@kaJ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/DefragMatchChat.csv b/titles/sao/data/1/DefragMatchChat.csv new file mode 100644 index 0000000000000000000000000000000000000000..6aa812e5eb6408e0c3d5497636d5e8643c2a5358 GIT binary patch literal 760 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 SRfAf&{8#~du?Qk>fc+mr6`d#m literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/DefragMatchGrade.csv b/titles/sao/data/1/DefragMatchGrade.csv new file mode 100644 index 0000000000000000000000000000000000000000..b81e7bf82d2eabd7e386f7542292001b13f471fc GIT binary patch literal 22852 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/DefragMatchPeriodBonuses.csv b/titles/sao/data/1/DefragMatchPeriodBonuses.csv new file mode 100644 index 0000000000000000000000000000000000000000..eb348f52cd4d802bb97dcc9288bbc0db6ee92f36 GIT binary patch literal 134736 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/DefragMatchRandomBonusConditions.csv b/titles/sao/data/1/DefragMatchRandomBonusConditions.csv new file mode 100644 index 0000000000000000000000000000000000000000..47c2e0167aa1977d66b495f07ad7782cd7dc0305 GIT binary patch literal 965 zcmbu7+e!ja6o&7E-XZ3yV1rKQZY!cLgs3N&(#i`RFuN&&ac?M7?BF30t;`CIvZ4c> z>tWW6lW);l<1~l_MP1FX+56w${?_kub&UGvLdv{H3C}J}DM7Cq7*>Nziz8~#>ks?Y z;DncrsiA-pX5&j<`>*ktR6A_M#o#0&685K-VI;O`&=@Jryy z75A!<->*l~wdl5lo3(9o>&+-s8tb6#NK9t!ZQYb}`k#azCg~3`{WW1$EK7==nLjlVcPfXC_8Rk{>OM9#Tge?CD!5IKWL79t1D49-rp$|CXaSfYhl`3J2MG*PNs&`}6Wo#<& m3V~onxTRIB13x0&M3<~3g;~7q=rj^(BbM)KmTMVtW6CFXIS@er literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/DefragMatchRandomBonusTables.csv b/titles/sao/data/1/DefragMatchRandomBonusTables.csv new file mode 100644 index 0000000000000000000000000000000000000000..6c8bf15e88cdd195c68fb4a0ac1ff322f0bb3f09 GIT binary patch literal 10097 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 au9M72W>=;Y%t&YtJ%`LlV)rda%=`zKuf4+n literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/DefragMatchRareDrops.csv b/titles/sao/data/1/DefragMatchRareDrops.csv new file mode 100644 index 0000000000000000000000000000000000000000..50ec74db2cf8ed58e7d8fdcff554b4576199c970 GIT binary patch literal 100597 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/Enemy.csv b/titles/sao/data/1/Enemy.csv new file mode 100644 index 0000000000000000000000000000000000000000..8f5323f5e59972c5170459380211a0cb8baa4ad4 GIT binary patch literal 3606 zcma)<%W{=f5QXPf`3@FisyP4UeZK=JNMDY7tde#`jaotes=N8ulVcJ&o7++ z@Pn!vRA;NfU^r;_a3-gP+^yxblDnPU{g%^a?$&c!I%8xlm8UUxqC1|4uxz60|(IU%4fGZ z`gVqIhfN>euYE2_-qO!G@d1;EeYE!@)LHo)4%$fSj`JnpSGjW}iD*fUF#hs~Ld6_b z)!dl0M37kB7GvqQJc}hfw?sRDSjCCM=egT52@sOtA&@4P2#k~yzPg+fh2Uuzo&t+o zyocNL)Oqa~x!|9QB;1PFN_05@-X(xrX0-ssXVsS6l^|L3XWfheCJai3$?uVVxE0TX zd1WTS-1Vcu6`_)55RM_iZ-j|R#%P@2WAnV2J0x^9cVr4PUfNI_hQ<8{zDR&R0tL}w!bQP+35jzACbPQ~*{*-`yd(4p>ogQ&sjb>|0|zm-^OL zMwAR>5m-^+QC&4vEmw4z6?kx&P*-UR+t$uy22=NVbXKeb$-Ai<+meP7IoM_nPjv?X zzdrJC!@WkdG(v>e+QUqE*uS!K_|vjSy}F~RTAS;A5yeo_sQ)w6*p$(#`9OG+y?}o9 zx4wD1^sSsw=MZgS`+h(F8E9Gr#+XlLp!?}^l6l=HjRus??(YBhtxv8+8|AB z8tb{9t5MzgplJrcWI}Wlo!3zmqGfN|L(B@<3ox0E%vosC{CqE33}eRbKxP2Se5lnF zljcFiWD7LN0&hecoM`4pBj>1LrG9uXfh=*amKK)h*Ox%)} zsRQQHK#Ic9Ex{|M{g}p@+7EFU#6w;&TIGlV4jF5ByE^q^jH&U?<%D>tnA=c-hOOk3 zzR&62XwnA2Z*c|1U^)2;ntm&kGqF=tmkD9C!DLamwap@9{<~^zRkABHkmf?+k=^y9 zOtzu1QT%sNjtVC{R^iZ;GNMOpAFo|&N~LzCc|`4#*|l=wNo#NYDRshG2-5mI{VW9O zlxO=YaN$4~r9^?NuBMJFU>@?PAA}%%5RSIe>FYrLi%8T^Qn+59YA65}=l`({#<^&C zqNw9bIUaH%?{x;_uPmufc+ZT_iK3RtO52qV_6bU1FwfVnjD+Aks*hPm-pJZ;7o2;Ou|a)^|y z{ir4qyMUFaYXOX|N7iv^UapR~OPQa((9(~Bm8CFSXqgbz@uMQ}W(HBlOn9mnb?}fc zZkgWk0d6&}!$cI(KHiwRe`EsK#nL>7gz>3NNa6|x3RgHha#~ZbvU358F-Br>&NV{2 xvGVv8Obre|TyZgmZqp?P31fuHFcc>N^KUd|VObvX;Q34)|M71Y{1T+y^e--NS)Kp@ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/EnemyKind.csv b/titles/sao/data/1/EnemyKind.csv new file mode 100644 index 0000000000000000000000000000000000000000..e969dbf4570a3da275935c3e441be673f07441af GIT binary patch literal 49181 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%0DVi~8?`%V+5NLwD_i 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 E04S3JtpET3 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/EnemySet.csv b/titles/sao/data/1/EnemySet.csv new file mode 100644 index 0000000000000000000000000000000000000000..771ed207a94053070b94348872efda31697c4975 GIT binary patch literal 1580 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 BYU%(0 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/EpisodeChapter.csv b/titles/sao/data/1/EpisodeChapter.csv new file mode 100644 index 0000000000000000000000000000000000000000..834419fb6cb1b705833cdb1a2778fa7ce1fc98e3 GIT binary patch literal 227 zcmY+-K?;B%5QX7=&>f<+ppJTiYSAXTf}l`PB-N(d=hQ&c@_jt`rL4L%A6tmcW|>(s$INAervbkP8i>!Zfo7Ot J1I;qS#tnQ{JM{nn literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/EpisodePart.csv b/titles/sao/data/1/EpisodePart.csv new file mode 100644 index 0000000000000000000000000000000000000000..97134fa848acda3745fface670e1c2bec3866f84 GIT binary patch literal 50 zcmdPbS8y%JEY43!4M;31@l4Ti$t*6&Nv!ls%uVIxGSpEreA&E0iI>YrN684n0syF@ B5F!8o literal 0 HcmV?d00001 diff --git a/titles/sao/data/Equipment.csv b/titles/sao/data/1/Equipment.csv similarity index 86% rename from titles/sao/data/Equipment.csv rename to titles/sao/data/1/Equipment.csv index a7fd263ac4672e89dce0051b44239d6e0c4f3fb5..96fb7cba7e3ad1946a6746eb2b52e170524d851a 100644 GIT binary patch delta 553 zcmWNOZ%hnu9LD!_b-U{7ic}({NS${1tkGt#cQgSW*BgvmtgvzyH&7ZdNhS|Pe z^#WtF`7<-m<^{$WTC>^oB0{WLN>);NL5$yv@4M&wJfH9Lz3?4ZrlB#J;_uu5Zz2qQ z=$8zRX(Azi{C~=9z$8bsnP7y@38@SGCdEM$Vh;XCv)%v}gk*rePz`w0-~b)Uwlx8uJvj$FkrDO|2I?$4)2W=)J zq}lw5Zi@j@v;MDCr7uWD#(SDJDCqo5#a3-iQXW}x;H7LWcr7Oa@?hgQujYn=ck_b5 zN46kvAb%0~p+H4V6%O%P(I!x5&xg1i^UQN9fvY$W;&uI?-3`#`@dryv3c<6R)j4lU z!y#YG=452cjJztJ^MY}=j- zxxM2pd+W;}Lpwk7euEy;ziW_vjf(U7Zq?MwJqq#T-Wc%LK4oWVN(3vL6-RB03TxXR z2p&J+fIMlP=e>h!>-iz|mM@3vAVuvxGSJ>Fr5)Y!y5ppHkMzi}ng(C5O!!VoOXnGx K>%8a}67(PB$kmJh delta 782 zcmW-fOH31C6ooSsuq}_aq(DUrSYB;ykqS~?S}Imiq>2&*Kux zU8sqRE=^d-tlheC$HHh0Q9@9oQ4u8~#K$@R=6rMR`Dfu ziDz+kVo8$$h>iGF=yJj*lwyhHOpMz7Oj>lGp?>{Gs3Ykg0(-K7xi_VZ7);d=VMBmW zjm5-*DU(=Bvk*peE>V(RNepCo0P!$$0XkuM4Q<~10YP<^i+TSR8}nORnV+|=qtu&y zkjYF=De*3M8==@7gfmYLP@B)zods-0xC@tItVIbtV6#^d?GBDDLe3Rv=l18&eAhez z#jRzoD^4cTcQ|>>SMnAn+rvqPd*>ghvvdPmQ1(V~&F+#LFqF&jioAuqv#}zF2vsH$ zBUNVJ8mZ=FLp7E8=K4hVG#;SV z_Q-jIXXJ+(?v;a1oz21t^--UE;aqG%4N#AM! diff --git a/titles/sao/data/1/EquipmentLevel.csv b/titles/sao/data/1/EquipmentLevel.csv new file mode 100644 index 0000000000000000000000000000000000000000..68f4e439b1b4bf1e618e296d94a5ee38ea6bee6d GIT binary patch literal 2047 zcmYLKOK#mT4BS89-Ju5{5KE*a>Hu97=&I-i3iK@sq+hf}kKdW0;{=Ig)8uIQ8T#qz z&D)=UzWn(5`1bq#tc%JSJH$f~gqlVW>vd{d=7jP?j9Qu#%8PB==7iz}vHf7`xB!5UO?MVk=XMlE zxfN7*ynyo<^)@UB1(RZj4MI&`0X2!a zKDM`@yxSyHI||FuGtz2}6-5ifCc#>(%KHEbKC`5JKh+=OfS?kACYVY=bJq$CR8q>b zQ5#I9rCgQE22+VC&t0*>lxVg!S@+upQ^{$2?V1gy($gN5{svPC3av#-2mw%^m{!6TfO``hqGd*)-(J%i(9s3 z61tT4V#7M+EtPbgft^}-aq+`Ph_eB|U|ofWFOgO@Mmb($@j22+a?UQBV|gofvV0Y* zPbBVbUHsaxEWaFAELIvr(3aOTu-3{CyXXQ$FXV{Iyp|9jt;^akUwpeRtG`(P1N{YW A1^@s6 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/Event.csv b/titles/sao/data/1/Event.csv new file mode 100644 index 0000000000000000000000000000000000000000..18a37edb7eb41afbeb02570bba4c6b2c6c3ff8b0 GIT binary patch literal 328 zcmdPbS8y#$%`5Rt(E-yTl?ACfA(vpB$lLt zd9HaWV0J)$aY<%gIzkdE0F!slNGw6s4HJQ>@JlTRI>RG1rvOMfrZ^?$<)s#RrtoqZ z>KN-NJ#Jp}xM|7b=FN|rwm)v(^SEgjkgf5!x$SY&&d1Fino2rKWMGPMLEh$!Vs40M2ymkR)T>t|vB literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/EventItems.csv b/titles/sao/data/1/EventItems.csv new file mode 100644 index 0000000000000000000000000000000000000000..3842ab5dd951fccd1c73b27c7bc8a05fe50c8b4e GIT binary patch literal 1656 zcmcJPyGjE=6oz}jcaW_IGP9Rx9$+zzDGDmxI(x_Fza{Jubw#rLxe|!3F;5jW4nNp@|M|+ z_u^*SO44|z<(QtR8?r1X`1bY>?+x`6!i@!+IfLQXRC|M9-V`xQPQ@w4e@ zS$yE|L4^-V{O9v{S$yd5VTF%KJUg5^iD!qiY4EEp&ldRt?D!ibo*TcCB%T|;vhFT6 ziyMxz;_3&~F9@g3c0jnWrp|l#=NAyUmPcjF740ZHX4+A9%+}GBwp`JgvOlENba78u G@qYujZ6~Gx literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/EventMonsters.csv b/titles/sao/data/1/EventMonsters.csv new file mode 100644 index 0000000000000000000000000000000000000000..d756ff52d736de857c5c5d68ad9188f45c783230 GIT binary patch literal 548 zcmZ9JI}XAy5JY<~iprjl3l%fbD8d2IgeBK)(I~=^5bKr7F~f=Q&kCjlr6|JM z3Tg>5AyZqCoRBafldRa75Nb)ugbX$)7LuHhFd<7Tt54LDk_lN1DPBc#Lc)Y>?Gv@6 MWI`5w%C;e)FCD*Z82|tP literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/EventScenes.csv b/titles/sao/data/1/EventScenes.csv new file mode 100644 index 0000000000000000000000000000000000000000..d5cde61d1928409879d498d8f4d3decb53c2faff GIT binary patch literal 9002 zcmai(NlzSE7KQgM^?zu2O{+3;&SgpMMQ=(ib*Z+N)y1Nun$%q?sdq#qU?8zEV5S0$ zZDz33#s)K(;lK1FrWJpo&$%};UuH%mxiDba@8i9D-o5YKn_qqPmxsR(|NPrO|26#c z@ZY~5lE2`){QcYi{yIGL@Yf&y^UL?c-~2N4?GL~GI6U-^$Nzr(lcV4A`mHeZ_4mJj z^Z2LXKmVzabB6Lc2VaJqp$GBaGk^2YxO>KJ#_qd#)04h$tKcECaQDcc{FqXF$)3+BF;c62*2-dfwy@N1l6CLjyB!MJw<47kW#N8d0a^w z%94hXYY|H0og44M)SqH6#+^6rE91==Z;Am)-wjJ*L`xb`k`PgUd@MYjV?fRt(ZP*z zdCi?#>V8=UgIdy{l7XN`drQV$FdpK%VLT5oFf!t58H{U5<4OkN8o7(O+j5+#aO)C) zDz0cxvRZ(Kv&>6g!7<7NFpvQF&o)Ajr|7%5jNe{XEo%7f(8749roL;uPo}R(KK z($p_a{ScI5? zf$Fmon{nf9-d(ytR%$7s?4c-BIVVEZR4C(K8}|iot@pG$?nD}I56B+rERNDuTGADV z{;E~lpTPx0BD^;)Dn1hQh9@oKi<4uG%9mO|RD8fXDt@J=OZMb8g0Tf&#_MMIc9xi`V31e2d_EIH^(rm(6cewng!?nVguBbe zb8jyiB-Mn3d(iJ(l(Ev1QAyFx0bVnZ;-{K+Qn-hxuJrPsw8DAUlkJWxZO~A{385_tHU_qfW#C9!`q#gP;paT z7pO*zlk39lF8lAtajwogRG`^#coR{svW|x6lO+D76`^QzCK@}}K;s4HhU7*ICp$t8 zJq(_q&JAIye>7#>8ALgL{el>|(R2VXOPRZo8(rdV@`;-Yx7YpVF^=W$B1YHx)TByL zv8yyzO5BJLkf!0nhj4)}ufP2%+a!2AH;P4-8ZLc5 zfaFezl@9=UqD=jzJlr=dpxrm5FNLX7lY*DWUiel;tm!ks$tiv@UW4vmU+z+%CdEw_ zLVX!c6m&KX*WYD zYEs(-04e;-(_rBwoWWJnQj{{Jb~UA_Nj;O*kRo;)u+oTOaCG4})`N*1Y`vPhhe0)J zQpvy&HL!@6!J7+DU|A-NOGe)iPzNNid$ZB8;2ummaqf@A{;%!Z?jV3e;*QeD#F zv&$&~mPQn5M3W-YhWSN01&LlQ>r3_Z(!M2b;FbKbolL32|ube zm(rSuXFExZ7QN@ZzqNaNwWc>Ar9-V-2S8dN=%AMV_G~e!Pm?F{$SZyP)0$Y4Xp&b= zxFu+UXIhJYaIxrnD>zVwCYB(Y5HFLBjZxb^N8d>_{^GUnMq=Cf@YO~;AdR-b>`s@#IYG5&!+N^A=Mx4C;xdCTd_QH?U~m+N@0b zCO9>@11ubHxbhvil!xO#irsc{1ALrQ5F=-|*2?8hBPTeqyS%pdnK|HCtlGG=n-iAg zz#vBl7VA};m9})kk{lRh>%i((;2cHfxf&y6w}2!89Ep9~Uv&CjhxQo`R1V0e4AnS1 z`5dgg$7>oqdt+R*V|-0}>#&1qTgOZT2ssxKsKXd?vG6r9LzoMm<6TJJbm9ZF6M#mX~fim&xUNnk1 zd7ft|6jks(*M8kQq!=x9PXPy@crpLhZX=)XD+CV8teq_6~$LPruHh!h}5Ffqb> zhZAKvNyh?2imKKw&K@C!KQSI%Ku+Z8YuqjWIg%Y&KkkoBU^^*gO5H^a+huVki>cxr z8V>=%ko!!oIc5PcQtO!#S&~RpReM4bBr;yp)HfO6`XWY=I9YJKq@&Rctt?8ks;WC7 zidvyx=Dy(NUdBtyNL~c{?s6krE{hVms_IOLqFjx2e*$;58Lo09k)f4cE?QN!jwMrC ze+#ceGafk$w)sg&Pr}%xqLTK#Ma)-v{Qmpfs|6YMVv@M4=SZn!dk4uMZH0x!{8?=V z)3|i2?1oboH(k~&OoY;2SYQw;7{gd&2Q7$k(bjYJ(?-TF2QC?MS)j7!n?E5|@#jtK?o`R7;h z+7xD(!2)V%(;wT5KJv4mv~Ctd-GHJ07Yq|DJ=?~a{y0K!DJ# zb*olT*l|N;=+6%o+Q-azsVtDv0mwE$fROI?d<8=%9&z>{SbUN#oh48@5a|3t(AqfD zkhw1=<1imj@qvOqH$91G8Hs4fb~2J#ZQm}g=p>!jfG!TZqU&rEv${C2wDZD$zOReJ zKhyNLSy^2iSlV_C=;AO@;Pkf5>eIymr)}4OE)KZlw%;>#=dW|L^BT~_0he6+exr9` zY3DVdivugU`~Bwc!qT>DKoZp0{sPA2KF3wLfb*v$%rW!YTFUDug8e;0#(m;r8zqz0>%9Z$I+U!<@iHS_=A4*$9!ElDv z5-;e$8bDie5X+63E11c|ax2?tMP$$b_6F=7SQbBKOiUIsFE9&~6YUVijMlh*J5-~f z)j@kuhy$f(!bc|(yDM7aikm=tz+T5G%)6YNs z`7giz<>#MxsXqRXKmPT%A1+VNuRQT7-+uh~ z{jb0L@Y8?(`d=Ua_RG(I`{9>g|9&YCcyoDpSqIxbzt-Ph%P%_2^$8Qt8|JoyxjkXx zdBaRQnCS@<&#&LVT|O?KpZxfkzCJ%bKdwCG1^(!@PyfICyz>0>a!fi9nu?M@Cq2Yz8>AugZG88mbD=s?Tp zw=?*=@JxNRUbCM)d(X%YEzWy!`&VF_|1!ll?$-b)5 zanZL%Ure+KvJ`)tEK|bji@d|QH^yD<_OP~+6j;sG_<%p+2R{6q^o!dK(|L?LK4v}iOsW%z zZu4vbp?7Kte3g_5rkQ}OQDE(~6xKvz?2oI#TEGZynXlImJTBLMe%?Eq&6JGCuO``@ z5z2JESQ(SACK+>XCSRJz_4<*?X4n@dPphj;(3HvM*Vo6RLY>7@CYxWlx|zJ@Zh85U zCdt)gdvw-2Eu^eBzhrw*`UJnO;+I3XaU|-8tY2e0LS={8S22t?HDcRs8Jp!=K|5l5 z+>Fa_4k3Q5F4t2pHN|rn)HhL#JQy}Z8N2xf*D>w;HzM2^>}76p#5$nsGZ(vlDk_i2 zc@x8wLpz)8tdz~-7~sYEC26zx1SUwqz-u7MZM=-d41Z{`Sf#ApS?tuAve>-3t!z$O zY&KC}KIYZQ!NhQ~>du8ka%8gV*r#emXR?#0Y2m8$z+-c^GN)qf3TA$IhiRO zT5M*i`bGT724~BZ#pcw^*h;iHCr_r5DyfpB%#V^_i)UFJweD@qPv(`1Vzb!ml(N{I zQum?aqE3|&vzD7us-ng6pocA2F&>5BWPYjcHOpO0GnPY1*l}lUmG_*lXRRg}*&M!( zT4syyvUm`Jv+1R>*DTg02xVR?OBAUpx(@&R{%tm`zCONqQ`%ayN#(O}xwH05*7Drf z>j&)GoLTg7u!gm(llbS!)WG{ErfTUxZ5%to$axw`o|GGKv)uBwk1cM|G~B$MvQR}F zR0Mf$R_umiB$jTqkmq9y7v3LRk~0=A%I9okM9;e110OE8btJmm)j|csHH%ekmV$2Lix;SRULnZH_g?F=~<G8F#nm|3W5?q&_;_>%ycawvWE>5XhXf>Q;3m@7#DogPXmtHN@3p?YK(Wpm8 zF+JYq8o*$29g(IPX-BmE_V;gJ9!VkXE#Ep`jMW3X$AGRHk8xHjHKMZBnkok)sxbpx zjm0VYqdCF@2L#tUvKdjqLn$hnlSW3<^{nE}dht~}BDkKt`|2jTe}SvfZXUvDmpVd3 zaTb@-8t8FX>%KHKE}&ksF6-;STQ`3RBSd6Q+}v$$<4W%bG?R*Q)1Y#*HlGK!K1`=B z_qvNWrpI-Uzkhp}3&iEeWp+O*!}uG1;);5AhgdyiKY=!(S_T%O;wn5M@LqwPYab?* z67kyAdTaMGV0R4$G=(+^)&1ZAWeOEtMn-nMu%>(DR5NI4O+m(~Ce0?LdQUU3(zH<* zS^8c(!~y0F<&l+UjnXkuVV)+;RIozSmRFl+w0wH~U`SfAK-bucd=U0#c5x)1xWcBL zd8J%u1{xc|h|vm#h%S-U8|+Lz;H`nKM)$jA)ikcHNf*+;Bm@W^SE!q@l&8faH}lPC zxogDW-~{pInF{h}F&O-73#=p5azy__z7Q51{Q zsWtpTkC&tu|X{(51xuFvicf7LO~u5HC@TD$H+;OO_RzD8bT+S+^L zE2Xm6F}sUsp61i0=w*WMYC`ooN-NE*FU$xUA6RQ{$=0<(gW1_OK3Quvwc;n=x{&Qe z?kgA3sac+KJ3@?%A}BuT_R6t$O)A=cU?o?Y$lhhVtZa8Nyv)QHd0Pz44|9^=9&)nl zYc9yvzEb6OpF=diE{Ayi*S!7e4K(bqsinZwRLrtgBH>wvFi6*oR_;v5iCwnV4tPkI zn<>XC)HcMRk>^D-?*UuJmc8R>yoqZdz2I{I9NKGfbewu!Dbl766I4Fb-)&&uv@l$% zay^s9ZX%p+gSDKUaWq>t!x}*v(R{U|6oPzhaNBuHdmQBu1Z+@>qFP-vL70IjxspTZgFbCo@Fz)t*}U1*I~9T9SmsS%?^_C@_V6wdAs<)NU#8d!9Fxp&6{Xs+ z%GFNG@YRlj3c=doRuCvE*saCr7o>X(SCOniZR%GhS)o`P){<509elMzOU<6gR=AD~ z*BRFvEknf`)}Ta%;>oFer>ENzU=ejdMz&#`z_O;Sd(FKyPGtsQsuU0Bq@6|xkt0at;VtztBhZ*ZqrP%iu2Xo zGc#0hiGIU78W-!_z{|3jh2m`xm+OAsm~vr+oxUbEQjmw)3wAW-u>V&nBeYkb;Tu};#sq<3<(+v z$uAfS7koe-#*4?q*wffD$d{>M$1D2d38;RlfW$?1SaP-e&0sZ2B#22UYfKF8OqbV# z()@yV5WefdsLx4{HTcGBWUshNFec|UIKK{!^ee|?VImpZz|P`zq3vv0q6vtCTy)n_ zW}0rHX%<`wx3YbCCRsrJle6xYy&1N8H^J#E-4nLz(!psnw0Sqid}E|JRd!@a-?$7j zUh8fX)&FW;n@uj(%{Rw71}j~N!^7f6In*S##jRt%id%;L7P`4is>YMdM# zU6#q9S~Ud`6nIYurOjcM)| zWUi*UM%zKXx?0u-T1ksn-9a51X%eYAu6+YWj`~*i;xe+8IE-8ifPJc8yo)Sr*+A>* zFMQAD`PeB4G9IrkJVx&1{BBg-Z{1qw>bl5^l4>Ils?^o$HPC8gCPu7X1FA-*K;nq+ z@+kXjq1F<-Gres>Wy>ANHS?O3^LXi$Zy2yA<*0?a##w54j8lP;5H&fL-6prS-mZX* zkvO|?qw>ZPA>#nG+_(z(8fgepnAl}k-@nq+NHDUIUl7@}J@uOb(r<)|PnO5OxS6xK~j& zdKE%Hnh<+hf%>Ml)+rO4w2r>YDP|~lYUq0FU3qb2uX?UknYF!o>J^12&qRD(QJiav<# z9Y}?l28>j&Hb^D7cf4ut=;o(>$FLEiso3%X>82o8a5}b>WF;n(4tfWRwZ&pR+B}A- zJ|``hN*=$(x0!_G)6u|A5yvN^E&HA`(P`&tGmV3`bMft?r=o7RaN0WtS@#{nK zvZ+N_4m&n0&A_Th01fvh)|mm-+?m;%EZRqj$sZCm9PW&zKkA_Ti|Zn1R(6R;<)uo3QlrMrF&(ik-F5;}Ki@VW+*Q^98o4L8Gy(E(1Dcpp|7ex$2zD zLJzxMi^_UeE9KVIdjNDKA<%R+?)Ot(r43(9$um8k`x{ zTQCN6%I{W*l~P-%P=kjl=SzEN-T$kKIH+OHu|^E4#!7~WUuK4PZKVbF`G>(8TN@_r z*X055XE9Juo~4VkTQtsZp}L>l=jS& z-Ohz9`7nR;B^Uu~3kGbIzr9V>XqA--6Jfi?QUZk_{H^eE+_G1wc6nNlaJq9u;p!M za^B5SEuhNF3{z0jZfv(@DPc?NT={BH7{>_@%|>ThZcIf+nvryS*Y!<1(CXQO<5>C z4OnHq_%t$5!+0zaB>0pu(E@Fp%PBO>n5fe+I?i)ym954Cs@zQ(C~CxE92o3vs}2hA z2NOR03%%S2bEi$-EW+}xbG{Ts0M&LWW$69mK}SG5>$aK&YpmigLCwo0vUU25S=eT> zAdkIi3j6(2-vYuH#Ozs$|HAKKR zd1d58HW>z;b0TsKC|x@QC;YNzK)t3tWET_LcE*Q_f!3wYd7nH*{=p}O*1&PH*= z#A|y1J_9hcQE3EN%{>_&TG<73Dysdx7rGa6>ekB*=5p&r_a|1)%Y{m@N96T4UuZ1< zPw!lhp_Fb1bir?v2g}89t}>;E%?yY$46ANTfmA0n7UszcS*iXmwsOV3$Q)ZME%71_ za{)#+M>2)RA}_F0Dclk-pi_%&g%>L^aCKv@Qa@B=;1^?+GMEXOhl-3~=NM^)S8T5C zOk{pMuEAWYPejdRi5FP)M`GzF3%r2Ngf+Vv8R$w)-chA?zIt8fE^xkon=J7HtBg!E z)02f=#b|Y53T19I(T?y=Ec4_Ox{Ps1%_X&VCMrpe;>CI{u)59}E|LK;kN~YtOw^dkaxQ6nXPHSs zT^RR|Su!8I1y|QO<3k_31$4@XI@$lvcy4J2C-^>S<78WD2DkL)nc5 zbB#$TQ4>cM3_C?g6kUU=3o|UfnHr}{jKAK2zM#uHnN>!<#l(I$mI!&pP;j=xZCQn)O7H$0Fk_d9A%gXu)ZTnBIWa^%0{>v94A%FV4^Uhdlw-#7 zgoagzyBDI{+3ARokky%xYjm7u;@FNsHSuIZhI2H4yxK)V;eP&33*N0ctBsm!*r|}= zbc;c~7soNfNm)?OF*8yfCk|v7*12#TF`SJsNT*G_%sK!&TxOADd%u^DIu3I;J~pfx zNWveEg_dei&E5VO&wz*A_5rlb-Ef0X9=%R&%R}zQ7+G!1@K85LG+du{#Vp70_L zhV(ogCKZWw>j$ab1SwyNr`I7*QNfHXJhgc$4ngpppPHknL*un^@o+uSia_-|we~X{ zOzZ(xEKJEUNGb+(Jl*TJwy7Cs0ow3XD>pJwVufJUKoqVaOA!KMtVZq(P1&BKYsn(r zes!$t#?osxdYYN|0jx7|ai6!dzFvFvC2W}us!YsuyKE-`Ib*uuV`}WPcR0KyK6^?d zi;XEJvduGS!^B|$VK)TIOmv!DRmj0Yvl|Imu`qL!k+0zkP-P-HY}8lJXsZ|~CT_Im zp@C+{hKcv_Smwr4njPNWozXI;Pxs%IiF}rS#QT|JvxZe4a@cgl#2InbpvuIAmNFx) z0@^T9DY5Nfowj#U@Ql7{WU(>B#MxEK=fBHM*F<2>wC@acnu+Z13@a9*VhvNy%x=M; z%0vttvV%z(ij+Bdo?)Ehi?n@-xR|k>8yY*JxH?j@n#K4hO6=ad>24 zrV;R1m5CTQ>a;kMF3^UF{v`9BO0mg_eA`nXi;XEJvitFHEho|p?4;jKiI~~RfI7`Y zwikvK3t{4zR7k1@RVHHK*o$IEoIK*a-eV-H^USA04eJdYW+@#R_E?RHROhh|#g4eE z-Z60`QfQxKSa0H}r1M=V0qU7JDtt403r5;7kyxR{*-61$CbGXUve=knB0axBjfsgC zVn$O1b()E&s)iK{VdC%ud^4J=L6wOa`l6@;I-L`dR1K>JCU$B1G+~U@GZBHvU0N5x z(Y2M{Z6^D1oA4xD5(bZOdL9%W2t~PIWem9 zj<&gFqLfr2n~mCZztFdfQvSPd`qZjGEhnbD2s@BKJ1?e~C>>R>&cfm6lV?e&0-a)_ zBvk$9L{9ElB%%t|8HhUuE|i4ovCc6O5%od+5f!B(xr30@KDa46Bclcm$sH6-2~o(L zfs?F+uBWBf6EyM9_`>&KOZS0=8EG{xrD}S@0zQGk5bG^$ZDQmirA%IJx1e}OwPSBz z!_n2aOj#tRVj8h2vQy-jHWeQ6+jU-Ue`GSBqtG8cg3Yuz2vPUy)rdbE&j1&7? zO+}Wlfy5Ax+3div?a4L*X{zHwS`@ZG4nHr^^StyNX-_svz12TFeqA9t;JBiwoTdnE zsZi?zVTA@0Q&uxXF$Ux<##S~g9tb~lKk+0zt!5L8QZ?NYH67KCqlSJyF4Hdv-WUSmHC%iZ)a zSF5GKcHH)nS9r>%Ev_Ki^Z8=E^ZCnQnFP1SxaxWxo-o74lgLT1g^oHdhFSa?2V~Zd z9#^PXi1**8Iamn#(6~y!5X^=@%8OnIe~ykBoBz5k0(Dldw>g-DSW`Q)44Dv~8J$5C zUBQ*7uPz*!Z#L=z?Stis`;jvebPQZw&O()v zcw^>qh3clnQmc~4T7~zCW@4cM0_Ntn(%eg1C71!t7rKSGLUe5+yX++;;{q;x<+u^X zk?6F9W=Q+_{oBI(Rtruwa0}cMF1Y>vn;wSdn_gU|kQ=iT)p0?(j^XPnrBLRSrK9pm zhRo5Lh2p|!;A##_al%YeS5}fnBH$J%uCc{i7gENk){bfbVj;r8Tr+ECDh@S;9 zJ8*Rq0IH;16K5yt7SwD|)~%Xf$qTAF#lBsfNd&Hrmhmf{RE$=Sh@|{##*h~Yk%Nyn zM7WTyirt&4xS(%qZ1WYnT?$fuHG{y_nWp?|23dYoYbKLon^EP@fw`<4=5m2LY{tPT z-GPFOC7WejjMy#Q>S87+hT3M0S|x*#%_b99fx0BHY_(lbzhm?|*Obj7lX`=`z9|LM z+4CCzcRuAoJbkLFi~hqr#+Omu+`_T?{ypL&ga@ipI3b@eQo{M@n;he6MocGe^DTT6 zhGE4*-4-yX%8d3bBxx8_^J_vNU8IBaskhZYT|Vf_m&Lz0WE)o!!-Xt1W`x8=I=Dbh zzDXG=#iE`J)NOlrwQ}pBL!@T`D;Cm-4)1F%(!m9)b%S?lCg#kPNK{ zREtZ7jMBm%9PTJKdaZ{?XcxX$(Xdlw#LWivUL3PgTKK~{PtV5D*@8uCxL}E?52!D%6)Ab$O+@bTt0@bW&A$-7IohIfhX{v$B zib{*aBeaW-6bo5x1U5R#z3A)G1nL8NoE7O6K&c$JtT;YGyXZ`@V5f+vGsOa(%8EKp z{BW1k@o=aCE;>+bSj#vpv^&qE+@TZ2f;A_GmUWz`bfEY_h+>)E`Z2;sOSZ*(rFJ<`f2(6B<8CiIm z>LYdDSi@~xJd8jcE`G$lfwg+4`bZ8_7*;II9HCuwrdVTjJRKgPUD#~`Qq`$E&GeBv zP%KzAFmax3(RpHz)ySQpsXj*jU{4LZ-1fk;%;rQViUsRT93EU$&Nrws5w8r}1cYBe z{`{f~zL@CE><)*wl^gNb$YNuPiDNDdOIIy zK1xSAQ!G$rA~|f>vFbSS!|yt^qtSt4!K#69V?36)p?5VVGA|!VJeU`2DwwN|hfw>Y z+UP{tWhXyhFZBJ}oqdU6oryyx-q|P^RGF9%D(-6dAMr7)!bInCc=clAhKYAtY9ot{ z87AK8aSiI3I8+VpG@YPaElx1;t~14g6$?oMxa4J8-7?7aW=FT9NwDLtJXsz!Fc6FiG6!h+cHsyiiIpTrkJQB#R4@Z(hTgR-zP7c9p$6(S(WEbW@E5T zWf`U%y}_WG6ESe;MI9%8py*Nh9M1$zqB`GopjfctLe(v=tQwdQ zU++3k?6G<#jtMLs_2EM%A(^N;kB?p4rKAd0O-vl2y-Pa(Fn78_Gcw2;bhjft5S!b&PD5DT5oiPlnq6$?`-$1*CQ%EXj`W=E?m z$((2%6^c{?Gu7EDDxj`UOqpnQ^mQfEHs7tJLdR-i;t1{CIx3)^iNjoP6%`JbXs*?H zN88-yL@TKvn~gp+BcgX??;q0)SVskPj)|60iJ6m3w2lg_vv7EX_HGFk&?zQbLUp=6 zRh=!O0_zMMH?o#cHCD@s875jpwffm|Vq(W)6%|-#;<&H3h6<=-;_yT5cWbERoSumk zO#P>$O`@JuTP9ja1zBuNW(2vioqP9*p&WHnnrn literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/ExTowerQuests.csv b/titles/sao/data/1/ExTowerQuests.csv new file mode 100644 index 0000000000000000000000000000000000000000..0b8a9448dc056e9a371820fa5046ddbee00d2cf8 GIT binary patch literal 4729 zcmZvg%dS*K6o%&}zJodAPT04;)YQa*2{BR53vlUy$pI4Kpu?l0;=l;e7)eM#BGCaF zQ3)gB!(bMzPvd6@cPk~_}f>n9A7&;f8l6*?)UEp-!?#a&wi%AlCAvP0(5i>os z)Zo-0lth;^H706Uj4d@fH3~(vw`Wa>;$BNlPEA4)HEK|&!JKxFZoRnuymcZmb#qML zZcrx(oS4QbQ|?3xDx3y&GD@8?0n$&4Brx&08u)BZ1 zbs{l!b4;Bkb%MZ&X`C|UPNbm1X;LSn)G1T$L<%aLCUr7OoigQ4q@coSsZLA(KK=6J z?&0UH6N#ytW9qb2CkULFmhV%d+=&!aI4#x5sQLSpD0dk%9`Rl{y)vPWf5x zL<%aL*6Or2r`^Nv_P^e3ok&dG98;&YIziyXG)|dvCsI)1v{omh)G1T$L<%aL*6L)G zI%Ue8NI`|uMx8dk_P%_wyZ3GDL}KbBX1|mhb%MZ&X<2)Tawk$y;j~dFqvo}jD0d1m%RcOnH9PO>>5KU1?)qTGoTR5;1zpi;9_qTGoTlsgr+MT?%Rf1h668x`qEE__`4 zMv&!2jgaqBBFv{qM{=3>MPzwNBVNBJD$R|i0PV!*i>TE64pl{0YS`(Qi;;;W~xUK zf|z;8I(}mFBZ-BRG(k0x=8ihtVmSf(|z7i zR2S)YD=`SXGZ2OQIHi)}0KNZQDzMKghk@nO6 z!(HU;Q0m!%?{c)yutD5K4i2Rr96+Ldh7IB_a%w2`)BqCgGi;FRBJI~B14y*bu-UCt z7inK|w#J5NpJ9Vk7inK|w#J5NpJ9Vk7inK|{vk*EgM9VV=Bv6$``oNZv_DAuX}?ij zq zP|fbdUF3XK>iLQni}o2dNOh6+C1<^i(LTclsV>sK$vG13bKYzacag(rsfSViS&sG@Hi)~(Nwn0HC`h!=utBPev|o>*AkjX< fgVUQoy}WyyJ?8%2$?4P2=KnV-+yNpvuzUFr{&Orq literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/ExTowers.csv b/titles/sao/data/1/ExTowers.csv new file mode 100644 index 0000000000000000000000000000000000000000..7b371e93bd62f82ac1153cdb012251dc75053e22 GIT binary patch literal 472 zcmdPbS8%Ne$uCbW@=VbQ$t=l9)d@-k=2-DsCmA8#?wX3$ZE_m)Vyq;_-x&NWHsg(YMw5d{A|TcWHlBTYM!@kd^)Ee zS&b!znx`ETpDx&fqy`v@=wbM5!}e#JHY2OS4CiM{_dcD2@n632pqoXX6+bSI#Guna^P)nLyQpUmPC9lzA_VxZX`sW}Be z$}z<$F)uH*$TNkP%h15Uz)(l&adYG2rj3uAn;$oKJnfkKboRU#oA*3zUHZ7W{c+Rc z$4xsQH?4l$wCr*7W}pHk9VH_JBLjUyBYguy1#>F{10aG38UjW1jm#8`kOeVS8k*`D PS^#wbbs6Xw@NxkFjpJi< literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/FixedFormChat.csv b/titles/sao/data/1/FixedFormChat.csv new file mode 100644 index 0000000000000000000000000000000000000000..2433d0233cd8957d8848930038435655cf68a2fe GIT binary patch literal 1545 zcmZ{kPiqrF7{>2{-$C}g(49Z&pQBWYz4R2sTL?B_z>=aKT14pVmQYPzRC_P`9f0}=}xa{*M zyS`fRd0Hy@4~j2VpXJw=@+(*>tnptSm5NUai_3TKh#>HVANU?cA1VApVSUto*N=C} z>`}NyrtJA%_Hi~h|L}e`7X%{rDtL`0%r{FOy9l@lxUfZsqHovn>2>@IcK!3WWa?>N z()E(oOTtO=i5e80Pg1j|2fc!meGZl8;^UX?CGk{QwnS#!wa SquL<;X#-0VD_x8vWAq=mLnZzI literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/FixedFormChatText.csv b/titles/sao/data/1/FixedFormChatText.csv new file mode 100644 index 0000000000000000000000000000000000000000..72e3f1b978bee16b70da6e53334a3cfe8782cfb9 GIT binary patch literal 15572 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/Fragment.csv b/titles/sao/data/1/Fragment.csv new file mode 100644 index 0000000000000000000000000000000000000000..5273d23ef5103adb7c2f25d651a31b367d011fbe GIT binary patch literal 144 zcmdPbS8yvzOwUctEAdRxajhuOan8?$@OZflbqo!3lmbItk=!qA`QcJRYxXFOwaR7(eX>nP1Ol5Nh~UHNi0d#am`Bs(Y#!S1_lN? zN`}v-FExBRd*0)wHIJLNKW<+9yk+6DX)_-;tp&0lH*bF2JnM1u9w0+WN6E;*$UxuF cK;OVj!Q9Hg0EobX#y}B6AW|@b3i5IR09qt8UH||9 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/GashaMedalBonuses.csv b/titles/sao/data/1/GashaMedalBonuses.csv new file mode 100644 index 0000000000000000000000000000000000000000..3df4b2a78799cb7baf14fce65dae0d59933248f8 GIT binary patch literal 317 zcmdPbS8z`(&Peo4O-amg%Fin;_Ds=n%uCFvtV(sv%`eR>(Q!{LK`8Mn&D9AmNh~UH zNi0d#am`Bs(Y#!SIv}WIWME{VZ(s;SN-&O@zJaBJnU$#}5GnC;8R;157{lc7DKrKu pGb2W!3D9CAm_o2^=2ivMzG0Z)@T&6%}Cd4Q-L$(^9i2y&iMMeMs literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/GashaMedalSettings.csv b/titles/sao/data/1/GashaMedalSettings.csv new file mode 100644 index 0000000000000000000000000000000000000000..b4a75667d3811de6d674eaff3e68b90867add1a9 GIT binary patch literal 2700 zcmX|>OKROf6b0u7?;#6#VD(486&MdP$_flNNg!kr@1IniZfS6?DYsfGwI1i?<=gA~ zzhCd)KR@38{P_I(`u+Fk+s7mSyZ&bF?c@2WtotKbmZgdZNWdbVAX%8;)*i{i6gx=f z#oG#!d8=&$2^Vi(%v}w5h}_jo+?Pi&7Z#9QSV6Kd*}J1*Ks9z0%!MfIYRpv>_Gs*C z?7XjGHHgt3tAQBpu?ij-nT5&T10!=GMn|m1Dn>`F24Zx?>gevp$gp=6F*2YU2S(;X zjE-21Rg8{U9e#xqBeO6?j11@}J25h#XLVv^K+o#L$Xtlg8LP31(HX0O7@e^?clTms z*y|TOF)|=lby*&!EKIS0S~0~6YQ+>As1;M}pjJ$A1+`*|8>kgi+`(a$y$7fj)72By zYGA>N+=x{fR$g4NBKIm*C04~d7pw@YMXQ1p5w$8<5mBpx6}b_s604F2VO3&PJgbTo z;o|C9Rji2USyilv=vh^)$c}s~W3;Sk+inttwW;JBtk~awAr4 zSY;Kf7OSRJ!-{Zm^Q;j++xEjQ& z$7&!}eOP4`s~)SaRmY03cOX_hRs*r>u^Na~k5$*IV@2GnRmX~mK4`^?fU93{#fpf2 z!4)eadR8k|MAT|UgNPo^iUzq64NLi2MI(hgFGeGUJa9vUTo-R>5O7n2ZZ@JHg)%mx zUt!}xMD%?rV*}=cQpPofJYIn^t|{bkl9X{xAy4E5Q^*r}ZVGuK@0&s%XGIy;6!JI? z%DASGnP^bP291GOrH}_w#x;dJ5vvsPM66QC6R}DmPsA#P%;Z6ovEe}$a;1!o=;2Vt z=0>bi$a58|6!JjIxTcVq?4^tidoAQj85_|b17&PPe+-nd5w)U>&5c;4kmo8^DddS* zrI06Ll|p7dKQ+qOc&lImhgGnG!z$RoVHND4R!ncTf?6@f4fL#-;tqONOz{Byf=uxQ z{arCZ%GiK~vuc#Fxe==rGSgM8QpgjrN+D0gDup}|s}%A?tWwBKZ-rF~c_LORWG1VW zu|dN^Zj`YR`GSoyHaB9GLT0*(RSKCYVwFOkh*b)CB33EniCCqOCt{UCW^yaa*!bKa zRw-nrt5~IwnIcvxWTuE!3YjTll|r6~RSJ0`Rw?9(Sf!9BVwFN>ax2=`VAa*2eT}FF I?Q16f2Nnh3lmGw# literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/GashaMedalShopItems.csv b/titles/sao/data/1/GashaMedalShopItems.csv new file mode 100644 index 0000000000000000000000000000000000000000..66a3bacaf006ca80a797393c701d544c739f356b GIT binary patch literal 47802 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/GashaMedalShops.csv b/titles/sao/data/1/GashaMedalShops.csv similarity index 65% rename from titles/sao/data/GashaMedalShops.csv rename to titles/sao/data/1/GashaMedalShops.csv index a4a78dcf5656b77f98263f9f031cf7f0a88de8ed..b92e0b48858fa740357a0f13a4b88373d16ab942 100644 GIT binary patch delta 8344 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 UCXyN5rC8Bj`u@vBE&uxe5AoT@5&!@I delta 6787 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/GenericCampaignPeriods.csv b/titles/sao/data/1/GenericCampaignPeriods.csv new file mode 100644 index 0000000000000000000000000000000000000000..839ceb238e56254b6569141d142ca53d132a3668 GIT binary patch literal 210 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 O@zvKp|I=}rZTLUJO?j>W literal 0 HcmV?d00001 diff --git a/titles/sao/data/HeroLog.csv b/titles/sao/data/1/HeroLog.csv similarity index 94% rename from titles/sao/data/HeroLog.csv rename to titles/sao/data/1/HeroLog.csv index 6fbacaccec2ab16c51a9e6c04b9d5f485041f8f6..339cce37753320b426c20fd9d38d23910b739ecc 100644 GIT binary patch delta 3740 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 Kw^DLY$L0S#;M-LI delta 4635 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 diff --git a/titles/sao/data/1/HeroLogLevel.csv b/titles/sao/data/1/HeroLogLevel.csv new file mode 100644 index 0000000000000000000000000000000000000000..4a9e8fd7e90472b02e6013359c05c8f2f66e8c86 GIT binary patch literal 2141 zcmX|?TdJc+420he-a{53m~N@B3kXbLoGdwu=o5Bv4?&%b|td;R?X-}c+b_us$r&+}2OSb09&YAGeZo{zBV z9GtJ`qgibnV(8GV^4EIa46B>NmUCP-8n=BO^0pyI ztAP$m&LpiF=rQ^xR-Ii|G9C;hIbh|l;+(?^aEgh6|x2@}1d#30Vs>pTqQIjya zD+1yK;|l;|)JTRgu_04K$_*1B^g4~s*kVNGwX&^?^aRktrYBx%CLFY}!KJh#;|N;W z<;BB^mnUkcBKNiqgGeVKnvau85a~=CE3%hCq;hCc9Pij5(ychcJtJ+rE;1U;vzD!@ zxdKL{m*!|iUSb_DEeJ{VXl2n8G}i#+wuO=g=!#K5KeA~9i6lT{l7Rq+02Gm0X^1d; z*kj=x8`5Di#*r*!&qnnp^q&QGZ0OA0!){F06KbB z`V%9`7$mL&&Al^@J}st7xKs{3SyV!9DeUpGsf4_2+Aqc+ak>rAXV!F7YxIcjW8qMo zV#x^UH$vtSv(pt?rK&lWgYn5wD#oY;oX$Y0CXDK7&KTAdCvpqVXvSoO(wDEZ1;)|_ z5GO){!p^oHDRDB%cqX05j@6cNu_3DUR2!LmpQ zf^_<$V$|76mUs>uC-+rIP#k7IcL8E8Iq#G4Pifa3r&E&+kW%LUlzGvll&+VlUBMz_ z4`im!WM(|eSrqD?>yw<{6`ydWN0OK2a8o#HsTdwz8^D;WDo^ZE0fA zaUD5qYuP#@J!x{<*|vr%kF<}7w`7x+*VMGLZmX@G5$>UF3F1-`uNX3Q03@`sgs>t~ z>YF8&S%gAN4r?rTVxaJ2XV}i}L~E)FcGwRkl^MN7&fR816m+3^Z-Y2su_H+W<{az_xz?QExoTSwF}kad!r2Yg|huFblqw4LwBL<@0-gWd~+qX t%L2>rLXpmevJo#7@m?rv@j_R>QFh}S4MccxS&$d%cW(SL-Y8-|+#l}(hEf0k literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/HeroLogRole.csv b/titles/sao/data/1/HeroLogRole.csv new file mode 100644 index 0000000000000000000000000000000000000000..4b75e2936591297d8d6ce38afd5bb16eac34e7e4 GIT binary patch literal 98 zcmdPbSMW$J%J<1n56aI;^-R(6OUzB>_HYakoBho(q%(i-Xjd00o;TJZ@eIR<;u;0st@)EpPw; literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/HeroLogTrustRank.csv b/titles/sao/data/1/HeroLogTrustRank.csv new file mode 100644 index 0000000000000000000000000000000000000000..cfc8e0daf29016e1159affbbba1c6d1c392822d9 GIT binary patch literal 912 zcmXBSO-da=5Cq`8;2m;+0;m7G413lvU15TULcq);%R1AOg{C}mdcEaQ f4COHl<#7z<2@K^)4CN^dhX(qJBx*zXLKkkon&U2pU+;h&oM}AS? zxT5Y66JsbU2?*ARq5zc?jYPG^=`HTX9D*dms2+~3s*)htfzALO!5l=3+KciY=VZSL z9=#4Bfm-bD>6DXAG&zbn(*uA90bW!EdX=ELJ6ImHTV^pcmfO9x$nK@Em^lk|j_3_E z^!6f0qp+Ac3k|N(Dl8Vpaw1p@YaeGIuN(GZdQewaAD|%Eiy0vbhsBILp)p7aEyVTE zb13WkK*?DhsYhklk8*Kwj5c$9C@T8ZVt)S)q=t8JsED(AJ?2JS;80Ow(5V9yn|G&a zQz(*Os4pJafrkSdWN0jb>fsx-A4?-W7(Lhn|6o6ENBMC{_W*AF?;Iy_%1VO<&Czwp zH~3{gr#@i3jFm(DnEzrY(uV$lvBTQsIOW%&WpaPa8~y`~Bc8ejzob&RbR&DHU>w!V zQL&ueAO#}o<%|4Iv7p!2zT!a>IlD$b#^y2iINZubcf?%50>Q(5aRL)c7Ej?Hv5W1K zh_vu%#4ifR!I%I@rZaeKdJez2ny!E((B&$h5{>cdApC4`ATzdB37EPAc56Nwt#z~{ zl7X~z(q@|$uDETm*=q3ErsSARu-iu9TD$`b#&+Wk8G0lp6v3BJL(3!-WMS-NffKZ- zPIMqKskYnioWT7<$K|7HT(u(EIZ2NsyB5Xc^AKrQ$j+tT1NiaAwM7 z?3(%)uZ47FrXI&rN;!l+F9KPTs@M{9se!*f+C<VaW6jcSNLW@c=aWH^eBE;3 zyX9^yTfyEsfs^!&225XBgw~byC|%{2@#f-n)U8F{Y6tqRX~0iwl-evJksO7Z5Au+- z){UoYm0HNJMFaQN0ow(sNo^5Eut&MFQ zNB*okIYy)m2tn7!mGu3Z1oSN&f~HNUvHg=atoZaKj5&3RCG~n2-5{xTqz~AK5IvbH&TnP~_ z{Dvx&l(;c{w;P&0XK-PU7X^FIxzfJqsY3df&t0=id#YS>_K}}4Yrjf`c?aAWROZ3W zvIaW)I6)9hFqTE2`d|gJzG}j#avz?S`;;JQ{Go8%J#-R#zrKr2hwozHH`g)t$aO?i j{7OKQNEk%uD#oDda0C*MI&tZ!2hMLVBJ0?Bb+G0?u7t9o delta 2517 zcmYLLYfx2H6rKx&crRWgK{2_PN16?yp2t00P$V)Rsi2gFNsyZ515i;z(iESlh=G@d zW(X)^N-B;5IQ{u9=iBT1*5mBWK3!M6_W$hV z@hlH|u=L3b7ZI)>0?{x<82E*OnXQfmpDU|fE zL8*^Niggl)GWJQ952U_O@_%@^7Y`5eEi=P)GyJ-58D`1qaTam7-zmh$e%~V=>v={- zyLfc_LL1arO%Iogc@R6twjCAEZKQ7UC-tgcRC}V`^e}jIn7<9QfbG)RFqj9i&jQG! zsP{ctxSRF)U|9gv1|G+y886=JAw~s?5(W$VwE6O9IIV@j^q}(?6cPLYu~***!bRoN za`Zbd2^X_a?T|K*Iu9Il zAF+GTUs4rADkoHp3xw#wIPUsKgDn>PdHkxkMWn)c(>CcFbyyHFY|Fu&sLPVz1MV6^ z-R_DeOdt9LF=^Nx5#r_zqz=D|bd*9N_mxh*sPa7wowI|WTctPOto_Yjhzg$mVbG;_ zv3@i~fn!NdIO?{-Z?26@jhqIv(j1JW9bay2KnG{can>R&>rg#5l&yQa3vq3$yFsq$ z3R_DYX@jM)1=3JwhD6c{7!tQ0MMvUHL!BGadfAB0xE4CnG<0#p%Lz8{jyDZm%#g_A z@taVPFv>K;6G7F{+Q0-dJDgye8Qg56$}eVx4G zM@uhF6qX$s3`5^IC_2@6VYFxb#~ejL^O&0=jRutF))+fn99t*GrN!`qD#raN4Psbl z732Cq#dtFpZV>8;vo_fArfJ~j2I&*~z={d2(!|Y7(kK3e6%3!$iujP>p(OfyesZhG zuZt!oO)i&=7*WqDCL?NWo6;g`*?PHhWsyQ^chA zp9_s4>di{OhJ0eiEyVB-9wFLi5O&YFjri+KQeBz#l&e%llzsQZ4*mx5`B)O3o!M;| zSN#zwOFsTXM605%E`0#h&-so`M5mLqczHOK%%wXcY+fS^CK?ZXZW#PK4@?G+GcqM} zt#D>OovEbECTXHGlVMq8(wb$O=-i|#8<1BQoIt$4z!bTdsC^-cG8UO47Z;7nA<^X= z5^Y&*iVP-7$+bb=k^)@nUSbLj5=Oz@rF0AyeR4t;XMksMIHcs3u_0k^;K`2!|7DFb zz>S^}@Nik98DLox0quFFLmW$b(a|peCakQJB=69% zs#y|LeFQuUu|q)qN;D|SZ;(q=L^x!w_8|RywMp~TU29H?+BC>Phf`~5EGyRiDb$9_ z)EQIluyg$(N%B{lx#6TFc#$aud&N67@ZwhshQi>Ddt`_U)~<_$CmXBKzj)IHku?Tr zBC9u3alH#~B0emntL?@XS!k@nge^q}xRWX-Qnd9P#-)7Tf#@uz%d)eWzf40>bhuR< z4oxNW4KZaKEm}Pn5wCgb5Z9H~BN}i7@itJym1Ts}wznV#?VzK5eFuJd)bIMj2QM(# zz4IS@sQi*1>Z{AyrM7n${Xk6xDKjeR5^`3tGOFmCrE+&WV&)zyFSeQ=*jPnT+>lru z1d)5cVUvnOMuAf`QE+KrFvNTMLNNX|?9cL3*-~UQG}Qc#78UzC5p%yHoV@=AV$=ab T-&#uCR(k=_^L3jyetG-{s2mkl diff --git a/titles/sao/data/1/ItemType.csv b/titles/sao/data/1/ItemType.csv new file mode 100644 index 0000000000000000000000000000000000000000..ada5092d958d625994a7289be675078eb5ff3b04 GIT binary patch literal 412 zcmdPbSMV%J%?+t6NcBw7fie9Ob5nV_40V(qH&1%pyytQAS}57H;c@eHFn8kP=C;R8 zi=XVC@nlDz5-*pLj?%NW%bw0$flGn0j?&8+o1V6A$ECmoWF3m(FP1NUHf0~sa8nGa zXWKfS_U#5rnE|Dmc0O(bx^Oj!0di{dh|^mEJaQ+na(W literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/LinkedSiteRegCampaigns.csv b/titles/sao/data/1/LinkedSiteRegCampaigns.csv new file mode 100644 index 0000000000000000000000000000000000000000..745a86d3c34fc5515a6e4e334d2305c0e581507d GIT binary patch literal 269 zcmdPbSMbTq%T7%R&MZj{N=XFOwaR7(Fw^c$w}4mFG$S`E=epZaY-zJ@Lcm! z!0dqh;*!j~bc7^S04DF3T3!q^#v?VS07yBeI3?!gr51Un@NyX%7#JApD1~JPholxg zZeH}bdBWqSC6Aj|Kixa|+4QB)XYPL4v*~fu+Q-d{A2)A)+&t@X^By2WNk_@Zz{pVF n&`96FP{G{FzyOHAg2o0w5s;vfv6ZPM5Rs-7Xo!K10WTK-&7oY2 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/MenuDisplayEnemy.csv b/titles/sao/data/1/MenuDisplayEnemy.csv new file mode 100644 index 0000000000000000000000000000000000000000..50db0f5927c10542f66ea9f0b48d835a24eb1fed GIT binary patch literal 18768 zcmZXbOU@)ma)kE{^c{472IkLq)mD%O7zkQP7a%}F7=YpkqGmC-*XI^)9v;O_v)ipA zJk4KW8CCq#pZ@9JfBEh2|MJ)0|L51A{_(HB{qo=c_{+~fK287e%l~2h=fC~_`=5XP z>A!yHWB>No-+unf&)>goKen&0?Z#y^R&EfJj%%6L2 zB6<9<{p&q;*+g^Nw|wwTJkQ$R9~aMaZsU)OXtO`Ly{I;OMqm@y%iC`e@_2f2y=wdY ziDY0G*=cvwcd?!JD`T^Z?d|RPxVG6v_O9(6_+4bDolnDy5)j*FkEaZ~*gm!W`2}6f zBK!31hg*@I_OCm)5!+_Z;Ot`iYTHAL$`jdFZGYW^)giLe{*~o)h;6gKBW&y=w(r_L zQ+SB%yS66;diq0ToBgKNVjHoY_WhNg54MzHw$qlCa0FS*Re*LIWSjlMX>5N6+hz}| z?7^05&h52Jd_2fvuI)3%XOL}nQm#HZgKe|#8T&KX(iDDrdkwOfy}b+b6xnH~5EQgi zY@7X^ZpF5DEsgd4+aU`*IvWxC9im}4KYt*&*U-6Gq%@Ri$(Y_n$yZ?T>B{m##eZFQ~Bi$`Qz7hdDzkH}6t zPp{xSV%zNg{PBZYuev`pGQWR&&S7?8QaOAK`?cEHdu)Gy*!}q@>{a()XY9{5uVJq3 zlkD^Uu(LKk|N8o{XXU)Mu+O@une_2}n7utY8FrDK^&JV+=f!r~w__CMOKhv|*<)-Y zva^mUOjXEBWSc!F<4bI(eai{^65Cn#*==u;optQkzeTp$^YDC&?X>Ti^0(N|y3ZiI zMRwM)3-&Ft&7Py{Ew7z;g~y#@T_sfNCKiffjuV!^6LlNR`rucnmSzE!)_No(Knt`3k;a` z#&a%!<<$1|4xl=qBnfAb?B2<;Y~%D;fQW`3igRKCNJIih0J96M*|u}o?V?z0qCM-~ zlXcs~djdYbHiQ)}suMh-H<*t>){a-H0!M z>Tbm^o(c6OyLYNwAiox%DhmCz0v>~xc+c+kTNw(B1+$5x#uX1F*b2CC&|nKtxj=*g zRCiklY^X5V&B97|Lx!zD>ZA=Fwg47N+b!O+yB%_r7z`ukMq0nS67xs-rTL9j0 z#zUde7NA%l(g3Qv$tt6QXF{dPZWn$t+>mJtK)PwZSRvl?>@FRJP-DgH?$a(ryLGqw z0;#42_DxpxP}Io^z)ijpt^v&MP9?jedt|Sja+vR^l?C7pRJqvE7z^M5vP-IQ6_UgJ z$cow})v%X~RD-*uS_9nOyQEqJP=o1Pyk~c3;p~!XNP%);7LsZWfCVw)#zs=D0fb3) zurtT`%-_>_XHDt&<^~Nodq#E{ek*{bw9nUjO zpjgm#3*h&bo$iV^B)h1{N~&Qm7g2NPTpkqPDr&8 za!EB76p-&7yQEqJDo~PYs4OcGr(04Dd+p>vNvbsf-ov+~S_g8f?UHKzF>`@7p*|$l zu-k4@oubcELfC4;$%jfCmVN+y~&$o=W%Z?z+Z| z?&gWhgJDbg*ehP_<4?IqP3V5zoCsx_bjBB_Sj zwu_XmyQCWS=0ciwmsIP310|`}0AG6Sl4=w~xZ%@^-xN8b@xg5L|amgVPO}H!4VHhwGKE?l4=b=M~$>fsxe;7A}@<}Nj2={ z!u27k)&UoYq*?=N3`(josO-YykxMnopmq0S7NR`?0;RTx05zC9MVYgcSMc`)bR%9Y{8D@%)i`74!}{j&K&q_(o+En)Qf&dO1`qBa z;uLBulp|E(u-7yBYa*nY78H>0xCc^g0cgG9TVGYq_lqb3Jrh!m1#?CbsPrAQ8{n6r zgLlsbu=qdpb>)1&Ab=y}`o0po9~SYSzD0WiVb((t3S3OUuP_JC15h){@7)KVmEA7T zQGq z9#&GV0lphNB-J{QcY}wd8fdzZV$n_-YO|4i+k8l>v7mgX$T=j{8c+j7QVlwqV%q*?>48xGy75yr_vx6Oy78g{$z9mpZ6)&M5$D1S+{22ix4 znkCgpNV*^%gPo)rcDo?pxl>5B2Ka*FkW_1cZx0ShHF7&y=)L=pRKso;lSQ1}4d98! z!%C_(poY1m8dYKzJ{Ba^u-k=Xc2u*ZS_7E0gSVtw2VBjPYSdf0I8(77l4{uPf=3;J zl2mJeHQXVo)&MFh=>=~p*MV|$x?zzT#Dc?Eov!&P7a)!pPs7Zm(w*zJPU@tpDVnRp>#fdQUKb$}TD0CG0- z)lmSmyYq&Vcn!OE@*N025%>UbAm6%GV<)fh!FuXejk%M#aQUCQRm1KD7Fegg0BwLr z(Wx&$8$j!+Xiwd$F~RI2vwG@Q4STupFLiXQ)&Rf4a3Tl2wjxLHiBtoq?iT9^IZ{n_ zyMW#ZIbv)D@~!dItr|Od1x1@HBHfJDWWhb@ey)KwGO0SI=Qsqu$f~pujNlkHSBg#-7Trs zfgFRUq*@1@ZloG6Y7D|*6f;sycDtx_Bh^+Q$KZ)nTL8=BQ&NrdI0NPPZqALUkIBNr z{FGGdfa;twmsD$j-}O#}4_i$Z`BHGAR%9<0c^sZ-j89->4`uKPjDT>S1Jp3*(`i?g z&(Tbva;F$-EU<5^1K_}00O~)1=x*dj1`2E1qr0)!PW~mKq*@1DQIcvM;8`^vCDpiN zN*4^&w2Stf*=U*cE!q>PGG{#TP!q5+KPAi4cazWsh)2@HN~*OL z)!mY6h^cg8@pHnMo!T(Z_lr}vY8^;5cuJ}@fUQPPVq>d6&L~MW{%|fR+7T$-sx`nr zN5f4eV2H-dW@t!NVEJ`5CoCio3{^{N+sfN8= z~uRG`iUC$a*>zmr+%Z>0e824q}G5sSoJHl`3nl- zFp54X8j#s*w=0$lq0;l4{t?h3i9KfOa6qAi0W=&lP6D z6=481qb!>tGwgQZ7Y{sr069PyZXZB4E3zqono$fEDY8pa4ZB@XvWnm(sn&r^_a&*; z09dHZFG)3C4IHREs%V37J!ceEHx`i47064}i!`i2UQk?;YP@8m3%1FfM0-vgA4!*_ z8VgL%GwPC5Yk<|@C8tpJGr|rNwo&h72}~K)f(U<>5^2Vo$Mli)_O^* zVYdt4HeZrz9mt<1UXp4Jp!L$X(p@u3eZ&B{B-Loxa*?OrC8^c`YuZa+fHolNCPwh3 zFF_xwFU4^ z&V^K4fqb>UkZJ(c-I}Mt4yh)4xybj-3#s-AjE6<4eFE&pR!B8~>Tb(sZr6srT;!y^ zkZM{`Kq~VKskQ*V`M;2A0M*?!Cy;8g*G{evq}l>l(_Tom1t3FX9!RP&Rx{nc$>I7b z7PRh0>4~M$%1PD+0B9^jX+7NvA{sJo}^j_RGn0m zq#EasThB9Fw`$nE6R8_ho_A7wPk^kZZ}DzGzIR`eYMf+Fw~j+xOR8Zn7j7g;wGOzu zCDl6MVIESA2eFIG9Trk8?Bya~im#Ar9q>!>6;f>h+%QNr6m)er(a_!Ch31moE-DvD zs0AQ*qx{h~3t)M0ah?NIcl&FKi{o5&yQtyC(YXSyD2~Vl;AuyaIHmxqyMu!|jI%{{ zyQp+?A}j#0$(_Wzo%WU{%xhLucjH<&Ipk#6%SGy_i;<}X1}YZ}x)n%SbPcICS@0>b zU=mPt^O-78^zQ-$>#;)L70eY;CTHgx?tGLMRqqY(<|UWG3-~sGwMdF;bI0Vue@%gn(TJrv+72wEdT|g(B4S3 z1+YB0k!k>yZVS#EsV2K!SV!IT&;q!kZYqBP$i)a08Kr(J7e111icI!$kwfi9sx5%W z|BX~z0L}}g^+u`z%v|K`x{+$K+l3Fe8>zMc6skQ(WD5M%d<$`Do7f3bP%Y{pj$60|q7H&3KfMS7E z1E^g1;_gPO$zCo}f!s*772p>siXc*L0X+V1q#8iw!ryb=NHy8*qUI)FNG(8h5>jmi z+!shS4!X((3r3)jYO>n}6*YPlskQ>OQ}AxzB~ekM4v=a9GZ$`Rq?+vIB9G`BskQ<> zNVrv70jCwI22i;mu7d?qO?JDWy9W!T+5%LdkZKEHC3+*(0A?=WrsN^jWVZ|Js2i!a z09BhvwFRJy^Pz$_PiDax9-_k})v((|2$KN>?G@l)V1=Yw0~qEb7m{l8D!2xSq#E|- zV$`OjS_j-0l4=bg;OQcG6Rl(cw~-4;HSEnr0;0VDBObhRYp1p%>4|scf^EhENws#d zTO}x|)&Sx$A}Fc00)quojW1p*7wnV^BHir*3(q4^NVNs1c<_R>0Bki_@LB^2u-xxfSYV(4EXHozkNj2=nA_7SHKay$~_I?)Hry!Ra*d0mM5fIU%`dtNNY&7jjr(+%pw19t0uc$Skpcs)nb8xauHH( z0qi2ATKwP6>B7VO38@zL+9^ly6H=`MR)bGSwGQBWun4KP%~yN9r$=9eR115#@WctJ zwgCBM;}cS?0~R??NVToK+IvArwXpxeMM$*{6pN5*9Viwd)wbo;e)L61wXpxug=kNJ s(2jV7RO>5zPy2*adlN0UUY-|ENVTw+i=6&XNVNrURzs?Fz+(6R0XNtJ&j0`b literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/Mission.csv b/titles/sao/data/1/Mission.csv new file mode 100644 index 0000000000000000000000000000000000000000..bacb114948184a96f67dc314b674ecda600ef467 GIT binary patch literal 3747 zcmai$O;6iE5QguS`X4IJme`$LC-E^2sT%QhNCdqhRDxuQ1gV4r|Gw{d6YoxD*S-XB z=3(ZYFVE%WkK6X+qkZ46UaI47SMBR-`}gzh@D-okJ@2;Frrm9C+Fg677VrC)_5i9{ z?zg+I_4WYMhv&D?tqngYeDS+|*?#|Kt+AD@E;h?Qo2T2=dcC^8d%9lT+&md$FDf$l zva>OjsW$&U141Q)B0>NX#FY>i5hoE}LVQHLMCuY!N2Hd>q=ZZ&GLgu%giIqcmB_4w z%px*N5kg%kUzg^DuuYO=GE_jUiHN8R8COF3>a&gT;!8+heKMjhWa<*qSD$T!mq`if zt4~JMh0L^s^wnn@;bm4r`s$Mrb+JupUK(V~g?WKZ;>9+ld1;Wb6C&zjo6@{A$k+)H zb+JupUK(WVgrs#LhyHPAJ+`>N{dsRg!q84^V!1M5_VG83BakZ)S3p8nc3vPiW(;0@ z0YPAp(jky5ywn9G@q+b`c=6EYhvlcvC;C?e&1jL#?n`H2<}`J;%G?=e1Egdjg; zj7_l5V=2+4#p?TzWN!8(Fo#YaMTC534UdF;ztH3SVcCU+&fpgiKDhluk2$<=Mi9%0 zO_AnKBe*r@`n+Y zPpN!|z|KqQLS3K|b?KHvH|`D{d@KzLH9~Q0NHl*$3gHd=;_wh3fAo|`gy$_SBIMz8 zJdyZ_6e1j^I6}`6`WT@{gu@g^=s7~)N9c3=^J@8PdADBj@q`A$9J5gl&e_^cKxfc%4g1FVYN!H@c+sF3nKbrZeulV}!YNs;IC~1*JD?hQd;jzVuSf zP*|&y(t9;SVY5m~uhtBOY}8R#ox7{&o6UT2eQb@o3N~F~eK>1KHXk5;I%`NyA|QP{Ybd1rG`@iJ`K+Ok@)PtQ1`Cnb literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/MissionClearText.csv b/titles/sao/data/1/MissionClearText.csv new file mode 100644 index 0000000000000000000000000000000000000000..316e1eeff9e5b73e374acfcdd735b25bce95a3e6 GIT binary patch literal 1716 zcmbVM%Wl(96x<{64=C$MjqL>JC$Q%e;15`^tnU@{0fjsZRROgmDQck)QQ9<$fsZ*! zDpvjl=FGKK6h9&%MV6(^+%sopu2)v>J$h1o{Pg*=yLUXV=2a_V*TwY3z7caN=1}a3 zn1R?$G3_{dKmFO6t+gfGi=(hYil0!%VkcrZ#C{bUiEZh#fD(XWF2sHyc$35?xkn|e zy0VT5I8$K;;A1hLODGMcjC6`QDS_SB6%NwHt(Y^hpTyz?++n)WKG$i*Q9EnG13h7v zMq#f>qSIn2SOJk&d@1zsq0-mIVi(YN)N?%5J&bEEj`JClZUi?j#GKPWm}%8RWp%O? z#)OlB3B@8`2t!^=SelgmMk_8!fk+UkvtSTof+T3`F(W91q>O2Pjp@J{*oEJKwu1$Q zs06rQ65o`*lii4^?NJX~q3ggC7avZ5PUN0Hnt8#EBSr?((B79~U<=e@Usv56%}nYe z4`)}MhbW;AYAuTNR(YX%=^z&t2H`?EZP^R8%A`=0p?2F`(-0SH4wzR7g6UgQSD48a zP)J=6!g7d=X_PuVCT!7U6s=aRxDxWh>Ye=)cIO*S3Ezp?b{_%25G7$q4VWUB&(ol% zSqcjX>nwxS3F|I{H3;jK!ve3CY8%DTK^$Gh(eUQ&FEOvhyh;lXmwvl$%um11Coldr zA@JP^ko})0)Ttq@it8l&?6U^iE(r(I$#8nTH9N(>TM}+Vo{ON7aMvggpGWlhmV2}R pW7Y@$HnIlQip|I4wqllqyAqBiJj|g7x@KGds80Z-AavABELRrQ-MnD!=&_u@wCJF#v=NR1p literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/MissionTable.csv b/titles/sao/data/1/MissionTable.csv new file mode 100644 index 0000000000000000000000000000000000000000..b399f22b1d63cb8ca93745daf65027b6522e2ea0 GIT binary patch literal 830 zcmYk4!A=7)3`Fmd@(+B#N{#K!w)+VjxBx%UiXJKOJnR$u#aCmyT z-S4;WulMui^ZNX;{FiUPm%lgYUe7<*-fY3o2L5{U>`{7)>`{7Kvq$M|W{=X_mOV;u z$LvvhJ7tg3+s@w8-$n`rn38=c!4&O75vFV($}oldP>3nrhf+-OJ``ij_oy5KKx7UH zAe7@IfKZN;075xV0$=MQNB|)NCjmqnkN_eLNC1%rBnTTwz)g}MaIX?12wVb1kRXf& zf&^h}3KE2;L69Ik4T1#WWk7<6T1J9Es@y~X2MH0ZwM+zSE@RpfYc884m^J@N0tg*@ zk^n--o+NE@yLCgRZ4Aq0M`nX@Bjb+ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/MonsterAction.csv b/titles/sao/data/1/MonsterAction.csv new file mode 100644 index 0000000000000000000000000000000000000000..052d917d6da43ea4b992a4f45b51a1c252943193 GIT binary patch literal 738612 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


    7A=r5EK$7_{rc1oFRTYsP(2%0(NC#RlMV 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/MonsterAttack.csv b/titles/sao/data/1/MonsterAttack.csv new file mode 100644 index 0000000000000000000000000000000000000000..06f8838dc37dbd75f5db706f267edd22fefc260d GIT binary patch literal 76672 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

    hD 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/NavigatorChara.csv b/titles/sao/data/1/NavigatorChara.csv new file mode 100644 index 0000000000000000000000000000000000000000..e1a42acd989bd2ed6812b6493938e1372614a720 GIT binary patch literal 103 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 PWK%#!BAEiz1~UZ!a;QvV literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/PlayCampaignRewards.csv b/titles/sao/data/1/PlayCampaignRewards.csv new file mode 100644 index 0000000000000000000000000000000000000000..627fbeefca4f60425ab2cba9b2a18a06b26f6dbc GIT binary patch literal 451 zcmZvWO$x#=5JvYx?;x%NCTTrES8hbKxDU;sg~rsFAl=%HH}Def+xjMXvT>qj%SLJOy{uW!Ga)nRSLcjTYYWyS~cB`tC(PnX^89WZ&zu}82O5W F#UEsAqZ$AJ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/PlayCampaigns.csv b/titles/sao/data/1/PlayCampaigns.csv new file mode 100644 index 0000000000000000000000000000000000000000..96ec39c3020b2af54d8770e7890a8376f09f0047 GIT binary patch literal 243 zcmdPbR|v>StaMJyElA8v&+|;t3CS$UN!5V~gj5!!>i8F=<^`7|7L~XpmOyx}c`0Ca zKz?yaW?ni%5-I?b_e(7=2Ab)Sno|Iz98;VU^YT)QJX3hN40V(qH&1`uyykJ!lE+PJ zA2%<4+`Rd5^Q_0sd%%pg$4xsQH+LxM80jb(85kMp8yEtS5|{&G0g-}{v6ZPM5J5x< ODKSveG0-vK_2WqVhX9?C7-yOyRs$(72-4?Si7P?|oDl&ifh_I9T1hl{;k zNyOe(d#l>JKetq|C+oF(Q@iY0Qt_Lczb^^p`o8=7nySC={=TW9`hHxgp|2-2*)wl= z9;v&r)8Eh3hrOTvex>1lFME%NW7+%FQU{})rs-3o^;yy~eI3;Fxuj+8a*I7zK=luR zP7gHDG6XuhRiN5ZCsx5F`QHI-#} z498TH*o$R2rmd&S0oCD{wqXga0>`w?RB_w{e#=VrU8!TrT`jvWj%m-SIi?C5hIL7e zL_o)MOnXVq^L9F>y;2tj@^nnq-fBvxW7<2F;yN7DJ`xc!rH*Nz)Q*4Rn0AV(yHdv# zpXX)1OviLkPF~-HOD!FeCZSbJ9n(QUd7!3aI%--987CZ5a9enx0>^Zarx!_Q5`%0| zQmRBHj_RPM^1CUXs)M4+?}{B)PG&B#uN>G(S&4^BGZcF#btMkVa%d-oRmAK8VLL-* z6~|#YxZIelhio~z6Pv4tXgRzSn`yUtJJB{h*xb6=vmD@w&F^7bjxd(z?&-1|;)Tsr zf$4FK7dDezE-`!-Hct;71+I53?FOD@%V7qAyqf#vI4`P9Ayf-Jd6zZ>4z^OHhyWE5}*iiqOzaWCjr$`h>;M{=*_dipZ*Zi)aniY}z84L$gfYBHBZUz`86k_lG)7SfAV?1`4I?Q`bmM9-^6Ad3?BN%27Qf+gdaNI%IMQ>LEnvFW?0w z(!N8=L5lr~d9U^Flf-R(rHM-f8fxs$Yx@*KQH?=^9(#+S)n?MI@!lUok$uE8fh4;E zao`0_jw^;1q8#3Qx2~4R%itqqIZ8}&=u*3HP!A1tYrtC94Tm3QUQqLq2Y=cd~hxHpUD*QpObitZMt z3_ps*Dusb_si7SBNM{rqwEn*XZb!zPdg#MdWK17Hh94Bf8FSVGWD;sZn2$2op7D^& z=AO{qm>@XEI2`W4kGgCi-S*)}i!mn<$Ru=LfsJ$X;p+Z2<44nlXk*3Zf^3GEOU92D zSwWcLn7Ts#343N{JB#}8qqh)q$@sy17O=|r(S6vu?Sq!{xNMo&GW;;AK5T}V^QeJM zg&j1H9?Dk)KgJC8!N|pocg2|NHaeN}PF!>$opJIK-AQMA*oPm}2mae;2%0%Ev~l)7 zMn7Hf4?lE2wX`~A_^}9FIENoAwsQCkS)9OxU6uTe@hv)?+Te8eX$DIEZlRrvF0I$& z4yanLNB-&RYUFU(tlMiY(KlUSNwyGk-C+sR*{_(1kgbR*ge@dZz)F`{jEpk;fKmfi za5iy@F^9BSU}A2-+RWN9hoEgK3jN_5ybZ3=K8PC(1A7RI8w4419O`DSjkN%Gb1QC~ zci;!LAFyip@tDkTm6@KZJHLg$rPUa72%OC#^mc*4*#}~efWjFzB35uXXJh_B;w%oa zH?at7rwj3b#${Zw*TLg#7%}D$xvr1FUzl9Rh&>i6XBCOPnAKQV&I1OJxy(mzhs||o ziFe?~WcNJrV@sxU#+bwBEH@AP@MA@ef}W7YxrNkY<A{{VVf=$76^CX2jLB|gwM&+P=kPuY=uGZKSIOw A;Q#;t literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/PlayerTraceTable.csv b/titles/sao/data/1/PlayerTraceTable.csv new file mode 100644 index 0000000000000000000000000000000000000000..1d36d9a5cf1d026453524010b8078ba25309cb7b GIT binary patch literal 554 zcmZXRL2kk@5JmTqat97D5*|AV&AKZ#sG_-mDc%vNA`s&C{ogiNrdio-FmE zjEhQQpz_?Ew0Dndi%SAMSoRPLJPEfw%hZHp|{$L))mRbYet}k+E$o zu1<7g@ZqR!gB#De$H-vXrYp>`=)n5K@-Vf~4Hcvu#*Ns2#*e~Y#xb$lsHUP>sS1ix zOxYt5Q>rbnBVhqR61ygW6<`k)w4eaCk1S+zFl8%6VG3RiSvbXyslm dS>vv>qU#06r`2*RbY?5(`HQ$#p?G&%{{ZeebASK< literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/Property.csv b/titles/sao/data/1/Property.csv new file mode 100644 index 0000000000000000000000000000000000000000..d7d8c3082a2e28e5053a0f2f2176870d3dde6b26 GIT binary patch literal 19611 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 b_}$TM`axs;xUiS=)$#&=d+3BGIl=z{s~VC; literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/QuestDropBoostCampaigns.csv b/titles/sao/data/1/QuestDropBoostCampaigns.csv new file mode 100644 index 0000000000000000000000000000000000000000..347b692716eb08db399bad49c418cdb8460ae809 GIT binary patch literal 204 zcmXZSK?;IE7zN zA-u(VA1?^JT_;+THo9JF-I|0~HJ7DY7cAqIV2M_3SBZnnPr_tf#m47`mr5RG&W+TH zZEK+CA9IP30>z0y}?mo literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/QuestEpisodeAppendRewards.csv b/titles/sao/data/1/QuestEpisodeAppendRewards.csv new file mode 100644 index 0000000000000000000000000000000000000000..26efbb1c94d66b2cd4afd18a4d417e477e5ac9f1 GIT binary patch literal 4996 zcmZXXJB}Pj5JY_fyn_xf0JpoVKV{00AxD736A;`nWQbajB6NMli&+`SAH~-Ve&-X8Py(uOA{cqp@ zdjD>D(x2s~7YF$YSD+){26O}*Ku5qG=m>ZK9RW|EBj5#e1e`#}8(f|Q9aeaJ`2`tA zLS&X^v>@ZiN@SL1v>@ZiN@SL1v>@ZiN@SL1v>@Y%$`vC=LX6gSjaFnFS&7lwuF;B& zBP%gl+cjE|abzV%Yr94(GLEdoXl>VM!^jbp8#0cB7;SNl*2n#+mvA>+Z+hvK8!+5m zIe>9B4R>I;8y>*8nuaGZ+zl^aTus9X40oVz&9&U0h6}J6>DCl%M!Gcx!)SYKh+g93 zhU-l)@o~cq*grmiu_3P9fw3Wm2QW6o@C3$&7+%2G5W@+K4FSIODsLD!ri)5*M+{NQ z9Wg|y?}(aJuqmlo1)GwZRj?_kSp}PtnpLnVsaXY^(rdG}y;rwxrDgf{>Q=#CiBh(# zD^bdpHAE>}))1v^SwobvWerivmNi5vTNe1*t!+ouu3PC@m!gzCYlza;ZoCa8g{Ju1 zmETZOREW~nuF{5*qE@1`wX3wDq$rhxDfB}#43reL6s6Iw(m+X3D^VIvX`rO2l_-s- zG*D91N|Z)Z8Yn4B<^E7=|I?0=qL!kxH>DjVMXf|>Z%R8#idu=%-jsHf6txniy(#S| zDN5z>B&etmqoWxe7%6HcMn^L`FjCY?jE-h>V5F#(7#+>%z(`RmF*=&jiIJjIo){@A z#OQ2BCq{}|iP71NPK*?_5~H&jofs)1s7(S?zs zR$_EDqYEQNt;FbRMi)kkT8Yusj3!2kQaLeFREW`RMiV1Nt;A?HqluBCR$?@p(Zonm zD>0hQXkw(uO8xz|5&y%%&|Pk$JY@}6U>F&0z%Vi#z%T;pF*nL%&X6_pF=xn{`Is|g z&3w!O^_&^yIb+D0`J6Fi&3w)nvSvPKfSU2640=P>%t3F+nmOnVSu+PcP(yZkL^lXPqHy=BzVh&75^W4VqD=jUj91v@vAOoHmB6nbQWS zRv)F`4Ouh$-HQn6Su;D%kTtX83|TWfPEfzEZiC21&`%U#z327A z16c3*MdxI}de1NP5mDAu3kkM0)k1=8O|_6+L9IFK_Y~BcvwlxOtvT!W z6x@L^ZL~d{=LKWh7@okGHij24rj6kQ#AfaKd89YQD3A1p80C@P5TiWO19hYyGk=8}VwAta4Kb>dRv*WxPFg{X>ZBFK zC{OfW6QexQ8)B3vdP9uzL~n>up6G!((U19htXDHW?mFiD%mckEF{*Q3AIGT9c|nZo LoEO9>5A^>5?s$RB literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/QuestExistUnit.csv b/titles/sao/data/1/QuestExistUnit.csv new file mode 100644 index 0000000000000000000000000000000000000000..355b290c7c0c52dbda1e3663afba9eeac33504cb GIT binary patch literal 173760 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 Z1?NJ)S{R+&7vj~fliyWwe0{~ui=2?YQE literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/QuestParam.csv b/titles/sao/data/1/QuestParam.csv new file mode 100644 index 0000000000000000000000000000000000000000..705a3a36ac06a8cc79612f401d7b89d412580c97 GIT binary patch literal 91 zcmdPbR|qUkEiMU2EK1DvOwsYl%*`xuNli;E%_)I!LNaqxT~d=F9On$6Iyf&VwYapX bC^fkxGe3`)%TUL}z(B`P$H)MP40yQ!&oCYH literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/QuestRareDrop.csv b/titles/sao/data/1/QuestRareDrop.csv new file mode 100644 index 0000000000000000000000000000000000000000..0d9c8ce604ebcb4097e724dd36efc4e86a33b2f9 GIT binary patch literal 40609 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 delta 1780 zcmXw(c~q2T6vodtjNssa(13ygvb!(@IHM!WiL%Tn6{%26&8V#0LU0KQvttX3h2@Zt zxt)lZ0a6rkj+OgJ<3;h=h`K+BMk0zbG13iNr57Vyyo3&eT`38W1R6%3zm`P)C&Kn0ae>}|c7@bgR^u+A3B%Hm=Pn_Lx z0Rl<_mj49CG#J9gnQ3HaizbquKWT(G%S=euP1cCDKaqA%Cz02a4D)tMw8WzBzC*y2 zN-Xmpm^t@)igWE0>b-RzvAX-wv`;1d;sbPja~cW0X*eSvf;r`3@@7xRS~UYo*-X|` zosRULSv;yegC=?(AzgXQHD4yqB5s4c_AOeieSyYfO~-I!849 zjqws&Q^d68#V9wFFrU5D^^t7k>Kt$K0NOJ00ymLhdKpo28zYPB92(eJ73F^I_rSGdSKvVK(hyCWCNNhd%219eW8Kk{iNsn$L zHtidlU-m6c6n_`&Dw`N@be1(vHs@CB8jqZ%-`4LrqV{uSxS!_~qb|74=OSNM`j5cE zOF+&~!1|wI?)ZfghuV3^whmNoTt?HQGgjI*{t9K*Z!G4;E-2f&Y4q?Fc6aG2llAv- z8v(ssO3Lr3%=m+6$?t<%`6tY#Ycz56FQ5M=GZ>tcnM|_K#%tI4x^CW}uFkQO0aOKA|HmWR71RCyQgwR(N`1=Q?9!?pZ;IOC-eRQ diff --git a/titles/sao/data/1/QuestSpecialRareDropSettings.csv b/titles/sao/data/1/QuestSpecialRareDropSettings.csv new file mode 100644 index 0000000000000000000000000000000000000000..ed7ced571f0f3ba8bee145699ec36f1b1b190e8b GIT binary patch literal 394 zcma)#(F(#a3`O4s|3UT~Y|_o)d{q(ObekVgT^Ix1O05k4-gGD^h)4s?y~)W{YO=ra z)fbjejXCGW@yd0!VDFo@-d0d{J-hO5847QlFP&@+p3K&5^`T$%!S=>gx$z8NkKc|0 zZ@6XGoR;QdO;fi!5nUzz5VH!boDctaM2H08X#|?iK(sW$jA))^inNMpLVAHH6^Wan tR+uTBMgy$_OOPN)_k{JZh6+jQ3lj^I5Tu`x@xPIY;3>iUJu>+f`2afMXF>n~ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/QuestSpecialRareDrops.csv b/titles/sao/data/1/QuestSpecialRareDrops.csv new file mode 100644 index 0000000000000000000000000000000000000000..623a2643d2ff736d856a34347fea8dc174aedbfa GIT binary patch literal 249 zcmdPbR|qUkEiMTzNKMX6%n3>?N_8p9FYrv!!6qDBngo;y&C4tSQqK9gx%qiPspW}9 zDIt{wsVD+y@_wbcI>9AHsd?!o8NQi$2zFwHP5{up)S{Bgki?{%REP~ACj=#yr1EkZ z8WBrswE&u1~U|)Z)_MpFS2v^dt``!J$X{~kO$&+;dP-pr-L)ycEzMgdZE%(@u z1HWoNKkfT_cTZZoIXF1*?^}I?>7F6^9Vh#S`Ud*7_9xxF=^r0I{nh(MH+Bs5_59M_ z|7bwF(>?f0+oMNxCw;}q`ns6bs719D{zbKj&@Y9)AoRWOdj=j44F2`cZLQIpiMAUe zGx@Nuqcc4yGE?rUD1UAUeOnl-!kiPvS7Dyp=7{y~Ko~jac<$=UYoR~mXTB1~n9xW6 zcdmc`&%qnQd`5ruWudPKyzq34A@jGH4`r1gic zpC7b$-D$h~peve)<48j)n$jBLEzyXkKJ|5Rtx1diC0>rp7#7B)T8X}lC)qO_&dGv3 zK4(p06+2 zeO*F}VSx#)A*Q8b(P&I-2KweJVg4qJbw8j&KLtd1yET=!vt!QsXG#x&s6Qw8j0v1} zbK<3o*F7qXHDQ_*Nl4y+I0B=PIJRMiXI^9sdU|ne$9Zvpxba${BR}PwTpxNO7&<2; z($U%8`j4(V_a3$Zfcm;5lZ^t8ao}#+=$s^?L?xDFR44uh~td;kt$AqrJ;A(WvC zklQha15CvqhJz#a!_my=7>*cDHi0AoS{9teg1wDU_NB5Xbhb4!><-^c(2W54)f z=S-z7BUd8nL+g}Kg_ifMpxJ?crOcYk09Y1-uNMF{F-tz!mChGw0YPmSiW7&(6BAM@ z%=5btFjHVmmET4F_Mo%#-rcU7t)1=n?lPqSV3||EvpEQ-)Sq&m6lu)K?+bkg%%SCA z{k5R1kd8GmU0hiNx2(%7eF5Rd$6&PfBD{MXkGl@kundB;>&!nrRCnPLOC_%XrQ@ge z&ek6!C{*Z_&`>cdK#?j`peW<1K`3w}|H)0+Jn0QiQdKaiycvpI*F?is?kk|+lrxWV zF>8%X@T0-QE#LbjOQy*8h+-(6SkB_A%Q67($?;qLh>SNTtwy>s#qWJ^QtDHo)2PMb zTEw1Nb&i1$1Oo~~Gc{mA6--1?d1YP*LCsLc_F=XnnI+KIm$*0xyX(p%=VLEoYW#6 z>Bnfks27WpErN~_^eTR_0^3FpdE_M?XVyySaSneYSG*`|cCToHDOiXLv5rCy5Pq*Q zQ29U;HeDkh>|fq<$q&$#z*LWrCHwUZL7~H{P=aLxvCWN1zREfMcN)3M9YWksH`iI`)#eAfH}bjzPToJdjurZebM z0};UjR8Z79qY97_5D$aES)(JQ8?@9W7z@KbVWECR1?#3OBL|=|@ja`8`OOi_3~JVt9r_%GqI2F)+Z!L91=!;U zJNwKY2Lok2C>v(&sU%S$nXsuO?)70Y7J!Nszc8{;^#naIEn;G6kxU3^L#3Eq$bPfq ztbVo%m?n4RQ0RO_-cD+XBrnYO!q^w)3O8?|s>s^;H5OmMXRb~&cui?+)|#CuEyA2D zu%--LFtTST4%W(Kb*;u?i(6~rBg{@XsgbbgD^C*>t z1cVoty|Awy&>2||5+pOA><7AXfzs$JMuCsU)#p)21ME=IKp-@>4io4|j#W5wCV+Cz zntf?qf;kc?A{^uhnb}Jlq@}PThl6TDwhvdWg9AbuRbStu#EUL2c zgfTFYV3Mg$10bN&;DT1L^ZV8=)*P}oVIR{N248UU*^u11@+TDBr(ke|q3;4J+4w5U z@;73zwUb?rPUai6jw_xq$#9;3f)^<*=GIG@3~Lbsxk+%BqCfnL4-K7>0d6s|}^ zV~cX;h&^8@WfpME`m|X-lT_8Mwf%nUZA{dWhUP}xfWy$Jzl0Ho2tG`6u$jtjg+ehi zcXc*mW#EP(XjF^D8rinzrfcErlEa@0v7f!)XLxlnUtB{ug!&9u816V(oI}^P;w*tNAj&59&(I)P zR%zox-wl}plN@T9CCa0beBW+CG}=T4?T(;ed6;fq{#KpN>cra<&%fm|XD4)OE5LG` zxl!xjt(`%LE+7&?bh3!r8V4tyaTS+dv}NZ%LYme(Cix7P1k}Y-7}wS54A*;%MtG3w zZzvVQIOY}&GX}N`!(t5!!d(ptv6Dm$oRYB z_Ad3?t~#$y;o_Vta7(pU&>T&IAQOlW{gpSZ{Trmbw`&|QdT_`k);LC-u+{_2Q-h#t zE{Jo^^dVPKps`$8ps`azb&)rW{bibm_2MvgRrH;JGqI0 zwiFwy34%_RPTsD=@Pa*2A~^XBb)msod literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/Rarity.csv b/titles/sao/data/1/Rarity.csv new file mode 100644 index 0000000000000000000000000000000000000000..40f6f41a0d65db08980001569f071704cf03b395 GIT binary patch literal 177 zcmdPbR|rZh$}Fk$OwkESEiBC}N_Ec9@vU@DEJ7CWFUd$PLKgE)O-al_hz3{Y0aX-d z7Q0py1SOWF@^TsK7#aWplmybeTt+%ZU?B(z7Bbc`0SiG$u#kz41z5;H#|Wg!RL9T^ J$_Fxexd5@?FWLYA literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/ResEarnCampaignShopItems.csv b/titles/sao/data/1/ResEarnCampaignShopItems.csv new file mode 100644 index 0000000000000000000000000000000000000000..e2bc6fdd5cbd79bd8bcee33430797f8cabe368a5 GIT binary patch literal 640 zcma)%&8osM5QX=G@8AOrI5Vl*uEm8L5f%4=2EB08mRJ$r-b`Zsi3MHckdx$_b21)} zHs-X@u9|Dx=)Xg?J=V>#HFjA--%Sbg+Sn2UDh?%J5Q15dr)ug(^>tuxi3J;K`6 zjdAUjx{ZI_ZE3In&xR7u56|7h7lsoi`X{4$7?m*5KbfqD$r2`d9u8LC_L{Q#)|DL*GBAr>KtG4mr}@(4}h^3YK<2PTQbo;c}z?<*a1 al#Zev3LnGiXU7jnI_9VZDrS;Ye1UEo{;}8q literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/ResEarnCampaignShops.csv b/titles/sao/data/1/ResEarnCampaignShops.csv new file mode 100644 index 0000000000000000000000000000000000000000..94138832fd9ced7f99eda22abb5895c2f516112f GIT binary patch literal 826 zcmbu-O-lkn7zgls(035e8_w=(O1Cfxp+xf3anL~rc307{v+gMQLP2#X=n}m_D-|9D zg+7gsZGMbqS9jG;q3|%f`|J!q{?BeG6gVN31TGtKtd}s&8<|3}l*~zgy8ES)MzfgF zq9IVOZ)Z(>cds)5zGvKZPK~z1C=~)tefv2{0}P>h2Z9ZsKmBay zaCmriKgZ$Jy7B1*bKFiJl0Nob*Pr9Zx9i3I`LOx_Jay2HgFAnYU+^;Y7dMPoN`Z(| zNbkq*$M3fg`cy`V_H>;6J4>msP225uUmkfq%pFR^G7G!>fKK(kQqw7B9C5*Y^ulrRya znae=@T_dzY&b1~lA;7cm6S2|c6;Qk%GHv8algm_WVE6Z4R;r9q#uE4G-PJkz+bQ_B RR>>;vEK0!_x$*9r{1@Y37g_)S literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/RewardTable.csv b/titles/sao/data/1/RewardTable.csv new file mode 100644 index 0000000000000000000000000000000000000000..50ea22b8c7aade3bb9f080c226f382f0b3787393 GIT binary patch literal 820935 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%0D=Ov-SOC_Ox!5+D03{^(s_ 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

    }T*Dv09jpiGjhT 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

    MA*FNfIr5dfD*CK{2DA_Bi{_M% z?Z?+Yr>k0DET??z(Jp^(o~JybU7VS`XN9)6k{8D*&wyHd&i+~QDrU;V6#TfnDyQUC z%ej7(=CEJqq>>lGChzvE;g$U2mm8Jav*p#YbA4|AF2Ccm_>Hn0_Ny$*p2aW781Xrq zf5|U?*}BZ0(;QPC#WDDe^@lw=E0p}=H{vtoSA5P$EaOA@KjM#fFAaOR1)BY*Aj_V` zZ^*knm;Bjz|-`vdnf^ExBeseE#`PF~$Ps5(5 zM~~0hH!_}ZXUOvm@BV5iRPqn?>+7GMUhrZ|oefTm&&84&-mHgy4^V1G;S3Jcp0-JZa<3iK#F~=S8 zctgV%!cbfxsLyxAU*7VT_?J(+ARBHztsB>eUwGxVuN$(_oQDlsSA6oOZuE|5AX^-N z$(6-s-U8XH_VCao;L zq{X30s|RmsBtu1;w|4)$(fxHsS$Q8ge7wUA#=^&bFe)aTipUl178a35__rI~U;Rjw zuk0TbjwEE>Gp+tFYB7!(@ZUtf5}8@yj%qVU|i z{_RHh7q)NJOULneVeqHCUNHU4(oT1k=h4dow(DuPu)(x zpyIxJj5Gk|G+uDG0E=mAaHlT~i)k=9oPM#2qe*D~g9jFnIla^SyT?fF1Hx^2PoHfKi)p5}`EaFo&ym_B0^Eno=~dGNxDOX# zF-<32!|JWy{g70dluo-3xOG0limhcZ%_d-gf7>KnE8GAx>538-xB=$$4S1?)OTK@* zYxJX5%>%E8%%t0g#dHAX0DVVkcJI6*(g_JszM?dlPJp)YC%|Mn0ou)<0JEka2I$L& zo+@=}uvNMSYXYn|Ovwgu>>8dLmP_m!Jy&WT2yh-Qz+##JOO1aQVAeEtirL8i?aqfc zdbD;S^RQ+>v22&{Y+J@pPQLApi6%8`!GPC`Osshwm<4|@TGmD>|gxy z4DbHx;;ZB*zgT*%e|mb!PktW;=+l1eiO%oC0DZ}e-yE2RK?u@AzkTBt(?h7&`t%n2 zr{%-xpCvDTbA9$tUtjSldDU;qv;Vlf`c=t`-;`&6aC>xxQ}U|clxO|=`l`p07r!ab zdNlb{FC{O2Q=a+!m%R8jdC#9^4@#r>rF`bUpPaV*;ewqIs&n-Xs z&3txw)l02E`F$9mcYc<<_=Te9q4?WNj*Gtg$*DM;KsHQ|P0t72_@XIJt-kxAsdyGT zUfEcMxWs?>82&fjUS2`Z2{1PaIob2D78avtTzrqYe}3Y_kl$c>tjz6D=i0M!3X99L z^4S}26^$_}>%mpMKz}&0rJ1vaZcg1^zkVevR$n=S-;noN$-07(_-rPq<&dIXeEq zi^bLUei?D2Gt&Z*2fH~8zmgtN4@r=;*3^|x2RGU!MOAsd=v5pqZ(k`|M6d-t4!PfY zO!6L|@xcr~%@_dDjJ|~D&TFnxfFfi7{K$lP)&x{p4S*bgh6_-{G=NoWCcWUXjj5sN z82}|zJSDyX#nJ$n4;KI=lB@>soMk5c!}FbOQZ$~Q9wrTdnRElH+y=l*I#+tH@2LTj zQJ)Qnt=^}A|M0=SHi=C4FsT7?mT(`z+xH^ z7(U!iFQ!SHS{{VgGWOjCn9eQChb&h%{C zNN+2kG-=f|3&@fSGhhY1K3}nA11lsirOY{_U>OZ+vo-&JAzG;0o(vI!u~F?iD3yA7N!& zbx3;9(9bQENqL#0jr<8PnNEQA^Ctk7wwlfhBiFEN8sEEc16;!eSlydl!&Ad@iCyDk zF-?G_#=i@&m?pqd;|9!{ei(8e;?ktabVkXE+fKv35vAB3=8$`7=qH()X#&g#e5H;m zjwbblsR4A_i1T_#z+##JBkl$)rU|g~(hU&PIb>ye>*@l(DN5gIk%&I>kg5v|{7G%8 zVe+shfS^S2)+jGe;ekuQ#J&Ru+AkChCi?1Fwx&0VVoqFH#nf&HvW)0}#Yx0|2 z+T~aOfvJPvs7H^_**7wt{pq~6pJ#aYR~KI;|4_fa{^{u@KkGM#f_7rreDz23%ASzT^BA zBY!-AC<4#G_;+D3c!ZyZ+_|zCG+~ulJJ@E3!6OXHSDaf|44UvoN(+m@{~U578Y)E- zR_V6Q97RJ|4F2bk8^U7n2%oFky|NhmbIARU5ibUQV(`x)cL|F@#PGKv_bZ-#!MfrP z5qy4*8=aYwBCjQ{q(@_*q?l_-UHNnfqFqu{ytU|694~L5xPXDBMFd@X9CE++MO&?1 zWDJ04Mqk2x{hF&3pa>ZNKQdu#J^-+lXPNl=HWowf z4Jeidzcdfs4r>pS z+9X~P~MS z@NXlm1enwR@X41Er5+}ASP5{aFTiA)2c+Tjj#9q_sx>gZ&4-uE2S|EN6W~5vfW;Q}nC*)=RRUI8At1X4#>39!_-0gGt@EH!Sxtm%g#_ad&xOT%d= zZadu{xNAUk$~olT8Wz(8m=7?ZaZ4dz{z9Wzu4rfIm_r1~G$ao+{0x zf19`-LAej;HKz$|lX?tQfZXG(FI~i8R_7)?48K=cQGpKNH(5DxXG5v5zAUEi@%Pp+ zna1KXHBP&44YQ`R8QW>*V!GdL-ce$kv2FJTi0K@8hD`|7;X%##Gll{2PZgw;XKS_0 zIIZ;q-x>vZRdmYVBk+zM@H_&4{Q>EbYyDPqP#m&hdhBdI0zb0i zl|$d?&{2y^9B&ul!Xh;%#N0G~6&9msocuHb&y_`|3G39`N8~m`Tpr=W%@RIyFB4WG zZeg)#!fLKtSQK*T`|Ak&BSO~?PQCxfbKWVe;ymNzo0PBkwgapz29NO52t0+wpb4wY z+QD8~3?5-nzH+05#h?jaxzWO6(5Bkz=WWJEJkR?Tz9{woc+UGhX8bQc%L-v0wN&S4 z)(O(w7SMRUWUeob10K>T02|l}xPMN%dzc6>GAo>?A8e@kK%Qs^=9^ zX1EOz$7uZfOLkYe|BCjFU;fYk`~UtgLm1J*x76JTMd1;_<2C+Jo$vcazh8BI&^@@p#yJaas&a>50vag;Nvas2T$s%%15gr z5e|dcIPl|ET@2ztbR*pJ8!5~+)qH{)iCcc~MRNw9x<&Mok@J z{2+!^H$sdX;%}?O_(8mSR;ixaaS@(?c|8}7qvDw&4G`Z)1KQ7w?Er}GJji05UlN_4 z;`@5}7TtMLo+t5&EHxAWQ7`iBX#Lm>8z8m~;M^%n4G`J!hBSPhAbem#Ar0~0D|)&b z75*Wz7LP=gRq@fc#>Cs~3d5T#8L78;OyUJM_X+{15b*)UTg&Gsj}G{Bo$~fTVo$gs zxFVw#F%GP>1erJFtqc?AbU&{}miy`??Y?NI`-L(05i%$o{)>3}Uy$iPvY(LjKMrf| ze?g}IZCUz{PkJ_l{ugBW-;nhG6(7VaE$Kh6|Cj%57%C>h4Ee^S|B0FYH|F~-&OWcW zh$%Jce?orqKMr^}v@`@*oC6Xv{ckP!H$o==1)2UggkMkwE#m*-+AJ#(2d!LPwDYJJ z?Ida}FU=?#CejXL8wN*P2qR4LwHJjsV!1?rSrpSImt<3(i{h_BJElx72&156Xh&cu zC?4q$1l3v2-bq2R*Md4-EkWZ9-e5%?s+M4d9fv}ghBs*=M90k9lo->OuQIlxKM=C_ z5m77*gbaT|U^zyv5j@Tg9i2UG6-GlhV(7RK#ZKwS@0v%qNP@yD9l*+SJV59=*0<9? zB8sn}V{BxXjv}rR+$;UyqPI zkAkbbQVtHzvG+!9gRF{fBFOnb$d5*db0XG^b@0&$ah{0i6X!liAh1KHAB_;_X;lCq zcCzGn-UxBdjXx`D z@y*RBGyRv%C}K$d#5gyj!aQ$A(K7=BdR0+zPT;u>JE5Nw+Lt&F5o4?$Omr{A4FAPB zsWD(GG2$JumY!hr#=sw{5%C!U7UF+|0QV)zoeV)@{v!lp9|~bwV*VopN&qMn=08GU zIdCw4hhSy_^AZ6)Q3EBYTITY59^GHxXBHI3LI6zninqcb`8*2>V<7-W35p3w(1Q_G zVHkqKSP0Cv&H}t8q%h2a!dM7QPh|m~xsnMCamin0=f zmD8KD5g)#rD@H#XZnvP==@oTGSgJ)%3+iaF1jS7YY6n_^qNWA4NiV_8OpNp%o!QKs znaEmkGjlGDry!VJar}juo<)g5l*Xftc)n?_h%IvpR^8yarX{$Ushy?=PDk}-rUf@M zv3ZO*w%}$4fB!7FnK>h+ies<1nK{#rCAgW1uX28}5v4T4^SP_ARQJp%-V}!7`u$o1 zpLVMi`^sQ5Q`Z`J4rvK)8(UB{(<^RfT2Rci;AW-;E8wgcY+I;*Huj8AoW8Vg*NGeN zM53_+q525~ei`S^9_$Q+I@gm9)Woer9y}tdk+qI_djyD=-WB`&jQ5WX9Yl!oM?}#y zbhsb4j^e8kaV|T%K=`4vZAG^SI|JcX-H58KfpDvI9+2mYb7rs#GOR-S4F-P}=Qvi+ zEYT!ZI;!mYlY>}vo$8fW_y_EQ*sYq6*iSPPfvQ>!tCUxb5a)(ai3Q@)AXIaZVla*E71P?qaYJ;ykZU z0urR1I`8P_?B@+HUaIm)07K<&C{#Htd&Bq24FDrGG<2>P0E-m>Ja+3L;V=dN`9%Y& zgO2x{2do&zjxnj6h;60*G2;6aw)Nzrapnu-}{cxGZ`U6p<~6+r^K9#vYA)#o6#tP?Xh*(Nl+Dhf+MXpbEPZ zv;;v`vD1Po=q0FD+=75Usm4d$){5HJ*NUR1SJV!*1UEBpsJEfI)3b*?&JJ@#DnjGf7;oaObMDLrOJiEOia!YWt(}J6w_svcVZgwz< zf3y)#{Vdg2(9@Y7zbNMTMCbF0yKX*yTXA#q@f(Zpn;SedGj&&*<2^{jo1pAja8VPd zlt)20xmMiNd}e%lW>Q`4*Ncg_9+Z?I+UHhX9QJtR2yWFasKV)MgkQ1(ugWfGT5#8F zuUG-681@YG=ylu$Re7+i_K%N}ap{2&pW`Unh@xO1RGm)<3-R!E=kCJnwl+Kd&CS z8x-VD5)5L^^aKAAJADsc20}$SGO-cjoX2)t(BMZsDfm#V8X?XTK|TgTd^AFwCnEA{ z`k^dogg8$Gqw6{jAB_;_iC~=%#N~%LKRTvWVz70H^Su5bAL?YzM_sUBfucMCblm9( zeI&51KYEVyUT-uHzvm@Ud(nW}9m9n<-qLNR2=YC;4E_QNsUuoOBuS5Uz@uT}{B~oa z`4c13kuTDNKRsZ=Xkv`^gTX210fRs!M#KXwJ>lJLTU7}@ZB{|f5QLlf`3;h4#C?V! zG5-+)v7aGG%->nvfs-$*%gAQpiG!DT6y*4Ckh=Tw)=vaQ8-`s4Iqn-I-mFc-WÌyEyAA8$Ky?+bFg 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 z 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

      !-LFKH{g%PjT^U;>w^YE_O{^-ENADTVDM@vRnlc zd@zp4l1*$}6j{PE?2=afo@*r^q*c5}dY%hwY*nsFt4z{ONsG`U4NqITNLqZF^hhpA zi_WPQfA~U49Zn~Eimq+?M()O{DpqtB(CY2+v((ZWi z@z~9R(*!ie7MC$Lv+90qaT#|ymX{aTVR*LvIy+$|to1?~^1Fq_WLzzQ{TKO~!Xh$+ z8SGIxDXgjtVR|@fK7~c2jeILC7DJeG(#XC&G92F|QkW*sUXsG9#~7KD*X_unkk>SB z?#{fTFPzP-5N37^zEfDmXd~-cG#N}`F=)brloS?&6u!ATlfq&!g!vG2YlaxKkw^OH z$YL;rnH!@wZDIVo=E`*mizzztIfcdG8F}`|6s`<%WDwJuUJ9!Qp&~BYtdmN=JF^1B zS>P=KDZ3ipy{!0yH8Jkmt?_a53qxP8xPrBs429RgAB4ppOuxPw^oy@X4vR$}W!J## zA@r?47gYRle1k>0N@Sq_!C5hlexFe9) z4Y7$yL~YRJBt5O#^dy4MTCM}ZsygsTR#+lf=#ChE#9M**fOg~v{tw%C_;CcH+;r?( zO9U4Ij?juXqZ@Ap9v#uTvpW53QHWi3TL*irTXh~9g%Ia)>!7w}=lsF%?|6O3TY<|e zLn!?&5#l@$%o61`5Q?sJh;u`@4$O=ZT_MD|A(ZLRF%VF?IS&Lg@uO9_fs~#T;Z`Yk z)2etY@WhG;w`zEvTS%#c+5XuoaUOmU;Z{u@jdLQ*DtnaLoPVj#LkBC$t%APFN8a5^ zKZtOvFsU^}V61)~yl6wZk-t1b|G3AJ?~{P=OJMs(xz-c{#;aI1#r@m63%xK$HTIsb4g zC;5mEyIMN1oXGhc<7&SSv(L`NSlE2WCtfv#9wyI6`b6h8$wT0K69oYxxJLJq7L)pLWk-+bg*BURo1W4s=a_t9YmN_ z7YK1~I?SqZE9d)Lbsh-zcIO;%le=7+5^wpDp|D?KM4jz9(1SjGE+C)?R~-Sg8KQb*&Q2=g5I*L5_` ziEz)Sj>b9ruKBT^_M0E-?ZF_k-4WCC#yO+wo=-j+=R}z2=eR9v@TYN3gnN$Ps~;H7 zImbZwaX&_^a+4}KXSSOkGu!j-RzbKQ!}GkmRS@pSL^RIni0gob&GX86cr>A}Z&h!`2KJel*S*E7vjV{I7D3@Z-mIOhl`5_7cyM zkym+lE2B$<^Dz;Pb0REDY-PDQ&mFMT!Jg<@GU`0DIZ)lzPYr4D*-49@z9Pv<&1h%g2(5RG#p5TDG%3xqh2YYTKlo00f0 z#p)HCT5py40YFSD&N49pV%z|iYy<#ZIg301Yl3nOXE~Mtgmm5XdhClrYc6-dxs{Uu zE#E=|0dA6}zyxR}4*=t8Q98410#x7xz#9BGK!uS2)puxEIa_={RYgxvfT%Wr`=F+i zfW|auKR0Or8q-`TIABDnF}*6a_@GMNCc)f794CF#aFz)PXiT%R9ngJ*>{Vut|%42&`_C1`UCKZheuI0 zYXZb{0N5&BgQBznXbPL@0I-ocK#eQ`Vmbiq8g9~gN(vwH1PFj4L^u3p&Gj5=)>NuMR8Ss6( z<;S2U+uow*CwLn-8E49S8F#cWh6=IiFK`85hKzJHrGgA=q;S#Z1WFpv{%&PN%AgeY@1))Ca=WRml zQY#4a<3h)-w?yz+&8#}7XIlpzB7(YtFsm*QyYdRctUBjy(gD%6@01930reL|7tOTr z@tYU260w^3S$6mx1nFp;vn{#j@Tuu&oD<=mPpcZ|M7ZY@(KzSE&1cUW=VZ_k+Dww? zjdN~FxaY{@>N(QC@Ii!m4n{hnaZZGLK6NzC>%tKX_8R=n9i`-)6=j}}Z2yhVcRzW> z=(^{FkK9vA9YmPtXCp16n>V=%!ac|DExMI+1heJtj8)^D*=~NE2Si!bI48pW7@p%F z3g<+)9~03yrz5Td7FN%5YiY+SJa<39W<%^pmy9kugCS;T$hQFt!mOIH`f7Dv*C1ED zByV!14%WG4;yG_iKJq44B9@NxaDqV0=r+z5;`+QzIx6R}6{3m$N=I%nZL0zSOJaR; ziKv_hLeu^w0)ty`kNpTa-~&_uIreH*4yi2C9E2G^=zCIVOes4XuX{XuaBvt z);W@**7?~CP6p$f3DvJ6R?gt`ym7u%T%Wh44m6j-2NCAS*?bkEaZb;T!C6tc;gk## zVGLd%YMsXx7);Gfyg-Qa*ro={ z6BNu6;7m}dK{Xx#?g<;31C#O&)X89 z`VI}NTHWc>3lku!4d6bg6(*oD&6&x47yuP_Xy8J@0V7I{=~b!42hGT7Qe&FS1k-Sq z2?=OSv!^*=_|TYM8j49;R%{KJ6bsWUN(In0#{uxClxSYq%CN2y zEyQVJ*(PC{DopbUz@5hLMMG|8Z4DT_YB()FHPo8^aNd@H%JhfxwgiajI8<3St#nXt z)!H#WM))^A@_kK>0bp;n)HuC00b)7;?5(arQA&WA4gedO0}%HJYXZb{0N6F$Bt0c1 zKs6lz*0gKD??nR=b2A+PmZ$+v0c{O=Nh_no^!^AC)1iR?&!u6Km?j|V;c`KqCRL`R z9vq;0NPucOOkzEFSO=go9qH`=6;NuZOn*3UOMsZ>snROXRY5yjleBl-uK&$_vGwM{ z+M{O&xRpk*H^=A1>hy~~cHYR!u{pJA-8!Vj?iu^6V1~4)HEAW!kQT2dtv)xTMJf-K z&^50j`1|I;G``k5V-iPDOL)dx(xUSmSbdNdmq&VTB5Q1wtVydr(#tK4Os#e=cHn8t z6G>~Sb;ic$ecwro%m3k^?a%keRt|FAr>aZ4_wm+WeliwR=s5BApzSZd_b{GP*4S*t zBL_9MxQww$<;W^Yi_8DvpzSX{FaB7JbMVyFKvzO^tG0gDv&;mJ48NB;2dnmm^OGlqUW-v8x0 zhO4YFGW~19U-;sNkTnA1IBKvb8;rgX9r*^kVpJn9L`Sx*gbi8aE@VftJ+RvsvYQPC z;q!^u>o*Xal7dk8hY|Qa7Mfp)*t`^k(gO$ts3Kr5$tegqaf#UTT_V^;%&N15Ppfht zsUXzQuzR5gc_ARWb{h-A{J21D))K*|DYMGXw|1;@BdH+Fstd#}zJf5T>_jYeG|rjM zY6OTbvas>dIA@ZuB^&80@HIM-1Ff_UTsPQE8P5; zp67>7C4vk(Vq{5vntLL+ZQ!0GkDKSaUJJrFhwmNHIHwNxeClYNbIoRctO>VS)i`HG zIbwR=IA?U-^T7xHSU4xbJU?4qnOC{7l(8bhJ;(3WkK9?>2m}*9?#GB#-h)aV%y#o* zW_wrdF4DjcRvt?hG?9#GZJL}vSJiEY|C3$Jet-3i8+dVOFPC4S{L@W`tx5s9Mrg{W>Fqqp+TSp)u zrG2T1sGJ8v6aS@-#yMl$d=K*VX`bBDPIZi5tL8(iE5))YSvPxLTB!Khbd$paLg=QN1}4 z+a{^LL&M5hclz|g)F7%2;6AA7B%m?PnaO=<0IUmYSh-MeK#S6QecXlfz=vn&L6sUN zz4ODgGM6~%n})MYNI+wnmF~V(uc-0 z=SlP7)Mx@4(+l7xO+aIsfDfsGEs;r_XY1NpE>X(8tBevgSob?~zi zNG~NVE{`-ky|Y_fn)JPw;_`nu5qsyi9l}{gkn28GUE00Rq24cX8PZ%Z-AbdJHkU{G zJj?d6eNSwiHIT}YRcVRuhw02i&rD-%aT%5{tM11ZmvOAKOu0J|d*_E@tyy^)LSZcw z(vUa! zRxO(FASH!WiWFw(CfzA4219s73g!yqTnbuQaJ>)`&I1Tvr6ogj~o5J|V z5Eg?d^P3Z~|Kgj>-}xz3D;SW)(s1OmY%uylbmSZC3JZ+95FOdJ5|*-vytoV5k!+9W zH_x};`N>lB>+^|Nj=m`=2=#Lqf!|}H31-8d-5U!+=>Y@+)DXM83PMg?A~r*bV0$vF z&Jtc$?LsREHMDXfmVRuy3c~!j(6L!d1fQnNs`E6JR-wemT|t;t7l^$=EeNw}^@AGS zd@nE&YazcL1oeD`ENqCzIs1$u&a;C2z~F1wBX!{4nHkanpPG)wIT7ypw5oAVgnK>_ zjdO0Tm>=hXTYfao$)F=J>UnN2ZO+4U_XAOAh{icPgCTl-;5z~u z=R}xQGgkRtU}ho_=J^Gpan3q72G1^VX33*+9?J%^>cWr4`LgQfM2xcmJg=O`W`(AD z1bZ-ue{jwNfqzs_oQTSKAT;q`>Zo;&U@k{Y$EfrCg!jx6B3#ErG|ubuAFLXAmG1>6 z=R`Ok6VW&)!m{K-N8_A5(X(XKd4BLz@!T1lo;S`{aBoh;c9tNJg>xdzkF!0Rxtq7I z(kgmx49@z<51%RsWAFk|>pV885TDG%3j_v_`8*C**i7_1fd5jg9$dQPdp^|L4+3)1 zan^}Kh;u_+@*#vc55$_IT*q0F386X<1bTNtoKrC&#JM5dDnvTEXd)2E5-T!ju{v|D z5UO+PU~v7YVLcx;9jf!NYE`X!etM#Gh;u`@AL>3rG|o9kxgQhJIOm$d5i?ee^HsIQ z4^^$KYMgTgU^>p4L5RjVJDek?AC2>+qgaIsu6%%?!ug6-K@1(aclFvw#zcJNBloWo z!I{(iI8~dT=Y1|mxK$U3#`)5*@-;idnboADan8PLR$=n(v1*)ChxNn@9hLK#2d!US zAS&l@6hDrDPmRIG`Knrv)tPb9b1aMs=c|`^)t+ZHAuj6Nb)4Bih+5~-sclx94CZ~V z&3Pbf4R?VM=W!?ki*C-#c#Zb^zaLQ^0JdFAlGAn*AjSj0u8WFLRv}-4jRc7B0IqT5Z?h{A90iP43!#0cK}%8u0aL60noVF4gl-b04J^q5ZM7>ntud{YXf*C4U^Q; z35c>Vs!v&@NtNlS3J0hv6401tQFvGfpfbHusq~LClck2rbfl{-4QE)zG|z@sjjlr7 zxs+*vJ$39oegF3>n&Tviec)CaO=xp`&Ye!z=ws(Af@?m_ZTzzu9MWRrcr|HtyCE%7c{YSBxr*Q~zrF1Hzr3OK`p0?MH{+eRvr?KXfDvzvEiTU~)yk0Q z3u(8c#idEBKDspiu(>?a@bqTvd>hd1zIuZ!y!0Kk#XMJd!|phD`u;CJRSP8j^Slhw z;_{q;t+jHEiN+R}NBZu(3}dT0Lz={otkT#j&5&lL-Fqo6Lz-E2Keo7xL!Xr=H|J&F z(3@16uoes=ew`3OSZy~>h`36c8MuX2lp)M?9fiXqFpR943}JexR@KcAjW+VFuviRX zPDZyji$n@Xh208^!x*`)GP}*9kVi8&=VciUF&M(kj=}d9hIyJiSHW<4)+1^&BkxhY zKE6SgBa1;h)w+vDe(u#Cnb*?hd0CDu25sb#{wXX5LzuZSdsAdxe$Z8#!4$pA=d+h} zM!x8gd*sSsY<$h8w}r(Z68rkRj7RD$D=@nmr10u^Yu@w2wXeTlzUBS>$aetO8Wbbb zzb^dWi@o%bpJcUy5vNsyy$9CbVT39$Wk7v8q4 z%8xd%{F-lRfog9_G9yMC-(wnWkYp)cj|m_6XEZqoJYvbGfUQ3vBLDCI`M>`k_}pe- zLuo=3w`<7P1w`SyhHSgju-g6?1Xeb~Fxf6w3#4e7knaM)v;LYlGOBAd6ll}(a{*B! zzJ~l>KvbXC5Og*31UZW|;FrBd2@b!UPOF+oJYH0mQz6c`r2_cn`+iAZbqEZmCACUUMy&&kg z;l3bZKMY#|D_V~Gf{6XAr>dnT-H(s;`o=4>>3tyReaXu7UI=j?k9zgF3Od%40X<0s zg0WQRw*H@z%NmYEVvlL7!7l=>Psg92zvsGT z`2D~x)5hQzVbFVeGkotS6ZCjKJ`tjm7}K^YK1 z2+%)*pd5%G1m-RX>+%JHpe$IA9s5h0vC6!1D1!i3l?Mm&IS9C6wJ{6=(-VXrJy>s| z??&ZhCg7%(XTkgI42Q2`u9>hg76f22O@DqO2)K8(^)Ltcbk}TlQ{POi+pn zMC%HQ!{VP9b6mc1Nf?HrF1DgGgrpdySCG^yAjwZj@tBgDmb;{}2RkvQx_+13@yB`{ z=AmC9f^~*eGs=|I)(2IW0!E__T<5CG!P&Oz-hesRsOH8^fyXYR+C6yOIoFE0iEGB#_OED}<5D%k01y z{|EDTsVD=Do7Sl)mPkR)q80(h|JIr>CvAD86o@de&9pFN-kdNf2_g&us$odb34_ug z!Vn+}1FTEXiGwl$b|Q8GT64&8DM2R=mJA0}sN$K685n?I6j7{M!c?)FlIra{<0L6cQ&KIxOB#=1 zs5-{~-`Klm>9VWJp&jy%Rqv{PxC`!p$8i50fCvIeee={kzN7YBgm?rXrKHT7k|ghp z2}>__lChLzwa+ohQ%bVRha~>}(3Fzk{4q+{uo{wF0L(E-QjW=4Y)Vd!-fkQr&xZCJ zN4Q8eBySwy!|Frw#t}ZK-X*QaJx6JB1YDQQT6&)xq49Ld^OX7yMuzsu5hW)_?~@}+ zPLA*&F4`wYb?5J}$uTEK?~@}+PL95>zE6(y1jJW19FrV*7r8$UyyL^?C!V=5#_BGU3XRjvXb`es{|OEZ z$l;~hBLVUY`{lN@F;0EOI)gbD=_0|qS z+P8?gmgfG_f@?_);tN8S5B^gv2$PrGGfKmJhHjAMer_2h#Dm=2UsUFfQG=-acJXVt zKiGFI&HWAO>?5Ru%Gxia`()o{>&RrIB3h^gGc)=3_s{3#FOn|^mZ>4qdm_kvAwD$3 z3xQxB9s}V|Pn-gb$EhQCiSk69E2?e(95U=~Cm0@NQ+ z(!2@;6CnZ-plcv}1M@w1sjLdjrvOPH;QXP<*oZhtHWWtUP?!os&j%!r|1fsQD7=l) z(*c>T>2NR=1;HQ)zKQ#uJ5?te4yJ-27$if)0Iv~hG8|0BKrtBue2_|W;b1BTfDM^x2l2hd=L`qJMKG27no!}@)`eXU!pj>>MK~vP? zH{!%a#}b`1eQ<7DqLU{y{b6ft-+$yTkQwUSe@>pxD*OX?IJ%{ulP5|}o<1i}l$<=_ zSmk2p(@si~qa5>=OBi8{Icq-0 z#5E$9^bxTo=g%!P0RIUyKz}^=z?*LyLQ9?@hl{3#COtzADF=d$I{YvvpCN~x24QlV z&D)nlQ-iSUJVOp&39($YN0n%Q27#6Bf$Af-bq>T4-4~Q)hajFd6ki1QR8#l2FL_}p z4ReSZwyDG`a9fMI{{ZRi!wmeetJr8zIeh8t;}IQ8E;a1Im%+Y4YLCgZEGj?9zCXW2 zCaYoe1vzf(hmQ}EF9?nCMv!|)cv8X^;Xcixj#IPwDv_nJZ3R@eOa#i}a1uJ4MmA3T zr)5>%RZ1NmU$tr@$b0GdhgGD#5Ve)3grw)W?UYveCW`vOtr{Xodg%a-uVO{c{pm0` z*UX~lXGieklbpx%r1Jp^$j3&I^FVlXUn9u5Ae!gNd0K@uJ)Fm*8kR!#1FMjZ_&67CCx6;dh^>#S!5 zh(!-psmX|abSW@Q01t!B!}ilK*0ZABO9aN4uFbzBo2h`($Ds@oBftg?- zKbJ_yy`wa*;vmUTpdN<=!6%P{F>V8xlwso0xW^%_`^@UeeW;TT2h`(`pbvuB2qF%l z={XK|sX5H+`EWG#d`L}{2>e&rXZgNcFF(lb< zj^ufC`^c>%jtPdkc1p5>kM^1&=9uIuCD|XRBxy=XE*z&MSxQN+7pEjiN=eT8N0L#R z9Id0plti36N3~uVW9GI`#q-8dZuXSq)u_hA8nk6H${@5)j=mIN=}ZBBzm5`)PkYlF#bO~ybx3Izd%{MW_;rMiLLa8Ktgu}%pVBcl2aWRsUuKk z1A$^ugtg`hV62-50*)#I9yNr8Y9RcLm+~BS*b&ULBNWP#u_B!*e3YxgeP6uxca7c_2I!Ut2}a1))|kcWD(l7lc~1JtyaZ z@N9o=6*(7#TD5fG9~$SbL#(oAr5@dQgRMBnZ_=6&UFaK#!MP*UDzxf>7@Rvotg>Uy zff$^7)xL~Xe0iz-aD-U(;Q8R(5o*gj%%`gLCh2VpVlGS~WO#gjn@}7fA818V6^-1=2j2p`ts02Fv!0+DM z<7?o?pdh$VgA`W)M6k{U!KLz}4stFC@%+Imavlh0P^>BjX%#sa1RuvR%YmEWIXM@E z`0;=s=Yc@fH$H{1tC^d-%TB$w{h;hT{&l#5WzKE=hL=4Uyp`LH62Ir1Y&o^Rl?(@0$VN2=Gd3;N}vfUX}#LANRpm-s??@A`t zs*j!z&K)71LvC6%ICq44&hC>sU_j&CJGJ;>5BS}4Y$`Q`SCk@_=kcZS^4z1Vp0DV} zmzM@YJh!_|!>Yl#>rl@(qH~Ub;79$~u^M&m*)D$UY{%uM7Ar@nAKUZ6xg*q%jToG} zBdP-y_E_ORs#W2+`hh46#NgaJgCKT z`Y1|1<*?O4TM(i;fz`~fjI_c|8_Yu%pN z9-k`jI%*pSQY*SYgLCtvPMsbRo%7g7mbvypN9Q~cu!M8%wyJX;2w5|19SCIO++(FW zR-MN;nHVdCA3v&NBSvrcUZPpD@+$t49(BZv)siK(PD}>lFX;`0WXS`f*Ex~`Kbj@0 z&f_~x)DfO5gWL1Lxv8-1O9pGzM?VJVju1Z{5QFo%3g7jCMMUF#uEHM>z0PBuDC?^S z1Ua{T`?CiC#p!vi$UgkW?q__$$%0z|1f>9MR|#O13*eEB1d#9m*aW2-YB`nw)_4G5 zTm#gXOcOx51)wHz3QPdm4uCTuQL0%s0VLZ2Fdsh(U?~N_lQs6OLW5PSI$gam0i;?0 z>I0ij0tVAQGpR`nz=d0A@P&c`MwGtnW`p`*mD+q@rKU-PX`l2(LoE{$Fqrn9rhw(c zVA?b^lTflTRi=i)v_+`_mWIwWo{|7~#RL9Zi;~Z*;zQNwF{w7)f(HYrNgFVjcEC%M z2GibR#iUx=rb&Zo*C5@m=C1^FrengB#p2!l=na1En=>5%nSeKdOvkkZv&n?mz1fW4{Hpp_ zeB#`q6aeq7k{Z=p6F{Z|U{PuskS1rXc{Gse0C*!)lQ6Az0GSSecMUbEo|29R)^q^8 zrd0!e?;6N-0K7y6P+?7{$#eibyp=mm zhXk;u!z8Z<4eJ7QrX#%-z$q&=bfzO)bPZTXXhHd%4UnRjzyf^Zi|!KSD!5f;~qy` zg*c|i=RYm#JM5GutM#$a7t*A(q;ZNkDCO8>RHRuZ=_aK~Xh|anZex>AkzU!7W5dJ~ zllVj@{#_m_(vtJ}&#(AExphsEX7Md)k{QyzZn{g8%aX1~+BG)03~8s5ooPvv%aHbh zTkOzFav9QIZ}+juWqfzML1pE03X?$uJU)nOC(QbdQ;Vk0FL31$=(5&I@3Q0%+{Czc@}T3s z*&hLofyti>+rTe`$sc}s{)Fq#Z(N-E(oHDH+Q7EpRx9wOf@1{P1LyOqPt+4$01bPE zJBXrYS7zcLLsXax(N#-t@!j^XU*Ro8S0%m02g<+j_8dzoL{}ZX{}&xOzVeN~-2}h6 z??ZEuL};wXyEAxv>AMh~^NN56192!x9lcng1DP`rr>+vwTfg4-c~7ejJ&CaAlL|X@ zaFc?F!%`x=E4=pOkd+93JXQpvJp4GECBl~%ia=u-h(lc>Vp7Ob)>F&l2h0w#4+5@s z&+BoNh*Nxi13CBln0Lzg+n;y+Zxpg8R6{WR9ued`ZlrjYs19Zcb&zvGs1Ed~h!qj! zToBB3ShW%4JP@9VudO2If>5iNyR?d&3qq~ho|E%Hc(%W^3Mth1aD-a5bmZnyGUy1g zN}hcW=kd4ltj@zKuPC(&`Z^!+E%AX+t7?xRbqvm3hgem6FB#qVTY06!t5&Vro)69) zAyz$jJ~(%TTD5fy&b>3JRX~qe4bB~*R-vpr0>d@V9idh&9l4E^40`ubtJr-qy7A@l zimoHXs@gmwV$``K)T*sxaPA#Wtdgy#lO=g$EB$bUSoMGyoI66SdO&o}ql>ClJG!0o zK&VyQ^Uir7)T)KRaLRdXt;qbbb2m4XdR5H2H@4CbN2rdC7`@$liDt>ltDnKSBP2^?op>0`8(W!Ij*u*QKn%{k zCu)|gI>%?HcC3`a?RoF*QBmSYJv-w+`PwJ`dLDaXAjFT2z<+F3x#z;*u8+L2l?*yU z7<@qVI*)ZC;***9fFS2_nZO<4&L#dAWA*7@MElOYvbTTU_elV&yfoDA_LBw@9srx5 zAXZLrf=UhKI{-G9E1>TCB!F}aKoewXV1)<3nUE;eEPFKIza6q20Bi800G3h$Sl^++ zsb|s08%Xg^?^+%0fT9unbf2OU~z{AUnnSGMhWjWs?%uS!v|Jsnlza9NnbS7 zG9dwjY42$YSUwDsqXuvNrP$EAl<=fANI|D8lX|r8-sTZ)$)&q+G}&-q8rQ1wTP>&HUY>4ya8l7E_Ikq zCY1eNp4oqG+WNs~5RVT5@ZKt^A&Ibd%B~w4~wbNSBmGv<{yl zy|RVUq%-ce;NNBQAT2pJVSaR*3|~-)KWfb4Thb&m#`bm7U7B2$bUo6pvB_mfJC!T1 zXg9eGX)icVKx=Gr8Pc9r_p!-kTv{u+K>=`*LKG=)#^KyO*ReIgF9}`f`Sj6qe1m z`#wLlx#hP-Uf%cl!5`$~lxQX3skD+KZj1aN*_*IW>1epIEJ>SFm<);;tM{ca8H^h) z{=~52oWf)T2(;Z|y%EEEIX|^G1$N^4%nM;M2zH+D<-C3Te)LMUY!^RPw*US&ICq5lu{|H0J3{@~h{3r#qB>w<_Z*aN z&(#k^VIa`Mk~la@LL=Z+9R9uR|bkCiaE>jPwItYWK77<@qVI)8DJmwx2^t#>(?(<7%^ zC;s|hjKSZiPov^o!P*u6A465k!~~FW0X(vi01_Smo1j!fO;8CS-vRL5W;F>mM?Xve z=@x*RgdleS*$#kn$0s+PWm5ymc7O%xa*}rdn5+)hp~0$EovvP(08%Xg^?^+%0j%x- z_{^j}EWlve7YYiPQOZ{YGnZ`j(tO~IoF)yXeVHH{YMGFL!L;`@1uP#1)25-BgpzGc ze-5TCN)50ybf)70`4tanqK#>vi^Yek>f>}?*2=INKuy|!!L$Qjnlza9Wv7@_EjCRW zHSHRt`_+0P0iEfX@Q@DKU^k#M4IlBN0Ql30%MWX1l&nNGN;R>hNrP#B0#K*%d)LsJ z#^7B;wfv(2Q>QZh;v_Ety`}>o6Yyd>zp3?pUc@(>Oo(9xIDGi<-HzY9pp^jct&$qm zTN6O04B5p`A6Fquo+9}3=SSYZdFjgj{Dno( zgm=6tO*-o+?1ePBEa|=D%&}RrBF*|pFDXqfOB$YzcvG5Oiu7V9rJ?k28OK$=lH)UH zT5^uUeszEBpGSDV`EH{<4VknDoHe?}CYL2$&$3IJ)fv)G<;p7BO)f*)EA8$jxeRH~ zs{7dFGR~pQ%i9s&?;oiYVJ;NX$vCw7#a{&Ee2Ms>e4p|)grT(yd$3pGq_9k^HnMxT z>OF;7l64$b4};z2zuM^vVV{gv_T|VVF{0uAU4_YEjO?@4RhSf(&9@`GzuMLE1E9+h z-lu;j=Pz$a*~DW>?WweqBZbMJjLaw24BZiiFPt=OWS{sKgDFe~(ZHt5$MkG8n?1NUM>hFc}PC&*zo=DNF`yA~#K*$Txl@pfTAuHU4?8?ly_b;Dk|K1N99)#CtZJ+)|^j}_5Y6#90Fap2F z681e2hnI$6E&+jB=m_}c<<$^$;t_EeN<^Q(+R53mDtC_>f~ob0fT-;;HiY<54=#gFZIzWtX7=R*-l)#1nB z+&3iDb2vH>gL6j+=kR?Z2Ir1Y&$o`jd0#u~E?_d4yGiM}SCn|Zvpw%TCBmbto-aNy zT;tpk;(2YNrB%71)O4ul_`OFr-~KxY1QS2%$BI?H{g*mC+r^Ka?fLd!L#Q9y^TE06 zP(LIb4Q5Tnk$GYDeWN8XZ3&mAFF?O0*B#(7^^AQPA8`SxGx z@H!U;YkxVjB=?pQVLIyh1cBH(AgaCH5SO#I(?#?8)X@>!AY9cw>gb#Y0+w*cYg^Sh z4+JOvM;(K6kCp0Jb8Wu;mwq@xb!^1w?cPf?OIBVXAzE}DAz4xzoXKErG9`nK(E8Xq z&cZnn-V-%TR-NZvtLC{fxIE7bSBbDzQjb^2-K}GA?g;VY0Wmmt&xOHVAGzC|5dUhVWRo`9spNx0(fL20VF&CHbJR| znxGPZ07Z=l!1sgIq&jOmCUGhkfSSa~KQ)l;05}tT#L`(d0VLZ27Npx*+cAmt9U81! z)#>Vmsex1rKz(4-NdT)m06sIR4- z)G{FfgK6(+3Rpf2rcFaL3F+LjHQ)S8lPpRNurze0U!AoD(|?0$pC`qKs_JxlFzu6` zr1u64rX6rk4Rf(G?JZVJlCw7R0f14{u0gtA&BN{k0KKMT!b3XjDKY__Y50gA1;8I6 z4jKm2R-%nKPAsWm)U-bVsMGkpYv@d4@UEd+ero7UzdCC>VeL%6I%_)sG93phW|O4@ z!^&p-Vb_qq5s_p%0Nz_AHLABJfJ_I#d#h?-loCLu1K^EJ0azYHSQ9{|1K?dlO+t2d z0GSSe*R*QD?;Sv<17HcSQK|w;lgM-cJiSH329Rk1Xf7?2$g~5Z9(1X-0G(-AfFA|0 z9*z$f;B@aW$?HMGx&WQ&NN)wOfKo$e`qf!mBwyal!rql_+gf>A1)Xe7(*FMJ^?ZDw zk2J?AlzV)aCdYMVRsCX(O@c+5>((Vrc1s$J-Rvf{BF*GkW0O~rW}lnVm~juOey)Tz z`xL>SKiek%{x83rWq&Q*HnUB5$D7imv(BtuNV957dT$MLY;q~mtdI1P(&VzF;pvDs zrOBm8FLo$RF5_IuS8{xsNK4|(3K1liBF(B>(&RFvJ>XYqkbJl->3Wu(W9yz+a#=lW zNt4SM+biwrrS65<*q&7@V>2dsqsmrDCT(6`&f32J`y`bj%!NXl?MG1%CX;bsWNmk6 zU<#ASI$hcYpTguZgx$kc?U6>q(89r-W zM`k&e&FBE5WYP>)qaVIp&f320ZsqrX`8lhPmuGD$Oa^6SKCvdM?^3~N&3!CV3Y0UC%yPD9X%N5o+$5q&UxHiSXw%jTN6j(yHIXT|sqaHCIb&&Hw*c_!gYK}@B2+QF-5WXj@R`I-z2=;bCXqI5e=%Pe$4HpRKLttCm&`&V2_32n?}erO~ZUO~l~bbhPNAf;)qGiz~C;V$~2UR=IQ45HI=2 z-K#|S%qgB%ozsuOxgpf52gKmq5wEQpoO|CDt88Oy#AuB#dtsRWSl0C;;-02U7s z+5>=zhwlJ*A5oLgQ#ybp9sn|(|+n?HEKn4vNcJ= z*1qjMz2%)Pn~!YA-}}H_njF`OR&|XvHVGDKu4-7INRE7DA!B~4yMn%!R1T^ddQa9PrO<2c8z-87MAeWaI^CYL1* zPe-0mnp}$X$`eYHOF3KPvqoBSPMz=)MtUjIthyylF6(TqPRo}xxh(024f5EVe#^gF z2=jTWTAhB4O)f*)EA8qfh&Wt^v}e`I*o;Z-lErb7O(D0FxVPFM6JahG((E`Pdix`j zahzmrcV}PavD)eJHyBd=OXGss{Fdm^nymcnE(ggu{k@`ugv*BO3-UTc~^!cP&&nJoSsw2X=u9**r zZ526>zbfhwc)Oqcz^!v0pD{Nbf?)as&nzK=oCm_QM0GH_M38eqs1CH9h%OQ2To5cY zShW%4JP@9VFRj9GhjT%wRm|PAD(*d1tXzj$wLFhqq(XSMzqX2;hgFVHtG158xg*4? zswn!wIu9LQQEC!UFP^*@X*hMO*_^ zs&>PO7c@&z>`@gTp6%jCbe)H1irZWRA$~j{dY#7_P8eME@ex~NrNd(-3_c)worey@Co}N@LC)jOhP%$qNc=Cx z>ch9GK4PoPj4A-csG^pM2_WMFcw{31Bs>5%L8*pXjvWAkc=!&0&E*QHzdf4(mbd`a zBu;?|V1)<3nUE;eESmt5?EqMV9|f?K62STn4VJUb2V`UP^aPM<0jLjbItds|gTijo z0jb-Lq#Kk*@10WOd29W8vGh#NGQ1<(3#&3Q!gZF+itO4-eDydPu zH34Kg0Nz_w1EZ7xG93VKWC~y-I{*aaFdYEz8fp?!J$Og}yLSM*rd0!e?*Ml10C=7wXVY4r4g`0 zX-V%B=N!AX%|x1Il5SF(gqAcs9qB@8@+s0QTPRIBMysGh-QTtkcTjX-z z=fgfY{QVJ^u#CYF_Pkq}l)_|CM&?s)=0*yWK@nb!GKI;Y3;P!ib|R%P84O{I^M3O_ zg~_0dyb3FY$zTY3)~z^)FmgQ^3}H|HRVgVfE1`U+e|O&$W;?BsLCk2UDa>vf!k%?2 z`BS(v=monQbqbR~7$28|>|9yz`#1|rEXO&(cihu_LaVSZIZyYEB71I$I!ih;lpH%cFQCbzZtja2XK2#mt z{vhI1Sn9Amu6_g0mml$6snX#O-l_vp9)29oQim@^6v0(Gtvb{tBBq&;`Ggf z@b0aC)PpV&D~f?)bRBFK3lJWEsuqnkP~+~Hghssjxz zqD#bSsA-k!V5Y;WjUeZt!!z-wLK^2f$(g9Z525egj%(A z49;DLSS3%@hx7O*RdMbWrB*@T;A3#^2(=2+Xh*<+#L2SBh;#`V{q=>N3CM_$=uC* zS{W-xh*fgllY9)$9idh&9r%aFxpz3RN;b8Qj=ZOpRyjhfdO(aicZ68=farDZEzxFx z+?%T|nz4#+wlhltp;m3rJLiE=t2Ux@9-B5Yf9%|i*Zs^YtPyfP$GGW-%?u~6&cf#F ztgae@55O>zD**iN%ZvDC`_REvFQk?Z3~@LYtHkpM1bcfRoI$Zl7(7?1 z;~QCp@D3*k$*c5(bskpvT&tefTze4shsL=h)bnLkZa5`_j!@4xf^{BN`Rpuy)EX{1 zk8ie@=gy!aP{BP`@zt$Dc;8jek;eluICq424qGN-aPA28eCuFu56`{tiXXN^F{~PO z?%A%0?fKx`qpO}TK45a=+!5k=9T6rUxiOWTJ3>9j@7<5wojM2%gdg=|#VWU`Qio@| z__4D+{(4|>?g;f`dpmdFMPlS3eMiff$^7XAs1$kKe($BgCp5 ztK7xP=sH3?e?UOg-pELV*SRn#>-N)2az85(rlYo95r`Gt+|*LU%bP@>c~9#g;*dw? z+6Nt-^FY87&b8aB&UqkY&G4XOaPF~E9jngc&ki!W2tR&Q$3_g!y_aZ~%)CO=>eD}y{e}O1 z2rK}^sG^pM2_WMFcw{31Bs>5%L8*pXjwOI=_5j#iu7J8plmIT@1fV8y3QPbiJOIvw zM5$)k1dwb8z#9B0fTffG)^}*IYHdECs-mYSfK&@WePGi`z+l>ECN*gS@V^_=zEDuW zj8g5rg-KSa%?DQMF)2Q@Wi2WIKIw~wS|%i5Fzr1}0n3NMv}tH2p=4WF-v`qcr3P3U zI@3sh0ABGB-`FareV!B_sz%f4!L(0$QgItFn0CM`lR#u++FPucWJhx?N_jymiE|Co z{c8R?KI8?h1BeMv8q)@Jrr{%g6aas^NrP!C(MH^?xO^)zeefp$bsE2S4V`HW-ZfOq zPp5lLM>m$4YY|slZC(!nkO_DL$aLIbF`G;%`+YUzH~#}3Ux?sgIso2VB{izICV<^L z0Nz_w1EZ7xcJBaqBU1nySpvv(0K99cN%fR;d?3>S@S0W)_&tbA4Xo(^c!>(2!kPdw z9RN@7mjE&?0L`Uk5^LH4Q4hj&)kB)pnTE;uQ2^`V0FY;mX|D$j>jHG9BfS;C0!j^? z>Bv@D{H?IYm$a<&`F$BHPphDltt1WqXxmF)wXqi0Yux1*;$*pQ<5b7kqmyG1r}bN$ z43~Jd`7KUf;S_gOZ_X61@B%Ou^TGzl$fcskOB(&SU5SGG`^bjGb2{JU%(q$TG@&X;bJ{qrW# zSA0x99=uH21I|*NV^mdZUY84de(YY7!sIYU?(54Dy4v9?n{PLXzG`zzgjY4D87xM> zTJrKH(bq2-3}J8dE0f}C$ydI0_;#)x`TWnP+;lL7$)K3A8f6NT!MG0Nj~9!SBMiqm zUm`_)9bele!;HLyb!>(lez>xm!elVa@T^;LPBYk0L)eplRZ0r825aQqeN(tIh$6A7 zn(Z`&JA?65vywlBS%YQsZqzAE1`(Ej-1zzWBZDq%UD~#}^S4dIP@f#gjLj0%)C+awyCBmOCxeS0G zXaU3XLtR6NRS$?$c?}^})fpkJI^~xL?=S3JunIXitU5KA2%CVa*CAF5fq!V6d&5)D z;ZxUn0hZCt-J`V1H&WDd)cX0|6=S)NMrPJP@4rA9W1QJyxn?)%j=V z9LbFz)v*u=edFAFiDt>ltGu<9d^ke+*a(PfZ+C>&$42xzM^fMiQjG4Z^W0oIR)y!v z;P!lQZYo-~ZykekM~EM_VVrrDx34q$;hz@z$nMwl8{-=V>(Rh_P0m;h2O0QG@Q=KxTa zjcK2m)Q1J&Vm&nYLO}sDN>6bhVrhT3iAF4*vq`|aLdXnA?0G}Gu4tQl!Zdzqcdy5s5Y}2i! zcizuRfNPNMS99d?AvdoMASOI%OdHUdhL8ABz^u6VsJkubBU`OR8*!Xi(xkz(KLM!I z_`N&bna1EyCgbzP?87rCgdeE>g zKxaDATLCPf)X6IsxCYS$%!@-~UT72vhSq}QT zk5!j;pJTHhkbJnTFEEBRBnGw37lMxDZB5Mg;f!uv3Fb}ILSkg}Ctj_^G6Axs7l!^;ug+mC+;<0rrF zZp)&}86IsA`a*PNGUkJ@K*$TxmB&^JAuHU4>`LRe_pi5*J#2Wy@=T8Dh9QyEvDAJ4 z{0YRNq#@V{fWYqqad>G6Cf<_{4B_N71f6(99EK9%Emf?l$By(P-}Gw;=3zU9NW$vNwcS^?*3V*AQZroZ_V)gL7{L$~m%dST#7enL>9+ z>-mP!9h`e-QqSR2*MWa%oc9?NoG+{LI#YV?2=#m;&h(gw-drDbK-6}V6X6VMthhy$ zp68o>iSVrs^&ELTJU{i?5W+d^nux)<>rl_Pj={OFGsTbEU!)&{bFU~xY|jVh9$oc( z@d1-tbR8j{*Y;dml^aPJD@Um3_`OFrcajbQ!5q1}VwGD-sl&5f{Mgx^m!TR${n(xl z&RvK4u@QrFcSLo-!r^)6JUmxFz~(><&b>1TV%K24>6e~6Laf@cLd$EM_hm>s#XJ2f zx0F(c*STb3?ObP;z1`C&fk2*T%fq*64OWRg; z&I7@T|53-_++(FW)_k6C`W??>-$!+9#HjQB%nGY!UO}L9?g+_}2gI1q9ijEHb&THb zJyEk{*7A{7qL5KUI2ioqLzsXAmajfWFrA2JOKVg zDjI4zmH-4O=JEjePO|{y6z}-J5*L7)#3?W}u)+i2Oz?S3@5&^AWIMp4YD+v4!8A_* z>pL`9eYdb88>6QufK&@WePGi`z+l>ECN*gS@V{GFeW9R$8Ku0h^>GeTtWui~tkh#t zzUh|$pY%mTEfW$jnD#EHfaSwr+B7tixU5JGgK3LW11t@l>3HmY#Y65@rPDr7iVszz zY0_ZYCp}5;4H!&2;FU=rvN7!~R!p+(@RodeOG|w~vtfGIJbZk}OIimI6P`4t4d_h6 zNBk%N{&bTD(^jI5xLI*|Lo0poCjfOCzjqCtX$;;qRLf7Ndre0-mYHi2mv8!Il)TNz zGHnCMbetZUO(v9Wrke4GUvU0K1P{{z@ZKt^QN1+*?A`(J-l`fHr3A2h2f!Pd0@%nB zK&AuWT|-Smss|4VAkzWxnpO??y#rX&0q~j@K!r6mkm&$;0lfr}X#r?1Et6Q&4v2aX zrmG&(q|P)<#*YG64+nreYfO7RXjm7ZGac!z02WYc=uE#l#f#+2H~p}8<-7E!f=;$3 zX@7tINrB(Ii*=;q#Ut9Yq{(rehE=~<(j-`8tlSNLneehzBFFQiFlorb-TX4RJT-bbb-ELo9eeWaI^ zCYL1*Pe;5dO)f?H9usmICsy8K*^|?fa~k%WulT`Pk6>@eOPXAUv@e)gqf;8`cDO9* zdX`<%tj>^jDpyve-FcrX?e^!r01>)dJ=d``JwJ9M zNnzGwjO?@4b!3)f*?fD&@3(ffM0izWn!#f91Eb3+Uc3qPo3HqNoVWHo?{+5namH`H z;+Mic@$>PP1#pDPpqR1xWST(+v)Ryo3HqpD1@!=+GDQ1i07o*$rZ{d8ANNkoZ`XjkYyi5RG#0&gUcbx z0!-1B$*?O#g}fMbC6JXu$g+Rtuq%zN=U3JnLadTgy!7J~Uqgsha*CITQ-O)_M!*(>=pqY;RfBWyV1lUU8+txC z$G`Wd3HUU049*>)o-eEL4~=t2sOKATYBN3e3Ku`N=edED2xm|cD8ueYex*GTzSW_e zBaa6HqPDx(5aKx)nTWx;>rl_Pj=_0fmFoUtGMKwaX_Z%$c)qheuRSHgqpO~8J_hHG z5YKCSF0DeiTdW+Rp5yl(-P}n!Rw0=9Q9o9!aw{qQ@N5@9cDCpHehs01EYI_OzlKmh zHezt@j;Ib;I6Uv1hv(`CqA(Dn&b>1TV%JA*D5W2c5UUb{dUyqvd=SC; zJPUs4<>LBNWP(Rpxh!~vvJg9zb1bchv@HK-XR;wvNuZ?+UbR--yAv&z#~%RV}R= zoEt)|dO!@$9q}?teg@~>cf~5(GV8gE;5E)&hxEjnozsup);fH|JShF@0ns^!qxez8 z>Lq!1D>=8S)mYUWMXLtq{%oM0MF9GCQ0GdzBBvS2wC<~#w$|6nbOv7aS zD1cRw02X(c&Wi0i4NP0|1@rNLN`Jj<5niru{t2YSfD8WNWgFuODLX z3DTrFPQTpayEHkjv$E>$pw>OMBPjDsp$DPGR_e*Vi3V%gOEk25|9lgT)HvbMW3@N}Pi2k?xH z-BtXo!bxHB7$duftKL(XG={K`d=(~(A?%aU%Dyu)*3eu&Sv1_gt1#;^M)q0jD$H^$ zn=fa4KX&C&&G69SyMd#=(qW6lG*S{AK~9Fc}o# zP4_W_47%{;O}!kM42G~jE8Wb1MlOf!K+qpyR$-lyYcDHC_N?1+4x95GKwFvF$e#RM zT90Vt7pqd(M&8{w&FBpJ$RK9Yeaz?##z@-{qZjV{QOsYR3?s(=i(vs_ zz5-$^>Fx_&0^AT*+A{BdS)0@4lSMiXgX@x<^}(?1=;GjHu4|c$Bxp0_^wrCvKmJB(Lp?s zarY2)IsV6!8Y@VAoGFn7RH$Zh;0>#F9divt>FcJyq7L4dyu-fG0{KP-g@frqNIeWfPlbc& zK}gIAf;BG^gwd^a7$BB>PRlzMTkbphVaoc7&t$FaMAkxR8TN)vCmq(h#eG=e8zz|S zby(8;u;z4Y(KEsTlIxN%44yYz5uT7FqbbRjli8e-w^QwD$5q zB_U)#Al5$m!UZ!`_(BNT4_^$?w3PdVkbPey#C+0nEKBS((l=bpI^GAuy>E#0o(OX9 zh;UxHht}{U5vYr%!yRde%t<21JbuAU?@O>TYo``AV%*I-YVZp|&-0b7x14=!RUHt1 zA?SI+vb~r93I7GMu7=3r|7>NI=7F&TVg}$BYBFj!2tI`(ra;8OOY@&`U=lDM?Cm zOil+=Qg{qQ`K&Z0N!}R~mUfqDCmBmgHnBM-c}htxC#EE6N=dFFrX*QPNlsEzk|d=h zXY(Oxy~;?mso$fdTl!v2={sKM8Foa&m)O3GFukEry!qEMkCS{ZjBy)jL&%q{Kk+|enMcUsqG@5t7-VZXq%;VtNUG>2GESM))tx@1vsR<{jUeVxS9TJe5mmZK){~F$E$F-pocAGH)sjOo9kQfO;4b z#4vzAHUYCPKoSNdN`e@N+_ka-Es#782#9gOSI=7!Bq>cv zEK?sPQB~y84SmOA=~+@{aF@hmSeML@=3bNO4oOz~$yZ8}r<7!sPf600lHk1A$uY@N zN^$`($0SK9$ysblPL4iMgH1crHTR8d$Z(z$@ENp3CrfzPzKjZIJ53*K>~mDSyVpfA zKaWvkv+_Ong=p&MIj(N)^+(SB%Psv&HIc9FDxE$s!bmpAoYRpCq1@7<1r&l1ep(n)7TJ6VxZ->ZUos% za)Y2K9`o=P91FNW`0WAo{{3yAPs5*y5%LR!Dd!24=H>2_MWH~(>^AQ$&CAP6CT1XS zum1`J-iSLsMIZw7k3itlPc0Aux(34jG6Vu4^R5T`C-Tg5;z zFxq2~dr>DB4yIxt7{nlK%PUM)+ZY`p^Ldh$keg5?I-e&?l(grl^LesFh3qh3K2Me? zIrbGJY(6B!hrsP~((oV9Jl5=fINs^S3oGOp@6Hk0mYx;iS=p%Q5EJHk=`l6B- z9mkv;;TF{+?;rn7j`S6jHYVcCnsn_bu;(#zYln7z&d6ikU|IK(`#F^Snru>Xa`d&v zj7O`IANPr)tck#3=Va`ZLXq~zr2dvZj{Sx1YqE|pB=JukrQE?el9(nYN9TF!BQFV+A7M}SFN`bEfvD%Wvu@WjnIKPWaz+Irs_Z!Xov?LXdsG!HiV~iykR?h=s@@t zVb5fUJgs_L(T%sz$`4!1*O@T**?#zoOhmv{=-@O21m?M6Rp;C`FPa~l!T8=%=`hai zaWaYo_{~S>-0!2dSSyo8&iTV6+DbiQF?8 zpDR`b2baELxn^v9@2JMM)yh34cy4K2`r76i@A%G9ANwA``1^Dv?fHEln>{un=+f65 zj4ycivGv|y=Mwuj%}X0wAH;_A;L@b^4&9JuUAo<9uNeE9C-E&K+U-uhV5iq*NXt^b zTY^@tUix3$zRzj#A@8!p2G@IaV{Fcs?j=s!AT1BQLwa!O9r-$w#J9X@iO-jJF8>CX zUh~&@2^Jf#ssV3~HEHMaI!ndhmn*xy(ynzGAM~a)NVgDP`iV72wIp`VZeD)c zOYZsffX7~E=kr!+pYeqvS`yOtu{)O`eYczQW#!4|t%^V6Z^#WxZdvsi-vaN_dg$D8 z@H75)+>pN8-FvKisfW*F>`|9i4PRHgkwA-`uUj>I#&^HF-N>xxdFK;5JZtRlTgHCI z_rAy2w~YP7!^9r@)_p$TdR=-1zppv?*6T8)uQ?cBDC&0Cv+kHLKi?j>y!P);yhgUX ztQ~|oHiEUKuUQpeC>nNOt0BHnG^DRt72ok5($}oQL-ew{o|%`I4_wxB=8}Hk^5dFS z@!jrj_s2D>;+x$=`kGbm4_sc?Y<62_$K=YT?i*!~y{>vc;~U+>?kkt^t)d})GP%S!(pj(9lO_Me8=L-{Ko^Au>E2; zQewqKH@kaGYCouEDc$fM(hoiM>uPuH1IgIejIBMOlGe@dVF~N<)wh<;bMYtc37wdf z^mS$W8QEJ>JJ2T-u7`-eYl(NG7H`&NNc%eWTJso2ExCMHEi<D@OZzhkKHPPQ310Y8FLB!P;)(GScY~U==iuFv&ZS?CxL0xfy|&6&%c^^Re|Ik9 zndIsvl2h%DXOe54)V@!|+tNx8)_P~FeIJp&#-#RrMEaV8weKU+*F33xACbOxw)l%} zjJL02fA2BrT!!?u=5f(S;~mo1K3MxcV)vCx45MSC(WBC?5v+Y5A3Lhy8o}E4ap}ma ztKIQk>mEUT^X^hTR-{2fwtOhL*JhpzG~m6;$3IHV?Fp)`#vGs(l|HJM!e3gSGDymYBF+cIx?E`#vFUdGaEH zgG*z+?gY#nM1xc=!^>+-YTw5#iIvhd-nH-J(vc^(j{H^oJ|cb1*xL6I>AT&X%dq6u zW543#)a(!;eVZ@8YTqX;@%8uJ?opSZ|sB zVr-wKu6EbHPe}Xv`x?R8_X%lRBVT9kuiE!7jiDj&PFzAvedI#w2_}N#W zZqj}26Jy^k>GNeo@LKbF?+2FnibLN@?D3xaKHdkf9eM8icptpx_uTjKYPj~3x$ooE zaP1H%6Xh~y*J}jFzE4!c)snIA6aD+@<=FR$YPd2#_I-lOyCuEHMm5}}M_r=Z%2xyC zEH(Ch;x65_4}SH!jJfz8?_QUl-w67p8bGpg8PeAroclh$>b+LO-1l+mE0=TM$EC0F z9{WCF_qBhIeIJwl@A@S0HTHd68h^X_7QxoeIINoUSjgJ?}JMbH|buN9zp#7ZqmIjP1-upO?q=_ z7pQO2o6GisaqspI`#$!?v)aFk>Z1TZ* zlR%J_1Hzfp-z@S#Vznobt%cKPK%#f4mJK1l0r5`S4BHTr?2woS%6+)DA;NS;?C;4J zOr3U3{!6!p2*J}}Y~QpX6C(9n5d7vJ2Y!SglSzC*9)p}(bf>5wcKhExLHw+RM`d`g zAQJ{R171PMzCs>zjE0eYh5WqKLiQD6pM|;mLiPg^IrbVd*gsS1OD$6D7O_an*S-w) zZPvlwx@bZ9M~R(?Vcpf(_vH^>S{4X1nGoJ7a`z8JwQNXd|I|xDyc0~jI{6VVy7GvC zHE`HITnX#XpY?zxL8QL)jDBqO^^Jl(2+Q`De+VQIc*!Vq2!bv3QHMPrxK)B+TYW^} zrK3Rj>ohU(aiQ^qfRh`+#q=WrFY|>Czx*FMI9)y>@KRqO;yv70Ra+)qBxii> z13>9JYu>x$3k({nVrrHs4CV=cL5_OJd^GT|&Ej1c#HeG)ePC*yc!44NfvJh&1%~`P z=48G#vB20=abDb|J4^siv z>-&^C*qwUt$CCAhZA=5zQ=xv;!!%HgwZ9j7m|sR?G94LR*Z92l;17VJjprpFaDxj~iwB zxTKy1_b8DgtnI*Ndq(P#C?%0ij~-#FRy*Gj_>1rO_a^zKr%`3+{|64? BEYJV| literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/SideQuest.csv b/titles/sao/data/1/SideQuest.csv new file mode 100644 index 0000000000000000000000000000000000000000..970ce37a630a8dc4a898660619f230f545348d24 GIT binary patch literal 2554 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 L;sgZo>XrWoe;uaX literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/SkillCutin.csv b/titles/sao/data/1/SkillCutin.csv new file mode 100644 index 0000000000000000000000000000000000000000..ccae1b000fd0c46ac252be0f82a41c9d4232823e GIT binary patch literal 63707 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/SkillTable.csv b/titles/sao/data/1/SkillTable.csv new file mode 100644 index 0000000000000000000000000000000000000000..4273c80205b1e182b0f58999e99cc60ec6cdd761 GIT binary patch literal 226670 zcmZs^%dRv%mSi_CAm2d`kU*ak_cPS60nJ)3(2Xt#jV@>=>Gfr{Y+vY+UHNC$|Hb-9 zCu!W9=5&wXfBH}V+kg3=|KmUY{rBe||MosU)+PDtzwdwi+voh;)u>sjGD7C{C$nY@1@KCeDJyJzx4T^Pk(;X=jvs3+5e`Vy%^`) z^msp3zi!jt`PgFJrn~z1Q0q3m)#ry?x9O~_so}8zx9P2cYf^Kh<86BD&r2~2e4FkH z=pPsO)ug&jcl~)O_Evu-()Jg{RKTB~9d5-e@%`-bso4GO^r6`O?DV17{nF`G?0)I< zDt5p0c@?`)m)#fUA~A5EF4yO`ACHjwQXSrpCD~*8tB()K9@AZY?txY<66P_TbuFcs z=jUU3YmkbV(2wb^!6DgW`YV8Bx1S%kX!`5VOEOQ2$Jt>q+N4-|oE>h-9Ar{yyIhj} zI4qxMrw_@VXQvOzo|j&)WY0^dSF-1&&nww;x@`|PbXOl| zpnn}3uj#EmFU6DyUej0Ca>UqcI&0vHB(X;AHJ$b6C730CO>YHCFo(=*dh5?iFc0(V z>~0ID9=y)}s*Kb0@2>{pb@sRgbF{wBJ|BX;&pt;mEiqaLE}bsHRL}d;=LmN5-@o*E z1$$4IJ(tu_%_j}@dwRSdfAsP6cRyBl-_u=v+#%+RPH*+O$2qIxd;02HdUPbrhs%34 zHE>00jdb};XZ`sh*k^hxfMB|UlHzB2>(4vF)S}PXT?A7B4cq7JZwdDEqaJ_G9;-4p z$;yAuF1KF3z}e;2OTvFHeU4t%<&QpgmrE}-=lqTBm`Yspg$~5(V*LjJcp{CVS!ScJ_%jAf=U;VYc3?h0ey386dm1z~7 z5`Wi&iIj>zZ%ympwP7MrF_&wPPY3hn^|x#{^nIwACNB>ylmd+X6M{mT6s?D>?;S zUuF^ky^#H`F*B$rM2@v)BBdaAWb4fg&LCWOCQ=I8p8c*r6Sye27EPoS^n&@jCQZN! zD$d+@RtOS2pRa&x(*P^r+B84}^d;7(0T9q@;P3b}T?YZ>>nPAcethoiH#Y6~oO*h$ z`|}8h8~7cYX5c}OasM5cMn%U$`0E_Ox(0DwYLjQ-7&Sly%u+N~%>)5;6{|5`4R9`n z^{CCG<#*eKSZ5dhNfBdE){{4Bp1Q zK`I8h_9S*+yA*Ul-DV%nMbt$94-;kV8=#V?1L`*Z%|!oDgr2l-H)sW4O5!*DdHdcm zXwk>RxyZ)gZ7f_qUjfI%1|K9a*NZaZS)sWl#klH>8Dh3ovp`5YpH2 zz+mN?bS(Pj{f3!q(y{0V5I5{xlTy-;fNt2i1)EOsa|<>Y*@s)O!HAt(u)&C%1CYuc z62uB-?)v$ik;Kbgfp6JvSh@bZqtT+^XNB2 z8RgZDGaB)7U8F6Imr70LP<$w??zp)ohlqFF+<;mXZx#_d*Q7-3c_Mk&!LA2ItT_#M5>I~BhOSFobi~pPab+swd$&8D zZpf)4rmjg+s{Z6o;_8N+LSpNhAf(Ⓢ2GCCZ*)h(|Td;noKx)l-ZkW5+$|WEZ{+( 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Μ z*gZv|5;a?ZIq;<`oZUg1zE7jw^en*H0(|VAqEP9YEx^a_DGHUa*}r`3o}!SI)gTeW zyQ2t*vJAy;C_)mdWSHGigrIEP#_lLWP?q-sAGk!_ksbP#7`VhQlCi@jo~Cc*G_aLPgRWheLxF7R~is=|rwhg)BpkdYM91ov)LlUYa1Q%6M>c)XNaZsvfM^ z9ptE&CWtEH{^YEeCTOa3m)h))njopJW8rezOA{-qB94a~_Of6V&1o-7R?(*hWG_?p z=s|6~$GByz=+BG6*%ukr7bjmuG-IQ!I5kpI>qu*Wjf+Ltqh6Y*Nb0gR=pqrcdc$5~ z6Dy!1smlqW!3fH5&Pgv^#?@)XvIW_bULXln?W7t>#H|lSRfr*AGqJDK`$(ye-NZ&n zT5IDIkJzNbGSf6; zs80))eMU7IO(i`|+ug(>67|iPViMI*eYarCFmP-qHfdE;W;T^oCNf0TeT~tT)tyHK z+V>cZsyc#X-(xhX>ez+dV_w|2O25^iSszWZrv9>j{d6re3aF~iGPN;^-6Q=qC+FNV z<)oKJm3)&C_BBRVtpDh71XB*H*hN}ZMtk33q)1d{Cg2sfj8)Bz%yZvhq)c*e%6MOy z$LF=*>qe&q9)y$l(G@LF5B`;)Dps+}M25Ud_S`oZbsfv#IY#Q+HyAM=8Mi{73SAwt zs#F4R-(hsA==z&nx-T&bRsJoFu!~(`hbzm|bKhcADTH+k)2nkNO4%$OPdsB+SjyJi z-?tduLjT7LoYTp^#0WXE@V>(cIkND+!U#cIzQOU_Hy9ykn=WA*$ zgH6RHM;^vDE;;fru8}E+kMd;AE%}p8#V?Xr#xs7ABta}=lju-!iDPV15u4G*Fg8I~ zhYINy%Q&d(V`||U2UUehotVZ(9kG!Q*ElGaDH|G3Y-6L2*sQ(y#zsi%7LvR$j*TW4 zGm){5jXGk}_Q{frc_KE|O>Tf}HkNtUeAwDH8*9(wLN*)c;1}!JzxG=Zn{!{jfc;EP zeYpZ=cg}oi(DCX?mm^=ALu&kHPSzP0$`S@aT%niuhN z^2?Hl>Y1ODUzS)@e&Ft&gI^rVTAH;Ccv_I3bMDIt+A!qUmy;+vdb+*lTQIIGs%E*) zp)XzJR2Adcpj6FD`I_&*(6XpX>VD04U?8O`HY~@!bbY9*7bT*?d&UxG2IP|XaUN6{vwX>9Uq9!49LrVim3JB;19O2So}r@<05WdY5}FH5qt zGTQSvI+sCHZhc8Qqm1@cle6vYric$fL9A&>e|1QVB**}PF0aKJ4G*EVC;)T zQubnAc8ybH0+j*a4aP20mMK%mzHtk+q&6fk-eK%Q9jIQ^IQ3-;m0{8w6rghmdSOLU zUSjO(Do*n<3+KK}eVu(-KVQ7X*rlQ=8?7(iVO)^p>xK2jJB&+qVddDDxlTQ&!C1d+ z91pS!>mK^TLl0}Js_786QM)2~6c)7=sEHF?<4IH|vA{NCla5qs+jkgMTXcv?-t%6# z4pE{epzFTG=q6Ns*rM0I#c0GlQ7PuuzQ!n|e=rL?W7;!c=4p+)%e3G37*!<7s#ih2 zv+iCcT2+dbXdg^7dHlW@*?X;P{Z3vXUsY+@Ol{j5;V zd1*4TdcDa>FN0j4OEIKa#zC#C6JySLX@ssW6*P%ay=`I1OF8YOOChXFArhO8jXGLM zCT}(!8+8&+kFk!8&LsTi(e#ppD|1Lqs>F>NgeyPak@H@*4B`5rPgut#gzF!}=Uqof ztCCK%m4ek-N5vO;P@AuNA*z|C**6X-X}N>opqC+~#FGZtHV$cNGjKMJi>kgS(t6)< z(M4MCI}Soxb?M>c{kC^p)VDZk#yJj1>rzOIee8i4X-NY5(^lAt_{o&TLUt)jt3h%i ze&Zk)pe$c};>4F}UY1wR$5oljNaS^hD2s#K+74yMK&r|_ZS3%SesAXhX<56+1Eiat z3YzKOzn@oJ=%xC+gpkd*b~xx|inOfQruTS9EuYs zQ>fz=KgD4$gG$txUXFViRHEj`T;BGNgG$u=n9G|l!E`H#*Ze{c2fj?1+~Z`MmlIzO zlGT+tZ2NeSBNf{{9^^>HHjm6W;S!ZSaE^Pq0NnucO{BM-)0`thSDWuCm%Z4k}p*eS60P94oBN<3WxU*52_ThphIF2RUT5bqsNC^%|D%NW8t} zcmcD(+BjZF%WB^^pps@Xk8R_SlGP6IZPPelf|W_)9mhqNS;7zQD28=Ip$1p9a-;RO zahy`6Yt0io$3>Nc+4p>}byS6=YfY3jkNO;4ZD!r}b&nz=D*?9tQRtL)?IR$vvV!eb zUm%f{slWCS!s5zr;^p9%8HfCy771PN2}?+}8*AgC)#KckFQTW{>JP`hTu3dhocc20 z)RjYDhC~NF@TM|*g=s+DYhpb(^<`1&(}QhFX*w)Ah2`9rK?tiCF;YkYu_U_cp||VP zj9R48%N;MJFp%9qbX9#;;)8)~Qo8C{IY>b7 z(bcOShrb-e;i?DH5CuivIvHK_-UesCe385Z!O<@lq8XE(VjX#}M76cB$cJ-ml7P+4 z;RoZ`q$3s||G_y9N_~12)$PVQ4k}^&gR?>&hDM!*aS7UDZa?fiF4>s<@Z5R{shAgE zK0LN|H233i#VVq+@%RN$iB}u106YBQOE3*uSjJ7`p}p3+h;>ldJDYLz%YfE3;_bVQ zF74{nGU97rZZt`CxTep(+$e&oD#JkU+l?j`RfNFXw;M&!R3xo-Ug%Z}QidtAZ#U}W z3f3Q16p`)(s-*VYd&H`=q^d_^@{ zN%%vm<$3iNiE=!yK8YI5;IQl1;M8DWZPZmt0tR|tZKT7we)8hJ+-Ov_QE1<8G^s#k zY5nZ$jY7S&va|Tv7aWZ$P&2Rg1xKL@RDD;`Q*PgI6w=@^KuHSwhNF=FS;6-WM}2&% zx-U2ajugzp>K?kfyLr)DHXN56DR^ISq&BOX2RI)#99d4ix};@@%6{Vs^zUyn((X4- zk%-EZ>MnAMy1R`k5mDK!`Rs0^tEw@>w|;iJ(dZO)_Zv-0)M&8#jY1WtS;2R|(WErx z?uNr(vZE(7$(KRkNp<(AG|e0QpWSd&sn(S6-VH~QQ`6mU1RR>~ZX+biDoK$i)!l+~ zv;V`B>Lo{{dNIx8AZq*n$vU?zNpc*AZfHI_Bf{gc|BVfB!IycRu9;I=NJ=t6q+pcH z$!eo9vW=VuEkNYskopOPQjVw_FbV1~!E!D(_V-hAZC2sjYvd!JTI|f`+-n56l+MLQ zkfxN`oSTh?I`k4l`1qyA)|3+C^&ig++}NwH*$&cPN`$2V%uHJ|>JUo>m_ZJs6o5H^ z8C6`z#EP*8S1Ep0A_ZU$vay!}Fb7#issEBg2BNYVMdecdN#&QZ>8;dj;E#)q5~pa1 z_E5qEwO_`l`OG3v z{zE2Ol`C9#*tIAAArdd3F|*75p%E{lHQE*z5zVTej}}>+DBvJc-SVFPo!Z3?W2ioh{J)( zM~MZ9!$GP!yccoUNb?D6h{Hkh3X>>~IBcX{6u(9tHUgg$TakwiHK8mV^kE~HQ1syf zC+Z>)7dcTEeYnWkM$w0hoNW|&$foSQK^vLxhC=mRW9(ZHS`bXm++tjS7r(!`#Au)x z{bg=YhTV%Ps1E_D_LBYG-Cwm!xtE39oQzmGNW*Sz)Go^qZP*Z$YSeigCk+N^waWvo zIP|zZ2=&AYS#>A`PCY&JwE9pGoXRMOb4cBjIn@vt_v%BLbl7EwS%C<0I9-7VayVUq z2y!?@AM!HoC}&O;XdT`6+vo-~OgV{lgvNYL9FS!rL{BitaZ@2yM{Q$L)s5y;fG41V zAvOIdwY-p<(|NC^T1MU$$H>iDIBG%#IUY2mhs8+lBV^JBdZ5`$(~}cvZ3L<6DZ}$h zXrvrfXCiJ-gIx$xa~v(?PJ>C+!-`Y^cNRh_^*Dt*ra=y&IdxiB$YU1vN4$kRW?_G8 zUx+6`o$915q-uJYxcw!a0?LDB;wgBV6sh}lv}~GGxrsJZ&p_LRg*+$vuz@Dk`bajO zf`O_z<`acDNHynIOc{9&8iG_!5Bwkz2Z^Vmb!2oW0a7&!tOP`28$C%yB{l@94$O?f zE1?mSs@5P?OjSi+Bt~EBaTs#nqYxQYzR`-6Z3{h z93-Ubi%zpZCb1z%l~KlEZ)l`QRi+#xuY`smRYt4?K7MJ$q{`J}Vs}`;q?SLT6Bof# zeOXlBSw3drdMcU3wVCiM8!rUKrpXEpsmR2O_#~EyfJ}Txm>pzdBWBe$@PJHg1XdNS zaLB#D$oR{MXt6gK4Rw2YR(nIYSKBJT45M#KJq-MmzG>^Um#j zGM#?TibOhI8%2aLh;(cu+-gVm*iep*m7f|_>T!ma)*#^@>ah`6m5morO27|u*hz)DFMU#EaAR?;!Y-B0~Z)Vk&YJ`LXnP*giuk*(7Xs5F$G#3c}}l^ z2Fg?U$VR`4yV*`cw6K3FK)(#-b+9((ROS0X z>-mLM^Lh|H#7vP8efbY z5*vZkS=*?`hRmwsG_#F(T;O;r;&G9%%CbT`E^<7TB;z8-Q>`4Wgv5*fP18NBS~xxs z-36c7(uD^;*0@G)f^#nFE7f#jA}wzaeH+U zz@C}})4#pB2*PVC38sI0a}nft>Rwy~IiAYRMZKRXwt4_r^UMJ^7cVkn_9D2z#2tRK zyOGO+{@bxBPCWs7lRH4WDq4t=FWXO6h(C>#krzVu)2U##TWY=x1gV-)F9d47EYf?b zR{}*}27=TIvQ&K;M001(v)NGgWuPLJ?UuSPgA}Rs<0(GCl1kl|gDk0(eL2XIO4*l# zEUBsb!kcU*2c0j=2&|OekPMnk<3;>)sb0M)`qD^P<=a&uR!WV)s{R12XvIc~R(?8G zKdPun7^CDO^cTJ8Q}$)7+@NNgohx-;8Vaxa6VJ2<(t6sCz*$23(TkuED=RzlhyLOY z17`KWSwo1%?kmjdPpmvtV?(Ca`Pj5~=i=rfJ~)#YrBf^vl}7E!%!7 zzkt-%YMvMYqVXcbI-2n!wt*)!VloOvicJ&AsYv3 zZXIb-_oboXmib0F4iu-Ybwt*&q2@LOA{`qVZduHT$A*Sm29J7d2)ETAGC;pcE`n?# z&qV!~gB)&=k888rE9GB~&EZz#QIOS=XJushd*`G0%NvkLh;n?hVB*k?4TRY8B$AGe z6c4N)RAU3hE82|0FWY^!#`-}vj!m=5GC?;s1grW39H1Kq38`7!4p-Ar@20*Vw>=QjVt^F$pq(Qc{f#jH|My$u$n-=46xsI5G|r zPW47^638_+1gCl)CX`g;AjN5-I;qBnAhq(hA7mOEfm0!jfka~?a4LjZAkWx{Db=tU z0a?Zc*j&*?A0!zUVRI$X|3Q**kwYm-#zhXLTwYYC`shik6(`LOK#uVp$kTXlcp^1s zXA~L;r8U!}7#k_S!sEy=HZYVDz(_F;R4asaK#p;cc2m{?$I}g!n}!2YjDtKVCB@j# z_^DS28OBD+O|yJSFg8+d8cI2!Zsd5WJnBr(-BaZ(4`kymm0o5_a|tcyJyd!*$i`g? zy(A)g-HFoHJ`{R+Aa+wPH|o4R5ZgHLQRZckA{F&Tm6t)xLhr*=c^TxvDs^5Ka(lM2 zFDONzSzwRxxG$|#dKu`kr&8)=p}VK1)=M||*i*IXp1yidCCW$)9tdVNLe@|UzI218 z)?@d&Q<2VN^x$^2BWxUQ^&IDUk6uc>m+j|p>qKMTy)-ho&6}JG<^3118&U1$&4Tw& zioFa_?v)v^VjKiw^IlA;mjRx<@}aaN3`rw+{hvRu)BqF}*62a2I9VvPYQMCR^NeFu zDmXg|JI1>fD-+v=9b?(!8=#@Z|uzr&96dAlXwLm_98S z53&JRKk5HKHUR6_?u9s+s7(q+wKXsW7K;x+F7HdoUzB_K55inqDh^Vd{xLKw#X(Gh zy74ARsh0tYQ-uW}uY(y{n$sYFlyP4u?V;iHYs3eEQ^i82+IhyYfz#Rr^&_tbfl}G< zK>Wf^51|8aoY7)&nuAkK4~qHIa&aJ&DugZa({k}3hgIvvgB(_!W<1DY)q3$DhgHkP zAog-iw?GjjalW_1k}&01o|))hI%iVY+1mnRteh^X~s5sxGHJJMUJbIW?Uq$ zO1L1;xX5u;@{EfdS0&E~;!u2?i!|dC$eJh1cmXYtECaHPjWnsmQtQRcfO@%}N|v!r znpF6a05~?}mMWA=k6fflwU_9u{Xp%io@&ay%n&-W1Pc^=8K_D1nxo>&Adp%sTX#=R zN5v^2M(6AYDNb=z-CTGe%PBQqrk{3H&zz32A2!RWPJ|!Ga;h`bMl`VNs8oDOKZ~&D zDfse^5UwcrGDx%PkgemK(@(L=wE05gm^7NE}ItJ(FHz&Z`WtF2gDYJU4Nv04iO?mR^PQu|sR zJtm?~Y*>yc#vVey+N8C|JnSz9eCchZ2jI;zzRDs&FVffm#9ztJ|5#+QonOqn$)ZVR zV9qZNa!GZ1aeyY3x1=whNiP&qGt>O2&WtS0#pzIsjkKrcX=Va6wpL2;<`6agw4*xu zQuJkzVl+{SvM&R{Xo&$$=xOc}x^j{EJdWzT;xyKdnz23R;M_C(;wN?bNzVsU8ubK( zNL>O{9y=OJvuUn>+1T`ygsXr#Q9 zx4^Geih_z!^w`%bMI$AXaMD$ZLW7xZ|O#6ah?V z5(!@`6+yh4Ml64=R0KJZccmi8iM*>6EBWBy!Go?+JO~SCmEu7xYra+}3VCqqelrC^ zu9L1xbYsmaZpB$N%h1r}bY-HE=9Fl_VRRd{mj)S6kWoe6qyxTIC<>a$n?X!K6f}{S zxW{>PcQujMiur5Rq6c_*^&e**I`T5Bs}?bV*X+V87C{cLD;7Zxud5ZU%OZUf;8rUx z62DuiSV+s4Rf+{ zDn%oueY171R1{Rcnn_r#D5Rrr_Qq9o^sr&LoIG;$_mnXmrRjR%;P^2=~FTQr=a3As-zlX6#n=1-7z$bp7f zJ6OuUbc0PSq5DO8u^|&HZIzz1M^1C?u0a$R4zlk0BDc7W;jV0XssFMF?wW@+oyiX4 z$bKsB0FyoJh-cl^9!ZwNs|_OC#YSJ!PY0Y|hAU7u?Rt{QmkaE;e z%Fi!01f?=cbKW2aiJz)CIz8Pv=xvoNTQBrtTNS7Lq}ta@JZ^(UD!-d1NK8&&W>qs} z;X&<}1FT$np&7fQ(!UuUl5vr2tGE`DaS>Sk@|OSN3Zp|*|D2NkJ$&z3v}w$Sn;5c3 z(S_)I(<0%uC(!~zYd%j(&6n;bw5Aund}*L*MFFSe%Rt>6yzW7?M^NqYJbMx?q&!te zNFLoDMH?z!vrhIb+5@j}!I}4K52FR?ALGi+)1X#^#U*ps@t5QE7w6Fph1bMI%f_)O zZ$+NIIFDYFY^*pK=h2I-TzYXJy~xU?7w6I3{dXj0)Jo@g)O`DLk-G5w;xzgR)R?_9 zH1P0N&Y~MJ4Z7jUO5iBEf!UeP&Jy6;sq5k4Dx{;!lvVUJMj-v-M ztr`T5%yD!h!)hS!4-FNo`8?yrfpkN~s`5sjI*z0pGOKmH`?X)aFx&gK`r5BvKn|;x zPcwx6c@MmmGwJOHR{i5=UoVcNxyZBBWS!Dh6dp~!9 zh4s_ad+{sR{=T!$!aV}y;uHDz#es=W-#!MMm_b-#H*_Z(LDn-`G7DteK)TwbS`&w4{HUceV19OS?C)U`2; zNoD}C*d|3PThljUu@SSN9p1j3QZEe*sql?j9LUXS^LC{8MlB9fq;mY1YA+2zs*Eyf zZw-SKr@Yfp?qwi2l@aTgyNhj9!8hNgQ}JbtAXP@t&DF&=GN*dj0A2?RB=*t|_ZAmP z?2V11;v(iW`uCe#i;E=o#>Vczod{lhHF1*3K|Bc;F{wcu7B3>3Oex>IH1cp&(?2$_ zs(zrAPhQ$)Xk}gP=h7Y=w5q3AIV_GBWcd?=Hs=ina++G~W#QJgJ9Ld;Fh!x~* z;2X`@P%+C-V+p!b5oYV4_8ZyQR!}R1QP{6`>^WCO>z=YNn}*=s=9~MA+Zz6wb%$zP z1aA2v`5V<}ecYGO`dQJ8Paw>q7@t74F7#pp4`TQ7qC}v1=(*m@i>N~(UV!k*f9TfW zwI^+_FZ%DayW-<}e^C&$_I&OIMk5`9StfgdQ4p-wIomgavB&TvbuTc=2vTK4+};a} zLd>Zi7MIxTivYN5DBbIeAh>HN^&4-lP=esD*^Kx4BFIbK@P_$~U^Lg7O7*V)(;rw< z=*4#gcR(+`BhbM0#YRGEz5w_}EjCgtWdBAiHd5Z2i~irp#ewiv{RtY-ivx9o3?ZH32qjN{o^&jVS_EgY+glw=0YQFRhB2Mk#_9XqMxF0 zQ}kt!YA-8g&Zym96B|dGLuw$Lwt@h8$8N9VF`+tzUmAi}1!gj-KXXj&_KH`2t^Mm~ z4yt)7`)nfrkN(IC;niZ>-++5~sizz|O<`Z7?h5rQGdeQ#aJ4CVq2JJy5(guc<$rR5#SD@``jSzi8y~R*4c%97ok{G|p;`{li&x zLpW>l!l(2LlT92(3jJ_Yy(aNh`tjeKxx1OBQ~HJ0;;Ysnsr&-nnp4MA?Qe{1PO8=7 z(~0Mxx{=-z=RTu>2di^TZNxOl#QNiBt~1h>UA1?wIim*Y)`)O(Mh%qac!&P6fJ{tK zKai^C*j?w4+BPWSlD$83NNog4Wy3x`htx)3R5n5E3O#G%rYyNRrDkxNIoUANb4VQk z)kLN?Wna3rd(-8I&!!h4`X=zqF?CvlQA9K~UvlPC@2@(MV`PX&O}xBz7|kY$c6>v4 z&iw#JCdC2Mxu3rXD8CA$$i`_a!Iu-kA7tYo%_ubFGk{} z%(Ujqp{X9UoHR!?`f-En z&9tfQwHZp8g*l$ij4q{fIvpTxNiK!bAcs=qVvjl((y{}m(2M^5eB!8= zysr#xa&4p={S5Uuo`P#4fMvMZMp=Z?WE)fBrA^F%8gLB#-E1Sd7a{&zw6^I+LvBv} zI9jK|OSjg!2;K=(;-w)tRZlq2<{Q;q`DqRYQsbqK;8Z;^2OLi~Qk*t)XQ4>d57jU} zuY|VBZp!KBuUfbOyJ>uG(~W*uO`gozXMgwS89_Go{%*bzWMgmYyzt89rRSN`Uc%7G zH(sRQ>3{i+or~B8j`)$CM%q);n&+SqXw@1E;wflE+ZIE}D%D&a2wr8y(w>Z?&c7$g zgt$tnmu@h`%F3}hwO$5lorJee#?cLiSv^&(d?eRaO)Z-2cQTH)f?Cf7v1u}nj8JoH zg!MHE#~>#LPrfn8iNWS=#!yNrOPq7+9$noajrWmn~x|q+)P*wGbR5c-4gBdt@Bj zs2w&eka27XT4lt#Bjeb}lT|W~4VA;@UGn1?0f zxX5u>GLDNJhea@|Q@sQ>sd-ZL;sppR9sqjrBKmin2)WomlgiU@r?HWc8h#Lq4HT() ziTy<`4ir+u50@GTDN?iG(2ETYWvp`OCe=wrW<9nZMj? zYzS6+rE;&akxMGK8W%WGm|KmDBnmTiTxwi|t(6zmU+y$6Vp8*>`pcz8-jKLL<%Q0R z>MwU1p8zkaS{j;yC%}uU&L9uaoO;1i?PW|tLWCsMUIs}B&J8Ncy)2UEB253R7Z++z zb%3Mb%RrDS&qse!@ns=LU~O}rH!8jiQd=w6o+$Y;NOMXel%g*Kji=hVDEl&yN!6Ts zlltQen4P)}ztnv>CL4aK`*M)gOVoWi2%gFo{)cGPsr~tpkK86n-Ipg4A4=VqCzA8W zlznL=MC8Xq{~QN$T|={G9<&+QgZ@yAZBo9Pt0}4aGEglOJn|3GI8b=a500kpOGCwL zay=>hGEjC_eIdm#92pxbZ`CJKKy!ab|Gk*aWtS9xX{%y3mt9i+r6Dt`2c{=AvOQH^ z3D^5WJgy1uN{;9c?YPKcmK5V6Fw13^zfCbBr&z-*t<5kN&>L%NzYx&Jgsm{8Um9p4 zEFe<(r4jQWsfl}WO5H%YD@x^0Q&^jjd#Tnk)yT#%s^*wAWMd=ktr;A;aiG#m$mbM) zX$V#|JeD28v5_J*yXW8jI-|x{q()h%{!3fMU2EW@6_~k=!GD}ouSsGszOSawJe==s zQvPLac4MXdi=%?1tgJQNdiAzg`QuvS1-!As5Z4-?NO>#Q8XGYWdc{v;a)#-}EC^uM z_zb2kAhmul@sH1721#Q`7>d74W4ztS#*&rdFN3tF#=prhc602jGGZZ+U~B|RH8@rr z`Nc+{R5lEo^kO5!Xqxi|(U2KcYXR;Y#7(7b8MflVF(Ck#jaI=yj+>HQ+-~Bg^t0JT z3kJ=#k|4M#AHuk`e*@%YjaS z@C9?6SEn^$+V*T(K#`D`vq#fHiUfXG`;Yu0Z(DB6q-sxRFWZA@Bi$V9Z4agmb$fxl zId*%Hs`gk3donGf*1s>NXOE@@=^y_;?XaG?J)72lhgG#FhWshS>1jMw6Cp@U&LGTc zHdFz=!PKK`PgOrc`tFX@pqGKUGZ8}OfF1-^y%L1Xdo;+zULlSMC}R+h)N)aP1HuIy zd(({r!bM~vx@9u&4Qi`sNdKa1P0WH!m>Ry8p0?Uk#e%*M@~!`Y+?@0({fOd&6sdMC z895}h5u|EwWYoUYxJYlP8N{6f4INS)ven+51xU?aE9B0?kec@HJeX8HEo^H*JBB7T zi2l-yu1Tdaeq5)YDCq}I?DUz`V;c4gDj{A7=qC+1;TQcY#0%kx6sufmd_yvTQHp9T ztRjEanDs%M6b;@pggCR*2)^oHx`#Y3vxVAOVSJ^chn)t|zxwdY?$8Z(1P(f}m zqP~q|1SrO}$;QeQp%~?9^Jb&-nM?zM@g2b@_&vsV1fM`JHWDiSeWf4IK_hWkHc*Y) zQ_u+1YPX1s@q3H|#baxAAs7d$wc@G>`a;js&``N7%1n@5XCV8m`yxDXxv?Rr^`;fb z0kR>ewH1#=s0wKh`B*C_5>Jh&y%xHcn$W#jd*$O*+H8W%aC*djaY z&Qqd?9d1c9vK|fsw?9;)GVuXqw3Cnt4xKmmrz9H}Ih>MhT;y;{ zws8?Sb&^T_cpV^$xF>Pk75(^*FmK4mcZ7LEJvMSVRo|zdco(ml`mESNs%>yrt#QwR z^u|TfTpU>j7jk?0?!|+X+&l=R=8G61c82b#d^H}ffOQ~P%?CCzvNyC5qzcLC92FXY zR5b?QN*x@?tm@kyuO1Ql0G3s8{Xmvg391LOtp2ltoDtN?&6jth)PRvI_*mxQsk(6} zn|FkXBi;CpnALw%LeQ-}Smm3Twh5~wFl6H?XarUzGU!K~9Hd+|)3Zm^9(Jt~hOlSU zLMjB4M9~N4o`vqIXeDl^3``^KtLTgrf@!ECa2DNsMeTT~cHp9qdoxhn70|4@x> zRHX8;fsE`94Hc=pKvN24ka%jAFsiXl>fJT52i3U93BZWPMa(H_CJkT$0tDfyS&DoS z!{$()s$Bzu5R4b_GGKPlix-iJx9ESU#Rg1*0M-Xuv4L<N}) z#X*`<)&XL%At==lARDnbNarI0&Hkt<=sh)0I@_a=@l)1;XDeHp{tZgCb+Ujh7Y8w= zdLm}jYViOGzJz7Ihv~s}I)V}KJCFO#zvY222HxL5lGbw04s!a;~>=>@1+!hnT~o(O`Ip;*jDYR3BM#9 z2QsbdirGdlHqv`)h(ItlG_=ObYoVd?)c^6u`VYz2ka?}#p&ahm)C=pkA6FMJ9*A8v z;aBJJ4`jnHm0)HBbuG;YcxugC135~KIpJ3&xInCxo=AA54$K4bH&|Zv)PWhKnBaw; zGBAUfSlgIb%D@a#5tvUy^pi54gc*X{vlX*|VjQSf3WM11VDw1EEMIl0L2nRk#m1@z zSw&k6#y^}~)Fz&Mpc>n1sI|v_AR8NkT944IZ#@`(iCJ@N#F1<3!30?y{4u}j9c07s zmV*g`&!Q-|8cdK4!zl*CckAV|T4;Ey2Bx8o!%Qfeagd6`_;TvNG}Lj}5&r|#*vPQT z$dQc=mBS|5eIOhgI)ONaU=~0x`O2X>@;Wl9#6X)yp=1V zGV%#vxXA9UABe_9c5nUIM5D=-GYqAhXe>lSV?U-&N|KX{ zWJ-~YBqxQ0g^EZh#zw+IJt>LCMxLyq83*e2SR{zXfx1D~FRHPjC$GrHf$Xe$C{nv0 z=*EVc*zkvPY)B8rB!xe(wwa2=VCTrZj1iA*Rn#Upp&l1G+@c;AIozTi7dhOb9v3;> zA|8>?dY*c{Ve-(9PeAWN40>K6#w0rm*BaX-?ppjI92+qaT0!)JZfu~4<)H5a;W$WI zE9XZ!4phxSE6TBvC#^`wff9o`G5c_$F|Q+f9$3vGx_*6a-XQd!i_|P)q+_@CbXSh5 z8#1SQR@@csxWJ(l?YPLH6z#akp>#fl$r0_@R#A@X^n6#tP5##h!to-K=4?=#XY?Rh z@`=EkW)$$CbkmGN;#ETtr&PGe9? zG)NtowOKFSGB8w(@RUjxGI6UIHDZ{PienC_G>!B-h#A@%FmCOVDm|$OZ5vq7AMB`G z0frGIzD2Zd2^b)^*P``v^`gg6p33&g75M3@d1Z6oDll%a(o0d?pJW<)fFV|Yf>}gk zLr-Q=jSZ>Ij4)R77U2>4fBJj&3EgNtb5Y3%e;+5r%b}aQZ?2!{#zod$DF$(xioje}dVQ{Flo70!YNQyP{8o`VFl_^;x$7rHp0Gyct63u!jRV1{ zj9_l>H7eMbtLk8yo+J~-2vTK)&sjANGM)php|uau|4>Yhs*N^{)L*6*r%lkDa?1c%l=nU+V|fP%%UB85WThH7MpLxWIa~%duJk-zVS;<;saS`wZa;~ z|Cd=x!em|#;<=+D%mXQADF`z_GwbK1Aj}}~Shh*sC%OG+M&p+9iVL|pJ%^V)1!1PO zc33nM6=4Q~R}Idwfr>DTRECMyPfEfJRJ6vGsR=XC!(S;1Gtkh=43TbxJ?3s4mZC6Y z)3iE3s^a{8TKRBG?4JP>ov5x-jHWVNcE5#TTma4SBJ2^mHY|%f`~3$woA`P16A198Wg_ z3;F{Shh}U9THPG8gK8Y8+e=UL`rt9RK@B|Yp&Q#OyvoJXpclhH@m9)Vzo-i{P?(if zMrg^vgka$=TNXoHoS`YiTOkZE* z90ziH8eL|Aq~k!mc}TW?~MkgAj@{0wg5)DSIQ!KX<_N!%dpW zCsH%CDaW$WrF7JeetzfJG`9p@FCxrXKa*%Wrc_O&^vYE4bAx z!TRPNWfX36!1}eRM-X$HJ2CqH_R$);IH7-YkJy;oC}w?O+BOa^aEo5mw~PM)B8$I} zkkGUynQ#(WcJGNdanrmgh4+5`xQbe&n zw75|DtRuC)GB`-n>Zqpc_y^I{nRR?3g<^VeMJl&tbY=V4m{V;Qe$*6-X_I!>bTi9< z8I8NfX43E=q11seWn#9qC?{+*i%}tQWUucGfa7Y%SCc1AvC+QeLTwiJlz5j3He!Y_r5OF;-_5=K3yv5mi}5VNgq z{M`aEtD9;{5sxf_QB?lfE0ysWKNx^;xz%CZ)`L-$W4Bd4#gNgB4YZ4rYE!05&pA*v z$3&wX2T5~8Hl|Y#S(5YjD7|#zEYi5S|9TI7l~#zabbKf>N#HAfAFj z?4&~AfHUewI_M@&tzy*Bpj2ZZw5?(k0;NK5QVyxRId;;{532Y9L5RhRXqcI7wBkitB&9G+Be0+q#uT6w8!-#k8R=(U z9T0|s`ZeXne`ur1FqIWjaiDGxiqMJ;wWo$x#Nt5ks$swcYO$dv_J<{eTx=-Bc3?&? zHdM~~zaN$)g0Uf}l~LNWPb_lW6~Va3;TFBP$Z=QX;v&agQHvaR@UqJyW_hC(FJNk| zJzq%0i)f+7#2(Q={43idGO>YnFCG(>*ofAh`zJ+^(lCR>`HNR%;z00PvxZD;xd5;{ZmI+rJQX!_H<`or{5-|gnR$@J-ModHPu1L8QiD?L8^#@)S zzvqh>Kk&G#1Jt*|%Ne2ORxaw5pE5Ds+gn2RVt^10Br7eOM)+JssZW7{+pj3yRCCc}PMyc3(|x*1!JZ zP6gCzglxax}zuT|QLWr=uPWZgF9Vit+pGE0cZMR41!6vX2q8;L0v!^s`jax;4< z`){WmABfgNJ&<;Z2QqGJ?Kp_JkX~e|YDN}lCLrC?aZI3g__KIiD9yQu;p^MtaglD% z*@kbc$AQ9ZzNe&E%pz>D)DV=7)Z-u(ia90uwtO69XeHcmTJ6^h&s=%zC!bn=b6njJ zwCX0C2dBTb&D|HAZ_caNHU&&TxZErccmud}VdkVxDN_+gYz$p+Tq-f1Xa4N(YD$V3&k_s_B zhW1w`XKy*mru`MV)%K2i+?9c^c=YISSCrJxYDa*$Yg&8Ef~HO+WJ>pfBQ~Zqar;M) zup_7=R|G-I!$3ARP)hD0)nVQcJ{3uEm?u&Ln6$eZyWX10Fl|z#GM^~M25t;aU6?_t zHNP9CF3cdkL?B`FjT%97%Cv31(MVAmWb%z3buFt5Zt{&nic*3zg<-Nm2pLK&5}v z!(!qo=x&+^*t2RJq@u7cxHAIJK^r}{Rtv|4Dg^k~H#KfAhqh{BGpUx23zf&l&mH3i zDv#CoqHfUQaiH?poV5N}Jr2~&@+R|R`8bf7)g-a{tsW0>Jl5**AZE6_&*JeQFw5^o z{8&341ZMeg`Deb5$@e*|Z@yvunGa+ZiI&oZW(`xl>K=PmgI+Z)vUG9!0GHWRiD{F| zY>LD*()%k!q)f~}ZciO~p`=XAAk`j`Gj(DbYGV2FHHBgZGO^Me_M;SvX(YVbeSy4N zHUzI4gx7IO#WYg1=A=HwVj2pqd8ExcGIdL9ip8vnXw?YPkCwuWpe{4Ij&DHv_Y5@9tirbg$RK7xZFv{{MK!hwqzZvKWaA*+ znqBgDKd1JXtGOVafi`MR$q@b`90xL|N{risQYoepIMo;&F@E=pYIOvq_4^RN`$4sk zP%0K2=zjN$YG!nPIwG}Vx}T20EFGldB8kDw0?Ecj?5T23ce9^U(+!joX;UhOk0UiO z$6&b|BSSb|z$*fNIHWLI5uJ* z)uRTubMPRPgX%Rogqo5WK>270MK!L?A(Vq^@=lsh6Y7w|dgq|}BE#tB8P_JWvx!C_ ziIq`UDG$@FnFKFs9AOiUZmo1m4Z)MpMoC1-iYeVxqphmJtdh+&3W8QY6BKQ((NOKG zVQ+Jdf*{r-WHoHEQBXx+Nl$yqW*Y^;tgPZHn{5%Ximl8tQy zsi}dY!(hKnHUg)5Br?dqWE&eYrvAWFnUS!u|Qz|QY`=};l&KZs|W3NimdJf&2K z8Kg*MAErReAUKx#@j|3N%pjUNoQ8f@DSB+hs(*Q1MtW&jBey4~@w%cy%plDwA%PMx z3z=4lU+*?45#!L|U%sjEoB82VV`jH3MK<9)aN zy-;9})9HaAHk;(1rgulsys}ABBW8L+FV!ZQ8Zq5m)5>StsS?xBIIP3^pOxdZSG1N} z@JV%BWozYZ}0*IwQ1Y-l2Q{-X;;q)^B3$@tDcq?=x7YC~5SXG=&4^nFcRsDxvZ0JcUf^ne8 zCGPG1tzh(8tnD3n{I`-(5Ty1>Sji{^PW2OYILc~9AxAC!t!4y(QuOrSYDN&$QUcRz zMvyP*1yXN+s~7=Z1_-p9V|2VL2V!|_j&YFO;n*TE{6ZP~Q+grA=t(os5tGJ9F*eeE zN|+_b*huZGiD8zD#2vb+<`POtGLBKTN6zxkf^n?$un7soF_MgJ)h{-rLHF{p$@=V_9Ph_%HA4BA;q}B3BY6+7fApn{E=c@M4qZY1aV+ogaG`_ zus6l%&{flbLu`t%5J{9Y=769msZBU0l?SFu%m7VP5Gfbkr_9<$&NA4PBwXV=Vjr*reJ zC=<=W1CWq%+FFRF;DKoT8MEJ_yDgKD*Fjn6`3EouvPkdFF1E#!QU{fV(wb$nvvn6K zO2ZC{vD<^vysOH{vU!jVzC!K{z-S_@kUIrWM)x}yS-@z5uZ->_m{C0|D{;P|&P-46 zmC0ik6y=-{+U!FnDwdG3?Pr(x@M(14m*f8cf zmNpPCwYpUIUIX1$Q-GI}U2LQ%jaSV_F!WNb;qvnl3`jSJ>uB1yBN)~5u-fJ;7#mgS zjnB`qG^0+u_Q8s7Gv6sFMl;iUEUnfcRQ)*lAR{k>c_Phe-c$wLNl31+*x7SwwN?r# zKFW76+ZYNd(?fo75yxG}P+he46qrSRy9!46s78nv!8-!i`yGs}Wus*TJ^LAqfN+4i zRb%#pZp<9Wgh?a0*Z_>mk1{e(z#wT&QHw#_4F*bc{-HAU<6zK8GaC2ZuV6GdDDB{i zNNl4DyWSOb*Zj`G(@FO`7&WJV>|;#ts1?p$`z;c7jQqrpWc@FEj0;_G3O%HRK+uVC~aidAlg3voDT z8)(oUU0kwd;?<$V*N~kyc)W}mPz59^kPF{R)0!g zcP5_Hl3;8rsC8egFA|ImL9PCPBa>iUjDtM9pA6$b)g0@D z3}YjqwF1L@1>>J~$@TTeorD{L zHGgM%Dg^soM>cke9zh@1c;*xl9>`LvAxc_VK744%iKl*}kcp+@1)5U*B+?tAj!m2r z?gualYTYxf1o;6>ful`&ktb{~5s-e_(l;(LUnH$Ll_NwGut+x-BMZeIG?Z%8#BD0V zEM%ReS@AYNMVLXLRKsJ3)b-WVUUBMIQ5oGyh@bw?zlqL>wpIBocdGQXUJ(P;>nb`um0=pvESX@= zN%hg1m>H|)7Mc7H_1IPui5VgKv7xwa`3CxNk= zHsV%O8^p>9gi8{BB2|pRX69j$OdcFu8}kIW$j3&^g^;Xb)MF#%xBlr)ebnb|qLJQU zLp$RAtEGu(1M-8RiFs~Gv%Nc%1E0rl8O`)vk?d>p9TBMzV+2WoCvUZy2B{fCHbt0%Xp$cCER?+jyngIPM;u6>sHkV-KFnO7NkS4gFpMjkHv!SC)gRN**& znOZRog;vR1yI+dMG^DY*Co_~#-kv4ztL5?8kf$pFwAmm~iNda|M3X;IFp71I#ZTCrsq zR#6R^S|e%C!C{fzX+Kbui@+^;r&Nns1a7lZ=38oJB0q|Uib}B7Lbx{ zbHnhKi;2l0l?3G4m{cyrs2j(}MIxV|j-zT#y>^ojWMP%((H5b9UqqKBG0_ve192it z$gyZnW8yc=ZmYeEu)t^3jX-Lycz%CyNIeM6sR>Bnkb0nMk1gVZW9o(~4rh~~TFeZh zy_NlyaxnvSAokBnYZ!MLpfx{#u3s^@^U$MI8N zu?96UCZ?f-{T@@hmkz=ZzUS12dX*3?_MqBOwdei)V^6Au6sxK|0pz&Y!){iyg7>Ui zRdzJNnB)5Br)MKoEg9geCSc+kK}bt7g$&w?xP zF-!xns>YZ!j;ROf)|fPosRv4Pi6fj-H`4K!jyR_tByTwhvYb;l(vBM9_!g!i&78-b zaLz$>BT%aS65=?hZp4i0Q3Gfdbd1NV8yqQYfYoJj=TQ$YfePf^r2GVoJrd5w7Yn zcv+=Z%s_5XkMHXd`c)M-)6gRVr&`QFwXYH}Q!b{VA~yTFl{httXEu z=fs-bxDY>&gJWvNT*Nl?gJ^8T)D9IKST|Ds1xMr{8)#-x7bz4oP&enelu9uJReP)< zl8}uIv3By5iW#UJ){cZmnOT5Wc_mM@qEWM;e>Mi|5|Adfn=4w&Emk)&clKC+|D=xW z6>W24@Rp0oUU)oqWh0Fpk6qaaay%B*NUYbuqG;J!KS@7cK&&E<={8%`n4sxXDW*-@ zU%eHkQcNRpukr@6kBw9iCYXI983%E5%GE;;*~dZ3TiGK&(TojM5GK@qq8SGXr$qZt za*vHXI3@Mi$dgk)`bu(?RGg{WpZ1DK;=wPbFJORZH zCfus=foM@AYFaf8LePx-p;F8M=0O_*6Uq(8>Aqqd!tB$Uacr`==GB-|F^g1lM0D;r zc5}@tuSC>}86#w{v@TPyqES;&JL~^AJNjJNCTb8q99TwrXkIon`e7Sm6%4_O^I@;6VuQMz$p{6fVXA*DrI68-~`0;mLf3=I1Isb zYQ!vHbw=zX&7@qGBv8?5e=|E&h3$QbM2$NzEK`#p=Q)h%0;(*MqhzTOa}d-o35YK~i0QH21Vl>2 zkofnzVdfh(^hJX4iR9>pL-ZV^m5rVg2TqBYwh67tQhgy68!2AVV_zu6Mjm_W7g}+k zY7a@48ZiTPgK&geY^a&ddfacQHFBb_ht7IHFSb=P%XXVOF%3PLbw{Y~;}c0DI7MPEQgZ1F z$=E;#OJts0EgNJl~T+LB9Os~iE$tXOwz99Z}8>Jm)W z{|ZNJRtSHsZUot_^$Xc(fBy31+iTSgqeeA8kOr(7p8(n~^FGXUOI-au`bK}>_DEp1saO#jzeDGswx770<|wYMET=w2lz z=(YD91r@7Y4x~EFH1}Zj#)MuZOrQHDac{Vl_4v zPHl73hSZ2T$g)a}n1hH_HIUZ)D!Hw}DmN5QiI}<fa zg;O7c5qtIWAfNHsUQPh~wf#WJAP!k!EZpG}M~X zgse>*HG8y5RvzTBt*XxCg}Ob+8_~$c!S<+=lvuhtyR zO-J`t%;thqO2u@8<*boXues@%`GeZbpZ?yC;=%3QbBxX5cCI-F!CS-a+;R+ZxJ5W} zk3zF>rSOYv<3*IP&*UK+FVf#_yikpem%((VLjy6;?m$`i`{U zl5ezsb31^j#w~yS9_KNMoAH6(i*#dK#L2R~l5K3@N$h@7?UAK5?*Hqj2TwQfs=O7E zoqS_A_jFn7#(B_k*~kSFj&1bVU9B6(22$l4iP9t-+XzzSimX-gjg7!*F8S*RoK9=y zt}dRSAGx265)z;^8zt$+ZOrR0{zbNN0k6I+U(3eiG1v+0UOA!B@1DFPO(=)d*3|#X zrZP?XZH!}56fn^oQMW}1C7q<7T{sp`LOG#sn5WA(zy-b$UA zV>5*6tF?#85K4`hWRD&1iI*Xi5;5-x@lv1Fs4;TrWutjw$mqoeOsD{_TB^g0g&A;E zHq{h|8Dtpsn;qq07IJgeevU=dhgm2MN^=3(4|)vEDdz=Lh*_wThpcN##0=E2mlP8< zVg?#kSqf@?`-0WF9iw}f2QjOa;ipE-w00veHDV58H>KvyHzi^Y!kZ1JHo98%=!VEk zc3Ib#87%i#^t0P>{sb&ST8JBONs zjLkmLt(jUA0e|ytjBO?w6R79g7$8$?t3Y;%Zm$$m?Ffj*hB_MaGM+jy1LgHKZ#m!O z92bfOZxCA~hKzgs z*fCYVP^^Xbv>=vkff!p<*mSts@-PO7!dkgOCNjErM`6DmryIwF>86^)RkuD2L!&{Z zp6&ZvAjZ&8>P>Vj!~kV~WhMSN;W%9-2y1{|q$v^8qZm(R>;#vFic~&n`r)&fMotV) zm6!!q4gW|$>=3RR{@JUIo}&DU1g}IX60@xlgNd3c5(C@zSk0X(NZb}$Uk(fo|rq=x_60-=DW^4#YtxDbG3#B5S6~Fn$0oW9N5RGpZ%o>N( z4Llrc?=-3{bD&O`nZ48KPNJ5yZ+OU>L4~;f>`j%JZms;3FOyRw zW|2ecUTdVaLn@k)oRgl$e(DS$6OLqjN8o!ijmL&Hx|v2H4_-IZD8xLtA8(GS4m16P z*rXbNHr42kx;BfQj-4!dZ`LWU@g<2LY`Npr82P|FjO zacs!c_97zRxWMsR@{NleW=S|MVrKKH+z$!IMZ~P0f@Md-5d_W;vt%5f$Uj~;e@HoA zq?sk-*g!ME7DmRg5fhK~Gh4Z*97h(aVC z2QjUcu%|>!Sk)X1tLe$9=Qe^>UGZ^q%4Zz}QiXVZ>r=mj98RebGmTwurAEv_%xS&= zphV0;;FNq4C1MT&r`#8$LQD{iINqu^Acp3oBac%^ef~&&m^XkchQIuHV_P((Ub<9= z8546*-#AhmW`IztKYBWUIiv2@2*WaBI;|Pks9Y8I`Q?^l8^u-iH!}uB#<8mXRY&f0 z<*Z{{4XF^s&+;@BSJmGPG+{yiyCo$s1kFKRZYJ>tUd@q z7$HoNn1eV7ztFqC+;Sw3T4^Q=I)^1{#3UVAh?WoGnHn(hv4Q3wh_g$Ll&5CI&aX9qr>c7<2GKZ3T1$TG zm-Fd?9-gYX-S(hV?ZFPRv5jz4tuPkI%0|r}jLL>(u(DA|7_HN|-_?!!@8zcdzIoUc zj)F|7I?534EIizFPpC0DZo0A&v5IrAWpnkfpm>#<587-6W%c zqV$(=xk*MLMQH$Q#p$FqFf)T#9H>`FhUSGZ&|M;%WK>7`hk{8Ehgxi#ioH4U`6d6+ zP{rP8hm?nDNK?1l#-vsf9)CB*DCly!2}Xe9rkh^`iJP*tH@^rXPL-@+?l!*& zk{uOCA-~9lR1gNu#F1XSfTDGL-cm7FY{w*|l3i?*2dQKi8;N5@)uc8|BdwCMEsvKGiOve)r83$LgL zQj8by^e}Ve7%!rS3E&xMpuNk8Zdx8B&c*!+ZQlo|_)AnwftYS=-d8=eREQahQ~NqohVmLx<9oh*`jtYU6Zk z`@=hsu;KTQAKqD;4Zo=nv&e?uREXhnYiS|Pfn7EAVJ_gqB<4*o{dMzpOrZ3SpWSJb z2c`V#P9u1h9wv=>88p&+DpTz^ut=KAqWUAtI7Y=OQ_Zc$MvBuck^OjDqpmHL6fpH+ zrlaQ64)>?OwnM1sn{_~rvHJ<7%0byl{`kS2hAyT1?KJbYUiwFdaZR9<7x_O8XGhR? zmRJV+=`^h!N;#dTHL}LUsxY@7P7hLS@0Zhs$et-6#n_EKI3>r}h&hmdLfn2g&BjKs zOv3PwBxBn={ggE0K-C@-s)?^TP)Blb2~;7dy_AuGE7JnRIxXAlm5_(-4m>; zJsuXZ*ho2QE`k3c7aKCGvSGz>GQGfYR8owK97jbiE^-_dwYbP(Rl}()r#A>qsxsG1 z!loDp;2n{=Fv*K9z=Wa{{nF%5FU@Hk5l|CmEO1l(rF3FXXcOF28wAf!esPd$jmV2m z9Hg5IK{QjnjP5x!!0}N&ed)$3r_bx@-yTF`a~R!|=yyhuiFj}6quDc2iEl`v zB_i>OWEpY{-GE8(Fj)oeHnC0J#IGv8q7d7rNo6}nA`a5cK{pz4pl;8S_z#iTP_v3N zA`%CA_$ex}p$fgJD)EO-Z0Jere*L0{ddA-U{Do=ty%tY|>*bz_C{Ok4gb+FOOwl=0 z6{0-KLEzP?Bq2VB?ZMSA^J`rRP(UF4#E)Hx3B9!|ga~jF#a`cllN&K{4&@?xX%Y`I zaSEk@rXdgG97-c*L9dwU#VM2qnp9`)bn33ZwGhqeFVft8`r@FG_I!_AM$RO4drhic zRghCj1DREw^YTDs6&neu39&M|vjC|w${6k}gi|$+DXS*h`FpidG+Bt2w_obw|*usKinbC5t>+-8+nGu3XhuXLYT{ zVX>QoR83uC>0V*<@Zze>&t6~zm~B<9X(3E&4_5d3A~v(F%En2x9znUP6Ei|4Bw%w` zwOWjO9|RkV#s46T+G25#M+CN393(U(CRr*D&=Hu0?Zo0DX)S@?T5*vFsTPX^RRGSD zS}ZQ&_&Y3EEe_PITI1^8)18I*YP6T`J>6+Y1XfsJ4RaJtL}%{2tNM6EHg_5x&dO2r znw$vCQS>5bSLG;r5u7y+3Yxj9;C#Qg}bhwc`Y>5v}QBr z6uP0JHOquk=thcFUWwJ7*Fr;fR!dNKWYKtlV1>ZGusI}wLgB`{A< zaaIbB$>cE+$R$3<&=tkUM0jV_+;}xAz&u)mR{u(Y5Kn`ZkjRAA-dQOR^B;r>=lbHi zjlD>hf=+A21p6n|VWu^R(Aby)vWwGN<=_crTGyw!-dfXTx4VLzq!Gf*4!yud#b~5yi_hZtdd@QM_`ro;yc2iNiQ}MR^ybqRi-W*2@72C z)ZJGPrjd5ncnS%|f!rS3h}RD(#(`>?Am9IyVr;1W6%F{06yrd7yGhv8WwbMlVwS@s z-N7|0Z8glYB$18{_3r9#F=XZ7&`_Ao_WEzXn`X{UZF%hc+Rph^Z#EEBsC%>qwebqH zKXoP1Ggy0wkd9%z|c)(M}|hity4k*JOvFvZHt+I zD93>w0RZVZP_;*JLOM3m%*OlBjsqnWN9L#w%ozpDwx5$~Y@;F8+Y7%!HbZY>okJJo z<Wlw;_)4U3AE!o zk^xvQGy)F_4Lm2xu@O8>UDDd#VPv^PxFu{M9ouN$UD-hP8l$bM!EA1Ok5Nz)>&s!f zv#tl9@#W=J!(h+ei;S|0%WCW_{k_O2sF~$eozgJVpiopNy7%8+WYm8*v%2tRK`hmD z2JzTq_ZA~2mQMU$nryThrk|uFq|InetKlH_SSC}oj+mnqg=xe@_#(BRCpBRjiGy*S zTZq+TBeTic%~KR+Ah*{Xr7Fxo)gUhuDGSq3dn}mZva`7;0uA=|f9u zM+mceELPDe4I`_fHnIKGhS7f~7U%Y=y7GqEqln8YamFAXbCE0}aqVME!_XSs))1^B zw>3GV{@|#_{q6{T4cc!z!!2jjyaF5qZc&l%2;3qf8!4AXx}+#fBSnSpb87_N8X75X zH9DYqpYRaUo^IU&&HIF*YLMuVvM}9XajPE=#me(AP`oy8JShy*P;r|#o>YcuNZpxx z{gQ$kL`ybQ-0D|CfxIFbI??z8Ex7>t$rr8F+G8s6#^cZPggj;DGSpU%_}_Yg+_G}8j?s%RhYJcSG_6lFnguZ z150xWkf{qZMs80cG#!mY$Ou-|9J7XkY#Tzc5d3v-HOl7cuY0Re5S;ow##3$InMnwx zno-)@Ta6yL|CgNq$6jg#*hu`bml{D%B;GrXASV* z{PmZf$Ge30>uVFlyJaKAYNpiv4)S1ilaC&OeZfPpeoR@IZVp-vLDA+PZPg7jh)qBW zDsSbR8#QRr&<%!IH3$=%fs_@@s;|VlO+gAOZ_Sy&$EF|!J*nLkq@aq#@#D=vg1~Je z@g^Wa;5LzXGms#W#Z1y>AVG-4h_sZ4;q6z`n!FR=C+nL(hlK~CNn!Hl&^mRlWS7^$ z53V-0NqZOpe~zqe(o8U?b7W0pggNy?EVD4$5!6yiWSTQ;tm3gG_&?^*+DLh9R>~Y& zgOqqm(3(?gLm^fN4_;n#YHcLEYIr;o$JYI{6@|HsC@b$14aH?i-hOawy#P^|7o?B* zeA*q6pin=MXUa}vrZsB$gLCU`4VV39Y@AzjDgfbrD1`h6r`AuPA}1NhHw1<_vu*$u z#5W6pBkM-OD(@d399TD?=W+kag?U0rK@L=l1a~C`IY=)OuLM1!rl6s6S6-de>_v)H z|7xX-EFjyc<1isrKk9Ly@>W%N#meuNZ8hF%B2JAMCe=w|Uiwan7=UH<6A9U^RoaPw zaVo@MgR^?NPkk5wlS+DW-wnoyhKFaw2GE&=OP;5!e^E3d?# zs~$DN;#EJg=wYmU6r_K=Bwwu7&()89F8#0K{U@JM_aN>Y?B~iyO!f^n^^nM7V=3q6S+{ngqffqz0?W}fwT^Br1lggVd z)nUe}o%M_H=}+5WNG;Vwftax}srl&Uhx#xF*q!y$$;X52&PsilgJfrg2PYp7^77O% z3v+I*EMs}=zwelMb8t*(M1ekZ&$0DE5-sM~+Q@@dufJ){G^jNW{XXZ^n%1)7x%c*y z>M%2ew8u4NK^+>g>IR8_b8u~F+?CZZC)Yr|x3cW!=-Lp>YJ^Ccl!)nJ6tfXcpX47K zf>~QZItj>zvbjbne_BA!T-56;?{ujWvov5}&+76Z2(2YNUxw;daTRt+zM@HWv%`|EcGF|Sh^-_u{wj%{^=Fw${> z&+QNZzb)%s)m{)Ns#6&m>(m(F2qSGozLm`$QRr~owIwC3s zRV4o86*^U78XA9P@TkXznps{KQYoe(Gb^WvjaS10M>e4!7s>WY3_?CG!uINNavHa@ zEQ>@pxgW7D1V`4a);o@uqrB!nKmw$e@_!JVB}HPotq>7mn<6od6b~L)O2jl!yz=V> zf;Vg?BhIpL&G%plEc`ssHFeqg+4&7&e5XV}GS zhA?YE!_+_VRu%)_#My{s7Q_9k#%gSSk1PQDlr39 z433K<9vdoJvrBxDcWkI=%~p^?F%7}1#4wB_9~&{PnpI{(f9pJNyp_|}FVy3j5Q526 zq)yBt@m9ZWexV%~f!45xbOiC-UvEV@z9URH!tou+s3*Om)*jx9Y;2n%A{?O_8-ZE9 ziZMB;#z7tng;VQ++@8L{U~tIBM&MNlkrCNANYl#d;(O|bpf#U#=ognJ*`_CgRUsMO zY?AuV<*bxwk{oG@mulYtMMRQj&p=7i2)lZ$ghHsSPwg#(Q21<<> z#FPb>omE>ZBUs_MNPKT~<3WgWBpkc7VwJ@37YWBk%tEJlzg9IO`2<;U6Ma@U8hZHa z3P(fTAQaI|cQsL%ptaIbe~BpUVbB-av8~Eq|Ca!Ocx(t}ZN(ZwJvP*FI6E);u^}8* zGaDnXheZg)g?KqE5^iAw`MAj0Ur~>Xoc)zlfL_^j+@U$r#LoVTc6>(|8`AL|!DC4~ zHuCUTgkvL6p+0dW@{Wz*v3|8pbDo5O+@7GUFQnr@Zcs~?GrupiV?%IjE4&QxIFOyz zeVKOs$I}*=S6;m}C+;>RE0n7xN#)+@j|GgP07e#SC(}rC7`$p+aj78_xl`FrqIk zWpjQZAO}i&Iew*F%vzc%u=ZZ!s|-Si_K|@P*%;2XE|PxwtnMOE%a=3V+Jjn6R!+%m6Swt`p#HqbKekDEEpLw$joAUDwQ?jf zkYkkQT;oB_`EpMq<+CoZAjFxsLE^G#RjS4e($Sc>`XU3_M&+^WF)tF3jX!-Das8bCBI;DH?N-!ztOv?Izo-_oS4JK`ndM@f8x+ulZ_*B0d5X zqtSJ#7xOe>r+UptGd6i}u*pXurofG*f4jmomN%2U^u9Dv2TFS}+U%nT9bZjgf6YfT z9s``ZE2ea_kA@SLNX0MHE{bqA>a`1D#~kbLZ(Dg+nfD6EXoUL+seD74l`IFyQsB9#%e4tI#iwi4Hm}w4gZCdx( z8WX%VwC=Gr2(%(Is1|ct6RmPxrePJNC6uR5djNrC1!N)fJgXnqCVS1wMQghj1 zo7L5hf?!pMBNw$}W(*UGGl&t7GJ;eoa<)s#$Bb1%F&~CfJ>~%GuHUO3{jdsnitB{p zZ$7&2CrW-o^X36&GO|#La=d`$0R*8OFQPFsH|WL&AVDjNsEBNAB%Jbt zd-{>=d6{INKlG4#Y@6b=76Q6)pmNmEjc{zJNX>N{RlCyk3=}O~K^E=UP{rTej!DUw zhARG6Kqvj!5VUHJ;$7&+hAywj#|8Y}TD&437m2IF9_n!sc+K)bJuY(Mufx8*TjKc1 zE7u(_paF0%glaMGCh)r7%&4t6R}rzF%m^tSvPkxe85l9Ib=5|{jDCma_Sz#Y9Crlq z)jX($;~=56*VcY7qn;kV>J>Fc#cJ}Y6pIW zF|#}zQu$(L5s|8G!&#nGi*a+3JUFYkV}+1*d;>_S=~w@>=-&_=AIaE2MNA~Jemd@$ zgjBAArcg|q5PzK4pM7`uPwe&j16@FCX%5T2Z^g@U7;8oX--+C zD8@$0QMuotU%NRERFtx;^kXguF{64Q&yIfM53DiKq^h4DaOl$4Zy zI^u!grp(S3iy`^3;de{LG|*GMrD7VX@VkX#3^b$GzxoJU{p+vkH#aL4QICmCY#=*o zdFd94p_}qjPxKaw0co#yoZm_@hG0~UdxdVL7!WgBJF31*JcDaSSs225x^&){gKD8bz4`?eU&i645b)XXXdeQI< zNcQyv{Sc`)0}u2hmQQ4QK!~+frs3t#P=Zx7v4+r$4VhX`Fo@OCA|zlplh-63zK8%$ zQ0lVRCfs6!WZco<_M6~GGWv7alYp~QII{kQpcvCK<|0ZT_y@h%K&Vir_oUH_jWo5a zd-P%>m4YM7{!wonh^12A;k0^?jF%VE(lVx@VwRt-RPPS?myd#duQ2P~hWX96)`p7N zYy>JJA1j#k;|t898~a+#Y?dX;u_2hPz(6=Iusdto#w_BX&F@O2Ys?}dRtt!AjBZ@S z#OBR^J-7EhU4;m51OyYG%82p(akbJ*dW!pHliw6pYm?Cl8Z5-}i?KpRCZN1W@P276>*kb`28G@+GN-c1b*>XC5ho;9GbEeeTKv9}lpw!q%#a2k5)YwSHs(uH+ z{7`EgDC6lv1t4z{1N9mSG&`l{-N8x~f>tqOHNlGOIIQjgD_A2wP>qdDtoj*`W-&8f zc&(im-PlH^)scdUCDQ_tOw3@ukqHyoUs=J(#?vLj^4MP$Fc+%vh*rAA z?CfelVv=?-0~N8+4D^dx$l!;PrJX;G$s`cC*;H|FZsXuR)z}3 zA|&WH`tc&lVRap^hei@)Sr2dIVZcqQA0n~`47ZwvS1fH~#tLpVU|f!jY^!kFwDZbiLvX8EuprQp ziyUtGy`Du5x0=y$Mg4RWPC`Yl4cz|YZYelA*8ljK6mHA06da$3KJM|oa$0>6Wf;85 zVRZw9S$_NR&Brngbkt@n@0N{JI@Xs$T*lRffx@gl`~mWIIZzEq>Uhid3w1h1C#H2w zTU9#N7c?Hw5^@Htbgb`TfV^Y2RYz@R=(6KL6}2ffz4>CMt->tA^KBJ5Hn)WMwu(H+ zYNxkFeyD0swY*}Fh$2k;Iy7$-yB#sVoG(d+z}PW1y&BfDL5{YSS4Rjaa@EvoOD6OagoF- zG*EH$n&Kcnv5K=PI6i^sVay7 z5Z@eB57OhY9rC_oLq%#_z)|%em4b1>%14n~lu~KI_4B3K4LPcYZF%5^Dc{LFfy58W@d+eKx7?_q z5?6`Etu_iEtU5xr+~}*F-NH&q;X6ewHA)h z+KQu0AhoJc@2xlr>D(JPY{^m3BTl#EDCESc9x*!~0DNhN9E-{u58$r>2ZK(QAHcT( zFR3(+>ANwZ`cWRo^@nn!Z~B`xATQ{$Ub^WU^9y0=rfSIP7}Xq{ zUeh_IkqOgG&yNrdB~0~Z2JYUUcf_lvi=SoxAQ{`{mJdJEpE^VkrYOdb$)D@g87m?# ztz&jHQZE_lvoAK5Od4AE#l{g(`q;>~x-T{!8z|E9uQM+p4_eWR932S>5Bjo-(JY%A zsZh;{*9WaQ&<)izj~R$i)uLuV(Xs;;v3ZyDgIsK@j#UbQpZ!rDPd&>a$8{fyj&1d% zmZD=rMXi3w*Y~x*%Y&EvP6Vm>vp>rNfC8r2|Dod8qupYETF5Ly2F^mE;a?;@1?C@2pp7B=Z2| zpX4X!m)}ToF(pUOz=N5I@hK(8Mofepz+#}}*g(Z>EqiK?19`ainlA@GAua^xn%s^}|F6F6ErMkq4`s zQ#WE7%r`a`jeDKi5)PDco zo>M-YR5voT5|P%9bERh-iYCl6aa9^`DX7LNxBtt=92$Ag?L*4oj0 zD@TOZF7|(1b^L|o<%o}!;{&N;KfPoI=(L&Ju?zY#kLa>)9E509O;K*MD=*^Vgh2wcZspdC`!ARYnS9A=d|xnqt3@>jOyDf2UB@|Ghq#1S|z2 z$Q6Z|9SPWCLcn!G$tFu6kNGf3s4|#5atBKS=2l&8JeTQWzdfPkz+(@m0Bo(f48_Ka zIJmUc$VM*sWn;;04;>(sQg#v|4~z+vCIJhvXqwBkc+GX>f`xj#+^Kx9P^}Ta04p-& zgn^n>Z=ZtXg@s7L$zk53V%F^dk~I|kTbPTq>NOzw+k8}T6H1o4ncOpK%rJY>jY#k4CDd*`gg4C zhK8Wlvxt@bFp#OWUQjyG8Nqc#Q=2g7z`Cu9TKyn4R$dSdL9N$6taD`Dkg2to@E@VK-77N-Ea}*gG9`} z7b925i9cnLsCjsw+z$&u6?8w$5di%u zR7BOWA-L6DCGS&pY^cN5FB$6m=enZvvDLgFr--(KTTOx(r0TfHXeZfdvp6;kEmVo zNCwGe2)|X2Mm$_+&sC2`;8iz3u&jI(1g{fEs~-)SS4A9*qaSD9-W24lAX*DE?_#wQ z2MV%{Dj6e)b*gv$5LSI^r87N^Ji|SbF$%Irt0&lmG6HguC?^6I{kX^oVqM2EAwfH( zekU##0(HlWOpc`PcoEyMNGUuv5?cAzT-R}iY$QCCcPKqJLcn@Bc(r^Sqwp$-1w{36 ztTJFFNUDzwbuv!qQGFZ;VmpOXer!mz=UG0}a7Z)+wUfdrKQ>g<)|N&6u_36{+*x^) z9~U7RC$Um~TqMcZo3pq(bLhg8xm9uOfoQHu`d*US<+X;aVD!HgmOiEwU=eu%QTxx! zPRslkqCvbGw8{^V2=lSN087Xo%RI=!4Czg*156^$Rh$;ursCB<4Iv}P!yp;XXDe^T z!a-ow#Wsx4kZsiA%8k;Iun|brjo>wl$hpuYVeZH(a-iWflek_;xFW^qE;BYIid}Hh zydQ2rJIO;J4=?1mqY30cG$ib4pN?fZfwvc=w6(1_r3na{%RCUd$Iq3r@iO>j!*2b@ z0&g=sA_NNC8OM`xKqhE{m6fLthxBzqpsWfrOdvluNQ2WnzbL9~}yD0w)7h6XbO zC0rE=EIg~ofuL5=6UTC5-L7bAT_)BW4A&Q-w#V~&Xrl+WoLMhIxQ1H}trtluW&dQtap=4sljI_i%XFtscp-Q8~!q-A=`w8?{6UU+OIM38&ZSf+s@R&ik8 zpdJSbu~|W=$3Z-t|6nyB9~(*4qUw3rqa;u!eXlnKX zxqgsh743Kt-DvK{K4{>) z10`6qNI0)<;+_-hH94GeWWC7Y zlq2g!4yUUe9e-?jsKYdsL1q=8C6Pc~-8d#ZC;Z`M$2JKESvV^iWzm6^+Z@g4v7$j; zZqqwZ`a7c0NJjH_CPL(=MS3_qy{b`06{kE4|5?>&B#gRbtl^vzXVzCN{h{jEkn9xP zO&n#%hTycs^B>BNjf7I3)c;U)T;PN$HOEB`r4$_(fztStqT?bfgXt)f*FCg8sY%p! zx98ObNGiRF`8}^*6ZFG=A0yxqrF&Q{#3X2sXN%smYL8X^L@fTnLDWqXm%y-rms4j)KE`bwx9*&YN=Q%RPM7Q)N{N>fP|V$nRa zlTY<;y>`+~W`TWNO*ffELaCQ;n#nAZ?bM!2FPTN4l&vJKWGte792Q=Oy!!Y~Bbi?S zl%|i&6X9tiU1S=#l%|PHBjJF=n-($+JSa^MnSnAKWty+8IeN|yO85I1L7jQM-o7}k z?%@bir5&83f2Mt?TmYl;0UP7jRva~4!Zf=5YYUD-YB%L&7`^!DbQ~${EcXNq?xu5@cvaC|;y%5MKzzMw$q3kJ~}Uqrrpz86kvB zY?~pLrHxP=$m97+WHL&P10`DXi2p^Yv7uo$R*r~)!fcAqUx>wqp3I^a8-iI)Bm5y3 z8>)a!DddY%V?$7@+5r0if^m_(|OfLm7@QrQTnw7Y)^T ztd!M@LWWot>k39gMQpMy?>P3o3U%D_%D66d-B2N0(acMZZB@kb<&~`F;lUI1|L9{m zdzF_Q+vbspdC74Rcny1w$HRnUwxXF=9M?v?b}C%esEHA?sgQoHXe?ktc17cupn>Ti z6E!K|LF+0;A)x`KOZ%8HdD6O)(U&1$d8gz}1DQ3d;fTqVjIt?KQ=X)Q%osJRSzDY` zTYLQVyo*)8Hu|QC%vdE{Qz!o7sJe}0XUi0Wzc{OIs7NITaa6s)304coxlW3~MV)oy zK}4zsV4ZSSy`vGVemmkV+O-e}V^)>^l3sM`6o>x@ap>!}y8aL12MgWSK`yOQ4F`b- zDTK^mlA~u3@1%m97BVwAc-8D;HQR)(JfL@=Ov0OGTfwZ$bPnaTkr}9@FwDwT#|ma` zWoFY!rmZGk8IU9EhKgD~`jOT31=MQp8SnbyKD286ok?_|-|Hd0Wcosth}jF$N@kI8 z>%@>wG9a3C%V976G?KZ9S;w#PS2?e2j4&GVv27mQA|D$mD&kbsV^hB7l;ar=(VtOslmP`Rf)wFWuda%jz&9ny;BAD<&5e9r=T@MuZV_pBX*M7?J#-gh=#(gCZ7TQjNMRDavqbM@-K3@-BW8k z%SIb+_tY8$ZjsIDDYMssTfa#9{)>|I%colC6}SJfZU3d{_(W>4q9ZRN)dv@-$OazN zA|e|pCj4cqCSVsdQYpE-gNPic#`_^QQIP}HfG=_fb;pLFRsl%q{x3Rmpi0Rfm_SH2 z6l$BK`Dq@zsHo-jW_>&6*E!m%!j@N#1$jXHG_Wp~KyoffWvT=5}h+o^m#G6F}#RRWc{6$4JVj}cv6EVAA z%5cs~L{xf5MYc^z<3F7D{oQY6Y~}GhZ3gtBo;g6Q&N*-?IpRiOYnhqP z=Xx+$)%#AFnPOp)iq;6I)sebRks1t zm!_Z0MJzl`L)yt)L^k*>?PMBhP8|#BCew&nu#H3O8~xZwv{P-pX(uyKjYkPI{bUBJ z0TI7xDAQ2yuQl`8DRs9UtgN84lxZu7)ePg;{mfccFlz`hH2k^`W_@4Y-O^R22Q;-t z@GLrV5wb9QWxC2N5^i%LXU9dz!kL|J<08AiesgFoU%F@oxBCB_n}53usp(vVPl_~a zt%nCv;YvrD0Zc{ZS}ODdBwERgw38X2cGv9UG?ZB=#7f54Z5&q5)QDH@5Ug)Lux_a1 z)hUaXGBaLy)zck|mE-C*s(|Gkl5dWy8+it-737Rp0UPeDAP2bts{t->NS*IxLW4-v z04)9aUM2`RIB90SmkDx6MLn|V%B4K)$UQ78#Nz{TZPD&QJ6=S2CxGLjfsR*bpa|Ir zEJ&ph$rK?QDO&l_LVeurXc&m`G&yKMIS!Novm>XaOheG>=A7ITWypadn)s(i}2 z7Shk--^j*mqm=}wh{gsItvOQp-d7zpm|4*C1HRce9etH16&LKQj)pRvGLzTHzUyeH zgEe!oUg$YM>#Wj!+fi1Pgi~~8L5~%@>IpRob>DWBmHv~5S7x|xJLRJ?-AwA}*qH zW3%*wbZo#($fuOh=p-{HAtHXGk<1_uX6Yoe5aVUTp_9xaMJ$qlRx$&H*pvfkC9_D9 zaLNnxk{M{?)eO;0W*~V_H3tgDkD-Bx9MiC5b#7{&0T%KJlGe6{g7}!I#@o8-j#CVExFS_)R8K?%NzO6Rb$Ep(Xe{M!3tCo(Q1rcj$gTpC6 z_J9?!fBred=p{4LfLWzJ62}kU%(PXg)eKqu^ZPvUtRpsZm<}8>-VIsW$s9!7%I8E3 z<;T8I?XRf19}cn?$^OdS&ezu86|!VWqnFpfTb30TYksmU7P)qf( zk%Snn#x>ZKn|zt1x^kS;%U-9cwQ{1J%t9Tr+!6K1zLdt)OnOmrj6G0-wwBQL7PCqLm?Fv7{HnSS~+C&qxBv(RW zBW7ho+MxL8rJKffJe!b&(2p1JCL0q+#YO5l=LhlFfQb;`O)=eM8VC(KtpKrdY@|b$ z)6uk(8K{QK-FPt!lJWA$l72D`g;s?*mqI-b1g#ncXCogQg4QaI{2(72fmNkg{DXXK z1X6Xk8O^Do5pyb&09H;5h*SNU!5(fXPH`Rjac$rzKx!7k6di*kP+16kDr2Fn1YNAw_JDZ2h-^u;eilNhw}~V?&PF)4 zMQF%b*AKd}5woDj3wAD4V*`*{4<0|f@i<74%478px^bWyj!g*N*a)0zZUhOsagb!+ z3R7NsY=|(e=a?T}dTgYUZ{BdikK=@Js)g!BuN!#y$B#HX+iTPZu*o-lWcot)gf4Al z7C|y0v(iOo5w=xM&S)az2$rA^r&SoDh0FtxIa+`YG7qEzmHsgU6sKf2+Q$rH5_A=> z51PjeP{}u-@b}@>C)YE*2d`F+2RXd*oy=b5@M_%{k*wR{ z2`AF!{4Oy zbdh-iluBO6#V0^!eo=31Af#rCP79evV4<@WN7aoGt=jl52x;~u z->%JrQ?z2+z-hhk{aURkYbez^@aFVdu_y#aWdqmL8hf-N^e?Y`zg8}KG7ySRdT~(Q zHutF}U1S!4P&V}!mBvNZK*N1%%=g$fM^Ao%jnO zc#w$=RFLLgkco{Xs(7E`MU}CENxpcKI^#e+9IKN`<3KfD5HEs8I`{JY@j@vMRLVEY zV6~#AP*M8FKfd#RtymOPQTm7PwCNx-*9xgxOa$ZVMZBt1S_@(IBEX5#)r%neKtl(a zxz2r5eXU%?#!;GY$X`=xq*y}Qp$VjJs0*$K;bn#wV$qqa5#0@|7pd5Qi4XwcD8&Xs zL+XhygkmF_oNag;{e@B-B(!R4v9FPe19?1Mh}cFdHd3_en?Q{G&@hl`Z4y>1Y68tF zZ-Ty7EDC~Ez01YDu38jQkxFmK_iOc{AV;cf2$hwK0FcTH0qG&rlgozsACHf()r;7$ zp=Qfixdf&e5WGL2|KY)BAr&P{a*mWm$wKtul5+BVBGSfa4^2}P^`Za1yX2Ch96jXV z7@l3u&J0)j`0-!$cKz{Eetm6UB6<1p_Ui@y`E(!$gM@1 z-*qFoQXL;WG7XTVpG8jN)8N`|1JFAS^)SkwcMcm!ne6P*v))<(aurIdBh<=No%;T) zXHD7tOd=)q5#5cC!kwM607Jqf=D?4~vj+tXQxY9PiqE1X*oOjUI6@U4dFP{$Vit18F!02J zn`TC$ZVtJ17V9UWCg6FV+8#pARl9dI;2N2N6tB#dc+|E)Jc^+mnq>h*JSZS8R50Kz zyMZI2T^iZ`6cK`l*Os9i1;~*C4T?t%ln4H>P8{y!%p;?SxQbQg3@ZxDB%{2zf)(a0 z95kcoIDAMQCnV+>rKi>%FVC_aro)XKm^H`2-PI5rY_b%sagApyN7+@A6k=T#*m{91 zv!A|dWm34ga8O3d%$E9^a9W02%p?q)%DkaUp8JDnd%2vKnLFcJdtU=|I56^Xt#faw zJhg*fbu>XPj(F}ZH3e&PhGcT@sDUp=M3Z(li}~!RXv9!07W$SlXi}SdJJr)DD=;!w^HImiCc@@Bk}mg7QqhVYI*HkRod10O{pH(DwfB^&!)Z-? zakqe>{S!CT@j@CLi`cP=bRTA__Bh4RR;lC_35)^1&K#P*)pGi{m5aB2J3TKWY!D$RroNN)!UD!Vd4kFdp{C7d{<}%KtmZ zM`WqK7XR623W$=#ad?h1U`H0Kv(oUsCHdaJl5Npn)DA+pBYy*!Htz@SnY93usR%CN zX>o)%9*0Zp0<}%aMa1>!L@$Pu12VIC=yY-pfuByOp%lFG?-K^}GiRGm6MlzoG< i$CEniOOHbyUUUQ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/SoundSe.csv b/titles/sao/data/1/SoundSe.csv new file mode 100644 index 0000000000000000000000000000000000000000..30a169904bca1cbc72961e6503ec44a6dfb749a3 GIT binary patch literal 146198 zcmb`w+j6AIjV5?6GrhxDUgy-r`EVH|gJg(7Mko%M%DM?FlX9)gMk}?I)U%^^+DF)T z+E-Y>9dQ5P2mEAeTh?XlF5wHfI{=5{^#70l@!!sW|F6IO<@|m3m(Qo~fByS#f1yAA z_+Q`Oe)&JYf4=`O{(pb@`(OWy{*Q<6fBxlPufP6H{`lp8e?I>9>)(I-^`HOR{pI`L z{`u?w@$2{BKA->Rum5@ZmHykie_a3Z{rJn@=#Ty1|Nfu9|J`{0`O|rO+dO=^Jsu91 z+uPyvy4ipF{OKRxKYgBj9)F&UK2PSKNA%a_xBvPc{y|g=OLZoi{q4(Pe|_C1+R;z* z4)wA{ecHS|W#ZlsuPo_)bH3a*r_=6BgXwX>^xD#1Y2C-oTjCdg^6{6y{zDf_J5X%V zjY;>1!?8&l_9+1T{&$l}puM~7Z}-n9`d?V&csxz}n^;x4siAu~d{sWjt3J`p5It=# zSLJZL?o&kxP!^xAo72PXesj5h*46RhM=_|_jB;RUUk{hvLD`)!NryO!ffB!N?zgw+ z-Q_kK>knu7tA04jK}|bRT4!&g9MrT^rJZ$oo<>imwj?8PLcfU=CUP`Bn=XP@z`0om95vq7t#Rz;l4;tt#Adhlalpi za%$!3@OBGpJsx&%7gW44;rGOAYQ^jPvLh39cYS=6pQoejl3MACq@=s2WT2*fv7TD- zio{!8^t3P2Gb>w>@ae4V_62%o1uGIB&#Fe#{;AHaSSh6{k+ZuqD^Zd1k7{n{{Cayk zvw{=}Pj|Y?z6{T-C`H2aU0!Bi3TIZF5@}jzUlM196w!tAY^@X>TX(I69A#qtWjeYp zaUn;USnU*@UXOTQ$WkCShKdfbOI*m)al1JcYwnBGyb!5OoYvge*?A#VnK-SvFIn?K zvI4PPb6>jVg>+rED$BFJT+OpwJ#04*x4YAJ^CFTwTYnz?v`$yw=%;CPpyYy|XSvFx zx4Xkx^_@;|{F!BI#D7%eS+WB8e)sgOW_-^7b#=Ys-{_Levs`6T^UEw&@XK?<_##Wz z_U-j{w>^Bl?jLWP%Vl%_a*NxYuW&k0z!D!)wqTLP%t6wFr_=2tWtnr3W^yug)P1BZ zfDY39_P9H#uS!DDhsz>~aNy379Q3KPOd>VC*4@jos2p;r4Q0EVFOw zmR9T@_otp3j3<4wwX`DFK+#o<>DkrWwxyLcMuCGKkNcKyX{9Vk7wmZ7STC)7386B( zaCo(%_4Ksw?wj-4Sy~}$peQS2=k>F+;>IYrZ}f8M?fA+H+|yydC3DDXQX0WUfAd#X z`Whg*2-2x8Csqz42&`h!cW+i!_?}L?$4BzEJJy_ZtjmLyzYdTthLo-gREVQ+1j`|{ z>k=0tDa2oQZ%<m7tGZarzJjc+fC}w?^Y#E| z+EMSgjUY6S!sNI zeJKSgAAVmm)>bMTD5}`wNnbPAljT4f2T%BFXBaq%F@+g>doUhZ@ryfXf<`qWkc zfm-=qd2Cw|Jnwg}Tf_LMFZ$z=6~J?T(dfpnyk%Pv1nR`N_uES$N1ye_Io_-CpAk-ndwnwUay;@ZN}2rY;qaip zPAl@rvn-vTvp6_{FHwHh*FeFJvHX@Jv*c>(D$j87I&w-*UZyzEwUU3wksEUAEEWEm zBQp}t-#$Lx97VBQSK;@((g0KmSbRw0{NgrE19X;^@4(S}}>Ta{hJ> zPxIU6$d*HPf5qEE=9E%1{11k~7d{(d{z)e0tOIR~M)Plz(Re*t{O2$K{PTZ&qO1l%9*kJv7H3(o@guzB4+Z8PWOh5Dpf$jIB?AJkDNhtsFa z0`|Du?jLSX*WCjpGTB*IA)T@r@Yv3B_C##oNJ>=2mgI^1v{}gb>bX$p?|dbzaCi6< zEPiO;var=4dU)i+x|~n|MLqQ!BJ;X^yWS4Rt!C{)xWFUL()PML zpDEpUyJrg_8&96I&vBMEC4b!P_S<-q1sgRUiH!B`in zm5f5(sM~0sXlDbo*|z=hx}}W05tacZm4pKSa3s#hdmGWxCqwjE*ka=6?s~b9z#i!# zrwf=2NQtBtm*%`T|{X@j8lcdzOHkMi)gYC8`z&mI71W4C#y_pYGc0V=pk}L6I=0!)vc4vcQaD zo!1^Q-L=;ir@)M2UShgyuWfmO8BJ)38E?RjEY*%&fm!O&d~iSMph z;k6Ixk>pb{pApmLb4ZUUHVJ&L>3@dTKBPw!bZlU**U=+r-W?%{=E)~TB^WclA76H- z-Q~cKSoN_+LvK*YoJ4whOucPx?CPD594^l&wd$GJhh$J93fEKE&|be zZ%09k#OH5s6gx`so>2(l+T*vxQKBO8=3#TZZ0`2-9?x;BXr49pRBNY&i$*!ZJ-l+n zjf5c-nShKg<&iiPn4wo-7EMAUiE_Y(Sc`TzvG#Q%!KJvs#M97jN7HLy0%NW9)iwfm zi@a#NzT@?6cYc;&#z*#@G{22>+n(@!{osc>)7Qd(H9M1RKx9x3AHQEpGm>&wgO(^}-1Bt#4nT_#) z@ta8M#c*;*Y3Ec7O%T52nNXsn;v+x+7rynGP`;!Mk?dcrrEs=XQZi;C51XeaDmBKn z_&PR`AU-@E52OVql0B*rfQJDkfJ{=B+0A7`?iEPN zK*V=~DJ8X(FM3a@~cjpdkV`^f5mO5Nr2@* zRCGe&X0~HW9a1PcIQ!}Il05p+Pb3oEsN#ec%n)}ZjmHi7>Xc8v>>j_V%eo$rZRryU z>5B`OWl(KK%26*v(PjQ|emEFQAsr%tI_91X{fYuYemr(U2_|MgAl!4B6SAD|A&~1bW%`haErj^xT&N36zO6kpu*)F`!+)l?VftNb)`b;clCX{a2xw%UgT2IDxKA zM?{JDmmUpFApf#Ea|0G?%!)$8K0ONDx4V?CTrCDPo!SwSq@K5XO{K4>`q%wIN&5tb zFW1ZAL^)bA5s&&XTv6TMfRa!@Li*|Z!|V2r8U;kyR-y9G*=|Yx#O(={}?{xF*$ue9hA`QKm}1et(053h9f{Qtl&hOKV)Ul3bQWY>1P=Bt*|FOM1&<{(Ly_ z&Kh^afDU-mlB*)QB$5B{4NF#uRX~8dBKse`VWo`)h(B<{Qqg@{ zIz5KyZvVgyE2${><&WL4($o^@f9!^p-j;yyV>hhywFHD8xGANfC6NEfO(|_Hf&Ts@ zHzi$3d~n~cB<&A$*+B%80y*meyDnWRiCXWPPoJk$(L`3E?^a1GN+NxPxHm`mT;-Rf zOCm;N$G<(G=8|7YL*3gFTNALIL5+vIF z_VFVAgoPN8H%WKIy(ftMjzXA6s(;#1jg5F&_!x$+uJs?UjmhaZCWg(<; zCN94wIhHe9g|0L2+{NFbAK(7z2$ahK{hdn6g4xCw&^UC&_kVFJ2@0lr+@W|4RQgRR z0@GCW4%p?@**h}) zelsdM^NjCQ(gaVGAl^`oILR&*i^s#`n(!QnoT7HA82Vl(T0Lim($_ldap}gk(nC(L`PR!a<#Y{g|2Shi1l84egjGe!=h@Gw3`D-!l|SJ_ylW|w6g>KAX6M8Rpv5=E@BDkbDEO5 z_#p!#L4Cz&8j;aYo>KzN9L$A;U7#C;O^N@Qoyx2zK zA2Tcx^S4ZVz_>umM_}Pc4U8lJl#dS@8R-9DE+TbOjUhuL2>|=sNhOAi4fK8RZ~v&l zkzl_v@#97Z`ahVTTG`)icx3*RvQ#6b9Ud}1(pl0+O1nK|fTYDlk*aX-kP(tFz0$KY z_Hd#!4J|G>0-;@KXgLy@R}juhQcjxEu0-;CQ9Ftw&&=v^-%f5klK`aGHzVjHh)@xwr=Pq#mncZsIU3*Q14gr46oPyWk-b^uar~Qj4r>L212+~ zNi#(9P;S0`3x+Fj!jbpR%P0MQ^k*XgX&_bMV6Xdhp!;_!=?b8y7kv70Kjb=j*lXcWT&YC z`|X-@{8W=c?<-dVBz++uKN3ToN*Y5TC}B#_)Xe#6|mqW@c z*$knlaoR5w)C;?j5Ue=V!QiR%a0tf7BiU1F;;;ZIG&vN^o=Q4H$UhiTmNbSCf3%~Y z^K%@85OTJo^!Md@lJX92ll8M%oMi)q7|@cvUk&uJvz;ht)3D)H7$E1EL&;qT=O2#Z zPbGPwE6*X+RTv%T{c^NkLir<6JV{?v2xte!Lt#A1%EIPlHa-x?lNndSM=&M-?T((o zWJ^8}Q=Um$Ltr$vu0lX}VJ8?917S1CZX_;3N(Ca~t1$eoe;_l-atHt$0S@h_VB{*y zzw_vg7$*Ak8ldaaGo~|{cZI*73QD>;)2N(GF(o8xjY8)AZo<{!0 zcMYfMu~@pc?lVc3)QEI((_A_68^aoXOE;6$NkY2pE>zU~(FI0XD?r}2I^H{sqRynL zq5vCOSZkA_Nef4x1t^}F4T19>Ssr2-JCL&Yz?_RnZ+*dCBI}el?|CZR60S$)SWa znbG)c(G9eAtOXf!bR{I;OH^f{nYqedAnQR7a6f*Ve)o8H>YctMw_QP;&iw2YGV8{)Lk7FmD9EFPZOsamM^)Sl2K{`Ia9A;xP~mB_A+QJUD7*E#15AO*Q6wU5+W=2hdm9+-S88d3T5vO ztbsug)mgC1Br8Dw=_Zk8lF(_vMc<)-vl?9=LzHcS+frKjiQd)pwk*3)^ zBU z63Gd9u+4+9@?0$)hKAA7o7~2DZ?U7+Le#MF<>YZYYbf8q6v7##rHEVBlOp1#yE)Ks zGK1U{0g+q$aA2k3*Fo2M^CBIMfn-$)DZMOhO&q8um_Y)oi`zQ+f$+o(Qd)!?a~Rxv z&831}O&W+<%pl8Efl}Q%Z750VsTRkwTJQ6S+nTM<;p1Am`2P1_?ZJ6D|f$C7ThG-gklX^hW(Cbc}udg)L zNOx-Yz%ZsTjeGLCOi3-0FlDg_mfNj#an1yKE?whjg7U?G(Z1tGeJAZaQEczQZ; zK>IDTAL{CQziy?Ii9;^xw7aKDe5y<3KOQt1Fs1NsEC`4?Jc>Fjp%h6(AtO{C#bv6L zbjTm5n}!;@9zRw(nI96O4c!1Hw9E0|SXN*dQQt$7OUTJr{$3(}E@3LWQ7&A!}DYeMY?y`M7i&>%?MUQ=J6rWDq>`g_xFA#I0G2o5_N~%aXhzRNX6EOtl zimw2OWuhdXrf{5zA!mVPb2Pqv)o&bz zBT8s7pwmXP3Iu2qa;HuQtg1~fImcYZm(g#tMjNSYs(_;imn-tn0<{_t)8|NcM!ca$+^J|s$d z2+`-P5#C821)?ICi!}VYBMS2Amx??(O3~YLgj&7<6Uf7veUZ>P|89)I_m&+6C;c!I zQi@OPfAg@Tl}VHjuUuo76?&wxzR(d7KGM^IA->qS1eoxRm@W*v+g;I0^%2;HTSRy@>1$_(KZGnf7#AjPk+1#0%2 zIX0{Xa#CLW09wd^gPQ>2;20uZ=b zmR@ifA}oRvK*2=`Ct1NrdI@0ua6Mn1_|tq@ukrk9glN+Mfx5lF$s7{i28jZ6em}|* zP~$Rg`!8stlfuxM`m2i8u8&G=efr0DEAss5LLW7nFh=Fimr=lh;&(D3tAJuN-uvv< zT!w@dIHwj%$uu=$!gCq+#W=w*Z1d}rlcCA$2yLfP4NAvqF3BE?K^2n_^T#BM!wsL+ zAc)qPXc9#rXvTD?-#g#$D8Qsaz5rk(Fn+6+`6 zrVoxbxs*41ILYef)y|*-@opCrT}?nqp|wOq8-(;MR?FZ^+}dl7Q^ky#sF!Rl@<rvdi z^O1WHK%gymcpUXwqm!A|x}L>4uiJ6A-=~o%3;iUy2uUHxlB!V<{uj z;rKn37dRe6n@d+2w690D>-_CRF)_La(sw|E@FpyDJSvv7pGUB$&ha7CK)hjjRDyDh zktB34gMMF6nP-xt0C@b-t%5FfQk5xlhqyJ^I z-@ef&8Ka9vI}NMCYrn>cZzkO!W+jdZZ!qL)vE+UfXnTFS(EyxRs<$*9QyTGNZ$Ae` zYPReJKrw3`zIwOa@3y$xipKY&qA_xzFw#Jzys=MxJJXZqg+rnHD{h)1^22+c9-0-R zWQr7VzdPUl5C@LNy`LtH$&4|R1!IygQkbU$rA#SlMOB8ka~}CgXQ|WULtH^u+5(Jk zF9jsZ1v#r!Bus6Q{IEG>y{7kse*chlkz!5cuQWDKT9*tYH?W<*Qb{dHi8_bDg^pID zg=R%RFvw{4oa=0%Wi4o-SuF@?kF4LEKevlbZdsVv+~?2gLqMeO#E^4#$DbOpm}vt! z7|@5bHot^429o||+Q)1{S}V5-5!3?*ouQ5*wdE$vPQ8@;bsz$LWa}`mNY?FZ_vp}^=ga!O5RJPAGRH-QA@r}ir z?DIErXU@h*C*HE7RRflKB7o!^X;oGbz=Xx}r>D^{T#{U}YrUN4rnb%v?3{h3Rkl@{ zt!PRQO{=B3hgjc4pGxUFehbO{DCPa(?ePlLJVcy#x_r7UB3-VmznypIaMB!gapD{c$r33sC(zz>iZvYseNmuz*krk@mk@2VVm(slv-a&E zQuM~NmEu#i&iF#6&nXhe0aKQpOqL36m|znvQwt=Dnu6R>w&~%x2r>Db6Af*vX{ljsnjKi!_A#rqJ;>s8-iL2!*IC6dUl`I!> z6%%FUDidpvxo5R17?X5Yjpwdab*lwvg_>6y87$VD`O9};3(m@ShC7nZUJmI#q$^s_ z6`vEu^+g2{cntI+-k0J5E|;#dVL_xfOSdfml{=P@Tze>OSq8~&Rl=dm&tu6-zSgHy zTh&PsvlZTM4Z9+&( ziEfBbpDiuZw;d55A&Xl^C>Fu4h_{F=V;RD%BBrJK`E+pQNb+734v8e`N{E(2(#NoJscf_yl0Jr&OvPw8Bz*`g zoC?u)Nct#NKozCskn}OEgepeEA?ZU{8RZMCdsS0W7K=&OC`%4b&zP}5Qd=&G119M= z1WO`YLY2XS!pcjcj0YaRZk~1&ZKkjnC64H2AQ^BfdZFnZ&g~^lNll2D`DO_BCY4!v z8G_ZPu#{5znTz<3yLCp3yETvA;NT&iVgRfC+$dWjLZj_B#@QD9!Q!CFyat% zdnmLM9!4~dZH&Z6XgtqbTJRx>t&9?_{|P(JW?K8mO%ARqE~WS6@mc)7szmmmUpa z{_UXQY&)`o`|hdqC$$jL-kECK%4?E5R7ME;UGU(#k&<_6A!HuheUy|_Mu^&7Fk!c{ zPzdQ$YC>c#tQ3_H@ty{Vpxc&$~kKgCp z)o@80^|4*HU1^t2r6zRnu?P5e^*}n79B`L$YqCl~DXl-q_w!-@ZGdlU%S!B0`$}w& zZC|k^ht=GYaDTaC;;Q^ovRr*^mu*iimy!d^(09AjL(iB{9!RStylq}edaMiTvg;}1 zQgUZ4s24yW!qE6r6kvy(1Ru5*P{0;*W z#$flkE)_A0UBvd-HpRN7=eCr2i!HW?&4+2KtDq$z*oAhPcGXaFg)QV^6&y!L^c%j;e`%>D}kk~}EP~1z>cZI=N$=noF#$7xh$(1v}rVdEhSUNnAAof2fwFD zSM+As?~Y|TV=ifOPhZk!T~rD|_mN#OkbXB8xl{dKG#!+in*}y+1Pz@&)5RLUZ59jF zXlt>u%M~u^gtN?s@hLIrkRo$Dr#fE%^}%N$&AcIwMnM=S=O^fIQ(U!_k6AH4Ib9re z{r-BS9)z;GR>hJo2!}n%uC-wKC^lhA-!2S$Y_=uPM<_k?Z0bUNZTvdneiv$>&qw-X z4b+Mz`9!a!+E3|mV}@(U+=2n;T&7nF;gN2)HlTC|@4v(kOG%5fx8f{{HG2sSuAo#? zJsvoyY(pJjxQ*TooCVYYhKmV+(c!93DjU)oI8>HXzqRbERZQ1DOPa2IUJ9Ew805fZ zR`PW|YTDg*qh`mUzXfS)0o654kPxg@{@%nfW#nmyM!9_Xka(j(}BLMll@RSsrj9=UpXbl&lE zTDMqO&Nnq>v-Ry&ojN2UYv{0}J!GHbdv& zbSVrfS5xQ~uwlVc@FnCUD^&6MdpnSC{~FZ_eqR3{>GRnykLD3k9vS<**fpklv)T2&Q;@eCgT!$-3E+$+k1FfQCoOfP+NHRgc6Ifj4d8c0~B(V0{ZoN zciJBhbT()D^5glrXaP))TK3TyR#a8ukJ7pZOK+my&eR5ioxsX9d)F#a4fL!6b|bc% z`)7hAo;R15+vE21<#5U}kT?e!XzfULF2?k#CdH+psuWGcafeWLilMf&4KnC(2^qd` z*SAf0oCks0??9l&>5=04QZhe~H#IV5xS~RPN@6&V2uQ6N@~GEL?)ir+$etPUctbLI zwz2g^yMhdvA&(9flV^Eqk>?{9^5Re!!P~tR zMt|KkmvrHBTB!nl+ERb?;o8G=ZK#YttT1U(5H(w0&)Z#`=5MAvnZ0mrtfZtG@B}`v z$!@rEB_9&2kWZT(HDdp~Nso-&wHvos1J!K{Kr-CiWB$P6hRUpIl>24d$97G%^tIJ2 zla6;Kq9`*il!}_Do9t3TfX2q0m{+wp4QX>*hF8-0RNzKu+&8`wlBV3KW zeuJlQ>9e_*t?0nwP=c!Z1guW`y&V2vnypoZXT_klG2#H^w9#Va+ zh3kmEzYuuJ?jWCm2h_ROxJ^XB&Xh0LQ-Nm(?Rn1YG)@{)gKs;k4fu9dUo{5D*-vzJ zQ@%;YUS0v9`!w)ifJ9;ekhjOZ?jUDa0Ay#`)gwp^CIEGZlH3eD8>mx~b}8veydUo4LB0#t#(3xR0Wya5THg79AVux&=_M7hP}r#dnq5iz zU2`p$Q&1RsK~R;qhmjwZ)mms0OHpRxzAhnwSVK{yTP0<#UnFXKG>|rI!`x_gO0855YqS*dvE=`4aU){jTERYitXmH2orIsvN8zb}K zDl@G#IpFz3idf&+S7Q0LSi#38ok$_wHr2I~1X@9Td8YCs3Q5zux%@mRWqUL!>o2V- zv<5hqJ2aECJn018*^=v~B)7ohLC{+O__o(s0WE!i-i8R@)1bW;+Fk=CbTqf`fQ~lT zLKl&b5<8pB)8@DfQzRjkFzAIt?#$AwBo8>@@*y(5E-iiBCH{R^T%g;}((Cmz5Vwbf zn$jolIX^^P*9y{T6-3?z*HS~XUj>mj!Zp&6C#xXxUbto&l42Ev-oOLFd+5-sAoSv$ zQI^5EZJ-gagg9Q*2O}@bgUE@H5+X;L$+INi(L>1&Y70e=c1~`ihmxxoN|aG@DajZ1 zAabo*h6o)PX*=B86Y_GI{%&*sLSHqFL#25yJkeN7axIu3!ccE$dP_&*$@f~4YbE)N zUJL5V_&*N;C;0ifj{oK~umVwvp}&`F$+DH4&=mIgF%@!#T&Y+~`&a=m=4S>~A%qI& zOBx$a!7rB?xW@Cc$S-R`L@uR7S_7m)@p;rM2NwYv~16EiXm4us^(nhQ~p@Gr-;q{o^NDiQwWxRw-H3*wLI zax}wmD}y1qE(?*e7<3c3nb)=Cv@AJ)Rw#^b*9*zb0veg|N%#)y{`!WMmA;>#i!;tC}5QcP7XP6#tM6^JT-$cK2F3)gH0 zk!jA=SCue_;o2ok*K}dyLc@zJmH4?$d~5mO7%SK$ly?>P@Z5b6t>s%|6}j&C+^u6; zLs};Ox^{2qcM8Zr_=XblG8SP=Em~Qa`FpO;nL%=!)y zULc(AP`JF8-5PQ;4G=w%xm$0zmf?t?Xy;rEz*^#7UyzTrWOv5K0is7KKW$t)CowGR1nI=fKotHR0Z))t$?&h1@TU` zkS~O>AXE_V)C)+0R1oh}3}|F3AAPOE2>1wuYKA%52Gojj1kmDLk6^W9tgZji4%=|jBixF^@rWdM!v*A zp-QORu9F9A%z^;U^me#AoDR21o~~YuAS!$!OolXYrt%FS;-?rlRN}x36>w%Zst%$L zU!SkCJu}~5!JG)d%qgBrPVn_cu^D}t%*@BbtCtC8MgVDXd--;K*^zS5ca>wQ39ro+ zWlWF&)bjSS-Q7P+!3v|eRu)qv8HK(|^FosjzvcaLQM4kv7@2*V0)O zoaqc=UraOd933&1QHMJl(Ue@l zNQR$WNRJPAo>Xf|mcN*}Q}U4`#5DG6!(ZU~K<;D>xeG&{cENW*Aa!BL(+2nt1xQ;M z^0apUp#Uk1NZxoT_{JGB78ap+D9|nMoFgPHS}3}gbGqm~lqgYrhqq94OXqagdnh@X z7EwO@P=HB+C4#PGz$b!%fF**iV&I_wJwYWxmJRpDlut+H-OT&&PKO9m79|hw^oO9E zC?UkDRjIOW?%w<35p)!l5PBGM*P|kcTq%%s@d=I(2XfO3c$f!4;&oEH@p_A;R!yZp3$dAr{8r!YTspAbTpwgN$q z*AMs;LKe0HAsY|R%OHd-X9Yqw9-cubge+o;(70P%ADKY1jFlk8^4`X9RJSg-wByNl3QMuNo$hoDr!(bV>eIL%m)NiA`YuU52GKGkW ziJ_%Ekt|DyOQ=1uAu9KMNLO0K2YUb@HDVN{l0LGBBan8`ACzu$cQsKuB3 z2s44?S%JM*Wf<_U(NrYQs_WZ&$$*rt5cu1KvP;@Vc z>^o#m8YsG@L&hDlCjljSGoc_pzdraigR@5{!I({8piBni-FE_HO9}+tgP{unG9?9q zu7Bt@fJ{k&kfqAM3ZR*#KzQ#x0GW~k;k}mtWJ)Z;yKexo+vOg^-&7>JM9dq}w$3>ZB;A29aPU=m_q5hHZvjb^vY z^>laLZ{N7pv5X=4U4xYTj+g7ZP*IU>rF40{Np8hQg~88M>b8)<&*Y%`*phVdu_10u z?y48d8;>LfQvuFz58KTH4F-)DL%5SE7mvL9#zYb`ePHG?e66pA?FE;K>3H=IV297> zHNXd+Et1Qrz*n~?N?7daZP`A%!J~_wX@$F{P1yX*(ND!4c2KcH2GoJRTmE=Dyj_Zk z)8FX_Zzm>WZ%=m!>>w8Kv(XN7>k^{T_+B+n7PAKsTnI+tS*==)A z-S%lKt;qUL6=sJ!9TKG_lq?W?xfMoQhdT&@_{gqqg`uv|e89-TbUDKK zxO)fRx-#^-h9Tz;zI0{imH#2v4#v$H`u93^@R2J+|6aEaM#vfZ_d0dZ>Vou_^zJM^ zx>U*$w7MWY4VF$G`h37(K*p$q&{LdKP{vb7$QlX6c|^tH`7`BncaX<;1bL$bK;`pk zI0M;zw*;RM@-sdmtZo--8YAHdOjm z!p*=q!KI@n-%tS>Y%SMH4jioHeJlu%9N%x^=cpND;AAE9V==yjfK6g!Ktv_=VFS!&L?d$*LpEaCg9*!h7eB;p;erU zC%00Cuo~jaAz~T`ccO0FB!I3#97DLu7S%MxxC4DHXLH#dw9IPm zwk?n-l~$Il)S19|%S}TFMddtcf+Ub(igD@%y6@^S4s(lO;YxNas;z|Ln{jNGsZdl~3B^}eoWF)BWrvCXo*HAvObr8T@?{WvW)Q}P zzGzYYNn_Vc4FlZx!Y7%W;BM3~u*I$;IL5A-8b)tST9kiP;0QE;iM1@e+S_sU_eeGWp*295!8It=g>kCOP8bDa5({TMPkfdTsZ-dFqkzBPlq4%0Ux z2Lr|f(mEC(ZQ+2~fUJ%IIP0vang8e~Boyiup=GtY{|++)$bBph6PH zqE2~a$J+y2FFIKq=bGeV2pbf_V$bMm-M($;!-~cC8ezX#*&MzhA=ASab#9&}dvie}5zSbzsl$pP=_BR#6=6JPrIkX#lNve`*@$P3CJCTRr)u^Y)8r^Vk~E;Jvg zd7S>s4jYv$KHc^I_U81|^GxIAxBs^GV|$a~-NM%fKt|Yq|K+#8{_E4{cmoA1&^iHZ zfHJ>AGlb}-guFo^IRkf)q{r~SjEWR+X;>qEdx;EyWqJs_r=$1^KdK8wIsSq z4F0-&qDSAYqL0#A($hF|B{%QBl3Ws8B{?~&(UTzd&7-%Xk6u|x5ATKn`sjZFy-W4y1##h`X-(e&4ETPbPEGKDuhz%Sl({O-F}~jqAkKDm3O^zlxXN?!G=W3 z!?-u}N40pzj2o(0s^u`m-fvscq-bXo7RInDtWqSY-6ww_j7GKTW07w7u4qgoua>tN zKQad(rW?0n1?6k|g+AU$pA<`#1QWUraBNXUjpCK4Rk9~kE8$Y3h%vPZ#!aY9!K0RB zSX_Rh&cDrH&6xF+aw18vOiigB7?(GpG7Xm;Ws86ObV!mpA(QXYq9ieG{OQa&dtVOc zXpXKw(Y9v241hGBG!WP!qV z)!7IXA4Y*Qn37TTXeCn=kN=H_$b(9QClo+N?SEDjt zjDReCDao&702CNX0(q=US|rjQo?q)9rzn>TfD*$1_~R68a%oXsn6}XIfqg@HNz`fA zsl>wlZIqWpourL?M3)-nB~d47BOlSDmh^`l*h^{KD3R|{qkT9lby_#&?_FxN5KL_) zogP*$HC`r6ji*iNb(a<;CGnkhoLWg;YLu14cV4xx-_q()?07maYO`^F8&CWEaw+7L z3IkkfV;z(_bMDKj1nre``R%l8blrHrEz$W*{d)L9=?V0>DZB3?Sb4da6Q|6+OKYV? zcu%`dbqOvtp7`_e8~yS=Wf`!6d0zqZsUZiq&;#8BgZpma?sHUjiqsE(YEBD&g=G7Tv{CBPv4yj!#1IA8u!Q1 zKqTt)+XD`OL~)DXRz;Z%H~`Ywkg4s7QSXY&IZ6w29;g%NbRsS_N()n$4#0%68ZH0| z3nGG8<5J_X-yIHS^Qi03rNu*MTDx>kp!XvZ zQ|T%YW1-ZEZ@P3{YGW*jI#fepLEVIs-YxsE5YPVLpP-ygNuTK!ziG2Qz|BMX;EcqGIPMb;zd|Wks2Hx`Ri-{DzXIjg*AFJhCC$E}++3vR=tL1wGsQGKz z`C?f5F=oDLEp5TKZ(F1oT~&~=>@0Fhsm`YK1L9KkRsItMcWm3^yP^;UtB4g!J<5}~n1Lyj#T=^M+snl}k-#%Zc zXiCcBCFHj7Yx1X3lpQf1_r@Ns{Gj?&%Ca-9-FH7Jz*)L1=lsioI_-NXxa{UqrY2OF zsMEgt*$__7HGVtqyYF{M^|b8!Q}H-l`A$ANHTk!nlsc{3kD0MkW2wO|t^9}?`y@bn z+Ql8$^8J+`x0=cv8(FndXTJSCGm*k4qBeZ{o|=?J=U;{v`IR55o62k$q2;GRX!>}i zFU+OhypSJ;g6+iVdl_J~BHW&Nc z>}mT+h^dTOX+q@ByRQZue3`eBQNm=Kk`v!=lbI`kaol{>KAja=Zcpr_J~a}*z7`3v zm7h(SO7&?$orKn}u$an#luV5$NS525pN)Lu)u7^O-ZD){|x7{NRMdSL?T-~(t z6M|Dyx*67!-S;8$W5RF`Cw9PXEp)E&@Nc>bsv0^! zGM+CqGPES)oepgn|9aG6^9QP}r6@`jb)1m<+%FcK>ZExk56O{S!bX0-M;s;P&JwGx zPeNx+uS{{O^W~M8^(~9nB($LPiQ|(Y{c5*pKc zzswVw8pP@VPUtb7ewpi|i(ii3WBO%{-N@C-RhJ%h4E-c(V_&EV!KIA>pG2$LY+`Pq z4Zgqf=zb=MI%XHXO4p~4#wpPY3+d28FG-)ekTs#E&mW7{P*rSb?C2vzC${|kd~}|o zaD!($_tW*ch}uoav2jjL3MRu(XX3PSa%((d5E>>fg@$}Nj~axAsS7ouyTBs`sma8d zZ>~M>?l(n;%#OuhPHGm$we*QWSn@BYvmz(N`(=<7Cbo(~e!oWxQj%!Xipk&iXu&Ea z+O*(MO59yAz1Yoe1)lSIU9%#g$s}I2W|GhD@GarVM4yZU=oUF&9zr2yilBy#+&+)G z5VO)Ukn84A7jo9J453Y+zxRc(C4{@{DUA!BP@Ry+MIm#7kxnpl8uU3Rq)w=HLenI4 z8}z9Qxf5#YKFqd}UL6ki5-=?#K<7J6Ld!z;_a$IjQZLi#yV@#4J4))6Qd0oH077YcO{=-jo!w+ACD5XD>XXIgPkC@7(&gBdYOCA2b)RQw%EO~ zI{TCGb)5d%3%RrJ?Fqe^ovoKT&+yaF^i@9g9d+4ZE<^WcC1#r_Y4-9P_`fP)w@PZ4kGmKy86N8{+;&eNNKCV77Sg1^#j7#X@>Jx)$ zV&c+)2!Y-{HHZjP+sl+LdGDyeFeTb_Qemb+_je`An@%eHZrZLesHRT~PI~&?v|FL& zuulu_R-#RYI1G{O(}FQdw8@Cl74Pho#D?v9lL@6O-lHvKOD=#hsbq>(PC}nvpY=k* z62$qcfujlC5*`zUmO#zfIvqIO5*~FSXi9CKHx%S{ASBM5_Fo{9)KHMy zqb?+_Fr<`|@Q4esIbM%cvsRc>C-gOwICJ7X0@PO3#VBM5G4dI@@%EX-oC`i`8|(5> zh*9LDHnlEBAxwyoB+4&}nn@hHxt1gpereQ9;@Jg8!~S}Uk*Ib7Qkh{FqOfUkKLSKL zT0b2>(;4FIsjz7Sh_s`AzI3LO#2XN4L;a-bOoxd#Akaj+dr=rVSO{8b7osVmVLQ=a zyAVwY6`NDpZ5OF9eQ`Yr$(nBuNQaBty%nG&CVq}`rW3}SAW2aCROL*^jJH8bo9?cu zX;~Yl-32M!zPQ7+g?BMP>h87&_V4Kn0~c|ZNvxggLC1abcHHeB!~@fr=SyxN*98XS(|)OKTZTcdT?Y&!@rhQA+R~4f>DOKj(=^d2JtCKWzzk#Y>9^GyF8$z* ze&yBtHVq-(>sxT?hK}YKjpyGE8Hn>`t6vaZy3wCG#^agXIvYzjXfu~72T4+_m$7uC zMspnxt_zREYU7q}z-O+L!7XtT6*t~9m*EA8ZK~c$A6#9!p_)0RRZ_U(DP-1YVu1!L zmTr(}u2a03=R~W4hGqChbWghHlvJsI7sDJ&H_S7~@O%30WQnNGqi+J|7=6#Qs2y&A zh(8Ka^PbK*e8IT8Zc0hiwCR}L;0%8SqNc^5-ZD(s>;E=*^t|q%S&x*()mw+$b#L3? z%1Y#X>m_n8kj~$1Fx*#q9li|QXC54+^y~bhNx$v|75OV3=GP0eK#sYya*W0EZx?2P z9CD8sUV@o8i3`=4c*KRM#a~YHLQc3xT*%tpX}h^R=eXLEt{9KJ5Vu5*nnE{?2LU3p zKNOWCOY;9cT9B7Sn>5_@kodch>9iAV-g1B0ASsD9@3^~O44X4;@v>V|F^scf44VgP zDwBAj*;d>-52GqmK>>MV9vX;_MT0rXOLFo(43Hp;LFJ+3H7CnKy<#2=ND{+rcSL(d zzkNyX1P=f#7XuX9OYZ}ZxDdiZd#ORsBQB&c5+_ljN*|B75X1BJm4?~U7r$ut)NE0m zkB3kQW1JhA>M@oyRL!Bru=?pzgld<*_+V5$(I)jHXWsi=5Sv7s_KbXaj}~Ml(I)jH zSKgxqF-f$^WhPJFqXj8p+GOqYpnPMg!>rjCGUV?!mQp|+yf}t{c;Ct`+Tm}dBy-1< zwu5L%-n_GLjH_qjeA4c)5$pFS-&^J4-S zH&5hrVkdP#W`0lrL*`5m;e?qV5s)(QwCpnt_6~Dx57+eYnfY-6jFg8Tx1Us*`GElp zk^{9`xtSjs!1y>*U+9B=SUpP$0S>H>OIc`FEahcrGkVJV0$%pG>O971#qL8 zfk1mswEhl)Ys9o+2hs5OPcjU6CvqddB%u!L81xSG+(eSa*MEIs&^r?+>GhvX81!ah zG}+&a*y2fT27*ae2H1D*PT3-_tCz-V=# z(-+#p4JIvQ#6+}ayf2!NShx?I1%|l8?`ckUL8*$q?k+IA9q6h-(SAC#Ud0Dv;j0F`iq-Ro~Q+Zjr(TfEJsso+M%gT*hET~k${$7$7UvDuq&A<12 z_`1(`#L8D*3{7X^bdtUXW1V;=PRHr1F&2qu;&i6IE>k&Z-m5Jvcj4Zr3mIM!Z2;5h zN*C@`x{$#YnNAnEaBtCtjI79Xy1s>bhb}Mx{mgu-%r1P}Aww?m@2Si#eA|J6=kR+f zvkTvLV8}Vpsmv~X+krLOflh7Q!nYkV3?r>C*|>#oJ7f?>qO&@(@C^v%l#H-N;v_k~ z6~T&ZUTGvw;^UhVEXK~nNrrrTq8~_Pm-+nihinqo?xSIWW!QmESGsmz3k!@E2RdEk znqKdYea1*}pwsoO-K^RIORoc+>d4wns4ZkrMv#R-r#iBBb7>0->Lf7;bgCn3H;uNS zIF6-L9a+2YrUizC!|$n%tlg*50^`6;mvm(9K9d$01rBuT2dwE4@0=e7fCF8U7x!(n zz}Rn~OY-8|a0=C!{TwHG@ohLpe8cZ0dGT#HMtTEXk{92GV}zIKtj$^bhFqp=Bq6mn zXYE^a4DjY(PTT97bPVuj;=IS+Q+t6i+Q$=oS$W~cN)|F$BP=)2sSGXL5Xl0gx`9p? zx$tcq#&H9ku5aPnI1JqeI+dY?Z{sjp8|YMq7QT(cNNu1~o3rq39L8w_o!Xp*Z{sjZ z8|c*LEPNY>@mZ!zHfQ16I1J1(oz;8n~9U;_|^^svza)Fk8koYB%6to4Ec5s zW2%?u9o);l??dZJb}!KBO4q*cgCW>Jr;A+sZV$#@1D&pK?Rz{Ja}9K=BWvH;!Dwrs zQym$ig94dAr#iCs{Ufs8c0W}|*8Y2o47a6I9a;NNEwb5$F6qeHe`R45me-eh@z(wW z3*)X#XLW1sKd?v?4YS4l<3~)ez&QVM5<5R^LPFX2gzwYvpr{q0&I7 zy0!9|#VBc@ON(@~*BntxiwtyWeQws8BWji|>6V+V=7^f5OS5^^@&_OIC ztS{-7TZzCCHT!$2TmCsLvFMk7FYA_@3SVNZG|(lV7qj48tYWg@ON^BUI+Yjt7_#Fl zFELgc=(4UX&gNBv_YJI)po4if+B8{Gjz#ztle@VZjrNe$zO46h?XW+O6waZd2y?UmL^up zbV**^x}l|sl`>tD7q?t!X=0^Jm*mB5CE`{%yDv#z+%_U^gR^u=UflK}Zhy0MNnYI6 zA#Q!MbV**^Iw)>=GjtPeu^OID-EuP|DH}j*`rmo%EDeiS^5GV0*!-3rE z)*wzY^9k^azx#^1u*a#=u}5IqVCawECf1TBuCU8I*gSDI$htww^bM` z4Rop_98vdv4{S%EQyp3OwhCjVflhT~;oB;Vl?FQ1k%e!oFjgAqR7V!Rt-@F-(ip@HigoRTS2v!?&05J0 z9qFqN*|&2C6)iD-8t8P_*7TxswjAT9flfDU?G7m7)+x)U?$z2IPPD}MY4|;rtF=3r zXo>ODK&N(S?G7bcV*E7FsU2Fo1E-c4KMizhht}>Coh8Ok1D)ETwL6TAd#cQSCOfot zr-3aoYRbQt-i2#-5ZDp}rhzWWi#r31`?oBgNnYIXUrUU!hTlu_;!cEGVvIG=C3$h@ zKrJ!G8t9U|xD%k37-J1|NnZST2gX}*?Z-PX#u|Pv$%`BBSYeDc&?R|s;~m_GW%*Qj@$Vn*zp`{$UOc~w`>qU~y|>nG zu!I}s8pLUb+=vOcT{Vc)Ho0LFZo6s_>t3zh@CSEJCE^R^QOoYb@o3;|!G}fq3A7&) zhP&?=L^T*v_dFi?TaR&69`N27dO!Y5*Guq_i=g}p1F9LIJ8j+p0wKsiT>2lD5}bh1 z;y-`+=b!(BrbKgGs>>2cL`LF*ENJ2gW{eQR^-wJe#KIyJHSrYvHKi&qAW9k3;{)U6&e-Sx7uNIAEn({OF}K z3kf9$2dq{D=lLw!Fb@S44h~qc2F@$wHs_(n!hvdvGYer5A%@b^pNEPI2dXR20qS~u z$ZqaD6ks@5J;{c4#CdSF9E?I5dmp*T5?$&SR?PA~3&Iar4GaVW(vO%8EUN{mkJt^2 zEF;9rZcpXJH0J)IX4zGD3^dm;GrArW2F+k?HZbs9tGc!+xsq0-t+483JDd2AFz8ELuWY< zq#v<+7*+?UkJvqoup>m!X1-ZK@kSxZmUp@InK0_!!Ab%?3W+xdtB^|BrKrWn!|t30 zE0dqhIYS4k5K03TdTPxYIcVg76;f%zj++zBbJK??tm2**)B8s<;hx&LUg?khG~HP=8KueXzBPl~b=6;7IRcAK< zgh>OQm=$JDHRfgw!Jrr=nBMFaddC>N^3KAfLS`zXmGcCAFqF^4S{S;l-ocW*10MrL zGGUaXe8?~GQ9y>CAI|h)(AQA9%AV(mrfvnFGiu9Hf(~@q3@9*W9{_YBpr|nkl!vjq zRsmBJ06M+BZXb46`e<;ARo+7v6%!YLI#bjpue_%|D!7z@IuFxF+MM#|Q+-SjXTV%U z%od+?Ee&D9ZO)hvbmiXDr~7U+nn-S5d-gWVTiZ#@lT?7wvK4@4pjrbEq}%`=uBl?F zKs2>l4MecKHDZ%TleTLh7CI!JULG}5Flb7;8gO8cBZKTXit;ps+-8^?cwmaZxwmBZRCi<&3(=u3P+ou7AG8gkxd(PVoXh=r~Q;@89JA>M~gRNL>^KrIvoQN_z>L)k+^ZOX`5 zowR+HjrA8ARKQMf3}S)o-<503`!yJ*0BXv06~Lx6x@Or7rm1&gMnmJdFo(w`HZ<0D za5m5j4g31MyKL!GG#nluJG)_O0UNM|o*^vx5527z&^7G&;60`#-{LIaKBu<(vB7Df zX@JQ-Xj^*S*2p!siWF={$d>7{U6Tzy3l#%CLwQzHZ{3zkE{HN(TR}GY91_<;!vK_q zaDVIUr@2>(2QL>=_4tgCO+E)C6#G_+L;AY8kfmvFsFBc$(L$ME?Sk3jG)8(HTZk<$ z%4+cJ`v*S`K@#s3$K_kqt^#VC(}8=y3>M;h;PAG)Z|@}4QBd47t$J>wcwFpdxC@SQ z^GGNhOa83C)IxW{mpyuH4cK`zlSpjP?w;M_hV>oWn!H-8G4HBJEB3qt=)VBhm@{QS zo`Ai*(5I0$_q*2gdw2fE8q=o+jqO-oZI#<%vdX(U)>1>umiKJ5Ht+VN8GqB#Hyk=S(P7oEJILhoYS^(*T2TRRCM+1>aN$ zJ9=jHQ@LxVQHWQW;ac|1DnkPfyqdt>`c|A~Ug&_HnwBEsY&?>Mwl>YEL1WWEbeS!} z$}!;LFpUm0pg?K^)U>}sb7wc8Kw<;bj3?^1Ma+nP0}33K05#9^gNyZ<`?-Nsh*E_p;59r^)G9~vVJ3TA<~jtvZ{L6U?XUl$q0@MQHgG{& zEp90t7Ir||u%#)%7IWKM+!m5oswy@+1=#qR9iB}ODq%S-B(Q=6VFpM@0=4+$_#hb0 z#=e4JGb}qzT^0xA5xcDz3p_@9#g6RC2a=#`{KPpvI!IG{w> zf);?WCb-2ZJt*Pn(O5Rz5&+mgY1^_>17gz}1D4aQn@kS8wJrhQkwA|c9h>f zzaC!j)so=2Y=X9>TROAG#PONRnEQ$I%%d;=*b4`UjjVY>958j*B?pMDlzD<2uyxo# z2av6Nd4en)hEfGEXUverZES2*!W^)A*mu{&1gnxT2Miwe(OeQx$o16}46ZQ}mpmppr zvpS$q*kRa4ZSp#xQ`mo4qEhIhBdP;Rh0Tdg&?ct?T7{j93fhRprTxU4j8p2RHNlQX z#%rX*GS)!e4!ax?tF_Ldm?L&RGFBa=&1|_UGZ|q58K9b6fuhvz2SLG8AV6^y2foZR zQ?7Op5s`@~Dt}0)!WG1sF?$gU6eW)V44;05JeWB7096PtMWA07?5qZ2NBm6P$cz zvczmIeBhKZ2^=ujX+~;o zlI;#|AQh?*d1{G;?UZdG6`By7pFdtVO-I_VQJRb}Ys(9aX7RM$Z#U2cy<9k2uyZq2-5_l`cEQtll@exza0(!MvNvP77*af!#)|req9A zJn8TKFn_^DeN%iW*2@x-(MiFzxuF22vsak*AiL+kr+6B(T)XQ{RaB1*nq| zHm7E!=IRD4J?2?6Qgd|!LXSCCMv5g_?ZX=oc}%bZRBL@@9K|}Xv{Qw+3s)v8(GW6h z*=HP`sE|80UN-iW;09`NCp;x0?HU4>CSsxk7`%`U!GW0$aAZ`^n>*srhT9W^1D-!- zRxMr~Y)_c*1gIZO#3Q)dO-vMIT{qmDO-ztu#^jj8-Qo3)>( zuA3~QGX>inSUY^#-U43hFv;y5z{9kw#Y5AS_?ryk6?&1^8{40vW0mkY80#blC*0;} z)HdVA2I&HiW5qsRp%WP|Hc1zF+z{pC75WhHYz{B!f*sIS8+J_Drn9JOKQbIBLrYcZ z@~*e;ay_-Iv7P1CU=7?DW{sro^h`DFJ!@xYyfyF&wMclu+BG!R4-S!>6nc>WUpIeh zz?FqA<#ml&SzhmvDtI?ADlp(IJWkc+EyTi&lK4+Weszsmdm<+{J88FJO@Ol6C__af(4 zDimf{E5x2gQBl_rY$5)_Xy>lB6Z+~c#FT9kH?Ejz-`4!P?PvQZBh1|va4oeO3b0`= zw}5Nu7L8^b+Ps!d#O1bB%+BL$>|UW5=lj!k+q!Iq!YP=~<%K3&zCRo=Tugz{v3Tq7 zngH9zUsw74?1I+1!NIdq&tH&-JEZBA3Coe>(0D=beo0u-=Fr z{M^6---fZuAg5~UP-q6zwv59y2k}YQFeO8Q8O+xPu)2vU+03D^4CZMOtEEjtff>xs zGFHcD8;Z(cI#ywLs?+9j+1x{sL|)^7(ZEzJ1HN9*SaOtc23}T}ePx`(-5+i**VoN? z(^5%0le!iyOuH)D&|A&Ut8QR|?N-dw;SMTp@?znY1^WH?%U}Ny6dY5n3Uzrt9lkaM zb|_MV3D$%~maGNkW*H|VOsg_f-#Hr!reiKOBempyDCmP()Qr@+K!&0|m_yA-t(#*g zw2v87MvAEdTdJC5fjl{=vMWoTCS%N@X0Y=W<|t$={|UuiKj{e-u&N}g+El;umbfZ} zJ;d5%K%%ws_LHBL+Hjwb<*BO9OUv`SVu>kuyoTjPsFqlf|K|BRV@#qlRJzAZXLjby zf7XmKh01Vz1-)&z5BruHlG_Fn(XbC=OrSE{*X`zbc%wqGbJ>EQIUEWljPcuGk2ju8 zYeLPRK8HC!FvP&t!A-`P-HZUCf~TsHAU{XNtZ;}cM3C18VmjClAcEXB5R={b03yh5 zM!e$=S#sMC*xwAG=GLs14RYLuY^~f}pcN#%Jll}1r5kfnL4v#8hD^58EF6YQG$M>+ z9KoAmZ;!N<UTq=8R!okxt!i`osOd6ZZ0MkTh%bmo0 zYYUHssj+P1L{ylS>WtRPBX?tjKzAFLgM>-VTkFR>tniE24OUIIpklSspv-D#J8i9E z1!#o*nZkO<>+$%l^_>bhBDO`dR7YE38fmwf!^-X=!#nelTI-QpL~iT6i)_TckK9&$ z57{J2Z|9eog};TzHl)z02gy!cD0kJQNei4{J%cPUjB7AWjx@mV^G9apFtuwNOyc8D7$E=&wFTSNiYl?>*5lNWE1jc9QF#YA--GmJX8h!dkB+}k*z*M zt|U`XD!q{+(CPY?M}on+Tt5Soj~S-5->z#x?|_1vsu#$f9y=5~_;>V~RGJ+MJI!G- zHa(-k@D;9^?zihlV7@UfuL|&|u9PI(z9goIT`1c!&Cb@7S3|UGNHgJ|e zW1^kG5-hTc*VKoAb*kE-f?7u!uZbqK44xC5NHczb{a$QOacc2#7-cp z8_lH$Q;PKYHsGhW^ZRf+M|uu=Br_gOR8I~tU#G;U-HSGhC6xH|@1lUo6qNc#bk_hL zp#jL7z{=`uLM4Y<`DN}z4+4{MhKK1bnj*f@Voz8IauneH_3>^Sn;``#2|CMRgpAjeJsWU&n_PmiX2{E3*u#L=STlYzvIz%nufQGIdOPO~o>&vH(4F&z z(ro0Fx6dRDM>jE<($T=g9doF7-4zc>O`$G4g_lQmcNk;?X+m%%f0(~x{t{k~L2&h2 z`-d4k#-r-3Jq5sX%QYwn)4R3-8zvJNBX+D8ynTT;wO*LL3uuS0JS{PZ-KWoMeDnf! zGSir_%j9}Nukp>>BnMHYyOF0Fd9$1FimdN7%&rO8!1$&CJTUBnmq#u^+flmHsGh(g zR&oV$S|P?wBf~MK5u_4BXj;VrvWsu z<$~r8bQ(aj4mMAka%VaXpn(M!-n_9+17MX>ga-_EQ6vE&OEmxnraN*L!CKNrW@-Se z(ulk5;p=t(C?yxvt8=09nQT8o7A`yJmCjO{zLdBQVhsCIUXLHc9wH|8;(|MfG2ugq z_7PF@X!;j}k?J7Qhr4uIAHmvJK?4@#`EuRF*<@i%Lq2J^7qVMFCZ*?NFSQpZ$`*j> zv=PvEbSTh~kEVc&hhcr30snJ?sj{a#nhZvtUwWZg1l!xTIrL8?Te{eIz4lv9lZk0c zB*aj~NyC-3^n_--U|Dc;%Ru~?sR%)1gRw%5afV!m3BCSuoQaTVa0vy(X_m3vq)Q6W z7G6hreweAE67L(Of#{z&I*U$ElhJ0}QEPXwWsuQm0`hskf#*$XRSJs>E{8lAi)(9w z(^Ui1G-jttZwPstHlB;>HB7K!5COTF1sq<*llT{iLd7AN%m6sMZLX(H#!8E2txTW) z;eD&1z+ej0e)sg8o=0#yW2UBg1Yj-|ieE@Ksy3#*OOSN$YOD{-yQ@gw1ShN-KOz=$ZUod!_ zZVYmmih7#ze#G=%KwOgNdZJcu{0;)js=0(}FAnp3hzDLFq7_bSY2Pv37tq%KmRw-2 zkKrbx{(%-Tw2CuurvnuEW4otR4-RX@X0g`Qh`oi3WYb&WLQLn0y@0jh!pvbpBF`j$ zA_&=H`s9OEVgWY!j;2D|oangGE5b`FQ84w#D7&}wmcF`@o>g&i3f7KnB`*_u{s7F* zjHLxCoU!o@-XNO6aII}uDAzt?vtI%#cU_T;nW(l4Wa>h7a>iy+v2tqAA)OBSW9#6n VD~S0%hB4zCsZv>S%zj&5{y(E+Y3Tp} literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/SoundUi.csv b/titles/sao/data/1/SoundUi.csv new file mode 100644 index 0000000000000000000000000000000000000000..0b2aa1482c9a7691887667631a9415eb6889ff6f GIT binary patch literal 14151 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

      ?1DX_>edo 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%0A82>Uonm4hA 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/SupportLog.csv b/titles/sao/data/1/SupportLog.csv similarity index 95% rename from titles/sao/data/SupportLog.csv rename to titles/sao/data/1/SupportLog.csv index 92295b11221b6dcb7e2ce64fb24a8b4fff8dc783..1c64be57bc4d184da204d543b60145230d15fc86 100644 GIT binary patch delta 2909 zcmYjTcT~_v5`H_gtAdCJ5fK7nmjsofDA>V>ElP~_>?Mk#BqSu{^fa->ZY=oh7?o#< zEgmZjilP{DmM9TTtR(vML{W?-YBXoLZ}Z39{j=})c4ua1zWKh{Uqy!hf+hYO9$sh9 z0Gkl6eY(XIk+EY{q`5c8w#R)8xiv#~>*E}*~dO?WoQSyjv z#~*{)4m*!!$|cyX{Q3XwTK;Kw`6}#AU&ra4G6eOyjjzUc;nDei9NRg+8Mcd_gs|Q9 z>;T#1=O}mMt4Nl!q+(dSDyb-z4j!sI%X}|Ymt|*lRh1>rSH-eH=8=&rg9B7;@vEtb zrB;Ay$&whPo{@A5QPC`)*HgV&N*byPl7djxn58UCHDak2uKKc!ic+mvGNTnP{2@jq zu+(g;Zj!uguiCM+jaLCI{X47XxV)=s!E&gF3S+s`OZl+8=&jyjiSMVn;B=rG#d3GB zxJOZzs8?81)n<~kH1#IS`gC=hw$7WR5N3+H zh3(H(2NpX+eM|D`7wQqo#JQ>-%i;y@d)AjKf+c6Es>yP4x$R_+f2bO=1V2$BEbX4TodM6)Lz3>V)MJv4L|s|t8Hz`RRR|#a zcu_x=r0Ud!Ww|efvlRIe;JsDL?f3<`H9o|xAJn5?Nrp9~8Z2p{1lAOUQ5nhRW(2$r zL=u{%qsa>~V+dFTwxMdsygi}CL*l3zZ(Z;fc(kw!q1%Ps32b`WlPa;idIuq$R3f7x zm5At-safPN(R~SIj2l4hS*8u5V03e+OYF!90tYUPrZ-q9$=P@(yYHA3Tp>xR^aDw& zGzwzrn@;bs?3+Z1EFM$oFGy(`0nDJ8ghn=)?b3^yN9Ra97Se8#ye|pR{j!wKqG8La zfaJrKbc&?I8qzFpWx6s4Zy+>#Y!-p@eYUurSSzL!pp_lr6 zfaHxvTukybly8$<4`U=%DV(p7lt*$37#GduByll38!Bk+VvcCXpOIYYz$nplVz9$I zfx(OTZu}CKZ}WMQfJBCxUVE1tv$W~Qpi29JZYO3i7m>Ue%9$ij0ei{bj@M#pno2Ni(lk3#>OWFJc8w1p)-6{#EIzNF~;DX@jXKaQp~GKdYABF65k)) z<^JaxJqx(R-vO{vMvnuoI^X!~?(%769LbVh&QQgJ3YSRT`>s*{dgy%1AGDK@LqlCh{WXN``?^Nay0%6p zmFntYEMppI#7}Ol5i{dWXDLlJI5#aqzs|C*xkgF<|F4j_7fLv(ciS2u7B5$W)r z4)1VyKG?16{r3Tn#PsT&qy40LwtkJJOO9^CGBeNN@?pNlL-0X?{+%SL&>=g%NMowa zIqDEUbHZ7A7i-Yor$k>Mxqa4IUOT6sl3c#%d@q*jRye(?pO93!?vSN24XsnT?#j}m z!rc;kPlGXO51r+X#~PHb{!D{6J)i5bEPG$MF76}Kl;x%|$i9|`f$vB!(;8i@4r$6& zUjzHvH4RwOH^4x!lY`L5czOJ^ApL6Py_i-4>QPfQZoaLmPeZ3VAI0w zr?oQPK(Ms|!&bF3K>Tn=Q;4o~a^Kq%4CMbyH&d5$d%DjS?-=|X1obi3DYw7D^ISC0 z#mXCOP}P=U224pBX;9n7_YAakI?3QU-@pfmXWhck8x;1`IfG*r9y)Tho^1 M&7s&)(;J7yZle=?cdjv4}IT+!S63 zSgdS>6;|4O3fOG>2FkT|9*~aN+W{^(+<)=8k~k zmT9n@;#Cev@O}vx3B6 zlWM^-Ysw2K*G{AF`z7feq@y$G`%34029pL0>;bJ7b^wf6>Lx+rZBize{$CXA&?NWF{r}yzeISK?@`ys; zcuIcn%R-TKP`LthdgB5Z`u-4#_htD&p`uq=$>AhlaK0}pge1ZxeP9m&8Fy*!GA z0k1~0?!d;UZRtYK&wUAdN3hhA+kWsKQq((1k0l=+K)8^1nT43k6;+QFW|FMOBT zr^6nGCe@z%%;&iuWF=NPlOLh9`7sl&;+2$?_g*^6mQ;qEp85&a8cxp%yQf3aZ-%CTDq}L3L)M@XG ze)pg3rRgL~J8O4Y{8KO42nT(ll3hbKX^e-%yi{^DzxJ@ZwYkB{WyLB>5iSq8^P}T$^0we^QpWS z`6cmBfIVk&ID$ac+p@VkJeJ?(xo$GahgnWkruUk^a>){tNsLy)fT%s+`jZIBC7FV1LRw;D7}c93w#IRPocm z>0H!+ey$Qk#{wJS3i+X}_zCOZ+Xk}?;iE2xPpf;->DKN_SMhQ=Z^^6uo=a&6Qt=$HS6EMF&Sm4Un zb7KV^Yi7Kl?#LZ3vY?M0DI(#&JyG;CSD?k$+SBa5$+RPW!tc{X|6V`nf37Wi6}=NeCk~kM}dWxO`g9M3Sw2!b#W5< z^~Hi%dA)?Wrj$n-AqNsaBp>uaCplBgEc(u5h}C8@dmRqP9ubck2OWCZlC;gX7Yr-$qUxml!J}i$k9E{;Im;8*Q5S*gq#QLm0;}35>1@6vBoZRf{9l?$?VhMTS?b^?dg(6 zd)N1&giTECy3 zjTS%jOkir~4C$oZ(35MiS=2Aq#Gf0lcdgd$~0vT-fB)aal52Rv1F$tF6QOR zV1)m$*OdFgeo2p?dxzv(#4XMT`P|PU;x!&W0MfJWSD~Z620$ z=$;v?s7|-z70n>K5sF@)Z$_#L_`gh4-H=bfI7KsO^h8DHojKXa#Zy%@*1eMyy-0@7 zR6`)=&oSt-K;1^1s$@ks(Zxk79_v0!6`f;?<)$7kKPY+`yi8Tpe!gjn=-Ve<(K+qU zF!it4qz1x2W{aX(ziOMJ8M`Z6(WCuljv`*x*`sKRjM-=K*Mq7q{7R0P^R>%Y9U%8O Lsq(n6{%QReuM>dS diff --git a/titles/sao/data/1/SupportLogType.csv b/titles/sao/data/1/SupportLogType.csv new file mode 100644 index 0000000000000000000000000000000000000000..fda48a13d09c63e2c206e0181af0d0dacceac83c GIT binary patch literal 62 zcmdPbR|qaGD9A4=@ySmQsVqqKOwsX6%uVIxGSpFeI(y#JeJhoCxr~79J=>r5Oarow MLE^if&FKWP0n?Wk>Hq)$ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/SynchroSkill.csv b/titles/sao/data/1/SynchroSkill.csv new file mode 100644 index 0000000000000000000000000000000000000000..311b6dd0c31a2f70e963538229274c9613727c26 GIT binary patch literal 5631 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 YGZmw-qx_Zx-_S^&u-cG2rHiEqMIc@PyQKTg5 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/TreasureHuntTaskText.csv b/titles/sao/data/1/TreasureHuntTaskText.csv new file mode 100644 index 0000000000000000000000000000000000000000..b737d5d33872d59f8e26669769fecbd75ed9774d GIT binary patch literal 1014 zcmbW0-AV#M7>3V-?jiPgz}Xpa^*D$+-y0Cz1BoK6KD6zZ;{PR zI+?OlnY5`^Tbb-$!d_p~DJ43gL<3m{`2gYu#5KrA5I-QFL3TmZ3wqIOv_Rmpqux3V z5M@neb2DaIoims~D0o^+i>`|9Ha^h&IRy$XoT$aTf*S7>pCG-|P(CcE42v z`2^x+VgPHOzIopl=M{Ez|W5#M}gcIIJ^JM fDB{uIEvjc=T)Cab{a+@0N;!Jw%5yNa?8N>7d#(zi literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/TrialTower.csv b/titles/sao/data/1/TrialTower.csv new file mode 100644 index 0000000000000000000000000000000000000000..ff51b87ef109f607afb799b20f41012a4d58007f GIT binary patch literal 2116 zcmY+FONv}a5Jl$&wFfWYf%5;E8ayy~VyidMl4@XRb%WY%d-*;m-kTUiWZtW&%6l@h zsZXDNdiwF_^UKrQKaU^3emnknygZ)YAOG`y`S<6y*N^w7=Pxgh&mUjt`u*ea{@3TP zkJm?hnQ1d+o!X2_E8D}6Bgg?n#@_qm@|SN)+mLq z&jb(80Pi5#B!5e1@5=C}tom=;W8N23gg3TP&Hcv2v$3Bd?Y4n(bZ zfP^OrqH-fe0#Rb)a1D8(r#MWHlM3Udfg6hs51COr;e<5b$wK&c||FIGwerHY{EN@+eQ z5tOc!21*q{=}Kv!R0-k~H>eIu6+!7r>7Y~*l&+KxN)qbP`B90n1d zD2TzmHU<%%D2TzmHU<%%D2PGmp7cOrBT7FeaeC(7Xkv{riPK3Ro+yaPg>}fo69q9z z*xTiaf|w-i&LK__1vNdILBxkeK}_zeGl=j+K}_zeGl=j+K`a9@i10)~ECPdad9hY z!o(&@&M++|5?Ut2X)=;9Wm+&rCo>6CrUg@&3?)pNmcJ{0XV>&3nJA|_u2z{AOwl?o zQ>Fz|m_9MJOqA2)jfE-Gg2~REG&zY)l+)$6C$voaV%p_0WkQ^t{4_?VO#5Qm?J{LT zoSi(h^CX$}#k6^9@p+jLXDe?lOquq@w0Ue{%7i#Od2M0Jv@a%}n(nS{qD1e1*P@DC literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/UnanalyzedLogGrade.csv b/titles/sao/data/1/UnanalyzedLogGrade.csv new file mode 100644 index 0000000000000000000000000000000000000000..b0bf28ae4f523984fe7fefe670bd9374364ea230 GIT binary patch literal 170 zcmdPbR|w5Z%uCFvtV&Js$xnALN=!-hOwsX6%uUsC&d<$F%`5Rt;pH;aQF=aeuab^Z zV5n=nyK6|ikH5PTFPD*y(#x(^3}IuCa07<02~fCwBC2qFkYkW5&?HkGr57`IqR9n^ K2Dk=66#xMDf-|WA literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/Unit.csv b/titles/sao/data/1/Unit.csv new file mode 100644 index 0000000000000000000000000000000000000000..70fbca14612ec10c5dc675c50aacfa1e1a82d853 GIT binary patch literal 561120 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 F{{t9rHp2h_ literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/UnitCollision.csv b/titles/sao/data/1/UnitCollision.csv new file mode 100644 index 0000000000000000000000000000000000000000..98eb0f993ebc1939385bca4b39648302945e7eec GIT binary patch literal 365911 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 sLskrD>#mfC^c1$ubFVmc+0*?7_qV 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 literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/YuiMedalBonus.csv b/titles/sao/data/1/YuiMedalBonus.csv new file mode 100644 index 0000000000000000000000000000000000000000..66bdb186761d064518a4ceb542b6afd2c4f76ed9 GIT binary patch literal 172 zcmdPbSBNal^i54k%yG)kD=qd+(Fra|EGltHEJ@XI%}W8%yj+F`20BVc28NdU28KYS z1mYMO=o^^n8(1nBSs54rkrGImA&QJSR0bqy3{(!%i=x~JMFzWaV=GfjAOac>02)*z A>;M1& literal 0 HcmV?d00001 diff --git a/titles/sao/data/1/YuiMedalBonusCondition.csv b/titles/sao/data/1/YuiMedalBonusCondition.csv new file mode 100644 index 0000000000000000000000000000000000000000..5f33487069cc9f1747afc5718d135f8940a99b8d GIT binary patch literal 174 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 E4+L>!>;M1& delta 6847 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 diff --git a/titles/sao/data/GashaMedalShopItems.csv b/titles/sao/data/GashaMedalShopItems.csv deleted file mode 100644 index c5a46aef3f4ad02b57b160fee878347396bab3f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46917 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 diff --git a/titles/sao/data/HeroLogLevel.csv b/titles/sao/data/HeroLogLevel.csv deleted file mode 100644 index 36a53b93b403e4a0a4c2f3753bb6618955363802..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1249 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 E4NDV+VgLXD diff --git a/titles/sao/data/RareDropTable.csv b/titles/sao/data/RareDropTable.csv deleted file mode 100644 index cb674f6afc5e3cedafda1d20a0d2dbd9a38d3bbb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11849 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 AxBvhE diff --git a/titles/sao/data/ResEarnCampaignShopItems.csv b/titles/sao/data/ResEarnCampaignShopItems.csv deleted file mode 100644 index 6d5dd17081410e8e3fd8905604d50d3ef5d88f29..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 630 zcmaiv&2GXl5QOi2mObpQ6G+ae2QH`zsCP@Tpi-SgZV=+_*|iBjZUhI9Jhs1`apV3z zZRl3k5B6u@Z4dph9-Uve(9GPlu07@3lC5bK!3SjYq@Z;{VoRV=7l0h5N|OqdqFmX(4PYC%gAeY<|{&JyL(`os&a;@V(9#3 z0c%7k6IE68>S!~u%~PWBBg@^ZR-vg0#b*7ih8yHq(G)5i5xSui z4MnFync_M<#FPj*z2aYY#8euIf`|}b%&Z7|;bm3Q|F_IO)*0%roOw~(ahlpIpP zEMVW@d<7A%f$=ya-dPHAR3ft;8dyEgzL`zhJc`$P@K_tHKCrjI9fRYBR`UOtl-wL$ z2CYWNvH9p_?mqh1(BYnsZGRz2PNt$$>(N=g-+my3KSMzANxlQS0O#2c$Ofx)sl90E EA299|^8f$< diff --git a/titles/sao/data/RewardTable.csv b/titles/sao/data/RewardTable.csv deleted file mode 100644 index 929ff82bf14bf419260324eb101c33dfe7034b7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 323785 zcmZU+&9ZbkkDWKKYpFq<|ID!m4o7&TkT2kKbcZKWw?h+$boGALdKP!)$@i4>RRf#E z#s&c_f@HG(%fJ7B|N0;Q_Fw;L?J|NXDG&-cII{(k%C?VtYr{SN2jZ+PRpmGk-c z$HjRs=j-p!i*qaI`|q!d^I6VMCBHvOrX_9UDEVH=aw_@jpGua4CV#zsy;ZWDO8!#k zkB8(hb(T}fU+OGJ$?7ae$?7ae$?E*|Bw3y1C|RB5RPwhv%cMTde>MW;{f7Dq{CI6_ioJ#(w&Tmh?@l&10spOyP zJdTp9^EgVb&f_S#I=?xl|74VZs`EHXuFm6B@~t|LQ^~jLJWeIws`CU_@~t|LQ^~jL zJdTp9^EgVb&f_RqJJ%X-|NQ;-*V|1ym-8V!tIqH0 zET@vOWNav>l0Vd0PU7PIL!IT+8XxLxuB+q^b(W)Kb(W)Kb(W)Kb(W*#r*V%@^7f~3 z$0y<7GuOD|li{ed8M2bWxL}i*n%N>*n%N>*n%O0Le!bxN+z z<5V*K$@|BtWH1gq9jB7PICLJTlEFB1UaqTTFb*FdN6FQB93@xhag1p3^D0 zI*(JyU>xrsr;@=qbRMUY!8mjtr;@?A*tt<)kN zPAJFd{x*-5gKm-YlzYt^{4ekKU0?@oz_{pB71alfi$3M3j~FLMeZaV@jr#mN#i089 zsB`70&yPBnGkw&#oatlkZ8WJ5{Jg6i^#S89j{1Oc7e{@-xO{1QsgD>ZM}2PU+&1cS zQ|EHj=O)HI5afLrSI+b?1|OL64#q{Fa?}Tmi$3M3&oHhW^#S9qHtKUX8@G-6+{KIL z1nqMdFUnD$yBJrF_PLA8H`i&a(k%{ICyc?=UtuKM*F<0b2;h*4kEdXzd!!^0P-??O&SH14;09&K8eJhlTY zU2Uq*Cy;mLmg@5f64U1irl*fOw~hMHH z>GuHcPayAVqdtSY2XKD^d3jek)8`4MwGTLWwNamZFTI*+wGTL$ca@`kz`={7eZaws zqdwqZB)6CL`FMh9_4&}B+eUrB!K>Hwsc*Ci!2KEFh;14vpnL*(d9|D*x=$c4LgXaT zeFAw5`#7oPKY_deifxkUJ^{E$ZfH-kgDywOPYIz=_4#?PWZNW#e)6%AET@tIIQ}_V zwQXv^aVi;rL+5d-GXRIq<0$#7fbuN)X(dXXzYL`(YkWPWS#`$vFV@&9<&!mBrSw%w zc9n9R>g+1zIMo?AL-IJ)nF{VVpnOuV#TvdVQ1wZ@#t4p6$v8u-VVg<@ykZSGl?-?x zd7RoA@Ivyl&em(sI$N(j>kN3k=nQzh=nPaL`DwE8iF3y59+QpFLDgfj@d;GL&X38) zCr}mNcuY1vfvOkZ5UTbWwT4hNPOSk{#TtG_twD7bYsjfJo`J~`d$y;4)hN_*vR%gkn z!TB397zWT}+!wUazP8Qy}<)f92-_!Pj%C)wKTw#H3B% zwKhU|IR%TaK}}}7@Zt+;@hCYR z9dL(#j-lHI`(K=n4!DElwdv@9J4hax`pGiow9PYm8*zO@Cx)_lvJ@y+c*jrvw;{qzZ zj0>oQq_wGJQR%X|kaXEx^m&?Cer>g|(?4y#(y1J6zS60d(dH|i+D4nNbb3r9zg9Yx zqs{r>*sA{NxPV8oa7RH4Kd%;Q;pf#tEesyT!uG0vf=98ioZ10Ada*Eg^kQM~2z{O{ zd}~aNQ^_FIi-lb+yetenq0D7rkSJf&azn4CM2gRpqlLFBSdJFns$lb~76yr8tG3a? zAkoFC^|0)NQwx75vglP$s}Fx;vDo2}TfXCy7bh9u+Y;$%Ci4w8#nbE+JA8vpvBM*` zd{ZJJS*PyUegE^C`M>{p&HUfk1j*}F$&^S)9w%e>En4v^Oz{E9C-Lfk7~Yb#FeIkS zQ#$u4-y71UiGT3%k_~(sCoXvEi2uWszhu?pDWlBOye^_(l&mo!(K$~W>5yvWq93GM zx#9<@RxbBJs+ENgq*__^K&lmZPp9l??76c^oCb))C*}&Wk6DJN<}^9iW3UA%lS5vBuFv3lCqazZM2xV)Jse zur-b`&Y)xA?NT-SjiWu=OPg<(svK>;U8-`l`F5$AbF}$(shY#(q%Znd9ds0cm}n@c zwxa6ED9EX;z@3bOoJKvklTnbpFJE zh@gWEW5mTeNMi)Ju`%Dv7`ZdW0fIfPVIlXl*#^=Ga&->U2ohg7YGC97E_I>qjQsVT z=#Ey|bl^q83ZzGYL9K)p$mSEG zRINU%)sKL}(`xktnpEd3AbkAwW0}L#s__GA#5d~h_2-}MC6!Zu{@KD>IrZlsQR8W8 z>qpd3PQCXhx*f^&-k&Y3RZhM4XA5i1GpP6W*N?!V9KP!v4*qcDbawHxy`;+N?BWLm ziLc6uul}&G7GISUkNWXU#j=5tyFM^ZeDx;={FO0&JX5hYmF$^{aVpuW2anPImOPN! zA6UV{koAfmU`5j55LS5Va0n}q^@<;11+rf86M+>~ulNyG*jB7p{0J+MdWEn8saC=Y zq*@6pkZL8YK&q9n0;yIOGLUKo%2W-qVmvAmqLtY9<5m${n`-5v8M~OOA+oTAsglA9 z}w?SEi*4{)7G(hhE{B>pEb(B^>iJW*y%BxJssEy;tmz zqxY_6dF0-o)hv(P`?H$mk$ZoDkLYa9tk+Sq{LZ~UG4jUYg2y~QyP>RUjPMVLIweUz>a)TzuHmQ35RkV z1+XLESdOExnx*mRD7a!~8*L7D#18GH%~!LOW5!s`($O?yxQ2$)_b=9?C2t?6c5n@C zoZ7)Pv~e2OuAz-nJGh3nNUw!mLmNlQLzBK-$z4NR8zpxQZ5$=L6?ifR;hdp783S06 z)a`*4Nn=x3p|Px?His}s~Zp#w_L`!c~*f*Y%|6UaOqQL%QumQr)m{d)Azk8 z;wGj*s+E8Osa9^&K&q9?WstSi4b;G}&dTb^w{6FCsOrf#SH^5pPrmIWUVXBje2Zd7 zPCfay?U>4`C*Q0@lv7W>S&U?&@egT+ymYf3G3Sg^?64Qcd8dtQI66~2@V4z3Iq|?7 zAd>7MCmwhMN0L3{!~<{nI?O1ilHHCOr;=BvJV^#qki0gP46OXl9ygKYq>CHKvh2Y; zg!h^cD^r{A#9cYs96Kj_l%vg8vpm^+dogXJ%~!LOqs>>dl%vg8vpm^+HA}O)Heb!s zUfO&$i=0|!HH)0uoW3tMU(I5h+T5Du+2+e=EYnHW9a_cO@+!zsb zAdL|a=P94uVy;9`yp9pEeo5b?_nXB_`bzS~HV&-wl-Jo;QhZr1x>>N$*ZA6M*mBWL zSm9}N(ak!ABw*C1OC`AnOKq z&j6%vBIqvSq_5;zj%&Ex#hUc()4VR_i4JxbWlmvx7h+Cfdlz3$VS5)`s3;q5cNe=L z8*Xyi@{i3vKQC!EqTb1y%;dU29ARBIXs}jhD+uf?<6t;J< z;}o`cs}e}HvMPa8E2|R7sj*Vs!uF1;jN=KYJ9rVS@65d6a|bUH2<0H~?XNp{adC7` z@FJX|13ILQbJX^#+uy;9IC(j`J$P|(bo=2&9oRMrGP@o<23neo7a7cyLHOiDEW0w<_>E7M)rHg_puaqw@As1KFEHz z9x(v5Fko?g<2c&0+G=z6P}E%KLva$?E9?s2x$#&Hor?BytI zjjL~88`n9@aa@EF^;xf{^r(gaO1{fnlB5A&)?FAnef%uU07k!}jeZmj)zEAvt#+BN>hJ@btopmwiaLAi}PU4_{ ztwALLPM_%~3Y}Fbo;R1CWhm%I{#l2DuAiQTDCkE0S&4$4elA5pca#sjKk(CYfyeJu_>$meFYa5;~N-S>D-zafkCjCb@il7%IuAiL=7a(5)pBWc)qv%Yz zpzEb)&IP?W32{>|PjGdrv?vjym<{dwL@4NepLGuOzE5<5-uGGQKrf0db)Xl;);iEQ zNTN(sf?kwZ?J$L!erXo{+*n}wyipE4{VaH(r{BRMr(m?NoAP}6fI~RZBT9fB#zzNT zlWi{(K5N|?} z)0orIbk#R%;=jayDJP9Mm_#$yVza2SxjepQ^-s2DK~) z^$nD|lI^U%WjI@Db+9UfDl0QJzS_eovb4GzIcFqn^?F=|j@5pxCjRxn3Ko1lu>wom z`$oVVCBQJWpRBP86_23@#(oVwuoWBBT@1K4kSjJQYr{n)b+Kl=t;#iYH_kkXiQ92w zleBqQ8=L2axsA>6tRpyY7@ief4$ByvXZM4_vrDfH*QzaBX;1Jh!zIfg0nakCmgR8e zEtl~c;<@+XVNYYwlIz!SS#yo0c#E#FCcfJ9!Z;#h1(@+VXiQxCAX%)K=Z#68qgUy( z7b#L@+JkQCZ%kiECQ`j!NG4LffnWUdd; z{vg@DFWvIKA=TT3Wc$7g$@cyW$@cyW$@cyW$?%!zcOjWb^>&bKNR`_h`u-u++l6G) zFJhwKkm~J1vgvan+4KR)aH0#T-rVU4Fm?z*mp4}I;*Di3O2D(Qn*J9h9w4w4vfI(w zRXZ+9@>NIHqGWi+kk={F5j=}$rz3fwvcR*8wSWfC!fHxJZadZ+13dX_EQx1h>FnDL zvX!wUo~@P6E}o55XGg_3_a#2}H|VcnRXo1v5VTRn<1SIPpNLtb7bEnFXYcM7UHJ9> zz%!gYT})R`WAhH4y^Kv(Y+uIa-OZxsvB@0{*FZQnxy0dOIX34Oho`YQ*El?lP401c z8Jl}70rx5M+;>~e?avFT

      Sword Art Online Arcade

      +{% if profile is defined and profile is not none and profile.id > 0 %} + + + +

      Profile for {{ profile.nick_name }} 

      +{% include "core/templates/widgets/err_banner.jinja" %} +{% include "core/templates/widgets/succ_banner.jinja" %} + +

      Register Hero Card

      +{% if all_heros is defined and all_heros|length > 0%} +If you have cards printed on the official network, they must be registered here in order to work with the game.
      +Only hero cards are supported at this time. If a card was registered incorrectly, contact a sysadmin.
      +
      + +

      + +{% else %} +Card registration is not set up on this server. Please contact a sysadmin. +{% endif %} +{% elif sesh is defined and sesh is not none and sesh.user_id > 0 %} + +No profile information found for this account. + + +{% else %} +Login to view profile information. +{% endif %} +{% endblock content %} \ No newline at end of file

      FQ~0-pLHe8cXAWXN>e%jtzKb;(3e>c=kFrXZi1G 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%0Ax+`b{~L$0w5pr!rndskdJv8sHE<2F(Ltwk9m1S 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 M*^-X+FdT~i0gl5fEdT%j diff --git a/titles/sao/data/Title.csv b/titles/sao/data/Title.csv deleted file mode 100644 index 73b4dfd7207ab28989dbe5cbc7d5fc46a10a30c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16225 zcmb7LU2hymc6|?!|6uSb0ce0V-?Pt70zV`Oj3loMVVB7ow&h*f#$w;5dn|ra6e)@N zpgt^%6e&ugNb8GQQR0tjcF)X{|3c2W)qSU{XS#-l0I5aRsXF)6t$XWMb^q6w-+w*( z`5&i0`|`U#e|_O^|8e1)+37E4|MJ6^muA12z4-m~|6KU`hgoC)sZ4)y;o?`*pMP`V z|7QR7%dcnu^TPLkn*PUsFw;~2eetV{-~RPtfB!Uj@IJowaB6x+{@_=i{mZ}o-b}IC z%*+h_A9b%q;X%}0j=C?S@NjC{OdB??q)pi>YmT2q-3L*3G3q{zy6>azmOON#?g?>q z;;KVjCBxxoQFkp0x1(?`3g1QDg)wOG0lYSZS2H+%7KJ}Y-EP!f$54WOB6Pt*My?39 zKE&2CEPe*7qV5xp4hzX0#P5?vc$&hiMR=WXbV`Bx&#pwlL43F#@4Wo=1Qzc{;maxL z1Hz^?v{;&FI4ITMyOqqn0W^8`Q*Uve2sAM@7avC z#5iJL+`nJ=?)%wGpM3kjpL{X#8HS7> zZ}xuqIOHOd)uDQFlk4=c4ct zfwh7S%}l5k$j$BaZmdwNotM3x`?h&uoL1Jp4Ifx|90hZO)vb8$O?@vFS&oS z7d(xRj;KSkI6~$MSjAKEjXA8fsCzT&J`-M`CT`X$jF9<+fltJXTm8#7@)~lSR&kun z8xSX~8|{k|z?m4)CEhK`m_HKUE)1CY1Y+4#@AVsat8L}Fg2`L~VPY!&a74dZdJr$Y zN`=B?JIlpnUQmG-3{HMR`=on0{^S_F<-4VfHK8>{l@R{oC)7 z`$!<`QMjBuUx^a=j0^N^=g&hk~LqCiXnfWL+-F%9qHZqy?0rL3*(A44&M7 zcr89g)U%OADYCIpY*~uwHVnA)-jbOvBI)#SteJygWKD({M%rbqb3bF3Li)!QDnx? z_Gt`UM1cogSQ=+2;dV6&ALm?A+%nzc$%q7}8ytd#9EixmiC4RWd1gaN0^!+lhj}1a zjzXk)=$Mz%VmP!sf$?B#FTNi};Y#lT+8``jQ52c63~?lsJ^%iX3w za%cV)`iin<8XN;n`I=f4-MfTsM&z(nx*ArB?79=lyuCNKlf_d+bT9L& zByQ;f%)MQdnov~}sxZOVhsTzxieIDn8^175@6R*uE_LF!yIw15YDJCuj|W@+buK!0 z3Tn!~#wi$!_Asw0^SaE!$0)cSaT~ju#%AsZ5aJ~{hkO5omHf}Lh>Udxj481L(^ywK z>M|RXyXx4k>McZ5*Q&Z&RhLS|*HHui2D=F1kJMGdv60gFa~ z8UMC*?%Z;2DE|idk06I^8#WT;*fx}HlQY8N?75^eBsA>#A4)) z!U_QUBpxHg+q-8U?&5?24(78$^R$t2-`h#KEt;$ileL$M&mv9PhAEq~5bVjp8qO?a zUwrP^iw-h%nZwW1Rk?MV)D4sRIr{S1s9E0FEdM$R9*CJ+@p}Zcr6_ppn=j4qrYd%g zhnL%;+1=ReJ{IreubJI2v-frbuJg5z*mV17Yf3jv=>=3dTg~OzFBM@vlA6SgP2x|Z z;1<_Ka67rXpWNH=QPr$%Y}OuwEhnsL+SoKb3ii>~ylj}4v4oS?Zy_&E?kMu>IUj9J z&4#IYEVi7sW@p3fJPz!mtqIyNLC4!agYBSmoa}t?5!R$^n3M~sa;ln$4HK~o^O4l# zYnXiF)72<=6K`+EJ2!nKHPsrX+5)Paq$XCw#OlI)BsGm1rqRLfLjUz4i>G7h)bJlX=3hUkhU&=Pnl zbD$JYk;mgb{41J3D@>qRU+~-h`xP7}`ek-63V;6^#jYqL5uB9iU zMq2B5C|QO$?uKv=#Pce0L|vU7l?h5tqvZ*k{2U7IkEiGtDYf{4pY#z%3I*Pu10m0t!H|WUZyLr=yLj` z>kM|vW|PICPH5g=aqsB(Yr4dU^XiIgN5@}>i;I^hLqi>Z1xMU<4;P2MJfY|C_9O=? zxGS#R>UmY|4T|6g`6vJ@ z9aYnvEypWY6&xK^tLm&(ud4Nes#W#X>LgWp&*Z3DRbS;6d{S)1T~1z|bSDlgxf36{ z0T)T$R~rRY)2%phUSDk#R86-&dpb8u}Gj-R{-6Fl~#)cmJ3UojSF+et@X?07WUt3eqHmz+5^k@s3j<#*pw(Zx}6tr!t zw(W`9I`7{x8niQQ&1T*Ke}}Yy$n-R$OhfgKGjk+Ja_Y zTeMB%tl^7*L!QNmfYQeCTQpbTL~Wfnj-aj4dMiC-_eWZkM~=2yaHXf~WrYE7PE0`a zjI+Pu!f&0Jfb(|+db9;iM_VnqjKAc|~ zR9={MM_Vnu>@9;Mk(0|{X}Ui^zMdF{(XW|he`8nQsmyoad<~trw}7h<89p& zZ=FhvD9vTiJh!w*a+y<#5vaMWJ~1Y^wHU!R-tv7+Y>|??3%H!`?He#S67`4qUQ#V5#o&W=9mKfW`V+tB`Cxa`uT7wr!_ ziFkXB*IkS6;)NZhmwY(D+u=O;4)>FV7iGlkY_Lnr#yLCk5wr8e{y?{2Xv!qm@8hF{ zw|B}Y*%@OOn6Zgn_{a>W53i*cdg?D7^%w5rbAsg72|gK#f)(B+mrS3$pw4&xX7Gmk zIXm(ZlQ-F=KYrEV`W0SjjzV1I<4qluZm06f4qhD$%DBl}?(7RS#Bb=!L(hH%AzhBT zz5Sqseg&rr%N#!4$C1^j!;g01BV!XJdxEPMwCX*<3nGu`52Ek$YLjJXqGH&Ydi0;3wJ0D4Petwftuvo74AsR0DKVl)A z9dGi5w(-ty)cN^&#yLCk5mV>qcN~TO&Q8|(hB2-cpU(H5t(Q?!pXa9?6T9$`v7da< z)p?;%=qb7VN?zhUh_7yyFiCf~#E<$_0q>)s9>tA)fku3=C~sNu8^B~?9gzwjMwIcf zdnNK2v+hbd@)6V3$Gv!w*t_E>zy%~V&9lJ8> z*uC9b@e5u{_paX>gvVuk)TJwv;(XV-rRG2qJ%Ki!7**l2eonZBsFiJ}rb}{Noqg{AJN^2bUG`h&*7x19- zxOQ6bu$R%LHntZZC0%f=g9`e@himaiWR(Mm)7v;K(?`QLE24>A_{gY7S4TZM`veQ0 zfh@;cj~EHUYh{$wudAbeUDlD0n0j}0)Vuqy7C;G((7Ump+X*@sWlvo`*z!y`}Y3_8XUOP diff --git a/titles/sao/data/YuiMedalShopItems.csv b/titles/sao/data/YuiMedalShopItems.csv deleted file mode 100644 index f5d91fe049abf8002ed086280ccf974c08008f5b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 41168 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 diff --git a/titles/sao/frontend.py b/titles/sao/frontend.py new file mode 100644 index 0000000..401257f --- /dev/null +++ b/titles/sao/frontend.py @@ -0,0 +1,264 @@ +import yaml +import jinja2 +from typing import List +from starlette.requests import Request +from starlette.responses import Response, RedirectResponse, JSONResponse, PlainTextResponse +from starlette.routing import Route +from os import path +import random +from Crypto.Protocol.KDF import PBKDF2 +from Crypto.Hash import SHA1 +from Crypto.Cipher import AES, _mode_cbc + +from core.frontend import FE_Base, UserSession +from core.config import CoreConfig +from .database import SaoData +from .config import SaoConfig +from .const import SaoConstants + + +class SaoFrontend(FE_Base): + SN_PREFIX = SaoConstants.SERIAL_IDENT + NETID_PREFIX = SaoConstants.NETID_PREFIX + ALL_HEROS = [] + def __init__( + self, cfg: CoreConfig, environment: jinja2.Environment, cfg_dir: str + ) -> None: + super().__init__(cfg, environment) + self.data = SaoData(cfg) + self.game_cfg = SaoConfig() + if path.exists(f"{cfg_dir}/{SaoConstants.CONFIG_NAME}"): + self.game_cfg.update( + yaml.safe_load(open(f"{cfg_dir}/{SaoConstants.CONFIG_NAME}")) + ) + self.nav_name = "SAO" + self.card_key= None + self.card_iv = None + + if self.game_cfg.card.enable and self.game_cfg.card.crypt_password and self.game_cfg.card.crypt_salt: + hash = PBKDF2( + self.game_cfg.card.crypt_password, + bytes.fromhex(self.game_cfg.card.crypt_salt), + 48, + count=1000, + hmac_hash_module=SHA1, + ) + + self.card_key = hash[:32] + self.card_iv = hash[32:48] + + def get_routes(self) -> List[Route]: + return [ + Route("/", self.render_GET, methods=['GET']), + Route("/update.name", self.change_name, methods=['POST']), + Route("/matching.auth", self.matching_auth, methods=['POST']), + Route("/matching.auth/", self.matching_auth, methods=['POST']), + Route("/qr.read", self.read_qr, methods=['POST']), + Route("/qr.register", self.reg_qr, methods=['POST']), + Route("/profile.register", self.reg_profile, methods=['POST']) + ] + + async def render_GET(self, request: Request) -> Response: + template = self.environment.get_template( + "titles/sao/templates/sao_index.jinja" + ) + pf = None + + usr_sesh = self.validate_session(request) + if not usr_sesh: + usr_sesh = UserSession() + + else: + profile = await self.data.profile.get_profile(usr_sesh.user_id) + if profile is not None: + pf = profile._asdict() + if not self.ALL_HEROS: + self.ALL_HEROS = await self.data.static.get_heros() + + err = 0 + suc = 0 + if "e" in request.query_params: + err = request.query_params.get("e", 0) + if "s" in request.query_params: + suc = request.query_params.get("s", 0) + + return Response(template.render( + title=f"{self.core_config.server.name} | {self.nav_name}", + game_list=self.environment.globals["game_list"], + sesh=vars(usr_sesh), + profile=pf, + success=int(suc), + error=int(err), + all_heros=self.ALL_HEROS if self.ALL_HEROS else [] + ), media_type="text/html; charset=utf-8") + + async def change_name(self, request: Request) -> RedirectResponse: + usr_sesh = self.validate_session(request) + if not usr_sesh: + return RedirectResponse("/game/sao/", 303) + + frm = await request.form() + new_name = frm.get("new_name") + + if len(new_name) > 16: + return RedirectResponse("/game/sao/?e=8", 303) + + await self.data.profile.set_profile_name(usr_sesh.user_id, new_name) + self.logger.info(f"User {usr_sesh.user_id} changed name to {new_name}") + + return RedirectResponse("/game/sao/?s=1", 303) + + async def matching_auth(self, request: Request) -> JSONResponse: + self.logger.debug(f"Mathing auth params: {request.query_params}") + self.logger.debug(f"Mathing auth headers: {request.headers}") + uid = request.query_params.get('userId', '') + + if not uid: + uid = f'Guest{str(random.randint(1,9999)).zfill(4)}' + self.logger.info(f"Matching auth request with no userId, using {uid}") + + else: + self.logger.info(f"Matching auth request for userId {uid}") + + return JSONResponse({ "ResultCode": 1, "UserId": uid }) # Just auth everything for now + + async def read_qr(self, request: Request) -> PlainTextResponse: + if not self.card_key or not self.card_iv: + return PlainTextResponse("e13-1", 400) + + usr_sesh = self.validate_session(request) + if not usr_sesh: + return PlainTextResponse("e9", 403) + + frm = await request.form() + qr_data = frm.get("qr_data", "") + if not qr_data.isalnum() or not len(qr_data) == 0x40: + return PlainTextResponse("e14-1", 400) + + try: + cipher: _mode_cbc.CbcMode = AES.new(self.card_key, AES.MODE_CBC, iv=self.card_iv) + except Exception as e: + self.logger.error(f"Error creating card cipher - {e}") + return PlainTextResponse("e13-2", 500) + sn = b"" + try: + sn = cipher.decrypt(bytes.fromhex(qr_data))[:19] + sn = sn.decode() + except Exception as e: + self.logger.error(f"Error decrypting card data {qr_data} ({sn}) - {e}") + return PlainTextResponse("e14-2", 400) + + if not sn.isnumeric(): + self.logger.error(f"Card serial {sn} decrypted incorrectly") + return PlainTextResponse("e13-3", 400) + + return PlainTextResponse(sn) + + async def reg_qr(self, request: Request) -> RedirectResponse: + if not self.card_key or not self.card_iv: + return RedirectResponse("/game/sao/?e=14", 303) + + usr_sesh = self.validate_session(request) + if not usr_sesh: + return RedirectResponse("/game/sao/?e=9", 303) + + frm = await request.form() + serial = frm.get("qr_register_serial") + hero = frm.get("qr_register_hero") + is_holo = bool(frm.get("qr_register_holo", False)) + + user_hero = await self.data.item.get_hero_log(usr_sesh.user_id, hero) + if not user_hero: + hero_statc = await self.data.static.get_hero_by_id(hero) + if not hero_statc: + self.logger.error(f"Failed to find hero log {hero}! Please run the reader") + return RedirectResponse(" /game/sao/?e=13", 303) + + skills = await self.data.static.get_skill_table_by_subid(hero_statc['SkillTableSubId']) + if not skills: + self.logger.error(f"Failed to find skill table {hero_statc['SkillTableSubId']}! Please run the reader") + return RedirectResponse("/game/sao/?e=13", 303) + + default_skills = [] + now_have_skills = [None, None, None, None, None] + x = 0 + for skill in skills: + if skill['LevelObtained'] == 1 and skill['AwakeningId'] == 0: + default_skills[x] = skill['SkillId'] + x += 1 + if x >= 5: + break + + for skill in default_skills: + skill_info = await self.data.static.get_skill_by_id(skill) + skill_slot = skill_info['Level'] - 1 + if now_have_skills[skill_slot] is not None: + now_have_skills[skill] + + + user_hero_id = await self.data.item.put_hero_log( + usr_sesh.user_id, + hero, + 1, + 0, + hero_statc['DefaultEquipmentId1'], + hero_statc['DefaultEquipmentId2'], + now_have_skills[0], + now_have_skills[1], + now_have_skills[2], + now_have_skills[3], + now_have_skills[4] + ) + if not user_hero_id: + self.logger.error(f"Failed to give user {usr_sesh.user_id} hero {hero}!") + return RedirectResponse("/game/sao/?e=99", 303) + else: + user_hero_id = user_hero['id'] + + card_id = await self.data.profile.put_hero_card(usr_sesh.user_id, serial, user_hero_id, is_holo) + if not card_id: + self.logger.error(f"Failed to give user {usr_sesh.user_id} hero card {hero}!") + return RedirectResponse("/game/sao/?e=99", 303) + + self.logger.info(f"User {usr_sesh.user_id} added hero {hero} as card with id {card_id}") + + return RedirectResponse("/game/sao/?s=1", 303) + + async def reg_profile(self, request: Request) -> RedirectResponse: + usr_sesh = self.validate_session(request) + if not usr_sesh: + return RedirectResponse("/game/sao/?e=9", 303) + + frm = await request.form() + name = frm.get("sao_register_username") + + if len(name) > 16: + return RedirectResponse("/game/sao/?e=8", 303) + + profile_id = await self.data.profile.create_profile(usr_sesh.user_id) + if not profile_id: + self.logger.error(f"Failed to web register User {usr_sesh.user_id} with name {name}") + return RedirectResponse("/game/sao/?e=99", 303) + + await self.data.profile.set_profile_name(usr_sesh.user_id, name) + + equip1 = await self.data.item.put_equipment(usr_sesh.user_id, 101000000) + equip2 = await self.data.item.put_equipment(usr_sesh.user_id, 102000000) + equip3 = await self.data.item.put_equipment(usr_sesh.user_id, 109000000) + if not equip1 or not equip2 or not equip3: + self.logger.error(f"Failed to create profile for user {usr_sesh.user_id} from (could not add equipment)") + return RedirectResponse("/game/sao/?e=98", 303) + + hero1 = await self.data.item.put_hero_log(usr_sesh.user_id, 101000010, 1, 0, equip1, None, 1002, 1003, 1014, None, None) + hero2 = await self.data.item.put_hero_log(usr_sesh.user_id, 102000010, 1, 0, equip2, None, 3001, 3002, 3004, None, None) + hero3 = await self.data.item.put_hero_log(usr_sesh.user_id, 105000010, 1, 0, equip3, None, 10005, 10002, 10004, None, None) + if not hero1 or not hero2 or not hero3: + self.logger.error(f"Failed to create profile for user {usr_sesh.user_id} (could not add heros)") + return RedirectResponse("/game/sao/?e=97", 303) + + await self.data.item.put_hero_party(usr_sesh.user_id, 0, hero1, hero2, hero3) + # await self.data.item.put_player_quest(usr_sesh.user_id, 1001, True, 300, 0, 0, 1) + # Force the tutorial stage to be completed due to potential crash in-game + self.logger.info(f"Web registered User {usr_sesh.user_id} profile {profile_id} with name {name}") + + return RedirectResponse("/game/sao/?s=1", 303) \ No newline at end of file diff --git a/titles/sao/handlers/base.py b/titles/sao/handlers/base.py index 2f2f13e..e2cb9d1 100644 --- a/titles/sao/handlers/base.py +++ b/titles/sao/handlers/base.py @@ -1,10 +1,9 @@ import struct from datetime import datetime -from typing import List -from construct import * +from typing import List, Union from .helpers import * -import csv -from csv import * + +from ..const import GameconnectCmd class SaoRequestHeader: def __init__(self, data: bytes) -> None: @@ -21,10 +20,9 @@ class SaoRequestHeader: class SaoBaseRequest: def __init__(self, header: SaoRequestHeader, data: bytes) -> None: self.header = header - # TODO: Length check class SaoResponseHeader: - def __init__(self, cmd_id: int) -> None: + def __init__(self, cmd_id: GameconnectCmd) -> None: self.cmd = cmd_id self.err_status = 0 self.error_type = 0 @@ -37,12 +35,40 @@ class SaoResponseHeader: return struct.pack("!HHIIIII", self.cmd, self.err_status, self.error_type, self.vendor_id, self.game_id, self.version_id, self.length) class SaoBaseResponse: - def __init__(self, cmd_id: int) -> None: - self.header = SaoResponseHeader(cmd_id) + def __init__(self, cmd_id: Union[GameconnectCmd, int]) -> None: + if type(cmd_id) == int: + cmd = GameconnectCmd(cmd_id) + else: + cmd = cmd_id + self.header = SaoResponseHeader(cmd) def make(self) -> bytes: return self.header.make() +class SaoGenericUserTicketRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + ticket_id = decode_str(data, off) + self.ticket_id = ticket_id[0] + off += ticket_id[1] + + user_id = decode_str(data, off) + self.user_id = user_id[0] + off += user_id[1] + +class SaoGenericUserRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + +class SaoNoopRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + self.dummy = decode_byte(data, 0) + class SaoNoopResponse(SaoBaseResponse): def __init__(self, cmd: int) -> None: super().__init__(cmd) @@ -51,154 +77,164 @@ class SaoNoopResponse(SaoBaseResponse): def make(self) -> bytes: return super().make() + struct.pack("!bI", self.result, 0) - -class SaoGetMaintRequest(SaoBaseRequest): + +class SaoTicketRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) - # TODO: The rest of the mait info request + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off -class SaoGetMaintResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) - self.result = 1 - self.maint_begin = datetime.fromtimestamp(0) - self.maint_begin_int_ct = 6 - self.maint_end = datetime.fromtimestamp(0) - self.maint_end_int_ct = 6 - self.dt_format = "%Y%m%d%H%M%S" +class SaoTicketResponse(SaoBaseResponse): + def __init__(self, ticket_id: str = "9") -> None: + super().__init__(GameconnectCmd.TICKET_RESPONSE) + self.result = "1" + self.ticket_id = ticket_id def make(self) -> bytes: - maint_begin_list = [x for x in datetime.strftime(self.maint_begin, self.dt_format)] - maint_end_list = [x for x in datetime.strftime(self.maint_end, self.dt_format)] - self.maint_begin_int_ct = len(maint_begin_list) * 2 - self.maint_end_int_ct = len(maint_end_list) * 2 + return super().make() \ + + encode_str(self.result) \ + + encode_str(self.ticket_id) - maint_begin_bytes = b"" - maint_end_bytes = b"" - - for x in maint_begin_list: - maint_begin_bytes += struct.pack(" None: + super().__init__(GameconnectCmd.GET_MAINTENANCE_INFO_RESPONSE) + self.result = 1 + self.maint_begin = maint_start + self.maint_end = maint_end + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_date_str(self.maint_begin) \ + + encode_date_str(self.maint_end) class SaoCommonAcCabinetBootNotificationRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF -class SaoCommonAcCabinetBootNotificationResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) - self.result = 1 - - def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - ) + self.net_id, new_off = decode_str(data, off) + off += new_off - resp_data = resp_struct.build(dict( - result=self.result, - )) + self.place_id, new_off = decode_str(data, off) + off += new_off - self.length = len(resp_data) - return super().make() + resp_data + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.store_name, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off + + self.current_version_app_id = decode_int(data, off) + off += INT_OFF + + self.current_master_data_version = decode_int(data, off) + off += INT_OFF class SaoMasterDataVersionCheckRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + self.current_data_version = decode_int(data, 0) class SaoMasterDataVersionCheckResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self, current_ver: int, game_ver: int) -> None: + super().__init__(GameconnectCmd.MASTER_DATA_VERSION_CHECK_RESPONSE) self.result = 1 - self.update_flag = 0 - self.data_version = 100 + self.update_flag = 1 if game_ver != current_ver else 0 + self.data_version = current_ver def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "update_flag" / Int8ul, # result is either 0 or 1 - "data_version" / Int32ub, - ) - - resp_data = resp_struct.build(dict( - result=self.result, - update_flag=self.update_flag, - data_version=self.data_version, - )) - - self.length = len(resp_data) + resp_data = encode_byte(self.result) + resp_data += encode_byte(self.update_flag) + resp_data += encode_int(self.data_version) return super().make() + resp_data -class SaoCommonGetAppVersionsRequest(SaoBaseRequest): +class SaoGetAppVersionsResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_APP_VERSIONS_RESPONSE) + self.result = 1 + self.data_list: List[AppVersionData] = [] + + def make(self) -> bytes: + ret = encode_byte(self.result) + ret += encode_arr_cls(self.data_list) + return super().make() + ret + +class SaoPayingPlayStartRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.paying_user_id, new_off = decode_str(data, off) + off += new_off -class SaoCommonGetAppVersionsRequest(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + self.game_sub_id, new_off = decode_str(data, off) + off += new_off + + self.net_id, new_off = decode_str(data, off) + off += new_off + + self.place_id, new_off = decode_str(data, off) + off += new_off + + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.store_name, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off + +class SaoPayingPlayStartResponse(SaoBaseResponse): + def __init__(self, session_id: str = "1") -> None: + super().__init__(GameconnectCmd.PAYING_PLAY_START_RESPONSE) self.result = 1 - self.data_list_size = 1 # Number of arrays - - self.version_app_id = 1 - self.applying_start_date = "20230520193000" + self.paying_session_id = session_id def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "data_list_size" / Int32ub, + return super().make() \ + + encode_byte(self.result) \ + + encode_str(self.paying_session_id) - "version_app_id" / Int32ub, - "applying_start_date_size" / Int32ub, # big endian - "applying_start_date" / Int16ul[len(self.applying_start_date)], - ) - - resp_data = resp_struct.build(dict( - result=self.result, - data_list_size=self.data_list_size, - - version_app_id=self.version_app_id, - applying_start_date_size=len(self.applying_start_date) * 2, - applying_start_date=[ord(x) for x in self.applying_start_date], - )) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoCommonPayingPlayStartRequest(SaoBaseRequest): +class SaoPayingPlayEndRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.paying_session_id, new_off = decode_str(data, off) + off += new_off -class SaoCommonPayingPlayStartRequest(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) - self.result = 1 - self.paying_session_id = "1" - - def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "paying_session_id_size" / Int32ub, # big endian - "paying_session_id" / Int16ul[len(self.paying_session_id)], - ) + self.paying_user_id, new_off = decode_str(data, off) + off += new_off - resp_data = resp_struct.build(dict( - result=self.result, - paying_session_id_size=len(self.paying_session_id) * 2, - paying_session_id=[ord(x) for x in self.paying_session_id], - )) + self.net_id, new_off = decode_str(data, off) + off += new_off - self.length = len(resp_data) - return super().make() + resp_data + self.place_id, new_off = decode_str(data, off) + off += new_off + + self.played_date, new_off = decode_str(data, off) + off += new_off + + self.played_type = decode_short(data, off) + off += SHORT_OFF + + self.played_amount = decode_short(data, off) + off += SHORT_OFF + + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.store_name, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off class SaoGetAuthCardDataRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: @@ -207,7 +243,7 @@ class SaoGetAuthCardDataRequest(SaoBaseRequest): self.cabinet_type = decode_byte(data, off) off += BYTE_OFF - self.auth_type = decode_byte(data, off) + self.auth_type = AuthType(decode_byte(data, off)) # 0 is unknown, 1 is card (banapass, aime, AICC), 2 is moble off += BYTE_OFF store_id = decode_str(data, off) @@ -226,147 +262,90 @@ class SaoGetAuthCardDataRequest(SaoBaseRequest): self.chip_id = chip_id[0] off += chip_id[1] -class SaoGetAuthCardDataResponse(SaoBaseResponse): #GssSite.dll / GssSiteSystem / GameConnectProt / public class get_auth_card_data_R : GameConnect.GssProtocolBase - def __init__(self, cmd, profile_data) -> None: - super().__init__(cmd) - +class SaoGetAuthCardDataResponse(SaoBaseResponse): + def __init__(self, nicknname: str, user_id: int) -> None: + super().__init__(GameconnectCmd.GET_AUTH_CARD_DATA_RESPONSE) self.result = 1 self.unused_card_flag = "" self.first_play_flag = 0 self.tutorial_complete_flag = 1 - self.nick_name = profile_data['nick_name'] # nick_name field #4 - self.personal_id = str(profile_data['user']) + self.nick_name = nicknname + self.personal_id = str(user_id) def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "unused_card_flag_size" / Int32ub, # big endian - "unused_card_flag" / Int16ul[len(self.unused_card_flag)], - "first_play_flag" / Int8ul, # result is either 0 or 1 - "tutorial_complete_flag" / Int8ul, # result is either 0 or 1 - "nick_name_size" / Int32ub, # big endian - "nick_name" / Int16ul[len(self.nick_name)], - "personal_id_size" / Int32ub, # big endian - "personal_id" / Int16ul[len(self.personal_id)] - ) + return super().make() \ + + encode_byte(self.result) \ + + encode_str(self.unused_card_flag) \ + + encode_byte(self.first_play_flag) \ + + encode_byte(self.tutorial_complete_flag) \ + + encode_str(self.nick_name) \ + + encode_str(self.personal_id) - resp_data = resp_struct.build(dict( - result=self.result, - unused_card_flag_size=len(self.unused_card_flag) * 2, - unused_card_flag=[ord(x) for x in self.unused_card_flag], - first_play_flag=self.first_play_flag, - tutorial_complete_flag=self.tutorial_complete_flag, - nick_name_size=len(self.nick_name) * 2, - nick_name=[ord(x) for x in self.nick_name], - personal_id_size=len(self.personal_id) * 2, - personal_id=[ord(x) for x in self.personal_id] - )) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoHomeCheckAcLoginBonusRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - -class SaoHomeCheckAcLoginBonusResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) - self.result = 1 - self.reward_get_flag = 1 - self.get_ac_login_bonus_id_list_size = 2 # Array - - self.get_ac_login_bonus_id_1 = 1 # "2020年7月9日~(アニメ&リコリス記念)" - self.get_ac_login_bonus_id_2 = 2 # "2020年10月6日~(秋のデビュー&カムバックCP)" - - def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "reward_get_flag" / Int8ul, # result is either 0 or 1 - "get_ac_login_bonus_id_list_size" / Int32ub, - - "get_ac_login_bonus_id_1" / Int32ub, - "get_ac_login_bonus_id_2" / Int32ub, - ) - - resp_data = resp_struct.build(dict( - result=self.result, - reward_get_flag=self.reward_get_flag, - get_ac_login_bonus_id_list_size=self.get_ac_login_bonus_id_list_size, - - get_ac_login_bonus_id_1=self.get_ac_login_bonus_id_1, - get_ac_login_bonus_id_2=self.get_ac_login_bonus_id_2, - )) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoGetQuestSceneMultiPlayPhotonServerRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - -class SaoGetQuestSceneMultiPlayPhotonServerResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) - self.result = 1 - self.application_id = "7df3a2f6-d69d-4073-aafe-810ee61e1cea" - - def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "application_id_size" / Int32ub, # big endian - "application_id" / Int16ul[len(self.application_id)], - ) - - resp_data = resp_struct.build(dict( - result=self.result, - application_id_size=len(self.application_id) * 2, - application_id=[ord(x) for x in self.application_id], - )) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoTicketRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - -class SaoTicketResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) - self.result = "1" - self.ticket_id = "9" #up to 18 - - def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result_size" / Int32ub, # big endian - "result" / Int16ul[len(self.result)], - "ticket_id_size" / Int32ub, # big endian - "ticket_id" / Int16ul[len(self.result)], - ) - - resp_data = resp_struct.build(dict( - result_size=len(self.result) * 2, - result=[ord(x) for x in self.result], - ticket_id_size=len(self.ticket_id) * 2, - ticket_id=[ord(x) for x in self.ticket_id], - )) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoCommonLoginRequest(SaoBaseRequest): +class SaoGetAccessCodeByKeitaiRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) off = 0 self.cabinet_type = decode_byte(data, off) off += BYTE_OFF - self.auth_type = decode_byte(data, off) + self.auth_type = AuthType(decode_byte(data, off)) # 0 is unknown, 1 is card (banapass, aime, AICC), 2 is moble + off += BYTE_OFF + + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off + + self.chip_id, new_off = decode_str(data, off) + off += new_off + +class SaoGetAccessCodeByKeitaiResponse(SaoBaseResponse): + def __init__(self, access_code: str) -> None: + super().__init__(GameconnectCmd.GET_ACCESS_CODE_BY_KEITAI_RESPONSE) + self.result = 1 + self.access_code = access_code + self.ba_id_flag = 1 + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_str(self.access_code) \ + + encode_byte(self.ba_id_flag) + +class SaoCheckAcLoginBonusResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.CHECK_AC_LOGIN_BONUS_RESPONSE) + self.result = 1 + self.reward_get_flag = 1 + + self.get_ac_login_bonus_id_list: List[int] = [] # "2020年7月9日~(アニメ&リコリス記念)" + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_byte(self.reward_get_flag) \ + + encode_arr_num(self.get_ac_login_bonus_id_list, INT_OFF) \ + +class SaoGetQuestSceneMultiPlayPhotonServerResponse(SaoBaseResponse): + def __init__(self, app_id: str = "7df3a2f6-d69d-4073-aafe-810ee61e1cea") -> None: + super().__init__(GameconnectCmd.GET_QUEST_SCENE_MULTI_PLAY_PHOTON_SERVER_RESPONSE) + self.result = 1 + self.application_id = app_id + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_str(self.application_id) + +class SaoLoginRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + + self.auth_type = AuthType(decode_byte(data, off)) # 0 is unknown, 1 is card (banapass, aime, AICC), 2 is moble off += BYTE_OFF store_id = decode_str(data, off) @@ -392,1107 +371,555 @@ class SaoCommonLoginRequest(SaoBaseRequest): self.free_ticket_distribution_target_flag = decode_byte(data, off) off += BYTE_OFF -class SaoCommonLoginResponse(SaoBaseResponse): - def __init__(self, cmd, profile_data) -> None: - super().__init__(cmd) +class SaoLoginResponse(SaoBaseResponse): + def __init__(self, user_id: int, first_play: bool = False, logged_in_today: bool = True) -> None: + super().__init__(GameconnectCmd.LOGIN_RESPONSE) self.result = 1 - self.user_id = str(profile_data['user']) - self.first_play_flag = 0 - self.grantable_free_ticket_flag = 1 - self.login_reward_vp = 99 - self.today_paying_flag = 1 + self.user_id = str(user_id) + self.first_play_flag = first_play + self.grantable_free_ticket_flag = not logged_in_today + self.login_reward_vp = 0 if logged_in_today else 100 + self.today_paying_flag = logged_in_today def make(self) -> bytes: - # create a resp struct - ''' - bool = Int8ul - short = Int16ub - int = Int32ub - ''' - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "user_id_size" / Int32ub, # big endian - "user_id" / Int16ul[len(self.user_id)], - "first_play_flag" / Int8ul, # result is either 0 or 1 - "grantable_free_ticket_flag" / Int8ul, # result is either 0 or 1 - "login_reward_vp" / Int16ub, - "today_paying_flag" / Int8ul, # result is either 0 or 1 - ) + return super().make() \ + + encode_byte(self.result) \ + + encode_str(self.user_id) \ + + encode_byte(self.first_play_flag) \ + + encode_byte(self.grantable_free_ticket_flag) \ + + encode_short(self.login_reward_vp) \ + + encode_byte(self.today_paying_flag) - resp_data = resp_struct.build(dict( - result=self.result, - user_id_size=len(self.user_id) * 2, - user_id=[ord(x) for x in self.user_id], - first_play_flag=self.first_play_flag, - grantable_free_ticket_flag=self.grantable_free_ticket_flag, - login_reward_vp=self.login_reward_vp, - today_paying_flag=self.today_paying_flag, - )) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoCheckComebackEventRequest(SaoBaseRequest): +class SaoLogoutRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off -class SaoCheckComebackEventRequest(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.cabinet_type = decode_byte(data, off) # 0 satalite, 1 terminal + off += BYTE_OFF + + self.remaining_ticket_num = decode_short(data, off) + off += SHORT_OFF + +class SaoPurchaseTicketRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.discount_type = decode_byte(data, off) + off += BYTE_OFF + self.purchase_num = decode_byte(data, off) + off += BYTE_OFF + +class SaoConsumeTicketRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.discount_type = decode_byte(data, off) + off += BYTE_OFF + self.act_type = ActTypeConsumeTicket(decode_byte(data, off)) + off += BYTE_OFF + self.consume_num = decode_byte(data, off) + off += BYTE_OFF + +class SaoAddCreditRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + self.add_num = decode_byte(data, off) + off += BYTE_OFF + +class SaoConsumeCreditRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + self.act_type = ActTypeConsumeCredit(decode_byte(data, off)) + off += BYTE_OFF + self.consume_num = decode_byte(data, off) + off += BYTE_OFF + +class SaoPurchaseTicketGuestRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off + + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + self.discount_type = decode_byte(data, off) + off += BYTE_OFF + self.purchase_num = decode_byte(data, off) + off += BYTE_OFF + +class SaoConsumeTicketGuestRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off + + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + self.discount_type = decode_byte(data, off) + off += BYTE_OFF + self.act_type = ActTypeConsumeTicket(decode_byte(data, off)) + off += BYTE_OFF + self.consume_num = decode_byte(data, off) + off += BYTE_OFF + +class SaoAddCreditGuestRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off + + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + self.add_num = decode_byte(data, off) + off += BYTE_OFF + +class SaoConsumeCreditGuestRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off + + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + self.act_type = ActTypeConsumeCredit(decode_byte(data, off)) + off += BYTE_OFF + self.consume_num = decode_byte(data, off) + off += BYTE_OFF + +class SaoCheckComebackEventResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.CHECK_COMEBACK_EVENT_RESPONSE) self.result = 1 - self.get_flag_ = 1 - self.get_comeback_event_id_list = "" # Array of events apparently + self.get_flag = 1 + self.get_comeback_event_id_list: List[int] = [] # Array of events apparently def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "get_flag_" / Int8ul, # result is either 0 or 1 - "get_comeback_event_id_list_size" / Int32ub, # big endian - "get_comeback_event_id_list" / Int16ul[len(self.get_comeback_event_id_list)], - ) + return super().make() \ + + encode_byte(self.result) \ + + encode_byte(self.get_flag) \ + + encode_arr_num(self.get_comeback_event_id_list, INT_OFF) - resp_data = resp_struct.build(dict( - result=self.result, - get_flag_=self.get_flag_, - get_comeback_event_id_list_size=len(self.get_comeback_event_id_list) * 2, - get_comeback_event_id_list=[ord(x) for x in self.get_comeback_event_id_list], - )) +class SaoChangeMyStoreRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off - self.length = len(resp_data) - return super().make() + resp_data + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.store_id, new_off = decode_str(data, off) + off += new_off + +class SaoCheckTitleGetDecisionRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_offset = decode_str(data, off) + off += new_offset + + self.user_id, new_offset = decode_str(data, off) + off += new_offset + +class SaoCheckTitleGetDecisionResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.CHECK_TITLE_GET_DECISION_RESPONSE) + self.result = 1 + self.get_title_id_list: List[int] = [] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_num(self.get_title_id_list, INT_OFF) class SaoGetUserBasicDataRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) - self.user_id = decode_str(data, 0)[0] + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off class SaoGetUserBasicDataResponse(SaoBaseResponse): - def __init__(self, cmd, profile_data) -> None: - super().__init__(cmd) + def __init__(self, profile_data) -> None: + super().__init__(GameconnectCmd.GET_USER_BASIC_DATA_RESPONSE) self.result = 1 - self.user_basic_data_size = 1 # Number of arrays - self.user_type = profile_data['user_type'] - self.nick_name = profile_data['nick_name'] - self.rank_num = profile_data['rank_num'] - self.rank_exp = profile_data['rank_exp'] - self.own_col = profile_data['own_col'] - self.own_vp = profile_data['own_vp'] - self.own_yui_medal = profile_data['own_yui_medal'] - self.setting_title_id = profile_data['setting_title_id'] - self.favorite_user_hero_log_id = "" - self.favorite_user_support_log_id = "" - self.my_store_id = "1" - self.my_store_name = "ARTEMiS" - self.user_reg_date = "20230101120000" - + self.user_basic_data: List[UserBasicData] = [UserBasicData.from_args(profile_data)] + def make(self) -> bytes: - # create a resp struct - ''' - bool = Int8ul - short = Int16ub - int = Int32ub - ''' - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "user_basic_data_size" / Int32ub, + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.user_basic_data) - "user_type" / Int16ub, - "nick_name_size" / Int32ub, # big endian - "nick_name" / Int16ul[len(self.nick_name)], - "rank_num" / Int16ub, - "rank_exp" / Int32ub, - "own_col" / Int32ub, - "own_vp" / Int32ub, - "own_yui_medal" / Int32ub, - "setting_title_id" / Int32ub, - "favorite_user_hero_log_id_size" / Int32ub, # big endian - "favorite_user_hero_log_id" / Int16ul[len(str(self.favorite_user_hero_log_id))], - "favorite_user_support_log_id_size" / Int32ub, # big endian - "favorite_user_support_log_id" / Int16ul[len(str(self.favorite_user_support_log_id))], - "my_store_id_size" / Int32ub, # big endian - "my_store_id" / Int16ul[len(str(self.my_store_id))], - "my_store_name_size" / Int32ub, # big endian - "my_store_name" / Int16ul[len(str(self.my_store_name))], - "user_reg_date_size" / Int32ub, # big endian - "user_reg_date" / Int16ul[len(self.user_reg_date)] - - ) - - resp_data = resp_struct.build(dict( - result=self.result, - user_basic_data_size=self.user_basic_data_size, - - user_type=self.user_type, - nick_name_size=len(self.nick_name) * 2, - nick_name=[ord(x) for x in self.nick_name], - rank_num=self.rank_num, - rank_exp=self.rank_exp, - own_col=self.own_col, - own_vp=self.own_vp, - own_yui_medal=self.own_yui_medal, - setting_title_id=self.setting_title_id, - favorite_user_hero_log_id_size=len(self.favorite_user_hero_log_id) * 2, - favorite_user_hero_log_id=[ord(x) for x in str(self.favorite_user_hero_log_id)], - favorite_user_support_log_id_size=len(self.favorite_user_support_log_id) * 2, - favorite_user_support_log_id=[ord(x) for x in str(self.favorite_user_support_log_id)], - my_store_id_size=len(self.my_store_id) * 2, - my_store_id=[ord(x) for x in str(self.my_store_id)], - my_store_name_size=len(self.my_store_name) * 2, - my_store_name=[ord(x) for x in str(self.my_store_name)], - user_reg_date_size=len(self.user_reg_date) * 2, - user_reg_date=[ord(x) for x in self.user_reg_date], - )) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoGetHeroLogUserDataListRequest(SaoBaseRequest): +class SaoGetVpGashaTicketDataListRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) - self.user_id = decode_str(data, 0)[0] + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + +class SaoGetVpGashaTicketDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_VP_GASHA_TICKET_DATA_LIST_RESPONSE) + self.result = 1 + self.vp_gasha_ticket_data_list: List[VpGashaTicketData] = [] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.vp_gasha_ticket_data_list) + +class SaoChangeTitleRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.user_title_id, new_off = decode_str(data, off) + off += new_off + +class SaoGetPresentBoxNumResponse(SaoBaseResponse): + def __init__(self, num_box: int = 0, max_num: int = 0) -> None: + super().__init__(GameconnectCmd.GET_PRESENT_BOX_NUM_RESPONSE) + self.result = 1 + self.num = num_box + self.max_num = max_num + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_short(self.num) \ + + encode_short(self.max_num) class SaoGetHeroLogUserDataListResponse(SaoBaseResponse): - def __init__(self, cmd, hero_data) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_HERO_LOG_USER_DATA_LIST_RESPONSE) self.result = 1 - self.user_hero_log_id = [] - self.log_level = [] - self.max_log_level_extended_num = [] - self.log_exp = [] - self.last_set_skill_slot1_skill_id = [] - self.last_set_skill_slot2_skill_id = [] - self.last_set_skill_slot3_skill_id = [] - self.last_set_skill_slot4_skill_id = [] - self.last_set_skill_slot5_skill_id = [] - - for i in range(len(hero_data)): - - # Calculate level based off experience and the CSV list - with open(r'titles/sao/data/HeroLogLevel.csv') as csv_file: - csv_reader = csv.reader(csv_file, delimiter=',') - line_count = 0 - data = [] - rowf = False - for row in csv_reader: - if rowf==False: - rowf=True - else: - data.append(row) - - exp = hero_data[i][4] - - for e in range(0,len(data)): - if exp>=int(data[e][1]) and exp bytes: - #new stuff - - hero_log_user_data_list_struct = Struct( - "user_hero_log_id_size" / Int32ub, # big endian - "user_hero_log_id" / Int16ul[9], #string - "hero_log_id" / Int32ub, #int - "log_level" / Int16ub, #short - "max_log_level_extended_num" / Int16ub, #short - "log_exp" / Int32ub, #int - "possible_awakening_flag" / Int8ul, # result is either 0 or 1 - "awakening_stage" / Int16ub, #short - "awakening_exp" / Int32ub, #int - "skill_slot_correction_value" / Int8ul, # result is either 0 or 1 - "last_set_skill_slot1_skill_id" / Int16ub, #short - "last_set_skill_slot2_skill_id" / Int16ub, #short - "last_set_skill_slot3_skill_id" / Int16ub, #short - "last_set_skill_slot4_skill_id" / Int16ub, #short - "last_set_skill_slot5_skill_id" / Int16ub, #short - "property1_property_id" / Int32ub, - "property1_value1" / Int32ub, - "property1_value2" / Int32ub, - "property2_property_id" / Int32ub, - "property2_value1" / Int32ub, - "property2_value2" / Int32ub, - "property3_property_id" / Int32ub, - "property3_value1" / Int32ub, - "property3_value2" / Int32ub, - "property4_property_id" / Int32ub, - "property4_value1" / Int32ub, - "property4_value2" / Int32ub, - "converted_card_num" / Int16ub, - "shop_purchase_flag" / Int8ul, # result is either 0 or 1 - "protect_flag" / Int8ul, # result is either 0 or 1 - "get_date_size" / Int32ub, # big endian - "get_date" / Int16ul[len(self.get_date)], - ) - - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "hero_log_user_data_list_size" / Rebuild(Int32ub, len_(this.hero_log_user_data_list)), # big endian - "hero_log_user_data_list" / Array(this.hero_log_user_data_list_size, hero_log_user_data_list_struct), - ) - - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - hero_log_user_data_list_size=0, - hero_log_user_data_list=[], - ))) - - for i in range(len(self.hero_log_id)): - hero_data = dict( - user_hero_log_id_size=len(self.user_hero_log_id[i]) * 2, - user_hero_log_id=[ord(x) for x in self.user_hero_log_id[i]], - hero_log_id=self.hero_log_id[i], - log_level=self.log_level[i], - max_log_level_extended_num=self.max_log_level_extended_num[i], - log_exp=self.log_exp[i], - possible_awakening_flag=self.possible_awakening_flag, - awakening_stage=self.awakening_stage, - awakening_exp=self.awakening_exp, - skill_slot_correction_value=self.skill_slot_correction_value, - last_set_skill_slot1_skill_id=self.last_set_skill_slot1_skill_id[i], - last_set_skill_slot2_skill_id=self.last_set_skill_slot2_skill_id[i], - last_set_skill_slot3_skill_id=self.last_set_skill_slot3_skill_id[i], - last_set_skill_slot4_skill_id=self.last_set_skill_slot4_skill_id[i], - last_set_skill_slot5_skill_id=self.last_set_skill_slot5_skill_id[i], - property1_property_id=self.property1_property_id, - property1_value1=self.property1_value1, - property1_value2=self.property1_value2, - property2_property_id=self.property2_property_id, - property2_value1=self.property2_value1, - property2_value2=self.property2_value2, - property3_property_id=self.property3_property_id, - property3_value1=self.property3_value1, - property3_value2=self.property3_value2, - property4_property_id=self.property4_property_id, - property4_value1=self.property4_value1, - property4_value2=self.property4_value2, - converted_card_num=self.converted_card_num, - shop_purchase_flag=self.shop_purchase_flag, - protect_flag=self.protect_flag, - get_date_size=len(self.get_date) * 2, - get_date=[ord(x) for x in self.get_date], - - ) - - resp_data.hero_log_user_data_list.append(hero_data) - - resp_data["hero_log_user_data_list_size"] = len(resp_data.hero_log_user_data_list) - - # finally, rebuild the resp_data - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoGetEquipmentUserDataListRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - self.user_id = decode_str(data, 0)[0] + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.hero_log_user_data_list) class SaoGetEquipmentUserDataListResponse(SaoBaseResponse): - def __init__(self, cmd, equipment_data) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_EQUIPMENT_USER_DATA_LIST_RESPONSE) self.result = 1 - - self.user_equipment_id = [] - self.enhancement_value = [] - self.max_enhancement_value_extended_num = [] - self.enhancement_exp = [] - self.awakening_stage = [] - self.awakening_exp = [] - self.possible_awakening_flag = [] - equipment_level = 0 - - for i in range(len(equipment_data)): - - # Calculate level based off experience and the CSV list - with open(r'titles/sao/data/EquipmentLevel.csv') as csv_file: - csv_reader = csv.reader(csv_file, delimiter=',') - line_count = 0 - data = [] - rowf = False - for row in csv_reader: - if rowf==False: - rowf=True - else: - data.append(row) - - exp = equipment_data[i][4] - - for e in range(0,len(data)): - if exp>=int(data[e][1]) and exp bytes: - - equipment_user_data_list_struct = Struct( - "user_equipment_id_size" / Int32ub, # big endian - "user_equipment_id" / Int16ul[9], #string - "equipment_id" / Int32ub, #int - "enhancement_value" / Int16ub, #short - "max_enhancement_value_extended_num" / Int16ub, #short - "enhancement_exp" / Int32ub, #int - "possible_awakening_flag" / Int8ul, # result is either 0 or 1 - "awakening_stage" / Int16ub, #short - "awakening_exp" / Int32ub, #int - "property1_property_id" / Int32ub, - "property1_value1" / Int32ub, - "property1_value2" / Int32ub, - "property2_property_id" / Int32ub, - "property2_value1" / Int32ub, - "property2_value2" / Int32ub, - "property3_property_id" / Int32ub, - "property3_value1" / Int32ub, - "property3_value2" / Int32ub, - "property4_property_id" / Int32ub, - "property4_value1" / Int32ub, - "property4_value2" / Int32ub, - "converted_card_num" / Int16ub, - "shop_purchase_flag" / Int8ul, # result is either 0 or 1 - "protect_flag" / Int8ul, # result is either 0 or 1 - "get_date_size" / Int32ub, # big endian - "get_date" / Int16ul[len(self.get_date)], - ) - - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "equipment_user_data_list_size" / Rebuild(Int32ub, len_(this.equipment_user_data_list)), # big endian - "equipment_user_data_list" / Array(this.equipment_user_data_list_size, equipment_user_data_list_struct), - ) - - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - equipment_user_data_list_size=0, - equipment_user_data_list=[], - ))) - - for i in range(len(self.equipment_id)): - equipment_data = dict( - user_equipment_id_size=len(self.user_equipment_id[i]) * 2, - user_equipment_id=[ord(x) for x in self.user_equipment_id[i]], - equipment_id=self.equipment_id[i], - enhancement_value=self.enhancement_value[i], - max_enhancement_value_extended_num=self.max_enhancement_value_extended_num[i], - enhancement_exp=self.enhancement_exp[i], - possible_awakening_flag=self.possible_awakening_flag[i], - awakening_stage=self.awakening_stage[i], - awakening_exp=self.awakening_exp[i], - property1_property_id=self.property1_property_id, - property1_value1=self.property1_value1, - property1_value2=self.property1_value2, - property2_property_id=self.property2_property_id, - property2_value1=self.property2_value1, - property2_value2=self.property2_value2, - property3_property_id=self.property3_property_id, - property3_value1=self.property3_value1, - property3_value2=self.property3_value2, - property4_property_id=self.property4_property_id, - property4_value1=self.property4_value1, - property4_value2=self.property4_value2, - converted_card_num=self.converted_card_num, - shop_purchase_flag=self.shop_purchase_flag, - protect_flag=self.protect_flag, - get_date_size=len(self.get_date) * 2, - get_date=[ord(x) for x in self.get_date], - - ) - - resp_data.equipment_user_data_list.append(equipment_data) - - resp_data["equipment_user_data_list_size"] = len(resp_data.equipment_user_data_list) - - # finally, rebuild the resp_data - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoGetItemUserDataListRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - self.user_id = decode_str(data, 0)[0] + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.equipment_user_data_list) class SaoGetItemUserDataListResponse(SaoBaseResponse): - def __init__(self, cmd, item_data) -> None: - super().__init__(cmd) + def __init__(self, item_data: List[Dict] = []) -> None: + super().__init__(GameconnectCmd.GET_ITEM_USER_DATA_LIST_RESPONSE) self.result = 1 + self.item_user_data_list: List[ItemUserData] = [] - self.user_item_id = [] - - for i in range(len(item_data)): - self.user_item_id.append(item_data[i][2]) - - # item_user_data_list - self.user_item_id = list(map(str,self.user_item_id)) #str - self.item_id = list(map(int,self.user_item_id)) #int - self.protect_flag = 0 #byte - self.get_date = "20230101120000" #str + if item_data: + for item in item_data: + self.item_user_data_list.append(ItemUserData.from_args(item)) def make(self) -> bytes: - #new stuff - - item_user_data_list_struct = Struct( - "user_item_id_size" / Int32ub, # big endian - "user_item_id" / Int16ul[6], #string but this will not work with 10000 IDs... only with 6 digits - "item_id" / Int32ub, #int - "protect_flag" / Int8ul, # result is either 0 or 1 - "get_date_size" / Int32ub, # big endian - "get_date" / Int16ul[len(self.get_date)], - ) - - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "item_user_data_list_size" / Rebuild(Int32ub, len_(this.item_user_data_list)), # big endian - "item_user_data_list" / Array(this.item_user_data_list_size, item_user_data_list_struct), - ) - - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - item_user_data_list_size=0, - item_user_data_list=[], - ))) - - for i in range(len(self.item_id)): - item_data = dict( - user_item_id_size=len(self.user_item_id[i]) * 2, - user_item_id=[ord(x) for x in self.user_item_id[i]], - item_id=self.item_id[i], - protect_flag=self.protect_flag, - get_date_size=len(self.get_date) * 2, - get_date=[ord(x) for x in self.get_date], - - ) - - resp_data.item_user_data_list.append(item_data) - - resp_data["item_user_data_list_size"] = len(resp_data.item_user_data_list) - - # finally, rebuild the resp_data - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoGetSupportLogUserDataListRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.item_user_data_list) class SaoGetSupportLogUserDataListResponse(SaoBaseResponse): - def __init__(self, cmd, supportIdsData) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_SUPPORT_LOG_USER_DATA_LIST_RESPONSE) self.result = 1 + self.support_log_user_data_list: List[SupportLogUserData] = [] - # support_log_user_data_list - self.user_support_log_id = list(map(str,supportIdsData)) #str - self.support_log_id = supportIdsData #int - self.possible_awakening_flag = 0 - self.awakening_stage = 0 - self.awakening_exp = 0 - self.converted_card_num = 0 - self.shop_purchase_flag = 0 - self.protect_flag = 0 #byte - self.get_date = "20230101120000" #str - def make(self) -> bytes: - support_log_user_data_list_struct = Struct( - "user_support_log_id_size" / Int32ub, # big endian - "user_support_log_id" / Int16ul[9], - "support_log_id" / Int32ub, #int - "possible_awakening_flag" / Int8ul, # result is either 0 or 1 - "awakening_stage" / Int16ub, #short - "awakening_exp" / Int32ub, # int - "converted_card_num" / Int16ub, #short - "shop_purchase_flag" / Int8ul, # result is either 0 or 1 - "protect_flag" / Int8ul, # result is either 0 or 1 - "get_date_size" / Int32ub, # big endian - "get_date" / Int16ul[len(self.get_date)], - ) - - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "support_log_user_data_list_size" / Rebuild(Int32ub, len_(this.support_log_user_data_list)), # big endian - "support_log_user_data_list" / Array(this.support_log_user_data_list_size, support_log_user_data_list_struct), - ) - - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - support_log_user_data_list_size=0, - support_log_user_data_list=[], - ))) - - for i in range(len(self.support_log_id)): - support_data = dict( - user_support_log_id_size=len(self.user_support_log_id[i]) * 2, - user_support_log_id=[ord(x) for x in self.user_support_log_id[i]], - support_log_id=self.support_log_id[i], - possible_awakening_flag=self.possible_awakening_flag, - awakening_stage=self.awakening_stage, - awakening_exp=self.awakening_exp, - converted_card_num=self.converted_card_num, - shop_purchase_flag=self.shop_purchase_flag, - protect_flag=self.protect_flag, - get_date_size=len(self.get_date) * 2, - get_date=[ord(x) for x in self.get_date], - - ) - - resp_data.support_log_user_data_list.append(support_data) - - resp_data["support_log_user_data_list_size"] = len(resp_data.support_log_user_data_list) - - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoGetTitleUserDataListRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.support_log_user_data_list) class SaoGetTitleUserDataListResponse(SaoBaseResponse): - def __init__(self, cmd, titleIdsData) -> None: - super().__init__(cmd) + def __init__(self, user_id: str, titles: List[int]) -> None: + super().__init__(GameconnectCmd.GET_TITLE_USER_DATA_LIST_RESPONSE) self.result = 1 + self.title_user_data_list: List[TitleUserData] = [] + + if titles: + for x in titles: + self.title_user_data_list.append(TitleUserData.from_args(user_id + str(x), x)) - # title_user_data_list - self.user_title_id = list(map(str,titleIdsData)) #str - self.title_id = titleIdsData #int - def make(self) -> bytes: - title_user_data_list_struct = Struct( - "user_title_id_size" / Int32ub, # big endian - "user_title_id" / Int16ul[6], #string - "title_id" / Int32ub, #int - ) - - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "title_user_data_list_size" / Rebuild(Int32ub, len_(this.title_user_data_list)), # big endian - "title_user_data_list" / Array(this.title_user_data_list_size, title_user_data_list_struct), - ) - - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - title_user_data_list_size=0, - title_user_data_list=[], - ))) - - for i in range(len(self.title_id)): - title_data = dict( - user_title_id_size=len(self.user_title_id[i]) * 2, - user_title_id=[ord(x) for x in self.user_title_id[i]], - title_id=self.title_id[i], - ) - - resp_data.title_user_data_list.append(title_data) - - resp_data["title_user_data_list_size"] = len(resp_data.title_user_data_list) - - # finally, rebuild the resp_data - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoGetEpisodeAppendDataListRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - self.user_id = decode_str(data, 0)[0] + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.title_user_data_list) class SaoGetEpisodeAppendDataListResponse(SaoBaseResponse): - def __init__(self, cmd, profile_data) -> None: - super().__init__(cmd) - self.length = None + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_EPISODE_APPEND_DATA_LIST_RESPONSE) self.result = 1 - - self.user_episode_append_id_list = ["10001", "10002", "10003", "10004", "10005"] - self.user_id_list = [str(profile_data["user"]), str(profile_data["user"]), str(profile_data["user"]), str(profile_data["user"]), str(profile_data["user"])] - self.episode_append_id_list = [10001, 10002, 10003, 10004, 10005] - self.own_num_list = [3, 3, 3, 3 ,3] + self.episode_append_data_list: List[EpisodeAppendUserData] = [] def make(self) -> bytes: - episode_data_struct = Struct( - "user_episode_append_id_size" / Rebuild(Int32ub, len_(this.user_episode_append_id) * 2), # calculates the length of the user_episode_append_id - "user_episode_append_id" / PaddedString(this.user_episode_append_id_size, "utf_16_le"), # user_episode_append_id is a (zero) padded string - "user_id_size" / Rebuild(Int32ub, len_(this.user_id) * 2), # calculates the length of the user_id - "user_id" / PaddedString(this.user_id_size, "utf_16_le"), # user_id is a (zero) padded string - "episode_append_id" / Int32ub, - "own_num" / Int32ub, - ) + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.episode_append_data_list) - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "episode_append_data_list_size" / Rebuild(Int32ub, len_(this.episode_append_data_list)), # big endian - "episode_append_data_list" / Array(this.episode_append_data_list_size, episode_data_struct), - ) - - # really dump to parse the build resp, but that creates a new object - # and is nicer to twork with - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - episode_append_data_list_size=0, - episode_append_data_list=[], - ))) - - if len(self.user_episode_append_id_list) != len(self.user_id_list) != len(self.episode_append_id_list) != len(self.own_num_list): - raise ValueError("all lists must be of the same length") - - for i in range(len(self.user_id_list)): - # add the episode_data_struct to the resp_struct.episode_append_data_list - resp_data.episode_append_data_list.append(dict( - user_episode_append_id=self.user_episode_append_id_list[i], - user_id=self.user_id_list[i], - episode_append_id=self.episode_append_id_list[i], - own_num=self.own_num_list[i], - )) - - resp_data["episode_append_data_list_size"] = len(resp_data.episode_append_data_list) - - # finally, rebuild the resp_data - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoGetPartyDataListRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - self.user_id = decode_str(data, 0)[0] - -class SaoGetPartyDataListResponse(SaoBaseResponse): # Default party - def __init__(self, cmd, hero1_data, hero2_data, hero3_data) -> None: - super().__init__(cmd) - +class SaoGetEventItemDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_EVENT_ITEM_DATA_LIST_RESPONSE) self.result = 1 - self.party_data_list_size = 1 # Number of arrays - - self.user_party_id = "0" - self.team_no = 0 - self.party_team_data_list_size = 3 # Number of arrays - - self.user_party_team_id_1 = "0" - self.arrangement_num_1 = 0 - self.user_hero_log_id_1 = str(hero1_data[2]) - self.main_weapon_user_equipment_id_1 = str(hero1_data[5]) - self.sub_equipment_user_equipment_id_1 = str(hero1_data[6]) - self.skill_slot1_skill_id_1 = hero1_data[7] - self.skill_slot2_skill_id_1 = hero1_data[8] - self.skill_slot3_skill_id_1 = hero1_data[9] - self.skill_slot4_skill_id_1 = hero1_data[10] - self.skill_slot5_skill_id_1 = hero1_data[11] - - self.user_party_team_id_2 = "0" - self.arrangement_num_2 = 0 - self.user_hero_log_id_2 = str(hero2_data[2]) - self.main_weapon_user_equipment_id_2 = str(hero2_data[5]) - self.sub_equipment_user_equipment_id_2 = str(hero2_data[6]) - self.skill_slot1_skill_id_2 = hero2_data[7] - self.skill_slot2_skill_id_2 = hero2_data[8] - self.skill_slot3_skill_id_2 = hero2_data[9] - self.skill_slot4_skill_id_2 = hero2_data[10] - self.skill_slot5_skill_id_2 = hero2_data[11] - - self.user_party_team_id_3 = "0" - self.arrangement_num_3 = 0 - self.user_hero_log_id_3 = str(hero3_data[2]) - self.main_weapon_user_equipment_id_3 = str(hero3_data[5]) - self.sub_equipment_user_equipment_id_3 = str(hero3_data[6]) - self.skill_slot1_skill_id_3 = hero3_data[7] - self.skill_slot2_skill_id_3 = hero3_data[8] - self.skill_slot3_skill_id_3 = hero3_data[9] - self.skill_slot4_skill_id_3 = hero3_data[10] - self.skill_slot5_skill_id_3 = hero3_data[11] + self.event_item_data_list: List[EventItemUserData] = [] def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "party_data_list_size" / Int32ub, # big endian + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.event_item_data_list) - "user_party_id_size" / Int32ub, # big endian - "user_party_id" / Int16ul[len(self.user_party_id)], - "team_no" / Int8ul, # result is either 0 or 1 - "party_team_data_list_size" / Int32ub, # big endian - - "user_party_team_id_1_size" / Int32ub, # big endian - "user_party_team_id_1" / Int16ul[len(self.user_party_team_id_1)], - "arrangement_num_1" / Int8ul, # big endian - "user_hero_log_id_1_size" / Int32ub, # big endian - "user_hero_log_id_1" / Int16ul[len(self.user_hero_log_id_1)], - "main_weapon_user_equipment_id_1_size" / Int32ub, # big endian - "main_weapon_user_equipment_id_1" / Int16ul[len(self.main_weapon_user_equipment_id_1)], - "sub_equipment_user_equipment_id_1_size" / Int32ub, # big endian - "sub_equipment_user_equipment_id_1" / Int16ul[len(self.sub_equipment_user_equipment_id_1)], - "skill_slot1_skill_id_1" / Int32ub, - "skill_slot2_skill_id_1" / Int32ub, - "skill_slot3_skill_id_1" / Int32ub, - "skill_slot4_skill_id_1" / Int32ub, - "skill_slot5_skill_id_1" / Int32ub, - - "user_party_team_id_2_size" / Int32ub, # big endian - "user_party_team_id_2" / Int16ul[len(self.user_party_team_id_2)], - "arrangement_num_2" / Int8ul, # result is either 0 or 1 - "user_hero_log_id_2_size" / Int32ub, # big endian - "user_hero_log_id_2" / Int16ul[len(self.user_hero_log_id_2)], - "main_weapon_user_equipment_id_2_size" / Int32ub, # big endian - "main_weapon_user_equipment_id_2" / Int16ul[len(self.main_weapon_user_equipment_id_2)], - "sub_equipment_user_equipment_id_2_size" / Int32ub, # big endian - "sub_equipment_user_equipment_id_2" / Int16ul[len(self.sub_equipment_user_equipment_id_2)], - "skill_slot1_skill_id_2" / Int32ub, - "skill_slot2_skill_id_2" / Int32ub, - "skill_slot3_skill_id_2" / Int32ub, - "skill_slot4_skill_id_2" / Int32ub, - "skill_slot5_skill_id_2" / Int32ub, - - "user_party_team_id_3_size" / Int32ub, # big endian - "user_party_team_id_3" / Int16ul[len(self.user_party_team_id_3)], - "arrangement_num_3" / Int8ul, # result is either 0 or 1 - "user_hero_log_id_3_size" / Int32ub, # big endian - "user_hero_log_id_3" / Int16ul[len(self.user_hero_log_id_3)], - "main_weapon_user_equipment_id_3_size" / Int32ub, # big endian - "main_weapon_user_equipment_id_3" / Int16ul[len(self.main_weapon_user_equipment_id_3)], - "sub_equipment_user_equipment_id_3_size" / Int32ub, # big endian - "sub_equipment_user_equipment_id_3" / Int16ul[len(self.sub_equipment_user_equipment_id_3)], - "skill_slot1_skill_id_3" / Int32ub, - "skill_slot2_skill_id_3" / Int32ub, - "skill_slot3_skill_id_3" / Int32ub, - "skill_slot4_skill_id_3" / Int32ub, - "skill_slot5_skill_id_3" / Int32ub, - - ) - - resp_data = resp_struct.build(dict( - result=self.result, - party_data_list_size=self.party_data_list_size, - - user_party_id_size=len(self.user_party_id) * 2, - user_party_id=[ord(x) for x in self.user_party_id], - team_no=self.team_no, - party_team_data_list_size=self.party_team_data_list_size, - - user_party_team_id_1_size=len(self.user_party_team_id_1) * 2, - user_party_team_id_1=[ord(x) for x in self.user_party_team_id_1], - arrangement_num_1=self.arrangement_num_1, - user_hero_log_id_1_size=len(self.user_hero_log_id_1) * 2, - user_hero_log_id_1=[ord(x) for x in self.user_hero_log_id_1], - main_weapon_user_equipment_id_1_size=len(self.main_weapon_user_equipment_id_1) * 2, - main_weapon_user_equipment_id_1=[ord(x) for x in self.main_weapon_user_equipment_id_1], - sub_equipment_user_equipment_id_1_size=len(self.sub_equipment_user_equipment_id_1) * 2, - sub_equipment_user_equipment_id_1=[ord(x) for x in self.sub_equipment_user_equipment_id_1], - skill_slot1_skill_id_1=self.skill_slot1_skill_id_1, - skill_slot2_skill_id_1=self.skill_slot2_skill_id_1, - skill_slot3_skill_id_1=self.skill_slot3_skill_id_1, - skill_slot4_skill_id_1=self.skill_slot4_skill_id_1, - skill_slot5_skill_id_1=self.skill_slot5_skill_id_1, - - user_party_team_id_2_size=len(self.user_party_team_id_2) * 2, - user_party_team_id_2=[ord(x) for x in self.user_party_team_id_2], - arrangement_num_2=self.arrangement_num_2, - user_hero_log_id_2_size=len(self.user_hero_log_id_2) * 2, - user_hero_log_id_2=[ord(x) for x in self.user_hero_log_id_2], - main_weapon_user_equipment_id_2_size=len(self.main_weapon_user_equipment_id_2) * 2, - main_weapon_user_equipment_id_2=[ord(x) for x in self.main_weapon_user_equipment_id_2], - sub_equipment_user_equipment_id_2_size=len(self.sub_equipment_user_equipment_id_2) * 2, - sub_equipment_user_equipment_id_2=[ord(x) for x in self.sub_equipment_user_equipment_id_2], - skill_slot1_skill_id_2=self.skill_slot1_skill_id_2, - skill_slot2_skill_id_2=self.skill_slot2_skill_id_2, - skill_slot3_skill_id_2=self.skill_slot3_skill_id_2, - skill_slot4_skill_id_2=self.skill_slot4_skill_id_2, - skill_slot5_skill_id_2=self.skill_slot5_skill_id_2, - - user_party_team_id_3_size=len(self.user_party_team_id_3) * 2, - user_party_team_id_3=[ord(x) for x in self.user_party_team_id_3], - arrangement_num_3=self.arrangement_num_3, - user_hero_log_id_3_size=len(self.user_hero_log_id_3) * 2, - user_hero_log_id_3=[ord(x) for x in self.user_hero_log_id_3], - main_weapon_user_equipment_id_3_size=len(self.main_weapon_user_equipment_id_3) * 2, - main_weapon_user_equipment_id_3=[ord(x) for x in self.main_weapon_user_equipment_id_3], - sub_equipment_user_equipment_id_3_size=len(self.sub_equipment_user_equipment_id_3) * 2, - sub_equipment_user_equipment_id_3=[ord(x) for x in self.sub_equipment_user_equipment_id_3], - skill_slot1_skill_id_3=self.skill_slot1_skill_id_3, - skill_slot2_skill_id_3=self.skill_slot2_skill_id_3, - skill_slot3_skill_id_3=self.skill_slot3_skill_id_3, - skill_slot4_skill_id_3=self.skill_slot4_skill_id_3, - skill_slot5_skill_id_3=self.skill_slot5_skill_id_3, - )) - - self.length = len(resp_data) - return super().make() + resp_data +class SaoGetGashaMedalUserDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_GASHA_MEDAL_USER_DATA_LIST_RESPONSE) + self.result = 1 + self.data_list: List[GashaMedalUserData] = [] -class SaoGetQuestScenePrevScanProfileCardRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetPartyDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_PARTY_DATA_LIST_RESPONSE) + self.result = 1 + self.party_data_list: List[PartyData] = [] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.party_data_list) + +class SaoGetSupportLogPartyDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_SUPPORT_LOG_PARTY_DATA_LIST_RESPONSE) + self.result = 1 + self.support_log_party_data_list: List[SupportLogPartyData] = [] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.support_log_party_data_list) class SaoGetQuestScenePrevScanProfileCardResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_QUEST_SCENE_PREV_SCAN_PROFILE_CARD_RESPONSE) self.result = 1 - self.profile_card_data = 1 # number of arrays - - self.profile_card_code = "" - self.nick_name = "" - + self.profile_card_data: List[ReadProfileCardData] = [] + def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "profile_card_data" / Int32ub, # big endian - - "profile_card_code_size" / Int32ub, # big endian - "profile_card_code" / Int16ul[len(self.profile_card_code)], - "nick_name_size" / Int32ub, # big endian - "nick_name" / Int16ul[len(self.nick_name)], - "rank_num" / Int16ub, #short - "setting_title_id" / Int32ub, # int - "skill_id" / Int16ub, # short - "hero_log_hero_log_id" / Int32ub, # int - "hero_log_log_level" / Int16ub, # short - "hero_log_awakening_stage" / Int16ub, # short - "hero_log_property1_property_id" / Int32ub, # int - "hero_log_property1_value1" / Int32ub, # int - "hero_log_property1_value2" / Int32ub, # int - "hero_log_property2_property_id" / Int32ub, # int - "hero_log_property2_value1" / Int32ub, # int - "hero_log_property2_value2" / Int32ub, # int - "hero_log_property3_property_id" / Int32ub, # int - "hero_log_property3_value1" / Int32ub, # int - "hero_log_property3_value2" / Int32ub, # int - "hero_log_property4_property_id" / Int32ub, # int - "hero_log_property4_value1" / Int32ub, # int - "hero_log_property4_value2" / Int32ub, # int - "main_weapon_equipment_id" / Int32ub, # int - "main_weapon_enhancement_value" / Int16ub, # short - "main_weapon_awakening_stage" / Int16ub, # short - "main_weapon_property1_property_id" / Int32ub, # int - "main_weapon_property1_value1" / Int32ub, # int - "main_weapon_property1_value2" / Int32ub, # int - "main_weapon_property2_property_id" / Int32ub, # int - "main_weapon_property2_value1" / Int32ub, # int - "main_weapon_property2_value2" / Int32ub, # int - "main_weapon_property3_property_id" / Int32ub, # int - "main_weapon_property3_value1" / Int32ub, # int - "main_weapon_property3_value2" / Int32ub, # int - "main_weapon_property4_property_id" / Int32ub, # int - "main_weapon_property4_value1" / Int32ub, # int - "main_weapon_property4_value2" / Int32ub, # int - "sub_equipment_equipment_id" / Int32ub, # int - "sub_equipment_enhancement_value" / Int16ub, # short - "sub_equipment_awakening_stage" / Int16ub, # short - "sub_equipment_property1_property_id" / Int32ub, # int - "sub_equipment_property1_value1" / Int32ub, # int - "sub_equipment_property1_value2" / Int32ub, # int - "sub_equipment_property2_property_id" / Int32ub, # int - "sub_equipment_property2_value1" / Int32ub, # int - "sub_equipment_property2_value2" / Int32ub, # int - "sub_equipment_property3_property_id" / Int32ub, # int - "sub_equipment_property3_value1" / Int32ub, # int - "sub_equipment_property3_value2" / Int32ub, # int - "sub_equipment_property4_property_id" / Int32ub, # int - "sub_equipment_property4_value1" / Int32ub, # int - "sub_equipment_property4_value2" / Int32ub, # int - "holographic_flag" / Int8ul, # result is either 0 or 1 - ) - - resp_data = resp_struct.build(dict( - result=self.result, - profile_card_data=self.profile_card_data, - - profile_card_code_size=len(self.profile_card_code) * 2, - profile_card_code=[ord(x) for x in self.profile_card_code], - nick_name_size=len(self.nick_name) * 2, - nick_name=[ord(x) for x in self.nick_name], - rank_num=0, - setting_title_id=0, - skill_id=0, - hero_log_hero_log_id=0, - hero_log_log_level=0, - hero_log_awakening_stage=0, - hero_log_property1_property_id=0, - hero_log_property1_value1=0, - hero_log_property1_value2=0, - hero_log_property2_property_id=0, - hero_log_property2_value1=0, - hero_log_property2_value2=0, - hero_log_property3_property_id=0, - hero_log_property3_value1=0, - hero_log_property3_value2=0, - hero_log_property4_property_id=0, - hero_log_property4_value1=0, - hero_log_property4_value2=0, - main_weapon_equipment_id=0, - main_weapon_enhancement_value=0, - main_weapon_awakening_stage=0, - main_weapon_property1_property_id=0, - main_weapon_property1_value1=0, - main_weapon_property1_value2=0, - main_weapon_property2_property_id=0, - main_weapon_property2_value1=0, - main_weapon_property2_value2=0, - main_weapon_property3_property_id=0, - main_weapon_property3_value1=0, - main_weapon_property3_value2=0, - main_weapon_property4_property_id=0, - main_weapon_property4_value1=0, - main_weapon_property4_value2=0, - sub_equipment_equipment_id=0, - sub_equipment_enhancement_value=0, - sub_equipment_awakening_stage=0, - sub_equipment_property1_property_id=0, - sub_equipment_property1_value1=0, - sub_equipment_property1_value2=0, - sub_equipment_property2_property_id=0, - sub_equipment_property2_value1=0, - sub_equipment_property2_value2=0, - sub_equipment_property3_property_id=0, - sub_equipment_property3_value1=0, - sub_equipment_property3_value2=0, - sub_equipment_property4_property_id=0, - sub_equipment_property4_value1=0, - sub_equipment_property4_value2=0, - holographic_flag=0, - - )) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoGetResourcePathInfoRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.profile_card_data) class SaoGetResourcePathInfoResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self, base_url: str) -> None: + super().__init__(GameconnectCmd.GET_RESOURCE_PATH_INFO_RESPONSE) self.result = 1 - self.resource_base_url = "http://localhost:9000/SDEW/100/" - self.gasha_base_dir = "a" - self.ad_base_dir = "b" - self.event_base_dir = "c" + self.resource_base_url = base_url + self.gasha_base_dir = "gasha" + self.ad_base_dir = "ad" + self.event_base_dir = "event" def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "resource_base_url_size" / Int32ub, # big endian - "resource_base_url" / Int16ul[len(self.resource_base_url)], - "gasha_base_dir_size" / Int32ub, # big endian - "gasha_base_dir" / Int16ul[len(self.gasha_base_dir)], - "ad_base_dir_size" / Int32ub, # big endian - "ad_base_dir" / Int16ul[len(self.ad_base_dir)], - "event_base_dir_size" / Int32ub, # big endian - "event_base_dir" / Int16ul[len(self.event_base_dir)], - ) + return super().make() \ + + encode_byte(self.result) \ + + encode_str(self.resource_base_url) \ + + encode_str(self.gasha_base_dir) \ + + encode_str(self.ad_base_dir) \ + + encode_str(self.event_base_dir) - resp_data = resp_struct.build(dict( - result=self.result, - resource_base_url_size=len(self.resource_base_url) * 2, - resource_base_url=[ord(x) for x in self.resource_base_url], - gasha_base_dir_size=len(self.gasha_base_dir) * 2, - gasha_base_dir=[ord(x) for x in self.gasha_base_dir], - ad_base_dir_size=len(self.ad_base_dir) * 2, - ad_base_dir=[ord(x) for x in self.ad_base_dir], - event_base_dir_size=len(self.event_base_dir) * 2, - event_base_dir=[ord(x) for x in self.event_base_dir], - )) +class SaoValidationErrorNotificationRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off - self.length = len(resp_data) - return super().make() + resp_data + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + + self.net_id, new_off = decode_str(data, off) + off += new_off + + self.place_id, new_off = decode_str(data, off) + off += new_off + + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.store_name, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off + + self.send_protocol_name, new_off = decode_str(data, off) + off += new_off + + self.send_data_to_fraud_value, new_off = decode_str(data, off) + off += new_off + + self.send_data_to_modification_value, new_off = decode_str(data, off) + off += new_off + +class SaoGetBeginnerMissionUserDataRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.beginner_mission_id = decode_int(data, off) + off += INT_OFF + +class SaoGetBeginnerMissionUserDataResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_BEGINNER_MISSION_USER_DATA_RESPONSE) + self.result = 1 + self.data: List[BeginnerMissionUserData] = [BeginnerMissionUserData.from_args(datetime.now())] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data) + +class SaoMatchingErrorNotificationRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + + self.net_id, new_off = decode_str(data, off) + off += new_off + + self.place_id, new_off = decode_str(data, off) + off += new_off + + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.store_name, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off + + self.matching_error_data_list: List[MatchingErrorData] + self.matching_error_data_list, new_off = decode_arr_cls(data, off, MatchingErrorData) + +class SaoPowerCuttingReturnNotification(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.cabinet_type = decode_byte(data, off) + off += BYTE_OFF + + self.net_id, new_off = decode_str(data, off) + off += new_off + + self.place_id, new_off = decode_str(data, off) + off += new_off + + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.store_name, new_off = decode_str(data, off) + off += new_off + + self.serial_no, new_off = decode_str(data, off) + off += new_off + + self.last_act_type = decode_byte(data, off) + off += BYTE_OFF + + self.remaining_ticket_num = decode_short(data, off) + off += SHORT_OFF + + self.remaining_credit_num = decode_short(data, off) + off += SHORT_OFF class SaoEpisodePlayStartRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) off = 0 - ticket_id = decode_str(data, off) - self.ticket_id = ticket_id[0] - off += ticket_id[1] + self.ticket_id, new_off = decode_str(data, off) + off += new_off - user_id = decode_str(data, off) - self.user_id = user_id[0] - off += user_id[1] + self.user_id, new_off = decode_str(data, off) + off += new_off self.episode_id = decode_int(data, off) off += INT_OFF @@ -1500,183 +927,60 @@ class SaoEpisodePlayStartRequest(SaoBaseRequest): self.play_mode = decode_byte(data, off) off += BYTE_OFF - self.play_start_request_data_count = decode_int(data, off) - off += INT_OFF + self.play_start_request_data: List[QuestScenePlayStartRequestData] = [] + self.play_start_request_data, new_off = decode_arr_cls(data, off, QuestScenePlayStartRequestData) + off += new_off - self.play_start_request_data: List[PlayStartRequestData] = [] - for _ in range(self.play_start_request_data_count): - tmp = PlayStartRequestData(data, off) - self.play_start_request_data.append(tmp) - off += tmp.get_size() - - self.multi_play_start_request_data_count = decode_int(data, off) - off += INT_OFF - - self.multi_play_start_request_data: List[MultiPlayStartRequestData] = [] - for _ in range(self.multi_play_start_request_data_count): - tmp = MultiPlayStartRequestData(data, off) - off += tmp.get_size() - self.multi_play_start_request_data.append(tmp) + self.multi_play_start_request_data: List[QuestSceneMultiPlayStartRequestData] = [] + self.multi_play_start_request_data, new_off = decode_arr_cls(data, off, QuestSceneMultiPlayStartRequestData) + off += new_off class SaoEpisodePlayStartResponse(SaoBaseResponse): - def __init__(self, cmd, profile_data) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.EPISODE_PLAY_START_RESPONSE) self.result = 1 - self.play_start_response_data_size = 1 # Number of arrays (minimum 1 mandatory) - self.multi_play_start_response_data_size = 0 # Number of arrays (set 0 due to single play) + self.play_start_response_data: List[QuestScenePlayStartResponseData] = [] + self.multi_play_start_response_data: List[QuestSceneMultiPlayStartResponseData] = [] - self.appearance_player_trace_data_list_size = 1 - - self.user_quest_scene_player_trace_id = "1003" - self.nick_name = profile_data["nick_name"] - def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "play_start_response_data_size" / Int32ub, - "multi_play_start_response_data_size" / Int32ub, - - "appearance_player_trace_data_list_size" / Int32ub, - - "user_quest_scene_player_trace_id_size" / Int32ub, # big endian - "user_quest_scene_player_trace_id" / Int16ul[len(self.user_quest_scene_player_trace_id)], - "nick_name_size" / Int32ub, # big endian - "nick_name" / Int16ul[len(self.nick_name)], - ) - - resp_data = resp_struct.build(dict( - result=self.result, - play_start_response_data_size=self.play_start_response_data_size, - multi_play_start_response_data_size=self.multi_play_start_response_data_size, - - appearance_player_trace_data_list_size=self.appearance_player_trace_data_list_size, - - user_quest_scene_player_trace_id_size=len(self.user_quest_scene_player_trace_id) * 2, - user_quest_scene_player_trace_id=[ord(x) for x in self.user_quest_scene_player_trace_id], - nick_name_size=len(self.nick_name) * 2, - nick_name=[ord(x) for x in self.nick_name], - )) - - self.length = len(resp_data) - return super().make() + resp_data + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.play_start_response_data) \ + + encode_arr_cls(self.multi_play_start_response_data) class SaoEpisodePlayEndRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) off = 0 - ticket_id = decode_str(data, off) - self.ticket_id = ticket_id[0] - off += ticket_id[1] + self.ticket_id, new_off = decode_str(data, off) + off += new_off - user_id = decode_str(data, off) - self.user_id = user_id[0] - off += user_id[1] + self.user_id, new_off = decode_str(data, off) + off += new_off self.episode_id = decode_int(data, off) off += INT_OFF - self.play_end_request_data_count = decode_int(data, off) - off += INT_OFF + self.play_end_request_data: List[QuestScenePlayEndRequestData] = [] + self.play_end_request_data, new_off = decode_arr_cls(data, off, QuestScenePlayEndRequestData) + off += new_off - self.play_end_request_data_list: List[PlayEndRequestData] = [] - for _ in range(self.play_end_request_data_count): - tmp = PlayEndRequestData(data, off) - off += tmp.get_size() - self.play_end_request_data_list.append(tmp) - - self.multi_play_end_request_data_count = decode_int(data, off) - off += INT_OFF - - self.multi_play_end_request_data_list: List[MultiPlayEndRequestData] = [] - for _ in range(self.multi_play_end_request_data_count): - tmp = MultiPlayEndRequestData(data, off) - off += tmp.get_size() - self.multi_play_end_request_data_list.append(tmp) + self.multi_play_end_request_data: List[QuestSceneMultiPlayEndRequestData] = [] + self.multi_play_end_request_data, new_off = decode_arr_cls(data, off, QuestSceneMultiPlayEndRequestData) + off += new_off class SaoEpisodePlayEndResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.EPISODE_PLAY_END_RESPONSE) self.result = 1 - self.play_end_response_data_size = 1 # Number of arrays - self.multi_play_end_response_data_size = 1 # Unused on solo play + self.play_end_response_data: List[QuestScenePlayEndResponseData] = [QuestScenePlayEndResponseData.from_args()] + self.multi_play_end_response_data: List[QuestSceneMultiPlayEndResponseData] = [QuestSceneMultiPlayEndResponseData.from_args()] - self.dummy_1 = 0 - self.dummy_2 = 0 - self.dummy_3 = 0 - - self.rarity_up_occurrence_flag = 0 - self.adventure_ex_area_occurrences_flag = 0 - self.ex_bonus_data_list_size = 1 # Number of arrays - self.play_end_player_trace_reward_data_list_size = 0 # Number of arrays - - self.ex_bonus_table_id = 0 # ExBonusTable.csv values, dont care for now - self.achievement_status = 1 - - self.common_reward_data_size = 1 # Number of arrays - - self.common_reward_type = 0 # dummy values from 2,101000000,1 from RewardTable.csv - self.common_reward_id = 0 - self.common_reward_num = 0 - def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "play_end_response_data_size" / Int32ub, # big endian - - "rarity_up_occurrence_flag" / Int8ul, # result is either 0 or 1 - "adventure_ex_area_occurrences_flag" / Int8ul, # result is either 0 or 1 - "ex_bonus_data_list_size" / Int32ub, # big endian - "play_end_player_trace_reward_data_list_size" / Int32ub, # big endian - - # ex_bonus_data_list - "ex_bonus_table_id" / Int32ub, - "achievement_status" / Int8ul, # result is either 0 or 1 - - # play_end_player_trace_reward_data_list - "common_reward_data_size" / Int32ub, - - # common_reward_data - "common_reward_type" / Int16ub, # short - "common_reward_id" / Int32ub, - "common_reward_num" / Int32ub, - - "multi_play_end_response_data_size" / Int32ub, # big endian - - # multi_play_end_response_data - "dummy_1" / Int8ul, # result is either 0 or 1 - "dummy_2" / Int8ul, # result is either 0 or 1 - "dummy_3" / Int8ul, # result is either 0 or 1 - ) - - resp_data = resp_struct.build(dict( - result=self.result, - play_end_response_data_size=self.play_end_response_data_size, - - rarity_up_occurrence_flag=self.rarity_up_occurrence_flag, - adventure_ex_area_occurrences_flag=self.adventure_ex_area_occurrences_flag, - ex_bonus_data_list_size=self.ex_bonus_data_list_size, - play_end_player_trace_reward_data_list_size=self.play_end_player_trace_reward_data_list_size, - - ex_bonus_table_id=self.ex_bonus_table_id, - achievement_status=self.achievement_status, - - common_reward_data_size=self.common_reward_data_size, - - common_reward_type=self.common_reward_type, - common_reward_id=self.common_reward_id, - common_reward_num=self.common_reward_num, - - multi_play_end_response_data_size=self.multi_play_end_response_data_size, - - dummy_1=self.dummy_1, - dummy_2=self.dummy_2, - dummy_3=self.dummy_3, - )) - - self.length = len(resp_data) - return super().make() + resp_data + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.play_end_response_data) \ + + encode_arr_cls(self.multi_play_end_response_data) class SaoTrialTowerPlayStartRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: @@ -1714,160 +1018,56 @@ class SaoTrialTowerPlayStartRequest(SaoBaseRequest): off += tmp.get_size() self.multi_play_start_request_data.append(tmp) +class SaoTrialTowerPlayStartResponse(SaoBaseResponse): + def __init__(self, sesh_id: int, nickname: str) -> None: + super().__init__(GameconnectCmd.TRIAL_TOWER_PLAY_START_RESPONSE) + self.result = 1 + self.play_start_response_data: List[QuestScenePlayStartResponseData] = [QuestScenePlayStartResponseData.from_args(sesh_id, nickname)] + self.multi_play_start_response_data: List[QuestSceneMultiPlayStartResponseData] = [QuestSceneMultiPlayStartResponseData.from_args()] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.play_start_response_data) \ + + encode_arr_cls(self.multi_play_start_response_data) + class SaoTrialTowerPlayEndRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) off = 0 - ticket_id = decode_str(data, off) - self.ticket_id = ticket_id[0] - off += ticket_id[1] + self.ticket_id, new_off = decode_str(data, off) + off += new_off - user_id = decode_str(data, off) - self.user_id = user_id[0] - off += user_id[1] + self.user_id, new_off = decode_str(data, off) + off += new_off self.trial_tower_id = decode_int(data, off) off += INT_OFF - self.play_end_request_data_count = decode_int(data, off) - off += INT_OFF + self.play_end_request_data: List[QuestScenePlayEndRequestData] = [] + self.play_end_request_data, new_off = decode_arr_cls(data, off, QuestScenePlayEndRequestData) + off += new_off - self.play_end_request_data_list: List[PlayEndRequestData] = [] - for _ in range(self.play_end_request_data_count): - tmp = PlayEndRequestData(data, off) - off += tmp.get_size() - self.play_end_request_data_list.append(tmp) - - self.multi_play_end_request_data_count = decode_int(data, off) - off += INT_OFF - - self.multi_play_end_request_data_list: List[MultiPlayEndRequestData] = [] - for _ in range(self.multi_play_end_request_data_count): - tmp = MultiPlayEndRequestData(data, off) - off += tmp.get_size() - self.multi_play_end_request_data_list.append(tmp) + self.multi_play_end_request_data: List[QuestSceneMultiPlayEndRequestData] + self.multi_play_end_request_data, new_off = decode_arr_cls(data, off, QuestSceneMultiPlayEndRequestData) + off += new_off class SaoTrialTowerPlayEndResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.TRIAL_TOWER_PLAY_END_RESPONSE) self.result = 1 - self.play_end_response_data_size = 1 # Number of arrays - self.multi_play_end_response_data_size = 1 # Unused on solo play - self.trial_tower_play_end_updated_notification_data_size = 1 # Number of arrays - self.treasure_hunt_play_end_response_data_size = 1 # Number of arrays + self.play_end_response_data: List[QuestScenePlayEndResponseData] = [QuestScenePlayEndResponseData.from_args()] + self.multi_play_end_response_data: List[QuestSceneMultiPlayEndResponseData] = [QuestSceneMultiPlayEndResponseData.from_args()] + self.trial_tower_play_end_updated_notification_data: List[QuestTrialTowerPlayEndUpdatedNotificationData] = [QuestTrialTowerPlayEndUpdatedNotificationData.from_args()] + self.treasure_hunt_play_end_response_data: List[QuestTreasureHuntPlayEndResponseData] = [QuestTreasureHuntPlayEndResponseData.from_args()] - self.dummy_1 = 0 - self.dummy_2 = 0 - self.dummy_3 = 0 - - self.rarity_up_occurrence_flag = 0 - self.adventure_ex_area_occurrences_flag = 0 - self.ex_bonus_data_list_size = 1 # Number of arrays - self.play_end_player_trace_reward_data_list_size = 0 # Number of arrays - - self.ex_bonus_table_id = 0 # ExBonusTable.csv values, dont care for now - self.achievement_status = 1 - - self.common_reward_data_size = 1 # Number of arrays - - self.common_reward_type = 0 # dummy values from 2,101000000,1 from RewardTable.csv - self.common_reward_id = 0 - self.common_reward_num = 0 - - self.store_best_score_clear_time_flag = 0 - self.store_best_score_combo_num_flag = 0 - self.store_best_score_total_damage_flag = 0 - self.store_best_score_concurrent_destroying_num_flag = 0 - self.store_reaching_trial_tower_rank = 0 - - self.get_event_point = 0 - self.total_event_point = 0 - def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "play_end_response_data_size" / Int32ub, # big endian - - "rarity_up_occurrence_flag" / Int8ul, # result is either 0 or 1 - "adventure_ex_area_occurrences_flag" / Int8ul, # result is either 0 or 1 - "ex_bonus_data_list_size" / Int32ub, # big endian - "play_end_player_trace_reward_data_list_size" / Int32ub, # big endian - - # ex_bonus_data_list - "ex_bonus_table_id" / Int32ub, - "achievement_status" / Int8ul, # result is either 0 or 1 - - # play_end_player_trace_reward_data_list - "common_reward_data_size" / Int32ub, - - # common_reward_data - "common_reward_type" / Int16ub, # short - "common_reward_id" / Int32ub, - "common_reward_num" / Int32ub, - - "multi_play_end_response_data_size" / Int32ub, # big endian - - # multi_play_end_response_data - "dummy_1" / Int8ul, # result is either 0 or 1 - "dummy_2" / Int8ul, # result is either 0 or 1 - "dummy_3" / Int8ul, # result is either 0 or 1 - - "trial_tower_play_end_updated_notification_data_size" / Int32ub, # big endian - - #trial_tower_play_end_updated_notification_data - "store_best_score_clear_time_flag" / Int8ul, # result is either 0 or 1 - "store_best_score_combo_num_flag" / Int8ul, # result is either 0 or 1 - "store_best_score_total_damage_flag" / Int8ul, # result is either 0 or 1 - "store_best_score_concurrent_destroying_num_flag" / Int8ul, # result is either 0 or 1 - "store_reaching_trial_tower_rank" / Int32ub, - - "treasure_hunt_play_end_response_data_size" / Int32ub, # big endian - - #treasure_hunt_play_end_response_data - "get_event_point" / Int32ub, - "total_event_point" / Int32ub, - ) - - resp_data = resp_struct.build(dict( - result=self.result, - play_end_response_data_size=self.play_end_response_data_size, - - rarity_up_occurrence_flag=self.rarity_up_occurrence_flag, - adventure_ex_area_occurrences_flag=self.adventure_ex_area_occurrences_flag, - ex_bonus_data_list_size=self.ex_bonus_data_list_size, - play_end_player_trace_reward_data_list_size=self.play_end_player_trace_reward_data_list_size, - - ex_bonus_table_id=self.ex_bonus_table_id, - achievement_status=self.achievement_status, - - common_reward_data_size=self.common_reward_data_size, - - common_reward_type=self.common_reward_type, - common_reward_id=self.common_reward_id, - common_reward_num=self.common_reward_num, - - multi_play_end_response_data_size=self.multi_play_end_response_data_size, - - dummy_1=self.dummy_1, - dummy_2=self.dummy_2, - dummy_3=self.dummy_3, - - trial_tower_play_end_updated_notification_data_size=self.trial_tower_play_end_updated_notification_data_size, - store_best_score_clear_time_flag=self.store_best_score_clear_time_flag, - store_best_score_combo_num_flag=self.store_best_score_combo_num_flag, - store_best_score_total_damage_flag=self.store_best_score_total_damage_flag, - store_best_score_concurrent_destroying_num_flag=self.store_best_score_concurrent_destroying_num_flag, - store_reaching_trial_tower_rank=self.store_reaching_trial_tower_rank, - - treasure_hunt_play_end_response_data_size=self.treasure_hunt_play_end_response_data_size, - - get_event_point=self.get_event_point, - total_event_point=self.total_event_point, - )) - - self.length = len(resp_data) - return super().make() + resp_data + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.play_end_response_data) \ + + encode_arr_cls(self.multi_play_end_response_data) \ + + encode_arr_cls(self.trial_tower_play_end_updated_notification_data) \ + + encode_arr_cls(self.treasure_hunt_play_end_response_data) class SaoEpisodePlayEndUnanalyzedLogFixedRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: @@ -1888,1150 +1088,597 @@ class SaoEpisodePlayEndUnanalyzedLogFixedRequest(SaoBaseRequest): off += BYTE_OFF class SaoEpisodePlayEndUnanalyzedLogFixedResponse(SaoBaseResponse): - def __init__(self, cmd, end_session_data) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.EPISODE_PLAY_END_UNANALYZED_LOG_FIXED_RESPONSE) self.result = 1 + self.play_end_unanalyzed_log_reward_data_list: List[QuestScenePlayEndUnanalyzedLogRewardData] = [] - self.unanalyzed_log_grade_id = [] - - self.common_reward_type = [] - self.common_reward_id = [] - self.common_reward_num = 1 - - for x in range(len(end_session_data)): - self.common_reward_id.append(end_session_data[x]) - - with open('titles/sao/data/RewardTable.csv', 'r') as f: - keys_unanalyzed = next(f).strip().split(',') - data_unanalyzed = list(DictReader(f, fieldnames=keys_unanalyzed)) - - for i in range(len(data_unanalyzed)): - if int(data_unanalyzed[i]["CommonRewardId"]) == int(end_session_data[x]): - self.unanalyzed_log_grade_id.append(int(data_unanalyzed[i]["UnanalyzedLogGradeId"])) - self.common_reward_type.append(int(data_unanalyzed[i]["CommonRewardType"])) - break - - self.unanalyzed_log_grade_id = list(map(int,self.unanalyzed_log_grade_id)) #int - self.common_reward_type = list(map(int,self.common_reward_type)) #int - self.common_reward_id = list(map(int,self.common_reward_id)) #int - def make(self) -> bytes: - #new stuff - common_reward_data_struct = Struct( - "common_reward_type" / Int16ub, - "common_reward_id" / Int32ub, - "common_reward_num" / Int32ub, - ) - - play_end_unanalyzed_log_reward_data_list_struct = Struct( - "unanalyzed_log_grade_id" / Int32ub, - "common_reward_data_size" / Rebuild(Int32ub, len_(this.common_reward_data)), # big endian - "common_reward_data" / Array(this.common_reward_data_size, common_reward_data_struct), - ) - - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "play_end_unanalyzed_log_reward_data_list_size" / Rebuild(Int32ub, len_(this.play_end_unanalyzed_log_reward_data_list)), # big endian - "play_end_unanalyzed_log_reward_data_list" / Array(this.play_end_unanalyzed_log_reward_data_list_size, play_end_unanalyzed_log_reward_data_list_struct), - ) - - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - play_end_unanalyzed_log_reward_data_list_size=0, - play_end_unanalyzed_log_reward_data_list=[], - ))) - - for i in range(len(self.common_reward_id)): - reward_resp_data = dict( - unanalyzed_log_grade_id=self.unanalyzed_log_grade_id[i], - common_reward_data_size=0, - common_reward_data=[], - ) - - reward_resp_data["common_reward_data"].append(dict( - common_reward_type=self.common_reward_type[i], - common_reward_id=self.common_reward_id[i], - common_reward_num=self.common_reward_num, - )) - - resp_data.play_end_unanalyzed_log_reward_data_list.append(reward_resp_data) - - resp_data["play_end_unanalyzed_log_reward_data_list_size"] = len(resp_data.play_end_unanalyzed_log_reward_data_list) - for i in range(len(resp_data.play_end_unanalyzed_log_reward_data_list)): - resp_data.play_end_unanalyzed_log_reward_data_list[i]["common_reward_data_size"] = len(resp_data.play_end_unanalyzed_log_reward_data_list[i]["common_reward_data"]) - - # finally, rebuild the resp_data - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data - -class SaoGetQuestSceneUserDataListRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - self.user_id = decode_str(data, 0)[0] + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.play_end_unanalyzed_log_reward_data_list) class SaoGetQuestSceneUserDataListResponse(SaoBaseResponse): - def __init__(self, cmd, quest_data) -> None: - super().__init__(cmd) - self.length = None + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_QUEST_SCENE_USER_DATA_LIST_RESPONSE) self.result = 1 + self.quest_scene_user_data_list: List[QuestSceneUserData] = [] - # quest_scene_user_data_list_size - self.quest_type = [] - self.quest_scene_id = [] - self.clear_flag = [] - - # quest_scene_best_score_user_data - self.clear_time = [] - self.combo_num = [] - self.total_damage = [] #string - self.concurrent_destroying_num = [] - - for i in range(len(quest_data)): - self.quest_type.append(1) - self.quest_scene_id.append(quest_data[i][2]) - self.clear_flag.append(int(quest_data[i][3])) - - self.clear_time.append(quest_data[i][4]) - self.combo_num.append(quest_data[i][5]) - self.total_damage.append(0) #totally absurd but Int16ul[1] is a big problem due to different lenghts... - self.concurrent_destroying_num.append(quest_data[i][7]) - - # quest_scene_ex_bonus_user_data_list - self.achievement_flag = [1,1,1] - self.ex_bonus_table_id = [1,2,3] - - - self.quest_type = list(map(int,self.quest_type)) #int - self.quest_scene_id = list(map(int,self.quest_scene_id)) #int - self.clear_flag = list(map(int,self.clear_flag)) #int - self.clear_time = list(map(int,self.clear_time)) #int - self.combo_num = list(map(int,self.combo_num)) #int - self.total_damage = list(map(str,self.total_damage)) #string - self.concurrent_destroying_num = list(map(int,self.combo_num)) #int - def make(self) -> bytes: - #new stuff - quest_scene_ex_bonus_user_data_list_struct = Struct( - "ex_bonus_table_id" / Int32ub, # big endian - "achievement_flag" / Int8ul, # result is either 0 or 1 - ) - - quest_scene_best_score_user_data_struct = Struct( - "clear_time" / Int32ub, # big endian - "combo_num" / Int32ub, # big endian - "total_damage_size" / Int32ub, # big endian - "total_damage" / Int16ul[1], - "concurrent_destroying_num" / Int16ub, - ) - - quest_scene_user_data_list_struct = Struct( - "quest_type" / Int8ul, # result is either 0 or 1 - "quest_scene_id" / Int16ub, #short - "clear_flag" / Int8ul, # result is either 0 or 1 - "quest_scene_best_score_user_data_size" / Rebuild(Int32ub, len_(this.quest_scene_best_score_user_data)), # big endian - "quest_scene_best_score_user_data" / Array(this.quest_scene_best_score_user_data_size, quest_scene_best_score_user_data_struct), - "quest_scene_ex_bonus_user_data_list_size" / Rebuild(Int32ub, len_(this.quest_scene_ex_bonus_user_data_list)), # big endian - "quest_scene_ex_bonus_user_data_list" / Array(this.quest_scene_ex_bonus_user_data_list_size, quest_scene_ex_bonus_user_data_list_struct), - ) - - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "quest_scene_user_data_list_size" / Rebuild(Int32ub, len_(this.quest_scene_user_data_list)), # big endian - "quest_scene_user_data_list" / Array(this.quest_scene_user_data_list_size, quest_scene_user_data_list_struct), - ) - - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - quest_scene_user_data_list_size=0, - quest_scene_user_data_list=[], - ))) - - for i in range(len(self.quest_scene_id)): - quest_resp_data = dict( - quest_type=self.quest_type[i], - quest_scene_id=self.quest_scene_id[i], - clear_flag=self.clear_flag[i], - - quest_scene_best_score_user_data_size=0, - quest_scene_best_score_user_data=[], - quest_scene_ex_bonus_user_data_list_size=0, - quest_scene_ex_bonus_user_data_list=[], - ) - - quest_resp_data["quest_scene_best_score_user_data"].append(dict( - clear_time=self.clear_time[i], - combo_num=self.combo_num[i], - total_damage_size=len(self.total_damage[i]) * 2, - total_damage=[ord(x) for x in self.total_damage[i]], - concurrent_destroying_num=self.concurrent_destroying_num[i], - )) - - resp_data.quest_scene_user_data_list.append(quest_resp_data) - - resp_data["quest_scene_user_data_list_size"] = len(resp_data.quest_scene_user_data_list) - for i in range(len(resp_data.quest_scene_user_data_list)): - resp_data.quest_scene_user_data_list[i]["quest_scene_best_score_user_data_size"] = len(resp_data.quest_scene_user_data_list[i]["quest_scene_best_score_user_data"]) - - # finally, rebuild the resp_data - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.quest_scene_user_data_list) class SaoCheckYuiMedalGetConditionRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + self.user_id, new_off = decode_str(data, off) + off += new_off class SaoCheckYuiMedalGetConditionResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self, elapsed_days: int = 0, get_num: int = 0) -> None: + super().__init__(GameconnectCmd.CHECK_YUI_MEDAL_GET_CONDITION_RESPONSE) self.result = 1 - self.get_flag = 1 - self.elapsed_days = 0 - self.get_yui_medal_num = 0 + self.get_flag = int(get_num > 0) + self.elapsed_days = elapsed_days + self.get_yui_medal_num = get_num def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "get_flag" / Int8ul, # result is either 0 or 1 - "elapsed_days" / Int16ub, #short - "get_yui_medal_num" / Int16ub, #short - ) - - resp_data = resp_struct.build(dict( - result=self.result, - get_flag=self.get_flag, - elapsed_days=self.elapsed_days, - get_yui_medal_num=self.get_yui_medal_num, - )) - - self.length = len(resp_data) - return super().make() + resp_data + return super().make() \ + + encode_byte(self.result) \ + + encode_byte(self.get_flag) \ + + encode_short(self.elapsed_days) \ + + encode_short(self.get_yui_medal_num) \ class SaoGetYuiMedalBonusUserDataRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.yui_medal_bonus_id = decode_int(data, off) + off += INT_OFF class SaoGetYuiMedalBonusUserDataResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self, elapsed_days: int = 0, loop_num: int = 0) -> None: + super().__init__(GameconnectCmd.GET_YUI_MEDAL_BONUS_USER_DATA_RESPONSE) self.result = 1 - self.data_size = 1 # number of arrays - - self.elapsed_days = 1 - self.loop_num = 1 - self.last_check_date = "20230520193000" - self.last_get_date = "20230520193000" + self.data: List[YuiMedalBonusUserData] = [YuiMedalBonusUserData.from_args(elapsed_days, loop_num)] def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "data_size" / Int32ub, # big endian - - "elapsed_days" / Int32ub, # big endian - "loop_num" / Int32ub, # big endian - "last_check_date_size" / Int32ub, # big endian - "last_check_date" / Int16ul[len(self.last_check_date)], - "last_get_date_size" / Int32ub, # big endian - "last_get_date" / Int16ul[len(self.last_get_date)], - ) - - resp_data = resp_struct.build(dict( - result=self.result, - data_size=self.data_size, - - elapsed_days=self.elapsed_days, - loop_num=self.loop_num, - last_check_date_size=len(self.last_check_date) * 2, - last_check_date=[ord(x) for x in self.last_check_date], - last_get_date_size=len(self.last_get_date) * 2, - last_get_date=[ord(x) for x in self.last_get_date], - - )) - - self.length = len(resp_data) - return super().make() + resp_data + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data) class SaoCheckProfileCardUsedRewardRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + self.user_id, new_off = decode_str(data, off) + off += new_off class SaoCheckProfileCardUsedRewardResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.CHECK_PROFILE_CARD_USED_REWARD_RESPONSE) self.result = 1 - self.get_flag = 1 + self.get_flag = 0 self.used_num = 0 - self.get_vp = 1 + self.get_vp = 0 def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "get_flag" / Int8ul, # result is either 0 or 1 - "used_num" / Int32ub, # big endian - "get_vp" / Int32ub, # big endian - ) + return super().make() \ + + encode_byte(self.result) \ + + encode_byte(self.get_flag) \ + + encode_int(self.used_num) \ + + encode_int(self.get_vp) - resp_data = resp_struct.build(dict( - result=self.result, - get_flag=self.get_flag, - used_num=self.used_num, - get_vp=self.get_vp, - - )) +class SaoDisposalResourceRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off - self.length = len(resp_data) - return super().make() + resp_data + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.disposal_common_reward_user_data_list: List[CommonRewardUserData] = [] + self.disposal_common_reward_user_data_list, new_off = decode_arr_cls(data, off, CommonRewardUserData) + off += new_off + +class SaoDisposalResourceResponse(SaoBaseResponse): + def __init__(self, get_col: int = 0) -> None: + super().__init__(GameconnectCmd.DISPOSAL_RESOURCE_RESPONSE) + self.result = 1 + self.get_col = get_col + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_int(self.get_col) class SaoSynthesizeEnhancementHeroLogRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) off = 0 - ticket_id = decode_str(data, off) - self.ticket_id = ticket_id[0] - off += ticket_id[1] + self.ticket_id, new_off = decode_str(data, off) + off += new_off - user_id = decode_str(data, off) - self.user_id = user_id[0] - off += user_id[1] + self.user_id, new_off = decode_str(data, off) + off += new_off - origin_user_hero_log_id = decode_str(data, off) - self.origin_user_hero_log_id = origin_user_hero_log_id[0] - off += origin_user_hero_log_id[1] + self.origin_user_hero_log_id, new_off = decode_str(data, off) + off += new_off - self.material_common_reward_user_data_list: List[MaterialCommonRewardUserData] = [] - - self.material_common_reward_user_data_count = decode_int(data, off) - off += INT_OFF - - for _ in range(self.material_common_reward_user_data_count): - mat = MaterialCommonRewardUserData(data, off) - off += mat.get_size() - self.material_common_reward_user_data_list.append(mat) + self.material_common_reward_user_data_list: List[CommonRewardUserData] = [] + self.material_common_reward_user_data_list, new_off = decode_arr_cls(data, off, CommonRewardUserData) + off += new_off class SaoSynthesizeEnhancementHeroLogResponse(SaoBaseResponse): - def __init__(self, cmd, hero_data) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.SYNTHESIZE_ENHANCEMENT_HERO_LOG_RESPONSE) self.result = 1 + self.after_hero_log_user_data: List[HeroLogUserData] = [] - # Calculate level based off experience and the CSV list - with open(r'titles/sao/data/HeroLogLevel.csv') as csv_file: - csv_reader = csv.reader(csv_file, delimiter=',') - line_count = 0 - data = [] - rowf = False - for row in csv_reader: - if rowf==False: - rowf=True - else: - data.append(row) - - exp = hero_data[4] - - for e in range(0,len(data)): - if exp>=int(data[e][1]) and exp bytes: - #new stuff - - hero_log_user_data_list_struct = Struct( - "user_hero_log_id_size" / Int32ub, # big endian - "user_hero_log_id" / Int16ul[9], #string - "hero_log_id" / Int32ub, #int - "log_level" / Int16ub, #short - "max_log_level_extended_num" / Int16ub, #short - "log_exp" / Int32ub, #int - "possible_awakening_flag" / Int8ul, # result is either 0 or 1 - "awakening_stage" / Int16ub, #short - "awakening_exp" / Int32ub, #int - "skill_slot_correction_value" / Int8ul, # result is either 0 or 1 - "last_set_skill_slot1_skill_id" / Int16ub, #short - "last_set_skill_slot2_skill_id" / Int16ub, #short - "last_set_skill_slot3_skill_id" / Int16ub, #short - "last_set_skill_slot4_skill_id" / Int16ub, #short - "last_set_skill_slot5_skill_id" / Int16ub, #short - "property1_property_id" / Int32ub, - "property1_value1" / Int32ub, - "property1_value2" / Int32ub, - "property2_property_id" / Int32ub, - "property2_value1" / Int32ub, - "property2_value2" / Int32ub, - "property3_property_id" / Int32ub, - "property3_value1" / Int32ub, - "property3_value2" / Int32ub, - "property4_property_id" / Int32ub, - "property4_value1" / Int32ub, - "property4_value2" / Int32ub, - "converted_card_num" / Int16ub, - "shop_purchase_flag" / Int8ul, # result is either 0 or 1 - "protect_flag" / Int8ul, # result is either 0 or 1 - "get_date_size" / Int32ub, # big endian - "get_date" / Int16ul[len(self.get_date)], - ) - - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "hero_log_user_data_list_size" / Rebuild(Int32ub, len_(this.hero_log_user_data_list)), # big endian - "hero_log_user_data_list" / Array(this.hero_log_user_data_list_size, hero_log_user_data_list_struct), - ) - - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - hero_log_user_data_list_size=0, - hero_log_user_data_list=[], - ))) - - hero_data = dict( - user_hero_log_id_size=len(self.user_hero_log_id) * 2, - user_hero_log_id=[ord(x) for x in self.user_hero_log_id], - hero_log_id=self.hero_log_id, - log_level=self.log_level, - max_log_level_extended_num=self.max_log_level_extended_num, - log_exp=self.log_exp, - possible_awakening_flag=self.possible_awakening_flag, - awakening_stage=self.awakening_stage, - awakening_exp=self.awakening_exp, - skill_slot_correction_value=self.skill_slot_correction_value, - last_set_skill_slot1_skill_id=self.last_set_skill_slot1_skill_id, - last_set_skill_slot2_skill_id=self.last_set_skill_slot2_skill_id, - last_set_skill_slot3_skill_id=self.last_set_skill_slot3_skill_id, - last_set_skill_slot4_skill_id=self.last_set_skill_slot4_skill_id, - last_set_skill_slot5_skill_id=self.last_set_skill_slot5_skill_id, - property1_property_id=self.property1_property_id, - property1_value1=self.property1_value1, - property1_value2=self.property1_value2, - property2_property_id=self.property2_property_id, - property2_value1=self.property2_value1, - property2_value2=self.property2_value2, - property3_property_id=self.property3_property_id, - property3_value1=self.property3_value1, - property3_value2=self.property3_value2, - property4_property_id=self.property4_property_id, - property4_value1=self.property4_value1, - property4_value2=self.property4_value2, - converted_card_num=self.converted_card_num, - shop_purchase_flag=self.shop_purchase_flag, - protect_flag=self.protect_flag, - get_date_size=len(self.get_date) * 2, - get_date=[ord(x) for x in self.get_date], - - ) - - resp_data.hero_log_user_data_list.append(hero_data) - - resp_data["hero_log_user_data_list_size"] = len(resp_data.hero_log_user_data_list) - - # finally, rebuild the resp_data - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.after_hero_log_user_data) class SaoSynthesizeEnhancementEquipmentRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) off = 0 - ticket_id = decode_str(data, off) - self.ticket_id = ticket_id[0] - off += ticket_id[1] + self.ticket_id, new_off = decode_str(data, off) + off += new_off - user_id = decode_str(data, off) - self.user_id = user_id[0] - off += user_id[1] - - origin_user_equipment_id = decode_str(data, off) - self.origin_user_equipment_id = origin_user_equipment_id[0] - off += origin_user_equipment_id[1] - - self.material_common_reward_user_data_list: List[MaterialCommonRewardUserData] = [] - - self.material_common_reward_user_data_count = decode_int(data, off) - off += INT_OFF + self.user_id, new_off = decode_str(data, off) + off += new_off - for _ in range(self.material_common_reward_user_data_count): - mat = MaterialCommonRewardUserData(data, off) - off += mat.get_size() - self.material_common_reward_user_data_list.append(mat) + self.origin_user_equipment_id, new_off = decode_str(data, off) + off += new_off + + self.material_common_reward_user_data_list: List[CommonRewardUserData] = [] + self.material_common_reward_user_data_list, new_off = decode_arr_cls(data, off, CommonRewardUserData) + off += new_off class SaoSynthesizeEnhancementEquipmentResponse(SaoBaseResponse): - def __init__(self, cmd, synthesize_equipment_data) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.SYNTHESIZE_ENHANCEMENT_EQUIPMENT_RESPONSE) self.result = 1 - equipment_level = 0 + self.after_equipment_user_data: List[EquipmentUserData] = [] - # Calculate level based off experience and the CSV list - with open(r'titles/sao/data/EquipmentLevel.csv') as csv_file: - csv_reader = csv.reader(csv_file, delimiter=',') - line_count = 0 - data = [] - rowf = False - for row in csv_reader: - if rowf==False: - rowf=True - else: - data.append(row) - - exp = synthesize_equipment_data[4] - - for e in range(0,len(data)): - if exp>=int(data[e][1]) and exp bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.after_equipment_user_data) - after_equipment_user_data_struct = Struct( - "user_equipment_id_size" / Int32ub, # big endian - "user_equipment_id" / Int16ul[9], #string - "equipment_id" / Int32ub, #int - "enhancement_value" / Int16ub, #short - "max_enhancement_value_extended_num" / Int16ub, #short - "enhancement_exp" / Int32ub, #int - "possible_awakening_flag" / Int8ul, # result is either 0 or 1 - "awakening_stage" / Int16ub, #short - "awakening_exp" / Int32ub, #int - "property1_property_id" / Int32ub, - "property1_value1" / Int32ub, - "property1_value2" / Int32ub, - "property2_property_id" / Int32ub, - "property2_value1" / Int32ub, - "property2_value2" / Int32ub, - "property3_property_id" / Int32ub, - "property3_value1" / Int32ub, - "property3_value2" / Int32ub, - "property4_property_id" / Int32ub, - "property4_value1" / Int32ub, - "property4_value2" / Int32ub, - "converted_card_num" / Int16ub, - "shop_purchase_flag" / Int8ul, # result is either 0 or 1 - "protect_flag" / Int8ul, # result is either 0 or 1 - "get_date_size" / Int32ub, # big endian - "get_date" / Int16ul[len(self.get_date)], - ) +class SaoGetAdventureExecUserDataResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_ADVENTURE_EXEC_USER_DATA_RESPONSE) + self.result = 1 + self.adventure_exec_user_data: List[AdventureExecUserData] = [] - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "after_equipment_user_data_size" / Rebuild(Int32ub, len_(this.after_equipment_user_data)), # big endian - "after_equipment_user_data" / Array(this.after_equipment_user_data_size, after_equipment_user_data_struct), - ) + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.adventure_exec_user_data) - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - after_equipment_user_data_size=0, - after_equipment_user_data=[], - ))) +class SaoGetChatSideStoryUserDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_CHAT_SIDE_STORY_USER_DATA_LIST_RESPONSE) + self.result = 1 + self.chat_side_story_user_data_list: List[ChatSideStoryUserData] = [] - synthesize_equipment_data = dict( - user_equipment_id_size=len(self.user_equipment_id) * 2, - user_equipment_id=[ord(x) for x in self.user_equipment_id], - equipment_id=self.equipment_id, - enhancement_value=self.enhancement_value, - max_enhancement_value_extended_num=self.max_enhancement_value_extended_num, - enhancement_exp=self.enhancement_exp, - possible_awakening_flag=self.possible_awakening_flag, - awakening_stage=self.awakening_stage, - awakening_exp=self.awakening_exp, - property1_property_id=self.property1_property_id, - property1_value1=self.property1_value1, - property1_value2=self.property1_value2, - property2_property_id=self.property2_property_id, - property2_value1=self.property2_value1, - property2_value2=self.property2_value2, - property3_property_id=self.property3_property_id, - property3_value1=self.property3_value1, - property3_value2=self.property3_value2, - property4_property_id=self.property4_property_id, - property4_value1=self.property4_value1, - property4_value2=self.property4_value2, - converted_card_num=self.converted_card_num, - shop_purchase_flag=self.shop_purchase_flag, - protect_flag=self.protect_flag, - get_date_size=len(self.get_date) * 2, - get_date=[ord(x) for x in self.get_date], + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.chat_side_story_user_data_list) - ) - - resp_data.after_equipment_user_data.append(synthesize_equipment_data) +class SaoBeginnerMissionAdConfirmNotificationRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off - resp_data["after_equipment_user_data_size"] = len(resp_data.after_equipment_user_data) + self.user_id, new_off = decode_str(data, off) + off += new_off - # finally, rebuild the resp_data - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data + self.beginner_mission_id = decode_int(data, off) + off += INT_OFF class SaoGetDefragMatchBasicDataRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.defrag_match_id = decode_int(data, off) + off += INT_OFF class SaoGetDefragMatchBasicDataResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_DEFRAG_MATCH_BASIC_DATA_RESPONSE) self.result = 1 - self.defrag_match_basic_user_data_size = 1 # number of arrays - - self.seed_flag = 1 - self.ad_confirm_flag = 1 - self.total_league_point = 0 - self.have_league_score = 0 - self.class_num = 1 # 1 to 6 - self.hall_of_fame_confirm_flag = 0 + self.defrag_match_basic_user_data: List[DefragMatchBasicUserData] = [] def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "defrag_match_basic_user_data_size" / Int32ub, # big endian - - "seed_flag" / Int16ub, #short - "ad_confirm_flag" / Int8ul, # result is either 0 or 1 - "total_league_point" / Int32ub, #int - "have_league_score" / Int16ub, #short - "class_num" / Int16ub, #short - "hall_of_fame_confirm_flag" / Int8ul, # result is either 0 or 1 - - ) - - resp_data = resp_struct.build(dict( - result=self.result, - defrag_match_basic_user_data_size=self.defrag_match_basic_user_data_size, - - seed_flag=self.seed_flag, - ad_confirm_flag=self.ad_confirm_flag, - total_league_point=self.total_league_point, - have_league_score=self.have_league_score, - class_num=self.class_num, - hall_of_fame_confirm_flag=self.hall_of_fame_confirm_flag, - )) - - self.length = len(resp_data) - return super().make() + resp_data + ret = encode_byte(self.result) + ret += encode_arr_cls(self.defrag_match_basic_user_data) + return super().make() + ret class SaoGetDefragMatchRankingUserDataRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.defrag_match_id = decode_int(data, off) + off += INT_OFF class SaoGetDefragMatchRankingUserDataResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self, profile: Dict) -> None: + super().__init__(GameconnectCmd.GET_DEFRAG_MATCH_RANKING_USER_DATA_RESPONSE) self.result = 1 - self.ranking_user_data_size = 1 # number of arrays + self.ranking_user_data: List[DefragMatchRankingUserData] = [DefragMatchRankingUserData.from_args(profile)] - self.league_point_rank = 1 - self.league_score_rank = 1 - self.nick_name = "PLAYER" - self.setting_title_id = 20005 # Default saved during profile creation, no changing for those atm - self.favorite_hero_log_id = 101000010 # Default saved during profile creation - self.favorite_hero_log_awakening_stage = 0 - self.favorite_support_log_id = 0 - self.favorite_support_log_awakening_stage = 0 - self.total_league_point = 1 - self.have_league_score = 1 - def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "ranking_user_data_size" / Int32ub, # big endian - - "league_point_rank" / Int32ub, #int - "league_score_rank" / Int32ub, #int - "nick_name_size" / Int32ub, # big endian - "nick_name" / Int16ul[len(self.nick_name)], - "setting_title_id" / Int32ub, #int - "favorite_hero_log_id" / Int32ub, #int - "favorite_hero_log_awakening_stage" / Int16ub, #short - "favorite_support_log_id" / Int32ub, #int - "favorite_support_log_awakening_stage" / Int16ub, #short - "total_league_point" / Int32ub, #int - "have_league_score" / Int16ub, #short - ) - - resp_data = resp_struct.build(dict( - result=self.result, - ranking_user_data_size=self.ranking_user_data_size, - - league_point_rank=self.league_point_rank, - league_score_rank=self.league_score_rank, - nick_name_size=len(self.nick_name) * 2, - nick_name=[ord(x) for x in self.nick_name], - setting_title_id=self.setting_title_id, - favorite_hero_log_id=self.favorite_hero_log_id, - favorite_hero_log_awakening_stage=self.favorite_hero_log_awakening_stage, - favorite_support_log_id=self.favorite_support_log_id, - favorite_support_log_awakening_stage=self.favorite_support_log_awakening_stage, - total_league_point=self.total_league_point, - have_league_score=self.have_league_score, - )) - - self.length = len(resp_data) - return super().make() + resp_data + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.ranking_user_data) class SaoGetDefragMatchLeaguePointRankingListRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.get_rank_start_num = decode_short(data, off) + off += SHORT_OFF + + self.get_rank_end_num = decode_short(data, off) + off += SHORT_OFF class SaoGetDefragMatchLeaguePointRankingListResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_DEFRAG_MATCH_LEAGUE_POINT_RANKING_LIST_RESPONSE) self.result = 1 - self.ranking_user_data_size = 1 # number of arrays + self.ranking_data_list: List[DefragMatchLeaguePointRankingData] = [] - self.rank = 1 - self.user_id = "1" - self.store_id = "123" - self.store_name = "ARTEMiS" - self.nick_name = "PLAYER" - self.setting_title_id = 20005 - self.favorite_hero_log_id = 101000010 - self.favorite_hero_log_awakening_stage = 0 - self.favorite_support_log_id = 0 - self.favorite_support_log_awakening_stage = 0 - self.class_num = 1 - self.total_league_point = 1 - def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "ranking_user_data_size" / Int32ub, # big endian - - "rank" / Int32ub, #int - "user_id_size" / Int32ub, # big endian - "user_id" / Int16ul[len(self.user_id)], - "store_id_size" / Int32ub, # big endian - "store_id" / Int16ul[len(self.store_id)], - "store_name_size" / Int32ub, # big endian - "store_name" / Int16ul[len(self.store_name)], - "nick_name_size" / Int32ub, # big endian - "nick_name" / Int16ul[len(self.nick_name)], - "setting_title_id" / Int32ub, #int - "favorite_hero_log_id" / Int32ub, #int - "favorite_hero_log_awakening_stage" / Int16ub, #short - "favorite_support_log_id" / Int32ub, #int - "favorite_support_log_awakening_stage" / Int16ub, #short - "class_num" / Int16ub, #short - "total_league_point" / Int32ub, #int - ) - - resp_data = resp_struct.build(dict( - result=self.result, - ranking_user_data_size=self.ranking_user_data_size, - - rank=self.rank, - user_id_size=len(self.user_id) * 2, - user_id=[ord(x) for x in self.user_id], - store_id_size=len(self.store_id) * 2, - store_id=[ord(x) for x in self.store_id], - store_name_size=len(self.store_name) * 2, - store_name=[ord(x) for x in self.store_name], - nick_name_size=len(self.nick_name) * 2, - nick_name=[ord(x) for x in self.nick_name], - setting_title_id=self.setting_title_id, - favorite_hero_log_id=self.favorite_hero_log_id, - favorite_hero_log_awakening_stage=self.favorite_hero_log_awakening_stage, - favorite_support_log_id=self.favorite_support_log_id, - favorite_support_log_awakening_stage=self.favorite_support_log_awakening_stage, - class_num=self.class_num, - total_league_point=self.total_league_point, - )) - - self.length = len(resp_data) - return super().make() + resp_data + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.ranking_data_list) class SaoGetDefragMatchLeagueScoreRankingListRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.get_rank_start_num = decode_short(data, off) + off += SHORT_OFF + + self.get_rank_end_num = decode_short(data, off) + off += SHORT_OFF class SaoGetDefragMatchLeagueScoreRankingListResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_DEFRAG_MATCH_LEAGUE_SCORE_RANKING_LIST_RESPONSE) self.result = 1 - self.ranking_user_data_size = 1 # number of arrays - - self.rank = 1 - self.user_id = "1" - self.store_id = "123" - self.store_name = "ARTEMiS" - self.nick_name = "PLAYER" - self.setting_title_id = 20005 - self.favorite_hero_log_id = 101000010 - self.favorite_hero_log_awakening_stage = 0 - self.favorite_support_log_id = 0 - self.favorite_support_log_awakening_stage = 0 - self.class_num = 1 - self.have_league_score = 1 + self.ranking_user_data: List[DefragMatchLeagueScoreRankingList] = [] def make(self) -> bytes: # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "ranking_user_data_size" / Int32ub, # big endian - - "rank" / Int32ub, #int - "user_id_size" / Int32ub, # big endian - "user_id" / Int16ul[len(self.user_id)], - "store_id_size" / Int32ub, # big endian - "store_id" / Int16ul[len(self.store_id)], - "store_name_size" / Int32ub, # big endian - "store_name" / Int16ul[len(self.store_name)], - "nick_name_size" / Int32ub, # big endian - "nick_name" / Int16ul[len(self.nick_name)], - "setting_title_id" / Int32ub, #int - "favorite_hero_log_id" / Int32ub, #int - "favorite_hero_log_awakening_stage" / Int16ub, #short - "favorite_support_log_id" / Int32ub, #int - "favorite_support_log_awakening_stage" / Int16ub, #short - "class_num" / Int16ub, #short - "have_league_score" / Int16ub, #short - ) - - resp_data = resp_struct.build(dict( - result=self.result, - ranking_user_data_size=self.ranking_user_data_size, - - rank=self.rank, - user_id_size=len(self.user_id) * 2, - user_id=[ord(x) for x in self.user_id], - store_id_size=len(self.store_id) * 2, - store_id=[ord(x) for x in self.store_id], - store_name_size=len(self.store_name) * 2, - store_name=[ord(x) for x in self.store_name], - nick_name_size=len(self.nick_name) * 2, - nick_name=[ord(x) for x in self.nick_name], - setting_title_id=self.setting_title_id, - favorite_hero_log_id=self.favorite_hero_log_id, - favorite_hero_log_awakening_stage=self.favorite_hero_log_awakening_stage, - favorite_support_log_id=self.favorite_support_log_id, - favorite_support_log_awakening_stage=self.favorite_support_log_awakening_stage, - class_num=self.class_num, - have_league_score=self.have_league_score, - )) - - self.length = len(resp_data) + resp_data = encode_byte(self.result) + resp_data += encode_arr_cls(self.ranking_user_data) return super().make() + resp_data +class SaoGetBeginnerMissionProgressesUserDataListRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.beginner_mission_id = decode_int(data, off) + off += INT_OFF + +class SaoGetBeginnerMissionProgressesUserDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_BEGINNER_MISSION_PROGRESSES_USER_DATA_LIST_RESPONSE) + self.result = 1 + self.data_list: List[BeginnerMissionProgressesUserData] = [] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetBeginnerMissionSeatProgressesUserDataListRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.beginner_mission_id = decode_int(data, off) + off += INT_OFF + +class SaoGetBeginnerMissionSeatProgressesUserDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_BEGINNER_MISSION_SEAT_PROGRESSES_USER_DATA_LIST_RESPONSE) + self.result = 1 + self.data_list: List[BeginnerMissionSeatProgressesUserData] = [] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetLinkedSiteRegCampaignUserDataRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.linked_site_reg_campaign_id = decode_int(data, off) + off += INT_OFF + +class SaoGetLinkedSiteRegCampaignUserDataResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_LINKED_SITE_REG_CAMPAIGN_USER_DATA_RESPONSE) + self.result = 1 + self.data: List[LinkedSiteRegCampaignUserData] = [] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data) + +class SaoGetHeroLogUnitUserDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_HERO_LOG_UNIT_USER_DATA_LIST_RESPONSE) + self.result = 1 + self.hero_log_unit_user_data_list: List[HeroLogUnitUserData] = [] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.hero_log_unit_user_data_list) + +class SaoGetCharaUnitUserDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_CHARA_UNIT_USER_DATA_LIST_RESPONSE) + self.result = 1 + self.chara_unit_user_data_list: List[CharaUnitUserData] = [] + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.chara_unit_user_data_list) + +class SaoBeginnerMissionAdConfirmNotificationRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.beginner_mission_id = decode_int(data, off) + off += INT_OFF + class SaoBnidSerialCodeCheckRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.bnid_serial_code, new_off = decode_str(data, off) + off += new_off class SaoBnidSerialCodeCheckResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) - + def __init__(self) -> None: + super().__init__(GameconnectCmd.BNID_SERIAL_CODE_CHECK_RESPONSE) self.result = 1 - self.bnid_item_id = "130050" + self.bnid_item_id = "" self.use_status = 0 - + def make(self) -> bytes: - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "bnid_item_id_size" / Int32ub, # big endian - "bnid_item_id" / Int16ul[len(self.bnid_item_id)], - "use_status" / Int8ul, # result is either 0 or 1 - ) + return super().make() \ + + encode_byte(self.result) \ + + encode_str(self.bnid_item_id) \ + + encode_byte(self.use_status) - resp_data = resp_struct.build(dict( - result=self.result, - bnid_item_id_size=len(self.bnid_item_id) * 2, - bnid_item_id=[ord(x) for x in self.bnid_item_id], - use_status=self.use_status, - )) +class SaoBnidSerialCodeEntryByAppendixCardRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off - self.length = len(resp_data) - return super().make() + resp_data + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.bnid_serial_code, new_off = decode_str(data, off) + off += new_off + +class SaoBnidSerialCodeEntryByAppendixCardResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.BNID_SERIAL_CODE_ENTRY_BY_APPENDIX_CARD_RESPONSE) + self.result = 1 + self.get_bnid_item_id = "" + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_str(self.get_bnid_item_id) + +class SaoDischargeProfileCardRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.hero_log_user_hero_log_id, new_off = decode_str(data, off) + off += new_off + + self.main_weapon_user_equipment_id, new_off = decode_str(data, off) + off += new_off + + self.sub_equipment_user_equipment_id, new_off = decode_str(data, off) + off += new_off + + self.skill_id = decode_int(data, off) + off += INT_OFF + self.text_chara_message_id = decode_int(data, off) + off += INT_OFF + + self.holographic_flag = decode_byte(data, off) + off += BYTE_OFF + self.execute_print_type = PrintType(decode_byte(data, off)) + off += BYTE_OFF + +class SaoDischargeProfileCardResponse(SaoBaseResponse): + def __init__(self, serial: str) -> None: + super().__init__(GameconnectCmd.DISCHARGE_PROFILE_CARD_RESPONSE) + self.result = 1 + self.profile_card_code = serial + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_str(self.profile_card_code) + +class SaoDischargeResourceCardRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.holographic_flag = decode_byte(data, off) + off += BYTE_OFF + + self.execute_print_type = PrintType(decode_byte(data, off)) + off += BYTE_OFF + + self.common_reward_user_data: List[MaterialCommonRewardUserData] = [] # typing lol + self.common_reward_user_data, new_off = decode_arr_cls(data, off, MaterialCommonRewardUserData) + off += new_off + +class SaoDischargeResourceCardResponse(SaoBaseResponse): + def __init__(self, serial: str) -> None: + super().__init__(GameconnectCmd.DISCHARGE_RESOURCE_CARD_RESPONSE) + self.result = 1 + self.profile_card_code = serial + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_str(self.profile_card_code) + +class SaoDischargeResourceCardCompleteRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.resource_card_code, new_off = decode_str(data, off) + off += new_off class SaoScanQrQuestProfileCardRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.profile_card_code, new_off = decode_str(data, off) + off += new_off class SaoScanQrQuestProfileCardResponse(SaoBaseResponse): - def __init__(self, cmd) -> None: - super().__init__(cmd) + def __init__(self) -> None: + super().__init__(GameconnectCmd.SCAN_QR_QUEST_PROFILE_CARD_RESPONSE) self.result = 1 - - # read_profile_card_data - self.profile_card_code = "1234123412341234123" # ID of the QR code - self.nick_name = "PLAYER" - self.rank_num = 1 #short - self.setting_title_id = 20005 #int - self.skill_id = 0 #short - self.hero_log_hero_log_id = 118000230 #int - self.hero_log_log_level = 1 #short - self.hero_log_awakening_stage = 1 #short - - self.hero_log_property1_property_id = 0 #int - self.hero_log_property1_value1 = 0 #int - self.hero_log_property1_value2 = 0 #int - self.hero_log_property2_property_id = 0 #int - self.hero_log_property2_value1 = 0 #int - self.hero_log_property2_value2 = 0 #int - self.hero_log_property3_property_id = 0 #int - self.hero_log_property3_value1 = 0 #int - self.hero_log_property3_value2 = 0 #int - self.hero_log_property4_property_id = 0 #int - self.hero_log_property4_value1 = 0 #int - self.hero_log_property4_value2 = 0 #int - - self.main_weapon_equipment_id = 0 #int - self.main_weapon_enhancement_value = 0 #short - self.main_weapon_awakening_stage = 0 #short - - self.main_weapon_property1_property_id = 0 #int - self.main_weapon_property1_value1 = 0 #int - self.main_weapon_property1_value2 = 0 #int - self.main_weapon_property2_property_id = 0 #int - self.main_weapon_property2_value1 = 0 #int - self.main_weapon_property2_value2 = 0 #int - self.main_weapon_property3_property_id = 0 #int - self.main_weapon_property3_value1 = 0 #int - self.main_weapon_property3_value2 = 0 #int - self.main_weapon_property4_property_id = 0 #int - self.main_weapon_property4_value1 = 0 #int - self.main_weapon_property4_value2 = 0 #int - - self.sub_equipment_equipment_id = 0 #int - self.sub_equipment_enhancement_value = 0 #short - self.sub_equipment_awakening_stage = 0 #short - - self.sub_equipment_property1_property_id = 0 #int - self.sub_equipment_property1_value1 = 0 #int - self.sub_equipment_property1_value2 = 0 #int - self.sub_equipment_property2_property_id = 0 #int - self.sub_equipment_property2_value1 = 0 #int - self.sub_equipment_property2_value2 = 0 #int - self.sub_equipment_property3_property_id = 0 #int - self.sub_equipment_property3_value1 = 0 #int - self.sub_equipment_property3_value2 = 0 #int - self.sub_equipment_property4_property_id = 0 #int - self.sub_equipment_property4_value1 = 0 #int - self.sub_equipment_property4_value2 = 0 #int - - self.holographic_flag = 1 #byte + self.profile_card_data: List[ReadProfileCard] = [] def make(self) -> bytes: - #new stuff + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.profile_card_data) - read_profile_card_data_struct = Struct( - "profile_card_code_size" / Int32ub, # big endian - "profile_card_code" / Int16ul[len(self.profile_card_code)], - "nick_name_size" / Int32ub, # big endian - "nick_name" / Int16ul[len(self.nick_name)], - "rank_num" / Int16ub, #short - "setting_title_id" / Int32ub, #int - "skill_id" / Int16ub, #short - "hero_log_hero_log_id" / Int32ub, #int - "hero_log_log_level" / Int16ub, #short - "hero_log_awakening_stage" / Int16ub, #short - - "hero_log_property1_property_id" / Int32ub, #int - "hero_log_property1_value1" / Int32ub, #int - "hero_log_property1_value2" / Int32ub, #int - "hero_log_property2_property_id" / Int32ub, #int - "hero_log_property2_value1" / Int32ub, #int - "hero_log_property2_value2" / Int32ub, #int - "hero_log_property3_property_id" / Int32ub, #int - "hero_log_property3_value1" / Int32ub, #int - "hero_log_property3_value2" / Int32ub, #int - "hero_log_property4_property_id" / Int32ub, #int - "hero_log_property4_value1" / Int32ub, #int - "hero_log_property4_value2" / Int32ub, #int - - "main_weapon_equipment_id" / Int32ub, #int - "main_weapon_enhancement_value" / Int16ub, #short - "main_weapon_awakening_stage" / Int16ub, #short - - "main_weapon_property1_property_id" / Int32ub, #int - "main_weapon_property1_value1" / Int32ub, #int - "main_weapon_property1_value2" / Int32ub, #int - "main_weapon_property2_property_id" / Int32ub, #int - "main_weapon_property2_value1" / Int32ub, #int - "main_weapon_property2_value2" / Int32ub, #int - "main_weapon_property3_property_id" / Int32ub, #int - "main_weapon_property3_value1" / Int32ub, #int - "main_weapon_property3_value2" / Int32ub, #int - "main_weapon_property4_property_id" / Int32ub, #int - "main_weapon_property4_value1" / Int32ub, #int - "main_weapon_property4_value2" / Int32ub, #int - - "sub_equipment_equipment_id" / Int32ub, #int - "sub_equipment_enhancement_value" / Int16ub, #short - "sub_equipment_awakening_stage" / Int16ub, #short - - "sub_equipment_property1_property_id" / Int32ub, #int - "sub_equipment_property1_value1" / Int32ub, #int - "sub_equipment_property1_value2" / Int32ub, #int - "sub_equipment_property2_property_id" / Int32ub, #int - "sub_equipment_property2_value1" / Int32ub, #int - "sub_equipment_property2_value2" / Int32ub, #int - "sub_equipment_property3_property_id" / Int32ub, #int - "sub_equipment_property3_value1" / Int32ub, #int - "sub_equipment_property3_value2" / Int32ub, #int - "sub_equipment_property4_property_id" / Int32ub, #int - "sub_equipment_property4_value1" / Int32ub, #int - "sub_equipment_property4_value2" / Int32ub, #int - - "holographic_flag" / Int8ul, # result is either 0 or 1 - - ) - - # create a resp struct - resp_struct = Struct( - "result" / Int8ul, # result is either 0 or 1 - "read_profile_card_data_size" / Rebuild(Int32ub, len_(this.read_profile_card_data)), # big endian - "read_profile_card_data" / Array(this.read_profile_card_data_size, read_profile_card_data_struct), - ) - - resp_data = resp_struct.parse(resp_struct.build(dict( - result=self.result, - read_profile_card_data_size=0, - read_profile_card_data=[], - ))) - - hero_data = dict( - profile_card_code_size=len(self.profile_card_code) * 2, - profile_card_code=[ord(x) for x in self.profile_card_code], - nick_name_size=len(self.nick_name) * 2, - nick_name=[ord(x) for x in self.nick_name], - - rank_num=self.rank_num, - setting_title_id=self.setting_title_id, - skill_id=self.skill_id, - hero_log_hero_log_id=self.hero_log_hero_log_id, - hero_log_log_level=self.hero_log_log_level, - hero_log_awakening_stage=self.hero_log_awakening_stage, - - hero_log_property1_property_id=self.hero_log_property1_property_id, - hero_log_property1_value1=self.hero_log_property1_value1, - hero_log_property1_value2=self.hero_log_property1_value2, - hero_log_property2_property_id=self.hero_log_property2_property_id, - hero_log_property2_value1=self.hero_log_property2_value1, - hero_log_property2_value2=self.hero_log_property2_value2, - hero_log_property3_property_id=self.hero_log_property3_property_id, - hero_log_property3_value1=self.hero_log_property3_value1, - hero_log_property3_value2=self.hero_log_property3_value2, - hero_log_property4_property_id=self.hero_log_property4_property_id, - hero_log_property4_value1=self.hero_log_property4_value1, - hero_log_property4_value2=self.hero_log_property4_value2, - - main_weapon_equipment_id=self.main_weapon_equipment_id, - main_weapon_enhancement_value=self.main_weapon_enhancement_value, - main_weapon_awakening_stage=self.main_weapon_awakening_stage, - - main_weapon_property1_property_id=self.main_weapon_property1_property_id, - main_weapon_property1_value1=self.main_weapon_property1_value1, - main_weapon_property1_value2=self.main_weapon_property1_value2, - main_weapon_property2_property_id=self.main_weapon_property2_property_id, - main_weapon_property2_value1=self.main_weapon_property2_value1, - main_weapon_property2_value2=self.main_weapon_property2_value2, - main_weapon_property3_property_id=self.main_weapon_property3_property_id, - main_weapon_property3_value1=self.main_weapon_property3_value1, - main_weapon_property3_value2=self.main_weapon_property3_value2, - main_weapon_property4_property_id=self.main_weapon_property4_property_id, - main_weapon_property4_value1=self.main_weapon_property4_value1, - main_weapon_property4_value2=self.main_weapon_property4_value2, - - sub_equipment_equipment_id=self.sub_equipment_equipment_id, - sub_equipment_enhancement_value=self.sub_equipment_enhancement_value, - sub_equipment_awakening_stage=self.sub_equipment_awakening_stage, - - sub_equipment_property1_property_id=self.sub_equipment_property1_property_id, - sub_equipment_property1_value1=self.sub_equipment_property1_value1, - sub_equipment_property1_value2=self.sub_equipment_property1_value2, - sub_equipment_property2_property_id=self.sub_equipment_property2_property_id, - sub_equipment_property2_value1=self.sub_equipment_property2_value1, - sub_equipment_property2_value2=self.sub_equipment_property2_value2, - sub_equipment_property3_property_id=self.sub_equipment_property3_property_id, - sub_equipment_property3_value1=self.sub_equipment_property3_value1, - sub_equipment_property3_value2=self.sub_equipment_property3_value2, - sub_equipment_property4_property_id=self.sub_equipment_property4_property_id, - sub_equipment_property4_value1=self.sub_equipment_property4_value1, - sub_equipment_property4_value2=self.sub_equipment_property4_value2, - - holographic_flag=self.holographic_flag, - ) +class SaoScanQrShopResourceCardRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off - resp_data.read_profile_card_data.append(hero_data) + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.resource_card_code, new_off = decode_str(data, off) + off += new_off - resp_data["read_profile_card_data_size"] = len(resp_data.read_profile_card_data) +class SaoScanQrQuestResourceCardRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.resource_card_code, new_off = decode_str(data, off) + off += new_off - # finally, rebuild the resp_data - resp_data = resp_struct.build(resp_data) - - self.length = len(resp_data) - return super().make() + resp_data +class SaoScanQrQuestResourceCardResponse(SaoBaseResponse): + def __init__(self, reward_type: int = 0, reward_id: int = 0, is_holo: bool = False) -> None: + super().__init__(GameconnectCmd.SCAN_QR_QUEST_RESOURCE_CARD_RESPONSE) + self.result = 1 + self.common_reward_type = reward_type + self.common_reward_id = reward_id + self.holographic_flag = is_holo + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_short(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_bool(self.holographic_flag) + class SaoConsumeCreditGuestRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) @@ -3047,7 +1694,7 @@ class SaoConsumeCreditGuestRequest(SaoBaseRequest): self.cab_type = decode_byte(data, off) off += BYTE_OFF - self.act_type = decode_byte(data, off) + self.act_type = ActTypeConsumeCredit(decode_byte(data, off)) off += BYTE_OFF self.consume_num = decode_byte(data, off) @@ -3065,20 +1712,14 @@ class SaoChangePartyRequest(SaoBaseRequest): self.user_id = user_id[0] off += user_id[1] - self.act_type = decode_byte(data, off) + self.act_type = ActTypeChangeParty(decode_byte(data, off)) off += BYTE_OFF - self.party_data_count = decode_int(data, off) - off += INT_OFF - self.party_data_list: List[PartyData] = [] + self.party_data_list, new_off = decode_arr_cls(data, off, PartyData) + off += new_off - for _ in range(self.party_data_count): - tmp = PartyData(data, off) - self.party_data_list.append(tmp) - off += tmp.get_size() - -class TrialTowerPlayEndUnanalyzedLogFixed(SaoBaseRequest): +class SaoTrialTowerPlayEndUnanalyzedLogFixedRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) off = 0 @@ -3096,17 +1737,20 @@ class TrialTowerPlayEndUnanalyzedLogFixed(SaoBaseRequest): self.rarity_up_exec_flag = decode_byte(data, off) off += BYTE_OFF -class GetShopResourceSalesDataListRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - off = 0 - user_id = decode_str(data, off) - self.user_id = user_id[0] - off += user_id[1] +class SaoTrialTowerPlayEndUnanalyzedLogFixedResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.TRIAL_TOWER_PLAY_END_UNANALYZED_LOG_FIXED_RESPONSE) + self.result = 1 + self.play_end_unanalyzed_log_reward_data_list: List[QuestScenePlayEndUnanalyzedLogRewardData] = [] -class GetShopResourceSalesDataListResponse(SaoBaseResponse): - def __init__(self, cmd_id: int) -> None: - super().__init__(cmd_id) + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.play_end_unanalyzed_log_reward_data_list) + +class SaoGetShopResourceSalesDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_SHOP_RESOURCE_SALES_DATA_LIST_RESPONSE) self.result = 1 # byte self.shop_resource_sales_data: List[ShopResourceSalesData] = [] @@ -3117,6 +1761,19 @@ class GetShopResourceSalesDataListResponse(SaoBaseResponse): self.header.length = len(ret) return super().make() + ret +class SaoPurchaseShopResourceRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.user_shop_resource_id, new_off = decode_str(data, off) + off += new_off + class GetYuiMedalShopUserDataListRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) @@ -3159,78 +1816,6 @@ class GetGashaMedalShopUserDataListResponse(SaoBaseResponse): self.header.length = len(ret) return super().make() + ret -class GetMYuiMedalShopDataRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - self.dummy = decode_byte(data, 0) - -class GetMYuiMedalShopDataResponse(SaoBaseResponse): - def __init__(self, cmd_id: int) -> None: - super().__init__(cmd_id) - self.result = 1 # byte - self.data_list: List[YuiMedalShopData] = [] - - def make(self) -> bytes: - ret = encode_byte(self.result) - ret += encode_arr_cls(self.data_list) - - self.header.length = len(ret) - return super().make() + ret - -class GetMYuiMedalShopItemsRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - self.dummy = decode_byte(data, 0) - -class GetMYuiMedalShopItemsResponse(SaoBaseResponse): - def __init__(self, cmd_id: int) -> None: - super().__init__(cmd_id) - self.result = 1 # byte - self.data_list: List[YuiMedalShopItemData] = [] - - def make(self) -> bytes: - ret = encode_byte(self.result) - ret += encode_arr_cls(self.data_list) - - self.header.length = len(ret) - return super().make() + ret - -class GetMGashaMedalShopsRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - self.dummy = decode_byte(data, 0) - -class GetMGashaMedalShopsResponse(SaoBaseResponse): - def __init__(self, cmd_id: int) -> None: - super().__init__(cmd_id) - self.result = 1 # byte - self.data_list: List[GashaMedalShop] = [] - - def make(self) -> bytes: - ret = encode_byte(self.result) - ret += encode_arr_cls(self.data_list) - - self.header.length = len(ret) - return super().make() + ret - -class GetMResEarnCampaignShopsRequest(SaoBaseRequest): - def __init__(self, header: SaoRequestHeader, data: bytes) -> None: - super().__init__(header, data) - self.dummy = decode_byte(data, 0) - -class GetMResEarnCampaignShopsResponse(SaoBaseResponse): - def __init__(self, cmd_id: int) -> None: - super().__init__(cmd_id) - self.result = 1 # byte - self.data_list: List[ResEarnCampaignShop] = [] - - def make(self) -> bytes: - ret = encode_byte(self.result) - ret += encode_arr_cls(self.data_list) - - self.header.length = len(ret) - return super().make() + ret - class SaoGiveFreeTicketRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) @@ -3244,15 +1829,6 @@ class SaoGiveFreeTicketRequest(SaoBaseRequest): self.give_num = decode_byte(data, off) off += BYTE_OFF -class SaoGiveFreeTicketResponse(SaoBaseResponse): - def __init__(self, cmd_id: int) -> None: - super().__init__(cmd_id) - self.result = 1 # byte - - def make(self) -> bytes: - ret = encode_byte(self.result) - return super().make() + ret - class SaoLogoutTicketUnpurchasedRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) @@ -3266,15 +1842,6 @@ class SaoLogoutTicketUnpurchasedRequest(SaoBaseRequest): self.cabinet_type = decode_byte(data, off) off += BYTE_OFF -class SaoLogoutTicketUnpurchasedResponse(SaoBaseResponse): - def __init__(self, cmd_id: int) -> None: - super().__init__(cmd_id) - self.result = 1 # byte - - def make(self) -> bytes: - ret = encode_byte(self.result) - return super().make() + ret - class SaoGetQuestHierarchyProgressDegreesRankingListRequest(SaoBaseRequest): def __init__(self, header: SaoRequestHeader, data: bytes) -> None: super().__init__(header, data) @@ -3322,3 +1889,2337 @@ class SaoGetQuestPopularHeroLogRankingListResponse(SaoBaseResponse): ret = encode_byte(self.result) ret += encode_arr_cls(self.quest_popular_hero_log_ranking_data_list) return super().make() + ret + +class SaoGetVariousTutorialDataListResponse(SaoBaseResponse): + def __init__(self) -> None: + super().__init__(GameconnectCmd.GET_VARIOUS_TUTORIAL_DATA_LIST_RESPONSE) + self.result = 1 + self.end_tutorial_type_list: List[int] = [] + + def make(self) -> bytes: + ret = encode_byte(self.result) + ret += encode_arr_num(self.end_tutorial_type_list, BYTE_OFF) + return super().make() + ret + +class SaoVariousTutorialEndRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ticket_id, new_off = decode_str(data, off) + off += new_off + self.user_id, new_off = decode_str(data, off) + off += new_off + self.tutorial_type = decode_byte(data, off) + off += BYTE_OFF + +class SaoGetMExTowersRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ex_tower_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMExTowerQuestsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.ex_tower_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMChatEventStoriesRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.event_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMTreasureHuntsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.treasure_hunt_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMTreasureHuntWholeTasksRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.treasure_hunt_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMTreasureHuntIndividualTasksRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.treasure_hunt_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMTreasureHuntSpecialEffectsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.treasure_hunt_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMTreasureHuntEventPointRewardCommonRewardsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.treasure_hunt_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMTreasureHuntEventPointRewardTitlesRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.treasure_hunt_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMDefragMatchesRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.defrag_match_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMDefragMatchSeedRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.defrag_match_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMDefragMatchSpecialEffectsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.defrag_match_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMDefragMatchGradesRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.defrag_match_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMDefragMatchPeriodBonusesRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.defrag_match_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMDefragMatchRandomBonusTablesRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.defrag_match_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMDefragMatchRareDropsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.defrag_match_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMEventScenesRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.event_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMBeginnerMissionConditionsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.beginner_mission_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMBeginnerMissionRewardsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.beginner_mission_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMBeginnerMissionSeatConditionsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.beginner_mission_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMBeginnerMissionSeatRewardsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.beginner_mission_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMEventMonstersRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.event_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMGashaMedalSettingsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.gasha_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMGashaMedalShopItemsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.gasha_medal_shop_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMResEarnCampaignApplicationProductsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.res_earn_campaign_application_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMResEarnCampaignShopItemsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.res_earn_campaign_shop_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMPlayCampaignRewardsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.play_campaign_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMLinkedSiteRegCampaignRewardsRequest(SaoBaseRequest): + def __init__(self, header: SaoRequestHeader, data: bytes) -> None: + super().__init__(header, data) + off = 0 + self.linked_site_reg_campaign_id_list, new_off = decode_arr_num(data, off, INT_OFF) + off += new_off + +class SaoGetMPlayerRanksResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_PLAYER_RANKS_RESPONSE) + self.result = 1 + self.data_list: List[PlayerRankData] = [] + + if data_list: + for item in data_list: + self.data_list.append(PlayerRankData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMTitlesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_TITLES_RESPONSE) + self.result = 1 + self.data_list: List[TitleData] = [] + + if data_list: + for item in data_list: + self.data_list.append(TitleData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMFragmentsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_FRAGMENTS_RESPONSE) + self.result = 1 + self.data_list: List[FragmentData] = [] + + if data_list: + for item in data_list: + self.data_list.append(FragmentData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMRewardTablesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_REWARD_TABLES_RESPONSE) + self.result = 1 + self.data_list: List[RewardTableData] = [] + + if data_list: + for item in data_list: + self.data_list.append(RewardTableData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMRewardSetsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_REWARD_SETS_RESPONSE) + self.result = 1 + self.data_list: List[RewardSetData] = [] + + if data_list: + for item in data_list: + self.data_list.append(RewardSetData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMUnanalyzedLogGradesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_UNANALYZED_LOG_GRADES_RESPONSE) + self.result = 1 + self.data_list: List[UnanalyzedLogGradeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(UnanalyzedLogGradeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMAppointLeaderParamsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_APPOINT_LEADER_PARAMS_RESPONSE) + self.result = 1 + self.data_list: List[AppointLeaderParamData] = [] + + if data_list: + for item in data_list: + self.data_list.append(AppointLeaderParamData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMAppointLeaderEffectsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_APPOINT_LEADER_EFFECTS_RESPONSE) + self.result = 1 + self.data_list: List[AppointLeaderEffectData] = [] + + if data_list: + for item in data_list: + self.data_list.append(AppointLeaderEffectData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMAppointLeaderEffectTypesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_APPOINT_LEADER_EFFECT_TYPES_RESPONSE) + self.result = 1 + self.data_list: List[AppointLeaderEffectTypeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(AppointLeaderEffectTypeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMRaritiesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_RARITIES_RESPONSE) + self.result = 1 + self.data_list: List[RarityData] = [] + + if data_list: + for item in data_list: + self.data_list.append(RarityData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMCompositionEventsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_COMPOSITION_EVENTS_RESPONSE) + self.result = 1 + self.data_list: List[CompositionEventData] = [] + + if data_list: + for item in data_list: + self.data_list.append(CompositionEventData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMCompositionParamsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_COMPOSITION_PARAMS_RESPONSE) + self.result = 1 + self.data_list: List[CompositionParamData] = [] + + if data_list: + for item in data_list: + self.data_list.append(CompositionParamData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGamePlayPricesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GAME_PLAY_PRICES_RESPONSE) + self.result = 1 + self.data_list: List[GamePlayPriceData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GamePlayPriceData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBuyTicketsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BUY_TICKETS_RESPONSE) + self.result = 1 + self.data_list: List[BuyTicketData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BuyTicketData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMTipsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_TIPS_RESPONSE) + self.result = 1 + self.data_list: List[TipsData] = [] + + if data_list: + for item in data_list: + self.data_list.append(TipsData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMCapsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_CAPS_RESPONSE) + self.result = 1 + self.data_list: List[CapData] = [] + + if data_list: + for item in data_list: + self.data_list.append(CapData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMHeroLogResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_HERO_LOG_RESPONSE) + self.result = 1 + self.data_list: List[HeroLogData] = [] + + if data_list: + for item in data_list: + self.data_list.append(HeroLogData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMHeroLogLevelsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_HERO_LOG_LEVELS_RESPONSE) + self.result = 1 + self.data_list: List[HeroLogLevelData] = [] + + if data_list: + for item in data_list: + self.data_list.append(HeroLogLevelData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMHeroLogRolesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_HERO_LOG_ROLES_RESPONSE) + self.result = 1 + self.data_list: List[HeroLogRoleData] = [] + + if data_list: + for item in data_list: + self.data_list.append(HeroLogRoleData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMHeroLogTrustRanksResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_HERO_LOG_TRUST_RANKS_RESPONSE) + self.result = 1 + self.data_list: List[HeroLogTrustRankData] = [] + + if data_list: + for item in data_list: + self.data_list.append(HeroLogTrustRankData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMCharasResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_CHARAS_RESPONSE) + self.result = 1 + self.data_list: List[CharaData] = [] + + if data_list: + for item in data_list: + self.data_list.append(CharaData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMCharaFriendlyRanksResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_CHARA_FRIENDLY_RANKS_RESPONSE) + self.result = 1 + self.data_list: List[CharaFriendlyRankData] = [] + + if data_list: + for item in data_list: + self.data_list.append(CharaFriendlyRankData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEquipmentsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EQUIPMENTS_RESPONSE) + self.result = 1 + self.data_list: List[EquipmentData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EquipmentData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEquipmentLevelsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EQUIPMENT_LEVELS_RESPONSE) + self.result = 1 + self.data_list: List[EquipmentLevelData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EquipmentLevelData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMWeaponTypesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_WEAPON_TYPES_RESPONSE) + self.result = 1 + self.data_list: List[WeaponTypeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(WeaponTypeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMItemsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_ITEMS_RESPONSE) + self.result = 1 + self.data_list: List[ItemData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ItemData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMItemTypesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_ITEM_TYPES_RESPONSE) + self.result = 1 + self.data_list: List[ItemTypeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ItemTypeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBuffItemsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BUFF_ITEMS_RESPONSE) + self.result = 1 + self.data_list: List[BuffItemData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BuffItemData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEnemiesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_ENEMIES_RESPONSE) + self.result = 1 + self.data_list: List[EnemyData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EnemyData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEnemySetsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_ENEMY_SETS_RESPONSE) + self.result = 1 + self.data_list: List[EnemySetData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EnemySetData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEnemyKindsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_ENEMY_KINDS_RESPONSE) + self.result = 1 + self.data_list: List[EnemyKindData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EnemyKindData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEnemyCategoriesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_ENEMY_CATEGORIES_RESPONSE) + self.result = 1 + self.data_list: List[EnemyCategoryData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EnemyCategoryData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMUnitsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_UNITS_RESPONSE) + self.result = 1 + self.data_list: List[UnitData] = [] + + if data_list: + for item in data_list: + self.data_list.append(UnitData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMUnitGimmicksResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_UNIT_GIMMICKS_RESPONSE) + self.result = 1 + self.data_list: List[UnitGimmickData] = [] + + if data_list: + for item in data_list: + self.data_list.append(UnitGimmickData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMUnitCollisionsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_UNIT_COLLISIONS_RESPONSE) + self.result = 1 + self.data_list: List[UnitCollisionData] = [] + + if data_list: + for item in data_list: + self.data_list.append(UnitCollisionData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMUnitPowersResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_UNIT_POWERS_RESPONSE) + self.result = 1 + self.data_list: List[UnitPowerData] = [] + + if data_list: + for item in data_list: + self.data_list.append(UnitPowerData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGimmickAttacksResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GIMMICK_ATTACKS_RESPONSE) + self.result = 1 + self.data_list: List[GimmickAttackData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GimmickAttackData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMCharaAttacksResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_CHARA_ATTACKS_RESPONSE) + self.result = 1 + self.data_list: List[CharaAttackData] = [] + + if data_list: + for item in data_list: + self.data_list.append(CharaAttackData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBossAttacksResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BOSS_ATTACKS_RESPONSE) + self.result = 1 + self.data_list: List[BossAttackData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BossAttackData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMMonsterAttacksResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_MONSTER_ATTACKS_RESPONSE) + self.result = 1 + self.data_list: List[MonsterAttackData] = [] + + if data_list: + for item in data_list: + self.data_list.append(MonsterAttackData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMMonsterActionsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_MONSTER_ACTIONS_RESPONSE) + self.result = 1 + self.data_list: List[MonsterActionData] = [] + + if data_list: + for item in data_list: + self.data_list.append(MonsterActionData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMPropertiesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_PROPERTIES_RESPONSE) + self.result = 1 + self.data_list: List[PropertyData] = [] + + if data_list: + for item in data_list: + self.data_list.append(PropertyData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMPropertyTablesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_PROPERTY_TABLES_RESPONSE) + self.result = 1 + self.data_list: List[PropertyTableData] = [] + + if data_list: + for item in data_list: + self.data_list.append(PropertyTableData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMPropertyTypesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_PROPERTY_TYPES_RESPONSE) + self.result = 1 + self.data_list: List[PropertyTypeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(PropertyTypeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMSkillsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_SKILLS_RESPONSE) + self.result = 1 + self.data_list: List[SkillData] = [] + + if data_list: + for item in data_list: + self.data_list.append(SkillData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMSkillTablesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_SKILL_TABLES_RESPONSE) + self.result = 1 + self.data_list: List[SkillTableData] = [] + + if data_list: + for item in data_list: + self.data_list.append(SkillTableData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMSkillLevelsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_SKILL_LEVELS_RESPONSE) + self.result = 1 + self.data_list: List[SkillLevelData] = [] + + if data_list: + for item in data_list: + self.data_list.append(SkillLevelData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMAwakeningsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_AWAKENINGS_RESPONSE) + self.result = 1 + self.data_list: List[AwakeningData] = [] + + if data_list: + for item in data_list: + self.data_list.append(AwakeningData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMSynchroSkillsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_SYNCHRO_SKILLS_RESPONSE) + self.result = 1 + self.data_list: List[SynchroSkillData] = [] + + if data_list: + for item in data_list: + self.data_list.append(SynchroSkillData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMSoundSkillCutInVoicesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_SOUND_SKILL_CUT_IN_VOICES_RESPONSE) + self.result = 1 + self.data_list: List[SoundSkillCutInVoiceData] = [] + + if data_list: + for item in data_list: + self.data_list.append(SoundSkillCutInVoiceData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestScenesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_SCENES_RESPONSE) + self.result = 1 + self.data_list: List[QuestSceneData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestSceneData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestExistUnitsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_EXIST_UNITS_RESPONSE) + self.result = 1 + self.data_list: List[QuestExistUnitData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestExistUnitData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestEpisodeAppendRewardsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_EPISODE_APPEND_REWARDS_RESPONSE) + self.result = 1 + self.data_list: List[QuestEpisodeAppendRewardData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestEpisodeAppendRewardData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMSideQuestsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_SIDE_QUESTS_RESPONSE) + self.result = 1 + self.data_list: List[SideQuestData] = [] + + if data_list: + for item in data_list: + self.data_list.append(SideQuestData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEpisodesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EPISODES_RESPONSE) + self.result = 1 + self.data_list: List[EpisodeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EpisodeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEpisodeChaptersResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EPISODE_CHAPTERS_RESPONSE) + self.result = 1 + self.data_list: List[EpisodeChapterData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EpisodeChapterData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEpisodePartsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EPISODE_PARTS_RESPONSE) + self.result = 1 + self.data_list: List[EpisodePartData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EpisodePartData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMTrialTowersResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_TRIAL_TOWERS_RESPONSE) + self.result = 1 + self.data_list: List[TrialTowerData] = [] + + if data_list: + for item in data_list: + self.data_list.append(TrialTowerData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMExTowersResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EX_TOWERS_RESPONSE) + self.result = 1 + self.data_list: List[ExTowerData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ExTowerData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMExTowerQuestsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EX_TOWER_QUESTS_RESPONSE) + self.result = 1 + self.data_list: List[ExTowerQuestData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ExTowerQuestData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMMenuDisplayEnemiesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_MENU_DISPLAY_ENEMIES_RESPONSE) + self.result = 1 + self.data_list: List[MenuDisplayEnemyData] = [] + + if data_list: + for item in data_list: + self.data_list.append(MenuDisplayEnemyData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMMissionsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_MISSIONS_RESPONSE) + self.result = 1 + self.data_list: List[MissionData] = [] + + if data_list: + for item in data_list: + self.data_list.append(MissionData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMMissionTablesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_MISSION_TABLES_RESPONSE) + self.result = 1 + self.data_list: List[MissionTableData] = [] + + if data_list: + for item in data_list: + self.data_list.append(MissionTableData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMMissionDifficultiesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_MISSION_DIFFICULTIES_RESPONSE) + self.result = 1 + self.data_list: List[MissionDifficultyData] = [] + + if data_list: + for item in data_list: + self.data_list.append(MissionDifficultyData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBattleCamerasResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BATTLE_CAMERAS_RESPONSE) + self.result = 1 + self.data_list: List[BattleCameraData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BattleCameraData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMChatMainStoriesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_CHAT_MAIN_STORIES_RESPONSE) + self.result = 1 + self.data_list: List[ChatMainStoryData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ChatMainStoryData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMChatSideStoriesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_CHAT_SIDE_STORIES_RESPONSE) + self.result = 1 + self.data_list: List[ChatSideStoryData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ChatSideStoryData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMChatEventStoriesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_CHAT_EVENT_STORIES_RESPONSE) + self.result = 1 + self.data_list: List[ChatEventStoryData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ChatEventStoryData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMNavigatorCharasResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_NAVIGATOR_CHARAS_RESPONSE) + self.result = 1 + self.data_list: List[NavigatorCharaData] = [] + + if data_list: + for item in data_list: + self.data_list.append(NavigatorCharaData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMNavigatorCommentsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_NAVIGATOR_COMMENTS_RESPONSE) + self.result = 1 + self.data_list: List[NavigatorCommentData] = [] + + if data_list: + for item in data_list: + self.data_list.append(NavigatorCommentData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMExBonusTablesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EX_BONUS_TABLES_RESPONSE) + self.result = 1 + self.data_list: List[ExBonusTableData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ExBonusTableData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMExBonusConditionsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EX_BONUS_CONDITIONS_RESPONSE) + self.result = 1 + self.data_list: List[ExBonusConditionData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ExBonusConditionData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestRareDropsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_RARE_DROPS_RESPONSE) + self.result = 1 + self.data_list: List[QuestRareDropData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestRareDropData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestSpecialRareDropSettingsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_SPECIAL_RARE_DROP_SETTINGS_RESPONSE) + self.result = 1 + self.data_list: List[QuestSpecialRareDropSettingData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestSpecialRareDropSettingData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestSpecialRareDropsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_SPECIAL_RARE_DROPS_RESPONSE) + self.result = 1 + self.data_list: List[QuestSpecialRareDropData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestSpecialRareDropData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestTutorialsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_TUTORIALS_RESPONSE) + self.result = 1 + self.data_list: List[QuestTutorialData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestTutorialData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestPlayerTraceTablesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_PLAYER_TRACE_TABLES_RESPONSE) + self.result = 1 + self.data_list: List[QuestPlayerTraceTableData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestPlayerTraceTableData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestStillsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_STILLS_RESPONSE) + self.result = 1 + self.data_list: List[QuestStillData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestStillData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashasResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHAS_RESPONSE) + self.result = 1 + self.data_list: List[GashaData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashaHeadersResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHA_HEADERS_RESPONSE) + self.result = 1 + self.data_list: List[GashaHeaderData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaHeaderData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashaLotteryRaritiesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHA_LOTTERY_RARITIES_RESPONSE) + self.result = 1 + self.data_list: List[GashaLotteryRarityData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaLotteryRarityData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashaPrizesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHA_PRIZES_RESPONSE) + self.result = 1 + self.data_list: List[GashaPrizeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaPrizeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMComebackEventsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_COMEBACK_EVENTS_RESPONSE) + self.result = 1 + self.data_list: List[ComebackEventData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ComebackEventData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMAdBannersResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_AD_BANNERS_RESPONSE) + self.result = 1 + self.data_list: List[AdBannerData] = [] + + if data_list: + for item in data_list: + self.data_list.append(AdBannerData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEventsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EVENTS_RESPONSE) + self.result = 1 + self.data_list: List[EventsData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EventsData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMTreasureHuntsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_TREASURE_HUNTS_RESPONSE) + self.result = 1 + self.data_list: List[TreasureHuntsData] = [] + + if data_list: + for item in data_list: + self.data_list.append(TreasureHuntsData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMTreasureHuntWholeTasksResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_TREASURE_HUNT_WHOLE_TASKS_RESPONSE) + self.result = 1 + self.data_list: List[TreasureHuntWholeTasksData] = [] + + if data_list: + for item in data_list: + self.data_list.append(TreasureHuntWholeTasksData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMTreasureHuntIndividualTasksResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_TREASURE_HUNT_INDIVIDUAL_TASKS_RESPONSE) + self.result = 1 + self.data_list: List[TreasureHuntIndividualTasksData] = [] + + if data_list: + for item in data_list: + self.data_list.append(TreasureHuntIndividualTasksData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMTreasureHuntSpecialEffectsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_TREASURE_HUNT_SPECIAL_EFFECTS_RESPONSE) + self.result = 1 + self.data_list: List[TreasureHuntSpecialEffectsData] = [] + + if data_list: + for item in data_list: + self.data_list.append(TreasureHuntSpecialEffectsData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMTreasureHuntEventPointRewardCommonRewardsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_TREASURE_HUNT_EVENT_POINT_REWARD_COMMON_REWARDS_RESPONSE) + self.result = 1 + self.data_list: List[TreasureHuntEventPointRewardCommonRewardsData] = [] + + if data_list: + for item in data_list: + self.data_list.append(TreasureHuntEventPointRewardCommonRewardsData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMTreasureHuntEventPointRewardTitlesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_TREASURE_HUNT_EVENT_POINT_REWARD_TITLES_RESPONSE) + self.result = 1 + self.data_list: List[TreasureHuntEventPointRewardTitlesData] = [] + + if data_list: + for item in data_list: + self.data_list.append(TreasureHuntEventPointRewardTitlesData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMTreasureHuntTaskTextsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_TREASURE_HUNT_TASK_TEXTS_RESPONSE) + self.result = 1 + self.data_list: List[TreasureHuntTaskTextData] = [] + + if data_list: + for item in data_list: + self.data_list.append(TreasureHuntTaskTextData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBnidSerialCodesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BNID_SERIAL_CODES_RESPONSE) + self.result = 1 + self.data_list: List[BnidSerialCodeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BnidSerialCodeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBnidSerialCodeRewardsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BNID_SERIAL_CODE_REWARDS_RESPONSE) + self.result = 1 + self.data_list: List[BnidSerialCodeRewardData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BnidSerialCodeRewardData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMSupportLogResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_SUPPORT_LOG_RESPONSE) + self.result = 1 + self.data_list: List[SupportLogData] = [] + + if data_list: + for item in data_list: + self.data_list.append(SupportLogData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMSupportLogTypesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_SUPPORT_LOG_TYPES_RESPONSE) + self.result = 1 + self.data_list: List[SupportLogTypeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(SupportLogTypeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEpisodeAppendsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EPISODE_APPENDS_RESPONSE) + self.result = 1 + self.data_list: List[EpisodeAppendData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EpisodeAppendData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestDefragMatchQuestsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_DEFRAG_MATCH_QUESTS_RESPONSE) + self.result = 1 + self.data_list: List[QuestDefragMatchQuestData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestDefragMatchQuestData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestDefragMatchQuestBossTablesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_DEFRAG_MATCH_QUEST_BOSS_TABLES_RESPONSE) + self.result = 1 + self.data_list: List[QuestDefragMatchQuestBossTableData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestDefragMatchQuestBossTableData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMDefragMatchesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_DEFRAG_MATCHES_RESPONSE) + self.result = 1 + self.data_list: List[DefragMatchData] = [] + + if data_list: + for item in data_list: + self.data_list.append(DefragMatchData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMDefragMatchSeedResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_DEFRAG_MATCH_SEED_RESPONSE) + self.result = 1 + self.data_list: List[DefragMatchSeedData] = [] + + if data_list: + for item in data_list: + self.data_list.append(DefragMatchSeedData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMDefragMatchSpecialEffectsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_DEFRAG_MATCH_SPECIAL_EFFECTS_RESPONSE) + self.result = 1 + self.data_list: List[DefragMatchSpecialEffectData] = [] + + if data_list: + for item in data_list: + self.data_list.append(DefragMatchSpecialEffectData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMDefragMatchGradesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_DEFRAG_MATCH_GRADES_RESPONSE) + self.result = 1 + self.data_list: List[DefragMatchGradeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(DefragMatchGradeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMDefragMatchCpuUnitsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_DEFRAG_MATCH_CPU_UNITS_RESPONSE) + self.result = 1 + self.data_list: List[DefragMatchCpuUnitData] = [] + + if data_list: + for item in data_list: + self.data_list.append(DefragMatchCpuUnitData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMDefragMatchCpuSupportLogsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_DEFRAG_MATCH_CPU_SUPPORT_LOGS_RESPONSE) + self.result = 1 + self.data_list: List[DefragMatchCpuSupportLogData] = [] + + if data_list: + for item in data_list: + self.data_list.append(DefragMatchCpuSupportLogData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMDefragMatchPeriodBonusesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_DEFRAG_MATCH_PERIOD_BONUSES_RESPONSE) + self.result = 1 + self.data_list: List[DefragMatchPeriodBonusData] = [] + + if data_list: + for item in data_list: + self.data_list.append(DefragMatchPeriodBonusData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMDefragMatchRandomBonusTablesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_DEFRAG_MATCH_RANDOM_BONUS_TABLES_RESPONSE) + self.result = 1 + self.data_list: List[DefragMatchRandomBonusTableData] = [] + + if data_list: + for item in data_list: + self.data_list.append(DefragMatchRandomBonusTableData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMDefragMatchRandomBonusConditionsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_DEFRAG_MATCH_RANDOM_BONUS_CONDITIONS_RESPONSE) + self.result = 1 + self.data_list: List[DefragMatchRandomBonusConditionData] = [] + + if data_list: + for item in data_list: + self.data_list.append(DefragMatchRandomBonusConditionData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMDefragMatchRareDropsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_DEFRAG_MATCH_RARE_DROPS_RESPONSE) + self.result = 1 + self.data_list: List[DefragMatchRareDropData] = [] + + if data_list: + for item in data_list: + self.data_list.append(DefragMatchRareDropData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMYuiMedalShopsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_YUI_MEDAL_SHOPS_RESPONSE) + self.result = 1 + self.data_list: List[YuiMedalShopData] = [] + + if data_list: + for item in data_list: + self.data_list.append(YuiMedalShopData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMYuiMedalShopItemsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_YUI_MEDAL_SHOP_ITEMS_RESPONSE) + self.result = 1 + self.data_list: List[YuiMedalShopItemData] = [] + + if data_list: + for item in data_list: + self.data_list.append(YuiMedalShopItemData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEventScenesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EVENT_SCENES_RESPONSE) + self.result = 1 + self.data_list: List[EventSceneData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EventSceneData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGenericCampaignPeriodsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GENERIC_CAMPAIGN_PERIODS_RESPONSE) + self.result = 1 + self.data_list: List[GenericCampaignPeriodData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GenericCampaignPeriodData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBeginnerMissionsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BEGINNER_MISSIONS_RESPONSE) + self.result = 1 + self.data_list: List[BeginnerMissionData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BeginnerMissionData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBeginnerMissionConditionsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BEGINNER_MISSION_CONDITIONS_RESPONSE) + self.result = 1 + self.data_list: List[BeginnerMissionConditionData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BeginnerMissionConditionData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBeginnerMissionRewardsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BEGINNER_MISSION_REWARDS_RESPONSE) + self.result = 1 + self.data_list: List[BeginnerMissionRewardData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BeginnerMissionRewardData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBeginnerMissionSeatConditionsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BEGINNER_MISSION_SEAT_CONDITIONS_RESPONSE) + self.result = 1 + self.data_list: List[BeginnerMissionSeatConditionData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BeginnerMissionSeatConditionData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMBeginnerMissionSeatRewardsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_BEGINNER_MISSION_SEAT_REWARDS_RESPONSE) + self.result = 1 + self.data_list: List[BeginnerMissionSeatRewardData] = [] + + if data_list: + for item in data_list: + self.data_list.append(BeginnerMissionSeatRewardData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEventItemsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EVENT_ITEMS_RESPONSE) + self.result = 1 + self.data_list: List[EventItemData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EventItemData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMEventMonstersResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_EVENT_MONSTERS_RESPONSE) + self.result = 1 + self.data_list: List[EventMonsterData] = [] + + if data_list: + for item in data_list: + self.data_list.append(EventMonsterData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMYuiMedalBonusesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_YUI_MEDAL_BONUSES_RESPONSE) + self.result = 1 + self.data_list: List[YuiMedalBonusData] = [] + + if data_list: + for item in data_list: + self.data_list.append(YuiMedalBonusData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMYuiMedalBonusConditionsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_YUI_MEDAL_BONUS_CONDITIONS_RESPONSE) + self.result = 1 + self.data_list: List[YuiMedalBonusConditionData] = [] + + if data_list: + for item in data_list: + self.data_list.append(YuiMedalBonusConditionData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashaMedalsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHA_MEDALS_RESPONSE) + self.result = 1 + self.data_list: List[GashaMedalData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaMedalData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashaMedalTypesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHA_MEDAL_TYPES_RESPONSE) + self.result = 1 + self.data_list: List[GashaMedalTypeData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaMedalTypeData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashaMedalSettingsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHA_MEDAL_SETTINGS_RESPONSE) + self.result = 1 + self.data_list: List[GashaMedalSettingData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaMedalSettingData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashaMedalBonusesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHA_MEDAL_BONUSES_RESPONSE) + self.result = 1 + self.data_list: List[GashaMedalBonusData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaMedalBonusData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashaMedalShopsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHA_MEDAL_SHOPS_RESPONSE) + self.result = 1 + self.data_list: List[GashaMedalShopData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaMedalShopData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashaMedalShopItemsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHA_MEDAL_SHOP_ITEMS_RESPONSE) + self.result = 1 + self.data_list: List[GashaMedalShopItemData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaMedalShopItemData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMResEarnCampaignApplicationsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_RES_EARN_CAMPAIGN_APPLICATIONS_RESPONSE) + self.result = 1 + self.data_list: List[ResEarnCampaignApplicationData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ResEarnCampaignApplicationData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMResEarnCampaignApplicationProductsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_RES_EARN_CAMPAIGN_APPLICATION_PRODUCTS_RESPONSE) + self.result = 1 + self.data_list: List[ResEarnCampaignApplicationProductData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ResEarnCampaignApplicationProductData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMResEarnCampaignShopsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_RES_EARN_CAMPAIGN_SHOPS_RESPONSE) + self.result = 1 + self.data_list: List[ResEarnCampaignShopData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ResEarnCampaignShopData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMResEarnCampaignShopItemsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_RES_EARN_CAMPAIGN_SHOP_ITEMS_RESPONSE) + self.result = 1 + self.data_list: List[ResEarnCampaignShopItemData] = [] + + if data_list: + for item in data_list: + self.data_list.append(ResEarnCampaignShopItemData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMPayingYuiMedalBonusesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_PAYING_YUI_MEDAL_BONUSES_RESPONSE) + self.result = 1 + self.data_list: List[PayingYuiMedalBonusData] = [] + + if data_list: + for item in data_list: + self.data_list.append(PayingYuiMedalBonusData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMAcLoginBonusesResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_AC_LOGIN_BONUSES_RESPONSE) + self.result = 1 + self.data_list: List[AcLoginBonusData] = [] + + if data_list: + for item in data_list: + self.data_list.append(AcLoginBonusData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMPlayCampaignsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_PLAY_CAMPAIGNS_RESPONSE) + self.result = 1 + self.data_list: List[PlayCampaignData] = [] + + if data_list: + for item in data_list: + self.data_list.append(PlayCampaignData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMPlayCampaignRewardsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_PLAY_CAMPAIGN_REWARDS_RESPONSE) + self.result = 1 + self.data_list: List[PlayCampaignRewardData] = [] + + if data_list: + for item in data_list: + self.data_list.append(PlayCampaignRewardData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMGashaFreeCampaignsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_GASHA_FREE_CAMPAIGNS_RESPONSE) + self.result = 1 + self.data_list: List[GashaFreeCampaignData] = [] + + if data_list: + for item in data_list: + self.data_list.append(GashaFreeCampaignData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMQuestDropBoostCampaignsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_QUEST_DROP_BOOST_CAMPAIGNS_RESPONSE) + self.result = 1 + self.data_list: List[QuestDropBoostCampaignData] = [] + + if data_list: + for item in data_list: + self.data_list.append(QuestDropBoostCampaignData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMFirstTicketPurchaseCampaignsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_FIRST_TICKET_PURCHASE_CAMPAIGNS_RESPONSE) + self.result = 1 + self.data_list: List[FirstTicketPurchaseCampaignData] = [] + + if data_list: + for item in data_list: + self.data_list.append(FirstTicketPurchaseCampaignData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMLinkedSiteRegCampaignsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_LINKED_SITE_REG_CAMPAIGNS_RESPONSE) + self.result = 1 + self.data_list: List[LinkedSiteRegCampaignsData] = [] + + if data_list: + for item in data_list: + self.data_list.append(LinkedSiteRegCampaignsData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + +class SaoGetMLinkedSiteRegCampaignRewardsResponse(SaoBaseResponse): + def __init__(self, data_list: List[Dict]) -> None: + super().__init__(GameconnectCmd.GET_M_LINKED_SITE_REG_CAMPAIGN_REWARDS_RESPONSE) + self.result = 1 + self.data_list: List[LinkedSiteRegCampaignRewardData] = [] + + if data_list: + for item in data_list: + self.data_list.append(LinkedSiteRegCampaignRewardData.from_args(item)) + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.result) \ + + encode_arr_cls(self.data_list) + diff --git a/titles/sao/handlers/helpers.py b/titles/sao/handlers/helpers.py index 97a15b2..6b91c7b 100644 --- a/titles/sao/handlers/helpers.py +++ b/titles/sao/handlers/helpers.py @@ -1,7 +1,8 @@ -from typing import Tuple, List, Optional +from typing import Tuple, List, Optional, Dict import struct import logging from datetime import datetime +from enum import IntEnum BIGINT_OFF = 16 LONG_OFF = 8 @@ -78,31 +79,64 @@ def decode_arr_str(data: bytes, offset: int) -> Tuple[List[str], int]: return (ret, size) +def decode_date_str(data: bytes, offset: int) -> Tuple[datetime, int]: + s, new_o = decode_str(data, offset) + return (prs_dt(s), new_o) + +def decode_bool(data: bytes, offset: int) -> bool: + return bool(decode_byte(data, offset)) + def encode_byte(data: int) -> bytes: - return struct.pack("!b", data) + if data is None: + return b"\0" + try: + return struct.pack("!b", int(data)) + except Exception as e: + logging.getLogger('sao').error(f"Failed to encode {data} as byte! - {e}") + return b"\0" def encode_short(data: int) -> bytes: - return struct.pack("!h", data) + if data is None: + return b"\0\0" + try: + return struct.pack("!h", int(data)) + except Exception as e: + logging.getLogger('sao').error(f"Failed to encode {data} as short! - {e}") + return b"\0\0" def encode_int(data: int) -> bytes: - return struct.pack("!i", data) + if data is None: + return b"\0\0\0\0" + try: + return struct.pack("!i", int(data)) + except Exception as e: + logging.getLogger('sao').error(f"Failed to encode {data} as int! - {e}") + return b"\0\0\0\0" def encode_long(data: int) -> bytes: - return struct.pack("!l", data) + if data is None: + return b"\0\0\0\0\0\0\0\0" + return struct.pack("!l", int(data)) def encode_bigint(data: int) -> bytes: - return struct.pack("!q", data) + if data is None: + return b"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" + return struct.pack("!q", int(data)) def encode_str(s: str) -> bytes: + if s is None: + return b"\0\0\0\0" try: - str_bytes = s.encode("utf-16-le", errors="replace") + str_bytes = str(s).encode("utf-16-le", errors="replace") str_len_bytes = struct.pack("!I", len(str_bytes)) return str_len_bytes + str_bytes - except: - logging.getLogger('sao').error(f"Failed to encode {s} as bytes!") + except Exception as e: + logging.getLogger('sao').error(f"Failed to encode {s} as bytes! - {e}") return b"" def encode_arr_num(data: List[int], element_size: int) -> bytes: + if data is None: + return b"\0\0\0\0" ret = encode_int(len(data)) if element_size == BYTE_OFF: @@ -126,6 +160,120 @@ def encode_arr_num(data: List[int], element_size: int) -> bytes: return ret +def encode_bool(b: bool) -> bytes: + if b is None: + return b"\0" + return encode_byte(int(b)) + +def encode_date_str(d: datetime) -> bytes: + return encode_str(fmt_dt(d)) + +class PrintType(IntEnum): + NONE = 0 + FromStorage = 1 + FromGasha = 2 + +class AuthType(IntEnum): + UNKNOWN = 0 + CARD = 1 + MOBLE = 2 + +class ActTypeConsumeTicket(IntEnum): + QuestEpisodeBeginner = 1 + QuestEpisode = 2 + QuestTrialTowerBeginner = 3 + QuestTrialTower = 4 + QuestPvEBeginner = 5 + QuestPvE = 6 + QuestContinue = 7 + QuesRarityUp = 8 + QuestEpisodeBoost = 9 + QuestTrialTowerBoost = 10 + QuestPvEBoost = 11 + CustomModeExtend = 21 + CustomModeRetry = 22 + YuiMedalShop = 31 + +class ActTypeChangeParty(IntEnum): + MANUAL = 1 + AUTO = 2 + +class ActTypeConsumeCredit(IntEnum): + PurchaseTicketA1 = 1 + PurchaseTicketA2 = 2 + PurchaseTicketA6 = 3 + PurchaseTicketB1 = 4 + PurchaseTicketB2 = 5 + PurchaseTicketB7 = 6 + PurchaseTicketC1 = 7 + PurchaseTicketC3 = 8 + PurchaseTicketC8 = 9 + PurchaseTicketD1 = 10 + PurchaseTicketD2 = 11 + PurchaseTicketD6 = 12 + PurchaseTicketE1 = 13 + PurchaseTicketE3 = 14 + PurchaseTicketE8 = 15 + PurchaseTicketF1 = 16 + PurchaseTicketF2 = 17 + PurchaseTicketF6 = 18 + QuestContinue = 21 + QuestRarityUp = 22 + GashaSatelite = 31 + GashaSateliteAdd1 = 32 + GashaSateliteAdd2 = 33 + GashaTerminal = 41 + GashaTerminalAdd1 = 42 + GashaTerminalAdd2 = 43 + ResourceDischarge = 44 + ResourceHolo = 45 + ProfileCardDischarge = 46 + ProfileCardHolo = 47 + +class ProtocolErrorNum(IntEnum): # header error_num field + SUCCESS = 0 + + ALREADY_LOGIN_DIFF = 1301 + ALREADY_LOGIN_SAME = 1302 + INVALID_AUTH_TYPE = 1303 + INVALID_CABINET_TYPE = 1304 + AMID_SERVER_CONNECT_ERROR = 1305 + AMID_INFO_REQUEST_ERROR = 1306 + NOT_EXIST_PLAY_DATA = 1307 + HAVE_NEVER_PLAYED_SATELLITE = 1308 + + RESOURCE_CARD_ERR1 = 4831 # ScanQRQuestProfileCard + RESOURCE_CARD_NOT_EXIST = 4832 + RESOURCE_CARD_ERR3 = 4833 # ScanQRQuestResourceCard / ScanQRShopResourceCard + RESOURCE_CARD_ERR6 = 4836 # ScanQRQuestResourceCard / ScanQRShopResourceCard + RESOURCE_CARD_ERR7 = 4837 # ScanQRQuestResourceCard / ScanQRShopResourceCard + RESOURCE_CARD_ERR8 = 4838 # ScanQRShopResourceCard + RESOURCE_CARD_ERR9 = 4839 # ScanQRQuestProfileCard + + CREDIT_GASHA_ERROR = 7111 + + PURCHASE_ERROR = 7711 + + PAYING_PLAY_END_ERROR = 9120 + + CODE_ANALYSIS_API_NOT_RESPONSE = 9201 + CODE_ANALYSIS_API_INIQUITY_SERIAL_CODE = 9202 + CODE_USE_API_USED_SERIAL_CODE = 9203 + CODE_USE_API_NOT_RESPONSE = 9206 + CODE_USE_API_NG = 9207 + CODE_USE_API_LOCK = 9208 + CODE_USE_API_MAINTENANCE = 9209 + CODE_ANALYSIS_API_NOT_MASTER_DATA = 9210 + CODE_ANALYSIS_API_EXPIRED_SERIAL_CODE = 9211 + +class ProtocolResult(IntEnum): # result field, if used + NONE = -1 + FAILED = 0 + SUCCESS = 1 + PARAM_ERROR = 2 + MAINTENANCE = 3 + CONNECT_ERROR = 99 + class BaseHelper: def __init__(self, data: bytes, offset: int) -> None: self._sz = 0 @@ -143,9 +291,10 @@ class BaseHelper: def decode_arr_cls(data: bytes, offset: int, cls: BaseHelper): size = 0 num_cls = decode_int(data, offset + size) + size += INT_OFF cls_type = type(cls) - ret: List[cls_type] = [] + ret: List[cls_type] = [] # type: ignore for _ in range(num_cls): tmp = cls(data, offset + size) size += tmp.get_size() @@ -171,65 +320,1303 @@ class MaterialCommonRewardUserData(BaseHelper): self.user_common_reward_id = user_common_reward_id[0] self._sz += user_common_reward_id[1] +class QuestScenePlayEndUnanalyzedLogRewardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.unanalyzed_log_grade_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_data, new_off = decode_arr_cls(data, off, CommonRewardData) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, grade: int, reward: Dict) -> "QuestScenePlayEndUnanalyzedLogRewardData": + ret = cls(b"\x00" * 8, 0) + ret.unanalyzed_log_grade_id = grade + ret.common_reward_data = [CommonRewardData.from_args(reward.get('CommonRewardType'), reward.get('CommonRewardId'), reward.get('CommonRewardNum'))] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.unanalyzed_log_grade_id) \ + + encode_arr_cls(self.common_reward_data) + class PartyTeamData(BaseHelper): - def __init__(self, data: bytes, offset: int) -> None: - sz = 0 - user_party_team_id = decode_str(data, offset + sz) - self.user_party_team_id = user_party_team_id[0] - sz += user_party_team_id[1] + def __init__(self, data: bytes, offset: int): + off = offset + self.user_party_team_id, new_off = decode_str(data, off) + off += new_off - self.arrangement_num = decode_byte(data, offset + sz) - sz += BYTE_OFF + self.arrangement_num = decode_byte(data, off) + off += BYTE_OFF - user_hero_log_id = decode_str(data, offset + sz) - self.user_hero_log_id = user_hero_log_id[0] - sz += user_hero_log_id[1] + self.user_hero_log_id, new_off = decode_str(data, off) + off += new_off - main_weapon_user_equipment_id = decode_str(data, offset + sz) - self.main_weapon_user_equipment_id = main_weapon_user_equipment_id[0] - sz += main_weapon_user_equipment_id[1] + self.main_weapon_user_equipment_id, new_off = decode_str(data, off) + off += new_off - sub_equipment_user_equipment_id = decode_str(data, offset + sz) - self.sub_equipment_user_equipment_id = sub_equipment_user_equipment_id[0] - sz += sub_equipment_user_equipment_id[1] + self.sub_equipment_user_equipment_id, new_off = decode_str(data, off) + off += new_off - self.skill_slot1_skill_id = decode_int(data, offset + sz) - sz += INT_OFF + self.skill_slot1_skill_id = decode_int(data, off) + off += INT_OFF - self.skill_slot2_skill_id = decode_int(data, offset + sz) - sz += INT_OFF + self.skill_slot2_skill_id = decode_int(data, off) + off += INT_OFF - self.skill_slot3_skill_id = decode_int(data, offset + sz) - sz += INT_OFF + self.skill_slot3_skill_id = decode_int(data, off) + off += INT_OFF - self.skill_slot4_skill_id = decode_int(data, offset + sz) - sz += INT_OFF + self.skill_slot4_skill_id = decode_int(data, off) + off += INT_OFF - self.skill_slot5_skill_id = decode_int(data, offset + sz) - sz += INT_OFF + self.skill_slot5_skill_id = decode_int(data, off) + off += INT_OFF - self._sz = sz + self._sz = off - offset + + @classmethod + def from_args(cls, party_team_id: str, arr_num: int, data: Dict) -> "PartyTeamData": + ret = cls(b"\x00" * 37, 0) + ret.user_party_team_id = party_team_id + ret.arrangement_num = arr_num + ret.user_hero_log_id = data['id'] + ret.main_weapon_user_equipment_id = data['main_weapon'] + ret.sub_equipment_user_equipment_id = data['sub_equipment'] + ret.skill_slot1_skill_id = data['skill_slot1_skill_id'] + ret.skill_slot2_skill_id = data['skill_slot2_skill_id'] + ret.skill_slot3_skill_id = data['skill_slot3_skill_id'] + ret.skill_slot4_skill_id = data['skill_slot4_skill_id'] + ret.skill_slot5_skill_id = data['skill_slot5_skill_id'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_party_team_id) \ + + encode_byte(self.arrangement_num) \ + + encode_str(self.user_hero_log_id) \ + + encode_str(self.main_weapon_user_equipment_id) \ + + encode_str(self.sub_equipment_user_equipment_id) \ + + encode_int(self.skill_slot1_skill_id) \ + + encode_int(self.skill_slot2_skill_id) \ + + encode_int(self.skill_slot3_skill_id) \ + + encode_int(self.skill_slot4_skill_id) \ + + encode_int(self.skill_slot5_skill_id) + +class CommonRewardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.common_reward_type = decode_short(data, off) + off += SHORT_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, reward_type: int, reward_id: int, reward_num: int) -> "CommonRewardData": + ret = cls(b"\x00" * 10, 0) + ret.common_reward_type = reward_type + ret.common_reward_id = reward_id + ret.common_reward_num = reward_num + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_int(self.common_reward_num) + +class ReadProfileCardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.profile_card_code, new_off = decode_str(data, off) + off += new_off + + self.nick_name, new_off = decode_str(data, off) + off += new_off + + self.rank_num = decode_short(data, off) + off += SHORT_OFF + + self.setting_title_id = decode_int(data, off) + off += INT_OFF + + self.skill_id = decode_short(data, off) + off += SHORT_OFF + + self.hero_log_hero_log_id = decode_int(data, off) + off += INT_OFF + + self.hero_log_log_level = decode_short(data, off) + off += SHORT_OFF + + self.hero_log_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.hero_log_property1_property_id = decode_int(data, off) + off += INT_OFF + + self.hero_log_property1_value1 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property1_value2 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property2_property_id = decode_int(data, off) + off += INT_OFF + + self.hero_log_property2_value1 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property2_value2 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property3_property_id = decode_int(data, off) + off += INT_OFF + + self.hero_log_property3_value1 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property3_value2 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property4_property_id = decode_int(data, off) + off += INT_OFF + + self.hero_log_property4_value1 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property4_value2 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_equipment_id = decode_int(data, off) + off += INT_OFF + + self.main_weapon_enhancement_value = decode_short(data, off) + off += SHORT_OFF + + self.main_weapon_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.main_weapon_property1_property_id = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property1_value1 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property1_value2 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property2_property_id = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property2_value1 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property2_value2 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property3_property_id = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property3_value1 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property3_value2 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property4_property_id = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property4_value1 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property4_value2 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_equipment_id = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_enhancement_value = decode_short(data, off) + off += SHORT_OFF + + self.sub_equipment_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.sub_equipment_property1_property_id = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property1_value1 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property1_value2 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property2_property_id = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property2_value1 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property2_value2 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property3_property_id = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property3_value1 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property3_value2 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property4_property_id = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property4_value1 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property4_value2 = decode_int(data, off) + off += INT_OFF + + self.holographic_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, user_profile: Dict, hero_data: Dict) -> "ReadProfileCardData": + ret = cls(b"\x00" * 185, 0) + # TODO: real data + ret.profile_card_code = "" + ret.nick_name = "" + ret.rank_num = 0 + ret.setting_title_id = 0 + ret.skill_id = 0 + ret.hero_log_hero_log_id = 0 + ret.hero_log_log_level = 0 + ret.hero_log_awakening_stage = 0 + ret.hero_log_property1_property_id = 0 + ret.hero_log_property1_value1 = 0 + ret.hero_log_property1_value2 = 0 + ret.hero_log_property2_property_id = 0 + ret.hero_log_property2_value1 = 0 + ret.hero_log_property2_value2 = 0 + ret.hero_log_property3_property_id = 0 + ret.hero_log_property3_value1 = 0 + ret.hero_log_property3_value2 = 0 + ret.hero_log_property4_property_id = 0 + ret.hero_log_property4_value1 = 0 + ret.hero_log_property4_value2 = 0 + ret.main_weapon_equipment_id = 0 + ret.main_weapon_enhancement_value = 0 + ret.main_weapon_awakening_stage = 0 + ret.main_weapon_property1_property_id = 0 + ret.main_weapon_property1_value1 = 0 + ret.main_weapon_property1_value2 = 0 + ret.main_weapon_property2_property_id = 0 + ret.main_weapon_property2_value1 = 0 + ret.main_weapon_property2_value2 = 0 + ret.main_weapon_property3_property_id = 0 + ret.main_weapon_property3_value1 = 0 + ret.main_weapon_property3_value2 = 0 + ret.main_weapon_property4_property_id = 0 + ret.main_weapon_property4_value1 = 0 + ret.main_weapon_property4_value2 = 0 + ret.sub_equipment_equipment_id = 0 + ret.sub_equipment_enhancement_value = 0 + ret.sub_equipment_awakening_stage = 0 + ret.sub_equipment_property1_property_id = 0 + ret.sub_equipment_property1_value1 = 0 + ret.sub_equipment_property1_value2 = 0 + ret.sub_equipment_property2_property_id = 0 + ret.sub_equipment_property2_value1 = 0 + ret.sub_equipment_property2_value2 = 0 + ret.sub_equipment_property3_property_id = 0 + ret.sub_equipment_property3_value1 = 0 + ret.sub_equipment_property3_value2 = 0 + ret.sub_equipment_property4_property_id = 0 + ret.sub_equipment_property4_value1 = 0 + ret.sub_equipment_property4_value2 = 0 + ret.holographic_flag = 0 + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.profile_card_code) \ + + encode_str(self.nick_name) \ + + encode_short(self.rank_num) \ + + encode_int(self.setting_title_id) \ + + encode_short(self.skill_id) \ + + encode_int(self.hero_log_hero_log_id) \ + + encode_short(self.hero_log_log_level) \ + + encode_short(self.hero_log_awakening_stage) \ + + encode_int(self.hero_log_property1_property_id) \ + + encode_int(self.hero_log_property1_value1) \ + + encode_int(self.hero_log_property1_value2) \ + + encode_int(self.hero_log_property2_property_id) \ + + encode_int(self.hero_log_property2_value1) \ + + encode_int(self.hero_log_property2_value2) \ + + encode_int(self.hero_log_property3_property_id) \ + + encode_int(self.hero_log_property3_value1) \ + + encode_int(self.hero_log_property3_value2) \ + + encode_int(self.hero_log_property4_property_id) \ + + encode_int(self.hero_log_property4_value1) \ + + encode_int(self.hero_log_property4_value2) \ + + encode_int(self.main_weapon_equipment_id) \ + + encode_short(self.main_weapon_enhancement_value) \ + + encode_short(self.main_weapon_awakening_stage) \ + + encode_int(self.main_weapon_property1_property_id) \ + + encode_int(self.main_weapon_property1_value1) \ + + encode_int(self.main_weapon_property1_value2) \ + + encode_int(self.main_weapon_property2_property_id) \ + + encode_int(self.main_weapon_property2_value1) \ + + encode_int(self.main_weapon_property2_value2) \ + + encode_int(self.main_weapon_property3_property_id) \ + + encode_int(self.main_weapon_property3_value1) \ + + encode_int(self.main_weapon_property3_value2) \ + + encode_int(self.main_weapon_property4_property_id) \ + + encode_int(self.main_weapon_property4_value1) \ + + encode_int(self.main_weapon_property4_value2) \ + + encode_int(self.sub_equipment_equipment_id) \ + + encode_short(self.sub_equipment_enhancement_value) \ + + encode_short(self.sub_equipment_awakening_stage) \ + + encode_int(self.sub_equipment_property1_property_id) \ + + encode_int(self.sub_equipment_property1_value1) \ + + encode_int(self.sub_equipment_property1_value2) \ + + encode_int(self.sub_equipment_property2_property_id) \ + + encode_int(self.sub_equipment_property2_value1) \ + + encode_int(self.sub_equipment_property2_value2) \ + + encode_int(self.sub_equipment_property3_property_id) \ + + encode_int(self.sub_equipment_property3_value1) \ + + encode_int(self.sub_equipment_property3_value2) \ + + encode_int(self.sub_equipment_property4_property_id) \ + + encode_int(self.sub_equipment_property4_value1) \ + + encode_int(self.sub_equipment_property4_value2) \ + + encode_byte(self.holographic_flag) + +class QuestSceneBestScoreUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.clear_time = decode_int(data, off) + off += INT_OFF + + self.combo_num = decode_int(data, off) + off += INT_OFF + + self.total_damage, new_off = decode_str(data, off) + off += new_off + + self.concurrent_destroying_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestSceneBestScoreUserData": + ret = cls(b"\x00" * 14, 0) + ret.clear_time = data['clear_time'] + ret.combo_num = data['combo_num'] + ret.total_damage = data['total_damage'] + ret.concurrent_destroying_num = data['concurrent_destroying_num'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.clear_time) \ + + encode_int(self.combo_num) \ + + encode_str(self.total_damage) \ + + encode_short(self.concurrent_destroying_num) + +class QuestSceneExBonusUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.ex_bonus_table_id = decode_int(data, off) + off += INT_OFF + + self.achievement_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, table_id: int = 0, ach_flag: bool = False) -> "QuestSceneExBonusUserData": + ret = cls(b"\x00" * 5, 0) + ret.ex_bonus_table_id = table_id + ret.achievement_flag = ach_flag + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.ex_bonus_table_id) \ + + encode_byte(self.achievement_flag) + +class QuestSceneUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_type = decode_byte(data, off) + off += BYTE_OFF + + self.quest_scene_id = decode_short(data, off) + off += SHORT_OFF + + self.clear_flag = decode_byte(data, off) + off += BYTE_OFF + + self.quest_scene_best_score_user_data: List[QuestSceneBestScoreUserData] = [] + self.quest_scene_best_score_user_data, new_off = decode_arr_cls(data, off, QuestSceneBestScoreUserData) + off += new_off + + self.quest_scene_ex_bonus_user_data_list: List[QuestSceneExBonusUserData] = [] + self.quest_scene_ex_bonus_user_data_list, new_off = decode_arr_cls(data, off, QuestSceneExBonusUserData) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestSceneUserData": + ret = cls(b"\x00" * 12, 0) + ret.quest_type = data['quest_type'] + ret.quest_scene_id = data['quest_scene_id'] + ret.clear_flag = data['quest_clear_flag'] + ret.quest_scene_best_score_user_data = [QuestSceneBestScoreUserData.from_args(data)] + ret.quest_scene_ex_bonus_user_data_list = [] # TODO + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.quest_type) \ + + encode_short(self.quest_scene_id) \ + + encode_byte(self.clear_flag) \ + + encode_arr_cls(self.quest_scene_best_score_user_data) \ + + encode_arr_cls(self.quest_scene_ex_bonus_user_data_list) + +class QuestScenePlayStartAppearancePlayerTraceData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.user_quest_scene_player_trace_id, new_off = decode_str(data, off) + off += new_off + + self.nick_name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, sesh_id:int, nickname: str) -> "QuestScenePlayStartAppearancePlayerTraceData": + ret = cls(b"\x00" * 8, 0) + ret.user_quest_scene_player_trace_id = str(sesh_id) + ret.nick_name = nickname + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_quest_scene_player_trace_id) \ + + encode_str(self.nick_name) + +class QuestScenePlayStartResponseData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.appearance_player_trace_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayStartAppearancePlayerTraceData) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, sesh_id: int, nickname: str) -> "QuestScenePlayStartResponseData": + ret = cls(b"\x00" * 99, 0) + ret.appearance_player_trace_data_list = [QuestScenePlayStartAppearancePlayerTraceData.from_args(sesh_id, nickname)] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_arr_cls(self.appearance_player_trace_data_list) + +class QuestScenePlayStartRequestData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.user_party_id, new_off = decode_str(data, off) + off += new_off + + self.appoint_leader_resource_card_code, new_off = decode_str(data, off) + off += new_off + + self.use_profile_card_code, new_off = decode_str(data, off) + off += new_off + + self.quest_drop_boost_apply_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayStartRequestData": + ret = cls(b"\x00" * 13, 0) + ret.user_party_id = data['UserPartyId'] + ret.appoint_leader_resource_card_code = data['AppointLeaderResourceCardCode'] + ret.use_profile_card_code = data['UseProfileCardCode'] + ret.quest_drop_boost_apply_flag = data['QuestDropBoostApplyFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_party_id) \ + + encode_str(self.appoint_leader_resource_card_code) \ + + encode_str(self.use_profile_card_code) \ + + encode_byte(self.quest_drop_boost_apply_flag) + +class QuestSceneMultiPlayStartEntryUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.host_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestSceneMultiPlayStartEntryUserData": + ret = cls(b"\x00" * 9, 0) + ret.store_id = data['StoreId'] + ret.user_id = data['UserId'] + ret.host_flag = data['HostFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.store_id) \ + + encode_str(self.user_id) \ + + encode_byte(self.host_flag) + +class QuestSceneMultiPlayStartRequestData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.room_id, new_off = decode_str(data, off) + off += new_off + + self.matching_mode = decode_byte(data, off) + off += BYTE_OFF + + self.entry_user_data_list: List[QuestSceneMultiPlayStartEntryUserData] = [] + self.entry_user_data_list, new_off = decode_arr_cls(data, off, QuestSceneMultiPlayStartEntryUserData) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestSceneMultiPlayStartRequestData": + ret = cls(b"\x00" * 9, 0) + ret.room_id = data['RoomId'] + ret.matching_mode = data['MatchingMode'] + ret.entry_user_data_list = [] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.room_id) \ + + encode_byte(self.matching_mode) \ + + encode_arr_cls(self.entry_user_data_list) + +class QuestSceneMultiPlayStartResponseData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.dummy_1 = decode_byte(data, off) + off += BYTE_OFF + + self.dummy_2 = decode_byte(data, off) + off += BYTE_OFF + + self.dummy_3 = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls) -> "QuestSceneMultiPlayStartResponseData": + ret = cls(b"\x00" * 3, 0) + ret.dummy_1 = 0 + ret.dummy_2 = 0 + ret.dummy_3 = 0 + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.dummy_1) \ + + encode_byte(self.dummy_2) \ + + encode_byte(self.dummy_3) + +class QuestSceneMultiPlayEndResponseData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.dummy_1 = decode_byte(data, off) + off += BYTE_OFF + + self.dummy_2 = decode_byte(data, off) + off += BYTE_OFF + + self.dummy_3 = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls) -> "QuestSceneMultiPlayEndResponseData": + ret = cls(b"\x00" * 3, 0) + ret.dummy_1 = 0 + ret.dummy_2 = 0 + ret.dummy_3 = 0 + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.dummy_1) \ + + encode_byte(self.dummy_2) \ + + encode_byte(self.dummy_3) + +class QuestScenePlayEndBaseGetData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.get_hero_log_exp = decode_int(data, off) + off += INT_OFF + + self.get_col = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndBaseGetData": + ret = cls(b"\x00" * 99, 0) + ret.get_hero_log_exp = data['GetHeroLogExp'] + ret.get_col = data['GetCol'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.get_hero_log_exp) \ + + encode_int(self.get_col) + +class QuestScenePlayEndDiscoveryEnemyData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.enemy_kind_id = decode_int(data, off) + off += INT_OFF + + self.destroy_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndDiscoveryEnemyData": + ret = cls(b"\x00" * 99, 0) + ret.enemy_kind_id = data['EnemyKindId'] + ret.destroy_num = data['DestroyNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.enemy_kind_id) \ + + encode_short(self.destroy_num) + +class QuestScenePlayEndGetPlayerTraceData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.user_quest_scene_player_trace_id, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndGetPlayerTraceData": + ret = cls(b"\x00" * 99, 0) + ret.user_quest_scene_player_trace_id = data['UserQuestScenePlayerTraceId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_quest_scene_player_trace_id) + +class QuestScenePlayEndGetRareDropData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_rare_drop_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndGetRareDropData": + ret = cls(b"\x00" * 99, 0) + ret.quest_rare_drop_id = data['QuestRareDropId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.quest_rare_drop_id) + +class QuestScenePlayEndGetSpecialRareDropData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_special_rare_drop_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndGetSpecialRareDropData": + ret = cls(b"\x00" * 99, 0) + ret.quest_special_rare_drop_id = data['QuestSpecialRareDropId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.quest_special_rare_drop_id) + +class QuestScenePlayEndGetUnanalyzedLogTmpRewardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.unanalyzed_log_grade_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndGetUnanalyzedLogTmpRewardData": + ret = cls(b"\x00" * 99, 0) + ret.unanalyzed_log_grade_id = data['UnanalyzedLogGradeId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.unanalyzed_log_grade_id) + +class QuestScenePlayEndScoreData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.clear_time = decode_int(data, off) + off += INT_OFF + + self.combo_num = decode_int(data, off) + off += INT_OFF + + self.total_damage, new_off = decode_str(data, off) + off += new_off + + self.concurrent_destroying_num = decode_short(data, off) + off += SHORT_OFF + + self.reaching_skill_level = decode_short(data, off) + off += SHORT_OFF + + self.ko_chara_num = decode_byte(data, off) + off += BYTE_OFF + + self.acceleration_invocation_num = decode_short(data, off) + off += SHORT_OFF + + self.boss_destroying_num = decode_short(data, off) + off += SHORT_OFF + + self.synchro_skill_used_flag = decode_byte(data, off) + off += BYTE_OFF + + self.used_friend_skill_id = decode_int(data, off) + off += INT_OFF + + self.friend_skill_used_flag = decode_byte(data, off) + off += BYTE_OFF + + self.continue_cnt = decode_short(data, off) + off += SHORT_OFF + + self.total_loss_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndScoreData": + ret = cls(b"\x00" * 99, 0) + ret.clear_time = data['ClearTime'] + ret.combo_num = data['ComboNum'] + ret.total_damage = data['TotalDamage'] + ret.concurrent_destroying_num = data['ConcurrentDestroyingNum'] + ret.reaching_skill_level = data['ReachingSkillLevel'] + ret.ko_chara_num = data['KoCharaNum'] + ret.acceleration_invocation_num = data['AccelerationInvocationNum'] + ret.boss_destroying_num = data['BossDestroyingNum'] + ret.synchro_skill_used_flag = data['SynchroSkillUsedFlag'] + ret.used_friend_skill_id = data['UsedFriendSkillId'] + ret.friend_skill_used_flag = data['FriendSkillUsedFlag'] + ret.continue_cnt = data['ContinueCnt'] + ret.total_loss_num = data['TotalLossNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.clear_time) \ + + encode_int(self.combo_num) \ + + encode_str(self.total_damage) \ + + encode_short(self.concurrent_destroying_num) \ + + encode_short(self.reaching_skill_level) \ + + encode_byte(self.ko_chara_num) \ + + encode_short(self.acceleration_invocation_num) \ + + encode_short(self.boss_destroying_num) \ + + encode_byte(self.synchro_skill_used_flag) \ + + encode_int(self.used_friend_skill_id) \ + + encode_byte(self.friend_skill_used_flag) \ + + encode_short(self.continue_cnt) \ + + encode_short(self.total_loss_num) + +class QuestScenePlayEndMissionData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.mission_id = decode_int(data, off) + off += INT_OFF + + self.clear_flag = decode_byte(data, off) + off += BYTE_OFF + + self.mission_difficulty_id = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndMissionData": + ret = cls(b"\x00" * 99, 0) + ret.mission_id = data['MissionId'] + ret.clear_flag = data['ClearFlag'] + ret.mission_difficulty_id = data['MissionDifficultyId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.mission_id) \ + + encode_byte(self.clear_flag) \ + + encode_short(self.mission_difficulty_id) + +class QuestScenePlayEndDestroyBossData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.boss_type = decode_byte(data, off) + off += BYTE_OFF + + self.enemy_kind_id = decode_int(data, off) + off += INT_OFF + + self.destroy_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndDestroyBossData": + ret = cls(b"\x00" * 99, 0) + ret.boss_type = data['BossType'] + ret.enemy_kind_id = data['EnemyKindId'] + ret.destroy_num = data['DestroyNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.boss_type) \ + + encode_int(self.enemy_kind_id) \ + + encode_short(self.destroy_num) + +class QuestScenePlayEndGetEventItemData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.event_item_id = decode_int(data, off) + off += INT_OFF + + self.get_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndGetEventItemData": + ret = cls(b"\x00" * 99, 0) + ret.event_item_id = data['EventItemId'] + ret.get_num = data['GetNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.event_item_id) \ + + encode_short(self.get_num) + +class QuestTreasureHuntPlayEndResponseData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.get_event_point = decode_int(data, off) + off += INT_OFF + + self.total_event_point = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, get_pt: int = 0, total_pt: int = 0) -> "QuestTreasureHuntPlayEndResponseData": + ret = cls(b"\x00" * 8, 0) + ret.get_event_point = get_pt + ret.total_event_point = total_pt + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.get_event_point) \ + + encode_int(self.total_event_point) + +class QuestTrialTowerPlayEndUpdatedNotificationData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.store_best_score_clear_time_flag = decode_byte(data, off) + off += BYTE_OFF + + self.store_best_score_combo_num_flag = decode_byte(data, off) + off += BYTE_OFF + + self.store_best_score_total_damage_flag = decode_byte(data, off) + off += BYTE_OFF + + self.store_best_score_concurrent_destroying_num_flag = decode_byte(data, off) + off += BYTE_OFF + + self.store_reaching_trial_tower_rank = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, shop_best_time: bool = False, shop_best_combo: bool = False, shop_best_damage: bool = False, shop_best_concurrent: bool = False, shop_tower_rank: int = 0) -> "QuestTrialTowerPlayEndUpdatedNotificationData": + ret = cls(b"\x00" * 8, 0) + ret.store_best_score_clear_time_flag = shop_best_time + ret.store_best_score_combo_num_flag = shop_best_combo + ret.store_best_score_total_damage_flag = shop_best_damage + ret.store_best_score_concurrent_destroying_num_flag = shop_best_concurrent + ret.store_reaching_trial_tower_rank = shop_tower_rank + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.store_best_score_clear_time_flag) \ + + encode_byte(self.store_best_score_combo_num_flag) \ + + encode_byte(self.store_best_score_total_damage_flag) \ + + encode_byte(self.store_best_score_concurrent_destroying_num_flag) \ + + encode_int(self.store_reaching_trial_tower_rank) + +class CommonRewardUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.common_reward_type = decode_short(data, off) + off += SHORT_OFF + + self.user_common_reward_id, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "CommonRewardUserData": + ret = cls(b"\x00" * 99, 0) + ret.common_reward_type = data['CommonRewardType'] + ret.user_common_reward_id = data['UserCommonRewardId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.common_reward_type) \ + + encode_str(self.user_common_reward_id) + +class QuestScenePlayEndResponseData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.rarity_up_occurrence_flag = decode_byte(data, off) + off += BYTE_OFF + + self.adventure_ex_area_occurrences_flag = decode_byte(data, off) + off += BYTE_OFF + + self.ex_bonus_data_list: List[QuestScenePlayEndExBonusData] = [] + self.ex_bonus_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayEndExBonusData) + off += new_off + + self.play_end_player_trace_reward_data_list: List[QuestScenePlayEndPlayerTraceRewardData] = [] + self.play_end_player_trace_reward_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayEndPlayerTraceRewardData) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, rarity_up_flag: bool = False, adventure_ex_area_flg: bool = False, ex_tables: List = []) -> "QuestScenePlayEndResponseData": + ret = cls(b"\x00" * 99, 0) + ret.rarity_up_occurrence_flag = rarity_up_flag + ret.adventure_ex_area_occurrences_flag = adventure_ex_area_flg + for x in ex_tables: + ret.ex_bonus_data_list.append(QuestScenePlayEndExBonusData.from_args(x['table'], x['ach_status'])) + ret.play_end_player_trace_reward_data_list = [] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.rarity_up_occurrence_flag) \ + + encode_byte(self.adventure_ex_area_occurrences_flag) \ + + encode_arr_cls(self.ex_bonus_data_list) \ + + encode_arr_cls(self.play_end_player_trace_reward_data_list) + +class QuestScenePlayEndExBonusData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.ex_bonus_table_id = decode_int(data, off) + off += INT_OFF + + self.achievement_status = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, table_id: int, ach_status: int) -> "QuestScenePlayEndExBonusData": + ret = cls(b"\x00" * 5, 0) + ret.ex_bonus_table_id = table_id + ret.achievement_status = ach_status + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.ex_bonus_table_id) \ + + encode_byte(self.achievement_status) + +class QuestScenePlayEndPlayerTraceRewardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.common_reward_data: List[CommonRewardData] + self.common_reward_data, new_off = decode_arr_cls(data, off, CommonRewardData) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, reward_data: Dict) -> "QuestScenePlayEndPlayerTraceRewardData": + ret = cls(b"\x00" * 4, 0) + ret.common_reward_data.append(CommonRewardData.from_args(reward_data['CommonRewardType'], reward_data['CommonRewardId'], reward_data['CommonRewardNum'])) + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_arr_cls(self.common_reward_data) + +class QuestScenePlayEndRequestData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.play_result_flag = decode_byte(data, off) + off += BYTE_OFF + + self.base_get_data: List[QuestScenePlayEndBaseGetData] = [] + self.base_get_data, new_off = decode_arr_cls(data, off, QuestScenePlayEndBaseGetData) + off += new_off + + self.get_player_trace_data_list: List[QuestScenePlayEndGetPlayerTraceData] = [] + self.get_player_trace_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayEndGetPlayerTraceData) + off += new_off + + self.get_rare_drop_data_list: List[QuestScenePlayEndGetRareDropData] = [] + self.get_rare_drop_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayEndGetRareDropData) + off += new_off + + self.get_special_rare_drop_data_list: List[QuestScenePlayEndGetSpecialRareDropData] = [] + self.get_special_rare_drop_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayEndGetSpecialRareDropData) + off += new_off + + self.get_unanalyzed_log_tmp_reward_data_list: List[QuestScenePlayEndGetUnanalyzedLogTmpRewardData] = [] + self.get_unanalyzed_log_tmp_reward_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayEndGetUnanalyzedLogTmpRewardData) + off += new_off + + self.get_event_item_data_list: List[QuestScenePlayEndGetEventItemData] = [] + self.get_event_item_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayEndGetEventItemData) + off += new_off + + self.discovery_enemy_data_list: List[QuestScenePlayEndDiscoveryEnemyData] = [] + self.discovery_enemy_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayEndDiscoveryEnemyData) + off += new_off + + self.destroy_boss_data_list: List[QuestScenePlayEndDestroyBossData] = [] + self.destroy_boss_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayEndDestroyBossData) + off += new_off + + self.mission_data_list: List[QuestScenePlayEndMissionData] = [] + self.mission_data_list, new_off = decode_arr_cls(data, off, QuestScenePlayEndMissionData) + off += new_off + + self.score_data: List[QuestScenePlayEndScoreData] = [] + self.score_data, new_off = decode_arr_cls(data, off, QuestScenePlayEndScoreData) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestScenePlayEndRequestData": + ret = cls(b"\x00" * 99, 0) + ret.play_result_flag = data['PlayResultFlag'] + ret.base_get_data = [] + ret.get_player_trace_data_list = [] + ret.get_rare_drop_data_list = [] + ret.get_special_rare_drop_data_list = [] + ret.get_unanalyzed_log_tmp_reward_data_list = [] + ret.get_event_item_data_list = [] + ret.discovery_enemy_data_list = [] + ret.destroy_boss_data_list = [] + ret.mission_data_list = [] + ret.score_data = [] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.play_result_flag) \ + + encode_arr_cls(self.base_get_data) \ + + encode_arr_cls(self.get_player_trace_data_list) \ + + encode_arr_cls(self.get_rare_drop_data_list) \ + + encode_arr_cls(self.get_special_rare_drop_data_list) \ + + encode_arr_cls(self.get_unanalyzed_log_tmp_reward_data_list) \ + + encode_arr_cls(self.get_event_item_data_list) \ + + encode_arr_cls(self.discovery_enemy_data_list) \ + + encode_arr_cls(self.destroy_boss_data_list) \ + + encode_arr_cls(self.mission_data_list) \ + + encode_arr_cls(self.score_data) + +class QuestSceneMultiPlayEndRequestData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.dummy_1 = decode_byte(data, off) + off += BYTE_OFF + + self.dummy_2 = decode_byte(data, off) + off += BYTE_OFF + + self.dummy_3 = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls) -> "QuestSceneMultiPlayEndRequestData": + ret = cls(b"\x00" * 3, 0) + ret.dummy_1 = 0 + ret.dummy_2 = 0 + ret.dummy_3 = 0 + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.dummy_1) \ + + encode_byte(self.dummy_2) \ + + encode_byte(self.dummy_3) + +class ChatSideStoryUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.chat_side_story_id = decode_int(data, off) + off += INT_OFF + + self.played_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ChatSideStoryUserData": + ret = cls(b"\x00" * 99, 0) + ret.chat_side_story_id = data['ChatSideStoryId'] + ret.played_flag = data['PlayedFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.chat_side_story_id) \ + + encode_byte(self.played_flag) class PartyData(BaseHelper): - def __init__(self, data: bytes, offset: int) -> None: - sz = 0 - user_party_id = decode_str(data, offset + sz) - self.user_party_id = user_party_id[0] - sz += user_party_id[1] + def __init__(self, data: bytes, offset: int): + off = offset + self.user_party_id, new_off = decode_str(data, off) + off += new_off - self.team_no = decode_byte(data, offset + sz) - sz += BYTE_OFF - - self.party_team_data_count = decode_int(data, offset + sz) - sz += INT_OFF + self.team_no = decode_byte(data, off) + off += BYTE_OFF self.party_team_data_list: List[PartyTeamData] = [] - for _ in range(self.party_team_data_count): - tmp = PartyTeamData(data, offset + sz) - self.party_team_data_list.append(tmp) - sz += tmp.get_size() + self.party_team_data_list, new_off = decode_arr_cls(data, off, PartyTeamData) + off += new_off - self._sz = sz + self._sz = off - offset + + @classmethod + def from_args(cls, user_party_id: int, team_num: int, member1: Dict, member2: Dict, member3: Dict) -> "PartyData": + ret = cls(b"\x00" * 9, 0) + ret.user_party_id = user_party_id + ret.team_no = team_num + ret.party_team_data_list = [ + PartyTeamData.from_args(f"{user_party_id}-{team_num}-1", 1, member1), + PartyTeamData.from_args(f"{user_party_id}-{team_num}-2", 2, member2), + PartyTeamData.from_args(f"{user_party_id}-{team_num}-3", 3, member3), + ] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_party_id) \ + + encode_byte(self.team_no) \ + + encode_arr_cls(self.party_team_data_list) + +class SupportLogPartyData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.party_no = decode_byte(data, off) + off += BYTE_OFF + + self.arrangement_num_1_user_support_log_id, new_off = decode_str(data, off) + off += new_off + + self.arrangement_num_2_user_support_log_id, new_off = decode_str(data, off) + off += new_off + + self.arrangement_num_3_user_support_log_id, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "SupportLogPartyData": + ret = cls(b"\x00" * 99, 0) + ret.party_no = data['PartyNo'] + ret.arrangement_num_1_user_support_log_id = data['ArrangementNum1UserSupportLogId'] + ret.arrangement_num_2_user_support_log_id = data['ArrangementNum2UserSupportLogId'] + ret.arrangement_num_3_user_support_log_id = data['ArrangementNum3UserSupportLogId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.party_no) \ + + encode_str(self.arrangement_num_1_user_support_log_id) \ + + encode_str(self.arrangement_num_2_user_support_log_id) \ + + encode_str(self.arrangement_num_3_user_support_log_id) class PlayStartRequestData(BaseHelper): def __init__(self, data: bytes, offset: int) -> None: @@ -607,7 +1994,7 @@ class ShopResourceSalesData(BaseHelper): ret += encode_str(self.discharge_user_id) ret += encode_short(self.remaining_num) ret += encode_short(self.purchase_num) - ret += encode_str(fmt_dt(self.sales_start_date)) + ret += encode_date_str(self.sales_start_date) ret += encode_arr_cls(self.sales_resource_data_list) return ret @@ -635,7 +2022,7 @@ class YuiMedalShopUserData(BaseHelper): def make(self) -> bytes: ret = encode_int(self.yui_medal_shop_id) ret += encode_int(self.purchase_num) - ret += encode_str(fmt_dt(self.last_purchase_date)) + ret += encode_date_str(self.last_purchase_date) return ret class GashaMedalShopUserData(BaseHelper): @@ -659,263 +2046,6 @@ class GashaMedalShopUserData(BaseHelper): ret += encode_int(self.purchase_num) return ret -class YuiMedalShopData(BaseHelper): - def __init__(self, data: bytes, offset: int) -> None: - super().__init__(data, offset) - self.yui_medal_shop_id = decode_int(data, offset + self._sz) - - name = decode_str(data, offset + self._sz) - self.name = name[0] - self._sz += name[1] - - description = decode_str(data, offset + self._sz) - self.description = description[0] - self._sz += description[1] - - self.selling_yui_medal = decode_short(data, offset + self._sz) - self._sz += SHORT_OFF - self.selling_col = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.selling_event_item_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.selling_event_item_num = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.selling_ticket_num = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.purchase_limit = decode_short(data, offset + self._sz) - self._sz += SHORT_OFF - self.pick_up_flag = decode_byte(data, offset + self._sz) - self._sz += BYTE_OFF - self.product_category = decode_byte(data, offset + self._sz) - self._sz += BYTE_OFF - self.sales_type = decode_byte(data, offset + self._sz) - self._sz += BYTE_OFF - self.target_days = decode_byte(data, offset + self._sz) - self._sz += BYTE_OFF - self.target_hour = decode_byte(data, offset + self._sz) - self._sz += BYTE_OFF - self.interval_hour = decode_byte(data, offset + self._sz) - self._sz += BYTE_OFF - - sales_start_date = decode_str(data, offset + self._sz) - self.sales_start_date = prs_dt(sales_start_date[0]) - self._sz += sales_start_date[1] - - sales_end_date = decode_str(data, offset + self._sz) - self.sales_end_date = prs_dt(sales_end_date[0]) - self._sz += sales_end_date[1] - - self.sort = decode_byte(data, offset + self._sz) - - @classmethod - def from_args(cls, shop_id: int = 0, name: str = "", desc: str = "") -> "YuiMedalShopData": - ret = cls(b"\x00" * 43, 0) - ret.yui_medal_shop_id = shop_id - ret.name = name - ret.description = desc - return ret - - def make(self) -> bytes: - ret = encode_int(self.yui_medal_shop_id) - ret += encode_str(self.name) - ret += encode_str(self.description) - ret += encode_short(self.selling_yui_medal) - ret += encode_int(self.selling_col) - ret += encode_int(self.selling_event_item_id) - ret += encode_int(self.selling_event_item_num) - ret += encode_int(self.selling_ticket_num) - ret += encode_short(self.purchase_limit) - ret += encode_byte(self.pick_up_flag) - ret += encode_byte(self.product_category) - ret += encode_byte(self.sales_type) - ret += encode_byte(self.target_days) - ret += encode_byte(self.target_hour) - ret += encode_byte(self.interval_hour) - ret += encode_str(fmt_dt(self.sales_start_date)) - ret += encode_str(fmt_dt(self.sales_end_date)) - ret += encode_byte(self.sort) - return ret - -class YuiMedalShopItemData(BaseHelper): - def __init__(self, data: bytes, offset: int) -> None: - super().__init__(data, offset) - self.yui_medal_shop_item_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.yui_medal_shop_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.common_reward_type = decode_byte(data, offset + self._sz) - self._sz += BYTE_OFF - self.common_reward_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.common_reward_num = decode_short(data, offset + self._sz) - self._sz += SHORT_OFF - self.strength = decode_int(data, offset + self._sz) - self._sz += INT_OFF - - self.property1_property_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.property1_value1 = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.property1_value2 = decode_int(data, offset + self._sz) - self._sz += INT_OFF - - self.property2_property_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.property2_value1 = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.property2_value2 = decode_int(data, offset + self._sz) - self._sz += INT_OFF - - self.property3_property_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.property3_value1 = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.property3_value2 = decode_int(data, offset + self._sz) - self._sz += INT_OFF - - self.property4_property_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.property4_value1 = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.property4_value2 = decode_int(data, offset + self._sz) - self._sz += INT_OFF - - @classmethod - def from_args(cls, item_id: int = 0, shop_id: int = 0, reward_type: int = 0, reward_id: int = 0, reward_num: int = 0, strength: int = 0) -> "YuiMedalShopItemData": - ret = cls(b"\x00" * 67, 0) - ret.yui_medal_shop_item_id = item_id - ret.yui_medal_shop_id = shop_id - ret.common_reward_type = reward_type - ret.common_reward_id = reward_id - ret.common_reward_num = reward_num - ret.strength = strength - return ret - - def make(self) -> bytes: - ret = encode_int(self.yui_medal_shop_item_id) - ret += encode_int(self.yui_medal_shop_id) - ret += encode_byte(self.common_reward_type) - ret += encode_int(self.common_reward_id) - ret += encode_short(self.common_reward_num) - ret += encode_int(self.strength) - - ret += encode_int(self.property1_property_id) - ret += encode_int(self.property1_value1) - ret += encode_int(self.property1_value2) - - ret += encode_int(self.property2_property_id) - ret += encode_int(self.property2_value1) - ret += encode_int(self.property2_value2) - - ret += encode_int(self.property3_property_id) - ret += encode_int(self.property3_value1) - ret += encode_int(self.property3_value2) - - ret += encode_int(self.property4_property_id) - ret += encode_int(self.property4_value1) - ret += encode_int(self.property4_value2) - return ret - -class ResEarnCampaignShop(BaseHelper): - def __init__(self, data: bytes, offset: int) -> None: - super().__init__(data, offset) - self.res_earn_campaign_shop_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.res_earn_campaign_application_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - - name = decode_str(data, offset + self._sz) - self.name = name[0] - self._sz += name[1] - - self.selling_yui_medal = decode_short(data, offset + self._sz) - self._sz += SHORT_OFF - self.selling_col = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.selling_event_item_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.selling_event_item_num = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.purchase_limit = decode_short(data, offset + self._sz) - self._sz += SHORT_OFF - self.get_application_point = decode_short(data, offset + self._sz) - self._sz += SHORT_OFF - - sales_start_date = decode_str(data, offset + self._sz) - self.sales_start_date = prs_dt(sales_start_date[0]) - self._sz += sales_start_date[1] - - sales_end_date = decode_str(data, offset + self._sz) - self.sales_end_date = prs_dt(sales_end_date[0]) - self._sz += sales_end_date[1] - - @classmethod - def from_args(cls, shop_id: int = 0, app_id: int = 0, name: str = "") -> "ResEarnCampaignShop": - ret = cls(b"\x00" * 26, 0) - ret.res_earn_campaign_shop_id = shop_id - ret.res_earn_campaign_application_id = app_id - ret.name = name - return ret - - def make(self) -> bytes: - ret = encode_int(self.res_earn_campaign_shop_id) - ret = encode_int(self.res_earn_campaign_application_id) - ret += encode_str(self.name) - ret += encode_short(self.selling_yui_medal) - ret += encode_int(self.selling_col) - ret += encode_int(self.selling_event_item_id) - ret += encode_int(self.selling_event_item_num) - ret += encode_short(self.purchase_limit) - ret += encode_short(self.get_application_point) - ret += encode_str(fmt_dt(self.sales_start_date)) - ret += encode_str(fmt_dt(self.sales_end_date)) - return ret - -class GashaMedalShop(BaseHelper): - def __init__(self, data: bytes, offset: int) -> None: - super().__init__(data, offset) - self.gasha_medal_shop_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - - name = decode_str(data, offset + self._sz) - self.name = name[0] - self._sz += name[1] - - self.gasha_medal_id = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.use_gasha_medal_num = decode_int(data, offset + self._sz) - self._sz += INT_OFF - self.purchase_limit = decode_short(data, offset + self._sz) - self._sz += SHORT_OFF - - sales_start_date = decode_str(data, offset + self._sz) - self.sales_start_date = prs_dt(sales_start_date[0]) - self._sz += sales_start_date[1] - - sales_end_date = decode_str(data, offset + self._sz) - self.sales_end_date = prs_dt(sales_end_date[0]) - self._sz += sales_end_date[1] - - @classmethod - def from_args(cls, shop_id: int = 0, name: str = "", medal_id: int = 0, medal_num: int = 0, purchase_limit: int = 0) -> "GashaMedalShop": - ret = cls(b"\x00" * 26, 0) - ret.gasha_medal_shop_id = shop_id - ret.name = name - ret.gasha_medal_id = medal_id - ret.use_gasha_medal_num = medal_num - ret.purchase_limit = purchase_limit - return ret - - def make(self) -> bytes: - ret = encode_int(self.gasha_medal_shop_id) - ret += encode_str(self.name) - ret += encode_int(self.gasha_medal_id) - ret += encode_int(self.use_gasha_medal_num) - ret += encode_short(self.purchase_limit) - ret += encode_str(fmt_dt(self.sales_start_date)) - ret += encode_str(fmt_dt(self.sales_end_date)) - return ret - class QuestHierarchyProgressDegreesRankingData(BaseHelper): def __init__(self, data: bytes, offset: int) -> None: super().__init__(data, offset) @@ -977,10 +2107,10 @@ class PopularHeroLogRankingData(BaseHelper): @classmethod def from_args(cls, ranking: int, hero_id: int, used_num: int) -> "PopularHeroLogRankingData": - ret = cls(b"\x00" * 12, 0) - cls.ranking = ranking - cls.hero_log_id = hero_id - cls.used_num = used_num + ret = cls(b"\x00" * 992, 0) + ret.rank = ranking + ret.hero_log_id = hero_id + ret.used_num = used_num return ret def make(self) -> bytes: @@ -988,3 +2118,10564 @@ class PopularHeroLogRankingData(BaseHelper): ret += encode_int(self.hero_log_id) ret += encode_int(self.used_num) return ret + +class DefragMatchBasicUserData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = offset + self.seed_flag = decode_short(data, off) + off += SHORT_OFF + + self.ad_confirm_flag = decode_byte(data, off) + off += BYTE_OFF + + self.total_league_point = decode_int(data, off) + off += INT_OFF + + self.have_league_score = decode_short(data, off) + off += SHORT_OFF + + self.class_num = decode_short(data, off) + off += SHORT_OFF + + self.hall_of_fame_confirm_flag = decode_byte(data, off) + off += BYTE_OFF + self._sz = off + + @classmethod + def from_args(cls, seed_flag: int = 0, ad_confirm_flag: int = 0, total_league_point: int = 0, league_score: int = 0, class_num: int = 1, hof_flag: int = 0) -> "DefragMatchBasicUserData": + ret = cls(b"\x00" * 12, 0) + ret.seed_flag = seed_flag + ret.ad_confirm_flag = ad_confirm_flag + ret.total_league_point = total_league_point + ret.have_league_score = league_score + ret.class_num = class_num + ret.hall_of_fame_confirm_flag = hof_flag + + def make(self) -> bytes: + ret = encode_short(self.seed_flag) + ret += encode_byte(self.ad_confirm_flag) + ret += encode_int(self.total_league_point) + ret += encode_short(self.have_league_score) + ret += encode_short(self.class_num) + ret += encode_byte(self.hall_of_fame_confirm_flag) + return ret + +class DefragMatchRankingUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.league_point_rank = decode_int(data, off) + off += INT_OFF + + self.league_score_rank = decode_int(data, off) + off += INT_OFF + + self.nick_name, new_off = decode_str(data, off) + off += new_off + + self.setting_title_id = decode_int(data, off) + off += INT_OFF + + self.favorite_hero_log_id = decode_int(data, off) + off += INT_OFF + + self.favorite_hero_log_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.favorite_support_log_id = decode_int(data, off) + off += INT_OFF + + self.favorite_support_log_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.total_league_point = decode_int(data, off) + off += INT_OFF + + self.have_league_score = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, profile: Dict) -> "DefragMatchRankingUserData": + ret = cls(b"\x00" * 34, 0) + ret.league_point_rank = 0 + ret.league_score_rank = 0 + ret.nick_name = profile['nick_name'] + ret.setting_title_id = profile['setting_title_id'] + ret.favorite_hero_log_id = profile['fav_hero'] + ret.favorite_hero_log_awakening_stage = 0 + ret.favorite_support_log_id = 0 + ret.favorite_support_log_awakening_stage = 0 + ret.total_league_point = 0 + ret.have_league_score = 0 + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.league_point_rank) \ + + encode_int(self.league_score_rank) \ + + encode_str(self.nick_name) \ + + encode_int(self.setting_title_id) \ + + encode_int(self.favorite_hero_log_id) \ + + encode_short(self.favorite_hero_log_awakening_stage) \ + + encode_int(self.favorite_support_log_id) \ + + encode_short(self.favorite_support_log_awakening_stage) \ + + encode_int(self.total_league_point) \ + + encode_short(self.have_league_score) + +class DefragMatchLeaguePointRankingData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.rank = decode_int(data, off) + off += INT_OFF + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.store_name, new_off = decode_str(data, off) + off += new_off + + self.nick_name, new_off = decode_str(data, off) + off += new_off + + self.setting_title_id = decode_int(data, off) + off += INT_OFF + + self.favorite_hero_log_id = decode_int(data, off) + off += INT_OFF + + self.favorite_hero_log_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.favorite_support_log_id = decode_int(data, off) + off += INT_OFF + + self.favorite_support_log_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.class_num = decode_short(data, off) + off += SHORT_OFF + + self.total_league_point = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchLeaguePointRankingData": + ret = cls(b"\x00" * 42, 0) + ret.rank = data['Rank'] + ret.user_id = data['UserId'] + ret.store_id = data['StoreId'] + ret.store_name = data['StoreName'] + ret.nick_name = data['NickName'] + ret.setting_title_id = data['SettingTitleId'] + ret.favorite_hero_log_id = data['FavoriteHeroLogId'] + ret.favorite_hero_log_awakening_stage = data['FavoriteHeroLogAwakeningStage'] + ret.favorite_support_log_id = data['FavoriteSupportLogId'] + ret.favorite_support_log_awakening_stage = data['FavoriteSupportLogAwakeningStage'] + ret.class_num = data['ClassNum'] + ret.total_league_point = data['TotalLeaguePoint'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.rank) \ + + encode_str(self.user_id) \ + + encode_str(self.store_id) \ + + encode_str(self.store_name) \ + + encode_str(self.nick_name) \ + + encode_int(self.setting_title_id) \ + + encode_int(self.favorite_hero_log_id) \ + + encode_short(self.favorite_hero_log_awakening_stage) \ + + encode_int(self.favorite_support_log_id) \ + + encode_short(self.favorite_support_log_awakening_stage) \ + + encode_short(self.class_num) \ + + encode_int(self.total_league_point) + +class DefragMatchLeagueScoreRankingList(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = offset + self.rank = decode_byte(data, off) + off += BYTE_OFF + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.store_id, new_off = decode_str(data, off) + off += new_off + + self.store_name, new_off = decode_str(data, off) + off += new_off + + self.nick_name, new_off = decode_str(data, off) + off += new_off + + self.setting_title_id = decode_int(data, off) + off += INT_OFF + + self.favorite_hero_log_id = decode_int(data, off) + off += INT_OFF + + self.favorite_hero_log_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.favorite_support_log_id = decode_int(data, off) + off += INT_OFF + + self.favorite_support_log_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.class_num = decode_short(data, off) + off += SHORT_OFF + + self.have_league_score = decode_short(data, off) + off += SHORT_OFF + + @classmethod + def from_args(cls) -> "DefragMatchLeagueScoreRankingList": + return cls(b"\x00" * 40, 0) + + def make(self) -> bytes: + ret = encode_int(self.rank) + ret += encode_str(self.user_id) + ret += encode_str(self.store_id) + ret += encode_str(self.store_name) + ret += encode_str(self.nick_name) + + ret += encode_int(self.setting_title_id) + ret += encode_int(self.favorite_hero_log_id) + ret += encode_short(self.favorite_hero_log_awakening_stage) + ret += encode_int(self.favorite_support_log_id) + ret += encode_short(self.favorite_support_log_awakening_stage) + ret += encode_short(self.class_num) + ret += encode_short(self.have_league_score) + return ret + +class AppVersionData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = offset + self.version_app_id = decode_int(data, off) + off += INT_OFF + + self.applying_start_date, new_off = decode_date_str(data, off) + off += new_off + + @classmethod + def from_args(cls, app_ver: int, start_date: datetime) -> BaseHelper: + ret = cls(b"\x00" * 8, 0) + ret.version_app_id = app_ver + ret.applying_start_date = start_date + return ret + + def make(self) -> bytes: + ret = encode_int(self.version_app_id) + ret += encode_date_str(self.applying_start_date) + return ret + +class MatchingErrorData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = 0 + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.param_1, new_off = decode_str(data, off) + off += new_off + + self.param_2, new_off = decode_str(data, off) + off += new_off + + self.param_3, new_off = decode_str(data, off) + off += new_off + + self.param_4, new_off = decode_str(data, off) + off += new_off + + self.param_5, new_off = decode_str(data, off) + off += new_off + + self.param_6, new_off = decode_str(data, off) + off += new_off + + self.param_7, new_off = decode_str(data, off) + off += new_off + + self.param_8, new_off = decode_str(data, off) + off += new_off + + self.param_9, new_off = decode_str(data, off) + off += new_off + + self.param_10, new_off = decode_str(data, off) + off += new_off + + self.error_occurred_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + def __str__(self) -> str: + s = f"User: {self.user_id} || " + s += f"Params: {self.param_1} {self.param_2} {self.param_3} {self.param_4} {self.param_5} {self.param_6} {self.param_7} {self.param_8} {self.param_9} {self.param_10} || " + s += f"Date: {self.error_occurred_date}" + return s + +class ReadProfileCard(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = offset + self.profile_card_code, new_off = decode_str(data, off) # ID of the QR code + off += new_off + self.nick_name = decode_str(data, off) + off += new_off + + self.rank_num = decode_short(data, off) #short + off += SHORT_OFF + self.setting_title_id = decode_int(data, off) #int + off += INT_OFF + self.skill_id = decode_short(data, off) #short + off += SHORT_OFF + self.hero_log_hero_log_id = decode_int(data, off) #int + off += INT_OFF + self.hero_log_log_level = decode_short(data, off) #short + off += SHORT_OFF + self.hero_log_awakening_stage = decode_short(data, off) #short + off += SHORT_OFF + + self.hero_log_property1_property_id = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property1_value1 = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property1_value2 = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property2_property_id = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property2_value1 = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property2_value2 = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property3_property_id = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property3_value1 = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property3_value2 = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property4_property_id = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property4_value1 = decode_int(data, off) #int + off += INT_OFF + self.hero_log_property4_value2 = decode_int(data, off) #int + off += INT_OFF + + self.main_weapon_equipment_id = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_enhancement_value = decode_short(data, off) #short + off += SHORT_OFF + self.main_weapon_awakening_stage = decode_short(data, off) #short + off += SHORT_OFF + + self.main_weapon_property1_property_id = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property1_value1 = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property1_value2 = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property2_property_id = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property2_value1 = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property2_value2 = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property3_property_id = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property3_value1 = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property3_value2 = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property4_property_id = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property4_value1 = decode_int(data, off) #int + off += INT_OFF + self.main_weapon_property4_value2 = decode_int(data, off) #int + off += INT_OFF + + self.sub_equipment_equipment_id = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_enhancement_value = decode_short(data, off) #short + off += SHORT_OFF + self.sub_equipment_awakening_stage = decode_short(data, off) #short + off += SHORT_OFF + + self.sub_equipment_property1_property_id = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property1_value1 = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property1_value2 = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property2_property_id = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property2_value1 = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property2_value2 = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property3_property_id = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property3_value1 = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property3_value2 = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property4_property_id = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property4_value1 = decode_int(data, off) #int + off += INT_OFF + self.sub_equipment_property4_value2 = decode_int(data, off) #int + off += INT_OFF + + self.holographic_flag = decode_byte(data, off) #byte + off += BYTE_OFF + self._sz = off - offset + + @classmethod + def from_args(cls, code: str, player_name: str) -> "ReadProfileCard": + resp = cls(b"\x00" * 44, 0) + resp.profile_card_code = code # ID of the QR code + resp.nick_name = player_name + resp.rank_num = 1 #short + resp.setting_title_id = 20005 #int + resp.skill_id = 0 #short + resp.hero_log_hero_log_id = 118000230 #int + resp.hero_log_log_level = 1 #short + resp.hero_log_awakening_stage = 1 #short + + resp.hero_log_property1_property_id = 0 #int + resp.hero_log_property1_value1 = 0 #int + resp.hero_log_property1_value2 = 0 #int + resp.hero_log_property2_property_id = 0 #int + resp.hero_log_property2_value1 = 0 #int + resp.hero_log_property2_value2 = 0 #int + resp.hero_log_property3_property_id = 0 #int + resp.hero_log_property3_value1 = 0 #int + resp.hero_log_property3_value2 = 0 #int + resp.hero_log_property4_property_id = 0 #int + resp.hero_log_property4_value1 = 0 #int + resp.hero_log_property4_value2 = 0 #int + + resp.main_weapon_equipment_id = 0 #int + resp.main_weapon_enhancement_value = 0 #short + resp.main_weapon_awakening_stage = 0 #short + + resp.main_weapon_property1_property_id = 0 #int + resp.main_weapon_property1_value1 = 0 #int + resp.main_weapon_property1_value2 = 0 #int + resp.main_weapon_property2_property_id = 0 #int + resp.main_weapon_property2_value1 = 0 #int + resp.main_weapon_property2_value2 = 0 #int + resp.main_weapon_property3_property_id = 0 #int + resp.main_weapon_property3_value1 = 0 #int + resp.main_weapon_property3_value2 = 0 #int + resp.main_weapon_property4_property_id = 0 #int + resp.main_weapon_property4_value1 = 0 #int + resp.main_weapon_property4_value2 = 0 #int + + resp.sub_equipment_equipment_id = 0 #int + resp.sub_equipment_enhancement_value = 0 #short + resp.sub_equipment_awakening_stage = 0 #short + + resp.sub_equipment_property1_property_id = 0 #int + resp.sub_equipment_property1_value1 = 0 #int + resp.sub_equipment_property1_value2 = 0 #int + resp.sub_equipment_property2_property_id = 0 #int + resp.sub_equipment_property2_value1 = 0 #int + resp.sub_equipment_property2_value2 = 0 #int + resp.sub_equipment_property3_property_id = 0 #int + resp.sub_equipment_property3_value1 = 0 #int + resp.sub_equipment_property3_value2 = 0 #int + resp.sub_equipment_property4_property_id = 0 #int + resp.sub_equipment_property4_value1 = 0 #int + resp.sub_equipment_property4_value2 = 0 #int + + resp.holographic_flag = 0 #byte + return resp + +class HeroLogUserData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = offset + self.user_hero_log_id, new_off = decode_str(data, off) + off += new_off + self.hero_log_id = decode_int(data, off) + off += INT_OFF + self.log_level = decode_short(data, off) + off += SHORT_OFF + self.max_log_level_extended_num = decode_short(data, off) + off += SHORT_OFF + self.log_exp = decode_int(data, off) + off += INT_OFF + self.possible_awakening_flag = decode_byte(data, off) + off += BYTE_OFF + self.awakening_stage = decode_short(data, off) + off += SHORT_OFF + self.awakening_exp = decode_int(data, off) + off += INT_OFF + self.skill_slot_correction_value = decode_byte(data, off) + off += BYTE_OFF + self.last_set_skill_slot1_skill_id = decode_short(data, off) + off += SHORT_OFF + self.last_set_skill_slot2_skill_id = decode_short(data, off) + off += SHORT_OFF + self.last_set_skill_slot3_skill_id = decode_short(data, off) + off += SHORT_OFF + self.last_set_skill_slot4_skill_id = decode_short(data, off) + off += SHORT_OFF + self.last_set_skill_slot5_skill_id = decode_short(data, off) + off += SHORT_OFF + self.property1_property_id = decode_int(data, off) + off += INT_OFF + self.property1_value1 = decode_int(data, off) + off += INT_OFF + self.property1_value2 = decode_int(data, off) + off += INT_OFF + self.property2_property_id = decode_int(data, off) + off += INT_OFF + self.property2_value1 = decode_int(data, off) + off += INT_OFF + self.property2_value2 = decode_int(data, off) + off += INT_OFF + self.property3_property_id = decode_int(data, off) + off += INT_OFF + self.property3_value1 = decode_int(data, off) + off += INT_OFF + self.property3_value2 = decode_int(data, off) + off += INT_OFF + self.property4_property_id = decode_int(data, off) + off += INT_OFF + self.property4_value1 = decode_int(data, off) + off += INT_OFF + self.property4_value2 = decode_int(data, off) + off += INT_OFF + self.converted_card_num = decode_short(data, off) + off += SHORT_OFF + self.shop_purchase_flag = decode_byte(data, off) + off += BYTE_OFF + self.protect_flag = decode_byte(data, off) + off += BYTE_OFF + + get_date, new_off = decode_str(data, off) + off += new_off + self.get_date = prs_dt(get_date) + self.sz = off - offset + + @classmethod + def from_args(cls, hero_data: Dict) -> "HeroLogUserData": + ret = cls(b"\x00" * 90, 0) + # Seems user_hero_log_id is a globally unique identifier, while hero_log_id identifies the hero + ret.user_hero_log_id = f"{hero_data['id']}" + ret.hero_log_id = hero_data['hero_log_id'] + + ret.log_level = hero_data['log_level'] + ret.max_log_level_extended_num = hero_data['max_level_extend_num'] + ret.log_exp = hero_data['log_exp'] + + ret.possible_awakening_flag = hero_data['is_awakenable'] + ret.awakening_stage = hero_data['awakening_stage'] + ret.awakening_exp = hero_data['awakening_exp'] + + ret.skill_slot_correction_value = 0 # Allows unlocking skill slot 4 and 5 early + ret.last_set_skill_slot1_skill_id = hero_data['skill_slot1_skill_id'] + ret.last_set_skill_slot2_skill_id = hero_data['skill_slot2_skill_id'] + ret.last_set_skill_slot3_skill_id = hero_data['skill_slot3_skill_id'] + ret.last_set_skill_slot4_skill_id = hero_data['skill_slot4_skill_id'] + ret.last_set_skill_slot5_skill_id = hero_data['skill_slot5_skill_id'] + + ret.property1_property_id = hero_data['property1_property_id'] + ret.property1_value1 = hero_data['property1_value1'] + ret.property1_value2 = hero_data['property1_value2'] + ret.property2_property_id = hero_data['property2_property_id'] + ret.property2_value1 = hero_data['property2_value1'] + ret.property2_value2 = hero_data['property2_value2'] + ret.property3_property_id = hero_data['property2_property_id'] + ret.property3_value1 = hero_data['property3_value1'] + ret.property3_value2 = hero_data['property3_value2'] + ret.property4_property_id = hero_data['property2_property_id'] + ret.property4_value1 = hero_data['property4_value1'] + ret.property4_value2 = hero_data['property4_value2'] + + ret.converted_card_num = hero_data['converted_card_num'] + ret.shop_purchase_flag = hero_data['is_shop_purchase'] + ret.protect_flag = hero_data['is_protect'] + ret.get_date = hero_data['get_date'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_hero_log_id) \ + + encode_int(self.hero_log_id) \ + + encode_short(self.log_level) \ + + encode_short(self.max_log_level_extended_num) \ + + encode_int(self.log_exp) \ + + encode_byte(self.possible_awakening_flag) \ + + encode_short(self.awakening_stage) \ + + encode_int(self.awakening_exp) \ + + encode_byte(self.skill_slot_correction_value) \ + + encode_short(self.last_set_skill_slot1_skill_id) \ + + encode_short(self.last_set_skill_slot2_skill_id) \ + + encode_short(self.last_set_skill_slot3_skill_id) \ + + encode_short(self.last_set_skill_slot4_skill_id) \ + + encode_short(self.last_set_skill_slot5_skill_id) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) \ + + encode_short(self.converted_card_num) \ + + encode_byte(self.shop_purchase_flag) \ + + encode_byte(self.protect_flag) \ + + encode_date_str(self.get_date) + +class YuiMedalBonusUserData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = offset + self.elapsed_days = decode_int(data, off) + off += INT_OFF + self.loop_num = decode_int(data, off) + off += INT_OFF + + last_check_date, new_off = decode_str(data, off) + off += new_off + self.last_check_date = prs_dt(last_check_date) + + last_get_date, new_off = decode_str(data, off) + off += new_off + self.last_get_date = prs_dt(last_get_date) + + self._sz = off - offset + + @classmethod + def from_args(cls, elapsed_days: int = 0, loop_num: int = 0) -> BaseHelper: + ret = cls(b"\x00" * 996, 0) + ret.elapsed_days = elapsed_days + ret.loop_num = loop_num + ret.last_check_date = datetime.fromtimestamp(0) + ret.last_get_date = datetime.fromtimestamp(0) + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.elapsed_days) \ + + encode_int(self.loop_num) \ + + encode_date_str(self.last_check_date) \ + + encode_date_str(self.last_get_date) + +class UserBasicData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = offset + self.user_type = decode_short(data, off) + off += SHORT_OFF + + self.nick_name, new_off = decode_str(data, off) + off += new_off + + self.rank_num = decode_short(data, off) + off += SHORT_OFF + + self.rank_exp = decode_int(data, off) + off += INT_OFF + + self.own_col = decode_int(data, off) + off += INT_OFF + + self.own_vp = decode_int(data, off) + off += INT_OFF + + self.own_yui_medal = decode_int(data, off) + off += INT_OFF + + self.setting_title_id = decode_int(data, off) + off += INT_OFF + + self.favorite_user_hero_log_id, new_off = decode_str(data, off) + off += new_off + + self.favorite_user_support_log_id, new_off = decode_str(data, off) + off += new_off + + self.my_store_id, new_off = decode_str(data, off) + off += new_off + + self.my_store_name, new_off = decode_str(data, off) + off += new_off + + user_reg_date, new_off = decode_str(data, off) + self.user_reg_date = prs_dt(user_reg_date) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, profile_data: Dict, shop_name: str = "ARTEMiS") -> "UserBasicData": + ret = cls(b"\0" * 52, 0) + ret.user_type = profile_data['user_type'] + ret.nick_name = profile_data['nick_name'] + ret.rank_num = profile_data['rank_num'] + ret.rank_exp = profile_data['rank_exp'] + ret.own_col = profile_data['own_col'] + ret.own_vp = profile_data['own_vp'] + ret.own_yui_medal = profile_data['own_yui_medal'] + ret.setting_title_id = profile_data['setting_title_id'] + ret.favorite_user_hero_log_id = profile_data['fav_hero'] + ret.favorite_user_support_log_id = "" # TODO: Supports + ret.my_store_id = "JPN0" + f"{profile_data['my_shop']:04X}" if profile_data["my_shop"] else "0" + ret.my_store_name = shop_name + ret.user_reg_date = profile_data['when_register'] if profile_data['when_register'] else prs_dt("20230101120000") + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.user_type) \ + + encode_str(self.nick_name) \ + + encode_short(self.rank_num) \ + + encode_int(self.rank_exp) \ + + encode_int(self.own_col) \ + + encode_int(self.own_vp) \ + + encode_int(self.own_yui_medal) \ + + encode_int(self.setting_title_id) \ + + encode_str(self.favorite_user_hero_log_id) \ + + encode_str(self.favorite_user_support_log_id) \ + + encode_str(self.my_store_id) \ + + encode_str(self.my_store_name) \ + + encode_date_str(self.user_reg_date) \ + +class VpGashaTicketData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = offset + self.remaining_own_vp_gasha_ticket = decode_int(data, off) + off += INT_OFF + + self.expire_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, ticket_remain: int, exp_date: datetime) -> "VpGashaTicketData": + ret = cls(b"\x00" * 8, 0) + ret.remaining_own_vp_gasha_ticket = ticket_remain + ret.expire_date = exp_date + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.remaining_own_vp_gasha_ticket) \ + + encode_date_str(self.expire_date) + +class BeginnerMissionUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.ad_confirm_flag = decode_byte(data, off) + off += BYTE_OFF + + self.ad_confirm_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, confirm_date: datetime, confirm_flg: bool = False) -> "BeginnerMissionUserData": + ret = cls(b"\x00" * 99, 0) + ret.ad_confirm_flag = confirm_flg + ret.ad_confirm_date = confirm_date + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.ad_confirm_flag) \ + + encode_date_str(self.ad_confirm_date) + +class EquipmentUserData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = offset + self.user_equipment_id, new_off = decode_str(data, off) + off += new_off + + self.equipment_id = decode_int(data, off) + off += INT_OFF + self.enhancement_value = decode_short(data, off) + off += SHORT_OFF + self.max_enhancement_value_extended_num = decode_short(data, off) + off += SHORT_OFF + self.enhancement_exp = decode_int(data, off) + off += INT_OFF + self.possible_awakening_flag = decode_byte(data, off) + off += BYTE_OFF + self.awakening_stage = decode_short(data, off) + off += SHORT_OFF + self.awakening_exp = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + self.property1_value1 = decode_int(data, off) + off += INT_OFF + self.property1_value2 = decode_int(data, off) + off += INT_OFF + self.property2_property_id = decode_int(data, off) + off += INT_OFF + self.property2_value1 = decode_int(data, off) + off += INT_OFF + self.property2_value2 = decode_int(data, off) + off += INT_OFF + self.property3_property_id = decode_int(data, off) + off += INT_OFF + self.property3_value1 = decode_int(data, off) + off += INT_OFF + self.property3_value2 = decode_int(data, off) + off += INT_OFF + self.property4_property_id = decode_int(data, off) + off += INT_OFF + self.property4_value1 = decode_int(data, off) + off += INT_OFF + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self.converted_card_num = decode_short(data, off) + off += SHORT_OFF + self.shop_purchase_flag = decode_byte(data, off) + off += BYTE_OFF + self.protect_flag = decode_byte(data, off) + off += BYTE_OFF + + self.get_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, equip_data: Dict) -> "EquipmentUserData": + ret = cls(b"\x00" * 79, 0) + ret.user_equipment_id = str(equip_data['id']) + ret.equipment_id = equip_data['equipment_id'] + ret.enhancement_value = equip_data['enhancement_value'] + ret.max_enhancement_value_extended_num = 0 #equip_data['max_enhancement_value_extended_num'] TODO: This + ret.enhancement_exp = equip_data['enhancement_exp'] + ret.possible_awakening_flag = equip_data['possible_awakening_flag'] + ret.awakening_stage = equip_data['awakening_stage'] + ret.awakening_exp = equip_data['awakening_exp'] + ret.property1_property_id = equip_data['property1_property_id'] + ret.property1_value1 = equip_data['property1_value1'] + ret.property1_value2 = equip_data['property1_value2'] + ret.property2_property_id = equip_data['property2_property_id'] + ret.property2_value1 = equip_data['property2_value1'] + ret.property2_value2 = equip_data['property2_value2'] + ret.property3_property_id = equip_data['property2_property_id'] + ret.property3_value1 = equip_data['property3_value1'] + ret.property3_value2 = equip_data['property3_value2'] + ret.property4_property_id = equip_data['property2_property_id'] + ret.property4_value1 = equip_data['property4_value1'] + ret.property4_value2 = equip_data['property4_value2'] + ret.converted_card_num = equip_data['converted_card_num'] + ret.shop_purchase_flag = equip_data['is_shop_purchase'] + ret.protect_flag = equip_data['is_protect'] + ret.get_date = equip_data['get_date'] + return ret + + def make(self) -> bytes: + return encode_str(self.user_equipment_id) \ + + encode_int(self.equipment_id) \ + + encode_short(self.enhancement_value) \ + + encode_short(self.max_enhancement_value_extended_num) \ + + encode_int(self.enhancement_exp) \ + + encode_byte(self.possible_awakening_flag) \ + + encode_short(self.awakening_stage) \ + + encode_int(self.awakening_exp) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) \ + + encode_short(self.converted_card_num) \ + + encode_byte(self.shop_purchase_flag) \ + + encode_byte(self.protect_flag) \ + + encode_date_str(self.get_date) + +class ItemUserData(BaseHelper): + def __init__(self, data: bytes, offset: int) -> None: + super().__init__(data, offset) + off = offset + self.user_item_id, new_off = decode_str(data, off) + off += new_off + self.item_id = decode_int(data, off) + off += INT_OFF + self.protect_flag = decode_byte(data, off) + off += BYTE_OFF + self.get_date = decode_date_str(data, off) + + self._sz = off - offset + + @classmethod + def from_args(cls, item_data: Dict) -> BaseHelper: + ret = cls(b"\x00" * 993, 0) + ret.user_item_id = str(item_data['id']) + ret.item_id = item_data['item_id'] + ret.protect_flag = 0 + ret.get_date = item_data['get_date'] + return ret + + def make(self) -> bytes: + return encode_str(self.user_item_id) \ + + encode_int(self.item_id) \ + + encode_byte(self.protect_flag) \ + + encode_date_str(self.get_date) + +class SupportLogUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.user_support_log_id, new_off = decode_str(data, off) + off += new_off + + self.support_log_id = decode_int(data, off) + off += INT_OFF + + self.possible_awakening_flag = decode_byte(data, off) + off += BYTE_OFF + + self.awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.awakening_exp = decode_int(data, off) + off += INT_OFF + + self.converted_card_num = decode_short(data, off) + off += SHORT_OFF + + self.shop_purchase_flag = decode_byte(data, off) + off += BYTE_OFF + + self.protect_flag = decode_byte(data, off) + off += BYTE_OFF + + self.get_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, user_support_log: str, support_log: int) -> "SupportLogUserData": + ret = cls(b"\x00" * 23, 0) + ret.user_support_log_id = user_support_log + ret.support_log_id = support_log + ret.possible_awakening_flag = 0 + ret.awakening_stage = 0 + ret.awakening_exp = 0 + ret.converted_card_num = 0 + ret.shop_purchase_flag = 0 + ret.protect_flag = 0 + ret.get_date = prs_dt() + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_support_log_id) \ + + encode_int(self.support_log_id) \ + + encode_byte(self.possible_awakening_flag) \ + + encode_short(self.awakening_stage) \ + + encode_int(self.awakening_exp) \ + + encode_short(self.converted_card_num) \ + + encode_byte(self.shop_purchase_flag) \ + + encode_byte(self.protect_flag) \ + + encode_date_str(self.get_date) + +class EventItemUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.user_event_item_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.event_item_id = decode_int(data, off) + off += INT_OFF + + self.own_num = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EventItemUserData": + ret = cls(b"\x00" * 996, 0) + ret.user_event_item_id = data['UserEventItemId'] + ret.user_id = data['UserId'] + ret.event_item_id = data['EventItemId'] + ret.own_num = data['OwnNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_event_item_id) \ + + encode_str(self.user_id) \ + + encode_int(self.event_item_id) \ + + encode_int(self.own_num) + +class GashaMedalUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.user_gasha_medal_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.gasha_medal_id = decode_int(data, off) + off += INT_OFF + + self.own_num = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaMedalUserData": + ret = cls(b"\x00" * 996, 0) + ret.user_gasha_medal_id = data['UserGashaMedalId'] + ret.user_id = data['UserId'] + ret.gasha_medal_id = data['GashaMedalId'] + ret.own_num = data['OwnNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_gasha_medal_id) \ + + encode_str(self.user_id) \ + + encode_int(self.gasha_medal_id) \ + + encode_int(self.own_num) + +class TitleUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.user_title_id, new_off = decode_str(data, off) + off += new_off + + self.title_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, user_title_id: str, title_id: int) -> "TitleUserData": + ret = cls(b"\x00" * 8, 0) + ret.user_title_id = user_title_id + ret.title_id = title_id + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_title_id) \ + + encode_int(self.title_id) + +class PlayerRankData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.player_rank_id = decode_short(data, off) + off += SHORT_OFF + + self.total_exp = decode_int(data, off) + off += INT_OFF + + self.storage = decode_short(data, off) + off += SHORT_OFF + + self.team_preset = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "PlayerRankData": + ret = cls(b"\x00" * 99, 0) + ret.player_rank_id = data['PlayerRankId'] + ret.total_exp = data['TotalExp'] + ret.storage = data['Storage'] + ret.team_preset = data['TeamPreset'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.player_rank_id) \ + + encode_int(self.total_exp) \ + + encode_short(self.storage) \ + + encode_short(self.team_preset) + +class TitleData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.title_id = decode_int(data, off) + off += INT_OFF + + self.display_name, new_off = decode_str(data, off) + off += new_off + + self.requirement = decode_int(data, off) + off += INT_OFF + + self.value1 = decode_int(data, off) + off += INT_OFF + + self.value2 = decode_int(data, off) + off += INT_OFF + + self.rank = decode_int(data, off) + off += INT_OFF + + self.image_file_path, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "TitleData": + ret = cls(b"\x00" * 99, 0) + ret.title_id = data['TitleId'] + ret.display_name = data['DisplayName'] + ret.requirement = data['Requirement'] + ret.value1 = data['Value1'] + ret.value2 = data['Value2'] + ret.rank = data['Rank'] + ret.image_file_path = data['ImageFilePath'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.title_id) \ + + encode_str(self.display_name) \ + + encode_int(self.requirement) \ + + encode_int(self.value1) \ + + encode_int(self.value2) \ + + encode_int(self.rank) \ + + encode_str(self.image_file_path) + +class FragmentData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.fragment_id = decode_short(data, off) + off += SHORT_OFF + + self.exp = decode_int(data, off) + off += INT_OFF + + self.comment_id, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "FragmentData": + ret = cls(b"\x00" * 99, 0) + ret.fragment_id = data['FragmentId'] + ret.exp = data['Exp'] + ret.comment_id = data['CommentId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.fragment_id) \ + + encode_int(self.exp) \ + + encode_str(self.comment_id) + +class RewardTableData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.reward_table_id = decode_int(data, off) + off += INT_OFF + + self.reward_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.unanalyzed_log_grade_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_int(data, off) + off += INT_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_int(data, off) + off += INT_OFF + + self.strength_min = decode_int(data, off) + off += INT_OFF + + self.strength_max = decode_int(data, off) + off += INT_OFF + + self.property_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.rate = decode_int(data, off) + off += INT_OFF + + self.quest_info_display_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "RewardTableData": + ret = cls(b"\x00" * 99, 0) + ret.reward_table_id = data['RewardTableId'] + ret.reward_table_sub_id = data['RewardTableSubId'] + ret.unanalyzed_log_grade_id = data['UnanalyzedLogGradeId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength_min = data['StrengthMin'] + ret.strength_max = data['StrengthMax'] + ret.property_table_sub_id = data['PropertyTableSubId'] + ret.rate = data['Rate'] + ret.quest_info_display_flag = data['QuestInfoDisplayFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.reward_table_id) \ + + encode_int(self.reward_table_sub_id) \ + + encode_int(self.unanalyzed_log_grade_id) \ + + encode_int(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_int(self.common_reward_num) \ + + encode_int(self.strength_min) \ + + encode_int(self.strength_max) \ + + encode_int(self.property_table_sub_id) \ + + encode_int(self.rate) \ + + encode_byte(self.quest_info_display_flag) + +class RewardSetData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.reward_set_id = decode_int(data, off) + off += INT_OFF + + self.reward_set_sub_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_int(data, off) + off += INT_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_int(data, off) + off += INT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "RewardSetData": + ret = cls(b"\x00" * 99, 0) + ret.reward_set_id = data['RewardSetId'] + ret.reward_set_sub_id = data['RewardSetSubId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.reward_set_id) \ + + encode_int(self.reward_set_sub_id) \ + + encode_int(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_int(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) + +class UnanalyzedLogGradeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.unanalyzed_log_grade_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.comment_id, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "UnanalyzedLogGradeData": + ret = cls(b"\x00" * 99, 0) + ret.unanalyzed_log_grade_id = data['UnanalyzedLogGradeId'] + ret.name = data['Name'] + ret.comment_id = data['CommentId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.unanalyzed_log_grade_id) \ + + encode_str(self.name) \ + + encode_str(self.comment_id) + +class AppointLeaderParamData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.appoint_leader_param_id = decode_short(data, off) + off += SHORT_OFF + + self.initial_synchro_rate = decode_int(data, off) + off += INT_OFF + + self.appoint_leader_increment_synchro_rate = decode_int(data, off) + off += INT_OFF + + self.awakening_increment_synchro_rate = decode_int(data, off) + off += INT_OFF + + self.foil_add_synchro_rate = decode_int(data, off) + off += INT_OFF + + self.appoint_leader_trust_bonus = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "AppointLeaderParamData": + ret = cls(b"\x00" * 99, 0) + ret.appoint_leader_param_id = data['AppointLeaderParamId'] + ret.initial_synchro_rate = data['InitialSynchroRate'] + ret.appoint_leader_increment_synchro_rate = data['AppointLeaderIncrementSynchroRate'] + ret.awakening_increment_synchro_rate = data['AwakeningIncrementSynchroRate'] + ret.foil_add_synchro_rate = data['FoilAddSynchroRate'] + ret.appoint_leader_trust_bonus = data['AppointLeaderTrustBonus'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.appoint_leader_param_id) \ + + encode_int(self.initial_synchro_rate) \ + + encode_int(self.appoint_leader_increment_synchro_rate) \ + + encode_int(self.awakening_increment_synchro_rate) \ + + encode_int(self.foil_add_synchro_rate) \ + + encode_int(self.appoint_leader_trust_bonus) + +class AppointLeaderEffectData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.appoint_leader_effect_id = decode_short(data, off) + off += SHORT_OFF + + self.chara_id = decode_short(data, off) + off += SHORT_OFF + + self.info_text_format, new_off = decode_str(data, off) + off += new_off + + self.appoint_leader_effect_type_id = decode_short(data, off) + off += SHORT_OFF + + self.low_effect_value, new_off = decode_str(data, off) + off += new_off + + self.middle_effect_value, new_off = decode_str(data, off) + off += new_off + + self.high_effect_value, new_off = decode_str(data, off) + off += new_off + + self.max_effect_value, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "AppointLeaderEffectData": + ret = cls(b"\x00" * 99, 0) + ret.appoint_leader_effect_id = data['AppointLeaderEffectId'] + ret.chara_id = data['CharaId'] + ret.info_text_format = data['InfoTextFormat'] + ret.appoint_leader_effect_type_id = data['AppointLeaderEffectTypeId'] + ret.low_effect_value = data['LowEffectValue'] + ret.middle_effect_value = data['MiddleEffectValue'] + ret.high_effect_value = data['HighEffectValue'] + ret.max_effect_value = data['MaxEffectValue'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.appoint_leader_effect_id) \ + + encode_short(self.chara_id) \ + + encode_str(self.info_text_format) \ + + encode_short(self.appoint_leader_effect_type_id) \ + + encode_str(self.low_effect_value) \ + + encode_str(self.middle_effect_value) \ + + encode_str(self.high_effect_value) \ + + encode_str(self.max_effect_value) + +class AppointLeaderEffectTypeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.appoint_leader_effect_type_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "AppointLeaderEffectTypeData": + ret = cls(b"\x00" * 99, 0) + ret.appoint_leader_effect_type_id = data['AppointLeaderEffectTypeId'] + ret.name = data['Name'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.appoint_leader_effect_type_id) \ + + encode_str(self.name) + +class RarityData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.rarity_id = decode_short(data, off) + off += SHORT_OFF + + self.require_col_my_card = decode_int(data, off) + off += INT_OFF + + self.require_col_other_card = decode_int(data, off) + off += INT_OFF + + self.require_medal_other_card = decode_int(data, off) + off += INT_OFF + + self.synthesis_exp_rate, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "RarityData": + ret = cls(b"\x00" * 99, 0) + ret.rarity_id = data['RarityId'] + ret.require_col_my_card = data['RequireColMyCard'] + ret.require_col_other_card = data['RequireColOtherCard'] + ret.require_medal_other_card = data['RequireMedalOtherCard'] + ret.synthesis_exp_rate = data['SynthesisExpRate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.rarity_id) \ + + encode_int(self.require_col_my_card) \ + + encode_int(self.require_col_other_card) \ + + encode_int(self.require_medal_other_card) \ + + encode_str(self.synthesis_exp_rate) + +class CompositionEventData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.composition_event_id = decode_short(data, off) + off += SHORT_OFF + + self.composition_exp_rate, new_off = decode_str(data, off) + off += new_off + + self.awakening_exp_rate, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "CompositionEventData": + ret = cls(b"\x00" * 99, 0) + ret.composition_event_id = data['CompositionEventId'] + ret.composition_exp_rate = data['CompositionExpRate'] + ret.awakening_exp_rate = data['AwakeningExpRate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.composition_event_id) \ + + encode_str(self.composition_exp_rate) \ + + encode_str(self.awakening_exp_rate) + +class CompositionParamData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.composition_param_id = decode_short(data, off) + off += SHORT_OFF + + self.use_value = decode_int(data, off) + off += INT_OFF + + self.max_extended_use_coef, new_off = decode_str(data, off) + off += new_off + + self.awakening_coef, new_off = decode_str(data, off) + off += new_off + + self.use_value_support_log = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "CompositionParamData": + ret = cls(b"\x00" * 99, 0) + ret.composition_param_id = data['CompositionParamId'] + ret.use_value = data['UseValue'] + ret.max_extended_use_coef = data['MaxExtendedUseCoef'] + ret.awakening_coef = data['AwakeningCoef'] + ret.use_value_support_log = data['UseValueSupportLog'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.composition_param_id) \ + + encode_int(self.use_value) \ + + encode_str(self.max_extended_use_coef) \ + + encode_str(self.awakening_coef) \ + + encode_int(self.use_value_support_log) + +class GamePlayPriceData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.game_play_price_id = decode_short(data, off) + off += SHORT_OFF + + self.player_rank_id = decode_short(data, off) + off += SHORT_OFF + + self.episode_ticket = decode_int(data, off) + off += INT_OFF + + self.trial_tower_ticket = decode_short(data, off) + off += SHORT_OFF + + self.custom_retry_ticket = decode_short(data, off) + off += SHORT_OFF + + self.subdue_ticket = decode_short(data, off) + off += SHORT_OFF + + self.continue_ticket = decode_short(data, off) + off += SHORT_OFF + + self.continue_credit = decode_short(data, off) + off += SHORT_OFF + + self.extend_time_ticket = decode_short(data, off) + off += SHORT_OFF + + self.reward_grade_up_ticket = decode_short(data, off) + off += SHORT_OFF + + self.reward_grade_up_credit = decode_short(data, off) + off += SHORT_OFF + + self.give_free_ticket = decode_short(data, off) + off += SHORT_OFF + + self.free_continue_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GamePlayPriceData": + ret = cls(b"\x00" * 99, 0) + ret.game_play_price_id = data['GamePlayPriceId'] + ret.player_rank_id = data['PlayerRankId'] + ret.episode_ticket = data['EpisodeTicket'] + ret.trial_tower_ticket = data['TrialTowerTicket'] + ret.custom_retry_ticket = data['CustomRetryTicket'] + ret.subdue_ticket = data['SubdueTicket'] + ret.continue_ticket = data['ContinueTicket'] + ret.continue_credit = data['ContinueCredit'] + ret.extend_time_ticket = data['ExtendTimeTicket'] + ret.reward_grade_up_ticket = data['RewardGradeUpTicket'] + ret.reward_grade_up_credit = data['RewardGradeUpCredit'] + ret.give_free_ticket = data['GiveFreeTicket'] + ret.free_continue_num = data['FreeContinueNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.game_play_price_id) \ + + encode_short(self.player_rank_id) \ + + encode_int(self.episode_ticket) \ + + encode_short(self.trial_tower_ticket) \ + + encode_short(self.custom_retry_ticket) \ + + encode_short(self.subdue_ticket) \ + + encode_short(self.continue_ticket) \ + + encode_short(self.continue_credit) \ + + encode_short(self.extend_time_ticket) \ + + encode_short(self.reward_grade_up_ticket) \ + + encode_short(self.reward_grade_up_credit) \ + + encode_short(self.give_free_ticket) \ + + encode_short(self.free_continue_num) + +class BuyTicketData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.buy_ticket_id = decode_int(data, off) + off += INT_OFF + + self.buy_ticket_pattern = decode_int(data, off) + off += INT_OFF + + self.credit_cnt = decode_int(data, off) + off += INT_OFF + + self.get_ticket_cnt = decode_int(data, off) + off += INT_OFF + + self.get_bonus_vp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BuyTicketData": + ret = cls(b"\x00" * 99, 0) + ret.buy_ticket_id = data['BuyTicketId'] + ret.buy_ticket_pattern = data['BuyTicketPattern'] + ret.credit_cnt = data['CreditCnt'] + ret.get_ticket_cnt = data['GetTicketCnt'] + ret.get_bonus_vp = data['GetBonusVp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.buy_ticket_id) \ + + encode_int(self.buy_ticket_pattern) \ + + encode_int(self.credit_cnt) \ + + encode_int(self.get_ticket_cnt) \ + + encode_int(self.get_bonus_vp) + +class TipsData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.tips_id = decode_int(data, off) + off += INT_OFF + + self.tips_category = decode_byte(data, off) + off += BYTE_OFF + + self.tips_text, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "TipsData": + ret = cls(b"\x00" * 99, 0) + ret.tips_id = data['TipsId'] + ret.tips_category = data['TipsCategory'] + ret.tips_text = data['TipsText'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.tips_id) \ + + encode_byte(self.tips_category) \ + + encode_str(self.tips_text) + +class CapData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.cap_id = decode_short(data, off) + off += SHORT_OFF + + self.trust1_cap = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "CapData": + ret = cls(b"\x00" * 99, 0) + ret.cap_id = data['CapId'] + ret.trust1_cap = data['Trust1Cap'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.cap_id) \ + + encode_int(self.trust1_cap) + +class HeroLogData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.hero_log_id = decode_int(data, off) + off += INT_OFF + + self.chara_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.nickname, new_off = decode_str(data, off) + off += new_off + + self.rarity = decode_byte(data, off) + off += BYTE_OFF + + self.weapon_type_id = decode_short(data, off) + off += SHORT_OFF + + self.hero_log_role_id = decode_short(data, off) + off += SHORT_OFF + + self.costume_type_id = decode_short(data, off) + off += SHORT_OFF + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.default_equipment_id1 = decode_int(data, off) + off += INT_OFF + + self.default_equipment_id2 = decode_int(data, off) + off += INT_OFF + + self.skill_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.hp_min = decode_int(data, off) + off += INT_OFF + + self.hp_max = decode_int(data, off) + off += INT_OFF + + self.str_min = decode_int(data, off) + off += INT_OFF + + self.str_max = decode_int(data, off) + off += INT_OFF + + self.vit_min = decode_int(data, off) + off += INT_OFF + + self.vit_max = decode_int(data, off) + off += INT_OFF + + self.int_min = decode_int(data, off) + off += INT_OFF + + self.int_max = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self.flavor_text, new_off = decode_str(data, off) + off += new_off + + self.sale_price = decode_int(data, off) + off += INT_OFF + + self.composition_exp = decode_int(data, off) + off += INT_OFF + + self.awakening_exp = decode_int(data, off) + off += INT_OFF + + self.slot4_unlock_level = decode_int(data, off) + off += INT_OFF + + self.slot5_unlock_level = decode_int(data, off) + off += INT_OFF + + self.cut_in_image, new_off = decode_str(data, off) + off += new_off + + self.cut_in_image_awake, new_off = decode_str(data, off) + off += new_off + + self.cut_in_upper_side_text = decode_byte(data, off) + off += BYTE_OFF + + self.chara_comment_image, new_off = decode_str(data, off) + off += new_off + + self.chara_comment_image_awake, new_off = decode_str(data, off) + off += new_off + + self.quest_start_introduce, new_off = decode_str(data, off) + off += new_off + + self.quest_start_introduce_awake, new_off = decode_str(data, off) + off += new_off + + self.quest_chara_icon, new_off = decode_str(data, off) + off += new_off + + self.quest_chara_icon_awake, new_off = decode_str(data, off) + off += new_off + + self.quest_chara_icon_loss, new_off = decode_str(data, off) + off += new_off + + self.quest_chara_icon_awake_loss, new_off = decode_str(data, off) + off += new_off + + self.collection_display_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.collection_empty_frame_display_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "HeroLogData": + ret = cls(b"\x00" * 99, 0) + ret.hero_log_id = data['HeroLogId'] + ret.chara_id = data['CharaId'] + ret.name = data['Name'] + ret.nickname = data['Nickname'] + ret.rarity = data['Rarity'] + ret.weapon_type_id = data['WeaponTypeId'] + ret.hero_log_role_id = data['HeroLogRoleId'] + ret.costume_type_id = data['CostumeTypeId'] + ret.unit_id = data['UnitId'] + ret.default_equipment_id1 = data['DefaultEquipmentId1'] + ret.default_equipment_id2 = data['DefaultEquipmentId2'] + ret.skill_table_sub_id = data['SkillTableSubId'] + ret.hp_min = data['HpMin'] + ret.hp_max = data['HpMax'] + ret.str_min = data['StrMin'] + ret.str_max = data['StrMax'] + ret.vit_min = data['VitMin'] + ret.vit_max = data['VitMax'] + ret.int_min = data['IntMin'] + ret.int_max = data['IntMax'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + ret.flavor_text = data['FlavorText'] + ret.sale_price = data['SalePrice'] + ret.composition_exp = data['CompositionExp'] + ret.awakening_exp = data['AwakeningExp'] + ret.slot4_unlock_level = data['Slot4UnlockLevel'] + ret.slot5_unlock_level = data['Slot5UnlockLevel'] + ret.cut_in_image = data['CutinImage'] + ret.cut_in_image_awake = data['CutinImageAwake'] + ret.cut_in_upper_side_text = data['CutinUpperSideText'] + ret.chara_comment_image = data['CharaCommentImage'] + ret.chara_comment_image_awake = data['CharaCommentImageAwake'] + ret.quest_start_introduce = data['QuestStartIntroduce'] + ret.quest_start_introduce_awake = data['QuestStartIntroduceAwake'] + ret.quest_chara_icon = data['QuestCharaIcon'] + ret.quest_chara_icon_awake = data['QuestCharaIconAwake'] + ret.quest_chara_icon_loss = data['QuestCharaIconLoss'] + ret.quest_chara_icon_awake_loss = data['QuestCharaIconAwakeLoss'] + ret.collection_display_start_date = data['CollectionDisplayStartDate'] + ret.collection_empty_frame_display_flag = data['CollectionEmptyFrameDisplayFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.hero_log_id) \ + + encode_short(self.chara_id) \ + + encode_str(self.name) \ + + encode_str(self.nickname) \ + + encode_byte(self.rarity) \ + + encode_short(self.weapon_type_id) \ + + encode_short(self.hero_log_role_id) \ + + encode_short(self.costume_type_id) \ + + encode_int(self.unit_id) \ + + encode_int(self.default_equipment_id1) \ + + encode_int(self.default_equipment_id2) \ + + encode_int(self.skill_table_sub_id) \ + + encode_int(self.hp_min) \ + + encode_int(self.hp_max) \ + + encode_int(self.str_min) \ + + encode_int(self.str_max) \ + + encode_int(self.vit_min) \ + + encode_int(self.vit_max) \ + + encode_int(self.int_min) \ + + encode_int(self.int_max) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) \ + + encode_str(self.flavor_text) \ + + encode_int(self.sale_price) \ + + encode_int(self.composition_exp) \ + + encode_int(self.awakening_exp) \ + + encode_int(self.slot4_unlock_level) \ + + encode_int(self.slot5_unlock_level) \ + + encode_str(self.cut_in_image) \ + + encode_str(self.cut_in_image_awake) \ + + encode_byte(self.cut_in_upper_side_text) \ + + encode_str(self.chara_comment_image) \ + + encode_str(self.chara_comment_image_awake) \ + + encode_str(self.quest_start_introduce) \ + + encode_str(self.quest_start_introduce_awake) \ + + encode_str(self.quest_chara_icon) \ + + encode_str(self.quest_chara_icon_awake) \ + + encode_str(self.quest_chara_icon_loss) \ + + encode_str(self.quest_chara_icon_awake_loss) \ + + encode_date_str(self.collection_display_start_date) \ + + encode_byte(self.collection_empty_frame_display_flag) + +class HeroLogLevelData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.level = decode_short(data, off) + off += SHORT_OFF + + self.require_exp = decode_int(data, off) + off += INT_OFF + + self.total_exp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "HeroLogLevelData": + ret = cls(b"\x00" * 99, 0) + ret.level = data['HeroLogLevelId'] + ret.require_exp = data['RequireExp'] + ret.total_exp = data['TotalExp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.level) \ + + encode_int(self.require_exp) \ + + encode_int(self.total_exp) + +class HeroLogRoleData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.hero_log_role_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "HeroLogRoleData": + ret = cls(b"\x00" * 99, 0) + ret.hero_log_role_id = data['HeroLogRoleId'] + ret.name = data['Name'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.hero_log_role_id) \ + + encode_str(self.name) + +class HeroLogTrustRankData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.rank = decode_short(data, off) + off += SHORT_OFF + + self.total_exp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "HeroLogTrustRankData": + ret = cls(b"\x00" * 99, 0) + ret.rank = data['HeroLogTrustRankId'] + ret.total_exp = data['TotalExp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.rank) \ + + encode_int(self.total_exp) + +class CharaData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.chara_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.roma, new_off = decode_str(data, off) + off += new_off + + self.gender = decode_short(data, off) + off += SHORT_OFF + + self.real_name, new_off = decode_str(data, off) + off += new_off + + self.comment, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "CharaData": + ret = cls(b"\x00" * 99, 0) + ret.chara_id = data['CharaId'] + ret.name = data['Name'] + ret.roma = data['Roma'] + ret.gender = data['Gender'] + ret.real_name = data['RealName'] + ret.comment = data['Comment'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.chara_id) \ + + encode_str(self.name) \ + + encode_str(self.roma) \ + + encode_short(self.gender) \ + + encode_str(self.real_name) \ + + encode_str(self.comment) + +class CharaFriendlyRankData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.rank = decode_short(data, off) + off += SHORT_OFF + + self.total_exp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "CharaFriendlyRankData": + ret = cls(b"\x00" * 99, 0) + ret.rank = data['CharaFriendlyRankId'] + ret.total_exp = data['TotalExp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.rank) \ + + encode_int(self.total_exp) + +class EquipmentData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.equipment_id = decode_int(data, off) + off += INT_OFF + + self.equipment_type = decode_byte(data, off) + off += BYTE_OFF + + self.weapon_type_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.rarity = decode_byte(data, off) + off += BYTE_OFF + + self.prefab, new_off = decode_str(data, off) + off += new_off + + self.power = decode_int(data, off) + off += INT_OFF + + self.strength_increment = decode_int(data, off) + off += INT_OFF + + self.skill_condition = decode_short(data, off) + off += SHORT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self.sale_price = decode_int(data, off) + off += INT_OFF + + self.composition_exp = decode_int(data, off) + off += INT_OFF + + self.awakening_exp = decode_int(data, off) + off += INT_OFF + + self.flavor_text, new_off = decode_str(data, off) + off += new_off + + self.collection_display_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.collection_empty_frame_display_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EquipmentData": + ret = cls(b"\x00" * 99, 0) + ret.equipment_id = data['EquipmentId'] + ret.equipment_type = data['EquipmentType'] + ret.weapon_type_id = data['WeaponTypeId'] + ret.name = data['Name'] + ret.rarity = data['Rarity'] + ret.prefab = data['Prefab'] + ret.power = data['Power'] + ret.strength_increment = data['StrengthIncrement'] + ret.skill_condition = data['SkillCondition'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + ret.sale_price = data['SalePrice'] + ret.composition_exp = data['CompositionExp'] + ret.awakening_exp = data['AwakeningExp'] + ret.flavor_text = data['FlavorText'] + ret.collection_display_start_date = data['CollectionDisplayStartDate'] + ret.collection_empty_frame_display_flag = data['CollectionEmptyFrameDisplayFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.equipment_id) \ + + encode_byte(self.equipment_type) \ + + encode_short(self.weapon_type_id) \ + + encode_str(self.name) \ + + encode_byte(self.rarity) \ + + encode_str(self.prefab) \ + + encode_int(self.power) \ + + encode_int(self.strength_increment) \ + + encode_short(self.skill_condition) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) \ + + encode_int(self.sale_price) \ + + encode_int(self.composition_exp) \ + + encode_int(self.awakening_exp) \ + + encode_str(self.flavor_text) \ + + encode_date_str(self.collection_display_start_date) \ + + encode_byte(self.collection_empty_frame_display_flag) + +class EquipmentLevelData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.level = decode_short(data, off) + off += SHORT_OFF + + self.require_exp = decode_int(data, off) + off += INT_OFF + + self.total_exp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EquipmentLevelData": + ret = cls(b"\x00" * 99, 0) + ret.level = data['EquipmentLevelId'] + ret.require_exp = data['RequireExp'] + ret.total_exp = data['TotalExp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.level) \ + + encode_int(self.require_exp) \ + + encode_int(self.total_exp) + +class WeaponTypeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.weapon_type_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.action_behaviour, new_off = decode_str(data, off) + off += new_off + + self.sound_behaviour, new_off = decode_str(data, off) + off += new_off + + self.physics_attr = decode_short(data, off) + off += SHORT_OFF + + self.main_equip = decode_short(data, off) + off += SHORT_OFF + + self.sub_equip1 = decode_short(data, off) + off += SHORT_OFF + + self.sub_equip2 = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "WeaponTypeData": + ret = cls(b"\x00" * 99, 0) + ret.weapon_type_id = data['WeaponTypeId'] + ret.name = data['Name'] + ret.action_behaviour = data['ActionBehaviour'] + ret.sound_behaviour = data['SoundBehaviour'] + ret.physics_attr = data['PhysicsAttr'] + ret.main_equip = data['MainEquip'] + ret.sub_equip1 = data['SubEquip1'] + ret.sub_equip2 = data['SubEquip2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.weapon_type_id) \ + + encode_str(self.name) \ + + encode_str(self.action_behaviour) \ + + encode_str(self.sound_behaviour) \ + + encode_short(self.physics_attr) \ + + encode_short(self.main_equip) \ + + encode_short(self.sub_equip1) \ + + encode_short(self.sub_equip2) + +class ItemData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.item_id = decode_int(data, off) + off += INT_OFF + + self.item_type = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.rarity = decode_byte(data, off) + off += BYTE_OFF + + self.value = decode_int(data, off) + off += INT_OFF + + self.property_id = decode_int(data, off) + off += INT_OFF + + self.property_value1_min, new_off = decode_str(data, off) + off += new_off + + self.property_value1_max, new_off = decode_str(data, off) + off += new_off + + self.property_value2_min, new_off = decode_str(data, off) + off += new_off + + self.property_value2_max, new_off = decode_str(data, off) + off += new_off + + self.flavor_text, new_off = decode_str(data, off) + off += new_off + + self.sale_price = decode_int(data, off) + off += INT_OFF + + self.item_icon, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ItemData": + ret = cls(b"\x00" * 99, 0) + ret.item_id = data['ItemId'] + ret.item_type = data['ItemTypeId'] + ret.name = data['Name'] + ret.rarity = data['Rarity'] + ret.value = data['Value'] + ret.property_id = data['PropertyId'] + ret.property_value1_min = data['PropertyValue1Min'] + ret.property_value1_max = data['PropertyValue1Max'] + ret.property_value2_min = data['PropertyValue2Min'] + ret.property_value2_max = data['PropertyValue2Max'] + ret.flavor_text = data['FlavorText'] + ret.sale_price = data['SalePrice'] + ret.item_icon = data['ItemIcon'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.item_id) \ + + encode_int(self.item_type) \ + + encode_str(self.name) \ + + encode_byte(self.rarity) \ + + encode_int(self.value) \ + + encode_int(self.property_id) \ + + encode_str(self.property_value1_min) \ + + encode_str(self.property_value1_max) \ + + encode_str(self.property_value2_min) \ + + encode_str(self.property_value2_max) \ + + encode_str(self.flavor_text) \ + + encode_int(self.sale_price) \ + + encode_str(self.item_icon) + +class ItemTypeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.item_type_id = decode_int(data, off) + off += INT_OFF + + self.item_type_name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ItemTypeData": + ret = cls(b"\x00" * 99, 0) + ret.item_type_id = data['ItemTypeId'] + ret.item_type_name = data['ItemTypeName'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.item_type_id) \ + + encode_str(self.item_type_name) + +class BuffItemData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.buff_item_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.flavor_text, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BuffItemData": + ret = cls(b"\x00" * 99, 0) + ret.buff_item_id = data['BuffItemId'] + ret.name = data['Name'] + ret.flavor_text = data['FlavorText'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.buff_item_id) \ + + encode_str(self.name) \ + + encode_str(self.flavor_text) + +class EnemyData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.enemy_id = decode_short(data, off) + off += SHORT_OFF + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EnemyData": + ret = cls(b"\x00" * 99, 0) + ret.enemy_id = data['EnemyId'] + ret.unit_id = data['UnitId'] + ret.name = data['Name'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.enemy_id) \ + + encode_int(self.unit_id) \ + + encode_str(self.name) + +class EnemySetData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.enemy_set_id = decode_int(data, off) + off += INT_OFF + + self.enemy_set_sub_id = decode_int(data, off) + off += INT_OFF + + self.enemy_id = decode_int(data, off) + off += INT_OFF + + self.enemy_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EnemySetData": + ret = cls(b"\x00" * 99, 0) + ret.enemy_set_id = data['EnemySetId'] + ret.enemy_set_sub_id = data['EnemySetSubId'] + ret.enemy_id = data['EnemyId'] + ret.enemy_num = data['EnemyNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.enemy_set_id) \ + + encode_int(self.enemy_set_sub_id) \ + + encode_int(self.enemy_id) \ + + encode_short(self.enemy_num) + +class EnemyKindData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.enemy_kind_id = decode_int(data, off) + off += INT_OFF + + self.enemy_category_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.icon_filepath, new_off = decode_str(data, off) + off += new_off + + self.weak_physics_attr = decode_short(data, off) + off += SHORT_OFF + + self.weak_magic_attr = decode_short(data, off) + off += SHORT_OFF + + self.weak_text, new_off = decode_str(data, off) + off += new_off + + self.resist_text, new_off = decode_str(data, off) + off += new_off + + self.flavor_text, new_off = decode_str(data, off) + off += new_off + + self.collection_display_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.collection_empty_frame_display_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EnemyKindData": + ret = cls(b"\x00" * 99, 0) + ret.enemy_kind_id = data['EnemyKindId'] + ret.enemy_category_id = data['EnemyCategoryId'] + ret.name = data['Name'] + ret.icon_filepath = data['IconFilepath'] + ret.weak_physics_attr = data['WeakPhysicsAttr'] + ret.weak_magic_attr = data['WeakMagicAttr'] + ret.weak_text = data['WeakText'] + ret.resist_text = data['ResistText'] + ret.flavor_text = data['FlavorText'] + ret.collection_display_start_date = data['CollectionDisplayStartDate'] + ret.collection_empty_frame_display_flag = data['CollectionEmptyFrameDisplayFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.enemy_kind_id) \ + + encode_short(self.enemy_category_id) \ + + encode_str(self.name) \ + + encode_str(self.icon_filepath) \ + + encode_short(self.weak_physics_attr) \ + + encode_short(self.weak_magic_attr) \ + + encode_str(self.weak_text) \ + + encode_str(self.resist_text) \ + + encode_str(self.flavor_text) \ + + encode_date_str(self.collection_display_start_date) \ + + encode_byte(self.collection_empty_frame_display_flag) + +class EnemyCategoryData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.enemy_category_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.detail_text, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EnemyCategoryData": + ret = cls(b"\x00" * 99, 0) + ret.enemy_category_id = data['EnemyCategoryId'] + ret.name = data['Name'] + ret.detail_text = data['DetailText'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.enemy_category_id) \ + + encode_str(self.name) \ + + encode_str(self.detail_text) + +class UnitData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.prefab, new_off = decode_str(data, off) + off += new_off + + self.animator, new_off = decode_str(data, off) + off += new_off + + self.collision, new_off = decode_str(data, off) + off += new_off + + self.radius, new_off = decode_str(data, off) + off += new_off + + self.child_unit_id = decode_int(data, off) + off += INT_OFF + + self.stage_start_prefab, new_off = decode_str(data, off) + off += new_off + + self.stage_start_y, new_off = decode_str(data, off) + off += new_off + + self.stage_start_z, new_off = decode_str(data, off) + off += new_off + + self.stage_touch_y, new_off = decode_str(data, off) + off += new_off + + self.stage_touch_z, new_off = decode_str(data, off) + off += new_off + + self.playable = decode_byte(data, off) + off += BYTE_OFF + + self.monster = decode_byte(data, off) + off += BYTE_OFF + + self.gimmick = decode_byte(data, off) + off += BYTE_OFF + + self.anger = decode_byte(data, off) + off += BYTE_OFF + + self.commander = decode_byte(data, off) + off += BYTE_OFF + + self.isolated = decode_byte(data, off) + off += BYTE_OFF + + self.base_behaviour, new_off = decode_str(data, off) + off += new_off + + self.sound_behaviour, new_off = decode_str(data, off) + off += new_off + + self.weapon_type = decode_int(data, off) + off += INT_OFF + + self.poison_time_coef, new_off = decode_str(data, off) + off += new_off + + self.paralysis_time_coef, new_off = decode_str(data, off) + off += new_off + + self.sealed_time_coef, new_off = decode_str(data, off) + off += new_off + + self.question_time_coef, new_off = decode_str(data, off) + off += new_off + + self.blue_rose_time_coef, new_off = decode_str(data, off) + off += new_off + + self.charm_time_coef, new_off = decode_str(data, off) + off += new_off + + self.burning_time_coef, new_off = decode_str(data, off) + off += new_off + + self.invalid_quake = decode_byte(data, off) + off += BYTE_OFF + + self.guard_coef, new_off = decode_str(data, off) + off += new_off + + self.just_guard_time, new_off = decode_str(data, off) + off += new_off + + self.flip_hp = decode_short(data, off) + off += SHORT_OFF + + self.down_hp = decode_short(data, off) + off += SHORT_OFF + + self.flip_recover_time, new_off = decode_str(data, off) + off += new_off + + self.down_recover_time, new_off = decode_str(data, off) + off += new_off + + self.down_time, new_off = decode_str(data, off) + off += new_off + + self.loss_damage = decode_short(data, off) + off += SHORT_OFF + + self.loss_time, new_off = decode_str(data, off) + off += new_off + + self.move_speed, new_off = decode_str(data, off) + off += new_off + + self.move_speed_angry, new_off = decode_str(data, off) + off += new_off + + self.rot_speed, new_off = decode_str(data, off) + off += new_off + + self.rot_speed_angry, new_off = decode_str(data, off) + off += new_off + + self.range_min, new_off = decode_str(data, off) + off += new_off + + self.range_max, new_off = decode_str(data, off) + off += new_off + + self.range_min_angry, new_off = decode_str(data, off) + off += new_off + + self.range_max_angry, new_off = decode_str(data, off) + off += new_off + + self.back_step_speed, new_off = decode_str(data, off) + off += new_off + + self.back_step_speed_angry, new_off = decode_str(data, off) + off += new_off + + self.back_step_cool_time, new_off = decode_str(data, off) + off += new_off + + self.monster_type = decode_short(data, off) + off += SHORT_OFF + + self.monster_type_angry = decode_short(data, off) + off += SHORT_OFF + + self.vs_boss_type = decode_short(data, off) + off += SHORT_OFF + + self.boss_camera_height, new_off = decode_str(data, off) + off += new_off + + self.boss_camera_near_distance, new_off = decode_str(data, off) + off += new_off + + self.boss_camera_far_distance, new_off = decode_str(data, off) + off += new_off + + self.boss_camera_near_range, new_off = decode_str(data, off) + off += new_off + + self.boss_camera_far_range, new_off = decode_str(data, off) + off += new_off + + self.search_range, new_off = decode_str(data, off) + off += new_off + + self.search_angle, new_off = decode_str(data, off) + off += new_off + + self.lost_range, new_off = decode_str(data, off) + off += new_off + + self.home_range, new_off = decode_str(data, off) + off += new_off + + self.roar_id, new_off = decode_str(data, off) + off += new_off + + self.auto_attack_range, new_off = decode_str(data, off) + off += new_off + + self.auto_attack_interval, new_off = decode_str(data, off) + off += new_off + + self.find_priority = decode_short(data, off) + off += SHORT_OFF + + self.find_range_min = decode_short(data, off) + off += SHORT_OFF + + self.find_range_max = decode_short(data, off) + off += SHORT_OFF + + self.leave_range = decode_short(data, off) + off += SHORT_OFF + + self.show_arrow = decode_byte(data, off) + off += BYTE_OFF + + self.find_id, new_off = decode_str(data, off) + off += new_off + + self.leave_id, new_off = decode_str(data, off) + off += new_off + + self.defeat_id, new_off = decode_str(data, off) + off += new_off + + self.warfare_id, new_off = decode_str(data, off) + off += new_off + + self.angry_id, new_off = decode_str(data, off) + off += new_off + + self.bad_state_bone, new_off = decode_str(data, off) + off += new_off + + self.bad_state_offset_x, new_off = decode_str(data, off) + off += new_off + + self.bad_state_offset_y, new_off = decode_str(data, off) + off += new_off + + self.bad_state_offset_z, new_off = decode_str(data, off) + off += new_off + + self.drop_offset_y, new_off = decode_str(data, off) + off += new_off + + self.col_drop_percentage, new_off = decode_str(data, off) + off += new_off + + self.col_drop_amount = decode_short(data, off) + off += SHORT_OFF + + self.vp_drop_percentage, new_off = decode_str(data, off) + off += new_off + + self.vp_drop_amount = decode_short(data, off) + off += SHORT_OFF + + self.enemy_kind_id = decode_int(data, off) + off += INT_OFF + + self.defrag_match_league_point = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "UnitData": + ret = cls(b"\x00" * 99, 0) + ret.unit_id = data['UnitId'] + ret.name = data['Name'] + ret.prefab = data['Prefab'] + ret.animator = data['Animator'] + ret.collision = data['Collision'] + ret.radius = data['Radius'] + ret.child_unit_id = data['ChildUnitId'] + ret.stage_start_prefab = data['StageStartPrefab'] + ret.stage_start_y = data['StageStartY'] + ret.stage_start_z = data['StageStartZ'] + ret.stage_touch_y = data['StageTouchY'] + ret.stage_touch_z = data['StageTouchZ'] + ret.playable = data['Playable'] + ret.monster = data['Monster'] + ret.gimmick = data['Gimmick'] + ret.anger = data['Anger'] + ret.commander = data['Commander'] + ret.isolated = data['Isolated'] + ret.base_behaviour = data['BaseBehaviour'] + ret.sound_behaviour = data['SoundBehaviour'] + ret.weapon_type = data['WeaponType'] + ret.poison_time_coef = data['PoisonTimeCoef'] + ret.paralysis_time_coef = data['ParalysisTimeCoef'] + ret.sealed_time_coef = data['SealedTimeCoef'] + ret.question_time_coef = data['QuestionTimeCoef'] + ret.blue_rose_time_coef = data['BlueRoseTimeCoef'] + ret.charm_time_coef = data['CharmTimeCoef'] + ret.burning_time_coef = data['BurningTimeCoef'] + ret.invalid_quake = data['InvalidQuake'] + ret.guard_coef = data['GuardCoef'] + ret.just_guard_time = data['JustGuardTime'] + ret.flip_hp = data['FlipHp'] + ret.down_hp = data['DownHp'] + ret.flip_recover_time = data['FlipRecoverTime'] + ret.down_recover_time = data['DownRecoverTime'] + ret.down_time = data['DownTime'] + ret.loss_damage = data['LossDamage'] + ret.loss_time = data['LossTime'] + ret.move_speed = data['MoveSpeed'] + ret.move_speed_angry = data['MoveSpeedAngry'] + ret.rot_speed = data['RotSpeed'] + ret.rot_speed_angry = data['RotSpeedAngry'] + ret.range_min = data['RangeMin'] + ret.range_max = data['RangeMax'] + ret.range_min_angry = data['RangeMinAngry'] + ret.range_max_angry = data['RangeMaxAngry'] + ret.back_step_speed = data['BackStepSpeed'] + ret.back_step_speed_angry = data['BackStepSpeedAngry'] + ret.back_step_cool_time = data['BackStepCoolTime'] + ret.monster_type = data['MonsterType'] + ret.monster_type_angry = data['MonsterTypeAngry'] + ret.vs_boss_type = data['VsBossType'] + ret.boss_camera_height = data['BossCameraHeight'] + ret.boss_camera_near_distance = data['BossCameraNearDistance'] + ret.boss_camera_far_distance = data['BossCameraFarDistance'] + ret.boss_camera_near_range = data['BossCameraNearRange'] + ret.boss_camera_far_range = data['BossCameraFarRange'] + ret.search_range = data['SearchRange'] + ret.search_angle = data['SearchAngle'] + ret.lost_range = data['LostRange'] + ret.home_range = data['HomeRange'] + ret.roar_id = data['RoarId'] + ret.auto_attack_range = data['AutoAttackRange'] + ret.auto_attack_interval = data['AutoAttackInterval'] + ret.find_priority = data['FindPriority'] + ret.find_range_min = data['FindRangeMin'] + ret.find_range_max = data['FindRangeMax'] + ret.leave_range = data['LeaveRange'] + ret.show_arrow = data['ShowArrow'] + ret.find_id = data['FindId'] + ret.leave_id = data['LeaveId'] + ret.defeat_id = data['DefeatId'] + ret.warfare_id = data['WarfareId'] + ret.angry_id = data['AngryId'] + ret.bad_state_bone = data['BadStateBone'] + ret.bad_state_offset_x = data['BadStateOffsetX'] + ret.bad_state_offset_y = data['BadStateOffsetY'] + ret.bad_state_offset_z = data['BadStateOffsetZ'] + ret.drop_offset_y = data['DropOffsetY'] + ret.col_drop_percentage = data['ColDropPercentage'] + ret.col_drop_amount = data['ColDropAmount'] + ret.vp_drop_percentage = data['VpDropPercentage'] + ret.vp_drop_amount = data['VpDropAmount'] + ret.enemy_kind_id = data['EnemyKindId'] + ret.defrag_match_league_point = data['DefragMatchLeaguePoint'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.unit_id) \ + + encode_str(self.name) \ + + encode_str(self.prefab) \ + + encode_str(self.animator) \ + + encode_str(self.collision) \ + + encode_str(self.radius) \ + + encode_int(self.child_unit_id) \ + + encode_str(self.stage_start_prefab) \ + + encode_str(self.stage_start_y) \ + + encode_str(self.stage_start_z) \ + + encode_str(self.stage_touch_y) \ + + encode_str(self.stage_touch_z) \ + + encode_byte(self.playable) \ + + encode_byte(self.monster) \ + + encode_byte(self.gimmick) \ + + encode_byte(self.anger) \ + + encode_byte(self.commander) \ + + encode_byte(self.isolated) \ + + encode_str(self.base_behaviour) \ + + encode_str(self.sound_behaviour) \ + + encode_int(self.weapon_type) \ + + encode_str(self.poison_time_coef) \ + + encode_str(self.paralysis_time_coef) \ + + encode_str(self.sealed_time_coef) \ + + encode_str(self.question_time_coef) \ + + encode_str(self.blue_rose_time_coef) \ + + encode_str(self.charm_time_coef) \ + + encode_str(self.burning_time_coef) \ + + encode_byte(self.invalid_quake) \ + + encode_str(self.guard_coef) \ + + encode_str(self.just_guard_time) \ + + encode_short(self.flip_hp) \ + + encode_short(self.down_hp) \ + + encode_str(self.flip_recover_time) \ + + encode_str(self.down_recover_time) \ + + encode_str(self.down_time) \ + + encode_short(self.loss_damage) \ + + encode_str(self.loss_time) \ + + encode_str(self.move_speed) \ + + encode_str(self.move_speed_angry) \ + + encode_str(self.rot_speed) \ + + encode_str(self.rot_speed_angry) \ + + encode_str(self.range_min) \ + + encode_str(self.range_max) \ + + encode_str(self.range_min_angry) \ + + encode_str(self.range_max_angry) \ + + encode_str(self.back_step_speed) \ + + encode_str(self.back_step_speed_angry) \ + + encode_str(self.back_step_cool_time) \ + + encode_short(self.monster_type) \ + + encode_short(self.monster_type_angry) \ + + encode_short(self.vs_boss_type) \ + + encode_str(self.boss_camera_height) \ + + encode_str(self.boss_camera_near_distance) \ + + encode_str(self.boss_camera_far_distance) \ + + encode_str(self.boss_camera_near_range) \ + + encode_str(self.boss_camera_far_range) \ + + encode_str(self.search_range) \ + + encode_str(self.search_angle) \ + + encode_str(self.lost_range) \ + + encode_str(self.home_range) \ + + encode_str(self.roar_id) \ + + encode_str(self.auto_attack_range) \ + + encode_str(self.auto_attack_interval) \ + + encode_short(self.find_priority) \ + + encode_short(self.find_range_min) \ + + encode_short(self.find_range_max) \ + + encode_short(self.leave_range) \ + + encode_byte(self.show_arrow) \ + + encode_str(self.find_id) \ + + encode_str(self.leave_id) \ + + encode_str(self.defeat_id) \ + + encode_str(self.warfare_id) \ + + encode_str(self.angry_id) \ + + encode_str(self.bad_state_bone) \ + + encode_str(self.bad_state_offset_x) \ + + encode_str(self.bad_state_offset_y) \ + + encode_str(self.bad_state_offset_z) \ + + encode_str(self.drop_offset_y) \ + + encode_str(self.col_drop_percentage) \ + + encode_short(self.col_drop_amount) \ + + encode_str(self.vp_drop_percentage) \ + + encode_short(self.vp_drop_amount) \ + + encode_int(self.enemy_kind_id) \ + + encode_int(self.defrag_match_league_point) + +class UnitGimmickData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.unit_gimmick_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.gimmick_type = decode_int(data, off) + off += INT_OFF + + self.range, new_off = decode_str(data, off) + off += new_off + + self.crystal_grade = decode_int(data, off) + off += INT_OFF + + self.col = decode_int(data, off) + off += INT_OFF + + self.skill_exp = decode_int(data, off) + off += INT_OFF + + self.heal_rate, new_off = decode_str(data, off) + off += new_off + + self.gimmick_attack_id = decode_short(data, off) + off += SHORT_OFF + + self.interval, new_off = decode_str(data, off) + off += new_off + + self.summon_count = decode_int(data, off) + off += INT_OFF + + self.effect, new_off = decode_str(data, off) + off += new_off + + self.effect_bone, new_off = decode_str(data, off) + off += new_off + + self.effect_x, new_off = decode_str(data, off) + off += new_off + + self.effect_y, new_off = decode_str(data, off) + off += new_off + + self.effect_z, new_off = decode_str(data, off) + off += new_off + + self.se, new_off = decode_str(data, off) + off += new_off + + self.ground_se, new_off = decode_str(data, off) + off += new_off + + self.sub_state_idle, new_off = decode_str(data, off) + off += new_off + + self.sub_state_reaction, new_off = decode_str(data, off) + off += new_off + + self.sub_state_active, new_off = decode_str(data, off) + off += new_off + + self.sub_state_break, new_off = decode_str(data, off) + off += new_off + + self.time_sub_state_break, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "UnitGimmickData": + ret = cls(b"\x00" * 99, 0) + ret.unit_gimmick_id = data['UnitGimmickId'] + ret.name = data['Name'] + ret.gimmick_type = data['GimmickType'] + ret.range = data['Range'] + ret.crystal_grade = data['CrystalGrade'] + ret.col = data['Col'] + ret.skill_exp = data['SkillExp'] + ret.heal_rate = data['HealRate'] + ret.gimmick_attack_id = data['GimmickAttackId'] + ret.interval = data['Interval'] + ret.summon_count = data['SummonCount'] + ret.effect = data['Effect'] + ret.effect_bone = data['EffectBone'] + ret.effect_x = data['EffectX'] + ret.effect_y = data['EffectY'] + ret.effect_z = data['EffectZ'] + ret.se = data['Se'] + ret.ground_se = data['GroundSe'] + ret.sub_state_idle = data['SubStateIdle'] + ret.sub_state_reaction = data['SubStateReaction'] + ret.sub_state_active = data['SubStateActive'] + ret.sub_state_break = data['SubStateBreak'] + ret.time_sub_state_break = data['TimeSubStateBreak'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.unit_gimmick_id) \ + + encode_str(self.name) \ + + encode_int(self.gimmick_type) \ + + encode_str(self.range) \ + + encode_int(self.crystal_grade) \ + + encode_int(self.col) \ + + encode_int(self.skill_exp) \ + + encode_str(self.heal_rate) \ + + encode_short(self.gimmick_attack_id) \ + + encode_str(self.interval) \ + + encode_int(self.summon_count) \ + + encode_str(self.effect) \ + + encode_str(self.effect_bone) \ + + encode_str(self.effect_x) \ + + encode_str(self.effect_y) \ + + encode_str(self.effect_z) \ + + encode_str(self.se) \ + + encode_str(self.ground_se) \ + + encode_str(self.sub_state_idle) \ + + encode_str(self.sub_state_reaction) \ + + encode_str(self.sub_state_active) \ + + encode_str(self.sub_state_break) \ + + encode_str(self.time_sub_state_break) + +class UnitCollisionData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.unit_collision_id = decode_int(data, off) + off += INT_OFF + + self.keyword, new_off = decode_str(data, off) + off += new_off + + self.name, new_off = decode_str(data, off) + off += new_off + + self.bone, new_off = decode_str(data, off) + off += new_off + + self.usually = decode_byte(data, off) + off += BYTE_OFF + + self.angry = decode_byte(data, off) + off += BYTE_OFF + + self.type_index = decode_short(data, off) + off += SHORT_OFF + + self.begin_x, new_off = decode_str(data, off) + off += new_off + + self.begin_y, new_off = decode_str(data, off) + off += new_off + + self.begin_z, new_off = decode_str(data, off) + off += new_off + + self.end_x, new_off = decode_str(data, off) + off += new_off + + self.end_y, new_off = decode_str(data, off) + off += new_off + + self.end_z, new_off = decode_str(data, off) + off += new_off + + self.radius, new_off = decode_str(data, off) + off += new_off + + self.slash_coef, new_off = decode_str(data, off) + off += new_off + + self.strike_coef, new_off = decode_str(data, off) + off += new_off + + self.thrust_coef, new_off = decode_str(data, off) + off += new_off + + self.fire_coef, new_off = decode_str(data, off) + off += new_off + + self.water_coef, new_off = decode_str(data, off) + off += new_off + + self.air_coef, new_off = decode_str(data, off) + off += new_off + + self.earth_coef, new_off = decode_str(data, off) + off += new_off + + self.holy_coef, new_off = decode_str(data, off) + off += new_off + + self.dark_coef, new_off = decode_str(data, off) + off += new_off + + self.poison_coef, new_off = decode_str(data, off) + off += new_off + + self.paralysis_coef, new_off = decode_str(data, off) + off += new_off + + self.sealed_coef, new_off = decode_str(data, off) + off += new_off + + self.question_coef, new_off = decode_str(data, off) + off += new_off + + self.blue_rose_coef, new_off = decode_str(data, off) + off += new_off + + self.charm_coef, new_off = decode_str(data, off) + off += new_off + + self.burning_coef, new_off = decode_str(data, off) + off += new_off + + self.flip_coef, new_off = decode_str(data, off) + off += new_off + + self.down_coef, new_off = decode_str(data, off) + off += new_off + + self.knock_back_coef, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "UnitCollisionData": + ret = cls(b"\x00" * 99, 0) + ret.unit_collision_id = data['UnitCollisionId'] + ret.keyword = data['Keyword'] + ret.name = data['Name'] + ret.bone = data['Bone'] + ret.usually = data['Usually'] + ret.angry = data['Angry'] + ret.type_index = data['TypeIndex'] + ret.begin_x = data['BeginX'] + ret.begin_y = data['BeginY'] + ret.begin_z = data['BeginZ'] + ret.end_x = data['EndX'] + ret.end_y = data['EndY'] + ret.end_z = data['EndZ'] + ret.radius = data['Radius'] + ret.slash_coef = data['SlashCoef'] + ret.strike_coef = data['StrikeCoef'] + ret.thrust_coef = data['ThrustCoef'] + ret.fire_coef = data['FireCoef'] + ret.water_coef = data['WaterCoef'] + ret.air_coef = data['AirCoef'] + ret.earth_coef = data['EarthCoef'] + ret.holy_coef = data['HolyCoef'] + ret.dark_coef = data['DarkCoef'] + ret.poison_coef = data['PoisonCoef'] + ret.paralysis_coef = data['ParalysisCoef'] + ret.sealed_coef = data['SealedCoef'] + ret.question_coef = data['QuestionCoef'] + ret.blue_rose_coef = data['BlueRoseCoef'] + ret.charm_coef = data['CharmCoef'] + ret.burning_coef = data['BurningCoef'] + ret.flip_coef = data['FlipCoef'] + ret.down_coef = data['DownCoef'] + ret.knock_back_coef = data['KnockBackCoef'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.unit_collision_id) \ + + encode_str(self.keyword) \ + + encode_str(self.name) \ + + encode_str(self.bone) \ + + encode_byte(self.usually) \ + + encode_byte(self.angry) \ + + encode_short(self.type_index) \ + + encode_str(self.begin_x) \ + + encode_str(self.begin_y) \ + + encode_str(self.begin_z) \ + + encode_str(self.end_x) \ + + encode_str(self.end_y) \ + + encode_str(self.end_z) \ + + encode_str(self.radius) \ + + encode_str(self.slash_coef) \ + + encode_str(self.strike_coef) \ + + encode_str(self.thrust_coef) \ + + encode_str(self.fire_coef) \ + + encode_str(self.water_coef) \ + + encode_str(self.air_coef) \ + + encode_str(self.earth_coef) \ + + encode_str(self.holy_coef) \ + + encode_str(self.dark_coef) \ + + encode_str(self.poison_coef) \ + + encode_str(self.paralysis_coef) \ + + encode_str(self.sealed_coef) \ + + encode_str(self.question_coef) \ + + encode_str(self.blue_rose_coef) \ + + encode_str(self.charm_coef) \ + + encode_str(self.burning_coef) \ + + encode_str(self.flip_coef) \ + + encode_str(self.down_coef) \ + + encode_str(self.knock_back_coef) + +class UnitPowerData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.unit_power_id = decode_int(data, off) + off += INT_OFF + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.lv = decode_int(data, off) + off += INT_OFF + + self.param_hp = decode_int(data, off) + off += INT_OFF + + self.param_str = decode_int(data, off) + off += INT_OFF + + self.param_vit = decode_int(data, off) + off += INT_OFF + + self.param_int = decode_int(data, off) + off += INT_OFF + + self.exp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "UnitPowerData": + ret = cls(b"\x00" * 99, 0) + ret.unit_power_id = data['UnitPowerId'] + ret.unit_id = data['UnitId'] + ret.lv = data['Lv'] + ret.param_hp = data['ParamHp'] + ret.param_str = data['ParamStr'] + ret.param_vit = data['ParamVit'] + ret.param_int = data['ParamInt'] + ret.exp = data['Exp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.unit_power_id) \ + + encode_int(self.unit_id) \ + + encode_int(self.lv) \ + + encode_int(self.param_hp) \ + + encode_int(self.param_str) \ + + encode_int(self.param_vit) \ + + encode_int(self.param_int) \ + + encode_int(self.exp) + +class GimmickAttackData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gimmick_attack_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.hit_enemy = decode_byte(data, off) + off += BYTE_OFF + + self.hit_friend = decode_byte(data, off) + off += BYTE_OFF + + self.attack_coef, new_off = decode_str(data, off) + off += new_off + + self.heal_coef, new_off = decode_str(data, off) + off += new_off + + self.flip_damage = decode_short(data, off) + off += SHORT_OFF + + self.down_damage = decode_short(data, off) + off += SHORT_OFF + + self.poison_incidence, new_off = decode_str(data, off) + off += new_off + + self.paralysis_incidence, new_off = decode_str(data, off) + off += new_off + + self.sealed_incidence, new_off = decode_str(data, off) + off += new_off + + self.question_incidence, new_off = decode_str(data, off) + off += new_off + + self.blue_rose_incidence, new_off = decode_str(data, off) + off += new_off + + self.charm_incidence, new_off = decode_str(data, off) + off += new_off + + self.burning_incidence, new_off = decode_str(data, off) + off += new_off + + self.knock_back, new_off = decode_str(data, off) + off += new_off + + self.knock_back_g, new_off = decode_str(data, off) + off += new_off + + self.forward_knock_back = decode_byte(data, off) + off += BYTE_OFF + + self.break_interval, new_off = decode_str(data, off) + off += new_off + + self.attack_type = decode_short(data, off) + off += SHORT_OFF + + self.physics_attr = decode_short(data, off) + off += SHORT_OFF + + self.magic_attr = decode_short(data, off) + off += SHORT_OFF + + self.hit_se, new_off = decode_str(data, off) + off += new_off + + self.weak_se, new_off = decode_str(data, off) + off += new_off + + self.resist_se, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GimmickAttackData": + ret = cls(b"\x00" * 99, 0) + ret.gimmick_attack_id = data['GimmickAttackId'] + ret.name = data['Name'] + ret.hit_enemy = data['HitEnemy'] + ret.hit_friend = data['HitFriend'] + ret.attack_coef = data['AttackCoef'] + ret.heal_coef = data['HealCoef'] + ret.flip_damage = data['FlipDamage'] + ret.down_damage = data['DownDamage'] + ret.poison_incidence = data['PoisonIncidence'] + ret.paralysis_incidence = data['ParalysisIncidence'] + ret.sealed_incidence = data['SealedIncidence'] + ret.question_incidence = data['QuestionIncidence'] + ret.blue_rose_incidence = data['BlueRoseIncidence'] + ret.charm_incidence = data['CharmIncidence'] + ret.burning_incidence = data['BurningIncidence'] + ret.knock_back = data['KnockBack'] + ret.knock_back_g = data['KnockBackG'] + ret.forward_knock_back = data['ForwardKnockBack'] + ret.break_interval = data['BreakInterval'] + ret.attack_type = data['AttackType'] + ret.physics_attr = data['PhysicsAttr'] + ret.magic_attr = data['MagicAttr'] + ret.hit_se = data['HitSe'] + ret.weak_se = data['WeakSe'] + ret.resist_se = data['ResistSe'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.gimmick_attack_id) \ + + encode_str(self.name) \ + + encode_byte(self.hit_enemy) \ + + encode_byte(self.hit_friend) \ + + encode_str(self.attack_coef) \ + + encode_str(self.heal_coef) \ + + encode_short(self.flip_damage) \ + + encode_short(self.down_damage) \ + + encode_str(self.poison_incidence) \ + + encode_str(self.paralysis_incidence) \ + + encode_str(self.sealed_incidence) \ + + encode_str(self.question_incidence) \ + + encode_str(self.blue_rose_incidence) \ + + encode_str(self.charm_incidence) \ + + encode_str(self.burning_incidence) \ + + encode_str(self.knock_back) \ + + encode_str(self.knock_back_g) \ + + encode_byte(self.forward_knock_back) \ + + encode_str(self.break_interval) \ + + encode_short(self.attack_type) \ + + encode_short(self.physics_attr) \ + + encode_short(self.magic_attr) \ + + encode_str(self.hit_se) \ + + encode_str(self.weak_se) \ + + encode_str(self.resist_se) + +class CharaAttackData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.chara_attack_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.attack_coef, new_off = decode_str(data, off) + off += new_off + + self.flip_damage = decode_short(data, off) + off += SHORT_OFF + + self.down_damage = decode_short(data, off) + off += SHORT_OFF + + self.poison_incidence, new_off = decode_str(data, off) + off += new_off + + self.paralysis_incidence, new_off = decode_str(data, off) + off += new_off + + self.sealed_incidence, new_off = decode_str(data, off) + off += new_off + + self.question_incidence, new_off = decode_str(data, off) + off += new_off + + self.blue_rose_incidence, new_off = decode_str(data, off) + off += new_off + + self.charm_incidence, new_off = decode_str(data, off) + off += new_off + + self.knock_back, new_off = decode_str(data, off) + off += new_off + + self.forward_knock_back = decode_byte(data, off) + off += BYTE_OFF + + self.break_interval, new_off = decode_str(data, off) + off += new_off + + self.weapon_slot = decode_short(data, off) + off += SHORT_OFF + + self.attack_type = decode_short(data, off) + off += SHORT_OFF + + self.physics_attr = decode_short(data, off) + off += SHORT_OFF + + self.magic_attr = decode_short(data, off) + off += SHORT_OFF + + self.spell_blast = decode_byte(data, off) + off += BYTE_OFF + + self.hit_se, new_off = decode_str(data, off) + off += new_off + + self.weak_se, new_off = decode_str(data, off) + off += new_off + + self.resist_se, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "CharaAttackData": + ret = cls(b"\x00" * 99, 0) + ret.chara_attack_id = data['CharaAttackId'] + ret.name = data['Name'] + ret.attack_coef = data['AttackCoef'] + ret.flip_damage = data['FlipDamage'] + ret.down_damage = data['DownDamage'] + ret.poison_incidence = data['PoisonIncidence'] + ret.paralysis_incidence = data['ParalysisIncidence'] + ret.sealed_incidence = data['SealedIncidence'] + ret.question_incidence = data['QuestionIncidence'] + ret.blue_rose_incidence = data['BlueRoseIncidence'] + ret.charm_incidence = data['CharmIncidence'] + ret.knock_back = data['KnockBack'] + ret.forward_knock_back = data['ForwardKnockBack'] + ret.break_interval = data['BreakInterval'] + ret.weapon_slot = data['WeaponSlot'] + ret.attack_type = data['AttackType'] + ret.physics_attr = data['PhysicsAttr'] + ret.magic_attr = data['MagicAttr'] + ret.spell_blast = data['SpellBlast'] + ret.hit_se = data['HitSe'] + ret.weak_se = data['WeakSe'] + ret.resist_se = data['ResistSe'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.chara_attack_id) \ + + encode_str(self.name) \ + + encode_str(self.attack_coef) \ + + encode_short(self.flip_damage) \ + + encode_short(self.down_damage) \ + + encode_str(self.poison_incidence) \ + + encode_str(self.paralysis_incidence) \ + + encode_str(self.sealed_incidence) \ + + encode_str(self.question_incidence) \ + + encode_str(self.blue_rose_incidence) \ + + encode_str(self.charm_incidence) \ + + encode_str(self.knock_back) \ + + encode_byte(self.forward_knock_back) \ + + encode_str(self.break_interval) \ + + encode_short(self.weapon_slot) \ + + encode_short(self.attack_type) \ + + encode_short(self.physics_attr) \ + + encode_short(self.magic_attr) \ + + encode_byte(self.spell_blast) \ + + encode_str(self.hit_se) \ + + encode_str(self.weak_se) \ + + encode_str(self.resist_se) + +class BossAttackData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.boss_attack_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.attack_coef, new_off = decode_str(data, off) + off += new_off + + self.flip_damage = decode_short(data, off) + off += SHORT_OFF + + self.down_damage = decode_short(data, off) + off += SHORT_OFF + + self.poison_incidence, new_off = decode_str(data, off) + off += new_off + + self.sealed_incidence, new_off = decode_str(data, off) + off += new_off + + self.question_incidence, new_off = decode_str(data, off) + off += new_off + + self.reduce_max_hp_incidence, new_off = decode_str(data, off) + off += new_off + + self.burning_incidence, new_off = decode_str(data, off) + off += new_off + + self.quake = decode_byte(data, off) + off += BYTE_OFF + + self.can_parry = decode_byte(data, off) + off += BYTE_OFF + + self.knock_back, new_off = decode_str(data, off) + off += new_off + + self.knock_back_g, new_off = decode_str(data, off) + off += new_off + + self.forward_knock_back = decode_byte(data, off) + off += BYTE_OFF + + self.attack_type = decode_short(data, off) + off += SHORT_OFF + + self.physics_attr = decode_short(data, off) + off += SHORT_OFF + + self.magic_attr = decode_short(data, off) + off += SHORT_OFF + + self.spell_blast = decode_byte(data, off) + off += BYTE_OFF + + self.hit_se, new_off = decode_str(data, off) + off += new_off + + self.weak_se, new_off = decode_str(data, off) + off += new_off + + self.resist_se, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BossAttackData": + ret = cls(b"\x00" * 99, 0) + ret.boss_attack_id = data['BossAttackId'] + ret.name = data['Name'] + ret.attack_coef = data['AttackCoef'] + ret.flip_damage = data['FlipDamage'] + ret.down_damage = data['DownDamage'] + ret.poison_incidence = data['PoisonIncidence'] + ret.sealed_incidence = data['SealedIncidence'] + ret.question_incidence = data['QuestionIncidence'] + ret.reduce_max_hp_incidence = data['ReduceMaxHpIncidence'] + ret.burning_incidence = data['BurningIncidence'] + ret.quake = data['Quake'] + ret.can_parry = data['CanParry'] + ret.knock_back = data['KnockBack'] + ret.knock_back_g = data['KnockBackG'] + ret.forward_knock_back = data['ForwardKnockBack'] + ret.attack_type = data['AttackType'] + ret.physics_attr = data['PhysicsAttr'] + ret.magic_attr = data['MagicAttr'] + ret.spell_blast = data['SpellBlast'] + ret.hit_se = data['HitSe'] + ret.weak_se = data['WeakSe'] + ret.resist_se = data['ResistSe'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.boss_attack_id) \ + + encode_str(self.name) \ + + encode_str(self.attack_coef) \ + + encode_short(self.flip_damage) \ + + encode_short(self.down_damage) \ + + encode_str(self.poison_incidence) \ + + encode_str(self.sealed_incidence) \ + + encode_str(self.question_incidence) \ + + encode_str(self.reduce_max_hp_incidence) \ + + encode_str(self.burning_incidence) \ + + encode_byte(self.quake) \ + + encode_byte(self.can_parry) \ + + encode_str(self.knock_back) \ + + encode_str(self.knock_back_g) \ + + encode_byte(self.forward_knock_back) \ + + encode_short(self.attack_type) \ + + encode_short(self.physics_attr) \ + + encode_short(self.magic_attr) \ + + encode_byte(self.spell_blast) \ + + encode_str(self.hit_se) \ + + encode_str(self.weak_se) \ + + encode_str(self.resist_se) + +class MonsterAttackData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.monster_attack_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.attack_coef, new_off = decode_str(data, off) + off += new_off + + self.flip_damage = decode_short(data, off) + off += SHORT_OFF + + self.down_damage = decode_short(data, off) + off += SHORT_OFF + + self.poison_incidence, new_off = decode_str(data, off) + off += new_off + + self.sealed_incidence, new_off = decode_str(data, off) + off += new_off + + self.question_incidence, new_off = decode_str(data, off) + off += new_off + + self.reduce_max_hp_incidence, new_off = decode_str(data, off) + off += new_off + + self.burning_incidence, new_off = decode_str(data, off) + off += new_off + + self.quake = decode_byte(data, off) + off += BYTE_OFF + + self.can_parry = decode_byte(data, off) + off += BYTE_OFF + + self.knock_back, new_off = decode_str(data, off) + off += new_off + + self.knock_back_g, new_off = decode_str(data, off) + off += new_off + + self.forward_knock_back = decode_byte(data, off) + off += BYTE_OFF + + self.attack_type = decode_short(data, off) + off += SHORT_OFF + + self.physics_attr = decode_short(data, off) + off += SHORT_OFF + + self.magic_attr = decode_short(data, off) + off += SHORT_OFF + + self.spell_blast = decode_byte(data, off) + off += BYTE_OFF + + self.hit_se, new_off = decode_str(data, off) + off += new_off + + self.weak_se, new_off = decode_str(data, off) + off += new_off + + self.resist_se, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "MonsterAttackData": + ret = cls(b"\x00" * 99, 0) + ret.monster_attack_id = data['MonsterAttackId'] + ret.name = data['Name'] + ret.attack_coef = data['AttackCoef'] + ret.flip_damage = data['FlipDamage'] + ret.down_damage = data['DownDamage'] + ret.poison_incidence = data['PoisonIncidence'] + ret.sealed_incidence = data['SealedIncidence'] + ret.question_incidence = data['QuestionIncidence'] + ret.reduce_max_hp_incidence = data['ReduceMaxHpIncidence'] + ret.burning_incidence = data['BurningIncidence'] + ret.quake = data['Quake'] + ret.can_parry = data['CanParry'] + ret.knock_back = data['KnockBack'] + ret.knock_back_g = data['KnockBackG'] + ret.forward_knock_back = data['ForwardKnockBack'] + ret.attack_type = data['AttackType'] + ret.physics_attr = data['PhysicsAttr'] + ret.magic_attr = data['MagicAttr'] + ret.spell_blast = data['SpellBlast'] + ret.hit_se = data['HitSe'] + ret.weak_se = data['WeakSe'] + ret.resist_se = data['ResistSe'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.monster_attack_id) \ + + encode_str(self.name) \ + + encode_str(self.attack_coef) \ + + encode_short(self.flip_damage) \ + + encode_short(self.down_damage) \ + + encode_str(self.poison_incidence) \ + + encode_str(self.sealed_incidence) \ + + encode_str(self.question_incidence) \ + + encode_str(self.reduce_max_hp_incidence) \ + + encode_str(self.burning_incidence) \ + + encode_byte(self.quake) \ + + encode_byte(self.can_parry) \ + + encode_str(self.knock_back) \ + + encode_str(self.knock_back_g) \ + + encode_byte(self.forward_knock_back) \ + + encode_short(self.attack_type) \ + + encode_short(self.physics_attr) \ + + encode_short(self.magic_attr) \ + + encode_byte(self.spell_blast) \ + + encode_str(self.hit_se) \ + + encode_str(self.weak_se) \ + + encode_str(self.resist_se) + +class MonsterActionData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.monster_action_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.slot = decode_int(data, off) + off += INT_OFF + + self.usable_lv = decode_int(data, off) + off += INT_OFF + + self.use_count = decode_int(data, off) + off += INT_OFF + + self.not_angry = decode_byte(data, off) + off += BYTE_OFF + + self.is_angry = decode_byte(data, off) + off += BYTE_OFF + + self.can_sealed = decode_byte(data, off) + off += BYTE_OFF + + self.multi_play_only = decode_byte(data, off) + off += BYTE_OFF + + self.angle_min, new_off = decode_str(data, off) + off += new_off + + self.angle_max, new_off = decode_str(data, off) + off += new_off + + self.range_min, new_off = decode_str(data, off) + off += new_off + + self.range_max, new_off = decode_str(data, off) + off += new_off + + self.attack_time, new_off = decode_str(data, off) + off += new_off + + self.delay_time, new_off = decode_str(data, off) + off += new_off + + self.cool_time, new_off = decode_str(data, off) + off += new_off + + self.state, new_off = decode_str(data, off) + off += new_off + + self.sub_state, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "MonsterActionData": + ret = cls(b"\x00" * 99, 0) + ret.monster_action_id = data['MonsterActionId'] + ret.name = data['Name'] + ret.unit_id = data['UnitId'] + ret.slot = data['Slot'] + ret.usable_lv = data['UsableLv'] + ret.use_count = data['UseCount'] + ret.not_angry = data['NotAngry'] + ret.is_angry = data['IsAngry'] + ret.can_sealed = data['CanSealed'] + ret.multi_play_only = data['MultiPlayOnly'] + ret.angle_min = data['AngleMin'] + ret.angle_max = data['AngleMax'] + ret.range_min = data['RangeMin'] + ret.range_max = data['RangeMax'] + ret.attack_time = data['AttackTime'] + ret.delay_time = data['DelayTime'] + ret.cool_time = data['CoolTime'] + ret.state = data['State'] + ret.sub_state = data['SubState'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.monster_action_id) \ + + encode_str(self.name) \ + + encode_int(self.unit_id) \ + + encode_int(self.slot) \ + + encode_int(self.usable_lv) \ + + encode_int(self.use_count) \ + + encode_byte(self.not_angry) \ + + encode_byte(self.is_angry) \ + + encode_byte(self.can_sealed) \ + + encode_byte(self.multi_play_only) \ + + encode_str(self.angle_min) \ + + encode_str(self.angle_max) \ + + encode_str(self.range_min) \ + + encode_str(self.range_max) \ + + encode_str(self.attack_time) \ + + encode_str(self.delay_time) \ + + encode_str(self.cool_time) \ + + encode_str(self.state) \ + + encode_str(self.sub_state) + +class PropertyData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.property_id = decode_int(data, off) + off += INT_OFF + + self.property_target_type = decode_short(data, off) + off += SHORT_OFF + + self.property_name, new_off = decode_str(data, off) + off += new_off + + self.property_name_format, new_off = decode_str(data, off) + off += new_off + + self.property_type_id = decode_int(data, off) + off += INT_OFF + + self.value1_min = decode_int(data, off) + off += INT_OFF + + self.value1_max = decode_int(data, off) + off += INT_OFF + + self.value2_min = decode_int(data, off) + off += INT_OFF + + self.value2_max = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "PropertyData": + ret = cls(b"\x00" * 99, 0) + ret.property_id = data['PropertyId'] + ret.property_target_type = data['PropertyTargetType'] + ret.property_name = data['PropertyName'] + ret.property_name_format = data['PropertyNameFormat'] + ret.property_type_id = data['PropertyTypeId'] + ret.value1_min = data['Value1Min'] + ret.value1_max = data['Value1Max'] + ret.value2_min = data['Value2Min'] + ret.value2_max = data['Value2Max'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.property_id) \ + + encode_short(self.property_target_type) \ + + encode_str(self.property_name) \ + + encode_str(self.property_name_format) \ + + encode_int(self.property_type_id) \ + + encode_int(self.value1_min) \ + + encode_int(self.value1_max) \ + + encode_int(self.value2_min) \ + + encode_int(self.value2_max) + +class PropertyTableData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.property_table_id = decode_int(data, off) + off += INT_OFF + + self.property_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.property_id = decode_int(data, off) + off += INT_OFF + + self.value1_min = decode_int(data, off) + off += INT_OFF + + self.value1_max = decode_int(data, off) + off += INT_OFF + + self.value2_min = decode_int(data, off) + off += INT_OFF + + self.value2_max = decode_int(data, off) + off += INT_OFF + + self.rate = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "PropertyTableData": + ret = cls(b"\x00" * 99, 0) + ret.property_table_id = data['PropertyTableId'] + ret.property_table_sub_id = data['PropertyTableSubId'] + ret.property_id = data['PropertyId'] + ret.value1_min = data['Value1Min'] + ret.value1_max = data['Value1Max'] + ret.value2_min = data['Value2Min'] + ret.value2_max = data['Value2Max'] + ret.rate = data['Rate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.property_table_id) \ + + encode_int(self.property_table_sub_id) \ + + encode_int(self.property_id) \ + + encode_int(self.value1_min) \ + + encode_int(self.value1_max) \ + + encode_int(self.value2_min) \ + + encode_int(self.value2_max) \ + + encode_int(self.rate) + +class PropertyTypeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.property_type_id = decode_int(data, off) + off += INT_OFF + + self.property_type_name, new_off = decode_str(data, off) + off += new_off + + self.physics_attr = decode_int(data, off) + off += INT_OFF + + self.magic_attr = decode_int(data, off) + off += INT_OFF + + self.permission_same_id_flag = decode_byte(data, off) + off += BYTE_OFF + + self.auto_equip_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "PropertyTypeData": + ret = cls(b"\x00" * 99, 0) + ret.property_type_id = data['PropertyTypeId'] + ret.property_type_name = data['PropertyTypeName'] + ret.physics_attr = data['PhysicsAttr'] + ret.magic_attr = data['MagicAttr'] + ret.permission_same_id_flag = data['PermissionSameIdFlag'] + ret.auto_equip_flag = data['AutoEquipFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.property_type_id) \ + + encode_str(self.property_type_name) \ + + encode_int(self.physics_attr) \ + + encode_int(self.magic_attr) \ + + encode_byte(self.permission_same_id_flag) \ + + encode_byte(self.auto_equip_flag) + +class SkillData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.skill_id = decode_short(data, off) + off += SHORT_OFF + + self.weapon_type_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.attack = decode_byte(data, off) + off += BYTE_OFF + + self.passive = decode_byte(data, off) + off += BYTE_OFF + + self.pet = decode_byte(data, off) + off += BYTE_OFF + + self.level = decode_short(data, off) + off += SHORT_OFF + + self.skill_condition = decode_short(data, off) + off += SHORT_OFF + + self.cool_time, new_off = decode_str(data, off) + off += new_off + + self.sword_color_r, new_off = decode_str(data, off) + off += new_off + + self.sword_color_g, new_off = decode_str(data, off) + off += new_off + + self.sword_color_b, new_off = decode_str(data, off) + off += new_off + + self.motion_index = decode_short(data, off) + off += SHORT_OFF + + self.state, new_off = decode_str(data, off) + off += new_off + + self.sub_state, new_off = decode_str(data, off) + off += new_off + + self.skill_icon, new_off = decode_str(data, off) + off += new_off + + self.friend_skill_icon, new_off = decode_str(data, off) + off += new_off + + self.info_text, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "SkillData": + ret = cls(b"\x00" * 99, 0) + ret.skill_id = data['SkillId'] + ret.weapon_type_id = data['WeaponTypeId'] + ret.name = data['Name'] + ret.attack = data['Attack'] + ret.passive = data['Passive'] + ret.pet = data['Pet'] + ret.level = data['Level'] + ret.skill_condition = data['SkillCondition'] + ret.cool_time = data['CoolTime'] + ret.sword_color_r = data['SwordColorR'] + ret.sword_color_g = data['SwordColorG'] + ret.sword_color_b = data['SwordColorB'] + ret.motion_index = data['MotionIndex'] + ret.state = data['State'] + ret.sub_state = data['SubState'] + ret.skill_icon = data['SkillIcon'] + ret.friend_skill_icon = data['FriendSkillIcon'] + ret.info_text = data['InfoText'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.skill_id) \ + + encode_short(self.weapon_type_id) \ + + encode_str(self.name) \ + + encode_byte(self.attack) \ + + encode_byte(self.passive) \ + + encode_byte(self.pet) \ + + encode_short(self.level) \ + + encode_short(self.skill_condition) \ + + encode_str(self.cool_time) \ + + encode_str(self.sword_color_r) \ + + encode_str(self.sword_color_g) \ + + encode_str(self.sword_color_b) \ + + encode_short(self.motion_index) \ + + encode_str(self.state) \ + + encode_str(self.sub_state) \ + + encode_str(self.skill_icon) \ + + encode_str(self.friend_skill_icon) \ + + encode_str(self.info_text) + +class SkillTableData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.skill_table_id = decode_int(data, off) + off += INT_OFF + + self.skill_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.level = decode_int(data, off) + off += INT_OFF + + self.awakening_id = decode_int(data, off) + off += INT_OFF + + self.skill_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "SkillTableData": + ret = cls(b"\x00" * 99, 0) + ret.skill_table_id = data['SkillTableId'] + ret.skill_table_sub_id = data['SkillTableSubId'] + ret.level = data['Level'] + ret.awakening_id = data['AwakeningId'] + ret.skill_id = data['SkillId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.skill_table_id) \ + + encode_int(self.skill_table_sub_id) \ + + encode_int(self.level) \ + + encode_int(self.awakening_id) \ + + encode_int(self.skill_id) + +class SkillLevelData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.skill_level_id = decode_short(data, off) + off += SHORT_OFF + + self.exp = decode_int(data, off) + off += INT_OFF + + self.exp_total = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "SkillLevelData": + ret = cls(b"\x00" * 99, 0) + ret.skill_level_id = data['SkillLevelId'] + ret.exp = data['Exp'] + ret.exp_total = data['ExpTotal'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.skill_level_id) \ + + encode_int(self.exp) \ + + encode_int(self.exp_total) + +class AwakeningData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.awakening_id = decode_short(data, off) + off += SHORT_OFF + + self.total_exp = decode_int(data, off) + off += INT_OFF + + self.bonus_hero_log, new_off = decode_str(data, off) + off += new_off + + self.bonus_weapon, new_off = decode_str(data, off) + off += new_off + + self.bonus_armor, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "AwakeningData": + ret = cls(b"\x00" * 99, 0) + ret.awakening_id = data['AwakeningId'] + ret.total_exp = data['TotalExp'] + ret.bonus_hero_log = data['BonusHeroLog'] + ret.bonus_weapon = data['BonusWeapon'] + ret.bonus_armor = data['BonusArmor'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.awakening_id) \ + + encode_int(self.total_exp) \ + + encode_str(self.bonus_hero_log) \ + + encode_str(self.bonus_weapon) \ + + encode_str(self.bonus_armor) + +class SynchroSkillData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.synchro_skill_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.name_in_skill_cutin, new_off = decode_str(data, off) + off += new_off + + self.sub_state, new_off = decode_str(data, off) + off += new_off + + self.chara_id = decode_short(data, off) + off += SHORT_OFF + + self.icon_file_path, new_off = decode_str(data, off) + off += new_off + + self.info_text, new_off = decode_str(data, off) + off += new_off + + self.se_name, new_off = decode_str(data, off) + off += new_off + + self.voice_id, new_off = decode_str(data, off) + off += new_off + + self.delay_time = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "SynchroSkillData": + ret = cls(b"\x00" * 99, 0) + ret.synchro_skill_id = data['SynchroSkillId'] + ret.name = data['Name'] + ret.name_in_skill_cutin = data['NameInSkillCutin'] + ret.sub_state = data['SubState'] + ret.chara_id = data['CharaId'] + ret.icon_file_path = data['IconFilePath'] + ret.info_text = data['InfoText'] + ret.se_name = data['SeName'] + ret.voice_id = data['VoiceId'] + ret.delay_time = data['DelayTime'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.synchro_skill_id) \ + + encode_str(self.name) \ + + encode_str(self.name_in_skill_cutin) \ + + encode_str(self.sub_state) \ + + encode_short(self.chara_id) \ + + encode_str(self.icon_file_path) \ + + encode_str(self.info_text) \ + + encode_str(self.se_name) \ + + encode_str(self.voice_id) \ + + encode_int(self.delay_time) + +class SoundSkillCutInVoiceData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.sound_skill_cut_in_voice_id = decode_short(data, off) + off += SHORT_OFF + + self.skill_id = decode_int(data, off) + off += INT_OFF + + self.chara_id = decode_int(data, off) + off += INT_OFF + + self.record_id, new_off = decode_str(data, off) + off += new_off + + self.que_name, new_off = decode_str(data, off) + off += new_off + + self.delay_time = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "SoundSkillCutInVoiceData": + ret = cls(b"\x00" * 99, 0) + ret.sound_skill_cut_in_voice_id = data['SoundSkillCutInVoiceId'] + ret.skill_id = data['SkillId'] + ret.chara_id = data['CharaId'] + ret.record_id = data['RecordId'] + ret.que_name = data['QueName'] + ret.delay_time = data['DelayTime'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.sound_skill_cut_in_voice_id) \ + + encode_int(self.skill_id) \ + + encode_int(self.chara_id) \ + + encode_str(self.record_id) \ + + encode_str(self.que_name) \ + + encode_int(self.delay_time) + +class QuestSceneData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_scene_id = decode_short(data, off) + off += SHORT_OFF + + self.sort_no = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.map_data, new_off = decode_str(data, off) + off += new_off + + self.unit_data, new_off = decode_str(data, off) + off += new_off + + self.demo_map, new_off = decode_str(data, off) + off += new_off + + self.bgm_basic, new_off = decode_str(data, off) + off += new_off + + self.bgm_boss, new_off = decode_str(data, off) + off += new_off + + self.tutorial = decode_byte(data, off) + off += BYTE_OFF + + self.chara_comment_id_0 = decode_int(data, off) + off += INT_OFF + + self.chara_comment_id_1 = decode_int(data, off) + off += INT_OFF + + self.chara_comment_id_2 = decode_int(data, off) + off += INT_OFF + + self.chara_comment_id_3 = decode_int(data, off) + off += INT_OFF + + self.chara_comment_id_4 = decode_int(data, off) + off += INT_OFF + + self.col_rate, new_off = decode_str(data, off) + off += new_off + + self.limit_default = decode_int(data, off) + off += INT_OFF + + self.limit_time_dec, new_off = decode_str(data, off) + off += new_off + + self.limit_chara_dec, new_off = decode_str(data, off) + off += new_off + + self.limit_resurrection = decode_int(data, off) + off += INT_OFF + + self.mission_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.mission_enemy_lv_limit = decode_short(data, off) + off += SHORT_OFF + + self.reward_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.player_trace_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.success_player_exp = decode_int(data, off) + off += INT_OFF + + self.failed_player_exp = decode_int(data, off) + off += INT_OFF + + self.greed_spawn_wait_count = decode_int(data, off) + off += INT_OFF + + self.honey_spawn_wait_count = decode_int(data, off) + off += INT_OFF + + self.menu_display_enemy_set_id = decode_int(data, off) + off += INT_OFF + + self.stage_filepath, new_off = decode_str(data, off) + off += new_off + + self.rarity_up_chance_rate, new_off = decode_str(data, off) + off += new_off + + self.pair_mob_hp_rate, new_off = decode_str(data, off) + off += new_off + + self.pair_mob_atk_rate, new_off = decode_str(data, off) + off += new_off + + self.pair_leader_hp_rate, new_off = decode_str(data, off) + off += new_off + + self.pair_leader_atk_rate, new_off = decode_str(data, off) + off += new_off + + self.pair_boss_hp_rate, new_off = decode_str(data, off) + off += new_off + + self.pair_boss_atk_rate, new_off = decode_str(data, off) + off += new_off + + self.pair_exp_rate, new_off = decode_str(data, off) + off += new_off + + self.trio_mob_hp_rate, new_off = decode_str(data, off) + off += new_off + + self.trio_mob_atk_rate, new_off = decode_str(data, off) + off += new_off + + self.trio_leader_hp_rate, new_off = decode_str(data, off) + off += new_off + + self.trio_leader_atk_rate, new_off = decode_str(data, off) + off += new_off + + self.trio_boss_hp_rate, new_off = decode_str(data, off) + off += new_off + + self.trio_boss_atk_rate, new_off = decode_str(data, off) + off += new_off + + self.trio_exp_rate, new_off = decode_str(data, off) + off += new_off + + self.single_reward_vp = decode_int(data, off) + off += INT_OFF + + self.pair_reward_vp = decode_int(data, off) + off += INT_OFF + + self.trio_reward_vp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestSceneData": + ret = cls(b"\x00" * 99, 0) + ret.quest_scene_id = data['QuestSceneId'] + ret.sort_no = data['SortNo'] + ret.name = data['Name'] + ret.map_data = data['MapData'] + ret.unit_data = data['UnitData'] + ret.demo_map = data['DemoMap'] + ret.bgm_basic = data['BgmBasic'] + ret.bgm_boss = data['BgmBoss'] + ret.tutorial = data['Tutorial'] + ret.chara_comment_id_0 = data['CharaCommentId0'] + ret.chara_comment_id_1 = data['CharaCommentId1'] + ret.chara_comment_id_2 = data['CharaCommentId2'] + ret.chara_comment_id_3 = data['CharaCommentId3'] + ret.chara_comment_id_4 = data['CharaCommentId4'] + ret.col_rate = data['ColRate'] + ret.limit_default = data['LimitDefault'] + ret.limit_time_dec = data['LimitTimeDec'] + ret.limit_chara_dec = data['LimitCharaDec'] + ret.limit_resurrection = data['LimitResurrection'] + ret.mission_table_sub_id = data['MissionTableSubId'] + ret.mission_enemy_lv_limit = data['MissionEnemyLvLimit'] + ret.reward_table_sub_id = data['RewardTableSubId'] + ret.player_trace_table_sub_id = data['PlayerTraceTableSubId'] + ret.success_player_exp = data['SuccessPlayerExp'] + ret.failed_player_exp = data['FailedPlayerExp'] + ret.greed_spawn_wait_count = data['GreedSpawnWaitCount'] + ret.honey_spawn_wait_count = data['HoneySpawnWaitCount'] + ret.menu_display_enemy_set_id = data['MenuDisplayEnemySetId'] + ret.stage_filepath = data['StageFilepath'] + ret.rarity_up_chance_rate = data['RarityUpChanceRate'] + ret.pair_mob_hp_rate = data['PairMobHpRate'] + ret.pair_mob_atk_rate = data['PairMobAtkRate'] + ret.pair_leader_hp_rate = data['PairLeaderHpRate'] + ret.pair_leader_atk_rate = data['PairLeaderAtkRate'] + ret.pair_boss_hp_rate = data['PairBossHpRate'] + ret.pair_boss_atk_rate = data['PairBossAtkRate'] + ret.pair_exp_rate = data['PairExpRate'] + ret.trio_mob_hp_rate = data['TrioMobHpRate'] + ret.trio_mob_atk_rate = data['TrioMobAtkRate'] + ret.trio_leader_hp_rate = data['TrioLeaderHpRate'] + ret.trio_leader_atk_rate = data['TrioLeaderAtkRate'] + ret.trio_boss_hp_rate = data['TrioBossHpRate'] + ret.trio_boss_atk_rate = data['TrioBossAtkRate'] + ret.trio_exp_rate = data['TrioExpRate'] + ret.single_reward_vp = data['SingleRewardVp'] + ret.pair_reward_vp = data['PairRewardVp'] + ret.trio_reward_vp = data['TrioRewardVp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.quest_scene_id) \ + + encode_short(self.sort_no) \ + + encode_str(self.name) \ + + encode_str(self.map_data) \ + + encode_str(self.unit_data) \ + + encode_str(self.demo_map) \ + + encode_str(self.bgm_basic) \ + + encode_str(self.bgm_boss) \ + + encode_byte(self.tutorial) \ + + encode_int(self.chara_comment_id_0) \ + + encode_int(self.chara_comment_id_1) \ + + encode_int(self.chara_comment_id_2) \ + + encode_int(self.chara_comment_id_3) \ + + encode_int(self.chara_comment_id_4) \ + + encode_str(self.col_rate) \ + + encode_int(self.limit_default) \ + + encode_str(self.limit_time_dec) \ + + encode_str(self.limit_chara_dec) \ + + encode_int(self.limit_resurrection) \ + + encode_int(self.mission_table_sub_id) \ + + encode_short(self.mission_enemy_lv_limit) \ + + encode_int(self.reward_table_sub_id) \ + + encode_int(self.player_trace_table_sub_id) \ + + encode_int(self.success_player_exp) \ + + encode_int(self.failed_player_exp) \ + + encode_int(self.greed_spawn_wait_count) \ + + encode_int(self.honey_spawn_wait_count) \ + + encode_int(self.menu_display_enemy_set_id) \ + + encode_str(self.stage_filepath) \ + + encode_str(self.rarity_up_chance_rate) \ + + encode_str(self.pair_mob_hp_rate) \ + + encode_str(self.pair_mob_atk_rate) \ + + encode_str(self.pair_leader_hp_rate) \ + + encode_str(self.pair_leader_atk_rate) \ + + encode_str(self.pair_boss_hp_rate) \ + + encode_str(self.pair_boss_atk_rate) \ + + encode_str(self.pair_exp_rate) \ + + encode_str(self.trio_mob_hp_rate) \ + + encode_str(self.trio_mob_atk_rate) \ + + encode_str(self.trio_leader_hp_rate) \ + + encode_str(self.trio_leader_atk_rate) \ + + encode_str(self.trio_boss_hp_rate) \ + + encode_str(self.trio_boss_atk_rate) \ + + encode_str(self.trio_exp_rate) \ + + encode_int(self.single_reward_vp) \ + + encode_int(self.pair_reward_vp) \ + + encode_int(self.trio_reward_vp) + +class QuestExistUnitData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_exist_unit_id = decode_int(data, off) + off += INT_OFF + + self.quest_scene_id = decode_int(data, off) + off += INT_OFF + + self.enemy_kind_id = decode_int(data, off) + off += INT_OFF + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestExistUnitData": + ret = cls(b"\x00" * 99, 0) + ret.quest_exist_unit_id = data['QuestExistUnitId'] + ret.quest_scene_id = data['QuestSceneId'] + ret.enemy_kind_id = data['EnemyKindId'] + ret.unit_id = data['UnitId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.quest_exist_unit_id) \ + + encode_int(self.quest_scene_id) \ + + encode_int(self.enemy_kind_id) \ + + encode_int(self.unit_id) + +class QuestEpisodeAppendRewardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_episode_append_reward_id = decode_int(data, off) + off += INT_OFF + + self.quest_scene_id = decode_int(data, off) + off += INT_OFF + + self.episode_append_id = decode_int(data, off) + off += INT_OFF + + self.episode_append_num = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestEpisodeAppendRewardData": + ret = cls(b"\x00" * 99, 0) + ret.quest_episode_append_reward_id = data['QuestEpisodeAppendRewardId'] + ret.quest_scene_id = data['QuestSceneId'] + ret.episode_append_id = data['EpisodeAppendId'] + ret.episode_append_num = data['EpisodeAppendNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.quest_episode_append_reward_id) \ + + encode_int(self.quest_scene_id) \ + + encode_int(self.episode_append_id) \ + + encode_int(self.episode_append_num) + +class SideQuestData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.side_quest_id = decode_int(data, off) + off += INT_OFF + + self.display_name, new_off = decode_str(data, off) + off += new_off + + self.episode_num = decode_int(data, off) + off += INT_OFF + + self.ex_bonus_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.quest_scene_id = decode_int(data, off) + off += INT_OFF + + self.recommend_lv = decode_int(data, off) + off += INT_OFF + + self.comment_summary, new_off = decode_str(data, off) + off += new_off + + self.comment_introduction, new_off = decode_str(data, off) + off += new_off + + self.start_adv_name, new_off = decode_str(data, off) + off += new_off + + self.end_adv_name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "SideQuestData": + ret = cls(b"\x00" * 99, 0) + ret.side_quest_id = data['SideQuestId'] + ret.display_name = data['DisplayName'] + ret.episode_num = data['EpisodeNum'] + ret.ex_bonus_table_sub_id = data['ExBonusTableSubId'] + ret.quest_scene_id = data['QuestSceneId'] + ret.recommend_lv = data['RecommendLv'] + ret.comment_summary = data['CommentSummary'] + ret.comment_introduction = data['CommentIntroduction'] + ret.start_adv_name = data['StartAdvName'] + ret.end_adv_name = data['EndAdvName'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.side_quest_id) \ + + encode_str(self.display_name) \ + + encode_int(self.episode_num) \ + + encode_int(self.ex_bonus_table_sub_id) \ + + encode_int(self.quest_scene_id) \ + + encode_int(self.recommend_lv) \ + + encode_str(self.comment_summary) \ + + encode_str(self.comment_introduction) \ + + encode_str(self.start_adv_name) \ + + encode_str(self.end_adv_name) + +class EpisodeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.episode_id = decode_int(data, off) + off += INT_OFF + + self.episode_chapter_id = decode_int(data, off) + off += INT_OFF + + self.release_episode_id = decode_int(data, off) + off += INT_OFF + + self.episode_num = decode_int(data, off) + off += INT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.comment_summary, new_off = decode_str(data, off) + off += new_off + + self.comment_introduction, new_off = decode_str(data, off) + off += new_off + + self.recommend_lv = decode_int(data, off) + off += INT_OFF + + self.ex_bonus_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.quest_scene_id = decode_int(data, off) + off += INT_OFF + + self.start_adv_name, new_off = decode_str(data, off) + off += new_off + + self.end_adv_name, new_off = decode_str(data, off) + off += new_off + + self.unlock_still_id = decode_int(data, off) + off += INT_OFF + + self.required_release_episode_append_id = decode_int(data, off) + off += INT_OFF + + self.required_release_episode_append_num = decode_short(data, off) + off += SHORT_OFF + + self.release_reward_vp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EpisodeData": + ret = cls(b"\x00" * 99, 0) + ret.episode_id = data['EpisodeId'] + ret.episode_chapter_id = data['EpisodeChapterId'] + ret.release_episode_id = data['ReleaseEpisodeId'] + ret.episode_num = data['EpisodeNum'] + ret.title = data['Title'] + ret.comment_summary = data['CommentSummary'] + ret.comment_introduction = data['CommentIntroduction'] + ret.recommend_lv = data['RecommendLv'] + ret.ex_bonus_table_sub_id = data['ExBonusTableSubId'] + ret.quest_scene_id = data['QuestSceneId'] + ret.start_adv_name = data['StartAdvName'] + ret.end_adv_name = data['EndAdvName'] + ret.unlock_still_id = data['UnlockStillId'] + ret.required_release_episode_append_id = data['RequiredReleaseEpisodeAppendId'] + ret.required_release_episode_append_num = data['RequiredReleaseEpisodeAppendNum'] + ret.release_reward_vp = data['ReleaseRewardVp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.episode_id) \ + + encode_int(self.episode_chapter_id) \ + + encode_int(self.release_episode_id) \ + + encode_int(self.episode_num) \ + + encode_str(self.title) \ + + encode_str(self.comment_summary) \ + + encode_str(self.comment_introduction) \ + + encode_int(self.recommend_lv) \ + + encode_int(self.ex_bonus_table_sub_id) \ + + encode_int(self.quest_scene_id) \ + + encode_str(self.start_adv_name) \ + + encode_str(self.end_adv_name) \ + + encode_int(self.unlock_still_id) \ + + encode_int(self.required_release_episode_append_id) \ + + encode_short(self.required_release_episode_append_num) \ + + encode_int(self.release_reward_vp) + +class EpisodeChapterData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.episode_chapter_id = decode_int(data, off) + off += INT_OFF + + self.episode_part_id = decode_int(data, off) + off += INT_OFF + + self.display_name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EpisodeChapterData": + ret = cls(b"\x00" * 99, 0) + ret.episode_chapter_id = data['EpisodeChapterId'] + ret.episode_part_id = data['EpisodePartId'] + ret.display_name = data['DisplayName'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.episode_chapter_id) \ + + encode_int(self.episode_part_id) \ + + encode_str(self.display_name) + +class EpisodePartData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.episode_part_id = decode_int(data, off) + off += INT_OFF + + self.display_name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EpisodePartData": + ret = cls(b"\x00" * 99, 0) + ret.episode_part_id = data['EpisodePartId'] + ret.display_name = data['DisplayName'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.episode_part_id) \ + + encode_str(self.display_name) + +class TrialTowerData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.trial_tower_id = decode_short(data, off) + off += SHORT_OFF + + self.release_trial_tower_id = decode_int(data, off) + off += INT_OFF + + self.ex_bonus_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.quest_scene_id = decode_int(data, off) + off += INT_OFF + + self.recommend_lv = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "TrialTowerData": + ret = cls(b"\x00" * 99, 0) + ret.trial_tower_id = data['TrialTowerId'] + ret.release_trial_tower_id = data['ReleaseTrialTowerId'] + ret.ex_bonus_table_sub_id = data['ExBonusTableSubId'] + ret.quest_scene_id = data['QuestSceneId'] + ret.recommend_lv = data['RecommendLv'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.trial_tower_id) \ + + encode_int(self.release_trial_tower_id) \ + + encode_int(self.ex_bonus_table_sub_id) \ + + encode_int(self.quest_scene_id) \ + + encode_int(self.recommend_lv) + +class ExTowerData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.ex_tower_id = decode_int(data, off) + off += INT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.release_trial_tower_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ExTowerData": + ret = cls(b"\x00" * 99, 0) + ret.ex_tower_id = data['ExTowerId'] + ret.title = data['Title'] + ret.release_trial_tower_id = data['ReleaseTrialTowerId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.ex_tower_id) \ + + encode_str(self.title) \ + + encode_int(self.release_trial_tower_id) + +class ExTowerQuestData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.ex_tower_quest_id = decode_int(data, off) + off += INT_OFF + + self.ex_tower_id = decode_int(data, off) + off += INT_OFF + + self.release_ex_tower_quest_id = decode_int(data, off) + off += INT_OFF + + self.level_num = decode_short(data, off) + off += SHORT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.ex_bonus_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.quest_scene_id = decode_int(data, off) + off += INT_OFF + + self.recommend_lv = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ExTowerQuestData": + ret = cls(b"\x00" * 99, 0) + ret.ex_tower_quest_id = data['ExTowerQuestId'] + ret.ex_tower_id = data['ExTowerId'] + ret.release_ex_tower_quest_id = data['ReleaseExTowerQuestId'] + ret.level_num = data['LevelNum'] + ret.title = data['Title'] + ret.ex_bonus_table_sub_id = data['ExBonusTableSubId'] + ret.quest_scene_id = data['QuestSceneId'] + ret.recommend_lv = data['RecommendLv'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.ex_tower_quest_id) \ + + encode_int(self.ex_tower_id) \ + + encode_int(self.release_ex_tower_quest_id) \ + + encode_short(self.level_num) \ + + encode_str(self.title) \ + + encode_int(self.ex_bonus_table_sub_id) \ + + encode_int(self.quest_scene_id) \ + + encode_int(self.recommend_lv) + +class MenuDisplayEnemyData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.menu_display_enemy_id = decode_short(data, off) + off += SHORT_OFF + + self.menu_display_enemy_set_id = decode_int(data, off) + off += INT_OFF + + self.boss_flag = decode_byte(data, off) + off += BYTE_OFF + + self.enemy_kind_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "MenuDisplayEnemyData": + ret = cls(b"\x00" * 99, 0) + ret.menu_display_enemy_id = data['MenuDisplayEnemyId'] + ret.menu_display_enemy_set_id = data['MenuDisplayEnemySetId'] + ret.boss_flag = data['BossFlag'] + ret.enemy_kind_id = data['EnemyKindId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.menu_display_enemy_id) \ + + encode_int(self.menu_display_enemy_set_id) \ + + encode_byte(self.boss_flag) \ + + encode_int(self.enemy_kind_id) + +class MissionData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.mission_id = decode_short(data, off) + off += SHORT_OFF + + self.mission_difficulty_id = decode_int(data, off) + off += INT_OFF + + self.mission_name, new_off = decode_str(data, off) + off += new_off + + self.time_limit = decode_int(data, off) + off += INT_OFF + + self.condition = decode_short(data, off) + off += SHORT_OFF + + self.enemy_set_id = decode_int(data, off) + off += INT_OFF + + self.value1 = decode_int(data, off) + off += INT_OFF + + self.value2 = decode_int(data, off) + off += INT_OFF + + self.enemy_hide = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "MissionData": + ret = cls(b"\x00" * 99, 0) + ret.mission_id = data['MissionId'] + ret.mission_difficulty_id = data['MissionDifficultyId'] + ret.mission_name = data['MissionName'] + ret.time_limit = data['TimeLimit'] + ret.condition = data['Condition'] + ret.enemy_set_id = data['EnemySetId'] + ret.value1 = data['Value1'] + ret.value2 = data['Value2'] + ret.enemy_hide = data['EnemyHide'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.mission_id) \ + + encode_int(self.mission_difficulty_id) \ + + encode_str(self.mission_name) \ + + encode_int(self.time_limit) \ + + encode_short(self.condition) \ + + encode_int(self.enemy_set_id) \ + + encode_int(self.value1) \ + + encode_int(self.value2) \ + + encode_byte(self.enemy_hide) + +class MissionTableData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.mission_table_id = decode_int(data, off) + off += INT_OFF + + self.mission_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.mission_id = decode_int(data, off) + off += INT_OFF + + self.rate = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "MissionTableData": + ret = cls(b"\x00" * 99, 0) + ret.mission_table_id = data['MissionTableId'] + ret.mission_table_sub_id = data['MissionTableSubId'] + ret.mission_id = data['MissionId'] + ret.rate = data['Rate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.mission_table_id) \ + + encode_int(self.mission_table_sub_id) \ + + encode_int(self.mission_id) \ + + encode_int(self.rate) + +class MissionDifficultyData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.mission_difficulty_id = decode_short(data, off) + off += SHORT_OFF + + self.skill_exp = decode_int(data, off) + off += INT_OFF + + self.unanalyzed_log_exp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "MissionDifficultyData": + ret = cls(b"\x00" * 99, 0) + ret.mission_difficulty_id = data['MissionDifficultyId'] + ret.skill_exp = data['SkillExp'] + ret.unanalyzed_log_exp = data['UnanalyzedLogExp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.mission_difficulty_id) \ + + encode_int(self.skill_exp) \ + + encode_int(self.unanalyzed_log_exp) + +class BattleCameraData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.battle_camera_id = decode_short(data, off) + off += SHORT_OFF + + self.offset_x, new_off = decode_str(data, off) + off += new_off + + self.offset_y, new_off = decode_str(data, off) + off += new_off + + self.offset_z, new_off = decode_str(data, off) + off += new_off + + self.rot_h, new_off = decode_str(data, off) + off += new_off + + self.rot_v, new_off = decode_str(data, off) + off += new_off + + self.distance, new_off = decode_str(data, off) + off += new_off + + self.near, new_off = decode_str(data, off) + off += new_off + + self.far, new_off = decode_str(data, off) + off += new_off + + self.fov, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BattleCameraData": + ret = cls(b"\x00" * 99, 0) + ret.battle_camera_id = data['BattleCameraId'] + ret.offset_x = data['OffsetX'] + ret.offset_y = data['OffsetY'] + ret.offset_z = data['OffsetZ'] + ret.rot_h = data['RotH'] + ret.rot_v = data['RotV'] + ret.distance = data['Distance'] + ret.near = data['Near'] + ret.far = data['Far'] + ret.fov = data['Fov'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.battle_camera_id) \ + + encode_str(self.offset_x) \ + + encode_str(self.offset_y) \ + + encode_str(self.offset_z) \ + + encode_str(self.rot_h) \ + + encode_str(self.rot_v) \ + + encode_str(self.distance) \ + + encode_str(self.near) \ + + encode_str(self.far) \ + + encode_str(self.fov) + +class ChatMainStoryData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.chat_main_story_id = decode_int(data, off) + off += INT_OFF + + self.release_condition_type = decode_byte(data, off) + off += BYTE_OFF + + self.release_condition_value = decode_int(data, off) + off += INT_OFF + + self.display_name, new_off = decode_str(data, off) + off += new_off + + self.first_reward_vp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ChatMainStoryData": + ret = cls(b"\x00" * 99, 0) + ret.chat_main_story_id = data['ChatMainStoryId'] + ret.release_condition_type = data['ReleaseConditionType'] + ret.release_condition_value = data['ReleaseConditionValue'] + ret.display_name = data['DisplayName'] + ret.first_reward_vp = data['FirstRewardVp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.chat_main_story_id) \ + + encode_byte(self.release_condition_type) \ + + encode_int(self.release_condition_value) \ + + encode_str(self.display_name) \ + + encode_int(self.first_reward_vp) + +class ChatSideStoryData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.chat_side_story_id = decode_int(data, off) + off += INT_OFF + + self.unlock_side_quest_id = decode_int(data, off) + off += INT_OFF + + self.release_condition_chara_id = decode_short(data, off) + off += SHORT_OFF + + self.release_condition_type = decode_byte(data, off) + off += BYTE_OFF + + self.release_condition_value1 = decode_int(data, off) + off += INT_OFF + + self.release_condition_value2 = decode_int(data, off) + off += INT_OFF + + self.display_name, new_off = decode_str(data, off) + off += new_off + + self.first_reward_vp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ChatSideStoryData": + ret = cls(b"\x00" * 99, 0) + ret.chat_side_story_id = data['ChatSideStoryId'] + ret.unlock_side_quest_id = data['UnlockSideQuestId'] + ret.release_condition_chara_id = data['ReleaseConditionCharaId'] + ret.release_condition_type = data['ReleaseConditionType'] + ret.release_condition_value1 = data['ReleaseConditionValue1'] + ret.release_condition_value2 = data['ReleaseConditionValue2'] + ret.display_name = data['DisplayName'] + ret.first_reward_vp = data['FirstRewardVp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.chat_side_story_id) \ + + encode_int(self.unlock_side_quest_id) \ + + encode_short(self.release_condition_chara_id) \ + + encode_byte(self.release_condition_type) \ + + encode_int(self.release_condition_value1) \ + + encode_int(self.release_condition_value2) \ + + encode_str(self.display_name) \ + + encode_int(self.first_reward_vp) + +class ChatEventStoryData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.chat_event_story_id = decode_int(data, off) + off += INT_OFF + + self.event_id = decode_int(data, off) + off += INT_OFF + + self.release_condition_type = decode_byte(data, off) + off += BYTE_OFF + + self.release_condition_value = decode_int(data, off) + off += INT_OFF + + self.display_name, new_off = decode_str(data, off) + off += new_off + + self.first_reward_vp = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ChatEventStoryData": + ret = cls(b"\x00" * 99, 0) + ret.chat_event_story_id = data['ChatEventStoryId'] + ret.event_id = data['EventId'] + ret.release_condition_type = data['ReleaseConditionType'] + ret.release_condition_value = data['ReleaseConditionValue'] + ret.display_name = data['DisplayName'] + ret.first_reward_vp = data['FirstRewardVp'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.chat_event_story_id) \ + + encode_int(self.event_id) \ + + encode_byte(self.release_condition_type) \ + + encode_int(self.release_condition_value) \ + + encode_str(self.display_name) \ + + encode_int(self.first_reward_vp) + +class NavigatorCharaData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.navigator_chara_id = decode_int(data, off) + off += INT_OFF + + self.condition_start_episode_id = decode_int(data, off) + off += INT_OFF + + self.condition_end_episode_id = decode_int(data, off) + off += INT_OFF + + self.disp_chara = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "NavigatorCharaData": + ret = cls(b"\x00" * 99, 0) + ret.navigator_chara_id = data['NavigatorCharaId'] + ret.condition_start_episode_id = data['ConditionStartEpisodeId'] + ret.condition_end_episode_id = data['ConditionEndEpisodeId'] + ret.disp_chara = data['DispChara'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.navigator_chara_id) \ + + encode_int(self.condition_start_episode_id) \ + + encode_int(self.condition_end_episode_id) \ + + encode_int(self.disp_chara) + +class NavigatorCommentData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.navigator_comment_id = decode_int(data, off) + off += INT_OFF + + self.menu_id = decode_int(data, off) + off += INT_OFF + + self.draw_type = decode_int(data, off) + off += INT_OFF + + self.condition_past_menu = decode_int(data, off) + off += INT_OFF + + self.priority = decode_int(data, off) + off += INT_OFF + + self.condition_start_episode_id = decode_int(data, off) + off += INT_OFF + + self.condition_end_episode_id = decode_int(data, off) + off += INT_OFF + + self.only_once = decode_byte(data, off) + off += BYTE_OFF + + self.only_rico = decode_byte(data, off) + off += BYTE_OFF + + self.comment_ai, new_off = decode_str(data, off) + off += new_off + + self.comment_rico, new_off = decode_str(data, off) + off += new_off + + self.expression = decode_int(data, off) + off += INT_OFF + + self.voice_id, new_off = decode_str(data, off) + off += new_off + + self.show_start_time, new_off = decode_str(data, off) + off += new_off + + self.show_end_time, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "NavigatorCommentData": + ret = cls(b"\x00" * 99, 0) + ret.navigator_comment_id = data['NavigatorCommentId'] + ret.menu_id = data['MenuId'] + ret.draw_type = data['DrawType'] + ret.condition_past_menu = data['ConditionPastMenu'] + ret.priority = data['Priority'] + ret.condition_start_episode_id = data['ConditionStartEpisodeId'] + ret.condition_end_episode_id = data['ConditionEndEpisodeId'] + ret.only_once = data['OnlyOnce'] + ret.only_rico = data['OnlyRico'] + ret.comment_ai = data['CommentAi'] + ret.comment_rico = data['CommentRico'] + ret.expression = data['Expression'] + ret.voice_id = data['VoiceId'] + ret.show_start_time = data['ShowStartTime'] + ret.show_end_time = data['ShowEndTime'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.navigator_comment_id) \ + + encode_int(self.menu_id) \ + + encode_int(self.draw_type) \ + + encode_int(self.condition_past_menu) \ + + encode_int(self.priority) \ + + encode_int(self.condition_start_episode_id) \ + + encode_int(self.condition_end_episode_id) \ + + encode_byte(self.only_once) \ + + encode_byte(self.only_rico) \ + + encode_str(self.comment_ai) \ + + encode_str(self.comment_rico) \ + + encode_int(self.expression) \ + + encode_str(self.voice_id) \ + + encode_str(self.show_start_time) \ + + encode_str(self.show_end_time) + +class ExBonusTableData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.ex_bonus_table_id = decode_int(data, off) + off += INT_OFF + + self.ex_bonus_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.ex_bonus_condition_id = decode_int(data, off) + off += INT_OFF + + self.condition_value1 = decode_int(data, off) + off += INT_OFF + + self.condition_value2 = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ExBonusTableData": + ret = cls(b"\x00" * 99, 0) + ret.ex_bonus_table_id = data['ExBonusTableId'] + ret.ex_bonus_table_sub_id = data['ExBonusTableSubId'] + ret.ex_bonus_condition_id = data['ExBonusConditionId'] + ret.condition_value1 = data['ConditionValue1'] + ret.condition_value2 = data['ConditionValue2'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.ex_bonus_table_id) \ + + encode_int(self.ex_bonus_table_sub_id) \ + + encode_int(self.ex_bonus_condition_id) \ + + encode_int(self.condition_value1) \ + + encode_int(self.condition_value2) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) + +class ExBonusConditionData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.ex_bonus_condition_id = decode_int(data, off) + off += INT_OFF + + self.format, new_off = decode_str(data, off) + off += new_off + + self.hud_format, new_off = decode_str(data, off) + off += new_off + + self.format_param_size = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ExBonusConditionData": + ret = cls(b"\x00" * 99, 0) + ret.ex_bonus_condition_id = data['ExBonusConditionId'] + ret.format = data['Format'] + ret.hud_format = data['HudFormat'] + ret.format_param_size = data['FomatParamSize'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.ex_bonus_condition_id) \ + + encode_str(self.format) \ + + encode_str(self.hud_format) \ + + encode_int(self.format_param_size) + +class BeginnerMissionProgressesUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.beginner_mission_condition_id = decode_int(data, off) + off += INT_OFF + + self.achievement_num = decode_short(data, off) + off += SHORT_OFF + + self.complete_flag = decode_byte(data, off) + off += BYTE_OFF + + self.complete_date, new_off = decode_date_str(data, off) + off += new_off + + self.reward_received_flag = decode_byte(data, off) + off += BYTE_OFF + + self.reward_received_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BeginnerMissionProgressesUserData": + ret = cls(b"\x00" * 99, 0) + ret.beginner_mission_condition_id = data['BeginnerMissionConditionId'] + ret.achievement_num = data['AchievementNum'] + ret.complete_flag = data['CompleteFlag'] + ret.complete_date = data['CompleteDate'] + ret.reward_received_flag = data['RewardReceivedFlag'] + ret.reward_received_date = data['RewardReceivedDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.beginner_mission_condition_id) \ + + encode_short(self.achievement_num) \ + + encode_byte(self.complete_flag) \ + + encode_date_str(self.complete_date) \ + + encode_byte(self.reward_received_flag) \ + + encode_date_str(self.reward_received_date) + +class BeginnerMissionSeatProgressesUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.beginner_mission_seat_condition_id = decode_int(data, off) + off += INT_OFF + + self.achievement_num = decode_short(data, off) + off += SHORT_OFF + + self.complete_flag = decode_byte(data, off) + off += BYTE_OFF + + self.complete_date, new_off = decode_date_str(data, off) + off += new_off + + self.reward_received_flag = decode_byte(data, off) + off += BYTE_OFF + + self.reward_received_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BeginnerMissionSeatProgressesUserData": + ret = cls(b"\x00" * 99, 0) + ret.beginner_mission_seat_condition_id = data['BeginnerMissionSeatConditionId'] + ret.achievement_num = data['AchievementNum'] + ret.complete_flag = data['CompleteFlag'] + ret.complete_date = data['CompleteDate'] + ret.reward_received_flag = data['RewardReceivedFlag'] + ret.reward_received_date = data['RewardReceivedDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.beginner_mission_seat_condition_id) \ + + encode_short(self.achievement_num) \ + + encode_byte(self.complete_flag) \ + + encode_date_str(self.complete_date) \ + + encode_byte(self.reward_received_flag) \ + + encode_date_str(self.reward_received_date) + +class LinkedSiteRegCampaignUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.reward_received_flag = decode_byte(data, off) + off += BYTE_OFF + + self.reward_received_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "LinkedSiteRegCampaignUserData": + ret = cls(b"\x00" * 99, 0) + ret.reward_received_flag = data['RewardReceivedFlag'] + ret.reward_received_date = data['RewardReceivedDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.reward_received_flag) \ + + encode_date_str(self.reward_received_date) + +class HeroLogUnitUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.hero_log_id = decode_int(data, off) + off += INT_OFF + + self.leader_appointment_normal_card_num = decode_int(data, off) + off += INT_OFF + + self.leader_appointment_holographic_card_num = decode_int(data, off) + off += INT_OFF + + self.skill_slot_max_release_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "HeroLogUnitUserData": + ret = cls(b"\x00" * 13, 0) + ret.hero_log_id = data['HeroLogId'] + ret.leader_appointment_normal_card_num = data['LeaderAppointmentNormalCardNum'] + ret.leader_appointment_holographic_card_num = data['LeaderAppointmentHolographicCardNum'] + ret.skill_slot_max_release_flag = data['SkillSlotMaxReleaseFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.hero_log_id) \ + + encode_int(self.leader_appointment_normal_card_num) \ + + encode_int(self.leader_appointment_holographic_card_num) \ + + encode_byte(self.skill_slot_max_release_flag) + +class CharaUnitUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.chara_id = decode_short(data, off) + off += SHORT_OFF + + self.reliability_1 = decode_int(data, off) + off += INT_OFF + + self.reliability_2 = decode_int(data, off) + off += INT_OFF + + self.motivation_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "CharaUnitUserData": + ret = cls(b"\x00" * 99, 0) + ret.chara_id = data['CharaId'] + ret.reliability_1 = data['Reliability1'] + ret.reliability_2 = data['Reliability2'] + ret.motivation_flag = data['MotivationFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.chara_id) \ + + encode_int(self.reliability_1) \ + + encode_int(self.reliability_2) \ + + encode_byte(self.motivation_flag) + +class AdventureExecUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.status = decode_byte(data, off) + off += BYTE_OFF + + self.adventure_id = decode_int(data, off) + off += INT_OFF + + self.adventure_difficulty_id = decode_int(data, off) + off += INT_OFF + + self.last_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.remaining_sec_to_complete = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "AdventureExecUserData": + ret = cls(b"\x00" * 99, 0) + ret.status = data['Status'] + ret.adventure_id = data['AdventureId'] + ret.adventure_difficulty_id = data['AdventureDifficultyId'] + ret.last_start_date = data['LastStartDate'] + ret.remaining_sec_to_complete = data['RemainingSecToComplete'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.status) \ + + encode_int(self.adventure_id) \ + + encode_int(self.adventure_difficulty_id) \ + + encode_date_str(self.last_start_date) \ + + encode_int(self.remaining_sec_to_complete) + +class QuestRareDropData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_rare_drop_id = decode_int(data, off) + off += INT_OFF + + self.quest_scene_id = decode_int(data, off) + off += INT_OFF + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_int(data, off) + off += INT_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_int(data, off) + off += INT_OFF + + self.strength_min = decode_int(data, off) + off += INT_OFF + + self.strength_max = decode_int(data, off) + off += INT_OFF + + self.property_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.drop_rate, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestRareDropData": + ret = cls(b"\x00" * 99, 0) + ret.quest_rare_drop_id = data['QuestRareDropId'] + ret.quest_scene_id = data['QuestSceneId'] + ret.unit_id = data['UnitId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength_min = data['StrengthMin'] + ret.strength_max = data['StrengthMax'] + ret.property_table_sub_id = data['PropertyTableSubId'] + ret.drop_rate = data['DropRate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.quest_rare_drop_id) \ + + encode_int(self.quest_scene_id) \ + + encode_int(self.unit_id) \ + + encode_int(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_int(self.common_reward_num) \ + + encode_int(self.strength_min) \ + + encode_int(self.strength_max) \ + + encode_int(self.property_table_sub_id) \ + + encode_str(self.drop_rate) + +class QuestSpecialRareDropSettingData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_special_rare_drop_setting_id = decode_int(data, off) + off += INT_OFF + + self.tower_type = decode_byte(data, off) + off += BYTE_OFF + + self.start_trial_tower_id = decode_short(data, off) + off += SHORT_OFF + + self.end_trial_tower_id = decode_short(data, off) + off += SHORT_OFF + + self.rare_drop_upward_rate, new_off = decode_str(data, off) + off += new_off + + self.quest_special_rare_drop_sub_id = decode_int(data, off) + off += INT_OFF + + self.generic_campaign_period_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestSpecialRareDropSettingData": + ret = cls(b"\x00" * 99, 0) + ret.quest_special_rare_drop_setting_id = data['QuestSpecialRareDropSettingId'] + ret.tower_type = data['TowerType'] + ret.start_trial_tower_id = data['StartTrialTowerId'] + ret.end_trial_tower_id = data['EndTrialTowerId'] + ret.rare_drop_upward_rate = data['RareDropUpwardRate'] + ret.quest_special_rare_drop_sub_id = data['QuestSpecialRareDropSubId'] + ret.generic_campaign_period_id = data['GenericCampaignPeriodId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.quest_special_rare_drop_setting_id) \ + + encode_byte(self.tower_type) \ + + encode_short(self.start_trial_tower_id) \ + + encode_short(self.end_trial_tower_id) \ + + encode_str(self.rare_drop_upward_rate) \ + + encode_int(self.quest_special_rare_drop_sub_id) \ + + encode_int(self.generic_campaign_period_id) + +class QuestSpecialRareDropData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_special_rare_drop_id = decode_int(data, off) + off += INT_OFF + + self.quest_special_rare_drop_sub_id = decode_int(data, off) + off += INT_OFF + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_int(data, off) + off += INT_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_int(data, off) + off += INT_OFF + + self.strength_min = decode_int(data, off) + off += INT_OFF + + self.strength_max = decode_int(data, off) + off += INT_OFF + + self.property_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.drop_rate, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestSpecialRareDropData": + ret = cls(b"\x00" * 99, 0) + ret.quest_special_rare_drop_id = data['QuestSpecialRareDropId'] + ret.quest_special_rare_drop_sub_id = data['QuestSpecialRareDropSubId'] + ret.unit_id = data['UnitId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength_min = data['StrengthMin'] + ret.strength_max = data['StrengthMax'] + ret.property_table_sub_id = data['PropertyTableSubId'] + ret.drop_rate = data['DropRate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.quest_special_rare_drop_id) \ + + encode_int(self.quest_special_rare_drop_sub_id) \ + + encode_int(self.unit_id) \ + + encode_int(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_int(self.common_reward_num) \ + + encode_int(self.strength_min) \ + + encode_int(self.strength_max) \ + + encode_int(self.property_table_sub_id) \ + + encode_str(self.drop_rate) + +class QuestTutorialData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_tutorial_id = decode_short(data, off) + off += SHORT_OFF + + self.trigger = decode_int(data, off) + off += INT_OFF + + self.trigger_delay, new_off = decode_str(data, off) + off += new_off + + self.trigger_during, new_off = decode_str(data, off) + off += new_off + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.unit_range, new_off = decode_str(data, off) + off += new_off + + self.comment_text, new_off = decode_str(data, off) + off += new_off + + self.voice_id, new_off = decode_str(data, off) + off += new_off + + self.comment_pos, new_off = decode_str(data, off) + off += new_off + + self.yui_face, new_off = decode_str(data, off) + off += new_off + + self.arrow_direct, new_off = decode_str(data, off) + off += new_off + + self.arrow_position, new_off = decode_str(data, off) + off += new_off + + self.image_plus, new_off = decode_str(data, off) + off += new_off + + self.image_plus_pos, new_off = decode_str(data, off) + off += new_off + + self.stick_info, new_off = decode_str(data, off) + off += new_off + + self.mark_effect, new_off = decode_str(data, off) + off += new_off + + self.mark_pos, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestTutorialData": + ret = cls(b"\x00" * 99, 0) + ret.quest_tutorial_id = data['Id'] + ret.trigger = data['Trigger'] + ret.trigger_delay = data['TriggerDelay'] + ret.trigger_during = data['TriggerDuring'] + ret.unit_id = data['UnitId'] + ret.unit_range = data['UnitRange'] + ret.comment_text = data['CommentText'] + ret.voice_id = data['VoiceID'] + ret.comment_pos = data['CommentPos'] + ret.yui_face = data['YuiFace'] + ret.arrow_direct = data['ArrowDirect'] + ret.arrow_position = data['ArrowPosition'] + ret.image_plus = data['ImagePlus'] + ret.image_plus_pos = data['ImagePlusPos'] + ret.stick_info = data['StickInfo'] + ret.mark_effect = data['MarkEffect'] + ret.mark_pos = data['MarkPos'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.quest_tutorial_id) \ + + encode_int(self.trigger) \ + + encode_str(self.trigger_delay) \ + + encode_str(self.trigger_during) \ + + encode_int(self.unit_id) \ + + encode_str(self.unit_range) \ + + encode_str(self.comment_text) \ + + encode_str(self.voice_id) \ + + encode_str(self.comment_pos) \ + + encode_str(self.yui_face) \ + + encode_str(self.arrow_direct) \ + + encode_str(self.arrow_position) \ + + encode_str(self.image_plus) \ + + encode_str(self.image_plus_pos) \ + + encode_str(self.stick_info) \ + + encode_str(self.mark_effect) \ + + encode_str(self.mark_pos) + +class QuestPlayerTraceTableData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.player_trace_table_id = decode_short(data, off) + off += SHORT_OFF + + self.player_trace_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.rate = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestPlayerTraceTableData": + ret = cls(b"\x00" * 99, 0) + ret.player_trace_table_id = data['PlayerTraceTableId'] + ret.player_trace_table_sub_id = data['PlayerTraceTableSubId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.rate = data['Rate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.player_trace_table_id) \ + + encode_int(self.player_trace_table_sub_id) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.rate) + +class QuestStillData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.still_id = decode_int(data, off) + off += INT_OFF + + self.file_name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestStillData": + ret = cls(b"\x00" * 99, 0) + ret.still_id = data['StillId'] + ret.file_name = data['FileName'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.still_id) \ + + encode_str(self.file_name) + +class GashaData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gasha_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.description, new_off = decode_str(data, off) + off += new_off + + self.gasha_type = decode_byte(data, off) + off += BYTE_OFF + + self.open_type = decode_byte(data, off) + off += BYTE_OFF + + self.free_target_flag = decode_byte(data, off) + off += BYTE_OFF + + self.reset_hour_list, new_off = decode_str(data, off) + off += new_off + + self.limit_num = decode_short(data, off) + off += SHORT_OFF + + self.open_days = decode_short(data, off) + off += SHORT_OFF + + self.sort_num = decode_int(data, off) + off += INT_OFF + + self.start_date, new_off = decode_date_str(data, off) + off += new_off + + self.end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaData": + ret = cls(b"\x00" * 99, 0) + ret.gasha_id = data['GashaId'] + ret.name = data['Name'] + ret.description = data['Description'] + ret.gasha_type = data['GashaType'] + ret.open_type = data['OpenType'] + ret.free_target_flag = data['FreeTargetFlag'] + ret.reset_hour_list = data['ResetHourList'] + ret.limit_num = data['LimitNum'] + ret.open_days = data['OpenDays'] + ret.sort_num = data['SortNum'] + ret.start_date = data['StartDate'] + ret.end_date = data['EndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.gasha_id) \ + + encode_str(self.name) \ + + encode_str(self.description) \ + + encode_byte(self.gasha_type) \ + + encode_byte(self.open_type) \ + + encode_byte(self.free_target_flag) \ + + encode_str(self.reset_hour_list) \ + + encode_short(self.limit_num) \ + + encode_short(self.open_days) \ + + encode_int(self.sort_num) \ + + encode_date_str(self.start_date) \ + + encode_date_str(self.end_date) + +class GashaHeaderData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gasha_header_id = decode_int(data, off) + off += INT_OFF + + self.gasha_id = decode_int(data, off) + off += INT_OFF + + self.step_no = decode_byte(data, off) + off += BYTE_OFF + + self.step_progress_flag = decode_byte(data, off) + off += BYTE_OFF + + self.platform = decode_byte(data, off) + off += BYTE_OFF + + self.use_type_1 = decode_byte(data, off) + off += BYTE_OFF + + self.use_type_2 = decode_byte(data, off) + off += BYTE_OFF + + self.provision_num = decode_byte(data, off) + off += BYTE_OFF + + self.premium_lottery_num = decode_byte(data, off) + off += BYTE_OFF + + self.premium_lottery_executable_num = decode_byte(data, off) + off += BYTE_OFF + + self.use_type_1_first_use_num = decode_int(data, off) + off += INT_OFF + + self.use_type_1_base_use_num = decode_int(data, off) + off += INT_OFF + + self.use_type_1_extra_use_num = decode_int(data, off) + off += INT_OFF + + self.use_type_2_first_use_num = decode_int(data, off) + off += INT_OFF + + self.use_type_2_base_use_num = decode_int(data, off) + off += INT_OFF + + self.use_type_2_extra_use_num = decode_int(data, off) + off += INT_OFF + + self.yui_chance_log_open_rate, new_off = decode_str(data, off) + off += new_off + + self.yui_chance_rarity_up_rate, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaHeaderData": + ret = cls(b"\x00" * 99, 0) + ret.gasha_header_id = data['GashaHeaderId'] + ret.gasha_id = data['GashaId'] + ret.step_no = data['StepNo'] + ret.step_progress_flag = data['StepProgressFlag'] + ret.platform = data['Platform'] + ret.use_type_1 = data['UseType1'] + ret.use_type_2 = data['UseType2'] + ret.provision_num = data['ProvisionNum'] + ret.premium_lottery_num = data['PremiumLotteryNum'] + ret.premium_lottery_executable_num = data['PremiumLotteryExecutableNum'] + ret.use_type_1_first_use_num = data['UseType1FirstUseNum'] + ret.use_type_1_base_use_num = data['UseType1BaseUseNum'] + ret.use_type_1_extra_use_num = data['UseType1ExtraUseNum'] + ret.use_type_2_first_use_num = data['UseType2FirstUseNum'] + ret.use_type_2_base_use_num = data['UseType2BaseUseNum'] + ret.use_type_2_extra_use_num = data['UseType2ExtraUseNum'] + ret.yui_chance_log_open_rate = data['YuiChanceLogOpenRate'] + ret.yui_chance_rarity_up_rate = data['YuiChanceRarityUpRate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.gasha_header_id) \ + + encode_int(self.gasha_id) \ + + encode_byte(self.step_no) \ + + encode_byte(self.step_progress_flag) \ + + encode_byte(self.platform) \ + + encode_byte(self.use_type_1) \ + + encode_byte(self.use_type_2) \ + + encode_byte(self.provision_num) \ + + encode_byte(self.premium_lottery_num) \ + + encode_byte(self.premium_lottery_executable_num) \ + + encode_int(self.use_type_1_first_use_num) \ + + encode_int(self.use_type_1_base_use_num) \ + + encode_int(self.use_type_1_extra_use_num) \ + + encode_int(self.use_type_2_first_use_num) \ + + encode_int(self.use_type_2_base_use_num) \ + + encode_int(self.use_type_2_extra_use_num) \ + + encode_str(self.yui_chance_log_open_rate) \ + + encode_str(self.yui_chance_rarity_up_rate) + +class GashaLotteryRarityData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gasha_lottery_rarity_id = decode_int(data, off) + off += INT_OFF + + self.gasha_id = decode_int(data, off) + off += INT_OFF + + self.gasha_header_id = decode_int(data, off) + off += INT_OFF + + self.lottery_rarity_type = decode_byte(data, off) + off += BYTE_OFF + + self.lottery_rarity_rate, new_off = decode_str(data, off) + off += new_off + + self.premium_rate, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaLotteryRarityData": + ret = cls(b"\x00" * 99, 0) + ret.gasha_lottery_rarity_id = data['GashaLotteryRarityId'] + ret.gasha_id = data['GashaId'] + ret.gasha_header_id = data['GashaHeaderId'] + ret.lottery_rarity_type = data['LotteryRarityType'] + ret.lottery_rarity_rate = data['LotteryRarityRate'] + ret.premium_rate = data['PremiumRate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.gasha_lottery_rarity_id) \ + + encode_int(self.gasha_id) \ + + encode_int(self.gasha_header_id) \ + + encode_byte(self.lottery_rarity_type) \ + + encode_str(self.lottery_rarity_rate) \ + + encode_str(self.premium_rate) + +class GashaPrizeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gasha_prize_id = decode_int(data, off) + off += INT_OFF + + self.gasha_id = decode_int(data, off) + off += INT_OFF + + self.lottery_rarity_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_type = decode_int(data, off) + off += INT_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_int(data, off) + off += INT_OFF + + self.unanalyzed_log_grade_id = decode_int(data, off) + off += INT_OFF + + self.correction_rate = decode_short(data, off) + off += SHORT_OFF + + self.pickup_flag = decode_byte(data, off) + off += BYTE_OFF + + self.property_table_sub_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaPrizeData": + ret = cls(b"\x00" * 99, 0) + ret.gasha_prize_id = data['GashaPrizeId'] + ret.gasha_id = data['GashaId'] + ret.lottery_rarity_type = data['LotteryRarityType'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.unanalyzed_log_grade_id = data['UnanalyzedLogGradeId'] + ret.correction_rate = data['CorrectionRate'] + ret.pickup_flag = data['PickupFlag'] + ret.property_table_sub_id = data['PropertyTableSubId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.gasha_prize_id) \ + + encode_int(self.gasha_id) \ + + encode_byte(self.lottery_rarity_type) \ + + encode_int(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_int(self.common_reward_num) \ + + encode_int(self.unanalyzed_log_grade_id) \ + + encode_short(self.correction_rate) \ + + encode_byte(self.pickup_flag) \ + + encode_int(self.property_table_sub_id) + +class ComebackEventData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.comeback_event_id = decode_int(data, off) + off += INT_OFF + + self.comeback_event_sub_id = decode_int(data, off) + off += INT_OFF + + self.display_name, new_off = decode_str(data, off) + off += new_off + + self.reward_set_sub_id = decode_int(data, off) + off += INT_OFF + + self.require_days = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ComebackEventData": + ret = cls(b"\x00" * 99, 0) + ret.comeback_event_id = data['ComebackEventId'] + ret.comeback_event_sub_id = data['ComebackEventSubId'] + ret.display_name = data['DisplayName'] + ret.reward_set_sub_id = data['RewardSetSubId'] + ret.require_days = data['RequireDays'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.comeback_event_id) \ + + encode_int(self.comeback_event_sub_id) \ + + encode_str(self.display_name) \ + + encode_int(self.reward_set_sub_id) \ + + encode_short(self.require_days) + +class AdBannerData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.ad_banner_id = decode_int(data, off) + off += INT_OFF + + self.category = decode_byte(data, off) + off += BYTE_OFF + + self.sort_num = decode_int(data, off) + off += INT_OFF + + self.start_date, new_off = decode_date_str(data, off) + off += new_off + + self.end_date, new_off = decode_date_str(data, off) + off += new_off + + self.active_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "AdBannerData": + ret = cls(b"\x00" * 99, 0) + ret.ad_banner_id = data['AdBannerId'] + ret.category = data['Category'] + ret.sort_num = data['SortNum'] + ret.start_date = data['StartDate'] + ret.end_date = data['EndDate'] + ret.active_flag = data['ActiveFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.ad_banner_id) \ + + encode_byte(self.category) \ + + encode_int(self.sort_num) \ + + encode_date_str(self.start_date) \ + + encode_date_str(self.end_date) \ + + encode_byte(self.active_flag) + +class EventsData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.event_id = decode_int(data, off) + off += INT_OFF + + self.event_type = decode_byte(data, off) + off += BYTE_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.param_1, new_off = decode_str(data, off) + off += new_off + + self.param_2, new_off = decode_str(data, off) + off += new_off + + self.param_3, new_off = decode_str(data, off) + off += new_off + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.posting_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.posting_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.chat_open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.chat_open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.news_id = decode_int(data, off) + off += INT_OFF + + self.help_id = decode_int(data, off) + off += INT_OFF + + self.ad_banner_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EventsData": + ret = cls(b"\x00" * 99, 0) + ret.event_id = data['EventId'] + ret.event_type = data['EventType'] + ret.title = data['Title'] + ret.param_1 = data['Param1'] + ret.param_2 = data['Param2'] + ret.param_3 = data['Param3'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + ret.posting_start_date = data['PostingStartDate'] + ret.posting_end_date = data['PostingEndDate'] + ret.chat_open_start_date = data['ChatOpenStartDate'] + ret.chat_open_end_date = data['ChatOpenEndDate'] + ret.news_id = data['NewId'] + ret.help_id = data['HelpId'] + ret.ad_banner_id = data['AdBannerId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.event_id) \ + + encode_byte(self.event_type) \ + + encode_str(self.title) \ + + encode_str(self.param_1) \ + + encode_str(self.param_2) \ + + encode_str(self.param_3) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) \ + + encode_date_str(self.posting_start_date) \ + + encode_date_str(self.posting_end_date) \ + + encode_date_str(self.chat_open_start_date) \ + + encode_date_str(self.chat_open_end_date) \ + + encode_int(self.news_id) \ + + encode_int(self.help_id) \ + + encode_int(self.ad_banner_id) + +class TreasureHuntsData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.treasure_hunt_id = decode_int(data, off) + off += INT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "TreasureHuntsData": + ret = cls(b"\x00" * 99, 0) + ret.treasure_hunt_id = data['TreasureHuntId'] + ret.title = data['Title'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.treasure_hunt_id) \ + + encode_str(self.title) + +class TreasureHuntWholeTasksData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.treasure_hunt_whole_task_id = decode_int(data, off) + off += INT_OFF + + self.treasure_hunt_id = decode_int(data, off) + off += INT_OFF + + self.task_type = decode_byte(data, off) + off += BYTE_OFF + + self.achievement_possible_num = decode_short(data, off) + off += SHORT_OFF + + self.get_event_point = decode_int(data, off) + off += INT_OFF + + self.condition_type = decode_byte(data, off) + off += BYTE_OFF + + self.condition_value_accumulation_flag = decode_byte(data, off) + off += BYTE_OFF + + self.condition_value_1, new_off = decode_str(data, off) + off += new_off + + self.condition_value_2, new_off = decode_str(data, off) + off += new_off + + self.condition_value_3, new_off = decode_str(data, off) + off += new_off + + self.condition_value_4, new_off = decode_str(data, off) + off += new_off + + self.condition_value_5, new_off = decode_str(data, off) + off += new_off + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "TreasureHuntWholeTasksData": + ret = cls(b"\x00" * 99, 0) + ret.treasure_hunt_whole_task_id = data['TreasureHuntWholeTaskId'] + ret.treasure_hunt_id = data['TreasureHuntId'] + ret.task_type = data['TaskType'] + ret.achievement_possible_num = data['AchievementPossibleNum'] + ret.get_event_point = data['GetEventPoint'] + ret.condition_type = data['ConditionType'] + ret.condition_value_accumulation_flag = data['ConditionValueAccumulationFlag'] + ret.condition_value_1 = data['ConditionValue1'] + ret.condition_value_2 = data['ConditionValue2'] + ret.condition_value_3 = data['ConditionValue3'] + ret.condition_value_4 = data['ConditionValue4'] + ret.condition_value_5 = data['ConditionValue5'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.treasure_hunt_whole_task_id) \ + + encode_int(self.treasure_hunt_id) \ + + encode_byte(self.task_type) \ + + encode_short(self.achievement_possible_num) \ + + encode_int(self.get_event_point) \ + + encode_byte(self.condition_type) \ + + encode_byte(self.condition_value_accumulation_flag) \ + + encode_str(self.condition_value_1) \ + + encode_str(self.condition_value_2) \ + + encode_str(self.condition_value_3) \ + + encode_str(self.condition_value_4) \ + + encode_str(self.condition_value_5) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) + +class TreasureHuntIndividualTasksData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.treasure_hunt_individual_task_id = decode_int(data, off) + off += INT_OFF + + self.treasure_hunt_id = decode_int(data, off) + off += INT_OFF + + self.task_type = decode_byte(data, off) + off += BYTE_OFF + + self.quest_scene_id = decode_short(data, off) + off += SHORT_OFF + + self.achievement_possible_num = decode_short(data, off) + off += SHORT_OFF + + self.get_event_point = decode_int(data, off) + off += INT_OFF + + self.condition_type = decode_byte(data, off) + off += BYTE_OFF + + self.condition_value_accumulation_flag = decode_byte(data, off) + off += BYTE_OFF + + self.condition_value_1, new_off = decode_str(data, off) + off += new_off + + self.condition_value_2, new_off = decode_str(data, off) + off += new_off + + self.condition_value_3, new_off = decode_str(data, off) + off += new_off + + self.condition_value_4, new_off = decode_str(data, off) + off += new_off + + self.condition_value_5, new_off = decode_str(data, off) + off += new_off + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "TreasureHuntIndividualTasksData": + ret = cls(b"\x00" * 99, 0) + ret.treasure_hunt_individual_task_id = data['TreasureHuntIndividualTaskId'] + ret.treasure_hunt_id = data['TreasureHuntId'] + ret.task_type = data['TaskType'] + ret.quest_scene_id = data['QuestSceneId'] + ret.achievement_possible_num = data['AchievementPossibleNum'] + ret.get_event_point = data['GetEventPoint'] + ret.condition_type = data['ConditionType'] + ret.condition_value_accumulation_flag = data['ConditionValueAccumulationFlag'] + ret.condition_value_1 = data['ConditionValue1'] + ret.condition_value_2 = data['ConditionValue2'] + ret.condition_value_3 = data['ConditionValue3'] + ret.condition_value_4 = data['ConditionValue4'] + ret.condition_value_5 = data['ConditionValue5'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.treasure_hunt_individual_task_id) \ + + encode_int(self.treasure_hunt_id) \ + + encode_byte(self.task_type) \ + + encode_short(self.quest_scene_id) \ + + encode_short(self.achievement_possible_num) \ + + encode_int(self.get_event_point) \ + + encode_byte(self.condition_type) \ + + encode_byte(self.condition_value_accumulation_flag) \ + + encode_str(self.condition_value_1) \ + + encode_str(self.condition_value_2) \ + + encode_str(self.condition_value_3) \ + + encode_str(self.condition_value_4) \ + + encode_str(self.condition_value_5) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) + +class TreasureHuntSpecialEffectsData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.treasure_hunt_special_effect_id = decode_int(data, off) + off += INT_OFF + + self.treasure_hunt_id = decode_int(data, off) + off += INT_OFF + + self.special_effect_type = decode_byte(data, off) + off += BYTE_OFF + + self.special_effect_coefficient, new_off = decode_str(data, off) + off += new_off + + self.target_common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.target_common_reward_id = decode_int(data, off) + off += INT_OFF + + self.obtaining_location_type = decode_byte(data, off) + off += BYTE_OFF + + self.obtaining_location_param, new_off = decode_str(data, off) + off += new_off + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "TreasureHuntSpecialEffectsData": + ret = cls(b"\x00" * 99, 0) + ret.treasure_hunt_special_effect_id = data['TreasureHuntSpecialEffectId'] + ret.treasure_hunt_id = data['TreasureHuntId'] + ret.special_effect_type = data['SpecialEffectType'] + ret.special_effect_coefficient = data['SpecialEffectCoefficient'] + ret.target_common_reward_type = data['TargetCommonRewardType'] + ret.target_common_reward_id = data['TargetCommonRewardId'] + ret.obtaining_location_type = data['ObtainingLocationType'] + ret.obtaining_location_param = data['ObtainingLocationParam'] + ret.open_start_date = data['OpenStartDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.treasure_hunt_special_effect_id) \ + + encode_int(self.treasure_hunt_id) \ + + encode_byte(self.special_effect_type) \ + + encode_str(self.special_effect_coefficient) \ + + encode_byte(self.target_common_reward_type) \ + + encode_int(self.target_common_reward_id) \ + + encode_byte(self.obtaining_location_type) \ + + encode_str(self.obtaining_location_param) \ + + encode_date_str(self.open_start_date) + +class TreasureHuntEventPointRewardCommonRewardsData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.treasure_hunt_event_point_reward_common_reward_id = decode_int(data, off) + off += INT_OFF + + self.treasure_hunt_id = decode_int(data, off) + off += INT_OFF + + self.need_event_point = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "TreasureHuntEventPointRewardCommonRewardsData": + ret = cls(b"\x00" * 99, 0) + ret.treasure_hunt_event_point_reward_common_reward_id = data['TreasureHuntEventPointRewardCommonRewardId'] + ret.treasure_hunt_id = data['TreasureHuntId'] + ret.need_event_point = data['NeedEventPoint'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.treasure_hunt_event_point_reward_common_reward_id) \ + + encode_int(self.treasure_hunt_id) \ + + encode_int(self.need_event_point) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) + +class TreasureHuntEventPointRewardTitlesData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.treasure_hunt_event_point_reward_title_id = decode_int(data, off) + off += INT_OFF + + self.treasure_hunt_id = decode_int(data, off) + off += INT_OFF + + self.need_event_point = decode_int(data, off) + off += INT_OFF + + self.title_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "TreasureHuntEventPointRewardTitlesData": + ret = cls(b"\x00" * 99, 0) + ret.treasure_hunt_event_point_reward_title_id = data['TreasureHuntEventPointRewardTitleId'] + ret.treasure_hunt_id = data['TreasureHuntId'] + ret.need_event_point = data['NeedEventPoint'] + ret.title_id = data['TitleId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.treasure_hunt_event_point_reward_title_id) \ + + encode_int(self.treasure_hunt_id) \ + + encode_int(self.need_event_point) \ + + encode_int(self.title_id) + +class TreasureHuntTaskTextData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.treasure_hunt_task_text_id = decode_int(data, off) + off += INT_OFF + + self.task_type = decode_byte(data, off) + off += BYTE_OFF + + self.condition_type = decode_byte(data, off) + off += BYTE_OFF + + self.format, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "TreasureHuntTaskTextData": + ret = cls(b"\x00" * 99, 0) + ret.treasure_hunt_task_text_id = data['TreasureHuntTaskTextId'] + ret.task_type = data['TaskType'] + ret.condition_type = data['ConditionType'] + ret.format = data['Format'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.treasure_hunt_task_text_id) \ + + encode_byte(self.task_type) \ + + encode_byte(self.condition_type) \ + + encode_str(self.format) + +class BnidSerialCodeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.bnid_item_id, new_off = decode_str(data, off) + off += new_off + + self.serial_code_type = decode_byte(data, off) + off += BYTE_OFF + + self.category = decode_byte(data, off) + off += BYTE_OFF + + self.description, new_off = decode_str(data, off) + off += new_off + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BnidSerialCodeData": + ret = cls(b"\x00" * 99, 0) + ret.bnid_item_id = data['BnidItemId'] + ret.serial_code_type = data['SerialCodeType'] + ret.category = data['Category'] + ret.description = data['Description'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.bnid_item_id) \ + + encode_byte(self.serial_code_type) \ + + encode_byte(self.category) \ + + encode_str(self.description) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) + +class BnidSerialCodeRewardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.bnid_item_id, new_off = decode_str(data, off) + off += new_off + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BnidSerialCodeRewardData": + ret = cls(b"\x00" * 99, 0) + ret.bnid_item_id = data['BnidItemId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.bnid_item_id) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) + +class SupportLogData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.support_log_id = decode_int(data, off) + off += INT_OFF + + self.chara_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.rarity = decode_byte(data, off) + off += BYTE_OFF + + self.support_log_type_id = decode_short(data, off) + off += SHORT_OFF + + self.sale_price = decode_int(data, off) + off += INT_OFF + + self.composition_exp = decode_int(data, off) + off += INT_OFF + + self.awakening_exp = decode_int(data, off) + off += INT_OFF + + self.use_rank = decode_short(data, off) + off += SHORT_OFF + + self.group_no = decode_short(data, off) + off += SHORT_OFF + + self.adaptable_appear_append = decode_short(data, off) + off += SHORT_OFF + + self.punisher_appear_append = decode_short(data, off) + off += SHORT_OFF + + self.state, new_off = decode_str(data, off) + off += new_off + + self.passive_state, new_off = decode_str(data, off) + off += new_off + + self.power_default_value = decode_int(data, off) + off += INT_OFF + + self.clt_default_value = decode_int(data, off) + off += INT_OFF + + self.awakening_1_power = decode_int(data, off) + off += INT_OFF + + self.awakening_1_clt = decode_int(data, off) + off += INT_OFF + + self.awakening_2_power = decode_int(data, off) + off += INT_OFF + + self.awakening_2_clt = decode_int(data, off) + off += INT_OFF + + self.awakening_3_power = decode_int(data, off) + off += INT_OFF + + self.awakening_3_clt = decode_int(data, off) + off += INT_OFF + + self.awakening_4_power = decode_int(data, off) + off += INT_OFF + + self.awakening_4_clt = decode_int(data, off) + off += INT_OFF + + self.awakening_5_power = decode_int(data, off) + off += INT_OFF + + self.awakening_5_clt = decode_int(data, off) + off += INT_OFF + + self.normal_leader = decode_int(data, off) + off += INT_OFF + + self.holo_leader = decode_int(data, off) + off += INT_OFF + + self.ui_display_power_title, new_off = decode_str(data, off) + off += new_off + + self.ui_display_power_content, new_off = decode_str(data, off) + off += new_off + + self.prefab, new_off = decode_str(data, off) + off += new_off + + self.cutin_mode, new_off = decode_str(data, off) + off += new_off + + self.skill_voice_id, new_off = decode_str(data, off) + off += new_off + + self.skill_name, new_off = decode_str(data, off) + off += new_off + + self.name_in_skill_cutin, new_off = decode_str(data, off) + off += new_off + + self.skill_text, new_off = decode_str(data, off) + off += new_off + + self.skill_text_in_skill_cutin, new_off = decode_str(data, off) + off += new_off + + self.chara_info, new_off = decode_str(data, off) + off += new_off + + self.cutin_image, new_off = decode_str(data, off) + off += new_off + + self.cutin_image_awake, new_off = decode_str(data, off) + off += new_off + + self.status_chara_icon, new_off = decode_str(data, off) + off += new_off + + self.status_chara_icon_awake, new_off = decode_str(data, off) + off += new_off + + self.collection_display_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.collection_empty_frame_display_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "SupportLogData": + ret = cls(b"\x00" * 99, 0) + ret.support_log_id = data['SupportLogId'] + ret.chara_id = data['CharaId'] + ret.name = data['Name'] + ret.rarity = data['Rarity'] + ret.support_log_type_id = data['SupportLogTypeId'] + ret.sale_price = data['SalePrice'] + ret.composition_exp = data['CompositionExp'] + ret.awakening_exp = data['AwakeningExp'] + ret.use_rank = data['UseRank'] + ret.group_no = data['GroupNo'] + ret.adaptable_appear_append = data['AdaptableAppearAppend'] + ret.punisher_appear_append = data['PunisherAppearAppend'] + ret.state = data['State'] + ret.passive_state = data['PassiveState'] + ret.power_default_value = data['PowerDefaultValue'] + ret.clt_default_value = data['CltDefaultValue'] + ret.awakening_1_power = data['Awakening1Power'] + ret.awakening_1_clt = data['Awakening1Clt'] + ret.awakening_2_power = data['Awakening2Power'] + ret.awakening_2_clt = data['Awakening2Clt'] + ret.awakening_3_power = data['Awakening3Power'] + ret.awakening_3_clt = data['Awakening3Clt'] + ret.awakening_4_power = data['Awakening4Power'] + ret.awakening_4_clt = data['Awakening4Clt'] + ret.awakening_5_power = data['Awakening5Power'] + ret.awakening_5_clt = data['Awakening5Clt'] + ret.normal_leader = data['NormalLeader'] + ret.holo_leader = data['HoloLeader'] + ret.ui_display_power_title = data['UiDisplayPowerTitle'] + ret.ui_display_power_content = data['UiDisplayPowerContent'] + ret.prefab = data['Prefab'] + ret.cutin_mode = data['CutinMode'] + ret.skill_voice_id = data['SkillVoiceId'] + ret.skill_name = data['SkillName'] + ret.name_in_skill_cutin = data['NameInSkillCutin'] + ret.skill_text = data['SkillText'] + ret.skill_text_in_skill_cutin = data['SkillTextInSkillCutin'] + ret.chara_info = data['CharaInfo'] + ret.cutin_image = data['CutinImage'] + ret.cutin_image_awake = data['CutinImageAwake'] + ret.status_chara_icon = data['StatusCharaIcon'] + ret.status_chara_icon_awake = data['StatusCharaIconAwake'] + ret.collection_display_start_date = data['CollectionDisplayStartDate'] + ret.collection_empty_frame_display_flag = data['CollectionEmptyFrameDisplayFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.support_log_id) \ + + encode_short(self.chara_id) \ + + encode_str(self.name) \ + + encode_byte(self.rarity) \ + + encode_short(self.support_log_type_id) \ + + encode_int(self.sale_price) \ + + encode_int(self.composition_exp) \ + + encode_int(self.awakening_exp) \ + + encode_short(self.use_rank) \ + + encode_short(self.group_no) \ + + encode_short(self.adaptable_appear_append) \ + + encode_short(self.punisher_appear_append) \ + + encode_str(self.state) \ + + encode_str(self.passive_state) \ + + encode_int(self.power_default_value) \ + + encode_int(self.clt_default_value) \ + + encode_int(self.awakening_1_power) \ + + encode_int(self.awakening_1_clt) \ + + encode_int(self.awakening_2_power) \ + + encode_int(self.awakening_2_clt) \ + + encode_int(self.awakening_3_power) \ + + encode_int(self.awakening_3_clt) \ + + encode_int(self.awakening_4_power) \ + + encode_int(self.awakening_4_clt) \ + + encode_int(self.awakening_5_power) \ + + encode_int(self.awakening_5_clt) \ + + encode_int(self.normal_leader) \ + + encode_int(self.holo_leader) \ + + encode_str(self.ui_display_power_title) \ + + encode_str(self.ui_display_power_content) \ + + encode_str(self.prefab) \ + + encode_str(self.cutin_mode) \ + + encode_str(self.skill_voice_id) \ + + encode_str(self.skill_name) \ + + encode_str(self.name_in_skill_cutin) \ + + encode_str(self.skill_text) \ + + encode_str(self.skill_text_in_skill_cutin) \ + + encode_str(self.chara_info) \ + + encode_str(self.cutin_image) \ + + encode_str(self.cutin_image_awake) \ + + encode_str(self.status_chara_icon) \ + + encode_str(self.status_chara_icon_awake) \ + + encode_date_str(self.collection_display_start_date) \ + + encode_byte(self.collection_empty_frame_display_flag) + +class SupportLogTypeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.support_log_type_id = decode_short(data, off) + off += SHORT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "SupportLogTypeData": + ret = cls(b"\x00" * 99, 0) + ret.support_log_type_id = data['SupportLogTypeId'] + ret.name = data['Name'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_short(self.support_log_type_id) \ + + encode_str(self.name) + +class EpisodeAppendData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.episode_append_id = decode_int(data, off) + off += INT_OFF + + self.episode_append_type = decode_byte(data, off) + off += BYTE_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.flavor_text, new_off = decode_str(data, off) + off += new_off + + self.sale_possible_flag = decode_int(data, off) + off += INT_OFF + + self.sale_price = decode_int(data, off) + off += INT_OFF + + self.episode_append_icon, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EpisodeAppendData": + ret = cls(b"\x00" * 99, 0) + ret.episode_append_id = data['EpisodeAppendId'] + ret.episode_append_type = data['EpisodeAppendType'] + ret.name = data['Name'] + ret.flavor_text = data['FlavorText'] + ret.sale_possible_flag = data['SalePossibleFlag'] + ret.sale_price = data['SalePrice'] + ret.episode_append_icon = data['EpisodeAppendIcon'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.episode_append_id) \ + + encode_byte(self.episode_append_type) \ + + encode_str(self.name) \ + + encode_str(self.flavor_text) \ + + encode_int(self.sale_possible_flag) \ + + encode_int(self.sale_price) \ + + encode_str(self.episode_append_icon) + +class QuestDefragMatchQuestData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_quest_id = decode_int(data, off) + off += INT_OFF + + self.quest_scene_id = decode_int(data, off) + off += INT_OFF + + self.defrag_match_quest_boss_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.display_name, new_off = decode_str(data, off) + off += new_off + + self.map_no = decode_int(data, off) + off += INT_OFF + + self.unit_data1, new_off = decode_str(data, off) + off += new_off + + self.unit_data2, new_off = decode_str(data, off) + off += new_off + + self.unit_data3, new_off = decode_str(data, off) + off += new_off + + self.adaptable_rate, new_off = decode_str(data, off) + off += new_off + + self.punisher_flag = decode_byte(data, off) + off += BYTE_OFF + + self.comment_details, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestDefragMatchQuestData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_quest_id = data['DefragMatchQuestId'] + ret.quest_scene_id = data['QuestSceneId'] + ret.defrag_match_quest_boss_table_sub_id = data['DefragMatchBossTableSubId'] + ret.display_name = data['DisplayName'] + ret.map_no = data['VsModeNo'] + ret.unit_data1 = data['UnitData1'] + ret.unit_data2 = data['UnitData2'] + ret.unit_data3 = data['UnitData3'] + ret.adaptable_rate = data['AdaptableRate'] + ret.punisher_flag = data['PunisherFlag'] + ret.comment_details = data['CommentDetails'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_quest_id) \ + + encode_int(self.quest_scene_id) \ + + encode_int(self.defrag_match_quest_boss_table_sub_id) \ + + encode_str(self.display_name) \ + + encode_int(self.map_no) \ + + encode_str(self.unit_data1) \ + + encode_str(self.unit_data2) \ + + encode_str(self.unit_data3) \ + + encode_str(self.adaptable_rate) \ + + encode_byte(self.punisher_flag) \ + + encode_str(self.comment_details) + +class QuestDefragMatchQuestBossTableData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_quest_boss_table_id = decode_int(data, off) + off += INT_OFF + + self.defrag_match_quest_boss_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.wave = decode_int(data, off) + off += INT_OFF + + self.type = decode_int(data, off) + off += INT_OFF + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.rate = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestDefragMatchQuestBossTableData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_quest_boss_table_id = data['DefragMatchBossTableId'] + ret.defrag_match_quest_boss_table_sub_id = data['DefragMatchBossTableSubId'] + ret.wave = data['Wave'] + ret.type = data['Type'] + ret.unit_id = data['UnitId'] + ret.rate = data['Rate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_quest_boss_table_id) \ + + encode_int(self.defrag_match_quest_boss_table_sub_id) \ + + encode_int(self.wave) \ + + encode_int(self.type) \ + + encode_int(self.unit_id) \ + + encode_int(self.rate) + +class DefragMatchData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.season_no = decode_short(data, off) + off += SHORT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.first_attack_bonus_coefficient, new_off = decode_str(data, off) + off += new_off + + self.last_attack_bonus_coefficient, new_off = decode_str(data, off) + off += new_off + + self.memo, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_id = data['DefragMatchId'] + ret.season_no = data['SeasonNo'] + ret.title = data['Title'] + ret.first_attack_bonus_coefficient = data['FirstAttackBonusCoefficient'] + ret.last_attack_bonus_coefficient = data['LastAttackBonusCoefficient'] + ret.memo = data['Memo'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_id) \ + + encode_short(self.season_no) \ + + encode_str(self.title) \ + + encode_str(self.first_attack_bonus_coefficient) \ + + encode_str(self.last_attack_bonus_coefficient) \ + + encode_str(self.memo) + +class DefragMatchSeedData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_seed_id = decode_int(data, off) + off += INT_OFF + + self.defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.check_type = decode_byte(data, off) + off += BYTE_OFF + + self.need_class_num = decode_short(data, off) + off += SHORT_OFF + + self.need_cleared_trial_tower_id = decode_short(data, off) + off += SHORT_OFF + + self.get_league_point = decode_int(data, off) + off += INT_OFF + + self.get_league_score = decode_short(data, off) + off += SHORT_OFF + + self.set_class_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchSeedData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_seed_id = data['DefragMatchSeedId'] + ret.defrag_match_id = data['DefragMatchId'] + ret.check_type = data['CheckType'] + ret.need_class_num = data['NeedClassNum'] + ret.need_cleared_trial_tower_id = data['NeedClearedTrialTowerId'] + ret.get_league_point = data['GetLeaguePoint'] + ret.get_league_score = data['GetLeagueScore'] + ret.set_class_num = data['SetClassNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_seed_id) \ + + encode_int(self.defrag_match_id) \ + + encode_byte(self.check_type) \ + + encode_short(self.need_class_num) \ + + encode_short(self.need_cleared_trial_tower_id) \ + + encode_int(self.get_league_point) \ + + encode_short(self.get_league_score) \ + + encode_short(self.set_class_num) + +class DefragMatchSpecialEffectData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_special_effec_id = decode_int(data, off) + off += INT_OFF + + self.defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.special_effect_type = decode_byte(data, off) + off += BYTE_OFF + + self.special_effect_coefficient, new_off = decode_str(data, off) + off += new_off + + self.target_chara_id = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchSpecialEffectData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_special_effec_id = data['DefragMatchSpecialEffectsId'] + ret.defrag_match_id = data['DefragMatchId'] + ret.special_effect_type = data['SpecialEffectType'] + ret.special_effect_coefficient = data['SpecialEffectCoefficient'] + ret.target_chara_id = data['TargetCharaId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_special_effec_id) \ + + encode_int(self.defrag_match_id) \ + + encode_byte(self.special_effect_type) \ + + encode_str(self.special_effect_coefficient) \ + + encode_short(self.target_chara_id) + +class DefragMatchGradeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_grade_id = decode_int(data, off) + off += INT_OFF + + self.defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.class_num = decode_short(data, off) + off += SHORT_OFF + + self.grade_name, new_off = decode_str(data, off) + off += new_off + + self.class_name, new_off = decode_str(data, off) + off += new_off + + self.promotion_line_league_score = decode_short(data, off) + off += SHORT_OFF + + self.demotion_line_league_score = decode_short(data, off) + off += SHORT_OFF + + self.league_score_decrease_flag = decode_byte(data, off) + off += BYTE_OFF + + self.target_league_point_1 = decode_int(data, off) + off += INT_OFF + + self.target_league_point_2 = decode_int(data, off) + off += INT_OFF + + self.mvp_add_league_point = decode_int(data, off) + off += INT_OFF + + self.mob_level = decode_short(data, off) + off += SHORT_OFF + + self.normal_boss_level = decode_short(data, off) + off += SHORT_OFF + + self.adaptable_level = decode_short(data, off) + off += SHORT_OFF + + self.punisher_level = decode_short(data, off) + off += SHORT_OFF + + self.punisher_appearance_rate, new_off = decode_str(data, off) + off += new_off + + self.cpu_level = decode_short(data, off) + off += SHORT_OFF + + self.record_medal_drop_num = decode_short(data, off) + off += SHORT_OFF + + self.target_league_point_coefficient, new_off = decode_str(data, off) + off += new_off + + self.reward_table_sub_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchGradeData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_grade_id = data['DefragMatchGradeId'] + ret.defrag_match_id = data['DefragMatchId'] + ret.class_num = data['ClassNum'] + ret.grade_name = data['GradeName'] + ret.class_name = data['ClassName'] + ret.promotion_line_league_score = data['PromotionLineLeagueScore'] + ret.demotion_line_league_score = data['DemotionLineLeagueScore'] + ret.league_score_decrease_flag = data['LeagueScoreDecreaseFlag'] + ret.target_league_point_1 = data['TargetLeaguePoint1'] + ret.target_league_point_2 = data['TargetLeaguePoint2'] + ret.mvp_add_league_point = data['MvpAddLeaguePoint'] + ret.mob_level = data['MobLevel'] + ret.normal_boss_level = data['NormalBossLevel'] + ret.adaptable_level = data['AdaptableLevel'] + ret.punisher_level = data['PunisherLevel'] + ret.punisher_appearance_rate = data['PunisherAppearanceRate'] + ret.cpu_level = data['CpuLevel'] + ret.record_medal_drop_num = data['RecordMedalDropNum'] + ret.target_league_point_coefficient = data['TargetLeaguePointCoefficient'] + ret.reward_table_sub_id = data['RewardTableSubId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_grade_id) \ + + encode_int(self.defrag_match_id) \ + + encode_short(self.class_num) \ + + encode_str(self.grade_name) \ + + encode_str(self.class_name) \ + + encode_short(self.promotion_line_league_score) \ + + encode_short(self.demotion_line_league_score) \ + + encode_byte(self.league_score_decrease_flag) \ + + encode_int(self.target_league_point_1) \ + + encode_int(self.target_league_point_2) \ + + encode_int(self.mvp_add_league_point) \ + + encode_short(self.mob_level) \ + + encode_short(self.normal_boss_level) \ + + encode_short(self.adaptable_level) \ + + encode_short(self.punisher_level) \ + + encode_str(self.punisher_appearance_rate) \ + + encode_short(self.cpu_level) \ + + encode_short(self.record_medal_drop_num) \ + + encode_str(self.target_league_point_coefficient) \ + + encode_int(self.reward_table_sub_id) + +class DefragMatchCpuUnitData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_cpu_unit_id = decode_int(data, off) + off += INT_OFF + + self.appearance_start_defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.appearance_end_defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.appearance_start_class_num = decode_int(data, off) + off += INT_OFF + + self.appearance_end_class_num = decode_int(data, off) + off += INT_OFF + + self.hero_log_hero_log_id = decode_int(data, off) + off += INT_OFF + + self.hero_log_log_level = decode_short(data, off) + off += SHORT_OFF + + self.hero_log_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.hero_log_property1_property_id = decode_int(data, off) + off += INT_OFF + + self.hero_log_property1_value1 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property1_value2 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property2_property_id = decode_int(data, off) + off += INT_OFF + + self.hero_log_property2_value1 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property2_value2 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property3_property_id = decode_int(data, off) + off += INT_OFF + + self.hero_log_property3_value1 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property3_value2 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property4_property_id = decode_int(data, off) + off += INT_OFF + + self.hero_log_property4_value1 = decode_int(data, off) + off += INT_OFF + + self.hero_log_property4_value2 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_equipment_id = decode_int(data, off) + off += INT_OFF + + self.main_weapon_enhancement_value = decode_short(data, off) + off += SHORT_OFF + + self.main_weapon_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.main_weapon_property1_property_id = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property1_value1 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property1_value2 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property2_property_id = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property2_value1 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property2_value2 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property3_property_id = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property3_value1 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property3_value2 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property4_property_id = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property4_value1 = decode_int(data, off) + off += INT_OFF + + self.main_weapon_property4_value2 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_equipment_id = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_enhancement_value = decode_short(data, off) + off += SHORT_OFF + + self.sub_equipment_awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self.sub_equipment_property1_property_id = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property1_value1 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property1_value2 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property2_property_id = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property2_value1 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property2_value2 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property3_property_id = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property3_value1 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property3_value2 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property4_property_id = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property4_value1 = decode_int(data, off) + off += INT_OFF + + self.sub_equipment_property4_value2 = decode_int(data, off) + off += INT_OFF + + self.skill_slot1_skill_id = decode_short(data, off) + off += SHORT_OFF + + self.skill_slot2_skill_id = decode_short(data, off) + off += SHORT_OFF + + self.skill_slot3_skill_id = decode_short(data, off) + off += SHORT_OFF + + self.skill_slot4_skill_id = decode_short(data, off) + off += SHORT_OFF + + self.skill_slot5_skill_id = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchCpuUnitData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_cpu_unit_id = data['DefragMatchCpuUnitsId'] + ret.appearance_start_defrag_match_id = data['AppearanceStartDefragMatchId'] + ret.appearance_end_defrag_match_id = data['AppearanceEndDefragMatchId'] + ret.appearance_start_class_num = data['AppearanceStartClassNum'] + ret.appearance_end_class_num = data['AppearanceEndClassNum'] + ret.hero_log_hero_log_id = data['HeroLogHeroLogId'] + ret.hero_log_log_level = data['HeroLogLogLevel'] + ret.hero_log_awakening_stage = data['HeroLogAwakeningStage'] + ret.hero_log_property1_property_id = data['HeroLogProperty1PropertyId'] + ret.hero_log_property1_value1 = data['HeroLogProperty1Value1'] + ret.hero_log_property1_value2 = data['HeroLogProperty1Value2'] + ret.hero_log_property2_property_id = data['HeroLogProperty2PropertyId'] + ret.hero_log_property2_value1 = data['HeroLogProperty2Value1'] + ret.hero_log_property2_value2 = data['HeroLogProperty2Value2'] + ret.hero_log_property3_property_id = data['HeroLogProperty3PropertyId'] + ret.hero_log_property3_value1 = data['HeroLogProperty3Value1'] + ret.hero_log_property3_value2 = data['HeroLogProperty3Value2'] + ret.hero_log_property4_property_id = data['HeroLogProperty4PropertyId'] + ret.hero_log_property4_value1 = data['HeroLogProperty4Value1'] + ret.hero_log_property4_value2 = data['HeroLogProperty4Value2'] + ret.main_weapon_equipment_id = data['MainWeaponEquipmentId'] + ret.main_weapon_enhancement_value = data['MainWeaponEnhancementValue'] + ret.main_weapon_awakening_stage = data['MainWeaponAwakeningStage'] + ret.main_weapon_property1_property_id = data['MainWeaponProperty1PropertyId'] + ret.main_weapon_property1_value1 = data['MainWeaponProperty1Value1'] + ret.main_weapon_property1_value2 = data['MainWeaponProperty1Value2'] + ret.main_weapon_property2_property_id = data['MainWeaponProperty2PropertyId'] + ret.main_weapon_property2_value1 = data['MainWeaponProperty2Value1'] + ret.main_weapon_property2_value2 = data['MainWeaponProperty2Value2'] + ret.main_weapon_property3_property_id = data['MainWeaponProperty3PropertyId'] + ret.main_weapon_property3_value1 = data['MainWeaponProperty3Value1'] + ret.main_weapon_property3_value2 = data['MainWeaponProperty3Value2'] + ret.main_weapon_property4_property_id = data['MainWeaponProperty4PropertyId'] + ret.main_weapon_property4_value1 = data['MainWeaponProperty4Value1'] + ret.main_weapon_property4_value2 = data['MainWeaponProperty4Value2'] + ret.sub_equipment_equipment_id = data['SubEquipmentEquipmentId'] + ret.sub_equipment_enhancement_value = data['SubEquipmentEnhancementValue'] + ret.sub_equipment_awakening_stage = data['SubEquipmentAwakeningStage'] + ret.sub_equipment_property1_property_id = data['SubEquipmentProperty1PropertyId'] + ret.sub_equipment_property1_value1 = data['SubEquipmentProperty1Value1'] + ret.sub_equipment_property1_value2 = data['SubEquipmentProperty1Value2'] + ret.sub_equipment_property2_property_id = data['SubEquipmentProperty2PropertyId'] + ret.sub_equipment_property2_value1 = data['SubEquipmentProperty2Value1'] + ret.sub_equipment_property2_value2 = data['SubEquipmentProperty2Value2'] + ret.sub_equipment_property3_property_id = data['SubEquipmentProperty3PropertyId'] + ret.sub_equipment_property3_value1 = data['SubEquipmentProperty3Value1'] + ret.sub_equipment_property3_value2 = data['SubEquipmentProperty3Value2'] + ret.sub_equipment_property4_property_id = data['SubEquipmentProperty4PropertyId'] + ret.sub_equipment_property4_value1 = data['SubEquipmentProperty4Value1'] + ret.sub_equipment_property4_value2 = data['SubEquipmentProperty4Value2'] + ret.skill_slot1_skill_id = data['SkillSlot1SkillId'] + ret.skill_slot2_skill_id = data['SkillSlot2SkillId'] + ret.skill_slot3_skill_id = data['SkillSlot3SkillId'] + ret.skill_slot4_skill_id = data['SkillSlot4SkillId'] + ret.skill_slot5_skill_id = data['SkillSlot5SkillId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_cpu_unit_id) \ + + encode_int(self.appearance_start_defrag_match_id) \ + + encode_int(self.appearance_end_defrag_match_id) \ + + encode_int(self.appearance_start_class_num) \ + + encode_int(self.appearance_end_class_num) \ + + encode_int(self.hero_log_hero_log_id) \ + + encode_short(self.hero_log_log_level) \ + + encode_short(self.hero_log_awakening_stage) \ + + encode_int(self.hero_log_property1_property_id) \ + + encode_int(self.hero_log_property1_value1) \ + + encode_int(self.hero_log_property1_value2) \ + + encode_int(self.hero_log_property2_property_id) \ + + encode_int(self.hero_log_property2_value1) \ + + encode_int(self.hero_log_property2_value2) \ + + encode_int(self.hero_log_property3_property_id) \ + + encode_int(self.hero_log_property3_value1) \ + + encode_int(self.hero_log_property3_value2) \ + + encode_int(self.hero_log_property4_property_id) \ + + encode_int(self.hero_log_property4_value1) \ + + encode_int(self.hero_log_property4_value2) \ + + encode_int(self.main_weapon_equipment_id) \ + + encode_short(self.main_weapon_enhancement_value) \ + + encode_short(self.main_weapon_awakening_stage) \ + + encode_int(self.main_weapon_property1_property_id) \ + + encode_int(self.main_weapon_property1_value1) \ + + encode_int(self.main_weapon_property1_value2) \ + + encode_int(self.main_weapon_property2_property_id) \ + + encode_int(self.main_weapon_property2_value1) \ + + encode_int(self.main_weapon_property2_value2) \ + + encode_int(self.main_weapon_property3_property_id) \ + + encode_int(self.main_weapon_property3_value1) \ + + encode_int(self.main_weapon_property3_value2) \ + + encode_int(self.main_weapon_property4_property_id) \ + + encode_int(self.main_weapon_property4_value1) \ + + encode_int(self.main_weapon_property4_value2) \ + + encode_int(self.sub_equipment_equipment_id) \ + + encode_short(self.sub_equipment_enhancement_value) \ + + encode_short(self.sub_equipment_awakening_stage) \ + + encode_int(self.sub_equipment_property1_property_id) \ + + encode_int(self.sub_equipment_property1_value1) \ + + encode_int(self.sub_equipment_property1_value2) \ + + encode_int(self.sub_equipment_property2_property_id) \ + + encode_int(self.sub_equipment_property2_value1) \ + + encode_int(self.sub_equipment_property2_value2) \ + + encode_int(self.sub_equipment_property3_property_id) \ + + encode_int(self.sub_equipment_property3_value1) \ + + encode_int(self.sub_equipment_property3_value2) \ + + encode_int(self.sub_equipment_property4_property_id) \ + + encode_int(self.sub_equipment_property4_value1) \ + + encode_int(self.sub_equipment_property4_value2) \ + + encode_short(self.skill_slot1_skill_id) \ + + encode_short(self.skill_slot2_skill_id) \ + + encode_short(self.skill_slot3_skill_id) \ + + encode_short(self.skill_slot4_skill_id) \ + + encode_short(self.skill_slot5_skill_id) + +class DefragMatchCpuSupportLogData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_cpu_support_log_id = decode_int(data, off) + off += INT_OFF + + self.appearance_start_defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.appearance_end_defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.appearance_start_class_num = decode_int(data, off) + off += INT_OFF + + self.appearance_end_class_num = decode_int(data, off) + off += INT_OFF + + self.support_log_id = decode_int(data, off) + off += INT_OFF + + self.awakening_stage = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchCpuSupportLogData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_cpu_support_log_id = data['DefragMatchCpuSupportLogId'] + ret.appearance_start_defrag_match_id = data['AppearanceStartDefragMatchId'] + ret.appearance_end_defrag_match_id = data['AppearanceEndDefragMatchId'] + ret.appearance_start_class_num = data['AppearanceStartClassNum'] + ret.appearance_end_class_num = data['AppearanceEndClassNum'] + ret.support_log_id = data['SupportLogId'] + ret.awakening_stage = data['AwakeningStage'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_cpu_support_log_id) \ + + encode_int(self.appearance_start_defrag_match_id) \ + + encode_int(self.appearance_end_defrag_match_id) \ + + encode_int(self.appearance_start_class_num) \ + + encode_int(self.appearance_end_class_num) \ + + encode_int(self.support_log_id) \ + + encode_short(self.awakening_stage) + +class DefragMatchPeriodBonusData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_period_bonus_id = decode_int(data, off) + off += INT_OFF + + self.defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.bonus_type = decode_byte(data, off) + off += BYTE_OFF + + self.param_1, new_off = decode_str(data, off) + off += new_off + + self.param_2, new_off = decode_str(data, off) + off += new_off + + self.param_3, new_off = decode_str(data, off) + off += new_off + + self.start_date, new_off = decode_date_str(data, off) + off += new_off + + self.end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchPeriodBonusData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_period_bonus_id = data['DefragMatchPeriodBonusId'] + ret.defrag_match_id = data['DefragMatchId'] + ret.bonus_type = data['BonusType'] + ret.param_1 = data['Param1'] + ret.param_2 = data['Param2'] + ret.param_3 = data['Param3'] + ret.start_date = data['StartDate'] + ret.end_date = data['EndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_period_bonus_id) \ + + encode_int(self.defrag_match_id) \ + + encode_byte(self.bonus_type) \ + + encode_str(self.param_1) \ + + encode_str(self.param_2) \ + + encode_str(self.param_3) \ + + encode_date_str(self.start_date) \ + + encode_date_str(self.end_date) + +class DefragMatchRandomBonusTableData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_random_bonus_id = decode_int(data, off) + off += INT_OFF + + self.defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.defrag_match_random_bonus_condition_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.condition_value1 = decode_int(data, off) + off += INT_OFF + + self.condition_value2 = decode_int(data, off) + off += INT_OFF + + self.get_league_point = decode_int(data, off) + off += INT_OFF + + self.random_bonus_num = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchRandomBonusTableData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_random_bonus_id = data['DefragMatchRandomBonusId'] + ret.defrag_match_id = data['DefragMatchId'] + ret.defrag_match_random_bonus_condition_id = data['DefragMatchRandomBonusConditionId'] + ret.name = data['Name'] + ret.condition_value1 = data['ConditionValue1'] + ret.condition_value2 = data['ConditionValue2'] + ret.get_league_point = data['GetLeaguePoint'] + ret.random_bonus_num = data['RandomBonusNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_random_bonus_id) \ + + encode_int(self.defrag_match_id) \ + + encode_int(self.defrag_match_random_bonus_condition_id) \ + + encode_str(self.name) \ + + encode_int(self.condition_value1) \ + + encode_int(self.condition_value2) \ + + encode_int(self.get_league_point) \ + + encode_byte(self.random_bonus_num) + +class DefragMatchRandomBonusConditionData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_random_bonus_condition_id = decode_int(data, off) + off += INT_OFF + + self.format, new_off = decode_str(data, off) + off += new_off + + self.hud_format, new_off = decode_str(data, off) + off += new_off + + self.format_param_size = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchRandomBonusConditionData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_random_bonus_condition_id = data['DefragMatchRandomBonusConditionId'] + ret.format = data['Format'] + ret.hud_format = data['HudFormat'] + ret.format_param_size = data['FormatParamSize'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_random_bonus_condition_id) \ + + encode_str(self.format) \ + + encode_str(self.hud_format) \ + + encode_int(self.format_param_size) + +class DefragMatchRareDropData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.defrag_match_rare_drop_id = decode_int(data, off) + off += INT_OFF + + self.defrag_match_id = decode_int(data, off) + off += INT_OFF + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_int(data, off) + off += INT_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_int(data, off) + off += INT_OFF + + self.strength_min = decode_int(data, off) + off += INT_OFF + + self.strength_max = decode_int(data, off) + off += INT_OFF + + self.property_table_sub_id = decode_int(data, off) + off += INT_OFF + + self.drop_rate, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "DefragMatchRareDropData": + ret = cls(b"\x00" * 99, 0) + ret.defrag_match_rare_drop_id = data['DefragMatchRareDropId'] + ret.defrag_match_id = data['DefragMatchId'] + ret.unit_id = data['UnitId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength_min = data['StrengthMin'] + ret.strength_max = data['StrengthMax'] + ret.property_table_sub_id = data['PropertyTableSubId'] + ret.drop_rate = data['DropRate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.defrag_match_rare_drop_id) \ + + encode_int(self.defrag_match_id) \ + + encode_int(self.unit_id) \ + + encode_int(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_int(self.common_reward_num) \ + + encode_int(self.strength_min) \ + + encode_int(self.strength_max) \ + + encode_int(self.property_table_sub_id) \ + + encode_str(self.drop_rate) + +class YuiMedalShopData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.yui_medal_shop_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.description, new_off = decode_str(data, off) + off += new_off + + self.selling_yui_medal = decode_short(data, off) + off += SHORT_OFF + + self.selling_col = decode_int(data, off) + off += INT_OFF + + self.selling_event_item_id = decode_int(data, off) + off += INT_OFF + + self.selling_event_item_num = decode_int(data, off) + off += INT_OFF + + self.selling_ticket_num = decode_int(data, off) + off += INT_OFF + + self.purchase_limit = decode_short(data, off) + off += SHORT_OFF + + self.pick_up_flag = decode_byte(data, off) + off += BYTE_OFF + + self.product_category = decode_byte(data, off) + off += BYTE_OFF + + self.sales_type = decode_byte(data, off) + off += BYTE_OFF + + self.target_days = decode_byte(data, off) + off += BYTE_OFF + + self.target_hour = decode_byte(data, off) + off += BYTE_OFF + + self.interval_hour = decode_byte(data, off) + off += BYTE_OFF + + self.sales_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.sales_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.sort = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "YuiMedalShopData": + ret = cls(b"\x00" * 99, 0) + ret.yui_medal_shop_id = data['YuiMedalShopId'] + ret.name = data['Name'] + ret.description = data['Description'] + ret.selling_yui_medal = data['SellingYuiMedal'] + ret.selling_col = data['SellingCol'] + ret.selling_event_item_id = data['SellingEventItemId'] + ret.selling_event_item_num = data['SellingEventItemNum'] + ret.selling_ticket_num = data['SellingTicketNum'] + ret.purchase_limit = data['PurchaseLimit'] + ret.pick_up_flag = data['PickUpFlag'] + ret.product_category = data['ProductCategory'] + ret.sales_type = data['SalesType'] + ret.target_days = data['TargetDays'] + ret.target_hour = data['TargetHour'] + ret.interval_hour = data['IntervalHour'] + ret.sales_start_date = data['SalesStartDate'] + ret.sales_end_date = data['SalesEndDate'] + ret.sort = data['Sort'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.yui_medal_shop_id) \ + + encode_str(self.name) \ + + encode_str(self.description) \ + + encode_short(self.selling_yui_medal) \ + + encode_int(self.selling_col) \ + + encode_int(self.selling_event_item_id) \ + + encode_int(self.selling_event_item_num) \ + + encode_int(self.selling_ticket_num) \ + + encode_short(self.purchase_limit) \ + + encode_byte(self.pick_up_flag) \ + + encode_byte(self.product_category) \ + + encode_byte(self.sales_type) \ + + encode_byte(self.target_days) \ + + encode_byte(self.target_hour) \ + + encode_byte(self.interval_hour) \ + + encode_date_str(self.sales_start_date) \ + + encode_date_str(self.sales_end_date) \ + + encode_byte(self.sort) + +class YuiMedalShopItemData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.yui_medal_shop_item_id = decode_int(data, off) + off += INT_OFF + + self.yui_medal_shop_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "YuiMedalShopItemData": + ret = cls(b"\x00" * 99, 0) + ret.yui_medal_shop_item_id = data['YuiMedalShopItemId'] + ret.yui_medal_shop_id = data['YuiMedalShopId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.yui_medal_shop_item_id) \ + + encode_int(self.yui_medal_shop_id) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) + +class EventSceneData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.event_scene_id = decode_int(data, off) + off += INT_OFF + + self.event_id = decode_int(data, off) + off += INT_OFF + + self.scene_type = decode_byte(data, off) + off += BYTE_OFF + + self.episode_no = decode_int(data, off) + off += INT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.param_1, new_off = decode_str(data, off) + off += new_off + + self.param_2, new_off = decode_str(data, off) + off += new_off + + self.param_3, new_off = decode_str(data, off) + off += new_off + + self.adv_name, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EventSceneData": + ret = cls(b"\x00" * 99, 0) + ret.event_scene_id = data['EventSceneId'] + ret.event_id = data['EventId'] + ret.scene_type = data['SceneType'] + ret.episode_no = data['EpisodeNo'] + ret.title = data['Title'] + ret.param_1 = data['Param1'] + ret.param_2 = data['Param2'] + ret.param_3 = data['Param3'] + ret.adv_name = data['AdvName'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.event_scene_id) \ + + encode_int(self.event_id) \ + + encode_byte(self.scene_type) \ + + encode_int(self.episode_no) \ + + encode_str(self.title) \ + + encode_str(self.param_1) \ + + encode_str(self.param_2) \ + + encode_str(self.param_3) \ + + encode_str(self.adv_name) + +class GenericCampaignPeriodData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.generic_campaign_period_id = decode_int(data, off) + off += INT_OFF + + self.start_date, new_off = decode_date_str(data, off) + off += new_off + + self.end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GenericCampaignPeriodData": + ret = cls(b"\x00" * 99, 0) + ret.generic_campaign_period_id = data['GenericCampaignPeriodId'] + ret.start_date = data['StartDate'] + ret.end_date = data['EndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.generic_campaign_period_id) \ + + encode_date_str(self.start_date) \ + + encode_date_str(self.end_date) + +class BeginnerMissionData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.beginner_mission_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.start_date, new_off = decode_date_str(data, off) + off += new_off + + self.end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BeginnerMissionData": + ret = cls(b"\x00" * 99, 0) + ret.beginner_mission_id = data['BeginnerMissionId'] + ret.name = data['Name'] + ret.start_date = data['StartDate'] + ret.end_date = data['EndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.beginner_mission_id) \ + + encode_str(self.name) \ + + encode_date_str(self.start_date) \ + + encode_date_str(self.end_date) + +class BeginnerMissionConditionData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.beginner_mission_condition_id = decode_int(data, off) + off += INT_OFF + + self.beginner_mission_id = decode_int(data, off) + off += INT_OFF + + self.seat_num = decode_short(data, off) + off += SHORT_OFF + + self.mission_num = decode_short(data, off) + off += SHORT_OFF + + self.display_content, new_off = decode_str(data, off) + off += new_off + + self.display_tips, new_off = decode_str(data, off) + off += new_off + + self.condition_type = decode_byte(data, off) + off += BYTE_OFF + + self.condition_param_1, new_off = decode_str(data, off) + off += new_off + + self.condition_param_2, new_off = decode_str(data, off) + off += new_off + + self.condition_param_3, new_off = decode_str(data, off) + off += new_off + + self.required_achievement_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BeginnerMissionConditionData": + ret = cls(b"\x00" * 99, 0) + ret.beginner_mission_condition_id = data['BeginnerMissionConditionId'] + ret.beginner_mission_id = data['BeginnerMissionId'] + ret.seat_num = data['SeatNum'] + ret.mission_num = data['MissionNum'] + ret.display_content = data['DisplayContent'] + ret.display_tips = data['DisplayTips'] + ret.condition_type = data['ConditionType'] + ret.condition_param_1 = data['ConditionParam1'] + ret.condition_param_2 = data['ConditionParam2'] + ret.condition_param_3 = data['ConditionParam3'] + ret.required_achievement_num = data['RequiredAchievementNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.beginner_mission_condition_id) \ + + encode_int(self.beginner_mission_id) \ + + encode_short(self.seat_num) \ + + encode_short(self.mission_num) \ + + encode_str(self.display_content) \ + + encode_str(self.display_tips) \ + + encode_byte(self.condition_type) \ + + encode_str(self.condition_param_1) \ + + encode_str(self.condition_param_2) \ + + encode_str(self.condition_param_3) \ + + encode_short(self.required_achievement_num) + +class BeginnerMissionRewardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.beginner_mission_id = decode_int(data, off) + off += INT_OFF + + self.beginner_mission_condition_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BeginnerMissionRewardData": + ret = cls(b"\x00" * 99, 0) + ret.beginner_mission_id = data['BeginnerMissionId'] + ret.beginner_mission_condition_id = data['BeginnerMissionConditionId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.beginner_mission_id) \ + + encode_int(self.beginner_mission_condition_id) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) + +class BeginnerMissionSeatConditionData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.beginner_mission_id = decode_int(data, off) + off += INT_OFF + + self.beginner_mission_seat_condition_id = decode_int(data, off) + off += INT_OFF + + self.seat_num = decode_short(data, off) + off += SHORT_OFF + + self.mission_seat_num = decode_short(data, off) + off += SHORT_OFF + + self.display_content, new_off = decode_str(data, off) + off += new_off + + self.display_tips, new_off = decode_str(data, off) + off += new_off + + self.condition_type = decode_byte(data, off) + off += BYTE_OFF + + self.condition_param_1, new_off = decode_str(data, off) + off += new_off + + self.condition_param_2, new_off = decode_str(data, off) + off += new_off + + self.condition_param_3, new_off = decode_str(data, off) + off += new_off + + self.required_achievement_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BeginnerMissionSeatConditionData": + ret = cls(b"\x00" * 99, 0) + ret.beginner_mission_id = data['BeginnerMissionId'] + ret.beginner_mission_seat_condition_id = data['BeginnerMissionSeatConditionId'] + ret.seat_num = data['SeatNum'] + ret.mission_seat_num = data['MissionSeatNum'] + ret.display_content = data['DisplayContent'] + ret.display_tips = data['DisplayTips'] + ret.condition_type = data['ConditionType'] + ret.condition_param_1 = data['ConditionParam1'] + ret.condition_param_2 = data['ConditionParam2'] + ret.condition_param_3 = data['ConditionParam3'] + ret.required_achievement_num = data['RequiredAchievementNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.beginner_mission_id) \ + + encode_int(self.beginner_mission_seat_condition_id) \ + + encode_short(self.seat_num) \ + + encode_short(self.mission_seat_num) \ + + encode_str(self.display_content) \ + + encode_str(self.display_tips) \ + + encode_byte(self.condition_type) \ + + encode_str(self.condition_param_1) \ + + encode_str(self.condition_param_2) \ + + encode_str(self.condition_param_3) \ + + encode_short(self.required_achievement_num) + +class BeginnerMissionSeatRewardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.beginner_mission_id = decode_int(data, off) + off += INT_OFF + + self.beginner_mission_seat_condition_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "BeginnerMissionSeatRewardData": + ret = cls(b"\x00" * 99, 0) + ret.beginner_mission_id = data['BeginnerMissionId'] + ret.beginner_mission_seat_condition_id = data['BeginnerMissionSeatConditionId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.beginner_mission_id) \ + + encode_int(self.beginner_mission_seat_condition_id) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) + +class EventItemData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.event_item_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.flavor_text, new_off = decode_str(data, off) + off += new_off + + self.event_item_icon, new_off = decode_str(data, off) + off += new_off + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EventItemData": + ret = cls(b"\x00" * 99, 0) + ret.event_item_id = data['EventItemId'] + ret.name = data['Name'] + ret.flavor_text = data['FlavorText'] + ret.event_item_icon = data['EventItemIcon'] + ret.unit_id = data['UnitId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.event_item_id) \ + + encode_str(self.name) \ + + encode_str(self.flavor_text) \ + + encode_str(self.event_item_icon) \ + + encode_int(self.unit_id) + +class EventMonsterData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.event_monster_id = decode_int(data, off) + off += INT_OFF + + self.event_id = decode_int(data, off) + off += INT_OFF + + self.unit_id = decode_int(data, off) + off += INT_OFF + + self.event_item_id = decode_int(data, off) + off += INT_OFF + + self.drop_rate, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "EventMonsterData": + ret = cls(b"\x00" * 99, 0) + ret.event_monster_id = data['EventMonsterId'] + ret.event_id = data['EventId'] + ret.unit_id = data['UnitId'] + ret.event_item_id = data['EventItemId'] + ret.drop_rate = data['DropRate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.event_monster_id) \ + + encode_int(self.event_id) \ + + encode_int(self.unit_id) \ + + encode_int(self.event_item_id) \ + + encode_str(self.drop_rate) + +class YuiMedalBonusData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.yui_medal_bonus_id = decode_int(data, off) + off += INT_OFF + + self.start_date, new_off = decode_date_str(data, off) + off += new_off + + self.end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "YuiMedalBonusData": + ret = cls(b"\x00" * 99, 0) + ret.yui_medal_bonus_id = data['YuiMedalBonusId'] + ret.start_date = data['StartDate'] + ret.end_date = data['EndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.yui_medal_bonus_id) \ + + encode_date_str(self.start_date) \ + + encode_date_str(self.end_date) + +class YuiMedalBonusConditionData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.yui_medal_bonus_condition_id = decode_int(data, off) + off += INT_OFF + + self.yui_medal_bonus_id = decode_int(data, off) + off += INT_OFF + + self.target_days = decode_int(data, off) + off += INT_OFF + + self.get_num = decode_int(data, off) + off += INT_OFF + + self.loop_flag = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "YuiMedalBonusConditionData": + ret = cls(b"\x00" * 99, 0) + ret.yui_medal_bonus_condition_id = data['YuiMedalBonusConditionId'] + ret.yui_medal_bonus_id = data['YuiMedalBonusId'] + ret.target_days = data['TargetDays'] + ret.get_num = data['GetNum'] + ret.loop_flag = data['LoopFlag'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.yui_medal_bonus_condition_id) \ + + encode_int(self.yui_medal_bonus_id) \ + + encode_int(self.target_days) \ + + encode_int(self.get_num) \ + + encode_byte(self.loop_flag) + +class GashaMedalData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gasha_medal_id = decode_int(data, off) + off += INT_OFF + + self.gasha_medal_type = decode_byte(data, off) + off += BYTE_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaMedalData": + ret = cls(b"\x00" * 99, 0) + ret.gasha_medal_id = data['GashaMedalId'] + ret.gasha_medal_type = data['GashaMedalType'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.gasha_medal_id) \ + + encode_byte(self.gasha_medal_type) + +class GashaMedalTypeData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gasha_medal_type = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.medal_icon, new_off = decode_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaMedalTypeData": + ret = cls(b"\x00" * 99, 0) + ret.gasha_medal_type = data['GashaMedalType'] + ret.name = data['Name'] + ret.medal_icon = data['MedalIcon'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.gasha_medal_type) \ + + encode_str(self.name) \ + + encode_str(self.medal_icon) + +class GashaMedalSettingData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gasha_id = decode_int(data, off) + off += INT_OFF + + self.gasha_medal_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaMedalSettingData": + ret = cls(b"\x00" * 99, 0) + ret.gasha_id = data['GashaId'] + ret.gasha_medal_id = data['GashaMedalId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.gasha_id) \ + + encode_int(self.gasha_medal_id) + +class GashaMedalBonusData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.analyze_amount = decode_byte(data, off) + off += BYTE_OFF + + self.get_gasha_medal_num = decode_int(data, off) + off += INT_OFF + + self.start_date, new_off = decode_date_str(data, off) + off += new_off + + self.end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaMedalBonusData": + ret = cls(b"\x00" * 99, 0) + ret.analyze_amount = data['AnalyzeAmount'] + ret.get_gasha_medal_num = data['GetGashaMedalNum'] + ret.start_date = data['StartDate'] + ret.end_date = data['EndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_byte(self.analyze_amount) \ + + encode_int(self.get_gasha_medal_num) \ + + encode_date_str(self.start_date) \ + + encode_date_str(self.end_date) + +class GashaMedalShopData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gasha_medal_shop_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.gasha_medal_id = decode_int(data, off) + off += INT_OFF + + self.use_gasha_medal_num = decode_int(data, off) + off += INT_OFF + + self.purchase_limit = decode_short(data, off) + off += SHORT_OFF + + self.start_date, new_off = decode_date_str(data, off) + off += new_off + + self.end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaMedalShopData": + ret = cls(b"\x00" * 99, 0) + ret.gasha_medal_shop_id = data['GashaMedalShopId'] + ret.name = data['Name'] + ret.gasha_medal_id = data['GashaMedalId'] + ret.use_gasha_medal_num = data['UseGashaMedalNum'] + ret.purchase_limit = data['PurchaseLimit'] + ret.start_date = data['StartDate'] + ret.end_date = data['EndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.gasha_medal_shop_id) \ + + encode_str(self.name) \ + + encode_int(self.gasha_medal_id) \ + + encode_int(self.use_gasha_medal_num) \ + + encode_short(self.purchase_limit) \ + + encode_date_str(self.start_date) \ + + encode_date_str(self.end_date) + +class GashaMedalShopItemData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gasha_medal_shop_item_id = decode_int(data, off) + off += INT_OFF + + self.gasha_medal_shop_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaMedalShopItemData": + ret = cls(b"\x00" * 99, 0) + ret.gasha_medal_shop_item_id = data['GashaMedalShopItemId'] + ret.gasha_medal_shop_id = data['GashaMedalShopId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.gasha_medal_shop_item_id) \ + + encode_int(self.gasha_medal_shop_id) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) + +class ResEarnCampaignApplicationData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.res_earn_campaign_application_id = decode_int(data, off) + off += INT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.posting_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.posting_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.news_id, new_off = decode_str(data, off) + off += new_off + + self.help_id = decode_int(data, off) + off += INT_OFF + + self.ad_banner_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ResEarnCampaignApplicationData": + ret = cls(b"\x00" * 99, 0) + ret.res_earn_campaign_application_id = data['ResEarnCampaignApplicationId'] + ret.title = data['Title'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + ret.posting_start_date = data['PostingStartDate'] + ret.posting_end_date = data['PostingEndDate'] + ret.news_id = data['NewsId'] + ret.help_id = data['HelpId'] + ret.ad_banner_id = data['AdBannerId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.res_earn_campaign_application_id) \ + + encode_str(self.title) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) \ + + encode_date_str(self.posting_start_date) \ + + encode_date_str(self.posting_end_date) \ + + encode_str(self.news_id) \ + + encode_int(self.help_id) \ + + encode_int(self.ad_banner_id) + +class ResEarnCampaignApplicationProductData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.res_earn_campaign_application_product_id = decode_int(data, off) + off += INT_OFF + + self.res_earn_campaign_application_id = decode_int(data, off) + off += INT_OFF + + self.award_name, new_off = decode_str(data, off) + off += new_off + + self.name, new_off = decode_str(data, off) + off += new_off + + self.need_application_point = decode_short(data, off) + off += SHORT_OFF + + self.winning_num = decode_short(data, off) + off += SHORT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ResEarnCampaignApplicationProductData": + ret = cls(b"\x00" * 99, 0) + ret.res_earn_campaign_application_product_id = data['ResEarnCampaignApplicationProductId'] + ret.res_earn_campaign_application_id = data['ResEarnCampaignApplicationId'] + ret.award_name = data['AwardName'] + ret.name = data['Name'] + ret.need_application_point = data['NeedApplicationPoint'] + ret.winning_num = data['WinningNum'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.res_earn_campaign_application_product_id) \ + + encode_int(self.res_earn_campaign_application_id) \ + + encode_str(self.award_name) \ + + encode_str(self.name) \ + + encode_short(self.need_application_point) \ + + encode_short(self.winning_num) + +class ResEarnCampaignShopData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.res_earn_campaign_shop_id = decode_int(data, off) + off += INT_OFF + + self.res_earn_campaign_application_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.selling_yui_medal = decode_short(data, off) + off += SHORT_OFF + + self.selling_col = decode_int(data, off) + off += INT_OFF + + self.selling_event_item_id = decode_int(data, off) + off += INT_OFF + + self.selling_event_item_num = decode_int(data, off) + off += INT_OFF + + self.purchase_limit = decode_short(data, off) + off += SHORT_OFF + + self.get_application_point = decode_short(data, off) + off += SHORT_OFF + + self.start_date, new_off = decode_date_str(data, off) + off += new_off + + self.end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ResEarnCampaignShopData": + ret = cls(b"\x00" * 99, 0) + ret.res_earn_campaign_shop_id = data['ResEarnCampaignShopId'] + ret.res_earn_campaign_application_id = data['ResEarnCampaignApplicationId'] + ret.name = data['Name'] + ret.selling_yui_medal = data['SellingYuiMedal'] + ret.selling_col = data['SellingCol'] + ret.selling_event_item_id = data['SellingEventItemId'] + ret.selling_event_item_num = data['SellingEventItemNum'] + ret.purchase_limit = data['PurchaseLimit'] + ret.get_application_point = data['GetApplicationPoint'] + ret.start_date = data['StartDate'] + ret.end_date = data['EndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.res_earn_campaign_shop_id) \ + + encode_int(self.res_earn_campaign_application_id) \ + + encode_str(self.name) \ + + encode_short(self.selling_yui_medal) \ + + encode_int(self.selling_col) \ + + encode_int(self.selling_event_item_id) \ + + encode_int(self.selling_event_item_num) \ + + encode_short(self.purchase_limit) \ + + encode_short(self.get_application_point) \ + + encode_date_str(self.start_date) \ + + encode_date_str(self.end_date) + +class ResEarnCampaignShopItemData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.res_earn_campaign_shop_item_id = decode_int(data, off) + off += INT_OFF + + self.res_earn_campaign_shop_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "ResEarnCampaignShopItemData": + ret = cls(b"\x00" * 99, 0) + ret.res_earn_campaign_shop_item_id = data['ResEarnCampaignShopItemId'] + ret.res_earn_campaign_shop_id = data['ResEarnCampaignShopId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.res_earn_campaign_shop_item_id) \ + + encode_int(self.res_earn_campaign_shop_id) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) + +class PayingYuiMedalBonusData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.paying_yui_medal_bonus_id = decode_int(data, off) + off += INT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.reward_yui_medal_num = decode_int(data, off) + off += INT_OFF + + self.news_id, new_off = decode_str(data, off) + off += new_off + + self.help_id = decode_int(data, off) + off += INT_OFF + + self.ad_banner_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "PayingYuiMedalBonusData": + ret = cls(b"\x00" * 99, 0) + ret.paying_yui_medal_bonus_id = data['PayingYuiMedalBonusId'] + ret.title = data['Title'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + ret.reward_yui_medal_num = data['RewardYuiMedalNum'] + ret.news_id = data['NewsId'] + ret.help_id = data['HelpId'] + ret.ad_banner_id = data['AdBannerId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.paying_yui_medal_bonus_id) \ + + encode_str(self.title) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) \ + + encode_int(self.reward_yui_medal_num) \ + + encode_str(self.news_id) \ + + encode_int(self.help_id) \ + + encode_int(self.ad_banner_id) + +class AcLoginBonusData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.ac_login_bonus_id = decode_int(data, off) + off += INT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.reward_set_sub_id = decode_int(data, off) + off += INT_OFF + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "AcLoginBonusData": + ret = cls(b"\x00" * 99, 0) + ret.ac_login_bonus_id = data['AcLoginBonusId'] + ret.title = data['Title'] + ret.reward_set_sub_id = data['RewardSetSubId'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.ac_login_bonus_id) \ + + encode_str(self.title) \ + + encode_int(self.reward_set_sub_id) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) + +class PlayCampaignData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.play_campaign_id = decode_int(data, off) + off += INT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.campaign_type = decode_byte(data, off) + off += BYTE_OFF + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.posting_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.posting_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.news_id, new_off = decode_str(data, off) + off += new_off + + self.help_id = decode_int(data, off) + off += INT_OFF + + self.ad_banner_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "PlayCampaignData": + ret = cls(b"\x00" * 99, 0) + ret.play_campaign_id = data['PlayCampaignId'] + ret.title = data['Title'] + ret.campaign_type = data['CampaignType'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + ret.posting_start_date = data['PostingStartDate'] + ret.posting_end_date = data['PostingEndDate'] + ret.news_id = data['NewsId'] + ret.help_id = data['HelpId'] + ret.ad_banner_id = data['AdBannerId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.play_campaign_id) \ + + encode_str(self.title) \ + + encode_byte(self.campaign_type) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) \ + + encode_date_str(self.posting_start_date) \ + + encode_date_str(self.posting_end_date) \ + + encode_str(self.news_id) \ + + encode_int(self.help_id) \ + + encode_int(self.ad_banner_id) + +class PlayCampaignRewardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.play_campaign_reward_id = decode_int(data, off) + off += INT_OFF + + self.play_campaign_id = decode_int(data, off) + off += INT_OFF + + self.product_no = decode_int(data, off) + off += INT_OFF + + self.product_name, new_off = decode_str(data, off) + off += new_off + + self.product_type = decode_byte(data, off) + off += BYTE_OFF + + self.resource_type = decode_byte(data, off) + off += BYTE_OFF + + self.required_credit_num = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self.title_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "PlayCampaignRewardData": + ret = cls(b"\x00" * 99, 0) + ret.play_campaign_reward_id = data['PlayCampaignRewardId'] + ret.play_campaign_id = data['PlayCampaignId'] + ret.product_no = data['ProductNo'] + ret.product_name = data['ProductName'] + ret.product_type = data['ProductType'] + ret.resource_type = data['ResourceType'] + ret.required_credit_num = data['RequiredCreditNum'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + ret.title_id = data['TitleId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.play_campaign_reward_id) \ + + encode_int(self.play_campaign_id) \ + + encode_int(self.product_no) \ + + encode_str(self.product_name) \ + + encode_byte(self.product_type) \ + + encode_byte(self.resource_type) \ + + encode_int(self.required_credit_num) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) \ + + encode_int(self.title_id) + +class GashaFreeCampaignData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.gasha_free_campaign_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.start_date, new_off = decode_date_str(data, off) + off += new_off + + self.end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "GashaFreeCampaignData": + ret = cls(b"\x00" * 99, 0) + ret.gasha_free_campaign_id = data['GashaFreeCampaignId'] + ret.name = data['Name'] + ret.start_date = data['StartDate'] + ret.end_date = data['EndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.gasha_free_campaign_id) \ + + encode_str(self.name) \ + + encode_date_str(self.start_date) \ + + encode_date_str(self.end_date) + +class QuestDropBoostCampaignData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.quest_drop_boost_campaign_id = decode_int(data, off) + off += INT_OFF + + self.name, new_off = decode_str(data, off) + off += new_off + + self.consume_ticket_num = decode_int(data, off) + off += INT_OFF + + self.drop_magnification = decode_byte(data, off) + off += BYTE_OFF + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "QuestDropBoostCampaignData": + ret = cls(b"\x00" * 99, 0) + ret.quest_drop_boost_campaign_id = data['QuestDropBoostCampaignId'] + ret.name = data['Name'] + ret.consume_ticket_num = data['ConsumeTicketNum'] + ret.drop_magnification = data['DropMagnification'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.quest_drop_boost_campaign_id) \ + + encode_str(self.name) \ + + encode_int(self.consume_ticket_num) \ + + encode_byte(self.drop_magnification) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) + +class FirstTicketPurchaseCampaignData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.first_ticket_purchase_campaign_id = decode_int(data, off) + off += INT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.not_target_applying_base_date, new_off = decode_date_str(data, off) + off += new_off + + self.target_ticket_purchase_id_list, new_off = decode_str(data, off) + off += new_off + + self.news_id, new_off = decode_str(data, off) + off += new_off + + self.help_id = decode_int(data, off) + off += INT_OFF + + self.ad_banner_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "FirstTicketPurchaseCampaignData": + ret = cls(b"\x00" * 99, 0) + ret.first_ticket_purchase_campaign_id = data['FirstTicketPurchaseCampaignId'] + ret.title = data['Title'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + ret.not_target_applying_base_date = data['NotTargetApplyingBaseDate'] + ret.target_ticket_purchase_id_list = data['TargetTicketPurchaseIdList'] + ret.news_id = data['NewsId'] + ret.help_id = data['HelpId'] + ret.ad_banner_id = data['AdBannerId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.first_ticket_purchase_campaign_id) \ + + encode_str(self.title) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) \ + + encode_date_str(self.not_target_applying_base_date) \ + + encode_str(self.target_ticket_purchase_id_list) \ + + encode_str(self.news_id) \ + + encode_int(self.help_id) \ + + encode_int(self.ad_banner_id) + +class LinkedSiteRegCampaignsData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.linked_site_reg_campaign_id = decode_int(data, off) + off += INT_OFF + + self.title, new_off = decode_str(data, off) + off += new_off + + self.open_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.open_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.posting_start_date, new_off = decode_date_str(data, off) + off += new_off + + self.posting_end_date, new_off = decode_date_str(data, off) + off += new_off + + self.news_id, new_off = decode_str(data, off) + off += new_off + + self.help_id = decode_int(data, off) + off += INT_OFF + + self.ad_banner_id = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "LinkedSiteRegCampaignsData": + ret = cls(b"\x00" * 99, 0) + ret.linked_site_reg_campaign_id = data['LinkedSiteRegCampaignId'] + ret.title = data['Title'] + ret.open_start_date = data['OpenStartDate'] + ret.open_end_date = data['OpenEndDate'] + ret.posting_start_date = data['PostingStartDate'] + ret.posting_end_date = data['PostingEndDate'] + ret.news_id = data['NewsId'] + ret.help_id = data['HelpId'] + ret.ad_banner_id = data['AdBannerId'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.linked_site_reg_campaign_id) \ + + encode_str(self.title) \ + + encode_date_str(self.open_start_date) \ + + encode_date_str(self.open_end_date) \ + + encode_date_str(self.posting_start_date) \ + + encode_date_str(self.posting_end_date) \ + + encode_str(self.news_id) \ + + encode_int(self.help_id) \ + + encode_int(self.ad_banner_id) + +class LinkedSiteRegCampaignRewardData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.linked_site_reg_campaign_reward_id = decode_int(data, off) + off += INT_OFF + + self.linked_site_reg_campaign_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_type = decode_byte(data, off) + off += BYTE_OFF + + self.common_reward_id = decode_int(data, off) + off += INT_OFF + + self.common_reward_num = decode_short(data, off) + off += SHORT_OFF + + self.strength = decode_int(data, off) + off += INT_OFF + + self.property1_property_id = decode_int(data, off) + off += INT_OFF + + self.property1_value1 = decode_int(data, off) + off += INT_OFF + + self.property1_value2 = decode_int(data, off) + off += INT_OFF + + self.property2_property_id = decode_int(data, off) + off += INT_OFF + + self.property2_value1 = decode_int(data, off) + off += INT_OFF + + self.property2_value2 = decode_int(data, off) + off += INT_OFF + + self.property3_property_id = decode_int(data, off) + off += INT_OFF + + self.property3_value1 = decode_int(data, off) + off += INT_OFF + + self.property3_value2 = decode_int(data, off) + off += INT_OFF + + self.property4_property_id = decode_int(data, off) + off += INT_OFF + + self.property4_value1 = decode_int(data, off) + off += INT_OFF + + self.property4_value2 = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, data: Dict) -> "LinkedSiteRegCampaignRewardData": + ret = cls(b"\x00" * 99, 0) + ret.linked_site_reg_campaign_reward_id = data['LinkedSiteRegCampaignRewardId'] + ret.linked_site_reg_campaign_id = data['LinkedSiteRegCampaignId'] + ret.common_reward_type = data['CommonRewardType'] + ret.common_reward_id = data['CommonRewardId'] + ret.common_reward_num = data['CommonRewardNum'] + ret.strength = data['Strength'] + ret.property1_property_id = data['Property1PropertyId'] + ret.property1_value1 = data['Property1Value1'] + ret.property1_value2 = data['Property1Value2'] + ret.property2_property_id = data['Property2PropertyId'] + ret.property2_value1 = data['Property2Value1'] + ret.property2_value2 = data['Property2Value2'] + ret.property3_property_id = data['Property3PropertyId'] + ret.property3_value1 = data['Property3Value1'] + ret.property3_value2 = data['Property3Value2'] + ret.property4_property_id = data['Property4PropertyId'] + ret.property4_value1 = data['Property4Value1'] + ret.property4_value2 = data['Property4Value2'] + return ret + + def make(self) -> bytes: + return super().make() \ + + encode_int(self.linked_site_reg_campaign_reward_id) \ + + encode_int(self.linked_site_reg_campaign_id) \ + + encode_byte(self.common_reward_type) \ + + encode_int(self.common_reward_id) \ + + encode_short(self.common_reward_num) \ + + encode_int(self.strength) \ + + encode_int(self.property1_property_id) \ + + encode_int(self.property1_value1) \ + + encode_int(self.property1_value2) \ + + encode_int(self.property2_property_id) \ + + encode_int(self.property2_value1) \ + + encode_int(self.property2_value2) \ + + encode_int(self.property3_property_id) \ + + encode_int(self.property3_value1) \ + + encode_int(self.property3_value2) \ + + encode_int(self.property4_property_id) \ + + encode_int(self.property4_value1) \ + + encode_int(self.property4_value2) + +class EpisodeAppendUserData(BaseHelper): + def __init__(self, data: bytes, offset: int): + off = offset + self.user_episode_append_id, new_off = decode_str(data, off) + off += new_off + + self.user_id, new_off = decode_str(data, off) + off += new_off + + self.episode_append_id = decode_int(data, off) + off += INT_OFF + + self.own_num = decode_int(data, off) + off += INT_OFF + + self._sz = off - offset + + @classmethod + def from_args(cls, episode_id: int = 0, user_id: int = 0, episode_append_id: int = 0, own_num: int = 99) -> "EpisodeAppendUserData": + ret = cls(b"\x00" * 996, 0) + ret.user_episode_append_id = episode_id + ret.user_id = user_id + ret.episode_append_id = episode_append_id + ret.own_num = own_num + + def make(self) -> bytes: + return super().make() \ + + encode_str(self.user_episode_append_id) \ + + encode_str(self.user_id) \ + + encode_int(self.episode_append_id) \ + + encode_int(self.own_num) diff --git a/titles/sao/index.py b/titles/sao/index.py index 1f68c43..8a775c6 100644 --- a/titles/sao/index.py +++ b/titles/sao/index.py @@ -1,17 +1,20 @@ from typing import Tuple, Dict, List from starlette.requests import Request -from starlette.responses import Response +from starlette.responses import Response, PlainTextResponse, FileResponse from starlette.routing import Route import yaml import logging, coloredlogs from logging.handlers import TimedRotatingFileHandler from os import path from Crypto.Cipher import Blowfish -from hashlib import md5 +from Crypto.Hash import MD5 import secrets +import traceback +import sys -from core import CoreConfig, Utils +from core import CoreConfig from core.title import BaseServlet +from core.utils import Utils from titles.sao.config import SaoConfig from titles.sao.const import SaoConstants from titles.sao.base import SaoBase @@ -55,13 +58,15 @@ class SaoServlet(BaseServlet): self.static_hash = None if self.game_cfg.hash.verify_hash: - self.static_hash = md5(self.game_cfg.hash.hash_base.encode()).digest() # Greate hashing guys, really validates the data - + self.static_hash = MD5.new(self.game_cfg.hash.hash_base.encode()).digest() # Greate hashing guys, really validates the data + def get_routes(self) -> List[Route]: return [ - Route("/{datecode:int}/proto/if/{category:str}/{endpoint:str}", self.render_POST, methods=['POST']) + Route("/{datecode:int}/proto/if/{category:str}/{endpoint:str}", self.render_POST, methods=['POST']), + Route("/saoresource/{resource_type:str}/{resource_id:int}/{endpoint:str}", self.handle_resource), + Route("/system_status.php", self.render_system_status), ] - + @classmethod def is_game_enabled(cls, game_code: str, core_cfg: CoreConfig, cfg_dir: str) -> bool: game_cfg = SaoConfig() @@ -75,29 +80,25 @@ class SaoServlet(BaseServlet): return False return True - - def get_allnet_info(self, game_code: str, game_ver: int, keychip: str) -> Tuple[str, str]: - port_ssl = Utils.get_title_port_ssl(self.core_cfg) - port_normal = Utils.get_title_port(self.core_cfg) - proto = "http" - port = f":{port_normal}" if port_normal != 80 else "" + def get_allnet_info(self, game_id: str, int_ver: int, serial: str) -> Tuple[str, str]: + if self.core_cfg.server.is_using_proxy: + return (f"https://{self.core_cfg.server.hostname}/", "") - if self.game_cfg.server.use_https: - proto = "https" - port = f":{port_ssl}" if port_ssl != 443 else "" + return (f"http://{self.core_cfg.server.hostname}:{Utils.get_title_port(self.core_cfg)}/", "") - return (f"{proto}://{self.core_cfg.server.hostname}{port}/", "") - - - def get_mucha_info(self, core_cfg: CoreConfig, cfg_dir: str) -> Tuple[bool, str]: + def get_mucha_info(self, core_cfg: CoreConfig, cfg_dir: str) -> Tuple[bool, List[str], List[str]]: if not self.game_cfg.server.enable: return (False, [], []) return (True, SaoConstants.GAME_CDS, SaoConstants.NETID_PREFIX) + async def render_system_status(self, request: Request) -> bytes: + return PlainTextResponse("open") + async def render_POST(self, request: Request) -> bytes: - endpoint = request.path_params.get('endpoint', '') + endpoint = request.path_params['endpoint'] + ip = Utils.get_ip_addr(request) iv = b"" req_raw = await request.body() @@ -122,10 +123,23 @@ class SaoServlet(BaseServlet): else: req_data = req_raw[40:] - handler = getattr(self.base, f"handle_{cmd_str}", self.base.handle_noop) - self.logger.info(f"{endpoint} - {cmd_str} request") - self.logger.debug(f"Request: {req_raw.hex()}") - resp = await handler(req_header, req_data) + self.logger.debug(f"{endpoint} ({cmd_str}) Request from {ip}: {req_raw.hex()}") + handler = getattr(self.base, f"handle_{cmd_str}", None) + if handler is None: + self.logger.info(f"Using Generic handler for {endpoint}") + handler = self.base.handle_noop + + try: + resp = await handler(req_header, req_data, ip) + + except Exception as e: + self.logger.error(f"Error handling {endpoint} - {e}") + tp, val, tb = sys.exc_info() + traceback.print_exception(tp, val, tb, limit=5) + with open("{0}/{1}.log".format(self.core_cfg.server.log_dir, "sao"), "a") as f: + traceback.print_exception(tp, val, tb, limit=5, file=f) + + resp = SaoNoopResponse(req_header.cmd + 1).make() if resp is None: resp = SaoNoopResponse(req_header.cmd + 1).make() @@ -138,7 +152,7 @@ class SaoServlet(BaseServlet): else: self.logger.error(f"Unknown response type {type(resp)}") - return Response() + return SaoNoopResponse(req_header.cmd + 1).make() self.logger.debug(f"Response: {resp.hex()}") @@ -154,6 +168,17 @@ class SaoServlet(BaseServlet): tmp = struct.pack("!I", crypt_data_len) # does it want the length of the encrypted response?? resp = resp[:20] + tmp + iv + data_crypt self.logger.debug(f"Encrypted Response: {resp.hex()}") - - - return Response(resp, media_type="text/html; charset=utf-8") \ No newline at end of file + + return Response(resp) + + async def handle_resource(self, request: Request) -> bytes: + # TODO: better guard against path traversal attacks + resource_type = request.path_params['resource_type'].replace(".\\", "").replace("..\\", "") + resource_id = request.path_params['resource_id'] + endpoint = request.path_params['endpoint'].replace(".\\", "").replace("..\\", "") + req_ip = Utils.get_ip_addr(request) + + self.logger.debug(f"{req_ip} requested {resource_type} id {resource_id} {endpoint}") + if path.exists(f"./titles/sao/data/{resource_type}/{resource_id}/{endpoint}"): + return FileResponse(f"./titles/sao/data/{resource_type}/{resource_id}/{endpoint}") + return Response(status_code=404) diff --git a/titles/sao/read.py b/titles/sao/read.py index 92aad8c..6299bc4 100644 --- a/titles/sao/read.py +++ b/titles/sao/read.py @@ -1,24 +1,16 @@ -from typing import Optional, Dict, List -from os import walk, path -import urllib import csv +from os import path +from typing import Optional, Dict, List -from read import BaseReader from core.config import CoreConfig -from titles.sao.database import SaoData -from titles.sao.const import SaoConstants +from read import BaseReader +from .database import SaoData +from .const import SaoConstants class SaoReader(BaseReader): - def __init__( - self, - config: CoreConfig, - version: int, - bin_arg: Optional[str], - opt_arg: Optional[str], - extra: Optional[str], - ) -> None: - super().__init__(config, version, bin_arg, opt_arg, extra) + def __init__(self, config: CoreConfig, version: int, bin_dir: Optional[str], opt_dir: Optional[str], extra: Optional[str]) -> None: + super().__init__(config, version, bin_dir, opt_dir, extra) self.data = SaoData(config) try: @@ -28,225 +20,207 @@ class SaoReader(BaseReader): except IndexError: self.logger.error(f"Invalid project SAO version {version}") exit(1) - + async def read(self) -> None: if path.exists(self.bin_dir): await self.read_csv(f"{self.bin_dir}") else: self.logger.warn("Directory not found, nothing to import") - + + def load_csv_file(self, file: str) -> List[Dict]: + ret = [] + try: + fullPath = self.bin_dir + "/" if not self.bin_dir.endswith("/") else "" + fullPath += file + with open(fullPath, encoding="UTF-8") as fp: + reader = csv.DictReader(fp) + for row in reader: + tmp = {} + + fkey = list(row.keys())[0] + new_fkey = fkey.replace("// ", "") + fval = row[fkey] + row.pop(fkey) + row[new_fkey] = fval + + for k,v in row.items(): + if v == "-1": + row[k] = None + elif v.isdigit(): + row[k] = int(v) + elif v.isdecimal(): + row[k] = float(v) + elif v == "True": + row[k] = True + elif v == "False": + row[k] = False + ret.append(row) + + except Exception as e: + self.logger.warning(f"Couldn't read csv file {fullPath}, skipping - {e}") + + return ret async def read_csv(self, bin_dir: str) -> None: self.logger.info(f"Read csv from {bin_dir}") self.logger.info("Now reading QuestScene.csv") - try: - fullPath = bin_dir + "/QuestScene.csv" - with open(fullPath, encoding="UTF-8") as fp: - reader = csv.DictReader(fp) - for row in reader: - questSceneId = row["QuestSceneId"] - sortNo = row["SortNo"] - name = row["Name"] - enabled = True + reader = self.load_csv_file("QuestScene.csv") + if reader: + for row in reader: + self.logger.info(f"Adding quest {row['QuestSceneId']}") + await self.data.static.put_quest(row) - self.logger.info(f"Added quest {questSceneId} | Name: {name}") - - try: - await self.data.static.put_quest( - questSceneId, - 0, - sortNo, - name, - enabled - ) - except Exception as err: - self.logger.error(err) - except Exception: - self.logger.warning(f"Couldn't read csv file in {self.bin_dir}, skipping") - - self.logger.info("Now reading HeroLog.csv") - try: - fullPath = bin_dir + "/HeroLog.csv" - with open(fullPath, encoding="UTF-8") as fp: - reader = csv.DictReader(fp) - for row in reader: - heroLogId = row["HeroLogId"] - name = row["Name"] - nickname = row["Nickname"] - rarity = row["Rarity"] - skillTableSubId = row["SkillTableSubId"] - awakeningExp = row["AwakeningExp"] - flavorText = row["FlavorText"] - enabled = True + self.logger.info("Now reading Property.csv") + reader = self.load_csv_file("Property.csv") + if reader: + for row in reader: + self.logger.info(f"Adding property {row['PropertyId']}") + await self.data.static.put_property(row) - self.logger.info(f"Added hero {heroLogId} | Name: {name}") - - try: - await self.data.static.put_hero( - 0, - heroLogId, - name, - nickname, - rarity, - skillTableSubId, - awakeningExp, - flavorText, - enabled - ) - except Exception as err: - self.logger.error(err) - except Exception: - self.logger.warning(f"Couldn't read csv file in {self.bin_dir}, skipping") - self.logger.info("Now reading Equipment.csv") - try: - fullPath = bin_dir + "/Equipment.csv" - with open(fullPath, encoding="UTF-8") as fp: - reader = csv.DictReader(fp) - for row in reader: - equipmentId = row["EquipmentId"] - equipmentType = row["EquipmentType"] - weaponTypeId = row["WeaponTypeId"] - name = row["Name"] - rarity = row["Rarity"] - flavorText = row["FlavorText"] - enabled = True + reader = self.load_csv_file("Equipment.csv") + if reader: + for row in reader: + self.logger.info(f"Adding equipment {row['EquipmentId']}") + await self.data.static.put_equipment(row) - self.logger.info(f"Added equipment {equipmentId} | Name: {name}") - - try: - await self.data.static.put_equipment( - 0, - equipmentId, - name, - equipmentType, - weaponTypeId, - rarity, - flavorText, - enabled - ) - except Exception as err: - self.logger.error(err) - except Exception: - self.logger.warning(f"Couldn't read csv file in {self.bin_dir}, skipping") + self.logger.info("Now reading Skill.csv") + reader = self.load_csv_file("Skill.csv") + if reader: + for row in reader: + self.logger.info(f"Adding skill {row['SkillId']}") + await self.data.static.put_skill(row) + + self.logger.info("Now reading SkillTable.csv") + reader = self.load_csv_file("SkillTable.csv") + if reader: + for row in reader: + self.logger.info(f"Adding skill table {row['SkillId']} | SubId: {row['SkillTableSubId']}") + await self.data.static.put_skill_table(row['SkillId'], row['SkillTableSubId'], row['Level'], row['AwakeningId'], row['SkillTableId']) + + self.logger.info("Now reading HeroLog.csv") + reader = self.load_csv_file("HeroLog.csv") + if reader: + for row in reader: + self.logger.info(f"Adding hero {row['HeroLogId']}") + await self.data.static.put_hero(row) self.logger.info("Now reading Item.csv") - try: - fullPath = bin_dir + "/Item.csv" - with open(fullPath, encoding="UTF-8") as fp: - reader = csv.DictReader(fp) - for row in reader: - itemId = row["ItemId"] - itemTypeId = row["ItemTypeId"] - name = row["Name"] - rarity = row["Rarity"] - flavorText = row["FlavorText"] - enabled = True + reader = self.load_csv_file("Item.csv") + if reader: + for row in reader: + self.logger.info(f"Adding item {row['ItemId']}") + await self.data.static.put_item(row) - self.logger.info(f"Added item {itemId} | Name: {name}") - - try: - await self.data.static.put_item( - 0, - itemId, - name, - itemTypeId, - rarity, - flavorText, - enabled - ) - except Exception as err: - self.logger.error(err) - except Exception: - self.logger.warning(f"Couldn't read csv file in {self.bin_dir}, skipping") - self.logger.info("Now reading SupportLog.csv") - try: - fullPath = bin_dir + "/SupportLog.csv" - with open(fullPath, encoding="UTF-8") as fp: - reader = csv.DictReader(fp) - for row in reader: - supportLogId = row["SupportLogId"] - charaId = row["CharaId"] - name = row["Name"] - rarity = row["Rarity"] - salePrice = row["SalePrice"] - skillName = row["SkillName"] - enabled = True + reader = self.load_csv_file("SupportLog.csv") + if reader: + for row in reader: + supportLogId = row["SupportLogId"] + charaId = row["CharaId"] + name = row["Name"] + rarity = row["Rarity"] + salePrice = row["SalePrice"] + skillName = row["SkillName"] + enabled = True + + self.logger.info(f"Adding support log {supportLogId}") + await self.data.static.put_support_log( + 0, + supportLogId, + charaId, + name, + rarity, + salePrice, + skillName, + enabled + ) - self.logger.info(f"Added support log {supportLogId} | Name: {name}") - - try: - await self.data.static.put_support_log( - 0, - supportLogId, - charaId, - name, - rarity, - salePrice, - skillName, - enabled - ) - except Exception as err: - self.logger.error(err) - except Exception: - self.logger.warning(f"Couldn't read csv file in {self.bin_dir}, skipping") - self.logger.info("Now reading Title.csv") - try: - fullPath = bin_dir + "/Title.csv" - with open(fullPath, encoding="UTF-8") as fp: - reader = csv.DictReader(fp) - for row in reader: - titleId = row["TitleId"] - displayName = row["DisplayName"] - requirement = row["Requirement"] - rank = row["Rank"] - imageFilePath = row["ImageFilePath"] - enabled = True + reader = self.load_csv_file("Title.csv") + if reader: + for row in reader: + titleId = row["TitleId"] + displayName = row["DisplayName"] + requirement = row["Requirement"] + rank = row["Rank"] + imageFilePath = row["ImageFilePath"] + enabled = True - self.logger.info(f"Added title {titleId} | Name: {displayName}") - - if len(titleId) > 5: - try: - await self.data.static.put_title( - 0, - titleId, - displayName, - requirement, - rank, - imageFilePath, - enabled - ) - except Exception as err: - self.logger.error(err) - elif len(titleId) < 6: # current server code cannot have multiple lengths for the id - continue - except Exception: - self.logger.warning(f"Couldn't read csv file in {self.bin_dir}, skipping") + self.logger.info(f"Adding title {titleId}") + await self.data.static.put_title( + 0, + titleId, + displayName, + requirement, + rank, + imageFilePath, + enabled + ) - self.logger.info("Now reading RareDropTable.csv") - try: - fullPath = bin_dir + "/RareDropTable.csv" - with open(fullPath, encoding="UTF-8") as fp: - reader = csv.DictReader(fp) - for row in reader: - questRareDropId = row["QuestRareDropId"] - commonRewardId = row["CommonRewardId"] - enabled = True + self.logger.info("Now reading QuestRareDrop.csv") + reader = self.load_csv_file("QuestRareDrop.csv") + if reader: + for row in reader: + questRareDropId = row["QuestRareDropId"] + commonRewardId = row["CommonRewardId"] + enabled = True - self.logger.info(f"Added rare drop {questRareDropId} | Reward: {commonRewardId}") - - try: - await self.data.static.put_rare_drop( - 0, - questRareDropId, - commonRewardId, - enabled - ) - except Exception as err: - self.logger.error(err) - except Exception: - self.logger.warning(f"Couldn't read csv file in {self.bin_dir}, skipping") + self.logger.info(f"Adding rare drop {questRareDropId} | Reward: {commonRewardId}") + await self.data.static.put_rare_drop( + 0, + questRareDropId, + commonRewardId, + enabled + ) + + self.logger.info("Now reading RewardTable.csv") + reader = self.load_csv_file("RewardTable.csv") + if reader: + for row in reader: + self.logger.info(f"Adding reward table {row['RewardTableId']} | Sub-ID: {row['RewardTableSubId']} | Reward {row['CommonRewardId']}") + await self.data.static.put_reward_table(row) + + self.logger.info("Now reading ExBonusTable.csv") + reader = self.load_csv_file("ExBonusTable.csv") + if reader: + for row in reader: + self.logger.info(f"Adding ex bonus {row['ExBonusTableId']} | Sub-ID: {row['ExBonusTableSubId']} | Reward {row['CommonRewardId']}") + await self.data.static.put_ex_bonus(row) + + self.logger.info("Now reading PlayerTraceTable.csv") + reader = self.load_csv_file("PlayerTraceTable.csv") + if reader: + for row in reader: + self.logger.info(f"Adding trace table {row['PlayerTraceTableId']} | Sub-ID: {row['PlayerTraceTableSubId']} | Reward {row['CommonRewardId']}") + await self.data.static.put_player_trace(row) + + self.logger.info("Now reading Episode.csv") + reader = self.load_csv_file("Episode.csv") + if reader: + for row in reader: + self.logger.info(f"Adding episode {row['EpisodeId']}") + await self.data.static.put_episode(row) + + self.logger.info("Now reading TrialTower.csv") + reader = self.load_csv_file("TrialTower.csv") + if reader: + for row in reader: + self.logger.info(f"Adding tower {row['TrialTowerId']}") + await self.data.static.put_tower(row) + + self.logger.info("Now reading ExTowerQuests.csv") + reader = self.load_csv_file("ExTowerQuests.csv") + if reader: + for row in reader: + self.logger.info(f"Adding ex tower {row['ExTowerQuestId']}") + await self.data.static.put_ex_tower(row) + + self.logger.info("Now reading SideQuest.csv") + reader = self.load_csv_file("SideQuest.csv") + if reader: + for row in reader: + self.logger.info(f"Adding side quest {row['SideQuestId']}") + await self.data.static.put_side_quest(row) diff --git a/titles/sao/schema/item.py b/titles/sao/schema/item.py index 332e135..abadca5 100644 --- a/titles/sao/schema/item.py +++ b/titles/sao/schema/item.py @@ -1,6 +1,6 @@ from typing import Optional, Dict, List from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_, case -from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON +from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON, BOOLEAN, INTEGER, BIGINT from sqlalchemy.schema import ForeignKey from sqlalchemy.sql import func, select, update, delete from sqlalchemy.engine import Row @@ -17,15 +17,30 @@ equipment_data = Table( ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False, ), - Column("equipment_id", Integer, nullable=False), + Column("equipment_id", BIGINT, ForeignKey("sao_static_equipment_list.EquipmentId", ondelete="cascade", onupdate="cascade"), nullable=False), Column("enhancement_value", Integer, nullable=False), Column("enhancement_exp", Integer, nullable=False), Column("awakening_exp", Integer, nullable=False), Column("awakening_stage", Integer, nullable=False), Column("possible_awakening_flag", Integer, nullable=False), + Column("is_shop_purchase", BOOLEAN, nullable=False, server_default="0"), + Column("is_protect", BOOLEAN, nullable=False, server_default="0"), + Column("property1_property_id", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False, server_default="2"), + Column("property1_value1", INTEGER, nullable=False, server_default="0"), + Column("property1_value2", INTEGER, nullable=False, server_default="0"), + Column("property2_property_id", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False, server_default="2"), + Column("property2_value1", INTEGER, nullable=False, server_default="0"), + Column("property2_value2", INTEGER, nullable=False, server_default="0"), + Column("property3_property_id", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False, server_default="2"), + Column("property3_value1", INTEGER, nullable=False, server_default="0"), + Column("property3_value2", INTEGER, nullable=False, server_default="0"), + Column("property4_property_id", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False, server_default="2"), + Column("property4_value1", INTEGER, nullable=False, server_default="0"), + Column("property4_value2", INTEGER, nullable=False, server_default="0"), + Column("converted_card_num", INTEGER, nullable=False, server_default="0"), Column("get_date", TIMESTAMP, nullable=False, server_default=func.now()), UniqueConstraint("user", "equipment_id", name="sao_equipment_data_uk"), - mysql_charset="utf8mb4", + mysql_charset="utf8mb4" ) item_data = Table( @@ -40,7 +55,7 @@ item_data = Table( Column("item_id", Integer, nullable=False), Column("get_date", TIMESTAMP, nullable=False, server_default=func.now()), UniqueConstraint("user", "item_id", name="sao_item_data_uk"), - mysql_charset="utf8mb4", + mysql_charset="utf8mb4" ) hero_log_data = Table( @@ -52,19 +67,38 @@ hero_log_data = Table( ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False, ), - Column("user_hero_log_id", Integer, nullable=False), + Column("hero_log_id", BIGINT, ForeignKey("sao_static_hero_list.HeroLogId", ondelete="cascade", onupdate="cascade"), nullable=False), Column("log_level", Integer, nullable=False), Column("log_exp", Integer, nullable=False), - Column("main_weapon", Integer, nullable=False), - Column("sub_equipment", Integer, nullable=False), - Column("skill_slot1_skill_id", Integer, nullable=False), - Column("skill_slot2_skill_id", Integer, nullable=False), - Column("skill_slot3_skill_id", Integer, nullable=False), - Column("skill_slot4_skill_id", Integer, nullable=False), - Column("skill_slot5_skill_id", Integer, nullable=False), + Column("main_weapon", BIGINT, ForeignKey("sao_equipment_data.id", ondelete="set null", onupdate="set null")), + Column("sub_equipment", BIGINT, ForeignKey("sao_equipment_data.id", ondelete="set null", onupdate="set null")), + Column("skill_slot1_skill_id", BIGINT, ForeignKey("sao_static_skill.SkillId", ondelete="set null", onupdate="set null")), + Column("skill_slot2_skill_id", BIGINT, ForeignKey("sao_static_skill.SkillId", ondelete="set null", onupdate="set null")), + Column("skill_slot3_skill_id", BIGINT, ForeignKey("sao_static_skill.SkillId", ondelete="set null", onupdate="set null")), + Column("skill_slot4_skill_id", BIGINT, ForeignKey("sao_static_skill.SkillId", ondelete="set null", onupdate="set null")), + Column("skill_slot5_skill_id", BIGINT, ForeignKey("sao_static_skill.SkillId", ondelete="set null", onupdate="set null")), + Column("max_level_extend_num", INTEGER, nullable=False, server_default="0"), + Column("is_awakenable", BOOLEAN, nullable=False, server_default="0"), + Column("awakening_stage", INTEGER, nullable=False, server_default="0"), + Column("awakening_exp", INTEGER, nullable=False, server_default="0"), + Column("is_shop_purchase", BOOLEAN, nullable=False, server_default="0"), + Column("is_protect", BOOLEAN, nullable=False, server_default="0"), + Column("property1_property_id", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False, server_default="2"), + Column("property1_value1", INTEGER, nullable=False, server_default="0"), + Column("property1_value2", INTEGER, nullable=False, server_default="0"), + Column("property2_property_id", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False, server_default="2"), + Column("property2_value1", INTEGER, nullable=False, server_default="0"), + Column("property2_value2", INTEGER, nullable=False, server_default="0"), + Column("property3_property_id", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False, server_default="2"), + Column("property3_value1", INTEGER, nullable=False, server_default="0"), + Column("property3_value2", INTEGER, nullable=False, server_default="0"), + Column("property4_property_id", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False, server_default="2"), + Column("property4_value1", INTEGER, nullable=False, server_default="0"), + Column("property4_value2", INTEGER, nullable=False, server_default="0"), + Column("converted_card_num", INTEGER, nullable=False, server_default="0"), Column("get_date", TIMESTAMP, nullable=False, server_default=func.now()), - UniqueConstraint("user", "user_hero_log_id", name="sao_hero_log_data_uk"), - mysql_charset="utf8mb4", + UniqueConstraint("user", "hero_log_id", name="sao_hero_log_data_uk"), + mysql_charset="utf8mb4" ) hero_party = Table( @@ -77,11 +111,11 @@ hero_party = Table( nullable=False, ), Column("user_party_team_id", Integer, nullable=False), - Column("user_hero_log_id_1", Integer, nullable=False), - Column("user_hero_log_id_2", Integer, nullable=False), - Column("user_hero_log_id_3", Integer, nullable=False), + Column("user_hero_log_id_1", Integer, ForeignKey("sao_hero_log_data.id", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("user_hero_log_id_2", Integer, ForeignKey("sao_hero_log_data.id", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("user_hero_log_id_3", Integer, ForeignKey("sao_hero_log_data.id", ondelete="cascade", onupdate="cascade"), nullable=False), UniqueConstraint("user", "user_party_team_id", name="sao_hero_party_uk"), - mysql_charset="utf8mb4", + mysql_charset="utf8mb4" ) quest = Table( @@ -93,15 +127,28 @@ quest = Table( ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False, ), - Column("episode_id", Integer, nullable=False), + Column("quest_type", INTEGER, nullable=False, server_default="1"), + Column("quest_scene_id", BIGINT, ForeignKey("sao_static_quest.QuestSceneId", ondelete="cascade", onupdate="cascade"), nullable=False), Column("quest_clear_flag", Boolean, nullable=False), Column("clear_time", Integer, nullable=False), Column("combo_num", Integer, nullable=False), Column("total_damage", Integer, nullable=False), Column("concurrent_destroying_num", Integer, nullable=False), Column("play_date", TIMESTAMP, nullable=False, server_default=func.now()), - UniqueConstraint("user", "episode_id", name="sao_player_quest_uk"), - mysql_charset="utf8mb4", + UniqueConstraint("user", "quest_scene_id", name="sao_player_quest_uk"), + mysql_charset="utf8mb4" +) + +ex_bonus = Table( + "sao_player_ex_bonus", + metadata, + Column("id", BIGINT, primary_key=True, nullable=False), + Column("user", INTEGER, ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("quest_scene_id", BIGINT, ForeignKey("sao_static_quest.QuestSceneId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("ex_bonus_table_id", BIGINT, ForeignKey("sao_static_ex_bonus.ExBonusTableId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("quest_clear_flag", BOOLEAN, nullable=False, server_default="0"), + UniqueConstraint("user", "quest_scene_id", "ex_bonus_table_id", name="sao_player_ex_bonus_uk"), + mysql_charset="utf8mb4" ) sessions = Table( @@ -114,12 +161,12 @@ sessions = Table( nullable=False, ), Column("user_party_team_id", Integer, nullable=False), - Column("episode_id", Integer, nullable=False), + Column("episode_id", Integer, nullable=False), # TODO: Change to quest scene id Column("play_mode", Integer, nullable=False), Column("quest_drop_boost_apply_flag", Integer, nullable=False), Column("play_date", TIMESTAMP, nullable=False, server_default=func.now()), UniqueConstraint("user", "user_party_team_id", "play_date", name="sao_play_sessions_uk"), - mysql_charset="utf8mb4", + mysql_charset="utf8mb4" ) end_sessions = Table( @@ -135,7 +182,7 @@ end_sessions = Table( Column("play_result_flag", Boolean, nullable=False), Column("reward_data", JSON, nullable=True), Column("play_date", TIMESTAMP, nullable=False, server_default=func.now()), - mysql_charset="utf8mb4", + mysql_charset="utf8mb4" ) class SaoItemData(BaseData): @@ -148,13 +195,17 @@ class SaoItemData(BaseData): quest_drop_boost_apply_flag=quest_drop_boost_apply_flag ) - conflict = sql.on_duplicate_key_update(user=user_id) + conflict = sql.on_duplicate_key_update( + user_party_team_id=user_party_team_id, + episode_id=episode_id, + play_mode=play_mode, + quest_drop_boost_apply_flag=quest_drop_boost_apply_flag + ) result = await self.execute(conflict) - if result is None: - self.logger.error(f"Failed to create SAO session for user {user_id}!") - return None - return result.lastrowid + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to create SAO session for user {user_id}!") async def create_end_session(self, user_id: int, quest_id: int, play_result_flag: bool, reward_data: JSON) -> Optional[int]: sql = insert(end_sessions).values( @@ -164,13 +215,16 @@ class SaoItemData(BaseData): reward_data=reward_data, ) - conflict = sql.on_duplicate_key_update(user=user_id) + conflict = sql.on_duplicate_key_update( + play_result_flag=play_result_flag, + reward_data=reward_data + ) result = await self.execute(conflict) - if result is None: - self.logger.error(f"Failed to create SAO end session for user {user_id}!") - return None - return result.lastrowid + if result: + return result.inserted_primary_key['id'] + + self.logger.error(f"Failed to create SAO end session for user {user_id}!") async def put_item(self, user_id: int, item_id: int) -> Optional[int]: sql = insert(item_data).values( @@ -178,51 +232,93 @@ class SaoItemData(BaseData): item_id=item_id, ) - conflict = sql.on_duplicate_key_update( - item_id=item_id, - ) + conflict = sql.on_duplicate_key_update(item_id=item_id) result = await self.execute(conflict) - if result is None: - self.logger.error( - f"{__name__} failed to insert item! user: {user_id}, item_id: {item_id}" - ) - return None - - return result.lastrowid + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert item! user: {user_id}, item_id: {item_id}") - async def put_equipment_data(self, user_id: int, equipment_id: int, enhancement_value: int, enhancement_exp: int, awakening_exp: int, awakening_stage: int, possible_awakening_flag: int) -> Optional[int]: + async def put_equipment(self, user_id: int, equipment_id: int) -> Optional[int]: sql = insert(equipment_data).values( user=user_id, equipment_id=equipment_id, - enhancement_value=enhancement_value, - enhancement_exp=enhancement_exp, - awakening_exp=awakening_exp, - awakening_stage=awakening_stage, - possible_awakening_flag=possible_awakening_flag, + enhancement_value=1, + enhancement_exp=200, + awakening_exp=0, + awakening_stage=0, + possible_awakening_flag=0, ) - conflict = sql.on_duplicate_key_update( - enhancement_value=enhancement_value, - enhancement_exp=enhancement_exp, - awakening_exp=awakening_exp, - awakening_stage=awakening_stage, - possible_awakening_flag=possible_awakening_flag, - ) + conflict = sql.on_duplicate_key_update(equipment_id=equipment_id) result = await self.execute(conflict) - if result is None: - self.logger.error( - f"{__name__} failed to insert equipment! user: {user_id}, equipment_id: {equipment_id}" - ) - return None + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert equipment! user: {user_id}, equipment_id: {equipment_id}") + + async def put_ex_bonus(self, user_id: int, quest_scene_id: int, ex_bonus_id: int, clear: bool = False) -> Optional[int]: + sql = insert(ex_bonus).values( + user=user_id, + quest_scene_id=quest_scene_id, + ex_bonus_table_id=ex_bonus_id, + quest_clear_flag=clear, + ) - return result.lastrowid + conflict = sql.on_duplicate_key_update(quest_clear_flag=clear) + result = await self.execute(conflict) + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert ex bonus status! user: {user_id}, quest_scene_id: {quest_scene_id}, ex_bonus_id: {ex_bonus_id}, clear: {clear}") + + async def add_equipment_enhancement_exp(self, user_weapon_id: int, enhancement_exp: int) -> None: + result = await self.execute( + equipment_data.update(equipment_data.c.id == user_weapon_id) + .values(enhancement_exp=equipment_data.c.enhancement_exp + enhancement_exp) + ) + if not result: + self.logger.error(f"Failed to give equipment {user_weapon_id} {enhancement_exp} xp!") + + async def get_equipment_enhancement_exp(self, user_weapon_id: int) -> Optional[int]: + result = await self.execute(select(equipment_data.c.enhancement_exp).where(equipment_data.c.id==user_weapon_id)) + if result: + row = result.fetchone() + if row: + return row['enhancement_exp'] + return 0 + self.logger.error(f"Failed to get equipment {user_weapon_id} xp!") + + async def set_equipment_enhancement_value(self, user_equip_id: int, enhancement_val: int) -> None: + result = await self.execute(equipment_data.update(equipment_data.c.id == user_equip_id).values(enhancement_value=enhancement_val)) + if result is None: + self.logger.error(f"Failed to set equipment {user_equip_id} level to {enhancement_val}!") + + async def add_hero_xp(self, user_hero_log_id: int, add_xp: int) -> Optional[int]: + result = await self.execute( + hero_log_data.update(hero_log_data.c.id == user_hero_log_id) + .values(log_exp=hero_log_data.c.log_exp + add_xp) + ) + if not result: + self.logger.error(f"Failed to give hero {user_hero_log_id} {add_xp} xp!") + + async def get_hero_xp(self, user_hero_log_id: int) -> Optional[int]: + result = await self.execute(select(hero_log_data.c.log_exp).where(hero_log_data.c.id==user_hero_log_id)) + if result: + row = result.fetchone() + if row: + return row['log_exp'] + return 0 + self.logger.error(f"Failed to get hero xp for {user_hero_log_id}") + + async def set_hero_level(self, user_hero_log_id: int, new_level: int): + result = await self.execute(hero_log_data.update(hero_log_data.c.id == user_hero_log_id).values(log_level=new_level)) + if result is None: + self.logger.error(f"Failed to set hero {user_hero_log_id} level to {new_level}!") async def put_hero_log(self, user_id: int, user_hero_log_id: int, log_level: int, log_exp: int, main_weapon: int, sub_equipment: int, skill_slot1_skill_id: int, skill_slot2_skill_id: int, skill_slot3_skill_id: int, skill_slot4_skill_id: int, skill_slot5_skill_id: int) -> Optional[int]: sql = insert(hero_log_data).values( user=user_id, - user_hero_log_id=user_hero_log_id, + hero_log_id=user_hero_log_id, log_level=log_level, log_exp=log_exp, main_weapon=main_weapon, @@ -243,17 +339,36 @@ class SaoItemData(BaseData): skill_slot2_skill_id=skill_slot2_skill_id, skill_slot3_skill_id=skill_slot3_skill_id, skill_slot4_skill_id=skill_slot4_skill_id, - skill_slot5_skill_id=skill_slot5_skill_id, + skill_slot5_skill_id=skill_slot5_skill_id ) result = await self.execute(conflict) + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert hero! user: {user_id}, user_hero_log_id: {user_hero_log_id}") + + async def set_user_hero_weapons(self, user_hero_id: int, main_weapon: int, sub_weapon: int) -> None: + sql = hero_log_data.update(hero_log_data.c.id == user_hero_id).values( + main_weapon=main_weapon, + sub_equipment=sub_weapon, + ) + result = await self.execute(sql) if result is None: - self.logger.error( - f"{__name__} failed to insert hero! user: {user_id}, user_hero_log_id: {user_hero_log_id}" - ) + self.logger.error(f"Failed to update user hero {user_hero_id} weapons {main_weapon}/{sub_weapon}") return None - return result.lastrowid + async def set_user_hero_skills(self, user_hero_id: int, skill1: int, skill2: int, skill3: int, skill4: int, skill5: int) -> None: + sql = hero_log_data.update(hero_log_data.c.id == user_hero_id).values( + skill_slot1_skill_id = skill1, + skill_slot2_skill_id = skill2, + skill_slot3_skill_id = skill3, + skill_slot4_skill_id = skill4, + skill_slot5_skill_id = skill5, + ) + result = await self.execute(sql) + if result is None: + self.logger.error(f"Failed to update user hero {user_hero_id} skills {skill1}/{skill2}/{skill3}/{skill4}/{skill5}") + return None async def put_hero_party(self, user_id: int, user_party_team_id: int, user_hero_log_id_1: int, user_hero_log_id_2: int, user_hero_log_id_3: int) -> Optional[int]: sql = insert(hero_party).values( @@ -267,22 +382,19 @@ class SaoItemData(BaseData): conflict = sql.on_duplicate_key_update( user_hero_log_id_1=user_hero_log_id_1, user_hero_log_id_2=user_hero_log_id_2, - user_hero_log_id_3=user_hero_log_id_3, + user_hero_log_id_3=user_hero_log_id_3 ) result = await self.execute(conflict) - if result is None: - self.logger.error( - f"{__name__} failed to insert hero party! user: {user_id}, user_party_team_id: {user_party_team_id}" - ) - return None + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert hero party! user: {user_id}, user_party_team_id: {user_party_team_id}") - return result.lastrowid - - async def put_player_quest(self, user_id: int, episode_id: int, quest_clear_flag: bool, clear_time: int, combo_num: int, total_damage: int, concurrent_destroying_num: int) -> Optional[int]: + async def put_player_quest(self, user_id: int, quest_type: int, quest_scene_id: int, quest_clear_flag: bool, clear_time: int, combo_num: int, total_damage: int, concurrent_destroying_num: int) -> Optional[int]: sql = insert(quest).values( user=user_id, - episode_id=episode_id, + quest_type=quest_type, + quest_scene_id=quest_scene_id, quest_clear_flag=quest_clear_flag, clear_time=clear_time, combo_num=combo_num, @@ -299,13 +411,9 @@ class SaoItemData(BaseData): ) result = await self.execute(conflict) - if result is None: - self.logger.error( - f"{__name__} failed to insert quest! user: {user_id}, episode_id: {episode_id}" - ) - return None - - return result.lastrowid + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert quest! user: {user_id}, quest_scene_id: {quest_scene_id}") async def get_user_equipment(self, user_id: int, equipment_id: int) -> Optional[Dict]: sql = equipment_data.select(equipment_data.c.user == user_id and equipment_data.c.equipment_id == equipment_id) @@ -315,6 +423,14 @@ class SaoItemData(BaseData): return None return result.fetchone() + async def get_user_equipment_by_id(self, equipment_user_id: int) -> Optional[Row]: + sql = equipment_data.select(equipment_data.c.id == equipment_user_id) + + result = await self.execute(sql) + if result is None: + return None + return result.fetchone() + async def get_user_equipments( self, user_id: int ) -> Optional[List[Row]]: @@ -349,6 +465,38 @@ class SaoItemData(BaseData): return None return result.fetchall() + async def get_player_ex_bonus_status(self, user_id: int) -> Optional[List[Row]]: + sql = equipment_data.select(ex_bonus.c.user == user_id) + + result = await self.execute(sql) + if result is None: + return None + return result.fetchall() + + async def get_player_ex_bonus_by_quest(self, user_id: int, quest_scene_id) -> Optional[List[Row]]: + sql = ex_bonus.select(and_(ex_bonus.c.user == user_id, ex_bonus.c.quest_scene_id == quest_scene_id)) + + result = await self.execute(sql) + if result is None: + return None + return result.fetchall() + + async def get_user_item_by_id( + self, user_item_id: int + ) -> Optional[Row]: + sql = item_data.select(item_data.c.id == user_item_id) + + result = await self.execute(sql) + if result is None: + return None + return result.fetchone() + + async def get_user_hero_by_id(self, user_hero_id: int) -> Optional[Row]: + result = await self.execute(hero_log_data.select(hero_log_data.c.id == user_hero_id)) + if result is None: + return None + return result.fetchone() + async def get_hero_log( self, user_id: int, user_hero_log_id: int = None ) -> Optional[List[Row]]: @@ -358,7 +506,7 @@ class SaoItemData(BaseData): sql = hero_log_data.select( and_( hero_log_data.c.user == user_id, - hero_log_data.c.user_hero_log_id == user_hero_log_id if user_hero_log_id is not None else True, + hero_log_data.c.hero_log_id == user_hero_log_id if user_hero_log_id is not None else True, ) ) @@ -366,6 +514,12 @@ class SaoItemData(BaseData): if result is None: return None return result.fetchone() + + async def get_hero_log_by_id(self, user_hero_log_id: int) -> Optional[Row]: + result = await self.execute(hero_log_data.select(hero_log_data.c.id == user_hero_log_id)) + if result is None: + return None + return result.fetchone() async def get_hero_logs( self, user_id: int @@ -373,17 +527,17 @@ class SaoItemData(BaseData): """ A catch-all hero lookup given a profile """ - sql = hero_log_data.select( - and_( - hero_log_data.c.user == user_id, - ) - ) - - result = await self.execute(sql) + result = await self.execute(hero_log_data.select(hero_log_data.c.user == user_id)) if result is None: return None return result.fetchall() + async def get_hero_party_by_id(self, party_id: int) -> Optional[Row]: + result = await self.execute(hero_party.select(hero_party.c.id == party_id)) + if result is None: + return None + return result.fetchone() + async def get_hero_party( self, user_id: int, user_party_team_id: int = None ) -> Optional[List[Row]]: @@ -397,18 +551,18 @@ class SaoItemData(BaseData): result = await self.execute(sql) if result is None: return None - return result.fetchone() + return result.fetchall() async def get_quest_log( - self, user_id: int, episode_id: int = None - ) -> Optional[List[Row]]: + self, user_id: int, quest_scene_id: int + ) -> Optional[Row]: """ - A catch-all quest lookup given a profile and episode_id + A catch-all quest lookup given a profile and quest_scene_id """ sql = quest.select( and_( quest.c.user == user_id, - quest.c.episode_id == episode_id if episode_id is not None else True, + quest.c.quest_scene_id == quest_scene_id ) ) @@ -420,16 +574,7 @@ class SaoItemData(BaseData): async def get_quest_logs( self, user_id: int ) -> Optional[List[Row]]: - """ - A catch-all quest lookup given a profile - """ - sql = quest.select( - and_( - quest.c.user == user_id, - ) - ) - - result = await self.execute(sql) + result = await self.execute(quest.select(quest.c.user == user_id)) if result is None: return None return result.fetchall() @@ -437,13 +582,7 @@ class SaoItemData(BaseData): async def get_session( self, user_id: int = None ) -> Optional[List[Row]]: - sql = sessions.select( - and_( - sessions.c.user == user_id, - ) - ).order_by( - sessions.c.play_date.asc() - ) + sql = sessions.select(sessions.c.user == user_id).order_by(sessions.c.play_date.desc()) result = await self.execute(sql) if result is None: @@ -453,54 +592,36 @@ class SaoItemData(BaseData): async def get_end_session( self, user_id: int = None ) -> Optional[List[Row]]: - sql = end_sessions.select( - and_( - end_sessions.c.user == user_id, - ) - ).order_by( - end_sessions.c.play_date.desc() - ) + sql = end_sessions.select(end_sessions.c.user == user_id).order_by(end_sessions.c.play_date.desc()) result = await self.execute(sql) if result is None: return None return result.fetchone() - - async def remove_hero_log(self, user_id: int, user_hero_log_id: int) -> None: - sql = hero_log_data.delete( - and_( - hero_log_data.c.user == user_id, - hero_log_data.c.user_hero_log_id == user_hero_log_id, - ) - ) + + async def remove_end_session(self, end_id: int) -> None: + result = await self.execute(end_sessions.delete(end_sessions.c.id == end_id)) + if result is None: + self.logger.error(f"Failed to delete end session {end_id}") + + async def remove_hero_log(self, user_hero_log_id: int) -> None: + sql = hero_log_data.delete(hero_log_data.c.id == user_hero_log_id) result = await self.execute(sql) - if result is None: - self.logger.error( - f"{__name__} failed to remove hero log! profile: {user_id}, user_hero_log_id: {user_hero_log_id}" - ) - return None + if not result: + self.logger.error(f"Failed to remove hero log id: {user_hero_log_id}") - async def remove_equipment(self, user_id: int, equipment_id: int) -> None: - sql = equipment_data.delete( - and_(equipment_data.c.user == user_id, equipment_data.c.equipment_id == equipment_id) - ) + async def remove_equipment(self, equipment_id: int) -> None: + sql = equipment_data.delete(equipment_data.c.id == equipment_id) result = await self.execute(sql) - if result is None: - self.logger.error( - f"{__name__} failed to remove equipment! profile: {user_id}, equipment_id: {equipment_id}" - ) - return None + if not result: + self.logger.error(f"Failed to remove equipment id {equipment_id}") - async def remove_item(self, user_id: int, item_id: int) -> None: - sql = item_data.delete( - and_(item_data.c.user == user_id, item_data.c.item_id == item_id) - ) + async def remove_item(self, user_item_id: int) -> None: + sql = item_data.delete(item_data.c.id == user_item_id) result = await self.execute(sql) - if result is None: - self.logger.error( - f"{__name__} failed to remove item! profile: {user_id}, item_id: {item_id}" - ) - return None \ No newline at end of file + if not result: + self.logger.error(f"Failed to remove item {user_item_id}!") + diff --git a/titles/sao/schema/profile.py b/titles/sao/schema/profile.py index 27d284d..4a6df93 100644 --- a/titles/sao/schema/profile.py +++ b/titles/sao/schema/profile.py @@ -1,13 +1,12 @@ -from typing import Optional, Dict, List +from typing import Optional, Tuple, List from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_, case -from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON +from sqlalchemy.types import Integer, String, BOOLEAN, INTEGER, BIGINT, VARCHAR, TIMESTAMP from sqlalchemy.schema import ForeignKey -from sqlalchemy.sql import func, select, update, delete +from sqlalchemy.sql import func, select from sqlalchemy.engine import Row from sqlalchemy.dialects.mysql import insert from core.data.schema import BaseData, metadata -from ..const import SaoConstants profile = Table( "sao_profile", @@ -24,9 +23,70 @@ profile = Table( Column("rank_num", Integer, server_default="1"), Column("rank_exp", Integer, server_default="0"), Column("own_col", Integer, server_default="0"), - Column("own_vp", Integer, server_default="300"), + Column("own_vp", Integer, server_default="0"), Column("own_yui_medal", Integer, server_default="0"), Column("setting_title_id", Integer, server_default="20005"), + Column("my_shop", INTEGER), + Column("fav_hero", INTEGER, ForeignKey("sao_hero_log_data.id", ondelete="set null", onupdate="cascade")), + Column("when_register", TIMESTAMP, server_default=func.now()), + Column("last_login_date", TIMESTAMP), + Column("last_yui_medal_date", TIMESTAMP), + Column("last_bonus_yui_medal_date", TIMESTAMP), + Column("last_comeback_date", TIMESTAMP), + Column("last_login_bonus_date", TIMESTAMP), + Column("ad_confirm_date", TIMESTAMP), + Column("login_ct", INTEGER, server_default="0"), + mysql_charset="utf8mb4" +) + +beginner_mission = Table( + "sao_player_beginner_mission", + metadata, + Column("id", BIGINT, primary_key=True, nullable=False), + Column("user", INTEGER, ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False, unique=True), + Column("beginner_mission_id", INTEGER, nullable=False), + Column("condition_id", INTEGER, nullable=False), + Column("is_seat", BOOLEAN, nullable=False, server_default="0"), + Column("achievement_num", INTEGER, nullable=False), + Column("complete_flag", BOOLEAN, nullable=False, server_default="0"), + Column("complete_date", TIMESTAMP), + Column("reward_received_flag", BOOLEAN, nullable=False, server_default="0"), + Column("reward_received_date", TIMESTAMP), + UniqueConstraint("user", "condition_id", name="sao_player_beginner_mission_uk"), + mysql_charset="utf8mb4" +) + +resource_card = Table( + "sao_player_resource_card", + metadata, + Column("id", BIGINT, primary_key=True, nullable=False), + Column("user", INTEGER, ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("common_reward_type", INTEGER, nullable=False), + Column("common_reward_id", INTEGER, nullable=False), + Column("holographic_flag", BOOLEAN, nullable=False, server_default="0"), + Column("serial", VARCHAR(20), unique=True), + mysql_charset="utf8mb4" +) + +hero_card = Table( + "sao_player_hero_card", + metadata, + Column("id", BIGINT, primary_key=True, nullable=False), + Column("user", INTEGER, ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("user_hero_id", INTEGER, ForeignKey("sao_hero_log_data.id", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("holographic_flag", BOOLEAN, nullable=False, server_default="0"), + Column("serial", VARCHAR(20), unique=True), + mysql_charset="utf8mb4" +) + +tutorial = Table( + "sao_player_tutorial", + metadata, + Column("id", BIGINT, primary_key=True, nullable=False), + Column("user", INTEGER, ForeignKey("aime_user.id", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("tutorial_byte", INTEGER, nullable=False), + UniqueConstraint("user", "tutorial_byte", name="sao_player_tutorial_uk"), + mysql_charset="utf8mb4" ) class SaoProfileData(BaseData): @@ -35,10 +95,81 @@ class SaoProfileData(BaseData): conflict = sql.on_duplicate_key_update(user=user_id) result = await self.execute(conflict) + if result: + return result.inserted_primary_key['id'] + self.logger.error("Failed to create SAO profile!") + + async def set_my_shop(self, user_id: int, store_id: int): + result = await self.execute(profile.update(profile.c.user == user_id).values(my_shop = store_id)) if result is None: - self.logger.error(f"Failed to create SAO profile for user {user_id}!") - return None - return result.lastrowid + self.logger.error(f"Failed to set my shop for user {user_id} to {store_id}!") + + async def user_login(self, user_id: int) -> Optional[Row]: + sql = profile.update(profile.c.user == user_id).values( + login_ct=profile.c.login_ct + 1, + last_login_date=func.now() + ) + result = await self.execute(sql) + if result: + return result.last_updated_params() + self.logger.error(f"Failed to create log in user {user_id}!") + + async def update_yui_medal_date(self, user_id: int) -> None: + sql = profile.update(profile.c.user == user_id).values( + last_yui_medal_date=func.now() + ) + result = await self.execute(sql) + if result is None: + self.logger.error(f"Failed to update user {user_id} yui medal date!") + + async def add_yui_medals(self, user_id: int, num_medals: int = 1): + sql = profile.update(profile.c.user == user_id).values( + own_yui_medal=profile.c.own_yui_medal + num_medals + ) + result = await self.execute(sql) + if result is None: + self.logger.error(f"Failed to give user {user_id} {num_medals} yui medals!") + + async def add_col(self, user_id: int, num_col: int) -> None: + sql = profile.update(profile.c.user == user_id).values( + own_col=profile.c.own_col + num_col + ) + result = await self.execute(sql) + if not result: + self.logger.error(f"Failed to give user {user_id} {num_col} Col!") + + async def add_vp(self, user_id: int, num_vp: int) -> None: + sql = profile.update(profile.c.user == user_id).values( + own_vp=profile.c.own_vp + num_vp + ) + result = await self.execute(sql) + if not result: + self.logger.error(f"Failed to give user {user_id} {num_vp} VP!") + + async def add_exp(self, user_id: int, xp_ammount: int) -> Optional[int]: + sql = profile.update(profile.c.user == user_id).values( + rank_exp=profile.c.rank_exp + xp_ammount + ) + result = await self.execute(sql) + if not result: + self.logger.error(f"Failed to give user {user_id} {xp_ammount} xp!") + + async def get_exp(self, user_id: int) -> Optional[int]: + result = await self.execute(select(profile.c.rank_exp).where(profile.c.user==user_id)) + if result: + row = result.fetchone() + if row: + return row['rank_exp'] + return 0 + self.logger.error(f"Failed to query rank xp for user {user_id}") + + async def set_level(self, user_id: int, level: int): + sql = profile.update(profile.c.user == user_id).values( + rank_num=level + ) + result = await self.execute(sql) + if result is None: + self.logger.error(f"Failed to set user {user_id} level to {level}!") async def put_profile(self, user_id: int, user_type: int, nick_name: str, rank_num: int, rank_exp: int, own_col: int, own_vp: int, own_yui_medal: int, setting_title_id: int) -> Optional[int]: sql = insert(profile).values( @@ -63,17 +194,118 @@ class SaoProfileData(BaseData): ) result = await self.execute(conflict) - if result is None: - self.logger.error( - f"{__name__} failed to insert profile! user: {user_id}" - ) - return None - - return result.lastrowid + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert profile! user: {user_id}") async def get_profile(self, user_id: int) -> Optional[Row]: sql = profile.select(profile.c.user == user_id) result = await self.execute(sql) if result is None: return None - return result.fetchone() \ No newline at end of file + return result.fetchone() + + async def set_profile_name(self, user_id: int, new_name: str) -> None: + sql = profile.update(profile.c.user == user_id).values( + nick_name=new_name + ) + result = await self.execute(sql) + if result is None: + self.logger.error(f"Failed to update nickname {new_name} for user {user_id}") + + async def add_tutorial_byte(self, user_id: int, tutorial_byte: int) -> None: + sql = insert(tutorial).values( + user = user_id, + tutorial_byte = tutorial_byte + ) + + conflict = sql.on_duplicate_key_update(tutorial_byte = tutorial_byte) + result = await self.execute(conflict) + if result is None: + self.logger.error(f"Failed to add tutorial byte {tutorial_byte} to user {user_id}") + + async def get_tutorial_bytes(self, user_id: int) -> Optional[List[Row]]: + sql = tutorial.select(tutorial.c.user == user_id) + + result = await self.execute(sql) + if result is None: + return None + return result.fetchall() + + async def put_hero_card(self, user_id: int, serial: str, user_hero_id: int, is_holo: bool) -> Optional[int]: + sql = insert(hero_card).values( + user=user_id, + user_hero_id=user_hero_id, + holographic_flag=is_holo, + serial=serial + ) + + conflict = sql.on_duplicate_key_update( + holographic_flag=is_holo, + serial=serial + ) + result = await self.execute(conflict) + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert card {serial} for user {user_id} as hero {user_hero_id}") + + async def get_hero_card(self, serial: str) -> Optional[Row]: + result = await self.execute(hero_card.select(hero_card.c.serial == serial)) + if result is None: + return None + return result.fetchone() + + async def put_resource_card(self, user_id: int, serial: str, reward_type: int, reward_id: int, is_holo: bool) -> Optional[int]: + sql = insert(resource_card).values( + user=user_id, + common_reward_type=reward_type, + common_reward_id=reward_id, + holographic_flag=is_holo, + serial=serial + ) + + conflict = sql.on_duplicate_key_update( + holographic_flag=is_holo, + serial=serial + ) + result = await self.execute(conflict) + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert card {serial} for user {user_id} as resource {reward_id}") + + async def get_resource_card(self, serial: str) -> Optional[int]: + result = await self.execute(resource_card.select(resource_card.c.serial == serial)) + if result is None: + return None + return result.fetchone() + + async def update_beginner_mission_date(self, user_id: int) -> None: + sql = profile.update(profile.c.user == user_id).values( + ad_confirm_date=func.now() + ) + result = await self.execute(sql) + if result is None: + self.logger.error(f"Failed to update user {user_id} yui medal date!") + + async def put_beginner_mission(self, user_id: int, beginner_mission_id: int, condition_id: int, is_seat: bool, achievement_num: int) -> Optional[int]: + pass + + async def complete_beginner_mission(self, user_id: int, condition_id: int) -> None: + pass + + async def reward_beginner_mission(self, user_id: int, condition_id: int) -> None: + pass + + async def get_beginner_missions(self, user_id: int) -> Optional[List[Row]]: + pass + + async def get_beginner_missions_by_mission_id(self, user_id: int, beginner_mission_id: int) -> Optional[List[Row]]: + pass + + async def get_beginner_mission(self, user_id: int, condition_id: int) -> Optional[Row]: + pass + + async def set_title(self, user_id: int, title_id: int) -> None: + result = await self.execute(profile.update(profile.c.user == user_id).values(setting_title_id=title_id)) + if not result: + self.logger.error(f"Failed to set user {user_id} title to {title_id}") diff --git a/titles/sao/schema/static.py b/titles/sao/schema/static.py index 8b5b1a1..7f4f679 100644 --- a/titles/sao/schema/static.py +++ b/titles/sao/schema/static.py @@ -1,81 +1,193 @@ -from typing import Dict, List, Optional -from sqlalchemy import Table, Column, UniqueConstraint, PrimaryKeyConstraint, and_ -from sqlalchemy.types import Integer, String, TIMESTAMP, Boolean, JSON, Float -from sqlalchemy.engine.base import Connection +from typing import Dict, List, Optional, Union +from sqlalchemy import Table, Column, UniqueConstraint, ForeignKey +from sqlalchemy.types import Integer, String, BIGINT, Boolean, INTEGER, VARCHAR, BOOLEAN, DECIMAL from sqlalchemy.engine import Row from sqlalchemy.schema import ForeignKey -from sqlalchemy.sql import func, select from sqlalchemy.dialects.mysql import insert from core.data.schema import BaseData, metadata +from core.data import cached quest = Table( "sao_static_quest", metadata, - Column("id", Integer, primary_key=True, nullable=False), - Column("version", Integer), - Column("questSceneId", Integer), - Column("sortNo", Integer), - Column("name", String(255)), - Column("enabled", Boolean), - UniqueConstraint( - "version", "questSceneId", name="sao_static_quest_uk" - ), - mysql_charset="utf8mb4", + Column("QuestSceneId", BIGINT, primary_key=True, nullable=False), + Column("SortNo", INTEGER, nullable=False), + Column("Tutorial", BOOLEAN, nullable=False), + Column("ColRate", DECIMAL, nullable=False), + Column("LimitDefault", INTEGER, nullable=False), + Column("LimitResurrection", INTEGER, nullable=False), + Column("RewardTableSubId", INTEGER, nullable=False), + Column("PlayerTraceTableSubId", INTEGER, nullable=False), + Column("SuccessPlayerExp", INTEGER, nullable=False), + Column("FailedPlayerExp", INTEGER, nullable=False), + Column("PairExpRate", INTEGER, nullable=False), + Column("TrioExpRate", INTEGER, nullable=False), + Column("SingleRewardVp", INTEGER, nullable=False), + Column("PairRewardVp", INTEGER, nullable=False), + Column("TrioRewardVp", INTEGER, nullable=False), + mysql_charset="utf8mb4" ) -hero = Table( - "sao_static_hero_list", +prop = Table( + "sao_static_property", metadata, - Column("id", Integer, primary_key=True, nullable=False), - Column("version", Integer), - Column("heroLogId", Integer), - Column("name", String(255)), - Column("nickname", String(255)), - Column("rarity", Integer), - Column("skillTableSubId", Integer), - Column("awakeningExp", Integer), - Column("flavorText", String(255)), - Column("enabled", Boolean), - UniqueConstraint( - "version", "heroLogId", name="sao_static_hero_list_uk" - ), - mysql_charset="utf8mb4", + Column("PropertyId", BIGINT, primary_key=True, nullable=False), + Column("PropertyTargetType", INTEGER, nullable=False), + Column("PropertyName", VARCHAR(255), nullable=False), + Column("PropertyName_en", VARCHAR(255)), + Column("PropertyNameFormat", VARCHAR(255), nullable=False), + Column("PropertyNameFormat_en", VARCHAR(255)), + Column("PropertyTypeId", INTEGER, nullable=False), + Column("Value1Min", INTEGER, nullable=False), + Column("Value1Max", INTEGER, nullable=False), + Column("Value2Min", INTEGER, nullable=False), + Column("Value2Max", INTEGER, nullable=False), + mysql_charset="utf8mb4" +) + +player_trace = Table( + "sao_static_trace_table", + metadata, + Column("PlayerTraceTableId", BIGINT, primary_key=True, nullable=False), + Column("PlayerTraceTableSubId", INTEGER, nullable=False), + Column("CommonRewardType", INTEGER, nullable=False), + Column("CommonRewardId", INTEGER, nullable=False), + Column("CommonRewardNum", INTEGER, nullable=False), + Column("Rate", INTEGER, nullable=False), + mysql_charset="utf8mb4" +) + +skill = Table( + "sao_static_skill", + metadata, + Column("SkillId", BIGINT, nullable=False, primary_key=True), + Column("WeaponTypeId", INTEGER, nullable=False), + Column("Name", VARCHAR(255), nullable=False), + Column("Name_en", VARCHAR(255)), + Column("Attack", BOOLEAN, nullable=False), + Column("Passive", BOOLEAN, nullable=False), + Column("Pet", BOOLEAN, nullable=False), + Column("Level", INTEGER, nullable=False), + Column("SkillCondition", INTEGER, nullable=False), + Column("CoolTime", INTEGER, nullable=False), + Column("SkillIcon", VARCHAR(255), nullable=False), + Column("FriendSkillIcon", VARCHAR(255), nullable=False), + Column("InfoText", VARCHAR(255), nullable=False), + Column("InfoText_en", VARCHAR(255)), + mysql_charset="utf8mb4" +) + +skill_table = Table( + "sao_static_skill_table", + metadata, + Column("SkillTableId", BIGINT, nullable=False, primary_key=True), + Column("SkillId", BIGINT, ForeignKey("sao_static_skill.SkillId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("SkillTableSubId", INTEGER, nullable=False), + Column("LevelObtained", INTEGER, nullable=False), # Level + Column("AwakeningId", INTEGER, nullable=False), + mysql_charset="utf8mb4" ) equipment = Table( "sao_static_equipment_list", metadata, - Column("id", Integer, primary_key=True, nullable=False), - Column("version", Integer), - Column("equipmentId", Integer), - Column("equipmentType", Integer), - Column("weaponTypeId", Integer), - Column("name", String(255)), - Column("rarity", Integer), - Column("flavorText", String(255)), - Column("enabled", Boolean), - UniqueConstraint( - "version", "equipmentId", name="sao_static_equipment_list_uk" - ), - mysql_charset="utf8mb4", + Column("EquipmentId", BIGINT, primary_key=True, nullable=False), + Column("EquipmentType", INTEGER, nullable=False), + Column("WeaponTypeId", INTEGER, nullable=False), + Column("Name", VARCHAR(255), nullable=False), + Column("Name_en", VARCHAR(255)), + Column("Rarity", INTEGER, nullable=False), + Column("Power", INTEGER, nullable=False), + Column("StrengthIncrement", INTEGER, nullable=False), + Column("SkillCondition", INTEGER, nullable=False), + Column("Property1PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property1Value1", INTEGER, nullable=False), + Column("Property1Value2", INTEGER, nullable=False), + Column("Property2PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property2Value1", INTEGER, nullable=False), + Column("Property2Value2", INTEGER, nullable=False), + Column("Property3PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property3Value1", INTEGER, nullable=False), + Column("Property3Value2", INTEGER, nullable=False), + Column("Property4PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property4Value1", INTEGER, nullable=False), + Column("Property4Value2", INTEGER, nullable=False), + Column("SalePrice", INTEGER, nullable=False), + Column("CompositionExp", INTEGER, nullable=False), + Column("AwakeningExp", INTEGER, nullable=False), + Column("FlavorText", VARCHAR(255), nullable=False), + Column("FlavorText_en", VARCHAR(255)), + mysql_charset="utf8mb4" +) + +hero = Table( + "sao_static_hero_list", + metadata, + Column("HeroLogId", BIGINT, primary_key=True, nullable=False), + Column("CharaId", INTEGER, nullable=False), + Column("Name", VARCHAR(255), nullable=False), + Column("Nickname", VARCHAR(255), nullable=False), + Column("Name_en", VARCHAR(255)), + Column("Nickname_en", VARCHAR(255)), + Column("Rarity", INTEGER, nullable=False), + Column("WeaponTypeId", INTEGER, nullable=False), + Column("HeroLogRoleId", INTEGER, nullable=False), + Column("CostumeTypeId", INTEGER, nullable=False), + Column("UnitId", INTEGER, nullable=False), + Column("DefaultEquipmentId1", BIGINT, ForeignKey("sao_static_equipment_list.EquipmentId", ondelete="cascade", onupdate="cascade")), + Column("DefaultEquipmentId2", BIGINT, ForeignKey("sao_static_equipment_list.EquipmentId", ondelete="cascade", onupdate="cascade")), + Column("SkillTableSubId", INTEGER, nullable=False), + Column("HpMin", INTEGER, nullable=False), + Column("HpMax", INTEGER, nullable=False), + Column("StrMin", INTEGER, nullable=False), + Column("StrMax", INTEGER, nullable=False), + Column("VitMin", INTEGER, nullable=False), + Column("VitMax", INTEGER, nullable=False), + Column("IntMin", INTEGER, nullable=False), + Column("IntMax", INTEGER, nullable=False), + Column("Property1PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property1Value1", INTEGER, nullable=False), + Column("Property1Value2", INTEGER, nullable=False), + Column("Property2PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property2Value1", INTEGER, nullable=False), + Column("Property2Value2", INTEGER, nullable=False), + Column("Property3PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property3Value1", INTEGER, nullable=False), + Column("Property3Value2", INTEGER, nullable=False), + Column("Property4PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property4Value1", INTEGER, nullable=False), + Column("Property4Value2", INTEGER, nullable=False), + Column("FlavorText", VARCHAR(255), nullable=False), + Column("FlavorText_en", VARCHAR(255)), + Column("SalePrice", INTEGER, nullable=False), + Column("CompositionExp", INTEGER, nullable=False), + Column("AwakeningExp", INTEGER, nullable=False), + Column("Slot4UnlockLevel", INTEGER, nullable=False), + Column("Slot5UnlockLevel", INTEGER, nullable=False), + Column("CollectionEmptyFrameDisplayFlag", BOOLEAN, nullable=False), + mysql_charset="utf8mb4" ) item = Table( "sao_static_item_list", metadata, - Column("id", Integer, primary_key=True, nullable=False), - Column("version", Integer), - Column("itemId", Integer), - Column("itemTypeId", Integer), - Column("name", String(255)), - Column("rarity", Integer), - Column("flavorText", String(255)), - Column("enabled", Boolean), - UniqueConstraint( - "version", "itemId", name="sao_static_item_list_uk" - ), - mysql_charset="utf8mb4", + Column("ItemId", INTEGER, nullable=False, primary_key=True), + Column("ItemTypeId", INTEGER, nullable=False), + Column("Name", VARCHAR(255), nullable=False), + Column("Name_en", VARCHAR(255)), + Column("Rarity", INTEGER, nullable=False), + Column("Value", INTEGER, nullable=False), + Column("PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("PropertyValue1Min", INTEGER, nullable=False), + Column("PropertyValue1Max", INTEGER, nullable=False), + Column("PropertyValue2Min", INTEGER, nullable=False), + Column("PropertyValue2Max", INTEGER, nullable=False), + Column("FlavorText", VARCHAR(255), nullable=False), + Column("FlavorText_en", VARCHAR(255)), + Column("SalePrice", INTEGER, nullable=False), + Column("ItemIcon", VARCHAR(255), nullable=False), + mysql_charset="utf8mb4" ) support = Table( @@ -93,7 +205,7 @@ support = Table( UniqueConstraint( "version", "supportLogId", name="sao_static_support_log_list_uk" ), - mysql_charset="utf8mb4", + mysql_charset="utf8mb4" ) rare_drop = Table( @@ -107,7 +219,7 @@ rare_drop = Table( UniqueConstraint( "version", "questRareDropId", "commonRewardId", name="sao_static_rare_drop_list_uk" ), - mysql_charset="utf8mb4", + mysql_charset="utf8mb4" ) title = Table( @@ -124,91 +236,361 @@ title = Table( UniqueConstraint( "version", "titleId", name="sao_static_title_list_uk" ), - mysql_charset="utf8mb4", + mysql_charset="utf8mb4" +) + +reward = Table( + "sao_static_reward", + metadata, + Column("RewardTableId", BIGINT, primary_key=True, nullable=False), + Column("RewardTableSubId", INTEGER, nullable=False), + Column("UnanalyzedLogGradeId", INTEGER, nullable=False), + Column("CommonRewardType", INTEGER, nullable=False), + Column("CommonRewardId", INTEGER, nullable=False), + Column("CommonRewardNum", INTEGER, nullable=False), + Column("StrengthMin", INTEGER, nullable=False), + Column("StrengthMax", INTEGER, nullable=False), + Column("PropertyTableSubId", INTEGER, nullable=False), + Column("QuestInfoDisplayFlag", BOOLEAN, nullable=False), + Column("Rate", INTEGER, nullable=False), + mysql_charset="utf8mb4" +) + +ex_bonus = Table( + "sao_static_ex_bonus", + metadata, + Column("ExBonusTableId", BIGINT, primary_key=True, nullable=False), + Column("ExBonusTableSubId", INTEGER, nullable=False), + Column("ExBonusConditionId", INTEGER, nullable=False), + Column("ConditionValue1", INTEGER, nullable=False), + Column("ConditionValue2", INTEGER, nullable=False), + Column("CommonRewardType", INTEGER, nullable=False), + Column("CommonRewardId", INTEGER, nullable=False), + Column("CommonRewardNum", INTEGER, nullable=False), + Column("Strength", INTEGER, nullable=False), + Column("Property1PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property1Value1", INTEGER, nullable=False), + Column("Property1Value2", INTEGER, nullable=False), + Column("Property2PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property2Value1", INTEGER, nullable=False), + Column("Property2Value2", INTEGER, nullable=False), + Column("Property3PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property3Value1", INTEGER, nullable=False), + Column("Property3Value2", INTEGER, nullable=False), + Column("Property4PropertyId", BIGINT, ForeignKey("sao_static_property.PropertyId", ondelete="cascade", onupdate="cascade"), nullable=False), + Column("Property4Value1", INTEGER, nullable=False), + Column("Property4Value2", INTEGER, nullable=False), + mysql_charset="utf8mb4" +) + +episode = Table( + "sao_static_episode", + metadata, + Column("EpisodeId", BIGINT, nullable=False, primary_key=True), + Column("EpisodeChapterId", INTEGER, nullable=False), + Column("ReleaseEpisodeId", INTEGER, nullable=False), + Column("Title", VARCHAR(255), nullable=False), + Column("CommentSummary", VARCHAR(255), nullable=False), + Column("ExBonusTableSubId", INTEGER, nullable=False), + Column("QuestSceneId", BIGINT, ForeignKey("sao_static_quest.QuestSceneId", ondelete="cascade", onupdate="cascade")), + mysql_charset="utf8mb4" +) + +tower = Table( + "sao_static_tower", + metadata, + Column("TowerId", BIGINT, nullable=False, primary_key=True), + Column("ReleaseTowerId", INTEGER, nullable=False), + Column("ExBonusTableSubId", INTEGER, nullable=False), + Column("QuestSceneId", BIGINT, ForeignKey("sao_static_quest.QuestSceneId", ondelete="cascade", onupdate="cascade"), nullable=False), + mysql_charset="utf8mb4" +) + +ex_tower = Table( + "sao_static_ex_tower", + metadata, + Column("ExTowerQuestId", BIGINT, nullable=False, primary_key=True), + Column("ExTowerId", INTEGER, nullable=False), + Column("ReleaseExTowerQuestId", INTEGER, nullable=False), + Column("Title", VARCHAR(255), nullable=False), + Column("Title_en", VARCHAR(255)), + Column("ExBonusTableSubId", INTEGER, nullable=False), + Column("QuestSceneId", BIGINT, ForeignKey("sao_static_quest.QuestSceneId", ondelete="cascade", onupdate="cascade"), nullable=False), + mysql_charset="utf8mb4" +) + +side_quest = Table( + "sao_static_side_quest", + metadata, + Column("SideQuestId", BIGINT, nullable=False, unique=True, primary_key=True), + Column("DisplayName", VARCHAR(255), nullable=False), + Column("DisplayName_en", VARCHAR(255)), + Column("EpisodeNum", INTEGER, nullable=False), + Column("ExBonusTableSubId", INTEGER, nullable=False), + Column("QuestSceneId", BIGINT, ForeignKey("sao_static_quest.QuestSceneId", ondelete="cascade", onupdate="cascade"), nullable=False), + mysql_charset="utf8mb4" ) class SaoStaticData(BaseData): - async def put_quest( self, questSceneId: int, version: int, sortNo: int, name: str, enabled: bool ) -> Optional[int]: + async def put_quest(self, data: Dict[str, str]) -> Optional[int]: sql = insert(quest).values( - questSceneId=questSceneId, - version=version, - sortNo=sortNo, - name=name, - enabled=enabled, + QuestSceneId=data["QuestSceneId"], + SortNo=data["SortNo"], + Tutorial=data["Tutorial"], + ColRate=data["ColRate"], + LimitDefault=data["LimitDefault"], + LimitResurrection=data["LimitResurrection"], + RewardTableSubId=data["RewardTableSubId"], + PlayerTraceTableSubId=data["PlayerTraceTableSubId"], + SuccessPlayerExp=data["SuccessPlayerExp"], + FailedPlayerExp=data["FailedPlayerExp"], + PairExpRate=data["PairExpRate"], + TrioExpRate=data["TrioExpRate"], + SingleRewardVp=data["SingleRewardVp"], + PairRewardVp=data["PairRewardVp"], + TrioRewardVp=data["TrioRewardVp"], ) - conflict = sql.on_duplicate_key_update( - name=name, questSceneId=questSceneId, version=version - ) + conflict = sql.on_duplicate_key_update(QuestSceneId=data["QuestSceneId"]) result = await self.execute(conflict) if result is None: return None - return result.lastrowid + return data["QuestSceneId"] - async def put_hero( self, version: int, heroLogId: int, name: str, nickname: str, rarity: int, skillTableSubId: int, awakeningExp: int, flavorText: str, enabled: bool ) -> Optional[int]: + async def put_hero(self, data: Dict[str, str]) -> Optional[int]: sql = insert(hero).values( - version=version, - heroLogId=heroLogId, - name=name, - nickname=nickname, - rarity=rarity, - skillTableSubId=skillTableSubId, - awakeningExp=awakeningExp, - flavorText=flavorText, - enabled=enabled + HeroLogId=data["HeroLogId"], + CharaId=data["CharaId"], + Name=data["Name"], + Nickname=data["Nickname"], + Rarity=data["Rarity"], + WeaponTypeId=data["WeaponTypeId"], + HeroLogRoleId=data["HeroLogRoleId"], + CostumeTypeId=data["CostumeTypeId"], + UnitId=data["UnitId"], + DefaultEquipmentId1=data["DefaultEquipmentId1"], + DefaultEquipmentId2=data["DefaultEquipmentId2"], + SkillTableSubId=data["SkillTableSubId"], + HpMin=data["HpMin"], + HpMax=data["HpMax"], + StrMin=data["StrMin"], + StrMax=data["StrMax"], + VitMin=data["VitMin"], + VitMax=data["VitMax"], + IntMin=data["IntMin"], + IntMax=data["IntMax"], + Property1PropertyId=data["Property1PropertyId"], + Property1Value1=data["Property1Value1"], + Property1Value2=data["Property1Value2"], + Property2PropertyId=data["Property2PropertyId"], + Property2Value1=data["Property2Value1"], + Property2Value2=data["Property2Value2"], + Property3PropertyId=data["Property3PropertyId"], + Property3Value1=data["Property3Value1"], + Property3Value2=data["Property3Value2"], + Property4PropertyId=data["Property4PropertyId"], + Property4Value1=data["Property4Value1"], + Property4Value2=data["Property4Value2"], + FlavorText=data["FlavorText"], + SalePrice=data["SalePrice"], + CompositionExp=data["CompositionExp"], + AwakeningExp=data["AwakeningExp"], + Slot4UnlockLevel=data["Slot4UnlockLevel"], + Slot5UnlockLevel=data["Slot5UnlockLevel"], + CollectionEmptyFrameDisplayFlag=data["CollectionEmptyFrameDisplayFlag"], ) - conflict = sql.on_duplicate_key_update( - name=name, heroLogId=heroLogId - ) + conflict = sql.on_duplicate_key_update(HeroLogId=data["HeroLogId"]) result = await self.execute(conflict) if result is None: return None - return result.lastrowid + return data["HeroLogId"] - async def put_equipment( self, version: int, equipmentId: int, name: str, equipmentType: int, weaponTypeId:int, rarity: int, flavorText: str, enabled: bool ) -> Optional[int]: + async def put_hero_translation(self, hero_id: int, name_en: str, nickname_en: str, flavor_text_en: str) -> None: + result = await self.execute(hero.update(hero.c.HeroLogId == hero_id).values( + Name=name_en, + Nickname=nickname_en, + FlavorText=flavor_text_en, + )) + + result = await self.execute(result) + if result is None: + self.logger.error(f"Failed to add translated text for hero {hero_id}") + + async def put_equipment(self, data: Dict[str, str]) -> Optional[int]: sql = insert(equipment).values( - version=version, - equipmentId=equipmentId, - name=name, - equipmentType=equipmentType, - weaponTypeId=weaponTypeId, - rarity=rarity, - flavorText=flavorText, - enabled=enabled + EquipmentId=data["EquipmentId"], + EquipmentType=data["EquipmentType"], + WeaponTypeId=data["WeaponTypeId"], + Name=data["Name"], + Rarity=data["Rarity"], + Power=data["Power"], + StrengthIncrement=data["StrengthIncrement"], + SkillCondition=data["SkillCondition"], + Property1PropertyId=data["Property1PropertyId"], + Property1Value1=data["Property1Value1"], + Property1Value2=data["Property1Value2"], + Property2PropertyId=data["Property2PropertyId"], + Property2Value1=data["Property2Value1"], + Property2Value2=data["Property2Value2"], + Property3PropertyId=data["Property3PropertyId"], + Property3Value1=data["Property3Value1"], + Property3Value2=data["Property3Value2"], + Property4PropertyId=data["Property4PropertyId"], + Property4Value1=data["Property4Value1"], + Property4Value2=data["Property4Value2"], + SalePrice=data["SalePrice"], + CompositionExp=data["CompositionExp"], + AwakeningExp=data["AwakeningExp"], + FlavorText=data["FlavorText"], ) - conflict = sql.on_duplicate_key_update( - name=name, equipmentId=equipmentId - ) + conflict = sql.on_duplicate_key_update(EquipmentId=data["EquipmentId"]) result = await self.execute(conflict) if result is None: return None - return result.lastrowid + return data["EquipmentId"] - async def put_item( self, version: int, itemId: int, name: str, itemTypeId: int, rarity: int, flavorText: str, enabled: bool ) -> Optional[int]: + async def put_equipment_translation(self, equip_id: int, name_en: str, flavor_text_en: str) -> None: + result = await self.execute(equipment.update(equipment.c.EquipmentId == equip_id).values( + Name_en=name_en, + FlavorText_en=flavor_text_en, + )) + + result = await self.execute(result) + if result is None: + self.logger.error(f"Failed to add translated text for equipment {equip_id}") + + async def put_item(self, data: Dict[str, str]) -> Optional[int]: sql = insert(item).values( - version=version, - itemId=itemId, - name=name, - itemTypeId=itemTypeId, - rarity=rarity, - flavorText=flavorText, - enabled=enabled + ItemId=data["ItemId"], + ItemTypeId=data["ItemTypeId"], + Name=data["Name"], + Rarity=data["Rarity"], + Value=data["Value"], + PropertyId=data["PropertyId"], + PropertyValue1Min=data["PropertyValue1Min"], + PropertyValue1Max=data["PropertyValue1Max"], + PropertyValue2Min=data["PropertyValue2Min"], + PropertyValue2Max=data["PropertyValue2Max"], + FlavorText=data["FlavorText"], + SalePrice=data["SalePrice"], + ItemIcon=data["ItemIcon"], + ) - conflict = sql.on_duplicate_key_update( - name=name, itemId=itemId - ) + conflict = sql.on_duplicate_key_update(ItemId=data["ItemId"]) result = await self.execute(conflict) if result is None: return None - return result.lastrowid + return data["ItemId"] + + async def put_item_translation(self, item_id: int, name_en: str, flavor_text_en: str) -> None: + result = await self.execute(item.update(item.c.ItemId == item_id).values( + Name_en=name_en, + FlavorText_en=flavor_text_en, + )) + + result = await self.execute(result) + if result is None: + self.logger.error(f"Failed to add translated text for item {item_id}") + + async def put_property(self, data: Dict[str, str]) -> None: + sql = insert(prop).values( + PropertyId=data["PropertyId"], + PropertyTargetType=data["PropertyTargetType"], + PropertyName=data["PropertyName"], + PropertyNameFormat=data["PropertyNameFormat"], + PropertyTypeId=data["PropertyTypeId"], + Value1Min=data["Value1Min"], + Value1Max=data["Value1Max"], + Value2Min=data["Value2Min"], + Value2Max=data["Value2Max"], + ) + + conflict = sql.on_duplicate_key_update(PropertyId=data["PropertyId"]) + + result = await self.execute(conflict) + if result is None: + return None + return data["PropertyId"] + async def put_property_translation(self, property_id: int, name_en: str, name_fmt: str) -> None: + result = await self.execute(prop.update(prop.c.PropertyId == property_id).values( + Name_en=name_en, + PropertyNameFormat_en=name_fmt, + )) + + result = await self.execute(result) + if result is None: + self.logger.error(f"Failed to add translated text for property {property_id}") + + async def put_skill(self, data: Dict[str, str]) -> None: + sql = insert(skill).values( + SkillId=data["SkillId"], + WeaponTypeId=data["WeaponTypeId"], + Name=data["Name"], + Attack=data["Attack"], + Passive=data["Passive"], + Pet=data["Pet"], + Level=data["Level"], + SkillCondition=data["SkillCondition"], + CoolTime=data["CoolTime"], + SkillIcon=data["SkillIcon"], + FriendSkillIcon=data["FriendSkillIcon"], + InfoText=data["InfoText"], + ) + + conflict = sql.on_duplicate_key_update(SkillId=data["SkillId"]) + + result = await self.execute(conflict) + if result is None: + return None + return data["SkillId"] + + async def put_skill_translation(self, skill_id: int, name_en: str, info_txt: str) -> None: + result = await self.execute(skill.update(skill.c.SkillId == skill_id).values( + Name_en=name_en, + InfoText_en=info_txt, + )) + + result = await self.execute(result) + if result is None: + self.logger.error(f"Failed to add translated text for skill {skill_id}") + + async def put_skill_table(self, skill_id: int, sub_id: int, level: int, awakening: int, table_id: int) -> None: + sql = insert(skill_table).values( + SkillTableId=table_id, + SkillId=skill_id, + SkillTableSubId=sub_id, + LevelObtained=level, + AwakeningId=awakening, + ) + conflict = sql.on_duplicate_key_update(SkillTableId=table_id) + result = await self.execute(conflict) + if result is None: + self.logger.error(f"Failed to add skill table {skill_id}") + + async def put_player_trace(self, data: Dict[str, str]) -> None: + sql = insert(player_trace).values( + PlayerTraceTableId=data["PlayerTraceTableId"], + PlayerTraceTableSubId=data["PlayerTraceTableSubId"], + CommonRewardType=data["CommonRewardType"], + CommonRewardId=data["CommonRewardId"], + CommonRewardNum=data["CommonRewardNum"], + Rate=data["Rate"], + ) + + conflict = sql.on_duplicate_key_update(PlayerTraceTableId=data["PlayerTraceTableId"]) + result = await self.execute(conflict) + if result is None: + return None + return data["PlayerTraceTableId"] + async def put_support_log( self, version: int, supportLogId: int, charaId: int, name: str, rarity: int, salePrice: int, skillName: str, enabled: bool ) -> Optional[int]: sql = insert(support).values( version=version, @@ -221,14 +603,12 @@ class SaoStaticData(BaseData): enabled=enabled ) - conflict = sql.on_duplicate_key_update( - name=name, supportLogId=supportLogId - ) + conflict = sql.on_duplicate_key_update(version=version) result = await self.execute(conflict) - if result is None: - return None - return result.lastrowid + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert support log {supportLogId}!") async def put_rare_drop( self, version: int, questRareDropId: int, commonRewardId: int, enabled: bool ) -> Optional[int]: sql = insert(rare_drop).values( @@ -238,14 +618,12 @@ class SaoStaticData(BaseData): enabled=enabled, ) - conflict = sql.on_duplicate_key_update( - questRareDropId=questRareDropId, commonRewardId=commonRewardId, version=version - ) + conflict = sql.on_duplicate_key_update(version=version) result = await self.execute(conflict) - if result is None: - return None - return result.lastrowid + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert rare drop {questRareDropId}!") async def put_title( self, version: int, titleId: int, displayName: str, requirement: int, rank: int, imageFilePath: str, enabled: bool ) -> Optional[int]: sql = insert(title).values( @@ -258,71 +636,141 @@ class SaoStaticData(BaseData): enabled=enabled ) - conflict = sql.on_duplicate_key_update( - displayName=displayName, titleId=titleId + conflict = sql.on_duplicate_key_update(version=version) + + result = await self.execute(conflict) + if result: + return result.inserted_primary_key['id'] + self.logger.error(f"Failed to insert title {titleId}") + + async def put_reward_table(self, data: Dict[str, Union[str, bool]]) -> None: + sql = insert(reward).values( + **data ) + conflict = sql.on_duplicate_key_update(**data) + result = await self.execute(conflict) if result is None: return None - return result.lastrowid + return data['RewardTableId'] + + async def put_ex_bonus(self, data: Dict[str, int]) -> None: + sql = insert(ex_bonus).values( + **data + ) - async def get_quests_id(self, sortNo: int) -> Optional[Dict]: - sql = quest.select(quest.c.sortNo == sortNo) - - result = await self.execute(sql) + conflict = sql.on_duplicate_key_update(**data) + + result = await self.execute(conflict) + if result is None: + return None + return data['ExBonusTableId'] + + async def put_episode(self, data: Dict[str, int]) -> None: + sql = insert(episode).values( + EpisodeId=data['EpisodeId'], + EpisodeChapterId=data['EpisodeChapterId'], + ReleaseEpisodeId=data['ReleaseEpisodeId'], + Title=data['Title'], + CommentSummary=data['CommentSummary'], + ExBonusTableSubId=data['ExBonusTableSubId'], + QuestSceneId=data['QuestSceneId'] if data['QuestSceneId'] > 0 else None, + ) + + conflict = sql.on_duplicate_key_update(EpisodeId=data['EpisodeId']) + + result = await self.execute(conflict) + if result is None: + return None + return data['EpisodeId'] + + async def put_tower(self, data: Dict[str, int]) -> None: + sql = insert(tower).values( + TowerId=data['TrialTowerId'], + ReleaseTowerId=data['ReleaseTrialTowerId'], + ExBonusTableSubId=data['ExBonusTableSubId'], + QuestSceneId=data['QuestSceneId'], + ) + + conflict = sql.on_duplicate_key_update(TowerId=data['TrialTowerId']) + + result = await self.execute(conflict) + if result is None: + return None + return data['TrialTowerId'] + + async def put_ex_tower(self, data: Dict[str, int]) -> None: + sql = insert(ex_tower).values( + ExTowerQuestId=data['ExTowerQuestId'], + ExTowerId=data['ExTowerId'], + ReleaseExTowerQuestId=data['ReleaseExTowerQuestId'], + Title=data['Title'], + ExBonusTableSubId=data['ExBonusTableSubId'], + QuestSceneId=data['QuestSceneId'], + ) + + conflict = sql.on_duplicate_key_update(ExTowerQuestId=data['ExTowerQuestId']) + + result = await self.execute(conflict) + if result is None: + return None + return data['ExTowerQuestId'] + + async def put_side_quest(self, data: Dict[str, int]) -> None: + sql = insert(side_quest).values( + SideQuestId=data['SideQuestId'], + DisplayName=data['DisplayName'], + EpisodeNum=data['EpisodeNum'], + ExBonusTableSubId=data['ExBonusTableSubId'], + QuestSceneId=data['QuestSceneId'], + ) + + conflict = sql.on_duplicate_key_update(SideQuestId=data['SideQuestId']) + + result = await self.execute(conflict) + if result is None: + return None + return data['SideQuestId'] + + async def get_quest_by_id(self, quest_scene_id: int) -> Optional[Row]: + result = await self.execute(quest.select(quest.c.QuestSceneId == quest_scene_id)) if result is None: return None return result.fetchone() - async def get_quests_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]: - sql = quest.select(quest.c.version == version and quest.c.enabled == enabled).order_by( - quest.c.questSceneId.asc() - ) - - result = await self.execute(sql) + async def get_quests(self) -> Optional[List[Row]]: + result = await self.execute(quest.select()) if result is None: return None - return [list[2] for list in result.fetchall()] + return result.fetchall() - async def get_hero_id(self, heroLogId: int) -> Optional[Dict]: - sql = hero.select(hero.c.heroLogId == heroLogId) - - result = await self.execute(sql) + async def get_hero_by_id(self, heroLogId: int) -> Optional[Row]: + result = await self.execute(hero.select(hero.c.HeroLogId == heroLogId)) if result is None: return None return result.fetchone() - async def get_hero_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]: - sql = hero.select(hero.c.version == version and hero.c.enabled == enabled).order_by( - hero.c.heroLogId.asc() - ) - - result = await self.execute(sql) + async def get_heros(self) -> Optional[List[Row]]: + result = await self.execute(hero.select()) if result is None: return None - return [list[2] for list in result.fetchall()] + return result.fetchall() - async def get_equipment_id(self, equipmentId: int) -> Optional[Dict]: - sql = equipment.select(equipment.c.equipmentId == equipmentId) - - result = await self.execute(sql) + async def get_equipment_by_id(self, equipmentId: int) -> Optional[Dict]: + result = await self.execute(equipment.select(equipment.c.EquipmentId == equipmentId)) if result is None: return None return result.fetchone() - async def get_equipment_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]: - sql = equipment.select(equipment.c.version == version and equipment.c.enabled == enabled).order_by( - equipment.c.equipmentId.asc() - ) - - result = await self.execute(sql) + async def get_equipment(self) -> Optional[List[Dict]]: + result = await self.execute(equipment.select()) if result is None: return None - return [list[2] for list in result.fetchall()] + return result.fetchall() - async def get_item_id(self, itemId: int) -> Optional[Dict]: - sql = item.select(item.c.itemId == itemId) + async def get_item_id(self, item_id: int) -> Optional[Dict]: + sql = item.select(item.c.ItemId == item_id) result = await self.execute(sql) if result is None: @@ -347,6 +795,12 @@ class SaoStaticData(BaseData): return None return [list[2] for list in result.fetchall()] + async def get_support_logs(self) -> Optional[List[Dict]]: + result = await self.execute(support.select()) + if result is None: + return None + return result.fetchall() + async def get_support_log_ids(self, version: int, enabled: bool) -> Optional[List[Dict]]: sql = support.select(support.c.version == version and support.c.enabled == enabled).order_by( support.c.supportLogId.asc() @@ -365,4 +819,156 @@ class SaoStaticData(BaseData): result = await self.execute(sql) if result is None: return None - return [list[2] for list in result.fetchall()] \ No newline at end of file + return [list[2] for list in result.fetchall()] + + async def get_reward_by_table(self, table_id: int) -> Optional[Row]: + result = await self.execute(reward.select(reward.c.RewardTableId == table_id)) + if result is None: + return None + return result.fetchone() + + async def get_rewards_by_subtable(self, subtable_id: int) -> Optional[List[Row]]: + result = await self.execute(reward.select(reward.c.RewardTableSubId == subtable_id)) + if result is None: + return None + return result.fetchall() + + async def get_rewards(self) -> Optional[List[Row]]: + result = await self.execute(reward.select()) + if result is None: + return None + return result.fetchall() + + async def get_ex_bonus_by_table(self, table_id: int) -> Optional[Row]: + result = await self.execute(ex_bonus.select(ex_bonus.c.ExBonusTableId == table_id)) + if result is None: + return None + return result.fetchone() + + async def get_ex_bonuses_by_subtable(self, subtable_id: int) -> Optional[List[Row]]: + result = await self.execute(ex_bonus.select(ex_bonus.c.ExBonusTableSubId == subtable_id)) + if result is None: + return None + return result.fetchall() + + async def get_ex_bonuses(self) -> Optional[List[Row]]: + result = await self.execute(ex_bonus.select()) + if result is None: + return None + return result.fetchall() + + async def get_episode_by_id(self, episode_id: int) -> Optional[Row]: + result = await self.execute(episode.select(episode.c.EpisodeId == episode_id)) + if result is None: + return None + return result.fetchone() + + async def get_episode_by_quest_id(self, quest_id: int) -> Optional[Row]: + result = await self.execute(episode.select(episode.c.QuestSceneId == quest_id)) + if result is None: + return None + return result.fetchone() + + async def get_episodes(self) -> Optional[List[Row]]: + result = await self.execute(episode.select()) + if result is None: + return None + return result.fetchall() + + async def get_tower_by_id(self, tower_id: int) -> Optional[Row]: + result = await self.execute(tower.select(tower.c.TowerId == tower_id)) + if result is None: + return None + return result.fetchone() + + async def get_tower_by_quest_id(self, quest_id: int) -> Optional[Row]: + result = await self.execute(tower.select(tower.c.QuestSceneId == quest_id)) + if result is None: + return None + return result.fetchone() + + async def get_towers(self) -> Optional[List[Row]]: + result = await self.execute(tower.select()) + if result is None: + return None + return result.fetchall() + + async def get_ex_tower_by_id(self, ex_tower_id: int) -> Optional[Row]: + result = await self.execute(ex_tower.select(ex_tower.c.ExTowerQuestId == ex_tower_id)) + if result is None: + return None + return result.fetchone() + + async def get_ex_tower_by_quest_id(self, quest_id: int) -> Optional[Row]: + result = await self.execute(ex_tower.select(ex_tower.c.QuestSceneId == quest_id)) + if result is None: + return None + return result.fetchone() + + async def get_ex_towers(self) -> Optional[List[Row]]: + result = await self.execute(ex_tower.select()) + if result is None: + return None + return result.fetchall() + + async def get_ex_towers_by_tower(self, ex_tower_id: int) -> Optional[List[Row]]: + result = await self.execute(ex_tower.select(ex_tower.c.ExTowerId == ex_tower_id)) + if result is None: + return None + return result.fetchall() + + async def get_side_quest_by_id(self, side_quest_id: int) -> Optional[Row]: + result = await self.execute(side_quest.select(side_quest.c.SideQuestId == side_quest_id)) + if result is None: + return None + return result.fetchone() + + async def get_side_quest_by_quest_id(self, quest_id: int) -> Optional[Row]: + result = await self.execute(side_quest.select(side_quest.c.QuestSceneId == quest_id)) + if result is None: + return None + return result.fetchone() + + async def get_side_quests(self) -> Optional[List[Row]]: + result = await self.execute(side_quest.select()) + if result is None: + return None + return result.fetchall() + + async def get_side_quests_by_episode(self, episode_num: int) -> Optional[List[Row]]: + result = await self.execute(side_quest.select(side_quest.c.EpisodeNum == episode_num)) + if result is None: + return None + return result.fetchall() + + async def get_player_trace_by_id(self, trace_id: int) -> Optional[Row]: + result = await self.execute(player_trace.select(player_trace.c.PlayerTraceTableId == trace_id)) + if result is None: + return None + return result.fetchone() + + async def get_player_trace_by_subid(self, trace_sub_id: int) -> Optional[List[Row]]: + result = await self.execute(player_trace.select(player_trace.c.PlayerTraceTableSubId == trace_sub_id)) + if result is None: + return None + return result.fetchall() + + async def get_player_traces(self) -> Optional[List[Row]]: + result = await self.execute(player_trace.select()) + if result is None: + return None + return result.fetchall() + + async def get_skill_table_by_subid(self, table_sub_id: int) -> Optional[List[Row]]: + result = await self.execute(skill_table.select(skill_table.c.SkillTableSubId == table_sub_id)) + + if result is None: + return None + return result.fetchall() + + async def get_skill_by_id(self, skill_id: int) -> Optional[Row]: + result = await self.execute(skill.select(skill.c.SkillId == skill_id)) + + if result is None: + return None + return result.fetchone() diff --git a/titles/sao/templates/sao_index.jinja b/titles/sao/templates/sao_index.jinja new file mode 100644 index 0000000..35d42ce --- /dev/null +++ b/titles/sao/templates/sao_index.jinja @@ -0,0 +1,182 @@ +{% extends "core/templates/index.jinja" %} +{% block content %} +