Browse Source

Finished web socket implementation

pull/369/head
ObsidianMinor 8 years ago
parent
commit
44fa72c8bf
9 changed files with 108 additions and 42 deletions
  1. +6
    -9
      src/Discord.Net.Core/Entities/Users/RelationshipType.cs
  2. +0
    -11
      src/Discord.Net.Rest/API/Common/RelationshipType.cs
  3. +5
    -4
      src/Discord.Net.Rest/BaseDiscordClient.cs
  4. +2
    -2
      src/Discord.Net.Rest/DiscordRestApiClient.cs
  5. +21
    -0
      src/Discord.Net.WebSocket/ClientState.cs
  6. +14
    -0
      src/Discord.Net.WebSocket/DiscordSocketClient.Events.cs
  7. +39
    -1
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  8. +15
    -3
      src/Discord.Net.WebSocket/Entities/Users/SocketRelationship.cs
  9. +6
    -12
      src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs

+ 6
- 9
src/Discord.Net.Core/Entities/Users/RelationshipType.cs View File

@@ -1,14 +1,11 @@
using System;
using System.Collections.Generic;
using System.Text;

namespace Discord
namespace Discord
{
public enum RelationshipType
{
Friend = 1,
Blocked = 2,
IncomingPending = 3,
OutgoingPending = 4
None,
Friend,
Blocked,
IncomingPending,
OutgoingPending
}
}

+ 0
- 11
src/Discord.Net.Rest/API/Common/RelationshipType.cs View File

@@ -1,11 +0,0 @@
#pragma warning disable CS1591
namespace Discord.API
{
internal enum RelationshipType
{
Friend = 1,
Blocked = 2,
IncomingPending = 3,
OutgoingPending = 4
}
}

+ 5
- 4
src/Discord.Net.Rest/BaseDiscordClient.cs View File

@@ -121,13 +121,14 @@ namespace Discord.Rest
}
/// <inheritdoc />
public void Dispose() => Dispose(true);

public Task<IReadOnlyCollection<IRelationship>> GetRelationshipsAsync() => ApiClient.GetRelationshipsAsync();

//IDiscordClient
ConnectionState IDiscordClient.ConnectionState => ConnectionState.Disconnected;
ISelfUser IDiscordClient.CurrentUser => CurrentUser;

Task<IReadOnlyCollection<IRelationship>> IDiscordClient.GetRelationshipsAsync()
=> Task.FromResult<IReadOnlyCollection<IRelationship>>(null);
Task<IApplication> IDiscordClient.GetApplicationInfoAsync() { throw new NotSupportedException(); }

Task<IChannel> IDiscordClient.GetChannelAsync(ulong id, CacheMode mode)


+ 2
- 2
src/Discord.Net.Rest/DiscordRestApiClient.cs View File

