mirror of
https://github.com/PretendoNetwork/splatoon.git
synced 2026-08-02 16:13:42 -05:00
feat: implement splatoon ranking functions
This commit is contained in:
parent
b8ef746870
commit
3ccda9ed26
38
nex/ranking/database/get_user_score_entries.go
Normal file
38
nex/ranking/database/get_user_score_entries.go
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/splatoon/globals"
|
||||
ranking_splatoon_types "github.com/PretendoNetwork/splatoon/nex/ranking/types"
|
||||
)
|
||||
|
||||
func GetScoreDataEntries(splatfestID uint32) ([]ranking_splatoon_types.CompetitionRankingScoreData, error) {
|
||||
list := []ranking_splatoon_types.CompetitionRankingScoreData{}
|
||||
|
||||
stream, err := globals.Postgres.Query(`SELECT
|
||||
uploader_pid,
|
||||
score,
|
||||
last_updated,
|
||||
app_data
|
||||
FROM ranking_splatoon.user_scores WHERE splatfest_id=$1`, uint64(splatfestID))
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for stream.Next() {
|
||||
competitionRankingScoreData := ranking_splatoon_types.NewCompetitionRankingScoreData()
|
||||
err = stream.Scan(&competitionRankingScoreData.PID, &competitionRankingScoreData.Score, &competitionRankingScoreData.Modified, &competitionRankingScoreData.AppData)
|
||||
if err != nil {
|
||||
stream.Close()
|
||||
return nil, err
|
||||
}
|
||||
list = append(list, competitionRankingScoreData)
|
||||
}
|
||||
|
||||
err = stream.Err()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return list, nil
|
||||
}
|
||||
23
nex/ranking/database/get_vote_count.go
Normal file
23
nex/ranking/database/get_vote_count.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/splatoon/globals"
|
||||
)
|
||||
|
||||
func GetVoteCount(splatfestID uint32, team_id uint8) (uint32, error) {
|
||||
row := globals.Postgres.QueryRow(`SELECT
|
||||
COUNT(user_id)
|
||||
FROM ranking_splatoon.user_scores WHERE splatfest_id=$1 AND team_id=$2`, uint64(splatfestID), int16(team_id))
|
||||
|
||||
if row.Err() != nil {
|
||||
return 0, row.Err()
|
||||
}
|
||||
var count uint32
|
||||
|
||||
err := row.Scan(&count)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
28
nex/ranking/database/get_win_count.go
Normal file
28
nex/ranking/database/get_win_count.go
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/splatoon/globals"
|
||||
)
|
||||
|
||||
func GetWinCount(splatfestID uint32, team_id uint8) (uint32, error) {
|
||||
row := globals.Postgres.QueryRow(`SELECT
|
||||
COUNT(upload_id)
|
||||
FROM ranking_splatoon.results
|
||||
WHERE splatfest_id=$1
|
||||
AND (
|
||||
(has_won = false AND team_id NOT EQUAL $2) OR
|
||||
(has_won = true AND team_id=$2)
|
||||
)`, uint64(splatfestID), int16(team_id))
|
||||
|
||||
if row.Err() != nil {
|
||||
return 0, row.Err()
|
||||
}
|
||||
var count uint32
|
||||
|
||||
err := row.Scan(&count)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
37
nex/ranking/database/setup.go
Normal file
37
nex/ranking/database/setup.go
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/splatoon/globals"
|
||||
)
|
||||
|
||||
func Setup() {
|
||||
var err error
|
||||
|
||||
_, err = globals.Postgres.Exec(`CREATE SCHEMA IF NOT EXISTS ranking_splatoon`)
|
||||
if err != nil {
|
||||
globals.Logger.Error(err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
_, err = globals.Postgres.Exec(`CREATE TABLE IF NOT EXISTS ranking_splatoon.results (
|
||||
upload_id bigserial primary key not null,
|
||||
uploader_pid int8 not null,
|
||||
splatfest_id int8 not null,
|
||||
team_id int2 not null,
|
||||
has_won int2 not null,
|
||||
app_data bytea not null,
|
||||
)`)
|
||||
_, err = globals.Postgres.Exec(`CREATE TABLE IF NOT EXISTS ranking_splatoon.user_scores (
|
||||
uploader_pid int8 not null,
|
||||
splatfest_id int8 not null,
|
||||
score int8 not null,
|
||||
team_id boolean not null,
|
||||
user_data bytea not null,
|
||||
last_updated int8 not null
|
||||
PRIMARY KEY(uploader_pid, splatfest_id)
|
||||
)`)
|
||||
if err != nil {
|
||||
globals.Logger.Error(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
25
nex/ranking/database/store_user_match_result.go
Normal file
25
nex/ranking/database/store_user_match_result.go
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/nex-go/v2/types"
|
||||
"github.com/PretendoNetwork/splatoon/globals"
|
||||
ranking_splatoon_types "github.com/PretendoNetwork/splatoon/nex/ranking/types"
|
||||
)
|
||||
|
||||
func StoreUserMatchResult(userPID types.PID, data ranking_splatoon_types.CompetitionRankingUploadScoreParam) error {
|
||||
var err error
|
||||
_, err = globals.Postgres.Exec(`
|
||||
INSERT INTO ranking_splatoon.results(
|
||||
uploader_pid,
|
||||
splatfest_id,
|
||||
score,
|
||||
team_id,
|
||||
has_won
|
||||
) VALUES ($1, $2, $3, $4, $5)
|
||||
`, int64(userPID), int64(data.SplatfestId), int64(data.Score), int16(data.TeamId), bool(data.HasWon))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
33
nex/ranking/database/store_user_score.go
Normal file
33
nex/ranking/database/store_user_score.go
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
package database
|
||||
|
||||
import (
|
||||
"github.com/PretendoNetwork/nex-go/v2/types"
|
||||
"github.com/PretendoNetwork/splatoon/globals"
|
||||
ranking_splatoon_types "github.com/PretendoNetwork/splatoon/nex/ranking/types"
|
||||
)
|
||||
|
||||
func StoreUserScore(userPID types.PID, data ranking_splatoon_types.CompetitionRankingUploadScoreParam) error {
|
||||
var err error
|
||||
time := types.NewDateTime(0).Now()
|
||||
_, err = globals.Postgres.Exec(`
|
||||
INSERT INTO ranking_splatoon.user_scores(
|
||||
uploader_pid,
|
||||
splatfest_id,
|
||||
score,
|
||||
team_id,
|
||||
last_updated,
|
||||
app_data
|
||||
) VALUES ($1, $2, $3, $4, $5, $6)
|
||||
ON CONFLICT (uploader_pid, splatfest_id)
|
||||
DO UPDATE SET
|
||||
score = EXCLUDED.score,
|
||||
last_updated = EXCLUDED.last_updated
|
||||
team_id = EXCLUDED.team_id
|
||||
app_data = EXCLUDED.app_data
|
||||
`, int64(userPID), int64(data.SplatfestId), int64(data.Score), int16(data.TeamId), int64(time), ([]byte)(data.AppData))
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
@ -6,9 +6,54 @@ import (
|
|||
common_globals "github.com/PretendoNetwork/nex-protocols-common-go/v2/globals"
|
||||
ranking "github.com/PretendoNetwork/nex-protocols-go/v2/ranking/splatoon"
|
||||
"github.com/PretendoNetwork/splatoon/globals"
|
||||
"github.com/PretendoNetwork/splatoon/nex/ranking/database"
|
||||
ranking_splatoon_types "github.com/PretendoNetwork/splatoon/nex/ranking/types"
|
||||
)
|
||||
|
||||
func GetSingleCompetitionRankingScore(splatfestID uint32) (ranking_splatoon_types.CompetitionRankingScoreInfo, error) {
|
||||
var err error
|
||||
info := ranking_splatoon_types.NewCompetitionRankingScoreInfo()
|
||||
|
||||
info.FestId = types.UInt32(splatfestID)
|
||||
|
||||
var team_alpha_count uint32
|
||||
team_alpha_count, err = database.GetVoteCount(splatfestID, 0)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
info.TeamVotes = append(info.TeamVotes, types.UInt32(team_alpha_count))
|
||||
|
||||
var team_bravo_count uint32
|
||||
team_bravo_count, err = database.GetVoteCount(splatfestID, 1)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
info.TeamVotes = append(info.TeamVotes, types.UInt32(team_bravo_count))
|
||||
|
||||
var team_alpha_wins uint32
|
||||
team_alpha_wins, err = database.GetWinCount(splatfestID, 0)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
info.TeamWins = append(info.TeamWins, types.UInt32(team_alpha_wins))
|
||||
|
||||
var team_bravo_wins uint32
|
||||
team_bravo_wins, err = database.GetVoteCount(splatfestID, 1)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
info.TeamWins = append(info.TeamWins, types.UInt32(team_bravo_wins))
|
||||
|
||||
var scoreDataEntries []ranking_splatoon_types.CompetitionRankingScoreData
|
||||
scoreDataEntries, err = database.GetScoreDataEntries(splatfestID)
|
||||
if err != nil {
|
||||
return info, err
|
||||
}
|
||||
info.ScoreData = scoreDataEntries
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
func GetCompetitionRankingScore(err error, packet nex.PacketInterface, callID uint32, packetPayload []byte) (*nex.RMCMessage, *nex.Error) {
|
||||
rmcResponseStream := nex.NewByteStreamOut(globals.SecureServer.LibraryVersions, globals.SecureServer.ByteStreamSettings)
|
||||
|
||||
|
|
@ -24,8 +69,19 @@ func GetCompetitionRankingScore(err error, packet nex.PacketInterface, callID ui
|
|||
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
// todo: actually implement this function
|
||||
retVal := types.NewList[ranking_splatoon_types.CompetitionRankingScoreInfo]()
|
||||
var festListIndex uint32
|
||||
for festListIndex = 0; festListIndex < uint32(params.ResultRange.Length); festListIndex++ {
|
||||
if festListIndex >= uint32(len(params.FestivalIds)) {
|
||||
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, "out of resultrange is out of bounds")
|
||||
}
|
||||
festId := params.FestivalIds[festListIndex+uint32(params.ResultRange.Offset)]
|
||||
info, err := GetSingleCompetitionRankingScore(uint32(festId))
|
||||
if err != nil {
|
||||
return nil, nex.NewError(nex.ResultCodes.Core.Exception, "error retrieving ranking scores")
|
||||
}
|
||||
retVal = append(retVal, info)
|
||||
}
|
||||
|
||||
retVal.WriteTo(rmcResponseStream)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ type CompetitionRankingUploadScoreParam struct {
|
|||
Unknown2 types.UInt32
|
||||
Score types.UInt32
|
||||
TeamId types.UInt8
|
||||
TeamWin types.UInt8
|
||||
HasWon types.Bool
|
||||
IsFirstUpload types.Bool
|
||||
AppData types.QBuffer
|
||||
}
|
||||
|
|
@ -30,7 +30,7 @@ func (crusp CompetitionRankingUploadScoreParam) WriteTo(writable types.Writable)
|
|||
crusp.Unknown2.WriteTo(contentWritable)
|
||||
crusp.Score.WriteTo(contentWritable)
|
||||
crusp.TeamId.WriteTo(contentWritable)
|
||||
crusp.TeamWin.WriteTo(contentWritable)
|
||||
crusp.HasWon.WriteTo(contentWritable)
|
||||
crusp.IsFirstUpload.WriteTo(contentWritable)
|
||||
crusp.AppData.WriteTo(contentWritable)
|
||||
|
||||
|
|
@ -62,7 +62,7 @@ func (crusp CompetitionRankingUploadScoreParam) ExtractFrom(readable types.Reada
|
|||
if err := crusp.TeamId.ExtractFrom(readable); err != nil {
|
||||
return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.TeamId. %s", err.Error())
|
||||
}
|
||||
if err := crusp.TeamWin.ExtractFrom(readable); err != nil {
|
||||
if err := crusp.HasWon.ExtractFrom(readable); err != nil {
|
||||
return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.TeamWin. %s", err.Error())
|
||||
}
|
||||
if err := crusp.IsFirstUpload.ExtractFrom(readable); err != nil {
|
||||
|
|
@ -85,7 +85,7 @@ func (crusp CompetitionRankingUploadScoreParam) Copy() types.RVType {
|
|||
copied.Unknown2 = crusp.Unknown2.Copy().(types.UInt32)
|
||||
copied.Score = crusp.Score.Copy().(types.UInt32)
|
||||
copied.TeamId = crusp.TeamId.Copy().(types.UInt8)
|
||||
copied.TeamWin = crusp.TeamWin.Copy().(types.UInt8)
|
||||
copied.HasWon = crusp.HasWon.Copy().(types.Bool)
|
||||
copied.IsFirstUpload = crusp.IsFirstUpload.Copy().(types.Bool)
|
||||
copied.AppData = crusp.AppData.Copy().(types.QBuffer)
|
||||
|
||||
|
|
@ -119,7 +119,7 @@ func (crusp CompetitionRankingUploadScoreParam) Equals(o types.RVType) bool {
|
|||
if !crusp.TeamId.Equals(other.TeamId) {
|
||||
return false
|
||||
}
|
||||
if !crusp.TeamWin.Equals(other.TeamWin) {
|
||||
if !crusp.HasWon.Equals(other.HasWon) {
|
||||
return false
|
||||
}
|
||||
if !crusp.IsFirstUpload.Equals(other.IsFirstUpload) {
|
||||
|
|
@ -161,7 +161,7 @@ func (crusp CompetitionRankingUploadScoreParam) FormatToString(indentationLevel
|
|||
fmt.Fprintf(&b, "%sUnknown2: %s,\n", indentationValues, crusp.Unknown2)
|
||||
fmt.Fprintf(&b, "%sScore: %s,\n", indentationValues, crusp.Score)
|
||||
fmt.Fprintf(&b, "%sTeamId: %s,\n", indentationValues, crusp.TeamId)
|
||||
fmt.Fprintf(&b, "%sTeamWin: %s,\n", indentationValues, crusp.TeamWin)
|
||||
fmt.Fprintf(&b, "%sHasWon: %s,\n", indentationValues, crusp.HasWon)
|
||||
fmt.Fprintf(&b, "%sIsFirstUpload: %s,\n", indentationValues, crusp.IsFirstUpload)
|
||||
fmt.Fprintf(&b, "%sAppData: %s,\n", indentationValues, crusp.AppData)
|
||||
fmt.Fprintf(&b, "%s}", indentationEnd)
|
||||
|
|
@ -177,7 +177,7 @@ func NewCompetitionRankingUploadScoreParam() CompetitionRankingUploadScoreParam
|
|||
Unknown2: types.NewUInt32(0),
|
||||
Score: types.NewUInt32(0),
|
||||
TeamId: types.NewUInt8(0),
|
||||
TeamWin: types.NewUInt8(0),
|
||||
HasWon: types.NewBool(false),
|
||||
IsFirstUpload: types.NewBool(false),
|
||||
AppData: types.NewQBuffer([]byte{}),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import (
|
|||
common_globals "github.com/PretendoNetwork/nex-protocols-common-go/v2/globals"
|
||||
ranking "github.com/PretendoNetwork/nex-protocols-go/v2/ranking/splatoon"
|
||||
"github.com/PretendoNetwork/splatoon/globals"
|
||||
"github.com/PretendoNetwork/splatoon/nex/ranking/database"
|
||||
ranking_splatoon_types "github.com/PretendoNetwork/splatoon/nex/ranking/types"
|
||||
)
|
||||
|
||||
|
|
@ -24,7 +25,10 @@ func UploadCompetitionRankingScore(err error, packet nex.PacketInterface, callID
|
|||
return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, err.Error())
|
||||
}
|
||||
|
||||
types.NewBool(false).WriteTo(rmcResponseStream)
|
||||
database.StoreUserMatchResult(packet.Sender().PID(), params)
|
||||
database.StoreUserScore(packet.Sender().PID(), params)
|
||||
|
||||
types.NewBool(true).WriteTo(rmcResponseStream)
|
||||
|
||||
rmcResponse := nex.NewRMCSuccess(globals.SecureEndpoint, rmcResponseStream.Bytes())
|
||||
rmcResponse.ProtocolID = ranking.ProtocolID
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
package nex
|
||||
|
||||
import (
|
||||
"slices"
|
||||
|
||||
"github.com/PretendoNetwork/nex-go/v2"
|
||||
"github.com/PretendoNetwork/nex-go/v2/types"
|
||||
commonmatchmaking "github.com/PretendoNetwork/nex-protocols-common-go/v2/match-making"
|
||||
commonmatchmakingext "github.com/PretendoNetwork/nex-protocols-common-go/v2/match-making-ext"
|
||||
|
|
@ -17,6 +20,7 @@ import (
|
|||
secure "github.com/PretendoNetwork/nex-protocols-go/v2/secure-connection"
|
||||
"github.com/PretendoNetwork/splatoon/globals"
|
||||
ranking_impl "github.com/PretendoNetwork/splatoon/nex/ranking"
|
||||
"github.com/PretendoNetwork/splatoon/nex/ranking/database"
|
||||
)
|
||||
|
||||
func CreateReportDBRecord(_ types.PID, _ types.UInt32, _ types.QBuffer) error {
|
||||
|
|
@ -29,11 +33,19 @@ func cleanupMatchmakeSessionSearchCriteriasHandler(searchCriterias types.List[ma
|
|||
}
|
||||
}
|
||||
|
||||
func adjustPublicStationFirst(packet nex.PacketInterface, urls types.List[types.StationURL], dataHolder types.DataHolder) {
|
||||
connection := packet.Sender().(*nex.PRUDPConnection)
|
||||
slices.Reverse(connection.StationURLs)
|
||||
}
|
||||
|
||||
func registerCommonSecureServerProtocols() {
|
||||
database.Setup()
|
||||
|
||||
secureProtocol := secure.NewProtocol()
|
||||
globals.SecureEndpoint.RegisterServiceProtocol(secureProtocol)
|
||||
commonSecureProtocol := commonsecure.NewCommonProtocol(secureProtocol)
|
||||
commonSecureProtocol.EnableInsecureRegister()
|
||||
commonSecureProtocol.OnAfterRegisterEx = adjustPublicStationFirst
|
||||
commonSecureProtocol.CreateReportDBRecord = CreateReportDBRecord
|
||||
|
||||
natTraversalProtocol := nattraversal.NewProtocol()
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user