From f5874b0ec767213ed59a8e8484ecf71ddd2abb17 Mon Sep 17 00:00:00 2001 From: hlaaftana Date: Mon, 16 Apr 2018 01:13:46 +0300 Subject: [PATCH] Killed the nazis --- .../groovy/hlaaftana/discordg/Client.groovy | 794 +++++++++--------- .../groovy/hlaaftana/discordg/DSLMain.groovy | 4 +- .../groovy/hlaaftana/discordg/DiscordG.groovy | 15 +- .../hlaaftana/discordg/DiscordObject.groovy | 96 +-- .../hlaaftana/discordg/Permissions.groovy | 53 +- .../discordg/collections/Cache.groovy | 6 +- .../collections/DiscordListCache.groovy | 14 +- .../collections/LazyClosureMap.groovy | 130 +-- .../hlaaftana/discordg/dsl/BotBuilder.groovy | 2 +- .../discordg/dsl/ClientBuilder.groovy | 4 +- .../exceptions/BadRequestException.groovy | 2 +- .../exceptions/HTTP5xxException.groovy | 2 +- .../discordg/exceptions/HTTPException.groovy | 2 +- .../exceptions/InvalidTokenException.groovy | 2 +- .../exceptions/MessageInvalidException.groovy | 2 +- .../exceptions/NoPermissionException.groovy | 2 +- .../exceptions/NotFoundException.groovy | 2 +- .../discordg/logic/ActionPool.groovy | 47 +- .../discordg/logic/BasicListenerSystem.groovy | 4 +- .../hlaaftana/discordg/logic/EventData.groovy | 10 +- .../discordg/logic/ListenerSystem.groovy | 39 +- .../logic/ParentListenerSystem.groovy | 17 - .../hlaaftana/discordg/net/HTTPClient.groovy | 38 +- .../hlaaftana/discordg/net/RateLimit.groovy | 8 +- .../discordg/net/VoiceWSClient.groovy | 56 +- .../hlaaftana/discordg/net/WSClient.groovy | 26 +- .../hlaaftana/discordg/objects/Channel.groovy | 202 ++--- .../hlaaftana/discordg/objects/Guild.groovy | 382 ++++----- .../hlaaftana/discordg/objects/Invite.groovy | 20 +- .../hlaaftana/discordg/objects/Message.groovy | 156 ++-- .../hlaaftana/discordg/objects/User.groovy | 110 +-- .../hlaaftana/discordg/objects/Webhook.groovy | 32 +- .../discordg/status/DiscordStatus.groovy | 4 +- .../discordg/status/IncidentUpdate.groovy | 8 +- .../discordg/status/Maintenance.groovy | 14 +- .../discordg/status/MapObject.groovy | 6 +- .../hlaaftana/discordg/status/Schedule.groovy | 10 +- .../discordg/status/StatusPage.groovy | 4 +- .../discordg/util/ClosureString.groovy | 22 +- .../discordg/util/ConversionUtil.groovy | 14 +- .../hlaaftana/discordg/util/JSONUtil.groovy | 28 +- .../groovy/hlaaftana/discordg/util/Log.groovy | 34 +- .../hlaaftana/discordg/util/MiscUtil.groovy | 44 +- .../hlaaftana/discordg/util/WhatIs.groovy | 18 +- .../discordg/util/bot/CleverbotDotIO.groovy | 14 +- .../discordg/util/bot/CommandBot.groovy | 94 +-- 46 files changed, 1308 insertions(+), 1285 deletions(-) delete mode 100644 src/main/groovy/hlaaftana/discordg/logic/ParentListenerSystem.groovy diff --git a/src/main/groovy/hlaaftana/discordg/Client.groovy b/src/main/groovy/hlaaftana/discordg/Client.groovy index 3a1f8d1..9d3c765 100644 --- a/src/main/groovy/hlaaftana/discordg/Client.groovy +++ b/src/main/groovy/hlaaftana/discordg/Client.groovy @@ -90,12 +90,12 @@ class Client extends User { static List knownEvents = ['INITIAL_GUILD_CREATE', 'UNRECOGINZED', 'ALL'] + knownDiscordEvents String customUserAgent = '' - String getFullUserAgent(){ "$DiscordG.USER_AGENT $customUserAgent" } + String getFullUserAgent() { "$DiscordG.USER_AGENT $customUserAgent" } String tokenPrefix String rawToken String email - String getEmail(){ userObject.getOrDefault('email', this.@email) } + String getEmail() { userObject.getOrDefault('email', this.@email) } String password boolean confirmedBot void setBot(boolean x) { if (x && !confirmedBot) confirmedBot = true } @@ -177,7 +177,6 @@ class Client extends User { Tuple2 shardTuple Log log - Map fields = [:] Map extraIdentifyData = [:] Set mutedChannels = [] Map pools = [ @@ -194,7 +193,16 @@ class Client extends User { List rawListeners = [] @Delegate(excludes = ['hashCode', 'equals', 'toString', 'listenerError', 'parseEvent']) - ListenerSystem> listenerSystem = new ParentListenerSystem<>(this) + ListenerSystem> listenerSystem = new ClientListenerSystem() + class ClientListenerSystem extends ListenerSystem> { + String parseEvent(param) { + Client.this.parseEvent(param) + } + + void listenerError(event, Throwable ex, Closure closure, Map data) { + Client.this.listenerError((String) event, ex, closure, data) + } + } HTTPClient http = new HTTPClient(this) WSClient ws Cache readyData = Cache.empty(this) @@ -223,7 +231,7 @@ class Client extends User { void setLogName(String name) { this.@logName = name - if (log) log.name = logName else log = new Log(logName) + getLog() } void setRequestMembersOnReady(boolean doso) { @@ -250,146 +258,112 @@ class Client extends User { boolean isBot() { boolean ass = confirmedBot || object.bot - if (ass) tokenPrefix = 'Bot' - else tokenPrefix = '' + tokenPrefix = ass ? 'Bot' : '' ass } WSClient getWebSocketClient() { ws } - def blacklist(event) { client.eventBlacklist.add(parseEvent(event)) } - def whitelist(event) { client.eventWhitelist.add(parseEvent(event)) } - - void login(String email, String password, boolean threaded = true){ - Closure a = { - log.info 'Getting token...' - this.email = email - this.password = password - File tokenCache = new File(tokenCachePath) - if (!cacheTokens) token = requestToken(email, password) - else try { - token = ((Map) JSONUtil.parse(tokenCache)[(email)]).token - } catch (ignored) { - JSONUtil.modify(tokenCache, - [(email): [token: requestToken(email, password)]]) - token = ((Map) JSONUtil.parse(tokenCache)[(email)]).token - } - log.info 'Got token.' - login(token.toString(), false, false) - } - if (threaded) Thread.start(a) - else a() - } - - void login(String token, boolean bot = true, boolean threaded = true){ - Closure a = { - confirmedBot = bot - this.token = token - connectGateway(true, false) + def blacklist(event) { eventBlacklist.add(parseEvent(event)) } + def whitelist(event) { eventWhitelist.add(parseEvent(event)) } + + void login(String email, String password) { + log.info 'Getting token...' + this.email = email + this.password = password + File tokenCache = new File(tokenCachePath) + if (!cacheTokens) token = requestToken(email, password) + else try { + token = ((Map) JSONUtil.parse(tokenCache)[(email)]).token.toString() + } catch (ignored) { + JSONUtil.modify(tokenCache, + [(email): [token: requestToken(email, password)]]) + token = ((Map) JSONUtil.parse(tokenCache)[(email)]).token.toString() } - if (threaded) Thread.start(a) - else a() - } - - void login(String customBotName, boolean threaded = true, Closure requestToken){ - Closure a = { - confirmedBot = true - File tokenFile = new File(tokenCachePath) - if (!tokenFile.exists()) JSONUtil.dump(tokenFile, [bots: [:]]) - Map original = (Map>>) JSONUtil.parse(tokenFile) - if (!original.bots) original.bots = [:] - if (!original.bots[customBotName]) original.bots[customBotName] = [:] - def x = (Map) original.bots[customBotName] - if (x.token){ - try{ - token = x.token - }catch (ignored){ - String newToken = requestToken() - JSONUtil.dump(tokenFile, original) - token = newToken - } - }else{ + log.info 'Got token.' + login(token, false) + } + + void login(String token, boolean bot = true) { + confirmedBot = bot + this.token = token + connectGateway(true) + } + + void login(String customBotName, Closure requestToken) { + confirmedBot = true + File tokenFile = new File(tokenCachePath) + if (!tokenFile.exists()) JSONUtil.dump(tokenFile, [bots: [:]]) + Map original = (Map>>) JSONUtil.parse(tokenFile) + if (!original.bots) original.bots = [:] + if (!original.bots[customBotName]) original.bots[customBotName] = [:] + def x = (Map) original.bots[customBotName] + if (x.token) { + try{ + token = x.token + }catch (ignored) { String newToken = requestToken() - x.token = newToken JSONUtil.dump(tokenFile, original) token = newToken } - connectGateway(true, false) + } else { + String newToken = requestToken() + x.token = newToken + JSONUtil.dump(tokenFile, original) + token = newToken } - if (threaded) Thread.start(a) - else a() + connectGateway(true) } - void login(boolean threaded = true){ - if (token) login(token, threaded) - else if (email && password) login(email, password, threaded) + void login() { + if (token) login(token) + else if (email && password) login(email, password) else throw new IllegalArgumentException('Can\'t login without credentials') } - void connectGateway(boolean requestGateway = true, boolean threaded = true){ - Closure a = { - if (requestGateway){ - log.info 'Requesting gateway...' - gateway = http.jsonGet('gateway').url - if (!gateway.endsWith('/')) gateway += '/' - gateway += "?encoding=json&v=$gatewayVersion" - } - WebSocketClient cl = new WebSocketClient(new SslContextFactory()) - if (!ws) ws = new WSClient(this) - log.info 'Starting websocket connection...' - gatewayClosed = false - cl.start() - cl.connect(ws, new URI(gateway), new ClientUpgradeRequest()) - } - askPool('connect'){ - if (threaded) Thread.start(a) - else a() + void connectGateway(boolean requestGateway = true) { + if (requestGateway) { + log.info 'Requesting gateway...' + gateway = http.jsonGet('gateway').url + if (!gateway.endsWith('/')) gateway += '/' + gateway += "?encoding=json&v=$gatewayVersion" } + WebSocketClient cl = new WebSocketClient(new SslContextFactory()) + if (null != ws) ws = new WSClient(this) + log.info 'Starting websocket connection...' + gatewayClosed = false + cl.start() + cl.connect(ws, new URI(gateway), new ClientUpgradeRequest()) } - void logout(boolean exit = false){ - if (!bot) http.post('auth/logout', ['token': token]) - closeGateway(false) + void logout() { + if (!bot) http.post('auth/logout', [token: token]) + closeGateway() ws = null - if (exit) System.exit(0) } - void closeGateway(boolean threaded = true){ - Closure a = { - gatewayClosed = true - if (ws){ - ws.heartbeatThread?.interrupt() - ws.session?.close(1000, 'Close') - } + void closeGateway() { + gatewayClosed = true + if (ws) { + ws.heartbeatThread?.interrupt() + ws.session?.close(1000, 'Close') } - if (threaded){ Thread.start(a) } - else { a() } } - static String parseEvent(str){ + static String parseEvent(str) { def r = str.toString().toUpperCase().replaceAll(/\s+/, '_') .replace('CHANGE', 'UPDATE').replaceAll(/^(?!VOICE_)GUILD/, 'GUILD') knownEvents.contains(r) ? r : (eventAliases[r] ?: 'UNRECOGNIZED') } - def listenerError(String event, Throwable ex, Closure closure, data){ + void listenerError(String event, Throwable ex, Closure closure, data) { ex.printStackTrace() log.info "Ignoring exception from event $event" } - def propertyMissing(String name){ - if (fields.containsKey(name)) fields[name] - else throw new MissingPropertyException(name, Client) - } - - def propertyMissing(String name, value){ - if (fields.containsKey(name)) fields.put name, value - else throw new MissingPropertyException(name, Client) - } - - boolean isLoaded(){ - rawToken && ws && ws.loaded && (null != guildCache && !guildCache.isEmpty()) && - (!bot || !anyUnavailableGuilds()) + boolean isLoaded() { + rawToken && ws && ws.loaded && !(null == guildCache || guildCache.isEmpty()) && + !(bot && anyUnavailableGuilds()) } boolean anyUnavailableGuilds() { @@ -397,83 +371,83 @@ class Client extends User { false } - String requestToken(String email, String password){ + String requestToken(String email, String password) { askPool('login') { http.jsonPost('auth/login', - ['email': email, 'password': password]).token + [email: email, password: password]).token } } - User getUser(){ new User(this, userObject) } + User getUser() { new User(this, userObject) } - Region getOptimalRegion(){ + Region getOptimalRegion() { requestRegions().find { it.optimal } } - boolean isPrivateChannel(c){ + boolean isPrivateChannel(c) { privateChannelCache.containsKey(id(c)) } - List getPrivateChannels(){ + List getPrivateChannels() { (List) (privateChannelCache?.list() ?: []) } - Map getPrivateChannelMap(){ + Map getPrivateChannelMap() { (Map) (privateChannelCache?.map() ?: [:]) } - Channel privateChannel(c){ find(privateChannelCache, c) } - List privateChannels(c){ findAll(privateChannelCache, c) } + Channel privateChannel(c) { find(privateChannelCache, c) } + List privateChannels(c) { findAll(privateChannelCache, c) } - DiscordListCache getUserDmChannelCache(){ + DiscordListCache getUserDmChannelCache() { DiscordListCache dlc = new DiscordListCache([], this, Channel) for (e in privateChannelCache) if (e.value.type == 1) dlc.put(((DiscordListCache) e.value.recipients).keySet()[0], e.value) dlc } - Map getUserDmChannelMap(){ + Map getUserDmChannelMap() { userDmChannelCache.map() } - DiscordListCache getDmChannelCache(){ + DiscordListCache getDmChannelCache() { DiscordListCache dlc = new DiscordListCache([], this, Channel) for (e in privateChannelCache) if (e.value.type == 1) dlc.add(e.value) dlc } - List getDmChannels(){ + List getDmChannels() { privateChannels.findAll { it.dm } } - Map getDmChannelMap(){ + Map getDmChannelMap() { privateChannelMap.findAll { k, v -> v.dm } } - Channel dmChannel(c){ channels(c).find { it.dm } } - List dmChannels(c){ channels(c).findAll { it.dm } } - Channel userDmChannel(u){ find(userDmChannelCache, u) } + Channel dmChannel(c) { channels(c).find { it.dm } } + List dmChannels(c) { channels(c).findAll { it.dm } } + Channel userDmChannel(u) { find(userDmChannelCache, u) } - List getGroups(){ + List getGroups() { privateChannels.findAll { it.group } } - Map getGroupMap(){ + Map getGroupMap() { privateChannelMap.findAll { k, v -> v.group } } - Channel group(c){ channels(c).find { it.group } } - List groups(c){ channels(c).findAll { it.group } } + Channel group(c) { channels(c).find { it.group } } + List groups(c) { channels(c).findAll { it.group } } - List getChannels(){ + List getChannels() { (List) (guildChannels + privateChannels ?: []) } - Map getChannelMap(){ + Map getChannelMap() { (Map) (guildChannelMap + privateChannelMap ?: [:]) } - List getGuildChannels(){ + List getGuildChannels() { def result = new ArrayList() for (e in guildCache) { def c = (DiscordListCache) e.value.channels @@ -482,7 +456,7 @@ class Client extends User { result } - Map getGuildChannelMap(){ + Map getGuildChannelMap() { def result = new HashMap() for (e in guildCache) { def c = (DiscordListCache) e.value.channels @@ -491,7 +465,7 @@ class Client extends User { result } - Map getChannelGuildIdMap(){ + Map getChannelGuildIdMap() { def result = new HashMap() for (e in guildCache) for (ce in (DiscordListCache) e.value.channels) { result.put ce.key, e.key @@ -499,58 +473,58 @@ class Client extends User { result } - Member member(t){ (Member) findNested(guildCache, "members", t) } - List members(t){ findAllNested(guildCache, "members", t) } - Member member(s, u){ find((DiscordListCache) guildCache[id(s)].members, u) } - List members(s, u){ findAll((DiscordListCache) guildCache[id(s)].members, u) } + Member member(t) { (Member) findNested(guildCache, "members", t) } + List members(t) { findAllNested(guildCache, "members", t) } + Member member(s, u) { find((DiscordListCache) guildCache[id(s)].members, u) } + List members(s, u) { findAll((DiscordListCache) guildCache[id(s)].members, u) } - User user(u){ (User) (member(u)?.user ?: + User user(u) { (User) (member(u)?.user ?: findNested(privateChannelCache, 'recipients', u) ?: relation(u)?.user) } - Relationship relationship(u){ find(relationshipCache, u) } - Relationship relation(u){ relationship(u) } + Relationship relationship(u) { find(relationshipCache, u) } + Relationship relation(u) { relationship(u) } - Guild guild(s){ find(guildCache, s) } + Guild guild(s) { find(guildCache, s) } - Channel textChannel(...args){ ((List) invokeMethod('channels', args)).find { it.text } } - List textChannels(...args){ ((List) invokeMethod('channels', args)).findAll { it.text } } - Channel voiceChannel(...args){ ((List) invokeMethod('channels', args)).find { it.voice } } - List voiceChannels(...args){ ((List) invokeMethod('channels', args)).findAll { it.voice } } + Channel textChannel(...args) { ((List) invokeMethod('channels', args)).find { it.text } } + List textChannels(...args) { ((List) invokeMethod('channels', args)).findAll { it.text } } + Channel voiceChannel(...args) { ((List) invokeMethod('channels', args)).find { it.voice } } + List voiceChannels(...args) { ((List) invokeMethod('channels', args)).findAll { it.voice } } - Channel channel(c){ guildChannel(c) ?: privateChannel(c) } - List channels(c){ guildChannels(c) ?: privateChannels(c) } - Channel guildChannel(c){ (Channel) findNested(guildCache, "channels", c) } - List guildChannels(c){ findAllNested(guildCache, "channels", c) } - Channel channel(s, c){ find((DiscordListCache) guildCache[id(s)].channels, c) } - List channels(s, c){ findAll((DiscordListCache) guildCache[id(s)].channels, c) } + Channel channel(c) { guildChannel(c) ?: privateChannel(c) } + List channels(c) { guildChannels(c) ?: privateChannels(c) } + Channel guildChannel(c) { (Channel) findNested(guildCache, "channels", c) } + List guildChannels(c) { findAllNested(guildCache, "channels", c) } + Channel channel(s, c) { find((DiscordListCache) guildCache[id(s)].channels, c) } + List channels(s, c) { findAll((DiscordListCache) guildCache[id(s)].channels, c) } - Role role(r){ (Role) findNested(guildCache, "roles", r) } - List roles(r){ findAllNested(guildCache, "roles", r) } - Role role(s, r){ find((DiscordListCache) guildCache[id(s)].roles, r) } - List roles(s, r){ findAll((DiscordListCache) guildCache[id(s)].roles, r) } + Role role(r) { (Role) findNested(guildCache, "roles", r) } + List roles(r) { findAllNested(guildCache, "roles", r) } + Role role(s, r) { find((DiscordListCache) guildCache[id(s)].roles, r) } + List roles(s, r) { findAll((DiscordListCache) guildCache[id(s)].roles, r) } - Call ongoingCall(c){ calls[id(c)] ? new Call(this, calls[id(c)]) : null } + Call ongoingCall(c) { calls[id(c)] ? new Call(this, calls[id(c)]) : null } - List getRelationships(){ relationshipCache.list() } - Map getRelationshipMap(){ relationshipCache.map() } + List getRelationships() { relationshipCache.list() } + Map getRelationshipMap() { relationshipCache.map() } List getGuilds() { (List) (guildCache?.list() ?: []) } - Map getGuildMap(){ (Map) (guildCache?.map() ?: [:]) } + Map getGuildMap() { (Map) (guildCache?.map() ?: [:]) } - List getGlobalPresences(){ (List) (presenceCache?.list() ?: []) } - Map getGlobalPresenceMap(){ (Map) (presenceCache?.map() ?: [:]) } + List getGlobalPresences() { (List) (presenceCache?.list() ?: []) } + Map getGlobalPresenceMap() { (Map) (presenceCache?.map() ?: [:]) } List getAllUsers() { userMap.values().toList() } - List getAllMembers(){ (List) memberMap.values()*.values().flatten().toList() } - List getAllRoles(){ (List) roleMap.values().flatten().toList() } - List getAllEmojis(){ (List) emojiIdMap.values().flatten().toList() } + List getAllMembers() { (List) memberMap.values()*.values().flatten().toList() } + List getAllRoles() { (List) roleMap.values().flatten().toList() } + List getAllEmojis() { (List) emojiIdMap.values().flatten().toList() } - List getUsers(){ allUsers } - List getMembers(){ allMembers } - List getRoles(){ allRoles } - List getEmojis(){ allEmojis } + List getUsers() { allUsers } + List getMembers() { allMembers } + List getRoles() { allRoles } + List getEmojis() { allEmojis } - Map getUserMap(){ + Map getUserMap() { def result = new HashMap() for (e in guildCache) { def m = (DiscordListCache) e.value.members @@ -567,51 +541,51 @@ class Client extends User { result } - Map> getMemberMap(){ + Map> getMemberMap() { Map doo = [:] guilds.each { doo[it.id] = it.memberMap } doo } - Map getRoleMap(){ + Map getRoleMap() { def result = new HashMap() for (e in guilds) result.putAll(e.roleMap) result } - Map getEmojiIdMap(){ + Map getEmojiIdMap() { def result = new HashMap() for (e in guilds) result.putAll(e.emojiIdMap) result } - Map getEmojiNameMap(){ + Map getEmojiNameMap() { def result = new HashMap() for (e in guilds) result.putAll(e.emojiNameMap) result } - boolean isVerified(){ userObject.verified as boolean } + boolean isVerified() { userObject.verified as boolean } - def T askPool(String name, String bucket = '$', Closure action){ + def T askPool(String name, String bucket = '$', Closure action) { pools[name].ask bucket, action } - def syncGuilds(g){ - g = g instanceof Collection ? + def syncGuilds(g) { + final g1 = g instanceof Collection ? g.collect(DiscordObject.&id).collate(25) : [[id(g)]] - for (c in g) { + for (c in g1) { ws.send op: 12, d: c Thread.sleep 1000 } } - def chunkMembersFor(guilds, String query = '', int limit = 0){ - guilds = guilds instanceof Collection ? + def chunkMembersFor(guilds, String query = '', int limit = 0) { + final g = guilds instanceof Collection ? guilds.collect(DiscordObject.&id).collate(25) : [id(guilds)] - guilds.each { + for (it in g) { ws.send op: 8, d: [ guild_id: it, query: query, @@ -621,29 +595,29 @@ class Client extends User { } } - def chunkMembersFor(guilds, int limit, String query = ''){ + def chunkMembersFor(guilds, int limit, String query = '') { chunkMembersFor(guilds, query, limit) } - String filterMessage(cnt){ + String filterMessage(cnt) { String a = cnt.toString() - messageFilters.each { k, v -> - if (k instanceof Pattern) a = a.invokeMethod('replaceAll', [((Pattern) k).pattern(), v]).toString() - else a = a.invokeMethod('replace', [k.toString(), v]).toString() + for (e in messageFilters) { + if (e.key instanceof Pattern) a = a.invokeMethod('replaceAll', [((Pattern) e.key).pattern(), e.value]).toString() + else a = a.invokeMethod('replace', [e.key.toString(), e.value]).toString() } a } - static String getApplicationLink(app, Permissions perms = null){ + static String getApplicationLink(app, Permissions perms = null) { "https://discordapp.com/oauth2/authorize?client_id=${id(app)}&scope=bot" + (perms ? "&permissions=$perms.value" : '') } - static String getAppLink(app, Permissions perms = null){ getApplicationLink(app, perms) } - static String applicationLink(app, Permissions perms = null){ getApplicationLink(app, perms) } - static String appLink(app, Permissions perms = null){ getApplicationLink(app, perms) } + static String getAppLink(app, Permissions perms = null) { getApplicationLink(app, perms) } + static String applicationLink(app, Permissions perms = null) { getApplicationLink(app, perms) } + static String appLink(app, Permissions perms = null) { getApplicationLink(app, perms) } - void mute(t){ + void mute(t) { if (t.class.array || t instanceof Collection) mutedChannels.addAll(t.collect(this.&id)) else mutedChannels.add(id(t)) } @@ -662,10 +636,10 @@ class Client extends User { since: data.since ?: 0, afk: data.afk ?: false, ] - askPool('changePresence'){ + askPool('changePresence') { ws.send(3, payload) } - for (s in guildCache){ + for (s in guildCache) { ((DiscordListCache) s.value.presences).add( user: userObject, game: payload.game, @@ -681,9 +655,9 @@ class Client extends User { ) } - void status(status){ changePresence(status: status) } - void play(game){ changePresence(game: game) } - void playGame(game){ changePresence(game: game) } + void status(status) { changePresence(status: status) } + void play(game) { changePresence(game: game) } + void playGame(game) { changePresence(game: game) } // WEBSOCKET LISTENERS @@ -696,26 +670,34 @@ class Client extends User { @CompileStatic void fire(String type, Map d) { def g = (String) d.guild_id - if (type == 'GUILD_MEMBER_ADD') { + switch (type) { + case 'GUILD_MEMBER_ADD': ((DiscordListCache) guildCache[g].members).add(d) ((int) guildCache[g].member_count)++ - } else if (type == 'GUILD_MEMBER_REMOVE') { - if (!guildCache[g]) return - ((DiscordListCache) guildCache[g].members).remove((String) ((Map) d.user).id) - ((int) guildCache[g].member_count)-- - } else if (type == 'GUILD_ROLE_CREATE') { + break + case 'GUILD_MEMBER_REMOVE': + if (guildCache[g]) { + ((DiscordListCache) guildCache[g].members).remove((String) ((Map) d.user).id) + ((int) guildCache[g].member_count)-- + } + break + case 'GUILD_ROLE_CREATE': ((DiscordListCache) guildCache[g].roles).add((Map) d.role + [guild_id: g]) - } else if (type == 'GUILD_ROLE_DELETE') { + break + case 'GUILD_ROLE_DELETE': ((DiscordListCache) guildCache[g].roles).remove((String) d.role_id) - } else if (type == 'CHANNEL_CREATE') { - (null != g ? ((DiscordListCache) guildCache[g].channels) : - privateChannelCache).add(d) - } else if (type == 'CHANNEL_DELETE') { - (null != g ? ((DiscordListCache) guildCache[g].channels) : - privateChannelCache).remove((String) d.id) - } else if (type == 'CHANNEL_UPDATE') { - final map = (null != g ? ((DiscordListCache) guildCache[g].channels) : - privateChannelCache)[(String) d.id] + break + case 'CHANNEL_CREATE': + (null == g ? privateChannelCache : + ((DiscordListCache) guildCache[g].channels)).add(d) + break + case 'CHANNEL_DELETE': + (null == g ? privateChannelCache : + ((DiscordListCache) guildCache[g].channels)).remove((String) d.id) + break + case 'CHANNEL_UPDATE': + final map = (null == g ? privateChannelCache : + ((DiscordListCache) guildCache[g].channels))[(String) d.id] for (e in d) { if (e.key == 'permission_overwrites') { final po = (List>) e.value @@ -725,11 +707,12 @@ class Client extends User { j.put('channel_id', (String) d.id) a.add(j) } - map.permission_overwrites = new DiscordListCache(a, client, PermissionOverwrite) + map.permission_overwrites = new DiscordListCache(a, Client.this, PermissionOverwrite) } else map[e.key] = e.value } - } else if (type == 'MESSAGE_CREATE') { - if (!cacheMessages) return + break + case 'MESSAGE_CREATE': + if (!cacheMessages) break if (messages[(String) d.channel_id]) { messages[(String) d.channel_id].add(d) } else { @@ -737,8 +720,9 @@ class Client extends User { a.setRoot channel((String) d.channel_id) messages[(String) d.channel_id] = a } - } else if (type == 'MESSAGE_UPDATE') { - if (!cacheMessages) return + break + case 'MESSAGE_UPDATE': + if (!cacheMessages) break if (messages[(String) d.channel_id]) { if (messages[(String) d.channel_id][(String) d.id]) { messages[(String) d.channel_id][(String) d.id] << d @@ -750,17 +734,22 @@ class Client extends User { a.setRoot channel((String) d.channel_id) messages[(String) d.channel_id] = a } - } else if (type == 'MESSAGE_DELETE') { - if (!cacheMessages) return + break + case 'MESSAGE_DELETE': + if (!cacheMessages) break messages[(String) d.channel_id]?.remove((String) d.id) - } else if (type == 'GUILD_CREATE') { + break + case 'GUILD_CREATE': if (guildCache[(String) d.id]) guildCache[(String) d.id].putAll(d) else guildCache.add(d) - } else if (type == 'GUILD_DELETE') { + break + case 'GUILD_DELETE': guildCache.remove((String) d.id) - } else if (type == 'GUILD_MEMBER_UPDATE') { + break + case 'GUILD_MEMBER_UPDATE': ((DiscordListCache) guildCache[g].members)[(String) ((Map) d.user).id]?.putAll(d) - } else if (type == 'GUILD_ROLE_UPDATE') { + break + case 'GUILD_ROLE_UPDATE': def r = (String) ((Map) d.role).id def rc = (DiscordListCache) guildCache[g].roles if (rc.containsKey(r)) rc[r].putAll((Map) d.role) @@ -769,11 +758,26 @@ class Client extends User { x.put('guild_id', g) rc.put r, x } - } else if (type == 'GUILD_UPDATE') { + break + case 'GUILD_UPDATE': guildCache[(String) d.id] << d - } else if (type == 'PRESENCE_UPDATE') { - if (null != g) { - if (guildCache[g].unavailable) return + break + case 'PRESENCE_UPDATE': + if (null == g) { + def m = (Map) d.user + def i = (String) m.id + if (null == user(i)) for (e in privateChannelCache) { + def v = (DiscordListCache) e.value.recipients + if (v.containsKey(i)) v[i] = m + } + if (d.status == 'offline') presenceCache.remove(i) + else { + def x = new HashMap(d) + x.put('id', i) + presenceCache[i] = x + } + } else { + if (guildCache[g].unavailable) break if (((Map) d.user).avatar) { def m = (DiscordListCache) guildCache[g].members if (m.containsKey((String) ((Map) d.user).id)) { @@ -795,27 +799,17 @@ class Client extends User { di.put 'id', ((Map) d.user).id pc?.add(di) } - } else { - def m = (Map) d.user - def i = (String) m.id - if (null == user(i)) for (e in privateChannelCache) { - def v = (DiscordListCache) e.value.recipients - if (v.containsKey(i)) v[i] = m - } - if (d.status == 'offline') presenceCache.remove(i) - else { - def x = new HashMap(d) - x.put('id', i) - presenceCache[i] = x - } } - } else if (type == 'CHANNEL_RECIPIENT_ADD') { + break + case 'CHANNEL_RECIPIENT_ADD': ((DiscordListCache) privateChannelCache[(String) d.channel_id].recipients) .add((Map) d.user) - } else if (type == 'CHANNEL_RECIPIENT_REMOVE') { + break + case 'CHANNEL_RECIPIENT_REMOVE': ((DiscordListCache) privateChannelCache[(String) d.channel_id].recipients) .remove((String) ((Map) d.user).id) - } else if (type == 'VOICE_STATE_UPDATE') { + break + case 'VOICE_STATE_UPDATE': def gi = g if (null == g) { for (e in guildCache) if (((DiscordListCache) e.value.channels) @@ -826,33 +820,40 @@ class Client extends User { if (x.containsKey((String) d.id)) x[(String) d.id].putAll d else x[(String) d.id] = d } else x.remove((String) d.id) - } else if (type == 'GUILD_EMOJIS_UPDATE') { + break + case 'GUILD_EMOJIS_UPDATE': guildCache[g].emojis = d.emojis - } else if (type == 'USER_UPDATE') { + break + case 'USER_UPDATE': userObject.putAll d - } else if (type == 'GUILD_MEMBERS_CHUNK') { + break + case 'GUILD_MEMBERS_CHUNK': for (x in (List) d.members) ((DiscordListCache) guildCache[g].members).add(x + [guild_id: g]) - } else if (type == 'GUILD_SYNC') { + break + case 'GUILD_SYNC': for (x in (List) d.members) ((DiscordListCache) guildCache[g].members).add(x + [guild_id: g]) for (x in (List) d.presences) ((DiscordListCache) guildCache[g].presences).add(x + [guild_id: g]) guildCache[(String) d.id].large = d.large - } else if (type == 'USER_NOTE_UPDATE') { + break + case 'USER_NOTE_UPDATE': def n = ((Map) readyData.notes) d.note ? n.put((String) d.id, d.note) : n.remove((String) d.id) - } else if (type == 'MESSAGE_REACTION_ADD') { - if (!cacheReactions) return + break + case 'MESSAGE_REACTION_ADD': + if (!cacheReactions) break def fabricated = [user_id: (String) d.user_id, emoji : d.emoji] reactions.containsKey((String) d.message_id) ? reactions[(String) d.message_id].add(fabricated) : reactions.put((String) d.message_id, [(Map) fabricated]) - } else if (type == 'MESSAGE_REACTION_REMOVE') { - if (!cacheReactions) return + break + case 'MESSAGE_REACTION_REMOVE': + if (!cacheReactions) break def x = reactions[(String) d.message_id] - if (null == x) return + if (null == x) break int i = 0 for (a in x) { if (a.user_id == d.user_id && a.emoji == d.emoji) { @@ -861,25 +862,34 @@ class Client extends User { } i++ } - } else if (type == 'MESSAGE_REACTION_REMOVE_ALL') { - if (!cacheReactions) return + break + case 'MESSAGE_REACTION_REMOVE_ALL': + if (!cacheReactions) break reactions.remove((String) d.message_id) - } else if (type == 'RELATIONSHIP_ADD') { + break + case 'RELATIONSHIP_ADD': relationshipCache.add(d) - } else if (type == 'RELATIONSHIP_REMOVE') { + break + case 'RELATIONSHIP_REMOVE': relationshipCache.remove((String) d.id) - } else if (type == 'CALL_CREATE') { + break + case 'CALL_CREATE': calls[(String) d.channel_id] = d - } else if (type == 'CALL_UPDATE') { + break + case 'CALL_UPDATE': calls[(String) d.channel_id] << d - } else if (type == 'CALL_DELETE') { + break + case 'CALL_DELETE': calls.remove((String) d.channel_id) - } else if (type == 'USER_GUILD_SETTINGS_UPDATE') { + break + case 'USER_GUILD_SETTINGS_UPDATE': def x = userGuildSettingCache[g] if (x) x.putAll(d) else userGuildSettingCache[g] = d - } else if (type == 'USER_SETTINGS_UPDATE') { + break + case 'USER_SETTINGS_UPDATE': ((Map) readyData.user_settings) << d + break } } } @@ -897,11 +907,11 @@ class Client extends User { } } - def requestMembersOnReady(){ addListener(memberRequesterOnReady) } - def dontRequestMembersOnReady(){ removeListener(memberRequesterOnReady) } + def requestMembersOnReady() { addListener(memberRequesterOnReady) } + def dontRequestMembersOnReady() { removeListener(memberRequesterOnReady) } // add this yourself - void addReconnector(){ + void addReconnector() { addListener('close') { Map it -> if (!gatewayClosed && ((int) it.code) < 4000) ws.reconnect() } @@ -909,11 +919,12 @@ class Client extends User { // HTTP REQUESTS - List requestGuilds(boolean checkCache = true){ - http.jsonGets('users/@me/guilds').collect { - Map object = it - if (checkCache && !it.unavailable){ - def cached = guildCache[(String) it.id] + List requestGuilds(boolean checkCache = true) { + final g = http.jsonGets('users/@me/guilds') + def result = new ArrayList(g.size()) + for (object in g) { + if (checkCache && !object.unavailable) { + def cached = guildCache[(String) object.id] object.members = cached.members object.channels = cached.channels object.presences = cached.presences @@ -922,15 +933,16 @@ class Client extends User { object.emojis = cached.emojis object.large = cached.large } - new Guild(this, object) + result.add(new Guild(this, object)) } + result } - List requestPrivateChannels(){ + List requestPrivateChannels() { http.jsonGets('users/@me/channels').collect { new Channel(this, it) } } - void moveMemberVoiceChannel(s, u, vc){ + void moveMemberVoiceChannel(s, u, vc) { editMember(channel_id: id(vc), s, u) } @@ -942,26 +954,26 @@ class Client extends User { editRoles(s, u, (List) ((DiscordListCache) guildCache[id(s)].members)[id(u)].roles + r) } - void addRole(s, m, r){ + void addRole(s, m, r) { http.put("guilds/${id(s)}/members/${id(m)}/roles/${id(r)}") } - void removeRole(s, m, r){ + void removeRole(s, m, r) { http.delete("guilds/${id(s)}/members/${id(m)}/roles/${id(r)}") } - String changeOwnGuildNick(s, String nick){ - askPool('changeNick'){ + String changeOwnGuildNick(s, String nick) { + askPool('changeNick') { http.jsonPatch("guilds/${id(s)}/members/@me/nick", [nick: nick]).nick } } - void changeGuildNick(s, m, String nick){ + void changeGuildNick(s, m, String nick) { editMember(nick: nick, s, m) } - void kick(s, m){ + void kick(s, m) { http.delete("guilds/${id(s)}/members/${id(m)}") } @@ -969,19 +981,19 @@ class Client extends User { http.jsonGets("guilds/${id(s)}/bans").collect { new Guild.Ban(this, it) } } - List requestGuildInvites(s){ + List requestGuildInvites(s) { http.jsonGets("guilds/${id(s)}/invites").collect { new Invite(this, it) } } - List requestRegions(s){ + List requestRegions(s) { http.jsonGets("guilds/${id(s)}/regions").collect { new Region(this, it) } } - List requestIntegrations(s){ + List requestIntegrations(s) { http.jsonGets("guilds/${id(s)}/integrations").collect { new Integration(this, it) } } - Integration createIntegration(s, type, id){ + Integration createIntegration(s, type, id) { new Integration(this, http.jsonPost("guilds/${this.id(s)}/integrations", [type: type.toString(), id: id.toString()])) } @@ -994,11 +1006,11 @@ class Client extends User { http.delete("guilds/${id(s)}/bans/${id(u)}") } - int checkPrune(s, int d){ + int checkPrune(s, int d) { (int) http.jsonGet("guilds/${id(s)}/prune?days=$d").pruned } - int prune(s, int d){ + int prune(s, int d) { (int) http.jsonPost("guilds/${id(s)}/prune?days=$d").pruned } @@ -1019,30 +1031,30 @@ class Client extends User { http.delete("guilds/${id(s)}/roles/${id(r)}") } - List editRolePositions(Map mods, s){ + List editRolePositions(Map mods, s) { http.jsonPatches("guilds/${id(s)}/roles", mods.collect { k, v -> [id: id(k), position: v]}).collect { new Role(this, it + [guild_id: (Object) id(s)]) } } - List editChannelPositions(Map mods, s){ + List editChannelPositions(Map mods, s) { http.jsonPatches("guilds/${id(s)}/channels", mods.collect { k, v -> [id: id(k), position: v]}).collect { new Channel(this, Channel.construct(this, it, id(s))) } } - List requestGuildWebhooks(s){ + List requestGuildWebhooks(s) { http.jsonGets("guilds/${s}/webhooks").collect { new Webhook(this, it) } } - List requestMembers(s, int max=1000, boolean updateCache=true){ + List requestMembers(s, int max=1000, boolean updateCache=true) { def i = id(s) List members = http.jsonGets("guilds/$i/members?limit=${max}") - if (max > 1000){ - for (int m = 1; m < (int) Math.ceil(max / 1000) - 1; m++){ + if (max > 1000) { + for (int m = 1; m < (int) Math.ceil(max / 1000) - 1; m++) { members += http.jsonGets("guilds/$i/members?after=${(m * 1000) + 1}&limit=1000") } members += http.jsonGets("guilds/$i/members?after=${(int)((Math.ceil(max / 1000) - 1) * 1000)+1}&limit=1000") } - if (updateCache){ + if (updateCache) { guildCache[i].members = new DiscordListCache(members.collect { def r = new HashMap(it) r.put('guild_id', i) @@ -1058,51 +1070,51 @@ class Client extends User { } } - Member requestMember(s, m){ new Member(this, + Member requestMember(s, m) { new Member(this, http.jsonGet("guilds/${id(s)}/members/${id(m)}")) } - List requestEmojis(s){ http.jsonGets("guilds/${id(s)}/emojis") + List requestEmojis(s) { http.jsonGets("guilds/${id(s)}/emojis") .collect { new Emoji(this, it) } } - Emoji createEmoji(Map data, s){ + Emoji createEmoji(Map data, s) { new Emoji(this, http.jsonPost("guilds/${id(s)}/emojis", patchData(data, 'image'))) } - Emoji editEmoji(Map data, s, emoji){ + Emoji editEmoji(Map data, s, emoji) { new Emoji(this, http.jsonPatch("guilds/${id(s)}/emojis/${id(emoji)}", data)) } - Webhook requestGuildWebhook(s, w){ + Webhook requestGuildWebhook(s, w) { new Webhook(this, http.jsonGet("guilds/${id(s)}/webhooks/${id(w)}")) } - Invite acceptInvite(i){ + Invite acceptInvite(i) { new Invite(this, http.jsonPost("invite/${Invite.parseId(i)}", [:])) } - Invite requestInvite(i){ + Invite requestInvite(i) { new Invite(this, http.jsonGet("invite/${Invite.parseId(i)}")) } - Invite createInvite(Map data = [:], c){ + Invite createInvite(Map data = [:], c) { new Invite(this, http.jsonPost("channels/${id(c)}/invites", data)) } - void deleteInvite(i){ + void deleteInvite(i) { http.delete("invite/${Invite.parseId(i)}") } - Guild.Embed requestEmbed(s){ new Guild.Embed(this, http.jsonGet("guilds/${id(s)}/embed")) } + Guild.Embed requestEmbed(s) { new Guild.Embed(this, http.jsonGet("guilds/${id(s)}/embed")) } - Guild.Embed editEmbed(Map data, s, e){ new Guild.Embed(this, + Guild.Embed editEmbed(Map data, s, e) { new Guild.Embed(this, http.jsonPatch("guilds/${id(s)}/embed", data)) } - List requestConnections(){ + List requestConnections() { http.jsonGets('users/@me/connections').collect { new Connection(this, it) } } - User edit(Map data){ + User edit(Map data) { Map map = [avatar: user.avatarHash, email: this?.email, password: this?.password, username: user.username] Map response = http.jsonPatch('users/@me', map << @@ -1117,53 +1129,53 @@ class Client extends User { new User(this, response) } - Profile requestProfile(a){ + Profile requestProfile(a) { new Profile(this, http.jsonGet("users/${id(a)}/profile")) } - Application requestApplication(){ + Application requestApplication() { new Application(this, http.jsonGet('oauth2/applications/@me')) } - List requestApplications(){ + List requestApplications() { http.jsonGets('oauth2/applications').collect { new Application(this, it) } } - Application requestApplication(a){ + Application requestApplication(a) { new Application(this, http.jsonGet("oauth2/applications/${id(a)}")) } - Application editApplication(Map data, a){ + Application editApplication(Map data, a) { new Application(this, http.jsonPut("oauth2/applications/${id(a)}", patchData(data))) } - void deleteApplication(a){ + void deleteApplication(a) { http.delete("oauth2/applications/${id(a)}") } - Application createApplication(Map data){ + Application createApplication(Map data) { Map map = [icon: null, description: '', redirect_uris: [], name: ''] new Application(this, http.jsonPost('oauth2/applications', map << patchData(data))) } - BotAccount createApplicationBotAccount(a, String oldAccountToken = null){ + BotAccount createApplicationBotAccount(a, String oldAccountToken = null) { new BotAccount(this, http.jsonPost("oauth2/applications/${id(a)}/bot", (oldAccountToken == null) ? [:] : [token: oldAccountToken])) } - List requestRegions(){ + List requestRegions() { http.jsonGets('voice/regions').collect { new Region(this, it) } } - List queueUsers(String query, int limit=25){ + List queueUsers(String query, int limit=25) { http.jsonGets("users?q=${URLEncoder.encode(query, 'UTF-8')}&limit=$limit") .collect { new User(this, it) } } - User requestUser(i){ new User(this, http.jsonGet("users/${id(i)}")) } - Guild requestGuild(i){ new Guild(this, http.jsonGet("guilds/${id(i)}")) } - Channel requestChannel(i){ new Channel(this, http.jsonGet("channels/${id(i)}")) } + User requestUser(i) { new User(this, http.jsonGet("users/${id(i)}")) } + Guild requestGuild(i) { new Guild(this, http.jsonGet("guilds/${id(i)}")) } + Channel requestChannel(i) { new Channel(this, http.jsonGet("channels/${id(i)}")) } Guild editGuild(Map data, s) { new Guild(this, object << http.jsonPatch("guilds/${id(s)}", @@ -1188,62 +1200,62 @@ class Client extends User { [name: name, type: 2])) } - Channel createChannel(Map data = [:], s){ + Channel createChannel(Map data = [:], s) { new Channel(this, http.jsonPost("guilds/${id(s)}/channels", data)) } - Channel requestGuildChannel(s, c){ + Channel requestGuildChannel(s, c) { new Channel(this, http.jsonGet("guilds/${id(s)}/channels/${id(c)}")) } - List requestGuildChannels(s){ + List requestGuildChannels(s) { http.jsonGets("guilds/${id(s)}/channels").collect { new Channel(this, it) } } - Integration editIntegration(Map data, s, i){ + Integration editIntegration(Map data, s, i) { new Integration(this, http.jsonPatch("guilds/${id(s)}/integrations/${id(i)}", data)) } - void deleteIntegration(s, i){ + void deleteIntegration(s, i) { http.delete("guilds/${id(s)}/integrations/${id(i)}") } - void syncIntegration(s, i){ + void syncIntegration(s, i) { http.post("guilds/${id(s)}/integrations/${id(i)}/sync") } - void editMember(Map data, s, m){ + void editMember(Map data, s, m) { askPool('editMembers', id(s)){ http.patch("guilds/${id(s)}/members/${id(m)}", data) } } - void addChannelRecipient(c, u){ + void addChannelRecipient(c, u) { http.put("channels/${id(c)}/recipients/${id(u)}") } - void removeChannelRecipient(c, u){ + void removeChannelRecipient(c, u) { http.delete("channels/${id(c)}/recipients/${id(u)}") } - void addRelationship(u, type){ + void addRelationship(u, type) { http.put("users/@me/relationships/${id(u)}", [type: type.invokeMethod('toInteger', null)]) } - void removeRelationship(u){ + void removeRelationship(u) { http.delete("users/@me/relationships/${id(u)}") } - List requestChannelInvites(c){ + List requestChannelInvites(c) { http.jsonGets("channels/${id(c)}/invites").collect { new Invite(this, it) } } - void startTyping(c){ + void startTyping(c) { http.post("channels/${id(c)}/typing") } - void deleteChannel(c){ + void deleteChannel(c) { http.delete("channels/${id(c)}") } @@ -1252,7 +1264,7 @@ class Client extends User { patchableObject << patchData(data))) } - void editChannelOverwrite(Map data, c, o){ + void editChannelOverwrite(Map data, c, o) { String i = id(o) String type = data.type ?: (role(i) ? 'role' : 'member') int allowBytes = null == data.allow ? 0 : (int) data.allow.invokeMethod('toInteger', null) @@ -1261,20 +1273,20 @@ class Client extends User { [allow: allowBytes, deny: denyBytes, id: i, type: type]) } - void deleteChannelOverwrite(c, o){ + void deleteChannelOverwrite(c, o) { http.delete("channels/${id(c)}/permissions/${id(o)}") } - Webhook createWebhook(Map data = [:], c){ + Webhook createWebhook(Map data = [:], c) { new Webhook(this, http.jsonPost("channels/${id(c)}/webhooks", patchData(data))) } - List requestChannelWebhooks(c){ + List requestChannelWebhooks(c) { http.jsonGets("channels/${id(c)}/webhooks").collect { new Webhook(this, it) } } - Webhook requestWebhook(w){ + Webhook requestWebhook(w) { new Webhook(this, http.jsonGet("webhooks/${id(w)}")) } @@ -1282,7 +1294,7 @@ class Client extends User { new Webhook(this, http.jsonGet("webhooks/${this.id(id)}/$token")) } - Message sendMessage(Map data, c){ + Message sendMessage(Map data, c) { if (data.containsKey('content')){ def s = data.content.toString() s = filterMessage(s) @@ -1303,9 +1315,9 @@ class Client extends User { isWebhook ? clos() : askPool('sendMessages', getChannelQueueName(c), clos) } - Message sendMessage(c, content, tts = false){ sendMessage(c, content: content, tts: tts) } + Message sendMessage(c, content, tts = false) { sendMessage(c, content: content, tts: tts) } - Message editMessage(Map data, c, m){ + Message editMessage(Map data, c, m) { if (data.containsKey('content')){ def s = data.content.toString() s = filterMessage(s) @@ -1317,28 +1329,30 @@ class Client extends User { } } - void deleteMessage(c, m){ + void deleteMessage(c, m) { askPool('deleteMessages', getChannelQueueName(c)){ http.delete("channels/${id(c)}/messages/${id(m)}") } } - Map sendFileRaw(Map data = [:], c, file){ + Map sendFileRaw(Map data = [:], c, file) { boolean isWebhook = MiscUtil.defaultValueOnException new Closure(this) { @CompileDynamic def call() { data.webhook && c?.id && c?.token } } - List fileArgs = [] - if (file instanceof File){ - if (data.filename){ - fileArgs += file.bytes - fileArgs += data.filename - }else fileArgs += file - }else{ - fileArgs += ConversionUtil.getBytes(file) + File f + String fn + byte[] bytes + if (file instanceof File) { + if (data.filename) { + bytes = ((File) file).bytes + fn = (String) data.filename + } else f = (File) file + } else { + bytes = ConversionUtil.getBytes(file) if (!data.filename) throw new IllegalArgumentException("Tried to send non-file class ${file.class} and gave no filename") - fileArgs += data.filename + fn = (String) data.filename } def url = http.baseUrl + (isWebhook ? "webhooks/${id(c)}/${((Webhook) c).token}" : @@ -1348,10 +1362,10 @@ class Client extends User { .header('User-Agent', fullUserAgent) .field('content', data.content == null ? '' : data.content.toString()) .field('tts', data.tts as boolean) - if (fileArgs.size() == 1){ - aa = aa.field('file', fileArgs[0]) - }else if (fileArgs.size() == 2){ - aa = (MultipartBody) aa.invokeMethod('field', ['file', fileArgs[0], fileArgs[1]]) + if (null != f) { + aa = aa.field('file', f) + } else { + aa = aa.field('file', bytes, fn) } Closure clos = { (Map) JSONUtil.parse(aa.asString().body) @@ -1370,19 +1384,19 @@ class Client extends User { sendFile(data, c, implicatedFile, null) } - Message sendFile(c, implicatedFile, filename){ + Message sendFile(c, implicatedFile, filename) { sendFile([:], c, implicatedFile, filename) } - Message sendFile(c, implicatedFile){ + Message sendFile(c, implicatedFile) { sendFile([:], c, implicatedFile, null) } - Message requestMessage(c, ms, boolean addToCache = true){ + Message requestMessage(c, ms, boolean addToCache = true) { def ch = id(c) def m = new Message(this, http.jsonGet("channels/$ch/messages/${id(ms)}")) - if (addToCache){ + if (addToCache) { if (messages[ch]) messages[ch].add(m) else { def r = new DiscordListCache([m], this, Message) @@ -1393,60 +1407,60 @@ class Client extends User { m } - Message message(c, m, boolean request = true){ + Message message(c, m, boolean request = true) { boolean inCache = messages[id(c)].containsKey(id(m)) if (inCache) new Message(this, messages[id(c)][id(m)]) else if (request) requestMessage(c, m) else null } - String getChannelQueueName(c){ + String getChannelQueueName(c) { guildChannel(id(c)) ?: 'dm' } - def pinMessage(c, m){ + def pinMessage(c, m) { http.put("channels/${id(c)}/pins/${id(m)}") } - def unpinMessage(c, m){ + def unpinMessage(c, m) { http.delete("channels/${id(c)}/pins/${id(m)}") } - Collection requestPinnedMessages(c){ + Collection requestPinnedMessages(c) { http.jsonGets("channels/${id(c)}/pins").collect { new Message(this, it) } } - void reactToMessage(c, m, e){ + void reactToMessage(c, m, e) { http.put("channels/${id(c)}/messages/${id(m)}/" + "reactions/${translateEmoji(e)}/@me") } - void unreactToMessage(c, m, e, u = '@me'){ + void unreactToMessage(c, m, e, u = '@me') { http.delete("channels/{id(c)}/messages/${id(m)}/" + "reactions/${translateEmoji(e)}/${id(u)}") } - List requestReactors(c, m, e, int limit = 100){ + List requestReactors(c, m, e, int limit = 100) { http.jsonGets("channels/${id(c)}/messages/${id(m)}/reactions/" + translateEmoji(e) + "?limit=$limit").collect { new User(this, it) } } - String translateEmoji(emoji, s = null){ - if (emoji ==~ /\d+/){ + String translateEmoji(emoji, s = null) { + if (emoji ==~ /\d+/) { translateEmoji(emojis.find { it.id == emoji }) - }else if (emoji instanceof Emoji){ + } else if (emoji instanceof Emoji) { "$emoji.name:$emoji.id" - }else if (emoji ==~ /\w+/){ + } else if (emoji ==~ /\w+/) { def i = ((List) (guild(s)?.emojis ?: []) + (List) (emojis - guild(s)?.emojis) ).find { it.name == emoji }?.id i ? "$emoji:$i" : ":$emoji:" - }else{ + } else { emoji } } List requestChannelLogs(c, int max = 100, boundary = null, - String boundaryType = 'before'){ + String boundaryType = 'before') { Map cached = messages[id(c)] if (!boundary && cached?.size() > max) return cached.values().sort { it.id }[-1..-max].collect { new Message(this, it) } @@ -1458,29 +1472,29 @@ class Client extends User { } List forceRequestChannelLogs(c, int m = 100, b = null, - String bt = 'before'){ directRequestChannelLogs(c, m, b, bt).collect { new Message(this, it) } } + String bt = 'before') { directRequestChannelLogs(c, m, b, bt).collect { new Message(this, it) } } // after and around sorted old-new // before sorted new-old @SuppressWarnings("GroovyAssignabilityCheck") - List> directRequestChannelLogs(c, int max, boundary = null, String boundaryType = 'before'){ + List> directRequestChannelLogs(c, int max, boundary = null, String boundaryType = 'before') { Map params = [limit: (Object) (max > 100 ? 100 : max)] - if (boundary){ + if (boundary) { if (boundaryType && boundaryType != 'before' && boundaryType != 'after' && boundaryType != 'around') throw new IllegalArgumentException('Boundary type has to be before, after or around') params.put boundaryType ?: 'before', id(boundary) } List> messages = directRequestChannelLogs(params, c) - if (max > 100){ - if (boundaryType == 'after'){ + if (max > 100) { + if (boundaryType == 'after') { for (int m = 1; m < Math.floor(max / 100); m++) { messages.addAll directRequestChannelLogs(c, after: messages.last().id, limit: 100) } if (max % 100 != 0) messages.addAll directRequestChannelLogs(c, after: messages.last().id, limit: max % 100) - }else if (boundaryType == 'around'){ + } else if (boundaryType == 'around') { int age = max - 100 int af = age.intdiv(2).intValue() int bef = age.intdiv(2).intValue() + (age % 2) @@ -1495,7 +1509,7 @@ class Client extends User { } if (af % 100 != 0) messages.addAll directRequestChannelLogs([before: messages.last().id, limit: af % 100], c) - }else{ + } else { for (int m = 1; m < Math.floor(max / 100); m++) { messages.addAll directRequestChannelLogs(c, before: messages.last().id, limit: 100) @@ -1507,30 +1521,30 @@ class Client extends User { messages } - List> directRequestChannelLogs(Map data = [:], c){ + List> directRequestChannelLogs(Map data = [:], c) { String parameters = data ? '?' + data.collect { k, v -> URLEncoder.encode(k.toString(), 'UTF-8') + '=' + URLEncoder.encode(v.toString(), 'UTF-8') }.join('&') : '' http.jsonGets("channels/${id(c)}/messages$parameters") } - def bulkDeleteMessages(c, Collection ids){ - askPool('bulkDeleteMessages'){ + def bulkDeleteMessages(c, Collection ids) { + askPool('bulkDeleteMessages') { http.post("channels/${id(c)}/messages/bulk-delete", [messages: ids.collect { id(it) }]) } } - Webhook editWebhook(Map data, w){ + Webhook editWebhook(Map data, w) { new Webhook(this, http.jsonPatch("webhooks/${id(w)}", patchData(data))) } - void deleteWebhook(w){ + void deleteWebhook(w) { http.delete("webhooks/${id(w)}") } - Channel createPrivateChannel(u){ + Channel createPrivateChannel(u) { new Channel(this, http.jsonPost('users/@me/channels', [recipient_id: id(u)])) } diff --git a/src/main/groovy/hlaaftana/discordg/DSLMain.groovy b/src/main/groovy/hlaaftana/discordg/DSLMain.groovy index 12920f1..4e1a177 100644 --- a/src/main/groovy/hlaaftana/discordg/DSLMain.groovy +++ b/src/main/groovy/hlaaftana/discordg/DSLMain.groovy @@ -8,7 +8,7 @@ import hlaaftana.discordg.dsl.* @CompileStatic class DSLMain { - static void main(String[] args){ + static void main(String[] args) { ImportCustomizer imports = new ImportCustomizer() imports.addStarImports('hlaaftana.discordg', 'hlaaftana.discordg.dsl', 'hlaaftana.discordg.objects', 'hlaaftana.discordg.status', @@ -23,7 +23,7 @@ class DSLMain { script.delegate = dsl script.run() if (null != dsl.bot) dsl.bot.initialize() - else if (null != dsl.client) dsl.client.login() + else if (null != dsl.client) Thread.start { dsl.client.login() } else throw new IllegalArgumentException('Why run a DSL if you aren\'t going to use it?') } } diff --git a/src/main/groovy/hlaaftana/discordg/DiscordG.groovy b/src/main/groovy/hlaaftana/discordg/DiscordG.groovy index 14c9991..4099fcf 100644 --- a/src/main/groovy/hlaaftana/discordg/DiscordG.groovy +++ b/src/main/groovy/hlaaftana/discordg/DiscordG.groovy @@ -8,21 +8,24 @@ class DiscordG { static final String GITHUB = 'https://github.com/hlaaftana/DiscordG' static final String USER_AGENT = "groovy/$GroovySystem.version DiscordBot ($GITHUB, $VERSION)" - static Client withLogin(String email, String password){ + static Client withLogin(String email, String password, boolean threaded = true) { Client client = new Client() - client.login(email, password) + def a = { client.login(email, password) } + if (threaded) Thread.start(a) else a() client } - static Client withToken(String token, boolean bot = true){ + static Client withToken(String token, boolean bot = true, boolean threaded = true) { Client client = new Client() - client.login(token, bot) + def a = { client.login(token, bot) } + if (threaded) Thread.start(a) else a() client } - static Client withToken(String botName, String token){ + static Client withToken(String botName, String token, boolean threaded = true) { Client client = new Client() - client.login(botName){ token } + def a = { client.login(botName) { token } } + if (threaded) Thread.start(a) else a() client } } diff --git a/src/main/groovy/hlaaftana/discordg/DiscordObject.groovy b/src/main/groovy/hlaaftana/discordg/DiscordObject.groovy index 9921d99..d15c407 100644 --- a/src/main/groovy/hlaaftana/discordg/DiscordObject.groovy +++ b/src/main/groovy/hlaaftana/discordg/DiscordObject.groovy @@ -16,17 +16,17 @@ import hlaaftana.discordg.util.ConversionUtil class DiscordObject implements Comparable, JSONable { Client client Map object - DiscordObject(Client c, Map o){ + DiscordObject(Client c, Map o) { client = c object = o } - InputStream inputStreamFromDiscord(String url){ + InputStream inputStreamFromDiscord(String url) { url.toURL().newInputStream(requestProperties: ['User-Agent': client.fullUserAgent, Accept: '*/*']) } - File downloadFileFromDiscord(String url, file){ + File downloadFileFromDiscord(String url, file) { File f = file as File f.withOutputStream { out -> out << inputStreamFromDiscord(url) @@ -35,7 +35,7 @@ class DiscordObject implements Comparable, JSONable { f } - Map getRawObject(){ + Map getRawObject() { def x = new HashMap(object.size()) for (e in x) { x.put(e.key, e.value instanceof DiscordListCache ? ((DiscordListCache) e.value).rawList() : e.value) @@ -43,7 +43,7 @@ class DiscordObject implements Comparable, JSONable { x } - Map getPatchableObject(){ + Map getPatchableObject() { def x = new HashMap(object.size()) for (e in x) { if (!(e.value instanceof DiscordListCache)) x.put(e.key, e.value) @@ -51,41 +51,41 @@ class DiscordObject implements Comparable, JSONable { x } - String getId(){ object.id.toString() } - String getName(){ object.name.toString() } - String toString(){ name } - String inspect(){ "'$name' ($id)" } - Date getCreatedAt(){ new Date(createdAtMillis) } - long getCreatedAtMillis(){ idToMillis(id) } + String getId() { object.id.toString() } + String getName() { object.name.toString() } + String toString() { name } + String inspect() { "'$name' ($id)" } + Date getCreatedAt() { new Date(createdAtMillis) } + long getCreatedAtMillis() { idToMillis(id) } - static long idToMillis(id){ + static long idToMillis(id) { (Long.parseLong(this.id(id)) >> 22) + 1420070400000L } - static String millisToId(long ms, boolean raised = false){ + static String millisToId(long ms, boolean raised = false) { ((ms - 1420070400000L) << 22) + (raised ? 1 << 22 : 0) } - static String mentionToId(String mention){ + static String mentionToId(String mention) { mention.substring(Character.isDigit(mention[2] as char) ? 2 : 3, mention.length() - 1) } - static boolean isId(long x){ + static boolean isId(long x) { x instanceof long && x > 2000000000000000 } - static boolean isId(String x){ + static boolean isId(String x) { x.isLong() && x.toLong() > 2000000000000000 } - static boolean isMention(String x){ + static boolean isMention(String x) { def a = x.charAt(0), b = x.charAt(1), c a == ((char) '<') && b == ((char) '@') || b == ((char) '#') && (Character.isDigit((c = x.charAt(2))) || c == ((char) '&') || c == ((char) '!')) && x.charAt(x.length() - 1) == (char) '>' } - static Map patchData(Map data, ...imageKeys = ['avatar', 'icon']){ + static Map patchData(Map data, ...imageKeys = ['avatar', 'icon']) { Map a = new HashMap(data.size()) for (e in data) { a.put(CasingType.camel.to(CasingType.snake, e.key.toString()), e.value) @@ -95,7 +95,7 @@ class DiscordObject implements Comparable, JSONable { if (a.containsKey(key)){ if (ConversionUtil.isImagable(a[key])){ a[key] = ConversionUtil.encodeImageBase64(a[key]) - }else{ + } else { throw new IllegalArgumentException("$key cannot be resolved " + "for class ${data[key].getClass()}") } @@ -104,69 +104,69 @@ class DiscordObject implements Comparable, JSONable { a } - static Map find(Collection ass, value){ + static Map find(Collection ass, value) { String bong = id(value) if (!bong || !ass) return null if (isId(bong)){ findId(ass, bong) ?: findName(ass, bong) - }else{ + } else { findName(ass, bong) } } - static Map find(Collection ass, Map idMap, value){ + static Map find(Collection ass, Map idMap, value) { String bong = id(value) if (!bong || !ass) return null if (isId(bong) && idMap.containsKey(bong)){ idMap[bong] - }else{ + } else { findName(ass, bong) } } - static T findBuilt(Collection ass, value){ + static T findBuilt(Collection ass, value) { String bong = id(value) if (!bong || !ass) return null if (isId(bong)){ findId(ass, bong) ?: findNameBuilt(ass, bong) - }else{ + } else { findNameBuilt(ass, bong) } } - static T findBuilt(Map idMap, value){ + static T findBuilt(Map idMap, value) { String bong = id(value) if (!bong || !idMap) return null if (isId(bong) && idMap.containsKey(bong)){ idMap[bong] - }else{ + } else { findNameBuilt(idMap.values(), bong) } } - static T find(DiscordListCache cache, value){ + static T find(DiscordListCache cache, value) { String a = id(value) if (!a || !cache) return null isId(a) && cache.containsKey(a) ? cache.at(a) : findName(cache, a) } - static Member findMember(DiscordListCache cache, value){ + static Member findMember(DiscordListCache cache, value) { String a = id(value) if (!a || !cache) return null isId(a) && cache.containsKey(a) ? cache.at(a) : findMemberName(cache, a) } - static List findAll(DiscordListCache cache, value){ + static List findAll(DiscordListCache cache, value) { String a = id(value) if (!a || !cache) return null isId(a) && cache.containsKey(a) ? [cache.at(a)] : findAllName(cache, a) } - static T findNested(DiscordListCache cache, name, value){ + static T findNested(DiscordListCache cache, name, value) { String x = id(value) if (!x || !cache) return null boolean a = isId(x) - for (e in cache){ + for (e in cache) { def c = (DiscordListCache) ((Map) e.value).get(name) if (null == c || c.isEmpty()) return null if (a && c.containsKey(x)) return c.class().newInstance(cache.client(), c[x]) @@ -178,12 +178,12 @@ class DiscordObject implements Comparable, JSONable { null } - static List findAllNested(DiscordListCache cache, name, value){ + static List findAllNested(DiscordListCache cache, name, value) { String x = id(value) if (!x || !cache) return [] boolean a = isId(x) def d = [] - for (e in cache){ + for (e in cache) { def c = (DiscordListCache) ((Map) e.value).get(name) if (null == c || c.isEmpty()) return [] if (a && c.containsKey(x)) d.add c.class().newInstance(cache.client(), c[x]) @@ -195,7 +195,7 @@ class DiscordObject implements Comparable, JSONable { d } - static String resolveId(thing){ + static String resolveId(thing) { if (null == thing) null else if (thing instanceof String) isMention(thing) ? mentionToId(thing) : thing else if (thing instanceof DiscordObject) thing.id @@ -209,9 +209,9 @@ class DiscordObject implements Comparable, JSONable { @CompileDynamic private static dynamicprop(a, String name) { a."$name" } - static String id(thing){ resolveId(thing) } + static String id(thing) { resolveId(thing) } - static T find(Collection ass, String propertyName, value){ + static T find(Collection ass, String propertyName, value) { if (!ass || null == value) return null int hash = value.hashCode() for (x in ass) { @@ -232,12 +232,12 @@ class DiscordObject implements Comparable, JSONable { ((Map) o.user).username == v || o.nick == v } - static Map findName(Collection ass, value){ + static Map findName(Collection ass, value) { if (!ass || null == value) return null ass.find(nameClosure.rcurry(value.toString())) } - static T findNameBuilt(Collection ass, value){ + static T findNameBuilt(Collection ass, value) { if (!ass || null == value) return null final s = value.toString() final h = s.hashCode() @@ -245,19 +245,19 @@ class DiscordObject implements Comparable, JSONable { null } - static T findName(DiscordListCache cache, value){ + static T findName(DiscordListCache cache, value) { if (null == value || !cache) return null def i = cache.rawList().find(nameClosure.rcurry(value)) null == i ? null : cache.at(i.id) } - static Member findMemberName(DiscordListCache cache, value){ + static Member findMemberName(DiscordListCache cache, value) { if (null == value || !cache) return null def i = cache.rawList().find(memberNameClosure.rcurry(value)) null == i ? null : cache.at(i.id) } - static List findAllName(DiscordListCache cache, value){ + static List findAllName(DiscordListCache cache, value) { if (null == value || !cache) return null def i = cache.rawList().findAll(nameClosure.rcurry(value)) if (i.empty) return [] @@ -266,7 +266,7 @@ class DiscordObject implements Comparable, JSONable { res } - static T findId(Collection ass, value){ + static T findId(Collection ass, value) { if (null == value || !ass) return null int hash = value.hashCode() for (x in ass) { @@ -276,20 +276,20 @@ class DiscordObject implements Comparable, JSONable { null } - DiscordObject swapClient(Client newClient){ + DiscordObject swapClient(Client newClient) { def oldNotClient = this oldNotClient.client = newClient oldNotClient } - boolean isCase(other){ id(other) in id } - boolean equals(other){ id == id(other) } + boolean isCase(other) { id(other) in id } + boolean equals(other) { id == id(other) } - int hashCode(){ + int hashCode() { id.hashCode() } /// compares creation dates - int compareTo(other){ + int compareTo(other) { id.toLong() <=> id(other).toLong() } diff --git a/src/main/groovy/hlaaftana/discordg/Permissions.groovy b/src/main/groovy/hlaaftana/discordg/Permissions.groovy index a3b08d8..6c85c2d 100644 --- a/src/main/groovy/hlaaftana/discordg/Permissions.groovy +++ b/src/main/groovy/hlaaftana/discordg/Permissions.groovy @@ -14,10 +14,11 @@ class Permissions { static final Permissions PRIVATE_CHANNEL = new Permissions(0b0000000000000011101110000000000) int value - Permissions(Map defaults) { for (e in defaults) each { set(e.key, e.value) } } - Permissions(v = 0){ value = v as int } + Permissions(Map defaults) { for (e in defaults) set(e.key, e.value) } + Permissions(int v = 0) { value = v } + Permissions(long v) { this((int) v) } - Map getOffsetMap(){ + Map getOffsetMap() { Map r = new HashMap<>() for (b in BitOffsets.values()) { r.put(b, get(b.offset)) @@ -25,73 +26,71 @@ class Permissions { r } - Map getLocalizedMap(){ + Map getLocalizedMap() { Map a = new HashMap<>() for (e in offsetMap) for (l in e.key.locals) a.put(l, e.value) a } - Map getMap(){ - localizedMap - } + Map getMap() { localizedMap } - Permissions set(String permissionName, boolean truth){ + Permissions set(String permissionName, boolean truth) { putAt(BitOffsets.get(permissionName).offset, truth) this } - Permissions plus(Permissions other){ + Permissions plus(Permissions other) { new Permissions(value | other.value) } - Permissions minus(Permissions other){ + Permissions minus(Permissions other) { new Permissions(value & ~other.value) } - boolean get(BitOffsets bitOffset){ + boolean get(BitOffsets bitOffset) { getAt(BitOffsets.get(bitOffset).offset) } - boolean get(bitOffset){ + boolean get(bitOffset) { getAt(BitOffsets.get(bitOffset).offset) } - boolean get(int index){ - ((value >> index) & 1) as boolean + boolean get(int index) { + ((value >> index) & 1) == 1 } - boolean getAt(BitOffsets w){ + boolean getAt(BitOffsets w) { get(w) } - boolean getAt(int w){ + boolean getAt(int w) { get(w) } - boolean getAt(w){ + boolean getAt(w) { get(w) } - int putAt(int index, boolean truth){ + int putAt(int index, boolean truth) { if (truth) value |= (1 << index) else value &= ~(1 << index) value } - Permissions putAt(String permissionName, boolean truth){ + Permissions putAt(String permissionName, boolean truth) { set(permissionName, truth) } - def propertyMissing(String bitOffset){ + def propertyMissing(String bitOffset) { get(bitOffset) } - def propertyMissing(String bitOffset, value){ + def propertyMissing(String bitOffset, value) { set(bitOffset, value as boolean) } - def asType(Class target){ - switch (target){ + def asType(Class target) { + switch (target) { case int: case Integer: return value @@ -103,7 +102,7 @@ class Permissions { } } - String toString(){ map.toString() } + String toString() { map.toString() } int toInteger() { value } static enum BitOffsets { @@ -137,17 +136,17 @@ class Permissions { Set locals int offset - BitOffsets(List locals, int offset){ + BitOffsets(List locals, int offset) { this.offset = offset this.locals = new HashSet<>(locals) } - BitOffsets(String local, int offset){ + BitOffsets(String local, int offset) { this([local], offset) } @Memoized - static BitOffsets get(thing){ + static BitOffsets get(thing) { if (thing instanceof Number) { for (v in values()) if (v.offset == thing as int) return v null diff --git a/src/main/groovy/hlaaftana/discordg/collections/Cache.groovy b/src/main/groovy/hlaaftana/discordg/collections/Cache.groovy index bd2fa85..dbddaf1 100644 --- a/src/main/groovy/hlaaftana/discordg/collections/Cache.groovy +++ b/src/main/groovy/hlaaftana/discordg/collections/Cache.groovy @@ -6,16 +6,16 @@ import groovy.transform.CompileStatic class Cache implements Map { def root @Delegate(excludes = ['plus', 'getClass']) Map store - Cache(Map store, root = null){ this.root = root; this.store = store } + Cache(Map store, root = null) { this.root = root; this.store = store } Map store() { store } Map store(Map n) { store = n } - static Cache empty(root = null){ + static Cache empty(root = null) { new Cache([:], root) } - def plus(Cache other){ + def plus(Cache other) { new Cache(store + other.store(), root) } } diff --git a/src/main/groovy/hlaaftana/discordg/collections/DiscordListCache.groovy b/src/main/groovy/hlaaftana/discordg/collections/DiscordListCache.groovy index 868d411..d8d60f5 100644 --- a/src/main/groovy/hlaaftana/discordg/collections/DiscordListCache.groovy +++ b/src/main/groovy/hlaaftana/discordg/collections/DiscordListCache.groovy @@ -10,7 +10,7 @@ import hlaaftana.discordg.objects.Member class DiscordListCache extends Cache> { Class class_ Client client - DiscordListCache(List list, Client client, Class class_ = (Class) DiscordObject){ + DiscordListCache(List list, Client client, Class class_ = (Class) DiscordObject) { super(superlister(list), client) this.client = client this.class_ = class_ @@ -52,14 +52,14 @@ class DiscordListCache extends Cache> rawList() { try{ store.values().collect() - }catch (ConcurrentModificationException ignored){ + }catch (ConcurrentModificationException ignored) { println 'inform me' Thread.sleep 250 rawList() } } - List> rawList(List newList){ + List> rawList(List newList) { for (it in newList) { if (it instanceof DiscordObject) put(((DiscordObject) it).id, ((DiscordObject) it).object) else if (it instanceof Map) put(((Map) it).id.toString(), it) @@ -68,19 +68,19 @@ class DiscordListCache extends Cache) object.user).id : object.id).toString(), object) } - def add(DiscordObject uh){ + def add(DiscordObject uh) { store[uh.id] = uh.object } - Map remove(key){ + Map remove(key) { store.remove(DiscordObject.id(key)) } } \ No newline at end of file diff --git a/src/main/groovy/hlaaftana/discordg/collections/LazyClosureMap.groovy b/src/main/groovy/hlaaftana/discordg/collections/LazyClosureMap.groovy index 0a8a33c..35ca2ca 100644 --- a/src/main/groovy/hlaaftana/discordg/collections/LazyClosureMap.groovy +++ b/src/main/groovy/hlaaftana/discordg/collections/LazyClosureMap.groovy @@ -10,17 +10,17 @@ import java.util.concurrent.FutureTask class LazyClosureMap implements Map { List> entries = Collections.synchronizedList([]) - LazyClosureMap(){} - LazyClosureMap(Map map){ putAll(map) } + LazyClosureMap() {} + LazyClosureMap(Map map) { putAll(map) } - static LazyClosureMap create(Map initial = [:], Closure c){ + static LazyClosureMap create(Map initial = [:], Closure c) { c.delegate = new LazyClosureMapBuilder(initial) c.resolveStrategy = Closure.OWNER_FIRST c() ((LazyClosureMapBuilder) c.delegate).result } - LazyEntry addEntry(LazyEntry entry){ + LazyEntry addEntry(LazyEntry entry) { int a = -1 def k = entry.key def khc = k.hashCode() @@ -36,31 +36,31 @@ class LazyClosureMap implements Map { entry } - Closure put(K key, boolean lazy = true, Closure value){ + Closure put(K key, boolean lazy = true, Closure value) { addEntry(new LazyEntry(this, key, lazy ? value : { (V) value })).rawValue } - Closure put(K key, boolean lazy = true, V value){ + Closure put(K key, boolean lazy = true, V value) { put(key, Closure.IDENTITY.curry(value)) } - Closure putClosure(K key, Closure value){ + Closure putClosure(K key, Closure value) { put(key, false, value) } - Closure putAt(K key, boolean lazy = true, Closure value){ + Closure putAt(K key, boolean lazy = true, Closure value) { put(key, lazy, value) } - Closure putAt(K key, boolean lazy = true, V ass){ + Closure putAt(K key, boolean lazy = true, V ass) { put(key, lazy, ass) } - Closure putAt(String key, boolean lazy = true, Closure value){ + Closure putAt(String key, boolean lazy = true, Closure value) { put((K) key, lazy, value) } - Closure putAt(String key, boolean lazy = true, V ass){ + Closure putAt(String key, boolean lazy = true, V ass) { put((K) key, lazy, ass) } @@ -68,55 +68,55 @@ class LazyClosureMap implements Map { for (e in m) put((K) e.key, false, (V) e.value) } - void putAll(LazyClosureMap map){ + void putAll(LazyClosureMap map) { for (e in map.getEntries()) put(e.key, true, e.rawValue) } - def alias(K key, K... otherKeys){ + def alias(K key, K... otherKeys) { for (int i = 0; i < otherKeys.length; ++i) this[otherKeys[i]] = getRaw(key) } - LazyClosureMap rawEach(Closure closure){ + LazyClosureMap rawEach(Closure closure) { if (closure.maximumNumberOfParameters == 2) rawEntryTuples().each(closure) else entrySet().each(closure) this } - def List rawCollect(Closure closure){ + def List rawCollect(Closure closure) { if (closure.maximumNumberOfParameters == 2) rawEntryTuples().collect(closure) else entrySet().collect(closure) } - boolean rawAny(Closure closure){ + boolean rawAny(Closure closure) { if (closure.maximumNumberOfParameters == 2) rawEntryTuples().any(closure) else entrySet().any(closure) } - boolean rawEvery(Closure closure){ + boolean rawEvery(Closure closure) { if (closure.maximumNumberOfParameters == 2) rawEntryTuples().every(closure) else entrySet().every(closure) } - LazyEntry rawFind(Closure closure){ + LazyEntry rawFind(Closure closure) { if (closure.maximumNumberOfParameters == 2) { entrySet().find { closure([it.key, it.rawValue]) } } else entrySet().find(closure) } - Set> rawFindAll(Closure closure){ + Set> rawFindAll(Closure closure) { if (closure.maximumNumberOfParameters == 2) { entrySet().findAll { closure([it.key, it.rawValue]) } } else entrySet().findAll(closure) } - boolean containsKey(key){ + boolean containsKey(key) { int hash = key.hashCode() for (e in entries) if (e.key.hashCode() == hash && e.key == key) return true false } - boolean containsRawValue(Closure value){ + boolean containsRawValue(Closure value) { for (e in entries) if (e.rawValue == value) return true false } @@ -134,115 +134,115 @@ class LazyClosureMap implements Map { entries.empty } - Set> entrySet(){ + Set> entrySet() { new HashSet<>(entries) } - List> entryTuples(){ + List> entryTuples() { entrySet().collect { [it.key, it.value] as Tuple2 } } - List>> rawEntryTuples(){ + List>> rawEntryTuples() { entrySet().collect { [it.key, it.rawValue] as Tuple2 } } - Set keySet(){ + Set keySet() { entrySet()*.key as Set } - List values(){ + List values() { entries*.value } - List> rawValues(){ + List> rawValues() { entries*.rawValue } - LazyEntry getEntry(K key){ + LazyEntry getEntry(K key) { int hash = key.hashCode() for (e in entries) if (e.key.hashCode() == hash && e.key == key) return e null } - V get(key){ + V get(key) { getEntry((K) key)?.value } - V getAt(K key){ + V getAt(K key) { get(key) } - V getAt(String key){ + V getAt(String key) { get((K) key) } - V getProperty(String key){ + V getProperty(String key) { get((K) key) } @CompileDynamic - void setProperty(String key, value){ + void setProperty(String key, value) { put((K) key, (V) value) } - void setProperty(String key, Closure value){ + void setProperty(String key, Closure value) { put((K) key, (V) value) } - Closure getRaw(K key){ + Closure getRaw(K key) { getEntry(key)?.rawValue } - LazyEntry removeEntry(K key){ + LazyEntry removeEntry(K key) { LazyEntry entry = getEntry(key) entries.remove(entry) entry } - V remove(key){ + V remove(key) { removeEntry((K) key)?.value } - Closure removeRaw(K key){ + Closure removeRaw(K key) { removeEntry(key)?.rawValue } - void clear(){ + void clear() { entries.clear() } - LazyClosureMap build(){ + LazyClosureMap build() { LazyClosureMap ass = this ass.buildSelf() } - LazyClosureMap buildSelf(){ + LazyClosureMap buildSelf() { refreshAll() evaluateAll() this } - Future buildSelfAsync(){ + Future buildSelfAsync() { new FutureTask(this.&buildSelf) } - Future buildAsync(){ + Future buildAsync() { new FutureTask(this.&build) } - V evaluate(K key){ + V evaluate(K key) { getEntry(key).value } - List evaluateAll(){ + List evaluateAll() { entries*.value } - V refresh(K key){ + V refresh(K key) { getEntry(key).refresh() } - List refreshAll(){ + List refreshAll() { entries*.refresh() } @@ -252,25 +252,25 @@ class LazyClosureMap implements Map { private Closure value private V evaluatedValue boolean evaluated - LazyEntry(LazyClosureMap map, K key, Closure value){ this.map = map; this.key = key; this.value = value } + LazyEntry(LazyClosureMap map, K key, Closure value) { this.map = map; this.key = key; this.value = value } Closure getRawValue() { this.@value } V getValue() { - if (!evaluated){ + if (!evaluated) { evaluatedValue = this.@value(map) evaluated = true } evaluatedValue } - Closure setValue(boolean lazy = true, Closure newValue){ + Closure setValue(boolean lazy = true, Closure newValue) { map.put(key, lazy, newValue) } - Closure setValue(V newValue){ + Closure setValue(V newValue) { map.put(key, newValue) } @@ -283,7 +283,7 @@ class LazyClosureMap implements Map { evaluatedValue } - boolean equals(Map.Entry other){ + boolean equals(Map.Entry other) { other.key == this.key && ( (other instanceof LazyEntry ? ((LazyEntry) other).rawValue == this.rawValue : @@ -291,7 +291,7 @@ class LazyClosureMap implements Map { || other.value == this.value) } - boolean equals(other){ + boolean equals(other) { other instanceof Map.Entry && equals((Map.Entry) other) } @@ -301,35 +301,35 @@ class LazyClosureMap implements Map { @CompileStatic class LazyClosureMapBuilder { LazyClosureMap result = [:] - LazyClosureMapBuilder(){} - LazyClosureMapBuilder(Map initial){ result << initial } + LazyClosureMapBuilder() {} + LazyClosureMapBuilder(Map initial) { result << initial } - def alias(o, ...g){ + def alias(o, ...g) { g.each { result[g] = result.getRaw(o) } } - def methodMissing(String name, args){ + def methodMissing(String name, args) { if (args.class.array) args = ((Object[]) args).toList() - if (args instanceof Collection){ - if (args[0] instanceof Closure){ + if (args instanceof Collection) { + if (args[0] instanceof Closure) { result[name] = args[0] - }else if (args[0] instanceof Boolean && args[1] instanceof Closure){ + } else if (args[0] instanceof Boolean && args[1] instanceof Closure) { result.put(name, (boolean) args[0], (Closure) args[1]) - }else if (args[0] instanceof Closure){ + } else if (args[0] instanceof Closure) { result.put(name, true, args[0]) - }else{ + } else { result.put(name, args[0]) } - }else{ + } else { methodMissing(name, [args]) } } - def propertyMissing(String name){ + def propertyMissing(String name) { result[name] } - def propertyMissing(String name, value){ + def propertyMissing(String name, value) { methodMissing(name, value) } } diff --git a/src/main/groovy/hlaaftana/discordg/dsl/BotBuilder.groovy b/src/main/groovy/hlaaftana/discordg/dsl/BotBuilder.groovy index e94a6c7..178bca3 100644 --- a/src/main/groovy/hlaaftana/discordg/dsl/BotBuilder.groovy +++ b/src/main/groovy/hlaaftana/discordg/dsl/BotBuilder.groovy @@ -14,7 +14,7 @@ class BotBuilder { this.options = options } - def client(Map data = [:], Closure closure){ + def client(Map data = [:], Closure closure) { ClientBuilder dad = new ClientBuilder(data) closure.delegate = dad closure() diff --git a/src/main/groovy/hlaaftana/discordg/dsl/ClientBuilder.groovy b/src/main/groovy/hlaaftana/discordg/dsl/ClientBuilder.groovy index 160d507..255e7ff 100644 --- a/src/main/groovy/hlaaftana/discordg/dsl/ClientBuilder.groovy +++ b/src/main/groovy/hlaaftana/discordg/dsl/ClientBuilder.groovy @@ -9,7 +9,7 @@ class ClientBuilder { Map options @Delegate(excludes = ['client', 'toString', 'getClass', 'sendFile']) Client client - ClientBuilder(Map options = [:]){ + ClientBuilder(Map options = [:]) { client = new Client() for (e in options) client.setProperty((String) e.key, e.value) this.options = options @@ -19,7 +19,7 @@ class ClientBuilder { int threadPoolSize(int x) { client.threadPoolSize = x } def shard(int id, int num) { client.shardTuple = new Tuple2<>(id, num) } - def Closure listener(event, Closure dung){ + def Closure listener(event, Closure dung) { client.addListener(event) { Map d -> dung.delegate = new EventData(event, d) dung.resolveStrategy = Closure.DELEGATE_FIRST diff --git a/src/main/groovy/hlaaftana/discordg/exceptions/BadRequestException.groovy b/src/main/groovy/hlaaftana/discordg/exceptions/BadRequestException.groovy index eaf2b50..33eff1a 100644 --- a/src/main/groovy/hlaaftana/discordg/exceptions/BadRequestException.groovy +++ b/src/main/groovy/hlaaftana/discordg/exceptions/BadRequestException.groovy @@ -4,7 +4,7 @@ import groovy.transform.CompileStatic @CompileStatic class BadRequestException extends HTTPException { - BadRequestException(url, Map res){ + BadRequestException(url, Map res) { super(res.collect { k, v -> "$k: $v" }.join('\n'), url, res) } } diff --git a/src/main/groovy/hlaaftana/discordg/exceptions/HTTP5xxException.groovy b/src/main/groovy/hlaaftana/discordg/exceptions/HTTP5xxException.groovy index e37a31e..e3342a4 100644 --- a/src/main/groovy/hlaaftana/discordg/exceptions/HTTP5xxException.groovy +++ b/src/main/groovy/hlaaftana/discordg/exceptions/HTTP5xxException.groovy @@ -4,7 +4,7 @@ import groovy.transform.CompileStatic @CompileStatic class HTTP5xxException extends HTTPException { - HTTP5xxException(url, Map res){ + HTTP5xxException(url, Map res) { super("$res.code when connecting to $url, message: $res.message", url, res) } } diff --git a/src/main/groovy/hlaaftana/discordg/exceptions/HTTPException.groovy b/src/main/groovy/hlaaftana/discordg/exceptions/HTTPException.groovy index 5549ead..374e896 100644 --- a/src/main/groovy/hlaaftana/discordg/exceptions/HTTPException.groovy +++ b/src/main/groovy/hlaaftana/discordg/exceptions/HTTPException.groovy @@ -6,5 +6,5 @@ import groovy.transform.CompileStatic class HTTPException extends Exception { String url Map response - HTTPException(message, u, Map res){ super(message.toString()); response = res; url = u.toString() } + HTTPException(message, u, Map res) { super(message.toString()); response = res; url = u.toString() } } diff --git a/src/main/groovy/hlaaftana/discordg/exceptions/InvalidTokenException.groovy b/src/main/groovy/hlaaftana/discordg/exceptions/InvalidTokenException.groovy index faecadd..1951162 100644 --- a/src/main/groovy/hlaaftana/discordg/exceptions/InvalidTokenException.groovy +++ b/src/main/groovy/hlaaftana/discordg/exceptions/InvalidTokenException.groovy @@ -4,7 +4,7 @@ import groovy.transform.CompileStatic @CompileStatic class InvalidTokenException extends HTTPException { - InvalidTokenException(url, Map res){ + InvalidTokenException(url, Map res) { super('Current token invalid. Try deleting the token cache file and restarting', url, res) } } diff --git a/src/main/groovy/hlaaftana/discordg/exceptions/MessageInvalidException.groovy b/src/main/groovy/hlaaftana/discordg/exceptions/MessageInvalidException.groovy index a0721fa..62b0b14 100644 --- a/src/main/groovy/hlaaftana/discordg/exceptions/MessageInvalidException.groovy +++ b/src/main/groovy/hlaaftana/discordg/exceptions/MessageInvalidException.groovy @@ -4,7 +4,7 @@ import groovy.transform.CompileStatic @CompileStatic class MessageInvalidException extends Exception { - MessageInvalidException(String message){ + MessageInvalidException(String message) { super(message ? 'Message longer than 2000 characters' : 'Cannot send empty message') } } diff --git a/src/main/groovy/hlaaftana/discordg/exceptions/NoPermissionException.groovy b/src/main/groovy/hlaaftana/discordg/exceptions/NoPermissionException.groovy index 46c95ab..7127866 100644 --- a/src/main/groovy/hlaaftana/discordg/exceptions/NoPermissionException.groovy +++ b/src/main/groovy/hlaaftana/discordg/exceptions/NoPermissionException.groovy @@ -4,7 +4,7 @@ import groovy.transform.CompileStatic @CompileStatic class NoPermissionException extends HTTPException { - NoPermissionException(url, Map res){ + NoPermissionException(url, Map res) { super("Insufficient permissions while connecting to $url, message: $res.message", url, res) } } diff --git a/src/main/groovy/hlaaftana/discordg/exceptions/NotFoundException.groovy b/src/main/groovy/hlaaftana/discordg/exceptions/NotFoundException.groovy index 8498ecb..ec1d7c4 100644 --- a/src/main/groovy/hlaaftana/discordg/exceptions/NotFoundException.groovy +++ b/src/main/groovy/hlaaftana/discordg/exceptions/NotFoundException.groovy @@ -4,5 +4,5 @@ import groovy.transform.CompileStatic @CompileStatic class NotFoundException extends HTTPException { - NotFoundException(url, Map res){ super("$url with message: $res.message", url, res) } + NotFoundException(url, Map res) { super("$url with message: $res.message", url, res) } } diff --git a/src/main/groovy/hlaaftana/discordg/logic/ActionPool.groovy b/src/main/groovy/hlaaftana/discordg/logic/ActionPool.groovy index 68ea275..46a4f6f 100644 --- a/src/main/groovy/hlaaftana/discordg/logic/ActionPool.groovy +++ b/src/main/groovy/hlaaftana/discordg/logic/ActionPool.groovy @@ -4,37 +4,58 @@ import groovy.transform.CompileStatic import java.util.concurrent.Executors import java.util.concurrent.ExecutorService +import java.util.concurrent.atomic.AtomicInteger @CompileStatic class ActionPool { long max long ms ExecutorService waitPool - Map actions = [:] - Closure suspend = { String it -> (actions[it] ?: 0) >= max } - - static ActionPool create(long max, long ms){ - def ap = new ActionPool() - ap.max = max - ap.ms = ms - ap + Map actions = [:].asSynchronized() + Closure suspend = { String it -> + final t = actions[it] + (null == t ? t : 0) >= max } - long setMax(long n){ + ActionPool() {} + + ActionPool(long max, long ms) { + this.max = max + this.ms = ms + } + + static ActionPool create(long max, long ms) { + new ActionPool(max, ms) + } + + long setMax(long n) { this.@max = n waitPool = Executors.newFixedThreadPool(n as int) max } - def T ask(String bucket = '$', Closure action){ + def T ask(String bucket = '$', Closure action) { while (suspend(bucket)) { Thread.sleep 10 } - if (actions[bucket]) actions[bucket]++ - else actions[bucket] = 1 + final t = actions[bucket] + if (null == t) actions[bucket] = new AtomicInteger(1) + else actions[bucket].getAndIncrement() def result = action() waitPool.submit { Thread.sleep(ms) - actions[bucket] = actions[bucket] - 1 + actions[bucket].getAndDecrement() } result } + + void ask(String bucket = '$', Runnable action) { + while (suspend(bucket)) { Thread.sleep 10 } + final t = actions[bucket] + if (null == t) actions[bucket] = new AtomicInteger(1) + else actions[bucket].getAndIncrement() + action.run() + waitPool.submit { + Thread.sleep(ms) + actions[bucket].getAndDecrement() + } + } } diff --git a/src/main/groovy/hlaaftana/discordg/logic/BasicListenerSystem.groovy b/src/main/groovy/hlaaftana/discordg/logic/BasicListenerSystem.groovy index f37f528..94b291c 100644 --- a/src/main/groovy/hlaaftana/discordg/logic/BasicListenerSystem.groovy +++ b/src/main/groovy/hlaaftana/discordg/logic/BasicListenerSystem.groovy @@ -6,7 +6,7 @@ import groovy.transform.CompileStatic class BasicListenerSystem extends ListenerSystem { def parseEvent(param) { param } - def listenerError(event, Throwable ex, Closure closure, T data){ + void listenerError(event, Throwable ex, Closure closure, T data) { throw new ListenerException(event, ex, closure, data) } } @@ -14,7 +14,7 @@ class BasicListenerSystem extends ListenerSystem { @CompileStatic class ListenerException extends Exception { def event, data, closure - ListenerException(e, Throwable ex, c, d){ + ListenerException(e, Throwable ex, c, d) { super(ex.toString(), ex) event = e data = d diff --git a/src/main/groovy/hlaaftana/discordg/logic/EventData.groovy b/src/main/groovy/hlaaftana/discordg/logic/EventData.groovy index 2ff85c3..7f915c1 100644 --- a/src/main/groovy/hlaaftana/discordg/logic/EventData.groovy +++ b/src/main/groovy/hlaaftana/discordg/logic/EventData.groovy @@ -7,9 +7,9 @@ import hlaaftana.discordg.collections.LazyClosureMap @CompileStatic class EventData extends LazyClosureMap { String type - EventData(type, Map data){ super(data); this.type = Client.parseEvent(type) } + EventData(type, Map data) { super(data); this.type = Client.parseEvent(type) } - EventData clone(){ + EventData clone() { EventData a = new EventData(type, [:]) rawEach { String k, v -> a[k] = (Closure) v.clone() } a @@ -19,21 +19,21 @@ class EventData extends LazyClosureMap { put name, obj } - def getProperty(String name){ + def getProperty(String name) { String methodName = 'get' + name.capitalize() if (methodName in getMetaClass().methods*.name) this.invokeMethod(methodName, null) else if (containsKey(name)) get name else throw new MissingPropertyException(name, this.class)//propertyMissing(name) } - void setProperty(String name, value){ + void setProperty(String name, value) { String methodName = 'set' + name.capitalize() if (methodName in getMetaClass().methods*.name) this.invokeMethod(methodName, value) else if (containsKey(name)) put name, value else throw new MissingPropertyException(name, this.class)//propertyMissing(name, value) } - def methodMissing(String name, args){ + def methodMissing(String name, args) { if (containsKey(this)) get(name).invokeMethod('call', args) else throw new MissingMethodException(name, EventData, args as Object[]) } diff --git a/src/main/groovy/hlaaftana/discordg/logic/ListenerSystem.groovy b/src/main/groovy/hlaaftana/discordg/logic/ListenerSystem.groovy index 4cf3bfd..50afca1 100644 --- a/src/main/groovy/hlaaftana/discordg/logic/ListenerSystem.groovy +++ b/src/main/groovy/hlaaftana/discordg/logic/ListenerSystem.groovy @@ -8,51 +8,54 @@ abstract class ListenerSystem { abstract parseEvent(param) - abstract listenerError(event, Throwable ex, Closure closure, T data) + abstract void listenerError(event, Throwable ex, Closure closure, T data) - Closure submit(event, boolean temporary = false, @DelegatesTo(T) Closure closure){ - addListener(event, temporary, closure) + def Closure temporaryListener(event, Closure closure) { + return { + final result = closure.call(it) + listeners.get(event).remove(closure) + result + } } - Closure addListener(event, boolean temporary = false, Closure closure) { + def Closure addListener(event, Closure closure) { event = parseEvent(event) - if (temporary) closure = { Map d -> closure(d); listeners.get(event).remove(closure) } - if (listeners.containsKey(event)) listeners[event] = listeners[event] + closure + if (listeners.containsKey(event)) listeners[event].add(closure) else listeners[event] = [closure] closure } - Closure listen(event, boolean temporary = false, @DelegatesTo(T) Closure closure){ - Closure ass - ass = { T d, Closure internal -> + def Closure listen(event, @DelegatesTo(T) Closure closure) { + final c = { T d, Closure internal -> Closure copy = (Closure) closure.clone() copy.delegate = d copy.parameterTypes.size() == 2 ? copy(copy.delegate, internal) : copy(copy.delegate) } - ass.resolveStrategy = Closure.DELEGATE_FIRST - addListener(event, temporary, ass) + c.resolveStrategy = Closure.DELEGATE_FIRST + addListener(event, c) } - def removeListener(event, Closure closure) { - listeners[parseEvent(event)]?.remove(closure) + boolean removeListener(event, Closure closure) { + final L = listeners[parseEvent(event)] + null == L ? false: L.remove(closure) } - def removeListenersFor(event){ + boolean removeListenersFor(event) { listeners.remove(parseEvent(event)) } - def removeAllListeners(){ + void removeAllListeners() { listeners = [:] } - def dispatchEvent(type, T data){ + def dispatchEvent(type, T data) { def x = listeners[parseEvent(type)] - if (null != x) for (l in x){ + if (null != x) for (l in x) { def a = (Closure) l.clone() try{ if (a.parameterTypes.length > 1) a.call(data, l) else a.call(data) - }catch (ex){ + }catch (ex) { listenerError(parseEvent(type), ex, l, data) } } diff --git a/src/main/groovy/hlaaftana/discordg/logic/ParentListenerSystem.groovy b/src/main/groovy/hlaaftana/discordg/logic/ParentListenerSystem.groovy deleted file mode 100644 index b4874ff..0000000 --- a/src/main/groovy/hlaaftana/discordg/logic/ParentListenerSystem.groovy +++ /dev/null @@ -1,17 +0,0 @@ -package hlaaftana.discordg.logic - -import groovy.transform.CompileStatic - -@CompileStatic -class ParentListenerSystem extends ListenerSystem { - def parent - ParentListenerSystem(parent){ this.parent = parent } - - def parseEvent(param){ - parent.invokeMethod('parseEvent', param) - } - - def listenerError(event, Throwable ex, Closure closure, T data){ - parent.invokeMethod('listenerError', [event, ex, closure, data]) - } -} diff --git a/src/main/groovy/hlaaftana/discordg/net/HTTPClient.groovy b/src/main/groovy/hlaaftana/discordg/net/HTTPClient.groovy index f3ad373..14b9ba3 100644 --- a/src/main/groovy/hlaaftana/discordg/net/HTTPClient.groovy +++ b/src/main/groovy/hlaaftana/discordg/net/HTTPClient.groovy @@ -70,28 +70,28 @@ class HTTPClient { Map ratelimits = [:].asSynchronized() Client client - HTTPClient(Client client, String concatUrl = ''){ + HTTPClient(Client client, String concatUrl = '') { this.client = client if (concatUrl) baseUrl = concatUrlPaths(baseUrl, concatUrl) } - HTTPClient(HTTPClient http, String concatUrl = ''){ + HTTPClient(HTTPClient http, String concatUrl = '') { client = http.client baseUrl = http.baseUrl if (concatUrl) baseUrl = concatUrlPaths(baseUrl, concatUrl) } - def normal(){ baseUrl = discordApi } - def normalDiscord(){ baseUrl = discordApi } - def canary(){ baseUrl = canaryApi } - def ptb(){ baseUrl = ptbApi } + def normal() { baseUrl = discordApi } + def normalDiscord() { baseUrl = discordApi } + def canary() { baseUrl = canaryApi } + def ptb() { baseUrl = ptbApi } - def setBaseUrl(String n){ + def setBaseUrl(String n) { baseUrl = n latestApi = n } - def parse(String request){ + def parse(String request) { def a = request.split(/\s+/, 3) methodMissing(camel.to(constant, a[0]), a.length == 2 ? a[1] : [a[1], a[2]]) } @@ -110,7 +110,7 @@ class HTTPClient { List> jsonPosts(...args) { (List>) methodMissing('jsonPost', args) } List> jsonPatches(...args) { (List>) methodMissing('jsonPatch', args) } - def methodMissing(String methodName, List argl){ + def methodMissing(String methodName, List argl) { String url List methodParams = camel.toWords(methodName) boolean global = methodParams.remove('global') @@ -131,11 +131,11 @@ class HTTPClient { else response } - def methodMissing(String methodName, Object[] args){ + def methodMissing(String methodName, Object[] args) { methodMissing(methodName, args.toList()) } - def methodMissing(String methodName, args){ + def methodMissing(String methodName, args) { methodMissing(methodName, [args]) } @@ -150,7 +150,7 @@ class HTTPClient { else throw new UnsupportedOperationException('Unirest does not support HTTP method '.concat(method)) } - BaseRequest headerUp(HttpRequest req){ + BaseRequest headerUp(HttpRequest req) { if (null != client.token) req = req.header('Authorization', client.token) if (!(req instanceof GetRequest)) req = req.header('Content-Type', 'application/json') req.header('User-Agent', null != client ? client.fullUserAgent : DiscordG.USER_AGENT) @@ -167,14 +167,14 @@ class HTTPClient { headerUp((HttpURLConnection) url.openConnection()) } - HttpResponse request(BaseRequest req){ + HttpResponse request(BaseRequest req) { _request(req, 0) } - private HttpResponse _request(BaseRequest req, int rid){ + private HttpResponse _request(BaseRequest req, int rid) { HttpRequest ft = req.httpRequest String rlUrl = ft.url.replaceFirst(Pattern.quote(baseUrl), '') - if (ratelimits[ratelimitUrl(rlUrl)]){ + if (ratelimits[ratelimitUrl(rlUrl)]) { int id = rid < 1 ? ratelimits[ratelimitUrl(rlUrl)].newRequest() : rid while (ratelimits[ratelimitUrl(rlUrl)]?.requests?.contains(id)) Thread.sleep 10 } @@ -183,7 +183,7 @@ class HTTPClient { if ((returned.headers.containsKey('X-RateLimit-Limit') && returned.headers['X-RateLimit-Remaining'][0].toInteger() < 2) || returned.headers.containsKey('X-RateLimit-Global') || - status == 429){ + status == 429) { boolean precaution HttpResponse r Thread.start { @@ -203,7 +203,7 @@ class HTTPClient { if (!precaution) Thread.start { r = _request(req, xxx) } - while (rl.requests){ + while (rl.requests) { Thread.sleep(rl.retryTime) rl.requests.removeAll(rl.requests.sort().take( returned.headers['X-RateLimit-Limit'][0].toInteger() - 1)) @@ -231,7 +231,7 @@ class HTTPClient { } @Memoized - static String ratelimitUrl(String url){ + static String ratelimitUrl(String url) { if (url.indexOf('?') > 0) url = url.substring(url.indexOf('?')) // AAAAAA url.replaceAll(/\/\d+\//) { ...full -> "/@${++i}/" } StringBuilder result = new StringBuilder() @@ -244,7 +244,7 @@ class HTTPClient { } @Memoized - static String concatUrlPaths(String...yeah){ + static String concatUrlPaths(String...yeah) { StringBuilder ass = new StringBuilder(yeah[0]) def whoop = yeah.drop(1) for (int i = 0; i < whoop.length; ++i) { diff --git a/src/main/groovy/hlaaftana/discordg/net/RateLimit.groovy b/src/main/groovy/hlaaftana/discordg/net/RateLimit.groovy index 5d86a1f..c5eddd4 100644 --- a/src/main/groovy/hlaaftana/discordg/net/RateLimit.groovy +++ b/src/main/groovy/hlaaftana/discordg/net/RateLimit.groovy @@ -9,12 +9,12 @@ import hlaaftana.discordg.DiscordObject class RateLimit extends DiscordObject { List requests = [] - int newRequest(){ + int newRequest() { int x = requests.size() + 1 requests.add(x) x } - String getMessage(){ (String) object.message } - long getRetryTime(){ (long) object.retry_after } - boolean isGlobal(){ (boolean) object.global } + String getMessage() { (String) object.message } + long getRetryTime() { (long) object.retry_after } + boolean isGlobal() { (boolean) object.global } } diff --git a/src/main/groovy/hlaaftana/discordg/net/VoiceWSClient.groovy b/src/main/groovy/hlaaftana/discordg/net/VoiceWSClient.groovy index ee6246e..6af3eda 100644 --- a/src/main/groovy/hlaaftana/discordg/net/VoiceWSClient.groovy +++ b/src/main/groovy/hlaaftana/discordg/net/VoiceWSClient.groovy @@ -24,11 +24,11 @@ class VoiceWSClient extends WebSocketAdapter { char seq = 0 BigInteger timestamp - VoiceWSClient(VoiceClient v){ + VoiceWSClient(VoiceClient v) { vc = v } - void onWebSocketConnect(Session s){ + void onWebSocketConnect(Session s) { session = s session.policy.maxTextMessageSize = Integer.MAX_VALUE session.policy.maxTextMessageBufferSize = Integer.MAX_VALUE @@ -37,13 +37,13 @@ class VoiceWSClient extends WebSocketAdapter { identify() } - void onWebSocketMessage(String message){ + void onWebSocketMessage(String message) { Map content = JSONUtil.parse(message) def data = content['d'] int op = content['op'] def o = { it == op } def event = data - if (op == 2){ + if (op == 2) { vc.ssrc = data['ssrc'] vc.port = data['port'] vc.heartbeatInterval = data['heartbeat_interval'] @@ -61,31 +61,31 @@ class VoiceWSClient extends WebSocketAdapter { threadUdpKeepAlive() selectProtocol(selfIp, selfPort) startHeartbeating(vc.heartbeatInterval) - }else if (op == 3){ + } else if (op == 3) { def interval = System.currentTimeMillis() - data vc.pingIntervals += interval event = [interval: interval, time: data] - }else if (op == 4){ + } else if (op == 4) { secretKey = data.secret_key.collect { (byte) it } as byte[] connected = true - }else if (op == 5){ + } else if (op == 5) { event = [speaking: data.speaking, ssrc: data.ssrc, user: vc.client.user(data.user_id)] - }else{ + } else { vc.log.info "Unhandled voice op code $op. " + "Full content (please report to Hlaaftana):\n$content', vc.log.name + 'WS" } vc.dispatchEvent(op, event << [json: data]) } - void onWebSocketClose(int code, String reason){ + void onWebSocketClose(int code, String reason) { vc.log.info "Connection closed. Reason: $reason, code: $code', vc.log.name + 'WS" Thread.start { vc.dispatchEvent('CLOSE', [code: code, reason: reason, json: [code: code, reason: reason]]) } - if (heartbeatThread){ + if (heartbeatThread) { heartbeatThread.interrupt() heartbeatThread = null } - if (udpKeepAliveThread){ + if (udpKeepAliveThread) { udpKeepAliveThread.interrupt() udpKeepAliveThread = null } @@ -94,11 +94,11 @@ class VoiceWSClient extends WebSocketAdapter { Thread.currentThread().close() } - void onWebSocketError(Throwable t){ + void onWebSocketError(Throwable t) { t.printStackTrace() } - void identify(){ + void identify() { send op: 0, d: [ token: vc.client.token, guild_id: vc.id, @@ -107,7 +107,7 @@ class VoiceWSClient extends WebSocketAdapter { ] } - void selectProtocol(String ip, int port){ + void selectProtocol(String ip, int port) { send op: 1, d: [ protocol: 'udp', data: [ @@ -118,21 +118,21 @@ class VoiceWSClient extends WebSocketAdapter { ] } - void heartbeat(){ + void heartbeat() { heartbeats++ send op: 3, d: System.currentTimeMillis().toString() } - void startHeartbeating(long interval){ + void startHeartbeating(long interval) { heartbeatThread = Thread.startDaemon { - while (true){ + while (true) { heartbeat() - try{ Thread.sleep(interval) }catch (InterruptedException ex){ return } + try{ Thread.sleep(interval) }catch (InterruptedException ex) { return } } } } - void udpKeepAlive(){ + void udpKeepAlive() { ByteBuffer buf = ByteBuffer.allocate(Long.BYTES + 1) udpSend bytebuf(65).with { put((byte) 0xC9) @@ -141,36 +141,36 @@ class VoiceWSClient extends WebSocketAdapter { } } - void threadUdpKeepAlive(long interval = 5000){ + void threadUdpKeepAlive(long interval = 5000) { udpKeepAliveThread = Thread.startDaemon { - while (true){ + while (true) { udpKeepAlive() Thread.sleep(interval) } } } - void send(message){ + void send(message) { String ass = message instanceof Map ? JSONUtil.json(message) : message.toString() session.remote.sendString(ass) } - void send(Map ass, int op){ + void send(Map ass, int op) { send op: op, d: ass } - void send(int op, Map ass){ + void send(int op, Map ass) { send ass, op } - void udpSend(ByteBuffer buf){ udpSend(buf.array()) } + void udpSend(ByteBuffer buf) { udpSend(buf.array()) } - void udpSend(byte[] arr){ + void udpSend(byte[] arr) { udpSocket.send new DatagramPacket(arr, arr.length) } - void sendVoice(ByteBuffer buf){ sendVoice(buf.array()) } - void sendVoice(byte[] bytes){ + void sendVoice(ByteBuffer buf) { sendVoice(buf.array()) } + void sendVoice(byte[] bytes) { ByteBuffer x = bytebuf(24).with { put(0x80) put(0x78) diff --git a/src/main/groovy/hlaaftana/discordg/net/WSClient.groovy b/src/main/groovy/hlaaftana/discordg/net/WSClient.groovy index ba98357..718b551 100644 --- a/src/main/groovy/hlaaftana/discordg/net/WSClient.groovy +++ b/src/main/groovy/hlaaftana/discordg/net/WSClient.groovy @@ -74,9 +74,9 @@ class WSClient extends WebSocketAdapter { } if (!careAbout(type)) return Map data = (Map) content.d - if (type == 'READY'){ + if (type == 'READY') { readyingState = LoadState.LOADING - if (!opCounts[7]){ + if (!opCounts[7]) { cachingState = LoadState.LOADING guildCreate = client.confirmedBot || ((Map) data.user).bot || ((List) data.guilds).size() >= 100 @@ -157,9 +157,9 @@ class WSClient extends WebSocketAdapter { if (type == 'RESUMED') { client.log.info 'Successfully resumed.' if (client.copyReady) client.readyData.putAll data - } else if (type == 'HEARTBEAT_ACK'){ + } else if (type == 'HEARTBEAT_ACK') { unackedHeartbeats-- - } else if (type == 'MESSAGE_DELETE_BULK' && client.spreadBulkDelete){ + } else if (type == 'MESSAGE_DELETE_BULK' && client.spreadBulkDelete) { for (i in data.ids) { onWebSocketText(/{"op":0,"s":$seq,"t":"MESSAGE_DELETE","d":{/ + /"channel_id":$data.channel_id,"id":$i,"bulk":true}}/) @@ -211,7 +211,7 @@ class WSClient extends WebSocketAdapter { } else if (op == 10) { guildCreatingState = LoadState.LOADING client.readyData.putAll((Map) content.d) - if (justReconnected){ + if (justReconnected) { dispatch = true justReconnected = false client.log.info 'Successfully reconnected. Resuming events...' @@ -247,7 +247,7 @@ class WSClient extends WebSocketAdapter { client.log.info "Connection closed. Reason: $reason, code: $code", client.log.name + 'WS' Thread.start { client.dispatchEvent('CLOSE', new HashMap( code: code, reason: reason, json: [code: code, reason: reason])) } - if (heartbeatThread){ + if (heartbeatThread) { heartbeatThread.interrupt() heartbeatThread = null } @@ -261,8 +261,8 @@ class WSClient extends WebSocketAdapter { void reconnect(boolean requestGateway = false) { dispatch = false - try { client.closeGateway(false) } catch (ignored) {} - while (++reconnectTries){ + try { client.closeGateway() } catch (ignored) {} + while (++reconnectTries) { if (reconnectTries > 5) { client.log.info 'Failed reconnect. Logging out.', client.log.name + 'WS' reconnectTries = 0 @@ -270,7 +270,7 @@ class WSClient extends WebSocketAdapter { return } try { - client.connectGateway(requestGateway || reconnectTries > 3, false) + client.connectGateway(requestGateway || reconnectTries > 3) reconnectTries = 0 justReconnected = true return @@ -295,11 +295,11 @@ class WSClient extends WebSocketAdapter { String ass = Client.parseEvent(event) if (ass in ['READY', 'GUILD_MEMBERS_CHUNK', 'GUILD_SYNC']) return true if (ass == 'GUILD_CREATE' && (guildCreate || client.bot)) return true - if (client.eventWhitelist){ + if (client.eventWhitelist) { aa = false aa |= ass in client.eventWhitelist.collect { Client.parseEvent(it) } } - if (client.eventBlacklist){ + if (client.eventBlacklist) { aa &= !(ass in client.eventBlacklist.collect { Client.parseEvent(it) }) } aa @@ -307,7 +307,7 @@ class WSClient extends WebSocketAdapter { void send(message) { String ass = message instanceof Map ? JSONUtil.json(message) : message - client.askPool('wsAnything'){ + client.askPool('wsAnything') { session.remote.sendString(ass) } } @@ -365,7 +365,7 @@ class WSClient extends WebSocketAdapter { enum LoadState { NOT_LOADED, LOADING, LOADED - boolean asBoolean(){ this == LOADED } + boolean asBoolean() { this == LOADED } } } diff --git a/src/main/groovy/hlaaftana/discordg/objects/Channel.groovy b/src/main/groovy/hlaaftana/discordg/objects/Channel.groovy index 603c7ed..9f23021 100644 --- a/src/main/groovy/hlaaftana/discordg/objects/Channel.groovy +++ b/src/main/groovy/hlaaftana/discordg/objects/Channel.groovy @@ -21,46 +21,46 @@ import java.util.regex.Pattern class Channel extends DiscordObject { static final Pattern MENTION_REGEX = ~/<#(\d+)>/ - String getMention(){ "<#$id>" } - Integer getPosition(){ (Integer) object.position } - Integer getType(){ (Integer) object.type } + String getMention() { "<#$id>" } + Integer getPosition() { (Integer) object.position } + Integer getType() { (Integer) object.type } /** * Only for guild channels. */ - boolean isText(){ type == 0 } - boolean isPrivate(){ (boolean) object.is_private || dm || group } - boolean isDm(){ type == 1 } + boolean isText() { type == 0 } + boolean isPrivate() { (boolean) object.is_private || dm || group } + boolean isDm() { type == 1 } /** * Only for guild channels. */ - boolean isVoice(){ type == 2 } - boolean isGroup(){ type == 3 } - boolean isInGuild(){ text || voice || category } + boolean isVoice() { type == 2 } + boolean isGroup() { type == 3 } + boolean isInGuild() { text || voice || category } boolean isCategory() { type == 4 } String getCategoryId() { (String) object.parent_id } Channel getCategory() { null == categoryId ? null : guild.channel(categoryId) } boolean isNsfw() { (boolean) object.nsfw } - String getTopic(){ (String) object.topic } - Guild getGuild(){ dm || group ? null : client.guildCache.at(guildId) } - String getGuildId(){ (String) object.guild_id } - List getUsers(){ + String getTopic() { (String) object.topic } + Guild getGuild() { dm || group ? null : client.guildCache.at(guildId) } + String getGuildId() { (String) object.guild_id } + List getUsers() { (List) (inGuild ? members : (recipients + client.user)) } DiscordListCache getRecipientCache() { (DiscordListCache) object.recipients } - List getRecipients(){ recipientCache?.list() } - Map getRecipientMap(){ recipientCache?.map() } - User getUser(){ recipients[0] } - User getRecipient(){ user } - String getName(){ + List getRecipients() { recipientCache?.list() } + Map getRecipientMap() { recipientCache?.map() } + User getUser() { recipients[0] } + User getRecipient() { user } + String getName() { dm ? user.name : group ? (recipientCache.rawList()*.get('name').join(', ') ?: 'Unnamed') : (String) object.name } - void addRecipient(user){ + void addRecipient(user) { client.addChannelRecipient(this, user) } - void removeRecipient(user){ + void removeRecipient(user) { client.removeChannelRecipient(this, user) } @@ -70,32 +70,32 @@ class Channel extends DiscordObject { DiscordListCache getOverwriteCache() { permissionOverwriteCache } - List getPermissionOverwrites(){ overwrites } + List getPermissionOverwrites() { overwrites } - List getOverwrites(){ overwriteCache.list() } + List getOverwrites() { overwriteCache.list() } - Map getPermissionOverwriteMap(){ + Map getPermissionOverwriteMap() { overwriteCache.map() } - Map getOverwriteMap(){ permissionOverwriteMap } + Map getOverwriteMap() { permissionOverwriteMap } - PermissionOverwrite permissionOverwrite(ass){ + PermissionOverwrite permissionOverwrite(ass) { (PermissionOverwrite) find(overwriteCache, ass) } - PermissionOverwrite overwrite(ass){ + PermissionOverwrite overwrite(ass) { permissionOverwrite(ass) } - Permissions permissionsFor(user, Permissions initialPerms){ + Permissions permissionsFor(user, Permissions initialPerms) { if (this.private) return Permissions.PRIVATE_CHANNEL Member member = guild.member(user) if (!member) return Permissions.ALL_FALSE def doodle = initialPerms.value def owMap = overwriteCache def everyoneOw = owMap[id] - if (everyoneOw){ + if (everyoneOw) { doodle &= ~((int) everyoneOw.deny) doodle |= (int) everyoneOw.allow } @@ -113,20 +113,20 @@ class Channel extends DiscordObject { new Permissions(doodle) } - Permissions permissionsFor(user){ + Permissions permissionsFor(user) { permissionsFor(user, guild.member(user).permissions) } - boolean canSee(user){ + boolean canSee(user) { if (this.private) recipientCache.containsKey(id(user)) else permissionsFor(user)['readMessages'] } - List requestInvites(){ + List requestInvites() { client.requestChannelInvites(this) } - Invite createInvite(Map data = [:]){ + Invite createInvite(Map data = [:]) { client.createInvite(data, this) } @@ -142,22 +142,22 @@ class Channel extends DiscordObject { client.editChannel(data, this) } - def move(int movement){ guild.moveChannel(this, movement) } + def move(int movement) { guild.moveChannel(this, movement) } - void editPermissions(Map d, t){ client.editChannelOverwrite(d, this, t) } - void editPermissions(t, Map d){ client.editChannelOverwrite(d, this, t) } - void addPermissions(Map d, t){ client.editChannelOverwrite(d, this, t) } - void addPermissions(t, Map d){ client.editChannelOverwrite(d, this, t) } - void createPermissions(Map d, t){ client.editChannelOverwrite(d, this, t) } - void createPermissions(t, Map d){ client.editChannelOverwrite(d, this, t) } + void editPermissions(Map d, t) { client.editChannelOverwrite(d, this, t) } + void editPermissions(t, Map d) { client.editChannelOverwrite(d, this, t) } + void addPermissions(Map d, t) { client.editChannelOverwrite(d, this, t) } + void addPermissions(t, Map d) { client.editChannelOverwrite(d, this, t) } + void createPermissions(Map d, t) { client.editChannelOverwrite(d, this, t) } + void createPermissions(t, Map d) { client.editChannelOverwrite(d, this, t) } - void deletePermissions(t){ client.deleteChannelOverwrite(this, t) } + void deletePermissions(t) { client.deleteChannelOverwrite(this, t) } - Webhook createWebhook(Map data = [:]){ + Webhook createWebhook(Map data = [:]) { client.createWebhook(data, this) } - List requestWebhooks(){ + List requestWebhooks() { client.requestChannelWebhooks(this) } @@ -165,26 +165,26 @@ class Channel extends DiscordObject { client.sendMessage(content: content, tts: tts, this) } - Message sendMessage(Map data){ + Message sendMessage(Map data) { client.sendMessage(data, this) } - Message send(Map data){ sendMessage(data) } - Message send(content, boolean tts = false){ sendMessage(content, tts) } + Message send(Map data) { sendMessage(data) } + Message send(content, boolean tts = false) { sendMessage(content, tts) } - Message editMessage(message, content){ + Message editMessage(message, content) { editMessage(message, content: content) } - Message editMessage(Map data, message){ + Message editMessage(Map data, message) { editMessage(message, data) } - Message editMessage(message, Map data){ + Message editMessage(message, Map data) { client.editMessage(data, this, message) } - void deleteMessage(message){ + void deleteMessage(message) { client.deleteMessage(this, message) } @@ -196,57 +196,57 @@ class Channel extends DiscordObject { sendFile([:], implicatedFile, filename) } - Message requestMessage(message, boolean atc = true){ + Message requestMessage(message, boolean atc = true) { client.requestMessage(this, message, atc) } - Message message(message, boolean aa = true){ + Message message(message, boolean aa = true) { client.message(this, message, aa) } - def pinMessage(message){ client.pinMessage(this, message) } - def pin(message){ pinMessage(message) } + def pinMessage(message) { client.pinMessage(this, message) } + def pin(message) { pinMessage(message) } - def unpinMessage(message){ client.unpinMessage(this, message) } - def unpin(message){ unpinMessage(message) } + def unpinMessage(message) { client.unpinMessage(this, message) } + def unpin(message) { unpinMessage(message) } - Collection requestPinnedMessages(){ client.requestPinnedMessages(this) } - Collection requestPins(){ requestPinnedMessages() } + Collection requestPinnedMessages() { client.requestPinnedMessages(this) } + Collection requestPins() { requestPinnedMessages() } - void react(message, emoji){ client.reactToMessage(this, message, emoji) } - void unreact(m, e, u = '@me'){ client.unreactToMessage(this, m, e, u) } + void react(message, emoji) { client.reactToMessage(this, message, emoji) } + void unreact(m, e, u = '@me') { client.unreactToMessage(this, m, e, u) } - List requestReactors(m, e, int l = 100){ client.requestReactors(this, m, e, l) } + List requestReactors(m, e, int l = 100) { client.requestReactors(this, m, e, l) } List requestLogs(int m = 100, b = null, - bt = 'before'){ client.requestChannelLogs(this, m, b, bt.toString()) } + bt = 'before') { client.requestChannelLogs(this, m, b, bt.toString()) } List logs(int m = 100, b = null, - bt = 'before'){ requestLogs(m, b, bt) } - List forceRequestLogs(int m = 100, b = null, String bt = 'before'){ + bt = 'before') { requestLogs(m, b, bt) } + List forceRequestLogs(int m = 100, b = null, String bt = 'before') { client.forceRequestChannelLogs(this, m, b, bt) } - List getCachedLogs(){ (List) (client.messages[id]?.list() ?: []) } - Map getCachedLogMap(){ (Map) (client.messages[id]?.map() ?: [:]) } + List getCachedLogs() { (List) (client.messages[id]?.list() ?: []) } + Map getCachedLogMap() { (Map) (client.messages[id]?.map() ?: [:]) } - def clear(int number = 100){ clear(logs(number)*.id) } + def clear(int number = 100) { clear(logs(number)*.id) } - def clear(int number = 100, Closure closure){ clear(logs(number).findAll { closure(it) }) } + def clear(int number = 100, Closure closure) { clear(logs(number).findAll { closure(it) }) } - def clear(List ids){ + def clear(List ids) { client.bulkDeleteMessages(this, ids) } - def clear(user, int number = 100){ - clear(number){ Message it -> ((String) ((Map) it.object.author).id) == id(user) } + def clear(user, int number = 100) { + clear(number) { Message it -> ((String) ((Map) it.object.author).id) == id(user) } } Message find(int number = 100, int maxTries = 10, - @ClosureParams(value = SimpleType, options = "hlaaftana.discordg.objects.Message") Closure closure){ + @ClosureParams(value = SimpleType, options = "hlaaftana.discordg.objects.Message") Closure closure) { List messages = logs(number) Message ass = messages.find(closure) if (ass) ass else { - while (!ass){ + while (!ass) { if (((messages.size() - 100) / 50) > maxTries) return null maxTries++ messages = logs(number, messages.min { it.id }) @@ -256,7 +256,7 @@ class Channel extends DiscordObject { } } - String getLastMessageId(){ (String) object.last_message_id } + String getLastMessageId() { (String) object.last_message_id } List getVoiceStates() { int hash = id.hashCode() @@ -284,34 +284,34 @@ class Channel extends DiscordObject { res } - VoiceState voiceState(thing){ findBuilt(voiceStateMap, thing) } - User member(thing){ findBuilt(memberMap, thing) } - Call getOngoingCall(){ client.ongoingCall(id) } + VoiceState voiceState(thing) { findBuilt(voiceStateMap, thing) } + User member(thing) { findBuilt(memberMap, thing) } + Call getOngoingCall() { client.ongoingCall(id) } int getBitrate() { (int) object.bitrate } int getUserLimit() { (int) object.user_limit } - boolean isFull(){ + boolean isFull() { voiceStates.size() == userLimit } - boolean canJoin(){ + boolean canJoin() { Permissions ass = guild.me.permissionsFor(this) ass['connect'] && (userLimit ? (!full || ass['moveMembers']) : true ) } - void move(member){ + void move(member) { client.moveMemberVoiceChannel(guildId, member, this) } - /*VoiceClient join(Map opts = [:]){ + /*VoiceClient join(Map opts = [:]) { if (!canJoin()) throw new Exception(full ? 'Channel is full' : "Insufficient permissions to join voice channel ${inspect()}") VoiceClient vc = new VoiceClient(client, this, opts) client.voiceClients[guild] = vc vc.connect() Thread.start { - while (vc.@endpoint == null){} + while (vc.@endpoint == null) {} WebSocketClient wsc = new WebSocketClient(new SslContextFactory()) VoiceWSClient socket = new VoiceWSClient(vc) wsc.start() @@ -321,9 +321,9 @@ class Channel extends DiscordObject { vc }*/ - static Map construct(Client client, Map c, String guildId = null){ + static Map construct(Client client, Map c, String guildId = null) { if (guildId) c.guild_id = guildId - if (c.guild_id){ + if (c.guild_id) { def po = c.permission_overwrites if (po instanceof List>) { def a = new ArrayList>(po.size()) @@ -334,7 +334,7 @@ class Channel extends DiscordObject { } c.permission_overwrites = new DiscordListCache(a, client, PermissionOverwrite) } - } else if (c.recipients != null){ + } else if (c.recipients != null) { c.recipients = new DiscordListCache((List) c.recipients, client, User) } c @@ -344,12 +344,12 @@ class Channel extends DiscordObject { @InheritConstructors @CompileStatic class PermissionOverwrite extends DiscordObject { - int getAllowedValue(){ def x = object.allow; null == x ? 0 : (int) x } - int getDeniedValue(){ def x = object.deny; null == x ? 0 : (int) x } - Permissions getAllowed(){ new Permissions(allowedValue) } - Permissions getDenied(){ new Permissions(deniedValue) } + int getAllowedValue() { def x = object.allow; null == x ? 0 : (int) x } + int getDeniedValue() { def x = object.deny; null == x ? 0 : (int) x } + Permissions getAllowed() { new Permissions(allowedValue) } + Permissions getDenied() { new Permissions(deniedValue) } String getType() { (String) object.type } - DiscordObject getAffected(){ + DiscordObject getAffected() { if (type == 'role') { channel.guild.role(id) } else if (type == 'member') { @@ -357,24 +357,24 @@ class PermissionOverwrite extends DiscordObject { } else null } String getChannelId() { (String) object.channel_id } - Channel getChannel(){ client.channel(channelId) } - Channel getParent(){ channel } - void edit(Map a){ + Channel getChannel() { client.channel(channelId) } + Channel getParent() { channel } + void edit(Map a) { def de = [allow: allowed, deny: denied] client.editChannelOverwrite(a, channelId, id) } - void delete(){ client.deleteChannelOverwrite(channelId, id) } - String getName(){ affected.name } - boolean involves(DiscordObject involved){ + void delete() { client.deleteChannelOverwrite(channelId, id) } + String getName() { affected.name } + boolean involves(DiscordObject involved) { if (id == channel.guildId) true else if (involved instanceof User) affected instanceof Role ? ((Role) affected).memberIds.contains(involved.id) : involved == affected else if (involved instanceof Role) involved == affected else false } - boolean isRole(){ type == 'role' } - boolean isMember(){ type == 'member' } - boolean isUser(){ type == 'member' } + boolean isRole() { type == 'role' } + boolean isMember() { type == 'member' } + boolean isUser() { type == 'member' } } @InheritConstructors @@ -383,8 +383,8 @@ class Call extends DiscordObject { String getId() { (String) object.channel_id } String getMessageId() { (String) object.message_id } String getRegionId() { (String) object.region } - List getRingingUserIds(){ (List) object.ringing } - List getRingingUsers(){ ringingUserIds.collect(client.&user) } - List getVoiceStates(){ ((List) object.voice_states).collect { new VoiceState(client, it) } } + List getRingingUserIds() { (List) object.ringing } + List getRingingUsers() { ringingUserIds.collect(client.&user) } + List getVoiceStates() { ((List) object.voice_states).collect { new VoiceState(client, it) } } boolean isUnavailable() { (boolean) object.unavailable } } \ No newline at end of file diff --git a/src/main/groovy/hlaaftana/discordg/objects/Guild.groovy b/src/main/groovy/hlaaftana/discordg/objects/Guild.groovy index 04f7206..eaf4ac1 100644 --- a/src/main/groovy/hlaaftana/discordg/objects/Guild.groovy +++ b/src/main/groovy/hlaaftana/discordg/objects/Guild.groovy @@ -20,42 +20,42 @@ import java.util.regex.Pattern @CompileStatic @SuppressWarnings('GroovyUnusedDeclaration') class Guild extends DiscordObject { - Guild(Client client, Map object){ + Guild(Client client, Map object) { super(client, object) } String getRegionId() { (String) object.region } String getRawJoinedAt() { (String) object.joined_at } - Date getJoinedAt(){ ConversionUtil.fromJsonDate(rawJoinedAt) } + Date getJoinedAt() { ConversionUtil.fromJsonDate(rawJoinedAt) } String getIconHash() { (String) object.icon } String getIcon() { iconHash ? "https://cdn.discordapp.com/icons/$id/${iconHash}.jpg" : '' } - boolean hasIcon(){ object.icon } - InputStream newIconInputStream(){ inputStreamFromDiscord(icon) } - File downloadIcon(file){ downloadFileFromDiscord(icon, file) } + boolean hasIcon() { object.icon } + InputStream newIconInputStream() { inputStreamFromDiscord(icon) } + File downloadIcon(file) { downloadFileFromDiscord(icon, file) } String getOwnerId() { (String) object.owner_id } - Member getOwner(){ member(ownerId) } + Member getOwner() { member(ownerId) } - Member getMe(){ member(client) } - String changeNick(String newNick){ client.changeOwnGuildNick(id, newNick) } - String nick(String newNick){ changeNick(newNick) } - String editNick(String newNick){ changeNick(newNick) } - String resetNick(){ changeNick('') } + Member getMe() { member(client) } + String changeNick(String newNick) { client.changeOwnGuildNick(id, newNick) } + String nick(String newNick) { changeNick(newNick) } + String editNick(String newNick) { changeNick(newNick) } + String resetNick() { changeNick('') } - Channel getDefaultChannel(){ channel(id) } - Channel getAfkChannel(){ channel(object.afk_channel_id) } + Channel getDefaultChannel() { channel(id) } + Channel getAfkChannel() { channel(object.afk_channel_id) } int getAfkTimeout() { (int) object.afk_timeout } - Channel getWidgetChannel(){ channel(object.embed_channel_id) } + Channel getWidgetChannel() { channel(object.embed_channel_id) } boolean isWidgetEnabled() { (boolean) object.embed_enabled } boolean isLarge() { (boolean) object.large } boolean isUnavailable() { (boolean) object.unavailable } int getVerificationLevel() { (int) object.verification_level } int getMfaLevel() { (int) object.mfa_level } - boolean isMfaRequiredForStaff(){ mfaLevel == MFALevelTypes.ELEVATED } + boolean isMfaRequiredForStaff() { mfaLevel == MFALevelTypes.ELEVATED } - Role getDefaultRole(){ role(id) } + Role getDefaultRole() { role(id) } Guild edit(Map data) { client.editGuild(data, id) @@ -77,54 +77,54 @@ class Guild extends DiscordObject { client.createVoiceChannel(this, name) } - Channel createChannel(Map data = [:]){ + Channel createChannel(Map data = [:]) { client.createChannel(data, this) } - Channel requestChannel(c){ + Channel requestChannel(c) { client.requestGuildChannel(this, c) } - List requestChannels(){ + List requestChannels() { client.requestGuildChannels(this) } - List getTextChannels(){ channels.findAll { it.text } } - Map getTextChannelMap(){ channelMap.findAll { k, v -> v.text } } + List getTextChannels() { channels.findAll { it.text } } + Map getTextChannelMap() { channelMap.findAll { k, v -> v.text } } - List getVoiceChannels(){ channels.findAll { it.voice } } - Map getVoiceChannelMap(){ channelMap.findAll { k, v -> v.voice } } + List getVoiceChannels() { channels.findAll { it.voice } } + Map getVoiceChannelMap() { channelMap.findAll { k, v -> v.voice } } - Channel textChannel(id){ findBuilt(textChannels, id) } + Channel textChannel(id) { findBuilt(textChannels, id) } - Channel voiceChannel(id){ findBuilt(voiceChannels, id) } + Channel voiceChannel(id) { findBuilt(voiceChannels, id) } - Channel channel(id){ find(channelCache, id) } + Channel channel(id) { find(channelCache, id) } DiscordListCache getChannelCache() { (DiscordListCache) object.channels } - List getChannels(){ channelCache.list() } - Map getChannelMap(){ channelCache.map() } + List getChannels() { channelCache.list() } + Map getChannelMap() { channelCache.map() } DiscordListCache getRoleCache() { (DiscordListCache) object.roles } - List getRoles(){ roleCache.list() } - Map getRoleMap(){ roleCache.map() } + List getRoles() { roleCache.list() } + Map getRoleMap() { roleCache.map() } Set getUsedRoleIds() { def res = new HashSet() for (e in memberCache) res.addAll((List) e.value.roles) res } - Role role(ass){ find(roleCache, ass) } + Role role(ass) { find(roleCache, ass) } DiscordListCache getMemberCache() { (DiscordListCache) object.members } - List getMembers(){ memberCache.list() } - Map getMemberMap(){ memberCache.map() } + List getMembers() { memberCache.list() } + Map getMemberMap() { memberCache.map() } DiscordListCache getPresenceCache() { (DiscordListCache) object.presences } - List getPresences(){ presenceCache.list() } - Map getPresenceMap(){ presenceCache.map() } + List getPresences() { presenceCache.list() } + Map getPresenceMap() { presenceCache.map() } - Presence presence(ass){ find(presenceCache, ass) } + Presence presence(ass) { find(presenceCache, ass) } void editRoles(member, List roles) { client.editRoles(this, member, roles) @@ -134,11 +134,11 @@ class Guild extends DiscordObject { client.addRoles(this, member, roles) } - void addRole(member, role){ + void addRole(member, role) { client.addRole(this, member, role) } - void removeRole(member, role){ + void removeRole(member, role) { client.removeRole(this, member, role) } @@ -146,33 +146,33 @@ class Guild extends DiscordObject { client.kick(this, member) } - List requestBans(){ + List requestBans() { client.requestBans(this) } DiscordListCache getVoiceStateCache() { (DiscordListCache) object.voice_states } - List getVoiceStates(){ + List getVoiceStates() { voiceStateCache.list() } - Map getVoiceStateMap(){ + Map getVoiceStateMap() { voiceStateCache.map() } - List requestInvites(){ + List requestInvites() { client.requestGuildInvites(this) } - List requestRegions(){ + List requestRegions() { client.requestRegions(this) } - List requestIntegrations(){ + List requestIntegrations() { client.requestIntegrations(this) } - Integration createIntegration(String type, String id){ + Integration createIntegration(String type, String id) { client.createIntegration(this, type, id) } @@ -186,11 +186,11 @@ class Guild extends DiscordObject { client.unban(this, user) } - int checkPrune(int days){ + int checkPrune(int days) { client.checkPrune(this, days) } - int prune(int days){ + int prune(int days) { client.prune(this, days) } @@ -206,15 +206,15 @@ class Guild extends DiscordObject { client.deleteRole(this, role) } - List requestWebhooks(){ + List requestWebhooks() { client.requestGuildWebhooks(this) } - List editRolePositions(Map mods){ + List editRolePositions(Map mods) { client.editRolePositions(mods, this) } - List moveRole(ro, int movement){ + List moveRole(ro, int movement) { Role r = role(ro) def rp = Math.max(r.position + movement, 0) def rg = rp.. moveChannel(chan, int movement){ + List moveChannel(chan, int movement) { Channel c = channel(chan) def cp = Math.max(c.position + movement, 0) def cg = cp.. editChannelPositions(Map mods){ + List editChannelPositions(Map mods) { client.editChannelPositions(mods, this) } - List requestMembers(int max=1000, boolean updateCache=true){ + List requestMembers(int max=1000, boolean updateCache=true) { client.requestMembers(this, max, updateCache) } - Member requestMember(id){ client.requestMember(this, id) } + Member requestMember(id) { client.requestMember(this, id) } - Member getLastMember(){ members.max { it.joinedAt } } - Member getLatestMember(){ members.max { it.joinedAt } } + Member getLastMember() { members.max { it.joinedAt } } + Member getLatestMember() { members.max { it.joinedAt } } int getMemberCount() { (int) object.member_count } DiscordListCache getEmojiCache() { (DiscordListCache) object.emojis } - List getEmojis(){ emojiCache.list() } - List getEmoji(){ emojis } - Map getEmojiIdMap(){ emojiCache.map() } - Map getEmojiNameMap(){ + List getEmojis() { emojiCache.list() } + List getEmoji() { emojis } + Map getEmojiIdMap() { emojiCache.map() } + Map getEmojiNameMap() { def res = new HashMap() for (e in emojiCache) res.put((String) e.value.name, new Emoji(client, e.value)) res } - List requestEmojis(){ client.requestEmojis(this) } + List requestEmojis() { client.requestEmojis(this) } - Emoji createEmoji(Map data){ + Emoji createEmoji(Map data) { client.createEmoji(data, this) } - Emoji editEmoji(Map data, emoji){ + Emoji editEmoji(Map data, emoji) { client.editEmoji(data, this, emoji) } - Member member(user){ findMember(memberCache, user) } + Member member(user) { findMember(memberCache, user) } - Message sendMessage(String message, boolean tts=false){ sendMessage(content: message, tts: tts) } - Message sendMessage(Map data){ client.sendMessage(data, this) } - Message sendFile(...args){ (Message) client.invokeMethod('sendFile', [this, *args]) } - Message sendFile(Map data, ...args){ (Message) client.invokeMethod('sendFile', [data, this, *args]) } + Message sendMessage(String message, boolean tts=false) { sendMessage(content: message, tts: tts) } + Message sendMessage(Map data) { client.sendMessage(data, this) } + Message sendFile(...args) { (Message) client.invokeMethod('sendFile', [this, *args]) } + Message sendFile(Map data, ...args) { (Message) client.invokeMethod('sendFile', [data, this, *args]) } - Embed requestEmbed(){ client.requestEmbed(this) } + Embed requestEmbed() { client.requestEmbed(this) } - static Map construct(Client client, Map g){ + static Map construct(Client client, Map g) { def gid = (String) g.id def m = (List) g.members, ml = new ArrayList(m.size()) @@ -332,73 +332,73 @@ class Guild extends DiscordObject { @InheritConstructors static class Embed extends DiscordObject { - String getId(){ (String) object.channel_id } - String getName(){ channel.name } - boolean isEnabled(){ (boolean) object.enabled } - Channel getChannel(){ client.channel(id) } - Guild getGuild(){ channel.guild } - Embed edit(Map data){ + String getId() { (String) object.channel_id } + String getName() { channel.name } + boolean isEnabled() { (boolean) object.enabled } + Channel getChannel() { client.channel(id) } + Guild getGuild() { channel.guild } + Embed edit(Map data) { client.editEmbed(data, guild, this) } } static class Ban extends User { - Ban(Client client, Map object){ super(client, object + (Map) object.user) } + Ban(Client client, Map object) { super(client, object + (Map) object.user) } - User getUser(){ new User(client, (Map) object.user) } - String getReason(){ (String) object.reason } + User getUser() { new User(client, (Map) object.user) } + String getReason() { (String) object.reason } } } @CompileStatic @SuppressWarnings('GroovyUnusedDeclaration') class VoiceState extends DiscordObject { - VoiceState(Client client, Map object){ super(client, object) } - - String getGuildId(){ (String) object.guild_id } - String getChannelId(){ (String) object.channel_id } - String getUserId(){ (String) object.user_id } - Channel getChannel(){ client.channel(channelId) } - User getUser(){ client.user(userId) } - Guild getGuild(){ guildId ? client.guild(guildId) : channel.guild } - Channel getParent(){ channel } - Member getMember(){ guild.member(user) } - boolean isDeaf(){ (boolean) object.deaf } - boolean isMute(){ (boolean) object.mute } - boolean isDeafened(){ deaf } - boolean isMuted(){ mute } - boolean isSelfDeaf(){ (boolean) object.self_deaf } - boolean isSelfMute(){ (boolean) object.self_mute } - boolean isSelfDeafened(){ selfDeaf } - boolean isSelfMuted(){ selfMute } - boolean isSuppress(){ (boolean) object.suppress } - String getToken(){ (String) object.token } - String getSessionId(){ (String) object.session_id } - String getName(){ user.name } + VoiceState(Client client, Map object) { super(client, object) } + + String getGuildId() { (String) object.guild_id } + String getChannelId() { (String) object.channel_id } + String getUserId() { (String) object.user_id } + Channel getChannel() { client.channel(channelId) } + User getUser() { client.user(userId) } + Guild getGuild() { guildId ? client.guild(guildId) : channel.guild } + Channel getParent() { channel } + Member getMember() { guild.member(user) } + boolean isDeaf() { (boolean) object.deaf } + boolean isMute() { (boolean) object.mute } + boolean isDeafened() { deaf } + boolean isMuted() { mute } + boolean isSelfDeaf() { (boolean) object.self_deaf } + boolean isSelfMute() { (boolean) object.self_mute } + boolean isSelfDeafened() { selfDeaf } + boolean isSelfMuted() { selfMute } + boolean isSuppress() { (boolean) object.suppress } + String getToken() { (String) object.token } + String getSessionId() { (String) object.session_id } + String getName() { user.name } } @CompileStatic @SuppressWarnings('GroovyUnusedDeclaration') class Integration extends DiscordObject { - Integration(Client client, Map object){ super(client, object) } - - int getSubscriberCount(){ (int) object.subscriber_count } - boolean isSyncing(){ (boolean) object.syncing } - boolean isEnableEmoticons(){ (boolean) object.enable_emoticons } - int getExpireBehaviour(){ (int) object.expire_behaviour } - int getExpireGracePeriod(){ (int) object.expire_grace_period } - User getUser(){ new User(client, (Map) object.user) } - DiscordObject getAccount(){ new DiscordObject(client, (Map) object.account) } + Integration(Client client, Map object) { super(client, object) } + + int getSubscriberCount() { (int) object.subscriber_count } + boolean isSyncing() { (boolean) object.syncing } + boolean isEnableEmoticons() { (boolean) object.enable_emoticons } + int getExpireBehaviour() { (int) object.expire_behaviour } + int getExpireGracePeriod() { (int) object.expire_grace_period } + User getUser() { new User(client, (Map) object.user) } + DiscordObject getAccount() { new DiscordObject(client, (Map) object.account) } boolean isEnabled() { (boolean) object.enabled } - String getRoleId(){ (String) object.role_id } - Role getRole(){ client.role(roleId) } - Guild getGuild(){ role.guild } + String getRoleId() { (String) object.role_id } + Role getRole() { client.role(roleId) } + Guild getGuild() { role.guild } String getRawSyncedAt() { (String) object.synced_at } - Date getSyncedAt(){ ConversionUtil.fromJsonDate(rawSyncedAt) } + Date getSyncedAt() { ConversionUtil.fromJsonDate(rawSyncedAt) } String getType() { (String) object.type } - Integration edit(Map data){ client.editIntegration(data, guild, this) } - void delete(){ client.deleteIntegration(guild, this) } - void sync(){ client.syncIntegration(guild, this) } + Integration edit(Map data) { client.editIntegration(data, guild, this) } + void delete() { client.deleteIntegration(guild, this) } + void sync() { client.syncIntegration(guild, this) } } @InheritConstructors @@ -408,18 +408,18 @@ class Emoji extends DiscordObject { static final Pattern REGEX = ~/<:(?\w+):(?\d+)>/ String getGuildId() { (String) object.guild_id } - Guild getGuild(){ client.guild(guildId) } - Guild getParent(){ guild } + Guild getGuild() { client.guild(guildId) } + Guild getParent() { guild } List getRoleIds() { (List) object.roles } - List getRoles(){ roleIds.collect(guild.&role) } - boolean requiresColons(){ (boolean) object.require_colons } - boolean requireColons(){ (boolean) object.require_colons } + List getRoles() { roleIds.collect(guild.&role) } + boolean requiresColons() { (boolean) object.require_colons } + boolean requireColons() { (boolean) object.require_colons } boolean isRequiresColons() { (boolean) object.require_colons } boolean isRequireColons() { (boolean) object.require_colons } boolean isManaged() { (boolean) object.managed } - String getUrl(){ "https://cdn.discordapp.com/emojis/${id}.png" } - InputStream newInputStream(){ inputStreamFromDiscord(url) } - File download(file){ downloadFileFromDiscord(url, file) } + String getUrl() { "https://cdn.discordapp.com/emojis/${id}.png" } + InputStream newInputStream() { inputStreamFromDiscord(url) } + File download(file) { downloadFileFromDiscord(url, file) } } @InheritConstructors @@ -454,60 +454,60 @@ class Role extends DiscordObject{ static final Closure MENTION_REGEX = { String id = /\d+/ -> /<@&$id>/ } int getColorValue() { (int) object.color } - Color getColor(){ new Color(colorValue) } - boolean isLocked(){ isLockedFor(guild.me) } - boolean isLockedFor(user){ + Color getColor() { new Color(colorValue) } + boolean isLocked() { isLockedFor(guild.me) } + boolean isLockedFor(user) { guild.member(user).owner ? false : position >= guild.member(user).primaryRole.position } boolean isHoist() { (boolean) object.hoist } boolean isManaged() { (boolean) object.managed } boolean isMentionable() { (boolean) object.mentionable } - Permissions getPermissions(){ new Permissions(permissionValue) } + Permissions getPermissions() { new Permissions(permissionValue) } int getPermissionValue() { (int) object.permissions } int getPosition() { (int) object.position } - Guild getGuild(){ client.guild(guildId) } + Guild getGuild() { client.guild(guildId) } String getGuildId() { (String) object.guild_id } - Guild getParent(){ guild } + Guild getParent() { guild } - String getMention(){ "<@&${id}>" } - String getMentionRegex(){ MENTION_REGEX(id) } + String getMention() { "<@&${id}>" } + String getMentionRegex() { MENTION_REGEX(id) } - List getMembers(){ + List getMembers() { def x = ((DiscordListCache) client.guildCache[guildId].members).values() def r = [] for (a in x) if (((List) a.roles).contains(id)) r.add(new Member(client, a)) r } - List getMemberIds(){ + List getMemberIds() { def x = ((DiscordListCache) client.guildCache[guildId].members).values() def r = [] for (a in x) if (((List) a.roles).contains(id)) r.add(a.id) r } - List getPermissionOverwrites(){ + List getPermissionOverwrites() { findAllNested((DiscordListCache) client.guildCache[guildId].channels, 'permission_overwrites', id) } - List getOverwrites(){ permissionOverwrites } + List getOverwrites() { permissionOverwrites } - boolean isUsed(){ guild.usedRoleIds.contains(id) } - Role edit(Map data){ client.editRole(data, guildId, this) } - void delete(){ client.deleteRole(guildId, this) } - void addTo(user){ client.addRole(guildId, user, this) } - void addTo(Collection users){ users.each(this.&addTo) } - void removeFrom(user){ client.removeRole(guildId, user, this) } - void removeFrom(Collection users){ users.each(this.&removeFrom) } - def move(int movement){ guild.moveRole(this, movement) } + boolean isUsed() { guild.usedRoleIds.contains(id) } + Role edit(Map data) { client.editRole(data, guildId, this) } + void delete() { client.deleteRole(guildId, this) } + void addTo(user) { client.addRole(guildId, user, this) } + void addTo(Collection users) { users.each(this.&addTo) } + void removeFrom(user) { client.removeRole(guildId, user, this) } + void removeFrom(Collection users) { users.each(this.&removeFrom) } + def move(int movement) { guild.moveRole(this, movement) } } @CompileStatic @SuppressWarnings('GroovyUnusedDeclaration') class Member extends User { - Member(Client client, Map object){ + Member(Client client, Map object) { super(client, object) if (object.user instanceof Map) object << ((Map) object.user) else if (object.user instanceof User) { @@ -515,65 +515,65 @@ class Member extends User { } } - User getUser(){ new User(client, (Map) object.user) } - String getNick(){ (String) object.nick ?: name } + User getUser() { new User(client, (Map) object.user) } + String getNick() { (String) object.nick ?: name } String getRawNick() { (String) object.nick } String getGuildId() { (String) object.guild_id } - Guild getGuild(){ client.guild(object.guild_id) } - Guild getParent(){ guild } + Guild getGuild() { client.guild(object.guild_id) } + Guild getParent() { guild } String getRawJoinedAt() { (String) object.joined_at } - Date getJoinedAt(){ ConversionUtil.fromJsonDate(rawJoinedAt) } - List getRoleIds(){ (List) object.roles } - List getRoles(){ + Date getJoinedAt() { ConversionUtil.fromJsonDate(rawJoinedAt) } + List getRoleIds() { (List) object.roles } + List getRoles() { DiscordListCache x = (DiscordListCache) client.guildCache[guildId].roles def r = [] for (ri in roleIds) r.add(x.at(ri)) r } - boolean isOwner(){ guild.ownerId == id } + boolean isOwner() { guild.ownerId == id } - Game getGame(){ + Game getGame() { presence?.game ?: null } - Presence getPresence(){ + Presence getPresence() { guild.presence(id) } - void edit(Map data){ + void edit(Map data) { client.editMember(data, guildId, this) } - void changeNick(String newNick){ + void changeNick(String newNick) { id == client.id ? client.changeOwnGuildNick(guildId, newNick) : edit(nick: newNick) } - void nick(String newNick){ changeNick(newNick) } - void editNick(String newNick){ changeNick(newNick) } - void resetNick(){ changeNick('') } + void nick(String newNick) { changeNick(newNick) } + void editNick(String newNick) { changeNick(newNick) } + void resetNick() { changeNick('') } - void mute(){ edit(mute: true) } - void unmute(){ edit(mute: false) } - void deafen(){ edit(deaf: true) } - void undeafen(){ edit(deaf: false) } - void ban(int days = 0){ client.ban(guildId, this, days) } - void unban(){ client.unban(guildId, this) } + void mute() { edit(mute: true) } + void unmute() { edit(mute: false) } + void deafen() { edit(deaf: true) } + void undeafen() { edit(deaf: false) } + void ban(int days = 0) { client.ban(guildId, this, days) } + void unban() { client.unban(guildId, this) } boolean isMute() { (boolean) object.mute } boolean isDeaf() { (boolean) object.deaf } boolean isDeafened() { (boolean) object.deaf } - String getStatus(){ + String getStatus() { presence?.status ?: 'offline' } - Role getPrimaryRole(){ roles.max { it.position } } - int getColorValue(){ roles.findAll { it.colorValue != 0 }.max { it.position }?.colorValue ?: 0 } - Color getColor(){ new Color(colorValue) } - Permissions getPermissions(){ + Role getPrimaryRole() { roles.max { it.position } } + int getColorValue() { roles.findAll { it.colorValue != 0 }.max { it.position }?.colorValue ?: 0 } + Color getColor() { new Color(colorValue) } + Permissions getPermissions() { if (owner) return Permissions.ALL_TRUE int full = guild.defaultRole.permissionValue - for (role in roles){ + for (role in roles) { def perms = role.permissionValue if (((perms >> 3) & 1) == 1) return Permissions.ALL_TRUE full |= perms @@ -589,11 +589,11 @@ class Member extends User { client.addRoles(guildId, this, roles) } - void addRole(role){ + void addRole(role) { client.addRole(guildId, this, role) } - void removeRole(role){ + void removeRole(role) { client.removeRole(guildId, this, role) } @@ -601,30 +601,30 @@ class Member extends User { client.kick(guildId, this) } - void moveTo(channel){ + void moveTo(channel) { client.moveMemberVoiceChannel(guildId, this, channel) } - List getPermissionOverwrites(){ + List getPermissionOverwrites() { findAllNested((DiscordListCache) client.guildCache[guildId].channels, 'permission_overwrites', id) } - List getOverwrites(){ permissionOverwrites } + List getOverwrites() { permissionOverwrites } - boolean isSuperior(){ + boolean isSuperior() { roles*.position.max() > guild.me.roles*.position.max() } - boolean isSuperiorTo(user){ + boolean isSuperiorTo(user) { roles*.position.max() > guild.member(user).roles*.position.max() } - User toUser(){ new User(client, (Map) object.user) } - def asType(Class target){ + User toUser() { new User(client, (Map) object.user) } + def asType(Class target) { if (target == User) toUser() else super.asType(target) } - String toString(){ nick } + String toString() { nick } } @InheritConstructors @@ -641,22 +641,22 @@ class Region extends DiscordObject { @InheritConstructors @CompileStatic class Presence extends DiscordObject { - Game getGame(){ null != object.game ? new Game(client, (Map) object.game) : null } + Game getGame() { null != object.game ? new Game(client, (Map) object.game) : null } String getStatus() { (String) object.status } - Guild getGuild(){ client.guildCache.at(guildId) } + Guild getGuild() { client.guildCache.at(guildId) } String getGuildId() { (String) object.guild_id } boolean isFromGuild() { null != guildId } - Guild getParent(){ guild } - Member getMember(){ guild ? guild.memberCache.at(id) : client.members(id)[0] } - String getName(){ member.name } + Guild getParent() { guild } + Member getMember() { guild ? guild.memberCache.at(id) : client.members(id)[0] } + String getName() { member.name } long getLastModified() { (long) object.last_modified } } @InheritConstructors @CompileStatic class Game extends DiscordObject { - String getId(){ type.toString() } - int getType(){ null == object.type ? 0 : (int) object.type } + String getId() { type.toString() } + int getType() { null == object.type ? 0 : (int) object.type } String getUrl() { (String) object.url } - String toString(){ type == 0 ? name : "$name ($url)" } + String toString() { type == 0 ? name : "$name ($url)" } } \ No newline at end of file diff --git a/src/main/groovy/hlaaftana/discordg/objects/Invite.groovy b/src/main/groovy/hlaaftana/discordg/objects/Invite.groovy index caad94f..137436a 100644 --- a/src/main/groovy/hlaaftana/discordg/objects/Invite.groovy +++ b/src/main/groovy/hlaaftana/discordg/objects/Invite.groovy @@ -15,25 +15,25 @@ class Invite extends DiscordObject { int getMaxAge() { (int) object.max_age } String getCode() { (String) object.code } String getId() { (String) object.code } - String getUrl(){ "https://discord.gg/${id}" } - Guild getGuild(){ client.guild((String) guildObject.id) } + String getUrl() { "https://discord.gg/${id}" } + Guild getGuild() { client.guild((String) guildObject.id) } Map getGuildObject() { (Map) object.guild } boolean isRevoked() { (boolean) object.revoked } - boolean isDeleted(){ revoked } + boolean isDeleted() { revoked } String getRawCreatedAt() { (String) object.created_at } - Date getCreatedAt(){ ConversionUtil.fromJsonDate(rawCreatedAt) } + Date getCreatedAt() { ConversionUtil.fromJsonDate(rawCreatedAt) } boolean isTemporary() { (boolean) object.temporary } int getUses() { (int) object.uses } int getMaxUses() { (int) object.max_uses } - User getInviter(){ new User(client, (Map) object.inviter) } - Channel getChannel(){ client.channel((String) channelObject.id) } + User getInviter() { new User(client, (Map) object.inviter) } + Channel getChannel() { client.channel((String) channelObject.id) } Map getChannelObject() { (Map) object.channel } - DiscordObject getParent(){ channel } - String toString(){ url } + DiscordObject getParent() { channel } + String toString() { url } - void delete(){ client.deleteInvite(id) } + void delete() { client.deleteInvite(id) } - static String parseId(i){ + static String parseId(i) { if (i instanceof Invite) return i def urlText = i.toString() URL urlObj = i instanceof URL ? (URL) i : new URL(i.toString()) diff --git a/src/main/groovy/hlaaftana/discordg/objects/Message.groovy b/src/main/groovy/hlaaftana/discordg/objects/Message.groovy index e3b665e..f8732b3 100644 --- a/src/main/groovy/hlaaftana/discordg/objects/Message.groovy +++ b/src/main/groovy/hlaaftana/discordg/objects/Message.groovy @@ -17,108 +17,108 @@ class Message extends DiscordObject { // this is discord's url pattern (with a little fiddling) static String urlPattern = /https?:\/\/[^\s<]+[^<"{|^~`\[\s]/ - Message(Client client, Map object){ + Message(Client client, Map object) { super(client, object) } - String getName(){ content } + String getName() { content } def getNonce() { object.nonce } String getContent() { (String) object.content } String getRawEditedAt() { (String) object.edited_timestamp } - Date getEditedAt(){ ConversionUtil.fromJsonDate(rawEditedAt) } + Date getEditedAt() { ConversionUtil.fromJsonDate(rawEditedAt) } String getRawTimestamp() { (String) object.timestamp } - Date getTimestamp(){ ConversionUtil.fromJsonDate(rawTimestamp) } + Date getTimestamp() { ConversionUtil.fromJsonDate(rawTimestamp) } boolean isTts() { (boolean) object.tts } int getType() { (int) object.type } boolean isMentionsEveryone() { (boolean) object.mention_everyone } String getChannelId() { (String) object.channel_id } - boolean isPrivate(){ client.privateChannelCache.containsKey(channelId) } - boolean isDm(){ channel.dm } - boolean isGroup(){ channel.group } + boolean isPrivate() { client.privateChannelCache.containsKey(channelId) } + boolean isDm() { channel.dm } + boolean isGroup() { channel.group } - Attachment getAttachment(){ attachments[0] } - List getAttachments(){ + Attachment getAttachment() { attachments[0] } + List getAttachments() { ((List) object.attachments).collect { new Attachment(client, it + [message_id: id]) } } - List getEmbeds(){ + List getEmbeds() { ((List) object.embeds).collect { new Embed(client, it + [message_id: id]) } } - List getUrls(){ + List getUrls() { (content =~ urlPattern).collect() as List } - List getUrlObjects(){ urls.collect(DefaultGroovyMethods.&toURL) } + List getUrlObjects() { urls.collect(DefaultGroovyMethods.&toURL) } User getAuthor() { getAuthor(false) } User getAuthor(boolean member) { resolveMember((Map) object.author, member) } - User author(boolean member = false){ + User author(boolean member = false) { getAuthor(member) } User getSender() { author } - User resolveMember(User user, boolean member = true){ + User resolveMember(User user, boolean member = true) { Member ass = guild?.member(user) if (ass && member) ass else user } - User resolveMember(Map object, boolean member = true){ + User resolveMember(Map object, boolean member = true) { Member ass = guild?.member(object) if (ass && member) ass else new User(client, object) } Member getMember() { (Member) author(true) } - boolean isByWebhook(){ webhookId } + boolean isByWebhook() { webhookId } String getWebhookId() { (String) object.webhook_id } - Webhook requestWebhook(){ client.requestWebhook(webhookId) } + Webhook requestWebhook() { client.requestWebhook(webhookId) } - String getGuildId(){ client.channelGuildIdMap[channelId] } - Guild getGuild(){ channel?.guild } - Channel getParent(){ channel } - Channel getChannel(){ client.channel(channelId) } + String getGuildId() { client.channelGuildIdMap[channelId] } + Guild getGuild() { channel?.guild } + Channel getParent() { channel } + Channel getChannel() { client.channel(channelId) } List getMentions() { getMentions(false) } - List getMentions(boolean member){ ((List) object.mentions).collect { resolveMember(it, member) } } - List mentions(boolean member = false){ getMentions(member) } - List getMentionedRoles(){ ((List) object.mention_roles).collect { guild.roleMap[it] } } - List getRoleMentions(){ mentionedRoles } - - List getMentionedChannelIds(){ channelIdMentions } - List getChannelMentionIds(){ channelIdMentions } - List getChannelIdMentions(){ + List getMentions(boolean member) { ((List) object.mentions).collect { resolveMember(it, member) } } + List mentions(boolean member = false) { getMentions(member) } + List getMentionedRoles() { ((List) object.mention_roles).collect { guild.roleMap[it] } } + List getRoleMentions() { mentionedRoles } + + List getMentionedChannelIds() { channelIdMentions } + List getChannelMentionIds() { channelIdMentions } + List getChannelIdMentions() { (content =~ /<#(\d+)>/).collect { full, String id -> id } } - List getMentionedChannels(){ channelMentions } - List getChannelMentions(){ + List getMentionedChannels() { channelMentions } + List getChannelMentions() { channelIdMentions.collect(guild.&channel) - (Object) null } - Permissions getAuthorPermissions(){ + Permissions getAuthorPermissions() { channel.permissionsFor(author()) } - boolean isMentioned(thing = client.user){ + boolean isMentioned(thing = client.user) { id(thing) in mentions.collect(this.&id) || guild.member(thing)?.roles?.any { it in mentionedRoles } || id(thing) in object.mention_roles } boolean isPinned() { (boolean) object.pinned } - def pin(){ client.pinMessage(channelId, id) } - def unpin(){ client.unpinMessage(channelId, id) } + def pin() { client.pinMessage(channelId, id) } + def unpin() { client.unpinMessage(channelId, id) } - List getReactions(){ ((List) object.reactions).collect { new Reaction(client, it) } } + List getReactions() { ((List) object.reactions).collect { new Reaction(client, it) } } - void react(emoji){ + void react(emoji) { client.reactToMessage(channelId, this, emoji) } - void unreact(emoji, user = '@me'){ + void unreact(emoji, user = '@me') { client.unreactToMessage(channelId, this, emoji, user) } - List requestReactors(emoji, int limit = 100){ + List requestReactors(emoji, int limit = 100) { client.requestReactors(channelId, id, emoji, limit) } @@ -126,7 +126,7 @@ class Message extends DiscordObject { edit(content: newContent) } - Message edit(Map data){ + Message edit(Map data) { client.editMessage(data, channelId, this) } @@ -134,12 +134,12 @@ class Message extends DiscordObject { client.deleteMessage(channelId, this) } - void deleteAfter(long ms){ Thread.sleep(ms); delete() } - Message editAfter(String newContent, long ms){ Thread.sleep(ms); edit(newContent) } - void deleteIf(Closure closure){ if (closure(this)){ delete() } } - Message editIf(String newContent, Closure closure){ if (closure(this)){ edit(newContent) } } + void deleteAfter(long ms) { Thread.sleep(ms); delete() } + Message editAfter(String newContent, long ms) { Thread.sleep(ms); edit(newContent) } + void deleteIf(Closure closure) { if (closure(this)){ delete() } } + Message editIf(String newContent, Closure closure) { if (closure(this)){ edit(newContent) } } - String toString(){ "$author.name: $content" } + String toString() { "$author.name: $content" } } @InheritConstructors @@ -150,65 +150,65 @@ class Attachment extends DiscordObject { String getFilename() { (String) object.filename } String getFileName() { (String) object.filename } int getSize() { (int) object.size } - boolean isImage(){ object.width && object.height } + boolean isImage() { object.width && object.height } int getWidth() { (int) object.width } int getHeight() { (int) object.height } String getProxyUrl() { (String) object.proxy_url } String getUrl() { (String) object.url } - InputStream newInputStream(){ inputStreamFromDiscord(url) } - File download(file){ downloadFileFromDiscord(url, file) } + InputStream newInputStream() { inputStreamFromDiscord(url) } + File download(file) { downloadFileFromDiscord(url, file) } } @InheritConstructors @CompileStatic class Embed extends DiscordObject { String getMessageId() { (String) object.message_id } - String getId(){ messageId } + String getId() { messageId } String getName() { (String) object.title } String getTitle() { (String) object.title } String getType() { (String) object.type } String getDescription() { (String) object.description } String getUrl() { (String) object.url } - InputStream newInputStream(){ inputStreamFromDiscord(url) } - File download(file){ downloadFileFromDiscord(url, file) } + InputStream newInputStream() { inputStreamFromDiscord(url) } + File download(file) { downloadFileFromDiscord(url, file) } int getColor() { (int) object.color } String getTimestamp() { (String) object.timestamp } - Image getThumbnail(){ object.thumbnail ? new Image(client, (Map) object.thumbnail) : null } - Provider getProvider(){ object.provider ? new Provider(client, (Map) object.provider) : null } - Video getVideo(){ object.video ? new Video(client, (Map) object.video) : null } - Image getImage(){ object.image ? new Image(client, (Map) object.image) : null } - Footer getFooter(){ object.footer ? new Footer(client, (Map) object.footer) : null } - Author getAuthor(){ object.author ? new Author(client, (Map) object.author) : null } - List getFields(){ object.fields ? ((List) object.fields).collect { new Field(client, it) } : null } + Image getThumbnail() { object.thumbnail ? new Image(client, (Map) object.thumbnail) : null } + Provider getProvider() { object.provider ? new Provider(client, (Map) object.provider) : null } + Video getVideo() { object.video ? new Video(client, (Map) object.video) : null } + Image getImage() { object.image ? new Image(client, (Map) object.image) : null } + Footer getFooter() { object.footer ? new Footer(client, (Map) object.footer) : null } + Author getAuthor() { object.author ? new Author(client, (Map) object.author) : null } + List getFields() { object.fields ? ((List) object.fields).collect { new Field(client, it) } : null } @InheritConstructors static class Image extends DiscordObject { - String getName(){ url } + String getName() { url } String getProxyUrl() { (String) object.proxy_url } String getUrl() { (String) object.url } int getWidth() { (int) object.width } int getHeight() { (int) object.height } - InputStream newInputStream(){ inputStreamFromDiscord(url) } - File download(file){ downloadFileFromDiscord(url, file) } + InputStream newInputStream() { inputStreamFromDiscord(url) } + File download(file) { downloadFileFromDiscord(url, file) } } @InheritConstructors static class Provider extends DiscordObject { - String getName(){ url } + String getName() { url } String getUrl() { (String) object.url } - InputStream newInputStream(){ inputStreamFromDiscord(url) } - File download(file){ downloadFileFromDiscord(url, file) } + InputStream newInputStream() { inputStreamFromDiscord(url) } + File download(file) { downloadFileFromDiscord(url, file) } } @InheritConstructors static class Video extends DiscordObject { - String getName(){ url } + String getName() { url } String getUrl() { (String) object.url } int getWidth() { (int) object.width } int getHeight() { (int) object.height } - InputStream newInputStream(){ inputStreamFromDiscord(url) } - File download(file){ downloadFileFromDiscord(url, file) } + InputStream newInputStream() { inputStreamFromDiscord(url) } + File download(file) { downloadFileFromDiscord(url, file) } } @InheritConstructors @@ -216,18 +216,18 @@ class Embed extends DiscordObject { String getName() { (String) object.name } String getIconUrl() { (String) object.icon_url } String getProxyIconUrl() { (String) object.proxy_icon_url } - InputStream newIconInputStream(){ inputStreamFromDiscord(iconUrl) } - File downloadIcon(file){ downloadFileFromDiscord(iconUrl, file) } + InputStream newIconInputStream() { inputStreamFromDiscord(iconUrl) } + File downloadIcon(file) { downloadFileFromDiscord(iconUrl, file) } } @InheritConstructors static class Footer extends DiscordObject { - String getName(){ text } + String getName() { text } String getText() { (String) object.text } String getIconUrl() { (String) object.icon_url } String getProxyIconUrl() { (String) object.proxy_icon_url } - InputStream newIconInputStream(){ inputStreamFromDiscord(iconUrl) } - File downloadIcon(file){ downloadFileFromDiscord(iconUrl, file) } + InputStream newIconInputStream() { inputStreamFromDiscord(iconUrl) } + File downloadIcon(file) { downloadFileFromDiscord(iconUrl, file) } } @InheritConstructors @@ -241,12 +241,12 @@ class Embed extends DiscordObject { @InheritConstructors @CompileStatic class Reaction extends DiscordObject { - String getId(){ (String) ((Map) object.emoji).id } - String getName(){ (String) ((Map) object.emoji).name } + String getId() { (String) ((Map) object.emoji).id } + String getName() { (String) ((Map) object.emoji).name } int getCount() { (int) object.count } - String getUrl(){ "https://cdn.discordapp.com/emojis/${id}.png" } - InputStream newInputStream(){ inputStreamFromDiscord(url) } - File download(file){ downloadFileFromDiscord(url, file) } - boolean isCustom(){ name ==~ /\w+/ } + String getUrl() { "https://cdn.discordapp.com/emojis/${id}.png" } + InputStream newInputStream() { inputStreamFromDiscord(url) } + File download(file) { downloadFileFromDiscord(url, file) } + boolean isCustom() { name ==~ /\w+/ } boolean isByMe() { (boolean) object.me } } diff --git a/src/main/groovy/hlaaftana/discordg/objects/User.groovy b/src/main/groovy/hlaaftana/discordg/objects/User.groovy index ee7bd80..6632670 100644 --- a/src/main/groovy/hlaaftana/discordg/objects/User.groovy +++ b/src/main/groovy/hlaaftana/discordg/objects/User.groovy @@ -17,77 +17,77 @@ import java.util.regex.Pattern class User extends DiscordObject{ static final Pattern MENTION_REGEX = ~/<@!?(\d+)>/ - User(Client client, Map object){ + User(Client client, Map object) { super(client, object) } - List getPresences(){ client.members(this)*.presence - (Object) null } - String getStatus(){ presences[0]?.status ?: 'offline' } - Game getGame(){ presences[0]?.game } - boolean isOnline(){ status == 'online' } - boolean isOffline(){ status == 'offline' } - boolean isIdle(){ status == 'idle' } - boolean isAway(){ status == 'idle' } - String getName(){ username } + List getPresences() { client.members(this)*.presence - (Object) null } + String getStatus() { presences[0]?.status ?: 'offline' } + Game getGame() { presences[0]?.game } + boolean isOnline() { status == 'online' } + boolean isOffline() { status == 'offline' } + boolean isIdle() { status == 'idle' } + boolean isAway() { status == 'idle' } + String getName() { username } String getUsername() { (String) object.username } String getAvatarHash() { (String) object.avatar } String getRawAvatarHash() { (String) object.avatar } - boolean hasAvatar(){ object.avatar } - int getDefaultAvatarType(){ Integer.parseInt(discriminator) % 5 } - String getAvatar(){ hasAvatar() ? + boolean hasAvatar() { object.avatar } + int getDefaultAvatarType() { Integer.parseInt(discriminator) % 5 } + String getAvatar() { hasAvatar() ? "https://cdn.discordapp.com/avatars/${id}/${avatarHash}.jpg" : '' } - InputStream newAvatarInputStream(){ inputStreamFromDiscord(avatar) } - File downloadAvatar(file){ downloadFileFromDiscord(avatar, file) } + InputStream newAvatarInputStream() { inputStreamFromDiscord(avatar) } + File downloadAvatar(file) { downloadFileFromDiscord(avatar, file) } String getDiscriminator() { (String) object.discriminator } String getDiscrim() { (String) object.discriminator } - String getNameAndDiscrim(){ "$name#$discrim" } - String getUniqueName(){ "$name#$discrim" } - String getUnique(){ "$name#$discrim" } + String getNameAndDiscrim() { "$name#$discrim" } + String getUniqueName() { "$name#$discrim" } + String getUnique() { "$name#$discrim" } boolean isBot() { (boolean) object.bot } String getEmail() { (String) object.email } String getPassword() { (String) object.password } - Channel getPrivateChannel(){ + Channel getPrivateChannel() { client.userDmChannel(id) } - Channel getChannel(){ + Channel getChannel() { createOrGetPrivateChannel() } - Channel createPrivateChannel(){ + Channel createPrivateChannel() { client.createPrivateChannel(this) } - Channel createOrGetPrivateChannel(){ + Channel createOrGetPrivateChannel() { privateChannel ?: createPrivateChannel() } - Relationship getRelationship(){ + Relationship getRelationship() { client.relationshipCache.at(id) } - void addRelationship(type){ + void addRelationship(type) { client.addRelationship(id, type) } - void removeRelationship(){ + void removeRelationship() { client.removeRelationship(id) } - Permissions permissionsFor(Channel channel){ + Permissions permissionsFor(Channel channel) { channel.permissionsFor(this) } - List getSharedGuilds(){ client.members(this)*.guild } - String getMention(){ "<@$id>" } - Member getMember(guild){ client.guild(guild).member(this) } - Member member(guild){ client.guild(guild).member(this) } + List getSharedGuilds() { client.members(this)*.guild } + String getMention() { "<@$id>" } + Member getMember(guild) { client.guild(guild).member(this) } + Member member(guild) { client.guild(guild).member(this) } Message sendMessage(content, boolean tts=false) { channel.sendMessage(content, tts) } - Message sendMessage(Map data){ channel.sendMessage(data) } - Message send(Map data){ sendMessage(data) } - Message send(content, boolean tts = false){ sendMessage(content, tts) } + Message sendMessage(Map data) { channel.sendMessage(data) } + Message send(Map data) { sendMessage(data) } + Message send(content, boolean tts = false) { sendMessage(content, tts) } Message sendFile(Map data, implicatedFile, filename = null) { channel.sendFile(data, implicatedFile, filename) @@ -101,50 +101,50 @@ class User extends DiscordObject{ @InheritConstructors @CompileStatic class Connection extends DiscordObject { - List getIntegrations(){ ((List) object.integrations).collect { new Integration(client, it) } } + List getIntegrations() { ((List) object.integrations).collect { new Integration(client, it) } } boolean isRevoked() { (boolean) object.revoked } String getType() { (String) object.type } } @CompileStatic class Application extends DiscordObject { - Application(Client client, Map object){ + Application(Client client, Map object) { super(client, object) } String getSecret() { (String) object.secret } List getRedirectUris() { (List) object.redirect_uris } - String getDescription(){ (String) object.description ?: '' } - BotAccount getBot(){ new BotAccount(client, (Map) object.bot) } - BotAccount getBotAccount(){ botAccount } + String getDescription() { (String) object.description ?: '' } + BotAccount getBot() { new BotAccount(client, (Map) object.bot) } + BotAccount getBotAccount() { botAccount } String getIconHash() { (String) object.icon } String getIcon() { iconHash ? "https://cdn.discordapp.com/app-icons/$id/${iconHash}.jpg" : '' } - boolean hasIcon(){ (boolean) object.icon } - InputStream newIconInputStream(){ inputStreamFromDiscord(icon) } - File downloadIcon(file){ downloadFileFromDiscord(icon, file) } + boolean hasIcon() { (boolean) object.icon } + InputStream newIconInputStream() { inputStreamFromDiscord(icon) } + File downloadIcon(file) { downloadFileFromDiscord(icon, file) } - Application edit(Map data){ + Application edit(Map data) { client.editApplication(data, id) } - void delete(){ + void delete() { client.deleteApplication(id) } - BotAccount createBot(String oldAccountToken = null){ + BotAccount createBot(String oldAccountToken = null) { client.createApplicationBotAccount(this, oldAccountToken) } - String getApplicationLink(Permissions perms = null){ + String getApplicationLink(Permissions perms = null) { Client.getApplicationLink(this, perms) } - String getAppLink(Permissions perms = null){ getApplicationLink(perms) } - String applicationLink(Permissions perms = null){ getApplicationLink(perms) } - String appLink(Permissions perms = null){ getApplicationLink(perms) } + String getAppLink(Permissions perms = null) { getApplicationLink(perms) } + String applicationLink(Permissions perms = null) { getApplicationLink(perms) } + String appLink(Permissions perms = null) { getApplicationLink(perms) } } @InheritConstructors @@ -155,16 +155,16 @@ class BotAccount extends User { @CompileStatic class Profile extends User { - Profile(Client client, Map object){ + Profile(Client client, Map object) { super(client, object + (Map) object.user) } - User getUser(){ new User(client, (Map) object.user) } + User getUser() { new User(client, (Map) object.user) } boolean isPremium() { (boolean) object.premium } - List getAccounts(){ ((List) object.connected_accounts).collect { new Account(client, it) } } - List getMutualGuildIds(){ ((List) object.mutual_guilds)*.get('id') } - List getMutualGuilds(){ mutualGuildIds.collect { client.guild(it) } } - Map getMutualGuildNickMap(){ + List getAccounts() { ((List) object.connected_accounts).collect { new Account(client, it) } } + List getMutualGuildIds() { ((List) object.mutual_guilds)*.get('id') } + List getMutualGuilds() { mutualGuildIds.collect { client.guild(it) } } + Map getMutualGuildNickMap() { ((List) object.mutual_guilds).collectEntries { [(it.id): it.nick] } } @@ -176,8 +176,8 @@ class Profile extends User { @CompileStatic class Relationship extends User { - Relationship(Client client, Map object){ super(client, object + (Map) object.user) } + Relationship(Client client, Map object) { super(client, object + (Map) object.user) } - User getUser(){ new User(client, (Map) object.user) } + User getUser() { new User(client, (Map) object.user) } int getType() { (int) object.type } } \ No newline at end of file diff --git a/src/main/groovy/hlaaftana/discordg/objects/Webhook.groovy b/src/main/groovy/hlaaftana/discordg/objects/Webhook.groovy index 0ff3c6d..fccc6fc 100644 --- a/src/main/groovy/hlaaftana/discordg/objects/Webhook.groovy +++ b/src/main/groovy/hlaaftana/discordg/objects/Webhook.groovy @@ -6,46 +6,46 @@ import hlaaftana.discordg.DiscordObject @CompileStatic class Webhook extends DiscordObject { - Webhook(Client client, Map object){ + Webhook(Client client, Map object) { super(client, object) } - String getName(){ object.name ?: ((Map) object.user).username } - String getAvatarHash(){ object.avatar ?: ((Map) object.user).avatar } - boolean hasAvatar(){ object.avatar } - String getAvatar(){ hasAvatar() ? + String getName() { object.name ?: ((Map) object.user).username } + String getAvatarHash() { object.avatar ?: ((Map) object.user).avatar } + boolean hasAvatar() { object.avatar } + String getAvatar() { hasAvatar() ? "https://cdn.discordapp.com/avatars/$id/${avatarHash}.jpg" : '' } - InputStream getAvatarInputStream(){ inputStreamFromDiscord(avatar) } - File downloadAvatar(file){ downloadFileFromDiscord(avatar, file) } - User getUser(){ object.user ? new User(client, (Map) object.user) : null } + InputStream getAvatarInputStream() { inputStreamFromDiscord(avatar) } + File downloadAvatar(file) { downloadFileFromDiscord(avatar, file) } + User getUser() { object.user ? new User(client, (Map) object.user) : null } String getChannelId() { (String) object.channel_id } String getGuildId() { (String) object.guild_id } - Guild getGuild(){ client.guild(guildId) } - Channel getChannel(){ guild.channel(channelId) } + Guild getGuild() { client.guild(guildId) } + Channel getChannel() { guild.channel(channelId) } String getToken() { (String) object.token } Webhook retrieve() { client.requestWebhook(id, token) } - Webhook edit(Map data){ + Webhook edit(Map data) { client.editWebhook(data, this) } - void delete(){ + void delete() { client.deleteWebhook(this) } - Message sendMessage(Map data){ + Message sendMessage(Map data) { client.sendMessage(data + [webhook: true], this) } - Message sendMessage(content, boolean tts = false){ + Message sendMessage(content, boolean tts = false) { sendMessage(content: content, tts: tts) } - Message send(Map data){ sendMessage(data) } - Message send(content, boolean tts = false){ sendMessage(content, tts) } + Message send(Map data) { sendMessage(data) } + Message send(content, boolean tts = false) { sendMessage(content, tts) } Message sendFile(Map data, implicatedFile, filename = null) { client.sendFile(data + [webhook: true], this, implicatedFile, filename) diff --git a/src/main/groovy/hlaaftana/discordg/status/DiscordStatus.groovy b/src/main/groovy/hlaaftana/discordg/status/DiscordStatus.groovy index df74739..441226a 100644 --- a/src/main/groovy/hlaaftana/discordg/status/DiscordStatus.groovy +++ b/src/main/groovy/hlaaftana/discordg/status/DiscordStatus.groovy @@ -3,6 +3,6 @@ package hlaaftana.discordg.status import hlaaftana.discordg.util.JSONSimpleHTTP class DiscordStatus { - static Schedule getActiveSchedule(){ new Schedule(JSONSimpleHTTP.get('https://status.discordapp.com/api/v2/scheduled-maintenances/active.json')) } - static Schedule getUpcomingSchedule(){ new Schedule(JSONSimpleHTTP.get('https://status.discordapp.com/api/v2/scheduled-maintenances/upcoming.json')) } + static Schedule getActiveSchedule() { new Schedule(JSONSimpleHTTP.get('https://status.discordapp.com/api/v2/scheduled-maintenances/active.json')) } + static Schedule getUpcomingSchedule() { new Schedule(JSONSimpleHTTP.get('https://status.discordapp.com/api/v2/scheduled-maintenances/upcoming.json')) } } diff --git a/src/main/groovy/hlaaftana/discordg/status/IncidentUpdate.groovy b/src/main/groovy/hlaaftana/discordg/status/IncidentUpdate.groovy index 0caa072..8416c50 100644 --- a/src/main/groovy/hlaaftana/discordg/status/IncidentUpdate.groovy +++ b/src/main/groovy/hlaaftana/discordg/status/IncidentUpdate.groovy @@ -3,16 +3,16 @@ package hlaaftana.discordg.status import hlaaftana.discordg.util.ConversionUtil class IncidentUpdate extends MapObject { - IncidentUpdate(Map object){ super(object) } + IncidentUpdate(Map object) { super(object) } String getStatus() { (String) object.status } String getBody() { (String) object.body } String getRawUpdatedAt() { (String) object.updated_at } - Date getUpdatedAt(){ ConversionUtil.fromJsonDate(object.updated_at) } + Date getUpdatedAt() { ConversionUtil.fromJsonDate(object.updated_at) } String getRawCreatedAt() { (String) object.created_at } - Date getCreatedAt(){ ConversionUtil.fromJsonDate(object.created_at) } + Date getCreatedAt() { ConversionUtil.fromJsonDate(object.created_at) } String getRawDisplayAt() { (String) object.display_at } - Date getDisplayAt(){ ConversionUtil.fromJsonDate(object.display_at) } + Date getDisplayAt() { ConversionUtil.fromJsonDate(object.display_at) } String getId() { (String) object.id } String getIncidentId() { (String) object.incident_id } } diff --git a/src/main/groovy/hlaaftana/discordg/status/Maintenance.groovy b/src/main/groovy/hlaaftana/discordg/status/Maintenance.groovy index d344c26..23ab6db 100644 --- a/src/main/groovy/hlaaftana/discordg/status/Maintenance.groovy +++ b/src/main/groovy/hlaaftana/discordg/status/Maintenance.groovy @@ -3,22 +3,22 @@ package hlaaftana.discordg.status import hlaaftana.discordg.util.ConversionUtil class Maintenance extends MapObject { - Maintenance(Map object){ super(object) } + Maintenance(Map object) { super(object) } String getName() { (String) object.name } String getStatus() { (String) object.status } String getRawUpdatedAt() { (String) object.updated_at } - Date getUpdatedAt(){ ConversionUtil.fromJsonDate(object.updated_at) } + Date getUpdatedAt() { ConversionUtil.fromJsonDate(object.updated_at) } String getRawCreatedAt() { (String) object.created_at } - Date getCreatedAt(){ ConversionUtil.fromJsonDate(object.created_at) } + Date getCreatedAt() { ConversionUtil.fromJsonDate(object.created_at) } String getShortlink() { (String) object.shortlink } String getRawScheduleStart() { (String) object.scheduled_for } - Date getScheduleStart(){ ConversionUtil.fromJsonDate(object.scheduled_for) } + Date getScheduleStart() { ConversionUtil.fromJsonDate(object.scheduled_for) } String getRawScheduleEnd() { (String) object.scheduled_until } - Date getScheduleEnd(){ ConversionUtil.fromJsonDate(object.scheduled_until) } + Date getScheduleEnd() { ConversionUtil.fromJsonDate(object.scheduled_until) } String getId() { (String) object.id } String getPageId() { (String) object.page_id } String getImpact() { (String) object.impact } - List getIncidentUpdates(){ object.incident_updates.collect { new IncidentUpdate(it) } } - List getUpdates(){ object.incident_updates.collect { new IncidentUpdate(it) } } + List getIncidentUpdates() { object.incident_updates.collect { new IncidentUpdate(it) } } + List getUpdates() { object.incident_updates.collect { new IncidentUpdate(it) } } } diff --git a/src/main/groovy/hlaaftana/discordg/status/MapObject.groovy b/src/main/groovy/hlaaftana/discordg/status/MapObject.groovy index 046480d..bb48029 100644 --- a/src/main/groovy/hlaaftana/discordg/status/MapObject.groovy +++ b/src/main/groovy/hlaaftana/discordg/status/MapObject.groovy @@ -6,8 +6,8 @@ package hlaaftana.discordg.status */ class MapObject { Map object - MapObject(Map object){ this.object = object } - String toString(){ object.toString() } - boolean equals(other){ object == other.object } + MapObject(Map object) { this.object = object } + String toString() { object.toString() } + boolean equals(other) { object == other.object } } diff --git a/src/main/groovy/hlaaftana/discordg/status/Schedule.groovy b/src/main/groovy/hlaaftana/discordg/status/Schedule.groovy index 8d19535..edc23f2 100644 --- a/src/main/groovy/hlaaftana/discordg/status/Schedule.groovy +++ b/src/main/groovy/hlaaftana/discordg/status/Schedule.groovy @@ -1,10 +1,10 @@ package hlaaftana.discordg.status class Schedule extends MapObject { - Schedule(Map object){ super(object) } + Schedule(Map object) { super(object) } - StatusPage getPage(){ new StatusPage(object.page) } - StatusPage getStatusPage(){ new StatusPage(object.page) } - List getScheduledMaintenances(){ object.scheduled_maintanences.collect { new Maintenance(it) } } - List getMaintenances(){ object.scheduled_maintanences.collect { new Maintenance(it) } } + StatusPage getPage() { new StatusPage(object.page) } + StatusPage getStatusPage() { new StatusPage(object.page) } + List getScheduledMaintenances() { object.scheduled_maintanences.collect { new Maintenance(it) } } + List getMaintenances() { object.scheduled_maintanences.collect { new Maintenance(it) } } } diff --git a/src/main/groovy/hlaaftana/discordg/status/StatusPage.groovy b/src/main/groovy/hlaaftana/discordg/status/StatusPage.groovy index 7e467da..cfb7057 100644 --- a/src/main/groovy/hlaaftana/discordg/status/StatusPage.groovy +++ b/src/main/groovy/hlaaftana/discordg/status/StatusPage.groovy @@ -3,11 +3,11 @@ package hlaaftana.discordg.status import hlaaftana.discordg.util.ConversionUtil class StatusPage extends MapObject { - StatusPage(Map object){ super(object) } + StatusPage(Map object) { super(object) } String getId() { (String) object.id } String getName() { (String) object.name } String getUrl() { (String) object.url } String getRawUpdatedAt() { (String) object.updated_at } - Date getUpdatedAt(){ ConversionUtil.fromJsonDate(object.updated_at) } + Date getUpdatedAt() { ConversionUtil.fromJsonDate(object.updated_at) } } diff --git a/src/main/groovy/hlaaftana/discordg/util/ClosureString.groovy b/src/main/groovy/hlaaftana/discordg/util/ClosureString.groovy index b9f34fd..19b963c 100644 --- a/src/main/groovy/hlaaftana/discordg/util/ClosureString.groovy +++ b/src/main/groovy/hlaaftana/discordg/util/ClosureString.groovy @@ -6,40 +6,40 @@ class ClosureString implements CharSequence { Closure closure boolean regex - ClosureString(Closure c){ + ClosureString(Closure c) { closure = c } - ClosureString(Pattern pattern){ + ClosureString(Pattern pattern) { closure = pattern.&toString regex = true } - ClosureString(notClosure){ + ClosureString(notClosure) { closure = notClosure.&toString } - ClosureString(ClosureString otherTrigger){ + ClosureString(ClosureString otherTrigger) { closure = otherTrigger.closure } - def plus(smh){ + def plus(smh) { "$this$smh" } - def plus(ClosureString trigger){ + def plus(ClosureString trigger) { this.class.newInstance({ "$this$trigger" }) } - boolean equals(other){ + boolean equals(other) { (other instanceof ClosureString && (is(other) || closure.is(other.closure))) || toString() == other.toString() } - String toString(){ + String toString() { "${closure()}" } - char charAt(int index){ toString() charAt index } - int length(){ toString() length() } - CharSequence subSequence(int start, int end){ toString() subSequence start, end } + char charAt(int index) { toString() charAt index } + int length() { toString() length() } + CharSequence subSequence(int start, int end) { toString() subSequence start, end } } \ No newline at end of file diff --git a/src/main/groovy/hlaaftana/discordg/util/ConversionUtil.groovy b/src/main/groovy/hlaaftana/discordg/util/ConversionUtil.groovy index 1ceb724..46b510a 100644 --- a/src/main/groovy/hlaaftana/discordg/util/ConversionUtil.groovy +++ b/src/main/groovy/hlaaftana/discordg/util/ConversionUtil.groovy @@ -10,22 +10,22 @@ class ConversionUtil { Calendar.DAY_OF_MONTH, Calendar.HOUR_OF_DAY, Calendar.MINUTE, Calendar.SECOND, Calendar.MILLISECOND] as int[] - static String encodeImageBase64(byte[] bytes, String type = 'jpg'){ + static String encodeImageBase64(byte[] bytes, String type = 'jpg') { "data:image/$type;base64," + bytes.encodeBase64().toString() } - static String encodeImageBase64(String pathToImage){ + static String encodeImageBase64(String pathToImage) { encodeImageBase64(pathToImage ==~ /https?:\/\/(?:.|\n)*/ ? new URL(pathToImage) : new File(pathToImage)) } - static String encodeImageBase64(imagable){ + static String encodeImageBase64(imagable) { if (imagable instanceof String) encodeImageBase64((String) imagable) else encodeImageBase64(getBytes(imagable)) } @CompileDynamic - static byte[] getBytes(thing){ + static byte[] getBytes(thing) { try { getBytes$(thing) } catch (MissingMethodException ignore) { try { getBytesProperty(thing) } catch (ex) { throw new UnsupportedOperationException("Cannot get byte array of $thing", ex) } } @@ -38,12 +38,12 @@ class ConversionUtil { static byte[] getBytes$(InputStream thing) { thing.bytes } static byte[] getBytes$(URL thing) { thing.bytes } static byte[] getBytes$(String thing) { thing.bytes } - static byte[] getBytes$(ByteArrayOutputStream stream){ stream.toByteArray() } + static byte[] getBytes$(ByteArrayOutputStream stream) { stream.toByteArray() } - static boolean isImagable(thing){ + static boolean isImagable(thing) { try{ thing instanceof byte[] || imagable.contains(thing.class) || getBytes(thing) != null - }catch (UnsupportedOperationException ignored){ + }catch (UnsupportedOperationException ignored) { false } } diff --git a/src/main/groovy/hlaaftana/discordg/util/JSONUtil.groovy b/src/main/groovy/hlaaftana/discordg/util/JSONUtil.groovy index 6789815..b9b6df3 100644 --- a/src/main/groovy/hlaaftana/discordg/util/JSONUtil.groovy +++ b/src/main/groovy/hlaaftana/discordg/util/JSONUtil.groovy @@ -16,29 +16,29 @@ import java.nio.charset.Charset class JSONUtil { static JsonSlurper slurper = new JsonSlurper() - static parse(String string){ + static parse(String string) { slurper.parseText(string) } - static parse(File file, String charset = 'UTF-8'){ parse(file.getText(charset)) } + static parse(File file, String charset = 'UTF-8') { parse(file.getText(charset)) } - static String json(thing){ + static String json(thing) { JsonOutput.toJson(thing instanceof JSONable ? thing.json() : thing) } - static String pjson(thing){ JsonOutput.prettyPrint(json(thing)) } + static String pjson(thing) { JsonOutput.prettyPrint(json(thing)) } - static File dump(String filename, thing, String charset = 'UTF-8'){ dump(new File(filename), thing, charset) } + static File dump(String filename, thing, String charset = 'UTF-8') { dump(new File(filename), thing, charset) } - static File dump(File file, thing, String charset = 'UTF-8'){ + static File dump(File file, thing, String charset = 'UTF-8') { if (!file.exists()) file.createNewFile() file.write(pjson(thing), charset) file } - static File modify(String filename, Map newData){ modify(new File(filename), newData) } + static File modify(String filename, Map newData) { modify(new File(filename), newData) } - static File modify(File file, Map newData){ + static File modify(File file, Map newData) { if (!file.exists()) return dump(file, newData) def a = parse(file) if (!(a instanceof Map)) @@ -52,7 +52,7 @@ class JSONUtil { dump(file, x) } - static Map modifyMaps(Map x, Map y){ + static Map modifyMaps(Map x, Map y) { def a = null == x ? new HashMap() : new HashMap(x) for (e in y) { def k = e.key, v = e.value @@ -82,23 +82,23 @@ interface JSONable { // it was bad. i replaced it with the Path class in my Kismet language class JSONSimpleHTTP { - static get(String url){ + static get(String url) { JSONUtil.parse(Unirest.get(url).header('User-Agent', DiscordG.USER_AGENT).asString().getBody()) } - static delete(String url){ + static delete(String url) { JSONUtil.parse(Unirest.delete(url).header('User-Agent', DiscordG.USER_AGENT).asString().getBody()) } - static post(String url, Map body){ + static post(String url, Map body) { JSONUtil.parse(Unirest.post(url).header('User-Agent', DiscordG.USER_AGENT).body(JSONUtil.json(body)).asString().getBody()) } - static patch(String url, Map body){ + static patch(String url, Map body) { JSONUtil.parse(Unirest.patch(url).header('User-Agent', DiscordG.USER_AGENT).body(JSONUtil.json(body)).asString().getBody()) } - static put(String url, Map body){ + static put(String url, Map body) { JSONUtil.parse(Unirest.put(url).header('User-Agent', DiscordG.USER_AGENT).body(JSONUtil.json(body)).asString().getBody()) } } diff --git a/src/main/groovy/hlaaftana/discordg/util/Log.groovy b/src/main/groovy/hlaaftana/discordg/util/Log.groovy index 37a7998..d6ec003 100644 --- a/src/main/groovy/hlaaftana/discordg/util/Log.groovy +++ b/src/main/groovy/hlaaftana/discordg/util/Log.groovy @@ -10,9 +10,9 @@ class Log { String name boolean enabled = true - Level enable(){ enabled = true; this } - Level disable(){ enabled = false; this } - boolean equals(Level other){ name == other.name } + Level enable() { enabled = true; this } + Level disable() { enabled = false; this } + boolean equals(Level other) { name == other.name } } static class Message { @@ -22,9 +22,9 @@ class Log { LocalDateTime time = LocalDateTime.now() Map info = [:] - String toString(){ toString(defaultFormatter) } - String toString(Log log){ toString(log.formatter) } - String toString(Closure formatter){ formatter(this) } + String toString() { toString(defaultFormatter) } + String toString(Log log) { toString(log.formatter) } + String toString(Closure formatter) { formatter(this) } } static List defaultLevels = [ @@ -52,22 +52,22 @@ class Log { List listeners = [{ Message it -> if (it.level.enabled) println formatter.call(it) }] String name - Log(String name){ this.name = name } + Log(String name) { this.name = name } - Log(Log parent){ + Log(Log parent) { formatter = parent.formatter name = parent.name } - def listen(Closure ass){ + def listen(Closure ass) { listeners.add ass } - def call(Message message){ + def call(Message message) { for (it in listeners) { it message } } - Level level(String name){ + Level level(String name) { Level ass = levels.find { it.name == name } if (null == ass) { ass = new Level(name: name) @@ -76,7 +76,7 @@ class Log { ass } - Level level(Level level){ + Level level(Level level) { if (level in levels) level else { levels.add level @@ -84,28 +84,28 @@ class Log { } } - Level propertyMissing(String name){ + Level propertyMissing(String name) { level(name) } - def methodMissing(String name, args){ + def methodMissing(String name, args) { Level level = (Level) propertyMissing(name) if (args.class.array) args = ((Object[]) args).toList() boolean argsIsMultiple = args instanceof Collection if (args instanceof Message || (argsIsMultiple && args.first() instanceof Message)){ invokeMethod('log', args) - }else{ + } else { def ahh = argsIsMultiple ? [level, *args] : [level, args] invokeMethod('log', ahh) } } - def log(Level level, content, String by = name){ + def log(Level level, content, String by = name) { Message ass = new Message(level: level, content: content.toString(), by: by) log(ass) } - def log(Message message){ + def log(Message message) { messages += message call(message) } diff --git a/src/main/groovy/hlaaftana/discordg/util/MiscUtil.groovy b/src/main/groovy/hlaaftana/discordg/util/MiscUtil.groovy index 70b46cc..110b17f 100644 --- a/src/main/groovy/hlaaftana/discordg/util/MiscUtil.groovy +++ b/src/main/groovy/hlaaftana/discordg/util/MiscUtil.groovy @@ -69,32 +69,32 @@ class MiscUtil { static Random listRandom = new Random() - static Clipboard getClipboard(){ Toolkit.defaultToolkit.systemClipboard } + static Clipboard getClipboard() { Toolkit.defaultToolkit.systemClipboard } - static copy(String content){ + static copy(String content) { clipboard.setContents(new StringSelection(content), null) } - static String paste(){ + static String paste() { clipboard.getContents(null).getTransferData(DataFlavor.stringFlavor) } static T defaultValueOnException(T defaultValue = null, Collection exceptions = [Exception], - Closure expr){ + Closure expr) { try{ expr() - }catch (ex){ + }catch (ex) { if (exceptions.any { it.isAssignableFrom(ex.class) }) defaultValue else throw ex } } - static String lchop(String s, CharSequence x){ + static String lchop(String s, CharSequence x) { s.startsWith(x.toString()) ? s.substring(x.size()) : s } - static String rchop(String s, CharSequence x){ + static String rchop(String s, CharSequence x) { s.endsWith(x.toString()) ? s.substring(0, s.size() - x.size()) : s } @@ -107,7 +107,7 @@ class MiscUtil { LocalDateTime.ofInstant(date.toInstant(), tz) } - static List> splitWhen(iter, @ClosureParams(FirstParam.FirstGenericType) Closure cond){ + static List> splitWhen(iter, @ClosureParams(FirstParam.FirstGenericType) Closure cond) { List> a = [[]] for (it in iter) { if (cond((T) it)) a.add([it]) @@ -116,38 +116,38 @@ class MiscUtil { a } - static String removeFromStart(String s, CharSequence x){ + static String removeFromStart(String s, CharSequence x) { s.startsWith(x.toString()) ? s.substring(x.size()) : s } - static String removeFromEnd(String s, CharSequence x){ + static String removeFromEnd(String s, CharSequence x) { s.endsWith(x.toString()) ? s.substring(0, s.size() - x.size()) : s } - static String removeFormatting(String s){ + static String removeFormatting(String s) { s.replace('~', '\\~').replace('_', '\\_').replace('*', '\\*') .replace('```', '\u200b`\u200b`\u200b`').replace('`', '\\`') .replace(':', '\\:').replace('`', '\\`').replace('/', '\\/') .replace('@', '\\@').replace('<', '\\<').replace('>', '\\>') } - static String surround(String s, String sur){ sur + s + sur } - static String bold(String s){ surround(s, '**') } - static String bolden(String s){ surround(s, '**') } - static String italic(String s, boolean underscore = false){ + static String surround(String s, String sur) { sur + s + sur } + static String bold(String s) { surround(s, '**') } + static String bolden(String s) { surround(s, '**') } + static String italic(String s, boolean underscore = false) { surround(s, underscore ? '_' : '*') } - static String italicize(String s, boolean underscore = false){ + static String italicize(String s, boolean underscore = false) { surround(s, underscore ? '_' : '*') } - static String underline(String s){ surround(s, '__') } - static String strikethrough(String s){ surround(s, '~~') } - static String code(String s){ surround(s, '`') } - static String block(String s, String language = ''){ "```$language\n$s```" } + static String underline(String s) { surround(s, '__') } + static String strikethrough(String s) { surround(s, '~~') } + static String code(String s) { surround(s, '`') } + static String block(String s, String language = '') { "```$language\n$s```" } /** * Registers a bunch of methods to help you with Discord formatting to the String meta class. */ @CompileDynamic - static registerStaticMethods(){ + static registerStaticMethods() { MiscUtil.metaClass.methods.findAll { it.declaringClass.theClass == MiscUtil && !(it.name in ['getProperty', 'invokeMethod', 'setProperty']) && @@ -251,7 +251,7 @@ abstract class CasingType { abstract List toWords(String words) abstract String fromWords(List words) - String to(CasingType casing, String text){ + String to(CasingType casing, String text) { casing.fromWords(toWords(text)) } } diff --git a/src/main/groovy/hlaaftana/discordg/util/WhatIs.groovy b/src/main/groovy/hlaaftana/discordg/util/WhatIs.groovy index e12d093..668340d 100644 --- a/src/main/groovy/hlaaftana/discordg/util/WhatIs.groovy +++ b/src/main/groovy/hlaaftana/discordg/util/WhatIs.groovy @@ -8,9 +8,9 @@ class WhatIs { def value def returnedValue - WhatIs(gay){ value = gay } + WhatIs(gay) { value = gay } - static whatis(value, @DelegatesTo(WhatIs) Closure tf){ + static whatis(value, @DelegatesTo(WhatIs) Closure tf) { WhatIs g = new WhatIs(value) tf.delegate = g tf.resolveStrategy = Closure.DELEGATE_FIRST @@ -18,8 +18,8 @@ class WhatIs { g.returnedValue } - def when(match, @DelegatesTo(WhatIs) Closure d){ - if (value in match){ + def when(match, @DelegatesTo(WhatIs) Closure d) { + if (value in match) { guessed = true d.delegate = this d.resolveStrategy = Closure.DELEGATE_FIRST @@ -27,18 +27,18 @@ class WhatIs { } } - def when(match, val){ - if (value in match){ + def when(match, val) { + if (value in match) { guessed = true returnedValue = val } } - def when(Map a){ + def when(Map a) { a.each(this.&when) } - def otherwise(Closure c){ + def otherwise(Closure c) { if (!guessed) { c.delegate = this c.resolveStrategy = Closure.DELEGATE_FIRST @@ -46,7 +46,7 @@ class WhatIs { } } - def otherwise(val){ + def otherwise(val) { if (!guessed) returnedValue = val } } diff --git a/src/main/groovy/hlaaftana/discordg/util/bot/CleverbotDotIO.groovy b/src/main/groovy/hlaaftana/discordg/util/bot/CleverbotDotIO.groovy index 8059c28..2fe2242 100644 --- a/src/main/groovy/hlaaftana/discordg/util/bot/CleverbotDotIO.groovy +++ b/src/main/groovy/hlaaftana/discordg/util/bot/CleverbotDotIO.groovy @@ -14,24 +14,24 @@ class CleverbotDotIO { String key String nick - CleverbotDotIO(String u, String k, String n = null){ + CleverbotDotIO(String u, String k, String n = null) { user = u key = k nick = n } - def startSession(){ + def startSession() { nick = post('create', [:]).nick } - String ask(text){ + String ask(text) { if (!nick) startSession() post('ask', [nick: nick, text: text]).response } - Map post(String path, Map body = null){ + Map post(String path, Map body = null) { Map response - if (body != null){ + if (body != null) { if (!user || !key) noAuth() Map a = new HashMap<>() a.user = user @@ -42,7 +42,7 @@ class CleverbotDotIO { Unirest.post(baseUrl + path) .fields(a) .asString().body) - }else{ + } else { response = (Map) JSONUtil.parse( Unirest.post(baseUrl + path) .asString().body) @@ -55,7 +55,7 @@ class CleverbotDotIO { 'Go to https://cleverbot.io/keys to get your user and key') } - private static Map checkResponse(Map response){ + private static Map checkResponse(Map response) { if (response.status != 'success') throw new APIException("Something messed up: $response.status") else response diff --git a/src/main/groovy/hlaaftana/discordg/util/bot/CommandBot.groovy b/src/main/groovy/hlaaftana/discordg/util/bot/CommandBot.groovy index 47ade52..3bef8b9 100644 --- a/src/main/groovy/hlaaftana/discordg/util/bot/CommandBot.groovy +++ b/src/main/groovy/hlaaftana/discordg/util/bot/CommandBot.groovy @@ -41,49 +41,49 @@ class CommandBot implements Triggerable { Client getClient() { this.@client ?: (client = new Client(bot: true)) } - def addCommand(Command command){ + def addCommand(Command command) { commands.add(command) } - def addCommands(List commands){ + def addCommands(List commands) { this.commands.addAll(commands) } void setTriggers(Collection s) { for (a in s) addTrigger(a) } DSLCommand command(Map info, alias, trigger = [], - @DelegatesTo(value = CommandEventData, strategy = Closure.DELEGATE_FIRST) Closure closure){ + @DelegatesTo(value = CommandEventData, strategy = Closure.DELEGATE_FIRST) Closure closure) { DSLCommand hey = new DSLCommand(info, closure, this, alias, trigger) commands.add(hey) hey } DSLCommand command(alias, trigger = [], - @DelegatesTo(value = CommandEventData, strategy = Closure.DELEGATE_FIRST) Closure closure){ + @DelegatesTo(value = CommandEventData, strategy = Closure.DELEGATE_FIRST) Closure closure) { command([:], alias, trigger, closure) } - Command command(Class commandClass, ...arguments){ + Command command(Class commandClass, ...arguments) { Object[] arr = new Object[arguments.length + 1] arr[0] = this System.arraycopy(arguments, 0, arr, 1, arguments.length) commandClass.newInstance(arr) } - Command command(Class commandClass, List arguments){ + Command command(Class commandClass, List arguments) { Object[] arr = new Object[arguments.size() + 1] arr[0] = this System.arraycopy(arguments, 0, arr, 1, arguments.size()) commandClass.newInstance(arr) } - Closure commandBuilder(Class commandClass){ + Closure commandBuilder(Class commandClass) { this.&command.curry(commandClass) } - void login(String token, boolean threaded = true){ + void login(String token) { loggedIn = true - client.login(token, true, threaded) + client.login(token, true) } /** @@ -99,7 +99,7 @@ class CommandBot implements Triggerable { commandRunnerListener = listenerSystem.addListener(Events.COMMAND) { BotCommandEventData d -> try { d.command.call(d.commandData) - d.command.uses += 1 + d.command.uses++ } catch (ex) { def c = new BotExceptionEventData(this, d, ex) listenerSystem.dispatchEvent(Events.EXCEPTION, c) @@ -124,15 +124,15 @@ class CommandBot implements Triggerable { if (!anyPassed) listenerSystem.dispatchEvent(Events.NO_COMMAND, new BotMapEventData(this, data)) } listenerSystem.dispatchEvent(Events.INITIALIZE, null) - if (null != token && !loggedIn) login(token) + if (!(null == token || loggedIn)) login(token) } - def initialize(String token){ + def initialize(String token) { initialize() login(token) } - def uninitialize(){ + def uninitialize() { listenerSystem.removeListener(Events.COMMAND, commandRunnerListener) client.removeListener('message', commandListener) } @@ -186,7 +186,7 @@ class BotExceptionEventData extends BotEventData { @CompileStatic abstract class CommandType { - private static quote(CommandPattern aot){ + private static quote(CommandPattern aot) { String g = aot.toString() aot.regex ? g : Pattern.quote(g) } @@ -222,16 +222,16 @@ trait Restricted { Map blacklist = [guild: [], channel: [], author: [], role: []] Map whitelist = [guild: [], channel: [], author: [], role: []] - def whitelist(){ white = true; this } - def blacklist(){ black = true; this } - def greylist(){ black = white = true; this } + def whitelist() { white = true; this } + def blacklist() { black = true; this } + def greylist() { black = white = true; this } - def whitelist(String type, thing){ whitelist(); allow(type, thing); this } - def blacklist(String type, thing){ blacklist(); disallow(type, thing); this } + def whitelist(String type, thing) { whitelist(); allow(type, thing); this } + def blacklist(String type, thing) { blacklist(); disallow(type, thing); this } - def allow(String type, ...thing){ allow(type, thing as Set) } + def allow(String type, ...thing) { allow(type, thing as Set) } - def allow(String type, thing){ + def allow(String type, thing) { if (thing instanceof Collection || thing.class.array) thing.each { allow(type, it) } if (white) @@ -241,9 +241,9 @@ trait Restricted { this } - def disallow(String type, ...thing){ disallow(type, thing as Set) } + def disallow(String type, ...thing) { disallow(type, thing as Set) } - def disallow(String type, thing){ + def disallow(String type, thing) { if (thing instanceof Collection || thing.class.array) thing.each { disallow(type, it) } if (white) @@ -253,13 +253,13 @@ trait Restricted { this } - def deny(String type, ...thing){ disallow(type, thing as Set) } + def deny(String type, ...thing) { disallow(type, thing as Set) } - def deny(String type, thing){ + def deny(String type, thing) { disallow(type, thing) } - boolean allows(Message msg){ + boolean allows(Message msg) { boolean wh = true boolean bl = false if (white) { @@ -291,7 +291,7 @@ trait Triggerable { triggers.add(trigger) } - def addTrigger(Triggerable triggers){ + def addTrigger(Triggerable triggers) { addTriggers(triggers.triggers) } @@ -318,7 +318,7 @@ trait Aliasable { aliases.add(alias) } - def addAlias(Aliasable aliases){ + def addAlias(Aliasable aliases) { addAliases(aliases.aliases) } @@ -366,7 +366,7 @@ class Command implements Triggerable, Aliasable, Restricted { type = parent.defaultCommandType } - Command(alias, trigger){ + Command(alias, trigger) { if (alias instanceof Collection || alias.class.array) addAliases(alias as Collection) else addAlias(alias) if (trigger instanceof Collection || trigger.class.array) addTriggers(trigger as Collection) @@ -374,7 +374,7 @@ class Command implements Triggerable, Aliasable, Restricted { } /// null if no match - Tuple2 match(Message msg){ + Tuple2 match(Message msg) { if (!allows(msg)) return null for (List x in (List>) [triggers, aliases].combinations()) if (x[0].allows(msg) && x[1].allows(msg) && msg.content ==~ type.matchCommand(x[0], x[1])) @@ -382,7 +382,7 @@ class Command implements Triggerable, Aliasable, Restricted { null } - Matcher matcher(Message msg){ + Matcher matcher(Message msg) { def pair = match(msg) if (!pair) return null msg.content =~ type.matchCommand(pair.first, pair.second) @@ -393,21 +393,21 @@ class Command implements Triggerable, Aliasable, Restricted { * @param d - the event data. * @return the arguments as a string. */ - String arguments(Message msg){ + String arguments(Message msg) { try{ msg.content.substring(allCaptures(msg)[0].length()).trim() - }catch (ignored){ + }catch (ignored) { '' } } // only for regex - List captures(Message msg){ + List captures(Message msg) { type.captures(allCaptures(msg)) } // only for regex - List allCaptures(Message msg){ + List allCaptures(Message msg) { def aa = matcher(msg).collect() String[] rid = [] if (aa instanceof String) rid = [aa] @@ -425,11 +425,11 @@ class Command implements Triggerable, Aliasable, Restricted { * Runs the command. * @param d - the event data. */ - def run(CommandEventData d){} - def run(Message msg){} + def run(CommandEventData d) {} + def run(Message msg) {} - def call(CommandEventData d){ run(d); run(d.message) } - def call(Message msg){ run(msg) } + def call(CommandEventData d) { run(d); run(d.message) } + def call(Message msg) { run(msg) } } /** @@ -444,13 +444,13 @@ class ResponseCommand extends Command { * @param response - a string to respond with to this command.
* The rest of the parameters are Command's parameters. */ - ResponseCommand(CommandBot parentT, alias, trigger = [], response){ + ResponseCommand(CommandBot parentT, alias, trigger = [], response) { super(parentT, alias, trigger) this.response = response instanceof Closure ? (Closure) response : { CommandEventData d -> "$response" } this.response.delegate = this } - def run(CommandEventData d){ + def run(CommandEventData d) { d.invokeMethod('sendMessage', response(d)) } } @@ -466,13 +466,13 @@ class ClosureCommand extends Command { /** * @param response - a closure to respond with to this command. Can take one parameter, which is the data of the event. */ - ClosureCommand(CommandBot parentT, alias, trigger = [], Closure response){ + ClosureCommand(CommandBot parentT, alias, trigger = [], Closure response) { super(parentT, alias, trigger) response.delegate = this this.response = response } - def run(CommandEventData d){ + def run(CommandEventData d) { response(d) } } @@ -485,7 +485,7 @@ class DSLCommand extends Command { DSLCommand(Map info = [:], @DelegatesTo(value = CommandEventData, strategy = Closure.DELEGATE_FIRST) Closure response, - CommandBot parentT, alias, trigger = []){ + CommandBot parentT, alias, trigger = []) { super(parentT, alias, trigger) this.response = (Closure) response.clone() info.each(this.&putAt) @@ -493,16 +493,16 @@ class DSLCommand extends Command { extraArgs << parentT.extraCommandArgs } - def propertyMissing(String name){ + def propertyMissing(String name) { if (info.containsKey(name)) info[name] else throw new MissingPropertyException(name, this.class) } - def propertyMissing(String name, value){ + def propertyMissing(String name, value) { info.put name, value } - def run(CommandEventData d){ + def run(CommandEventData d) { CommandEventData aa = (CommandEventData) d.clone() for (a in extraArgs) aa.setProperty(a.key, a.value.call(d))