Skip to content

Commit

Permalink
Open-source release for Rocket Plugin 0.6.8.
Browse files Browse the repository at this point in the history
- Add nullcheck marco's everywhere.
- Changed the log marco names to avoid conflicts.
- Added Notifier to clear physics cache.
- Upgraded to c++20.
- Rewrote CrazyRumble.
- Split RocketPlugin.cpp into modules.
- Split ExternalFunctions.cpp into external modules.
- Added colored logs.
  • Loading branch information
Stanbroek committed Sep 19, 2021
1 parent 39d5fc7 commit ec31a52
Show file tree
Hide file tree
Showing 78 changed files with 5,326 additions and 5,035 deletions.

Large diffs are not rendered by default.

53 changes: 26 additions & 27 deletions source/External/BakkesModAdditions/include/utils/exception_safety.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,26 +16,26 @@
//})

#define LOG_EXCEPTIONS(desc, msg, trace) \
LOG("=== Critical error: ===\n{}\n{}\n\n{}", desc, msg, trace)
BM_LOG("=== Critical error: ===\n{:s}\n{:s}\n\n{:s}", desc, msg, trace)

#define CATCH_EXCEPTIONS(desc) \
catch (const std::exception& e) { \
try { \
LOG_EXCEPTIONS(desc, e.what(), StackWalkerBM().DumpCallStack()); \
} \
catch (...) { CRITICAL_LOG("Failed to get callstack {}", e.what()); } \
catch (...) { BM_CRITICAL_LOG("Failed to get callstack {:s}", e.what()); } \
} \
catch (const SE_Exception& e) { \
try { \
LOG_EXCEPTIONS(desc, e.getSeMessage(), StackWalkerBM().DumpCallStack(e.GetExceptionPointers())); \
} \
catch (...) { CRITICAL_LOG("Failed to get callstack {}", e.getSeMessage()); } \
catch (...) { BM_CRITICAL_LOG("Failed to get callstack {:s}", e.getSeMessage()); } \
} \
catch (...) { \
try { \
LOG_EXCEPTIONS(desc, "Unknown exception", StackWalkerBM().DumpCallStack()); \
} \
catch (...) { CRITICAL_LOG("Failed to get callstack"); } \
catch (...) { BM_CRITICAL_LOG("Failed to get callstack"); } \
}

#define TRY_CATCH_EXCEPTIONS(body, desc) \
Expand All @@ -47,22 +47,22 @@

inline void Nothing(void*) {}

