├── 3DS_Japan_Devil_Survivor_2_Record_Breaker.js ├── 3DS_Japan_Exstetra.js ├── 3DS_Japan_Gaist_Crusher_God.js ├── 3DS_Japan_Layton_Kyouju_vs_Gyakuten_Saiban.js ├── 3DS_Japan_Metal_Max_4_Gekkou_no_Diva.js ├── 3DS_Japan_Monster_Strike.js ├── 3DS_Japan_Puzzle_Dragons_X_Ryuu_no_Shou.js ├── 3DS_Japan_Tales_of_the_World_Reve_Unitia.js ├── 3DS_Japan_Toushin_Toshi_Girls_Gift_RPG.js ├── 3DS_USA_Shin_Megami_Tensei_Devil_Survivor_2_Record_Breaker.js ├── Android_MAGES_STEINS_GATE.js ├── HCode ├── v16032_TAISHOxALICE_Episode_1.js ├── v19841_Nora_To_Oujo_To_Noraneko_Heart_2.js └── v777_Mahoutsukai_no_Yoru.js ├── LICENSE ├── NS_01000130150FA000_MUSICUS.js ├── NS_01000200194AE000_Majestic _Majolical.js ├── NS_010003F003A34000_Pokemon_Let's_Go_Pikachu.js ├── NS_010007500F27C000_Detective_Pikachu_Returns.js ├── NS_0100086005EDC000_Naruto_Shippuden_Ultimate_Ninja_Storm_Trilogy.js ├── NS_01000AE01954A000_Unicorn_Overlord.js ├── NS_01000BB01CB8A000_Trouble_Magia_Wakeari_Shoujo_wa_Mirai_o_Kachitoru_Tame_ni_Ikoku_no_Mahou_Gakkou_e_Ryuugaku_Shimasu.js ├── NS_01000C7019E1C000_Wand_of_Fortune_R_for_Nintendo_Switch.js ├── NS_01000E200DC58000_Octopath_Traveler.js ├── NS_01000E701DAE8000_Natsuzora_no_Monologue.js ├── NS_01000EA00D2EE000_Toraware_no_Paruma_-Refrain-.js ├── NS_01000EA014150000_Final_Fantasy_1.js ├── NS_010012A017F18000_Mahoyo.js ├── NS_010014D01216E000_Rune_Factory_5.js ├── NS_01001A500AD6A000_Norn9_Norn_Nonette_LOFN.js ├── NS_01001B900C0E2000_Moujuutsukai_to_Ouji-sama_Flower_&_Snow.js ├── NS_01001BA01EBFC000_Moeyo_Otome_Doushi_Kayuu_Koigatari.js ├── NS_01001BB01E8E2000_FANTASIAN_Neo_Dimension.js ├── NS_01001C1009892000_The_World_Ends_With_You.js ├── NS_01001C400E9D8000_Persona_5_Scramble.js ├── NS_01001CC017BB2000_Aiyoku_no_Eustia.js ├── NS_01001DC01486A000_Tsukihime.js ├── NS_01001DC01486A000_Tsukihime_EN.js ├── NS_01001DD010A2E000_Jack_Jeanne.js ├── NS_01001EF017BE6000_Rune_Factory_3_Special.js ├── NS_010021300F69E000_Zettai_Kaikyu_Gakuen.js ├── NS_0100217014266000_Dragon_Quest_Treasures.js ├── NS_010021D01474E000_Kimi_wa_Yukima_ni_Koinegau.js ├── NS_010024200E00A000_Uta_no_Prince_sama_Repeat_Love.js ├── NS_010027100C79A000_Rune_Factory_4_Special.js ├── NS_010027300A660000_Shiritsu_Berubara_Gakuen_Versailles_no_Bara_Re_imagination.js ├── NS_0100273013ECA000_Summer_Pockets_REFLECTION_BLUE.js ├── NS_010027401A2A2000_Utakata_no_Uchronia.js ├── NS_010028D0148E6000_Sweet_Clown-Gozen_San-ji_no_Okashi_na_Doukeshi.js ├── NS_010029B018432000_Ghost_Trick_Phantom_Detective.js ├── NS_01002AE00F442000_FLOWERS_Les_Quatre_Saisons.js ├── NS_01002B400E9DA000_Collar_x_Malice.js ├── NS_01002BB00A662000_Nil_Admirari_no_Tenbin_Irodori_Nadeshiko.js ├── NS_01002BE0118AE000_OZMAFIA!!_vivace.js ├── NS_01002C0008E52000_Tales_of_Vesperia.js ├── NS_01002C00177AE000_Tengoku_Struggle_strayside.js ├── NS_01002DA013484000_The_Legend_of_Zelda_Skyward_Sword.js ├── NS_01002E2014158000_Final_Fantasy_3.js ├── NS_010032300C562000_LoverPretend.js ├── NS_0100325012B70000_Sugar_Style.js ├── NS_010037400DAAE000_Brothers_Conflict_Precious_Baby.js ├── NS_010037500DF38000_Gensou_Manege.js ├── NS_010039B015CB6000_Eiyuden_Chronicle_Rising.js ├── NS_01003BB01DF54000_My9Swallows_TOPSTARS_LEAGUE.js ├── NS_01003BD013E30000_Kanda_Alice_mo_Suiri_Suru.js ├── NS_01003D2017FEA000_Jyuzaengi_Engetsu_Sangokuden_1_and_2.js ├── NS_01003E601E324000_Dragon_Quest_III_Hd-2D_Remake.js ├── NS_01003F5017760000_GrimGrimoire_OnceMore.js ├── NS_01003F800CF5C000_Naruto_Shippuden_Ultimate_Ninja_Storm_4.js ├── NS_01003FE00E2F8000_Spade_no_Kuni_no_Alice_Wonderful_White_World.js ├── NS_010042300C4F6000_Nightshade.js ├── NS_010043B013C5C000_NEO_The_World_Ends_With_You.js ├── NS_010044701E9BC000_The_Hokkaido_Serial_Murder_Case_-_The_Okhotsk_Disappearance_Memories_in_Ice,_Tearful_Figurine.js ├── NS_010044800D2EC000_Toraware_no_Paruma.js ├── NS_010045C0109F2000_VARIABLE_BARRICADE.js ├── NS_010045C014650000_13_Sentinels_Aegis_Rim.js ├── NS_010046601125A000_Fuuraiki4.js ├── NS_010047A013268000_MAGES_Memories_off_6_~T-Wave~.js ├── NS_010048101D49E000_Re;quartz_Raid.js ├── NS_01004B301415A000_Final_Fantasy_4.js ├── NS_01004BD01639E000_Birushana_Senki_~Ichijuu_no_Kaze~.js ├── NS_01004D601B0AA000_Shuuen_no_Virche_EpiC_lycoris.js ├── NS_01004DF01DD2A000_Eiyuden_Chronicle_Hundred_Heroes.js ├── NS_01004E5017C54000_Dance_with_Devils.js ├── NS_010050000705E000_Dragon_Quest_Builders_2.js ├── NS_010051701A7BE000_Wand_of_Fortune_R2_FD_Kimi_ni_Sasageru_Epilogue.js ├── NS_010051D010FC2000_Yo-kai_Academy_Y_Waiwai_Gakuen.js ├── NS_0100556015CCC000_MAGES_ANONYMOUS;CODE.js ├── NS_010055D009F78000_Fire_Emblem_Three_Houses.js ├── NS_010056F00C7B4000_Bravely_Default_II.js ├── NS_010057E00AC56000_Dragon's_Dogma.js ├── NS_01005940182EC000_Summertime_Render-Another_Horizon.js ├── NS_01005A401D766000_Shinjuku_Rashoumon.js ├── NS_01005AF00E9DC000_Tokeijikake_no_Apocalypse.js ├── NS_01005B9014BE0000_Shuuen_no_Virche_ErroR_salvation.js ├── NS_01005BA00F486000_Crayon_Shin_chan_Ora_to_Hakase_no_Natsuyasumi.js ├── NS_01005CA01580E000_Persona_5_Royal_USA.js ├── NS_01005E9016BDE000_MAGES_The_Quintessential_Quintuplets_The_Movie.js ├── NS_01005F700DC56000_Piofiore_no_Banshou_-Ricordo-.js ├── NS_01005F80112B0000_Code_Realize_Shirogane_no_Kiseki.js ├── NS_010060800B7A8000_BUSTAFELLOWS.js ├── NS_010061300DF48000_Dairoku_Ayakashimori.js ├── NS_010061701DB38000_MAGES_IWAKURA_ARIA.js ├── NS_010061A01C1CE000_Unity_Despera_Drops.js ├── NS_010062B01525C000_Persona_4_Golden.js ├── NS_010064701F37A000_Jewelry_Hearts_Academia_We_will_wing_wonder_world.js ├── NS_01006530151F0000_Kamigami_no_Asobi-Unite_Edition.js ├── NS_010065301A2E0000_Star_Ocean_The_Second_Story_R.js ├── NS_01006590155AC000_Sakura_ no _Kumo.js ├── NS_01006A300BA2C000_Umineko_no_Naku_Koro_ni_Saku.js ├── NS_01006B000A666000_Cendrillon_palikA.js ├── NS_01006B7014156000_Final_Fantasy_2.js ├── NS_01006BB00C6F0000_The_Legend_of_Zelda_Link's_Awakening.js ├── NS_01006BD0095F4000_Shin_Megami_Tensei_V.js ├── NS_01006F000B056000_Final_Fantasy_9.js ├── NS_01007010157B4000_Galleria_no_Chika_Meikyuu_to_Majo_no_Ryodan.js ├── NS_010072000BD32000_World_of_Final_Fantasy.js ├── NS_010073901326C000_MAGES_Memories_off_5_Togireta_Film.js ├── NS_010074F013262000_Xenoblade_Chronicles_3.js ├── NS_010076501DAEA000_Getsuei_no _Kusari_Kyouran_Moratorium.js ├── NS_010076902126E000_DYNAMIC_CHORD_feat_rēve_parfait.js ├── NS_0100771013FA8000_Ken_ga_Kimi_for_S.js ├── NS_010078400F7B0000_MAGES_Famicom_Tantei_Club_Ushiro_ni_Tatsu_Shoujo.js ├── NS_010079200C26E000_Gensou_Kissa_Enchante.js ├── NS_010079201BD88000_Tokimeki_Memorial_Girl's_Side_2nd_Season_for_Nintendo_Switch.js ├── NS_010079C012896000_MAGES_Memories_off_Yubikiri_no_Kioku.js ├── NS_010079C017B98000_Cupid_Parasite_Sweet_&_Spicy_Darling.js ├── NS_01007A901E728000_Hakkenden.js ├── NS_01007AD01CB42000_Mistonia_no_Kibou.js ├── NS_01007B601C608000_Crayon_Shin_chan_Shiro_of_Coal_Town.js ├── NS_01007F000EB36000_Doukoku_Soshite.js ├── NS_01007FD00DB20000_Katakoi_Contrast.js ├── NS_010080C01AA22000_Tokyo_Xanadu_eX+.js ├── NS_010086C00AF7C000_Yo-kai_Watch_4++.js ├── NS_0100874017BE2000_Unity_BUSTAFELLOWS_season2.js ├── NS_010088A01A774000_Wand_of_Fortune_R2_~Jikuu_ni_Shizumu_Mokushiroku~.js ├── NS_010088B01A8FC000_Radiant_Tale_Fanfare.js ├── NS_01008A001C79A000_Kurenai_no_Homura_Sanada_Ninpou_Chou.js ├── NS_01008A3016162000_Etrian_Odyssey_I.js ├── NS_01008A401FEB6000_Mystery_no_Arukikata.js ├── NS_01008BE016CE2000_Ikemen_Sengoku_Toki_o_Kakeru_Koi.js ├── NS_01008C0016544000_Sea_of_Stars.js ├── NS_01008C100C572000_CLOCK_ZERO_Shuuen_no_Ichibyou_Devote.js ├── NS_01008DE00C022000_Hanayaka_Nari,_Waga_Ichizoku_Modern_Nostalgie.js ├── NS_010091C01BD8A000_Tokimeki_Memorial_Girl's_Side_3rd_Story_for_Nintendo_Switch.js ├── NS_0100925014864000_Radiant_Tale.js ├── NS_0100936018EB4000_Story_of_Seasons_a_Wonderful_Life.js ├── NS_010093800DB1C000_Jakou_no_Lyla_~Trap_of_MUSK~.js ├── NS_010094601D910000_5_Fungo_ni_Igai_na_Ketsumatsu.js ├── NS_0100957016B90000_MAGES_CHAOS;HEAD_NOAH.js ├── NS_010095E01581C000_even_if_TEMPEST_Yoiyami_ni_Kaku_Katariki_Majo.js ├── NS_010096000CA38000_Taishou_x_Alice_all_in_one.js ├── NS_0100978013276000_MAGES_Memories_Off.js ├── NS_0100982015606000_HamefuraPirates.js ├── NS_01009B50139A8000_DORAEMON_STORY_OF_SEASONS_Friends_of_the_Great_Kingdom.js ├── NS_01009CB01BD36000_Yohane_the_Parhelion_BLAZE_in_the_DEEPBLUE.js ├── NS_01009E30120F4000_Piofiore_no_Banshou_-Episodio1926-.js ├── NS_0100A1200CA3C000_Chou_no_Doku_Hana_no_Kusari_Taishou_Tsuya_Koi_Ibun.js ├── NS_0100A1E00BFEA000_AMNESIA_for_Nintendo_Switch.js ├── NS_0100A250191E8000_Money_Parasite_Usotsuki_na_Onna.js ├── NS_0100A3501946E000_Octopath_Traveler_2.js ├── NS_0100A3A00CC7E000_CLANNAD.js ├── NS_0100A3A00CC7E000_CLANNAD_JP.js ├── NS_0100A460141B8000_Shiro_to_Kuro_no_Alice.js ├── NS_0100A62019078000_Temirana_Koku_no_Tsuiteru_Hime_to_Tsuitenai_Kishidan.js ├── NS_0100A6301214E000_Fire_Emblem_Engage.js ├── NS_0100A77018EA0000_Dragon_Quest_Monsters_The_Dark_Prince.js ├── NS_0100A8401A0A8000_Natsumon-20th_Century_Summer_Vacation.js ├── NS_0100A89019EEC000_Sakura_Moyu_as_the_Night's_Reincarnation.js ├── NS_0100A9501759E000_MAGES_Famicom_Tantei_Club_Emio.js ├── NS_0100AA001415E000_Final_Fantasy_6.js ├── NS_0100AA201415C000_Final_Fantasy_5.js ├── NS_0100AAF020664000_Apathy_Danshikou_de_Atta_Kowai_Hanashi.js ├── NS_0100AB100E2FA000_Spade_no_Kuni_no_Alice_Wonderful_Black_World.js ├── NS_0100AC20128AC000_Chrono_Cross.js ├── NS_0100ADC014DA0000_AIR.js ├── NS_0100AFA01750C000_Shinigami_to_Shoujo.js ├── NS_0100B0100E26C000_Tokimeki_Memorial_Girl's_Side_4th_Heart.js ├── NS_0100B0601852A000_AKA.js ├── NS_0100B0C016164000_Etrian_Odyssey_II.js ├── NS_0100B1F0123B6000_Taishou_x_Alice_HEADS_&_TAILS.js ├── NS_0100B4500F7AE000_MAGES_Famicom_Tantei_Club_Kieta_Koukeisha.js ├── NS_0100B4A01326E000_MAGES_Memories_off_~Sorekara~.js ├── NS_0100B5500CA0C000_Hanayaka_Nari,_Waga_Ichizoku_Gentou_Nostalgie.js ├── NS_0100B5700CDFC000_Amnesia_Later_x_Crowd_V.js ├── NS_0100B5800C0E4000_Reine_des_Fleurs.js ├── NS_0100B5801D7CE000_Kannagi_no_Mori_Satsukiame_Tsuzuri.js ├── NS_0100B6501FE4C000_Kenka_Banchou_Otome_Double_Pack.js ├── NS_0100B6900A668000_Code_Realize_Saikou_no_Hanataba.js ├── NS_0100B880154FC000_Persona_5_Royal.js ├── NS_0100B8E016F76000_NieR_Automata.js ├── NS_0100BBA00B23E000_Yoshiwara_Higanbana_Kuon_no_Chigiri.js ├── NS_0100BC0018138000_Super_Mario_RPG.js ├── NS_0100BD4014D8C000_AI_The_Somnium_Files _nirvanA_Initiative.js ├── NS_0100BD700E648000_Diabolik Lovers Grand Edition.js ├── NS_0100BD7015E6C000_Kiss_Bell.js ├── NS_0100BDD01AAE4000_9_R.I.P.js ├── NS_0100BE40138B8000_Fata_morgana_no_Yakata.js ├── NS_0100C0000CEEA000_Yo-kai_Watch_1.js ├── NS_0100C1E0102B8000_Shinobi, Koi Utsutsu.js ├── NS_0100C2901153C000_Yoru_Tomosu.js ├── NS_0100C29017106000_LIVE_A_LIVE.js ├── NS_0100C30020F70000_BYAKKO_Shijin_Butai_Enrenki.js ├── NS_0100C310110B4000_Piofiore_no_Banshou_-Ricordo-_CN.js ├── NS_0100C4E013E5E000_Ni_no_Kuni_II_Revenant_Kingdom.js ├── NS_0100C7400CFB4000_AI_The_Somnium_Files.js ├── NS_0100CB700D438000_Monster_Hunter_Stories_2.js ├── NS_0100CB9018F5A000_Another_Code_Recollection.js ├── NS_0100CBA014014000_Tantei_Bokumetsu.js ├── NS_0100CC401A16C000_Ys_X_Nordics.js ├── NS_0100CC80140F8000_Triangle_Strategy.js ├── NS_0100CEF0152DE000_Charade_Maniacs.js ├── NS_0100CF400F7CE000_Harukanaru_Toki_no_Naka_de_7.js ├── NS_0100D11018A7E000_Aquarium.js ├── NS_0100D12014FC2000_Yuru Camp_Have_a_nice_day.js ├── NS_0100D31013274000_MAGES_Memories_Off_2nd.js ├── NS_0100D32015A52000_Etrian_Odyssey_III.js ├── NS_0100D4601FD60000_Soukoku_no_Kusabi_Hiiro_no_Kakera_Tamayorihime_Kitan.js ├── NS_0100D57014692000_Hakuouki_Reimeiroku.js ├── NS_0100D7800E9E0000_Trials_of_Mana.js ├── NS_0100D7E01E998000_Fuyuzono_Sacrifice.js ├── NS_0100D9500A0F6000_ClosedNightmare.js ├── NS_0100D9A01BD86000_Tokimeki_Memorial_Girl's_Side_1st_Love_for_Nintendo_Switch.js ├── NS_0100DA101D9AA000_Utsusemi_no_Meguri.js ├── NS_0100DA201E0DA000_Akuyaku_Reijou_wa_Ringoku_no_Outaishi_ni_Dekiai_Sareru.js ├── NS_0100DB300B996000_BuddyMissionBOND.js ├── NS_0100DCD01525A000_Persona_3_Portable.js ├── NS_0100DE200C0DA000_Yunohana Spring! ~Mellow Times~.js ├── NS_0100DE701446A000_Akiba's_Trip_Hellbound_&_Debriefed.js ├── NS_0100DEF01D0C2000_even_if_TEMPEST_Tsuranaru_Toki_no_Akatsuki.js ├── NS_0100DEF01D0C6000_Hanaemu_Kare_to_&_bloom.js ├── NS_0100E0D0154BC000_MAGES_Yahari.Game.demo.Ore.no.Seishun.Love.Come.wa.Machigatteiru.js ├── NS_0100E190117D6000_Angelique.Luminarise.js ├── NS_0100E1E00E2AE000_Hakuouki_Shinkai_Tsukikage_no_Shou.js ├── NS_0100E390145C8000_Koroshiya_to_Strawberry_Plus.js ├── NS_0100E4000F616000_Himehibi_Another_Princess_Days_White_or_Black.js ├── NS_0100E5200D1A2000_Kaeru_Batake_DE_Tsukamaete.js ├── NS_0100E8E016D82000_KLAP_Kind_Love_and_Punish.js ├── NS_0100E94014792000_MAGES_SINceMemories.js ├── NS_0100E9801CAC2000_OVER_REQUIEMZ.js ├── NS_0100EA001A626000_Matsurika_no_Kei_Tenmeiin_Iden.js ├── NS_0100EA100DF92000_Meiji_Katsugeki_Haikara_Ryuuseigumi.js ├── NS_0100EC001DE7E000_Hiiro_no_Kakera_Tamayorihime_Kitan_Omoiiro_no_Kioku.js ├── NS_0100EDD018032000_Harvestella.js ├── NS_0100EF00134F4000_Dragon_Ball_Z_Kakarot.js ├── NS_0100EFE0159C6000_Kaeru_Batake_DE_ Tsukamaete_Natsu_Chigira_Sansen.js ├── NS_0100F3400332C000_Xenoblade_Chronicles_2.js ├── NS_0100F4401940A000_Master_Detective_Archives_Rain_Code.js ├── NS_0100F4800F872000_Prison_Princess.js ├── NS_0100F6A00A684000_Higurashi_no_Naku-Koro_ni_Hou.js ├── NS_0100F7401AA74000_Getsuei_no_Kusari_Sakuran_Paranoia.js ├── NS_0100F7E00DFC8000_Cupid_Parasite.js ├── NS_0100F8A017BAA000_Sen _no _Hatou_Tsukisome _no _Kouki.js ├── NS_0100F8D0129F4000_Himehibi_Princess_Days.js ├── NS_0100F9D00C186000_Olympia_Soiree.js ├── NS_0100FA001E160000_7scarlet.js ├── NS_0100FA10185B0000_SympathyKiss.js ├── NS_0100FB301E70A000_Honey_Vibes.js ├── NS_0100FB7019ADE000_Kanon.js ├── NS_0100FC2019346000_Princess_Arthur.js ├── NS_0100FDB00AA80000_Layton’s_Mystery_Journey.js ├── NS_0100FF500E34A000_Xenoblade_Chronicles.js ├── NS_0100FFA013272000_MAGES_Omoide_ni_Kawaru_Kimi_~Memories_Off~.js ├── NS__Ryujinx.js ├── PC98_Leaf_Kizuato.js ├── PC98_Leaf_Shizuku.js ├── PC_AIO.js ├── PC_Cursed_Futanari_Ring.js ├── PC_DMM_MAGES_SINceMemories.js ├── PC_Flash_Rondo_Duo.js ├── PC_HCode.js ├── PC_InnocentGrey_FLOWERS_Le_volume_sur_automne.js ├── PC_InnocentGrey_FLOWERS_Le_volume_sur_ete.js ├── PC_InnocentGrey_FLOWERS_Le_volume_sur_hiver.js ├── PC_InnocentGrey_FLOWERS_Le_volume_sur_printemps.js ├── PC_JavaScript_Tyrano+.js ├── PC_Leaf_Kizuato.js ├── PC_Leaf_KizuatoRenewal.js ├── PC_Leaf_Shizuku.js ├── PC_Malie_Dies_Irae_Acta_est_Fabula.js ├── PC_Malie_Dies_Irae_Interview_with_Kaziklu_Bey.js ├── PC_Steam Superdimension_Neptune_VS_Sega_Hard_Girls.js ├── PC_Steam_ASTLIBRA_Revision.js ├── PC_Steam_Air.js ├── PC_Steam_Ao_no_Kiseki.js ├── PC_Steam_Atelier_Sophie_The_Alchemist_of_the_Mysterious_Book_DX.js ├── PC_Steam_Chrono_Trigger.js ├── PC_Steam_Danganronpa_2_Goodbye_Despair.js ├── PC_Steam_Danganronpa_Another_Episode_Ultra_Despair_Girls.js ├── PC_Steam_Danganronpa_Trigger_Happy_Havoc.js ├── PC_Steam_Danganronpa_V3_Killing_Harmony.js ├── PC_Steam_Death_end_reQuest.js ├── PC_Steam_Death_end_reQuest_2.js ├── PC_Steam_ENDER_LILIES_Quietus_of_the_Knights.js ├── PC_Steam_FINAL_FANTASY_VIII_Remastered.js ├── PC_Steam_Granblue_Fantasy_Relink.js ├── PC_Steam_Hajimari_no_Kiseki.js ├── PC_Steam_Hyperdimension_Neptunia_ReBirth1.js ├── PC_Steam_Hyperdimension_Neptunia_ReBirth2_Sisters_Generation.js ├── PC_Steam_Hyperdimension_Neptunia_ReBirth3_V_Generation.js ├── PC_Steam_KiriKiriZ_9-nine.js ├── PC_Steam_KiriKiriZ_Marco_&_The_Galaxy_Dragon.js ├── PC_Steam_KiriKiriZ_Tsuyuchiru_Letter_Umi_to_Shiori_ni_Amaoto_o.js ├── PC_Steam_LUNAR_1_REMASTERED.js ├── PC_Steam_Like.a.dragon.Gaiden.js ├── PC_Steam_Like.a.dragon.Infinite.Wealth.js ├── PC_Steam_Little_Busters!_English_Edition.js ├── PC_Steam_MAGES_CHAOS;HEAD_NOAH.js ├── PC_Steam_MAGES_Chaos;Child.js ├── PC_Steam_MAGES_Memories_Off_-Innocent_Fille-.js ├── PC_Steam_MAGES_Memories_Off_-Innocent_Fille-_for_Dearest.js ├── PC_Steam_MAGES_Memories_Off_Historia.js ├── PC_Steam_MAGES_Memories_Off_Yubikiri_No_Kioku.js ├── PC_Steam_MAGES_Robotics;Notes-DaSH.js ├── PC_Steam_MAGES_Robotics;Notes-Elite.js ├── PC_Steam_MAGES_Steins;Gate-0.js ├── PC_Steam_MAGES_Steins;Gate-Elite.js ├── PC_Steam_MAGES_Steins;Gate-Linear_Bounded_Phenogram.js ├── PC_Steam_MAGES_Steins;Gate-My_Darlings_Embrace.js ├── PC_Steam_MAGES_Steins;Gate.js ├── PC_Steam_MAGES_Steins;Gate_Korean_Patch.js ├── PC_Steam_MAGES_Steins;Gate_Traditional_Chinese.js ├── PC_Steam_MAGES_YUNO.js ├── PC_Steam_Megadimension_Neptunia_VIIR.js ├── PC_Steam_Metaphor_ReFantazio.js ├── PC_Steam_Muv_Luv.js ├── PC_Steam_Muv_Luv_Alternative.js ├── PC_Steam_Ni.No.Kuni.Wrath.Of.The.White.Witch.Remastered.js ├── PC_Steam_Nier_Replicant.js ├── PC_Steam_Persona_3_Portable.js ├── PC_Steam_Persona_3_Reload.js ├── PC_Steam_Persona_4_Golden.js ├── PC_Steam_Persona_5_Royal.js ├── PC_Steam_SENRAN_KAGURA_Bon_Appetit!_Full_Course.js ├── PC_Steam_SENRAN_KAGURA_Burst_ReNewal.js ├── PC_Steam_SENRAN_KAGURA_ESTIVAL_VERSUS.js ├── PC_Steam_SENRAN_KAGURA_Peach_Beach_Splash.js ├── PC_Steam_SENRAN_KAGURA_Reflexions.js ├── PC_Steam_SENRAN_KAGURA_SHINOVI_VERSUS.js ├── PC_Steam_The_Hundred_Line_Last_Defense_Academy.js ├── PC_Steam_Unity_AI_The_Somnium_Files.js ├── PC_Steam_Unity_AI_The_Somnium_Files_-_nirvanA_Initiative.js ├── PC_Steam_Unity_AKAIITO.js ├── PC_Steam_Unity_AOISHIRO.js ├── PC_Steam_Unity_Aokana_Four_Rhythms_Across_the_Blue.js ├── PC_Steam_Unity_As.Dusk.Falls.js ├── PC_Steam_Unity_Bunny_Garden.js ├── PC_Steam_Unity_Children.of.Silentown.js ├── PC_Steam_Unity_Depersonalization.js ├── PC_Steam_Unity_Digimon_Survive.js ├── PC_Steam_Unity_Disco.Elysium.js ├── PC_Steam_Unity_Doraemon_Story_of_Seasons.js ├── PC_Steam_Unity_Hayaski_no_Kuroyuri.js ├── PC_Steam_Unity_Higurashi_Hou.js ├── PC_Steam_Unity_Hira_Hira_Hihiru.js ├── PC_Steam_Unity_Inverted_Angel.js ├── PC_Steam_Unity_Ken_ga_Kimi.js ├── PC_Steam_Unity_Ken_ga_Kimi_Momoyo_Tsuzuri.js ├── PC_Steam_Unity_Livestream_Escape_from_Hotel_Izanami.js ├── PC_Steam_Unity_Moonless_Moon.js ├── PC_Steam_Unity_Neptunia_Sisters_VS_Sisters.js ├── PC_Steam_Unity_Night_in_the_Woods.js ├── PC_Steam_Unity_Nobody.The.Turnaround.js ├── PC_Steam_Unity_Paranormasight.js ├── PC_Steam_Unity_Pathfinder_Kingmaker.js ├── PC_Steam_Unity_Pathfinder_Wrath.of.the.Righteous.js ├── PC_Steam_Unity_Pentiment.js ├── PC_Steam_Unity_Persona_5_Tactica.js ├── PC_Steam_Unity_Phoenix_Wright_Ace_Attorney_Trilogy.js ├── PC_Steam_Unity_Prison_Princess.js ├── PC_Steam_Unity_Raging-Loop.js ├── PC_Steam_Unity_SeaBed.js ├── PC_Steam_Unity_Shin.Megami.Tensei.III.Nocturne.HD.Remaster.js ├── PC_Steam_Unity_Shin.chan.Summer.Vacation.js ├── PC_Steam_Unity_Soul.Hackers.2.js ├── PC_Steam_Unity_Spiritfarer.js ├── PC_Steam_Unity_Urban_Myth_Dissolution_Center.js ├── PC_Steam_Unity_Uso_kara_Hajimaru_Koi_no_Natsu.js ├── PC_Steam_Unreal_Dragon.Quest.XI.S_Echoes.of.an.Elusive.Age.js ├── PC_Steam_Unreal_Hogwarts.Legacy.js ├── PC_Steam_Unreal_Like.a.Dragon.Ishin!.js ├── PC_Steam_Unreal_Tales.of.Arise.js ├── PC_Steam_WITCH_ON_THE_HOLY_NIGHT.js ├── PC_Steam_Wo.Long.Fallen.Dynasty.js ├── PC_Steam_Wushu.Chronicles.js ├── PC_Steam_Yakuza.0.js ├── PC_Steam_Yakuza.5.js ├── PC_Steam_Yakuza.Kiwami.js ├── PC_Steam_Zero_Escape_The_Nonary_Games_999.js ├── PC_Steam_Zero_Escape_The_Nonary_Games_Virtue's_Last_Reward.js ├── PC_Steam_Zero_Escape_Zero_Time_Dilemma.js ├── PC_Steam_Zero_no_Kiseki.js ├── PC_Unity_Kyokkou_no_Marriage.js ├── PC_Unity_Mononokei_Kanojo.js ├── PS2_SLPM65732_Akai_Ito.js ├── PS2_SLPM65914_NANA.js ├── PS2_SLPM66045_My_Merry_May_with_be.js ├── PS2_SLPM66302_CLANNAD.js ├── PS2_SLPM66892_Myself_Yourself.js ├── PS2_SLPS25332_SNOW.js ├── PS2_SLPS25547_Ichigo_Marshmallow.js ├── PS2_SLPS25677_BLOOD+_One_Night_Kiss.js ├── PS3_BLJM60347_Dunamis15.js ├── PS3_BLJM61131_'&'-Sora no Mukou de Sakimasu you ni-.js ├── PSP_NPJH50127_Tokimeki-Memorial-4.js ├── PSP_NPJH50505_Fate-EXTRA-CCC.js ├── PSP_NPJH50619_Sol-Trigger.js ├── PSP_NPJH50909_Kamigami-no-Asobi-InFinite.js ├── PSP_ULJM05054_Kiniro_no_Corda.js ├── PSP_ULJM05428_Kiniro_no_Corda_2f.js ├── PSP_ULJM05447_Will_O'_Wisp_Portable.js ├── PSP_ULJM05701_Hanakisou.js ├── PSP_ULJM05795_Togainu_no_Chi.js ├── PSP_ULJM05802_Bara_no_Ki_ni_Bara_no_Hanasaku.js ├── PSP_ULJM05878_Sekai-de-Ichiban-Dame-na-Koi.js ├── PSP_ULJM05943_Gekka_Ryouran_Romance.js ├── PSP_ULJM06036 _Princess-Evangile-Portable.js ├── PSP_ULJM06119_Dunamis15.js ├── PSP_ULJM06129_Toki_no_Kizuna_Sekigahara_Kitan.js ├── PSP_ULJM06291_Arcana_Famiglia_2.js ├── PSP_ULJM06301_Toki_no_Kizuna_Hanayuitsuzuri.js ├── PSP_ULJM06302-3_Seishun_Hajimemashita.js ├── PSP_ULJM06393_Omerta_Chinmoku_no_Okite_The_Legacy.js ├── PSP_ULJM6064_Armen_Noir_Portable.js ├── PSP_ULJS00339_Amagami.js ├── PSP_ULJS00403_Shinigami_to_Shoujo.js ├── PSVita_PCSG00172_Kajiri_Kamui_Kagura_Akebono_no_Hikari.js ├── PSVita_PCSG00216_Rui_wa_Tomo_o_Yobu.js ├── PSVita_PCSG00291_Amagami.js ├── PSVita_PCSG00389_Binary_Star.js ├── PSVita_PCSG00401_Sora_Yume.js ├── PSVita_PCSG00405_Reine_des_Fleurs.js ├── PSVita_PCSG00410_Nekketsu_Inou_Bukatsu-tan_Trigger_Kiss.js ├── PSVita_PCSG00420_DRAMAtical_Murder_recode.js ├── PSVita_PCSG00448_MARGINAL_#4_IDOL_OF_SUPERNOVA.js ├── PSVita_PCSG00468_Kokuchou_no_Psychedelica.js ├── PSVita_PCSG00477_Hyakka_Yakou.js ├── PSVita_PCSG00488_Sora_no_Kiseki_FC_Evolution.js ├── PSVita_PCSG00489_Sora_no_Kiseki_SC_Evolution.js ├── PSVita_PCSG00490_Sora_no_Kiseki_the_3rd_Evolution.js ├── PSVita_PCSG00510_Starry_Sky_Spring_Stories.js ├── PSVita_PCSG00611_Zettai_Meikyuu_Himitsu_no_Oyayubi_Hime.js ├── PSVita_PCSG00648_Tsuki_ni_Yorisou_Otome_no_Sahou.js ├── PSVita_PCSG00667_LoveQuiz_Koi_Suru_Otome_no_Final_Answer.js ├── PSVita_PCSG00696_Angelique_Retour.js ├── PSVita_PCSG00706_Moshi_Kono_Sekai_ni_Kami_sama_ga_Iru_to_suru_Naraba.js ├── PSVita_PCSG00745_Scared_Rider_Xechs_Rev.js ├── PSVita_PCSG00751_Arcana_famiglia_-La_storia_della_Arcana_Famiglia-.js ├── PSVita_PCSG00776_Muv_Luv.js ├── PSVita_PCSG00787_Kyoukai_no_Shirayuki.js ├── PSVita_PCSG00790_Wand_of_Fortune_R.js ├── PSVita_PCSG00808_Yuukyuu_no_Tierblade_Lost_Chronicle.js ├── PSVita_PCSG00812_Haitaka_no_Psychedelica.js ├── PSVita_PCSG00815_PsychicEmotion6.js ├── PSVita_PCSG00839_Kenka_Banchou_Otome.js ├── PSVita_PCSG00852_Magic_Kyun_Renaissance.js ├── PSVita_PCSG00855_Hana_Oboro_Sengoku-den_Ranki.js ├── PSVita_PCSG00903_New_Game!_The_Challenge_Stage!.js ├── PSVita_PCSG00911_Re_Birthday_Song_Koi_o_Utau_Shinigami.js ├── PSVita_PCSG00912_Un_Birthday_Song_Ai_o_Utau_Shinigami.js ├── PSVita_PCSG00916_Starry_Sky_Summer_Stories.js ├── PSVita_PCSG00917_Starry_Sky_Autumn_Stories.js ├── PSVita_PCSG00918_Starry_Sky_Winter_Stories.js ├── PSVita_PCSG00935_BLACK_WOLVES_SAGA_Weiβ_und_Schwarz.js ├── PSVita_PCSG00938_Wand_of_Fortune_R2_Jikuu_ni_Shizumu_Mokushiroku.js ├── PSVita_PCSG01008_MARGINAL_#4_ROAD_TO_GALAXY.js ├── PSVita_PCSG01019_Tsumikui _Sen_no_Noroi_Sen_no_Inori.js ├── PSVita_PCSG01023_Tsuihou_Senkyo.js ├── PSVita_PCSG01036_Hiiro_no_Kakera_Omoi_Iro_no_Kioku.js ├── PSVita_PCSG01046_Usotsuki_Shangri_La.js ├── PSVita_PCSG01066_Chouchou_Jiken_Lovesodic.js ├── PSVita_PCSG01075_Yuukyuu_no_Tierblade_Fragments_of_Memory.js ├── PSVita_PCSG01110_Code_Realize_Shirogane_no_Kiseki.js ├── PSVita_PCSG01180_Tengai_ni_Mau_Iki_na_Hana.js ├── PSVita_PCSG01194_Sanzen_Sekai_Yuugi_Re_Multi_Universe_Myself.js ├── PSVita_PCSG01268_Kannagi_no_Mori_Satsukiame_Tsuzuri.js ├── PSVita_PCSG01282_Shinigami_to_Shoujo.js ├── README.md ├── _ExecutionWatch.js ├── charsets ├── tblLeafKizuatoJP.txt ├── tblLeafShizukuJP.txt └── tblNECInterChannelJP.txt ├── libCitra.js ├── libDOSBoxX.js ├── libFlash.js ├── libHelperEncoding.js ├── libLoader.js ├── libLoader.js.qjs ├── libLoaderAgent.js ├── libLoaderSelf.js ├── libMono.js ├── libOverlay.html ├── libOverlay.js ├── libPCAtlus.js ├── libPCKiriKiriZ.js ├── libPCMAGES.js ├── libPCSX2.js ├── libPPSSPP.js ├── libRPCS3.js ├── libRyujinx.cjs ├── libTranslate.js ├── libTranslateDeepL.js ├── libTranslateGoogle.js ├── libTranslateMicrosoft.js ├── libTranslateVietPhrase.js ├── libUI.js ├── libUnrealEngine.js ├── libVita3k.js ├── libWebSocket.js ├── libYuzu.js └── translate.html /3DS_Japan_Devil_Survivor_2_Record_Breaker.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [00040000000C3A00] Devil Survivor 2 Record Breaker (Japan) 3 | // @version 1.1 4 | // @author [Gilfar] 5 | // @description Citra 6 | // ==/UserScript== 7 | const { setHook } = require("./libCitra.js"); 8 | 9 | const mainHandler = trans.send(handler.bind_(null, 0), '200+'); // join 200ms 10 | 11 | setHook({ 12 | 0x1a2d2c: mainHandler, // dialouge only (whole line) 13 | }); 14 | 15 | function handler(regs, index) { 16 | const address = regs[index].value; 17 | 18 | console.log('onEnter'); 19 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 20 | 21 | /* processString */ 22 | let s = address.readShiftJisString(); 23 | 24 | // filters 25 | s = s 26 | //.replace(/(\)+/g, ' ') // single line 27 | .replace(/(\uFFFD\x40)+/g, '!?') // !? gets mangled 28 | .replace(/(\)+/g, '\r\n') // page break 29 | .replace(/(<.+?>)+/g, ' ') // htmlTag 30 | ; 31 | 32 | return s; 33 | } -------------------------------------------------------------------------------- /3DS_Japan_Exstetra.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [00040000000F4100] Exstetra (Japan) 3 | // @version 0.1 4 | // @author [Gilfar] 5 | // @description Citra 6 | // ==/UserScript== 7 | const { setHook } = require("./libCitra.js"); 8 | 9 | const mainHandler = trans.send(handler.bind_(null, 1), '200+'); // join 200ms 10 | 11 | setHook({ 12 | 0x23a8c4: mainHandler, // dialouge 13 | }); 14 | 15 | function handler(regs, index) { 16 | const address = regs[index].value; 17 | 18 | console.log('onEnter'); 19 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 20 | 21 | /* processString */ 22 | let s = address.readUtf16String(); 23 | 24 | // filters 25 | s = s 26 | .replace(/(#C[0-9])+/g, '') // control codes 27 | ; 28 | 29 | return s; 30 | } -------------------------------------------------------------------------------- /3DS_Japan_Layton_Kyouju_vs_Gyakuten_Saiban.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0004000000078B00] Layton Kyouju vs Gyakuten Saiban (Japan) 3 | // @version 0.1 4 | // @author [sasuke yo] 5 | // @description Citra 6 | // ==/UserScript== 7 | const { setHook } = require("./libCitra.js"); 8 | 9 | const mainHandler = trans.send(handler.bind_(null, 6), '200+'); // join 200ms 10 | 11 | setHook({ 12 | 0x1c6a38: mainHandler, 13 | }); 14 | 15 | function handler(regs, index) { 16 | const address = regs[index].value; 17 | 18 | // console.log('onEnter'); 19 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 20 | 21 | /* processString */ 22 | let s = address.readShiftJisString(); 23 | 24 | // filters 25 | s = s 26 | .replace(/<[^>]+>/g, '') // control codes 27 | .replace(/\[([^\/\]]+)\/[^\]]+\]/g, '$1') // removes furigana 28 | .replace(/>/g, '') // removes '>' 29 | ; 30 | 31 | return s; 32 | } -------------------------------------------------------------------------------- /3DS_Japan_Metal_Max_4_Gekkou_no_Diva.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [00040000000AFD00] Metal Max 4 - Gekkou no Diva (Japan) 3 | // @version 1.1 4 | // @author [Gilfar] 5 | // @description Citra 6 | // ==/UserScript== 7 | const { setHook } = require("./libCitra.js"); 8 | 9 | const mainHandler = trans.send(handler.bind_(null, 10), '200+'); // join 200ms 10 | const optionHandler = trans.send(handler.bind_(null, 0), '200+'); // join 200ms 11 | 12 | setHook({ 13 | 0x248c30: mainHandler, // text 14 | 0x2483c0: optionHandler, // dialouge options 15 | }); 16 | 17 | function handler(regs, index) { 18 | const address = regs[index].value; 19 | 20 | //console.log('onEnter'); 21 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 22 | 23 | /* processString */ 24 | let s = address.readUtf8String(); 25 | 26 | // filters 27 | s = s 28 | //.replace(/(\)+/g, ' ') // single line 29 | .replace(/(\n )+/g, '') // new line 30 | .replace(/(@w[0-9]+)+/g, '') // wait timers ex. @w30 31 | ; 32 | return s; 33 | } -------------------------------------------------------------------------------- /3DS_Japan_Monster_Strike.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [000400000017B300] Monster Strike (Japan) 3 | // @version 0.1 4 | // @author [Gilfar] 5 | // @description Citra 6 | // ==/UserScript== 7 | const { setHook } = require("./libCitra.js"); 8 | 9 | const mainHandler = trans.send(handler.bind_(null, 0), '200+'); // join 200ms 10 | 11 | setHook({ 12 | 0x1a9aa0: mainHandler, // dialouge only 13 | }); 14 | 15 | function handler(regs, index) { 16 | const address = regs[index].value; 17 | 18 | console.log('onEnter'); 19 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 20 | 21 | /* processString */ 22 | let s = address.readUtf16String(); 23 | 24 | // filters 25 | s = s 26 | .replace(/(\n)+/g, ' ') // page break 27 | ; 28 | 29 | return s; 30 | } -------------------------------------------------------------------------------- /3DS_Japan_Tales_of_the_World_Reve_Unitia.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [000400000012F500] Tales of the World: Reve Unitia (Japan) 3 | // @version 0.1 4 | // @author [Gilfar] 5 | // @description Citra 6 | // ==/UserScript== 7 | const { setHook } = require("./libCitra.js"); 8 | 9 | const mainHandler = trans.send(handler.bind_(null, 0), '200+'); // join 200ms 10 | 11 | setHook({ 12 | 0x251aa0: mainHandler, // dialouge only 13 | }); 14 | 15 | function handler(regs, index) { 16 | const address = regs[index].value; 17 | 18 | console.log('onEnter'); 19 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 20 | 21 | /* processString */ 22 | let s = address.readUtf16String(); 23 | 24 | // filters 25 | s = s 26 | .replace(/(鸚c[0-9]鵡)+/g, '') // color 27 | .replace(/(\n)+/g, ' ') // page break 28 | ; 29 | 30 | return s; 31 | } -------------------------------------------------------------------------------- /3DS_Japan_Toushin_Toshi_Girls_Gift_RPG.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0004000000112000] Toushin Toshi: Girls Gift RPG (Japan) 3 | // @version 0.1 4 | // @author [Gilfar] 5 | // @description Citra 6 | // ==/UserScript== 7 | const { setHook } = require("./libCitra.js"); 8 | 9 | const mainHandler = trans.send(handler.bind_(null, 2), '200+'); // join 200ms 10 | 11 | setHook({ 12 | 0x160528: mainHandler, // dialouge only 13 | }); 14 | 15 | function handler(regs, index) { 16 | const address = regs[index].value; 17 | 18 | console.log('onEnter'); 19 | //console.log(hexdump(address, { header: false, ansi: false, length: 0xF0 })); 20 | 21 | /* processString */ 22 | let s = readString(address); 23 | 24 | // filters 25 | s = s 26 | .replace(/(\n)+/g, ' ') // page break 27 | ; 28 | 29 | return s; 30 | } 31 | 32 | function readString(address) { 33 | let s = '', c; 34 | address = address.add(4); 35 | while ((c = address.readU16()) !== 0x00) { 36 | s += address.readUtf16String(1); 37 | address = address.add(6); 38 | } 39 | return s; 40 | } -------------------------------------------------------------------------------- /Android_MAGES_STEINS_GATE.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name STEINS;GATE 3 | // @version 4 | // @author [DC] 5 | // @description com.mages.steinsgate 6 | // 7 | // ==/UserScript== 8 | Java.perform(() => { 9 | const GameView = Java.use('com.mtrix.steinsgate.gameclass.GameView'); 10 | GameView.messageDisplay.implementation = function (vector) { 11 | const m_stMess = this.m_pEngine.value.m_stMess.value; 12 | 13 | // this.m_pEngine.m_stMess.strName 14 | const name = m_stMess.strName.value; 15 | // this.m_pEngine.m_stMess.strMes 16 | const mess = m_stMess.strMes.value.replace(/%p/g, ''); 17 | 18 | trans.send(name + '\r\n' + mess); 19 | 20 | this.messageDisplay(vector); 21 | }; 22 | }); -------------------------------------------------------------------------------- /HCode/v16032_TAISHOxALICE_Episode_1.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name TAISHO x ALICE Episode 1 3 | // @version 4 | // @author [DC] 5 | // @description JP only, Steam (outdated?; the frist hcode script) 6 | // * 2XT - Primula Adventure Engine (4.4.1.1) 7 | // ==/UserScript== 8 | 9 | const { setHook } = require('../PC_HCode.js'); 10 | 11 | setHook('/HS8@6E300:PJADVJP.bin', { 12 | // Filter 13 | blacklist: true, // bool 14 | threads: { 15 | //':$0x15618': true, // name 16 | //':$0x15667': true, // dialouge 17 | ':$0x6dcad': true, // ruby 18 | }, 19 | 20 | // Linker 21 | join: '500+' 22 | }); 23 | 24 | /* Replacer */ 25 | const patt = /\\\{([^\|]+).([^}]+)./g; 26 | trans.replace((s) => { 27 | // が\{挫|くじ}け 28 | // \{text|rubi} 29 | const rubis = s.matchAll(patt); 30 | // print rubi 31 | for (const rubi of rubis) { 32 | console.log('rubi ' + rubi[2]); 33 | console.log('rube ' + rubi[1]); 34 | } 35 | // remove rubi 36 | s = s.replace(patt, '$1'); 37 | 38 | s = s.replaceAll('\\n', ' '); 39 | 40 | return s; 41 | }); -------------------------------------------------------------------------------- /HCode/v777_Mahoutsukai_no_Yoru.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Mahoutsukai no Yoru 3 | // @version 4 | // @author Textractor 5 | // @description 6 | // * KiriKiri v2.32.2010.425 7 | // * https://krkrz.github.io/ 8 | // ==/UserScript== 9 | 10 | /* 11 | https://github.com/Artikash/Textractor/blob/aa0c0e0047685b502934fe7ba855b7a7be0a5836/texthook/engine/engine.cc#L463 12 | /HW-4*14:-4*0@1137D0:魔法使いの夜.exe 13 | Compiler: Borland C++ 14 | */ 15 | 16 | const { setHook } = require('../PC_HCode.js'); 17 | 18 | setHook('/HW-4*14@1137D0:', { 19 | threads: { 20 | ':$0x119fc6': true 21 | } 22 | }); -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 0xDC00 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NS_010003F003A34000_Pokemon_Let's_Go_Pikachu.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010003F003A34000] Pokémon Let’s Go, Pikachu! 3 | // @version 1.0.2 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Nintendo 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.2'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, -200); 13 | 14 | setHook({ 15 | '1.0.2': { 16 | [0x8067d9fc - 0x80004000]: mainHandler.bind_(null, 0, "Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | 21 | function handler(regs, index, hookname) { 22 | const address = regs[index].value; 23 | //console.log('onEnter: ' + hookname); 24 | 25 | /* processString */ 26 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 27 | let s = address.readUtf16String(); 28 | 29 | s = s 30 | .replace(/[\s\S]*$/, '') // Remove anything after  31 | .replace(/\n+/g, ' ') // Remove line breaks 32 | .replace(/\s/g, '') // Remove spaces 33 | .replace(/[＀븅]/g, '') // Remove specified characters 34 | 35 | return s; 36 | } -------------------------------------------------------------------------------- /NS_01000AE01954A000_Unicorn_Overlord.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01000AE01954A000] Unicorn Overlord 3 | // @version 1.00 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Atlus, Vanillaware 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.00'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.00': { 16 | [0x805ae1f8 - 0x80004000]: mainHandler.bind_(null, 1, "Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs, index, hookname) { 21 | const address = regs[index].value; 22 | // console.log('onEnter: ' + hookname); 23 | 24 | /* processString */ 25 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 26 | let s = address.readUtf8String(); 27 | 28 | s = s 29 | .replace(/[A-Za-z0-9]/g, '') // Remove letters and numbers 30 | .replace(/[~^(-).%,!:#@$/*&;+_]/g, ''); // Remove specified symbols 31 | 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_01000E200DC58000_Octopath_Traveler.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01000E200DC58000] Octopath Traveler 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Square Enix 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x8005ef78 - 0x80004000]: mainHandler.bind_(null, 0, "main text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | 21 | function handler(regs, index, hookname) { 22 | const address = regs[index].value; 23 | //console.log('onEnter: ' + hookname); 24 | 25 | /* processString */ 26 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 27 | let s = address.readUtf32StringLE(); 28 | 29 | return s; 30 | } -------------------------------------------------------------------------------- /NS_01000E701DAE8000_Natsuzora_no_Monologue.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01000E701DAE8000] Natsuzora no Monologue ~Another Memory~ 3 | // @version 1.0.0 4 | // @author kenzy 5 | // @description Yuzu/Sudachi, Ryujinx 6 | // * Design Factory & Otomate 7 | // * Idea Factory 8 | // ==/UserScript== 9 | const gameVer = "1.0.0"; 10 | 11 | const { setHook } = require("./libYuzu.js"); 12 | const mainHandler = trans.send(handler, "200+"); 13 | 14 | setHook( 15 | { 16 | "1.0.0": { 17 | [0x8006007c - 0x80004000]: mainHandler.bind_(null, 0, "dialogue"), // dialogue & names 18 | [0x800578c4 - 0x80004000]: mainHandler.bind_(null, 1, "choices"), 19 | }, 20 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 21 | ); 22 | 23 | function handler(regs, index, hookname) { 24 | const reg = regs[index]; 25 | const address = reg.value; 26 | 27 | /* processString */ 28 | let s = address.readShiftJisString(); 29 | s = s 30 | .replace(/(#n)+/g, " ") 31 | .replace(/(#[A-Za-z]+\[(\d*[.])?\d+\])+/g, "") 32 | .replace(/\u3000+/gu, ""); 33 | 34 | return s; 35 | } 36 | -------------------------------------------------------------------------------- /NS_01000EA014150000_Final_Fantasy_1.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01000EA014150000] Final Fantasy I 3 | // @version 1.0.1 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Square Enix 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.1': { 16 | [0x81e88040 - 0x80004000]: mainHandler.bind_(null, 0, "main text"), // Main text 17 | [0x81cae54c - 0x80004000]: mainHandler.bind_(null, 0, "intro text"), // Intro text 18 | [0x81a3e494 - 0x80004000]: mainHandler.bind_(null, 0, "battle text"), // Battle text 19 | [0x81952c28 - 0x80004000]: mainHandler.bind_(null, 0, "location"), // Location 20 | 21 | } 22 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 23 | 24 | function handler(regs, index, hookname) { 25 | const address = regs[index].value; 26 | //console.log('onEnter:' + hookname); 27 | 28 | /* processString */ 29 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 30 | const len = address.add(0x10).readU32() * 2; 31 | let s = address.add(0x14).readUtf16String(len); 32 | 33 | return s; 34 | } -------------------------------------------------------------------------------- /NS_01001B900C0E2000_Moujuutsukai_to_Ouji-sama_Flower_&_Snow.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01001B900C0E2000] Moujuutsukai to Ouji-sama ~Flower & Snow~ 3 | // @version 1.0.0 4 | // @author [GO123] 5 | // @description Yuzu 6 | // *Otomate 7 | // *Design Factory Co., Ltd. & Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | trans.replace(function (s) { 10 | return s 11 | .replaceAll(/[\s]/g, '') 12 | .replaceAll(/(#[A-Za-z]+\[(\d*[.])?\d+\])+/g, '') 13 | .replaceAll(/#[a-z]/g, '') 14 | .replaceAll(/[a-z]/g, '') 15 | 16 | ; 17 | }); 18 | const gameVer = '1.0.0'; 19 | 20 | const { setHook } = require('./libYuzu.js'); 21 | const mainHandler = trans.send(handler, '200+'); 22 | 23 | setHook({ 24 | '1.0.0': { 25 | [0x800a1a10 - 0x80004000]: mainHandler.bind_(null, 1, "Dialogue1"), // Dialogue 26 | [0x80058f80 - 0x80004000]: mainHandler.bind_(null, 1, "Dialogue2"), // Dialogue 27 | } 28 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 29 | 30 | function handler(regs, index, hookname) { 31 | console.log('onEnter ' + hookname); 32 | 33 | const address = regs[index].value; 34 | 35 | /* processString */ 36 | let s = address.readUtf8String(); 37 | 38 | return s; 39 | } 40 | -------------------------------------------------------------------------------- /NS_01001BA01EBFC000_Moeyo_Otome_Doushi_Kayuu_Koigatari.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01001BA01EBFC000] Moeyo! Otome Doushi ~Kayuu Koigatari~ (燃えよ! 乙女道士 ~華遊恋語~) 3 | // @version 1.0.0 4 | // @author Mansive 5 | // @description Ryujinx 6 | // * Otomate 7 | // * Design Factory Co., Ltd. & Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const gameVer = "1.0.0"; 10 | 11 | const { setHook } = require("./libYuzu.js"); 12 | 13 | const mainHandler = trans.send(handler, "200+"); 14 | 15 | setHook( 16 | { 17 | "1.0.0": { 18 | [0x8005c698 - 0x80004000]: mainHandler.bind_(null, 1, 0x20, "text"), 19 | [0x80051cd0 - 0x80004000]: mainHandler.bind_(null, 1, 0, "choice"), 20 | }, 21 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 22 | ); 23 | 24 | function handler(regs, index, offset, hookname) { 25 | const address = regs[index].value; 26 | 27 | // console.log("onEnter: " + hookname); 28 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | 30 | let s = address 31 | .add(offset) 32 | .readUtf8String() 33 | .replace(/#n/g, "") 34 | .replace(/#\w+(\[.+?\])?/g, ""); 35 | 36 | return s; 37 | } 38 | -------------------------------------------------------------------------------- /NS_01001BB01E8E2000_FANTASIAN_Neo_Dimension.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01001BB01E8E2000] FANTASIAN Neo Dimension 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu/Ryujinx 6 | // * Square Enix 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x81719ea0 - 0x80004000]: mainHandler.bind_(null, 0, "Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs, index, hookname) { 21 | const address = regs[index].value; 22 | // console.log('onEnter: ' + hookname); 23 | 24 | /* processString */ 25 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 26 | const len = address.add(0x10).readU32() * 2; 27 | let s = address.add(0x14).readUtf16String(len); 28 | 29 | s = s.replace(/<[^>]*>/g, ''); // Remove HTML tags 30 | 31 | return s; 32 | } -------------------------------------------------------------------------------- /NS_01001C1009892000_The_World_Ends_With_You.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01001C1009892000] The World Ends with You: Final Remix 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * SQUARE ENIX 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, -200); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x80706ab8 - 0x80004000]: mainHandler.bind_(null, 2, "Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs, index, hookname) { 21 | const address = regs[index].value; 22 | // console.log('onEnter: ' + hookname); 23 | 24 | /* processString */ 25 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 26 | let s = address.readUtf16String(); 27 | 28 | s = s.replace(/\[.*?\]/g, ''); // Remove anything inside [] 29 | 30 | return s; 31 | } -------------------------------------------------------------------------------- /NS_01001DC01486A000_Tsukihime_EN.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01001DC01486A000] 月姫 -A piece of blue glass moon- 3 | // @version 1.0.1, 1.0.2 4 | // @author [DC] 5 | // @description English Patch: https://github.com/Tsukihimates/Tsukihime-Translation 6 | // * Aniplex (アニプレックス) 7 | // * 8 | // KnowIssue: Prologue video (missed) 9 | // ==/UserScript== 10 | require('./NS_01001DC01486A000_Tsukihime.js'); 11 | 12 | trans.replace((s) => { 13 | let result = ''; 14 | 15 | for (let i = 0; i < s.length; i++) { 16 | const c = s.charCodeAt(i); 17 | if (c >= 0xE000 && c <= 0xe2FF) { 18 | result += String.fromCharCode((c - 0xE000) % 0x80); 19 | } 20 | else { 21 | result += s[i]; 22 | } 23 | } 24 | 25 | return result; 26 | }, true); -------------------------------------------------------------------------------- /NS_01001DD010A2E000_Jack_Jeanne.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01001DD010A2E800] JackJanne 3 | // @version 1.0.5 4 | // @author [zooo] 5 | // @description Yuzu 6 | // * 7 | // ==/UserScript== 8 | const gameVer = '1.0.5'; 9 | 10 | const { setHook } = require('./libYuzu.js'); 11 | const mainHandler = trans.send(handler, '200+'); 12 | 13 | setHook({ 14 | '1.0.5': { 15 | [0x81f02cd8 - 0x80004000]: mainHandler, // text 16 | [0x821db028 - 0x80004000]: mainHandler, // choice 17 | 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | function handler(regs) { 22 | const address = regs[0].value; 23 | console.log('onEnter'); 24 | 25 | /* processString */ 26 | const len = address.add(0x10).readU32() * 2; 27 | let s = address.add(0x14).readUtf16String(len); 28 | s = s.replace(/\n+|(\\n)+/g, ' '); 29 | 30 | return s; 31 | } -------------------------------------------------------------------------------- /NS_010021300F69E000_Zettai_Kaikyu_Gakuen.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010021300F69E000] Zettai Kaikyu Gakuen 3 | // @version 1.0.0 4 | // @author [GO123] 5 | // @description Yuzu 6 | // * PROTOTYPE 7 | // * 8 | // 9 | // ==/UserScript== 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | const mainHandler = trans.send(handler, '200+'); 14 | 15 | 16 | setHook({ 17 | '1.0.0': { 18 | [0x80067b5c - 0x80004000]: mainHandler.bind_(null, 1, "text1"),// name+ dialogue main(ADV)+choices 19 | [0x80067cd4 - 0x80004000]: mainHandler.bind_(null, 1, "text2"),//dialogueNVL 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | let previous = ""; 23 | function handler(regs, index, hookname) { 24 | const reg = regs[index]; 25 | // console.log('onEnter: ' + hookname); 26 | const address = reg.value; 27 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | /* processString */ 29 | let s = address.readUtf16String() 30 | .replaceAll(/\$[a-z]/g, "") 31 | .replaceAll("@", "") 32 | ; 33 | if (s === previous) { 34 | return null; 35 | } 36 | previous = s; 37 | return s; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /NS_010024200E00A000_Uta_no_Prince_sama_Repeat_Love.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010024200E00A000] Uta no☆Prince-sama♪ Repeat Love / うたの☆プリンスさまっ♪Repeat LOVE 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * 株式会社ブロッコリー 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x800374a0 - 0x80004000]: mainHandler.bind_(null, 0, "Main Text + Name"), 17 | [0x8002ea08 - 0x80004000]: mainHandler.bind_(null, 0, "Choices"), 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | console.log(` 22 | * This script is only for the main text, any other UI element will not be captured. 23 | * Try using an OCR for those parts. 24 | `); 25 | 26 | function handler(regs, index, hookname) { 27 | const address = regs[index].value; 28 | // console.log('onEnter: ' + hookname); 29 | 30 | /* processString */ 31 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 32 | let s = address.readShiftJisString(); 33 | 34 | s = s.replace(/%N/g, '\n'); // Replace %N with Line breaks 35 | 36 | return s; 37 | } -------------------------------------------------------------------------------- /NS_010027100C79A000_Rune_Factory_4_Special.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010027100C79A000] Rune Factory 4 Special 3 | // @version 1.0.1 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * XSEED Games, Marvelous 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | globalThis.ARM = true; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | const mainHandler = trans.send(handler, 200); 14 | 15 | 16 | 17 | setHook({ 18 | '1.0.1': { 19 | [0x48b268 - 0x204000]: mainHandler, // All text 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | let previous = ""; 24 | function handler(regs) { 25 | // I don't know if those scripts have been done before the tracer fix so if there's a problem multiply the register by 2 26 | // Old tracer assumed the register were 64bit which was wrong 27 | const address = regs[3].value; 28 | // console.log('onEnter: ' + hookname); 29 | 30 | /* processString */ 31 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 32 | let s = address.readUtf8String(); 33 | 34 | if (s === previous) { 35 | return; 36 | } 37 | previous = s; 38 | 39 | return s; 40 | } -------------------------------------------------------------------------------- /NS_010027300A660000_Shiritsu_Berubara_Gakuen_Versailles_no_Bara_Re_imagination.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010027300A660000] Shiritsu Berubara Gakuen ~Versailles no Bara Re*imagination~ (私立ベルばら学園 ~ベルサイユのばらRe*imagination~) 3 | // @version 1.0.0 4 | // @author Mansive 5 | // @description Yuzu, Ryujinx 6 | // * Otomate 7 | // * Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const gameVer = "1.0.0"; 10 | 11 | const { setHook } = require("./libYuzu.js"); 12 | 13 | const mainHandler = trans.send(handler, "200+"); 14 | 15 | setHook( 16 | { 17 | "1.0.0": { 18 | [0x8001b68c - 0x80004000]: mainHandler.bind_(null, 0, 0x1c, "text"), 19 | [0x800460f0 - 0x80004000]: mainHandler.bind_(null, 1, 0, "choice"), 20 | }, 21 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 22 | ); 23 | 24 | function handler(regs, index, offset, hookname) { 25 | const address = regs[index].value; 26 | 27 | // console.log("onEnter: " + hookname); 28 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | 30 | let s = address 31 | .add(offset) 32 | .readUtf8String() 33 | .replace(/#n\u3000*/gu, ""); 34 | 35 | return s; 36 | } 37 | -------------------------------------------------------------------------------- /NS_010027401A2A2000_Utakata_no_Uchronia.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010027401A2A2000] Utakata no Uchronia 3 | // @version 1.0.0 4 | // @author emilybrooks 5 | // @description Yuzu 6 | // * LicoBiTs 7 | // * Unity (il2cpp) 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x8180de40 - 0x80004000]: mainHandler.bind_(null, 0, "text"), 17 | [0x816b61c0 - 0x80004000]: mainHandler.bind_(null, 0, "dictionary"), 18 | [0x815fe594 - 0x80004000]: mainHandler.bind_(null, 0, "choices"), 19 | } 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | function handler(regs, index, name) { 23 | const address = regs[index].value; 24 | const len = address.add(0x10).readU16() * 2; 25 | let text = address.add(0x14).readUtf16String(len); 26 | text = text.replace(/\[dic.*?text=/g, ''); // dictionary words 27 | text = text.replace(/\[|'.*?\]/g, ''); // ruby text 28 | text = text.replace(/\]/g, ''); // closing brace if no ruby text 29 | text = text.replace(name === 'choices' ? /[^\S\n]| /g : /\s| /g, ''); // remove whitespace (leave line breaks for choices) 30 | return text; 31 | } 32 | -------------------------------------------------------------------------------- /NS_01002AE00F442000_FLOWERS_Les_Quatre_Saisons.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01002AE00F442000] Flowers: Les Quatre Saisons 3 | // @version 1.0.1 4 | // @author [Owlie] 5 | // @description Yuzu 6 | // * Innocent Grey 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.1': { 16 | [0x8006f940 - 0x80004000]: mainHandler, // text  17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs) { 21 | const address = regs[1].value; 22 | //console.log('onEnter'); 23 | 24 | /* processString */ 25 | let s = address.readUtf16String(); 26 | 27 | // Remove furigana enclosed within square brackets 28 | s = s.replace(/\[([^\]\/]+)\/[^\]]+\]/g, '$1'); 29 | 30 | // Remove @ symbol 31 | s = s.replace(/(\S*)@/g, '$1'); 32 | 33 | // Remove remaining $ symbols 34 | s = s.replace(/\$/g, ''); 35 | 36 | return s; 37 | } 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /NS_01002B400E9DA000_Collar_x_Malice.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01002B400E9DA000] Collar x Malice 3 | // @version 1.0.0 4 | // @author [Owlie] 5 | // @description Yuzu 6 | // * Design Factory Co., Ltd. & Otomate 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200++'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x800444c4 - 0x80004000]: mainHandler, // text 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs) { 21 | const address = regs[0].value; 22 | console.log('onEnter'); 23 | 24 | /* processString */ 25 | let s = address.readUtf8String() 26 | 27 | return s; 28 | } -------------------------------------------------------------------------------- /NS_01002DA013484000_The_Legend_of_Zelda_Skyward_Sword.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01002DA013484000] The Legend of Zelda: Skyward Sword HD 3 | // @version 1.0.1 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Nintendo 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | 13 | setHook({ 14 | '1.0.1': { 15 | [0x80dc36dc - 0x80004000]: swapHandler, 16 | } 17 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 18 | 19 | function handler(regs, index, hookname) { 20 | // console.log('onEnter: ' + hookname); 21 | const address = regs[index].value; 22 | 23 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 24 | let s = address.readUtf16String(); 25 | 26 | s = s.replace(/^\s*$/gm, ''); // Remove empty lines 27 | return s; 28 | } 29 | 30 | let text = []; 31 | let timerSwap; 32 | function swapHandler(regs) { 33 | const s = handler.call(this, regs, 3, "Text"); 34 | text.unshift(s); 35 | 36 | clearTimeout(timerSwap); 37 | timerSwap = setTimeout(() => { 38 | const s = [...text].join('\r\n'); 39 | trans.send(s); 40 | text = []; 41 | }, 300); 42 | } -------------------------------------------------------------------------------- /NS_01002E2014158000_Final_Fantasy_3.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01002E2014158000] Final Fantasy III 3 | // @version 1.0.1 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Square Enix 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.1': { 16 | [0x82019e84 - 0x80004000]: mainHandler.bind_(null, 0, "text1"), // Main text1 17 | [0x817ffcfc - 0x80004000]: mainHandler.bind_(null, 0, "text2"), // Main text2 18 | [0x81b8b7e4 - 0x80004000]: mainHandler.bind_(null, 0, "battle text"), // battle text 19 | [0x8192c4a8 - 0x80004000]: mainHandler.bind_(null, 0, "location"), // Location 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index, hookname) { 24 | const address = regs[index].value; 25 | //console.log('onEnter: ' + hookname); 26 | 27 | /* processString */ 28 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | const len = address.add(0x10).readU32() * 2; 30 | let s = address.add(0x14).readUtf16String(len); 31 | 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_010037400DAAE000_Brothers_Conflict_Precious_Baby.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010037400DAAE000] Brothers Conflict: Precious Baby 3 | // @version 1.0.0 4 | // @author [Hiyo] 5 | // @description Yuzu 6 | // * Idea Factory Co., Ltd. / Otomate 7 | 8 | // ==/UserScript== 9 | 10 | const gameVer = '1.0.0'; 11 | const decoder = new TextDecoder('utf-16'); 12 | const { setHook } = require('./libYuzu.js'); 13 | 14 | const mainHandler = trans.send(handler, '200+'); // join 200ms 15 | 16 | setHook({ 17 | '1.0.0': { 18 | // Passion Pink & Brilliant Blue 19 | [0x8016aecc - 0x80004000]: mainHandler.bind_(null, 0, "name"), 20 | [0x80126b9c - 0x80004000]: mainHandler.bind_(null, 0, "dialogue"), 21 | [0x80129160 - 0x80004000]: mainHandler.bind_(null, 2, "choice"), 22 | } 23 | 24 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 25 | 26 | function handler(regs, index, hookname) { 27 | const reg = regs[index]; 28 | const address = reg.value; 29 | 30 | /* processString */ 31 | const len = address.add(0x10).readU16() * 2; 32 | let s = address.add(0x14).readUtf16String(len); 33 | s = s.replace(/\n+|(\\n)+/g, ' '); 34 | return s; 35 | } 36 | -------------------------------------------------------------------------------- /NS_01003BD013E30000_Kanda_Alice_mo_Suiri_Suru.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01003BD013E30000] Kanda Alice mo Suiri Suru. 3 | // @version 1.0.0 4 | // @author emilybrooks 5 | // @description Yuzu 6 | // * El Dia 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x80041db0 - 0x80004000]: mainHandler, 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs) { 21 | const address = regs[0].value; 22 | let text = address.readShiftJisString(); 23 | text = text.replace(/{|\/.*?}|\[.*?\]/g, ''); 24 | return text; 25 | } 26 | -------------------------------------------------------------------------------- /NS_01003D2017FEA000_Jyuzaengi_Engetsu_Sangokuden_1_and_2.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01003D2017FEA000] 十三支演義 偃月三国伝1・2 for Nintendo Switch (Juuzaengi ~Engetsu Sangokuden~) 3 | // @version 1.0.0 4 | // @author [zooo] 5 | // @description Yuzu 6 | // * Idea Factory (アイディアファクトリー) 7 | // ==/UserScript== 8 | const gameVer = '1.0.0'; 9 | const decoder = new TextDecoder('utf-16'); 10 | const { setHook } = require('./libYuzu.js'); 11 | 12 | const mainHandler = trans.send(handler, '200+'); // join 200ms 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x82031f20 - 0x80004000]: mainHandler.bind_(null, 2, 0), // name 17 | [0x82ef9550 - 0x80004000]: mainHandler.bind_(null, 1, 0), // dialogue 18 | [0x83252e0c - 0x80004000]: mainHandler.bind_(null, 0, 0), // choice 19 | 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index, hookname) { 24 | const reg = regs[index]; 25 | console.log('onEnter'); 26 | 27 | 28 | console.log('onEnter: ' + hookname); 29 | const address = reg.value; 30 | 31 | /* processString */ 32 | const len = address.add(0x10).readU16() * 2; 33 | let s = address.add(0x14).readUtf16String(len); 34 | s = s.replaceAll(/[\s]/g,''); 35 | return s; 36 | } 37 | -------------------------------------------------------------------------------- /NS_01003E601E324000_Dragon_Quest_III_Hd-2D_Remake.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01003E601E324000] Dragon Quest III Hd-2D Remake 3 | // @version 1.0.1 4 | // @author [Kalleo] 5 | // @description Yuzu/Ryujinx 6 | // * SQUARE ENIX 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.1': { 16 | [0x80c4b094 - 0x80004000]: mainHandler.bind_(null, 0, "Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs, index, hookname) { 21 | const address = regs[index].value; 22 | // console.log('onEnter: ' + hookname); 23 | 24 | /* processString */ 25 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 26 | let s = address.readUtf16String(); 27 | 28 | s = s 29 | .replace(/<[^>]*>/g, '') // Remove HTML Tags 30 | .replace(/\[[^\]]*\]/g, ''); // Remove furigana [] 31 | return s; 32 | } -------------------------------------------------------------------------------- /NS_01003F5017760000_GrimGrimoire_OnceMore.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01003F5017760000] GrimGrimoire OnceMore 3 | // @version 1.0.0 4 | // @author [kinyarou] 5 | // @description Yuzu 6 | // * PROTOTYPE 7 | // * 8 | // 9 | // ==/UserScript== 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | const mainHandler = trans.send(handler, '200+'); 14 | 15 | setHook({ 16 | '1.0.0': { 17 | [0x80020bd4 - 0x80004000]: mainHandler.bind_(null, 0, 0, "Main"), 18 | [0x800375a0 - 0x80004000]: mainHandler.bind_(null, 2, 0, "Tutorial"), 19 | [0x800781dc - 0x80004000]: mainHandler.bind_(null, 0, 0, "Chapter"), 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index, offset, hookname) { 24 | return regs[index].value.add(offset).readUtf8String(); 25 | } 26 | -------------------------------------------------------------------------------- /NS_01003FE00E2F8000_Spade_no_Kuni_no_Alice_Wonderful_White_World.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01003FE00E2F8000] Spade no Kuni no Alice ~Wonderful White World~ / スペードの国のアリス ~Wonderful White World~ 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * アイディアファクトリー株式会社 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x8135d018 - 0x80004000]: mainHandler.bind_(null, 1, "Text + Name"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs, index, hookname) { 21 | const address = regs[index].value; 22 | // console.log('onEnter: ' + hookname); 23 | 24 | /* processString */ 25 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 26 | const len = address.add(0x10).readU32() * 2; 27 | let s = address.add(0x14).readUtf16String(len); 28 | 29 | s = s 30 | .replace(/<[^>]*>/g, '') // Remove HTML tags 31 | 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_010044701E9BC000_The_Hokkaido_Serial_Murder_Case_-_The_Okhotsk_Disappearance_Memories_in_Ice,_Tearful_Figurine.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010044701E9BC000] オホーツクに消ゆ ~追憶の流氷・涙のニポポ人形~ 3 | // @version 1.0.0 4 | // @author [hitsulol] 5 | // @description Yuzu 6 | // * G-MODE 7 | // 8 | 9 | // ==/UserScript== 10 | const gameVer = '1.2.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | 14 | const mainHandler = trans.send(handler, "200+"); 15 | 16 | 17 | setHook({ 18 | '1.2.0': { 19 | [0x83d4bda0 - 0x80004000]: mainHandler.bind_(null, 1, "Dialogue"), 20 | [0x83d59320 - 0x80004000]: mainHandler.bind_(null, 0, "Choice"), 21 | [0x83d22530 - 0x80004000]: mainHandler.bind_(null, 0, "Map Description"), 22 | [0x83d225c0 - 0x80004000]: mainHandler.bind_(null, 0, "Map Memo"), 23 | [0x83d26fd8 - 0x80004000]: mainHandler.bind_(null, 0, "Person Description"), 24 | } 25 | }[globalThis.gameVer ?? gameVer]); 26 | 27 | function handler(regs, index, hookname) { 28 | 29 | const address = regs[index].value; 30 | console.log('onEnter: ' + hookname); 31 | 32 | /* processString */ 33 | let s = address.add(0x14).readUtf16String(); 34 | s = s 35 | .replace(/\<.*?\>/g, '') //remove HTML/ruby 36 | .replace(/\s/g, '') //remove any whitespace 37 | 38 | return s; 39 | } -------------------------------------------------------------------------------- /NS_010044800D2EC000_Toraware_no_Paruma.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010044800D2EC000] Toraware no Paruma 3 | // @version 1.0.0 4 | // @author [DC] 5 | // @description Yuzu 6 | // * Capcom 7 | // * Unity (il2cpp) 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | 13 | const mainHandler = trans.send(handler, '250+'); 14 | 15 | setHook({ 16 | '1.0.0': { 17 | [0x8015b7a8 - 0x80004000]: mainHandler.bind_(null, 0), // text x0 18 | [0x8015b46c - 0x80004000]: mainHandler.bind_(null, 1), // name x1 19 | // choice? 20 | // alert? 21 | // prompt? 22 | } 23 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 24 | 25 | function handler(regs, index) { 26 | const address = regs[index].value; 27 | console.log('onEnter'); 28 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | 30 | /* processString */ 31 | const len = address.add(0x10).readU32() * 2; 32 | let s = null; 33 | if (len > 0) { 34 | s = address.add(0x14).readUtf16String(len); 35 | s = s.replace(/\n+/g, ' '); // single line 36 | s = s.replace(/\/g, '???'); // name 37 | s = s.replace(/<.+?>/g, ''); // html tag 38 | } 39 | 40 | return s; 41 | } -------------------------------------------------------------------------------- /NS_010048101D49E000_Re;quartz_Raid.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010048101D49E000] Re;quartz Raid (Re;quartz零度) 3 | // @version 1.0.1 4 | // @author kenzy 5 | // @description Ryujinx 6 | // * B-cluster 7 | // * PROTOTYPE 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, "200+"); 13 | 14 | setHook({ 15 | '1.0.1': { 16 | [0x800ef69c - 0x80004000]: mainHandler.bind_(null, 1, 'text'), 17 | [0x8011aea4 - 0x80004000]: mainHandler.bind_(null, 9, "choices"), 18 | } 19 | 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | function handler(regs, index, hookname) { 23 | const address = regs[index].value; 24 | 25 | // console.log("onEnter: " + hookname); 26 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 27 | 28 | let s = address.readUtf16String(); 29 | s = s.replace(/\$\[([^\$\/]*)\$\/[^\$]*\$]|([^\$\/]*)\$\/[^\$]*\$\]/g, '$1$2'); // remove rubi 30 | 31 | if (s.startsWith('@')) { 32 | s = s.replaceAll('@', ''); 33 | } 34 | 35 | if (hookname === "choices") { 36 | s = s.split('$d').join('\n'); 37 | } 38 | 39 | return s; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /NS_01004B301415A000_Final_Fantasy_4.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01004B301415A000] Final Fantasy IV 3 | // @version 1.0.2 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Square Enix 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.2'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.2': { 16 | [0x81e44bf4 - 0x80004000]: mainHandler.bind_(null, 0, "main text"), // Main text 17 | [0x819f92c4 - 0x80004000]: mainHandler.bind_(null, 0, "rolling text"), // Rolling text 18 | [0x81e2e798 - 0x80004000]: mainHandler.bind_(null, 0, "battle text"), // Battle text 19 | [0x81b1e6a8 - 0x80004000]: mainHandler.bind_(null, 0, "location"), // Location 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index, hookname) { 24 | const address = regs[index].value; 25 | //console.log('onEnter: ' + hookname); 26 | 27 | /* processString */ 28 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | const len = address.add(0x10).readU32() * 2; 30 | let s = address.add(0x14).readUtf16String(len); 31 | 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_01004E5017C54000_Dance_with_Devils.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01004E5017C54000] Dance with Devils 3 | // @version 1.0.0 4 | // @author Mansive 5 | // @description Yuzu / Ryujinx 6 | // * Rejet 7 | // ==/UserScript== 8 | const gameVer = "1.0.0"; 9 | 10 | const { setHook } = require("./libYuzu.js"); 11 | 12 | const mainHandler = trans.send(handler, "200+"); 13 | 14 | setHook( 15 | { 16 | "1.0.0": { 17 | [0x81616034 - 0x80004000]: mainHandler.bind_(null, 0, "text"), 18 | [0x8185a800 - 0x80004000]: mainHandler.bind_(null, 0, "choices"), 19 | }, 20 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 21 | ); 22 | 23 | function handler(regs, index, hookname) { 24 | const address = regs[index].value; 25 | 26 | // console.log("onEnter: " + hookname); 27 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | 29 | let s = address 30 | .add(0x14) 31 | .readUtf16String() 32 | .replace(/<.+?>/g, "") // remove
tags 33 | .replace(/\u3000/gu, ""); // remove fullwidth whitespace 34 | 35 | return s; 36 | } 37 | -------------------------------------------------------------------------------- /NS_010056F00C7B4000_Bravely_Default_II.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010056F00C7B4000] Bravely Default II 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * SQUARE ENIX 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x80b97700 - 0x80004000]: mainHandler.bind_(null, 0, "Main Text"), 17 | [0x80bb8d3c - 0x80004000]: mainHandler.bind_(null, 0, "Main Ptc Text"), 18 | [0x810add68 - 0x80004000]: mainHandler.bind_(null, 0, "Secondary Text"), 19 | } 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | function handler(regs, index, hookname) { 23 | const address = regs[index].value; 24 | // console.log('onEnter: ' + hookname); 25 | 26 | /* processString */ 27 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | let s = address.readUtf16String(); 29 | 30 | return s; 31 | } -------------------------------------------------------------------------------- /NS_01005940182EC000_Summertime_Render-Another_Horizon.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01005940182EC000] サマータイムレンダ Another Horizon 3 | // @version 1.0.0 4 | // @author [hitsulol] 5 | // @description Yuzu 6 | // * MAGES. GAME 7 | // * Unity (il2cpp) 8 | 9 | // ==/UserScript== 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | 14 | const mainHandler = trans.send(handler, "200+"); 15 | 16 | setHook({ 17 | '1.0.0': { 18 | [0x818ebaf0 - 0x80004000]: mainHandler, //dialogue 19 | } 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | function handler(regs) { 23 | 24 | const address = regs[0].value; 25 | 26 | 27 | console.log('onEnter'); 28 | 29 | /* processString */ 30 | let s = address.add(0x14).readUtf16String(); 31 | s = s.replace(/\s/g, '') //remove any whitespace 32 | .replace(/(.*)<\/color>/g, '$1'); //remove color tag 33 | return s; 34 | } -------------------------------------------------------------------------------- /NS_01005AF00E9DC000_Tokeijikake_no_Apocalypse.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01005AF00E9DC000] Tokeijikake no Apocalypse (時計仕掛けのアポカリプス) 3 | // @version 1.0.0 4 | // @author Mansive 5 | // @description Yuzu, Ryujinx 6 | // * Otomate 7 | // * Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const gameVer = "1.0.0"; 10 | 11 | const { setHook } = require("./libYuzu.js"); 12 | 13 | const mainHandler = trans.send(handler, "200+"); // join 200ms 14 | 15 | setHook( 16 | { 17 | "1.0.0": { 18 | [0x8001d9c4 - 0x80004000]: mainHandler.bind_(null, 0, 0x1c, "text"), 19 | [0x8004ca84 - 0x80004000]: mainHandler.bind_(null, 1, 0, "choices"), 20 | [0x8005b304 - 0x80004000]: mainHandler.bind_(null, 0, 0, "dict word"), 21 | [0x8005b310 - 0x80004000]: mainHandler.bind_(null, 0, 0, "dict meaning"), 22 | }, 23 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 24 | ); 25 | 26 | function handler(regs, index, offset, hookname) { 27 | const address = regs[index].value; 28 | 29 | // console.log("onEnter: " + hookname); 30 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 31 | 32 | let s = address 33 | .add(offset) 34 | .readUtf8String() 35 | .replace(/#n/g, "") // single line 36 | .replace(/#\w+(\[.+?\])?/g, ""); // removes #Color[5] stuff 37 | 38 | return s; 39 | } 40 | -------------------------------------------------------------------------------- /NS_01005CA01580E000_Persona_5_Royal_USA.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01005CA01580E000] Persona 5 Royal 3 | // @version 1.0.0 4 | // @author Koukdw & [DC] 5 | // @description Yuzu 6 | // * Atlus 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const { readString, createTable } = require('./libPCAtlus.js'); 13 | 14 | const mainHandler = trans.send(handler, '200+'); // join 200ms 15 | const table = createTable('P5R'); 16 | table[0xa] = ' '; // single line 17 | 18 | setHook({ 19 | '1.0.0': { 20 | [0x80ec4db0 - 0x80004000]: mainHandler 21 | } 22 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 23 | 24 | function handler(regs) { 25 | const type = regs[2].value & 0xFFFF; 26 | //console.log(ptr(this.returnAddress) + ' ' + type); 27 | if (type === 3 || type === 4) return null; 28 | 29 | const address = regs[1].value; 30 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 31 | const s = readString(address, table); 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_010060800B7A8000_BUSTAFELLOWS.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010060800B7A8000] BUSTAFELLOWS 3 | // @version 1.1.3 4 | // @author [Owlie] 5 | // @description Yuzu 6 | // * Extend 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.1.3'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.1.3': { 16 | [0x80191b18 - 0x80004000]: mainHandler.bind_(null, 0, "Dialogue"), 17 | [0x80191f88 - 0x80004000]: mainHandler.bind_(null, 0, "Choice"), 18 | [0x801921a4 - 0x80004000]: mainHandler.bind_(null, 0, "Choice 2"), 19 | [0x801935f0 - 0x80004000]: mainHandler.bind_(null, 0, "option"), 20 | } 21 | 22 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 23 | 24 | function handler(regs, index, hookname) { 25 | console.log('onEnter: ' + hookname); 26 | const address = regs[index].value; 27 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | 29 | /* processString */ 30 | const len = address.add(0x10).readU16() * 2; 31 | let s = address.add(0x14).readUtf16String(len); 32 | s = s.replace(/\n+|(\\n)+/g, ' '); 33 | s = s.replace(/#n/g, ''); 34 | return s; 35 | } 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /NS_010061A01C1CE000_Unity_Despera_Drops.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010061A01C1CE000] DesperaDrops 3 | // @version 1.0.0 4 | // @author [zooo] 5 | // @description Yuzu 6 | // * Idea Factory (アイディアファクトリー) 7 | // * Unity 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x8199c95c - 0x80004000]: mainHandler, // text1 17 | [0x81d5c900 - 0x80004000]: mainHandler, // text2 18 | [0x820d6324 - 0x80004000]: mainHandler, // choice 19 | 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs) { 24 | const address = regs[1].value; 25 | console.log('onEnter'); 26 | 27 | /* processString */ 28 | const len = address.add(0x10).readU32() * 2; 29 | let s = address.add(0x14).readUtf16String(len); 30 | s = s.replaceAll(/[\s]/g,''); 31 | s = s.replace(/sound/g, ' '); 32 | 33 | return s; 34 | } 35 | -------------------------------------------------------------------------------- /NS_010062B01525C000_Persona_4_Golden.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010062B01525C000] Persona 4 Golden 3 | // @version 1.0.0 4 | // @author Koukdw & [DC] 5 | // @description Yuzu 6 | // * Atlus 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const { readString, createTable } = require('./libPCAtlus.js'); 13 | 14 | const mainHandler = trans.send(handler, '200+'); // join 200ms 15 | const table = createTable('P4G'); 16 | table[0xa] = ' '; // single line 17 | 18 | setHook({ 19 | '1.0.0': { 20 | [0x802d5ba0 - 0x80004000]: mainHandler 21 | } 22 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 23 | 24 | function handler(regs) { 25 | const type = regs[1].value & 0xFFFF; 26 | //console.log(ptr(this.returnAddress) + ' ' + type); 27 | if (type === 3) return null; 28 | 29 | const address = regs[0].value; 30 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 31 | const s = readString(address, table); 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_01006B000A666000_Cendrillon_palikA.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01006B000A666000] Cendrillon palikA 3 | // @version 1.0.0 4 | // @author Koukdw 5 | // @description 6 | // * Otomate 7 | // * Idea Factory (アイディアファクトリー) 8 | // * 9 | // ==/UserScript== 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | const mainHandler0 = trans.send(handler); 14 | const mainHandler1 = trans.send(handler, 200); 15 | 16 | setHook({ 17 | '1.0.0': { 18 | [0x8001ab8c - 0x80004000]: mainHandler0.bind_(null, 2, "name"), 19 | [0x80027b30 - 0x80004000]: mainHandler1.bind_(null, 0, "dialogue"), // only copy the last invocation on this hook. (example: 3 line -> string get appended 3 times) 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index, hookname) { 24 | console.log('onEnter: ' + hookname); 25 | 26 | const address = regs[index].value; 27 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | 29 | /* processString */ 30 | let s = address.readUtf8String() 31 | .replace(/(#n)+/g, ' ') 32 | ; 33 | return s; 34 | } -------------------------------------------------------------------------------- /NS_01006B7014156000_Final_Fantasy_2.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01006B7014156000] Final Fantasy II 3 | // @version 1.0.1 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Square Enix 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.1': { 16 | [0x8208f4cc - 0x80004000]: mainHandler.bind_(null, 0, "main text"), // Main text 17 | [0x817e464c - 0x80004000]: mainHandler.bind_(null, 0, "intro text"), // Intro text 18 | [0x81fb6414 - 0x80004000]: mainHandler.bind_(null, 0, "battle text"), // Battle text 19 | } 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | function handler(regs, index, hookname) { 23 | const address = regs[index].value; 24 | //console.log('onEnter: ' + hookname); 25 | 26 | /* processString */ 27 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | const len = address.add(0x10).readU32() * 2; 29 | let s = address.add(0x14).readUtf16String(len); 30 | 31 | return s; 32 | } -------------------------------------------------------------------------------- /NS_01006BB00C6F0000_The_Legend_of_Zelda_Link's_Awakening.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01006BB00C6F0000] The Legend of Zelda: Link's Awakening 3 | // @version 1.0.1 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Nintendo 7 | // * 8 | // * OBS: Furigana needs to be disabled 9 | // * 10 | // ==/UserScript== 11 | const gameVer = '1.0.1'; 12 | 13 | const { setHook } = require('./libYuzu.js'); 14 | const mainHandler = trans.send(handler, '200+'); 15 | 16 | setHook({ 17 | '1.0.1': { 18 | [0x80f57910 - 0x80004000]: mainHandler.bind_(null, 1, "Main Text"), 19 | } 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | 23 | function handler(regs, index, hookname) { 24 | const address = regs[index].value; 25 | console.log('onEnter: ' + hookname); 26 | 27 | /* processString */ 28 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | let s = address.readUtf8String(); 30 | 31 | return s; 32 | } -------------------------------------------------------------------------------- /NS_01006BD0095F4000_Shin_Megami_Tensei_V.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01006BD0095F4000] Shin Megami Tensei V 3 | // @version 1.0.2 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Atlus 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.2'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.2': { 16 | [0x80ce01a4 - 0x80004000]: mainHandler.bind_(null, 0, "Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs, index, hookname) { 21 | const address = regs[index].value; 22 | // console.log('onEnter: ' + hookname); 23 | 24 | /* processString */ 25 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 26 | let s = address.readUtf16String(); 27 | 28 | return s; 29 | } -------------------------------------------------------------------------------- /NS_01007010157B4000_Galleria_no_Chika_Meikyuu_to_Majo_no_Ryodan.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01007010157B4000] Galleria no Chika Meikyuu to Majo no Ryodan ガレリアの地下迷宮と魔女ノ旅団 3 | // @version 1.0.1 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * 日本一ソフトウェア 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.1': { 16 | [0x8002f64c - 0x80004000]: mainHandler.bind_(null, 0, "Main Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | console.log(` 21 | 1* This script is only for the main text, any other UI element will not be captured. 22 | 2* The intro (Black screen and white text) could not be hooked. Try using an OCR for that part. 23 | `); 24 | 25 | function handler(regs, index, hookname) { 26 | const address = regs[index].value; 27 | console.log('onEnter: ' + hookname); 28 | 29 | /* processString */ 30 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 31 | let s = address.readUtf8String(); 32 | 33 | return s; 34 | } -------------------------------------------------------------------------------- /NS_010076501DAEA000_Getsuei_no _Kusari_Kyouran_Moratorium.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010076501DAEA000] Getsuei no Kusari -Kyouran Moratorium- 3 | // @version 1.0.0 4 | // @author kenzy 5 | // @description Yuzu/Sudachi, Ryujinx 6 | // * TAKUYO 7 | // ==/UserScript== 8 | const gameVer = '1.0.0'; 9 | 10 | globalThis.ARM = true; 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x217950 - 0x204000]: mainHandler.bind_(null, 0, "text"), 17 | [0x217f64 - 0x204000]: mainHandler.bind_(null, 0, "choices"), 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | function handler(regs, index, hookname) { 22 | const address = regs[index].value; 23 | // console.log("onEnter: " + hookname); 24 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 25 | 26 | let s = address.readShiftJisString(); 27 | s = s.replace(/(\\n)+/g, ' ') 28 | .replace(/\\d$|^\@[a-z]+|#.*?#|\$/g, '') 29 | .replace(/\u3000+/gu, '') 30 | .replace(/@w|\\c/g, ''); 31 | 32 | if (hookname === "choices") { 33 | s = s.replace(/, ?\w+/g, ''); 34 | } 35 | 36 | return s; 37 | } 38 | -------------------------------------------------------------------------------- /NS_010076902126E000_DYNAMIC_CHORD_feat_rēve_parfait.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010076902126E000] DYNAMIC CHORD feat.[rēve parfait] 3 | // @version 1.0.0 4 | // @author GO123 5 | // @description sudachi 6 | // * Honeybee Black & arithmetic & Dramatic Create 7 | // ==/UserScript== 8 | const gameVer = "1.0.0"; 9 | 10 | const { setHook } = require("./libYuzu.js"); 11 | 12 | const mainHandler = trans.send(handler, "200+"); 13 | 14 | setHook( 15 | { 16 | "1.0.0": { 17 | [0x81a48614 - 0x80004000]: mainHandler.bind_(null, 1, "text"), 18 | [0x81a5d890 - 0x80004000]: mainHandler.bind_(null, 1, "choices"), 19 | 20 | 21 | }, 22 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 23 | ); 24 | 25 | function handler(regs, index, hookname) { 26 | const address = regs[index].value; 27 | // console.log("onEnter: " + hookname); 28 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | 30 | let s = address.readUtf8String().replace(/
/g, "") 31 | 32 | 33 | return s; 34 | } 35 | -------------------------------------------------------------------------------- /NS_0100771013FA8000_Ken_ga_Kimi_for_S.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100771013FA8000] Ken ga Kimi for S / 剣が君 for S 3 | // @version 1.1 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Rejet 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.1': { 16 | [0x81477128 - 0x80004000]: mainHandler.bind_(null, 0, "Main Text"), 17 | [0x81470e38 - 0x80004000]: mainHandler.bind_(null, 1, "Secondary Text"), 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | function handler(regs, index, hookname) { 22 | const address = regs[index].value; 23 | // console.log('onEnter: ' + hookname); 24 | 25 | /* processString */ 26 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 27 | const len = address.add(0x10).readU32() * 2; 28 | let s = address.add(0x14).readUtf16String(len); 29 | 30 | s = s 31 | .replace(/
/g, '\n') // Replace
with line breaks 32 | .replace(/^\s+/, ''); // Trim spaces if the sentence starts with one 33 | 34 | return s; 35 | } -------------------------------------------------------------------------------- /NS_01007A901E728000_Hakkenden.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01007A901E728000] Hakkenden 3 | // @version 1.0.1 4 | // @author [GO123] 5 | // @description Ryujinx 6 | // * PROTOTYPE 7 | // * 8 | // 9 | // ==/UserScript== 10 | const gameVer = '1.0.1'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | const mainHandler = trans.send(handler, '200+'); 14 | 15 | 16 | setHook({ 17 | '1.0.1': { 18 | [0x819ade74 - 0x80004000]: mainHandler.bind_(null, 1, "text1"), 19 | } 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | function handler(regs, index, hookname) { 23 | const address = regs[index].value; 24 | // console.log('onEnter: ' + hookname); 25 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 26 | /* processString */ 27 | const len = address.add(0x10).readU32() * 2; 28 | let s = address.add(0x14).readUtf16String(len) 29 | 30 | .replace(/(\\n)+/g, '') 31 | .replace(/\S+@/g, "") 32 | .replace(/\\/g, "") 33 | .replace(/(\@)+/g, '') 34 | 35 | ; 36 | 37 | return s; 38 | 39 | } 40 | -------------------------------------------------------------------------------- /NS_01007AD01CB42000_Mistonia_no_Kibou.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01007AD01CB42000] Mistonia no Kibou -The Lost Delight- 3 | // @version 1.0.0 4 | // @author [nanaa] 5 | // @description Yuzu 6 | // Idea Factory Co., Ltd. & Otomate 7 | 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200++'); 13 | 14 | 15 | setHook({ 16 | '1.0.0': { 17 | [0x817ed548 - 0x80004000]: mainHandler.bind_(null, 0), //dialogues 18 | [0x817f183c - 0x80004000]: mainHandler.bind_(null, 1), //pop up dictionary 1 19 | //[0x82869dbc - 0x80004000]: mainHandler.bind_(null, 1), //dictionary menu (buggy) 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index) { 24 | const address = regs[index].value; 25 | const len = address.add(0x10).readU32() * 2; 26 | let s = address.add(0x14).readUtf16String(len); 27 | s = s.replace(/\n+/g, ' '); // single line 28 | s = s.replace(/[~^$(,)R]/g, ' '); //remove symbols 29 | return s; 30 | } 31 | -------------------------------------------------------------------------------- /NS_01007F000EB36000_Doukoku_Soshite.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01007F000EB36000] Doukoku Soshite 3 | // @version 1.0.0 4 | // @author GO123 5 | // @description Ryujinx 6 | // * Sakata SAS & Studio Line & El Dia 7 | // * Data East Corporation & El Dia & Red Flagship 8 | // * 9 | // ==/UserScript== 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | const mainHandler = trans.send(handler, '200++'); // join 200ms 14 | 15 | setHook({ 16 | '1.0.0': { 17 | 18 | [0x8008171c - 0x80004000]: mainHandler.bind_(null, 0,0x0,"dialouge"), 19 | 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index, offset, hookname) { 24 | console.log('onEnter: ' + hookname); 25 | 26 | const address = regs[index].value; 27 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | 29 | /* processString */ 30 | let s = address.add(offset).readShiftJisString(); 31 | 32 | return s; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /NS_010086C00AF7C000_Yo-kai_Watch_4++.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010086C00AF7C000] Yo-kai Watch 4++ 3 | // @version 2.2.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Level-5 7 | //* 8 | // ==/UserScript== 9 | const gameVer = '2.2.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '2.2.0': { 16 | [0x80a88080 - 0x80004000]: mainHandler.bind_(null, 1, "All Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs, index, hookname) { 21 | //console.log('onEnter: ' + hookname); 22 | 23 | const address = regs[index].value; 24 | 25 | let s = address.readUtf8String() 26 | s = s 27 | .replace(/\[([^\]]+)\/[^\]]+\]/g, '$1') // Remove furigana 28 | .replace(/\s+/g, ' ') // Replace any sequence of whitespace characters with a single space 29 | .replace(/\\n/g, ' ') // Replace '\n' with a space 30 | .replace(/<[^>]+>|\[[^\]]+\]/g, ''); // Remove anything within < > or [ ] 31 | 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_0100874017BE2000_Unity_BUSTAFELLOWS_season2.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100874017BE2000] BUSTAFELLOWS season2 3 | // @version 1.0.0 4 | // @author [zooo] 5 | // @description Yuzu 6 | // * Unity 7 | // ==/UserScript== 8 | const gameVer = '1.0.0'; 9 | const { setHook } = require('./libYuzu.js'); 10 | 11 | const mainHandler = trans.send(handler, '200+'); // join 200ms 12 | 13 | setHook({ 14 | '1.0.0': { 15 | [0x819ed3e4 - 0x80004000]: mainHandler.bind_(null, 0, "dialogue"), 16 | [0x82159cd0 - 0x80004000]: mainHandler.bind_(null, 1, "textmessage"), 17 | [0x81e17530 - 0x80004000]: mainHandler.bind_(null, 0, "option"), 18 | [0x81e99d64 - 0x80004000]: mainHandler.bind_(null, 0, "choice"), 19 | [0x8186f81c - 0x80004000]: mainHandler.bind_(null, 0, "archives"), 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index, hookname) { 24 | console.log('onEnter: ' + hookname); 25 | const address = regs[index].value; 26 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 27 | 28 | /* processString */ 29 | const len = address.add(0x10).readU16() * 2; 30 | let s = address.add(0x14).readUtf16String(len); 31 | s = s.replace(/\n+|(\\n)+/g, ' '); 32 | s = s.replace(/#n/g, ''); 33 | return s; 34 | } -------------------------------------------------------------------------------- /NS_01008BE016CE2000_Ikemen_Sengoku_Toki_o_Kakeru_Koi.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01008BE016CE2000] Ikemen Sengoku Toki o Kakeru Koi / イケメン戦国◆時をかける恋 新たなる出逢い 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * アイディアファクトリー株式会社 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x813e4fb4 - 0x80004000]: mainHandler.bind_(null, 0, "Main Text"), 17 | [0x813e4c60 - 0x80004000]: mainHandler.bind_(null, 0, "Name"), 18 | [0x813b5360 - 0x80004000]: mainHandler.bind_(null, 0, "Choices"), 19 | [0x81bab9ac - 0x80004000]: mainHandler.bind_(null, 1, "Info"), 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index, hookname) { 24 | const address = regs[index].value; 25 | // console.log('onEnter: ' + hookname); 26 | 27 | /* processString */ 28 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | const len = address.add(0x10).readU32() * 2; 30 | let s = address.add(0x14).readUtf16String(len); 31 | 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_01008C0016544000_Sea_of_Stars.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [01008C0016544000] Sea of Stars 3 | // @version 1.0.45861 - 1.0.47140 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Sabotage Studio 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.47140'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.45861': { 16 | [0x83e93ca0 - 0x80004000]: mainHandler.bind_(null, 0, "Main text"), 17 | }, 18 | '1.0.47140': { 19 | [0x820c3fa0 - 0x80004000]: mainHandler.bind_(null, 0, "Main text"), 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index, hookname) { 24 | const address = regs[index].value; 25 | //console.log('onEnter', hookname); 26 | 27 | /* processString */ 28 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | const len = address.add(0x10).readU32() * 2; 30 | let s = address.add(0x14).readUtf16String(len); 31 | s = s.replace(/<[^>]+>/g, ''); // Remove anything inside < > 32 | 33 | return s; 34 | } 35 | -------------------------------------------------------------------------------- /NS_0100925014864000_Radiant_Tale.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100925014864000] Radiant Tale 3 | // @version 1.0.0 4 | // @author Koukdw 5 | // @description 6 | // * Design Factory & Otomate 7 | // * Idea Factory (アイディアファクトリー) 8 | // * 9 | // ==/UserScript== 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | 14 | const mainHandler = trans.send(handler, '200+'); // join 200ms 15 | 16 | setHook({ 17 | '1.0.0': { 18 | [0x80075190 - 0x80004000]: mainHandler.bind_(null, 1, "prompt"), 19 | [0x8002fb18 - 0x80004000]: mainHandler.bind_(null, 0, "name"), 20 | [0x8002fd7c - 0x80004000]: mainHandler.bind_(null, 0, "text"), 21 | [0x8004cf28 - 0x80004000]: mainHandler.bind_(null, 1, "choices"), 22 | } 23 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 24 | 25 | function handler(regs, index, hookname) { 26 | console.log('onEnter: ' + hookname); 27 | 28 | const address = regs[index].value; 29 | 30 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 31 | let s = address.readUtf8String() 32 | .replace(/(#n)+/g, ' ') // Single line 33 | .replace(/(#[A-Za-z]+\[(\d*[.])?\d+\])+/g, '') // Remove controls 34 | ; 35 | return s; 36 | } 37 | -------------------------------------------------------------------------------- /NS_0100936018EB4000_Story_of_Seasons_a_Wonderful_Life.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100936018EB4000] Story of Seasons a Wonderful Life 3 | // @version 1.0.3 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Marvelous 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.3'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.3': { 16 | [0x80ac4d88 - 0x80004000]: mainHandler.bind_(null, 0, "main text"), // Main text 17 | [0x808f7e84 - 0x80004000]: mainHandler.bind_(null, 0, "item name"), // Item name 18 | [0x80bdf804 - 0x80004000]: mainHandler.bind_(null, 0, "item description"), // Item description 19 | } 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | function handler(regs, index, hookname) { 23 | const address = regs[index].value; 24 | //console.log('onEnter: ' + hookname); 25 | 26 | /* processString */ 27 | let s = address.readUtf32StringLE(); 28 | s = s.replace(/<[^>]+>/g, ''); // Remove characters inside < > 29 | s = s.replace(/\n+/g, ' '); // Remove line breaks 30 | 31 | return s; 32 | } -------------------------------------------------------------------------------- /NS_010094601D910000_5_Fungo_ni_Igai_na_Ketsumatsu.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [010094601D910000] 5分後に意外な結末 モノクロームの図書館 3 | // @version 1.0.1 4 | // @author hitsulol 5 | // @description Yuzu 6 | // ==/UserScript== 7 | const gameVer = '1.0.1'; 8 | 9 | const { setHook } = require('./libYuzu.js'); 10 | 11 | const mainHandler = trans.send(handler, '250+'); 12 | 13 | setHook({ 14 | '1.0.1': { 15 | [0x81fa4890 - 0x80004000]: mainHandler.bind_(null, 1, "book text" ), 16 | [0x81fa5250 - 0x80004000]: mainHandler.bind_(null, 1, "book text"), 17 | [0x81b1c68c - 0x80004000]: mainHandler.bind_(null, 0, "choice1"), 18 | [0x81b1c664 - 0x80004000]: mainHandler.bind_(null, 0, "choice2"), 19 | [0x81b1e5b0 - 0x80004000]: mainHandler.bind_(null, 3, "dialogue"), 20 | //[0x81ec5660 - 0x80004000]: mainHandler.bind_(null, 0, "book names"), 21 | //[0x81ec6910 - 0x80004000]: mainHandler.bind_(null, 0, "categories"), 22 | } 23 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 24 | 25 | function handler(regs, index, hookname) { 26 | const address = regs[index].value.add(0x14); 27 | 28 | let s = address.readUtf16String(); 29 | 30 | s = s.replace(/\<.*?\>/g, '') 31 | .replace(/\[.*?\]/g, '') 32 | .replace(/\s/g, ''); 33 | 34 | return s; 35 | } 36 | -------------------------------------------------------------------------------- /NS_0100982015606000_HamefuraPirates.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100982015606000] Hamefura Pirates 3 | // @version 1.0.0 4 | // @author [SciresM] 5 | // @description Yuzu 6 | // * Idea Factory (アイディアファクトリー) 7 | // * Unity (il2cpp) 8 | // 9 | // https://vndb.org/v29251 10 | // ==/UserScript== 11 | const gameVer = '1.0.0'; 12 | 13 | const { setHook } = require('./libYuzu.js'); 14 | 15 | const mainHandler = trans.send(handler, '200+'); 16 | 17 | setHook({ 18 | '1.0.0': { 19 | [0x81e75940 - 0x80004000]: mainHandler, // Hamekai.TalkPresenter$$AddMessageBacklog 20 | [0x81c9ae60 - 0x80004000]: mainHandler, // Hamekai.ChoicesText$$SetText 21 | [0x81eb7dc0 - 0x80004000]: mainHandler, // Hamekai.ShortStoryTextView$$AddText 22 | } 23 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 24 | 25 | function handler(regs) { 26 | const address = regs[1].value; 27 | console.log('onEnter'); 28 | 29 | /* processString */ 30 | const len = address.add(0x10).readU32() * 2; 31 | let s = address.add(0x14).readUtf16String(len); 32 | s = s.replace(/\n+|(\\n)+/g, ' '); 33 | 34 | return s; 35 | } -------------------------------------------------------------------------------- /NS_0100A250191E8000_Money_Parasite_Usotsuki_na_Onna.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100A250191E8000] Money Parasite ~Usotsuki na Onna~ 3 | // @version 1.0.0 4 | // @author kenzy 5 | // @description Yuzu/Sudachi, Ryujinx 6 | // * TAKUYO 7 | // ==/UserScript== 8 | const gameVer = '1.0.0'; 9 | 10 | globalThis.ARM = true; 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x2169ac - 0x204000]: mainHandler.bind_(null, 0, "text"), 17 | [0x217030 - 0x204000]: mainHandler.bind_(null, 0, "choices"), 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | function handler(regs, index, hookname) { 22 | const address = regs[index].value; 23 | // console.log("onEnter: " + hookname); 24 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 25 | 26 | let s = address.readShiftJisString(); 27 | s = s.replace(/(\\n)+/g, ' ') 28 | .replace(/\\d$|^\@[a-z]+|#.*?#|\$/g, '') 29 | .replace(/\u3000+/gu, '') 30 | .replace(/@w|\\c/g, ''); 31 | 32 | if (hookname === "choices") { 33 | s = s.replace(/, ?\w+/g, ''); 34 | } 35 | 36 | return s; 37 | } 38 | -------------------------------------------------------------------------------- /NS_0100A3501946E000_Octopath_Traveler_2.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100A3501946E000] Octopath Traveler II 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Square Enix 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x8088a4d4 - 0x80004000]: mainHandler.bind_(null, 0, "main text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | 21 | function handler(regs, index, hookname) { 22 | const address = regs[index].value; 23 | //console.log('onEnter', hookname); 24 | 25 | /* processString */ 26 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 27 | let s = address.readUtf16String(); 28 | 29 | return s; 30 | } -------------------------------------------------------------------------------- /NS_0100A3A00CC7E000_CLANNAD_JP.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100A3A00CC7E000] CLANNAD 3 | // @version 1.0.0 4 | // @author [DC] 5 | // @description Yuzu 6 | // * PROTOTYPE 7 | // * 8 | // 9 | // Warnning: Japanese 10 | // ==/UserScript== 11 | trans.replace(function(str) { 12 | const s = str.replace("Tomoya", "朋也").replace("Okazaki", "岡崎") 13 | const splited = s.split('\n'); 14 | if (splited.length % 2 === 0) { 15 | const N = splited.length / 2; 16 | return splited.slice(0, N).join('\r\n'); 17 | } 18 | return s; 19 | }); 20 | 21 | require('./NS_0100A3A00CC7E000_CLANNAD.js'); -------------------------------------------------------------------------------- /NS_0100A62019078000_Temirana_Koku_no_Tsuiteru_Hime_to_Tsuitenai_Kishidan.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100A62019078000] Temirana Koku no Tsuiteru Hime to Tsuitenai Kishidan 3 | // @version 1.0.1 4 | // @author GO123 5 | // @description Ryujinx 6 | //* Ichi Column 7 | //* Idea Factory Co., Ltd. & Otomate 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200++'); 13 | 14 | setHook({ 15 | '1.0.1': { 16 | [0x82457970 - 0x80004000]: mainHandler.bind_(null, 0, "Dialogue text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | 21 | function handler(regs, index, hookname) { 22 | 23 | const address = regs[index].value; 24 | // console.log("onEnter: " + hookname); 25 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 26 | 27 | /* processString */ 28 | let s = address.add(0x14).readUtf16String() 29 | .replaceAll(/[\s]/g, '') 30 | .replaceAll("$$R", '') 31 | .replaceAll("%", '') 32 | 33 | 34 | return s; 35 | } -------------------------------------------------------------------------------- /NS_0100A77018EA0000_Dragon_Quest_Monsters_The_Dark_Prince.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100A77018EA0000] Dragon Quest Monsters: The Dark Prince 3 | // @version 1.0.6 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * SQUARE ENIX 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.6'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.6': { 16 | "Hb4462d78e1881de9": mainHandler.bind_(null, 1, "Text"), 17 | "Hbd4bb92daec3d3b2": mainHandler.bind_(null, 0, "Config Description"), 18 | } 19 | }, globalThis.gameVer = globalThis.gameVer ?? gameVer); 20 | 21 | function handler(regs, index, hookname) { 22 | const address = regs[index].value; 23 | // console.log('onEnter: ' + hookname); 24 | 25 | /* processString */ 26 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 27 | const len = address.add(0x10).readU32() * 2; 28 | let s = address.add(0x14).readUtf16String(len); 29 | 30 | s = s 31 | .replace(/.*?<\/size><\/voffset>/g, "") // Remove Furigana 32 | .replace(/<[^>]*>/g, '') // Remove HTML Tags 33 | 34 | return s; 35 | } 36 | -------------------------------------------------------------------------------- /NS_0100A89019EEC000_Sakura_Moyu_as_the_Night's_Reincarnation.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100A89019EEC000] Sakura, Moyu. -as the Night's, Reincarnation- 3 | // @version 1.0.0 4 | // @author [GO123] 5 | // @description yuzu & ryujinx 6 | // * Unity 7 | // ==/UserScript== 8 | trans.replace(function (s) { 9 | return s 10 | .replaceAll(/\s/g, '') 11 | 12 | ; 13 | }); 14 | const gameVer = '1.0.0'; 15 | 16 | const { setHook } = require('./libYuzu.js'); 17 | 18 | const mainHandler = trans.send(handler, '200++'); // join 200ms 19 | 20 | setHook({ 21 | '1.0.0': { 22 | [0x82340e88 - 0x80004000]: mainHandler.bind_(null, 0, "dialogue"), 23 | 24 | } 25 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 26 | 27 | function handler(regs, index, hookname) { 28 | console.log('onEnter: ' + hookname); 29 | const address = regs[index].value; 30 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 31 | 32 | /* processString */ 33 | const len = address.add(0x10).readU16() * 2; 34 | let s = address.add(0x14).readUtf16String(len); 35 | return s; 36 | } 37 | -------------------------------------------------------------------------------- /NS_0100AA001415E000_Final_Fantasy_6.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100AA001415E000] Final Fantasy VI 3 | // @version 1.0.2 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Square Enix 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.2'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.2': { 16 | [0x81e6b350 - 0x80004000]: mainHandler.bind_(null, 0, "main text"), // Main text 17 | [0x81ab40ec - 0x80004000]: mainHandler.bind_(null, 0, "location"), // Location 18 | [0x819b8c88 - 0x80004000]: mainHandler.bind_(null, 0, "battle text"), // Battle text 19 | } 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | function handler(regs, index, hookname) { 23 | const address = regs[index].value; 24 | //console.log('onEnter: ' + hookname); 25 | 26 | /* processString */ 27 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | const len = address.add(0x10).readU32() * 2; 29 | let s = address.add(0x14).readUtf16String(len); 30 | 31 | return s; 32 | } -------------------------------------------------------------------------------- /NS_0100AA201415C000_Final_Fantasy_5.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100AA201415C000] Final Fantasy V 3 | // @version 1.0.2 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Square Enix 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.2'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.2': { 16 | [0x81d63e24 - 0x80004000]: mainHandler.bind_(null, 0, "main text"), // Main text 17 | [0x81adfb3c - 0x80004000]: mainHandler.bind_(null, 0, "location"), // Location 18 | [0x81a8fda8 - 0x80004000]: mainHandler.bind_(null, 0, "battle text"), // Battle text 19 | } 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | function handler(regs, index, hookname) { 23 | const address = regs[index].value; 24 | //console.log('onEnter: ' + hookname); 25 | 26 | /* processString */ 27 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | const len = address.add(0x10).readU32() * 2; 29 | let s = address.add(0x14).readUtf16String(len); 30 | 31 | return s; 32 | } -------------------------------------------------------------------------------- /NS_0100AAF020664000_Apathy_Danshikou_de_Atta_Kowai_Hanashi.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100AAF020664000] Apathy - Danshikou de Atta Kowai Hanashi 3 | // @version 1.0.1 4 | // @author kenzy 5 | // @description Sudachi, Ryujinx 6 | // * Shannon 7 | // * Mebius 8 | // ==/UserScript== 9 | const gameVer = "1.0.1"; 10 | 11 | const { setHook } = require("./libYuzu.js"); 12 | const mainHandler = trans.send(handler, "200+"); 13 | 14 | setHook( 15 | { 16 | "1.0.1": { 17 | [0x8008eb00 - 0x80004000]: mainHandler.bind_(null, 1, "text"), 18 | [0x80009388 - 0x80004000]: mainHandler.bind_(null, 10, "names"), 19 | [0x80014a64 - 0x80004000]: mainHandler.bind_(null, 0, "choices"), 20 | }, 21 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 22 | ); 23 | 24 | function handler(regs, index, hookname) { 25 | const address = regs[index].value; 26 | // console.log("onEnter: " + hookname); 27 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | 29 | let s = address.readUtf32StringLE() 30 | s = s.replace(/\n/g, "") // single line 31 | .replace(/\u3000/gu, ""); // remove fullwidth spaces 32 | 33 | return s; 34 | } 35 | -------------------------------------------------------------------------------- /NS_0100ADC014DA0000_AIR.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100ADC014DA0000] AIR 3 | // @version 1.0.1 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Key 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.1'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.1': { 16 | [0x800a6b10 - 0x80004000]: mainHandler.bind_(null, 1, "Text + Name"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | console.log(` 21 | The intro (White screen and black text) was not hooked, probably because it's an image or video. 22 | Try using an OCR for that part. 23 | `); 24 | 25 | function handler(regs, index, hookname) { 26 | const address = regs[index].value; 27 | // console.log('onEnter: ' + hookname); 28 | 29 | /* processString */ 30 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 31 | let s = address.readUtf16String(); 32 | 33 | s = s 34 | .replace(/[~^$(,)]/g, '') // Remove specified symbols 35 | .replace(/[A-Za-z0-9]/g, '') // Remove letters and numbers 36 | .replace(/@/g, ' ') // Replace @ for spaces 37 | .replace(/^\s+/, ''); // Trim spaces if the sentence starts with one 38 | 39 | return s; 40 | } -------------------------------------------------------------------------------- /NS_0100AFA01750C000_Shinigami_to_Shoujo.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100AFA01750C000] Shinigami to Shoujo 3 | // @version 1.0.0, 1.0.2 4 | // @author koukdw 5 | // @description Yuzu 6 | // * TAKUYO 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.2'; 10 | 11 | 12 | globalThis.ARM = true; 13 | const { setHook } = require('./libYuzu.js'); 14 | const mainHandler = trans.send(handler, '200+'); 15 | 16 | 17 | console.log("To solve text display bug, use opengl API and set Grahpics -> Advanced -> Accuracy level to Extreme.") 18 | 19 | setHook({ 20 | '1.0.2': { 21 | [0x21cb08 - 0x204000]: mainHandler.bind_(null, 1, "text"), 22 | } 23 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 24 | 25 | 26 | function handler(regs, index, hookname) { 27 | const reg = regs[index]; 28 | 29 | //console.log('onEnter: ' + hookname); 30 | const address = reg.value; 31 | /* processString */ 32 | const s = address.readShiftJisString() 33 | .replace(/(\\n)+/g, ' ') 34 | .replace(/\\d$|^\@[a-z]+|#.*?#|\$/g, '') // #.*?# <=> #[^#]+. 35 | ; 36 | 37 | return s; 38 | } 39 | -------------------------------------------------------------------------------- /NS_0100B5700CDFC000_Amnesia_Later_x_Crowd_V.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100B5700CDFC000] AMNESIA LATER×CROWD for Nintendo Switch 3 | // @version 1.0.0 4 | // @author [DC] 5 | // @description Yuzu 6 | // * Idea Factory (アイディアファクトリー) 7 | // * Unity (il2cpp) 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | // trans.replace(function(s) { 11 | // return s 12 | // .replace(/オリオン/g, 'Orion') 13 | // .replace(/トーマ/g, 'Toma') 14 | // ; 15 | // }); 16 | 17 | const { setHook } = require('./libYuzu.js'); 18 | 19 | const mainHandler = trans.send(handler.bind_(null, 1), '250+'); // join 250ms; x1 20 | 21 | setHook({ 22 | '1.0.0': { 23 | [0x800ebc34 - 0x80004000]: mainHandler, // waterfall 24 | [0x8014dc64 - 0x80004000]: mainHandler, // name 25 | [0x80149b10 - 0x80004000]: mainHandler, // dialogue 26 | [0x803add50 - 0x80004000]: mainHandler, // choice 27 | } 28 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 29 | 30 | function handler(regs, index) { 31 | const address = regs[index].value; 32 | console.log('onEnter'); 33 | 34 | /* processString */ 35 | const len = address.add(0x10).readU32() * 2; 36 | let s = address.add(0x14).readUtf16String(len); 37 | s = s.replace(/\n+|(\\n)+/g, ' '); 38 | 39 | return s; 40 | } -------------------------------------------------------------------------------- /NS_0100B5800C0E4000_Reine_des_Fleurs.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100B5800C0E4000] Reine des Fleurs 3 | // @version 1.0.0 4 | // @author [Owlie] 5 | // @description Yuzu 6 | // * Design Factory Co., Ltd. & Otomate 7 | //* 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200++'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x80026434 - 0x80004000]: mainHandler.bind_(null, 0, "Dialogue text"), // Dialogue text 17 | 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | function handler(regs, index, hookname) { 22 | //console.log('onEnter ' + hookname); 23 | 24 | const address = regs[index].value; 25 | 26 | /* processString */ 27 | let s = address.readUtf8String() 28 | //.replace(/\s+/g, ' ') // Replace any sequence of whitespace characters with a single space 29 | // .replace(/\\n/g, ' ') // Replace '\n' with a space 30 | 31 | return s; 32 | } -------------------------------------------------------------------------------- /NS_0100B5801D7CE000_Kannagi_no_Mori_Satsukiame_Tsuzuri.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100B5801D7CE000] Kannagi no Mori Satsukiame Tsuzuri 3 | // @version 1.0.0 4 | // @author kenzy 5 | // @description Yuzu/Sudachi, Ryujinx 6 | // *Matatabi 7 | // ==/UserScript== 8 | const gameVer = '1.0.0'; 9 | 10 | const { setHook } = require('./libYuzu.js'); 11 | const mainHandler = trans.send(handler, "200+"); 12 | 13 | setHook({ 14 | '1.0.0': { 15 | [0x8205e150 - 0x80004000]: mainHandler.bind_(null, 0, 0, "dialogue"), 16 | [0x820e2e6c - 0x80004000]: mainHandler.bind_(null, 0, 0, "choices"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs, index, offset, hookname) { 21 | const address = regs[index].value.add(offset); 22 | // console.log("onEnter: " + hookname); 23 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 24 | 25 | let s = address.add(0x14).readUtf16String(); 26 | 27 | if (hookname === "dialogue") { 28 | s = s.replace(/\n/g, ''); 29 | } 30 | 31 | return s; 32 | } 33 | -------------------------------------------------------------------------------- /NS_0100B6501FE4C000_Kenka_Banchou_Otome_Double_Pack.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100B6501FE4C000] Kenka Banchou Otome Double Pack 3 | // @version 1.1.0 4 | // @author kenzy 5 | // @description Yuzu, Ryujinx 6 | // * RED 7 | // * Spike Chunsoft 8 | // ==/UserScript== 9 | const gameVer = '1.1.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | console.log 15 | (` 16 | * Set the game's TEXT SPEED to MAX for the script to display properly. 17 | `) 18 | 19 | setHook({ 20 | '1.1.0': { 21 | [0x81801c7c - 0x80004000]: mainHandler.bind_(null, 0, 'text'), 22 | [0x8161f640 - 0x80004000]: mainHandler.bind_(null, 0, "names"), 23 | [0x817f8490 - 0x80004000]: mainHandler.bind_(null, 1, "choices"), 24 | } 25 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 26 | 27 | function handler(regs, index, hookname) { 28 | const address = regs[index].value; 29 | 30 | // console.log("onEnter: " + hookname); 31 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 32 | 33 | let s = address.add(0x14).readUtf16String(); 34 | s = s.replace(/[\r\n]+/g, ''); 35 | 36 | 37 | return s; 38 | } 39 | 40 | -------------------------------------------------------------------------------- /NS_0100B6900A668000_Code_Realize_Saikou_no_Hanataba.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100B6900A668000] Code: Realize ~Saikou no Hanataba~ (Code:Realize ~彩虹の花束~) 3 | // @version 1.0.0 4 | // @author [Owlie], Mansive 5 | // @description Yuzu/Sudachi, Ryujinx 6 | // * -Design Factory Co., Ltd. & Otomate 7 | // * 8 | // ==/UserScript== 9 | const gameVer = "1.0.0"; 10 | 11 | const { setHook } = require("./libYuzu.js"); 12 | 13 | const mainHandler = trans.send(handler, "200+"); 14 | 15 | setHook( 16 | { 17 | "1.0.0": { 18 | [0x80019c14 - 0x80004000]: mainHandler.bind_(null, 0, 0x1c, "text"), 19 | [0x80041560 - 0x80004000]: mainHandler.bind_(null, 1, 0, "choice"), 20 | [0x800458c8 - 0x80004000]: mainHandler.bind_(null, 0, 0, "dict"), 21 | }, 22 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 23 | ); 24 | 25 | let previous = ""; 26 | 27 | function handler(regs, index, offset, hookname) { 28 | const address = regs[index].value; 29 | 30 | // console.log("onEnter:", hookname); 31 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 32 | 33 | let s = address.add(offset).readUtf8String(); 34 | s = s.replace(/#\w+(\[.+?\])?/g, "").replace(/\u3000/gu, ""); 35 | 36 | if (s === "" || s === previous) { 37 | return null; 38 | } 39 | previous = s; 40 | 41 | return s; 42 | } 43 | -------------------------------------------------------------------------------- /NS_0100B880154FC000_Persona_5_Royal.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100B880154FC000] Persona 5 Royal 3 | // @version 1.0.0 4 | // @author Koukdw & [DC] 5 | // @description Yuzu 6 | // * Atlus 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const { readString, createTable } = require('./libPCAtlus.js'); 13 | 14 | const mainHandler = trans.send(handler, '200+'); // join 200ms 15 | const table = createTable('P5R'); 16 | table[0xa] = ' '; // single line 17 | 18 | setHook({ 19 | '1.0.0': { 20 | [0x80ec4c90 - 0x80004000]: mainHandler 21 | } 22 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 23 | 24 | function handler(regs) { 25 | const type = regs[2].value & 0xFFFF; 26 | //console.log(ptr(this.returnAddress) + ' ' + type); 27 | if (type === 3 || type === 4) return null; 28 | 29 | const address = regs[1].value; 30 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 31 | const s = readString(address, table); 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_0100B8E016F76000_NieR_Automata.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100B8E016F76000] NieR:Automata The End of YoRHa Edition 3 | // @version 1.0.2 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * PlatinumGames, Square Enix 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.2'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.2': { 16 | [0x808e7068 - 0x80004000]: mainHandler.bind_(null, 3, "Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | 21 | function handler(regs, index, hookname) { 22 | const address = regs[index].value; 23 | //console.log('onEnter: ' + hookname); 24 | 25 | /* processString */ 26 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 27 | let s = address.readUtf16String(); 28 | s = s.replace(/お金を\d+G取得しました\s*/g, ''); // Remove money received message 29 | 30 | return s; 31 | } -------------------------------------------------------------------------------- /NS_0100BD700E648000_Diabolik Lovers Grand Edition.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100BD700E648000] Diabolik Lovers Grand Edition 3 | // @version 1.0.0 4 | // @author [Hiyo] 5 | // @description Yuzu 6 | // * Idea Factory Co., Ltd. / Otomate & Rejet 7 | 8 | // ==/UserScript== 9 | 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | 14 | const mainHandler = trans.send(handler, '200+'); // join 200ms 15 | 16 | setHook({ 17 | '1.0.0': { 18 | 19 | [0x80041080 - 0x80004000]: mainHandler.bind_(null, 1, "name"), 20 | [0x8002886c - 0x80004000]: mainHandler.bind_(null, 0, "dialogue"), 21 | [0x80041040 - 0x80004000]: mainHandler.bind_(null, 2, "choice1"), 22 | } 23 | 24 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 25 | 26 | function handler(regs, index, hookname) { 27 | const address = regs[index].value; 28 | 29 | let s = address.readUtf8String() 30 | .replace('*', ' ') 31 | .replace('ゞ', '!?') 32 | ; 33 | 34 | return s; 35 | } -------------------------------------------------------------------------------- /NS_0100C1E0102B8000_Shinobi, Koi Utsutsu.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100C1E0102B8000] Shinobi, Koi Utsutsu 3 | // @version 1.0.0 4 | // @author [Hiyo] 5 | // @description Yuzu 6 | // * Idea Factory Co., Ltd. / Otomate 7 | 8 | // ==/UserScript== 9 | 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | 14 | const mainHandler = trans.send(handler, '200+'); // join 200ms 15 | 16 | setHook({ 17 | '1.0.0': { 18 | [0x8002aca0 - 0x80004000]: mainHandler.bind_(null, 0, "name"), 19 | [0x8002aea4 - 0x80004000]: mainHandler.bind_(null, 0, "dialogue1"), 20 | [0x8001ca90 - 0x80004000]: mainHandler.bind_(null, 2, "dialogue2"), 21 | [0x80049dbc - 0x80004000]: mainHandler.bind_(null, 1, "choice"), 22 | } 23 | 24 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 25 | 26 | function handler(regs, index, hookname) { 27 | const address = regs[index].value; 28 | 29 | let s = address.readUtf8String() 30 | .replace('\n', ' ') 31 | .replace('#n', ' ') 32 | .replace(/#Color\[[\d]+\]/g, ''); 33 | ; 34 | 35 | return s; 36 | } -------------------------------------------------------------------------------- /NS_0100C2901153C000_Yoru_Tomosu.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100C2901153C000] Yoru, Tomosu 3 | // @version 1.0.0 4 | // @author [Owlie] 5 | // @description Yuzu 6 | // * Nippon Ichi Software 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0xe2748eb0 - 0x80004000]: mainHandler, // text1 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs) { 21 | const address = regs[1].value; 22 | console.log('onEnter'); 23 | 24 | /* processString */ 25 | let s = address.readUtf32StringLE() 26 | .replaceAll('\n', ' ') // Single line 27 | ; 28 | return s; 29 | } -------------------------------------------------------------------------------- /NS_0100C29017106000_LIVE_A_LIVE.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100C29017106000] Live a Live 3 | // @version 1.0.0 4 | // @author [Owlie] 5 | // @description Yuzu 6 | // * Square Enix 7 | // * Nintendo 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x80a05170 - 0x80004000]: mainHandler, // text 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs) { 21 | const address = regs[0].value; 22 | console.log('onEnter'); 23 | 24 | /* processString */ 25 | let s = address.readUtf16String() 26 | s = s.replace(/\n+|(\\n)+/g, ' ') 27 | ; 28 | return s; 29 | } -------------------------------------------------------------------------------- /NS_0100C4E013E5E000_Ni_no_Kuni_II_Revenant_Kingdom.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100C4E013E5E000] Ni no Kuni II: Revenant Kingdom 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Level-5 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x80ac651c - 0x80004000]: mainHandler.bind_(null, 0, "Main Text"), 17 | [0x80335ea0 - 0x80004000]: mainHandler.bind_(null, 0, "Name"), 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | console.log(` 22 | * This script is only for the main text, any other UI element will not be captured. 23 | * Try using an OCR for those parts. 24 | `); 25 | 26 | function handler(regs, index, hookname) { 27 | const address = regs[index].value; 28 | // console.log('onEnter: ' + hookname); 29 | 30 | /* processString */ 31 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 32 | let s = address.readUtf8String(); 33 | 34 | s = s.replace(/\\n/g, '\n'); // Replace \n with Line breaks 35 | 36 | return s; 37 | } -------------------------------------------------------------------------------- /NS_0100CBA014014000_Tantei_Bokumetsu.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100CBA014014000] Tantei Bokumetsu / 探偵撲滅 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Nippon Ichi Software 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x8011c340 - 0x80004000]: mainHandler.bind_(null, 1, "Text"), 17 | [0x80064f20 - 0x80004000]: mainHandler.bind_(null, 1, "Choices"), 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | console.log(` 22 | * This script is only for the main text, any other UI element will not be captured. 23 | * Try using an OCR for those parts. 24 | `); 25 | 26 | function handler(regs, index, hookname) { 27 | const address = regs[index].value; 28 | // console.log('onEnter: ' + hookname); 29 | 30 | /* processString */ 31 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 32 | let s = address.readUtf8String(); 33 | 34 | s = s 35 | .replace(/《.*?》/g, '') // Remove furigana ( 和都《2,わと》) 36 | .replace(/<[^>]*>/g, ''); // Remove HTML tags 37 | 38 | return s; 39 | } -------------------------------------------------------------------------------- /NS_0100CEF0152DE000_Charade_Maniacs.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100CEF0152DE000] Charade Maniacs / CharadeManiacs 3 | // @version 1.0.0 4 | // @author Mansive 5 | // @description Yuzu / Ryujinx 6 | // * Otomate & Idea Factory Co., Ltd. 7 | // ==/UserScript== 8 | const gameVer = "1.0.0"; 9 | 10 | const { setHook } = require("./libYuzu.js"); 11 | 12 | const mainHandler = trans.send(handler, "200+"); 13 | 14 | setHook( 15 | { 16 | "1.0.0": { 17 | [0x8001c460 - 0x80004000]: mainHandler.bind_(null, 0, 0x5c, "text"), 18 | [0x8004c390 - 0x80004000]: mainHandler.bind_(null, 1, 0, "choices"), 19 | [0x80050d60 - 0x80004000]: mainHandler.bind_(null, 0, 0, "dictionary"), 20 | [0x8007ee20 - 0x80004000]: mainHandler.bind_(null, 0, 0, "materials"), 21 | }, 22 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 23 | ); 24 | 25 | function handler(regs, index, offset, hookname) { 26 | let address = regs[index].value; 27 | 28 | console.log("onEnter: " + hookname); 29 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 30 | 31 | let s = address 32 | .add(offset) 33 | .readUtf8String() 34 | .replace(/\u3000/gu, "") // remove fullwidth whitespace 35 | .replace(/#n/g, "") 36 | .replace(/#\w.+?]/g, ""); // remove #Color[69] stuff 37 | 38 | return s; 39 | } 40 | -------------------------------------------------------------------------------- /NS_0100D12014FC2000_Yuru Camp_Have_a_nice_day.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100D12014FC2000] Yuru Camp△ - Have a Nice Day! 3 | // @version 1.0.0 4 | // @author [Darkmans] 5 | // @description Yuzu 6 | // * MAGES. GAME 7 | // * Unity (il2cpp) 8 | // 9 | // https://vndb.org/v30937 10 | // ==/UserScript== 11 | const gameVer = '1.0.0'; 12 | 13 | const { setHook } = require('./libYuzu.js'); 14 | 15 | const mainHandler = trans.send(handler, "200+"); 16 | 17 | setHook({ 18 | '1.0.0': { 19 | [0x816d03f8 - 0x80004000]: mainHandler, // dialog / backlog 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs) { 24 | const address = regs[0].value; 25 | console.log('onEnter'); 26 | 27 | /* processString */ 28 | const len = address.add(0x10).readU32() * 2; 29 | let s = address.add(0x14).readUtf16String(len); 30 | s = s.replace(/\n+|(\\n)+/g, ' '); 31 | 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_0100D7E01E998000_Fuyuzono_Sacrifice.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100D7E01E998000] Fuyuzono Sacrifice 3 | // @version 1.0.0 4 | // @author emilybrooks 5 | // @description Sudachi, Ryujinx 1.1.1403 6 | // * Design Factory Co., Ltd. & Otomate 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x816c9e24 - 0x80004000]: mainHandler.bind_(null, 0, "text"), 17 | [0x818c90d4 - 0x80004000]: mainHandler.bind_(null, 0, "dictionary"), 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | function handler(regs, index, name) { 22 | const address = regs[index].value; 23 | const len = address.add(0x10).readU16() * 2; 24 | let text = address.add(0x14).readUtf16String(len); 25 | text = text.replace(/\s+/g, ''); // remove whitespace 26 | text = text.replace(/\$+/g, ''); // remove dictionary word markers 27 | return text; 28 | } 29 | -------------------------------------------------------------------------------- /NS_0100D9500A0F6000_ClosedNightmare.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100D9500A0F6000] Closed Nightmare 3 | // @version 1.0.0 4 | // @author [DC] 5 | // @description Yuzu 6 | // * Nippon Ichi Software, Inc. 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | 13 | const mainHandler = trans.send(handler, '200+'); // join 200ms 14 | 15 | setHook({ 16 | '1.0.0': { 17 | [0x800c0918 - 0x80004000]: mainHandler, // line + name 18 | [0x80070b98 - 0x80004000]: mainHandler, // fast trophy 19 | [0x800878fc - 0x80004000]: mainHandler, // prompt 20 | [0x80087aa0 - 0x80004000]: mainHandler // choice 21 | } 22 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 23 | 24 | function handler(regs) { 25 | const address = regs[0].value; // x0 26 | 27 | console.log('onEnter'); 28 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | 30 | let s = address.readUtf8String() 31 | .replace(/㊤|㊥/g, '―') 32 | .replace(/^㌻/g, ' ') // \n 33 | ; 34 | 35 | return s; 36 | } -------------------------------------------------------------------------------- /NS_0100DA101D9AA000_Utsusemi_no_Meguri.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100DA101D9AA000] Utsusemi no Meguri 3 | // @version 1.0.0 4 | // @author GO123 5 | // @description Yuzu 6 | // * Matatabi 7 | // * Unity 8 | // ==/UserScript== 9 | trans.replace(function (s) { 10 | return s 11 | .replaceAll("\n", '') 12 | 13 | ; 14 | }); 15 | const gameVer = '1.0.0'; 16 | 17 | const { setHook } = require('./libYuzu.js'); 18 | const mainHandler = trans.send(handler, '200+'); 19 | 20 | setHook({ 21 | '1.0.0': { 22 | [0x821b452c - 0x80004000]: mainHandler.bind_(null, 0, 0), // text1 23 | [0x821b456c - 0x80004000]: mainHandler.bind_(null, 0, 0), // text2 24 | [0x821b45ac - 0x80004000]: mainHandler.bind_(null, 0, 0), // text3 25 | } 26 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 27 | 28 | function handler(regs, index, offset) { 29 | console.log('onEnter'); 30 | const address = regs[index].value.add(offset); // x0 31 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 32 | const len = address.add(0x10).readU32() * 2; 33 | let s = address.add(0x14).readUtf16String(len); 34 | return s; 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /NS_0100DA201E0DA000_Akuyaku_Reijou_wa_Ringoku_no_Outaishi_ni_Dekiai_Sareru.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100DA201E0DA000] Akuyaku Reijou wa Ringoku no Outaishi ni Dekiai Sareru 3 | // @version 1.0.0 4 | // @author [GO123] 5 | // @description Yuzu 6 | // *OperaHouse 7 | // * 8 | // ==/UserScript== 9 | trans.replace(function (s) { 10 | return s 11 | .replaceAll(/[\s]/g, '') 12 | ; 13 | }); 14 | const gameVer = '1.0.0'; 15 | 16 | const { setHook } = require('./libYuzu.js'); 17 | const mainHandler = trans.send(handler, '200+'); 18 | 19 | setHook({ 20 | '1.0.0': { 21 | [0x817b35c4 - 0x80004000]: mainHandler.bind_(null, 1, "Dialogue"), // Dialogue 22 | } 23 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 24 | 25 | function handler(regs, index, hookname) { 26 | //console.log('onEnter ' + hookname); 27 | 28 | const address = regs[index].value; 29 | 30 | /* processString */ 31 | let s = address.readUtf8String(); 32 | 33 | return s; 34 | } 35 | -------------------------------------------------------------------------------- /NS_0100DCD01525A000_Persona_3_Portable.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100DCD01525A000] Persona 3 Portable 3 | // @version 1.0.0 4 | // @author Koukdw & [DC] 5 | // @description Yuzu 6 | // * Atlus 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const { readString, createTable } = require('./libPCAtlus.js'); 13 | 14 | const mainHandler = trans.send(handler, '200+'); // join 200ms 15 | const table = createTable('P3P'); 16 | table[0xa] = ' '; // single line 17 | 18 | setHook({ 19 | '1.0.0': { 20 | [0x801b9a00 - 0x80004000]: mainHandler 21 | } 22 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 23 | 24 | function handler(regs) { 25 | const type = regs[1].value & 0xFFFF; 26 | //console.log(ptr(this.returnAddress) + ' ' + type); 27 | if (type === 3) return null; 28 | 29 | const address = regs[0].value; 30 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 31 | const s = readString(address, table); 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_0100DE200C0DA000_Yunohana Spring! ~Mellow Times~.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100DE200C0DA000] Yunohana Spring! ~Mellow Times~ 3 | // @version 1.0.0 4 | // @author [Hiyo] 5 | // @description Yuzu 6 | // * Idea Factory Co., Ltd. / Otomate 7 | 8 | // ==/UserScript== 9 | 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | 14 | const mainHandler = trans.send(handler, '200+'); // join 200ms 15 | 16 | setHook({ 17 | '1.0.0': { 18 | [0x80028178 - 0x80004000]: mainHandler.bind_(null, 0, "name"), 19 | [0x8001b9d8 - 0x80004000]: mainHandler.bind_(null, 2, "dialogue1"), 20 | [0x8001b9b0 - 0x80004000]: mainHandler.bind_(null, 2, "dialogue2"), 21 | [0x8004b940 - 0x80004000]: mainHandler.bind_(null, 2, "dialogue3"), 22 | [0x8004a8d0 - 0x80004000]: mainHandler.bind_(null, 1, "choice"), 23 | } 24 | 25 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 26 | 27 | function handler(regs, index, hookname) { 28 | const address = regs[index].value; 29 | 30 | let s = address.readUtf8String() 31 | .replace('\n', ' ') 32 | .replace('#n', ' ') 33 | ; 34 | 35 | return s; 36 | } -------------------------------------------------------------------------------- /NS_0100E1E00E2AE000_Hakuouki_Shinkai_Tsukikage_no_Shou.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100E1E00E2AE000] Hakuouki Shinkai: Tsukikage no Shou / 薄桜鬼 真改 月影ノ抄 3 | // @version 1.0.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * アイディアファクトリー株式会社 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x8019ecd0 - 0x80004000]: mainHandler.bind_(null, 1, "Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs, index, hookname) { 21 | const address = regs[index].value; 22 | // console.log('onEnter: ' + hookname); 23 | 24 | /* processString */ 25 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 26 | let s = address.readUtf8String(); 27 | 28 | s = s 29 | .replace(/#n/g, '\n') // Replace #n for line breaks 30 | .replace(/[A-Za-z0-9]/g, '') // Remove letters and numbers 31 | .replace(/[~^,\-\[\]#]/g, ''); // Remove specified symbols 32 | 33 | return s; 34 | } -------------------------------------------------------------------------------- /NS_0100E4000F616000_Himehibi_Another_Princess_Days_White_or_Black.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100E4000F616000] Himehibi Another Princess Days -White or Black- (ひめひび Another Princess Days – White or Black –) 3 | // @version 1.0.0 4 | // @author Mansive 5 | // @description Ryujinx 6 | // * TAKUYO 7 | // ==/UserScript== 8 | const gameVer = "1.0.0"; 9 | 10 | globalThis.ARM = true; 11 | const { setHook } = require("./libYuzu.js"); 12 | 13 | const mainHandler = trans.send(handler, "200+"); 14 | 15 | setHook( 16 | { 17 | "1.0.0": { 18 | // [0x21ca64 - 0x204000]: mainHandler.bind_(null, 4, "name"), 19 | [0x219ed0 - 0x204000]: mainHandler.bind_(null, 0, "text"), 20 | [0x21a3e0 - 0x204000]: mainHandler.bind_(null, 0, "choice"), 21 | }, 22 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 23 | ); 24 | 25 | function handler(regs, index, hookname) { 26 | const address = regs[index].value; 27 | 28 | // console.log("onEnter: ", hookname); 29 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 30 | 31 | let s = address 32 | .readShiftJisString() 33 | // .replace(/@\w+|^\s+|\s+$/g, "") // cleanup name 34 | .replace(/\\\w/g, ""); 35 | 36 | return s; 37 | } 38 | -------------------------------------------------------------------------------- /NS_0100E5200D1A2000_Kaeru_Batake_DE_Tsukamaete.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100E5200D1A2000] Kaeru Batake DE Tsukamaete☆ (カエル畑DEつかまえて☆彡) 3 | // @version 1.0.0 4 | // @author kenzy 5 | // @description Yuzu/Sudachi, Ryujinx 6 | // * TAKUYO 7 | // ==/UserScript== 8 | const gameVer = '1.0.0'; 9 | 10 | globalThis.ARM = true; 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x2206bc - 0x204000]: mainHandler.bind_(null, 0, "text"), // dialogue + names 17 | [0x220cfc - 0x204000]: mainHandler.bind_(null, 0, "choices"), 18 | [0x2372b0 - 0x204000]: mainHandler.bind_(null, 1, "game"), // eco question 19 | } 20 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 21 | 22 | function handler(regs, index, hookname) { 23 | const reg = regs[index]; 24 | const address = reg.value; 25 | 26 | /* processString */ 27 | let s = address.readShiftJisString(); 28 | s = s 29 | .replace(/(\\n)+/g, ' ') 30 | .replace(/\\d$|^\@[a-z]+|#.*?#|\$/g, '') 31 | .replace(/\u3000+/gu, '') 32 | 33 | if (hookname === "choices") { 34 | s = s.replace(/, ?\w+/g, ''); 35 | } 36 | 37 | return s; 38 | } 39 | -------------------------------------------------------------------------------- /NS_0100EC001DE7E000_Hiiro_no_Kakera_Tamayorihime_Kitan_Omoiiro_no_Kioku.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100EC001DE7E000] Hiiro_no_Kakera_Tamayorihime_Kitan_Omoiiro_no_Kioku 3 | // @version 1.0.0 4 | // @author GO123 5 | // @description Ryujinx 6 | // * Design Factory Co., Ltd. & Otomate 7 | // *Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | trans.replace(function (s) { 10 | return s 11 | .replaceAll(/<\w+=[^>]+>|<\/\w+>/g, '') 12 | 13 | ; 14 | }); 15 | const gameVer = '1.0.0'; 16 | 17 | const { setHook } = require('./libYuzu.js'); 18 | const mainHandler = trans.send(handler, '200++'); 19 | 20 | setHook({ 21 | '1.0.0': { 22 | [0x81922ce8 - 0x80004000]: mainHandler.bind_(null, 0, "Dialogue text"), 23 | 24 | 25 | } 26 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 27 | 28 | function handler(regs, index, hookname) { 29 | 30 | 31 | const address = regs[index].value; 32 | //console.log("onEnter: " + hookname); 33 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 34 | 35 | /* processString */ 36 | let s = address.add(0x14).readUtf16String() 37 | 38 | return s; 39 | } 40 | -------------------------------------------------------------------------------- /NS_0100EFE0159C6000_Kaeru_Batake_DE_ Tsukamaete_Natsu_Chigira_Sansen.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100EFE0159C6000] Kaeru Batake DE Tsukamaete: Natsu Chigira Sansen! (カエル畑DEつかまえて・夏 千木良参戦!) 3 | // @version 1.0.0 4 | // @author kenzy 5 | // @description Yuzu/Sudachi, Ryujinx 6 | // * TAKUYO 7 | // ==/UserScript== 8 | 9 | const gameVer = '1.0.0'; 10 | 11 | globalThis.ARM = true; 12 | const { setHook } = require('./libYuzu.js'); 13 | const mainHandler = trans.send(handler, '200+'); 14 | 15 | setHook({ 16 | '1.0.0': { 17 | [0x2210d0 - 0x204000]: mainHandler.bind_(null, 0, "text"), // dialogue + names 18 | [0x221768 - 0x204000]: mainHandler.bind_(null, 0, "choices"), 19 | } 20 | 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs, index, hookname) { 24 | const reg = regs[index]; 25 | const address = reg.value; 26 | 27 | /* processString */ 28 | let s = address.readShiftJisString(); 29 | s = s 30 | .replace(/(\\n)+/g, ' ') 31 | .replace(/\\d$|^\@[a-z]+|#.*?#|\$/g, '') 32 | .replace(/\u3000+/gu, '') 33 | .replace(/@w|\\c/g, ''); 34 | 35 | if (hookname === "choices") { 36 | s = s.replace(/, ?\w+/g, ''); 37 | } 38 | 39 | return s; 40 | } 41 | -------------------------------------------------------------------------------- /NS_0100F3400332C000_Xenoblade_Chronicles_2.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100F3400332C000] Xenoblade Chronicles 2 3 | // @version 2.0.2 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * Monolith Soft, Nintendo 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '2.0.2'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '2.0.2': { 16 | [0x8010b180 - 0x80004000]: mainHandler.bind_(null, 1, "Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | console.log(` 21 | * This script is only for the main text (cutscenes + press to continue text). 22 | 23 | * Any other elements like tutorials, objectives, menu text, etc., could not be captured. 24 | 25 | * Try using an OCR for those parts. 26 | `); 27 | 28 | function handler(regs, index, hookname) { 29 | const address = regs[index].value; 30 | // console.log('onEnter: ' + hookname); 31 | 32 | /* processString */ 33 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 34 | let s = address.readUtf8String(); 35 | 36 | s = s.replace(/\[.*?\]/g, '') // Remove anything inside [] 37 | 38 | return s; 39 | } -------------------------------------------------------------------------------- /NS_0100F4800F872000_Prison_Princess.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100F4800F872000] Prison Princess 3 | // @version 1.0.0 4 | // @author [kinyarou] 5 | // @description Yuzu 6 | // * PROTOTYPE 7 | // * 8 | // 9 | // ==/UserScript== 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | const mainHandler = trans.send(handler, '200+'); 14 | 15 | setHook({ 16 | '1.0.0': { 17 | [0x800eba00 - 0x80004000]: mainHandler 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | function handler(regs) { 22 | return regs[2].value.add(0x14).readUtf16String(); 23 | } -------------------------------------------------------------------------------- /NS_0100F7401AA74000_Getsuei_no_Kusari_Sakuran_Paranoia.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100F7401AA74000] Getsuei no Kusari -Sakuran Paranoia- 3 | // @version 1.0.0 4 | // @author GO123 5 | // @description Yuzu 6 | // * TAKUYO 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | 12 | globalThis.ARM = true; 13 | const { setHook } = require('./libYuzu.js'); 14 | const mainHandler = trans.send(handler, '200+'); 15 | 16 | // I don't know if those scripts have been done before the tracer fix so if there's a problem multiply the register by 2 17 | // Old tracer assumed the register were 64bit which was wrong 18 | setHook({ 19 | '1.0.0': { 20 | [0x21801c - 0x204000]: mainHandler.bind_(null, 2, "text"), 21 | [0x228fac - 0x204000]: mainHandler.bind_(null, 1, "choices"), 22 | [0x267f24 - 0x204000]: mainHandler.bind_(null, 1, "dictionary"), 23 | } 24 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 25 | 26 | 27 | function handler(regs, index, hookname) { 28 | const reg = regs[index]; 29 | const address = reg.value; 30 | /* processString */ 31 | const s = address.readShiftJisString() 32 | .replaceAll(/[\s]/g, '') 33 | .replaceAll(/@[a-z]/g, "") 34 | .replaceAll(/@[0-9]/g, "") 35 | ; 36 | 37 | return s; 38 | } 39 | -------------------------------------------------------------------------------- /NS_0100F8A017BAA000_Sen _no _Hatou_Tsukisome _no _Kouki.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100F8A017BAA000] Sen no Hatou, Tsukisome no Kouki 3 | // @version 1.0.0 4 | // @author GO123 5 | // @description Yuzu 6 | // * AUGUST & ARIA & ENTERGRAM 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200++'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x8003fc90 - 0x80004000]: mainHandler.bind_(null, 1, 0), // text1 17 | [0x8017a740 - 0x80004000]: mainHandler.bind_(null, 0, 0), // text2 18 | 19 | // [0x8017a61c - 0x80004000]: mainHandler, //with no text at top 20 | 21 | } 22 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 23 | 24 | function handler(regs, index, offset) { 25 | console.log('onEnter'); 26 | 27 | const address = regs[index].value.add(offset); 28 | 29 | /* processString */ 30 | let s = address.readUtf8String() 31 | 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS_0100FA001E160000_7scarlet.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100FA001E160000] 7'scarlet 3 | // @version 1.0.0 4 | // @author Mansive 5 | // @description Yuzu, Ryujinx 6 | // * Otomate & Toybox Inc. 7 | // * Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const gameVer = "1.0.0"; 10 | 11 | const { setHook } = require("./libYuzu.js"); 12 | 13 | const mainHandler = trans.send(handler, "200+"); 14 | 15 | setHook( 16 | { 17 | "1.0.0": { 18 | [0x8177ec00 - 0x80004000]: mainHandler.bind_(null, 0, "text"), 19 | [0x817754ac - 0x80004000]: mainHandler.bind_(null, 0, "choices"), 20 | }, 21 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 22 | ); 23 | 24 | function handler(regs, index, hookname) { 25 | const address = regs[index].value; 26 | 27 | // console.log("onEnter: " + hookname); 28 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | 30 | let s = address 31 | .add(0x14) 32 | .readUtf16String() 33 | .replace(/\r\n/g, "") 34 | .replace(/\u3000/gu, ""); 35 | 36 | return s; 37 | } 38 | -------------------------------------------------------------------------------- /NS_0100FB7019ADE000_Kanon.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100FB7019ADE000] Kanon 3 | // @version 1.0.0 4 | // @author [kinyarou] 5 | // @description Yuzu 6 | // * PROTOTYPE 7 | // * 8 | // 9 | // ==/UserScript== 10 | const gameVer = '1.0.0'; 11 | 12 | const { setHook } = require('./libYuzu.js'); 13 | const mainHandler = trans.send(handler, '200+'); 14 | 15 | let nEnter = 0; 16 | 17 | setHook({ 18 | '1.0.0': { 19 | [0x800dc524 - 0x80004000]: mainHandler 20 | } 21 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 22 | 23 | function handler(regs) { 24 | console.log('onEnter'); 25 | if ((++nEnter) % 2 == 1) return null; 26 | return regs[0].value.readUtf16String(); 27 | } -------------------------------------------------------------------------------- /NS_0100FC2019346000_Princess_Arthur.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100FC2019346000] Princess Arthur 3 | // @version 1.0.0 4 | // @author [GO123] 5 | // @description Yuzu 6 | // * Design Factory Co., Ltd. & Otomate 7 | //* 8 | // ==/UserScript== 9 | const gameVer = '1.0.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200++'); 13 | 14 | setHook({ 15 | '1.0.0': { 16 | [0x80066e10 - 0x80004000]: mainHandler.bind_(null, 2, "Dialogue text"), // Dialogue text 17 | [0x8001f7d0 - 0x80004000]: mainHandler.bind_(null, 0, "Name"),// name 18 | } 19 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 20 | 21 | function handler(regs, index, hookname) { 22 | //console.log('onEnter ' + hookname); 23 | 24 | const address = regs[index].value; 25 | 26 | /* processString */ 27 | let s = address.readShiftJisString(); 28 | s = s.replace(/#n/g,'') ; 29 | 30 | 31 | return s; 32 | } 33 | -------------------------------------------------------------------------------- /NS_0100FDB00AA80000_Layton’s_Mystery_Journey.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [0100FDB00AA80000] Layton’s Mystery Journey: Katrielle and the Millionaires’ Conspiracy 3 | // @version 1.1.0 4 | // @author [Kalleo] 5 | // @description Yuzu 6 | // * LEVEL-5 7 | // * 8 | // ==/UserScript== 9 | const gameVer = '1.1.0'; 10 | 11 | const { setHook } = require('./libYuzu.js'); 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | '1.1.0': { 16 | [0x8025d520 - 0x80004000]: mainHandler.bind_(null, 2, "All Text"), 17 | } 18 | }[globalThis.gameVer = globalThis.gameVer ?? gameVer]); 19 | 20 | function handler(regs, index, hookname) { 21 | const address = regs[index].value; 22 | // console.log('onEnter: ' + hookname); 23 | 24 | /* processString */ 25 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 26 | let s = address.readShiftJisString(); 27 | 28 | s = s 29 | .replace(/\[([^\]]+)\/[^\]]+\]/g, '$1') // Remove furigana ex: [腕/うで] 30 | .replace(/<[^>]*>/g, ''); // Remove HTML tags 31 | 32 | return s; 33 | } -------------------------------------------------------------------------------- /NS__Ryujinx.js: -------------------------------------------------------------------------------- 1 | globalThis.gameVer = null; 2 | const ns = require('./libRyujinx.js'); 3 | 4 | const scripts = Agent.getScripts(); 5 | 6 | ns.onBoot((info) => { 7 | console.log("\r\n\x1b[1;32m---Nintendo Switch Text Hooker---\x1B[0m\r\n"); 8 | console.log('Target: ' + info.titleId); 9 | 10 | globalThis.gameVer = null; // reset 11 | const script = findScriptByTitleId(info.titleId); 12 | if (script) { 13 | console.log("\x1B[32mFound script: " + script.name + '\x1b[0m'); 14 | Agent.setTargetID(script.fullPath); // WS exSTATic, sessionStorage 15 | require(script.fullPath); 16 | return; 17 | } 18 | 19 | console.warn("Script not found, perform pattern scan..."); 20 | const nss = getPatternScripts(); 21 | for (let i = 0; i < nss.length; i++) { 22 | const script = nss[i]; 23 | console.log('- ' + script.name); 24 | const hook = require(script.fullPath)(info.modules); 25 | if (hook) { 26 | ns.setHook(hook, null); 27 | } 28 | } 29 | 30 | if (ns.count() === 0) { 31 | console.error("Error: No hook found!"); 32 | } 33 | }); 34 | 35 | function findScriptByTitleId(titleId) { return scripts.find(v => v.name.includes(titleId)); } 36 | function getPatternScripts() { return scripts.filter(v => v.name.startsWith('libNS') === true); } -------------------------------------------------------------------------------- /PC_Flash_Rondo_Duo.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Rondo Duo -Yoake no Fortissimo- Punyu Puri ff 3 | // @version 4 | // @author [DC] 5 | // @description 6 | // * TinkleBell 7 | // * Adobe Flash 8 | // 9 | // https://vndb.org/v16266 10 | // ==/UserScript== 11 | 12 | const { setHook } = require('./libFlash.js'); 13 | 14 | const ptrSize = Process.pointerSize; 15 | const mainHandler = trans.send(handler, '200+'); 16 | 17 | setHook({ 18 | 'AS.StoryObj.MsgWin::MsgArea/ShowMsg': mainHandler 19 | }); 20 | 21 | function handler(args) { 22 | const argx = args[2]; // env, argc, args 23 | console.log('onEnter ShowMsg'); 24 | const address = argx.add(ptrSize).readPointer(); // get args[0]; (this call?) 25 | 26 | const s = address.readFlashString(); 27 | return s; 28 | } 29 | 30 | /* OR */ 31 | 32 | // const ptrSize = Process.pointerSize; 33 | // const mainHandler = trans.send(s => s, '200+'); 34 | 35 | // setHook('AS.StoryObj.MsgWin::MsgArea/ShowMsg', function (args) { 36 | // const argx = args[2]; 37 | // console.log('onEnter ShowMsg'); 38 | 39 | // const address = argx.add(4).readPointer(); 40 | // const s = address.readFlashString(); 41 | 42 | // mainHandler(s); 43 | // }); -------------------------------------------------------------------------------- /PC_InnocentGrey_FLOWERS_Le_volume_sur_automne.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name FLOWERS -Le volume sur automne- 3 | // @version 4 | // @author [DC] 5 | // @description Autumn 6 | // * Innocent Grey 7 | // * 8 | // 9 | // https://vndb.org/v18152 10 | // ==/UserScript== 11 | require('./PC_InnocentGrey_FLOWERS_Le_volume_sur_printemps.js') -------------------------------------------------------------------------------- /PC_InnocentGrey_FLOWERS_Le_volume_sur_ete.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name FLOWERS -Le volume sur été- 3 | // @version 4 | // @author [DC] 5 | // @description Summer 6 | // * Innocent Grey 7 | // * 8 | // 9 | // https://vndb.org/v15395 10 | // ==/UserScript== 11 | require('./PC_InnocentGrey_FLOWERS_Le_volume_sur_printemps.js') -------------------------------------------------------------------------------- /PC_InnocentGrey_FLOWERS_Le_volume_sur_hiver.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name FLOWERS -Le volume sur hiver- 3 | // @version 4 | // @author [DC] 5 | // @description Winter 6 | // * Innocent Grey 7 | // * 8 | // 9 | // https://vndb.org/v19545 10 | // ==/UserScript== 11 | require('./PC_InnocentGrey_FLOWERS_Le_volume_sur_printemps.js') -------------------------------------------------------------------------------- /PC_Malie_Dies_Irae_Interview_with_Kaziklu_Bey.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Dies irae ~Interview with Kaziklu Bey~ 3 | // @version 4 | // @author Koukdw 5 | // @description 6 | // * 7 | // * Malie 8 | // 9 | // ==/UserScript== 10 | require('./PC_Malie_Dies_Irae_Acta_est_Fabula.js'); -------------------------------------------------------------------------------- /PC_Steam_Air.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name AIR 3 | // @version 1.0.0.0 4 | // @author [logantgt] 5 | // @description Steam 6 | // * KEY/LUCA System 7 | // 8 | // https://store.steampowered.com/app/2983250/AIR/ 9 | // ==/UserScript== 10 | 11 | const __e = Process.enumerateModules()[0]; 12 | const handler = trans.send(s => s, -200); 13 | 14 | // Filter out @ symbols around character names 15 | trans.replace(function (s) { 16 | return s.replaceAll(/\@/g, ''); 17 | }); 18 | 19 | (function () { 20 | attach('DialogueHook', '0F B7 ?? 8D ?? ?? 66 ?? ?? ?? 8D ?? ?? 66 0F 47 CA 0F B7 ?? ?? ?? ?? 0F 94 C0 C3', 'r11'); 21 | 22 | function attach(name, pattern, register) { 23 | const results = Memory.scanSync(__e.base, __e.size, pattern); 24 | if (results.length === 0) { 25 | console.error(`[${name}] Hook not found!`); 26 | return false; 27 | } 28 | 29 | let address = results[0].address; 30 | console.log(`\x1b[32m[${name}] Found hook ${address}\x1b[0m`); 31 | if (results.length > 1) { 32 | console.warn(`[${name}] has ${results.length} results`); 33 | } 34 | 35 | Interceptor.attach(address, function (args) { 36 | const text = this.context[register].readUtf16String(); 37 | handler(text); 38 | }); 39 | } 40 | })(); -------------------------------------------------------------------------------- /PC_Steam_Chrono_Trigger.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name CHRONO TRIGGER 3 | // @version 0.1 4 | // @author [blacktide082] 5 | // @description Steam 6 | // * Square Enix 7 | // 8 | // https://store.steampowered.com/app/613830/CHRONO_TRIGGER/ 9 | // ==/UserScript== 10 | 11 | const __e = Process.enumerateModules()[0]; 12 | const handler = trans.send(s => s, '100+'); 13 | 14 | (function () { 15 | const pattern = '55 8B ?? 8B ?? ?? 53 8B ?? ?? 56 8B ?? C7'; 16 | const results = Memory.scanSync(__e.base, __e.size, pattern); 17 | if (results.length === 0) { 18 | console.error('[DialoguePattern] Hook not found!'); 19 | return; 20 | } 21 | 22 | const address = results[0].address; 23 | console.log('[DialoguePattern] Found hook', address); 24 | Interceptor.attach(address, function (args) { 25 | const text = this.context.eax.readUtf8String() 26 | .replaceAll('\\', '') 27 | .replace(/\s+/g, '') 28 | .replace(/.+?<\/C[0-9]>/g, '') 29 | .replaceAll('', '') 30 | .replaceAll('', '\n'); 31 | handler(text); 32 | }); 33 | })(); 34 | -------------------------------------------------------------------------------- /PC_Steam_Danganronpa_2_Goodbye_Despair.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Danganronpa 2: Goodbye Despair 3 | // @version 0.1 4 | // @author [blacktide082] 5 | // @description Steam 6 | // * Spike Chunsoft 7 | // 8 | // https://store.steampowered.com/app/413420/Danganronpa_2_Goodbye_Despair/ 9 | // ==/UserScript== 10 | 11 | const __e = Process.enumerateModules()[0]; 12 | const handler = trans.send(s => s, '200++'); // join lines 13 | 14 | (function () { 15 | const dialogSig = '66 ?? ?? C1 ?? ?? 03 ?? 66 ?? ?? ?? ???????? 80 ?? ?? 75 ?? 8A ?? ?? 80'; 16 | const results = Memory.scanSync(__e.base, __e.size, dialogSig); 17 | if (results.length === 0) { 18 | console.error('[DialoguePattern] Hook not found!'); 19 | return; 20 | } 21 | 22 | let text = ''; 23 | const address = results[0].address; 24 | console.log('[DialoguePattern] Found hook', address); 25 | 26 | Interceptor.attach(address, function (args) { 27 | const value = this.context.esi.readUtf16String() 28 | .replace(//g, '') 29 | .replaceAll('\n', '') 30 | .trim(); 31 | if (!text.endsWith(value)) { 32 | text = value; 33 | handler(text); 34 | } 35 | }); 36 | })(); 37 | -------------------------------------------------------------------------------- /PC_Steam_Danganronpa_Another_Episode_Ultra_Despair_Girls.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Danganronpa Another Episode: Ultra Despair Girls 3 | // @version 0.1 4 | // @author [blacktide082] 5 | // @description Steam 6 | // * Spike Chunsoft 7 | // 8 | // https://store.steampowered.com/app/555950/Danganronpa_Another_Episode_Ultra_Despair_Girls/ 9 | // ==/UserScript== 10 | 11 | const __e = Process.enumerateModules()[0]; 12 | const handler = trans.send(s => s, '100+'); 13 | 14 | (function () { 15 | const dialogSig = '66 ?? ?? ?? ?? 8B ?? ???????? 01 ?? ???????? 0F?? ?? ?? ?? EB'; 16 | const results = Memory.scanSync(__e.base, __e.size, dialogSig); 17 | if (results.length === 0) { 18 | console.error('[DialoguePattern] Hook not found!'); 19 | return; 20 | } 21 | 22 | const address = results[0].address; 23 | console.log('[DialoguePattern] Found hook', address); 24 | 25 | let timeout = 0; 26 | let previous = ' '; 27 | Interceptor.attach(address, function (args) { 28 | const text = args[3].readUtf16String() 29 | .replace(/#[Rl][0-9]+[#\.]{0,2}/g, '') 30 | .replace(/\s+/g, ''); 31 | if (previous.startsWith(text)) return; 32 | previous = text; 33 | clearTimeout(timeout); 34 | timeout = setTimeout(() => handler(text), 100); 35 | }); 36 | })(); 37 | -------------------------------------------------------------------------------- /PC_Steam_Danganronpa_Trigger_Happy_Havoc.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Danganronpa: Trigger Happy Havoc 3 | // @version 0.1 4 | // @author [blacktide082] 5 | // @description Steam 6 | // * Spike Chunsoft 7 | // 8 | // https://store.steampowered.com/app/413410/Danganronpa_Trigger_Happy_Havoc/ 9 | // ==/UserScript== 10 | 11 | const __e = Process.enumerateModules()[0]; 12 | const handler = trans.send(s => s, '200+'); 13 | 14 | (function () { 15 | const dialogSig = '89 ?? ?? 89 ?? ?? 8D ?? ?? ???????? 0FB7 ?? 83 ?? ?? 75 ?? 8B'; 16 | const results = Memory.scanSync(__e.base, __e.size, dialogSig); 17 | if (results.length === 0) { 18 | console.error('[DialoguePattern] Hook not found!'); 19 | return; 20 | } 21 | 22 | let text = ''; 23 | const address = results[0].address.add(0xD); 24 | console.log('[DialoguePattern] Found hook', address); 25 | 26 | Interceptor.attach(address, function (args) { 27 | const value = this.context.ecx.readUtf16String() 28 | .replace(//g, '') 29 | .replaceAll('\n', '') 30 | .trim(); 31 | if (!text.endsWith(value)) { 32 | text = value; 33 | handler(text); 34 | } 35 | }); 36 | })(); 37 | -------------------------------------------------------------------------------- /PC_Steam_Hyperdimension_Neptunia_ReBirth2_Sisters_Generation.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Hyperdimension Neptunia Re;Birth2: Sisters Generation 3 | // @version 4 | // @author Tom (tomrock645) 5 | // @description Steam 6 | // * developer Idea Factory, Compile Heart 7 | // * publisher Idea Factory, Compile Heart 8 | // 9 | // https://store.steampowered.com/app/351710/Hyperdimension_Neptunia_ReBirth2_Sisters_Generation/ 10 | // ==/UserScript== 11 | 12 | 13 | require('./PC_Steam_Hyperdimension_Neptunia_ReBirth1.js'); -------------------------------------------------------------------------------- /PC_Steam_KiriKiriZ_9-nine.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name 9-nine-:Episode * 3 | // @version 4 | // @author [DC] 5 | // @description [PC] https://store.steampowered.com/app/976390/9nineEpisode_1/ 6 | // * KiriKiriZ Engine 7 | // ==/UserScript== 8 | const engine = require('./libPCKiriKiriZ.js'); 9 | 10 | engine.hookTextrenderDll(function(s) { 11 | trans.send(s); 12 | return s; 13 | }); -------------------------------------------------------------------------------- /PC_Steam_KiriKiriZ_Marco_&_The_Galaxy_Dragon.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Marco & The Galaxy Dragon 3 | // @version 0.1 4 | // @author [blacktide082] 5 | // @description Steam 6 | // * TOKYOTOON 7 | // * KiriKiriZ 8 | // * tested on ver1.10 9 | // 10 | // https://store.steampowered.com/app/1202540/Marco__The_Galaxy_Dragon/ 11 | // ==/UserScript== 12 | 13 | const engine = require('./libPCKiriKiriZ.js'); 14 | const handler = trans.send((s) => s.trim(), '200+'); 15 | engine.hookTextrenderDll(handler); 16 | -------------------------------------------------------------------------------- /PC_Steam_KiriKiriZ_Tsuyuchiru_Letter_Umi_to_Shiori_ni_Amaoto_o.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name ツユチル・レター~海と栞に雨音を~ / Letters From a Rainy Day -Oceans and Lace- 3 | // @version 4 | // @author Tom (tomrock645) 5 | // @description Steam 6 | // * Developer Lily Spinel 7 | // * Publisher HUBLOTS, mirai works 8 | // * Engine KiriKiriZ 9 | // 10 | // https://store.steampowered.com/app/1637370/Letters_From_a_Rainy_Day_Oceans_and_Lace/ 11 | // ==/UserScript== 12 | 13 | 14 | const engine = require('./libPCKiriKiriZ.js'); 15 | 16 | engine.hookTextrenderDll(function (text) { 17 | trans.send(text); 18 | return text; 19 | }); -------------------------------------------------------------------------------- /PC_Steam_MAGES_Memories_Off_-Innocent_Fille-.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Memories Off: -Innocent Fille- 3 | // @version 0.1 4 | // @author [DC] 5 | // @description [PC] https://store.steampowered.com/app/738510/Innocent_Fille/ 6 | // * MAGES Engine 7 | // ==/UserScript== 8 | require('./PC_Steam_MAGES_Steins;Gate-0.js'); -------------------------------------------------------------------------------- /PC_Steam_MAGES_Memories_Off_-Innocent_Fille-_for_Dearest.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Memories Off: -Innocent Fille- for Dearest 3 | // @version 0.1 4 | // @author [DC] 5 | // @description [PC] https://store.steampowered.com/app/1200110/Innocent_Fille_for_Dearest/ 6 | // * MAGES Engine 7 | // ==/UserScript== 8 | require('./PC_Steam_MAGES_Steins;Gate-0.js'); -------------------------------------------------------------------------------- /PC_Steam_MAGES_Memories_Off_Historia.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Memories Off Historia 3 | // @version 0.1 4 | // @author MSBBoy 5 | // @description [PC] https://store.steampowered.com/bundle/37122/Memories_Off_Historia/ 6 | // * MAGES Engine 7 | // ==/UserScript== 8 | require('./PC_Steam_MAGES_Steins;Gate-0.js'); 9 | -------------------------------------------------------------------------------- /PC_Steam_Muv_Luv.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Muv-Luv (マブラヴ) 3 | // @version 0.1 4 | // @author [blacktide082] 5 | // @description Steam 6 | // * aNCHOR Inc. 7 | // 8 | // https://store.steampowered.com/app/802880/MuvLuv/ 9 | // ==/UserScript== 10 | 11 | const __e = Process.enumerateModules()[0]; 12 | const handler = trans.send(s => s, '200+'); 13 | 14 | (function () { 15 | var dialogSig = '8B ?? ?? 8D ?? ?? 89 ?? ?? 0FB7 ?? 8D ?? ?? 85 ?? 0F84 ???????? 83'; 16 | const results = Memory.scanSync(__e.base, __e.size, dialogSig); 17 | if (results.length === 0) { 18 | console.error('[DialoguePattern] Hook not found!'); 19 | return; 20 | } 21 | 22 | const address = results[0].address.add(0xC); 23 | console.log('[DialoguePattern] Found hook', address); 24 | 25 | Interceptor.attach(address, function (args) { 26 | const text = this.context.eax.readUtf16String() 27 | .replaceAll('\u0001', '') // remove unicode Start of Text characters 28 | .replaceAll('\u0003', '') // remove unicode End of Text characters 29 | .replaceAll('\n', '') 30 | .trim(); 31 | 32 | // skip blank lines 33 | if (text === '') return; 34 | 35 | handler(text); 36 | }); 37 | })(); 38 | -------------------------------------------------------------------------------- /PC_Steam_Unity_AI_The_Somnium_Files.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name AI: The Somnium Files 3 | // @version 0.1 4 | // @author [blacktide082] 5 | // @description Steam 6 | // * Spike Chunsoft 7 | // * Unity (JIT) 8 | // 9 | // https://store.steampowered.com/app/948740/AI_The_Somnium_Files/ 10 | // ==/UserScript== 11 | 12 | const Mono = require('./libMono.js'); 13 | const handler = trans.send(s => s, '200+'); 14 | 15 | Mono.setHook('', 'Game.TextController', 'SetNextLine', 1, { 16 | onEnter(args) { 17 | const text = args[1] 18 | .readMonoString() 19 | .split('\n') 20 | .map(t => t.trim()) 21 | .join('') 22 | // handle button/keys 23 | .replace(//g, '{$1}') 24 | // remove any remaining HTML tags 25 | .replace(/<.*?>/g, ''); 26 | handler(text); 27 | } 28 | }); 29 | -------------------------------------------------------------------------------- /PC_Steam_Unity_AI_The_Somnium_Files_-_nirvanA_Initiative.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name AI: THE SOMNIUM FILES - nirvanA Initiative 3 | // @version 0.1 4 | // @author [blacktide082] 5 | // @description Steam 6 | // * Spike Chunsoft 7 | // * Unity (IL2CPP) 8 | // 9 | // https://store.steampowered.com/app/1449200/AI_THE_SOMNIUM_FILES__nirvanA_Initiative/ 10 | // ==/UserScript== 11 | 12 | require('./PC_Steam_Unity_AI_The_Somnium_Files.js'); 13 | -------------------------------------------------------------------------------- /PC_Steam_Unity_AOISHIRO.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name AOISHIRO 3 | // @version 4 | // @author emilybrooks 5 | // @description Steam 6 | // * SUCCESS Corp. 7 | // * Unity (JIT) 8 | // 9 | // https://store.steampowered.com/app/2097750/AOISHIRO_HD_REMASTER/ 10 | // ==/UserScript== 11 | require('./PC_Steam_Unity_AKAIITO.js') 12 | -------------------------------------------------------------------------------- /PC_Steam_Unity_Hayaski_no_Kuroyuri.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Hayasaki no Kuroyuri 3 | // @version 4 | // @author emilybrooks 5 | // @description Steam 6 | // * 1000-REKA 7 | // * Unity (IL2CPP) 8 | // 9 | // https://store.steampowered.com/app/1931940/ 10 | // ==/UserScript== 11 | const Mono = require('./libMono.js'); 12 | 13 | Mono.setHook('', 'AdvText', 'SetText', 6, { 14 | onEnter(args) { 15 | let text = args[3].readMonoString().replace(/\s+|#Keyword.*?]|#End/g, ''); 16 | trans.send(text); 17 | } 18 | }); 19 | -------------------------------------------------------------------------------- /PC_Steam_Unity_Higurashi_Hou.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Higurashi When They Cry Hou 3 | // @version 4 | // @author samheiden 5 | // @description Steam 6 | // * 07th Expansion 7 | // * MangaGamer 8 | // * Unity (JIT) 9 | // 10 | // https://store.steampowered.com/app/310360/Higurashi_When_They_Cry_Hou__Ch1_Onikakushi/ 11 | // ==/UserScript== 12 | const Mono = require('./libMono.js'); 13 | const { 14 | setHook 15 | } = Mono; 16 | 17 | function cleanText(s) { 18 | return s 19 | .replace(/\s+/g, '') //remove whitespace 20 | .replace(/<\/?[^>]*./g, ''); //remove control codes 21 | } 22 | 23 | Mono.setHook('', 'Assets.Scripts.Core.TextWindow.TextController', 'SetText', 4, { 24 | onEnter(args) { 25 | if (args[4] == 2) return; 26 | let text = args[2].readMonoString(); 27 | text = cleanText(text); 28 | trans.send(text); 29 | } 30 | }); 31 | -------------------------------------------------------------------------------- /PC_Steam_Unity_Ken_ga_Kimi_Momoyo_Tsuzuri.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Ken ga Kimi | Ken ga Kimi: Momoyo Tsuzuri 3 | // @version 4 | // @author [DC] 5 | // @description Steam 6 | // * Rejet | Beijing Happy Entertainment Technology 7 | // * Unity (JIT), engine MV_? 8 | // 9 | // https://store.steampowered.com/app/1162650/Ken_ga_Kimi/ 10 | // https://store.steampowered.com/app/1387350/Ken_ga_Kimi_Momoyo_Tsuzuri/ 11 | // ==/UserScript== 12 | require('./PC_Steam_Unity_Ken_ga_Kimi.js'); -------------------------------------------------------------------------------- /PC_Steam_Unity_Paranormasight.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Paranormasight 3 | // @version 4 | // @author Owlie 5 | // @description Steam 6 | // * Square Enix 7 | // * Unity (IL2CPP) 8 | // 9 | // https://store.steampowered.com/app/2106840/PARANORMASIGHT_The_Seven_Mysteries_of_Honjo/ 10 | // ==/UserScript== 11 | const Mono = require('./libMono.js'); 12 | const handlerLine = trans.send((s) => s, '200+'); 13 | 14 | 15 | Mono.setHook('', 'Misty.MainMenu', 'ReserveLogData', -1, { 16 | onEnter(args) { 17 | const s = args[2].readMonoString().replace(/\[[^\]]*\]/g, ''); 18 | handlerLine(s) 19 | } 20 | }); 21 | 22 | Mono.setHook('', 'Misty.WindowMessage', 'SetTextParam', 4, { 23 | onEnter(args) { 24 | const s = args[1].readMonoString().replace(/\[[^\]]*\]|<[^>]*>/g, ''); 25 | handlerLine(s) 26 | } 27 | 28 | }); 29 | -------------------------------------------------------------------------------- /PC_Steam_Unity_Raging-Loop.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Raging Loop 3 | // @version 4 | // @author Enfys 5 | // @description Steam 6 | // * KEMCO 7 | // * Unity (JIT) 8 | // 9 | // https://store.steampowered.com/app/648100/Raging_Loop/ 10 | // ==/UserScript== 11 | const Mono = require('./libMono.js'); 12 | 13 | const { 14 | setHook 15 | } = Mono; 16 | 17 | const handlerLine = trans.send((s) => s, '250+'); 18 | 19 | const BackLog = Mono.use('', '.MainScene$BackLog'); // names + dialog 20 | 21 | BackLog['.ctor'].attach({ 22 | onEnter(args) { 23 | const message = args[1].readMonoString().trim(); 24 | handlerLine(message); 25 | }, 26 | }) 27 | 28 | setHook('', 'Game', 'NewText', -1, { // choices + system text 29 | onEnter(args) { 30 | const s = args[3].readMonoString(); 31 | if (s.length > 1) handlerLine(s) // filter out dialog 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /PC_Steam_Unity_SeaBed.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name SeaBed 3 | // @version 4 | // @author landon 5 | // @description Steam 6 | // * Fruitbat Factory 7 | // * Paleontology 8 | // * Unity (IL2CPP) 9 | // 10 | // https://store.steampowered.com/app/583090/SeaBed/ 11 | // ==/UserScript== 12 | const Mono = require('./libMono.js'); 13 | const handleLine = trans.send((s) => s, '250++'); 14 | // use 250+ if you want newlines for things like menus, but be aware that furigana styled text will have its own lines which may be annoying 15 | 16 | //System.Void FruitbatVN.Engine.MessageLayer::AddText(System.String) 17 | Mono.setHook('', 'FruitbatVN.Engine.MessageLayer', 'AddText', -1, { 18 | onEnter(args) { 19 | let line = args[1].readMonoString() 20 | if (line[0] == " ") { 21 | line = line.substring(1); 22 | } 23 | if (line.includes("]*>/g, ''); 16 | 17 | // Call the swapHandler to handle the text 18 | swapHandler(text); 19 | } 20 | }); 21 | 22 | // Swap handler to handle the swapping logic 23 | let text = []; 24 | let timerSwap; 25 | function swapHandler(s) { 26 | text.unshift(s); 27 | clearTimeout(timerSwap); 28 | timerSwap = setTimeout(() => { 29 | const joinedText = [...text].join('\r\n'); 30 | trans.send(joinedText); 31 | text = []; // Reset 32 | }, 300); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /PC_Steam_Unity_Uso_kara_Hajimaru_Koi_no_Natsu.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Uso kara Hajimaru Koi no Natsu 3 | // @version 4 | // @author emilybrooks 5 | // @description Steam 6 | // * LYCORIS 7 | // * Unity (JIT) 8 | // 9 | // https://store.steampowered.com/app/1575980/ 10 | // ==/UserScript== 11 | const Mono = require('./libMono.js'); 12 | 13 | function cleanText(s) { 14 | return s 15 | .replace(/.*?<\/size>/g, '') 16 | .replace(/.*?<\/size5>/g, '') //typo in chapter 15 17 | .replace(/<.*?>/g, ''); 18 | } 19 | 20 | let lastMessage = ''; 21 | 22 | Mono.setHook('Elringus.Naninovel.Runtime', 'Naninovel.UI.RevealableText', 'SetText', 1, { 23 | onEnter(args) { 24 | let text = args[1].readMonoString(); 25 | if (text == lastMessage) 26 | { 27 | lastMessage = '' 28 | return 29 | } 30 | else 31 | { 32 | lastMessage = text; 33 | text = cleanText(text); 34 | trans.send(text); 35 | } 36 | } 37 | }); 38 | -------------------------------------------------------------------------------- /PC_Steam_WITCH_ON_THE_HOLY_NIGHT.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name WITCH ON THE HOLY NIGHT 3 | // @version 0.1 4 | // @author [blacktide082] 5 | // @description Steam 6 | // * TYPE MOON 7 | // * tested on ver1.1 8 | // 9 | // https://store.steampowered.com/app/2052410/WITCH_ON_THE_HOLY_NIGHT/ 10 | // ==/UserScript== 11 | 12 | const __e = Process.enumerateModules()[0]; 13 | const handler = trans.send(s => s, '200+'); 14 | 15 | (function () { 16 | const dialogSig = '48 ?? ?? ?? ?? 48 ?? ?? ?? 48 ?? ?? ?? ???????? 33 C0 48 ?? ?? 10 48 ?? ?? 18 ???????? 66'; 17 | const results = Memory.scanSync(__e.base, __e.size, dialogSig); 18 | if (results.length === 0) { 19 | console.error('[DialoguePattern] Hook not found!'); 20 | return; 21 | } 22 | 23 | const address = results[0].address; 24 | console.log('[DialoguePattern] Found hook', address); 25 | Interceptor.attach(address, function (args) { 26 | // skip if not dialogue 27 | if (args[3] != 1) return; 28 | const text = args[2].readUtf16String() 29 | .replace(/(.*?)<\/r>/g, "$1") // remove furigana 30 | .split('\n') 31 | .map(s => s.trim()) 32 | .join(''); 33 | handler(text); 34 | }); 35 | })(); 36 | -------------------------------------------------------------------------------- /PC_Steam_Yakuza.Kiwami.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Yakuza Kiwami 3 | // @version 4 | // @author Koukdw & [DC] 5 | // @description Steam 6 | // ==/UserScript== 7 | require('./PC_Steam_Yakuza.0.js'); -------------------------------------------------------------------------------- /PS2_SLPM65732_Akai_Ito.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [SLPM65732] Akai Ito 3 | // @version 0.1 4 | // @author logantgt 5 | // @description PCSX2 x64 6 | // ==/UserScript== 7 | 8 | const { setHookEE, asPsxPtr } = require("./libPCSX2.js"); 9 | 10 | setHookEE({ 11 | 0x136800: trans.send(handler) 12 | }); 13 | 14 | function handler(args) { 15 | // return if not dialogue buffer 16 | if(this.context.t0(Uint32Array)[0] != 0x49F8B0) return; 17 | 18 | let s = this.context.t0(asPsxPtr).readShiftJisString(); 19 | 20 | s = s 21 | .replaceAll('#cr0', '') 22 | .replace(/(\\n)+/g, ' ') 23 | .replace(/\\d$|^\@[a-z]+|#.*?#|\$/g, '') 24 | .replace(/\u3000+/gu, '') 25 | .replace(/@w|\\c/g, '') 26 | 27 | return s; 28 | } -------------------------------------------------------------------------------- /PS2_SLPM65914_NANA.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [SLPM65914] NANA 3 | // @version 0.1 4 | // @author Owlie 5 | // @description PCSX2 x64 6 | // ==/UserScript== 7 | 8 | const { setHookEE, asPsxPtr } = require("./libPCSX2.js"); 9 | 10 | setHookEE({ 11 | 0x15036C: trans.send(handler) 12 | }); 13 | 14 | function handler(args) { 15 | let s = this.context.a3(asPsxPtr).readShiftJisString(); 16 | 17 | // Remove ①n from dialogue lines 18 | s = s.replace(/①n/g, ''); 19 | 20 | // Remove lines with unwanted patterns 21 | s = s 22 | .replace(/^(V_.*|[\s-0-90-9,.\-±]+)$/gm, '') // Remove lines starting with V_, or lines with only "-", full/half-width numbers and punctuation 23 | .replace(/^([±\s]+[0-90-9,.\-]+|[0-90-9,.\-]+)$/gm, ''); // Remove lines starting with ± and full-width numbers and punctuation 24 | 25 | return s.trim(); 26 | } 27 | -------------------------------------------------------------------------------- /PS2_SLPM66045_My_Merry_May_with_be.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [SLPM66045] My Merry May with be 3 | // @version 0.1 4 | // @author Owlie 5 | // @description PCSX2 x64 6 | // ==/UserScript== 7 | 8 | const { setHookEE, asPsxPtr } = require("./libPCSX2.js"); 9 | 10 | setHookEE({ 11 | 12 | 0x1DB7DC: trans.send(handler), 13 | 14 | 15 | }); 16 | 17 | function handler(args) { 18 | 19 | let s = this.context.a3(asPsxPtr).readShiftJisString(); 20 | 21 | s = s 22 | 23 | .replace(/%\w+\d*\w*/g, '') 24 | .replace(/%N+/g, '') 25 | 26 | return s; 27 | } -------------------------------------------------------------------------------- /PS2_SLPM66302_CLANNAD.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [SLPM66302] CLANNAD 3 | // @version 0.2 4 | // @author logantgt 5 | // @description PCSX2 x64 6 | // * Interchannel/Prototype Legacy Engine 7 | // ==/UserScript== 8 | 9 | const { setHookEE, asPsxPtr } = require("./libPCSX2.js"); 10 | 11 | setHookEE({ 12 | 0x14AC38: trans.send(handler) 13 | }); 14 | 15 | function handler(args) { 16 | // Read string 17 | let s = this.context.s4(asPsxPtr).readShiftJisString().split(");")[0]; 18 | 19 | // Filter out name text 20 | if(s.split('】').length > 1) { s = s.split('】')[1] } 21 | 22 | // Process string, replace MC name variables 23 | s = s 24 | .replace(/(\\n)+/g, ' ') 25 | .replace(/\\d$|^\@[a-z]+|#.*?#|\$/g, '') 26 | .replace(/\u3000+/gu, '') 27 | .replace(/@w|\\c/g, '') 28 | .replace("*A", "岡崎") 29 | .replace("*B", "朋也") 30 | 31 | return s; 32 | } -------------------------------------------------------------------------------- /PS2_SLPM66892_Myself_Yourself.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [SLPM-66892] Myself;Yourself 3 | // @version 0.1 4 | // @author konan 5 | // @description PCSX2 x64 6 | // ==/UserScript== 7 | 8 | const { setHookEE, asPsxPtr } = require("./libPCSX2.js"); 9 | 10 | setHookEE({ 11 | 0x1443e8: trans.send(mainHandler), 12 | 0x13F1F8: trans.send(choicesHandler), 13 | }); 14 | 15 | function mainHandler(args) { 16 | let s = this.context.t0(asPsxPtr).add(0x15010).readShiftJisString(); // speaker 17 | s += this.context.t0(asPsxPtr).readShiftJisString(); // line 18 | 19 | s = s.replace(/^(%n)+/, ""); 20 | 21 | return s; 22 | } 23 | 24 | function choicesHandler(args) { 25 | let t0 = this.context.t0(asPsxPtr); 26 | let offset = findStringStart(t0); 27 | 28 | let s = t0.add(offset).readShiftJisString(); 29 | 30 | return s; 31 | } 32 | 33 | function findStringStart(last2BytesAddress) { 34 | let offset = 0; 35 | let address = last2BytesAddress; 36 | 37 | while (address.readU8() != 0) { 38 | address = address.add(-1); 39 | offset--; 40 | } 41 | offset++; 42 | 43 | return offset; 44 | } 45 | -------------------------------------------------------------------------------- /PS2_SLPS25332_SNOW.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [SLPS25332] SNOW 3 | // @version 0.2 4 | // @author logantgt 5 | // @description PCSX2 x64 6 | // * Interchannel/Prototype Legacy Engine 7 | // ==/UserScript== 8 | 9 | const { setHookEE, asPsxPtr } = require("./libPCSX2.js"); 10 | const Encoding = require('./libHelperEncoding.js'); 11 | const enc = new Encoding(__dirname + '/charsets/tblNECInterChannelJP.txt'); 12 | 13 | setHookEE({ 14 | 0x10D7CC: trans.send(handler) 15 | }); 16 | 17 | function handler(args) { 18 | let s = ""; 19 | 20 | // Read string at right position 21 | if(new Uint8Array(this.context.a0(asPsxPtr).readByteArray(1))[0] == 0x2C) { 22 | s = this.context.a0(asPsxPtr).add(1).readCustomString(enc); 23 | } 24 | else { 25 | s = this.context.a0(asPsxPtr).readCustomString(enc); 26 | } 27 | 28 | // Process string, replace MC name variables 29 | s = s 30 | .split('($')[0] 31 | .replace(/(\\n)+/g, ' ') 32 | .replace(/\\d$|^\@[a-z]+|#.*?#|\$/g, '') 33 | .replace(/\u3000+/gu, '') 34 | .replace(/@w|\\c/g, '') 35 | .replace("*A", "出雲") 36 | .replace("*B", "彼方") 37 | 38 | return s; 39 | } -------------------------------------------------------------------------------- /PS2_SLPS25547_Ichigo_Marshmallow.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [SLPS25547] Ichigo Marshmallow 3 | // @version 0.1 4 | // @author Owlie 5 | // @description PCSX2 x64 6 | // ==/UserScript== 7 | 8 | const { setHookEE, asPsxPtr } = require("./libPCSX2.js"); 9 | 10 | setHookEE({ 11 | 0x1439F4: trans.send(handler) 12 | }); 13 | 14 | function handler(args) { 15 | 16 | let s = this.context.s1(asPsxPtr).readShiftJisString(); 17 | 18 | s = s 19 | .replace(/^\[.*$/gm, '') 20 | .replace(/\_0C|\_1_5C|\_1C/gm, '') 21 | .replace(/^([a-zA-Z]+)|([a-zA-Z]+)$/gm, '') 22 | 23 | return s; 24 | } 25 | -------------------------------------------------------------------------------- /PS2_SLPS25677_BLOOD+_One_Night_Kiss.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [SLPS25677] BLOOD+ One Night Kiss 3 | // @version 0.1 4 | // @author Owlie 5 | // @description PCSX2 x64 6 | // ==/UserScript== 7 | 8 | const { setHookEE, asPsxPtr } = require("./libPCSX2.js"); 9 | 10 | setHookEE({ 11 | 0x267B58: trans.send(handler), // Information text 12 | 0x268260: trans.send(handler), // NPC dialogue text 13 | }); 14 | 15 | function handler(args) { 16 | 17 | let s = this.context.a3(asPsxPtr).readShiftJisString(); 18 | 19 | return s; 20 | } -------------------------------------------------------------------------------- /PSP_ULJM05447_Will_O'_Wisp_Portable.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [ULJM05447] Will O' Wisp Portable (v1.02) 3 | // @version 1.02 4 | // @author kenzy 5 | // @description PPSSPP x64 6 | // * Design Factory Co., Ltd. & Otomate 7 | // * Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const { setHook } = require("./libPPSSPP.js"); 10 | 11 | const mainHandler = trans.send(handler); 12 | 13 | setHook({ 14 | 0x885dd04: mainHandler.bind_(null, 0) // text 15 | }); 16 | 17 | function handler(regs, index, offset) { 18 | const address = regs[index].value; 19 | // console.log("onEnter: " + hookname); 20 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 21 | 22 | let s = address.readShiftJisString(); 23 | s = s.replace(/(#n)+/g, ' ') 24 | .replace(/(#[A-Za-z]+\[(\d*[.])?\d+\])+/g, '') 25 | 26 | return s; 27 | } 28 | -------------------------------------------------------------------------------- /PSP_ULJM05701_Hanakisou.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [ULJM05701] Hanakisou (花帰葬) 3 | // @version 0.1 4 | // @author Mansive 5 | // @description PPSSPP x64 6 | // * HaccaWorks* 7 | // * PROTOTYPE 8 | // ==/UserScript== 9 | const { setHook } = require("./libPPSSPP.js"); 10 | 11 | const mainHandler = trans.send(handler, "200+"); 12 | 13 | setHook({ 14 | 0x88139f4: mainHandler.bind_(null, 0, "text"), 15 | }); 16 | 17 | console.log(` 18 | If PPSSPP flickers, disable "Skip buffer effects". 19 | `); 20 | 21 | let previous = ""; 22 | 23 | function handler(regs, index, hookname) { 24 | // console.log("onEnter:", hookname); 25 | 26 | const address = regs[index].value; 27 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | 29 | let s = address.readUtf16String(); 30 | 31 | if (s === previous) { 32 | return null; 33 | } 34 | previous = s; 35 | 36 | s = s 37 | .replace(/^\u3010[^\u3011]+\u3011/gu, "") // remove name 38 | .replace(/\n\u3000+/g, ""); // single line without fullwidth whitespace padding 39 | 40 | return s; 41 | } 42 | -------------------------------------------------------------------------------- /PSP_ULJM05802_Bara_no_Ki_ni_Bara_no_Hanasaku.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [ULJM05802] Bara no Ki ni Bara no Hanasaku (薔薇ノ木ニ薔薇ノ花咲ク) 3 | // @version 0.1 4 | // @author Mansive 5 | // @description PPSSPP x64 6 | // * Cyc Rosé 7 | // * Interchannel & QuinRose 8 | // ==/UserScript== 9 | const { setHook } = require("./libPPSSPP.js"); 10 | 11 | const mainHandler = trans.send(handler, "200+"); 12 | 13 | setHook({ 14 | 0x880e6fc: mainHandler.bind_(null, 3, "name"), 15 | 0x880be70: mainHandler.bind_(null, 3, "text"), 16 | }); 17 | 18 | function handler(regs, index, hookname) { 19 | console.log("onEnter:", hookname); 20 | 21 | const address = regs[index].value; 22 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 23 | 24 | let s = address.readShiftJisString().replace(/\n/g, ""); 25 | 26 | if (hookname === "name") { 27 | return s.replace(/\r.*/g, ""); 28 | } else if (hookname === "text") { 29 | return s.replace(/^[^\r]+\r/, "").replace(/\r\u3000*/gu, ""); // single line 30 | } 31 | 32 | return s; 33 | } 34 | 35 | trans.replace((s) => { 36 | return s.trim(); 37 | }); 38 | -------------------------------------------------------------------------------- /PSP_ULJM05878_Sekai-de-Ichiban-Dame-na-Koi.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [NPJH50909] Sekai de Ichiban Dame na Koi 3 | // @version 0.1 4 | // @author [DC] 5 | // @description PPSSPP x64 6 | // * 7 | // * 8 | // ==/UserScript== 9 | const { setHook } = require("./libPPSSPP.js"); 10 | 11 | const mainHandler = trans.send(handler); 12 | 13 | setHook({ 14 | 0x8814adc: mainHandler, // name + dialouge 15 | 0x8850b2c: mainHandler, // onscreen toast 16 | }); 17 | 18 | function handler(regs) { 19 | console.log('onEnter'); 20 | 21 | const address = regs[0].value; // a0 22 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 23 | 24 | /* processString */ 25 | let s = address.readShiftJisString(); 26 | 27 | // controls 28 | s = s.replace(/(\%N)+/g, ' ') // single line 29 | .replace(/\%@\%\d+/, '') // scale %@%200 30 | ; 31 | 32 | // reformat name 33 | let name = s.match(/(^[^「]+)「/); 34 | if (name !== null) { 35 | s = s.replace(/^[^「]+/, ''); 36 | s = name[1] + '\n' + s; 37 | } 38 | 39 | return s; 40 | } -------------------------------------------------------------------------------- /PSP_ULJM05943_Gekka_Ryouran_Romance.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [ULJM05943] Gekka Ryouran Romance 3 | // @version 0.1 4 | // @author Koukdw 5 | // @description PPSSPP x64 6 | // * Otomate & Rejet 7 | // * Idea Factory (アイディアファクトリー) 8 | // * 9 | // ==/UserScript== 10 | const { setHook } = require("./libPPSSPP.js"); 11 | 12 | const mainHandler = trans.send(handler); 13 | 14 | setHook({ 15 | 0x88eeba4: mainHandler.bind_(null, 0, 0), // a0 - monologue text 16 | 0x8875e0c: mainHandler.bind_(null, 1, 6), // a1 - dialogue text 17 | }); 18 | 19 | function handler(regs, index, offset) { 20 | console.log('onEnter'); 21 | const address = regs[index].value.add(offset); 22 | 23 | /* processString */ 24 | let s = address.readShiftJisString(); 25 | 26 | // Example dialogue: #Speed[5]#Effect[0]#Scale[1]はーん……あれが、#n津森なずな 27 | s = s.replace(/(#n)+/g, ' ') // Single line 28 | .replace(/(#[A-Za-z]+\[(\d*[.])?\d+\])+/g, ''); // Remove controls 29 | return s; 30 | } -------------------------------------------------------------------------------- /PSP_ULJM06036 _Princess-Evangile-Portable.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [ULJM06036] Princess Evangile Portable 3 | // @version 0.1 4 | // @author [DC] 5 | // @description PPSSPP x64 6 | // * 7 | // * 8 | // ==/UserScript== 9 | const { setHook } = require("./libPPSSPP.js"); 10 | 11 | const mainHandler = trans.send(handler.bind_(null, 2), '200+'); // join 200ms 12 | 13 | setHook({ 14 | 0x88506d0: mainHandler, // [0x88506d0(2)...0x088507C0(?)] // name text text (line doubled) 15 | }); 16 | 17 | function handler(regs, index) { 18 | const address = regs[index].value; // a2 19 | 20 | console.log('onEnter'); 21 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 22 | 23 | /* processString */ 24 | let s = address.readUtf16String(); 25 | 26 | const patt = /]+)./g; 27 | // print rubi 28 | const rubis = s.matchAll(patt); 29 | for (const rubi of rubis) { 30 | console.log('rubi: ' + rubi[1]); 31 | console.log('rube: ' + rubi[2]); 32 | } 33 | // remove ruby 34 | s = s.replace(patt, '$2'); 35 | // remove tag (control) 36 | s = s.replace(/<[A-Z]+>/g, ''); 37 | 38 | return s; 39 | } 40 | -------------------------------------------------------------------------------- /PSP_ULJM06291_Arcana_Famiglia_2.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [ULJM06291] Arcana Famiglia 2 3 | // @version 0.1 4 | // @author Mansive 5 | // @description PPSSPP x64 6 | // * HuneX 7 | // * Comfort 8 | // ==/UserScript== 9 | const { setHook } = require("./libPPSSPP.js"); 10 | 11 | const mainHandler = trans.send(handler, "200+"); 12 | 13 | setHook({ 14 | 0x889c6d0: mainHandler.bind_(null, 1, 2, "dialogue"), 15 | 0x88c1cc4: mainHandler.bind_(null, 1, 0, "wall of text"), 16 | }); 17 | 18 | function handler(regs, index, offset, hookname) { 19 | console.log("onEnter:", hookname); 20 | 21 | const address = regs[index].value; 22 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 23 | 24 | const s = address 25 | .add(offset) 26 | .readShiftJisString() 27 | .replace(/@n/g, "") // single line 28 | .replace(/@\w|$/g, "") // stuff 29 | .replace(/\u3000{2,}/gu, "\n"); // newline for header of big white wall of text 30 | 31 | return s; 32 | } 33 | -------------------------------------------------------------------------------- /PSP_ULJM06302-3_Seishun_Hajimemashita.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [ULJM06302-3] Seishun Hajimemashita! 3 | // @version 1.0 4 | // @author kenzy 5 | // @description PPSSPP x64 6 | // * honeybee 7 | // ==/UserScript== 8 | const { setHook } = require("./libPPSSPP.js"); 9 | 10 | const mainHandler = trans.send(handler); 11 | 12 | setHook({ 13 | 0x880a744: mainHandler.bind_(null, 0), // text 14 | }); 15 | 16 | function handler(regs, index, offset) { 17 | const address = regs[index].value; 18 | // console.log('onEnter'); 19 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 20 | 21 | let s = address.readShiftJisString(); 22 | s = s.replace(/\n/g, ''); 23 | 24 | return s; 25 | } 26 | -------------------------------------------------------------------------------- /PSP_ULJM06393_Omerta_Chinmoku_no_Okite_The_Legacy.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [ULJM06393] Omertà ~Chinmoku no Okite~ The Legacy / Omerta (オメルタ~沈黙の掟~ THE LEGACY) 3 | // @version 0.1 4 | // @author Mansive 5 | // @description PPSSPP x64 6 | // * Karin Chatnoir Ω 7 | // ==/UserScript== 8 | const { setHook } = require("./libPPSSPP.js"); 9 | 10 | const mainHandler = trans.send(handler, "200+"); 11 | 12 | setHook({ 13 | 0x8885fd8: mainHandler.bind_(null, 0, "name"), 14 | 0x88861e0: mainHandler.bind_(null, 3, "text"), 15 | // 0x8889f40: mainHandler.bind_(null, 1, "timed choice"), // less calls but extra garbage line 16 | 0x88ac3a8: mainHandler.bind_(null, 1, "timed choice"), // more calls but cleaner 17 | }); 18 | 19 | console.log(` 20 | If PPSSPP is flickering on button presses, disable "Skip buffer effects". 21 | `); 22 | 23 | function handler(regs, index, hookname) { 24 | console.log("onEnter:", hookname); 25 | 26 | const address = regs[index].value; 27 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | 29 | // remove fullwidth whitespace at start 30 | const s = address.readShiftJisString().replace(/^\u3000/gu, ""); 31 | 32 | return s; 33 | } 34 | -------------------------------------------------------------------------------- /PSP_ULJM6064_Armen_Noir_Portable.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [ULJM6064] Armen Noir Portable 3 | // @version 1.0 4 | // @author kenzy 5 | // @description PPSSPP x64 6 | // * Design Factory Co., Ltd. & Otomate 7 | // * Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const { setHook } = require("./libPPSSPP.js"); 10 | 11 | const mainHandler = trans.send(handler); 12 | 13 | setHook({ 14 | 0x883b6a8: mainHandler.bind_(null, 0), // text 15 | }); 16 | 17 | function handler(regs, index, offset) { 18 | const address = regs[index].value; 19 | // console.log('onEnter'); 20 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 21 | 22 | let s = address.readShiftJisString(); 23 | s = s.replace(/(#n)+/g, ' ') 24 | .replace(/(#[A-Za-z]+\[(\d*[.])?\d+\])+/g, '') 25 | 26 | return s; 27 | } 28 | -------------------------------------------------------------------------------- /PSP_ULJS00403_Shinigami_to_Shoujo.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [ULJS00403] Shinigami to Shoujo 3 | // @version 0.1 4 | // @author [DC] 5 | // @description PPSSPP x64 6 | // * TAKUYO 7 | // * TAKUYO 8 | // * 9 | // ==/UserScript== 10 | const { setHook } = require("./libPPSSPP.js"); 11 | 12 | const mainHandler = trans.send(handler, '250+'); 13 | 14 | /* 15 | 0x883b0bc: mainHandler.bind_(null, 2), // a2 - choices (un-formated) 16 | 0x883cf04: mainHandler.bind_(null, 3), // a3 - choices + nameX2 17 | 0x883bf34: mainHandler.bind_(null, 1), // a1 - choices + dialogue + nameX2 <---- 18 | 0x8836984: mainHandler.bind_(null, 1), // a1 - dialogue 19 | 0x883cecc: mainHandler.bind_(null, 3), // a3 - dialogue 20 | */ 21 | setHook({ 22 | 0x883bf34: mainHandler 23 | }); 24 | 25 | function handler(regs) { 26 | console.log('onEnter'); 27 | const address = regs[1].value; 28 | 29 | /* processString */ 30 | // @w \nけど……#STAND\TOOY01A_N.bmp 3#微妙だっ $お姫様$』 \d 31 | const s = address.readShiftJisString() 32 | .replace(/(\\n)+/g, ' ') 33 | .replace(/\\d$|^\@[a-z]+|#.*?#|\$/g, '') // #.*?# <=> #[^#]+. 34 | ; 35 | 36 | return s; 37 | } -------------------------------------------------------------------------------- /PSVita_PCSG00172_Kajiri_Kamui_Kagura_Akebono_no_Hikari.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00172] Kajiri Kamui Kagura: Akebono no Hikari 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // *light 7 | // ==/UserScript== 8 | trans.replace(function (s) { 9 | return s 10 | .replace(/Mレ  ー_Mレ ���/g, '') 11 | .replace(/u_/g, '') 12 | .replace("ata/data4.dat", '') 13 | .replace(":data/data4.dat", '') 14 | .replace(/@/g,"") 15 | .replace(/�/g,"") 16 | .replace(/∥pp0:d/g,"") 17 | .replace(/app0:d:d/g,"") 18 | 19 | 20 | 21 | ; 22 | }); 23 | //------------------------------------------------ 24 | const { setHook } = require("./libVita3k.js"); 25 | 26 | const mainHandler = trans.send(handler, "200++"); // join 200ms 27 | 28 | setHook({ 29 | 0x810a2486: mainHandler.bind_(null, 0, 0, "dialogue"), 30 | 31 | 32 | }); 33 | 34 | function handler(regs, index, offset, hookname) { 35 | const address = regs[index].value.add(offset); 36 | 37 | 38 | console.log("onEnter: " + hookname); 39 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 40 | 41 | let s = address.readShiftJisString(); 42 | 43 | 44 | return s; 45 | } 46 | -------------------------------------------------------------------------------- /PSVita_PCSG00389_Binary_Star.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00389] バイナリースター Binary Star 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // *Design Factory Co., Ltd. & Otomate 7 | // ==/UserScript== 8 | trans.replace(function (s) { 9 | return s 10 | .replaceAll(/[\s]/g, '') 11 | .replace(/(#n)+/g, '') // Single line 12 | .replace(/(#[A-Za-z]+\[(\d*[.])?\d+\])+/g, '') 13 | .replace(/#Pos\[[\s\S]*?\]/g, ''); 14 | ; 15 | }); 16 | //------------------------------------------------ 17 | const { setHook } = require("./libVita3k.js"); 18 | 19 | const mainHandler = trans.send(handler, '200++'); // join 200ms 20 | 21 | setHook({ 22 | 23 | 0x80058606: mainHandler.bind_(null, 1, 0, "dialogue"), 24 | 25 | 26 | }); 27 | 28 | function handler(regs, index, offset, hookname) { 29 | const address = regs[index].value.add(offset); 30 | 31 | //console.log("onEnter: " + hookname); 32 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 33 | 34 | let s = address.add(0xD).readShiftJisString() 35 | 36 | return s; 37 | } 38 | -------------------------------------------------------------------------------- /PSVita_PCSG00401_Sora_Yume.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00401] Sora*yume 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // *TAKUYO 7 | // ==/UserScript== 8 | trans.replace(function (s) { 9 | return s 10 | .replaceAll(/[\s]/g, '') 11 | .replaceAll(/\c/g, '') 12 | .replaceAll(/\\n/g, '') 13 | ; 14 | }); 15 | //------------------------------------------------ 16 | const { setHook } = require("./libVita3k.js"); 17 | 18 | const mainHandler = trans.send(handler, '200+'); // join 200ms 19 | 20 | setHook({ 21 | 22 | 0x8000bad4: mainHandler.bind_(null, 1, 0, "dialogue"), 23 | 24 | 25 | }); 26 | 27 | function handler(regs, index, offset, hookname) { 28 | const address = regs[index].value.add(offset); 29 | 30 | //console.log("onEnter: " + hookname); 31 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 32 | 33 | let s = address.readShiftJisString() 34 | 35 | return s; 36 | } 37 | -------------------------------------------------------------------------------- /PSVita_PCSG00405_Reine_des_Fleurs.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00405] Reine des Fleurs 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // *Design Factory Co., Ltd. & Otomate &Idea Factory Co., Ltd. 7 | // ==/UserScript== 8 | trans.replace(function (s) { 9 | return s 10 | .replaceAll(/[\s]/g, '') 11 | ; 12 | }); 13 | //------------------------------------------------ 14 | const { setHook } = require("./libVita3k.js"); 15 | 16 | const mainHandler = trans.send(handler, '200+'); // join 200ms 17 | 18 | setHook({ 19 | 20 | 0x8001bff2: mainHandler.bind_(null, 0, 0, "dialogue"), 21 | 22 | 23 | }); 24 | 25 | function handler(regs, index, offset, hookname) { 26 | const address = regs[index].value.add(offset); 27 | 28 | //console.log("onEnter: " + hookname); 29 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 30 | 31 | let s = address.readShiftJisString() 32 | 33 | return s; 34 | } 35 | -------------------------------------------------------------------------------- /PSVita_PCSG00410_Nekketsu_Inou_Bukatsu-tan_Trigger_Kiss.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00410] Nekketsu Inou Bukatsu-tan Trigger Kiss 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // *Design Factory Co., Ltd. & Otomate 7 | // ==/UserScript== 8 | trans.replace(function (s) { 9 | return s 10 | .replace(/(#[A-Za-z]+\[(\d*[.])?\d+\])+/g, '') 11 | .replace(/#Pos\[[\s\S]*?\]/g, '') 12 | .replaceAll("#n", " ") 13 | .replaceAll("④", "!?") 14 | .replaceAll("②", "!!") 15 | .replaceAll("⑥", "。") 16 | .replaceAll("⑪", "【") 17 | .replaceAll("⑫", "】") 18 | .replaceAll("⑤", "、") 19 | .replaceAll("①", "・・・") 20 | 21 | ; 22 | }); 23 | //------------------------------------------------ 24 | const { setHook } = require("./libVita3k.js"); 25 | 26 | const mainHandler = trans.send(handler, '200++'); 27 | setHook({ 28 | 0x8004e44a: mainHandler.bind_(null, 0, 0, "dialogue"), 29 | }); 30 | function handler(regs, index, offset, hookname) { 31 | const reg = regs[index]; 32 | const address = regs[index].value.add(offset); 33 | 34 | console.log("onEnter: " + hookname); 35 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 36 | 37 | let s = address.readShiftJisString(); 38 | return s; 39 | } 40 | -------------------------------------------------------------------------------- /PSVita_PCSG00420_DRAMAtical_Murder_recode.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00420] DRAMAtical Murder re:code 3 | // @version 1.00 4 | // @author kenzy 5 | // @description Vita3K 6 | // * Nitro+CHiRAL 7 | // * 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, '200+'); 12 | 13 | setHook({ 14 | 0x8004630a: mainHandler.bind_(null, 0), // text 15 | 0x8003eed2: mainHandler.bind_(null, 0), // choices 16 | }); 17 | 18 | function handler(regs, index, hookname) { 19 | const address = regs[index].value; 20 | // console.log("onEnter: ", hookname); 21 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 22 | 23 | let s = address.readShiftJisString() 24 | s = s.replace(/\^/g, ""); 25 | 26 | 27 | return s; 28 | } 29 | -------------------------------------------------------------------------------- /PSVita_PCSG00448_MARGINAL_#4_IDOL_OF_SUPERNOVA.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00448] MARGINAL#4 IDOL OF SUPERNOVA 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // * Otomate / Rejet 7 | // * Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | trans.replace(function (s) { 10 | return s 11 | .replaceAll(/[\s]/g, '') 12 | .replace(/(#n)+/g, '') // Single line 13 | .replace(/(#[A-Za-z]+\[(\d*[.])?\d+\])+/g, '') 14 | .replace(/#Pos\[[\s\S]*?\]/g, ''); 15 | ; 16 | }); 17 | //------------------------------------------------ 18 | const { setHook } = require("./libVita3k.js"); 19 | 20 | const mainHandler = trans.send(handler, '200++'); // join 300ms 21 | 22 | setHook({ 23 | 24 | 0x800718f8: mainHandler.bind_(null, 0, 0, "dialogue"), 25 | 26 | }); 27 | 28 | function handler(regs, index, offset, hookname) { 29 | const address = regs[index].value.add(offset); 30 | 31 | console.log("onEnter: " + hookname); 32 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 33 | 34 | let s = address.readShiftJisString() 35 | 36 | return s; 37 | } 38 | -------------------------------------------------------------------------------- /PSVita_PCSG00468_Kokuchou_no_Psychedelica.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00468] Kokuchou no Psychedelica (黒蝶のサイケデリカ) 3 | // @version 1.00 4 | // @author Mansive 5 | // @description Vita3K 6 | // * STING 7 | // * Otomate & Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, "200+"); // join 200ms 12 | 13 | setHook({ 14 | 0x80043538: mainHandler.bind_(null, 1, "text"), 15 | }); 16 | 17 | function handler(regs, index, hookname) { 18 | const address = regs[index].value; 19 | 20 | console.log("onEnter: ", hookname); 21 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 22 | 23 | let s = address 24 | .readUtf8String() 25 | .replace(/\\n\u3000*|\\k/gu, "") // remove escape characters and fullwidth whitespace 26 | .replace(/\[|\*[^\]]+]/g, "") // remove furigana '災いを[齎*もたら]す' to '災いを齎す' 27 | .replace(/×/g, ""); // remove weird symbol appearing after player name 28 | 29 | return s; 30 | } 31 | -------------------------------------------------------------------------------- /PSVita_PCSG00510_Starry_Sky_Spring_Stories.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00510] Starry☆Sky ~Spring Stories~ / Starry Sky ~Spring Stories~ 3 | // @version 1.00 4 | // @author Mansive 5 | // @description Vita3K 6 | // * honeybee 7 | // ==/UserScript== 8 | const { setHook } = require("./libVita3k.js"); 9 | 10 | const mainHandler = trans.send(handler, "200+"); 11 | 12 | setHook({ 13 | 0x8003542e: mainHandler.bind_(null, 3, 0x0, "name"), 14 | 0x80033f2e: mainHandler.bind_(null, 0, 0x0, "text"), 15 | 0x8002c5b8: mainHandler.bind_(null, 0, 0x8, "choice"), 16 | }); 17 | 18 | function handler(regs, index, offset, hookname) { 19 | const address = regs[index].value; 20 | 21 | // console.log("onEnter: ", hookname); 22 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 23 | 24 | const s = address.add(offset).readShiftJisString().replace(/%N/g, ""); 25 | 26 | return s; 27 | } 28 | -------------------------------------------------------------------------------- /PSVita_PCSG00611_Zettai_Meikyuu_Himitsu_no_Oyayubi_Hime.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00611] Zettai Meikyuu Himitsu no Oyayubi Hime 3 | // @version 4 | // @author emilybrooks 5 | // @description Vita3k 6 | // * Karin Entertainment 7 | // ==/UserScript== 8 | const { setHook } = require("./libVita3k.js"); 9 | 10 | const mainHandler = trans.send(handler); 11 | 12 | setHook({ 13 | 0x800bb35e: mainHandler.bind_(null, 5, 0, "text"), 14 | }); 15 | 16 | function handler(regs, index, name) { 17 | const address = regs[index].value; 18 | let text = address.readShiftJisString(); 19 | return text; 20 | } 21 | -------------------------------------------------------------------------------- /PSVita_PCSG00648_Tsuki_ni_Yorisou_Otome_no_Sahou.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00648] Tsuki ni Yorisou Otome no Sahou 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // *Navel& Dramatic Create 7 | // ==/UserScript== 8 | //------------------------------------------------ 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, '200++'); // join 300ms 12 | 13 | setHook({ 14 | 15 | 0x8002aefa: mainHandler.bind_(null, 2, 0, "dialogue"), 16 | 17 | }); 18 | 19 | function handler(regs, index, offset, hookname) { 20 | const address = regs[index].value.add(offset); 21 | 22 | //console.log("onEnter: " + hookname); 23 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 24 | 25 | let s = address.readShiftJisString(); 26 | 27 | return s; 28 | } 29 | -------------------------------------------------------------------------------- /PSVita_PCSG00667_LoveQuiz_Koi_Suru_Otome_no_Final_Answer.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00667] Love:Quiz ~Koi Suru Otome no Final Answer~ 3 | // @version 1.00 4 | // @author kenzy 5 | // @description Vita3k 6 | // * EMIQ Inc. & Asgard 7 | // * 8 | // ==/UserScript== 9 | 10 | const { setHook } = require("./libVita3k.js"); 11 | 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | setHook({ 15 | 0x8003acba: mainHandler.bind_(null, 0), // text 16 | 0x80016dd6: mainHandler.bind_(null, 1), // choices 17 | }); 18 | 19 | function handler(regs, index, offset, hookname) { 20 | const address = regs[index].value; 21 | // console.log("onEnter", hookname); 22 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 23 | 24 | let s = address.readUtf16String(); 25 | 26 | return s; 27 | } 28 | -------------------------------------------------------------------------------- /PSVita_PCSG00696_Angelique_Retour.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00696] Angelique Retour 3 | // @version 0.1 4 | // @author [zooo] 5 | // @description Vita3k 6 | // ==/UserScript== 7 | trans.replace(function (s) { 8 | return s 9 | .replace(/㌔/g, '⁉') 10 | .replace(/㍉/g, '!!') 11 | ; 12 | }); 13 | //------------------------------------------------ 14 | const { setHook } = require("./libVita3k.js"); 15 | 16 | const mainHandler = trans.send(handler, "200+"); // join 200ms 17 | 18 | setHook({ 19 | 0x8008bd1a: mainHandler.bind_(null, 1, 0, "text1"), 20 | 0x8008cd48: mainHandler.bind_(null, 0, 0, "text2"), 21 | 0x8008f75a: mainHandler.bind_(null, 0, 0, "choice"), 22 | }); 23 | 24 | function handler(regs, index, offset, hookname) { 25 | const address = regs[index].value.add(offset); 26 | 27 | console.log("onEnter: " + hookname); 28 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | 30 | let s = address.readShiftJisString(); 31 | 32 | 33 | return s; 34 | } 35 | -------------------------------------------------------------------------------- /PSVita_PCSG00706_Moshi_Kono_Sekai_ni_Kami_sama_ga_Iru_to_suru_Naraba.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00706] もし、この世界に神様がいるとするならば。 Moshi, Kono Sekai ni Kami-sama ga Iru to Suru Naraba. 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // *Rejet 7 | // ==/UserScript== 8 | trans.replace(function (s) { 9 | return s 10 | .replace(/
/g, '') 11 | 12 | ; 13 | }); 14 | //------------------------------------------------ 15 | const { setHook } = require("./libVita3k.js"); 16 | 17 | const mainHandler = trans.send(handler, "200+"); // join 200ms 18 | 19 | //however when the game goes NVL it will extract the whole box instead of line by line 20 | setHook({ 21 | 0x80c1f270: mainHandler.bind_(null, 0, 0, "dialogue"),//dialogue+ textmessage 22 | 0x80d48bfc: mainHandler.bind_(null, 1, 0, "Dictionary1"),//Dictionary1 23 | 0x80d48c20: mainHandler.bind_(null, 0, 0, "Dictionary2"),//Dictionary2 24 | }); 25 | 26 | function handler(regs, index, offset, hookname) { 27 | const address = regs[index].value.add(offset); 28 | 29 | console.log("onEnter: " + hookname); 30 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 31 | 32 | const len = address.add(0x8).readU32() * 2; 33 | let s = address.add(0xC).readUtf16String(len); 34 | 35 | 36 | return s; 37 | } 38 | -------------------------------------------------------------------------------- /PSVita_PCSG00745_Scared_Rider_Xechs_Rev.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00745] Scared Rider Xechs Rev. (スカーレッドライダーゼクス Rev.) 3 | // @version 1.00 4 | // @author Mansive 5 | // @description Vita3K 6 | // * RED 7 | // * Rejet 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, "200+"); // join 200ms 12 | 13 | setHook({ 14 | 0x8000c2d4: mainHandler.bind_(null, 12, 0x8, "text"), 15 | }); 16 | 17 | function handler(regs, index, offset, hookname) { 18 | const address = regs[index].value; 19 | 20 | console.log("onEnter:", hookname); 21 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 22 | 23 | const s = address.add(offset).readUtf8String().replace(/\n/g, ""); // single line 24 | 25 | if (s === "") { 26 | return null; 27 | } 28 | 29 | return s; 30 | } 31 | -------------------------------------------------------------------------------- /PSVita_PCSG00751_Arcana_famiglia_-La_storia_della_Arcana_Famiglia-.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name Arcana famiglia -La storia della Arcana Famiglia- 3 | // @version 1.0.0 4 | // @author [zooo] 5 | // @description Vita3k 6 | // * HuneX 7 | // * Comfort 8 | // ==/UserScript== 9 | 10 | const { setHook } = require("./libVita3k.js"); 11 | 12 | const mainHandler = trans.send(handler, "200+"); 13 | 14 | setHook({ 15 | 16 | 0x80070e30: mainHandler.bind_(null, 2, 0, "all"), 17 | 0x80070cdc: mainHandler.bind_(null, 1, 0, "ext"), 18 | 19 | 20 | }); 21 | 22 | let pre = ""; 23 | function handler(regs, index, offset, hookname) { 24 | const address = regs[index].value.add(offset); 25 | 26 | console.log("onEnter", hookname); 27 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 28 | 29 | let s = address.readShiftJisString(); 30 | 31 | if (pre.indexOf(s) !== -1) { 32 | return null; // skip duplicate (menu, color) 33 | } 34 | 35 | pre = s; 36 | s = s.replaceAll(/[\s]/g,''); 37 | s = s.replace(/@[a-z]/g, ""); 38 | s = s.replace(/$/g, ""); 39 | 40 | return s; 41 | } 42 | 43 | -------------------------------------------------------------------------------- /PSVita_PCSG00776_Muv_Luv.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00776] Muv-Luv 3 | // @version 1.00 4 | // @author [blacktide082] 5 | // @description Vita3k 6 | // * 5pb 7 | // ==/UserScript== 8 | 9 | const { setHook } = require("./libVita3k.js"); 10 | const handler = trans.send(s => s || null, '100+'); 11 | 12 | setHook({ 13 | 0x80118f10: callback.bind_(null, 5, 0, "dialogue"), 14 | 0x80126e7e: callback.bind_(null, 0, 0, "choices"), 15 | }); 16 | 17 | function callback(regs, index, offset, hookname) { 18 | const address = regs[index].value.add(offset); 19 | const text = address.readShiftJisString() 20 | .replace('\u0002', '') // remove STX character 21 | .trim(); 22 | handler(text); 23 | } 24 | -------------------------------------------------------------------------------- /PSVita_PCSG00787_Kyoukai_no_Shirayuki.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00787] Kyoukai no Shirayuki (鏡界の白雪) 3 | // @version 1.00 4 | // @author Mansive 5 | // @description Vita3K 6 | // * Otomate 7 | // * Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, "200+"); // join 200ms 12 | 13 | setHook({ 14 | 0x80025f0e: mainHandler.bind_(null, 5, 0x2, "name"), 15 | 0x80025f1a: mainHandler.bind_(null, 6, 0x2, "text"), 16 | 0x80141978: mainHandler.bind_(null, 1, 0x1, "choice"), 17 | }); 18 | 19 | function handler(regs, index, offset, hookname) { 20 | const address = regs[index].value; 21 | 22 | console.log("onEnter:", hookname); 23 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 24 | 25 | const s = address.readUtf8String().replace(/\\/g, ""); // single line 26 | 27 | if (s === "") { 28 | return null; 29 | } 30 | 31 | return s; 32 | } 33 | -------------------------------------------------------------------------------- /PSVita_PCSG00812_Haitaka_no_Psychedelica.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00812] Haitaka no Psychedelica (灰鷹のサイケデリカ) 3 | // @version 1.00 4 | // @author Mansive 5 | // @description Vita3K 6 | // * Otomate & Idea Factory Co., Ltd. 7 | // ==/UserScript== 8 | const { setHook } = require("./libVita3k.js"); 9 | 10 | const mainHandler = trans.send(handler, "200+"); // join 200ms 11 | 12 | setHook({ 13 | 0x80022c06: mainHandler.bind_(null, 4, "text"), 14 | }); 15 | 16 | function handler(regs, index, hookname) { 17 | const address = regs[index].value; 18 | 19 | console.log("onEnter: ", hookname); 20 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 21 | 22 | let s = address 23 | .readUtf8String() 24 | .replace(/\\n\u3000*|\\k/gu, "") // remove escape characters and fullwidth whitespace 25 | .replace(/\[|\*[^\]]+]/g, "") // remove furigana '災いを[齎*もたら]す' to '災いを齎す' 26 | .replace(/×/g, ""); // remove weird symbol appearing after player name 27 | 28 | return s; 29 | } 30 | -------------------------------------------------------------------------------- /PSVita_PCSG00815_PsychicEmotion6.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00815] PsychicEmotion6 (サイキックエモーション ムー) 3 | // @version 1.00 4 | // @author Mansive 5 | // @description Vita3K 6 | // * Otomate 7 | // * Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, "200+"); 12 | 13 | setHook({ 14 | 0x80035948: mainHandler.bind_(null, 9, "text"), 15 | 0x80034580: mainHandler.bind_(null, 6, "choice"), 16 | }); 17 | 18 | function handler(regs, index, hookname) { 19 | const address = regs[index].value; 20 | 21 | // console.log("onEnter: ", hookname); 22 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 23 | 24 | let s = address 25 | .readUtf8String() 26 | .replace(/\s*(#n)*\s*/g, "") 27 | .replace(/#\w+(\[.+?\])?/g, ""); // Not sure if needed but using just in case 28 | 29 | return s; 30 | } 31 | -------------------------------------------------------------------------------- /PSVita_PCSG00852_Magic_Kyun_Renaissance.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00852] Magic Kyun! Renaissance (マジきゅんっ!ルネッサンス) 3 | // @version 1.00 4 | // @author Mansive 5 | // @description Vita3K 6 | // * HuneX 7 | // * Broccoli 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, "200+"); 12 | 13 | setHook({ 14 | // 0x8001b29c: mainHandler.bind_(null, 5, "name"), 15 | 0x8008375a: mainHandler.bind_(null, 1, "text"), 16 | 0x8001c194: mainHandler.bind_(null, 1, "choice"), 17 | }); 18 | 19 | function handler(regs, index, hookname) { 20 | const address = regs[index].value; 21 | 22 | // console.log("onEnter: ", hookname); 23 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 24 | 25 | let s = address.readShiftJisString().replace(/\^/g, "").replace(/�L/g, " "); 26 | 27 | if (s === "") { 28 | return null; 29 | } 30 | 31 | return s; 32 | } 33 | -------------------------------------------------------------------------------- /PSVita_PCSG00903_New_Game!_The_Challenge_Stage!.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00903] New Game! The Challenge Stage! 3 | // @version 1.00 4 | // @author [DC] 5 | // @description Vita3k 6 | // * MAGES. GAME 7 | // * 5pb. 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | setHook({ 12 | // 0x0022b738(2) 0x0022b74c(0) | 0x0022b74c-0x00109000+0x80004000=0x8012674c 13 | 0x8012674c: trans.send(handler.bind_(null, 0), '200+') // join 200ms (dialouge + choice + ...; \n); x0 14 | }); 15 | 16 | function handler(regs, index) { 17 | const address = regs[index].value; 18 | 19 | console.warn('onEnter'); 20 | //console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 21 | 22 | /* processString */ 23 | const len = address.add(0x14).readU32(); 24 | //console.log(ArrayBuffer.wrap(address.add(0x1C), len)); 25 | 26 | let s = address.add(0x1C).readUtf8String(len); 27 | 28 | // filters 29 | s = s.replace(/\\n/g, ' '); // single line 30 | 31 | return s; 32 | } 33 | -------------------------------------------------------------------------------- /PSVita_PCSG00911_Re_Birthday_Song_Koi_o_Utau_Shinigami.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00911] Re:Birthday Song ~Koi o Utau Shinigami~ 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // *honeybee 7 | // ==/UserScript== 8 | trans.replace(function (s) { 9 | return s 10 | .replaceAll(/%N/g, '') 11 | ; 12 | }); 13 | //------------------------------------------------ 14 | const { setHook } = require("./libVita3k.js"); 15 | 16 | const mainHandler = trans.send(handler, '200++'); // join 200ms 17 | 18 | setHook({ 19 | 20 | 0x80033af6: mainHandler.bind_(null, 0, 0, "dialogue"), 21 | 22 | 23 | }); 24 | 25 | function handler(regs, index, offset, hookname) { 26 | const address = regs[index].value.add(offset); 27 | 28 | console.log("onEnter: " + hookname); 29 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 30 | 31 | let s = address.add(0x2).readShiftJisString() 32 | 33 | return s; 34 | } 35 | -------------------------------------------------------------------------------- /PSVita_PCSG00916_Starry_Sky_Summer_Stories.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00916] Starry☆Sky ~Summer Stories~ / Starry Sky ~Summer Stories~ 3 | // @version 1.00 4 | // @author Mansive 5 | // @description Vita3K 6 | // * honeybee 7 | // ==/UserScript== 8 | const { setHook } = require("./libVita3k.js"); 9 | 10 | const mainHandler = trans.send(handler, "200+"); 11 | 12 | setHook({ 13 | 0x80035634: mainHandler.bind_(null, 3, 0x0, "name"), 14 | 0x80034114: mainHandler.bind_(null, 0, 0x0, "text"), 15 | 0x8002c77a: mainHandler.bind_(null, 0, 0x8, "choice"), 16 | }); 17 | 18 | function handler(regs, index, offset, hookname) { 19 | const address = regs[index].value; 20 | 21 | // console.log("onEnter: ", hookname); 22 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 23 | 24 | const s = address.add(offset).readShiftJisString().replace(/%N/g, ""); 25 | 26 | return s; 27 | } 28 | -------------------------------------------------------------------------------- /PSVita_PCSG00917_Starry_Sky_Autumn_Stories.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00917] Starry☆Sky ~Autumn Stories~ / Starry Sky ~Autumn Stories~ 3 | // @version 1.00, 1.01 4 | // @author Mansive 5 | // @description Vita3K 6 | // * honeybee 7 | // ==/UserScript== 8 | const gameVer = "1.01"; 9 | 10 | const { setHook } = require("./libVita3k.js"); 11 | 12 | const mainHandler = trans.send(handler, "200+"); 13 | 14 | setHook( 15 | { 16 | "1.00": { 17 | 0x80035b10: mainHandler.bind_(null, 3, 0x0, "name"), 18 | 0x800345f0: mainHandler.bind_(null, 0, 0x0, "text"), 19 | 0x8002cc56: mainHandler.bind_(null, 0, 0x8, "choice"), 20 | }, 21 | 1.01: { 22 | 0x80035b2c: mainHandler.bind_(null, 3, 0x0, "name"), 23 | 0x8003460c: mainHandler.bind_(null, 0, 0x0, "text"), 24 | 0x8002cc72: mainHandler.bind_(null, 0, 0x8, "choice"), 25 | }, 26 | }[(globalThis.gameVer = globalThis.gameVer ?? gameVer)] 27 | ); 28 | 29 | function handler(regs, index, offset, hookname) { 30 | const address = regs[index].value; 31 | 32 | // console.log("onEnter: ", hookname); 33 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 34 | 35 | const s = address.add(offset).readShiftJisString().replace(/%N/g, ""); 36 | 37 | return s; 38 | } 39 | -------------------------------------------------------------------------------- /PSVita_PCSG00918_Starry_Sky_Winter_Stories.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG00916] Starry☆Sky ~Winter Stories~ / Starry Sky ~Winter Stories~ 3 | // @version 1.00 + 1.01 4 | // @author Mansive 5 | // @description Vita3K 6 | // * honeybee 7 | // ==/UserScript== 8 | const { setHook } = require("./libVita3k.js"); 9 | 10 | const mainHandler = trans.send(handler, "200+"); 11 | 12 | setHook({ 13 | 0x80035a20: mainHandler.bind_(null, 3, 0x0, "name"), 14 | 0x80034500: mainHandler.bind_(null, 0, 0x0, "text"), 15 | 0x8002cb66: mainHandler.bind_(null, 0, 0x8, "choice"), 16 | }); 17 | 18 | function handler(regs, index, offset, hookname) { 19 | const address = regs[index].value; 20 | 21 | // console.log("onEnter: ", hookname); 22 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 23 | 24 | const s = address.add(offset).readShiftJisString().replace(/%N/g, ""); 25 | 26 | return s; 27 | } 28 | -------------------------------------------------------------------------------- /PSVita_PCSG01008_MARGINAL_#4_ROAD_TO_GALAXY.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG01008] Marginal #4 Road to Galaxy 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // * Otomate / Rejet 7 | // * Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, "200++"); // join 200ms 12 | 13 | setHook({ 14 | 0x8002ff90: mainHandler.bind_(null, 0, 0, "text"), 15 | }); 16 | 17 | function handler(regs, index, offset, hookname) { 18 | const address = regs[index].value.add(offset); 19 | 20 | console.log("onEnter", hookname); 21 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 22 | 23 | let s = address.readUtf8String(); 24 | 25 | const rubis = s.matchAll(/(#Ruby\[)([^,]+).([^\]]+)./g); 26 | for (const rubi of rubis) { 27 | console.log("rubi", rubi[3]); 28 | console.log("rube", rubi[2]); 29 | } 30 | // remove rubi 31 | s = s.replace(/(#Ruby\[)([^,]+).([^\]]+)./g, "$2"); 32 | 33 | s = s 34 | .replace(/(#n)+/g, " ") // Single line 35 | .replace(/(#[A-Za-z]+\[(\d*[.])?\d+\])+/g, ""); // Remove controls 36 | 37 | return s; 38 | } -------------------------------------------------------------------------------- /PSVita_PCSG01019_Tsumikui _Sen_no_Noroi_Sen_no_Inori.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG01019] Tsumikui ~Sen no Noroi, Sen no Inori~ for V 3 | // @version 1.0 4 | // @author kenzy 5 | // @description Vita3k 6 | // * Operetta 7 | // * Dramatic Create 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, '200+'); 12 | 13 | setHook({ 14 | 0x80080cd0: mainHandler.bind_(null, 0), // text 15 | // 0x80080d4a: mainHandler.bind_(null, 0), // names 16 | 0x8001c73e: mainHandler.bind_(null, 1), // choices 17 | }); 18 | 19 | function handler(regs, index, hookname) { 20 | const address = regs[index].value; 21 | // console.log("onEnter: ", hookname); 22 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 23 | 24 | let s = address.readShiftJisString(); 25 | 26 | return s; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /PSVita_PCSG01023_Tsuihou_Senkyo.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG01023] Tsuihou Senkyo 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // *Nippon Ichi Software & Regista 7 | // ==/UserScript== 8 | trans.replace(function (s) { 9 | return s 10 | .replace(/
/g, '') 11 | .replace(/%CF11F/g, "") 12 | .replace(/%CFFFF/g, "") 13 | .replace(/%K%P/g, '') 14 | .replace(/%K%N/g, '') 15 | .replaceAll("\n", '') 16 | 17 | ; 18 | }); 19 | //------------------------------------------------ 20 | const { setHook } = require("./libVita3k.js"); 21 | 22 | const mainHandler = trans.send(handler, "200+"); // join 200ms 23 | 24 | setHook({ 25 | 0x8002e176: mainHandler.bind_(null, 0, 0, "dialogue"),//dialogue+name 26 | }); 27 | 28 | function handler(regs, index, offset, hookname) { 29 | const address = regs[index].value.add(offset); 30 | 31 | console.log("onEnter: " + hookname); 32 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 33 | 34 | let s = address.readShiftJisString(); 35 | 36 | 37 | return s; 38 | } 39 | -------------------------------------------------------------------------------- /PSVita_PCSG01046_Usotsuki_Shangri_La.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG01046] Usotsuki Shangri-La (嘘月シャングリラ) 3 | // @version 1.0 4 | // @author kenzy 5 | // @description Vita3k 6 | // * Rejet 7 | // * 8 | // ==/UserScript== 9 | 10 | const { setHook } = require("./libVita3k.js"); 11 | 12 | const mainHandler = trans.send(handler, '200+'); 13 | 14 | console.log("In NVL section, the text will be displayed block by block rather than line by line.") 15 | 16 | setHook({ 17 | 0x81e1f5c8: mainHandler.bind_(null, 0, 0, 'text'), 18 | 0x81e4a514: mainHandler.bind_(null, 0, 0, 'choices'), 19 | }); 20 | 21 | function handler(regs, index, offset, hookname) { 22 | const address = regs[index].value.add(offset); 23 | // console.log("onEnter", hookname); 24 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x80 })); 25 | 26 | const len = address.add(0x8).readU32() * 2; 27 | let s = address.add(0xC).readUtf16String(len); 28 | s = s.replace(/
/g, ''); 29 | 30 | return s; 31 | } 32 | -------------------------------------------------------------------------------- /PSVita_PCSG01066_Chouchou_Jiken_Lovesodic.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG01066] Chouchou Jiken Lovesodic / Chouchou Jiken Rhapsodic (蝶々事件ラブソディック) 3 | // @version 1.00 4 | // @author Mansive 5 | // @description Vita3K 6 | // * RED 7 | // * Idea Factory Co., Ltd. & Otomate 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, "200+"); 12 | 13 | setHook({ 14 | // 0x80090fe0: mainHandler.bind_(null, 11, "name"), 15 | 0x8008dea2: mainHandler.bind_(null, 4, "text"), 16 | 0x8008eb38: mainHandler.bind_(null, 0, "choice"), 17 | }); 18 | 19 | function handler(regs, index, hookname) { 20 | const address = regs[index].value; 21 | 22 | console.log("onEnter: ", hookname); 23 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 24 | 25 | let s = address.readUtf8String().replace(/\n\u3000*/gu, ""); 26 | 27 | return s; 28 | } 29 | -------------------------------------------------------------------------------- /PSVita_PCSG01110_Code_Realize_Shirogane_no_Kiseki.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG01110] Code: Realize ~Shirogane no Kiseki~ (Code:Realize ~白銀の奇跡~) 3 | // @version 1.00 4 | // @author Mansive 5 | // @description Vita3K 6 | // * Design Factory Co., Ltd. & Otomate 7 | // * Idea Factory Co., Ltd. 8 | // ==/UserScript== 9 | const { setHook } = require("./libVita3k.js"); 10 | 11 | const mainHandler = trans.send(handler, "200+"); // join 200ms 12 | 13 | setHook({ 14 | 0x80015bcc: mainHandler.bind_(null, 0, 0x1c, "text"), 15 | 0x80038e76: mainHandler.bind_(null, 8, 0, "dict"), 16 | }); 17 | 18 | let previous = ""; 19 | 20 | function handler(regs, index, offset, hookname) { 21 | const address = regs[index].value; 22 | 23 | // console.log("onEnter: ", hookname); 24 | // console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 25 | 26 | let s = address 27 | .add(offset) 28 | .readUtf8String() 29 | .replace(/#\w+(\[.+?\])?/g, "") 30 | .replace(/\u3000/gu, ""); 31 | 32 | if (s === "" || s === previous) { 33 | return null; 34 | } 35 | previous = s; 36 | 37 | return s; 38 | } 39 | -------------------------------------------------------------------------------- /PSVita_PCSG01180_Tengai_ni_Mau_Iki_na_Hana.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG01180] Tengai ni Mau, Iki na Hana 3 | // @version 1.00 4 | // @author nanaa 5 | // @description Vita3k 6 | // Ichi Column 7 | // ==/UserScript== 8 | const { setHook } = require("./libVita3k.js"); 9 | 10 | const mainHandler = trans.send(handler, "200++"); // join 200ms 11 | 12 | setHook({ 13 | 0x8006808e: mainHandler.bind_(null, 0, 0, "dialogue"), 14 | 0x80089408: mainHandler.bind_(null, 0, 0, "choices"), 15 | }); 16 | 17 | function handler(regs, index, offset, hookname) { 18 | const address = regs[index].value.add(offset); 19 | 20 | //console.log("onEnter", hookname); 21 | let s = address.readUtf8String(); 22 | s = s.replace(/\\n/g, ' '); // single line 23 | s = s.replace(/,.*$/,' '); 24 | 25 | return s; 26 | } 27 | -------------------------------------------------------------------------------- /PSVita_PCSG01268_Kannagi_no_Mori_Satsukiame_Tsuzuri.js: -------------------------------------------------------------------------------- 1 | // ==UserScript== 2 | // @name [PCSG01268] 神凪ノ杜 Kannagi no Mori Satsukiame Tsuzuri 3 | // @version 0.1 4 | // @author GO123 5 | // @description Vita3k 6 | // *Matatabi 7 | // ==/UserScript== 8 | trans.replace(function (s) { 9 | return s 10 | .replace(/
/g, '') 11 | 12 | ; 13 | }); 14 | //------------------------------------------------ 15 | const { setHook } = require("./libVita3k.js"); 16 | 17 | const mainHandler = trans.send(handler, "200+"); // join 200ms 18 | 19 | setHook({ 20 | 0x828bb50c: mainHandler.bind_(null, 0, 0, "dialogue"),//dialogue 21 | 0x828ba9b6: mainHandler.bind_(null, 0, 0, "name"),//name 22 | }); 23 | 24 | function handler(regs, index, offset, hookname) { 25 | const address = regs[index].value.add(offset); 26 | 27 | console.log("onEnter: " + hookname); 28 | console.log(hexdump(address, { header: false, ansi: false, length: 0x50 })); 29 | 30 | const len = address.add(0x8).readU32() * 2; 31 | let s = address.add(0xC).readUtf16String(len); 32 | 33 | 34 | return s; 35 | } 36 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scripts 2 | A collection of scripts for [Agent](https://github.com/0xDC00/agent). 3 | -------------------------------------------------------------------------------- /libLoader.js.qjs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/0xDC00/scripts/6838069c3721982c378d71529eb61c28504315c5/libLoader.js.qjs -------------------------------------------------------------------------------- /libRyujinx.cjs: -------------------------------------------------------------------------------- 1 | console.warn('[Compatibility]'); 2 | console.warn('Ryujinx 1.1.1340++'); 3 | console.log('[Mirror] Download: https://github.com/koukdw/emulators/releases'); 4 | 5 | console.log(` 6 | 1. ReLaunch Ryujinx (dont boot the game yet). 7 | 2. Attach. 8 | 3. Boot game. 9 | `); 10 | 11 | module.exports = exports = [ 12 | 'H458d5136f', 'H45a45971f', 0 13 | ]; 14 | -------------------------------------------------------------------------------- /libTranslate.js: -------------------------------------------------------------------------------- 1 | if (typeof module !== 'undefined') { 2 | module.exports = { 3 | Google: require('./libTranslateGoogle.js'), 4 | DeepL: require('./libTranslateDeepL.js'), 5 | Microsoft: require('./libTranslateMicrosoft.js'), 6 | VietPhrase: require('./libTranslateVietPhrase.js') 7 | }; 8 | } 9 | else { 10 | return ['Google', 'DeepL', 'Microsoft', 'VietPhrase']; 11 | } -------------------------------------------------------------------------------- /libTranslateVietPhrase.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | function init(sl, tl) { } 3 | 4 | function translate(str, sl, tl) { 5 | return createRequest(str, sl, tl) 6 | .then(r => r.text()) 7 | .then(r => r.replace(/\t+/g, '')); 8 | } 9 | 10 | function createRequest(str, sl, tl) { 11 | str = JSON.stringify(str); 12 | const body = '{"chineseContent":' + str + '}'; 13 | return fetch("https://vietphrase.info/Vietphrase/TranslateVietPhraseS", { 14 | headers: { 15 | 'content-type': 'application/json; charset=utf-8' 16 | }, 17 | method: "POST", 18 | body: body 19 | }); 20 | } 21 | 22 | function setSrc(v) { } 23 | function setDst(v) { } 24 | 25 | if (typeof module !== 'undefined') { 26 | module.exports = { init, translate, setSrc, setDst, createRequest }; 27 | } 28 | else { 29 | init(); 30 | globalThis._init = init; 31 | globalThis._trans = translate; 32 | } 33 | })(); --------------------------------------------------------------------------------