Add discord rpc support

This commit is contained in:
Grinch_ 2022-03-10 04:23:08 +06:00
parent 420581056f
commit b62341284f
45 changed files with 5028 additions and 51 deletions

View File

@ -74,6 +74,7 @@
"xtr1common": "cpp", "xtr1common": "cpp",
"xtree": "cpp", "xtree": "cpp",
"xutility": "cpp", "xutility": "cpp",
"*.rh": "cpp" "*.rh": "cpp",
"csignal": "cpp"
} }
} }

View File

@ -0,0 +1,98 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "achievement_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
class AchievementEvents final {
public:
static void OnUserAchievementUpdate(void* callbackData, DiscordUserAchievement* userAchievement)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->AchievementManager();
module.OnUserAchievementUpdate(*reinterpret_cast<UserAchievement const*>(userAchievement));
}
};
IDiscordAchievementEvents AchievementManager::events_{
&AchievementEvents::OnUserAchievementUpdate,
};
void AchievementManager::SetUserAchievement(Snowflake achievementId,
std::uint8_t percentComplete,
std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->set_user_achievement(
internal_, achievementId, percentComplete, cb.release(), wrapper);
}
void AchievementManager::FetchUserAchievements(std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->fetch_user_achievements(internal_, cb.release(), wrapper);
}
void AchievementManager::CountUserAchievements(std::int32_t* count)
{
if (!count) {
return;
}
internal_->count_user_achievements(internal_, reinterpret_cast<int32_t*>(count));
}
Result AchievementManager::GetUserAchievement(Snowflake userAchievementId,
UserAchievement* userAchievement)
{
if (!userAchievement) {
return Result::InternalError;
}
auto result = internal_->get_user_achievement(
internal_, userAchievementId, reinterpret_cast<DiscordUserAchievement*>(userAchievement));
return static_cast<Result>(result);
}
Result AchievementManager::GetUserAchievementAt(std::int32_t index,
UserAchievement* userAchievement)
{
if (!userAchievement) {
return Result::InternalError;
}
auto result = internal_->get_user_achievement_at(
internal_, index, reinterpret_cast<DiscordUserAchievement*>(userAchievement));
return static_cast<Result>(result);
}
} // namespace discord

View File

@ -0,0 +1,34 @@
#pragma once
#include "types.h"
namespace discord {
class AchievementManager final {
public:
~AchievementManager() = default;
void SetUserAchievement(Snowflake achievementId,
std::uint8_t percentComplete,
std::function<void(Result)> callback);
void FetchUserAchievements(std::function<void(Result)> callback);
void CountUserAchievements(std::int32_t* count);
Result GetUserAchievement(Snowflake userAchievementId, UserAchievement* userAchievement);
Result GetUserAchievementAt(std::int32_t index, UserAchievement* userAchievement);
Event<UserAchievement const&> OnUserAchievementUpdate;
private:
friend class Core;
AchievementManager() = default;
AchievementManager(AchievementManager const& rhs) = delete;
AchievementManager& operator=(AchievementManager const& rhs) = delete;
AchievementManager(AchievementManager&& rhs) = delete;
AchievementManager& operator=(AchievementManager&& rhs) = delete;
IDiscordAchievementManager* internal_;
static IDiscordAchievementEvents events_;
};
} // namespace discord

View File

@ -0,0 +1,177 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "activity_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
class ActivityEvents final {
public:
static void OnActivityJoin(void* callbackData, char const* secret)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->ActivityManager();
module.OnActivityJoin(static_cast<const char*>(secret));
}
static void OnActivitySpectate(void* callbackData, char const* secret)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->ActivityManager();
module.OnActivitySpectate(static_cast<const char*>(secret));
}
static void OnActivityJoinRequest(void* callbackData, DiscordUser* user)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->ActivityManager();
module.OnActivityJoinRequest(*reinterpret_cast<User const*>(user));
}
static void OnActivityInvite(void* callbackData,
EDiscordActivityActionType type,
DiscordUser* user,
DiscordActivity* activity)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->ActivityManager();
module.OnActivityInvite(static_cast<ActivityActionType>(type),
*reinterpret_cast<User const*>(user),
*reinterpret_cast<Activity const*>(activity));
}
};
IDiscordActivityEvents ActivityManager::events_{
&ActivityEvents::OnActivityJoin,
&ActivityEvents::OnActivitySpectate,
&ActivityEvents::OnActivityJoinRequest,
&ActivityEvents::OnActivityInvite,
};
Result ActivityManager::RegisterCommand(char const* command)
{
auto result = internal_->register_command(internal_, const_cast<char*>(command));
return static_cast<Result>(result);
}
Result ActivityManager::RegisterSteam(std::uint32_t steamId)
{
auto result = internal_->register_steam(internal_, steamId);
return static_cast<Result>(result);
}
void ActivityManager::UpdateActivity(Activity const& activity, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->update_activity(internal_,
reinterpret_cast<DiscordActivity*>(const_cast<Activity*>(&activity)),
cb.release(),
wrapper);
}
void ActivityManager::ClearActivity(std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->clear_activity(internal_, cb.release(), wrapper);
}
void ActivityManager::SendRequestReply(UserId userId,
ActivityJoinRequestReply reply,
std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->send_request_reply(internal_,
userId,
static_cast<EDiscordActivityJoinRequestReply>(reply),
cb.release(),
wrapper);
}
void ActivityManager::SendInvite(UserId userId,
ActivityActionType type,
char const* content,
std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->send_invite(internal_,
userId,
static_cast<EDiscordActivityActionType>(type),
const_cast<char*>(content),
cb.release(),
wrapper);
}
void ActivityManager::AcceptInvite(UserId userId, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->accept_invite(internal_, userId, cb.release(), wrapper);
}
} // namespace discord

View File

@ -0,0 +1,42 @@
#pragma once
#include "types.h"
namespace discord {
class ActivityManager final {
public:
~ActivityManager() = default;
Result RegisterCommand(char const* command);
Result RegisterSteam(std::uint32_t steamId);
void UpdateActivity(Activity const& activity, std::function<void(Result)> callback);
void ClearActivity(std::function<void(Result)> callback);
void SendRequestReply(UserId userId,
ActivityJoinRequestReply reply,
std::function<void(Result)> callback);
void SendInvite(UserId userId,
ActivityActionType type,
char const* content,
std::function<void(Result)> callback);
void AcceptInvite(UserId userId, std::function<void(Result)> callback);
Event<char const*> OnActivityJoin;
Event<char const*> OnActivitySpectate;
Event<User const&> OnActivityJoinRequest;
Event<ActivityActionType, User const&, Activity const&> OnActivityInvite;
private:
friend class Core;
ActivityManager() = default;
ActivityManager(ActivityManager const& rhs) = delete;
ActivityManager& operator=(ActivityManager const& rhs) = delete;
ActivityManager(ActivityManager&& rhs) = delete;
ActivityManager& operator=(ActivityManager&& rhs) = delete;
IDiscordActivityManager* internal_;
static IDiscordActivityEvents events_;
};
} // namespace discord

View File

@ -0,0 +1,78 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "application_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
void ApplicationManager::ValidateOrExit(std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->validate_or_exit(internal_, cb.release(), wrapper);
}
void ApplicationManager::GetCurrentLocale(char locale[128])
{
if (!locale) {
return;
}
internal_->get_current_locale(internal_, reinterpret_cast<DiscordLocale*>(locale));
}
void ApplicationManager::GetCurrentBranch(char branch[4096])
{
if (!branch) {
return;
}
internal_->get_current_branch(internal_, reinterpret_cast<DiscordBranch*>(branch));
}
void ApplicationManager::GetOAuth2Token(std::function<void(Result, OAuth2Token const&)> callback)
{
static auto wrapper =
[](void* callbackData, EDiscordResult result, DiscordOAuth2Token* oauth2Token) -> void {
std::unique_ptr<std::function<void(Result, OAuth2Token const&)>> cb(
reinterpret_cast<std::function<void(Result, OAuth2Token const&)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result), *reinterpret_cast<OAuth2Token const*>(oauth2Token));
};
std::unique_ptr<std::function<void(Result, OAuth2Token const&)>> cb{};
cb.reset(new std::function<void(Result, OAuth2Token const&)>(std::move(callback)));
internal_->get_oauth2_token(internal_, cb.release(), wrapper);
}
void ApplicationManager::GetTicket(std::function<void(Result, char const*)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result, char const* data) -> void {
std::unique_ptr<std::function<void(Result, char const*)>> cb(
reinterpret_cast<std::function<void(Result, char const*)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result), static_cast<const char*>(data));
};
std::unique_ptr<std::function<void(Result, char const*)>> cb{};
cb.reset(new std::function<void(Result, char const*)>(std::move(callback)));
internal_->get_ticket(internal_, cb.release(), wrapper);
}
} // namespace discord

View File

@ -0,0 +1,30 @@
#pragma once
#include "types.h"
namespace discord {
class ApplicationManager final {
public:
~ApplicationManager() = default;
void ValidateOrExit(std::function<void(Result)> callback);
void GetCurrentLocale(char locale[128]);
void GetCurrentBranch(char branch[4096]);
void GetOAuth2Token(std::function<void(Result, OAuth2Token const&)> callback);
void GetTicket(std::function<void(Result, char const*)> callback);
private:
friend class Core;
ApplicationManager() = default;
ApplicationManager(ApplicationManager const& rhs) = delete;
ApplicationManager& operator=(ApplicationManager const& rhs) = delete;
ApplicationManager(ApplicationManager&& rhs) = delete;
ApplicationManager& operator=(ApplicationManager&& rhs) = delete;
IDiscordApplicationManager* internal_;
static IDiscordApplicationEvents events_;
};
} // namespace discord

182
depend/discord/core.cpp Normal file
View File

@ -0,0 +1,182 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
Result Core::Create(ClientId clientId, std::uint64_t flags, Core** instance)
{
if (!instance) {
return Result::InternalError;
}
(*instance) = new Core();
DiscordCreateParams params{};
DiscordCreateParamsSetDefault(&params);
params.client_id = clientId;
params.flags = flags;
params.events = nullptr;
params.event_data = *instance;
params.user_events = &UserManager::events_;
params.activity_events = &ActivityManager::events_;
params.relationship_events = &RelationshipManager::events_;
params.lobby_events = &LobbyManager::events_;
params.network_events = &NetworkManager::events_;
params.overlay_events = &OverlayManager::events_;
params.store_events = &StoreManager::events_;
params.voice_events = &VoiceManager::events_;
params.achievement_events = &AchievementManager::events_;
auto result = DiscordCreate(DISCORD_VERSION, &params, &((*instance)->internal_));
if (result != DiscordResult_Ok || !(*instance)->internal_) {
delete (*instance);
(*instance) = nullptr;
}
return static_cast<Result>(result);
}
Core::~Core()
{
if (internal_) {
internal_->destroy(internal_);
internal_ = nullptr;
}
}
Result Core::RunCallbacks()
{
auto result = internal_->run_callbacks(internal_);
return static_cast<Result>(result);
}
void Core::SetLogHook(LogLevel minLevel, std::function<void(LogLevel, char const*)> hook)
{
setLogHook_.DisconnectAll();
setLogHook_.Connect(std::move(hook));
static auto wrapper =
[](void* callbackData, EDiscordLogLevel level, char const* message) -> void {
auto cb(reinterpret_cast<decltype(setLogHook_)*>(callbackData));
if (!cb) {
return;
}
(*cb)(static_cast<LogLevel>(level), static_cast<const char*>(message));
};
internal_->set_log_hook(
internal_, static_cast<EDiscordLogLevel>(minLevel), &setLogHook_, wrapper);
}
discord::ApplicationManager& Core::ApplicationManager()
{
if (!applicationManager_.internal_) {
applicationManager_.internal_ = internal_->get_application_manager(internal_);
}
return applicationManager_;
}
discord::UserManager& Core::UserManager()
{
if (!userManager_.internal_) {
userManager_.internal_ = internal_->get_user_manager(internal_);
}
return userManager_;
}
discord::ImageManager& Core::ImageManager()
{
if (!imageManager_.internal_) {
imageManager_.internal_ = internal_->get_image_manager(internal_);
}
return imageManager_;
}
discord::ActivityManager& Core::ActivityManager()
{
if (!activityManager_.internal_) {
activityManager_.internal_ = internal_->get_activity_manager(internal_);
}
return activityManager_;
}
discord::RelationshipManager& Core::RelationshipManager()
{
if (!relationshipManager_.internal_) {
relationshipManager_.internal_ = internal_->get_relationship_manager(internal_);
}
return relationshipManager_;
}
discord::LobbyManager& Core::LobbyManager()
{
if (!lobbyManager_.internal_) {
lobbyManager_.internal_ = internal_->get_lobby_manager(internal_);
}
return lobbyManager_;
}
discord::NetworkManager& Core::NetworkManager()
{
if (!networkManager_.internal_) {
networkManager_.internal_ = internal_->get_network_manager(internal_);
}
return networkManager_;
}
discord::OverlayManager& Core::OverlayManager()
{
if (!overlayManager_.internal_) {
overlayManager_.internal_ = internal_->get_overlay_manager(internal_);
}
return overlayManager_;
}
discord::StorageManager& Core::StorageManager()
{
if (!storageManager_.internal_) {
storageManager_.internal_ = internal_->get_storage_manager(internal_);
}
return storageManager_;
}
discord::StoreManager& Core::StoreManager()
{
if (!storeManager_.internal_) {
storeManager_.internal_ = internal_->get_store_manager(internal_);
}
return storeManager_;
}
discord::VoiceManager& Core::VoiceManager()
{
if (!voiceManager_.internal_) {
voiceManager_.internal_ = internal_->get_voice_manager(internal_);
}
return voiceManager_;
}
discord::AchievementManager& Core::AchievementManager()
{
if (!achievementManager_.internal_) {
achievementManager_.internal_ = internal_->get_achievement_manager(internal_);
}
return achievementManager_;
}
} // namespace discord

64
depend/discord/core.h Normal file
View File

@ -0,0 +1,64 @@
#pragma once
#include "types.h"
#include "application_manager.h"
#include "user_manager.h"
#include "image_manager.h"
#include "activity_manager.h"
#include "relationship_manager.h"
#include "lobby_manager.h"
#include "network_manager.h"
#include "overlay_manager.h"
#include "storage_manager.h"
#include "store_manager.h"
#include "voice_manager.h"
#include "achievement_manager.h"
namespace discord {
class Core final {
public:
static Result Create(ClientId clientId, std::uint64_t flags, Core** instance);
~Core();
Result RunCallbacks();
void SetLogHook(LogLevel minLevel, std::function<void(LogLevel, char const*)> hook);
discord::ApplicationManager& ApplicationManager();
discord::UserManager& UserManager();
discord::ImageManager& ImageManager();
discord::ActivityManager& ActivityManager();
discord::RelationshipManager& RelationshipManager();
discord::LobbyManager& LobbyManager();
discord::NetworkManager& NetworkManager();
discord::OverlayManager& OverlayManager();
discord::StorageManager& StorageManager();
discord::StoreManager& StoreManager();
discord::VoiceManager& VoiceManager();
discord::AchievementManager& AchievementManager();
private:
Core() = default;
Core(Core const& rhs) = delete;
Core& operator=(Core const& rhs) = delete;
Core(Core&& rhs) = delete;
Core& operator=(Core&& rhs) = delete;
IDiscordCore* internal_;
Event<LogLevel, char const*> setLogHook_;
discord::ApplicationManager applicationManager_;
discord::UserManager userManager_;
discord::ImageManager imageManager_;
discord::ActivityManager activityManager_;
discord::RelationshipManager relationshipManager_;
discord::LobbyManager lobbyManager_;
discord::NetworkManager networkManager_;
discord::OverlayManager overlayManager_;
discord::StorageManager storageManager_;
discord::StoreManager storeManager_;
discord::VoiceManager voiceManager_;
discord::AchievementManager achievementManager_;
};
} // namespace discord

16
depend/discord/discord.h Normal file
View File

@ -0,0 +1,16 @@
#pragma once
#include "types.h"
#include "core.h"
#include "application_manager.h"
#include "user_manager.h"
#include "image_manager.h"
#include "activity_manager.h"
#include "relationship_manager.h"
#include "lobby_manager.h"
#include "network_manager.h"
#include "overlay_manager.h"
#include "storage_manager.h"
#include "store_manager.h"
#include "voice_manager.h"
#include "achievement_manager.h"

59
depend/discord/event.h Normal file
View File

@ -0,0 +1,59 @@
#pragma once
#include <functional>
#include <vector>
namespace discord {
template <typename... Args>
class Event final {
public:
using Token = int;
Event() { slots_.reserve(4); }
Event(Event const&) = default;
Event(Event&&) = default;
~Event() = default;
Event& operator=(Event const&) = default;
Event& operator=(Event&&) = default;
template <typename EventHandler>
Token Connect(EventHandler slot)
{
slots_.emplace_back(Slot{nextToken_, std::move(slot)});
return nextToken_++;
}
void Disconnect(Token token)
{
for (auto& slot : slots_) {
if (slot.token == token) {
slot = slots_.back();
slots_.pop_back();
break;
}
}
}
void DisconnectAll() { slots_ = {}; }
void operator()(Args... args)
{
for (auto const& slot : slots_) {
slot.fn(std::forward<Args>(args)...);
}
}
private:
struct Slot {
Token token;
std::function<void(Args...)> fn;
};
Token nextToken_{};
std::vector<Slot> slots_{};
};
} // namespace discord

