Skip to content

Commit

Permalink
Merge pull request #34 from lonemeow/improve-logs
Browse files Browse the repository at this point in the history
Add support for saving logs to file
  • Loading branch information
lonemeow authored Jun 22, 2024
2 parents 60d2a48 + 13f3675 commit 52edc18
Show file tree
Hide file tree
Showing 8 changed files with 87 additions and 16 deletions.
22 changes: 11 additions & 11 deletions client-gui/ACCHook.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ public static string FindHookDLL() {
var exeLocation = Path.GetDirectoryName(Path.GetFullPath(Application.ExecutablePath));
foreach (var loc in HOOK_DLL_LOCATIONS) {
var dllLocation = Path.GetFullPath(Path.Combine([exeLocation!, .. loc]));
Trace.WriteLine($"Looking for hook DLL in {dllLocation}");
if (File.Exists(dllLocation)) {
Logging.Log(Logging.Severity.DEBUG, $"Using hook DLL from {dllLocation}");
return dllLocation;
}
}
Expand All @@ -42,7 +42,7 @@ public static bool IsACCRunning() {
bool found = false;
if (!User32.EnumWindows(delegate (IntPtr hWnd, IntPtr lParam) {
if (IsACCWindow(hWnd)) {
Trace.WriteLine("ACC window found");
Logging.Log(Logging.Severity.DEBUG, $"ACC window found: {hWnd}");
found = true;
}
return true;
Expand All @@ -59,30 +59,30 @@ private static string NullTerminatedString(char[] buffer) {
private static IEnumerable<string> FindSteamFolders() {
using var steamSubKey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Wow6432Node\\Valve\\Steam");
if (steamSubKey == null || steamSubKey.GetValue("InstallPath") is not string steamInstallPath) {
Trace.WriteLine("Steam install path not found in registry");
Logging.Log(Logging.Severity.ERROR, "Steam install path not found in registry");
return Enumerable.Empty<string>();
}
Trace.WriteLine($"Steam installed in {steamInstallPath}");
Logging.Log(Logging.Severity.DEBUG, $"Steam installed in {steamInstallPath}");

using var steamFolderReader = new StreamReader(Path.Join(steamInstallPath, "steamapps", "libraryfolders.vdf"), Encoding.UTF8);
if (VDFSerializer.Deserialize(steamFolderReader).Item2 is not Dictionary<string, object> folderInfo) {
Trace.WriteLine("Could not parse Steam library folders");
Logging.Log(Logging.Severity.ERROR, "Could not parse Steam library folders");
return Enumerable.Empty<string>();
}
var steamFolders = from Dictionary<string, object> dict in folderInfo.Values
select dict["path"] as string;
Trace.WriteLine($"Steam library folders: {String.Join(", ", steamFolders)}");
Logging.Log(Logging.Severity.DEBUG, $"Steam library folders: {String.Join(", ", steamFolders)}");
return steamFolders;
}

public static string? FindACCInstallDir() {
foreach (var f in FindSteamFolders()) {
var accManifestPath = Path.Join(f, "steamapps", "appmanifest_805550.acf");
if (File.Exists(accManifestPath)) {
Trace.WriteLine($"ACC appmanifest found in {accManifestPath}");
Logging.Log(Logging.Severity.DEBUG, $"ACC appmanifest found in {accManifestPath}");
using var acfReader = new StreamReader(accManifestPath, Encoding.UTF8);
if (VDFSerializer.Deserialize(acfReader).Item2 is not Dictionary<string, object> accInfo) {
Trace.WriteLine("Could not parse ACC appmanifest");
Logging.Log(Logging.Severity.ERROR, "Could not parse ACC appmanifest");
break;
}
return Path.Join(f, "steamapps", "common", (string)accInfo["installdir"]);
Expand All @@ -99,7 +99,7 @@ public static bool IsHookOutdated(string accInstallPath) {
if (IsHookInstalled(accInstallPath)) {
var myInfo = FileVersionInfo.GetVersionInfo(FindHookDLL());
var verInfo = FileVersionInfo.GetVersionInfo(InstallPathToDllPath(accInstallPath));
Trace.WriteLine($"Installed hook version: {verInfo.ProductVersion} my version {myInfo.ProductVersion}");
Logging.Log(Logging.Severity.INFO, $"Installed hook version: {verInfo.ProductVersion} my version {myInfo.ProductVersion}");
return myInfo.ProductVersion != verInfo.ProductVersion;
}
return false;
Expand All @@ -112,13 +112,13 @@ private static string InstallPathToDllPath(string accInstallPath) {
public static void RemoveHook(string accInstallPath) {
var dllPath = InstallPathToDllPath(accInstallPath);
File.Delete(InstallPathToDllPath(accInstallPath));
Trace.WriteLine($"Deleted hook DLL from {dllPath}");
Logging.Log(Logging.Severity.DEBUG, $"Deleted hook DLL from {dllPath}");
}

public static void InstallHook(string accInstallPath) {
var dllPath = InstallPathToDllPath(accInstallPath);
File.Copy(FindHookDLL(), dllPath, true);
Trace.WriteLine($"Copied hook DLL to {dllPath}");
Logging.Log(Logging.Severity.DEBUG, $"Copied hook DLL to {dllPath}");
}
}
}
27 changes: 27 additions & 0 deletions client-gui/Logging.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Diagnostics;

namespace ACCConnector {
internal class Logging {
public enum Severity {
FATAL,
ERROR,
WARNING,
INFO,
DEBUG
}

private static StreamWriter? logStream;

public static void Init(string logFolder) {
Directory.CreateDirectory(logFolder);
logStream = new StreamWriter(File.Open(Path.Join(logFolder, "app.log"), FileMode.Append, FileAccess.Write, FileShare.Read)) {
AutoFlush = true
};
}

public static void Log(Severity severity, string msg) {
logStream?.WriteLine($"{DateTimeOffset.Now:yyyy-MM-dd HH:mm:ss.fff} {severity}: {msg}");
Trace.WriteLine(msg);
}
}
}
10 changes: 7 additions & 3 deletions client-gui/ProgramMain.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ private static void SendUriToWindow(IntPtr hWnd, string uri) {

[STAThread]
static void Main(string[] args) {
Logging.Init(Path.Join(GetMyFolder(), "logs"));

#if !DEBUG
AppDomain.CurrentDomain.UnhandledException += UnhandledException;
#endif
Expand Down Expand Up @@ -80,7 +82,7 @@ Configure it manually via the settings dialog

IntPtr? openWindowHandle = FindAlreadyOpenWindow();
if (openWindowHandle != null && serverToAdd != null) {
Trace.WriteLine($"Sending URI {serverToAdd} to window {openWindowHandle}");
Logging.Log(Logging.Severity.INFO, $"Sending URI {serverToAdd} to window {openWindowHandle}");
SendUriToWindow(openWindowHandle.Value, serverToAdd);
return;
}
Expand All @@ -105,15 +107,17 @@ Configure it manually via the settings dialog
while (true) {
try {
await npss.WaitForConnectionAsync(cancelSource.Token);
Logging.Log(Logging.Severity.DEBUG, "Pipe connection request from hook DLL");
lock (serverDataLock) {
npss.Write(serverData);
}
npss.WaitForPipeDrain();
npss.Disconnect();
Logging.Log(Logging.Severity.DEBUG, "Successfully sent server list to hook DLL");
} catch (OperationCanceledException) {
break;
} catch (Exception ex) {
Trace.WriteLine($"Named pipe error: {ex.Message}");
Logging.Log(Logging.Severity.ERROR, $"Named pipe error: {ex.Message}");
}
}
});
Expand Down Expand Up @@ -172,7 +176,7 @@ private static void UnhandledException(object sender, UnhandledExceptionEventArg
{ex.StackTrace}
""";
MessageBox.Show(description, "ACC Connector has crashed", MessageBoxButtons.OK, MessageBoxIcon.Error);
Debug.Write($"Unhandled exception:\n{description}");
Logging.Log(Logging.Severity.FATAL, $"Unhandled exception:\n{description}");
}

public static string GetMyVersion() {
Expand Down
2 changes: 1 addition & 1 deletion client-gui/ServerInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public static ServerInfo FromUri(Uri uri) {
try {
address = Dns.GetHostAddresses(hostname)[0];
} catch (SocketException e) {
Trace.WriteLine($"Failed to resolve hostname \"{hostname}\": {e.Message}");
Logging.Log(Logging.Severity.ERROR, $"Failed to resolve hostname \"{hostname}\": {e.Message}");
}

return new ServerInfo(name, hostname, address, (ushort)port, persistent);
Expand Down
3 changes: 3 additions & 0 deletions client-hooks/client-hooks.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,6 @@ void log_msg(const wchar_t* fmt, ...);

BOOL initProxy();
void closeProxy();

void initLog();
void closeLog();
2 changes: 2 additions & 0 deletions client-hooks/dllmain.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvReserved)
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
initLog();
log_msg(L"DLL attaching...");
if (!initProxy()) {
log_msg(L"Failed to initialize proxy DLL");
Expand All @@ -20,6 +21,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvReserved)
log_msg(L"DLL detaching...");
removeHooks();
closeProxy();
closeLog();
break;

case DLL_THREAD_ATTACH:
Expand Down
1 change: 0 additions & 1 deletion client-hooks/hooks.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ void handle_discovery(SOCKET s, DWORD id) {
log_msg(L"CreateFileW(\"%s\") failed: 0x%x", NAMED_PIPE_NAME, GetLastError());
return;
}
log_msg(L"CreateFileW done");

DWORD mode = PIPE_READMODE_MESSAGE;
if (!SetNamedPipeHandleState(hPipe, &mode, NULL, NULL)) {
Expand Down
36 changes: 36 additions & 0 deletions client-hooks/log.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,48 @@
#include "client-hooks.h"

#include <Shlobj.h>
#include <Share.h>
#include <stdio.h>

FILE* log_file = NULL;

void initLog() {
wchar_t *documents_path;
HRESULT res = SHGetKnownFolderPath(&FOLDERID_Documents, 0, NULL, &documents_path);
if (SUCCEEDED(res)) {
wchar_t path[512];
swprintf_s(path, 512, L"%s\\ACC Connector", documents_path);
CreateDirectory(path, NULL);
swprintf_s(path, 512, L"%s\\ACC Connector\\logs", documents_path);
CreateDirectory(path, NULL);
swprintf_s(path, 512, L"%s\\ACC Connector\\logs\\hook.log", documents_path);
log_file = _wfsopen(path, L"a", _SH_DENYWR);
CoTaskMemFree(documents_path);
log_msg(L"Log opened");
}
else {
log_msg(L"Failed to get Documents folder location: %x", res);
}
}

void closeLog() {
log_msg(L"Closing log");
fclose(log_file);
log_file = NULL;
}

void log_msg(const wchar_t* fmt, ...) {
va_list args;
wchar_t buffer[512];
va_start(args, fmt);
vswprintf_s(buffer, 512, fmt, args);
va_end(args);
OutputDebugStringW(buffer);
if (log_file) {
SYSTEMTIME time;
GetLocalTime(&time);
fwprintf(log_file, L"%04d-%02d-%02d %02d:%02d:%02d.%03d %s\n",
time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond, time.wMilliseconds, buffer);
fflush(log_file);
}
}

0 comments on commit 52edc18

Please sign in to comment.