feat: support new username system (#1387)
* Add support for new username system in User.String and User.AvatarURL * Move default avatar index logic from EndpointDefaultUserAvatar into User.DefaultAvatarIndex --------- Co-authored-by: Fedor Lapshin <fe.lap.prog@gmail.com>
This commit is contained in:
parent
0b0ea10b47
commit
e39e715086
3 changed files with 70 additions and 17 deletions
|
@ -49,9 +49,8 @@ var (
|
||||||
EndpointUser = func(uID string) string { return EndpointUsers + uID }
|
EndpointUser = func(uID string) string { return EndpointUsers + uID }
|
||||||
EndpointUserAvatar = func(uID, aID string) string { return EndpointCDNAvatars + uID + "/" + aID + ".png" }
|
EndpointUserAvatar = func(uID, aID string) string { return EndpointCDNAvatars + uID + "/" + aID + ".png" }
|
||||||
EndpointUserAvatarAnimated = func(uID, aID string) string { return EndpointCDNAvatars + uID + "/" + aID + ".gif" }
|
EndpointUserAvatarAnimated = func(uID, aID string) string { return EndpointCDNAvatars + uID + "/" + aID + ".gif" }
|
||||||
EndpointDefaultUserAvatar = func(uDiscriminator string) string {
|
EndpointDefaultUserAvatar = func(idx int) string {
|
||||||
uDiscriminatorInt, _ := strconv.Atoi(uDiscriminator)
|
return EndpointCDN + "embed/avatars/" + strconv.Itoa(idx) + ".png"
|
||||||
return EndpointCDN + "embed/avatars/" + strconv.Itoa(uDiscriminatorInt%5) + ".png"
|
|
||||||
}
|
}
|
||||||
EndpointUserBanner = func(uID, cID string) string {
|
EndpointUserBanner = func(uID, cID string) string {
|
||||||
return EndpointCDNBanners + uID + "/" + cID + ".png"
|
return EndpointCDNBanners + uID + "/" + cID + ".png"
|
||||||
|
|
37
user.go
37
user.go
|
@ -1,5 +1,9 @@
|
||||||
package discordgo
|
package discordgo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
// UserFlags is the flags of "user" (see UserFlags* consts)
|
// UserFlags is the flags of "user" (see UserFlags* consts)
|
||||||
// https://discord.com/developers/docs/resources/user#user-object-user-flags
|
// https://discord.com/developers/docs/resources/user#user-object-user-flags
|
||||||
type UserFlags int
|
type UserFlags int
|
||||||
|
@ -44,6 +48,10 @@ type User struct {
|
||||||
// The discriminator of the user (4 numbers after name).
|
// The discriminator of the user (4 numbers after name).
|
||||||
Discriminator string `json:"discriminator"`
|
Discriminator string `json:"discriminator"`
|
||||||
|
|
||||||
|
// The user's display name, if it is set.
|
||||||
|
// For bots, this is the application name.
|
||||||
|
GlobalName string `json:"global_name"`
|
||||||
|
|
||||||
// The token of the user. This is only present for
|
// The token of the user. This is only present for
|
||||||
// the user represented by the current session.
|
// the user represented by the current session.
|
||||||
Token string `json:"token"`
|
Token string `json:"token"`
|
||||||
|
@ -81,7 +89,14 @@ type User struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// String returns a unique identifier of the form username#discriminator
|
// String returns a unique identifier of the form username#discriminator
|
||||||
|
// or just username, if the discriminator is set to "0".
|
||||||
func (u *User) String() string {
|
func (u *User) String() string {
|
||||||
|
// If the user has been migrated from the legacy username system, their discriminator is "0".
|
||||||
|
// See https://support-dev.discord.com/hc/en-us/articles/13667755828631
|
||||||
|
if u.Discriminator == "0" {
|
||||||
|
return u.Username
|
||||||
|
}
|
||||||
|
|
||||||
return u.Username + "#" + u.Discriminator
|
return u.Username + "#" + u.Discriminator
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,17 +106,35 @@ func (u *User) Mention() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AvatarURL returns a URL to the user's avatar.
|
// AvatarURL returns a URL to the user's avatar.
|
||||||
|
//
|
||||||
// size: The size of the user's avatar as a power of two
|
// size: The size of the user's avatar as a power of two
|
||||||
// if size is an empty string, no size parameter will
|
// if size is an empty string, no size parameter will
|
||||||
// be added to the URL.
|
// be added to the URL.
|
||||||
func (u *User) AvatarURL(size string) string {
|
func (u *User) AvatarURL(size string) string {
|
||||||
return avatarURL(u.Avatar, EndpointDefaultUserAvatar(u.Discriminator),
|
return avatarURL(
|
||||||
EndpointUserAvatar(u.ID, u.Avatar), EndpointUserAvatarAnimated(u.ID, u.Avatar), size)
|
u.Avatar,
|
||||||
|
EndpointDefaultUserAvatar(u.DefaultAvatarIndex()),
|
||||||
|
EndpointUserAvatar(u.ID, u.Avatar),
|
||||||
|
EndpointUserAvatarAnimated(u.ID, u.Avatar),
|
||||||
|
size,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// BannerURL returns the URL of the users's banner image.
|
// BannerURL returns the URL of the users's banner image.
|
||||||
|
//
|
||||||
// size: The size of the desired banner image as a power of two
|
// size: The size of the desired banner image as a power of two
|
||||||
// Image size can be any power of two between 16 and 4096.
|
// Image size can be any power of two between 16 and 4096.
|
||||||
func (u *User) BannerURL(size string) string {
|
func (u *User) BannerURL(size string) string {
|
||||||
return bannerURL(u.Banner, EndpointUserBanner(u.ID, u.Banner), EndpointUserBannerAnimated(u.ID, u.Banner), size)
|
return bannerURL(u.Banner, EndpointUserBanner(u.ID, u.Banner), EndpointUserBannerAnimated(u.ID, u.Banner), size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DefaultAvatarIndex returns the index of the user's default avatar.
|
||||||
|
func (u *User) DefaultAvatarIndex() int {
|
||||||
|
if u.Discriminator == "0" {
|
||||||
|
id, _ := strconv.ParseUint(u.ID, 10, 64)
|
||||||
|
return int((id >> 22) % 6)
|
||||||
|
}
|
||||||
|
|
||||||
|
id, _ := strconv.Atoi(u.Discriminator)
|
||||||
|
return id % 5
|
||||||
|
}
|
||||||
|
|
31
user_test.go
31
user_test.go
|
@ -2,15 +2,36 @@ package discordgo
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
||||||
func TestUser(t *testing.T) {
|
func TestUser_String(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
user := &User{
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
u *User
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "User with a discriminator",
|
||||||
|
u: &User{
|
||||||
Username: "bob",
|
Username: "bob",
|
||||||
Discriminator: "8192",
|
Discriminator: "8192",
|
||||||
|
},
|
||||||
|
want: "bob#8192",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "User with discriminator set to 0",
|
||||||
|
u: &User{
|
||||||
|
Username: "aldiwildan",
|
||||||
|
Discriminator: "0",
|
||||||
|
},
|
||||||
|
want: "aldiwildan",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
for _, tc := range tests {
|
||||||
if user.String() != "bob#8192" {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Errorf("user.String() == %v", user.String())
|
if got := tc.u.String(); got != tc.want {
|
||||||
|
t.Errorf("User.String() = %v, want %v", got, tc.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue