diff --git a/assets/font.ttf b/assets/font.ttf new file mode 100644 index 0000000..114e6c1 Binary files /dev/null and b/assets/font.ttf differ diff --git a/assets/godot.png b/assets/godot.png new file mode 100644 index 0000000..2cdf25a Binary files /dev/null and b/assets/godot.png differ diff --git a/assets/unity.png b/assets/unity.png new file mode 100644 index 0000000..96690cc Binary files /dev/null and b/assets/unity.png differ diff --git a/assets/unreal.png b/assets/unreal.png new file mode 100644 index 0000000..7e9a006 Binary files /dev/null and b/assets/unreal.png differ diff --git a/captchagen/captchagen.go b/captchagen/captchagen.go new file mode 100644 index 0000000..736b7f6 --- /dev/null +++ b/captchagen/captchagen.go @@ -0,0 +1,97 @@ +package captchagen + +import ( + "fmt" + "image" + "image/color" + "io/ioutil" + "log" + "math/rand" + "strings" + "time" + + "github.com/fogleman/gg" +) + +type Logo struct { + Image image.Image + IsCorrect bool +} + +type Captcha struct { + Image image.Image + CorrectAnswer int +} + +var Logos []Logo = []Logo{} + +func initImage() *gg.Context { + dc := gg.NewContext(600, 400) + if err := dc.LoadFontFace("./assets/font.ttf", 24); err != nil { + panic(err) + } + grad := gg.NewLinearGradient(0, 0, 600, 400) + grad.AddColorStop(0, color.RGBA{71, 100, 106, 255}) + grad.AddColorStop(1, color.RGBA{44, 43, 51, 255}) + + dc.SetFillStyle(grad) + dc.DrawRectangle(0, 0, 600, 400) + dc.Fill() + return dc +} + +func GenCaptcha() Captcha { + dc := initImage() + rand.Seed(time.Now().UnixNano()) + rand.Shuffle(len(Logos), func(i, j int) { Logos[i], Logos[j] = Logos[j], Logos[i] }) + correct_answer := 0 + count := len(Logos) + for i, logo := range Logos { + x := i*600/count + 50 + y := rand.Intn(400 - logo.Image.Bounds().Dy()) + dc.DrawImage(logo.Image, x, y) + if logo.IsCorrect { + correct_answer = i + 1 + } + var tx float64 = float64(x) + 50.0 + var ty float64 = float64(y) + 120.0 + text := fmt.Sprintf("%d", i+1) + dc.SetRGB(1, 1, 1) + dc.DrawStringAnchored(text, tx, ty, 0.5, 0.5) + } + img := dc.Image() + captcha := Captcha{ + Image: img, + CorrectAnswer: correct_answer, + } + + return captcha +} + +func InitImages() error { + images := []Logo{} + files, err := ioutil.ReadDir("./assets") + if err != nil { + return err + } + for _, file := range files { + + name := file.Name() + if !strings.HasSuffix(name, ".png") { + continue + } + log.Printf("%s", name) + path := fmt.Sprintf("./assets/%s", name) + im, err := gg.LoadPNG(path) + if err != nil { + log.Print(err) + return err + } + is_correct := strings.HasPrefix(name, "godot") + logo := Logo{Image: im, IsCorrect: is_correct} + images = append(images, logo) + } + Logos = images + log.Printf("%v", Logos) + return nil +} diff --git a/db/structs.go b/db/structs.go index 794101c..fe7c150 100644 --- a/db/structs.go +++ b/db/structs.go @@ -6,16 +6,12 @@ type Chat struct { } type User struct { - Id int64 - ChatId int64 `bson:"chat_id"` - Username string `bson:"username"` - FirstName string `bson:"first_name"` - LastName string `bson:"last_name"` - CorrectAnswer int8 `bson:"correct_answer"` - IsBanned bool `bson:"is_banned"` -} - -type Captcha struct { - MessageId int `bson:"message_id"` - CorrectAnswer int8 `bson:"correct_answer"` + Id int64 + ChatId int64 `bson:"chat_id"` + Username string `bson:"username"` + FirstName string `bson:"first_name"` + LastName string `bson:"last_name"` + CorrectAnswer int8 `bson:"correct_answer"` + CaptchaMessage int `bson:"captcha_message"` + IsBanned bool `bson:"is_banned"` } diff --git a/go.mod b/go.mod index 69e104c..fe6efa9 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,9 @@ module kickerbot go 1.17 require ( + github.com/fogleman/gg v1.3.0 // indirect github.com/go-stack/stack v1.8.0 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect github.com/golang/snappy v0.0.1 // indirect github.com/joho/godotenv v1.4.0 // indirect github.com/klauspost/compress v1.13.6 // indirect @@ -14,7 +16,8 @@ require ( github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect go.mongodb.org/mongo-driver v1.8.0 // indirect golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f // indirect + golang.org/x/image v0.0.0-20211028202545-6944b10bf410 // indirect golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect - golang.org/x/text v0.3.5 // indirect + golang.org/x/text v0.3.6 // indirect gopkg.in/tucnak/telebot.v3 v3.0.0-20211126232936-7f936709f3ee // indirect ) diff --git a/go.sum b/go.sum index e4830ce..b26337d 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8= +github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= @@ -9,6 +11,8 @@ github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/goccy/go-yaml v1.9.1/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -50,6 +54,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f h1:aZp0e2vLN4MToVqnjNEYEtrEA8RH8U8FN1CU7JgqsPU= golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410 h1:hTftEOvwiOq2+O8k2D5/Q7COC7k5Qcrgc2TFURJYnvQ= +golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -66,6 +72,8 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/kicker/handlers.go b/kicker/handlers.go index 55d2c06..6590b52 100644 --- a/kicker/handlers.go +++ b/kicker/handlers.go @@ -1,8 +1,11 @@ package kicker import ( + "bytes" "context" "fmt" + "image/png" + "kickerbot/captchagen" "kickerbot/db" "log" "time" @@ -28,19 +31,13 @@ func userJoined(c tb.Context) error { log.Print(user) str := fmt.Sprintf("%v", user) c.Bot().Send(&tb.User{ID: 60441930}, str) + msg := fmt.Sprintf("Приветствую, %v!\nПеред тем, как дать тебе что-то здесь писать, я задам тебе один вопрос:\nКакой из этих движков самый лучший? Подумай хорошенько, и дай ответ цифрой.", user.FirstName) + c.Reply(msg) db.Log("new user", str) return nil } var HandlersV1 = []Handler{ - // { - // Endpoint: tb.OnText, - // Handler: func(c tb.Context) error { - // m := c.Message() - // c.Bot().Send(m.Sender, m.Text) - // return nil - // }, - // }, { Endpoint: tb.OnText, Handler: func(c tb.Context) error { @@ -48,6 +45,22 @@ var HandlersV1 = []Handler{ return nil }, }, + { + Endpoint: "/gen", + Handler: func(c tb.Context) error { + captcha := captchagen.GenCaptcha() + buff := new(bytes.Buffer) + err := png.Encode(buff, captcha.Image) + if err != nil { + fmt.Println("failed to create buffer", err) + } + reader := bytes.NewReader(buff.Bytes()) + // log.Print(reader) + caption := fmt.Sprintf("Правильный ответ: %d", captcha.CorrectAnswer) + c.Reply(&tb.Photo{File: tb.FromReader(reader), Caption: caption}) + return nil + }, + }, { Endpoint: tb.OnAddedToGroup, Handler: func(c tb.Context) error { diff --git a/kickerbot b/kickerbot new file mode 100755 index 0000000..f258368 Binary files /dev/null and b/kickerbot differ diff --git a/main.go b/main.go index 5a84f43..8ef2b1f 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "kickerbot/captchagen" "kickerbot/db" "kickerbot/kicker" "log" @@ -11,6 +12,7 @@ import ( func main() { err := godotenv.Load() + captchagen.InitImages() if err != nil { log.Print("Error loading .env file") } diff --git a/out.png b/out.png new file mode 100644 index 0000000..3ca1cf1 Binary files /dev/null and b/out.png differ