Skip to content

Commit

Permalink
Discord: first 100 guild users are fetched from the server
Browse files Browse the repository at this point in the history
  • Loading branch information
georgehazan committed Dec 27, 2020
1 parent b06220b commit 0a5de30
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 44 deletions.
5 changes: 5 additions & 0 deletions libs/libjson/src/stdafx.cxx
Expand Up @@ -51,7 +51,12 @@ LIBJSON_DLL(JSONNode&) operator<<(JSONNode &json, const CHAR_PARAM &param)
JSONNode tmp(JSON_NULL); tmp.set_name(param.szName);
json.push_back(tmp);
}
else if (param.szName == nullptr) {
JSONNode tmp; tmp.set_name(param.szValue);
json.push_back(tmp);
}
else json.push_back(JSONNode(param.szName, param.szValue));

return json;
}

Expand Down
55 changes: 55 additions & 0 deletions protocols/Discord/src/dispatch.cpp
Expand Up @@ -39,6 +39,7 @@ static handlers[] = // these structures must me sorted alphabetically
{ L"GUILD_CREATE", &CDiscordProto::OnCommandGuildCreated },
{ L"GUILD_DELETE", &CDiscordProto::OnCommandGuildDeleted },
{ L"GUILD_MEMBER_ADD", &CDiscordProto::OnCommandGuildMemberAdded },
{ L"GUILD_MEMBER_LIST_UPDATE", &CDiscordProto::OnCommandGuildMemberListUpdate },
{ L"GUILD_MEMBER_REMOVE", &CDiscordProto::OnCommandGuildMemberRemoved },
{ L"GUILD_MEMBER_UPDATE", &CDiscordProto::OnCommandGuildMemberUpdated },
{ L"GUILD_ROLE_CREATE", &CDiscordProto::OnCommandRoleCreated },
Expand Down Expand Up @@ -198,6 +199,60 @@ void CDiscordProto::OnCommandGuildMemberAdded(const JSONNode&)
{
}

void CDiscordProto::OnCommandGuildMemberListUpdate(const JSONNode &pRoot)
{
auto *pGuild = FindGuild(::getId(pRoot["guild_id"]));
if (pGuild == nullptr)
return;

int iStatus = 0;

for (auto &ops: pRoot["ops"]) {
for (auto &it : ops["items"]) {
auto &item = it.at((size_t)0);
if (!mir_strcmp(item .name(), "group")) {
iStatus = item ["id"].as_string() == "online" ? ID_STATUS_ONLINE : ID_STATUS_OFFLINE;
continue;
}

if (!mir_strcmp(item .name(), "member")) {
bool bNew = false;
CMStringW wszUserId = item["user"]["id"].as_mstring();
SnowFlake userId = _wtoi64(wszUserId);
CDiscordGuildMember *pm = pGuild->FindUser(userId);
if (pm == nullptr) {
pm = new CDiscordGuildMember(userId);
pGuild->arChatUsers.insert(pm);
pm->wszNick = item["user"]["username"].as_mstring() + L"#" + item["user"]["discriminator"].as_mstring();
bNew = true;
}

pm->iStatus = iStatus;

if (bNew)
AddGuildUser(pGuild, *pm);
else if (iStatus) {
GCEVENT gce = { m_szModuleName, 0, GC_EVENT_SETCONTACTSTATUS };
gce.time = time(0);
gce.pszUID.w = wszUserId;
Chat_Event(&gce);

for (auto &cc : pGuild->arChannels) {
if (!cc->bIsGroup)
continue;

gce.pszID.w = cc->wszChannelName;
gce.dwItemData = iStatus;
Chat_Event(&gce);
}
}
}
}
}

pGuild->bSynced = true;
}

