Added Discord Rich Presence integration. Added discord exclusion preprocessor checks in emscripten build. Changed emscripten callbacks to use the browser window instead of the internal body.

This commit is contained in:
sigonasr2 2023-12-19 14:06:17 -06:00
parent fcb3ee87fd
commit d9e1a1ebaf
59 changed files with 5541 additions and 28 deletions

1
.gitignore vendored
View File

@ -375,3 +375,4 @@ Crawler/Crawler.wasm
Crawler/pixelGameEngine_wasm.o
*.tiled-session
/Crawler/Crawler.tiled-session
/Crawler/assets/discordAPI.txt

View File

@ -67,6 +67,9 @@ All rights reserved.
#include "olcPGEX_TTF.h"
#include "MenuItemItemButton.h"
#include "Merchant.h"
#ifndef __EMSCRIPTEN__
#include "discord-files/discord.h"
#endif
INCLUDE_EMITTER_LIST
@ -89,14 +92,14 @@ InputGroup Crawler::KEY_DOWN;
InputGroup Crawler::KEY_ATTACK;
InputGroup Crawler::KEY_CONFIRM;
InputGroup Crawler::KEY_MENU;
#ifndef __EMSCRIPTEN__
::discord::Core*Discord{};
#endif
float Crawler::SIZE_CHANGE_SPEED=1;
Crawler::Crawler()
{
sAppName = "Crawler Concept";
game=this;
utils::datafile::Read(DATA,"assets/config/configuration.txt");
_DEBUG_MAP_LOAD_INFO=bool("debug_map_load_info"_I);
@ -141,6 +144,9 @@ Crawler::Crawler()
}
utils::datafile::DEBUG_ACCESS_OPTIONS="debug_access_options"_I;
sAppName = "GAME_NAME"_S;
game=this;
}
bool Crawler::OnUserCreate(){
@ -202,6 +208,8 @@ bool Crawler::OnUserCreate(){
utils::datafile::INITIAL_SETUP_COMPLETE=true;
ValidateGameStatus(); //Checks to make sure everything has been initialized properly.
SetupDiscord();
return true;
}
@ -216,6 +224,11 @@ bool Crawler::OnUserUpdate(float fElapsedTime){
RenderMenu();
RenderFadeout();
RenderVersionInfo();
#ifndef __EMSCRIPTEN__
if(Discord){
Discord->RunCallbacks();
}
#endif
return !gameEnd;
}
@ -2276,4 +2289,43 @@ bool Crawler::GamePaused(){
void Crawler::EndGame(){
gameEnd=true;
}
void Crawler::SetupDiscord(){
gameStarted=time(NULL);
#ifndef __EMSCRIPTEN__
auto result = ::discord::Core::Create(1186719371750555780,DiscordCreateFlags_NoRequireDiscord,&Discord);
if(result==::discord::Result::Ok){
Discord->SetLogHook(
discord::LogLevel::Debug, [](discord::LogLevel level, const char* message) {
std::cerr << "Log(" << static_cast<uint32_t>(level) << "): " << message << "\n";
});
std::cout<<"Connected to Discord!"<<std::endl;
UpdateDiscordStatus("Main Menu",player.get()->GetClassName());
}
#endif
}
void Crawler::UpdateDiscordStatus(std::string levelName,std::string className){
#ifndef __EMSCRIPTEN__
if(Discord){
::discord::Activity newActivity{};
newActivity.SetDetails(levelName.c_str());
newActivity.SetState(("Class: "+className).c_str());
discord::ActivityTimestamps&timestamps=newActivity.GetTimestamps();
timestamps.SetStart(gameStarted);
newActivity.SetType(discord::ActivityType::Playing);
discord::ActivityAssets&assets=newActivity.GetAssets();
assets.SetLargeImage("heart_512");
if(levelName!="Main Menu"){
std::for_each(className.begin(),className.end(),[](char&c){c=std::tolower(c);});
assets.SetSmallImage(("nico-"+className+"_512").c_str());
}
assets.SetLargeText(game->sAppName.c_str());
assets.SetSmallText(className.c_str());
Discord->ActivityManager().UpdateActivity(newActivity,[](::discord::Result result){
std::cout<<"Discord Activity successfully updated!"<<std::endl;
});
}
#endif
}

View File

@ -110,8 +110,10 @@ private:
States::State transitionState=States::State::GAME_RUN;
bool gameEnd=false;
std::vector<Monster>monstersToBeSpawned;
time_t gameStarted;
void ValidateGameStatus();
void SetupDiscord();
public:
Crawler();
bool OnUserCreate() override;
@ -197,6 +199,7 @@ public:
void RenderFadeout();
bool GamePaused();
void EndGame();
void UpdateDiscordStatus(std::string levelName,std::string className);
struct TileGroupData{
vi2d tilePos;

View File

@ -131,14 +131,14 @@
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\sigon\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\Users\sigon\source\repos\Crawler\Crawler;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>discord_game_sdk.dll.lib;freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies);</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"</Command>
@ -154,14 +154,14 @@
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies);discord_game_sdk.dll.lib</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"</Command>
@ -177,14 +177,14 @@
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;C:\Users\sigon\source\repos\Crawler\Crawler\discord-files</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>discord_game_sdk.dll.lib;freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies);discord_game_sdk.dll.lib</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"</Command>
@ -197,14 +197,14 @@
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\sigon\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalLibraryDirectories>C:\Users\sigon\source\repos\Crawler\Crawler;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalDependencies>freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>discord_game_sdk.dll.lib;freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies);</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"</Command>
@ -224,14 +224,14 @@
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies);discord_game_sdk.dll.lib</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"</Command>
@ -250,14 +250,14 @@
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalOptions>/MP8 %(AdditionalOptions)</AdditionalOptions>
<AdditionalIncludeDirectories>C:\Users\sigon\Documents\include;</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;C:\Users\sigon\Documents\include;C:\Users\sigon\source\repos\Crawler\Crawler\discord-files</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalDependencies>discord_game_sdk.dll.lib;freetype.lib;$(CoreLibraryDependencies);%(AdditionalDependencies);discord_game_sdk.dll.lib</AdditionalDependencies>
</Link>
<PreBuildEvent>
<Command>powershell.exe -ExecutionPolicy Bypass -NoProfile -NonInteractive -File update_version.ps1 "./version.h"</Command>
@ -270,17 +270,21 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Emscripten|Win32'">
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);discord_game_sdk.dll.lib</AdditionalDependencies>
</Link>
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Emscripten|x64'">
<Link>
<SubSystem>Console</SubSystem>
<AdditionalDependencies>$(CoreLibraryDependencies);%(AdditionalDependencies);discord_game_sdk.dll.lib</AdditionalDependencies>
</Link>
<ClCompile>
<LanguageStandard>stdcpp20</LanguageStandard>
<AdditionalIncludeDirectories>C:\Users\sigon\source\repos\Crawler\Crawler\discord-files;</AdditionalIncludeDirectories>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
@ -307,6 +311,23 @@
<ClInclude Include="Crawler.h" />
<ClInclude Include="DamageNumber.h" />
<ClInclude Include="DEFINES.h" />
<ClInclude Include="discord-files\achievement_manager.h" />
<ClInclude Include="discord-files\activity_manager.h" />
<ClInclude Include="discord-files\application_manager.h" />
<ClInclude Include="discord-files\core.h" />
<ClInclude Include="discord-files\discord.h" />
<ClInclude Include="discord-files\event.h" />
<ClInclude Include="discord-files\ffi.h" />
<ClInclude Include="discord-files\image_manager.h" />
<ClInclude Include="discord-files\lobby_manager.h" />
<ClInclude Include="discord-files\network_manager.h" />
<ClInclude Include="discord-files\overlay_manager.h" />
<ClInclude Include="discord-files\relationship_manager.h" />
<ClInclude Include="discord-files\storage_manager.h" />
<ClInclude Include="discord-files\store_manager.h" />
<ClInclude Include="discord-files\types.h" />
<ClInclude Include="discord-files\user_manager.h" />
<ClInclude Include="discord-files\voice_manager.h" />
<ClInclude Include="drawutil.h" />
<ClInclude Include="Effect.h" />
<ClInclude Include="Emitter.h" />
@ -428,6 +449,20 @@
<ClCompile Include="ConnectionPoint.cpp" />
<ClCompile Include="Crawler.cpp" />
<ClCompile Include="DamageNumber.cpp" />
<ClCompile Include="discord-files\achievement_manager.cpp" />
<ClCompile Include="discord-files\activity_manager.cpp" />
<ClCompile Include="discord-files\application_manager.cpp" />
<ClCompile Include="discord-files\core.cpp" />
<ClCompile Include="discord-files\image_manager.cpp" />
<ClCompile Include="discord-files\lobby_manager.cpp" />
<ClCompile Include="discord-files\network_manager.cpp" />
<ClCompile Include="discord-files\overlay_manager.cpp" />
<ClCompile Include="discord-files\relationship_manager.cpp" />
<ClCompile Include="discord-files\storage_manager.cpp" />
<ClCompile Include="discord-files\store_manager.cpp" />
<ClCompile Include="discord-files\types.cpp" />
<ClCompile Include="discord-files\user_manager.cpp" />
<ClCompile Include="discord-files\voice_manager.cpp" />
<ClCompile Include="drawutil.cpp" />
<ClCompile Include="Effect.cpp" />
<ClCompile Include="Emitter.cpp" />

