├── .gitignore ├── poco-changes └── readme.txt ├── src ├── dll-debug.aps ├── resource.h ├── dll.rc ├── dll-debug.rc ├── protocols │ ├── log.h │ ├── sql_raw_v2.h │ ├── steam_v2.h │ ├── abstract_protocol.h │ ├── rcon.h │ ├── misc.h │ ├── log.cpp │ ├── sql_custom_v2.h │ ├── rcon.cpp │ ├── steam_v2.cpp │ ├── misc.cpp │ └── sql_raw_v2.cpp ├── sanitize.h ├── spdlog │ ├── LICENSE │ ├── details │ │ ├── null_mutex.h │ │ ├── log_msg.h │ │ ├── async_logger_impl.h │ │ ├── file_helper.h │ │ ├── os.h │ │ ├── line_logger.h │ │ ├── mpmc_bounded_q.h │ │ ├── spdlog_impl.h │ │ ├── registry.h │ │ └── logger_impl.h │ ├── sinks │ │ ├── sink.h │ │ ├── null_sink.h │ │ ├── base_sink.h │ │ ├── ostream_sink.h │ │ ├── stdout_sinks.h │ │ ├── dist_sink.h │ │ ├── android_sink.h │ │ ├── syslog_sink.h │ │ └── file_sinks.h │ ├── formatter.h │ ├── common.h │ ├── tweakme.h │ ├── async_logger.h │ ├── logger.h │ └── spdlog.h ├── memory_allocator.cpp ├── sanitize.cpp ├── backends │ ├── steam.h │ ├── belogscanner.h │ └── rcon.h ├── main.cpp ├── abstract_ext.h └── ext.h ├── Changelog STEAM_V2.txt ├── LICENSES ├── examples ├── sqf │ ├── fn_strip.sqf │ ├── fn_async.sqf │ └── init.sqf └── sql_custom_v2 │ └── example.ini ├── README.md ├── extdb-conf.ini └── Changelog SQL_CUSTOM.txt /.gitignore: -------------------------------------------------------------------------------- 1 | bld/ 2 | *.aps 3 | -------------------------------------------------------------------------------- /poco-changes/readme.txt: -------------------------------------------------------------------------------- 1 | Custom Poco now located @ https://github.com/ArmaLife/poco 2 | -------------------------------------------------------------------------------- /src/dll-debug.aps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/AsYetUntitled/extDB2/HEAD/src/dll-debug.aps -------------------------------------------------------------------------------- /Changelog STEAM_V2.txt: -------------------------------------------------------------------------------- 1 | STEAM Protocol 2 | GetFriends -> GET_FRIENDS (now case sensitive) 3 | STEAMBanned -> VAC_BANNED (now case sensitive) -------------------------------------------------------------------------------- /LICENSES: -------------------------------------------------------------------------------- 1 | License Info is located inside the relevant directories... 2 | 3 | src/LICENSE 4 | src/spdlog/LICENSE https://github.com/gabime/spdlog 5 | -------------------------------------------------------------------------------- /src/resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Visual C++ generated include file. 3 | // Used by dll.rc 4 | // 5 | 6 | // Next default values for new objects 7 | // 8 | #ifdef APSTUDIO_INVOKED 9 | #ifndef APSTUDIO_READONLY_SYMBOLS 10 | #define _APS_NEXT_RESOURCE_VALUE 101 11 | #define _APS_NEXT_COMMAND_VALUE 40001 12 | #define _APS_NEXT_CONTROL_VALUE 1000 13 | #define _APS_NEXT_SYMED_VALUE 101 14 | #endif 15 | #endif 16 | -------------------------------------------------------------------------------- /examples/sqf/fn_strip.sqf: -------------------------------------------------------------------------------- 1 | /* 2 | File: fn_strip.sqf 3 | Author: Declan Ireland 4 | 5 | Description: 6 | Strips : from String 7 | Needed since extDB2 uses : as seperator character 8 | 9 | i.e Playernames 10 | Uhis is not needed if you have enabled extDB2 RCon + kicking for Bad Playernames 11 | Or have a 3rd party Rcon Application that will kick players for have : in thier playername 12 | 13 | But if you allow saving of Player Input i.e messages etc you will still need to parse them for : 14 | Parameters: 15 | 0: ClientID 16 | */ 17 | 18 | private["_string","_array"]; 19 | 20 | _string = (_this select 0); 21 | 22 | _array = toArray _string; 23 | { 24 | if (_x == 58) then 25 | { 26 | _array set[_forEachIndex, -1]; 27 | }; 28 | } foreach _array; 29 | _array = _array - [-1]; 30 | _string = toString _array; 31 | _string -------------------------------------------------------------------------------- /src/dll.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define PRODUCT_NAME_STR "extDB2" 4 | #define PRODUCT_DESCRIPTION "Arma Kitchen Sink Extension" 5 | #define VER_VERSION 70,0,0,0 6 | #define VER_VERSION_STR "70.0.0.0" 7 | 8 | VS_VERSION_INFO VERSIONINFO 9 | FILEVERSION VER_VERSION 10 | PRODUCTVERSION VER_VERSION 11 | FILEFLAGSMASK 0x3fL 12 | #ifdef _DEBUG 13 | FILEFLAGS 0x1L 14 | #else 15 | FILEFLAGS 0x0L 16 | #endif 17 | FILEOS VOS__WINDOWS32 18 | FILETYPE VFT_DLL 19 | FILESUBTYPE VFT2_UNKNOWN 20 | BEGIN 21 | BLOCK "StringFileInfo" 22 | BEGIN 23 | BLOCK "000004b0" 24 | BEGIN 25 | VALUE "FileDescription", PRODUCT_DESCRIPTION 26 | VALUE "FileVersion", VER_VERSION_STR 27 | VALUE "ProductName", PRODUCT_NAME_STR 28 | VALUE "ProductVersion", VER_VERSION_STR 29 | END 30 | END 31 | BLOCK "VarFileInfo" 32 | BEGIN 33 | VALUE "Translation", 0x0, 1200 34 | END 35 | END 36 | -------------------------------------------------------------------------------- /src/dll-debug.rc: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define PRODUCT_NAME_STR "extDB2 Debug" 4 | #define PRODUCT_DESCRIPTION "Arma Kitchen Sink Extension" 5 | #define VER_VERSION 71,0,0,0 6 | #define VER_VERSION_STR "71.0.0.0" 7 | 8 | VS_VERSION_INFO VERSIONINFO 9 | FILEVERSION VER_VERSION 10 | PRODUCTVERSION VER_VERSION 11 | FILEFLAGSMASK 0x3fL 12 | #ifdef _DEBUG 13 | FILEFLAGS 0x1L 14 | #else 15 | FILEFLAGS 0x0L 16 | #endif 17 | FILEOS VOS__WINDOWS32 18 | FILETYPE VFT_DLL 19 | FILESUBTYPE VFT2_UNKNOWN 20 | BEGIN 21 | BLOCK "StringFileInfo" 22 | BEGIN 23 | BLOCK "000004b0" 24 | BEGIN 25 | VALUE "FileDescription", PRODUCT_DESCRIPTION 26 | VALUE "FileVersion", VER_VERSION_STR 27 | VALUE "ProductName", PRODUCT_NAME_STR 28 | VALUE "ProductVersion", VER_VERSION_STR 29 | END 30 | END 31 | BLOCK "VarFileInfo" 32 | BEGIN 33 | VALUE "Translation", 0x0, 1200 34 | END 35 | END 36 | -------------------------------------------------------------------------------- /src/protocols/log.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include "abstract_protocol.h" 22 | 23 | 24 | class LOG: public AbstractProtocol 25 | { 26 | public: 27 | bool init(AbstractExt *extension, const std::string &database_id, const std::string &init_str); 28 | bool callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id=1); 29 | 30 | private: 31 | std::shared_ptr logger; 32 | }; -------------------------------------------------------------------------------- /src/protocols/sql_raw_v2.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include "abstract_protocol.h" 22 | 23 | 24 | class SQL_RAW_V2: public AbstractProtocol 25 | { 26 | public: 27 | bool init(AbstractExt *extension, const std::string &database_id, const std::string &init_str); 28 | bool callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id=1); 29 | 30 | private: 31 | bool stringDataTypeCheck; 32 | }; 33 | -------------------------------------------------------------------------------- /src/protocols/steam_v2.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include "abstract_protocol.h" 22 | 23 | 24 | class STEAM_V2: public AbstractProtocol 25 | { 26 | public: 27 | bool init(AbstractExt *extension, const std::string &database_id, const std::string &init_str); 28 | bool callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id=1); 29 | 30 | private: 31 | bool isNumber(const std::string &input_str); 32 | }; -------------------------------------------------------------------------------- /src/sanitize.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | Copyright (C) 2009-2012 Rajko Stojadinovic 4 | 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | 21 | 22 | #pragma once 23 | 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | namespace Sqf 31 | { 32 | typedef boost::make_recursive_variant< double, int, Poco::Int64, bool, std::string, void*, std::vector >::type Value; 33 | typedef std::vector Parameters; 34 | typedef std::string::iterator iter_t; 35 | 36 | bool check(std::string input_str); 37 | } -------------------------------------------------------------------------------- /src/protocols/abstract_protocol.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include "../abstract_ext.h" 22 | 23 | class AbstractProtocol 24 | { 25 | public: 26 | AbstractProtocol(){}; 27 | ~AbstractProtocol(){}; 28 | 29 | virtual bool init(AbstractExt *extension, const std::string &database_id, const std::string &init_str)=0; 30 | virtual bool callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id=1)=0; 31 | 32 | AbstractExt *extension_ptr; 33 | AbstractExt::DBConnectionInfo *database_ptr; 34 | }; 35 | -------------------------------------------------------------------------------- /src/protocols/rcon.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include "abstract_protocol.h" 22 | 23 | 24 | class RCON: public AbstractProtocol 25 | { 26 | public: 27 | bool init(AbstractExt *extension, const std::string &database_id, const std::string &init_str); 28 | bool callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id=1); 29 | 30 | void processCommand(std::string &command, std::string &input_str, const unsigned int unique_id, std::string &result); 31 | 32 | private: 33 | std::vector allowed_commands; 34 | }; 35 | -------------------------------------------------------------------------------- /src/spdlog/LICENSE: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | -------------------------------------------------------------------------------- /examples/sqf/fn_async.sqf: -------------------------------------------------------------------------------- 1 | /* 2 | File: asyncCall.sqf 3 | Author: Bryan "Tonic" Boardwine 4 | 5 | Description: 6 | Commits an asynchronous call to extDB 7 | Gets result via extDB 4:x + uses 5:x if message is Multi-Part 8 | 9 | Parameters: 10 | 0: STRING (Query to be ran). 11 | 1: INTEGER (1 = ASYNC + not return for update/insert, 2 = ASYNC + return for query's). 12 | */ 13 | 14 | private["_queryStmt","_queryResult","_key","_mode","_return","_loop"]; 15 | 16 | if (!params [ 17 | ["_queryStmt", "", [""]], 18 | ["_mode", 0, [0]] 19 | ]) exitWith {}; 20 | 21 | _key = "extDB2" callExtension format["%1:%2:%3",_mode, (call extDB_SQL_CUSTOM_ID), _queryStmt]; 22 | if(_mode isEqualTo 1) exitWith {true}; 23 | 24 | _key = call compile format["%1",_key]; 25 | _key = _key select 1; 26 | 27 | uisleep (random .03); 28 | 29 | _queryResult = ""; 30 | _loop = true; 31 | while{_loop} do 32 | { 33 | _queryResult = "extDB2" callExtension format["4:%1", _key]; 34 | if (_queryResult isEqualTo "[5]") then { 35 | // extDB2 returned that result is Multi-Part Message 36 | _queryResult = ""; 37 | while{true} do { 38 | _pipe = "extDB2" callExtension format["5:%1", _key]; 39 | if(_pipe isEqualTo "") exitWith {_loop = false}; 40 | _queryResult = _queryResult + _pipe; 41 | }; 42 | } 43 | else 44 | { 45 | if (_queryResult isEqualTo "[3]") then 46 | { 47 | diag_log format ["extDB2: uisleep [4]: %1", diag_tickTime]; 48 | uisleep 0.1; 49 | } else { 50 | _loop = false; 51 | }; 52 | }; 53 | }; 54 | 55 | 56 | _queryResult = call compile _queryResult; 57 | 58 | // Not needed, its SQF Code incase extDB2 ever returns error message i.e Database Connection Died 59 | if ((_queryResult select 0) isEqualTo 0) exitWith {diag_log format ["extDB2: Protocol Error: %1", _queryResult]; []}; 60 | _return = (_queryResult select 1); 61 | _return; 62 | -------------------------------------------------------------------------------- /src/memory_allocator.cpp: -------------------------------------------------------------------------------- 1 | #include "tbb/scalable_allocator.h" 2 | 3 | // No retry loop because we assume that scalable_malloc does 4 | // all it takes to allocate the memory, so calling it repeatedly 5 | // will not improve the situation at all 6 | // 7 | // No use of std::new_handler because it cannot be done in portable 8 | // and thread-safe way (see sidebar) 9 | // 10 | // We throw std::bad_alloc() when scalable_malloc returns NULL 11 | //(we return NULL if it is a no-throw implementation) 12 | 13 | // Code is from Intel threading building blocks 14 | 15 | 16 | void* operator new (size_t size) 17 | { 18 | if (size == 0) size = 1; 19 | void* ptr = scalable_malloc(size); 20 | if (ptr == NULL) 21 | { 22 | throw std::bad_alloc(); 23 | } 24 | return ptr; 25 | } 26 | 27 | void* operator new[] (size_t size) 28 | { 29 | void* ptr = scalable_malloc(size); 30 | if (ptr == NULL) 31 | { 32 | throw std::bad_alloc(); 33 | } 34 | return ptr; 35 | } 36 | 37 | void* operator new (size_t size, const std::nothrow_t&) 38 | { 39 | if (size == 0) size = 1; 40 | void* ptr = scalable_malloc(size); 41 | if (ptr == NULL) 42 | { 43 | return ptr; 44 | } 45 | else 46 | { 47 | return NULL; 48 | } 49 | } 50 | 51 | void* operator new[] (size_t size, const std::nothrow_t&) 52 | { 53 | void* ptr = scalable_malloc(size); 54 | if (ptr == NULL) 55 | { 56 | return ptr; 57 | } 58 | else 59 | { 60 | return NULL; 61 | } 62 | } 63 | 64 | void operator delete (void* ptr) 65 | { 66 | if (ptr != NULL) 67 | { 68 | scalable_free(ptr); 69 | } 70 | } 71 | 72 | void operator delete[] (void* ptr) 73 | { 74 | operator delete (ptr); 75 | } 76 | 77 | void operator delete (void* ptr, const std::nothrow_t&) 78 | { 79 | if (ptr != NULL) 80 | { 81 | scalable_free(ptr); 82 | } 83 | } 84 | 85 | void operator delete[] (void* ptr, const std::nothrow_t&) 86 | { 87 | operator delete(ptr); 88 | } 89 | -------------------------------------------------------------------------------- /src/protocols/misc.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include 24 | 25 | #include 26 | #include 27 | 28 | #include "abstract_protocol.h" 29 | 30 | 31 | class MISC: public AbstractProtocol 32 | { 33 | public: 34 | bool init(AbstractExt *extension, const std::string &database_id, const std::string &init_str); 35 | bool callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id=1); 36 | 37 | private: 38 | Poco::MD5Engine md5; 39 | std::mutex mutex_md5; 40 | 41 | Poco::MD4Engine md4; 42 | std::mutex mutex_md4; 43 | 44 | boost::crc_32_type crc32; 45 | std::mutex mutex_crc32; 46 | 47 | void getCrc32(std::string &input_str, std::string &result); 48 | void getMD4(std::string &input_str, std::string &result); 49 | void getMD5(std::string &input_str, std::string &result); 50 | void getBEGUID(std::string &input_str, std::string &result); 51 | void getDateTime(const std::string &input_str, std::string &result); 52 | 53 | void getRandomString(std::string &input_str, std::string &result); 54 | }; 55 | -------------------------------------------------------------------------------- /src/protocols/log.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #include "log.h" 20 | 21 | #include 22 | 23 | 24 | bool LOG::init(AbstractExt *extension, const std::string &database_id, const std::string &init_str) 25 | { 26 | bool status = false; 27 | extension_ptr = extension; 28 | 29 | if (!(init_str.empty())) 30 | { 31 | try 32 | { 33 | boost::filesystem::path customlog(extension_ptr->ext_info.log_path); 34 | customlog /= init_str; 35 | if (customlog.parent_path().make_preferred().string() == extension_ptr->ext_info.log_path) 36 | { 37 | logger = spdlog::rotating_logger_mt(init_str, customlog.make_preferred().string(), 1048576 * 100, 3, extension_ptr->ext_info.logger_flush); 38 | status = true; 39 | } 40 | } 41 | catch (spdlog::spdlog_ex& e) 42 | { 43 | #ifdef DEBUG_TESTING 44 | extension_ptr->console->warn("extDB2: LOG: Error: {0}", e.what()); 45 | #endif 46 | extension_ptr->logger->warn("extDB2: LOG: Error: {0}", e.what()); 47 | status = false; 48 | } 49 | } 50 | else 51 | { 52 | logger = extension_ptr->logger; 53 | status = true; 54 | } 55 | return status; 56 | } 57 | 58 | 59 | bool LOG::callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id) 60 | { 61 | logger->info(input_str.c_str()); 62 | result = "[1]"; 63 | return true; 64 | } -------------------------------------------------------------------------------- /src/spdlog/details/null_mutex.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | // null, no cost mutex 28 | 29 | namespace spdlog 30 | { 31 | namespace details 32 | { 33 | struct null_mutex 34 | { 35 | void lock() {} 36 | void unlock() {} 37 | bool try_lock() 38 | { 39 | return true; 40 | } 41 | }; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/spdlog/sinks/sink.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | #include "../details/log_msg.h" 28 | 29 | namespace spdlog 30 | { 31 | namespace sinks 32 | { 33 | class sink 34 | { 35 | public: 36 | virtual ~sink() {} 37 | virtual void log(const details::log_msg& msg) = 0; 38 | virtual void flush() = 0; 39 | }; 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /examples/sqf/init.sqf: -------------------------------------------------------------------------------- 1 | /* 2 | File: init.sqf 3 | Author: 4 | 5 | Description: 6 | Initializes extDB, loads Protocol + options if any + Locks extDB 7 | 8 | Parameters: 9 | 0: STRING Database name as in extdb-conf.ini 10 | 1: STRING Protocol to enable 11 | 2: STRING Optional Protocol Options i.e db_conf name for DB_CUSTOM 12 | */ 13 | 14 | private["_database","_protocol","_protocol_options","_return","_result","_random_number","_extDB_SQL_CUSTOM_ID"]; 15 | 16 | _database = [_this,0,"",[""]] call BIS_fnc_param; 17 | _protocol = [_this,1,"",[""]] call BIS_fnc_param; 18 | _protocol_options = [_this,2,"",[""]] call BIS_fnc_param; 19 | 20 | 21 | _return = false; 22 | 23 | if ( isNil {uiNamespace getVariable "extDB_SQL_CUSTOM_ID"}) then 24 | { 25 | // extDB Version 26 | _result = "extDB2" callExtension "9:VERSION"; 27 | 28 | diag_log format ["extDB2: Version: %1", _result]; 29 | if(_result == "") exitWith {diag_log "extDB2: Failed to Load"; false}; 30 | //if ((parseNumber _result) < 20) exitWith {diag_log "Error: extDB version 20 or Higher Required";}; 31 | 32 | // extDB Connect to Database 33 | _result = call compile ("extDB2" callExtension format["9:ADD_DATABASE:%1", _database]); 34 | if (_result select 0 isEqualTo 0) exitWith {diag_log format ["extDB2: Error Database: %1", _result]; false}; 35 | diag_log "extDB2: Connected to Database"; 36 | 37 | // Generate Randomized Protocol Name 38 | _random_number = round(random(999999)); 39 | _extDB_SQL_CUSTOM_ID = str(_random_number); 40 | extDB_SQL_CUSTOM_ID = compileFinal _extDB_SQL_CUSTOM_ID; 41 | 42 | // extDB Load Protocol 43 | _result = call compile ("extDB2" callExtension format["9:ADD_DATABASE_PROTOCOL:%1:%2:%3:%4", _database, _protocol, _extDB_SQL_CUSTOM_ID, _protocol_options]); 44 | if ((_result select 0) isEqualTo 0) exitWith {diag_log format ["extDB2: Error Database Setup: %1", _result]; false}; 45 | 46 | diag_log format ["extDB2: Initalized %1 Protocol", _protocol]; 47 | 48 | // extDB2 Lock 49 | "extDB2" callExtension "9:LOCK"; 50 | diag_log "extDB2: Locked"; 51 | 52 | // Save Randomized ID 53 | uiNamespace setVariable ["extDB_SQL_CUSTOM_ID", _extDB_SQL_CUSTOM_ID]; 54 | _return = true; 55 | } 56 | else 57 | { 58 | extDB_SQL_CUSTOM_ID = compileFinal str(uiNamespace getVariable "extDB_SQL_CUSTOM_ID"); 59 | diag_log "extDB2: Already Setup"; 60 | _return = true; 61 | }; 62 | 63 | _return 64 | -------------------------------------------------------------------------------- /src/spdlog/sinks/null_sink.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | #include 27 | #include "./base_sink.h" 28 | #include "../details/null_mutex.h" 29 | 30 | 31 | namespace spdlog 32 | { 33 | namespace sinks 34 | { 35 | 36 | template 37 | class null_sink : public base_sink < Mutex > 38 | { 39 | protected: 40 | void _sink_it(const details::log_msg&) override 41 | {} 42 | 43 | void flush() override 44 | {} 45 | 46 | }; 47 | typedef null_sink null_sink_st; 48 | typedef null_sink null_sink_mt; 49 | 50 | } 51 | } 52 | 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Arma3 Extension DB2 2 | Arma3 Database + Rcon Extension for both Windows + Linux. 3 | 4 | [paypal] 5 | 6 | #### Public Missions / Mods using extDB2 7 | https://www.exilemod.com 8 | 9 | #### Features 10 | 11 | - ASync + Sync Support 12 | - Unique ID for fetching Results 13 | - Multi-Part Messages 14 | - Arma2 Legacy randomize configfile support 15 | 16 | - Commandline Arguments Support 17 | - Rcon Support 18 | - Rcon Whitelisting + Kicking for Bad Playernames 19 | - Steam VAC + Friends Queries 20 | 21 | 22 | #### Supported Backends 23 | 24 | - MySQL 25 | - SQLite 26 | 27 | #### Protocols 28 | 29 | - SQL_CUSTOM_V2 (Ability to define sql prepared statements in a .ini file) 30 | - SQL_RAW 31 | - LOG (Custom Logfiles) 32 | - MISC (has beguid, crc32, md4/5, time + time offset) 33 | - RCON (Ability to whitelist allowed commands) 34 | - STEAM_V2 (Ability to Query Steam for VAC Bans / Friend Info) 35 | 36 | 37 | #### Documentation @ 38 | https://github.com/Torndeco/extDB2/wiki 39 | 40 | 41 | #### Troubleshooting for Server Admins 42 | Have a look at this: [Troubleshooting](https://github.com/Torndeco/extDB2/wiki/Troubleshooting) 43 | 44 | 45 | #### Linux Requirements 46 | Linux Distro with Glibc 2.17 or higher 47 | Debian 8 / Centos 7 / Ubuntu 14.10 48 | 49 | #### Windows Requirements 50 | Windows Server 2008 + Later 51 | Windows 7 + Later 52 | 53 | Install vcredist_x86.exe 54 | http://www.microsoft.com/en-ie/download/details.aspx?id=40784 55 | 56 | 57 | ##### Donations 58 | If you link to donate to extDB2 Developement use donate button above. 59 | Don't forget to leave message if any features you would like to see implemented. 60 | 61 | 62 | #### Thanks to 63 | 64 | - [firefly2442](https://github.com/firefly2442) for the CMake Build System. 65 | - [MaHuJa](https://github.com/MaHuJa) for taking time to look over the code and fixing / improving the code. 66 | - [bladez-](https://github.com/bladez-) For the original Rcon code, made my life alot easier. 67 | - [Fank](https://gist.github.com/Fank) for his code to convert SteamID to BEGuid. 68 | - [Gabime](https://github.com/gabime) for Spdlog Logging Library. 69 | - [rajkosto](https://github.com/rajkosto) for his work on DayZ Hive, using same code for sanitize checks. 70 | - [Tonic](https://github.com/TAWTonic) & Altis RPG Admins for initial testing of extDB etc. 71 | -------------------------------------------------------------------------------- /examples/sql_custom_v2/example.ini: -------------------------------------------------------------------------------- 1 | [Default] 2 | Version = 10 3 | 4 | Number of Inputs = 0 5 | 6 | ;;Sanitize Checks are better than Strip Characters, but only accept ASCII Characters 7 | ;;Requires abit more work to setup correctly. 8 | Sanitize Input Value Check = false 9 | Sanitize Output Value Check = false 10 | 11 | ;;Allows you to disable Prepared Statement Caching. 12 | ;;Mainly for people that don't want to waste memory on caching a Statement that is only once. 13 | Prepared Statement Cache = true 14 | 15 | ;;Returns InsertID, Instead of returning [1,[]] It returns [1,[,[]]] 16 | Return InsertID = false 17 | 18 | ;;Strip Characters 19 | Strip = true 20 | ;;Possible Actions Are "Strip" / "Strip+Log" / "Strip+Error" / "None" 21 | Strip Chars Action = STRIP 22 | Strip Chars = /\|;{}<>'` 23 | ;;Strip Chars Used for $CUSTOM_x$ Inputs 24 | Strip Custom Chars = /\|;{}<>'` 25 | 26 | 27 | ; -------------------------------------------------------------------------------- 28 | ; SQL Statements 29 | ; -------------------------------------------------------------------------------- 30 | 31 | [existPlayerInfo] 32 | ;; Name of call == existPlayerInfo 33 | SQL1_1 = SELECT CASE 34 | SQL1_2 = WHEN EXISTS(SELECT * FROM PlayerInfo WHERE UID = ?) 35 | SQL1_3 = THEN 'true' ELSE 'false' 36 | SQL1_4 = END 37 | SQL1_INPUTS = 1 38 | 39 | Number of Inputs = 1 40 | 41 | ;;SQL Statements can be split up into multiple lines to make more readable. 42 | ;; You can also run multiple SQL Statements via SQL2_1, SQL2_2, SQL3_1 etc.. 43 | 44 | 45 | [updatePlayerSaveValueString] 46 | SQL1_1 = UPDATE PlayerSave 47 | SQL1_2 = SET $CUSTOM_1$ = ? 48 | SQL1_3 = WHERE PlayerUID = ? AND MapID = ?; 49 | SQL1_INPUTS = 3, 1, 2 50 | 51 | Number of Inputs = 3 52 | Number of Custom Inputs = 1 53 | 54 | ;;$CUSTOM_x$ allows you to insert dynamic text into an prepared statement. 55 | ;;Downside is the statement isn't cached + possible less secure. 56 | 57 | ;;Note the order of passing inputs to extDB2 is important with custom inputs. 58 | ;; Its : 59 | ;; So the inputs would be in this order _playerUID:_mapID:_value:_custom_1 60 | 61 | ;;Also you can re-arrange the Input Value Order 62 | 63 | 64 | [gangInfo] 65 | SQL1_1 = SELECT id, owner, name, maxmembers, bank, members FROM gangs WHERE active='1' AND members LIKE ?; 66 | SQL1_INPUTS = 1 67 | 68 | Number of Inputs = 1 69 | OUTPUT = 1, 2-String, 3-String, 4, 5, 6 70 | 71 | ;;You can also define options for Output Value aswell if you like aswell i.e 1-STRING-BEGUID 72 | ;;Or do mixture of using INPUTS + OUTPUT Options. 73 | 74 | -------------------------------------------------------------------------------- /src/spdlog/formatter.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | #pragma once 25 | 26 | #include "details/log_msg.h" 27 | namespace spdlog 28 | { 29 | namespace details 30 | { 31 | class flag_formatter; 32 | } 33 | 34 | class formatter 35 | { 36 | public: 37 | virtual ~formatter() {} 38 | virtual void format(details::log_msg& msg) = 0; 39 | }; 40 | 41 | class pattern_formatter : public formatter 42 | { 43 | 44 | public: 45 | explicit pattern_formatter(const std::string& pattern); 46 | pattern_formatter(const pattern_formatter&) = delete; 47 | pattern_formatter& operator=(const pattern_formatter&) = delete; 48 | void format(details::log_msg& msg) override; 49 | private: 50 | const std::string _pattern; 51 | std::vector> _formatters; 52 | void handle_flag(char flag); 53 | void compile_pattern(const std::string& pattern); 54 | }; 55 | } 56 | 57 | #include "details/pattern_formatter_impl.h" 58 | 59 | -------------------------------------------------------------------------------- /src/spdlog/sinks/base_sink.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | // 27 | // base sink templated over a mutex (either dummy or realy) 28 | // concrete implementation should only overrid the _sink_it method. 29 | // all locking is taken care of here so no locking needed by the implementors.. 30 | // 31 | 32 | #include 33 | #include 34 | #include 35 | #include "./sink.h" 36 | #include "../formatter.h" 37 | #include "../common.h" 38 | #include "../details/log_msg.h" 39 | 40 | 41 | namespace spdlog 42 | { 43 | namespace sinks 44 | { 45 | template 46 | class base_sink:public sink 47 | { 48 | public: 49 | base_sink():_mutex() {} 50 | virtual ~base_sink() = default; 51 | 52 | base_sink(const base_sink&) = delete; 53 | base_sink& operator=(const base_sink&) = delete; 54 | 55 | void log(const details::log_msg& msg) override 56 | { 57 | std::lock_guard lock(_mutex); 58 | _sink_it(msg); 59 | } 60 | 61 | protected: 62 | virtual void _sink_it(const details::log_msg& msg) = 0; 63 | Mutex _mutex; 64 | }; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/spdlog/sinks/ostream_sink.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "../details/null_mutex.h" 32 | #include "./base_sink.h" 33 | 34 | namespace spdlog 35 | { 36 | namespace sinks 37 | { 38 | template 39 | class ostream_sink: public base_sink 40 | { 41 | public: 42 | explicit ostream_sink(std::ostream& os, bool force_flush=false) :_ostream(os), _force_flush(force_flush) {} 43 | ostream_sink(const ostream_sink&) = delete; 44 | ostream_sink& operator=(const ostream_sink&) = delete; 45 | virtual ~ostream_sink() = default; 46 | 47 | protected: 48 | void _sink_it(const details::log_msg& msg) override 49 | { 50 | _ostream.write(msg.formatted.data(), msg.formatted.size()); 51 | if (_force_flush) 52 | _ostream.flush(); 53 | } 54 | 55 | void flush() override 56 | { 57 | _ostream.flush(); 58 | } 59 | 60 | std::ostream& _ostream; 61 | bool _force_flush; 62 | }; 63 | 64 | typedef ostream_sink ostream_sink_mt; 65 | typedef ostream_sink ostream_sink_st; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/spdlog/sinks/stdout_sinks.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | #include 28 | #include 29 | #include "./ostream_sink.h" 30 | #include "../details/null_mutex.h" 31 | 32 | namespace spdlog 33 | { 34 | namespace sinks 35 | { 36 | 37 | template 38 | class stdout_sink : public ostream_sink 39 | { 40 | using MyType = stdout_sink; 41 | public: 42 | stdout_sink() : ostream_sink(std::cout, true) {} 43 | static std::shared_ptr instance() 44 | { 45 | static std::shared_ptr instance = std::make_shared(); 46 | return instance; 47 | } 48 | }; 49 | 50 | typedef stdout_sink stdout_sink_st; 51 | typedef stdout_sink stdout_sink_mt; 52 | 53 | 54 | template 55 | class stderr_sink : public ostream_sink 56 | { 57 | using MyType = stderr_sink; 58 | public: 59 | stderr_sink() : ostream_sink(std::cerr, true) {} 60 | static std::shared_ptr instance() 61 | { 62 | static std::shared_ptr instance = std::make_shared(); 63 | return instance; 64 | } 65 | 66 | }; 67 | 68 | typedef stderr_sink stderr_sink_mt; 69 | typedef stderr_sink stderr_sink_st; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/protocols/sql_custom_v2.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | 28 | #include "abstract_protocol.h" 29 | 30 | #define EXTDB_SQL_CUSTOM_V2_REQUIRED_VERSION 8 31 | #define EXTDB_SQL_CUSTOM_V2_LATEST_VERSION 12 32 | 33 | 34 | class SQL_CUSTOM_V2: public AbstractProtocol 35 | { 36 | public: 37 | bool init(AbstractExt *extension, const std::string &database_id, const std::string &init_str); 38 | bool callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id=1); 39 | 40 | private: 41 | std::string default_seperator; 42 | 43 | Poco::MD5Engine md5; 44 | std::mutex mutex_md5; 45 | 46 | struct Value_Options 47 | { 48 | int number = -1; 49 | 50 | bool check; 51 | bool check_add_quotes = false; 52 | bool check_add_escape_quotes = false; 53 | 54 | bool boolean = false; 55 | bool beguid = false; 56 | 57 | bool vac_steamID = false; 58 | 59 | bool string = false; 60 | bool string_escape_quotes = false; 61 | 62 | bool datetime_iso8601 = false; 63 | 64 | bool strip = false; 65 | bool return_player_key = false; 66 | }; 67 | 68 | struct customCall 69 | { 70 | bool strip; 71 | bool preparedStatement_cache; 72 | bool returnInsertID; 73 | bool returnPlayerKey; 74 | 75 | int number_of_inputs; 76 | int number_of_custom_inputs; 77 | 78 | int strip_chars_action; 79 | std::string strip_chars; 80 | std::string strip_custom_input_chars; 81 | 82 | std::string seperator; 83 | 84 | std::vector< std::string> sql_prepared_statements; 85 | 86 | std::vector< std::vector< Value_Options > > sql_inputs_options; 87 | std::vector< Value_Options > sql_outputs_options; 88 | }; 89 | 90 | typedef std::unordered_map Custom_Call_UnorderedMap; 91 | 92 | Custom_Call_UnorderedMap custom_calls; 93 | 94 | void callPreparedStatement(std::string call_name, Custom_Call_UnorderedMap::const_iterator custom_calls_itr, std::vector< std::vector > &all_processed_inputs, std::vector &custom_inputs, std::string &player_key, bool &status, std::string &result); 95 | 96 | void executeSQL(Poco::Data::Statement &sql_statement, std::string &result, bool &status); 97 | 98 | void getBEGUID(std::string &input_str, std::string &result); 99 | void getResult(std::unordered_map::const_iterator &custom_protocol_itr, Poco::Data::Session &session, Poco::Data::Statement &sql_statement, std::string &player_key, std::string &result, bool &status); 100 | }; 101 | -------------------------------------------------------------------------------- /extdb-conf.ini: -------------------------------------------------------------------------------- 1 | [Main] 2 | Version = 5 3 | 4 | ;Threads = 0 5 | ; Default Value is the number of CPU Cores Detected (max value is 6, min value is 2) 6 | 7 | Randomize Config File = false 8 | ;This is a legacy option to randomize config file for Arma2 Servers. Only for Windows Builds 9 | 10 | 11 | [Rcon] 12 | ;; This is functional, should be working fine. Just needs abit of testing on a $ 13 | ;; Allow for changing Address for those running server in a VM environment. 14 | IP = 127.0.0.1 15 | Port = 2302 16 | 17 | ;; Rcon Password i.e Battleye/beserver.cfg 18 | Password = password 19 | 20 | ;; Bad Player Name Checks 21 | ;; This will only work if your mission / mod has started extDB2 Rcon. i.e 9:START_RCON:RCON 22 | Bad Playername Enable = false 23 | Bad Playername Kick Message = Bad Player Name 24 | 25 | ;; By default : is a bad character (used as seperator for extDB2 Calls (this is hardcoded in) 26 | ;;Bad Playername Strings = (:):{:} 27 | ;;Bad Playername Regex_1 = [:alnum:] 28 | ;;Bad Playername Regex_2 = [:alnum:] 29 | ;;Bad Playername Regex_3 = [:alnum:] 30 | 31 | 32 | ;; Whitelisting / Reserve Slots 33 | ;; This will only work if your mission / mod has started extDB2 Rcon. i.e 9:START_RCON:RCON 34 | Whitelist Enable = false 35 | Whitelist Kick Message = Only Reserved Slots Left 36 | 37 | Whitelist Public Slots = 999 38 | 39 | ;; Database settings to use (Optional) 40 | Whitelist Database = MySQL_Example 41 | Whitelist SQL Prepared Statement = SELECT CASE WHEN EXISTS(SELECT UID FROM PlayerInfo WHERE BattlEyeGUID=? AND Whitelisted=1) THEN 1 ELSE 0 END 42 | Whitelist Kick on SQL Query Failed = false 43 | 44 | ;; Hardcoded BEGuids for whitelisted players 45 | ;Whitelist BEGuids = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx : yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy 46 | 47 | 48 | [Steam] 49 | ;; This is for VAC Protocol for VAC Bans + Steam Friends. 50 | ;; https://steamcommunity.com/dev/apikey 51 | API Key = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 52 | 53 | 54 | [VAC] 55 | ;; This feature requires Steam + Rcon to be enabled. 56 | ;; Also this feature is called via SQF Code atm, i.e it doesn't auto detect players joining server yet.... 57 | Auto Ban = true 58 | 59 | ;; For Player to get banned ( their total VAC Bans => NumberOfVACBans) AND ( Days Since their Last Ban was <= DaysSinceLastBan) 60 | ;; This is also used extDB Protocol VAC:VACBanned returned results 61 | 62 | NumberOfVACBans = 1 63 | DaysSinceLastBan = 999999999 64 | BanDuration = 0 65 | ;; 0 = Forever, otherwise its x Minutes 66 | BanMessage = Steam VAC Banned 67 | 68 | 69 | [Log] 70 | ;; Flush Logs after each write, more work on Harddrive 71 | Flush = true 72 | 73 | 74 | [MySQL_Example] 75 | Type = MySQL 76 | Name = Database_Name 77 | 78 | Username = root 79 | Password = password 80 | 81 | IP = 127.0.0.1 82 | Port = 3306 83 | 84 | ;minSessions = 2 85 | idleTime = 60 86 | 87 | compress = false 88 | ; Really should only use this if MySQL server is external. Also only for MySQL 89 | 90 | Secure Auth = true 91 | ; Recommend you turn this on http://dev.mysql.com/doc/refman/5.6/en/mysql-command-options.html#option_mysql_secure-auth 92 | 93 | 94 | [SQLite_Example] 95 | Type = SQLite 96 | Name = sqlite.db 97 | 98 | minSessions = 1 99 | ; minSession Default Value = 1 100 | 101 | ;maxSessions = 4 102 | ; maxSession Default Value = number of Main->Threads 103 | ; You really should leave this value alone 104 | idleTime = 60 105 | ; idleTime no Default Value yet, needs to be defined. 106 | ; idleTime is the time before a database session is stopped if not used. 107 | ; If Database Sessions are greater than minSessions -------------------------------------------------------------------------------- /src/spdlog/sinks/dist_sink.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2015 David Schury. */ 4 | /* Copyright (c) 2014 Gabi Melman. */ 5 | /* */ 6 | /* Permission is hereby granted, free of charge, to any person obtaining */ 7 | /* a copy of this software and associated documentation files (the */ 8 | /* "Software"), to deal in the Software without restriction, including */ 9 | /* without limitation the rights to use, copy, modify, merge, publish, */ 10 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 11 | /* permit persons to whom the Software is furnished to do so, subject to */ 12 | /* the following conditions: */ 13 | /* */ 14 | /* The above copyright notice and this permission notice shall be */ 15 | /* included in all copies or substantial portions of the Software. */ 16 | /* */ 17 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 18 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 19 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 20 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 21 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 22 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 23 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 24 | /*************************************************************************/ 25 | 26 | #pragma once 27 | 28 | #include 29 | #include 30 | #include 31 | #include 32 | 33 | #include "../details/log_msg.h" 34 | #include "../details/null_mutex.h" 35 | #include "./base_sink.h" 36 | #include "./sink.h" 37 | 38 | namespace spdlog 39 | { 40 | namespace sinks 41 | { 42 | template 43 | class dist_sink: public base_sink 44 | { 45 | public: 46 | explicit dist_sink() :_sinks() {} 47 | dist_sink(const dist_sink&) = delete; 48 | dist_sink& operator=(const dist_sink&) = delete; 49 | virtual ~dist_sink() = default; 50 | 51 | protected: 52 | void _sink_it(const details::log_msg& msg) override 53 | { 54 | for (auto iter = _sinks.begin(); iter != _sinks.end(); iter++) 55 | (*iter)->log(msg); 56 | } 57 | 58 | std::vector> _sinks; 59 | 60 | public: 61 | void flush() override 62 | { 63 | std::lock_guard lock(base_sink::_mutex); 64 | for (auto iter = _sinks.begin(); iter != _sinks.end(); iter++) 65 | (*iter)->flush(); 66 | } 67 | 68 | void add_sink(std::shared_ptr sink) 69 | { 70 | std::lock_guard lock(base_sink::_mutex); 71 | if (sink && 72 | _sinks.end() == std::find(_sinks.begin(), _sinks.end(), sink)) 73 | { 74 | _sinks.push_back(sink); 75 | } 76 | } 77 | 78 | void remove_sink(std::shared_ptr sink) 79 | { 80 | std::lock_guard lock(base_sink::_mutex); 81 | auto pos = std::find(_sinks.begin(), _sinks.end(), sink); 82 | if (pos != _sinks.end()) 83 | { 84 | _sinks.erase(pos); 85 | } 86 | } 87 | }; 88 | 89 | typedef dist_sink dist_sink_mt; 90 | typedef dist_sink dist_sink_st; 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /src/spdlog/details/log_msg.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | #include 28 | #include "../common.h" 29 | #include "./format.h" 30 | 31 | namespace spdlog 32 | { 33 | namespace details 34 | { 35 | struct log_msg 36 | { 37 | log_msg() = default; 38 | log_msg(level::level_enum l): 39 | logger_name(), 40 | level(l), 41 | raw(), 42 | formatted() {} 43 | 44 | 45 | log_msg(const log_msg& other) : 46 | logger_name(other.logger_name), 47 | level(other.level), 48 | time(other.time), 49 | thread_id(other.thread_id) 50 | { 51 | if (other.raw.size()) 52 | raw << fmt::BasicStringRef(other.raw.data(), other.raw.size()); 53 | if (other.formatted.size()) 54 | formatted << fmt::BasicStringRef(other.formatted.data(), other.formatted.size()); 55 | } 56 | 57 | log_msg(log_msg&& other) : 58 | logger_name(std::move(other.logger_name)), 59 | level(other.level), 60 | time(std::move(other.time)), 61 | thread_id(other.thread_id), 62 | raw(std::move(other.raw)), 63 | formatted(std::move(other.formatted)) 64 | { 65 | other.clear(); 66 | } 67 | 68 | log_msg& operator=(log_msg&& other) 69 | { 70 | if (this == &other) 71 | return *this; 72 | 73 | logger_name = std::move(other.logger_name); 74 | level = other.level; 75 | time = std::move(other.time); 76 | thread_id = other.thread_id; 77 | raw = std::move(other.raw); 78 | formatted = std::move(other.formatted); 79 | other.clear(); 80 | return *this; 81 | } 82 | 83 | void clear() 84 | { 85 | level = level::off; 86 | raw.clear(); 87 | formatted.clear(); 88 | } 89 | 90 | std::string logger_name; 91 | level::level_enum level; 92 | log_clock::time_point time; 93 | size_t thread_id; 94 | fmt::MemoryWriter raw; 95 | fmt::MemoryWriter formatted; 96 | }; 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/sanitize.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | Copyright (C) 2009-2012 Rajko Stojadinovic 4 | 5 | 6 | This program is free software: you can redistribute it and/or modify 7 | it under the terms of the GNU General Public License as published by 8 | the Free Software Foundation, either version 3 of the License, or 9 | (at your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, 12 | but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | GNU General Public License for more details. 15 | 16 | You should have received a copy of the GNU General Public License 17 | along with this program. If not, see . 18 | */ 19 | 20 | 21 | #include "sanitize.h" 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | 29 | 30 | template 31 | struct SqfValueParser : boost::spirit::qi::grammar 32 | { 33 | SqfValueParser() : SqfValueParser::base_type(start,"Sqf::Value") 34 | { 35 | quoted_string = boost::spirit::qi::lexeme['"' >> *(boost::spirit::ascii::char_ - '"') >> '"'] | boost::spirit::qi::lexeme["'" >> *(boost::spirit::ascii::char_ - "'") >> "'"]; 36 | quoted_string.name("quoted_string"); 37 | 38 | start = strict_double | 39 | (boost::spirit::qi::int_ >> !boost::spirit::qi::digit) | 40 | boost::spirit::qi::long_long | 41 | boost::spirit::qi::bool_ | 42 | quoted_string | 43 | (boost::spirit::qi::lit("any") >> boost::spirit::qi::attr(static_cast(nullptr))) | 44 | (boost::spirit::qi::lit("[") >> -(start % ",") >> boost::spirit::qi::lit("]")); 45 | } 46 | 47 | boost::spirit::qi::rule quoted_string; 48 | boost::spirit::qi::real_parser< double, boost::spirit::qi::strict_real_policies > strict_double; 49 | boost::spirit::qi::rule start; 50 | }; 51 | 52 | template 53 | struct SqfParametersParser : boost::spirit::qi::grammar 54 | { 55 | SqfParametersParser() : SqfParametersParser::base_type(start,"Sqf::Parameters") 56 | { 57 | val_parser.name("one_value"); 58 | start = *(val_parser); 59 | } 60 | 61 | SqfValueParser val_parser; 62 | boost::spirit::qi::rule one_value; 63 | boost::spirit::qi::rule start; 64 | }; 65 | 66 | namespace Sqf 67 | { 68 | bool check(std::string input_str) 69 | { 70 | std::string::iterator first = input_str.begin(); 71 | std::string::iterator last = input_str.end(); 72 | 73 | bool r = boost::spirit::qi::phrase_parse( 74 | first, 75 | last, 76 | SqfParametersParser(), 77 | boost::spirit::qi::space_type() 78 | ); 79 | if (first != last) // fail if we did not get a full match 80 | { 81 | return false; 82 | } 83 | else 84 | { 85 | return r; 86 | } 87 | }; 88 | } 89 | 90 | #ifdef SANITIZE_APP 91 | int main(int nNumberofArgs, char* pszArgs[]) 92 | { 93 | std::string input_str; 94 | for (;;) { 95 | std::getline(std::cin, input_str); 96 | if (input_str == "quit") 97 | { 98 | break; 99 | } 100 | else 101 | { 102 | if (Sqf::check(input_str)) 103 | { 104 | std::cout << "extDB: Sanitize Check True: " << input_str << std::endl; 105 | } 106 | else 107 | { 108 | std::cout << "extDB: Sanitize Check False: " << input_str << std::endl; 109 | } 110 | } 111 | } 112 | return 0; 113 | } 114 | #endif -------------------------------------------------------------------------------- /src/backends/steam.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | #include "Poco/Dynamic/Var.h" 26 | #include "Poco/JSON/Parser.h" 27 | 28 | #include 29 | #include 30 | 31 | #include 32 | #include 33 | #include 34 | 35 | #include 36 | 37 | #include "../abstract_ext.h" 38 | 39 | 40 | class SteamGet: public Poco::Runnable 41 | { 42 | public: 43 | void init(AbstractExt *extension); 44 | 45 | void run(); 46 | void stop(); 47 | 48 | void abort(); 49 | 50 | void update(std::string &update_path, Poco::Dynamic::Var &var); 51 | int getResponse(); 52 | 53 | private: 54 | AbstractExt *extension_ptr; 55 | 56 | std::string path; 57 | std::string steam_api_key; 58 | 59 | std::unique_ptr session; 60 | 61 | Poco::Dynamic::Var *json; 62 | Poco::JSON::Parser parser; 63 | 64 | int response=-1; 65 | }; 66 | 67 | 68 | class Steam: public Poco::Runnable 69 | { 70 | public: 71 | void run(); 72 | void stop(); 73 | 74 | void init(AbstractExt *extension, std::string &extension_path, Poco::DateTime ¤t_dateTime); 75 | void initBanslogger(); 76 | void addQuery(const unsigned int &unique_id, bool queryFriends, bool queryVacBans, std::vector &steamIDs); 77 | 78 | private: 79 | AbstractExt *extension_ptr; 80 | 81 | struct SteamVACBans 82 | { 83 | int NumberOfVACBans; 84 | int DaysSinceLastBan; 85 | std::string steamID; 86 | 87 | bool extDBBanned=false; 88 | bool VACBanned; 89 | }; 90 | 91 | struct SteamFriends 92 | { 93 | std::string steamID; 94 | std::vector friends; 95 | }; 96 | 97 | struct SteamQuery 98 | { 99 | unsigned long unique_id; 100 | std::vector steamIDs; 101 | 102 | bool queryFriends; 103 | bool queryVACBans; 104 | }; 105 | 106 | struct RConBan 107 | { 108 | int NumberOfVACBans; 109 | int DaysSinceLastBan; 110 | std::string BanDuration; 111 | std::string BanMessage; 112 | bool autoBan; 113 | }; 114 | 115 | std::vector query_queue; 116 | std::mutex mutex_query_queue; 117 | 118 | std::string STEAM_api_key; 119 | RConBan rconBanSettings; 120 | std::unique_ptr > SteamVacBans_Cache; // 1 Hour (3600000) 121 | std::unique_ptr > SteamFriends_Cache; // 1 Hour (3600000) 122 | 123 | void updateSteamBans(std::vector &steamIDs); 124 | void updateSteamFriends(std::vector &steamIDs); 125 | std::string convertSteamIDtoBEGUID(const std::string &input_str); 126 | std::vector generateSteamIDStrings(std::vector &steamIDs); 127 | 128 | Poco::MD5Engine md5; 129 | std::mutex mutex_md5; 130 | 131 | std::atomic *steam_run_flag; 132 | 133 | SteamGet steam_get; 134 | 135 | std::string log_filename; 136 | }; 137 | -------------------------------------------------------------------------------- /Changelog SQL_CUSTOM.txt: -------------------------------------------------------------------------------- 1 | SQL_CUSTOM Major Changes 2 | This just lists info on changes when SQL_CUSTOM version is bumped. 3 | Looking for more info on SQL_CUSTOM check out https://github.com/Torndeco/extDB2/wiki/Calls:-Protocol--SQL_CUSTOM 4 | 5 | Versions 6 | --------------------------------------------------------------------------------------------------- 7 | 11->12 8 | Added: SQL_CUSTOM + SQL_CUSTOM_V2 Seperator Character (Base10) Option 9 | Allows you define the seperator character for entire SQL_CUSTOM Protocol or callnames 10 | Value for Option is in Base10 i.e 58 = : 11 | 12 | --------------------------------------------------------------------------------------------------- 13 | 10->11 14 | Added: Player_Key 15 | Example of use 16 | 9:START_RCON:PLAYERKEY 17 | 18 | [getPlayerBankMoney] 19 | SQL1_1 = SELECT BankMoney FROM PlayerInfo WHERE UID = ?; 20 | 21 | Number of Inputs = 1 22 | SQL1_INPUTS = 1-PlayerKey 23 | Return Player Key = true 24 | 25 | Example of returned result = [1,["QWIOEJQWSAD",[2000]]] 26 | 27 | Ok time to explain what PlayerKey is.... 28 | 29 | To start with it requires extDB2 to be connected to server via Rcon and using the option PLAYERKEY. 30 | When a player connects to Rcon they are automatically given a unique randomized PlayerKey. 31 | When the player disconnects the PlayerKey is removed (read note below) 32 | 33 | By saying 1-PlayerKey we are telling SQL_CUSTOM to use Input Value 1 + return the unique player key for that player. 34 | The input value can either be PlayerUID or BEGuid, makes no difference. 35 | You can also use InsertID at the same time, the format for that is [1,[,[,]]] 36 | 37 | If there is an error, for example extDB2 isn't connected to the server via Rcon. 38 | The returned PlayerKey is an empty string. 39 | 40 | 41 | Why ? 42 | This will allow you to offload randomized player value to the extension. 43 | But the main reason it will be integerated feature to extDB2 upcoming BELogscanner. 44 | You will be able to make regex rules to ban/kick players for entries in BattlEye that don't have the correct playerkey. 45 | It will be possible to enable adding/removing playerkeys manually, but it will require extra callExtensions + will be less secure. 46 | 47 | The BELogscanner feature is heavily based of my old pyBEscanner, if anyone remembers it. 48 | 49 | 50 | --------------------------------------------------------------------------------------------------- 51 | 9->10 52 | Added: String_Escape_Quotes 53 | Escapes " -> "" , ' -> '' 54 | Added " to either end of string 55 | Example aaa'bbb"dsadsd" -> "aaa''bbb""dsadsd""" so it will call compile correctly 56 | Useful for when storing + retreiving playernames from Database 57 | 58 | Added: Check_Add_Quotes (Input Only Option) 59 | This just adds "" before running a sanitize check. 60 | Useful for when storing a string in database + you like to a check it, but you don't wont to store quotes wrapping the string. 61 | 62 | Added: Check_Add_Escape_Quotes (Input Only Option) 63 | This will escape the quotations (just like String_Escape_Quotes) before running a sanitize check. 64 | Useful for when storing strings in raw form and are retrieving via String_Escape_Quotes later on. e.g playernames 65 | 66 | Added: DateTime_ISO8601 (Output Only Option) 67 | Used to convert ISO8601 Format i.e "2015-05-13T20:16:24Z" to arma array [Year,Month,Day,Hour,Minute,Second] or [] for Null Entry 68 | 69 | 70 | Removed Vac_BeGUID Why the hell did i think you could query Steam Servers with BEGuid 71 | 72 | 73 | --------------------------------------------------------------------------------------------------- 74 | 8->9 75 | Change "Strip Custom Input Chars" -> "Strip Custom Chars" 76 | Not a Typo, only afew people will have "Strip Custom Input Chars", most should already be using "Strip Custom Chars". -------------------------------------------------------------------------------- /src/spdlog/common.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | #include 28 | #include 29 | #include 30 | #include 31 | 32 | //visual studio does not support noexcept yet 33 | #ifndef _MSC_VER 34 | #define SPDLOG_NOEXCEPT noexcept 35 | #else 36 | #define SPDLOG_NOEXCEPT throw() 37 | #endif 38 | 39 | 40 | namespace spdlog 41 | { 42 | 43 | class formatter; 44 | 45 | namespace sinks 46 | { 47 | class sink; 48 | } 49 | 50 | // Common types across the lib 51 | using log_clock = std::chrono::system_clock; 52 | using sink_ptr = std::shared_ptr < sinks::sink >; 53 | using sinks_init_list = std::initializer_list < sink_ptr >; 54 | using formatter_ptr = std::shared_ptr; 55 | 56 | 57 | //Log level enum 58 | namespace level 59 | { 60 | typedef enum 61 | { 62 | trace = 0, 63 | debug = 1, 64 | info = 2, 65 | notice = 3, 66 | warn = 4, 67 | err = 5, 68 | critical = 6, 69 | alert = 7, 70 | emerg = 8, 71 | off = 9 72 | } level_enum; 73 | 74 | static const char* level_names[] { "trace", "debug", "info", "notice", "warning", "error", "critical", "alert", "emerg", "off"}; 75 | 76 | static const char* short_level_names[] { "T", "D", "I", "N", "W", "E", "C", "A", "M", "O"}; 77 | 78 | inline const char* to_str(spdlog::level::level_enum l) 79 | { 80 | return level_names[l]; 81 | } 82 | 83 | inline const char* to_short_str(spdlog::level::level_enum l) 84 | { 85 | return short_level_names[l]; 86 | } 87 | } //level 88 | 89 | 90 | // 91 | // Async overflow policy - block by default. 92 | // 93 | enum class async_overflow_policy 94 | { 95 | block_retry, // Block / yield / sleep until message can be enqueued 96 | discard_log_msg // Discard the message it enqueue fails 97 | }; 98 | 99 | 100 | // 101 | // Log exception 102 | // 103 | class spdlog_ex : public std::exception 104 | { 105 | public: 106 | spdlog_ex(const std::string& msg) :_msg(msg) {} 107 | const char* what() const SPDLOG_NOEXCEPT override 108 | { 109 | return _msg.c_str(); 110 | } 111 | private: 112 | std::string _msg; 113 | 114 | }; 115 | 116 | } //spdlog -------------------------------------------------------------------------------- /src/protocols/rcon.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #include "rcon.h" 20 | 21 | #include 22 | 23 | #include 24 | 25 | 26 | bool RCON::init(AbstractExt *extension, const std::string &database_id, const std::string &init_str) 27 | { 28 | extension_ptr = extension; 29 | 30 | if (!init_str.empty()) 31 | { 32 | Poco::StringTokenizer tokens(init_str, "-"); 33 | allowed_commands.insert(allowed_commands.begin(), tokens.begin(), tokens.end()); 34 | #ifdef DEBUG_TESTING 35 | extension_ptr->console->warn("extDB2: RCON: Commands Allowed: {0}", init_str); 36 | extension_ptr->console->warn("extDB2: RCON Status: {0}", extension_ptr->ext_connectors_info.rcon); 37 | #endif 38 | extension_ptr->logger->warn("extDB2: RCON: Commands Allowed: {0}", init_str); 39 | extension_ptr->logger->warn("extDB2: RCON Status: {0}", extension_ptr->ext_connectors_info.rcon); 40 | } 41 | return extension_ptr->ext_connectors_info.rcon; 42 | } 43 | 44 | 45 | void RCON::processCommand(std::string &command, std::string &input_str, const unsigned int unique_id, std::string &result) 46 | { 47 | if (boost::algorithm::iequals(command, std::string("players")) == 1) 48 | { 49 | extension_ptr->rconPlayers(unique_id); 50 | } 51 | else if (boost::algorithm::iequals(command, std::string("missions")) == 1) 52 | { 53 | extension_ptr->rconMissions(unique_id); 54 | } 55 | else if (boost::algorithm::iequals(command, std::string("addBan")) == 1) 56 | { 57 | extension_ptr->rconAddBan(input_str); 58 | result = "[1]"; 59 | } 60 | else if (boost::algorithm::iequals(command, std::string("ban")) == 1) 61 | { 62 | extension_ptr->rconAddBan(input_str); 63 | result = "[1]"; 64 | } 65 | else 66 | { 67 | extension_ptr->rconCommand(input_str); 68 | result = "[1]"; 69 | } 70 | } 71 | 72 | 73 | bool RCON::callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id) 74 | { 75 | #ifdef DEBUG_TESTING 76 | extension_ptr->console->info("extDB2: RCON: Trace: Input: {0}", input_str); 77 | #endif 78 | #ifdef DEBUG_LOGGING 79 | extension_ptr->logger->info("extDB2: RCON: Trace: Input: {0}", input_str); 80 | #endif 81 | 82 | boost::trim(input_str); 83 | 84 | if (allowed_commands.size() > 0) 85 | { 86 | std::string command; 87 | const std::string::size_type found = input_str.find(" "); 88 | if (found==std::string::npos) 89 | { 90 | command = input_str; 91 | } 92 | else 93 | { 94 | command = input_str.substr(0, found-1); 95 | } 96 | 97 | if (std::find(allowed_commands.begin(), allowed_commands.end(), command) == allowed_commands.end()) 98 | { 99 | result ="[0,\"RCon Command Not Allowed\"]"; 100 | #ifdef DEBUG_TESTING 101 | extension_ptr->console->warn("extDB2: RCON: Command Not Allowed: Input: {0}", input_str); 102 | #endif 103 | extension_ptr->logger->warn("extDB2: RCON: Command Not Allowed: Input: {0}", input_str); 104 | } 105 | else 106 | { 107 | processCommand(command, input_str, unique_id, result); 108 | } 109 | } 110 | else 111 | { 112 | processCommand(input_str, input_str, unique_id, result); 113 | } 114 | 115 | return (!result.empty()); // If result is empty due to error, save error message 116 | } -------------------------------------------------------------------------------- /src/spdlog/details/async_logger_impl.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | 28 | #include "./async_log_helper.h" 29 | 30 | // 31 | // Async Logger implementation 32 | // Use single async_sink (queue) to perform the logging in a worker thread 33 | // 34 | 35 | 36 | template 37 | inline spdlog::async_logger::async_logger(const std::string& logger_name, 38 | const It& begin, 39 | const It& end, 40 | size_t queue_size, 41 | const async_overflow_policy overflow_policy, 42 | const std::function& worker_warmup_cb, 43 | const std::chrono::milliseconds& flush_interval_ms) : 44 | logger(logger_name, begin, end), 45 | _async_log_helper(new details::async_log_helper(_formatter, _sinks, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms)) 46 | { 47 | } 48 | 49 | inline spdlog::async_logger::async_logger(const std::string& logger_name, 50 | sinks_init_list sinks, 51 | size_t queue_size, 52 | const async_overflow_policy overflow_policy, 53 | const std::function& worker_warmup_cb, 54 | const std::chrono::milliseconds& flush_interval_ms) : 55 | async_logger(logger_name, sinks.begin(), sinks.end(), queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms) {} 56 | 57 | inline spdlog::async_logger::async_logger(const std::string& logger_name, 58 | sink_ptr single_sink, 59 | size_t queue_size, 60 | const async_overflow_policy overflow_policy, 61 | const std::function& worker_warmup_cb, 62 | const std::chrono::milliseconds& flush_interval_ms) : 63 | async_logger(logger_name, { single_sink }, queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms) {} 64 | 65 | 66 | inline void spdlog::async_logger::_set_formatter(spdlog::formatter_ptr msg_formatter) 67 | { 68 | _formatter = msg_formatter; 69 | _async_log_helper->set_formatter(_formatter); 70 | } 71 | 72 | inline void spdlog::async_logger::_set_pattern(const std::string& pattern) 73 | { 74 | _formatter = std::make_shared(pattern); 75 | _async_log_helper->set_formatter(_formatter); 76 | } 77 | 78 | 79 | inline void spdlog::async_logger::_log_msg(details::log_msg& msg) 80 | { 81 | _async_log_helper->log(msg); 82 | } 83 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include "ext.h" 2 | 3 | #include 4 | #include 5 | 6 | 7 | Ext *extension; 8 | 9 | 10 | #ifdef __GNUC__ 11 | #include 12 | // Code for GNU C compiler 13 | static void __attribute__((constructor)) 14 | extension_init(void) 15 | { 16 | //je_init(); 17 | std::unordered_map options; 18 | 19 | FILE *fh = fopen ("/proc/self/cmdline", "r"); // /proc/self :D 20 | if (fh != NULL) 21 | { 22 | char *arg = 0; 23 | size_t size = 0; 24 | while(getdelim(&arg, &size, 0, fh) != -1) 25 | { 26 | std::string argument_str(arg); 27 | boost::erase_all(argument_str, "\""); 28 | if (boost::algorithm::istarts_with(argument_str, "-extDB2_VAR=")) 29 | { 30 | options["VAR"] = argument_str.substr(argument_str.find("=") + 1); 31 | } 32 | else if (boost::algorithm::istarts_with(argument_str, "-extDB2_WORK=")) 33 | { 34 | options["WORK"] = argument_str.substr(argument_str.find("=") + 1); 35 | } 36 | else if (boost::algorithm::istarts_with(argument_str, "-bepath=")) 37 | { 38 | options["BEPATH"] = argument_str.substr(argument_str.find("=") + 1); 39 | } 40 | } 41 | free(arg); 42 | }; 43 | fclose(fh); 44 | 45 | Dl_info dl_info; 46 | dladdr((void*)extension_init, &dl_info); 47 | extension = new Ext(boost::filesystem::path (dl_info.dli_fname).string(), options); 48 | } 49 | 50 | static void __attribute__((destructor)) 51 | extension_destroy(void) 52 | { 53 | extension->stop(); 54 | //je_uninit(); 55 | } 56 | 57 | extern "C" 58 | { 59 | void RVExtension(char *output, int outputSize, const char *function); 60 | }; 61 | 62 | void RVExtension(char *output, int outputSize, const char *function) 63 | { 64 | outputSize -= 1; 65 | extension->callExtension(output, outputSize, function); 66 | }; 67 | 68 | 69 | #elif _MSC_VER 70 | // Code for MSVC compiler 71 | //#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Now Defined VIA CMake Build System 72 | 73 | #include 74 | #include 75 | #include 76 | 77 | EXTERN_C IMAGE_DOS_HEADER __ImageBase; 78 | 79 | BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) 80 | { 81 | switch (ul_reason_for_call) 82 | { 83 | case DLL_PROCESS_ATTACH: 84 | { 85 | int nArgs; 86 | LPWSTR *pszArgsW = CommandLineToArgvW(GetCommandLineW(), &nArgs); 87 | std::unordered_map options; 88 | 89 | if (nArgs != NULL) 90 | { 91 | std::string argument_str; 92 | for (int i = 0; i < nArgs; i++) 93 | { 94 | argument_str = CW2A(pszArgsW[i]); 95 | boost::erase_all(argument_str, "\""); 96 | if (boost::algorithm::istarts_with(argument_str, "-extDB2_VAR=")) 97 | { 98 | options["VAR"] = argument_str.substr(argument_str.find("=") + 1); 99 | } 100 | else if (boost::algorithm::istarts_with(argument_str, "-extDB2_WORK=")) 101 | { 102 | options["WORK"] = argument_str.substr(argument_str.find("=") + 1); 103 | } 104 | else if (boost::algorithm::istarts_with(argument_str, "-bepath=")) 105 | { 106 | options["BEPATH"] = argument_str.substr(argument_str.find("=") + 1); 107 | } 108 | } 109 | } 110 | 111 | WCHAR path[MAX_PATH + 1]; 112 | GetModuleFileNameW((HINSTANCE)&__ImageBase, path, (MAX_PATH + 1)); 113 | extension = new Ext(boost::filesystem::path(path).string(), options); 114 | } 115 | break; 116 | case DLL_PROCESS_DETACH: 117 | extension->stop(); 118 | break; 119 | } 120 | return true; 121 | } 122 | 123 | extern "C" 124 | { 125 | __declspec(dllexport) void __stdcall RVExtension(char *output, int outputSize, const char *function); 126 | }; 127 | 128 | void __stdcall RVExtension(char *output, int outputSize, const char *function) 129 | { 130 | outputSize -= 1; 131 | extension->callExtension(output, outputSize, function); 132 | }; 133 | #endif 134 | -------------------------------------------------------------------------------- /src/abstract_ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | 28 | #include "spdlog/spdlog.h" 29 | 30 | 31 | #define EXTDB_VERSION "71" 32 | #define EXTDB_CONF_VERSION 5 33 | 34 | 35 | class AbstractExt 36 | { 37 | public: 38 | struct resultData 39 | { 40 | std::string message; 41 | bool wait = true; 42 | }; 43 | 44 | // Database Connection Info 45 | struct DBConnectionInfo 46 | { 47 | std::string type; 48 | 49 | // SQL Database Session Pool 50 | std::unique_ptr sql_pool; 51 | std::mutex mutex_sql_pool; 52 | }; 53 | 54 | // extDB Connectors 55 | struct extConnectors 56 | { 57 | std::unordered_map databases; 58 | 59 | bool mysql = false; 60 | bool sqlite = false; 61 | 62 | bool belog_scanner = false; 63 | bool rcon = false; 64 | bool steam = false; 65 | }; 66 | extConnectors ext_connectors_info; 67 | 68 | // ext Info 69 | struct extInfo 70 | { 71 | std::string var; 72 | std::string path; 73 | std::string be_path; 74 | std::string log_path; 75 | 76 | int max_threads; 77 | bool extDB_lock = false; 78 | bool logger_flush = true; 79 | 80 | }; 81 | extInfo ext_info; 82 | 83 | Poco::AutoPtr pConf; 84 | 85 | #ifdef DEBUG_TESTING 86 | std::shared_ptr console; 87 | #endif 88 | std::shared_ptr logger; 89 | std::shared_ptr vacBans_logger; 90 | 91 | std::mutex player_unique_keys_mutex; 92 | 93 | virtual void saveResult_mutexlock(const unsigned int &unique_id, const resultData &result_data)=0; 94 | virtual void saveResult_mutexlock(std::vector &unique_ids, const resultData &result_data)=0; 95 | 96 | virtual Poco::Data::Session getDBSession_mutexlock(DBConnectionInfo &database)=0; 97 | virtual Poco::Data::Session getDBSession_mutexlock(DBConnectionInfo &database, Poco::Data::SessionPool::SessionDataPtr &session_data_ptr)=0; 98 | 99 | virtual void rconCommand(std::string input_str)=0; 100 | virtual void rconAddBan(std::string input_str) = 0; 101 | virtual void rconPlayers(unsigned int unique_id)=0; 102 | virtual void rconMissions(unsigned int unique_id)=0; 103 | 104 | virtual void steamQuery(const unsigned int &unique_id, bool queryFriends, bool queryVacBans, std::string &steamID, bool wakeup)=0; 105 | virtual void steamQuery(const unsigned int &unique_id, bool queryFriends, bool queryVacBans, std::vector &steamIDs, bool wakeup)=0; 106 | 107 | virtual void getDateTime(const std::string &input_str, std::string &result)=0; 108 | virtual void getUniqueString(int &len_of_string, int &num_of_string, std::string &result)=0; 109 | 110 | virtual void createPlayerKey_mutexlock(std::string &player_beguid, int len_of_key)=0; 111 | virtual void delPlayerKey_delayed(std::string &player_beguid)=0; 112 | 113 | virtual void getPlayerKey_SteamID(std::string &player_steam_id, std::string &player_key)=0; 114 | virtual void getPlayerKey_BEGuid(std::string &player_beguid, std::string &player_key)=0; 115 | virtual std::string getPlayerRegex_BEGuid(std::string &player_beguid)=0; 116 | }; 117 | -------------------------------------------------------------------------------- /src/protocols/steam_v2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | 17 | Code to Convert SteamID -> BEGUID 18 | From Frank https://gist.github.com/Fank/11127158 19 | 20 | */ 21 | 22 | 23 | #include "steam_v2.h" 24 | 25 | #include 26 | 27 | #include 28 | 29 | #include "../backends/steam.h" 30 | 31 | 32 | bool STEAM_V2::init(AbstractExt *extension, const std::string &database_id, const std::string &init_str) 33 | { 34 | extension_ptr = extension; 35 | return true; 36 | } 37 | 38 | 39 | bool STEAM_V2::isNumber(const std::string &input_str) 40 | { 41 | bool status = true; 42 | for (unsigned int index=0; index < input_str.length(); index++) 43 | { 44 | if (!std::isdigit(input_str[index])) 45 | { 46 | status = false; 47 | break; 48 | } 49 | } 50 | return status; 51 | } 52 | 53 | 54 | bool STEAM_V2::callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id) 55 | { 56 | #ifdef DEBUG_TESTING 57 | extension_ptr->console->info("extDB2: STEAM_V2: Trace: Input: {0}", input_str); 58 | #endif 59 | #ifdef DEBUG_LOGGING 60 | extension_ptr->logger->info("extDB2: STEAM_V2: Trace: Input: {0}", input_str); 61 | #endif 62 | 63 | if (!async_method) 64 | { 65 | #ifdef DEBUG_TESTING 66 | extension_ptr->console->warn("extDB2: STEAM_V2: SYNC MODE NOT SUPPORTED"); 67 | #endif 68 | extension_ptr->logger->warn("extDB2: STEAM_V2: SYNC MODE NOT SUPPORTED"); 69 | result = "[0, \"STEAM_V2: SYNC MODE NOT SUPPORTED\"]"; 70 | } 71 | else 72 | { 73 | const std::string::size_type found = input_str.find(":", 0); 74 | if ((found==std::string::npos) || (found == (input_str.size() - 1))) 75 | { 76 | #ifdef DEBUG_TESTING 77 | extension_ptr->console->warn("extDB2: STEAM_V2: Invalid Query: {0}", input_str); 78 | #endif 79 | extension_ptr->logger->warn("extDB2: STEAM_V2: Invalid Query: {0}", input_str); 80 | } 81 | else 82 | { 83 | Poco::StringTokenizer tokens(input_str.substr(found+1), ":"); 84 | std::vector steamIDs; 85 | bool status = true; 86 | for (auto &token : tokens) 87 | { 88 | if (isNumber(token)) 89 | { 90 | steamIDs.push_back(token); 91 | } 92 | else 93 | { 94 | #ifdef DEBUG_TESTING 95 | extension_ptr->console->warn("extDB2: STEAM_V2: Invalid SteamID: {0}", token); 96 | #endif 97 | extension_ptr->logger->warn("extDB2: STEAM_V2: Invalid SteamID: {0}", token); 98 | result = "[0, \"STEAM_V2: Invalid SteamID\"]"; 99 | status = false; 100 | break; 101 | } 102 | } 103 | 104 | if (status) 105 | { 106 | std::string steam_query = input_str.substr(0, found); 107 | if (steam_query == "GET_FRIENDS") 108 | { 109 | extension_ptr->steamQuery(unique_id, true, false, steamIDs, true); 110 | } 111 | else if (steam_query == "VAC_BANNED") 112 | { 113 | extension_ptr->steamQuery(unique_id, false, true, steamIDs, true); 114 | } 115 | else 116 | { 117 | #ifdef DEBUG_TESTING 118 | extension_ptr->console->warn("extDB2: STEAM_V2: Invalid Query Type: {0}", steam_query); 119 | #endif 120 | extension_ptr->logger->warn("extDB2: STEAM_V2: Invalid Query Type: {0}", steam_query); 121 | result = "[0, \"STEAM_V2: Invalid Query Type\"]"; 122 | } 123 | } 124 | } 125 | } 126 | return (!result.empty()); // If result is empty due to error, save error message 127 | } -------------------------------------------------------------------------------- /src/spdlog/sinks/android_sink.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* Copyright (c) 2015 Ruslan Baratov. */ 5 | /* */ 6 | /* Permission is hereby granted, free of charge, to any person obtaining */ 7 | /* a copy of this software and associated documentation files (the */ 8 | /* "Software"), to deal in the Software without restriction, including */ 9 | /* without limitation the rights to use, copy, modify, merge, publish, */ 10 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 11 | /* permit persons to whom the Software is furnished to do so, subject to */ 12 | /* the following conditions: */ 13 | /* */ 14 | /* The above copyright notice and this permission notice shall be */ 15 | /* included in all copies or substantial portions of the Software. */ 16 | /* */ 17 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 18 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 19 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 20 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 21 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 22 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 23 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 24 | /*************************************************************************/ 25 | 26 | #pragma once 27 | 28 | #if defined(__ANDROID__) 29 | 30 | #include 31 | #include "base_sink.h" 32 | #include "../details/null_mutex.h" 33 | 34 | #include 35 | 36 | namespace spdlog 37 | { 38 | namespace sinks 39 | { 40 | /* 41 | * Android sink (logging using __android_log_write) 42 | */ 43 | template 44 | class base_android_sink : public base_sink < Mutex > 45 | { 46 | public: 47 | explicit base_android_sink(std::string tag="spdlog"): _tag(tag) 48 | { 49 | } 50 | 51 | void flush() override 52 | { 53 | } 54 | 55 | protected: 56 | void _sink_it(const details::log_msg& msg) override 57 | { 58 | const android_LogPriority priority = convert_to_android(msg.level); 59 | const int expected_size = msg.formatted.size(); 60 | const int size = __android_log_write( 61 | priority, _tag.c_str(), msg.formatted.c_str() 62 | ); 63 | if (size > expected_size) 64 | { 65 | // Will write a little bit more than original message 66 | } 67 | else 68 | { 69 | throw spdlog_ex("Send to Android logcat failed"); 70 | } 71 | } 72 | 73 | private: 74 | static android_LogPriority convert_to_android(spdlog::level::level_enum level) 75 | { 76 | switch(level) 77 | { 78 | case spdlog::level::trace: return ANDROID_LOG_VERBOSE; 79 | case spdlog::level::debug: return ANDROID_LOG_DEBUG; 80 | case spdlog::level::info: return ANDROID_LOG_INFO; 81 | case spdlog::level::notice: return ANDROID_LOG_INFO; 82 | case spdlog::level::warn: return ANDROID_LOG_WARN; 83 | case spdlog::level::err: return ANDROID_LOG_ERROR; 84 | case spdlog::level::critical: return ANDROID_LOG_FATAL; 85 | case spdlog::level::alert: return ANDROID_LOG_FATAL; 86 | case spdlog::level::emerg: return ANDROID_LOG_FATAL; 87 | default: throw spdlog_ex("Incorrect level value"); 88 | } 89 | } 90 | 91 | std::string _tag; 92 | }; 93 | 94 | typedef base_android_sink android_sink_mt; 95 | typedef base_android_sink android_sink_st; 96 | 97 | } 98 | } 99 | 100 | #endif 101 | -------------------------------------------------------------------------------- /src/spdlog/sinks/syslog_sink.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | #ifdef __linux__ 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include "./sink.h" 34 | #include "../common.h" 35 | #include "../details/log_msg.h" 36 | 37 | 38 | namespace spdlog 39 | { 40 | namespace sinks 41 | { 42 | /** 43 | * Sink that write to syslog using the `syscall()` library call. 44 | * 45 | * Locking is not needed, as `syslog()` itself is thread-safe. 46 | */ 47 | class syslog_sink : public sink 48 | { 49 | public: 50 | // 51 | syslog_sink(const std::string& ident = "", int syslog_option=0, int syslog_facility=LOG_USER): 52 | _ident(ident) 53 | { 54 | _priorities[static_cast(level::trace)] = LOG_DEBUG; 55 | _priorities[static_cast(level::debug)] = LOG_DEBUG; 56 | _priorities[static_cast(level::info)] = LOG_INFO; 57 | _priorities[static_cast(level::notice)] = LOG_NOTICE; 58 | _priorities[static_cast(level::warn)] = LOG_WARNING; 59 | _priorities[static_cast(level::err)] = LOG_ERR; 60 | _priorities[static_cast(level::critical)] = LOG_CRIT; 61 | _priorities[static_cast(level::alert)] = LOG_ALERT; 62 | _priorities[static_cast(level::emerg)] = LOG_EMERG; 63 | _priorities[static_cast(level::off)] = LOG_INFO; 64 | 65 | //set ident to be program name if empty 66 | ::openlog(_ident.empty()? nullptr:_ident.c_str(), syslog_option, syslog_facility); 67 | } 68 | ~syslog_sink() 69 | { 70 | ::closelog(); 71 | } 72 | 73 | syslog_sink(const syslog_sink&) = delete; 74 | syslog_sink& operator=(const syslog_sink&) = delete; 75 | 76 | void log(const details::log_msg &msg) override 77 | { 78 | ::syslog(syslog_prio_from_level(msg), "%s", msg.raw.str().c_str()); 79 | } 80 | 81 | void flush() override 82 | { 83 | } 84 | 85 | 86 | private: 87 | std::array _priorities; 88 | //must store the ident because the man says openlog might use the pointer as is and not a string copy 89 | const std::string _ident; 90 | 91 | // 92 | // Simply maps spdlog's log level to syslog priority level. 93 | // 94 | int syslog_prio_from_level(const details::log_msg &msg) const 95 | { 96 | return _priorities[static_cast(msg.level)]; 97 | } 98 | }; 99 | } 100 | } 101 | 102 | #endif 103 | -------------------------------------------------------------------------------- /src/spdlog/tweakme.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | 26 | #pragma once 27 | 28 | /////////////////////////////////////////////////////////////////////////////// 29 | // Edit this file to squeeze every last drop of performance out of spdlog. 30 | /////////////////////////////////////////////////////////////////////////////// 31 | 32 | 33 | /////////////////////////////////////////////////////////////////////////////// 34 | // Under Linux, the much faster CLOCK_REALTIME_COARSE clock can be used. 35 | // This clock is less accurate - can be off by dozens of millis - depending on the kernel HZ. 36 | // Uncomment to use it instead of the regular (but slower) clock. 37 | #define SPDLOG_CLOCK_COARSE 38 | /////////////////////////////////////////////////////////////////////////////// 39 | 40 | 41 | /////////////////////////////////////////////////////////////////////////////// 42 | // Uncomment if date/time logging is not needed. 43 | // This will prevent spdlog from quering the clock on each log call. 44 | // #define SPDLOG_NO_DATETIME 45 | /////////////////////////////////////////////////////////////////////////////// 46 | 47 | 48 | /////////////////////////////////////////////////////////////////////////////// 49 | // Uncomment if thread id logging is not needed (i.e. no %t in the log pattern). 50 | // This will prevent spdlog from quering the thread id on each log call. 51 | // #define SPDLOG_NO_THREAD_ID 52 | /////////////////////////////////////////////////////////////////////////////// 53 | 54 | 55 | /////////////////////////////////////////////////////////////////////////////// 56 | // Uncomment if logger name logging is not needed. 57 | // This will prevent spdlog from copying the logger name on each log call. 58 | #define SPDLOG_NO_NAME 59 | /////////////////////////////////////////////////////////////////////////////// 60 | 61 | 62 | /////////////////////////////////////////////////////////////////////////////// 63 | // Uncomment to enable the SPDLOG_DEBUG/SPDLOG_TRACE macros. 64 | // #define SPDLOG_DEBUG_ON 65 | // #define SPDLOG_TRACE_ON 66 | /////////////////////////////////////////////////////////////////////////////// 67 | 68 | 69 | /////////////////////////////////////////////////////////////////////////////// 70 | // Uncomment to avoid locking in the registry operations (spdlog::get(), spdlog::drop() spdlog::register()). 71 | // Use only if your code never modifes concurrently the registry. 72 | // Note that upon creating a logger the registry is modified by spdlog.. 73 | // #define SPDLOG_NO_REGISTRY_MUTEX 74 | /////////////////////////////////////////////////////////////////////////////// 75 | -------------------------------------------------------------------------------- /src/spdlog/async_logger.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | // Very fast asynchronous logger (millions of logs per second on an average desktop) 28 | // Uses pre allocated lockfree queue for maximum throughput even under large number of threads. 29 | // Creates a single back thread to pop messages from the queue and log them. 30 | // 31 | // Upon each log write the logger: 32 | // 1. Checks if its log level is enough to log the message 33 | // 2. Push a new copy of the message to a queue (or block the caller until space is available in the queue) 34 | // 3. will throw spdlog_ex upon log exceptions 35 | // Upong destruction, logs all remaining messages in the queue before destructing.. 36 | 37 | #include 38 | #include 39 | #include "common.h" 40 | #include "logger.h" 41 | #include "spdlog.h" 42 | 43 | 44 | namespace spdlog 45 | { 46 | 47 | namespace details 48 | { 49 | class async_log_helper; 50 | } 51 | 52 | class async_logger :public logger 53 | { 54 | public: 55 | template 56 | async_logger(const std::string& name, 57 | const It& begin, 58 | const It& end, 59 | size_t queue_size, 60 | const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, 61 | const std::function& worker_warmup_cb = nullptr, 62 | const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero()); 63 | 64 | async_logger(const std::string& logger_name, 65 | sinks_init_list sinks, 66 | size_t queue_size, 67 | const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, 68 | const std::function& worker_warmup_cb = nullptr, 69 | const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero()); 70 | 71 | async_logger(const std::string& logger_name, 72 | sink_ptr single_sink, 73 | size_t queue_size, 74 | const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, 75 | const std::function& worker_warmup_cb = nullptr, 76 | const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero()); 77 | 78 | 79 | protected: 80 | void _log_msg(details::log_msg& msg) override; 81 | void _set_formatter(spdlog::formatter_ptr msg_formatter) override; 82 | void _set_pattern(const std::string& pattern) override; 83 | 84 | private: 85 | std::unique_ptr _async_log_helper; 86 | }; 87 | } 88 | 89 | 90 | #include "./details/async_logger_impl.h" 91 | -------------------------------------------------------------------------------- /src/backends/belogscanner.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2015 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "../abstract_ext.h" 32 | 33 | 34 | class BELogScanner 35 | { 36 | public: 37 | BELogScanner(); 38 | ~BELogScanner(); 39 | 40 | void start(AbstractExt *extension, boost::asio::io_service &io_service); 41 | void stop(); 42 | 43 | void updateAdd(std::string &steam_id, std::string &value); 44 | void updateRemove(std::string &steam_id, std::string &value); 45 | 46 | protected: 47 | 48 | private: 49 | AbstractExt *extension_ptr; 50 | 51 | Poco::DateTime current_dateTime; 52 | 53 | boost::filesystem::path be_custom_log_path; 54 | boost::filesystem::path filters_path; 55 | 56 | boost::asio::io_service *io_service_ptr; 57 | 58 | std::unique_ptr be_directory_watcher; 59 | std::unique_ptr filters_directory_watcher; 60 | 61 | 62 | struct Filter 63 | { 64 | std::regex regex; 65 | std::string regex_str; 66 | bool dynamic_regex = false; 67 | }; 68 | 69 | struct Spam 70 | { 71 | std::regex regex; 72 | std::string regex_str; 73 | bool dynamic_regex = false; 74 | 75 | int action=0; //0=NONE, 1=KICK, 2=BAN 76 | int count=-1; 77 | int time=-1; 78 | 79 | std::shared_ptr > > cache; 80 | }; 81 | 82 | struct FilterRules 83 | { 84 | std::vector banlist_regex; 85 | std::vector kicklist_regex; 86 | std::vector whitelist_regex; 87 | std::vector spam_rules; 88 | }; 89 | std::unordered_map filters_rules; 90 | 91 | struct LogData 92 | { 93 | //Poco::DateTime date_time; 94 | std::string date_time; 95 | 96 | std::string player_name; 97 | std::string player_guid; 98 | 99 | std::string player_ip; 100 | std::string player_port; 101 | 102 | std::string logged_line; 103 | }; 104 | 105 | struct BELog 106 | { 107 | std::streamoff f_pos; 108 | LogData log_data; 109 | 110 | std::unique_ptr scan_timer; 111 | 112 | std::shared_ptr kick_logger; 113 | std::shared_ptr ban_logger; 114 | std::shared_ptr unknown_logger; 115 | }; 116 | std::unordered_map belogs; 117 | std::mutex belogs_mutex; 118 | 119 | struct AddPlayerKey 120 | { 121 | std::string steam_id; 122 | std::string value; 123 | }; 124 | 125 | struct RemovePlayerKey 126 | { 127 | std::string steam_id; 128 | std::string value; 129 | Poco::Timestamp timestamp; 130 | }; 131 | 132 | Poco::MD5Engine md5; 133 | 134 | 135 | void loadFilters(); 136 | void reloadFilters(const Poco::DirectoryWatcher::DirectoryEvent& event); 137 | 138 | void loadRegexFile(std::string &path_str, std::vector &filters); 139 | void loadSpamFile(std::string &path_str, std::vector &spam_rules); 140 | 141 | void onFileAdded(const Poco::DirectoryWatcher::DirectoryEvent& event); 142 | void onFileRemoved(const Poco::DirectoryWatcher::DirectoryEvent& event); 143 | void onFileModified(const Poco::DirectoryWatcher::DirectoryEvent& event); 144 | void onFileMovedFrom(const Poco::DirectoryWatcher::DirectoryEvent& event); 145 | void onFileMovedTo(const Poco::DirectoryWatcher::DirectoryEvent& event); 146 | 147 | void launchProcess(); 148 | void getBEGUID(std::string &steam_id, std::string &beguid); 149 | 150 | void checkLogData(std::string &filename); 151 | void scanLog(std::string path_str); 152 | void timerScanLog(const size_t delay, std::string &belog_path); 153 | }; -------------------------------------------------------------------------------- /src/spdlog/details/file_helper.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | // Helper class for file sink 28 | // When failing to open a file, retry several times(5) with small delay between the tries(10 ms) 29 | // Can be set to auto flush on every line 30 | // Throw spdlog_ex exception on errors 31 | 32 | #include 33 | #include 34 | #include 35 | #include "os.h" 36 | 37 | 38 | 39 | 40 | namespace spdlog 41 | { 42 | namespace details 43 | { 44 | 45 | class file_helper 46 | { 47 | public: 48 | const int open_tries = 5; 49 | const int open_interval = 10; 50 | 51 | explicit file_helper(bool force_flush) : 52 | _fd(nullptr), 53 | _force_flush(force_flush) 54 | {} 55 | 56 | file_helper(const file_helper&) = delete; 57 | file_helper& operator=(const file_helper&) = delete; 58 | 59 | ~file_helper() 60 | { 61 | close(); 62 | } 63 | 64 | 65 | void open(const std::string& fname, bool truncate = false) 66 | { 67 | 68 | close(); 69 | const char* mode = truncate ? "wb" : "ab"; 70 | _filename = fname; 71 | for (int tries = 0; tries < open_tries; ++tries) 72 | { 73 | if (!os::fopen_s(&_fd, fname, mode)) 74 | return; 75 | 76 | std::this_thread::sleep_for(std::chrono::milliseconds(open_interval)); 77 | } 78 | 79 | throw spdlog_ex("Failed opening file " + fname + " for writing"); 80 | } 81 | 82 | void reopen(bool truncate) 83 | { 84 | if (_filename.empty()) 85 | throw spdlog_ex("Failed re opening file - was not opened before"); 86 | open(_filename, truncate); 87 | 88 | } 89 | 90 | void flush() { 91 | std::fflush(_fd); 92 | } 93 | 94 | void close() 95 | { 96 | if (_fd) 97 | { 98 | std::fclose(_fd); 99 | _fd = nullptr; 100 | } 101 | } 102 | 103 | void write(const log_msg& msg) 104 | { 105 | 106 | size_t size = msg.formatted.size(); 107 | auto data = msg.formatted.data(); 108 | if (std::fwrite(data, 1, size, _fd) != size) 109 | throw spdlog_ex("Failed writing to file " + _filename); 110 | 111 | if (_force_flush) 112 | std::fflush(_fd); 113 | 114 | } 115 | 116 | long size() 117 | { 118 | if (!_fd) 119 | throw spdlog_ex("Cannot use size() on closed file " + _filename); 120 | 121 | auto pos = ftell(_fd); 122 | if (fseek(_fd, 0, SEEK_END) != 0) 123 | throw spdlog_ex("fseek failed on file " + _filename); 124 | 125 | auto size = ftell(_fd); 126 | 127 | if(fseek(_fd, pos, SEEK_SET) !=0) 128 | throw spdlog_ex("fseek failed on file " + _filename); 129 | 130 | if (size == -1) 131 | throw spdlog_ex("ftell failed on file " + _filename); 132 | 133 | 134 | return size; 135 | 136 | 137 | } 138 | 139 | const std::string& filename() const 140 | { 141 | return _filename; 142 | } 143 | 144 | static bool file_exists(const std::string& name) 145 | { 146 | FILE* file; 147 | if (!os::fopen_s(&file, name.c_str(), "r")) 148 | { 149 | fclose(file); 150 | return true; 151 | } 152 | else 153 | { 154 | return false; 155 | } 156 | } 157 | 158 | 159 | 160 | private: 161 | FILE* _fd; 162 | std::string _filename; 163 | bool _force_flush; 164 | 165 | 166 | }; 167 | } 168 | } 169 | -------------------------------------------------------------------------------- /src/protocols/misc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | 17 | getGUID -- 18 | Code to Convert SteamID -> BEGUID 19 | From Frank https://gist.github.com/Fank/11127158 20 | 21 | */ 22 | 23 | #include "misc.h" 24 | 25 | #include 26 | #include 27 | 28 | #include 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | 40 | bool MISC::init(AbstractExt *extension, const std::string &database_id, const std::string &init_str) 41 | { 42 | extension_ptr = extension; 43 | return true; 44 | } 45 | 46 | 47 | void MISC::getDateTime(const std::string &input_str, std::string &result) 48 | { 49 | int time_offset = 0; 50 | if (!(input_str.empty())) 51 | { 52 | if (!(Poco::NumberParser::tryParse(input_str, time_offset))) 53 | { 54 | time_offset = 0; 55 | } 56 | } 57 | 58 | Poco::DateTime newtime = Poco::DateTime() + Poco::Timespan(time_offset * Poco::Timespan::HOURS); 59 | result = "[1,[" + Poco::DateTimeFormatter::format(newtime, "%Y,%n,%d,%H,%M") + "]]"; 60 | } 61 | 62 | 63 | void MISC::getCrc32(std::string &input_str, std::string &result) 64 | { 65 | std::lock_guard lock(mutex_crc32); 66 | crc32.reset(); 67 | crc32.process_bytes(input_str.data(), input_str.length()); 68 | result = "[1,\"" + Poco::NumberFormatter::format(crc32.checksum()) + "\"]"; 69 | } 70 | 71 | 72 | void MISC::getMD4(std::string &input_str, std::string &result) 73 | { 74 | std::lock_guard lock(mutex_md4); 75 | md4.update(input_str); 76 | result = "[1,\"" + Poco::DigestEngine::digestToHex(md4.digest()) + "\"]"; 77 | } 78 | 79 | 80 | void MISC::getMD5(std::string &input_str, std::string &result) 81 | { 82 | std::lock_guard lock(mutex_md5); 83 | md5.update(input_str); 84 | result = "[1,\"" + Poco::DigestEngine::digestToHex(md5.digest()) + "\"]"; 85 | } 86 | 87 | 88 | void MISC::getBEGUID(std::string &input_str, std::string &result) 89 | // From Frank https://gist.github.com/Fank/11127158 90 | // Modified to use libpoco 91 | { 92 | bool status = true; 93 | 94 | if (input_str.empty()) 95 | { 96 | status = false; 97 | result = "[0,\"Invalid SteamID\""; 98 | } 99 | else 100 | { 101 | for (unsigned int index=0; index < input_str.length(); index++) 102 | { 103 | if (!std::isdigit(input_str[index])) 104 | { 105 | status = false; 106 | result = "[0,\"Invalid SteamID\""; 107 | break; 108 | } 109 | } 110 | } 111 | 112 | if (status) 113 | { 114 | Poco::Int64 steamID = Poco::NumberParser::parse64(input_str); 115 | Poco::Int8 i = 0, parts[8] = { 0 }; 116 | 117 | do 118 | { 119 | parts[i++] = steamID & 0xFFu; 120 | } while (steamID >>= 8); 121 | 122 | std::stringstream bestring; 123 | bestring << "BE"; 124 | for (auto &part: parts) 125 | { 126 | bestring << char(part); 127 | } 128 | 129 | std::lock_guard lock(mutex_md5); 130 | md5.update(bestring.str()); 131 | result = "[1,\"" + Poco::DigestEngine::digestToHex(md5.digest()) + "\"]"; 132 | } 133 | } 134 | 135 | 136 | void MISC::getRandomString(std::string &input_str, std::string &result) 137 | { 138 | Poco::StringTokenizer tokens(input_str, ":"); 139 | if (tokens.count() != 2) 140 | { 141 | result = "[0,\"Error Syntax\"]"; 142 | } 143 | else 144 | { 145 | int num_of_strings; 146 | int len_of_string; 147 | 148 | if (!((Poco::NumberParser::tryParse(tokens[0], num_of_strings)) && (Poco::NumberParser::tryParse(tokens[1], len_of_string)))) 149 | { 150 | result = "[0,\"Error Invalid Number\"]"; 151 | } 152 | else 153 | { 154 | if (num_of_strings <= 0) 155 | { 156 | result = "[0,\"Error Number of Variable <= 0\"]"; 157 | } 158 | else 159 | { 160 | extension_ptr->getUniqueString(len_of_string, num_of_strings, result); 161 | } 162 | } 163 | } 164 | } 165 | 166 | 167 | bool MISC::callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id) 168 | { 169 | // Protocol 170 | std::string command; 171 | std::string data; 172 | 173 | const std::string::size_type found = input_str.find(":"); 174 | 175 | if (found==std::string::npos) // Check Invalid Format 176 | { 177 | command = input_str; 178 | } 179 | else 180 | { 181 | command = input_str.substr(0,found); 182 | data = input_str.substr(found+1); 183 | } 184 | if (command == "TIME") 185 | { 186 | getDateTime(data, result); 187 | } 188 | else if (command == "BEGUID") 189 | { 190 | getBEGUID(data, result); 191 | } 192 | else if (command == "CRC32") 193 | { 194 | getCrc32(data, result); 195 | } 196 | else if (command == "MD4") 197 | { 198 | getMD4(data, result); 199 | } 200 | else if (command == "MD5") 201 | { 202 | getMD5(data, result); 203 | } 204 | else if (command == "RANDOM_UNIQUE_STRING") 205 | { 206 | getRandomString(data, result); 207 | } 208 | else if (command == "TEST") 209 | { 210 | result = data; 211 | } 212 | else 213 | { 214 | result = "[0,\"Error Invalid Format\"]"; 215 | extension_ptr->logger->warn("extDB2: Misc Invalid Command: {0}", command); 216 | } 217 | return true; 218 | } 219 | -------------------------------------------------------------------------------- /src/spdlog/details/os.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | #include 27 | #include 28 | #include 29 | 30 | #ifdef _WIN32 31 | # ifndef WIN32_LEAN_AND_MEAN 32 | # define WIN32_LEAN_AND_MEAN 33 | # endif 34 | # include 35 | 36 | #ifdef __MINGW32__ 37 | #include 38 | #endif 39 | 40 | #elif __linux__ 41 | #include //Use gettid() syscall under linux to get thread id 42 | #include 43 | #else 44 | #include 45 | #endif 46 | 47 | #include "../common.h" 48 | 49 | namespace spdlog 50 | { 51 | namespace details 52 | { 53 | namespace os 54 | { 55 | 56 | inline spdlog::log_clock::time_point now() 57 | { 58 | 59 | #if defined __linux__ && defined SPDLOG_CLOCK_COARSE 60 | timespec ts; 61 | ::clock_gettime(CLOCK_REALTIME_COARSE, &ts); 62 | return std::chrono::time_point( 63 | std::chrono::duration_cast( 64 | std::chrono::seconds(ts.tv_sec) + std::chrono::nanoseconds(ts.tv_nsec))); 65 | 66 | #else 67 | return log_clock::now(); 68 | #endif 69 | 70 | } 71 | inline std::tm localtime(const std::time_t &time_tt) 72 | { 73 | 74 | #ifdef _WIN32 75 | std::tm tm; 76 | localtime_s(&tm, &time_tt); 77 | #else 78 | std::tm tm; 79 | localtime_r(&time_tt, &tm); 80 | #endif 81 | return tm; 82 | } 83 | 84 | inline std::tm localtime() 85 | { 86 | std::time_t now_t = time(nullptr); 87 | return localtime(now_t); 88 | } 89 | 90 | 91 | inline std::tm gmtime(const std::time_t &time_tt) 92 | { 93 | 94 | #ifdef _WIN32 95 | std::tm tm; 96 | gmtime_s(&tm, &time_tt); 97 | #else 98 | std::tm tm; 99 | gmtime_r(&time_tt, &tm); 100 | #endif 101 | return tm; 102 | } 103 | 104 | inline std::tm gmtime() 105 | { 106 | std::time_t now_t = time(nullptr); 107 | return gmtime(now_t); 108 | } 109 | inline bool operator==(const std::tm& tm1, const std::tm& tm2) 110 | { 111 | return (tm1.tm_sec == tm2.tm_sec && 112 | tm1.tm_min == tm2.tm_min && 113 | tm1.tm_hour == tm2.tm_hour && 114 | tm1.tm_mday == tm2.tm_mday && 115 | tm1.tm_mon == tm2.tm_mon && 116 | tm1.tm_year == tm2.tm_year && 117 | tm1.tm_isdst == tm2.tm_isdst); 118 | } 119 | 120 | inline bool operator!=(const std::tm& tm1, const std::tm& tm2) 121 | { 122 | return !(tm1 == tm2); 123 | } 124 | 125 | #ifdef _WIN32 126 | inline const char* eol() 127 | { 128 | return "\r\n"; 129 | } 130 | #else 131 | constexpr inline const char* eol() 132 | { 133 | return "\n"; 134 | } 135 | #endif 136 | 137 | #ifdef _WIN32 138 | inline unsigned short eol_size() 139 | { 140 | return 2; 141 | } 142 | #else 143 | constexpr inline unsigned short eol_size() 144 | { 145 | return 1; 146 | } 147 | #endif 148 | 149 | //fopen_s on non windows for writing 150 | inline int fopen_s(FILE** fp, const std::string& filename, const char* mode) 151 | { 152 | #ifdef _WIN32 153 | *fp = _fsopen((filename.c_str()), mode, _SH_DENYWR); 154 | return *fp == nullptr; 155 | #else 156 | *fp = fopen((filename.c_str()), mode); 157 | return *fp == nullptr; 158 | #endif 159 | 160 | 161 | } 162 | 163 | //Return utc offset in minutes or -1 on failure 164 | inline int utc_minutes_offset(const std::tm& tm = details::os::localtime()) 165 | { 166 | 167 | #ifdef _WIN32 168 | (void)tm; // avoid unused param warning 169 | DYNAMIC_TIME_ZONE_INFORMATION tzinfo; 170 | auto rv = GetDynamicTimeZoneInformation(&tzinfo); 171 | if (!rv) 172 | return -1; 173 | return -1 * (tzinfo.Bias + tzinfo.DaylightBias); 174 | #else 175 | return static_cast(tm.tm_gmtoff / 60); 176 | #endif 177 | } 178 | 179 | //Return current thread id as size_t 180 | //It exists because the std::this_thread::get_id() is much slower(espcially under VS 2013) 181 | inline size_t thread_id() 182 | { 183 | #ifdef _WIN32 184 | return static_cast(::GetCurrentThreadId()); 185 | #elif __linux__ 186 | # if defined(__ANDROID__) && defined(__ANDROID_API__) && (__ANDROID_API__ < 21) 187 | # define SYS_gettid __NR_gettid 188 | # endif 189 | return static_cast(syscall(SYS_gettid)); 190 | #else //Default to standard C++11 (OSX and other Unix) 191 | return static_cast(std::hash()(std::this_thread::get_id())); 192 | #endif 193 | 194 | } 195 | 196 | } //os 197 | } //details 198 | } //spdlog 199 | 200 | 201 | -------------------------------------------------------------------------------- /src/spdlog/logger.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | // Thread safe logger 28 | // Has name, log level, vector of std::shared sink pointers and formatter 29 | // Upon each log write the logger: 30 | // 1. Checks if its log level is enough to log the message 31 | // 2. Format the message using the formatter function 32 | // 3. Pass the formatted message to its sinks to performa the actual logging 33 | 34 | #include 35 | #include 36 | #include "sinks/base_sink.h" 37 | #include "common.h" 38 | 39 | namespace spdlog 40 | { 41 | 42 | namespace details 43 | { 44 | class line_logger; 45 | } 46 | 47 | class logger 48 | { 49 | public: 50 | logger(const std::string& logger_name, sink_ptr single_sink); 51 | logger(const std::string& name, sinks_init_list); 52 | template 53 | logger(const std::string& name, const It& begin, const It& end); 54 | 55 | virtual ~logger(); 56 | logger(const logger&) = delete; 57 | logger& operator=(const logger&) = delete; 58 | 59 | void set_level(level::level_enum); 60 | level::level_enum level() const; 61 | 62 | const std::string& name() const; 63 | bool should_log(level::level_enum) const; 64 | 65 | // logger.info(cppformat_string, arg1, arg2, arg3, ...) call style 66 | template details::line_logger trace(const char* fmt, const Args&... args); 67 | template details::line_logger debug(const char* fmt, const Args&... args); 68 | template details::line_logger info(const char* fmt, const Args&... args); 69 | template details::line_logger notice(const char* fmt, const Args&... args); 70 | template details::line_logger warn(const char* fmt, const Args&... args); 71 | template details::line_logger error(const char* fmt, const Args&... args); 72 | template details::line_logger critical(const char* fmt, const Args&... args); 73 | template details::line_logger alert(const char* fmt, const Args&... args); 74 | template details::line_logger emerg(const char* fmt, const Args&... args); 75 | 76 | 77 | // logger.info(msg) << ".." call style 78 | template details::line_logger trace(const T&); 79 | template details::line_logger debug(const T&); 80 | template details::line_logger info(const T&); 81 | template details::line_logger notice(const T&); 82 | template details::line_logger warn(const T&); 83 | template details::line_logger error(const T&); 84 | template details::line_logger critical(const T&); 85 | template details::line_logger alert(const T&); 86 | template details::line_logger emerg(const T&); 87 | 88 | 89 | // logger.info() << ".." call style 90 | details::line_logger trace(); 91 | details::line_logger debug(); 92 | details::line_logger info(); 93 | details::line_logger notice(); 94 | details::line_logger warn(); 95 | details::line_logger error(); 96 | details::line_logger critical(); 97 | details::line_logger alert(); 98 | details::line_logger emerg(); 99 | 100 | 101 | 102 | // Create log message with the given level, no matter what is the actual logger's level 103 | template 104 | details::line_logger force_log(level::level_enum lvl, const char* fmt, const Args&... args); 105 | 106 | // Set the format of the log messages from this logger 107 | void set_pattern(const std::string&); 108 | void set_formatter(formatter_ptr); 109 | 110 | void flush(); 111 | 112 | protected: 113 | virtual void _log_msg(details::log_msg&); 114 | virtual void _set_pattern(const std::string&); 115 | virtual void _set_formatter(formatter_ptr); 116 | details::line_logger _log_if_enabled(level::level_enum lvl); 117 | template 118 | details::line_logger _log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args); 119 | template 120 | inline details::line_logger _log_if_enabled(level::level_enum lvl, const T& msg); 121 | 122 | 123 | friend details::line_logger; 124 | std::string _name; 125 | std::vector _sinks; 126 | formatter_ptr _formatter; 127 | std::atomic_int _level; 128 | 129 | }; 130 | } 131 | 132 | #include "./details/logger_impl.h" 133 | -------------------------------------------------------------------------------- /src/spdlog/details/line_logger.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | #include 27 | #include "../common.h" 28 | #include "../logger.h" 29 | 30 | // Line logger class - aggregates operator<< calls to fast ostream 31 | // and logs upon destruction 32 | 33 | namespace spdlog 34 | { 35 | namespace details 36 | { 37 | class line_logger 38 | { 39 | public: 40 | line_logger(logger* callback_logger, level::level_enum msg_level, bool enabled): 41 | _callback_logger(callback_logger), 42 | _log_msg(msg_level), 43 | _enabled(enabled) 44 | {} 45 | 46 | // No copy intended. Only move 47 | line_logger(const line_logger& other) = delete; 48 | line_logger& operator=(const line_logger&) = delete; 49 | line_logger& operator=(line_logger&&) = delete; 50 | 51 | 52 | line_logger(line_logger&& other) : 53 | _callback_logger(other._callback_logger), 54 | _log_msg(std::move(other._log_msg)), 55 | _enabled(other._enabled) 56 | { 57 | other.disable(); 58 | } 59 | 60 | //Log the log message using the callback logger 61 | ~line_logger() 62 | { 63 | if (_enabled) 64 | { 65 | #ifndef SPDLOG_NO_NAME 66 | _log_msg.logger_name = _callback_logger->name(); 67 | #endif 68 | #ifndef SPDLOG_NO_DATETIME 69 | _log_msg.time = os::now(); 70 | #endif 71 | 72 | #ifndef SPDLOG_NO_THREAD_ID 73 | _log_msg.thread_id = os::thread_id(); 74 | #endif 75 | _callback_logger->_log_msg(_log_msg); 76 | } 77 | } 78 | 79 | // 80 | // Support for format string with variadic args 81 | // 82 | 83 | 84 | void write(const char* what) 85 | { 86 | if (_enabled) 87 | _log_msg.raw << what; 88 | } 89 | 90 | template 91 | void write(const char* fmt, const Args&... args) 92 | { 93 | if (!_enabled) 94 | return; 95 | try 96 | { 97 | _log_msg.raw.write(fmt, args...); 98 | } 99 | catch (const fmt::FormatError& e) 100 | { 101 | throw spdlog_ex(fmt::format("formatting error while processing format string '{}': {}", fmt, e.what())); 102 | } 103 | } 104 | 105 | 106 | // 107 | // Support for operator<< 108 | // 109 | line_logger& operator<<(const char* what) 110 | { 111 | if (_enabled) 112 | _log_msg.raw << what; 113 | return *this; 114 | } 115 | 116 | line_logger& operator<<(const std::string& what) 117 | { 118 | if (_enabled) 119 | _log_msg.raw << what; 120 | return *this; 121 | } 122 | 123 | line_logger& operator<<(int what) 124 | { 125 | if (_enabled) 126 | _log_msg.raw << what; 127 | return *this; 128 | } 129 | 130 | line_logger& operator<<(unsigned int what) 131 | { 132 | if (_enabled) 133 | _log_msg.raw << what; 134 | return *this; 135 | } 136 | 137 | 138 | line_logger& operator<<(long what) 139 | { 140 | if (_enabled) 141 | _log_msg.raw << what; 142 | return *this; 143 | } 144 | 145 | line_logger& operator<<(unsigned long what) 146 | { 147 | if (_enabled) 148 | _log_msg.raw << what; 149 | return *this; 150 | } 151 | 152 | line_logger& operator<<(long long what) 153 | { 154 | if (_enabled) 155 | _log_msg.raw << what; 156 | return *this; 157 | } 158 | 159 | line_logger& operator<<(unsigned long long what) 160 | { 161 | if (_enabled) 162 | _log_msg.raw << what; 163 | return *this; 164 | } 165 | 166 | line_logger& operator<<(double what) 167 | { 168 | if (_enabled) 169 | _log_msg.raw << what; 170 | return *this; 171 | } 172 | 173 | line_logger& operator<<(long double what) 174 | { 175 | if (_enabled) 176 | _log_msg.raw << what; 177 | return *this; 178 | } 179 | 180 | line_logger& operator<<(float what) 181 | { 182 | if (_enabled) 183 | _log_msg.raw << what; 184 | return *this; 185 | } 186 | 187 | line_logger& operator<<(char what) 188 | { 189 | if (_enabled) 190 | _log_msg.raw << what; 191 | return *this; 192 | } 193 | 194 | //Support user types which implements operator<< 195 | template 196 | line_logger& operator<<(const T& what) 197 | { 198 | if (_enabled) 199 | _log_msg.raw.write("{}", what); 200 | return *this; 201 | } 202 | 203 | 204 | void disable() 205 | { 206 | _enabled = false; 207 | } 208 | 209 | bool is_enabled() const 210 | { 211 | return _enabled; 212 | } 213 | 214 | 215 | private: 216 | logger* _callback_logger; 217 | log_msg _log_msg; 218 | bool _enabled; 219 | }; 220 | } //Namespace details 221 | } // Namespace spdlog 222 | -------------------------------------------------------------------------------- /src/spdlog/details/mpmc_bounded_q.h: -------------------------------------------------------------------------------- 1 | /* 2 | A modified version of Bounded MPMC queue by Dmitry Vyukov. 3 | 4 | Original code from: 5 | http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue 6 | 7 | licensed by Dmitry Vyukov under the terms below: 8 | 9 | Simplified BSD license 10 | 11 | Copyright (c) 2010-2011 Dmitry Vyukov. All rights reserved. 12 | Redistribution and use in source and binary forms, with or without modification, 13 | are permitted provided that the following conditions are met: 14 | 1. Redistributions of source code must retain the above copyright notice, this list of 15 | conditions and the following disclaimer. 16 | 17 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 18 | of conditions and the following disclaimer in the documentation and/or other materials 19 | provided with the distribution. 20 | 21 | THIS SOFTWARE IS PROVIDED BY DMITRY VYUKOV "AS IS" AND ANY EXPRESS OR IMPLIED 22 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 23 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 24 | SHALL DMITRY VYUKOV OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 25 | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 27 | OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 28 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 29 | OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | The views and conclusions contained in the software and documentation are those of the authors and 33 | should not be interpreted as representing official policies, either expressed or implied, of Dmitry Vyukov. 34 | */ 35 | 36 | /* 37 | The code in its current form adds the license below: 38 | 39 | spdlog - an extremely fast and easy to use c++11 logging library. 40 | Copyright (c) 2014 Gabi Melman. 41 | 42 | Permission is hereby granted, free of charge, to any person obtaining 43 | a copy of this software and associated documentation files (the 44 | "Software"), to deal in the Software without restriction, including 45 | without limitation the rights to use, copy, modify, merge, publish, 46 | distribute, sublicense, and/or sell copies of the Software, and to 47 | permit persons to whom the Software is furnished to do so, subject to 48 | the following conditions: 49 | 50 | The above copyright notice and this permission notice shall be 51 | included in all copies or substantial portions of the Software. 52 | 53 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 54 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 55 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 56 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 57 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 58 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 59 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 60 | */ 61 | 62 | #pragma once 63 | 64 | #include 65 | #include "../common.h" 66 | 67 | namespace spdlog 68 | { 69 | namespace details 70 | { 71 | 72 | template 73 | class mpmc_bounded_queue 74 | { 75 | public: 76 | 77 | using item_type = T; 78 | mpmc_bounded_queue(size_t buffer_size) 79 | : buffer_(new cell_t [buffer_size]), 80 | buffer_mask_(buffer_size - 1) 81 | { 82 | //queue size must be power of two 83 | if(!((buffer_size >= 2) && ((buffer_size & (buffer_size - 1)) == 0))) 84 | throw spdlog_ex("async logger queue size must be power of two"); 85 | 86 | for (size_t i = 0; i != buffer_size; i += 1) 87 | buffer_[i].sequence_.store(i, std::memory_order_relaxed); 88 | enqueue_pos_.store(0, std::memory_order_relaxed); 89 | dequeue_pos_.store(0, std::memory_order_relaxed); 90 | } 91 | 92 | ~mpmc_bounded_queue() 93 | { 94 | delete [] buffer_; 95 | } 96 | 97 | 98 | bool enqueue(T&& data) 99 | { 100 | cell_t* cell; 101 | size_t pos = enqueue_pos_.load(std::memory_order_relaxed); 102 | for (;;) 103 | { 104 | cell = &buffer_[pos & buffer_mask_]; 105 | size_t seq = cell->sequence_.load(std::memory_order_acquire); 106 | intptr_t dif = (intptr_t)seq - (intptr_t)pos; 107 | if (dif == 0) 108 | { 109 | if (enqueue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) 110 | break; 111 | } 112 | else if (dif < 0) 113 | { 114 | return false; 115 | } 116 | else 117 | { 118 | pos = enqueue_pos_.load(std::memory_order_relaxed); 119 | } 120 | } 121 | cell->data_ = std::move(data); 122 | cell->sequence_.store(pos + 1, std::memory_order_release); 123 | return true; 124 | } 125 | 126 | bool dequeue(T& data) 127 | { 128 | cell_t* cell; 129 | size_t pos = dequeue_pos_.load(std::memory_order_relaxed); 130 | for (;;) 131 | { 132 | cell = &buffer_[pos & buffer_mask_]; 133 | size_t seq = 134 | cell->sequence_.load(std::memory_order_acquire); 135 | intptr_t dif = (intptr_t)seq - (intptr_t)(pos + 1); 136 | if (dif == 0) 137 | { 138 | if (dequeue_pos_.compare_exchange_weak(pos, pos + 1, std::memory_order_relaxed)) 139 | break; 140 | } 141 | else if (dif < 0) 142 | return false; 143 | else 144 | pos = dequeue_pos_.load(std::memory_order_relaxed); 145 | } 146 | data = std::move(cell->data_); 147 | cell->sequence_.store(pos + buffer_mask_ + 1, std::memory_order_release); 148 | return true; 149 | } 150 | 151 | private: 152 | struct cell_t 153 | { 154 | std::atomic sequence_; 155 | T data_; 156 | }; 157 | 158 | static size_t const cacheline_size = 64; 159 | typedef char cacheline_pad_t [cacheline_size]; 160 | 161 | cacheline_pad_t pad0_; 162 | cell_t* const buffer_; 163 | size_t const buffer_mask_; 164 | cacheline_pad_t pad1_; 165 | std::atomic enqueue_pos_; 166 | cacheline_pad_t pad2_; 167 | std::atomic dequeue_pos_; 168 | cacheline_pad_t pad3_; 169 | 170 | mpmc_bounded_queue(mpmc_bounded_queue const&); 171 | void operator = (mpmc_bounded_queue const&); 172 | }; 173 | 174 | } // ns details 175 | } // ns spdlog 176 | -------------------------------------------------------------------------------- /src/spdlog/details/spdlog_impl.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | // 28 | // Global registry functions 29 | // 30 | #include "registry.h" 31 | #include "../sinks/file_sinks.h" 32 | #include "../sinks/stdout_sinks.h" 33 | #include "../sinks/syslog_sink.h" 34 | 35 | inline void spdlog::register_logger(std::shared_ptr logger) 36 | { 37 | return details::registry::instance().register_logger(logger); 38 | } 39 | 40 | inline std::shared_ptr spdlog::get(const std::string& name) 41 | { 42 | return details::registry::instance().get(name); 43 | } 44 | 45 | inline void spdlog::drop(const std::string &name) 46 | { 47 | details::registry::instance().drop(name); 48 | } 49 | 50 | // Create multi/single threaded rotating file logger 51 | inline std::shared_ptr spdlog::rotating_logger_mt(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool force_flush) 52 | { 53 | return create(logger_name, filename, "log", max_file_size, max_files, force_flush); 54 | } 55 | 56 | inline std::shared_ptr spdlog::rotating_logger_st(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool force_flush) 57 | { 58 | return create(logger_name, filename, "log", max_file_size, max_files, force_flush); 59 | } 60 | 61 | // Create file logger which creates new file at midnight): 62 | inline std::shared_ptr spdlog::daily_logger_mt(const std::string& logger_name, const std::string& filename, int hour, int minute, bool force_flush) 63 | { 64 | return create(logger_name, filename, "log", hour, minute, force_flush); 65 | } 66 | inline std::shared_ptr spdlog::daily_logger_st(const std::string& logger_name, const std::string& filename, int hour, int minute, bool force_flush) 67 | { 68 | return create(logger_name, filename, "log", hour, minute, force_flush); 69 | } 70 | 71 | 72 | // Create stdout/stderr loggers 73 | inline std::shared_ptr spdlog::stdout_logger_mt(const std::string& logger_name) 74 | { 75 | return details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_mt::instance()); 76 | } 77 | 78 | inline std::shared_ptr spdlog::stdout_logger_st(const std::string& logger_name) 79 | { 80 | return details::registry::instance().create(logger_name, spdlog::sinks::stdout_sink_st::instance()); 81 | } 82 | 83 | inline std::shared_ptr spdlog::stderr_logger_mt(const std::string& logger_name) 84 | { 85 | return details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_mt::instance()); 86 | } 87 | 88 | inline std::shared_ptr spdlog::stderr_logger_st(const std::string& logger_name) 89 | { 90 | return details::registry::instance().create(logger_name, spdlog::sinks::stderr_sink_st::instance()); 91 | } 92 | 93 | #ifdef __linux__ 94 | // Create syslog logger 95 | inline std::shared_ptr spdlog::syslog_logger(const std::string& logger_name, const std::string& syslog_ident, int syslog_option) 96 | { 97 | return create(logger_name, syslog_ident, syslog_option); 98 | } 99 | #endif 100 | 101 | 102 | //Create logger with multiple sinks 103 | 104 | inline std::shared_ptr spdlog::create(const std::string& logger_name, spdlog::sinks_init_list sinks) 105 | { 106 | return details::registry::instance().create(logger_name, sinks); 107 | } 108 | 109 | 110 | template 111 | inline std::shared_ptr spdlog::create(const std::string& logger_name, Args&... args) 112 | { 113 | sink_ptr sink = std::make_shared(args...); 114 | return details::registry::instance().create(logger_name, { sink }); 115 | } 116 | 117 | 118 | template 119 | inline std::shared_ptr spdlog::create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) 120 | { 121 | return details::registry::instance().create(logger_name, sinks_begin, sinks_end); 122 | } 123 | 124 | inline void spdlog::set_formatter(spdlog::formatter_ptr f) 125 | { 126 | details::registry::instance().formatter(f); 127 | } 128 | 129 | inline void spdlog::set_pattern(const std::string& format_string) 130 | { 131 | return details::registry::instance().set_pattern(format_string); 132 | } 133 | 134 | inline void spdlog::set_level(level::level_enum log_level) 135 | { 136 | return details::registry::instance().set_level(log_level); 137 | } 138 | 139 | 140 | inline void spdlog::set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms) 141 | { 142 | details::registry::instance().set_async_mode(queue_size, overflow_policy, worker_warmup_cb, flush_interval_ms); 143 | } 144 | 145 | inline void spdlog::set_sync_mode() 146 | { 147 | details::registry::instance().set_sync_mode(); 148 | } 149 | 150 | inline void spdlog::drop_all() 151 | { 152 | details::registry::instance().drop_all(); 153 | } 154 | 155 | -------------------------------------------------------------------------------- /src/spdlog/details/registry.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | // Loggers registy of unique name->logger pointer 27 | // An attempt to create a logger with an alreasy existing name will be ignored 28 | // If user requests a non existing logger, nullptr will be returned 29 | // This class is thread safe 30 | 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #include "./null_mutex.h" 37 | #include "../logger.h" 38 | #include "../async_logger.h" 39 | #include "../common.h" 40 | 41 | namespace spdlog 42 | { 43 | namespace details 44 | { 45 | template class registry_t 46 | { 47 | public: 48 | 49 | void register_logger(std::shared_ptr logger) 50 | { 51 | std::lock_guard lock(_mutex); 52 | register_logger_impl(logger); 53 | } 54 | 55 | 56 | std::shared_ptr get(const std::string& logger_name) 57 | { 58 | std::lock_guard lock(_mutex); 59 | auto found = _loggers.find(logger_name); 60 | return found == _loggers.end() ? nullptr : found->second; 61 | } 62 | 63 | template 64 | std::shared_ptr create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end) 65 | { 66 | 67 | std::shared_ptr new_logger; 68 | 69 | std::lock_guard lock(_mutex); 70 | 71 | 72 | if (_async_mode) 73 | new_logger = std::make_shared(logger_name, sinks_begin, sinks_end, _async_q_size, _overflow_policy, _worker_warmup_cb, _flush_interval_ms); 74 | else 75 | new_logger = std::make_shared(logger_name, sinks_begin, sinks_end); 76 | 77 | if (_formatter) 78 | new_logger->set_formatter(_formatter); 79 | 80 | new_logger->set_level(_level); 81 | register_logger_impl(new_logger); 82 | return new_logger; 83 | } 84 | 85 | void drop(const std::string& logger_name) 86 | { 87 | std::lock_guard lock(_mutex); 88 | _loggers.erase(logger_name); 89 | } 90 | 91 | void drop_all() 92 | { 93 | std::lock_guard lock(_mutex); 94 | _loggers.clear(); 95 | } 96 | std::shared_ptr create(const std::string& logger_name, sinks_init_list sinks) 97 | { 98 | return create(logger_name, sinks.begin(), sinks.end()); 99 | } 100 | 101 | std::shared_ptr create(const std::string& logger_name, sink_ptr sink) 102 | { 103 | return create(logger_name, { sink }); 104 | } 105 | 106 | 107 | void formatter(formatter_ptr f) 108 | { 109 | std::lock_guard lock(_mutex); 110 | _formatter = f; 111 | for (auto& l : _loggers) 112 | l.second->set_formatter(_formatter); 113 | } 114 | 115 | void set_pattern(const std::string& pattern) 116 | { 117 | std::lock_guard lock(_mutex); 118 | _formatter = std::make_shared(pattern); 119 | for (auto& l : _loggers) 120 | l.second->set_formatter(_formatter); 121 | } 122 | 123 | void set_level(level::level_enum log_level) 124 | { 125 | std::lock_guard lock(_mutex); 126 | for (auto& l : _loggers) 127 | l.second->set_level(log_level); 128 | _level = log_level; 129 | } 130 | 131 | void set_async_mode(size_t q_size, const async_overflow_policy overflow_policy, const std::function& worker_warmup_cb, const std::chrono::milliseconds& flush_interval_ms) 132 | { 133 | std::lock_guard lock(_mutex); 134 | _async_mode = true; 135 | _async_q_size = q_size; 136 | _overflow_policy = overflow_policy; 137 | _worker_warmup_cb = worker_warmup_cb; 138 | _flush_interval_ms = flush_interval_ms; 139 | } 140 | 141 | void set_sync_mode() 142 | { 143 | std::lock_guard lock(_mutex); 144 | _async_mode = false; 145 | } 146 | 147 | static registry_t& instance() 148 | { 149 | static registry_t s_instance; 150 | return s_instance; 151 | } 152 | 153 | private: 154 | void register_logger_impl(std::shared_ptr logger) 155 | { 156 | auto logger_name = logger->name(); 157 | if (_loggers.find(logger_name) != std::end(_loggers)) 158 | throw spdlog_ex("logger with name " + logger_name + " already exists"); 159 | _loggers[logger->name()] = logger; 160 | } 161 | registry_t(){} 162 | registry_t(const registry_t&) = delete; 163 | registry_t& operator=(const registry_t&) = delete; 164 | Mutex _mutex; 165 | std::unordered_map > _loggers; 166 | formatter_ptr _formatter; 167 | level::level_enum _level = level::info; 168 | bool _async_mode = false; 169 | size_t _async_q_size = 0; 170 | async_overflow_policy _overflow_policy = async_overflow_policy::block_retry; 171 | std::function _worker_warmup_cb = nullptr; 172 | std::chrono::milliseconds _flush_interval_ms; 173 | }; 174 | #ifdef SPDLOG_NO_REGISTRY_MUTEX 175 | typedef registry_t registry; 176 | #else 177 | typedef registry_t registry; 178 | #endif 179 | } 180 | } 181 | -------------------------------------------------------------------------------- /src/spdlog/spdlog.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | 26 | // spdlog main header file. 27 | //see example.cpp for usage example 28 | 29 | #pragma once 30 | 31 | #include "tweakme.h" 32 | #include "common.h" 33 | #include "logger.h" 34 | 35 | namespace spdlog 36 | { 37 | // Return an existing logger or nullptr if a logger with such name doesn't exist. 38 | // Examples: 39 | // 40 | // spdlog::get("mylog")->info("Hello"); 41 | // auto logger = spdlog::get("mylog"); 42 | // logger.info("This is another message" , x, y, z); 43 | // logger.info() << "This is another message" << x << y << z; 44 | std::shared_ptr get(const std::string& name); 45 | 46 | // 47 | // Set global formatting 48 | // example: spdlog::set_pattern("%Y-%m-%d %H:%M:%S.%e %l : %v"); 49 | // 50 | void set_pattern(const std::string& format_string); 51 | void set_formatter(formatter_ptr f); 52 | 53 | // 54 | // Set global logging level for 55 | // 56 | void set_level(level::level_enum log_level); 57 | 58 | // 59 | // Turn on async mode (off by default) and set the queue size for each async_logger. 60 | // effective only for loggers created after this call. 61 | // queue_size: size of queue (must be power of 2): 62 | // Each logger will pre-allocate a dedicated queue with queue_size entries upon construction. 63 | // 64 | // async_overflow_policy (optional, block_retry by default): 65 | // async_overflow_policy::block_retry - if queue is full, block until queue has room for the new log entry. 66 | // async_overflow_policy::discard_log_msg - never block and discard any new messages when queue overflows. 67 | // 68 | // worker_warmup_cb (optional): 69 | // callback function that will be called in worker thread upon start (can be used to init stuff like thread affinity) 70 | // 71 | void set_async_mode(size_t queue_size, const async_overflow_policy overflow_policy = async_overflow_policy::block_retry, const std::function& worker_warmup_cb = nullptr, const std::chrono::milliseconds& flush_interval_ms = std::chrono::milliseconds::zero()); 72 | 73 | // Turn off async mode 74 | void set_sync_mode(); 75 | 76 | // 77 | // Create and register multi/single threaded rotating file logger 78 | // 79 | std::shared_ptr rotating_logger_mt(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool force_flush = false); 80 | std::shared_ptr rotating_logger_st(const std::string& logger_name, const std::string& filename, size_t max_file_size, size_t max_files, bool force_flush = false); 81 | 82 | // 83 | // Create file logger which creates new file on the given time (default in midnight): 84 | // 85 | std::shared_ptr daily_logger_mt(const std::string& logger_name, const std::string& filename, int hour=0, int minute=0, bool force_flush = false); 86 | std::shared_ptr daily_logger_st(const std::string& logger_name, const std::string& filename, int hour=0, int minute=0, bool force_flush = false); 87 | 88 | 89 | // 90 | // Create and register stdout/stderr loggers 91 | // 92 | std::shared_ptr stdout_logger_mt(const std::string& logger_name); 93 | std::shared_ptr stdout_logger_st(const std::string& logger_name); 94 | std::shared_ptr stderr_logger_mt(const std::string& logger_name); 95 | std::shared_ptr stderr_logger_st(const std::string& logger_name); 96 | 97 | 98 | // 99 | // Create and register a syslog logger 100 | // 101 | #ifdef __linux__ 102 | std::shared_ptr syslog_logger(const std::string& logger_name, const std::string& ident = "", int syslog_option = 0); 103 | #endif 104 | 105 | 106 | // Create and register a logger with multiple sinks 107 | std::shared_ptr create(const std::string& logger_name, sinks_init_list sinks); 108 | template 109 | std::shared_ptr create(const std::string& logger_name, const It& sinks_begin, const It& sinks_end); 110 | 111 | 112 | // Create and register a logger with templated sink type 113 | // Example: spdlog::create("mylog", "dailylog_filename", "txt"); 114 | template 115 | std::shared_ptr create(const std::string& logger_name, Args&...); 116 | 117 | 118 | // Register the given logger with the given name 119 | void register_logger(std::shared_ptr logger); 120 | 121 | // Drop the reference to the given logger 122 | void drop(const std::string &name); 123 | 124 | // Drop all references 125 | void drop_all(); 126 | 127 | 128 | /////////////////////////////////////////////////////////////////////////////// 129 | // 130 | // Macros to be display source file & line 131 | // Trace & Debug can be switched on/off at compile time for zero cost debug statements. 132 | // Uncomment SPDLOG_DEBUG_ON/SPDLOG_TRACE_ON in teakme.h to enable. 133 | // 134 | // Example: 135 | // spdlog::set_level(spdlog::level::debug); 136 | // SPDLOG_DEBUG(my_logger, "Some debug message {} {}", 1, 3.2); 137 | /////////////////////////////////////////////////////////////////////////////// 138 | 139 | #ifdef SPDLOG_TRACE_ON 140 | #define SPDLOG_TRACE(logger, ...) logger->trace(__VA_ARGS__) << " (" << __FILE__ << " #" << __LINE__ <<")"; 141 | #else 142 | #define SPDLOG_TRACE(logger, ...) 143 | #endif 144 | 145 | #ifdef SPDLOG_DEBUG_ON 146 | #define SPDLOG_DEBUG(logger, ...) logger->debug(__VA_ARGS__) << " (" << __FILE__ << " #" << __LINE__ <<")"; 147 | #else 148 | #define SPDLOG_DEBUG(logger, ...) 149 | #endif 150 | 151 | 152 | } 153 | 154 | 155 | #include "details/spdlog_impl.h" 156 | -------------------------------------------------------------------------------- /src/backends/rcon.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2012 Prithu "bladez" Parker 3 | Copyright (C) 2014 Declan Ireland 4 | 5 | This program is free software: you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation, either version 3 of the License, or 8 | (at your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program. If not, see . 17 | 18 | * Change Log 19 | * Changed Code to use Poco Net Library 20 | */ 21 | 22 | 23 | #pragma once 24 | 25 | #include 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | #include 39 | #include 40 | #include 41 | #include 42 | 43 | #include 44 | #include 45 | #include 46 | 47 | #include "../abstract_ext.h" 48 | 49 | 50 | class Rcon 51 | { 52 | public: 53 | struct RconSettings 54 | { 55 | bool return_full_player_info = false; 56 | bool generate_unique_id = false; 57 | 58 | unsigned int port; 59 | 60 | std::string address; 61 | std::string password; 62 | }; 63 | RconSettings rcon_settings; 64 | 65 | struct BadPlayernameSettings 66 | { 67 | bool enable = false; 68 | std::vector bad_strings; 69 | std::vector bad_regexs; 70 | std::string kick_message; 71 | }; 72 | BadPlayernameSettings bad_playername_settings; 73 | 74 | struct WhitelistSettings 75 | { 76 | int open_slots = 0; 77 | bool enable = false; 78 | 79 | bool connected_database = false; 80 | bool kick_on_failed_sql_query = false; 81 | std::string database; 82 | 83 | std::vector whitelisted_guids; 84 | 85 | std::unordered_map players_whitelisted; 86 | std::unordered_map players_non_whitelisted; 87 | 88 | std::string sql_statement; 89 | std::string kick_message; 90 | }; 91 | WhitelistSettings whitelist_settings; 92 | 93 | std::unique_ptr whitelist_session; 94 | std::unique_ptr whitelist_statement; 95 | 96 | // Player Name / BEGuid 97 | std::unordered_map players_name_beguid; 98 | 99 | Rcon(boost::asio::io_service &io_service, std::shared_ptr spdlog); 100 | ~Rcon(); 101 | 102 | void timerReconnect(const size_t delay); 103 | void Reconnect(const boost::system::error_code& error); 104 | 105 | #ifndef RCON_APP 106 | void extInit(AbstractExt *extension); 107 | #endif 108 | 109 | void start(RconSettings &rcon, BadPlayernameSettings &bad_playername, WhitelistSettings &reserved_slots, Poco::AutoPtr pConf); 110 | 111 | void disconnect(); 112 | bool status(); 113 | 114 | void sendCommand(std::string command); 115 | 116 | void addBan(std::string command); 117 | void getMissions(unsigned int &unique_id); 118 | void getPlayers(unsigned int &unique_id); 119 | 120 | private: 121 | #ifdef RCON_APP 122 | struct DBConnectors 123 | { 124 | bool mysql=false; 125 | bool sqlite=false; 126 | }; 127 | DBConnectors DB_connectors_info; 128 | #else 129 | AbstractExt *extension_ptr; 130 | #endif 131 | 132 | bool auto_reconnect = true; 133 | char *rcon_password; 134 | 135 | boost::asio::io_service *io_service_ptr; 136 | std::shared_ptr logger; 137 | 138 | // Inputs are strings + Outputs are strings. 139 | // Info is not kept for long, so there no point converting to a different datatype just to convert back to a string for armaserver 140 | struct RconPlayerInfo 141 | { 142 | std::string number; 143 | std::string ip; 144 | std::string port; 145 | std::string ping; 146 | std::string guid; 147 | std::string verified; 148 | std::string player_name; 149 | std::string lobby; 150 | }; 151 | 152 | struct RconPacket 153 | { 154 | char *cmd; 155 | char cmd_char_workaround; 156 | unsigned char packetCode; 157 | }; 158 | 159 | struct RconRequest 160 | { 161 | unsigned int unique_id; 162 | int request_type; 163 | }; 164 | 165 | 166 | typedef std::pair< int, std::unordered_map > RconMultiPartMsg; 167 | struct RconSocket 168 | { 169 | std::atomic *rcon_run_flag; 170 | std::atomic *rcon_login_flag; 171 | 172 | std::unique_ptr socket; 173 | boost::array recv_buffer; 174 | 175 | std::unique_ptr keepalive_timer; 176 | 177 | std::unique_ptr > rcon_msg_cache; 178 | 179 | //Mission Requests 180 | std::vector mission_requests; 181 | std::mutex mutex_mission_requests; 182 | 183 | //Player Requests 184 | std::vector player_requests; 185 | std::mutex mutex_players_requests; 186 | 187 | boost::crc_32_type keep_alive_crc32; 188 | 189 | std::mutex mutex; 190 | }; 191 | RconSocket rcon_socket; 192 | 193 | 194 | void connect(); 195 | void startReceive(); 196 | 197 | void timerKeepAlive(const size_t delay); 198 | void createKeepAlive(const boost::system::error_code& error); 199 | 200 | void sendPacket(RconPacket &rcon_packet); 201 | void sendBanPacket(RconPacket &rcon_packet); 202 | void extractData(std::size_t &bytes_received, int pos, std::string &result); 203 | 204 | void connectionHandler(const boost::system::error_code& error); 205 | void handleReceive(const boost::system::error_code& error, std::size_t bytes_received); 206 | void handleSent(std::shared_ptr packet, const boost::system::error_code &error, std::size_t bytes_transferred); 207 | void handleBanSent(std::shared_ptr packet, const boost::system::error_code &error, std::size_t bytes_transferred); 208 | 209 | void loginResponse(); 210 | void serverResponse(std::size_t &bytes_received); 211 | 212 | void processMessage(unsigned char &sequence_number, std::string &message); 213 | void processMessageMission(Poco::StringTokenizer &tokens); 214 | void processMessagePlayers(Poco::StringTokenizer &tokens); 215 | void chatMessage(std::size_t &bytes_received); 216 | 217 | void connectDatabase(Poco::AutoPtr pConf); 218 | void checkDatabase(bool &status, bool &error); 219 | 220 | void checkBadPlayerString(std::string &player_number, std::string &player_name, bool &kicked); 221 | void checkWhitelistedPlayer(std::string &player_number, std::string &player_name, std::string &player_guid, bool &kicked); 222 | }; 223 | -------------------------------------------------------------------------------- /src/ext.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #pragma once 20 | 21 | #include 22 | #include 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | #include "abstract_ext.h" 33 | #include "backends/belogscanner.h" 34 | #include "backends/rcon.h" 35 | #include "backends/steam.h" 36 | 37 | #include "protocols/abstract_protocol.h" 38 | 39 | 40 | class Ext: public AbstractExt 41 | { 42 | public: 43 | Ext(std::string shared_libary_path, std::unordered_map &options); 44 | ~Ext(); 45 | void stop(); 46 | void callExtension(char *output, const int &output_size, const char *function); 47 | void rconCommand(std::string input_str); 48 | 49 | void rconAddBan(std::string input_str); 50 | void rconMissions(unsigned int unique_id); 51 | void rconPlayers(unsigned int unique_id); 52 | 53 | void getUniqueString(int &len_of_string, int &num_of_string, std::string &result); 54 | 55 | void createPlayerKey_mutexlock(std::string &player_beguid, int len_of_key); 56 | 57 | void delPlayerKey_delayed(std::string &player_beguid); 58 | void delPlayerKey_mutexlock(); 59 | 60 | void getPlayerKey_SteamID(std::string &player_steam_id, std::string &player_key); 61 | void getPlayerKey_BEGuid(std::string &player_beguid, std::string &player_key); 62 | std::string getPlayerRegex_BEGuid(std::string &player_beguid); 63 | 64 | protected: 65 | const unsigned int saveResult_mutexlock(const resultData &result_data); 66 | void saveResult_mutexlock(const unsigned int &unique_id, const resultData &result_data); 67 | void saveResult_mutexlock(std::vector &unique_ids, const resultData &result_data); 68 | 69 | Poco::Thread steam_thread; 70 | 71 | Poco::Data::Session getDBSession_mutexlock(AbstractExt::DBConnectionInfo &database); 72 | Poco::Data::Session getDBSession_mutexlock(AbstractExt::DBConnectionInfo &database, Poco::Data::SessionPool::SessionDataPtr &session_data_ptr); 73 | 74 | void steamQuery(const unsigned int &unique_id, bool queryFriends, bool queryVacBans, std::string &steamID, bool wakeup); 75 | void steamQuery(const unsigned int &unique_id, bool queryFriends, bool queryVacBans, std::vector &steamIDs, bool wakeup); 76 | 77 | private: 78 | // Input 79 | std::string::size_type input_str_length; 80 | 81 | struct PlayerKeys 82 | { 83 | std::list keys; 84 | std::string regex_rule; 85 | }; 86 | std::unordered_map player_unique_keys; 87 | std::list< std::pair > del_players_keys; 88 | // std::mutex player_unique_keys_mutex; defined in abstract_ext.h used by BELogscanner 89 | 90 | // Rcon 91 | std::unique_ptr rcon; 92 | 93 | // BELogScanner 94 | BELogScanner belog_scanner; 95 | 96 | // Steam 97 | Steam steam; 98 | 99 | // Main ASIO Thread Queue 100 | std::unique_ptr io_work_ptr; 101 | boost::asio::io_service io_service; 102 | boost::thread_group threads; 103 | std::unique_ptr timer; 104 | 105 | // Rcon ASIO Thread Queue 106 | std::unique_ptr rcon_io_work_ptr; 107 | boost::asio::io_service rcon_io_service; 108 | boost::thread_group rcon_threads; 109 | 110 | // Protocols 111 | std::unordered_map< std::string, std::unique_ptr > unordered_map_protocol; 112 | std::mutex mutex_unordered_map_protocol; 113 | 114 | // Unique Random String 115 | std::string random_chars; 116 | boost::random::random_device random_chars_rng; 117 | std::mutex mutex_RandomString; 118 | std::vector < std::string > uniqueRandomVarNames; 119 | 120 | // Unique ID 121 | std::string::size_type call_extension_input_str_length; 122 | unsigned int unique_id_counter = 100; // Can't be value 1 123 | 124 | // Results 125 | std::unordered_map stored_results; 126 | std::mutex mutex_results; // Using Same Lock for Unique ID aswell 127 | 128 | // Player Key 129 | Poco::MD5Engine md5; 130 | std::mutex mutex_md5; 131 | 132 | // Timestamp 133 | Poco::Timestamp timestamp; 134 | 135 | // DateTime 136 | int dateTime_offset = 0; 137 | Poco::DateTime dateTime; 138 | Poco::LocalDateTime localdateTime; 139 | 140 | // TimeDiff 141 | int timeDiff_zoneDiff = 0; //ALways Zero 142 | std::string timeDiff_fmt = ("[%Y,%n,%d,%H,%M]"); 143 | Poco::DateTime dateDiffTime_1; 144 | Poco::DateTime dateDiffTime_2; 145 | Poco::Timespan timespan; 146 | 147 | 148 | #ifdef _WIN32 149 | // Search for randomized config file 150 | void search(boost::filesystem::path &extDB_config_path, bool &conf_found, bool &conf_randomized); 151 | #endif 152 | 153 | // Time 154 | void getDateTime(const std::string &input_str, std::string &result); 155 | void getLocalDateTime(std::string &result); 156 | void getUPTime(std::string &token, std::string &result); 157 | void getDateAdd(std::string& time1, std::string& time2, std::string &result); 158 | void getTimeDiff(std::string &type, std::string& time1, std::string& time2, std::string &result); 159 | void getCurrentTimeDiff(std::string &type, std::string& time1, std::string &result); 160 | void getCurrentLocalTimeDiff(std::string &type, std::string& time1, std::string &result); 161 | void getCurrentTimeDiff(std::string &type, std::string &time1, std::string &offset, std::string &result); 162 | 163 | // BELogScanner 164 | void startBELogscanner(char *output, const std::string &conf); 165 | 166 | // Database 167 | void connectDatabase(char *output, const std::string &database_conf, const std::string &database_id); 168 | void getSinglePartResult_mutexlock(char *output, const int &output_size, const unsigned int &unique_id); 169 | void getMultiPartResult_mutexlock(char *output, const int &output_size, const unsigned int &unique_id); 170 | 171 | // RCon 172 | void startRcon(char *output, const std::string &conf, std::vector &extra_rcon_options); 173 | 174 | // Protocols 175 | void addProtocol(char *output, const std::string &database_id, const std::string &protocol, const std::string &protocol_name, const std::string &init_data); 176 | void syncCallProtocol(char *output, const int &output_size, std::string &input_str); 177 | void onewayCallProtocol(std::string &input_str); 178 | void asyncCallProtocol(const int &output_size, const std::string &protocol, const std::string &data, const unsigned int unique_id); 179 | }; 180 | -------------------------------------------------------------------------------- /src/spdlog/sinks/file_sinks.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | 27 | #include 28 | #include "base_sink.h" 29 | #include "../details/null_mutex.h" 30 | #include "../details/file_helper.h" 31 | #include "../details/format.h" 32 | 33 | namespace spdlog 34 | { 35 | namespace sinks 36 | { 37 | /* 38 | * Trivial file sink with single file as target 39 | */ 40 | template 41 | class simple_file_sink : public base_sink < Mutex > 42 | { 43 | public: 44 | explicit simple_file_sink(const std::string &filename, 45 | bool force_flush = false) : 46 | _file_helper(force_flush) 47 | { 48 | _file_helper.open(filename); 49 | } 50 | void flush() override 51 | { 52 | _file_helper.flush(); 53 | } 54 | 55 | protected: 56 | void _sink_it(const details::log_msg& msg) override 57 | { 58 | _file_helper.write(msg); 59 | } 60 | private: 61 | details::file_helper _file_helper; 62 | }; 63 | 64 | typedef simple_file_sink simple_file_sink_mt; 65 | typedef simple_file_sink simple_file_sink_st; 66 | 67 | /* 68 | * Rotating file sink based on size 69 | */ 70 | template 71 | class rotating_file_sink : public base_sink < Mutex > 72 | { 73 | public: 74 | rotating_file_sink(const std::string &base_filename, const std::string &extension, 75 | std::size_t max_size, std::size_t max_files, 76 | bool force_flush = false) : 77 | _base_filename(base_filename), 78 | _extension(extension), 79 | _max_size(max_size), 80 | _max_files(max_files), 81 | _current_size(0), 82 | _file_helper(force_flush) 83 | { 84 | _file_helper.open(calc_filename(_base_filename, 0, _extension)); 85 | _current_size = _file_helper.size(); //expensive. called only once 86 | } 87 | 88 | void flush() override 89 | { 90 | _file_helper.flush(); 91 | } 92 | 93 | protected: 94 | void _sink_it(const details::log_msg& msg) override 95 | { 96 | _current_size += msg.formatted.size(); 97 | if (_current_size > _max_size) 98 | { 99 | _rotate(); 100 | _current_size = msg.formatted.size(); 101 | } 102 | _file_helper.write(msg); 103 | } 104 | 105 | private: 106 | static std::string calc_filename(const std::string& filename, std::size_t index, const std::string& extension) 107 | { 108 | fmt::MemoryWriter w; 109 | if (index) 110 | w.write("{}.{}.{}", filename, index, extension); 111 | else 112 | w.write("{}.{}", filename, extension); 113 | return w.str(); 114 | } 115 | 116 | // Rotate files: 117 | // log.txt -> log.1.txt 118 | // log.1.txt -> log2.txt 119 | // log.2.txt -> log3.txt 120 | // log.3.txt -> delete 121 | 122 | void _rotate() 123 | { 124 | _file_helper.close(); 125 | for (auto i = _max_files; i > 0; --i) 126 | { 127 | std::string src = calc_filename(_base_filename, i - 1, _extension); 128 | std::string target = calc_filename(_base_filename, i, _extension); 129 | 130 | if (details::file_helper::file_exists(target)) 131 | { 132 | if (std::remove(target.c_str()) != 0) 133 | { 134 | throw spdlog_ex("rotating_file_sink: failed removing " + target); 135 | } 136 | } 137 | if (details::file_helper::file_exists(src) && std::rename(src.c_str(), target.c_str())) 138 | { 139 | throw spdlog_ex("rotating_file_sink: failed renaming " + src + " to " + target); 140 | } 141 | } 142 | _file_helper.reopen(true); 143 | } 144 | std::string _base_filename; 145 | std::string _extension; 146 | std::size_t _max_size; 147 | std::size_t _max_files; 148 | std::size_t _current_size; 149 | details::file_helper _file_helper; 150 | }; 151 | 152 | typedef rotating_file_sink rotating_file_sink_mt; 153 | typedef rotating_file_sinkrotating_file_sink_st; 154 | 155 | /* 156 | * Rotating file sink based on date. rotates at midnight 157 | */ 158 | template 159 | class daily_file_sink :public base_sink < Mutex > 160 | { 161 | public: 162 | //create daily file sink which rotates on given time 163 | daily_file_sink( 164 | const std::string& base_filename, 165 | const std::string& extension, 166 | int rotation_hour, 167 | int rotation_minute, 168 | bool force_flush = false) : _base_filename(base_filename), 169 | _extension(extension), 170 | _rotation_h(rotation_hour), 171 | _rotation_m(rotation_minute), 172 | _file_helper(force_flush) 173 | { 174 | if (rotation_hour < 0 || rotation_hour > 23 || rotation_minute < 0 || rotation_minute > 59) 175 | throw spdlog_ex("daily_file_sink: Invalid rotation time in ctor"); 176 | _rotation_tp = _next_rotation_tp(); 177 | _file_helper.open(calc_filename(_base_filename, _extension)); 178 | } 179 | 180 | void flush() override 181 | { 182 | _file_helper.flush(); 183 | } 184 | 185 | protected: 186 | void _sink_it(const details::log_msg& msg) override 187 | { 188 | if (std::chrono::system_clock::now() >= _rotation_tp) 189 | { 190 | _file_helper.open(calc_filename(_base_filename, _extension)); 191 | _rotation_tp = _next_rotation_tp(); 192 | } 193 | _file_helper.write(msg); 194 | } 195 | 196 | private: 197 | std::chrono::system_clock::time_point _next_rotation_tp() 198 | { 199 | using namespace std::chrono; 200 | auto now = system_clock::now(); 201 | time_t tnow = std::chrono::system_clock::to_time_t(now); 202 | tm date = spdlog::details::os::localtime(tnow); 203 | date.tm_hour = _rotation_h; 204 | date.tm_min = _rotation_m; 205 | date.tm_sec = 0; 206 | auto rotation_time = std::chrono::system_clock::from_time_t(std::mktime(&date)); 207 | if (rotation_time > now) 208 | return rotation_time; 209 | else 210 | return system_clock::time_point(rotation_time + hours(24)); 211 | } 212 | 213 | //Create filename for the form basename.YYYY-MM-DD.extension 214 | static std::string calc_filename(const std::string& basename, const std::string& extension) 215 | { 216 | std::tm tm = spdlog::details::os::localtime(); 217 | fmt::MemoryWriter w; 218 | w.write("{}_{:04d}-{:02d}-{:02d}_{:02d}-{:02d}.{}", basename, tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, extension); 219 | return w.str(); 220 | } 221 | 222 | std::string _base_filename; 223 | std::string _extension; 224 | int _rotation_h; 225 | int _rotation_m; 226 | std::chrono::system_clock::time_point _rotation_tp; 227 | details::file_helper _file_helper; 228 | }; 229 | 230 | typedef daily_file_sink daily_file_sink_mt; 231 | typedef daily_file_sink daily_file_sink_st; 232 | } 233 | } -------------------------------------------------------------------------------- /src/spdlog/details/logger_impl.h: -------------------------------------------------------------------------------- 1 | /*************************************************************************/ 2 | /* spdlog - an extremely fast and easy to use c++11 logging library. */ 3 | /* Copyright (c) 2014 Gabi Melman. */ 4 | /* */ 5 | /* Permission is hereby granted, free of charge, to any person obtaining */ 6 | /* a copy of this software and associated documentation files (the */ 7 | /* "Software"), to deal in the Software without restriction, including */ 8 | /* without limitation the rights to use, copy, modify, merge, publish, */ 9 | /* distribute, sublicense, and/or sell copies of the Software, and to */ 10 | /* permit persons to whom the Software is furnished to do so, subject to */ 11 | /* the following conditions: */ 12 | /* */ 13 | /* The above copyright notice and this permission notice shall be */ 14 | /* included in all copies or substantial portions of the Software. */ 15 | /* */ 16 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 17 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 18 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 19 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 20 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 21 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 22 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 23 | /*************************************************************************/ 24 | 25 | #pragma once 26 | // 27 | // Logger implementation 28 | // 29 | 30 | #include "./line_logger.h" 31 | 32 | 33 | // create logger with given name, sinks and the default pattern formatter 34 | // all other ctors will call this one 35 | template 36 | inline spdlog::logger::logger(const std::string& logger_name, const It& begin, const It& end) : 37 | _name(logger_name), 38 | _sinks(begin, end), 39 | _formatter(std::make_shared("%+")) 40 | { 41 | 42 | // no support under vs2013 for member initialization for std::atomic 43 | _level = level::info; 44 | } 45 | 46 | // ctor with sinks as init list 47 | inline spdlog::logger::logger(const std::string& logger_name, sinks_init_list sinks_list) : 48 | logger(logger_name, sinks_list.begin(), sinks_list.end()) {} 49 | 50 | 51 | // ctor with single sink 52 | inline spdlog::logger::logger(const std::string& logger_name, spdlog::sink_ptr single_sink) : 53 | logger(logger_name, { 54 | single_sink 55 | }) {} 56 | 57 | 58 | inline spdlog::logger::~logger() = default; 59 | 60 | 61 | inline void spdlog::logger::set_formatter(spdlog::formatter_ptr msg_formatter) 62 | { 63 | _set_formatter(msg_formatter); 64 | } 65 | 66 | inline void spdlog::logger::set_pattern(const std::string& pattern) 67 | { 68 | _set_pattern(pattern); 69 | } 70 | 71 | // 72 | // log only if given level>=logger's log level 73 | // 74 | 75 | 76 | template 77 | inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl, const char* fmt, const Args&... args) 78 | { 79 | bool msg_enabled = should_log(lvl); 80 | details::line_logger l(this, lvl, msg_enabled); 81 | l.write(fmt, args...); 82 | return l; 83 | } 84 | 85 | inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl) 86 | { 87 | return details::line_logger(this, lvl, should_log(lvl)); 88 | } 89 | 90 | template 91 | inline spdlog::details::line_logger spdlog::logger::_log_if_enabled(level::level_enum lvl, const T& msg) 92 | { 93 | bool msg_enabled = should_log(lvl); 94 | details::line_logger l(this, lvl, msg_enabled); 95 | l << msg; 96 | return l; 97 | } 98 | 99 | // 100 | // logger.info(cppformat_string, arg1, arg2, arg3, ...) call style 101 | // 102 | template 103 | inline spdlog::details::line_logger spdlog::logger::trace(const char* fmt, const Args&... args) 104 | { 105 | return _log_if_enabled(level::trace, fmt, args...); 106 | } 107 | 108 | template 109 | inline spdlog::details::line_logger spdlog::logger::debug(const char* fmt, const Args&... args) 110 | { 111 | return _log_if_enabled(level::debug, fmt, args...); 112 | } 113 | 114 | template 115 | inline spdlog::details::line_logger spdlog::logger::info(const char* fmt, const Args&... args) 116 | { 117 | return _log_if_enabled(level::info, fmt, args...); 118 | } 119 | 120 | template 121 | inline spdlog::details::line_logger spdlog::logger::notice(const char* fmt, const Args&... args) 122 | { 123 | return _log_if_enabled(level::notice, fmt, args...); 124 | } 125 | 126 | template 127 | inline spdlog::details::line_logger spdlog::logger::warn(const char* fmt, const Args&... args) 128 | { 129 | return _log_if_enabled(level::warn, fmt, args...); 130 | } 131 | 132 | template 133 | inline spdlog::details::line_logger spdlog::logger::error(const char* fmt, const Args&... args) 134 | { 135 | return _log_if_enabled(level::err, fmt, args...); 136 | } 137 | 138 | template 139 | inline spdlog::details::line_logger spdlog::logger::critical(const char* fmt, const Args&... args) 140 | { 141 | return _log_if_enabled(level::critical, fmt, args...); 142 | } 143 | 144 | template 145 | inline spdlog::details::line_logger spdlog::logger::alert(const char* fmt, const Args&... args) 146 | { 147 | return _log_if_enabled(level::alert, fmt, args...); 148 | } 149 | 150 | template 151 | inline spdlog::details::line_logger spdlog::logger::emerg(const char* fmt, const Args&... args) 152 | { 153 | return _log_if_enabled(level::emerg, fmt, args...); 154 | } 155 | 156 | // 157 | // logger.info(msg) << ".." call style 158 | // 159 | template 160 | inline spdlog::details::line_logger spdlog::logger::trace(const T& msg) 161 | { 162 | return _log_if_enabled(level::trace, msg); 163 | } 164 | 165 | template 166 | inline spdlog::details::line_logger spdlog::logger::debug(const T& msg) 167 | { 168 | return _log_if_enabled(level::debug, msg); 169 | } 170 | 171 | 172 | template 173 | inline spdlog::details::line_logger spdlog::logger::info(const T& msg) 174 | { 175 | return _log_if_enabled(level::info, msg); 176 | } 177 | 178 | template 179 | inline spdlog::details::line_logger spdlog::logger::notice(const T& msg) 180 | { 181 | return _log_if_enabled(level::notice, msg); 182 | } 183 | 184 | template 185 | inline spdlog::details::line_logger spdlog::logger::warn(const T& msg) 186 | { 187 | return _log_if_enabled(level::warn, msg); 188 | } 189 | 190 | template 191 | inline spdlog::details::line_logger spdlog::logger::error(const T& msg) 192 | { 193 | return _log_if_enabled(level::err, msg); 194 | } 195 | 196 | template 197 | inline spdlog::details::line_logger spdlog::logger::critical(const T& msg) 198 | { 199 | return _log_if_enabled(level::critical, msg); 200 | } 201 | 202 | template 203 | inline spdlog::details::line_logger spdlog::logger::alert(const T& msg) 204 | { 205 | return _log_if_enabled(level::alert, msg); 206 | } 207 | 208 | template 209 | inline spdlog::details::line_logger spdlog::logger::emerg(const T& msg) 210 | { 211 | return _log_if_enabled(level::emerg, msg); 212 | } 213 | 214 | 215 | 216 | 217 | // 218 | // logger.info() << ".." call style 219 | // 220 | inline spdlog::details::line_logger spdlog::logger::trace() 221 | { 222 | return _log_if_enabled(level::trace); 223 | } 224 | 225 | inline spdlog::details::line_logger spdlog::logger::debug() 226 | { 227 | return _log_if_enabled(level::debug); 228 | } 229 | 230 | inline spdlog::details::line_logger spdlog::logger::info() 231 | { 232 | return _log_if_enabled(level::info); 233 | } 234 | 235 | inline spdlog::details::line_logger spdlog::logger::notice() 236 | { 237 | return _log_if_enabled(level::notice); 238 | } 239 | 240 | inline spdlog::details::line_logger spdlog::logger::warn() 241 | { 242 | return _log_if_enabled(level::warn); 243 | } 244 | 245 | inline spdlog::details::line_logger spdlog::logger::error() 246 | { 247 | return _log_if_enabled(level::err); 248 | } 249 | 250 | inline spdlog::details::line_logger spdlog::logger::critical() 251 | { 252 | return _log_if_enabled(level::critical); 253 | } 254 | 255 | inline spdlog::details::line_logger spdlog::logger::alert() 256 | { 257 | return _log_if_enabled(level::alert); 258 | } 259 | 260 | inline spdlog::details::line_logger spdlog::logger::emerg() 261 | { 262 | return _log_if_enabled(level::emerg); 263 | } 264 | 265 | 266 | // always log, no matter what is the actual logger's log level 267 | template 268 | inline spdlog::details::line_logger spdlog::logger::force_log(level::level_enum lvl, const char* fmt, const Args&... args) 269 | { 270 | details::line_logger l(this, lvl, true); 271 | l.write(fmt, args...); 272 | return l; 273 | } 274 | 275 | // 276 | // name and level 277 | // 278 | inline const std::string& spdlog::logger::name() const 279 | { 280 | return _name; 281 | } 282 | 283 | inline void spdlog::logger::set_level(spdlog::level::level_enum log_level) 284 | { 285 | _level.store(log_level); 286 | } 287 | 288 | inline spdlog::level::level_enum spdlog::logger::level() const 289 | { 290 | return static_cast(_level.load(std::memory_order_relaxed)); 291 | } 292 | 293 | inline bool spdlog::logger::should_log(spdlog::level::level_enum msg_level) const 294 | { 295 | return msg_level >= _level.load(std::memory_order_relaxed); 296 | } 297 | 298 | // 299 | // protected virtual called at end of each user log call (if enabled) by the line_logger 300 | // 301 | inline void spdlog::logger::_log_msg(details::log_msg& msg) 302 | { 303 | _formatter->format(msg); 304 | for (auto &sink : _sinks) 305 | sink->log(msg); 306 | } 307 | 308 | inline void spdlog::logger::_set_pattern(const std::string& pattern) 309 | { 310 | _formatter = std::make_shared(pattern); 311 | } 312 | inline void spdlog::logger::_set_formatter(formatter_ptr msg_formatter) 313 | { 314 | _formatter = msg_formatter; 315 | } 316 | 317 | inline void spdlog::logger::flush() { 318 | for (auto& sink : _sinks) 319 | sink->flush(); 320 | } -------------------------------------------------------------------------------- /src/protocols/sql_raw_v2.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2014 Declan Ireland 3 | 4 | This program 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 3 of the License, or 7 | (at your option) any later version. 8 | 9 | This program 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 this program. If not, see . 16 | */ 17 | 18 | 19 | #include "sql_raw_v2.h" 20 | 21 | #include 22 | 23 | #include 24 | #include 25 | 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | 34 | bool SQL_RAW_V2::init(AbstractExt *extension, const std::string &database_id, const std::string &init_str) 35 | { 36 | extension_ptr = extension; 37 | if (extension_ptr->ext_connectors_info.databases.count(database_id) == 0) 38 | { 39 | #ifdef DEBUG_TESTING 40 | extension_ptr->console->warn("extDB2: SQL_RAW_V2: No Database Connection ID: {0}", database_id); 41 | #endif 42 | extension_ptr->logger->warn("extDB2: SQL_RAW_V2: No Database Connection ID: {0}", database_id); 43 | return false; 44 | } 45 | 46 | database_ptr = &extension_ptr->ext_connectors_info.databases[database_id]; 47 | 48 | bool status; 49 | if (database_ptr->type == "MySQL") 50 | { 51 | status = true; 52 | } 53 | else if (database_ptr->type == "SQLite") 54 | { 55 | status = true; 56 | } 57 | else 58 | { 59 | // DATABASE NOT SETUP YET 60 | #ifdef DEBUG_TESTING 61 | extension_ptr->console->warn("extDB2: SQL_RAW_V2: No Database Connection"); 62 | #endif 63 | extension_ptr->logger->warn("extDB2: SQL_RAW_V2: No Database Connection"); 64 | status = false; 65 | } 66 | 67 | if (status) 68 | { 69 | if (init_str.empty()) 70 | { 71 | stringDataTypeCheck = false; 72 | #ifdef DEBUG_TESTING 73 | extension_ptr->console->info("extDB2: SQL_RAW_V2: Initialized: ADD_QUOTES False"); 74 | #endif 75 | extension_ptr->logger->info("extDB2: SQL_RAW_V2: Initialized: ADD_QUOTES False"); 76 | } 77 | else if (boost::algorithm::iequals(init_str, std::string("ADD_QUOTES"))) 78 | { 79 | stringDataTypeCheck = true; 80 | #ifdef DEBUG_TESTING 81 | extension_ptr->console->info("extDB2: SQL_RAW_V2: Initialized: ADD_QUOTES True"); 82 | #endif 83 | extension_ptr->logger->info("extDB2: SQL_RAW_V2: Initialized: ADD_QUOTES True"); 84 | } 85 | else 86 | { 87 | status = false; 88 | } 89 | } 90 | return status; 91 | } 92 | 93 | 94 | bool SQL_RAW_V2::callProtocol(std::string input_str, std::string &result, const bool async_method, const unsigned int unique_id) 95 | { 96 | try 97 | { 98 | #ifdef DEBUG_TESTING 99 | extension_ptr->console->info("extDB2: SQL_RAW_V2: Trace: Input: {0}", input_str); 100 | #endif 101 | #ifdef DEBUG_LOGGING 102 | extension_ptr->logger->info("extDB2: SQL_RAW_V2: Trace: Input: {0}", input_str); 103 | #endif 104 | 105 | Poco::Data::Session session = extension_ptr->getDBSession_mutexlock(*database_ptr); 106 | Poco::Data::RecordSet rs(session, input_str); 107 | 108 | result = "[1,["; 109 | std::string temp_str; 110 | temp_str.reserve(result.capacity()); 111 | 112 | std::size_t cols = rs.columnCount(); 113 | if (cols >= 1) 114 | { 115 | bool more = rs.moveFirst(); 116 | if (more) 117 | { 118 | result += "["; 119 | while (more) 120 | { 121 | for (std::size_t col = 0; col < cols; ++col) 122 | { 123 | if (rs[col].isEmpty()) 124 | { 125 | temp_str.clear(); 126 | } 127 | else 128 | { 129 | temp_str = rs[col].convert(); 130 | } 131 | 132 | auto datatype = rs.columnType(col); 133 | if ((datatype == Poco::Data::MetaColumn::FDT_DATE) || (datatype == Poco::Data::MetaColumn::FDT_TIME) || (datatype == Poco::Data::MetaColumn::FDT_TIMESTAMP)) 134 | { 135 | if (temp_str.empty()) 136 | { 137 | result += "\"\""; 138 | } 139 | else 140 | { 141 | boost::erase_all(temp_str, "\""); 142 | result += "\"" + temp_str + "\""; 143 | } 144 | } 145 | else if ((stringDataTypeCheck) && (rs.columnType(col) == Poco::Data::MetaColumn::FDT_STRING)) 146 | { 147 | if (temp_str.empty()) 148 | { 149 | result += ("\"\""); 150 | } 151 | else 152 | { 153 | boost::erase_all(temp_str, "\""); 154 | result += "\"" + temp_str + "\""; 155 | } 156 | } 157 | else 158 | { 159 | if (temp_str.empty()) 160 | { 161 | result += "\"\""; 162 | } 163 | else 164 | { 165 | result += temp_str; 166 | } 167 | } 168 | 169 | if (col < (cols - 1)) 170 | { 171 | result += ","; 172 | } 173 | } 174 | more = rs.moveNext(); 175 | if (more) 176 | { 177 | result += "],["; 178 | } 179 | } 180 | result += "]"; 181 | } 182 | } 183 | result += "]]"; 184 | #ifdef DEBUG_TESTING 185 | extension_ptr->console->info("extDB2: SQL_RAW_V2: Trace: Result: {0}", result); 186 | #endif 187 | #ifdef DEBUG_LOGGING 188 | extension_ptr->logger->info("extDB2: SQL_RAW_V2: Trace: Result: {0}", result); 189 | #endif 190 | } 191 | catch (Poco::InvalidAccessException& e) 192 | { 193 | #ifdef DEBUG_TESTING 194 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error InvalidAccessException: {0}", e.displayText()); 195 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error InvalidAccessException: SQL: {0}", input_str); 196 | #endif 197 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error InvalidAccessException: {0}", e.displayText()); 198 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error InvalidAccessException: SQL: {0}", input_str); 199 | result = "[0,\"Error DBLocked Exception\"]"; 200 | } 201 | catch (Poco::Data::NotConnectedException& e) 202 | { 203 | #ifdef DEBUG_TESTING 204 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error NotConnectedException: {0}", e.displayText()); 205 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error NotConnectedException: SQL: {0}", input_str); 206 | #endif 207 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error NotConnectedException: {0}", e.displayText()); 208 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error NotConnectedException: SQL: {0}", input_str); 209 | result = "[0,\"Error DBLocked Exception\"]"; 210 | } 211 | catch (Poco::NotImplementedException& e) 212 | { 213 | #ifdef DEBUG_TESTING 214 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error NotImplementedException: {0}", e.displayText()); 215 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error NotImplementedException: SQL: {0}", input_str); 216 | 217 | #endif 218 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error NotImplementedException: {0}", e.displayText()); 219 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error NotImplementedException: SQL: {0}", input_str); 220 | result = "[0,\"Error DBLocked Exception\"]"; 221 | } 222 | catch (Poco::Data::SQLite::DBLockedException& e) 223 | { 224 | #ifdef DEBUG_TESTING 225 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error DBLockedException: {0}", e.displayText()); 226 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error DBLockedException: SQL: {0}", input_str); 227 | #endif 228 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error DBLockedException: {0}", e.displayText()); 229 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error DBLockedException: SQL: {0}", input_str); 230 | result = "[0,\"Error DBLocked Exception\"]"; 231 | } 232 | catch (Poco::Data::MySQL::ConnectionException& e) 233 | { 234 | #ifdef DEBUG_TESTING 235 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error ConnectionException: {0}", e.displayText()); 236 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error ConnectionException: SQL: {0}", input_str); 237 | #endif 238 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error ConnectionException: {0}", e.displayText()); 239 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error ConnectionException: SQL: {0}", input_str); 240 | result = "[0,\"Error Connection Exception\"]"; 241 | } 242 | catch(Poco::Data::MySQL::StatementException& e) 243 | { 244 | #ifdef DEBUG_TESTING 245 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error StatementException: {0}", e.displayText()); 246 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error StatementException: SQL: {0}", input_str); 247 | #endif 248 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error StatementException: {0}", e.displayText()); 249 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error StatementException: SQL: {0}", input_str); 250 | result = "[0,\"Error Statement Exception\"]"; 251 | } 252 | catch (Poco::Data::ConnectionFailedException& e) 253 | { 254 | #ifdef DEBUG_TESTING 255 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error ConnectionFailedException: {0}", e.displayText()); 256 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error ConnectionFailedException: SQL {0}", input_str); 257 | #endif 258 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error ConnectionFailedException: {0}", e.displayText()); 259 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error ConnectionFailedException: SQL {0}", input_str); 260 | result = "[0,\"Error ConnectionFailedException\"]"; 261 | } 262 | catch (Poco::Data::DataException& e) 263 | { 264 | #ifdef DEBUG_TESTING 265 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error DataException: {0}", e.displayText()); 266 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error DataException: SQL: {0}", input_str); 267 | #endif 268 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error DataException: {0}", e.displayText()); 269 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error DataException: SQL: {0}", input_str); 270 | result = "[0,\"Error Data Exception\"]"; 271 | } 272 | catch (Poco::Exception& e) 273 | { 274 | #ifdef DEBUG_TESTING 275 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error Exception: {0}", e.displayText()); 276 | extension_ptr->console->error("extDB2: SQL_RAW_V2: Error Exception: SQL: {0}", input_str); 277 | #endif 278 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error Exception: {0}", e.displayText()); 279 | extension_ptr->logger->error("extDB2: SQL_RAW_V2: Error Exception: SQL: {0}", input_str); 280 | result = "[0,\"Error Exception\"]"; 281 | } 282 | return true; 283 | } --------------------------------------------------------------------------------