Files
Discord.Net/src/Discord.Net.WebSocket/Extensions/EntityExtensions.cs
Chris Johnston a4846516fb fix: false-positive detection of CustomStatusGame based on Id property (#1416)
This change fixes a bug that was introduced in PR #1406. Games were falsely detected to be CustomStatusGames, based on the Id property being included in the model payload.

This fixes the false detection of Games as CustomStatusGame. An activity will only be considered a CustomStatusGame if the Id has a value of "custom".

This change has been tested by listening to the GuildMemberUpdated event, and opening/closing games with a custom status set.
2019-11-29 22:13:08 -05:00

134 lines
5.3 KiB
C#

using Discord.Rest;
using System;
using System.Collections.Immutable;
using System.Linq;
namespace Discord.WebSocket
{
internal static class EntityExtensions
{
public static IActivity ToEntity(this API.Game model)
{
// Custom Status Game
if (model.Id.IsSpecified && model.Id.Value == "custom")
{
return new CustomStatusGame()
{
Type = ActivityType.CustomStatus,
Name = model.Name,
State = model.State.IsSpecified ? model.State.Value : null,
Emote = model.Emoji.IsSpecified ? model.Emoji.Value.ToIEmote() : null,
CreatedAt = DateTimeOffset.FromUnixTimeMilliseconds(model.CreatedAt.Value),
};
}
// Spotify Game
if (model.SyncId.IsSpecified)
{
var assets = model.Assets.GetValueOrDefault()?.ToEntity();
string albumText = assets?[1]?.Text;
string albumArtId = assets?[1]?.ImageId?.Replace("spotify:","");
var timestamps = model.Timestamps.IsSpecified ? model.Timestamps.Value.ToEntity() : null;
return new SpotifyGame
{
Name = model.Name,
SessionId = model.SessionId.GetValueOrDefault(),
TrackId = model.SyncId.Value,
TrackUrl = CDN.GetSpotifyDirectUrl(model.SyncId.Value),
AlbumTitle = albumText,
TrackTitle = model.Details.GetValueOrDefault(),
Artists = model.State.GetValueOrDefault()?.Split(';').Select(x=>x?.Trim()).ToImmutableArray(),
StartedAt = timestamps?.Start,
EndsAt = timestamps?.End,
Duration = timestamps?.End - timestamps?.Start,
AlbumArtUrl = albumArtId != null ? CDN.GetSpotifyAlbumArtUrl(albumArtId) : null,
Type = ActivityType.Listening,
Flags = model.Flags.GetValueOrDefault(),
};
}
// Rich Game
if (model.ApplicationId.IsSpecified)
{
ulong appId = model.ApplicationId.Value;
var assets = model.Assets.GetValueOrDefault()?.ToEntity(appId);
return new RichGame
{
ApplicationId = appId,
Name = model.Name,
Details = model.Details.GetValueOrDefault(),
State = model.State.GetValueOrDefault(),
SmallAsset = assets?[0],
LargeAsset = assets?[1],
Party = model.Party.IsSpecified ? model.Party.Value.ToEntity() : null,
Secrets = model.Secrets.IsSpecified ? model.Secrets.Value.ToEntity() : null,
Timestamps = model.Timestamps.IsSpecified ? model.Timestamps.Value.ToEntity() : null,
Flags = model.Flags.GetValueOrDefault()
};
}
// Stream Game
if (model.StreamUrl.IsSpecified)
{
return new StreamingGame(
model.Name,
model.StreamUrl.Value)
{
Flags = model.Flags.GetValueOrDefault(),
Details = model.Details.GetValueOrDefault()
};
}
// Normal Game
return new Game(model.Name, model.Type.GetValueOrDefault() ?? ActivityType.Playing,
model.Flags.IsSpecified ? model.Flags.Value : ActivityProperties.None,
model.Details.GetValueOrDefault());
}
// (Small, Large)
public static GameAsset[] ToEntity(this API.GameAssets model, ulong? appId = null)
{
return new GameAsset[]
{
model.SmallImage.IsSpecified ? new GameAsset
{
ApplicationId = appId,
ImageId = model.SmallImage.GetValueOrDefault(),
Text = model.SmallText.GetValueOrDefault()
} : null,
model.LargeImage.IsSpecified ? new GameAsset
{
ApplicationId = appId,
ImageId = model.LargeImage.GetValueOrDefault(),
Text = model.LargeText.GetValueOrDefault()
} : null,
};
}
public static GameParty ToEntity(this API.GameParty model)
{
// Discord will probably send bad data since they don't validate anything
long current = 0, cap = 0;
if (model.Size?.Length == 2)
{
current = model.Size[0];
cap = model.Size[1];
}
return new GameParty
{
Id = model.Id,
Members = current,
Capacity = cap,
};
}
public static GameSecrets ToEntity(this API.GameSecrets model)
{
return new GameSecrets(model.Match, model.Join, model.Spectate);
}
public static GameTimestamps ToEntity(this API.GameTimestamps model)
{
return new GameTimestamps(model.Start.ToNullable(), model.End.ToNullable());
}
}
}