View File

@ -73,6 +73,12 @@
<Filter Include="Documentation\Story">
<UniqueIdentifier>{9ab34e07-c7ba-4f4b-9dad-29c7602c1550}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\discord-files">
<UniqueIdentifier>{4fada79e-3b17-42df-8609-adf564fe12d9}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\discord-files">
<UniqueIdentifier>{8911e0bb-703c-4a2b-b3dd-259192956733}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClInclude Include="olcPixelGameEngine.h">
@ -312,6 +318,57 @@
<ClInclude Include="FunctionPriming.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="discord-files\user_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\voice_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\achievement_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\activity_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\application_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\core.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\discord.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\event.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\ffi.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\image_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\lobby_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\network_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\overlay_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\relationship_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\storage_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\store_manager.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
<ClInclude Include="discord-files\types.h">
<Filter>Header Files\discord-files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Player.cpp">
@ -506,6 +563,48 @@
<ClCompile Include="Merchant.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="discord-files\voice_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\achievement_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\activity_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\application_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\core.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\image_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\lobby_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\network_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\overlay_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\relationship_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\storage_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\store_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\types.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
<ClCompile Include="discord-files\user_manager.cpp">
<Filter>Source Files\discord-files</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="cpp.hint" />

View File

@ -237,6 +237,7 @@ T*Component(MenuType menu,std::string componentName){
}else{
ERR("WARNING! Attempting to cast a button that isn't a "<<typeid(T).name()<<"!");
}
return nullptr;
}
struct MenuFuncData{

View File

@ -71,6 +71,7 @@ void State_OverworldMap::OnStateChange(GameState*prevState){
Component<EncountersSpawnListScrollableWindowComponent>(OVERWORLD_LEVEL_SELECT,"Spawns List")->UpdateSpawns(currentConnectionPoint->spawns);
Component<MenuComponent>(OVERWORLD_LEVEL_SELECT,"Enter Button")->Enable(currentConnectionPoint->levelDataExists);
Menu::OpenMenu(OVERWORLD_LEVEL_SELECT,false);
game->UpdateDiscordStatus("Overworld Map",game->GetPlayer()->GetClassName());
};
void State_OverworldMap::OnUserUpdate(Crawler*game){
if(Menu::stack.size()>1)return;
@ -156,6 +157,7 @@ ConnectionPoint&State_OverworldMap::GetCurrentConnectionPoint(){
}
void State_OverworldMap::StartLevel(){
game->UpdateDiscordStatus(State_OverworldMap::GetCurrentConnectionPoint().name,game->GetPlayer()->GetClassName());
if(State_OverworldMap::GetCurrentConnectionPoint().map.starts_with("STORY")){
VisualNovel::LoadVisualNovel(State_OverworldMap::GetCurrentConnectionPoint().map);
}else{

View File

@ -39,7 +39,7 @@ All rights reserved.
#define VERSION_MAJOR 0
#define VERSION_MINOR 2
#define VERSION_PATCH 1
#define VERSION_BUILD 4156
#define VERSION_BUILD 4187
#define stringify(a) stringify_(a)
#define stringify_(a) #a

View File

@ -3,6 +3,8 @@ config_path = assets/config/
# 360x240 is 15x10 tiles of visibility.
WINDOW_SIZE = 360,240
GAME_NAME = Crawler Project
# Graphics Loading Config
gfx_config = gfx/gfx.txt

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,99 @@
#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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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

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

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

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"

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

1113
Crawler/discord-files/ffi.h Normal file

File diff suppressed because it is too large Load Diff

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,554 @@
#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 DISCORD_CALLBACK OnLobbyUpdate(void* callbackData, int64_t lobbyId)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->LobbyManager();
module.OnLobbyUpdate(lobbyId);
}
static void DISCORD_CALLBACK 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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,229 @@
#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 DISCORD_CALLBACK 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);
}
Result OverlayManager::InitDrawingDxgi(IDXGISwapChain* swapchain, bool useMessageForwarding)
{
auto result =
internal_->init_drawing_dxgi(internal_, swapchain, (useMessageForwarding ? 1 : 0));
return static_cast<Result>(result);
}
void OverlayManager::OnPresent()
{
internal_->on_present(internal_);
}
void OverlayManager::ForwardMessage(MSG* message)
{
internal_->forward_message(internal_, message);
}
void OverlayManager::KeyEvent(bool down, char const* keyCode, KeyVariant variant)
{
internal_->key_event(internal_,
(down ? 1 : 0),
const_cast<char*>(keyCode),
static_cast<EDiscordKeyVariant>(variant));
}
void OverlayManager::CharEvent(char const* character)
{
internal_->char_event(internal_, const_cast<char*>(character));
}
void OverlayManager::MouseButtonEvent(std::uint8_t down,
std::int32_t clickCount,
MouseButton which,
std::int32_t x,
std::int32_t y)
{
internal_->mouse_button_event(
internal_, down, clickCount, static_cast<EDiscordMouseButton>(which), x, y);
}
void OverlayManager::MouseMotionEvent(std::int32_t x, std::int32_t y)
{
internal_->mouse_motion_event(internal_, x, y);
}
void OverlayManager::ImeCommitText(char const* text)
{
internal_->ime_commit_text(internal_, const_cast<char*>(text));
}
void OverlayManager::ImeSetComposition(char const* text,
ImeUnderline* underlines,
std::uint32_t underlinesLength,
std::int32_t from,
std::int32_t to)
{
internal_->ime_set_composition(internal_,
const_cast<char*>(text),
reinterpret_cast<DiscordImeUnderline*>(underlines),
underlinesLength,
from,
to);
}
void OverlayManager::ImeCancelComposition()
{
internal_->ime_cancel_composition(internal_);
}
void OverlayManager::SetImeCompositionRangeCallback(
std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)>
onImeCompositionRangeChanged)
{
static auto wrapper = [](void* callbackData,
int32_t from,
int32_t to,
DiscordRect* bounds,
uint32_t boundsLength) -> void {
std::unique_ptr<std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)>> cb(
reinterpret_cast<std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)>*>(
callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(from, to, reinterpret_cast<Rect*>(bounds), boundsLength);
};
std::unique_ptr<std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)>> cb{};
cb.reset(new std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)>(
std::move(onImeCompositionRangeChanged)));
internal_->set_ime_composition_range_callback(internal_, cb.release(), wrapper);
}
void OverlayManager::SetImeSelectionBoundsCallback(
std::function<void(Rect, Rect, bool)> onImeSelectionBoundsChanged)
{
static auto wrapper =
[](void* callbackData, DiscordRect anchor, DiscordRect focus, bool isAnchorFirst) -> void {
std::unique_ptr<std::function<void(Rect, Rect, bool)>> cb(
reinterpret_cast<std::function<void(Rect, Rect, bool)>*>(callbackData));
if (!cb || !(*cb)) {
return;
}
(*cb)(*reinterpret_cast<Rect const*>(&anchor),
*reinterpret_cast<Rect const*>(&focus),
(isAnchorFirst != 0));
};
std::unique_ptr<std::function<void(Rect, Rect, bool)>> cb{};
cb.reset(new std::function<void(Rect, Rect, bool)>(std::move(onImeSelectionBoundsChanged)));
internal_->set_ime_selection_bounds_callback(internal_, cb.release(), wrapper);
}
bool OverlayManager::IsPointInsideClickZone(std::int32_t x, std::int32_t y)
{
auto result = internal_->is_point_inside_click_zone(internal_, x, y);
return (result != 0);
}
} // namespace discord