inline int LogCallStack(const std::string& desc, PEXCEPTION_POINTERS pExceptionPointers)
static inline int LogCallStack(const std::string& desc, PEXCEPTION_POINTERS pExceptionPointers)
{
if (pExceptionPointers == nullptr || pExceptionPointers->ExceptionRecord == nullptr) {
CRITICAL_LOG("could not get the exception record");
BM_CRITICAL_LOG("could not get the exception record");
return EXCEPTION_CONTINUE_SEARCH;
}

const DWORD exceptionCode = pExceptionPointers->ExceptionRecord->ExceptionCode;
std::string exceptionMessage = GetExceptionMessage(exceptionCode);
const std::string exceptionCallStack = StackWalkerBM().DumpCallStack(pExceptionPointers);
const std::string exceptionCallStack = to_string(StackWalkerBM().DumpCallStack(pExceptionPointers));

if (exceptionMessage.empty()) {
try {
// MSVC exception ptr hack.
// https://github.com/microsoft/STL/blob/68b344c9dcda6ddf1a8fca112cb9033f9e50e787/stl/src/excptptr.cpp#L476
auto exceptionRecord = std::shared_ptr<const EXCEPTION_RECORD>(pExceptionPointers->ExceptionRecord, Nothing);
const auto exceptionRecord = std::shared_ptr<const EXCEPTION_RECORD>(pExceptionPointers->ExceptionRecord, Nothing);
__ExceptionPtrRethrow(&exceptionRecord);
}
catch (const std::exception& e) {
Expand Down Expand Up @@ -92,25 +92,24 @@ inline int LogCallStack(const std::string& desc, PEXCEPTION_POINTERS pExceptionP
}

template<typename Func>
inline bool GuardedFunction(const std::string& desc, Func lambda)
static inline bool GuardedFunction(const std::string& desc, Func lambda)
{
__try {
lambda();
return true;
}
__except (LogCallStack(desc, GetExceptionInformation())) {
MessageBox(NULL,
"Addional info should be provided in the F6 console.\n"
"A crashdump should be located in \"%appdata%\\bakkesmod\\bakkesmod\\crashes\".\n"
"You can continue to use BakkesMod and Rocket Plugin.",
"Rocket Plugin Error", MB_OK | MB_ICONERROR);
TEXT("Addional info should be provided in the F6 console.\n")
TEXT("A crashdump should be located in \"%appdata%\\bakkesmod\\bakkesmod\\crashes\"."),
TEXT("Rocket Plugin Error"), MB_OK | MB_ICONERROR);
}

return false;
}

#define TRY_EXCEPT(desc, body, args) \
if (GuardedFunction(desc, [&]() { body(args); })) return;
if (GuardedFunction(desc, [&]() { body(args); })) { return; }

#define CATCH_FUNCTION(func, body, args, desc, before, after) \
func \
Expand All @@ -125,10 +124,10 @@ inline bool GuardedFunction(const std::string& desc, Func lambda)
CATCH_FUNCTION(funcOverride, body, args, desc, before, after) \
func

#define CATCH_ONLOAD \
CATCH_OVERRIDE_FUNCTION(void onLoad(), void OnLoad(), OnLoad, \
, "Game thread exception:", SET_SE_TRANSLATOR;, \
cvarManager->executeCommand("plugin unload RocketPlugin");)
#define CATCH_ONLOAD \
CATCH_OVERRIDE_FUNCTION(void onLoad(), void OnLoad(), OnLoad, \
, "Game thread exception:", SET_SE_TRANSLATOR;, \
cvarManager->executeCommand("sleep 100; plugin unload RocketPlugin");)

#define CATCH_ONUNLOAD \
CATCH_OVERRIDE_FUNCTION(void onUnload(), void OnUnload(), OnUnload, \
Expand All @@ -141,9 +140,9 @@ inline bool GuardedFunction(const std::string& desc, Func lambda)
ImGui::GetStateStorage()->Clear(); \
ImGui::NewFrame();)

#define CATCH_RENDER_SETTINGS \
CATCH_OVERRIDE_FUNCTION(void RenderSettings(), void OnRenderSettings(), OnRenderSettings, \
, "Rendering thread exception:", SET_SE_TRANSLATOR;, \
#define CATCH_RENDER_SETTINGS \
CATCH_OVERRIDE_FUNCTION(void RenderSettings(), void OnRenderSettings(), OnRenderSettings, \
, "Rendering thread exception:", SET_SE_TRANSLATOR;, \
cvarManager->executeCommand("closemenu settings");)

#define CATCH_HOOK_EVENT \
Expand All @@ -166,19 +165,19 @@ inline bool GuardedFunction(const std::string& desc, Func lambda)
callback, caller COMMA_ params COMMA_ _eventName, + quote(eventName) + ", Game thread exception:", \
gameWrapper->HookEventWithCallerPost<T> LPARENT_ eventName COMMA_ [=](T caller, void* params, const std::string& _eventName) LBRACKET_, RBRACKET_ RPARENT_;)

#define CATCH_SET_TIMEOUT \
CATCH_FUNCTION(void SetTimeout(const std::function<void(GameWrapper*)>& theLambda, float time) const, \
theLambda, gw, "Game thread exception:", \
#define CATCH_SET_TIMEOUT \
CATCH_FUNCTION(void SetTimeout(const std::function<void(GameWrapper*)>& theLambda, const float time) const, \
theLambda, gw, "Game thread exception:", \
gameWrapper->SetTimeout LPARENT_ [=](GameWrapper* gw) LBRACKET_, RBRACKET_ COMMA_ time RPARENT_;)

#define CATCH_EXECUTE \
CATCH_FUNCTION(void Execute(const std::function<void(GameWrapper*)>& theLambda) const, \
theLambda, gw, "Game thread exception:", \
gameWrapper->Execute LPARENT_ [=](GameWrapper* gw) LBRACKET_, RBRACKET_ RPARENT_;)

#define CATCH_REGISTER_NOTIFIER \
CATCH_FUNCTION(void RegisterNotifier(const std::string& cvar, const std::function<void(std::vector<std::string>)>& notifier, const std::string& description, unsigned char permissions) const, \
notifier, arguments, + quote(cvar) + ", Game thread exception:", \
#define CATCH_REGISTER_NOTIFIER \
CATCH_FUNCTION(void RegisterNotifier(const std::string& cvar, const std::function<void(std::vector<std::string>)>& notifier, const std::string& description, const unsigned char permissions) const, \
notifier, arguments, + quote(cvar) + ", Game thread exception:", \
cvarManager->registerNotifier LPARENT_ cvar COMMA_ [=](const std::vector<std::string>& arguments) LBRACKET_, RBRACKET_ COMMA_ description COMMA_ permissions RPARENT_;)

#define CATCH_DEFAULT_BM_FUNCTIONS \
Expand Down
54 changes: 54 additions & 0 deletions source/External/BakkesModAdditions/include/utils/filesystem.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#pragma once
#include <string>
#include <vector>
#include <algorithm>
#include <filesystem>


static inline bool has_extension(const std::string& fileExtension, const std::vector<std::string>& extensions)
{
// Filter out unwanted file extensions.
return std::ranges::any_of(extensions, [&](const std::string& extension) {
return fileExtension == extension;
});
}


static inline std::vector<std::filesystem::path> iterate_directory(const std::filesystem::path& directory,
const std::vector<std::string>& extensions, const int depth = 0, const int maxDepth = 3)
{
if (depth > maxDepth) {
return std::vector<std::filesystem::path>();
}

std::vector<std::filesystem::path> files;
for (const std::filesystem::directory_entry& file : std::filesystem::directory_iterator(directory)) {
const std::filesystem::path& filePath = file.path();
if (file.is_directory()) {
std::vector<std::filesystem::path> directoryFiles = iterate_directory(
filePath, extensions, depth + 1, maxDepth);
// Remove if directory is empty.
if (!directoryFiles.empty()) {
files.insert(files.end(), directoryFiles.begin(), directoryFiles.end());
}
}
else if (has_extension(filePath.extension().string(), extensions)) {
files.push_back(filePath);
}
}

return files;
}


template<class... TArgs, typename = std::enable_if_t<std::conjunction_v<std::is_convertible<TArgs, std::string>...>>>
static inline std::vector<std::filesystem::path> get_files_from_dir(const std::filesystem::path& directory, const int maxDepth, const TArgs... extension)
{
if (!exists(directory)) {
return std::vector<std::filesystem::path>();
}

const std::vector<std::string> fileExtensions = { extension... };

return iterate_directory(directory, fileExtensions, 0, maxDepth);
}
170 changes: 85 additions & 85 deletions source/External/BakkesModAdditions/include/utils/parser_w.h
Original file line number Diff line number Diff line change
@@ -1,85 +1,85 @@
#pragma once
#include <string>
#include <vector>
#include <algorithm>


/*
* Wide string parser equivalents.
*/

// Checks if the given string starts with given string.
inline bool string_starts_with(const std::wstring& wstr, const std::wstring& begin)
{
return wstr.compare(0, begin.length(), begin) == 0;
}


// Splits the string by delimiter.
inline size_t split(const std::wstring& wstr, std::vector<std::wstring>& wstrs, const wchar_t delimiter)
{
size_t pos = wstr.find(delimiter);
size_t initialPos = 0;
wstrs.clear();

// Decompose statement.
while (pos != std::string::npos) {
wstrs.push_back(wstr.substr(initialPos, pos - initialPos));
initialPos = pos + 1;

pos = wstr.find(delimiter, initialPos);
}

// Add the last one.
wstrs.push_back(wstr.substr(initialPos, std::min(pos, wstr.size()) - initialPos));

return wstrs.size();
}


// Trim from start.
inline std::wstring& ltrim(std::wstring& wstr) {
wstr.erase(wstr.begin(), std::find_if(wstr.begin(), wstr.end(), [](const int wc) {
return !std::isspace(wc);
}));

return wstr;
}


// Trim from end.
inline std::wstring& rtrim(std::wstring& wstr) {
wstr.erase(std::find_if(wstr.rbegin(), wstr.rend(), [](const int wc) {
return !std::isspace(wc);
}).base(), wstr.end());

return wstr;
}


// Trim from both ends.
inline std::wstring& trim(std::wstring& wstr) {
return ltrim(rtrim(wstr));
}


// Replaces the first occurrence with the other string.
inline bool replace(std::wstring& wstr, const std::wstring& from, const std::wstring& to) {
const size_t start_pos = wstr.find(from);
if (start_pos == std::string::npos) {
return false;
}
wstr.replace(start_pos, from.length(), to);

return true;
}


// Replaces all occurrences with the other string.
inline void replace_all(std::wstring& wstr, const std::wstring& from, const std::wstring& to) {
size_t start_pos = wstr.find(from);
while (start_pos != std::string::npos) {
wstr.replace(start_pos, from.length(), to);
start_pos = wstr.find(from);
}
}
#pragma once
#include <string>
#include <vector>
#include <algorithm>


/*
* Wide string parser equivalents.
*/

// Checks if the given string starts with given string.
inline bool string_starts_with(const std::wstring& wstr, const std::wstring& begin)
{
return wstr.compare(0, begin.length(), begin) == 0;
}


// Splits the string by delimiter.
inline size_t split(const std::wstring& wstr, std::vector<std::wstring>& wstrs, const wchar_t delimiter)
{
size_t pos = wstr.find(delimiter);
size_t initialPos = 0;
wstrs.clear();

// Decompose statement.
while (pos != std::string::npos) {
wstrs.push_back(wstr.substr(initialPos, pos - initialPos));
initialPos = pos + 1;

pos = wstr.find(delimiter, initialPos);
}

// Add the last one.
wstrs.push_back(wstr.substr(initialPos, std::min(pos, wstr.size()) - initialPos));

return wstrs.size();
}


// Trim from start.
inline std::wstring& ltrim(std::wstring& wstr) {
wstr.erase(wstr.begin(), std::find_if(wstr.begin(), wstr.end(), [](const int wc) {
return !std::isspace(wc);
}));

return wstr;
}


// Trim from end.
inline std::wstring& rtrim(std::wstring& wstr) {
wstr.erase(std::find_if(wstr.rbegin(), wstr.rend(), [](const int wc) {
return !std::isspace(wc);
}).base(), wstr.end());

return wstr;
}


// Trim from both ends.
inline std::wstring& trim(std::wstring& wstr) {
return ltrim(rtrim(wstr));
}


// Replaces the first occurrence with the other string.
inline bool replace(std::wstring& wstr, const std::wstring& from, const std::wstring& to) {
const size_t start_pos = wstr.find(from);
if (start_pos == std::string::npos) {
return false;
}
wstr.replace(start_pos, from.length(), to);

return true;
}


// Replaces all occurrences with the other string.
inline void replace_all(std::wstring& wstr, const std::wstring& from, const std::wstring& to) {
size_t start_pos = wstr.find(from);
while (start_pos != std::string::npos) {
wstr.replace(start_pos, from.length(), to);
start_pos = wstr.find(from);
}
}
Loading

0 comments on commit ec31a52

Please sign in to comment.