TerraForge3D  2.3.1
3D Terrain And Landscape Generator
Utils.cpp
1#define _CRT_SECURE_NO_WARNINGS
2
3#define CPPHTTPLIB_OPENSSL_SUPPORT
4#include <httplib/httplib.h>
5#include <openssl/md5.h>
6#include <openssl/sha.h>
7#include <Utils.h>
8#include <fstream>
9#include <iostream>
10#include <sys/stat.h>
11#include <cstdio>
12#include <cstdlib>
13#ifdef _WIN32
14#include <io.h>
15#elif __linux__
16#include <inttypes.h>
17#include <unistd.h>
18#define __int64 int64_t
19#define _close close
20#define _read read
21#define _lseek64 lseek64
22#define _O_RDONLY O_RDONLY
23#define _open open
24#define _lseeki64 lseek64
25#define _lseek lseek
26#define stricmp strcasecmp
27#endif
28//SAF_Handle.cpp line:458 old line:INFILE = _open(infilename, _O_RDONLY | _O_BINARY);
29#ifdef __linux__
30// INFILE = _open(infilename, _O_RDONLY);
31#else
32// INFILE = _open(infilename, _O_RDONLY | _O_BINARY);
33#endif
34
35#include "GLFW/glfw3.h"
36#include "Application.h"
37#include "Data/ProjectData.h"
38
39#ifndef TERR3D_WIN32
40#include <libgen.h> // dirname
41#include <unistd.h> // readlink
42#include <linux/limits.h> // PATH_MAX
43#define MAX_PATH PATH_MAX
44#else
45#include <atlstr.h>
46#include <windows.h>
47#include <Commdlg.h>
48#endif
49
50
51static std::string getExecutablePath()
52{
53 char rawPathName[MAX_PATH];
54#ifdef TERR3D_WIN32
55 GetModuleFileNameA(NULL, rawPathName, MAX_PATH);
56#else
57 readlink("/proc/self/exe", rawPathName, PATH_MAX);
58#endif
59 return std::string(rawPathName);
60}
61
62static std::string getExecutableDir()
63{
64 std::string executablePath = getExecutablePath();
65 std::string directory = executablePath.substr(0, executablePath.find_last_of("\\/"));
66 return directory;
67}
68
69const char HEX_MAP[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
70
71char replace(unsigned char c)
72{
73 return HEX_MAP[c & 0x0f];
74}
75
76std::string UChar2Hex(unsigned char c)
77{
78 {
79 std::string hex;
80 // First four bytes
81 char left = (c >> 4);
82 // Second four bytes
83 char right = (c & 0x0f);
84 hex += replace(left);
85 hex += replace(right);
86 return hex;
87 }
88}
89
90#ifdef TERR3D_WIN32
91
92std::wstring s2ws(const std::string &s)
93{
94 int len;
95 int slength = (int)s.length() + 1;
96 len = MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, 0, 0);
97 wchar_t *buf = new wchar_t[len];
98 MultiByteToWideChar(CP_ACP, 0, s.c_str(), slength, buf, len);
99 std::wstring r(buf);
100 delete[] buf;
101 return r;
102}
103
104#endif
105
106std::string ShowSaveFileDialog(std::string ext)
107{
108#ifdef TERR3D_WIN32
109 OPENFILENAME ofn;
110 WCHAR fileName[MAX_PATH];
111 ZeroMemory(fileName, MAX_PATH);
112 ZeroMemory(&ofn, sizeof(ofn));
113 ofn.lStructSize = sizeof(OPENFILENAME);
114 ofn.hwndOwner = NULL;
115 //ofn.lpstrFilter = s2ws(ext).c_str();
116 ofn.lpstrFilter = L"*.*\0";
117 ofn.lpstrFile = fileName;
118 ofn.nMaxFile = MAX_PATH;
119 ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
120 ofn.lpstrDefExt = (LPWSTR)"";
121 std::string fileNameStr;
122
123 if (GetSaveFileName(&ofn))
124 {
125 std::wstring ws(ofn.lpstrFile);
126 // your new String
127 std::string str(ws.begin(), ws.end());
128 return str;
129 }
130
131 return std::string("");
132#else
133 char filename[PATH_MAX];
134 FILE *f = popen("zenity --file-selection --save", "r");
135 fgets(filename, PATH_MAX, f);
136 pclose(f);
137 filename[strcspn(filename, "\n")] = 0;
138 return std::string(filename);
139#endif
140}
141
142std::string openfilename()
143{
144 return ShowOpenFileDialog(".obj");
145}
146
147bool DeleteFileT(std::string path)
148{
149 try
150 {
151 if (std::filesystem::remove(path))
152 {
153 std::cout << "File " << path << " deleted.\n";
154 }
155
156 else
157 {
158 std::cout << "File " << path << " could not be deleted.\n";
159 return false;
160 }
161 }
162
163 catch(const std::filesystem::filesystem_error &err)
164 {
165 std::cout << "filesystem error: " << err.what() << '\n';
166 return false;
167 }
168
169 return true;
170}
171
172std::string ShowOpenFileDialog(std::string ext)
173{
174#ifdef TERR3D_WIN32
175 OPENFILENAME ofn;
176 WCHAR fileName[MAX_PATH];
177 ZeroMemory(fileName, MAX_PATH);
178 ZeroMemory(&ofn, sizeof(ofn));
179 ofn.lStructSize = sizeof(OPENFILENAME);
180 ofn.hwndOwner = NULL;
181 //ofn.lpstrFilter = s2ws(ext).c_str();
182 ofn.lpstrFilter = L"*.*\0";
183 ofn.lpstrFile = fileName;
184 ofn.nMaxFile = MAX_PATH;
185 ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
186 ofn.lpstrDefExt = (LPWSTR)"";
187 std::string fileNameStr;
188
189 if (GetOpenFileName(&ofn))
190 {
191 std::wstring ws(ofn.lpstrFile);
192 // your new String
193 std::string str(ws.begin(), ws.end());
194 return str;
195 }
196
197 return std::string("");
198#else
199 char filename[PATH_MAX];
200 FILE *f = popen("zenity --file-selection", "r");
201 fgets(filename, PATH_MAX, f);
202 pclose(f);
203 filename[strcspn(filename, "\n")] = 0;
204 return std::string(filename);
205#endif
206}
207
208std::string ReadShaderSourceFile(std::string path, bool *result)
209{
210 std::fstream newfile;
211 newfile.open(path.c_str(), std::ios::in);
212
213 if (newfile.is_open())
214 {
215 std::string tp;
216 std::string res = "";
217 getline(newfile, res, '\0');
218 newfile.close();
219 *result = true;
220 return res;
221 }
222
223 else
224 {
225 *result = false;
226 }
227
228 return std::string("");
229}
230
231std::string GetExecutablePath()
232{
233 return getExecutablePath();
234}
235
236std::string GetExecutableDir()
237{
238 return getExecutableDir();
239}
240
241std::string GenerateId(uint32_t length)
242{
243 std::string id;
244 srand(time(NULL));
245
246 for (int i = 0; i < length; i++)
247 {
248 id += std::to_string(rand() % 9);
249 }
250
251 return id;
252}
253
254std::string FetchURL(std::string baseURL, std::string path)
255{
256 httplib::Client cli(baseURL);
257 auto res = cli.Get(path.c_str());
258 cli.set_read_timeout(10);
259
260 if (res.error() == httplib::Error::Success)
261 {
262 try
263 {
264 return res->body;
265 }
266
267 catch (...) {}
268 }
269 else
270 {
271 Log("Error in fetching " + baseURL+ path + " ERROR : " + httplib::to_string(res.error()));
272 }
273
274 return "";
275}
276
277char *UChar2Char(unsigned char *data, int length)
278{
279 char *odata = new char[length];
280
281 for (int i = 0; i < length; i++)
282 {
283 odata[i] = (char)data[i];
284 }
285
286 return odata;
287}
288
289bool FileExists(std::string path, bool writeAccess)
290{
291#ifdef TERR3D_WIN32
292
293 if ((_access(path.c_str(), 0)) != -1)
294 {
295 if (!writeAccess)
296 {
297 return true;
298 }
299
300 if ((_access(path.c_str(), 2)) != -1)
301 {
302 return true;
303 }
304 }
305
306 return false;
307#else
308 struct stat buffer;
309 return (stat (path.c_str(), &buffer) == 0);
310#endif
311}
312
313bool PathExist(const std::string &s)
314{
315 struct stat buffer;
316 return (stat(s.c_str(), &buffer) == 0);
317}
318
319
320#ifdef TERR3D_WIN32
321#include <wininet.h>
322#pragma comment(lib, "Wininet.lib")
323#endif
324
325bool IsNetWorkConnected()
326{
327#ifdef TERR3D_WIN32
328 bool bConnect = InternetCheckConnectionW(L"http://www.google.com", FLAG_ICC_FORCE_CONNECTION, 0);
329 return bConnect;
330#else
331 // Return true if internet connection is alive else false
332 return true;
333#endif
334}
335
336char *ReadBinaryFile(std::string path, int *fSize, uint32_t sizeToLoad)
337{
338 std::ifstream in(path, std::ifstream::ate | std::ifstream::binary);
339 int size = in.tellg();
340 in.close();
341
342 if(sizeToLoad > 0)
343 {
344 size = size < sizeToLoad ? size : sizeToLoad;
345 }
346
347 std::ifstream f1(path, std::fstream::binary);
348
349 if (size < 1)
350 {
351 size = 1024;
352 }
353
354 char *buffer = new char[size];
355 f1.read(buffer, size);
356 f1.close();
357 *fSize = size;
358 return buffer;
359}
360
361char *ReadBinaryFile(std::string path, uint32_t sizeToLoad)
362{
363 int size;
364 return ReadBinaryFile(path, &size, sizeToLoad);
365}
366
367Hash MD5File(std::string path)
368{
369 int size = 1;
370 unsigned char *data = (unsigned char *)ReadBinaryFile(path, &size);
371 unsigned char hash[MD5_DIGEST_LENGTH];
372 MD5(data, size, hash);
373 Hash resultHash(hash, MD5_DIGEST_LENGTH);
374 delete[] data;
375 return resultHash;
376}
377
378void DownloadFile(std::string baseURL, std::string urlPath, std::string path, int size)
379{
380 try
381 {
382 std::ofstream outfile;
383 httplib::Client cli(baseURL);
384 int done = 0;
385 outfile.open(path.c_str(), std::ios::binary | std::ios::out);
386 std::cout << "Starting download - " << baseURL << urlPath << std::endl;
387 auto res = cli.Get(urlPath.c_str(),
388 [&](const char *data, size_t data_length)
389 {
390 done = done + data_length;
391
392 if (size > 0)
393 {
394 float percent = (float)done / (float)size;
395 std::cout << "Downloaded " << (int)(percent * 100) << "% \r";
396 }
397
398 outfile.write(data, data_length);
399 return true;
400 });
401 std::cout << "Download Complete - " << path << std::endl;
402 outfile.close();
403 }
404
405 catch(...) {}
406}
407
408void SaveToFile(std::string filename, std::string content)
409{
410 std::ofstream outfile;
411 outfile.open(filename);
412 outfile << content;
413 outfile.close();
414}
415
416void Log(const char *log)
417{
418 std::cout << log << std::endl;
419};
420
421
422void Log(std::string log)
423{
424 std::cout << log << std::endl;
425};
426
427#ifdef TERR3D_WIN32
428
429// From https://stackoverflow.com/a/20256714/14911094
430void RegSet(HKEY hkeyHive, const char *pszVar, const char *pszValue)
431{
432 HKEY hkey;
433 char szValueCurrent[1000];
434 DWORD dwType;
435 DWORD dwSize = sizeof(szValueCurrent);
436 int iRC = RegGetValue(hkeyHive, CA2CT(pszVar), NULL, RRF_RT_ANY, &dwType, szValueCurrent, &dwSize);
437 bool bDidntExist = iRC == ERROR_FILE_NOT_FOUND;
438
439 if (iRC != ERROR_SUCCESS && !bDidntExist)
440 {
441 Log("RegGetValue( " + std::string(pszVar) + " ) Failed : " + strerror(iRC));
442 }
443
444 if (!bDidntExist)
445 {
446 if (dwType != REG_SZ)
447 {
448 Log("RegGetValue( " + std::string(pszVar) + " ) found type unhandled " + std::to_string(dwType));
449 }
450
451 if (strcmp(szValueCurrent, pszValue) == 0)
452 {
453 Log("RegSet( \"" + std::string(pszVar) + "\" \"" + std::string(pszValue) + "\" ): already correct");
454 return;
455 }
456 }
457
458 DWORD dwDisposition;
459 iRC = RegCreateKeyEx(hkeyHive, CA2CT(pszVar), 0, 0, 0, KEY_ALL_ACCESS, NULL, &hkey, &dwDisposition);
460
461 if (iRC != ERROR_SUCCESS)
462 {
463 Log("RegSetValue( " + std::string(pszVar) + " ) Failed : " + strerror(iRC));
464 }
465
466 iRC = RegSetValueEx(hkey, L"", 0, REG_SZ, (BYTE *)pszValue, strlen(pszValue) + 1);
467
468 if (iRC != ERROR_SUCCESS)
469 {
470 Log("RegSetValue( " + std::string(pszVar) + " ) Failed: " + strerror(iRC));
471 }
472
473 if (bDidntExist)
474 {
475 Log("RegSet( " + std::string(pszVar) +" ): set to \"" + std::string(pszValue) + "\"");
476 }
477
478 else
479 {
480 Log("RegSet( " + std::string(pszVar) +" ): changed \"" + std::string(szValueCurrent) + "\" to \"" + std::string(pszValue) + "\"");
481 }
482
483 RegCloseKey(hkey);
484}
485
486#endif
487
488void AccocFileType()
489{
490#ifdef TERR3D_WIN32
491 RegSet(HKEY_CURRENT_USER, "Software\\Classes\\.terr3d", "TerraGen3D.TerraGen3D.1");
492 // Not needed.
493 RegSet(HKEY_CURRENT_USER, "Software\\Classes\\.terr3d\\Content Type", "application/json");
494 RegSet(HKEY_CURRENT_USER, "Software\\Classes\\.terr3d\\PerceivedType", "json");
495 //Not needed, but may be be a way to have wordpad show up on the default list.
496 RegSet( HKEY_CURRENT_USER, "Software\\Classes\\.terr3d\\OpenWithProgIds\\TerraGen3D.TerraGen3D.1", "" );
497 RegSet(HKEY_CURRENT_USER, "Software\\Classes\\TerraGen3D.TerraGen3D.1", "TerraGen3D");
498 RegSet(HKEY_CURRENT_USER, "Software\\Classes\\TerraGen3D.TerraGen3D.1\\Shell\\Open\\Command", (getExecutablePath() + " %1").c_str());
499#endif // TERR3D_WIN32
500}
501
502void MkDir(std::string path)
503{
504 if (!PathExist(path))
505 {
506#ifdef TERR3D_WIN32
507 system((std::string("mkdir \"") + path + "\"").c_str());
508#else
509 system((std::string("mkdir -p \"") + path + "\"").c_str());
510#endif
511 }
512}
513
514#ifndef TERR3D_WIN32
515int get_file_size(char *source)
516{
517 FILE *fichier = fopen(source, "rb");
518 fseek(fichier, 0, SEEK_END);
519 int size = ftell(fichier);
520 fseek(fichier, 0, SEEK_SET);
521 fclose(fichier);
522 return size;
523}
524#endif
525
526void CopyFileData(std::string source, std::string destination)
527{
528#ifdef TERR3D_WIN32
529 CopyFileW(CString(source.c_str()), CString(destination.c_str()), false);
530#else
531 int srcsize = get_file_size(source.data());
532 char *data = (char *)malloc(srcsize);
533 int fsource = open(source.c_str(), O_RDONLY);
534 int fdest = open(destination.c_str(), O_WRONLY | O_CREAT, 0777);
535 read(fsource, data, srcsize);
536 write(fdest, data, srcsize);
537 close(fsource);
538 close(fdest);
539 free(data);
540#endif
541}
542
543bool IsKeyDown(int key)
544{
545 return glfwGetKey(Application::Get()->GetWindow()->GetNativeWindow(), key) == GLFW_PRESS;
546}
547
548bool IsMouseButtonDown(int button)
549{
550 return glfwGetMouseButton(Application::Get()->GetWindow()->GetNativeWindow(), button);
551}
552
553void ShowMessageBox(std::string message, std::string title)
554{
555#ifdef TERR3D_WIN32
556 MessageBox(NULL, s2ws(message).c_str(), s2ws(title).c_str(), 0);
557#else
558 system(("zenity --info --text=" + message + " --title="+title + "").c_str());
559#endif
560}
561
562bool LoadTexture(Texture2D *texture, bool loadToAssets, bool preserveData, bool readAlpha, ProjectManager *projectManager)
563{
564 std::string fileName = ShowOpenFileDialog(".png");
565
566 if (fileName.size() > 3)
567 {
568 if (texture)
569 {
570 delete texture;
571 }
572
573 texture = new Texture2D(fileName, preserveData, readAlpha);
574
575 if(projectManager == nullptr)
576 {
577 projectManager = ProjectManager::Get();
578 }
579
580 if (loadToAssets)
581 {
582 projectManager->SaveTexture(texture);
583 }
584
585 return true;
586 }
587
588 return false;
589}
590
591void ToggleSystemConsole()
592{
593 static bool state = false;
594 state = !state;
595#ifdef TERR3D_WIN32
596 ShowWindow(GetConsoleWindow(), state ? SW_SHOW : SW_HIDE);
597#else
598 std::cout << "Toogle Console Not Supported on Linux!" << std::endl;
599#endif
600}
601
602void OpenURL(std::string url)
603{
604#ifdef TERR3D_WIN32
605 std::string op = std::string("start ").append(url);
606 system(op.c_str());
607#else
608 std::string op = std::string("xdg-open ").append(url);
609 system(op.c_str());
610#endif // TERR3D_WIN32
611}
std::size_t hash(const BasicJsonType &j)
hash a JSON value
Definition: json.hpp:5240
Definition: Utils.h:15