This commit is contained in:
Jemma Poffinbarger 2026-05-06 02:16:37 +00:00 committed by GitHub
commit f08dc24fde
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 665 additions and 1 deletions

47
database/3ds/get_mii.go Normal file
View File

@ -0,0 +1,47 @@
package database_3ds
import (
"database/sql"
"github.com/PretendoNetwork/friends/database"
"github.com/PretendoNetwork/nex-go/v2/types"
friends_3ds_types "github.com/PretendoNetwork/nex-protocols-go/v2/friends-3ds/types"
)
// GetMii returns the Mii of a specified user
func GetMii(pid uint32) (friends_3ds_types.FriendMii, error) {
friendMii := friends_3ds_types.NewFriendMii()
rows, err := database.Manager.QueryRow(`
SELECT mii_name, mii_profanity, mii_character_set, mii_data, mii_changed FROM "3ds".user_data WHERE pid=$1`, pid)
if err != nil {
return friendMii, err
}
var miiName string
var miiProfanity bool
var miiCharacterSet uint8
var miiData []byte
var changedTime uint64
err = rows.Scan(&pid, &miiName, &miiProfanity, &miiCharacterSet, &miiData, &changedTime)
if err != nil {
if err == sql.ErrNoRows {
return friendMii, database.ErrPIDNotFound
} else {
return friendMii, err
}
}
mii := friends_3ds_types.NewMii()
mii.Name = types.NewString(miiName)
mii.ProfanityFlag = types.NewBool(miiProfanity)
mii.CharacterSet = types.NewUInt8(miiCharacterSet)
mii.MiiData = types.NewBuffer(miiData)
friendMii.PID = types.NewPID(uint64(pid))
friendMii.Mii = mii
friendMii.ModifiedAt = types.NewDateTime(changedTime)
return friendMii, nil
}

View File

@ -0,0 +1,83 @@
package database_3ds
import (
"database/sql"
"github.com/PretendoNetwork/friends/database"
"github.com/PretendoNetwork/nex-go/v2/types"
friends_3ds_types "github.com/PretendoNetwork/nex-protocols-go/v2/friends-3ds/types"
)
// GetUserData returns a data for a specific user
func GetUserData(pid uint32) (friends_3ds_types.FriendPersistentInfo, error) {
userData := friends_3ds_types.NewFriendPersistentInfo()
row, err := database.Manager.QueryRow(`
SELECT pid, region, area,
language, country, favorite_title,
favorite_title_version, comment,
comment_changed, last_online, mii_changed
FROM "3ds".user_data WHERE pid=$1
`, pid)
if err != nil {
if err == sql.ErrNoRows {
return userData, database.ErrPIDNotFound
} else {
return userData, err
}
}
var relationshipType uint8
err = row.Scan(&pid, &relationshipType)
if err != nil {
return userData, err
}
gameKey := friends_3ds_types.NewGameKey()
var region uint8
var area uint8
var language uint8
var country uint8
var titleID uint64
var titleVersion uint16
var message string
var lastOnlineTime uint64
var msgUpdateTime uint64
var miiModifiedAtTime uint64
err = row.Scan(
&pid,
&region,
&area,
&language,
&country,
&titleID,
&titleVersion,
&message,
&msgUpdateTime,
&lastOnlineTime,
&miiModifiedAtTime,
)
if err != nil {
return userData, err
}
gameKey.TitleID = types.NewUInt64(titleID)
gameKey.TitleVersion = types.NewUInt16(titleVersion)
userData.PID = types.NewPID(uint64(pid))
userData.Region = types.NewUInt8(region)
userData.Country = types.NewUInt8(country)
userData.Area = types.NewUInt8(area)
userData.Language = types.NewUInt8(language)
userData.Platform = types.NewUInt8(2) // * Always 3DS
userData.GameKey = gameKey
userData.Message = types.NewString(message)
userData.MessageUpdatedAt = types.NewDateTime(msgUpdateTime)
userData.MiiModifiedAt = types.NewDateTime(miiModifiedAtTime)
userData.LastOnline = types.NewDateTime(lastOnlineTime)
return userData, nil
}

