Skip to content

Commit

Permalink
Merge branch 'main' into feat/whitelist-safeio-file-extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
GeckoEidechse authored Aug 9, 2024
2 parents 59d19a8 + a28c1cb commit d679e05
Show file tree
Hide file tree
Showing 43 changed files with 273 additions and 120 deletions.
18 changes: 13 additions & 5 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,17 @@ env:
jobs:
build:
runs-on: windows-2022
strategy:
matrix:
config:
- { name: "MSVC", cc: cl }
- { name: "LLVM", cc: clang-cl }
env:
CC: ${{ matrix.config.cc }}
CXX: ${{ matrix.config.cc }}
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
submodules: 'true'
- name: Setup msvc
Expand All @@ -31,16 +39,16 @@ jobs:
shell: bash
run: echo commit=$(git rev-parse --short HEAD) >> $GITHUB_OUTPUT
- name: Upload Build Artifact
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v4
with:
name: NorthstarLauncher-${{ steps.extract.outputs.commit }}
name: NorthstarLauncher-${{ matrix.config.name }}-${{ steps.extract.outputs.commit }}
path: |
game/
format-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: DoozyX/[email protected]
with:
source: 'primedev'
Expand All @@ -52,7 +60,7 @@ jobs:
format-check-cmake-files:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: puneetmatharu/[email protected]
with:
args: "--in-place"
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/merge-conflict-auto-label.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
name: Merge Conflict Auto Label
on:
workflow_dispatch: # Manual run
push:
branches:
- main
schedule:
- cron: "10 21 * * *"
- cron: "10 21 * * *" # Runs at 21:10; time was chosen based on contributor activity and low GitHub Actions cron load.

jobs:
triage:
Expand Down
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
cmake_minimum_required(VERSION 3.15)
cmake_policy(
SET
CMP0091
NEW
)

project(
Northstar
Expand All @@ -20,6 +25,9 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_C_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_VS_PLATFORM_TOOLSET v143)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
# Deal with MSVC incompatiblity
add_compile_definitions(_DISABLE_CONSTEXPR_MUTEX_CONSTRUCTOR)

# This determines the real binary root directory
set(NS_BINARY_DIR ${CMAKE_BINARY_DIR}/game)
Expand Down
2 changes: 1 addition & 1 deletion primedev/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
include(Northstar.cmake)
include(Launcher.cmake)
add_subdirectory(primelauncher)
add_subdirectory(wsockproxy)
12 changes: 6 additions & 6 deletions primedev/Northstar.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -172,13 +172,13 @@ target_link_libraries(
libcurl
minizip
silver-bun
WS2_32.lib
Crypt32.lib
Cryptui.lib
ws2_32.lib
crypt32.lib
cryptui.lib
dbghelp.lib
Wldap32.lib
Normaliz.lib
Bcrypt.lib
wldap32.lib
normaliz.lib
bcrypt.lib
version.lib
)

Expand Down
33 changes: 30 additions & 3 deletions primedev/client/audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include <iostream>
#include <sstream>
#include <random>
#include <ranges>

namespace fs = std::filesystem;

AUTOHOOK_INIT()

Expand All @@ -28,7 +31,7 @@ unsigned char EMPTY_WAVE[45] = {0x52, 0x49, 0x46, 0x46, 0x25, 0x00, 0x00, 0x00,
0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x44, 0xAC, 0x00, 0x00, 0x88, 0x58,
0x01, 0x00, 0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x74, 0x00, 0x00, 0x00, 0x00};

