From ef924d26c789d382ad087dba2b3f8352066c8b42 Mon Sep 17 00:00:00 2001 From: Vladimir Hodakov Date: Fri, 13 Oct 2017 03:05:26 +0400 Subject: [PATCH] Pokememes possibilities, some refactoring --- lib/config/config.go | 2 +- lib/{dbmappings => dbmapping}/elements.go | 4 +- lib/{dbmappings => dbmapping}/leagues.go | 4 +- lib/{dbmappings => dbmapping}/levels.go | 4 +- lib/{dbmappings => dbmapping}/locations.go | 4 +- lib/{dbmappings => dbmapping}/players.go | 4 +- lib/{dbmappings => dbmapping}/pokememes.go | 12 +- .../pokememes_elements.go | 4 +- .../pokememes_locations.go | 4 +- lib/{dbmappings => dbmapping}/profiles.go | 4 +- .../profiles_pokememes.go | 4 +- lib/{dbmappings => dbmapping}/weapons.go | 4 +- .../gettersinterface/gettersinterface.go | 14 +- lib/getters/player.go | 38 +++ lib/getters/pokememes.go | 143 ++++++++ lib/getters/possibility.go | 8 +- lib/getters/profile.go | 22 ++ lib/migrations/14_fix_time_element.go | 27 ++ lib/migrations/migrations.go | 1 + .../parsersinterface/parsersinterface.go | 6 +- lib/parsers/pokememe.go | 14 +- lib/parsers/profile.go | 14 +- lib/router/router.go | 31 +- lib/talkers/errors.go | 10 + lib/talkers/hello.go | 4 +- lib/talkers/help.go | 2 +- lib/talkers/pokedex.go | 312 ++++++------------ lib/talkers/profile.go | 22 +- .../talkersinterface/talkersinterface.go | 9 +- 29 files changed, 438 insertions(+), 293 deletions(-) rename lib/{dbmappings => dbmapping}/elements.go (90%) rename lib/{dbmappings => dbmapping}/leagues.go (88%) rename lib/{dbmappings => dbmapping}/levels.go (89%) rename lib/{dbmappings => dbmapping}/locations.go (88%) rename lib/{dbmappings => dbmapping}/players.go (92%) rename lib/{dbmappings => dbmapping}/pokememes.go (76%) rename lib/{dbmappings => dbmapping}/pokememes_elements.go (86%) rename lib/{dbmappings => dbmapping}/pokememes_locations.go (86%) rename lib/{dbmappings => dbmapping}/profiles.go (95%) rename lib/{dbmappings => dbmapping}/profiles_pokememes.go (89%) rename lib/{dbmappings => dbmapping}/weapons.go (90%) create mode 100644 lib/getters/player.go create mode 100644 lib/getters/pokememes.go create mode 100644 lib/getters/profile.go create mode 100644 lib/migrations/14_fix_time_element.go diff --git a/lib/config/config.go b/lib/config/config.go index cbe44b6..a8f1401 100644 --- a/lib/config/config.go +++ b/lib/config/config.go @@ -12,7 +12,7 @@ import ( "gopkg.in/yaml.v2" ) -const VERSION = "0.25" +const VERSION = "0.28" type DatabaseConnection struct { Host string `yaml:"host"` diff --git a/lib/dbmappings/elements.go b/lib/dbmapping/elements.go similarity index 90% rename from lib/dbmappings/elements.go rename to lib/dbmapping/elements.go index c0ee84d..3b6dc06 100644 --- a/lib/dbmappings/elements.go +++ b/lib/dbmapping/elements.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type Elements struct { +type Element struct { Id int `db:"id"` Symbol string `db:"symbol"` Name string `db:"name"` diff --git a/lib/dbmappings/leagues.go b/lib/dbmapping/leagues.go similarity index 88% rename from lib/dbmappings/leagues.go rename to lib/dbmapping/leagues.go index bf4a246..55eacfc 100644 --- a/lib/dbmappings/leagues.go +++ b/lib/dbmapping/leagues.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type Leagues struct { +type League struct { Id int `db:"id"` Symbol string `db:"symbol"` Name string `db:"name"` diff --git a/lib/dbmappings/levels.go b/lib/dbmapping/levels.go similarity index 89% rename from lib/dbmappings/levels.go rename to lib/dbmapping/levels.go index cf5a8b1..3dcf7bd 100644 --- a/lib/dbmappings/levels.go +++ b/lib/dbmapping/levels.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type Levels struct { +type Level struct { Id int `db:"id"` Max_exp int `db:"max_exp"` Max_egg int `db:"max_egg"` diff --git a/lib/dbmappings/locations.go b/lib/dbmapping/locations.go similarity index 88% rename from lib/dbmappings/locations.go rename to lib/dbmapping/locations.go index b8ec1b3..115d9cb 100644 --- a/lib/dbmappings/locations.go +++ b/lib/dbmapping/locations.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type Locations struct { +type Location struct { Id int `db:"id"` Symbol string `db:"symbol"` Name string `db:"name"` diff --git a/lib/dbmappings/players.go b/lib/dbmapping/players.go similarity index 92% rename from lib/dbmappings/players.go rename to lib/dbmapping/players.go index c0ad2bf..ca90eae 100644 --- a/lib/dbmappings/players.go +++ b/lib/dbmapping/players.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type Players struct { +type Player struct { Id int `db:"id"` Telegram_id int `db:"telegram_id"` League_id int `db:"league_id"` diff --git a/lib/dbmappings/pokememes.go b/lib/dbmapping/pokememes.go similarity index 76% rename from lib/dbmappings/pokememes.go rename to lib/dbmapping/pokememes.go index ebabdf1..5022d90 100644 --- a/lib/dbmappings/pokememes.go +++ b/lib/dbmapping/pokememes.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type Pokememes struct { +type Pokememe struct { Id int `db:"id"` Grade int `db:"grade"` Name string `db:"name"` @@ -23,3 +23,11 @@ type Pokememes struct { Player_id int `db:"player_id"` Created_at time.Time `db:"created_at"` } + +// Type for handling pokememe with all informations about locations and elements + +type PokememeFull struct { + Pokememe Pokememe + Locations []Location + Elements []Element +} diff --git a/lib/dbmappings/pokememes_elements.go b/lib/dbmapping/pokememes_elements.go similarity index 86% rename from lib/dbmappings/pokememes_elements.go rename to lib/dbmapping/pokememes_elements.go index 6fd3af8..7988c30 100644 --- a/lib/dbmappings/pokememes_elements.go +++ b/lib/dbmapping/pokememes_elements.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type PokememesElements struct { +type PokememeElement struct { Id int `db:"id"` Pokememe_id int `db:"pokememe_id"` Element_id int `db:"element_id"` diff --git a/lib/dbmappings/pokememes_locations.go b/lib/dbmapping/pokememes_locations.go similarity index 86% rename from lib/dbmappings/pokememes_locations.go rename to lib/dbmapping/pokememes_locations.go index 110dc7b..14e5af5 100644 --- a/lib/dbmappings/pokememes_locations.go +++ b/lib/dbmapping/pokememes_locations.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type PokememesLocations struct { +type PokememeLocation struct { Id int `db:"id"` Pokememe_id int `db:"pokememe_id"` Location_id int `db:"location_id"` diff --git a/lib/dbmappings/profiles.go b/lib/dbmapping/profiles.go similarity index 95% rename from lib/dbmappings/profiles.go rename to lib/dbmapping/profiles.go index 3e5e91d..2a5bdbf 100644 --- a/lib/dbmappings/profiles.go +++ b/lib/dbmapping/profiles.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type Profiles struct { +type Profile struct { Id int `db:"id"` Player_id int `db:"player_id"` Nickname string `db:"nickname"` diff --git a/lib/dbmappings/profiles_pokememes.go b/lib/dbmapping/profiles_pokememes.go similarity index 89% rename from lib/dbmappings/profiles_pokememes.go rename to lib/dbmapping/profiles_pokememes.go index 6369749..bd7a387 100644 --- a/lib/dbmappings/profiles_pokememes.go +++ b/lib/dbmapping/profiles_pokememes.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type ProfilesPokememes struct { +type ProfilePokememe struct { Id int `db:"id"` Profile_id int `db:"profile_id"` Pokememe_id int `db:"pokememe_id"` diff --git a/lib/dbmappings/weapons.go b/lib/dbmapping/weapons.go similarity index 90% rename from lib/dbmappings/weapons.go rename to lib/dbmapping/weapons.go index e46cb49..0ebbb17 100644 --- a/lib/dbmappings/weapons.go +++ b/lib/dbmapping/weapons.go @@ -1,14 +1,14 @@ // i2_bot – Instinct PokememBro Bot // Copyright (c) 2017 Vladimir "fat0troll" Hodakov -package dbmappings +package dbmapping import ( // stdlib "time" ) -type Weapons struct { +type Weapon struct { Id int `db:"id"` Name string `db:"name"` Power int `db:"power"` diff --git a/lib/getters/gettersinterface/gettersinterface.go b/lib/getters/gettersinterface/gettersinterface.go index d032fec..79856f7 100644 --- a/lib/getters/gettersinterface/gettersinterface.go +++ b/lib/getters/gettersinterface/gettersinterface.go @@ -3,8 +3,20 @@ package gettersinterface +import ( + // local + "../../dbmapping" +) + type GettersInterface interface { Init() + // Player + GetOrCreatePlayer(telegram_id int) (dbmapping.Player, bool) + // Profile + GetProfile(player_id int) (dbmapping.Profile, bool) + // Pokememes + GetPokememes() ([]dbmapping.PokememeFull, bool) + GetPokememeByID(pokememe_id string) (dbmapping.PokememeFull, bool) // Possibilities - PossibilityRequiredPokeballs(location int, grade int, lvl int) int + PossibilityRequiredPokeballs(location int, grade int, lvl int) (float64, int) } diff --git a/lib/getters/player.go b/lib/getters/player.go new file mode 100644 index 0000000..6bbaa92 --- /dev/null +++ b/lib/getters/player.go @@ -0,0 +1,38 @@ +// i2_bot – Instinct PokememBro Bot +// Copyright (c) 2017 Vladimir "fat0troll" Hodakov + +package getters + +import ( + // stdlib + "log" + "time" + // local + "../dbmapping" +) + +func (g *Getters) GetOrCreatePlayer(telegram_id int) (dbmapping.Player, bool) { + player_raw := dbmapping.Player{} + err := c.Db.Get(&player_raw, c.Db.Rebind("SELECT * FROM players WHERE telegram_id=?"), telegram_id) + if err != nil { + log.Printf("Message user not found in database.") + log.Printf(err.Error()) + + // Create "nobody" user + player_raw.Telegram_id = telegram_id + player_raw.League_id = 0 + player_raw.Squad_id = 0 + player_raw.Status = "nobody" + player_raw.Created_at = time.Now().UTC() + player_raw.Updated_at = time.Now().UTC() + _, err = c.Db.NamedExec("INSERT INTO players VALUES(NULL, :telegram_id, :league_id, :squad_id, :status, :created_at, :updated_at)", &player_raw) + if err != nil { + log.Printf(err.Error()) + return player_raw, false + } + } else { + log.Printf("Message user found in database.") + } + + return player_raw, true +} diff --git a/lib/getters/pokememes.go b/lib/getters/pokememes.go new file mode 100644 index 0000000..91baf35 --- /dev/null +++ b/lib/getters/pokememes.go @@ -0,0 +1,143 @@ +// i2_bot – Instinct PokememBro Bot +// Copyright (c) 2017 Vladimir "fat0troll" Hodakov + +package getters + +import ( + // stdlib + "log" + "strconv" + // local + "../dbmapping" +) + +func (g *Getters) GetPokememes() ([]dbmapping.PokememeFull, bool) { + pokememes_full := []dbmapping.PokememeFull{} + pokememes := []dbmapping.Pokememe{} + err := c.Db.Select(&pokememes, "SELECT * FROM pokememes ORDER BY grade asc, name asc"); + if err != nil { + log.Println(err) + return pokememes_full, false + } + elements := []dbmapping.Element{} + err = c.Db.Select(&elements, "SELECT * FROM elements"); + if err != nil { + log.Println(err) + return pokememes_full, false + } + locations := []dbmapping.Location{} + err = c.Db.Select(&locations, "SELECT * FROM locations"); + if err != nil { + log.Println(err) + return pokememes_full, false + } + pokememes_elements := []dbmapping.PokememeElement{} + err = c.Db.Select(&pokememes_elements, "SELECT * FROM pokememes_elements"); + if err != nil { + log.Println(err) + return pokememes_full, false + } + pokememes_locations := []dbmapping.PokememeLocation{} + err = c.Db.Select(&pokememes_locations, "SELECT * FROM pokememes_locations"); + if err != nil { + log.Println(err) + return pokememes_full, false + } + + for i := range(pokememes) { + full_pokememe := dbmapping.PokememeFull{} + elements_listed := []dbmapping.Element{} + locations_listed := []dbmapping.Location{} + + for j := range(pokememes_locations) { + if pokememes_locations[j].Pokememe_id == pokememes[i].Id { + for l := range(locations) { + if pokememes_locations[j].Location_id == locations[l].Id { + locations_listed = append(locations_listed, locations[l]) + } + } + } + } + + for k := range(pokememes_elements) { + if pokememes_elements[k].Pokememe_id == pokememes[i].Id { + for e := range(elements) { + if pokememes_elements[k].Element_id == elements[e].Id { + elements_listed = append(elements_listed, elements[e]) + } + } + } + } + + full_pokememe.Pokememe = pokememes[i] + full_pokememe.Elements = elements_listed + full_pokememe.Locations = locations_listed + + pokememes_full = append(pokememes_full, full_pokememe) + } + + return pokememes_full, true +} + +func (g *Getters) GetPokememeByID(pokememe_id string) (dbmapping.PokememeFull, bool) { + pokememe_full := dbmapping.PokememeFull{} + pokememe := dbmapping.Pokememe{} + err := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE id=?"), pokememe_id) + if err != nil { + log.Println(err) + return pokememe_full, false + } + elements := []dbmapping.Element{} + err = c.Db.Select(&elements, "SELECT * FROM elements"); + if err != nil { + log.Println(err) + return pokememe_full, false + } + locations := []dbmapping.Location{} + err = c.Db.Select(&locations, "SELECT * FROM locations"); + if err != nil { + log.Println(err) + return pokememe_full, false + } + pokememes_elements := []dbmapping.PokememeElement{} + err = c.Db.Select(&pokememes_elements, "SELECT * FROM pokememes_elements WHERE pokememe_id='" + strconv.Itoa(pokememe.Id) + "'"); + if err != nil { + log.Println(err) + return pokememe_full, false + } + pokememes_locations := []dbmapping.PokememeLocation{} + err = c.Db.Select(&pokememes_locations, "SELECT * FROM pokememes_locations WHERE pokememe_id='" + strconv.Itoa(pokememe.Id) + "'"); + if err != nil { + log.Println(err) + return pokememe_full, false + } + + elements_listed := []dbmapping.Element{} + locations_listed := []dbmapping.Location{} + + for j := range(pokememes_locations) { + if pokememes_locations[j].Pokememe_id == pokememe.Id { + for l := range(locations) { + if pokememes_locations[j].Location_id == locations[l].Id { + locations_listed = append(locations_listed, locations[l]) + } + } + } + } + + for k := range(pokememes_elements) { + if pokememes_elements[k].Pokememe_id == pokememe.Id { + for e := range(elements) { + if pokememes_elements[k].Element_id == elements[e].Id { + elements_listed = append(elements_listed, elements[e]) + } + } + } + } + + pokememe_full.Pokememe = pokememe + pokememe_full.Elements = elements_listed + pokememe_full.Locations = locations_listed + + return pokememe_full, true +} diff --git a/lib/getters/possibility.go b/lib/getters/possibility.go index 9ca179a..25a77fb 100644 --- a/lib/getters/possibility.go +++ b/lib/getters/possibility.go @@ -8,9 +8,10 @@ import ( "log" ) -func (g *Getters) PossibilityRequiredPokeballs(location int, grade int, lvl int) int { +func (g *Getters) PossibilityRequiredPokeballs(location int, grade int, lvl int) (float64, int) { var base_possibility float64 = 0.00 var required_pokeballs int = 0 + var percentile = 0.00 if lvl > 3 { switch { @@ -70,8 +71,9 @@ func (g *Getters) PossibilityRequiredPokeballs(location int, grade int, lvl int) } if base_possibility != 0 && number_of_pokememes != 0 { - required_pokeballs = int(1.0 / (base_possibility / float64(number_of_pokememes))) + percentile = base_possibility * 100.0 / float64(number_of_pokememes) + required_pokeballs = int(100.0 / percentile) } - return required_pokeballs + return percentile, required_pokeballs } diff --git a/lib/getters/profile.go b/lib/getters/profile.go new file mode 100644 index 0000000..64dac80 --- /dev/null +++ b/lib/getters/profile.go @@ -0,0 +1,22 @@ +// i2_bot – Instinct PokememBro Bot +// Copyright (c) 2017 Vladimir "fat0troll" Hodakov + +package getters + +import ( + // stdlib + "log" + // local + "../dbmapping" +) + +func (g *Getters) GetProfile(profile_id int) (dbmapping.Profile, bool) { + profile_raw := dbmapping.Profile{} + err := c.Db.Get(&profile_raw, c.Db.Rebind("SELECT * FROM profiles WHERE player_id=? ORDER BY created_at DESC LIMIT 1"), profile_id) + if err != nil { + log.Println(err) + return profile_raw, false + } + + return profile_raw, true +} diff --git a/lib/migrations/14_fix_time_element.go b/lib/migrations/14_fix_time_element.go new file mode 100644 index 0000000..3fb1317 --- /dev/null +++ b/lib/migrations/14_fix_time_element.go @@ -0,0 +1,27 @@ +// i2_bot – Instinct PokememBro Bot +// Copyright (c) 2017 Vladimir "fat0troll" Hodakov + +package migrations + +import ( + // stdlib + "database/sql" +) + +func FixTimeElementUp(tx *sql.Tx) error { + _, err := tx.Exec("UPDATE `elements` SET league_id=3 WHERE symbol='⌛';") + if err != nil { + return err + } + + return nil +} + +func FixTimeElementDown(tx *sql.Tx) error { + _, err := tx.Exec("UPDATE `elements` SET league_id=1 WHERE symbol='⌛';") + if err != nil { + return err + } + + return nil +} diff --git a/lib/migrations/migrations.go b/lib/migrations/migrations.go index 356f4aa..75f103b 100644 --- a/lib/migrations/migrations.go +++ b/lib/migrations/migrations.go @@ -28,6 +28,7 @@ func (m *Migrations) Init() { goose.AddNamedMigration("11_profile_data_additions.go", ProfileDataAdditionsUp, ProfileDataAdditionsDown) goose.AddNamedMigration("12_create_profile_relations.go", CreateProfileRelationsUp, CreateProfileRelationsDown) goose.AddNamedMigration("13_create_weapons_and_add_wealth.go", CreateWeaponsAndAddWealthUp, CreateWeaponsAndAddWealthDown) + goose.AddNamedMigration("14_fix_time_element.go", FixTimeElementUp, FixTimeElementDown) } func (m *Migrations) Migrate() error { diff --git a/lib/parsers/parsersinterface/parsersinterface.go b/lib/parsers/parsersinterface/parsersinterface.go index c13b1ca..dc5d03c 100644 --- a/lib/parsers/parsersinterface/parsersinterface.go +++ b/lib/parsers/parsersinterface/parsersinterface.go @@ -7,12 +7,12 @@ import ( // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" // local - "../../dbmappings" + "../../dbmapping" ) type ParsersInterface interface { - ParsePokememe(text string, player_raw dbmappings.Players) string - ParseProfile(update tgbotapi.Update, player_raw dbmappings.Players) string + ParsePokememe(text string, player_raw dbmapping.Player) string + ParseProfile(update tgbotapi.Update, player_raw dbmapping.Player) string ReturnPoints(points int) string } diff --git a/lib/parsers/pokememe.go b/lib/parsers/pokememe.go index 3d64b2c..548d72e 100644 --- a/lib/parsers/pokememe.go +++ b/lib/parsers/pokememe.go @@ -11,7 +11,7 @@ import ( "strconv" "time" // local - "../dbmappings" + "../dbmapping" ) // Internal functions @@ -34,7 +34,7 @@ func (p *Parsers) getPoints(points_str string) int { // External functions -func (p *Parsers) ParsePokememe(text string, player_raw dbmappings.Players) string { +func (p *Parsers) ParsePokememe(text string, player_raw dbmapping.Player) string { var defendable_pokememe bool = false pokememe_info_strings := strings.Split(text, "\n") pokememe_info_runed_strings := make([][]rune, 0) @@ -47,7 +47,7 @@ func (p *Parsers) ParsePokememe(text string, player_raw dbmappings.Players) stri } // Getting elements - elements := []dbmappings.Elements{} + elements := []dbmapping.Element{} element_emojis := make([]string, 0) element_emojis = append(element_emojis, string(pokememe_info_runed_strings[4][11])) if len(pokememe_info_runed_strings[4]) > 12 { @@ -75,7 +75,7 @@ func (p *Parsers) ParsePokememe(text string, player_raw dbmappings.Players) stri defence := "0" price := "0" - locations := []dbmappings.Locations{} + locations := []dbmapping.Location{} purchaseable := false image := "" @@ -180,7 +180,7 @@ func (p *Parsers) ParsePokememe(text string, player_raw dbmappings.Players) stri log.Printf("Image: " + image) // Building pokememe - pokememe := dbmappings.Pokememes{} + pokememe := dbmapping.Pokememe{} // Checking if pokememe exists in database err3 := c.Db.Get(&pokememe, c.Db.Rebind("SELECT * FROM pokememes WHERE grade='" + grade + "' AND name='" + name + "';")) if err3 != nil { @@ -227,7 +227,7 @@ func (p *Parsers) ParsePokememe(text string, player_raw dbmappings.Players) stri return "fail" } for i := range(elements) { - link := dbmappings.PokememesElements{} + link := dbmapping.PokememeElement{} link.Pokememe_id = pokememe.Id link.Element_id = elements[i].Id link.Created_at = time.Now().UTC() @@ -239,7 +239,7 @@ func (p *Parsers) ParsePokememe(text string, player_raw dbmappings.Players) stri } } for i := range(locations) { - link := dbmappings.PokememesLocations{} + link := dbmapping.PokememeLocation{} link.Pokememe_id = pokememe.Id link.Location_id = locations[i].Id link.Created_at = time.Now().UTC() diff --git a/lib/parsers/profile.go b/lib/parsers/profile.go index 8bc579a..8370e64 100644 --- a/lib/parsers/profile.go +++ b/lib/parsers/profile.go @@ -13,13 +13,13 @@ import ( // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" // local - "../dbmappings" + "../dbmapping" ) // Internal functions func (p *Parsers) fillProfilePokememe(profile_id int, meme string, attack string, rarity string) { - spk_raw := dbmappings.Pokememes{} + spk_raw := dbmapping.Pokememe{} err := c.Db.Get(&spk_raw, c.Db.Rebind("SELECT * FROM pokememes WHERE name='" + meme + "';")) if err != nil { log.Println(err) @@ -32,7 +32,7 @@ func (p *Parsers) fillProfilePokememe(profile_id int, meme string, attack string } level := int(float64(attack_int) / orig_attack) - ppk := dbmappings.ProfilesPokememes{} + ppk := dbmapping.ProfilePokememe{} ppk.Profile_id = profile_id ppk.Pokememe_id = spk_raw.Id ppk.Pokememe_lvl = level @@ -47,7 +47,7 @@ func (p *Parsers) fillProfilePokememe(profile_id int, meme string, attack string // External functions -func (p *Parsers) ParseProfile(update tgbotapi.Update, player_raw dbmappings.Players) string { +func (p *Parsers) ParseProfile(update tgbotapi.Update, player_raw dbmapping.Player) string { text := update.Message.Text log.Println(text) @@ -57,7 +57,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, player_raw dbmappings.Pla profile_info_runed_strings = append(profile_info_runed_strings, []rune(profile_info_strings[i])) } - league := dbmappings.Leagues{} + league := dbmapping.League{} telegram_nickname := update.Message.From.UserName nickname := "" @@ -199,7 +199,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, player_raw dbmappings.Pla } // Information is gathered, let's create profile in database! - weapon_raw := dbmappings.Weapons{} + weapon_raw := dbmapping.Weapon{} err2 := c.Db.Get(&weapon_raw, c.Db.Rebind("SELECT * FROM weapons WHERE name='" + weapon + "'")) if err2 != nil { log.Println(err2) @@ -234,7 +234,7 @@ func (p *Parsers) ParseProfile(update tgbotapi.Update, player_raw dbmappings.Pla } } - profile_raw := dbmappings.Profiles{} + profile_raw := dbmapping.Profile{} profile_raw.Player_id = player_raw.Id profile_raw.Nickname = nickname profile_raw.TelegramNickname = telegram_nickname diff --git a/lib/router/router.go b/lib/router/router.go index 8547b1f..55bbb4e 100644 --- a/lib/router/router.go +++ b/lib/router/router.go @@ -5,15 +5,11 @@ package router import ( // stdlib - "fmt" "log" "regexp" "strings" - "time" // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" - // local - "../dbmappings" ) type Router struct {} @@ -23,32 +19,13 @@ type Router struct {} // If command doesn't exist, it's "fail" func (r *Router) RouteRequest(update tgbotapi.Update) string { text := update.Message.Text - user_id := update.Message.From.ID - player_raw := dbmappings.Players{} - err := c.Db.Get(&player_raw, c.Db.Rebind("SELECT * FROM players WHERE telegram_id=?"), user_id) - if err != nil { - log.Printf("Message user not found in database.") - log.Printf(err.Error()) - - // Create "nobody" user - player_raw.Telegram_id = user_id - player_raw.League_id = 0 - player_raw.Squad_id = 0 - player_raw.Status = "nobody" - player_raw.Created_at = time.Now().UTC() - player_raw.Updated_at = time.Now().UTC() - _, erradd := c.Db.NamedExec("INSERT INTO players VALUES(NULL, :telegram_id, :league_id, :squad_id, :status, :created_at, :updated_at)", &player_raw) - if erradd != nil { - log.Printf(erradd.Error()) - return "fail" - } - } else { - log.Printf("Message user found in database.") + player_raw, ok := c.Getters.GetOrCreatePlayer(update.Message.From.ID) + if !ok { + // Silently fail + return "fail" } - fmt.Println(player_raw) - // Regular expressions var durakMsg = regexp.MustCompile("(Д|д)(У|у)(Р|р)(А|а|Е|е|О|о)") var huMsg = regexp.MustCompile("(Х|х)(У|у)(Й|й|Я|я|Ю|ю|Е|е)") diff --git a/lib/talkers/errors.go b/lib/talkers/errors.go index 3662fa7..052b4e4 100644 --- a/lib/talkers/errors.go +++ b/lib/talkers/errors.go @@ -17,3 +17,13 @@ func (t *Talkers) AnyMessageUnauthorized(update tgbotapi.Update) { c.Bot.Send(msg) } + +func (t *Talkers) GetterError(update tgbotapi.Update) { + error_message := "Ой, внутренняя ошибка в боте :(\n\n" + error_message += "Напиши @fat0troll, приложив форвардом последние сообщения до этого.\n" + + msg := tgbotapi.NewMessage(update.Message.Chat.ID, error_message) + msg.ParseMode = "Markdown" + + c.Bot.Send(msg) +} diff --git a/lib/talkers/hello.go b/lib/talkers/hello.go index a8bc8b6..45ad63a 100644 --- a/lib/talkers/hello.go +++ b/lib/talkers/hello.go @@ -7,7 +7,7 @@ import ( // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" // local - "../dbmappings" + "../dbmapping" ) func (t *Talkers) HelloMessageUnauthorized(update tgbotapi.Update) { @@ -21,7 +21,7 @@ func (t *Talkers) HelloMessageUnauthorized(update tgbotapi.Update) { c.Bot.Send(msg) } -func (t *Talkers) HelloMessageAuthorized(update tgbotapi.Update, player_raw dbmappings.Players) { +func (t *Talkers) HelloMessageAuthorized(update tgbotapi.Update, player_raw dbmapping.Player) { hello_message := "*Бот Инстинкта приветствует тебя. Снова.*\n\n" hello_message += "Привет, " + update.Message.From.FirstName + " " + update.Message.From.LastName + "!\n" hello_message += "Последнее обновление информации о тебе: " + player_raw.Updated_at.Format("02.01.2006 15:04:05 -0700") diff --git a/lib/talkers/help.go b/lib/talkers/help.go index bf065ad..d1b68aa 100644 --- a/lib/talkers/help.go +++ b/lib/talkers/help.go @@ -15,7 +15,7 @@ func (t *Talkers) HelpMessage(update tgbotapi.Update) { help_message += "Текущая версия: *" + config.VERSION + "*\n\n" help_message += "Список команд:\n\n" help_message += "+ /me – посмотреть свой сохраненный профиль в боте\n" - help_message += "+ /pokedex – получить список известных боту покемемов\n" + help_message += "+ /pokedeks – получить список известных боту покемемов\n" help_message += "+ /help – выводит данное сообщение\n" help_message += "\n\n" help_message += "Связаться с автором: @fat0troll\n" diff --git a/lib/talkers/pokedex.go b/lib/talkers/pokedex.go index 80c5875..5caaeaa 100644 --- a/lib/talkers/pokedex.go +++ b/lib/talkers/pokedex.go @@ -5,205 +5,22 @@ package talkers import ( // stdlib - "log" "strings" "strconv" // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" // local - "../dbmappings" + "../dbmapping" ) -type PokememeFull struct { - Pokememe dbmappings.Pokememes - Elements []dbmappings.Elements - Locations []dbmappings.Locations -} +// Internal functions -func (t *Talkers) PokememeInfo(update tgbotapi.Update, player_raw dbmappings.Players) string { - pokememe_number := strings.Replace(update.Message.Text, "/pk", "", 1) - var calculate_possibilites bool = false - profile_raw := dbmappings.Profiles{} - err := c.Db.Get(&profile_raw, c.Db.Rebind("SELECT * FROM profiles WHERE player_id=? ORDER BY created_at DESC LIMIT 1"), player_raw.Id) - if err != nil { - log.Println(err) - } else { - calculate_possibilites = true - } - - // Building pokememe - pk := dbmappings.Pokememes{} - // Checking if pokememe exists in database - err = c.Db.Get(&pk, c.Db.Rebind("SELECT * FROM pokememes WHERE id='" + pokememe_number + "'")) - if err != nil { - log.Println(err) - return "fail" - } - - elements := []dbmappings.Elements{} - err = c.Db.Select(&elements, "SELECT * FROM elements"); - if err != nil { - log.Println(err) - } - locations := []dbmappings.Locations{} - err = c.Db.Select(&locations, "SELECT * FROM locations"); - if err != nil { - log.Println(err) - } - - pokememes_elements := []dbmappings.PokememesElements{} - err = c.Db.Select(&pokememes_elements, "SELECT * FROM pokememes_elements WHERE pokememe_id='" + pokememe_number + "'"); - if err != nil { - log.Println(err) - } - pokememes_locations := []dbmappings.PokememesLocations{} - err = c.Db.Select(&pokememes_locations, "SELECT * FROM pokememes_locations WHERE pokememe_id='" + pokememe_number + "'"); - if err != nil { - log.Println(err) - } - - message := strconv.Itoa(pk.Grade) + "⃣ *" + pk.Name + "*\n" - message += pk.Description + "\n\n" - message += "Элементы:" - for i := range(pokememes_elements) { - for j := range(elements) { - if pokememes_elements[i].Element_id == elements[j].Id { - message += " " + elements[j].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(pokememes_locations) { - for j := range(locations) { - if pokememes_locations[i].Location_id == locations[j].Id { - message += " *" + locations[j].Name + "*" - if (i + 1) < len(pokememes_locations) { - message += "," - } - } - } - } - - if calculate_possibilites { - message += "\nВероятность поимки:" - for i := range(pokememes_locations) { - for j := range(locations) { - if pokememes_locations[i].Location_id == locations[j].Id { - message += "\n" + locations[j].Name + " – " + strconv.Itoa(c.Getters.PossibilityRequiredPokeballs(locations[j].Id, pk.Grade, profile_raw.Level_id)) + "⭕" - } - } - } - } - - message += "\n" + pk.Image_url - - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - keyboard := tgbotapi.InlineKeyboardMarkup{} - for i := range(pokememes_locations) { - for j := range(locations) { - if pokememes_locations[i].Location_id == locations[j].Id { - var row []tgbotapi.InlineKeyboardButton - btn := tgbotapi.NewInlineKeyboardButtonSwitch(locations[j].Symbol + locations[j].Name, locations[j].Symbol + locations[j].Name) - row = append(row, btn) - keyboard.InlineKeyboard = append(keyboard.InlineKeyboard, row) - } - } - } - - msg.ReplyMarkup = keyboard - msg.ParseMode = "Markdown" - - c.Bot.Send(msg) - - return "ok" -} - -func (t *Talkers) PokememesList(update tgbotapi.Update, page int) { - pokememes := []dbmappings.Pokememes{} - err := c.Db.Select(&pokememes, "SELECT * FROM pokememes"); - if err != nil { - log.Println(err) - } - pokememes_limited := []dbmappings.Pokememes{} - err = c.Db.Select(&pokememes_limited, "SELECT * FROM pokememes ORDER BY grade asc, name asc LIMIT 50 OFFSET " + strconv.Itoa(50*(page-1))); - if err != nil { - log.Println(err) - } - elements := []dbmappings.Elements{} - err = c.Db.Select(&elements, "SELECT * FROM elements"); - if err != nil { - log.Println(err) - } - locations := []dbmappings.Locations{} - err = c.Db.Select(&locations, "SELECT * FROM locations"); - if err != nil { - log.Println(err) - } - pokememes_elements := []dbmappings.PokememesElements{} - err = c.Db.Select(&pokememes_elements, "SELECT * FROM pokememes_elements"); - if err != nil { - log.Println(err) - } - pokememes_locations := []dbmappings.PokememesLocations{} - err = c.Db.Select(&pokememes_locations, "SELECT * FROM pokememes_locations"); - if err != nil { - log.Println(err) - } - - pokememes_full := []PokememeFull{} - - for i := range(pokememes_limited) { - full_pokememe := PokememeFull{} - elements_listed := []dbmappings.Elements{} - locations_listed := []dbmappings.Locations{} - - for j := range(pokememes_locations) { - if pokememes_locations[j].Pokememe_id == pokememes_limited[i].Id { - for l := range(locations) { - if pokememes_locations[j].Location_id == locations[l].Id { - locations_listed = append(locations_listed, locations[l]) - } - } - } - } - - for k := range(pokememes_elements) { - if pokememes_elements[k].Pokememe_id == pokememes_limited[i].Id { - for e := range(elements) { - if pokememes_elements[k].Element_id == elements[e].Id { - elements_listed = append(elements_listed, elements[e]) - } - } - } - } - - full_pokememe.Pokememe = pokememes_limited[i] - full_pokememe.Elements = elements_listed - full_pokememe.Locations = locations_listed - - pokememes_full = append(pokememes_full, full_pokememe) - } - - message := "*Известные боту покемемы*\n" - message += "Список отсортирован по грейду и алфавиту.\n" - message += "Покедекс: " + strconv.Itoa(len(pokememes)) + " / 206\n" +func (t *Talkers) pokememesListing(update tgbotapi.Update, page int, pokememes_full []dbmapping.PokememeFull) { + message := "*Известные боту покемемы*\n" + message += "Список отсортирован по грейду и алфавиту.\n" + message += "Покедекс: " + strconv.Itoa(len(pokememes_full)) + " / 206\n" message += "Отображаем покемемов с " + strconv.Itoa(((page - 1)*50)+1) + " по " + strconv.Itoa(page*50) + "\n" - if len(pokememes) > page*50 { + if len(pokememes_full) > page*50 { message += "Переход на следующую страницу: /pokedeks" + strconv.Itoa(page + 1) } if page > 1 { @@ -212,21 +29,110 @@ func (t *Talkers) PokememesList(update tgbotapi.Update, page int) { message += "\n\n" for i := range(pokememes_full) { - pk := pokememes_full[i].Pokememe - pk_e := pokememes_full[i].Elements - message += strconv.Itoa(i + 1 + (50*(page-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(pk_e) { - message += pk_e[j].Symbol + if (i + 1 > 50*(page - 1)) && (i + 1 < (50*page) + 1) { + pk := pokememes_full[i].Pokememe + pk_e := pokememes_full[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(pk_e) { + message += pk_e[j].Symbol + } + message += "] " + c.Parsers.ReturnPoints(pk.Price) + "$ /pk" + strconv.Itoa(pk.Id) + message += "\n" } - message += "] " + c.Parsers.ReturnPoints(pk.Price) + "$ /pk" + strconv.Itoa(pk.Id) - message += "\n" } - msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) - msg.ParseMode = "Markdown" + msg := tgbotapi.NewMessage(update.Message.Chat.ID, message) + msg.ParseMode = "Markdown" + + c.Bot.Send(msg) - c.Bot.Send(msg) +} + +// External functions + +func (t *Talkers) PokememesList(update tgbotapi.Update, page int) { + pokememes_full, ok := c.Getters.GetPokememes() + if !ok { + t.GetterError(update) + } else { + t.pokememesListing(update, page, pokememes_full) + } +} + +func (t *Talkers) PokememeInfo(update tgbotapi.Update, player_raw dbmapping.Player) string { + pokememe_number := strings.Replace(update.Message.Text, "/pk", "", 1) + var calculate_possibilites bool = true + profile_raw, ok := c.Getters.GetProfile(player_raw.Id) + if !ok { + calculate_possibilites = false + } + + pokememe, ok := c.Getters.GetPokememeByID(pokememe_number) + 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 calculate_possibilites { + if (pk.Grade < profile_raw.Level_id + 2) || (pk.Grade > profile_raw.Level_id - 3) { + message += "\nВероятность поимки:" + for i := range(pokememe.Locations) { + percentile, pokeballs := c.Getters.PossibilityRequiredPokeballs(pokememe.Locations[i].Id, pk.Grade, profile_raw.Level_id) + message += "\n" + pokememe.Locations[i].Name + " – " + message += strconv.FormatFloat(percentile, 'f', 2, 64) + "% или " + message += strconv.Itoa(pokeballs) + "⭕" + } + } + } + + message += "\n" + pk.Image_url + + 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" } diff --git a/lib/talkers/profile.go b/lib/talkers/profile.go index 39e5321..4520a54 100644 --- a/lib/talkers/profile.go +++ b/lib/talkers/profile.go @@ -10,40 +10,38 @@ import ( // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" // local - "../dbmappings" + "../dbmapping" ) -func (t *Talkers) ProfileMessage(update tgbotapi.Update, player_raw dbmappings.Players) string { - profile_raw := dbmappings.Profiles{} - err := c.Db.Get(&profile_raw, c.Db.Rebind("SELECT * FROM profiles WHERE player_id=? ORDER BY created_at DESC LIMIT 1"), player_raw.Id) - if err != nil { - log.Println(err) +func (t *Talkers) ProfileMessage(update tgbotapi.Update, player_raw dbmapping.Player) string { + profile_raw, ok := c.Getters.GetProfile(player_raw.Id) + if !ok { c.Talkers.AnyMessageUnauthorized(update) return "fail" } - league := dbmappings.Leagues{} - err = c.Db.Get(&league, c.Db.Rebind("SELECT * FROM leagues WHERE id=?"), player_raw.League_id) + league := dbmapping.League{} + err := c.Db.Get(&league, c.Db.Rebind("SELECT * FROM leagues WHERE id=?"), player_raw.League_id) if err != nil { log.Println(err) } - level := dbmappings.Levels{} + level := dbmapping.Level{} err = c.Db.Get(&level, c.Db.Rebind("SELECT * FROM levels WHERE id=?"), profile_raw.Level_id) if err != nil { log.Println(err) } - weapon := dbmappings.Weapons{} + weapon := dbmapping.Weapon{} if profile_raw.Weapon_id != 0 { err = c.Db.Get(&weapon, c.Db.Rebind("SELECT * FROM weapons WHERE id=?"), profile_raw.Weapon_id) if err != nil { log.Println(err) } } - p_pk := []dbmappings.ProfilesPokememes{} + p_pk := []dbmapping.ProfilePokememe{} err = c.Db.Select(&p_pk, c.Db.Rebind("SELECT * FROM profiles_pokememes WHERE profile_id=?"), profile_raw.Id) if err != nil { log.Println(err) } - pokememes := []dbmappings.Pokememes{} + pokememes := []dbmapping.Pokememe{} err = c.Db.Select(&pokememes, c.Db.Rebind("SELECT * FROM pokememes")) if err != nil { log.Println(err) diff --git a/lib/talkers/talkersinterface/talkersinterface.go b/lib/talkers/talkersinterface/talkersinterface.go index 3870ebe..09c2033 100644 --- a/lib/talkers/talkersinterface/talkersinterface.go +++ b/lib/talkers/talkersinterface/talkersinterface.go @@ -7,17 +7,17 @@ import ( // 3rd party "github.com/go-telegram-bot-api/telegram-bot-api" // local - "../../dbmappings" + "../../dbmapping" ) type TalkersInterface interface { Init() // Commands HelloMessageUnauthorized(update tgbotapi.Update) - HelloMessageAuthorized(update tgbotapi.Update, player_raw dbmappings.Players) + HelloMessageAuthorized(update tgbotapi.Update, player_raw dbmapping.Player) HelpMessage(update tgbotapi.Update) PokememesList(update tgbotapi.Update, page int) - PokememeInfo(update tgbotapi.Update, player_raw dbmappings.Players) string + PokememeInfo(update tgbotapi.Update, player_raw dbmapping.Player) string // Returns PokememeAddSuccessMessage(update tgbotapi.Update) @@ -25,10 +25,11 @@ type TalkersInterface interface { PokememeAddFailureMessage(update tgbotapi.Update) ProfileAddSuccessMessage(update tgbotapi.Update) ProfileAddFailureMessage(update tgbotapi.Update) - ProfileMessage(update tgbotapi.Update, player_raw dbmappings.Players) string + ProfileMessage(update tgbotapi.Update, player_raw dbmapping.Player) string // Errors AnyMessageUnauthorized(update tgbotapi.Update) + GetterError(update tgbotapi.Update) // Easter eggs DurakMessage(update tgbotapi.Update)