From b8ef7468703a806cd919cbbba12d64c9ea20cd61 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Thu, 23 Jul 2026 23:09:19 +0200 Subject: [PATCH 1/5] feat: implement splatoon ranking types and stub functions --- nex/ranking/get_competition_ranking_score.go | 39 ++++ .../types/competition_ranking_get_param.go | 134 +++++++++++++ .../types/competition_ranking_score_data.go | 172 ++++++++++++++++ .../types/competition_ranking_score_info.go | 163 +++++++++++++++ .../competition_ranking_upload_score_param.go | 185 ++++++++++++++++++ .../upload_competition_ranking_score.go | 36 ++++ ...register_common_secure_server_protocols.go | 3 + 7 files changed, 732 insertions(+) create mode 100644 nex/ranking/get_competition_ranking_score.go create mode 100644 nex/ranking/types/competition_ranking_get_param.go create mode 100644 nex/ranking/types/competition_ranking_score_data.go create mode 100644 nex/ranking/types/competition_ranking_score_info.go create mode 100644 nex/ranking/types/competition_ranking_upload_score_param.go create mode 100644 nex/ranking/upload_competition_ranking_score.go diff --git a/nex/ranking/get_competition_ranking_score.go b/nex/ranking/get_competition_ranking_score.go new file mode 100644 index 0000000..ac9d047 --- /dev/null +++ b/nex/ranking/get_competition_ranking_score.go @@ -0,0 +1,39 @@ +package nex_ranking_splaton + +import ( + "github.com/PretendoNetwork/nex-go/v2" + "github.com/PretendoNetwork/nex-go/v2/types" + 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" + ranking_splatoon_types "github.com/PretendoNetwork/splatoon/nex/ranking/types" +) + +func GetCompetitionRankingScore(err error, packet nex.PacketInterface, callID uint32, packetPayload []byte) (*nex.RMCMessage, *nex.Error) { + rmcResponseStream := nex.NewByteStreamOut(globals.SecureServer.LibraryVersions, globals.SecureServer.ByteStreamSettings) + + parameters := packet.RMCMessage().Parameters + parametersStream := nex.NewByteStreamIn(parameters, globals.SecureServer.LibraryVersions, globals.SecureServer.ByteStreamSettings) + + params := ranking_splatoon_types.NewCompetitionRankingGetParam() + + err = params.ExtractFrom(parametersStream) + if err != nil { + common_globals.Logger.Error("Failed to extract param on call to GetCompetitionRankingScore.") + common_globals.Logger.Error(err.Error()) + return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, err.Error()) + } + + // todo: actually implement this function + retVal := types.NewList[ranking_splatoon_types.CompetitionRankingScoreInfo]() + + retVal.WriteTo(rmcResponseStream) + + rmcResponse := nex.NewRMCSuccess(globals.SecureEndpoint, rmcResponseStream.Bytes()) + rmcResponse.ProtocolID = ranking.ProtocolID + rmcResponse.MethodID = ranking.MethodGetCompetitionRankingScore + rmcResponse.CallID = callID + + return rmcResponse, nil + +} diff --git a/nex/ranking/types/competition_ranking_get_param.go b/nex/ranking/types/competition_ranking_get_param.go new file mode 100644 index 0000000..a462532 --- /dev/null +++ b/nex/ranking/types/competition_ranking_get_param.go @@ -0,0 +1,134 @@ +// Package types implements all the types used by the Ranking protocol +package types + +import ( + "fmt" + "strings" + + "github.com/PretendoNetwork/nex-go/v2/types" +) + +// CompetitionRankingGetParam is a type within the Ranking protocol +type CompetitionRankingGetParam struct { + types.Structure + Unknown types.UInt32 + ResultRange types.ResultRange + FestivalIds types.List[types.UInt32] +} + +// WriteTo writes the CompetitionRankingGetParam to the given writable +func (crgp CompetitionRankingGetParam) WriteTo(writable types.Writable) { + contentWritable := writable.CopyNew() + + crgp.Unknown.WriteTo(contentWritable) + crgp.ResultRange.WriteTo(contentWritable) + crgp.FestivalIds.WriteTo(contentWritable) + + content := contentWritable.Bytes() + + crgp.WriteHeaderTo(writable, uint32(len(content))) + + writable.Write(content) +} + +// ExtractFrom extracts the CompetitionRankingGetParam from the given readable +func (crgp CompetitionRankingGetParam) ExtractFrom(readable types.Readable) error { + if err := crgp.ExtractHeaderFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingGetParam header. %s", err.Error()) + } + + if err := crgp.Unknown.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingGetParam.Unknown. %s", err.Error()) + } + + if err := crgp.ResultRange.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingGetParam.ResultRange. %s", err.Error()) + } + + if err := crgp.FestivalIds.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingGetParam.FestivalIds. %s", err.Error()) + } + + return nil +} + +// Copy returns a new copied instance of CompetitionRankingGetParam +func (crgp CompetitionRankingGetParam) Copy() types.RVType { + copied := NewCompetitionRankingGetParam() + + copied.StructureVersion = crgp.StructureVersion + copied.Unknown = crgp.Unknown.Copy().(types.UInt32) + copied.ResultRange = crgp.Copy().(types.ResultRange) + copied.FestivalIds = crgp.FestivalIds.Copy().(types.List[types.UInt32]) + + return copied +} + +// Equals checks if the given CompetitionRankingGetParam contains the same data as the current CompetitionRankingGetParam +func (crgp CompetitionRankingGetParam) Equals(o types.RVType) bool { + if _, ok := o.(CompetitionRankingGetParam); !ok { + return false + } + + other := o.(CompetitionRankingGetParam) + + if crgp.StructureVersion != other.StructureVersion { + return false + } + + if !crgp.Unknown.Equals(other.Unknown) { + return false + } + + if !crgp.ResultRange.Equals(other.ResultRange) { + return false + } + + return crgp.FestivalIds.Equals(other.FestivalIds) +} + +// CopyRef copies the current value of the CompetitionRankingGetParam +// and returns a pointer to the new copy +func (crgp CompetitionRankingGetParam) CopyRef() types.RVTypePtr { + copied := crgp.Copy().(CompetitionRankingGetParam) + return &copied +} + +// Deref takes a pointer to the CompetitionRankingGetParam +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (crgp *CompetitionRankingGetParam) Deref() types.RVType { + return *crgp +} + +// String returns the string representation of the CompetitionRankingGetParam +func (crgp CompetitionRankingGetParam) String() string { + return crgp.FormatToString(0) +} + +// FormatToString pretty-prints the CompetitionRankingGetParam using the provided indentation level +func (crgp CompetitionRankingGetParam) FormatToString(indentationLevel int) string { + indentationValues := strings.Repeat("\t", indentationLevel+1) + indentationEnd := strings.Repeat("\t", indentationLevel) + + var b strings.Builder + + b.WriteString("CompetitionRankingGetParam{\n") + fmt.Fprintf(&b, "%sUnknown: %s,\n", indentationValues, crgp.Unknown) + fmt.Fprintf(&b, "%sResultRange: %s,\n", indentationValues, crgp.ResultRange) + fmt.Fprintf(&b, "%sFestivalIds: %s,\n", indentationValues, crgp.FestivalIds) + fmt.Fprintf(&b, "%s}", indentationEnd) + + return b.String() +} + +// NewCompetitionRankingGetParam returns a new CompetitionRankingGetParam +func NewCompetitionRankingGetParam() CompetitionRankingGetParam { + return CompetitionRankingGetParam{ + Structure: types.Structure{StructureVersion: 1}, + Unknown: types.NewUInt32(0), + ResultRange: types.NewResultRange(), + FestivalIds: types.NewList[types.UInt32](), + } + +} diff --git a/nex/ranking/types/competition_ranking_score_data.go b/nex/ranking/types/competition_ranking_score_data.go new file mode 100644 index 0000000..9bf9a22 --- /dev/null +++ b/nex/ranking/types/competition_ranking_score_data.go @@ -0,0 +1,172 @@ +// Package types implements all the types used by the Ranking protocol +package types + +import ( + "fmt" + "strings" + + "github.com/PretendoNetwork/nex-go/v2/types" +) + +// CompetitionRankingScoreData is a type within the Ranking protocol +type CompetitionRankingScoreData struct { + types.Structure + Unknown1 types.UInt32 + PID types.PID + Score types.UInt32 + Modified types.DateTime + Unknown2 types.UInt8 + AppData types.QBuffer +} + +// WriteTo writes the CompetitionRankingScoreData to the given writable +func (crsd CompetitionRankingScoreData) WriteTo(writable types.Writable) { + contentWritable := writable.CopyNew() + + crsd.Unknown1.WriteTo(contentWritable) + crsd.PID.WriteTo(contentWritable) + crsd.Score.WriteTo(contentWritable) + crsd.Modified.WriteTo(contentWritable) + crsd.Unknown2.WriteTo(contentWritable) + crsd.AppData.WriteTo(contentWritable) + + content := contentWritable.Bytes() + + crsd.WriteHeaderTo(writable, uint32(len(content))) + + writable.Write(content) +} + +// ExtractFrom extracts the CompetitionRankingScoreData from the given readable +func (crsd CompetitionRankingScoreData) ExtractFrom(readable types.Readable) error { + if err := crsd.ExtractHeaderFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreData header. %s", err.Error()) + } + + if err := crsd.Unknown1.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreData.Unknown1. %s", err.Error()) + } + + if err := crsd.PID.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreData.PID. %s", err.Error()) + } + + if err := crsd.Score.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreData.Score. %s", err.Error()) + } + + if err := crsd.Modified.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreData.Modified. %s", err.Error()) + } + + if err := crsd.Unknown2.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreData.Unknown2. %s", err.Error()) + } + + if err := crsd.AppData.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreData.AppData. %s", err.Error()) + } + + return nil +} + +// Copy returns a new copied instance of CompetitionRankingScoreData +func (csrd CompetitionRankingScoreData) Copy() types.RVType { + copied := NewCompetitionRankingScoreData() + + copied.StructureVersion = csrd.StructureVersion + copied.Unknown1 = csrd.Unknown1.Copy().(types.UInt32) + copied.PID = csrd.PID.Copy().(types.PID) + copied.Score = csrd.Score.Copy().(types.UInt32) + copied.Modified = csrd.Modified.Copy().(types.DateTime) + copied.Unknown2 = csrd.Unknown2.Copy().(types.UInt8) + copied.AppData = csrd.AppData.Copy().(types.QBuffer) + + return copied +} + +// Equals checks if the given CompetitionRankingScoreData contains the same data as the current CompetitionRankingScoreData +func (csrd CompetitionRankingScoreData) Equals(o types.RVType) bool { + if _, ok := o.(CompetitionRankingScoreData); !ok { + return false + } + + other := o.(CompetitionRankingScoreData) + + if csrd.StructureVersion != other.StructureVersion { + return false + } + + if !csrd.Unknown1.Equals(other.Unknown1) { + return false + } + + if !csrd.PID.Equals(other.PID) { + return false + } + + if !csrd.Score.Equals(other.Score) { + return false + } + + if !csrd.Modified.Equals(other.Modified) { + return false + } + + if !csrd.Unknown2.Equals(other.Unknown2) { + return false + } + + return csrd.AppData.Equals(other.AppData) +} + +// CopyRef copies the current value of the CompetitionRankingScoreData +// and returns a pointer to the new copy +func (csrd CompetitionRankingScoreData) CopyRef() types.RVTypePtr { + copied := csrd.Copy().(CompetitionRankingScoreData) + return &copied +} + +// Deref takes a pointer to the CompetitionRankingScoreData +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (csrd *CompetitionRankingScoreData) Deref() types.RVType { + return *csrd +} + +// String returns the string representation of the CompetitionRankingScoreData +func (csrd CompetitionRankingScoreData) String() string { + return csrd.FormatToString(0) +} + +// FormatToString pretty-prints the CompetitionRankingScoreData using the provided indentation level +func (csrd CompetitionRankingScoreData) FormatToString(indentationLevel int) string { + indentationValues := strings.Repeat("\t", indentationLevel+1) + indentationEnd := strings.Repeat("\t", indentationLevel) + + var b strings.Builder + + b.WriteString("CompetitionRankingScoreData{\n") + fmt.Fprintf(&b, "%sUnknown1: %s,\n", indentationValues, csrd.Unknown1) + fmt.Fprintf(&b, "%sPID: %s,\n", indentationValues, csrd.PID) + fmt.Fprintf(&b, "%sScore: %s,\n", indentationValues, csrd.PID) + fmt.Fprintf(&b, "%sModified: %s,\n", indentationValues, csrd.Modified) + fmt.Fprintf(&b, "%ssUnknown2: %s,\n", indentationValues, csrd.Unknown2) + fmt.Fprintf(&b, "%sAppData: %s,\n", indentationValues, csrd.AppData) + fmt.Fprintf(&b, "%s}", indentationEnd) + + return b.String() +} + +// NewCompetitionRankingScoreData returns a new CompetitionRankingScoreData +func NewCompetitionRankingScoreData() CompetitionRankingScoreData { + return CompetitionRankingScoreData{ + Unknown1: types.NewUInt32(0), + PID: types.NewPID(0), + Score: types.NewUInt32(0), + Modified: types.NewDateTime(0), + Unknown2: types.NewUInt8(0), + AppData: types.NewQBuffer([]byte{}), + } + +} diff --git a/nex/ranking/types/competition_ranking_score_info.go b/nex/ranking/types/competition_ranking_score_info.go new file mode 100644 index 0000000..b0c6de1 --- /dev/null +++ b/nex/ranking/types/competition_ranking_score_info.go @@ -0,0 +1,163 @@ +// Package types implements all the types used by the Ranking protocol +package types + +import ( + "fmt" + "strings" + + "github.com/PretendoNetwork/nex-go/v2/types" +) + +// CompetitionRankingScoreInfo is a type within the Ranking protocol +type CompetitionRankingScoreInfo struct { + types.Structure + FestId types.UInt32 + ScoreData types.List[CompetitionRankingScoreData] + Unknown types.UInt32 + TeamWins types.List[types.UInt32] + TeamVotes types.List[types.UInt32] +} + +// WriteTo writes the CompetitionRankingScoreInfo to the given writable +func (crsi CompetitionRankingScoreInfo) WriteTo(writable types.Writable) { + contentWritable := writable.CopyNew() + + crsi.FestId.WriteTo(contentWritable) + crsi.ScoreData.WriteTo(contentWritable) + crsi.Unknown.WriteTo(contentWritable) + crsi.TeamWins.WriteTo(contentWritable) + crsi.TeamVotes.WriteTo(contentWritable) + + content := contentWritable.Bytes() + + crsi.WriteHeaderTo(writable, uint32(len(content))) + + writable.Write(content) +} + +// ExtractFrom extracts the CompetitionRankingScoreInfo from the given readable +func (crsi CompetitionRankingScoreInfo) ExtractFrom(readable types.Readable) error { + if err := crsi.ExtractHeaderFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreInfo header. %s", err.Error()) + } + + if err := crsi.FestId.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreInfo.FestId. %s", err.Error()) + } + + if err := crsi.ScoreData.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreInfo.ScoreData. %s", err.Error()) + } + + if err := crsi.Unknown.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreInfo.Unknown. %s", err.Error()) + } + + if err := crsi.TeamWins.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreInfo.TeamWins. %s", err.Error()) + } + + if err := crsi.TeamVotes.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingScoreInfo.TeamVotes. %s", err.Error()) + } + + return nil +} + +// Copy returns a new copied instance of CompetitionRankingScoreInfo +func (crsi CompetitionRankingScoreInfo) Copy() types.RVType { + copied := NewCompetitionRankingScoreInfo() + + copied.StructureVersion = crsi.StructureVersion + copied.FestId = crsi.FestId.Copy().(types.UInt32) + copied.ScoreData = crsi.ScoreData.Copy().(types.List[CompetitionRankingScoreData]) + copied.Unknown = crsi.Unknown.Copy().(types.UInt32) + copied.TeamWins = crsi.TeamWins.Copy().(types.List[types.UInt32]) + copied.TeamVotes = crsi.TeamVotes.Copy().(types.List[types.UInt32]) + + return copied +} + +// Equals checks if the given CompetitionRankingScoreInfo contains the same data as the current CompetitionRankingScoreInfo +func (crsi CompetitionRankingScoreInfo) Equals(o types.RVType) bool { + if _, ok := o.(CompetitionRankingScoreInfo); !ok { + return false + } + + other := o.(CompetitionRankingScoreInfo) + + if crsi.StructureVersion != other.StructureVersion { + return false + } + + if !crsi.FestId.Equals(other.FestId) { + return false + } + + if !crsi.ScoreData.Equals(other.ScoreData) { + return false + } + + if !crsi.Unknown.Equals(other.Unknown) { + return false + } + + if !crsi.TeamWins.Equals(other.TeamWins) { + return false + } + + if !crsi.TeamVotes.Equals(other.TeamVotes) { + return false + } + + return crsi.TeamVotes.Equals(other.TeamVotes) +} + +// CopyRef copies the current value of the CompetitionRankingScoreInfo +// and returns a pointer to the new copy +func (crsi CompetitionRankingScoreInfo) CopyRef() types.RVTypePtr { + copied := crsi.Copy().(CompetitionRankingScoreInfo) + return &copied +} + +// Deref takes a pointer to the CompetitionRankingScoreInfo +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (crsi *CompetitionRankingScoreInfo) Deref() types.RVType { + return *crsi +} + +// String returns the string representation of the CompetitionRankingScoreInfo +func (crsi CompetitionRankingScoreInfo) String() string { + return crsi.FormatToString(0) +} + +// FormatToString pretty-prints the CompetitionRankingScoreInfo using the provided indentation level +func (crsi CompetitionRankingScoreInfo) FormatToString(indentationLevel int) string { + indentationValues := strings.Repeat("\t", indentationLevel+1) + indentationEnd := strings.Repeat("\t", indentationLevel) + + var b strings.Builder + + b.WriteString("CompetitionRankingScoreInfo{\n") + fmt.Fprintf(&b, "%sFestId: %s,\n", indentationValues, crsi.FestId) + fmt.Fprintf(&b, "%sScoreData: %s,\n", indentationValues, crsi.ScoreData) + fmt.Fprintf(&b, "%sUnknown: %s,\n", indentationValues, crsi.Unknown) + fmt.Fprintf(&b, "%sTeamWins: %s,\n", indentationValues, crsi.TeamWins) + fmt.Fprintf(&b, "%sTeamVotes: %s,\n", indentationValues, crsi.TeamVotes) + fmt.Fprintf(&b, "%s}", indentationEnd) + + return b.String() +} + +// NewCompetitionRankingScoreInfo returns a new CompetitionRankingScoreInfo +func NewCompetitionRankingScoreInfo() CompetitionRankingScoreInfo { + return CompetitionRankingScoreInfo{ + FestId: types.NewUInt32(0), + ScoreData: types.NewList[CompetitionRankingScoreData](), + Unknown: types.NewUInt32(0), + TeamWins: types.NewList[types.UInt32](), + TeamVotes: types.NewList[types.UInt32](), + } + +} diff --git a/nex/ranking/types/competition_ranking_upload_score_param.go b/nex/ranking/types/competition_ranking_upload_score_param.go new file mode 100644 index 0000000..aba1924 --- /dev/null +++ b/nex/ranking/types/competition_ranking_upload_score_param.go @@ -0,0 +1,185 @@ +// Package types implements all the types used by the Ranking protocol +package types + +import ( + "fmt" + "strings" + + "github.com/PretendoNetwork/nex-go/v2/types" +) + +// CompetitionRankingUploadScoreParam is a type within the Ranking protocol +type CompetitionRankingUploadScoreParam struct { + types.Structure + Unknown1 types.UInt32 + SplatfestId types.UInt32 + Unknown2 types.UInt32 + Score types.UInt32 + TeamId types.UInt8 + TeamWin types.UInt8 + IsFirstUpload types.Bool + AppData types.QBuffer +} + +// WriteTo writes the CompetitionRankingUploadScoreParam to the given writable +func (crusp CompetitionRankingUploadScoreParam) WriteTo(writable types.Writable) { + contentWritable := writable.CopyNew() + + crusp.Unknown1.WriteTo(contentWritable) + crusp.SplatfestId.WriteTo(contentWritable) + crusp.Unknown2.WriteTo(contentWritable) + crusp.Score.WriteTo(contentWritable) + crusp.TeamId.WriteTo(contentWritable) + crusp.TeamWin.WriteTo(contentWritable) + crusp.IsFirstUpload.WriteTo(contentWritable) + crusp.AppData.WriteTo(contentWritable) + + content := contentWritable.Bytes() + + crusp.WriteHeaderTo(writable, uint32(len(content))) + + writable.Write(content) +} + +// ExtractFrom extracts the CompetitionRankingUploadScoreParam from the given readable +func (crusp CompetitionRankingUploadScoreParam) ExtractFrom(readable types.Readable) error { + if err := crusp.ExtractHeaderFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam header. %s", err.Error()) + } + + if err := crusp.Unknown1.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.Unknown1. %s", err.Error()) + } + if err := crusp.SplatfestId.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.SplatfestId. %s", err.Error()) + } + if err := crusp.Unknown2.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.Unknown2. %s", err.Error()) + } + if err := crusp.Score.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.Score. %s", err.Error()) + } + 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 { + return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.TeamWin. %s", err.Error()) + } + if err := crusp.IsFirstUpload.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.IsFirstUpload. %s", err.Error()) + } + if err := crusp.AppData.ExtractFrom(readable); err != nil { + return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.AppData. %s", err.Error()) + } + + return nil +} + +// Copy returns a new copied instance of CompetitionRankingUploadScoreParam +func (crusp CompetitionRankingUploadScoreParam) Copy() types.RVType { + copied := NewCompetitionRankingUploadScoreParam() + + copied.StructureVersion = crusp.StructureVersion + copied.Unknown1 = crusp.Unknown1.Copy().(types.UInt32) + copied.SplatfestId = crusp.SplatfestId.Copy().(types.UInt32) + 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.IsFirstUpload = crusp.IsFirstUpload.Copy().(types.Bool) + copied.AppData = crusp.AppData.Copy().(types.QBuffer) + + return copied +} + +// Equals checks if the given CompetitionRankingUploadScoreParam contains the same data as the current CompetitionRankingUploadScoreParam +func (crusp CompetitionRankingUploadScoreParam) Equals(o types.RVType) bool { + if _, ok := o.(CompetitionRankingUploadScoreParam); !ok { + return false + } + + other := o.(CompetitionRankingUploadScoreParam) + + if crusp.StructureVersion != other.StructureVersion { + return false + } + + if !crusp.Unknown1.Equals(other.Unknown1) { + return false + } + if !crusp.SplatfestId.Equals(other.SplatfestId) { + return false + } + if !crusp.Unknown2.Equals(other.Unknown2) { + return false + } + if !crusp.Score.Equals(other.Score) { + return false + } + if !crusp.TeamId.Equals(other.TeamId) { + return false + } + if !crusp.TeamWin.Equals(other.TeamWin) { + return false + } + if !crusp.IsFirstUpload.Equals(other.IsFirstUpload) { + return false + } + + return crusp.AppData.Equals(other.AppData) +} + +// CopyRef copies the current value of the CompetitionRankingUploadScoreParam +// and returns a pointer to the new copy +func (crusp CompetitionRankingUploadScoreParam) CopyRef() types.RVTypePtr { + copied := crusp.Copy().(CompetitionRankingScoreInfo) + return &copied +} + +// Deref takes a pointer to the CompetitionRankingUploadScoreParam +// and dereferences it to the raw value. +// Only useful when working with an instance of RVTypePtr +func (crusp *CompetitionRankingUploadScoreParam) Deref() types.RVType { + return *crusp +} + +// String returns the string representation of the CompetitionRankingUploadScoreParam +func (crusp CompetitionRankingUploadScoreParam) String() string { + return crusp.FormatToString(0) +} + +// FormatToString pretty-prints the CompetitionRankingUploadScoreParam using the provided indentation level +func (crusp CompetitionRankingUploadScoreParam) FormatToString(indentationLevel int) string { + indentationValues := strings.Repeat("\t", indentationLevel+1) + indentationEnd := strings.Repeat("\t", indentationLevel) + + var b strings.Builder + + b.WriteString("CompetitionRankingUploadScoreParam{\n") + fmt.Fprintf(&b, "%sUnknown1: %s,\n", indentationValues, crusp.Unknown1) + fmt.Fprintf(&b, "%sSplatfestId: %s,\n", indentationValues, crusp.SplatfestId) + 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, "%sIsFirstUpload: %s,\n", indentationValues, crusp.IsFirstUpload) + fmt.Fprintf(&b, "%sAppData: %s,\n", indentationValues, crusp.AppData) + fmt.Fprintf(&b, "%s}", indentationEnd) + + return b.String() +} + +// CompetitionRankingUploadScoreParam returns a new CompetitionRankingUploadScoreParam +func NewCompetitionRankingUploadScoreParam() CompetitionRankingUploadScoreParam { + return CompetitionRankingUploadScoreParam{ + Unknown1: types.NewUInt32(0), + SplatfestId: types.NewUInt32(0), + Unknown2: types.NewUInt32(0), + Score: types.NewUInt32(0), + TeamId: types.NewUInt8(0), + TeamWin: types.NewUInt8(0), + IsFirstUpload: types.NewBool(false), + AppData: types.NewQBuffer([]byte{}), + } + +} diff --git a/nex/ranking/upload_competition_ranking_score.go b/nex/ranking/upload_competition_ranking_score.go new file mode 100644 index 0000000..5d1e3db --- /dev/null +++ b/nex/ranking/upload_competition_ranking_score.go @@ -0,0 +1,36 @@ +package nex_ranking_splaton + +import ( + "github.com/PretendoNetwork/nex-go/v2" + "github.com/PretendoNetwork/nex-go/v2/types" + 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" + ranking_splatoon_types "github.com/PretendoNetwork/splatoon/nex/ranking/types" +) + +func UploadCompetitionRankingScore(err error, packet nex.PacketInterface, callID uint32, packetPayload []byte) (*nex.RMCMessage, *nex.Error) { + rmcResponseStream := nex.NewByteStreamOut(globals.SecureServer.LibraryVersions, globals.SecureServer.ByteStreamSettings) + + parameters := packet.RMCMessage().Parameters + parametersStream := nex.NewByteStreamIn(parameters, globals.SecureServer.LibraryVersions, globals.SecureServer.ByteStreamSettings) + + params := ranking_splatoon_types.NewCompetitionRankingUploadScoreParam() + + err = params.ExtractFrom(parametersStream) + if err != nil { + common_globals.Logger.Error("Failed to extract param on call to UploadCompetitionRankingScore.") + common_globals.Logger.Error(err.Error()) + return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, err.Error()) + } + + types.NewBool(false).WriteTo(rmcResponseStream) + + rmcResponse := nex.NewRMCSuccess(globals.SecureEndpoint, rmcResponseStream.Bytes()) + rmcResponse.ProtocolID = ranking.ProtocolID + rmcResponse.MethodID = ranking.MethodGetCompetitionRankingScore + rmcResponse.CallID = callID + + return rmcResponse, nil + +} diff --git a/nex/register_common_secure_server_protocols.go b/nex/register_common_secure_server_protocols.go index 7e6cb85..48be6fd 100644 --- a/nex/register_common_secure_server_protocols.go +++ b/nex/register_common_secure_server_protocols.go @@ -16,6 +16,7 @@ import ( ranking "github.com/PretendoNetwork/nex-protocols-go/v2/ranking/splatoon" secure "github.com/PretendoNetwork/nex-protocols-go/v2/secure-connection" "github.com/PretendoNetwork/splatoon/globals" + ranking_impl "github.com/PretendoNetwork/splatoon/nex/ranking" ) func CreateReportDBRecord(_ types.PID, _ types.UInt32, _ types.QBuffer) error { @@ -57,5 +58,7 @@ func registerCommonSecureServerProtocols() { rankingProtocol := ranking.NewProtocol(globals.SecureEndpoint) globals.SecureEndpoint.RegisterServiceProtocol(rankingProtocol) + rankingProtocol.GetCompetitionRankingScore = ranking_impl.GetCompetitionRankingScore + rankingProtocol.UploadCompetitionRankingScore = ranking_impl.UploadCompetitionRankingScore commonranking.NewCommonProtocol(rankingProtocol) } From 3ccda9ed2618577ca0efe5bc12668e1d9561d97e Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Wed, 29 Jul 2026 00:29:18 +0200 Subject: [PATCH 2/5] feat: implement splatoon ranking functions --- .../database/get_user_score_entries.go | 38 ++++++++++++ nex/ranking/database/get_vote_count.go | 23 ++++++++ nex/ranking/database/get_win_count.go | 28 +++++++++ nex/ranking/database/setup.go | 37 ++++++++++++ .../database/store_user_match_result.go | 25 ++++++++ nex/ranking/database/store_user_score.go | 33 +++++++++++ nex/ranking/get_competition_ranking_score.go | 58 ++++++++++++++++++- .../competition_ranking_upload_score_param.go | 14 ++--- .../upload_competition_ranking_score.go | 6 +- ...register_common_secure_server_protocols.go | 12 ++++ 10 files changed, 265 insertions(+), 9 deletions(-) create mode 100644 nex/ranking/database/get_user_score_entries.go create mode 100644 nex/ranking/database/get_vote_count.go create mode 100644 nex/ranking/database/get_win_count.go create mode 100644 nex/ranking/database/setup.go create mode 100644 nex/ranking/database/store_user_match_result.go create mode 100644 nex/ranking/database/store_user_score.go diff --git a/nex/ranking/database/get_user_score_entries.go b/nex/ranking/database/get_user_score_entries.go new file mode 100644 index 0000000..920033a --- /dev/null +++ b/nex/ranking/database/get_user_score_entries.go @@ -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 +} diff --git a/nex/ranking/database/get_vote_count.go b/nex/ranking/database/get_vote_count.go new file mode 100644 index 0000000..9cb74b7 --- /dev/null +++ b/nex/ranking/database/get_vote_count.go @@ -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 +} diff --git a/nex/ranking/database/get_win_count.go b/nex/ranking/database/get_win_count.go new file mode 100644 index 0000000..504b788 --- /dev/null +++ b/nex/ranking/database/get_win_count.go @@ -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 +} diff --git a/nex/ranking/database/setup.go b/nex/ranking/database/setup.go new file mode 100644 index 0000000..509f4c7 --- /dev/null +++ b/nex/ranking/database/setup.go @@ -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 + } +} diff --git a/nex/ranking/database/store_user_match_result.go b/nex/ranking/database/store_user_match_result.go new file mode 100644 index 0000000..f7b87c3 --- /dev/null +++ b/nex/ranking/database/store_user_match_result.go @@ -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 +} diff --git a/nex/ranking/database/store_user_score.go b/nex/ranking/database/store_user_score.go new file mode 100644 index 0000000..c9c215a --- /dev/null +++ b/nex/ranking/database/store_user_score.go @@ -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 +} diff --git a/nex/ranking/get_competition_ranking_score.go b/nex/ranking/get_competition_ranking_score.go index ac9d047..327202a 100644 --- a/nex/ranking/get_competition_ranking_score.go +++ b/nex/ranking/get_competition_ranking_score.go @@ -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) diff --git a/nex/ranking/types/competition_ranking_upload_score_param.go b/nex/ranking/types/competition_ranking_upload_score_param.go index aba1924..9b40e1f 100644 --- a/nex/ranking/types/competition_ranking_upload_score_param.go +++ b/nex/ranking/types/competition_ranking_upload_score_param.go @@ -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{}), } diff --git a/nex/ranking/upload_competition_ranking_score.go b/nex/ranking/upload_competition_ranking_score.go index 5d1e3db..885707f 100644 --- a/nex/ranking/upload_competition_ranking_score.go +++ b/nex/ranking/upload_competition_ranking_score.go @@ -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 diff --git a/nex/register_common_secure_server_protocols.go b/nex/register_common_secure_server_protocols.go index 48be6fd..185e72a 100644 --- a/nex/register_common_secure_server_protocols.go +++ b/nex/register_common_secure_server_protocols.go @@ -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() From 81dfc8b1131919e69d607f8bb4d12cec958923b7 Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Fri, 31 Jul 2026 14:43:28 +0200 Subject: [PATCH 3/5] fix: change HasWon to TeamScore, limit request entries to 1 and merge sql queries --- .../database/get_vote_and_win_count.go | 46 +++++++++++++++++++ nex/ranking/database/get_vote_count.go | 23 ---------- nex/ranking/database/get_win_count.go | 28 ----------- nex/ranking/database/setup.go | 6 ++- .../database/store_user_match_result.go | 4 +- nex/ranking/get_competition_ranking_score.go | 46 ++++++------------- .../competition_ranking_upload_score_param.go | 14 +++--- 7 files changed, 72 insertions(+), 95 deletions(-) create mode 100644 nex/ranking/database/get_vote_and_win_count.go delete mode 100644 nex/ranking/database/get_vote_count.go delete mode 100644 nex/ranking/database/get_win_count.go diff --git a/nex/ranking/database/get_vote_and_win_count.go b/nex/ranking/database/get_vote_and_win_count.go new file mode 100644 index 0000000..6be9118 --- /dev/null +++ b/nex/ranking/database/get_vote_and_win_count.go @@ -0,0 +1,46 @@ +package database + +import ( + "github.com/PretendoNetwork/nex-go/v2/types" + "github.com/PretendoNetwork/splatoon/globals" +) + +// might be better to just return a struct here cause its not immediately obbvious from the signature which is which +func GetVoteAndWinCount(splatfestID uint32) (types.List[types.UInt32], types.List[types.UInt32], error) { + row := globals.Postgres.QueryRow(`SELECT + (SELECT + COUNT(user_id) + FROM ranking_splatoon.user_scores WHERE splatfest_id=$1 AND team_id=0) as alpha_team_votes, + (SELECT + COUNT(user_id) + FROM ranking_splatoon.user_scores WHERE splatfest_id=$1 AND team_id=1) as bravo_team_votes, + (SELECT + SUM(team_score) + FROM ranking_splatoon.results + WHERE splatfest_id=$1 + AND team_id=1 + ) as alpha_team_wins, + (SELECT + COUNT(team_score) + FROM ranking_splatoon.results + WHERE splatfest_id=$1 + AND team_id=1 + ) as bravo_team_wins + `, uint64(splatfestID)) + + if row.Err() != nil { + return types.NewList[types.UInt32](), types.NewList[types.UInt32](), row.Err() + } + var alpha_team_votes uint32 + var bravo_team_votes uint32 + var alpha_team_wins uint32 + var bravo_team_wins uint32 + + err := row.Scan(&alpha_team_votes, &bravo_team_votes, &alpha_team_wins, &bravo_team_wins) + if err != nil { + return types.NewList[types.UInt32](), types.NewList[types.UInt32](), err + } + + return types.List[types.UInt32]{types.NewUInt32(alpha_team_votes), types.NewUInt32(bravo_team_votes)}, + types.List[types.UInt32]{types.NewUInt32(alpha_team_wins), types.NewUInt32(bravo_team_wins)}, nil +} diff --git a/nex/ranking/database/get_vote_count.go b/nex/ranking/database/get_vote_count.go deleted file mode 100644 index 9cb74b7..0000000 --- a/nex/ranking/database/get_vote_count.go +++ /dev/null @@ -1,23 +0,0 @@ -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 -} diff --git a/nex/ranking/database/get_win_count.go b/nex/ranking/database/get_win_count.go deleted file mode 100644 index 504b788..0000000 --- a/nex/ranking/database/get_win_count.go +++ /dev/null @@ -1,28 +0,0 @@ -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 -} diff --git a/nex/ranking/database/setup.go b/nex/ranking/database/setup.go index 509f4c7..7679d3f 100644 --- a/nex/ranking/database/setup.go +++ b/nex/ranking/database/setup.go @@ -18,8 +18,9 @@ func Setup() { uploader_pid int8 not null, splatfest_id int8 not null, team_id int2 not null, - has_won int2 not null, + team_score int8 not null, app_data bytea not null, + created_at timestamp not null default now() )`) _, err = globals.Postgres.Exec(`CREATE TABLE IF NOT EXISTS ranking_splatoon.user_scores ( uploader_pid int8 not null, @@ -27,7 +28,8 @@ func Setup() { score int8 not null, team_id boolean not null, user_data bytea not null, - last_updated int8 not null + last_updated int8 not null, + created_at timestamp not null default now(), PRIMARY KEY(uploader_pid, splatfest_id) )`) if err != nil { diff --git a/nex/ranking/database/store_user_match_result.go b/nex/ranking/database/store_user_match_result.go index f7b87c3..271fcc1 100644 --- a/nex/ranking/database/store_user_match_result.go +++ b/nex/ranking/database/store_user_match_result.go @@ -14,9 +14,9 @@ func StoreUserMatchResult(userPID types.PID, data ranking_splatoon_types.Competi splatfest_id, score, team_id, - has_won + team_score ) VALUES ($1, $2, $3, $4, $5) - `, int64(userPID), int64(data.SplatfestId), int64(data.Score), int16(data.TeamId), bool(data.HasWon)) + `, int64(userPID), int64(data.SplatfestId), int64(data.Score), int16(data.TeamId), int64(data.TeamScore)) if err != nil { return err diff --git a/nex/ranking/get_competition_ranking_score.go b/nex/ranking/get_competition_ranking_score.go index 327202a..05cafa9 100644 --- a/nex/ranking/get_competition_ranking_score.go +++ b/nex/ranking/get_competition_ranking_score.go @@ -16,33 +16,14 @@ func GetSingleCompetitionRankingScore(splatfestID uint32) (ranking_splatoon_type 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)) + team_wins, team_votes, err := database.GetVoteAndWinCount(splatfestID) - 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)) + info.TeamWins = types.List[types.UInt32](team_wins) + info.TeamVotes = types.List[types.UInt32](team_votes) var scoreDataEntries []ranking_splatoon_types.CompetitionRankingScoreData scoreDataEntries, err = database.GetScoreDataEntries(splatfestID) @@ -70,19 +51,18 @@ func GetCompetitionRankingScore(err error, packet nex.PacketInterface, callID ui } 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) + + if uint32(params.ResultRange.Offset) >= uint32(len(params.FestivalIds)) { + return nil, nex.NewError(nex.ResultCodes.Core.InvalidArgument, "out of resultrange is out of bounds") } + festId := params.FestivalIds[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) rmcResponse := nex.NewRMCSuccess(globals.SecureEndpoint, rmcResponseStream.Bytes()) diff --git a/nex/ranking/types/competition_ranking_upload_score_param.go b/nex/ranking/types/competition_ranking_upload_score_param.go index 9b40e1f..c0e52ed 100644 --- a/nex/ranking/types/competition_ranking_upload_score_param.go +++ b/nex/ranking/types/competition_ranking_upload_score_param.go @@ -16,7 +16,7 @@ type CompetitionRankingUploadScoreParam struct { Unknown2 types.UInt32 Score types.UInt32 TeamId types.UInt8 - HasWon types.Bool + TeamScore types.UInt32 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.HasWon.WriteTo(contentWritable) + crusp.TeamScore.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.HasWon.ExtractFrom(readable); err != nil { + if err := crusp.TeamScore.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.HasWon = crusp.HasWon.Copy().(types.Bool) + copied.TeamScore = crusp.TeamScore.Copy().(types.UInt32) 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.HasWon.Equals(other.HasWon) { + if !crusp.TeamScore.Equals(other.TeamScore) { 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, "%sHasWon: %s,\n", indentationValues, crusp.HasWon) + fmt.Fprintf(&b, "%TeamScore: %s,\n", indentationValues, crusp.TeamScore) 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), - HasWon: types.NewBool(false), + TeamScore: types.NewUInt32(0), IsFirstUpload: types.NewBool(false), AppData: types.NewQBuffer([]byte{}), } From f2364776c66b461b3052157a1995b5e4d99d40ae Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Fri, 31 Jul 2026 14:57:11 +0200 Subject: [PATCH 4/5] fix: remove experimental stationurl order adjustment --- nex/register_common_secure_server_protocols.go | 9 --------- 1 file changed, 9 deletions(-) diff --git a/nex/register_common_secure_server_protocols.go b/nex/register_common_secure_server_protocols.go index 185e72a..119049e 100644 --- a/nex/register_common_secure_server_protocols.go +++ b/nex/register_common_secure_server_protocols.go @@ -1,9 +1,6 @@ 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" @@ -33,11 +30,6 @@ 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() @@ -45,7 +37,6 @@ func registerCommonSecureServerProtocols() { globals.SecureEndpoint.RegisterServiceProtocol(secureProtocol) commonSecureProtocol := commonsecure.NewCommonProtocol(secureProtocol) commonSecureProtocol.EnableInsecureRegister() - commonSecureProtocol.OnAfterRegisterEx = adjustPublicStationFirst commonSecureProtocol.CreateReportDBRecord = CreateReportDBRecord natTraversalProtocol := nattraversal.NewProtocol() From ec414108d50f2378e921441ebd4804827ee8c38e Mon Sep 17 00:00:00 2001 From: Maple Nebel Date: Sun, 2 Aug 2026 12:58:55 +0200 Subject: [PATCH 5/5] chore: change Id to ID --- nex/ranking/database/store_user_match_result.go | 2 +- nex/ranking/get_competition_ranking_score.go | 2 +- .../types/competition_ranking_score_info.go | 14 +++++++------- .../competition_ranking_upload_score_param.go | 14 +++++++------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/nex/ranking/database/store_user_match_result.go b/nex/ranking/database/store_user_match_result.go index 271fcc1..5cf1f3d 100644 --- a/nex/ranking/database/store_user_match_result.go +++ b/nex/ranking/database/store_user_match_result.go @@ -16,7 +16,7 @@ func StoreUserMatchResult(userPID types.PID, data ranking_splatoon_types.Competi team_id, team_score ) VALUES ($1, $2, $3, $4, $5) - `, int64(userPID), int64(data.SplatfestId), int64(data.Score), int16(data.TeamId), int64(data.TeamScore)) + `, int64(userPID), int64(data.SplatfestId), int64(data.Score), int16(data.TeamID), int64(data.TeamScore)) if err != nil { return err diff --git a/nex/ranking/get_competition_ranking_score.go b/nex/ranking/get_competition_ranking_score.go index 05cafa9..49893dd 100644 --- a/nex/ranking/get_competition_ranking_score.go +++ b/nex/ranking/get_competition_ranking_score.go @@ -14,7 +14,7 @@ func GetSingleCompetitionRankingScore(splatfestID uint32) (ranking_splatoon_type var err error info := ranking_splatoon_types.NewCompetitionRankingScoreInfo() - info.FestId = types.UInt32(splatfestID) + info.FestID = types.UInt32(splatfestID) team_wins, team_votes, err := database.GetVoteAndWinCount(splatfestID) diff --git a/nex/ranking/types/competition_ranking_score_info.go b/nex/ranking/types/competition_ranking_score_info.go index b0c6de1..64c86dc 100644 --- a/nex/ranking/types/competition_ranking_score_info.go +++ b/nex/ranking/types/competition_ranking_score_info.go @@ -11,7 +11,7 @@ import ( // CompetitionRankingScoreInfo is a type within the Ranking protocol type CompetitionRankingScoreInfo struct { types.Structure - FestId types.UInt32 + FestID types.UInt32 ScoreData types.List[CompetitionRankingScoreData] Unknown types.UInt32 TeamWins types.List[types.UInt32] @@ -22,7 +22,7 @@ type CompetitionRankingScoreInfo struct { func (crsi CompetitionRankingScoreInfo) WriteTo(writable types.Writable) { contentWritable := writable.CopyNew() - crsi.FestId.WriteTo(contentWritable) + crsi.FestID.WriteTo(contentWritable) crsi.ScoreData.WriteTo(contentWritable) crsi.Unknown.WriteTo(contentWritable) crsi.TeamWins.WriteTo(contentWritable) @@ -41,7 +41,7 @@ func (crsi CompetitionRankingScoreInfo) ExtractFrom(readable types.Readable) err return fmt.Errorf("failed to extract CompetitionRankingScoreInfo header. %s", err.Error()) } - if err := crsi.FestId.ExtractFrom(readable); err != nil { + if err := crsi.FestID.ExtractFrom(readable); err != nil { return fmt.Errorf("failed to extract CompetitionRankingScoreInfo.FestId. %s", err.Error()) } @@ -69,7 +69,7 @@ func (crsi CompetitionRankingScoreInfo) Copy() types.RVType { copied := NewCompetitionRankingScoreInfo() copied.StructureVersion = crsi.StructureVersion - copied.FestId = crsi.FestId.Copy().(types.UInt32) + copied.FestID = crsi.FestID.Copy().(types.UInt32) copied.ScoreData = crsi.ScoreData.Copy().(types.List[CompetitionRankingScoreData]) copied.Unknown = crsi.Unknown.Copy().(types.UInt32) copied.TeamWins = crsi.TeamWins.Copy().(types.List[types.UInt32]) @@ -90,7 +90,7 @@ func (crsi CompetitionRankingScoreInfo) Equals(o types.RVType) bool { return false } - if !crsi.FestId.Equals(other.FestId) { + if !crsi.FestID.Equals(other.FestID) { return false } @@ -140,7 +140,7 @@ func (crsi CompetitionRankingScoreInfo) FormatToString(indentationLevel int) str var b strings.Builder b.WriteString("CompetitionRankingScoreInfo{\n") - fmt.Fprintf(&b, "%sFestId: %s,\n", indentationValues, crsi.FestId) + fmt.Fprintf(&b, "%sFestId: %s,\n", indentationValues, crsi.FestID) fmt.Fprintf(&b, "%sScoreData: %s,\n", indentationValues, crsi.ScoreData) fmt.Fprintf(&b, "%sUnknown: %s,\n", indentationValues, crsi.Unknown) fmt.Fprintf(&b, "%sTeamWins: %s,\n", indentationValues, crsi.TeamWins) @@ -153,7 +153,7 @@ func (crsi CompetitionRankingScoreInfo) FormatToString(indentationLevel int) str // NewCompetitionRankingScoreInfo returns a new CompetitionRankingScoreInfo func NewCompetitionRankingScoreInfo() CompetitionRankingScoreInfo { return CompetitionRankingScoreInfo{ - FestId: types.NewUInt32(0), + FestID: types.NewUInt32(0), ScoreData: types.NewList[CompetitionRankingScoreData](), Unknown: types.NewUInt32(0), TeamWins: types.NewList[types.UInt32](), diff --git a/nex/ranking/types/competition_ranking_upload_score_param.go b/nex/ranking/types/competition_ranking_upload_score_param.go index c0e52ed..60dfa98 100644 --- a/nex/ranking/types/competition_ranking_upload_score_param.go +++ b/nex/ranking/types/competition_ranking_upload_score_param.go @@ -15,7 +15,7 @@ type CompetitionRankingUploadScoreParam struct { SplatfestId types.UInt32 Unknown2 types.UInt32 Score types.UInt32 - TeamId types.UInt8 + TeamID types.UInt8 TeamScore types.UInt32 IsFirstUpload types.Bool AppData types.QBuffer @@ -29,7 +29,7 @@ func (crusp CompetitionRankingUploadScoreParam) WriteTo(writable types.Writable) crusp.SplatfestId.WriteTo(contentWritable) crusp.Unknown2.WriteTo(contentWritable) crusp.Score.WriteTo(contentWritable) - crusp.TeamId.WriteTo(contentWritable) + crusp.TeamID.WriteTo(contentWritable) crusp.TeamScore.WriteTo(contentWritable) crusp.IsFirstUpload.WriteTo(contentWritable) crusp.AppData.WriteTo(contentWritable) @@ -59,7 +59,7 @@ func (crusp CompetitionRankingUploadScoreParam) ExtractFrom(readable types.Reada if err := crusp.Score.ExtractFrom(readable); err != nil { return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.Score. %s", err.Error()) } - if err := crusp.TeamId.ExtractFrom(readable); err != nil { + if err := crusp.TeamID.ExtractFrom(readable); err != nil { return fmt.Errorf("failed to extract CompetitionRankingUploadScoreParam.TeamId. %s", err.Error()) } if err := crusp.TeamScore.ExtractFrom(readable); err != nil { @@ -84,7 +84,7 @@ func (crusp CompetitionRankingUploadScoreParam) Copy() types.RVType { copied.SplatfestId = crusp.SplatfestId.Copy().(types.UInt32) copied.Unknown2 = crusp.Unknown2.Copy().(types.UInt32) copied.Score = crusp.Score.Copy().(types.UInt32) - copied.TeamId = crusp.TeamId.Copy().(types.UInt8) + copied.TeamID = crusp.TeamID.Copy().(types.UInt8) copied.TeamScore = crusp.TeamScore.Copy().(types.UInt32) copied.IsFirstUpload = crusp.IsFirstUpload.Copy().(types.Bool) copied.AppData = crusp.AppData.Copy().(types.QBuffer) @@ -116,7 +116,7 @@ func (crusp CompetitionRankingUploadScoreParam) Equals(o types.RVType) bool { if !crusp.Score.Equals(other.Score) { return false } - if !crusp.TeamId.Equals(other.TeamId) { + if !crusp.TeamID.Equals(other.TeamID) { return false } if !crusp.TeamScore.Equals(other.TeamScore) { @@ -160,7 +160,7 @@ func (crusp CompetitionRankingUploadScoreParam) FormatToString(indentationLevel fmt.Fprintf(&b, "%sSplatfestId: %s,\n", indentationValues, crusp.SplatfestId) 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, "%sTeamId: %s,\n", indentationValues, crusp.TeamID) fmt.Fprintf(&b, "%TeamScore: %s,\n", indentationValues, crusp.TeamScore) fmt.Fprintf(&b, "%sIsFirstUpload: %s,\n", indentationValues, crusp.IsFirstUpload) fmt.Fprintf(&b, "%sAppData: %s,\n", indentationValues, crusp.AppData) @@ -176,7 +176,7 @@ func NewCompetitionRankingUploadScoreParam() CompetitionRankingUploadScoreParam SplatfestId: types.NewUInt32(0), Unknown2: types.NewUInt32(0), Score: types.NewUInt32(0), - TeamId: types.NewUInt8(0), + TeamID: types.NewUInt8(0), TeamScore: types.NewUInt32(0), IsFirstUpload: types.NewBool(false), AppData: types.NewQBuffer([]byte{}),