Skip to content

Commit

Permalink
Merge pull request #12 from DaniElectra/revamp
Browse files Browse the repository at this point in the history
Lots of changes on common protocols
  • Loading branch information
jonbarrow authored Jun 17, 2023
2 parents 618b185 + eaad0fc commit 0342dc2
Show file tree
Hide file tree
Showing 24 changed files with 428 additions and 291 deletions.
19 changes: 16 additions & 3 deletions authentication/generate_ticket.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,28 @@ func generateTicket(userPID uint32, targetPID uint32) ([]byte, uint32) {
rand.Read(sessionKey)

ticketInternalData := nex.NewKerberosTicketInternalData()
ticketInternalData.SetTimestamp(nex.NewDateTime(0)) // CHANGE THIS
serverTime := nex.NewDateTime(0)
serverTime.UTC()
ticketInternalData.SetTimestamp(serverTime)
ticketInternalData.SetUserPID(userPID)
ticketInternalData.SetSessionKey(sessionKey)
encryptedTicketInternalData := ticketInternalData.Encrypt(targetKey, nex.NewStreamOut(commonAuthenticationProtocol.server))

encryptedTicketInternalData, err := ticketInternalData.Encrypt(targetKey, nex.NewStreamOut(commonAuthenticationProtocol.server))
if err != nil {
logger.Error(err.Error())
return []byte{}, nex.Errors.Authentication.Unknown
}

ticket := nex.NewKerberosTicket()
ticket.SetSessionKey(sessionKey)
ticket.SetTargetPID(targetPID)
ticket.SetInternalData(encryptedTicketInternalData)

return ticket.Encrypt(userKey, nex.NewStreamOut(commonAuthenticationProtocol.server)), 0
encryptedTicket, err := ticket.Encrypt(userKey, nex.NewStreamOut(commonAuthenticationProtocol.server))
if err != nil {
logger.Error(err.Error())
return []byte{}, nex.Errors.Authentication.Unknown
}

return encryptedTicket, 0
}
2 changes: 1 addition & 1 deletion authentication/login_ex.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
"github.com/PretendoNetwork/nex-protocols-go/authentication"
)

