Skip to content

Commit 78eb4f2

Browse files
committed
clean-up and resource files
Signed-off-by: Stavros Avramidis <[email protected]>
1 parent 6d326e8 commit 78eb4f2

File tree

8 files changed

+188
-125
lines changed

8 files changed

+188
-125
lines changed

.idea/misc.xml

+4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

CMakeLists.txt

+16-5
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@ cmake_minimum_required(VERSION 3.10)
33

44
project(TIDAL-RPC)
55

6+
# Create executable
67
include_directories(.)
7-
add_executable(tidal-rpc main.cc)
8-
9-
10-
set(CMAKE_PREFIX_PATH "/usr/local/opt/qt5/lib/cmake/Qt5Widgets/")
118

9+
if (APPLE)
10+
set(CMAKE_PREFIX_PATH "/usr/local/opt/qt5/lib/cmake/Qt5Widgets/")
11+
endif (APPLE)
1212

1313
# Find includes in corresponding build directories
1414
set(CMAKE_INCLUDE_CURRENT_DIR ON)
@@ -17,11 +17,22 @@ set(CMAKE_AUTOMOC ON)
1717
# Create code from a list of Qt designer ui files
1818
set(CMAKE_AUTOUIC ON)
1919

20+
2021
# Find the QtWidgets library
2122
find_package(Qt5Widgets CONFIG REQUIRED)
23+
find_package(Qt5Network CONFIG REQUIRED)
24+
25+
link_directories("C:\\Qt\\5.12.1\\msvc2017\\lib")
26+
2227

2328
set(CMAKE_CXX_FLAGS_COVERAGE "${CMAKE_CXX_FLAGS_RELEASE} -fprofile-arcs -ftest-coverage")
24-
target_link_libraries(tidal-rpc Qt5::Widgets)
29+
30+
qt5_add_resources(QRCS resources.qrc)
31+
32+
add_executable(tidal-rpc main.cc resource.rc ${QRCS})
33+
34+
35+
target_link_libraries(tidal-rpc Qt5::Widgets Qt5::Network)
2536

2637

2738
# generate proper GUI program on specified platform if on release

main.cc

+67-50
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66

77
/* C++ libs */
8+
#include <atomic>
89
#include <cctype>
910
#include <chrono>
1011
#include <exception>
@@ -18,13 +19,16 @@
1819
/* C libs */
1920
#include <cstdio>
2021
/* Qt */
21-
#include <QApplication>
22-
#include <QPushButton>
2322
#include <QAction>
24-
#include <QMenu>
23+
#include <QApplication>
24+
#include <QCoreApplication>
2525
#include <QIcon>
26+
#include <QMenu>
27+
#include <QObject>
28+
#include <QPushButton>
2629
#include <QSystemTrayIcon>
27-
#include <QCoreApplication>
30+
#include <QtNetwork>
31+
2832
/* local libs*/
2933
#include "discord_rpc.h"
3034
#include "discord_register.h"
@@ -34,32 +38,31 @@
3438
#ifdef WIN32
3539

3640
#include "windows_api_hook.hh"
41+
3742
#pragma comment(lib, "discord-rpc.lib")
3843

3944
#elif defined(__APPLE__) or defined(__MACH__)
40-
#include <Carbon/Carbon.h>
45+
4146
#include "osx_api_hook.hh"
4247

43-
#elif defined(__linux__)
4448
#else
45-
# error "unkown target os"
49+
#error "Not supported target"
4650
#endif
4751

4852
#define CURRENT_TIME std::time(nullptr)
4953
#define HIFI_ASSET "hifi"
5054

51-
static std::string lastfmUsername;
5255
static const char *APPLICATION_ID = "584458858731405315";
53-
volatile bool isPresenceActive = true;
56+
std::atomic<bool> isPresenceActive;
5457
static char *countryCode = nullptr;
5558

