Skip to content

Commit a4646fb

Browse files
committed
add support for snap/flatpak discord
1 parent b79b565 commit a4646fb

File tree

3 files changed

+79
-35
lines changed

3 files changed

+79
-35
lines changed

src/platform/unix.hpp

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#pragma once
2+
#include <array>
23
#include <fcntl.h>
34
#include <unistd.h>
45
#include <fmt/format.h>
@@ -11,9 +12,9 @@ namespace discord::platform {
1112
return ::getpid();
1213
}
1314

14-
inline const char* getTempPath() noexcept {
15-
static const char* path = []() {
16-
const char* tmp = ::getenv("XDG_RUNTIME_DIR");
15+
inline char const* getTempPath() noexcept {
16+
static char const* path = []() {
17+
char const* tmp = ::getenv("XDG_RUNTIME_DIR");
1718
tmp = tmp ? tmp : ::getenv("TMPDIR");
1819
tmp = tmp ? tmp : ::getenv("TMP");
1920
tmp = tmp ? tmp : ::getenv("TEMP");
@@ -22,6 +23,30 @@ namespace discord::platform {
2223
return path;
2324
}
2425

26+
inline std::array<std::string, 4> const& getCandidatePaths() {
27+
static std::array<std::string, 4> paths = []() {
28+
char const* base = ::getenv("XDG_RUNTIME_DIR");
29+
if (!base) {
30+
auto runUser = fmt::format("/run/user/{}", ::getuid());
31+
if (::access(runUser.c_str(), F_OK) == 0) {
32+
base = runUser.c_str();
33+
} else {
34+
base = getTempPath();
35+
}
36+
}
37+
38+
std::array<std::string, 4> result = {
39+
base,
40+
fmt::format("{}/snap.discord", base),
41+
fmt::format("{}/app/com.discordapp.Discord", base),
42+
fmt::format("{}/app/com.discordapp.DiscordCanary", base),
43+
};
44+
45+
return result;
46+
}();
47+
return paths;
48+
}
49+
2550
class PipeConnection {
2651
PipeConnection() noexcept {
2752
m_address.sun_family = AF_UNIX;
@@ -49,11 +74,13 @@ namespace discord::platform {
4974
::setsockopt(m_socket, SOL_SOCKET, SO_NOSIGPIPE, &optval, sizeof(optval));
5075
#endif
5176

52-
for (int i = 0; i < 10; ++i) {
53-
fmt::format_to(m_address.sun_path, "{}/discord-ipc-{}", getTempPath(), i);
54-
if (::connect(m_socket, reinterpret_cast<sockaddr*>(&m_address), sizeof(m_address)) == 0) {
55-
m_isOpen = true;
56-
return true;
77+
for (auto& dir : getCandidatePaths()) {
78+
for (int i = 0; i < 10; ++i) {
79+
fmt::format_to(m_address.sun_path, "{}/discord-ipc-{}", dir, i);
80+
if (::connect(m_socket, reinterpret_cast<sockaddr*>(&m_address), sizeof(m_address)) == 0) {
81+
m_isOpen = true;
82+
return true;
83+
}
5784
}
5885
}
5986

@@ -76,7 +103,7 @@ namespace discord::platform {
76103
return m_isOpen;
77104
}
78105

79-
bool write(const void* data, size_t length) noexcept {
106+
bool write(void const* data, size_t length) noexcept {
80107
if (!m_isOpen || m_socket == -1) {
81108
return false;
82109
}

src/platform/windows.cpp

Lines changed: 41 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "windows.hpp"
2+
#include <array>
23
#include <WinSock2.h>
34
#include <fmt/format.h>
45

@@ -16,10 +17,10 @@ namespace wine {
1617
}
1718

1819
static std::string getTempPath() {
19-
const wchar_t* envVars[] = {L"XDG_RUNTIME_DIR", L"TMPDIR", L"TMP", L"TEMP"};
20+
wchar_t const* envVars[] = {L"XDG_RUNTIME_DIR", L"TMPDIR", L"TMP", L"TEMP"};
2021

2122
wchar_t buffer[MAX_PATH];
22-
for (const auto& var : envVars) {
23+
for (auto const& var : envVars) {
2324
DWORD result = ::GetEnvironmentVariableW(var, buffer, MAX_PATH);
2425
if (result > 0 && result < MAX_PATH) {
2526
int len = WideCharToMultiByte(CP_UTF8, 0, buffer, result, nullptr, 0, nullptr, nullptr);
@@ -32,6 +33,22 @@ namespace wine {
3233
return "/tmp";
3334
}
3435

36+
static std::array<std::string, 4> const& getCandidatePaths() {
37+
static std::array<std::string, 4> paths = []() {
38+
auto base = getTempPath();
39+
40+
std::array<std::string, 4> result = {
41+
base,
42+
fmt::format("{}/snap.discord", base),
43+
fmt::format("{}/app/com.discordapp.Discord", base),
44+
fmt::format("{}/app/com.discordapp.DiscordCanary", base),
45+
};
46+
47+
return result;
48+
}();
49+
return paths;
50+
}
51+
3552
static std::string convertWinePathToWindows(std::string const& unixPath) noexcept {
3653
auto command = fmt::format("winepath -w \"{}\"", unixPath);
3754

@@ -157,7 +174,7 @@ namespace discord::platform {
157174
return true;
158175
}
159176

160-
bool PipeConnection::write(const void* data, size_t length) const noexcept {
177+
bool PipeConnection::write(void const* data, size_t length) const noexcept {
161178
if (length == 0) {
162179
return true;
163180
}
@@ -174,7 +191,7 @@ namespace discord::platform {
174191
return false;
175192
}
176193

177-
const auto bytesToWrite = static_cast<DWORD>(length);
194+
auto const bytesToWrite = static_cast<DWORD>(length);
178195
DWORD bytesWritten = 0;
179196
if (!::WriteFile(m_pipe, data, bytesToWrite, &bytesWritten, nullptr)) {
180197
return false;
@@ -227,27 +244,27 @@ namespace discord::platform {
227244
u_long mode = 1;
228245
::ioctlsocket(socket, FIONBIO, &mode);
229246

230-
for (int i = 0; i < 10; ++i) {
231-
auto socketPath = wine::convertWinePathToWindows(fmt::format("{}\\discord-ipc-{}", basePath, i));
232-
if (socketPath.empty()) {
233-
return false;
234-
}
235-
236-
struct UnixAddr {
237-
short sun_family;
238-
char sun_path[108] = {};
239-
};
247+
for (auto& dir : wine::getCandidatePaths()) {
248+
for (int i = 0; i < 10; ++i) {
249+
auto socketPath = wine::convertWinePathToWindows(fmt::format("{}\\discord-ipc-{}", dir, i));
250+
if (socketPath.empty()) {
251+
return false;
252+
}
240253

241-
UnixAddr addr{};
242-
addr.sun_family = AF_UNIX;
254+
struct UnixAddr {
255+
short sun_family;
256+
char sun_path[108] = {};
257+
};
243258

244-
std::memcpy(addr.sun_path, socketPath.c_str(), std::min(socketPath.size(), sizeof(addr.sun_path) - 1));
259+
UnixAddr addr{AF_UNIX};
260+
std::memcpy(addr.sun_path, socketPath.c_str(), std::min(socketPath.size(), sizeof(addr.sun_path) - 1));
245261

246-
if (::connect(socket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == 0) {
247-
m_pipe = reinterpret_cast<HANDLE>(socket);
248-
m_isOpen = true;
249-
m_useWineFallback = true;
250-
return true;
262+
if (::connect(socket, reinterpret_cast<sockaddr*>(&addr), sizeof(addr)) == 0) {
263+
m_pipe = reinterpret_cast<HANDLE>(socket);
264+
m_isOpen = true;
265+
m_useWineFallback = true;
266+
return true;
267+
}
251268
}
252269
}
253270

@@ -271,7 +288,7 @@ namespace discord::platform {
271288
return true;
272289
}
273290

274-
bool PipeConnection::writeUnix(const void* data, size_t length) const noexcept {
291+
bool PipeConnection::writeUnix(void const* data, size_t length) const noexcept {
275292
if (!data) {
276293
return true;
277294
}
@@ -281,7 +298,7 @@ namespace discord::platform {
281298
return false;
282299
}
283300

284-
int bytesSent = ::send(socket, static_cast<const char*>(data), static_cast<int>(length), 0);
301+
int bytesSent = ::send(socket, static_cast<char const*>(data), static_cast<int>(length), 0);
285302
if (bytesSent == SOCKET_ERROR) {
286303
return false;
287304
}

src/platform/windows.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ namespace discord::platform {
2323
bool open() noexcept;
2424
bool close() noexcept;
2525

26-
bool write(const void* data, size_t length) const noexcept;
26+
bool write(void const* data, size_t length) const noexcept;
2727
bool read(void* data, size_t length) noexcept;
2828

2929
[[nodiscard]] bool isOpen() const noexcept { return m_isOpen; }
@@ -32,7 +32,7 @@ namespace discord::platform {
3232
// Unix methods for Wine compatibility
3333
bool openUnix() noexcept;
3434
bool closeUnix() noexcept;
35-
bool writeUnix(const void* data, size_t length) const noexcept;
35+
bool writeUnix(void const* data, size_t length) const noexcept;
3636
bool readUnix(void* data, size_t length) noexcept;
3737

3838
HANDLE m_pipe = INVALID_HANDLE_VALUE;

0 commit comments

Comments
 (0)