87 lines
3.2 KiB
Go
87 lines
3.2 KiB
Go
package economy
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
)
|
|
|
|
// Stats آمار بازیِ کاربر برای نمایش در پروفایل.
|
|
type Stats struct {
|
|
Games int64 `json:"games"` // بازی کل
|
|
Wins int64 `json:"wins"` // برد کل
|
|
Losses int64 `json:"losses"` // باخت کل
|
|
KotMade int64 `json:"kot_made"` // کُت کردن
|
|
KotReceived int64 `json:"kot_received"` // کُت شدن
|
|
Cuts int64 `json:"cuts"` // بریدن (با حکم)
|
|
HakemCount int64 `json:"hakem_count"` // دست حاکم
|
|
}
|
|
|
|
// GetStats آمار کاربر را میخواند (اگر ردیفی نباشد، صفر برمیگرداند).
|
|
func (s *Service) GetStats(ctx context.Context, userID int64) (*Stats, error) {
|
|
var st Stats
|
|
err := s.db.QueryRowContext(ctx,
|
|
`SELECT games, wins, losses, kot_made, kot_received, cuts, hakem_count
|
|
FROM user_stats WHERE user_id = ?`, userID).
|
|
Scan(&st.Games, &st.Wins, &st.Losses, &st.KotMade, &st.KotReceived, &st.Cuts, &st.HakemCount)
|
|
if err == sql.ErrNoRows {
|
|
return &st, nil // هنوز بازیای ثبت نشده
|
|
}
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &st, nil
|
|
}
|
|
|
|
// bumpStats یک یا چند شمارنده را بهصورت upsert افزایش میدهد.
|
|
// fields نگاشتِ ستون→مقدار افزوده است؛ ستونها از مجموعهی ثابتِ زیر میآیند (نه ورودی کاربر).
|
|
func (s *Service) bumpStats(ctx context.Context, userID int64, games, wins, losses, kotMade, kotRecv, cuts, hakem int64) {
|
|
_, err := s.db.ExecContext(ctx,
|
|
`INSERT INTO user_stats (user_id, games, wins, losses, kot_made, kot_received, cuts, hakem_count)
|
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
ON CONFLICT(user_id) DO UPDATE SET
|
|
games = games + excluded.games,
|
|
wins = wins + excluded.wins,
|
|
losses = losses + excluded.losses,
|
|
kot_made = kot_made + excluded.kot_made,
|
|
kot_received = kot_received + excluded.kot_received,
|
|
cuts = cuts + excluded.cuts,
|
|
hakem_count = hakem_count + excluded.hakem_count`,
|
|
userID, games, wins, losses, kotMade, kotRecv, cuts, hakem)
|
|
if err != nil {
|
|
// آمار غیرحیاتی است؛ خطا را لاگنشده میگذریم تا جریان بازی مختل نشود.
|
|
_ = err
|
|
}
|
|
}
|
|
|
|
// RecordHand یک هَندِ پایانیافته را برای کاربر ثبت میکند.
|
|
func (s *Service) RecordHand(ctx context.Context, userID int64, won, kot, asHakem bool) {
|
|
var kotMade, kotRecv, hakem int64
|
|
if asHakem {
|
|
hakem = 1
|
|
}
|
|
if kot {
|
|
if won {
|
|
kotMade = 1
|
|
} else {
|
|
kotRecv = 1
|
|
}
|
|
}
|
|
s.bumpStats(ctx, userID, 0, 0, 0, kotMade, kotRecv, 0, hakem)
|
|
}
|
|
|
|
// RecordCut یک بُرِش با حکم را برای کاربر ثبت میکند.
|
|
func (s *Service) RecordCut(ctx context.Context, userID int64) {
|
|
s.bumpStats(ctx, userID, 0, 0, 0, 0, 0, 1, 0)
|
|
}
|
|
|
|
// RecordGameResult پایانِ یک بازی را برای کاربر ثبت میکند (برد/باخت).
|
|
func (s *Service) RecordGameResult(ctx context.Context, userID int64, won bool) {
|
|
var wins, losses int64
|
|
if won {
|
|
wins = 1
|
|
} else {
|
|
losses = 1
|
|
}
|
|
s.bumpStats(ctx, userID, 1, wins, losses, 0, 0, 0, 0)
|
|
}
|