942
depend/discord/ffi.h Normal file
View File

@ -0,0 +1,942 @@
#ifndef _DISCORD_GAME_SDK_H_
#define _DISCORD_GAME_SDK_H_
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <string.h>
#ifndef __cplusplus
#include <stdbool.h>
#endif
#define DISCORD_VERSION 2
#define DISCORD_APPLICATION_MANAGER_VERSION 1
#define DISCORD_USER_MANAGER_VERSION 1
#define DISCORD_IMAGE_MANAGER_VERSION 1
#define DISCORD_ACTIVITY_MANAGER_VERSION 1
#define DISCORD_RELATIONSHIP_MANAGER_VERSION 1
#define DISCORD_LOBBY_MANAGER_VERSION 1
#define DISCORD_NETWORK_MANAGER_VERSION 1
#define DISCORD_OVERLAY_MANAGER_VERSION 1
#define DISCORD_STORAGE_MANAGER_VERSION 1
#define DISCORD_STORE_MANAGER_VERSION 1
#define DISCORD_VOICE_MANAGER_VERSION 1
#define DISCORD_ACHIEVEMENT_MANAGER_VERSION 1
enum EDiscordResult {
DiscordResult_Ok = 0,
DiscordResult_ServiceUnavailable = 1,
DiscordResult_InvalidVersion = 2,
DiscordResult_LockFailed = 3,
DiscordResult_InternalError = 4,
DiscordResult_InvalidPayload = 5,
DiscordResult_InvalidCommand = 6,
DiscordResult_InvalidPermissions = 7,
DiscordResult_NotFetched = 8,
DiscordResult_NotFound = 9,
DiscordResult_Conflict = 10,
DiscordResult_InvalidSecret = 11,
DiscordResult_InvalidJoinSecret = 12,
DiscordResult_NoEligibleActivity = 13,
DiscordResult_InvalidInvite = 14,
DiscordResult_NotAuthenticated = 15,
DiscordResult_InvalidAccessToken = 16,
DiscordResult_ApplicationMismatch = 17,
DiscordResult_InvalidDataUrl = 18,
DiscordResult_InvalidBase64 = 19,
DiscordResult_NotFiltered = 20,
DiscordResult_LobbyFull = 21,
DiscordResult_InvalidLobbySecret = 22,
DiscordResult_InvalidFilename = 23,
DiscordResult_InvalidFileSize = 24,
DiscordResult_InvalidEntitlement = 25,
DiscordResult_NotInstalled = 26,
DiscordResult_NotRunning = 27,
DiscordResult_InsufficientBuffer = 28,
DiscordResult_PurchaseCanceled = 29,
DiscordResult_InvalidGuild = 30,
DiscordResult_InvalidEvent = 31,
DiscordResult_InvalidChannel = 32,
DiscordResult_InvalidOrigin = 33,
DiscordResult_RateLimited = 34,
DiscordResult_OAuth2Error = 35,
DiscordResult_SelectChannelTimeout = 36,
DiscordResult_GetGuildTimeout = 37,
DiscordResult_SelectVoiceForceRequired = 38,
DiscordResult_CaptureShortcutAlreadyListening = 39,
DiscordResult_UnauthorizedForAchievement = 40,
DiscordResult_InvalidGiftCode = 41,
DiscordResult_PurchaseError = 42,
DiscordResult_TransactionAborted = 43,
};
enum EDiscordCreateFlags {
DiscordCreateFlags_Default = 0,
DiscordCreateFlags_NoRequireDiscord = 1,
};
enum EDiscordLogLevel {
DiscordLogLevel_Error = 1,
DiscordLogLevel_Warn,
DiscordLogLevel_Info,
DiscordLogLevel_Debug,
};
enum EDiscordUserFlag {
DiscordUserFlag_Partner = 2,
DiscordUserFlag_HypeSquadEvents = 4,
DiscordUserFlag_HypeSquadHouse1 = 64,
DiscordUserFlag_HypeSquadHouse2 = 128,
DiscordUserFlag_HypeSquadHouse3 = 256,
};
enum EDiscordPremiumType {
DiscordPremiumType_None = 0,
DiscordPremiumType_Tier1 = 1,
DiscordPremiumType_Tier2 = 2,
};
enum EDiscordImageType {
DiscordImageType_User,
};
enum EDiscordActivityType {
DiscordActivityType_Playing,
DiscordActivityType_Streaming,
DiscordActivityType_Listening,
DiscordActivityType_Watching,
};
enum EDiscordActivityActionType {
DiscordActivityActionType_Join = 1,
DiscordActivityActionType_Spectate,
};
enum EDiscordActivityJoinRequestReply {
DiscordActivityJoinRequestReply_No,
DiscordActivityJoinRequestReply_Yes,
DiscordActivityJoinRequestReply_Ignore,
};
enum EDiscordStatus {
DiscordStatus_Offline = 0,
DiscordStatus_Online = 1,
DiscordStatus_Idle = 2,
DiscordStatus_DoNotDisturb = 3,
};
enum EDiscordRelationshipType {
DiscordRelationshipType_None,
DiscordRelationshipType_Friend,
DiscordRelationshipType_Blocked,
DiscordRelationshipType_PendingIncoming,
DiscordRelationshipType_PendingOutgoing,
DiscordRelationshipType_Implicit,
};
enum EDiscordLobbyType {
DiscordLobbyType_Private = 1,
DiscordLobbyType_Public,
};
enum EDiscordLobbySearchComparison {
DiscordLobbySearchComparison_LessThanOrEqual = -2,
DiscordLobbySearchComparison_LessThan,
DiscordLobbySearchComparison_Equal,
DiscordLobbySearchComparison_GreaterThan,
DiscordLobbySearchComparison_GreaterThanOrEqual,
DiscordLobbySearchComparison_NotEqual,
};
enum EDiscordLobbySearchCast {
DiscordLobbySearchCast_String = 1,
DiscordLobbySearchCast_Number,
};
enum EDiscordLobbySearchDistance {
DiscordLobbySearchDistance_Local,
DiscordLobbySearchDistance_Default,
DiscordLobbySearchDistance_Extended,
DiscordLobbySearchDistance_Global,
};
enum EDiscordEntitlementType {
DiscordEntitlementType_Purchase = 1,
DiscordEntitlementType_PremiumSubscription,
DiscordEntitlementType_DeveloperGift,
DiscordEntitlementType_TestModePurchase,
DiscordEntitlementType_FreePurchase,
DiscordEntitlementType_UserGift,
DiscordEntitlementType_PremiumPurchase,
};
enum EDiscordSkuType {
DiscordSkuType_Application = 1,
DiscordSkuType_DLC,
DiscordSkuType_Consumable,
DiscordSkuType_Bundle,
};
enum EDiscordInputModeType {
DiscordInputModeType_VoiceActivity = 0,
DiscordInputModeType_PushToTalk,
};
typedef int64_t DiscordClientId;
typedef int32_t DiscordVersion;
typedef int64_t DiscordSnowflake;
typedef int64_t DiscordTimestamp;
typedef DiscordSnowflake DiscordUserId;
typedef char DiscordLocale[128];
typedef char DiscordBranch[4096];
typedef DiscordSnowflake DiscordLobbyId;
typedef char DiscordLobbySecret[128];
typedef char DiscordMetadataKey[256];
typedef char DiscordMetadataValue[4096];
typedef uint64_t DiscordNetworkPeerId;
typedef uint8_t DiscordNetworkChannelId;
typedef char DiscordPath[4096];
typedef char DiscordDateTime[64];
struct DiscordUser {
DiscordUserId id;
char username[256];
char discriminator[8];
char avatar[128];
bool bot;
};
struct DiscordOAuth2Token {
char access_token[128];
char scopes[1024];
DiscordTimestamp expires;
};
struct DiscordImageHandle {
enum EDiscordImageType type;
int64_t id;
uint32_t size;
};
struct DiscordImageDimensions {
uint32_t width;
uint32_t height;
};
struct DiscordActivityTimestamps {
DiscordTimestamp start;
DiscordTimestamp end;
};
struct DiscordActivityAssets {
char large_image[128];
char large_text[128];
char small_image[128];
char small_text[128];
};
struct DiscordPartySize {
int32_t current_size;
int32_t max_size;
};
struct DiscordActivityParty {
char id[128];
struct DiscordPartySize size;
};
struct DiscordActivitySecrets {
char match[128];
char join[128];
char spectate[128];
};
struct DiscordActivity {
enum EDiscordActivityType type;
int64_t application_id;
char name[128];
char state[128];
char details[128];
struct DiscordActivityTimestamps timestamps;
struct DiscordActivityAssets assets;
struct DiscordActivityParty party;
struct DiscordActivitySecrets secrets;
bool instance;
};
struct DiscordPresence {
enum EDiscordStatus status;
struct DiscordActivity activity;
};
struct DiscordRelationship {
enum EDiscordRelationshipType type;
struct DiscordUser user;
struct DiscordPresence presence;
};
struct DiscordLobby {
DiscordLobbyId id;
enum EDiscordLobbyType type;
DiscordUserId owner_id;
DiscordLobbySecret secret;
uint32_t capacity;
bool locked;
};
struct DiscordFileStat {
char filename[260];
uint64_t size;
uint64_t last_modified;
};
struct DiscordEntitlement {
DiscordSnowflake id;
enum EDiscordEntitlementType type;
DiscordSnowflake sku_id;
};
struct DiscordSkuPrice {
uint32_t amount;
char currency[16];
};
struct DiscordSku {
DiscordSnowflake id;
enum EDiscordSkuType type;
char name[256];
struct DiscordSkuPrice price;
};
struct DiscordInputMode {
enum EDiscordInputModeType type;
char shortcut[256];
};
struct DiscordUserAchievement {
DiscordSnowflake user_id;
DiscordSnowflake achievement_id;
uint8_t percent_complete;
DiscordDateTime unlocked_at;
};
struct IDiscordLobbyTransaction {
enum EDiscordResult (*set_type)(struct IDiscordLobbyTransaction* lobby_transaction,
enum EDiscordLobbyType type);
enum EDiscordResult (*set_owner)(struct IDiscordLobbyTransaction* lobby_transaction,
DiscordUserId owner_id);
enum EDiscordResult (*set_capacity)(struct IDiscordLobbyTransaction* lobby_transaction,
uint32_t capacity);
enum EDiscordResult (*set_metadata)(struct IDiscordLobbyTransaction* lobby_transaction,
DiscordMetadataKey key,
DiscordMetadataValue value);
enum EDiscordResult (*delete_metadata)(struct IDiscordLobbyTransaction* lobby_transaction,
DiscordMetadataKey key);
enum EDiscordResult (*set_locked)(struct IDiscordLobbyTransaction* lobby_transaction,
bool locked);
};
struct IDiscordLobbyMemberTransaction {
enum EDiscordResult (*set_metadata)(
struct IDiscordLobbyMemberTransaction* lobby_member_transaction,
DiscordMetadataKey key,
DiscordMetadataValue value);
enum EDiscordResult (*delete_metadata)(
struct IDiscordLobbyMemberTransaction* lobby_member_transaction,
DiscordMetadataKey key);
};
struct IDiscordLobbySearchQuery {
enum EDiscordResult (*filter)(struct IDiscordLobbySearchQuery* lobby_search_query,
DiscordMetadataKey key,
enum EDiscordLobbySearchComparison comparison,
enum EDiscordLobbySearchCast cast,
DiscordMetadataValue value);
enum EDiscordResult (*sort)(struct IDiscordLobbySearchQuery* lobby_search_query,
DiscordMetadataKey key,
enum EDiscordLobbySearchCast cast,
DiscordMetadataValue value);
enum EDiscordResult (*limit)(struct IDiscordLobbySearchQuery* lobby_search_query,
uint32_t limit);
enum EDiscordResult (*distance)(struct IDiscordLobbySearchQuery* lobby_search_query,
enum EDiscordLobbySearchDistance distance);
};
typedef void* IDiscordApplicationEvents;
struct IDiscordApplicationManager {
void (*validate_or_exit)(struct IDiscordApplicationManager* manager,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*get_current_locale)(struct IDiscordApplicationManager* manager, DiscordLocale* locale);
void (*get_current_branch)(struct IDiscordApplicationManager* manager, DiscordBranch* branch);
void (*get_oauth2_token)(struct IDiscordApplicationManager* manager,
void* callback_data,
void (*callback)(void* callback_data,
enum EDiscordResult result,
struct DiscordOAuth2Token* oauth2_token));
void (*get_ticket)(struct IDiscordApplicationManager* manager,
void* callback_data,
void (*callback)(void* callback_data,
enum EDiscordResult result,
const char* data));
};
struct IDiscordUserEvents {
void (*on_current_user_update)(void* event_data);
};
struct IDiscordUserManager {
enum EDiscordResult (*get_current_user)(struct IDiscordUserManager* manager,
struct DiscordUser* current_user);
void (*get_user)(struct IDiscordUserManager* manager,
DiscordUserId user_id,
void* callback_data,
void (*callback)(void* callback_data,
enum EDiscordResult result,
struct DiscordUser* user));
enum EDiscordResult (*get_current_user_premium_type)(struct IDiscordUserManager* manager,
enum EDiscordPremiumType* premium_type);
enum EDiscordResult (*current_user_has_flag)(struct IDiscordUserManager* manager,
enum EDiscordUserFlag flag,
bool* has_flag);
};
typedef void* IDiscordImageEvents;
struct IDiscordImageManager {
void (*fetch)(struct IDiscordImageManager* manager,
struct DiscordImageHandle handle,
bool refresh,
void* callback_data,
void (*callback)(void* callback_data,
enum EDiscordResult result,
struct DiscordImageHandle handle_result));
enum EDiscordResult (*get_dimensions)(struct IDiscordImageManager* manager,
struct DiscordImageHandle handle,
struct DiscordImageDimensions* dimensions);
enum EDiscordResult (*get_data)(struct IDiscordImageManager* manager,
struct DiscordImageHandle handle,
uint8_t* data,
uint32_t data_length);
};
struct IDiscordActivityEvents {
void (*on_activity_join)(void* event_data, const char* secret);
void (*on_activity_spectate)(void* event_data, const char* secret);
void (*on_activity_join_request)(void* event_data, struct DiscordUser* user);
void (*on_activity_invite)(void* event_data,
enum EDiscordActivityActionType type,
struct DiscordUser* user,
struct DiscordActivity* activity);
};
struct IDiscordActivityManager {
enum EDiscordResult (*register_command)(struct IDiscordActivityManager* manager,
const char* command);
enum EDiscordResult (*register_steam)(struct IDiscordActivityManager* manager,
uint32_t steam_id);
void (*update_activity)(struct IDiscordActivityManager* manager,
struct DiscordActivity* activity,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*clear_activity)(struct IDiscordActivityManager* manager,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*send_request_reply)(struct IDiscordActivityManager* manager,
DiscordUserId user_id,
enum EDiscordActivityJoinRequestReply reply,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*send_invite)(struct IDiscordActivityManager* manager,
DiscordUserId user_id,
enum EDiscordActivityActionType type,
const char* content,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*accept_invite)(struct IDiscordActivityManager* manager,
DiscordUserId user_id,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
};
struct IDiscordRelationshipEvents {
void (*on_refresh)(void* event_data);
void (*on_relationship_update)(void* event_data, struct DiscordRelationship* relationship);
};
struct IDiscordRelationshipManager {
void (*filter)(struct IDiscordRelationshipManager* manager,
void* filter_data,
bool (*filter)(void* filter_data, struct DiscordRelationship* relationship));
enum EDiscordResult (*count)(struct IDiscordRelationshipManager* manager, int32_t* count);
enum EDiscordResult (*get)(struct IDiscordRelationshipManager* manager,
DiscordUserId user_id,
struct DiscordRelationship* relationship);
enum EDiscordResult (*get_at)(struct IDiscordRelationshipManager* manager,
uint32_t index,
struct DiscordRelationship* relationship);
};
struct IDiscordLobbyEvents {
void (*on_lobby_update)(void* event_data, int64_t lobby_id);
void (*on_lobby_delete)(void* event_data, int64_t lobby_id, uint32_t reason);
void (*on_member_connect)(void* event_data, int64_t lobby_id, int64_t user_id);
void (*on_member_update)(void* event_data, int64_t lobby_id, int64_t user_id);
void (*on_member_disconnect)(void* event_data, int64_t lobby_id, int64_t user_id);
void (*on_lobby_message)(void* event_data,
int64_t lobby_id,
int64_t user_id,
uint8_t* data,
uint32_t data_length);
void (*on_speaking)(void* event_data, int64_t lobby_id, int64_t user_id, bool speaking);
void (*on_network_message)(void* event_data,
int64_t lobby_id,
int64_t user_id,
uint8_t channel_id,
uint8_t* data,
uint32_t data_length);
};
struct IDiscordLobbyManager {
enum EDiscordResult (*get_lobby_create_transaction)(
struct IDiscordLobbyManager* manager,
struct IDiscordLobbyTransaction** transaction);
enum EDiscordResult (*get_lobby_update_transaction)(
struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
struct IDiscordLobbyTransaction** transaction);
enum EDiscordResult (*get_member_update_transaction)(
struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
DiscordUserId user_id,
struct IDiscordLobbyMemberTransaction** transaction);
void (*create_lobby)(struct IDiscordLobbyManager* manager,
struct IDiscordLobbyTransaction* transaction,
void* callback_data,
void (*callback)(void* callback_data,
enum EDiscordResult result,
struct DiscordLobby* lobby));
void (*update_lobby)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
struct IDiscordLobbyTransaction* transaction,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*delete_lobby)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*connect_lobby)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
DiscordLobbySecret secret,
void* callback_data,
void (*callback)(void* callback_data,
enum EDiscordResult result,
struct DiscordLobby* lobby));
void (*connect_lobby_with_activity_secret)(struct IDiscordLobbyManager* manager,
DiscordLobbySecret activity_secret,
void* callback_data,
void (*callback)(void* callback_data,
enum EDiscordResult result,
struct DiscordLobby* lobby));
void (*disconnect_lobby)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
enum EDiscordResult (*get_lobby)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
struct DiscordLobby* lobby);
enum EDiscordResult (*get_lobby_activity_secret)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
DiscordLobbySecret* secret);
enum EDiscordResult (*get_lobby_metadata_value)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
DiscordMetadataKey key,
DiscordMetadataValue* value);
enum EDiscordResult (*get_lobby_metadata_key)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
int32_t index,
DiscordMetadataKey* key);
enum EDiscordResult (*lobby_metadata_count)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
int32_t* count);
enum EDiscordResult (*member_count)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
int32_t* count);
enum EDiscordResult (*get_member_user_id)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
int32_t index,
DiscordUserId* user_id);
enum EDiscordResult (*get_member_user)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
DiscordUserId user_id,
struct DiscordUser* user);
enum EDiscordResult (*get_member_metadata_value)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
DiscordUserId user_id,
DiscordMetadataKey key,
DiscordMetadataValue* value);
enum EDiscordResult (*get_member_metadata_key)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
DiscordUserId user_id,
int32_t index,
DiscordMetadataKey* key);
enum EDiscordResult (*member_metadata_count)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
DiscordUserId user_id,
int32_t* count);
void (*update_member)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
DiscordUserId user_id,
struct IDiscordLobbyMemberTransaction* transaction,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*send_lobby_message)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
uint8_t* data,
uint32_t data_length,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
enum EDiscordResult (*get_search_query)(struct IDiscordLobbyManager* manager,
struct IDiscordLobbySearchQuery** query);
void (*search)(struct IDiscordLobbyManager* manager,
struct IDiscordLobbySearchQuery* query,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*lobby_count)(struct IDiscordLobbyManager* manager, int32_t* count);
enum EDiscordResult (*get_lobby_id)(struct IDiscordLobbyManager* manager,
int32_t index,
DiscordLobbyId* lobby_id);
void (*connect_voice)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*disconnect_voice)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
enum EDiscordResult (*connect_network)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id);
enum EDiscordResult (*disconnect_network)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id);
enum EDiscordResult (*flush_network)(struct IDiscordLobbyManager* manager);
enum EDiscordResult (*open_network_channel)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
uint8_t channel_id,
bool reliable);
enum EDiscordResult (*send_network_message)(struct IDiscordLobbyManager* manager,
DiscordLobbyId lobby_id,
DiscordUserId user_id,
uint8_t channel_id,
uint8_t* data,
uint32_t data_length);
};
struct IDiscordNetworkEvents {
void (*on_message)(void* event_data,
DiscordNetworkPeerId peer_id,
DiscordNetworkChannelId channel_id,
uint8_t* data,
uint32_t data_length);
void (*on_route_update)(void* event_data, const char* route_data);
};
struct IDiscordNetworkManager {
/**
* Get the local peer ID for this process.
*/
void (*get_peer_id)(struct IDiscordNetworkManager* manager, DiscordNetworkPeerId* peer_id);
/**
* Send pending network messages.
*/
enum EDiscordResult (*flush)(struct IDiscordNetworkManager* manager);
/**
* Open a connection to a remote peer.
*/
enum EDiscordResult (*open_peer)(struct IDiscordNetworkManager* manager,
DiscordNetworkPeerId peer_id,
const char* route_data);
/**
* Update the route data for a connected peer.
*/
enum EDiscordResult (*update_peer)(struct IDiscordNetworkManager* manager,
DiscordNetworkPeerId peer_id,
const char* route_data);
/**
* Close the connection to a remote peer.
*/
enum EDiscordResult (*close_peer)(struct IDiscordNetworkManager* manager,
DiscordNetworkPeerId peer_id);
/**
* Open a message channel to a connected peer.
*/
enum EDiscordResult (*open_channel)(struct IDiscordNetworkManager* manager,
DiscordNetworkPeerId peer_id,
DiscordNetworkChannelId channel_id,
bool reliable);
/**
* Close a message channel to a connected peer.
*/
enum EDiscordResult (*close_channel)(struct IDiscordNetworkManager* manager,
DiscordNetworkPeerId peer_id,
DiscordNetworkChannelId channel_id);
/**
* Send a message to a connected peer over an opened message channel.
*/
enum EDiscordResult (*send_message)(struct IDiscordNetworkManager* manager,
DiscordNetworkPeerId peer_id,
DiscordNetworkChannelId channel_id,
uint8_t* data,
uint32_t data_length);
};
struct IDiscordOverlayEvents {
void (*on_toggle)(void* event_data, bool locked);
};
struct IDiscordOverlayManager {
void (*is_enabled)(struct IDiscordOverlayManager* manager, bool* enabled);
void (*is_locked)(struct IDiscordOverlayManager* manager, bool* locked);
void (*set_locked)(struct IDiscordOverlayManager* manager,
bool locked,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*open_activity_invite)(struct IDiscordOverlayManager* manager,
enum EDiscordActivityActionType type,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*open_guild_invite)(struct IDiscordOverlayManager* manager,
const char* code,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*open_voice_settings)(struct IDiscordOverlayManager* manager,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
};
typedef void* IDiscordStorageEvents;
struct IDiscordStorageManager {
enum EDiscordResult (*read)(struct IDiscordStorageManager* manager,
const char* name,
uint8_t* data,
uint32_t data_length,
uint32_t* read);
void (*read_async)(struct IDiscordStorageManager* manager,
const char* name,
void* callback_data,
void (*callback)(void* callback_data,
enum EDiscordResult result,
uint8_t* data,
uint32_t data_length));
void (*read_async_partial)(struct IDiscordStorageManager* manager,
const char* name,
uint64_t offset,
uint64_t length,
void* callback_data,
void (*callback)(void* callback_data,
enum EDiscordResult result,
uint8_t* data,
uint32_t data_length));
enum EDiscordResult (*write)(struct IDiscordStorageManager* manager,
const char* name,
uint8_t* data,
uint32_t data_length);
void (*write_async)(struct IDiscordStorageManager* manager,
const char* name,
uint8_t* data,
uint32_t data_length,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
enum EDiscordResult (*delete_)(struct IDiscordStorageManager* manager, const char* name);
enum EDiscordResult (*exists)(struct IDiscordStorageManager* manager,
const char* name,
bool* exists);
void (*count)(struct IDiscordStorageManager* manager, int32_t* count);
enum EDiscordResult (*stat)(struct IDiscordStorageManager* manager,
const char* name,
struct DiscordFileStat* stat);
enum EDiscordResult (*stat_at)(struct IDiscordStorageManager* manager,
int32_t index,
struct DiscordFileStat* stat);
enum EDiscordResult (*get_path)(struct IDiscordStorageManager* manager, DiscordPath* path);
};
struct IDiscordStoreEvents {
void (*on_entitlement_create)(void* event_data, struct DiscordEntitlement* entitlement);
void (*on_entitlement_delete)(void* event_data, struct DiscordEntitlement* entitlement);
};
struct IDiscordStoreManager {
void (*fetch_skus)(struct IDiscordStoreManager* manager,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*count_skus)(struct IDiscordStoreManager* manager, int32_t* count);
enum EDiscordResult (*get_sku)(struct IDiscordStoreManager* manager,
DiscordSnowflake sku_id,
struct DiscordSku* sku);
enum EDiscordResult (*get_sku_at)(struct IDiscordStoreManager* manager,
int32_t index,
struct DiscordSku* sku);
void (*fetch_entitlements)(struct IDiscordStoreManager* manager,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*count_entitlements)(struct IDiscordStoreManager* manager, int32_t* count);
enum EDiscordResult (*get_entitlement)(struct IDiscordStoreManager* manager,
DiscordSnowflake entitlement_id,
struct DiscordEntitlement* entitlement);
enum EDiscordResult (*get_entitlement_at)(struct IDiscordStoreManager* manager,
int32_t index,
struct DiscordEntitlement* entitlement);
enum EDiscordResult (*has_sku_entitlement)(struct IDiscordStoreManager* manager,
DiscordSnowflake sku_id,
bool* has_entitlement);
void (*start_purchase)(struct IDiscordStoreManager* manager,
DiscordSnowflake sku_id,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
};
struct IDiscordVoiceEvents {
void (*on_settings_update)(void* event_data);
};
struct IDiscordVoiceManager {
enum EDiscordResult (*get_input_mode)(struct IDiscordVoiceManager* manager,
struct DiscordInputMode* input_mode);
void (*set_input_mode)(struct IDiscordVoiceManager* manager,
struct DiscordInputMode input_mode,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
enum EDiscordResult (*is_self_mute)(struct IDiscordVoiceManager* manager, bool* mute);
enum EDiscordResult (*set_self_mute)(struct IDiscordVoiceManager* manager, bool mute);
enum EDiscordResult (*is_self_deaf)(struct IDiscordVoiceManager* manager, bool* deaf);
enum EDiscordResult (*set_self_deaf)(struct IDiscordVoiceManager* manager, bool deaf);
enum EDiscordResult (*is_local_mute)(struct IDiscordVoiceManager* manager,
DiscordSnowflake user_id,
bool* mute);
enum EDiscordResult (*set_local_mute)(struct IDiscordVoiceManager* manager,
DiscordSnowflake user_id,
bool mute);
enum EDiscordResult (*get_local_volume)(struct IDiscordVoiceManager* manager,
DiscordSnowflake user_id,
uint8_t* volume);
enum EDiscordResult (*set_local_volume)(struct IDiscordVoiceManager* manager,
DiscordSnowflake user_id,
uint8_t volume);
};
struct IDiscordAchievementEvents {
void (*on_user_achievement_update)(void* event_data,
struct DiscordUserAchievement* user_achievement);
};
struct IDiscordAchievementManager {
void (*set_user_achievement)(struct IDiscordAchievementManager* manager,
DiscordSnowflake achievement_id,
uint8_t percent_complete,
void* callback_data,
void (*callback)(void* callback_data, enum EDiscordResult result));
void (*fetch_user_achievements)(struct IDiscordAchievementManager* manager,
void* callback_data,
void (*callback)(void* callback_data,
enum EDiscordResult result));
void (*count_user_achievements)(struct IDiscordAchievementManager* manager, int32_t* count);
enum EDiscordResult (*get_user_achievement)(struct IDiscordAchievementManager* manager,
DiscordSnowflake user_achievement_id,
struct DiscordUserAchievement* user_achievement);
enum EDiscordResult (*get_user_achievement_at)(struct IDiscordAchievementManager* manager,
int32_t index,
struct DiscordUserAchievement* user_achievement);
};
typedef void* IDiscordCoreEvents;
struct IDiscordCore {
void (*destroy)(struct IDiscordCore* core);
enum EDiscordResult (*run_callbacks)(struct IDiscordCore* core);
void (*set_log_hook)(struct IDiscordCore* core,
enum EDiscordLogLevel min_level,
void* hook_data,
void (*hook)(void* hook_data,
enum EDiscordLogLevel level,
const char* message));
struct IDiscordApplicationManager* (*get_application_manager)(struct IDiscordCore* core);
struct IDiscordUserManager* (*get_user_manager)(struct IDiscordCore* core);
struct IDiscordImageManager* (*get_image_manager)(struct IDiscordCore* core);
struct IDiscordActivityManager* (*get_activity_manager)(struct IDiscordCore* core);
struct IDiscordRelationshipManager* (*get_relationship_manager)(struct IDiscordCore* core);
struct IDiscordLobbyManager* (*get_lobby_manager)(struct IDiscordCore* core);
struct IDiscordNetworkManager* (*get_network_manager)(struct IDiscordCore* core);
struct IDiscordOverlayManager* (*get_overlay_manager)(struct IDiscordCore* core);
struct IDiscordStorageManager* (*get_storage_manager)(struct IDiscordCore* core);
struct IDiscordStoreManager* (*get_store_manager)(struct IDiscordCore* core);
struct IDiscordVoiceManager* (*get_voice_manager)(struct IDiscordCore* core);
struct IDiscordAchievementManager* (*get_achievement_manager)(struct IDiscordCore* core);
};
struct DiscordCreateParams {
DiscordClientId client_id;
uint64_t flags;
IDiscordCoreEvents* events;
void* event_data;
IDiscordApplicationEvents* application_events;
DiscordVersion application_version;
struct IDiscordUserEvents* user_events;
DiscordVersion user_version;
IDiscordImageEvents* image_events;
DiscordVersion image_version;
struct IDiscordActivityEvents* activity_events;
DiscordVersion activity_version;
struct IDiscordRelationshipEvents* relationship_events;
DiscordVersion relationship_version;
struct IDiscordLobbyEvents* lobby_events;
DiscordVersion lobby_version;
struct IDiscordNetworkEvents* network_events;
DiscordVersion network_version;
struct IDiscordOverlayEvents* overlay_events;
DiscordVersion overlay_version;
IDiscordStorageEvents* storage_events;
DiscordVersion storage_version;
struct IDiscordStoreEvents* store_events;
DiscordVersion store_version;
struct IDiscordVoiceEvents* voice_events;
DiscordVersion voice_version;
struct IDiscordAchievementEvents* achievement_events;
DiscordVersion achievement_version;
};
#ifdef __cplusplus
inline
#else
static
#endif
void
DiscordCreateParamsSetDefault(struct DiscordCreateParams* params)
{
memset(params, 0, sizeof(struct DiscordCreateParams));
params->application_version = DISCORD_APPLICATION_MANAGER_VERSION;
params->user_version = DISCORD_USER_MANAGER_VERSION;
params->image_version = DISCORD_IMAGE_MANAGER_VERSION;
params->activity_version = DISCORD_ACTIVITY_MANAGER_VERSION;
params->relationship_version = DISCORD_RELATIONSHIP_MANAGER_VERSION;
params->lobby_version = DISCORD_LOBBY_MANAGER_VERSION;
params->network_version = DISCORD_NETWORK_MANAGER_VERSION;
params->overlay_version = DISCORD_OVERLAY_MANAGER_VERSION;
params->storage_version = DISCORD_STORAGE_MANAGER_VERSION;
params->store_version = DISCORD_STORE_MANAGER_VERSION;
params->voice_version = DISCORD_VOICE_MANAGER_VERSION;
params->achievement_version = DISCORD_ACHIEVEMENT_MANAGER_VERSION;
}
enum EDiscordResult DiscordCreate(DiscordVersion version,
struct DiscordCreateParams* params,
struct IDiscordCore** result);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,57 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "image_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
void ImageManager::Fetch(ImageHandle handle,
bool refresh,
std::function<void(Result, ImageHandle)> callback)
{
static auto wrapper =
[](void* callbackData, EDiscordResult result, DiscordImageHandle handleResult) -> void {
std::unique_ptr<std::function<void(Result, ImageHandle)>> cb(
reinterpret_cast<std::function<void(Result, ImageHandle)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result), *reinterpret_cast<ImageHandle const*>(&handleResult));
};
std::unique_ptr<std::function<void(Result, ImageHandle)>> cb{};
cb.reset(new std::function<void(Result, ImageHandle)>(std::move(callback)));
internal_->fetch(internal_,
*reinterpret_cast<DiscordImageHandle const*>(&handle),
(refresh ? 1 : 0),
cb.release(),
wrapper);
}
Result ImageManager::GetDimensions(ImageHandle handle, ImageDimensions* dimensions)
{
if (!dimensions) {
return Result::InternalError;
}
auto result = internal_->get_dimensions(internal_,
*reinterpret_cast<DiscordImageHandle const*>(&handle),
reinterpret_cast<DiscordImageDimensions*>(dimensions));
return static_cast<Result>(result);
}
Result ImageManager::GetData(ImageHandle handle, std::uint8_t* data, std::uint32_t dataLength)
{
auto result = internal_->get_data(internal_,
*reinterpret_cast<DiscordImageHandle const*>(&handle),
reinterpret_cast<uint8_t*>(data),
dataLength);
return static_cast<Result>(result);
}
} // namespace discord

View File

@ -0,0 +1,28 @@
#pragma once
#include "types.h"
namespace discord {
class ImageManager final {
public:
~ImageManager() = default;
void Fetch(ImageHandle handle, bool refresh, std::function<void(Result, ImageHandle)> callback);
Result GetDimensions(ImageHandle handle, ImageDimensions* dimensions);
Result GetData(ImageHandle handle, std::uint8_t* data, std::uint32_t dataLength);
private:
friend class Core;
ImageManager() = default;
ImageManager(ImageManager const& rhs) = delete;
ImageManager& operator=(ImageManager const& rhs) = delete;
ImageManager(ImageManager&& rhs) = delete;
ImageManager& operator=(ImageManager&& rhs) = delete;
IDiscordImageManager* internal_;
static IDiscordImageEvents events_;
};
} // namespace discord

View File

@ -0,0 +1,547 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "lobby_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
class LobbyEvents final {
public:
static void OnLobbyUpdate(void* callbackData, int64_t lobbyId)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->LobbyManager();
module.OnLobbyUpdate(lobbyId);
}
static void OnLobbyDelete(void* callbackData, int64_t lobbyId, uint32_t reason)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->LobbyManager();
module.OnLobbyDelete(lobbyId, reason);
}
static void OnMemberConnect(void* callbackData, int64_t lobbyId, int64_t userId)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->LobbyManager();
module.OnMemberConnect(lobbyId, userId);
}
static void OnMemberUpdate(void* callbackData, int64_t lobbyId, int64_t userId)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->LobbyManager();
module.OnMemberUpdate(lobbyId, userId);
}
static void OnMemberDisconnect(void* callbackData, int64_t lobbyId, int64_t userId)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->LobbyManager();
module.OnMemberDisconnect(lobbyId, userId);
}
static void OnLobbyMessage(void* callbackData,
int64_t lobbyId,
int64_t userId,
uint8_t* data,
uint32_t dataLength)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->LobbyManager();
module.OnLobbyMessage(lobbyId, userId, data, dataLength);
}
static void OnSpeaking(void* callbackData, int64_t lobbyId, int64_t userId, bool speaking)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->LobbyManager();
module.OnSpeaking(lobbyId, userId, (speaking != 0));
}
static void OnNetworkMessage(void* callbackData,
int64_t lobbyId,
int64_t userId,
uint8_t channelId,
uint8_t* data,
uint32_t dataLength)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->LobbyManager();
module.OnNetworkMessage(lobbyId, userId, channelId, data, dataLength);
}
};
IDiscordLobbyEvents LobbyManager::events_{
&LobbyEvents::OnLobbyUpdate,
&LobbyEvents::OnLobbyDelete,
&LobbyEvents::OnMemberConnect,
&LobbyEvents::OnMemberUpdate,
&LobbyEvents::OnMemberDisconnect,
&LobbyEvents::OnLobbyMessage,
&LobbyEvents::OnSpeaking,
&LobbyEvents::OnNetworkMessage,
};
Result LobbyManager::GetLobbyCreateTransaction(LobbyTransaction* transaction)
{
if (!transaction) {
return Result::InternalError;
}
auto result = internal_->get_lobby_create_transaction(internal_, transaction->Receive());
return static_cast<Result>(result);
}
Result LobbyManager::GetLobbyUpdateTransaction(LobbyId lobbyId, LobbyTransaction* transaction)
{
if (!transaction) {
return Result::InternalError;
}
auto result =
internal_->get_lobby_update_transaction(internal_, lobbyId, transaction->Receive());
return static_cast<Result>(result);
}
Result LobbyManager::GetMemberUpdateTransaction(LobbyId lobbyId,
UserId userId,
LobbyMemberTransaction* transaction)
{
if (!transaction) {
return Result::InternalError;
}
auto result =
internal_->get_member_update_transaction(internal_, lobbyId, userId, transaction->Receive());
return static_cast<Result>(result);
}
void LobbyManager::CreateLobby(LobbyTransaction const& transaction,
std::function<void(Result, Lobby const&)> callback)
{
static auto wrapper =
[](void* callbackData, EDiscordResult result, DiscordLobby* lobby) -> void {
std::unique_ptr<std::function<void(Result, Lobby const&)>> cb(
reinterpret_cast<std::function<void(Result, Lobby const&)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result), *reinterpret_cast<Lobby const*>(lobby));
};
std::unique_ptr<std::function<void(Result, Lobby const&)>> cb{};
cb.reset(new std::function<void(Result, Lobby const&)>(std::move(callback)));
internal_->create_lobby(
internal_, const_cast<LobbyTransaction&>(transaction).Internal(), cb.release(), wrapper);
}
void LobbyManager::UpdateLobby(LobbyId lobbyId,
LobbyTransaction const& transaction,
std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->update_lobby(internal_,
lobbyId,
const_cast<LobbyTransaction&>(transaction).Internal(),
cb.release(),
wrapper);
}
void LobbyManager::DeleteLobby(LobbyId lobbyId, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->delete_lobby(internal_, lobbyId, cb.release(), wrapper);
}
void LobbyManager::ConnectLobby(LobbyId lobbyId,
LobbySecret secret,
std::function<void(Result, Lobby const&)> callback)
{
static auto wrapper =
[](void* callbackData, EDiscordResult result, DiscordLobby* lobby) -> void {
std::unique_ptr<std::function<void(Result, Lobby const&)>> cb(
reinterpret_cast<std::function<void(Result, Lobby const&)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result), *reinterpret_cast<Lobby const*>(lobby));
};
std::unique_ptr<std::function<void(Result, Lobby const&)>> cb{};
cb.reset(new std::function<void(Result, Lobby const&)>(std::move(callback)));
internal_->connect_lobby(internal_, lobbyId, const_cast<char*>(secret), cb.release(), wrapper);
}
void LobbyManager::ConnectLobbyWithActivitySecret(
LobbySecret activitySecret,
std::function<void(Result, Lobby const&)> callback)
{
static auto wrapper =
[](void* callbackData, EDiscordResult result, DiscordLobby* lobby) -> void {
std::unique_ptr<std::function<void(Result, Lobby const&)>> cb(
reinterpret_cast<std::function<void(Result, Lobby const&)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result), *reinterpret_cast<Lobby const*>(lobby));
};
std::unique_ptr<std::function<void(Result, Lobby const&)>> cb{};
cb.reset(new std::function<void(Result, Lobby const&)>(std::move(callback)));
internal_->connect_lobby_with_activity_secret(
internal_, const_cast<char*>(activitySecret), cb.release(), wrapper);
}
void LobbyManager::DisconnectLobby(LobbyId lobbyId, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->disconnect_lobby(internal_, lobbyId, cb.release(), wrapper);
}
Result LobbyManager::GetLobby(LobbyId lobbyId, Lobby* lobby)
{
if (!lobby) {
return Result::InternalError;
}
auto result = internal_->get_lobby(internal_, lobbyId, reinterpret_cast<DiscordLobby*>(lobby));
return static_cast<Result>(result);
}
Result LobbyManager::GetLobbyActivitySecret(LobbyId lobbyId, char secret[128])
{
if (!secret) {
return Result::InternalError;
}
auto result = internal_->get_lobby_activity_secret(
internal_, lobbyId, reinterpret_cast<DiscordLobbySecret*>(secret));
return static_cast<Result>(result);
}
Result LobbyManager::GetLobbyMetadataValue(LobbyId lobbyId, MetadataKey key, char value[4096])
{
if (!value) {
return Result::InternalError;
}
auto result = internal_->get_lobby_metadata_value(
internal_, lobbyId, const_cast<char*>(key), reinterpret_cast<DiscordMetadataValue*>(value));
return static_cast<Result>(result);
}
Result LobbyManager::GetLobbyMetadataKey(LobbyId lobbyId, std::int32_t index, char key[256])
{
if (!key) {
return Result::InternalError;
}
auto result = internal_->get_lobby_metadata_key(
internal_, lobbyId, index, reinterpret_cast<DiscordMetadataKey*>(key));
return static_cast<Result>(result);
}
Result LobbyManager::LobbyMetadataCount(LobbyId lobbyId, std::int32_t* count)
{
if (!count) {
return Result::InternalError;
}
auto result =
internal_->lobby_metadata_count(internal_, lobbyId, reinterpret_cast<int32_t*>(count));
return static_cast<Result>(result);
}
Result LobbyManager::MemberCount(LobbyId lobbyId, std::int32_t* count)
{
if (!count) {
return Result::InternalError;
}
auto result = internal_->member_count(internal_, lobbyId, reinterpret_cast<int32_t*>(count));
return static_cast<Result>(result);
}
Result LobbyManager::GetMemberUserId(LobbyId lobbyId, std::int32_t index, UserId* userId)
{
if (!userId) {
return Result::InternalError;
}
auto result =
internal_->get_member_user_id(internal_, lobbyId, index, reinterpret_cast<int64_t*>(userId));
return static_cast<Result>(result);
}
Result LobbyManager::GetMemberUser(LobbyId lobbyId, UserId userId, User* user)
{
if (!user) {
return Result::InternalError;
}
auto result =
internal_->get_member_user(internal_, lobbyId, userId, reinterpret_cast<DiscordUser*>(user));
return static_cast<Result>(result);
}
Result LobbyManager::GetMemberMetadataValue(LobbyId lobbyId,
UserId userId,
MetadataKey key,
char value[4096])
{
if (!value) {
return Result::InternalError;
}
auto result =
internal_->get_member_metadata_value(internal_,
lobbyId,
userId,
const_cast<char*>(key),
reinterpret_cast<DiscordMetadataValue*>(value));
return static_cast<Result>(result);
}
Result LobbyManager::GetMemberMetadataKey(LobbyId lobbyId,
UserId userId,
std::int32_t index,
char key[256])
{
if (!key) {
return Result::InternalError;
}
auto result = internal_->get_member_metadata_key(
internal_, lobbyId, userId, index, reinterpret_cast<DiscordMetadataKey*>(key));
return static_cast<Result>(result);
}
Result LobbyManager::MemberMetadataCount(LobbyId lobbyId, UserId userId, std::int32_t* count)
{
if (!count) {
return Result::InternalError;
}
auto result = internal_->member_metadata_count(
internal_, lobbyId, userId, reinterpret_cast<int32_t*>(count));
return static_cast<Result>(result);
}
void LobbyManager::UpdateMember(LobbyId lobbyId,
UserId userId,
LobbyMemberTransaction const& transaction,
std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->update_member(internal_,
lobbyId,
userId,
const_cast<LobbyMemberTransaction&>(transaction).Internal(),
cb.release(),
wrapper);
}
void LobbyManager::SendLobbyMessage(LobbyId lobbyId,
std::uint8_t* data,
std::uint32_t dataLength,
std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->send_lobby_message(
internal_, lobbyId, reinterpret_cast<uint8_t*>(data), dataLength, cb.release(), wrapper);
}
Result LobbyManager::GetSearchQuery(LobbySearchQuery* query)
{
if (!query) {
return Result::InternalError;
}
auto result = internal_->get_search_query(internal_, query->Receive());
return static_cast<Result>(result);
}
void LobbyManager::Search(LobbySearchQuery const& query, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->search(
internal_, const_cast<LobbySearchQuery&>(query).Internal(), cb.release(), wrapper);
}
void LobbyManager::LobbyCount(std::int32_t* count)
{
if (!count) {
return;
}
internal_->lobby_count(internal_, reinterpret_cast<int32_t*>(count));
}
Result LobbyManager::GetLobbyId(std::int32_t index, LobbyId* lobbyId)
{
if (!lobbyId) {
return Result::InternalError;
}
auto result = internal_->get_lobby_id(internal_, index, reinterpret_cast<int64_t*>(lobbyId));
return static_cast<Result>(result);
}
void LobbyManager::ConnectVoice(LobbyId lobbyId, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->connect_voice(internal_, lobbyId, cb.release(), wrapper);
}
void LobbyManager::DisconnectVoice(LobbyId lobbyId, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->disconnect_voice(internal_, lobbyId, cb.release(), wrapper);
}
Result LobbyManager::ConnectNetwork(LobbyId lobbyId)
{
auto result = internal_->connect_network(internal_, lobbyId);
return static_cast<Result>(result);
}
Result LobbyManager::DisconnectNetwork(LobbyId lobbyId)
{
auto result = internal_->disconnect_network(internal_, lobbyId);
return static_cast<Result>(result);
}
Result LobbyManager::FlushNetwork()
{
auto result = internal_->flush_network(internal_);
return static_cast<Result>(result);
}
Result LobbyManager::OpenNetworkChannel(LobbyId lobbyId, std::uint8_t channelId, bool reliable)
{
auto result =
internal_->open_network_channel(internal_, lobbyId, channelId, (reliable ? 1 : 0));
return static_cast<Result>(result);
}
Result LobbyManager::SendNetworkMessage(LobbyId lobbyId,
UserId userId,
std::uint8_t channelId,
std::uint8_t* data,
std::uint32_t dataLength)
{
auto result = internal_->send_network_message(
internal_, lobbyId, userId, channelId, reinterpret_cast<uint8_t*>(data), dataLength);
return static_cast<Result>(result);
}
} // namespace discord

