added sussy stuff
This commit is contained in:
parent
8c6a7f3919
commit
ae2a8691c2
103
src/shard.zig
103
src/shard.zig
@ -172,6 +172,7 @@ allocator: mem.Allocator,
|
|||||||
resume_gateway_url: ?[]const u8 = null,
|
resume_gateway_url: ?[]const u8 = null,
|
||||||
info: GatewayBotInfo,
|
info: GatewayBotInfo,
|
||||||
|
|
||||||
|
properties: IdentifyProperties = _default_properties,
|
||||||
session_id: ?[]const u8,
|
session_id: ?[]const u8,
|
||||||
sequence: isize,
|
sequence: isize,
|
||||||
heart: Heart = .{ .heartbeatInterval = 45000, .ack = false, .lastBeat = 0 },
|
heart: Heart = .{ .heartbeatInterval = 45000, .ack = false, .lastBeat = 0 },
|
||||||
@ -213,26 +214,36 @@ inline fn gatewayUrl(self: ?*Self) []const u8 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// identifies in order to connect to Discord and get the online status, this shall be done on hello perhaps
|
// identifies in order to connect to Discord and get the online status, this shall be done on hello perhaps
|
||||||
fn identify(self: *Self) !void {
|
fn identify(self: *Self, properties: ?IdentifyProperties) !void {
|
||||||
self.logif("intents: {d}", .{self.intents.toRaw()});
|
self.logif("intents: {d}", .{self.intents.toRaw()});
|
||||||
|
|
||||||
|
if (self.intents.toRaw() != 0) {
|
||||||
const data = .{
|
const data = .{
|
||||||
.op = @intFromEnum(Opcode.Identify),
|
.op = @intFromEnum(Opcode.Identify),
|
||||||
.d = .{
|
.d = .{
|
||||||
//.compress = false,
|
|
||||||
.intents = self.intents.toRaw(),
|
.intents = self.intents.toRaw(),
|
||||||
.properties = Self._default_properties,
|
.properties = properties orelse Self._default_properties,
|
||||||
.token = self.token,
|
.token = self.token,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
// try posting our shitty data
|
|
||||||
try self.send(data);
|
try self.send(data);
|
||||||
|
} else {
|
||||||
|
const data = .{
|
||||||
|
.op = @intFromEnum(Opcode.Identify),
|
||||||
|
.d = .{
|
||||||
|
.capabilities = 30717,
|
||||||
|
.properties = properties orelse Self._default_properties,
|
||||||
|
.token = self.token,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
try self.send(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Log = union(enum) { yes, no };
|
const Log = union(enum) { yes, no };
|
||||||
|
|
||||||
// asks /gateway/bot initializes both the ws client and the http client
|
// asks /gateway/bot initializes both the ws client and the http client
|
||||||
pub fn init(allocator: mem.Allocator, args: struct {
|
pub fn login(allocator: mem.Allocator, args: struct {
|
||||||
token: []const u8,
|
token: []const u8,
|
||||||
intents: Intents,
|
intents: Intents,
|
||||||
run: GatewayDispatchEvent,
|
run: GatewayDispatchEvent,
|
||||||
@ -365,7 +376,7 @@ pub fn readMessage(self: *Self, _: anytype) !void {
|
|||||||
try self.resume_();
|
try self.resume_();
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
try self.identify();
|
try self.identify(self.properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -502,7 +513,7 @@ pub fn handleEvent(self: *Self, name: []const u8, payload: []const u8) !void {
|
|||||||
|
|
||||||
self.logif("new gateway url: {s}", .{self.gatewayUrl()});
|
self.logif("new gateway url: {s}", .{self.gatewayUrl()});
|
||||||
|
|
||||||
const application = obj.getT(.object, "application").?;
|
const application = obj.getT(.object, "application");
|
||||||
const user = try Parser.parseUser(self.allocator, obj.getT(.object, "user").?);
|
const user = try Parser.parseUser(self.allocator, obj.getT(.object, "user").?);
|
||||||
|
|
||||||
var ready = Discord.Ready{
|
var ready = Discord.Ready{
|
||||||
@ -512,7 +523,7 @@ pub fn handleEvent(self: *Self, name: []const u8, payload: []const u8) !void {
|
|||||||
.session_id = obj.getT(.string, "session_id").?,
|
.session_id = obj.getT(.string, "session_id").?,
|
||||||
.guilds = &[0]Discord.UnavailableGuild{},
|
.guilds = &[0]Discord.UnavailableGuild{},
|
||||||
.resume_gateway_url = obj.getT(.string, "resume_gateway_url").?,
|
.resume_gateway_url = obj.getT(.string, "resume_gateway_url").?,
|
||||||
.application = .{
|
.application = if (application) |app| .{
|
||||||
// todo
|
// todo
|
||||||
.name = null,
|
.name = null,
|
||||||
.description = null,
|
.description = null,
|
||||||
@ -540,9 +551,9 @@ pub fn handleEvent(self: *Self, name: []const u8, payload: []const u8) !void {
|
|||||||
.bot = null,
|
.bot = null,
|
||||||
.redirect_uris = null,
|
.redirect_uris = null,
|
||||||
.interactions_endpoint_url = null,
|
.interactions_endpoint_url = null,
|
||||||
.flags = @as(Discord.ApplicationFlags, @bitCast(@as(u25, @intCast(application.getT(.integer, "flags").?)))),
|
.flags = @as(Discord.ApplicationFlags, @bitCast(@as(u25, @intCast(app.getT(.integer, "flags").?)))),
|
||||||
.id = try Shared.Snowflake.fromRaw(application.getT(.string, "id").?),
|
.id = try Shared.Snowflake.fromRaw(app.getT(.string, "id").?),
|
||||||
},
|
} else null,
|
||||||
};
|
};
|
||||||
|
|
||||||
const shard = obj.getT(.array, "shard");
|
const shard = obj.getT(.array, "shard");
|
||||||
@ -615,6 +626,74 @@ pub fn handleEvent(self: *Self, name: []const u8, payload: []const u8) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn loginWithEmail(allocator: mem.Allocator, settings: struct { login: []const u8, password: []const u8, run: GatewayDispatchEvent, log: Log }) !Self {
|
||||||
|
const AUTH_LOGIN = "https://discord.com/api/v9/auth/login";
|
||||||
|
const WS_CONNECT = "gateway.discord.gg";
|
||||||
|
|
||||||
|
var body = std.ArrayList(u8).init(allocator);
|
||||||
|
|
||||||
|
const AuthLoginResponse = struct { user_id: []const u8, token: []const u8, user_settings: struct { locale: []const u8, theme: []const u8 } };
|
||||||
|
|
||||||
|
var fetch_options = HttpClient.FetchOptions{
|
||||||
|
.location = HttpClient.FetchOptions.Location{
|
||||||
|
.url = AUTH_LOGIN,
|
||||||
|
},
|
||||||
|
.extra_headers = &[_]http.Header{
|
||||||
|
http.Header{ .name = "Accept", .value = "application/json" },
|
||||||
|
http.Header{ .name = "Content-Type", .value = "application/json" },
|
||||||
|
},
|
||||||
|
.method = .POST,
|
||||||
|
.response_storage = .{ .dynamic = &body },
|
||||||
|
};
|
||||||
|
|
||||||
|
fetch_options.payload = try json.stringifyAlloc(allocator, .{
|
||||||
|
.login = settings.login,
|
||||||
|
.password = settings.password,
|
||||||
|
}, .{});
|
||||||
|
|
||||||
|
var client = HttpClient{ .allocator = allocator };
|
||||||
|
defer client.deinit();
|
||||||
|
|
||||||
|
const res = try client.fetch(fetch_options);
|
||||||
|
|
||||||
|
if (res.status == std.http.Status.ok) {
|
||||||
|
const response = try std.json.parseFromSliceLeaky(AuthLoginResponse, allocator, try body.toOwnedSlice(), .{});
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.allocator = allocator,
|
||||||
|
.token = response.token,
|
||||||
|
.intents = @bitCast(@as(u28, @intCast(0))),
|
||||||
|
// maybe there is a better way to do this
|
||||||
|
.client = try Self._connect_ws(allocator, WS_CONNECT),
|
||||||
|
.session_id = undefined,
|
||||||
|
.sequence = 0,
|
||||||
|
.info = GatewayBotInfo{ .url = "wss://" ++ WS_CONNECT, .shards = 0, .session_start_limit = null },
|
||||||
|
.handler = settings.run,
|
||||||
|
.log = settings.log,
|
||||||
|
.packets = std.ArrayList(u8).init(allocator),
|
||||||
|
.inflator = try zlib.Decompressor.init(allocator, .{ .header = .zlib_or_gzip }),
|
||||||
|
.properties = IdentifyProperties{
|
||||||
|
.os = "Linux",
|
||||||
|
.browser = "Firefox",
|
||||||
|
.device = "",
|
||||||
|
.system_locale = "en-US",
|
||||||
|
.browser_user_agent = "Mozilla/5.0 (X11; Linux x86_64; rv:132.0) Gecko/20100101 Firefox/132.0",
|
||||||
|
.browser_version = "132.0",
|
||||||
|
.os_version = "",
|
||||||
|
.referrer = "",
|
||||||
|
.referring_domain = "",
|
||||||
|
.referrer_current = "",
|
||||||
|
.referring_domain_current = "",
|
||||||
|
.release_channel = "stable",
|
||||||
|
.client_build_number = 342245,
|
||||||
|
.client_event_source = null,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return error.effn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline fn logif(self: *Self, comptime format: []const u8, args: anytype) void {
|
inline fn logif(self: *Self, comptime format: []const u8, args: anytype) void {
|
||||||
switch (self.log) {
|
switch (self.log) {
|
||||||
.yes => debug.info(format, args),
|
.yes => debug.info(format, args),
|
||||||
|
@ -13,6 +13,18 @@ pub const IdentifyProperties = struct {
|
|||||||
/// The device on which the shard is running.
|
/// The device on which the shard is running.
|
||||||
///
|
///
|
||||||
device: []const u8,
|
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
|
/// https://discord.com/developers/docs/topics/gateway#get-gateway
|
||||||
|
@ -16,7 +16,7 @@ pub fn main() !void {
|
|||||||
const allocator = std.heap.c_allocator;
|
const allocator = std.heap.c_allocator;
|
||||||
const token = std.posix.getenv("TOKEN") orelse unreachable;
|
const token = std.posix.getenv("TOKEN") orelse unreachable;
|
||||||
|
|
||||||
var handler = try Shard.init(allocator, .{
|
var handler = try Shard.login(allocator, .{
|
||||||
.token = token,
|
.token = token,
|
||||||
.intents = Intents.fromRaw(37379),
|
.intents = Intents.fromRaw(37379),
|
||||||
.run = Shard.GatewayDispatchEvent{
|
.run = Shard.GatewayDispatchEvent{
|
||||||
|
@ -4312,8 +4312,8 @@ pub const Ready = struct {
|
|||||||
resume_gateway_url: []const u8,
|
resume_gateway_url: []const u8,
|
||||||
/// The shard information associated with this session, if sent when identifying
|
/// The shard information associated with this session, if sent when identifying
|
||||||
shard: ?[2]isize,
|
shard: ?[2]isize,
|
||||||
/// Contains id and flags
|
/// Contains id and flags, only sent to bots
|
||||||
application: struct {
|
application: ?struct {
|
||||||
name: ?[]const u8,
|
name: ?[]const u8,
|
||||||
description: ?[]const u8,
|
description: ?[]const u8,
|
||||||
rpc_origins: ?[]?[]const u8,
|
rpc_origins: ?[]?[]const u8,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user