View File

@ -0,0 +1,98 @@
package database_wiiu
import (
"database/sql"
"github.com/PretendoNetwork/friends/database"
"github.com/PretendoNetwork/friends/globals"
"github.com/PretendoNetwork/nex-go/v2/types"
friends_wiiu_types "github.com/PretendoNetwork/nex-protocols-go/v2/friends-wiiu/types"
)
// GetUserData returns a data for a specific user
func GetUserData(pid uint32) (friends_wiiu_types.FriendInfo, error) {
friendInfo := friends_wiiu_types.NewFriendInfo()
row, err := database.Manager.QueryRow(`
SELECT
u.comment, u.comment_changed,
u.last_online,
bi.username, bi.unknown,
ai.unknown1, ai.unknown2,
mii.name, mii.unknown1, mii.unknown2, mii.data, mii.unknown_datetime
FROM wiiu.user_data AS u
INNER JOIN wiiu.principal_basic_info AS bi ON bi.pid = $1
INNER JOIN wiiu.network_account_info AS ai ON ai.pid = $1
INNER JOIN wiiu.mii AS mii ON mii.pid = $1
WHERE u.pid=$1
LIMIT 1
`, pid)
if err != nil {
if err == sql.ErrNoRows {
return friendInfo, database.ErrPIDNotFound
} else {
return friendInfo, err
}
}
var date uint64
var lastOnlineTime uint64
var commentContents string
var commentChanged uint64 = 0
var nnid string
var unknown uint8
var unknown1 uint8
var unknown2 uint8
var miiName string
var miiUnknown1 uint8
var miiUnknown2 uint8
var miiData []byte
var miiDatetime uint64
err = row.Scan(&commentContents, &commentChanged, &lastOnlineTime, &nnid, &unknown, &unknown1, &unknown2, &miiName, &miiUnknown1, &miiUnknown2, &miiData, &miiDatetime)
if err != nil {
return friendInfo, err
}
comment := friends_wiiu_types.NewComment()
comment.Unknown = types.NewUInt8(0)
comment.Contents = types.NewString(commentContents)
comment.LastChanged = types.NewDateTime(commentChanged)
mii := friends_wiiu_types.NewMiiV2()
mii.Name = types.NewString(miiName)
mii.Unknown1 = types.NewUInt8(miiUnknown1)
mii.Unknown2 = types.NewUInt8(miiUnknown2)
mii.MiiData = types.NewBuffer(miiData)
mii.Datetime = types.NewDateTime(miiDatetime)
principalBasicInfo := friends_wiiu_types.NewPrincipalBasicInfo()
principalBasicInfo.PID = types.NewPID(uint64(pid))
principalBasicInfo.NNID = types.NewString(nnid)
principalBasicInfo.Unknown = types.NewUInt8(unknown)
principalBasicInfo.Mii = mii
nnaInfo := friends_wiiu_types.NewNNAInfo()
nnaInfo.Unknown1 = types.NewUInt8(unknown1)
nnaInfo.Unknown2 = types.NewUInt8(unknown2)
nnaInfo.PrincipalBasicInfo = principalBasicInfo
friendInfo.NNAInfo = nnaInfo
lastOnline := types.NewDateTime(0).Now()
connectedUser, ok := globals.ConnectedUsers.Get(pid)
if ok && connectedUser != nil {
// * Online
friendInfo.Presence = connectedUser.PresenceV2.Copy().(friends_wiiu_types.NintendoPresenceV2)
} else {
// * Offline
lastOnline = types.NewDateTime(lastOnlineTime) // TODO - Change this
}
friendInfo.Status = comment
friendInfo.BecameFriend = types.NewDateTime(date)
friendInfo.LastOnline = lastOnline
friendInfo.Unknown = types.NewUInt64(0)
return friendInfo, nil
}