View File

@ -0,0 +1,88 @@
#pragma once
#include "types.h"
namespace discord {
class LobbyManager final {
public:
~LobbyManager() = default;
Result GetLobbyCreateTransaction(LobbyTransaction* transaction);
Result GetLobbyUpdateTransaction(LobbyId lobbyId, LobbyTransaction* transaction);
Result GetMemberUpdateTransaction(LobbyId lobbyId,
UserId userId,
LobbyMemberTransaction* transaction);
void CreateLobby(LobbyTransaction const& transaction,
std::function<void(Result, Lobby const&)> callback);
void UpdateLobby(LobbyId lobbyId,
LobbyTransaction const& transaction,
std::function<void(Result)> callback);
void DeleteLobby(LobbyId lobbyId, std::function<void(Result)> callback);
void ConnectLobby(LobbyId lobbyId,
LobbySecret secret,
std::function<void(Result, Lobby const&)> callback);
void ConnectLobbyWithActivitySecret(LobbySecret activitySecret,
std::function<void(Result, Lobby const&)> callback);
void DisconnectLobby(LobbyId lobbyId, std::function<void(Result)> callback);
Result GetLobby(LobbyId lobbyId, Lobby* lobby);
Result GetLobbyActivitySecret(LobbyId lobbyId, char secret[128]);
Result GetLobbyMetadataValue(LobbyId lobbyId, MetadataKey key, char value[4096]);
Result GetLobbyMetadataKey(LobbyId lobbyId, std::int32_t index, char key[256]);
Result LobbyMetadataCount(LobbyId lobbyId, std::int32_t* count);
Result MemberCount(LobbyId lobbyId, std::int32_t* count);
Result GetMemberUserId(LobbyId lobbyId, std::int32_t index, UserId* userId);
Result GetMemberUser(LobbyId lobbyId, UserId userId, User* user);
Result GetMemberMetadataValue(LobbyId lobbyId,
UserId userId,
MetadataKey key,
char value[4096]);
Result GetMemberMetadataKey(LobbyId lobbyId, UserId userId, std::int32_t index, char key[256]);
Result MemberMetadataCount(LobbyId lobbyId, UserId userId, std::int32_t* count);
void UpdateMember(LobbyId lobbyId,
UserId userId,
LobbyMemberTransaction const& transaction,
std::function<void(Result)> callback);
void SendLobbyMessage(LobbyId lobbyId,
std::uint8_t* data,
std::uint32_t dataLength,
std::function<void(Result)> callback);
Result GetSearchQuery(LobbySearchQuery* query);
void Search(LobbySearchQuery const& query, std::function<void(Result)> callback);
void LobbyCount(std::int32_t* count);
Result GetLobbyId(std::int32_t index, LobbyId* lobbyId);
void ConnectVoice(LobbyId lobbyId, std::function<void(Result)> callback);
void DisconnectVoice(LobbyId lobbyId, std::function<void(Result)> callback);
Result ConnectNetwork(LobbyId lobbyId);
Result DisconnectNetwork(LobbyId lobbyId);
Result FlushNetwork();
Result OpenNetworkChannel(LobbyId lobbyId, std::uint8_t channelId, bool reliable);
Result SendNetworkMessage(LobbyId lobbyId,
UserId userId,
std::uint8_t channelId,
std::uint8_t* data,
std::uint32_t dataLength);
Event<std::int64_t> OnLobbyUpdate;
Event<std::int64_t, std::uint32_t> OnLobbyDelete;
Event<std::int64_t, std::int64_t> OnMemberConnect;
Event<std::int64_t, std::int64_t> OnMemberUpdate;
Event<std::int64_t, std::int64_t> OnMemberDisconnect;
Event<std::int64_t, std::int64_t, std::uint8_t*, std::uint32_t> OnLobbyMessage;
Event<std::int64_t, std::int64_t, bool> OnSpeaking;
Event<std::int64_t, std::int64_t, std::uint8_t, std::uint8_t*, std::uint32_t> OnNetworkMessage;
private:
friend class Core;
LobbyManager() = default;
LobbyManager(LobbyManager const& rhs) = delete;
LobbyManager& operator=(LobbyManager const& rhs) = delete;
LobbyManager(LobbyManager&& rhs) = delete;
LobbyManager& operator=(LobbyManager&& rhs) = delete;
IDiscordLobbyManager* internal_;
static IDiscordLobbyEvents events_;
};
} // namespace discord

