From 8ea669e48189e8f622278c4d90e0b0e8d3d73fa2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arthur=20Gon=C3=A7alves?= Date: Tue, 24 Aug 2021 12:47:58 -0300 Subject: [PATCH] Mintor refactor in clan and membership model to improve legibility (#94) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Arthur Nogueira Gonçalves --- models/clan.go | 18 +++- models/membership.go | 222 +++++++++++++++++++++---------------------- 2 files changed, 127 insertions(+), 113 deletions(-) diff --git a/models/clan.go b/models/clan.go index 03a0494..93ae2e0 100644 --- a/models/clan.go +++ b/models/clan.go @@ -611,7 +611,7 @@ func TransferClanOwnership(db DB, encryptionKey []byte, gameID, clanPublicID, pl return nil, nil, nil, err } - level := GetLevelByLevelInt(maxLevel, levels) + level := getClanLevelByLevelInt(maxLevel, levels) if level == "" { return nil, nil, nil, &InvalidLevelForGameError{gameID, level} } @@ -680,6 +680,22 @@ func TransferClanOwnership(db DB, encryptionKey []byte, gameID, clanPublicID, pl return clan, oldOwner, newOwner, nil } +func getClanLevelByLevelInt(levelInt int, levels map[string]interface{}) string { + for k, v := range levels { + switch v.(type) { + case float64: + if int(v.(float64)) == levelInt { + return k + } + case int: + if v.(int) == levelInt { + return k + } + } + } + return "" +} + // UpdateClan updates an existing clan func UpdateClan(db DB, gameID, publicID, name, ownerPublicID string, metadata map[string]interface{}, allowApplication, autoJoin bool) (*Clan, error) { clan, err := GetClanByPublicIDAndOwnerPublicID(db, gameID, publicID, ownerPublicID) diff --git a/models/membership.go b/models/membership.go index 122a105..8ab9866 100644 --- a/models/membership.go +++ b/models/membership.go @@ -156,56 +156,6 @@ func GetOldestMemberWithHighestLevel(db DB, gameID, clanPublicID string) (*Membe return memberships[0], nil } -func clanReachedMaxMemberships(db DB, game *Game, clan *Clan, clanID int64) error { - var err error - if clan == nil { - clan, err = GetClanByID(db, clanID) - if err != nil { - return err - } - } - if clan.MembershipCount >= game.MaxMembers { - return &ClanReachedMaxMembersError{clan.PublicID} - } - return nil -} - -func playerReachedMaxInvites(db DB, encryptionKey []byte, game *Game, playerID int64) error { - player, err := GetPlayerByID(db, encryptionKey, playerID) - if err != nil { - return err - } - - pendingInvites, err := GetNumberOfPendingInvites(db, player) - if err != nil { - return err - } - - if game.MaxPendingInvites > 0 && pendingInvites >= game.MaxPendingInvites { - return &PlayerReachedMaxInvitesError{ID: player.PublicID} - } - - return nil -} - -func playerReachedMaxClans(db DB, encryptionKey []byte, game *Game, player *Player) error { - playerID := player.ID - if player.MembershipCount+player.OwnershipCount >= game.MaxClansPerPlayer { - err := UpdatePlayerMembershipCount(db, playerID) - if err != nil { - return err - } - player, err = GetPlayerByID(db, encryptionKey, playerID) - if err != nil { - return err - } - if player.MembershipCount+player.OwnershipCount >= game.MaxClansPerPlayer { - return &PlayerReachedMaxClansError{player.PublicID} - } - } - return nil -} - // GetNumberOfPendingInvites gets total number of pending invites for player func GetNumberOfPendingInvites(db DB, player *Player) (int, error) { membershipCount, err := db.SelectInt(` @@ -302,13 +252,82 @@ func ApproveOrDenyMembershipApplication(db DB, encryptionKey []byte, game *Game, return approveOrDenyMembershipHelper(db, membership, action, requestor) } - levelInt := GetLevelIntByLevel(reqMembership.Level, game.MembershipLevels) + levelInt := getLevelIntByLevel(reqMembership.Level, game.MembershipLevels) if !reqMembership.Approved || levelInt < game.MinLevelToAcceptApplication { return nil, &PlayerCannotPerformMembershipActionError{action, playerPublicID, clanPublicID, requestorPublicID} } return approveOrDenyMembershipHelper(db, membership, action, requestor) } +// PromoteOrDemoteMember increments or decrements Membership.LevelInt by one +func PromoteOrDemoteMember(db DB, game *Game, gameID, playerPublicID, clanPublicID, requestorPublicID, action string) (*Membership, error) { + demote := action == "demote" + promote := action == "promote" + + levelOffset := game.MinLevelOffsetToDemoteMember + if promote { + levelOffset = game.MinLevelOffsetToPromoteMember + } + + if playerPublicID == requestorPublicID { + return nil, &PlayerCannotPerformMembershipActionError{action, playerPublicID, clanPublicID, requestorPublicID} + } + + membership, err := GetValidMembershipByClanAndPlayerPublicID(db, gameID, clanPublicID, playerPublicID) + if err != nil { + return nil, err + } + if !isValidMember(membership) { + return nil, &CannotPromoteOrDemoteInvalidMemberError{action} + } + + levelInt := getLevelIntByLevel(membership.Level, game.MembershipLevels) + if promote && levelInt >= game.MaxMembershipLevel || demote && levelInt <= game.MinMembershipLevel { + return nil, &CannotPromoteOrDemoteMemberLevelError{action, levelInt} + } + + reqMembership, _ := GetValidMembershipByClanAndPlayerPublicID(db, gameID, clanPublicID, requestorPublicID) + if reqMembership == nil { + _, clanErr := GetClanByPublicIDAndOwnerPublicID(db, gameID, clanPublicID, requestorPublicID) + if clanErr != nil { + return nil, &PlayerCannotPerformMembershipActionError{action, playerPublicID, clanPublicID, requestorPublicID} + } + return promoteOrDemoteMemberHelper(db, membership, action, game.MembershipLevels) + } + + reqLevelInt := getLevelIntByLevel(reqMembership.Level, game.MembershipLevels) + if isValidMember(reqMembership) && reqLevelInt >= levelInt+levelOffset { + return promoteOrDemoteMemberHelper(db, membership, action, game.MembershipLevels) + } + return nil, &PlayerCannotPerformMembershipActionError{action, playerPublicID, clanPublicID, requestorPublicID} +} + +// DeleteMembership soft deletes a membership +func DeleteMembership(db DB, game *Game, gameID, playerPublicID, clanPublicID, requestorPublicID string) (*Membership, error) { + membership, err := GetValidMembershipByClanAndPlayerPublicID(db, gameID, clanPublicID, playerPublicID) + if err != nil { + return nil, err + } + if playerPublicID == requestorPublicID { + return deleteMembershipHelper(db, membership, membership.PlayerID) + } + reqMembership, _ := GetValidMembershipByClanAndPlayerPublicID(db, gameID, clanPublicID, requestorPublicID) + if reqMembership == nil { + clan, clanErr := GetClanByPublicIDAndOwnerPublicID(db, gameID, clanPublicID, requestorPublicID) + if clanErr != nil { + return nil, &PlayerCannotPerformMembershipActionError{"delete", playerPublicID, clanPublicID, requestorPublicID} + } + return deleteMembershipHelper(db, membership, clan.OwnerID) + } + + levelInt := getLevelIntByLevel(membership.Level, game.MembershipLevels) + reqLevelInt := getLevelIntByLevel(reqMembership.Level, game.MembershipLevels) + if isValidMember(reqMembership) && reqLevelInt >= game.MinLevelToRemoveMember && reqLevelInt >= levelInt+game.MinLevelOffsetToRemoveMember { + return deleteMembershipHelper(db, membership, reqMembership.PlayerID) + } + return nil, &PlayerCannotPerformMembershipActionError{"delete", playerPublicID, clanPublicID, requestorPublicID} +} + // CreateMembership creates a new membership func CreateMembership(db DB, encryptionKey []byte, game *Game, gameID, level, playerPublicID, clanPublicID, requestorPublicID, message string) (*Membership, error) { if _, levelValid := game.MembershipLevels[level]; !levelValid { @@ -450,7 +469,7 @@ func inviteMember(db DB, encryptionKey []byte, game *Game, membership *Membershi return nil, reachedMaxMembersError } - levelInt := GetLevelIntByLevel(reqMembership.Level, game.MembershipLevels) + levelInt := getLevelIntByLevel(reqMembership.Level, game.MembershipLevels) if isValidMember(reqMembership) && levelInt >= game.MinLevelToCreateInvitation { if previousMembership { @@ -461,73 +480,54 @@ func inviteMember(db DB, encryptionKey []byte, game *Game, membership *Membershi return nil, &PlayerCannotCreateMembershipError{requestorPublicID, clan.PublicID} } -// PromoteOrDemoteMember increments or decrements Membership.LevelInt by one -func PromoteOrDemoteMember(db DB, game *Game, gameID, playerPublicID, clanPublicID, requestorPublicID, action string) (*Membership, error) { - demote := action == "demote" - promote := action == "promote" - - levelOffset := game.MinLevelOffsetToDemoteMember - if promote { - levelOffset = game.MinLevelOffsetToPromoteMember +func clanReachedMaxMemberships(db DB, game *Game, clan *Clan, clanID int64) error { + var err error + if clan == nil { + clan, err = GetClanByID(db, clanID) + if err != nil { + return err + } } - - if playerPublicID == requestorPublicID { - return nil, &PlayerCannotPerformMembershipActionError{action, playerPublicID, clanPublicID, requestorPublicID} + if clan.MembershipCount >= game.MaxMembers { + return &ClanReachedMaxMembersError{clan.PublicID} } + return nil +} - membership, err := GetValidMembershipByClanAndPlayerPublicID(db, gameID, clanPublicID, playerPublicID) +func playerReachedMaxInvites(db DB, encryptionKey []byte, game *Game, playerID int64) error { + player, err := GetPlayerByID(db, encryptionKey, playerID) if err != nil { - return nil, err - } - if !isValidMember(membership) { - return nil, &CannotPromoteOrDemoteInvalidMemberError{action} + return err } - levelInt := GetLevelIntByLevel(membership.Level, game.MembershipLevels) - if promote && levelInt >= game.MaxMembershipLevel || demote && levelInt <= game.MinMembershipLevel { - return nil, &CannotPromoteOrDemoteMemberLevelError{action, levelInt} + pendingInvites, err := GetNumberOfPendingInvites(db, player) + if err != nil { + return err } - reqMembership, _ := GetValidMembershipByClanAndPlayerPublicID(db, gameID, clanPublicID, requestorPublicID) - if reqMembership == nil { - _, clanErr := GetClanByPublicIDAndOwnerPublicID(db, gameID, clanPublicID, requestorPublicID) - if clanErr != nil { - return nil, &PlayerCannotPerformMembershipActionError{action, playerPublicID, clanPublicID, requestorPublicID} - } - return promoteOrDemoteMemberHelper(db, membership, action, game.MembershipLevels) + if game.MaxPendingInvites > 0 && pendingInvites >= game.MaxPendingInvites { + return &PlayerReachedMaxInvitesError{ID: player.PublicID} } - reqLevelInt := GetLevelIntByLevel(reqMembership.Level, game.MembershipLevels) - if isValidMember(reqMembership) && reqLevelInt >= levelInt+levelOffset { - return promoteOrDemoteMemberHelper(db, membership, action, game.MembershipLevels) - } - return nil, &PlayerCannotPerformMembershipActionError{action, playerPublicID, clanPublicID, requestorPublicID} + return nil } -// DeleteMembership soft deletes a membership -func DeleteMembership(db DB, game *Game, gameID, playerPublicID, clanPublicID, requestorPublicID string) (*Membership, error) { - membership, err := GetValidMembershipByClanAndPlayerPublicID(db, gameID, clanPublicID, playerPublicID) - if err != nil { - return nil, err - } - if playerPublicID == requestorPublicID { - return deleteMembershipHelper(db, membership, membership.PlayerID) - } - reqMembership, _ := GetValidMembershipByClanAndPlayerPublicID(db, gameID, clanPublicID, requestorPublicID) - if reqMembership == nil { - clan, clanErr := GetClanByPublicIDAndOwnerPublicID(db, gameID, clanPublicID, requestorPublicID) - if clanErr != nil { - return nil, &PlayerCannotPerformMembershipActionError{"delete", playerPublicID, clanPublicID, requestorPublicID} +func playerReachedMaxClans(db DB, encryptionKey []byte, game *Game, player *Player) error { + playerID := player.ID + if player.MembershipCount+player.OwnershipCount >= game.MaxClansPerPlayer { + err := UpdatePlayerMembershipCount(db, playerID) + if err != nil { + return err + } + player, err = GetPlayerByID(db, encryptionKey, playerID) + if err != nil { + return err + } + if player.MembershipCount+player.OwnershipCount >= game.MaxClansPerPlayer { + return &PlayerReachedMaxClansError{player.PublicID} } - return deleteMembershipHelper(db, membership, clan.OwnerID) - } - - levelInt := GetLevelIntByLevel(membership.Level, game.MembershipLevels) - reqLevelInt := GetLevelIntByLevel(reqMembership.Level, game.MembershipLevels) - if isValidMember(reqMembership) && reqLevelInt >= game.MinLevelToRemoveMember && reqLevelInt >= levelInt+game.MinLevelOffsetToRemoveMember { - return deleteMembershipHelper(db, membership, reqMembership.PlayerID) } - return nil, &PlayerCannotPerformMembershipActionError{"delete", playerPublicID, clanPublicID, requestorPublicID} + return nil } func isValidMember(membership *Membership) bool { @@ -628,11 +628,11 @@ func updatePreviousMembershipHelper(db DB, membership *Membership, level string, } func promoteOrDemoteMemberHelper(db DB, membership *Membership, action string, levels map[string]interface{}) (*Membership, error) { - levelInt := GetLevelIntByLevel(membership.Level, levels) + levelInt := getLevelIntByLevel(membership.Level, levels) if action == "promote" { - membership.Level = GetLevelByLevelInt(levelInt+1, levels) + membership.Level = getLevelByLevelInt(levelInt+1, levels) } else if action == "demote" { - membership.Level = GetLevelByLevelInt(levelInt-1, levels) + membership.Level = getLevelByLevelInt(levelInt-1, levels) } else { return nil, &InvalidMembershipActionError{action} } @@ -675,8 +675,7 @@ func deleteMembershipHelper(db DB, membership *Membership, deletedBy int64) (*Me return membership, err } -// GetLevelByLevelInt returns the level string given the level int -func GetLevelByLevelInt(levelInt int, levels map[string]interface{}) string { +func getLevelByLevelInt(levelInt int, levels map[string]interface{}) string { for k, v := range levels { switch v.(type) { case float64: @@ -692,8 +691,7 @@ func GetLevelByLevelInt(levelInt int, levels map[string]interface{}) string { return "" } -// GetLevelIntByLevel returns the level string given the level int -func GetLevelIntByLevel(level string, levels map[string]interface{}) int { +func getLevelIntByLevel(level string, levels map[string]interface{}) int { v := levels[level] switch v.(type) { case float64: