Rando: Allow strings as seed hashes (#2438)

* Allows strings to be used for rando seed hashes;
updated conversion method from `stoi` to `stoul`

* apply suggestions

* Allow spaces + autoselect on input field focus

* Added new text filter; applied suggestions

* leaving 3d rando logic alone

* Apply more suggestions

* Revert buffer size to 1024
This commit is contained in:
Ralphie Morell 2023-02-14 21:43:25 -05:00 committed by GitHub
parent e60f2b0c55
commit 7c3c662eba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 45 additions and 31 deletions

View File

@ -16,6 +16,7 @@
#include "debug.hpp"
#include <spdlog/spdlog.h>
#include "../../randomizer/randomizerTypes.h"
#include <boost_custom/container_hash/hash_32.hpp>
namespace {
bool seedChanged;
@ -512,16 +513,16 @@ void PrintOptionDescription() {
}
std::string GenerateRandomizer(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettings, std::set<RandomizerCheck> excludedLocations,
std::string seedInput) {
std::string seedString) {
srand(time(NULL));
// if a blank seed was entered, make a random one
if (seedInput.empty()) {
if (seedString.empty()) {
Settings::seed = rand() & 0xFFFFFFFF;
} else if (seedInput.rfind("seed_testing_count", 0) == 0 && seedInput.length() > 18) {
} else if (seedString.rfind("seed_testing_count", 0) == 0 && seedString.length() > 18) {
int count;
try {
count = std::stoi(seedInput.substr(18), nullptr);
count = std::stoi(seedString.substr(18), nullptr);
} catch (std::invalid_argument &e) {
count = 1;
} catch (std::out_of_range &e) {
@ -531,8 +532,10 @@ std::string GenerateRandomizer(std::unordered_map<RandomizerSettingKey, uint8_t>
return "";
} else {
try {
int seed = std::stoi(seedInput, nullptr);
uint32_t seedHash = boost::hash_32<std::string>{}(seedString);
int seed = seedHash & 0xFFFFFFFF;
Settings::seed = seed;
Settings::seedString = seedString;
} catch (...) {
return "";
}

View File

@ -12,7 +12,7 @@
#define TICKS_PER_SEC 268123480.0
void RandoMain::GenerateRando(std::unordered_map<RandomizerSettingKey, u8> cvarSettings, std::set<RandomizerCheck> excludedLocations,
std::string seedInput) {
std::string seedString) {
HintTable_Init();
ItemTable_Init();
LocationTable_Init();
@ -20,7 +20,7 @@ void RandoMain::GenerateRando(std::unordered_map<RandomizerSettingKey, u8> cvarS
// std::string settingsFileName = "./randomizer/latest_settings.json";
// CVarSetString("gLoadedPreset", settingsFileName.c_str());
std::string fileName = Ship::Window::GetPathRelativeToAppDirectory(GenerateRandomizer(cvarSettings, excludedLocations, seedInput).c_str());
std::string fileName = Ship::Window::GetPathRelativeToAppDirectory(GenerateRandomizer(cvarSettings, excludedLocations, seedString).c_str());
CVarSetString("gSpoilerLog", fileName.c_str());
CVarSave();

View File

@ -23,6 +23,7 @@ namespace Settings {
std::string hash;
std::string version = RANDOMIZER_VERSION "-" COMMIT_NUMBER;
std::array<uint8_t, 5> hashIconIndexes;
std::string seedString;
bool skipChildZelda = false;

View File

@ -891,6 +891,7 @@ void UpdateSettings(std::unordered_map<RandomizerSettingKey, uint8_t> cvarSettin
extern std::string version;
extern std::array<uint8_t, 5> hashIconIndexes;
extern std::string hash;
extern std::string seedString;
extern bool skipChildZelda;

View File

@ -775,7 +775,7 @@ const char* SpoilerLog_Write(int language) {
jsonData.clear();
jsonData["_version"] = (char*) gBuildVersion;
jsonData["_seed"] = Settings::seed;
jsonData["_seed"] = Settings::seedString;
// Write Hash
int index = 0;

View File

@ -26,6 +26,7 @@
#include <functional>
#include "draw.h"
#include "rando_hash.h"
#include <boost_custom/container_hash/hash_32.hpp>
extern "C" uint32_t ResourceMgr_IsGameMasterQuest();
extern "C" uint32_t ResourceMgr_IsSceneMasterQuest(s16 sceneNum);
@ -39,7 +40,7 @@ std::multimap<std::tuple<s16, s16, s32>, RandomizerCheckObject> checkFromActorMu
std::set<RandomizerCheck> excludedLocations;
u8 generated;
char* seedInputBuffer;
char* seedString;
const std::string Randomizer::getItemMessageTableID = "Randomizer";
const std::string Randomizer::hintMessageTableID = "RandomizerHints";
@ -2949,8 +2950,6 @@ void GenerateRandomizerImgui(std::string seed = "") {
RandoMain::GenerateRando(cvarSettings, excludedLocations, seed);
memset(seedInputBuffer, 0, MAX_SEED_BUFFER_SIZE);
CVarSetInteger("gRandoGenerating", 0);
CVarSave();
CVarLoad();
@ -3049,27 +3048,28 @@ void DrawRandoEditor(bool& open) {
DrawPresetSelector(PRESET_TYPE_RANDOMIZER);
UIWidgets::Spacer(0);
ImGui::Text("Seed");
if (ImGui::InputText("##RandomizerSeed", seedInputBuffer, MAX_SEED_BUFFER_SIZE, ImGuiInputTextFlags_CharsDecimal | ImGuiInputTextFlags_CallbackCharFilter, UIWidgets::TextFilters::FilterNumbers)) {
uint32_t seedInput;
ImGui::DataTypeApplyFromText(seedInputBuffer, ImGuiDataType_U32, &seedInput, "%u");
strncpy(seedInputBuffer, std::to_string(seedInput).c_str(), MAX_SEED_BUFFER_SIZE);
}
UIWidgets::Tooltip("Leaving this field blank will use a random seed value automatically\nSeed range is 0 - 4,294,967,295");
ImGui::SameLine();
if (ImGui::Button("New Seed")) {
strncpy(seedInputBuffer, std::to_string(rand() & 0xFFFFFFFF).c_str(), MAX_SEED_BUFFER_SIZE);
}
UIWidgets::Tooltip("Creates a new random seed value to be used when generating a randomizer");
ImGui::SameLine();
if (ImGui::Button("Clear Seed")) {
memset(seedInputBuffer, 0, MAX_SEED_BUFFER_SIZE);
UIWidgets::EnhancementCheckbox("Manual seed entry", "gRandoManualSeedEntry", false, "");
if (CVarGetInteger("gRandoManualSeedEntry", 0)) {
ImGui::Text("Seed");
ImGui::InputText("##RandomizerSeed", seedString, MAX_SEED_STRING_SIZE, ImGuiInputTextFlags_CallbackCharFilter, UIWidgets::TextFilters::FilterAlphaNum);
UIWidgets::Tooltip(
"Characters from a-z, A-Z, and 0-9 are supported.\n"
"Character limit is 1023, after which the seed will be truncated.\n"
);
ImGui::SameLine();
if (ImGui::Button("New Seed")) {
strncpy(seedString, std::to_string(rand() & 0xFFFFFFFF).c_str(), MAX_SEED_STRING_SIZE);
}
UIWidgets::Tooltip("Creates a new random seed value to be used when generating a randomizer");
ImGui::SameLine();
if (ImGui::Button("Clear Seed")) {
memset(seedString, 0, MAX_SEED_STRING_SIZE);
}
}
UIWidgets::Spacer(0);
if (ImGui::Button("Generate Randomizer")) {
GenerateRandomizer(seedInputBuffer);
if (ImGui::Button("Generate Randomizer")) {
GenerateRandomizer(CVarGetInteger("gRandoManualSeedEntry", 0) ? seedString : std::to_string(rand() & 0xFFFFFFFF).c_str());
}
UIWidgets::Spacer(0);
@ -5305,7 +5305,7 @@ void InitRandoItemTable() {
void InitRando() {
SohImGui::AddWindow("Randomizer", "Randomizer Settings", DrawRandoEditor);
Randomizer::CreateCustomMessages();
seedInputBuffer = (char*)calloc(MAX_SEED_BUFFER_SIZE, sizeof(char));
seedString = (char*)calloc(MAX_SEED_STRING_SIZE, sizeof(char));
InitRandoItemTable();
}

View File

@ -12,7 +12,7 @@
#include <soh/Enhancements/custom-message/CustomMessageManager.h>
#include "soh/Enhancements/item-tables/ItemTableTypes.h"
#define MAX_SEED_BUFFER_SIZE 11 // digits for uint32
#define MAX_SEED_STRING_SIZE 1024
#define NUM_NAVI_MESSAGES 19
#define NUM_ICE_TRAP_MESSAGES 23
#define NUM_GORON_MESSAGES 9

View File

@ -22,6 +22,15 @@ namespace UIWidgets {
}
return 1;
}
static int FilterAlphaNum(ImGuiInputTextCallbackData* data) {
const char* alphanum = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWYZ0123456789";
if (data->EventChar < 256 && strchr(alphanum, (char)data->EventChar)) {
return 0;
}
return 1;
}
};
// MARK: - Enums