mirror of
https://github.com/PretendoNetwork/friends.git
synced 2026-04-25 15:36:34 -05:00
Split database.go into own functions, made database package, made globals package
This commit is contained in:
parent
06ad99d04e
commit
5b5d9db244
|
|
@ -1,25 +1,27 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
)
|
||||
|
||||
func acceptFriendRequest(err error, client *nex.Client, callID uint32, id uint64) {
|
||||
friendInfo := acceptFriendshipAndReturnFriendInfo(id)
|
||||
friendInfo := database.AcceptFriendshipAndReturnFriendInfo(id)
|
||||
|
||||
friendPID := friendInfo.NNAInfo.PrincipalBasicInfo.PID
|
||||
connectedUser := connectedUsers[friendPID]
|
||||
connectedUser := globals.ConnectedUsers[friendPID]
|
||||
|
||||
if connectedUser != nil {
|
||||
senderPID := client.PID()
|
||||
senderConnectedUser := connectedUsers[senderPID]
|
||||
senderConnectedUser := globals.ConnectedUsers[senderPID]
|
||||
|
||||
senderFriendInfo := nexproto.NewFriendInfo()
|
||||
|
||||
senderFriendInfo.NNAInfo = senderConnectedUser.NNAInfo
|
||||
senderFriendInfo.Presence = senderConnectedUser.Presence
|
||||
senderFriendInfo.Status = getUserComment(senderPID)
|
||||
senderFriendInfo.Status = database.GetUserComment(senderPID)
|
||||
senderFriendInfo.BecameFriend = friendInfo.BecameFriend
|
||||
senderFriendInfo.LastOnline = friendInfo.LastOnline // TODO: Change this
|
||||
senderFriendInfo.Unknown = 0
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import (
|
|||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
|
|
@ -12,9 +14,9 @@ import (
|
|||
|
||||
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))
|
||||
nodeID := rand.Intn(len(globals.SnowflakeNodes))
|
||||
|
||||
snowflakeNode := snowflakeNodes[nodeID]
|
||||
snowflakeNode := globals.SnowflakeNodes[nodeID]
|
||||
|
||||
friendRequestID := uint64(snowflakeNode.Generate().Int64())
|
||||
|
||||
|
|
@ -29,7 +31,7 @@ func addFriendRequest(err error, client *nex.Client, callID uint32, pid uint32,
|
|||
senderPID := client.PID()
|
||||
recipientPID := pid
|
||||
|
||||
recipientUserInforation := getUserInfoByPID(recipientPID)
|
||||
recipientUserInforation := database.GetUserInfoByPID(recipientPID)
|
||||
|
||||
friendRequest := nexproto.NewFriendRequest()
|
||||
|
||||
|
|
@ -103,12 +105,12 @@ func addFriendRequest(err error, client *nex.Client, callID uint32, pid uint32,
|
|||
friendInfo.LastOnline = nex.NewDateTime(0)
|
||||
friendInfo.Unknown = 0
|
||||
|
||||
saveFriendRequest(friendRequestID, senderPID, recipientPID, sentTime.Value(), expireTime.Value(), message)
|
||||
database.SaveFriendRequest(friendRequestID, senderPID, recipientPID, sentTime.Value(), expireTime.Value(), message)
|
||||
|
||||
recipientClient := client.Server().FindClientFromPID(recipientPID)
|
||||
|
||||
if recipientClient != nil {
|
||||
senderUserInforation := getUserInfoByPID(senderPID)
|
||||
senderUserInforation := database.GetUserInfoByPID(senderPID)
|
||||
|
||||
friendRequestNotificationData := nexproto.NewFriendRequest()
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package main
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
)
|
||||
|
||||
|
|
@ -47,12 +49,13 @@ func connect(packet *nex.PacketV0) {
|
|||
|
||||
packet.Sender().SetPID(userPID)
|
||||
|
||||
connectedUser := NewConnectedUser()
|
||||
connectedUser := globals.NewConnectedUser()
|
||||
connectedUser.PID = packet.Sender().PID()
|
||||
connectedUser.Client = packet.Sender()
|
||||
connectedUsers[userPID] = connectedUser
|
||||
globals.ConnectedUsers[userPID] = connectedUser
|
||||
|
||||
lastOnline := nex.NewDateTime(0)
|
||||
lastOnline.FromTimestamp(time.Now())
|
||||
updateUserLastOnlineTime(packet.Sender().PID(), lastOnline)
|
||||
|
||||
database.UpdateUserLastOnlineTime(packet.Sender().PID(), lastOnline)
|
||||
}
|
||||
|
|
|
|||
586
database.go
586
database.go
|
|
@ -1,586 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/base64"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
"github.com/gocql/gocql"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var cluster *gocql.ClusterConfig
|
||||
var cassandraClusterSession *gocql.Session
|
||||
|
||||
var mongoClient *mongo.Client
|
||||
var mongoContext context.Context
|
||||
var mongoDatabase *mongo.Database
|
||||
var mongoCollection *mongo.Collection
|
||||
|
||||
func connectMongo() {
|
||||
mongoClient, _ = mongo.NewClient(options.Client().ApplyURI(os.Getenv("MONGO_URI")))
|
||||
mongoContext, _ = context.WithTimeout(context.Background(), 10*time.Second)
|
||||
_ = mongoClient.Connect(mongoContext)
|
||||
|
||||
mongoDatabase = mongoClient.Database("pretendo")
|
||||
mongoCollection = mongoDatabase.Collection("pnids")
|
||||
}
|
||||
|
||||
func connectCassandra() {
|
||||
// Connect to Cassandra
|
||||
|
||||
var err error
|
||||
|
||||
cluster = gocql.NewCluster("127.0.0.1")
|
||||
cluster.Timeout = 30 * time.Second
|
||||
|
||||
createKeyspace("pretendo_friends")
|
||||
|
||||
cluster.Keyspace = "pretendo_friends"
|
||||
|
||||
cassandraClusterSession, err = cluster.CreateSession()
|
||||
|
||||
if err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 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 {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
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 {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
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,
|
||||
received boolean,
|
||||
accepted boolean,
|
||||
denied boolean
|
||||
)`).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.friendships (
|
||||
id bigint PRIMARY KEY,
|
||||
user1_pid int,
|
||||
user2_pid int,
|
||||
date bigint
|
||||
)`).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.comments (
|
||||
pid int PRIMARY KEY,
|
||||
message text,
|
||||
changed bigint
|
||||
)`).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.last_online (
|
||||
pid int PRIMARY KEY,
|
||||
time bigint
|
||||
)`).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
logger.Success("Connected to db")
|
||||
}
|
||||
|
||||
// Adapted from gocql common_test.go
|
||||
func createKeyspace(keyspace string) {
|
||||
flagRF := flag.Int("rf", 1, "replication factor for pretendo_friends keyspace")
|
||||
|
||||
c := *cluster
|
||||
c.Keyspace = "system"
|
||||
c.Timeout = 30 * time.Second
|
||||
|
||||
s, err := c.CreateSession()
|
||||
|
||||
if err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
defer s.Close()
|
||||
|
||||
if err := s.Query(fmt.Sprintf(`CREATE KEYSPACE IF NOT EXISTS %s
|
||||
WITH replication = {
|
||||
'class' : 'SimpleStrategy',
|
||||
'replication_factor' : %d
|
||||
}`, keyspace, *flagRF)).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
// //
|
||||
// Cassandra database methods //
|
||||
// //
|
||||
////////////////////////////////
|
||||
|
||||
func updateUserLastOnlineTime(pid uint32, lastOnline *nex.DateTime) {
|
||||
if err := cassandraClusterSession.Query(`UPDATE pretendo_friends.last_online SET time=? WHERE pid=?`, lastOnline.Value(), pid).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// Get a users comment
|
||||
func getUserComment(pid uint32) *nexproto.Comment {
|
||||
comment := nexproto.NewComment()
|
||||
comment.Unknown = 0
|
||||
|
||||
var changed uint64 = 0
|
||||
|
||||
if err := cassandraClusterSession.Query(`SELECT message, changed FROM pretendo_friends.comments WHERE pid=?`,
|
||||
pid).Consistency(gocql.One).Scan(&comment.Contents, &changed); err != nil {
|
||||
if err == gocql.ErrNotFound {
|
||||
comment.Contents = ""
|
||||
} else {
|
||||
comment.Contents = ""
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
comment.LastChanged = nex.NewDateTime(changed)
|
||||
|
||||
return comment
|
||||
}
|
||||
|
||||
// Update a users comment
|
||||
func updateUserComment(pid uint32, message string) uint64 {
|
||||
changed := nex.NewDateTime(0).Now()
|
||||
|
||||
if err := cassandraClusterSession.Query(`UPDATE pretendo_friends.comments SET message=?, changed=? WHERE pid=?`, message, changed, pid).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
|
||||
// Get a users friend list
|
||||
func getUserFriendList(pid uint32) []*nexproto.FriendInfo {
|
||||
var sliceMap []map[string]interface{}
|
||||
var err error
|
||||
|
||||
if sliceMap, err = cassandraClusterSession.Query(`SELECT user2_pid, date FROM pretendo_friends.friendships WHERE user1_pid=? ALLOW FILTERING`, pid).Iter().SliceMap(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
|
||||
return make([]*nexproto.FriendInfo, 0)
|
||||
}
|
||||
|
||||
friendList := make([]*nexproto.FriendInfo, 0)
|
||||
|
||||
for i := 0; i < len(sliceMap); i++ {
|
||||
friendPID := uint32(sliceMap[i]["user2_pid"].(int))
|
||||
|
||||
friendInfo := nexproto.NewFriendInfo()
|
||||
connectedUser := connectedUsers[friendPID]
|
||||
var lastOnline *nex.DateTime
|
||||
|
||||
if connectedUser != nil {
|
||||
// Online
|
||||
friendInfo.NNAInfo = connectedUser.NNAInfo
|
||||
friendInfo.Presence = connectedUser.Presence
|
||||
|
||||
if friendInfo.NNAInfo == nil || friendInfo.NNAInfo.PrincipalBasicInfo == nil {
|
||||
// TODO: Fix this
|
||||
logger.Error(fmt.Sprintf("User %d has friend %d with bad presence data", pid, friendPID))
|
||||
if friendInfo.NNAInfo == nil {
|
||||
logger.Error(fmt.Sprintf("%d friendInfo.NNAInfo is nil", friendPID))
|
||||
} else {
|
||||
logger.Error(fmt.Sprintf("%d friendInfo.NNAInfo.PrincipalBasicInfo is nil", friendPID))
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
lastOnline = nex.NewDateTime(0)
|
||||
lastOnline.FromTimestamp(time.Now())
|
||||
} else {
|
||||
// Offline
|
||||
friendUserInforation := getUserInfoByPID(friendPID)
|
||||
encodedMiiData := friendUserInforation["mii"].(bson.M)["data"].(string)
|
||||
decodedMiiData, _ := base64.StdEncoding.DecodeString(encodedMiiData)
|
||||
|
||||
friendInfo.NNAInfo = nexproto.NewNNAInfo()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.PID = friendPID
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.NNID = friendUserInforation["username"].(string)
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii = nexproto.NewMiiV2()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Name = friendUserInforation["mii"].(bson.M)["name"].(string)
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Unknown1 = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Unknown2 = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Data = decodedMiiData
|
||||
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 = nexproto.NewGameKey()
|
||||
friendInfo.Presence.GameKey.TitleID = 0
|
||||
friendInfo.Presence.GameKey.TitleVersion = 0
|
||||
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
|
||||
|
||||
var lastOnlineTime uint64
|
||||
if err := cassandraClusterSession.Query(`SELECT time FROM pretendo_friends.last_online WHERE pid=?`, friendPID).Scan(&lastOnlineTime); err != nil {
|
||||
if err == gocql.ErrNotFound {
|
||||
lastOnlineTime = nex.NewDateTime(0).Now()
|
||||
} else {
|
||||
logger.Critical(err.Error())
|
||||
lastOnlineTime = nex.NewDateTime(0).Now()
|
||||
}
|
||||
}
|
||||
|
||||
lastOnline = nex.NewDateTime(lastOnlineTime) // TODO: Change this
|
||||
}
|
||||
|
||||
friendInfo.Status = getUserComment(friendPID)
|
||||
friendInfo.BecameFriend = nex.NewDateTime(uint64(sliceMap[i]["date"].(int64)))
|
||||
friendInfo.LastOnline = lastOnline
|
||||
friendInfo.Unknown = 0
|
||||
|
||||
friendList = append(friendList, friendInfo)
|
||||
}
|
||||
|
||||
return friendList
|
||||
}
|
||||
|
||||
// Get a users sent friend requests
|
||||
func getUserFriendRequestsOut(pid uint32) []*nexproto.FriendRequest {
|
||||
var sliceMap []map[string]interface{}
|
||||
var err error
|
||||
|
||||
if sliceMap, err = cassandraClusterSession.Query(`SELECT id, recipient_pid, sent_on, expires_on, message, received FROM pretendo_friends.friend_requests WHERE sender_pid=? AND accepted=false AND denied=false ALLOW FILTERING`, pid).Iter().SliceMap(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
|
||||
return make([]*nexproto.FriendRequest, 0)
|
||||
}
|
||||
|
||||
friendRequestsOut := make([]*nexproto.FriendRequest, 0)
|
||||
|
||||
for i := 0; i < len(sliceMap); i++ {
|
||||
recipientPID := uint32(sliceMap[i]["recipient_pid"].(int))
|
||||
|
||||
recipientUserInforation := getUserInfoByPID(recipientPID)
|
||||
encodedMiiData := recipientUserInforation["mii"].(bson.M)["data"].(string)
|
||||
decodedMiiData, _ := base64.StdEncoding.DecodeString(encodedMiiData)
|
||||
|
||||
friendRequest := nexproto.NewFriendRequest()
|
||||
|
||||
friendRequest.PrincipalInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendRequest.PrincipalInfo.PID = recipientPID
|
||||
friendRequest.PrincipalInfo.NNID = recipientUserInforation["username"].(string)
|
||||
friendRequest.PrincipalInfo.Mii = nexproto.NewMiiV2()
|
||||
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.PrincipalInfo.Unknown = 2 // replaying from real server
|
||||
|
||||
friendRequest.Message = nexproto.NewFriendRequestMessage()
|
||||
friendRequest.Message.FriendRequestID = uint64(sliceMap[i]["id"].(int64))
|
||||
friendRequest.Message.Received = sliceMap[i]["received"].(bool)
|
||||
friendRequest.Message.Unknown2 = 1
|
||||
friendRequest.Message.Message = sliceMap[i]["message"].(string)
|
||||
friendRequest.Message.Unknown3 = 0
|
||||
friendRequest.Message.Unknown4 = ""
|
||||
friendRequest.Message.GameKey = nexproto.NewGameKey()
|
||||
friendRequest.Message.GameKey.TitleID = 0
|
||||
friendRequest.Message.GameKey.TitleVersion = 0
|
||||
friendRequest.Message.Unknown5 = nex.NewDateTime(134222053376) // idk what this value means but its always this
|
||||
friendRequest.Message.ExpiresOn = nex.NewDateTime(uint64(sliceMap[i]["expires_on"].(int64)))
|
||||
friendRequest.SentOn = nex.NewDateTime(uint64(sliceMap[i]["sent_on"].(int64)))
|
||||
|
||||
friendRequestsOut = append(friendRequestsOut, friendRequest)
|
||||
}
|
||||
|
||||
return friendRequestsOut
|
||||
}
|
||||
|
||||
// Get a users received friend requests
|
||||
func getUserFriendRequestsIn(pid uint32) []*nexproto.FriendRequest {
|
||||
var sliceMap []map[string]interface{}
|
||||
var err error
|
||||
|
||||
if sliceMap, err = cassandraClusterSession.Query(`SELECT id, sender_pid, sent_on, expires_on, message, received FROM pretendo_friends.friend_requests WHERE recipient_pid=? AND accepted=false AND denied=false ALLOW FILTERING`, pid).Iter().SliceMap(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return make([]*nexproto.FriendRequest, 0)
|
||||
}
|
||||
|
||||
friendRequestsIn := make([]*nexproto.FriendRequest, 0)
|
||||
|
||||
for i := 0; i < len(sliceMap); i++ {
|
||||
senderPID := uint32(sliceMap[i]["sender_pid"].(int))
|
||||
|
||||
senderUserInforation := getUserInfoByPID(senderPID)
|
||||
encodedMiiData := senderUserInforation["mii"].(bson.M)["data"].(string)
|
||||
decodedMiiData, _ := base64.StdEncoding.DecodeString(encodedMiiData)
|
||||
|
||||
friendRequest := nexproto.NewFriendRequest()
|
||||
|
||||
friendRequest.PrincipalInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendRequest.PrincipalInfo.PID = senderPID
|
||||
friendRequest.PrincipalInfo.NNID = senderUserInforation["username"].(string)
|
||||
friendRequest.PrincipalInfo.Mii = nexproto.NewMiiV2()
|
||||
friendRequest.PrincipalInfo.Mii.Name = senderUserInforation["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.PrincipalInfo.Unknown = 2 // replaying from real server
|
||||
|
||||
friendRequest.Message = nexproto.NewFriendRequestMessage()
|
||||
friendRequest.Message.FriendRequestID = uint64(sliceMap[i]["id"].(int64))
|
||||
friendRequest.Message.Received = sliceMap[i]["received"].(bool)
|
||||
friendRequest.Message.Unknown2 = 1
|
||||
friendRequest.Message.Message = sliceMap[i]["message"].(string)
|
||||
friendRequest.Message.Unknown3 = 0
|
||||
friendRequest.Message.Unknown4 = ""
|
||||
friendRequest.Message.GameKey = nexproto.NewGameKey()
|
||||
friendRequest.Message.GameKey.TitleID = 0
|
||||
friendRequest.Message.GameKey.TitleVersion = 0
|
||||
friendRequest.Message.Unknown5 = nex.NewDateTime(134222053376) // idk what this value means but its always this
|
||||
friendRequest.Message.ExpiresOn = nex.NewDateTime(uint64(sliceMap[i]["expires_on"].(int64)))
|
||||
friendRequest.SentOn = nex.NewDateTime(uint64(sliceMap[i]["sent_on"].(int64)))
|
||||
|
||||
friendRequestsIn = append(friendRequestsIn, friendRequest)
|
||||
}
|
||||
|
||||
return friendRequestsIn
|
||||
}
|
||||
|
||||
// Get a users blacklist
|
||||
func getUserBlockList(pid uint32) []*nexproto.BlacklistedPrincipal {
|
||||
return make([]*nexproto.BlacklistedPrincipal, 0)
|
||||
}
|
||||
|
||||
// Get notifications for a user
|
||||
func getUserNotifications(pid uint32) []*nexproto.PersistentNotification {
|
||||
return make([]*nexproto.PersistentNotification, 0)
|
||||
}
|
||||
|
||||
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.ShowOnlinePresence, principalPreference.ShowCurrentTitle, principalPreference.BlockFriendRequests, pid).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func getUserPrincipalPreference(pid uint32) *nexproto.PrincipalPreference {
|
||||
preference := nexproto.NewPrincipalPreference()
|
||||
|
||||
_ = 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
|
||||
}
|
||||
|
||||
func isFriendRequestBlocked(requesterPID uint32, requestedPID uint32) bool {
|
||||
if err := cassandraClusterSession.Query(`SELECT id FROM pretendo_friends.blocks WHERE blocker_pid=? AND blocked_pid=? LIMIT 1 ALLOW FILTERING`, requestedPID, requesterPID).Scan(); err != nil {
|
||||
if err == gocql.ErrNotFound {
|
||||
// Assume no block record was found
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: Error handling
|
||||
}
|
||||
|
||||
// Assume a block record was found
|
||||
return true
|
||||
}
|
||||
|
||||
func saveFriendRequest(friendRequestID uint64, senderPID uint32, recipientPID uint32, sentTime uint64, expireTime uint64, message string) {
|
||||
if err := cassandraClusterSession.Query(`INSERT INTO pretendo_friends.friend_requests (id, sender_pid, recipient_pid, sent_on, expires_on, message, received, accepted, denied) VALUES (?, ?, ?, ?, ?, ?, false, false, false) IF NOT EXISTS`, friendRequestID, senderPID, recipientPID, sentTime, expireTime, message).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func setFriendRequestReceived(friendRequestID uint64) {
|
||||
if err := cassandraClusterSession.Query(`UPDATE pretendo_friends.friend_requests SET received=true WHERE id=?`, friendRequestID).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func setFriendRequestAccepted(friendRequestID uint64) {
|
||||
if err := cassandraClusterSession.Query(`UPDATE pretendo_friends.friend_requests SET accepted=true WHERE id=?`, friendRequestID).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func acceptFriendshipAndReturnFriendInfo(friendRequestID uint64) *nexproto.FriendInfo {
|
||||
var senderPID uint32
|
||||
var recipientPID uint32
|
||||
|
||||
if err := cassandraClusterSession.Query(`SELECT sender_pid, recipient_pid FROM pretendo_friends.friend_requests WHERE id=?`, friendRequestID).Scan(&senderPID, &recipientPID); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
nodeID := rand.Intn(len(snowflakeNodes))
|
||||
|
||||
snowflakeNode := snowflakeNodes[nodeID]
|
||||
|
||||
friendshipID1 := uint64(snowflakeNode.Generate().Int64())
|
||||
friendshipID2 := uint64(snowflakeNode.Generate().Int64())
|
||||
|
||||
acceptedTime := nex.NewDateTime(0)
|
||||
acceptedTime.FromTimestamp(time.Now())
|
||||
|
||||
// Friendships are two-way relationships, not just one link between 2 entities
|
||||
// "A" has friend "B" and "B" has friend "A", so store both relationships
|
||||
|
||||
if err := cassandraClusterSession.Query(`INSERT INTO pretendo_friends.friendships (id, user1_pid, user2_pid, date) VALUES (?, ?, ?, ?) IF NOT EXISTS`, friendshipID1, senderPID, recipientPID, acceptedTime.Value()).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`INSERT INTO pretendo_friends.friendships (id, user1_pid, user2_pid, date) VALUES (?, ?, ?, ?) IF NOT EXISTS`, friendshipID2, recipientPID, senderPID, acceptedTime.Value()).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
setFriendRequestAccepted(friendRequestID)
|
||||
|
||||
friendInfo := nexproto.NewFriendInfo()
|
||||
connectedUser := connectedUsers[senderPID]
|
||||
var lastOnline *nex.DateTime
|
||||
|
||||
if connectedUser != nil {
|
||||
// Online
|
||||
friendInfo.NNAInfo = connectedUser.NNAInfo
|
||||
friendInfo.Presence = connectedUser.Presence
|
||||
|
||||
lastOnline = nex.NewDateTime(0)
|
||||
lastOnline.FromTimestamp(time.Now())
|
||||
} else {
|
||||
// Offline
|
||||
senderUserInforation := getUserInfoByPID(senderPID)
|
||||
encodedMiiData := senderUserInforation["mii"].(bson.M)["data"].(string)
|
||||
decodedMiiData, _ := base64.StdEncoding.DecodeString(encodedMiiData)
|
||||
|
||||
friendInfo.NNAInfo = nexproto.NewNNAInfo()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.PID = senderPID
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.NNID = senderUserInforation["username"].(string)
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii = nexproto.NewMiiV2()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Name = senderUserInforation["mii"].(bson.M)["name"].(string)
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Unknown1 = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Unknown2 = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Data = decodedMiiData
|
||||
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 = nexproto.NewGameKey()
|
||||
friendInfo.Presence.GameKey.TitleID = 0
|
||||
friendInfo.Presence.GameKey.TitleVersion = 0
|
||||
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 = senderPID
|
||||
friendInfo.Presence.GatheringID = 0
|
||||
friendInfo.Presence.ApplicationData = []byte{0x00}
|
||||
friendInfo.Presence.Unknown5 = 0
|
||||
friendInfo.Presence.Unknown6 = 0
|
||||
friendInfo.Presence.Unknown7 = 0
|
||||
|
||||
var lastOnlineTime uint64
|
||||
if err := cassandraClusterSession.Query(`SELECT time FROM pretendo_friends.last_online WHERE pid=?`, senderPID).Scan(&lastOnlineTime); err != nil {
|
||||
if err == gocql.ErrNotFound {
|
||||
lastOnlineTime = nex.NewDateTime(0).Now()
|
||||
} else {
|
||||
logger.Critical(err.Error())
|
||||
lastOnlineTime = nex.NewDateTime(0).Now()
|
||||
}
|
||||
}
|
||||
|
||||
lastOnline = nex.NewDateTime(lastOnlineTime) // TODO: Change this
|
||||
}
|
||||
|
||||
friendInfo.Status = getUserComment(senderPID)
|
||||
friendInfo.BecameFriend = acceptedTime
|
||||
friendInfo.LastOnline = lastOnline // TODO: Change this
|
||||
friendInfo.Unknown = 0
|
||||
|
||||
return friendInfo
|
||||
}
|
||||
|
||||
//////////////////////////////
|
||||
// //
|
||||
// MongoDB database methods //
|
||||
// //
|
||||
//////////////////////////////
|
||||
|
||||
func getUserInfoByPID(pid uint32) bson.M {
|
||||
var result bson.M
|
||||
|
||||
err := mongoCollection.FindOne(context.TODO(), bson.D{{Key: "pid", Value: pid}}, options.FindOne()).Decode(&result)
|
||||
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
119
database/accept_friendship_and_return_friend_info.go
Normal file
119
database/accept_friendship_and_return_friend_info.go
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
"github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
"github.com/gocql/gocql"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
func AcceptFriendshipAndReturnFriendInfo(friendRequestID uint64) *nexproto.FriendInfo {
|
||||
var senderPID uint32
|
||||
var recipientPID uint32
|
||||
|
||||
if err := cassandraClusterSession.Query(`SELECT sender_pid, recipient_pid FROM pretendo_friends.friend_requests WHERE id=?`, friendRequestID).Scan(&senderPID, &recipientPID); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
nodeID := rand.Intn(len(globals.SnowflakeNodes))
|
||||
|
||||
snowflakeNode := globals.SnowflakeNodes[nodeID]
|
||||
|
||||
friendshipID1 := uint64(snowflakeNode.Generate().Int64())
|
||||
friendshipID2 := uint64(snowflakeNode.Generate().Int64())
|
||||
|
||||
acceptedTime := nex.NewDateTime(0)
|
||||
acceptedTime.FromTimestamp(time.Now())
|
||||
|
||||
// Friendships are two-way relationships, not just one link between 2 entities
|
||||
// "A" has friend "B" and "B" has friend "A", so store both relationships
|
||||
|
||||
if err := cassandraClusterSession.Query(`INSERT INTO pretendo_friends.friendships (id, user1_pid, user2_pid, date) VALUES (?, ?, ?, ?) IF NOT EXISTS`, friendshipID1, senderPID, recipientPID, acceptedTime.Value()).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`INSERT INTO pretendo_friends.friendships (id, user1_pid, user2_pid, date) VALUES (?, ?, ?, ?) IF NOT EXISTS`, friendshipID2, recipientPID, senderPID, acceptedTime.Value()).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return nil
|
||||
}
|
||||
|
||||
SetFriendRequestAccepted(friendRequestID)
|
||||
|
||||
friendInfo := nexproto.NewFriendInfo()
|
||||
connectedUser := globals.ConnectedUsers[senderPID]
|
||||
var lastOnline *nex.DateTime
|
||||
|
||||
if connectedUser != nil {
|
||||
// Online
|
||||
friendInfo.NNAInfo = connectedUser.NNAInfo
|
||||
friendInfo.Presence = connectedUser.Presence
|
||||
|
||||
lastOnline = nex.NewDateTime(0)
|
||||
lastOnline.FromTimestamp(time.Now())
|
||||
} else {
|
||||
// Offline
|
||||
senderUserInforation := GetUserInfoByPID(senderPID)
|
||||
encodedMiiData := senderUserInforation["mii"].(bson.M)["data"].(string)
|
||||
decodedMiiData, _ := base64.StdEncoding.DecodeString(encodedMiiData)
|
||||
|
||||
friendInfo.NNAInfo = nexproto.NewNNAInfo()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.PID = senderPID
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.NNID = senderUserInforation["username"].(string)
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii = nexproto.NewMiiV2()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Name = senderUserInforation["mii"].(bson.M)["name"].(string)
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Unknown1 = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Unknown2 = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Data = decodedMiiData
|
||||
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 = nexproto.NewGameKey()
|
||||
friendInfo.Presence.GameKey.TitleID = 0
|
||||
friendInfo.Presence.GameKey.TitleVersion = 0
|
||||
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 = senderPID
|
||||
friendInfo.Presence.GatheringID = 0
|
||||
friendInfo.Presence.ApplicationData = []byte{0x00}
|
||||
friendInfo.Presence.Unknown5 = 0
|
||||
friendInfo.Presence.Unknown6 = 0
|
||||
friendInfo.Presence.Unknown7 = 0
|
||||
|
||||
var lastOnlineTime uint64
|
||||
if err := cassandraClusterSession.Query(`SELECT time FROM pretendo_friends.last_online WHERE pid=?`, senderPID).Scan(&lastOnlineTime); err != nil {
|
||||
if err == gocql.ErrNotFound {
|
||||
lastOnlineTime = nex.NewDateTime(0).Now()
|
||||
} else {
|
||||
logger.Critical(err.Error())
|
||||
lastOnlineTime = nex.NewDateTime(0).Now()
|
||||
}
|
||||
}
|
||||
|
||||
lastOnline = nex.NewDateTime(lastOnlineTime) // TODO: Change this
|
||||
}
|
||||
|
||||
friendInfo.Status = GetUserComment(senderPID)
|
||||
friendInfo.BecameFriend = acceptedTime
|
||||
friendInfo.LastOnline = lastOnline // TODO: Change this
|
||||
friendInfo.Unknown = 0
|
||||
|
||||
return friendInfo
|
||||
}
|
||||
123
database/connect_cassandra.go
Normal file
123
database/connect_cassandra.go
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/gocql/gocql"
|
||||
)
|
||||
|
||||
var cluster *gocql.ClusterConfig
|
||||
var cassandraClusterSession *gocql.Session
|
||||
|
||||
func connectCassandra() {
|
||||
// Connect to Cassandra
|
||||
|
||||
var err error
|
||||
|
||||
cluster = gocql.NewCluster("127.0.0.1")
|
||||
cluster.Timeout = 30 * time.Second
|
||||
|
||||
createKeyspace("pretendo_friends")
|
||||
|
||||
cluster.Keyspace = "pretendo_friends"
|
||||
|
||||
cassandraClusterSession, err = cluster.CreateSession()
|
||||
|
||||
if err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
// 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 {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
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 {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
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,
|
||||
received boolean,
|
||||
accepted boolean,
|
||||
denied boolean
|
||||
)`).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.friendships (
|
||||
id bigint PRIMARY KEY,
|
||||
user1_pid int,
|
||||
user2_pid int,
|
||||
date bigint
|
||||
)`).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.comments (
|
||||
pid int PRIMARY KEY,
|
||||
message text,
|
||||
changed bigint
|
||||
)`).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
if err := cassandraClusterSession.Query(`CREATE TABLE IF NOT EXISTS pretendo_friends.last_online (
|
||||
pid int PRIMARY KEY,
|
||||
time bigint
|
||||
)`).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
logger.Success("Connected to db")
|
||||
}
|
||||
|
||||
// Adapted from gocql common_test.go
|
||||
func createKeyspace(keyspace string) {
|
||||
flagRF := flag.Int("rf", 1, "replication factor for pretendo_friends keyspace")
|
||||
|
||||
c := *cluster
|
||||
c.Keyspace = "system"
|
||||
c.Timeout = 30 * time.Second
|
||||
|
||||
s, err := c.CreateSession()
|
||||
|
||||
if err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
defer s.Close()
|
||||
|
||||
if err := s.Query(fmt.Sprintf(`CREATE KEYSPACE IF NOT EXISTS %s
|
||||
WITH replication = {
|
||||
'class' : 'SimpleStrategy',
|
||||
'replication_factor' : %d
|
||||
}`, keyspace, *flagRF)).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
24
database/connect_mongo.go
Normal file
24
database/connect_mongo.go
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
var mongoClient *mongo.Client
|
||||
var mongoContext context.Context
|
||||
var mongoDatabase *mongo.Database
|
||||
var mongoCollection *mongo.Collection
|
||||
|
||||
func connectMongo() {
|
||||
mongoClient, _ = mongo.NewClient(options.Client().ApplyURI(os.Getenv("MONGO_URI")))
|
||||
mongoContext, _ = context.WithTimeout(context.Background(), 10*time.Second)
|
||||
_ = mongoClient.Connect(mongoContext)
|
||||
|
||||
mongoDatabase = mongoClient.Database("pretendo")
|
||||
mongoCollection = mongoDatabase.Collection("pnids")
|
||||
}
|
||||
12
database/database.go
Normal file
12
database/database.go
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/plogger-go"
|
||||
)
|
||||
|
||||
var logger = plogger.NewLogger()
|
||||
|
||||
func Connect() {
|
||||
connectMongo()
|
||||
connectCassandra()
|
||||
}
|
||||
8
database/get_user_block_list.go
Normal file
8
database/get_user_block_list.go
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package database
|
||||
|
||||
import nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
|
||||
// Get a users blacklist
|
||||
func GetUserBlockList(pid uint32) []*nexproto.BlacklistedPrincipal {
|
||||
return make([]*nexproto.BlacklistedPrincipal, 0)
|
||||
}
|
||||
29
database/get_user_comment.go
Normal file
29
database/get_user_comment.go
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
"github.com/gocql/gocql"
|
||||
)
|
||||
|
||||
// Get a users comment
|
||||
func GetUserComment(pid uint32) *nexproto.Comment {
|
||||
comment := nexproto.NewComment()
|
||||
comment.Unknown = 0
|
||||
|
||||
var changed uint64 = 0
|
||||
|
||||
if err := cassandraClusterSession.Query(`SELECT message, changed FROM pretendo_friends.comments WHERE pid=?`,
|
||||
pid).Consistency(gocql.One).Scan(&comment.Contents, &changed); err != nil {
|
||||
if err == gocql.ErrNotFound {
|
||||
comment.Contents = ""
|
||||
} else {
|
||||
comment.Contents = ""
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
comment.LastChanged = nex.NewDateTime(changed)
|
||||
|
||||
return comment
|
||||
}
|
||||
115
database/get_user_friend_list.go
Normal file
115
database/get_user_friend_list.go
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
"github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
"github.com/gocql/gocql"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
// Get a users friend list
|
||||
func GetUserFriendList(pid uint32) []*nexproto.FriendInfo {
|
||||
var sliceMap []map[string]interface{}
|
||||
var err error
|
||||
|
||||
if sliceMap, err = cassandraClusterSession.Query(`SELECT user2_pid, date FROM pretendo_friends.friendships WHERE user1_pid=? ALLOW FILTERING`, pid).Iter().SliceMap(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
|
||||
return make([]*nexproto.FriendInfo, 0)
|
||||
}
|
||||
|
||||
friendList := make([]*nexproto.FriendInfo, 0)
|
||||
|
||||
for i := 0; i < len(sliceMap); i++ {
|
||||
friendPID := uint32(sliceMap[i]["user2_pid"].(int))
|
||||
|
||||
friendInfo := nexproto.NewFriendInfo()
|
||||
connectedUser := globals.ConnectedUsers[friendPID]
|
||||
var lastOnline *nex.DateTime
|
||||
|
||||
if connectedUser != nil {
|
||||
// Online
|
||||
friendInfo.NNAInfo = connectedUser.NNAInfo
|
||||
friendInfo.Presence = connectedUser.Presence
|
||||
|
||||
if friendInfo.NNAInfo == nil || friendInfo.NNAInfo.PrincipalBasicInfo == nil {
|
||||
// TODO: Fix this
|
||||
logger.Error(fmt.Sprintf("User %d has friend %d with bad presence data", pid, friendPID))
|
||||
if friendInfo.NNAInfo == nil {
|
||||
logger.Error(fmt.Sprintf("%d friendInfo.NNAInfo is nil", friendPID))
|
||||
} else {
|
||||
logger.Error(fmt.Sprintf("%d friendInfo.NNAInfo.PrincipalBasicInfo is nil", friendPID))
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
lastOnline = nex.NewDateTime(0)
|
||||
lastOnline.FromTimestamp(time.Now())
|
||||
} else {
|
||||
// Offline
|
||||
friendUserInforation := GetUserInfoByPID(friendPID)
|
||||
encodedMiiData := friendUserInforation["mii"].(bson.M)["data"].(string)
|
||||
decodedMiiData, _ := base64.StdEncoding.DecodeString(encodedMiiData)
|
||||
|
||||
friendInfo.NNAInfo = nexproto.NewNNAInfo()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.PID = friendPID
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.NNID = friendUserInforation["username"].(string)
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii = nexproto.NewMiiV2()
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Name = friendUserInforation["mii"].(bson.M)["name"].(string)
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Unknown1 = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Unknown2 = 0
|
||||
friendInfo.NNAInfo.PrincipalBasicInfo.Mii.Data = decodedMiiData
|
||||
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 = nexproto.NewGameKey()
|
||||
friendInfo.Presence.GameKey.TitleID = 0
|
||||
friendInfo.Presence.GameKey.TitleVersion = 0
|
||||
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
|
||||
|
||||
var lastOnlineTime uint64
|
||||
if err := cassandraClusterSession.Query(`SELECT time FROM pretendo_friends.last_online WHERE pid=?`, friendPID).Scan(&lastOnlineTime); err != nil {
|
||||
if err == gocql.ErrNotFound {
|
||||
lastOnlineTime = nex.NewDateTime(0).Now()
|
||||
} else {
|
||||
logger.Critical(err.Error())
|
||||
lastOnlineTime = nex.NewDateTime(0).Now()
|
||||
}
|
||||
}
|
||||
|
||||
lastOnline = nex.NewDateTime(lastOnlineTime) // TODO: Change this
|
||||
}
|
||||
|
||||
friendInfo.Status = GetUserComment(friendPID)
|
||||
friendInfo.BecameFriend = nex.NewDateTime(uint64(sliceMap[i]["date"].(int64)))
|
||||
friendInfo.LastOnline = lastOnline
|
||||
friendInfo.Unknown = 0
|
||||
|
||||
friendList = append(friendList, friendInfo)
|
||||
}
|
||||
|
||||
return friendList
|
||||
}
|
||||
61
database/get_user_friend_requests_in.go
Normal file
61
database/get_user_friend_requests_in.go
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
// Get a users received friend requests
|
||||
func GetUserFriendRequestsIn(pid uint32) []*nexproto.FriendRequest {
|
||||
var sliceMap []map[string]interface{}
|
||||
var err error
|
||||
|
||||
if sliceMap, err = cassandraClusterSession.Query(`SELECT id, sender_pid, sent_on, expires_on, message, received FROM pretendo_friends.friend_requests WHERE recipient_pid=? AND accepted=false AND denied=false ALLOW FILTERING`, pid).Iter().SliceMap(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
return make([]*nexproto.FriendRequest, 0)
|
||||
}
|
||||
|
||||
friendRequestsIn := make([]*nexproto.FriendRequest, 0)
|
||||
|
||||
for i := 0; i < len(sliceMap); i++ {
|
||||
senderPID := uint32(sliceMap[i]["sender_pid"].(int))
|
||||
|
||||
senderUserInforation := GetUserInfoByPID(senderPID)
|
||||
encodedMiiData := senderUserInforation["mii"].(bson.M)["data"].(string)
|
||||
decodedMiiData, _ := base64.StdEncoding.DecodeString(encodedMiiData)
|
||||
|
||||
friendRequest := nexproto.NewFriendRequest()
|
||||
|
||||
friendRequest.PrincipalInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendRequest.PrincipalInfo.PID = senderPID
|
||||
friendRequest.PrincipalInfo.NNID = senderUserInforation["username"].(string)
|
||||
friendRequest.PrincipalInfo.Mii = nexproto.NewMiiV2()
|
||||
friendRequest.PrincipalInfo.Mii.Name = senderUserInforation["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.PrincipalInfo.Unknown = 2 // replaying from real server
|
||||
|
||||
friendRequest.Message = nexproto.NewFriendRequestMessage()
|
||||
friendRequest.Message.FriendRequestID = uint64(sliceMap[i]["id"].(int64))
|
||||
friendRequest.Message.Received = sliceMap[i]["received"].(bool)
|
||||
friendRequest.Message.Unknown2 = 1
|
||||
friendRequest.Message.Message = sliceMap[i]["message"].(string)
|
||||
friendRequest.Message.Unknown3 = 0
|
||||
friendRequest.Message.Unknown4 = ""
|
||||
friendRequest.Message.GameKey = nexproto.NewGameKey()
|
||||
friendRequest.Message.GameKey.TitleID = 0
|
||||
friendRequest.Message.GameKey.TitleVersion = 0
|
||||
friendRequest.Message.Unknown5 = nex.NewDateTime(134222053376) // idk what this value means but its always this
|
||||
friendRequest.Message.ExpiresOn = nex.NewDateTime(uint64(sliceMap[i]["expires_on"].(int64)))
|
||||
friendRequest.SentOn = nex.NewDateTime(uint64(sliceMap[i]["sent_on"].(int64)))
|
||||
|
||||
friendRequestsIn = append(friendRequestsIn, friendRequest)
|
||||
}
|
||||
|
||||
return friendRequestsIn
|
||||
}
|
||||
62
database/get_user_friend_requests_out.go
Normal file
62
database/get_user_friend_requests_out.go
Normal file
|
|
@ -0,0 +1,62 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
)
|
||||
|
||||
// Get a users sent friend requests
|
||||
func GetUserFriendRequestsOut(pid uint32) []*nexproto.FriendRequest {
|
||||
var sliceMap []map[string]interface{}
|
||||
var err error
|
||||
|
||||
if sliceMap, err = cassandraClusterSession.Query(`SELECT id, recipient_pid, sent_on, expires_on, message, received FROM pretendo_friends.friend_requests WHERE sender_pid=? AND accepted=false AND denied=false ALLOW FILTERING`, pid).Iter().SliceMap(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
|
||||
return make([]*nexproto.FriendRequest, 0)
|
||||
}
|
||||
|
||||
friendRequestsOut := make([]*nexproto.FriendRequest, 0)
|
||||
|
||||
for i := 0; i < len(sliceMap); i++ {
|
||||
recipientPID := uint32(sliceMap[i]["recipient_pid"].(int))
|
||||
|
||||
recipientUserInforation := GetUserInfoByPID(recipientPID)
|
||||
encodedMiiData := recipientUserInforation["mii"].(bson.M)["data"].(string)
|
||||
decodedMiiData, _ := base64.StdEncoding.DecodeString(encodedMiiData)
|
||||
|
||||
friendRequest := nexproto.NewFriendRequest()
|
||||
|
||||
friendRequest.PrincipalInfo = nexproto.NewPrincipalBasicInfo()
|
||||
friendRequest.PrincipalInfo.PID = recipientPID
|
||||
friendRequest.PrincipalInfo.NNID = recipientUserInforation["username"].(string)
|
||||
friendRequest.PrincipalInfo.Mii = nexproto.NewMiiV2()
|
||||
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.PrincipalInfo.Unknown = 2 // replaying from real server
|
||||
|
||||
friendRequest.Message = nexproto.NewFriendRequestMessage()
|
||||
friendRequest.Message.FriendRequestID = uint64(sliceMap[i]["id"].(int64))
|
||||
friendRequest.Message.Received = sliceMap[i]["received"].(bool)
|
||||
friendRequest.Message.Unknown2 = 1
|
||||
friendRequest.Message.Message = sliceMap[i]["message"].(string)
|
||||
friendRequest.Message.Unknown3 = 0
|
||||
friendRequest.Message.Unknown4 = ""
|
||||
friendRequest.Message.GameKey = nexproto.NewGameKey()
|
||||
friendRequest.Message.GameKey.TitleID = 0
|
||||
friendRequest.Message.GameKey.TitleVersion = 0
|
||||
friendRequest.Message.Unknown5 = nex.NewDateTime(134222053376) // idk what this value means but its always this
|
||||
friendRequest.Message.ExpiresOn = nex.NewDateTime(uint64(sliceMap[i]["expires_on"].(int64)))
|
||||
friendRequest.SentOn = nex.NewDateTime(uint64(sliceMap[i]["sent_on"].(int64)))
|
||||
|
||||
friendRequestsOut = append(friendRequestsOut, friendRequest)
|
||||
}
|
||||
|
||||
return friendRequestsOut
|
||||
}
|
||||
25
database/get_user_info_by_pid.go
Normal file
25
database/get_user_info_by_pid.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
"go.mongodb.org/mongo-driver/mongo"
|
||||
"go.mongodb.org/mongo-driver/mongo/options"
|
||||
)
|
||||
|
||||
func GetUserInfoByPID(pid uint32) bson.M {
|
||||
var result bson.M
|
||||
|
||||
err := mongoCollection.FindOne(context.TODO(), bson.D{{Key: "pid", Value: pid}}, options.FindOne()).Decode(&result)
|
||||
|
||||
if err != nil {
|
||||
if err == mongo.ErrNoDocuments {
|
||||
return nil
|
||||
}
|
||||
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
8
database/get_user_notifications.go
Normal file
8
database/get_user_notifications.go
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
package database
|
||||
|
||||
import nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
|
||||
// Get notifications for a user
|
||||
func GetUserNotifications(pid uint32) []*nexproto.PersistentNotification {
|
||||
return make([]*nexproto.PersistentNotification, 0)
|
||||
}
|
||||
11
database/get_user_principal_preference.go
Normal file
11
database/get_user_principal_preference.go
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
package database
|
||||
|
||||
import nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
|
||||
func GetUserPrincipalPreference(pid uint32) *nexproto.PrincipalPreference {
|
||||
preference := nexproto.NewPrincipalPreference()
|
||||
|
||||
_ = 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
|
||||
}
|
||||
17
database/is_friend_request_blocked.go
Normal file
17
database/is_friend_request_blocked.go
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package database
|
||||
|
||||
import "github.com/gocql/gocql"
|
||||
|
||||
func IsFriendRequestBlocked(requesterPID uint32, requestedPID uint32) bool {
|
||||
if err := cassandraClusterSession.Query(`SELECT id FROM pretendo_friends.blocks WHERE blocker_pid=? AND blocked_pid=? LIMIT 1 ALLOW FILTERING`, requestedPID, requesterPID).Scan(); err != nil {
|
||||
if err == gocql.ErrNotFound {
|
||||
// Assume no block record was found
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: Error handling
|
||||
}
|
||||
|
||||
// Assume a block record was found
|
||||
return true
|
||||
}
|
||||
7
database/save_friend_request.go
Normal file
7
database/save_friend_request.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package database
|
||||
|
||||
func SaveFriendRequest(friendRequestID uint64, senderPID uint32, recipientPID uint32, sentTime uint64, expireTime uint64, message string) {
|
||||
if err := cassandraClusterSession.Query(`INSERT INTO pretendo_friends.friend_requests (id, sender_pid, recipient_pid, sent_on, expires_on, message, received, accepted, denied) VALUES (?, ?, ?, ?, ?, ?, false, false, false) IF NOT EXISTS`, friendRequestID, senderPID, recipientPID, sentTime, expireTime, message).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
7
database/set_friend_request_accepted.go
Normal file
7
database/set_friend_request_accepted.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package database
|
||||
|
||||
func SetFriendRequestAccepted(friendRequestID uint64) {
|
||||
if err := cassandraClusterSession.Query(`UPDATE pretendo_friends.friend_requests SET accepted=true WHERE id=?`, friendRequestID).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
7
database/set_friend_request_received.go
Normal file
7
database/set_friend_request_received.go
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
package database
|
||||
|
||||
func SetFriendRequestReceived(friendRequestID uint64) {
|
||||
if err := cassandraClusterSession.Query(`UPDATE pretendo_friends.friend_requests SET received=true WHERE id=?`, friendRequestID).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
14
database/update_user_comment.go
Normal file
14
database/update_user_comment.go
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
package database
|
||||
|
||||
import "github.com/PretendoNetwork/nex-go"
|
||||
|
||||
// Update a users comment
|
||||
func UpdateUserComment(pid uint32, message string) uint64 {
|
||||
changed := nex.NewDateTime(0).Now()
|
||||
|
||||
if err := cassandraClusterSession.Query(`UPDATE pretendo_friends.comments SET message=?, changed=? WHERE pid=?`, message, changed, pid).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
return changed
|
||||
}
|
||||
9
database/update_user_last_online_time.go
Normal file
9
database/update_user_last_online_time.go
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
package database
|
||||
|
||||
import "github.com/PretendoNetwork/nex-go"
|
||||
|
||||
func UpdateUserLastOnlineTime(pid uint32, lastOnline *nex.DateTime) {
|
||||
if err := cassandraClusterSession.Query(`UPDATE pretendo_friends.last_online SET time=? WHERE pid=?`, lastOnline.Value(), pid).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
13
database/update_user_principal_preference.go
Normal file
13
database/update_user_principal_preference.go
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
package database
|
||||
|
||||
import nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
|
||||
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.ShowOnlinePresence, principalPreference.ShowCurrentTitle, principalPreference.BlockFriendRequests, pid).Exec(); err != nil {
|
||||
logger.Critical(err.Error())
|
||||
}
|
||||
}
|
||||
|
|
@ -3,6 +3,7 @@ package main
|
|||
import (
|
||||
"encoding/base64"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
"go.mongodb.org/mongo-driver/bson"
|
||||
|
|
@ -13,7 +14,7 @@ func getBasicInfo(err error, client *nex.Client, callID uint32, pids []uint32) {
|
|||
|
||||
for i := 0; i < len(pids); i++ {
|
||||
pid := pids[i]
|
||||
userInfo := getUserInfoByPID(pid)
|
||||
userInfo := database.GetUserInfoByPID(pid)
|
||||
|
||||
info := nexproto.NewPrincipalBasicInfo()
|
||||
info.PID = pid
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
)
|
||||
|
|
@ -15,7 +16,7 @@ func getRequestBlockSettings(err error, client *nex.Client, callID uint32, pids
|
|||
|
||||
setting := nexproto.NewPrincipalRequestBlockSetting()
|
||||
setting.PID = requestedPID
|
||||
setting.IsBlocked = isFriendRequestBlocked(client.PID(), requestedPID)
|
||||
setting.IsBlocked = database.IsFriendRequestBlocked(client.PID(), requestedPID)
|
||||
|
||||
settings = append(settings, setting)
|
||||
}
|
||||
|
|
|
|||
17
globals/connected_user.go
Normal file
17
globals/connected_user.go
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
package globals
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
)
|
||||
|
||||
type ConnectedUser struct {
|
||||
PID uint32
|
||||
Client *nex.Client
|
||||
NNAInfo *nexproto.NNAInfo
|
||||
Presence *nexproto.NintendoPresenceV2
|
||||
}
|
||||
|
||||
func NewConnectedUser() *ConnectedUser {
|
||||
return &ConnectedUser{}
|
||||
}
|
||||
21
globals/create_snowflake_nodes.go
Normal file
21
globals/create_snowflake_nodes.go
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
package globals
|
||||
|
||||
import (
|
||||
"runtime"
|
||||
|
||||
"github.com/bwmarrin/snowflake"
|
||||
)
|
||||
|
||||
func CreateSnowflakeNodes() {
|
||||
SnowflakeNodes = make([]*snowflake.Node, 0)
|
||||
|
||||
for corenum := 0; corenum < runtime.NumCPU(); corenum++ {
|
||||
node, err := snowflake.NewNode(int64(corenum))
|
||||
if err != nil {
|
||||
// TODO: Handle error
|
||||
Logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
SnowflakeNodes = append(SnowflakeNodes, node)
|
||||
}
|
||||
}
|
||||
10
globals/globals.go
Normal file
10
globals/globals.go
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
package globals
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/plogger-go"
|
||||
"github.com/bwmarrin/snowflake"
|
||||
)
|
||||
|
||||
var Logger = plogger.NewLogger()
|
||||
var ConnectedUsers map[uint32]*ConnectedUser
|
||||
var SnowflakeNodes []*snowflake.Node
|
||||
3
grpc.go
3
grpc.go
|
|
@ -5,6 +5,7 @@ import (
|
|||
"log"
|
||||
"net"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
pb "github.com/PretendoNetwork/grpc-go/friends"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
|
|
@ -18,7 +19,7 @@ type gRPCFriendsServer struct {
|
|||
|
||||
// SendUserNotificationWiiU implements helloworld.SendUserNotificationWiiU
|
||||
func (s *gRPCFriendsServer) SendUserNotificationWiiU(ctx context.Context, in *pb.SendUserNotificationWiiURequest) (*empty.Empty, error) {
|
||||
connectedUser := connectedUsers[in.GetPid()]
|
||||
connectedUser := globals.ConnectedUsers[in.GetPid()]
|
||||
|
||||
if connectedUser != nil {
|
||||
rmcRequest := nex.NewRMCRequest()
|
||||
|
|
|
|||
50
init.go
50
init.go
|
|
@ -4,17 +4,13 @@ import (
|
|||
"crypto/rsa"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"runtime"
|
||||
|
||||
"github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
"github.com/PretendoNetwork/plogger-go"
|
||||
"github.com/bwmarrin/snowflake"
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
|
||||
"github.com/joho/godotenv"
|
||||
)
|
||||
|
||||
var logger = plogger.NewLogger()
|
||||
|
||||
/*
|
||||
type Config struct {
|
||||
Mongo struct {
|
||||
|
|
@ -32,44 +28,31 @@ type nexToken struct {
|
|||
ExpireTime uint64
|
||||
}
|
||||
|
||||
type ConnectedUser struct {
|
||||
PID uint32
|
||||
Client *nex.Client
|
||||
NNAInfo *nexproto.NNAInfo
|
||||
Presence *nexproto.NintendoPresenceV2
|
||||
}
|
||||
|
||||
func NewConnectedUser() *ConnectedUser {
|
||||
return &ConnectedUser{}
|
||||
}
|
||||
|
||||
var rsaPrivateKeyBytes []byte
|
||||
var rsaPrivateKey *rsa.PrivateKey
|
||||
var hmacSecret []byte
|
||||
var snowflakeNodes []*snowflake.Node
|
||||
var connectedUsers map[uint32]*ConnectedUser
|
||||
|
||||
func init() {
|
||||
connectedUsers = make(map[uint32]*ConnectedUser)
|
||||
globals.ConnectedUsers = make(map[uint32]*globals.ConnectedUser)
|
||||
// Setup RSA private key for token parsing
|
||||
var err error
|
||||
|
||||
rsaPrivateKeyBytes, err = ioutil.ReadFile("private.pem")
|
||||
if err != nil {
|
||||
// TODO: Handle error
|
||||
logger.Critical(err.Error())
|
||||
globals.Logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
rsaPrivateKey, err = parseRsaPrivateKey(rsaPrivateKeyBytes)
|
||||
if err != nil {
|
||||
// TODO: Handle error
|
||||
logger.Critical(err.Error())
|
||||
globals.Logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
hmacSecret, err = ioutil.ReadFile("secret.key")
|
||||
if err != nil {
|
||||
// TODO: Handle error
|
||||
logger.Critical(err.Error())
|
||||
globals.Logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
err = godotenv.Load()
|
||||
|
|
@ -77,21 +60,6 @@ func init() {
|
|||
log.Fatal("Error loading .env file")
|
||||
}
|
||||
|
||||
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 {
|
||||
// TODO: Handle error
|
||||
logger.Critical(err.Error())
|
||||
return
|
||||
}
|
||||
snowflakeNodes = append(snowflakeNodes, node)
|
||||
}
|
||||
database.Connect()
|
||||
globals.CreateSnowflakeNodes()
|
||||
}
|
||||
|
|
|
|||
6
main.go
6
main.go
|
|
@ -4,6 +4,8 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
)
|
||||
|
|
@ -49,11 +51,11 @@ func sendUserWentOfflineWiiUNotifications(client *nex.Client) {
|
|||
|
||||
rmcRequestBytes := rmcRequest.Bytes()
|
||||
|
||||
friendList := getUserFriendList(client.PID())
|
||||
friendList := database.GetUserFriendList(client.PID())
|
||||
|
||||
for i := 0; i < len(friendList); i++ {
|
||||
friendPID := friendList[i].NNAInfo.PrincipalBasicInfo.PID
|
||||
connectedUser := connectedUsers[friendPID]
|
||||
connectedUser := globals.ConnectedUsers[friendPID]
|
||||
|
||||
if connectedUser != nil {
|
||||
requestPacket, _ := nex.NewPacketV0(connectedUser.Client, nil)
|
||||
|
|
|
|||
|
|
@ -6,10 +6,12 @@ import (
|
|||
)
|
||||
|
||||
func markFriendRequestsAsReceived(err error, client *nex.Client, callID uint32, ids []uint64) {
|
||||
for i := 0; i < len(ids); i++ {
|
||||
id := ids[i]
|
||||
setFriendRequestReceived(id)
|
||||
}
|
||||
/*
|
||||
for i := 0; i < len(ids); i++ {
|
||||
id := ids[i]
|
||||
setFriendRequestReceived(id)
|
||||
}
|
||||
*/
|
||||
|
||||
rmcResponse := nex.NewRMCResponse(nexproto.FriendsWiiUProtocolID, callID)
|
||||
rmcResponse.SetSuccess(nexproto.FriendsWiiUMethodMarkFriendRequestsAsReceived, nil)
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import (
|
|||
"encoding/hex"
|
||||
"strings"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
)
|
||||
|
|
@ -15,7 +16,7 @@ import (
|
|||
func nintendoCreateAccount(err error, client *nex.Client, callID uint32, strPrincipalName string, strKey string, uiGroups uint32, strEmail string, oAuthData *nex.DataHolder) {
|
||||
if err != nil {
|
||||
// TODO: Handle error
|
||||
logger.Critical(err.Error())
|
||||
globals.Logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
var tokenBase64 string
|
||||
|
|
@ -40,7 +41,7 @@ func nintendoCreateAccount(err error, client *nex.Client, callID uint32, strPrin
|
|||
decryptedToken, err := decryptToken(encryptedToken)
|
||||
if err != nil {
|
||||
// TODO: Handle error
|
||||
logger.Critical(err.Error())
|
||||
globals.Logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
pid := decryptedToken.UserPID
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import (
|
|||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
)
|
||||
|
||||
|
|
@ -30,12 +32,12 @@ func nexServerStart() {
|
|||
|
||||
nexServer.On("Kick", func(packet *nex.PacketV0) {
|
||||
pid := packet.Sender().PID()
|
||||
delete(connectedUsers, pid)
|
||||
delete(globals.ConnectedUsers, pid)
|
||||
|
||||
lastOnline := nex.NewDateTime(0)
|
||||
lastOnline.FromTimestamp(time.Now())
|
||||
|
||||
updateUserLastOnlineTime(pid, lastOnline)
|
||||
database.UpdateUserLastOnlineTime(pid, lastOnline)
|
||||
sendUserWentOfflineWiiUNotifications(packet.Sender())
|
||||
|
||||
fmt.Println("Leaving")
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package main
|
|||
import (
|
||||
"os"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
)
|
||||
|
|
@ -11,7 +13,7 @@ func updateAndGetAllInformation(err error, client *nex.Client, callID uint32, nn
|
|||
|
||||
if err != nil {
|
||||
// TODO: Handle error
|
||||
logger.Critical(err.Error())
|
||||
globals.Logger.Critical(err.Error())
|
||||
}
|
||||
|
||||
// Update user information
|
||||
|
|
@ -24,16 +26,16 @@ func updateAndGetAllInformation(err error, client *nex.Client, callID uint32, nn
|
|||
// Get user information
|
||||
pid := client.PID()
|
||||
|
||||
connectedUsers[pid].NNAInfo = nnaInfo
|
||||
connectedUsers[pid].Presence = presence
|
||||
globals.ConnectedUsers[pid].NNAInfo = nnaInfo
|
||||
globals.ConnectedUsers[pid].Presence = presence
|
||||
|
||||
principalPreference := getUserPrincipalPreference(pid)
|
||||
comment := getUserComment(pid)
|
||||
friendList := getUserFriendList(pid)
|
||||
friendRequestsOut := getUserFriendRequestsOut(pid)
|
||||
friendRequestsIn := getUserFriendRequestsIn(pid)
|
||||
blockList := getUserBlockList(pid)
|
||||
notifications := getUserNotifications(pid)
|
||||
principalPreference := database.GetUserPrincipalPreference(pid)
|
||||
comment := database.GetUserComment(pid)
|
||||
friendList := database.GetUserFriendList(pid)
|
||||
friendRequestsOut := database.GetUserFriendRequestsOut(pid)
|
||||
friendRequestsIn := database.GetUserFriendRequestsIn(pid)
|
||||
blockList := database.GetUserBlockList(pid)
|
||||
notifications := database.GetUserNotifications(pid)
|
||||
|
||||
if os.Getenv("ENABLE_BELLA") == "true" {
|
||||
bella := nexproto.NewFriendInfo()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
)
|
||||
|
|
@ -8,7 +9,7 @@ import (
|
|||
func updateCommentWiiU(err error, client *nex.Client, callID uint32, comment *nexproto.Comment) {
|
||||
// TODO: Do something with this
|
||||
|
||||
changed := updateUserComment(client.PID(), comment.Contents)
|
||||
changed := database.UpdateUserComment(client.PID(), comment.Contents)
|
||||
|
||||
rmcResponseStream := nex.NewStreamOut(nexServer)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
)
|
||||
|
||||
func updatePreferenceWiiU(err error, client *nex.Client, callID uint32, principalPreference *nexproto.PrincipalPreference) {
|
||||
updateUserPrincipalPreference(client.PID(), principalPreference)
|
||||
database.UpdateUserPrincipalPreference(client.PID(), principalPreference)
|
||||
|
||||
rmcResponse := nex.NewRMCResponse(nexproto.FriendsWiiUProtocolID, callID)
|
||||
rmcResponse.SetSuccess(nexproto.FriendsWiiUMethodUpdatePreference, nil)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package main
|
|||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/PretendoNetwork/friends-secure/database"
|
||||
"github.com/PretendoNetwork/friends-secure/globals"
|
||||
nex "github.com/PretendoNetwork/nex-go"
|
||||
nexproto "github.com/PretendoNetwork/nex-protocols-go"
|
||||
)
|
||||
|
|
@ -13,7 +15,7 @@ func updatePresenceWiiU(err error, client *nex.Client, callID uint32, presence *
|
|||
presence.Online = true // Force online status. I have no idea why this is always false
|
||||
presence.PID = client.PID() // WHY IS THIS SET TO 0 BY DEFAULT??
|
||||
|
||||
connectedUsers[pid].Presence = presence
|
||||
globals.ConnectedUsers[pid].Presence = presence
|
||||
sendUpdatePresenceWiiUNotifications(presence)
|
||||
|
||||
rmcResponse := nex.NewRMCResponse(nexproto.FriendsWiiUProtocolID, callID)
|
||||
|
|
@ -54,7 +56,7 @@ func sendUpdatePresenceWiiUNotifications(presence *nexproto.NintendoPresenceV2)
|
|||
|
||||
rmcRequestBytes := rmcRequest.Bytes()
|
||||
|
||||
friendList := getUserFriendList(presence.PID)
|
||||
friendList := database.GetUserFriendList(presence.PID)
|
||||
|
||||
for i := 0; i < len(friendList); i++ {
|
||||
if friendList[i] == nil || friendList[i].NNAInfo == nil || friendList[i].NNAInfo.PrincipalBasicInfo == nil {
|
||||
|
|
@ -67,21 +69,21 @@ func sendUpdatePresenceWiiUNotifications(presence *nexproto.NintendoPresenceV2)
|
|||
friendPID = friendList[i].Presence.PID
|
||||
}
|
||||
|
||||
logger.Error(fmt.Sprintf("User %d has friend %d with bad presence data", pid, friendPID))
|
||||
globals.Logger.Error(fmt.Sprintf("User %d has friend %d with bad presence data", pid, friendPID))
|
||||
|
||||
if friendList[i] == nil {
|
||||
logger.Error(fmt.Sprintf("%d friendList[i] nil", friendPID))
|
||||
globals.Logger.Error(fmt.Sprintf("%d friendList[i] nil", friendPID))
|
||||
} else if friendList[i].NNAInfo == nil {
|
||||
logger.Error(fmt.Sprintf("%d friendList[i].NNAInfo is nil", friendPID))
|
||||
globals.Logger.Error(fmt.Sprintf("%d friendList[i].NNAInfo is nil", friendPID))
|
||||
} else if friendList[i].NNAInfo.PrincipalBasicInfo == nil {
|
||||
logger.Error(fmt.Sprintf("%d friendList[i].NNAInfo.PrincipalBasicInfo is nil", friendPID))
|
||||
globals.Logger.Error(fmt.Sprintf("%d friendList[i].NNAInfo.PrincipalBasicInfo is nil", friendPID))
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
friendPID := friendList[i].NNAInfo.PrincipalBasicInfo.PID
|
||||
connectedUser := connectedUsers[friendPID]
|
||||
connectedUser := globals.ConnectedUsers[friendPID]
|
||||
|
||||
if connectedUser != nil {
|
||||
requestPacket, _ := nex.NewPacketV0(connectedUser.Client, nil)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user