dsu3 0.9.2 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/dsu3 +3 -2
- data/lib/dsu3/api/channel.rb +3 -3
- data/lib/dsu3/api/guild.rb +4 -5
- data/lib/dsu3/api/invite.rb +2 -2
- data/lib/dsu3/api/message.rb +26 -0
- data/lib/dsu3/api/user.rb +19 -0
- data/lib/dsu3/api.rb +12 -13
- data/lib/dsu3/data/channel.rb +33 -0
- data/lib/dsu3/data/guild.rb +11 -0
- data/lib/dsu3/data/invite.rb +11 -0
- data/lib/dsu3/data/message.rb +20 -0
- data/lib/dsu3/data.rb +8 -0
- data/lib/dsu3/dobject.rb +15 -0
- data/lib/dsu3/errors.rb +14 -0
- data/lib/dsu3/net.rb +24 -36
- data/lib/dsu3/props.rb +25 -21
- data/lib/dsu3/version.rb +1 -1
- metadata +11 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 926cbe8acc038109fc2b0cda6f10af35f204f2c78e91fe6a31c87d9bd1ea81c3
|
4
|
+
data.tar.gz: a4e823799e5a47bcf068650364dd29d94154708c7db601275eb0f768bbb81e16
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6eda735ef22ec9762a781d228fcc217f6dade60fbbdc2d65ba0c4efbfe2ceb6fc969698ff3f0311ac035fdf1b952e2e90560f0547e2f79ad07d6f3227836c4c9
|
7
|
+
data.tar.gz: a712aa467a11baeebd5549e88905d570d5e6df41446ef500e6e97785f026ec22b2d7a29ef2bc1f307ec9b20e7a21d14b8ebd89929045bf01b0d2ca2104e67a58
|
data/bin/dsu3
CHANGED
data/lib/dsu3/api/channel.rb
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
module DSU3
|
4
4
|
module API
|
5
|
-
#
|
5
|
+
# Channel API calls
|
6
6
|
module Channel
|
7
7
|
module_function
|
8
8
|
|
9
|
-
# Types text into a
|
9
|
+
# Types text into a channel
|
10
10
|
# @param [String] token Discord account token
|
11
11
|
# @param [String, Integer] channel Channel ID
|
12
12
|
def type(token, channel)
|
@@ -15,7 +15,7 @@ module DSU3
|
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
18
|
-
# Sends a message to a
|
18
|
+
# Sends a message to a channel
|
19
19
|
# @param [String] token Discord account token
|
20
20
|
# @param [String, Integer] channel Channel ID
|
21
21
|
# @param [String, Integer] message Message contents
|
data/lib/dsu3/api/guild.rb
CHANGED
@@ -2,21 +2,20 @@
|
|
2
2
|
|
3
3
|
module DSU3
|
4
4
|
module API
|
5
|
-
#
|
5
|
+
# Guild API calls
|
6
6
|
module Guild
|
7
7
|
module_function
|
8
8
|
|
9
9
|
# Verifies the server member
|
10
10
|
# @param [String] token Discord account token
|
11
11
|
# @param [String, Integer] guild Guild ID
|
12
|
-
|
13
|
-
def verify(token, guild, invite)
|
12
|
+
def verify(token, guild)
|
14
13
|
DSU3::API.request(
|
15
14
|
token, :get,
|
16
15
|
"guilds/#{guild}/member-verification",
|
17
|
-
{ params: { with_guild: false
|
16
|
+
{ params: { with_guild: false } }
|
18
17
|
)
|
19
18
|
end
|
20
19
|
end
|
21
20
|
end
|
22
|
-
end
|
21
|
+
end
|
data/lib/dsu3/api/invite.rb
CHANGED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DSU3
|
4
|
+
module API
|
5
|
+
# Message API calls
|
6
|
+
module Message
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# Reacts to a message
|
10
|
+
# @note To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id
|
11
|
+
# @param [String] token Discord account token
|
12
|
+
# @param [String, Integer] channel Channel ID
|
13
|
+
# @param [String, Integer] message Message ID
|
14
|
+
# @param [String] emoji
|
15
|
+
def react(token, channel, message, emoji)
|
16
|
+
emoji = URI.encode_www_form_component(emoji)
|
17
|
+
|
18
|
+
DSU3::API.request(
|
19
|
+
token, :put,
|
20
|
+
"channels/#{channel}/messages/#{message}/reactions/#{emoji}/@me",
|
21
|
+
{ params: { location: 'Message' } }
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DSU3
|
4
|
+
module API
|
5
|
+
# User API calls
|
6
|
+
module User
|
7
|
+
module_function
|
8
|
+
|
9
|
+
# Get user
|
10
|
+
# @param [String] token Discord account token
|
11
|
+
# @param [String, Integer] user User ID
|
12
|
+
def get(token, user)
|
13
|
+
DSU3::API.request(
|
14
|
+
token, :get, "users/#{user}"
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/dsu3/api.rb
CHANGED
@@ -2,17 +2,18 @@
|
|
2
2
|
|
3
3
|
require 'rest-client'
|
4
4
|
require 'json'
|
5
|
-
require 'uri'
|
6
5
|
|
7
6
|
require 'dsu3/props'
|
7
|
+
require 'dsu3/errors'
|
8
8
|
require 'dsu3/api/channel'
|
9
9
|
require 'dsu3/api/guild'
|
10
10
|
require 'dsu3/api/invite'
|
11
|
+
require 'dsu3/api/message'
|
11
12
|
|
12
13
|
module DSU3
|
13
14
|
# Namespace for all methods representing Discord API endpoints
|
14
15
|
module API
|
15
|
-
API_BASE = 'https://discord.com/api/v9'
|
16
|
+
API_BASE = 'https://discord.com/api/v9/'
|
16
17
|
|
17
18
|
module_function
|
18
19
|
|
@@ -22,32 +23,30 @@ module DSU3
|
|
22
23
|
# @param [String] route Discord API route
|
23
24
|
# @param [Hash] headers Additional request headers
|
24
25
|
# @param [String] payload
|
25
|
-
# @return [
|
26
|
+
# @return [String] Response body
|
26
27
|
def raw_request(token, method, route, headers = {}, payload = nil)
|
27
28
|
RestClient::Request.execute(
|
28
29
|
method: method,
|
29
|
-
url:
|
30
|
+
url: API_BASE + route,
|
30
31
|
headers: headers.merge(DSU3::Props::HEADERS, { authorization: token }),
|
31
32
|
payload: payload,
|
32
33
|
proxy: DSU3.proxies.sample
|
33
|
-
)
|
34
|
+
).body
|
34
35
|
end
|
35
36
|
|
36
|
-
# Makes an API request, includes
|
37
|
+
# Makes an API request, includes handling ratelimits and errors
|
37
38
|
# @param (see #raw_request)
|
38
39
|
# @return (see #raw_request)
|
39
40
|
def request(...)
|
40
41
|
raw_request(...)
|
41
42
|
rescue RestClient::ExceptionWithResponse => e
|
42
|
-
|
43
|
-
LOGGER.warn('ratelimit exceeded')
|
44
|
-
elsif e.response.headers[:content_type] == 'application/json'
|
43
|
+
begin
|
45
44
|
data = JSON.parse(e.response.body)
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
raise DSU3::RateLimitError('ratelimit exceeded', data['retry_after']) if e.is_a?(RestClient::TooManyRequests)
|
46
|
+
raise DSU3::CodeError, "#{data['code']}: #{data['message']}"
|
47
|
+
rescue JSON::ParserError
|
48
|
+
raise e
|
49
49
|
end
|
50
|
-
e.response
|
51
50
|
end
|
52
51
|
end
|
53
52
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DSU3
|
4
|
+
# Channel object
|
5
|
+
class Channel < DObject
|
6
|
+
# Types text into a channel
|
7
|
+
def type
|
8
|
+
@net.request(cooldown: 9, loop: true) { DSU3::API::Channel.type(_1, @id) }
|
9
|
+
end
|
10
|
+
|
11
|
+
# Sends a message to a channel
|
12
|
+
# @param [String, Integer] message Message contents
|
13
|
+
def send(message)
|
14
|
+
@net.request { DSU3::API::Channel.send(_1, @id, message) }
|
15
|
+
end
|
16
|
+
|
17
|
+
# @overload spam(message)
|
18
|
+
# Spams to a channel
|
19
|
+
# @param [String] message Message contents
|
20
|
+
# @overload spam(&block)
|
21
|
+
# Every time the decisive moment to send a message comes up,
|
22
|
+
# this function calls our block and pigeonholes the value returned by it
|
23
|
+
def spam(message)
|
24
|
+
@net.request(loop: true) { DSU3::API::Channel.send(_1, @id, message || yield) }
|
25
|
+
end
|
26
|
+
|
27
|
+
# Returns Message instance
|
28
|
+
# @param [String, Integer] message Message ID
|
29
|
+
def message(message_id)
|
30
|
+
DSU3::Message.new(self, message_id)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DSU3
|
4
|
+
# Message object
|
5
|
+
class Message < DObject
|
6
|
+
# @param [DSU3::Channel] channel Channel instance
|
7
|
+
# @param [String, Integer] id Message ID
|
8
|
+
def initialize(channel, id)
|
9
|
+
super(channel.net, id)
|
10
|
+
@channel_id = channel.id
|
11
|
+
end
|
12
|
+
|
13
|
+
# Reacts to a message
|
14
|
+
# @note To use custom emoji, you must encode it in the format name:id with the emoji name and emoji id
|
15
|
+
# @param [String] emoji
|
16
|
+
def react(emoji)
|
17
|
+
@net.request { DSU3::API::Message.react(_1, @channel_id, @id, emoji) }
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
data/lib/dsu3/data.rb
ADDED
data/lib/dsu3/dobject.rb
ADDED
data/lib/dsu3/errors.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module DSU3
|
4
|
+
class RateLimitError < StandardError
|
5
|
+
attr_reader :retry_after
|
6
|
+
|
7
|
+
def initialize(message, retry_after)
|
8
|
+
@message = message
|
9
|
+
@retry_after = retry_after
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
CodeError = Class.new(StandardError)
|
14
|
+
end
|
data/lib/dsu3/net.rb
CHANGED
@@ -1,55 +1,43 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'dsu3/
|
3
|
+
require 'dsu3/data'
|
4
4
|
|
5
5
|
module DSU3
|
6
6
|
# Class used to manage multiple bots
|
7
7
|
class Net
|
8
|
+
attr_reader :tokens, :mutex
|
9
|
+
|
8
10
|
# @param [Array] tokens List of bot tokens
|
9
11
|
def initialize(*tokens)
|
10
|
-
|
11
|
-
end
|
12
|
-
|
13
|
-
# (see DSU3::API::Channel#type)
|
14
|
-
def typespam(channel)
|
15
|
-
loop do
|
16
|
-
@tokens.each { |token| DSU3::API::Channel.type(token, channel) }
|
17
|
-
sleep 9
|
18
|
-
end
|
19
|
-
end
|
12
|
+
raise 'There must be at least one token' if tokens.empty?
|
20
13
|
|
21
|
-
|
22
|
-
|
23
|
-
@tokens.each { |token| DSU3::API::Channel.send(token, channel, message) }
|
14
|
+
@tokens = tokens
|
15
|
+
@mutex = Mutex.new
|
24
16
|
end
|
25
17
|
|
26
|
-
#
|
27
|
-
# @param [
|
28
|
-
|
29
|
-
|
30
|
-
loop do
|
31
|
-
@tokens.each { |token| DSU3::API::Channel.send(token, channel, block.call) }
|
32
|
-
end
|
33
|
-
end
|
18
|
+
# An auxiliary method that can be used to make an Discord API call from multiple tokens with ratelimit and thread support
|
19
|
+
# @param [Hash] opts Options
|
20
|
+
def request(opts = {})
|
21
|
+
opts = { cooldown: 0, loop: false }.merge(opts)
|
34
22
|
|
35
|
-
# (see DSU3::API::Invite#join)
|
36
|
-
def join(invite)
|
37
23
|
@tokens.each do |token|
|
38
|
-
|
39
|
-
|
24
|
+
Thread.new do
|
25
|
+
begin
|
26
|
+
@mutex.synchronize { yield token }
|
27
|
+
sleep(opts[:cooldown])
|
28
|
+
rescue DSU3::RateLimitError => e
|
29
|
+
DSU3::LOGGER.warn('ratelimit exceeded')
|
30
|
+
@mutex.sleep(e.retry_after)
|
31
|
+
retry
|
32
|
+
end while opts[:loop]
|
33
|
+
end.join
|
40
34
|
end
|
41
35
|
end
|
42
36
|
|
43
|
-
#
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
# (see DSU3::API::Guild#verify)
|
49
|
-
def verify(guild, invite)
|
50
|
-
@tokens.each do |token|
|
51
|
-
DSU3::API::Guild.verify(token, guild, invite)
|
52
|
-
sleep(0.5)
|
37
|
+
# I'm too lazy to try to document it
|
38
|
+
%w[channel guild invite].each do |s|
|
39
|
+
define_method s do |id|
|
40
|
+
DSU3.const_get(s.capitalize).new(self, id)
|
53
41
|
end
|
54
42
|
end
|
55
43
|
end
|
data/lib/dsu3/props.rb
CHANGED
@@ -8,30 +8,34 @@ module DSU3
|
|
8
8
|
# user-agent header
|
9
9
|
USER_AGENT = 'Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Firefox/91.0'
|
10
10
|
|
11
|
-
|
11
|
+
module_function
|
12
12
|
|
13
13
|
# Fetches Discord client build number
|
14
|
-
def
|
15
|
-
JSON.parse(
|
14
|
+
def fetch_build_number
|
15
|
+
JSON.parse(
|
16
|
+
RestClient.get('https://api.github.com/repos/Discord-Datamining/Discord-Datamining/commits/master')
|
17
|
+
)['commit']['message'].match(/Build (\d+)/)[1]
|
16
18
|
end
|
17
19
|
|
18
|
-
#
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
20
|
+
# Generates x-super-properties header
|
21
|
+
def generate_x_super_properties
|
22
|
+
Base64.strict_encode64(JSON.generate(
|
23
|
+
os: 'Linux',
|
24
|
+
browser: 'Firefox',
|
25
|
+
device: '',
|
26
|
+
system_locale: 'en',
|
27
|
+
browser_user_agent: USER_AGENT,
|
28
|
+
browser_version: '91.0',
|
29
|
+
os_version: '',
|
30
|
+
referrer: '',
|
31
|
+
referring_domain: '',
|
32
|
+
referrer_current: '',
|
33
|
+
referring_domain_current: '',
|
34
|
+
release_channel: 'stable',
|
35
|
+
client_build_number: fetch_build_number,
|
36
|
+
client_event_source: nil
|
37
|
+
))
|
38
|
+
end
|
35
39
|
|
36
40
|
resp = RestClient.get('https://discord.com/api/v9/experiments')
|
37
41
|
|
@@ -50,7 +54,7 @@ module DSU3
|
|
50
54
|
user_agent: USER_AGENT,
|
51
55
|
x_debug_options: 'bugReporterEnabled',
|
52
56
|
x_discord_locale: 'en-US',
|
53
|
-
x_super_properties:
|
57
|
+
x_super_properties: generate_x_super_properties,
|
54
58
|
content_type: 'application/json',
|
55
59
|
cookie: HTTP::Cookie.cookie_value(resp.cookie_jar.cookies),
|
56
60
|
x_fingerprint: JSON.parse(resp.body)['fingerprint']
|
data/lib/dsu3/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dsu3
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Artur Sheremetjev IV
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rest-client
|
@@ -39,6 +39,15 @@ files:
|
|
39
39
|
- lib/dsu3/api/channel.rb
|
40
40
|
- lib/dsu3/api/guild.rb
|
41
41
|
- lib/dsu3/api/invite.rb
|
42
|
+
- lib/dsu3/api/message.rb
|
43
|
+
- lib/dsu3/api/user.rb
|
44
|
+
- lib/dsu3/data.rb
|
45
|
+
- lib/dsu3/data/channel.rb
|
46
|
+
- lib/dsu3/data/guild.rb
|
47
|
+
- lib/dsu3/data/invite.rb
|
48
|
+
- lib/dsu3/data/message.rb
|
49
|
+
- lib/dsu3/dobject.rb
|
50
|
+
- lib/dsu3/errors.rb
|
42
51
|
- lib/dsu3/net.rb
|
43
52
|
- lib/dsu3/props.rb
|
44
53
|
- lib/dsu3/version.rb
|