Skip to content

Commit

Permalink
Refactor clan model to decouple from membership
Browse files Browse the repository at this point in the history
  • Loading branch information
Arthur Nogueira Gonçalves committed Aug 20, 2021
1 parent e132660 commit 2b5b99e
Show file tree
Hide file tree
Showing 2 changed files with 128 additions and 113 deletions.
18 changes: 17 additions & 1 deletion models/clan.go
Original file line number Diff line number Diff line change
Expand Up @@ -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}
}
Expand Down Expand Up @@ -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)
Expand Down
223 changes: 111 additions & 112 deletions models/membership.go
Original file line number Diff line number Diff line change
Expand Up @@ -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(`
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down Expand Up @@ -608,6 +608,7 @@ func updatePreviousMembershipHelper(db DB, membership *Membership, level string,
membership.Message = message
if approved {
membership.ApproverID = sql.NullInt64{Int64: requestorID, Valid: true}
membership.ApprovedAt = util.NowMilli()
}

_, err := db.Update(membership)
Expand All @@ -628,11 +629,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}
}
Expand Down Expand Up @@ -675,8 +676,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:
Expand All @@ -692,8 +692,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:
Expand Down

0 comments on commit 2b5b99e

Please sign in to comment.