View File

@ -0,0 +1,57 @@
#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);
Result InitDrawingDxgi(IDXGISwapChain* swapchain, bool useMessageForwarding);
void OnPresent();
void ForwardMessage(MSG* message);
void KeyEvent(bool down, char const* keyCode, KeyVariant variant);
void CharEvent(char const* character);
void MouseButtonEvent(std::uint8_t down,
std::int32_t clickCount,
MouseButton which,
std::int32_t x,
std::int32_t y);
void MouseMotionEvent(std::int32_t x, std::int32_t y);
void ImeCommitText(char const* text);
void ImeSetComposition(char const* text,
ImeUnderline* underlines,
std::uint32_t underlinesLength,
std::int32_t from,
std::int32_t to);
void ImeCancelComposition();
void SetImeCompositionRangeCallback(
std::function<void(std::int32_t, std::int32_t, Rect*, std::uint32_t)>
onImeCompositionRangeChanged);
void SetImeSelectionBoundsCallback(
std::function<void(Rect, Rect, bool)> onImeSelectionBoundsChanged);
bool IsPointInsideClickZone(std::int32_t x, std::int32_t y);
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,91 @@
#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 DISCORD_CALLBACK OnRefresh(void* callbackData)
{
auto* core = reinterpret_cast<Core*>(callbackData);
if (!core) {
return;
}
auto& module = core->RelationshipManager();
module.OnRefresh();
}
static void DISCORD_CALLBACK 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,162 @@
#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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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

