Massive refactoring for future development
This commit is contained in:
parent
f5d801b768
commit
dfe0d08ecc
@ -6,15 +6,17 @@ package main
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/broadcaster"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/chatter"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/forwarder"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/getters"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/migrations"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/parsers"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/pinner"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/pokedexer"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/router"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/squader"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/statistics"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/talkers"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/users"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/welcomer"
|
||||
"time"
|
||||
)
|
||||
@ -30,13 +32,15 @@ func main() {
|
||||
migrations.New(c)
|
||||
c.RunDatabaseMigrations()
|
||||
forwarder.New(c)
|
||||
parsers.New(c)
|
||||
pokedexer.New(c)
|
||||
pinner.New(c)
|
||||
talkers.New(c)
|
||||
getters.New(c)
|
||||
broadcaster.New(c)
|
||||
welcomer.New(c)
|
||||
chatter.New(c)
|
||||
squader.New(c)
|
||||
users.New(c)
|
||||
statistics.New(c)
|
||||
|
||||
c.Log.Info("=======================")
|
||||
c.Log.Info("= i2_bot initialized. =")
|
||||
|
@ -6,17 +6,19 @@ package appcontext
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"github.com/jmoiron/sqlx"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/broadcaster/broadcasterinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/chatter/chatterinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/config"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/connections"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/forwarder/forwarderinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/getters/gettersinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/migrations/migrationsinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/parsers/parsersinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/pinner/pinnerinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/pokedexer/pokedexerinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/router/routerinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/squader/squaderinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/statistics/statisticsinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/talkers/talkersinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/users/usersinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/welcomer/welcomerinterface"
|
||||
"lab.pztrn.name/golibs/mogrus"
|
||||
"os"
|
||||
@ -30,14 +32,16 @@ type Context struct {
|
||||
Forwarder forwarderinterface.ForwarderInterface
|
||||
Migrations migrationsinterface.MigrationsInterface
|
||||
Router routerinterface.RouterInterface
|
||||
Parsers parsersinterface.ParsersInterface
|
||||
Pokedexer pokedexerinterface.PokedexerInterface
|
||||
Db *sqlx.DB
|
||||
Talkers talkersinterface.TalkersInterface
|
||||
Getters gettersinterface.GettersInterface
|
||||
Broadcaster broadcasterinterface.BroadcasterInterface
|
||||
Welcomer welcomerinterface.WelcomerInterface
|
||||
Pinner pinnerinterface.PinnerInterface
|
||||
Chatter chatterinterface.ChatterInterface
|
||||
Squader squaderinterface.SquaderInterface
|
||||
Users usersinterface.UsersInterface
|
||||
Statistics statisticsinterface.StatisticsInterface
|
||||
}
|
||||
|
||||
// Init is a initialization function for context
|
||||
@ -75,9 +79,9 @@ func (c *Context) RegisterMigrationsInterface(mi migrationsinterface.MigrationsI
|
||||
c.Migrations.Init()
|
||||
}
|
||||
|
||||
// RegisterParsersInterface registering parsers interface in application
|
||||
func (c *Context) RegisterParsersInterface(pi parsersinterface.ParsersInterface) {
|
||||
c.Parsers = pi
|
||||
// RegisterPokedexerInterface registering parsers interface in application
|
||||
func (c *Context) RegisterPokedexerInterface(pi pokedexerinterface.PokedexerInterface) {
|
||||
c.Pokedexer = pi
|
||||
}
|
||||
|
||||
// RegisterTalkersInterface registering talkers interface in application
|
||||
@ -86,10 +90,10 @@ func (c *Context) RegisterTalkersInterface(ti talkersinterface.TalkersInterface)
|
||||
c.Talkers.Init()
|
||||
}
|
||||
|
||||
// RegisterGettersInterface registering getters interface in application
|
||||
func (c *Context) RegisterGettersInterface(gi gettersinterface.GettersInterface) {
|
||||
c.Getters = gi
|
||||
c.Getters.Init()
|
||||
// RegisterBroadcasterInterface registering broadcaster interface in application
|
||||
func (c *Context) RegisterBroadcasterInterface(bi broadcasterinterface.BroadcasterInterface) {
|
||||
c.Broadcaster = bi
|
||||
c.Broadcaster.Init()
|
||||
}
|
||||
|
||||
// RegisterWelcomerInterface registering welcomer interface in application
|
||||
@ -122,6 +126,18 @@ func (c *Context) RegisterSquaderInterface(si squaderinterface.SquaderInterface)
|
||||
c.Squader.Init()
|
||||
}
|
||||
|
||||
// RegisterUsersInterface registers users interface in application
|
||||
func (c *Context) RegisterUsersInterface(ui usersinterface.UsersInterface) {
|
||||
c.Users = ui
|
||||
c.Users.Init()
|
||||
}
|
||||
|
||||
// RegisterStatisticsInterface registers statistics interface in application
|
||||
func (c *Context) RegisterStatisticsInterface(si statisticsinterface.StatisticsInterface) {
|
||||
c.Statistics = si
|
||||
c.Statistics.Init()
|
||||
}
|
||||
|
||||
// RunDatabaseMigrations applies migrations on bot's startup
|
||||
func (c *Context) RunDatabaseMigrations() {
|
||||
c.Migrations.SetDialect("mysql")
|
||||
|
@ -1,15 +1,14 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package getters
|
||||
package broadcaster
|
||||
|
||||
import (
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CreateBroadcastMessage creates broadcast message item in database
|
||||
func (g *Getters) CreateBroadcastMessage(playerRaw *dbmapping.Player, messageBody string, broadcastType string) (dbmapping.Broadcast, bool) {
|
||||
func (b *Broadcaster) createBroadcastMessage(playerRaw *dbmapping.Player, messageBody string, broadcastType string) (dbmapping.Broadcast, bool) {
|
||||
messageRaw := dbmapping.Broadcast{}
|
||||
messageRaw.Text = messageBody
|
||||
messageRaw.Status = "new"
|
||||
@ -30,8 +29,7 @@ func (g *Getters) CreateBroadcastMessage(playerRaw *dbmapping.Player, messageBod
|
||||
return messageRaw, true
|
||||
}
|
||||
|
||||
// GetBroadcastMessageByID returns dbmapping.Broadcast instance with given ID.
|
||||
func (g *Getters) GetBroadcastMessageByID(messageID int) (dbmapping.Broadcast, bool) {
|
||||
func (b *Broadcaster) getBroadcastMessageByID(messageID int) (dbmapping.Broadcast, bool) {
|
||||
messageRaw := dbmapping.Broadcast{}
|
||||
err := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE id=?"), messageID)
|
||||
if err != nil {
|
||||
@ -42,8 +40,7 @@ func (g *Getters) GetBroadcastMessageByID(messageID int) (dbmapping.Broadcast, b
|
||||
return messageRaw, true
|
||||
}
|
||||
|
||||
// UpdateBroadcastMessageStatus updates broadcast message status
|
||||
func (g *Getters) UpdateBroadcastMessageStatus(messageID int, messageStatus string) (dbmapping.Broadcast, bool) {
|
||||
func (b *Broadcaster) updateBroadcastMessageStatus(messageID int, messageStatus string) (dbmapping.Broadcast, bool) {
|
||||
messageRaw := dbmapping.Broadcast{}
|
||||
err := c.Db.Get(&messageRaw, c.Db.Rebind("SELECT * FROM broadcasts WHERE id=?"), messageID)
|
||||
if err != nil {
|
17
lib/broadcaster/broadcasterinterface/broadcasterinterface.go
Normal file
17
lib/broadcaster/broadcasterinterface/broadcasterinterface.go
Normal file
@ -0,0 +1,17 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package broadcasterinterface
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
)
|
||||
|
||||
// BroadcasterInterface implements Broadcaster for importing via appcontex
|
||||
type BroadcasterInterface interface {
|
||||
Init()
|
||||
|
||||
AdminBroadcastMessageCompose(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
AdminBroadcastMessageSend(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
}
|
28
lib/broadcaster/exported.go
Normal file
28
lib/broadcaster/exported.go
Normal file
@ -0,0 +1,28 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package broadcaster
|
||||
|
||||
import (
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/broadcaster/broadcasterinterface"
|
||||
)
|
||||
|
||||
var (
|
||||
c *appcontext.Context
|
||||
)
|
||||
|
||||
// Broadcaster is a function-handling struct for broadcaster
|
||||
type Broadcaster struct{}
|
||||
|
||||
// New is a appcontext initialization function
|
||||
func New(ac *appcontext.Context) {
|
||||
c = ac
|
||||
b := &Broadcaster{}
|
||||
c.RegisterBroadcasterInterface(broadcasterinterface.BroadcasterInterface(b))
|
||||
}
|
||||
|
||||
// Init is an initialization function for talkers
|
||||
func (b *Broadcaster) Init() {
|
||||
c.Log.Info("Initializing Broadcaster...")
|
||||
}
|
47
lib/broadcaster/responders.go
Normal file
47
lib/broadcaster/responders.go
Normal file
@ -0,0 +1,47 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package broadcaster
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// AdminBroadcastMessageCompose saves message for future broadcast
|
||||
func (b *Broadcaster) AdminBroadcastMessageCompose(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
broadcastingMessageBody := strings.Replace(update.Message.Text, "/send_all ", "", 1)
|
||||
|
||||
messageRaw, ok := b.createBroadcastMessage(playerRaw, broadcastingMessageBody, "all")
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
message := "Сообщение сохранено в базу.\n"
|
||||
message += "Выглядеть оно будет так:"
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
broadcastingMessage := "*Привет, %username%!*\n\n"
|
||||
broadcastingMessage += "*Важное сообщение от администратора " + update.Message.From.FirstName + " " + update.Message.From.LastName + "* (@" + update.Message.From.UserName + ")\n\n"
|
||||
broadcastingMessage += messageRaw.Text
|
||||
|
||||
msg = tgbotapi.NewMessage(update.Message.Chat.ID, broadcastingMessage)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
message = "Чтобы отправить сообщение всем, отправь команду /send\\_confirm " + strconv.Itoa(messageRaw.ID)
|
||||
|
||||
msg = tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
return "ok"
|
||||
}
|
59
lib/broadcaster/sender.go
Normal file
59
lib/broadcaster/sender.go
Normal file
@ -0,0 +1,59 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package broadcaster
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// AdminBroadcastMessageSend sends saved message to all private chats
|
||||
func (b *Broadcaster) AdminBroadcastMessageSend(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
messageNum := strings.Replace(update.Message.Text, "/send_confirm ", "", 1)
|
||||
messageNumInt, _ := strconv.Atoi(messageNum)
|
||||
messageRaw, ok := b.getBroadcastMessageByID(messageNumInt)
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
if messageRaw.AuthorID != playerRaw.ID {
|
||||
return "fail"
|
||||
}
|
||||
if messageRaw.Status != "new" {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
broadcastingMessageBody := messageRaw.Text
|
||||
|
||||
privateChats, ok := c.Chatter.GetAllPrivateChats()
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
for i := range privateChats {
|
||||
chat := privateChats[i]
|
||||
broadcastingMessage := "*Привет, " + chat.Name + "!*\n\n"
|
||||
broadcastingMessage += "*Важное сообщение от администратора " + update.Message.From.FirstName + " " + update.Message.From.LastName + "* (@" + update.Message.From.UserName + ")\n\n"
|
||||
broadcastingMessage += broadcastingMessageBody
|
||||
|
||||
msg := tgbotapi.NewMessage(int64(chat.TelegramID), broadcastingMessage)
|
||||
msg.ParseMode = "Markdown"
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
messageRaw, ok = b.updateBroadcastMessageStatus(messageRaw.ID, "sent")
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
message := "Сообщение всем отправлено. Надеюсь, пользователи бота за него тебя не убьют.\n"
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
return "ok"
|
||||
}
|
@ -10,7 +10,7 @@ import (
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const VERSION = "0.35"
|
||||
const VERSION = "0.51"
|
||||
|
||||
// DatabaseConnection handles database connection settings in config.yaml
|
||||
type DatabaseConnection struct {
|
||||
|
@ -24,5 +24,5 @@ func New(ac *appcontext.Context) {
|
||||
|
||||
// Init is a initialization function for package
|
||||
func (f *Forwarder) Init() {
|
||||
c.Log.Info("Initializing forwarder...")
|
||||
c.Log.Info("Initializing Forwarder...")
|
||||
}
|
||||
|
@ -20,33 +20,14 @@ func (f *Forwarder) ProcessForward(update *tgbotapi.Update, playerRaw *dbmapping
|
||||
case pokememeMsg.MatchString(text):
|
||||
c.Log.Debug("Pokememe posted!")
|
||||
if playerRaw.LeagueID == 1 {
|
||||
status := c.Parsers.ParsePokememe(text, playerRaw)
|
||||
switch status {
|
||||
case "ok":
|
||||
c.Talkers.PokememeAddSuccessMessage(update)
|
||||
return "ok"
|
||||
case "dup":
|
||||
c.Talkers.PokememeAddDuplicateMessage(update)
|
||||
return "ok"
|
||||
case "fail":
|
||||
c.Talkers.PokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
return c.Pokedexer.ParsePokememe(update, playerRaw)
|
||||
} else {
|
||||
c.Talkers.AnyMessageUnauthorized(update)
|
||||
return "fail"
|
||||
}
|
||||
case profileMsg.MatchString(text):
|
||||
c.Log.Debug("Profile posted!")
|
||||
status := c.Parsers.ParseProfile(update, playerRaw)
|
||||
switch status {
|
||||
case "ok":
|
||||
c.Talkers.ProfileAddSuccessMessage(update)
|
||||
return "ok"
|
||||
case "fail":
|
||||
c.Talkers.ProfileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
return c.Users.ParseProfile(update, playerRaw)
|
||||
default:
|
||||
c.Log.Debug(text)
|
||||
}
|
||||
|
@ -1,28 +0,0 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package getters
|
||||
|
||||
import (
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/getters/gettersinterface"
|
||||
)
|
||||
|
||||
var (
|
||||
c *appcontext.Context
|
||||
)
|
||||
|
||||
// Getters is a function-handling struct for package getters.
|
||||
type Getters struct{}
|
||||
|
||||
// New is an initialization function for appcontext
|
||||
func New(ac *appcontext.Context) {
|
||||
c = ac
|
||||
g := &Getters{}
|
||||
c.RegisterGettersInterface(gettersinterface.GettersInterface(g))
|
||||
}
|
||||
|
||||
// Init is a initialization function for package
|
||||
func (g *Getters) Init() {
|
||||
c.Log.Info("Initializing getters...")
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package gettersinterface
|
||||
|
||||
import (
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
)
|
||||
|
||||
// GettersInterface implements Getters for importing via appcontext.
|
||||
type GettersInterface interface {
|
||||
Init()
|
||||
CreateBroadcastMessage(playerRaw *dbmapping.Player, messageBody string, broadcastType string) (dbmapping.Broadcast, bool)
|
||||
GetBroadcastMessageByID(messageID int) (dbmapping.Broadcast, bool)
|
||||
UpdateBroadcastMessageStatus(messageID int, messageStatus string) (dbmapping.Broadcast, bool)
|
||||
GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool)
|
||||
GetPlayerByID(playerID int) (dbmapping.Player, bool)
|
||||
PlayerBetterThan(playerRaw *dbmapping.Player, powerLevel string) bool
|
||||
GetProfile(playerID int) (dbmapping.Profile, bool)
|
||||
GetPokememes() ([]dbmapping.PokememeFull, bool)
|
||||
GetBestPokememes(playerID int) ([]dbmapping.PokememeFull, bool)
|
||||
GetPokememeByID(pokememeID string) (dbmapping.PokememeFull, bool)
|
||||
PossibilityRequiredPokeballs(location int, grade int, lvl int) (float64, int)
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package getters
|
||||
|
||||
import (
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
)
|
||||
|
||||
// GetProfile returns last saved profile of player
|
||||
func (g *Getters) GetProfile(playerID int) (dbmapping.Profile, bool) {
|
||||
profileRaw := dbmapping.Profile{}
|
||||
err := c.Db.Get(&profileRaw, c.Db.Rebind("SELECT * FROM profiles WHERE player_id=? ORDER BY created_at DESC LIMIT 1"), playerID)
|
||||
if err != nil {
|
||||
c.Log.Error(err)
|
||||
return profileRaw, false
|
||||
}
|
||||
|
||||
return profileRaw, true
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package parsersinterface
|
||||
|
||||
import (
|
||||
// 3rd party
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
// local
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
)
|
||||
|
||||
// ParsersInterface implements Parsers for importing via appcontext.
|
||||
type ParsersInterface interface {
|
||||
ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
ReturnPoints(points int) string
|
||||
}
|
@ -1,24 +1,24 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package parsers
|
||||
package pokedexer
|
||||
|
||||
import (
|
||||
// local
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/parsers/parsersinterface"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/pokedexer/pokedexerinterface"
|
||||
)
|
||||
|
||||
var (
|
||||
c *appcontext.Context
|
||||
)
|
||||
|
||||
// Parsers is a function-handling struct for package parsers
|
||||
type Parsers struct{}
|
||||
// Pokedexer is a function-handling struct for package pokedexer
|
||||
type Pokedexer struct{}
|
||||
|
||||
// New is an initialization function for appcontext
|
||||
func New(ac *appcontext.Context) {
|
||||
c = ac
|
||||
p := &Parsers{}
|
||||
c.RegisterParsersInterface(parsersinterface.ParsersInterface(p))
|
||||
p := &Pokedexer{}
|
||||
c.RegisterPokedexerInterface(pokedexerinterface.PokedexerInterface(p))
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package getters
|
||||
package pokedexer
|
||||
|
||||
import (
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
@ -10,7 +10,7 @@ import (
|
||||
|
||||
// Internal functions
|
||||
|
||||
func (g *Getters) formFullPokememes(pokememes []dbmapping.Pokememe) ([]dbmapping.PokememeFull, bool) {
|
||||
func (p *Pokedexer) formFullPokememes(pokememes []dbmapping.Pokememe) ([]dbmapping.PokememeFull, bool) {
|
||||
pokememesArray := []dbmapping.PokememeFull{}
|
||||
elements := []dbmapping.Element{}
|
||||
err := c.Db.Select(&elements, "SELECT * FROM elements")
|
||||
@ -75,7 +75,7 @@ func (g *Getters) formFullPokememes(pokememes []dbmapping.Pokememe) ([]dbmapping
|
||||
// External functions
|
||||
|
||||
// GetPokememes returns all existing pokememes, known by bot
|
||||
func (g *Getters) GetPokememes() ([]dbmapping.PokememeFull, bool) {
|
||||
func (p *Pokedexer) GetPokememes() ([]dbmapping.PokememeFull, bool) {
|
||||
pokememesArray := []dbmapping.PokememeFull{}
|
||||
pokememes := []dbmapping.Pokememe{}
|
||||
err := c.Db.Select(&pokememes, "SELECT * FROM pokememes ORDER BY grade asc, name asc")
|
||||
@ -84,18 +84,17 @@ func (g *Getters) GetPokememes() ([]dbmapping.PokememeFull, bool) {
|
||||
return pokememesArray, false
|
||||
}
|
||||
|
||||
pokememesArray, ok := g.formFullPokememes(pokememes)
|
||||
pokememesArray, ok := p.formFullPokememes(pokememes)
|
||||
return pokememesArray, ok
|
||||
}
|
||||
|
||||
// GetBestPokememes returns all pokememes, which will be good for player to catch
|
||||
func (g *Getters) GetBestPokememes(playerID int) ([]dbmapping.PokememeFull, bool) {
|
||||
func (p *Pokedexer) getBestPokememes(playerID int) ([]dbmapping.PokememeFull, bool) {
|
||||
pokememesArray := []dbmapping.PokememeFull{}
|
||||
playerRaw, ok := g.GetPlayerByID(playerID)
|
||||
playerRaw, ok := c.Users.GetPlayerByID(playerID)
|
||||
if !ok {
|
||||
return pokememesArray, ok
|
||||
}
|
||||
profileRaw, ok := g.GetProfile(playerID)
|
||||
profileRaw, ok := c.Users.GetProfile(playerID)
|
||||
if !ok {
|
||||
return pokememesArray, ok
|
||||
}
|
||||
@ -112,12 +111,12 @@ func (g *Getters) GetBestPokememes(playerID int) ([]dbmapping.PokememeFull, bool
|
||||
return pokememesArray, false
|
||||
}
|
||||
|
||||
pokememesArray, ok = g.formFullPokememes(pokememes)
|
||||
pokememesArray, ok = p.formFullPokememes(pokememes)
|
||||
return pokememesArray, ok
|
||||
}
|
||||
|
||||
// GetPokememeByUD returns single pokememe based on internal ID in database
|
||||
func (g *Getters) GetPokememeByID(pokememeID string) (dbmapping.PokememeFull, bool) {
|
||||
// GetPokememeByID returns single pokememe based on internal ID in database
|
||||
func (p *Pokedexer) GetPokememeByID(pokememeID string) (dbmapping.PokememeFull, bool) {
|
||||
fullPokememe := dbmapping.PokememeFull{}
|
||||
pokememe := dbmapping.Pokememe{}
|
||||
err := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE id=?"), pokememeID)
|
@ -1,9 +1,10 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package parsers
|
||||
package pokedexer
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
"regexp"
|
||||
"strconv"
|
||||
@ -11,28 +12,9 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
// Internal functions
|
||||
|
||||
func (p *Parsers) getPoints(pointsStr string) int {
|
||||
value := 0
|
||||
if strings.HasSuffix(pointsStr, "K") {
|
||||
valueNumber := strings.Replace(pointsStr, "K", "", 1)
|
||||
valueFloat, _ := strconv.ParseFloat(valueNumber, 64)
|
||||
value = int(valueFloat * 1000)
|
||||
} else if strings.HasSuffix(pointsStr, "M") {
|
||||
valueNumber := strings.Replace(pointsStr, "M", "", 1)
|
||||
valueFloat, _ := strconv.ParseFloat(valueNumber, 64)
|
||||
value = int(valueFloat * 1000000)
|
||||
} else {
|
||||
value, _ = strconv.Atoi(pointsStr)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// External functions
|
||||
|
||||
// ParsePokememe parses pokememe, forwarded from PokememeBroBot, to database
|
||||
func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string {
|
||||
func (p *Pokedexer) ParsePokememe(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
text := update.Message.Text
|
||||
var defendablePokememe = false
|
||||
pokememeStringsArray := strings.Split(text, "\n")
|
||||
pokememeRunesArray := make([][]rune, 0)
|
||||
@ -58,6 +40,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
err := c.Db.Select(&elements, "SELECT * FROM elements WHERE symbol IN ('"+strings.Join(elementEmojis, "', '")+"')")
|
||||
if err != nil {
|
||||
c.Log.Error(err.Error())
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
|
||||
@ -67,6 +50,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
if len(hitPoints) != 3 {
|
||||
c.Log.Error("Can't parse hitpoints!")
|
||||
c.Log.Debug(pokememeRunesArray[5])
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
|
||||
@ -84,6 +68,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
if len(defenceMatch) < 1 {
|
||||
c.Log.Error("Can't parse defence!")
|
||||
c.Log.Debug(pokememeRunesArray[6])
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
defence = defenceMatch[0]
|
||||
@ -91,6 +76,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
if len(priceMatch) < 1 {
|
||||
c.Log.Error("Can't parse price!")
|
||||
c.Log.Debug(pokememeRunesArray[7])
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
price = priceMatch[0]
|
||||
@ -98,18 +84,21 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
if len(locationsPrepare) < 2 {
|
||||
c.Log.Error("Can't parse locations!")
|
||||
c.Log.Debug(pokememeRunesArray[8])
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
locationsNames := strings.Split(locationsPrepare[1], ", ")
|
||||
if len(locationsNames) < 1 {
|
||||
c.Log.Error("Can't parse locations!")
|
||||
c.Log.Debug(locationsPrepare)
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
|
||||
err2 := c.Db.Select(&locations, "SELECT * FROM locations WHERE name IN ('"+strings.Join(locationsNames, "', '")+"')")
|
||||
if err2 != nil {
|
||||
c.Log.Error(err2.Error())
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
if strings.HasSuffix(string(pokememeRunesArray[9]), "Можно") {
|
||||
@ -123,6 +112,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
if len(priceMatch) < 1 {
|
||||
c.Log.Error("Can't parse price!")
|
||||
c.Log.Debug(pokememeRunesArray[6])
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
price = priceMatch[0]
|
||||
@ -130,18 +120,21 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
if len(locationsPrepare) < 2 {
|
||||
c.Log.Error("Can't parse locations!")
|
||||
c.Log.Debug(pokememeRunesArray[7])
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
locationsNames := strings.Split(locationsPrepare[1], ", ")
|
||||
if len(locationsNames) < 1 {
|
||||
c.Log.Error("Can't parse locations!")
|
||||
c.Log.Debug(locationsPrepare)
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
|
||||
err2 := c.Db.Select(&locations, "SELECT * FROM locations WHERE name IN ('"+strings.Join(locationsNames, "', '")+"')")
|
||||
if err2 != nil {
|
||||
c.Log.Error(err2.Error())
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
if strings.HasSuffix(string(pokememeRunesArray[8]), "Можно") {
|
||||
@ -184,15 +177,16 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
c.Log.Debug("Adding new pokememe...")
|
||||
} else {
|
||||
c.Log.Info("This pokememe already exist. Return specific error.")
|
||||
p.pokememeAddDuplicateMessage(update)
|
||||
return "dup"
|
||||
}
|
||||
|
||||
gradeInt, _ := strconv.Atoi(grade)
|
||||
attackInt := p.getPoints(hitPoints[0])
|
||||
hpInt := p.getPoints(hitPoints[1])
|
||||
mpInt := p.getPoints(hitPoints[2])
|
||||
defenceInt := p.getPoints(defence)
|
||||
priceInt := p.getPoints(price)
|
||||
attackInt := c.Statistics.GetPoints(hitPoints[0])
|
||||
hpInt := c.Statistics.GetPoints(hitPoints[1])
|
||||
mpInt := c.Statistics.GetPoints(hitPoints[2])
|
||||
defenceInt := c.Statistics.GetPoints(defence)
|
||||
priceInt := c.Statistics.GetPoints(price)
|
||||
|
||||
pokememe.Grade = gradeInt
|
||||
pokememe.Name = name
|
||||
@ -214,6 +208,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
_, err4 := c.Db.NamedExec("INSERT INTO pokememes VALUES(NULL, :grade, :name, :description, :attack, :hp, :mp, :defence, :price, :purchaseable, :image_url, :player_id, :created_at)", &pokememe)
|
||||
if err4 != nil {
|
||||
c.Log.Error(err4.Error())
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
|
||||
@ -221,6 +216,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
err5 := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE grade='"+grade+"' AND name='"+name+"';"))
|
||||
if err5 != nil {
|
||||
c.Log.Error("Pokememe isn't added!")
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
for i := range elements {
|
||||
@ -232,6 +228,7 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
_, err6 := c.Db.NamedExec("INSERT INTO pokememes_elements VALUES(NULL, :pokememe_id, :element_id, :created_at)", &link)
|
||||
if err6 != nil {
|
||||
c.Log.Error(err6.Error())
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
}
|
||||
@ -244,23 +241,11 @@ func (p *Parsers) ParsePokememe(text string, playerRaw *dbmapping.Player) string
|
||||
_, err7 := c.Db.NamedExec("INSERT INTO pokememes_locations VALUES(NULL, :pokememe_id, :location_id, :created_at)", &link)
|
||||
if err7 != nil {
|
||||
c.Log.Error(err7.Error())
|
||||
p.pokememeAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
}
|
||||
|
||||
p.pokememeAddSuccessMessage(update)
|
||||
return "ok"
|
||||
}
|
||||
|
||||
// ReturnPoints returns to output points (ht, attack, mp...) formatted
|
||||
// like in PokememBroBot itself.
|
||||
func (p *Parsers) ReturnPoints(points int) string {
|
||||
if points < 1000 {
|
||||
return strconv.Itoa(points)
|
||||
} else if points < 1000000 {
|
||||
floatNum := float64(points) / 1000.0
|
||||
return strconv.FormatFloat(floatNum, 'f', -1, 64) + "K"
|
||||
} else {
|
||||
floatNum := float64(points) / 1000000.0
|
||||
return strconv.FormatFloat(floatNum, 'f', -1, 64) + "M"
|
||||
}
|
||||
}
|
85
lib/pokedexer/pokedexer.go
Normal file
85
lib/pokedexer/pokedexer.go
Normal file
@ -0,0 +1,85 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package pokedexer
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func (p *Pokedexer) pokememesListing(update *tgbotapi.Update, page int, pokememesArray []dbmapping.PokememeFull) {
|
||||
message := "*Известные боту покемемы*\n"
|
||||
message += "Список отсортирован по грейду и алфавиту.\n"
|
||||
message += "Покедекс: " + strconv.Itoa(len(pokememesArray)) + " / 219\n"
|
||||
message += "Отображаем покемемов с " + strconv.Itoa(((page-1)*50)+1) + " по " + strconv.Itoa(page*50) + "\n"
|
||||
if len(pokememesArray) > page*50 {
|
||||
message += "Переход на следующую страницу: /pokedeks" + strconv.Itoa(page+1)
|
||||
}
|
||||
if page > 1 {
|
||||
message += "\nПереход на предыдущую страницу: /pokedeks" + strconv.Itoa(page-1)
|
||||
}
|
||||
message += "\n\n"
|
||||
|
||||
for i := range pokememesArray {
|
||||
if (i+1 > 50*(page-1)) && (i+1 < (50*page)+1) {
|
||||
pk := pokememesArray[i].Pokememe
|
||||
pkE := pokememesArray[i].Elements
|
||||
message += strconv.Itoa(i+1) + ". " + strconv.Itoa(pk.Grade)
|
||||
message += "⃣ *" + pk.Name
|
||||
message += "* (" + c.Statistics.GetPrintablePoints(pk.HP) + "-" + c.Statistics.GetPrintablePoints(pk.MP) + ") ⚔️ *"
|
||||
message += c.Statistics.GetPrintablePoints(pk.Attack) + "* \\["
|
||||
for j := range pkE {
|
||||
message += pkE[j].Symbol
|
||||
}
|
||||
message += "] " + c.Statistics.GetPrintablePoints(pk.Price) + "$ /pk" + strconv.Itoa(pk.ID)
|
||||
message += "\n"
|
||||
}
|
||||
}
|
||||
|
||||
if len(pokememesArray) > page*50 {
|
||||
message += "\n"
|
||||
message += "Переход на следующую страницу: /pokedeks" + strconv.Itoa(page+1)
|
||||
}
|
||||
if page > 1 {
|
||||
message += "\nПереход на предыдущую страницу: /pokedeks" + strconv.Itoa(page-1)
|
||||
}
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
func (p *Pokedexer) pokememeAddSuccessMessage(update *tgbotapi.Update) {
|
||||
message := "*Покемем успешно добавлен.*\n\n"
|
||||
message += "Посмотреть всех известных боту покемемов можно командой /pokedeks"
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
func (p *Pokedexer) pokememeAddDuplicateMessage(update *tgbotapi.Update) {
|
||||
message := "*Мы уже знаем об этом покемеме*\n\n"
|
||||
message += "Посмотреть всех известных боту покемемов можно командой /pokedeks\n\n"
|
||||
message += "Если у покемема изменились описание или характеристики, напиши @fat0troll для обновления базы."
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
func (p *Pokedexer) pokememeAddFailureMessage(update *tgbotapi.Update) {
|
||||
message := "*Неудачно получилось :(*\n\n"
|
||||
message += "Случилась жуткая ошибка, и мы не смогли записать покемема в базу. Напиши @fat0troll, он разберется.\n\n"
|
||||
message += "Посмотреть всех известных боту покемемов можно командой /pokedeks"
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
}
|
21
lib/pokedexer/pokedexerinterface/pokedexerinterface.go
Normal file
21
lib/pokedexer/pokedexerinterface/pokedexerinterface.go
Normal file
@ -0,0 +1,21 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package pokedexerinterface
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
)
|
||||
|
||||
// PokedexerInterface implements Pokedexer for importing via appcontext.
|
||||
type PokedexerInterface interface {
|
||||
ParsePokememe(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
|
||||
PokememesList(update *tgbotapi.Update)
|
||||
PokememeInfo(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
BestPokememesList(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
|
||||
GetPokememes() ([]dbmapping.PokememeFull, bool)
|
||||
GetPokememeByID(pokememeID string) (dbmapping.PokememeFull, bool)
|
||||
}
|
148
lib/pokedexer/responders.go
Normal file
148
lib/pokedexer/responders.go
Normal file
@ -0,0 +1,148 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package pokedexer
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// BestPokememesList shows list for catching based on player league and grade
|
||||
func (p *Pokedexer) BestPokememesList(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
pokememes, ok := p.getBestPokememes(playerRaw.ID)
|
||||
if !ok {
|
||||
c.Log.Error("Cannot get pokememes from getter!")
|
||||
return "fail"
|
||||
}
|
||||
|
||||
message := "*Лучшие покемемы для ловли*\n\n"
|
||||
for i := range pokememes {
|
||||
pk := pokememes[i].Pokememe
|
||||
pkL := pokememes[i].Locations
|
||||
pkE := pokememes[i].Elements
|
||||
message += strconv.Itoa(pk.Grade) + "⃣ "
|
||||
message += pk.Name + " (⚔"
|
||||
message += c.Statistics.GetPrintablePoints(pk.Attack)
|
||||
message += ", 🛡" + c.Statistics.GetPrintablePoints(pk.Defence) + ")"
|
||||
for i := range pkE {
|
||||
message += pkE[i].Symbol
|
||||
}
|
||||
message += " /pk" + strconv.Itoa(pk.ID) + "\n"
|
||||
message += "Локации: "
|
||||
for i := range pkL {
|
||||
message += pkL[i].Symbol + pkL[i].Name
|
||||
if i+1 < len(pkL) {
|
||||
message += ", "
|
||||
}
|
||||
}
|
||||
message += "\nКупить: "
|
||||
if pk.Purchaseable {
|
||||
message += "💲" + c.Statistics.GetPrintablePoints(pk.Price*3)
|
||||
} else {
|
||||
message += "Нельзя"
|
||||
}
|
||||
message += "\n\n"
|
||||
}
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
return "ok"
|
||||
}
|
||||
|
||||
// PokememesList lists all known pokememes
|
||||
func (p *Pokedexer) PokememesList(update *tgbotapi.Update) {
|
||||
pageNumber := strings.Replace(update.Message.Text, "/pokedex", "", 1)
|
||||
pageNumber = strings.Replace(pageNumber, "/pokedeks", "", 1)
|
||||
page, _ := strconv.Atoi(pageNumber)
|
||||
if page == 0 {
|
||||
page = 1
|
||||
}
|
||||
pokememesArray, ok := p.GetPokememes()
|
||||
if !ok {
|
||||
c.Talkers.BotError(update)
|
||||
} else {
|
||||
p.pokememesListing(update, page, pokememesArray)
|
||||
}
|
||||
}
|
||||
|
||||
// PokememeInfo shows information about single pokememe based on internal ID
|
||||
func (p *Pokedexer) PokememeInfo(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
pokememeNumber := strings.Replace(update.Message.Text, "/pk", "", 1)
|
||||
var calculatePossibilites = true
|
||||
profileRaw, ok := c.Users.GetProfile(playerRaw.ID)
|
||||
if !ok {
|
||||
calculatePossibilites = false
|
||||
}
|
||||
|
||||
pokememe, ok := p.GetPokememeByID(pokememeNumber)
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
pk := pokememe.Pokememe
|
||||
|
||||
message := strconv.Itoa(pk.Grade) + "⃣ *" + pk.Name + "*\n"
|
||||
message += pk.Description + "\n\n"
|
||||
message += "Элементы:"
|
||||
for i := range pokememe.Elements {
|
||||
message += " " + pokememe.Elements[i].Symbol
|
||||
}
|
||||
message += "\n⚔ Атака: *" + c.Statistics.GetPrintablePoints(pk.Attack)
|
||||
message += "*\n❤️ HP: *" + c.Statistics.GetPrintablePoints(pk.HP)
|
||||
message += "*\n💙 MP: *" + c.Statistics.GetPrintablePoints(pk.MP)
|
||||
if pk.Defence != pk.Attack {
|
||||
message += "*\n🛡Защита: *" + c.Statistics.GetPrintablePoints(pk.Defence) + "* _(сопротивляемость покемема к поимке)_"
|
||||
} else {
|
||||
message += "*"
|
||||
}
|
||||
message += "\nСтоимость: *" + c.Statistics.GetPrintablePoints(pk.Price)
|
||||
message += "*\nКупить: *"
|
||||
if pk.Purchaseable {
|
||||
message += "Можно"
|
||||
} else {
|
||||
message += "Нельзя"
|
||||
}
|
||||
message += "*\nОбитает:"
|
||||
for i := range pokememe.Locations {
|
||||
message += " *" + pokememe.Locations[i].Name + "*"
|
||||
if (i + 1) < len(pokememe.Locations) {
|
||||
message += ","
|
||||
}
|
||||
}
|
||||
|
||||
if calculatePossibilites {
|
||||
if (pk.Grade < profileRaw.LevelID+2) && (pk.Grade > profileRaw.LevelID-3) {
|
||||
message += "\nВероятность поимки:"
|
||||
for i := range pokememe.Locations {
|
||||
percentile, pokeballs := c.Statistics.PossibilityRequiredPokeballs(pokememe.Locations[i].ID, pk.Grade, profileRaw.LevelID)
|
||||
message += "\n" + pokememe.Locations[i].Name + " – "
|
||||
message += strconv.FormatFloat(percentile, 'f', 2, 64) + "% или "
|
||||
message += strconv.Itoa(pokeballs) + "⭕"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
message += "\n" + pk.ImageURL
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
keyboard := tgbotapi.InlineKeyboardMarkup{}
|
||||
for i := range pokememe.Locations {
|
||||
var row []tgbotapi.InlineKeyboardButton
|
||||
btn := tgbotapi.NewInlineKeyboardButtonSwitch(pokememe.Locations[i].Symbol+pokememe.Locations[i].Name, pokememe.Locations[i].Symbol+pokememe.Locations[i].Name)
|
||||
row = append(row, btn)
|
||||
keyboard.InlineKeyboard = append(keyboard.InlineKeyboard, row)
|
||||
}
|
||||
|
||||
msg.ReplyMarkup = keyboard
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
return "ok"
|
||||
}
|
@ -22,7 +22,7 @@ func (r *Router) routeGroupRequest(update *tgbotapi.Update, playerRaw *dbmapping
|
||||
if update.Message.NewChatMembers != nil {
|
||||
newUsers := *update.Message.NewChatMembers
|
||||
if len(newUsers) > 0 {
|
||||
return c.Welcomer.WelcomeMessage(update)
|
||||
return c.Welcomer.GroupWelcomeMessage(update)
|
||||
}
|
||||
}
|
||||
// New chat names
|
||||
|
@ -33,51 +33,51 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi
|
||||
switch {
|
||||
case update.Message.Command() == "start":
|
||||
if playerRaw.ID != 0 {
|
||||
c.Talkers.HelloMessageAuthorized(update, playerRaw)
|
||||
c.Welcomer.PrivateWelcomeMessageAuthorized(update, playerRaw)
|
||||
return "ok"
|
||||
}
|
||||
|
||||
c.Talkers.HelloMessageUnauthorized(update)
|
||||
c.Welcomer.PrivateWelcomeMessageUnauthorized(update)
|
||||
return "ok"
|
||||
case update.Message.Command() == "help":
|
||||
c.Talkers.HelpMessage(update, playerRaw)
|
||||
return "ok"
|
||||
// Pokememes info
|
||||
case pokedexMsg.MatchString(text):
|
||||
c.Talkers.PokememesList(update)
|
||||
c.Pokedexer.PokememesList(update)
|
||||
return "ok"
|
||||
case pokememeInfoMsg.MatchString(text):
|
||||
c.Talkers.PokememeInfo(update, playerRaw)
|
||||
c.Pokedexer.PokememeInfo(update, playerRaw)
|
||||
return "ok"
|
||||
case update.Message.Command() == "me":
|
||||
if playerRaw.ID != 0 {
|
||||
c.Talkers.ProfileMessage(update, playerRaw)
|
||||
c.Users.ProfileMessage(update, playerRaw)
|
||||
return "ok"
|
||||
}
|
||||
|
||||
c.Talkers.AnyMessageUnauthorized(update)
|
||||
return "fail"
|
||||
case update.Message.Command() == "best":
|
||||
c.Talkers.BestPokememesList(update, playerRaw)
|
||||
c.Pokedexer.BestPokememesList(update, playerRaw)
|
||||
return "ok"
|
||||
case update.Message.Command() == "send_all":
|
||||
if c.Getters.PlayerBetterThan(playerRaw, "admin") {
|
||||
c.Talkers.AdminBroadcastMessageCompose(update, playerRaw)
|
||||
if c.Users.PlayerBetterThan(playerRaw, "admin") {
|
||||
c.Broadcaster.AdminBroadcastMessageCompose(update, playerRaw)
|
||||
return "ok"
|
||||
}
|
||||
|
||||
c.Talkers.AnyMessageUnauthorized(update)
|
||||
return "fail"
|
||||
case update.Message.Command() == "send_confirm":
|
||||
if c.Getters.PlayerBetterThan(playerRaw, "admin") {
|
||||
c.Talkers.AdminBroadcastMessageSend(update, playerRaw)
|
||||
if c.Users.PlayerBetterThan(playerRaw, "admin") {
|
||||
c.Broadcaster.AdminBroadcastMessageSend(update, playerRaw)
|
||||
return "ok"
|
||||
}
|
||||
|
||||
c.Talkers.AnyMessageUnauthorized(update)
|
||||
return "fail"
|
||||
case update.Message.Command() == "group_chats":
|
||||
if c.Getters.PlayerBetterThan(playerRaw, "admin") {
|
||||
if c.Users.PlayerBetterThan(playerRaw, "admin") {
|
||||
c.Chatter.GroupsList(update)
|
||||
return "ok"
|
||||
}
|
||||
@ -85,7 +85,7 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi
|
||||
c.Talkers.AnyMessageUnauthorized(update)
|
||||
return "fail"
|
||||
case update.Message.Command() == "squads":
|
||||
if c.Getters.PlayerBetterThan(playerRaw, "admin") {
|
||||
if c.Users.PlayerBetterThan(playerRaw, "admin") {
|
||||
c.Squader.SquadsList(update)
|
||||
return "ok"
|
||||
}
|
||||
@ -93,14 +93,14 @@ func (r *Router) routePrivateRequest(update *tgbotapi.Update, playerRaw *dbmappi
|
||||
c.Talkers.AnyMessageUnauthorized(update)
|
||||
return "fail"
|
||||
case update.Message.Command() == "make_squad":
|
||||
if c.Getters.PlayerBetterThan(playerRaw, "admin") {
|
||||
if c.Users.PlayerBetterThan(playerRaw, "admin") {
|
||||
return c.Squader.CreateSquad(update)
|
||||
}
|
||||
|
||||
c.Talkers.AnyMessageUnauthorized(update)
|
||||
return "fail"
|
||||
case update.Message.Command() == "pin":
|
||||
if c.Getters.PlayerBetterThan(playerRaw, "admin") {
|
||||
if c.Users.PlayerBetterThan(playerRaw, "admin") {
|
||||
return c.Pinner.PinMessageToAllChats(update)
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ import (
|
||||
|
||||
// RouteRequest decides, what to do with user input
|
||||
func (r *Router) RouteRequest(update *tgbotapi.Update) string {
|
||||
playerRaw, ok := c.Getters.GetOrCreatePlayer(update.Message.From.ID)
|
||||
playerRaw, ok := c.Users.GetOrCreatePlayer(update.Message.From.ID)
|
||||
if !ok {
|
||||
// Silently fail
|
||||
return "fail"
|
||||
|
@ -74,7 +74,7 @@ func (s *Squader) createSquad(update *tgbotapi.Update, chatID int, floodChatID i
|
||||
if err != nil {
|
||||
c.Log.Debug(err)
|
||||
|
||||
playerRaw, ok := c.Getters.GetOrCreatePlayer(update.Message.From.ID)
|
||||
playerRaw, ok := c.Users.GetOrCreatePlayer(update.Message.From.ID)
|
||||
if !ok {
|
||||
return squad, "fail"
|
||||
}
|
||||
@ -240,8 +240,8 @@ func (s *Squader) SquadStatictics(squadID int) string {
|
||||
for i := range squadMembers {
|
||||
fullInfo := dbmapping.SquadPlayerFull{}
|
||||
|
||||
playerRaw, _ := c.Getters.GetPlayerByID(squadMembers[i].PlayerID)
|
||||
profileRaw, _ := c.Getters.GetProfile(playerRaw.ID)
|
||||
playerRaw, _ := c.Users.GetPlayerByID(squadMembers[i].PlayerID)
|
||||
profileRaw, _ := c.Users.GetProfile(playerRaw.ID)
|
||||
|
||||
fullInfo.Squad = squad
|
||||
fullInfo.Player = playerRaw
|
||||
|
28
lib/statistics/exported.go
Normal file
28
lib/statistics/exported.go
Normal file
@ -0,0 +1,28 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package statistics
|
||||
|
||||
import (
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/statistics/statisticsinterface"
|
||||
)
|
||||
|
||||
var (
|
||||
c *appcontext.Context
|
||||
)
|
||||
|
||||
// Statistics is a function-handling struct for package statistics.
|
||||
type Statistics struct{}
|
||||
|
||||
// New is an initialization function for appcontext
|
||||
func New(ac *appcontext.Context) {
|
||||
c = ac
|
||||
s := &Statistics{}
|
||||
c.RegisterStatisticsInterface(statisticsinterface.StatisticsInterface(s))
|
||||
}
|
||||
|
||||
// Init is a initialization function for package
|
||||
func (s *Statistics) Init() {
|
||||
c.Log.Info("Initializing Statistics...")
|
||||
}
|
40
lib/statistics/points.go
Normal file
40
lib/statistics/points.go
Normal file
@ -0,0 +1,40 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package statistics
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// GetPoints returns points to use in database
|
||||
func (s *Statistics) GetPoints(pointsStr string) int {
|
||||
value := 0
|
||||
if strings.HasSuffix(pointsStr, "K") {
|
||||
valueNumber := strings.Replace(pointsStr, "K", "", 1)
|
||||
valueFloat, _ := strconv.ParseFloat(valueNumber, 64)
|
||||
value = int(valueFloat * 1000)
|
||||
} else if strings.HasSuffix(pointsStr, "M") {
|
||||
valueNumber := strings.Replace(pointsStr, "M", "", 1)
|
||||
valueFloat, _ := strconv.ParseFloat(valueNumber, 64)
|
||||
value = int(valueFloat * 1000000)
|
||||
} else {
|
||||
value, _ = strconv.Atoi(pointsStr)
|
||||
}
|
||||
return value
|
||||
}
|
||||
|
||||
// GetPrintablePoints returns to output points (ht, attack, mp...) formatted
|
||||
// like in PokememBroBot itself.
|
||||
func (s *Statistics) GetPrintablePoints(points int) string {
|
||||
if points < 1000 {
|
||||
return strconv.Itoa(points)
|
||||
} else if points < 1000000 {
|
||||
floatNum := float64(points) / 1000.0
|
||||
return strconv.FormatFloat(floatNum, 'f', -1, 64) + "K"
|
||||
} else {
|
||||
floatNum := float64(points) / 1000000.0
|
||||
return strconv.FormatFloat(floatNum, 'f', -1, 64) + "M"
|
||||
}
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package getters
|
||||
package statistics
|
||||
|
||||
// PossibilityRequiredPokeballs returns possibility of catching pokememe
|
||||
// It's based on location, grade of pokememe and current level of player
|
||||
func (g *Getters) PossibilityRequiredPokeballs(location int, grade int, lvl int) (float64, int) {
|
||||
func (s *Statistics) PossibilityRequiredPokeballs(location int, grade int, lvl int) (float64, int) {
|
||||
var basePossibility float64
|
||||
var requiredPokeballs int
|
||||
var percentile float64
|
14
lib/statistics/statisticsinterface/statisticinterface.go
Normal file
14
lib/statistics/statisticsinterface/statisticinterface.go
Normal file
@ -0,0 +1,14 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package statisticsinterface
|
||||
|
||||
// StatisticsInterface implements Statistics for importing via appcontext.
|
||||
type StatisticsInterface interface {
|
||||
Init()
|
||||
|
||||
GetPoints(pointsStr string) int
|
||||
GetPrintablePoints(points int) string
|
||||
|
||||
PossibilityRequiredPokeballs(location int, grade int, lvl int) (float64, int)
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package talkers
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// AdminBroadcastMessageCompose saves message for future broadcast
|
||||
func (t *Talkers) AdminBroadcastMessageCompose(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
broadcastingMessageBody := strings.Replace(update.Message.Text, "/send_all ", "", 1)
|
||||
|
||||
messageRaw, ok := c.Getters.CreateBroadcastMessage(playerRaw, broadcastingMessageBody, "all")
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
message := "Сообщение сохранено в базу.\n"
|
||||
message += "Выглядеть оно будет так:"
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
broadcastingMessage := "*Привет, %username%!*\n\n"
|
||||
broadcastingMessage += "*Важное сообщение от администратора " + update.Message.From.FirstName + " " + update.Message.From.LastName + "* (@" + update.Message.From.UserName + ")\n\n"
|
||||
broadcastingMessage += messageRaw.Text
|
||||
|
||||
msg = tgbotapi.NewMessage(update.Message.Chat.ID, broadcastingMessage)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
message = "Чтобы отправить сообщение всем, отправь команду /send\\_confirm " + strconv.Itoa(messageRaw.ID)
|
||||
|
||||
msg = tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
return "ok"
|
||||
}
|
||||
|
||||
// AdminBroadcastMessageSend sends saved message to all private chats
|
||||
func (t *Talkers) AdminBroadcastMessageSend(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
messageNum := strings.Replace(update.Message.Text, "/send_confirm ", "", 1)
|
||||
messageNumInt, _ := strconv.Atoi(messageNum)
|
||||
messageRaw, ok := c.Getters.GetBroadcastMessageByID(messageNumInt)
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
if messageRaw.AuthorID != playerRaw.ID {
|
||||
return "fail"
|
||||
}
|
||||
if messageRaw.Status != "new" {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
broadcastingMessageBody := messageRaw.Text
|
||||
|
||||
privateChats, ok := c.Chatter.GetAllPrivateChats()
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
for i := range privateChats {
|
||||
chat := privateChats[i]
|
||||
broadcastingMessage := "*Привет, " + chat.Name + "!*\n\n"
|
||||
broadcastingMessage += "*Важное сообщение от администратора " + update.Message.From.FirstName + " " + update.Message.From.LastName + "* (@" + update.Message.From.UserName + ")\n\n"
|
||||
broadcastingMessage += broadcastingMessageBody
|
||||
|
||||
msg := tgbotapi.NewMessage(int64(chat.TelegramID), broadcastingMessage)
|
||||
msg.ParseMode = "Markdown"
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
messageRaw, ok = c.Getters.UpdateBroadcastMessageStatus(messageRaw.ID, "sent")
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
message := "Сообщение всем отправлено. Надеюсь, пользователи бота за него тебя не убьют.\n"
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
return "ok"
|
||||
}
|
@ -18,8 +18,8 @@ func (t *Talkers) AnyMessageUnauthorized(update *tgbotapi.Update) {
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
// GetterError throws when bot can't get something
|
||||
func (t *Talkers) GetterError(update *tgbotapi.Update) {
|
||||
// BotError throws when bot can't do something
|
||||
func (t *Talkers) BotError(update *tgbotapi.Update) {
|
||||
message := "Ой, внутренняя ошибка в боте :(\n\n"
|
||||
message += "Напиши @fat0troll, приложив форвардом последние сообщения до этого.\n"
|
||||
|
||||
|
@ -24,5 +24,5 @@ func New(ac *appcontext.Context) {
|
||||
|
||||
// Init is an initialization function for talkers
|
||||
func (t *Talkers) Init() {
|
||||
c.Log.Info("Initializing responders...")
|
||||
c.Log.Info("Initializing common Responders...")
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ func (t *Talkers) HelpMessage(update *tgbotapi.Update, playerRaw *dbmapping.Play
|
||||
message += "+ /me – посмотреть свой сохраненный профиль в боте\n"
|
||||
message += "+ /best – посмотреть лучших покемонов для поимки\n"
|
||||
message += "+ /pokedeks – получить список известных боту покемемов\n"
|
||||
if c.Getters.PlayerBetterThan(playerRaw, "admin") {
|
||||
if c.Users.PlayerBetterThan(playerRaw, "admin") {
|
||||
message += "+ /send\\_all _текст_ — отправить сообщение всем пользователям бота\n"
|
||||
message += "+ /group\\_chats — получить список групп, в которых работает бот.\n"
|
||||
message += "+ /squads — получить список отрядов.\n"
|
||||
|
@ -1,151 +0,0 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package talkers
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Internal functions
|
||||
|
||||
func (t *Talkers) pokememesListing(update *tgbotapi.Update, page int, pokememesArray []dbmapping.PokememeFull) {
|
||||
message := "*Известные боту покемемы*\n"
|
||||
message += "Список отсортирован по грейду и алфавиту.\n"
|
||||
message += "Покедекс: " + strconv.Itoa(len(pokememesArray)) + " / 219\n"
|
||||
message += "Отображаем покемемов с " + strconv.Itoa(((page-1)*50)+1) + " по " + strconv.Itoa(page*50) + "\n"
|
||||
if len(pokememesArray) > page*50 {
|
||||
message += "Переход на следующую страницу: /pokedeks" + strconv.Itoa(page+1)
|
||||
}
|
||||
if page > 1 {
|
||||
message += "\nПереход на предыдущую страницу: /pokedeks" + strconv.Itoa(page-1)
|
||||
}
|
||||
message += "\n\n"
|
||||
|
||||
for i := range pokememesArray {
|
||||
if (i+1 > 50*(page-1)) && (i+1 < (50*page)+1) {
|
||||
pk := pokememesArray[i].Pokememe
|
||||
pkE := pokememesArray[i].Elements
|
||||
message += strconv.Itoa(i+1) + ". " + strconv.Itoa(pk.Grade)
|
||||
message += "⃣ *" + pk.Name
|
||||
message += "* (" + c.Parsers.ReturnPoints(pk.HP) + "-" + c.Parsers.ReturnPoints(pk.MP) + ") ⚔️ *"
|
||||
message += c.Parsers.ReturnPoints(pk.Attack) + "* \\["
|
||||
for j := range pkE {
|
||||
message += pkE[j].Symbol
|
||||
}
|
||||
message += "] " + c.Parsers.ReturnPoints(pk.Price) + "$ /pk" + strconv.Itoa(pk.ID)
|
||||
message += "\n"
|
||||
}
|
||||
}
|
||||
|
||||
if len(pokememesArray) > page*50 {
|
||||
message += "\n"
|
||||
message += "Переход на следующую страницу: /pokedeks" + strconv.Itoa(page+1)
|
||||
}
|
||||
if page > 1 {
|
||||
message += "\nПереход на предыдущую страницу: /pokedeks" + strconv.Itoa(page-1)
|
||||
}
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
}
|
||||
|
||||
// External functions
|
||||
|
||||
// PokememesList lists all known pokememes
|
||||
func (t *Talkers) PokememesList(update *tgbotapi.Update) {
|
||||
pageNumber := strings.Replace(update.Message.Text, "/pokedex", "", 1)
|
||||
pageNumber = strings.Replace(pageNumber, "/pokedeks", "", 1)
|
||||
page, _ := strconv.Atoi(pageNumber)
|
||||
if page == 0 {
|
||||
page = 1
|
||||
}
|
||||
pokememesArray, ok := c.Getters.GetPokememes()
|
||||
if !ok {
|
||||
t.GetterError(update)
|
||||
} else {
|
||||
t.pokememesListing(update, page, pokememesArray)
|
||||
}
|
||||
}
|
||||
|
||||
// PokememeInfo shows information about single pokememe based on internal ID
|
||||
func (t *Talkers) PokememeInfo(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
pokememeNumber := strings.Replace(update.Message.Text, "/pk", "", 1)
|
||||
var calculatePossibilites = true
|
||||
profileRaw, ok := c.Getters.GetProfile(playerRaw.ID)
|
||||
if !ok {
|
||||
calculatePossibilites = false
|
||||
}
|
||||
|
||||
pokememe, ok := c.Getters.GetPokememeByID(pokememeNumber)
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
pk := pokememe.Pokememe
|
||||
|
||||
message := strconv.Itoa(pk.Grade) + "⃣ *" + pk.Name + "*\n"
|
||||
message += pk.Description + "\n\n"
|
||||
message += "Элементы:"
|
||||
for i := range pokememe.Elements {
|
||||
message += " " + pokememe.Elements[i].Symbol
|
||||
}
|
||||
message += "\n⚔ Атака: *" + c.Parsers.ReturnPoints(pk.Attack)
|
||||
message += "*\n❤️ HP: *" + c.Parsers.ReturnPoints(pk.HP)
|
||||
message += "*\n💙 MP: *" + c.Parsers.ReturnPoints(pk.MP)
|
||||
if pk.Defence != pk.Attack {
|
||||
message += "*\n🛡Защита: *" + c.Parsers.ReturnPoints(pk.Defence) + "* _(сопротивляемость покемема к поимке)_"
|
||||
} else {
|
||||
message += "*"
|
||||
}
|
||||
message += "\nСтоимость: *" + c.Parsers.ReturnPoints(pk.Price)
|
||||
message += "*\nКупить: *"
|
||||
if pk.Purchaseable {
|
||||
message += "Можно"
|
||||
} else {
|
||||
message += "Нельзя"
|
||||
}
|
||||
message += "*\nОбитает:"
|
||||
for i := range pokememe.Locations {
|
||||
message += " *" + pokememe.Locations[i].Name + "*"
|
||||
if (i + 1) < len(pokememe.Locations) {
|
||||
message += ","
|
||||
}
|
||||
}
|
||||
|
||||
if calculatePossibilites {
|
||||
if (pk.Grade < profileRaw.LevelID+2) && (pk.Grade > profileRaw.LevelID-3) {
|
||||
message += "\nВероятность поимки:"
|
||||
for i := range pokememe.Locations {
|
||||
percentile, pokeballs := c.Getters.PossibilityRequiredPokeballs(pokememe.Locations[i].ID, pk.Grade, profileRaw.LevelID)
|
||||
message += "\n" + pokememe.Locations[i].Name + " – "
|
||||
message += strconv.FormatFloat(percentile, 'f', 2, 64) + "% или "
|
||||
message += strconv.Itoa(pokeballs) + "⭕"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
message += "\n" + pk.ImageURL
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
keyboard := tgbotapi.InlineKeyboardMarkup{}
|
||||
for i := range pokememe.Locations {
|
||||
var row []tgbotapi.InlineKeyboardButton
|
||||
btn := tgbotapi.NewInlineKeyboardButtonSwitch(pokememe.Locations[i].Symbol+pokememe.Locations[i].Name, pokememe.Locations[i].Symbol+pokememe.Locations[i].Name)
|
||||
row = append(row, btn)
|
||||
keyboard.InlineKeyboard = append(keyboard.InlineKeyboard, row)
|
||||
}
|
||||
|
||||
msg.ReplyMarkup = keyboard
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
return "ok"
|
||||
}
|
@ -1,43 +0,0 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package talkers
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
)
|
||||
|
||||
// PokememeAddSuccessMessage shows pokememe adding success message
|
||||
func (t *Talkers) PokememeAddSuccessMessage(update *tgbotapi.Update) {
|
||||
message := "*Покемем успешно добавлен.*\n\n"
|
||||
message += "Посмотреть всех известных боту покемемов можно командой /pokedeks"
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
// PokememeAddDuplicateMessage shows pokememe add duplication message
|
||||
func (t *Talkers) PokememeAddDuplicateMessage(update *tgbotapi.Update) {
|
||||
message := "*Мы уже знаем об этом покемеме*\n\n"
|
||||
message += "Посмотреть всех известных боту покемемов можно командой /pokedeks\n\n"
|
||||
message += "Если у покемема изменились описание или характеристики, напиши @fat0troll для обновления базы."
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
// PokememeAddFailureMessage shows pokememe add error message
|
||||
func (t *Talkers) PokememeAddFailureMessage(update *tgbotapi.Update) {
|
||||
message := "*Неудачно получилось :(*\n\n"
|
||||
message += "Случилась жуткая ошибка, и мы не смогли записать покемема в базу. Напиши @fat0troll, он разберется.\n\n"
|
||||
message += "Посмотреть всех известных боту покемемов можно командой /pokedeks"
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package talkers
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// BestPokememesList shows list for catching based on player league and grade
|
||||
func (t *Talkers) BestPokememesList(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
pokememes, ok := c.Getters.GetBestPokememes(playerRaw.ID)
|
||||
if !ok {
|
||||
c.Log.Error("Cannot get pokememes from getter!")
|
||||
return "fail"
|
||||
}
|
||||
|
||||
message := "*Лучшие покемемы для ловли*\n\n"
|
||||
for i := range pokememes {
|
||||
pk := pokememes[i].Pokememe
|
||||
pkL := pokememes[i].Locations
|
||||
pkE := pokememes[i].Elements
|
||||
message += strconv.Itoa(pk.Grade) + "⃣ "
|
||||
message += pk.Name + " (⚔"
|
||||
message += c.Parsers.ReturnPoints(pk.Attack)
|
||||
message += ", 🛡" + c.Parsers.ReturnPoints(pk.Defence) + ")"
|
||||
for i := range pkE {
|
||||
message += pkE[i].Symbol
|
||||
}
|
||||
message += " /pk" + strconv.Itoa(pk.ID) + "\n"
|
||||
message += "Локации: "
|
||||
for i := range pkL {
|
||||
message += pkL[i].Symbol + pkL[i].Name
|
||||
if i+1 < len(pkL) {
|
||||
message += ", "
|
||||
}
|
||||
}
|
||||
message += "\nКупить: "
|
||||
if pk.Purchaseable {
|
||||
message += "💲" + c.Parsers.ReturnPoints(pk.Price*3)
|
||||
} else {
|
||||
message += "Нельзя"
|
||||
}
|
||||
message += "\n\n"
|
||||
}
|
||||
|
||||
msg := tgbotapi.NewMessage(update.Message.Chat.ID, message)
|
||||
msg.ParseMode = "Markdown"
|
||||
|
||||
c.Bot.Send(msg)
|
||||
|
||||
return "ok"
|
||||
}
|
@ -11,25 +11,10 @@ import (
|
||||
// TalkersInterface implements Talkers for importing via appcontex
|
||||
type TalkersInterface interface {
|
||||
Init()
|
||||
HelloMessageUnauthorized(update *tgbotapi.Update)
|
||||
HelloMessageAuthorized(update *tgbotapi.Update, playerRaw *dbmapping.Player)
|
||||
HelpMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player)
|
||||
PokememesList(update *tgbotapi.Update)
|
||||
PokememeInfo(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
BestPokememesList(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
|
||||
PokememeAddSuccessMessage(update *tgbotapi.Update)
|
||||
PokememeAddDuplicateMessage(update *tgbotapi.Update)
|
||||
PokememeAddFailureMessage(update *tgbotapi.Update)
|
||||
ProfileAddSuccessMessage(update *tgbotapi.Update)
|
||||
ProfileAddFailureMessage(update *tgbotapi.Update)
|
||||
ProfileMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
|
||||
AnyMessageUnauthorized(update *tgbotapi.Update)
|
||||
GetterError(update *tgbotapi.Update)
|
||||
|
||||
AdminBroadcastMessageCompose(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
AdminBroadcastMessageSend(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
BotError(update *tgbotapi.Update)
|
||||
|
||||
DurakMessage(update *tgbotapi.Update)
|
||||
MatMessage(update *tgbotapi.Update)
|
||||
|
28
lib/users/exported.go
Normal file
28
lib/users/exported.go
Normal file
@ -0,0 +1,28 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package users
|
||||
|
||||
import (
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/appcontext"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/users/usersinterface"
|
||||
)
|
||||
|
||||
var (
|
||||
c *appcontext.Context
|
||||
)
|
||||
|
||||
// Users is a function-handling struct for users
|
||||
type Users struct{}
|
||||
|
||||
// New is a appcontext initialization function
|
||||
func New(ac *appcontext.Context) {
|
||||
c = ac
|
||||
u := &Users{}
|
||||
c.RegisterUsersInterface(usersinterface.UsersInterface(u))
|
||||
}
|
||||
|
||||
// Init is an initialization function for users
|
||||
func (u *Users) Init() {
|
||||
c.Log.Info("Initializing Users...")
|
||||
}
|
@ -1,15 +1,27 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package getters
|
||||
package users
|
||||
|
||||
import (
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GetProfile returns last saved profile of player
|
||||
func (u *Users) GetProfile(playerID int) (dbmapping.Profile, bool) {
|
||||
profileRaw := dbmapping.Profile{}
|
||||
err := c.Db.Get(&profileRaw, c.Db.Rebind("SELECT * FROM profiles WHERE player_id=? ORDER BY created_at DESC LIMIT 1"), playerID)
|
||||
if err != nil {
|
||||
c.Log.Error(err)
|
||||
return profileRaw, false
|
||||
}
|
||||
|
||||
return profileRaw, true
|
||||
}
|
||||
|
||||
// GetPlayerByID returns dbmapping.Player instance with given ID.
|
||||
func (g *Getters) GetPlayerByID(playerID int) (dbmapping.Player, bool) {
|
||||
func (u *Users) GetPlayerByID(playerID int) (dbmapping.Player, bool) {
|
||||
playerRaw := dbmapping.Player{}
|
||||
err := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE id=?"), playerID)
|
||||
if err != nil {
|
||||
@ -22,7 +34,7 @@ func (g *Getters) GetPlayerByID(playerID int) (dbmapping.Player, bool) {
|
||||
|
||||
// GetOrCreatePlayer seeks for player in database via Telegram ID.
|
||||
// In case, when there is no player with such ID, new player will be created.
|
||||
func (g *Getters) GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool) {
|
||||
func (u *Users) GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool) {
|
||||
playerRaw := dbmapping.Player{}
|
||||
err := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE telegram_id=?"), telegramID)
|
||||
if err != nil {
|
||||
@ -49,7 +61,7 @@ func (g *Getters) GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool) {
|
||||
|
||||
// PlayerBetterThan return true, if profile is more or equal powerful than
|
||||
// provided power level
|
||||
func (g *Getters) PlayerBetterThan(playerRaw *dbmapping.Player, powerLevel string) bool {
|
||||
func (u *Users) PlayerBetterThan(playerRaw *dbmapping.Player, powerLevel string) bool {
|
||||
var isBetter = false
|
||||
switch playerRaw.Status {
|
||||
case "owner":
|
@ -1,7 +1,7 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package parsers
|
||||
package users
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
@ -14,13 +14,13 @@ import (
|
||||
|
||||
// Internal functions
|
||||
|
||||
func (p *Parsers) fillProfilePokememe(profileID int, meme string, attack string, rarity string) {
|
||||
func (u *Users) fillProfilePokememe(profileID int, meme string, attack string, rarity string) {
|
||||
spkRaw := dbmapping.Pokememe{}
|
||||
err := c.Db.Get(&spkRaw, c.Db.Rebind("SELECT * FROM pokememes WHERE name='"+meme+"';"))
|
||||
if err != nil {
|
||||
c.Log.Error(err.Error())
|
||||
} else {
|
||||
attackInt := p.getPoints(attack)
|
||||
attackInt := c.Statistics.GetPoints(attack)
|
||||
ppk := dbmapping.ProfilePokememe{}
|
||||
ppk.ProfileID = profileID
|
||||
ppk.PokememeID = spkRaw.ID
|
||||
@ -37,7 +37,7 @@ func (p *Parsers) fillProfilePokememe(profileID int, meme string, attack string,
|
||||
// External functions
|
||||
|
||||
// ParseProfile parses user profile, forwarded from PokememBroBot, to database
|
||||
func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
func (u *Users) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
text := update.Message.Text
|
||||
c.Log.Info(text)
|
||||
|
||||
@ -78,6 +78,7 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
err1 := c.Db.Get(&league, c.Db.Rebind("SELECT * FROM leagues WHERE symbol='"+string(currentRunes[0])+"'"))
|
||||
if err1 != nil {
|
||||
c.Log.Error(err1.Error())
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
for j := range currentRunes {
|
||||
@ -91,6 +92,7 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
levelArray := levelRx.FindAllString(currentString, -1)
|
||||
if len(levelArray) < 1 {
|
||||
c.Log.Error("Level string broken")
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
level = levelArray[0]
|
||||
@ -102,6 +104,7 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
expArray := expRx.FindAllString(currentString, -1)
|
||||
if len(expArray) < 4 {
|
||||
c.Log.Error("Exp string broken")
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
exp = expArray[0]
|
||||
@ -115,6 +118,7 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
pkbArray := pkbRx.FindAllString(currentString, -1)
|
||||
if len(pkbArray) < 2 {
|
||||
c.Log.Error("Pokeballs string broken")
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
pokeballs = pkbArray[1]
|
||||
@ -126,12 +130,13 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
wealthArray := wealthRx.FindAllString(currentString, -1)
|
||||
if len(wealthArray) < 2 {
|
||||
c.Log.Error("Wealth string broken")
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
wealth = wealthArray[0]
|
||||
wealthInt = p.getPoints(wealth)
|
||||
wealthInt = c.Statistics.GetPoints(wealth)
|
||||
crystalls = wealthArray[1]
|
||||
crystallsInt = p.getPoints(crystalls)
|
||||
crystallsInt = c.Statistics.GetPoints(crystalls)
|
||||
}
|
||||
|
||||
if strings.HasPrefix(currentString, "🔫") {
|
||||
@ -146,11 +151,12 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
pkNumArray := pkmnumRx.FindAllString(currentString, -1)
|
||||
if len(pkNumArray) < 3 {
|
||||
c.Log.Error("Pokememes count broken")
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
pokememesCount, _ := strconv.Atoi(pkNumArray[0])
|
||||
pokememesWealth = pkNumArray[2]
|
||||
pokememesWealthInt = p.getPoints(pokememesWealth)
|
||||
pokememesWealthInt = c.Statistics.GetPoints(pokememesWealth)
|
||||
if pokememesCount > 0 {
|
||||
for pi := 0; pi < pokememesCount; pi++ {
|
||||
pokememeString := string(profileRunesArray[i+1+pi])
|
||||
@ -162,7 +168,7 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
pkName = strings.TrimSuffix(pkName, " ")
|
||||
pkName = strings.Split(pkName, "⃣ ")[1]
|
||||
pokememes[pkName] = pkAttack
|
||||
powerInt += p.getPoints(pkAttack)
|
||||
powerInt += c.Statistics.GetPoints(pkAttack)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,6 +216,7 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
_, err4 := c.Db.NamedExec("UPDATE `players` SET league_id=:league_id, status=:status WHERE id=:id", &playerRaw)
|
||||
if err4 != nil {
|
||||
c.Log.Error(err4.Error())
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
} else if playerRaw.LeagueID != league.ID {
|
||||
@ -220,11 +227,13 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
_, err5 := c.Db.NamedExec("INSERT INTO players VALUES(NULL, :telegram_id, :league_id, :status, :created_at, :updated_at)", &playerRaw)
|
||||
if err5 != nil {
|
||||
c.Log.Error(err5.Error())
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
err6 := c.Db.Get(&playerRaw, c.Db.Rebind("SELECT * FROM players WHERE telegram_id='"+strconv.Itoa(playerRaw.TelegramID)+"' AND league_id='"+strconv.Itoa(league.ID)+"';"))
|
||||
if err6 != nil {
|
||||
c.Log.Error(err6.Error())
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
}
|
||||
@ -247,6 +256,7 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
_, err3 := c.Db.NamedExec("INSERT INTO `profiles` VALUES(NULL, :player_id, :nickname, :telegram_nickname, :level_id, :pokeballs, :wealth, :pokememes_wealth, :exp, :egg_exp, :power, :weapon_id, :crystalls, :created_at)", &profileRaw)
|
||||
if err3 != nil {
|
||||
c.Log.Error(err3.Error())
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
|
||||
@ -254,6 +264,7 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
if err8 != nil {
|
||||
c.Log.Error(err8.Error())
|
||||
c.Log.Error("Profile isn't added!")
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
|
||||
@ -261,6 +272,7 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
_, err7 := c.Db.NamedExec("UPDATE `players` SET updated_at=:updated_at WHERE id=:id", &playerRaw)
|
||||
if err7 != nil {
|
||||
c.Log.Error(err7.Error())
|
||||
u.profileAddFailureMessage(update)
|
||||
return "fail"
|
||||
}
|
||||
|
||||
@ -282,8 +294,9 @@ func (p *Parsers) ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Pla
|
||||
rarity = "super liber"
|
||||
meme = strings.Replace(meme, "🔷", "", 1)
|
||||
}
|
||||
p.fillProfilePokememe(profileRaw.ID, meme, attack, rarity)
|
||||
u.fillProfilePokememe(profileRaw.ID, meme, attack, rarity)
|
||||
}
|
||||
|
||||
u.profileAddSuccessMessage(update)
|
||||
return "ok"
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package talkers
|
||||
package users
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
@ -10,8 +10,8 @@ import (
|
||||
)
|
||||
|
||||
// ProfileMessage shows current player's profile
|
||||
func (t *Talkers) ProfileMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
profileRaw, ok := c.Getters.GetProfile(playerRaw.ID)
|
||||
func (u *Users) ProfileMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) string {
|
||||
profileRaw, ok := u.GetProfile(playerRaw.ID)
|
||||
if !ok {
|
||||
c.Talkers.AnyMessageUnauthorized(update)
|
||||
return "fail"
|
||||
@ -60,13 +60,13 @@ func (t *Talkers) ProfileMessage(update *tgbotapi.Update, playerRaw *dbmapping.P
|
||||
message += "\n👤 " + strconv.Itoa(profileRaw.LevelID)
|
||||
message += " | 🎓 " + strconv.Itoa(profileRaw.Exp) + "/" + strconv.Itoa(level.MaxExp)
|
||||
message += " | 🥚 " + strconv.Itoa(profileRaw.EggExp) + "/" + strconv.Itoa(level.MaxEgg)
|
||||
message += "\n💲" + c.Parsers.ReturnPoints(profileRaw.Wealth)
|
||||
message += "\n💲" + c.Statistics.GetPrintablePoints(profileRaw.Wealth)
|
||||
message += " |💎" + strconv.Itoa(profileRaw.Crystalls)
|
||||
message += " |⭕" + strconv.Itoa(profileRaw.Pokeballs)
|
||||
message += "\n⚔Атака: 1 + " + c.Parsers.ReturnPoints(weapon.Power) + " + " + c.Parsers.ReturnPoints(attackPokememes) + "\n"
|
||||
message += "\n⚔Атака: 1 + " + c.Statistics.GetPrintablePoints(weapon.Power) + " + " + c.Statistics.GetPrintablePoints(attackPokememes) + "\n"
|
||||
|
||||
if profileRaw.WeaponID != 0 {
|
||||
message += "\n🔫Оружие: " + weapon.Name + " " + c.Parsers.ReturnPoints(weapon.Power) + "⚔"
|
||||
message += "\n🔫Оружие: " + weapon.Name + " " + c.Statistics.GetPrintablePoints(weapon.Power) + "⚔"
|
||||
}
|
||||
|
||||
message += "\n🐱Покемемы:"
|
||||
@ -75,11 +75,11 @@ func (t *Talkers) ProfileMessage(update *tgbotapi.Update, playerRaw *dbmapping.P
|
||||
if profilePokememes[i].PokememeID == pokememes[j].ID {
|
||||
message += "\n" + strconv.Itoa(pokememes[j].Grade)
|
||||
message += "⃣ " + pokememes[j].Name
|
||||
message += " +" + c.Parsers.ReturnPoints(profilePokememes[i].PokememeAttack) + "⚔"
|
||||
message += " +" + c.Statistics.GetPrintablePoints(profilePokememes[i].PokememeAttack) + "⚔"
|
||||
}
|
||||
}
|
||||
}
|
||||
message += "\nСтоимость покемемов на руках: " + c.Parsers.ReturnPoints(profileRaw.PokememesWealth) + "$"
|
||||
message += "\nСтоимость покемемов на руках: " + c.Statistics.GetPrintablePoints(profileRaw.PokememesWealth) + "$"
|
||||
message += "\n\n💳" + strconv.Itoa(playerRaw.TelegramID)
|
||||
message += "\n⏰Последнее обновление профиля: " + profileRaw.CreatedAt.Format("02.01.2006 15:04:05")
|
||||
message += "\n\nНе забывай обновляться, это важно для получения актуальной информации.\n\n"
|
@ -1,14 +1,16 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package talkers
|
||||
package users
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
)
|
||||
|
||||
// ProfileAddSuccessMessage shows profile addition success message
|
||||
func (t *Talkers) ProfileAddSuccessMessage(update *tgbotapi.Update) {
|
||||
// Internal functions for Users package
|
||||
|
||||
// profileAddSuccessMessage shows profile addition success message
|
||||
func (u *Users) profileAddSuccessMessage(update *tgbotapi.Update) {
|
||||
message := "*Профиль успешно обновлен.*\n\n"
|
||||
message += "Функциональность бота держится на актуальности профилей. Обновляйся почаще, и да пребудет с тобой Рандом!\n"
|
||||
message += "Сохраненный профиль ты можешь просмотреть командой /me.\n\n"
|
||||
@ -20,8 +22,8 @@ func (t *Talkers) ProfileAddSuccessMessage(update *tgbotapi.Update) {
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
// ProfileAddFailureMessage shows profile addition failure message
|
||||
func (t *Talkers) ProfileAddFailureMessage(update *tgbotapi.Update) {
|
||||
// profileAddFailureMessage shows profile addition failure message
|
||||
func (u *Users) profileAddFailureMessage(update *tgbotapi.Update) {
|
||||
message := "*Неудачно получилось :(*\n\n"
|
||||
message += "Случилась жуткая ошибка, и мы не смогли записать профиль в базу. Напиши @fat0troll, он разберется."
|
||||
|
23
lib/users/usersinterface/usersinterface.go
Normal file
23
lib/users/usersinterface/usersinterface.go
Normal file
@ -0,0 +1,23 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package usersinterface
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
)
|
||||
|
||||
// UsersInterface implements Users for importing via appcontex
|
||||
type UsersInterface interface {
|
||||
Init()
|
||||
|
||||
ParseProfile(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
|
||||
GetProfile(playerID int) (dbmapping.Profile, bool)
|
||||
GetOrCreatePlayer(telegramID int) (dbmapping.Player, bool)
|
||||
GetPlayerByID(playerID int) (dbmapping.Player, bool)
|
||||
PlayerBetterThan(playerRaw *dbmapping.Player, powerLevel string) bool
|
||||
|
||||
ProfileMessage(update *tgbotapi.Update, playerRaw *dbmapping.Player) string
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
// i2_bot – Instinct PokememBro Bot
|
||||
// Copyright (c) 2017 Vladimir "fat0troll" Hodakov
|
||||
|
||||
package talkers
|
||||
package welcomer
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
)
|
||||
|
||||
// HelloMessageUnauthorized tell new user what to do.
|
||||
func (t *Talkers) HelloMessageUnauthorized(update *tgbotapi.Update) {
|
||||
// PrivateWelcomeMessageUnauthorized tell new user what to do.
|
||||
func (w *Welcomer) PrivateWelcomeMessageUnauthorized(update *tgbotapi.Update) {
|
||||
message := "*Бот Инстинкта приветствует тебя!*\n\n"
|
||||
message += "Для начала работы с ботом, пожалуйста, перешли от бота игры @PokememBroBot профиль героя.\n"
|
||||
message += "Все дальнейшие действия с ботом возможны лишь при наличии профиля игрока."
|
||||
@ -20,8 +20,8 @@ func (t *Talkers) HelloMessageUnauthorized(update *tgbotapi.Update) {
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
// HelloMessageAuthorized greets existing user
|
||||
func (t *Talkers) HelloMessageAuthorized(update *tgbotapi.Update, playerRaw *dbmapping.Player) {
|
||||
// PrivateWelcomeMessageAuthorized greets existing user
|
||||
func (w *Welcomer) PrivateWelcomeMessageAuthorized(update *tgbotapi.Update, playerRaw *dbmapping.Player) {
|
||||
message := "*Бот Инстинкта приветствует тебя. Снова.*\n\n"
|
||||
message += "Привет, " + update.Message.From.FirstName + " " + update.Message.From.LastName + "!\n"
|
||||
message += "Последнее обновление информации о тебе: " + playerRaw.UpdatedAt.Format("02.01.2006 15:04:05 -0700")
|
||||
@ -31,3 +31,18 @@ func (t *Talkers) HelloMessageAuthorized(update *tgbotapi.Update, playerRaw *dbm
|
||||
|
||||
c.Bot.Send(msg)
|
||||
}
|
||||
|
||||
// GroupWelcomeMessage welcomes new user on group or bot itself
|
||||
func (w *Welcomer) GroupWelcomeMessage(update *tgbotapi.Update) string {
|
||||
newUsers := *update.Message.NewChatMembers
|
||||
for i := range newUsers {
|
||||
if (newUsers[i].UserName == "i2_bot") || (newUsers[i].UserName == "i2_dev_bot") {
|
||||
w.groupStartMessage(update)
|
||||
}
|
||||
|
||||
newUser := newUsers[i]
|
||||
w.groupWelcomeUser(update, &newUser)
|
||||
}
|
||||
|
||||
return "ok"
|
||||
}
|
@ -9,12 +9,12 @@ import (
|
||||
)
|
||||
|
||||
func (w *Welcomer) groupWelcomeUser(update *tgbotapi.Update, newUser *tgbotapi.User) string {
|
||||
playerRaw, ok := c.Getters.GetOrCreatePlayer(newUser.ID)
|
||||
playerRaw, ok := c.Users.GetOrCreatePlayer(newUser.ID)
|
||||
if !ok {
|
||||
return "fail"
|
||||
}
|
||||
|
||||
profileRaw, profileExist := c.Getters.GetProfile(playerRaw.ID)
|
||||
profileRaw, profileExist := c.Users.GetProfile(playerRaw.ID)
|
||||
|
||||
message := "*Бот Инстинкта приветствует тебя, *@"
|
||||
message += newUser.UserName
|
||||
@ -55,18 +55,3 @@ func (w *Welcomer) groupStartMessage(update *tgbotapi.Update) string {
|
||||
|
||||
return "ok"
|
||||
}
|
||||
|
||||
// WelcomeMessage welcomes new user on group or bot itself
|
||||
func (w *Welcomer) WelcomeMessage(update *tgbotapi.Update) string {
|
||||
newUsers := *update.Message.NewChatMembers
|
||||
for i := range newUsers {
|
||||
if (newUsers[i].UserName == "i2_bot") || (newUsers[i].UserName == "i2_dev_bot") {
|
||||
w.groupStartMessage(update)
|
||||
}
|
||||
|
||||
newUser := newUsers[i]
|
||||
w.groupWelcomeUser(update, &newUser)
|
||||
}
|
||||
|
||||
return "ok"
|
||||
}
|
||||
|
@ -5,10 +5,14 @@ package welcomerinterface
|
||||
|
||||
import (
|
||||
"github.com/go-telegram-bot-api/telegram-bot-api"
|
||||
"lab.pztrn.name/fat0troll/i2_bot/lib/dbmapping"
|
||||
)
|
||||
|
||||
// WelcomerInterface implements Welcomer for importing via appcontex
|
||||
type WelcomerInterface interface {
|
||||
Init()
|
||||
WelcomeMessage(update *tgbotapi.Update) string
|
||||
|
||||
PrivateWelcomeMessageUnauthorized(update *tgbotapi.Update)
|
||||
PrivateWelcomeMessageAuthorized(update *tgbotapi.Update, playerRaw *dbmapping.Player)
|
||||
GroupWelcomeMessage(update *tgbotapi.Update) string
|
||||
}
|
||||
|
Reference in New Issue
Block a user