Skip to content
This repository has been archived by the owner on Oct 23, 2020. It is now read-only.

Commit

Permalink
Update library to support latest DMD changes, rip out voice
Browse files Browse the repository at this point in the history
  • Loading branch information
b1naryth1ef committed May 6, 2019
1 parent 4e0e7d3 commit 2fa0c80
Show file tree
Hide file tree
Showing 20 changed files with 139 additions and 1,074 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,25 @@

[![](https://travis-ci.org/b1naryth1ef/dscord.svg?branch=master)](https://travis-ci.org/b1naryth1ef/dscord)

dscord is a client library for the Discord chat service, written in D-lang. The core focus of dscord is to provide a clean interface with a highly performant and scalable backing runtime, to support use-cases that contain a large number of user or guilds. Dscord provides both a base client implementation, and various extras that assist in constructing bots out of it. Dscord is still very much a work-in-progress, so beware of sharp edges or missing pieces.

dscord is a client libray for interacting with [Discord](https://discordapp.com). Currently dscord supports the majority footprint of the Discord API with some newer features and changes lacking.

## Development

For the moment dscord is in "maintence mode" which means no new features are being worked on but reported bugs will be investigated and any pull requests will be reviewed.

## Examples

If you're looking for sample code, or example implementations, the following are good places to start:

- [this repo's examples](https://github.com/b1naryth1ef/dscord/tree/master/examples)
- [jeff](https://github.com/b1naryth1ef/jeff), a friendly neighborhood Discord bot fully implemented in dscord.


## Compiling/Installing

Dscord is available on [dub](https://code.dlang.org/packages/dscord), and can be easily dropped into new or existing projects.

## Documentation
Documentation is available [here](http://b1naryth1ef.github.io/dscord/).

Some documentation is available [here](http://b1naryth1ef.github.io/dscord/).
4 changes: 2 additions & 2 deletions dub.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
"targetType": "library",
"dependencies": {
"shaker": "~>0.0.8",
"vibe-d:core": "~>0.8.0-beta.3",
"vibe-d:http": "~>0.8.0-beta.3",
"vibe-d:core": "~>0.8.5",
"vibe-d:http": "~>0.8.5",
"dcad": "~>0.0.9"
},
"configurations": [
Expand Down
35 changes: 1 addition & 34 deletions examples/src/basic.d
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,18 @@ import std.stdio,

import vibe.core.core;
import vibe.http.client;
import dcad.types : DCAFile;


import dscord.core,
dscord.util.process,
dscord.util.emitter,
dscord.voice.youtubedl;
dscord.util.emitter;

import core.sys.posix.signal;
import etc.linux.memoryerror;

import dscord.util.string : camelCaseToUnderscores;

class BasicPlugin : Plugin {
DCAFile sound;

this() {
super();
}

@Listener!(MessageCreate, EmitterOrder.AFTER)
void onMessageCreate(MessageCreate event) {
this.log.infof("MessageCreate: %s", event.message.content);
Expand Down Expand Up @@ -88,31 +80,6 @@ class BasicPlugin : Plugin {

}

@Command("sound")
void onSound(CommandEvent event) {
auto chan = this.userVoiceChannel(event.msg.guild, event.msg.author);

if (!chan) {
event.msg.reply("You are not in a voice channel!");
return;
}

if (!this.sound) {
this.sound = new DCAFile(File("test.dca", "r"));
}

auto playable = new DCAPlayable(this.sound);

auto vc = chan.joinVoice();

if (vc.connect()) {
vc.play(playable).disconnect();
} else {
event.msg.reply("Failed :(");
}

}

@Command("whereami")
void onWhereAmI(CommandEvent event) {
auto chan = this.userVoiceChannel(event.msg.guild, event.msg.author);
Expand Down
Binary file removed examples/test.dca
Binary file not shown.
3 changes: 2 additions & 1 deletion src/dscord/api/ratelimit.d
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import std.conv,
core.sync.mutex;

import vibe.core.core;
import vibe.core.sync : LocalManualEvent, createManualEvent;

import dscord.api.routes,
dscord.util.time;
Expand Down Expand Up @@ -50,7 +51,7 @@ struct RateLimitState {
RateLimiter provides an interface for rate limiting HTTP Requests.
*/
class RateLimiter {
ManualEvent[Bucket] cooldowns;
LocalManualEvent[Bucket] cooldowns;
RateLimitState[Bucket] states;

/// Cooldown a bucket for a given duration. Blocks ALL requests from completing.
Expand Down
6 changes: 1 addition & 5 deletions src/dscord/client.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import std.algorithm.iteration;
import dscord.api,
dscord.types,
dscord.state,
dscord.voice,
dscord.gateway,
dscord.util.emitter;

Expand Down Expand Up @@ -48,9 +47,6 @@ class Client {
/** State instance */
State state;

/** Mapping of voice connections */
VoiceClient[Snowflake] voiceConns;

/** Emitter for gateway events */
Emitter events;

Expand Down Expand Up @@ -98,7 +94,7 @@ class Client {
foreach(message; messages){
msgIDs ~= message.id;
}

return deleteMessages(channelID, msgIDs);
}

Expand Down
1 change: 0 additions & 1 deletion src/dscord/core.d
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@ public import dscord.api;
public import dscord.bot;
public import dscord.gateway;
public import dscord.types;
public import dscord.voice;
public import dscord.util.storage;
2 changes: 2 additions & 0 deletions src/dscord/gateway/events.d
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ class GuildDelete {
class GuildBanAdd {
mixin Event;

Snowflake guildID;
User user;
}

Expand All @@ -175,6 +176,7 @@ class GuildBanAdd {
class GuildBanRemove {
mixin Event;

Snowflake guildID;
User user;
}

Expand Down
4 changes: 2 additions & 2 deletions src/dscord/state.d
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import std.functional,
std.algorithm.iteration,
std.experimental.logger;

import vibe.core.sync : createManualEvent, ManualEvent;
import vibe.core.sync : createManualEvent, LocalManualEvent;
import std.algorithm.searching : canFind, countUntil;
import std.algorithm.mutation : remove;

Expand Down Expand Up @@ -47,7 +47,7 @@ class State : Emitter {
VoiceStateMap voiceStates;

/// Event triggered when all guilds are synced
ManualEvent ready;
LocalManualEvent ready;

bool requestOfflineMembers = true;

Expand Down
8 changes: 4 additions & 4 deletions src/dscord/types/base.d
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import std.conv,
import dscord.client;

import vibe.core.core : runTask, sleep;
import vibe.core.sync;
import vibe.core.sync : createManualEvent, LocalManualEvent;

// Commonly used public imports
public import dscord.util.json;
Expand All @@ -39,7 +39,7 @@ class AsyncChainer(T) {
private {
T obj;
AsyncChainer!T parent;
ManualEvent resolveEvent;
LocalManualEvent resolveEvent;
bool ignoreFailure;
}

Expand Down Expand Up @@ -144,7 +144,7 @@ class IModel {
@JSONIgnore
Client client;

void init() {};
void initialize() {};
// void load(JSONDecoder obj) {};

this() {}
Expand Down Expand Up @@ -181,7 +181,7 @@ mixin template Model() {

this.client = client;
this.deserializeFromJSON(obj);
this.init();
this.initialize();

version (TIMING) {
this.client.log.tracef("Finished creation of model %s in %sms", this.toString,
Expand Down
13 changes: 1 addition & 12 deletions src/dscord/types/channel.d
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import std.stdio,
core.vararg;

import dscord.types,
dscord.voice,
dscord.client;

alias ChannelMap = ModelMap!(Snowflake, Channel);
Expand Down Expand Up @@ -64,16 +63,11 @@ class Channel : IModel, IPermissible {
@JSONSource("permission_overwrites")
PermissionOverwriteMap overwrites;

// Voice Connection
// TODO: move?
@JSONIgnore
VoiceClient vc;

@property Guild guild() {
return this.client.state.guilds.get(this.guildID);
}

override void init() {
override void initialize() {
this.overwrites = new PermissionOverwriteMap;
}

Expand Down Expand Up @@ -134,11 +128,6 @@ class Channel : IModel, IPermissible {
return this.guild.voiceStates.filter(c => c.channelID == this.id);
}

VoiceClient joinVoice() {
this.vc = new VoiceClient(this);
return this.vc;
}

override Permission getPermissions(Snowflake user) {
GuildMember member = this.guild.getMember(user);
Permission perm = this.guild.getPermissions(user);
Expand Down
10 changes: 9 additions & 1 deletion src/dscord/types/guild.d
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ class Guild : IModel, IPermissible {
@JSONListToMap("id")
EmojiMap emojis;

override void init() {
override void initialize() {
// It's possible these are not created
if (!this.members) return;

Expand All @@ -154,6 +154,14 @@ class Guild : IModel, IPermissible {
return format("<Guild %s (%s)>", this.name, this.id);
}

/// Returns a URL to the guild icon
string getIconURL(string fmt = "webp", size_t size = 1024) {
if (this.icon == "") {
return "";
}
return format("https://cdn.discordapp.com/icons/%s/%s.%s?size=%s", this.id, this.icon, fmt, size);
}

/// Returns a GuildMember for a given user object
GuildMember getMember(User obj) {
return this.getMember(obj.id);
Expand Down
15 changes: 12 additions & 3 deletions src/dscord/types/message.d
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,22 @@ class Message : IModel {
Snowflake channelID;
User author;
string content;
string timestamp; // TODO: timestamps lol
string editedTimestamp; // TODO: timestamps lol
bool tts;
bool mentionEveryone;
string nonce;
bool pinned;

// Nonce is very unpredictable and user-provided, so we don't unpack it into
// a concrete type.
VibeJSON nonce;

@JSONTimestamp
SysTime timestamp;

@JSONTimestamp
SysTime editedTimestamp;

GuildMember member;

// TODO: GuildMemberMap here
@JSONListToMap("id")
UserMap mentions;
Expand Down
32 changes: 31 additions & 1 deletion src/dscord/types/user.d
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
module dscord.types.user;

import std.stdio,
std.format;
std.format,
std.algorithm.searching;

import std.conv : to;

import dscord.types,
dscord.client;
Expand All @@ -11,6 +14,8 @@ alias UserMap = ModelMap!(Snowflake, User);
enum GameType : ushort {
DEFAULT = 0,
STREAMING = 1,
LISTENING = 2,
WATCHING = 3,
}

enum UserStatus : string {
Expand All @@ -21,6 +26,13 @@ enum UserStatus : string {
OFFLINE = "offline",
}

enum DefaultAvatarColor {
BLURPLE = 0,
GREY = 1,
GREEN = 2,
ORANGE = 3,
RED = 4,
}

class Game {
string name;
Expand Down Expand Up @@ -69,4 +81,22 @@ class User : IModel {
override string toString() {
return format("<User %s#%s (%s)>", this.username, this.discriminator, this.id);
}

string getAvatarURL(string fmt = null, size_t size = 1024) {
if (!this.avatar) {
return format("https://cdn.discordapp.com/embed/avatars/%s.png", cast(int)this.defaultAvatarColor);
}

if (fmt is null) {
fmt = this.avatar.startsWith("a_") ? "gif" : "webp";
}

return format("https://cdn.discordapp.com/avatars/%s/%s.%s?size=%s", this.id, this.avatar, fmt, size);
}

@property DefaultAvatarColor defaultAvatarColor() {
auto discrimNumber = this.discriminator.to!int;

return cast(DefaultAvatarColor)(discrimNumber % DefaultAvatarColor.sizeof);
}
}
Loading

0 comments on commit 2fa0c80

Please sign in to comment.