1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
#pragma once
#include <string>
#include <utility>
#include <vector>
#include <nlohmann/json.hpp>
/*
The following JSON will be part of an array of similar objects in the root level "JSON DB" for FOMOD Plus.
It contains information to resolve the identity of a given mod (names can change), and then the options
in the FOMOD with their respective masters.
{
modId: 12345,
displayName: "Lux (Patch Hub)",
options: [
{
"name" "JK's The Hag's Cure",
"fileName": "Lux - JK's The Hag's Cure patch.esp",
"masters": [
"Skyrim.esm",
"JK's The Hag's Cure.esp",
"Lux - Resources.esp",
"Lux.esp"
],
"step": "Page One",
"group": "Group One",
"selectionState": "Available"
}
]
}
*/
enum class SelectionState {
Unknown, // Not yet matched to choices
Selected, // User selected this option
Deselected, // User manually deselected
Available // Present but user didn't interact (or choices not recorded)
};
inline std::string selectionStateToString(SelectionState state) {
switch (state) {
case SelectionState::Unknown: return "Unknown";
case SelectionState::Selected: return "Selected";
case SelectionState::Deselected: return "Deselected";
case SelectionState::Available: return "Available";
default: return "Unknown";
}
}
inline SelectionState stringToSelectionState(const std::string& str) {
if (str == "Selected") return SelectionState::Selected;
if (str == "Deselected") return SelectionState::Deselected;
if (str == "Available") return SelectionState::Available;
return SelectionState::Unknown;
}
struct FomodOption {
std::string name;
std::string fileName;
std::vector<std::string> masters;
std::string step;
std::string group;
SelectionState selectionState = SelectionState::Unknown;
FomodOption(std::string n, std::string fn, std::vector<std::string> m, std::string s, std::string g,
SelectionState state = SelectionState::Unknown)
: name(std::move(n)), fileName(std::move(fn)), masters(std::move(m)), step(std::move(s)), group(std::move(g)),
selectionState(state) {}
};
class FomodDbEntry {
public:
explicit FomodDbEntry(nlohmann::json json) {
modId = json["modId"];
displayName = json["displayName"];
for (auto &option: json["options"]) {
// create an option from this object
SelectionState state = SelectionState::Unknown;
if (option.contains("selectionState")) {
state = stringToSelectionState(option["selectionState"]);
}
FomodOption fomodOption(
option["name"],
option["fileName"],
option["masters"],
option["step"],
option["group"],
state
);
options.push_back(fomodOption);
}
}
explicit FomodDbEntry(const int modId, std::string displayName, const std::vector<FomodOption> &options)
: modId(modId), displayName(std::move(displayName)), options(options) {
}
[[nodiscard]] int getModId() const { return modId; }
[[nodiscard]] std::string getDisplayName() const { return displayName; }
[[nodiscard]] const std::vector<FomodOption>& getOptions() const { return options; }
[[nodiscard]] std::vector<FomodOption>& getOptionsMutable() { return options; }
[[nodiscard]] nlohmann::json toJson() const {
nlohmann::json result;
result["modId"] = modId;
result["displayName"] = displayName;
nlohmann::json optionsArray = nlohmann::json::array();
for (const auto &[name, fileName, masters, step, group, selectionState]: options) {
nlohmann::json optionJson;
optionJson["name"] = name;
optionJson["fileName"] = fileName;
optionJson["masters"] = masters;
optionJson["step"] = step;
optionJson["group"] = group;
optionJson["selectionState"] = selectionStateToString(selectionState);
optionsArray.push_back(optionJson);
}
result["options"] = optionsArray;
return result;
}
private:
int modId;
std::string displayName;
std::vector<FomodOption> options;
};
|