View File

@ -0,0 +1,103 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "network_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
class NetworkEvents final {
public:
static void OnMessage(void* callbackData,
DiscordNetworkPeerId peerId,
DiscordNetworkChannelId channelId,
uint8_t* data,
uint32_t dataLength)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->NetworkManager();
module.OnMessage(peerId, channelId, data, dataLength);
}
static void OnRouteUpdate(void* callbackData, char const* routeData)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->NetworkManager();
module.OnRouteUpdate(static_cast<const char*>(routeData));
}
};
IDiscordNetworkEvents NetworkManager::events_{
&NetworkEvents::OnMessage,
&NetworkEvents::OnRouteUpdate,
};
void NetworkManager::GetPeerId(NetworkPeerId* peerId)
{
if (!peerId) {
return;
}
internal_->get_peer_id(internal_, reinterpret_cast<uint64_t*>(peerId));
}
Result NetworkManager::Flush()
{
auto result = internal_->flush(internal_);
return static_cast<Result>(result);
}
Result NetworkManager::OpenPeer(NetworkPeerId peerId, char const* routeData)
{
auto result = internal_->open_peer(internal_, peerId, const_cast<char*>(routeData));
return static_cast<Result>(result);
}
Result NetworkManager::UpdatePeer(NetworkPeerId peerId, char const* routeData)
{
auto result = internal_->update_peer(internal_, peerId, const_cast<char*>(routeData));
return static_cast<Result>(result);
}
Result NetworkManager::ClosePeer(NetworkPeerId peerId)
{
auto result = internal_->close_peer(internal_, peerId);
return static_cast<Result>(result);
}
Result NetworkManager::OpenChannel(NetworkPeerId peerId, NetworkChannelId channelId, bool reliable)
{
auto result = internal_->open_channel(internal_, peerId, channelId, (reliable ? 1 : 0));
return static_cast<Result>(result);
}
Result NetworkManager::CloseChannel(NetworkPeerId peerId, NetworkChannelId channelId)
{
auto result = internal_->close_channel(internal_, peerId, channelId);
return static_cast<Result>(result);
}
Result NetworkManager::SendMessage(NetworkPeerId peerId,
NetworkChannelId channelId,
std::uint8_t* data,
std::uint32_t dataLength)
{
auto result = internal_->send_message(
internal_, peerId, channelId, reinterpret_cast<uint8_t*>(data), dataLength);
return static_cast<Result>(result);
}
} // namespace discord

