Skip to content

Commit

Permalink
Minor Discord-RPC updates and Crowdin integration (#3224)
Browse files Browse the repository at this point in the history
  • Loading branch information
znvjder authored Nov 3, 2023
1 parent d7fb4cf commit 1511bdd
Show file tree
Hide file tree
Showing 13 changed files with 183 additions and 68 deletions.
24 changes: 18 additions & 6 deletions Client/core/CCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ template <>
CCore* CSingleton<CCore>::m_pSingleton = NULL;

static auto Win32LoadLibraryA = static_cast<decltype(&LoadLibraryA)>(nullptr);
static constexpr long long TIME_DISCORD_UPDATE_RICH_PRESENCE_RATE = 10000;

static HMODULE WINAPI SkipDirectPlay_LoadLibraryA(LPCSTR fileName)
{
Expand Down Expand Up @@ -158,6 +159,7 @@ CCore::CCore()
m_fMaxStreamingMemory = 0;
m_bGettingIdleCallsFromMultiplayer = false;
m_bWindowsTimerEnabled = false;
m_timeDiscordAppLastUpdate = 0;

// Create tray icon
m_pTrayIcon = new CTrayIcon();
Expand Down Expand Up @@ -665,13 +667,13 @@ void CCore::SetConnected(bool bConnected)

if (g_pCore->GetCVars()->GetValue("allow_discord_rpc", false))
{
auto discord = g_pCore->GetDiscord();
const auto discord = g_pCore->GetDiscord();
if (!discord->IsDiscordRPCEnabled())
discord->SetDiscordRPCEnabled(true);

discord->SetPresenceState(bConnected ? "In-game" : "Main menu", false);
discord->SetPresenceState(bConnected ? _("In-game") : _("Main menu"), false);
discord->SetPresenceStartTimestamp(0);
discord->SetPresenceDetails("");
discord->SetPresenceDetails("", false);

if (bConnected)
discord->SetPresenceStartTimestamp(time(nullptr));
Expand Down Expand Up @@ -1337,9 +1339,19 @@ void CCore::DoPostFramePulse()
GetGraphStats()->Draw();
m_pConnectManager->DoPulse();

static auto discord = g_pCore->GetDiscord();
if (discord && discord->IsDiscordRPCEnabled())
discord->UpdatePresence();
// Update Discord Rich Presence status
if (const long long ticks = GetTickCount64_(); ticks > m_timeDiscordAppLastUpdate + TIME_DISCORD_UPDATE_RICH_PRESENCE_RATE)
{
if (const auto discord = g_pCore->GetDiscord(); discord && discord->IsDiscordRPCEnabled())
{
discord->UpdatePresence();
m_timeDiscordAppLastUpdate = ticks;
#ifdef DISCORD_DISABLE_IO_THREAD
// Update manually if we're not using the IO thread
discord->UpdatePresenceConnection();
#endif
}
}

TIMING_CHECKPOINT("-CorePostFrame2");
}
Expand Down
2 changes: 2 additions & 0 deletions Client/core/CCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,4 +396,6 @@ class CCore : public CCoreInterface, public CSingleton<CCore>
static void ParseCommandLine(std::map<std::string, std::string>& options, const char*& szArgs, const char** pszNoValOptions = NULL);
std::map<std::string, std::string> m_CommandLineOptions; // e.g. "-o option" -> {"o" = "option"}
const char* m_szCommandLineArgs; // Everything that comes after the options

long long m_timeDiscordAppLastUpdate;
};
69 changes: 61 additions & 8 deletions Client/core/CDiscordRichPresence.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ CDiscordRichPresence::CDiscordRichPresence() : m_uiDiscordAppStart(0), m_uiDisco
SetDefaultData();

m_strDiscordAppState.clear();
m_bConnected = false;
}

CDiscordRichPresence::~CDiscordRichPresence()
Expand All @@ -37,15 +38,22 @@ void CDiscordRichPresence::InitializeDiscord()
DiscordEventHandlers handlers;
memset(&handlers, 0, sizeof(handlers));

// Handlers .ready .disconnected .errored maybe use in future?
handlers.ready = HandleDiscordReady;
handlers.errored = HandleDiscordError;
handlers.disconnected = HandleDiscordDisconnected;

Discord_Initialize((m_strDiscordAppCurrentId.empty()) ? DEFAULT_APP_ID : m_strDiscordAppCurrentId.c_str(), &handlers, 1, nullptr);

m_bDisallowCustomDetails = (m_strDiscordAppCurrentId == DEFAULT_APP_ID) ? true : false;
m_bConnected = true;
}

void CDiscordRichPresence::ShutdownDiscord()
{
Discord_ClearPresence();
Discord_Shutdown();

m_bConnected = false;
}

