feat: leveling system
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
package levelrepo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
type Level struct {
|
||||
GuildID int64
|
||||
UserID int64
|
||||
Level int
|
||||
XP int64
|
||||
}
|
||||
|
||||
type Repo struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func NewRepo(db *sql.DB) *Repo {
|
||||
return &Repo{db: db}
|
||||
}
|
||||
|
||||
func (r *Repo) GetLevel(ctx context.Context, guildID, userID int64) (*Level, error) {
|
||||
const q = `
|
||||
SELECT level, xp
|
||||
FROM levels
|
||||
WHERE guild = $1 AND user_id = $2
|
||||
`
|
||||
row := r.db.QueryRowContext(ctx, q, guildID, userID)
|
||||
var lvl Level
|
||||
lvl.GuildID = guildID
|
||||
lvl.UserID = userID
|
||||
switch err := row.Scan(&lvl.Level, &lvl.XP); err {
|
||||
case sql.ErrNoRows:
|
||||
// default new user
|
||||
lvl.Level = 0
|
||||
lvl.XP = 0
|
||||
return &lvl, nil
|
||||
case nil:
|
||||
return &lvl, nil
|
||||
default:
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
func (r *Repo) UpsertLevel(ctx context.Context, lvl *Level) error {
|
||||
const q = `
|
||||
INSERT INTO levels (guild, user_id, level, xp)
|
||||
VALUES ($1, $2, $3, $4)
|
||||
ON CONFLICT (guild, user_id)
|
||||
DO UPDATE SET level = EXCLUDED.level, xp = EXCLUDED.xp
|
||||
`
|
||||
_, err := r.db.ExecContext(ctx, q, lvl.GuildID, lvl.UserID, lvl.Level, lvl.XP)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Repo) SetLevel(ctx context.Context, guildID, userID int64, level int) error {
|
||||
const q = `
|
||||
INSERT INTO levels (guild, user_id, level, xp)
|
||||
VALUES ($1, $2, $3, 99)
|
||||
ON CONFLICT (guild, user_id)
|
||||
DO UPDATE SET level = EXCLUDED.level, xp = 99
|
||||
`
|
||||
_, err := r.db.ExecContext(ctx, q, guildID, userID, level)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Repo) TopLevels(ctx context.Context, guildID int64, limit int) ([]*Level, error) {
|
||||
const q = `
|
||||
SELECT user_id, level, xp
|
||||
FROM levels
|
||||
WHERE guild = $1
|
||||
ORDER BY level DESC, xp DESC, user_id ASC
|
||||
LIMIT $2
|
||||
`
|
||||
|
||||
rows, err := r.db.QueryContext(ctx, q, guildID, limit)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
out := make([]*Level, 0, limit)
|
||||
for rows.Next() {
|
||||
lvl := &Level{GuildID: guildID}
|
||||
if err := rows.Scan(&lvl.UserID, &lvl.Level, &lvl.XP); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
out = append(out, lvl)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
package settingsrepo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
)
|
||||
|
||||
type Repo struct {
|
||||
db *sql.DB
|
||||
}
|
||||
|
||||
func NewRepo(db *sql.DB) *Repo {
|
||||
return &Repo{db: db}
|
||||
}
|
||||
|
||||
func (r *Repo) SetLevelSystemEnabled(ctx context.Context, guildID int64, enabled bool) error {
|
||||
const q = `
|
||||
INSERT INTO levelsettings (guild_id, levelsys)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (guild_id)
|
||||
DO UPDATE SET levelsys = EXCLUDED.levelsys
|
||||
`
|
||||
_, err := r.db.ExecContext(ctx, q, guildID, enabled)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Repo) IsLevelSystemEnabled(ctx context.Context, guildID int64) (bool, error) {
|
||||
const q = `
|
||||
SELECT levelsys
|
||||
FROM levelsettings
|
||||
WHERE guild_id = $1
|
||||
`
|
||||
row := r.db.QueryRowContext(ctx, q, guildID)
|
||||
var enabled bool
|
||||
switch err := row.Scan(&enabled); err {
|
||||
case nil:
|
||||
return enabled, nil
|
||||
case sql.ErrNoRows:
|
||||
return false, nil
|
||||
default:
|
||||
return false, err
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Repo) GetLevelupChannelID(ctx context.Context, guildID int64) (int64, bool, error) {
|
||||
const q = `
|
||||
SELECT levelup_channel_id
|
||||
FROM levelup
|
||||
WHERE guild_id = $1
|
||||
`
|
||||
row := r.db.QueryRowContext(ctx, q, guildID)
|
||||
var channelID sql.NullInt64
|
||||
switch err := row.Scan(&channelID); err {
|
||||
case nil:
|
||||
if !channelID.Valid {
|
||||
return 0, false, nil
|
||||
}
|
||||
return channelID.Int64, true, nil
|
||||
case sql.ErrNoRows:
|
||||
return 0, false, nil
|
||||
default:
|
||||
return 0, false, err
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Repo) GetRoleRewardForLevel(ctx context.Context, guildID int64, level int) (roleID int64, ok bool, err error) {
|
||||
const q = `
|
||||
SELECT role
|
||||
FROM levelrewards
|
||||
WHERE guild_id = $1 AND levelreq = $2
|
||||
`
|
||||
row := r.db.QueryRowContext(ctx, q, guildID, level)
|
||||
var role sql.NullInt64
|
||||
switch err := row.Scan(&role); err {
|
||||
case nil:
|
||||
if !role.Valid {
|
||||
return 0, false, nil
|
||||
}
|
||||
return role.Int64, true, nil
|
||||
case sql.ErrNoRows:
|
||||
return 0, false, nil
|
||||
default:
|
||||
return 0, false, err
|
||||
}
|
||||
}
|
||||
|
||||
func (r *Repo) SetRoleRewardForLevel(ctx context.Context, guildID int64, level int, roleID int64) error {
|
||||
const q = `
|
||||
INSERT INTO levelrewards (guild_id, levelreq, role)
|
||||
VALUES ($1, $2, $3)
|
||||
ON CONFLICT (guild_id, levelreq)
|
||||
DO UPDATE SET role = EXCLUDED.role
|
||||
`
|
||||
_, err := r.db.ExecContext(ctx, q, guildID, level, roleID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Repo) SetLevelUpChannel(ctx context.Context, guildID int64, channelID int64) error {
|
||||
const q = `
|
||||
INSERT INTO levelup (guild_id, levelup_channel_id)
|
||||
VALUES ($1, $2)
|
||||
ON CONFLICT (guild_id)
|
||||
DO UPDATE SET levelup_channel_id = EXCLUDED.levelup_channel_id
|
||||
`
|
||||
_, err := r.db.ExecContext(ctx, q, guildID, channelID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Repo) SetLevelUpMessage(ctx context.Context, guildID int64, message string) error {
|
||||
const q = `
|
||||
UPDATE levelsettings
|
||||
SET message = $1
|
||||
WHERE guild_id = $2
|
||||
`
|
||||
_, err := r.db.ExecContext(ctx, q, message, guildID)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Repo) GetLevelUpMessage(ctx context.Context, guildID int64) (string, error) {
|
||||
const q = `
|
||||
SELECT message
|
||||
FROM levelsettings
|
||||
WHERE guild_id = $1
|
||||
`
|
||||
row := r.db.QueryRowContext(ctx, q, guildID)
|
||||
var message sql.NullString
|
||||
switch err := row.Scan(&message); err {
|
||||
case nil:
|
||||
if !message.Valid {
|
||||
return "GG {user}, you reached level {level}!", nil
|
||||
}
|
||||
return message.String, nil
|
||||
case sql.ErrNoRows:
|
||||
return "GG {user}, you reached level {level}!", nil
|
||||
default:
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user