Util: Implement ScenePrepoFunction (#1001)

This commit is contained in:
Fuzzy2319 2026-03-30 18:52:32 +02:00 committed by GitHub
parent e95a370468
commit 976594c87c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 541 additions and 51 deletions

View file

@ -158496,87 +158496,87 @@ Util/ScenePrepoFunction.o:
- offset: 0x574094 - offset: 0x574094
size: 288 size: 288
label: _ZN2rs32trySavePrepoCompleteMainScenarioEiilll label: _ZN2rs32trySavePrepoCompleteMainScenarioEiilll
status: NotDecompiled status: Matching
- offset: 0x5741b4 - offset: 0x5741b4
size: 380 size: 380
label: _ZN2rs22trySavePrepoStartStageEPKcRKN4sead7Vector3IfEElll label: _ZN2rs22trySavePrepoStartStageEPKcRKN4sead7Vector3IfEElll
status: NotDecompiled status: Matching
- offset: 0x574330 - offset: 0x574330
size: 380 size: 380
label: _ZN2rs21trySavePrepoExitStageEPKcRKN4sead7Vector3IfEElll label: _ZN2rs21trySavePrepoExitStageEPKcRKN4sead7Vector3IfEElll
status: NotDecompiled status: Matching
- offset: 0x5744ac - offset: 0x5744ac
size: 380 size: 380
label: _ZN2rs21trySavePrepoMissEventEPKcRKN4sead7Vector3IfEElll label: _ZN2rs21trySavePrepoMissEventEPKcRKN4sead7Vector3IfEElll
status: NotDecompiled status: Matching
- offset: 0x574628 - offset: 0x574628
size: 364 size: 364
label: _ZN2rs25trySavePrepoShineGetEventEPKciiilll label: _ZN2rs25trySavePrepoShineGetEventEPKciiilll
status: NotDecompiled status: Matching
- offset: 0x574794 - offset: 0x574794
size: 308 size: 308
label: _ZN2rs30trySavePrepoReceiveAchievementEPKcilll label: _ZN2rs30trySavePrepoReceiveAchievementEPKcilll
status: NotDecompiled status: Matching
- offset: 0x5748c8 - offset: 0x5748c8
size: 1216 size: 1216
label: _ZN2rs31trySavePrepoAchievementProgressE22GameDataHolderAccessorlll label: _ZN2rs31trySavePrepoAchievementProgressE22GameDataHolderAccessorlll
status: NotDecompiled status: Matching
- offset: 0x574d88 - offset: 0x574d88
size: 324 size: 324
label: _ZN2rs23trySavePrepoGetCapEventEPKcilll label: _ZN2rs23trySavePrepoGetCapEventEPKcilll
status: NotDecompiled status: Matching
- offset: 0x574ecc - offset: 0x574ecc
size: 328 size: 328
label: _ZN2rs25trySavePrepoGetClothEventEPKcilll label: _ZN2rs25trySavePrepoGetClothEventEPKcilll
status: NotDecompiled status: Matching
- offset: 0x575014 - offset: 0x575014
size: 328 size: 328
label: _ZN2rs24trySavePrepoGetGiftEventEPKcilll label: _ZN2rs24trySavePrepoGetGiftEventEPKcilll
status: NotDecompiled status: Matching
- offset: 0x57515c - offset: 0x57515c
size: 328 size: 328
label: _ZN2rs27trySavePrepoGetStickerEventEPKcilll label: _ZN2rs27trySavePrepoGetStickerEventEPKcilll
status: NotDecompiled status: Matching
- offset: 0x5752a4 - offset: 0x5752a4
size: 292 size: 292
label: _ZN2rs26trySavePrepoChangeCapEventEPKclll label: _ZN2rs26trySavePrepoChangeCapEventEPKclll
status: NotDecompiled status: Matching
- offset: 0x5753c8 - offset: 0x5753c8
size: 296 size: 296
label: _ZN2rs28trySavePrepoChangeClothEventEPKclll label: _ZN2rs28trySavePrepoChangeClothEventEPKclll
status: NotDecompiled status: Matching
- offset: 0x5754f0 - offset: 0x5754f0
size: 308 size: 308
label: _ZN2rs26trySavePrepoFirstHackEventEPKcilll label: _ZN2rs26trySavePrepoFirstHackEventEPKcilll
status: NotDecompiled status: Matching
- offset: 0x575624 - offset: 0x575624
size: 384 size: 384
label: _ZN2rs30trySavePrepoGetCollectBgmEventEPKcS1_billl label: _ZN2rs30trySavePrepoGetCollectBgmEventEPKcS1_billl
status: NotDecompiled status: Matching
- offset: 0x5757a4 - offset: 0x5757a4
size: 504 size: 504
label: _ZN2rs25trySavePrepoSettingsStateEbPKcRK14GameConfigDatall label: _ZN2rs25trySavePrepoSettingsStateEbPKcRK14GameConfigDatall
status: NotDecompiled status: Matching
- offset: 0x57599c - offset: 0x57599c
size: 256 size: 256
label: _ZN2rs28trySavePrepoSeparatePlayModeEblll label: _ZN2rs28trySavePrepoSeparatePlayModeEblll
status: NotDecompiled status: Matching
- offset: 0x575a9c - offset: 0x575a9c
size: 4 size: 4
label: _ZN2rs5prepo17enableIsSavePrepoEv label: _ZN2rs5prepo17enableIsSavePrepoEv
status: NotDecompiled status: Matching
- offset: 0x575aa0 - offset: 0x575aa0
size: 4 size: 4
label: _ZN2rs5prepo18disableIsSavePrepoEv label: _ZN2rs5prepo18disableIsSavePrepoEv
status: NotDecompiled status: Matching
- offset: 0x575aa4 - offset: 0x575aa4
size: 68 size: 68
label: _ZN2rs5prepo18generateSaveDataIdEv label: _ZN2rs5prepo18generateSaveDataIdEv
status: NotDecompiled status: Matching
- offset: 0x575ae8 - offset: 0x575ae8
size: 12 size: 12
label: _ZN2rs5prepo17calcPrepoHashCodeEPKc label: _ZN2rs5prepo17calcPrepoHashCodeEPKc
status: NotDecompiled status: Matching
Util/StageInputFunction.o: Util/StageInputFunction.o:
'.text': '.text':
- offset: 0x575af4 - offset: 0x575af4

View file

@ -5,37 +5,37 @@
#include <cstring> #include <cstring>
namespace al { namespace al {
s32 calcHashCode(const char* str) { u32 calcHashCode(const char* str) {
if (str[0] == '\0') if (str[0] == '\0')
return 0; return 0;
s32 hashCode = 0; u32 hashCode = 0;
for (s32 i = 0; str[i] != '\0'; i++) for (s32 i = 0; str[i] != '\0'; i++)
hashCode = (hashCode * 0x1f) + str[i]; hashCode = (hashCode * 0x1f) + str[i];
return hashCode; return hashCode;
} }
s32 calcHashCodeLower(const char* str) { u32 calcHashCodeLower(const char* str) {
s32 hashCode = 0; u32 hashCode = 0;
for (s32 i = 0; str[i] != '\0'; i++) for (s32 i = 0; str[i] != '\0'; i++)
hashCode = (hashCode * 0x1f) + tolower(str[i]); hashCode = (hashCode * 0x1f) + tolower(str[i]);
return hashCode; return hashCode;
} }
s32 calcHashCodeFmt(const char* format, std::va_list argv) { u32 calcHashCodeFmt(const char* format, std::va_list argv) {
char buf[0x100]; char buf[0x100];
vsnprintf(buf, 0x100, format, argv); vsnprintf(buf, 0x100, format, argv);
return calcHashCode(buf); return calcHashCode(buf);
} }
s32 calcHashCodeFmt(const char* format, ...) { u32 calcHashCodeFmt(const char* format, ...) {
std::va_list argv; std::va_list argv;
va_start(argv, format); va_start(argv, format);
s32 result = calcHashCodeFmt(format, argv); u32 result = calcHashCodeFmt(format, argv);
va_end(argv); va_end(argv);
return result; return result;

View file

@ -4,9 +4,9 @@
#include <cstdarg> #include <cstdarg>
namespace al { namespace al {
s32 calcHashCode(const char* str); u32 calcHashCode(const char* str);
s32 calcHashCodeLower(const char* str); u32 calcHashCodeLower(const char* str);
s32 calcHashCodeFmt(const char* format, std::va_list argv); u32 calcHashCodeFmt(const char* format, std::va_list argv);
s32 calcHashCodeFmt(const char* format, ...); u32 calcHashCodeFmt(const char* format, ...);
const char* getBaseName(const char* name); const char* getBaseName(const char* name);
} // namespace al } // namespace al

View file

@ -0,0 +1,460 @@
#include "Util/ScenePrepoFunction.h"
#include <nn/account.h>
#include <nn/prepo.h>
#include <nn/time.h>
#include "Library/Base/HashCodeUtil.h"
#include "System/GameConfigData.h"
#include "System/GameDataFunction.h"
#include "System/GameDataUtil.h"
#include "Util/AchievementUtil.h"
#include "Util/ClothUtil.h"
namespace rs {
static char buffer[0x2000];
bool trySavePrepoCompleteMainScenario(s32 worldId, s32 mainScenarioNo, s64 playTime, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("complete_main_scenario_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(6));
playReport.Add("world_id", static_cast<s64>(worldId));
playReport.Add("main_scenario_no", static_cast<s64>(mainScenarioNo));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoStartStage(const char* stageName, const sead::Vector3f& position, s64 playTime,
s64 saveDataId, s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("stage_in_out_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
// BUG: buffer too small (prepared for 8 entries, adds 9)
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(8));
playReport.Add("stage_name", static_cast<s64>(prepo::calcPrepoHashCode(stageName)));
playReport.Add("x", position.x);
playReport.Add("y", position.y);
playReport.Add("z", position.z);
playReport.Add("in_out_type", InOutType_Start);
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoExitStage(const char* stageName, const sead::Vector3f& position, s64 playTime,
s64 saveDataId, s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("stage_in_out_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
// BUG: buffer too small (prepared for 8 entries, adds 9)
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(8));
playReport.Add("stage_name", static_cast<s64>(prepo::calcPrepoHashCode(stageName)));
playReport.Add("x", position.x);
playReport.Add("y", position.y);
playReport.Add("z", position.z);
playReport.Add("in_out_type", InOutType_Exit);
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoMissEvent(const char* stageName, const sead::Vector3f& position, s64 playTime,
s64 saveDataId, s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("stage_in_out_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
// BUG: buffer too small (prepared for 8 entries, adds 9)
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(8));
playReport.Add("stage_name", static_cast<s64>(prepo::calcPrepoHashCode(stageName)));
playReport.Add("x", position.x);
playReport.Add("y", position.y);
playReport.Add("z", position.z);
playReport.Add("in_out_type", InOutType_Miss);
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoShineGetEvent(const char* stageName, s32 shineId, s32 totalShineNum,
s32 totalShopShineNum, s64 playTime, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("shine_get_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(8));
playReport.Add("stage_name", static_cast<s64>(prepo::calcPrepoHashCode(stageName)));
playReport.Add("shine_id", static_cast<s64>(shineId));
playReport.Add("total_shine_num", static_cast<s64>(totalShineNum));
playReport.Add("total_shop_shine_num", static_cast<s64>(totalShopShineNum));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoReceiveAchievement(const char* achievementName, s32 receivedNum, s64 playTime,
s64 saveDataId, s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("receive_achievement_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(6));
playReport.Add("achievement_name", static_cast<s64>(prepo::calcPrepoHashCode(achievementName)));
playReport.Add("received_num", static_cast<s64>(receivedNum));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoAchievementProgress(GameDataHolderAccessor accessor, s64 playTime, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("achievement_progress_state");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(38));
playReport.Add("shine_gather", static_cast<s64>(GameDataFunction::getTotalShineNum(accessor)));
playReport.Add("shine_collect_coin_shop",
static_cast<s64>(calcBuyItemNumForCoinCollectByWorld(accessor)));
playReport.Add("shine_shine_2d", static_cast<s64>(calcGetShineNumDot(accessor)));
playReport.Add("shine_treasure_box", static_cast<s64>(calcGetShineNumTreasureBox(accessor)));
playReport.Add("shine_music_note", static_cast<s64>(calcGetShineNumNoteObj(accessor)));
// typo: athretic / athletic
playReport.Add("shine_timer_athretic",
static_cast<s64>(calcGetShineNumTimerAthletic(accessor)));
playReport.Add("shine_captain_kinopio",
static_cast<s64>(calcGetShineNumKinopioBrigade(accessor)));
playReport.Add("shine_traveling_peach",
static_cast<s64>(calcGetShineNumWorldTravelingPeach(accessor)));
playReport.Add("shine_collect_animal_all",
static_cast<s64>(calcGetShineNumCollectAnimal(accessor)));
playReport.Add("shine_kuribo_girl", static_cast<s64>(calcGetShineNumKuriboGirl(accessor)));
playReport.Add("shine_jugem", static_cast<s64>(calcGetShineNumJugemFish(accessor)));
playReport.Add("shine_seed", static_cast<s64>(calcGetShineNumGrowPlant(accessor)));
playReport.Add("shine_rabbit", static_cast<s64>(calcGetShineNumRabbit(accessor)));
playReport.Add("shine_dig_point", static_cast<s64>(calcGetShineNumDigPoint(accessor)));
playReport.Add("shine_cap_hanger", static_cast<s64>(calcGetShineNumCapHanger(accessor)));
playReport.Add("shine_bird", static_cast<s64>(calcGetShineNumBird(accessor)));
playReport.Add("shine_costume_room", static_cast<s64>(calcGetShineNumCostumeRoom(accessor)));
playReport.Add("shine_cap_throttle", static_cast<s64>(calcGetShineNumSlot(accessor)));
playReport.Add("shine_hide_and_seek_cap_man",
static_cast<s64>(calcGetShineNumHideAndSeekCapMan(accessor)));
playReport.Add("shine_collect_bgm", static_cast<s64>(calcGetShineNumCollectedBgm(accessor)));
playReport.Add("shine_hint_photo", static_cast<s64>(calcGetShineNumHintPhoto(accessor)));
playReport.Add("mini_game_race_man", static_cast<s64>(calcGetShineNumRace(accessor)));
playReport.Add("mini_game_figure_walker",
static_cast<s64>(calcGetShineNumFigureWalking(accessor)));
playReport.Add("mini_game_sphinx_quiz", static_cast<s64>(calcSphinxQuizCompleteNum(accessor)));
playReport.Add("souvenir_count",
static_cast<s64>(calcHaveGiftNum(accessor) + calcHaveStickerNum(accessor)));
playReport.Add("capture_count", static_cast<s64>(calcHackObjNum(accessor)));
playReport.Add("costume_cap", static_cast<s64>(calcHaveCapNum(accessor)));
playReport.Add("costume_clothes", static_cast<s64>(calcHaveClothNum(accessor)));
playReport.Add("other_moon_stone_all", static_cast<s64>(calcUnlockMoonRockNum(accessor)));
playReport.Add("other_world_warp_hole_all",
static_cast<s64>(calcWorldWarpHoleThroughNum(accessor)));
playReport.Add("other_check_point", static_cast<s64>(calcGetCheckpointNum(accessor)));
playReport.Add("other_coin", static_cast<s64>(getTotalCoinNum(accessor)));
playReport.Add("other_jump", static_cast<s64>(getPlayerJumpCount(accessor)));
playReport.Add("other_cap_throw", static_cast<s64>(getPlayerThrowCapCount(accessor)));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoGetCapEvent(const char* itemName, s32 totalNum, s64 playTime, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("collect_item_get_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(7));
playReport.Add("category", ItemCategoryType_Cap);
playReport.Add("item_name", static_cast<s64>(prepo::calcPrepoHashCode(itemName)));
playReport.Add("total_num", static_cast<s64>(totalNum));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoGetClothEvent(const char* itemName, s32 totalNum, s64 playTime, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("collect_item_get_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(7));
playReport.Add("category", ItemCategoryType_Cloth);
playReport.Add("item_name", static_cast<s64>(prepo::calcPrepoHashCode(itemName)));
playReport.Add("total_num", static_cast<s64>(totalNum));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoGetGiftEvent(const char* itemName, s32 totalNum, s64 playTime, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("collect_item_get_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(7));
playReport.Add("category", ItemCategoryType_Gift);
playReport.Add("item_name", static_cast<s64>(prepo::calcPrepoHashCode(itemName)));
playReport.Add("total_num", static_cast<s64>(totalNum));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoGetStickerEvent(const char* itemName, s32 totalNum, s64 playTime, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("collect_item_get_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(7));
playReport.Add("category", ItemCategoryType_Sticker);
playReport.Add("item_name", static_cast<s64>(prepo::calcPrepoHashCode(itemName)));
playReport.Add("total_num", static_cast<s64>(totalNum));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoChangeCapEvent(const char* itemName, s64 playTime, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("cloth_change_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(6));
playReport.Add("category", ItemCategoryType_Cap);
playReport.Add("item_name", static_cast<s64>(prepo::calcPrepoHashCode(itemName)));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoChangeClothEvent(const char* itemName, s64 playTime, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("cloth_change_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(6));
playReport.Add("category", ItemCategoryType_Cloth);
playReport.Add("item_name", static_cast<s64>(prepo::calcPrepoHashCode(itemName)));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoFirstHackEvent(const char* hackObjName, s32 totalHackedObjNum, s64 playTime,
s64 saveDataId, s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("first_hack_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(6));
playReport.Add("hack_obj_name", static_cast<s64>(prepo::calcPrepoHashCode(hackObjName)));
playReport.Add("total_hacked_obj_num", static_cast<s64>(totalHackedObjNum));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoGetCollectBgmEvent(const char* bgmResourceName, const char* bgmSituationName,
bool isBailout, s32 collectedBgmNum, s64 playTime,
s64 saveDataId, s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("get_collect_bgm_event");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(8));
playReport.Add("bgm_resource_name",
static_cast<s64>(prepo::calcPrepoHashCode(bgmResourceName)));
playReport.Add("bgm_situation_name",
static_cast<s64>(prepo::calcPrepoHashCode(bgmSituationName)));
playReport.Add("is_bailout", static_cast<s64>(isBailout));
playReport.Add("collected_bgm_num", static_cast<s64>(collectedBgmNum));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoSettingsState(bool isKidsMode, const char* language,
const GameConfigData& configData, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("settings_state");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
// NOTE: buffer too large (prepared for 14 entries, adds 12)
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(14));
playReport.Add("is_kids_mode", static_cast<s64>(isKidsMode));
playReport.Add("language", static_cast<s64>(prepo::calcPrepoHashCode(language)));
playReport.Add("camera_stick_sensitivity_level",
static_cast<s64>(configData.getCameraStickSensitivityLevel()));
bool isCameraReverseInputH = configData.isCameraReverseInputH();
bool isCameraReverseInputV = configData.isCameraReverseInputV();
playReport.Add("camera_reverse_input",
static_cast<s64>((isCameraReverseInputH << 1) | isCameraReverseInputV));
playReport.Add("is_valid_camera_gyro", static_cast<s64>(configData.isValidCameraGyro()));
playReport.Add("camera_gyro_sensitivity_level",
static_cast<s64>(configData.getCameraGyroSensitivityLevel()));
playReport.Add("is_use_open_list_additional_button",
static_cast<s64>(configData.isUseOpenListAdditionalButton()));
playReport.Add("is_valid_pad_rumble", static_cast<s64>(configData.isValidPadRumble()));
playReport.Add("pad_rumble_level", static_cast<s64>(configData.getPadRumbleLevel()));
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
bool trySavePrepoSeparatePlayMode(bool isSeparatePlayMode, s64 playTime, s64 saveDataId,
s64 acrossPlayTime) {
nn::account::Uid lastOpenedUser;
nn::prepo::PlayReport playReport = nn::prepo::PlayReport("separate_play_mode_state");
if (nn::account::GetLastOpenedUser(&lastOpenedUser).IsFailure() || !lastOpenedUser.IsValid())
return false;
playReport.SetBuffer(&buffer, nn::prepo::PlayReport::CalcBufferSize(5));
playReport.Add("is_separate_play_mode", static_cast<s64>(isSeparatePlayMode));
playReport.Add("play_time", playTime);
playReport.Add("across_play_time", acrossPlayTime);
playReport.Add("save_data_id", saveDataId);
playReport.Add("app_version", 1l);
return playReport.Save(lastOpenedUser).IsSuccess();
}
namespace prepo {
void enableIsSavePrepo() {}
void disableIsSavePrepo() {}
s64 generateSaveDataId() {
if (!nn::time::IsInitialized() && nn::time::Initialize().IsFailure())
return -1l;
nn::time::PosixTime time;
if (nn::time::StandardUserSystemClock::GetCurrentTime(&time).IsFailure())
return -1l;
return time.time;
}
u32 calcPrepoHashCode(const char* str) {
if (!str)
return 0;
return al::calcHashCode(str);
}
} // namespace prepo
} // namespace rs

View file

@ -3,32 +3,62 @@
#include <basis/seadTypes.h> #include <basis/seadTypes.h>
#include <math/seadVector.h> #include <math/seadVector.h>
class GameDataHolderAccessor; #include "System/GameDataHolderAccessor.h"
class GameConfigData; class GameConfigData;
namespace rs { namespace rs {
bool trySavePrepoCompleteMainScenario(s32, s32, s64, s64, s64); enum InOutType : s64 { InOutType_Start, InOutType_Exit, InOutType_Miss };
bool trySavePrepoStartStage(const char*, const sead::Vector3f&, s64, s64, s64);
bool trySavePrepoExitStage(const char*, const sead::Vector3f&, s64, s64, s64); enum ItemCategoryType : s64 {
bool trySavePrepoMissEvent(const char*, const sead::Vector3f&, s64, s64, s64); ItemCategoryType_Cap,
bool trySavePrepoShineGetEvent(const char*, s32, s32, s32, s64, s64, s64); ItemCategoryType_Cloth,
bool trySavePrepoReceiveAchievement(const char* s32, s64, s64, s64); ItemCategoryType_Gift,
bool trySavePrepoAchievementProgress(GameDataHolderAccessor, s64, s64, s64); ItemCategoryType_Sticker
bool trySavePrepoGetCapEvent(const char*, s32, s64, s64, s64); };
bool trySavePrepoGetClothEvent(const char*, s32, s64, s64, s64);
bool trySavePrepoGetGiftEvent(const char*, s32, s64, s64, s64); bool trySavePrepoCompleteMainScenario(s32 worldId, s32 mainScenarioNo, s64 playTime, s64 saveDataId,
bool trySavePrepoGetStickerEvent(const char*, s32, s64, s64, s64); s64 acrossPlayTime);
bool trySavePrepoChangeCapEvent(const char*, s64, s64, s64); bool trySavePrepoStartStage(const char* stageName, const sead::Vector3f& position, s64 playTime,
bool trySavePrepoChangeClothEvent(const char*, s64, s64, s64); s64 saveDataId, s64 acrossPlayTime);
bool trySavePrepoFirstHackEvent(const char*, s32, s64, s64, s64); bool trySavePrepoExitStage(const char* stageName, const sead::Vector3f& position, s64 playTime,
bool trySavePrepoGetCollectBgmEvent(const char*, const char*, bool, s32, s64, s64, s64); s64 saveDataId, s64 acrossPlayTime);
bool trySavePrepoSettingsState(bool, const char*, const GameConfigData&, s64, s64); bool trySavePrepoMissEvent(const char* stageName, const sead::Vector3f& position, s64 playTime,
bool trySavePrepoSeparatePlayMode(bool, s64, s64, s64); s64 saveDataId, s64 acrossPlayTime);
bool trySavePrepoShineGetEvent(const char* stageName, s32 shineId, s32 totalShineNum,
s32 totalShopShineNum, s64 playTime, s64 saveDataId,
s64 acrossPlayTime);
bool trySavePrepoReceiveAchievement(const char* achievementName, s32 receivedNum, s64 playTime,
s64 saveDataId, s64 acrossPlayTime);
bool trySavePrepoAchievementProgress(GameDataHolderAccessor accessor, s64 playTime, s64 saveDataId,
s64 acrossPlayTime);
bool trySavePrepoGetCapEvent(const char* itemName, s32 totalNum, s64 playTime, s64 saveDataId,
s64 acrossPlayTime);
bool trySavePrepoGetClothEvent(const char* itemName, s32 totalNum, s64 playTime, s64 saveDataId,
s64 acrossPlayTime);
bool trySavePrepoGetGiftEvent(const char* itemName, s32 totalNum, s64 playTime, s64 saveDataId,
s64 acrossPlayTime);
bool trySavePrepoGetStickerEvent(const char* itemName, s32 totalNum, s64 playTime, s64 saveDataId,
s64 acrossPlayTime);
bool trySavePrepoChangeCapEvent(const char* itemName, s64 playTime, s64 saveDataId,
s64 acrossPlayTime);
bool trySavePrepoChangeClothEvent(const char* itemName, s64 playTime, s64 saveDataId,
s64 acrossPlayTime);
bool trySavePrepoFirstHackEvent(const char* hackObjName, s32 totalHackedObjNum, s64 playTime,
s64 saveDataId, s64 acrossPlayTime);
bool trySavePrepoGetCollectBgmEvent(const char* bgmResourceName, const char* bgmSituationName,
bool isBailout, s32 collectedBgmNum, s64 playTime,
s64 saveDataId, s64 acrossPlayTime);
bool trySavePrepoSettingsState(bool isKidsMode, const char* language,
const GameConfigData& configData, s64 saveDataId,
s64 acrossPlayTime);
bool trySavePrepoSeparatePlayMode(bool isSeparatePlayMode, s64 playTime, s64 saveDataId,
s64 acrossPlayTime);
namespace prepo { namespace prepo {
void enableIsSavePrepo(); void enableIsSavePrepo();
void disableIsSavePrepo(); void disableIsSavePrepo();
s64 generateSaveDataId(); s64 generateSaveDataId();
s32 calcPrepoHashCode(const char*); u32 calcPrepoHashCode(const char* str);
} // namespace prepo } // namespace prepo
} // namespace rs } // namespace rs