void CDiscordRichPresence::RestartDiscord()
Expand Down Expand Up @@ -76,13 +84,19 @@ void CDiscordRichPresence::SetDefaultData()

m_iPartySize = 0;
m_iPartyMax = 0;

m_iPlayersCount = 0;
m_iMaxPlayers = 0;
}

void CDiscordRichPresence::UpdatePresence()
{
// run callbacks
Discord_RunCallbacks();

if (!m_bUpdateRichPresence)
return;

DiscordRichPresence discordPresence;
memset(&discordPresence, 0, sizeof(discordPresence));

Expand All @@ -97,6 +111,7 @@ void CDiscordRichPresence::UpdatePresence()
(!m_strDiscordAppCustomDetails.empty() || !m_bDisallowCustomDetails) ? m_strDiscordAppCustomDetails.c_str() : m_strDiscordAppDetails.c_str();
discordPresence.startTimestamp = m_uiDiscordAppStart;
discordPresence.endTimestamp = m_uiDiscordAppEnd;
discordPresence.instance = 0;

DiscordButton buttons[2];
if (m_aButtons)
Expand All @@ -109,8 +124,8 @@ void CDiscordRichPresence::UpdatePresence()
discordPresence.buttons = buttons;
}

discordPresence.partySize = (m_bDisallowCustomDetails) ? 0 : m_iPartySize;
discordPresence.partyMax = (m_bDisallowCustomDetails) ? 0 : m_iPartyMax;
discordPresence.partySize = (m_bDisallowCustomDetails) ? m_iPlayersCount : m_iPartySize;
discordPresence.partyMax = (m_bDisallowCustomDetails) ? m_iMaxPlayers : m_iPartyMax;

Discord_UpdatePresence(&discordPresence);
m_bUpdateRichPresence = false;
Expand All @@ -128,7 +143,6 @@ void CDiscordRichPresence::SetPresenceEndTimestamp(const unsigned long ulEnd)
m_bUpdateRichPresence = true;
}


void CDiscordRichPresence::SetAssetLargeData(const char* szAsset, const char* szAssetText)
{
SetAsset(szAsset, szAssetText, true);
Expand Down Expand Up @@ -248,8 +262,47 @@ bool CDiscordRichPresence::IsDiscordCustomDetailsDisallowed() const
return m_bDisallowCustomDetails;
}

void CDiscordRichPresence::SetPresencePartySize(int iSize, int iMax)
void CDiscordRichPresence::SetPresencePartySize(int iSize, int iMax, bool bCustom)
{
if (bCustom)
{
m_iPartySize = iSize;
m_iPartyMax = iMax;
}
else
{
m_iPlayersCount = iSize;
m_iMaxPlayers = iMax;
}
}

#ifdef DISCORD_DISABLE_IO_THREAD
void CDiscordRichPresence::UpdatePresenceConnection()
{
Discord_UpdateConnection();
}
#endif

void CDiscordRichPresence::HandleDiscordReady(const DiscordUser* pDiscordUser)
{
if (const auto discord = g_pCore->GetDiscord(); discord && discord->IsDiscordRPCEnabled())
discord->SetDiscordClientConnected(true);
}

void CDiscordRichPresence::HandleDiscordDisconnected(int iErrorCode, const char* szMessage)
{
WriteDebugEvent(SString("[DISCORD] Disconnected %s (error #%d)", szMessage, iErrorCode));

if (const auto discord = g_pCore->GetDiscord(); discord)
discord->SetDiscordClientConnected(false);
}

void CDiscordRichPresence::HandleDiscordError(int iErrorCode, const char* szMessage)
{
WriteDebugEvent(SString("[DISCORD] Error: %s (error #%d)", szMessage, iErrorCode));
}

bool CDiscordRichPresence::IsDiscordClientConnected() const
{
m_iPartySize = iSize;
m_iPartyMax = iMax;
return m_bConnected;
}
25 changes: 18 additions & 7 deletions Client/core/CDiscordRichPresence.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,30 @@ class CDiscordRichPresence : public CDiscordInterface
void UpdatePresence();
void SetPresenceStartTimestamp(const unsigned long ulStart);
void SetPresenceEndTimestamp(const unsigned long ulEnd);
void SetAsset(const char* szAsset, const char* szAssetText, bool bIsLarge = false);
void SetAsset(const char* szAsset, const char* szAssetText, bool bIsLarge);
void SetAssetLargeData(const char* szAsset, const char* szAssetText);
void SetAssetSmallData(const char* szAsset, const char* szAssetText);

