remove DiscordBM dependency
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"originHash" : "8fae71593cfeba2ef52421241b82a32253b5dfcaf81f7533c3f5b0f981822d3a",
|
"originHash" : "219f2158581681a4b5edbd171ed8aebcd120092f145806d33067fb0cfbb93848",
|
||||||
"pins" : [
|
"pins" : [
|
||||||
{
|
{
|
||||||
"identity" : "async-http-client",
|
"identity" : "async-http-client",
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ let package = Package(
|
|||||||
.executableTarget(
|
.executableTarget(
|
||||||
name: "zundamon",
|
name: "zundamon",
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.product(name: "DiscordBM", package: "discordbm"),
|
|
||||||
.product(name: "SwiftDotenv", package: "swift-dotenv"),
|
.product(name: "SwiftDotenv", package: "swift-dotenv"),
|
||||||
.product(name: "XMLCoder", package: "xmlcoder"),
|
.product(name: "XMLCoder", package: "xmlcoder"),
|
||||||
.target(name: "DiscordKit")
|
.target(name: "DiscordKit")
|
||||||
|
|||||||
@@ -11,9 +11,7 @@ public struct Bot {
|
|||||||
|
|
||||||
let gatewayURL = try await client.getGatewayURL()
|
let gatewayURL = try await client.getGatewayURL()
|
||||||
|
|
||||||
print(gatewayURL.absoluteURL)
|
|
||||||
let gateway = GatewayClient(gatewayURL: gatewayURL)
|
let gateway = GatewayClient(gatewayURL: gatewayURL)
|
||||||
try await gateway.openConnection()
|
try await gateway.openConnection()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,40 +3,30 @@ import Foundation
|
|||||||
import FoundationNetworking
|
import FoundationNetworking
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct GatewayClient {
|
class GatewayClient {
|
||||||
let gatewayURL: URL
|
|
||||||
let ws: URLSessionWebSocketTask
|
let ws: URLSessionWebSocketTask
|
||||||
|
var sequenceNum: Int? = nil
|
||||||
|
|
||||||
init(gatewayURL: URL) {
|
init(gatewayURL: URL) {
|
||||||
self.gatewayURL = gatewayURL
|
|
||||||
ws = URLSession.shared.webSocketTask(with: gatewayURL.appending(component: "?v=10&encoding=json"))
|
ws = URLSession.shared.webSocketTask(with: gatewayURL.appending(component: "?v=10&encoding=json"))
|
||||||
}
|
}
|
||||||
|
|
||||||
func openConnection() {
|
func openConnection() async throws {
|
||||||
listen()
|
|
||||||
ws.resume()
|
ws.resume()
|
||||||
RunLoop.current.run()
|
guard case .hello(let helloMessage) = try await getMessage().d else { throw GatewayError.mismatchedOpcode }
|
||||||
|
dump(helloMessage)
|
||||||
|
Timer.scheduledTimer(withTimeInterval: (helloMessage.heartbeat_interval / 1000.0), repeats: true) {
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func listen() {
|
func getMessage() async throws -> GatewayMessage {
|
||||||
ws.receive { result in
|
let wsMessage = try await ws.receive()
|
||||||
defer { listen() }
|
guard case .string(let str) = wsMessage else { throw GatewayError.invalidMessage }
|
||||||
do {
|
|
||||||
if case .failure(let err) = result { throw err }
|
|
||||||
guard case .success(let message) = result else { return }
|
|
||||||
guard case .string(let str) = message else { throw GatewayError.invalidMessage }
|
|
||||||
let json = JSONDecoder()
|
let json = JSONDecoder()
|
||||||
let gwMessage = try json.decode(GatewayMessage.self, from: Data(str.utf8))
|
let gwMessage = try json.decode(GatewayMessage.self, from: Data(str.utf8))
|
||||||
switch gwMessage.d {
|
sequenceNum = gwMessage.s ?? sequenceNum
|
||||||
case .hello(let hello):
|
return gwMessage
|
||||||
dump(hello)
|
|
||||||
case .none:
|
|
||||||
return
|
|
||||||
}
|
|
||||||
} catch {
|
|
||||||
print(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -44,4 +34,5 @@ struct GatewayClient {
|
|||||||
public enum GatewayError: Error {
|
public enum GatewayError: Error {
|
||||||
case invalidMessage
|
case invalidMessage
|
||||||
case invalidOpcode
|
case invalidOpcode
|
||||||
|
case mismatchedOpcode
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ public enum GatewayPayload: Decodable {
|
|||||||
public struct GatewayMessage: Decodable {
|
public struct GatewayMessage: Decodable {
|
||||||
let op: Int
|
let op: Int
|
||||||
let d: GatewayPayload?
|
let d: GatewayPayload?
|
||||||
|
let s: Int?
|
||||||
|
let t: String?
|
||||||
|
|
||||||
enum CodingKeys: String, CodingKey {
|
enum CodingKeys: String, CodingKey {
|
||||||
case t
|
case t
|
||||||
@@ -34,6 +36,8 @@ public struct GatewayMessage: Decodable {
|
|||||||
public init(from decoder: Decoder) throws {
|
public init(from decoder: Decoder) throws {
|
||||||
let container = try decoder.container(keyedBy: CodingKeys.self)
|
let container = try decoder.container(keyedBy: CodingKeys.self)
|
||||||
op = try container.decode(Int.self, forKey: .op)
|
op = try container.decode(Int.self, forKey: .op)
|
||||||
|
s = try container.decode(Int?.self, forKey: .s)
|
||||||
|
t = try container.decode(String?.self, forKey: .t)
|
||||||
switch op {
|
switch op {
|
||||||
case 10:
|
case 10:
|
||||||
let hello = try container.decode(HelloPayload.self, forKey: .d)
|
let hello = try container.decode(HelloPayload.self, forKey: .d)
|
||||||
|
|||||||
@@ -1,107 +1,107 @@
|
|||||||
import DiscordBM
|
// import DiscordBM
|
||||||
|
//
|
||||||
struct Actions {
|
// struct Actions {
|
||||||
static func getUserFromMention(_ mention: MentionUser) -> String {
|
// static func getUserFromMention(_ mention: MentionUser) -> String {
|
||||||
mention.member?.nick ?? mention.global_name ?? mention.username
|
// mention.member?.nick ?? mention.global_name ?? mention.username
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static func performAction(ctx: Gateway.MessageCreate, client: DiscordClient, resOpts: [String]) async throws {
|
// static func performAction(ctx: Gateway.MessageCreate, client: DiscordClient, resOpts: [String]) async throws {
|
||||||
let author = "**\(ctx.member?.nick ?? ctx.author?.global_name ?? ctx.author?.username ?? "Zundamon")**"
|
// let author = "**\(ctx.member?.nick ?? ctx.author?.global_name ?? ctx.author?.username ?? "Zundamon")**"
|
||||||
let dests = ctx.mentions.map(getUserFromMention).map({ "**\($0)**" })
|
// let dests = ctx.mentions.map(getUserFromMention).map({ "**\($0)**" })
|
||||||
let orig: String
|
// let orig: String
|
||||||
let dest: String
|
// let dest: String
|
||||||
if let firstDest = dests.first {
|
// if let firstDest = dests.first {
|
||||||
orig = "\(author)"
|
// orig = "\(author)"
|
||||||
dest = "\(firstDest)"
|
// dest = "\(firstDest)"
|
||||||
} else {
|
// } else {
|
||||||
orig = "**Zundamon**"
|
// orig = "**Zundamon**"
|
||||||
dest = "\(author)"
|
// dest = "\(author)"
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
guard let res = resOpts.randomElement()?
|
// guard let res = resOpts.randomElement()?
|
||||||
.replacingOccurrences(of: "{orig}", with: orig)
|
// .replacingOccurrences(of: "{orig}", with: orig)
|
||||||
.replacingOccurrences(of: "{dest}", with: dest)
|
// .replacingOccurrences(of: "{dest}", with: dest)
|
||||||
else { print("retOptions empty"); return }
|
// else { print("retOptions empty"); return }
|
||||||
|
//
|
||||||
let retMsg = res
|
// let retMsg = res
|
||||||
|
//
|
||||||
try await client.createMessage(
|
// try await client.createMessage(
|
||||||
channelId: ctx.channel_id,
|
// channelId: ctx.channel_id,
|
||||||
payload: .init(
|
// payload: .init(
|
||||||
embeds: [.init(description: retMsg)],
|
// embeds: [.init(description: retMsg)],
|
||||||
)
|
// )
|
||||||
).guardSuccess()
|
// ).guardSuccess()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static let hugRes = (try? String(contentsOfFile: "resources/choices/hug.txt", encoding: .utf8))?
|
// static let hugRes = (try? String(contentsOfFile: "resources/choices/hug.txt", encoding: .utf8))?
|
||||||
.split(separator: "\n")
|
// .split(separator: "\n")
|
||||||
.map({ $0.trimmingCharacters(in: .whitespacesAndNewlines) })
|
// .map({ $0.trimmingCharacters(in: .whitespacesAndNewlines) })
|
||||||
|
//
|
||||||
static func hug(
|
// static func hug(
|
||||||
_ args: ArraySlice<String.SubSequence>,
|
// _ args: ArraySlice<String.SubSequence>,
|
||||||
client: DiscordClient,
|
// client: DiscordClient,
|
||||||
ctx: Gateway.MessageCreate
|
// ctx: Gateway.MessageCreate
|
||||||
) async throws {
|
// ) async throws {
|
||||||
guard let hugRes = hugRes else { print("hug.txt not loaded"); return }
|
// guard let hugRes = hugRes else { print("hug.txt not loaded"); return }
|
||||||
let author = "**\(ctx.member?.nick ?? ctx.author?.global_name ?? ctx.author?.username ?? "Zundamon")**"
|
// let author = "**\(ctx.member?.nick ?? ctx.author?.global_name ?? ctx.author?.username ?? "Zundamon")**"
|
||||||
let dests = ctx.mentions.map(getUserFromMention).map({ "**\($0)**" })
|
// let dests = ctx.mentions.map(getUserFromMention).map({ "**\($0)**" })
|
||||||
|
//
|
||||||
let retMsg: String
|
// let retMsg: String
|
||||||
|
//
|
||||||
if dests.count > 1 {
|
// if dests.count > 1 {
|
||||||
let groupHugs = [
|
// let groupHugs = [
|
||||||
"{subjects} all huddled together.",
|
// "{subjects} all huddled together.",
|
||||||
"{subjects} hugged each other pairwise, generating a total of **{total}** hugs.",
|
// "{subjects} hugged each other pairwise, generating a total of **{total}** hugs.",
|
||||||
"{subjects} hugged each other at the same time in the same place (although I'm not sure how that works with the current understanding of spacetime).",
|
// "{subjects} hugged each other at the same time in the same place (although I'm not sure how that works with the current understanding of spacetime).",
|
||||||
]
|
// ]
|
||||||
|
//
|
||||||
let group = [author] + dests
|
// let group = [author] + dests
|
||||||
let total = String(group.count)
|
// let total = String(group.count)
|
||||||
let subjects = String(group.joined(by: ", "))
|
// let subjects = String(group.joined(by: ", "))
|
||||||
|
//
|
||||||
guard let res = groupHugs.randomElement()?
|
// guard let res = groupHugs.randomElement()?
|
||||||
.replacingOccurrences(of: "{subjects}", with: subjects)
|
// .replacingOccurrences(of: "{subjects}", with: subjects)
|
||||||
.replacingOccurrences(of: "{total}", with: total)
|
// .replacingOccurrences(of: "{total}", with: total)
|
||||||
else { print("groupHugs.randomElement() returned null"); return }
|
// else { print("groupHugs.randomElement() returned null"); return }
|
||||||
|
//
|
||||||
retMsg = res
|
// retMsg = res
|
||||||
} else {
|
// } else {
|
||||||
let orig: String
|
// let orig: String
|
||||||
let dest: String
|
// let dest: String
|
||||||
if let firstDest = dests.first {
|
// if let firstDest = dests.first {
|
||||||
orig = "\(author)"
|
// orig = "\(author)"
|
||||||
dest = "\(firstDest)"
|
// dest = "\(firstDest)"
|
||||||
} else {
|
// } else {
|
||||||
orig = "**Zundamon**"
|
// orig = "**Zundamon**"
|
||||||
dest = "\(author)"
|
// dest = "\(author)"
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
guard let res = hugRes.randomElement()?
|
// guard let res = hugRes.randomElement()?
|
||||||
.replacingOccurrences(of: "{orig}", with: orig)
|
// .replacingOccurrences(of: "{orig}", with: orig)
|
||||||
.replacingOccurrences(of: "{dest}", with: dest)
|
// .replacingOccurrences(of: "{dest}", with: dest)
|
||||||
else { print("hug.txt empty"); return }
|
// else { print("hug.txt empty"); return }
|
||||||
|
//
|
||||||
retMsg = res
|
// retMsg = res
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
try await client.createMessage(
|
// try await client.createMessage(
|
||||||
channelId: ctx.channel_id,
|
// channelId: ctx.channel_id,
|
||||||
payload: .init(
|
// payload: .init(
|
||||||
embeds: [.init(description: retMsg)],
|
// embeds: [.init(description: retMsg)],
|
||||||
)
|
// )
|
||||||
).guardSuccess()
|
// ).guardSuccess()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static let patRes = (try? String(contentsOfFile: "resources/choices/pat.txt", encoding: .utf8))?
|
// static let patRes = (try? String(contentsOfFile: "resources/choices/pat.txt", encoding: .utf8))?
|
||||||
.split(separator: "\n")
|
// .split(separator: "\n")
|
||||||
.map({ $0.trimmingCharacters(in: .whitespacesAndNewlines) })
|
// .map({ $0.trimmingCharacters(in: .whitespacesAndNewlines) })
|
||||||
|
//
|
||||||
static func pat(
|
// static func pat(
|
||||||
_ args: ArraySlice<String.SubSequence>,
|
// _ args: ArraySlice<String.SubSequence>,
|
||||||
client: DiscordClient,
|
// client: DiscordClient,
|
||||||
ctx: Gateway.MessageCreate
|
// ctx: Gateway.MessageCreate
|
||||||
) async throws {
|
// ) async throws {
|
||||||
guard let patRes = patRes else { print("pat.txt not loaded"); return }
|
// guard let patRes = patRes else { print("pat.txt not loaded"); return }
|
||||||
try await performAction(ctx: ctx, client: client, resOpts: patRes)
|
// try await performAction(ctx: ctx, client: client, resOpts: patRes)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -1,116 +1,116 @@
|
|||||||
import Foundation
|
// import Foundation
|
||||||
#if canImport(FoundationNetworking)
|
// #if canImport(FoundationNetworking)
|
||||||
import FoundationNetworking
|
// import FoundationNetworking
|
||||||
#endif
|
// #endif
|
||||||
import DiscordBM
|
// import DiscordBM
|
||||||
|
//
|
||||||
struct MessageHandler {
|
// struct MessageHandler {
|
||||||
let ctx: Gateway.MessageCreate
|
// let ctx: Gateway.MessageCreate
|
||||||
let client: any DiscordClient
|
// let client: any DiscordClient
|
||||||
|
//
|
||||||
static let prefix = ":"
|
// static let prefix = ":"
|
||||||
static let zundaGifData = try? Data(contentsOf: URL(filePath: "resources/media/zundamone.gif"))
|
// static let zundaGifData = try? Data(contentsOf: URL(filePath: "resources/media/zundamone.gif"))
|
||||||
|
//
|
||||||
func handle() async throws {
|
// func handle() async throws {
|
||||||
guard !(ctx.author?.bot ?? false) else { return }
|
// guard !(ctx.author?.bot ?? false) else { return }
|
||||||
if (ctx.content.hasPrefix(MessageHandler.prefix)) {
|
// if (ctx.content.hasPrefix(MessageHandler.prefix)) {
|
||||||
let split = ctx.content.split(separator: " ")
|
// let split = ctx.content.split(separator: " ")
|
||||||
let command = split.first?.trimmingPrefix(MessageHandler.prefix)
|
// let command = split.first?.trimmingPrefix(MessageHandler.prefix)
|
||||||
let args = split[1...]
|
// let args = split[1...]
|
||||||
|
//
|
||||||
switch command {
|
// switch command {
|
||||||
case "wow": try await handleWow(args)
|
// case "wow": try await handleWow(args)
|
||||||
case "domath": try await Wolfram.handleMath(args, client: client, ctx: ctx)
|
// case "domath": try await Wolfram.handleMath(args, client: client, ctx: ctx)
|
||||||
case "hug": try await Actions.hug(args, client: client, ctx: ctx)
|
// case "hug": try await Actions.hug(args, client: client, ctx: ctx)
|
||||||
case "pat": try await Actions.pat(args, client: client, ctx: ctx)
|
// case "pat": try await Actions.pat(args, client: client, ctx: ctx)
|
||||||
case "pet": try await Actions.pat(args, client: client, ctx: ctx)
|
// case "pet": try await Actions.pat(args, client: client, ctx: ctx)
|
||||||
default: break
|
// default: break
|
||||||
}
|
// }
|
||||||
} else if ctx.mentions.contains(where: { $0.id == Zundamon.ownID }) {
|
// } else if ctx.mentions.contains(where: { $0.id == Zundamon.ownID }) {
|
||||||
if ctx.content
|
// if ctx.content
|
||||||
.replacingOccurrences(of: "<@\(Zundamon.ownID!.rawValue)>", with: "")
|
// .replacingOccurrences(of: "<@\(Zundamon.ownID!.rawValue)>", with: "")
|
||||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
// .trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
.count == 0,
|
// .count == 0,
|
||||||
let zundaGif = MessageHandler.zundaGifData
|
// let zundaGif = MessageHandler.zundaGifData
|
||||||
{
|
// {
|
||||||
try await client.createMessage(
|
// try await client.createMessage(
|
||||||
channelId: ctx.channel_id,
|
// channelId: ctx.channel_id,
|
||||||
payload: .init(
|
// payload: .init(
|
||||||
message_reference: .init(
|
// message_reference: .init(
|
||||||
type: .default,
|
// type: .default,
|
||||||
message_id: ctx.id,
|
// message_id: ctx.id,
|
||||||
channel_id: ctx.channel_id,
|
// channel_id: ctx.channel_id,
|
||||||
guild_id: ctx.guild_id,
|
// guild_id: ctx.guild_id,
|
||||||
),
|
// ),
|
||||||
files: [.init(data: .init(data: zundaGif), filename: "zundamone.gif")],
|
// files: [.init(data: .init(data: zundaGif), filename: "zundamone.gif")],
|
||||||
attachments: [.init(index: 0, filename: "zundamone.gif")],
|
// attachments: [.init(index: 0, filename: "zundamone.gif")],
|
||||||
)
|
// )
|
||||||
).guardSuccess()
|
// ).guardSuccess()
|
||||||
} else {
|
// } else {
|
||||||
try await handle8Ball()
|
// try await handle8Ball()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static let ballResponses = [
|
// static let ballResponses = [
|
||||||
"It is certain.",
|
// "It is certain.",
|
||||||
"It is decidedly so.",
|
// "It is decidedly so.",
|
||||||
"Without a doubt.",
|
// "Without a doubt.",
|
||||||
"Yes – definitely.",
|
// "Yes – definitely.",
|
||||||
"You may rely on it.",
|
// "You may rely on it.",
|
||||||
"As I see it, yes.",
|
// "As I see it, yes.",
|
||||||
"Most likely.",
|
// "Most likely.",
|
||||||
"Outlook good.",
|
// "Outlook good.",
|
||||||
"Yes.",
|
// "Yes.",
|
||||||
"Signs point to yes.",
|
// "Signs point to yes.",
|
||||||
"Reply hazy, try again.",
|
// "Reply hazy, try again.",
|
||||||
"Ask again later.",
|
// "Ask again later.",
|
||||||
"Better not tell you now.",
|
// "Better not tell you now.",
|
||||||
"Cannot predict now.",
|
// "Cannot predict now.",
|
||||||
"Concentrate and ask again.",
|
// "Concentrate and ask again.",
|
||||||
"Don’t count on it.",
|
// "Don’t count on it.",
|
||||||
"My reply is no.",
|
// "My reply is no.",
|
||||||
"My sources say no.",
|
// "My sources say no.",
|
||||||
"Outlook not so good.",
|
// "Outlook not so good.",
|
||||||
"Very doubtful.",
|
// "Very doubtful.",
|
||||||
"Ui beam",
|
// "Ui beam",
|
||||||
"We are Shigure Ui",
|
// "We are Shigure Ui",
|
||||||
"We are Shigure Ux",
|
// "We are Shigure Ux",
|
||||||
]
|
// ]
|
||||||
func handle8Ball() async throws {
|
// func handle8Ball() async throws {
|
||||||
try await client.createMessage(
|
// try await client.createMessage(
|
||||||
channelId: ctx.channel_id,
|
// channelId: ctx.channel_id,
|
||||||
payload: .init(
|
// payload: .init(
|
||||||
content: MessageHandler.ballResponses.randomElement(),
|
// content: MessageHandler.ballResponses.randomElement(),
|
||||||
message_reference: .init(
|
// message_reference: .init(
|
||||||
type: .default,
|
// type: .default,
|
||||||
message_id: ctx.id,
|
// message_id: ctx.id,
|
||||||
channel_id: ctx.channel_id,
|
// channel_id: ctx.channel_id,
|
||||||
guild_id: ctx.guild_id,
|
// guild_id: ctx.guild_id,
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
).guardSuccess()
|
// ).guardSuccess()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static let wows = [
|
// static let wows = [
|
||||||
"<:wow:1477062414913634334>",
|
// "<:wow:1477062414913634334>",
|
||||||
"<:wow2:1477062432357875948>",
|
// "<:wow2:1477062432357875948>",
|
||||||
"<:wow4:1477062471746588713>",
|
// "<:wow4:1477062471746588713>",
|
||||||
"<:wow5:1477062452804849845>"
|
// "<:wow5:1477062452804849845>"
|
||||||
]
|
// ]
|
||||||
func handleWow(_ args: ArraySlice<String.SubSequence>) async throws {
|
// func handleWow(_ args: ArraySlice<String.SubSequence>) async throws {
|
||||||
try await client.createMessage(
|
// try await client.createMessage(
|
||||||
channelId: ctx.channel_id,
|
// channelId: ctx.channel_id,
|
||||||
payload: .init(
|
// payload: .init(
|
||||||
content: MessageHandler.wows.randomElement(),
|
// content: MessageHandler.wows.randomElement(),
|
||||||
message_reference: .init(
|
// message_reference: .init(
|
||||||
type: .default,
|
// type: .default,
|
||||||
message_id: ctx.id,
|
// message_id: ctx.id,
|
||||||
channel_id: ctx.channel_id,
|
// channel_id: ctx.channel_id,
|
||||||
guild_id: ctx.guild_id,
|
// guild_id: ctx.guild_id,
|
||||||
),
|
// ),
|
||||||
)
|
// )
|
||||||
).guardSuccess()
|
// ).guardSuccess()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
// }
|
||||||
|
|||||||
@@ -1,107 +1,107 @@
|
|||||||
import Foundation
|
// import Foundation
|
||||||
#if canImport(FoundationNetworking)
|
// #if canImport(FoundationNetworking)
|
||||||
import FoundationNetworking
|
// import FoundationNetworking
|
||||||
#endif
|
// #endif
|
||||||
import XMLCoder
|
// import XMLCoder
|
||||||
import DiscordBM
|
// import DiscordBM
|
||||||
|
//
|
||||||
struct Wolfram {
|
// struct Wolfram {
|
||||||
static let token = ProcessInfo.processInfo.environment["WOLFRAM_APP_ID"]!
|
// static let token = ProcessInfo.processInfo.environment["WOLFRAM_APP_ID"]!
|
||||||
static let apiUrl = "http://api.wolframalpha.com/v2/query"
|
// static let apiUrl = "http://api.wolframalpha.com/v2/query"
|
||||||
|
//
|
||||||
static func getWolfram(_ question: String) async throws -> (String, URL?) {
|
// static func getWolfram(_ question: String) async throws -> (String, URL?) {
|
||||||
let encQuestion = question.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
|
// let encQuestion = question.addingPercentEncoding(withAllowedCharacters: .alphanumerics)
|
||||||
let url = URL(string: "\(apiUrl)?appid=\(token)&input=\(encQuestion!)")!
|
// let url = URL(string: "\(apiUrl)?appid=\(token)&input=\(encQuestion!)")!
|
||||||
let (data, _) = try await URLSession.shared.data(from: url)
|
// let (data, _) = try await URLSession.shared.data(from: url)
|
||||||
|
//
|
||||||
let wolframRes = try XMLDecoder().decode(WolframQueryResult.self, from: data)
|
// let wolframRes = try XMLDecoder().decode(WolframQueryResult.self, from: data)
|
||||||
|
//
|
||||||
let resultPod = wolframRes.pod.first(where: { $0.primary ?? false || $0.id == "Result" })
|
// let resultPod = wolframRes.pod.first(where: { $0.primary ?? false || $0.id == "Result" })
|
||||||
|
//
|
||||||
var ans: String?
|
// var ans: String?
|
||||||
var img: URL?
|
// var img: URL?
|
||||||
|
//
|
||||||
if let resultPod = resultPod {
|
// if let resultPod = resultPod {
|
||||||
ans = String(resultPod.subpod.compactMap(\.plaintext).joined(by: "\n"))
|
// ans = String(resultPod.subpod.compactMap(\.plaintext).joined(by: "\n"))
|
||||||
.replacingOccurrences(of: " | ", with: ": ")
|
// .replacingOccurrences(of: " | ", with: ": ")
|
||||||
}
|
// }
|
||||||
if let imgPod = wolframRes.pod.first(where: {
|
// if let imgPod = wolframRes.pod.first(where: {
|
||||||
["RootPlot", "NumberLine", "Plot", "ImplicitPlot", "3DPlot"].contains($0.id) ||
|
// ["RootPlot", "NumberLine", "Plot", "ImplicitPlot", "3DPlot"].contains($0.id) ||
|
||||||
($0.id == "Example" && $0.scanner == "Dice")
|
// ($0.id == "Example" && $0.scanner == "Dice")
|
||||||
}) {
|
// }) {
|
||||||
ans = ans ?? "Plot:"
|
// ans = ans ?? "Plot:"
|
||||||
img = imgPod.subpod.first?.img.src
|
// img = imgPod.subpod.first?.img.src
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
if ans == nil,
|
// if ans == nil,
|
||||||
let maybePod = wolframRes.pod.first(where: { $0.title == "Input interpretation" }),
|
// let maybePod = wolframRes.pod.first(where: { $0.title == "Input interpretation" }),
|
||||||
let maybeText = maybePod.subpod.first?.plaintext
|
// let maybeText = maybePod.subpod.first?.plaintext
|
||||||
.replacingOccurrences(of: " | ", with: ": ") {
|
// .replacingOccurrences(of: " | ", with: ": ") {
|
||||||
ans = "<:smol_rise:852763040452575252> I don't know. Maybe you meant '\(maybeText)'"
|
// ans = "<:smol_rise:852763040452575252> I don't know. Maybe you meant '\(maybeText)'"
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
return (ans ?? "<:smol_rise:852763040452575252> sorry, I have no idea (´._.`)", img)
|
// return (ans ?? "<:smol_rise:852763040452575252> sorry, I have no idea (´._.`)", img)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
static func handleMath(
|
// static func handleMath(
|
||||||
_ args: ArraySlice<String.SubSequence>,
|
// _ args: ArraySlice<String.SubSequence>,
|
||||||
client: DiscordClient,
|
// client: DiscordClient,
|
||||||
ctx: Gateway.MessageCreate
|
// ctx: Gateway.MessageCreate
|
||||||
) async throws {
|
// ) async throws {
|
||||||
try await client.triggerTypingIndicator(channelId: ctx.channel_id).guardSuccess()
|
// try await client.triggerTypingIndicator(channelId: ctx.channel_id).guardSuccess()
|
||||||
|
//
|
||||||
let question = String(args.joined(by: " "))
|
// let question = String(args.joined(by: " "))
|
||||||
|
//
|
||||||
let (answer, img) = try await getWolfram(question)
|
// let (answer, img) = try await getWolfram(question)
|
||||||
|
//
|
||||||
var attachments: [Payloads.Attachment] = []
|
// var attachments: [Payloads.Attachment] = []
|
||||||
var files: [RawFile] = []
|
// var files: [RawFile] = []
|
||||||
|
//
|
||||||
if let img = img {
|
// if let img = img {
|
||||||
let data = try? await URLSession.shared.data(from: img)
|
// let data = try? await URLSession.shared.data(from: img)
|
||||||
if let data = data?.0 {
|
// if let data = data?.0 {
|
||||||
attachments.append(.init(index: 0, filename: "img.gif"))
|
// attachments.append(.init(index: 0, filename: "img.gif"))
|
||||||
files.append(.init(data: .init(data: data), filename: "img.gif"))
|
// files.append(.init(data: .init(data: data), filename: "img.gif"))
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
try await client.createMessage(channelId: ctx.channel_id, payload: .init(
|
// try await client.createMessage(channelId: ctx.channel_id, payload: .init(
|
||||||
content: answer,
|
// content: answer,
|
||||||
message_reference: .init(
|
// message_reference: .init(
|
||||||
type: .default,
|
// type: .default,
|
||||||
message_id: ctx.id,
|
// message_id: ctx.id,
|
||||||
channel_id: ctx.channel_id,
|
// channel_id: ctx.channel_id,
|
||||||
guild_id: ctx.guild_id,
|
// guild_id: ctx.guild_id,
|
||||||
),
|
// ),
|
||||||
files: files,
|
// files: files,
|
||||||
attachments: attachments
|
// attachments: attachments
|
||||||
)).guardSuccess()
|
// )).guardSuccess()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
struct WolframQueryResult: Codable {
|
// struct WolframQueryResult: Codable {
|
||||||
struct Pod: Codable {
|
// struct Pod: Codable {
|
||||||
let title: String
|
// let title: String
|
||||||
let id: String
|
// let id: String
|
||||||
let scanner: String
|
// let scanner: String
|
||||||
let primary: Bool?
|
// let primary: Bool?
|
||||||
|
//
|
||||||
let subpod: [Subpod]
|
// let subpod: [Subpod]
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
struct Subpod: Codable {
|
// struct Subpod: Codable {
|
||||||
let title: String
|
// let title: String
|
||||||
let img: Image
|
// let img: Image
|
||||||
let plaintext: String
|
// let plaintext: String
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
struct Image: Codable {
|
// struct Image: Codable {
|
||||||
let src: URL
|
// let src: URL
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
let success: Bool
|
// let success: Bool
|
||||||
let numpods: Int
|
// let numpods: Int
|
||||||
|
//
|
||||||
let pod: [Pod]
|
// let pod: [Pod]
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import DiscordBM
|
|
||||||
import DiscordKit
|
import DiscordKit
|
||||||
import SwiftDotenv
|
import SwiftDotenv
|
||||||
|
|
||||||
@main
|
@main
|
||||||
struct Zundamon {
|
struct Zundamon {
|
||||||
nonisolated(unsafe) static private(set) var ownID: UserSnowflake? = nil
|
//nonisolated(unsafe) static private(set) var ownID: UserSnowflake? = nil
|
||||||
|
|
||||||
static func main() async throws {
|
static func main() async throws {
|
||||||
let tmp = Result { try Dotenv.configure() }
|
let tmp = Result { try Dotenv.configure() }
|
||||||
@@ -41,12 +40,12 @@ struct Zundamon {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EventHandler: GatewayEventHandler {
|
//struct EventHandler: GatewayEventHandler {
|
||||||
let event: Gateway.Event
|
// let event: Gateway.Event
|
||||||
let client: any DiscordClient
|
// let client: any DiscordClient
|
||||||
|
//
|
||||||
func onMessageCreate(_ payload: Gateway.MessageCreate) async throws {
|
// func onMessageCreate(_ payload: Gateway.MessageCreate) async throws {
|
||||||
try await MessageHandler(ctx: payload, client: client).handle()
|
// try await MessageHandler(ctx: payload, client: client).handle()
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
}
|
//}
|
||||||
|
|||||||
Reference in New Issue
Block a user