View File

@ -0,0 +1,63 @@
#pragma once
#include "types.h"
namespace discord {
class NetworkManager final {
public:
~NetworkManager() = default;
/**
* Get the local peer ID for this process.
*/
void GetPeerId(NetworkPeerId* peerId);
/**
* Send pending network messages.
*/
Result Flush();
/**
* Open a connection to a remote peer.
*/
Result OpenPeer(NetworkPeerId peerId, char const* routeData);
/**
* Update the route data for a connected peer.
*/
Result UpdatePeer(NetworkPeerId peerId, char const* routeData);
/**
* Close the connection to a remote peer.
*/
Result ClosePeer(NetworkPeerId peerId);
/**
* Open a message channel to a connected peer.
*/
Result OpenChannel(NetworkPeerId peerId, NetworkChannelId channelId, bool reliable);
/**
* Close a message channel to a connected peer.
*/
Result CloseChannel(NetworkPeerId peerId, NetworkChannelId channelId);
/**
* Send a message to a connected peer over an opened message channel.
*/
Result SendMessage(NetworkPeerId peerId,
NetworkChannelId channelId,
std::uint8_t* data,
std::uint32_t dataLength);
Event<NetworkPeerId, NetworkChannelId, std::uint8_t*, std::uint32_t> OnMessage;
Event<char const*> OnRouteUpdate;
private:
friend class Core;
NetworkManager() = default;
NetworkManager(NetworkManager const& rhs) = delete;
NetworkManager& operator=(NetworkManager const& rhs) = delete;
NetworkManager(NetworkManager&& rhs) = delete;
NetworkManager& operator=(NetworkManager&& rhs) = delete;
IDiscordNetworkManager* internal_;
static IDiscordNetworkEvents events_;
};
} // namespace discord

View File

@ -0,0 +1,112 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "overlay_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
class OverlayEvents final {
public:
static void OnToggle(void* callbackData, bool locked)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->OverlayManager();
module.OnToggle((locked != 0));
}
};
IDiscordOverlayEvents OverlayManager::events_{
&OverlayEvents::OnToggle,
};
void OverlayManager::IsEnabled(bool* enabled)
{
if (!enabled) {
return;
}
internal_->is_enabled(internal_, reinterpret_cast<bool*>(enabled));
}
void OverlayManager::IsLocked(bool* locked)
{
if (!locked) {
return;
}
internal_->is_locked(internal_, reinterpret_cast<bool*>(locked));
}
void OverlayManager::SetLocked(bool locked, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->set_locked(internal_, (locked ? 1 : 0), cb.release(), wrapper);
}
void OverlayManager::OpenActivityInvite(ActivityActionType type,
std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->open_activity_invite(
internal_, static_cast<EDiscordActivityActionType>(type), cb.release(), wrapper);
}
void OverlayManager::OpenGuildInvite(char const* code, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->open_guild_invite(internal_, const_cast<char*>(code), cb.release(), wrapper);
}
void OverlayManager::OpenVoiceSettings(std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->open_voice_settings(internal_, cb.release(), wrapper);
}
} // namespace discord

View File

@ -0,0 +1,33 @@
#pragma once
#include "types.h"
namespace discord {
class OverlayManager final {
public:
~OverlayManager() = default;
void IsEnabled(bool* enabled);
void IsLocked(bool* locked);
void SetLocked(bool locked, std::function<void(Result)> callback);
void OpenActivityInvite(ActivityActionType type, std::function<void(Result)> callback);
void OpenGuildInvite(char const* code, std::function<void(Result)> callback);
void OpenVoiceSettings(std::function<void(Result)> callback);
Event<bool> OnToggle;
private:
friend class Core;
OverlayManager() = default;
OverlayManager(OverlayManager const& rhs) = delete;
OverlayManager& operator=(OverlayManager const& rhs) = delete;
OverlayManager(OverlayManager&& rhs) = delete;
OverlayManager& operator=(OverlayManager&& rhs) = delete;
IDiscordOverlayManager* internal_;
static IDiscordOverlayEvents events_;
};
} // namespace discord

View File

@ -0,0 +1,90 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "relationship_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
class RelationshipEvents final {
public:
static void OnRefresh(void* callbackData)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->RelationshipManager();
module.OnRefresh();
}
static void OnRelationshipUpdate(void* callbackData, DiscordRelationship* relationship)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->RelationshipManager();
module.OnRelationshipUpdate(*reinterpret_cast<Relationship const*>(relationship));
}
};
IDiscordRelationshipEvents RelationshipManager::events_{
&RelationshipEvents::OnRefresh,
&RelationshipEvents::OnRelationshipUpdate,
};
void RelationshipManager::Filter(std::function<bool(Relationship const&)> filter)
{
static auto wrapper = [](void* callbackData, DiscordRelationship* relationship) -> bool {
auto cb(reinterpret_cast<std::function<bool(Relationship const&)>*>(callbackData));
if (!cb || !(*cb)) {
return {};
}
return (*cb)(*reinterpret_cast<Relationship const*>(relationship));
};
std::unique_ptr<std::function<bool(Relationship const&)>> cb{};
cb.reset(new std::function<bool(Relationship const&)>(std::move(filter)));
internal_->filter(internal_, cb.get(), wrapper);
}
Result RelationshipManager::Count(std::int32_t* count)
{
if (!count) {
return Result::InternalError;
}
auto result = internal_->count(internal_, reinterpret_cast<int32_t*>(count));
return static_cast<Result>(result);
}
Result RelationshipManager::Get(UserId userId, Relationship* relationship)
{
if (!relationship) {
return Result::InternalError;
}
auto result =
internal_->get(internal_, userId, reinterpret_cast<DiscordRelationship*>(relationship));
return static_cast<Result>(result);
}
Result RelationshipManager::GetAt(std::uint32_t index, Relationship* relationship)
{
if (!relationship) {
return Result::InternalError;
}
auto result =
internal_->get_at(internal_, index, reinterpret_cast<DiscordRelationship*>(relationship));
return static_cast<Result>(result);
}
} // namespace discord

View File

@ -0,0 +1,32 @@
#pragma once
#include "types.h"
namespace discord {
class RelationshipManager final {
public:
~RelationshipManager() = default;
void Filter(std::function<bool(Relationship const&)> filter);
Result Count(std::int32_t* count);
Result Get(UserId userId, Relationship* relationship);
Result GetAt(std::uint32_t index, Relationship* relationship);
Event<> OnRefresh;
Event<Relationship const&> OnRelationshipUpdate;
private:
friend class Core;
RelationshipManager() = default;
RelationshipManager(RelationshipManager const& rhs) = delete;
RelationshipManager& operator=(RelationshipManager const& rhs) = delete;
RelationshipManager(RelationshipManager&& rhs) = delete;
RelationshipManager& operator=(RelationshipManager&& rhs) = delete;
IDiscordRelationshipManager* internal_;
static IDiscordRelationshipEvents events_;
};
} // namespace discord

View File

@ -0,0 +1,158 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "storage_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
Result StorageManager::Read(char const* name,
std::uint8_t* data,
std::uint32_t dataLength,
std::uint32_t* read)
{
if (!read) {
return Result::InternalError;
}
auto result = internal_->read(internal_,
const_cast<char*>(name),
reinterpret_cast<uint8_t*>(data),
dataLength,
reinterpret_cast<uint32_t*>(read));
return static_cast<Result>(result);
}
void StorageManager::ReadAsync(char const* name,
std::function<void(Result, std::uint8_t*, std::uint32_t)> callback)
{
static auto wrapper =
[](void* callbackData, EDiscordResult result, uint8_t* data, uint32_t dataLength) -> void {
std::unique_ptr<std::function<void(Result, std::uint8_t*, std::uint32_t)>> cb(
reinterpret_cast<std::function<void(Result, std::uint8_t*, std::uint32_t)>*>(
callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result), data, dataLength);
};
std::unique_ptr<std::function<void(Result, std::uint8_t*, std::uint32_t)>> cb{};
cb.reset(new std::function<void(Result, std::uint8_t*, std::uint32_t)>(std::move(callback)));
internal_->read_async(internal_, const_cast<char*>(name), cb.release(), wrapper);
}
void StorageManager::ReadAsyncPartial(
char const* name,
std::uint64_t offset,
std::uint64_t length,
std::function<void(Result, std::uint8_t*, std::uint32_t)> callback)
{
static auto wrapper =
[](void* callbackData, EDiscordResult result, uint8_t* data, uint32_t dataLength) -> void {
std::unique_ptr<std::function<void(Result, std::uint8_t*, std::uint32_t)>> cb(
reinterpret_cast<std::function<void(Result, std::uint8_t*, std::uint32_t)>*>(
callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result), data, dataLength);
};
std::unique_ptr<std::function<void(Result, std::uint8_t*, std::uint32_t)>> cb{};
cb.reset(new std::function<void(Result, std::uint8_t*, std::uint32_t)>(std::move(callback)));
internal_->read_async_partial(
internal_, const_cast<char*>(name), offset, length, cb.release(), wrapper);
}
Result StorageManager::Write(char const* name, std::uint8_t* data, std::uint32_t dataLength)
{
auto result = internal_->write(
internal_, const_cast<char*>(name), reinterpret_cast<uint8_t*>(data), dataLength);
return static_cast<Result>(result);
}
void StorageManager::WriteAsync(char const* name,
std::uint8_t* data,
std::uint32_t dataLength,
std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->write_async(internal_,
const_cast<char*>(name),
reinterpret_cast<uint8_t*>(data),
dataLength,
cb.release(),
wrapper);
}
Result StorageManager::Delete(char const* name)
{
auto result = internal_->delete_(internal_, const_cast<char*>(name));
return static_cast<Result>(result);
}
Result StorageManager::Exists(char const* name, bool* exists)
{
if (!exists) {
return Result::InternalError;
}
auto result =
internal_->exists(internal_, const_cast<char*>(name), reinterpret_cast<bool*>(exists));
return static_cast<Result>(result);
}
void StorageManager::Count(std::int32_t* count)
{
if (!count) {
return;
}
internal_->count(internal_, reinterpret_cast<int32_t*>(count));
}
Result StorageManager::Stat(char const* name, FileStat* stat)
{
if (!stat) {
return Result::InternalError;
}
auto result =
internal_->stat(internal_, const_cast<char*>(name), reinterpret_cast<DiscordFileStat*>(stat));
return static_cast<Result>(result);
}
Result StorageManager::StatAt(std::int32_t index, FileStat* stat)
{
if (!stat) {
return Result::InternalError;
}
auto result = internal_->stat_at(internal_, index, reinterpret_cast<DiscordFileStat*>(stat));
return static_cast<Result>(result);
}
Result StorageManager::GetPath(char path[4096])
{
if (!path) {
return Result::InternalError;
}
auto result = internal_->get_path(internal_, reinterpret_cast<DiscordPath*>(path));
return static_cast<Result>(result);
}
} // namespace discord

View File

@ -0,0 +1,46 @@
#pragma once
#include "types.h"
namespace discord {
class StorageManager final {
public:
~StorageManager() = default;
Result Read(char const* name,
std::uint8_t* data,
std::uint32_t dataLength,
std::uint32_t* read);
void ReadAsync(char const* name,
std::function<void(Result, std::uint8_t*, std::uint32_t)> callback);
void ReadAsyncPartial(char const* name,
std::uint64_t offset,
std::uint64_t length,
std::function<void(Result, std::uint8_t*, std::uint32_t)> callback);
Result Write(char const* name, std::uint8_t* data, std::uint32_t dataLength);
void WriteAsync(char const* name,
std::uint8_t* data,
std::uint32_t dataLength,
std::function<void(Result)> callback);
Result Delete(char const* name);
Result Exists(char const* name, bool* exists);
void Count(std::int32_t* count);
Result Stat(char const* name, FileStat* stat);
Result StatAt(std::int32_t index, FileStat* stat);
Result GetPath(char path[4096]);
private:
friend class Core;
StorageManager() = default;
StorageManager(StorageManager const& rhs) = delete;
StorageManager& operator=(StorageManager const& rhs) = delete;
StorageManager(StorageManager&& rhs) = delete;
StorageManager& operator=(StorageManager&& rhs) = delete;
IDiscordStorageManager* internal_;
static IDiscordStorageEvents events_;
};
} // namespace discord

View File

@ -0,0 +1,160 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "store_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
class StoreEvents final {
public:
static void OnEntitlementCreate(void* callbackData, DiscordEntitlement* entitlement)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->StoreManager();
module.OnEntitlementCreate(*reinterpret_cast<Entitlement const*>(entitlement));
}
static void OnEntitlementDelete(void* callbackData, DiscordEntitlement* entitlement)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->StoreManager();
module.OnEntitlementDelete(*reinterpret_cast<Entitlement const*>(entitlement));
}
};
IDiscordStoreEvents StoreManager::events_{
&StoreEvents::OnEntitlementCreate,
&StoreEvents::OnEntitlementDelete,
};
void StoreManager::FetchSkus(std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->fetch_skus(internal_, cb.release(), wrapper);
}
void StoreManager::CountSkus(std::int32_t* count)
{
if (!count) {
return;
}
internal_->count_skus(internal_, reinterpret_cast<int32_t*>(count));
}
Result StoreManager::GetSku(Snowflake skuId, Sku* sku)
{
if (!sku) {
return Result::InternalError;
}
auto result = internal_->get_sku(internal_, skuId, reinterpret_cast<DiscordSku*>(sku));
return static_cast<Result>(result);
}
Result StoreManager::GetSkuAt(std::int32_t index, Sku* sku)
{
if (!sku) {
return Result::InternalError;
}
auto result = internal_->get_sku_at(internal_, index, reinterpret_cast<DiscordSku*>(sku));
return static_cast<Result>(result);
}
void StoreManager::FetchEntitlements(std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->fetch_entitlements(internal_, cb.release(), wrapper);
}
void StoreManager::CountEntitlements(std::int32_t* count)
{
if (!count) {
return;
}
internal_->count_entitlements(internal_, reinterpret_cast<int32_t*>(count));
}
Result StoreManager::GetEntitlement(Snowflake entitlementId, Entitlement* entitlement)
{
if (!entitlement) {
return Result::InternalError;
}
auto result = internal_->get_entitlement(
internal_, entitlementId, reinterpret_cast<DiscordEntitlement*>(entitlement));
return static_cast<Result>(result);
}
Result StoreManager::GetEntitlementAt(std::int32_t index, Entitlement* entitlement)
{
if (!entitlement) {
return Result::InternalError;
}
auto result = internal_->get_entitlement_at(
internal_, index, reinterpret_cast<DiscordEntitlement*>(entitlement));
return static_cast<Result>(result);
}
Result StoreManager::HasSkuEntitlement(Snowflake skuId, bool* hasEntitlement)
{
if (!hasEntitlement) {
return Result::InternalError;
}
auto result =
internal_->has_sku_entitlement(internal_, skuId, reinterpret_cast<bool*>(hasEntitlement));
return static_cast<Result>(result);
}
void StoreManager::StartPurchase(Snowflake skuId, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->start_purchase(internal_, skuId, cb.release(), wrapper);
}
} // namespace discord

View File

