mirror of
https://github.com/SashLilac/cambridge.git
synced 2025-05-13 20:21:25 -05:00
Preliminary work to change from DiscordRPC to Discord GameSDK
This commit is contained in:
155
libs/discordGameSDK/examples/c/main.c
Normal file
155
libs/discordGameSDK/examples/c/main.c
Normal file
@@ -0,0 +1,155 @@
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include "discord_game_sdk.h"
|
||||
#ifdef _WIN32
|
||||
#include <Windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#endif
|
||||
|
||||
#define DISCORD_REQUIRE(x) assert(x == DiscordResult_Ok)
|
||||
|
||||
struct Application {
|
||||
struct IDiscordCore* core;
|
||||
struct IDiscordUserManager* users;
|
||||
struct IDiscordAchievementManager* achievements;
|
||||
struct IDiscordActivityManager* activities;
|
||||
struct IDiscordRelationshipManager* relationships;
|
||||
struct IDiscordApplicationManager* application;
|
||||
struct IDiscordLobbyManager* lobbies;
|
||||
DiscordUserId user_id;
|
||||
};
|
||||
|
||||
void UpdateActivityCallback(void* data, enum EDiscordResult result)
|
||||
{
|
||||
DISCORD_REQUIRE(result);
|
||||
}
|
||||
|
||||
int RelationshipPassFilter(void* data, struct DiscordRelationship* relationship)
|
||||
{
|
||||
return (relationship->type == DiscordRelationshipType_Friend);
|
||||
}
|
||||
|
||||
int RelationshipSnowflakeFilter(void* data, struct DiscordRelationship* relationship)
|
||||
{
|
||||
struct Application* app = (struct Application*)data;
|
||||
|
||||
return (relationship->type == DiscordRelationshipType_Friend &&
|
||||
relationship->user.id < app->user_id);
|
||||
}
|
||||
|
||||
void OnRelationshipsRefresh(void* data)
|
||||
{
|
||||
struct Application* app = (struct Application*)data;
|
||||
struct IDiscordRelationshipManager* module = app->relationships;
|
||||
|
||||
module->filter(module, app, RelationshipPassFilter);
|
||||
|
||||
int32_t unfiltered_count = 0;
|
||||
DISCORD_REQUIRE(module->count(module, &unfiltered_count));
|
||||
|
||||
module->filter(module, app, RelationshipSnowflakeFilter);
|
||||
|
||||
int32_t filtered_count = 0;
|
||||
DISCORD_REQUIRE(module->count(module, &filtered_count));
|
||||
|
||||
printf("=== Cool Friends ===\n");
|
||||
for (int32_t i = 0; i < filtered_count; i += 1) {
|
||||
struct DiscordRelationship relationship;
|
||||
DISCORD_REQUIRE(module->get_at(module, i, &relationship));
|
||||
|
||||
printf("%lld %s#%s\n",
|
||||
relationship.user.id,
|
||||
relationship.user.username,
|
||||
relationship.user.discriminator);
|
||||
}
|
||||
printf("(%d friends less cool than you omitted)\n", unfiltered_count - filtered_count);
|
||||
|
||||
struct DiscordActivity activity;
|
||||
memset(&activity, 0, sizeof(activity));
|
||||
sprintf(activity.details, "Cooler than %d friends", unfiltered_count - filtered_count);
|
||||
sprintf(activity.state, "%d friends total", unfiltered_count);
|
||||
|
||||
app->activities->update_activity(app->activities, &activity, app, UpdateActivityCallback);
|
||||
}
|
||||
|
||||
void OnUserUpdated(void* data)
|
||||
{
|
||||
struct Application* app = (struct Application*)data;
|
||||
struct DiscordUser user;
|
||||
app->users->get_current_user(app->users, &user);
|
||||
app->user_id = user.id;
|
||||
}
|
||||
|
||||
void OnOAuth2Token(void* data, enum EDiscordResult result, struct DiscordOAuth2Token* token)
|
||||
{
|
||||
if (result == DiscordResult_Ok) {
|
||||
printf("OAuth2 token: %s\n", token->access_token);
|
||||
}
|
||||
else {
|
||||
printf("GetOAuth2Token failed with %d\n", (int)result);
|
||||
}
|
||||
}
|
||||
|
||||
void OnLobbyConnect(void* data, enum EDiscordResult result, struct DiscordLobby* lobby)
|
||||
{
|
||||
printf("LobbyConnect returned %d\n", (int)result);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
struct Application app;
|
||||
memset(&app, 0, sizeof(app));
|
||||
|
||||
struct IDiscordUserEvents users_events;
|
||||
memset(&users_events, 0, sizeof(users_events));
|
||||
users_events.on_current_user_update = OnUserUpdated;
|
||||
|
||||
struct IDiscordActivityEvents activities_events;
|
||||
memset(&activities_events, 0, sizeof(activities_events));
|
||||
|
||||
struct IDiscordRelationshipEvents relationships_events;
|
||||
memset(&relationships_events, 0, sizeof(relationships_events));
|
||||
relationships_events.on_refresh = OnRelationshipsRefresh;
|
||||
|
||||
struct DiscordCreateParams params;
|
||||
DiscordCreateParamsSetDefault(¶ms);
|
||||
params.client_id = 418559331265675294;
|
||||
params.flags = DiscordCreateFlags_Default;
|
||||
params.event_data = &app;
|
||||
params.activity_events = &activities_events;
|
||||
params.relationship_events = &relationships_events;
|
||||
params.user_events = &users_events;
|
||||
DISCORD_REQUIRE(DiscordCreate(DISCORD_VERSION, ¶ms, &app.core));
|
||||
|
||||
app.users = app.core->get_user_manager(app.core);
|
||||
app.achievements = app.core->get_achievement_manager(app.core);
|
||||
app.activities = app.core->get_activity_manager(app.core);
|
||||
app.application = app.core->get_application_manager(app.core);
|
||||
app.lobbies = app.core->get_lobby_manager(app.core);
|
||||
|
||||
app.lobbies->connect_lobby_with_activity_secret(
|
||||
app.lobbies, "invalid_secret", &app, OnLobbyConnect);
|
||||
|
||||
app.application->get_oauth2_token(app.application, &app, OnOAuth2Token);
|
||||
|
||||
DiscordBranch branch;
|
||||
app.application->get_current_branch(app.application, &branch);
|
||||
printf("Current branch %s\n", branch);
|
||||
|
||||
app.relationships = app.core->get_relationship_manager(app.core);
|
||||
|
||||
for (;;) {
|
||||
DISCORD_REQUIRE(app.core->run_callbacks(app.core));
|
||||
|
||||
#ifdef _WIN32
|
||||
Sleep(16);
|
||||
#else
|
||||
usleep(16 * 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
297
libs/discordGameSDK/examples/cpp/main.cpp
Normal file
297
libs/discordGameSDK/examples/cpp/main.cpp
Normal file
@@ -0,0 +1,297 @@
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
#include <csignal>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <thread>
|
||||
#include <vector>
|
||||
|
||||
#include "discord.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#pragma pack(push, 1)
|
||||
struct BitmapImageHeader {
|
||||
uint32_t const structSize{sizeof(BitmapImageHeader)};
|
||||
int32_t width{0};
|
||||
int32_t height{0};
|
||||
uint16_t const planes{1};
|
||||
uint16_t const bpp{32};
|
||||
uint32_t const pad0{0};
|
||||
uint32_t const pad1{0};
|
||||
uint32_t const hres{2835};
|
||||
uint32_t const vres{2835};
|
||||
uint32_t const pad4{0};
|
||||
uint32_t const pad5{0};
|
||||
|
||||
BitmapImageHeader& operator=(BitmapImageHeader const&) = delete;
|
||||
};
|
||||
|
||||
struct BitmapFileHeader {
|
||||
uint8_t const magic0{'B'};
|
||||
uint8_t const magic1{'M'};
|
||||
uint32_t size{0};
|
||||
uint32_t const pad{0};
|
||||
uint32_t const offset{sizeof(BitmapFileHeader) + sizeof(BitmapImageHeader)};
|
||||
|
||||
BitmapFileHeader& operator=(BitmapFileHeader const&) = delete;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
|
||||
struct DiscordState {
|
||||
discord::User currentUser;
|
||||
|
||||
std::unique_ptr<discord::Core> core;
|
||||
};
|
||||
|
||||
namespace {
|
||||
volatile bool interrupted{false};
|
||||
}
|
||||
|
||||
int main(int, char**)
|
||||
{
|
||||
DiscordState state{};
|
||||
|
||||
discord::Core* core{};
|
||||
auto result = discord::Core::Create(310270644849737729, DiscordCreateFlags_Default, &core);
|
||||
state.core.reset(core);
|
||||
if (!state.core) {
|
||||
std::cout << "Failed to instantiate discord core! (err " << static_cast<int>(result)
|
||||
<< ")\n";
|
||||
std::exit(-1);
|
||||
}
|
||||
|
||||
state.core->SetLogHook(
|
||||
discord::LogLevel::Debug, [](discord::LogLevel level, const char* message) {
|
||||
std::cerr << "Log(" << static_cast<uint32_t>(level) << "): " << message << "\n";
|
||||
});
|
||||
|
||||
core->UserManager().OnCurrentUserUpdate.Connect([&state]() {
|
||||
state.core->UserManager().GetCurrentUser(&state.currentUser);
|
||||
|
||||
std::cout << "Current user updated: " << state.currentUser.GetUsername() << "#"
|
||||
<< state.currentUser.GetDiscriminator() << "\n";
|
||||
|
||||
state.core->UserManager().GetUser(130050050968518656,
|
||||
[](discord::Result result, discord::User const& user) {
|
||||
if (result == discord::Result::Ok) {
|
||||
std::cout << "Get " << user.GetUsername() << "\n";
|
||||
}
|
||||
else {
|
||||
std::cout << "Failed to get David!\n";
|
||||
}
|
||||
});
|
||||
|
||||
discord::ImageHandle handle{};
|
||||
handle.SetId(state.currentUser.GetId());
|
||||
handle.SetType(discord::ImageType::User);
|
||||
handle.SetSize(256);
|
||||
|
||||
state.core->ImageManager().Fetch(
|
||||
handle, true, [&state](discord::Result res, discord::ImageHandle handle) {
|
||||
if (res == discord::Result::Ok) {
|
||||
discord::ImageDimensions dims{};
|
||||
state.core->ImageManager().GetDimensions(handle, &dims);
|
||||
std::cout << "Fetched " << dims.GetWidth() << "x" << dims.GetHeight()
|
||||
<< " avatar!\n";
|
||||
|
||||
std::vector<uint8_t> data;
|
||||
data.reserve(dims.GetWidth() * dims.GetHeight() * 4);
|
||||
uint8_t* d = data.data();
|
||||
state.core->ImageManager().GetData(handle, d, data.size());
|
||||
|
||||
#if defined(_WIN32)
|
||||
auto fileSize =
|
||||
data.size() + sizeof(BitmapImageHeader) + sizeof(BitmapFileHeader);
|
||||
|
||||
BitmapImageHeader imageHeader;
|
||||
imageHeader.width = static_cast<int32_t>(dims.GetWidth());
|
||||
imageHeader.height = static_cast<int32_t>(dims.GetHeight());
|
||||
|
||||
BitmapFileHeader fileHeader;
|
||||
fileHeader.size = static_cast<uint32_t>(fileSize);
|
||||
|
||||
FILE* fp = fopen("avatar.bmp", "wb");
|
||||
fwrite(&fileHeader, sizeof(BitmapFileHeader), 1, fp);
|
||||
fwrite(&imageHeader, sizeof(BitmapImageHeader), 1, fp);
|
||||
|
||||
for (auto y = 0u; y < dims.GetHeight(); ++y) {
|
||||
auto pixels = reinterpret_cast<uint32_t const*>(data.data());
|
||||
auto invY = dims.GetHeight() - y - 1;
|
||||
fwrite(
|
||||
&pixels[invY * dims.GetWidth()], sizeof(uint32_t) * dims.GetWidth(), 1, fp);
|
||||
}
|
||||
|
||||
fflush(fp);
|
||||
fclose(fp);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
std::cout << "Failed fetching avatar. (err " << static_cast<int>(res) << ")\n";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
state.core->ActivityManager().RegisterCommand("run/command/foo/bar/baz/here.exe");
|
||||
state.core->ActivityManager().RegisterSteam(123123321);
|
||||
|
||||
state.core->ActivityManager().OnActivityJoin.Connect(
|
||||
[](const char* secret) { std::cout << "Join " << secret << "\n"; });
|
||||
state.core->ActivityManager().OnActivitySpectate.Connect(
|
||||
[](const char* secret) { std::cout << "Spectate " << secret << "\n"; });
|
||||
state.core->ActivityManager().OnActivityJoinRequest.Connect([](discord::User const& user) {
|
||||
std::cout << "Join Request " << user.GetUsername() << "\n";
|
||||
});
|
||||
state.core->ActivityManager().OnActivityInvite.Connect(
|
||||
[](discord::ActivityActionType, discord::User const& user, discord::Activity const&) {
|
||||
std::cout << "Invite " << user.GetUsername() << "\n";
|
||||
});
|
||||
|
||||
state.core->LobbyManager().OnLobbyUpdate.Connect(
|
||||
[](std::int64_t lobbyId) { std::cout << "Lobby update " << lobbyId << "\n"; });
|
||||
|
||||
state.core->LobbyManager().OnLobbyDelete.Connect(
|
||||
[](std::int64_t lobbyId, std::uint32_t reason) {
|
||||
std::cout << "Lobby delete " << lobbyId << " (reason: " << reason << ")\n";
|
||||
});
|
||||
|
||||
state.core->LobbyManager().OnMemberConnect.Connect(
|
||||
[](std::int64_t lobbyId, std::int64_t userId) {
|
||||
std::cout << "Lobby member connect " << lobbyId << " userId " << userId << "\n";
|
||||
});
|
||||
|
||||
state.core->LobbyManager().OnMemberUpdate.Connect(
|
||||
[](std::int64_t lobbyId, std::int64_t userId) {
|
||||
std::cout << "Lobby member update " << lobbyId << " userId " << userId << "\n";
|
||||
});
|
||||
|
||||
state.core->LobbyManager().OnMemberDisconnect.Connect(
|
||||
[](std::int64_t lobbyId, std::int64_t userId) {
|
||||
std::cout << "Lobby member disconnect " << lobbyId << " userId " << userId << "\n";
|
||||
});
|
||||
|
||||
state.core->LobbyManager().OnLobbyMessage.Connect([&](std::int64_t lobbyId,
|
||||
std::int64_t userId,
|
||||
std::uint8_t* payload,
|
||||
std::uint32_t payloadLength) {
|
||||
std::vector<uint8_t> buffer{};
|
||||
buffer.resize(payloadLength);
|
||||
memcpy(buffer.data(), payload, payloadLength);
|
||||
std::cout << "Lobby message " << lobbyId << " from " << userId << " of length "
|
||||
<< payloadLength << " bytes.\n";
|
||||
|
||||
char fourtyNinetySix[4096];
|
||||
state.core->LobbyManager().GetLobbyMetadataValue(lobbyId, "foo", fourtyNinetySix);
|
||||
|
||||
std::cout << "Metadata for key foo is " << fourtyNinetySix << "\n";
|
||||
});
|
||||
|
||||
state.core->LobbyManager().OnSpeaking.Connect(
|
||||
[&](std::int64_t, std::int64_t userId, bool speaking) {
|
||||
std::cout << "User " << userId << " is " << (speaking ? "" : "NOT ") << "speaking.\n";
|
||||
});
|
||||
|
||||
discord::Activity activity{};
|
||||
activity.SetDetails("Fruit Tarts");
|
||||
activity.SetState("Pop Snacks");
|
||||
activity.GetAssets().SetSmallImage("the");
|
||||
activity.GetAssets().SetSmallText("i mage");
|
||||
activity.GetAssets().SetLargeImage("the");
|
||||
activity.GetAssets().SetLargeText("u mage");
|
||||
activity.SetType(discord::ActivityType::Playing);
|
||||
state.core->ActivityManager().UpdateActivity(activity, [](discord::Result result) {
|
||||
std::cout << ((result == discord::Result::Ok) ? "Succeeded" : "Failed")
|
||||
<< " updating activity!\n";
|
||||
});
|
||||
|
||||
discord::LobbyTransaction lobby{};
|
||||
state.core->LobbyManager().GetLobbyCreateTransaction(&lobby);
|
||||
lobby.SetCapacity(2);
|
||||
lobby.SetMetadata("foo", "bar");
|
||||
lobby.SetMetadata("baz", "bat");
|
||||
lobby.SetType(discord::LobbyType::Public);
|
||||
state.core->LobbyManager().CreateLobby(
|
||||
lobby, [&state](discord::Result result, discord::Lobby const& lobby) {
|
||||
if (result == discord::Result::Ok) {
|
||||
std::cout << "Created lobby with secret " << lobby.GetSecret() << "\n";
|
||||
std::array<uint8_t, 234> data{};
|
||||
state.core->LobbyManager().SendLobbyMessage(
|
||||
lobby.GetId(),
|
||||
reinterpret_cast<uint8_t*>(data.data()),
|
||||
data.size(),
|
||||
[](discord::Result result) {
|
||||
std::cout << "Sent message. Result: " << static_cast<int>(result) << "\n";
|
||||
});
|
||||
}
|
||||
else {
|
||||
std::cout << "Failed creating lobby. (err " << static_cast<int>(result) << ")\n";
|
||||
}
|
||||
|
||||
discord::LobbySearchQuery query{};
|
||||
state.core->LobbyManager().GetSearchQuery(&query);
|
||||
query.Limit(1);
|
||||
state.core->LobbyManager().Search(query, [&state](discord::Result result) {
|
||||
if (result == discord::Result::Ok) {
|
||||
std::int32_t lobbyCount{};
|
||||
state.core->LobbyManager().LobbyCount(&lobbyCount);
|
||||
std::cout << "Lobby search succeeded with " << lobbyCount << " lobbies.\n";
|
||||
for (auto i = 0; i < lobbyCount; ++i) {
|
||||
discord::LobbyId lobbyId{};
|
||||
state.core->LobbyManager().GetLobbyId(i, &lobbyId);
|
||||
std::cout << " " << lobbyId << "\n";
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "Lobby search failed. (err " << static_cast<int>(result) << ")\n";
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
state.core->RelationshipManager().OnRefresh.Connect([&]() {
|
||||
std::cout << "Relationships refreshed!\n";
|
||||
|
||||
state.core->RelationshipManager().Filter(
|
||||
[](discord::Relationship const& relationship) -> bool {
|
||||
return relationship.GetType() == discord::RelationshipType::Friend;
|
||||
});
|
||||
|
||||
std::int32_t friendCount{0};
|
||||
state.core->RelationshipManager().Count(&friendCount);
|
||||
|
||||
state.core->RelationshipManager().Filter(
|
||||
[&](discord::Relationship const& relationship) -> bool {
|
||||
return relationship.GetType() == discord::RelationshipType::Friend &&
|
||||
relationship.GetUser().GetId() < state.currentUser.GetId();
|
||||
});
|
||||
|
||||
std::int32_t filteredCount{0};
|
||||
state.core->RelationshipManager().Count(&filteredCount);
|
||||
|
||||
discord::Relationship relationship{};
|
||||
for (auto i = 0; i < filteredCount; ++i) {
|
||||
state.core->RelationshipManager().GetAt(i, &relationship);
|
||||
std::cout << relationship.GetUser().GetId() << " "
|
||||
<< relationship.GetUser().GetUsername() << "#"
|
||||
<< relationship.GetUser().GetDiscriminator() << "\n";
|
||||
}
|
||||
});
|
||||
|
||||
state.core->RelationshipManager().OnRelationshipUpdate.Connect(
|
||||
[](discord::Relationship const& relationship) {
|
||||
std::cout << "Relationship with " << relationship.GetUser().GetUsername()
|
||||
<< " updated!\n";
|
||||
});
|
||||
|
||||
std::signal(SIGINT, [](int) { interrupted = true; });
|
||||
|
||||
do {
|
||||
state.core->RunCallbacks();
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(16));
|
||||
} while (!interrupted);
|
||||
|
||||
return 0;
|
||||
}
|
||||
412
libs/discordGameSDK/examples/csharp/Program.cs
Normal file
412
libs/discordGameSDK/examples/csharp/Program.cs
Normal file
@@ -0,0 +1,412 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Text;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
class Program
|
||||
{
|
||||
// Request user's avatar data. Sizes can be powers of 2 between 16 and 2048
|
||||
static void FetchAvatar(Discord.ImageManager imageManager, Int64 userID)
|
||||
{
|
||||
imageManager.Fetch(Discord.ImageHandle.User(userID), (result, handle) =>
|
||||
{
|
||||
{
|
||||
if (result == Discord.Result.Ok)
|
||||
{
|
||||
// You can also use GetTexture2D within Unity.
|
||||
// These return raw RGBA.
|
||||
var data = imageManager.GetData(handle);
|
||||
Console.WriteLine("image updated {0} {1}", handle.Id, data.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("image error {0}", handle.Id);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Update user's activity for your game.
|
||||
// Party and secrets are vital.
|
||||
// Read https://discordapp.com/developers/docs/rich-presence/how-to for more details.
|
||||
static void UpdateActivity(Discord.Discord discord, Discord.Lobby lobby)
|
||||
{
|
||||
var activityManager = discord.GetActivityManager();
|
||||
var lobbyManager = discord.GetLobbyManager();
|
||||
|
||||
var activity = new Discord.Activity
|
||||
{
|
||||
State = "olleh",
|
||||
Details = "foo details",
|
||||
Timestamps =
|
||||
{
|
||||
Start = 5,
|
||||
End = 6,
|
||||
},
|
||||
Assets =
|
||||
{
|
||||
LargeImage = "foo largeImageKey",
|
||||
LargeText = "foo largeImageText",
|
||||
SmallImage = "foo smallImageKey",
|
||||
SmallText = "foo smallImageText",
|
||||
},
|
||||
Party = {
|
||||
Id = lobby.Id.ToString(),
|
||||
Size = {
|
||||
CurrentSize = lobbyManager.MemberCount(lobby.Id),
|
||||
MaxSize = (int)lobby.Capacity,
|
||||
},
|
||||
},
|
||||
Secrets = {
|
||||
Join = lobbyManager.GetLobbyActivitySecret(lobby.Id),
|
||||
},
|
||||
Instance = true,
|
||||
};
|
||||
|
||||
activityManager.UpdateActivity(activity, result =>
|
||||
{
|
||||
Console.WriteLine("Update Activity {0}", result);
|
||||
|
||||
// Send an invite to another user for this activity.
|
||||
// Receiver should see an invite in their DM.
|
||||
// Use a relationship user's ID for this.
|
||||
// activityManager
|
||||
// .SendInvite(
|
||||
// 364843917537050624,
|
||||
// Discord.ActivityActionType.Join,
|
||||
// "",
|
||||
// inviteResult =>
|
||||
// {
|
||||
// Console.WriteLine("Invite {0}", inviteResult);
|
||||
// }
|
||||
// );
|
||||
});
|
||||
}
|
||||
|
||||
static void Main(string[] args)
|
||||
{
|
||||
// Use your client ID from Discord's developer site.
|
||||
var clientID = Environment.GetEnvironmentVariable("DISCORD_CLIENT_ID");
|
||||
if (clientID == null)
|
||||
{
|
||||
clientID = "418559331265675294";
|
||||
}
|
||||
var discord = new Discord.Discord(Int64.Parse(clientID), (UInt64)Discord.CreateFlags.Default);
|
||||
discord.SetLogHook(Discord.LogLevel.Debug, (level, message) =>
|
||||
{
|
||||
Console.WriteLine("Log[{0}] {1}", level, message);
|
||||
});
|
||||
|
||||
var applicationManager = discord.GetApplicationManager();
|
||||
// Get the current locale. This can be used to determine what text or audio the user wants.
|
||||
Console.WriteLine("Current Locale: {0}", applicationManager.GetCurrentLocale());
|
||||
// Get the current branch. For example alpha or beta.
|
||||
Console.WriteLine("Current Branch: {0}", applicationManager.GetCurrentBranch());
|
||||
// If you want to verify information from your game's server then you can
|
||||
// grab the access token and send it to your server.
|
||||
//
|
||||
// This automatically looks for an environment variable passed by the Discord client,
|
||||
// if it does not exist the Discord client will focus itself for manual authorization.
|
||||
//
|
||||
// By-default the SDK grants the identify and rpc scopes.
|
||||
// Read more at https://discordapp.com/developers/docs/topics/oauth2
|
||||
// applicationManager.GetOAuth2Token((Discord.Result result, ref Discord.OAuth2Token oauth2Token) =>
|
||||
// {
|
||||
// Console.WriteLine("Access Token {0}", oauth2Token.AccessToken);
|
||||
// });
|
||||
|
||||
var activityManager = discord.GetActivityManager();
|
||||
var lobbyManager = discord.GetLobbyManager();
|
||||
// Received when someone accepts a request to join or invite.
|
||||
// Use secrets to receive back the information needed to add the user to the group/party/match
|
||||
activityManager.OnActivityJoin += secret =>
|
||||
{
|
||||
Console.WriteLine("OnJoin {0}", secret);
|
||||
lobbyManager.ConnectLobbyWithActivitySecret(secret, (Discord.Result result, ref Discord.Lobby lobby) =>
|
||||
{
|
||||
Console.WriteLine("Connected to lobby: {0}", lobby.Id);
|
||||
lobbyManager.ConnectNetwork(lobby.Id);
|
||||
lobbyManager.OpenNetworkChannel(lobby.Id, 0, true);
|
||||
foreach (var user in lobbyManager.GetMemberUsers(lobby.Id))
|
||||
{
|
||||
lobbyManager.SendNetworkMessage(lobby.Id, user.Id, 0,
|
||||
Encoding.UTF8.GetBytes(String.Format("Hello, {0}!", user.Username)));
|
||||
}
|
||||
UpdateActivity(discord, lobby);
|
||||
});
|
||||
};
|
||||
// Received when someone accepts a request to spectate
|
||||
activityManager.OnActivitySpectate += secret =>
|
||||
{
|
||||
Console.WriteLine("OnSpectate {0}", secret);
|
||||
};
|
||||
// A join request has been received. Render the request on the UI.
|
||||
activityManager.OnActivityJoinRequest += (ref Discord.User user) =>
|
||||
{
|
||||
Console.WriteLine("OnJoinRequest {0} {1}", user.Id, user.Username);
|
||||
};
|
||||
// An invite has been received. Consider rendering the user / activity on the UI.
|
||||
activityManager.OnActivityInvite += (Discord.ActivityActionType Type, ref Discord.User user, ref Discord.Activity activity2) =>
|
||||
{
|
||||
Console.WriteLine("OnInvite {0} {1} {2}", Type, user.Username, activity2.Name);
|
||||
// activityManager.AcceptInvite(user.Id, result =>
|
||||
// {
|
||||
// Console.WriteLine("AcceptInvite {0}", result);
|
||||
// });
|
||||
};
|
||||
// This is used to register the game in the registry such that Discord can find it.
|
||||
// This is only needed by games acquired from other platforms, like Steam.
|
||||
// activityManager.RegisterCommand();
|
||||
|
||||
var imageManager = discord.GetImageManager();
|
||||
|
||||
var userManager = discord.GetUserManager();
|
||||
// The auth manager fires events as information about the current user changes.
|
||||
// This event will fire once on init.
|
||||
//
|
||||
// GetCurrentUser will error until this fires once.
|
||||
userManager.OnCurrentUserUpdate += () =>
|
||||
{
|
||||
var currentUser = userManager.GetCurrentUser();
|
||||
Console.WriteLine(currentUser.Username);
|
||||
Console.WriteLine(currentUser.Id);
|
||||
};
|
||||
// If you store Discord user ids in a central place like a leaderboard and want to render them.
|
||||
// The users manager can be used to fetch arbitrary Discord users. This only provides basic
|
||||
// information and does not automatically update like relationships.
|
||||
userManager.GetUser(450795363658366976, (Discord.Result result, ref Discord.User user) =>
|
||||
{
|
||||
if (result == Discord.Result.Ok)
|
||||
{
|
||||
Console.WriteLine("user fetched: {0}", user.Username);
|
||||
|
||||
// Request users's avatar data.
|
||||
// This can only be done after a user is successfully fetched.
|
||||
FetchAvatar(imageManager, user.Id);
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine("user fetch error: {0}", result);
|
||||
}
|
||||
});
|
||||
|
||||
var relationshipManager = discord.GetRelationshipManager();
|
||||
// It is important to assign this handle right away to get the initial relationships refresh.
|
||||
// This callback will only be fired when the whole list is initially loaded or was reset
|
||||
relationshipManager.OnRefresh += () =>
|
||||
{
|
||||
// Filter a user's relationship list to be just friends
|
||||
relationshipManager.Filter((ref Discord.Relationship relationship) => { return relationship.Type == Discord.RelationshipType.Friend; });
|
||||
// Loop over all friends a user has.
|
||||
Console.WriteLine("relationships updated: {0}", relationshipManager.Count());
|
||||
for (var i = 0; i < Math.Min(relationshipManager.Count(), 10); i++)
|
||||
{
|
||||
// Get an individual relationship from the list
|
||||
var r = relationshipManager.GetAt((uint)i);
|
||||
Console.WriteLine("relationships: {0} {1} {2} {3}", r.Type, r.User.Username, r.Presence.Status, r.Presence.Activity.Name);
|
||||
|
||||
// Request relationship's avatar data.
|
||||
FetchAvatar(imageManager, r.User.Id);
|
||||
}
|
||||
};
|
||||
// All following relationship updates are delivered individually.
|
||||
// These are fired when a user gets a new friend, removes a friend, or a relationship's presence changes.
|
||||
relationshipManager.OnRelationshipUpdate += (ref Discord.Relationship r) =>
|
||||
{
|
||||
Console.WriteLine("relationship updated: {0} {1} {2} {3}", r.Type, r.User.Username, r.Presence.Status, r.Presence.Activity.Name);
|
||||
};
|
||||
|
||||
lobbyManager.OnLobbyMessage += (lobbyID, userID, data) =>
|
||||
{
|
||||
Console.WriteLine("lobby message: {0} {1}", lobbyID, Encoding.UTF8.GetString(data));
|
||||
};
|
||||
lobbyManager.OnNetworkMessage += (lobbyId, userId, channelId, data) =>
|
||||
{
|
||||
Console.WriteLine("network message: {0} {1} {2} {3}", lobbyId, userId, channelId, Encoding.UTF8.GetString(data));
|
||||
};
|
||||
lobbyManager.OnSpeaking += (lobbyID, userID, speaking) =>
|
||||
{
|
||||
Console.WriteLine("lobby speaking: {0} {1} {2}", lobbyID, userID, speaking);
|
||||
};
|
||||
// Create a lobby.
|
||||
var transaction = lobbyManager.GetLobbyCreateTransaction();
|
||||
transaction.SetCapacity(6);
|
||||
transaction.SetType(Discord.LobbyType.Public);
|
||||
transaction.SetMetadata("a", "123");
|
||||
transaction.SetMetadata("a", "456");
|
||||
transaction.SetMetadata("b", "111");
|
||||
transaction.SetMetadata("c", "222");
|
||||
|
||||
lobbyManager.CreateLobby(transaction, (Discord.Result result, ref Discord.Lobby lobby) =>
|
||||
{
|
||||
if (result != Discord.Result.Ok)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the lobby's configuration.
|
||||
Console.WriteLine("lobby {0} with capacity {1} and secret {2}", lobby.Id, lobby.Capacity, lobby.Secret);
|
||||
|
||||
// Check lobby metadata.
|
||||
foreach (var key in new string[] { "a", "b", "c" })
|
||||
{
|
||||
Console.WriteLine("{0} = {1}", key, lobbyManager.GetLobbyMetadataValue(lobby.Id, key));
|
||||
}
|
||||
|
||||
// Print all the members of the lobby.
|
||||
foreach (var user in lobbyManager.GetMemberUsers(lobby.Id))
|
||||
{
|
||||
Console.WriteLine("lobby member: {0}", user.Username);
|
||||
}
|
||||
|
||||
// Send everyone a message.
|
||||
lobbyManager.SendLobbyMessage(lobby.Id, "Hello from C#!", (_) =>
|
||||
{
|
||||
Console.WriteLine("sent message");
|
||||
});
|
||||
|
||||
// Update lobby.
|
||||
var lobbyTransaction = lobbyManager.GetLobbyUpdateTransaction(lobby.Id);
|
||||
lobbyTransaction.SetMetadata("d", "e");
|
||||
lobbyTransaction.SetCapacity(16);
|
||||
lobbyManager.UpdateLobby(lobby.Id, lobbyTransaction, (_) =>
|
||||
{
|
||||
Console.WriteLine("lobby has been updated");
|
||||
});
|
||||
|
||||
// Update a member.
|
||||
var lobbyID = lobby.Id;
|
||||
var userID = lobby.OwnerId;
|
||||
var memberTransaction = lobbyManager.GetMemberUpdateTransaction(lobbyID, userID);
|
||||
memberTransaction.SetMetadata("hello", "there");
|
||||
lobbyManager.UpdateMember(lobbyID, userID, memberTransaction, (_) =>
|
||||
{
|
||||
Console.WriteLine("lobby member has been updated: {0}", lobbyManager.GetMemberMetadataValue(lobbyID, userID, "hello"));
|
||||
});
|
||||
|
||||
// Search lobbies.
|
||||
var query = lobbyManager.GetSearchQuery();
|
||||
// Filter by a metadata value.
|
||||
query.Filter("metadata.a", Discord.LobbySearchComparison.GreaterThan, Discord.LobbySearchCast.Number, "455");
|
||||
query.Sort("metadata.a", Discord.LobbySearchCast.Number, "0");
|
||||
// Only return 1 result max.
|
||||
query.Limit(1);
|
||||
lobbyManager.Search(query, (_) =>
|
||||
{
|
||||
Console.WriteLine("search returned {0} lobbies", lobbyManager.LobbyCount());
|
||||
if (lobbyManager.LobbyCount() == 1)
|
||||
{
|
||||
Console.WriteLine("first lobby secret: {0}", lobbyManager.GetLobby(lobbyManager.GetLobbyId(0)).Secret);
|
||||
}
|
||||
});
|
||||
|
||||
// Connect to voice chat.
|
||||
lobbyManager.ConnectVoice(lobby.Id, (_) =>
|
||||
{
|
||||
Console.WriteLine("Connected to voice chat!");
|
||||
});
|
||||
|
||||
// Setup networking.
|
||||
lobbyManager.ConnectNetwork(lobby.Id);
|
||||
lobbyManager.OpenNetworkChannel(lobby.Id, 0, true);
|
||||
|
||||
// Update activity.
|
||||
UpdateActivity(discord, lobby);
|
||||
});
|
||||
|
||||
/*
|
||||
var overlayManager = discord.GetOverlayManager();
|
||||
overlayManager.OnOverlayLocked += locked =>
|
||||
{
|
||||
Console.WriteLine("Overlay Locked: {0}", locked);
|
||||
};
|
||||
overlayManager.SetLocked(false);
|
||||
*/
|
||||
|
||||
var storageManager = discord.GetStorageManager();
|
||||
var contents = new byte[20000];
|
||||
var random = new Random();
|
||||
random.NextBytes(contents);
|
||||
Console.WriteLine("storage path: {0}", storageManager.GetPath());
|
||||
storageManager.WriteAsync("foo", contents, res =>
|
||||
{
|
||||
var files = storageManager.Files();
|
||||
foreach (var file in files)
|
||||
{
|
||||
Console.WriteLine("file: {0} size: {1} last_modified: {2}", file.Filename, file.Size, file.LastModified);
|
||||
}
|
||||
storageManager.ReadAsyncPartial("foo", 400, 50, (result, data) =>
|
||||
{
|
||||
Console.WriteLine("partial contents of foo match {0}", Enumerable.SequenceEqual(data, new ArraySegment<byte>(contents, 400, 50)));
|
||||
});
|
||||
storageManager.ReadAsync("foo", (result, data) =>
|
||||
{
|
||||
Console.WriteLine("length of contents {0} data {1}", contents.Length, data.Length);
|
||||
Console.WriteLine("contents of foo match {0}", Enumerable.SequenceEqual(data, contents));
|
||||
Console.WriteLine("foo exists? {0}", storageManager.Exists("foo"));
|
||||
storageManager.Delete("foo");
|
||||
Console.WriteLine("post-delete foo exists? {0}", storageManager.Exists("foo"));
|
||||
});
|
||||
});
|
||||
|
||||
var storeManager = discord.GetStoreManager();
|
||||
storeManager.OnEntitlementCreate += (ref Discord.Entitlement entitlement) =>
|
||||
{
|
||||
Console.WriteLine("Entitlement Create1: {0}", entitlement.Id);
|
||||
};
|
||||
|
||||
// Start a purchase flow.
|
||||
// storeManager.StartPurchase(487507201519255552, result =>
|
||||
// {
|
||||
// if (result == Discord.Result.Ok)
|
||||
// {
|
||||
// Console.WriteLine("Purchase Complete");
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Console.WriteLine("Purchase Canceled");
|
||||
// }
|
||||
// });
|
||||
|
||||
// Get all entitlements.
|
||||
storeManager.FetchEntitlements(result =>
|
||||
{
|
||||
if (result == Discord.Result.Ok)
|
||||
{
|
||||
foreach (var entitlement in storeManager.GetEntitlements())
|
||||
{
|
||||
Console.WriteLine("entitlement: {0} - {1} {2}", entitlement.Id, entitlement.Type, entitlement.SkuId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Get all SKUs.
|
||||
storeManager.FetchSkus(result =>
|
||||
{
|
||||
if (result == Discord.Result.Ok)
|
||||
{
|
||||
foreach (var sku in storeManager.GetSkus())
|
||||
{
|
||||
Console.WriteLine("sku: {0} - {1} {2}", sku.Name, sku.Price.Amount, sku.Price.Currency);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Pump the event look to ensure all callbacks continue to get fired.
|
||||
try
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
discord.RunCallbacks();
|
||||
lobbyManager.FlushNetwork();
|
||||
Thread.Sleep(1000 / 60);
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
discord.Dispose();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user