void CDiscordProto::OnCommandGuildMemberRemoved(const JSONNode &pRoot)
{
CDiscordGuild *pGuild = FindGuild(::getId(pRoot["guild_id"]));
Expand Down
20 changes: 20 additions & 0 deletions protocols/Discord/src/gateway.cpp
Expand Up @@ -236,6 +236,26 @@ bool CDiscordProto::GatewayProcess(const JSONNode &pRoot)
//////////////////////////////////////////////////////////////////////////////////////
// requests to be sent to a gateway

void CDiscordProto::GatewaySendGuildInfo(CDiscordGuild *pGuild)
{
if (!pGuild->arChannels.getCount())
return;

JSONNode a1(JSON_ARRAY); a1 << INT_PARAM("", 0) << INT_PARAM("", 99);

CMStringA szId(FORMAT, "%lld", pGuild->arChannels[0]->id);
JSONNode chl(JSON_ARRAY); chl.set_name(szId.c_str()); chl << a1;

JSONNode channels; channels.set_name("channels"); channels << chl;

JSONNode payload; payload.set_name("d");
payload << SINT64_PARAM("guild_id", pGuild->id) << BOOL_PARAM("typing", true) << BOOL_PARAM("activities", true) << BOOL_PARAM("presences", true) << channels;

JSONNode root;
root << INT_PARAM("op", OPCODE_REQUEST_SYNC_CHANNEL) << payload;
GatewaySend(root);
}

void CDiscordProto::GatewaySendHeartbeat()
{
// we don't send heartbeat packets until we get logged in
Expand Down
46 changes: 6 additions & 40 deletions protocols/Discord/src/guilds.cpp
Expand Up @@ -173,9 +173,6 @@ void CDiscordProto::ProcessGuild(const JSONNode &pRoot)
pGuild->hContact = si->hContact;
setId(pGuild->hContact, DB_KEY_CHANNELID, guildId);

if (!pGuild->bSynced && getByte(si->hContact, "EnableSync"))
LoadGuildInfo(pGuild);

Chat_Control(m_szModuleName, pGuild->wszName, WINDOW_HIDDEN);
Chat_Control(m_szModuleName, pGuild->wszName, SESSION_ONLINE);

Expand All @@ -184,6 +181,12 @@ void CDiscordProto::ProcessGuild(const JSONNode &pRoot)

BuildStatusList(pGuild, si);

for (auto &it : pRoot["channels"])
ProcessGuildChannel(pGuild, it);

if (!pGuild->bSynced && getByte(si->hContact, "EnableSync"))
GatewaySendGuildInfo(pGuild);

// store all guild members
for (auto &it : pRoot["members"]) {
CMStringW wszUserId = it["user"]["id"].as_mstring();
Expand Down Expand Up @@ -222,9 +225,6 @@ void CDiscordProto::ProcessGuild(const JSONNode &pRoot)
for (auto &it : pGuild->arChatUsers)
AddGuildUser(pGuild, *it);

for (auto &it : pRoot["channels"])
ProcessGuildChannel(pGuild, it);

if (m_bUseGroupchats)
ForkThread(&CDiscordProto::BatchChatCreate, pGuild);

Expand Down Expand Up @@ -311,37 +311,3 @@ void CDiscordProto::AddGuildUser(CDiscordGuild *pGuild, const CDiscordGuildMembe
if (pUser.userId == m_ownId)
pGuild->pParentSi->pMe = pu;
}

/////////////////////////////////////////////////////////////////////////////////////////

static CMStringW GetCacheFileName(SnowFlake guildId)
{
VARSW wszCacheDir(L"%miranda_userdata%\\Discord");
CreateDirectoryTreeW(wszCacheDir);

return CMStringW(FORMAT, L"%s\\%lld.cache", wszCacheDir.get(), guildId);
}

void CDiscordProto::LoadGuildInfo(CDiscordGuild *pGuild)
{
CMStringW wszCacheFile(GetCacheFileName(pGuild->id));
int fileId = _wopen(wszCacheFile, _O_BINARY | _O_RDONLY);
if (fileId != -1) {
size_t length = _filelength(fileId);
ptrA buf((char *)mir_alloc(length+1));
int result = _read(fileId, buf, (unsigned)length);
_close(fileId);
if (result == -1)
return;

JSONNode root(JSONNode::parse(buf));
for (auto &cc : root) {
auto *pUser = new CDiscordGuildMember(_wtoi64(cc["id"].as_mstring()));
pUser->wszNick = cc["nick"].as_mstring();
pUser->wszRole = cc["role"].as_mstring();
pGuild->arChatUsers.insert(pUser);

AddGuildUser(pGuild, *pUser);
}
}
}
2 changes: 1 addition & 1 deletion protocols/Discord/src/menus.cpp
Expand Up @@ -95,7 +95,7 @@ INT_PTR CDiscordProto::OnMenuToggleSync(WPARAM hContact, LPARAM)

if (bEnabled)
if (auto *pGuild = FindGuild(getId(hContact, DB_KEY_CHANNELID)))
LoadGuildInfo(pGuild);
GatewaySendGuildInfo(pGuild);
return 0;
}

Expand Down
5 changes: 3 additions & 2 deletions protocols/Discord/src/proto.h
Expand Up @@ -234,6 +234,7 @@ class CDiscordProto : public PROTO<CDiscordProto>
void GatewaySend(const JSONNode &pNode);
bool GatewayProcess(const JSONNode &pNode);

void GatewaySendGuildInfo(CDiscordGuild *pGuild);
void GatewaySendHeartbeat(void);
void GatewaySendIdentify(void);
void GatewaySendResume(void);
Expand Down Expand Up @@ -299,8 +300,7 @@ class CDiscordProto : public PROTO<CDiscordProto>
}

void AddGuildUser(CDiscordGuild *guild, const CDiscordGuildMember &pUser);
void LoadGuildInfo(CDiscordGuild *guild);


void ProcessGuild(const JSONNode &json);
CDiscordUser* ProcessGuildChannel(CDiscordGuild *guild, const JSONNode &json);
void ProcessPresence(const JSONNode &json);
Expand Down Expand Up @@ -398,6 +398,7 @@ class CDiscordProto : public PROTO<CDiscordProto>
void OnCommandGuildCreated(const JSONNode &json);
void OnCommandGuildDeleted(const JSONNode &json);
void OnCommandGuildMemberAdded(const JSONNode &json);
void OnCommandGuildMemberListUpdate(const JSONNode &json);
void OnCommandGuildMemberRemoved(const JSONNode &json);
void OnCommandGuildMemberUpdated(const JSONNode &json);
void OnCommandFriendAdded(const JSONNode &json);
Expand Down
2 changes: 1 addition & 1 deletion protocols/Discord/src/version.h
@@ -1,7 +1,7 @@
#define __MAJOR_VERSION 0
#define __MINOR_VERSION 6
#define __RELEASE_NUM 2
#define __BUILD_NUM 5
#define __BUILD_NUM 6

#include <stdver.h>

Expand Down

0 comments on commit 0a5de30

Please sign in to comment.