From d4845414f5eb39b22fd38f040ec3c08bfb11b6fb Mon Sep 17 00:00:00 2001 From: Andrei Mihu Date: Mon, 20 Nov 2017 13:55:14 +0000 Subject: [PATCH] Improve friend block behaviour. Merge #129 --- CHANGELOG.md | 4 ++++ server/core_leaderboard.go | 12 ++++++------ server/pipeline_friend.go | 31 +++++++++++++++++++++++++++---- server/pipeline_group.go | 16 +++++++++++----- server/runtime_nakama_module.go | 5 +++++ 5 files changed, 53 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4c8f69ba..e82376faa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ The format is based on [keep a changelog](http://keepachangelog.com/) and this p ### Changed - Internal operations exposed to the script runtime through function bindings now silently ignore unknown parameters. +### Fixed +- Blocking users now works correctly when there was no prior friend relationship in place. +- Correctly assign cursor data in paginated leaderboard records list queries. + ## [1.2.0] - 2017-11-06 ### Added - New experimental rUDP socket protocol option for client connections. diff --git a/server/core_leaderboard.go b/server/core_leaderboard.go index b2c71e88d..257cc0bd7 100644 --- a/server/core_leaderboard.go +++ b/server/core_leaderboard.go @@ -189,15 +189,15 @@ func leaderboardRecordsList(logger *zap.Logger, db *sql.DB, caller string, list count := len(params) if sortOrder == 0 { // Ascending leaderboard. - query += " AND (score, updated_at, id) > ($" + strconv.Itoa(count) + - ", $" + strconv.Itoa(count+1) + - ", $" + strconv.Itoa(count+2) + ")" + query += " AND (score, updated_at, id) > ($" + strconv.Itoa(count+1) + + ", $" + strconv.Itoa(count+2) + + ", $" + strconv.Itoa(count+3) + ")" params = append(params, incomingCursor.Score, incomingCursor.UpdatedAt, incomingCursor.Id) } else { // Descending leaderboard. - query += " AND (score, updated_at_inverse, id) < ($" + strconv.Itoa(count) + - ", $" + strconv.Itoa(count+1) + - ", $" + strconv.Itoa(count+2) + ")" + query += " AND (score, updated_at_inverse, id) < ($" + strconv.Itoa(count+1) + + ", $" + strconv.Itoa(count+2) + + ", $" + strconv.Itoa(count+3) + ")" params = append(params, incomingCursor.Score, invertMs(incomingCursor.UpdatedAt), incomingCursor.Id) } } diff --git a/server/pipeline_friend.go b/server/pipeline_friend.go index e28d76802..ff68b3108 100644 --- a/server/pipeline_friend.go +++ b/server/pipeline_friend.go @@ -462,16 +462,39 @@ func (p *pipeline) friendBlock(l *zap.Logger, session session, envelope *Envelop } }() + ts := nowMs() + + // Try to update any previous edge between these users. res, err := tx.Exec("UPDATE user_edge SET state = 3, updated_at = $3 WHERE source_id = $1 AND destination_id = $2", - session.UserID(), userID, nowMs()) + session.UserID(), userID, ts) if err != nil { return } if rowsAffected, _ := res.RowsAffected(); rowsAffected == 0 { - err = errors.New("Could not block user. User ID may not exist") - return + // If there was no previous edge then create one. + query := `INSERT INTO user_edge (source_id, destination_id, state, position, updated_at) +SELECT source_id, destination_id, state, position, updated_at +FROM (VALUES + ($1::BYTEA, $2::BYTEA, 3, $3::BIGINT, $3::BIGINT) +) AS ue(source_id, destination_id, state, position, updated_at) +WHERE EXISTS (SELECT id FROM users WHERE id = $2::BYTEA)` + res, err = tx.Exec(query, session.UserID(), userID, ts) + if err != nil { + return + } + + if rowsAffected, _ := res.RowsAffected(); rowsAffected == 0 { + err = errors.New("Could not block user. User ID may not exist") + return + } + + // Update the edge count. + _, err = tx.Exec("UPDATE user_edge_metadata SET count = count + 1, updated_at = $2 WHERE source_id = $1", session.UserID(), ts) + if err != nil { + return + } } // Delete opposite relationship if user hasn't blocked you already @@ -483,7 +506,7 @@ func (p *pipeline) friendBlock(l *zap.Logger, session session, envelope *Envelop } if rowsAffected, _ := res.RowsAffected(); rowsAffected == 1 { - _, err = tx.Exec("UPDATE user_edge_metadata SET count = count - 1, updated_at = $2 WHERE source_id = $1", userID, nowMs()) + _, err = tx.Exec("UPDATE user_edge_metadata SET count = count - 1, updated_at = $2 WHERE source_id = $1", userID, ts) } } diff --git a/server/pipeline_group.go b/server/pipeline_group.go index f3d3003bf..ef6452750 100644 --- a/server/pipeline_group.go +++ b/server/pipeline_group.go @@ -837,12 +837,18 @@ func (p *pipeline) groupUserAdd(l *zap.Logger, session session, envelope *Envelo // Look up the user being added. err = tx.QueryRow("SELECT handle FROM users WHERE id = $1 AND disabled_at = 0", userID).Scan(&handle) if err != nil { + if err == sql.ErrNoRows { + err = errors.New("Could not add user to group. User does not exist") + } return } // Look up the name of the group. err = tx.QueryRow("SELECT name FROM groups WHERE id = $1", groupID).Scan(&name) if err != nil { + if err == sql.ErrNoRows { + err = errors.New("Could not add user to group. Group does not exist") + } return } @@ -850,14 +856,14 @@ func (p *pipeline) groupUserAdd(l *zap.Logger, session session, envelope *Envelo INSERT INTO group_edge (source_id, position, updated_at, destination_id, state) SELECT data.id, data.position, data.updated_at, data.destination, data.state FROM ( - SELECT $1 AS id, $2::INT AS position, $2::INT AS updated_at, $3 AS destination, 1 AS state + SELECT $1::BYTEA AS id, $2::INT AS position, $2::INT AS updated_at, $3::BYTEA AS destination, 1 AS state UNION ALL - SELECT $3 AS id, $2::INT AS position, $2::INT AS updated_at, $1 AS destination, 1 AS state + SELECT $3::BYTEA AS id, $2::INT AS position, $2::INT AS updated_at, $1::BYTEA AS destination, 1 AS state ) AS data WHERE - EXISTS (SELECT source_id FROM group_edge WHERE source_id = $1 AND destination_id = $4 AND state = 0) + EXISTS (SELECT source_id FROM group_edge WHERE source_id = $1::BYTEA AND destination_id = $4 AND state = 0) AND - EXISTS (SELECT id FROM groups WHERE id = $1 AND disabled_at = 0) + EXISTS (SELECT id FROM groups WHERE id = $1::BYTEA AND disabled_at = 0) ON CONFLICT (source_id, destination_id) DO UPDATE SET state = 1, updated_at = $2::INT`, groupID, ts, userID, session.UserID()) @@ -867,7 +873,7 @@ DO UPDATE SET state = 1, updated_at = $2::INT`, } if affectedRows, _ := res.RowsAffected(); affectedRows == 0 { - err = errors.New("Could not add user to group. Group may not exists or you may not be group admin") + err = errors.New("Could not add user to group. Group may not exist or you may not be group admin") return } diff --git a/server/runtime_nakama_module.go b/server/runtime_nakama_module.go index 457fcbf49..028651184 100644 --- a/server/runtime_nakama_module.go +++ b/server/runtime_nakama_module.go @@ -131,6 +131,7 @@ func (n *NakamaModule) Loader(l *lua.LState) int { "group_users_list": n.groupUsersList, "groups_user_list": n.groupsUserList, "notifications_send_id": n.notificationsSendId, + "event_publish": n.eventPublish, }) l.Push(mod) @@ -2006,3 +2007,7 @@ func (n *NakamaModule) notificationsSendId(l *lua.LState) int { return 0 } + +func (n *NakamaModule) eventPublish(l *lua.LState) int { + return 0 +} -- GitLab