diff --git a/AmongUsCapture/AmongUsCapture.csproj b/AmongUsCapture/AmongUsCapture.csproj
index 6141bc4a..3713f773 100644
--- a/AmongUsCapture/AmongUsCapture.csproj
+++ b/AmongUsCapture/AmongUsCapture.csproj
@@ -14,6 +14,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
+
diff --git a/AmongUsCapture/IPC/DBus/IPCadapterDBus.cs b/AmongUsCapture/IPC/DBus/IPCadapterDBus.cs
index 43371aa3..e674db7e 100644
--- a/AmongUsCapture/IPC/DBus/IPCadapterDBus.cs
+++ b/AmongUsCapture/IPC/DBus/IPCadapterDBus.cs
@@ -2,10 +2,14 @@
using System.Diagnostics;
using System.IO;
using System.Net;
+using System.Runtime.InteropServices;
using System.Security.Policy;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Castle.Components.DictionaryAdapter;
+using Gtk;
+using Mono.Unix;
using SharedMemory;
using Tmds.DBus;
using Tmds.DBus.Transports;
@@ -28,6 +32,7 @@ public override URIStartResult HandleURIStart(string[] args)
{
var myProcessId = Process.GetCurrentProcess().Id;
//Process[] processes = Process.GetProcessesByName("AmongUsCapture");
+ //Process[] dotnetprocesses = Process.GetProcessesByName("dotnet");
//foreach (Process p in processes)
//{
//if (p.Id != myProcessId)
@@ -37,18 +42,81 @@ public override URIStartResult HandleURIStart(string[] args)
// }
Console.WriteLine(Program.GetExecutablePath());
- mutex = new Mutex(true, appName, out var createdNew);
+ //mutex = new Mutex(true, appName, out var createdNew);
+ bool createdNew = false;
var wasURIStart = args.Length > 0 && args[0].StartsWith(UriScheme + "://");
var result = URIStartResult.CONTINUE;
+ if (!File.Exists(Path.Join(Settings.StorageLocation, ".amonguscapture.pid")))
+ {
+ createdNew = true;
+ }
+ else
+ {
+ // Open our PID file.
+ using (var pidfile = File.OpenText(Path.Join(Settings.StorageLocation, ".amonguscapture.pid")))
+ {
+ var pid = pidfile.ReadLine();
+ if (pid != null)
+ {
+ var pidint = Int32.Parse(pid);
+
+ try
+ {
+ var capproc = Process.GetProcessById(pidint);
+ var assmbname = System.Reflection.Assembly.GetExecutingAssembly().GetName().Name;
+ var runnername = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName;
+
+ if (!capproc.ProcessName.Contains("dotnet"))
+ {
+ // We're just going to assume that a dotnet process that matches this set of parameters
+ // is a running capture process.
+ throw new ArgumentException();
+
+ }
+ else if (!capproc.ProcessName.Contains(Path.GetFileName(runnername)))
+ {
+ throw new ArgumentException();
+ }
+
+
+ if (capproc.HasExited)
+ {
+ throw new ArgumentException();
+ }
+ }
+ catch (ArgumentException e)
+ {
+ // Process doesn't exist. Clear the file.
+ Console.WriteLine($"Found stale PID file containing {pid}.");
+ File.Delete(Path.Join(Settings.StorageLocation, ".amonguscapture.pid"));
+ createdNew = true;
+ }
+ }
+ }
+
+ }
+
+ if (createdNew)
+ {
+ using (var pidwriter = File.CreateText(Path.Join(Settings.StorageLocation, ".amonguscapture.pid")))
+ {
+ pidwriter.Write(myProcessId);
+ }
+ }
+
+
if (!createdNew) // send it to already existing instance if applicable, then close
{
- if (wasURIStart) SendToken(args[0]);
+ if (wasURIStart) SendToken(args[0]).Wait();
return URIStartResult.CLOSE;
}
else if (wasURIStart) // URI start on new instance, continue as normal but also handle current argument
{
+ // if we are running, we create a file lock with our process in it.
+ // Also attach the pid delete handler from Program.
+
result = URIStartResult.PARSE;
}
@@ -56,24 +124,76 @@ public override URIStartResult HandleURIStart(string[] args)
return result;
}
-
+
private static void RegisterProtocol()
{
-
+ // we really should query the user for this, but since Dialogs appear to be completely fucked, we're going
+ // to just install it right now.
+ var xdg_path = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
+ "applications");
+ var xdg_file = Path.Join(xdg_path, "aucapture-opener.desktop");
+
+ if (!File.Exists(xdg_file))
+ {
+ var executingassmb = System.Reflection.Assembly.GetExecutingAssembly().Location;
+ if (Path.HasExtension("dll"))
+ {
+ executingassmb = "dotnet " + executingassmb;
+ }
+
+ var xdg_file_write = new string[]
+ {
+ "[Desktop Entry]",
+ "Type=Application",
+ "Name=aucapture URI Handler",
+ $"Exec={executingassmb} %u",
+ "StartupNotify=false",
+ "MimeType=x-scheme-handler/aucapture;"
+ };
+
+ using (var file = File.CreateText(xdg_file))
+ {
+ foreach (string str in xdg_file_write)
+ {
+ file.WriteLine(str);
+ }
+ }
+
+ var xdg_posix = new UnixFileInfo(xdg_file);
+
+ xdg_posix.FileAccessPermissions = FileAccessPermissions.UserReadWriteExecute
+ | FileAccessPermissions.GroupRead
+ | FileAccessPermissions.GroupExecute
+ | FileAccessPermissions.OtherRead
+ | FileAccessPermissions.OtherExecute;
+
+ // Finally, register with xdg-mime.
+
+ var xdgproc = new Process()
+ {
+ StartInfo = new ProcessStartInfo
+ {
+ FileName = "/usr/bin/xdg-mime",
+ Arguments = $"default aucapture-opener.desktop x-scheme-handler/aucapture",
+ RedirectStandardOutput = true,
+ UseShellExecute = false,
+ CreateNoWindow = true,
+ }
+ };
+
+ xdgproc.Start();
+ string result = xdgproc.StandardOutput.ReadToEnd();
+ xdgproc.WaitForExit();
+ }
}
public override async Task SendToken(string jsonText)
{
- while (!_isListening)
- {
- Thread.Sleep(1000);
- }
-
// Send the token via DBus.
using (Connection conn = new Connection(Address.Session))
{
await conn.ConnectAsync();
-
+
var obj = new IPCLink();
await conn.RegisterObjectAsync(obj);
await conn.RegisterServiceAsync("org.AmongUsCapture.ipc", ServiceRegistrationOptions.None);
@@ -92,7 +212,7 @@ public override void SendToken(string host, string connectCode)
public async override Task RegisterMinion()
{
- Task.Factory.StartNew( async () =>
+ Task.Factory.StartNew(async () =>
{
using (_dbusconnection = new Connection(Address.Session))
@@ -113,7 +233,7 @@ public async override Task RegisterMinion()
}
}
});
-
+
}
public override void startWithToken(string uri)
@@ -124,18 +244,18 @@ public override void startWithToken(string uri)
public override bool Cancel()
{
if (!_cancellation.IsCancellationRequested)
- {
+ {
_cancellation.Cancel();
return true;
}
return false;
}
-
+
private void RespondToDbus(string signalresponse)
{
Settings.conInterface.WriteModuleTextColored("DBus", Color.Silver,
- $"Recieved new message on DBus: {signalresponse}");
+ $"Received new message on DBus: \"{signalresponse}\"");
signalresponse = signalresponse.Trim('\r', '\n');
@@ -144,5 +264,4 @@ private void RespondToDbus(string signalresponse)
OnTokenEvent(token);
}
}
-
}
\ No newline at end of file
diff --git a/AmongUsCapture/Memory/ProcessMemoryLinux.cs b/AmongUsCapture/Memory/ProcessMemoryLinux.cs
index 5f67536c..0c8296b5 100644
--- a/AmongUsCapture/Memory/ProcessMemoryLinux.cs
+++ b/AmongUsCapture/Memory/ProcessMemoryLinux.cs
@@ -296,9 +296,12 @@ public static class LinuxAPI
//
// https://man7.org/linux/man-pages/man2/process_vm_readv.2.html
- [DllImport("libc.so.6", SetLastError = true)]
+ [DllImport("libc", SetLastError = true)]
public static extern int process_vm_readv(int pid, IntPtr local_iov, ulong liovcnt, IntPtr remote_iov,
ulong riovcnt, ulong flags);
+
+ [DllImport("libc", SetLastError = true)]
+ private static extern int chmod(string pathname, int mode);
}
diff --git a/AmongUsCapture/Program.cs b/AmongUsCapture/Program.cs
index a58cdc15..e31c2338 100644
--- a/AmongUsCapture/Program.cs
+++ b/AmongUsCapture/Program.cs
@@ -1,5 +1,6 @@
using System;
using System.Drawing;
+using System.IO;
using System.IO.Pipes;
using System.Net.Sockets;
using System.Runtime.InteropServices;
@@ -34,6 +35,11 @@ private static void Main(string[] args)
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows) && Settings.PersistentSettings.debugConsole)
AllocConsole(); // needs to be the first call in the program to prevent weird bugs
+ if (!Directory.Exists(Settings.StorageLocation))
+ {
+ // Create Settings directory if it doesn't exist, as we need to stick our pidfile there.
+ Directory.CreateDirectory(Settings.StorageLocation);
+ }
URIStartResult uriRes = URIStartResult.CLOSE;
uriRes = IPCadapter.getInstance().HandleURIStart(args);
@@ -87,17 +93,17 @@ private static void OpenGUI()
window.DeleteEvent += (object o, DeleteEventArgs e) =>
{
+ // Make sure the pid file is deleted if the application quits.
+ CleanPid();
Application.Quit();
};
- // Post a quick message to the console if we are using Linux, notifying the user that IPC links do not work.
-
- Settings.conInterface.WriteModuleTextColored("Notification", Color.Red,
- $"You are running amonguscapture under Linux. Discord capture links are not currently supported. Use the manual details in your DM instead.");
-
window.ShowAll();
Application.Run();
+
+ CleanPid();
+
Environment.Exit(0);
}
@@ -106,11 +112,37 @@ public static string GetExecutablePath()
return Process.GetCurrentProcess().MainModule.FileName;
}
+ private static void CleanPid()
+ {
+ // Make sure the pidfile is cleaned up if we have one.
+ var pidfile = Path.Join(Settings.StorageLocation, ".amonguscapture.pid");
+
+ if (File.Exists(pidfile))
+ {
+ int pid;
+ bool fileread;
+ using (var pidread = File.OpenText(Path.Join(Settings.StorageLocation, ".amonguscapture.pid")))
+ {
+ fileread = Int32.TryParse(pidread.ReadLine(), out pid);
+ }
+
+ if (!fileread)
+ {
+ // Bad read, file must be corrupt. Clear pidfile.
+ File.Delete(pidfile);
+ }
+
+ if (pid == Process.GetCurrentProcess().Id)
+ {
+ // This is our process. Delete file.
+ File.Delete(pidfile);
+ }
+ }
+ }
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool AllocConsole();
-
}
}
\ No newline at end of file
diff --git a/AmongUsCapture/Properties/launchSettings.json b/AmongUsCapture/Properties/launchSettings.json
index 556eeb71..e8056cc8 100644
--- a/AmongUsCapture/Properties/launchSettings.json
+++ b/AmongUsCapture/Properties/launchSettings.json
@@ -5,7 +5,7 @@
},
"AmongUsCaptureIPC": {
"commandName": "Project",
- "commandLineArgs": "aucapture://localhost:8123/3A9CD4A1?insecure"
+ "commandLineArgs": "aucapture://localhost:8123/E68A0AD9?insecure"
}
}
}
\ No newline at end of file
diff --git a/AmongUsCapture/Settings.cs b/AmongUsCapture/Settings.cs
index f2d49ae9..593fbe6f 100644
--- a/AmongUsCapture/Settings.cs
+++ b/AmongUsCapture/Settings.cs
@@ -7,7 +7,7 @@ namespace AmongUsCapture
{
public static class Settings
{
- public static string StorageLocation = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "\\AmongUsCapture");
+ public static string StorageLocation = Path.Join(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "AmongUsCapture");
public static ConsoleInterface conInterface;
diff --git a/AmongUsCapture/UserForm.cs b/AmongUsCapture/UserForm.cs
index 0c00214f..5ff26da7 100644
--- a/AmongUsCapture/UserForm.cs
+++ b/AmongUsCapture/UserForm.cs
@@ -66,9 +66,7 @@ public UserForm(ClientSocket sock) : base("Among Us Capture - GTK")
GameMemReader.getInstance().ChatMessageAdded += OnChatMessageAdded;
GameMemReader.getInstance().JoinedLobby += OnJoinedLobby;
GameMemReader.getInstance().GameUnverified += _eventGameIsPirated;
-
-
-
+
// Load URL
_urlHostEntryField.Text = Settings.PersistentSettings.host;