Started converting websocket and rpc classes
This commit is contained in:
@@ -1,9 +0,0 @@
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
internal interface ISocketUser : IUser, IEntity<ulong>
|
||||
{
|
||||
SocketGlobalUser User { get; }
|
||||
|
||||
ISocketUser Clone();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +0,0 @@
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
//TODO: C#7 Candidate for record type
|
||||
internal struct Presence : IPresence
|
||||
{
|
||||
public Game Game { get; }
|
||||
public UserStatus Status { get; }
|
||||
|
||||
public Presence(Game game, UserStatus status)
|
||||
{
|
||||
Game = game;
|
||||
Status = status;
|
||||
}
|
||||
|
||||
public Presence Clone() => this;
|
||||
}
|
||||
}
|
||||
@@ -1,46 +0,0 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using PresenceModel = Discord.API.Presence;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
internal class SocketDMUser : ISocketUser
|
||||
{
|
||||
internal bool IsAttached => true;
|
||||
bool IEntity<ulong>.IsAttached => IsAttached;
|
||||
|
||||
public SocketGlobalUser User { get; }
|
||||
|
||||
public DiscordSocketClient Discord => User.Discord;
|
||||
|
||||
public Game Game => Presence.Game;
|
||||
public UserStatus Status => Presence.Status;
|
||||
public Presence Presence => User.Presence; //{ get; private set; }
|
||||
|
||||
public ulong Id => User.Id;
|
||||
public string AvatarUrl => User.AvatarUrl;
|
||||
public DateTimeOffset CreatedAt => User.CreatedAt;
|
||||
public string Discriminator => User.Discriminator;
|
||||
public ushort DiscriminatorValue => User.DiscriminatorValue;
|
||||
public bool IsBot => User.IsBot;
|
||||
public string Mention => MentionUtils.Mention(this);
|
||||
public string Username => User.Username;
|
||||
|
||||
public SocketDMUser(SocketGlobalUser user)
|
||||
{
|
||||
User = user;
|
||||
}
|
||||
|
||||
public void Update(PresenceModel model)
|
||||
{
|
||||
User.Update(model, source);
|
||||
}
|
||||
|
||||
public SocketDMUser Clone() => MemberwiseClone() as SocketDMUser;
|
||||
ISocketUser ISocketUser.Clone() => Clone();
|
||||
|
||||
public override string ToString() => $"{Username}#{Discriminator}";
|
||||
private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id})";
|
||||
}
|
||||
}
|
||||
@@ -1,61 +1,10 @@
|
||||
using Discord.Rest;
|
||||
using System;
|
||||
using Model = Discord.API.User;
|
||||
using PresenceModel = Discord.API.Presence;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
internal class SocketGlobalUser : User, ISocketUser
|
||||
internal class SocketGlobalUser : SocketUser
|
||||
{
|
||||
internal override bool IsAttached => true;
|
||||
private readonly object _lockObj = new object();
|
||||
|
||||
private ushort _references;
|
||||
|
||||
public Presence Presence { get; private set; }
|
||||
|
||||
public new DiscordSocketClient Discord { get { throw new NotSupportedException(); } }
|
||||
SocketGlobalUser ISocketUser.User => this;
|
||||
|
||||
public SocketGlobalUser(Model model)
|
||||
: base(model)
|
||||
internal SocketGlobalUser(DiscordSocketClient discord, ulong id)
|
||||
: base(discord, id)
|
||||
{
|
||||
}
|
||||
|
||||
public void AddRef()
|
||||
{
|
||||
checked
|
||||
{
|
||||
lock (_lockObj)
|
||||
_references++;
|
||||
}
|
||||
}
|
||||
public void RemoveRef(DiscordSocketClient discord)
|
||||
{
|
||||
lock (_lockObj)
|
||||
{
|
||||
if (--_references == 0)
|
||||
discord.RemoveUser(Id);
|
||||
}
|
||||
}
|
||||
|
||||
public override void Update(Model model)
|
||||
{
|
||||
lock (_lockObj)
|
||||
base.Update(model, source);
|
||||
}
|
||||
public void Update(PresenceModel model)
|
||||
{
|
||||
//Race conditions are okay here. Multiple shards racing already cant guarantee presence in order.
|
||||
|
||||
//lock (_lockObj)
|
||||
//{
|
||||
var game = model.Game != null ? new Game(model.Game) : null;
|
||||
Presence = new Presence(game, model.Status);
|
||||
//}
|
||||
}
|
||||
|
||||
public SocketGlobalUser Clone() => MemberwiseClone() as SocketGlobalUser;
|
||||
ISocketUser ISocketUser.Clone() => Clone();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,30 @@
|
||||
using Discord.Rest;
|
||||
using System.Diagnostics;
|
||||
using Model = Discord.API.User;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
internal class SocketGroupUser : GroupUser, ISocketUser
|
||||
public class SocketGroupUser : SocketUser, IGroupUser
|
||||
{
|
||||
internal override bool IsAttached => true;
|
||||
|
||||
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
|
||||
public new SocketGroupChannel Channel => base.Channel as SocketGroupChannel;
|
||||
public new SocketGlobalUser User => base.User as SocketGlobalUser;
|
||||
public Presence Presence => User.Presence; //{ get; private set; }
|
||||
|
||||
public override Game Game => Presence.Game;
|
||||
public override UserStatus Status => Presence.Status;
|
||||
|
||||
public VoiceState? VoiceState => Channel.GetVoiceState(Id);
|
||||
public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false;
|
||||
public bool IsSelfMuted => VoiceState?.IsSelfMuted ?? false;
|
||||
public bool IsSuppressed => VoiceState?.IsSuppressed ?? false;
|
||||
public SocketVoiceChannel VoiceChannel => VoiceState?.VoiceChannel;
|
||||
|
||||
public SocketGroupUser(SocketGroupChannel channel, SocketGlobalUser user)
|
||||
: base(channel, user)
|
||||
internal SocketGroupUser(DiscordSocketClient discord, ulong id)
|
||||
: base(discord, id)
|
||||
{
|
||||
}
|
||||
internal new static SocketGroupUser Create(DiscordSocketClient discord, Model model)
|
||||
{
|
||||
var entity = new SocketGroupUser(discord, model.Id);
|
||||
entity.Update(model);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public SocketGroupUser Clone() => MemberwiseClone() as SocketGroupUser;
|
||||
ISocketUser ISocketUser.Clone() => Clone();
|
||||
|
||||
public override string ToString() => $"{Username}#{Discriminator}";
|
||||
private string DebuggerDisplay => $"{Username}#{Discriminator} ({Id})";
|
||||
//IVoiceState
|
||||
bool IVoiceState.IsDeafened => false;
|
||||
bool IVoiceState.IsMuted => false;
|
||||
bool IVoiceState.IsSelfDeafened => false;
|
||||
bool IVoiceState.IsSelfMuted => false;
|
||||
bool IVoiceState.IsSuppressed => false;
|
||||
IVoiceChannel IVoiceState.VoiceChannel => null;
|
||||
string IVoiceState.VoiceSessionId => null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,53 +1,74 @@
|
||||
using Discord.Rest;
|
||||
using Discord.API.Rest;
|
||||
using Discord.Rest;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Immutable;
|
||||
using System.Threading.Tasks;
|
||||
using Model = Discord.API.GuildMember;
|
||||
using PresenceModel = Discord.API.Presence;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
internal class SocketGuildUser : GuildUser, ISocketUser, IVoiceState
|
||||
internal class SocketGuildUser : SocketUser, IGuildUser
|
||||
{
|
||||
internal override bool IsAttached => true;
|
||||
private long? _joinedAtTicks;
|
||||
private ImmutableArray<ulong> _roleIds;
|
||||
|
||||
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
|
||||
public new SocketGuild Guild => base.Guild as SocketGuild;
|
||||
public new SocketGlobalUser User => base.User as SocketGlobalUser;
|
||||
public Presence Presence => User.Presence; //{ get; private set; }
|
||||
public string Nickname { get; private set; }
|
||||
public ulong GuildId { get; private set; }
|
||||
|
||||
public override Game Game => Presence.Game;
|
||||
public override UserStatus Status => Presence.Status;
|
||||
public IReadOnlyCollection<ulong> RoleIds => _roleIds;
|
||||
|
||||
public VoiceState? VoiceState => Guild.GetVoiceState(Id);
|
||||
public bool IsSelfDeafened => VoiceState?.IsSelfDeafened ?? false;
|
||||
public bool IsSelfMuted => VoiceState?.IsSelfMuted ?? false;
|
||||
public bool IsSuppressed => VoiceState?.IsSuppressed ?? false;
|
||||
public SocketVoiceChannel VoiceChannel => VoiceState?.VoiceChannel;
|
||||
public bool IsDeafened => VoiceState?.IsDeafened ?? false;
|
||||
public bool IsMuted => VoiceState?.IsMuted ?? false;
|
||||
public string VoiceSessionId => VoiceState?.VoiceSessionId ?? "";
|
||||
public DateTimeOffset? JoinedAt => DateTimeUtils.FromTicks(_joinedAtTicks);
|
||||
|
||||
public SocketGuildUser(SocketGuild guild, SocketGlobalUser user, Model model)
|
||||
: base(guild, user, model)
|
||||
{
|
||||
//Presence = new Presence(null, UserStatus.Offline);
|
||||
}
|
||||
public SocketGuildUser(SocketGuild guild, SocketGlobalUser user, PresenceModel model)
|
||||
: base(guild, user, model)
|
||||
internal SocketGuildUser(DiscordSocketClient discord, ulong id)
|
||||
: base(discord, id)
|
||||
{
|
||||
}
|
||||
|
||||
public override void Update(PresenceModel model)
|
||||
internal static SocketGuildUser Create(DiscordSocketClient discord, Model model)
|
||||
{
|
||||
base.Update(model, source);
|
||||
|
||||
var game = model.Game != null ? new Game(model.Game) : null;
|
||||
//Presence = new Presence(game, model.Status);
|
||||
|
||||
User.Update(model, source);
|
||||
var entity = new SocketGuildUser(discord, model.User.Id);
|
||||
entity.Update(model);
|
||||
return entity;
|
||||
}
|
||||
internal void Update(Model model)
|
||||
{
|
||||
_joinedAtTicks = model.JoinedAt.UtcTicks;
|
||||
if (model.Nick.IsSpecified)
|
||||
Nickname = model.Nick.Value;
|
||||
UpdateRoles(model.Roles);
|
||||
}
|
||||
private void UpdateRoles(ulong[] roleIds)
|
||||
{
|
||||
var roles = ImmutableArray.CreateBuilder<ulong>(roleIds.Length + 1);
|
||||
roles.Add(GuildId);
|
||||
for (int i = 0; i < roleIds.Length; i++)
|
||||
roles.Add(roleIds[i]);
|
||||
_roleIds = roles.ToImmutable();
|
||||
}
|
||||
|
||||
IVoiceChannel IVoiceState.VoiceChannel => VoiceState?.VoiceChannel;
|
||||
public override async Task UpdateAsync()
|
||||
=> Update(await UserHelper.GetAsync(this, Discord));
|
||||
public Task ModifyAsync(Action<ModifyGuildMemberParams> func)
|
||||
=> UserHelper.ModifyAsync(this, Discord, func);
|
||||
public Task KickAsync()
|
||||
=> UserHelper.KickAsync(this, Discord);
|
||||
|
||||
public SocketGuildUser Clone() => MemberwiseClone() as SocketGuildUser;
|
||||
ISocketUser ISocketUser.Clone() => Clone();
|
||||
public ChannelPermissions GetPermissions(IGuildChannel channel)
|
||||
{
|
||||
throw new NotImplementedException(); //TODO: Impl
|
||||
}
|
||||
|
||||
//IGuildUser
|
||||
IReadOnlyCollection<ulong> IGuildUser.RoleIds => RoleIds;
|
||||
|
||||
//IVoiceState
|
||||
bool IVoiceState.IsDeafened => false;
|
||||
bool IVoiceState.IsMuted => false;
|
||||
bool IVoiceState.IsSelfDeafened => false;
|
||||
bool IVoiceState.IsSelfMuted => false;
|
||||
bool IVoiceState.IsSuppressed => false;
|
||||
IVoiceChannel IVoiceState.VoiceChannel => null;
|
||||
string IVoiceState.VoiceSessionId => null;
|
||||
}
|
||||
}
|
||||
|
||||
23
src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs
Normal file
23
src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs
Normal file
@@ -0,0 +1,23 @@
|
||||
using Model = Discord.API.Presence;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
//TODO: C#7 Candidate for record type
|
||||
internal struct SocketPresence : IPresence
|
||||
{
|
||||
public Game? Game { get; }
|
||||
public UserStatus Status { get; }
|
||||
|
||||
internal SocketPresence(Game? game, UserStatus status)
|
||||
{
|
||||
Game = game;
|
||||
Status = status;
|
||||
}
|
||||
internal SocketPresence Create(Model model)
|
||||
{
|
||||
return new SocketPresence(model.Game != null ? Discord.Game.Create(model.Game) : (Game?)null, model.Status);
|
||||
}
|
||||
|
||||
public SocketPresence Clone() => this;
|
||||
}
|
||||
}
|
||||
@@ -6,42 +6,39 @@ using Model = Discord.API.User;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
internal class SocketSelfUser : SelfUser, ISocketUser, ISelfUser
|
||||
public class SocketSelfUser : SocketUser, ISelfUser
|
||||
{
|
||||
internal override bool IsAttached => true;
|
||||
public string Email { get; private set; }
|
||||
public bool IsVerified { get; private set; }
|
||||
public bool IsMfaEnabled { get; private set; }
|
||||
|
||||
public new DiscordSocketClient Discord => base.Discord as DiscordSocketClient;
|
||||
SocketGlobalUser ISocketUser.User { get { throw new NotSupportedException(); } }
|
||||
|
||||
public SocketSelfUser(DiscordSocketClient discord, Model model)
|
||||
: base(discord, model)
|
||||
internal SocketSelfUser(DiscordSocketClient discord, ulong id)
|
||||
: base(discord, id)
|
||||
{
|
||||
}
|
||||
|
||||
public async Task ModifyStatusAsync(Action<ModifyPresenceParams> func)
|
||||
internal new static SocketSelfUser Create(DiscordSocketClient discord, Model model)
|
||||
{
|
||||
if (func == null) throw new NullReferenceException(nameof(func));
|
||||
var entity = new SocketSelfUser(discord, model.Id);
|
||||
entity.Update(model);
|
||||
return entity;
|
||||
}
|
||||
internal override void Update(Model model)
|
||||
{
|
||||
base.Update(model);
|
||||
|
||||
var args = new ModifyPresenceParams();
|
||||
func(args);
|
||||
|
||||
var game = args._game.GetValueOrDefault(_game);
|
||||
var status = args._status.GetValueOrDefault(_status);
|
||||
|
||||
long idleSince = _idleSince;
|
||||
if (status == UserStatus.Idle && _status != UserStatus.Idle)
|
||||
idleSince = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
|
||||
var apiGame = game != null ? new API.Game { Name = game.Name, StreamType = game.StreamType, StreamUrl = game.StreamUrl } : null;
|
||||
|
||||
await Discord.ApiClient.SendStatusUpdateAsync(status == UserStatus.Idle ? _idleSince : (long?)null, apiGame).ConfigureAwait(false);
|
||||
|
||||
//Save values
|
||||
_idleSince = idleSince;
|
||||
_game = game;
|
||||
_status = status;
|
||||
if (model.Email.IsSpecified)
|
||||
Email = model.Email.Value;
|
||||
if (model.Verified.IsSpecified)
|
||||
IsVerified = model.Verified.Value;
|
||||
if (model.MfaEnabled.IsSpecified)
|
||||
IsMfaEnabled = model.MfaEnabled.Value;
|
||||
}
|
||||
|
||||
public SocketSelfUser Clone() => MemberwiseClone() as SocketSelfUser;
|
||||
ISocketUser ISocketUser.Clone() => Clone();
|
||||
public override async Task UpdateAsync()
|
||||
=> Update(await UserHelper.GetAsync(this, Discord));
|
||||
public Task ModifyAsync(Action<ModifyCurrentUserParams> func)
|
||||
=> UserHelper.ModifyAsync(this, Discord, func);
|
||||
|
||||
Task ISelfUser.ModifyStatusAsync(Action<ModifyPresenceParams> func) { throw new NotSupportedException(); }
|
||||
}
|
||||
}
|
||||
|
||||
50
src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
Normal file
50
src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using Discord.Rest;
|
||||
using System.Threading.Tasks;
|
||||
using Model = Discord.API.User;
|
||||
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
public class SocketUser : SocketEntity<ulong>, IUser
|
||||
{
|
||||
public bool IsBot { get; private set; }
|
||||
public string Username { get; private set; }
|
||||
public ushort DiscriminatorValue { get; private set; }
|
||||
public string AvatarId { get; private set; }
|
||||
|
||||
public string AvatarUrl => API.CDN.GetUserAvatarUrl(Id, AvatarId);
|
||||
public string Discriminator => DiscriminatorValue.ToString("D4");
|
||||
public string Mention => MentionUtils.MentionUser(Id);
|
||||
public virtual Game? Game => null;
|
||||
public virtual UserStatus Status => UserStatus.Unknown;
|
||||
|
||||
internal SocketUser(DiscordSocketClient discord, ulong id)
|
||||
: base(discord, id)
|
||||
{
|
||||
}
|
||||
internal static SocketUser Create(DiscordSocketClient discord, Model model)
|
||||
{
|
||||
var entity = new SocketUser(discord, model.Id);
|
||||
entity.Update(model);
|
||||
return entity;
|
||||
}
|
||||
internal virtual void Update(Model model)
|
||||
{
|
||||
if (model.Avatar.IsSpecified)
|
||||
AvatarId = model.Avatar.Value;
|
||||
if (model.Discriminator.IsSpecified)
|
||||
DiscriminatorValue = ushort.Parse(model.Discriminator.Value);
|
||||
if (model.Bot.IsSpecified)
|
||||
IsBot = model.Bot.Value;
|
||||
if (model.Username.IsSpecified)
|
||||
Username = model.Username.Value;
|
||||
}
|
||||
|
||||
public virtual async Task UpdateAsync()
|
||||
=> Update(await UserHelper.GetAsync(this, Discord));
|
||||
|
||||
public Task<IDMChannel> CreateDMChannelAsync()
|
||||
=> UserHelper.CreateDMChannelAsync(this, Discord);
|
||||
|
||||
IDMChannel IUser.GetCachedDMChannel() => null;
|
||||
}
|
||||
}
|
||||
@@ -4,7 +4,7 @@ using Model = Discord.API.VoiceState;
|
||||
namespace Discord.WebSocket
|
||||
{
|
||||
//TODO: C#7 Candidate for record type
|
||||
internal struct VoiceState : IVoiceState
|
||||
public struct SocketVoiceState : IVoiceState
|
||||
{
|
||||
[Flags]
|
||||
private enum Flags : byte
|
||||
@@ -28,9 +28,7 @@ namespace Discord.WebSocket
|
||||
public bool IsSelfMuted => (_voiceStates & Flags.SelfMuted) != 0;
|
||||
public bool IsSelfDeafened => (_voiceStates & Flags.SelfDeafened) != 0;
|
||||
|
||||
public VoiceState(SocketVoiceChannel voiceChannel, Model model)
|
||||
: this(voiceChannel, model.SessionId, model.SelfMute, model.SelfDeaf, model.Suppress) { }
|
||||
public VoiceState(SocketVoiceChannel voiceChannel, string sessionId, bool isSelfMuted, bool isSelfDeafened, bool isSuppressed)
|
||||
internal SocketVoiceState(SocketVoiceChannel voiceChannel, string sessionId, bool isSelfMuted, bool isSelfDeafened, bool isSuppressed)
|
||||
{
|
||||
VoiceChannel = voiceChannel;
|
||||
VoiceSessionId = sessionId;
|
||||
@@ -44,8 +42,12 @@ namespace Discord.WebSocket
|
||||
voiceStates |= Flags.Suppressed;
|
||||
_voiceStates = voiceStates;
|
||||
}
|
||||
internal static SocketVoiceState Create(SocketVoiceChannel voiceChannel, Model model)
|
||||
{
|
||||
return new SocketVoiceState(voiceChannel, model.SessionId, model.SelfMute, model.SelfDeaf, model.Suppress);
|
||||
}
|
||||
|
||||
public VoiceState Clone() => this;
|
||||
public SocketVoiceState Clone() => this;
|
||||
|
||||
IVoiceChannel IVoiceState.VoiceChannel => VoiceChannel;
|
||||
}
|
||||
Reference in New Issue
Block a user