Skip to content

Commit

Permalink
Improve file copying during Discord updates
Browse files Browse the repository at this point in the history
  • Loading branch information
hdrover committed Dec 20, 2024
1 parent 2f5e3d5 commit 22e5753
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 22 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Discord Drover is a program that forces the Discord application for Windows to use a specified proxy server (HTTP or SOCKS5) for TCP connections (chat, updates). This may be necessary because the original Discord application lacks proxy settings, and the global system proxy is also not used.

Additionally, the program slightly interferes with Discord's outgoing UDP traffic, which helps bypass some local restrictions on voice chats (UAE, Russia and others).
Additionally, the program slightly interferes with Discord's outgoing UDP traffic, which helps bypass some local restrictions on voice chats.

The program works locally at the specific process level (without drivers) and does not affect the operating system globally. This approach serves as an alternative to using a global VPN (such as TUN interfaces and others).

Expand Down
83 changes: 62 additions & 21 deletions drover.dpr
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ uses
System.RegularExpressions,
System.NetEncoding,
SocketManager,
Options;
Options,
System.IOUtils,
Classes;

var
RealGetFileVersionInfoA: pointer;
Expand Down Expand Up @@ -57,6 +59,9 @@ var
droverOptions: TDroverOptions;
proxyValue: TProxyValue;

const
DISCORD_FILENAME = 'Discord.exe';

procedure MyGetFileVersionInfoA;
asm
JMP [RealGetFileVersionInfoA]
Expand Down Expand Up @@ -163,41 +168,77 @@ begin
result := RealGetEnvironmentVariableW(lpName, lpBuffer, nSize);
end;

procedure CopyFilesToNewVersionFolderIfNeeded(lpApplicationName: LPCWSTR);
procedure FindDiscordDirs(list: TStringList);
var
launchingDir: string;
srcOptionsPath, srcDllPath, dstOptionsPath, dstDllPath: string;
subdirs: TArray<string>;
s, subdir, baseDir: string;
begin
if lpApplicationName = nil then
exit;
baseDir := IncludeTrailingPathDelimiter(ExtractFilePath(ExcludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0)))));
if TDirectory.Exists(baseDir) then
begin
subdirs := TDirectory.GetDirectories(baseDir, 'app-*', TSearchOption.soTopDirectoryOnly);
for subdir in subdirs do
begin
s := IncludeTrailingPathDelimiter(subdir);
if FileExists(s + DISCORD_FILENAME) then
begin
list.Add(s);
end;
end;
end;
end;

if not SameText(ExtractFileName(lpApplicationName), 'Discord.exe') then
exit;
procedure CopyFilesToAllDiscordDirs;
var
dirs: TStringList;
dir: string;
srcOptionsPath, srcDllPath, dstOptionsPath, dstDllPath: string;
begin
srcOptionsPath := currentProcessDir + OPTIONS_FILENAME;
srcDllPath := currentProcessDir + DLL_FILENAME;

if not SameText(ExtractFileName(ParamStr(0)), 'Discord.exe') then
if not FileExists(srcOptionsPath) or not FileExists(srcDllPath) then
exit;

launchingDir := IncludeTrailingPathDelimiter(ExtractFilePath(lpApplicationName));
dirs := TStringList.Create;
try
FindDiscordDirs(dirs);

srcOptionsPath := currentProcessDir + OPTIONS_FILENAME;
srcDllPath := currentProcessDir + DLL_FILENAME;
dstOptionsPath := launchingDir + OPTIONS_FILENAME;
dstDllPath := launchingDir + DLL_FILENAME;
for dir in dirs do
begin
dstOptionsPath := dir + OPTIONS_FILENAME;
dstDllPath := dir + DLL_FILENAME;

if FileExists(launchingDir + 'Discord.exe') and FileExists(srcOptionsPath) and FileExists(srcDllPath) and
not FileExists(dstOptionsPath) and not FileExists(dstDllPath) then
begin
CopyFile(PChar(srcOptionsPath), PChar(dstOptionsPath), true);
CopyFile(PChar(srcDllPath), PChar(dstDllPath), true);
if FileExists(dir + DISCORD_FILENAME) and not FileExists(dstOptionsPath) and not FileExists(dstDllPath) then
begin
CopyFile(PChar(srcOptionsPath), PChar(dstOptionsPath), true);
CopyFile(PChar(srcDllPath), PChar(dstDllPath), true);
end;
end;
finally
dirs.Free;
end;
end;

procedure CopyFilesOnCreateProcessIfNeeded(lpApplicationName: LPCWSTR);
var
appName: string;
begin
if lpApplicationName = nil then
exit;

appName := ExtractFileName(lpApplicationName);

if SameText(appName, DISCORD_FILENAME) or SameText(appName, 'reg.exe') then
CopyFilesToAllDiscordDirs;
end;

function MyCreateProcessW(lpApplicationName: LPCWSTR; lpCommandLine: LPWSTR;
lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; bInheritHandles: bool; dwCreationFlags: DWORD;
lpEnvironment: pointer; lpCurrentDirectory: LPCWSTR; const lpStartupInfo: TStartupInfoW;
var lpProcessInformation: TProcessInformation): bool; stdcall;
begin
CopyFilesToNewVersionFolderIfNeeded(lpApplicationName);
CopyFilesOnCreateProcessIfNeeded(lpApplicationName);

result := RealCreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes,
bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation);
Expand All @@ -210,7 +251,7 @@ begin
s := RealGetCommandLineW;
if proxyValue.isSpecified then
begin
if SameText(ExtractFileName(ParamStr(0)), 'Discord.exe') then
if SameText(ExtractFileName(ParamStr(0)), DISCORD_FILENAME) then
s := s + ' --proxy-server=' + proxyValue.FormatToChromeProxy;
end;
result := PChar(s);
Expand Down

0 comments on commit 22e5753

Please sign in to comment.