minor refactor
This commit is contained in:
parent
195c5945eb
commit
b8c42bb22c
@ -17,7 +17,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
const zlib = b.dependency("zlib", .{});
|
const zlib = b.dependency("zlib", .{});
|
||||||
|
|
||||||
const dzig = b.addModule("discord.zig", .{
|
const dzig = b.addModule("discord.zig", .{
|
||||||
.root_source_file = b.path("src/discord.zig"),
|
.root_source_file = b.path("src/lib.zig"),
|
||||||
.link_libc = true,
|
.link_libc = true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ pub fn build(b: *std.Build) void {
|
|||||||
|
|
||||||
const lib = b.addStaticLibrary(.{
|
const lib = b.addStaticLibrary(.{
|
||||||
.name = "discord.zig",
|
.name = "discord.zig",
|
||||||
.root_source_file = b.path("src/discord.zig"),
|
.root_source_file = b.path("lib/discord.zig"),
|
||||||
.target = target,
|
.target = target,
|
||||||
.optimize = optimize,
|
.optimize = optimize,
|
||||||
});
|
});
|
||||||
|
22
src/cache.zig → src/cache/cache.zig
vendored
22
src/cache.zig → src/cache/cache.zig
vendored
@ -4,23 +4,23 @@ const std = @import("std");
|
|||||||
/// otherwise, simply do TableTemplate{}
|
/// otherwise, simply do TableTemplate{}
|
||||||
/// this is a template for the cache tables
|
/// this is a template for the cache tables
|
||||||
pub const TableTemplate = struct {
|
pub const TableTemplate = struct {
|
||||||
comptime User: type = @import("./config.zig").StoredUser,
|
comptime User: type = @import("../config.zig").StoredUser,
|
||||||
comptime Guild: type = @import("./config.zig").StoredGuild,
|
comptime Guild: type = @import("../config.zig").StoredGuild,
|
||||||
comptime Channel: type = @import("./config.zig").StoredChannel,
|
comptime Channel: type = @import("../config.zig").StoredChannel,
|
||||||
comptime Emoji: type = @import("./config.zig").StoredEmoji,
|
comptime Emoji: type = @import("../config.zig").StoredEmoji,
|
||||||
comptime Message: type = @import("./config.zig").StoredMessage,
|
comptime Message: type = @import("../config.zig").StoredMessage,
|
||||||
comptime Role: type = @import("./config.zig").StoredRole,
|
comptime Role: type = @import("../config.zig").StoredRole,
|
||||||
comptime Sticker: type = @import("./config.zig").StoredSticker,
|
comptime Sticker: type = @import("../config.zig").StoredSticker,
|
||||||
comptime Reaction: type = @import("./config.zig").StoredReaction,
|
comptime Reaction: type = @import("../config.zig").StoredReaction,
|
||||||
comptime Member: type = @import("./config.zig").StoredMember,
|
comptime Member: type = @import("../config.zig").StoredMember,
|
||||||
comptime Thread: type = @import("./config.zig").StoredChannel,
|
comptime Thread: type = @import("../config.zig").StoredChannel,
|
||||||
};
|
};
|
||||||
|
|
||||||
// by default this caches everything
|
// by default this caches everything
|
||||||
// therefore we'll allow custom cache tables
|
// therefore we'll allow custom cache tables
|
||||||
pub fn CacheTables(comptime Table: TableTemplate) type {
|
pub fn CacheTables(comptime Table: TableTemplate) type {
|
||||||
return struct {
|
return struct {
|
||||||
const Snowflake = @import("./structures/snowflake.zig").Snowflake;
|
const Snowflake = @import("../structures/snowflake.zig").Snowflake;
|
||||||
|
|
||||||
const StoredUser: type = Table.User;
|
const StoredUser: type = Table.User;
|
||||||
const StoredGuild: type = Table.Guild;
|
const StoredGuild: type = Table.Guild;
|
@ -4,6 +4,7 @@ const PremiumTypes = @import("./structures/shared.zig").PremiumTypes;
|
|||||||
const Snowflake = @import("./structures/snowflake.zig").Snowflake;
|
const Snowflake = @import("./structures/snowflake.zig").Snowflake;
|
||||||
const AvatarDecorationData = @import("./structures/user.zig").AvatarDecorationData;
|
const AvatarDecorationData = @import("./structures/user.zig").AvatarDecorationData;
|
||||||
|
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/user#user-object
|
/// https://discord.com/developers/docs/resources/user#user-object
|
||||||
/// modify this to your liking
|
/// modify this to your liking
|
||||||
pub const StoredUser = struct {
|
pub const StoredUser = struct {
|
||||||
|
@ -29,5 +29,5 @@ pub const DiscordError = struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub fn Result(comptime T: type) type {
|
pub fn Result(comptime T: type) type {
|
||||||
return @import("json-helper.zig").OwnedEither(DiscordError, T);
|
return @import("./utils/json.zig").OwnedEither(DiscordError, T);
|
||||||
}
|
}
|
||||||
|
0
src/http/api.zig
Normal file
0
src/http/api.zig
Normal file
@ -18,10 +18,10 @@ const std = @import("std");
|
|||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const http = std.http;
|
const http = std.http;
|
||||||
const json = std.json;
|
const json = std.json;
|
||||||
const json_helpers = @import("json-helper.zig");
|
const json_helpers = @import("../utils/json.zig");
|
||||||
|
|
||||||
pub const Result = @import("errors.zig").Result;
|
pub const Result = @import("../errors.zig").Result;
|
||||||
pub const DiscordError = @import("errors.zig").DiscordError;
|
pub const DiscordError = @import("../errors.zig").DiscordError;
|
||||||
|
|
||||||
pub const BASE_URL = "https://discord.com/api/v10";
|
pub const BASE_URL = "https://discord.com/api/v10";
|
||||||
|
|
@ -67,8 +67,6 @@ pub const PermissionStrings = @import("structures/types.zig").PermissionStrings;
|
|||||||
pub const GatewayCloseEventCodes = @import("structures/types.zig").GatewayCloseEventCodes;
|
pub const GatewayCloseEventCodes = @import("structures/types.zig").GatewayCloseEventCodes;
|
||||||
pub const GatewayOpcodes = @import("structures/types.zig").GatewayOpcodes;
|
pub const GatewayOpcodes = @import("structures/types.zig").GatewayOpcodes;
|
||||||
pub const GatewayDispatchEventNames = @import("structures/types.zig").GatewayDispatchEventNames;
|
pub const GatewayDispatchEventNames = @import("structures/types.zig").GatewayDispatchEventNames;
|
||||||
pub const GatewayIntents = @import("structures/types.zig").GatewayIntents;
|
|
||||||
pub const Intents = @import("structures/types.zig").Intents;
|
|
||||||
pub const InteractionResponseTypes = @import("structures/types.zig").InteractionResponseTypes;
|
pub const InteractionResponseTypes = @import("structures/types.zig").InteractionResponseTypes;
|
||||||
pub const SortOrderTypes = @import("structures/types.zig").SortOrderTypes;
|
pub const SortOrderTypes = @import("structures/types.zig").SortOrderTypes;
|
||||||
pub const ForumLayout = @import("structures/types.zig").ForumLayout;
|
pub const ForumLayout = @import("structures/types.zig").ForumLayout;
|
||||||
@ -307,26 +305,26 @@ pub const ApplicationWebhook = @import("structures/types.zig").ApplicationWebhoo
|
|||||||
pub const GatewayPayload = @import("structures/types.zig").GatewayPayload;
|
pub const GatewayPayload = @import("structures/types.zig").GatewayPayload;
|
||||||
// END USING NAMESPACE
|
// END USING NAMESPACE
|
||||||
|
|
||||||
pub const CacheTables = @import("cache.zig").CacheTables;
|
pub const CacheTables = @import("cache/cache.zig").CacheTables;
|
||||||
pub const CacheLike = @import("cache.zig").CacheLike;
|
pub const CacheLike = @import("cache/cache.zig").CacheLike;
|
||||||
pub const DefaultCache = @import("cache.zig").DefaultCache;
|
pub const DefaultCache = @import("cache/cache.zig").DefaultCache;
|
||||||
|
|
||||||
pub const Permissions = @import("extra/permissions.zig").Permissions;
|
pub const Permissions = @import("utils/permissions.zig").Permissions;
|
||||||
pub const Shard = @import("shard.zig").Shard;
|
pub const Shard = @import("shard/shard.zig").Shard;
|
||||||
pub const zjson = @compileError("Deprecated.");
|
pub const zjson = @compileError("Deprecated.");
|
||||||
|
|
||||||
pub const Internal = @import("internal.zig");
|
pub const Internal = @import("utils/core.zig");
|
||||||
const GatewayDispatchEvent = Internal.GatewayDispatchEvent;
|
const GatewayDispatchEvent = Internal.GatewayDispatchEvent;
|
||||||
const GatewayBotInfo = Internal.GatewayBotInfo;
|
const GatewayBotInfo = @import("shard/util.zig").GatewayBotInfo;
|
||||||
const Log = Internal.Log;
|
const Log = Internal.Log;
|
||||||
|
|
||||||
// sharder
|
// sharder
|
||||||
pub const Sharder = @import("sharder.zig").ShardManager;
|
pub const Sharder = @import("shard/sharder.zig").ShardManager;
|
||||||
|
|
||||||
pub const cache = @import("cache.zig");
|
pub const cache = @import("cache/cache.zig");
|
||||||
|
|
||||||
pub const FetchReq = @import("http.zig").FetchReq;
|
pub const FetchReq = @import("http/http.zig").FetchReq;
|
||||||
pub const FileData = @import("http.zig").FileData;
|
pub const FileData = @import("http/http.zig").FileData;
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
@ -421,6 +419,9 @@ pub fn deinit(self: *Session) void {
|
|||||||
self.deinit();
|
self.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub const GatewayIntents = @import("./shard/intents.zig").GatewayIntents;
|
||||||
|
pub const Intents = @import("./shard/intents.zig").Intents;
|
||||||
|
|
||||||
pub fn start(self: *Session, settings: struct {
|
pub fn start(self: *Session, settings: struct {
|
||||||
token: []const u8,
|
token: []const u8,
|
||||||
intents: Intents,
|
intents: Intents,
|
106
src/shard/bucket.zig
Normal file
106
src/shard/bucket.zig
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const mem = std.mem;
|
||||||
|
const math = std.math;
|
||||||
|
const time = std.time;
|
||||||
|
const atomic = std.atomic;
|
||||||
|
const Thread = std.Thread;
|
||||||
|
const PriorityQueue = std.PriorityQueue;
|
||||||
|
|
||||||
|
pub const Bucket = struct {
|
||||||
|
pub const RequestWithPrio = struct {
|
||||||
|
callback: *const fn () void,
|
||||||
|
priority: u32 = 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
fn lessthan(_: void, a: RequestWithPrio, b: RequestWithPrio) math.Order {
|
||||||
|
return math.order(a.priority, b.priority);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The queue of requests to acquire an available request.
|
||||||
|
/// Mapped by (shardId, RequestWithPrio)
|
||||||
|
queue: PriorityQueue(RequestWithPrio, void, lessthan),
|
||||||
|
|
||||||
|
limit: usize,
|
||||||
|
refill_interval: u64,
|
||||||
|
refill_amount: usize,
|
||||||
|
|
||||||
|
/// The amount of requests that have been used up already.
|
||||||
|
used: usize = 0,
|
||||||
|
|
||||||
|
/// Whether or not the queue is already processing.
|
||||||
|
processing: bool = false,
|
||||||
|
|
||||||
|
/// Whether the timeout should be killed because there is already one running
|
||||||
|
should_stop: atomic.Value(bool) = .init(false),
|
||||||
|
|
||||||
|
/// The timestamp in milliseconds when the next refill is scheduled.
|
||||||
|
refills_at: ?u64 = null,
|
||||||
|
|
||||||
|
pub fn init(allocator: mem.Allocator, limit: usize, refill_interval: u64, refill_amount: usize) Bucket {
|
||||||
|
return .{
|
||||||
|
.queue = PriorityQueue(RequestWithPrio, void, lessthan).init(allocator, {}),
|
||||||
|
.limit = limit,
|
||||||
|
.refill_interval = refill_interval,
|
||||||
|
.refill_amount = refill_amount,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
fn remaining(self: *Bucket) usize {
|
||||||
|
if (self.limit < self.used) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return self.limit - self.used;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn refill(self: *Bucket) Thread.SpawnError!void {
|
||||||
|
// Lower the used amount by the refill amount
|
||||||
|
self.used = if (self.refill_amount > self.used) 0 else self.used - self.refill_amount;
|
||||||
|
|
||||||
|
// Reset the refills_at timestamp since it just got refilled
|
||||||
|
self.refills_at = null;
|
||||||
|
|
||||||
|
if (self.used > 0) {
|
||||||
|
if (self.should_stop.load(.monotonic) == true) {
|
||||||
|
self.should_stop.store(false, .monotonic);
|
||||||
|
}
|
||||||
|
const thread = try Thread.spawn(.{}, Bucket.timeout, .{self});
|
||||||
|
thread.detach;
|
||||||
|
self.refills_at = time.milliTimestamp() + self.refill_interval;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn timeout(self: *Bucket) void {
|
||||||
|
while (!self.should_stop.load(.monotonic)) {
|
||||||
|
self.refill();
|
||||||
|
time.sleep(time.ns_per_ms * self.refill_interval);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn processQueue(self: *Bucket) std.Thread.SpawnError!void {
|
||||||
|
if (self.processing) return;
|
||||||
|
|
||||||
|
while (self.queue.remove()) |first_element| {
|
||||||
|
if (self.remaining() != 0) {
|
||||||
|
first_element.callback();
|
||||||
|
self.used += 1;
|
||||||
|
|
||||||
|
if (!self.should_stop.load(.monotonic)) {
|
||||||
|
const thread = try Thread.spawn(.{}, Bucket.timeout, .{self});
|
||||||
|
thread.detach;
|
||||||
|
self.refills_at = time.milliTimestamp() + self.refill_interval;
|
||||||
|
}
|
||||||
|
} else if (self.refills_at) |ra| {
|
||||||
|
const now = time.milliTimestamp();
|
||||||
|
if (ra > now) time.sleep(time.ns_per_ms * (ra - now));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.processing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn acquire(self: *Bucket, rq: RequestWithPrio) !void {
|
||||||
|
try self.queue.add(rq);
|
||||||
|
try self.processQueue();
|
||||||
|
}
|
||||||
|
};
|
87
src/shard/connect_queue.zig
Normal file
87
src/shard/connect_queue.zig
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const mem = std.mem;
|
||||||
|
|
||||||
|
/// inspired from:
|
||||||
|
/// https://github.com/tiramisulabs/seyfert/blob/main/src/websocket/structures/timeout.ts
|
||||||
|
pub fn ConnectQueue(comptime T: type) type {
|
||||||
|
return struct {
|
||||||
|
pub const RequestWithShard = struct {
|
||||||
|
callback: *const fn (self: *RequestWithShard) anyerror!void,
|
||||||
|
shard: T,
|
||||||
|
};
|
||||||
|
|
||||||
|
// ignore this function
|
||||||
|
// so it becomes a regular dequeue
|
||||||
|
fn eq(_: void, _: RequestWithShard, _: RequestWithShard) std.math.Order {
|
||||||
|
return std.math.Order.eq;
|
||||||
|
}
|
||||||
|
|
||||||
|
dequeue: std.PriorityDequeue(RequestWithShard, void, eq),
|
||||||
|
allocator: mem.Allocator,
|
||||||
|
remaining: usize,
|
||||||
|
interval_time: u64 = 5000,
|
||||||
|
running: bool = false,
|
||||||
|
concurrency: usize = 1,
|
||||||
|
|
||||||
|
pub fn init(allocator: mem.Allocator, concurrency: usize, interval_time: u64) !ConnectQueue(T) {
|
||||||
|
return .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.dequeue = std.PriorityDequeue(RequestWithShard, void, eq).init(allocator, {}),
|
||||||
|
.remaining = concurrency,
|
||||||
|
.interval_time = interval_time,
|
||||||
|
.concurrency = concurrency,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deinit(self: *ConnectQueue(T)) void {
|
||||||
|
self.dequeue.deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn push(self: *ConnectQueue(T), req: RequestWithShard) !void {
|
||||||
|
if (self.remaining == 0) {
|
||||||
|
return self.dequeue.add(req);
|
||||||
|
}
|
||||||
|
self.remaining -= 1;
|
||||||
|
|
||||||
|
if (!self.running) {
|
||||||
|
try self.startInterval();
|
||||||
|
self.running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.dequeue.count() < self.concurrency) {
|
||||||
|
// perhaps store this?
|
||||||
|
const ptr = try self.allocator.create(RequestWithShard);
|
||||||
|
ptr.* = req;
|
||||||
|
try req.callback(ptr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self.dequeue.add(req);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn startInterval(self: *ConnectQueue(T)) !void {
|
||||||
|
while (self.running) {
|
||||||
|
std.Thread.sleep(std.time.ns_per_ms * (self.interval_time / self.concurrency));
|
||||||
|
const req: ?RequestWithShard = self.dequeue.removeMin(); // pop front
|
||||||
|
|
||||||
|
while (self.dequeue.count() == 0 and req == null) {}
|
||||||
|
|
||||||
|
if (req) |r| {
|
||||||
|
const ptr = try self.allocator.create(RequestWithShard);
|
||||||
|
ptr.* = r;
|
||||||
|
try @call(.auto, r.callback, .{ptr});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.remaining < self.concurrency) {
|
||||||
|
self.remaining += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.dequeue.count() == 0) {
|
||||||
|
self.running = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
179
src/shard/intents.zig
Normal file
179
src/shard/intents.zig
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const mem = std.mem;
|
||||||
|
const json = std.json;
|
||||||
|
|
||||||
|
/// https://discord.com/developers/docs/topics/gateway#list-of-intents
|
||||||
|
pub const GatewayIntents = packed struct {
|
||||||
|
pub fn toRaw(self: GatewayIntents) u32 {
|
||||||
|
return @bitCast(self);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn fromRaw(raw: u32) GatewayIntents {
|
||||||
|
return @bitCast(raw);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn jsonParse(allocator: mem.Allocator, src: anytype, _: json.ParseOptions) !@This() {
|
||||||
|
const value = try json.innerParse(json.Value, allocator, src, .{
|
||||||
|
.ignore_unknown_fields = true,
|
||||||
|
.max_value_len = 0x1000,
|
||||||
|
});
|
||||||
|
if (value != .integer) @panic("Invalid value for bitfield");
|
||||||
|
|
||||||
|
return fromRaw(@intCast(value.integer));
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn jsonParseFromValue(_: mem.Allocator, src: json.Value, _: json.ParseOptions) @This() {
|
||||||
|
if (src != .integer) @panic("Invalid value for bitfield");
|
||||||
|
return fromRaw(@intCast(src.integer));
|
||||||
|
}
|
||||||
|
|
||||||
|
///
|
||||||
|
/// - GUILD_CREATE
|
||||||
|
/// - GUILD_UPDATE
|
||||||
|
/// - GUILD_DELETE
|
||||||
|
/// - GUILD_ROLE_CREATE
|
||||||
|
/// - GUILD_ROLE_UPDATE
|
||||||
|
/// - GUILD_ROLE_DELETE
|
||||||
|
/// - CHANNEL_CREATE
|
||||||
|
/// - CHANNEL_UPDATE
|
||||||
|
/// - CHANNEL_DELETE
|
||||||
|
/// - CHANNEL_PINS_UPDATE
|
||||||
|
/// - THREAD_CREATE
|
||||||
|
/// - THREAD_UPDATE
|
||||||
|
/// - THREAD_DELETE
|
||||||
|
/// - THREAD_LIST_SYNC
|
||||||
|
/// - THREAD_MEMBER_UPDATE
|
||||||
|
/// - THREAD_MEMBERS_UPDATE
|
||||||
|
/// - STAGE_INSTANCE_CREATE
|
||||||
|
/// - STAGE_INSTANCE_UPDATE
|
||||||
|
/// - STAGE_INSTANCE_DELETE
|
||||||
|
////
|
||||||
|
Guilds: bool = false,
|
||||||
|
///
|
||||||
|
/// - GUILD_MEMBER_ADD
|
||||||
|
/// - GUILD_MEMBER_UPDATE
|
||||||
|
/// - GUILD_MEMBER_REMOVE
|
||||||
|
/// - THREAD_MEMBERS_UPDATE
|
||||||
|
///
|
||||||
|
/// This is a privileged intent.
|
||||||
|
////
|
||||||
|
GuildMembers: bool = false,
|
||||||
|
///
|
||||||
|
/// - GUILD_AUDIT_LOG_ENTRY_CREATE
|
||||||
|
/// - GUILD_BAN_ADD
|
||||||
|
/// - GUILD_BAN_REMOVE
|
||||||
|
////
|
||||||
|
GuildModeration: bool = false,
|
||||||
|
///
|
||||||
|
/// - GUILD_EMOJIS_UPDATE
|
||||||
|
/// - GUILD_STICKERS_UPDATE
|
||||||
|
////
|
||||||
|
GuildEmojisAndStickers: bool = false,
|
||||||
|
///
|
||||||
|
/// - GUILD_INTEGRATIONS_UPDATE
|
||||||
|
/// - INTEGRATION_CREATE
|
||||||
|
/// - INTEGRATION_UPDATE
|
||||||
|
/// - INTEGRATION_DELETE
|
||||||
|
////
|
||||||
|
GuildIntegrations: bool = false,
|
||||||
|
///
|
||||||
|
/// - WEBHOOKS_UPDATE
|
||||||
|
////
|
||||||
|
GuildWebhooks: bool = false,
|
||||||
|
///
|
||||||
|
/// - INVITE_CREATE
|
||||||
|
/// - INVITE_DELETE
|
||||||
|
////
|
||||||
|
GuildInvites: bool = false,
|
||||||
|
///
|
||||||
|
/// - VOICE_STATE_UPDATE
|
||||||
|
/// - VOICE_CHANNEL_EFFECT_SEND
|
||||||
|
////
|
||||||
|
GuildVoiceStates: bool = false,
|
||||||
|
///
|
||||||
|
/// - PRESENCE_UPDATE
|
||||||
|
///
|
||||||
|
/// This is a privileged intent.
|
||||||
|
////
|
||||||
|
GuildPresences: bool = false,
|
||||||
|
///
|
||||||
|
/// - MESSAGE_CREATE
|
||||||
|
/// - MESSAGE_UPDATE
|
||||||
|
/// - MESSAGE_DELETE
|
||||||
|
/// - MESSAGE_DELETE_BULK
|
||||||
|
///
|
||||||
|
/// The messages do not contain content by default.
|
||||||
|
/// If you want to receive their content too, you need to turn on the privileged `MESSAGE_CONTENT` intent. */
|
||||||
|
GuildMessages: bool = false,
|
||||||
|
///
|
||||||
|
/// - MESSAGE_REACTION_ADD
|
||||||
|
/// - MESSAGE_REACTION_REMOVE
|
||||||
|
/// - MESSAGE_REACTION_REMOVE_ALL
|
||||||
|
/// - MESSAGE_REACTION_REMOVE_EMOJI
|
||||||
|
////
|
||||||
|
GuildMessageReactions: bool = false,
|
||||||
|
///
|
||||||
|
/// - TYPING_START
|
||||||
|
////
|
||||||
|
GuildMessageTyping: bool = false,
|
||||||
|
///
|
||||||
|
/// - CHANNEL_CREATE
|
||||||
|
/// - MESSAGE_CREATE
|
||||||
|
/// - MESSAGE_UPDATE
|
||||||
|
/// - MESSAGE_DELETE
|
||||||
|
/// - CHANNEL_PINS_UPDATE
|
||||||
|
////
|
||||||
|
DirectMessages: bool = false,
|
||||||
|
///
|
||||||
|
/// - MESSAGE_REACTION_ADD
|
||||||
|
/// - MESSAGE_REACTION_REMOVE
|
||||||
|
/// - MESSAGE_REACTION_REMOVE_ALL
|
||||||
|
/// - MESSAGE_REACTION_REMOVE_EMOJI
|
||||||
|
////
|
||||||
|
DirectMessageReactions: bool = false,
|
||||||
|
///
|
||||||
|
/// - TYPING_START
|
||||||
|
////
|
||||||
|
DirectMessageTyping: bool = false,
|
||||||
|
///
|
||||||
|
/// This intent will add all content related values to message events.
|
||||||
|
///
|
||||||
|
/// This is a privileged intent.
|
||||||
|
////
|
||||||
|
MessageContent: bool = false,
|
||||||
|
///
|
||||||
|
/// - GUILD_SCHEDULED_EVENT_CREATE
|
||||||
|
/// - GUILD_SCHEDULED_EVENT_UPDATE
|
||||||
|
/// - GUILD_SCHEDULED_EVENT_DELETE
|
||||||
|
/// - GUILD_SCHEDULED_EVENT_USER_ADD this is experimental and unstable.
|
||||||
|
/// - GUILD_SCHEDULED_EVENT_USER_REMOVE this is experimental and unstable.
|
||||||
|
////
|
||||||
|
GuildScheduledEvents: bool = false,
|
||||||
|
_pad: u4 = 0,
|
||||||
|
///
|
||||||
|
/// - AUTO_MODERATION_RULE_CREATE
|
||||||
|
/// - AUTO_MODERATION_RULE_UPDATE
|
||||||
|
/// - AUTO_MODERATION_RULE_DELETE
|
||||||
|
////
|
||||||
|
AutoModerationConfiguration: bool = false,
|
||||||
|
///
|
||||||
|
/// - AUTO_MODERATION_ACTION_EXECUTION
|
||||||
|
////
|
||||||
|
AutoModerationExecution: bool = false,
|
||||||
|
_pad2: u3 = 0,
|
||||||
|
///
|
||||||
|
/// - MESSAGE_POLL_VOTE_ADD
|
||||||
|
/// - MESSAGE_POLL_VOTE_REMOVE
|
||||||
|
////
|
||||||
|
GuildMessagePolls: bool = false,
|
||||||
|
///
|
||||||
|
/// - MESSAGE_POLL_VOTE_ADD
|
||||||
|
/// - MESSAGE_POLL_VOTE_REMOVE
|
||||||
|
////
|
||||||
|
DirectMessagePolls: bool = false,
|
||||||
|
_pad3: u4 = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// https://discord.com/developers/docs/topics/gateway#list-of-intents
|
||||||
|
/// alias
|
||||||
|
pub const Intents = GatewayIntents;
|
@ -28,29 +28,31 @@ const http = std.http;
|
|||||||
const zlib = @import("zlib");
|
const zlib = @import("zlib");
|
||||||
const json = @import("std").json;
|
const json = @import("std").json;
|
||||||
|
|
||||||
const Result = @import("errors.zig").Result;
|
const Result = @import("../errors.zig").Result;
|
||||||
|
|
||||||
const IdentifyProperties = @import("internal.zig").IdentifyProperties;
|
const IdentifyProperties = @import("util.zig").IdentifyProperties;
|
||||||
const GatewayInfo = @import("internal.zig").GatewayInfo;
|
const GatewayInfo = @import("util.zig").GatewayInfo;
|
||||||
const GatewayBotInfo = @import("internal.zig").GatewayBotInfo;
|
const GatewayBotInfo = @import("util.zig").GatewayBotInfo;
|
||||||
const GatewaySessionStartLimit = @import("internal.zig").GatewaySessionStartLimit;
|
const GatewaySessionStartLimit = @import("util.zig").GatewaySessionStartLimit;
|
||||||
const ShardDetails = @import("internal.zig").ShardDetails;
|
const ShardDetails = @import("util.zig").ShardDetails;
|
||||||
const internalLogif = @import("internal.zig").logif;
|
const internalLogif = @import("../utils/core.zig").logif;
|
||||||
|
|
||||||
const Log = @import("internal.zig").Log;
|
const Log = @import("../utils/core.zig").Log;
|
||||||
const GatewayDispatchEvent = @import("internal.zig").GatewayDispatchEvent;
|
const GatewayDispatchEvent = @import("../utils/core.zig").GatewayDispatchEvent;
|
||||||
const Bucket = @import("internal.zig").Bucket;
|
const Bucket = @import("bucket.zig").Bucket;
|
||||||
const default_identify_properties = @import("internal.zig").default_identify_properties;
|
const default_identify_properties = @import("util.zig").default_identify_properties;
|
||||||
|
|
||||||
const Types = @import("./structures/types.zig");
|
const Types = @import("../structures/types.zig");
|
||||||
const Opcode = Types.GatewayOpcodes;
|
const Opcode = Types.GatewayOpcodes;
|
||||||
const Intents = Types.Intents;
|
const Intents = @import("intents.zig").Intents;
|
||||||
|
|
||||||
const Snowflake = Types.Snowflake;
|
const Snowflake = Types.Snowflake;
|
||||||
const FetchReq = @import("http.zig").FetchReq;
|
const FetchReq = @import("../http/http.zig").FetchReq;
|
||||||
const MakeRequestError = @import("http.zig").MakeRequestError;
|
const MakeRequestError = @import("../http/http.zig").MakeRequestError;
|
||||||
const Partial = Types.Partial;
|
const Partial = Types.Partial;
|
||||||
const TableTemplate = @import("cache.zig").TableTemplate;
|
const TableTemplate = @import("../cache/cache.zig").TableTemplate;
|
||||||
|
const CacheTables = @import("../cache/cache.zig").CacheTables;
|
||||||
|
const FileData = @import("../http/http.zig").FileData;
|
||||||
|
|
||||||
pub fn Shard(comptime Table: TableTemplate) type {
|
pub fn Shard(comptime Table: TableTemplate) type {
|
||||||
return struct {
|
return struct {
|
||||||
@ -106,7 +108,7 @@ pub fn Shard(comptime Table: TableTemplate) type {
|
|||||||
log: Log = .no,
|
log: Log = .no,
|
||||||
|
|
||||||
/// actual cache
|
/// actual cache
|
||||||
cache_handler: *@import("cache.zig").CacheTables(Table),
|
cache_handler: *CacheTables(Table),
|
||||||
|
|
||||||
pub fn resumable(self: *Self) bool {
|
pub fn resumable(self: *Self) bool {
|
||||||
return self.resume_gateway_url != null and
|
return self.resume_gateway_url != null and
|
||||||
@ -160,7 +162,7 @@ pub fn Shard(comptime Table: TableTemplate) type {
|
|||||||
options: ShardOptions,
|
options: ShardOptions,
|
||||||
run: GatewayDispatchEvent,
|
run: GatewayDispatchEvent,
|
||||||
log: Log,
|
log: Log,
|
||||||
cache: *@import("cache.zig").CacheTables(Table),
|
cache: *CacheTables(Table),
|
||||||
sharder_pool: ?*std.Thread.Pool = null,
|
sharder_pool: ?*std.Thread.Pool = null,
|
||||||
}) zlib.Error!Self {
|
}) zlib.Error!Self {
|
||||||
return Self{
|
return Self{
|
||||||
@ -933,7 +935,7 @@ pub fn Shard(comptime Table: TableTemplate) type {
|
|||||||
/// the create message payload
|
/// the create message payload
|
||||||
create_message: Partial(Types.CreateMessage),
|
create_message: Partial(Types.CreateMessage),
|
||||||
/// the files to send, must be one of FileData.type
|
/// the files to send, must be one of FileData.type
|
||||||
files: []@import("http.zig").FileData,
|
files: []FileData,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// same as `sendMessage` but acceps a files field
|
/// same as `sendMessage` but acceps a files field
|
||||||
@ -1448,7 +1450,7 @@ pub fn Shard(comptime Table: TableTemplate) type {
|
|||||||
|
|
||||||
pub const StartThreadInForumOrMediaChannelWithFiles = struct {
|
pub const StartThreadInForumOrMediaChannelWithFiles = struct {
|
||||||
start_thread: Types.StartThreadFromMessage,
|
start_thread: Types.StartThreadFromMessage,
|
||||||
files: []@import("http.zig").FileData,
|
files: []FileData,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// same as `startThreadInForumOrMediaChannel`
|
/// same as `startThreadInForumOrMediaChannel`
|
||||||
@ -2862,7 +2864,7 @@ pub fn Shard(comptime Table: TableTemplate) type {
|
|||||||
self: *Self,
|
self: *Self,
|
||||||
guild_id: Snowflake,
|
guild_id: Snowflake,
|
||||||
sticker: Types.CreateModifyGuildSticker,
|
sticker: Types.CreateModifyGuildSticker,
|
||||||
file: @import("http.zig").FileData,
|
file: FileData,
|
||||||
) RequestFailedError!Result(Types.Sticker) {
|
) RequestFailedError!Result(Types.Sticker) {
|
||||||
var buf: [256]u8 = undefined;
|
var buf: [256]u8 = undefined;
|
||||||
const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/stickers", .{guild_id.into()});
|
const path = try std.fmt.bufPrint(&buf, "/guilds/{d}/stickers", .{guild_id.into()});
|
@ -14,20 +14,21 @@
|
|||||||
//! OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
//! OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
//! PERFORMANCE OF THIS SOFTWARE.
|
//! PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
const Intents = @import("./structures/types.zig").Intents;
|
const Intents = @import("intents.zig").Intents;
|
||||||
const Snowflake = @import("./structures/snowflake.zig").Snowflake;
|
const Snowflake = @import("../structures/snowflake.zig").Snowflake;
|
||||||
const GatewayBotInfo = @import("internal.zig").GatewayBotInfo;
|
const GatewayBotInfo = @import("util.zig").GatewayBotInfo;
|
||||||
const IdentifyProperties = @import("internal.zig").IdentifyProperties;
|
const IdentifyProperties = @import("util.zig").IdentifyProperties;
|
||||||
const internalLogif = @import("internal.zig").logif;
|
const internalLogif = @import("../utils/core.zig").logif;
|
||||||
const ShardDetails = @import("internal.zig").ShardDetails;
|
const ShardDetails = @import("util.zig").ShardDetails;
|
||||||
const ConnectQueue = @import("internal.zig").ConnectQueue;
|
const ConnectQueue = @import("connect_queue.zig").ConnectQueue;
|
||||||
const GatewayDispatchEvent = @import("internal.zig").GatewayDispatchEvent;
|
const GatewayDispatchEvent = @import("../utils/core.zig").GatewayDispatchEvent;
|
||||||
const Log = @import("internal.zig").Log;
|
const Log = @import("../utils/core.zig").Log;
|
||||||
const Shard = @import("shard.zig").Shard;
|
const Shard = @import("shard.zig").Shard;
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const debug = @import("internal.zig").debug;
|
const debug = @import("../utils/core.zig").debug;
|
||||||
const TableTemplate = @import("cache.zig").TableTemplate;
|
const TableTemplate = @import("../cache/cache.zig").TableTemplate;
|
||||||
|
const CacheTables = @import("../cache/cache.zig").CacheTables;
|
||||||
|
|
||||||
pub fn ShardManager(comptime Table: TableTemplate) type {
|
pub fn ShardManager(comptime Table: TableTemplate) type {
|
||||||
return struct {
|
return struct {
|
||||||
@ -50,7 +51,7 @@ pub fn ShardManager(comptime Table: TableTemplate) type {
|
|||||||
log: Log,
|
log: Log,
|
||||||
|
|
||||||
// must be initialised
|
// must be initialised
|
||||||
cache: *@import("cache.zig").CacheTables(Table),
|
cache: *CacheTables(Table),
|
||||||
|
|
||||||
pub const ShardData = struct {
|
pub const ShardData = struct {
|
||||||
/// resume seq to resume connections
|
/// resume seq to resume connections
|
||||||
@ -87,11 +88,11 @@ pub fn ShardManager(comptime Table: TableTemplate) type {
|
|||||||
options: SessionOptions,
|
options: SessionOptions,
|
||||||
run: GatewayDispatchEvent,
|
run: GatewayDispatchEvent,
|
||||||
log: Log,
|
log: Log,
|
||||||
cache: @import("cache.zig").TableTemplate,
|
cache: TableTemplate,
|
||||||
}) mem.Allocator.Error!Self {
|
}) mem.Allocator.Error!Self {
|
||||||
const concurrency = settings.options.info.session_start_limit.?.max_concurrency;
|
const concurrency = settings.options.info.session_start_limit.?.max_concurrency;
|
||||||
const cache = try allocator.create(@import("cache.zig").CacheTables(Table));
|
const cache = try allocator.create(CacheTables(Table));
|
||||||
cache.* = @import("cache.zig").CacheTables(Table).defaults(allocator);
|
cache.* = CacheTables(Table).defaults(allocator);
|
||||||
|
|
||||||
return .{
|
return .{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
59
src/shard/util.zig
Normal file
59
src/shard/util.zig
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
pub const IdentifyProperties = struct {
|
||||||
|
/// Operating system the shard runs on.
|
||||||
|
os: []const u8,
|
||||||
|
/// The "browser" where this shard is running on.
|
||||||
|
browser: []const u8,
|
||||||
|
/// The device on which the shard is running.
|
||||||
|
device: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const default_identify_properties = IdentifyProperties{
|
||||||
|
.os = @tagName(@import("builtin").os.tag),
|
||||||
|
.browser = "discord.zig",
|
||||||
|
.device = "discord.zig",
|
||||||
|
};
|
||||||
|
|
||||||
|
/// https://discord.com/developers/docs/topics/gateway#get-gateway
|
||||||
|
pub const GatewayInfo = struct {
|
||||||
|
/// The WSS URL that can be used for connecting to the gateway
|
||||||
|
url: []const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// https://discord.com/developers/docs/events/gateway#session-start-limit-object
|
||||||
|
pub const GatewaySessionStartLimit = struct {
|
||||||
|
/// Total number of session starts the current user is allowed
|
||||||
|
total: u32,
|
||||||
|
/// Remaining number of session starts the current user is allowed
|
||||||
|
remaining: u32,
|
||||||
|
/// Number of milliseconds after which the limit resets
|
||||||
|
reset_after: u32,
|
||||||
|
/// Number of identify requests allowed per 5 seconds
|
||||||
|
max_concurrency: u32,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// https://discord.com/developers/docs/topics/gateway#get-gateway-bot
|
||||||
|
pub const GatewayBotInfo = struct {
|
||||||
|
url: []const u8,
|
||||||
|
/// The recommended number of shards to use when connecting
|
||||||
|
///
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway#sharding
|
||||||
|
shards: u32,
|
||||||
|
/// Information on the current session start limit
|
||||||
|
///
|
||||||
|
/// See https://discord.com/developers/docs/topics/gateway#session-start-limit-object
|
||||||
|
session_start_limit: ?GatewaySessionStartLimit,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ShardDetails = struct {
|
||||||
|
/// Bot token which is used to connect to Discord */
|
||||||
|
token: []const u8,
|
||||||
|
/// The URL of the gateway which should be connected to.
|
||||||
|
url: []const u8 = "wss://gateway.discord.gg",
|
||||||
|
/// The gateway version which should be used.
|
||||||
|
version: ?usize = 10,
|
||||||
|
/// The calculated intent value of the events which the shard should receive.
|
||||||
|
intents: @import("./intents.zig").Intents,
|
||||||
|
/// Identify properties to use
|
||||||
|
properties: IdentifyProperties = default_identify_properties,
|
||||||
|
};
|
||||||
|
|
@ -21,7 +21,7 @@ const Partial = @import("partial.zig").Partial;
|
|||||||
const User = @import("user.zig").User;
|
const User = @import("user.zig").User;
|
||||||
const Team = @import("team.zig").Team;
|
const Team = @import("team.zig").Team;
|
||||||
const Guild = @import("guild.zig").Guild;
|
const Guild = @import("guild.zig").Guild;
|
||||||
const AssociativeArray = @import("../json-helper.zig").AssociativeArray;
|
const AssociativeArray = @import("../utils/json.zig").AssociativeArray;
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/application#application-object
|
/// https://discord.com/developers/docs/resources/application#application-object
|
||||||
pub const Application = struct {
|
pub const Application = struct {
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
const InteractionResponseTypes = @import("shared.zig").InteractionResponseTypes;
|
const InteractionResponseTypes = @import("shared.zig").InteractionResponseTypes;
|
||||||
const InteractionContextType = @import("command.zig").InteractionContextType;
|
const InteractionContextType = @import("command.zig").InteractionContextType;
|
||||||
const Entitlement = @import("monetization.zig").Entitlement;
|
const Entitlement = @import("monetization.zig").Entitlement;
|
||||||
const Record = @import("../json-helper.zig").Record;
|
const Record = @import("../utils/json.zig").Record;
|
||||||
|
|
||||||
pub const Interaction = struct {
|
pub const Interaction = struct {
|
||||||
/// Id of the interaction
|
/// Id of the interaction
|
||||||
|
@ -15,12 +15,13 @@
|
|||||||
//! PERFORMANCE OF THIS SOFTWARE.
|
//! PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const builtin = std.builtin;
|
||||||
|
|
||||||
pub fn Partial(comptime T: type) type {
|
pub fn Partial(comptime T: type) type {
|
||||||
const info = @typeInfo(T);
|
const info = @typeInfo(T);
|
||||||
switch (info) {
|
switch (info) {
|
||||||
.@"struct" => |s| {
|
.@"struct" => |s| {
|
||||||
comptime var fields: []const std.builtin.Type.StructField = &[_]std.builtin.Type.StructField{};
|
comptime var fields: []const builtin.Type.StructField = &[_]builtin.Type.StructField{};
|
||||||
inline for (s.fields) |field| {
|
inline for (s.fields) |field| {
|
||||||
if (field.is_comptime) {
|
if (field.is_comptime) {
|
||||||
@compileError("Cannot make Partial of " ++ @typeName(T) ++ ", it has a comptime field " ++ field.name);
|
@compileError("Cannot make Partial of " ++ @typeName(T) ++ ", it has a comptime field " ++ field.name);
|
||||||
@ -31,7 +32,7 @@ pub fn Partial(comptime T: type) type {
|
|||||||
};
|
};
|
||||||
const default_value: optional_type = null;
|
const default_value: optional_type = null;
|
||||||
const aligned_ptr: *align(field.alignment) const anyopaque = @alignCast(@ptrCast(&default_value));
|
const aligned_ptr: *align(field.alignment) const anyopaque = @alignCast(@ptrCast(&default_value));
|
||||||
const optional_field: [1]std.builtin.Type.StructField = [_]std.builtin.Type.StructField{.{
|
const optional_field: [1]builtin.Type.StructField = [_]builtin.Type.StructField{.{
|
||||||
.alignment = field.alignment,
|
.alignment = field.alignment,
|
||||||
.default_value_ptr = aligned_ptr,
|
.default_value_ptr = aligned_ptr,
|
||||||
.is_comptime = false,
|
.is_comptime = false,
|
||||||
@ -40,9 +41,9 @@ pub fn Partial(comptime T: type) type {
|
|||||||
}};
|
}};
|
||||||
fields = fields ++ optional_field;
|
fields = fields ++ optional_field;
|
||||||
}
|
}
|
||||||
const partial_type_info: std.builtin.Type = .{ .@"struct" = .{
|
const partial_type_info: builtin.Type = .{ .@"struct" = .{
|
||||||
.backing_integer = s.backing_integer,
|
.backing_integer = s.backing_integer,
|
||||||
.decls = &[_]std.builtin.Type.Declaration{},
|
.decls = &[_]builtin.Type.Declaration{},
|
||||||
.fields = fields,
|
.fields = fields,
|
||||||
.is_tuple = s.is_tuple,
|
.is_tuple = s.is_tuple,
|
||||||
.layout = s.layout,
|
.layout = s.layout,
|
||||||
|
@ -665,18 +665,18 @@ pub const GuildFeatures = enum {
|
|||||||
RAID_ALERTS_DISABLED,
|
RAID_ALERTS_DISABLED,
|
||||||
/// Guild is using the old permissions configuration behavior
|
/// Guild is using the old permissions configuration behavior
|
||||||
APPLICATION_COMMAND_PERMISSIONS_V2,
|
APPLICATION_COMMAND_PERMISSIONS_V2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/guild#guild-object-mfa-level
|
/// https://discord.com/developers/docs/resources/guild#guild-object-mfa-level
|
||||||
pub const MfaLevels = enum {
|
pub const MfaLevels = enum {
|
||||||
/// Guild has no MFA/2FA requirement for moderation actions
|
/// Guild has no MFA/2FA requirement for moderation actions
|
||||||
None,
|
None,
|
||||||
/// Guild has a 2FA requirement for moderation actions
|
/// Guild has a 2FA requirement for moderation actions
|
||||||
Elevated,
|
Elevated,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags
|
/// https://discord.com/developers/docs/resources/guild#guild-object-system-channel-flags
|
||||||
pub const SystemChannelFlags = packed struct {
|
pub const SystemChannelFlags = packed struct {
|
||||||
pub fn toRaw(self: SystemChannelFlags) u8 {
|
pub fn toRaw(self: SystemChannelFlags) u8 {
|
||||||
return @bitCast(self);
|
return @bitCast(self);
|
||||||
}
|
}
|
||||||
@ -710,10 +710,10 @@ pub const GuildFeatures = enum {
|
|||||||
/// Hide member join sticker reply buttons
|
/// Hide member join sticker reply buttons
|
||||||
SuppressJoinNotificationReplies: bool = false,
|
SuppressJoinNotificationReplies: bool = false,
|
||||||
_pad: u4 = 0,
|
_pad: u4 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/guild#guild-object-premium-tier
|
/// https://discord.com/developers/docs/resources/guild#guild-object-premium-tier
|
||||||
pub const PremiumTiers = enum {
|
pub const PremiumTiers = enum {
|
||||||
/// Guild has not unlocked any Server Boost perks
|
/// Guild has not unlocked any Server Boost perks
|
||||||
None,
|
None,
|
||||||
/// Guild has unlocked Server Boost level 1 perks
|
/// Guild has unlocked Server Boost level 1 perks
|
||||||
@ -722,18 +722,18 @@ pub const GuildFeatures = enum {
|
|||||||
Tier2,
|
Tier2,
|
||||||
/// Guild has unlocked Server Boost level 3 perks
|
/// Guild has unlocked Server Boost level 3 perks
|
||||||
Tier3,
|
Tier3,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/guild#guild-object-guild-nsfw-level
|
/// https://discord.com/developers/docs/resources/guild#guild-object-guild-nsfw-level
|
||||||
pub const GuildNsfwLevel = enum {
|
pub const GuildNsfwLevel = enum {
|
||||||
Default,
|
Default,
|
||||||
Explicit,
|
Explicit,
|
||||||
Safe,
|
Safe,
|
||||||
AgeRestricted,
|
AgeRestricted,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/channel#channel-object-channel-types
|
/// https://discord.com/developers/docs/resources/channel#channel-object-channel-types
|
||||||
pub const ChannelTypes = packed struct {
|
pub const ChannelTypes = packed struct {
|
||||||
pub fn toRaw(self: ChannelTypes) u32 {
|
pub fn toRaw(self: ChannelTypes) u32 {
|
||||||
return @bitCast(self);
|
return @bitCast(self);
|
||||||
}
|
}
|
||||||
@ -786,32 +786,32 @@ pub const GuildFeatures = enum {
|
|||||||
/// Channel that can only contain threads, similar to GUILD_FORUM channels
|
/// Channel that can only contain threads, similar to GUILD_FORUM channels
|
||||||
GuildMedia: bool = false,
|
GuildMedia: bool = false,
|
||||||
_pad1: u15 = 0,
|
_pad1: u15 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const OverwriteTypes = enum {
|
pub const OverwriteTypes = enum {
|
||||||
Role,
|
Role,
|
||||||
Member,
|
Member,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const VideoQualityModes = enum(u4) {
|
pub const VideoQualityModes = enum(u4) {
|
||||||
/// Discord chooses the quality for optimal performance
|
/// Discord chooses the quality for optimal performance
|
||||||
Auto = 1,
|
Auto = 1,
|
||||||
/// 720p
|
/// 720p
|
||||||
Full,
|
Full,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/topics/gateway-events#activity-object-activity-types
|
/// https://discord.com/developers/docs/topics/gateway-events#activity-object-activity-types
|
||||||
pub const ActivityTypes = enum(u4) {
|
pub const ActivityTypes = enum(u4) {
|
||||||
Playing = 0,
|
Playing = 0,
|
||||||
Streaming = 1,
|
Streaming = 1,
|
||||||
Listening = 2,
|
Listening = 2,
|
||||||
Watching = 3,
|
Watching = 3,
|
||||||
Custom = 4,
|
Custom = 4,
|
||||||
Competing = 5,
|
Competing = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/channel#message-object-message-types
|
/// https://discord.com/developers/docs/resources/channel#message-object-message-types
|
||||||
pub const MessageTypes = enum(u8) {
|
pub const MessageTypes = enum(u8) {
|
||||||
Default,
|
Default,
|
||||||
RecipientAdd,
|
RecipientAdd,
|
||||||
RecipientRemove,
|
RecipientRemove,
|
||||||
@ -849,43 +849,43 @@ pub const GuildFeatures = enum {
|
|||||||
GuildIncidentReportFalseAlarm,
|
GuildIncidentReportFalseAlarm,
|
||||||
PurchaseNotification = 44,
|
PurchaseNotification = 44,
|
||||||
PollResult = 46,
|
PollResult = 46,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/channel#message-object-message-activity-types
|
/// https://discord.com/developers/docs/resources/channel#message-object-message-activity-types
|
||||||
pub const MessageActivityTypes = enum(u4) {
|
pub const MessageActivityTypes = enum(u4) {
|
||||||
Join = 1,
|
Join = 1,
|
||||||
Spectate = 2,
|
Spectate = 2,
|
||||||
Listen = 3,
|
Listen = 3,
|
||||||
JoinRequest = 5,
|
JoinRequest = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-types
|
/// https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-types
|
||||||
pub const StickerTypes = enum(u4) {
|
pub const StickerTypes = enum(u4) {
|
||||||
/// an official sticker in a pack
|
/// an official sticker in a pack
|
||||||
Standard = 1,
|
Standard = 1,
|
||||||
/// a sticker uploaded to a guild for the guild's members
|
/// a sticker uploaded to a guild for the guild's members
|
||||||
Guild = 2,
|
Guild = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types
|
/// https://discord.com/developers/docs/resources/sticker#sticker-object-sticker-format-types
|
||||||
pub const StickerFormatTypes = enum(u4) {
|
pub const StickerFormatTypes = enum(u4) {
|
||||||
Png = 1,
|
Png = 1,
|
||||||
APng,
|
APng,
|
||||||
Lottie,
|
Lottie,
|
||||||
Gif,
|
Gif,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/interactions/slash-commands#interaction-interactiontype
|
/// https://discord.com/developers/docs/interactions/slash-commands#interaction-interactiontype
|
||||||
pub const InteractionTypes = enum(u4) {
|
pub const InteractionTypes = enum(u4) {
|
||||||
Ping = 1,
|
Ping = 1,
|
||||||
ApplicationCommand = 2,
|
ApplicationCommand = 2,
|
||||||
MessageComponent = 3,
|
MessageComponent = 3,
|
||||||
ApplicationCommandAutocomplete = 4,
|
ApplicationCommandAutocomplete = 4,
|
||||||
ModalSubmit = 5,
|
ModalSubmit = 5,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptiontype
|
/// https://discord.com/developers/docs/interactions/slash-commands#applicationcommandoptiontype
|
||||||
pub const ApplicationCommandOptionTypes = enum(u4) {
|
pub const ApplicationCommandOptionTypes = enum(u4) {
|
||||||
SubCommand = 1,
|
SubCommand = 1,
|
||||||
SubCommandGroup,
|
SubCommandGroup,
|
||||||
String,
|
String,
|
||||||
@ -897,10 +897,10 @@ pub const GuildFeatures = enum {
|
|||||||
Mentionable,
|
Mentionable,
|
||||||
Number,
|
Number,
|
||||||
Attachment,
|
Attachment,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events
|
/// https://discord.com/developers/docs/resources/audit-log#audit-log-entry-object-audit-log-events
|
||||||
pub const AuditLogEvents = enum(u4) {
|
pub const AuditLogEvents = enum(u4) {
|
||||||
/// Server settings were updated
|
/// Server settings were updated
|
||||||
GuildUpdate = 1,
|
GuildUpdate = 1,
|
||||||
/// Channel was created
|
/// Channel was created
|
||||||
@ -1027,33 +1027,33 @@ pub const GuildFeatures = enum {
|
|||||||
HomeSettingsCreate = 190,
|
HomeSettingsCreate = 190,
|
||||||
/// Guild Server Guide was updated
|
/// Guild Server Guide was updated
|
||||||
HomeSettingsUpdate,
|
HomeSettingsUpdate,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ScheduledEventPrivacyLevel = enum(u4) {
|
pub const ScheduledEventPrivacyLevel = enum(u4) {
|
||||||
/// the scheduled event is only accessible to guild members
|
/// the scheduled event is only accessible to guild members
|
||||||
GuildOnly = 2,
|
GuildOnly = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ScheduledEventEntityType = enum(u4) {
|
pub const ScheduledEventEntityType = enum(u4) {
|
||||||
StageInstance = 1,
|
StageInstance = 1,
|
||||||
Voice,
|
Voice,
|
||||||
External,
|
External,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ScheduledEventStatus = enum(u4) {
|
pub const ScheduledEventStatus = enum(u4) {
|
||||||
Scheduled = 1,
|
Scheduled = 1,
|
||||||
Active,
|
Active,
|
||||||
Completed,
|
Completed,
|
||||||
Canceled,
|
Canceled,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/invite#invite-object-target-user-types
|
/// https://discord.com/developers/docs/resources/invite#invite-object-target-user-types
|
||||||
pub const TargetTypes = enum(u4) {
|
pub const TargetTypes = enum(u4) {
|
||||||
Stream = 1,
|
Stream = 1,
|
||||||
EmbeddedApplication,
|
EmbeddedApplication,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ApplicationCommandTypes = enum(u4) {
|
pub const ApplicationCommandTypes = enum(u4) {
|
||||||
/// A text-based command that shows up when a user types `/`
|
/// A text-based command that shows up when a user types `/`
|
||||||
ChatInput = 1,
|
ChatInput = 1,
|
||||||
/// A UI-based command that shows up when you right click or tap on a user
|
/// A UI-based command that shows up when you right click or tap on a user
|
||||||
@ -1062,17 +1062,17 @@ pub const GuildFeatures = enum {
|
|||||||
Message,
|
Message,
|
||||||
/// A UI-based command that represents the primary way to invoke an app's Activity
|
/// A UI-based command that represents the primary way to invoke an app's Activity
|
||||||
PrimaryEntryPoint,
|
PrimaryEntryPoint,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ApplicationCommandPermissionTypes = enum(u4) {
|
pub const ApplicationCommandPermissionTypes = enum(u4) {
|
||||||
Role = 1,
|
Role = 1,
|
||||||
User,
|
User,
|
||||||
Channel,
|
Channel,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags
|
/// https://discord.com/developers/docs/topics/permissions#permissions-bitwise-permission-flags
|
||||||
/// Permissions v2
|
/// Permissions v2
|
||||||
pub const BitwisePermissionFlags = packed struct {
|
pub const BitwisePermissionFlags = packed struct {
|
||||||
pub fn toRaw(self: BitwisePermissionFlags) u64 {
|
pub fn toRaw(self: BitwisePermissionFlags) u64 {
|
||||||
return @bitCast(self);
|
return @bitCast(self);
|
||||||
}
|
}
|
||||||
@ -1196,9 +1196,9 @@ pub const GuildFeatures = enum {
|
|||||||
/// Allows user-installed apps to send public responses. When disabled, users will still be allowed to use their apps but the responses will be ephemeral. This only applies to apps not also installed to the server.
|
/// Allows user-installed apps to send public responses. When disabled, users will still be allowed to use their apps but the responses will be ephemeral. This only applies to apps not also installed to the server.
|
||||||
USE_EXTERNAL_APPS: bool = false,
|
USE_EXTERNAL_APPS: bool = false,
|
||||||
_pad: u15 = 0,
|
_pad: u15 = 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const PermissionStrings = union(enum) {
|
pub const PermissionStrings = union(enum) {
|
||||||
/// Allows creation of instant invites
|
/// Allows creation of instant invites
|
||||||
CREATE_INSTANT_INVITE,
|
CREATE_INSTANT_INVITE,
|
||||||
/// Allows kicking members
|
/// Allows kicking members
|
||||||
@ -1297,10 +1297,10 @@ pub const GuildFeatures = enum {
|
|||||||
SEND_POLLS,
|
SEND_POLLS,
|
||||||
/// Allows user-installed apps to send public responses. When disabled, users will still be allowed to use their apps but the responses will be ephemeral. This only applies to apps not also installed to the server.
|
/// Allows user-installed apps to send public responses. When disabled, users will still be allowed to use their apps but the responses will be ephemeral. This only applies to apps not also installed to the server.
|
||||||
USE_EXTERNAL_APPS,
|
USE_EXTERNAL_APPS,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/topics/opcodes-and-status-codes#opcodes-and-status-codes
|
/// https://discord.com/developers/docs/topics/opcodes-and-status-codes#opcodes-and-status-codes
|
||||||
pub const GatewayCloseEventCodes = enum(u16) {
|
pub const GatewayCloseEventCodes = enum(u16) {
|
||||||
/// A normal closure of the gateway. You may attempt to reconnect.
|
/// A normal closure of the gateway. You may attempt to reconnect.
|
||||||
NormalClosure = 1000,
|
NormalClosure = 1000,
|
||||||
/// We're not sure what went wrong. Try reconnecting?
|
/// We're not sure what went wrong. Try reconnecting?
|
||||||
@ -1331,10 +1331,10 @@ pub const GuildFeatures = enum {
|
|||||||
InvalidIntents,
|
InvalidIntents,
|
||||||
/// You sent a disallowed intent for a [Gateway Intent](https://discord.com/developers/docs/topics/gateway#gateway-intents). You may have tried to specify an intent that you [have not enabled or are not approved for](https://discord.com/developers/docs/topics/gateway#privileged-intents).
|
/// You sent a disallowed intent for a [Gateway Intent](https://discord.com/developers/docs/topics/gateway#gateway-intents). You may have tried to specify an intent that you [have not enabled or are not approved for](https://discord.com/developers/docs/topics/gateway#privileged-intents).
|
||||||
DisallowedIntents,
|
DisallowedIntents,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes
|
/// https://discord.com/developers/docs/topics/opcodes-and-status-codes#gateway-gateway-opcodes
|
||||||
pub const GatewayOpcodes = enum(u4) {
|
pub const GatewayOpcodes = enum(u4) {
|
||||||
/// An event was dispatched.
|
/// An event was dispatched.
|
||||||
Dispatch,
|
Dispatch,
|
||||||
/// Fired periodically by the client to keep the connection alive.
|
/// Fired periodically by the client to keep the connection alive.
|
||||||
@ -1357,9 +1357,9 @@ pub const GuildFeatures = enum {
|
|||||||
Hello,
|
Hello,
|
||||||
/// Sent in response to receiving a heartbeat to acknowledge that it has been received.
|
/// Sent in response to receiving a heartbeat to acknowledge that it has been received.
|
||||||
HeartbeatACK,
|
HeartbeatACK,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const GatewayDispatchEventNames = union(enum) {
|
pub const GatewayDispatchEventNames = union(enum) {
|
||||||
APPLICATION_COMMAND_PERMISSIONS_UPDATE,
|
APPLICATION_COMMAND_PERMISSIONS_UPDATE,
|
||||||
AUTO_MODERATION_RULE_CREATE,
|
AUTO_MODERATION_RULE_CREATE,
|
||||||
AUTO_MODERATION_RULE_UPDATE,
|
AUTO_MODERATION_RULE_UPDATE,
|
||||||
@ -1428,186 +1428,11 @@ pub const GuildFeatures = enum {
|
|||||||
|
|
||||||
READY,
|
READY,
|
||||||
RESUMED,
|
RESUMED,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/topics/gateway#list-of-intents
|
|
||||||
pub const GatewayIntents = packed struct {
|
|
||||||
pub fn toRaw(self: GatewayIntents) u32 {
|
|
||||||
return @bitCast(self);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn fromRaw(raw: u32) GatewayIntents {
|
|
||||||
return @bitCast(raw);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn jsonParse(allocator: std.mem.Allocator, src: anytype, _: std.json.ParseOptions) !@This() {
|
|
||||||
const value = try std.json.innerParse(std.json.Value, allocator, src, .{
|
|
||||||
.ignore_unknown_fields = true,
|
|
||||||
.max_value_len = 0x1000,
|
|
||||||
});
|
|
||||||
if (value != .integer) @panic("Invalid value for bitfield");
|
|
||||||
|
|
||||||
return fromRaw(@intCast(value.integer));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn jsonParseFromValue(_: std.mem.Allocator, src: std.json.Value, _: std.json.ParseOptions) @This() {
|
|
||||||
if (src != .integer) @panic("Invalid value for bitfield");
|
|
||||||
return fromRaw(@intCast(src.integer));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
///
|
/// https://discord.com/developers/docs/interactions/slash-commands#interaction-response-interactionresponsetype
|
||||||
/// - GUILD_CREATE
|
pub const InteractionResponseTypes = enum(u4) {
|
||||||
/// - GUILD_UPDATE
|
|
||||||
/// - GUILD_DELETE
|
|
||||||
/// - GUILD_ROLE_CREATE
|
|
||||||
/// - GUILD_ROLE_UPDATE
|
|
||||||
/// - GUILD_ROLE_DELETE
|
|
||||||
/// - CHANNEL_CREATE
|
|
||||||
/// - CHANNEL_UPDATE
|
|
||||||
/// - CHANNEL_DELETE
|
|
||||||
/// - CHANNEL_PINS_UPDATE
|
|
||||||
/// - THREAD_CREATE
|
|
||||||
/// - THREAD_UPDATE
|
|
||||||
/// - THREAD_DELETE
|
|
||||||
/// - THREAD_LIST_SYNC
|
|
||||||
/// - THREAD_MEMBER_UPDATE
|
|
||||||
/// - THREAD_MEMBERS_UPDATE
|
|
||||||
/// - STAGE_INSTANCE_CREATE
|
|
||||||
/// - STAGE_INSTANCE_UPDATE
|
|
||||||
/// - STAGE_INSTANCE_DELETE
|
|
||||||
////
|
|
||||||
Guilds: bool = false,
|
|
||||||
///
|
|
||||||
/// - GUILD_MEMBER_ADD
|
|
||||||
/// - GUILD_MEMBER_UPDATE
|
|
||||||
/// - GUILD_MEMBER_REMOVE
|
|
||||||
/// - THREAD_MEMBERS_UPDATE
|
|
||||||
///
|
|
||||||
/// This is a privileged intent.
|
|
||||||
////
|
|
||||||
GuildMembers: bool = false,
|
|
||||||
///
|
|
||||||
/// - GUILD_AUDIT_LOG_ENTRY_CREATE
|
|
||||||
/// - GUILD_BAN_ADD
|
|
||||||
/// - GUILD_BAN_REMOVE
|
|
||||||
////
|
|
||||||
GuildModeration: bool = false,
|
|
||||||
///
|
|
||||||
/// - GUILD_EMOJIS_UPDATE
|
|
||||||
/// - GUILD_STICKERS_UPDATE
|
|
||||||
////
|
|
||||||
GuildEmojisAndStickers: bool = false,
|
|
||||||
///
|
|
||||||
/// - GUILD_INTEGRATIONS_UPDATE
|
|
||||||
/// - INTEGRATION_CREATE
|
|
||||||
/// - INTEGRATION_UPDATE
|
|
||||||
/// - INTEGRATION_DELETE
|
|
||||||
////
|
|
||||||
GuildIntegrations: bool = false,
|
|
||||||
///
|
|
||||||
/// - WEBHOOKS_UPDATE
|
|
||||||
////
|
|
||||||
GuildWebhooks: bool = false,
|
|
||||||
///
|
|
||||||
/// - INVITE_CREATE
|
|
||||||
/// - INVITE_DELETE
|
|
||||||
////
|
|
||||||
GuildInvites: bool = false,
|
|
||||||
///
|
|
||||||
/// - VOICE_STATE_UPDATE
|
|
||||||
/// - VOICE_CHANNEL_EFFECT_SEND
|
|
||||||
////
|
|
||||||
GuildVoiceStates: bool = false,
|
|
||||||
///
|
|
||||||
/// - PRESENCE_UPDATE
|
|
||||||
///
|
|
||||||
/// This is a privileged intent.
|
|
||||||
////
|
|
||||||
GuildPresences: bool = false,
|
|
||||||
///
|
|
||||||
/// - MESSAGE_CREATE
|
|
||||||
/// - MESSAGE_UPDATE
|
|
||||||
/// - MESSAGE_DELETE
|
|
||||||
/// - MESSAGE_DELETE_BULK
|
|
||||||
///
|
|
||||||
/// The messages do not contain content by default.
|
|
||||||
/// If you want to receive their content too, you need to turn on the privileged `MESSAGE_CONTENT` intent. */
|
|
||||||
GuildMessages: bool = false,
|
|
||||||
///
|
|
||||||
/// - MESSAGE_REACTION_ADD
|
|
||||||
/// - MESSAGE_REACTION_REMOVE
|
|
||||||
/// - MESSAGE_REACTION_REMOVE_ALL
|
|
||||||
/// - MESSAGE_REACTION_REMOVE_EMOJI
|
|
||||||
////
|
|
||||||
GuildMessageReactions: bool = false,
|
|
||||||
///
|
|
||||||
/// - TYPING_START
|
|
||||||
////
|
|
||||||
GuildMessageTyping: bool = false,
|
|
||||||
///
|
|
||||||
/// - CHANNEL_CREATE
|
|
||||||
/// - MESSAGE_CREATE
|
|
||||||
/// - MESSAGE_UPDATE
|
|
||||||
/// - MESSAGE_DELETE
|
|
||||||
/// - CHANNEL_PINS_UPDATE
|
|
||||||
////
|
|
||||||
DirectMessages: bool = false,
|
|
||||||
///
|
|
||||||
/// - MESSAGE_REACTION_ADD
|
|
||||||
/// - MESSAGE_REACTION_REMOVE
|
|
||||||
/// - MESSAGE_REACTION_REMOVE_ALL
|
|
||||||
/// - MESSAGE_REACTION_REMOVE_EMOJI
|
|
||||||
////
|
|
||||||
DirectMessageReactions: bool = false,
|
|
||||||
///
|
|
||||||
/// - TYPING_START
|
|
||||||
////
|
|
||||||
DirectMessageTyping: bool = false,
|
|
||||||
///
|
|
||||||
/// This intent will add all content related values to message events.
|
|
||||||
///
|
|
||||||
/// This is a privileged intent.
|
|
||||||
////
|
|
||||||
MessageContent: bool = false,
|
|
||||||
///
|
|
||||||
/// - GUILD_SCHEDULED_EVENT_CREATE
|
|
||||||
/// - GUILD_SCHEDULED_EVENT_UPDATE
|
|
||||||
/// - GUILD_SCHEDULED_EVENT_DELETE
|
|
||||||
/// - GUILD_SCHEDULED_EVENT_USER_ADD this is experimental and unstable.
|
|
||||||
/// - GUILD_SCHEDULED_EVENT_USER_REMOVE this is experimental and unstable.
|
|
||||||
////
|
|
||||||
GuildScheduledEvents: bool = false,
|
|
||||||
_pad: u4 = 0,
|
|
||||||
///
|
|
||||||
/// - AUTO_MODERATION_RULE_CREATE
|
|
||||||
/// - AUTO_MODERATION_RULE_UPDATE
|
|
||||||
/// - AUTO_MODERATION_RULE_DELETE
|
|
||||||
////
|
|
||||||
AutoModerationConfiguration: bool = false,
|
|
||||||
///
|
|
||||||
/// - AUTO_MODERATION_ACTION_EXECUTION
|
|
||||||
////
|
|
||||||
AutoModerationExecution: bool = false,
|
|
||||||
_pad2: u3 = 0,
|
|
||||||
///
|
|
||||||
/// - MESSAGE_POLL_VOTE_ADD
|
|
||||||
/// - MESSAGE_POLL_VOTE_REMOVE
|
|
||||||
////
|
|
||||||
GuildMessagePolls: bool = false,
|
|
||||||
///
|
|
||||||
/// - MESSAGE_POLL_VOTE_ADD
|
|
||||||
/// - MESSAGE_POLL_VOTE_REMOVE
|
|
||||||
////
|
|
||||||
DirectMessagePolls: bool = false,
|
|
||||||
_pad3: u4 = 0,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/topics/gateway#list-of-intents
|
|
||||||
pub const Intents = GatewayIntents;
|
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/interactions/slash-commands#interaction-response-interactionresponsetype
|
|
||||||
pub const InteractionResponseTypes = enum(u4) {
|
|
||||||
/// ACK a `Ping`
|
/// ACK a `Ping`
|
||||||
Pong = 1,
|
Pong = 1,
|
||||||
/// Respond to an interaction with a message
|
/// Respond to an interaction with a message
|
||||||
@ -1633,27 +1458,27 @@ pub const GuildFeatures = enum {
|
|||||||
/// @remarks
|
/// @remarks
|
||||||
/// Only available for apps with Activities enabled
|
/// Only available for apps with Activities enabled
|
||||||
LaunchActivity = 12,
|
LaunchActivity = 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const SortOrderTypes = enum {
|
pub const SortOrderTypes = enum {
|
||||||
/// Sort forum posts by activity
|
/// Sort forum posts by activity
|
||||||
LatestActivity,
|
LatestActivity,
|
||||||
/// Sort forum posts by creation time (from most recent to oldest)
|
/// Sort forum posts by creation time (from most recent to oldest)
|
||||||
CreationDate,
|
CreationDate,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ForumLayout = enum {
|
pub const ForumLayout = enum {
|
||||||
/// No default has been set for forum channel.
|
/// No default has been set for forum channel.
|
||||||
NotSet,
|
NotSet,
|
||||||
/// Display posts as a list.
|
/// Display posts as a list.
|
||||||
ListView,
|
ListView,
|
||||||
/// Display posts as a collection of tiles.
|
/// Display posts as a collection of tiles.
|
||||||
GalleryView,
|
GalleryView,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/reference#image-formatting
|
/// https://discord.com/developers/docs/reference#image-formatting
|
||||||
/// json is only for stickers
|
/// json is only for stickers
|
||||||
pub const ImageFormat = union(enum) {
|
pub const ImageFormat = union(enum) {
|
||||||
jpg,
|
jpg,
|
||||||
jpeg,
|
jpeg,
|
||||||
png,
|
png,
|
||||||
|
@ -66,8 +66,6 @@
|
|||||||
pub const GatewayCloseEventCodes = @import("shared.zig").GatewayCloseEventCodes;
|
pub const GatewayCloseEventCodes = @import("shared.zig").GatewayCloseEventCodes;
|
||||||
pub const GatewayOpcodes = @import("shared.zig").GatewayOpcodes;
|
pub const GatewayOpcodes = @import("shared.zig").GatewayOpcodes;
|
||||||
pub const GatewayDispatchEventNames = @import("shared.zig").GatewayDispatchEventNames;
|
pub const GatewayDispatchEventNames = @import("shared.zig").GatewayDispatchEventNames;
|
||||||
pub const GatewayIntents = @import("shared.zig").GatewayIntents;
|
|
||||||
pub const Intents = @import("shared.zig").Intents;
|
|
||||||
pub const InteractionResponseTypes = @import("shared.zig").InteractionResponseTypes;
|
pub const InteractionResponseTypes = @import("shared.zig").InteractionResponseTypes;
|
||||||
pub const SortOrderTypes = @import("shared.zig").SortOrderTypes;
|
pub const SortOrderTypes = @import("shared.zig").SortOrderTypes;
|
||||||
pub const ForumLayout = @import("shared.zig").ForumLayout;
|
pub const ForumLayout = @import("shared.zig").ForumLayout;
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
const OAuth2Scope = @import("shared.zig").OAuth2Scope;
|
const OAuth2Scope = @import("shared.zig").OAuth2Scope;
|
||||||
const Integration = @import("integration.zig").Integration;
|
const Integration = @import("integration.zig").Integration;
|
||||||
const Partial = @import("partial.zig").Partial;
|
const Partial = @import("partial.zig").Partial;
|
||||||
const Record = @import("../json-helper.zig").Record;
|
const Record = @import("../utils/json.zig").Record;
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/resources/user#user-object
|
/// https://discord.com/developers/docs/resources/user#user-object
|
||||||
pub const User = struct {
|
pub const User = struct {
|
||||||
|
@ -15,74 +15,7 @@
|
|||||||
//! PERFORMANCE OF THIS SOFTWARE.
|
//! PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const mem = std.mem;
|
const Types = @import("../structures/types.zig");
|
||||||
const builtin = @import("builtin");
|
|
||||||
const Types = @import("./structures/types.zig");
|
|
||||||
|
|
||||||
pub const IdentifyProperties = struct {
|
|
||||||
/// Operating system the shard runs on.
|
|
||||||
os: []const u8,
|
|
||||||
/// The "browser" where this shard is running on.
|
|
||||||
browser: []const u8,
|
|
||||||
/// The device on which the shard is running.
|
|
||||||
device: []const u8,
|
|
||||||
|
|
||||||
system_locale: ?[]const u8 = null, // TODO parse this
|
|
||||||
browser_user_agent: ?[]const u8 = null,
|
|
||||||
browser_version: ?[]const u8 = null,
|
|
||||||
os_version: ?[]const u8 = null,
|
|
||||||
referrer: ?[]const u8 = null,
|
|
||||||
referring_domain: ?[]const u8 = null,
|
|
||||||
referrer_current: ?[]const u8 = null,
|
|
||||||
referring_domain_current: ?[]const u8 = null,
|
|
||||||
release_channel: ?[]const u8 = null,
|
|
||||||
client_build_number: ?u64 = null,
|
|
||||||
client_event_source: ?[]const u8 = null,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/topics/gateway#get-gateway
|
|
||||||
pub const GatewayInfo = struct {
|
|
||||||
/// The WSS URL that can be used for connecting to the gateway
|
|
||||||
url: []const u8,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/events/gateway#session-start-limit-object
|
|
||||||
pub const GatewaySessionStartLimit = struct {
|
|
||||||
/// Total number of session starts the current user is allowed
|
|
||||||
total: u32,
|
|
||||||
/// Remaining number of session starts the current user is allowed
|
|
||||||
remaining: u32,
|
|
||||||
/// Number of milliseconds after which the limit resets
|
|
||||||
reset_after: u32,
|
|
||||||
/// Number of identify requests allowed per 5 seconds
|
|
||||||
max_concurrency: u32,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// https://discord.com/developers/docs/topics/gateway#get-gateway-bot
|
|
||||||
pub const GatewayBotInfo = struct {
|
|
||||||
url: []const u8,
|
|
||||||
/// The recommended number of shards to use when connecting
|
|
||||||
///
|
|
||||||
/// See https://discord.com/developers/docs/topics/gateway#sharding
|
|
||||||
shards: u32,
|
|
||||||
/// Information on the current session start limit
|
|
||||||
///
|
|
||||||
/// See https://discord.com/developers/docs/topics/gateway#session-start-limit-object
|
|
||||||
session_start_limit: ?GatewaySessionStartLimit,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const ShardDetails = struct {
|
|
||||||
/// Bot token which is used to connect to Discord */
|
|
||||||
token: []const u8,
|
|
||||||
/// The URL of the gateway which should be connected to.
|
|
||||||
url: []const u8 = "wss://gateway.discord.gg",
|
|
||||||
/// The gateway version which should be used.
|
|
||||||
version: ?usize = 10,
|
|
||||||
/// The calculated intent value of the events which the shard should receive.
|
|
||||||
intents: Types.Intents,
|
|
||||||
/// Identify properties to use
|
|
||||||
properties: IdentifyProperties = default_identify_properties,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const debug = std.log.scoped(.@"discord.zig");
|
pub const debug = std.log.scoped(.@"discord.zig");
|
||||||
|
|
||||||
@ -95,194 +28,6 @@ pub inline fn logif(log: Log, comptime format: []const u8, args: anytype) void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const default_identify_properties = IdentifyProperties{
|
|
||||||
.os = @tagName(builtin.os.tag),
|
|
||||||
.browser = "discord.zig",
|
|
||||||
.device = "discord.zig",
|
|
||||||
};
|
|
||||||
|
|
||||||
/// inspired from:
|
|
||||||
/// https://github.com/tiramisulabs/seyfert/blob/main/src/websocket/structures/timeout.ts
|
|
||||||
pub fn ConnectQueue(comptime T: type) type {
|
|
||||||
return struct {
|
|
||||||
pub const RequestWithShard = struct {
|
|
||||||
callback: *const fn (self: *RequestWithShard) anyerror!void,
|
|
||||||
shard: T,
|
|
||||||
};
|
|
||||||
|
|
||||||
// ignore this function
|
|
||||||
// so it becomes a regular dequeue
|
|
||||||
fn eq(_: void, _: RequestWithShard, _: RequestWithShard) std.math.Order {
|
|
||||||
return std.math.Order.eq;
|
|
||||||
}
|
|
||||||
|
|
||||||
dequeue: std.PriorityDequeue(RequestWithShard, void, eq),
|
|
||||||
allocator: mem.Allocator,
|
|
||||||
remaining: usize,
|
|
||||||
interval_time: u64 = 5000,
|
|
||||||
running: bool = false,
|
|
||||||
concurrency: usize = 1,
|
|
||||||
|
|
||||||
pub fn init(allocator: mem.Allocator, concurrency: usize, interval_time: u64) !ConnectQueue(T) {
|
|
||||||
return .{
|
|
||||||
.allocator = allocator,
|
|
||||||
.dequeue = std.PriorityDequeue(RequestWithShard, void, eq).init(allocator, {}),
|
|
||||||
.remaining = concurrency,
|
|
||||||
.interval_time = interval_time,
|
|
||||||
.concurrency = concurrency,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn deinit(self: *ConnectQueue(T)) void {
|
|
||||||
self.dequeue.deinit();
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn push(self: *ConnectQueue(T), req: RequestWithShard) !void {
|
|
||||||
if (self.remaining == 0) {
|
|
||||||
return self.dequeue.add(req);
|
|
||||||
}
|
|
||||||
self.remaining -= 1;
|
|
||||||
|
|
||||||
if (!self.running) {
|
|
||||||
try self.startInterval();
|
|
||||||
self.running = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.dequeue.count() < self.concurrency) {
|
|
||||||
// perhaps store this?
|
|
||||||
const ptr = try self.allocator.create(RequestWithShard);
|
|
||||||
ptr.* = req;
|
|
||||||
try req.callback(ptr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return self.dequeue.add(req);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn startInterval(self: *ConnectQueue(T)) !void {
|
|
||||||
while (self.running) {
|
|
||||||
std.Thread.sleep(std.time.ns_per_ms * (self.interval_time / self.concurrency));
|
|
||||||
const req: ?RequestWithShard = self.dequeue.removeMin(); // pop front
|
|
||||||
|
|
||||||
while (self.dequeue.count() == 0 and req == null) {}
|
|
||||||
|
|
||||||
if (req) |r| {
|
|
||||||
const ptr = try self.allocator.create(RequestWithShard);
|
|
||||||
ptr.* = r;
|
|
||||||
try @call(.auto, r.callback, .{ptr});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.remaining < self.concurrency) {
|
|
||||||
self.remaining += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self.dequeue.count() == 0) {
|
|
||||||
self.running = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Bucket = struct {
|
|
||||||
/// The queue of requests to acquire an available request. Mapped by (shardId, RequestWithPrio)
|
|
||||||
queue: std.PriorityQueue(RequestWithPrio, void, Bucket.lessthan),
|
|
||||||
|
|
||||||
limit: usize,
|
|
||||||
refill_interval: u64,
|
|
||||||
refill_amount: usize,
|
|
||||||
|
|
||||||
/// The amount of requests that have been used up already.
|
|
||||||
used: usize = 0,
|
|
||||||
|
|
||||||
/// Whether or not the queue is already processing.
|
|
||||||
processing: bool = false,
|
|
||||||
|
|
||||||
/// Whether the timeout should be killed because there is already one running
|
|
||||||
should_stop: std.atomic.Value(bool) = std.atomic.Value(bool).init(false),
|
|
||||||
|
|
||||||
/// The timestamp in milliseconds when the next refill is scheduled.
|
|
||||||
refills_at: ?u64 = null,
|
|
||||||
|
|
||||||
pub const RequestWithPrio = struct {
|
|
||||||
callback: *const fn () void,
|
|
||||||
priority: u32 = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn lessthan(_: void, a: RequestWithPrio, b: RequestWithPrio) std.math.Order {
|
|
||||||
return std.math.order(a.priority, b.priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn init(allocator: mem.Allocator, limit: usize, refill_interval: u64, refill_amount: usize) Bucket {
|
|
||||||
return .{
|
|
||||||
.queue = std.PriorityQueue(RequestWithPrio, void, lessthan).init(allocator, {}),
|
|
||||||
.limit = limit,
|
|
||||||
.refill_interval = refill_interval,
|
|
||||||
.refill_amount = refill_amount,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn remaining(self: *Bucket) usize {
|
|
||||||
if (self.limit < self.used) {
|
|
||||||
return 0;
|
|
||||||
} else {
|
|
||||||
return self.limit - self.used;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn refill(self: *Bucket) std.Thread.SpawnError!void {
|
|
||||||
// Lower the used amount by the refill amount
|
|
||||||
self.used = if (self.refill_amount > self.used) 0 else self.used - self.refill_amount;
|
|
||||||
|
|
||||||
// Reset the refills_at timestamp since it just got refilled
|
|
||||||
self.refills_at = null;
|
|
||||||
|
|
||||||
if (self.used > 0) {
|
|
||||||
if (self.should_stop.load(.monotonic) == true) {
|
|
||||||
self.should_stop.store(false, .monotonic);
|
|
||||||
}
|
|
||||||
const thread = try std.Thread.spawn(.{}, Bucket.timeout, .{self});
|
|
||||||
thread.detach;
|
|
||||||
self.refills_at = std.time.milliTimestamp() + self.refill_interval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn timeout(self: *Bucket) void {
|
|
||||||
while (!self.should_stop.load(.monotonic)) {
|
|
||||||
self.refill();
|
|
||||||
std.time.sleep(std.time.ns_per_ms * self.refill_interval);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn processQueue(self: *Bucket) std.Thread.SpawnError!void {
|
|
||||||
if (self.processing) return;
|
|
||||||
|
|
||||||
while (self.queue.remove()) |first_element| {
|
|
||||||
if (self.remaining() != 0) {
|
|
||||||
first_element.callback();
|
|
||||||
self.used += 1;
|
|
||||||
|
|
||||||
if (!self.should_stop.load(.monotonic)) {
|
|
||||||
const thread = try std.Thread.spawn(.{}, Bucket.timeout, .{self});
|
|
||||||
thread.detach;
|
|
||||||
self.refills_at = std.time.milliTimestamp() + self.refill_interval;
|
|
||||||
}
|
|
||||||
} else if (self.refills_at) |ra| {
|
|
||||||
const now = std.time.milliTimestamp();
|
|
||||||
if (ra > now) std.time.sleep(std.time.ns_per_ms * (ra - now));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.processing = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn acquire(self: *Bucket, rq: RequestWithPrio) !void {
|
|
||||||
try self.queue.add(rq);
|
|
||||||
try self.processQueue();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const GatewayDispatchEvent = struct {
|
pub const GatewayDispatchEvent = struct {
|
||||||
application_command_permissions_update: ?*const fn (save: *anyopaque, application_command_permissions: Types.ApplicationCommandPermissions) anyerror!void = undefined,
|
application_command_permissions_update: ?*const fn (save: *anyopaque, application_command_permissions: Types.ApplicationCommandPermissions) anyerror!void = undefined,
|
||||||
auto_moderation_rule_create: ?*const fn (save: *anyopaque, rule: Types.AutoModerationRule) anyerror!void = undefined,
|
auto_moderation_rule_create: ?*const fn (save: *anyopaque, rule: Types.AutoModerationRule) anyerror!void = undefined,
|
Loading…
x
Reference in New Issue
Block a user