@ -0,0 +1,38 @@
#pragma once
#include "types.h"
namespace discord {
class StoreManager final {
public:
~StoreManager() = default;
void FetchSkus(std::function<void(Result)> callback);
void CountSkus(std::int32_t* count);
Result GetSku(Snowflake skuId, Sku* sku);
Result GetSkuAt(std::int32_t index, Sku* sku);
void FetchEntitlements(std::function<void(Result)> callback);
void CountEntitlements(std::int32_t* count);
Result GetEntitlement(Snowflake entitlementId, Entitlement* entitlement);
Result GetEntitlementAt(std::int32_t index, Entitlement* entitlement);
Result HasSkuEntitlement(Snowflake skuId, bool* hasEntitlement);
void StartPurchase(Snowflake skuId, std::function<void(Result)> callback);
Event<Entitlement const&> OnEntitlementCreate;
Event<Entitlement const&> OnEntitlementDelete;
private:
friend class Core;
StoreManager() = default;
StoreManager(StoreManager const& rhs) = delete;
StoreManager& operator=(StoreManager const& rhs) = delete;
StoreManager(StoreManager&& rhs) = delete;
StoreManager& operator=(StoreManager&& rhs) = delete;
IDiscordStoreManager* internal_;
static IDiscordStoreEvents events_;
};
} // namespace discord

769
depend/discord/types.cpp Normal file
View File

@ -0,0 +1,769 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "types.h"
#include <cstring>
#include <memory>
namespace discord {
void User::SetId(UserId id)
{
internal_.id = id;
}
UserId User::GetId() const
{
return internal_.id;
}
void User::SetUsername(char const* username)
{
strncpy(internal_.username, username, 256);
internal_.username[256 - 1] = '\0';
}
char const* User::GetUsername() const
{
return internal_.username;
}
void User::SetDiscriminator(char const* discriminator)
{
strncpy(internal_.discriminator, discriminator, 8);
internal_.discriminator[8 - 1] = '\0';
}
char const* User::GetDiscriminator() const
{
return internal_.discriminator;
}
void User::SetAvatar(char const* avatar)
{
strncpy(internal_.avatar, avatar, 128);
internal_.avatar[128 - 1] = '\0';
}
char const* User::GetAvatar() const
{
return internal_.avatar;
}
void User::SetBot(bool bot)
{
internal_.bot = bot;
}
bool User::GetBot() const
{
return internal_.bot != 0;
}
void OAuth2Token::SetAccessToken(char const* accessToken)
{
strncpy(internal_.access_token, accessToken, 128);
internal_.access_token[128 - 1] = '\0';
}
char const* OAuth2Token::GetAccessToken() const
{
return internal_.access_token;
}
void OAuth2Token::SetScopes(char const* scopes)
{
strncpy(internal_.scopes, scopes, 1024);
internal_.scopes[1024 - 1] = '\0';
}
char const* OAuth2Token::GetScopes() const
{
return internal_.scopes;
}
void OAuth2Token::SetExpires(Timestamp expires)
{
internal_.expires = expires;
}
Timestamp OAuth2Token::GetExpires() const
{
return internal_.expires;
}
void ImageHandle::SetType(ImageType type)
{
internal_.type = static_cast<EDiscordImageType>(type);
}
ImageType ImageHandle::GetType() const
{
return static_cast<ImageType>(internal_.type);
}
void ImageHandle::SetId(std::int64_t id)
{
internal_.id = id;
}
std::int64_t ImageHandle::GetId() const
{
return internal_.id;
}
void ImageHandle::SetSize(std::uint32_t size)
{
internal_.size = size;
}
std::uint32_t ImageHandle::GetSize() const
{
return internal_.size;
}
void ImageDimensions::SetWidth(std::uint32_t width)
{
internal_.width = width;
}
std::uint32_t ImageDimensions::GetWidth() const
{
return internal_.width;
}
void ImageDimensions::SetHeight(std::uint32_t height)
{
internal_.height = height;
}
std::uint32_t ImageDimensions::GetHeight() const
{
return internal_.height;
}
void ActivityTimestamps::SetStart(Timestamp start)
{
internal_.start = start;
}
Timestamp ActivityTimestamps::GetStart() const
{
return internal_.start;
}
void ActivityTimestamps::SetEnd(Timestamp end)
{
internal_.end = end;
}
Timestamp ActivityTimestamps::GetEnd() const
{
return internal_.end;
}
void ActivityAssets::SetLargeImage(char const* largeImage)
{
strncpy(internal_.large_image, largeImage, 128);
internal_.large_image[128 - 1] = '\0';
}
char const* ActivityAssets::GetLargeImage() const
{
return internal_.large_image;
}
void ActivityAssets::SetLargeText(char const* largeText)
{
strncpy(internal_.large_text, largeText, 128);
internal_.large_text[128 - 1] = '\0';
}
char const* ActivityAssets::GetLargeText() const
{
return internal_.large_text;
}
void ActivityAssets::SetSmallImage(char const* smallImage)
{
strncpy(internal_.small_image, smallImage, 128);
internal_.small_image[128 - 1] = '\0';
}
char const* ActivityAssets::GetSmallImage() const
{
return internal_.small_image;
}
void ActivityAssets::SetSmallText(char const* smallText)
{
strncpy(internal_.small_text, smallText, 128);
internal_.small_text[128 - 1] = '\0';
}
char const* ActivityAssets::GetSmallText() const
{
return internal_.small_text;
}
void PartySize::SetCurrentSize(std::int32_t currentSize)
{
internal_.current_size = currentSize;
}
std::int32_t PartySize::GetCurrentSize() const
{
return internal_.current_size;
}
void PartySize::SetMaxSize(std::int32_t maxSize)
{
internal_.max_size = maxSize;
}
std::int32_t PartySize::GetMaxSize() const
{
return internal_.max_size;
}
void ActivityParty::SetId(char const* id)
{
strncpy(internal_.id, id, 128);
internal_.id[128 - 1] = '\0';
}
char const* ActivityParty::GetId() const
{
return internal_.id;
}
PartySize& ActivityParty::GetSize()
{
return reinterpret_cast<PartySize&>(internal_.size);
}
PartySize const& ActivityParty::GetSize() const
{
return reinterpret_cast<PartySize const&>(internal_.size);
}
void ActivitySecrets::SetMatch(char const* match)
{
strncpy(internal_.match, match, 128);
internal_.match[128 - 1] = '\0';
}
char const* ActivitySecrets::GetMatch() const
{
return internal_.match;
}
void ActivitySecrets::SetJoin(char const* join)
{
strncpy(internal_.join, join, 128);
internal_.join[128 - 1] = '\0';
}
char const* ActivitySecrets::GetJoin() const
{
return internal_.join;
}
void ActivitySecrets::SetSpectate(char const* spectate)
{
strncpy(internal_.spectate, spectate, 128);
internal_.spectate[128 - 1] = '\0';
}
char const* ActivitySecrets::GetSpectate() const
{
return internal_.spectate;
}
void Activity::SetType(ActivityType type)
{
internal_.type = static_cast<EDiscordActivityType>(type);
}
ActivityType Activity::GetType() const
{
return static_cast<ActivityType>(internal_.type);
}
void Activity::SetApplicationId(std::int64_t applicationId)
{
internal_.application_id = applicationId;
}
std::int64_t Activity::GetApplicationId() const
{
return internal_.application_id;
}
void Activity::SetName(char const* name)
{
strncpy(internal_.name, name, 128);
internal_.name[128 - 1] = '\0';
}
char const* Activity::GetName() const
{
return internal_.name;
}
void Activity::SetState(char const* state)
{
strncpy(internal_.state, state, 128);
internal_.state[128 - 1] = '\0';
}
char const* Activity::GetState() const
{
return internal_.state;
}
void Activity::SetDetails(char const* details)
{
strncpy(internal_.details, details, 128);
internal_.details[128 - 1] = '\0';
}
char const* Activity::GetDetails() const
{
return internal_.details;
}
ActivityTimestamps& Activity::GetTimestamps()
{
return reinterpret_cast<ActivityTimestamps&>(internal_.timestamps);
}
ActivityTimestamps const& Activity::GetTimestamps() const
{
return reinterpret_cast<ActivityTimestamps const&>(internal_.timestamps);
}
ActivityAssets& Activity::GetAssets()
{
return reinterpret_cast<ActivityAssets&>(internal_.assets);
}
ActivityAssets const& Activity::GetAssets() const
{
return reinterpret_cast<ActivityAssets const&>(internal_.assets);
}
ActivityParty& Activity::GetParty()
{
return reinterpret_cast<ActivityParty&>(internal_.party);
}
ActivityParty const& Activity::GetParty() const
{
return reinterpret_cast<ActivityParty const&>(internal_.party);
}
ActivitySecrets& Activity::GetSecrets()
{
return reinterpret_cast<ActivitySecrets&>(internal_.secrets);
}
ActivitySecrets const& Activity::GetSecrets() const
{
return reinterpret_cast<ActivitySecrets const&>(internal_.secrets);
}
void Activity::SetInstance(bool instance)
{
internal_.instance = instance;
}
bool Activity::GetInstance() const
{
return internal_.instance != 0;
}
void Presence::SetStatus(Status status)
{
internal_.status = static_cast<EDiscordStatus>(status);
}
Status Presence::GetStatus() const
{
return static_cast<Status>(internal_.status);
}
Activity& Presence::GetActivity()
{
return reinterpret_cast<Activity&>(internal_.activity);
}
Activity const& Presence::GetActivity() const
{
return reinterpret_cast<Activity const&>(internal_.activity);
}
void Relationship::SetType(RelationshipType type)
{
internal_.type = static_cast<EDiscordRelationshipType>(type);
}
RelationshipType Relationship::GetType() const
{
return static_cast<RelationshipType>(internal_.type);
}
User& Relationship::GetUser()
{
return reinterpret_cast<User&>(internal_.user);
}
User const& Relationship::GetUser() const
{
return reinterpret_cast<User const&>(internal_.user);
}
Presence& Relationship::GetPresence()
{
return reinterpret_cast<Presence&>(internal_.presence);
}
Presence const& Relationship::GetPresence() const
{
return reinterpret_cast<Presence const&>(internal_.presence);
}
void Lobby::SetId(LobbyId id)
{
internal_.id = id;
}
LobbyId Lobby::GetId() const
{
return internal_.id;
}
void Lobby::SetType(LobbyType type)
{
internal_.type = static_cast<EDiscordLobbyType>(type);
}
LobbyType Lobby::GetType() const
{
return static_cast<LobbyType>(internal_.type);
}
void Lobby::SetOwnerId(UserId ownerId)
{
internal_.owner_id = ownerId;
}
UserId Lobby::GetOwnerId() const
{
return internal_.owner_id;
}
void Lobby::SetSecret(LobbySecret secret)
{
strncpy(internal_.secret, secret, 128);
internal_.secret[128 - 1] = '\0';
}
LobbySecret Lobby::GetSecret() const
{
return internal_.secret;
}
void Lobby::SetCapacity(std::uint32_t capacity)
{
internal_.capacity = capacity;
}
std::uint32_t Lobby::GetCapacity() const
{
return internal_.capacity;
}
void Lobby::SetLocked(bool locked)
{
internal_.locked = locked;
}
bool Lobby::GetLocked() const
{
return internal_.locked != 0;
}
void FileStat::SetFilename(char const* filename)
{
strncpy(internal_.filename, filename, 260);
internal_.filename[260 - 1] = '\0';
}
char const* FileStat::GetFilename() const
{
return internal_.filename;
}
void FileStat::SetSize(std::uint64_t size)
{
internal_.size = size;
}
std::uint64_t FileStat::GetSize() const
{
return internal_.size;
}
void FileStat::SetLastModified(std::uint64_t lastModified)
{
internal_.last_modified = lastModified;
}
std::uint64_t FileStat::GetLastModified() const
{
return internal_.last_modified;
}
void Entitlement::SetId(Snowflake id)
{
internal_.id = id;
}
Snowflake Entitlement::GetId() const
{
return internal_.id;
}
void Entitlement::SetType(EntitlementType type)
{
internal_.type = static_cast<EDiscordEntitlementType>(type);
}
EntitlementType Entitlement::GetType() const
{
return static_cast<EntitlementType>(internal_.type);
}
void Entitlement::SetSkuId(Snowflake skuId)
{
internal_.sku_id = skuId;
}
Snowflake Entitlement::GetSkuId() const
{
return internal_.sku_id;
}
void SkuPrice::SetAmount(std::uint32_t amount)
{
internal_.amount = amount;
}
std::uint32_t SkuPrice::GetAmount() const
{
return internal_.amount;
}
void SkuPrice::SetCurrency(char const* currency)
{
strncpy(internal_.currency, currency, 16);
internal_.currency[16 - 1] = '\0';
}
char const* SkuPrice::GetCurrency() const
{
return internal_.currency;
}
void Sku::SetId(Snowflake id)
{
internal_.id = id;
}
Snowflake Sku::GetId() const
{
return internal_.id;
}
void Sku::SetType(SkuType type)
{
internal_.type = static_cast<EDiscordSkuType>(type);
}
SkuType Sku::GetType() const
{
return static_cast<SkuType>(internal_.type);
}
void Sku::SetName(char const* name)
{
strncpy(internal_.name, name, 256);
internal_.name[256 - 1] = '\0';
}
char const* Sku::GetName() const
{
return internal_.name;
}
SkuPrice& Sku::GetPrice()
{
return reinterpret_cast<SkuPrice&>(internal_.price);
}
SkuPrice const& Sku::GetPrice() const
{
return reinterpret_cast<SkuPrice const&>(internal_.price);
}
void InputMode::SetType(InputModeType type)
{
internal_.type = static_cast<EDiscordInputModeType>(type);
}
InputModeType InputMode::GetType() const
{
return static_cast<InputModeType>(internal_.type);
}
void InputMode::SetShortcut(char const* shortcut)
{
strncpy(internal_.shortcut, shortcut, 256);
internal_.shortcut[256 - 1] = '\0';
}
char const* InputMode::GetShortcut() const
{
return internal_.shortcut;
}
void UserAchievement::SetUserId(Snowflake userId)
{
internal_.user_id = userId;
}
Snowflake UserAchievement::GetUserId() const
{
return internal_.user_id;
}
void UserAchievement::SetAchievementId(Snowflake achievementId)
{
internal_.achievement_id = achievementId;
}
Snowflake UserAchievement::GetAchievementId() const
{
return internal_.achievement_id;
}
void UserAchievement::SetPercentComplete(std::uint8_t percentComplete)
{
internal_.percent_complete = percentComplete;
}
std::uint8_t UserAchievement::GetPercentComplete() const
{
return internal_.percent_complete;
}
void UserAchievement::SetUnlockedAt(DateTime unlockedAt)
{
strncpy(internal_.unlocked_at, unlockedAt, 64);
internal_.unlocked_at[64 - 1] = '\0';
}
DateTime UserAchievement::GetUnlockedAt() const
{
return internal_.unlocked_at;
}
Result LobbyTransaction::SetType(LobbyType type)
{
auto result = internal_->set_type(internal_, static_cast<EDiscordLobbyType>(type));
return static_cast<Result>(result);
}
Result LobbyTransaction::SetOwner(UserId ownerId)
{
auto result = internal_->set_owner(internal_, ownerId);
return static_cast<Result>(result);
}
Result LobbyTransaction::SetCapacity(std::uint32_t capacity)
{
auto result = internal_->set_capacity(internal_, capacity);
return static_cast<Result>(result);
}
Result LobbyTransaction::SetMetadata(MetadataKey key, MetadataValue value)
{
auto result =
internal_->set_metadata(internal_, const_cast<char*>(key), const_cast<char*>(value));
return static_cast<Result>(result);
}
Result LobbyTransaction::DeleteMetadata(MetadataKey key)
{
auto result = internal_->delete_metadata(internal_, const_cast<char*>(key));
return static_cast<Result>(result);
}
Result LobbyTransaction::SetLocked(bool locked)
{
auto result = internal_->set_locked(internal_, (locked ? 1 : 0));
return static_cast<Result>(result);
}
Result LobbyMemberTransaction::SetMetadata(MetadataKey key, MetadataValue value)
{
auto result =
internal_->set_metadata(internal_, const_cast<char*>(key), const_cast<char*>(value));
return static_cast<Result>(result);
}
Result LobbyMemberTransaction::DeleteMetadata(MetadataKey key)
{
auto result = internal_->delete_metadata(internal_, const_cast<char*>(key));
return static_cast<Result>(result);
}
Result LobbySearchQuery::Filter(MetadataKey key,
LobbySearchComparison comparison,
LobbySearchCast cast,
MetadataValue value)
{
auto result = internal_->filter(internal_,
const_cast<char*>(key),
static_cast<EDiscordLobbySearchComparison>(comparison),
static_cast<EDiscordLobbySearchCast>(cast),
const_cast<char*>(value));
return static_cast<Result>(result);
}
Result LobbySearchQuery::Sort(MetadataKey key, LobbySearchCast cast, MetadataValue value)
{
auto result = internal_->sort(internal_,
const_cast<char*>(key),
static_cast<EDiscordLobbySearchCast>(cast),
const_cast<char*>(value));
return static_cast<Result>(result);
}
Result LobbySearchQuery::Limit(std::uint32_t limit)
{
auto result = internal_->limit(internal_, limit);
return static_cast<Result>(result);
}
Result LobbySearchQuery::Distance(LobbySearchDistance distance)
{
auto result =
internal_->distance(internal_, static_cast<EDiscordLobbySearchDistance>(distance));
return static_cast<Result>(result);
}
} // namespace discord

