44#include " client/linux/handler/exception_handler.h"
55#include " common/linux/linux_libc_support.h"
66#include " third_party/lss/linux_syscall_support.h"
7+ #include " common/linux/http_upload.h"
78
89#include < dirent.h>
910#include < unistd.h>
1011#else
1112#include " client/windows/handler/exception_handler.h"
13+ #include " common/windows/http_upload.h"
1214#endif
1315
16+ #include " vendor/nlohmann/json.hpp"
17+
1418#include < sys/stat.h>
1519#include < stdio.h>
1620#include < stdlib.h>
1721#include < signal.h>
1822#include < limits>
1923#include < filesystem>
2024#include < codecvt>
25+ #include < thread>
26+ #include < fstream>
2127
2228#include " common/path_helper.h"
2329#include " common/using_std_string.h"
@@ -42,6 +48,8 @@ char crashMap[256];
4248char crashGamePath[512 ];
4349char crashCommandLine[1024 ];
4450char dumpStoragePath[512 ];
51+ std::string g_serverId;
52+ std::string g_UserId;
4553
4654CGameEntitySystem *GameEntitySystem ()
4755{
@@ -283,6 +291,137 @@ static bool dumpCallback(const wchar_t* dump_path,
283291}
284292#endif
285293
294+ #ifdef _LINUX
295+ void UploadThread ()
296+ {
297+ for (const auto & entry : std::filesystem::directory_iterator (dumpStoragePath)) {
298+ if (entry.path ().extension () == " .dmp" ) {
299+ std::filesystem::path uploadedPath = entry.path ();
300+
301+ // is dump already uploaded
302+ if (entry.path ().stem ().string ().find (" _uploaded" ) != std::string::npos) {
303+ continue ;
304+ }
305+
306+ ConMsg (" Uploading minidump %s\n " , entry.path ().string ().c_str ());
307+
308+ std::map<std::string, std::string> params;
309+
310+ params[" UserID" ] = g_UserId.c_str ();
311+ params[" GameDirectory" ] = " csgo" ;
312+ params[" ExtensionVersion" ] = std::string (g_AcceleratorCS2.GetVersion ()) + " [AcceleratorCS2 Build]" ;
313+ params[" ServerID" ] = g_serverId.c_str ();
314+ params[" PresubmitToken" ] = " " ;
315+
316+ std::filesystem::path metadataPath = entry.path ();
317+ metadataPath.replace_extension (" .dmp.txt" );
318+
319+ std::map<std::string, std::string> files;
320+ files[" upload_file_minidump" ] = entry.path ().string ();
321+ files[" upload_file_metadata" ] = metadataPath.string ();
322+
323+ std::string res;
324+ google_breakpad::HTTPUpload::SendRequest (" http://crash.limetech.org/submit" , params, files, " " , " " , " " , &res, nullptr , nullptr );
325+
326+ ConMsg (" Upload response: %s\n " , res.c_str ());
327+
328+ uploadedPath.replace_filename (uploadedPath.stem ().string () + " _uploaded" + uploadedPath.extension ().string ());
329+ std::filesystem::rename (entry.path (), uploadedPath);
330+ }
331+ }
332+ };
333+ #else
334+ void UploadThread ()
335+ {
336+ for (const auto & entry : std::filesystem::directory_iterator (dumpStoragePath)) {
337+ if (entry.path ().extension () == " .dmp" ) {
338+ std::filesystem::path uploadedPath = entry.path ();
339+
340+
341+ // is dump already uploaded
342+ if (entry.path ().stem ().string ().find (" _uploaded" ) != std::string::npos) {
343+ continue ;
344+ }
345+
346+ ConMsg (" Uploading minidump %s\n " , entry.path ().string ().c_str ());
347+
348+ std::wstring_convert<std::codecvt_utf8<wchar_t >, wchar_t > strconverter;
349+ std::map<std::wstring, std::wstring> params;
350+
351+ params[L" UserID" ] = strconverter.from_bytes (g_UserId).c_str ();
352+ params[L" GameDirectory" ] = L" csgo" ;
353+ params[L" ExtensionVersion" ] = strconverter.from_bytes (g_AcceleratorCS2.GetVersion ()) + L" [AcceleratorCS2 Build]" ;
354+ params[L" ServerID" ] = strconverter.from_bytes (g_serverId).c_str ();
355+ params[L" PresubmitToken" ] = L" " ;
356+
357+ std::filesystem::path metadataPath = entry.path ();
358+ metadataPath.replace_extension (" .dmp.txt" );
359+
360+ std::map<std::wstring, std::wstring> files;
361+ files[L" upload_file_minidump" ] = entry.path ().wstring ();
362+ files[L" upload_file_metadata" ] = metadataPath.wstring ();
363+
364+ std::wstring res;
365+ google_breakpad::HTTPUpload::SendMultipartPostRequest (L" http://crash.limetech.org/submit" , params, files, nullptr , &res, nullptr );
366+
367+ ConMsg (" Upload response: %s\n " , strconverter.to_bytes (res).c_str ());
368+
369+ uploadedPath.replace_filename (uploadedPath.stem ().string () + " _uploaded" + uploadedPath.extension ().string ());
370+ std::filesystem::rename (entry.path (), uploadedPath);
371+ }
372+ }
373+ };
374+ #endif
375+
376+ void LoadServerId ()
377+ {
378+ std::string serverIdPath = std::string (crashGamePath) + " /addons/accelerator_local/serverid.txt" ;
379+ std::ifstream serverIdFile (serverIdPath);
380+ if (serverIdFile.is_open ()) {
381+ serverIdFile >> g_serverId;
382+ serverIdFile.close ();
383+ }
384+ else {
385+ char buffer[64 ];
386+ V_snprintf (buffer, sizeof (buffer), " %02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" ,
387+ rand () % 255 , rand () % 255 , rand () % 255 , rand () % 255 , rand () % 255 , rand () % 255 , 0x40 | ((rand () % 255 ) & 0x0F ), rand () % 255 ,
388+ 0x80 | ((rand () % 255 ) & 0x3F ), rand () % 255 , rand () % 255 , rand () % 255 , rand () % 255 , rand () % 255 , rand () % 255 , rand () % 255 );
389+ g_serverId = buffer;
390+
391+ std::ofstream serverIdFile (serverIdPath);
392+ if (serverIdFile.is_open ()) {
393+ serverIdFile << g_serverId;
394+ serverIdFile.close ();
395+ }
396+ }
397+ };
398+
399+ void LoadConfig ()
400+ {
401+ // load json config
402+ std::string configPath = std::string (crashGamePath) + " /addons/accelerator_local/config.json" ;
403+ std::ifstream configFile (configPath);
404+ if (configFile.is_open ()) {
405+ nlohmann::json config;
406+ configFile >> config;
407+ configFile.close ();
408+
409+ if (config.contains (" MinidumpAccountSteamId64" )) {
410+ g_UserId = config[" MinidumpAccountSteamId64" ];
411+ }
412+ }
413+ else {
414+ nlohmann::json config;
415+ config[" MinidumpAccountSteamId64" ] = " " ;
416+
417+ std::ofstream configFile (configPath);
418+ if (configFile.is_open ()) {
419+ configFile << config.dump (2 );
420+ configFile.close ();
421+ }
422+ }
423+ }
424+
286425bool AcceleratorCS2::Load (PluginId id, ISmmAPI* ismm, char * error, size_t maxlen, bool late)
287426{
288427 PLUGIN_SAVEVARS ();
@@ -324,6 +463,12 @@ bool AcceleratorCS2::Load(PluginId id, ISmmAPI* ismm, char* error, size_t maxlen
324463 if (late)
325464 StartupServer ({}, nullptr , nullptr );
326465
466+ LoadServerId ();
467+ LoadConfig ();
468+
469+ ConMsg (" Start accelerator uploader thread\n " );
470+ new std::thread (UploadThread);
471+
327472 return true ;
328473}
329474
0 commit comments