Line data Source code
1 : /* Copyright (C) 2022 Wildfire Games.
2 : * This file is part of 0 A.D.
3 : *
4 : * 0 A.D. is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 2 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * 0 A.D. is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16 : */
17 :
18 : #include "precompiled.h"
19 :
20 : #include "JSInterface_ConfigDB.h"
21 :
22 : #include "ps/ConfigDB.h"
23 : #include "ps/CLogger.h"
24 : #include "ps/VideoMode.h"
25 : #include "scriptinterface/FunctionWrapper.h"
26 : #include "scriptinterface/ScriptRequest.h"
27 :
28 : #include <string>
29 : #include <unordered_set>
30 :
31 : namespace JSI_ConfigDB
32 : {
33 : // These entries will not be readable nor writable for JS, so that e.g. malicious mods can't leak personal or sensitive data
34 6 : static const std::unordered_set<std::string> g_ProtectedConfigNames = {
35 : "modio.public_key", // See ModIO.cpp
36 : "modio.v1.baseurl",
37 : "modio.v1.api_key",
38 : "modio.v1.name_id",
39 : "userreport.id" // Acts as authentication token for GDPR personal data requests.
40 5 : };
41 :
42 0 : bool IsProtectedConfigName(const std::string& name)
43 : {
44 0 : if (g_ProtectedConfigNames.find(name) != g_ProtectedConfigNames.end())
45 : {
46 0 : LOGERROR("Access denied (%s)", name.c_str());
47 0 : return true;
48 : }
49 0 : return false;
50 : }
51 :
52 0 : bool GetConfigNamespace(const std::wstring& cfgNsString, EConfigNamespace& cfgNs)
53 : {
54 0 : if (cfgNsString == L"default")
55 0 : cfgNs = CFG_DEFAULT;
56 0 : else if (cfgNsString == L"mod")
57 0 : cfgNs = CFG_MOD;
58 0 : else if (cfgNsString == L"system")
59 0 : cfgNs = CFG_SYSTEM;
60 0 : else if (cfgNsString == L"user")
61 0 : cfgNs = CFG_USER;
62 0 : else if (cfgNsString == L"hwdetect")
63 0 : cfgNs = CFG_HWDETECT;
64 : else
65 : {
66 0 : LOGERROR("Invalid namespace name passed to the ConfigDB!");
67 0 : cfgNs = CFG_DEFAULT;
68 0 : return false;
69 : }
70 0 : return true;
71 : }
72 :
73 0 : bool HasChanges(const std::wstring& cfgNsString)
74 : {
75 : EConfigNamespace cfgNs;
76 0 : if (!GetConfigNamespace(cfgNsString, cfgNs))
77 0 : return false;
78 :
79 0 : return g_ConfigDB.HasChanges(cfgNs);
80 : }
81 :
82 0 : bool SetChanges(const std::wstring& cfgNsString, bool value)
83 : {
84 : EConfigNamespace cfgNs;
85 0 : if (!GetConfigNamespace(cfgNsString, cfgNs))
86 0 : return false;
87 :
88 0 : g_ConfigDB.SetChanges(cfgNs, value);
89 0 : return true;
90 : }
91 :
92 0 : std::string GetValue(const std::wstring& cfgNsString, const std::string& name)
93 : {
94 0 : if (IsProtectedConfigName(name))
95 0 : return "";
96 :
97 : EConfigNamespace cfgNs;
98 0 : if (!GetConfigNamespace(cfgNsString, cfgNs))
99 0 : return std::string();
100 :
101 0 : std::string value;
102 0 : g_ConfigDB.GetValue(cfgNs, name, value);
103 0 : return value;
104 : }
105 :
106 0 : bool CreateValue(const std::wstring& cfgNsString, const std::string& name, const std::string& value)
107 : {
108 0 : if (IsProtectedConfigName(name))
109 0 : return false;
110 :
111 : EConfigNamespace cfgNs;
112 0 : if (!GetConfigNamespace(cfgNsString, cfgNs))
113 0 : return false;
114 :
115 0 : g_ConfigDB.SetValueString(cfgNs, name, value);
116 0 : g_ConfigDB.SetChanges(cfgNs, true);
117 0 : return true;
118 : }
119 :
120 0 : bool CreateValues(const std::wstring& cfgNsString, const std::string& name, const std::vector<CStr>& values)
121 : {
122 0 : if (IsProtectedConfigName(name))
123 0 : return false;
124 :
125 : EConfigNamespace cfgNs;
126 0 : if (!GetConfigNamespace(cfgNsString, cfgNs))
127 0 : return false;
128 :
129 0 : g_ConfigDB.SetValueList(cfgNs, name, values);
130 0 : g_ConfigDB.SetChanges(cfgNs, true);
131 0 : return true;
132 : }
133 :
134 :
135 0 : bool RemoveValue(const std::wstring& cfgNsString, const std::string& name)
136 : {
137 0 : if (IsProtectedConfigName(name))
138 0 : return false;
139 :
140 : EConfigNamespace cfgNs;
141 0 : if (!GetConfigNamespace(cfgNsString, cfgNs))
142 0 : return false;
143 :
144 0 : bool result = g_ConfigDB.RemoveValue(cfgNs, name);
145 0 : if (result)
146 0 : g_ConfigDB.SetChanges(cfgNs, true);
147 :
148 0 : return result;
149 : }
150 :
151 0 : bool SaveChanges(const std::wstring& cfgNsString)
152 : {
153 : EConfigNamespace cfgNs;
154 0 : if (!GetConfigNamespace(cfgNsString, cfgNs))
155 0 : return false;
156 :
157 0 : bool result = g_ConfigDB.WriteFile(cfgNs);
158 0 : if (result)
159 0 : g_ConfigDB.SetChanges(cfgNs, false);
160 :
161 0 : return result;
162 : }
163 :
164 0 : bool RemoveValueAndSave(const std::wstring& cfgNsString, const std::string& name)
165 : {
166 0 : if (RemoveValue(cfgNsString, name))
167 0 : return SaveChanges(cfgNsString);
168 :
169 0 : return false;
170 : }
171 :
172 :
173 0 : bool SaveValue(const std::wstring& cfgNsString, const std::string& name, const std::string& value)
174 : {
175 0 : if (IsProtectedConfigName(name))
176 0 : return false;
177 :
178 : EConfigNamespace cfgNs;
179 0 : if (!GetConfigNamespace(cfgNsString, cfgNs))
180 0 : return false;
181 :
182 0 : return g_ConfigDB.WriteValueToFile(cfgNs, name, value);
183 : }
184 :
185 0 : void CreateAndSaveValue(const std::wstring& cfgNsString, const std::string& name, const std::string& value)
186 : {
187 0 : if (CreateValue(cfgNsString, name, value))
188 0 : SaveValue(cfgNsString, name, value);
189 0 : }
190 :
191 0 : bool Reload(const std::wstring& cfgNsString)
192 : {
193 : EConfigNamespace cfgNs;
194 0 : if (!GetConfigNamespace(cfgNsString, cfgNs))
195 0 : return false;
196 :
197 0 : return g_ConfigDB.Reload(cfgNs);
198 : }
199 :
200 0 : void PauseOnFocusLoss(bool pause)
201 : {
202 0 : g_PauseOnFocusLoss = pause;
203 0 : }
204 :
205 0 : void SetGUIScale(float scale)
206 : {
207 0 : g_VideoMode.Rescale(scale);
208 0 : }
209 :
210 12 : void RegisterScriptFunctions(const ScriptRequest& rq)
211 : {
212 12 : ScriptFunction::Register<&HasChanges>(rq, "ConfigDB_HasChanges");
213 12 : ScriptFunction::Register<&SetChanges>(rq, "ConfigDB_SetChanges");
214 12 : ScriptFunction::Register<&GetValue>(rq, "ConfigDB_GetValue");
215 12 : ScriptFunction::Register<&CreateValue>(rq, "ConfigDB_CreateValue");
216 12 : ScriptFunction::Register<&CreateValues>(rq, "ConfigDB_CreateValues");
217 12 : ScriptFunction::Register<&RemoveValue>(rq, "ConfigDB_RemoveValue");
218 12 : ScriptFunction::Register<&RemoveValueAndSave>(rq, "ConfigDB_RemoveValueAndSave");
219 12 : ScriptFunction::Register<&SaveChanges>(rq, "ConfigDB_SaveChanges");
220 12 : ScriptFunction::Register<&SaveValue>(rq, "ConfigDB_SaveValue");
221 12 : ScriptFunction::Register<&CreateAndSaveValue>(rq, "ConfigDB_CreateAndSaveValue");
222 12 : ScriptFunction::Register<&Reload>(rq, "ConfigDB_Reload");
223 12 : ScriptFunction::Register<&PauseOnFocusLoss>(rq, "PauseOnFocusLoss");
224 12 : ScriptFunction::Register<&SetGUIScale>(rq, "SetGUIScale");
225 12 : }
226 3 : }
|