├── LICENSE ├── README.md ├── UnityAsset.php ├── UnityBundle.php ├── bang ├── AppGetResponse_gen.proto ├── AssetBundleInfo_gen.proto ├── SuiteMaster_gen.proto ├── main.php ├── reprocess.php ├── resource_fetch.php └── version_hash.txt ├── cgss ├── diff_parse.php ├── eventrank │ ├── README.md │ ├── data │ │ ├── highcharts.js │ │ ├── index.htm │ │ ├── main.css │ │ └── main.js │ └── main.php ├── main.php └── resource_fetch.php ├── dankagu ├── DankaguScore.php ├── convert_db.sh ├── main.php ├── resource_fetch.php ├── schema │ ├── ActiveSkillRaw.fbs │ ├── AdMobExpeditionRaw.fbs │ ├── AdMobGachaSettingRaw.fbs │ ├── AdMobMovieSettingRaw.fbs │ ├── AdMobSpecialChanceRaw.fbs │ ├── AdMobStepRewardRaw.fbs │ ├── AssetPathRaw.fbs │ ├── AwakeBonusRaw.fbs │ ├── AwakeItemRaw.fbs │ ├── AwakeRaw.fbs │ ├── BarrageBulletDataRaw.fbs │ ├── BarrageCommonDataRaw.fbs │ ├── BarrageDataRaw.fbs │ ├── BingoCharacterMessageRaw.fbs │ ├── BlackBallCharacterRaw.fbs │ ├── BonusMusicRaw.fbs │ ├── BookVoiceCategoryRaw.fbs │ ├── BookVoiceInfoRaw.fbs │ ├── BoostRaw.fbs │ ├── BossRaw.fbs │ ├── CampaignCategoryRaw.fbs │ ├── CampaignExpeditionBoostRaw.fbs │ ├── CampaignRaw.fbs │ ├── CardR1ExpRaw.fbs │ ├── CardR2ExpRaw.fbs │ ├── CardR3ExpRaw.fbs │ ├── CardR4ExpRaw.fbs │ ├── CardRaw.fbs │ ├── CharacterCefficientRaw.fbs │ ├── CharacterExpRaw.fbs │ ├── CharacterParameterRaw.fbs │ ├── CharacterRaw.fbs │ ├── CharacterVoiceMotionTextRaw.fbs │ ├── ClubEmblemRaw.fbs │ ├── ClubObjectItemRaw.fbs │ ├── ClubPositionRaw.fbs │ ├── ClubStampRaw.fbs │ ├── ClubThemeRaw.fbs │ ├── ComboCefficientRaw.fbs │ ├── ComboMaxRaw.fbs │ ├── CoopEventExpeditionPointRaw.fbs │ ├── CoopEventInfoRaw.fbs │ ├── CoopEventPhaseVisitMaxRaw.fbs │ ├── CoopEventProgressItemRaw.fbs │ ├── CoopEventProgressRewardRaw.fbs │ ├── CoopEventScheduleRaw.fbs │ ├── CoopEventTweetIdEventIdMapRaw.fbs │ ├── CoopEventTweetRaw.fbs │ ├── DailyBonusItemRaw.fbs │ ├── DailyBonusRaw.fbs │ ├── DailyHeroineRaw.fbs │ ├── DanmakuPassActivationKeyRaw.fbs │ ├── DanmakuPassCefficientRaw.fbs │ ├── DanmakuPassPlanRaw.fbs │ ├── DanmakuPassRaw.fbs │ ├── DanmakuPassRewardRaw.fbs │ ├── DanmakuRaw.fbs │ ├── DataVersionRaw.fbs │ ├── DecomposeItemRaw.fbs │ ├── DefaultHaveItemRaw.fbs │ ├── DownloadBGRaw.fbs │ ├── EmblemRaw.fbs │ ├── EpisodeLivePresetRaw.fbs │ ├── EpisodeRaw.fbs │ ├── EpisodeRewardRaw.fbs │ ├── ErrorMessageRaw.fbs │ ├── EventBoxRewardRaw.fbs │ ├── EventCefficientRaw.fbs │ ├── EventInfoRaw.fbs │ ├── EventRaidBossDamageParamRaw.fbs │ ├── EventRaidBossHpRaw.fbs │ ├── EventRaidBossRaw.fbs │ ├── EventRaidBotRaw.fbs │ ├── EventRankingGroupRaw.fbs │ ├── EventRankingRewardRaw.fbs │ ├── EventScheduleRaw.fbs │ ├── EventTotalRewardRaw.fbs │ ├── Exp2LvRaw.fbs │ ├── ExpeditionChallengeBonusRaw.fbs │ ├── ExpeditionChallengeTypeRaw.fbs │ ├── ExpeditionConditionRaw.fbs │ ├── ExpeditionExecMaxRaw.fbs │ ├── ExpeditionFilterTypeRaw.fbs │ ├── ExpeditionMissionRaw.fbs │ ├── ExpeditionRankingGroupRaw.fbs │ ├── ExpeditionRewardItemRaw.fbs │ ├── ExpeditionRewardRaw.fbs │ ├── ExpeditionSkillRaw.fbs │ ├── ExpeditionSuccessWeightRaw.fbs │ ├── ExpeditionUnlockRaw.fbs │ ├── GachaTicketRaw.fbs │ ├── GachaTicketTypeRaw.fbs │ ├── GachaTopScaleRaw.fbs │ ├── GenericConstantRaw.fbs │ ├── GenericItemRaw.fbs │ ├── GpxClassRaw.fbs │ ├── GpxInfoRaw.fbs │ ├── GpxPhaseRaw.fbs │ ├── GpxRankingGroupRaw.fbs │ ├── GpxRankingRewardRaw.fbs │ ├── GpxScheduleRaw.fbs │ ├── GpxTemplateRaw.fbs │ ├── GpxTicketSettingRaw.fbs │ ├── GrowthItemRaw.fbs │ ├── HakoniwaCefficientRaw.fbs │ ├── HeroineGrowthRaw.fbs │ ├── HeroineRaw.fbs │ ├── HeroineSkillRaw.fbs │ ├── HomeBannerRaw.fbs │ ├── HomeVoiceRaw.fbs │ ├── ImageHelpRaw.fbs │ ├── IndividualDiff2Raw.fbs │ ├── IndividualDiffRaw.fbs │ ├── LifeDecreasRaw.fbs │ ├── LimitBreakRaw.fbs │ ├── LinkBurstSkillRaw.fbs │ ├── MapGridRaw.fbs │ ├── MapUnlockRaw.fbs │ ├── MessageMapRaw.fbs │ ├── MissionBeginnerRaw.fbs │ ├── MissionConditionRaw.fbs │ ├── MissionRaw.fbs │ ├── MissionTableRaw.fbs │ ├── MonthlyPassRaw.fbs │ ├── MonthlyPassRewardRaw.fbs │ ├── MusicLevelScoreRaw.fbs │ ├── MusicProductRaw.fbs │ ├── MusicRaw.fbs │ ├── MusicScoreRaw.fbs │ ├── NewMusicAnnouncementRaw.fbs │ ├── NoteTapSeRaw.fbs │ ├── NotesAdjustmentRaw.fbs │ ├── PKVSRaw.fbs │ ├── PartyRaw.fbs │ ├── PartyRewardRaw.fbs │ ├── PassiveSkillRaw.fbs │ ├── PlayRewardRaw.fbs │ ├── PlayerCefficientRaw.fbs │ ├── PlayerExpRaw.fbs │ ├── PlayerLvUpRewardRaw.fbs │ ├── RGameActiveSkillTimingRaw.fbs │ ├── RandomTweetRaw.fbs │ ├── RandomTweetSpotLimitSetRaw.fbs │ ├── ReconstructionRewardRaw.fbs │ ├── RegularRankingRaw.fbs │ ├── ResourceItemRaw.fbs │ ├── RewardConditionRaw.fbs │ ├── RewardItemSetRaw.fbs │ ├── RgCounstantRaw.fbs │ ├── RythmGameRaw.fbs │ ├── ScoreCefficientRaw.fbs │ ├── SdSkinRaw.fbs │ ├── SelectTicketRaw.fbs │ ├── ShopProductRaw.fbs │ ├── ShopRaw.fbs │ ├── SpecialSkillRaw.fbs │ ├── SpellCardMissionRaw.fbs │ ├── SpellCardRaw.fbs │ ├── SpotObjectItemRaw.fbs │ ├── SpotObjectRaw.fbs │ ├── SpotObjectRewardRaw.fbs │ ├── SpotRaw.fbs │ ├── SpotRepairObjectRaw.fbs │ ├── SpotRepairRaw.fbs │ ├── SpotThemeRaw.fbs │ ├── SpotUnlockRaw.fbs │ ├── SpotVisitRaw.fbs │ ├── StrengthenRaw.fbs │ ├── SystemIntRaw.fbs │ ├── SystemStringRaw.fbs │ ├── TitleBGRaw.fbs │ ├── TutorialAdvRaw.fbs │ ├── TutorialRGameRaw.fbs │ ├── TweetRaw.fbs │ ├── VCRaw.fbs │ └── WavRaw.fbs └── sec_dankagu.php ├── haifuri ├── main.php └── resource_fetch.php ├── llas └── main.php ├── redive ├── Coneshell_call │ ├── coneshell_cdb_ver2.7z │ ├── coneshell_cdb_ver3.7z │ └── main.cpp ├── RediveStoryDeserializer.php ├── db-remap.php ├── diff_parse.php ├── main.php ├── nameMap.json └── resource_fetch.php ├── rizline └── main.php ├── sbr ├── main.php └── resource_fetch.php ├── tw_redive ├── RediveStoryDeserializer.php ├── UnityAsset.php ├── diff_parse.php └── main.php └── wds ├── exportTable.php └── main.php /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 esterTion 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Unity Texture Toolkit 2 | 3 | > written in PHP 4 | 5 | ## What's this for 6 | I wrote this for automatic game resource updating and dumping to png/webp, it's currently deployed on my server https://redive.estertion.win/ 7 | Main codes are highly inspired by [AssetStudio](https://github.com/Perfare/AssetStudio) 8 | 9 | ## Requirement 10 | [php-ext-lz4](https://github.com/kjdev/php-ext-lz4/) ( For decompressing the bundle ) 11 | [astcenc](https://github.com/ARM-software/astc-encoder/tree/master/Binary) ( For decompressing ASTC texture format ) 12 | [ffmpeg](http://ffmpeg.org/download.html) ( For reencoding ) 13 | `astcenc` and `ffmepg` need to be placed under PATH, like `/usr/bin` (cron may not search for `/usr/local/bin`, or you can configure it) 14 | 15 | ## Limitation 16 | Current supported format: 17 | - ASTC compressed 2d image 18 | - Raw rgb ( e.g. RGB24 RGB565 RGBA4444 etc ) 19 | > I've only met these formats so far 20 | 21 | ## How to use 22 | 23 | ```PHP 24 | require_once 'UnityAsset.php'; // This will require UnityBundle.php as it needs FileStream 25 | 26 | $bundleFileName = 'bundle_name.unity3d'; // This is the bundle file with file header "UnityFS" 27 | $bundleFileStream = new FileStream($bundleFileName); // Create a read stream 28 | $assetsList = extractBundle($bundleFileStream); // This will extract assets to disk 29 | unset($bundleFileStream); // Free the handle 30 | 31 | foreach ($assetsList as $asset) { 32 | if (substr($asset, -4,4) == '.resS') continue; // .resS file is external data storage file 33 | $asset = new AssetFile($asset); 34 | 35 | foreach ($asset->preloadTable as &$item) { 36 | if ($item->typeString == 'Texture2D') { 37 | $item = new Texture2D($item, true); // Parse and read data 38 | $item->exportTo($item->name, 'webp', '-lossless 1'); // export to format, with additional encode parameters 39 | // $item->exportTo($item->name, 'png'); 40 | unset($item); // Free up memory 41 | } 42 | } 43 | $asset->__desctruct(); 44 | unset($asset); // Free up memory 45 | } 46 | foreach ($assetsList as $asset) { 47 | unlink($asset); // clean up files 48 | } 49 | ``` 50 | 51 | ### What's in the sub directory 52 | These are the files I'm croning on my server for automatic update 53 | There are different versions, as I wrote the `Princess Connect Re:dive` first, its code has least feature, and `cgss` is the current latest 54 | They all share the same `UnityBundle.php` 55 | 56 | ### Implementation detail 57 | 1. UnityBundle.php 58 | 59 | class `FileStream($filename)` and `MemoryStream($data)`: 60 | Two similar stream reader, FileStream accepts filename, MemoryStream accepts string as binary. 61 | Reading value can perform either function `$stream->readInt32()` or property `$stream->ulong` 62 | Property `position` can get current and set to seek point 63 | Property `littleEndian` determine either use little endian reading or not 64 | Function `write($newData)` will always write to the end for MemoryStream, but can overwrite current data position for FileStream 65 | 66 | function `extractBundle($bundleStream)`: 67 | Accepts a stream, may throw exception if is invalid file, or chunk is LZMA compressed, or something wrong happened 68 | Returns a list of asset file names extracted 69 | 70 | 2. UnityAsset.php 71 | 72 | class `AssetFile($assetFileName)`: 73 | Accepts a filename, may throw exception if something is not supported 74 | Can get resource info through property `preloadTable` 75 | 76 | class `Texture2D($preloadData, $readSwitch = false)`: 77 | Accepts an `AssetPreloadData` item from `preloadTable`, may throw an exception if format not supported 78 | Second parameter determine weither read data or not, if you only want to get the information 79 | Can call member function `exportTo($saveTo, $format = 'png', $extraEncodeParam = '')` to export supported texture 80 | -------------------------------------------------------------------------------- /bang/AppGetResponse_gen.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | message AppGetResponse { 3 | optional string clientVersion = 1; // normal type 4 | optional string dataVersion = 2; // normal type 5 | optional string appStatus = 3; // normal type 6 | optional string clientStatus = 4; // normal type 7 | optional string schema = 5; // normal type 8 | optional string gacha = 7; // normal type 9 | optional string multiLive = 8; // normal type 10 | optional string starShop = 9; // normal type 11 | optional string masterDataVersion = 10; // normal type 12 | optional string photonAppId = 11; // normal type 13 | } 14 | -------------------------------------------------------------------------------- /bang/AssetBundleInfo_gen.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto2"; 2 | message AssetBundleElement { 3 | optional string bundleName = 1; // normal type 4 | optional string hash = 2; // normal type 5 | optional string version = 3; // normal type 6 | optional string category = 4; // normal type 7 | optional uint32 crc = 5; // normal type 8 | repeated string dependencies = 6; // array 9 | optional int64 fileSize = 7; // normal type 10 | } 11 | message string_AssetBundleElement { 12 | optional string string_AssetBundleElement_key = 1; // normal type 13 | optional AssetBundleElement string_AssetBundleElement_value = 2; // sub class 14 | } 15 | message AssetBundleInfo { 16 | optional string version = 1; // normal type 17 | repeated string_AssetBundleElement bundles = 2; // dictionary 18 | } 19 | -------------------------------------------------------------------------------- /bang/reprocess.php: -------------------------------------------------------------------------------- 1 | '0','master'=>'0'); 10 | } else { 11 | $last_version = json_decode(file_get_contents('last_version'), true); 12 | } 13 | 14 | function _log($s) { 15 | //fwrite($logFile, date('[m/d H:i] ').$s."\n"); 16 | echo $s."\n"; 17 | } 18 | 19 | function parseProto($file) { 20 | $proto = file_get_contents($file); 21 | $proto = preg_replace('(//.+\n)', "\n", $proto); 22 | preg_match_all('(message (\w+) \{([\w\W]+?)\})', $proto, $messages); 23 | $output = []; 24 | for ($i=0; $i $fields[0] == 'repeated', 34 | 'type' => $fields[1], 35 | 'name' => $fields[2] 36 | ); 37 | } 38 | } 39 | return $output; 40 | } 41 | 42 | function readVarInt32($pb) { 43 | $b = ord($pb->readData(1)); 44 | $result = $b & 0x7f; 45 | $shift = 0; 46 | while ($b & 0x80) { 47 | $shift += 7; 48 | if ($shift > 64) throw new Exception('Too many bytes for varint'); 49 | $b=ord($pb->readData(1)); 50 | $result |= ($b & 0x7f) << $shift; 51 | } 52 | return $result; 53 | } 54 | 55 | function setValue(&$arr, $key, &$val, $isArr) { 56 | if ($isArr) { 57 | if (!isset($arr[$key])) $arr[$key] = []; 58 | $arr[$key][] = $val; 59 | } else { 60 | $arr[$key] = $val; 61 | } 62 | } 63 | 64 | function parseProtoBuf($messageName, $end, &$pb, &$proto, $messageCallback = null, $level = 1) { 65 | $message = []; 66 | while ($pb->position() < $end){ 67 | $id = readVarInt32($pb); 68 | $type = $id & 7; 69 | $id = $id >> 3; 70 | if (isset($proto[$messageName][$id])) { 71 | $def = $proto[$messageName][$id]; 72 | } else { 73 | $def = array('type'=>'byte', 'name'=>'UNKNOWN_'.$id, 'repeated'=>false); 74 | } 75 | $typeName = $def['type']; 76 | $name = $def['name']; 77 | $isRepeated = $def['repeated']; 78 | switch($type){ 79 | case 0: 80 | $data = readVarInt32($pb); 81 | setValue($message, $name, $data, $isRepeated); 82 | break; 83 | case 1: 84 | $data = $pb->readData(8); 85 | if ($typeName == 'double') { 86 | $data = unpack('d', $data)[1]; 87 | } else { 88 | $data = ' '.bin2hex($data); 89 | } 90 | setValue($message, $name, $data, $isRepeated); 91 | break; 92 | case 2: 93 | $length = readVarInt32($pb); 94 | if (isset($proto[$typeName])) { 95 | $sub = parseProtoBuf($typeName, $pb->position()+$length, $pb, $proto, $messageCallback, $level + 1); 96 | if ($messageCallback === null || call_user_func($messageCallback, $name, $sub, $level)) { 97 | setValue($message, $name, $sub, $isRepeated); 98 | } 99 | } else if ($length > 0) { 100 | $data = $pb->readData($length); 101 | if ($typeName == 'string') { 102 | } else { 103 | if (mb_detect_encoding($data, 'UTF-8', true)) { 104 | $data = ' '.$data; 105 | } else { 106 | $data = ' '.bin2hex($data); 107 | } 108 | } 109 | setValue($message, $name, $data, $isRepeated); 110 | } 111 | break; 112 | case 5: 113 | $data = $pb->readData(4); 114 | if ($typeName == 'float') { 115 | $data = unpack('f', $data)[1]; 116 | } else { 117 | $data = ' '.bin2hex($data); 118 | } 119 | setValue($message, $name, $data, $isRepeated); 120 | break; 121 | default: 122 | throw new Exception('unsupported type '.$type); 123 | } 124 | } 125 | return $message; 126 | } 127 | 128 | function processDict(&$arr) { 129 | foreach ($arr as $key=>&$val) { 130 | if (gettype($val) == 'array') { 131 | if (isset($val[0]) && gettype($val[0]) == 'array') { 132 | $keys = array_keys($val[0]); 133 | if (count($keys) == 2 134 | && substr($keys[0], -4, 4) == '_key' 135 | && substr($keys[1], -6, 6) == '_value') { 136 | $newDict = []; 137 | foreach ($val as &$item) { 138 | $newDict[ $item[$keys[0]] ] = $item[$keys[1]]; 139 | } 140 | unset($arr[$key]); 141 | $arr[$key] = $newDict; 142 | $val = &$arr[$key]; 143 | } 144 | } 145 | processDict($val); 146 | 147 | $keys = array_keys($val); 148 | if (count($keys) == 1 && $keys[0] === 'entries') { 149 | $arr[$key] = $val['entries']; 150 | } 151 | } 152 | } 153 | } 154 | 155 | function prettifyJSON($in) { 156 | $a = $in; 157 | if (gettype($a) == 'string') $a = json_decode($a); 158 | $a = json_encode($a, JSON_UNESCAPED_UNICODE+JSON_UNESCAPED_SLASHES+JSON_PRETTY_PRINT); 159 | $a = preg_replace("/([^\]\}]),\n +/", "$1, ", $a); 160 | $a = preg_replace('/("[^"]+?":) /', '$1', $a); 161 | $a = preg_replace_callback("/\n +/", function ($m) { return "\n".str_repeat(' ', (strlen($m[0])-1) / 2); }, $a); 162 | return $a; 163 | } 164 | 165 | $masterVer = $last_version['master']; 166 | $masterData = new FileStream('master.dat'); 167 | //$masterData = new FileStream('master'); 168 | 169 | chdir('data'); 170 | exec('git rm *.json --cached'); 171 | chdir(__DIR__); 172 | foreach (glob('data/*.json') as $file) {$file!='data/AssetBundleInfo.json'&&unlink($file);} 173 | 174 | $MasterProto = parseProto('SuiteMaster_gen.proto'); 175 | _log("dumping master"); 176 | parseProtoBuf('SuiteMasterGetResponse', $masterData->size, $masterData, $MasterProto, function ($name, $sub, $level) { 177 | if ($level > 1) return true; 178 | $sub = ['a'=>$sub]; 179 | processDict($sub); 180 | $sub = $sub['a']; 181 | if ($name === 'masterCharacterSituationMap') { 182 | global $situationMap; 183 | $situationMap = $sub; 184 | } else if ($name === 'masterCharacterInfoMap') { 185 | global $charaInfo; 186 | $charaInfo = $sub; 187 | } 188 | echo "$name ".memory_get_usage()."\n"; 189 | file_put_contents("data/${name}.json", prettifyJSON($sub)); 190 | return false; 191 | }); 192 | unset($masterData, $MasterProto); 193 | 194 | foreach ($situationMap as &$entry) { 195 | $id = substr($entry['resourceSetName'], 3); 196 | $names[$id] = str_repeat('★',$entry['rarity']).'['.$entry['prefix'].']'.$charaInfo[$entry['characterId']]['characterName']; 197 | } 198 | file_put_contents(RESOURCE_PATH_PREFIX.'card/index.json', json_encode($names, JSON_UNESCAPED_SLASHES)); 199 | unset($situationMap, $charaInfo, $names); 200 | file_put_contents('data/!masterDataVersion.txt', $masterVer."\n"); 201 | $commit[] = 'master: '.$masterVer.' (re-process)'; 202 | $last_version['master'] = $masterVer; 203 | 204 | if (!empty($commit)) { 205 | chdir('data'); 206 | exec('git add *.json !dataVersion.txt !masterDataVersion.txt'); 207 | exec('git commit -m "'.implode(' ', $commit).'"'); 208 | //exec('git push origin master'); 209 | } 210 | 211 | chdir(__DIR__); 212 | file_put_contents('last_version', json_encode($last_version)); 213 | 214 | if (isset($dataUpdated)) { 215 | checkAndUpdateResource($dataVer); 216 | } 217 | -------------------------------------------------------------------------------- /bang/resource_fetch.php: -------------------------------------------------------------------------------- 1 | '/^characters\/resourceset\/res(\d+)$/', 'namePrefix'=>'$1_', 'nameMatch'=>'/^(.+)$/', 'exportTo'=>'card/$1' ], 8 | [ 'bundleNameMatch'=>'/^title\/(.+)$/', 'namePrefix'=>'$1_', 'nameMatch'=>'/^(.+?)_title_bg$/', 'exportTo'=>'title_bg/$1', 'extraParamCb'=>function(&$item){return ($item->width==$item->height)?'-s '.$item->width.'x'.($item->width/16*10):'';} ] 9 | ]; 10 | 11 | function shouldExportFile($name, $rule) { 12 | return preg_match($rule['nameMatch'], $name) != 0; 13 | } 14 | 15 | $cacheHashDb = new PDO('sqlite:'.__DIR__.'/cacheHash.db'); 16 | $chkHashStmt = $cacheHashDb->prepare('SELECT hash FROM cacheHash WHERE res=?'); 17 | function shouldUpdate($name, $hash) { 18 | global $chkHashStmt; 19 | $chkHashStmt->execute([$name]); 20 | $row = $chkHashStmt->fetch(); 21 | return !(!empty($row) && $row['hash'] == $hash); 22 | } 23 | $setHashStmt = $cacheHashDb->prepare('REPLACE INTO cacheHash (res,hash) VALUES (?,?)'); 24 | function setHashCached($name, $hash) { 25 | global $setHashStmt; 26 | $setHashStmt->execute([$name, $hash]); 27 | } 28 | 29 | function findRule($name, $rules) { 30 | foreach ($rules as $rule) { 31 | if (preg_match($rule['bundleNameMatch'], $name) != 0) return $rule; 32 | } 33 | return false; 34 | } 35 | 36 | $chkTextureHashStmt = $cacheHashDb->prepare('SELECT hash FROM textureHash WHERE res=?'); 37 | function textureHasUpdated($name, Texture2D &$item) { 38 | global $chkTextureHashStmt; 39 | $hash = crc32($item->imageData); 40 | $item->imageDataHash = $hash; 41 | $chkTextureHashStmt->execute([$name]); 42 | $row = $chkTextureHashStmt->fetch(); 43 | return !(!empty($row) && $row['hash'] == $hash); 44 | } 45 | $setTextureHashStmt = $cacheHashDb->prepare('REPLACE INTO textureHash (res,hash) VALUES (?,?)'); 46 | function updateTextureHash($name, Texture2D &$item) { 47 | global $setTextureHashStmt; 48 | $setTextureHashStmt->execute([$name, $item->imageDataHash]); 49 | } 50 | 51 | define('RESOURCE_PATH_PREFIX', '/data/home/web/_redive/bang/'); 52 | //define('RESOURCE_PATH_PREFIX', 'D:/cygwin64/home/ester/quickcode/bang/img/'); 53 | 54 | function checkAndUpdateResource($dataVer) { 55 | global $resourceToExport; 56 | global $curl; 57 | chdir(__DIR__); 58 | $currenttime = time(); 59 | curl_setopt_array($curl, array( 60 | CURLOPT_CONNECTTIMEOUT=>5, 61 | CURLOPT_ENCODING=>'gzip', 62 | CURLOPT_RETURNTRANSFER=>true, 63 | CURLOPT_HEADER=>0, 64 | CURLOPT_SSL_VERIFYPEER=>false 65 | )); 66 | $manifest = json_decode(file_get_contents('data/AssetBundleInfo.json'), true); 67 | 68 | foreach ($manifest['bundles'] as $name => $info) { 69 | if (($rule = findRule($name, $resourceToExport)) !== false && shouldUpdate($name, $info['crc'])) { 70 | _log('download '. $name); 71 | curl_setopt_array($curl, array( 72 | CURLOPT_URL=>'https://content.garupa.jp/Release/'.$dataVer.'/iOS/'.$info['bundleName'], 73 | )); 74 | $bundleData = curl_exec($curl); 75 | if (strlen($bundleData) != $info['fileSize']) { 76 | _log('download failed '.$name); 77 | continue; 78 | } 79 | $bundleData = new MemoryStream($bundleData); 80 | $assets = extractBundle($bundleData); 81 | 82 | try{ 83 | 84 | foreach ($assets as $asset) { 85 | if (substr($asset, -5,5) == '.resS') continue; 86 | $asset = new AssetFile($asset); 87 | 88 | foreach ($asset->preloadTable as &$item) { 89 | if ($item->typeString == 'Texture2D') { 90 | try { 91 | $item = new Texture2D($item, true); 92 | } catch (Exception $e) { continue; } 93 | $itemname = $item->name; 94 | if (isset($rule['namePrefix'])) { 95 | $itemname = preg_replace($rule['bundleNameMatch'], $rule['namePrefix'], $name).$itemname; 96 | } 97 | if (isset($rule['print'])) { 98 | var_dump($itemname); 99 | continue; 100 | } 101 | if (shouldExportFile($itemname, $rule) && textureHasUpdated("$name:$itemname", $item)) { 102 | $saveTo = RESOURCE_PATH_PREFIX. preg_replace($rule['nameMatch'], $rule['exportTo'], $itemname); 103 | $param = '-lossless 1'; 104 | if (isset($rule['extraParam'])) $param .= ' '.$rule['extraParam']; 105 | if (isset($rule['extraParamCb'])) @$param .= ' '.call_user_func($rule['extraParamCb'], $item); 106 | $item->exportTo($saveTo, 'webp', $param); 107 | if (!file_exists($saveTo. '.webp')) throw new Exception('Error exporting'); 108 | if (filemtime($saveTo. '.webp') > $currenttime) 109 | touch($saveTo. '.webp', $currenttime); 110 | updateTextureHash("$name:$itemname", $item); 111 | } 112 | unset($item); 113 | } 114 | } 115 | $asset->__desctruct(); 116 | unset($asset); 117 | gc_collect_cycles(); 118 | } 119 | 120 | } catch(Exception $e) { 121 | $asset->__desctruct(); 122 | unset($asset); 123 | _log('Not supported: '. $e->getMessage()); 124 | } 125 | 126 | foreach ($assets as $asset) { 127 | unlink($asset); 128 | } 129 | unset($bundleData); 130 | //if (isset($rule['print'])) exit; 131 | setHashCached($name, $info['crc']); 132 | } 133 | } 134 | } 135 | 136 | if (defined('TEST_SUITE') && TEST_SUITE == __FILE__) { 137 | chdir(__DIR__); 138 | $curl = curl_init(); 139 | function _log($s) {echo "$s\n";} 140 | var_dump(trim(file_get_contents('data/!dataVersion.txt'))); 141 | $verHash = trim(file_get_contents('version_hash.txt')); 142 | checkAndUpdateResource(trim(file_get_contents('data/!dataVersion.txt')).'_'.$verHash); 143 | /*$asset = new AssetFile('CAB-4856cccde53d6f3bfd0054253f1639a8'); 144 | foreach ($asset->preloadTable as &$item) { 145 | if ($item->typeString == 'Texture2D') { 146 | $item = new Texture2D($item, true); 147 | _log($item->name); 148 | $item->exportTo($item->name, 'webp', '-lossless 1'); 149 | } 150 | }*/ 151 | } 152 | //print_r($asset); 153 | 154 | -------------------------------------------------------------------------------- /bang/version_hash.txt: -------------------------------------------------------------------------------- 1 | 6d6d727758ad125a554e8c062d418ba83e7b7ba74d3747543dc41f18a36fc53d -------------------------------------------------------------------------------- /cgss/eventrank/README.md: -------------------------------------------------------------------------------- 1 | ## CGSS Event Rank Border Data 2 | https://redive.estertion.win/cgss/rank_border/ 3 | -------------------------------------------------------------------------------- /cgss/eventrank/data/highcharts.js: -------------------------------------------------------------------------------- 1 | /* 2 | Highcharts JS v6.0.1 (2017-10-05) 3 | 4 | (c) 2009-2016 Torstein Honsi 5 | 6 | License: www.highcharts.com/license 7 | */ 8 | /* 9 | placeholder js 10 | */ -------------------------------------------------------------------------------- /cgss/eventrank/data/index.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CGSS event rank border 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 |
13 |
14 | 15 | -------------------------------------------------------------------------------- /cgss/eventrank/data/main.css: -------------------------------------------------------------------------------- 1 | html,body{ 2 | background:#10100B; 3 | color:#FFF; 4 | margin:0; 5 | font-family:-apple-system,Arial,'PingFang SC','STHeiti Light','Hiragino Kaku Gothic ProN','Microsoft YaHei',sans-serif; 6 | cursor:default 7 | } 8 | .heading{ 9 | background:#474747; 10 | height:40px; 11 | width:100%; 12 | position:fixed; 13 | top:0; 14 | left:0; 15 | border-bottom:1px solid #333; 16 | text-align:center; 17 | z-index:1 18 | } 19 | .head_select { 20 | color: #FFF; 21 | padding: 5px; 22 | border-radius: 2px; 23 | background:#10100B; 24 | height: 34px; 25 | margin: 2px auto; 26 | border: 1px solid #888; 27 | display: inline-block; 28 | font-size: 16px; 29 | line-height: 34px; 30 | white-space:pre; 31 | max-width:calc(100% - 44px); 32 | text-overflow:ellipsis; 33 | overflow:hidden; 34 | font-family:Arial,Meiryo 35 | } 36 | 37 | .content { 38 | margin-top: 41px; 39 | height: calc(100% - 41px); 40 | position: fixed; 41 | width: 100%; 42 | } 43 | 44 | @media screen and (max-width:800px){ 45 | html,body{ 46 | height:calc(100% + 1px) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /cgss/eventrank/data/main.js: -------------------------------------------------------------------------------- 1 | function _(type, props, children) { 2 | var elem = null; 3 | if (type === "text") { 4 | return document.createTextNode(props); 5 | } else { 6 | elem = document.createElement(type); 7 | } 8 | for (var n in props) { 9 | if (n === "style") { 10 | for (var x in props.style) { 11 | elem.style[x] = props.style[x]; 12 | } 13 | } else if (n === "className") { 14 | elem.className = props[n]; 15 | } else if (n === "event") { 16 | for (var x in props.event) { 17 | elem.addEventListener(x, props.event[x]); 18 | } 19 | } else { 20 | elem.setAttribute(n, props[n]); 21 | } 22 | } 23 | if (children) { 24 | for (var i = 0; i < children.length; i++) { 25 | if (children[i] != null) 26 | elem.appendChild(children[i]); 27 | } 28 | } 29 | return elem; 30 | }; 31 | 32 | var timezoneOffset = (new Date).getTimezoneOffset(); 33 | var names = {}, list; 34 | function loadedIndex(data) { 35 | names = data.name; 36 | list = document.querySelector('select') 37 | data.available.forEach(function (i) { 38 | var option = _('option', { value: i }, [_('text', names[i])]); 39 | if (i == data.current) option.setAttribute('selected', ''); 40 | list.appendChild(option); 41 | }); 42 | list.firstChild.remove(); 43 | list.addEventListener('change', function () { 44 | var xhr = new XMLHttpRequest(); 45 | xhr.open('GET', list.value + '.json', true); 46 | xhr.responseType = 'json'; 47 | xhr.onload = function () { loadedData(xhr.response) }; 48 | xhr.send(); 49 | }); 50 | list.dispatchEvent(new Event('change')); 51 | } 52 | var chart; 53 | function loadedData(data) { 54 | var axises = [], series = [], keys, yAxis = 0; 55 | if (data.score) { 56 | axises.push({ 57 | allowDecimals: false, 58 | title: { 59 | text: 'score' 60 | }, 61 | lineColor: Highcharts.getOptions().colors[yAxis] 62 | }); 63 | keys = Object.keys(data.score); 64 | keys.sort(function (a, b) { return a - b; }); 65 | keys.forEach(function (i) { 66 | series.push({ 67 | name: 'score - ' + i, 68 | type: 'line', 69 | yAxis: yAxis, 70 | marker: { 71 | enabled: false 72 | }, 73 | data: data.score[i] 74 | }); 75 | }); 76 | yAxis++; 77 | } 78 | if (data.pt) { 79 | axises.push({ 80 | allowDecimals: false, 81 | title: { 82 | text: 'pt' 83 | }, 84 | lineColor: Highcharts.getOptions().colors[yAxis], 85 | opposite: !!yAxis 86 | }); 87 | keys = Object.keys(data.pt); 88 | keys.sort(function (a, b) { return a - b; }); 89 | keys.forEach(function (i) { 90 | series.push({ 91 | name: 'pt - ' + i, 92 | type: 'line', 93 | yAxis: yAxis, 94 | marker: { 95 | enabled: false 96 | }, 97 | data: data.pt[i], 98 | dashStyle: 'Dash' 99 | }); 100 | }); 101 | yAxis++; 102 | } 103 | if (chart) chart.destroy(); 104 | chart = new Highcharts.chart({ 105 | chart: { 106 | renderTo: document.querySelector('.content'), 107 | zoomType: "x", 108 | //backgroundColor: 'transparent' 109 | }, 110 | credits: { 111 | enabled: false 112 | }, 113 | type: 'line', 114 | xAxis: { 115 | type: 'datetime', 116 | dateTimeLabelFormats: { 117 | //day:'%H:%M', 118 | day: '%m/%d', 119 | hour: '%H:%M' 120 | } 121 | }, 122 | yAxis: axises, 123 | title: { 124 | text: null 125 | }, 126 | tooltip: { 127 | formatter: function () { 128 | var time = new Date(this.x + (timezoneOffset - (-9 * 60))*60*1e3), str = '', check = function (a) { return (a < 10 ? '0' : '') + a }; 129 | str += check(time.getDate()) + ' ' + check(time.getHours()) + ':' + check(time.getMinutes()) + '

'; 130 | if (!this.points) { 131 | str = check(time.getMonth() + 1) + '/' + check(time.getDate()) + '
'; 132 | str += ''; 133 | str += '
' + this.point.name + '' + this.y + '
'; 134 | return str; 135 | } 136 | this.points.forEach(function (i) { 137 | str += '' + i.series.name + '' + i.y + ''; 138 | }); 139 | str += ''; 140 | return str; 141 | }, 142 | shared: true, 143 | crosshairs: true, 144 | useHTML: true 145 | }, 146 | series: series, 147 | exporting: { 148 | filename: 'DereSute_event_border', 149 | enabled: true, 150 | buttons: { 151 | contextButton: { 152 | menuItems: [ 153 | 'downloadPNG', 154 | 'downloadJPEG', 155 | 'downloadSVG' 156 | ] 157 | } 158 | } 159 | } 160 | }); 161 | var legendGroupElement = chart.legend.group.element, prevFoundItem = null, prevFoundTime = 0; 162 | var legendClicker = function (e) { 163 | var findLegend = e.target, current = performance.now(); 164 | while (legendGroupElement.contains(findLegend)) { 165 | if (findLegend.classList.contains('highcharts-legend-item')) break; 166 | findLegend = findLegend.parentNode; 167 | } 168 | if (!legendGroupElement.contains(findLegend)) return; 169 | if (prevFoundItem != null && findLegend == prevFoundItem && current - prevFoundTime <= 500) { 170 | e.preventDefault(); 171 | e.stopPropagation(); 172 | var currentOn = 0; 173 | chart.legend.allItems.forEach(function (i) { 174 | i.visible && ++currentOn; 175 | }); 176 | chart.legend.allItems.forEach(function (i) { 177 | i.setVisible(currentOn <= 1 || i.legendGroup.element == findLegend, false); 178 | }) 179 | chart.redraw(); 180 | prevFoundItem = null; 181 | return; 182 | } 183 | prevFoundItem = findLegend; 184 | prevFoundTime = current; 185 | }; 186 | legendGroupElement.addEventListener('click', legendClicker); 187 | legendGroupElement.addEventListener('touchend', legendClicker); 188 | } 189 | 190 | window.addEventListener('load', function () { 191 | var xhr = new XMLHttpRequest(); 192 | xhr.open('GET', 'available.json', true); 193 | xhr.responseType = 'json'; 194 | xhr.onload = function () { loadedIndex(xhr.response); }; 195 | xhr.send(); 196 | Highcharts.setOptions({ 197 | global: { 198 | timezoneOffset: -9 * 60 199 | }, 200 | lang: { 201 | resetZoom: '重置缩放', 202 | resetZoomTitle: '重置缩放比例至1:1', 203 | thousandsSep: ',' 204 | } 205 | }); 206 | document.querySelector('.content').addEventListener('touchmove',function(e){e.preventDefault();}) 207 | }); 208 | 209 | -------------------------------------------------------------------------------- /cgss/eventrank/main.php: -------------------------------------------------------------------------------- 1 | 745B625l856B6417737l515;535;726A7217263;113@551n768l838:516m832;624A287p772p121o626:634466828748373881115683521611874'); 18 | 19 | account from stat 20 | $userID = "253867193"; 21 | $viewerID = "112284050"; 22 | $udid = "0c4eb0b4-cf99-43b5-a9b6-18550611b7dc"; 23 | */ 24 | 25 | $userID = "272779236"; 26 | $viewerID = "326646583"; 27 | $udid = unlolfuscate("002422<557=158>256o855?652;831=563?8557826o117=148<635B7217735>637p776p488:4747225C278=215?858k7377425>566C721C476l531>588A123m743n567o815A857m363o42673358426683716"); 28 | 29 | function _log($s) { 30 | //global $logFile; 31 | //fwrite($logFile, date('[m/d H:i] ').$s."\n"); 32 | echo $s."\n"; 33 | } 34 | function execQuery($db, $query) { 35 | $returnVal = []; 36 | $result = $db->query($query); 37 | $returnVal = $result->fetchAll(PDO::FETCH_ASSOC); 38 | return $returnVal; 39 | } 40 | 41 | function lolfuscate($s) { 42 | $mid = implode('',array_map(function($i){ 43 | return rand(0,9).rand(0,9).chr(ord($i)+10).rand(0,9); 44 | }, str_split($s))); 45 | $post = rand(10000000,99999999).rand(10000000,99999999); 46 | return sprintf('%04x', strlen($s)).$mid.$post; 47 | } 48 | function unlolfuscate($in) { 49 | $num = hexdec(substr($in, 0, 4)); 50 | $text = ''; 51 | for ($i=6; $i$body,'header'=>$header]; 103 | curl_setopt_array($curl, [ 104 | CURLOPT_URL=>'https://apis.game.starlight-stage.jp'.$path, 105 | CURLOPT_SSL_VERIFYPEER=>false, 106 | CURLOPT_HTTPHEADER=>$header, 107 | CURLOPT_POST=>true, 108 | CURLOPT_POSTFIELDS=>$body, 109 | CURLOPT_HEADER=>false, 110 | CURLOPT_RETURNTRANSFER=>true, 111 | CURLOPT_ENCODING=>'gzip, deflate' 112 | ]); 113 | $response = curl_exec($curl); 114 | 115 | $response = base64_decode($response); 116 | $key = substr($response, -32, 32); 117 | $iv = str_replace('-','',$udid); 118 | $response = msgpack_unpack(base64_decode(decrypt256(substr($response, 0, -32), $key, hex2bin($iv)))); 119 | return $response; 120 | } 121 | 122 | $db = new PDO('sqlite:../master.db'); 123 | 124 | $time = time(); 125 | $time -= $time % 900; 126 | $now = date('Y-m-d H:i:s', $time + 3600 - 50); // 第一个整点不获取 127 | $now_slight_after = date('Y-m-d H:i:s', $time + 3600 + 850); // 最后一个整点不获取 128 | 129 | //$now = '2018-05-06 00:00:00'; 130 | //$now_slight_before = '2018-05-06 00:00:00'; 131 | 132 | $current = execQuery($db, "SELECT * FROM event_data WHERE event_start < \"${now}\" AND event_end > \"${now}\""); 133 | if (empty($current)) { 134 | // final_result 135 | $current = execQuery($db, "SELECT * FROM event_data WHERE result_start < \"${now_slight_after}\" AND result_start > \"${now}\""); 136 | if (empty($current)) exit; 137 | } 138 | 139 | $current = $current[0]; 140 | $id = $current['id']; 141 | $type = $current['type']; 142 | 143 | $fetchPt = false; 144 | $fetchScore = false; 145 | switch ($type) { 146 | case 1: { 147 | $fetchPt = true; 148 | $fetchScore = true; 149 | $ptTable = 'atapon_point_rank_disp'; 150 | $scoreTable = 'atapon_score_rank_disp'; 151 | $path = '/event/atapon/ranking_list'; 152 | break; 153 | } 154 | case 3: { 155 | $fetchPt = true; 156 | $fetchScore = true; 157 | $ptTable = 'medley_point_rank_disp'; 158 | $scoreTable = 'medley_score_rank_disp'; 159 | $path = '/event/medley/ranking_list'; 160 | break; 161 | } 162 | case 5: { 163 | $fetchScore = true; 164 | $scoreTable = 'tour_score_rank_disp'; 165 | $path = '/event/tour/ranking_list'; 166 | break; 167 | } 168 | case 7: { 169 | $fetchPt = true; 170 | $ptTable = 'carnival_point_rank_disp'; 171 | $path = '/event/carnival/ranking_list'; 172 | break; 173 | } 174 | } 175 | 176 | $ptBorders=[]; 177 | if ($fetchPt) { 178 | foreach(execQuery($db, "SELECT rank_min FROM $ptTable WHERE event_id=$id") as $row) { 179 | $ptBorders[] = $row['rank_min']+0; 180 | } 181 | if (!in_array(501, $ptBorders)) $ptBorders[]= 501; 182 | } 183 | $scoreBorders=[1]; 184 | if ($fetchScore) { 185 | foreach(execQuery($db, "SELECT rank_max FROM $scoreTable WHERE event_id=$id") as $row) { 186 | $scoreBorders[] = $row['rank_max']+1; 187 | } 188 | } 189 | unset($db); 190 | gc_collect_cycles(); 191 | 192 | if (!$fetchPt && !$fetchScore) exit; 193 | 194 | $time = time(); 195 | $time -= $time%900; 196 | $time *= 1000; 197 | $availableEvents = ['current'=>$id, 'available'=>[], 'name'=>[]]; 198 | $eventData = []; 199 | if (file_exists("data/$id.json")) $eventData = json_decode(file_get_contents("data/$id.json"), true); 200 | if (file_exists("data/available.json")) $availableEvents = json_decode(file_get_contents("data/available.json"), true); 201 | if (!in_array($id, $availableEvents['available'])) { 202 | array_unshift($availableEvents['available'], $id); 203 | $availableEvents['name'][$id] = $current['name']; 204 | } 205 | $availableEvents['current'] = $id; 206 | file_put_contents("data/available.json", json_encode($availableEvents)); 207 | 208 | function saveTop($type, &$data) { 209 | global $eventData; 210 | global $time; 211 | if (!isset($eventData['top'])) $eventData['top']=[]; 212 | if (!isset($eventData['top'][$type])) $eventData['top'][$type]=[]; 213 | $currentPool = &$eventData['top'][$type]; 214 | 215 | foreach ($data['data']['ranking_list'] as &$player) { 216 | if (!isset($currentPool[$player['user_info']['viewer_id']])) 217 | $currentPool[$player['user_info']['viewer_id']] = [ 218 | 'info' => [], 219 | 'data' => [] 220 | ]; 221 | $currentPool[$player['user_info']['viewer_id']]['info'] = $player['user_info']; 222 | $currentPool[$player['user_info']['viewer_id']]['data'][] = [ 223 | $time, $player['score'] 224 | ]; 225 | } 226 | } 227 | 228 | if ($fetchPt) { 229 | if (!isset($eventData['pt'])) $eventData['pt'] = []; 230 | $max = 0; 231 | $missed=[]; 232 | foreach($ptBorders as $border) { 233 | $data = callapi($path, [ 234 | 'page'=>$border/10+1, 235 | 'ranking_type'=>1, 236 | 'timezone'=>'09:00:00' 237 | ]); 238 | if (isset($eventData['pt'][$border])) $max = $border; 239 | 240 | if (!isset($data['data']['ranking_list'][0])) { 241 | //var_dump($border); 242 | //print_r($data); 243 | $missed[] = $border; 244 | continue; 245 | } 246 | $max = $border; 247 | if (!isset($eventData['pt'][$border])) $eventData['pt'][$border] = []; 248 | $eventData['pt'][$border][] = [$time, $data['data']['ranking_list'][0]['score']]; 249 | if ($border == 1) saveTop('pt', $data); 250 | } 251 | //var_dump($max); 252 | //print_r($missed); 253 | foreach ($missed as $border) { 254 | if ($border > $max) continue; 255 | $retry = 0; 256 | while (1) { 257 | sleep(1); 258 | if ($retry++ > 5) break; 259 | $data = callapi($path, [ 260 | 'page'=>$border/10+1, 261 | 'ranking_type'=>1, 262 | 'timezone'=>'09:00:00' 263 | ]); 264 | if (!isset($data['data']['ranking_list'][0])) { 265 | //var_dump($border); 266 | continue; 267 | } 268 | if (!isset($eventData['pt'][$border])) $eventData['pt'][$border] = []; 269 | //echo $border.' '.$data['data']['ranking_list'][0]['score']."\n"; 270 | $eventData['pt'][$border][] = [$time, $data['data']['ranking_list'][0]['score']]; 271 | if ($border == 1) saveTop('pt', $data); 272 | break; 273 | } 274 | } 275 | } 276 | 277 | if ($fetchScore) { 278 | if (!isset($eventData['score'])) $eventData['score'] = []; 279 | $max = 0; 280 | $missed=[]; 281 | foreach($scoreBorders as $border) { 282 | $data = callapi($path, [ 283 | 'page'=>$border/10+1, 284 | 'ranking_type'=>2, 285 | 'timezone'=>'09:00:00' 286 | ]); 287 | if (isset($eventData['score'][$border])) $max = $border; 288 | 289 | if (!isset($data['data']['ranking_list'][0])) { 290 | //var_dump($border); 291 | //print_r($data); 292 | $missed[] = $border; 293 | continue; 294 | } 295 | if (!isset($eventData['score'][$border])) $eventData['score'][$border] = []; 296 | $eventData['score'][$border][] = [$time, $data['data']['ranking_list'][0]['score']]; 297 | if ($border == 1) saveTop('score', $data); 298 | } 299 | //var_dump($max); 300 | //print_r($missed); 301 | foreach ($missed as $border) { 302 | if ($border > $max) continue; 303 | $retry = 0; 304 | while (1) { 305 | sleep(1); 306 | if ($retry++ > 5) break; 307 | $data = callapi($path, [ 308 | 'page'=>$border/10+1, 309 | 'ranking_type'=>2, 310 | 'timezone'=>'09:00:00' 311 | ]); 312 | if (!isset($data['data']['ranking_list'][0])) { 313 | //var_dump($border); 314 | continue; 315 | } 316 | if (!isset($eventData['score'][$border])) $eventData['score'][$border] = []; 317 | //echo $border.' '.$data['data']['ranking_list'][0]['score']."\n"; 318 | $eventData['score'][$border][] = [$time, $data['data']['ranking_list'][0]['score']]; 319 | if ($border == 1) saveTop('score', $data); 320 | break; 321 | } 322 | } 323 | } 324 | 325 | $filedata = json_encode($eventData); 326 | file_put_contents("data/$id.json", $filedata); 327 | file_put_contents("data/$id.json.br", brotli_compress($filedata, 11, BROTLI_TEXT)); 328 | file_put_contents("data/$id.json.gz", gzencode($filedata, 9)); 329 | -------------------------------------------------------------------------------- /cgss/resource_fetch.php: -------------------------------------------------------------------------------- 1 | '/^card_bg_\d+.unity3d$/', 'nameMatch'=>'/^bg_(\d+)$/', 'exportTo'=>'card/$1' ], 9 | [ 'bundleNameMatch'=>'/^chara_(\d{3}_\d{2})_base.unity3d$/', 'namePrefixCb'=>function ($s)use(&$poseData){return isset($poseData[$s[1]])?$poseData[$s[1]]:$s[1];}, 'nameMatch'=>'/^([\d_]+\d).+?$/', 'exportTo'=>'card/$1_trim' ], 10 | [ 'bundleNameMatch'=>'/^latte_art_page_\d+.unity3d$/', 'nameMatch'=>'/^latte_art_page_(\d+)_(\d+)$/', 'exportTo'=>'gekijou/$1/$2' ], 11 | [ 'bundleNameMatch'=>'/^title_bg_\d+.unity3d$/', 'nameMatch'=>'/^(\d+)$/', 'exportTo'=>'title/$1' ], 12 | ]; 13 | 14 | function shouldExportFile($name, $rule) { 15 | return preg_match($rule['nameMatch'], $name) != 0; 16 | } 17 | 18 | $cacheHashDb = new PDO('sqlite:'.__DIR__.'/cacheHash.db'); 19 | $chkHashStmt = $cacheHashDb->prepare('SELECT hash FROM cacheHash WHERE res=?'); 20 | function shouldUpdate($name, $hash) { 21 | global $chkHashStmt; 22 | $chkHashStmt->execute([$name]); 23 | $row = $chkHashStmt->fetch(); 24 | return !(!empty($row) && $row['hash'] == $hash); 25 | } 26 | $setHashStmt = $cacheHashDb->prepare('REPLACE INTO cacheHash (res,hash) VALUES (?,?)'); 27 | function setHashCached($name, $hash) { 28 | global $setHashStmt; 29 | $setHashStmt->execute([$name, $hash]); 30 | } 31 | 32 | function findRule($name, $rules) { 33 | foreach ($rules as $rule) { 34 | if (preg_match($rule['bundleNameMatch'], $name) != 0) return $rule; 35 | } 36 | return false; 37 | } 38 | 39 | define('RESOURCE_PATH_PREFIX', '/data/home/web/_redive/cgss/'); 40 | //define('RESOURCE_PATH_PREFIX', 'D:/cygwin64/home/ester/quickcode/cgss/'); 41 | 42 | function checkAndUpdateResource() { 43 | global $resourceToExport; 44 | $curl = curl_init(); 45 | global $poseData; 46 | chdir(__DIR__); 47 | $currenttime = time(); 48 | curl_setopt_array($curl, array( 49 | CURLOPT_CONNECTTIMEOUT=>5, 50 | CURLOPT_HTTPHEADER=>['X-Unity-Version: 2020.3.8f1'], 51 | CURLOPT_RETURNTRANSFER=>true, 52 | CURLOPT_HEADER=>0, 53 | CURLOPT_SSL_VERIFYPEER=>false, 54 | CURLOPT_FILETIME=>true 55 | )); 56 | $manifest = new PDO('sqlite:manifest.db');; 57 | 58 | foreach (execQuery($manifest, 'SELECT name,hash FROM manifests') as $info) { 59 | $name = $info['name']; 60 | $hash = $info['hash']; 61 | if (($rule = findRule($name, $resourceToExport)) !== false && shouldUpdate($name, $hash)) { 62 | _log('download '. $name); 63 | curl_setopt_array($curl, array( 64 | CURLOPT_URL=>'https://asset-starlight-stage.akamaized.net/dl/resources/AssetBundles/'.substr($hash, 0, 2).'/'.$hash, 65 | )); 66 | $bundleData = curl_exec($curl); 67 | $bundleTime = curl_getinfo($curl, CURLINFO_FILETIME); 68 | $bundleTime -= $bundleTime % 60; 69 | $gotHash = hash('md5', $bundleData); 70 | if ($gotHash != $hash) { 71 | _log('download failed '.$name." expected $hash got $gotHash"); 72 | continue; 73 | } 74 | $bundleData = new MemoryStream(cgss_data_uncompress($bundleData)); 75 | $assets = extractBundle($bundleData); 76 | 77 | try{ 78 | 79 | foreach ($assets as $asset) { 80 | if (substr($asset, -5,5) == '.resS') continue; 81 | $asset = new AssetFile($asset); 82 | 83 | foreach ($asset->preloadTable as &$item) { 84 | if ($item->typeString == 'Texture2D') { 85 | $item = new Texture2D($item, true); 86 | if (isset($rule['print'])) { 87 | var_dump($item->name); 88 | continue; 89 | } 90 | $itemname = $item->name; 91 | if (isset($rule['namePrefix'])) { 92 | $itemname = preg_replace($rule['bundleNameMatch'], $rule['namePrefix'], $name).$itemname; 93 | } 94 | if (isset($rule['namePrefixCb'])) { 95 | $itemname = preg_replace_callback($rule['bundleNameMatch'], $rule['namePrefixCb'], $name).$itemname; 96 | } 97 | if (shouldExportFile($itemname, $rule)) { 98 | $saveTo = RESOURCE_PATH_PREFIX. preg_replace($rule['nameMatch'], $rule['exportTo'], $itemname); 99 | $item->exportTo($saveTo, 'webp', '-lossless 1'); 100 | touch($saveTo. '.webp', $bundleTime); 101 | } 102 | unset($item); 103 | } 104 | } 105 | $asset->__desctruct(); 106 | unset($asset); 107 | gc_collect_cycles(); 108 | } 109 | 110 | } catch(Exception $e) { 111 | $asset->__desctruct(); 112 | unset($asset); 113 | _log('Not supported: '. $e->getMessage()); 114 | } 115 | 116 | foreach ($assets as $asset) { 117 | unlink($asset); 118 | } 119 | unset($bundleData); 120 | if (isset($rule['print'])) exit; 121 | setHashCached($name, $hash); 122 | } 123 | } 124 | } 125 | 126 | if (defined('TEST_SUITE') && TEST_SUITE == __FILE__) { 127 | chdir(__DIR__); 128 | $curl = curl_init(); 129 | function _log($s) {echo "$s\n";} 130 | function cgss_data_uncompress($data) { 131 | $data = new MemoryStream($data); 132 | $data->littleEndian = true; 133 | $num1 = $data->long; 134 | $uncompressedSize = $data->long; 135 | $data->long; 136 | $num2 = $data->long; 137 | if ($num1 != 100 || $num2 != 1) { 138 | _log('invalid data'); 139 | exit; 140 | } 141 | $uncompressed = lz4_uncompress_stream($data->readData($data->size - 16), $uncompressedSize); 142 | unset($data); 143 | return $uncompressed; 144 | } 145 | function execQuery($db, $query) { 146 | $returnVal = []; 147 | $result = $db->query($query); 148 | $returnVal = $result->fetchAll(PDO::FETCH_ASSOC); 149 | return $returnVal; 150 | } 151 | $db = new PDO('sqlite:master.db'); 152 | $poseData=[]; 153 | foreach(execQuery($db, 'SELECT id,name,chara_id,pose FROM card_data') as $row) { 154 | $poseData[sprintf('%03d_%02d', $row['chara_id'], $row['pose'])] = $row['id']; 155 | } 156 | unset($db); 157 | checkAndUpdateResource(); 158 | //print_r(extractBundle(new FileStream('bundle/-card_bg_100062.unity3d'))); 159 | /*$asset = new AssetFile('CAB-ed8bb316f8c8bc10b8cb0f403c1e3f35'); 160 | foreach ($asset->preloadTable as &$item) { 161 | if ($item->typeString == 'Texture2D') { 162 | $item = new Texture2D($item, true); 163 | _log($item->name); 164 | $item->exportTo($item->name, 'bmp'); 165 | } 166 | }*/ 167 | } 168 | //print_r($asset); 169 | 170 | -------------------------------------------------------------------------------- /dankagu/convert_db.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | flatc_binary=/data/home/web/_redive/cron/dankagu/flatc/flatc 4 | schema_dir=/data/home/web/_redive/cron/dankagu/schema 5 | 6 | for a in ../*.raw; do 7 | 8 | fname=${a#../} 9 | fname=${fname%.raw} 10 | name=${fname%-*} 11 | echo $fname 12 | $flatc_binary --json $schema_dir/${name}Raw.fbs -- ../$fname.raw 13 | 14 | done 15 | 16 | sed -i -E -e 's/ (\w*):/ "\1":/g' *.json -------------------------------------------------------------------------------- /dankagu/main.php: -------------------------------------------------------------------------------- 1 | '0'); 12 | } else { 13 | $last_version = json_decode(file_get_contents('last_version.json'), true); 14 | } 15 | 16 | $logFile = fopen('dankagu.log', 'a'); 17 | function _log($s) { 18 | global $logFile; 19 | fwrite($logFile, date('[m/d H:i] ').$s."\n"); 20 | echo $s."\n"; 21 | } 22 | 23 | $exe = "E:\\VS\\danmaku\\build\\MinSizeRel\\danmaku"; 24 | $exe = "./danmaku"; 25 | $exeConfig = json_decode(file_get_contents('danmaku.json'), true); 26 | list($appVer, $assetKey, $gameId) = [$exeConfig['app_ver'], $exeConfig['asset_key'], $exeConfig['game_id']]; 27 | 28 | exec("$exe get_root $appVer > net-root.json"); 29 | exec("$exe get_filelist $appVer AssetUploadV2+$assetKey+g$gameId > net-filelist.json"); 30 | 31 | $filelist = json_decode(file_get_contents('net-filelist.json'), true); 32 | if (empty($filelist)) exit; 33 | 34 | $latest_filelist = ['Date'=>0]; 35 | foreach ($filelist['Uploads'] as $i) { 36 | if ($i['Date'] > $latest_filelist['Date']) { 37 | $latest_filelist = $i; 38 | } 39 | } 40 | 41 | $dataVersions = array_reduce($latest_filelist['FileList'], function ($c, $i){$c[$i['DataVersion']] = $i['OpenAt'];return $c;}, []); 42 | $currentDataVer = [0,0]; 43 | $now = time(); 44 | foreach ($dataVersions as $v=>$t) { 45 | if ($t > $currentDataVer[1] && $t < $now) { 46 | $currentDataVer = [$v, $t]; 47 | } 48 | } 49 | $currentDataVer = $currentDataVer[0]; 50 | $manifestUrls = array_values(array_filter($latest_filelist['FileList'], function ($i) use($currentDataVer) { 51 | return $i['DataVersion'] == $currentDataVer && substr($i['DB'], 0, 5) === 'arg_m'; 52 | })); 53 | 54 | $dataVer = $currentDataVer; 55 | $assetDir = $latest_filelist['Path']; 56 | $assetDir = "/assets/$assetDir/data"; 57 | $assetDate = pathinfo(dirname($assetDir), PATHINFO_BASENAME); 58 | 59 | $dataVerNum = $dataVer; 60 | $dataVer = "$dataVer-$assetDate"; 61 | 62 | if ($dataVer != $last_version['data']) { 63 | 64 | _log("data ver $dataVer, downloading manifest"); 65 | $header = [ 66 | 'User-Agent: dankagu/1.0.311 CFNetwork/1126 Darwin/19.5.0', 67 | 'X-Unity-Version: 2019.4.14f1' 68 | ]; 69 | $curl = curl_init(); 70 | curl_setopt_array($curl, array( 71 | //CURLOPT_PROXY=>'127.0.0.1:23456', 72 | //CURLOPT_PROXYTYPE=>CURLPROXY_SOCKS5, 73 | CURLOPT_SSL_VERIFYPEER=>false, 74 | CURLOPT_HEADER=>false, 75 | CURLOPT_RETURNTRANSFER=>true, 76 | CURLOPT_HTTPHEADER=>$header 77 | )); 78 | 79 | $manifestList = []; 80 | $lwe = Encryptor::$encryptors[1004]; 81 | $rijn = Encryptor::$encryptors[1001]; 82 | 83 | $rijnPwd = 'Pg97xygbey7aw'; 84 | $rijnSalt = '857fesfd'; 85 | $rijnIter = 117; 86 | $buf = openssl_pbkdf2($rijnPwd, $rijnSalt, 32, $rijnIter); 87 | $rijnKey = substr($buf, 0, 16); 88 | $rijnIv = substr($buf, 16, 16); 89 | 90 | foreach ($manifestUrls as $item) { 91 | $url = $assetDir.'/'.$item['HashPath']; 92 | $category = pathinfo(dirname(dirname($url)), PATHINFO_FILENAME); 93 | curl_setopt($curl, CURLOPT_URL, ASSET_DOMAIN.$url); 94 | $fData = curl_exec($curl); 95 | $salt = $item['Salt']; 96 | $lwe->Modify($fData, 0, strlen($fData), 0, $salt); 97 | $fData = $rijn->Transform($fData, 0, strlen($fData)); 98 | if ($data = gzdecode($fData)) { 99 | $size = octdec(substr($data, 124, 11)); 100 | $data = substr($data, 512, $size); 101 | $bb = ByteBuffer::wrap($data); 102 | $apr = AssetPathRaw::getRootAsAssetPathRaw($bb); 103 | if (!isset($manifestList[$category]) || $apr->getEntryLength() > $manifestList[$category]->getEntryLength()) { 104 | $manifestList[$category] = $apr; 105 | } 106 | } 107 | } 108 | 109 | foreach ($manifestList as $category=>$apr) { 110 | $count = $apr->getEntryLength(); 111 | $entries = []; 112 | for ($j=0; $j<$count; $j++) { 113 | $entry = $apr->getEntry($j); 114 | $entry = [ 115 | 'ID' => $entry->getID(), 116 | 'AssetPath' => $entry->getAssetPath(), 117 | 'HashedPath' => $entry->getHashedPath(), 118 | 'FileHash' => $entry->getFileHash(), 119 | 'FileSize' => $entry->getFileSize(), 120 | 'FileRev' => $entry->getFileRev(), 121 | 'FileType' => $entry->getFileType(), 122 | 'DownloadOption' => $entry->getDownloadOption(), 123 | ]; 124 | $entries[] = $entry; 125 | } 126 | $manifestList[$category] = $entries; 127 | } 128 | 129 | _log("done"); 130 | file_put_contents("manifest/$dataVer.json", json_encode(['assetDir' => $assetDir, 'manifest' => $manifestList], JSON_UNESCAPED_SLASHES)); 131 | $last_version['data'] = $dataVer; 132 | file_put_contents('last_version.json', json_encode($last_version)); 133 | 134 | checkAndUpdateResource($dataVer); 135 | 136 | $current = glob("master/*".str_pad($dataVerNum, 8, '0', STR_PAD_LEFT).'*'); 137 | if (count($current)) { 138 | chdir(array_reverse($current)[0]); 139 | $messages = json_decode(file_get_contents('MessageMap-parsed.json'), true); 140 | 141 | $out = []; 142 | foreach ($messages['Music']['Title'] as $id=>$name) { 143 | $out[str_pad($id, 8, '0', STR_PAD_LEFT)] = "$name - ".$messages['Music']['Circle'][$id]; 144 | } 145 | file_put_contents(RESOURCE_PATH_PREFIX.'jacket/index.json', json_encode($out)); 146 | 147 | $musicscore = json_decode(file_get_contents('MusicScore.json'), true); 148 | $out = []; 149 | foreach ($musicscore['Entries'] as $entry) { 150 | $mid = floor($entry['ID'] / 10000); 151 | if (!isset($out[$mid])) $out[$mid] = [0]; 152 | $out[$mid][$entry['ID']%10000] = $entry['MusicLevel']; 153 | } 154 | file_put_contents(RESOURCE_PATH_PREFIX.'jacket/index-level.json', json_encode($out)); 155 | 156 | $creators = $messages['CreaterName']['CreaterName']; 157 | $music = json_decode(file_get_contents('Music.json'), true); 158 | $out = []; 159 | foreach ($music['Entries'] as $entry) { 160 | $mid = floor($entry['ID']); 161 | $out[$mid] = $creators[$entry['CreaterNo']?:0]; 162 | } 163 | file_put_contents(RESOURCE_PATH_PREFIX.'jacket/index-cd.json', json_encode($out)); 164 | 165 | $cardInfo = json_decode(file_get_contents('Card.json'), true)['Entries']; 166 | $out = []; 167 | foreach ($cardInfo as $card) { 168 | $id = $card['ID']; 169 | $rarity = ['', 'N','R','SR','SSR'][$card['Rarity']]; 170 | $out[str_pad($id, 8, '0', STR_PAD_LEFT)] = "$rarity ".$messages['Card']['Name'][$id]; 171 | } 172 | file_put_contents(RESOURCE_PATH_PREFIX.'card/index.json', json_encode($out)); 173 | } 174 | } 175 | 176 | -------------------------------------------------------------------------------- /dankagu/schema/ActiveSkillRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ActiveSkillRawEntry { 4 | ID:int32; 5 | Rarity:int32; 6 | Strength:int32; 7 | EffectType:int32; 8 | Name:string; 9 | Description:string; 10 | Class1:int32; 11 | Type1:int32; 12 | Param11:int32; 13 | Param12:int32; 14 | Param13:int32; 15 | Param14:int32; 16 | FlParam11Array:[int32]; 17 | FlParam12Array:[int32]; 18 | FlParam13Array:[int32]; 19 | FlParam14Array:[int32]; 20 | TestParam1Array:[int32]; 21 | Condition1:int32; 22 | Class2:int32; 23 | Type2:int32; 24 | Param21:int32; 25 | Param22:int32; 26 | Param23:int32; 27 | Param24:int32; 28 | FlParam21Array:[int32]; 29 | FlParam22Array:[int32]; 30 | FlParam23Array:[int32]; 31 | FlParam24Array:[int32]; 32 | TestParam2Array:[int32]; 33 | Condition2:int32; 34 | } 35 | 36 | table ActiveSkillRaw { 37 | Entries:[ActiveSkillRawEntry]; 38 | } 39 | 40 | file_identifier "D4AO"; 41 | root_type ActiveSkillRaw; 42 | 43 | -------------------------------------------------------------------------------- /dankagu/schema/AdMobExpeditionRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table AdMobExpeditionRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | MaxShowCountExpedition:int32; 10 | ExpeditionShortCutVCPrice:int32; 11 | ExpeditionShortCutTime:int32; 12 | } 13 | 14 | table AdMobExpeditionRaw { 15 | Entries:[AdMobExpeditionRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type AdMobExpeditionRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/AdMobGachaSettingRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table AdMobGachaSettingRawEntry { 4 | ID:int64; 5 | DataVersion:int32; 6 | Enable:int32; 7 | GachaID:int32; 8 | GachaProductID:string; 9 | OpenAt:int64; 10 | CloseAt:int64; 11 | Price:int32; 12 | ImageID:int32; 13 | PickupIdAndCount:[int32]; 14 | } 15 | 16 | table AdMobGachaSettingRaw { 17 | Entries:[AdMobGachaSettingRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type AdMobGachaSettingRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/AdMobMovieSettingRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table AdMobMovieSettingRawEntry { 4 | ID:int64; 5 | Enable:int32; 6 | IsDefault:int32; 7 | MaxShowCountHome:int32; 8 | GetAdPoint:[int32]; 9 | ContinueBonus:int32; 10 | } 11 | 12 | table AdMobMovieSettingRaw { 13 | Entries:[AdMobMovieSettingRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type AdMobMovieSettingRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/AdMobSpecialChanceRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table AdMobSpecialChanceRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | SpecialChanceTime:int64; 10 | StepRewardGroup:int32; 11 | StepShowCount:[int32]; 12 | StepRate:[int32]; 13 | CoolDay:int32; 14 | } 15 | 16 | table AdMobSpecialChanceRaw { 17 | Entries:[AdMobSpecialChanceRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type AdMobSpecialChanceRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/AdMobStepRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table AdMobStepRewardRawEntry { 4 | ID:int32; 5 | StepNo:int32; 6 | ItemPrefix:int32; 7 | ItemValue:int32; 8 | ItemCount:int32; 9 | StepRewardGroup:int32; 10 | } 11 | 12 | table AdMobStepRewardRaw { 13 | Entries:[AdMobStepRewardRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type AdMobStepRewardRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/AssetPathRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table AssetPathRawEntry { 4 | ID:int64; 5 | AssetPath:string; 6 | HashedPath:string; 7 | FileHash:string; 8 | FileSize:int32; 9 | FileRev:int32; 10 | FileType:int32; 11 | DownloadOption:int32; 12 | } 13 | 14 | table AssetPathRaw { 15 | Entries:[AssetPathRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type AssetPathRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/AwakeBonusRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table AwakeBonusRawEntry { 4 | ID:int32; 5 | TotalFrom:int32; 6 | TotalTo:int32; 7 | FlUpPer:int32; 8 | } 9 | 10 | table AwakeBonusRaw { 11 | Entries:[AwakeBonusRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type AwakeBonusRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/AwakeItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table AwakeItemRawEntry { 4 | ID:int32; 5 | Item1ID:int32; 6 | Item1Count:int32; 7 | Item2ID:int32; 8 | Item2Count:int32; 9 | Item3ID:int32; 10 | Item3Count:int32; 11 | Item4ID:int32; 12 | Item4Count:int32; 13 | Cost:int32; 14 | UnlockType1:int32; 15 | UnlockType2:int32; 16 | } 17 | 18 | table AwakeItemRaw { 19 | Entries:[AwakeItemRawEntry]; 20 | } 21 | 22 | file_identifier "D4AO"; 23 | root_type AwakeItemRaw; 24 | 25 | -------------------------------------------------------------------------------- /dankagu/schema/AwakeRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table AwakeRawEntry { 4 | ID:int32; 5 | AwakeItem1ID:int32; 6 | AwakeItem2ID:int32; 7 | AwakeItem3ID:int32; 8 | AwakeItem4ID:int32; 9 | AwakeItem5ID:int32; 10 | AwakeItem6ID:int32; 11 | } 12 | 13 | table AwakeRaw { 14 | Entries:[AwakeRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type AwakeRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/BarrageBulletDataRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table BarrageBulletDataRawEntry { 4 | ID:int32; 5 | Path:string; 6 | Name:string; 7 | IsActive:int32; 8 | SeCueName:string; 9 | SeCueID:int32; 10 | TotalNumOfAnims:int32; 11 | NumOfAnimWraps:int32; 12 | AddAnimPosX:int32; 13 | AddAnimPosY:int32; 14 | } 15 | 16 | table BarrageBulletDataRaw { 17 | Entries:[BarrageBulletDataRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type BarrageBulletDataRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/BarrageCommonDataRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table BarrageCommonDataRawEntry { 4 | ID:int32; 5 | PointPosZ:float; 6 | TouchPointChangeSpeedBase:float; 7 | TouchPointChangeSpeed:float; 8 | TouchPointFallFrame:float; 9 | BreakPointMoveSpeed:float; 10 | BreakPointWaitFrame:float; 11 | PowerValuePlanA:int32; 12 | PointGenerateRange:float; 13 | ShotDelayTimePlanA:float; 14 | LineEffectTime:float; 15 | DeleteRangePlanA:float; 16 | RippleInitSize:float; 17 | RippleSize:float; 18 | RippleSpeed:float; 19 | RippleOffset:float; 20 | BBMainCharacter:int32; 21 | } 22 | 23 | table BarrageCommonDataRaw { 24 | Entries:[BarrageCommonDataRawEntry]; 25 | } 26 | 27 | file_identifier "D4AO"; 28 | root_type BarrageCommonDataRaw; 29 | 30 | -------------------------------------------------------------------------------- /dankagu/schema/BarrageDataRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table BarrageDataRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | IdName:string; 8 | BarrageName:string; 9 | PrefabName:string; 10 | UseCommonTexture:bool; 11 | } 12 | 13 | table BarrageDataRaw { 14 | Entries:[BarrageDataRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type BarrageDataRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/BingoCharacterMessageRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table BingoCharacterMessageRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | MessageTable:[string]; 8 | } 9 | 10 | table BingoCharacterMessageRaw { 11 | Entries:[BingoCharacterMessageRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type BingoCharacterMessageRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/BlackBallCharacterRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table BlackBallCharacterRawEntry { 4 | ID:int32; 5 | Name:string; 6 | } 7 | 8 | table BlackBallCharacterRaw { 9 | Entries:[BlackBallCharacterRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type BlackBallCharacterRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/BonusMusicRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table BonusMusicRawEntry { 4 | ID:int32; 5 | OpenAt:int64; 6 | CloseAt:int64; 7 | PlayMusicIDs:[int32]; 8 | } 9 | 10 | table BonusMusicRaw { 11 | Entries:[BonusMusicRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type BonusMusicRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/BookVoiceCategoryRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table BookVoiceCategoryRawEntry { 4 | ID:int32; 5 | Name:string; 6 | } 7 | 8 | table BookVoiceCategoryRaw { 9 | Entries:[BookVoiceCategoryRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type BookVoiceCategoryRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/BookVoiceInfoRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table BookVoiceInfoRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | BookVoiceCategoryID:int32; 7 | Name:string; 8 | Priorty:int32; 9 | VoiceCount:int32; 10 | VoiceCuesheet:string; 11 | VoicePrefix:string; 12 | VoiceIDs:string; 13 | } 14 | 15 | table BookVoiceInfoRaw { 16 | Entries:[BookVoiceInfoRawEntry]; 17 | } 18 | 19 | file_identifier "D4AO"; 20 | root_type BookVoiceInfoRaw; 21 | 22 | -------------------------------------------------------------------------------- /dankagu/schema/BoostRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table BoostRawEntry { 4 | ID:int32; 5 | Type:int32; 6 | UseBoost:int32; 7 | FlExpBoostValue:int32; 8 | FlItemBoostValue:int32; 9 | } 10 | 11 | table BoostRaw { 12 | Entries:[BoostRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type BoostRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/BossRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table BossRawEntry { 4 | ID:int32; 5 | AssetName:string; 6 | HeroineID:int32; 7 | } 8 | 9 | table BossRaw { 10 | Entries:[BossRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type BossRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/CampaignCategoryRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CampaignCategoryRawEntry { 4 | ID:int32; 5 | CategoryName:string; 6 | } 7 | 8 | table CampaignCategoryRaw { 9 | Entries:[CampaignCategoryRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type CampaignCategoryRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/CampaignExpeditionBoostRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CampaignExpeditionBoostRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | Value:int32; 10 | ExpeditionRangeMinID:int32; 11 | ExpeditionRangeMaxID:int32; 12 | ExcludedExpeditionIDs:[int32]; 13 | ExcludedRewardItemIDs:[int32]; 14 | } 15 | 16 | table CampaignExpeditionBoostRaw { 17 | Entries:[CampaignExpeditionBoostRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type CampaignExpeditionBoostRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/CampaignRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CampaignRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVesion:int32; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | Category:int32; 10 | Value:int32; 11 | Context:string; 12 | } 13 | 14 | table CampaignRaw { 15 | Entries:[CampaignRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type CampaignRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/CardR1ExpRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CardR1ExpRawEntry { 4 | ID:int32; 5 | Exp:int32; 6 | } 7 | 8 | table CardR1ExpRaw { 9 | Entries:[CardR1ExpRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type CardR1ExpRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/CardR2ExpRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CardR2ExpRawEntry { 4 | ID:int32; 5 | Exp:int32; 6 | } 7 | 8 | table CardR2ExpRaw { 9 | Entries:[CardR2ExpRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type CardR2ExpRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/CardR3ExpRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CardR3ExpRawEntry { 4 | ID:int32; 5 | Exp:int32; 6 | } 7 | 8 | table CardR3ExpRaw { 9 | Entries:[CardR3ExpRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type CardR3ExpRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/CardR4ExpRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CardR4ExpRawEntry { 4 | ID:int32; 5 | Exp:int32; 6 | } 7 | 8 | table CardR4ExpRaw { 9 | Entries:[CardR4ExpRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type CardR4ExpRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/CardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CardRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | CharaID:int32; 9 | ImageID:int32; 10 | AwakeImageID:int32; 11 | Name:string; 12 | SecondName:string; 13 | NameYomi:string; 14 | NameDispText:string; 15 | IllustratorName:string; 16 | FlavorText:string; 17 | AwakeFlavorText:string; 18 | EpisodeID1:int32; 19 | EpisodeID2:int32; 20 | Rarity:int32; 21 | Element:int32; 22 | ParamAMin:int32; 23 | ParamAMax:int32; 24 | ParamBMin:int32; 25 | ParamBMax:int32; 26 | ParamCMin:int32; 27 | ParamCMax:int32; 28 | AwakeID:int32; 29 | LimitBreakID:int32; 30 | StrengthenID:int32; 31 | PassiveSkillID:int32; 32 | ActiveSkillID:int32; 33 | LinkBurstSkillID:int32; 34 | ExpeditionSkillID:int32; 35 | DanmakuExp2LvID:int32; 36 | DecomposeItemID:int32; 37 | FlUvX:int32; 38 | FlUvY:int32; 39 | FlUvW:int32; 40 | GachaMessage:string; 41 | StampDir:int32; 42 | DisplayOrder:int32; 43 | OffsetUvX:int32; 44 | OffsetUvY:int32; 45 | } 46 | 47 | table CardRaw { 48 | Entries:[CardRawEntry]; 49 | } 50 | 51 | file_identifier "D4AO"; 52 | root_type CardRaw; 53 | 54 | -------------------------------------------------------------------------------- /dankagu/schema/CharacterCefficientRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CharacterCefficientRawEntry { 4 | ID:int32; 5 | StrengthenCostCefficient:int32; 6 | HeroineGetFlagmentCount:int32; 7 | HeroineExchangeFlagmentCount:int32; 8 | NakayosiPtMax:int32; 9 | NakayosiPtThreshold:[int32]; 10 | FlIndividualUp0:int32; 11 | FlIndividualUp1:int32; 12 | FlIndividualUp2:int32; 13 | FlIndividualUp3:int32; 14 | FlIndividualUp4:int32; 15 | FlIndividualUpLifeShot0:int32; 16 | FlIndividualUpLifeShot1:int32; 17 | FlIndividualUpLifeShot2:int32; 18 | FlIndividualUpLifeShot3:int32; 19 | FlIndividualUpLifeShot4:int32; 20 | } 21 | 22 | table CharacterCefficientRaw { 23 | Entries:[CharacterCefficientRawEntry]; 24 | } 25 | 26 | file_identifier "D4AO"; 27 | root_type CharacterCefficientRaw; 28 | 29 | -------------------------------------------------------------------------------- /dankagu/schema/CharacterExpRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CharacterExpRawEntry { 4 | ID:int32; 5 | Exp:int32; 6 | } 7 | 8 | table CharacterExpRaw { 9 | Entries:[CharacterExpRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type CharacterExpRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/CharacterParameterRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CharacterParameterRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | CharaID:int32; 8 | ImageID:int32; 9 | MenuText1:string; 10 | MenuText2:string; 11 | MenuText3:string; 12 | MenuText4:string; 13 | Voice1:int32; 14 | Voice2:int32; 15 | Voice3:int32; 16 | Voice4:int32; 17 | MouceOff1:int32; 18 | MouceOff2:int32; 19 | MouceOff3:int32; 20 | MouceOff4:int32; 21 | Motion1:int32; 22 | Motion2:int32; 23 | Face1:int32; 24 | Face2:int32; 25 | Presonality:int32; 26 | Animationtype:int32; 27 | PartyWalk:int32; 28 | NgEmotion:[int32]; 29 | NgInteractObject:[int32]; 30 | PartyItem:string; 31 | SDTalkSpeed:float; 32 | SDTalkDispTime:float; 33 | SDFlyUpWaitTime:float; 34 | SDFlyDownWaitTime:float; 35 | SDMoveSpeed:float; 36 | SDPartyMoveSpeed:float; 37 | SDOption:int32; 38 | SDDisableFlight:int32; 39 | } 40 | 41 | table CharacterParameterRaw { 42 | Entries:[CharacterParameterRawEntry]; 43 | } 44 | 45 | file_identifier "D4AO"; 46 | root_type CharacterParameterRaw; 47 | 48 | -------------------------------------------------------------------------------- /dankagu/schema/CharacterRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CharacterRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | ImageID:int32; 9 | Name:string; 10 | NameYomi:string; 11 | ShortName:string; 12 | NameDispText:string; 13 | ActorName:string; 14 | ShotDamageInterval:int32; 15 | IsSpot:bool; 16 | IsEpisode:bool; 17 | GachaMessage1:string; 18 | GachaMessage2:string; 19 | GachaMessage3:string; 20 | GrowthEmblem1ID:int32; 21 | GrowthEmblem2ID:int32; 22 | DefaultSkinName:string; 23 | } 24 | 25 | table CharacterRaw { 26 | Entries:[CharacterRawEntry]; 27 | } 28 | 29 | file_identifier "D4AO"; 30 | root_type CharacterRaw; 31 | 32 | -------------------------------------------------------------------------------- /dankagu/schema/CharacterVoiceMotionTextRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CharacterVoiceMotionTextRawEntry { 4 | ID:int32; 5 | CharacterID:int32; 6 | ConditionID:int16; 7 | MotionID:int16; 8 | FaceID:int16; 9 | VoiceTypeID:int16; 10 | VoiceID:int32; 11 | VoiceText:string; 12 | MouceOff:int32; 13 | } 14 | 15 | table CharacterVoiceMotionTextRaw { 16 | Entries:[CharacterVoiceMotionTextRawEntry]; 17 | } 18 | 19 | file_identifier "D4AO"; 20 | root_type CharacterVoiceMotionTextRaw; 21 | 22 | -------------------------------------------------------------------------------- /dankagu/schema/ClubEmblemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ClubEmblemRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | DataVersion:int32; 7 | Enable:int32; 8 | Name:string; 9 | NameYomi:string; 10 | Description:string; 11 | ImageID:int32; 12 | Type:int32; 13 | } 14 | 15 | table ClubEmblemRaw { 16 | Entries:[ClubEmblemRawEntry]; 17 | } 18 | 19 | file_identifier "D4AO"; 20 | root_type ClubEmblemRaw; 21 | 22 | -------------------------------------------------------------------------------- /dankagu/schema/ClubObjectItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ClubObjectItemRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | Name:string; 9 | NameYomi:string; 10 | InstallCost:int32; 11 | InstallType:int32; 12 | ReactionNo:int32; 13 | IsPoster:bool; 14 | } 15 | 16 | table ClubObjectItemRaw { 17 | Entries:[ClubObjectItemRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type ClubObjectItemRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/ClubPositionRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ClubPositionRawEntry { 4 | ID:int32; 5 | Name:string; 6 | IsClubSettingEdit:bool; 7 | IsClubInfoEdit:bool; 8 | IsSolicit:bool; 9 | IsSolicitCancel:bool; 10 | IsJoinPermission:bool; 11 | IsPositionChange:bool; 12 | IsLeaderChange:bool; 13 | IsWithdrawal:bool; 14 | IsWithdrawalForce:bool; 15 | IsSpaceEdit:bool; 16 | IsPurchaseItem:bool; 17 | IsPlayMission:bool; 18 | IsPostMessage:bool; 19 | IsAnnouncSetting:bool; 20 | IsPostQuestionnaire:bool; 21 | IsVotingQuestionnaire:bool; 22 | } 23 | 24 | table ClubPositionRaw { 25 | Entries:[ClubPositionRawEntry]; 26 | } 27 | 28 | file_identifier "D4AO"; 29 | root_type ClubPositionRaw; 30 | 31 | -------------------------------------------------------------------------------- /dankagu/schema/ClubStampRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ClubStampRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | ImageID:int32; 9 | Name:string; 10 | NameYomi:string; 11 | Description:string; 12 | GroupNo:int32; 13 | IsDefaultUnlock:bool; 14 | } 15 | 16 | table ClubStampRaw { 17 | Entries:[ClubStampRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type ClubStampRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/ClubThemeRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ClubThemeRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | SpotID:int32; 9 | Situation:int32; 10 | Name:string; 11 | NameYomi:string; 12 | Description:string; 13 | UnlockType:int32; 14 | UnlockParam:int32; 15 | ThemaCategoryTag:int32; 16 | ThumbnailID:int32; 17 | } 18 | 19 | table ClubThemeRaw { 20 | Entries:[ClubThemeRawEntry]; 21 | } 22 | 23 | file_identifier "D4AO"; 24 | root_type ClubThemeRaw; 25 | 26 | -------------------------------------------------------------------------------- /dankagu/schema/ComboCefficientRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ComboCefficientRawEntry { 4 | ID:int64; 5 | UpperLimit:int32; 6 | LowerLimit:int32; 7 | FlValue:int32; 8 | } 9 | 10 | table ComboCefficientRaw { 11 | Entries:[ComboCefficientRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type ComboCefficientRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/ComboMaxRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ComboMaxRawEntry { 4 | ID:int32; 5 | Count:int32; 6 | TotalAttack:int32; 7 | DapSec:int32; 8 | } 9 | 10 | table ComboMaxRaw { 11 | Entries:[ComboMaxRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type ComboMaxRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/CoopEventExpeditionPointRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CoopEventExpeditionPointRawEntry { 4 | ID:int32; 5 | ThresholdMinute:int32; 6 | Amount:int32; 7 | } 8 | 9 | table CoopEventExpeditionPointRaw { 10 | Entries:[CoopEventExpeditionPointRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type CoopEventExpeditionPointRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/CoopEventInfoRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CoopEventInfoRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | Name:string; 8 | OpenAt:int64; 9 | EntryStartAt:int64; 10 | EntryEndAt:int64; 11 | CloseAt:int64; 12 | PhaseMax:int32; 13 | PhaseProgressAt:int64; 14 | PhaseProgressAt2:int64; 15 | PhaseProgressAt3:int64; 16 | PhaseProgressAt4:int64; 17 | PhaseSpotIDs:[int32]; 18 | PhaseMaxPoints:[int64]; 19 | PhaseShopLineupIDs:[int32]; 20 | PhaseProgressItemIDs:[int32]; 21 | ImageHelpIDs:[int32]; 22 | ImageHelpIDs2:[int32]; 23 | ImageHelpIDs3:[int32]; 24 | ImageHelpIDs4:[int32]; 25 | ResourcePointID:int32; 26 | KaguraBasePt:int32; 27 | ExpeditionBasePtVarientID:int32; 28 | ProgressRewardVarientID:int32; 29 | PhaseTweetVarientID:int32; 30 | TweetIntervalTime:int32; 31 | BannerIDs:[int32]; 32 | } 33 | 34 | table CoopEventInfoRaw { 35 | Entries:[CoopEventInfoRawEntry]; 36 | } 37 | 38 | file_identifier "D4AO"; 39 | root_type CoopEventInfoRaw; 40 | 41 | -------------------------------------------------------------------------------- /dankagu/schema/CoopEventPhaseVisitMaxRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CoopEventPhaseVisitMaxRawEntry { 4 | ID:int32; 5 | Phase:int32; 6 | VisitMax:int32; 7 | } 8 | 9 | table CoopEventPhaseVisitMaxRaw { 10 | Entries:[CoopEventPhaseVisitMaxRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type CoopEventPhaseVisitMaxRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/CoopEventProgressItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CoopEventProgressItemRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | Value:int32; 8 | CoopEventID:int32; 9 | } 10 | 11 | table CoopEventProgressItemRaw { 12 | Entries:[CoopEventProgressItemRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type CoopEventProgressItemRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/CoopEventProgressRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CoopEventProgressRewardRawEntry { 4 | ID:int32; 5 | Phase:int32; 6 | Progress:int32; 7 | PointBonusRatio:int32; 8 | TweetIDs:[int32]; 9 | ShopLineupIDs:[int32]; 10 | } 11 | 12 | table CoopEventProgressRewardRaw { 13 | Entries:[CoopEventProgressRewardRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type CoopEventProgressRewardRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/CoopEventScheduleRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CoopEventScheduleRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | OpenAt:int64; 8 | EntryStartAt:int64; 9 | EntryEndAt:int64; 10 | CloseAt:int64; 11 | CoopEventInfoVarientID:int32; 12 | EventName:string; 13 | } 14 | 15 | table CoopEventScheduleRaw { 16 | Entries:[CoopEventScheduleRawEntry]; 17 | } 18 | 19 | file_identifier "D4AO"; 20 | root_type CoopEventScheduleRaw; 21 | 22 | -------------------------------------------------------------------------------- /dankagu/schema/CoopEventTweetIdEventIdMapRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CoopEventTweetIdEventIdMapRawEntry { 4 | ID:int32; 5 | CoopEventId:int32; 6 | } 7 | 8 | table CoopEventTweetIdEventIdMapRaw { 9 | Entries:[CoopEventTweetIdEventIdMapRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type CoopEventTweetIdEventIdMapRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/CoopEventTweetRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table CoopEventTweetRawEntry { 4 | ID:int32; 5 | TweetID:int32; 6 | Phase:int32; 7 | UnlockTweetID:int32; 8 | UnlockProgress:int32; 9 | } 10 | 11 | table CoopEventTweetRaw { 12 | Entries:[CoopEventTweetRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type CoopEventTweetRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/DailyBonusItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DailyBonusItemRawEntry { 4 | ID:int32; 5 | ItemPrefix:[int32]; 6 | ItemValue:[int32]; 7 | ItemCount:[int32]; 8 | ItemWeight:[int32]; 9 | } 10 | 11 | table DailyBonusItemRaw { 12 | Entries:[DailyBonusItemRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type DailyBonusItemRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/DailyBonusRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DailyBonusRawEntry { 4 | ID:int32; 5 | OpenAt:int64; 6 | CloseAt:int64; 7 | MonBonusID:int32; 8 | TueBonusID:int32; 9 | WedBonusID:int32; 10 | ThuBonusID:int32; 11 | FriBonusID:int32; 12 | SatBonusID:int32; 13 | SanBonusID:int32; 14 | } 15 | 16 | table DailyBonusRaw { 17 | Entries:[DailyBonusRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type DailyBonusRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/DailyHeroineRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DailyHeroineRawEntry { 4 | ID:int32; 5 | OpenAt:int64; 6 | CloseAt:int64; 7 | HeroineIDs:[int32]; 8 | Magnification:int32; 9 | } 10 | 11 | table DailyHeroineRaw { 12 | Entries:[DailyHeroineRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type DailyHeroineRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/DanmakuPassActivationKeyRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DanmakuPassActivationKeyRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | ImageID:int32; 8 | } 9 | 10 | table DanmakuPassActivationKeyRaw { 11 | Entries:[DanmakuPassActivationKeyRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type DanmakuPassActivationKeyRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/DanmakuPassCefficientRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DanmakuPassCefficientRawEntry { 4 | ID:int32; 5 | Exp2Tier:int32; 6 | TierLimit:int32; 7 | TierSkipCost:int32; 8 | } 9 | 10 | table DanmakuPassCefficientRaw { 11 | Entries:[DanmakuPassCefficientRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type DanmakuPassCefficientRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/DanmakuPassPlanRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DanmakuPassPlanRawEntry { 4 | ID:int32; 5 | DanmakuPassID:int32; 6 | VarientID:int32; 7 | PassType:int32; 8 | OpenAt:int64; 9 | CloseAt:int64; 10 | } 11 | 12 | table DanmakuPassPlanRaw { 13 | Entries:[DanmakuPassPlanRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type DanmakuPassPlanRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/DanmakuPassRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DanmakuPassRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | VarientIDs:[int32]; 8 | OpenAt:int64; 9 | CloseAt:int64; 10 | SkipEnableAt:int64; 11 | RewardCloseAt:int64; 12 | } 13 | 14 | table DanmakuPassRaw { 15 | Entries:[DanmakuPassRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type DanmakuPassRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/DanmakuPassRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DanmakuPassRewardRawEntry { 4 | ID:int64; 5 | TierNo:int32; 6 | ItemPrefix:int32; 7 | ItemValue:int32; 8 | ItemCount:int32; 9 | Pickup:bool; 10 | } 11 | 12 | table DanmakuPassRewardRaw { 13 | Entries:[DanmakuPassRewardRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type DanmakuPassRewardRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/DanmakuRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DanmakuRawEntry { 4 | ID:int32; 5 | Name:string; 6 | AssetName:string; 7 | Damage:int32; 8 | } 9 | 10 | table DanmakuRaw { 11 | Entries:[DanmakuRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type DanmakuRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/DataVersionRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DataVersionRawEntry { 4 | ID:int64; 5 | DataVersion:int32; 6 | OpenAt:int64; 7 | } 8 | 9 | table DataVersionRaw { 10 | Entries:[DataVersionRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type DataVersionRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/DecomposeItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DecomposeItemRawEntry { 4 | ID:int32; 5 | Item1ID:int32; 6 | Item1Prefix:int32; 7 | Item1Count:int32; 8 | Item2ID:int32; 9 | Item2Prefix:int32; 10 | Item2Count:int32; 11 | } 12 | 13 | table DecomposeItemRaw { 14 | Entries:[DecomposeItemRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type DecomposeItemRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/DefaultHaveItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DefaultHaveItemRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | ItemPrefix:int32; 8 | ItemValue:int32; 9 | ItemCount:int32; 10 | } 11 | 12 | table DefaultHaveItemRaw { 13 | Entries:[DefaultHaveItemRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type DefaultHaveItemRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/DownloadBGRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table DownloadBGRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | Condition:int32; 8 | ImageID:int32; 9 | } 10 | 11 | table DownloadBGRaw { 12 | Entries:[DownloadBGRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type DownloadBGRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/EmblemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EmblemRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | DataVersion:int32; 7 | Enable:int32; 8 | Name:string; 9 | NameYomi:string; 10 | Description:string; 11 | ReleaseDescription:string; 12 | ImageID:int32; 13 | Type:int32; 14 | } 15 | 16 | table EmblemRaw { 17 | Entries:[EmblemRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type EmblemRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/EpisodeLivePresetRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EpisodeLivePresetRawEntry { 4 | ID:int32; 5 | MusicID:int32; 6 | Difficulty:int32; 7 | HeroineIDs:[int32]; 8 | CharacterLvs:[int32]; 9 | CardIDs:[int32]; 10 | CardLvs:[int32]; 11 | ReturnEpisodeID:int32; 12 | } 13 | 14 | table EpisodeLivePresetRaw { 15 | Entries:[EpisodeLivePresetRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type EpisodeLivePresetRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/EpisodeRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EpisodeRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | Category:int32; 8 | SortNo:int32; 9 | MainIndex:int32; 10 | SubIndex:int32; 11 | SubSubIndex:int32; 12 | ListDisplay:bool; 13 | EpisodeRewardID:int32; 14 | Title:string; 15 | AssetName:string; 16 | Character1ID:int32; 17 | Character2ID:int32; 18 | BackgroundID:int32; 19 | ThumbnailBackgroundID:int32; 20 | Character1Thumbnail:int32; 21 | Character2Thumbnail:int32; 22 | Character3Thumbnail:int32; 23 | ThumbnailDispOrder:int32; 24 | ReadUnlockEpisodeID:int32; 25 | AfterEpisodeID:int32; 26 | UnlockConditionMessage:string; 27 | IsVoice:bool; 28 | UnlockMusicIDs:[int32]; 29 | UnlocMenuHeroineIDs:[int32]; 30 | EventEpisodeType:int8; 31 | } 32 | 33 | table EpisodeRaw { 34 | Entries:[EpisodeRawEntry]; 35 | } 36 | 37 | file_identifier "D4AO"; 38 | root_type EpisodeRaw; 39 | 40 | -------------------------------------------------------------------------------- /dankagu/schema/EpisodeRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EpisodeRewardRawEntry { 4 | ID:int32; 5 | ItemID:int32; 6 | ItemPrefix:int32; 7 | ItemCount:int32; 8 | } 9 | 10 | table EpisodeRewardRaw { 11 | Entries:[EpisodeRewardRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type EpisodeRewardRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/ErrorMessageRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ErrorMessageRawEntry { 4 | ID:int32; 5 | ErrorTitle:string; 6 | ErrorMessage:string; 7 | } 8 | 9 | table ErrorMessageRaw { 10 | Entries:[ErrorMessageRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type ErrorMessageRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/EventBoxRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventBoxRewardRawEntry { 4 | ID:int64; 5 | BoxNo:int32; 6 | ItemPrefix:int32; 7 | ItemValue:int32; 8 | ItemCount:int32; 9 | Reset:bool; 10 | LotteryWeight:int32; 11 | RewardCount:int32; 12 | } 13 | 14 | table EventBoxRewardRaw { 15 | Entries:[EventBoxRewardRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type EventBoxRewardRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/EventCefficientRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventCefficientRawEntry { 4 | ID:int32; 5 | ExpeditionUnlockSpotCount:int32; 6 | RaidDamageRate:int32; 7 | RaidCoopBonus:int32; 8 | RaidCoinRate:int32; 9 | RaidEncountBoostPoint:[int32]; 10 | RaidRareBonus:int32; 11 | } 12 | 13 | table EventCefficientRaw { 14 | Entries:[EventCefficientRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type EventCefficientRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/EventInfoRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventInfoRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | Name:string; 8 | OpenAt:int64; 9 | RankingStartAt:int64; 10 | RankingEndAt:int64; 11 | RewardStartAt:int64; 12 | ResultEndAt:int64; 13 | CloseAt:int64; 14 | EventType:string; 15 | ImageHelpIDs:[int32]; 16 | ImageHelpIDs2:[int32]; 17 | TotalRewardVarientIDs:[int32]; 18 | BoxRewardValientIDs:[int32]; 19 | EventRankingRewardIDs:[string]; 20 | EventMissionVarientIDs:[int32]; 21 | RankingVarientIDs:[int32]; 22 | RankingTargetValueIDs:[int32]; 23 | EventElement:int32; 24 | EventCharacter:[int32]; 25 | EventCharacter2:[int32]; 26 | EventCharacter2OpenAt:int64; 27 | EventElementCefficient:int32; 28 | EventElementCefficients:[int32]; 29 | EventCharacterCefficient:int32; 30 | EventCharacterCefficients:[int32]; 31 | EventCharacterElementCefficients:[int32]; 32 | EventMusicID:int32; 33 | MainRewardCardIDs:[int32]; 34 | NormalBasePt:int32; 35 | EventBasePt:int32; 36 | NormalPlayDiffcultyCefficient:[int32]; 37 | EventPlayDiffcultyCefficient:[int32]; 38 | NormalClearRankCefficient:[int32]; 39 | EventClearRankCefficient:[int32]; 40 | BossGaugePt:[int32]; 41 | ExpedtionIDs:[int32]; 42 | ExpedtionMaxCount:[int32]; 43 | ExpeditionRaidDifficultyRate:[int32]; 44 | BackgroundID:int32; 45 | PrologueEpisodeID:int32; 46 | EpilogueEpisodeID:int32; 47 | OpenBoxPoint:int32; 48 | BannerIDs:[int32]; 49 | IllustScaleX:float; 50 | RaidBossVarientIDs:[int32]; 51 | IllustScaleY:float; 52 | IllustOffsetX:float; 53 | IllustOffsetY:float; 54 | } 55 | 56 | table EventInfoRaw { 57 | Entries:[EventInfoRawEntry]; 58 | } 59 | 60 | file_identifier "D4AO"; 61 | root_type EventInfoRaw; 62 | 63 | -------------------------------------------------------------------------------- /dankagu/schema/EventRaidBossDamageParamRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventRaidBossDamageParamRawEntry { 4 | ID:int32; 5 | BaseDamage:int32; 6 | BaseDamageWithBonus:int32; 7 | DifficultyRate:[float]; 8 | ScoreRankRate:[float]; 9 | } 10 | 11 | table EventRaidBossDamageParamRaw { 12 | Entries:[EventRaidBossDamageParamRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type EventRaidBossDamageParamRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/EventRaidBossHpRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventRaidBossHpRawEntry { 4 | ID:int32; 5 | BossLvStart:int32; 6 | BossLvEnd:int32; 7 | BaseHp:int32; 8 | AddPerLv:int32; 9 | } 10 | 11 | table EventRaidBossHpRaw { 12 | Entries:[EventRaidBossHpRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type EventRaidBossHpRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/EventRaidBossRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventRaidBossRawEntry { 4 | ID:int32; 5 | HeroineID:int32; 6 | Lv:int32; 7 | MaxHp:int32; 8 | RaidBossType:int32; 9 | OffsetIconPosX:float; 10 | OffsetIconPosY:float; 11 | OffsetIconScaleX:float; 12 | OffsetIconScaleY:float; 13 | } 14 | 15 | table EventRaidBossRaw { 16 | Entries:[EventRaidBossRawEntry]; 17 | } 18 | 19 | file_identifier "D4AO"; 20 | root_type EventRaidBossRaw; 21 | 22 | -------------------------------------------------------------------------------- /dankagu/schema/EventRaidBotRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventRaidBotRawEntry { 4 | ID:int32; 5 | DispName:string; 6 | IconType:int32; 7 | HeroineId:int32; 8 | CardId:int32; 9 | } 10 | 11 | table EventRaidBotRaw { 12 | Entries:[EventRaidBotRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type EventRaidBotRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/EventRankingGroupRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventRankingGroupRawEntry { 4 | ID:int32; 5 | Group:string; 6 | RankFrom:int64; 7 | RankTo:int64; 8 | } 9 | 10 | table EventRankingGroupRaw { 11 | Entries:[EventRankingGroupRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type EventRankingGroupRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/EventRankingRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventRankingRewardRawEntry { 4 | ID:int64; 5 | RankFrom:int64; 6 | RankTo:int64; 7 | AchievementKey:string; 8 | ItemPrefix:[int32]; 9 | ItemValue:[int32]; 10 | ItemCount:[int32]; 11 | } 12 | 13 | table EventRankingRewardRaw { 14 | Entries:[EventRankingRewardRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type EventRankingRewardRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/EventScheduleRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventScheduleRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | EventInfoVarientID:int32; 10 | RewardStartAt:int64; 11 | RankingStartAt:int64; 12 | RankingEndAt:int64; 13 | ResultEndAt:int64; 14 | EventName:string; 15 | } 16 | 17 | table EventScheduleRaw { 18 | Entries:[EventScheduleRawEntry]; 19 | } 20 | 21 | file_identifier "D4AO"; 22 | root_type EventScheduleRaw; 23 | 24 | -------------------------------------------------------------------------------- /dankagu/schema/EventTotalRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table EventTotalRewardRawEntry { 4 | ID:int64; 5 | Point:int64; 6 | AchievementKey:string; 7 | ItemPrefix:int32; 8 | ItemValue:int32; 9 | ItemCount:int32; 10 | } 11 | 12 | table EventTotalRewardRaw { 13 | Entries:[EventTotalRewardRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type EventTotalRewardRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/Exp2LvRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table Exp2LvRawEntry { 4 | ID:int32; 5 | ExpArray:[int32]; 6 | } 7 | 8 | table Exp2LvRaw { 9 | Entries:[Exp2LvRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type Exp2LvRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionChallengeBonusRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionChallengeBonusRawEntry { 4 | ID:int32; 5 | Description:string; 6 | BonusPercent:int32; 7 | Type:int32; 8 | Lv:int32; 9 | Rarity:int32; 10 | Element:int32; 11 | Character:[int32]; 12 | MinimumNum:int32; 13 | IsOnly:bool; 14 | } 15 | 16 | table ExpeditionChallengeBonusRaw { 17 | Entries:[ExpeditionChallengeBonusRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type ExpeditionChallengeBonusRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionChallengeTypeRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionChallengeTypeRawEntry { 4 | ID:int32; 5 | Description:string; 6 | } 7 | 8 | table ExpeditionChallengeTypeRaw { 9 | Entries:[ExpeditionChallengeTypeRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type ExpeditionChallengeTypeRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionConditionRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionConditionRawEntry { 4 | ID:int32; 5 | Total:int32; 6 | Type:int32; 7 | FlSuccessThreshold1:int32; 8 | FlSuccessThreshold2:int32; 9 | Character1ID:int32; 10 | Character2ID:int32; 11 | Card1Element:int32; 12 | Card2Element:int32; 13 | Card3Element:int32; 14 | Card4Element:int32; 15 | Card5Element:int32; 16 | } 17 | 18 | table ExpeditionConditionRaw { 19 | Entries:[ExpeditionConditionRawEntry]; 20 | } 21 | 22 | file_identifier "D4AO"; 23 | root_type ExpeditionConditionRaw; 24 | 25 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionExecMaxRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionExecMaxRawEntry { 4 | ID:int32; 5 | SpotCount:int32; 6 | ExecMax:int32; 7 | } 8 | 9 | table ExpeditionExecMaxRaw { 10 | Entries:[ExpeditionExecMaxRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type ExpeditionExecMaxRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionFilterTypeRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionFilterTypeRawEntry { 4 | ID:int32; 5 | Description:string; 6 | } 7 | 8 | table ExpeditionFilterTypeRaw { 9 | Entries:[ExpeditionFilterTypeRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type ExpeditionFilterTypeRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionMissionRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionMissionRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | SpotID:int32; 9 | Name:string; 10 | Category:int32; 11 | ResourceType:int32; 12 | ResourceValue:int64; 13 | UnlockID:int32; 14 | CloseID:int32; 15 | ConditionID:int32; 16 | ProductPattern:int32; 17 | CharacterID:int32; 18 | ExpeditionReward1ID:int32; 19 | GetExp:int32; 20 | GetPartyPt:int32; 21 | GetNakayosiPt:int32; 22 | GetCardExp:int32; 23 | IsOnce:int32; 24 | TryDayOfWeek:int32; 25 | IsAllReconstructComplete:int32; 26 | ChallengeList:[int32]; 27 | ChallengeOpenAt:int64; 28 | ChallengeFinishAt:int64; 29 | ChallengeCloseAt:int64; 30 | FilterType:int32; 31 | } 32 | 33 | table ExpeditionMissionRaw { 34 | Entries:[ExpeditionMissionRawEntry]; 35 | } 36 | 37 | file_identifier "D4AO"; 38 | root_type ExpeditionMissionRaw; 39 | 40 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionRankingGroupRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionRankingGroupRawEntry { 4 | ID:int32; 5 | RankFrom:int64; 6 | RankTo:int64; 7 | } 8 | 9 | table ExpeditionRankingGroupRaw { 10 | Entries:[ExpeditionRankingGroupRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type ExpeditionRankingGroupRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionRewardItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionRewardItemRawEntry { 4 | ID:int32; 5 | ItemID:int32; 6 | ItemPrefix:int32; 7 | ItemMinCount:int32; 8 | ItemMaxCount:int32; 9 | BoostDisable:int32; 10 | } 11 | 12 | table ExpeditionRewardItemRaw { 13 | Entries:[ExpeditionRewardItemRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type ExpeditionRewardItemRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionRewardRawEntry { 4 | ID:int32; 5 | CoinMin:int32; 6 | CoinMax:int32; 7 | RewardItem1ID:int32; 8 | Item1Display:int32; 9 | FlItem1Weight:int32; 10 | RewardItem2ID:int32; 11 | Item2Display:int32; 12 | FlItem2Weight:int32; 13 | RewardItem3ID:int32; 14 | Item3Display:int32; 15 | FlItem3Weight:int32; 16 | RewardItem4ID:int32; 17 | Item4Display:int32; 18 | FlItem4Weight:int32; 19 | RewardItem5ID:int32; 20 | Item5Display:int32; 21 | FlItem5Weight:int32; 22 | RewardItem6ID:int32; 23 | Item6Display:int32; 24 | FlItem6Weight:int32; 25 | RewardItem7ID:int32; 26 | Item7Display:int32; 27 | FlItem7Weight:int32; 28 | RewardItem8ID:int32; 29 | Item8Display:int32; 30 | FlItem8Weight:int32; 31 | RewardItem9ID:int32; 32 | Item9Display:int32; 33 | FlItem9Weight:int32; 34 | } 35 | 36 | table ExpeditionRewardRaw { 37 | Entries:[ExpeditionRewardRawEntry]; 38 | } 39 | 40 | file_identifier "D4AO"; 41 | root_type ExpeditionRewardRaw; 42 | 43 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionSkillRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionSkillRawEntry { 4 | ID:int32; 5 | Class:int32; 6 | Rarety:int32; 7 | Condition:int32; 8 | Name:string; 9 | Description:string; 10 | Type:int32; 11 | FlParamArray:[int32]; 12 | } 13 | 14 | table ExpeditionSkillRaw { 15 | Entries:[ExpeditionSkillRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type ExpeditionSkillRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionSuccessWeightRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionSuccessWeightRawEntry { 4 | ID:int32; 5 | TotalPerThreshold:int32; 6 | SuccessWeight:int32; 7 | GreatSuccessWeight:int32; 8 | SuperSuccessWeight:int32; 9 | } 10 | 11 | table ExpeditionSuccessWeightRaw { 12 | Entries:[ExpeditionSuccessWeightRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type ExpeditionSuccessWeightRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/ExpeditionUnlockRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ExpeditionUnlockRawEntry { 4 | ID:int32; 5 | Type:int32; 6 | Param1:int32; 7 | Param2:int32; 8 | Param3:int32; 9 | } 10 | 11 | table ExpeditionUnlockRaw { 12 | Entries:[ExpeditionUnlockRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type ExpeditionUnlockRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/GachaTicketRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GachaTicketRawEntry { 4 | ID:int32; 5 | GachaTicketType:int32; 6 | PKVSName:string; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | DeliverOpenAt:int64; 10 | DeliverCloseAt:int64; 11 | } 12 | 13 | table GachaTicketRaw { 14 | Entries:[GachaTicketRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type GachaTicketRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/GachaTicketTypeRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GachaTicketTypeRawEntry { 4 | ID:int32; 5 | PKVSPrefix:string; 6 | LotCount:int32; 7 | ImageID:int32; 8 | SSROnly:bool; 9 | PickupOnly:bool; 10 | } 11 | 12 | table GachaTicketTypeRaw { 13 | Entries:[GachaTicketTypeRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type GachaTicketTypeRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/GachaTopScaleRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GachaTopScaleRawEntry { 4 | ID:int32; 5 | IllustScaleX:float; 6 | IllustScaleY:float; 7 | IllustOffsetX:float; 8 | IllustOffsetY:float; 9 | } 10 | 11 | table GachaTopScaleRaw { 12 | Entries:[GachaTopScaleRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type GachaTopScaleRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/GenericConstantRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GenericConstantRawEntry { 4 | ID:int32; 5 | Key:string; 6 | Value:string; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | } 10 | 11 | table GenericConstantRaw { 12 | Entries:[GenericConstantRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type GenericConstantRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/GenericItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GenericItemRawEntry { 4 | ID:int64; 5 | DataVersion:int32; 6 | Enable:int32; 7 | Value:int32; 8 | SortOrder:int32; 9 | Rarity:int32; 10 | HaveMax:int32; 11 | } 12 | 13 | table GenericItemRaw { 14 | Entries:[GenericItemRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type GenericItemRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/GpxClassRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GpxClassRawEntry { 4 | ID:int64; 5 | Name:string; 6 | RankFrom:int64; 7 | RankTo:int64; 8 | } 9 | 10 | table GpxClassRaw { 11 | Entries:[GpxClassRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type GpxClassRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/GpxInfoRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GpxInfoRawEntry { 4 | ID:int64; 5 | DataVersion:int32; 6 | Enable:int32; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | GpxRewardVarientID:[string]; 10 | ClassRewardVarientID:[string]; 11 | GroupRewardVarientID:[string]; 12 | ImageHelpIDs:[int32]; 13 | BannerID:string; 14 | } 15 | 16 | table GpxInfoRaw { 17 | Entries:[GpxInfoRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type GpxInfoRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/GpxPhaseRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GpxPhaseRawEntry { 4 | ID:int64; 5 | OpenAt:int64; 6 | RankingEndAt:int64; 7 | RewardStartAt:int64; 8 | CloseAt:int64; 9 | MusicIDs:[int32]; 10 | TopMusicID:int32; 11 | TopBgID:int32; 12 | } 13 | 14 | table GpxPhaseRaw { 15 | Entries:[GpxPhaseRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type GpxPhaseRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/GpxRankingGroupRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GpxRankingGroupRawEntry { 4 | ID:int32; 5 | Group:string; 6 | RankFrom:int64; 7 | RankTo:int64; 8 | } 9 | 10 | table GpxRankingGroupRaw { 11 | Entries:[GpxRankingGroupRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type GpxRankingGroupRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/GpxRankingRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GpxRankingRewardRawEntry { 4 | ID:int64; 5 | ClassID:int32; 6 | RankFrom:int64; 7 | RankTo:int64; 8 | ItemPrefix:[int32]; 9 | ItemValue:[int32]; 10 | ItemCount:[int32]; 11 | } 12 | 13 | table GpxRankingRewardRaw { 14 | Entries:[GpxRankingRewardRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type GpxRankingRewardRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/GpxScheduleRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GpxScheduleRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | GpxInfoVarientID:int32; 10 | } 11 | 12 | table GpxScheduleRaw { 13 | Entries:[GpxScheduleRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type GpxScheduleRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/GpxTemplateRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GpxTemplateRawEntry { 4 | ID:int32; 5 | Value:string; 6 | } 7 | 8 | table GpxTemplateRaw { 9 | Entries:[GpxTemplateRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type GpxTemplateRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/GpxTicketSettingRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GpxTicketSettingRawEntry { 4 | ID:int32; 5 | HealTime:int32; 6 | PlayVCCount:int32; 7 | MaxHaveTicket:int32; 8 | BuyTicketCount:int32; 9 | PriodWarningTimeTop:int32; 10 | PriodWarningTimeStart:int32; 11 | StartTicket:int32; 12 | } 13 | 14 | table GpxTicketSettingRaw { 15 | Entries:[GpxTicketSettingRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type GpxTicketSettingRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/GrowthItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table GrowthItemRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | Category:int32; 8 | Rarity:int32; 9 | Name:string; 10 | Description:string; 11 | Type:int32; 12 | Value:int32; 13 | HaveMax:int32; 14 | } 15 | 16 | table GrowthItemRaw { 17 | Entries:[GrowthItemRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type GrowthItemRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/HakoniwaCefficientRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table HakoniwaCefficientRawEntry { 4 | ID:int32; 5 | FlElementSameCefficient:int32; 6 | FlElementAllSameCefficient:int32; 7 | FlHeroineSameCefficient:int32; 8 | MySpotMaxCost:int32; 9 | SpotCharacterMax:int32; 10 | ContactMax:int32; 11 | ContactUpdateInterval:int32; 12 | BossExpeditionSpawn:int32; 13 | BossExpedtionInitPer:int32; 14 | } 15 | 16 | table HakoniwaCefficientRaw { 17 | Entries:[HakoniwaCefficientRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type HakoniwaCefficientRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/HeroineGrowthRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table HeroineGrowthRawEntry { 4 | ID:int32; 5 | FlParamA:int32; 6 | FlParamB:int32; 7 | FlParamC:int32; 8 | Life:int32; 9 | Shot:int32; 10 | RewardItemPrefix:int32; 11 | RewardItemValue:int32; 12 | RewardItemCount:int32; 13 | ResourceFlagmentCount:int32; 14 | } 15 | 16 | table HeroineGrowthRaw { 17 | Entries:[HeroineGrowthRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type HeroineGrowthRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/HeroineRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table HeroineRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | CharaType:int32; 9 | CharaID:int32; 10 | ImageID:int32; 11 | Name:string; 12 | NameYomi:string; 13 | NameDispText:string; 14 | IllustratorName:string; 15 | AblityName:string; 16 | FlavorText:string; 17 | MenuText1:string; 18 | MenuText2:string; 19 | MenuText3:string; 20 | VoiceID1:int32; 21 | VoiceID2:int32; 22 | VoiceID3:int32; 23 | MotionA:int32; 24 | FaceA:int32; 25 | MotionB:int32; 26 | FaceB:int32; 27 | DecomposeItemID:int32; 28 | Personality:int32; 29 | AnimationType:int32; 30 | DisplayOrder:int32; 31 | PartyWalk:int32; 32 | NgEmotion:[int32]; 33 | PartyItem:string; 34 | SDTalkSpeed:float; 35 | SDTalkDispTime:float; 36 | SDFlyUpWaitTime:float; 37 | SDFlyDownWaitTime:float; 38 | SDMoveSpeed:float; 39 | SDPartyMoveSpeed:float; 40 | SDOption:int32; 41 | } 42 | 43 | table HeroineRaw { 44 | Entries:[HeroineRawEntry]; 45 | } 46 | 47 | file_identifier "D4AO"; 48 | root_type HeroineRaw; 49 | 50 | -------------------------------------------------------------------------------- /dankagu/schema/HeroineSkillRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table HeroineSkillRawEntry { 4 | ID:int32; 5 | Description:string; 6 | Value:int32; 7 | Weight:int32; 8 | } 9 | 10 | table HeroineSkillRaw { 11 | Entries:[HeroineSkillRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type HeroineSkillRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/HomeBannerRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table HomeBannerRawEntry { 4 | ID:int64; 5 | DataVersion:int32; 6 | Enable:int32; 7 | ImageID:string; 8 | OpenAt:int64; 9 | CloseAt:int64; 10 | TransitionID:int32; 11 | TransitionValue:string; 12 | SortOrder:int32; 13 | EventStatus:int32; 14 | PlayerLevel:int32; 15 | DisplayType:int32; 16 | } 17 | 18 | table HomeBannerRaw { 19 | Entries:[HomeBannerRawEntry]; 20 | } 21 | 22 | file_identifier "D4AO"; 23 | root_type HomeBannerRaw; 24 | 25 | -------------------------------------------------------------------------------- /dankagu/schema/HomeVoiceRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table HomeVoiceRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | Cuesheet:string; 8 | Prefix:string; 9 | VoiceNo:int32; 10 | ReserveNo:int32; 11 | OpenAt:int64; 12 | CloseAt:int64; 13 | ConditionID:int32; 14 | ConditionValue:string; 15 | Weight:int32; 16 | FirstVoice:int32; 17 | } 18 | 19 | table HomeVoiceRaw { 20 | Entries:[HomeVoiceRawEntry]; 21 | } 22 | 23 | file_identifier "D4AO"; 24 | root_type HomeVoiceRaw; 25 | 26 | -------------------------------------------------------------------------------- /dankagu/schema/ImageHelpRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ImageHelpRawEntry { 4 | ID:int64; 5 | DataVersion:int32; 6 | Enable:int32; 7 | GroupID:int32; 8 | ImageID:int32; 9 | AppearanceID:int32; 10 | } 11 | 12 | table ImageHelpRaw { 13 | Entries:[ImageHelpRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type ImageHelpRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/IndividualDiff2Raw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table IndividualDiff2RawEntry { 4 | ID:int32; 5 | Up0ParamType:int32; 6 | Up1ParamType:int32; 7 | Up2ParamType:int32; 8 | Up3ParamType:int32; 9 | Up4ParamType:int32; 10 | Weight:int32; 11 | } 12 | 13 | table IndividualDiff2Raw { 14 | Entries:[IndividualDiff2RawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type IndividualDiff2Raw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/IndividualDiffRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table IndividualDiffRawEntry { 4 | ID:int32; 5 | LifeBase:int32; 6 | FlLifeAdd:int32; 7 | FlParamABase:int32; 8 | FlParamAAdd:int32; 9 | FlParamBBase:int32; 10 | FlParamBAdd:int32; 11 | FlParamCBase:int32; 12 | FlParamCAdd:int32; 13 | ShotBase:int32; 14 | FlShotAdd:int32; 15 | } 16 | 17 | table IndividualDiffRaw { 18 | Entries:[IndividualDiffRawEntry]; 19 | } 20 | 21 | file_identifier "D4AO"; 22 | root_type IndividualDiffRaw; 23 | 24 | -------------------------------------------------------------------------------- /dankagu/schema/LifeDecreasRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table LifeDecreasRawEntry { 4 | ID:int32; 5 | FlNomalBad:int32; 6 | FlNomalMiss:int32; 7 | FlLongBad:int32; 8 | FlLongMiss:int32; 9 | FlSlideBad:int32; 10 | FlSlideMiss:int32; 11 | FlFuzzyBad:int32; 12 | FlFuzzyMiss:int32; 13 | } 14 | 15 | table LifeDecreasRaw { 16 | Entries:[LifeDecreasRawEntry]; 17 | } 18 | 19 | file_identifier "D4AO"; 20 | root_type LifeDecreasRaw; 21 | 22 | -------------------------------------------------------------------------------- /dankagu/schema/LimitBreakRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table LimitBreakRawEntry { 4 | ID:int32; 5 | CardCount:[int32]; 6 | Cost:[int32]; 7 | ParamAdd:[int32]; 8 | ItemCount:[int32]; 9 | FlSameParam:[int32]; 10 | FlOtherParam:[int32]; 11 | PassiveSkillLv:[int32]; 12 | ActiveSkillLv:[int32]; 13 | ExpeditionSkillLv:[int32]; 14 | } 15 | 16 | table LimitBreakRaw { 17 | Entries:[LimitBreakRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type LimitBreakRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/LinkBurstSkillRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table LinkBurstSkillRawEntry { 4 | ID:int32; 5 | Strength:int32; 6 | Name:string; 7 | Description:string; 8 | Detail:string; 9 | Type1:int32; 10 | FlParam11Array:[int32]; 11 | FlParam12Array:[int32]; 12 | FlParam13Array:[int32]; 13 | FlParam14Array:[int32]; 14 | } 15 | 16 | table LinkBurstSkillRaw { 17 | Entries:[LinkBurstSkillRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type LinkBurstSkillRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/MapGridRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MapGridRawEntry { 4 | ID:int32; 5 | Width:int32; 6 | Height:int32; 7 | GridArray:[int32]; 8 | } 9 | 10 | table MapGridRaw { 11 | Entries:[MapGridRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type MapGridRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/MapUnlockRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MapUnlockRawEntry { 4 | ID:int32; 5 | SpotCount:int32; 6 | UnlockEpisodeID:int32; 7 | UnlockGridID:int32; 8 | BeforeSpotObjectItemID:int32; 9 | AfterToSpotObjectItemID:int32; 10 | SpotRepairCount:int32; 11 | } 12 | 13 | table MapUnlockRaw { 14 | Entries:[MapUnlockRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type MapUnlockRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/MessageMapRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MessageMapRawEntry { 4 | ID:int64; 5 | Label:string; 6 | Value:string; 7 | } 8 | 9 | table MessageMapRaw { 10 | Entries:[MessageMapRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type MessageMapRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/MissionBeginnerRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MissionBeginnerRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | ItemPrefix:int32; 8 | ItemValue:int32; 9 | ItemCount:int32; 10 | Step:int32; 11 | StepWord:string; 12 | } 13 | 14 | table MissionBeginnerRaw { 15 | Entries:[MissionBeginnerRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type MissionBeginnerRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/MissionConditionRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MissionConditionRawEntry { 4 | ID:int32; 5 | MissionCateogryID:int32; 6 | TransitionID:int32; 7 | } 8 | 9 | table MissionConditionRaw { 10 | Entries:[MissionConditionRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type MissionConditionRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/MissionRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MissionRawEntry { 4 | ID:int64; 5 | DataVersion:int32; 6 | Enable:int32; 7 | ConditionID:int32; 8 | TargetValue:int64; 9 | ConditionValue:int64; 10 | LimitType:int32; 11 | ItemPrefix:[int32]; 12 | ItemValue:[int32]; 13 | ItemCount:[int32]; 14 | OpenAt:int64; 15 | CloseAt:int64; 16 | GroupOrder:int32; 17 | SortOrder:int32; 18 | PreconditionID1:int32; 19 | PreconditionValue1:int32; 20 | PreconditionID2:int32; 21 | PreconditionValue2:int32; 22 | PreconditionID3:int32; 23 | PreconditionValue3:int32; 24 | PreconditionID4:int32; 25 | PreconditionValue4:int32; 26 | TransitionID:int32; 27 | TransitionValue:string; 28 | } 29 | 30 | table MissionRaw { 31 | Entries:[MissionRawEntry]; 32 | } 33 | 34 | file_identifier "D4AO"; 35 | root_type MissionRaw; 36 | 37 | -------------------------------------------------------------------------------- /dankagu/schema/MissionTableRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MissionTableRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | VarientID:int32; 8 | MissionType:int32; 9 | OpenAt:int64; 10 | CloseAt:int64; 11 | } 12 | 13 | table MissionTableRaw { 14 | Entries:[MissionTableRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type MissionTableRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/MonthlyPassRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MonthlyPassRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | Name:string; 8 | OpenAt:int64; 9 | CloseAt:int64; 10 | Period:int32; 11 | LoginRewardID:int32; 12 | LoginReward2ID:int32; 13 | PurchaseRewardID:int32; 14 | UpdateCount:[int32]; 15 | UpdateRewardIDs:[int32]; 16 | BoostRecover:int32; 17 | TierUpPercent:int32; 18 | } 19 | 20 | table MonthlyPassRaw { 21 | Entries:[MonthlyPassRawEntry]; 22 | } 23 | 24 | file_identifier "D4AO"; 25 | root_type MonthlyPassRaw; 26 | 27 | -------------------------------------------------------------------------------- /dankagu/schema/MonthlyPassRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MonthlyPassRewardRawEntry { 4 | ID:int32; 5 | ItemPrefix:int32; 6 | ItemValue:int32; 7 | ItemCount:int32; 8 | } 9 | 10 | table MonthlyPassRewardRaw { 11 | Entries:[MonthlyPassRewardRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type MonthlyPassRewardRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/MusicLevelScoreRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MusicLevelScoreRawEntry { 4 | ID:int32; 5 | BaseValue:int32; 6 | } 7 | 8 | table MusicLevelScoreRaw { 9 | Entries:[MusicLevelScoreRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type MusicLevelScoreRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/MusicProductRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MusicProductRawEntry { 4 | ID:int32; 5 | PurchaseType:int32; 6 | ConsumeItemPrefix:int32; 7 | ConsumeItemValue:int32; 8 | Price:int32; 9 | OpenAt:int64; 10 | CloseAt:int64; 11 | } 12 | 13 | table MusicProductRaw { 14 | Entries:[MusicProductRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type MusicProductRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/MusicRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MusicRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | WavID:int32; 8 | ScoreBaseID:int32; 9 | MusicType:int32; 10 | NotShowBossSpellName:int32; 11 | CoverID:int32; 12 | BackgroundID:int32; 13 | MusicDateFileID:int32; 14 | CharaType:int32; 15 | BossID:int32; 16 | BossID2:int32; 17 | BossID3:int32; 18 | BossHp:int32; 19 | RankMaxScore:int32; 20 | RankSScore:int32; 21 | RankAScore:int32; 22 | RankBScore:int32; 23 | RankCScore:int32; 24 | RankDScore:int32; 25 | RankMaxTotal:int32; 26 | RankSTotal:int32; 27 | RankATotal:int32; 28 | RankBTotal:int32; 29 | RankCTotal:int32; 30 | RankDTotal:int32; 31 | MusicStartTime:int32; 32 | SpellCardID:int32; 33 | SpellCard2ID:int32; 34 | SpellCard3ID:int32; 35 | SpellCardMissionID:int32; 36 | GroupeID:int32; 37 | IllustratorName:string; 38 | CreaterNo:int32; 39 | MusicAttr:int32; 40 | Circle:string; 41 | Title:string; 42 | TitleYomi:string; 43 | OriginalName:string; 44 | Vocal:string; 45 | Part1:string; 46 | Part2:string; 47 | Part3:string; 48 | Part4:string; 49 | Part5:string; 50 | Part6:string; 51 | Part7:string; 52 | Part8:string; 53 | Part9:string; 54 | Part10:string; 55 | Part11:string; 56 | DisplayOrder:int32; 57 | DanmakuRate:int32; 58 | ScoreRewardID:int32; 59 | ComboRewardID:int32; 60 | BossGaugeRewardID:int32; 61 | ConsumeStamina:[int32]; 62 | GetExp:[int32]; 63 | GetNakayosiPt:[int32]; 64 | GetCardPt:[int32]; 65 | GetPartyPt:[int32]; 66 | BaseBPM:int32; 67 | IsShowStageSelect:bool; 68 | LunaticNoDamageClearEmblemID:int32; 69 | DetailURL:string; 70 | } 71 | 72 | table MusicRaw { 73 | Entries:[MusicRawEntry]; 74 | } 75 | 76 | file_identifier "D4AO"; 77 | root_type MusicRaw; 78 | 79 | -------------------------------------------------------------------------------- /dankagu/schema/MusicScoreRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table MusicScoreRawEntry { 4 | ID:int32; 5 | MusicLevel:int32; 6 | } 7 | 8 | table MusicScoreRaw { 9 | Entries:[MusicScoreRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type MusicScoreRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/NewMusicAnnouncementRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table NewMusicAnnouncementRawEntry { 4 | ID:int32; 5 | MusicID:int32; 6 | DispOrder:int32; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | } 10 | 11 | table NewMusicAnnouncementRaw { 12 | Entries:[NewMusicAnnouncementRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type NewMusicAnnouncementRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/NoteTapSeRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table NoteTapSeRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | TapNBrillantSeNo:int32; 7 | TapNGreatSeNo:int32; 8 | TapNBadSeNo:int32; 9 | TapFBrillantSeNo:int32; 10 | TapFBadSeNo:int32; 11 | TapAtkNoteSeNo:int32; 12 | TapDefSeNo:int32; 13 | TapLoopSeNo:int32; 14 | } 15 | 16 | table NoteTapSeRaw { 17 | Entries:[NoteTapSeRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type NoteTapSeRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/NotesAdjustmentRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table NotesAdjustmentRawEntry { 4 | ID:int32; 5 | Name:string; 6 | Value:[int32]; 7 | } 8 | 9 | table NotesAdjustmentRaw { 10 | Entries:[NotesAdjustmentRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type NotesAdjustmentRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/PKVSRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table PKVSRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | Label:string; 8 | ImageId:int32; 9 | OpenAt:int64; 10 | CloseAt:int64; 11 | PKVSType:int32; 12 | } 13 | 14 | table PKVSRaw { 15 | Entries:[PKVSRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type PKVSRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/PartyRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table PartyRawEntry { 4 | ID:int32; 5 | CharacterMax:int32; 6 | PartyPt:int32; 7 | PartyTime:int32; 8 | RewardNum:int32; 9 | } 10 | 11 | table PartyRaw { 12 | Entries:[PartyRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type PartyRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/PartyRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table PartyRewardRawEntry { 4 | ID:int32; 5 | ItemID:int32; 6 | ItemPrefix:int32; 7 | ItemCount:int32; 8 | Weight:int32; 9 | } 10 | 11 | table PartyRewardRaw { 12 | Entries:[PartyRewardRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type PartyRewardRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/schema/PassiveSkillRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table PassiveSkillRawEntry { 4 | ID:int32; 5 | Rarity:int32; 6 | Strength:int32; 7 | Name:string; 8 | Description:string; 9 | EffectType:int32; 10 | Class:int32; 11 | Type:int32; 12 | Param1:int32; 13 | Param2:int32; 14 | Param3:int32; 15 | Param4:int32; 16 | FlParam1Array:[int32]; 17 | FlParam2Array:[int32]; 18 | FlParam3Array:[int32]; 19 | FlParam4Array:[int32]; 20 | TestParamArray:[int32]; 21 | Condition:int32; 22 | } 23 | 24 | table PassiveSkillRaw { 25 | Entries:[PassiveSkillRawEntry]; 26 | } 27 | 28 | file_identifier "D4AO"; 29 | root_type PassiveSkillRaw; 30 | 31 | -------------------------------------------------------------------------------- /dankagu/schema/PlayRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table PlayRewardRawEntry { 4 | ID:int32; 5 | ItemPrefix:int32; 6 | ItemValue:int32; 7 | ItemCount:int32; 8 | Condition:int32; 9 | LotteryWeight:int32; 10 | } 11 | 12 | table PlayRewardRaw { 13 | Entries:[PlayRewardRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type PlayRewardRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/PlayerCefficientRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table PlayerCefficientRawEntry { 4 | ID:int32; 5 | CardInitMax:int32; 6 | CardMax:int32; 7 | HeroineInitMax:int32; 8 | HeroineMax:int32; 9 | AddCount:int32; 10 | Cost:int32; 11 | DailyBonusMax:int32; 12 | FriendMax:int32; 13 | ClubInitMax:int32; 14 | ClubMax:int32; 15 | ClubCreateCost:int32; 16 | ClubUnlockCost:int32; 17 | PlaySkipMax:int32; 18 | ClubUnlockCost2:int32; 19 | } 20 | 21 | table PlayerCefficientRaw { 22 | Entries:[PlayerCefficientRawEntry]; 23 | } 24 | 25 | file_identifier "D4AO"; 26 | root_type PlayerCefficientRaw; 27 | 28 | -------------------------------------------------------------------------------- /dankagu/schema/PlayerExpRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table PlayerExpRawEntry { 4 | ID:int32; 5 | Exp:int32; 6 | } 7 | 8 | table PlayerExpRaw { 9 | Entries:[PlayerExpRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type PlayerExpRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/PlayerLvUpRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table PlayerLvUpRewardRawEntry { 4 | ID:int32; 5 | Lv:int32; 6 | VC:int32; 7 | Coin:int32; 8 | SkipTicket:int32; 9 | BoostRecoverType:int32; 10 | BoostRecoverCount:int32; 11 | UnlockType:int32; 12 | } 13 | 14 | table PlayerLvUpRewardRaw { 15 | Entries:[PlayerLvUpRewardRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type PlayerLvUpRewardRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/RGameActiveSkillTimingRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table RGameActiveSkillTimingRawEntry { 4 | ID:int32; 5 | TimingArray:[int32]; 6 | } 7 | 8 | table RGameActiveSkillTimingRaw { 9 | Entries:[RGameActiveSkillTimingRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type RGameActiveSkillTimingRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/RandomTweetRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table RandomTweetRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | AssetNo:int32; 8 | CharacterID:int32; 9 | UseSpotSetID:int32; 10 | IgnoreSpotSetID:int32; 11 | } 12 | 13 | table RandomTweetRaw { 14 | Entries:[RandomTweetRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type RandomTweetRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/RandomTweetSpotLimitSetRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table RandomTweetSpotLimitSetRawEntry { 4 | ID:int32; 5 | SpotIDs:[int32]; 6 | } 7 | 8 | table RandomTweetSpotLimitSetRaw { 9 | Entries:[RandomTweetSpotLimitSetRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type RandomTweetSpotLimitSetRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/ReconstructionRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ReconstructionRewardRawEntry { 4 | ID:int32; 5 | EpisodeID:int32; 6 | CharacterID:int32; 7 | SpotObjectRewardID:int32; 8 | ExpeditionID:int32; 9 | ItemID:int32; 10 | ItemPrefix:int32; 11 | ItemCount:int32; 12 | IsUniqueItem:int32; 13 | } 14 | 15 | table ReconstructionRewardRaw { 16 | Entries:[ReconstructionRewardRawEntry]; 17 | } 18 | 19 | file_identifier "D4AO"; 20 | root_type ReconstructionRewardRaw; 21 | 22 | -------------------------------------------------------------------------------- /dankagu/schema/RegularRankingRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table RegularRankingRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | SeriesNo:int32; 8 | SlotNo:int32; 9 | RankingStartAt:int64; 10 | RankingEndAt:int64; 11 | } 12 | 13 | table RegularRankingRaw { 14 | Entries:[RegularRankingRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type RegularRankingRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/ResourceItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ResourceItemRawEntry { 4 | ID:int32; 5 | Cost:int32; 6 | Item1ID:int32; 7 | Item1Prefix:int32; 8 | Item1Count:int32; 9 | Item2ID:int32; 10 | Item2Prefix:int32; 11 | Item2Count:int32; 12 | Item3ID:int32; 13 | Item3Prefix:int32; 14 | Item3Count:int32; 15 | Item4ID:int32; 16 | Item4Prefix:int32; 17 | Item4Count:int32; 18 | Item5ID:int32; 19 | Item5Prefix:int32; 20 | Item5Count:int32; 21 | } 22 | 23 | table ResourceItemRaw { 24 | Entries:[ResourceItemRawEntry]; 25 | } 26 | 27 | file_identifier "D4AO"; 28 | root_type ResourceItemRaw; 29 | 30 | -------------------------------------------------------------------------------- /dankagu/schema/RewardConditionRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table RewardConditionRawEntry { 4 | ID:int32; 5 | Threshold1:int32; 6 | ItemSet1ID:int32; 7 | Threshold2:int32; 8 | ItemSet2ID:int32; 9 | Threshold3:int32; 10 | ItemSet3ID:int32; 11 | Threshold4:int32; 12 | ItemSet4ID:int32; 13 | Threshold5:int32; 14 | ItemSet5ID:int32; 15 | } 16 | 17 | table RewardConditionRaw { 18 | Entries:[RewardConditionRawEntry]; 19 | } 20 | 21 | file_identifier "D4AO"; 22 | root_type RewardConditionRaw; 23 | 24 | -------------------------------------------------------------------------------- /dankagu/schema/RewardItemSetRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table RewardItemSetRawEntry { 4 | ID:int32; 5 | Item1ID:int32; 6 | Item1Prefix:int32; 7 | Item1Count:int32; 8 | Item2ID:int32; 9 | Item2Prefix:int32; 10 | Item2Count:int32; 11 | Item3ID:int32; 12 | Item3Prefix:int32; 13 | Item3Count:int32; 14 | Item4ID:int32; 15 | Item4Prefix:int32; 16 | Item4Count:int32; 17 | } 18 | 19 | table RewardItemSetRaw { 20 | Entries:[RewardItemSetRawEntry]; 21 | } 22 | 23 | file_identifier "D4AO"; 24 | root_type RewardItemSetRaw; 25 | 26 | -------------------------------------------------------------------------------- /dankagu/schema/RgCounstantRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table RgCounstantRawEntry { 4 | ID:int32; 5 | MaxRange:int32; 6 | MinRange:int32; 7 | HitRectWidth:float; 8 | HitRectTop:float; 9 | HitRectBottom:float; 10 | HitRectWidthWid:float; 11 | HitRectTopWid:float; 12 | HitRectBottomWid:float; 13 | DamageBase:float; 14 | AttackPower:float; 15 | AttackBaseNum:float; 16 | ComboSeparate:float; 17 | ActiveSkillCoefficient:float; 18 | ActiveSkillBrillantValue:int32; 19 | ActiveSkillGreatValue:int32; 20 | PowerMax:int32; 21 | PowerCoef:float; 22 | BossDamageAdjustRate:float; 23 | BossPowerAdjustRate:float; 24 | PassiveActivationRate:float; 25 | } 26 | 27 | table RgCounstantRaw { 28 | Entries:[RgCounstantRawEntry]; 29 | } 30 | 31 | file_identifier "D4AO"; 32 | root_type RgCounstantRaw; 33 | 34 | -------------------------------------------------------------------------------- /dankagu/schema/RythmGameRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table RythmGameRawEntry { 4 | ID:int32; 5 | BeginnerID:int32; 6 | EasyID:int32; 7 | NormalID:int32; 8 | HardID:int32; 9 | LunaticID:int32; 10 | FlPlanXBossDamageCefficient:int32; 11 | FlPlanXBossDamageJudgeCefficient:[int32]; 12 | FlPlanABossDamageCefficient:int32; 13 | FlPlanABossDamagePawerCefficient:int32; 14 | FlActiveSkillCoolTime:int32; 15 | LunaticReleaseConditionsNum:int32; 16 | } 17 | 18 | table RythmGameRaw { 19 | Entries:[RythmGameRawEntry]; 20 | } 21 | 22 | file_identifier "D4AO"; 23 | root_type RythmGameRaw; 24 | 25 | -------------------------------------------------------------------------------- /dankagu/schema/ScoreCefficientRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ScoreCefficientRawEntry { 4 | ID:int32; 5 | FlDiffcaltyAdd:int32; 6 | FlScoreAdjustment:int32; 7 | FlJadgeBrilliant:int32; 8 | FlJadgeGreat:int32; 9 | FlJadgeFastSlow:int32; 10 | FlJadgeBad:int32; 11 | FlJadgeMiss:int32; 12 | FlAttrEm:int32; 13 | FlAttrCo:int32; 14 | FlAttrRo:int32; 15 | FlAttrAll:int32; 16 | ComboCefficientIDs:[int64]; 17 | } 18 | 19 | table ScoreCefficientRaw { 20 | Entries:[ScoreCefficientRawEntry]; 21 | } 22 | 23 | file_identifier "D4AO"; 24 | root_type ScoreCefficientRaw; 25 | 26 | -------------------------------------------------------------------------------- /dankagu/schema/SdSkinRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SdSkinRawEntry { 4 | ID:int64; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | CharaID:int32; 9 | SkinID:int32; 10 | Name:string; 11 | NameYomi:string; 12 | Description:string; 13 | Option:int32; 14 | } 15 | 16 | table SdSkinRaw { 17 | Entries:[SdSkinRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type SdSkinRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/SelectTicketRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SelectTicketRawEntry { 4 | ID:int32; 5 | SelectTicketType:int32; 6 | PKVSName:string; 7 | OpenAt:int64; 8 | CloseAt:int64; 9 | ImageID:int32; 10 | } 11 | 12 | table SelectTicketRaw { 13 | Entries:[SelectTicketRawEntry]; 14 | } 15 | 16 | file_identifier "D4AO"; 17 | root_type SelectTicketRaw; 18 | 19 | -------------------------------------------------------------------------------- /dankagu/schema/ShopProductRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ShopProductRawEntry { 4 | ID:int64; 5 | DataVersion:int32; 6 | Enable:int32; 7 | ProductName:string; 8 | Price:int32; 9 | ConsumeItemPrefix:int32; 10 | ConsumeItemValue:int32; 11 | SubConsumeItemPrefix:int32; 12 | SubConsumeItemValue:int32; 13 | ItemPrefix:int32; 14 | ItemValue:int32; 15 | ItemCount:int32; 16 | MaxPurchaseCount:int64; 17 | PurchaseButtonID:int32; 18 | OpenAt:int64; 19 | CloseAt:int64; 20 | GameProductID:string; 21 | ViewOrder:int32; 22 | IsShowCloseAt:int32; 23 | IsShowMaxPurchaseCount:int32; 24 | IsShowCount:int32; 25 | ResetType:int32; 26 | ImageID:int32; 27 | IsLimited:int32; 28 | } 29 | 30 | table ShopProductRaw { 31 | Entries:[ShopProductRawEntry]; 32 | } 33 | 34 | file_identifier "D4AO"; 35 | root_type ShopProductRaw; 36 | 37 | -------------------------------------------------------------------------------- /dankagu/schema/ShopRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table ShopRawEntry { 4 | ID:int64; 5 | DataVersion:int32; 6 | Enable:int32; 7 | ShopName:string; 8 | ShopCategoryID:int32; 9 | LineupID:int32; 10 | BannerID:int32; 11 | ConsumeItemPrefix:int32; 12 | ConsumeItemValue:int32; 13 | OpenAt:int64; 14 | CloseAt:int64; 15 | ViewOrder:int32; 16 | } 17 | 18 | table ShopRaw { 19 | Entries:[ShopRawEntry]; 20 | } 21 | 22 | file_identifier "D4AO"; 23 | root_type ShopRaw; 24 | 25 | -------------------------------------------------------------------------------- /dankagu/schema/SpecialSkillRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpecialSkillRawEntry { 4 | ID:int32; 5 | Name:string; 6 | Description:string; 7 | FlRate:int32; 8 | Life:int32; 9 | FlParamA:int32; 10 | FlParamB:int32; 11 | FlParamC:int32; 12 | Shot:int32; 13 | } 14 | 15 | table SpecialSkillRaw { 16 | Entries:[SpecialSkillRawEntry]; 17 | } 18 | 19 | file_identifier "D4AO"; 20 | root_type SpecialSkillRaw; 21 | 22 | -------------------------------------------------------------------------------- /dankagu/schema/SpellCardMissionRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpellCardMissionRawEntry { 4 | ID:int32; 5 | Type:int32; 6 | Threshold:int32; 7 | Name:string; 8 | } 9 | 10 | table SpellCardMissionRaw { 11 | Entries:[SpellCardMissionRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type SpellCardMissionRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/SpellCardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpellCardRawEntry { 4 | ID:int32; 5 | Name:string; 6 | DanmakuID:int32; 7 | AssetName:string; 8 | BeginnerSpellCardID:int32; 9 | EasySpellCardID:int32; 10 | NormalSpellCardID:int32; 11 | HardSpellCardID:int32; 12 | LunaticSpellCardID:int32; 13 | } 14 | 15 | table SpellCardRaw { 16 | Entries:[SpellCardRawEntry]; 17 | } 18 | 19 | file_identifier "D4AO"; 20 | root_type SpellCardRaw; 21 | 22 | -------------------------------------------------------------------------------- /dankagu/schema/SpotObjectItemRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpotObjectItemRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | Name:string; 9 | NameYomi:string; 10 | InstallCost:int32; 11 | InstallType:int32; 12 | ReactionNo:int32; 13 | IsPoster:bool; 14 | } 15 | 16 | table SpotObjectItemRaw { 17 | Entries:[SpotObjectItemRawEntry]; 18 | } 19 | 20 | file_identifier "D4AO"; 21 | root_type SpotObjectItemRaw; 22 | 23 | -------------------------------------------------------------------------------- /dankagu/schema/SpotObjectRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpotObjectRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | SpotID:int32; 8 | SpotObjectItemID:int32; 9 | SpotObjectItem2ID:int32; 10 | AssetNo:int32; 11 | SpotObjectUnlockStep:int32; 12 | ResourceItemID:[int32]; 13 | ReconstructionStep:[int32]; 14 | RequiredTime:int64; 15 | Reconstruction:int32; 16 | ReconstructionReward1ID:[int32]; 17 | ReconstructionReward1Step:[int32]; 18 | ReconstructionReward2ID:[int32]; 19 | ReconstructionReward2Step:[int32]; 20 | ReconstructionReward3ID:[int32]; 21 | ReconstructionReward3Step:[int32]; 22 | ReconstructionMesssage:string; 23 | UnlockSpotObject:[int32]; 24 | } 25 | 26 | table SpotObjectRaw { 27 | Entries:[SpotObjectRawEntry]; 28 | } 29 | 30 | file_identifier "D4AO"; 31 | root_type SpotObjectRaw; 32 | 33 | -------------------------------------------------------------------------------- /dankagu/schema/SpotObjectRewardRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpotObjectRewardRawEntry { 4 | ID:int32; 5 | SpotObjectID:int32; 6 | ItemID:int32; 7 | ItemPrefix:int32; 8 | Count:int32; 9 | Max:int32; 10 | Interval:int64; 11 | } 12 | 13 | table SpotObjectRewardRaw { 14 | Entries:[SpotObjectRewardRawEntry]; 15 | } 16 | 17 | file_identifier "D4AO"; 18 | root_type SpotObjectRewardRaw; 19 | 20 | -------------------------------------------------------------------------------- /dankagu/schema/SpotRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpotRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | Name:string; 9 | NameYomi:string; 10 | Width:int32; 11 | Height:int32; 12 | IsEventSpot:bool; 13 | IsArea:bool; 14 | ParentSpotID:int32; 15 | RequiredTime:int64; 16 | UnlockID:int32; 17 | MapFlavorText:string; 18 | FirstFlavorText:string; 19 | SpotCharacterID:int32; 20 | SpotCharacterID1:int32; 21 | SpotCharacterID2:int32; 22 | FirstTweetText:string; 23 | FirstTweetID:int32; 24 | FirstTweetAssetNo:int32; 25 | ReconstructionMax:int32; 26 | Situation:int32; 27 | Thumbnail:string; 28 | BgmNo:int32; 29 | } 30 | 31 | table SpotRaw { 32 | Entries:[SpotRawEntry]; 33 | } 34 | 35 | file_identifier "D4AO"; 36 | root_type SpotRaw; 37 | 38 | -------------------------------------------------------------------------------- /dankagu/schema/SpotRepairObjectRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpotRepairObjectRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | SpotRepairID:int32; 8 | SpotObjectID:int32; 9 | ResourceItemID:[int32]; 10 | RepairStep:[int32]; 11 | RepairReward1ID:[int32]; 12 | RepairReward1Step:[int32]; 13 | RepairReward2ID:[int32]; 14 | RepairReward2Step:[int32]; 15 | RepairReward3ID:[int32]; 16 | RepairReward3Step:[int32]; 17 | DestructionObjectType:int32; 18 | } 19 | 20 | table SpotRepairObjectRaw { 21 | Entries:[SpotRepairObjectRawEntry]; 22 | } 23 | 24 | file_identifier "D4AO"; 25 | root_type SpotRepairObjectRaw; 26 | 27 | -------------------------------------------------------------------------------- /dankagu/schema/SpotRepairRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpotRepairRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | SpotID:int32; 8 | UnlockID:int32; 9 | RewardObjectID:[int32]; 10 | DestructionType:int32; 11 | FirstTweetAssetNo:int32; 12 | RepairedTweetAssetNo:int32; 13 | PartyAssetNo01:int32; 14 | PartyAssetNo02:int32; 15 | PartyCharacters:[int32]; 16 | } 17 | 18 | table SpotRepairRaw { 19 | Entries:[SpotRepairRawEntry]; 20 | } 21 | 22 | file_identifier "D4AO"; 23 | root_type SpotRepairRaw; 24 | 25 | -------------------------------------------------------------------------------- /dankagu/schema/SpotThemeRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpotThemeRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | SpotID:int32; 9 | Situation:int32; 10 | Name:string; 11 | NameYomi:string; 12 | Description:string; 13 | UnlockType:int32; 14 | UnlockParam:int32; 15 | ThemaCategoryTag:int32; 16 | ThumbnailID:int32; 17 | PartyEnable:int32; 18 | } 19 | 20 | table SpotThemeRaw { 21 | Entries:[SpotThemeRawEntry]; 22 | } 23 | 24 | file_identifier "D4AO"; 25 | root_type SpotThemeRaw; 26 | 27 | -------------------------------------------------------------------------------- /dankagu/schema/SpotUnlockRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpotUnlockRawEntry { 4 | ID:int32; 5 | Spot1ID:int32; 6 | Spot2ID:int32; 7 | Spot3ID:int32; 8 | Spot4ID:int32; 9 | Repair1ID:int32; 10 | Repair2ID:int32; 11 | Repair3ID:int32; 12 | Repair4ID:int32; 13 | } 14 | 15 | table SpotUnlockRaw { 16 | Entries:[SpotUnlockRawEntry]; 17 | } 18 | 19 | file_identifier "D4AO"; 20 | root_type SpotUnlockRaw; 21 | 22 | -------------------------------------------------------------------------------- /dankagu/schema/SpotVisitRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SpotVisitRawEntry { 4 | ID:int32; 5 | SpotID:int32; 6 | CharacterID:int32; 7 | FlVistWeightMin:int32; 8 | FlVistWeightMax:int32; 9 | NakayosiPt:int32; 10 | NakayosiCharacterID:int32; 11 | FirstTweetText:string; 12 | FirstTweetID:int32; 13 | FirstTweetAssetNo:int32; 14 | VisitType:int32; 15 | NGCharacterID:[int32]; 16 | NGSpotID:[int32]; 17 | } 18 | 19 | table SpotVisitRaw { 20 | Entries:[SpotVisitRawEntry]; 21 | } 22 | 23 | file_identifier "D4AO"; 24 | root_type SpotVisitRaw; 25 | 26 | -------------------------------------------------------------------------------- /dankagu/schema/StrengthenRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table StrengthenRawEntry { 4 | ID:int32; 5 | SameParamArray:[int32]; 6 | OtherParamArray:[int32]; 7 | } 8 | 9 | table StrengthenRaw { 10 | Entries:[StrengthenRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type StrengthenRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/SystemIntRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SystemIntRawEntry { 4 | ID:int64; 5 | Value:int64; 6 | } 7 | 8 | table SystemIntRaw { 9 | Entries:[SystemIntRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type SystemIntRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/SystemStringRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table SystemStringRawEntry { 4 | ID:int64; 5 | Value:string; 6 | } 7 | 8 | table SystemStringRaw { 9 | Entries:[SystemStringRawEntry]; 10 | } 11 | 12 | file_identifier "D4AO"; 13 | root_type SystemStringRaw; 14 | 15 | -------------------------------------------------------------------------------- /dankagu/schema/TitleBGRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table TitleBGRawEntry { 4 | ID:int32; 5 | DataVersion:int32; 6 | Enable:int32; 7 | ImageID:string; 8 | OpenAt:int64; 9 | CloseAt:int64; 10 | LogoMovieID:string; 11 | SysBgmID:int32; 12 | } 13 | 14 | table TitleBGRaw { 15 | Entries:[TitleBGRawEntry]; 16 | } 17 | 18 | file_identifier "D4AO"; 19 | root_type TitleBGRaw; 20 | 21 | -------------------------------------------------------------------------------- /dankagu/schema/TutorialAdvRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table TutorialAdvRawEntry { 4 | ID:int32; 5 | GroupID:int32; 6 | Style:int32; 7 | Chara:int32; 8 | Motion:string; 9 | Face:string; 10 | Pos:int32; 11 | Msg:string; 12 | AppearanceID:int32; 13 | Dir:int32; 14 | TargetBtn:string; 15 | Parent:string; 16 | FocusType:int32; 17 | } 18 | 19 | table TutorialAdvRaw { 20 | Entries:[TutorialAdvRawEntry]; 21 | } 22 | 23 | file_identifier "D4AO"; 24 | root_type TutorialAdvRaw; 25 | 26 | -------------------------------------------------------------------------------- /dankagu/schema/TutorialRGameRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table TutorialRGameRawEntry { 4 | ID:int64; 5 | NoteEventID:int64; 6 | Msg:string; 7 | Mode:int64; 8 | } 9 | 10 | table TutorialRGameRaw { 11 | Entries:[TutorialRGameRawEntry]; 12 | } 13 | 14 | file_identifier "D4AO"; 15 | root_type TutorialRGameRaw; 16 | 17 | -------------------------------------------------------------------------------- /dankagu/schema/TweetRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table TweetRawEntry { 4 | ID:int32; 5 | SortNo:int32; 6 | Enable:int32; 7 | DataVersion:int32; 8 | Title:string; 9 | Category:int32; 10 | AssetNo:int32; 11 | Character1ID:int32; 12 | Character2ID:int32; 13 | Character3ID:int32; 14 | SpotID:int32; 15 | Reconstruction:int32; 16 | NakayosiPt:int32; 17 | NakayosiCharacter1ID:int32; 18 | NakayosiCharacter2ID:int32; 19 | UnlockEpisodeID:int32; 20 | Character1Thumbnail:int32; 21 | Character2Thumbnail:int32; 22 | Character3Thumbnail:int32; 23 | ThumbnailBackgroundID:int32; 24 | Priority:int32; 25 | CharacterLv:int32; 26 | EventTweet:int32; 27 | } 28 | 29 | table TweetRaw { 30 | Entries:[TweetRawEntry]; 31 | } 32 | 33 | file_identifier "D4AO"; 34 | root_type TweetRaw; 35 | 36 | -------------------------------------------------------------------------------- /dankagu/schema/VCRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table VCRawEntry { 4 | ID:int32; 5 | Label:string; 6 | Paid:int32; 7 | } 8 | 9 | table VCRaw { 10 | Entries:[VCRawEntry]; 11 | } 12 | 13 | file_identifier "D4AO"; 14 | root_type VCRaw; 15 | 16 | -------------------------------------------------------------------------------- /dankagu/schema/WavRaw.fbs: -------------------------------------------------------------------------------- 1 | namespace D4L.TakashoFes.Master; 2 | 3 | table WavRawEntry { 4 | ID:int32; 5 | Enable:int32; 6 | DataVersion:int32; 7 | CuesheetID:int64; 8 | DecKey:int64; 9 | } 10 | 11 | table WavRaw { 12 | Entries:[WavRawEntry]; 13 | } 14 | 15 | file_identifier "D4AO"; 16 | root_type WavRaw; 17 | 18 | -------------------------------------------------------------------------------- /dankagu/sec_dankagu.php: -------------------------------------------------------------------------------- 1 | Init($seed & 0x7fffffff); 12 | if ($initSpin >= 1) { 13 | do { 14 | $XorShift->Next(); 15 | --$initSpin; 16 | } while ($initSpin); 17 | } 18 | $this->swizzleBytes = str_repeat(chr(0), $tableSize); 19 | $XorShift->MakeSwizzleTable($this->swizzleBytes); 20 | $this->Coef = ($XorShift->Next() & 0xf) + 3; // $v10 + 8 21 | $result = $XorShift->Next(); 22 | $this->offset = ($result & 0x1f) + 1; // $v10 + 12 23 | //print_r($this); 24 | //echo bin2hex($this->swizzleBytes); 25 | return $this; 26 | } 27 | function Modify(string &$dataBytes, $offset, $count, $streamOffset, $salt) { 28 | $v13 = 0; 29 | $v14 = strlen($this->swizzleBytes) - 1;// ((count($this->swizzleBytes) << 32) - 0x100000000) >> 32; 30 | do { 31 | $v20 = ($this->offset + ($streamOffset + $offset + $salt + $v13) * $this->Coef) & $v14; 32 | $dataBytes[$offset + $v13] = $this->swizzleBytes[$v20] ^ $dataBytes[$offset + $v13]; 33 | ++$v13; 34 | } while ($count != $v13); 35 | } 36 | function Transform($inputBytes, $inputOffset, $inputCount) { 37 | throw new BadMethodCallException(); 38 | } 39 | } 40 | class RijndaelEncryptor { 41 | private $key; 42 | private $iv; 43 | private $isDecrypt; 44 | function __construct($pw, $salt, bool $isDecrypt) 45 | { 46 | $rijnIter = 117; 47 | $buf = openssl_pbkdf2($pw, $salt, 32, $rijnIter); 48 | $this->key = substr($buf, 0, 16); 49 | $this->iv = substr($buf, 16, 16); 50 | $this->isDecrypt = $isDecrypt; 51 | } 52 | function Modify(string &$dataBytes, $offset, $count, $streamOffset, $salt) { 53 | throw new BadMethodCallException(); 54 | } 55 | function Transform($inputBytes, $inputOffset, $inputCount) { 56 | $data = substr($inputBytes, $inputOffset, $inputCount); 57 | if ($this->isDecrypt) { 58 | return openssl_decrypt($data, 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv); 59 | } else { 60 | return openssl_encrypt($data, 'AES-128-CBC', $this->key, OPENSSL_RAW_DATA, $this->iv); 61 | } 62 | } 63 | } 64 | 65 | class XorShift { 66 | private $lockObject; // object 0x10 67 | private $seed; // uint 0x18 68 | private $y; //uint 0x1c 69 | function __construct() 70 | { 71 | return $this; 72 | } 73 | function Init($seed) { 74 | $this->seed = $seed; 75 | $this->y = $seed; 76 | } 77 | function Next() { 78 | $v3 = $this->y ^ (($this->y << 13) & 0xffffffff); 79 | $v4 = $v3 ^ ($v3 >> 17) ^ (32 * ($v3 ^ ($v3 >> 17))) & 0xffffffff; 80 | $this->y = $v4; 81 | return $v4; 82 | } 83 | function MakeSwizzleTable(string &$dest) { 84 | $v5 = strlen($dest); 85 | if ($v5 >= 1) { 86 | $v4 = 0; 87 | do { 88 | $result = $this->Next(); 89 | $dest[$v4++] = chr(($result >> 3) & 0xff); 90 | } while ($v5 != $v4); 91 | } 92 | } 93 | static function SwizzleBytes(&$target, $swizzle, $coef, $offset, $start) { 94 | $count = strlen($target); 95 | if ($count >= 1) { 96 | $mask = strlen($swizzle) - 1; 97 | $k = $count + $start; 98 | for ($i = 0; $i < $count; ) { 99 | $k = ($offset + $k * $coef) & 0xffffffff; 100 | $target[$i] = $target[$i] ^ $swizzle[$k & $mask]; 101 | $i++; 102 | } 103 | } 104 | } 105 | function Range($min, $max) { 106 | // 107 | } 108 | function NextFloat() { 109 | // 110 | } 111 | } 112 | 113 | class Encryptor { 114 | static $encryptors; 115 | } 116 | 117 | Encryptor::$encryptors = [ 118 | 1001 => new RijndaelEncryptor('Pg97xygbey7aw', '857fesfd', true), 119 | 1002 => new LightWeightEncryptor(1749853741, 11, 512), 120 | 1003 => new LightWeightEncryptor(0xCE2B9A93, 13, 512), 121 | 1004 => new LightWeightEncryptor(874156713, 17, 512), 122 | 1501 => new RijndaelEncryptor('CgU6T5tehiGoZ', '37F741ED', true), 123 | 2001 => new LightWeightEncryptor(0x51C1D53, 17, 512), 124 | 2002 => new LightWeightEncryptor(0xF5F1B55, 13, 512), 125 | 2003 => new LightWeightEncryptor(0x28087953, 11, 512), 126 | ]; 127 | -------------------------------------------------------------------------------- /haifuri/main.php: -------------------------------------------------------------------------------- 1 | -1,'AppBuild'=>33); 7 | } else { 8 | $last_version = json_decode(file_get_contents('last_version'), true); 9 | } 10 | $logFile = fopen('haifuri.log', 'a'); 11 | function _log($s) { 12 | global $logFile; 13 | fwrite($logFile, date('[m/d H:i] ').$s."\n"); 14 | echo date('[m/d H:i] ').$s."\n"; 15 | } 16 | 17 | function GeneratePBKDF2Key($password, $salt) { 18 | return openssl_pbkdf2($password, $salt, 32, 32); 19 | } 20 | define("SAVEDATA_IV", hex2bin('1AF932518C58DCE9C2FA487EE96FB587')); 21 | define('SAVEDATA_KEY', GeneratePBKDF2Key('savedata', 'd1e95c245d961a35e3e354b73f3960de9a53a4b72197c53f9cfe7d3398f77eed')); 22 | define('MASTER_PASSWORD', 'nCG80L6W3FA3PdSv'); 23 | 24 | function EncryptSaveData($data) { 25 | return openssl_encrypt($data, 'AES-256-CBC', SAVEDATA_KEY, OPENSSL_RAW_DATA, SAVEDATA_IV); 26 | } 27 | function DecryptSaveData($data) { 28 | return openssl_decrypt($data, 'AES-256-CBC', SAVEDATA_KEY, OPENSSL_RAW_DATA, SAVEDATA_IV); 29 | } 30 | 31 | function EncryptMaster($data, $iv, $salt) { 32 | return openssl_encrypt($data, 'AES-256-CBC', GeneratePBKDF2Key(MASTER_PASSWORD, $salt), OPENSSL_RAW_DATA, hex2bin($iv)); 33 | } 34 | function DecryptMaster($data, $iv, $salt) { 35 | return openssl_decrypt($data, 'AES-256-CBC', GeneratePBKDF2Key(MASTER_PASSWORD, $salt), OPENSSL_RAW_DATA, hex2bin($iv)); 36 | } 37 | 38 | 39 | function main() { 40 | 41 | global $last_version; 42 | chdir(__DIR__); 43 | 44 | //check app ver at 00:00 45 | $appver = file_exists('appver') ? file_get_contents('appver') : '1.0.6'; 46 | $itunesid = 1304807840; 47 | $curl = curl_init(); 48 | curl_setopt_array($curl, array( 49 | CURLOPT_URL=>'https://itunes.apple.com/lookup?id='.$itunesid.'&lang=ja_jp&country=jp&rnd='.rand(10000000,99999999), 50 | CURLOPT_HEADER=>0, 51 | CURLOPT_RETURNTRANSFER=>1, 52 | CURLOPT_SSL_VERIFYPEER=>false 53 | )); 54 | $appinfo = curl_exec($curl); 55 | curl_close($curl); 56 | if ($appinfo !== false) { 57 | $appinfo = json_decode($appinfo, true); 58 | if (!empty($appinfo['results'][0]['version'])) { 59 | $prevappver = $appver; 60 | $appver = $appinfo['results'][0]['version']; 61 | 62 | if (version_compare($prevappver,$appver, '<')) { 63 | _log('new game version: '. $appver); 64 | file_put_contents('appver', $appver); 65 | $data = json_encode(array( 66 | 'game'=>'haifuri', 67 | 'ver'=>$appver, 68 | 'link'=>'https://itunes.apple.com/jp/app/id'.$itunesid, 69 | 'desc'=>$appinfo['results'][0]['releaseNotes'] 70 | )); 71 | $header = [ 72 | 'X-GITHUB-EVENT: app_update', 73 | 'X-HUB-SIGNATURE: sha1='.hash_hmac('sha1', $data, file_get_contents(__DIR__.'/../webhook_secret'), false) 74 | ]; 75 | $curl = curl_init(); 76 | curl_setopt_array($curl, array( 77 | CURLOPT_URL=>'https://redive.estertion.win/masterdb_subscription/webhook.php', 78 | CURLOPT_HEADER=>0, 79 | CURLOPT_RETURNTRANSFER=>1, 80 | CURLOPT_SSL_VERIFYPEER=>false, 81 | CURLOPT_HTTPHEADER=>$header, 82 | CURLOPT_POST=>1, 83 | CURLOPT_POSTFIELDS=>$data 84 | )); 85 | curl_exec($curl); 86 | curl_close($curl); 87 | } 88 | } 89 | } 90 | 91 | //check update 92 | $curl = curl_init(); 93 | $appbuildUpper = $last_version['AppBuild'] + 25; 94 | while (1) { 95 | $game_start_header = [ 96 | 'User-Agent: ', 97 | 'Content-Length: 0', 98 | 'Content-Type: application/octet-stream', 99 | 'X-ANX-AppVersion: '.$last_version['AppBuild'], 100 | 'X-ANX-MasterVersion: '.$last_version['MasterVer'], 101 | 'X-ANX-Nonce: '.preg_replace('/(.{8})(.{4})(.{4})(.{4})(.{12})/', '$1-$2-$3-$4-$5', bin2hex(openssl_random_pseudo_bytes(16))), 102 | 'X-ANX-Serialize: application/x-msgpack', 103 | 'X-ANX-Store: 1', 104 | 'X-ANX-Ts: '.time() 105 | ]; 106 | curl_setopt_array($curl, array( 107 | CURLOPT_URL => 'https://prd-app.haifuri.app/base/system', 108 | //CURLOPT_PROXY=>'127.0.0.1:50000', 109 | CURLOPT_HTTPHEADER=>$game_start_header, 110 | CURLOPT_HEADER=>0, 111 | CURLOPT_ENCODING=>'gzip', 112 | CURLOPT_RETURNTRANSFER=>1, 113 | CURLOPT_SSL_VERIFYPEER=>false 114 | )); 115 | $response = @msgpack_unpack(curl_exec($curl)); 116 | $code = curl_getinfo($curl, CURLINFO_HTTP_CODE); 117 | if ($code == 426) { 118 | _log('Build '.$last_version['AppBuild'].' outdated'); 119 | $last_version['AppBuild']++; 120 | if ($last_version['AppBuild'] >= $appbuildUpper) { 121 | _log('Max build guess exceeded, exiting'); 122 | return; 123 | } 124 | continue; 125 | } else if ($code == 410) { 126 | file_put_contents('last_version', json_encode($last_version)); 127 | break; 128 | } else if ($code == 200) { 129 | _log('no update found'); 130 | file_put_contents('last_version', json_encode($last_version)); 131 | return; 132 | } else { 133 | _log('invalid response: ['.$code.'] '. json_encode($response)); 134 | return; 135 | } 136 | } 137 | curl_close($curl); 138 | 139 | $MasterVer = $response['Version']; 140 | 141 | global $curl; 142 | $curl = curl_init(); 143 | $last_version['MasterVer'] = $MasterVer; 144 | _log("MasterVer: ${MasterVer}"); 145 | file_put_contents('data/!MasterVer.txt', $MasterVer."\n"); 146 | file_put_contents('data/MasterHashes.json', prettifyJSON(json_encode($response, JSON_UNESCAPED_SLASHES+JSON_UNESCAPED_UNICODE))); 147 | curl_setopt_array($curl, [ 148 | CURLOPT_RETURNTRANSFER=>true, 149 | //CURLOPT_PROXY=>'127.0.0.1:50000', 150 | CURLOPT_HEADER=>false, 151 | CURLOPT_SSL_VERIFYPEER=>false, 152 | CURLOPT_CONNECTTIMEOUT=>5 153 | ]); 154 | 155 | $updateAsset = false; 156 | foreach ($response['Signatures'] as $item) { 157 | $fname = 'data/'.$item['MasterName'].'.json'; 158 | if (isset($last_version[$item['MasterName']]) && $last_version[$item['MasterName']] == $item['Sha1']) continue; 159 | if ($item['MasterName'] == 'AssetVersions') $updateAsset = true; 160 | _log('Downloading '. $item['MasterName']. ', Size: '.$item['Size'].' Sha1: '.$item['Sha1']); 161 | curl_setopt($curl, CURLOPT_URL, 'https://prd-static.haifuri.app/masters/'.$item['Signature'].'.j'); 162 | $response = curl_exec($curl); 163 | if (strlen($response) != $item['Size'] || sha1($response) != $item['Sha1']) { 164 | _log('failed'); 165 | continue; 166 | } 167 | $dec = DecryptMaster($response, $item['Iv'], $item['Salt']); 168 | fclose(fopen($fname, 'w')); 169 | prettifyJSON(json_encode(json_decode($dec, true), JSON_UNESCAPED_SLASHES+JSON_UNESCAPED_UNICODE), new FileStream($fname), false); 170 | $last_version[$item['MasterName']] = $item['Sha1']; 171 | } 172 | 173 | if ($updateAsset) { 174 | $AssetVersions = json_decode(file_get_contents('data/AssetVersions.json'), true); 175 | $assetVer = []; 176 | foreach ($AssetVersions['Rows'] as $row) { 177 | $assetVer[['AndroidAssets'=>'android', 'iOSAssets'=>'ios'][$row['Name']]] = $row['Version']; 178 | } 179 | foreach ($assetVer as $platform => $ver) { 180 | _log("Downloading assets manifest ver $ver for $platform"); 181 | curl_setopt($curl, CURLOPT_URL, "https://prd-static.haifuri.app/assets/$platform/$ver/FileSystemOverrideRecords"); 182 | $manifest = gzdecode(DecryptSaveData(curl_exec($curl))); 183 | fclose(fopen("data/AssetManifest_${platform}.json", 'w')); 184 | prettifyJSON(json_encode(json_decode($manifest), JSON_UNESCAPED_SLASHES+JSON_UNESCAPED_UNICODE), new FileStream("data/AssetManifest_${platform}.json"), false); 185 | } 186 | } 187 | 188 | file_put_contents('last_version', json_encode($last_version)); 189 | 190 | chdir('data'); 191 | exec('git add *.json !MasterVer.txt'); 192 | exec('git commit -m '.$MasterVer); 193 | exec('git push origin master'); 194 | if ($updateAsset) checkAndUpdateResource($assetVer['ios']); 195 | _log('finished'); 196 | 197 | } 198 | 199 | main(); 200 | 201 | 202 | function prettifyJSON($in, Stream $out = NULL, $returnData = true) { 203 | $in = new MemoryStream($in); 204 | if ($out == NULL) $out = new MemoryStream(''); 205 | 206 | $offset = 0; 207 | $length = $in->size; 208 | 209 | $level = 0; 210 | while($offset < $length) { 211 | $char = $in->readData(1); 212 | switch($char) { 213 | case '"': 214 | // write until unqoute 215 | $out->write($char); 216 | $skipNext = false; 217 | while (1) { 218 | $char = $in->readData(1); 219 | $out->write($char); 220 | $offset++; 221 | if ($skipNext) $skipNext = false; 222 | else { 223 | if ($char == '\\') $skipNext = true; 224 | else if ($char == '"') break; 225 | } 226 | } 227 | break; 228 | case '{': 229 | case '[': 230 | // increase level 231 | $level++; 232 | $out->write($char); 233 | $out->write("\n".str_repeat(' ', $level)); 234 | break; 235 | case '}': 236 | case ']': 237 | $level--; 238 | $nextChar = $in->readData(1); 239 | if ($nextChar == ',') { 240 | $out->write("\n".str_repeat(' ', $level)); 241 | $out->write($char); 242 | $out->write($nextChar); 243 | $out->write("\n".str_repeat(' ', $level)); 244 | $offset++; 245 | } else { 246 | $out->write("\n".str_repeat(' ', $level)); 247 | $out->write($char); 248 | if ($nextChar == '') $out->write("\n"); 249 | $in->seek($offset+1); 250 | } 251 | break; 252 | case ',': 253 | // add space after comma 254 | $out->write($char); 255 | $out->write(' '); 256 | break; 257 | default: 258 | $out->write($char); 259 | } 260 | $offset++; 261 | } 262 | if (!$returnData) return; 263 | $out->seek(0); 264 | $output = $out->readData($out->size); 265 | unset($out); 266 | return $output; 267 | } 268 | -------------------------------------------------------------------------------- /haifuri/resource_fetch.php: -------------------------------------------------------------------------------- 1 | '/^cdtl\d+$/', 'nameMatch'=>'/^cas_(\d+)$/', 'exportTo'=>'card/$1' ] 9 | ]; 10 | 11 | function shouldExportFile($name, $rule) { 12 | return preg_match($rule['nameMatch'], $name) != 0; 13 | } 14 | 15 | $cacheHashDb = new PDO('sqlite:'.__DIR__.'/cacheHash.db'); 16 | $chkHashStmt = $cacheHashDb->prepare('SELECT hash FROM cacheHash WHERE res=?'); 17 | function shouldUpdate($name, $hash) { 18 | global $chkHashStmt; 19 | $chkHashStmt->execute([$name]); 20 | $row = $chkHashStmt->fetch(); 21 | return !(!empty($row) && $row['hash'] == $hash); 22 | } 23 | $setHashStmt = $cacheHashDb->prepare('REPLACE INTO cacheHash (res,hash) VALUES (?,?)'); 24 | function setHashCached($name, $hash) { 25 | global $setHashStmt; 26 | $setHashStmt->execute([$name, $hash]); 27 | } 28 | 29 | function findRule($name, $rules) { 30 | foreach ($rules as $rule) { 31 | if (preg_match($rule['bundleNameMatch'], $name) != 0) return $rule; 32 | } 33 | return false; 34 | } 35 | 36 | define('RESOURCE_PATH_PREFIX', '/data/home/web/_redive/haifuri/'); 37 | //define('RESOURCE_PATH_PREFIX', 'D:/cygwin64/home/ester/quickcode/cgss/'); 38 | 39 | function checkAndUpdateResource($ver) { 40 | global $resourceToExport; 41 | global $curl; 42 | global $poseData; 43 | chdir(__DIR__); 44 | $currenttime = time(); 45 | curl_setopt_array($curl, array( 46 | CURLOPT_CONNECTTIMEOUT=>5, 47 | CURLOPT_RETURNTRANSFER=>true, 48 | CURLOPT_HEADER=>0, 49 | CURLOPT_SSL_VERIFYPEER=>false 50 | )); 51 | $manifest = json_decode(file_get_contents('data/AssetManifest_ios.json'), true); 52 | 53 | foreach ($manifest['Rows'] as $info) { 54 | $name = $info['FileName']; 55 | $hash = $info['ContentHash']; 56 | if (($rule = findRule($name, $resourceToExport)) !== false && shouldUpdate($name, $hash)) { 57 | _log('download '. $name); 58 | curl_setopt_array($curl, array( 59 | CURLOPT_URL=>"https://prd-static.haifuri.app/assets/ios/$ver/".$info['DownloadName'], 60 | CURLOPT_HTTPHEADER=>['Range: bytes='.$info['AssetOffset'].'-'.($info['AssetOffset'] + $info['AssetLength'] - 1)] 61 | )); 62 | $bundleData = curl_exec($curl); 63 | $dlHash = hash('sha1', $bundleData); 64 | if ($dlHash != $hash) { 65 | _log('download failed '.$name. ' '.json_encode(['expected'=>$hash,'received'=>$dlHash,'len'=>strlen($bundleData)])); 66 | continue; 67 | } 68 | if ($info['Crypto']) $bundleData = DecryptSaveData($bundleData); 69 | $bundleData = new MemoryStream($bundleData); 70 | $assets = extractBundle($bundleData); 71 | 72 | try{ 73 | 74 | foreach ($assets as $asset) { 75 | if (substr($asset, -5,5) == '.resS') continue; 76 | $asset = new AssetFile($asset); 77 | 78 | foreach ($asset->preloadTable as &$item) { 79 | if ($item->typeString == 'Texture2D') { 80 | $item = new Texture2D($item, true); 81 | if (isset($rule['print'])) { 82 | var_dump($item->name); 83 | continue; 84 | } 85 | $itemname = $item->name; 86 | if (isset($rule['namePrefix'])) { 87 | $itemname = preg_replace($rule['bundleNameMatch'], $rule['namePrefix'], $name).$itemname; 88 | } 89 | if (isset($rule['namePrefixCb'])) { 90 | $itemname = preg_replace_callback($rule['bundleNameMatch'], $rule['namePrefixCb'], $name).$itemname; 91 | } 92 | if (shouldExportFile($itemname, $rule)) { 93 | $saveTo = RESOURCE_PATH_PREFIX. preg_replace($rule['nameMatch'], $rule['exportTo'], $itemname); 94 | $item->exportTo($saveTo, 'webp', '-lossless 1'); 95 | touch($saveTo. '.webp', $currenttime); 96 | } 97 | unset($item); 98 | } 99 | } 100 | $asset->__desctruct(); 101 | unset($asset); 102 | gc_collect_cycles(); 103 | } 104 | 105 | } catch(Exception $e) { 106 | $asset->__desctruct(); 107 | unset($asset); 108 | _log('Not supported: '. $e->getMessage()); 109 | } 110 | 111 | foreach ($assets as $asset) { 112 | unlink($asset); 113 | } 114 | unset($bundleData); 115 | if (isset($rule['print'])) exit; 116 | setHashCached($name, $hash); 117 | } 118 | } 119 | } 120 | 121 | if (defined('TEST_SUITE') && TEST_SUITE == __FILE__) { 122 | function GeneratePBKDF2Key($password, $salt) { 123 | return openssl_pbkdf2($password, $salt, 32, 32); 124 | } 125 | define("SAVEDATA_IV", hex2bin('1AF932518C58DCE9C2FA487EE96FB587')); 126 | define('SAVEDATA_KEY', GeneratePBKDF2Key('savedata', 'd1e95c245d961a35e3e354b73f3960de9a53a4b72197c53f9cfe7d3398f77eed')); 127 | 128 | function EncryptSaveData($data) { 129 | return openssl_encrypt($data, 'AES-256-CBC', SAVEDATA_KEY, OPENSSL_RAW_DATA, SAVEDATA_IV); 130 | } 131 | function DecryptSaveData($data) { 132 | return openssl_decrypt($data, 'AES-256-CBC', SAVEDATA_KEY, OPENSSL_RAW_DATA, SAVEDATA_IV); 133 | } 134 | chdir(__DIR__); 135 | $curl = curl_init(); 136 | function _log($s) {echo date('[m/d H:i:s] ').$s."\n";} 137 | $AssetVersions = json_decode(file_get_contents('data/AssetVersions.json'), true); 138 | $assetVer = []; 139 | foreach ($AssetVersions['Rows'] as $row) { 140 | $assetVer[['AndroidAssets'=>'android', 'iOSAssets'=>'ios'][$row['Name']]] = $row['Version']; 141 | } 142 | checkAndUpdateResource($assetVer['ios']); 143 | //print_r(extractBundle(new FileStream('bundle/-card_bg_100062.unity3d'))); 144 | /*$asset = new AssetFile('CAB-ed8bb316f8c8bc10b8cb0f403c1e3f35'); 145 | foreach ($asset->preloadTable as &$item) { 146 | if ($item->typeString == 'Texture2D') { 147 | $item = new Texture2D($item, true); 148 | _log($item->name); 149 | $item->exportTo($item->name, 'bmp'); 150 | } 151 | }*/ 152 | } 153 | //print_r($asset); 154 | 155 | -------------------------------------------------------------------------------- /llas/main.php: -------------------------------------------------------------------------------- 1 | 'https://allstars.kirara.ca/api/v1/master_version.json', 15 | CURLOPT_HEADER=>0, 16 | CURLOPT_RETURNTRANSFER=>1, 17 | CURLOPT_SSL_VERIFYPEER=>false 18 | )); 19 | 20 | $verInfo = json_decode(curl_exec($curl), true); 21 | if (empty($verInfo) || empty($verInfo['version'])) { 22 | _log('fetch version info failed'); 23 | exit; 24 | } 25 | $version = $verInfo['version']; 26 | if ($version == trim(file_get_contents('data/!masterdata_version.txt'))) { 27 | _log('no update'); 28 | exit; 29 | } 30 | _log("new version: $version"); 31 | $urlBase = "https://jp-real-prod-v4tadlicuqeeumke.api.game25.klabgames.net/ep1001/static/$version"; 32 | curl_setopt($curl, CURLOPT_URL, "$urlBase/masterdata_i_ja"); 33 | $masterdata = curl_exec($curl); 34 | 35 | $f = new MemoryStream($masterdata); 36 | $f->position = 20; 37 | $hash = ReadString($f); 38 | $lang = ReadString($f); 39 | $rows = ReadInt($f); 40 | 41 | $out = []; 42 | for ($i=0; $i < $rows; $i++) { 43 | $v15 = ReadString($f); // db name 44 | $v16 = ReadString($f); // db keys 45 | $out[] = [$v15, $v16, GetKeyData($v16)]; 46 | } 47 | for ($i=0; $i < $rows; $i++) { 48 | $out[$i][] = bin2hex($f->readData(20)); // download sha1 hash 49 | $out[$i][] = ReadInt($f); // download file size 50 | } 51 | $db = new PDO('sqlite::memory:'); 52 | $db->query('pragma JOURNAL_MODE=MEMORY'); 53 | $db->query('CREATE TABLE masterdata(name TEXT NOT NULL, keys TEXT NOT NULL, hash TEXT NOT NULL, size INTEGER NOT NULL)'); 54 | $insert = $db->prepare('INSERT INTO masterdata (name,keys,hash,size) VALUES (?,?,?,?)'); 55 | foreach ($out as $row) { 56 | $insert->execute([$row[0], $row[1], $row[3], $row[4]]); 57 | } 58 | chdir('data'); 59 | $output = []; 60 | exec('git rm -rf --ignore-unmatch -q */', $output); 61 | chdir('..'); 62 | exportSqlite($db, 'data'); 63 | 64 | $constKeys = [ 65 | 0x3039, // 12345 66 | 0x10932,// 67890 67 | 0x7AB7 // 31415 68 | ]; 69 | $retry = 0; 70 | for ($i=0; $ibyte)); 107 | } 108 | function ReadInt(Stream $f) { 109 | $val = ReadByte($f); 110 | if ($val >= 128) { 111 | $b2 = ReadByte($f); 112 | $b3 = ReadByte($f); 113 | $b4 = ReadByte($f); 114 | $val = $val + (($b2 + (($b3 + ($b4 << 8)) << 8)) << 7); 115 | } 116 | return $val; 117 | } 118 | function ReadString(Stream $f) { 119 | $strlen = ReadInt($f); 120 | return $f->readData($strlen); 121 | } 122 | function GetKeyData($k) { 123 | $keys = []; 124 | for ($i=0; $i> 24) & 0xff); 132 | $key0 = (0x343fd * $key0 + 0x269ec3) & 0xFFFFFFFF; 133 | $key1 = (0x343fd * $key1 + 0x269ec3) & 0xFFFFFFFF; 134 | $key2 = (0x343fd * $key2 + 0x269ec3) & 0xFFFFFFFF; 135 | } 136 | return $data; 137 | } 138 | 139 | function encodeValue($value) { 140 | $arr = []; 141 | foreach ($value as $key=>$val) { 142 | $arr[] = '/*'.$key.'*/' . (is_numeric($val) ? $val : ('"'.str_replace('"','\\"',$val).'"')); 143 | } 144 | return implode(", ", $arr); 145 | } 146 | function exportSqlite(PDO $db, string $path) { 147 | if (!is_dir($path)) { 148 | if (file_exists($path)) throw new Exception('output path is not directory'); 149 | mkdir($path, 0777, true); 150 | } 151 | 152 | $tables = $db->query('SELECT * FROM sqlite_master')->fetchAll(PDO::FETCH_ASSOC); 153 | foreach ($tables as $entry) { 154 | if ($entry['name'] == 'sqlite_stat1') continue; 155 | if ($entry['type'] == 'table') { 156 | $tblName = $entry['name']; 157 | $f = fopen("$path/${tblName}.sql", 'w'); 158 | fwrite($f, $entry['sql'].";\n"); 159 | $values = $db->query("SELECT * FROM ${tblName}"); 160 | while($value = $values->fetch(PDO::FETCH_ASSOC)) { 161 | fwrite($f, "INSERT INTO `${tblName}` VALUES (".encodeValue($value).");\n"); 162 | } 163 | fclose($f); 164 | } else if ($entry['type'] == 'index' && $entry['sql']) { 165 | $tblName = $entry['tbl_name']; 166 | file_put_contents("$path/${tblName}.sql", $entry['sql'].";\n", FILE_APPEND); 167 | } 168 | //echo "\r".++$i.'/'.count($tables); 169 | } 170 | } 171 | 172 | /* 173 | Read assets: (not tested) 174 | SIFAS_Decrypt_Stream($encrypted_asset_data, 12345, $key1, $key2) 175 | $key1 & $key2 from asset_i_ja_0.db 176 | */ 177 | -------------------------------------------------------------------------------- /redive/Coneshell_call/coneshell_cdb_ver2.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esterTion/unity-texture-toolkit/91a5abf59ba121a8a10bc0083ede580787ecd7d2/redive/Coneshell_call/coneshell_cdb_ver2.7z -------------------------------------------------------------------------------- /redive/Coneshell_call/coneshell_cdb_ver3.7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/esterTion/unity-texture-toolkit/91a5abf59ba121a8a10bc0083ede580787ecd7d2/redive/Coneshell_call/coneshell_cdb_ver3.7z -------------------------------------------------------------------------------- /redive/Coneshell_call/main.cpp: -------------------------------------------------------------------------------- 1 | /** 2 | * coneshell.dll caller 3 | * @author EAirPeter & esterTion 4 | * coneshell.dll is from (c)Cygames Inc. 5 | */ 6 | #define _CRT_SECURE_NO_WARNINGS 7 | #define _WIN32_LEAN_AND_MEAN 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | using namespace std; 16 | 17 | #include 18 | 19 | #include "sqlite3.h" 20 | 21 | template 22 | decltype(auto) Wrap(Obj *ptr, Del del) { 23 | return std::unique_ptr(ptr, del); 24 | } 25 | std::string ReadAll(const char *file) { 26 | std::string res; 27 | auto f = Wrap(fopen(file, "rb"), &fclose); 28 | char buf[4096]; 29 | while (!feof(f.get())) 30 | res.append(buf, fread(buf, 1, sizeof(buf), f.get())); 31 | return res; 32 | } 33 | void WriteAll(const char *file, const char* data, int length) { 34 | auto f = Wrap(fopen(file, "wb"), &fclose); 35 | int wrote = 0; 36 | int nextChunk = 4096; 37 | while (wrote < length) { 38 | wrote += 4096; 39 | if (wrote > length) { 40 | nextChunk -= wrote - length; 41 | } 42 | fwrite(data + wrote - 4096, 1, nextChunk, f.get()); 43 | } 44 | } 45 | string hex2bin(string hex) { 46 | if (hex.length() % 2 != 0) { 47 | return NULL; 48 | } 49 | string val = ""; 50 | int len = hex.length(); 51 | for (int i = 0; i < len; i += 2) { 52 | char byte = 0; 53 | char c; 54 | c = hex[i]; 55 | if (c >= '0' && c <= '9') byte = (c - '0') << 4; 56 | else if (c >= 'A' && c <= 'F') byte = (c - 'A' + 10) << 4; 57 | else if (c >= 'a' && c <= 'f') byte = (c - 'a' + 10) << 4; 58 | else return NULL; 59 | 60 | c = hex[i + 1]; 61 | if (c >= '0' && c <= '9') byte |= (c - '0'); 62 | else if (c >= 'A' && c <= 'F') byte |= (c - 'A' + 10); 63 | else if (c >= 'a' && c <= 'f') byte |= (c - 'a' + 10); 64 | else return NULL; 65 | val += byte; 66 | } 67 | return val; 68 | } 69 | 70 | int main(int argc, const char* argv[]) { 71 | //auto h = Wrap(LoadLibraryA("E:/Game/DMM/priconner/PrincessConnectReDive_Data/Plugins/coneshell.dll"), &FreeLibrary); 72 | auto h = Wrap(LoadLibraryA("coneshell.dll"), &FreeLibrary); 73 | using Int = std::int32_t; 74 | using Long = std::int64_t; 75 | using IntPtr = void *; 76 | using ByteArray = char *; 77 | auto *_fx00 = (IntPtr(*)()) GetProcAddress(h.get(), "_fx00"); 78 | auto *_a = (IntPtr(*)()) _fx00(); // 获取函数指针 79 | auto *_e = (Int(*)(IntPtr, ByteArray, Int, ByteArray, Int)) _a(); // Pack(IntPtr out, ByteArray body, int bodyLen, ByteArray iv, int unk) 80 | auto *_g = (Int(*)(IntPtr, ByteArray, Int)) _a(); // Unpack(IntPtr out, ByteArray body, int bodyLen) 81 | auto *_h = (Int(*)(IntPtr, Int, IntPtr, Int)) _a(); // DecompressUnpacked(IntPtr out, int decompressedSize, IntPtr body, int bodyLen) 82 | auto *_c = (void(*)()) _a(); // ResetContext() 83 | auto *_i = (IntPtr(*)(ByteArray, Long, ByteArray)) _a(); // OpenCustomVFS(ByteArray cdb, int cdbSize, ByteArray dbName) 84 | auto *_j = (void(*)(IntPtr)) _a(); // CloseVFS(IntPtr vfsHandle) 85 | auto *_b = (Int(*)(ByteArray, ByteArray)) _a(); // InitializeContext(udid, key) 86 | auto *_d = (Int(*)(Int, Int)) _a(); // GetPackedSize(int bodySize) 87 | auto *_f = (Int(*)(Int)) _a(); // GetUnpackedSize(int bodySize) 88 | 89 | if (argc < 4) { 90 | cerr << endl << "Not enough param" << endl 91 | << "\t-cdb\t\t \tunpack cdb" << endl; 92 | Sleep(3000LL); 93 | return 1; 94 | } 95 | string mode = argv[1]; 96 | if (mode == "-cdb") { 97 | auto cdb = ReadAll(argv[2]); 98 | char name[]{ "master.mdb" }; 99 | //pre key transformation 100 | if (cdb[3] == 3) { 101 | uint8_t *cdbChar = (uint8_t*)cdb.data(); 102 | uint64_t v12 = 0; 103 | uint64_t v13, v14, v15, v16; 104 | uint8_t v109[16]; 105 | v13 = 2 106 | * ((((((((unsigned __int64)cdbChar[32] << 56) & 0xFF00FFFFFFFFFFFFLL | ((unsigned __int64)cdbChar[33] << 48)) & 0xFFFF00FFFFFFFFFFLL | ((unsigned __int64)cdbChar[34] << 40)) & 0xFFFFFF00FFFFFFFFLL | ((unsigned __int64)cdbChar[35] << 32)) & 0xFFFFFFFF00FFFFFFLL | ((unsigned __int64)cdbChar[36] << 24)) & 0xFFFFFFFFFF00FFFFLL | ((unsigned __int64)cdbChar[37] << 16)) & 0xFFFFFFFFFFFF00FFLL | ((unsigned __int64)cdbChar[38] << 8) | cdbChar[39]) | 1; 107 | v14 = v13 108 | + 0x5851F42D4C957F2DLL 109 | * (v13 110 | + ((((((((unsigned __int64)cdbChar[24] << 56) & 0xFF00FFFFFFFFFFFFLL | ((unsigned __int64)cdbChar[25] << 48)) & 0xFFFF00FFFFFFFFFFLL | ((unsigned __int64)cdbChar[26] << 40)) & 0xFFFFFF00FFFFFFFFLL | ((unsigned __int64)cdbChar[27] << 32)) & 0xFFFFFFFF00FFFFFFLL | ((unsigned __int64)cdbChar[28] << 24)) & 0xFFFFFFFFFF00FFFFLL | ((unsigned __int64)cdbChar[29] << 16)) & 0xFFFFFFFFFFFF00FFLL | ((unsigned __int64)cdbChar[30] << 8) | cdbChar[31])); 111 | v15 = 2 112 | * ((((((((unsigned __int64)cdbChar[12] << 56) & 0xFF00FFFFFFFFFFFFLL | ((unsigned __int64)cdbChar[13] << 48)) & 0xFFFF00FFFFFFFFFFLL | ((unsigned __int64)cdbChar[14] << 40)) & 0xFFFFFF00FFFFFFFFLL | ((unsigned __int64)cdbChar[15] << 32)) & 0xFFFFFFFF00FFFFFFLL | ((unsigned __int64)cdbChar[16] << 24)) & 0xFFFFFFFFFF00FFFFLL | ((unsigned __int64)cdbChar[17] << 16)) & 0xFFFFFFFFFFFF00FFLL | ((unsigned __int64)cdbChar[18] << 8) | cdbChar[19]) | 1; 113 | v16 = v15 114 | + 0x5851F42D4C957F2DLL 115 | * (v15 116 | + ((((((((unsigned __int64)cdbChar[4] << 56) & 0xFF00FFFFFFFFFFFFLL | ((unsigned __int64)cdbChar[5] << 48)) & 0xFFFF00FFFFFFFFFFLL | ((unsigned __int64)cdbChar[6] << 40)) & 0xFFFFFF00FFFFFFFFLL | ((unsigned __int64)cdbChar[7] << 32)) & 0xFFFFFFFF00FFFFFFLL | ((unsigned __int64)cdbChar[8] << 24)) & 0xFFFFFFFFFF00FFFFLL | ((unsigned __int64)cdbChar[9] << 16)) & 0xFFFFFFFFFFFF00FFLL | ((unsigned __int64)cdbChar[10] << 8) | cdbChar[11])); 117 | do 118 | { 119 | uint64_t v17 = v13 + 0x5851F42D4C957F2DLL * v14; 120 | uint64_t v18 = _lrotr((v14 ^ (v14 >> 18)) >> 27, v14 >> 59); 121 | uint64_t v19 = _lrotr((v16 ^ (v16 >> 18)) >> 27, v16 >> 59); 122 | v109[v12] = v18 ^ v19; 123 | uint64_t v20 = 0LL; 124 | uint64_t v21 = 1LL; 125 | if (v19) 126 | { 127 | uint64_t v22 = v13; 128 | uint64_t v23 = 6364136223846793005LL; 129 | v19 = (unsigned int)v19; 130 | do 131 | { 132 | if (v19 & 1) 133 | v21 *= v23; 134 | if (v19 & 1) 135 | v20 = v22 + v23 * v20; 136 | v22 *= v23 + 1; 137 | v23 *= v23; 138 | v19 >>= 1; 139 | } while (v19); 140 | } 141 | uint64_t v24 = v15 + 0x5851F42D4C957F2DLL * v16; 142 | v14 = v20 + v21 * v17; 143 | uint64_t v25 = 0LL; 144 | uint64_t v26 = 1LL; 145 | if (v18) 146 | { 147 | uint64_t v27 = v15; 148 | uint64_t v28 = 0x5851F42D4C957F2DLL; 149 | v18 = (unsigned int)v18; 150 | do 151 | { 152 | if (v18 & 1) 153 | v26 *= v28; 154 | if (v18 & 1) 155 | v25 = v27 + v28 * v25; 156 | v27 *= v28 + 1; 157 | v28 *= v28; 158 | v18 >>= 1; 159 | } while (v18); 160 | } 161 | v16 = v25 + v26 * v24; 162 | ++v12; 163 | } while (v12 != 16); 164 | int i = 0; 165 | do { 166 | cdbChar[4 + i] = cdbChar[20 + i]; 167 | } while (++i != 4); 168 | i = 0; 169 | do { 170 | cdbChar[8 + i] = v109[i]; 171 | } while (++i != 16); 172 | cdbChar[3] = 2; 173 | } 174 | else if (cdb[3] != 2) { 175 | return -1; 176 | } 177 | // prepare cdb to vfs 178 | auto vfs = _i((ByteArray)cdb.data(), (Long)cdb.size(), name); 179 | if (vfs == NULL) { 180 | return -1; 181 | } 182 | int* dbSize = (int*)((char*)vfs + 0x58); 183 | char* dbData = (char*)vfs + 0x1000; 184 | WriteAll(argv[3], dbData, *dbSize); 185 | return 0; 186 | 187 | auto res = sqlite3_vfs_register((sqlite3_vfs *)vfs, 0); 188 | if (res) 189 | return res; 190 | sqlite3 *psrc; 191 | res = sqlite3_open_v2(name, &psrc, SQLITE_OPEN_READONLY, name); 192 | if (res) 193 | return res; 194 | auto src = Wrap(psrc, &sqlite3_close); 195 | sqlite3 *pdst; 196 | res = sqlite3_open(argv[3], &pdst); 197 | if (res) 198 | return res; 199 | auto dst = Wrap(pdst, &sqlite3_close); 200 | auto pbk = sqlite3_backup_init(pdst, "main", psrc, "main"); 201 | if (!pbk) 202 | return -1; 203 | auto bk = Wrap(pbk, &sqlite3_backup_finish); 204 | res = sqlite3_backup_step(pbk, -1); 205 | if (res != SQLITE_DONE) 206 | return res; 207 | return 0; 208 | } 209 | else { 210 | cerr << endl << "Not recognized param" << endl 211 | << "\t-cdb\t\t \tunpack cdb" << endl; 212 | return 1; 213 | } 214 | } 215 | -------------------------------------------------------------------------------- /redive/db-remap.php: -------------------------------------------------------------------------------- 1 | query('SELECT name FROM sqlite_master WHERE type="table"')->fetchAll(PDO::FETCH_COLUMN); 11 | 12 | $normalTables = array_filter($tableNames, function($name) { 13 | return !preg_match('/^v1_/', $name); 14 | }); 15 | $encryptedTables = array_filter($tableNames, function($name) { 16 | return preg_match('/^v1_/', $name); 17 | }); 18 | 19 | sort($normalTables); 20 | sort($encryptedTables); 21 | 22 | $nameMap = []; 23 | foreach ($encryptedTables as $encryptedTableName) { 24 | //echo "$encryptedTableName\t"; 25 | $firstRow = $db->query("SELECT * FROM $encryptedTableName LIMIT 1")->fetch(PDO::FETCH_ASSOC); 26 | if ($firstRow === false) { 27 | //echo "\n"; 28 | continue; 29 | } 30 | $columnCount = count($firstRow); 31 | $columnNames = array_keys($firstRow); 32 | $firstRowValues = array_values($firstRow); 33 | 34 | $matches = []; 35 | 36 | foreach ($normalTables as $normalTableName) { 37 | if (isset($nameMap[$normalTableName])) { 38 | continue; 39 | } 40 | $normalFirstRow = $db->query("SELECT * FROM $normalTableName LIMIT 1")->fetch(PDO::FETCH_ASSOC); 41 | if ($normalFirstRow === false) { 42 | continue; 43 | } 44 | $normalColumnCount = count($normalFirstRow); 45 | if ($columnCount !== $normalColumnCount) { 46 | continue; 47 | } 48 | $normalColumnNames = array_keys($normalFirstRow); 49 | $normalFirstRowValues = array_values($normalFirstRow); 50 | $diff = array_diff($firstRowValues, $normalFirstRowValues); 51 | if (!empty($diff)) { 52 | continue; 53 | } 54 | 55 | // check values row by row 56 | $isDiff = false; 57 | $encryptedRows = $db->query("SELECT * FROM $encryptedTableName"); 58 | $normalRows = $db->query("SELECT * FROM $normalTableName"); 59 | if ($encryptedRows->rowCount() !== $normalRows->rowCount()) { 60 | continue; 61 | } 62 | while ($encryptedRow = $encryptedRows->fetch(PDO::FETCH_NUM)) { 63 | $normalRow = $normalRows->fetch(PDO::FETCH_NUM); 64 | if ($encryptedRow !== $normalRow) { 65 | $isDiff = true; 66 | break; 67 | } 68 | } 69 | if ($isDiff) { 70 | continue; 71 | } 72 | //echo "$normalTableName\t"; 73 | $nameMap[$normalTableName] = $encryptedTableName; 74 | $matches[] = $normalTableName; 75 | break; 76 | } 77 | //echo "\n"; 78 | 79 | $columnMap = []; 80 | for ($i=0; $i<$columnCount; $i++) { 81 | $columnMap[$normalColumnNames[$i]] = $columnNames[$i]; 82 | } 83 | $nameMap[$normalTableName] = [ 84 | 'table' => $nameMap[$normalTableName], 85 | 'column' => $columnMap, 86 | ]; 87 | } 88 | 89 | ksort($nameMap); 90 | //print_r($nameMap); 91 | file_put_contents('nameMap.json', json_encode($nameMap, JSON_PRETTY_PRINT)); 92 | 93 | -------------------------------------------------------------------------------- /rizline/main.php: -------------------------------------------------------------------------------- 1 | true, 21 | CURLOPT_SSL_VERIFYPEER=>false, 22 | CURLOPT_HEADER=>false, 23 | CURLOPT_URL=>"${dlUrl}iOS/catalog_catalog.hash", 24 | ]); 25 | $hash = curl_exec($ch); 26 | $oldHash = file_exists("catalog_hash-$branch.txt") ? file_get_contents("catalog_hash-$branch.txt") : ''; 27 | var_dump($hash); 28 | if (empty($hash) || strlen($hash) != 32) { 29 | // failed 30 | _log("dl catalog hash failed for ${branch}"); 31 | return; 32 | } 33 | if ($hash === $oldHash) { 34 | // same 35 | return; 36 | } 37 | curl_setopt($ch, CURLOPT_URL, "${dlUrl}iOS/catalog_catalog.json"); 38 | $list = json_decode(curl_exec($ch), true); 39 | if ($list === NULL) { 40 | _log("dl catalog json failed for $branch"); 41 | return; 42 | } 43 | 44 | _log("$branch new catalog hash - $hash"); 45 | file_put_contents("catalog_hash-$branch.txt", $hash); 46 | chdir('data'); 47 | exec("git symbolic-ref HEAD refs/heads/${branch}"); 48 | exec('git reset'); 49 | exec('git rm -r .'); 50 | 51 | file_put_contents('catalog_catalog.json', json_encode($list, JSON_UNESCAPED_SLASHES+JSON_UNESCAPED_UNICODE+JSON_PRETTY_PRINT)); 52 | list($map, $dlToClass) = parseAddressable($list); 53 | file_put_contents('catalog_parsed.json', json_encode($map, JSON_UNESCAPED_SLASHES+JSON_UNESCAPED_UNICODE+JSON_PRETTY_PRINT)); 54 | file_put_contents('catalog_dltoclass.json', json_encode($dlToClass, JSON_UNESCAPED_SLASHES+JSON_UNESCAPED_UNICODE+JSON_PRETTY_PRINT)); 55 | 56 | $list = []; 57 | foreach ($map as $i) { 58 | if (preg_match('/^[0-9a-f]{32}\.bundle$/', $i['dependencyKey'])) { 59 | $list[$i['primaryKey']] = $i['dependencyKey']; 60 | } 61 | } 62 | $t = count($list); 63 | $d = 1; 64 | foreach ($list as $f=>$b) { 65 | #echo "\r$d/$t $f "; 66 | curl_setopt($ch, CURLOPT_URL, "${dlUrl}iOS/$b"); 67 | $data = curl_exec($ch); 68 | file_put_contents("$f.bundle", $data); 69 | $d++; 70 | } 71 | exec('git add .'); 72 | exec('git commit -m '.date('Ymd')); 73 | exec("git push origin ${branch}"); 74 | 75 | } 76 | 77 | function parseAddressable($list) { 78 | // ref: https://github.com/needle-mirror/com.unity.addressables/blob/5a722ef6ae2d07e55cba9c07c751d8ce8ccad3c7/Runtime/ResourceLocators/ContentCatalogData.cs#L294 79 | $bucketData = base64_decode($list['m_BucketDataString']); 80 | $s = new MemoryStream($bucketData); 81 | $s->littleEndian = true; 82 | $bc = $s->long; 83 | $buckets = []; 84 | for ($i=0; $i<$bc; $i++) { 85 | $index = $s->long; 86 | $entryCount = $s->long; 87 | $entry = []; 88 | for ($c=0; $c<$entryCount; $c++) { 89 | $entry[] = $s->long; 90 | } 91 | $buckets[] = [ 92 | 'dataOffset' => $index, 93 | 'entries' => $entry, 94 | ]; 95 | } 96 | $extraData = base64_decode($list['m_ExtraDataString']); 97 | $es = new MemoryStream($extraData); 98 | $es->littleEndian = true; 99 | $keyData = base64_decode($list['m_KeyDataString']); 100 | $s = new MemoryStream($keyData); 101 | $s->littleEndian = true; 102 | $kc = $s->long; 103 | $keys = []; 104 | for ($i=0; $i<$kc; $i++) { 105 | $keys[] = ReadObjectFromStream($s, $buckets[$i]['dataOffset']); 106 | } 107 | $entryData = base64_decode($list['m_EntryDataString']); 108 | $s = new MemoryStream($entryData); 109 | $s->littleEndian = true; 110 | $ec = $s->long; 111 | $locations = []; 112 | for ($i=0; $i<$ec; $i++) { 113 | $internalId = $s->long; 114 | $providerIndex = $s->long; 115 | $dependencyKeyIndex = $s->long; 116 | $depHash = $s->long; 117 | $dataIndex = $s->long; 118 | $primaryKey = $s->long; 119 | $resourceType = $s->long; 120 | $data = $dataIndex < 0 ? null : ReadObjectFromStream($es, $dataIndex); 121 | $locations[] = [ 122 | 'internalId' => $list['m_InternalIds'][$internalId], 123 | 'providerId' => $list['m_ProviderIds'][$providerIndex], 124 | 'dependencyKey' => $dependencyKeyIndex < 0 ? null : $keys[$dependencyKeyIndex], 125 | 'data'=> $data, 126 | 'depHash'=> $depHash, 127 | 'primaryKey'=> $keys[$primaryKey], 128 | 'type'=> $list['m_resourceTypes'][$resourceType], 129 | ]; 130 | } 131 | $map = []; 132 | $dlToClass = []; 133 | foreach ($locations as $i) { 134 | if (!empty($i['dependencyKey'])) { 135 | if (empty($dlToClass[$i['dependencyKey']])) $dlToClass[$i['dependencyKey']] = ['class'=>[],'key'=>'']; 136 | $dlToClass[$i['dependencyKey']]['class'][] = $i['type']['m_ClassName']; 137 | $dlToClass[$i['dependencyKey']]['key'] = $i['primaryKey']; 138 | } 139 | $map[$i['type']['m_ClassName'].'-'.$i['primaryKey']] = $i; 140 | unset($i['type']); 141 | unset($i['primaryKey']); 142 | } 143 | ksort($map); 144 | ksort($dlToClass); 145 | 146 | return [ 147 | $map, 148 | $dlToClass, 149 | ]; 150 | } 151 | 152 | function ReadObjectFromStream(Stream $s, $offset) { 153 | $ObjectType = [ 154 | 'AsciiString', 155 | 'UnicodeString', 156 | 'UInt16', 157 | 'UInt32', 158 | 'Int32', 159 | 'Hash128', 160 | 'Type', 161 | 'JsonObject' 162 | ]; 163 | $s->position = $offset; 164 | $keyType = ord($s->byte); 165 | switch ($keyType) { 166 | case 0: { /*AsciiString */ $len = $s->long; return $s->readData($len); } 167 | case 1: { /*UnicodeString*/ $len = $s->long; return $s->readData($len); } 168 | case 2: { /*UInt16 */ return $s->ushort; } 169 | case 3: { /*UInt32 */ return $s->ulong; } 170 | case 4: { /*Int32 */ return $s->long; } 171 | case 5: { /*Hash128 */ $len = ord($s->byte);return $s->readData($len); } 172 | case 6: { /*Type */ $len = ord($s->byte);return $s->readData($len); } 173 | case 7: { /*JsonObject */ 174 | $anl = ord($s->byte); 175 | $assemblyName = $s->readData($anl); 176 | $cnl = ord($s->byte); 177 | $className = $s->readData($cnl); 178 | $jl = $s->long; 179 | $json = $s->readData($jl); 180 | return [ 181 | 'assemblyName' => $assemblyName, 182 | 'className' => $className, 183 | 'data' => json_decode($json, true) 184 | ]; 185 | } 186 | default : {var_dump($keyType);exit;} 187 | } 188 | } -------------------------------------------------------------------------------- /sbr/resource_fetch.php: -------------------------------------------------------------------------------- 1 | '/^charactercard\/charactercard(\d+)$/', 'nameMatch'=>'/^charactercard(.+)$/', 'exportTo'=>'card/$1' ], 9 | [ 'bundleNameMatch'=>'/^humanmodel\/humanmodel(\d+)$/', 'customAssetProcessor' => 'exportHumanModel' ], 10 | ]; 11 | 12 | function GeneratePBKDF2Key($password, $salt) { 13 | return hash_pbkdf2('SHA1', $password, $salt, 1024, 32+16, true); 14 | } 15 | function getAssetUrl(string $path) { 16 | $path = explode('/', trim($path, '/')); 17 | if (count($path) > 3) { 18 | array_splice( 19 | $path, 1, 0, 20 | implode('/', array_splice($path, 1, count($path) - 2)) 21 | ); 22 | } 23 | $path = array_map(function ($i) { 24 | return xxhash64($i, SBR_HASH_SEED, true); 25 | }, $path); 26 | return implode('/', $path); 27 | } 28 | function decryptAsset_SBR(string $data) { 29 | $key = hex2bin("d9e7f9f78d35ef76f8e377bd6f7ddde3c7dadb5e78e3bef4"); 30 | $salt = hex2bin("ef4d3adfbeb871bf76e3cd356f671de1c6b57396f46fddf4"); 31 | $aesData = GeneratePBKDF2Key($key, $salt); 32 | return openssl_decrypt($data, 'AES-256-CBC', substr($aesData, 0, 32), OPENSSL_RAW_DATA, substr($aesData, 32, 16)); 33 | } 34 | 35 | function shouldExportFile($name, $rule) { 36 | return preg_match($rule['nameMatch'], $name) != 0; 37 | } 38 | 39 | $cacheHashDb = new PDO('sqlite:'.__DIR__.'/cacheHash.db'); 40 | $chkHashStmt = $cacheHashDb->prepare('SELECT hash FROM cacheHash WHERE res=?'); 41 | function shouldUpdate($name, $hash) { 42 | global $chkHashStmt; 43 | $chkHashStmt->execute([$name]); 44 | $row = $chkHashStmt->fetch(); 45 | return !(!empty($row) && $row['hash'] == $hash); 46 | } 47 | $setHashStmt = $cacheHashDb->prepare('REPLACE INTO cacheHash (res,hash) VALUES (?,?)'); 48 | function setHashCached($name, $hash) { 49 | global $setHashStmt; 50 | $setHashStmt->execute([$name, $hash]); 51 | } 52 | 53 | function findRule($name, $rules) { 54 | foreach ($rules as $rule) { 55 | if (preg_match($rule['bundleNameMatch'], $name) != 0) return $rule; 56 | } 57 | return false; 58 | } 59 | 60 | define('RESOURCE_PATH_PREFIX', '/data/home/web/_redive/sbr/'); 61 | 62 | function exportHumanModel($asset, $remoteTime) { 63 | foreach ($asset->preloadTable as $item) { 64 | if ($item->typeString == 'TextAsset') { 65 | $item = new TextAsset($item, true); 66 | checkAndCreateFile(RESOURCE_PATH_PREFIX.'spine/model/'.$item->name, $item->data, $remoteTime); 67 | } else if ($item->typeString == 'Texture2D') { 68 | $item = new Texture2D($item, true); 69 | $saveTo = RESOURCE_PATH_PREFIX.'spine/model/'.$item->name; 70 | $item->exportTo($saveTo, 'png'); 71 | if (filemtime($saveTo.'.png') > $remoteTime) 72 | touch($saveTo.'.png', $remoteTime); 73 | } 74 | } 75 | } 76 | 77 | function checkAndUpdateResource() { 78 | global $resourceToExport; 79 | $curl = curl_init(); 80 | chdir(__DIR__); 81 | $currenttime = time(); 82 | curl_setopt_array($curl, array( 83 | CURLOPT_CONNECTTIMEOUT=>5, 84 | CURLOPT_ENCODING=>'gzip', 85 | CURLOPT_RETURNTRANSFER=>true, 86 | CURLOPT_HEADER=>0, 87 | CURLOPT_SSL_VERIFYPEER=>false 88 | )); 89 | $manifest = json_decode(file_get_contents('data/asset_infos.json'), true); 90 | 91 | foreach ($manifest as $name => $info) { 92 | if (($rule = findRule($name, $resourceToExport)) !== false && shouldUpdate($name, $info['hash'])) { 93 | _log('download '. $name); 94 | curl_setopt_array($curl, array( 95 | CURLOPT_URL=>'https://prod-dlc-cache.showbyrock-fes.com/asset/'.getAssetUrl('ios/'.$name), 96 | )); 97 | $bundleData = curl_exec($curl); 98 | $gotHash = xxhash64($bundleData, SBR_HASH_SEED); 99 | $expectedHash = str_pad(dechex($info['hash']), 16, '0', STR_PAD_LEFT); 100 | if ($gotHash != $expectedHash) { 101 | _log('download failed '.$name . " expected $expectedHash got $gotHash"); 102 | continue; 103 | } 104 | $bundleData = new MemoryStream(decryptAsset_SBR($bundleData)); 105 | $assets = extractBundle($bundleData); 106 | 107 | try{ 108 | 109 | foreach ($assets as $asset) { 110 | if (substr($asset, -5,5) == '.resS') continue; 111 | $asset = new AssetFile($asset); 112 | 113 | if (isset($rule['customAssetProcessor'])) { 114 | call_user_func($rule['customAssetProcessor'], $asset, $currenttime); 115 | } else 116 | foreach ($asset->preloadTable as &$item) { 117 | if ($item->typeString == 'Texture2D') { 118 | $item = new Texture2D($item, true); 119 | $itemname = $item->name; 120 | if (isset($rule['namePrefix'])) { 121 | $itemname = preg_replace($rule['bundleNameMatch'], $rule['namePrefix'], $name).$itemname; 122 | } 123 | if (isset($rule['print'])) { 124 | var_dump($itemname); 125 | continue; 126 | } 127 | if (shouldExportFile($itemname, $rule)) { 128 | $saveTo = RESOURCE_PATH_PREFIX. preg_replace($rule['nameMatch'], $rule['exportTo'], $itemname); 129 | $param = '-lossless 1'; 130 | if (isset($rule['extraParam'])) $param .= ' '.$rule['extraParam']; 131 | if (isset($rule['extraParamCb'])) $param .= ' '.call_user_func($rule['extraParamCb'], $item); 132 | $item->exportTo($saveTo, 'webp', $param); 133 | if (filemtime($saveTo. '.webp') > $currenttime) 134 | touch($saveTo. '.webp', $currenttime); 135 | } 136 | unset($item); 137 | } 138 | } 139 | $asset->__desctruct(); 140 | unset($asset); 141 | gc_collect_cycles(); 142 | } 143 | 144 | } catch(Exception $e) { 145 | $asset->__desctruct(); 146 | unset($asset); 147 | _log('Not supported: '. $e->getMessage()); 148 | } 149 | 150 | foreach ($assets as $asset) { 151 | unlink($asset); 152 | } 153 | unset($bundleData); 154 | //if (isset($rule['print'])) exit; 155 | setHashCached($name, $info['hash']); 156 | } 157 | } 158 | } 159 | 160 | if (defined('TEST_SUITE') && TEST_SUITE == __FILE__) { 161 | chdir(__DIR__); 162 | function _log($s) {echo "$s\n";} 163 | checkAndUpdateResource(); 164 | /*$asset = new AssetFile('CAB-4856cccde53d6f3bfd0054253f1639a8'); 165 | foreach ($asset->preloadTable as &$item) { 166 | if ($item->typeString == 'Texture2D') { 167 | $item = new Texture2D($item, true); 168 | _log($item->name); 169 | $item->exportTo($item->name, 'webp', '-lossless 1'); 170 | } 171 | }*/ 172 | } -------------------------------------------------------------------------------- /wds/exportTable.php: -------------------------------------------------------------------------------- 1 | \n"; 5 | exit; 6 | } 7 | $dumpcs = file_get_contents($argv[1]); 8 | 9 | /*preg_match_all("((\[MemoryTable\(\"[^\)]]+\"\)\]\n)?(\[.+\]\n)*public class [^{}]*?\{[^{}]+\[Key\(\d+\)\](((?>[^{}]+)|{(?-2)})*)\})", $dumpcs, $classes);*/ 10 | preg_match_all("(// Namespace: ([^\n]*)\n(\[.+\]\n)*(\[MemoryTable\(\"[^\)]]+\"\)\]\n)?(\[.+\]\n)*public class [^{}]*?\{[^{}]+\[Key\(\d+\)\](((?>[^{}]+)|{(?-2)})*)\})", $dumpcs, $classes); 11 | 12 | $types = []; 13 | $typesDb = new PDO('sqlite:'.__DIR__.'/types.db'); 14 | $typesDb->beginTransaction(); 15 | $typesDb->query('DELETE FROM types'); 16 | $insert = $typesDb->prepare('INSERT INTO types VALUES (?,?,?)'); 17 | $rename = $typesDb->prepare('UPDATE types SET class=? WHERE class=?'); 18 | 19 | $f = fopen(__DIR__.'/tables.cs', 'w'); 20 | 21 | preg_match_all("(// Namespace: ([^\n]*)\npublic enum ([^ ]+) [^{]*?\{(((?>[^{}]+)|{(?-2)})*)\})", $dumpcs, $enums); 22 | $typesDb->query('DELETE FROM enums'); 23 | $enumInsert = $typesDb->prepare('INSERT INTO enums VALUES (?,?)'); 24 | $enumTables = []; 25 | 26 | foreach ($enums[0] as $i=>$enum) { 27 | $namespace = $enums[1][$i]; 28 | $enumName = $enums[2][$i]; 29 | preg_match_all('(public const [^ ]+ ([^ ]+) = ([\d-]+);)', $enum, $enumEntries); 30 | $enumTable = ['']; 31 | for ($i=0; $i$class) { 48 | $class = preg_replace('(\[CompilerGenerated\][\w\W]+?\n\n)', "\n", $class); 49 | $class = preg_replace('(public void .ctor\(\) \{ \})', "\n", $class); 50 | $class = preg_replace('(//.+)', "", $class); 51 | $class = preg_replace('(/\*[\w\W]+?\*/)', "", $class); 52 | $class = preg_replace('((?<=\n) *\n)', "", $class); 53 | fwrite($f, $class."\n\n"); 54 | 55 | $namespace = $classes[1][$i]; 56 | $type = []; 57 | preg_match('(class ([\w\.]+))', $class, $className); 58 | $className = $className[1]; 59 | if (isset($seenTypes[$className])) { 60 | $prev = $seenTypes[$className]; 61 | echo "Duplicate class $className $prev $namespace\n"; 62 | if ($namespace === 'SiriusApi.Shared') { 63 | $rename->execute([$prev.'.'.$className, $className]); 64 | $typesIdx[$prev.'.'.$className] = $typesIdx[$className]; 65 | unset($typesIdx[$className]); 66 | } else { 67 | $className = $prev.'.'.$className; 68 | } 69 | } 70 | $typesIdx[$className] = count($types); 71 | $type['class'] = $className; 72 | preg_match('(\[MemoryTable\(\"([\w]+)\"\)\])', $class, $tableName); 73 | $type['tableName'] = empty($tableName[1]) ? null : $tableName[1]; 74 | preg_match_all('(\[Key\((\d+)\)\](\n \[[^\]]+?\])*\n [^{\n]*? ([^{]+) ([^ {]+) )', $class, $keys); 75 | $type['keys'] = []; 76 | 77 | preg_match('(class [\w\.]+ : ([\w\.]+))', $class, $classInherit); 78 | $inherit = empty($classInherit[1]) ? null : $classInherit[1]; 79 | if ($inherit !== null) { 80 | if (isset($typesIdx[$inherit])) { 81 | $type['keys'] = array_merge($type['keys'], $types[$typesIdx[$inherit]]['keys']); 82 | } 83 | } 84 | 85 | for ($i=0; $i < count($keys[1]); $i++) { 86 | $typeName = $keys[3][$i]; 87 | $type['keys'][$keys[1][$i]] = [ 88 | 'type' => $typeName, 89 | 'name' => $keys[4][$i] 90 | ]; 91 | if (isset($enumTables[$typeName]) && !isset($usedEnumTables[$typeName])) { 92 | $usedEnumTables[$typeName] = $enumTables[$typeName]; 93 | } 94 | $typeName = preg_replace('(^Nullable<(.+)>$)', '$1', $typeName); 95 | if (isset($enumTables[$typeName]) && !isset($usedEnumTables[$typeName])) { 96 | $usedEnumTables[$typeName] = $enumTables[$typeName]; 97 | } 98 | } 99 | $type['keys'] = $type['keys'] + array_fill(0, max(array_keys($type['keys'])), 0); 100 | ksort($type['keys']); 101 | $types[] = $type; 102 | 103 | $type['keys'] = json_encode($type['keys'], JSON_PRETTY_PRINT); 104 | $insert->execute(array_values($type)); 105 | $seenTypes[$type['class']] = $namespace; 106 | } 107 | $enumsF = fopen(__DIR__.'/enums.cs', 'w'); 108 | foreach ($usedEnumTables as $enumName=>$enumTable) { 109 | fwrite($enumsF, "public enum $enumName\n{\n"); 110 | $enumInsert->execute([ 111 | $enumName, 112 | json_encode($enumTable, JSON_PRETTY_PRINT), 113 | ]); 114 | foreach ($enumTable as $value=>$name) { 115 | if (empty($name)) continue; 116 | fwrite($enumsF, " $name = $value,\n"); 117 | } 118 | fwrite($enumsF, "}\n\n"); 119 | } 120 | fclose($f); 121 | file_put_contents(__DIR__.'/types.json', json_encode($types, JSON_PRETTY_PRINT)); 122 | $typesDb->commit(); 123 | --------------------------------------------------------------------------------