Browse Source

Integrated Activities with user entities

rebase hell from 5f3cb947a9
pull/877/head
Christopher F 7 years ago
parent
commit
349b8997b4
10 changed files with 82 additions and 88 deletions
  1. +1
    -1
      src/Discord.Net.Core/Entities/Activities/GameSecrets.cs
  2. +1
    -1
      src/Discord.Net.Core/Entities/Activities/GameTimestamps.cs
  3. +2
    -2
      src/Discord.Net.Core/Entities/Users/IPresence.cs
  4. +1
    -1
      src/Discord.Net.Rest/Entities/Users/RestUser.cs
  5. +1
    -1
      src/Discord.Net.Rpc/Entities/Users/RpcUser.cs
  6. +1
    -1
      src/Discord.Net.WebSocket/DiscordShardedClient.cs
  7. +19
    -57
      src/Discord.Net.WebSocket/DiscordSocketClient.cs
  8. +5
    -5
      src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs
  9. +1
    -1
      src/Discord.Net.WebSocket/Entities/Users/SocketUser.cs
  10. +50
    -18
      src/Discord.Net.WebSocket/Extensions/EntityExtensions.cs

+ 1
- 1
src/Discord.Net.Core/Entities/Activities/GameSecrets.cs View File

@@ -1,6 +1,6 @@
namespace Discord
{
public struct GameSecrets
public class GameSecrets
{
public string Match { get; }
public string Join { get; }


+ 1
- 1
src/Discord.Net.Core/Entities/Activities/GameTimestamps.cs View File

@@ -2,7 +2,7 @@

namespace Discord
{
public struct GameTimestamps
public class GameTimestamps
{
public DateTimeOffset Start { get; }
public DateTimeOffset End { get; }


+ 2
- 2
src/Discord.Net.Core/Entities/Users/IPresence.cs View File

@@ -2,8 +2,8 @@
{
public interface IPresence
{
/// <summary> Gets the game this user is currently playing, if any. </summary>
Game? Game { get; }
/// <summary> Gets the activity this user is currently doing. </summary>
IActivity Activity { get; }
/// <summary> Gets the current status of this user. </summary>
UserStatus Status { get; }
}

+ 1
- 1
src/Discord.Net.Rest/Entities/Users/RestUser.cs View File

@@ -16,7 +16,7 @@ namespace Discord.Rest
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
public string Discriminator => DiscriminatorValue.ToString("D4");
public string Mention => MentionUtils.MentionUser(Id);
public virtual Game? Game => null;
public virtual IActivity Activity => null;
public virtual UserStatus Status => UserStatus.Offline;
public virtual bool IsWebhook => false;



+ 1
- 1
src/Discord.Net.Rpc/Entities/Users/RpcUser.cs View File

@@ -18,7 +18,7 @@ namespace Discord.Rpc
public string Discriminator => DiscriminatorValue.ToString("D4");
public string Mention => MentionUtils.MentionUser(Id);
public virtual bool IsWebhook => false;
public virtual Game? Game => null;
public virtual IActivity Activity => null;
public virtual UserStatus Status => UserStatus.Offline;

internal RpcUser(DiscordRpcClient discord, ulong id)


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

@@ -22,7 +22,7 @@ namespace Discord.WebSocket
/// <summary> Gets the estimated round-trip latency, in milliseconds, to the gateway server. </summary>
public override int Latency { get => GetLatency(); protected set { } }
public override UserStatus Status { get => _shards[0].Status; protected set { } }
public override Game? Game { get => _shards[0].Game; protected set { } }
public IActivity Activity { get => _shards[0].Activity; protected set { } }

internal new DiscordSocketApiClient ApiClient => base.ApiClient as DiscordSocketApiClient;
public override IReadOnlyCollection<SocketGuild> Guilds => GetGuilds().ToReadOnlyCollection(() => GetGuildCount());


+ 19
- 57
src/Discord.Net.WebSocket/DiscordSocketClient.cs View File

@@ -48,7 +48,7 @@ namespace Discord.WebSocket
/// <inheritdoc />
public override int Latency { get; protected set; }
public override UserStatus Status { get; protected set; } = UserStatus.Online;
public override Game? Game { get; protected set; }
internal IActivity Activity { get; protected set; }

//From DiscordSocketConfig
internal int TotalShards { get; private set; }
@@ -328,77 +328,39 @@ namespace Discord.WebSocket
}
public override async Task SetGameAsync(string name, string streamUrl = null, StreamType streamType = StreamType.NotStreaming)
{
if (name != null)
Game = new Game(name, streamUrl, streamType);
if (name != null && streamUrl != null)
Activity = new StreamingGame(name, streamUrl, streamType);
else if (name != null)
Activity = new Game(name);
else
Game = null;
Activity = null;
await SendStatusAsync().ConfigureAwait(false);
}

public async Task SetGameAsync(Game game)
public async Task SetActivityAsync(IActivity activity)
{
Game = game;
Activity = activity;
await SendStatusAsync().ConfigureAwait(false);
}
private async Task SendStatusAsync()
{
if (CurrentUser == null)
return;
var game = Game;
var activity = Activity;
var status = Status;
var statusSince = _statusSince;
CurrentUser.Presence = new SocketPresence(status, game);
CurrentUser.Presence = new SocketPresence(status, activity);

GameModel gameModel;
if (game != null)
var gameModel = new GameModel();
// Discord only accepts rich presence over RPC, don't even bother building a payload
if (activity is RichGame game) throw new NotSupportedException("Outgoing Rich Presences are not supported");
if (activity is StreamingGame stream)
{
var assets = game.Value.Assets.HasValue
? new API.GameAssets()
{
SmallText = game.Value.Assets.Value.SmallText,
SmallImage = game.Value.Assets.Value.SmallImage,
LargeText = game.Value.Assets.Value.LargeText,
LargeImage = game.Value.Assets.Value.LargeImage,
}
: Optional.Create<API.GameAssets>();
var party = game.Value.Party.HasValue
? new API.GameParty
{
Id = game.Value.Party.Value.Id,
Size = game.Value.Party.Value.Size
}
: Optional.Create<API.GameParty>();
var secrets = game.Value.Secrets.HasValue
? new API.GameSecrets()
{
Join = game.Value.Secrets.Value.Join,
Match = game.Value.Secrets.Value.Match,
Spectate = game.Value.Secrets.Value.Spectate
}
: Optional.Create<API.GameSecrets>();
var timestamps = game.Value.Timestamps.HasValue
? new API.GameTimestamps
{
Start = game.Value.Timestamps.Value.Start,
End = game.Value.Timestamps.Value.End
}
: Optional.Create<API.GameTimestamps>();
gameModel = new API.Game
{
Name = game.Value.Name,
StreamType = game.Value.StreamType,
StreamUrl = game.Value.StreamUrl,
Details = game.Value.Details,
State = game.Value.State,
ApplicationId = game.Value.ApplicationId ?? Optional.Create<ulong>(),
Assets = assets,
Party = party,
Secrets = secrets,
Timestamps = timestamps,
};
gameModel.StreamUrl = stream.Url;
gameModel.StreamType = stream.StreamType;
}
else
gameModel = null;
else if (activity != null)
gameModel.Name = activity.Name;

await ApiClient.SendStatusUpdateAsync(
status,


+ 5
- 5
src/Discord.Net.WebSocket/Entities/Users/SocketPresence.cs View File

@@ -8,20 +8,20 @@ namespace Discord.WebSocket
public struct SocketPresence : IPresence
{
public UserStatus Status { get; }
public Game? Game { get; }
public IActivity Activity { get; }

internal SocketPresence(UserStatus status, Game? game)
internal SocketPresence(UserStatus status, IActivity activity)
{
Status = status;
Game = game;
Activity= activity;
}
internal static SocketPresence Create(Model model)
{
return new SocketPresence(model.Status, model.Game != null ? model.Game.ToEntity() : (Game?)null);
return new SocketPresence(model.Status, model.Game?.ToEntity());
}

public override string ToString() => Status.ToString();
private string DebuggerDisplay => $"{Status}{(Game != null ? $", {Game.Value.Name} ({Game.Value.StreamType})" : "")}";
private string DebuggerDisplay => $"{Status}{(Activity != null ? $", {Activity.Name}": "")}";

internal SocketPresence Clone() => this;
}


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

@@ -18,7 +18,7 @@ namespace Discord.WebSocket
public DateTimeOffset CreatedAt => SnowflakeUtils.FromSnowflake(Id);
public string Discriminator => DiscriminatorValue.ToString("D4");
public string Mention => MentionUtils.MentionUser(Id);
public Game? Game => Presence.Game;
public IActivity Activity => Presence.Activity;
public UserStatus Status => Presence.Status;

internal SocketUser(DiscordSocketClient discord, ulong id)


+ 50
- 18
src/Discord.Net.WebSocket/Extensions/EntityExtensions.cs View File

@@ -2,32 +2,64 @@
{
internal static class EntityExtensions
{
public static Game ToEntity(this API.Game model)
public static IActivity ToEntity(this API.Game model)
{
return new Game(model.Name,
model.StreamUrl.GetValueOrDefault(null),
model.StreamType.GetValueOrDefault(null) ?? StreamType.NotStreaming,
model.Details.GetValueOrDefault(),
model.State.GetValueOrDefault(),
model.ApplicationId.ToNullable(),
model.Assets.GetValueOrDefault(null)?.ToEntity(),
model.Party.GetValueOrDefault(null)?.ToEntity(),
model.Secrets.GetValueOrDefault(null)?.ToEntity(),
model.Timestamps.GetValueOrDefault(null)?.ToEntity()
);
// Rich Game
if (model.Details.IsSpecified)
{
var appId = model.ApplicationId.ToNullable();
return new RichGame
{
ApplicationId = appId,
Name = model.Name,
Details = model.Details.GetValueOrDefault(),
State = model.State.GetValueOrDefault(),
Assets = model.Assets.GetValueOrDefault()?.ToEntity(appId ?? 0),
Party = model.Party.GetValueOrDefault()?.ToEntity(),
Secrets = model.Secrets.GetValueOrDefault()?.ToEntity(),
Timestamps = model.Timestamps.GetValueOrDefault()?.ToEntity()
};
}
// Stream Game
if (model.StreamUrl.IsSpecified)
{
return new StreamingGame(
model.Name,
model.StreamUrl.Value,
model.StreamType.Value.GetValueOrDefault());
}
// Normal Game
return new Game(model.Name);
}

public static GameAssets ToEntity(this API.GameAssets model)
public static GameAssets ToEntity(this API.GameAssets model, ulong appId)
{
return new GameAssets(model.SmallText.GetValueOrDefault(),
model.SmallImage.GetValueOrDefault(),
model.LargeText.GetValueOrDefault(),
model.LargeImage.GetValueOrDefault());
return new GameAssets
{
Large = new GameAsset
{
ApplicationId = appId,
ImageId = model.LargeImage.GetValueOrDefault(),
Text = model.LargeText.GetValueOrDefault()
},
Small = new GameAsset
{
ApplicationId = appId,
ImageId = model.LargeImage.GetValueOrDefault(),
Text = model.LargeText.GetValueOrDefault()
},
};
}

public static GameParty ToEntity(this API.GameParty model)
{
return new GameParty(model.Size, model.Id);
return new GameParty
{
Id = model.Id,
Size = model.Size
};
}

public static GameSecrets ToEntity(this API.GameSecrets model)


Loading…
Cancel
Save