DiscordCoreAPI
A Discord bot library written in C++, with custom asynchronous coroutines.
Loading...
Searching...
No Matches
GuildMemberEntities.cpp
Go to the documentation of this file.
1/*
2 MIT License
3
4 DiscordCoreAPI, A bot library for Discord, written in C++, and featuring explicit multithreading through the usage of custom, asynchronous C++ CoRoutines.
5
6 Copyright 2022, 2023 Chris M. (RealTimeChris)
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in all
16 copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 SOFTWARE.
25*/
26/// GuildMemberEntities.cpp - Source file for the guild_member_data related classes and structs.
27/// May 13, 2021
28/// https://discordcoreapi.com
29/// \file GuildMemberEntities.cpp
30
35
36namespace jsonifier {
37
38 template<> struct core<discord_core_api::add_guild_member_data> {
40 static constexpr auto parseValue = createObject("roles", &value_type::roles, "access_token", &value_type::accessToken, "guild_id", &value_type::guildId, "user_id",
41 &value_type::userId, "nick", &value_type::nick, "mute", &value_type::mute, "deaf", &value_type::deaf);
42 };
43
44 template<> struct core<discord_core_api::modify_current_guild_member_data> {
46 static constexpr auto parseValue = createObject("guild_id", &value_type::guildId, "nick", &value_type::nick, "reason", &value_type::reason);
47 };
48
49 template<> struct core<discord_core_api::modify_guild_member_data> {
51 static constexpr auto parseValue = createObject("channel_id", &value_type::currentChannelId, "deaf", &value_type::deaf, "guild_id", &value_type::guildId, "mute",
52 &value_type::mute, "nick", &value_type::nick, "roles", &value_type::roleIds, "user_id", &value_type::guildMemberId, "voice_channel_id", &value_type::newVoiceChannelId,
53 "reason", &value_type::reason);
54 };
55}
56
57namespace discord_core_api {
58
59 guild_member_cache_data& guild_member_cache_data::operator=(const guild_member_data& other) {
60 if (static_cast<int64_t>(other.flags) != 0) {
61 flags = other.flags;
62 }
63 setFlagValue(guild_member_flags::Pending, other.pending);
64 setFlagValue(guild_member_flags::Deaf, other.deaf);
65 setFlagValue(guild_member_flags::Mute, other.mute);
66 if (other.permissions.operator std::string_view() != "") {
67 permissionsVal = other.permissions;
68 }
69 if (other.joinedAt != "") {
70 joinedAt = other.joinedAt;
71 }
72 if (other.user.id != 0) {
73 user.id = other.user.id;
74 }
75 if (other.guildId != 0) {
76 guildId = other.guildId;
77 }
78 if (other.avatar != "") {
79 avatar = other.avatar;
80 }
81 if (other.roles.size() > 0) {
82 roles = other.roles;
83 }
84 if (other.nick != "") {
85 nick = other.nick;
86 }
87 return *this;
88 };
89
90 guild_member_cache_data::guild_member_cache_data(const guild_member_data& other) {
91 *this = other;
92 }
93
94 guild_member_cache_data& guild_member_cache_data::operator=(guild_member_data&& other) noexcept {
95 if (static_cast<int64_t>(other.flags) != 0) {
96 flags = other.flags;
97 }
98 setFlagValue(guild_member_flags::Pending, other.pending);
99 setFlagValue(guild_member_flags::Deaf, other.deaf);
100 setFlagValue(guild_member_flags::Mute, other.mute);
101 if (other.permissions.operator std::string_view() != "") {
102 permissionsVal = std::move(other.permissions);
103 }
104 if (other.joinedAt != "") {
105 joinedAt = std::move(other.joinedAt);
106 }
107 if (other.avatar != "") {
108 avatar = std::move(other.avatar);
109 }
110 if (other.roles.size() > 0) {
111 roles = std::move(other.roles);
112 }
113 if (other.nick != "") {
114 nick = std::move(other.nick);
115 }
116 if (other.user.id != 0) {
117 user.id = other.user.id;
118 }
119 if (other.guildId != 0) {
120 guildId = other.guildId;
121 }
122 return *this;
123 };
124
125 guild_member_cache_data::operator guild_member_data() {
126 guild_member_data returnData{};
127 returnData.permissions = permissionsVal.operator jsonifier::string();
128 returnData.pending = getFlagValue(guild_member_flags::Pending);
129 returnData.deaf = getFlagValue(guild_member_flags::Deaf);
130 returnData.mute = getFlagValue(guild_member_flags::Mute);
131 returnData.joinedAt = joinedAt.operator jsonifier::string();
132 returnData.guildId = guildId;
133 returnData.user.id = user.id;
134 returnData.avatar = avatar;
135 returnData.roles = roles;
136 returnData.flags = flags;
137 returnData.nick = nick;
138 return returnData;
139 }
140
141 guild_member_cache_data::guild_member_cache_data(guild_member_data&& other) noexcept {
142 *this = std::move(other);
143 }
144
145 void guild_members::initialize(discord_core_internal::https_client* client, config_manager* configManagerNew) {
146 guild_members::doWeCacheGuildMembersBool = configManagerNew->doWeCacheGuildMembers();
147 guild_members::doWeCacheVoiceStatesBool = configManagerNew->doWeCacheVoiceStates();
148 guild_members::httpsClient = client;
149 }
150
152 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Get_Guild_Member };
153 co_await newThreadAwaitable<guild_member_data>();
154 workload.workloadClass = discord_core_internal::https_workload_class::Get;
155 workload.relativePath = "/guilds/" + dataPackage.guildId + "/members/" + dataPackage.guildMemberId;
156 workload.callStack = "guild_members::getGuildMemberAsync()";
157 guild_member_data data{};
158 data.user.id = dataPackage.guildMemberId;
159 data.guildId = dataPackage.guildId;
160 two_id_key key{ data };
161 if (cache.contains(key)) {
162 data = cache[key];
163 }
164 guild_members::httpsClient->submitWorkloadAndGetResult(std::move(workload), data);
165 if (doWeCacheGuildMembersBool) {
166 insertGuildMember(static_cast<guild_member_cache_data>(data));
167 }
168 co_return data;
169 }
170
173 data.user.id = dataPackage.guildMemberId;
174 data.guildId = dataPackage.guildId;
175 two_id_key key{ data };
176 if (cache.contains(key)) {
177 return cache[key];
178 } else {
179 return getGuildMemberAsync({ .guildMemberId = dataPackage.guildMemberId, .guildId = dataPackage.guildId }).get();
180 }
181 }
182
184 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Get_Guild_Members };
185 co_await newThreadAwaitable<jsonifier::vector<guild_member_data>>();
186 workload.workloadClass = discord_core_internal::https_workload_class::Get;
187 workload.relativePath = "/guilds/" + dataPackage.guildId + "/members";
188 if (dataPackage.after != 0) {
189 workload.relativePath += "?after=" + dataPackage.after;
190 if (dataPackage.limit != 0) {
191 workload.relativePath += "&limit=" + jsonifier::toString(dataPackage.limit);
192 }
193 } else if (dataPackage.limit != 0) {
194 workload.relativePath += "?limit=" + jsonifier::toString(dataPackage.limit);
195 }
196 workload.callStack = "guild_members::listGuildMembersAsync()";
197 jsonifier::vector<guild_member_data> returnData{};
198 guild_members::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
199 co_return returnData;
200 }
201
203 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Get_Search_Guild_Members };
204 co_await newThreadAwaitable<jsonifier::vector<guild_member_data>>();
205 workload.workloadClass = discord_core_internal::https_workload_class::Get;
206 workload.relativePath = "/guilds/" + dataPackage.guildId + "/members/search";
207 if (dataPackage.query != "") {
208 workload.relativePath += "?query=" + dataPackage.query;
209 if (dataPackage.limit != 0) {
210 workload.relativePath += "&limit=" + jsonifier::toString(dataPackage.limit);
211 }
212 } else if (dataPackage.limit != 0) {
213 workload.relativePath += "?limit=" + jsonifier::toString(dataPackage.limit);
214 }
215 workload.callStack = "guild_members::searchGuildMembersAsync()";
216 jsonifier::vector<guild_member_data> returnData{};
217 guild_members::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
218 co_return returnData;
219 }
220
222 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Put_Guild_Member };
223 co_await newThreadAwaitable<guild_member_data>();
224 workload.workloadClass = discord_core_internal::https_workload_class::Put;
225 workload.relativePath = "/guilds/" + dataPackage.guildId + "/members/" + dataPackage.userId;
226 parser.serializeJson<true>(dataPackage, workload.content);
227 workload.callStack = "guild_members::addGuildMemberAsync()";
228 guild_member_data returnData{};
229 guild_members::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
230 co_return returnData;
231 }
232
234 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Patch_Current_Guild_Member };
235 co_await newThreadAwaitable<guild_member_data>();
236 workload.workloadClass = discord_core_internal::https_workload_class::Patch;
237 workload.relativePath = "/guilds/" + dataPackage.guildId + "/members/@me";
238 parser.serializeJson<true>(dataPackage, workload.content);
239 workload.callStack = "guild_members::modifyCurrentGuildMemberAsync()";
240 if (dataPackage.reason != "") {
241 workload.headersToInsert["x-audit-log-reason"] = dataPackage.reason;
242 }
243 guild_member_data returnData{};
244 guild_members::httpsClient->submitWorkloadAndGetResult(std::move(workload), returnData);
245 co_return returnData;
246 }
247
249 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Patch_Guild_Member };
250 co_await newThreadAwaitable<guild_member_data>();
251 workload.workloadClass = discord_core_internal::https_workload_class::Patch;
252 workload.relativePath = "/guilds/" + dataPackage.guildId + "/members/" + dataPackage.guildMemberId;
253 parser.serializeJson<true>(dataPackage, workload.content);
254 workload.callStack = "guild_members::modifyGuildMemberAsync()";
255 if (dataPackage.reason != "") {
256 workload.headersToInsert["x-audit-log-reason"] = dataPackage.reason;
257 }
258 guild_member_data data{};
259 data.user.id = dataPackage.guildMemberId;
260 data.guildId = dataPackage.guildId;
261 two_id_key key{ data };
262 if (cache.contains(key)) {
263 data = cache[key];
264 }
265 guild_members::httpsClient->submitWorkloadAndGetResult(std::move(workload), data);
266 if (doWeCacheGuildMembersBool) {
267 insertGuildMember(static_cast<guild_member_cache_data>(data));
268 }
269 co_return data;
270 }
271
273 discord_core_internal::https_workload_data workload{ discord_core_internal::https_workload_type::Delete_Guild_Member };
274 co_await newThreadAwaitable<void>();
275 workload.workloadClass = discord_core_internal::https_workload_class::Delete;
276 workload.relativePath = "/guilds/" + dataPackage.guildId + "/members/" + dataPackage.guildMemberId;
277 workload.callStack = "guild_members::removeGuildMemberAsync()";
278 if (dataPackage.reason != "") {
279 workload.headersToInsert["x-audit-log-reason"] = dataPackage.reason;
280 }
281 guild_members::httpsClient->submitWorkloadAndGetResult(std::move(workload));
282 co_return;
283 }
284
286 co_await newThreadAwaitable<guild_member_data>();
287 guild_member_data guildMember = guild_members::getCachedGuildMember({ .guildMemberId = dataPackage.guildMemberId, .guildId = dataPackage.guildId });
288 modify_guild_member_data dataPackage01{};
289 dataPackage01.deaf = guildMember.getFlagValue(guild_member_flags::Deaf);
290 dataPackage01.guildId = guildMember.guildId;
291 dataPackage01.guildMemberId = guildMember.user.id;
292 dataPackage01.mute = guildMember.getFlagValue(guild_member_flags::Mute);
293 for (auto& value: guildMember.roles) {
294 dataPackage01.roleIds.emplace_back(value);
295 }
296 dataPackage01.nick = guildMember.nick;
297 dataPackage01.reason = dataPackage.reason;
298 time_stamp timeStamp{};
299 switch (dataPackage.numOfMinutesToTimeoutFor) {
301 auto string = timeStamp.convertToFutureISO8601TimeStamp(0, 0, 1, 0, 0, time_format::long_date_time);
302 dataPackage01.communicationDisabledUntil = string;
303 break;
304 }
306 auto string = timeStamp.convertToFutureISO8601TimeStamp(5, 0, 0, 0, 0, time_format::long_date_time);
307 dataPackage01.communicationDisabledUntil = string;
308 break;
309 }
311 auto string = timeStamp.convertToFutureISO8601TimeStamp(0, 1, 0, 0, 0, time_format::long_date_time);
312 dataPackage01.communicationDisabledUntil = string;
313 break;
314 }
316 auto string = timeStamp.convertToFutureISO8601TimeStamp(10, 0, 0, 0, 0, time_format::long_date_time);
317 dataPackage01.communicationDisabledUntil = string;
318 break;
319 }
321 auto string = timeStamp.convertToFutureISO8601TimeStamp(0, 0, 7, 0, 0, time_format::long_date_time);
322 dataPackage01.communicationDisabledUntil = string;
323 break;
324 }
326 auto string = timeStamp.convertToFutureISO8601TimeStamp(1, 0, 0, 0, 0, time_format::long_date_time);
327 dataPackage01.communicationDisabledUntil = string;
328 break;
329 }
331 auto string = timeStamp.convertToFutureISO8601TimeStamp(0, 0, 0, 0, 0, time_format::long_date_time);
332 dataPackage01.communicationDisabledUntil = string;
333 break;
334 }
335 }
336 guild_members::modifyGuildMemberAsync(dataPackage01).get();
337 co_return guildMember;
338 }
339
341 if (vsCache.contains(key)) {
342 return vsCache[key];
343 } else {
344 return {};
345 }
346 }
347
348 void guild_members::removeGuildMember(const two_id_key& key) {
349 cache.erase(key);
350 };
351
352 void guild_members::removeVoiceState(const two_id_key& key) {
353 vsCache.erase(key);
354 }
355
356 bool guild_members::doWeCacheGuildMembers() {
357 return guild_members::doWeCacheGuildMembersBool;
358 }
359
360 bool guild_members::doWeCacheVoiceStates() {
361 return guild_members::doWeCacheVoiceStatesBool;
362 }
363
364 object_cache<voice_state_data_light> guild_members::vsCache{};
365 object_cache<guild_member_cache_data> guild_members::cache{};
366 discord_core_internal::https_client* guild_members::httpsClient{};
367 bool guild_members::doWeCacheGuildMembersBool{};
368 bool guild_members::doWeCacheVoiceStatesBool{};
369};
A co_routine - representing a potentially asynchronous operation/function.
Definition: CoRoutine.hpp:83
Data structure representing a single guild_member_data.
jsonifier::string nick
Their nick/display name.
icon_hash avatar
This guild_member_data's guild avatar.
time_stamp joinedAt
When they joined the guild.
snowflake guildId
The current guild's id.
user_id_base user
The user id for this guild_member_data.
permissions permissionsVal
Their base-level permissions in the guild.
guild_member_flags flags
Guild_member_data flags.
jsonifier::vector< snowflake > roles
The guild roGuildMemberDatales that they have.
Data structure representing a single guild_member_data.
jsonifier::vector< snowflake > roles
Array of role object ids.
snowflake guildId
The guild that this member belongs to.
user_data user
The user this guild member represents.
jsonifier::string nick
This user's guild nickname.
static co_routine< jsonifier::vector< guild_member_data > > searchGuildMembersAsync(const search_guild_members_data dataPackage)
Searches for a list of guild_members of a chosen guild.
static co_routine< guild_member_data > modifyGuildMemberAsync(const modify_guild_member_data dataPackage)
Modifies a guild_member's properties.
static co_routine< guild_member_data > modifyCurrentGuildMemberAsync(const modify_current_guild_member_data dataPackage)
Modifies the current guild_member_data's properties.
static guild_member_cache_data getCachedGuildMember(const get_guild_member_data dataPackage)
Collects a guild_member from the library's cache.
static co_routine< guild_member_data > getGuildMemberAsync(const get_guild_member_data dataPackage)
Collects a guild_member from the discord servers.
static co_routine< void > removeGuildMemberAsync(const remove_guild_member_data dataPackage)
Removes a chosen guild_member_data from a chosen guild.
static voice_state_data_light getVoiceStateData(const two_id_key &voiceState)
Collect a given guild_member's voice state data.
static co_routine< jsonifier::vector< guild_member_data > > listGuildMembersAsync(const list_guild_members_data dataPackage)
Lists all of the guild_members of a chosen guild.
static co_routine< guild_member_data > addGuildMemberAsync(const add_guild_member_data dataPackage)
Adds a guild_member to a chosen guild.
static co_routine< guild_member_data > timeoutGuildMemberAsync(const timeout_guild_member_data dataPackage)
Times-out a chosen guild_member_data from a chosen guild.
A class that extends time_stamp_base to provide additional functionality.
Definition: Base.hpp:618
snowflake id
The user's id.
@ long_date_time
"Tuesday, 20 April 2021 16:20" - Long Date/Time
The main namespace for the forward-facing interfaces.
For adding a new guild_member_data to a chosen guild.
snowflake userId
The user_data id of the user you wish to add.
snowflake guildId
The guild to add the new guild_member_data to.
For getting a guild_member, from the library's cache or discord server.
snowflake guildMemberId
The user id of the desired guild_member_data.
snowflake guildId
The id of the guild from which you would like to acquire a member.
For listing the guild_members of a chosen guild.
snowflake after
The highest user id in the previous page.
int32_t limit
Max number of members to return (1 - 1000).
snowflake guildId
Guild from which to list the guild_members.
For modifying the current guild_member_data's values.
jsonifier::string reason
A reason for modifying the current user's values.
snowflake guildId
The guild within which to modify the current user's values.
For modifying a guild_member's values.
snowflake guildId
The id of the guild for which you would like to modify a member.
bool deaf
Whether or not to deafen them, in voice.
jsonifier::string reason
Reason for modifying this guild_member_data.
snowflake guildMemberId
The user id of the desired guild memeber.
For removing a guild_member from a chosen guild.
snowflake guildMemberId
snowflake of the chosen guild_member_data to kick.
snowflake guildId
Guild from which to kick the chosen guild_member_data.
jsonifier::string reason
Reason for kicking the guild_member_data.
For searching for one or more guild_members within a chosen guild.
int32_t limit
Max number of members to return (1 - 1000).
snowflake guildId
Guild within which to search for the guild_members.
jsonifier::string query
Query jsonifier::string to match username(s) and nickname(s) against.
jsonifier::string reason
Reason for timing them out.
snowflake guildMemberId
The id of the guild_member_data to be timed-out.
snowflake guildId
The id of the guild from which you would like to acquire a member.
timeout_durations numOfMinutesToTimeoutFor
The number of minutes to time-out the guild_member_data for.