mirror of
https://github.com/PretendoNetwork/friends.git
synced 2026-04-24 23:07:13 -05:00
Added AddFriendRequest method
This commit is contained in:
parent
51f1032c41
commit
5bbf1653ba
200
add_friend_request.go
Normal file
200
add_friend_request.go
Normal file
|
|
@ -0,0 +1,200 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
func addFriendRequest(err error, client *nex.Client, callID uint32, pid uint32, unknown2 uint8, message string, unknown4 uint8, unknown5 string, gameKey *nexproto.GameKey, unknown6 *nex.DateTime) {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
nodeID := rand.Intn(len(snowflakeNodes))
|
||||
|
||||
snowflakeNode := snowflakeNodes[nodeID]
|
||||
|
||||
friendRequestID := uint64(snowflakeNode.Generate().Int64())
|
||||
|
||||
currentTimestamp := time.Now()
|
||||
expireTimestamp := currentTimestamp.Add(time.Hour * 24 * 29)
|
||||
|
||||
sentTime := nex.NewDateTime(0)
|
||||
expireTime := nex.NewDateTime(0)
|
||||
sentTime.FromTimestamp(currentTimestamp)
|
||||
expireTime.FromTimestamp(expireTimestamp)
|
||||
|
||||
senderPID := client.PID()
|
||||
recipientPID := pid
|
||||
|
||||
recipientUserInforation := getUserInfoByPID(recipientPID)
|
||||
|
||||
friendRequest := nexproto.NewFriendRequest()
|
||||
|
||||
friendRequest.PrincipalInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendRequest.PrincipalInfo.PID = recipientPID
|
||||
friendRequest.PrincipalInfo.NNID = recipientUserInforation["username"].(string)
|
||||
friendRequest.PrincipalInfo.Mii = nexproto.NewMiiV2()
|
||||
friendRequest.PrincipalInfo.Unknown = 2 // replaying from real server
|
||||
|
||||
encodedMiiData := recipientUserInforation["mii"].(bson.M)["data"].(string)
|
||||
decodedMiiData, _ := base64.StdEncoding.DecodeString(encodedMiiData)
|
||||
|
||||
friendRequest.PrincipalInfo.Mii.Name = recipientUserInforation["mii"].(bson.M)["name"].(string)
|
||||
friendRequest.PrincipalInfo.Mii.Unknown1 = 0 // replaying from real server
|
||||
friendRequest.PrincipalInfo.Mii.Unknown2 = 0 // replaying from real server
|
||||
friendRequest.PrincipalInfo.Mii.Data = decodedMiiData
|
||||
friendRequest.PrincipalInfo.Mii.Datetime = nex.NewDateTime(0)
|
||||
|
||||
friendRequest.Message = nexproto.NewFriendRequestMessage()
|
||||
friendRequest.Message.FriendRequestID = friendRequestID
|
||||
friendRequest.Message.Unknown1 = 0 // replaying from real server
|
||||
friendRequest.Message.Unknown2 = 1 // replaying from real
|
||||
friendRequest.Message.Message = message
|
||||
friendRequest.Message.Unknown3 = 0 // replaying from real server
|
||||
friendRequest.Message.Unknown4 = "" // replaying from real server
|
||||
friendRequest.Message.GameKey = gameKey // maybe this is reused?
|
||||
friendRequest.Message.Unknown5 = unknown6 // maybe this is reused?
|
||||
friendRequest.Message.ExpiresOn = sentTime // no idea why this is set as the sent time
|
||||
friendRequest.SentOn = sentTime
|
||||
|
||||
// Why does this exist?? Always empty??
|
||||
friendInfo := nexproto.NewFriendInfo()
|
||||
|
||||
friendInfo.NNAInfo = nexproto.NewNNAInfo()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.PID = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.NNID = ""
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii = nexproto.NewMiiV2()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Name = ""
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Unknown1 = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Unknown2 = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Data = []byte{}
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Datetime = nex.NewDateTime(0)
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Unknown = 0
|
||||
friendInfo.NNAInfo.Unknown1 = 0
|
||||
friendInfo.NNAInfo.Unknown2 = 0
|
||||
|
||||
friendInfo.Presence = nexproto.NewNintendoPresenceV2()
|
||||
friendInfo.Presence.ChangedFlags = 0
|
||||
friendInfo.Presence.Online = false
|
||||
friendInfo.Presence.GameKey = gameKey // maybe this is reused?
|
||||
friendInfo.Presence.Unknown1 = 0
|
||||
friendInfo.Presence.Message = ""
|
||||
friendInfo.Presence.Unknown2 = 0
|
||||
friendInfo.Presence.Unknown3 = 0
|
||||
friendInfo.Presence.GameServerID = 0
|
||||
friendInfo.Presence.Unknown4 = 0
|
||||
friendInfo.Presence.PID = 0
|
||||
friendInfo.Presence.GatheringID = 0
|
||||
friendInfo.Presence.ApplicationData = []byte{0x00}
|
||||
friendInfo.Presence.Unknown5 = 0
|
||||
friendInfo.Presence.Unknown6 = 0
|
||||
friendInfo.Presence.Unknown7 = 0
|
||||
|
||||
friendInfo.Status = nexproto.NewComment()
|
||||
friendInfo.Status.Unknown = 0
|
||||
friendInfo.Status.Contents = ""
|
||||
friendInfo.Status.LastChanged = nex.NewDateTime(0)
|
||||
|
||||
friendInfo.BecameFriend = nex.NewDateTime(0)
|
||||
friendInfo.LastOnline = nex.NewDateTime(0)
|
||||
friendInfo.Unknown = 0
|
||||
|
||||
recipientClient := client.Server().FindClientFromPID(recipientPID)
|
||||
|
||||
if recipientClient != nil {
|
||||
senderUserInforation := getUserInfoByPID(senderPID)
|
||||
|
||||
friendRequestNotificationData := nexproto.NewFriendRequest()
|
||||
|
||||
friendRequestNotificationData.PrincipalInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendRequestNotificationData.PrincipalInfo.PID = senderPID
|
||||
friendRequestNotificationData.PrincipalInfo.NNID = senderUserInforation["username"].(string)
|
||||
friendRequestNotificationData.PrincipalInfo.Mii = nexproto.NewMiiV2()
|
||||
friendRequestNotificationData.PrincipalInfo.Unknown = 2 // replaying from real server
|
||||
|
||||
encodedMiiData := senderUserInforation["mii"].(bson.M)["data"].(string)
|
||||
decodedMiiData, _ := base64.StdEncoding.DecodeString(encodedMiiData)
|
||||
|
||||
friendRequestNotificationData.PrincipalInfo.Mii.Name = senderUserInforation["mii"].(bson.M)["name"].(string)
|
||||
friendRequestNotificationData.PrincipalInfo.Mii.Unknown1 = 0 // replaying from real server
|
||||
friendRequestNotificationData.PrincipalInfo.Mii.Unknown2 = 0 // replaying from real server
|
||||
friendRequestNotificationData.PrincipalInfo.Mii.Data = decodedMiiData
|
||||
friendRequestNotificationData.PrincipalInfo.Mii.Datetime = nex.NewDateTime(0)
|
||||
|
||||
friendRequestNotificationData.Message = nexproto.NewFriendRequestMessage()
|
||||
friendRequestNotificationData.Message.FriendRequestID = friendRequestID
|
||||
friendRequestNotificationData.Message.Unknown1 = 0 // replaying from real server
|
||||
friendRequestNotificationData.Message.Unknown2 = 1 // replaying from real
|
||||
friendRequestNotificationData.Message.Message = message
|
||||
friendRequestNotificationData.Message.Unknown3 = 0 // replaying from real server
|
||||
friendRequestNotificationData.Message.Unknown4 = "" // replaying from real server
|
||||
friendRequestNotificationData.Message.GameKey = gameKey // maybe this is reused?
|
||||
friendRequestNotificationData.Message.Unknown5 = unknown6 // maybe this is reused?
|
||||
friendRequestNotificationData.Message.ExpiresOn = sentTime // no idea why this is set as the sent time
|
||||
friendRequestNotificationData.SentOn = sentTime
|
||||
|
||||
sendFriendRequestNotification(recipientClient, friendRequestNotificationData)
|
||||
}
|
||||
|
||||
rmcResponseStream := nex.NewStreamOut(nexServer)
|
||||
|
||||
rmcResponseStream.WriteUInt8(0xFF)
|
||||
|
||||
rmcResponseBody := rmcResponseStream.Bytes()
|
||||
|
||||
// Build response packet
|
||||
rmcResponse := nex.NewRMCResponse(nexproto.FriendsProtocolID, callID)
|
||||
rmcResponse.SetSuccess(nexproto.FriendsMethodAddFriendRequest, rmcResponseBody)
|
||||
|
||||
rmcResponseBytes := rmcResponse.Bytes()
|
||||
|
||||
responsePacket, _ := nex.NewPacketV0(client, nil)
|
||||
|
||||
responsePacket.SetVersion(0)
|
||||
responsePacket.SetSource(0xA1)
|
||||
responsePacket.SetDestination(0xAF)
|
||||
responsePacket.SetType(nex.DataPacket)
|
||||
responsePacket.SetPayload(rmcResponseBytes)
|
||||
|
||||
responsePacket.AddFlag(nex.FlagNeedsAck)
|
||||
responsePacket.AddFlag(nex.FlagReliable)
|
||||
|
||||
nexServer.Send(responsePacket)
|
||||
}
|
||||
|
||||
func sendFriendRequestNotification(client *nex.Client, friendRequestNotificationData *nexproto.FriendRequest) {
|
||||
eventObject := nexproto.NewNintendoNotificationEvent()
|
||||
eventObject.Type = 27
|
||||
eventObject.SenderPID = friendRequestNotificationData.PrincipalInfo.PID
|
||||
eventObject.DataHolder = nex.NewDataHolder()
|
||||
eventObject.DataHolder.Name = "FriendRequest"
|
||||
eventObject.DataHolder.Object = friendRequestNotificationData
|
||||
|
||||
stream := nex.NewStreamOut(nexServer)
|
||||
eventObjectBytes := eventObject.Bytes(stream)
|
||||
|
||||
rmcRequest := nex.NewRMCRequest()
|
||||
rmcRequest.SetProtocolID(nexproto.NintendoNotificationsProtocolID)
|
||||
rmcRequest.SetCallID(3810693103)
|
||||
rmcRequest.SetMethodID(nexproto.NintendoNotificationsMethodProcessNintendoNotificationEvent2)
|
||||
rmcRequest.SetParameters(eventObjectBytes)
|
||||
|
||||
rmcRequestBytes := rmcRequest.Bytes()
|
||||
|
||||
requestPacket, _ := nex.NewPacketV0(client, nil)
|
||||
|
||||
requestPacket.SetVersion(0)
|
||||
requestPacket.SetSource(0xA1)
|
||||
requestPacket.SetDestination(0xAF)
|
||||
requestPacket.SetType(nex.DataPacket)
|
||||
requestPacket.SetPayload(rmcRequestBytes)
|
||||
|
||||
requestPacket.AddFlag(nex.FlagNeedsAck)
|
||||
requestPacket.AddFlag(nex.FlagReliable)
|
||||
|
||||
nexServer.Send(requestPacket)
|
||||
}
|
||||
74
database.go
74
database.go
|
|
@ -53,6 +53,35 @@ func connectCassandra() {
|
|||
|
||||
// Create tables if missing
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.preferences (
|
||||
pid int PRIMARY KEY,
|
||||
show_online boolean,
|
||||
show_current_game boolean,
|
||||
block_friend_requests boolean
|
||||
)`).Exec(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.blocks (
|
||||
id text PRIMARY KEY,
|
||||
blocker_pid int,
|
||||
blocked_pid int,
|
||||
date bigint
|
||||
)`).Exec(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.friend_requests (
|
||||
id bigint PRIMARY KEY,
|
||||
sender_pid int,
|
||||
recipient_pid int,
|
||||
sent_on bigint,
|
||||
expires_on bigint,
|
||||
message text
|
||||
)`).Exec(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.users (
|
||||
pid int PRIMARY KEY,
|
||||
nnid text,
|
||||
|
|
@ -71,15 +100,6 @@ func connectCassandra() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.preferences (
|
||||
pid int PRIMARY KEY,
|
||||
show_online boolean,
|
||||
show_current_game boolean,
|
||||
block_friend_requests boolean
|
||||
)`).Exec(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.friendships (
|
||||
id bigint PRIMARY KEY,
|
||||
user1_pid int,
|
||||
|
|
@ -89,15 +109,6 @@ func connectCassandra() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.blocks (
|
||||
id text PRIMARY KEY,
|
||||
blocker_pid int,
|
||||
blocked_pid int,
|
||||
date bigint
|
||||
)`).Exec(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.miis (
|
||||
pid int PRIMARY KEY,
|
||||
name text,
|
||||
|
|
@ -109,16 +120,6 @@ func connectCassandra() {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.friend_requests (
|
||||
id bigint PRIMARY KEY,
|
||||
sender_pid int,
|
||||
recipient_pid int,
|
||||
sent_on bigint,
|
||||
message text
|
||||
)`).Exec(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.notifications (
|
||||
id bigint PRIMARY KEY,
|
||||
sender_pid int,
|
||||
|
|
@ -237,22 +238,19 @@ func getUserBlockList(pid uint32) {}
|
|||
func getUserNotifications(pid uint32) {}
|
||||
|
||||
func updateUserPrincipalPreference(pid uint32, principalPreference *nexproto.PrincipalPreference) {
|
||||
if err := cassandraClusterSession.Query(`UPDATE pretendo_friends.preferences SET show_online=?, show_current_game=?, block_friend_requests=? WHERE pid=?`, principalPreference.Unknown1, principalPreference.Unknown2, principalPreference.Unknown3, pid).Exec(); err != nil {
|
||||
if err := cassandraClusterSession.Query(`UPDATE pretendo_friends.preferences SET
|
||||
show_online=?,
|
||||
show_current_game=?,
|
||||
block_friend_requests=?
|
||||
WHERE pid=?`, principalPreference.ShowOnlinePresence, principalPreference.ShowCurrentTitle, principalPreference.BlockFriendRequests, pid).Exec(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func getUserPrincipalPreference(pid uint32) *nexproto.PrincipalPreference {
|
||||
var showOnline bool
|
||||
var showCurrentGame bool
|
||||
var blockFriendRequests bool
|
||||
|
||||
_ = cassandraClusterSession.Query(`SELECT show_online, show_current_game, block_friend_requests FROM pretendo_friends.preferences WHERE pid=?`, pid).Scan(&showOnline, &showCurrentGame, &blockFriendRequests)
|
||||
|
||||
preference := nexproto.NewPrincipalPreference()
|
||||
preference.Unknown1 = showOnline
|
||||
preference.Unknown2 = showCurrentGame
|
||||
preference.Unknown3 = blockFriendRequests
|
||||
|
||||
_ = cassandraClusterSession.Query(`SELECT show_online, show_current_game, block_friend_requests FROM pretendo_friends.preferences WHERE pid=?`, pid).Scan(&preference.ShowOnlinePresence, &preference.ShowCurrentTitle, &preference.BlockFriendRequests)
|
||||
|
||||
return preference
|
||||
}
|
||||
|
|
|
|||
18
init.go
18
init.go
|
|
@ -2,9 +2,12 @@ package main
|
|||
|
||||
import (
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"runtime"
|
||||
|
||||
"github.com/bwmarrin/snowflake"
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
|
|
@ -27,6 +30,7 @@ type nexToken struct {
|
|||
var rsaPrivateKeyBytes []byte
|
||||
var rsaPrivateKey *rsa.PrivateKey
|
||||
var hmacSecret []byte
|
||||
var snowflakeNodes []*snowflake.Node
|
||||
|
||||
func init() {
|
||||
// Setup RSA private key for token parsing
|
||||
|
|
@ -54,4 +58,18 @@ func init() {
|
|||
|
||||
connectMongo()
|
||||
connectCassandra()
|
||||
createSnowflakeNodes()
|
||||
}
|
||||
|
||||
func createSnowflakeNodes() {
|
||||
snowflakeNodes = make([]*snowflake.Node, 0)
|
||||
|
||||
for corenum := 0; corenum < runtime.NumCPU(); corenum++ {
|
||||
node, err := snowflake.NewNode(int64(corenum))
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
snowflakeNodes = append(snowflakeNodes, node)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
main.go
3
main.go
|
|
@ -44,9 +44,10 @@ func main() {
|
|||
|
||||
// Friends (WiiU) protocol handles
|
||||
friendsServer.UpdateAndGetAllInformation(updateAndGetAllInformation)
|
||||
friendsServer.CheckSettingStatus(checkSettingStatus)
|
||||
friendsServer.AddFriendRequest(addFriendRequest)
|
||||
friendsServer.UpdatePreference(updatePreferenceWiiU)
|
||||
friendsServer.GetBasicInfo(getBasicInfo)
|
||||
friendsServer.CheckSettingStatus(checkSettingStatus)
|
||||
friendsServer.GetRequestBlockSettings(getRequestBlockSettings)
|
||||
|
||||
// Friends (3DS) protocol handles
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user