aboutsummaryrefslogtreecommitdiff
path: root/libs/installer_fomod_plus/share/FOMODData/FomodDBEntry.h
blob: 5d39f954b38a916f41b4acc26a7dc9c34adee63e (plain)
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;
};