View File

@ -0,0 +1,879 @@
#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 ActivityParty::SetPrivacy(ActivityPartyPrivacy privacy)
{
internal_.privacy = static_cast<EDiscordActivityPartyPrivacy>(privacy);
}
ActivityPartyPrivacy ActivityParty::GetPrivacy() const
{
return static_cast<ActivityPartyPrivacy>(internal_.privacy);
}
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 Activity::SetSupportedPlatforms(std::uint32_t supportedPlatforms)
{
internal_.supported_platforms = supportedPlatforms;
}
std::uint32_t Activity::GetSupportedPlatforms() const
{
return internal_.supported_platforms;
}
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 ImeUnderline::SetFrom(std::int32_t from)
{
internal_.from = from;
}
std::int32_t ImeUnderline::GetFrom() const
{
return internal_.from;
}
void ImeUnderline::SetTo(std::int32_t to)
{
internal_.to = to;
}
std::int32_t ImeUnderline::GetTo() const
{
return internal_.to;
}
void ImeUnderline::SetColor(std::uint32_t color)
{
internal_.color = color;
}
std::uint32_t ImeUnderline::GetColor() const
{
return internal_.color;
}
void ImeUnderline::SetBackgroundColor(std::uint32_t backgroundColor)
{
internal_.background_color = backgroundColor;
}
std::uint32_t ImeUnderline::GetBackgroundColor() const
{
return internal_.background_color;
}
void ImeUnderline::SetThick(bool thick)
{
internal_.thick = thick;
}
bool ImeUnderline::GetThick() const
{
return internal_.thick != 0;
}
void Rect::SetLeft(std::int32_t left)
{
internal_.left = left;
}
std::int32_t Rect::GetLeft() const
{
return internal_.left;
}
void Rect::SetTop(std::int32_t top)
{
internal_.top = top;
}
std::int32_t Rect::GetTop() const
{
return internal_.top;
}
void Rect::SetRight(std::int32_t right)
{
internal_.right = right;
}
std::int32_t Rect::GetRight() const
{
return internal_.right;
}
void Rect::SetBottom(std::int32_t bottom)
{
internal_.bottom = bottom;
}
std::int32_t Rect::GetBottom() const
{
return internal_.bottom;
}
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