bool ResetDiscordData();
bool SetPresenceState(const char* szState, bool bCustom = false);
bool SetPresenceDetails(const char* szDetails, bool bCustom = false);
bool SetPresenceState(const char* szState, bool bCustom);
bool SetPresenceDetails(const char* szDetails, bool bCustom);
bool SetPresenceButtons(unsigned short int iIndex, const char* szName, const char* szUrl);
void SetPresencePartySize(int iSize, int iMax);
void SetPresencePartySize(int iSize, int iMax, bool bCustom);
bool SetDiscordRPCEnabled(bool bEnabled);
bool IsDiscordCustomDetailsDisallowed() const;
bool IsDiscordRPCEnabled() const;
bool SetApplicationID(const char* szAppID);
void SetDiscordClientConnected(bool bConnected) { m_bConnected = bConnected; };
bool IsDiscordClientConnected() const;

// void SetPresenceTimestamp();
// void SetPresenceImage();
// void SetPresenceText();
// handlers
static void HandleDiscordReady(const struct DiscordUser* pDiscordUser);
static void HandleDiscordDisconnected(int iErrorCode, const char* szMessage);
static void HandleDiscordError(int iErrorCode, const char* szMessage);

#ifdef DISCORD_DISABLE_IO_THREAD
void UpdatePresenceConnection();
#endif

private:
std::string m_strDiscordAppId;
Expand All @@ -66,7 +73,11 @@ class CDiscordRichPresence : public CDiscordInterface
bool m_bDisallowCustomDetails;
bool m_bDiscordRPCEnabled;
bool m_bUpdateRichPresence;
bool m_bConnected;

int m_iPartySize;
int m_iPartyMax;

int m_iPlayersCount;
int m_iMaxPlayers;
};
2 changes: 1 addition & 1 deletion Client/core/CMainMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,7 @@ CMainMenu::CMainMenu(CGUI* pManager)
if (!discord->IsDiscordRPCEnabled())
discord->SetDiscordRPCEnabled(true);

discord->SetPresenceState("Main menu", false);
discord->SetPresenceState(_("Main menu"), false);
discord->SetPresenceStartTimestamp(0);
}

Expand Down
6 changes: 3 additions & 3 deletions Client/core/CSettings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3454,15 +3454,15 @@ void CSettings::SaveData()