@@ -1030,10 +1030,10 @@ namespace Discord.API
}
//Relationships
public async Task<IReadOnlyCollection<IRelationship>> GetRelationshipsAsync(RequestOptions options = null)
public async Task<IReadOnlyCollection<Relationship>> GetRelationshipsAsync(RequestOptions options = null)
{
options = RequestOptions.CreateOrClone(options);
return await SendAsync<IReadOnlyCollection<IRelationship>>("GET", () => "users/@me/relationships", new BucketIds(), options: options).ConfigureAwait(false);
return await SendAsync<IReadOnlyCollection<Relationship>>("GET", () => "users/@me/relationships", new BucketIds(), options: options).ConfigureAwait(false);
}
public async Task AddFriendAsync(ulong userId, RequestOptions options = null)
{


+ 21
- 0
src/Discord.Net.WebSocket/ClientState.cs View File

@@ -10,11 +10,13 @@ namespace Discord.WebSocket
private const double AverageChannelsPerGuild = 10.22; //Source: Googie2149
private const double AverageUsersPerGuild = 47.78; //Source: Googie2149
private const double CollectionMultiplier = 1.05; //Add 5% buffer to handle growth
private const double AverageRelationshipsPerUser = 30;

private readonly ConcurrentDictionary<ulong, SocketChannel> _channels;
private readonly ConcurrentDictionary<ulong, SocketDMChannel> _dmChannels;
private readonly ConcurrentDictionary<ulong, SocketGuild> _guilds;
private readonly ConcurrentDictionary<ulong, SocketGlobalUser> _users;
private readonly ConcurrentDictionary<ulong, SocketRelationship> _relations;
private readonly ConcurrentHashSet<ulong> _groupChannels;

internal IReadOnlyCollection<SocketChannel> Channels => _channels.ToReadOnlyCollection();
@@ -22,6 +24,7 @@ namespace Discord.WebSocket
internal IReadOnlyCollection<SocketGroupChannel> GroupChannels => _groupChannels.Select(x => GetChannel(x) as SocketGroupChannel).ToReadOnlyCollection(_groupChannels);
internal IReadOnlyCollection<SocketGuild> Guilds => _guilds.ToReadOnlyCollection();
internal IReadOnlyCollection<SocketGlobalUser> Users => _users.ToReadOnlyCollection();
internal IReadOnlyCollection<SocketRelationship> Relationships => _relations.ToReadOnlyCollection();

internal IReadOnlyCollection<ISocketPrivateChannel> PrivateChannels =>
_dmChannels.Select(x => x.Value as ISocketPrivateChannel).Concat(
@@ -36,6 +39,7 @@ namespace Discord.WebSocket
_dmChannels = new ConcurrentDictionary<ulong, SocketDMChannel>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(dmChannelCount * CollectionMultiplier));
_guilds = new ConcurrentDictionary<ulong, SocketGuild>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(guildCount * CollectionMultiplier));
_users = new ConcurrentDictionary<ulong, SocketGlobalUser>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(estimatedUsersCount * CollectionMultiplier));
_relations = new ConcurrentDictionary<ulong, SocketRelationship>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)AverageRelationshipsPerUser);
_groupChannels = new ConcurrentHashSet<ulong>(ConcurrentHashSet.DefaultConcurrencyLevel, (int)(10 * CollectionMultiplier));
}

@@ -126,5 +130,22 @@ namespace Discord.WebSocket
return user;
return null;
}

internal SocketRelationship GetRelationship(ulong id)
{
if (_relations.TryGetValue(id, out SocketRelationship value))
return value;
return null;
}
internal void AddRelationship(SocketRelationship relation)
{
_relations[relation.User.Id] = relation;
}
internal SocketRelationship RemoveRelationship(ulong id)
{
if (_relations.TryRemove(id, out SocketRelationship value))
return value;
return null;
}
}
}

+ 14
- 0
src/Discord.Net.WebSocket/DiscordSocketClient.Events.cs View File

@@ -221,5 +221,19 @@ namespace Discord.WebSocket
remove { _recipientRemovedEvent.Remove(value); }
}
private readonly AsyncEvent<Func<SocketGroupUser, Task>> _recipientRemovedEvent = new AsyncEvent<Func<SocketGroupUser, Task>>();
// relationships
public event Func<SocketRelationship, SocketRelationship, Task> RelationshipAdd
{
add { _relationshipAddedEvent.Add(value); }
remove { _relationshipAddedEvent.Remove(value); }
}
private readonly AsyncEvent<Func<SocketRelationship, SocketRelationship, Task>> _relationshipAddedEvent = new AsyncEvent<Func<SocketRelationship, SocketRelationship, Task>>();
public event Func<SocketRelationship, Task> RelationshipRemoved
{
add { _relationshipRemovedEvent.Add(value); }
remove { _relationshipRemovedEvent.Remove(value); }
}
private readonly AsyncEvent<Func<SocketRelationship, Task>> _relationshipRemovedEvent = new AsyncEvent<Func<SocketRelationship, Task>>();
}
}

+ 39
- 1
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -70,6 +70,7 @@ namespace Discord.WebSocket
public IReadOnlyCollection<SocketGroupChannel> GroupChannels
=> State.PrivateChannels.Select(x => x as SocketGroupChannel).Where(x => x != null).ToImmutableArray();
public IReadOnlyCollection<RestVoiceRegion> VoiceRegions => _voiceRegions.ToReadOnlyCollection();
public IReadOnlyCollection<SocketRelationship> Relationships => State.Relationships;

