2024-03-14 00:15:26 +03:00

305 lines
8.1 KiB
C++

#include "STDInc.hpp"
#include <discord_rpc.h>
namespace Components
{
DiscordRichPresence discord_presence;
Discord::DiscordCustomInformation_t Discord::DiscordCustomInformation;
bool Discord_Presence_Initialized = false;
static const char* stock_sp_map_names[] =
{
"killhouse",
"cargoship",
"coup",
"blackout",
"armada",
"bog_a",
"hunted",
"ac130",
"bog_b",
"airlift",
"aftermath",
"village_assault",
"scoutsniper",
"sniperescape",
"village_defend",
"ambush",
"icbm",
"launchfacility_a",
"launchfacility_b",
"jeepride",
"simplecredits",
"airplane",
};
bool InMainMenu(std::string map_name_info)
{
if (map_name_info == "") return true;
else return false;
}
bool VanillaMap(std::string map_name_info)
{
for (const auto& map_name : stock_sp_map_names)
{
if (map_name == map_name_info)
return true;
}
return false;
}
std::string GetDifficultyForState(std::string map_name_info)
{
if (!InMainMenu(map_name_info))
{
const auto difficulty = Dvars::Functions::Dvar_FindVar("g_gameskill")->current.integer;
if (difficulty == 0)
return "IW3SP_MOD_LOC_DISCORD_DIFFICULTY_EASY";
else if (difficulty == 1)
return "IW3SP_MOD_LOC_DISCORD_DIFFICULTY_MEDIUM";
else if (difficulty == 2)
return "IW3SP_MOD_LOC_DISCORD_DIFFICULTY_HARD";
else if (difficulty == 3)
return "IW3SP_MOD_LOC_DISCORD_DIFFICULTY_FU";
else
return "IW3SP_MOD_LOC_DISCORD_DIFFICULTY_UNKNOWN";
}
else
return "";
}
std::string GetMapName(std::string map_name_info)
{
if (VanillaMap(map_name_info))
{
if(map_name_info.contains("ac130") && Dvars::Functions::Dvar_FindVar("credits_active")->current.string == "1"s)
return "IW3SP_MOD_LOC_DISCORD_SIMPLECREDITS";
return std::string("IW3SP_MOD_LOC_DISCORD_") + map_name_info.data();
}
else
{
if (InMainMenu(map_name_info))
return "IW3SP_MOD_LOC_DISCORD_MAINMENU";
else
return "custom_map";
}
}
void Discord::DiscordUpdate()
{
Discord_RunCallbacks();
std::string map_name_offset = reinterpret_cast<const char*>(0x1290DD8);
std::string mapname = GetMapName(map_name_offset.data());
std::string difficulty = GetDifficultyForState(map_name_offset.data());
if (InMainMenu(map_name_offset.data()))
{
DiscordCustomInformation.details.reset();
DiscordCustomInformation.state.reset();
DiscordCustomInformation.button = std::make_pair("", "");
DiscordCustomInformation.large_image_key.reset();
discord_presence.largeImageKey = "preview_mainmenu";
}
else
{
if (DiscordCustomInformation.large_image_key.has_value())
{
const auto& imageUrl = DiscordCustomInformation.large_image_key.value();
discord_presence.largeImageKey = imageUrl.data();
}
else
{
if (VanillaMap(map_name_offset.data()))
{
std::string imageKey = std::string("preview_") + map_name_offset.data();
discord_presence.largeImageKey = imageKey.data();
}
else discord_presence.largeImageKey = nullptr;
}
}
if (DiscordCustomInformation.details.has_value())
{
const auto& details_value = DiscordCustomInformation.details.value();
if (details_value.starts_with("@") && details_value.size() > 1)
{
const auto loc_string = details_value.substr(1);
const auto value = Game::UI_SafeTranslateString(loc_string.data());
discord_presence.details = value;
}
else
{
discord_presence.details = details_value.data();
}
}
else
{
if(mapname.contains("custom_map"))
discord_presence.details = Game::UI_ReplaceConversionString(Game::UI_SafeTranslateString("IW3SP_MOD_LOC_DISCORD_MAPUNKNOWN"), map_name_offset.c_str());
else
discord_presence.details = Game::UI_SafeTranslateString(mapname.data());
}
if (DiscordCustomInformation.state.has_value())
{
const auto& state_value = DiscordCustomInformation.state.value();
if (state_value.starts_with("@") && state_value.size() > 1)
{
const auto loc_string = state_value.substr(1);
const auto value = Game::UI_SafeTranslateString(loc_string.data());
discord_presence.state = value;
}
else discord_presence.state = state_value.data();
}
else
{
if (difficulty.data()) discord_presence.state = Game::UI_SafeTranslateString(difficulty.data());
else discord_presence.state = nullptr;
}
if (!DiscordCustomInformation.button.first.empty() && !DiscordCustomInformation.button.second.empty())
{
const auto& buttonLabel = DiscordCustomInformation.button.first;
const auto& buttonUrl = DiscordCustomInformation.button.second;
if (buttonLabel.starts_with("@") && buttonLabel.size() > 1)
{
const auto loc_string = buttonLabel.substr(1);
const auto value = Game::UI_SafeTranslateString(loc_string.data());
discord_presence.button2Label = value;
}
else discord_presence.button2Label = buttonLabel.data();
discord_presence.button2Url = buttonUrl.data();
}
else
{
discord_presence.button2Label = nullptr;
discord_presence.button2Url = nullptr;
}
if (!discord_presence.startTimestamp)
{
discord_presence.startTimestamp = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();
}
Discord_UpdatePresence(&discord_presence);
}
static void ready([[maybe_unused]] const DiscordUser* request)
{
ZeroMemory(&discord_presence, sizeof(discord_presence));
discord_presence.instance = 1;
discord_presence.state = "";
discord_presence.button1Label = "About IW3SP-MOD";
discord_presence.button1Url = "https://gitea.com/JerryALT/iw3sp_mod";
Discord_UpdatePresence(&discord_presence);
}
static void Errored(const int error_code, const char* message)
{
Game::Com_Printf(0, "Discord: (%i) %s", error_code, message);
}
void Discord::DiscordInit()
{
if (EnableDiscord_RPC && !Discord_Presence_Initialized)
{
DiscordEventHandlers handlers;
ZeroMemory(&handlers, sizeof(handlers));
handlers.ready = ready;
handlers.errored = Errored;
handlers.disconnected = Errored;
handlers.joinGame = nullptr;
handlers.spectateGame = nullptr;
handlers.joinRequest = nullptr;
Discord_Initialize("1088866597940248626", &handlers, 1, nullptr);
Discord_Presence_Initialized = true;
Scheduler::Loop(Discord::DiscordUpdate, Scheduler::Pipeline::MAIN, 5s);
}
}
void Discord::DiscordShutdown()
{
if (Discord_Presence_Initialized)
{
Discord_Shutdown();
Discord_Presence_Initialized = false;
}
}
Discord::Discord()
{
Discord::DiscordInit();
GSC::AddFunction("setdiscorddetails", []
{
if (Game::Scr_GetNumParam() != 1)
{
Game::Scr_Error("setdiscorddetails ( <string> detail ) requires 1 string parameter");
return;
}
const char* details = Game::Scr_GetString(0);
DiscordCustomInformation.details.emplace(details);
Scheduler::Once(Discord::DiscordUpdate, Scheduler::Pipeline::ASYNC);
Game::Scr_AddInt(true);
}, false);
GSC::AddFunction("setdiscordstate", []
{
if (Game::Scr_GetNumParam() != 1)
{
Game::Scr_Error("setdiscordstate ( <string> state ) requires 1 string parameter");
return;
}
const char* state = Game::Scr_GetString(0);
DiscordCustomInformation.state.emplace(state);
Scheduler::Once(Discord::DiscordUpdate, Scheduler::Pipeline::ASYNC);
Game::Scr_AddInt(true);
}, false);
GSC::AddFunction("setbuttoninformation", []
{
const char* label = Game::Scr_GetString(0);
const char* url = Game::Scr_GetString(1);
if (strlen(label) > 32)
{
Game::Scr_Error("URL label maximum is 32 characters");
return;
}
DiscordCustomInformation.button.first = label;
DiscordCustomInformation.button.second = url;
Scheduler::Once(Discord::DiscordUpdate, Scheduler::Pipeline::ASYNC);
Game::Scr_AddInt(true);
}, false);
GSC::AddFunction("setdiscordimage", []
{
if (Game::Scr_GetNumParam() != 1)
{
Game::Scr_Error("setdiscordimage ( <string> url ) requires 1 string parameter");
return;
}
const char* imageLink = Game::Scr_GetString(0);
DiscordCustomInformation.large_image_key.emplace(imageLink);
Scheduler::Once(Discord::DiscordUpdate, Scheduler::Pipeline::ASYNC);
Game::Scr_AddInt(true);
}, false);
}
Discord::~Discord()
{
Discord::DiscordShutdown();
}
}