Skip to content

Commit

Permalink
Merge branch 'main' into file-extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
GeckoEidechse authored Aug 19, 2024
2 parents b8e4ef0 + bebda79 commit 59c51b5
Show file tree
Hide file tree
Showing 46 changed files with 442 additions and 206 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)
14 changes: 8 additions & 6 deletions primedev/Northstar.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,8 @@ add_library(
"util/version.h"
"util/wininfo.cpp"
"util/wininfo.h"
"windows/libsys.cpp"
"windows/libsys.h"
"dllmain.cpp"
"ns_version.h"
"Northstar.def"
Expand All @@ -172,13 +174,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
89 changes: 8 additions & 81 deletions primedev/core/hooks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include <filesystem>
#include <Psapi.h>

#define XINPUT1_3_DLL "XInput1_3.dll"
namespace fs = std::filesystem;

AUTOHOOK_INIT()

Expand Down Expand Up @@ -104,7 +104,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 Expand Up @@ -388,87 +390,12 @@ void CallAllPendingDLLLoadCallbacks()
}
}

// clang-format off
AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExA, (LPVOID)LoadLibraryExA,
HMODULE, WINAPI, (LPCSTR lpLibFileName, HANDLE hFile, DWORD dwFlags))
// clang-format on
{
HMODULE moduleAddress;

LPCSTR lpLibFileNameEnd = lpLibFileName + strlen(lpLibFileName);
LPCSTR lpLibName = lpLibFileNameEnd - strlen(XINPUT1_3_DLL);

// replace xinput dll with one that has ASLR
if (lpLibFileName <= lpLibName && !strncmp(lpLibName, XINPUT1_3_DLL, strlen(XINPUT1_3_DLL) + 1))
{
moduleAddress = _LoadLibraryExA("XInput9_1_0.dll", hFile, dwFlags);

if (!moduleAddress)
{
MessageBoxA(0, "Could not find XInput9_1_0.dll", "Northstar", MB_ICONERROR);
exit(EXIT_FAILURE);

return nullptr;
}
}
else
moduleAddress = _LoadLibraryExA(lpLibFileName, hFile, dwFlags);

if (moduleAddress)
{
CallLoadLibraryACallbacks(lpLibFileName, moduleAddress);
g_pPluginManager->InformDllLoad(moduleAddress, fs::path(lpLibFileName));
}

return moduleAddress;
}

// clang-format off
AUTOHOOK_ABSOLUTEADDR(_LoadLibraryA, (LPVOID)LoadLibraryA,
HMODULE, WINAPI, (LPCSTR lpLibFileName))
// clang-format on
{
HMODULE moduleAddress = _LoadLibraryA(lpLibFileName);

if (moduleAddress)
CallLoadLibraryACallbacks(lpLibFileName, moduleAddress);

return moduleAddress;
}

// clang-format off
AUTOHOOK_ABSOLUTEADDR(_LoadLibraryExW, (LPVOID)LoadLibraryExW,
HMODULE, WINAPI, (LPCWSTR lpLibFileName, HANDLE hFile, DWORD dwFlags))
// clang-format on
{
HMODULE moduleAddress = _LoadLibraryExW(lpLibFileName, hFile, dwFlags);

if (moduleAddress)
CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress);

return moduleAddress;
}

// clang-format off
AUTOHOOK_ABSOLUTEADDR(_LoadLibraryW, (LPVOID)LoadLibraryW,
HMODULE, WINAPI, (LPCWSTR lpLibFileName))
// clang-format on
{
HMODULE moduleAddress = _LoadLibraryW(lpLibFileName);

if (moduleAddress)
{
CallLoadLibraryWCallbacks(lpLibFileName, moduleAddress);
g_pPluginManager->InformDllLoad(moduleAddress, fs::path(lpLibFileName));
}

return moduleAddress;
}

void InstallInitialHooks()
void HookSys_Init()
{
if (MH_Initialize() != MH_OK)
{
spdlog::error("MH_Initialize (minhook initialization) failed");

}
// todo: remove remaining instances of autohook in this file
AUTOHOOK_DISPATCH()
}
Loading

0 comments on commit 59c51b5

Please sign in to comment.