From 1279655f9dbbc129f999e108dbc464ac043821d5 Mon Sep 17 00:00:00 2001 From: wildfire Date: Fri, 22 Sep 2023 23:12:21 +0100 Subject: [PATCH 1/6] Add checksum tests for narcs in the res folder --- meson.build | 5 + platinum.us/meson.build | 5 +- platinum.us/res.sha1 | 341 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 350 insertions(+), 1 deletion(-) create mode 100644 platinum.us/res.sha1 diff --git a/meson.build b/meson.build index 9639c33369..8c9866b569 100644 --- a/meson.build +++ b/meson.build @@ -226,6 +226,11 @@ test('SBIN Checksums', args: ['-c', '--quiet', sbins_sha1] ) +test('Resource Checksums', + sha1sum, + args: ['-c', '--quiet', res_sha1] +) + test('ROM Checksum', sha1sum, args: ['-c', '--quiet', rom_sha1] diff --git a/platinum.us/meson.build b/platinum.us/meson.build index 3e2821e2cf..c36126fa40 100644 --- a/platinum.us/meson.build +++ b/platinum.us/meson.build @@ -32,7 +32,10 @@ main_lcf = custom_target('main.lcf', ) # Collect spec files for later use -sbins_sha1 = files('sbins.sha1') rom_header_template = files('rom_header_template.sbin') rom_rsf = files('rom.rsf') + +# Checksum files for matching +sbins_sha1 = files('sbins.sha1') +res_sha1 = files('res.sha1') rom_sha1 = files('rom.sha1') diff --git a/platinum.us/res.sha1 b/platinum.us/res.sha1 new file mode 100644 index 0000000000..9769731f0c --- /dev/null +++ b/platinum.us/res.sha1 @@ -0,0 +1,341 @@ +42e2b71655a74d6e5bffb9ec75a25df930b20c59 res/battle/moves/pl_waza_tbl.narc +683a7691d685c153e738b136b8266deefb0b4552 res/items/nuts_data.narc +70d103831556bb58ae8e602adbcce99333a22889 res/items/pl_item_data.narc +3614557aa04eb1ad7e5f260578de925f73da584d res/text/pl_msg.narc + +1f8689cbc763d9efedac9e6f12e940dbd361f7a9 res/prebuilt/poketool/personal/pl_personal.narc +007c171966e3811ecaa5763ec959835dc67f57ba res/prebuilt/application/balloon/graphic/balloon_gra.narc +6e4f26a6a77242c7db11f6145a77d85ee7dfe12e res/prebuilt/application/bucket/ballslow_data.narc +3e420c904e49c441a22210726e7017e4ee0f607f res/prebuilt/application/custom_ball/data/cb_data.narc +8088363d46d621357a33956f8e03cb4e5c779734 res/prebuilt/application/custom_ball/edit/pl_cb_data.narc +a8171d59d53db11ef6fd8ca89d1bbf439bb24a58 res/prebuilt/application/wifi_earth/wifi_earth.narc +e171ea4a5b54d4e68fe7e0031a2edc0d561c7e7c res/prebuilt/application/wifi_earth/wifi_earth_place.narc +7fecc969c3a9d6ee05e8157505458927476def4d res/prebuilt/application/wifi_lobby/map_conv/wflby_map.narc +5ab40a1a509372d16f6e3b678820c0932cce9d03 res/prebuilt/application/zukanlist/zkn_data/zukan_data.narc +285382cf40985e52e30f07471ee477203a4a5304 res/prebuilt/application/zukanlist/zkn_data/zukan_data_gira.narc +2bc5d3a3f60966591593cc441ab6bd2eb9cfcaa1 res/prebuilt/application/zukanlist/zkn_data/zukan_enc_diamond.narc +ebb8d95aa9e03304b587861e9f912b8f2304fd48 res/prebuilt/application/zukanlist/zkn_data/zukan_enc_pearl.narc +00d042c278d7a76bff49d4f317dd522604887368 res/prebuilt/application/zukanlist/zkn_data/zukan_enc_platinum.narc +b54b704c20f35cb66eb2790086dc47cd9ac612f7 res/prebuilt/arc/area_win_gra.narc +7d5eac7006f041f4da9f9baf04ee61cc187f4580 res/prebuilt/arc/balance_ball_gra.narc +99295a6e74067238dbbc23105cad1679687c6d86 res/prebuilt/arc/bm_anime.narc +afd2be309c09733b33ec9b73b793518b41153828 res/prebuilt/arc/bm_anime_list.narc +6a403c707b8737e4f19644ffe51606838fe43456 res/prebuilt/arc/codein_gra.narc +f1ef036922af5a593650d6a52f56fb3ec59d3d83 res/prebuilt/arc/demo_tengan_gra.narc +adcb9634923530fd7f217a131a3949f556f4f324 res/prebuilt/arc/email_gra.narc +0832d441d7e543e14d68e9df7e9118b472d67833 res/prebuilt/arc/encdata_ex.narc +d534f791217a311610812b18ef674a326ecdd2ac res/prebuilt/arc/manene.narc +ad5fefc4758eba86f6f647e506531d6cfe9c9ce5 res/prebuilt/arc/plgym_ghost.narc +89b24d0c67f2cb089800613d5a0254a124d98ba6 res/prebuilt/arc/ppark.narc +9b0b19798338e63d907a95c35be4b302778192f1 res/prebuilt/arc/ship_demo.narc +91559385ad608514630650e1f1e94206048bc3a8 res/prebuilt/arc/ship_demo_pl.narc +114d4f20de27a95ad930b246bb6f62a6d7295fe5 res/prebuilt/arc/tv.narc +ecdb14e0bc6619f114549e6126c8b6934cfc3aeb res/prebuilt/battle/b_pl_stage/pl_bsdpm.narc +2dac84a8a4c8dca13be326dc071ecbd550eb2ee7 res/prebuilt/battle/b_pl_tower/pl_btdpm.narc +738eeff4bee6a7cfbc8d448f23f58ad52ce76314 res/prebuilt/battle/b_pl_tower/pl_btdtr.narc +e5b1a6b28919a947ae2d2e73306abdaf91499aff res/prebuilt/battle/b_tower/btdpm.narc +b0344401b36411ecad92e706059cc9a0d8fc2365 res/prebuilt/battle/b_tower/btdtr.narc +d672202157109fb1bb293070b5d35787b2b2b6d3 res/prebuilt/battle/graphic/batt_bg.narc +c9baf056c8646bc0bc826bbc98f5cbd439643f3d res/prebuilt/battle/graphic/batt_obj.narc +8bac81f0ff446438c6bf34a161619dce22e9db77 res/prebuilt/battle/graphic/b_bag_gra.narc +036b81fe61c6347100c73b2c23d28da5abc7626c res/prebuilt/battle/graphic/b_plist_gra.narc +2fafdda86f7f740e2843c95382f08dfac35fa64f res/prebuilt/battle/graphic/pl_batt_bg.narc +db5906303178da70f6b6c852990df560fb4dfeba res/prebuilt/battle/graphic/pl_batt_obj.narc +036b81fe61c6347100c73b2c23d28da5abc7626c res/prebuilt/battle/graphic/pl_b_plist_gra.narc +955ce80b532be2184c62c36a6cb9d6b68c4669dd res/prebuilt/battle/graphic/vs_demo_gra.narc +20e86a2ef9050edef59a91bfcefcc2869ab29349 res/prebuilt/battle/skill/be_seq.narc +b646973b4c92a1d25479c5b08d28ff283274db33 res/prebuilt/battle/skill/sub_seq.narc +abbe7036e7117af7f4fd397cd3619b83f5e1d321 res/prebuilt/battle/skill/waza_seq.narc +e8c96b0f5b6d59820e7201f7881183e3aff1b35f res/prebuilt/battle/tr_ai/tr_ai_seq.narc +f477dce1ffaf2db070ef0f31f422b51433463485 res/prebuilt/contest/data/contest_data.narc +8e3c5c332cff4ae218ce746e59b9221e229d382c res/prebuilt/contest/graphic/contest_bg.narc +cec363028fa6bc6240f9c8da7ab8f9e8bb1b1465 res/prebuilt/contest/graphic/contest_obj.narc +cea2ad20f4550dcf648aeb6f2bc118dcec7570d9 res/prebuilt/data/arealight.narc +a0c8ba8987d30f0c9930dfe109b7ee8c325582b9 res/prebuilt/data/battle_win.NSCR +09f94a65e5581ef1cf30066be8786c185aa9b2b2 res/prebuilt/data/btower_canm.resdat +89951491d6b76b65098917872397e0b11c7bb9de res/prebuilt/data/btower_celact.cldat +56805c0b9108a7ff0efb6c96437188afde6e0345 res/prebuilt/data/btower_cell.resdat +9cd64d47ca924bae65f78d438e0928f1fd430235 res/prebuilt/data/btower_chr.resdat +85493120fb2fee27ed2d5bd56d697304a60baac0 res/prebuilt/data/btower_pal.resdat +7666516466c447f3d4af62823d13ab4f33f44d6c res/prebuilt/data/cell0.NCGR +62e12a4af9562e650b4191afaec32bfd6f34e3d8 res/prebuilt/data/cell0.NCLR +41941e73a6729ccfb9e66a8b1f9b961a11c4654b res/prebuilt/data/clact_default.NANR +62e778d1aad86bb28d65baf976c157cd3d1c9181 res/prebuilt/data/crystal.nsbmd +616aac9b8fe12b6624f78156f1edc08010968131 res/prebuilt/data/demo_climax.narc +aa0f5012b291baaef7dcf4a865f5b2ef355cb1bc res/prebuilt/data/dp_areawindow.NCGR +fae298e263cc5800c2987c29fa8fd15b974c5978 res/prebuilt/data/dp_areawindow.NCLR +48c2e7921740a7b3abc849c09516efba63b5f130 res/prebuilt/data/dt_test_celact.txt +f442a95122e988b5bad14ceda6a6f62451cc6968 res/prebuilt/data/dt_test_res_cell.txt +37cd0bcc5e7e8b82617008015a14c9970ba7d855 res/prebuilt/data/dt_test_res_cellanm.txt +1a1cc9fe2a195191303e017e9c034608b1bf9c1c res/prebuilt/data/dt_test_res_char.txt +245259849f99c2d640832074943a96df17aca5b5 res/prebuilt/data/dt_test_res_multi.txt +edf382a2cc6133a555f6e6d6ca0ebd94accf887e res/prebuilt/data/dt_test_res_multianm.txt +2cded1523dae981a97c28a3c2e919fbf4ca61d5b res/prebuilt/data/dt_test_res_pltt.txt +6867106d6543d3d390e8936b051ef9183726ce41 res/prebuilt/data/dun_sea.nsbtx +3d8f61973d6070daa563e7019db6caf9f93c60db res/prebuilt/data/eoo.dat +157cfbbab2f334d38de826f26490c75a4b68e517 res/prebuilt/data/exdata.dat +d809e2ff8a9b2bccc2516037e32c723a08102b3c res/prebuilt/data/field_cutin.narc +80c1eee60f30744205e89c0d80aeebe7d268d2d9 res/prebuilt/data/fldtanime.narc +1957d473f231e05dd68e260343bb517547c23e3f res/prebuilt/data/fld_anime0.bin +5f06e9777b8fb95a8741ea73a9b1ec74d76bb17b res/prebuilt/data/fld_anime1.bin +cf1232e407b9639ce12b95df787435597e6da7d5 res/prebuilt/data/fld_anime10.bin +b0beddfb2a497738651ad0b8fff8c541a444c858 res/prebuilt/data/fld_anime2.bin +7785b70b421a568be99ead865dfa68051611072f res/prebuilt/data/fld_anime3.bin +2dcd6a2a5ad1b0a0058f8ea10044839fc4e648a7 res/prebuilt/data/fld_anime4.bin +40143d38d6c59f3a9d73852eb3cd35439750b1b9 res/prebuilt/data/fld_anime5.bin +5efdeb8d90ca827f6878183f976ecee186f54dea res/prebuilt/data/fld_anime6.bin +677047913ac8457137ac4e51b8616214fc10d377 res/prebuilt/data/fld_anime7.bin +2dbb7cb747ac4a7e56db4d4e985d299850e8d31a res/prebuilt/data/fld_anime8.bin +a5b04e2e3062e4a14334b89b8f60bd9776c030ed res/prebuilt/data/fld_anime9.bin +0fc4ff4b2b5d62db34b2fa44dd5afb4786b43e6a res/prebuilt/data/fs_kanban.nsbca +5b61100f2f26bf5792227cec9ff110e195e0d84b res/prebuilt/data/ground0.NCGR +662203463cfef49cdc3ac4d5962943f6b0d46e7d res/prebuilt/data/ground0.NCLR +6ebf0c0f5c761c7bf1e702ba4154c8a850042386 res/prebuilt/data/ground0.NSCR +8c27b0f5ac5c3de0bdbfff5f10048fd29c6ae023 res/prebuilt/data/guru2.narc +8337a5c056d6cfec13973f10127c300b25000d0c res/prebuilt/data/kemu_itpconv.dat +7a7d116a42225bde50223bb6028c6296196d39de res/prebuilt/data/lake_anim.nsbtx +ce356d7406f181532de0f64c41fb1f178abc21e9 res/prebuilt/data/miniasahamabe.nsbtx +b6c7a3b01146ef7a8e5cd0c583a6185a62fce803 res/prebuilt/data/miniasasea.nsbtx +0634ba96cde00f4ae9417aa3b503925272480752 res/prebuilt/data/minihamabe.nsbtx +71f4cedade64a030172afc432049106ad198e0e6 res/prebuilt/data/minimum.nsbtx +4bd3072a3c2e0d833feb9ce6c4b8264c73cf3c29 res/prebuilt/data/minirhana.nsbtx +70d483c69d9f83dc52de91f2451c6cdfba6a046c res/prebuilt/data/mmodel/fldeff.narc +21bd9b9e352c828de0a93979589f7ea487c846d6 res/prebuilt/data/mmodel/mmodel.narc +8138e762591a993179132f20550ca3c94aba6b9d res/prebuilt/data/namein.narc +5d5c14fcfa0f8534c2eec79ffa945d01f4c547b4 res/prebuilt/data/nfont.NCGR +9eae4f97e9e97b6cd427c95def1c166ea868da43 res/prebuilt/data/nfont.NCLR +bbec5b2143b48f7439efa8eb285b69635f3720fa res/prebuilt/data/pc.nsbca +1914b6e76596ffa892508899cad35acedf7ae070 res/prebuilt/data/plbr.dat +516b0800e4ebeca7982a487160ed6a04db95eb8b res/prebuilt/data/plist_canm.resdat +c63feb68844c5a535611cd61945810977dc13989 res/prebuilt/data/plist_cell.resdat +ea682a75054a3e229c3caa91bf7701d60fa05aa4 res/prebuilt/data/plist_chr.resdat +d47a8e1fe411e19c194939abb643d2af1e1cf329 res/prebuilt/data/plist_h.cldat +df06f0ebd532087ff88a709a86ec4c6f00b6d05a res/prebuilt/data/plist_pal.resdat +0ccb5f6bfe786b95323c2547ee4201af2e47ee8b res/prebuilt/data/pl_wifi.ncgr +e8982c6379fcc2dbd01e2a3626fa1e11477c77c9 res/prebuilt/data/pl_wm.ncgr +26ca766959599944cd52221ad42cc0a93d95ba2e res/prebuilt/data/pl_wm.nclr +1e111fc17f1496bab5b2f20455985a6139bd770d res/prebuilt/data/porucase_canm.resdat +b844263884695da81d055287a8e5311cf80fc49e res/prebuilt/data/porucase_celact.cldat +f8716c3d16aa2f8ccbb29c3e2ae55f2d872a689f res/prebuilt/data/porucase_cell.resdat +f70867dd71f9809cfad32b8dad2adc1f7b9cd281 res/prebuilt/data/porucase_chr.resdat +ecff5b0d3d4800d3843db63620537fa487ce8934 res/prebuilt/data/porucase_pal.resdat +6d3ed9ed9df3f3b4285a4e767de4c8aea01ed950 res/prebuilt/data/pst_canm.resdat +132a2e16407dc32b15bc22812234cc720b351126 res/prebuilt/data/pst_cell.resdat +61aa12d59c1c79a7f2e7c0e1e2476d361c2876ee res/prebuilt/data/pst_chr.resdat +51305113cfd7a2694d82b5ff6e56878b31e193e9 res/prebuilt/data/pst_h.cldat +729603785c0d10750cef1f42d344616a37630415 res/prebuilt/data/pst_pal.resdat +4b9fc365f7dbe2486e9f07b129422d131b3ded2d res/prebuilt/data/shop_canm.resdat +ca25450477e4d283af4693f1d4664ed4ba279608 res/prebuilt/data/shop_cell.resdat +4607568f0688fbabc865d01cfbb38d33c707044f res/prebuilt/data/shop_chr.resdat +13b14a575d361fea840cf6a433bde418e992bc5d res/prebuilt/data/shop_h.cldat +6ef9a9cb38575cb47bfa9f3070c068aeff2b7ab0 res/prebuilt/data/shop_pal.resdat +7d890728684f972892221535e43f2dd07a63ac5c res/prebuilt/data/slot.narc +5bb388f5b16ef1eb8c8ea4c638eccf1244e7789c res/prebuilt/data/smptm_koori.NANR +295d997311252e0c1cedaa36fc0083d024a140a2 res/prebuilt/data/smptm_koori.NCER +bba8cd586df5dfb3554fac257e7eecb5886991ba res/prebuilt/data/smptm_koori.NCGR +ba96e0749e4e09914b8f4aadd05448917a2a0003 res/prebuilt/data/smptm_koori.NCLR +fc2c57d9b37c1c4555273821eecebbdfdce577c9 res/prebuilt/data/smptm_nemuri.NANR +edbd2b8fb90e4890224f681a95cfc182cda8f9e7 res/prebuilt/data/smptm_nemuri.NCER +9d435cc3b966e4f5fcd03fdcb19942204ffd40c5 res/prebuilt/data/smptm_nemuri.NCGR +126c06e829baf0a99f5b2e896965276b6385cf40 res/prebuilt/data/smptm_nemuri.NCLR +a4160e55ee085f23df76a1c2b7b9427520b994fe res/prebuilt/data/sound/pl_sound_data.sdat +ea0bcdd85b625239fc4c3cbb08f312ff24446991 res/prebuilt/data/sound/sound_data.sdat +8cc4c99a828b9654d574239c291229beffe48462 res/prebuilt/data/str2uni.bin +f170b58aac00ee3093b284368a626f996fa187bf res/prebuilt/data/t3_fl_b.nsbtx +aa3240383bc0d0ed15b4848616698a25623a6d22 res/prebuilt/data/t3_fl_p.nsbtx +2aead045ba9169c7eaf35d4e82ac8f37f5e615bf res/prebuilt/data/t3_fl_r.nsbtx +efcb17fc440548aefb1ec4b830955fa9e7954025 res/prebuilt/data/t3_fl_y.nsbtx +b5b6089df980ad54540fad84c76f76bcde0bb464 res/prebuilt/data/test.atr +aba8f43ada2b1919151c50366ec00df4f875350d res/prebuilt/data/tmapn_canm.resdat +b350396f553cf8c70888aca59e327310812b1ee9 res/prebuilt/data/tmapn_celact.cldat +b2d44b4083a618fa1da3e463e757b7af5e839bb3 res/prebuilt/data/tmapn_celact.txt +066150350014d8db521c0905da4c2cf9b523229b res/prebuilt/data/tmapn_cell.resdat +b976d3f03befcad1b4ed934c0f78a8a5d1d34aa8 res/prebuilt/data/tmapn_chr.resdat +9ea7f860223c7895ca701901d7ab9453b5f4a72f res/prebuilt/data/tmapn_pal.resdat +a1d847fd53a2b8f2a1fbee0afd6cab7985f0aab7 res/prebuilt/data/tmapn_res_canm.txt +52930c878755a7bb702fbe24ebfc2908617605ae res/prebuilt/data/tmapn_res_cell.txt +9750b822217dbcfa12f08d33f2597b3c7c4f52c4 res/prebuilt/data/tmapn_res_chr.txt +71bb82389ed0c7632c847dfba9aa3840d6670d93 res/prebuilt/data/tmapn_res_pal.txt +337f8bd7788eaea30946c8632bdbc9ef9b12b51f res/prebuilt/data/tmap_block.dat +973dc6f187a2b7469c6a1a11d5c4c0c41b2f221c res/prebuilt/data/tmap_flags.dat +8ac36eeaf690fd2686b8d3ec3a4952e3d5571280 res/prebuilt/data/tradelist.narc +5d1052e8c22db3c69fc17455a63b4df9c876f2fb res/prebuilt/data/trapmark.narc +e4ea803a861a64f3307f1e85c131f03f368aaf44 res/prebuilt/data/tw_arc_etc.naix +9d3f30933c0033f9369a1079a4a91b4e9ec02245 res/prebuilt/data/tw_arc_etc.narc +973098a1a60f7923024562e2ac18334567edb574 res/prebuilt/data/ugeffect_obj_graphic.narc +fed2bdb82fffa0aa263e3d6df0f6287f742ac430 res/prebuilt/data/ugroundeffect.naix +9a9c462760c8a718fbf8cd41d0bb87dfcfa50a41 res/prebuilt/data/ugroundeffect.narc +9aa715c371fa7ba5c6f2bc756974577229fd127f res/prebuilt/data/uground_cell.resdat +b8e444f219193fab8db5901fc017cc7e25b91d30 res/prebuilt/data/uground_cellanm.resdat +46ad24833d46809f113460f7515bad3095ec7b24 res/prebuilt/data/uground_char.resdat +3a39e9918bd968965c4c27830e6a4445fbbfa6e8 res/prebuilt/data/uground_char2.resdat +f70dd62e5908f8723fef69a48951a2a82adf01b3 res/prebuilt/data/uground_clact.cldat +8a998f37b0e2e504c17e252cad745ea82abf7e04 res/prebuilt/data/uground_pltt.resdat +bf16274373fa7a0a1db503ac7f82ef977c2d823a res/prebuilt/data/uground_pltt2.resdat +fb20bce19e6550b9cf45d94cd09c298779b912ab res/prebuilt/data/ug_anim.narc +3948cfbe187f0d02cc0e3269c9bf1ff881b25f81 res/prebuilt/data/ug_base_cur.nsbmd +805ec6c0fa7a4f55dbe7be7dabd542e8e8f41bea res/prebuilt/data/ug_boygirl.NCGR +cf5ffbfffd68a7e54150dc27f826d254668a49d0 res/prebuilt/data/ug_boygirl.NCLR +b95f318662fd141a2c6eec4bd8b0599e5a6e098f res/prebuilt/data/ug_fossil.narc +da14fe8a18432a8d76ecdc8bc88b220015915dab res/prebuilt/data/ug_hero.NANR +020bca936666479e88e99b6cc0e9ff51ebe33d02 res/prebuilt/data/ug_hero.NCER +b65415bfb95a51df288ce300aa84db510ee10f73 res/prebuilt/data/ug_hole.NANR +1a2a014b627ecd9e3bdb3b5852818a0fe1f52253 res/prebuilt/data/ug_hole.NCER +914803c8d6a4d785bc71374d81785fccf6588bac res/prebuilt/data/ug_hole.NCGR +baea1d536bbf3364fa00a9ee7586075d69ef94e1 res/prebuilt/data/ug_parts.narc +8604aca94d462a013d3820c769e6eb45e38f30b9 res/prebuilt/data/ug_radar.narc +efcfa6c0c26afef1840af4fd062f6790f4fb1f14 res/prebuilt/data/ug_trap.narc +010b6c08bc7da35acaaf093feac31518cd64027e res/prebuilt/data/underg_radar.narc +dd9f06b78e2a187fb62f2d3ad5d781a8a74d3d1b res/prebuilt/data/UTF16.dat +771128a72a1452c507a57f5efe8d5554f4394ea2 res/prebuilt/data/utility.bin +2e51272d8f954300bf0108af0006e8e1345e5bf2 res/prebuilt/data/weather_sys.narc +54fdcacd4730f2d511ca78c016c154415e5ca256 res/prebuilt/data/wifi.ncgr +b3eb598efc61f42b4541a1d93364520258c1a4b4 res/prebuilt/data/wifip2pmatch.narc +e8982c6379fcc2dbd01e2a3626fa1e11477c77c9 res/prebuilt/data/wm.ncgr +b65f8a707781ecede813f948cbc8c9154d4b623f res/prebuilt/data/wm.nclr +fdded15baac71b1bcfc285a6b7d6008336873e12 res/prebuilt/debug/cb_edit/d_test.narc +4357303bd09370350bb2fdd8324bed6e5b87ea39 res/prebuilt/demo/egg/data/egg_data.narc +fc33b6a3e954c139eae32244b2991cf280ab54a4 res/prebuilt/demo/egg/data/particle/egg_demo_particle.narc +49603d37492c5214a6e9751c07c30caf7fee7389 res/prebuilt/demo/intro/intro.narc +965db23ff625232448bbe4dfb410476203e09c94 res/prebuilt/demo/intro/intro_tv.narc +e388289d5648250d73b02a38e7a8a3ecca525e0c res/prebuilt/demo/shinka/data/particle/shinka_demo_particle.narc +d05e7387a0b95ad4ef79b75b93e130c303cf92e2 res/prebuilt/demo/syoujyou/syoujyou.narc +7fa87d90ba039f67221a43782bf6a1a1107d5947 res/prebuilt/demo/title/op_demo.narc +d7e86fadf59a54f922fc7cf65ae65fa326b8429e res/prebuilt/demo/title/titledemo.narc +771128a72a1452c507a57f5efe8d5554f4394ea2 res/prebuilt/dwc/utility.bin +8174da67845c24f377f56e84a0f5f0e890e765ec res/prebuilt/fielddata/areadata/area_build_model/areabm_texset.narc +a2cd6f636960544440b489e827e5e16dcaa7f014 res/prebuilt/fielddata/areadata/area_build_model/area_build.narc +2df833d8f0145f29f21b23c06ba3561dec3f5180 res/prebuilt/fielddata/areadata/area_data.narc +74aded294b971d68f10554f86fd795b072a0b01f res/prebuilt/fielddata/areadata/area_map_tex/map_tex_set.narc +2fb9b73d29f2577fdbd385daf961749794969d72 res/prebuilt/fielddata/areadata/area_move_model/move_model_list.narc +7eca91aaa5f7ef816f51a884e2f42a26f51f8bbd res/prebuilt/fielddata/build_model/build_model.narc +f49c6992b8caf5fea13831789fe4bfb026beb967 res/prebuilt/fielddata/build_model/build_model_matshp.dat +bda5c8e66cfa121c2d518d4388bd6f742746cda0 res/prebuilt/fielddata/encountdata/d_enc_data.narc +d9bf534c175c3c991e77fff985c099723499e1eb res/prebuilt/fielddata/encountdata/pl_enc_data.narc +4bcbf53d522ed962160b85af588816f7257fb1c3 res/prebuilt/fielddata/encountdata/p_enc_data.narc +e484a4ea105e16977b9f39b965aaad014a4ec923 res/prebuilt/fielddata/eventdata/zone_event.narc +fa044bf2e0599ed2bf42d3b632776af3b7e8452e res/prebuilt/fielddata/land_data/land_data.narc +992f33f6450613066830606d28e94b91031caddb res/prebuilt/fielddata/mapmatrix/map_matrix.narc +e486e52fc813b5c8d334afedf515cbce879de372 res/prebuilt/fielddata/maptable/mapname.bin +205a3d2db44040f4fafa6cb15301f3d9e77e5109 res/prebuilt/fielddata/mm_list/move_model_list.narc +32a0989a18cc7f3eb17c5949adecb3f057a84eea res/prebuilt/fielddata/pokemon_trade/fld_trade.narc +9f4d3587b7032f4f673ccc1b8971685b2199396b res/prebuilt/fielddata/script/scr_seq.narc +def7833f7d5b18328cbe9cc5d5331ff634b082cc res/prebuilt/fielddata/tornworld/tw_arc.narc +bf51c9691b15f9aff257a3e8012dc36bd015619f res/prebuilt/fielddata/tornworld/tw_arc_attr.narc +da56afbb7a3f070d8e14f99c9ba6334f7d9b6c2e res/prebuilt/frontier/script/fr_script.narc +86e4a1030a0f3939eff107e94023140dd91acf6a res/prebuilt/graphic/bag_gra.narc +1c6bab5b5b8295bb3e6b8b6a271a7ca20c1ae177 res/prebuilt/graphic/box.narc +cf140701a40be4f23bb24fb17145b1a176ceabcd res/prebuilt/graphic/btower.narc +f0dd678b1de5b9231ffad99f207085a1dab37491 res/prebuilt/graphic/bucket.narc +9d3829844b18063946f3bddcf67a839c95c0186f res/prebuilt/graphic/config_gra.narc +937807f1632664139194b95e3f7b8a58ac33f89a res/prebuilt/graphic/demo_trade.narc +67a8fb6c1b269ab107f2a98f23a5f53fb383ca1d res/prebuilt/graphic/dendou_demo.narc +d5a8953a61b8589539ce7b139ab956a802adaa33 res/prebuilt/graphic/dendou_pc.narc +2d1a354e31cdd1861bdd7aade661fb9e4dc0ae31 res/prebuilt/graphic/ending.narc +d91ceca1e3ef5e57061dabc690c0f1a1556dc624 res/prebuilt/graphic/ev_pokeselect.narc +4941a639804c2b009836d1ab9b86a2ab0bb0c436 res/prebuilt/graphic/field_board.narc +3a71f8eca65f2524f96c4bb8463800ae19a70a90 res/prebuilt/graphic/field_encounteffect.narc +e4ad5fcd9010114089a5ded83a077a75860d633a res/prebuilt/graphic/fld_comact.narc +1122e901209b1047fbbacb1a47311c8bd529a647 res/prebuilt/graphic/font.narc +02e2132b2bb08413d890c220bff7219e3725f7c2 res/prebuilt/graphic/fontoam.narc +e7266bd8b7095861b6e1fdaf4f13cb648a9c325d res/prebuilt/graphic/footprint_board.narc +5c673be62fe6bddfa911e3be26762b7e47d60b41 res/prebuilt/graphic/f_note_gra.narc +035a00972c8c63a18e00d82f4fc0cb1f46aef76d res/prebuilt/graphic/hiden_effect.narc +24760aae84c838f66389e1de92bc1b1579f5d953 res/prebuilt/graphic/imageclip.narc +4d1aac7d0014e2ffdfb6501b3f16ec2084d46e04 res/prebuilt/graphic/library_tv.narc +44214e37e0345a75b00a1c01d46ca787cdba1fb8 res/prebuilt/graphic/lobby_news.narc +428a40285a2c82705502962047f8cb9492ef3df1 res/prebuilt/graphic/mail_gra.narc +1d70dd8856d2f85beb2d4e461cfaf7179153640a res/prebuilt/graphic/menu_gra.narc +5ccc879d6b89822eff8adeb0637af9f06c7d640d res/prebuilt/graphic/mysign.narc +0f05587c988da3072761675d31b6bf94c9928d65 res/prebuilt/graphic/mystery.narc +0de1d0a92bf3c1cf90b4522b11fb397dfdf9d533 res/prebuilt/graphic/ntag_gra.narc +46742a8665062b1fa4fe576491fa2ad67ca83f49 res/prebuilt/graphic/nutmixer.narc +e22f0296444ce01e0b7619f73a8cf2016b2307b4 res/prebuilt/graphic/oekaki.narc +917f25f4e5bb3f5e1837471d2a90225e9e95363d res/prebuilt/graphic/opening.narc +b9f77b38cc07a6754fc00a7c1830d86c88d45aa6 res/prebuilt/graphic/plist_gra.narc +dd0663e46347230d1d1b9eb8b583cee9acc10f31 res/prebuilt/graphic/pl_bag_gra.narc +0929061d78710595aa53796ecffe3545f8406d82 res/prebuilt/graphic/pl_font.narc +d397dbd087737151aa8bea242016c626afb55fa5 res/prebuilt/graphic/pl_plist_gra.narc +883e6afb310f0ab02c26f2026cba1c76210bb3ac res/prebuilt/graphic/pl_pst_gra.narc +c16faeeeee494830c720d1f795a141cacfe49121 res/prebuilt/graphic/pl_wifinote.narc +298fd1d0ab31efd35cb00b977f69eacbfb8a8da8 res/prebuilt/graphic/pl_winframe.narc +e6a7fe0328d168e1b4d92919fe047d2fa12daf56 res/prebuilt/graphic/pmsi.narc +7c6a50d69659697636849cedebb0143ed0cf146a res/prebuilt/graphic/poketch.narc +072d6abfeee0e866719b37d40475fcd86cf928a9 res/prebuilt/graphic/poruact.narc +d263e5a1eae27a68063e10093e15b06e02de10f5 res/prebuilt/graphic/porudemo.narc +3201157ab4617a303e9cac30cf1e3f7104c653e2 res/prebuilt/graphic/poru_gra.narc +1360486ee8eb2c19e8c5b6e36e4843d56a42c066 res/prebuilt/graphic/pst_gra.narc +a14c782aba232ccd2fa1968512950f5d055936e3 res/prebuilt/graphic/ranking.narc +dc5129bfe80b3fb77c46f54392e6762d0b3aaeb3 res/prebuilt/graphic/record.narc +53fff347f98f51eab9aa00f720a67cd43ffc0502 res/prebuilt/graphic/shop_gra.narc +f79e12419475818dcdb42df7fbf843e3c8f71252 res/prebuilt/graphic/tmap_gra.narc +3675606fff996a3c20fd8a35b514aacdff54c46a res/prebuilt/graphic/touch_subwindow.narc +3446f96721b7dee9983222f2ecf4bc30e1530f27 res/prebuilt/graphic/trainer_case.narc +474dd2ac959d28cf2be9cdc2fb0626b091ab281e res/prebuilt/graphic/unionobj2d_onlyfront.narc +a90eefcf0fe8e649978329bec0185c072392ee58 res/prebuilt/graphic/unionroom.narc +b653d274c54681632e3c4f166f523573be9be08e res/prebuilt/graphic/waza_oshie_gra.narc +aa8f109bb43f94b0c8cf3cf5c27fb166da269823 res/prebuilt/graphic/wifi2dchar.narc +16b0d7afaa52c353007b44bbdfbb73e9ccf0207c res/prebuilt/graphic/wifi_lobby.narc +9cafec00fea9184395906e6063dad7ad456b99d3 res/prebuilt/graphic/wifi_lobby_other.narc +022fba2bbc1c798b111d90b3562c8847dfe678fd res/prebuilt/graphic/wifi_unionobj.narc +205b32679ea797b998bffb8b2d89194963dbd13a res/prebuilt/graphic/winframe.narc +8c845e477096afff262c3890ec8490b5426064f2 res/prebuilt/graphic/worldtimer.narc +a2eca9df316b9cad191ace16d08a90603966e892 res/prebuilt/graphic/worldtrade.narc +2e02f8d5040f0fce4fe1033c3831689244fe9fe4 res/prebuilt/itemtool/itemdata/item_data.narc +4fcc3fbd829a7cbf34a1b32440f619b731f7a08f res/prebuilt/itemtool/itemdata/item_icon.narc +1ad55f1a6d2ad34116b9e9502a330bf054e2f2d3 res/prebuilt/msgdata/msg.narc +c995669c61058be149d6282036397ebee3a3b1b8 res/prebuilt/msgdata/scenario/scr_msg.narc +e03ff29bc200e233217ad7a8f068ec77b33e6472 res/prebuilt/particledata/particledata.narc +3b475e06d86853ac3986f78ea356e4efe03d2d00 res/prebuilt/particledata/pl_etc/pl_etc_particle.narc +710d0fb2429a9fcd547ed2f165eb7a860e4be63f res/prebuilt/particledata/pl_frontier/frontier_particle.narc +ad8bf1d7e289c679e0d2c844ba1700fb2e61fedd res/prebuilt/particledata/pl_pokelist/pokelist_particle.narc +dc6caed3c4b1a0b04bebfcf6627a668e37ae6f2c res/prebuilt/pokeanime/pl_poke_anm.narc +b37a0c1e61ba1b2ceb905bad16476f1fb5966f18 res/prebuilt/pokeanime/poke_anm.narc +6d861f9f35d1b267cd7b84368a1b7dc76b4e9669 res/prebuilt/poketool/icongra/pl_poke_icon.narc +0622e95a5dc830735e711852032b829ead7d21e6 res/prebuilt/poketool/icongra/poke_icon.narc +7755e3a884a11b098122ca9dd656223fd4b02dd0 res/prebuilt/poketool/personal/evo.narc +fbbf1287b2ac10c5212be0e4a69461507e860005 res/prebuilt/poketool/personal/growtbl.narc +16f526ba6a59561e1f351769ef74a6a3e0428e8c res/prebuilt/poketool/personal/personal.narc +fbbf1287b2ac10c5212be0e4a69461507e860005 res/prebuilt/poketool/personal/pl_growtbl.narc +de5c1035595e3cb52990b183497e513246bd0efe res/prebuilt/poketool/personal/pms.narc +cd4b737f173cc6ac1a25636efa4edfd83da79599 res/prebuilt/poketool/personal/wotbl.narc +9848c22dfdab0edbf9bab5dc6562fea41498d962 res/prebuilt/poketool/pl_pokezukan.narc +f414660585d0c1c638cb235ad6b025bd590986a4 res/prebuilt/poketool/pokeanm/pl_pokeanm.narc +f414660585d0c1c638cb235ad6b025bd590986a4 res/prebuilt/poketool/pokeanm/pokeanm.narc +7fb44c0bcde2ac5ae042835146c21b84159f5693 res/prebuilt/poketool/pokefoot/pokefoot.narc +58a73976128abaa281f1567960c6028d81bf44c6 res/prebuilt/poketool/pokegra/dp_height.narc +75749218feb89f6cbfc672af461a37ae83b9c459 res/prebuilt/poketool/pokegra/dp_height_o.narc +cb0cb82390e01eea3983613d5458d51510fe77d5 res/prebuilt/poketool/pokegra/height.narc +998d53ececa0729beaad2a0dd630cd8e719e1ffb res/prebuilt/poketool/pokegra/height_o.narc +9b75e436fb4c7b35156eed3cf7c5f0827a829435 res/prebuilt/poketool/pokegra/otherpoke.narc +e7f8f89140c65a6655da72dca09e1f93d5360942 res/prebuilt/poketool/pokegra/pl_otherpoke.narc +e55f97e91b48ddd010cae4db6cec329160e963b5 res/prebuilt/poketool/pokegra/pl_pokegra.narc +23a3e0392b77e0a10759b282796a139235fc5302 res/prebuilt/poketool/pokegra/pokegra.narc +42620751f836fd71cc87076b77890eed968c600e res/prebuilt/poketool/pokegra/poke_shadow.narc +878ee9603413426966c0a4e12e83f98473522769 res/prebuilt/poketool/pokegra/poke_shadow_ofx.narc +093dd07a406d331369d1066e78f8617b8c6dd9d7 res/prebuilt/poketool/pokegra/poke_yofs.narc +115e9632aba1f20195779667fe7ba8f89f268aad res/prebuilt/poketool/pokezukan.narc +231228a02a80612dbe2036e2296a59e2c5a8b681 res/prebuilt/poketool/poke_edit/pl_poke_data.narc +e7b13d750733413f481d6c2423fee32cb7d5df37 res/prebuilt/poketool/shinzukan.narc +59f49fe682ef8cf4dfb8f6b7da2e0f51401b50cc res/prebuilt/poketool/trainer/trdata.narc +da4dc734c7051754a3280d9e918942c42d183adb res/prebuilt/poketool/trainer/trpoke.narc +4fb9e47d018968ca2bf28ca3194e85d872102dd1 res/prebuilt/poketool/trgra/trbgra.narc +e32324642d5ec29155743970ac8bc14dd74f63e1 res/prebuilt/poketool/trgra/trfgra.narc +f2510b7ff0305a01e0aaec1fd438ebd63a52b3bc res/prebuilt/poketool/trmsg/trtbl.narc +eb67fe3a80265f7d874c107850a3f6b75cadb83d res/prebuilt/poketool/trmsg/trtblofs.narc +20a2a364629e4eb897f3cf443e15e65b7f1ac957 res/prebuilt/poketool/waza/waza_tbl.narc +7e85af57b27fa4a0829b24550fc6c0dd275cf994 res/prebuilt/resource/eng/batt_rec/batt_rec_gra.narc +6be171e5d73a8ce4f6e262e6be0dd47c9bb95e41 res/prebuilt/resource/eng/frontier_graphic/frontier_bg.narc +8da7c7124dc267e37a556c7f7f5f56b15cd2e1fe res/prebuilt/resource/eng/frontier_graphic/frontier_obj.narc +9f8e15ee6e39f5d3ab5abf065dcc8d4850c08c5e res/prebuilt/resource/eng/pms_aikotoba/pms_aikotoba.narc +5e8b4dcaf50f35dbf82ba9035c9fdddc88208b6e res/prebuilt/resource/eng/scratch/scratch.narc +2994f2955035001a22a1f225c68bfa809e4c85bf res/prebuilt/resource/eng/wifi_lobby_minigame/wlmngm_tool.narc +d4b6f9731b808a613338005f59959325ce1e3ac9 res/prebuilt/resource/eng/zukan/zukan.narc +64c710d25e5dd7f0d8b7558b6d183648b1f56721 res/prebuilt/wazaeffect/effectclact/wecell.narc +82101cf2a686e2834dd45fa0a6c11407120b863d res/prebuilt/wazaeffect/effectclact/wecellanm.narc +8aa94ec2f9b21eab75e33d2a21b83a61c55e67b0 res/prebuilt/wazaeffect/effectclact/wechar.narc +e3bb819c8dbab8a8db5e4ddccc788b234424e605 res/prebuilt/wazaeffect/effectclact/wepltt.narc +5de52d02105237dc02fb4c87c9b8378a5da93217 res/prebuilt/wazaeffect/effectdata/ball_particle.narc +bd80949f0ab84fe4b4963a41063088b2e2d6df92 res/prebuilt/wazaeffect/effectdata/waza_particle.narc +c7e601f3c145dd3c36c6f1deee1f63d526be3c37 res/prebuilt/wazaeffect/we.arc +30bb77e76c27874bc8ff923b33492595f1a377e2 res/prebuilt/wazaeffect/we_sub.narc From 83d35529eef3e88b42d3b95bc5f05a48df603801 Mon Sep 17 00:00:00 2001 From: wildfire Date: Sat, 23 Sep 2023 13:46:03 +0100 Subject: [PATCH 2/6] Add support for multiple inputs, repsonse files --- res/prebuilt/data/mmodel/meson.build | 5 +- res/text/meson.build | 5 +- tools/json2bin/json2bin.py | 5 +- tools/knarc/Narc.cpp | 604 +++++++++++++++------------ tools/knarc/Narc.h | 12 +- tools/knarc/Source.cpp | 196 +++++---- tools/knarc/meson.build | 3 +- tools/knarc/util.cpp | 56 +++ tools/knarc/util.h | 4 + 9 files changed, 537 insertions(+), 353 deletions(-) create mode 100644 tools/knarc/util.cpp create mode 100644 tools/knarc/util.h diff --git a/res/prebuilt/data/mmodel/meson.build b/res/prebuilt/data/mmodel/meson.build index 9c997b9fa5..31cef82885 100644 --- a/res/prebuilt/data/mmodel/meson.build +++ b/res/prebuilt/data/mmodel/meson.build @@ -5,8 +5,9 @@ mmodel_narc = custom_target('mmodel.narc', input: mmodel_files_targets, command: [ knarc_exe, - '-d', '@OUTDIR@/mmodel', - '-p', '@OUTPUT0@' + 'pack', '-s', + '-o', '@OUTPUT0@', + '@OUTDIR@/mmodel' ] ) diff --git a/res/text/meson.build b/res/text/meson.build index 648c9947bf..1c2486c91c 100644 --- a/res/text/meson.build +++ b/res/text/meson.build @@ -742,8 +742,9 @@ pl_msg_narc = custom_target('pl_msg.narc', input: gmm_to_bin_gen.process(pl_msg_gmm), command: [ knarc_exe, - '-d', '@PRIVATE_DIR@', - '-p', '@OUTPUT0@' + 'pack', '-s', + '-o', '@OUTPUT0@', + '@PRIVATE_DIR@', ] ) diff --git a/tools/json2bin/json2bin.py b/tools/json2bin/json2bin.py index e85f65145b..54ea2aae05 100644 --- a/tools/json2bin/json2bin.py +++ b/tools/json2bin/json2bin.py @@ -178,6 +178,7 @@ def json2bin(target: str, subprocess.run([ pathlib.Path(narc_packer), - '-d', private_dir, - '-p', output_dir / f'{narc_name}.narc' + 'pack', '-s', + '-o', output_dir / f'{narc_name}.narc', + files_output_dir, ]) diff --git a/tools/knarc/Narc.cpp b/tools/knarc/Narc.cpp index 0459409107..fbaf4ba56a 100644 --- a/tools/knarc/Narc.cpp +++ b/tools/knarc/Narc.cpp @@ -30,6 +30,31 @@ using namespace std; extern bool debug; extern bool pack_no_fnt; extern bool output_header; +extern bool orderInputs; +extern fs::path knarcorder_path; +extern fs::path knarcignore_path; +extern fs::path knarckeep_path; + +std::string get_error_string(NarcError error) +{ + switch (error) + { + case NarcError::None: return "ERROR: No error???"; + case NarcError::InvalidInputFile: return "ERROR: Invalid input file"; + case NarcError::InvalidHeaderId: return "ERROR: Invalid header ID"; + case NarcError::InvalidByteOrderMark: return "ERROR: Invalid byte order mark"; + case NarcError::InvalidVersion: return "ERROR: Invalid NARC version"; + case NarcError::InvalidHeaderSize: return "ERROR: Invalid header size"; + case NarcError::InvalidChunkCount: return "ERROR: Invalid chunk count"; + case NarcError::InvalidFileAllocationTableId: return "ERROR: Invalid file allocation table ID"; + case NarcError::InvalidFileAllocationTableReserved: return "ERROR: Invalid file allocation table reserved section"; + case NarcError::InvalidFileNameTableId: return "ERROR: Invalid file name table ID"; + case NarcError::InvalidFileNameTableEntryId: return "ERROR: Invalid file name table entry ID"; + case NarcError::InvalidFileImagesId: return "ERROR: Invalid file images ID"; + case NarcError::InvalidOutputFile: return "ERROR: Invalid output file"; + default: return "ERROR: Unknown error???"; + } +} void Narc::AlignDword(ofstream& ofs, uint8_t paddingChar) { @@ -60,125 +85,184 @@ bool Narc::Cleanup(ofstream& ofs, const NarcError& e) return false; } -std::vector Narc::KnarcOrderDirectoryIterator(const fs::path& path, bool recursive) const +std::vector read_knarcorder_file(fs::path file) { + std::vector ordered_files; + std::ifstream order_file(knarcorder_path); + if (order_file) + { + if (debug) + { + cerr << "DEBUG: knarcorder file exists" << endl; + } + // read the filenames in the order file and add the corresponding directory entries to the ordered files vector + std::string filename; + while (std::getline(order_file, filename)) + { + fs::path file_path = file.parent_path() / filename; + if (fs::exists(file_path)) + { + if (debug) + { + cerr << "DEBUG: knarcorder file: " << file_path << endl; + } + ordered_files.push_back(file_path); + } + } + } + return ordered_files; +} + +std::vector Narc::KnarcInputIterator(const std::vector& paths, bool recursive, bool lexSort) const { - std::vector ordered_files; - std::vector unordered_files; + std::vector ordered_files; + std::vector unordered_files; - // open the order file - if (fs::exists(path / ".knarcorder")) + if (!knarcorder_path.empty()) { + ordered_files = read_knarcorder_file(knarcorder_path); + } + + for (fs::path path: paths) { - std::ifstream order_file(path / ".knarcorder"); - if (order_file) + if (fs::is_directory(path)) { - if (debug) + // open the order file + if (fs::exists(path / ".knarcorder")) { - cerr << "DEBUG: knarcorder file exists" << endl; + knarcorder_path = path / ".knarcorder"; + std::vector paths = read_knarcorder_file(knarcorder_path); + for (fs::path path: paths) + { + if (std::find(ordered_files.begin(), ordered_files.end(), path) == ordered_files.end()) + { + ordered_files.push_back(path); + } + } } - // read the filenames in the order file and add the corresponding directory entries to the ordered files vector - std::string filename; - while (std::getline(order_file, filename)) + + // if recursive flag is set, search for knarcorder files in subdirectories and process them recursively + if (recursive) { - fs::path file_path = path / filename; - if (fs::exists(file_path)) + for (auto &entry : fs::directory_iterator(path)) { - if (debug) + if (entry.is_directory()) { - cerr << "DEBUG: knarcorder file: " << file_path << endl; + std::vector sub; + sub.emplace_back(entry.path()); + std::vector subdirectory_files = + KnarcInputIterator(sub, true, lexSort); + ordered_files.insert( + ordered_files.end(), subdirectory_files.begin(), subdirectory_files.end()); } - ordered_files.push_back(fs::directory_entry(file_path)); } } - } - } - // if recursive flag is set, search for knarcorder files in subdirectories and process them recursively - if (recursive) - { - for (auto &entry : fs::directory_iterator(path)) - { - if (entry.is_directory()) + // add the remaining files in alphabetical order + for (auto& entry : fs::directory_iterator(path)) { - std::vector subdirectory_files = - KnarcOrderDirectoryIterator(entry.path(), true); - ordered_files.insert( - ordered_files.end(), subdirectory_files.begin(), subdirectory_files.end()); + if (entry.is_regular_file() && entry.path().filename() != ".knarcorder") + { + if (std::find(ordered_files.begin(), ordered_files.end(), entry) == ordered_files.end()) + { + unordered_files.push_back(entry); + } + } } } - } - - // add the remaining files in alphabetical order - for (auto& entry : fs::directory_iterator(path)) - { - if (entry.is_regular_file() && entry.path().filename() != ".knarcorder") + else { - if (std::find(ordered_files.begin(), ordered_files.end(), entry) == ordered_files.end()) + if (std::find(ordered_files.begin(), ordered_files.end(), path) == ordered_files.end()) { - unordered_files.push_back(entry); + unordered_files.push_back(path); } } } - std::sort(unordered_files.begin(), unordered_files.end(), - [](const fs::directory_entry& a, const fs::directory_entry& b) - { - // I fucking hate C++ - string aStr = a.path().filename().string(); - string bStr = b.path().filename().string(); - - for (size_t i = 0; i < aStr.size(); ++i) - { - aStr[i] = tolower(aStr[i]); - } - - for (size_t i = 0; i < bStr.size(); ++i) - { - bStr[i] = tolower(bStr[i]); - } - - return aStr < bStr; - }); + + if(lexSort) + { + std::sort(unordered_files.begin(), unordered_files.end(), + [](const fs::path& a, const fs::path& b) + { + // I fucking hate C++ + string aStr = a.filename().string(); + string bStr = b.filename().string(); + + for (size_t i = 0; i < aStr.size(); ++i) + { + aStr[i] = tolower(aStr[i]); + } + + for (size_t i = 0; i < bStr.size(); ++i) + { + bStr[i] = tolower(bStr[i]); + } + // std::transform(aStr.begin(), aStr.end(), aStr.begin(), ::tolower); + // std::transform(bStr.begin(), bStr.end(), bStr.begin(), ::tolower); + + return aStr < bStr; + } + ); + } ordered_files.insert(ordered_files.end(), unordered_files.begin(), unordered_files.end()); return ordered_files; } -vector Narc::OrderedDirectoryIterator(const fs::path& path, bool recursive) const +vector Narc::InputIterator(const std::vector& paths, bool recursive, bool lexSort) const { - vector v; + vector v; - for (const auto& de : fs::directory_iterator(path)) + for(fs::path path: paths) { - v.push_back(de); - } - - sort(v.begin(), v.end(), [](const fs::directory_entry& a, const fs::directory_entry& b) + if(fs::is_directory(path)) { - // I fucking hate C++ - string aStr = a.path().filename().string(); - string bStr = b.path().filename().string(); - - for (size_t i = 0; i < aStr.size(); ++i) + for (const auto& de : fs::directory_iterator(path)) { - aStr[i] = tolower(aStr[i]); + v.push_back(de.path()); } + } + else + { + v.push_back(path); + } + } - for (size_t i = 0; i < bStr.size(); ++i) - { - bStr[i] = tolower(bStr[i]); - } + if(lexSort) + { + std::sort(v.begin(), v.end(), + [](const fs::path& a, const fs::path& b) + { + // I fucking hate C++ + string aStr = a.filename().string(); + string bStr = b.filename().string(); + + for (size_t i = 0; i < aStr.size(); ++i) + { + aStr[i] = tolower(aStr[i]); + } - return aStr < bStr; - }); + for (size_t i = 0; i < bStr.size(); ++i) + { + bStr[i] = tolower(bStr[i]); + } + // std::transform(aStr.begin(), aStr.end(), aStr.begin(), ::tolower); + // std::transform(bStr.begin(), bStr.end(), bStr.begin(), ::tolower); + + return aStr < bStr; + } + ); + } if (recursive) { size_t vSize = v.size(); - for (size_t i = 0; i < vSize; ++i) + for (fs::path path: v) { - if (is_directory(v[i])) + if (is_directory(path)) { - vector temp = OrderedDirectoryIterator(v[i], true); + std::vector sub; + sub.emplace_back(path); + std::vector temp = InputIterator(sub, true, lexSort); v.insert(v.end(), temp.begin(), temp.end()); } @@ -204,7 +288,7 @@ class WildcardVector : public vector { if (!line.empty()) { // strip CR - size_t i; + size_t i = 0; for (i = line.size() - 1; line[i] == '\r'; i--) ; if (i < line.size() - 1) @@ -222,9 +306,9 @@ class WildcardVector : public vector { } }; -bool Narc::Pack(const fs::path& fileName, const fs::path& directory) +bool Narc::Pack(const fs::path& outputPath, const std::vector& inputPaths) { - ofstream ofs(fileName, ios::binary); + ofstream ofs(outputPath, ios::binary); if (!ofs.good()) { return Cleanup(ofs, NarcError::InvalidOutputFile); } @@ -235,7 +319,7 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) // Output an includable header that enumerates the NARC contents if (output_header) { - fs::path naixfname = fileName; + fs::path naixfname = outputPath; naixfname.replace_extension(".naix"); ofhs.open(naixfname); @@ -245,10 +329,11 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) return Cleanup(ofs, NarcError::InvalidOutputFile); } - stem = fileName.stem().string(); + stem = outputPath.stem().string(); stem_upper = stem; for (char &c : stem_upper) { c = toupper(c); } + // std::transform(stem_upper.begin(), stem_upper.end(), stem_upper.begin(), ::toupper); ofhs << "/*\n" " * THIS FILE WAS AUTOMATICALLY\n" @@ -264,29 +349,29 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) vector fatEntries; uint16_t directoryCounter = 1; - WildcardVector ignore_patterns(directory / ".knarcignore"); + WildcardVector ignore_patterns(knarcignore_path); ignore_patterns.push_back(".*ignore"); ignore_patterns.push_back(".*keep"); ignore_patterns.push_back(".*order"); - WildcardVector keep_patterns(directory / ".knarckeep"); + WildcardVector keep_patterns(knarckeep_path); int memberNo = 0; - for (const auto& de : KnarcOrderDirectoryIterator(directory, true)) + for (const auto& path : KnarcInputIterator(inputPaths, true, orderInputs)) { - if (is_directory(de)) + if (is_directory(path)) { ++directoryCounter; } - else if (keep_patterns.matches(de.path().filename().string()) || !ignore_patterns.matches(de.path().filename().string())) + else if (keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string())) { if (debug) { - cerr << "DEBUG: adding file " << de.path() << endl; + std::cerr << "DEBUG: adding file " << path << endl; } if (output_header) { - string de_stem = de.path().filename().string(); - std::replace(de_stem.begin(), de_stem.end(), '.', '_'); - ofhs << "\tNARC_" << stem << "_" << de_stem << " = " << (memberNo++) << ",\n"; + string path_stem = path.filename().string(); + std::replace(path_stem.begin(), path_stem.end(), '.', '_'); + ofhs << "\tNARC_" << stem << "_" << path_stem << " = " << (memberNo++) << ",\n"; } fatEntries.push_back(FileAllocationTableEntry { @@ -304,7 +389,7 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) } } - fatEntries.back().End = fatEntries.back().Start + static_cast(file_size(de)); + fatEntries.back().End = fatEntries.back().Start + static_cast(file_size(path)); } } if (output_header) @@ -326,27 +411,27 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) directoryCounter = 0; - for (const auto& de : KnarcOrderDirectoryIterator(directory, true)) + for (const auto& path : KnarcInputIterator(inputPaths, true, orderInputs)) { - if (!subTables.count(de.path().parent_path()) && (keep_patterns.matches(de.path().filename().string()) || !ignore_patterns.matches(de.path().filename().string()))) + if (!subTables.count(path.parent_path()) && (keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string()))) { - subTables.insert({ de.path().parent_path(), "" }); - paths.push_back(de.path().parent_path()); + subTables.insert({ path.parent_path(), "" }); + paths.push_back(path.parent_path()); } - if (is_directory(de)) + if (is_directory(path)) { ++directoryCounter; - subTables[de.path().parent_path()] += static_cast(0x80 + de.path().filename().string().size()); - subTables[de.path().parent_path()] += de.path().filename().string(); - subTables[de.path().parent_path()] += (0xF000 + directoryCounter) & 0xFF; - subTables[de.path().parent_path()] += (0xF000 + directoryCounter) >> 8; + subTables[path.parent_path()] += static_cast(0x80 + path.filename().string().size()); + subTables[path.parent_path()] += path.filename().string(); + subTables[path.parent_path()] += (0xF000 + directoryCounter) & 0xFF; + subTables[path.parent_path()] += (0xF000 + directoryCounter) >> 8; } - else if (keep_patterns.matches(de.path().filename().string()) || !ignore_patterns.matches(de.path().filename().string())) + else if (keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string())) { - subTables[de.path().parent_path()] += static_cast(de.path().filename().string().size()); - subTables[de.path().parent_path()] += de.path().filename().string(); + subTables[path.parent_path()] += static_cast(path.filename().string().size()); + subTables[path.parent_path()] += path.filename().string(); } } @@ -468,19 +553,19 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) ofs.write(reinterpret_cast(&fi), sizeof(FileImages)); - for (const auto& de : KnarcOrderDirectoryIterator(directory, true)) + for (const auto& path : KnarcInputIterator(inputPaths, true, orderInputs)) { - if (is_directory(de)) + if (is_directory(path)) { continue; } - if (!(keep_patterns.matches(de.path().filename().string()) || !ignore_patterns.matches(de.path().filename().string()))) + if (!(keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string()))) { continue; } - ifstream ifs(de.path(), ios::binary | ios::ate); + ifstream ifs(path, ios::binary | ios::ate); if (!ifs.good()) { @@ -506,215 +591,218 @@ bool Narc::Pack(const fs::path& fileName, const fs::path& directory) return error == NarcError::None ? true : false; } -bool Narc::Unpack(const fs::path& fileName, const fs::path& directory) +bool Narc::Unpack(const fs::path& outputPath, const std::vector& inputPaths) { - ifstream ifs(fileName, ios::binary); + for (fs::path path: inputPaths) { - if (!ifs.good()) { return Cleanup(ifs, NarcError::InvalidInputFile); } + ifstream ifs(path, ios::binary); - Header header; - ifs.read(reinterpret_cast(&header), sizeof(Header)); + if (!ifs.good()) { return Cleanup(ifs, NarcError::InvalidInputFile); } - if (header.Id != 0x4352414E) { return Cleanup(ifs, NarcError::InvalidHeaderId); } - if (header.ByteOrderMark != 0xFFFE) { return Cleanup(ifs, NarcError::InvalidByteOrderMark); } - if ((header.Version != 0x0100) && (header.Version != 0x0000)) { return Cleanup(ifs, NarcError::InvalidVersion); } - if (header.ChunkSize != 0x10) { return Cleanup(ifs, NarcError::InvalidHeaderSize); } - if (header.ChunkCount != 0x3) { return Cleanup(ifs, NarcError::InvalidChunkCount); } + Header header; + ifs.read(reinterpret_cast(&header), sizeof(Header)); - FileAllocationTable fat; - ifs.read(reinterpret_cast(&fat), sizeof(FileAllocationTable)); + if (header.Id != 0x4352414E) { return Cleanup(ifs, NarcError::InvalidHeaderId); } + if (header.ByteOrderMark != 0xFFFE) { return Cleanup(ifs, NarcError::InvalidByteOrderMark); } + if ((header.Version != 0x0100) && (header.Version != 0x0000)) { return Cleanup(ifs, NarcError::InvalidVersion); } + if (header.ChunkSize != 0x10) { return Cleanup(ifs, NarcError::InvalidHeaderSize); } + if (header.ChunkCount != 0x3) { return Cleanup(ifs, NarcError::InvalidChunkCount); } - if (fat.Id != 0x46415442) { return Cleanup(ifs, NarcError::InvalidFileAllocationTableId); } - if (fat.Reserved != 0x0) { return Cleanup(ifs, NarcError::InvalidFileAllocationTableReserved); } + FileAllocationTable fat; + ifs.read(reinterpret_cast(&fat), sizeof(FileAllocationTable)); - unique_ptr fatEntries = make_unique(fat.FileCount); + if (fat.Id != 0x46415442) { return Cleanup(ifs, NarcError::InvalidFileAllocationTableId); } + if (fat.Reserved != 0x0) { return Cleanup(ifs, NarcError::InvalidFileAllocationTableReserved); } - for (uint16_t i = 0; i < fat.FileCount; ++i) - { - ifs.read(reinterpret_cast(&fatEntries.get()[i]), sizeof(FileAllocationTableEntry)); - } + unique_ptr fatEntries = make_unique(fat.FileCount); - FileNameTable fnt; - vector FileNameTableEntries; - ifs.read(reinterpret_cast(&fnt), sizeof(FileNameTable)); + for (uint16_t i = 0; i < fat.FileCount; ++i) + { + ifs.read(reinterpret_cast(&fatEntries.get()[i]), sizeof(FileAllocationTableEntry)); + } - if (fnt.Id != 0x464E5442) { return Cleanup(ifs, NarcError::InvalidFileNameTableId); } + FileNameTable fnt; + vector FileNameTableEntries; + ifs.read(reinterpret_cast(&fnt), sizeof(FileNameTable)); - vector fntEntries; + if (fnt.Id != 0x464E5442) { return Cleanup(ifs, NarcError::InvalidFileNameTableId); } - do - { - fntEntries.push_back(FileNameTableEntry()); + vector fntEntries; - ifs.read(reinterpret_cast(&fntEntries.back().Offset), sizeof(uint32_t)); - ifs.read(reinterpret_cast(&fntEntries.back().FirstFileId), sizeof(uint16_t)); - ifs.read(reinterpret_cast(&fntEntries.back().Utility), sizeof(uint16_t)); - } while (static_cast(ifs.tellg()) < (header.ChunkSize + fat.ChunkSize + sizeof(FileNameTable) + fntEntries[0].Offset)); + do + { + fntEntries.push_back(FileNameTableEntry()); - unique_ptr fileNames = make_unique(0xFFFF); + ifs.read(reinterpret_cast(&fntEntries.back().Offset), sizeof(uint32_t)); + ifs.read(reinterpret_cast(&fntEntries.back().FirstFileId), sizeof(uint16_t)); + ifs.read(reinterpret_cast(&fntEntries.back().Utility), sizeof(uint16_t)); + } while (static_cast(ifs.tellg()) < (header.ChunkSize + fat.ChunkSize + sizeof(FileNameTable) + fntEntries[0].Offset)); - for (size_t i = 0; i < fntEntries.size(); ++i) - { - ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + sizeof(FileNameTable) + fntEntries[i].Offset); + unique_ptr fileNames = make_unique(0xFFFF); - uint16_t fileId = 0x0000; - - for (uint8_t length = 0x80; length != 0x00; ifs.read(reinterpret_cast(&length), sizeof(uint8_t))) + for (size_t i = 0; i < fntEntries.size(); ++i) { - if (length <= 0x7F) - { - for (uint8_t j = 0; j < length; ++j) - { - uint8_t c; - ifs.read(reinterpret_cast(&c), sizeof(uint8_t)); + ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + sizeof(FileNameTable) + fntEntries[i].Offset); - fileNames.get()[fntEntries[i].FirstFileId + fileId] += c; - } + uint16_t fileId = 0x0000; - ++fileId; - } - else if (length == 0x80) - { - // Reserved - } - else if (length <= 0xFF) + for (uint8_t length = 0x80; length != 0x00; ifs.read(reinterpret_cast(&length), sizeof(uint8_t))) { - length -= 0x80; - string directoryName; - - for (uint8_t j = 0; j < length; ++j) + if (length <= 0x7F) { - uint8_t c; - ifs.read(reinterpret_cast(&c), sizeof(uint8_t)); + for (uint8_t j = 0; j < length; ++j) + { + uint8_t c; + ifs.read(reinterpret_cast(&c), sizeof(uint8_t)); + + fileNames.get()[fntEntries[i].FirstFileId + fileId] += c; + } - directoryName += c; + ++fileId; + } + else if (length == 0x80) + { + // Reserved } + else if (length <= 0xFF) + { + length -= 0x80; + string directoryName; - uint16_t directoryId; - ifs.read(reinterpret_cast(&directoryId), sizeof(uint16_t)); + for (uint8_t j = 0; j < length; ++j) + { + uint8_t c; + ifs.read(reinterpret_cast(&c), sizeof(uint8_t)); - fileNames.get()[directoryId] = directoryName; - } - else - { - return Cleanup(ifs, NarcError::InvalidFileNameTableEntryId); + directoryName += c; + } + + uint16_t directoryId; + ifs.read(reinterpret_cast(&directoryId), sizeof(uint16_t)); + + fileNames.get()[directoryId] = directoryName; + } + else + { + return Cleanup(ifs, NarcError::InvalidFileNameTableEntryId); + } } } - } - if ((ifs.tellg() % 4) != 0) - { - ifs.seekg(4 - (ifs.tellg() % 4), ios::cur); - } + if ((ifs.tellg() % 4) != 0) + { + ifs.seekg(4 - (ifs.tellg() % 4), ios::cur); + } - FileImages fi; - ifs.read(reinterpret_cast(&fi), sizeof(FileImages)); + FileImages fi; + ifs.read(reinterpret_cast(&fi), sizeof(FileImages)); - if (fi.Id != 0x46494D47) { return Cleanup(ifs, NarcError::InvalidFileImagesId); } + if (fi.Id != 0x46494D47) { return Cleanup(ifs, NarcError::InvalidFileImagesId); } - fs::create_directory(directory); - fs::current_path(directory); + fs::create_directory(outputPath); + fs::current_path(outputPath); - if (fnt.ChunkSize == 0x10) - { - for (uint16_t i = 0; i < fat.FileCount; ++i) + if (fnt.ChunkSize == 0x10) { - ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + fnt.ChunkSize + 8 + fatEntries.get()[i].Start); + for (uint16_t i = 0; i < fat.FileCount; ++i) + { + ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + fnt.ChunkSize + 8 + fatEntries.get()[i].Start); - unique_ptr buffer = make_unique(fatEntries.get()[i].End - fatEntries.get()[i].Start); - ifs.read(buffer.get(), fatEntries.get()[i].End - fatEntries.get()[i].Start); + unique_ptr buffer = make_unique(fatEntries.get()[i].End - fatEntries.get()[i].Start); + ifs.read(buffer.get(), fatEntries.get()[i].End - fatEntries.get()[i].Start); - ostringstream oss; - oss << fileName.stem().string() << "_" << setfill('0') << setw(8) << i << ".bin"; + ostringstream oss; + oss << path.stem().string() << "_" << setfill('0') << setw(8) << i << ".bin"; - ofstream ofs(oss.str(), ios::binary); + ofstream ofs(oss.str(), ios::binary); - if (!ofs.good()) - { - ofs.close(); + if (!ofs.good()) + { + ofs.close(); - return Cleanup(ifs, NarcError::InvalidOutputFile); - } + return Cleanup(ifs, NarcError::InvalidOutputFile); + } - ofs.write(buffer.get(), fatEntries.get()[i].End - fatEntries.get()[i].Start); - ofs.close(); + ofs.write(buffer.get(), fatEntries.get()[i].End - fatEntries.get()[i].Start); + ofs.close(); + } } - } - else - { - fs::path absolutePath = fs::absolute(fs::current_path()); - - for (size_t i = 0; i < fntEntries.size(); ++i) + else { - fs::current_path(absolutePath); - stack directories; + fs::path absolutePath = fs::absolute(fs::current_path()); - for (uint16_t j = fntEntries[i].Utility; j > 0xF000; j = fntEntries[j - 0xF000].Utility) + for (size_t i = 0; i < fntEntries.size(); ++i) { - directories.push(fileNames.get()[j]); - } + fs::current_path(absolutePath); + stack directories; - for (; !directories.empty(); directories.pop()) - { - fs::create_directory(directories.top()); - fs::current_path(directories.top()); - } + for (uint16_t j = fntEntries[i].Utility; j > 0xF000; j = fntEntries[j - 0xF000].Utility) + { + directories.push(fileNames.get()[j]); + } - if (fntEntries[i].Utility >= 0xF000) - { - fs::create_directory(fileNames.get()[0xF000 + i]); - fs::current_path(fileNames.get()[0xF000 + i]); - } + for (; !directories.empty(); directories.pop()) + { + fs::create_directory(directories.top()); + fs::current_path(directories.top()); + } - ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + sizeof(FileNameTable) + fntEntries[i].Offset); + if (fntEntries[i].Utility >= 0xF000) + { + fs::create_directory(fileNames.get()[0xF000 + i]); + fs::current_path(fileNames.get()[0xF000 + i]); + } - uint16_t fileId = 0x0000; + ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + sizeof(FileNameTable) + fntEntries[i].Offset); - for (uint8_t length = 0x80; length != 0x00; ifs.read(reinterpret_cast(&length), sizeof(uint8_t))) - { - if (length <= 0x7F) + uint16_t fileId = 0x0000; + + for (uint8_t length = 0x80; length != 0x00; ifs.read(reinterpret_cast(&length), sizeof(uint8_t))) { - streampos savedPosition = ifs.tellg(); + if (length <= 0x7F) + { + streampos savedPosition = ifs.tellg(); - ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + fnt.ChunkSize + 8 + fatEntries.get()[fntEntries[i].FirstFileId + fileId].Start); + ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + fnt.ChunkSize + 8 + fatEntries.get()[fntEntries[i].FirstFileId + fileId].Start); - unique_ptr buffer = make_unique(fatEntries.get()[fntEntries[i].FirstFileId + fileId].End - fatEntries.get()[fntEntries[i].FirstFileId + fileId].Start); - ifs.read(buffer.get(), fatEntries.get()[fntEntries[i].FirstFileId + fileId].End - fatEntries.get()[fntEntries[i].FirstFileId + fileId].Start); + unique_ptr buffer = make_unique(fatEntries.get()[fntEntries[i].FirstFileId + fileId].End - fatEntries.get()[fntEntries[i].FirstFileId + fileId].Start); + ifs.read(buffer.get(), fatEntries.get()[fntEntries[i].FirstFileId + fileId].End - fatEntries.get()[fntEntries[i].FirstFileId + fileId].Start); - ofstream ofs(fileNames.get()[fntEntries[i].FirstFileId + fileId], ios::binary); + ofstream ofs(fileNames.get()[fntEntries[i].FirstFileId + fileId], ios::binary); - if (!ofs.good()) - { - ofs.close(); + if (!ofs.good()) + { + ofs.close(); - return Cleanup(ifs, NarcError::InvalidOutputFile); - } + return Cleanup(ifs, NarcError::InvalidOutputFile); + } - ofs.write(buffer.get(), fatEntries.get()[fntEntries[i].FirstFileId + fileId].End - fatEntries.get()[fntEntries[i].FirstFileId + fileId].Start); - ofs.close(); + ofs.write(buffer.get(), fatEntries.get()[fntEntries[i].FirstFileId + fileId].End - fatEntries.get()[fntEntries[i].FirstFileId + fileId].Start); + ofs.close(); - ifs.seekg(savedPosition); - ifs.seekg(length, ios::cur); + ifs.seekg(savedPosition); + ifs.seekg(length, ios::cur); - ++fileId; - } - else if (length == 0x80) - { - // Reserved - } - else if (length <= 0xFF) - { - ifs.seekg(static_cast(length) - 0x80 + 0x2, ios::cur); - } - else - { - return Cleanup(ifs, NarcError::InvalidFileNameTableEntryId); + ++fileId; + } + else if (length == 0x80) + { + // Reserved + } + else if (length <= 0xFF) + { + ifs.seekg(static_cast(length) - 0x80 + 0x2, ios::cur); + } + else + { + return Cleanup(ifs, NarcError::InvalidFileNameTableEntryId); + } } } } - } - - ifs.close(); + ifs.close(); + if (error != NarcError::None) return false; + } return error == NarcError::None ? true : false; } diff --git a/tools/knarc/Narc.h b/tools/knarc/Narc.h index ed0504f90b..b332cc97f2 100644 --- a/tools/knarc/Narc.h +++ b/tools/knarc/Narc.h @@ -27,9 +27,11 @@ enum class NarcError InvalidFileNameTableId, InvalidFileNameTableEntryId, InvalidFileImagesId, - InvalidOutputFile + InvalidOutputFile, }; +std::string get_error_string(NarcError error); + struct Header { uint32_t Id; @@ -78,8 +80,8 @@ class Narc public: NarcError GetError() const; - bool Pack(const fs::path& fileName, const fs::path& directory); - bool Unpack(const fs::path& fileName, const fs::path& directory); + bool Pack(const fs::path& outputPath, const std::vector& inputPaths); + bool Unpack(const fs::path& outputPath, const std::vector& inputPaths); private: NarcError error = NarcError::None; @@ -89,6 +91,6 @@ class Narc bool Cleanup(std::ifstream& ifs, const NarcError& e); bool Cleanup(std::ofstream& ofs, const NarcError& e); - std::vector KnarcOrderDirectoryIterator(const fs::path& path, bool recursive) const; - std::vector OrderedDirectoryIterator(const fs::path& path, bool recursive) const; + std::vector KnarcInputIterator(const std::vector& paths, bool recursive, bool order) const; + std::vector InputIterator(const std::vector& paths, bool recursive, bool order) const; }; diff --git a/tools/knarc/Source.cpp b/tools/knarc/Source.cpp index 587c852752..2cdeb340d6 100644 --- a/tools/knarc/Source.cpp +++ b/tools/knarc/Source.cpp @@ -1,150 +1,180 @@ #include +#include #include +#include #include +#include "util.h" #include "Narc.h" -using namespace std; - bool debug = false; bool pack_no_fnt = true; bool output_header = false; +bool orderInputs = false; +fs::path knarcorder_path; +fs::path knarcignore_path; +fs::path knarckeep_path; void PrintError(NarcError error) { - switch (error) - { - case NarcError::None: cout << "ERROR: No error???" << endl; break; - case NarcError::InvalidInputFile: cout << "ERROR: Invalid input file" << endl; break; - case NarcError::InvalidHeaderId: cout << "ERROR: Invalid header ID" << endl; break; - case NarcError::InvalidByteOrderMark: cout << "ERROR: Invalid byte order mark" << endl; break; - case NarcError::InvalidVersion: cout << "ERROR: Invalid NARC version" << endl; break; - case NarcError::InvalidHeaderSize: cout << "ERROR: Invalid header size" << endl; break; - case NarcError::InvalidChunkCount: cout << "ERROR: Invalid chunk count" << endl; break; - case NarcError::InvalidFileAllocationTableId: cout << "ERROR: Invalid file allocation table ID" << endl; break; - case NarcError::InvalidFileAllocationTableReserved: cout << "ERROR: Invalid file allocation table reserved section" << endl; break; - case NarcError::InvalidFileNameTableId: cout << "ERROR: Invalid file name table ID" << endl; break; - case NarcError::InvalidFileNameTableEntryId: cout << "ERROR: Invalid file name table entry ID" << endl; break; - case NarcError::InvalidFileImagesId: cout << "ERROR: Invalid file images ID" << endl; break; - case NarcError::InvalidOutputFile: cout << "ERROR: Invalid output file" << endl; break; - default: cout << "ERROR: Unknown error???" << endl; break; - } + std::cout << get_error_string(error) << std::endl; } static inline void usage() { - cout << "OVERVIEW: Knarc" << endl << endl; - cout << "USAGE: knarc [options] -d DIRECTORY [-p TARGET | -u SOURCE]" << endl << endl; - cout << "OPTIONS:" << endl; - cout << "\t-d DIRECTORY\tDirectory to pack from/unpack to" << endl; - cout << "\t-p TARGET\tPack to the target NARC" << endl; - cout << "\t-u SOURCE\tUnpack from the source NARC" << endl; - cout << "\t-n\tBuild the filename table (default: discards filenames)" << endl; - cout << "\t-D/--debug\tPrint additional debug messages" << endl; - cout << "\t-h/--help\tPrint this message and exit" << endl; - cout << "\t-i\tOutput a .naix header" << endl; + std::cout << "OVERVIEW: Knarc" << std::endl << std::endl; + std::cout << "USAGE: knarc [] []" << std::endl << std::endl; + std::cout << "COMMANDS:" << std::endl; + std::cout << "\tpack\tPack a NARC file" << std::endl; + std::cout << "\tunpack\tUnpack a NARC file" << std::endl; + std::cout << "\thelp\tDisplay this text" << std::endl; + std::cout << "OPTIONS:" << std::endl; + std::cout << "\t-o \tPath to output file/directory" << std::endl; + std::cout << "\t-ko \tPath to .knarcorder file" << std::endl; + std::cout << "\t-ki \tPath to .knarcignore file" << std::endl; + std::cout << "\t-kk \tPath to .knarckeep file" << std::endl; + std::cout << "\t-n\t\tBuild the filename table (default: discards filenames)" << std::endl; + std::cout << "\t-s\t\tSort files lexicographically" << std::endl; + std::cout << "\t-D/--debug\tPrint additional debug messages" << std::endl; + std::cout << "\t-i\t\tOutput a .naix header" << std::endl; } + int main(int argc, char* argv[]) { - string directory = ""; - string fileName = ""; - bool pack = false; + std::vector args = get_arguments(argc, argv); - for (int i = 1; i < argc; ++i) + if (args.empty()) { - if (!strcmp(argv[i], "-d")) - { - if (i == (argc - 1)) - { - cerr << "ERROR: No directory specified" << endl; + usage(); + return 0; + } - return 1; - } + enum Command { + None, + Pack, + Unpack, + }; + std::string subcommand = args[0]; + Command mode = Command::None; + if (subcommand == "pack") + { + mode = Command::Pack; + } + else if (subcommand == "unpack") + { + mode = Command::Unpack; + } + else if (subcommand == "help") + { + usage(); + return 0; + } + else { + usage(); + std::cerr << "ERROR: Invalid subcommand '" << subcommand << "'" << std::endl; + return 1; + } - if (!directory.empty()) { - cerr << "ERROR: Multiple directories specified" << endl; - return 1; - } - directory = argv[++i]; - } - else if (!strcmp(argv[i], "-p")) + fs::path outputPath = ""; + std::vector inputPaths; + + for(int i = 1; i < args.size(); i++) { + std::string arg = args[i]; + if (arg == "-o") { - if (i == (argc - 1)) + if (i == args.size() - 1) { - cerr << "ERROR: No NARC specified to pack to" << endl; - + std::cerr << "ERROR: No output path specified" << std::endl; return 1; } - if (!fileName.empty()) { - cerr << "ERROR: Multiple files specified" << endl; + if (!outputPath.empty()) { + std::cerr << "ERROR: Multiple output paths specified" << std::endl; return 1; } - fileName = argv[++i]; - pack = true; + outputPath = args[++i]; } - else if (!strcmp(argv[i], "-u")) + else if (arg == "-ko") + { + knarcorder_path = fs::path(args[++i]); + } + else if (arg == "-ki") + { + knarcignore_path = fs::path(args[++i]); + } + else if (arg == "-kk") + { + knarckeep_path = fs::path(args[++i]); + } + else if (arg == "-D" || arg == "--debug") { - if (i == (argc - 1)) - { - cerr << "ERROR: No NARC specified to unpack from" << endl; - - return 1; - } - - if (!fileName.empty()) { - cerr << "ERROR: Multiple files specified" << endl; - return 1; - } - fileName = argv[++i]; - } else if (!strcmp(argv[i], "-D") || !strcmp(argv[i], "--debug")) { debug = true; - } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { + } + else if (arg == "-h" || arg == "--help") + { usage(); return 0; } - else if (!strcmp(argv[i], "-n")) { + else if (arg == "-n") + { pack_no_fnt = false; } - else if (!strcmp(argv[i], "-i")) { + else if (arg == "-i") + { output_header = true; } - else { + else if (arg == "-s") + { + orderInputs = true; + } + else if (arg[0] == '-') + { usage(); - cerr << "ERROR: Unrecognized argument: " << argv[i] << endl; + std::cerr << "ERROR: Unrecognized argument: '" << arg << "'" << std::endl; return 1; } + else { + inputPaths.emplace_back(arg); + } } - if (fileName.empty()) { - cerr << "ERROR: Missing -u or -p" << endl; + if (inputPaths.empty()) { + std::cerr << "ERROR: No inputs specified" << std::endl; return 1; } - if (directory.empty()) { - cerr << "ERROR: Missing -d" << endl; + if (outputPath.empty()) { + std::cerr << "ERROR: No output specified" << std::endl; return 1; } Narc narc; - if (pack) + if (mode == Command::Pack) { - if (!narc.Pack(fileName, directory)) + if (!narc.Pack(outputPath, inputPaths)) { PrintError(narc.GetError()); return 1; } } - else + else if (mode == Command::Unpack) { - if (!narc.Unpack(fileName, directory)) + if (!fs::is_directory(outputPath)) + { + std::cerr << "ERROR: Invalid output directory '" << subcommand << "'" << std::endl; + } + if (!narc.Unpack(outputPath, inputPaths)) { PrintError(narc.GetError()); return 1; } } - - return 0; + else + { + usage(); + std::cerr << "ERROR: Invalid subcommand '" << subcommand << "'" << std::endl; + return 1; + } } diff --git a/tools/knarc/meson.build b/tools/knarc/meson.build index e92fb089ce..359b7372c6 100644 --- a/tools/knarc/meson.build +++ b/tools/knarc/meson.build @@ -6,7 +6,8 @@ endif cpp_scrs = [ 'Source.cpp', - 'Narc.cpp' + 'Narc.cpp', + 'util.cpp' ] knarc_exe = executable('knarc', diff --git a/tools/knarc/util.cpp b/tools/knarc/util.cpp new file mode 100644 index 0000000000..b4336028de --- /dev/null +++ b/tools/knarc/util.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +const std::string WHITESPACE = " \n\r\t\f\v"; + +std::string ltrim(const std::string &s) +{ + size_t start = s.find_first_not_of(WHITESPACE); + return (start == std::string::npos) ? "" : s.substr(start); +} + +std::string rtrim(const std::string &s) +{ + size_t end = s.find_last_not_of(WHITESPACE); + return (end == std::string::npos) ? "" : s.substr(0, end + 1); +} + +std::string trim(const std::string &s) { + return rtrim(ltrim(s)); +} + +/** + * @brief gets list of arguments from argv, expanding any response files found + * + * @param argc + * @param argv + * @return list of arguments + */ +std::vector get_arguments(int argc, char* argv[]) +{ + std::vector args; + for(int i = 1; i < argc; i++) { + std::string arg = argv[i]; + if (arg[0] == '@') { + // Response file + std::ifstream response_file; + response_file.open(arg.substr(1)); + std::stringstream response_text; + response_text << response_file.rdbuf(); + while (!response_text.eof()) { + std::string response_arg; + response_text >> std::quoted(response_arg); + if (!trim(response_arg).empty()) { + args.emplace_back(trim(response_arg)); + } + } + } + else + { + args.emplace_back(arg); + } + } + return args; +} diff --git a/tools/knarc/util.h b/tools/knarc/util.h new file mode 100644 index 0000000000..d688d4eea6 --- /dev/null +++ b/tools/knarc/util.h @@ -0,0 +1,4 @@ +#include +#include + +std::vector get_arguments(int argc, char* argv[]); From 7278f961dfbfcea01f315c5bc4618bd568317831 Mon Sep 17 00:00:00 2001 From: wildfire Date: Sat, 23 Sep 2023 13:56:31 +0100 Subject: [PATCH 3/6] Convert tabs to spaces --- tools/knarc/Narc.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/knarc/Narc.cpp b/tools/knarc/Narc.cpp index fbaf4ba56a..b07443a06a 100644 --- a/tools/knarc/Narc.cpp +++ b/tools/knarc/Narc.cpp @@ -39,20 +39,20 @@ std::string get_error_string(NarcError error) { switch (error) { - case NarcError::None: return "ERROR: No error???"; - case NarcError::InvalidInputFile: return "ERROR: Invalid input file"; - case NarcError::InvalidHeaderId: return "ERROR: Invalid header ID"; - case NarcError::InvalidByteOrderMark: return "ERROR: Invalid byte order mark"; - case NarcError::InvalidVersion: return "ERROR: Invalid NARC version"; - case NarcError::InvalidHeaderSize: return "ERROR: Invalid header size"; - case NarcError::InvalidChunkCount: return "ERROR: Invalid chunk count"; - case NarcError::InvalidFileAllocationTableId: return "ERROR: Invalid file allocation table ID"; - case NarcError::InvalidFileAllocationTableReserved: return "ERROR: Invalid file allocation table reserved section"; - case NarcError::InvalidFileNameTableId: return "ERROR: Invalid file name table ID"; - case NarcError::InvalidFileNameTableEntryId: return "ERROR: Invalid file name table entry ID"; - case NarcError::InvalidFileImagesId: return "ERROR: Invalid file images ID"; - case NarcError::InvalidOutputFile: return "ERROR: Invalid output file"; - default: return "ERROR: Unknown error???"; + case NarcError::None: return "ERROR: No error???"; + case NarcError::InvalidInputFile: return "ERROR: Invalid input file"; + case NarcError::InvalidHeaderId: return "ERROR: Invalid header ID"; + case NarcError::InvalidByteOrderMark: return "ERROR: Invalid byte order mark"; + case NarcError::InvalidVersion: return "ERROR: Invalid NARC version"; + case NarcError::InvalidHeaderSize: return "ERROR: Invalid header size"; + case NarcError::InvalidChunkCount: return "ERROR: Invalid chunk count"; + case NarcError::InvalidFileAllocationTableId: return "ERROR: Invalid file allocation table ID"; + case NarcError::InvalidFileAllocationTableReserved: return "ERROR: Invalid file allocation table reserved section"; + case NarcError::InvalidFileNameTableId: return "ERROR: Invalid file name table ID"; + case NarcError::InvalidFileNameTableEntryId: return "ERROR: Invalid file name table entry ID"; + case NarcError::InvalidFileImagesId: return "ERROR: Invalid file images ID"; + case NarcError::InvalidOutputFile: return "ERROR: Invalid output file"; + default: return "ERROR: Unknown error???"; } } From 810e8c87708b152a8aad456c58e49b3d215a392e Mon Sep 17 00:00:00 2001 From: wildfire Date: Mon, 25 Sep 2023 16:29:16 +0100 Subject: [PATCH 4/6] Formatting --- tools/knarc/Narc.cpp | 466 ++++++++++++++++--------------------------- 1 file changed, 176 insertions(+), 290 deletions(-) diff --git a/tools/knarc/Narc.cpp b/tools/knarc/Narc.cpp index b07443a06a..26486b9f1a 100644 --- a/tools/knarc/Narc.cpp +++ b/tools/knarc/Narc.cpp @@ -37,32 +37,29 @@ extern fs::path knarckeep_path; std::string get_error_string(NarcError error) { - switch (error) - { - case NarcError::None: return "ERROR: No error???"; - case NarcError::InvalidInputFile: return "ERROR: Invalid input file"; - case NarcError::InvalidHeaderId: return "ERROR: Invalid header ID"; - case NarcError::InvalidByteOrderMark: return "ERROR: Invalid byte order mark"; - case NarcError::InvalidVersion: return "ERROR: Invalid NARC version"; - case NarcError::InvalidHeaderSize: return "ERROR: Invalid header size"; - case NarcError::InvalidChunkCount: return "ERROR: Invalid chunk count"; - case NarcError::InvalidFileAllocationTableId: return "ERROR: Invalid file allocation table ID"; - case NarcError::InvalidFileAllocationTableReserved: return "ERROR: Invalid file allocation table reserved section"; - case NarcError::InvalidFileNameTableId: return "ERROR: Invalid file name table ID"; - case NarcError::InvalidFileNameTableEntryId: return "ERROR: Invalid file name table entry ID"; - case NarcError::InvalidFileImagesId: return "ERROR: Invalid file images ID"; - case NarcError::InvalidOutputFile: return "ERROR: Invalid output file"; - default: return "ERROR: Unknown error???"; + switch (error) { + case NarcError::None: return "ERROR: No error???"; + case NarcError::InvalidInputFile: return "ERROR: Invalid input file"; + case NarcError::InvalidHeaderId: return "ERROR: Invalid header ID"; + case NarcError::InvalidByteOrderMark: return "ERROR: Invalid byte order mark"; + case NarcError::InvalidVersion: return "ERROR: Invalid NARC version"; + case NarcError::InvalidHeaderSize: return "ERROR: Invalid header size"; + case NarcError::InvalidChunkCount: return "ERROR: Invalid chunk count"; + case NarcError::InvalidFileAllocationTableId: return "ERROR: Invalid file allocation table ID"; + case NarcError::InvalidFileAllocationTableReserved: return "ERROR: Invalid file allocation table reserved section"; + case NarcError::InvalidFileNameTableId: return "ERROR: Invalid file name table ID"; + case NarcError::InvalidFileNameTableEntryId: return "ERROR: Invalid file name table entry ID"; + case NarcError::InvalidFileImagesId: return "ERROR: Invalid file images ID"; + case NarcError::InvalidOutputFile: return "ERROR: Invalid output file"; + default: return "ERROR: Unknown error???"; } } void Narc::AlignDword(ofstream& ofs, uint8_t paddingChar) { - if ((ofs.tellp() % 4) != 0) - { - for (int i = 4 - (ofs.tellp() % 4); i-- > 0; ) - { - ofs.write(reinterpret_cast(&paddingChar), sizeof(uint8_t)); + if ((ofs.tellp() % 4) != 0) { + for (int i = 4 - (ofs.tellp() % 4); i-- > 0;) { + ofs.write(reinterpret_cast(&paddingChar), sizeof(uint8_t)); } } } @@ -85,24 +82,20 @@ bool Narc::Cleanup(ofstream& ofs, const NarcError& e) return false; } -std::vector read_knarcorder_file(fs::path file) { +std::vector read_knarcorder_file(fs::path file) +{ std::vector ordered_files; std::ifstream order_file(knarcorder_path); - if (order_file) - { - if (debug) - { + if (order_file) { + if (debug) { cerr << "DEBUG: knarcorder file exists" << endl; } // read the filenames in the order file and add the corresponding directory entries to the ordered files vector std::string filename; - while (std::getline(order_file, filename)) - { + while (std::getline(order_file, filename)) { fs::path file_path = file.parent_path() / filename; - if (fs::exists(file_path)) - { - if (debug) - { + if (fs::exists(file_path)) { + if (debug) { cerr << "DEBUG: knarcorder file: " << file_path << endl; } ordered_files.push_back(file_path); @@ -121,86 +114,65 @@ std::vector Narc::KnarcInputIterator(const std::vector& path ordered_files = read_knarcorder_file(knarcorder_path); } - for (fs::path path: paths) - { - if (fs::is_directory(path)) - { + for (fs::path path : paths) { + if (fs::is_directory(path)) { // open the order file - if (fs::exists(path / ".knarcorder")) - { + if (fs::exists(path / ".knarcorder")) { knarcorder_path = path / ".knarcorder"; std::vector paths = read_knarcorder_file(knarcorder_path); - for (fs::path path: paths) - { - if (std::find(ordered_files.begin(), ordered_files.end(), path) == ordered_files.end()) - { + for (fs::path path : paths) { + if (std::find(ordered_files.begin(), ordered_files.end(), path) == ordered_files.end()) { ordered_files.push_back(path); } } } // if recursive flag is set, search for knarcorder files in subdirectories and process them recursively - if (recursive) - { - for (auto &entry : fs::directory_iterator(path)) - { - if (entry.is_directory()) - { + if (recursive) { + for (auto& entry : fs::directory_iterator(path)) { + if (entry.is_directory()) { std::vector sub; sub.emplace_back(entry.path()); - std::vector subdirectory_files = - KnarcInputIterator(sub, true, lexSort); + std::vector subdirectory_files = KnarcInputIterator(sub, true, lexSort); ordered_files.insert( - ordered_files.end(), subdirectory_files.begin(), subdirectory_files.end()); + ordered_files.end(), subdirectory_files.begin(), subdirectory_files.end()); } } } // add the remaining files in alphabetical order - for (auto& entry : fs::directory_iterator(path)) - { - if (entry.is_regular_file() && entry.path().filename() != ".knarcorder") - { - if (std::find(ordered_files.begin(), ordered_files.end(), entry) == ordered_files.end()) - { + for (auto& entry : fs::directory_iterator(path)) { + if (entry.is_regular_file() && entry.path().filename() != ".knarcorder") { + if (std::find(ordered_files.begin(), ordered_files.end(), entry) == ordered_files.end()) { unordered_files.push_back(entry); } } } - } - else - { - if (std::find(ordered_files.begin(), ordered_files.end(), path) == ordered_files.end()) - { + } else { + if (std::find(ordered_files.begin(), ordered_files.end(), path) == ordered_files.end()) { unordered_files.push_back(path); } } } - if(lexSort) - { - std::sort(unordered_files.begin(), unordered_files.end(), - [](const fs::path& a, const fs::path& b) - { - // I fucking hate C++ - string aStr = a.filename().string(); - string bStr = b.filename().string(); + if (lexSort) { + std::sort(unordered_files.begin(), unordered_files.end(), [](const fs::path& a, const fs::path& b) { + // I fucking hate C++ + string aStr = a.filename().string(); + string bStr = b.filename().string(); - for (size_t i = 0; i < aStr.size(); ++i) - { - aStr[i] = tolower(aStr[i]); - } + for (size_t i = 0; i < aStr.size(); ++i) { + aStr[i] = tolower(aStr[i]); + } - for (size_t i = 0; i < bStr.size(); ++i) - { - bStr[i] = tolower(bStr[i]); - } - // std::transform(aStr.begin(), aStr.end(), aStr.begin(), ::tolower); - // std::transform(bStr.begin(), bStr.end(), bStr.begin(), ::tolower); + for (size_t i = 0; i < bStr.size(); ++i) { + bStr[i] = tolower(bStr[i]); + } + // std::transform(aStr.begin(), aStr.end(), aStr.begin(), ::tolower); + // std::transform(bStr.begin(), bStr.end(), bStr.begin(), ::tolower); - return aStr < bStr; - } - ); + return aStr < bStr; + }); } ordered_files.insert(ordered_files.end(), unordered_files.begin(), unordered_files.end()); @@ -211,55 +183,41 @@ vector Narc::InputIterator(const std::vector& paths, bool re { vector v; - for(fs::path path: paths) - { - if(fs::is_directory(path)) - { - for (const auto& de : fs::directory_iterator(path)) - { + for (fs::path path : paths) { + if (fs::is_directory(path)) { + for (const auto& de : fs::directory_iterator(path)) { v.push_back(de.path()); } - } - else - { + } else { v.push_back(path); } } - if(lexSort) - { - std::sort(v.begin(), v.end(), - [](const fs::path& a, const fs::path& b) - { - // I fucking hate C++ - string aStr = a.filename().string(); - string bStr = b.filename().string(); + if (lexSort) { + std::sort(v.begin(), v.end(), [](const fs::path& a, const fs::path& b) { + // I fucking hate C++ + string aStr = a.filename().string(); + string bStr = b.filename().string(); - for (size_t i = 0; i < aStr.size(); ++i) - { - aStr[i] = tolower(aStr[i]); - } + for (size_t i = 0; i < aStr.size(); ++i) { + aStr[i] = tolower(aStr[i]); + } - for (size_t i = 0; i < bStr.size(); ++i) - { - bStr[i] = tolower(bStr[i]); - } - // std::transform(aStr.begin(), aStr.end(), aStr.begin(), ::tolower); - // std::transform(bStr.begin(), bStr.end(), bStr.begin(), ::tolower); + for (size_t i = 0; i < bStr.size(); ++i) { + bStr[i] = tolower(bStr[i]); + } + // std::transform(aStr.begin(), aStr.end(), aStr.begin(), ::tolower); + // std::transform(bStr.begin(), bStr.end(), bStr.begin(), ::tolower); - return aStr < bStr; - } - ); + return aStr < bStr; + }); } - if (recursive) - { + if (recursive) { size_t vSize = v.size(); - for (fs::path path: v) - { - if (is_directory(path)) - { + for (fs::path path : v) { + if (is_directory(path)) { std::vector sub; sub.emplace_back(path); std::vector temp = InputIterator(sub, true, lexSort); @@ -277,16 +235,17 @@ NarcError Narc::GetError() const return error; } -class WildcardVector : public vector { -public: - WildcardVector(fs::path fp) { +class WildcardVector : public vector +{ + public: + WildcardVector(fs::path fp) + { fstream infile; if (!fs::exists(fp)) return; infile.open(fp, ios_base::in); string line; while (getline(infile, line)) { - if (!line.empty()) - { + if (!line.empty()) { // strip CR size_t i = 0; for (i = line.size() - 1; line[i] == '\r'; i--) @@ -297,7 +256,8 @@ class WildcardVector : public vector { } } } - bool matches(string fp) { + bool matches(string fp) + { for (string& pattern : *this) { if (fnmatch(pattern.c_str(), fp.c_str(), FNM_PERIOD) == 0) return true; @@ -317,22 +277,19 @@ bool Narc::Pack(const fs::path& outputPath, const std::vector& inputPa string stem_upper; // Pikalax 29 May 2021 // Output an includable header that enumerates the NARC contents - if (output_header) - { + if (output_header) { fs::path naixfname = outputPath; naixfname.replace_extension(".naix"); ofhs.open(naixfname); - if (!ofhs.good()) - { + if (!ofhs.good()) { ofhs.close(); return Cleanup(ofs, NarcError::InvalidOutputFile); } stem = outputPath.stem().string(); stem_upper = stem; - for (char &c : stem_upper) - { c = toupper(c); } + for (char& c : stem_upper) { c = toupper(c); } // std::transform(stem_upper.begin(), stem_upper.end(), stem_upper.begin(), ::toupper); ofhs << "/*\n" @@ -356,35 +313,27 @@ bool Narc::Pack(const fs::path& outputPath, const std::vector& inputPa WildcardVector keep_patterns(knarckeep_path); int memberNo = 0; - for (const auto& path : KnarcInputIterator(inputPaths, true, orderInputs)) - { - if (is_directory(path)) - { + for (const auto& path : KnarcInputIterator(inputPaths, true, orderInputs)) { + if (is_directory(path)) { ++directoryCounter; - } - else if (keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string())) - { + } else if (keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string())) { if (debug) { std::cerr << "DEBUG: adding file " << path << endl; } - if (output_header) - { + if (output_header) { string path_stem = path.filename().string(); std::replace(path_stem.begin(), path_stem.end(), '.', '_'); ofhs << "\tNARC_" << stem << "_" << path_stem << " = " << (memberNo++) << ",\n"; } - fatEntries.push_back(FileAllocationTableEntry - { - .Start = 0x0, - .End = 0x0 - }); + fatEntries.push_back(FileAllocationTableEntry{ + .Start = 0x0, + .End = 0x0, + }); - if (fatEntries.size() > 1) - { + if (fatEntries.size() > 1) { fatEntries.back().Start = fatEntries.rbegin()[1].End; - if ((fatEntries.rbegin()[1].End % 4) != 0) - { + if ((fatEntries.rbegin()[1].End % 4) != 0) { fatEntries.back().Start += 4 - (fatEntries.rbegin()[1].End % 4); } } @@ -392,15 +341,13 @@ bool Narc::Pack(const fs::path& outputPath, const std::vector& inputPa fatEntries.back().End = fatEntries.back().Start + static_cast(file_size(path)); } } - if (output_header) - { + if (output_header) { ofhs << "};\n\n#endif //NARC_" << stem_upper << "_NAIX_\n"; ofhs.close(); } - FileAllocationTable fat - { - .Id = 0x46415442, // BTAF + FileAllocationTable fat{ + .Id = 0x46415442, // BTAF .ChunkSize = static_cast(sizeof(FileAllocationTable) + ((uint32_t)fatEntries.size() * sizeof(FileAllocationTableEntry))), .FileCount = static_cast(fatEntries.size()), .Reserved = 0x0 @@ -411,114 +358,93 @@ bool Narc::Pack(const fs::path& outputPath, const std::vector& inputPa directoryCounter = 0; - for (const auto& path : KnarcInputIterator(inputPaths, true, orderInputs)) - { - if (!subTables.count(path.parent_path()) && (keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string()))) - { + for (const auto& path : KnarcInputIterator(inputPaths, true, orderInputs)) { + if (!subTables.count(path.parent_path()) && (keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string()))) { subTables.insert({ path.parent_path(), "" }); paths.push_back(path.parent_path()); } - if (is_directory(path)) - { + if (is_directory(path)) { ++directoryCounter; subTables[path.parent_path()] += static_cast(0x80 + path.filename().string().size()); subTables[path.parent_path()] += path.filename().string(); subTables[path.parent_path()] += (0xF000 + directoryCounter) & 0xFF; subTables[path.parent_path()] += (0xF000 + directoryCounter) >> 8; - } - else if (keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string())) - { + } else if (keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string())) { subTables[path.parent_path()] += static_cast(path.filename().string().size()); subTables[path.parent_path()] += path.filename().string(); } } - for (auto& subTable : subTables) - { + for (auto& subTable : subTables) { subTable.second += '\0'; } vector fntEntries; - if (!pack_no_fnt) - { + if (!pack_no_fnt) { fntEntries.push_back( { .Offset = static_cast((directoryCounter + 1) * sizeof(FileNameTableEntry)), .FirstFileId = 0x0, - .Utility = static_cast(directoryCounter + 1) + .Utility = static_cast(directoryCounter + 1), }); - for (uint16_t i = 0; i < directoryCounter; ++i) - { + for (uint16_t i = 0; i < directoryCounter; ++i) { fntEntries.push_back( { .Offset = static_cast(fntEntries.back().Offset + subTables[paths[i]].size()), .FirstFileId = fntEntries.back().FirstFileId, - .Utility = 0x0 + .Utility = 0x0, }); - for (size_t j = 0; j < (subTables[paths[i]].size() - 1); ++j) - { - if (static_cast(subTables[paths[i]][j]) <= 0x7F) - { + for (size_t j = 0; j < (subTables[paths[i]].size() - 1); ++j) { + if (static_cast(subTables[paths[i]][j]) <= 0x7F) { j += static_cast(subTables[paths[i]][j]); ++fntEntries.back().FirstFileId; - } - else if (static_cast(subTables[paths[i]][j]) <= 0xFF) - { + } else if (static_cast(subTables[paths[i]][j]) <= 0xFF) { j += static_cast(subTables[paths[i]][j]) - 0x80 + 0x2; } } fntEntries.back().Utility = 0xF000 + (find(paths.begin(), paths.end(), paths[i + 1].parent_path()) - paths.begin()); } - } - else - { + } else { fntEntries.push_back( { .Offset = 0x4, .FirstFileId = 0x0, - .Utility = 0x1 + .Utility = 0x1, }); } - FileNameTable fnt - { - .Id = 0x464E5442, // BTNF + FileNameTable fnt{ + .Id = 0x464E5442, // BTNF .ChunkSize = static_cast(sizeof(FileNameTable) + (fntEntries.size() * sizeof(FileNameTableEntry))) }; - if (!pack_no_fnt) - { - for (const auto& subTable : subTables) - { + if (!pack_no_fnt) { + for (const auto& subTable : subTables) { fnt.ChunkSize += subTable.second.size(); } } - if ((fnt.ChunkSize % 4) != 0) - { + if ((fnt.ChunkSize % 4) != 0) { fnt.ChunkSize += 4 - (fnt.ChunkSize % 4); } - FileImages fi - { - .Id = 0x46494D47, // GMIF + FileImages fi{ + .Id = 0x46494D47, // GMIF .ChunkSize = static_cast(sizeof(FileImages) + (fatEntries.empty() ? 0 : fatEntries.back().End)) }; - if ((fi.ChunkSize % 4) != 0) - { + if ((fi.ChunkSize % 4) != 0) { fi.ChunkSize += 4 - (fi.ChunkSize % 4); } - Header header - { - .Id = 0x4352414E, // NARC + Header header{ + .Id = 0x4352414E, // NARC .ByteOrderMark = 0xFFFE, .Version = 0x100, .FileSize = static_cast(sizeof(Header) + fat.ChunkSize + fnt.ChunkSize + fi.ChunkSize), @@ -526,49 +452,41 @@ bool Narc::Pack(const fs::path& outputPath, const std::vector& inputPa .ChunkCount = 0x3 }; - ofs.write(reinterpret_cast(&header), sizeof(Header)); - ofs.write(reinterpret_cast(&fat), sizeof(FileAllocationTable)); + ofs.write(reinterpret_cast(&header), sizeof(Header)); + ofs.write(reinterpret_cast(&fat), sizeof(FileAllocationTable)); - for (auto& entry : fatEntries) - { - ofs.write(reinterpret_cast(&entry), sizeof(FileAllocationTableEntry)); + for (auto& entry : fatEntries) { + ofs.write(reinterpret_cast(&entry), sizeof(FileAllocationTableEntry)); } - ofs.write(reinterpret_cast(&fnt), sizeof(FileNameTable)); + ofs.write(reinterpret_cast(&fnt), sizeof(FileNameTable)); - for (auto& entry : fntEntries) - { - ofs.write(reinterpret_cast(&entry), sizeof(FileNameTableEntry)); + for (auto& entry : fntEntries) { + ofs.write(reinterpret_cast(&entry), sizeof(FileNameTableEntry)); } - if (!pack_no_fnt) - { - for (const auto& path : paths) - { + if (!pack_no_fnt) { + for (const auto& path : paths) { ofs << subTables[path]; } } AlignDword(ofs, 0xFF); - ofs.write(reinterpret_cast(&fi), sizeof(FileImages)); + ofs.write(reinterpret_cast(&fi), sizeof(FileImages)); - for (const auto& path : KnarcInputIterator(inputPaths, true, orderInputs)) - { - if (is_directory(path)) - { + for (const auto& path : KnarcInputIterator(inputPaths, true, orderInputs)) { + if (is_directory(path)) { continue; } - if (!(keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string()))) - { + if (!(keep_patterns.matches(path.filename().string()) || !ignore_patterns.matches(path.filename().string()))) { continue; } ifstream ifs(path, ios::binary | ios::ate); - if (!ifs.good()) - { + if (!ifs.good()) { ifs.close(); return Cleanup(ofs, NarcError::InvalidInputFile); @@ -593,14 +511,14 @@ bool Narc::Pack(const fs::path& outputPath, const std::vector& inputPa bool Narc::Unpack(const fs::path& outputPath, const std::vector& inputPaths) { - for (fs::path path: inputPaths) { + for (fs::path path : inputPaths) { ifstream ifs(path, ios::binary); if (!ifs.good()) { return Cleanup(ifs, NarcError::InvalidInputFile); } Header header; - ifs.read(reinterpret_cast(&header), sizeof(Header)); + ifs.read(reinterpret_cast(&header), sizeof(Header)); if (header.Id != 0x4352414E) { return Cleanup(ifs, NarcError::InvalidHeaderId); } if (header.ByteOrderMark != 0xFFFE) { return Cleanup(ifs, NarcError::InvalidByteOrderMark); } @@ -609,103 +527,87 @@ bool Narc::Unpack(const fs::path& outputPath, const std::vector& input if (header.ChunkCount != 0x3) { return Cleanup(ifs, NarcError::InvalidChunkCount); } FileAllocationTable fat; - ifs.read(reinterpret_cast(&fat), sizeof(FileAllocationTable)); + ifs.read(reinterpret_cast(&fat), sizeof(FileAllocationTable)); if (fat.Id != 0x46415442) { return Cleanup(ifs, NarcError::InvalidFileAllocationTableId); } if (fat.Reserved != 0x0) { return Cleanup(ifs, NarcError::InvalidFileAllocationTableReserved); } unique_ptr fatEntries = make_unique(fat.FileCount); - for (uint16_t i = 0; i < fat.FileCount; ++i) - { - ifs.read(reinterpret_cast(&fatEntries.get()[i]), sizeof(FileAllocationTableEntry)); + for (uint16_t i = 0; i < fat.FileCount; ++i) { + ifs.read(reinterpret_cast(&fatEntries.get()[i]), sizeof(FileAllocationTableEntry)); } FileNameTable fnt; vector FileNameTableEntries; - ifs.read(reinterpret_cast(&fnt), sizeof(FileNameTable)); + ifs.read(reinterpret_cast(&fnt), sizeof(FileNameTable)); if (fnt.Id != 0x464E5442) { return Cleanup(ifs, NarcError::InvalidFileNameTableId); } vector fntEntries; - do - { + do { fntEntries.push_back(FileNameTableEntry()); - ifs.read(reinterpret_cast(&fntEntries.back().Offset), sizeof(uint32_t)); - ifs.read(reinterpret_cast(&fntEntries.back().FirstFileId), sizeof(uint16_t)); - ifs.read(reinterpret_cast(&fntEntries.back().Utility), sizeof(uint16_t)); + ifs.read(reinterpret_cast(&fntEntries.back().Offset), sizeof(uint32_t)); + ifs.read(reinterpret_cast(&fntEntries.back().FirstFileId), sizeof(uint16_t)); + ifs.read(reinterpret_cast(&fntEntries.back().Utility), sizeof(uint16_t)); } while (static_cast(ifs.tellg()) < (header.ChunkSize + fat.ChunkSize + sizeof(FileNameTable) + fntEntries[0].Offset)); unique_ptr fileNames = make_unique(0xFFFF); - for (size_t i = 0; i < fntEntries.size(); ++i) - { + for (size_t i = 0; i < fntEntries.size(); ++i) { ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + sizeof(FileNameTable) + fntEntries[i].Offset); uint16_t fileId = 0x0000; - for (uint8_t length = 0x80; length != 0x00; ifs.read(reinterpret_cast(&length), sizeof(uint8_t))) - { - if (length <= 0x7F) - { - for (uint8_t j = 0; j < length; ++j) - { + for (uint8_t length = 0x80; length != 0x00; ifs.read(reinterpret_cast(&length), sizeof(uint8_t))) { + if (length <= 0x7F) { + for (uint8_t j = 0; j < length; ++j) { uint8_t c; - ifs.read(reinterpret_cast(&c), sizeof(uint8_t)); + ifs.read(reinterpret_cast(&c), sizeof(uint8_t)); fileNames.get()[fntEntries[i].FirstFileId + fileId] += c; } ++fileId; - } - else if (length == 0x80) - { + } else if (length == 0x80) { // Reserved - } - else if (length <= 0xFF) - { + } else if (length <= 0xFF) { length -= 0x80; string directoryName; - for (uint8_t j = 0; j < length; ++j) - { + for (uint8_t j = 0; j < length; ++j) { uint8_t c; - ifs.read(reinterpret_cast(&c), sizeof(uint8_t)); + ifs.read(reinterpret_cast(&c), sizeof(uint8_t)); directoryName += c; } uint16_t directoryId; - ifs.read(reinterpret_cast(&directoryId), sizeof(uint16_t)); + ifs.read(reinterpret_cast(&directoryId), sizeof(uint16_t)); fileNames.get()[directoryId] = directoryName; - } - else - { + } else { return Cleanup(ifs, NarcError::InvalidFileNameTableEntryId); } } } - if ((ifs.tellg() % 4) != 0) - { + if ((ifs.tellg() % 4) != 0) { ifs.seekg(4 - (ifs.tellg() % 4), ios::cur); } FileImages fi; - ifs.read(reinterpret_cast(&fi), sizeof(FileImages)); + ifs.read(reinterpret_cast(&fi), sizeof(FileImages)); if (fi.Id != 0x46494D47) { return Cleanup(ifs, NarcError::InvalidFileImagesId); } fs::create_directory(outputPath); fs::current_path(outputPath); - if (fnt.ChunkSize == 0x10) - { - for (uint16_t i = 0; i < fat.FileCount; ++i) - { + if (fnt.ChunkSize == 0x10) { + for (uint16_t i = 0; i < fat.FileCount; ++i) { ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + fnt.ChunkSize + 8 + fatEntries.get()[i].Start); unique_ptr buffer = make_unique(fatEntries.get()[i].End - fatEntries.get()[i].Start); @@ -716,8 +618,7 @@ bool Narc::Unpack(const fs::path& outputPath, const std::vector& input ofstream ofs(oss.str(), ios::binary); - if (!ofs.good()) - { + if (!ofs.good()) { ofs.close(); return Cleanup(ifs, NarcError::InvalidOutputFile); @@ -726,29 +627,23 @@ bool Narc::Unpack(const fs::path& outputPath, const std::vector& input ofs.write(buffer.get(), fatEntries.get()[i].End - fatEntries.get()[i].Start); ofs.close(); } - } - else - { + } else { fs::path absolutePath = fs::absolute(fs::current_path()); - for (size_t i = 0; i < fntEntries.size(); ++i) - { + for (size_t i = 0; i < fntEntries.size(); ++i) { fs::current_path(absolutePath); stack directories; - for (uint16_t j = fntEntries[i].Utility; j > 0xF000; j = fntEntries[j - 0xF000].Utility) - { + for (uint16_t j = fntEntries[i].Utility; j > 0xF000; j = fntEntries[j - 0xF000].Utility) { directories.push(fileNames.get()[j]); } - for (; !directories.empty(); directories.pop()) - { + for (; !directories.empty(); directories.pop()) { fs::create_directory(directories.top()); fs::current_path(directories.top()); } - if (fntEntries[i].Utility >= 0xF000) - { + if (fntEntries[i].Utility >= 0xF000) { fs::create_directory(fileNames.get()[0xF000 + i]); fs::current_path(fileNames.get()[0xF000 + i]); } @@ -757,10 +652,8 @@ bool Narc::Unpack(const fs::path& outputPath, const std::vector& input uint16_t fileId = 0x0000; - for (uint8_t length = 0x80; length != 0x00; ifs.read(reinterpret_cast(&length), sizeof(uint8_t))) - { - if (length <= 0x7F) - { + for (uint8_t length = 0x80; length != 0x00; ifs.read(reinterpret_cast(&length), sizeof(uint8_t))) { + if (length <= 0x7F) { streampos savedPosition = ifs.tellg(); ifs.seekg(static_cast(header.ChunkSize) + fat.ChunkSize + fnt.ChunkSize + 8 + fatEntries.get()[fntEntries[i].FirstFileId + fileId].Start); @@ -770,8 +663,7 @@ bool Narc::Unpack(const fs::path& outputPath, const std::vector& input ofstream ofs(fileNames.get()[fntEntries[i].FirstFileId + fileId], ios::binary); - if (!ofs.good()) - { + if (!ofs.good()) { ofs.close(); return Cleanup(ifs, NarcError::InvalidOutputFile); @@ -784,17 +676,11 @@ bool Narc::Unpack(const fs::path& outputPath, const std::vector& input ifs.seekg(length, ios::cur); ++fileId; - } - else if (length == 0x80) - { + } else if (length == 0x80) { // Reserved - } - else if (length <= 0xFF) - { + } else if (length <= 0xFF) { ifs.seekg(static_cast(length) - 0x80 + 0x2, ios::cur); - } - else - { + } else { return Cleanup(ifs, NarcError::InvalidFileNameTableEntryId); } } From f48f063c854fb23e65af6e1cb407d504327e639e Mon Sep 17 00:00:00 2001 From: wildfire Date: Mon, 25 Sep 2023 16:53:32 +0100 Subject: [PATCH 5/6] Extract path comparison function --- tools/knarc/Narc.cpp | 64 ++++++++++++++++++-------------------------- 1 file changed, 26 insertions(+), 38 deletions(-) diff --git a/tools/knarc/Narc.cpp b/tools/knarc/Narc.cpp index 26486b9f1a..85fe485295 100644 --- a/tools/knarc/Narc.cpp +++ b/tools/knarc/Narc.cpp @@ -105,6 +105,24 @@ std::vector read_knarcorder_file(fs::path file) return ordered_files; } +static bool lex_sort(fs::path a, fs::path b) +{ + string aStr = a.filename().string(); + string bStr = b.filename().string(); + + for (size_t i = 0; i < aStr.size(); ++i) { + aStr[i] = tolower(aStr[i]); + } + + for (size_t i = 0; i < bStr.size(); ++i) { + bStr[i] = tolower(bStr[i]); + } + // std::transform(aStr.begin(), aStr.end(), aStr.begin(), ::tolower); + // std::transform(bStr.begin(), bStr.end(), bStr.begin(), ::tolower); + + return aStr < bStr; +} + std::vector Narc::KnarcInputIterator(const std::vector& paths, bool recursive, bool lexSort) const { std::vector ordered_files; @@ -156,23 +174,7 @@ std::vector Narc::KnarcInputIterator(const std::vector& path } if (lexSort) { - std::sort(unordered_files.begin(), unordered_files.end(), [](const fs::path& a, const fs::path& b) { - // I fucking hate C++ - string aStr = a.filename().string(); - string bStr = b.filename().string(); - - for (size_t i = 0; i < aStr.size(); ++i) { - aStr[i] = tolower(aStr[i]); - } - - for (size_t i = 0; i < bStr.size(); ++i) { - bStr[i] = tolower(bStr[i]); - } - // std::transform(aStr.begin(), aStr.end(), aStr.begin(), ::tolower); - // std::transform(bStr.begin(), bStr.end(), bStr.begin(), ::tolower); - - return aStr < bStr; - }); + std::sort(unordered_files.begin(), unordered_files.end(), lex_sort); } ordered_files.insert(ordered_files.end(), unordered_files.begin(), unordered_files.end()); @@ -194,23 +196,7 @@ vector Narc::InputIterator(const std::vector& paths, bool re } if (lexSort) { - std::sort(v.begin(), v.end(), [](const fs::path& a, const fs::path& b) { - // I fucking hate C++ - string aStr = a.filename().string(); - string bStr = b.filename().string(); - - for (size_t i = 0; i < aStr.size(); ++i) { - aStr[i] = tolower(aStr[i]); - } - - for (size_t i = 0; i < bStr.size(); ++i) { - bStr[i] = tolower(bStr[i]); - } - // std::transform(aStr.begin(), aStr.end(), aStr.begin(), ::tolower); - // std::transform(bStr.begin(), bStr.end(), bStr.begin(), ::tolower); - - return aStr < bStr; - }); + std::sort(v.begin(), v.end(), lex_sort); } if (recursive) { @@ -298,10 +284,12 @@ bool Narc::Pack(const fs::path& outputPath, const std::vector& inputPa " * DO NOT MODIFY!!!\n" " */\n" "\n" - "#ifndef NARC_" << stem_upper << "_NAIX_\n" - "#define NARC_" << stem_upper << "_NAIX_\n" - "\n" - "enum {\n"; + "#ifndef NARC_" + << stem_upper << "_NAIX_\n" + "#define NARC_" + << stem_upper << "_NAIX_\n" + "\n" + "enum {\n"; } vector fatEntries; uint16_t directoryCounter = 1; From c1a666dc484a4e63e158f5e94e62f069bc3eca81 Mon Sep 17 00:00:00 2001 From: wildfire Date: Tue, 26 Sep 2023 11:55:00 +0100 Subject: [PATCH 6/6] Fix build errors --- platinum.us/res.sha1 | 6 +++--- tools/json2bin/json2bin.py | 2 +- tools/scripts/make_pl_poke_icon.py | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/platinum.us/res.sha1 b/platinum.us/res.sha1 index 9769731f0c..8edf050a39 100644 --- a/platinum.us/res.sha1 +++ b/platinum.us/res.sha1 @@ -1,9 +1,11 @@ 42e2b71655a74d6e5bffb9ec75a25df930b20c59 res/battle/moves/pl_waza_tbl.narc +d9bf534c175c3c991e77fff985c099723499e1eb res/field/encounters/pl_enc_data.narc 683a7691d685c153e738b136b8266deefb0b4552 res/items/nuts_data.narc 70d103831556bb58ae8e602adbcce99333a22889 res/items/pl_item_data.narc +1f8689cbc763d9efedac9e6f12e940dbd361f7a9 res/pokemon/pl_personal.narc +6d861f9f35d1b267cd7b84368a1b7dc76b4e9669 res/pokemon/pl_poke_icon.narc 3614557aa04eb1ad7e5f260578de925f73da584d res/text/pl_msg.narc -1f8689cbc763d9efedac9e6f12e940dbd361f7a9 res/prebuilt/poketool/personal/pl_personal.narc 007c171966e3811ecaa5763ec959835dc67f57ba res/prebuilt/application/balloon/graphic/balloon_gra.narc 6e4f26a6a77242c7db11f6145a77d85ee7dfe12e res/prebuilt/application/bucket/ballslow_data.narc 3e420c904e49c441a22210726e7017e4ee0f607f res/prebuilt/application/custom_ball/data/cb_data.narc @@ -211,7 +213,6 @@ a2cd6f636960544440b489e827e5e16dcaa7f014 res/prebuilt/fielddata/areadata/area_bu 7eca91aaa5f7ef816f51a884e2f42a26f51f8bbd res/prebuilt/fielddata/build_model/build_model.narc f49c6992b8caf5fea13831789fe4bfb026beb967 res/prebuilt/fielddata/build_model/build_model_matshp.dat bda5c8e66cfa121c2d518d4388bd6f742746cda0 res/prebuilt/fielddata/encountdata/d_enc_data.narc -d9bf534c175c3c991e77fff985c099723499e1eb res/prebuilt/fielddata/encountdata/pl_enc_data.narc 4bcbf53d522ed962160b85af588816f7257fb1c3 res/prebuilt/fielddata/encountdata/p_enc_data.narc e484a4ea105e16977b9f39b965aaad014a4ec923 res/prebuilt/fielddata/eventdata/zone_event.narc fa044bf2e0599ed2bf42d3b632776af3b7e8452e res/prebuilt/fielddata/land_data/land_data.narc @@ -291,7 +292,6 @@ e03ff29bc200e233217ad7a8f068ec77b33e6472 res/prebuilt/particledata/particledata. ad8bf1d7e289c679e0d2c844ba1700fb2e61fedd res/prebuilt/particledata/pl_pokelist/pokelist_particle.narc dc6caed3c4b1a0b04bebfcf6627a668e37ae6f2c res/prebuilt/pokeanime/pl_poke_anm.narc b37a0c1e61ba1b2ceb905bad16476f1fb5966f18 res/prebuilt/pokeanime/poke_anm.narc -6d861f9f35d1b267cd7b84368a1b7dc76b4e9669 res/prebuilt/poketool/icongra/pl_poke_icon.narc 0622e95a5dc830735e711852032b829ead7d21e6 res/prebuilt/poketool/icongra/poke_icon.narc 7755e3a884a11b098122ca9dd656223fd4b02dd0 res/prebuilt/poketool/personal/evo.narc fbbf1287b2ac10c5212be0e4a69461507e860005 res/prebuilt/poketool/personal/growtbl.narc diff --git a/tools/json2bin/json2bin.py b/tools/json2bin/json2bin.py index 54ea2aae05..101d324e35 100644 --- a/tools/json2bin/json2bin.py +++ b/tools/json2bin/json2bin.py @@ -180,5 +180,5 @@ def json2bin(target: str, pathlib.Path(narc_packer), 'pack', '-s', '-o', output_dir / f'{narc_name}.narc', - files_output_dir, + private_dir, ]) diff --git a/tools/scripts/make_pl_poke_icon.py b/tools/scripts/make_pl_poke_icon.py index a43fe8bec6..09c3b78d91 100644 --- a/tools/scripts/make_pl_poke_icon.py +++ b/tools/scripts/make_pl_poke_icon.py @@ -56,4 +56,4 @@ '-version101' ]) -subprocess.run([args.knarc, '-d', bin_dest_dir, '-p', output_dir / 'pl_poke_icon.narc']) +subprocess.run([args.knarc, 'pack', '-s', '-o', output_dir / 'pl_poke_icon.narc', bin_dest_dir])