Skip to content

Commit

Permalink
Merge pull request #44 from mohabhassan/dev
Browse files Browse the repository at this point in the history
Wine support
  • Loading branch information
mohabhassan authored Jan 18, 2024
2 parents 7554684 + e88cede commit f19e11d
Show file tree
Hide file tree
Showing 18 changed files with 87 additions and 52 deletions.
11 changes: 6 additions & 5 deletions CrashReporter/CrashDummy/CrashDummy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,11 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
break;
case ID_LOADDBGBTN:
{
HANDLE hLocalProc = GetCurrentProcess();
HANDLE hGlobalProc;
//HANDLE hLocalProc = GetCurrentProcess();
DWORD pid = GetCurrentProcessId();
//HANDLE hGlobalProc;
WCHAR procPath[] = L"D:/nightfall/NightFall/CrashReporter/Release/CrashReporter.exe";

/*
if (!DuplicateHandle(hLocalProc,
hLocalProc,
hLocalProc,
Expand All @@ -220,7 +221,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
);
break;
}

*/
STARTUPINFO si;
PROCESS_INFORMATION pi;

Expand All @@ -230,7 +231,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

WCHAR cmdline[2048];
DWORD pollDelay = 5000, hungDelay = 30000;
wsprintf(cmdline, L"%s %p %u %u", procPath, hGlobalProc, pollDelay, hungDelay);
wsprintf(cmdline, L"%s %u %u %u", procPath, pid, pollDelay, hungDelay);
if (!CreateProcess(NULL, // No module name (use command line)
cmdline, // Command line
NULL, // Process handle not inheritable
Expand Down
3 changes: 3 additions & 0 deletions CrashReporter/CrashReporter/CrashReporter.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,9 @@
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>Dbghelp.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
<PostBuildEvent>
<Command>$(OutputPath)\copy,bat</Command>
</PostBuildEvent>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="..\src\main.cpp" />
Expand Down
45 changes: 30 additions & 15 deletions CrashReporter/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <thread>
#include <mutex>
#include "Dbghelp.h"
#include <fstream>
#include <locale>
Expand All @@ -12,6 +13,8 @@
#include <filesystem>
namespace fs = std::filesystem;
using std::thread;
using std::mutex;
using std::lock_guard;
using std::pair;
using std::ofstream;
using std::string;
Expand Down Expand Up @@ -39,8 +42,10 @@ inline std::string CurrDateTimeStr()
}

ofstream logfile(CRASHLOG_NAME, std::ofstream::out);
mutex logfile_mutex;
void PrintLog(const char* format, ...)
{
lock_guard<mutex> lock(logfile_mutex);
static int n = 256;
static char* buffer = new char[n];
va_list args;
Expand All @@ -61,6 +66,7 @@ void PrintLog(const char* format, ...)

void PrintLogW(const WCHAR* format, ...)
{
lock_guard<mutex> lock(logfile_mutex);
static int n = 256;
static WCHAR* wbuffer = new WCHAR[n];
static CHAR* buffer = new CHAR[n];
Expand Down Expand Up @@ -253,29 +259,46 @@ void HangLoop(HANDLE hProcess, DWORD dwTargetProcessId, DWORD pollDelay, DWORD h
}
}
}
bool IsWINE()

bool DebugLoop(HANDLE hProcess, DWORD dwTargetProcessId, DWORD pollDelay, DWORD hungDelay, bool &dumped)
{
HMODULE hmod = GetModuleHandleA("ntdll.dll");
if (!hmod)
return false;
if (!GetProcAddress(hmod, "wine_get_version"))
return false;
return true;

}

bool DebugLoop(DWORD dwTargetProcessId, DWORD pollDelay, DWORD hungDelay, bool &dumped)
{
DEBUG_EVENT de;
if (OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetProcessId) == NULL)
HANDLE hProcess;
PrintLog("OpenProcess\n");
bool is_wine = IsWINE();
if ((hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwTargetProcessId)) == NULL)
{
PrintLog("OpenProcess - FAILED: %u\n", GetLastError());
return false;
}
PrintLog("IsWINE: %u\n", is_wine);
BOOL bDbgrPresent;
PrintLog("CheckRemoteDebuggerPresent\n");
if (CheckRemoteDebuggerPresent(hProcess, &bDbgrPresent) && bDbgrPresent)
{
PrintLog("Remote debugger already present, exiting...\n");
return false;
}
PrintLog("DebugActiveProcess\n");
if (!DebugActiveProcess(dwTargetProcessId))
{
PrintLog("DebugActiveProcess - FAILED: %u\n", GetLastError());
return false;
}

PrintLog("Starting HangLoop thread\n");
thread(HangLoop, hProcess, dwTargetProcessId, pollDelay, hungDelay).detach();

PrintLog("Entering WaitForDebugEvent loop\n");
unsigned int numBPs = 0;
bool isHung;
dumped = false;
Expand Down Expand Up @@ -375,29 +398,21 @@ void CopyCrashFiles()


//pCmdLine: 134321524 5000 30000
// ^parent handle ^polling delay ^hung duration
// ^parent pid ^polling delay ^hung duration
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)
{
HANDLE hParent;
DWORD dwParentPID;
DWORD pollDelay, hungDelay;

if (swscanf_s(pCmdLine, L"%p %u %u", &hParent, &pollDelay, &hungDelay) != 3)
if (swscanf_s(pCmdLine, L"%u %u %u", &dwParentPID, &pollDelay, &hungDelay) != 3)
{
PrintLogW(L"Failed to parse CMDLine: %s", pCmdLine);
return -1;
}

dwParentPID = GetProcessId(hParent);
if (dwParentPID == 0)
{
PrintLog("GetProcessId - FAILED: %u\n", GetLastError());
return -2;
}

PrintLog("ParentPID: %u\n", dwParentPID);
bool dumped;
if (!DebugLoop(hParent, dwParentPID, pollDelay, hungDelay, dumped))
if (!DebugLoop(dwParentPID, pollDelay, hungDelay, dumped))
{
PrintLog("Ending crash reporter due to previous error.");
return -3;
Expand Down
2 changes: 1 addition & 1 deletion dgamexwrapper/BaseHeaders/Version.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#pragma once
#define PATCH_NAME "NightFall"
//don't remove this macro from this file as it's used in building/packaging scripts
#define PATCH_VERSION "1.2.0"
#define PATCH_VERSION "1.2.1"
#define PATCH_STAGE "stable"
17 changes: 10 additions & 7 deletions dgamexwrapper/src/HTTPClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ mutex HTTPClient::cv_mutex;//mutex for cv
atomic<HTTPClient::Status> HTTPClient::status;

list<QueuedClientRequest> HTTPClient::requests;
mutex HTTPClient::requests_mutex;//mutex for requests
//mutex HTTPClient::requests_mutex;//mutex for requests

list<QueuedClientResponse> HTTPClient::responses;
mutex HTTPClient::responses_mutex;//mutex for responses
Expand All @@ -29,22 +29,24 @@ void HTTPClient::HandleRequests()
{
if (status == CST_IDLE)
{
cv.wait(lk);
cv.wait(lk); // acquires the lock before returning
}

if (status == CST_NEWREQ)
{
QueuedClientRequest req;
{
lock_guard<mutex> lock(requests_mutex);
//lock_guard<mutex> lock(requests_mutex);
req = requests.front();
requests.pop_front();
if (!requests.size())
{
status = CST_IDLE;
}
}
lk.unlock();
CreateRequest(req);
lk.lock();
}
}
}
Expand Down Expand Up @@ -131,7 +133,8 @@ void HTTPClient::CreateRequest(QueuedClientRequest & req)
void HTTPClient::EnqueueResponse(QueuedClientRequest & req, string respStr, long http_code)
{
lock_guard<mutex> lock(responses_mutex);
responses.emplace_back(respStr, http_code, req.getScript(), req.getUserData());
if (status != CST_STOP)
responses.emplace_back(respStr, http_code, req.getScript(), req.getUserData());
}


Expand Down Expand Up @@ -179,7 +182,7 @@ void HTTPClient::Shutdown()
}
cv.notify_all();

