2023-06-20 04:33:09 +00:00
|
|
|
#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:
|
2024-03-08 09:09:27 +00:00
|
|
|
static void DISCORD_CALLBACK OnToggle(void* callbackData, bool locked)
|
2023-06-20 04:33:09 +00:00
|
|
|
{
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2024-03-08 09:09:27 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2023-06-20 04:33:09 +00:00
|
|
|
} // namespace discord
|