Merge branch '164-crash-on-patching-and-possibly-right-after-login' into main/gingo...
[ryzomcore.git] / ryzom / client / src / permanent_ban.cpp
blob56903f0cce018fdf396e667aa4358f0a82b3b7ef
1 // Ryzom - MMORPG Framework <http://dev.ryzom.com/projects/ryzom/>
2 // Copyright (C) 2010 Winch Gate Property Limited
3 //
4 // This source file has been modified by the following contributors:
5 // Copyright (C) 2019 Jan BOON (Kaetemi) <jan.boon@kaetemi.be>
6 //
7 // This program is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU Affero General Public License as
9 // published by the Free Software Foundation, either version 3 of the
10 // License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU Affero General Public License for more details.
17 // You should have received a copy of the GNU Affero General Public License
18 // along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "stdpch.h"
21 #include "permanent_ban.h"
22 #include "nel/misc/file.h"
23 #include "nel/misc/path.h"
24 #include "nel/misc/big_file.h"
25 #include "nel/misc/random.h"
28 using namespace NLMISC;
31 #define REGKEY_RYZOM_PATH L"Software\\Nevrax\\ryzom"
32 #define REGKEY_PERMANENT_BAN L"PB"
35 // ************************************************************
36 static void setPermanentBanRegistryKey(bool on)
38 #ifndef NL_OS_WINDOWS
39 nlinfo("Not implemented");
40 #else
41 HKEY hKey;
42 if (RegCreateKeyW(HKEY_CURRENT_USER, REGKEY_RYZOM_PATH, &hKey)==ERROR_SUCCESS)
44 DWORD permanentBan = on ? 1 : 0;
45 LONG result = RegSetValueExW(hKey, REGKEY_PERMANENT_BAN, 0, REG_DWORD, (LPBYTE)&permanentBan, 4);
47 if (result != ERROR_SUCCESS)
49 nlwarning("pb key not created");
52 else
54 nlwarning("pb key not created");
56 #endif
59 // ************************************************************
60 static bool getPermanentBanRegistryKey()
62 #ifndef NL_OS_WINDOWS
63 return false; // not implemented
64 #else
65 HKEY hKey;
66 if (RegOpenKeyExW(HKEY_CURRENT_USER, REGKEY_RYZOM_PATH, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
68 DWORD permanentBan;
69 DWORD type;
70 DWORD dataSize = sizeof(DWORD);
72 RegQueryValueExW(hKey, REGKEY_PERMANENT_BAN, 0, &type, (LPBYTE)&permanentBan, &dataSize);
74 if (type == REG_DWORD && dataSize == sizeof(DWORD))
76 return permanentBan != 0;
80 return false;
81 #endif
84 // ***********************************************************
85 static void setPermanentBanFileMarker(const std::string &path, bool on)
87 if (on)
89 try
91 // simply touch a file
92 COFile f(path);
93 #ifdef NL_OS_WINDOWS
94 SetFileAttributesW(nlUtf8ToWide(path), FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM);
95 #endif
97 catch(const EStream &e)
99 nlinfo(e.what());
102 else
104 CFile::deleteFile(path);
108 // ***********************************************************
109 static bool getPermanentBanFileMarker(const std::string &path)
111 return CFile::isExists(path);
114 #define PERMANENT_BAN_FILE0 "c:\\3289763c1ecd044e"
115 #define PERMANENT_BAN_FILE1 "78d0732e50bf2bbd"
117 // ************************************************************
118 void setPermanentBanMarkers(bool on)
120 setPermanentBanRegistryKey(on);
121 setPermanentBanFileMarker(PERMANENT_BAN_FILE0, on);
122 setPermanentBanFileMarker(CPath::getWindowsDirectory() + PERMANENT_BAN_FILE1, on);
126 // ************************************************************
127 bool testPermanentBanMarkers()
129 /*#ifndef NL_OS_WINDOWS
130 nlinfo("Not implemented");
131 return false;
132 #else
133 if (getPermanentBanRegistryKey()) return true;
134 if (getPermanentBanFileMarker(PERMANENT_BAN_FILE0)) return true;
135 if (getPermanentBanFileMarker(CPath::getWindowsDirectory() + PERMANENT_BAN_FILE1)) return true;
136 #endif
137 return false;
139 return false;
143 // mark a bnp file without corrupting its datas (this force the patch to be applied the next time the client is launched, thus delaying the trouble maker)
144 static void markBNPFile(std::string &path)
146 CRandom rnd;
147 rnd.srand((sint32) CTime::getLocalTime());
149 uint32 nFileSize=CFile::getFileSize(path);
150 if (!nFileSize) return;
151 FILE *f = nlfopen(path, "rb+");
152 if (!f) return;
153 // Result
154 if (nlfseek64 (f, nFileSize-4, SEEK_SET) != 0)
156 fclose (f);
157 return;
160 uint32 nOffsetFromBeginning;
161 if (fread (&nOffsetFromBeginning, sizeof(uint32), 1, f) != 1)
163 fclose (f);
164 return;
167 #ifdef NL_BIG_ENDIAN
168 NLMISC_BSWAP32(nOffsetFromBeginning);
169 #endif
171 if (nlfseek64 (f, nOffsetFromBeginning, SEEK_SET) != 0)
173 fclose (f);
174 return;
177 // Read the file count
178 uint32 nNbFile;
179 if (fread (&nNbFile, sizeof(uint32), 1, f) != 1)
181 fclose (f);
182 return;
185 #ifdef NL_BIG_ENDIAN
186 NLMISC_BSWAP32(nNbFile);
187 #endif
189 for (uint32 i = 0; i < nNbFile; ++i)
191 char FileName[MAX_PATH];
192 uint8 nStringSize;
193 if (fread (&nStringSize, 1, 1, f) != 1)
195 fclose(f);
196 return;
199 sint64 currPos = nlftell64(f);
200 if (currPos < 0)
202 fclose(f);
203 return;
205 if (fread (FileName, 1, nStringSize, f) != nStringSize)
207 fclose (f);
208 return;
211 FileName[nStringSize] = 0;
213 for(uint k = 0; k < nStringSize; ++k)
215 if (rnd.rand() & 1) FileName[k] = toupper(FileName[k]);
216 else FileName[k] = tolower(FileName[k]);
220 if (nlfseek64 (f, currPos, SEEK_SET) != 0)
222 fclose (f);
223 return;
227 // write shuffled version
228 if (fwrite(FileName, 1, nStringSize, f) != nStringSize)
230 fclose(f);
231 return;
233 fflush(f);
235 uint32 nFileSize2;
236 if (fread (&nFileSize2, sizeof(uint32), 1, f) != 1)
238 fclose (f);
239 return;
242 #ifdef NL_BIG_ENDIAN
243 NLMISC_BSWAP32(nFileSize2);
244 #endif
246 uint32 nFilePos;
247 if (fread (&nFilePos, sizeof(uint32), 1, f) != 1)
249 fclose (f);
250 return;
253 #ifdef NL_BIG_ENDIAN
254 NLMISC_BSWAP32(nFilePos);
255 #endif
258 fclose (f);
261 // ************************************************************
262 void applyPermanentBanPunishment()
264 // go in the data directory & touch all bnp files so that the client should repatch all its datas
265 std::vector<std::string> bigFilePaths;
266 CBigFile::getInstance().getBigFilePaths(bigFilePaths);
267 for(uint k = 0; k < bigFilePaths.size(); ++k)
269 markBNPFile(bigFilePaths[k]);