491
depend/discord/types.h Normal file
View File

@ -0,0 +1,491 @@
#pragma once
#include "ffi.h"
#include "event.h"
namespace discord {
enum class Result {
Ok = 0,
ServiceUnavailable = 1,
InvalidVersion = 2,
LockFailed = 3,
InternalError = 4,
InvalidPayload = 5,
InvalidCommand = 6,
InvalidPermissions = 7,
NotFetched = 8,
NotFound = 9,
Conflict = 10,
InvalidSecret = 11,
InvalidJoinSecret = 12,
NoEligibleActivity = 13,
InvalidInvite = 14,
NotAuthenticated = 15,
InvalidAccessToken = 16,
ApplicationMismatch = 17,
InvalidDataUrl = 18,
InvalidBase64 = 19,
NotFiltered = 20,
LobbyFull = 21,
InvalidLobbySecret = 22,
InvalidFilename = 23,
InvalidFileSize = 24,
InvalidEntitlement = 25,
NotInstalled = 26,
NotRunning = 27,
InsufficientBuffer = 28,
PurchaseCanceled = 29,
InvalidGuild = 30,
InvalidEvent = 31,
InvalidChannel = 32,
InvalidOrigin = 33,
RateLimited = 34,
OAuth2Error = 35,
SelectChannelTimeout = 36,
GetGuildTimeout = 37,
SelectVoiceForceRequired = 38,
CaptureShortcutAlreadyListening = 39,
UnauthorizedForAchievement = 40,
InvalidGiftCode = 41,
PurchaseError = 42,
TransactionAborted = 43,
};
enum class CreateFlags {
Default = 0,
NoRequireDiscord = 1,
};
enum class LogLevel {
Error = 1,
Warn,
Info,
Debug,
};
enum class UserFlag {
Partner = 2,
HypeSquadEvents = 4,
HypeSquadHouse1 = 64,
HypeSquadHouse2 = 128,
HypeSquadHouse3 = 256,
};
enum class PremiumType {
None = 0,
Tier1 = 1,
Tier2 = 2,
};
enum class ImageType {
User,
};
enum class ActivityType {
Playing,
Streaming,
Listening,
Watching,
};
enum class ActivityActionType {
Join = 1,
Spectate,
};
enum class ActivityJoinRequestReply {
No,
Yes,
Ignore,
};
enum class Status {
Offline = 0,
Online = 1,
Idle = 2,
DoNotDisturb = 3,
};
enum class RelationshipType {
None,
Friend,
Blocked,
PendingIncoming,
PendingOutgoing,
Implicit,
};
enum class LobbyType {
Private = 1,
Public,
};
enum class LobbySearchComparison {
LessThanOrEqual = -2,
LessThan,
Equal,
GreaterThan,
GreaterThanOrEqual,
NotEqual,
};
enum class LobbySearchCast {
String = 1,
Number,
};
enum class LobbySearchDistance {
Local,
Default,
Extended,
Global,
};
enum class EntitlementType {
Purchase = 1,
PremiumSubscription,
DeveloperGift,
TestModePurchase,
FreePurchase,
UserGift,
PremiumPurchase,
};
enum class SkuType {
Application = 1,
DLC,
Consumable,
Bundle,
};
enum class InputModeType {
VoiceActivity = 0,
PushToTalk,
};
using ClientId = std::int64_t;
using Version = std::int32_t;
using Snowflake = std::int64_t;
using Timestamp = std::int64_t;
using UserId = Snowflake;
using Locale = char const*;
using Branch = char const*;
using LobbyId = Snowflake;
using LobbySecret = char const*;
using MetadataKey = char const*;
using MetadataValue = char const*;
using NetworkPeerId = std::uint64_t;
using NetworkChannelId = std::uint8_t;
using Path = char const*;
using DateTime = char const*;
class User final {
public:
void SetId(UserId id);
UserId GetId() const;
void SetUsername(char const* username);
char const* GetUsername() const;
void SetDiscriminator(char const* discriminator);
char const* GetDiscriminator() const;
void SetAvatar(char const* avatar);
char const* GetAvatar() const;
void SetBot(bool bot);
bool GetBot() const;
private:
DiscordUser internal_;
};
class OAuth2Token final {
public:
void SetAccessToken(char const* accessToken);
char const* GetAccessToken() const;
void SetScopes(char const* scopes);
char const* GetScopes() const;
void SetExpires(Timestamp expires);
Timestamp GetExpires() const;
private:
DiscordOAuth2Token internal_;
};
class ImageHandle final {
public:
void SetType(ImageType type);
ImageType GetType() const;
void SetId(std::int64_t id);
std::int64_t GetId() const;
void SetSize(std::uint32_t size);
std::uint32_t GetSize() const;
private:
DiscordImageHandle internal_;
};
class ImageDimensions final {
public:
void SetWidth(std::uint32_t width);
std::uint32_t GetWidth() const;
void SetHeight(std::uint32_t height);
std::uint32_t GetHeight() const;
private:
DiscordImageDimensions internal_;
};
class ActivityTimestamps final {
public:
void SetStart(Timestamp start);
Timestamp GetStart() const;
void SetEnd(Timestamp end);
Timestamp GetEnd() const;
private:
DiscordActivityTimestamps internal_;
};
class ActivityAssets final {
public:
void SetLargeImage(char const* largeImage);
char const* GetLargeImage() const;
void SetLargeText(char const* largeText);
char const* GetLargeText() const;
void SetSmallImage(char const* smallImage);
char const* GetSmallImage() const;
void SetSmallText(char const* smallText);
char const* GetSmallText() const;
private:
DiscordActivityAssets internal_;
};
class PartySize final {
public:
void SetCurrentSize(std::int32_t currentSize);
std::int32_t GetCurrentSize() const;
void SetMaxSize(std::int32_t maxSize);
std::int32_t GetMaxSize() const;
private:
DiscordPartySize internal_;
};
class ActivityParty final {
public:
void SetId(char const* id);
char const* GetId() const;
PartySize& GetSize();
PartySize const& GetSize() const;
private:
DiscordActivityParty internal_;
};
class ActivitySecrets final {
public:
void SetMatch(char const* match);
char const* GetMatch() const;
void SetJoin(char const* join);
char const* GetJoin() const;
void SetSpectate(char const* spectate);
char const* GetSpectate() const;
private:
DiscordActivitySecrets internal_;
};
class Activity final {
public:
void SetType(ActivityType type);
ActivityType GetType() const;
void SetApplicationId(std::int64_t applicationId);
std::int64_t GetApplicationId() const;
void SetName(char const* name);
char const* GetName() const;
void SetState(char const* state);
char const* GetState() const;
void SetDetails(char const* details);
char const* GetDetails() const;
ActivityTimestamps& GetTimestamps();
ActivityTimestamps const& GetTimestamps() const;
ActivityAssets& GetAssets();
ActivityAssets const& GetAssets() const;
ActivityParty& GetParty();
ActivityParty const& GetParty() const;
ActivitySecrets& GetSecrets();
ActivitySecrets const& GetSecrets() const;
void SetInstance(bool instance);
bool GetInstance() const;
private:
DiscordActivity internal_;
};
class Presence final {
public:
void SetStatus(Status status);
Status GetStatus() const;
Activity& GetActivity();
Activity const& GetActivity() const;
private:
DiscordPresence internal_;
};
class Relationship final {
public:
void SetType(RelationshipType type);
RelationshipType GetType() const;
User& GetUser();
User const& GetUser() const;
Presence& GetPresence();
Presence const& GetPresence() const;
private:
DiscordRelationship internal_;
};
class Lobby final {
public:
void SetId(LobbyId id);
LobbyId GetId() const;
void SetType(LobbyType type);
LobbyType GetType() const;
void SetOwnerId(UserId ownerId);
UserId GetOwnerId() const;
void SetSecret(LobbySecret secret);
LobbySecret GetSecret() const;
void SetCapacity(std::uint32_t capacity);
std::uint32_t GetCapacity() const;
void SetLocked(bool locked);
bool GetLocked() const;
private:
DiscordLobby internal_;
};
class FileStat final {
public:
void SetFilename(char const* filename);
char const* GetFilename() const;
void SetSize(std::uint64_t size);
std::uint64_t GetSize() const;
void SetLastModified(std::uint64_t lastModified);
std::uint64_t GetLastModified() const;
private:
DiscordFileStat internal_;
};
class Entitlement final {
public:
void SetId(Snowflake id);
Snowflake GetId() const;
void SetType(EntitlementType type);
EntitlementType GetType() const;
void SetSkuId(Snowflake skuId);
Snowflake GetSkuId() const;
private:
DiscordEntitlement internal_;
};
class SkuPrice final {
public:
void SetAmount(std::uint32_t amount);
std::uint32_t GetAmount() const;
void SetCurrency(char const* currency);
char const* GetCurrency() const;
private:
DiscordSkuPrice internal_;
};
class Sku final {
public:
void SetId(Snowflake id);
Snowflake GetId() const;
void SetType(SkuType type);
SkuType GetType() const;
void SetName(char const* name);
char const* GetName() const;
SkuPrice& GetPrice();
SkuPrice const& GetPrice() const;
private:
DiscordSku internal_;
};
class InputMode final {
public:
void SetType(InputModeType type);
InputModeType GetType() const;
void SetShortcut(char const* shortcut);
char const* GetShortcut() const;
private:
DiscordInputMode internal_;
};
class UserAchievement final {
public:
void SetUserId(Snowflake userId);
Snowflake GetUserId() const;
void SetAchievementId(Snowflake achievementId);
Snowflake GetAchievementId() const;
void SetPercentComplete(std::uint8_t percentComplete);
std::uint8_t GetPercentComplete() const;
void SetUnlockedAt(DateTime unlockedAt);
DateTime GetUnlockedAt() const;
private:
DiscordUserAchievement internal_;
};
class LobbyTransaction final {
public:
Result SetType(LobbyType type);
Result SetOwner(UserId ownerId);
Result SetCapacity(std::uint32_t capacity);
Result SetMetadata(MetadataKey key, MetadataValue value);
Result DeleteMetadata(MetadataKey key);
Result SetLocked(bool locked);
IDiscordLobbyTransaction** Receive() { return &internal_; }
IDiscordLobbyTransaction* Internal() { return internal_; }
private:
IDiscordLobbyTransaction* internal_;
};
class LobbyMemberTransaction final {
public:
Result SetMetadata(MetadataKey key, MetadataValue value);
Result DeleteMetadata(MetadataKey key);
IDiscordLobbyMemberTransaction** Receive() { return &internal_; }
IDiscordLobbyMemberTransaction* Internal() { return internal_; }
private:
IDiscordLobbyMemberTransaction* internal_;
};
class LobbySearchQuery final {
public:
Result Filter(MetadataKey key,
LobbySearchComparison comparison,
LobbySearchCast cast,
MetadataValue value);
Result Sort(MetadataKey key, LobbySearchCast cast, MetadataValue value);
Result Limit(std::uint32_t limit);
Result Distance(LobbySearchDistance distance);
IDiscordLobbySearchQuery** Receive() { return &internal_; }
IDiscordLobbySearchQuery* Internal() { return internal_; }
private:
IDiscordLobbySearchQuery* internal_;
};
} // namespace discord

View File

@ -0,0 +1,80 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "user_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
class UserEvents final {
public:
static void OnCurrentUserUpdate(void* callbackData)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->UserManager();
module.OnCurrentUserUpdate();
}
};
IDiscordUserEvents UserManager::events_{
&UserEvents::OnCurrentUserUpdate,
};
Result UserManager::GetCurrentUser(User* currentUser)
{
if (!currentUser) {
return Result::InternalError;
}
auto result =
internal_->get_current_user(internal_, reinterpret_cast<DiscordUser*>(currentUser));
return static_cast<Result>(result);
}
void UserManager::GetUser(UserId userId, std::function<void(Result, User const&)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result, DiscordUser* user) -> void {
std::unique_ptr<std::function<void(Result, User const&)>> cb(
reinterpret_cast<std::function<void(Result, User const&)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result), *reinterpret_cast<User const*>(user));
};
std::unique_ptr<std::function<void(Result, User const&)>> cb{};
cb.reset(new std::function<void(Result, User const&)>(std::move(callback)));
internal_->get_user(internal_, userId, cb.release(), wrapper);
}
Result UserManager::GetCurrentUserPremiumType(PremiumType* premiumType)
{
if (!premiumType) {
return Result::InternalError;
}
auto result = internal_->get_current_user_premium_type(
internal_, reinterpret_cast<EDiscordPremiumType*>(premiumType));
return static_cast<Result>(result);
}
Result UserManager::CurrentUserHasFlag(UserFlag flag, bool* hasFlag)
{
if (!hasFlag) {
return Result::InternalError;
}
auto result = internal_->current_user_has_flag(
internal_, static_cast<EDiscordUserFlag>(flag), reinterpret_cast<bool*>(hasFlag));
return static_cast<Result>(result);
}
} // namespace discord

View File

@ -0,0 +1,31 @@
#pragma once
#include "types.h"
namespace discord {
class UserManager final {
public:
~UserManager() = default;
Result GetCurrentUser(User* currentUser);
void GetUser(UserId userId, std::function<void(Result, User const&)> callback);
Result GetCurrentUserPremiumType(PremiumType* premiumType);
Result CurrentUserHasFlag(UserFlag flag, bool* hasFlag);
Event<> OnCurrentUserUpdate;
private:
friend class Core;
UserManager() = default;
UserManager(UserManager const& rhs) = delete;
UserManager& operator=(UserManager const& rhs) = delete;
UserManager(UserManager&& rhs) = delete;
UserManager& operator=(UserManager&& rhs) = delete;
IDiscordUserManager* internal_;
static IDiscordUserEvents events_;
};
} // namespace discord

View File

@ -0,0 +1,124 @@
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS
#endif
#include "voice_manager.h"
#include "core.h"
#include <cstring>
#include <memory>
namespace discord {
class VoiceEvents final {
public:
static void OnSettingsUpdate(void* callbackData)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->VoiceManager();
module.OnSettingsUpdate();
}
};
IDiscordVoiceEvents VoiceManager::events_{
&VoiceEvents::OnSettingsUpdate,
};
Result VoiceManager::GetInputMode(InputMode* inputMode)
{
if (!inputMode) {
return Result::InternalError;
}
auto result =
internal_->get_input_mode(internal_, reinterpret_cast<DiscordInputMode*>(inputMode));
return static_cast<Result>(result);
}
void VoiceManager::SetInputMode(InputMode inputMode, std::function<void(Result)> callback)
{
static auto wrapper = [](void* callbackData, EDiscordResult result) -> void {
std::unique_ptr<std::function<void(Result)>> cb(
reinterpret_cast<std::function<void(Result)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(static_cast<Result>(result));
};
std::unique_ptr<std::function<void(Result)>> cb{};
cb.reset(new std::function<void(Result)>(std::move(callback)));
internal_->set_input_mode(
internal_, *reinterpret_cast<DiscordInputMode const*>(&inputMode), cb.release(), wrapper);
}
Result VoiceManager::IsSelfMute(bool* mute)
{
if (!mute) {
return Result::InternalError;
}
auto result = internal_->is_self_mute(internal_, reinterpret_cast<bool*>(mute));
return static_cast<Result>(result);
}
Result VoiceManager::SetSelfMute(bool mute)
{
auto result = internal_->set_self_mute(internal_, (mute ? 1 : 0));
return static_cast<Result>(result);
}
Result VoiceManager::IsSelfDeaf(bool* deaf)
{
if (!deaf) {
return Result::InternalError;
}
auto result = internal_->is_self_deaf(internal_, reinterpret_cast<bool*>(deaf));
return static_cast<Result>(result);
}
Result VoiceManager::SetSelfDeaf(bool deaf)
{
auto result = internal_->set_self_deaf(internal_, (deaf ? 1 : 0));
return static_cast<Result>(result);
}
Result VoiceManager::IsLocalMute(Snowflake userId, bool* mute)
{
if (!mute) {
return Result::InternalError;
}
auto result = internal_->is_local_mute(internal_, userId, reinterpret_cast<bool*>(mute));
return static_cast<Result>(result);
}
Result VoiceManager::SetLocalMute(Snowflake userId, bool mute)
{
auto result = internal_->set_local_mute(internal_, userId, (mute ? 1 : 0));
return static_cast<Result>(result);
}
Result VoiceManager::GetLocalVolume(Snowflake userId, std::uint8_t* volume)
{
if (!volume) {
return Result::InternalError;
}
auto result =
internal_->get_local_volume(internal_, userId, reinterpret_cast<uint8_t*>(volume));
return static_cast<Result>(result);
}
Result VoiceManager::SetLocalVolume(Snowflake userId, std::uint8_t volume)
{
auto result = internal_->set_local_volume(internal_, userId, volume);
return static_cast<Result>(result);
}
} // namespace discord

View File