lock_guard<mutex> lock2(requests_mutex);
lock_guard<mutex> lock2(cv_mutex);
requests.clear();
lock_guard<mutex> lock3(responses_mutex);
responses.clear();
Expand All @@ -194,13 +197,13 @@ bool HTTPClient::IsRunning()
void HTTPClient::CreateAPIRequest(string url, string method, ScriptVariable & script, ScriptVariable & user_data)
{
{
lock_guard<mutex> lock2(requests_mutex);
lock_guard<mutex> lock2(cv_mutex);
requests.emplace_back(url, method, script, user_data);
}

//auto start = chrono::high_resolution_clock::now();
{
lock_guard<mutex> lock1(cv_mutex);
//lock_guard<mutex> lock1(cv_mutex);
status = CST_NEWREQ;
}
cv.notify_all();
Expand Down
2 changes: 1 addition & 1 deletion dgamexwrapper/src/HTTPClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class HTTPClient
static atomic<Status> status;

static list<QueuedClientRequest> requests;
static mutex requests_mutex;//mutex for requests
//static mutex requests_mutex;//mutex for requests

static list<QueuedClientResponse> responses;
static mutex responses_mutex;//mutex for responses
Expand Down
11 changes: 7 additions & 4 deletions dgamexwrapper/src/dgamex86.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -563,13 +563,14 @@ void shutdownScriptHooks()
{
SV_Commands_Shutdown();

HTTPServer::Shutdown();
HTTPClient::Shutdown();

EntityNF::Shutdown();
PlayerNF::Shutdown();
ScriptThread::Shutdown();
ScriptedEvent::Shutdown();

HTTPServer::Shutdown();
HTTPClient::Shutdown();

LONG ret = DetourTransactionBegin();
ret = DetourUpdateThread(GetCurrentThread());
Expand Down Expand Up @@ -614,6 +615,7 @@ void startCrashReporter()
CustomCvar sv_crashrpt_poll_delay("sv_crashrpt_poll_delay", "5", CVAR_ARCHIVE);//in seconds
CustomCvar sv_crashrpt_hang_wait("sv_crashrpt_hang_wait", "30", CVAR_ARCHIVE);//in seconds

/*
HANDLE hLocalProc = GetCurrentProcess();
HANDLE hGlobalProc;
Expand All @@ -628,7 +630,8 @@ void startCrashReporter()
gi->Printf("Start crash reporter error 1: %u\n", GetLastError());
return;
}

*/
DWORD PID = GetCurrentProcessId();
STARTUPINFOW si;
PROCESS_INFORMATION pi;

Expand All @@ -639,7 +642,7 @@ void startCrashReporter()
auto crashRptPath = mainPath / "CrashReporter.exe";
WCHAR cmdline[2048];
DWORD pollDelay = sv_crashrpt_poll_delay.GetIntValue() * 1000, hungDelay = sv_crashrpt_hang_wait.GetIntValue() * 1000;
wsprintfW(cmdline, L"%s %p %u %u", crashRptPath.c_str(), hGlobalProc, pollDelay, hungDelay);
wsprintfW(cmdline, L"%s %u %u %u", crashRptPath.c_str(), PID, pollDelay, hungDelay);
if (!CreateProcessW(NULL, // No module name (use command line)
cmdline, // Command line
NULL, // Process handle not inheritable
Expand Down
Binary file modified tests/bot/MOHPC.dll
Binary file not shown.
Binary file modified tests/bot/Network.exe
Binary file not shown.
Binary file modified tests/bot/morfuse.dll
Binary file not shown.
5 changes: 3 additions & 2 deletions tests/bot_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,14 @@ def __del__(self):

def start_bot(self, *args):
try:
self.bot_process = subprocess.Popen([self.exe_path.as_posix(), '-t', self.server_port, *args], stdout=subprocess.PIPE, stdin=subprocess.PIPE, cwd=self.bot_path)
self.bot_process = subprocess.Popen([self.exe_path, '-t', self.server_port, *args], stdout=subprocess.PIPE, stdin=subprocess.PIPE, cwd=self.bot_path)
self.out_q = Queue()
self.stdout_thread_stop = Event()
self.stdout_thread = Thread(target=enqueue_output, args=(self.bot_process.stdout, self.out_q, self.stdout_thread_stop), daemon=True)
self.stdout_thread.start()
self.instance_id = BotManager.total_instances
BotManager.total_instances += 1
print('BotManager: start_bot: exe_path:', self.exe_path)
print('BotManager: start_bot: instance_id:', self.instance_id)
return True
except Exception as e:
Expand Down Expand Up @@ -191,5 +192,5 @@ def spawn(self, team=b'axis'):
self.send_command(b'set dm_playergermanmodel german_wehrmacht_soldier')
assert self.instance_id != -1
self.join_team(team)
time.sleep(1) #for spawn
time.sleep(5) #for spawn
print('BotManager: spawned:', team.decode())
17 changes: 13 additions & 4 deletions tests/game_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ def __init__(self, game='bt', game_ver='2.40', gamepath='D:/nightfall/game/serve
self.game_ver = game_ver
self.port = port
self.gamespy_port = str(int(port)+97)
self.sv_api_ports = str(int(port)+80)
self.game_path = Path(gamepath)
self.main_path = self.game_path / self.game_main_name[self.game]
self.mode = mode
Expand All @@ -25,15 +26,20 @@ def start_game(self):
return True
SW_MINIMIZE = 6
SW_SHOWMINNOACTIVE = 7
info = subprocess.STARTUPINFO()
info.dwFlags = subprocess.STARTF_USESHOWWINDOW
info.wShowWindow = SW_SHOWMINNOACTIVE
if os.name != 'nt':
info = None
else:
info = subprocess.STARTUPINFO()
info.dwFlags = subprocess.STARTF_USESHOWWINDOW
info.wShowWindow = SW_SHOWMINNOACTIVE
print('net_port:', self.port)
args = [self.exe_path.as_posix()]
if self.mode == 'client':
args += ['+set', 'dedicated', '1']

args += ['+set', 'developer', '2', '+set', 'net_port', self.port, '+set', 'net_gamespy_port', self.gamespy_port, "+exec", "server_nf.cfg"]
args += ['+set', 'developer', '2', '+set', 'net_port', self.port, '+set', 'net_gamespy_port', self.gamespy_port, '+set', 'sv_api_ports', self.sv_api_ports, "+exec", "server_nf.cfg"]
# if os.name != 'nt':
# args = ['winedbg'] + args
self.game_process = subprocess.Popen(args, cwd=self.game_path, startupinfo=info)
return True
except Exception as e:
Expand Down Expand Up @@ -63,6 +69,9 @@ def wait_for_game_exit(self):
def game_shortname(self):
return self.game

def game_sv_api_ports(self):
return self.sv_api_ports

def mainpath(self):
return self.main_path

Expand Down
8 changes: 4 additions & 4 deletions tests/libs/Build instructions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ cd morfuse
mkdir cmake
cd cmake
cmake -DFLEX_EXECUTABLE="..\..\win_flex_bison-2.5.25\win_flex.exe" -DBISON_EXECUTABLE="..\..\win_flex_bison-2.5.25\win_bison.exe" -DFLEX_INCLUDE_DIR="..\..\win_flex_bison-2.5.25\" -DCMAKE_BUILD_TYPE=Release -A Win32 ..\
cmake --build . --config RelWithDebInfo
cmake --install . --config RelWithDebInfo
cmake --build . --config Release #RelWithDebInfo
cmake --install . --config Release #RelWithDebInfo
cd ../../
mohpc:
clone https://github.com/moh-rises/mohpc.git
clone https://github.com/mohabhassan/mohpc.git
cd mohpc
cd thirdparty

Expand Down Expand Up @@ -52,6 +52,6 @@ mkdir build
cd build

cmake -A Win32 ..\
cmake --build . --config RelWithDebInfo
cmake --build . --config Release # or use RelWithDebInfo

copy mohpc.dll and morfuse.dll to same directory as Network.exe
2 changes: 1 addition & 1 deletion tests/tests/test_clientadmin.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ def test_ad_timelimit(self, game_manager, file_manager, rcon_manager, bot_manage
timelimit = int(timelimit)
timelimit = max(timelimit+1, 7)
bot_manager.send_command(b'ad_timelimit ' + str(timelimit).encode())
time.sleep(1) # so cvar change can be executed
time.sleep(5) # so cvar change can be executed
assert rcon_manager.get_cvar_value(b'timelimit') == str(timelimit)

def test_ad_gametype(self, game_manager, file_manager, rcon_manager, bot_manager):
Expand Down
Loading

0 comments on commit f19e11d

Please sign in to comment.