This commit is contained in:
@@ -43,7 +43,13 @@ func HandleCommand(commandName string, cooldownDuration time.Duration, handler C
|
||||
response, handlerErr := handler(s, i)
|
||||
|
||||
if handlerErr != nil {
|
||||
RespondWithError(s, i, "Error processing command: "+handlerErr.Error())
|
||||
s.FollowupMessageCreate(i.Interaction, true, &discordgo.WebhookParams{
|
||||
Content: "Error processing command: " + handlerErr.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
if response == "" {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
type Config struct {
|
||||
// Discord settings
|
||||
DiscordToken string
|
||||
AdminIDs []string
|
||||
|
||||
// Himbucks settings
|
||||
HimbucksPerReward int
|
||||
@@ -36,6 +37,8 @@ type Config struct {
|
||||
HimbucksCooldown int
|
||||
HimboardCooldown int
|
||||
SendbucksCooldown int
|
||||
ShopCooldown int
|
||||
GivebucksCooldown int
|
||||
}
|
||||
|
||||
var AppConfig *Config
|
||||
@@ -45,6 +48,7 @@ func LoadConfig() *Config {
|
||||
config := &Config{
|
||||
// Discord settings
|
||||
DiscordToken: getEnv("DISCORD_TOKEN", ""),
|
||||
AdminIDs: getEnvSlice("ADMIN_USER_IDS", []string{}),
|
||||
|
||||
// Himbucks settings
|
||||
HimbucksPerReward: getEnvInt("HIMBUCKS_PER_REWARD", 10),
|
||||
@@ -71,6 +75,8 @@ func LoadConfig() *Config {
|
||||
HimbucksCooldown: getEnvInt("HIMBUCKS_COOLDOWN_SECONDS", 5),
|
||||
HimboardCooldown: getEnvInt("HIMBOARD_COOLDOWN_SECONDS", 5),
|
||||
SendbucksCooldown: getEnvInt("SENDBUCKS_COOLDOWN_SECONDS", 1800),
|
||||
ShopCooldown: getEnvInt("SHOP_COOLDOWN_SECONDS", 5),
|
||||
GivebucksCooldown: getEnvInt("GIVEBUCKS_COOLDOWN_SECONDS", 1),
|
||||
}
|
||||
|
||||
AppConfig = config
|
||||
@@ -93,4 +99,29 @@ func getEnvInt(key string, defaultValue int) int {
|
||||
}
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
}
|
||||
|
||||
func getEnvSlice(key string, defaultValue []string) []string {
|
||||
if value := os.Getenv(key); value != "" {
|
||||
return importStrings(value)
|
||||
}
|
||||
return defaultValue
|
||||
}
|
||||
|
||||
func importStrings(s string) []string {
|
||||
var strings []string
|
||||
current := ""
|
||||
for _, c := range s {
|
||||
if c == ',' {
|
||||
strings = append(strings, current)
|
||||
current = ""
|
||||
} else {
|
||||
current += string(c)
|
||||
}
|
||||
}
|
||||
if current != "" {
|
||||
strings = append(strings, current)
|
||||
}
|
||||
return strings
|
||||
}
|
||||
|
||||
143
lib/himbucks.go
143
lib/himbucks.go
@@ -24,12 +24,13 @@ func ProcessHimbucks(s *discordgo.Session, m *discordgo.MessageCreate, ctx *Proc
|
||||
// Get current state
|
||||
var messageCount int
|
||||
var lastRewardAt sql.NullTime
|
||||
var multiplier float64
|
||||
|
||||
err = tx.QueryRow(`
|
||||
SELECT message_count, last_reward_at
|
||||
SELECT message_count, last_reward_at, COALESCE(multiplier, 1.0)
|
||||
FROM guild_profiles
|
||||
WHERE user_id = ? AND guild_id = ?`,
|
||||
ctx.UserID, ctx.GuildID).Scan(&messageCount, &lastRewardAt)
|
||||
ctx.UserID, ctx.GuildID).Scan(&messageCount, &lastRewardAt, &multiplier)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get message count: %w", err)
|
||||
}
|
||||
@@ -39,13 +40,14 @@ func ProcessHimbucks(s *discordgo.Session, m *discordgo.MessageCreate, ctx *Proc
|
||||
(!lastRewardAt.Valid || time.Since(lastRewardAt.Time) >= AppConfig.CooldownPeriod)
|
||||
|
||||
if shouldReward {
|
||||
reward := int(float64(AppConfig.HimbucksPerReward) * multiplier)
|
||||
_, err = tx.Exec(`
|
||||
UPDATE guild_profiles
|
||||
SET currency_balance = currency_balance + ?,
|
||||
message_count = 0,
|
||||
last_reward_at = CURRENT_TIMESTAMP
|
||||
WHERE user_id = ? AND guild_id = ?`,
|
||||
AppConfig.HimbucksPerReward, ctx.UserID, ctx.GuildID)
|
||||
reward, ctx.UserID, ctx.GuildID)
|
||||
} else {
|
||||
_, err = tx.Exec(`
|
||||
UPDATE guild_profiles
|
||||
@@ -179,3 +181,138 @@ func GetLeaderboard(guildID string, limit int) ([]HimbucksEntry, error) {
|
||||
}
|
||||
return entries, nil
|
||||
}
|
||||
|
||||
func BuyMultiplier(discordID, guildID string) (float64, int, int, error) {
|
||||
tx, err := DBClient.Begin()
|
||||
if err != nil {
|
||||
return 0, 0, 0, fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
var userID int
|
||||
err = tx.QueryRow("SELECT id FROM users WHERE discord_id = ?", discordID).Scan(&userID)
|
||||
if err != nil {
|
||||
return 0, 0, 0, fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
var balance int
|
||||
var currentMultiplier float64
|
||||
err = tx.QueryRow(`
|
||||
SELECT currency_balance, COALESCE(multiplier, 1.0)
|
||||
FROM guild_profiles
|
||||
WHERE user_id = ? AND guild_id = ?`,
|
||||
userID, guildID).Scan(&balance, ¤tMultiplier)
|
||||
if err != nil {
|
||||
return 0, 0, 0, fmt.Errorf("failed to get profile: %w", err)
|
||||
}
|
||||
|
||||
cost := int(1000 * currentMultiplier)
|
||||
if balance < cost {
|
||||
return 0, 0, 0, fmt.Errorf("insufficient funds: have %d, need %d", balance, cost)
|
||||
}
|
||||
|
||||
newBalance := balance - cost
|
||||
newMultiplier := currentMultiplier + 0.5
|
||||
_, err = tx.Exec(`
|
||||
UPDATE guild_profiles
|
||||
SET currency_balance = ?,
|
||||
multiplier = ?
|
||||
WHERE user_id = ? AND guild_id = ?`,
|
||||
newBalance, newMultiplier, userID, guildID)
|
||||
if err != nil {
|
||||
return 0, 0, 0, fmt.Errorf("failed to update profile: %w", err)
|
||||
}
|
||||
|
||||
if err = tx.Commit(); err != nil {
|
||||
return 0, 0, 0, fmt.Errorf("failed to commit: %w", err)
|
||||
}
|
||||
|
||||
return newMultiplier, cost, newBalance, nil
|
||||
}
|
||||
|
||||
func BuyPizza(discordID, guildID string) (int, int, error) {
|
||||
tx, err := DBClient.Begin()
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
var userID int
|
||||
err = tx.QueryRow("SELECT id FROM users WHERE discord_id = ?", discordID).Scan(&userID)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
var balance int
|
||||
err = tx.QueryRow(`
|
||||
SELECT currency_balance
|
||||
FROM guild_profiles
|
||||
WHERE user_id = ? AND guild_id = ?`,
|
||||
userID, guildID).Scan(&balance)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to get profile: %w", err)
|
||||
}
|
||||
|
||||
cost := 100
|
||||
if balance < cost {
|
||||
return 0, 0, fmt.Errorf("insufficient funds: have %d, need %d", balance, cost)
|
||||
}
|
||||
|
||||
newBalance := balance - cost
|
||||
_, err = tx.Exec(`
|
||||
UPDATE guild_profiles
|
||||
SET currency_balance = ?
|
||||
WHERE user_id = ? AND guild_id = ?`,
|
||||
newBalance, userID, guildID)
|
||||
if err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to update balance: %w", err)
|
||||
}
|
||||
|
||||
if err = tx.Commit(); err != nil {
|
||||
return 0, 0, fmt.Errorf("failed to commit transaction: %w", err)
|
||||
}
|
||||
|
||||
return cost, newBalance, nil
|
||||
}
|
||||
|
||||
func GiveHimbucks(discordID, guildID string, amount int) error {
|
||||
tx, err := DBClient.Begin()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to start transaction: %w", err)
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
var userID int
|
||||
// Get user ID
|
||||
err = tx.QueryRow("SELECT id FROM users WHERE discord_id = ?", discordID).Scan(&userID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("user not found: %w", err)
|
||||
}
|
||||
|
||||
result, err := tx.Exec(`
|
||||
UPDATE guild_profiles
|
||||
SET currency_balance = currency_balance + ?
|
||||
WHERE user_id = ? AND guild_id = ?`,
|
||||
amount, userID, guildID)
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update balance: %w", err)
|
||||
}
|
||||
|
||||
rows, err := result.RowsAffected()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check rows affected: %w", err)
|
||||
}
|
||||
|
||||
if rows == 0 {
|
||||
_, err = tx.Exec(`
|
||||
INSERT INTO guild_profiles (user_id, guild_id, currency_balance, message_count)
|
||||
VALUES (?, ?, ?, 0)`,
|
||||
userID, guildID, amount)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create profile: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user