Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
axstin
GitHub Repository: axstin/rbxfpsunlocker
Path: blob/master/Source/settings.cpp
259 views
1
#include "settings.h"
2
#include "rfu.h"
3
4
#include <string>
5
#include <iostream>
6
#include <fstream>
7
#include <functional>
8
#include <cerrno>
9
10
// todo: jesus this is ugly rewrite all this if i ever care enough
11
// todo: do the above todo. we have advanced technology now (json)
12
13
const char *advance(const char *ptr)
14
{
15
while (isspace(*ptr)) ptr++;
16
return ptr;
17
}
18
19
// scuffed array parse. e.g. [1, 2, 3, 4, 5]
20
std::vector<double> ParseDoubleArray(const std::string &value, size_t max_elements = 0)
21
{
22
std::vector<double> result;
23
24
auto ptr = advance(value.c_str());
25
if (*ptr != '[') throw std::invalid_argument("unexpected character");
26
27
while (++ptr < value.c_str() + value.size())
28
{
29
ptr = advance(ptr);
30
if (*ptr == ']') break;
31
32
errno = 0;
33
34
char *end_ptr;
35
double element = std::strtod(ptr, &end_ptr);
36
if (errno != 0) throw std::invalid_argument("conversion error");
37
if (std::isnan(element)) throw std::invalid_argument("element is nan");
38
if (std::isinf(element)) throw std::invalid_argument("element is infinite");
39
40
if (max_elements == 0 || result.size() < max_elements) result.push_back(element);
41
42
ptr = advance(end_ptr);
43
if (*ptr == ']') break;
44
if (*ptr != ',') throw std::invalid_argument("unexpected character");
45
}
46
47
return result;
48
}
49
50
bool ParseBool(const std::string &value)
51
{
52
if (_stricmp(value.c_str(), "true") == 0) return true;
53
if (_stricmp(value.c_str(), "false") == 0) return false;
54
return std::stoi(value) != 0;
55
}
56
57
std::string BoolToString(bool value)
58
{
59
return value ? "true" : "false";
60
}
61
62
std::string DoubleArrayToString(const std::vector<double> &array)
63
{
64
std::string buffer = "[";
65
for (size_t i = 0; i < array.size(); i++)
66
{
67
if (i > 0) buffer += ", ";
68
buffer += std::to_string(array[i]);
69
}
70
buffer += "]";
71
return buffer;
72
}
73
74
namespace Settings
75
{
76
std::vector<double> FPSCapValues = { 30, 60, 75, 120, 144, 165, 240, 360 };
77
uint32_t FPSCapSelection = 0;
78
double FPSCap = 0.0;
79
bool UnlockClient = true;
80
bool UnlockStudio = false;
81
bool CheckForUpdates = true;
82
bool AltEnterFix = false;
83
bool NonBlockingErrors = true;
84
bool SilentErrors = false;
85
bool QuickStart = false;
86
bool RevertFlagsOnClose = true;
87
UnlockMethodType UnlockMethod = UnlockMethodType::Hybrid;
88
89
bool Init()
90
{
91
if (!Load())
92
{
93
Save();
94
}
95
return true;
96
}
97
98
// very basic settings parser/writer
99
100
bool Load()
101
{
102
std::ifstream file("settings");
103
if (!file.is_open()) return false;
104
105
printf("Loading settings from file...\n");
106
107
std::string line;
108
109
while (std::getline(file, line))
110
{
111
size_t eq = line.find('=');
112
if (eq != std::string::npos)
113
{
114
std::string key = line.substr(0, eq);
115
std::string value = line.substr(eq + 1);
116
117
try
118
{
119
if (key == "FPSCapValues")
120
FPSCapValues = ParseDoubleArray(value, 100);
121
else if (key == "FPSCapSelection")
122
FPSCapSelection = std::stoul(value);
123
else if (key == "FPSCap")
124
FPSCap = std::stod(value);
125
else if (key == "UnlockClient")
126
UnlockClient = ParseBool(value);
127
else if (key == "UnlockStudio")
128
UnlockStudio = ParseBool(value);
129
else if (key == "CheckForUpdates")
130
CheckForUpdates = ParseBool(value);
131
else if (key == "AltEnterFix")
132
AltEnterFix = ParseBool(value);
133
else if (key == "NonBlockingErrors")
134
NonBlockingErrors = ParseBool(value);
135
else if (key == "SilentErrors")
136
SilentErrors = ParseBool(value);
137
else if (key == "QuickStart")
138
QuickStart = ParseBool(value);
139
else if (key == "RevertFlagsOnClose")
140
RevertFlagsOnClose = ParseBool(value);
141
else if (key == "UnlockMethodV2")
142
{
143
auto parsed = std::stoul(value);
144
if (parsed < static_cast<uint32_t>(UnlockMethodType::Count))
145
UnlockMethod = static_cast<UnlockMethodType>(parsed);
146
}
147
}
148
catch (std::exception& e)
149
{
150
// catch string conversion errors
151
}
152
}
153
}
154
155
if (FPSCapSelection > 0 && FPSCapSelection > FPSCapValues.size())
156
{
157
FPSCapSelection = 0;
158
}
159
160
for (double &value : FPSCapValues)
161
{
162
value = std::fmin(std::fmax(value, -2147483648.0), 2147483647.0);
163
}
164
165
FPSCap = FPSCapSelection == 0 ? 0.0 : FPSCapValues[FPSCapSelection - 1];
166
167
return true;
168
}
169
170
bool Save()
171
{
172
std::ofstream file("settings");
173
if (!file.is_open()) return false;
174
175
printf("Saving settings to file...\n");
176
177
file << "UnlockClient=" << BoolToString(UnlockClient) << std::endl;
178
file << "UnlockStudio=" << BoolToString(UnlockStudio) << std::endl;
179
file << "FPSCapValues=" << DoubleArrayToString(FPSCapValues) << std::endl;
180
file << "FPSCapSelection=" << std::to_string(FPSCapSelection) << std::endl;
181
file << "FPSCap=" << std::to_string(FPSCap) << std::endl;
182
file << "CheckForUpdates=" << BoolToString(CheckForUpdates) << std::endl;
183
file << "AltEnterFix=" << BoolToString(AltEnterFix) << std::endl;
184
file << "NonBlockingErrors=" << BoolToString(NonBlockingErrors) << std::endl;
185
file << "SilentErrors=" << BoolToString(SilentErrors) << std::endl;
186
file << "QuickStart=" << BoolToString(QuickStart) << std::endl;
187
file << "RevertFlagsOnClose=" << BoolToString(RevertFlagsOnClose) << std::endl;
188
file << "UnlockMethodV2=" << std::to_string(static_cast<uint32_t>(UnlockMethod)) << std::endl;
189
190
return true;
191
}
192
}
193