View File

@ -0,0 +1,567 @@
#pragma once
#include "ffi.h"
#include "event.h"
#ifdef _WIN32
#include <Windows.h>
#include <dxgi.h>
#endif
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,
DrawingInitFailed = 44,
};
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 ActivityPartyPrivacy {
Private = 0,
Public = 1,
};
enum class ActivityType {
Playing,
Streaming,
Listening,
Watching,
};
enum class ActivityActionType {
Join = 1,
Spectate,
};
enum class ActivitySupportedPlatformFlags {
Desktop = 1,
Android = 2,
iOS = 4,
};
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 KeyVariant {
Normal,
Right,
Left,
};
enum class MouseButton {
Left,
Middle,
Right,
};
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;
#ifdef __APPLE__
using IDXGISwapChain = void;
#endif
#ifdef __linux__
using IDXGISwapChain = void;
#endif
#ifdef __APPLE__
using MSG = void;
#endif
#ifdef __linux__
using MSG = void;
#endif
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;
void SetPrivacy(ActivityPartyPrivacy privacy);
ActivityPartyPrivacy GetPrivacy() 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;
void SetSupportedPlatforms(std::uint32_t supportedPlatforms);
std::uint32_t GetSupportedPlatforms() 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 ImeUnderline final {
public:
void SetFrom(std::int32_t from);
std::int32_t GetFrom() const;
void SetTo(std::int32_t to);
std::int32_t GetTo() const;
void SetColor(std::uint32_t color);
std::uint32_t GetColor() const;
void SetBackgroundColor(std::uint32_t backgroundColor);
std::uint32_t GetBackgroundColor() const;
void SetThick(bool thick);
bool GetThick() const;
private:
DiscordImeUnderline internal_;
};
class Rect final {
public:
void SetLeft(std::int32_t left);
std::int32_t GetLeft() const;
void SetTop(std::int32_t top);
std::int32_t GetTop() const;
void SetRight(std::int32_t right);
std::int32_t GetRight() const;
void SetBottom(std::int32_t bottom);
std::int32_t GetBottom() const;
private:
DiscordRect 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 DISCORD_CALLBACK 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 DISCORD_CALLBACK 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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Crawler/discord_game_sdk.so Normal file

Binary file not shown.

View File

@ -1,2 +1,2 @@
~\Documents\emsdk\emsdk_env.ps1 activate latest
em++ -std=c++20 -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_LIBPNG=1 -s USE_FREETYPE=1 $(Get-ChildItem *.cpp) -o pge.html --preload-file assets
em++ -std=c++20 -fexperimental-library -O2 -s ALLOW_MEMORY_GROWTH=1 -s MAX_WEBGL_VERSION=2 -s MIN_WEBGL_VERSION=2 -s USE_LIBPNG=1 -s USE_FREETYPE=1 $(Get-ChildItem *.cpp) -o pge.html --preload-file assets

View File

@ -1,3 +1,3 @@
TOTAL=$(wc -l $(find *.cpp *.h -not -name "olc*.h")|grep "total"|awk '{print $1}')
FILECOUNT=$(find *.cpp *.h -not -name "olc*.h"|wc -l)
TOTAL=$(wc -l $(find *.cpp *.h -not -name "miniaudio.h" -not -name "olc*.h")|grep "total"|awk '{print $1}')
FILECOUNT=$(find *.cpp *.h -not -name "miniaudio.h" -not -name "olc*.h"|wc -l)
echo "$[TOTAL-FILECOUNT*37] (License lines Excluded)"

View File

@ -6801,19 +6801,19 @@ namespace olc
mapKeys[DOM_PK_QUOTE] = Key::OEM_7; mapKeys[DOM_PK_BACKSLASH] = Key::OEM_8;
// Keyboard Callbacks
emscripten_set_keydown_callback("body", 0, 1, keyboard_callback);
emscripten_set_keyup_callback("body", 0, 1, keyboard_callback);
emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, 1, keyboard_callback);
emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, 1, keyboard_callback);
// Mouse Callbacks
emscripten_set_wheel_callback("#canvas", 0, 1, wheel_callback);
emscripten_set_mousedown_callback("body", 0, 1, mouse_callback);
emscripten_set_mouseup_callback("body", 0, 1, mouse_callback);
emscripten_set_mousemove_callback("body", 0, 1, mouse_callback);
emscripten_set_mousedown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, 1, mouse_callback);
emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, 1, mouse_callback);
emscripten_set_mousemove_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, 1, mouse_callback);
// Touch Callbacks
emscripten_set_touchstart_callback("body", 0, 1, touch_callback);
emscripten_set_touchmove_callback("body", 0, 1, touch_callback);
emscripten_set_touchend_callback("body", 0, 1, touch_callback);
emscripten_set_touchstart_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, 1, touch_callback);
emscripten_set_touchmove_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, 1, touch_callback);
emscripten_set_touchend_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, 0, 1, touch_callback);
// Canvas Focus Callbacks
emscripten_set_blur_callback("#canvas", 0, 1, focus_callback);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.9 MiB

After

Width:  |  Height:  |  Size: 10 MiB

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.