Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 33 additions & 8 deletions src/Feature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,12 @@ void Feature::Load(json& o_json)
auto iter = FeatureVersions::FEATURE_MINIMAL_VERSIONS.find(shortName);
if (iter != FeatureVersions::FEATURE_MINIMAL_VERSIONS.end()) {
std::string minimalVersionString = iter->second.string();
minimumVersion = minimalVersionString.substr(0, minimalVersionString.size() - 2);
// Only remove trailing ".0" if it exists, don't truncate non-zero patch versions
if (minimalVersionString.ends_with(".0")) {
minimumVersion = minimalVersionString.substr(0, minimalVersionString.size() - 2);
} else {
minimumVersion = minimalVersionString;
}
}
}

Expand Down Expand Up @@ -210,14 +215,34 @@ const std::vector<Feature*>& Feature::GetFeatureList()
globals::features::ibl
};

static std::vector<Feature*> featuresVR = [] {
auto v = features;
v.push_back(globals::features::vr);
std::erase_if(v, [](Feature* a) { return !a->SupportsVR(); });
return v;
}();
if (REL::Module::IsVR()) {
// Helper function to build VR feature list
static auto BuildVRList = []() -> std::vector<Feature*> {
auto v = features;
v.push_back(globals::features::vr);

// In developer mode, keep all features for testing
// In production mode, filter to VR-compatible only
if (!globals::state->IsDeveloperMode()) {
std::erase_if(v, [](Feature* a) { return !a->SupportsVR(); });
}
return v;
};

// Cache the VR feature list but invalidate when developer mode changes
static std::vector<Feature*> featuresVR;
static bool cachedDevMode = false;

return (REL::Module::IsVR() && !globals::state->IsDeveloperMode()) ? featuresVR : features;
bool currentDevMode = globals::state->IsDeveloperMode();
if (featuresVR.empty() || currentDevMode != cachedDevMode) {
featuresVR = BuildVRList();
cachedDevMode = currentDevMode;
}

return featuresVR;
} else {
return features;
}
}

bool Feature::ToggleAtBootSetting()
Expand Down
41 changes: 1 addition & 40 deletions src/FeatureIssues.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -816,8 +816,7 @@ namespace FeatureIssues

bool TestIniInfo::wasManuallyDeleted() const
{
// If marker exists but test INI doesn't, it was manually deleted
return std::filesystem::exists(testMarkerPath) && !std::filesystem::exists(testIniPath);
return !std::filesystem::exists(testIniPath);
}

bool LoadPersistentTestState()
Expand All @@ -841,7 +840,6 @@ namespace FeatureIssues
for (const auto& testData : stateData["testInis"]) {
TestIniInfo testInfo;
testInfo.testIniPath = testData["testIniPath"].get<std::string>();
testInfo.testMarkerPath = testData["testMarkerPath"].get<std::string>();
testInfo.isNewFile = testData["isNewFile"].get<bool>();
testInfo.testType = testData["testType"].get<std::string>();
testInfo.featureName = testData["featureName"].get<std::string>();
Expand Down Expand Up @@ -869,7 +867,6 @@ namespace FeatureIssues
for (const auto& testInfo : s_activeTestInis) {
nlohmann::json testData;
testData["testIniPath"] = testInfo.testIniPath;
testData["testMarkerPath"] = testInfo.testMarkerPath;
testData["isNewFile"] = testInfo.isNewFile;
testData["testType"] = testInfo.testType;
testData["featureName"] = testInfo.featureName;
Expand Down Expand Up @@ -1085,16 +1082,8 @@ namespace FeatureIssues
if (outFile.fail()) {
throw std::runtime_error("Failed to write file contents");
}

// Create marker file to track this test INI
const std::filesystem::path testMarkerPath = featuresPath / (testCase.selectedFeature + ".test");
std::ofstream markerFile(testMarkerPath);
markerFile << "# Test marker created by CS Developer Mode\n";
markerFile.close();

TestIniInfo testInfo;
testInfo.testIniPath = iniPath.string();
testInfo.testMarkerPath = testMarkerPath.string();
testInfo.isNewFile = true;
testInfo.testType = "obsolete";
testInfo.featureName = testCase.selectedFeature;
Expand Down Expand Up @@ -1131,16 +1120,8 @@ namespace FeatureIssues
if (outFile.fail()) {
throw std::runtime_error("Failed to write file contents");
}

// Create marker file
const std::filesystem::path testMarkerPath = featuresPath / (unknownFeature + ".test");
std::ofstream markerFile(testMarkerPath);
markerFile << "# Test marker created by CS Developer Mode\n";
markerFile.close();

TestIniInfo testInfo;
testInfo.testIniPath = unknownIniPath.string();
testInfo.testMarkerPath = testMarkerPath.string();
testInfo.isNewFile = true;
testInfo.testType = "unknown";
testInfo.featureName = unknownFeature;
Expand Down Expand Up @@ -1168,12 +1149,6 @@ namespace FeatureIssues
// Analyze ALL features (loaded and unloaded) to find safe version mismatch candidates
for (const auto& [featureName, feature] : loadedFeatureMap) {
const std::filesystem::path iniPath = featuresPath / (featureName + ".ini");
const std::filesystem::path testStatePath = featuresPath / (featureName + ".test");

// Skip if we already have a test state for this feature
if (std::filesystem::exists(testStatePath)) {
continue;
}

std::string modLink = GetFeatureModLink(featureName);
bool hasModLink = !modLink.empty();
Expand Down Expand Up @@ -1290,7 +1265,6 @@ namespace FeatureIssues

TestIniInfo testInfo;
testInfo.testIniPath = iniPath.string();
testInfo.testMarkerPath = ""; // No marker needed for modified files
testInfo.isNewFile = false;
testInfo.testType = "version mismatch";
testInfo.featureName = testFeatureName;
Expand Down Expand Up @@ -1320,16 +1294,8 @@ namespace FeatureIssues
if (outFile.fail()) {
throw std::runtime_error("Failed to write file contents");
}

// Create marker file to track this test INI
const std::filesystem::path testMarkerPath = featuresPath / (testFeatureName + ".test");
std::ofstream markerFile(testMarkerPath);
markerFile << "# Test marker created by CS Developer Mode\n";
markerFile.close();

TestIniInfo testInfo;
testInfo.testIniPath = iniPath.string();
testInfo.testMarkerPath = testMarkerPath.string();
testInfo.isNewFile = true;
testInfo.testType = "version mismatch";
testInfo.featureName = testFeatureName;
Expand Down Expand Up @@ -1397,11 +1363,6 @@ namespace FeatureIssues
std::filesystem::remove(testInfo.testIniPath);
logger::debug("Removed test INI: {}", testInfo.testIniPath);
}
// Remove marker file
if (std::filesystem::exists(testInfo.testMarkerPath)) {
std::filesystem::remove(testInfo.testMarkerPath);
logger::debug("Removed test marker: {}", testInfo.testMarkerPath);
}
} else {
// Restore original version using INI functions
CSimpleIniA ini;
Expand Down
1 change: 0 additions & 1 deletion src/FeatureIssues.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,6 @@ namespace FeatureIssues
struct TestIniInfo
{
std::string testIniPath; // Path to the test INI file created
std::string testMarkerPath; // Path to .test marker file for tracking (new files only)
bool isNewFile{ true }; // Whether this is a completely new file or modified existing
std::string testType; // Description of test type (obsolete, unknown, version mismatch)
std::string featureName; // Name of the feature being tested
Expand Down