if (bAllowDiscordRPC)
{
auto discord = g_pCore->GetDiscord();
const auto discord = g_pCore->GetDiscord();

if (discord)
{
const char* state = "Main menu";
const char* state = _("Main menu");

if (g_pCore->IsConnected())
{
state = "In-game";
state = _("In-game");

const SString& serverName = g_pCore->GetLastConnectedServerName();
discord->SetPresenceDetails(serverName.c_str(), false);
Expand Down
56 changes: 44 additions & 12 deletions Client/mods/deathmatch/logic/CClientGame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,35 @@ CClientGame::CClientGame(bool bLocalPlay) : m_ServerInfo(new CServerInfo())

// Setup builtin Lua events
SetupGlobalLuaEvents();

// Setup default states for Rich Presence
g_vehicleTypePrefixes = {
_("Flying a UFO around"), _("Cruising around"), _("Riding the waves of"),
_("Riding the train in"), _("Flying around"), _("Flying around"),
_("Riding around"), _("Monster truckin' around"), _("Quaddin' around"),
_("Bunny hopping around"), _("Doing weird stuff in")
};

g_playerTaskStates = {
{TASK_COMPLEX_JUMP, {true, _("Climbing around in"), TASK_SIMPLE_CLIMB}},
{TASK_SIMPLE_GANG_DRIVEBY, {true, _("Doing a drive-by in")}},
{TASK_SIMPLE_DRIVEBY_SHOOT, {true, _("Doing a drive-by in")}},
{TASK_SIMPLE_DIE, {false, _("Blub blub..."), TASK_SIMPLE_DROWN}},
{TASK_SIMPLE_DIE, {false, _("Breathing water"), TASK_SIMPLE_DROWN}},
{TASK_SIMPLE_DIE, {true, _("Drowning in"), TASK_SIMPLE_DROWN}},
{TASK_SIMPLE_PLAYER_ON_FOOT, {true, _("Ducking for cover in"), {}, TASK_SIMPLE_DUCK, TASK_SECONDARY_DUCK}},
{TASK_SIMPLE_PLAYER_ON_FOOT, {true, _("Fighting in"), {}, TASK_SIMPLE_FIGHT, TASK_SECONDARY_ATTACK}},
{TASK_SIMPLE_PLAYER_ON_FOOT, {true, _("Throwing fists in"), {}, TASK_SIMPLE_FIGHT, TASK_SECONDARY_ATTACK}},
{TASK_SIMPLE_PLAYER_ON_FOOT, {true, _("Blastin' fools in"), {}, TASK_SIMPLE_USE_GUN, TASK_SECONDARY_ATTACK}},
{TASK_SIMPLE_PLAYER_ON_FOOT, {true, _("Shooting up"), {}, TASK_SIMPLE_USE_GUN, TASK_SECONDARY_ATTACK}},
{TASK_SIMPLE_JETPACK, {true, _("Jetpacking in")}},
{TASK_SIMPLE_PLAYER_ON_FOOT, {true, _("Literally on fire in"), {}, TASK_SIMPLE_PLAYER_ON_FIRE, TASK_SECONDARY_PARTIAL_ANIM}},
{TASK_SIMPLE_PLAYER_ON_FOOT, {true, _("Burning up in"), {}, TASK_SIMPLE_PLAYER_ON_FIRE, TASK_SECONDARY_PARTIAL_ANIM}},
{TASK_COMPLEX_IN_WATER, {true, _("Swimming in"), TASK_SIMPLE_SWIM}},
{TASK_COMPLEX_IN_WATER, {true, _("Floating around in"), TASK_SIMPLE_SWIM}},
{TASK_COMPLEX_IN_WATER, {false, _("Being chased by a shark"), TASK_SIMPLE_SWIM}},
{TASK_SIMPLE_CHOKING, {true, _("Choking to death in")}},
};
}

CClientGame::~CClientGame()
Expand Down Expand Up @@ -491,11 +520,11 @@ CClientGame::~CClientGame()
SetCursorEventsEnabled(false);

// Reset discord stuff
auto discord = g_pCore->GetDiscord();
const auto discord = g_pCore->GetDiscord();
if (discord && discord->IsDiscordRPCEnabled())
{
discord->ResetDiscordData();
discord->SetPresenceState("Main menu", false);
discord->SetPresenceState(_("Main menu"), false);
discord->UpdatePresence();
}

Expand Down Expand Up @@ -967,10 +996,10 @@ void CClientGame::DoPulsePostFrame()
// Check if we need to update the Discord Rich Presence state
if (const long long ticks = GetTickCount64_(); ticks > m_timeLastDiscordStateUpdate + TIME_DISCORD_UPDATE_RATE)
{
auto discord = g_pCore->GetDiscord();
const auto discord = g_pCore->GetDiscord();

if (discord && discord->IsDiscordRPCEnabled())
{
if (discord && discord->IsDiscordRPCEnabled() && discord->IsDiscordCustomDetailsDisallowed())
{
if (auto pLocalPlayer = g_pClientGame->GetLocalPlayer())
{
CVector position;
Expand All @@ -981,7 +1010,7 @@ void CClientGame::DoPulsePostFrame()

if (zoneName == "Unknown")
{
zoneName = "Area 51";
zoneName = _("Area 51");
}

auto taskManager = pLocalPlayer->GetTaskManager();
Expand All @@ -990,7 +1019,7 @@ void CClientGame::DoPulsePostFrame()
bool useZoneName = true;

const eClientVehicleType vehicleType = (pVehicle) ? CClientVehicleManager::GetVehicleType(pVehicle->GetModel()) : CLIENTVEHICLE_NONE;
std::string discordState = (pVehicle) ? g_vehicleTypePrefixes.at(vehicleType).c_str() : "Walking around ";
std::string discordState = (pVehicle) ? g_vehicleTypePrefixes.at(vehicleType).c_str() : _("Walking around ");

if (task && task->IsValid())
{
Expand Down Expand Up @@ -1051,9 +1080,10 @@ void CClientGame::DoPulsePostFrame()
}
else
{
discord->SetPresenceState("In-game", false);
discord->SetPresenceState(_("In-game"), false);
}

discord->SetPresencePartySize(m_pPlayerManager->Count(), g_pClientGame->GetServerInfo()->GetMaxPlayers(), false);
m_timeLastDiscordStateUpdate = ticks;
}
}
Expand Down Expand Up @@ -5656,11 +5686,13 @@ void CClientGame::DoWastedCheck(ElementID damagerID, unsigned char ucWeapon, uns
g_pNet->SendPacket(PACKET_ID_PLAYER_WASTED, pBitStream, PACKET_PRIORITY_HIGH, PACKET_RELIABILITY_RELIABLE_ORDERED);
g_pNet->DeallocateNetBitStream(pBitStream);

auto discord = g_pCore->GetDiscord();
if (discord->IsDiscordRPCEnabled())
const auto discord = g_pCore->GetDiscord();
if (discord && discord->IsDiscordRPCEnabled() && discord->IsDiscordCustomDetailsDisallowed())
{
static const std::vector<std::string> states{"In a ditch", "En-route to hospital", "Meeting their maker", "Regretting their decisions",
"Wasted"};
static const std::vector<std::string> states{
_("In a ditch"), _("En-route to hospital"), _("Meeting their maker"),
_("Regretting their decisions"), _("Wasted")
};

const std::string& state = states[rand() % states.size()];
discord->SetPresenceState(state.c_str(), false);
Expand Down
Loading

0 comments on commit 1511bdd

Please sign in to comment.