/// <summary> Creates a new REST/WebSocket discord client. </summary>
public DiscordSocketClient() : this(new DiscordSocketConfig()) { }
@@ -270,7 +271,7 @@ namespace Discord.WebSocket
/// <inheritdoc />
public Task<RestInvite> GetInviteAsync(string inviteId)
=> ClientHelper.GetInviteAsync(this, inviteId);
/// <inheritdoc />
public SocketUser GetUser(ulong id)
{
@@ -484,6 +485,8 @@ namespace Discord.WebSocket
}
for (int i = 0; i < data.PrivateChannels.Length; i++)
AddPrivateChannel(data.PrivateChannels[i], state);
for (int i = 0; i < data.Relationships.Length; i++)
AddRelationship(data.Relationships[i], state);

_sessionId = data.SessionId;
_unavailableGuilds = unavailableGuilds;
@@ -1499,6 +1502,29 @@ namespace Discord.WebSocket
}
}
return;
//Relationships
case "RELATIONSHIP_ADD":
{
await _gatewayLogger.DebugAsync("Received Dispatch (RELATIONSHIP_ADD)").ConfigureAwait(false);

var addedModel = (payload as JToken).ToObject<Relationship>(_serializer);
var before = State.GetRelationship(addedModel.Id);
var after = AddRelationship(addedModel, State);

await _relationshipAddedEvent.InvokeAsync(before, after);
return;
}
case "RELATIONSHIP_REMOVE":
{
await _gatewayLogger.DebugAsync("Received Dispatch (RELATIONSHIP_REMOVE)").ConfigureAwait(false);

var removedModel = (payload as JToken).ToObject<Relationship>(_serializer);
var removed = RemoveRelationship(removedModel.Id);

await _relationshipRemovedEvent.InvokeAsync(removed);
return;
}

//Ignored (User only)
case "CHANNEL_PINS_ACK":
@@ -1650,6 +1676,18 @@ namespace Discord.WebSocket
return channel;
}

internal SocketRelationship AddRelationship(Relationship model, ClientState state)
{
var relation = SocketRelationship.Create(this, state, model);
State.AddRelationship(relation);
return relation;
}
internal SocketRelationship RemoveRelationship(ulong id)
{
var relation = State.RemoveRelationship(id);
return relation;
}

//IDiscordClient
ConnectionState IDiscordClient.ConnectionState => _connection.State;



+ 15
- 3
src/Discord.Net.WebSocket/Entities/Users/SocketRelationship.cs View File

@@ -1,11 +1,23 @@
using System;
using Model = Discord.API.Relationship;

namespace Discord.WebSocket
{
public class SocketRelationship : IRelationship
{
public RelationshipType Type { get; private set; }
public RelationshipType Type { get; internal set; }

public IUser User { get; private set; }
public IUser User { get; internal set; }

public SocketRelationship(RelationshipType type, IUser user)
{
Type = type;
User = user;
}

internal static SocketRelationship Create(DiscordSocketClient discord, ClientState state, Model model)
{
SocketSimpleUser user = SocketSimpleUser.Create(discord, state, model.User);
return new SocketRelationship(model.Type, user);
}
}
}

+ 6
- 12
src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs View File

@@ -56,19 +56,13 @@ namespace Discord.WebSocket
async Task<IDMChannel> IUser.CreateDMChannelAsync(RequestOptions options)
=> await CreateDMChannelAsync(options).ConfigureAwait(false);

public Task AddFriendAsync(RequestOptions options = null)
{
throw new NotImplementedException();
}
public async Task AddFriendAsync(RequestOptions options = null)
=> await Discord.ApiClient.AddFriendAsync(Id, options);

public Task BlockUserAsync(RequestOptions options = null)
{
throw new NotImplementedException();
}
public async Task BlockUserAsync(RequestOptions options = null)
=> await Discord.ApiClient.BlockUserAsync(Id, options);

public Task RemoveRelationshipAsync(RequestOptions options = null)
{
throw new NotImplementedException();
}
public async Task RemoveRelationshipAsync(RequestOptions options = null)
=> await Discord.ApiClient.RemoveRelationshipAsync(Id, options);
}
}

Loading…
Cancel
Save