2
go.mod
View File

@ -5,7 +5,7 @@ go 1.24.0
toolchain go1.24.3
require (
github.com/PretendoNetwork/grpc/go v0.0.0-20260114221322-0631a1e0c840
github.com/PretendoNetwork/grpc/go v0.0.0-20260501210425-981c793afb28
github.com/PretendoNetwork/nex-go/v2 v2.3.0
github.com/PretendoNetwork/nex-protocols-common-go/v2 v2.4.0
github.com/PretendoNetwork/nex-protocols-go/v2 v2.2.2

2
go.sum
View File

@ -1,5 +1,7 @@
github.com/PretendoNetwork/grpc/go v0.0.0-20260114221322-0631a1e0c840 h1:IkflRrU2XT/8voysYxZTxcQYPyMBCt7yBHWy8U6Q/tU=
github.com/PretendoNetwork/grpc/go v0.0.0-20260114221322-0631a1e0c840/go.mod h1:L6We4KkcQeiQVPrF7iu8Zax0B1Bm0v4nssR1JOAiRFQ=
github.com/PretendoNetwork/grpc/go v0.0.0-20260501210425-981c793afb28 h1:BHRf3HF4Wyavo1+GAzaem+dqsox/V2asr91W3YY8GbI=
github.com/PretendoNetwork/grpc/go v0.0.0-20260501210425-981c793afb28/go.mod h1:L6We4KkcQeiQVPrF7iu8Zax0B1Bm0v4nssR1JOAiRFQ=
github.com/PretendoNetwork/nex-go/v2 v2.3.0 h1:CQNm/DzYhXvyzD/5l+Dxfp0/AbObuCfyfhLAeY6BejI=
github.com/PretendoNetwork/nex-go/v2 v2.3.0/go.mod h1:2xKxiTtNxGliQ80xeicc6w3D53hmunOndoB3XJxUn/8=
github.com/PretendoNetwork/nex-protocols-common-go/v2 v2.4.0 h1:EhXj1EDbNgdg40BPx/7n1HHsAy/DayGIWthu81UNyvI=

146
grpc/get_user_data.go Normal file
View File

@ -0,0 +1,146 @@
package grpc
import (
"context"
"time"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"github.com/PretendoNetwork/friends/database"
database_3ds "github.com/PretendoNetwork/friends/database/3ds"
database_wiiu "github.com/PretendoNetwork/friends/database/wiiu"
"github.com/PretendoNetwork/friends/globals"
pb "github.com/PretendoNetwork/grpc/go/friends/v2"
"google.golang.org/protobuf/types/known/timestamppb"
)
func (s *gRPCFriendsV2Server) GetUserDataWiiU(ctx context.Context, in *pb.GetUserDataWiiURequest) (*pb.GetUserDataWiiUResponse, error) {
friend, err := database_wiiu.GetUserData(in.GetPid())
if err != nil {
globals.Logger.Critical(err.Error())
if err == database.ErrPIDNotFound {
return nil, status.Errorf(codes.NotFound, "PID was not found")
} else {
return nil, status.Errorf(codes.Internal, "Internal error")
}
}
var comment = &pb.Comment{
Contents: string(friend.Status.Contents),
LastChanged: timestamppb.New(time.Unix(int64(friend.Status.LastChanged.Second()), 0)),
}
var mii = &pb.MiiV2{
Name: string(friend.NNAInfo.PrincipalBasicInfo.Mii.Name),
MiiData: friend.NNAInfo.PrincipalBasicInfo.Mii.MiiData,
Datetime: timestamppb.New(time.Unix(int64(friend.NNAInfo.PrincipalBasicInfo.Mii.Datetime.Second()), 0)),
}
var principal = &pb.PrincipalBasicInfo{
Pid: uint32(friend.NNAInfo.PrincipalBasicInfo.PID),
Nnid: string(friend.NNAInfo.PrincipalBasicInfo.NNID),
Mii: mii,
}
var nnaInfo = &pb.NNAInfo{
PrincipalBasicInfo: principal,
}
var gameKey = &pb.GameKey{
TitleId: uint64(friend.Presence.GameKey.TitleID),
TitleVersion: uint32(friend.Presence.GameKey.TitleVersion),
}
var presence = &pb.NintendoPresenceV2{
ChangedFlags: uint32(friend.Presence.ChangedFlags),
Online: bool(friend.Presence.Online),
GameKey: gameKey,
Message: string(friend.Presence.Message),
GameServerId: uint32(friend.Presence.GameServerID),
Pid: uint32(friend.Presence.PID),
GatheringId: uint32(friend.Presence.GatheringID),
ApplicationData: friend.Presence.ApplicationData,
}
var info = &pb.FriendInfoWiiU{
NnaInfo: nnaInfo,
Presence: presence,
Status: comment,
BecameFriend: timestamppb.New(time.Unix(int64(friend.BecameFriend.Second()), 0)),
LastOnline: timestamppb.New(time.Unix(int64(friend.LastOnline.Second()), 0)),
}
return &pb.GetUserDataWiiUResponse{
User: info,
}, nil
}
func (s *gRPCFriendsV2Server) GetUserData3DS(ctx context.Context, in *pb.GetUserData3DSRequest) (*pb.GetUserData3DSResponse, error) {
friend, err := database_3ds.GetUserData(in.GetPid())
if err != nil {
globals.Logger.Critical(err.Error())
if err == database.ErrPIDNotFound {
return nil, status.Errorf(codes.NotFound, "PID was not found")
} else {
return nil, status.Errorf(codes.Internal, "Internal error")
}
}
miiData, err := database_3ds.GetMii(in.GetPid())
if err != nil {
globals.Logger.Critical(err.Error())
if err == database.ErrPIDNotFound {
return nil, status.Errorf(codes.NotFound, "PID was not found")
} else {
return nil, status.Errorf(codes.Internal, "Internal error")
}
}
var gameKey = &pb.GameKey{
TitleId: uint64(friend.GameKey.TitleID),
TitleVersion: uint32(friend.GameKey.TitleVersion),
}
var mii = &pb.Mii{
Name: string(miiData.Mii.Name),
ProfanityFlag: bool(miiData.Mii.ProfanityFlag),
CharacterSet: uint32(miiData.Mii.CharacterSet),
MiiDataEncrypted: miiData.Mii.MiiData,
// TODO: Implement MiiData
}
var friendMii = &pb.FriendMii{
Pid: uint32(miiData.PID),
Mii: mii,
ModifiedAt: timestamppb.New(time.Unix(int64(miiData.ModifiedAt.Second()), 0)),
}
var presence = &pb.NintendoPresence{}
connectedUser, ok := globals.ConnectedUsers.Get(uint32(friend.PID))
if ok && connectedUser != nil {
presence.ChangedFlags = uint32(connectedUser.Presence.ChangedFlags)
presence.GameKey = &pb.GameKey{
TitleId: uint64(connectedUser.Presence.GameKey.TitleID),
TitleVersion: uint32(connectedUser.Presence.GameKey.TitleVersion),
}
presence.Message = string(connectedUser.Presence.Message)
presence.JoinAvailableFlag = uint32(connectedUser.Presence.JoinAvailableFlag)
presence.MatchmakeType = uint32(connectedUser.Presence.MatchmakeType)
presence.JoinGameId = uint32(connectedUser.Presence.JoinGameID)
presence.JoinGameMode = uint32(connectedUser.Presence.JoinGameMode)
presence.OwnerPid = uint32(connectedUser.Presence.OwnerPID)
presence.JoinGroupId = uint32(connectedUser.Presence.JoinGroupID)
presence.ApplicationArg = connectedUser.Presence.ApplicationArg
}
var info = &pb.FriendInfo3DS{
Pid: uint32(friend.PID),
Region: uint32(friend.Region),
Country: uint32(friend.Country),
Area: uint32(friend.Area),
Language: uint32(friend.Language),
Platform: uint32(friend.Platform),
Presence: presence,
GameKey: gameKey,
Message: string(friend.Message),
MessageUpdatedAt: timestamppb.New(time.Unix(int64(friend.MessageUpdatedAt.Second()), 0)),
MiiModifiedAt: timestamppb.New(time.Unix(int64(friend.MiiModifiedAt.Second()), 0)),
LastOnline: timestamppb.New(time.Unix(int64(friend.LastOnline.Second()), 0)),
Mii: friendMii,
}
return &pb.GetUserData3DSResponse{
User: info,
}, nil
}

View File

@ -0,0 +1,282 @@
package grpc
import (
"context"
"database/sql"
"time"
"github.com/PretendoNetwork/friends/database"
database_3ds "github.com/PretendoNetwork/friends/database/3ds"
database_wiiu "github.com/PretendoNetwork/friends/database/wiiu"
"github.com/PretendoNetwork/friends/globals"
pb "github.com/PretendoNetwork/grpc/go/friends/v2"
"github.com/PretendoNetwork/nex-go/v2/types"
friends_3ds_types "github.com/PretendoNetwork/nex-protocols-go/v2/friends-3ds/types"
friends_wiiu_types "github.com/PretendoNetwork/nex-protocols-go/v2/friends-wiiu/types"
"google.golang.org/protobuf/types/known/timestamppb"
)
func (s *gRPCFriendsV2Server) GetUserFriendsDataWiiU(ctx context.Context, in *pb.GetUserFriendsDataWiiURequest) (*pb.GetUserFriendsDataWiiUResponse, error) {
var friends []*pb.FriendInfoWiiU
friendList, err := database_wiiu.GetUserFriendList(in.Pid)
if err != nil && err != database.ErrEmptyList {
return &pb.GetUserFriendsDataWiiUResponse{
Friends: friends,
}, nil
}
if globals.Config.EnableBella {
bella := friends_wiiu_types.NewFriendInfo()
bella.NNAInfo = friends_wiiu_types.NewNNAInfo()
bella.Presence = friends_wiiu_types.NewNintendoPresenceV2()
bella.Status = friends_wiiu_types.NewComment()
bella.BecameFriend = types.NewDateTime(0)
bella.LastOnline = types.NewDateTime(0)
bella.Unknown = types.NewUInt64(0)
bella.NNAInfo.PrincipalBasicInfo = friends_wiiu_types.NewPrincipalBasicInfo()
bella.NNAInfo.Unknown1 = types.NewUInt8(0)
bella.NNAInfo.Unknown2 = types.NewUInt8(0)
bella.NNAInfo.PrincipalBasicInfo.PID = types.NewPID(1743126339)
bella.NNAInfo.PrincipalBasicInfo.NNID = types.NewString("PN_Testing")
bella.NNAInfo.PrincipalBasicInfo.Mii = friends_wiiu_types.NewMiiV2()
bella.NNAInfo.PrincipalBasicInfo.Unknown = types.NewUInt8(0)
bella.NNAInfo.PrincipalBasicInfo.Mii.Name = types.NewString("Bandwidth")
bella.NNAInfo.PrincipalBasicInfo.Mii.Unknown1 = types.NewUInt8(0)
bella.NNAInfo.PrincipalBasicInfo.Mii.Unknown2 = types.NewUInt8(0)
bella.NNAInfo.PrincipalBasicInfo.Mii.MiiData = types.NewBuffer([]byte{
0x03, 0x00, 0x00, 0x40, 0xE9, 0x55, 0xA2, 0x09,
0xE7, 0xC7, 0x41, 0x82, 0xD9, 0x7D, 0x0B, 0x2D,
0x03, 0xB3, 0xB8, 0x8D, 0x27, 0xD9, 0x00, 0x00,
0x01, 0x40, 0x62, 0x00, 0x65, 0x00, 0x6C, 0x00,
0x6C, 0x00, 0x61, 0x00, 0x00, 0x00, 0x45, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
0x12, 0x00, 0x81, 0x01, 0x04, 0x68, 0x43, 0x18,
0x20, 0x34, 0x46, 0x14, 0x81, 0x12, 0x17, 0x68,
0x0D, 0x00, 0x00, 0x29, 0x03, 0x52, 0x48, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x86,
})
bella.NNAInfo.PrincipalBasicInfo.Mii.Datetime = types.NewDateTime(0)
bella.Presence.ChangedFlags = types.NewUInt32(0x1EE)
bella.Presence.Online = types.NewBool(true)
bella.Presence.GameKey = friends_wiiu_types.NewGameKey()
bella.Presence.Unknown1 = types.NewUInt8(0)
bella.Presence.Message = types.NewString("Testing")
bella.Presence.Unknown2 = types.NewUInt32(0)
bella.Presence.Unknown3 = types.NewUInt8(0)
bella.Presence.GameServerID = types.NewUInt32(0)
bella.Presence.Unknown4 = types.NewUInt32(0)
bella.Presence.PID = types.NewPID(1743126339)
bella.Presence.GatheringID = types.NewUInt32(0)
bella.Presence.ApplicationData = types.NewBuffer([]byte{0x0})
bella.Presence.Unknown5 = types.NewUInt8(0)
bella.Presence.Unknown6 = types.NewUInt8(0)
bella.Presence.Unknown7 = types.NewUInt8(0)
bella.Presence.GameKey.TitleID = 0x0005000010176900
bella.Presence.GameKey.TitleVersion = types.NewUInt16(0)
bella.Status.Unknown = types.NewUInt8(0)
bella.Status.Contents = types.NewString("Greetings programs!")
bella.Status.LastChanged = types.NewDateTime(0)
friendList = append(friendList, bella)
}
for _, friend := range friendList {
// TODO: Is there a better way to do this? I really don't know what I'm doing here
var comment = &pb.Comment{
Contents: string(friend.Status.Contents),
LastChanged: timestamppb.New(time.Unix(int64(friend.Status.LastChanged.Second()), 0)),
}
var mii = &pb.MiiV2{
Name: string(friend.NNAInfo.PrincipalBasicInfo.Mii.Name),
MiiData: friend.NNAInfo.PrincipalBasicInfo.Mii.MiiData,
Datetime: timestamppb.New(time.Unix(int64(friend.NNAInfo.PrincipalBasicInfo.Mii.Datetime.Second()), 0)),
}
var principal = &pb.PrincipalBasicInfo{
Pid: uint32(friend.NNAInfo.PrincipalBasicInfo.PID),
Nnid: string(friend.NNAInfo.PrincipalBasicInfo.NNID),
Mii: mii,
}
var nnaInfo = &pb.NNAInfo{
PrincipalBasicInfo: principal,
}
var gameKey = &pb.GameKey{
TitleId: uint64(friend.Presence.GameKey.TitleID),
TitleVersion: uint32(friend.Presence.GameKey.TitleVersion),
}
var presence = &pb.NintendoPresenceV2{
ChangedFlags: uint32(friend.Presence.ChangedFlags),
Online: bool(friend.Presence.Online),
GameKey: gameKey,
Message: string(friend.Presence.Message),
GameServerId: uint32(friend.Presence.GameServerID),
Pid: uint32(friend.Presence.PID),
GatheringId: uint32(friend.Presence.GatheringID),
ApplicationData: friend.Presence.ApplicationData,
}
var info = &pb.FriendInfoWiiU{
NnaInfo: nnaInfo,
Presence: presence,
Status: comment,
BecameFriend: timestamppb.New(time.Unix(int64(friend.BecameFriend.Second()), 0)),
LastOnline: timestamppb.New(time.Unix(int64(friend.LastOnline.Second()), 0)),
}
friends = append(friends, info)
}
return &pb.GetUserFriendsDataWiiUResponse{
Friends: friends,
}, nil
}
func (s *gRPCFriendsV2Server) GetUserFriendsData3DS(ctx context.Context, in *pb.GetUserFriendsData3DSRequest) (*pb.GetUserFriendsData3DSResponse, error) {
var friends []*pb.FriendInfo3DS
friendList, err := database_3ds.GetUserFriends(in.Pid)
if err != nil && err != database.ErrEmptyList {
return &pb.GetUserFriendsData3DSResponse{
Friends: friends,
}, nil
}
friendPIDs := make([]uint32, len(friendList))
for _, friend := range friendList {
friendPIDs = append(friendPIDs, uint32(friend.PID))
}
friendInfoList, err := database_3ds.GetFriendPersistentInfos(uint32(in.Pid), friendPIDs)
if err != nil && err != sql.ErrNoRows {
globals.Logger.Critical(err.Error())
return &pb.GetUserFriendsData3DSResponse{
Friends: friends,
}, nil
}
miiList, err := database_3ds.GetFriendMiis(friendPIDs)
if err != nil && err != sql.ErrNoRows {
globals.Logger.Critical(err.Error())
return &pb.GetUserFriendsData3DSResponse{
Friends: friends,
}, nil
}
if globals.Config.EnableBella {
bella := friends_3ds_types.NewFriendPersistentInfo()
bella.PID = types.NewPID(1743126339)
bella.Region = types.NewUInt8(0)
bella.Country = types.NewUInt8(0)
bella.Area = types.NewUInt8(0)
bella.Language = types.NewUInt8(0)
bella.Platform = types.NewUInt8(0)
bella.GameKey.TitleID = 0x0005000010176900
bella.GameKey.TitleVersion = types.NewUInt16(0)
bella.Message = "Howdy Hey!"
bella.MessageUpdatedAt = types.NewDateTime(0)
bella.MiiModifiedAt = types.NewDateTime(0)
bella.LastOnline = types.NewDateTime(0)
mii := friends_3ds_types.NewMii()
mii.Name = types.NewString("Bandwidth")
mii.ProfanityFlag = types.NewBool(false)
mii.CharacterSet = types.NewUInt8(0)
mii.MiiData = types.NewBuffer([]byte{
0x03, 0x00, 0x00, 0x40, 0xE9, 0x55, 0xA2, 0x09,
0xE7, 0xC7, 0x41, 0x82, 0xD9, 0x7D, 0x0B, 0x2D,
0x03, 0xB3, 0xB8, 0x8D, 0x27, 0xD9, 0x00, 0x00,
0x01, 0x40, 0x62, 0x00, 0x65, 0x00, 0x6C, 0x00,
0x6C, 0x00, 0x61, 0x00, 0x00, 0x00, 0x45, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40,
0x12, 0x00, 0x81, 0x01, 0x04, 0x68, 0x43, 0x18,
0x20, 0x34, 0x46, 0x14, 0x81, 0x12, 0x17, 0x68,
0x0D, 0x00, 0x00, 0x29, 0x03, 0x52, 0x48, 0x50,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x86,
})
friendMii := friends_3ds_types.NewFriendMii()
friendMii.PID = types.NewPID(uint64(bella.PID))
friendMii.Mii = mii
friendMii.ModifiedAt = types.NewDateTime(0)
friendInfoList = append(friendInfoList, bella)
miiList = append(miiList, friendMii)
}
for _, friend := range friendInfoList {
// TODO: Is there a better way to do this? I really don't know what I'm doing here
var gameKey = &pb.GameKey{
TitleId: uint64(friend.GameKey.TitleID),
TitleVersion: uint32(friend.GameKey.TitleVersion),
}
var miiIndex = -1
for index, mii := range miiList {
if mii.PID == friend.PID {
miiIndex = index
break
}
}
if miiIndex == -1 {
continue
}
var miiData = miiList[miiIndex]
var mii = &pb.Mii{
Name: string(miiData.Mii.Name),
ProfanityFlag: bool(miiData.Mii.ProfanityFlag),
CharacterSet: uint32(miiData.Mii.CharacterSet),
MiiData: miiData.Mii.MiiData,
}
var friendMii = &pb.FriendMii{
Pid: uint32(miiData.PID),
Mii: mii,
ModifiedAt: timestamppb.New(time.Unix(int64(miiData.ModifiedAt.Second()), 0)),
}
var presence = &pb.NintendoPresence{}
connectedUser, ok := globals.ConnectedUsers.Get(uint32(friend.PID))
if ok && connectedUser != nil {
presence.ChangedFlags = uint32(connectedUser.Presence.ChangedFlags)
presence.GameKey = &pb.GameKey{
TitleId: uint64(connectedUser.Presence.GameKey.TitleID),
TitleVersion: uint32(connectedUser.Presence.GameKey.TitleVersion),
}
presence.Message = string(connectedUser.Presence.Message)
presence.JoinAvailableFlag = uint32(connectedUser.Presence.JoinAvailableFlag)
presence.MatchmakeType = uint32(connectedUser.Presence.MatchmakeType)
presence.JoinGameId = uint32(connectedUser.Presence.JoinGameID)
presence.JoinGameMode = uint32(connectedUser.Presence.JoinGameMode)
presence.OwnerPid = uint32(connectedUser.Presence.OwnerPID)
presence.JoinGroupId = uint32(connectedUser.Presence.JoinGroupID)
presence.ApplicationArg = connectedUser.Presence.ApplicationArg
}
var info = &pb.FriendInfo3DS{
Pid: uint32(friend.PID),
Region: uint32(friend.Region),
Country: uint32(friend.Country),
Area: uint32(friend.Area),
Language: uint32(friend.Language),
Platform: uint32(friend.Platform),
Presence: presence,
GameKey: gameKey,
Message: string(friend.Message),
MessageUpdatedAt: timestamppb.New(time.Unix(int64(friend.MessageUpdatedAt.Second()), 0)),
MiiModifiedAt: timestamppb.New(time.Unix(int64(friend.MiiModifiedAt.Second()), 0)),
LastOnline: timestamppb.New(time.Unix(int64(friend.LastOnline.Second()), 0)),
Mii: friendMii,
}
friends = append(friends, info)
}
return &pb.GetUserFriendsData3DSResponse{
Friends: friends,
}, nil
}

View File

@ -7,6 +7,7 @@ import (
"github.com/PretendoNetwork/friends/globals"
pb "github.com/PretendoNetwork/grpc/go/friends"
pbv2 "github.com/PretendoNetwork/grpc/go/friends/v2"
"google.golang.org/grpc"
)
@ -14,6 +15,10 @@ type gRPCFriendsServer struct {
pb.UnimplementedFriendsServer
}
type gRPCFriendsV2Server struct {
pbv2.UnimplementedFriendsServiceServer
}
func StartGRPCServer() {
listener, err := net.Listen("tcp", fmt.Sprintf(":%d", globals.Config.GRPCServerPort))
if err != nil {
@ -25,6 +30,7 @@ func StartGRPCServer() {
)
pb.RegisterFriendsServer(server, &gRPCFriendsServer{})
pbv2.RegisterFriendsServiceServer(server, &gRPCFriendsV2Server{})
log.Printf("server listening at %v", listener.Addr())