@ -0,0 +1,37 @@
#pragma once
#include "types.h"
namespace discord {
class VoiceManager final {
public:
~VoiceManager() = default;
Result GetInputMode(InputMode* inputMode);
void SetInputMode(InputMode inputMode, std::function<void(Result)> callback);
Result IsSelfMute(bool* mute);
Result SetSelfMute(bool mute);
Result IsSelfDeaf(bool* deaf);
Result SetSelfDeaf(bool deaf);
Result IsLocalMute(Snowflake userId, bool* mute);
Result SetLocalMute(Snowflake userId, bool mute);
Result GetLocalVolume(Snowflake userId, std::uint8_t* volume);
Result SetLocalVolume(Snowflake userId, std::uint8_t volume);
Event<> OnSettingsUpdate;
private:
friend class Core;
VoiceManager() = default;
VoiceManager(VoiceManager const& rhs) = delete;
VoiceManager& operator=(VoiceManager const& rhs) = delete;
VoiceManager(VoiceManager&& rhs) = delete;
VoiceManager& operator=(VoiceManager&& rhs) = delete;
IDiscordVoiceManager* internal_;
static IDiscordVoiceEvents events_;
};
} // namespace discord

Binary file not shown.

View File

@ -117,6 +117,7 @@
"Config": "Config", "Config": "Config",
"CopyrightDisclaimer": "Copyright Grinch_ 2019-2022. All rights reserved.", "CopyrightDisclaimer": "Copyright Grinch_ 2019-2022. All rights reserved.",
"Credits": "Credits", "Credits": "Credits",
"DiscordRPC" : "Discord rich presence",
"DiscordServer": "Discord server", "DiscordServer": "Discord server",
"FixVehKey": "Fix current vehicle", "FixVehKey": "Fix current vehicle",
"FlipVehKey": "Flip current vehicle", "FlipVehKey": "Flip current vehicle",
@ -605,5 +606,15 @@
"VehiclePage": "Vehicle", "VehiclePage": "Vehicle",
"VisualPage": "Visual", "VisualPage": "Visual",
"WeaponPage": "Weapon" "WeaponPage": "Weapon"
},
"RPC" :
{
"Walking" : "Walking",
"Driving" : "Driving",
"In" : "in",
"DoingMission" : "Doing missions",
"BrowsingCheatMenu" : "Browsing CheatMenu",
"InsideMenus" : "Inside Menus",
"PlayingFor" : "Playing for {}:{}:{}"
} }
} }

View File

@ -385,6 +385,11 @@ void CheatMenu::ShowUpdatePage()
} }
} }
bool CheatMenu::IsMenuShown()
{
return m_bShowMenu;
}
void CheatMenu::ApplyStyle() void CheatMenu::ApplyStyle()
{ {
ImGuiStyle* style = &ImGui::GetStyle(); ImGuiStyle* style = &ImGui::GetStyle();

View File

@ -44,6 +44,7 @@ public:
CheatMenu(const CheatMenu&) = delete; CheatMenu(const CheatMenu&) = delete;
static void Init(); static void Init();
static bool IsMenuShown();
static void ResetMenuSize(); static void ResetMenuSize();
static void GenHeaderList(); static void GenHeaderList();
}; };

View File

@ -2,6 +2,7 @@
#include "cheatmenu.h" #include "cheatmenu.h"
#include "updater.h" #include "updater.h"
#include "version.h" #include "version.h"
#include "rpc.h"
void MenuThread(void* param) void MenuThread(void* param)
{ {
@ -85,7 +86,8 @@ void MenuThread(void* param)
while (true) while (true)
{ {
Updater::Process(); Updater::Process();
Sleep(5000); RPC::Process();
Sleep(1000);
} }
} }

View File

@ -770,7 +770,7 @@ void Game::ShowPage()
{ {
for (size_t i = 69; i != 80; ++i) for (size_t i = 69; i != 80; ++i)
{ {
CStats::SetStatValue(i, 1000); CStats::SetStatValue((unsigned short)i, 1000);
} }
CHud::GetRidOfAllHudMessages(true); CHud::GetRidOfAllHudMessages(true);
SetHelpMessage(TEXT("Game.MaxWepSkillsText")); SetHelpMessage(TEXT("Game.MaxWepSkillsText"));

View File

@ -5,6 +5,7 @@
#include "util.h" #include "util.h"
#include "updater.h" #include "updater.h"
#include "cheatmenu.h" #include "cheatmenu.h"
#include "rpc.h"
#ifdef GTASA #ifdef GTASA
#include "teleport.h" #include "teleport.h"
@ -31,7 +32,7 @@ void Menu::Init()
m_Overlay::textColor[1] = gConfig.GetValue("overlay.text_color.g", 1.0f); m_Overlay::textColor[1] = gConfig.GetValue("overlay.text_color.g", 1.0f);
m_Overlay::textColor[2] = gConfig.GetValue("overlay.text_color.b", 1.0f); m_Overlay::textColor[2] = gConfig.GetValue("overlay.text_color.b", 1.0f);
m_Overlay::textColor[3] = gConfig.GetValue("overlay.text_color.a", 1.0f); m_Overlay::textColor[3] = gConfig.GetValue("overlay.text_color.a", 1.0f);
m_bDiscordRPC = gConfig.GetValue("menu.discord_rpc", false);
// Hotkeys // Hotkeys
aimSkinChanger.m_key1 = gConfig.GetValue("hotkey.aim_skin_changer.key1", VK_RETURN); aimSkinChanger.m_key1 = gConfig.GetValue("hotkey.aim_skin_changer.key1", VK_RETURN);
@ -76,6 +77,11 @@ void Menu::Init()
GlobalMemoryStatusEx(&memInfo); GlobalMemoryStatusEx(&memInfo);
m_Overlay::mTotalRam = static_cast<int>(memInfo.ullTotalPhys * 1e-6); // Bytes -> MegaBytes m_Overlay::mTotalRam = static_cast<int>(memInfo.ullTotalPhys * 1e-6); // Bytes -> MegaBytes
if (m_bDiscordRPC)
{
RPC::Init();
}
} }
void Menu::DrawOverlay() void Menu::DrawOverlay()
@ -384,6 +390,24 @@ void Menu::ShowPage()
} }
} }
} }
ImGui::Spacing();
ImGui::Columns(2);
if (ImGui::Checkbox(TEXT("Menu.DiscordRPC"), &m_bDiscordRPC))
{
if (m_bDiscordRPC)
{
RPC::Init();
}
else
{
RPC::Shutdown();
}
gConfig.SetValue("menu.discord_rpc", m_bDiscordRPC);
}
ImGui::NextColumn();
ImGui::Columns(1);
ImGui::EndTabItem(); ImGui::EndTabItem();
} }

View File

@ -44,6 +44,7 @@ public:
static inline bool m_bShowMenu; static inline bool m_bShowMenu;
static inline char m_nInputBuffer[INPUT_BUFFER_SIZE] = ""; static inline char m_nInputBuffer[INPUT_BUFFER_SIZE] = "";
}; };
static inline bool m_bDiscordRPC;
Menu() = delete; Menu() = delete;
Menu(const Menu&) = delete; Menu(const Menu&) = delete;

View File

@ -578,7 +578,7 @@ void Player::ShowPage()
{ {
ImGui::BeginChild("PlayerMenus"); ImGui::BeginChild("PlayerMenus");
Ui::EditReference(TEXT("Player.Armour"), pPlayer->m_fArmour, 0, 100, pInfo->m_nMaxArmour); Ui::EditReference(TEXT("Player.Armour"), pPlayer->m_fArmour, 0, 100, BY_GAME(pInfo->m_nMaxArmour, pInfo->m_nMaxArmour, 100));
#ifdef GTASA #ifdef GTASA
if (ImGui::CollapsingHeader(TEXT("Player.Body"))) if (ImGui::CollapsingHeader(TEXT("Player.Body")))
{ {

123
src/rpc.cpp Normal file
View File

@ -0,0 +1,123 @@
#include "pch.h"
#include "rpc.h"
#include "util.h"
#include "menu.h"
#include "vehicle.h"
#include "cheatmenu.h"
char asciitolower(char in)
{
if (in <= 'Z' && in >= 'A')
return in - ('Z' - 'z');
return in;
}
void RPC::Shutdown()
{
}
void RPC::Init()
{
discord::Result result = discord::Core::Create(951199292981403669, DiscordCreateFlags_Default, &pCore);
bInit = result == discord::Result::Ok;
}
void RPC::Process()
{
if (!Menu::m_bDiscordRPC)
{
return;
}
static std::string detailsText, stateText, smallImg, smallImgText, largeImg, largeImgText;
static size_t curImage = 1;
static size_t timer = 0;
static size_t startTime = CTimer::m_snTimeInMilliseconds;
CPlayerInfo *pInfo = &CWorld::Players[CWorld::PlayerInFocus];
CPlayerPed *pPed = pInfo->m_pPed;
if (pPed)
{
size_t curTimer = CTimer::m_snTimeInMilliseconds;
size_t wantedLevel = pPed->m_pWanted->m_nWantedLevel;
if (wantedLevel > 0)
{
detailsText = std::format("{}: ", TEXT("Player.WantedLevel"));
for (size_t i = 0; i < wantedLevel; ++i)
{
detailsText += "";
}
}
else
{
detailsText = std::format("{}: ${}", TEXT("Player.Money"), pInfo->m_nMoney);
}
if (BY_GAME(pPed->m_nPedFlags.bInVehicle, pPed->m_bInVehicle, pPed->m_bInVehicle))
{
std::string name = Vehicle::GetNameFromModel(pPed->m_pVehicle->m_nModelIndex);
std::transform(name.begin(), name.end(), name.begin(), asciitolower);
smallImgText = std::format("{} {} {} {}", TEXT("RPC.Driving"), name, TEXT("RPC.In"), Util::GetLocationName(&pPed->GetPosition()));
smallImg = "drive";
}
else
{
smallImg = "walk";
smallImgText = std::format("{} {} {}", TEXT("RPC.Walking"), TEXT("RPC.In"), Util::GetLocationName(&pPed->GetPosition()));
}
size_t seconds = curTimer - startTime;
size_t minutes = (seconds / 60) % 60;
size_t hours = (minutes / 60) % 60;
stateText = std::format(TEXT("RPC.PlayingFor"), hours, minutes, seconds);
if (BY_GAME(Util::IsOnMission(), false, false))
{
stateText = TEXT("RPC.DoingMission");
}
if (CheatMenu::IsMenuShown())
{
stateText = TEXT("RPC.BrowsingCheatMenu");
}
if (BY_GAME(FrontEndMenuManager.m_bMenuActive, FrontendMenuManager.m_bMenuVisible, FrontEndMenuManager.m_bMenuActive))
{
stateText = TEXT("RPC.InsideMenus");
}
largeImgText = std::format("{}: {} / {} {}: {} / {}", TEXT("Player.Armour"), pPed->m_fArmour, BY_GAME(pInfo->m_nMaxArmour, pInfo->m_nMaxArmour, 100), TEXT("Player.Health"), pPed->m_fHealth, BY_GAME(pPed->m_fMaxHealth, 100, 100));
largeImg = std::format("{}{}", BY_GAME("sa", "vc", "3"), curImage);
discord::Activity activity{};
activity.SetDetails(detailsText.c_str());
activity.SetState(stateText.c_str());
activity.GetAssets().SetSmallImage(smallImg.c_str());
activity.GetAssets().SetSmallText(smallImgText.c_str());
activity.GetAssets().SetLargeImage(largeImg.c_str());
activity.GetAssets().SetLargeText(largeImgText.c_str());
activity.SetType(discord::ActivityType::Playing);
pCore->ActivityManager().UpdateActivity(activity,
[](discord::Result result)
{
if (result != discord::Result::Ok)
{
gLog << "Failed to set discord activity!" << std::endl;
}
});
pCore->RunCallbacks();
if (curTimer - timer > 10000)
{
curImage++;
if (curImage > totalLargeImages)
{
curImage = 1;
}
timer = curTimer;
}
}
}

18
src/rpc.h Normal file
View File

@ -0,0 +1,18 @@
#pragma once
#include "../depend/discord/discord.h"
class RPC
{
private:
static inline discord::Core* pCore;
static inline bool bInit = false;
static inline size_t totalLargeImages = 5;
public:
RPC() = delete;
RPC(RPC&) = delete;
static void Init();
static void Process();
static void Shutdown();
};

View File

@ -2,5 +2,5 @@
#define MENU_NAME "Cheat Menu" #define MENU_NAME "Cheat Menu"
#define MENU_VERSION_NUMBER "3.2" #define MENU_VERSION_NUMBER "3.2"
#define MENU_VERSION MENU_VERSION_NUMBER"-beta" #define MENU_VERSION MENU_VERSION_NUMBER"-beta"
#define BUILD_NUMBER "20220304" #define BUILD_NUMBER "20220306"
#define MENU_TITLE MENU_NAME " v" MENU_VERSION #define MENU_TITLE MENU_NAME " v" MENU_VERSION

View File

@ -30,16 +30,28 @@ workspace "CheatMenu"
location "../build" location "../build"
targetdir "../build/bin" targetdir "../build/bin"
project "Depend" links {
"d3d9",
"d3d11",
"Pdh",
"urlmon",
"depend",
"discord_game_sdk"
}
project "depend"
kind "StaticLib" kind "StaticLib"
files { files {
"../depned/**.h", "../depend/**.h",
"../depend/**.hpp", "../depend/**.hpp",
"../depend/**.c", "../depend/**.c",
"../depend/**.cpp" "../depend/**.cpp"
} }
libdirs (PSDK_DIR .. "/output/lib") libdirs {
PSDK_DIR .. "/output/lib",
"../depend/lib"
}
filter "configurations:Debug" filter "configurations:Debug"
defines { "DEBUG", "IS_PLATFORM_WIN" } defines { "DEBUG", "IS_PLATFORM_WIN" }
@ -108,7 +120,6 @@ project "CheatMenuIII"
libdirs (PSDK_DIR .. "/output/lib") libdirs (PSDK_DIR .. "/output/lib")
defines { defines {
"NDEBUG",
"IS_PLATFORM_WIN" , "IS_PLATFORM_WIN" ,
"_CRT_SECURE_NO_WARNINGS", "_CRT_SECURE_NO_WARNINGS",
"_CRT_NON_CONFORMING_SWPRINTFS", "_CRT_NON_CONFORMING_SWPRINTFS",
@ -123,24 +134,14 @@ project "CheatMenuIII"
filter "configurations:Debug" filter "configurations:Debug"
symbols "On" symbols "On"
links { links {
"Depend", "depend",
"d3d9",
"d3d11",
"XInput9_1_0",
"Pdh",
"urlmon",
"plugin_III_d.lib" "plugin_III_d.lib"
} }
filter "configurations:Release" filter "configurations:Release"
optimize "On" optimize "On"
links { links {
"Depend", "depend",
"d3d9",
"d3d11",
"XInput9_1_0",
"Pdh",
"urlmon",
"plugin_III.lib" "plugin_III.lib"
} }
@ -202,7 +203,6 @@ project "CheatMenuVC"
libdirs (PSDK_DIR .. "/output/lib") libdirs (PSDK_DIR .. "/output/lib")
defines { defines {
"NDEBUG",
"IS_PLATFORM_WIN" , "IS_PLATFORM_WIN" ,
"_CRT_SECURE_NO_WARNINGS", "_CRT_SECURE_NO_WARNINGS",
"_CRT_NON_CONFORMING_SWPRINTFS", "_CRT_NON_CONFORMING_SWPRINTFS",
@ -217,24 +217,14 @@ project "CheatMenuVC"
filter "configurations:Debug" filter "configurations:Debug"
symbols "On" symbols "On"
links { links {
"Depend", "depend",
"d3d9",
"d3d11",
"XInput9_1_0",
"Pdh",
"urlmon",
"plugin_vc_d.lib" "plugin_vc_d.lib"
} }
filter "configurations:Release" filter "configurations:Release"
optimize "On" optimize "On"
links { links {
"Depend", "depend",
"d3d9",
"d3d11",
"XInput9_1_0",
"Pdh",
"urlmon",
"plugin_vc.lib" "plugin_vc.lib"
} }
@ -253,10 +243,12 @@ project "CheatMenuSA"
PSDK_DIR .. "/shared/", PSDK_DIR .. "/shared/",
PSDK_DIR .. "/shared/game/" PSDK_DIR .. "/shared/game/"
} }
libdirs (PSDK_DIR .. "/output/lib") libdirs {
PSDK_DIR .. "/output/lib",
"../depend/lib"
}
defines { defines {
"NDEBUG",
"IS_PLATFORM_WIN" , "IS_PLATFORM_WIN" ,
"_CRT_SECURE_NO_WARNINGS", "_CRT_SECURE_NO_WARNINGS",
"_CRT_NON_CONFORMING_SWPRINTFS", "_CRT_NON_CONFORMING_SWPRINTFS",
@ -271,24 +263,14 @@ project "CheatMenuSA"
filter "configurations:Debug" filter "configurations:Debug"
symbols "On" symbols "On"
links { links {
"Depend", "depend",
"d3d9", "plugin_d.lib",
"d3d11",
"XInput9_1_0",
"Pdh",
"urlmon",
"plugin_d.lib"
} }
filter "configurations:Release" filter "configurations:Release"
optimize "On" optimize "On"
links { links {
"Depend", "depend",
"d3d9", "plugin.lib",
"d3d11",
"XInput9_1_0",
"Pdh",
"urlmon",
"plugin.lib"
} }