Files
YaeMikoBot/plugins/economy.go
2025-10-06 16:19:26 +03:00

379 lines
11 KiB
Go
Raw 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 plugins
import (
"fmt"
"kurumibot/database"
"kurumibot/database/psql"
"kurumibot/utils"
"math"
"math/rand/v2"
"strconv"
"strings"
"time"
"kurumibot/laniakea"
"github.com/shopspring/decimal"
)
func RegisterEconomy(bot *laniakea.Bot) {
economy := laniakea.NewPlugin("Economy")
economy = economy.Command(profile, "profile", "профиль")
economy = economy.Command(work, "work", "работать")
economy = economy.Command(collect, "collect", "собрать")
economy = economy.Command(code, "code", "код")
economy = economy.Command(vacancies, "vacancies", "вакансии")
economy = economy.Command(getAJob, "getajob", "устроиться")
economy = economy.Command(aboutGroup, "group", "о группе")
economy = economy.Command(about, "about", "о боте")
go passiveIncome(bot)
bot.AddPlugins(economy.Build())
}
func about(msgCtx *laniakea.MsgContext, _ *laniakea.DatabaseContext) {
out := []string{
fmt.Sprintf("Go: %s", "1.25.0"),
fmt.Sprintf("Версия laniakea: %s", laniakea.VersionString),
}
msgCtx.Answer(strings.Join(out, "\n"))
}
func passiveIncome(b *laniakea.Bot) {
for {
users, err := psql.GetAllUsers()
if err != nil {
b.Logger().Error(err)
continue
}
for _, user := range users {
if user.Business == nil && user.Maid == nil && user.Miner == nil {
continue
}
if time.Now().Before(user.IncomeTime.Add(time.Hour * 3)) {
continue
}
moneyIncome := decimal.NewFromInt(0)
expIncome := decimal.NewFromInt(0)
btcIncome := decimal.NewFromInt(0)
if user.Business != nil {
moneyIncome = moneyIncome.Add(user.Business.Income).Mul(user.Group.Multiplier)
}
if user.Maid != nil {
expIncome = expIncome.Add(user.Maid.Income).Mul(user.Group.Multiplier)
}
if user.Miner != nil {
btcIncome = btcIncome.Add(user.Miner.Income).Mul(user.Group.Multiplier)
}
waifus, err := psql.GetUserWaifus(user.ID)
if err != nil {
b.Logger().Error(err)
continue
}
for _, waifu := range waifus {
moneyIncome = moneyIncome.Mul(waifu.MoneyBonus)
expIncome = expIncome.Mul(waifu.ExpBonus)
btcIncome = btcIncome.Mul(waifu.MoneyBonus)
}
expIncome = expIncome.Mul(decimal.NewFromFloat(0.25))
moneyIncome = moneyIncome.Mul(decimal.NewFromFloat(0.25))
btcIncome = btcIncome.Mul(decimal.NewFromFloat(0.25))
user.ExpIncome += int(expIncome.IntPart())
user.MoneyIncome = user.MoneyIncome.Add(moneyIncome)
user.BtcIncome = user.BtcIncome.Add(btcIncome)
user.IncomeTime = time.Now().Add(-time.Hour * 2)
database.PostgresDatabase.Save(user)
b.Logger().Debug(fmt.Sprintf("У %d было пассивно собрано. След. сбор через час\n", user.TelegramID))
}
time.Sleep(time.Second * 5)
}
}
func profile(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) {
user, err := psql.GetOrCreateUser(ctx.FromID, ctx.Update.Message.From.FirstName)
if err != nil {
ctx.Answer(err.Error())
return
}
pair := "нет"
if user.Pair != nil {
pair = user.Pair.Name
}
fraction := "нет"
if user.Fraction != nil {
fraction = user.Fraction.Name
}
auto := "нет"
if user.Auto != nil {
auto = fmt.Sprintf("%s (ID: %d)", user.Auto.Name, user.Auto.ID)
}
business := "нет"
if user.Business != nil {
business = fmt.Sprintf("%s (ID: %d)", user.Business.Name, user.Business.ID)
}
maid := "нет"
if user.Maid != nil {
maid = fmt.Sprintf("%s (ID: %d)", user.Maid.Name, user.Maid.ID)
}
miner := "нет"
if user.Miner != nil {
miner = fmt.Sprintf("%s (ID: %d)", user.Miner.Name, user.Miner.ID)
}
_, needXp := psql.CountLevel(user.Exp)
out := []string{
fmt.Sprintf("🖤%s, %s🖤", user.Greeting, user.Name),
fmt.Sprintf("🆔ID: %d", user.ID),
fmt.Sprintf("🔰Фракция: %s", fraction),
fmt.Sprintf("📊Группа: %s (ID: %d, x%.1f)", user.Group.Name, user.Group.ID, user.Group.Multiplier.InexactFloat64()),
fmt.Sprintf("❤️Пара: %s", pair),
fmt.Sprintf("💡Уровень: %d (%d опыта, %d опыта до повышения)", user.Level, user.Exp, needXp-user.Exp),
fmt.Sprintf("💴Баланс: %s¥ %s, %s₿", utils.DecimalComma(&user.Balance), utils.Short(user.Balance.String()), utils.DecimalComma(&user.BTC)),
fmt.Sprintf("💼Работа: %s (ID: %d)", user.Work.Name, user.Work.ID),
fmt.Sprintf("🚘Авто: %s", auto),
fmt.Sprintf("🏢Бизнес: %s", business),
fmt.Sprintf("👩‍🦳Горничная: %s", maid),
fmt.Sprintf("🖥Майнер: %s", miner),
}
ctx.Answer(strings.Join(out, "\n"))
}
func work(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) {
user, err := psql.GetOrCreateUser(ctx.FromID, ctx.Update.Message.From.FirstName)
if err != nil {
ctx.Error(err)
return
}
if time.Now().Before(user.WorkTime.Add(time.Minute * 10)) {
nextTime := time.Since(user.WorkTime.Add(time.Minute * 10))
seconds := int(math.Round(math.Abs(nextTime.Seconds())))
minutes := seconds / 60
seconds -= minutes * 60
ctx.Answer(fmt.Sprintf("Приходи через %02d:%02d", minutes, seconds))
return
}
work := user.Work
exp := rand.IntN(work.MaxExp-work.MinExp) + work.MinExp
// Count exp
expToAdd := decimal.NewFromInt(int64(exp)).Mul(user.Group.Multiplier)
// Count money
moneyToAdd := work.MoneyIncome.Mul(user.Group.Multiplier)
waifus, err := psql.GetUserWaifus(user.ID)
if err != nil {
ctx.Error(err)
return
}
for _, waifu := range waifus {
expToAdd = expToAdd.Mul(waifu.ExpBonus)
moneyToAdd = moneyToAdd.Mul(waifu.MoneyBonus)
}
user.Exp += int(expToAdd.IntPart())
user.Balance = user.Balance.Add(moneyToAdd)
user.WorkTime = time.Now()
user.Level, _ = psql.CountLevel(user.Exp)
database.PostgresDatabase.Save(user)
ctx.Answer(fmt.Sprintf(
"Ты заработал %s¥ и %d опыта.\nПриходи через 10 минут.",
utils.DecimalComma(&work.MoneyIncome),
expToAdd.IntPart(),
))
}
func collect(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) {
user, err := psql.GetOrCreateUser(ctx.FromID, ctx.Update.Message.From.FirstName)
if err != nil {
ctx.Error(err)
return
}
if user.Business == nil && user.Maid == nil && user.Miner == nil {
ctx.Answer("Нечего собирать!")
return
}
if time.Now().Before(user.IncomeTime.Add(time.Hour * 2)) {
nextTime := time.Since(user.IncomeTime.Add(time.Hour * 2))
seconds := int(math.Round(math.Abs(nextTime.Seconds())))
minutes := seconds / 60
seconds -= minutes * 60
hours := minutes / 60
minutes -= hours * 60
ctx.Answer(fmt.Sprintf("Приходи через %02d:%02d:%02d", hours, minutes, seconds))
return
}
moneyIncome := decimal.NewFromInt(0)
expIncome := decimal.NewFromInt(0)
btcIncome := decimal.NewFromInt(0)
if user.Business != nil {
moneyIncome = moneyIncome.Add(user.Business.Income).Mul(user.Group.Multiplier)
}
if user.Maid != nil {
expIncome = expIncome.Add(user.Maid.Income).Mul(user.Group.Multiplier)
}
if user.Miner != nil {
btcIncome = btcIncome.Add(user.Miner.Income).Mul(user.Group.Multiplier)
}
waifus, err := psql.GetUserWaifus(user.ID)
if err != nil {
ctx.Error(err)
return
}
for _, waifu := range waifus {
moneyIncome = moneyIncome.Mul(waifu.MoneyBonus)
expIncome = expIncome.Mul(waifu.ExpBonus)
btcIncome = btcIncome.Mul(waifu.MoneyBonus)
}
var incomeText []string
if moneyIncome.IntPart() > 0 {
incomeText = append(incomeText, fmt.Sprintf("%s¥", utils.DecimalComma(&moneyIncome)))
}
if expIncome.IntPart() > 0 {
incomeText = append(incomeText, fmt.Sprintf("%d опыта", expIncome.IntPart()))
}
if btcIncome.InexactFloat64() > 0 {
incomeText = append(incomeText, fmt.Sprintf("%.6f₿", btcIncome.InexactFloat64()))
}
var passiveIncomeText []string
if user.MoneyIncome.IntPart() > 0 {
user.Balance = user.Balance.Add(user.MoneyIncome)
passiveIncomeText = append(passiveIncomeText, fmt.Sprintf("%s¥", utils.DecimalComma(&user.MoneyIncome)))
user.MoneyIncome = decimal.NewFromInt(0)
}
if user.ExpIncome > 0 {
user.Exp += user.ExpIncome
passiveIncomeText = append(passiveIncomeText, fmt.Sprintf("%d опыта", user.ExpIncome))
user.ExpIncome = 0
}
if user.BtcIncome.InexactFloat64() > 0 {
user.BTC = user.BTC.Add(user.BtcIncome)
passiveIncomeText = append(passiveIncomeText, fmt.Sprintf("%.6f₿", user.BtcIncome.InexactFloat64()))
user.BtcIncome = decimal.NewFromFloat(0.0000000)
}
user.Balance = user.Balance.Add(moneyIncome)
user.Exp += int(expIncome.IntPart())
user.Level, _ = psql.CountLevel(user.Exp)
user.BTC = user.BTC.Add(btcIncome)
user.IncomeTime = time.Now()
database.PostgresDatabase.Save(user)
out := []string{
fmt.Sprintf("Ты собрал %s.", strings.Join(incomeText, ", ")),
}
if len(passiveIncomeText) > 0 {
out = append(out, fmt.Sprintf("Пока тебя не было, было собрано %s.", strings.Join(passiveIncomeText, ", ")))
}
out = append(out, "Приходи через 02:00:00")
ctx.Answer(strings.Join(out, "\n"))
}
func code(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) {
// user, err := database.Get
}
func vacancies(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) {
works, err := psql.GetAllWorks()
if err != nil {
ctx.Error(err)
return
}
out := []string{
"Список вакансий:",
}
for _, work := range works {
out = append(out, fmt.Sprintf("%d) %s", work.ID, work.Name))
}
ctx.Answer(strings.Join(out, "\n"))
}
func getAJob(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) {
if len(ctx.Args) == 0 {
ctx.Answer("Недостаточно аргументов")
return
}
user, err := psql.GetOrCreateUser(ctx.FromID, ctx.Msg.From.FirstName)
if err != nil {
ctx.Error(err)
return
}
workId, err := strconv.Atoi(ctx.Args[0])
if err != nil {
ctx.Error(err)
return
}
work, err := psql.GetWorkById(workId)
if err != nil {
ctx.Error(err)
return
}
if user.Level < work.RequiredLevel {
ctx.Answer("Уровень слишком низкий для этой работы!")
return
}
user.WorkID = workId
user.Work = work
db.PostgresSQL.Save(user)
ctx.Answer("Ты успешно устроился на работу!")
}
func aboutGroup(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) {
user, err := psql.GetOrCreateUser(ctx.FromID, ctx.Msg.From.FirstName)
if err != nil {
ctx.Error(err)
return
}
group := user.Group
out := []string{
fmt.Sprintf("%s, %s!", user.Greeting, user.Name),
fmt.Sprintf("📝Твоя группа: %s", group.Name),
fmt.Sprintf("📉Твоя скидка: %.0f%%", 100-group.Sale.InexactFloat64()*100),
fmt.Sprintf("📈Твой множитель: x%.2f", group.Multiplier.InexactFloat64()),
fmt.Sprintf("👩🏼Максимум вайфу: %d", group.MaxWaifus),
}
if group.IsVip {
out = append(out, "🎏Доступ к ВИП функциям: ✅")
}
if group.IsAdmin {
out = append(out, "🖥️Доступ к админ функциям: ✅")
}
if group.IsVip {
out = append(out, "🔓Бета-тестер: ✅")
}
ctx.Answer(strings.Join(out, "\n"))
}