Files
2026-06-24 10:47:54 +03:30

89 lines
2.5 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package economy
import (
"context"
"database/sql"
)
// RankEntry یک ردیف از جدولِ رتبه‌بندی.
type RankEntry struct {
Rank int `json:"rank"`
Name string `json:"name"`
Avatar string `json:"avatar"`
RankPoints int64 `json:"rank_points"`
Tier string `json:"tier"`
}
// AwardRank امتیازِ رتبه را پس از یک بازیِ رتبه‌بندی به‌روزرسانی می‌کند.
// برنده +reward، بازنده reward/2 (کفِ صفر). برای میزِ غیرِرتبه‌بندی بی‌اثر است.
func (s *Service) AwardRank(ctx context.Context, userID int64, reward int, won bool) error {
if reward <= 0 {
return nil
}
delta := reward
if !won {
delta = -(reward / 2)
}
_, err := s.db.ExecContext(ctx,
`UPDATE users SET rank_points = MAX(0, rank_points + ?) WHERE id = ?`,
delta, userID)
return err
}
// Leaderboard فهرستِ برترین بازیکنان بر اساس امتیازِ رتبه را برمی‌گرداند.
func (s *Service) Leaderboard(ctx context.Context, limit int) ([]RankEntry, error) {
if limit <= 0 || limit > 100 {
limit = 50
}
rows, err := s.db.QueryContext(ctx,
`SELECT first_name, avatar, rank_points FROM users
WHERE rank_points > 0 ORDER BY rank_points DESC LIMIT ?`, limit)
if err != nil {
return nil, err
}
defer rows.Close()
out := make([]RankEntry, 0, limit)
rank := 0
for rows.Next() {
var name, avatar sql.NullString
var pts int64
if err := rows.Scan(&name, &avatar, &pts); err != nil {
return nil, err
}
rank++
tier, _ := RankTier(pts)
nm := name.String
if nm == "" {
nm = "بازیکن"
}
out = append(out, RankEntry{
Rank: rank, Name: nm, Avatar: avatar.String, RankPoints: pts, Tier: tier,
})
}
return out, rows.Err()
}
// ResetSeason امتیازِ رتبه‌ی همه‌ی کاربران را صفر کرده و شماره‌ی فصل را زیاد می‌کند.
func (s *Service) ResetSeason(ctx context.Context) error {
tx, err := s.db.BeginTx(ctx, nil)
if err != nil {
return err
}
defer tx.Rollback()
if _, err := tx.ExecContext(ctx, `UPDATE users SET rank_points = 0`); err != nil {
return err
}
if _, err := tx.ExecContext(ctx,
`UPDATE app_settings SET value = value + 1 WHERE key = 'season'`); err != nil {
return err
}
return tx.Commit()
}
// Season شماره‌ی فصلِ جاری را برمی‌گرداند.
func (s *Service) Season(ctx context.Context) int {
var v int
_ = s.db.QueryRowContext(ctx, `SELECT value FROM app_settings WHERE key = 'season'`).Scan(&v)
return v
}