From e15d56196d8e4b8c9bb6fabe66f9debba1caaf55 Mon Sep 17 00:00:00 2001 From: ScuroNeko Date: Mon, 29 Sep 2025 09:14:39 +0300 Subject: [PATCH] log middleware --- .env | 4 +- Dockerfile | 14 ++- Makefile | 3 + build.bat | 5 - database/database.go | 39 -------- database/mdb/logs.go | 23 +++++ database/mongo.go | 27 +++++ database/postgresql.go | 32 ++++++ database/{ => psql}/fraction.go | 2 +- database/{ => psql}/groups.go | 2 +- database/psql/migrate.go | 10 ++ database/{ => psql}/shop.go | 18 +++- database/{ => psql}/users.go | 39 +++++--- database/{ => psql}/waifus.go | 20 ++-- database/{ => psql}/works.go | 12 ++- database/redis.go | 13 +++ db.docker-compose.yml | 13 ++- go.mod | 25 +++-- go.sum | 72 +++++++++++++- main.go | 38 ++++--- main.log | 26 +++++ plugins/admin.go | 12 +-- plugins/economy.go | 94 +++++++++++------- plugins/logs.go | 27 +++++ plugins/waifus.go | 34 +++---- requests.log | 30 ++++++ scripts/postgres/Init.sql | 171 ++++++++++++++++++++++++++++++++ 27 files changed, 641 insertions(+), 164 deletions(-) create mode 100644 Makefile delete mode 100644 build.bat delete mode 100644 database/database.go create mode 100644 database/mdb/logs.go create mode 100644 database/mongo.go create mode 100644 database/postgresql.go rename database/{ => psql}/fraction.go (91%) rename database/{ => psql}/groups.go (95%) create mode 100644 database/psql/migrate.go rename database/{ => psql}/shop.go (61%) rename database/{ => psql}/users.go (58%) rename database/{ => psql}/waifus.go (60%) rename database/{ => psql}/works.go (63%) create mode 100644 database/redis.go create mode 100644 main.log create mode 100644 plugins/logs.go create mode 100644 requests.log create mode 100644 scripts/postgres/Init.sql diff --git a/.env b/.env index 6ca2b6c..19e4613 100644 --- a/.env +++ b/.env @@ -1,7 +1,9 @@ # Used for bot AND docker compose +PSQL_HOST=127.0.0.1 PSQL_USER=kurumi_bot PSQL_PASS=kurumi_bot PSQL_NAME=kurumi_bot +MONGO_HOST=127.0.0.1 MONGO_USER=kurumi_bot MONGO_PASS=kurumi_bot -MONGO_NAME=kurumi_bot \ No newline at end of file +MONGO_NAME=kurumi \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index d4047e3..4ffee2e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,15 @@ -FROM golang:1.25-alpine +FROM golang:1.25-alpine AS builder WORKDIR /usr/src/kurumi COPY go.mod go.sum ./ RUN go mod download -COPY . . +COPY ./database ./database +COPY ./laniakea ./laniakea +COPY ./plugins ./plugins +COPY ./utils ./utils +COPY ./main.go ./ RUN --mount=type=cache,target=/go/pkg/mod go build -trimpath -o /usr/local/bin/kurumi ./ -CMD ["kurumi"] \ No newline at end of file + +FROM alpine AS runner +WORKDIR /app +COPY --from=builder /usr/local/bin/kurumi /app/kurumi +CMD ["/app/kurumi"] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..6022d87 --- /dev/null +++ b/Makefile @@ -0,0 +1,3 @@ +build: + docker build -t git.nix13.pw/scuroneko/kurumibotgo:latest -t git.nix13.pw/scuroneko/kurumibotgo:0.1.4 -f ./Dockerfile . + docker push git.nix13.pw/scuroneko/kurumibotgo --all-tags \ No newline at end of file diff --git a/build.bat b/build.bat deleted file mode 100644 index 3fab3c2..0000000 --- a/build.bat +++ /dev/null @@ -1,5 +0,0 @@ -@echo off -set GOARCH=amd64 -set GOOS=linux -go build . -pause \ No newline at end of file diff --git a/database/database.go b/database/database.go deleted file mode 100644 index 3793717..0000000 --- a/database/database.go +++ /dev/null @@ -1,39 +0,0 @@ -package database - -import ( - "fmt" - "log" - "os" - - "gorm.io/driver/postgres" - "gorm.io/gorm" -) - -type config struct { - Host string `json:"host"` - User string `json:"user"` - Password string `json:"password"` - Database string `json:"database"` -} - -var Database *gorm.DB - -func getDSN() string { - user := os.Getenv("PSQL_USER") - password := os.Getenv("PSQL_PASS") - database := os.Getenv("PSQL_NAME") - log.Println("user:", user, "database:", database) - return fmt.Sprintf("postgresql://%s:%s@%s/%s?sslmode=disable", user, password, "postgres", database) -} - -func Connect() { - var err error - Database, err = gorm.Open(postgres.Open(getDSN()), new(gorm.Config)) - if err != nil { - log.Fatalln(err) - } - err = Database.AutoMigrate(&User{}, &Fraction{}, &Group{}, &ShopAuto{}) - if err != nil { - log.Fatalln(err) - } -} diff --git a/database/mdb/logs.go b/database/mdb/logs.go new file mode 100644 index 0000000..00c8fb0 --- /dev/null +++ b/database/mdb/logs.go @@ -0,0 +1,23 @@ +package mdb + +import ( + "context" + "kurumibot/laniakea" + "time" +) + +type MessageLogEntry struct { + MessageID int `bson:"messageId"` + SenderID int `bson:"senderId"` + ChatID int `bson:"chatId"` + Text string `bson:"text"` + TimeStamp int64 `bson:"timestamp"` +} + +func WriteMessageLog(db *laniakea.DatabaseContext, e *MessageLogEntry) error { + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + defer cancel() + collection := db.MongoDB.Database("kurumi").Collection("msg_logs") + _, err := collection.InsertOne(ctx, e) + return err +} diff --git a/database/mongo.go b/database/mongo.go new file mode 100644 index 0000000..4f44d99 --- /dev/null +++ b/database/mongo.go @@ -0,0 +1,27 @@ +package database + +import ( + "fmt" + "log" + "os" + + "go.mongodb.org/mongo-driver/v2/mongo" + "go.mongodb.org/mongo-driver/v2/mongo/options" +) + +var MongoClient *mongo.Client + +func ConnectMongo() { + var err error + opts := options.Client() + host, exists := os.LookupEnv("MONGO_HOST") + if !exists { + host = "localhost" + } + opts = opts.ApplyURI(fmt.Sprintf("mongodb://%s:%s@%s:27017", os.Getenv("MONGO_USER"), os.Getenv("MONGO_PASS"), host)) + opts = opts.SetCompressors([]string{"snappy", "zlib", "zstd"}) + MongoClient, err = mongo.Connect(opts) + if err != nil { + log.Fatalln(err) + } +} diff --git a/database/postgresql.go b/database/postgresql.go new file mode 100644 index 0000000..f19122e --- /dev/null +++ b/database/postgresql.go @@ -0,0 +1,32 @@ +package database + +import ( + "fmt" + "log" + "os" + + "gorm.io/driver/postgres" + "gorm.io/gorm" +) + +var PostgresDatabase *gorm.DB + +func getDSN() string { + user := os.Getenv("PSQL_USER") + password := os.Getenv("PSQL_PASS") + database := os.Getenv("PSQL_NAME") + host, exists := os.LookupEnv("PSQL_HOST") + if !exists { + host = "localhost" + } + log.Println("user:", user, "database:", database) + return fmt.Sprintf("postgresql://%s:%s@%s/%s?sslmode=disable", user, password, host, database) +} + +func ConnectPostgres() { + var err error + PostgresDatabase, err = gorm.Open(postgres.Open(getDSN()), new(gorm.Config)) + if err != nil { + log.Fatalln(err) + } +} diff --git a/database/fraction.go b/database/psql/fraction.go similarity index 91% rename from database/fraction.go rename to database/psql/fraction.go index 50a0b4c..1d36426 100644 --- a/database/fraction.go +++ b/database/psql/fraction.go @@ -1,4 +1,4 @@ -package database +package psql import "github.com/shopspring/decimal" diff --git a/database/groups.go b/database/psql/groups.go similarity index 95% rename from database/groups.go rename to database/psql/groups.go index 478bf0f..e6220d5 100644 --- a/database/groups.go +++ b/database/psql/groups.go @@ -1,4 +1,4 @@ -package database +package psql import "github.com/shopspring/decimal" diff --git a/database/psql/migrate.go b/database/psql/migrate.go new file mode 100644 index 0000000..1c7bdd4 --- /dev/null +++ b/database/psql/migrate.go @@ -0,0 +1,10 @@ +package psql + +import "kurumibot/database" + +func Migrate() error { + return database.PostgresDatabase.AutoMigrate( + &User{}, &Fraction{}, &Group{}, &Waifu{}, &Work{}, + &ShopAuto{}, &ShopBusiness{}, &ShopMaid{}, &ShopMiner{}, + ) +} diff --git a/database/shop.go b/database/psql/shop.go similarity index 61% rename from database/shop.go rename to database/psql/shop.go index 5c63531..5cf2613 100644 --- a/database/shop.go +++ b/database/psql/shop.go @@ -1,4 +1,4 @@ -package database +package psql import "github.com/shopspring/decimal" @@ -8,6 +8,10 @@ type ShopAuto struct { Price decimal.Decimal } +func (ShopAuto) TableName() string { + return "shop_auto" +} + type ShopBusiness struct { ID int Name string @@ -15,6 +19,10 @@ type ShopBusiness struct { Income decimal.Decimal } +func (ShopBusiness) TableName() string { + return "shop_business" +} + type ShopMaid struct { ID int Name string @@ -22,9 +30,17 @@ type ShopMaid struct { Income decimal.Decimal } +func (ShopMaid) TableName() string { + return "shop_maid" +} + type ShopMiner struct { ID int Name string Price decimal.Decimal Income decimal.Decimal } + +func (ShopMiner) TableName() string { + return "shop_miner" +} diff --git a/database/users.go b/database/psql/users.go similarity index 58% rename from database/users.go rename to database/psql/users.go index 966f004..d9c484e 100644 --- a/database/users.go +++ b/database/psql/users.go @@ -1,8 +1,10 @@ -package database +package psql import ( "database/sql" "errors" + "kurumibot/database" + "log" "math" "time" @@ -15,28 +17,28 @@ type User struct { TelegramID int `gorm:"column:tg_id"` Balance decimal.Decimal Name string - GroupID int + GroupID int `gorm:"default:1"` Group *Group - Level int - WorkID int + Level int `gorm:"default:1"` + Exp int `gorm:"default:0"` + WorkID int `gorm:"default:1"` Work *Work WorkTime time.Time - Exp int - AutoID int + AutoID sql.NullInt64 Auto *ShopAuto - BusinessID int + BusinessID sql.NullInt64 Business *ShopBusiness - MaidID int + MaidID sql.NullInt64 Maid *ShopMaid - MinerID int + MinerID sql.NullInt64 Miner *ShopMiner IncomeTime time.Time BTC decimal.Decimal Invested decimal.Decimal - PairID int + PairID sql.NullInt64 Pair *User - Greeting string - Donat int + Greeting string `gorm:"size:255,default:Привет"` + Donat int `gorm:"default:0"` FractionID sql.NullInt64 Fraction *Fraction @@ -49,8 +51,13 @@ type User struct { func GetOrCreateUser(tgId int, name string) (*User, error) { user, err := GetUser(tgId) + log.Println(errors.Is(err, gorm.ErrRecordNotFound)) if errors.Is(err, gorm.ErrRecordNotFound) { - user, err = CreateUser(tgId, name) + _, err = CreateUser(tgId, name) + if err != nil { + return nil, err + } + return GetUser(tgId) } return user, err } @@ -60,19 +67,19 @@ func CreateUser(tgId int, name string) (*User, error) { TelegramID: tgId, Name: name, } - tx := Database.Create(user) + tx := database.PostgresDatabase.Create(user) return user, tx.Error } func GetUser(telegramId int) (*User, error) { user := new(User) - tx := Database.Joins("Group").Joins("Work").Joins("Auto").Joins("Business").Joins("Maid").Joins("Miner").Joins("Fraction").Preload("Pair").Take(user, "tg_id=?", telegramId) + tx := database.PostgresDatabase.Joins("Group").Joins("Work").Joins("Auto").Joins("Business").Joins("Maid").Joins("Miner").Joins("Fraction").Preload("Pair").Take(user, "tg_id=?", telegramId) return user, tx.Error } func GetAllUsers() ([]*User, error) { users := make([]*User, 0) - tx := Database.Joins("Group").Joins("Work").Joins("Auto").Joins("Business").Joins("Maid").Joins("Miner").Joins("Fraction").Preload("Pair").Find(&users) + tx := database.PostgresDatabase.Joins("Group").Joins("Work").Joins("Auto").Joins("Business").Joins("Maid").Joins("Miner").Joins("Fraction").Preload("Pair").Find(&users) return users, tx.Error } diff --git a/database/waifus.go b/database/psql/waifus.go similarity index 60% rename from database/waifus.go rename to database/psql/waifus.go index b18fa8d..c14cdb7 100644 --- a/database/waifus.go +++ b/database/psql/waifus.go @@ -1,6 +1,10 @@ -package database +package psql -import "github.com/shopspring/decimal" +import ( + "kurumibot/database" + + "github.com/shopspring/decimal" +) type Waifu struct { ID int @@ -18,36 +22,36 @@ type Waifu struct { func GetAllWaifus() ([]*Waifu, error) { waifus := make([]*Waifu, 0) - tx := Database.Joins("Owner").Find(&waifus).Order("id") + tx := database.PostgresDatabase.Joins("Owner").Find(&waifus).Order("id") return waifus, tx.Error } func GetUserWaifus(userId int) ([]*Waifu, error) { waifus := make([]*Waifu, 0) - tx := Database.Find(&waifus, "owner_id = ?", userId).Order("id") + tx := database.PostgresDatabase.Find(&waifus, "owner_id = ?", userId).Order("id") return waifus, tx.Error } func GetFreeWaifus() ([]*Waifu, error) { waifus := make([]*Waifu, 0) - tx := Database.Find(&waifus, "owner_id is null").Order("id") + tx := database.PostgresDatabase.Find(&waifus, "owner_id is null").Order("id") return waifus, tx.Error } func GetFreeWaifusCount() (int64, error) { var count int64 = 0 - tx := Database.Model(&Waifu{}).Where("owner_id is null").Count(&count) + tx := database.PostgresDatabase.Model(&Waifu{}).Where("owner_id is null").Count(&count) return count, tx.Error } func GetFreeWaifusWithRarity(rarity int) ([]*Waifu, error) { waifus := make([]*Waifu, 0) - tx := Database.Find(&waifus, "owner_id is null and rarity = ?", rarity) + tx := database.PostgresDatabase.Find(&waifus, "owner_id is null and rarity = ?", rarity) return waifus, tx.Error } func GetWaifuById(id int) (*Waifu, error) { waifu := new(Waifu) - tx := Database.Joins("Owner").Find(waifu, id) + tx := database.PostgresDatabase.Joins("Owner").Find(waifu, id) return waifu, tx.Error } diff --git a/database/works.go b/database/psql/works.go similarity index 63% rename from database/works.go rename to database/psql/works.go index 6018b83..8ee547f 100644 --- a/database/works.go +++ b/database/psql/works.go @@ -1,6 +1,10 @@ -package database +package psql -import "github.com/shopspring/decimal" +import ( + "kurumibot/database" + + "github.com/shopspring/decimal" +) type Work struct { ID int @@ -13,12 +17,12 @@ type Work struct { func GetWorkById(id int) (*Work, error) { work := new(Work) - tx := Database.First(work, id) + tx := database.PostgresDatabase.First(work, id) return work, tx.Error } func GetAllWorks() ([]*Work, error) { works := make([]*Work, 0) - tx := Database.Order("id").Find(&works) + tx := database.PostgresDatabase.Order("id").Find(&works) return works, tx.Error } diff --git a/database/redis.go b/database/redis.go new file mode 100644 index 0000000..b328675 --- /dev/null +++ b/database/redis.go @@ -0,0 +1,13 @@ +package database + +import "github.com/redis/go-redis/v9" + +var RedisClient *redis.Client + +func ConnectRedis() { + RedisClient = redis.NewClient(&redis.Options{ + Addr: "redis:6379", + Password: "", + DB: 0, + }) +} diff --git a/db.docker-compose.yml b/db.docker-compose.yml index d0fa60a..50e1274 100644 --- a/db.docker-compose.yml +++ b/db.docker-compose.yml @@ -1,6 +1,6 @@ services: postgres: - image: postgres:alpine + image: postgres:17.6-alpine3.22 networks: - bot restart: always @@ -19,7 +19,7 @@ services: - ./scripts/postgres:/docker-entrypoint-initdb.d - postgres_data:/var/lib/postgresql/data mongo: - image: mongo:noble + image: mongo:8.0.14-noble networks: - bot restart: always @@ -28,21 +28,24 @@ services: environment: MONGO_INITDB_ROOT_USERNAME: ${MONGO_USER} MONGO_INITDB_ROOT_PASSWORD: ${MONGO_PASS} - MONGO_INIDB_DATABASE: ${MONGO_NAME} + MONGO_INITDB_DATABASE: ${MONGO_NAME} volumes: - ./scripts/mongo:/docker-entrypoint-initdb.d - mongo_data:/data/db redis: - image: redis:alpine + image: redis:8.2.1-alpine networks: - bot restart: always ports: - "6379:6379" + volumes: + - redis_data:/data networks: bot: driver: bridge volumes: postgres_data: - mongo_data: \ No newline at end of file + mongo_data: + redis_data: \ No newline at end of file diff --git a/go.mod b/go.mod index f220b46..f892dbc 100644 --- a/go.mod +++ b/go.mod @@ -4,22 +4,33 @@ go 1.25.0 require ( github.com/fatih/color v1.18.0 + github.com/redis/go-redis/v9 v9.12.1 github.com/shopspring/decimal v1.4.0 + go.mongodb.org/mongo-driver/v2 v2.3.0 gorm.io/driver/postgres v1.6.0 - gorm.io/gorm v1.30.1 + gorm.io/gorm v1.30.2 ) require ( + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/golang/snappy v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect - github.com/jackc/pgx/v5 v5.7.1 // indirect + github.com/jackc/pgx/v5 v5.7.5 // indirect github.com/jackc/puddle/v2 v2.2.2 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect + github.com/joho/godotenv v1.5.1 // indirect + github.com/klauspost/compress v1.18.0 // indirect + github.com/mattn/go-colorable v0.1.14 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - golang.org/x/crypto v0.31.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/sys v0.28.0 // indirect - golang.org/x/text v0.21.0 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect + golang.org/x/crypto v0.41.0 // indirect + golang.org/x/sync v0.16.0 // indirect + golang.org/x/sys v0.35.0 // indirect + golang.org/x/text v0.28.0 // indirect ) diff --git a/go.sum b/go.sum index 3d2f486..fb789ba 100644 --- a/go.sum +++ b/go.sum @@ -1,27 +1,45 @@ +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= +github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 h1:iCEnooe7UlwOQYpKFhBabPMi4aNAfoODPEFNiAnClxo= github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgx/v5 v5.7.1 h1:x7SYsPBYDkHDksogeSmZZ5xzThcTgRz++I5E+ePFUcs= github.com/jackc/pgx/v5 v5.7.1/go.mod h1:e7O26IywZZ+naJtWWos6i6fvWK+29etgITqrqHLfoZA= +github.com/jackc/pgx/v5 v5.7.5 h1:JHGfMnQY+IEtGM63d+NGMjoRpysB2JBwDr5fsngwmJs= +github.com/jackc/pgx/v5 v5.7.5/go.mod h1:aruU7o91Tc2q2cFp5h4uP3f6ztExVpyVv88Xl/8Vl8M= github.com/jackc/puddle/v2 v2.2.2 h1:PR8nw+E/1w0GLuRFSmiioY6UooMp6KJv0/61nB7icHo= github.com/jackc/puddle/v2 v2.2.2/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFrfEOc3H4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I= +github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE= +github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= +github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= +github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/redis/go-redis/v9 v9.12.1 h1:k5iquqv27aBtnTm2tIkROUDp8JBXhXZIVu1InSgvovg= +github.com/redis/go-redis/v9 v9.12.1/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -29,21 +47,71 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver/v2 v2.3.0 h1:sh55yOXA2vUjW1QYw/2tRlHSQViwDyPnW61AwpZ4rtU= +go.mongodb.org/mongo-driver/v2 v2.3.0/go.mod h1:jHeEDJHJq7tm6ZF45Issun9dbogjfnPySb1vXA7EeAI= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.35.0 h1:b15kiHdrGCHrP6LvwaQ3c03kgNhhiMgvlhxHQhmg2Xs= +golang.org/x/crypto v0.35.0/go.mod h1:dy7dXNW32cAb/6/PRuTNsix8T+vJAqvuIy5Bli/x0YQ= +golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4= +golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.11.0 h1:GGz8+XQP4FvTTrjZPzNKTMFtSXH80RAzG+5ghFPgK9w= +golang.org/x/sync v0.11.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw= +golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.30.0 h1:QjkSwP/36a20jFYWkSue1YwXzLmsV5Gfq7Eiy72C1uc= +golang.org/x/sys v0.30.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI= +golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.22.0 h1:bofq7m3/HAFvbF51jz3Q9wLg3jkvSPuiZu/pD1XwgtM= +golang.org/x/text v0.22.0/go.mod h1:YRoo4H8PVmsu+E3Ou7cqLVH8oXWIHVoX0jqUWALQhfY= +golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng= +golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/postgres v1.6.0 h1:2dxzU8xJ+ivvqTRph34QX+WrRaJlmfyPqXmoGVjMBa4= gorm.io/driver/postgres v1.6.0/go.mod h1:vUw0mrGgrTK+uPHEhAdV4sfFELrByKVGnaVRkXDhtWo= -gorm.io/gorm v1.30.1 h1:lSHg33jJTBxs2mgJRfRZeLDG+WZaHYCk3Wtfl6Ngzo4= -gorm.io/gorm v1.30.1/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= +gorm.io/gorm v1.30.2 h1:f7bevlVoVe4Byu3pmbWPVHnPsLoWaMjEb7/clyr9Ivs= +gorm.io/gorm v1.30.2/go.mod h1:8Z33v652h4//uMA76KjeDH8mJXPm1QNCYrMeatR0DOE= diff --git a/main.go b/main.go index dd786b6..03a1557 100644 --- a/main.go +++ b/main.go @@ -2,25 +2,39 @@ package main import ( "kurumibot/database" + "kurumibot/database/psql" + "kurumibot/laniakea" "kurumibot/plugins" "log" - "os" - "kurumibot/laniakea" + "github.com/joho/godotenv" ) func main() { - database.Connect() - bot := laniakea.NewBot(&laniakea.BotSettings{ - Token: os.Getenv("TG_TOKEN"), - Debug: true, - Prefixes: laniakea.LoadPrefixesFromEnv(), - UseRequestLogger: true, - LoggerBasePath: "./logs/", - }) - log.Println(os.Getenv("PSQL_NAME")) - log.Println(os.Getenv("PREFIXES")) + err := godotenv.Load(".env", ".env.production") + if err != nil { + log.Println("Error loading .env file") + } + + database.ConnectPostgres() + database.ConnectMongo() + database.ConnectRedis() + err = psql.Migrate() + if err != nil { + log.Fatalln(err) + } + + bot := laniakea.NewBot(laniakea.LoadSettingsFromEnv()) + dbCtx := &laniakea.DatabaseContext{ + PostgresSQL: database.PostgresDatabase, + MongoDB: database.MongoClient, + Redis: database.RedisClient, + } bot = bot.ErrorTemplate("Во время выполнения команды произошла ошибка!\nСообщите об этом разработчику!\n\n%s") + bot = bot.InitDatabaseContext(dbCtx) + + bot.AddMiddleware(plugins.InitLogMiddleware()) + plugins.RegisterEconomy(bot) plugins.RegisterWaifus(bot) plugins.RegisterAdmin(bot) diff --git a/main.log b/main.log new file mode 100644 index 0000000..3e45c3f --- /dev/null +++ b/main.log @@ -0,0 +1,26 @@ +[LOG] [INFO] [28.08.2025 12:27:21] Bot running. Press CTRL+C to exit. +[LOG] [INFO] [28.08.2025 12:28:31] Bot running. Press CTRL+C to exit. +[LOG] [INFO] [28.08.2025 12:29:48] Bot running. Press CTRL+C to exit. +[LOG] [INFO] [28.08.2025 12:32:17] Bot running. Press CTRL+C to exit. +[LOG] [ERROR] [28.08.2025 12:32:28] [400] Bad Request: can't parse entities: Can't find end of the entity starting at byte offset 1636 +[LOG] [INFO] [28.08.2025 12:33:01] Bot running. Press CTRL+C to exit. +[LOG] [INFO] [28.08.2025 12:35:39] Bot running. Press CTRL+C to exit. +[LOG] [INFO] [28.08.2025 12:36:38] Bot running. Press CTRL+C to exit. +[LOG] [INFO] [28.08.2025 12:37:08] Bot running. Press CTRL+C to exit. +[LOG] [ERROR] [28.08.2025 12:37:12] [400] Bad Request: can't parse entities: Can't find end of the entity starting at byte offset 1578 +[LOG] [INFO] [28.08.2025 12:37:26] Bot running. Press CTRL+C to exit. +[LOG] [DEBUG] [29.09.2025 09:05:07] middleware with name "LogMiddleware" was registered +[LOG] [DEBUG] [29.09.2025 09:05:07] plugins with name "Economy" was registered +[LOG] [DEBUG] [29.09.2025 09:05:07] plugins with name "Waifus" was registered +[LOG] [DEBUG] [29.09.2025 09:05:07] plugins with name "Admin" was registered +[LOG] [INFO] [29.09.2025 09:05:07] Bot running. Press CTRL+C to exit. +[LOG] [DEBUG] [29.09.2025 09:11:32] middleware with name "LogMiddleware" was registered +[LOG] [DEBUG] [29.09.2025 09:11:32] plugins with name "Economy" was registered +[LOG] [DEBUG] [29.09.2025 09:11:32] plugins with name "Waifus" was registered +[LOG] [DEBUG] [29.09.2025 09:11:32] plugins with name "Admin" was registered +[LOG] [INFO] [29.09.2025 09:11:32] Bot running. Press CTRL+C to exit. +[LOG] [DEBUG] [29.09.2025 09:13:53] middleware with name "LogMiddleware" was registered +[LOG] [DEBUG] [29.09.2025 09:13:53] plugins with name "Economy" was registered +[LOG] [DEBUG] [29.09.2025 09:13:53] plugins with name "Waifus" was registered +[LOG] [DEBUG] [29.09.2025 09:13:53] plugins with name "Admin" was registered +[LOG] [INFO] [29.09.2025 09:13:53] Bot running. Press CTRL+C to exit. diff --git a/plugins/admin.go b/plugins/admin.go index 2832c15..366c4a0 100644 --- a/plugins/admin.go +++ b/plugins/admin.go @@ -1,7 +1,7 @@ package plugins import ( - "kurumibot/database" + "kurumibot/database/psql" "kurumibot/laniakea" ) @@ -13,16 +13,16 @@ func RegisterAdmin(b *laniakea.Bot) { b.AddPlugins(p.Build()) } -func uploadPhoto(ctx *laniakea.MsgContext) { - user, err := database.GetOrCreateUser(ctx.FromID, ctx.Msg.From.FirstName) +func uploadPhoto(msgContext *laniakea.MsgContext, _ *laniakea.DatabaseContext) { + user, err := psql.GetOrCreateUser(msgContext.FromID, msgContext.Msg.From.FirstName) if err != nil { - ctx.Error(err) + msgContext.Error(err) return } if !user.Group.IsAdmin { return } - photoId := ctx.Msg.Photo[0].FileID - ctx.AnswerPhoto(photoId, photoId) + photoId := msgContext.Msg.Photo[0].FileID + msgContext.AnswerPhoto(photoId, photoId) } diff --git a/plugins/economy.go b/plugins/economy.go index 9fee20a..a2a5761 100644 --- a/plugins/economy.go +++ b/plugins/economy.go @@ -3,6 +3,7 @@ package plugins import ( "fmt" "kurumibot/database" + "kurumibot/database/psql" "kurumibot/utils" "math" "math/rand/v2" @@ -34,17 +35,17 @@ func RegisterEconomy(bot *laniakea.Bot) { bot.AddPlugins(economy.Build()) } -func about(ctx *laniakea.MsgContext) { +func about(msgCtx *laniakea.MsgContext, _ *laniakea.DatabaseContext) { out := []string{ - "Версия Go: 1.23.4", - fmt.Sprintf("Версия laniakea: %s", laniakea.VERSION_STRING), + fmt.Sprintf("Go: %s", "1.25.0"), + fmt.Sprintf("Версия laniakea: %s", laniakea.VersionString), } - ctx.Answer(strings.Join(out, "\n")) + msgCtx.Answer(strings.Join(out, "\n")) } func passiveIncome(b *laniakea.Bot) { for { - users, err := database.GetAllUsers() + users, err := psql.GetAllUsers() if err != nil { b.Logger().Error(err) continue @@ -73,7 +74,7 @@ func passiveIncome(b *laniakea.Bot) { btcIncome = btcIncome.Add(user.Miner.Income).Mul(user.Group.Multiplier) } - waifus, err := database.GetUserWaifus(user.ID) + waifus, err := psql.GetUserWaifus(user.ID) if err != nil { b.Logger().Error(err) continue @@ -92,7 +93,7 @@ func passiveIncome(b *laniakea.Bot) { user.MoneyIncome = user.MoneyIncome.Add(moneyIncome) user.BtcIncome = user.BtcIncome.Add(btcIncome) user.IncomeTime = time.Now().Add(-time.Hour * 2) - database.Database.Save(user) + database.PostgresDatabase.Save(user) b.Logger().Debug(fmt.Sprintf("У %d было пассивно собрано. След. сбор через час\n", user.TelegramID)) } @@ -101,8 +102,8 @@ func passiveIncome(b *laniakea.Bot) { } } -func profile(ctx *laniakea.MsgContext) { - user, err := database.GetOrCreateUser(ctx.FromID, ctx.Update.Message.From.FirstName) +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 @@ -117,7 +118,24 @@ func profile(ctx *laniakea.MsgContext) { if user.Fraction != nil { fraction = user.Fraction.Name } - _, needXp := database.CountLevel(user.Exp) + + 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), @@ -128,16 +146,16 @@ func profile(ctx *laniakea.MsgContext) { 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 (ID: %d)", user.Auto.Name, user.Auto.ID), - fmt.Sprintf("🏢Бизнес: %s (ID: %d)", user.Business.Name, user.Business.ID), - fmt.Sprintf("👩‍🦳Горничная: %s (ID: %d)", user.Maid.Name, user.Maid.ID), - fmt.Sprintf("🖥Майнер: %s (ID: %d)", user.Miner.Name, user.Miner.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) { - user, err := database.GetOrCreateUser(ctx.FromID, ctx.Update.Message.From.FirstName) +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 @@ -158,7 +176,7 @@ func work(ctx *laniakea.MsgContext) { // Count money moneyToAdd := work.MoneyIncome.Mul(user.Group.Multiplier) - waifus, err := database.GetUserWaifus(user.ID) + waifus, err := psql.GetUserWaifus(user.ID) if err != nil { ctx.Error(err) return @@ -170,13 +188,17 @@ func work(ctx *laniakea.MsgContext) { user.Exp += int(expToAdd.IntPart()) user.Balance = user.Balance.Add(moneyToAdd) user.WorkTime = time.Now() - user.Level, _ = database.CountLevel(user.Exp) - database.Database.Save(user) - ctx.Answer(fmt.Sprintf("Ты заработал %s¥ и %d опыта.\nПриходи через 10 минут.", utils.DecimalComma(&work.MoneyIncome), expToAdd.IntPart())) + 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) { - user, err := database.GetOrCreateUser(ctx.FromID, ctx.Update.Message.From.FirstName) +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 @@ -212,7 +234,7 @@ func collect(ctx *laniakea.MsgContext) { btcIncome = btcIncome.Add(user.Miner.Income).Mul(user.Group.Multiplier) } - waifus, err := database.GetUserWaifus(user.ID) + waifus, err := psql.GetUserWaifus(user.ID) if err != nil { ctx.Error(err) return @@ -224,7 +246,7 @@ func collect(ctx *laniakea.MsgContext) { btcIncome = btcIncome.Mul(waifu.MoneyBonus) } - incomeText := []string{} + var incomeText []string if moneyIncome.IntPart() > 0 { incomeText = append(incomeText, fmt.Sprintf("%s¥", utils.DecimalComma(&moneyIncome))) @@ -236,7 +258,7 @@ func collect(ctx *laniakea.MsgContext) { incomeText = append(incomeText, fmt.Sprintf("%.6f₿", btcIncome.InexactFloat64())) } - passiveIncomeText := []string{} + 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))) @@ -255,11 +277,11 @@ func collect(ctx *laniakea.MsgContext) { user.Balance = user.Balance.Add(moneyIncome) user.Exp += int(expIncome.IntPart()) - user.Level, _ = database.CountLevel(user.Exp) + user.Level, _ = psql.CountLevel(user.Exp) user.BTC = user.BTC.Add(btcIncome) user.IncomeTime = time.Now() - database.Database.Save(user) + database.PostgresDatabase.Save(user) out := []string{ fmt.Sprintf("Ты собрал %s.", strings.Join(incomeText, ", ")), @@ -274,12 +296,12 @@ func collect(ctx *laniakea.MsgContext) { ctx.Answer(strings.Join(out, "\n")) } -func code(ctx *laniakea.MsgContext) { +func code(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) { // user, err := database.Get } -func vacancies(ctx *laniakea.MsgContext) { - works, err := database.GetAllWorks() +func vacancies(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) { + works, err := psql.GetAllWorks() if err != nil { ctx.Error(err) @@ -297,13 +319,13 @@ func vacancies(ctx *laniakea.MsgContext) { ctx.Answer(strings.Join(out, "\n")) } -func getAJob(ctx *laniakea.MsgContext) { +func getAJob(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) { if len(ctx.Args) == 0 { ctx.Answer("Недостаточно аргументов") return } - user, err := database.GetOrCreateUser(ctx.FromID, ctx.Msg.From.FirstName) + user, err := psql.GetOrCreateUser(ctx.FromID, ctx.Msg.From.FirstName) if err != nil { ctx.Error(err) return @@ -313,7 +335,7 @@ func getAJob(ctx *laniakea.MsgContext) { ctx.Error(err) return } - work, err := database.GetWorkById(workId) + work, err := psql.GetWorkById(workId) if err != nil { ctx.Error(err) return @@ -324,12 +346,12 @@ func getAJob(ctx *laniakea.MsgContext) { } user.WorkID = workId user.Work = work - database.Database.Save(user) + database.PostgresDatabase.Save(user) ctx.Answer("Ты успешно устроился на работу!") } -func aboutGroup(ctx *laniakea.MsgContext) { - user, err := database.GetOrCreateUser(ctx.FromID, ctx.Msg.From.FirstName) +func aboutGroup(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) { + user, err := psql.GetOrCreateUser(ctx.FromID, ctx.Msg.From.FirstName) if err != nil { ctx.Error(err) return diff --git a/plugins/logs.go b/plugins/logs.go new file mode 100644 index 0000000..5787b27 --- /dev/null +++ b/plugins/logs.go @@ -0,0 +1,27 @@ +package plugins + +import ( + "fmt" + "kurumibot/database/mdb" + "kurumibot/laniakea" + "time" +) + +func InitLogsPlugin() {} +func InitLogMiddleware() *laniakea.Middleware { + middle := laniakea.NewMiddleware("LogMiddleware") + middle = middle.SetExecutor(logMiddleware).SetAsync(true) + return middle.Build() +} + +func logMiddleware(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { + entry := &mdb.MessageLogEntry{ + MessageID: ctx.Msg.MessageID, + SenderID: ctx.FromID, + ChatID: ctx.Msg.Chat.ID, + Text: ctx.Msg.Text, + TimeStamp: time.Now().Unix(), + } + err := mdb.WriteMessageLog(db, entry) + fmt.Println(err) +} diff --git a/plugins/waifus.go b/plugins/waifus.go index 0369304..1f06eec 100644 --- a/plugins/waifus.go +++ b/plugins/waifus.go @@ -2,7 +2,7 @@ package plugins import ( "fmt" - "kurumibot/database" + "kurumibot/database/psql" "kurumibot/utils" "strconv" "strings" @@ -23,8 +23,8 @@ func RegisterWaifus(bot *laniakea.Bot) { bot.AddPlugins(waifus.Build()) } -func myWaifu(ctx *laniakea.MsgContext) { - user, err := database.GetUser(ctx.FromID) +func myWaifu(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) { + user, err := psql.GetUser(ctx.FromID) if err != nil { ctx.Answer(err.Error()) return @@ -35,7 +35,7 @@ func myWaifu(ctx *laniakea.MsgContext) { "Список твоих вайфу:", } - waifus, err := database.GetUserWaifus(user.ID) + waifus, err := psql.GetUserWaifus(user.ID) if err != nil { ctx.Error(err) return @@ -48,17 +48,17 @@ func myWaifu(ctx *laniakea.MsgContext) { ctx.Answer(strings.Join(out, "\n")) } -func sellWaifu(ctx *laniakea.MsgContext) { +func sellWaifu(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) { } -func waifuList(ctx *laniakea.MsgContext) { - waifus, err := database.GetAllWaifus() +func waifuList(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) { + waifus, err := psql.GetAllWaifus() if err != nil { ctx.Answer(err.Error()) return } - out := []string{} + var out []string for _, w := range waifus { var owner string @@ -74,7 +74,7 @@ func waifuList(ctx *laniakea.MsgContext) { ctx.Answer(strings.Join(out, "\n")) } -func waifuInfo(ctx *laniakea.MsgContext) { +func waifuInfo(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) { rawArgs := strings.TrimSpace(ctx.Text) args := strings.Split(rawArgs, " ") if len(args) != 1 { @@ -88,7 +88,7 @@ func waifuInfo(ctx *laniakea.MsgContext) { return } - waifu, err := database.GetWaifuById(waifuId) + waifu, err := psql.GetWaifuById(waifuId) if err != nil { ctx.Error(err) return @@ -108,8 +108,8 @@ func waifuInfo(ctx *laniakea.MsgContext) { } } -func waifuSearch(ctx *laniakea.MsgContext) { - user, err := database.GetOrCreateUser(ctx.FromID, ctx.Msg.From.FirstName) +func waifuSearch(ctx *laniakea.MsgContext, _ *laniakea.DatabaseContext) { + user, err := psql.GetOrCreateUser(ctx.FromID, ctx.Msg.From.FirstName) if err != nil { ctx.Error(err) return @@ -120,7 +120,7 @@ func waifuSearch(ctx *laniakea.MsgContext) { return } - count, err := database.GetFreeWaifusCount() + count, err := psql.GetFreeWaifusCount() if err != nil { ctx.Error(err) return @@ -136,7 +136,7 @@ func waifuSearch(ctx *laniakea.MsgContext) { return } - var freeWaifus []*database.Waifu + var freeWaifus []*psql.Waifu rarity := 3 if rand == 0 { rarity = 5 @@ -146,7 +146,7 @@ func waifuSearch(ctx *laniakea.MsgContext) { fmt.Println(rarity) - freeWaifus, err = database.GetFreeWaifusWithRarity(rarity) + freeWaifus, err = psql.GetFreeWaifusWithRarity(rarity) if err != nil { ctx.Error(err) return @@ -157,8 +157,8 @@ func waifuSearch(ctx *laniakea.MsgContext) { return } - findedWaifuIndex := utils.RandRange(0, len(freeWaifus)) - waifu := freeWaifus[findedWaifuIndex] + foundWaifuIndex := utils.RandRange(0, len(freeWaifus)) + waifu := freeWaifus[foundWaifuIndex] out := []string{ "Ты нашел новую вайфу!", fmt.Sprintf("*%s* из \"*%s*\"", waifu.Name, waifu.Fandom), diff --git a/requests.log b/requests.log new file mode 100644 index 0000000..47c4725 --- /dev/null +++ b/requests.log @@ -0,0 +1,30 @@ +[REQUESTS] [DEBUG] [29.09.2025 09:05:07] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":0,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:05:38] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":0,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:05:43] UPDATE {"message":{"chat":{"first_name":"scuroneko","id":314834933,"type":"private","username":"scuroneko"},"date":1759125940,"entities":[{"length":8,"offset":0,"type":"bot_command"}],"from":{"first_name":"scuroneko","id":314834933,"is_bot":false,"language_code":"ru","username":"scuroneko"},"message_id":584,"text":"/profile"},"update_id":475625435} +[REQUESTS] [DEBUG] [29.09.2025 09:05:43] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:05:43] POST https://api.telegram.org/bot/sendMessage {"chat_id":314834933,"parse_mode":"markdown","text":"🖤, scuroneko🖤\n🆔ID: 1\n🔰Фракция: нет\n📊Группа: ✨Пользователь✨ (ID: 1, x1.0)\n❤️Пара: нет\n💡Уровень: 1 (0 опыта, 48 опыта до повышения)\n💴Баланс: 0¥ (0 ), 0₿\n💼Работа: Уборщик в маке (ID: 1)\n🚘Авто: нет\n🏢Бизнес: нет\n👩‍🦳Горничная: нет\n🖥Майнер: нет"} +[REQUESTS] [DEBUG] [29.09.2025 09:06:13] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:06:43] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:07:13] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:07:43] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:08:13] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:08:44] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:09:14] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:09:44] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:10:14] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:10:44] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:11:14] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625436,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:11:32] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":0,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:11:37] UPDATE {"message":{"chat":{"first_name":"scuroneko","id":314834933,"type":"private","username":"scuroneko"},"date":1759126293,"entities":[{"length":8,"offset":0,"type":"bot_command"}],"from":{"first_name":"scuroneko","id":314834933,"is_bot":false,"language_code":"ru","username":"scuroneko"},"message_id":586,"text":"/profile"},"update_id":475625436} +[REQUESTS] [DEBUG] [29.09.2025 09:11:37] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625437,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:11:37] POST https://api.telegram.org/bot/sendMessage {"chat_id":314834933,"parse_mode":"markdown","text":"🖤, scuroneko🖤\n🆔ID: 1\n🔰Фракция: нет\n📊Группа: ✨Пользователь✨ (ID: 1, x1.0)\n❤️Пара: нет\n💡Уровень: 1 (0 опыта, 48 опыта до повышения)\n💴Баланс: 0¥ (0 ), 0₿\n💼Работа: Уборщик в маке (ID: 1)\n🚘Авто: нет\n🏢Бизнес: нет\n👩‍🦳Горничная: нет\n🖥Майнер: нет"} +[REQUESTS] [DEBUG] [29.09.2025 09:12:07] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625437,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:12:37] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625437,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:13:07] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625437,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:13:23] UPDATE {"message":{"chat":{"first_name":"scuroneko","id":314834933,"type":"private","username":"scuroneko"},"date":1759126400,"entities":[{"length":8,"offset":0,"type":"bot_command"}],"from":{"first_name":"scuroneko","id":314834933,"is_bot":false,"language_code":"ru","username":"scuroneko"},"message_id":588,"text":"/profile"},"update_id":475625437} +[REQUESTS] [DEBUG] [29.09.2025 09:13:23] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625438,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:13:23] POST https://api.telegram.org/bot/sendMessage {"chat_id":314834933,"parse_mode":"markdown","text":"🖤, scuroneko🖤\n🆔ID: 1\n🔰Фракция: нет\n📊Группа: ✨Пользователь✨ (ID: 1, x1.0)\n❤️Пара: нет\n💡Уровень: 1 (0 опыта, 48 опыта до повышения)\n💴Баланс: 0¥ (0 ), 0₿\n💼Работа: Уборщик в маке (ID: 1)\n🚘Авто: нет\n🏢Бизнес: нет\n👩‍🦳Горничная: нет\n🖥Майнер: нет"} +[REQUESTS] [DEBUG] [29.09.2025 09:13:53] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":0,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:13:58] UPDATE {"message":{"chat":{"first_name":"scuroneko","id":314834933,"type":"private","username":"scuroneko"},"date":1759126435,"entities":[{"length":8,"offset":0,"type":"bot_command"}],"from":{"first_name":"scuroneko","id":314834933,"is_bot":false,"language_code":"ru","username":"scuroneko"},"message_id":590,"text":"/profile"},"update_id":475625438} +[REQUESTS] [DEBUG] [29.09.2025 09:13:58] POST https://api.telegram.org/bot/getUpdates {"allowed_updates":[],"offset":475625439,"timeout":30} +[REQUESTS] [DEBUG] [29.09.2025 09:13:58] POST https://api.telegram.org/bot/sendMessage {"chat_id":314834933,"parse_mode":"markdown","text":"🖤, scuroneko🖤\n🆔ID: 1\n🔰Фракция: нет\n📊Группа: ✨Пользователь✨ (ID: 1, x1.0)\n❤️Пара: нет\n💡Уровень: 1 (0 опыта, 48 опыта до повышения)\n💴Баланс: 0¥ (0 ), 0₿\n💼Работа: Уборщик в маке (ID: 1)\n🚘Авто: нет\n🏢Бизнес: нет\n👩‍🦳Горничная: нет\n🖥Майнер: нет"} diff --git a/scripts/postgres/Init.sql b/scripts/postgres/Init.sql new file mode 100644 index 0000000..230ca57 --- /dev/null +++ b/scripts/postgres/Init.sql @@ -0,0 +1,171 @@ +SET statement_timeout = 0; +SET lock_timeout = 0; +SET idle_in_transaction_session_timeout = 0; +SET transaction_timeout = 0; +SET client_encoding = 'UTF8'; +SET standard_conforming_strings = on; +SELECT pg_catalog.set_config('search_path', '', false); +SET check_function_bodies = false; +SET xmloption = content; +SET client_min_messages = warning; +SET row_security = off; +SET default_tablespace = ''; +SET default_table_access_method = heap; + +CREATE TABLE public.groups ( + id integer NOT NULL, + name text, + is_admin boolean DEFAULT false NOT NULL, + is_vip boolean DEFAULT false NOT NULL, + multiplier numeric DEFAULT 1 NOT NULL, + sale double precision DEFAULT 1 NOT NULL, + max_multigen integer DEFAULT 2 NOT NULL, + is_tester boolean DEFAULT false NOT NULL, + max_waifus integer DEFAULT 3 NOT NULL +); +ALTER TABLE public.groups OWNER TO kurumi_bot; +CREATE SEQUENCE public.groups_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE public.groups_id_seq OWNER TO kurumi_bot; +ALTER SEQUENCE public.groups_id_seq OWNED BY public.groups.id; + +CREATE TABLE public.shop_autos ( + id integer NOT NULL, + name text DEFAULT ''::text NOT NULL, + price numeric(20,0) DEFAULT '999999999999'::bigint NOT NULL +); +ALTER TABLE public.shop_autos OWNER TO kurumi_bot; +CREATE SEQUENCE public.shop_autos_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE public.shop_autos_id_seq OWNER TO kurumi_bot; +ALTER SEQUENCE public.shop_autos_id_seq OWNED BY public.shop_autos.id; + +CREATE TABLE public.shop_businesses ( + id integer NOT NULL, + name text DEFAULT ''::text NOT NULL, + price numeric(20,0) DEFAULT 999999999 NOT NULL, + income numeric(20,0) DEFAULT 0 NOT NULL +); +ALTER TABLE public.shop_businesses OWNER TO kurumi_bot; +CREATE SEQUENCE public.shop_businesses_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE public.shop_businesses_id_seq OWNER TO kurumi_bot; +ALTER SEQUENCE public.shop_businesses_id_seq OWNED BY public.shop_businesses.id; + +CREATE TABLE public.shop_maids ( + id integer NOT NULL, + name text DEFAULT ''::text NOT NULL, + price numeric(20,0) DEFAULT 0 NOT NULL, + income numeric(20,0) DEFAULT 0 NOT NULL +); +ALTER TABLE public.shop_maids OWNER TO kurumi_bot; +CREATE SEQUENCE public.shop_maids_id_seq AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE public.shop_maids_id_seq OWNER TO kurumi_bot; +ALTER SEQUENCE public.shop_maids_id_seq OWNED BY public.shop_maids.id; + +CREATE TABLE public.shop_miners ( + id integer NOT NULL, + name text DEFAULT ''::text NOT NULL, + price numeric(20,0) DEFAULT 1 NOT NULL, + income numeric(20,6) DEFAULT 1 NOT NULL +); +ALTER TABLE public.shop_miners OWNER TO kurumi_bot; +CREATE SEQUENCE public.shop_miners_id_seq START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE public.shop_miners_id_seq OWNER TO kurumi_bot; +ALTER SEQUENCE public.shop_miners_id_seq OWNED BY public.shop_miners.id; + +CREATE TABLE public.works ( + id integer NOT NULL, + name text NOT NULL, + required_level integer DEFAULT 1 NOT NULL, + money_income numeric(10,0) DEFAULT 1 NOT NULL, + min_exp integer DEFAULT 1 NOT NULL, + max_exp integer DEFAULT 1 NOT NULL +); +ALTER TABLE public.works OWNER TO kurumi_bot; +CREATE SEQUENCE public.works_id_seq AS integer START WITH 1 INCREMENT BY 1 NO MINVALUE NO MAXVALUE CACHE 1; +ALTER SEQUENCE public.works_id_seq OWNER TO kurumi_bot; +ALTER SEQUENCE public.works_id_seq OWNED BY public.works.id; + +ALTER TABLE ONLY public.groups ALTER COLUMN id SET DEFAULT nextval('public.groups_id_seq'::regclass); +ALTER TABLE ONLY public.shop_autos ALTER COLUMN id SET DEFAULT nextval('public.shop_autos_id_seq'::regclass); +ALTER TABLE ONLY public.shop_businesses ALTER COLUMN id SET DEFAULT nextval('public.shop_businesses_id_seq'::regclass); +ALTER TABLE ONLY public.shop_maids ALTER COLUMN id SET DEFAULT nextval('public.shop_maids_id_seq'::regclass); +ALTER TABLE ONLY public.shop_miners ALTER COLUMN id SET DEFAULT nextval('public.shop_miners_id_seq'::regclass); +ALTER TABLE ONLY public.works ALTER COLUMN id SET DEFAULT nextval('public.works_id_seq'::regclass); + +INSERT INTO public.groups VALUES (1, '✨Пользователь✨', false, false, 1.0, 1, 3, false, 3); +INSERT INTO public.groups VALUES (3, '👾Премиум🌟', false, true, 5, 0.75, 7, false, 3); +INSERT INTO public.groups VALUES (2, '🔮VIP🔮', false, true, 2.5, 0.9, 5, false, 3); +INSERT INTO public.groups VALUES (4, '💎Админ💎', true, true, 10, 0.6, 10, true, 3); +INSERT INTO public.groups VALUES (5, '💰🔱СОЗДАТЕЛЬ🔱💰', true, true, 20, 0.5, 10, true, 3); +INSERT INTO public.groups VALUES (6, '⚠Тостер⚠', false, true, 3, 0.85, 3, true, 3); +INSERT INTO public.groups VALUES (1488, '📚Экономист📈', false, true, 14.88, 0.6, 3, false, 3); +INSERT INTO public.groups VALUES (1337, '🏳‍🌈ToP GaY In ThE WorlD🏳‍🌈🌈', false, true, 13.37, 0.7, 3, false, 3); + +INSERT INTO public.shop_autos VALUES (1, 'Москвич 412', 40000); +INSERT INTO public.shop_autos VALUES (2, 'ВАЗ 2105', 100000); +INSERT INTO public.shop_autos VALUES (3, 'Nissan Skyline GT-R R32', 225000); +INSERT INTO public.shop_autos VALUES (4, 'Toyota AE86 Sprinter Trueno', 450000); +INSERT INTO public.shop_autos VALUES (5, 'Toyota Mark II X90 Tourer V', 800000); +INSERT INTO public.shop_autos VALUES (6, 'Mazda RX-7 FD3S', 1200000); +INSERT INTO public.shop_autos VALUES (7, 'Mitsubishi Lancer Evolution X', 1650000); +INSERT INTO public.shop_autos VALUES (8, 'Subaru Impreza WRX STI II', 1875000); + +INSERT INTO public.shop_businesses VALUES (1, 'Стенд с лимонадом', 200000, 1500); +INSERT INTO public.shop_businesses VALUES (2, 'Союзпечать', 1000000, 7000); +INSERT INTO public.shop_businesses VALUES (3, 'Маленький магазин вещей из Китая', 2500000, 17500); +INSERT INTO public.shop_businesses VALUES (4, 'Ларёк с шаурмой', 3000000, 21000); +INSERT INTO public.shop_businesses VALUES (5, 'Магазин тофу', 5000000, 35000); +INSERT INTO public.shop_businesses VALUES (6, 'Соц. сеть', 10000000, 70000); +INSERT INTO public.shop_businesses VALUES (7, 'Продажа машин из Японии', 20000000, 140000); +INSERT INTO public.shop_businesses VALUES (8, 'Автосервис', 40000000, 280000); +INSERT INTO public.shop_businesses VALUES (9, 'Компания по разработке игр', 100000000, 700000); +INSERT INTO public.shop_businesses VALUES (10, 'Аниме студия', 250000000, 1725000); +INSERT INTO public.shop_businesses VALUES (11, 'Сеть магазинов', 500000000, 3500000); +INSERT INTO public.shop_businesses VALUES (12, 'Сеть заводов', 1000000000, 7000000); +INSERT INTO public.shop_businesses VALUES (13, 'Автосалон', 10000000000, 70000000); +INSERT INTO public.shop_businesses VALUES (14, 'Бренд электроники', 50000000000, 350000000); +INSERT INTO public.shop_businesses VALUES (15, 'Автомобильная марка', 100000000000, 700000000); + +INSERT INTO public.shop_maids VALUES (1, 'Кавайная горничная', 50, 7500); +INSERT INTO public.shop_maids VALUES (2, 'Кавайная в кружеве', 100, 15000); +INSERT INTO public.shop_maids VALUES (3, 'Тору', 250, 30000); +INSERT INTO public.shop_maids VALUES (4, 'Лоли горничные', 500, 52500); +INSERT INTO public.shop_maids VALUES (5, 'Рам и Рем', 2000, 150000); +INSERT INTO public.shop_maids VALUES (6, 'Неко-горничная', 4500, 225000); + +INSERT INTO public.shop_miners VALUES (1, 'Старый ПК', 20000, 0.000001); +INSERT INTO public.shop_miners VALUES (2, 'Новый ПК', 120000, 0.000005); +INSERT INTO public.shop_miners VALUES (3, 'Маленький майнер', 250000, 0.000010); +INSERT INTO public.shop_miners VALUES (4, 'Средний майнер', 600000, 0.000025); +INSERT INTO public.shop_miners VALUES (5, 'Большой майнер', 1000000, 0.000050); +INSERT INTO public.shop_miners VALUES (6, 'Огромный майнер', 2500000, 0.000100); +INSERT INTO public.shop_miners VALUES (7, 'Маленькая ферма майнеров', 10000000, 0.000500); +INSERT INTO public.shop_miners VALUES (8, 'Средняя ферма майнкеров', 100000000, 0.005000); +INSERT INTO public.shop_miners VALUES (9, 'Большая ферма майнеров', 500000000, 0.025000); +INSERT INTO public.shop_miners VALUES (10, 'Огромная ферма майнеров', 5000000000, 0.250000); +INSERT INTO public.shop_miners VALUES (11, 'Гигантская ферма майнеров', 10000000000, 0.500000); +INSERT INTO public.shop_miners VALUES (12, 'Комната майнеров', 25000000000, 1.000000); +INSERT INTO public.shop_miners VALUES (13, 'Этаж с майнерми', 100000000000, 5.000000); +INSERT INTO public.shop_miners VALUES (14, 'Небоскреб майнеров', 250000000000, 10.000000); + +INSERT INTO public.works VALUES (1, 'Уборщик в маке', 1, 13000, 20, 28); +INSERT INTO public.works VALUES (2, 'Рабочий на заводе', 3, 20000, 48, 65); +INSERT INTO public.works VALUES (3, 'Продавец в пятёрочке', 5, 25000, 76, 103); +INSERT INTO public.works VALUES (4, 'Учитель', 7, 40000, 104, 141); +INSERT INTO public.works VALUES (5, 'Повар', 9, 50000, 175, 237); +INSERT INTO public.works VALUES (6, 'Полицейский', 11, 60000, 260, 351); +INSERT INTO public.works VALUES (7, 'Художник', 13, 80000, 305, 412); +INSERT INTO public.works VALUES (8, 'Программист', 15, 100000, 350, 474); + +SELECT pg_catalog.setval('public.groups_id_seq', 7, false); +SELECT pg_catalog.setval('public.shop_autos_id_seq', 8, true); +SELECT pg_catalog.setval('public.shop_businesses_id_seq', 15, true); +SELECT pg_catalog.setval('public.shop_maids_id_seq', 6, true); +SELECT pg_catalog.setval('public.shop_miners_id_seq', 14, true); +SELECT pg_catalog.setval('public.works_id_seq', 8, true); + +ALTER TABLE ONLY public.groups ADD CONSTRAINT groups_pk PRIMARY KEY (id); +ALTER TABLE ONLY public.shop_autos ADD CONSTRAINT shop_autos_pk PRIMARY KEY (id); +ALTER TABLE ONLY public.shop_businesses ADD CONSTRAINT shop_businesses_pk PRIMARY KEY (id); +ALTER TABLE ONLY public.shop_maids ADD CONSTRAINT shop_maids_pk PRIMARY KEY (id); +ALTER TABLE ONLY public.shop_miners ADD CONSTRAINT shop_miners_pk PRIMARY KEY (id); +ALTER TABLE ONLY public.works ADD CONSTRAINT works_pk PRIMARY KEY (id); \ No newline at end of file