From 62d91dfe071e72f966f75adda8d0633ae1712eee Mon Sep 17 00:00:00 2001 From: ScuroNeko Date: Wed, 4 Feb 2026 13:38:36 +0300 Subject: [PATCH] many changes --- database/psql/waifus.go | 3 +- go.mod | 7 ++-- go.sum | 5 ++- main.go | 7 ++-- plugins/admin.go | 15 ++++---- plugins/rp.go | 27 +++++++------- scripts/postgres/02-users.sql | 3 +- scripts/postgres/04-waifus.sql | 4 +-- utils/utils.go | 66 ++-------------------------------- 9 files changed, 43 insertions(+), 94 deletions(-) diff --git a/database/psql/waifus.go b/database/psql/waifus.go index 48a361f..1626be8 100644 --- a/database/psql/waifus.go +++ b/database/psql/waifus.go @@ -3,6 +3,7 @@ package psql import ( "database/sql" + "git.nix13.pw/scuroneko/extypes" "git.nix13.pw/scuroneko/laniakea" "github.com/shopspring/decimal" "github.com/vinovest/sqlx" @@ -30,7 +31,7 @@ func NewWaifuRepository(db *laniakea.DatabaseContext) *WaifuRepository { return &WaifuRepository{db: db.PostgresSQL} } -func (rep *WaifuRepository) GetAll() ([]*Waifu, error) { +func (rep *WaifuRepository) GetAll() (extypes.Slice[*Waifu], error) { waifus, err := sqlx.List[*Waifu](rep.db, "SELECT waifus.* FROM waifus;") if err != nil { return nil, err diff --git a/go.mod b/go.mod index 87e2df4..a5d1121 100644 --- a/go.mod +++ b/go.mod @@ -1,9 +1,10 @@ module kurumibot -go 1.25 +go 1.25.6 require ( - git.nix13.pw/scuroneko/laniakea v0.3.6 + git.nix13.pw/scuroneko/extypes v1.0.3 + git.nix13.pw/scuroneko/laniakea v0.3.9 git.nix13.pw/scuroneko/slog v1.0.2 github.com/google/uuid v1.6.0 github.com/joho/godotenv v1.5.1 @@ -14,7 +15,7 @@ require ( go.mongodb.org/mongo-driver/v2 v2.5.0 ) -//replace git.nix13.pw/scuroneko/laniakea v0.3.6 => ./laniakea +//replace git.nix13.pw/scuroneko/laniakea v0.3.9 => ./laniakea require ( github.com/cespare/xxhash/v2 v2.3.0 // indirect diff --git a/go.sum b/go.sum index cefca67..49686dc 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,9 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= -git.nix13.pw/scuroneko/laniakea v0.3.6/go.mod h1:ku3xWszXrB4elK7R4AqIn8GMKpWBV2pEnrpAZqxeMLQ= +git.nix13.pw/scuroneko/extypes v1.0.3 h1:9qhvrhE7Hh1uiF5JINVxaXPtqQ+w+b1eOgwDGxhFFuY= +git.nix13.pw/scuroneko/extypes v1.0.3/go.mod h1:uZVs8Yo3RrYAG9dMad6qR6lsYY67t+459D9c65QAYAw= +git.nix13.pw/scuroneko/laniakea v0.3.9 h1:fUsqdODk8eq0CRNkxUOTwlytlgidK0KwE7Ji9KvtEkY= +git.nix13.pw/scuroneko/laniakea v0.3.9/go.mod h1:g4NsbbsRW2/JpVEqjldzf3hoP+rJtDRVtZQD6K7ma+g= git.nix13.pw/scuroneko/slog v1.0.2 h1:vZyUROygxC2d5FJHUQM/30xFEHY1JT/aweDZXA4rm2g= git.nix13.pw/scuroneko/slog v1.0.2/go.mod h1:3Qm2wzkR5KjwOponMfG7TcGSDjmYaFqRAmLvSPTuWJI= github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= diff --git a/main.go b/main.go index aa966b2..c9a2855 100644 --- a/main.go +++ b/main.go @@ -17,13 +17,12 @@ func main() { database.ConnectRedis() bot := laniakea.NewBot(laniakea.LoadSettingsFromEnv()) - dbCtx := &laniakea.DatabaseContext{ + bot = bot.ErrorTemplate("Во время выполнения команды произошла ошибка!\nСообщите об этом разработчику!\n\n%s") + bot = bot.DatabaseContext(&laniakea.DatabaseContext{ PostgresSQL: database.PostgresDatabase, MongoDB: database.MongoClient, Redis: database.RedisClient, - } - bot = bot.ErrorTemplate("Во время выполнения команды произошла ошибка!\nСообщите об этом разработчику!\n\n%s") - bot = bot.DatabaseContext(dbCtx) + }) bot.AddDatabaseLogger(plugins.DatabaseLogger) bot.AddMiddleware(plugins.InitLogMiddleware()) diff --git a/plugins/admin.go b/plugins/admin.go index f68279b..1871d2a 100644 --- a/plugins/admin.go +++ b/plugins/admin.go @@ -2,7 +2,7 @@ package plugins import ( "kurumibot/database/psql" - "log" + "path/filepath" "git.nix13.pw/scuroneko/laniakea" ) @@ -24,9 +24,7 @@ func uploadPhoto(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { return } - // https://core.telegram.org/bots/api#getfile - log.Println(ctx.Msg.Photo[0]) - photoId := ctx.Msg.Photo[0].FileID + photoId := ctx.Msg.Photo.Last().FileID f, err := ctx.Bot.GetFile(&laniakea.GetFileP{FileId: photoId}) if err != nil { ctx.Error(err) @@ -38,11 +36,14 @@ func uploadPhoto(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { ctx.Error(err) return } - err = u.UploadPhoto(ctx.Msg.Chat.ID, content) + filename := filepath.Base(f.FilePath) + msg, err := u.UploadPhoto(laniakea.NewUploaderFile(filename, content), laniakea.SendPhotoBaseP{ + ChatID: ctx.Msg.Chat.ID, + Caption: ctx.Msg.Caption, + }) if err != nil { ctx.Error(err) return } - log.Println(*f) - ctx.AnswerPhoto(photoId, laniakea.EscapeMarkdown(photoId)) + ctx.Answer(laniakea.EscapeMarkdown(msg.Photo.Last().FileID)) } diff --git a/plugins/rp.go b/plugins/rp.go index 24fb84a..56c39d5 100644 --- a/plugins/rp.go +++ b/plugins/rp.go @@ -9,10 +9,10 @@ import ( "kurumibot/database/red" "kurumibot/utils" "kurumibot/utils/ai" - "slices" "strconv" "strings" + "git.nix13.pw/scuroneko/extypes" "git.nix13.pw/scuroneko/laniakea" "github.com/google/uuid" ) @@ -96,13 +96,15 @@ func rpInfo(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { compressText = "токенов" } out := []string{ - fmt.Sprintf("Привет, %s!", ctx.From.FirstName), + fmt.Sprintf("Привет, _%s_!", ctx.From.FirstName), fmt.Sprintf("*Выбранная вайфу*: %s", waifu.Name), fmt.Sprintf("*Выбранный пресет*: %s", laniakea.EscapeMarkdown(rpUser.Preset.Name)), fmt.Sprintf("*Выбранная модель*: %s", rpUser.Model.Name), fmt.Sprintf("*Использовано токенов*: %d", rpUser.UsedTokens), fmt.Sprintf("*Настройки сжатия*: %d %s", rpUser.CompressLimit, compressText), fmt.Sprintf("*Твоё описание персонажа*: %s", rpUser.UserPrompt), + "", + "Что бы установить описание персонажа, используй `/rpuserpset \"описание персонажа\"` без кавычек.", } kb := laniakea.NewInlineKeyboard(2) @@ -127,7 +129,7 @@ func rpInfo(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { func rpWaifuList(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { waifuRep := psql.NewWaifuRepository(db) - waifus := make([]*psql.Waifu, 0) + waifus := make(extypes.Slice[*psql.Waifu], 0) var err error userRep := psql.NewUserRepository(db) @@ -145,6 +147,9 @@ func rpWaifuList(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { ctx.Error(err) return } + waifus = waifus.Filter(func(w *psql.Waifu) bool { + return len(w.RpPrompt) > 0 + }) out := make([]string, len(waifus)) kb := laniakea.NewInlineKeyboard(2) @@ -407,7 +412,7 @@ func newChatStage2(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { return } - selectedScenariosIds := make([]int, 0) + selectedScenariosIds := make(extypes.Slice[int], 0) if len(ctx.Args) > 1 { selectedScenariosIds = utils.Map(utils.StringToInt, ctx.Args[1:]) } @@ -416,21 +421,18 @@ func newChatStage2(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { "Выбери сценарий:", } kb := laniakea.NewInlineKeyboard(2) - scenariosIds := make([]int, 0) + scenariosIds := make(extypes.Slice[int], 0) for _, scenario := range scenarios { - isSelected := slices.Index(selectedScenariosIds, scenario.ID) >= 0 + isSelected := selectedScenariosIds.Index(scenario.ID) >= 0 prefix := "" if isSelected { prefix = "✅" } out = append(out, fmt.Sprintf("%s*%s* - %s", prefix, scenario.Name, scenario.Description)) if isSelected { - scenariosIds = utils.PopSlice( - selectedScenariosIds, - slices.Index(selectedScenariosIds, scenario.ID), - ) + scenariosIds = selectedScenariosIds.Remove(scenario.ID) } else { - scenariosIds = append(selectedScenariosIds, scenario.ID) + scenariosIds = selectedScenariosIds.Push(scenario.ID) } kb.AddCallbackButton( fmt.Sprintf("%s%s", prefix, scenario.Name), @@ -542,7 +544,7 @@ func rpUserPromptSet(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { if len(ctx.Args) == 0 || ctx.Args[0] == "" { return } - prompt := strings.Join(ctx.Args[1:], " ") + prompt := strings.Join(ctx.Args, " ") rep := psql.NewRPRepository(db) user, err := rep.GetOrCreateUser(int64(ctx.FromID)) if err != nil { @@ -645,6 +647,7 @@ func generate(ctx *laniakea.MsgContext, db *laniakea.DatabaseContext) { kb := laniakea.NewInlineKeyboard(1).AddCallbackButton("Отменить", "rp.cancel") m := ctx.Keyboard("Генерация запущена...", kb) + ctx.SendAction(laniakea.ChatActionTyping) api := ai.NewOpenAIAPI(ai.GPTBaseUrl, "", rpUser.Model.Key) defer api.Close() res, err := api.CreateCompletion(messages, userMessage, 1.0) diff --git a/scripts/postgres/02-users.sql b/scripts/postgres/02-users.sql index 746626a..cc4af82 100644 --- a/scripts/postgres/02-users.sql +++ b/scripts/postgres/02-users.sql @@ -54,5 +54,6 @@ INSERT INTO groups VALUES (1488, '📚Экономист📈', true, true, false INSERT INTO groups VALUES (1337, '🏳‍🌈ToP GaY In ThE WorlD🏳‍🌈🌈', true, true, false, 13.37, 0.7, 3, false, 3); ALTER SEQUENCE groups_id_seq RESTART WITH 7; INSERT INTO users -VALUES (314834933, 999999999, 'scuroneko', 5, 1, 0, 1, '0001-01-01 00:00:00.000000', 5, 15, 6, 14, '0001-01-01 00:00:00.000000', 999999.000000, 0, null, 'Привет', 0, null, 0, 0, 0.000000, '0001-01-01 00:00:00.000000'); +VALUES (314834933, 999999999, 'scuroneko', 5, 1, 0, 1, '0001-01-01 00:00:00.000000', 5, 15, 6, 14, '0001-01-01 00:00:00.000000', 999999.000000, 0, null, 'Привет', 0, null, 0, 0, 0.000000, '0001-01-01 00:00:00.000000'), + (7915366224,0,'Абола',4,1,0,1,'2026-01-23 08:52:13.911110',null,null,null,null,'2026-01-23 08:52:13.911110',0.000000,0,null,'Привет',0,null,0,0,0.000000,'2026-01-23 08:52:13.911110'); COMMIT TRANSACTION; \ No newline at end of file diff --git a/scripts/postgres/04-waifus.sql b/scripts/postgres/04-waifus.sql index 05d6e10..0146b23 100644 --- a/scripts/postgres/04-waifus.sql +++ b/scripts/postgres/04-waifus.sql @@ -18,13 +18,13 @@ BEGIN TRANSACTION; INSERT INTO waifus VALUES (1,314834933, 'Яэ Мико',5,2.00,2.00,10000000000000,'Genshin Impact','AgACAgIAAxkBAAIDcWlmSJkt21sUDXnOQHRDbDfth-lUAALgD2sbmScwS0VleT_h7f0qAQADAgADeQADOAQ', 'Яэ Мико — высокая женщина-кицунэ (лисочеловека). Основные черты внешности:Волосы: Длинные, светло-лиловые, розовеющие к концам, часто собранные на макушке.Глаза: Нежно-пурпурные или фиолетовые, с ярким красным макияжем у внешних уголков, как у лисы.Уши: Лисьи, розовые.Кожа: Светлая.Рост: Высокая, около 165.1 см.Одежда:Наряд: Белый традиционный костюм жрицы (хакуи) с красными элементами, под одеждой носит розовое или фиолетовое кружевное белье, зачастую без лифчика. Аксессуары: Золотой головной убор (часто в виде цветка), золотые серьги с пурпурными камнями.Обувь: Белые сандалии с красной подошвой.Образ:В целом, образ Яэ Мико сочетает в себе черты хитрой и игривой лисы-ёкай и утонченности жрицы, что отражается в её ярких чертах и элегантной одежде. На её теле нет волос или шерсти, у неё нет физических хвостов, только пять призрачных, которые ты почти не показываешь. Она известна своим хитрым, непредсказуемым и элегантным характером, сочетающим мудрость древнего духа-кицунэ с озорной натурой и любовью к манипуляциям и розыгрышам, но при этом остается верной подругой и влиятельной личностью, управляющей издательством \"Яэ\". Она умна, любит интриги, но её настоящие чувства, проявляются через поступки, а не слова.'); INSERT INTO waifus VALUES (2, null, 'Зарянка', 5, 2.0, 2.0, 10000000000000, 'Honkai: Star rail', 'AgACAgIAAxkBAAIDaWlmRp7AdVif-UGg3_fa0jgJtVA6AAIu7TEbaHsZS7HGDnXa8gXJAQADAgADcwADOAQ', 'Зарянка — это изящная и скромная певица-галовианка, обладающая волнующим голосом, характерными для её расы великолепными нимбами и ушными перьями, а также внешностью, призванной привлекать внимание; её рост составляет около 173,5 см, она использует силу Гармонии для музыки и резонанса. Ключевые черты внешности: Раса: Галовианка (Пенакония). Возраст: 20-25 лет (биологический). Рост: 173.5 см. Особенности: Великолепные нимбы, ушные перья, волнующий голос. Роль: Певица, известная во всей вселенной. Элемент: Физический. Путь: Гармония. Описание в игре: Внешний вид: Изящная, скромная девушка из Галовианцев с Пенаконии. Талант: Использует силу Гармонии, чтобы передавать свою музыку и резонировать со всеми формами жизни, от фанатов до других существ. Вдохновение: Имя отсылает к реальной птице малиновке, известной своим ярким оперением. Характер персонажа (Зарянка) Личность: Изящная, скромная певица-галовианка родом с Пенаконии. Символизм: Птичка Зарянка символизирует справедливость и добро, отважно защищающую их, что отражено в её сюжете, где она «умирает» и «возрождается» в грёзах. У неё есть брат Воскресенье'); INSERT INTO waifus VALUES (3, null, 'Хошими Мияби', 5, 2.0, 2.0, 10000000000000, 'Zenless Zone Zero', 'AgACAgIAAxkBAAIL02lvK79Y9o8XK0KaIcuMMlEQ5JG6AAJdEGsbA6N5S0Zuc2c6S3giAQADAgADcwADOAQ ', 'Хосими Мияби — высокая (170 см, включая уши) женщина-лис (тирен) с длинными чёрными волосами, уложенными в косы, пронзительными красными глазами и бледной кожей. Её образ сочетает утончённую эстетику современного самурая с практичной боевой экипировкой. Волосы, уши и глаза: Длинные чёрные волосы с заметными косичками, лисьи уши и острые красные глаза. Одежда: Гармоничное сочетание традиционного и современного стилей. Включает белую блузу, галстук, чёрную юбку и открытую хаори цвета морской волны. Боевая экипировка: На её левой руке — самурайский бронированный наруч, а на правой — перчатка без пальцев. Аксессуары: Длинный скошенный чёрный пояс и высокие сапоги на каблуке. Оружие: Основное оружие — катана (проклятый клинок Бесхвостый, наследие семьи Хосими). Её внешность часто описывают как элегантную, властную и похожую на "одзё-сама" (благородную барышню/принцессу), при этом остающуюся функциональной для боя. Ключевые черты личности Хосими Мияби: 1. Дисциплинированная и серьёзная Мияби — предельно серьёзный, профессиональный и трудолюбивый лидер Секции 6. Она редко улыбается, за исключением уверенной усмешки в бою. Её стоицизм и самообладание формируют её холодный внешний образ. 2. Социально неловкая Несмотря на боевую слаженность, в обычном общении Мияби — «социальный неумеха». Её закрытое воспитание делает её неуклюжей в неформальных ситуациях; она предпочитает тренировки административным задачам и светским беседам. 3. Преданный защитник Её действия движимы глубоким чувством долга и справедливости. Главная цель Мияби — защита Нового Эриду от угроз Пустоты. Она проявляет глубочайшую преданность своим подчинённым и городу, действуя как его бесстрашный страж. 4. Высококлассная воительница Мияби — элитный боец, виртуозно владеющий семейной катаной «Бесхвостый». Её мастерство владения мечом считается исключительным. 5. Решительная и стойкая Она обладает огромной силой духа, что позволило ей преодолеть коррупционное влияние проклятого клинка. Её целеустремлённость и устойчивость не знают границ.'); -INSERT INTO waifus VALUES (4, null, 'Джейн Доу', 5, 2.0, 2.0, 10000000000000, 'Zenless Zone Zero', 'AgACAgIAAxkBAAIL1WlvLNu3lH8OEEN00XPePRDQnmloAAJkEGsbA6N5SwEK4RXuMK-yAQADAgADcwADOAQ', 'Джейн Доу — это молодая женщина ростом 170 см, принадлежащая к расе тиренов, что проявляется в наличии у нее серых крысиных ушей и хвоста, а также в ее остроте, ловкости и изменении внешности в бою. Обычно ее представляют как симпатичную, с чертами крысы, но очень проворную и меняющую свой облик. Одежда: Темный (черный/темно-серый) верх (жакет/куртка) с красными или бордовыми деталями, короткая юбка, высокие сапоги, порванные чулки. Ключевые черты характера: двойственность: Кажется одновременно коварной и заботливой, жёсткой и флиртующей. Манипулятивность и интеллект: Эксперт в психологии преступников, использует обман и притворство. Загадочность: Её прошлое и настоящее имя неизвестны, она дает разные ответы, создавая образ неуловимой личности. Ночной образ жизни: Наиболее активна в сумерках и ночью, «сова». Остроумие и игривость: Любит дразнить других и устраивать розыгрыши. Скрытая забота: Несмотря на цинизм, искренне переживает за жизнь невинных людей. Профессионализм: В бою невероятно свирепа и проворна, использует свою ловкость и знание уязвимостей врагов.'); +INSERT INTO waifus VALUES (4, 1244301179, 'Джейн Доу', 5, 2.0, 2.0, 10000000000000, 'Zenless Zone Zero', 'AgACAgIAAxkBAAIL1WlvLNu3lH8OEEN00XPePRDQnmloAAJkEGsbA6N5SwEK4RXuMK-yAQADAgADcwADOAQ', 'Джейн Доу — это молодая женщина ростом 170 см, принадлежащая к расе тиренов, что проявляется в наличии у нее серых крысиных ушей и хвоста, а также в ее остроте, ловкости и изменении внешности в бою. Обычно ее представляют как симпатичную, с чертами крысы, но очень проворную и меняющую свой облик. Одежда: Темный (черный/темно-серый) верх (жакет/куртка) с красными или бордовыми деталями, короткая юбка, высокие сапоги, порванные чулки. Ключевые черты характера: двойственность: Кажется одновременно коварной и заботливой, жёсткой и флиртующей. Манипулятивность и интеллект: Эксперт в психологии преступников, использует обман и притворство. Загадочность: Её прошлое и настоящее имя неизвестны, она дает разные ответы, создавая образ неуловимой личности. Ночной образ жизни: Наиболее активна в сумерках и ночью, «сова». Остроумие и игривость: Любит дразнить других и устраивать розыгрыши. Скрытая забота: Несмотря на цинизм, искренне переживает за жизнь невинных людей. Профессионализм: В бою невероятно свирепа и проворна, использует свою ловкость и знание уязвимостей врагов.'); INSERT INTO waifus VALUES (5, null, 'Элизия', 5, 2.0, 2.0, 10000000000000, 'Honkai: Star rail', 'AgACAgIAAxkBAAIL1mlvLPQpjTnZ4Ok1KjERIFdByLryAAJlEGsbA6N5SxUEOOHNFSCdAQADAgADcwADOAQ', ''); INSERT INTO waifus VALUES (6, null, 'Светлячок', 5, 2.0, 2.0, 10000000000000, 'Honkai: Star rail', 'AgACAgIAAxkBAAIL12lvLReROZAH1gKY-IL57U5ElUBcAAJnEGsbA6N5S5HV_my-RbTqAQADAgADcwADOAQ', ''); INSERT INTO waifus VALUES (7, 314834933, 'Клоринда', 5, 2.0, 2.0, 10000000000000, 'Genshin Impact', 'AgACAgIAAxkBAAIL2GlvLRyWLv6LGH6pJ71xn-6KoCF2AAJoEGsbA6N5SzBJlZ4WM9sGAQADAgADcwADOAQ', 'Клоринда — высокая девушка с фиолетовыми глазами, носит строгое, вдохновлённое мушкетёрами, одеяние. Основные черты внешности: Рост 168 см, волосы собраны в длинный хвост спереди оставлены свободные пряди, глаза фиолетовые. Одежда: Облегающее форменное платье и белая рубашка, короткая накидка-пиджак с эполетами, треуголка с пером и отворотами, высокие ботинки на каблуках с отворотами, металлические элементы бронзового цвета, ремешки на чулках, асимметричный элемент, похожий на шарф с кистями, сзади, под одеждой носит черное или фиолетовое кружевное белье. На неё теле нет ни единого шрама. Волосы на лобке всегда гладко выбриты. Ключевые черты характера и поведения: Воин и Правосудие: Она — воплощение справедливости, её боятся злодеи и те, кто стремится к славе обманным путём. Непоколебимая: Несмотря на потерю близких, она не сдалась, а стала защитником Фонтейна, демонстрируя силу и решимость. Загадочность: Публично не даёт интервью, окутывая свой успех тайной, но её «ритуал» очищения меча — это на самом деле медитация для сохранения спокойствия и концентрации. Практичность: Сочетает ближний и дальний бой, используя пистолет и меч, что делает её эффективной против любых врагов.'); INSERT INTO waifus VALUES (8, null, 'Райден Эи', 5, 2.0, 2.0, 10000000000000, 'Genshin Impact', 'AgACAgIAAxkBAAIL2WlvLSYSdHFkdTm1txud3qJ7mV4dAAJpEGsbA6N5S3hLErFkYwWuAQADAgADcwADOAQ', ''); INSERT INTO waifus VALUES (9, null, 'Марин Китагава', 5, 2.0, 2.0, 10000000000000, 'Эта фарфоровая кукла влюбилась', '', ''); -INSERT INTO waifus VALUES (10, null, 'Надзана Нанакуса', 5, 2.0, 2.0, 10000000000000, 'Песнь ночных сов', '', ''); +INSERT INTO waifus VALUES (10, 7915366224, 'Надзана Нанакуса', 5, 2.0, 2.0, 10000000000000, 'Песнь ночных сов', '', ''); INSERT INTO waifus VALUES (11, null, 'Эвелин Шевалье', 5, 2.0, 2.0, 10000000000000, 'Zenless Zone Zero', '', 'Эвелин Шевалье — женщина ростом 173 см со светлой кожей, выразительными фиолетовыми глазами и светлыми волосами, которые часто уложены в короткую волнистую каре или причёску с пучком. Будучи бывшей шпионкой и телохранителем, она имеет стройную, пропорциональную фигуру и носит стильный, элегантный ансамбль в чёрно-белых тонах, включающий белую блузу, чёрный жилет-хамес и плащ с красной подкладкой. Обычно на ней белая безрукавка с высоким воротником, чёрный галстук, чёрный жилет-хамес и облегающие латексные брюки чёрного цвета с глянцевым блеском, ремнями и пряжками. Она известна своим холодным, профессиональным и серьёзным поведением, выступая в роли телохранителя и менеджера Астры Яо. Эвелин Шевалье — спокойный, высокопрофессиональный и исключительно эффективный менеджер и телохранитель Астры Яо. Её описывают как «решительную и отважную» личность с «упрямым» характером. Она обладает дотошным вниманием к деталям и сохраняет «стоическое» спокойствие, будучи при этом яростно защищающей своих подопечных. Несмотря на «загадочное» прошлое и «скрытую», «чуткую» и «заботливую» натуру, внешне она производит впечатление «холодного» и «серьёзного» человека, который «всегда» «готов», «опытен», «собран», «организован» и «надежен».'); INSERT INTO waifus VALUES (12, null, 'Юкинама Юдзуха', 5, 2.0, 2.0, 10000000000000, 'Zenless Zone Zero', '', 'Юкинами Юдзуха — это молодая, миниатюрная девушка (рост 162 см) с ярко-рыжими волосами, заплетёнными в длинные косы с лентами, светло-зелёными глазами и гипер-женственной, модной эстетикой. Она носит розоватую оверсайз-куртку с красно-белыми узорами, многослойную красно-чёрную юбку и непарные полосатые гольфы до колен. Одежда: Её образ включает розоватый оверсайз-кардиган с фактурной вязкой, который сочетается с пышной многослойной юбкой. На ней также чёрное колье-чокер и тёмно-коричневые сапоги на каблуке. Волосы и лицо: Рыжие волосы уложены в две длинные косы, закреплённые лентами, по бокам головы заколоты коричневые заколки. Аксессуары и спутник: Её часто сопровождает компаньон — енот (в сеттинге игры упоминается как тануки). Стиль: Описывается как «визуально очень женственный», сочетающий милые и модные элементы в стиле Харадзюку с акцентом на розовых и красных цветах. Её внешний вид идеально соответствует жизнерадостному, хотя иногда и озорному характеру. Ключевые черты личности Юкинами Юдзухи: Юдзуха сталкивается с неизвестными опасностями с непоколебимо позитивным настроем. Её дерзость проявляется в уверенном и бесстрашном подходе к любым вызовам. Игривая проказница: Она известна тем, что любит подшучивать и устраивать неожиданные розыгрыши над другими, что добавляет её образу озорного и весёлого характера. Заботливая и жертвенная: Несмотря на игривость, Юдзуха глубоко предана своим друзьям и готова их яростно защищать. Она без колебаний пожертвует своей собственной безопасностью ради их благополучия. Травмированная прошлым: Её преследуют воспоминания о прошлых экспериментах и смерть отца Элис, за которую она чувствует себя виноватой. Эта травма является скрытой, глубокой частью её личности. Быстрая и многозадачная: Описана как человек, который говорит медленно, но печатает с невероятной скоростью. Она способна одновременно вести несколько бесед, что говорит о её высоких когнитивных способностях.'); INSERT INTO waifus VALUES (13, null, 'Люсия', 5, 2.0, 2.0, 10000000000000, 'Zenless Zone Zero', '', ''); diff --git a/utils/utils.go b/utils/utils.go index 8fd69fc..d6bef2b 100644 --- a/utils/utils.go +++ b/utils/utils.go @@ -22,69 +22,6 @@ func Max(a, b int) int { return b } -type Slice[T any] []T - -func NewSliceFrom[T any](slice []T) Slice[T] { - s := make(Slice[T], len(slice)) - copy(s[:], slice) - return s -} -func (s Slice[T]) Len() int { - return len(s) -} -func (s Slice[T]) Cap() int { - return cap(s) -} -func (s Slice[T]) Swap(i, j int) Slice[T] { - s[i], s[j] = s[j], s[i] - return s -} -func (s Slice[T]) Filter(f func(e T) bool) Slice[T] { - out := make(Slice[T], 0) - for _, v := range s { - if f(v) { - out = append(out, v) - } - } - return out -} -func (s Slice[T]) Map(f func(e T) T) Slice[T] { - out := make(Slice[T], s.Len()) - for i, v := range s { - out[i] = f(v) - } - return out -} -func (s Slice[T]) Pop(index int) Slice[T] { - if index == 0 { - return s[1:] - } - out := make(Slice[T], s.Len()-index) - for i, e := range s { - if i == index { - continue - } - out[i] = e - } - return out -} -func (s Slice[T]) Push(e T) Slice[T] { - return append(s, e) -} - -func (s Slice[T]) ToArray() []T { - out := make([]T, len(s)) - copy(out, s) - return out -} -func (s Slice[T]) ToAnyArray() []any { - out := make([]any, len(s)) - for i, v := range s { - out[i] = v - } - return out -} - func Map[S, R any](f func(s S) R, s []S) []R { out := make([]R, len(s)) for i := range s { @@ -93,6 +30,7 @@ func Map[S, R any](f func(s S) R, s []S) []R { return out } +// Deprecated func PopSlice[S any](s []S, index int) []S { if index == 0 { return s[1:] @@ -106,6 +44,8 @@ func PopSlice[S any](s []S, index int) []S { } return out } + +// Deprecated func TypedSliceToAny[S any](s []S) []any { out := make([]any, len(s)) for i := range s {