EventOverrideData::EventOverrideData(const std::string& data, const fs::path& path)
EventOverrideData::EventOverrideData(const std::string& data, const fs::path& path, const std::vector<std::string>& registeredEvents)
{
if (data.length() <= 0)
{
Expand Down Expand Up @@ -191,6 +194,14 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
{
std::string pathString = file.path().string();

// Retrieve event id from path (standard?)
std::string eventId = file.path().parent_path().filename().string();
if (std::find(registeredEvents.begin(), registeredEvents.end(), eventId) != registeredEvents.end())
{
spdlog::warn("{} couldn't be loaded because {} event has already been overrided, skipping.", pathString, eventId);
continue;
}

// Open the file.
std::ifstream wavStream(pathString, std::ios::binary);

Expand Down Expand Up @@ -259,7 +270,7 @@ EventOverrideData::EventOverrideData(const std::string& data, const fs::path& pa
LoadedSuccessfully = true;
}

bool CustomAudioManager::TryLoadAudioOverride(const fs::path& defPath)
bool CustomAudioManager::TryLoadAudioOverride(const fs::path& defPath, std::string modName)
{
if (IsDedicatedServer())
return true; // silently fail
Expand All @@ -279,19 +290,35 @@ bool CustomAudioManager::TryLoadAudioOverride(const fs::path& defPath)

jsonStream.close();

std::shared_ptr<EventOverrideData> data = std::make_shared<EventOverrideData>(jsonStringStream.str(), defPath);
// Pass the list of overriden events to avoid multiple event registrations crash
auto kv = std::views::keys(m_loadedAudioOverrides);
std::vector<std::string> keys {kv.begin(), kv.end()};
std::shared_ptr<EventOverrideData> data = std::make_shared<EventOverrideData>(jsonStringStream.str(), defPath, keys);

if (!data->LoadedSuccessfully)
return false; // no logging, the constructor has probably already logged

for (const std::string& eventId : data->EventIds)
{
if (m_loadedAudioOverrides.contains(eventId))
{
spdlog::warn("\"{}\" mod tried to override sound event \"{}\" but it is already overriden, skipping.", modName, eventId);
continue;
}
spdlog::info("Registering sound event {}", eventId);
m_loadedAudioOverrides.insert({eventId, data});
}

for (const auto& eventIdRegexData : data->EventIdsRegex)
{
if (m_loadedAudioOverridesRegex.contains(eventIdRegexData.first))
{
spdlog::warn(
"\"{}\" mod tried to override sound event regex \"{}\" but it is already overriden, skipping.",
modName,
eventIdRegexData.first);
continue;
}
spdlog::info("Registering sound event regex {}", eventIdRegexData.first);
m_loadedAudioOverridesRegex.insert({eventIdRegexData.first, data});
}
Expand Down
6 changes: 4 additions & 2 deletions primedev/client/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include <regex>
#include <shared_mutex>

namespace fs = std::filesystem;

enum class AudioSelectionStrategy
{
INVALID = -1,
Expand All @@ -15,7 +17,7 @@ enum class AudioSelectionStrategy
class EventOverrideData
{
public:
EventOverrideData(const std::string&, const fs::path&);
EventOverrideData(const std::string&, const fs::path&, const std::vector<std::string>& registeredEvents);
EventOverrideData();

public:
Expand All @@ -35,7 +37,7 @@ class EventOverrideData
class CustomAudioManager
{
public:
bool TryLoadAudioOverride(const fs::path&);
bool TryLoadAudioOverride(const fs::path&, std::string modName);
void ClearAudioOverrides();

std::shared_mutex m_loadingMutex;
Expand Down
4 changes: 3 additions & 1 deletion primedev/client/languagehooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
#include <filesystem>
#include <regex>

namespace fs = std::filesystem;

AUTOHOOK_INIT()

typedef LANGID (*Tier0_DetectDefaultLanguageType)();
Expand Down Expand Up @@ -41,7 +43,7 @@ std::vector<std::string> file_list(fs::path dir, std::regex ext_pattern)
std::string GetAnyInstalledAudioLanguage()
{
for (const auto& lang : file_list("r2\\sound\\", std::regex(".*?general_([a-z]+)_patch_1\\.mstr")))
if (lang != "general" || lang != "")
if (lang != "general" && lang != "" && lang != "stream")
return lang;
return "NO LANGUAGE DETECTED";
}
Expand Down
4 changes: 2 additions & 2 deletions primedev/client/latencyflex.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ ON_DLL_LOAD_CLIENT_RELIESON("client.dll", LatencyFlex, ConVar, (CModule module))
// https://ishitatsuyuki.github.io/post/latencyflex/
HMODULE pLfxModule;

if (pLfxModule = LoadLibraryA("latencyflex_layer.dll"))
if ((pLfxModule = LoadLibraryA("latencyflex_layer.dll")))
m_winelfx_WaitAndBeginFrame =
reinterpret_cast<void (*)()>(reinterpret_cast<void*>(GetProcAddress(pLfxModule, "lfx_WaitAndBeginFrame")));
else if (pLfxModule = LoadLibraryA("latencyflex_wine.dll"))
else if ((pLfxModule = LoadLibraryA("latencyflex_wine.dll")))
m_winelfx_WaitAndBeginFrame =
reinterpret_cast<void (*)()>(reinterpret_cast<void*>(GetProcAddress(pLfxModule, "winelfx_WaitAndBeginFrame")));
else
Expand Down
6 changes: 5 additions & 1 deletion primedev/core/hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#define XINPUT1_3_DLL "XInput1_3.dll"

namespace fs = std::filesystem;

AUTOHOOK_INIT()

// called from the ON_DLL_LOAD macros
Expand Down Expand Up @@ -104,7 +106,9 @@ bool ManualHook::Dispatch(LPVOID addr, LPVOID* orig)
if (orig)
ppOrigFunc = orig;

if (MH_CreateHook(addr, pHookFunc, ppOrigFunc) == MH_OK)
if (!addr)
spdlog::error("Address for hook {} is invalid", pFuncName);
else if (MH_CreateHook(addr, pHookFunc, ppOrigFunc) == MH_OK)
{
if (MH_EnableHook(addr) == MH_OK)
{
Expand Down
4 changes: 3 additions & 1 deletion primedev/core/hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,9 @@ class __autohook
}
}

if (MH_CreateHook(targetAddr, pHookFunc, ppOrigFunc) == MH_OK)
if (!targetAddr)
spdlog::error("Address for hook {} is invalid", pFuncName);
else if (MH_CreateHook(targetAddr, pHookFunc, ppOrigFunc) == MH_OK)
{
if (MH_EnableHook(targetAddr) == MH_OK)
spdlog::info("Enabling hook {}", pFuncName);
Expand Down
36 changes: 31 additions & 5 deletions primedev/core/memalloc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

// TODO: rename to malloc and free after removing statically compiled .libs

extern "C" void* _malloc_base(size_t n)
void* _malloc_base(size_t n)
{
// allocate into static buffer if g_pMemAllocSingleton isn't initialised
if (!g_pMemAllocSingleton)
Expand All @@ -17,23 +17,23 @@ extern "C" void* _malloc_base(size_t n)
return _malloc_base(n);
}*/

extern "C" void _free_base(void* p)
void _free_base(void* p)
{
if (!g_pMemAllocSingleton)
TryCreateGlobalMemAlloc();

g_pMemAllocSingleton->m_vtable->Free(g_pMemAllocSingleton, p);
}

extern "C" void* _realloc_base(void* oldPtr, size_t size)
void* _realloc_base(void* oldPtr, size_t size)
{
if (!g_pMemAllocSingleton)
TryCreateGlobalMemAlloc();

return g_pMemAllocSingleton->m_vtable->Realloc(g_pMemAllocSingleton, oldPtr, size);
}

extern "C" void* _calloc_base(size_t n, size_t size)
void* _calloc_base(size_t n, size_t size)
{
size_t bytes = n * size;
void* memory = _malloc_base(bytes);
Expand All @@ -44,7 +44,33 @@ extern "C" void* _calloc_base(size_t n, size_t size)
return memory;
}

extern "C" char* _strdup_base(const char* src)
void* _recalloc_base(void* const block, size_t const count, size_t const size)
{
if (!block)
return _calloc_base(count, size);

const size_t new_size = count * size;
const size_t old_size = _msize(block);

void* const memory = _realloc_base(block, new_size);

if (memory && old_size < new_size)
{
memset(static_cast<char*>(memory) + old_size, 0, new_size - old_size);
}

return memory;
}

size_t _msize(void* const block)
{
if (!g_pMemAllocSingleton)
TryCreateGlobalMemAlloc();

return g_pMemAllocSingleton->m_vtable->GetSize(g_pMemAllocSingleton, block);
}

char* _strdup_base(const char* src)
{
char* str;
char* p;
Expand Down
16 changes: 10 additions & 6 deletions primedev/core/memalloc.h
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
#pragma once

#include <malloc.h>

#include "rapidjson/document.h"
// #include "include/rapidjson/allocators.h"

extern "C" void* _malloc_base(size_t size);
extern "C" void* _calloc_base(size_t const count, size_t const size);
extern "C" void* _realloc_base(void* block, size_t size);
extern "C" void* _recalloc_base(void* const block, size_t const count, size_t const size);
extern "C" void _free_base(void* const block);
extern "C" char* _strdup_base(const char* src);
// The prelude is needed for these to be usable by the CRT
extern "C" __declspec(noinline) void* __cdecl _malloc_base(size_t const size);
extern "C" __declspec(noinline) void* __cdecl _calloc_base(size_t const count, size_t const size);
extern "C" __declspec(noinline) void* __cdecl _realloc_base(void* const block, size_t const size);
extern "C" __declspec(noinline) void* __cdecl _recalloc_base(void* const block, size_t const count, size_t const size);
extern "C" __declspec(noinline) void __cdecl _free_base(void* const block);
extern "C" __declspec(noinline) size_t __cdecl _msize(void* const block);
extern "C" __declspec(noinline) char* __cdecl _strdup_base(const char* src);

void* operator new(size_t n);
void operator delete(void* p) noexcept;
Expand Down
2 changes: 1 addition & 1 deletion primedev/dedicated/dedicatedlogtoclient.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
class DedicatedServerLogToClientSink : public CustomSink
{
protected:
void custom_sink_it_(const custom_log_msg& msg);
void custom_sink_it_(const custom_log_msg& msg) override;
void sink_it_(const spdlog::details::log_msg& msg) override;
void flush_() override;
};
6 changes: 1 addition & 5 deletions primedev/logging/logging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,11 +124,7 @@ void CustomSink::custom_log(const custom_log_msg& msg)

void InitialiseConsole()
{
if (AllocConsole() == FALSE)
{
std::cout << "[*] Failed to create a console window, maybe a console already exists?" << std::endl;
}
else
if (AllocConsole() != FALSE)
{
freopen("CONOUT$", "w", stdout);
freopen("CONOUT$", "w", stderr);
Expand Down
Loading

0 comments on commit d679e05

Please sign in to comment.