package plugins import ( "fmt" "kurumibot/database/psql" "kurumibot/utils" "math" "math/rand/v2" "strconv" "strings" "time" "git.nix13.pw/scuroneko/laniakea" "github.com/shopspring/decimal" ) func RegisterEconomy(bot *laniakea.Bot) { p := laniakea.NewPlugin("Economy") p.AddCommand(p.NewCommand(profile, "profile")) p.AddCommand(p.NewCommand(profile, "профиль").SkipCommandAutoGen()) p.AddCommand(p.NewCommand(work, "work")) p.AddCommand(p.NewCommand(work, "работать").SkipCommandAutoGen()) p.AddCommand(p.NewCommand(collect, "collect")) p.AddCommand(p.NewCommand(collect, "собрать").SkipCommandAutoGen()) p.AddCommand(p.NewCommand(code, "code")) p.AddCommand(p.NewCommand(code, "код").SkipCommandAutoGen()) p.AddCommand(p.NewCommand(vacancies, "vacancies")) p.AddCommand(p.NewCommand(vacancies, "вакансии").SkipCommandAutoGen()) p.AddCommand(p.NewCommand(getAJob, "getajob")) p.AddCommand(p.NewCommand(getAJob, "устроиться").SkipCommandAutoGen()) p.AddCommand(p.NewCommand(aboutGroup, "group")) p.AddCommand(p.NewCommand(aboutGroup, "о группе").SkipCommandAutoGen()) bot.AddRunner(laniakea.NewRunner( "economy.PassiveIncome", passiveIncome, ).Timeout(time.Minute).Build()) bot.AddPlugins(p) } func passiveIncome(b *laniakea.Bot) error { ctx := b.GetDBContext() waifuRep := psql.NewWaifuRepository(ctx) userRep := psql.NewUserRepository(ctx) users, err := userRep.GetAll() if err != nil { return err } b.Logger().Debugf("Loaded %d users\n", len(users)) for _, user := range users { if user.Business == nil && user.Maid == nil && user.Miner == nil { continue } if time.Now().Before(user.IncomeTime.Add(time.Hour)) { 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 := waifuRep.GetByUserId(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() _, err = userRep.Update(&user) if err != nil { b.Logger().Error(err) continue } b.Logger().Debug(fmt.Sprintf("У %d было пассивно собрано. След. сбор через час\n", user.ID)) } return nil } func profile(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { rep := psql.NewUserRepository(db) user, err := rep.GetOrCreate(ctx.FromID, ctx.Msg.From.FirstName) if err != nil { ctx.Error(err) 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, db *laniakea.DatabaseContext) { rep := psql.NewUserRepository(db) user, err := rep.GetOrCreate(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) waifuRep := psql.NewWaifuRepository(db) waifus, err := waifuRep.GetByUserId(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().Add(-time.Hour * 3) user.Level, _ = psql.CountLevel(user.Exp) _, err = rep.Update(user) if err != nil { ctx.Error(err) return } ctx.Answer(fmt.Sprintf( "Ты заработал %s¥ и %d опыта.\nПриходи через 10 минут.", utils.DecimalComma(&moneyToAdd), expToAdd.IntPart(), )) } func collect(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { rep := psql.NewUserRepository(db) user, err := rep.GetOrCreate(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) } waifuRep := psql.NewWaifuRepository(db) waifus, err := waifuRep.GetByUserId(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() _, err = rep.Update(user) if err != nil { ctx.Error(err) return } 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, db *laniakea.DatabaseContext) { worksRep := psql.NewWorkRepository(db) works, err := worksRep.GetAll() 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 } userRep := psql.NewUserRepository(db) workRep := psql.NewWorkRepository(db) user, err := userRep.GetOrCreate(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 := workRep.GetById(workId) if err != nil { ctx.Error(err) return } if user.Level < work.RequiredLevel { ctx.Answer("Уровень слишком низкий для этой работы!") return } user.WorkID = workId _, err = userRep.Update(user) if err != nil { ctx.Error(err) return } ctx.Answer("Ты успешно устроился на работу!") } func aboutGroup(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { userRep := psql.NewUserRepository(db) user, err := userRep.GetOrCreate(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.IsPremium { out = append(out, "🎏Доступ к премиум функциям: ✅") } if group.IsTester { out = append(out, "🔓Бета-тестер: ✅") } if group.IsAdmin { out = append(out, "🖥️Доступ к админ функциям: ✅") } ctx.Answer(strings.Join(out, "\n")) }