func loginEx(err error, client *nex.Client, callID uint32, username string, authenticationInfo *authentication.AuthenticationInfo) {
func loginEx(err error, client *nex.Client, callID uint32, username string, oExtraData *nex.DataHolder) {
var userPID uint32

if username == "guest" {
Expand Down
1 change: 1 addition & 0 deletions authentication/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package authentication

import (
"github.com/PretendoNetwork/nex-go"
_ "github.com/PretendoNetwork/nex-protocols-go"
"github.com/PretendoNetwork/nex-protocols-go/authentication"
"github.com/PretendoNetwork/plogger-go"
)
Expand Down
65 changes: 48 additions & 17 deletions globals/matchmaking_globals.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,62 @@
package common_globals
import (
match_making "github.com/PretendoNetwork/nex-protocols-go/match-making"
"math"
"reflect"

match_making "github.com/PretendoNetwork/nex-protocols-go/match-making"
)

type CommonMatchmakeSession struct {
GameMatchmakeSession match_making.MatchmakeSession //used by the game, contains the current state of the MatchmakeSession
SearchMatchmakeSession match_making.MatchmakeSession //used by the server when searching for matches, contains the state of the MatchmakeSession during the search process for easy compares
ConnectionIDs []uint32 //players in the room, referenced by their connection IDs. This is used instead of the PID in order to ensure we're talking to the correct client (in case of e.g. multiple logins)
GameMatchmakeSession *match_making.MatchmakeSession // Used by the game, contains the current state of the MatchmakeSession
SearchMatchmakeSession *match_making.MatchmakeSession // Used by the server when searching for matches, contains the state of the MatchmakeSession during the search process for easy compares
ConnectionIDs []uint32 // Players in the room, referenced by their connection IDs. This is used instead of the PID in order to ensure we're talking to the correct client (in case of e.g. multiple logins)
}

var Sessions map[uint32]*CommonMatchmakeSession
var CurrentGatheringID uint32

// GetSessionIndex returns a gathering ID which doesn't belong to any session
func GetSessionIndex() uint32 {
var gatheringID uint32 = 1
for gatheringID < math.MaxUint32 {
// If the session does not exist, the gathering ID is empty and can be used
if _, ok := Sessions[gatheringID]; !ok {
return gatheringID
}

gatheringID++
}

return 0
}

// DeleteIndex removes a value from a slice with the given index
func DeleteIndex(s []uint32, index int) []uint32 {
return append(s[:index], s[index+1:]...)
s[index] = s[len(s)-1]
return s[:len(s)-1]
}

// FindOtherConnectionID searches a connection ID on the gathering that isn't the given one
func FindOtherConnectionID(myConnectionID uint32, gathering uint32) uint32 {
for _, connectionID := range Sessions[gathering].ConnectionIDs {
if connectionID != myConnectionID {
return connectionID
}
}
return 0
}

// RemoveConnectionIDFromRoom removes a client from the gathering
func RemoveConnectionIDFromRoom(clientConnectionID uint32, gathering uint32) {
for index, connectionID := range Sessions[gathering].ConnectionIDs {
if connectionID == clientConnectionID {
Sessions[gathering].ConnectionIDs = DeleteIndex(Sessions[gathering].ConnectionIDs, index)
}
}
if len(Sessions[gathering].ConnectionIDs) == 0 {
delete(Sessions, gathering)
delete(Sessions, gathering)
}
}

// FindClientSession searches the gathering where the client is on
func FindClientSession(clientConnectionID uint32) uint32 {
for gatheringID := range Sessions {
for _, connectionID := range Sessions[gatheringID].ConnectionIDs {
Expand All @@ -37,22 +65,25 @@ func FindClientSession(clientConnectionID uint32) uint32 {
}
}
}
return math.MaxUint32
return 0
}

// RemoveConnectionIDFromAllSessions removes a client from every session
func RemoveConnectionIDFromAllSessions(clientConnectionID uint32) {
foundSession := FindClientSession(clientConnectionID)
if(foundSession != math.MaxUint32){
RemoveConnectionIDFromRoom(clientConnectionID, foundSession)
if foundSession != 0 {
RemoveConnectionIDFromRoom(clientConnectionID, uint32(foundSession))
}
}

func FindSearchMatchmakeSession(searchMatchmakeSession match_making.MatchmakeSession) int {
returnSessionIndex := math.MaxUint32
//this portion finds any sessions that match the search session. It does not care about anything beyond that, such as if the match is already full. This is handled below.
// SearchGatheringWithMatchmakeSession finds a gathering that matches with a MatchmakeSession
func SearchGatheringWithMatchmakeSession(searchMatchmakeSession *match_making.MatchmakeSession) uint32 {
var returnSessionIndex uint32 = 0

// This portion finds any sessions that match the search session. It does not care about anything beyond that, such as if the match is already full. This is handled below.
candidateSessionIndexes := make([]uint32, 0, len(Sessions))
for index, session := range Sessions {
if reflect.DeepEqual(session.SearchMatchmakeSession, searchMatchmakeSession) { // TODO - for Jon: Equals in StructureInterface
if session.SearchMatchmakeSession.Equals(searchMatchmakeSession) {
candidateSessionIndexes = append(candidateSessionIndexes, index)
}
}
Expand All @@ -61,9 +92,9 @@ func FindSearchMatchmakeSession(searchMatchmakeSession match_making.MatchmakeSes
if len(sessionToCheck.ConnectionIDs) >= int(sessionToCheck.GameMatchmakeSession.MaximumParticipants) {
continue
} else {
returnSessionIndex = int(sessionIndex) //found a match
returnSessionIndex = sessionIndex //found a match
break
}
}
return returnSessionIndex
}
}
6 changes: 3 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ module github.com/PretendoNetwork/nex-protocols-common-go
go 1.19

require (
github.com/PretendoNetwork/nex-go v1.0.22
github.com/PretendoNetwork/nex-protocols-go v1.0.26
github.com/PretendoNetwork/nex-go v1.0.26
github.com/PretendoNetwork/nex-protocols-go v1.0.32
github.com/PretendoNetwork/plogger-go v1.0.2
)

require (
github.com/fatih/color v1.15.0 // indirect
github.com/jwalton/go-supportscolor v1.1.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.18 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/superwhiskers/crunch/v3 v3.5.7 // indirect
golang.org/x/sys v0.8.0 // indirect
golang.org/x/term v0.8.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
github.com/PretendoNetwork/nex-go v1.0.22 h1:BXUvnp++muen86t2Iv47h2ZCX8xWMw00p8nTzS57zRE=
github.com/PretendoNetwork/nex-go v1.0.22/go.mod h1:Bx2ONeSefnbJyE0IDIwGopxrjRrnszOV/uQv74Cx+m0=
github.com/PretendoNetwork/nex-protocols-go v1.0.26 h1:jscXlgcyz1xZVY4kyR2m9366uof8pm9msf+IOtK6tVU=
github.com/PretendoNetwork/nex-protocols-go v1.0.26/go.mod h1:Rg3dwo0dU+uujoI9q1kcQkDiSYKpuew0xF8ojIaUPm0=
github.com/PretendoNetwork/nex-go v1.0.26 h1:lJqDS5F8s836xcQzCEI5hNvUesmTsh2NGDC4tZvG250=
github.com/PretendoNetwork/nex-go v1.0.26/go.mod h1:qzc5s4iNrt1ubS9Axb38b2jPuEsiETN2mDijn+MthmI=
github.com/PretendoNetwork/nex-protocols-go v1.0.32 h1:FdZwpzDdhNLSX1DVQIK91b8a+QI7Z6ow7hYlbMEjBYI=
github.com/PretendoNetwork/nex-protocols-go v1.0.32/go.mod h1:Pw1u2rsZGXuv45iM9y/7nZ5TBr1L5hctv9ylNXlW1ws=
github.com/PretendoNetwork/plogger-go v1.0.2 h1:vWKEnEmJJzYwqLxLyiSsAvCrZV6qnnu/a0GQOjIfzY0=
github.com/PretendoNetwork/plogger-go v1.0.2/go.mod h1:7kD6M4vPq1JL4LTuPg6kuB1OvUBOwQOtAvTaUwMbwvU=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
Expand All @@ -12,8 +12,8 @@ github.com/jwalton/go-supportscolor v1.1.0/go.mod h1:hFVUAZV2cWg+WFFC4v8pT2X/S2q
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/superwhiskers/crunch/v3 v3.5.7 h1:N9RLxaR65C36i26BUIpzPXGy2f6pQ7wisu2bawbKNqg=
github.com/superwhiskers/crunch/v3 v3.5.7/go.mod h1:4ub2EKgF1MAhTjoOCTU4b9uLMsAweHEa89aRrfAypXA=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
Expand Down
60 changes: 38 additions & 22 deletions matchmake-extension/auto_matchmake_postpone.go
Original file line number Diff line number Diff line change
@@ -1,48 +1,64 @@
package matchmake_extension

import (
"math"

nex "github.com/PretendoNetwork/nex-go"
match_making "github.com/PretendoNetwork/nex-protocols-go/match-making"
matchmake_extension "github.com/PretendoNetwork/nex-protocols-go/matchmake-extension"
"github.com/PretendoNetwork/nex-protocols-go/notifications"
common_globals "github.com/PretendoNetwork/nex-protocols-common-go/globals"
"encoding/json"
)

func AutoMatchmake_Postpone(err error, client *nex.Client, callID uint32, matchmakeSession *match_making.MatchmakeSession, message string) {
func autoMatchmake_Postpone(err error, client *nex.Client, callID uint32, anyGathering *nex.DataHolder, message string) {
server := commonMatchmakeExtensionProtocol.server
if commonMatchmakeExtensionProtocol.CleanupSearchMatchmakeSessionHandler == nil {
if commonMatchmakeExtensionProtocol.cleanupSearchMatchmakeSessionHandler == nil {
logger.Warning("MatchmakeExtension::AutoMatchmake_Postpone missing CleanupSearchMatchmakeSessionHandler!")
return
}
//This is the best way I found to copy the full object. And I still hate it.
// TODO - for Jon: Copy in MatchmakeSession (and anything else that needs it)
tmp, _ := json.Marshal(matchmakeSession)
matchmakeSessionCopy := match_making.NewMatchmakeSession()
json.Unmarshal(tmp, &matchmakeSessionCopy)
searchMatchmakeSession := commonMatchmakeExtensionProtocol.CleanupSearchMatchmakeSessionHandler(*matchmakeSessionCopy)
sessionIndex := uint32(common_globals.FindSearchMatchmakeSession(searchMatchmakeSession))
if sessionIndex == math.MaxUint32 {

// A client may disconnect from a session without leaving reliably,
// so let's make sure the client is removed from the session
common_globals.RemoveConnectionIDFromAllSessions(client.ConnectionID())

var matchmakeSession *match_making.MatchmakeSession
anyGatheringDataType := anyGathering.TypeName()

if anyGatheringDataType == "MatchmakeSession" {
matchmakeSession = anyGathering.ObjectData().(*match_making.MatchmakeSession)
}

searchMatchmakeSession := matchmakeSession.Copy().(*match_making.MatchmakeSession)
commonMatchmakeExtensionProtocol.cleanupSearchMatchmakeSessionHandler(searchMatchmakeSession)
sessionIndex := common_globals.SearchGatheringWithMatchmakeSession(searchMatchmakeSession)
if sessionIndex == 0 {
sessionIndex = common_globals.GetSessionIndex()
// This should in theory be impossible, as there aren't enough PIDs creating sessions to fill the uint32 limit.
// If we ever get here, we must be not deleting sessions properly
if sessionIndex == 0 {
logger.Critical("No gatherings available!")
return
}

session := common_globals.CommonMatchmakeSession{
SearchMatchmakeSession: searchMatchmakeSession,
GameMatchmakeSession: *matchmakeSession,
GameMatchmakeSession: matchmakeSession,
}
sessionIndex = common_globals.CurrentGatheringID

common_globals.Sessions[sessionIndex] = &session
common_globals.Sessions[sessionIndex].GameMatchmakeSession.Gathering.ID = uint32(sessionIndex)
common_globals.Sessions[sessionIndex].GameMatchmakeSession.Gathering.ID = sessionIndex
common_globals.Sessions[sessionIndex].GameMatchmakeSession.Gathering.OwnerPID = client.PID()
common_globals.Sessions[sessionIndex].GameMatchmakeSession.Gathering.HostPID = client.PID()
common_globals.CurrentGatheringID++

common_globals.Sessions[sessionIndex].GameMatchmakeSession.StartedTime = nex.NewDateTime(0)
common_globals.Sessions[sessionIndex].GameMatchmakeSession.StartedTime.UTC()
}

common_globals.Sessions[sessionIndex].ConnectionIDs = append(common_globals.Sessions[sessionIndex].ConnectionIDs, client.ConnectionID())
common_globals.Sessions[sessionIndex].GameMatchmakeSession.ParticipationCount = uint32(len(common_globals.Sessions[sessionIndex].ConnectionIDs))

rmcResponseStream := nex.NewStreamOut(server)
matchmakeDataHolder := nex.NewDataHolder()
matchmakeDataHolder.SetTypeName("MatchmakeSession")
matchmakeDataHolder.SetObjectData(&common_globals.Sessions[sessionIndex].GameMatchmakeSession)
matchmakeDataHolder.SetObjectData(common_globals.Sessions[sessionIndex].GameMatchmakeSession)
rmcResponseStream.WriteDataHolder(matchmakeDataHolder)

rmcResponseBody := rmcResponseStream.Bytes()
Expand Down Expand Up @@ -78,17 +94,17 @@ func AutoMatchmake_Postpone(err error, client *nex.Client, callID uint32, matchm

oEvent := notifications.NewNotificationEvent()
oEvent.PIDSource = common_globals.Sessions[sessionIndex].GameMatchmakeSession.Gathering.HostPID
// TODO - for Jon: notifications type to make this simpler
oEvent.Type = 3001 // New participant
oEvent.Param1 = uint32(sessionIndex)
oEvent.Type = notifications.NotificationTypes.NewParticipant
oEvent.Param1 = sessionIndex
oEvent.Param2 = client.PID()
oEvent.StrParam = message

stream := nex.NewStreamOut(server)
oEventBytes := oEvent.Bytes(stream)
rmcMessage.SetParameters(oEventBytes)
rmcMessageBytes := rmcMessage.Bytes()

targetClient := server.FindClientFromPID(uint32(common_globals.Sessions[sessionIndex].GameMatchmakeSession.Gathering.HostPID))
targetClient := server.FindClientFromPID(uint32(common_globals.Sessions[sessionIndex].GameMatchmakeSession.Gathering.OwnerPID))

var messagePacket nex.PacketInterface

Expand Down
8 changes: 4 additions & 4 deletions matchmake-extension/protocol.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ type CommonMatchmakeExtensionProtocol struct {
*matchmake_extension.MatchmakeExtensionProtocol
server *nex.Server

CleanupSearchMatchmakeSessionHandler func(matchmakeSession match_making.MatchmakeSession) match_making.MatchmakeSession
cleanupSearchMatchmakeSessionHandler func(matchmakeSession *match_making.MatchmakeSession)
}

// CleanupSearchMatchmakeSession sets the CleanupSearchMatchmakeSession handler function
func (commonMatchmakeExtensionProtocol *CommonMatchmakeExtensionProtocol) CleanupSearchMatchmakeSession(handler func(matchmakeSession match_making.MatchmakeSession) match_making.MatchmakeSession) {
commonMatchmakeExtensionProtocol.CleanupSearchMatchmakeSessionHandler = handler
func (commonMatchmakeExtensionProtocol *CommonMatchmakeExtensionProtocol) CleanupSearchMatchmakeSession(handler func(matchmakeSession *match_making.MatchmakeSession)) {
commonMatchmakeExtensionProtocol.cleanupSearchMatchmakeSessionHandler = handler
}

// NewCommonMatchmakeExtensionProtocol returns a new CommonMatchmakeExtensionProtocol
func NewCommonMatchmakeExtensionProtocol(server *nex.Server) *CommonMatchmakeExtensionProtocol {
MatchmakeExtensionProtocol := matchmake_extension.NewMatchmakeExtensionProtocol(server)
commonMatchmakeExtensionProtocol = &CommonMatchmakeExtensionProtocol{MatchmakeExtensionProtocol: MatchmakeExtensionProtocol, server: server}

MatchmakeExtensionProtocol.AutoMatchmake_Postpone(AutoMatchmake_Postpone)
MatchmakeExtensionProtocol.AutoMatchmake_Postpone(autoMatchmake_Postpone)

return commonMatchmakeExtensionProtocol
}
Loading

0 comments on commit 0342dc2

Please sign in to comment.