Documented stuff, get methods, etc

This commit is contained in:
Zachary Vacura 2016-09-16 20:02:09 -05:00
parent c7af29060f
commit a3368b0610
17 changed files with 586 additions and 322 deletions

View file

@ -7,16 +7,6 @@ import 'http.dart';
/// The base class.
/// It contains all of the methods.
class Client {
Map _defaultOptions = {
"bot": true,
"debug": false,
"internal": {
"ws": {
"large_threshold": 100
}
}
};
var _socket;
int _lastS = null;
String _sessionID;
@ -25,36 +15,29 @@ class Client {
"ready": [],
"message": [],
"messageDelete": [],
"messageEdit": []
"messageEdit": [],
"debug": [],
"loginError": []
};
/// The token passed into the constructor.
String token;
/// The options passed into the constuctor.
///
/// {
/// "bot": true,
/// "debug": false,
/// "internal": {
/// "ws": {
/// "large_threshold": 100
/// }
/// }
/// }
Map<String, Object> options;
//Map<String, Guild> guilds = {};
/// The client's options.
ClientOptions options;
String _heartbeat() {
return JSON.encode({"op": 1,"d": this._lastS});
/// The logged in user.
ClientUser user;
void _heartbeat() {
this._socket.add(JSON.encode({"op": 1,"d": this._lastS}));
}
void _handleMsg(msg) {
if (this.options['debug']) {
print('Message received: $msg\n');
}
var json = JSON.decode(msg);
this._handlers['debug'].forEach((function) => function(json));
if (json['s'] != null) {
this._lastS = json['s'];
}
@ -63,7 +46,7 @@ class Client {
if (json["op"] == 10) {
const heartbeat_interval = const Duration(milliseconds: 41250);
new Timer.periodic(heartbeat_interval, (Timer t) => this._socket.add(this._heartbeat()));
new Timer.periodic(heartbeat_interval, (Timer t) => this._heartbeat());
this._socket.add(JSON.encode({
"op": 2,
@ -72,11 +55,17 @@ class Client {
"properties": {
"\$browser": "Discord Dart"
},
"large_threshold": this.options['internal']['ws']['large_threshold'],
"large_threshold": 100,
"compress": false
}
}));
} /*else if (json['op'] == 7) {
}
else if (json['op'] == 9) {
this._handlers['loginError'].forEach((function) => function());
}
/*else if (json['op'] == 7) {
this._socket.add(JSON.encode({
"token": this.token,
"session_id": this._sessionID,
@ -87,6 +76,14 @@ class Client {
else if (json["op"] == 0) {
if (json['t'] == "READY") {
this._sessionID = json['d']['session_id'];
this.user = new ClientUser(json['d']['user']);
if (this.user.bot) {
this._api.headers['Authorization'] = "Bot ${this.token}";
} else {
this._api.headers['Authorization'] = this.token;
}
this._handlers['ready'].forEach((function) => function());
}
@ -115,16 +112,14 @@ class Client {
}
}
Client(String token, [Map options = const {}]) {
this.options = this._defaultOptions..addAll(options);
if (this.options['bot']) {
this.token = "Bot $token";
Client(String token, [ClientOptions options]) {
if (options == null) {
this.options = new ClientOptions();
} else {
this.token = token;
this.options = options;
}
this._api.headers['Authorization'] = this.token;
this.token = token;
WebSocket.connect('wss://gateway.discord.gg?v=6&encoding=json').then((socket) {
this._socket = socket;
@ -150,7 +145,6 @@ class Client {
/// Sends a message.
///
/// Throws an [Exception] if the HTTP request errored.
/// Returns a [Message] object.
/// Client.sendMessage("channel id", "My content!");
Future<Message> sendMessage(String channel, String content) async {
var r = await this._api.post('channels/$channel/messages', {"content": content});
@ -166,7 +160,6 @@ class Client {
/// Deletes a message.
///
/// Throws an [Exception] if the HTTP request errored.
/// Returns nothing.
/// Client.sendMessage("channel id", "message id");
Future deleteMessage(String channel, String message) async {
var r = await this._api.delete('channels/$channel/messages/$message');
@ -181,7 +174,6 @@ class Client {
/// Edits a message.
///
/// Throws an [Exception] if the HTTP request errored.
/// Returns a [Message] object.
/// Client.sendMessage("channel id", "message id", "My edited content!");
Future<Message> editMessage(String channel, String message, String content) async {
var r = await this._api.patch('channels/$channel/messages/$message', {"content": content});
@ -190,14 +182,13 @@ class Client {
if (r.statusCode == 200) {
return new Message(res);
} else {
throw new Exception("'deleteMessage' error.");
throw new Exception("${res['code']}:${res['message']}");
}
}
/// Gets a [Channel] object.
///
/// Throws an [Exception] if the HTTP request errored.
/// Returns a [Channel] object.
/// Client.getChannel("channel id");
Future<Channel> getChannel(String id) async {
var r = await this._api.get('channels/$id');
@ -212,7 +203,6 @@ class Client {
/// Gets a [Guild] object.
///
/// Throws an [Exception] if the HTTP request errored.
/// Returns a [Guild] object.
/// Client.getGuild("guild id");
Future<Guild> getGuild(String id) async {
var r = await this._api.get('guilds/$id');
@ -227,7 +217,6 @@ class Client {
/// Gets a [Member] object.
///
/// Throws an [Exception] if the HTTP request errored.
/// Returns a [Member] object.
/// Client.getMember("guild id", "user id");
Future<Member> getMember(String guild, String member) async {
var r = await this._api.get('guilds/$guild/members/$member');
@ -242,7 +231,6 @@ class Client {
/// Gets a [User] object.
///
/// Throws an [Exception] if the HTTP request errored.
/// Returns a [User] object.
/// Client.getUser("user id");
Future<User> getUser(String id) async {
var r = await this._api.get('users/$id');
@ -254,25 +242,9 @@ class Client {
}
}
/// Gets the [User] object for the current logged in user.
///
/// Throws an [Exception] if the HTTP request errored.
/// Returns a [User] object.
/// Client.getUser("user id");
Future<User> getMe() async {
var r = await this._api.get('users/@me');
Map res = JSON.decode(r.body);
if (r.statusCode == 200) {
return new User(res);
} else {
throw new Exception("${res['code']}:${res['message']}");
}
}
/// Gets an [Invite] object.
///
/// Throws an [Exception] if the HTTP request errored.
/// Returns a [Invite] object.
/// Client.getInvite("invite code");
Future<Invite> getInvite(String code) async {
var r = await this._api.get('invites/$code');
@ -283,4 +255,23 @@ class Client {
throw new Exception("${res['code']}:${res['message']}");
}
}
/// Gets a [Message] object. Only usable by bot accounts.
///
/// Throws an [Exception] if the HTTP request errored or if the client user
/// is not a bot.
/// Client.getMessage("channel id", "message id");
Future<Message> getMessage(String channel, String message) async {
if (this.user.bot) {
var r = await this._api.get('channels/$channel/messages/$message');
Map res = JSON.decode(r.body);
if (r.statusCode == 200) {
return new Message(res);
} else {
throw new Exception("${res['code']}:${res['message']}");
}
} else {
throw new Exception("'getMessage' is only usable by bot accounts.");
}
}
}

View file

@ -1,258 +1,14 @@
class User {
String username;
String id;
String discriminator;
String avatar;
String mention;
bool bot = false;
User(Map data) {
this.username = data['username'];
this.id = data['id'];
this.discriminator = data['discriminator'];
this.avatar = data['avatar'];
this.mention = "<@${this.id}>";
if (data['bot']) {
this.bot = data['bot'];
}
}
}
class Member {
String nickname;
String joinedAt;
bool deaf;
bool mute;
List<String> roles;
User user;
Member(Map data) {
this.nickname = data['nick'];
this.joinedAt = data['joined_at'];
this.deaf = data['deaf'];
this.mute = data['mute'];
this.roles = data['roles'];
this.user = new User(data['user']);
}
}
class Guild {
String name;
String id;
String icon;
String afkChannelID;
String region;
String embedChannelID;
int afkTimeout;
int memberCount;
int verificationLevel;
int notificationLevel;
int mfaLevel;
bool large;
bool embedEnabled;
User ownerID;
Map<String, Member> members = {};
Guild(Map data, bool guildCreate) {
this.name = data['name'];
this.id = data['id'];
this.icon = data['icon'];
this.afkChannelID = data['afk_channel_id'];
this.region = data['region'];
this.embedChannelID = data['embed_channel_id'];
this.afkTimeout = data['afk_timeout'];
this.memberCount = data['member_count'];
this.verificationLevel = data['verification_level'];
this.notificationLevel = data['default_message_notifications'];
this.mfaLevel = data['default_message_notifications'];
this.embedEnabled = data['embed_enabled'];
this.ownerID = data['owner_id'];
if (guildCreate) {
this.large = data['large'];
//this.roles = JSON.decode(data['roles']);
data['members'].forEach((i) {
//print(data['members'][i]);
Member member = new Member(data['members'][0]);
print(member);
this.members[member.user.id] = member;
});
}
}
}
class Channel {
String name;
String id;
String topic;
String type;
String lastMessageID;
String guildID;
int position;
int bitrate;
int userLimit;
bool isPrivate;
Channel(Map data) {
this.name = data['name'];
this.id = data['id'];
this.type = data['type'];
this.guildID = data['guild_id'];
this.position = data['position'];
this.isPrivate = data['is_private'];
if (this.type == "text") {
this.topic = data['topic'];
this.lastMessageID = data['last_message_id'];
} else {
this.bitrate = data['bitrate'];
this.userLimit = data['user_limit'];
}
}
}
class Message {
String content;
String id;
String nonce;
String timestamp;
String editedTimestamp;
String channel;
User author;
List<User> mentions = [];
List<String> roleMentions = [];
List<Embed> embeds = [];
List<Attachment> attachments = [];
bool pinned;
bool tts;
bool mentionEveryone;
Message(Map data) {
this.content = data['content'];
this.id = data['id'];
this.nonce = data['nonce'];
this.timestamp = data['timestamp'];
this.editedTimestamp = data['edited_timestamp'];
this.author = new User(data['author']);
this.channel = data['channel_id'];
this.pinned = data['pinned'];
this.tts = data['tts'];
this.mentionEveryone = data['mention_everyone'];
this.roleMentions = data['mention_roles'];
data['mentions'].forEach((user) {
this.mentions.add(new User(user));
});
data['embeds'].forEach((embed) {
this.embeds.add(new Embed(embed));
});
data['attachments'].forEach((attachment) {
this.attachments.add(new Attachment(attachment));
});
}
}
class Attachment {
String id;
String filename;
String url;
String proxyUrl;
int size;
int height;
int width;
Attachment(Map data) {
this.id = data['id'];
this.filename = data['filename'];
this.url = data['url'];
this.proxyUrl = data['proxyUrl'];
this.size = data['size'];
this.height = data['height'];
this.width = data['width'];
}
}
class EmbedThumbnail {
String url;
String proxyUrl;
int height;
int width;
EmbedThumbnail(Map data) {
this.url = data['url'];
this.proxyUrl = data['proxy_url'];
this.height = data['height'];
this.width = data['width'];
}
}
class EmbedProvider {
String name;
String url;
EmbedProvider(Map data) {
this.name = data['name'];
this.url = data['url'];
}
}
class Embed {
String url;
String type;
String description;
String title;
EmbedThumbnail thumbnail;
EmbedProvider provider;
Embed(Map data) {
this.url = data['url'];
this.type = data['type'];
this.description = data['description'];
if (data.containsKey('thumbnail')) {
this.thumbnail = new EmbedThumbnail(data['thumbnail']);
}
if (data.containsKey('provider')) {
this.provider = new EmbedProvider(data['provider']);
}
}
}
class InviteGuild {
String id;
String name;
String spash;
InviteGuild(Map data) {
this.id = data['id'];
this.name = data['name'];
this.spash = data['splash_hash'];
}
}
class InviteChannel {
String id;
String name;
String type;
InviteChannel(Map data) {
this.id = data['id'];
this.name = data['name'];
this.type = data['type'];
}
}
class Invite {
String code;
InviteGuild guild;
InviteChannel channel;
Invite(Map data) {
this.code = data['code'];
this.guild = new InviteGuild(data['guild']);
this.channel = new InviteChannel(data['channel']);
}
}
export 'objects/Attachment.dart';
export 'objects/Channel.dart';
export 'objects/ClientOptions.dart';
export 'objects/ClientUser.dart';
export 'objects/Embed.dart';
export 'objects/EmbedProvider.dart';
export 'objects/EmbedThumbnail.dart';
export 'objects/Guild.dart';
export 'objects/Invite.dart';
export 'objects/InviteChannel.dart';
export 'objects/InviteGuild.dart';
export 'objects/Member.dart';
export 'objects/Message.dart';
export 'objects/User.dart';

View file

@ -0,0 +1,39 @@
import '../objects.dart';
/// A message attachment.
class Attachment {
/// The attachment's ID
String id;
/// The attachment's filename.
String filename;
/// The attachment's URL.
String url;
/// The attachment's proxy URL.
String proxyUrl;
/// The attachment's file size.
int size;
/// The attachment's height, if an image.
int height;
/// The attachment's width, if an image,
int width;
/// A timestamp for when the message was created.
double createdAt;
Attachment(Map data) {
this.id = data['id'];
this.filename = data['filename'];
this.url = data['url'];
this.proxyUrl = data['proxyUrl'];
this.size = data['size'];
this.height = data['height'];
this.width = data['width'];
this.createdAt = (int.parse(this.id) / 4194304) + 1420070400000;
}
}

View file

@ -0,0 +1,56 @@
import '../objects.dart';
/// A channel.
class Channel {
/// The channel's name.
String name;
/// The channel's ID.
String id;
/// The channel's topic, only available if the channel is a text channel.
String topic;
/// The channel's type, either `text` or `voice`.
String type;
/// The ID for the last message in the channel.
String lastMessageID;
/// The ID for the guild that the channel is in, only available if the channel
/// is not private.
String guildID;
/// The channel's position in the channel list.
int position;
/// The channel's bitrate, only available if the channel is a voice channel.
int bitrate;
/// The channel's user limit, only available if the channel is a voice channel.
int userLimit;
/// A timestamp for when the channel was created.
double createdAt;
/// Whether or not the channel is a DM.
bool isPrivate;
Channel(Map data) {
this.name = data['name'];
this.id = data['id'];
this.type = data['type'];
this.guildID = data['guild_id'];
this.position = data['position'];
this.isPrivate = data['is_private'];
this.createdAt = (int.parse(this.id) / 4194304) + 1420070400000;
if (this.type == "text") {
this.topic = data['topic'];
this.lastMessageID = data['last_message_id'];
} else {
this.bitrate = data['bitrate'];
this.userLimit = data['user_limit'];
}
}
}

View file

@ -0,0 +1,7 @@
import '../objects.dart';
/// The options for [Client]
class ClientOptions {
/// Whether or not to disable @everyone and @here mentions at a global level.
bool disableEveryone = false;
}

View file

@ -0,0 +1,50 @@
import '../objects.dart';
/// The client user.
class ClientUser {
/// The client user's username.
String username;
/// The client user's ID.
String id;
/// The client user's discriminator.
String discriminator;
/// The client user's avatar hash.
String avatar;
/// The client user's email, null if the client user is a bot.
String email;
/// The string for mentioning the client user.
String mention;
/// A timestamp for when the client user was created.
double createdAt;
/// Weather or not the client user is a bot.
bool bot = false;
/// Weather or not the client user's account is verified.
bool verified;
/// Weather or not the client user has MFA enabled.
bool mfa;
ClientUser(Map data) {
this.username = data['username'];
this.id = data['id'];
this.discriminator = data['discriminator'];
this.avatar = data['avatar'];
this.email = data['email'];
this.mention = "<@${this.id}>";
this.createdAt = (int.parse(this.id) / 4194304) + 1420070400000;
this.verified = data['verified'];
this.mfa = data['mfa_enabled'];
if (data['bot']) {
this.bot = data['bot'];
}
}
}

View file

@ -0,0 +1,35 @@
import '../objects.dart';
/// A message embed.
class Embed {
/// The embed's URL
String url;
/// The embed's type
String type;
/// The embed's description.
String description;
/// The embed's title.
String title;
/// The embed's thumbnail, if any.
EmbedThumbnail thumbnail;
/// The embed's provider, if any.
EmbedProvider provider;
Embed(Map data) {
this.url = data['url'];
this.type = data['type'];
this.description = data['description'];
if (data.containsKey('thumbnail')) {
this.thumbnail = new EmbedThumbnail(data['thumbnail']);
}
if (data.containsKey('provider')) {
this.provider = new EmbedProvider(data['provider']);
}
}
}

View file

@ -0,0 +1,15 @@
import '../objects.dart';
/// A message embed provider.
class EmbedProvider {
/// The embed provider's name.
String name;
/// The embed provider's URL.
String url;
EmbedProvider(Map data) {
this.name = data['name'];
this.url = data['url'];
}
}

View file

@ -0,0 +1,23 @@
import '../objects.dart';
/// A message embed thumbnail.
class EmbedThumbnail {
/// The embed thumbnail's URL.
String url;
/// The embed thumbnal's proxy URL.
String proxyUrl;
/// The embed thumbnal's height.
int height;
/// The embed thumbnal's width.
int width;
EmbedThumbnail(Map data) {
this.url = data['url'];
this.proxyUrl = data['proxy_url'];
this.height = data['height'];
this.width = data['width'];
}
}

View file

@ -0,0 +1,82 @@
import '../objects.dart';
/// A guild.
class Guild {
/// The guild's name.
String name;
/// The guild's ID.
String id;
/// The guild's icon hash.
String icon;
/// The guild's afk channel ID, null if not set.
String afkChannelID;
/// The guild's voice region.
String region;
/// The channel ID for the guild's widget if enabled.
String embedChannelID;
/// The guild's AFK timeout.
int afkTimeout;
/// The guild's member count.
int memberCount;
/// The guild's verification level.
int verificationLevel;
/// The guild's notification level.
int notificationLevel;
/// The guild's MFA level.
int mfaLevel;
/// A timestamp for when the guild was created.
double createdAt;
/// Whether or not the guild has over 100 members, it is only available in
/// `guildCreate` events, not via `Client.getGuild()`.
bool large;
/// If the guild's widget is enabled.
bool embedEnabled;
/// The guild owner's ID
User ownerID;
/// The guild's members, it is only available in
/// `guildCreate` events, not via `Client.getGuild()`.
Map<String, Member> members = {};
Guild(Map data, bool guildCreate) {
this.name = data['name'];
this.id = data['id'];
this.icon = data['icon'];
this.afkChannelID = data['afk_channel_id'];
this.region = data['region'];
this.embedChannelID = data['embed_channel_id'];
this.afkTimeout = data['afk_timeout'];
this.memberCount = data['member_count'];
this.verificationLevel = data['verification_level'];
this.notificationLevel = data['default_message_notifications'];
this.mfaLevel = data['default_message_notifications'];
this.embedEnabled = data['embed_enabled'];
this.ownerID = data['owner_id'];
this.createdAt = (int.parse(this.id) / 4194304) + 1420070400000;
if (guildCreate) {
this.large = data['large'];
//this.roles = JSON.decode(data['roles']);
data['members'].forEach((i) {
//print(data['members'][i]);
Member member = new Member(data['members'][0]);
print(member);
this.members[member.user.id] = member;
});
}
}
}

View file

@ -0,0 +1,19 @@
import '../objects.dart';
/// An invite.
class Invite {
/// The invite's code.
String code;
/// A mini guild object for the invite's guild.
InviteGuild guild;
/// A mini channel object for the invite's channel.
InviteChannel channel;
Invite(Map data) {
this.code = data['code'];
this.guild = new InviteGuild(data['guild']);
this.channel = new InviteChannel(data['channel']);
}
}

View file

@ -0,0 +1,23 @@
import '../objects.dart';
/// A mini channel object for invites.
class InviteChannel {
/// The channel's ID.
String id;
/// The channel's name.
String name;
/// The channel's type.
String type;
/// A timestamp for the channel was created.
double createdAt;
InviteChannel(Map data) {
this.id = data['id'];
this.name = data['name'];
this.type = data['type'];
this.createdAt = (int.parse(this.id) / 4194304) + 1420070400000;
}
}

View file

@ -0,0 +1,23 @@
import '../objects.dart';
/// A mini guild object for invites.
class InviteGuild {
/// The guild's ID.
String id;
/// The guild's name.
String name;
/// The guild's spash if any.
String spash;
/// A timestamp for when the guild was created.
double createdAt;
InviteGuild(Map data) {
this.id = data['id'];
this.name = data['name'];
this.spash = data['splash_hash'];
this.createdAt = (int.parse(this.id) / 4194304) + 1420070400000;
}
}

View file

@ -0,0 +1,31 @@
import '../objects.dart';
/// A guild member.
class Member {
/// The member's nickname, null if not set.
String nickname;
/// When the member joined the guild.
String joinedAt;
/// Weather or not the member is deafened.
bool deaf;
/// Weather or not the member is muted.
bool mute;
/// A list of role IDs the member has.
List<String> roles;
/// The [User] object for the member.
User user;
Member(Map data) {
this.nickname = data['nick'];
this.joinedAt = data['joined_at'];
this.deaf = data['deaf'];
this.mute = data['mute'];
this.roles = data['roles'];
this.user = new User(data['user']);
}
}

View file

@ -0,0 +1,76 @@
import '../objects.dart';
/// A message.
class Message {
/// The message's content.
String content;
/// The message's ID.
String id;
/// The message's nonce, null if not set.
String nonce;
/// The timestamp of when the message was created.
String timestamp;
/// The timestamp of when the message was last edited, null if not edited.
String editedTimestamp;
/// The ID for the message's channel.
String channel;
/// The message's author.
User author;
/// A list of the mentions in the message.
List<User> mentions = [];
/// A list of IDs for the role mentions in the message.
List<String> roleMentions = [];
/// A list of the embeds in the message.
List<Embed> embeds = [];
/// A list of attachments in the message.
List<Attachment> attachments = [];
/// When the message was created, redundant of `timestamp`.
double createdAt;
/// Whether or not the message is pinned.
bool pinned;
/// Whether or not the message was sent with TTS enabled.
bool tts;
/// Whether or @everyone was mentioned in the message.
bool mentionEveryone;
Message(Map data) {
this.content = data['content'];
this.id = data['id'];
this.nonce = data['nonce'];
this.timestamp = data['timestamp'];
this.editedTimestamp = data['edited_timestamp'];
this.author = new User(data['author']);
this.channel = data['channel_id'];
this.pinned = data['pinned'];
this.tts = data['tts'];
this.mentionEveryone = data['mention_everyone'];
this.roleMentions = data['mention_roles'];
this.createdAt = (int.parse(this.id) / 4194304) + 1420070400000;
data['mentions'].forEach((user) {
this.mentions.add(new User(user));
});
data['embeds'].forEach((embed) {
this.embeds.add(new Embed(embed));
});
data['attachments'].forEach((attachment) {
this.attachments.add(new Attachment(attachment));
});
}
}

38
lib/src/objects/User.dart Normal file
View file

@ -0,0 +1,38 @@
import '../objects.dart';
/// A user.
class User {
/// The user's username.
String username;
/// The user's ID.
String id;
/// The user's discriminator.
String discriminator;
/// The user's avatar hash.
String avatar;
/// The string to mention the user.
String mention;
/// A timestamp of when the user was created.
double createdAt;
/// Whether or not the user is a bot.
bool bot = false;
User(Map data) {
this.username = data['username'];
this.id = data['id'];
this.discriminator = data['discriminator'];
this.avatar = data['avatar'];
this.mention = "<@${this.id}>";
this.createdAt = (int.parse(this.id) / 4194304) + 1420070400000;
if (data['bot']) {
this.bot = data['bot'];
}
}
}

View file

@ -1,5 +1,5 @@
name: discord_dart
version: 0.2.1
version: 0.3.0
description: A Discord library for Dart
author: Hackzzila <admin@hackzzila.com>
homepage: https://github.com/Hackzzila/Discord-Dart