This repository has been archived on 2023-04-26. You can view files and clone it, but cannot push or open issues or pull requests.
nimcord/src/nimcordutils.nim

89 lines
3.2 KiB
Nim
Raw Normal View History

2020-06-17 05:34:23 +00:00
import parseutils, json, httpClient, strformat, tables, times, asyncdispatch
2020-05-31 05:10:18 +00:00
from discordobject import snowflake
proc getIDFromJson*(str: string): uint64 =
var num: uint64
2020-06-18 03:16:58 +00:00
discard parseBiggestUInt(str, num)
2020-05-31 05:10:18 +00:00
return num
2020-06-17 05:34:23 +00:00
proc endpoint*(url: string): string =
return fmt("https://discord.com/api/v6{url}")
2020-05-31 05:10:18 +00:00
2020-06-17 05:34:23 +00:00
type
RateLimitBucketType* = enum
channel,
guild,
webhook,
global
RateLimit = ref object {.requiresInit.}
limit: int
remainingLimit: int
ratelimitReset: float
proc newRateLimit(lmt: int = 500, remLmnt: int = 500, ratelmtReset: float = 0): RateLimit =
return RateLimit(limit: lmt, remainingLimit: remLmnt, ratelimitReset: ratelmtReset)
# Rate limit buckets
let channelRatelimitBucket = newTable[snowflake, RateLimit]()
let guildRatelimitBucket = newTable[snowflake, RateLimit]()
let webhookRatelimitBucket = newTable[snowflake, RateLimit]()
var globalRateLimit: RateLimit = newRateLimit()
proc handleRateLimits*(headers: HttpHeaders, objectID: snowflake, bucketType: RateLimitBucketType) =
var obj: RateLimit
if (headers.hasKey("x-ratelimit-global")):
obj = globalRateLimit
elif (headers.hasKey("x-ratelimit-limit")):
case bucketType:
of RateLimitBucketType.channel:
obj = channelRatelimitBucket[objectID]
discard
of RateLimitBucketType.guild:
obj = guildRatelimitBucket[objectID]
discard
of RateLimitBucketType.webhook:
obj = webhookRatelimitBucket[objectID]
discard
of RateLimitBucketType.global:
obj = globalRateLimit
discard
else:
return
discard parseInt(headers["x-ratelimit-limit"], obj.limit)
discard parseInt(headers["x-ratelimit-remaining"], obj.remainingLimit)
discard parseFloat(headers["x-ratelimit-reset"], obj.ratelimitReset)
proc handleResponse*(response: Response, objectID: snowflake, bucketType: RateLimitBucketType): JsonNode =
echo fmt("Received requested payload: {response.body}")
handleRateLimits(response.headers, objectID, bucketType)
return parseJson(response.body())
proc waitForRateLimits*(objectID: snowflake, bucketType: RateLimitBucketType) =
var rlmt: RateLimit
if (globalRateLimit.remainingLimit == 0):
rlmt = globalRateLimit
else:
case bucketType:
of RateLimitBucketType.channel:
rlmt = channelRatelimitBucket[objectID]
discard
of RateLimitBucketType.guild:
rlmt = guildRatelimitBucket[objectID]
discard
of RateLimitBucketType.webhook:
rlmt = webhookRatelimitBucket[objectID]
discard
of RateLimitBucketType.global:
rlmt = globalRateLimit
discard
if (rlmt.remainingLimit == 0):
let millisecondTime: float = rlmt.ratelimitReset * 1000 - epochTime() * 1000
if (millisecondTime > 0):
echo fmt("Rate limit wait time: {millisecondTime} miliseconds")
discard sleepAsync(millisecondTime)