From 7f00441a713e514c236dc849e466579a0f5d4bb1 Mon Sep 17 00:00:00 2001 From: Tellow Krinkle Date: Sat, 28 Jul 2018 23:24:43 +0900 Subject: [PATCH 01/16] Added multiple message send feature --- .../DiscordEndpointConsumer+Channels.swift | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift index 3e9b05c04..e7de61075 100644 --- a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift +++ b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift @@ -338,6 +338,51 @@ public extension DiscordEndpointConsumer where Self: DiscordUserActor { callback: requestCallback) } + /** + Sends multiple messages in a row + + Guarantees that the messages will be sent (and received by Discord) in the specified order + - parameter messages: The list of messages to send + - parameter channelID: The ID of the channel to send the messages to + - parameter callback: The function that will be called after all messages are sent or one fails to send. + The HTTPURLResponse will be from the last attempt to send a message (first failure or final success). + If all messages were sent successfully, the length of the array will be the same as the length of the input. + Otherwise, the callback's array will be shorter. + */ + public func sendMessages(_ messages: [DiscordMessage], + to channelID: ChannelID, + callback: (([DiscordMessage], HTTPURLResponse?) -> ())? = nil ) { + guard let firstMessage = messages.first else { + callback?([], nil) + return + } + + var messagesToSend = messages.dropFirst() + var sentMessages: [DiscordMessage] = [] + + // This function strongly captures `self` (which, being a protocol that doesn't require + // its implementors to be classes, can't be made weak). It shouldn't lead to any reference + // cycles due to the fact that `self` never holds onto a reference to the function. + // It does, however, keep `self` alive until all messages are sent. If this is undesirable, + // maybe we should include an `: AnyClass` on `DiscordEndpointConsumer` + func handlerFunc(sentMessage: DiscordMessage?, response: HTTPURLResponse?) { + guard let sentMessage = sentMessage else { + callback?(sentMessages, response) + return + } + if (callback != nil) { // Save a bit of memory in the case that we won't need `sentMessages` + sentMessages.append(sentMessage) + } + guard let nextMessage = messagesToSend.first else { + callback?(sentMessages, response) + return + } + messagesToSend = messagesToSend.dropFirst() + sendMessage(nextMessage, to: channelID, callback: handlerFunc) + } + sendMessage(firstMessage, to: channelID, callback: handlerFunc) + } + /// Default implementation public func triggerTyping(on channelId: ChannelID, callback: ((Bool, HTTPURLResponse?) -> ())? = nil) { From 02cd0d3ae14e841c79a53a269cf5a2507f9c4fc4 Mon Sep 17 00:00:00 2001 From: tellowkrinkle Date: Tue, 31 Jul 2018 04:11:58 +0900 Subject: [PATCH 02/16] Remove unnecessary parentheses This is Swift, not C --- .../SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift index e7de61075..e51866b77 100644 --- a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift +++ b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift @@ -370,7 +370,7 @@ public extension DiscordEndpointConsumer where Self: DiscordUserActor { callback?(sentMessages, response) return } - if (callback != nil) { // Save a bit of memory in the case that we won't need `sentMessages` + if callback != nil { // Save a bit of memory in the case that we won't need `sentMessages` sentMessages.append(sentMessage) } guard let nextMessage = messagesToSend.first else { From 0f41e21c272d5d1ed32ac348ca1080a8ce8b310d Mon Sep 17 00:00:00 2001 From: Erik Little Date: Thu, 23 Aug 2018 16:07:15 -0400 Subject: [PATCH 03/16] fix linux build --- .travis/before_install.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis/before_install.sh b/.travis/before_install.sh index 14e399a6f..6b54db2c1 100755 --- a/.travis/before_install.sh +++ b/.travis/before_install.sh @@ -12,9 +12,9 @@ else sudo apt-get install swift vapor libopus-dev # Sodium - wget https://download.libsodium.org/libsodium/releases/libsodium-1.0.13.tar.gz - tar -xzf libsodium-1.0.13.tar.gz - cd libsodium-1.0.13 + wget https://download.libsodium.org/libsodium/releases/libsodium-1.0.16.tar.gz + tar -xzf libsodium-1.0.16.tar.gz + cd libsodium-1.0.16 ./configure --prefix=/usr/ make sudo make install From 510c55131c0dbce8d76c6672655b86ff3fd5ad46 Mon Sep 17 00:00:00 2001 From: Tellow Krinkle Date: Fri, 5 Oct 2018 23:13:02 -0500 Subject: [PATCH 04/16] Hopefully fix DiscordGatewayPayloadData.dataFromDictionary on Swift 4.2 Linux --- Sources/SwiftDiscord/Gateway/DiscordGateway.swift | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/Sources/SwiftDiscord/Gateway/DiscordGateway.swift b/Sources/SwiftDiscord/Gateway/DiscordGateway.swift index a6ac78f65..c55cda3e4 100644 --- a/Sources/SwiftDiscord/Gateway/DiscordGateway.swift +++ b/Sources/SwiftDiscord/Gateway/DiscordGateway.swift @@ -164,29 +164,16 @@ extension DiscordGatewayPayloadData { guard let data = data else { return .null } // TODO this is very ugly. See https://bugs.swift.org/browse/SR-5863 - #if !os(Linux) switch data { case let object as [String: Any]: return .object(object) - case let number as NSNumber where number === kCFBooleanTrue || number === kCFBooleanFalse: + case let number as NSNumber where number === (true as NSNumber) || number === (false as NSNumber): return .bool(number.boolValue) case let integer as Int: return .integer(integer) default: return .null } - #else - switch data { - case let object as [String: Any]: - return .object(object) - case let bool as Bool: - return .bool(bool) - case let integer as Int: - return .integer(integer) - default: - return .null - } - #endif } } From e7a04e94d8ab82d27a8ff47d33afa8a99e72b127 Mon Sep 17 00:00:00 2001 From: Tellow Krinkle Date: Mon, 4 Feb 2019 15:28:09 -0600 Subject: [PATCH 05/16] Fix calls to crypto_secretbox_easy I think we were doing the wrong thing the whole time, not sure why the compiler was okay with it before --- Sources/SwiftDiscord/Voice/DiscordVoiceEngine.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftDiscord/Voice/DiscordVoiceEngine.swift b/Sources/SwiftDiscord/Voice/DiscordVoiceEngine.swift index 24b135a01..6afba617d 100644 --- a/Sources/SwiftDiscord/Voice/DiscordVoiceEngine.swift +++ b/Sources/SwiftDiscord/Voice/DiscordVoiceEngine.swift @@ -232,7 +232,7 @@ public final class DiscordVoiceEngine : DiscordVoiceEngineSpec { defer { encrypted.deallocate() } - let success = crypto_secretbox_easy(encrypted, &buf, UInt64(buf.count), &nonce, &secret!) + let success = crypto_secretbox_easy(encrypted, &buf, UInt64(buf.count), &nonce, secret!) guard success != -1 else { throw EngineError.encryptionError } @@ -252,7 +252,7 @@ public final class DiscordVoiceEngine : DiscordVoiceEngineSpec { defer { unencrypted.deallocate() } - let success = crypto_secretbox_open_easy(unencrypted, voiceData, UInt64(data.count - 12), &nonce, &secret!) + let success = crypto_secretbox_open_easy(unencrypted, voiceData, UInt64(data.count - 12), &nonce, secret!) guard success != -1 else { throw EngineError.decryptionError } From bebe2529327a0797ef3cbe10cf01135607b29657 Mon Sep 17 00:00:00 2001 From: Tellow Krinkle Date: Mon, 4 Feb 2019 15:40:17 -0600 Subject: [PATCH 06/16] Don't `&` const pointers They're not required and make it look like things are modifiable even though they're not --- Sources/SwiftDiscord/Voice/DiscordVoiceEngine.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/SwiftDiscord/Voice/DiscordVoiceEngine.swift b/Sources/SwiftDiscord/Voice/DiscordVoiceEngine.swift index 6afba617d..2bd5cd96c 100644 --- a/Sources/SwiftDiscord/Voice/DiscordVoiceEngine.swift +++ b/Sources/SwiftDiscord/Voice/DiscordVoiceEngine.swift @@ -232,7 +232,7 @@ public final class DiscordVoiceEngine : DiscordVoiceEngineSpec { defer { encrypted.deallocate() } - let success = crypto_secretbox_easy(encrypted, &buf, UInt64(buf.count), &nonce, secret!) + let success = crypto_secretbox_easy(encrypted, buf, UInt64(buf.count), nonce, secret) guard success != -1 else { throw EngineError.encryptionError } @@ -252,7 +252,7 @@ public final class DiscordVoiceEngine : DiscordVoiceEngineSpec { defer { unencrypted.deallocate() } - let success = crypto_secretbox_open_easy(unencrypted, voiceData, UInt64(data.count - 12), &nonce, secret!) + let success = crypto_secretbox_open_easy(unencrypted, voiceData, UInt64(data.count - 12), nonce, secret) guard success != -1 else { throw EngineError.decryptionError } From e8f223ef0816e805a7f1047457448e2eecd5c3a6 Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 6 Apr 2019 00:20:18 +0200 Subject: [PATCH 07/16] Add message reaction endpoints --- Package.resolved | 27 ------------------- .../SwiftDiscord/Rest/DiscordEndpoint.swift | 17 ++++++++++++ .../Rest/DiscordRateLimiter.swift | 3 +++ 3 files changed, 20 insertions(+), 27 deletions(-) diff --git a/Package.resolved b/Package.resolved index a1c76345a..d6687f82e 100644 --- a/Package.resolved +++ b/Package.resolved @@ -10,15 +10,6 @@ "version": "1.1.0" } }, - { - "package": "SSCommonCrypto", - "repositoryURL": "https://github.com/daltoniam/common-crypto-spm", - "state": { - "branch": null, - "revision": "2eb3aff0fb57f92f5722fac5d6d20bf64669ca66", - "version": "1.1.0" - } - }, { "package": "COPUS", "repositoryURL": "https://github.com/nuclearace/copus", @@ -100,15 +91,6 @@ "version": "2.0.0" } }, - { - "package": "Starscream", - "repositoryURL": "https://github.com/daltoniam/Starscream", - "state": { - "branch": null, - "revision": "114e5df9b6251970a069e8f1c0cbb5802759f0a9", - "version": "3.0.5" - } - }, { "package": "TLS", "repositoryURL": "https://github.com/vapor/tls.git", @@ -117,15 +99,6 @@ "revision": "02a47309249e69358aa3c28b5853897585d7a750", "version": "2.1.2" } - }, - { - "package": "SSCZLib", - "repositoryURL": "https://github.com/daltoniam/zlib-spm.git", - "state": { - "branch": null, - "revision": "83ac8d719a2f3aa775dbdf116a57f56fb2c49abb", - "version": "1.1.0" - } } ] }, diff --git a/Sources/SwiftDiscord/Rest/DiscordEndpoint.swift b/Sources/SwiftDiscord/Rest/DiscordEndpoint.swift index 8ce3f8d50..ee5040fdb 100644 --- a/Sources/SwiftDiscord/Rest/DiscordEndpoint.swift +++ b/Sources/SwiftDiscord/Rest/DiscordEndpoint.swift @@ -51,6 +51,13 @@ public enum DiscordEndpoint : CustomStringConvertible { /// The channel typing endpoint. case typing(channel: ChannelID) + // Reactions + /// The endpoint for creating/deleting own reactions. + case reactions(channel: ChannelID, message: MessageID, emoji: String) + + /// The endpoint for another user's reactions + case userReactions(channel: ChannelID, message: MessageID, emoji: String, user: UserID) + // Permissions /// The base channel permissions endpoint. case permissions(channel: ChannelID) @@ -264,6 +271,11 @@ public extension DiscordEndpoint { return "/channels/\(channel)/messages/\(message)" case let .typing(channel): return "/channels/\(channel)/typing" + // Reactions + case let .reactions(channel, message, emoji): + return "/channels/\(channel)/messages/\(message)/reactions/\(emoji)/@me" + case let .userReactions(channel, message, emoji, user): + return "/channels/\(channel)/messages/\(message)/reactions/\(emoji)/\(user)" // Permissions case let .permissions(channel): return "/channels/\(channel)/permissions" @@ -362,6 +374,11 @@ public extension DiscordEndpoint { return DiscordRateLimitKey(id: channel, urlParts: [.channels, .channelID, .messagesDelete, .messageID]) case let .typing(channel): return DiscordRateLimitKey(id: channel, urlParts: [.channels, .channelID, .typing]) + // Reactions + case let .reactions(channel, _, _): + return DiscordRateLimitKey(id: channel, urlParts: [.channels, .channelID, .messages, .messageID, .reactions, .emoji, .me]) + case let .userReactions(channel, _, _, _): + return DiscordRateLimitKey(id: channel, urlParts: [.channels, .channelID, .messages, .messageID, .reactions, .emoji, .userID]) // Permissions case let .permissions(channel): return DiscordRateLimitKey(id: channel, urlParts: [.channels, .channelID, .permissions]) diff --git a/Sources/SwiftDiscord/Rest/DiscordRateLimiter.swift b/Sources/SwiftDiscord/Rest/DiscordRateLimiter.swift index 594c6e3c4..4398b88c3 100644 --- a/Sources/SwiftDiscord/Rest/DiscordRateLimiter.swift +++ b/Sources/SwiftDiscord/Rest/DiscordRateLimiter.swift @@ -245,6 +245,9 @@ public struct DiscordRateLimitKey : Hashable { static let slack = DiscordRateLimitURLParts(rawValue: 1 << 23) static let github = DiscordRateLimitURLParts(rawValue: 1 << 24) static let auditLog = DiscordRateLimitURLParts(rawValue: 1 << 25) + static let reactions = DiscordRateLimitURLParts(rawValue: 1 << 26) + static let emoji = DiscordRateLimitURLParts(rawValue: 1 << 27) + static let me = DiscordRateLimitURLParts(rawValue: 1 << 28) public init(rawValue: Int) { self.rawValue = rawValue From 42511b197801e3636e3d44e0f505fd4ef2a1133c Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 6 Apr 2019 00:35:18 +0200 Subject: [PATCH 08/16] Add DiscordEndpointConsumer.createReaction --- .../DiscordEndpointConsumer+Channels.swift | 20 +++++++++++++++++++ .../Rest/DiscordEndpointConsumer.swift | 13 ++++++++++++ 2 files changed, 33 insertions(+) diff --git a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift index e51866b77..05bf6f497 100644 --- a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift +++ b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift @@ -83,6 +83,26 @@ public extension DiscordEndpointConsumer where Self: DiscordUserActor { callback: requestCallback) } + /// Default implementation + public func createReaction(for messageId: MessageID, + on channelId: ChannelID, + emoji: String, + callback: ((DiscordMessage?, HTTPURLResponse?) -> ())?) { + let requestCallback: DiscordRequestCallback = { data, response, error in + guard case let .object(message)? = JSON.jsonFromResponse(data: data, response: response) else { + callback?(nil, response) + return + } + + callback?(DiscordMessage(messageObject: message, client: nil), response) + } + + rateLimiter.executeRequest(endpoint: .reactions(channel: channelId, message: messageId, emoji: emoji), + token: token, + requestInfo: .put(content: nil, extraHeaders: nil), + callback: requestCallback) + } + /// Default implementation public func deleteChannel(_ channelId: ChannelID, reason: String? = nil, diff --git a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer.swift b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer.swift index f3ee8b919..0ce041d54 100644 --- a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer.swift +++ b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer.swift @@ -69,6 +69,19 @@ public protocol DiscordEndpointConsumer { reason: String?, callback: @escaping (DiscordInvite?, HTTPURLResponse?) -> ()) + /// + /// Creates a reaction for the specified message. + /// + /// - parameter for: The message that is to be edited's snowflake id + /// - parameter on: The channel that we are editing on + /// - parameter emoji: The emoji name + /// - parameter callback: An optional callback containing the edited message, if successful. + /// + func createReaction(for messageId: MessageID, + on channelId: ChannelID, + emoji: String, + callback: ((DiscordMessage?, HTTPURLResponse?) -> ())?) + /// /// Deletes the specified channel. /// From acd369c47be81f38f0551530b5d3f0259fe16626 Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 6 Apr 2019 01:01:05 +0200 Subject: [PATCH 09/16] Set callback in DiscordEndpointConsumer.createReaction to nil by default --- .../SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift index 05bf6f497..696f9ef70 100644 --- a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift +++ b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift @@ -87,7 +87,7 @@ public extension DiscordEndpointConsumer where Self: DiscordUserActor { public func createReaction(for messageId: MessageID, on channelId: ChannelID, emoji: String, - callback: ((DiscordMessage?, HTTPURLResponse?) -> ())?) { + callback: ((DiscordMessage?, HTTPURLResponse?) -> ())? = nil) { let requestCallback: DiscordRequestCallback = { data, response, error in guard case let .object(message)? = JSON.jsonFromResponse(data: data, response: response) else { callback?(nil, response) From 4c19a3b30ace6c414f51d55b93d3299ef4b3806e Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 6 Apr 2019 01:20:06 +0200 Subject: [PATCH 10/16] URL-encode emojis --- .../SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift index 696f9ef70..343570188 100644 --- a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift +++ b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift @@ -97,7 +97,7 @@ public extension DiscordEndpointConsumer where Self: DiscordUserActor { callback?(DiscordMessage(messageObject: message, client: nil), response) } - rateLimiter.executeRequest(endpoint: .reactions(channel: channelId, message: messageId, emoji: emoji), + rateLimiter.executeRequest(endpoint: .reactions(channel: channelId, message: messageId, emoji: emoji.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)), token: token, requestInfo: .put(content: nil, extraHeaders: nil), callback: requestCallback) From 4582c77544aed60c1962650bb94be93d4c59540f Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 6 Apr 2019 01:22:33 +0200 Subject: [PATCH 11/16] Add HTTP 204 to the allowed reponse status codes --- Sources/SwiftDiscord/DiscordJSON.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftDiscord/DiscordJSON.swift b/Sources/SwiftDiscord/DiscordJSON.swift index 2d9555346..d05ebdf8a 100644 --- a/Sources/SwiftDiscord/DiscordJSON.swift +++ b/Sources/SwiftDiscord/DiscordJSON.swift @@ -66,7 +66,7 @@ enum JSON { return nil } - guard response.statusCode == 200 || response.statusCode == 201 else { + guard response.statusCode == 200 || response.statusCode == 201 || response.statusCode == 204 else { DefaultDiscordLogger.Logger.error("Invalid response code \(response.statusCode)", type: "JSON") DefaultDiscordLogger.Logger.error("Response: \(stringData)", type: "JSON") From d67df86845204c63297e35a8767d627dd55a97bd Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 6 Apr 2019 01:24:42 +0200 Subject: [PATCH 12/16] Handle 204 response separately --- Sources/SwiftDiscord/DiscordJSON.swift | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Sources/SwiftDiscord/DiscordJSON.swift b/Sources/SwiftDiscord/DiscordJSON.swift index d05ebdf8a..99c918778 100644 --- a/Sources/SwiftDiscord/DiscordJSON.swift +++ b/Sources/SwiftDiscord/DiscordJSON.swift @@ -66,7 +66,13 @@ enum JSON { return nil } - guard response.statusCode == 200 || response.statusCode == 201 || response.statusCode == 204 else { + guard response.statusCode != 204 else { + DefaultDiscordLogger.Logger.debug("Response code 204: No content") + + return nil + } + + guard response.statusCode == 200 || response.statusCode == 201 else { DefaultDiscordLogger.Logger.error("Invalid response code \(response.statusCode)", type: "JSON") DefaultDiscordLogger.Logger.error("Response: \(stringData)", type: "JSON") From 4e0fc0055dbc960afd0d83ab94ad179bae0e924c Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 6 Apr 2019 01:27:45 +0200 Subject: [PATCH 13/16] Provide null coalescing default value in default implementation of DiscordEndpointChannel.createReaction --- .../SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift index 343570188..5abbfe5bd 100644 --- a/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift +++ b/Sources/SwiftDiscord/Rest/DiscordEndpointConsumer+Channels.swift @@ -97,7 +97,7 @@ public extension DiscordEndpointConsumer where Self: DiscordUserActor { callback?(DiscordMessage(messageObject: message, client: nil), response) } - rateLimiter.executeRequest(endpoint: .reactions(channel: channelId, message: messageId, emoji: emoji.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed)), + rateLimiter.executeRequest(endpoint: .reactions(channel: channelId, message: messageId, emoji: emoji.addingPercentEncoding(withAllowedCharacters: .urlHostAllowed) ?? emoji), token: token, requestInfo: .put(content: nil, extraHeaders: nil), callback: requestCallback) From 1d3748f69aaec4f01bcc89d3ae174ab76ce2b1ed Mon Sep 17 00:00:00 2001 From: fwcd Date: Sat, 6 Apr 2019 01:36:40 +0200 Subject: [PATCH 14/16] Add 'type' parameter to logging call in DiscordJSON.jsonFromResponse --- Sources/SwiftDiscord/DiscordJSON.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/SwiftDiscord/DiscordJSON.swift b/Sources/SwiftDiscord/DiscordJSON.swift index 99c918778..4f6a7d63f 100644 --- a/Sources/SwiftDiscord/DiscordJSON.swift +++ b/Sources/SwiftDiscord/DiscordJSON.swift @@ -67,7 +67,7 @@ enum JSON { } guard response.statusCode != 204 else { - DefaultDiscordLogger.Logger.debug("Response code 204: No content") + DefaultDiscordLogger.Logger.debug("Response code 204: No content", type: "JSON") return nil } From 0fc784cf510c86f957141a7083bbdb398e0ddf2c Mon Sep 17 00:00:00 2001 From: Tellow Krinkle Date: Sat, 9 Nov 2019 21:37:39 -0600 Subject: [PATCH 15/16] Remove DiscordOpus Use the new functions in COPUS instead --- Package.resolved | 4 +-- Package.swift | 5 ++- Sources/DiscordOpus/configure.c | 33 ------------------- Sources/DiscordOpus/include/configure.h | 26 --------------- .../Voice/DiscordOpusCoding.swift | 10 +++--- .../Voice/DiscordVoiceDataSource.swift | 1 - .../Voice/DiscordVoiceDecoder.swift | 1 - 7 files changed, 9 insertions(+), 71 deletions(-) delete mode 100644 Sources/DiscordOpus/configure.c delete mode 100644 Sources/DiscordOpus/include/configure.h diff --git a/Package.resolved b/Package.resolved index d6687f82e..43eff05c6 100644 --- a/Package.resolved +++ b/Package.resolved @@ -15,8 +15,8 @@ "repositoryURL": "https://github.com/nuclearace/copus", "state": { "branch": null, - "revision": "365743902efc1c93730757cea288bef4b90637a0", - "version": "2.0.0" + "revision": "a2af57fa582c0191789f446cc430615ee7e41d4f", + "version": "2.1.1" } }, { diff --git a/Package.swift b/Package.swift index a39195a2d..3b44ad532 100644 --- a/Package.swift +++ b/Package.swift @@ -20,12 +20,12 @@ import PackageDescription var deps: [Package.Dependency] = [ - .package(url: "https://github.com/nuclearace/copus", .upToNextMinor(from: "2.0.0")), + .package(url: "https://github.com/nuclearace/copus", .upToNextMinor(from: "2.1.1")), .package(url: "https://github.com/nuclearace/Sodium", .upToNextMinor(from: "2.0.0")), .package(url: "https://github.com/vapor/engine", .upToNextMinor(from: "2.2.0")), ] -var targetDeps: [Target.Dependency] = ["DiscordOpus", "WebSockets"] +var targetDeps: [Target.Dependency] = ["WebSockets"] #if !os(Linux) deps += [.package(url: "https://github.com/daltoniam/Starscream", .upToNextMinor(from: "3.0.0")),] @@ -41,7 +41,6 @@ let package = Package( dependencies: deps, targets: [ .target(name: "SwiftDiscord", dependencies: targetDeps), - .target(name: "DiscordOpus"), .testTarget(name: "SwiftDiscordTests", dependencies: ["SwiftDiscord"]), ] ) diff --git a/Sources/DiscordOpus/configure.c b/Sources/DiscordOpus/configure.c deleted file mode 100644 index 678a49c86..000000000 --- a/Sources/DiscordOpus/configure.c +++ /dev/null @@ -1,33 +0,0 @@ -// The MIT License (MIT) -// Copyright (c) 2017 Erik Little - -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -// documentation files (the "Software"), to deal in the Software without restriction, including without -// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the -// Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -// Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO -// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -#include "configure.h" - -int configure_encoder(OpusEncoder *enc, int bitrate, int vbr) -{ - int err; - - err = opus_encoder_ctl(enc, OPUS_SET_BITRATE(bitrate)); - err = opus_encoder_ctl(enc, OPUS_SET_VBR(vbr)); - - return err; -} - -int configure_decoder(OpusDecoder *dec, int gain) -{ - return opus_decoder_ctl(dec, OPUS_SET_GAIN(gain)); -} diff --git a/Sources/DiscordOpus/include/configure.h b/Sources/DiscordOpus/include/configure.h deleted file mode 100644 index 67c7b1577..000000000 --- a/Sources/DiscordOpus/include/configure.h +++ /dev/null @@ -1,26 +0,0 @@ -// The MIT License (MIT) -// Copyright (c) 2017 Erik Little - -// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated -// documentation files (the "Software"), to deal in the Software without restriction, including without -// limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the -// Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the -// Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING -// BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO -// EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN -// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. - -#ifndef configure_h -#define configure_h - -#include - -int configure_encoder(OpusEncoder *enc, int bitrate, int vbr); -int configure_decoder(OpusDecoder *dec, int gain); - -#endif /* configure_h */ diff --git a/Sources/SwiftDiscord/Voice/DiscordOpusCoding.swift b/Sources/SwiftDiscord/Voice/DiscordOpusCoding.swift index 2f55f23c7..f4276ca98 100644 --- a/Sources/SwiftDiscord/Voice/DiscordOpusCoding.swift +++ b/Sources/SwiftDiscord/Voice/DiscordOpusCoding.swift @@ -16,7 +16,6 @@ // DEALINGS IN THE SOFTWARE. import COPUS -import DiscordOpus import Foundation /// Declares that a type has enough information to encode/decode Opus data. @@ -93,9 +92,10 @@ open class DiscordOpusEncoder : DiscordOpusCodeable { var err = 0 as Int32 encoderState = opus_encoder_create(Int32(sampleRate), Int32(channels), OPUS_APPLICATION_VOIP, &err) - err = configure_encoder(encoderState, Int32(bitrate), vbr ? 1 : 0) + let err2 = opus_encoder_set_bitrate(encoderState, Int32(bitrate)) + let err3 = opus_encoder_set_vbr(encoderState, vbr ? 1 : 0) - guard err == 0 else { + guard err == 0, err2 == 0, err3 == 0 else { destroyState() throw DiscordVoiceError.creationFail @@ -163,9 +163,9 @@ open class DiscordOpusDecoder : DiscordOpusCodeable { var err = 0 as Int32 decoderState = opus_decoder_create(Int32(sampleRate), Int32(channels), &err) - err = configure_decoder(decoderState, Int32(gain)) + let err2 = opus_decoder_set_gain(decoderState, Int32(gain)) - guard err == 0 else { + guard err == 0, err2 == 0 else { destroyState() throw DiscordVoiceError.creationFail diff --git a/Sources/SwiftDiscord/Voice/DiscordVoiceDataSource.swift b/Sources/SwiftDiscord/Voice/DiscordVoiceDataSource.swift index b8541a33e..5b617be8e 100644 --- a/Sources/SwiftDiscord/Voice/DiscordVoiceDataSource.swift +++ b/Sources/SwiftDiscord/Voice/DiscordVoiceDataSource.swift @@ -16,7 +16,6 @@ // DEALINGS IN THE SOFTWARE. import COPUS -import DiscordOpus import Dispatch import Foundation diff --git a/Sources/SwiftDiscord/Voice/DiscordVoiceDecoder.swift b/Sources/SwiftDiscord/Voice/DiscordVoiceDecoder.swift index b1aeb0aa1..fbaee8e82 100644 --- a/Sources/SwiftDiscord/Voice/DiscordVoiceDecoder.swift +++ b/Sources/SwiftDiscord/Voice/DiscordVoiceDecoder.swift @@ -16,7 +16,6 @@ // DEALINGS IN THE SOFTWARE. import COPUS -import DiscordOpus import Foundation /// Class that decodes Opus voice data into raw PCM data for a VoiceEngine. It can decode multiple streams. Decoding is From 1f531d95741078e69896a3f7fb867fd72b4e050b Mon Sep 17 00:00:00 2001 From: Tellow Krinkle Date: Wed, 13 Nov 2019 23:12:32 -0600 Subject: [PATCH 16/16] Update readme You no longer need special flags hooray --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index aef7fefb7..3f8508f49 100644 --- a/README.md +++ b/README.md @@ -28,11 +28,11 @@ A Discord API client for Swift. - Create your Swift Package Manager project - Add `.package(url: "https://github.com/nuclearace/SwiftDiscord", .upToNextMajor(from: "6.0.0"))` to your dependencies in Package.swift - Add `import SwiftDiscord` to files you wish to use the module in. - - Run `swift build -Xlinker -L/usr/local/lib -Xlinker -lopus -Xcc -I/usr/local/include`. The Xlinker options are needed to tell the package manager where to find the libsodium and opus libraries that were installed through Homebrew. The Xcc option tells clang where to find the headers for opus. + - Run `swift build` Xcode: -If you wish to use Xcode with your Swift Package Manager project, you can do `swift package generate-xcodeproj`. However after doing that, you'll have to make a change to SwiftDiscord's build settings. Just like when compiling from the command line, we have to tell Xcode where to find libsodium and libopus. This can be done by adding `/usr/local/lib` to the library search paths and `/usr/local/include` to the header search paths. This should be done for the SwiftDiscord and DiscordOpus targets. The DiscordOpus target also needs the `-lopus` option in "Other Linker Flags". +If you wish to use Xcode with your Swift Package Manager project, you can do `swift package generate-xcodeproj`. In Xcode 11 and higher, you can also add SwiftDiscord as a dependency under the `Link Binary With Libraries` section of the `Build Phases` tab of an existing Xcode project. ![](https://i.imgur.com/JR97eTO.png)