5659
struct Song {
5760
enum AudioQualityEnum { master, hifi, normal };
58-
5961
std::string title;
6062
std::string artist;
6163
std::string album;
6264
std::string url;
65+
char id[10];
6366
int64_t starttime;
6467
int64_t runtime;
6568
uint64_t pausedtime;
@@ -68,6 +71,7 @@ struct Song {
6871
bool isPaused = false;
6972
AudioQualityEnum quality;
7073

74+
7175
void setQuality(const std::string &q) {
7276
if (q == "HI_RES") {
7377
quality = master;
@@ -76,17 +80,21 @@ struct Song {
7680
}
7781
}
7882

83+
7984
inline bool isHighRes() const noexcept {
8085
return quality == master;
8186
}
8287

88+
8389
friend std::ostream &operator<<(std::ostream &out, const Song &song) {
8490
out << song.title << " of " << song.album << " from " << song.artist << "(" << song.runtime << ")";
8591
return out;
8692
}
8793
};
8894

8995
#include <locale>
96+
97+
9098
std::string urlEncode(const std::string &value) {
9199
std::ostringstream escaped;
92100
escaped.fill('0');
@@ -104,6 +112,7 @@ std::string urlEncode(const std::string &value) {
104112
return escaped.str();
105113
}
106114

115+
107116
static void updateDiscordPresence(const Song &song) {
108117
if (isPresenceActive) {
109118
DiscordRichPresence discordPresence;
@@ -119,52 +128,58 @@ static void updateDiscordPresence(const Song &song) {
119128
}
120129
discordPresence.largeImageKey = song.isHighRes() ? "test" : HIFI_ASSET;
121130
discordPresence.largeImageText = song.isHighRes() ? "Playing High-Res Audio" : "";
131+
if (song.id[0] != '\0')
132+
discordPresence.spectateSecret = song.id;
122133
discordPresence.instance = 0;
123134

135+
124136
Discord_UpdatePresence(&discordPresence);
125137
} else {
126138
Discord_ClearPresence();
127139
}
128140
}
129141

142+
130143
static void handleDiscordReady(const DiscordUser *connectedUser) {
131-
printf("\nDiscord: connected to user %s#%s - %s\n",
132-
connectedUser->username,
133-
connectedUser->discriminator,
134-
connectedUser->userId);
144+
std::clog << "Connected to discord " << connectedUser->userId << "\n";
135145
}
136146

147+
137148
static void handleDiscordDisconnected(int errcode, const char *message) {
138-
printf("\nDiscord: disconnected (%d: %s)\n", errcode, message);
149+
std::clog << "Discord: disconnected (" << errcode << " : " << message << ")\n";
139150
}
140151

152+
141153
static void handleDiscordError(int errcode, const char *message) {
142-
printf("\nDiscord: error (%d: %s)\n", errcode, message);
154+
std::cerr << "Discord: Error (" << errcode << " : " << message << ")\n";
143155
}
144156

157+
//static void handleDiscordSpectate(const char* secret) {
158+
// printf("\nDiscord: spectate (%s)\n", secret);
159+
//}
160+
145161
static void discordInit() {
146162
DiscordEventHandlers handlers;
147163
memset(&handlers, 0, sizeof(handlers));
148164
handlers.ready = handleDiscordReady;
149165
handlers.disconnected = handleDiscordDisconnected;
150166
handlers.errored = handleDiscordError;
151-
Discord_Initialize(APPLICATION_ID, &handlers, 1, NULL);
167+
168+
Discord_Initialize(APPLICATION_ID, &handlers, 1, nullptr);
152169
}
153170

171+
154172
inline void rpcLoop() {
155173

156174
using json = nlohmann::json;
157175
using string = std::string;
158176
httplib::Client cli("api.tidal.com");
159-
160177
char getSongInfoBuf[1024];
161178
json j;
162-
163-
Song curSong;
179+
static Song curSong;
164180

165181
for (;;) {
166182
std::wstring tmpTrack, tmpArtist;
167-
168183
auto localStatus = tidalInfo(tmpTrack, tmpArtist);
169184

170185
// If song is playing
@@ -178,6 +193,7 @@ inline void rpcLoop() {
178193
curSong.runtime = 0;
179194
curSong.pausedtime = 0;
180195
curSong.setQuality("");
196+
curSong.id[0] = '\0';
181197

182198
// get info form TIDAL api
183199
auto search_param =
@@ -201,11 +217,16 @@ inline void rpcLoop() {
201217
auto c_str = rawWstringToString(tmpTrack);
202218

203219
if (fetched_str == c_str) {
204-
curSong.setQuality(j["tracks"]["items"][i]["audioQuality"].get<std::string>());
205-
curSong.trackNumber = j["tracks"]["items"][i]["trackNumber"].get<uint_fast8_t>();
206-
curSong.volumeNumber = j["tracks"]["items"][i]["volumeNumber"].get<uint_fast8_t>();
207-
curSong.runtime = j["tracks"]["items"][i]["duration"].get<int64_t>();
208-
break;
220+
if (curSong.runtime == 0
221+
or j["tracks"]["items"][i]["audioQuality"].get<std::string>().compare("HI_RES")
222+
== 0) { // Ignore songs with same name if you have found song
223+
curSong.setQuality(j["tracks"]["items"][i]["audioQuality"].get<std::string>());
224+
curSong.trackNumber = j["tracks"]["items"][i]["trackNumber"].get<uint_fast8_t>();
225+
curSong.volumeNumber = j["tracks"]["items"][i]["volumeNumber"].get<uint_fast8_t>();
226+
curSong.runtime = j["tracks"]["items"][i]["duration"].get<int64_t>();
227+
sprintf(curSong.id, "%u", j["tracks"]["items"][i]["id"].get<unsigned>());
228+
if (curSong.isHighRes()) break; // keep searching for high-res version.
229+
}
209230
}
210231
}
211232
} catch (...) {
@@ -218,7 +239,7 @@ inline void rpcLoop() {
218239
#endif
219240

220241
// get time just before passing it to RPC handlers
221-
curSong.starttime = 2 + CURRENT_TIME; // add 2 seconds to be more accurate.
242+
curSong.starttime = CURRENT_TIME + 2; // add 2 seconds to be more accurate, not a chance
222243
updateDiscordPresence(curSong);
223244
} else {
224245
if (curSong.isPaused) {
@@ -228,42 +249,37 @@ inline void rpcLoop() {
228249
}
229250

230251
} else if (localStatus == opened) {
231-
if ((CURRENT_TIME - (curSong.starttime + curSong.runtime + curSong.pausedtime) > 5)) {
232-
curSong.pausedtime += 1;
233-
curSong.isPaused = true;
234-
}
252+
curSong.pausedtime += 1;
253+
curSong.isPaused = true;
235254
updateDiscordPresence(curSong);
255+
} else {
256+
Discord_ClearPresence();
236257
}
237-
238258
_continue:
259+
260+
#ifdef DISCORD_DISABLE_IO_THREAD
261+
Discord_UpdateConnection();
262+
#endif
263+
Discord_RunCallbacks();
264+
239265
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
240266

241267
}
242268
}
243269

270+
244271
int main(int argc, char **argv) {
245-
using json = nlohmann::json;
246-
using string = std::string;
247272

248273
// get country code for TIDAL api queries
249274
countryCode = getLocale();
275+
isPresenceActive = true;
250276

251-
// try {
252-
// std::ifstream i("settings.json");
253-
// json j;
254-
// i >> j;
255-
// lastfmUsername = j["last_fm_username"].get<string>();
256-
// } catch (...) {
257-
// std::cerr << "Couldn't read last.fm username\n";
258-
// }
259-
277+
// Qt main app setup
260278
QApplication app(argc, argv);
261-
app.setWindowIcon(QIcon("icon.ico"));
262-
263-
QSystemTrayIcon tray(QIcon("icon.ico"), &app);
264-
265-
QAction titleAction(QIcon("icon.ico"), "TIDAL - Discord RPC ", nullptr);
279+
app.setWindowIcon(QIcon(":assets/icon.ico"));
266280

281+
QSystemTrayIcon tray(QIcon(":assets/icon.ico"), &app);
282+
QAction titleAction(QIcon(":assets/icon.ico"), "TIDAL - Discord RPC ", nullptr);
267283
QAction changePresenceStatusAction("Running", nullptr);
268284
changePresenceStatusAction.setCheckable(true);
269285
changePresenceStatusAction.setChecked(true);
@@ -292,11 +308,12 @@ int main(int argc, char **argv) {
292308

293309
tray.show();
294310

311+
discordInit();
312+
// RPC loop call
295313
std::thread t1(rpcLoop);
296314
t1.detach();
297315

298-
discordInit();
299316

300317
return app.exec();
301318

302-
}
319+
}

0 commit comments

Comments
 (0)