diff --git a/.dockerignore b/.dockerignore
index 707fbd5f..47d9cbdf 100644
--- a/.dockerignore
+++ b/.dockerignore
@@ -7,3 +7,5 @@ docs
.git
!.git/HEAD
!.git/refs/*
+config/
+!config/defaults-*.json
diff --git a/.github/workflows/publish-image.yml b/.github/workflows/publish-image.yml
index 387f55b0..352698f6 100644
--- a/.github/workflows/publish-image.yml
+++ b/.github/workflows/publish-image.yml
@@ -25,6 +25,7 @@ jobs:
echo ::set-output name=channel::"latest"
echo ::set-output name=version::main_$(cat VERSION)-${GITHUB_SHA::6}
elif [[ "$GITHUB_REF" == "refs/heads/"* ]]; then
+ echo ::set-output name=channel::${GITHUB_REF/refs\/heads\//}-"latest"
echo ::set-output name=version::${GITHUB_REF/refs\/heads\//}-$(cat VERSION)-${GITHUB_SHA::6}
elif [[ "$GITHUB_REF" == "refs/tags/"* ]]; then
echo ::set-output name=channel::${GITHUB_REF/refs\/tags\//}
@@ -60,3 +61,5 @@ jobs:
token: ${{ secrets.TELEGRAM_TOKEN }}
message: "New Docker image has been built: ${{ steps.meta.outputs.tags }}"
disable_web_page_preview: true
+ disable_notification: true
+
diff --git a/.gitignore b/.gitignore
index b9367220..81b81617 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,6 +5,7 @@
/access/**
/custom/**
/ddos/**
+/core/tools/hash.php
!/access/.gitkeep
!/custom/.gitkeep
!/ddos/.gitkeep
diff --git a/.htaccess b/.htaccess
index 9db9cb98..aa828807 100644
--- a/.htaccess
+++ b/.htaccess
@@ -1,11 +1,23 @@
-# Block access to all dot files
-RedirectMatch 404 /\..*$
+# Deny everything by default
+Order deny,allow
+Deny from all
-# Block access to .git files and folders
-RedirectMatch 404 /\.git
+# Allow plain requests that get routed to index.php
+/set [' . getTranslation("config_option") . '] [' . getTranslation('option_value') . ']' . CR;
+ foreach($json as $cfg_name => $cfg_value) {
+ // Only allowed configs
+ if(in_array($cfg_name, $allowed)) {
+ // Is alias set?
+ $alias = '';
+ if(isset($ajson[$cfg_name])){
+ $alias = $ajson[$cfg_name];
+ }
+ // Config name / Alias + value
+ $msg .= '/set' . SP . (empty($alias) ? $cfg_name : $alias) . SP . (empty($cfg_value) ? '' . getTranslation('no_value') . '' : $cfg_value);
+
+ // Only bool?
+ if(in_array($cfg_name, $allowed_bool)) {
+ $msg .= SP . '(' . getTranslation('help_only_bool') . ')';
+
+ // Only numbers?
+ } else if(in_array($cfg_name, $allowed_numbers)) {
+ $msg .= SP . '(' . getTranslation('help_only_numbers') . ')';
+
+ // Any type
+ }
+ $msg .= CR;
+ }
+ }
+ } else {
+ $msg .= getTranslation('not_supported');
+ }
+ debug_log('Unsupported request for a telegram config change: ' . $input);
+}
+
+// Send message.
+send_message(create_chat_object([$update['message']['chat']['id']]), $msg);
diff --git a/commands/start.php b/commands/start.php
index 23816ba8..67b450c2 100644
--- a/commands/start.php
+++ b/commands/start.php
@@ -1,99 +1,63 @@
accessCheck('create', true, $new_user);
+if(!$access && !$new_user) {
+ if($botUser->accessCheck('list', true)){
debug_log('No access to create, will do a list instead');
require('list.php');
- exit;
+ }else {
+ $response_msg = '' . getTranslation('bot_access_denied') . '';
+ send_message(create_chat_object([$update['message']['chat']['id']]), $response_msg);
+ }
+ exit;
}
-if($config->TUTORIAL_MODE && $new_user && (!$access or $access == 'BOT_ADMINS')) {
- // Tutorial
- if(is_file(ROOT_PATH . '/config/tutorial.php')) {
- require_once(ROOT_PATH . '/config/tutorial.php');
- }
- $msg = $tutorial[0]['msg_new'];
- $keys = [
- [
- [
- 'text' => getTranslation("next"),
- 'callback_data' => '0:tutorial:1'
- ]
- ]
- ];
- $photo = $tutorial[0]['photo'];
- send_photo($update['message']['from']['id'], $photo, $msg, $keys, ['disable_web_page_preview' => 'true'],false);
-}else {
- // Trim away everything before "/start "
- $searchterm = $update['message']['text'];
- $searchterm = substr($searchterm, 7);
- debug_log($searchterm, 'SEARCHTERM');
-
- // Start raid message.
- if(strpos($searchterm , 'c0de-') === 0) {
- $code_raid_id = explode("-", $searchterm, 2)[1];
- require_once(ROOT_PATH . '/mods/code_start.php');
- exit();
- }
+if($new_user && !$access) {
+ // Tutorial
+ require_once('tutorial.php');
+ exit;
+}
+// Trim away everything before "/start "
+$searchterm = $update['message']['text'];
+$searchterm = substr($searchterm, 7);
+debug_log($searchterm, 'SEARCHTERM');
- // Get the keys by gym name search.
- $keys = '';
- if(!empty($searchterm)) {
- $keys = raid_get_gyms_list_keys($searchterm);
- }
+// Start raid message.
+if(strpos($searchterm , 'c0de-') === 0) {
+ $code_raid_id = explode("-", $searchterm, 2)[1];
+ require_once(ROOT_PATH . '/mods/code_start.php');
+ exit();
+}
- // Get the keys if nothing was returned.
- if(!$keys) {
- $keys_and_gymarea = raid_edit_gyms_first_letter_keys('raid_by_gym', false, false, 'raid_by_gym_letter');
- $keys = $keys_and_gymarea['keys'];
- }
+// Get the keys by gym name search.
+$addAbortKey = true;
+$keys = false;
+if(!empty($searchterm)) {
+ $keys = raid_get_gyms_list_keys($searchterm);
+ $msg = getTranslation('select_gym_name');
+}
- // No keys found.
- if (!$keys) {
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('not_supported'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
- }else {
- $keys[] = [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
- }
- $msg = '';
- // Set message.
- if($config->ENABLE_GYM_AREAS) {
- if($keys_and_gymarea['gymarea_name'] == '') {
- $msg .= '' . getTranslation('select_gym_area') . '' . CR;
- }else {
- if($keys_and_gymarea['letters']) {
- $msg .= '' . getTranslation('select_gym_first_letter_or_gym_area') . '' . CR;
- }else {
- $msg .= '' . getTranslation('select_gym_name_or_gym_area') . '' . CR;
- }
- }
- }elseif($keys_and_gymarea['letters']) {
- $msg .= '' . getTranslation('select_gym_first_letter') . '' . CR;
- }else {
- $msg .= '' . getTranslation('select_gym_name') . '' . CR;
- }
- $msg.= (($keys_and_gymarea['gymarea_name'] != '') ? CR . CR . getTranslation('current_gymarea') . ': ' . $keys_and_gymarea['gymarea_name'] : '');
- $msg.= ($config->RAID_VIA_LOCATION ? (CR . CR . getTranslation('send_location')) : '');
+// Get the keys if nothing was returned.
+if(!$keys) {
+ $gymarea = resolveDefaultGymarea($botUser->userId);
+ $keys_and_gymarea = gymMenu('create', false, 1, false, $gymarea);
+ $keys = $keys_and_gymarea['keys'];
+ $msg = $keys_and_gymarea['gymareaTitle'];
+ $addAbortKey = false;
+}
- // Send message.
- send_message($update['message']['chat']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
+// No keys found.
+if ($addAbortKey) {
+ $keys[][] = button(getTranslation('abort'), 'exit');
}
-?>
+
+// Send message.
+send_message(create_chat_object([$update['message']['chat']['id']]), $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
diff --git a/commands/team.php b/commands/team.php
deleted file mode 100644
index 30489775..00000000
--- a/commands/team.php
+++ /dev/null
@@ -1,47 +0,0 @@
- 'mystic',
- 'instinct' => 'instinct',
- 'valor' => 'valor',
- getTranslation('red') => 'valor',
- getTranslation('blue') => 'mystic',
- getTranslation('yellow') => 'instinct',
- 'r' => 'valor',
- 'b' => 'mystic',
- 'y' => 'instinct',
- 'g' => 'instinct'
-);
-
-// Valid team name.
-if (!empty($gym_team) && $teams[$gym_team]) {
- // Update team in raids table.
- my_query(
- "
- UPDATE raids
- SET gym_team = '{$teams[$gym_team]}'
- WHERE user_id = {$update['message']['from']['id']}
- ORDER BY id DESC LIMIT 1
- "
- );
-
- // Send the message.
- send_message($update['message']['chat']['id'], getTranslation('gym_team_set_to') . ' ' . ucfirst($teams[$gym_team]));
-
-// Invalid team name.
-} else {
- // Send the message.
- send_message($update['message']['chat']['id'], getTranslation('invalid_team'));
-}
-
-?>
diff --git a/commands/trainer.php b/commands/trainer.php
index f6eeef33..a46237d5 100644
--- a/commands/trainer.php
+++ b/commands/trainer.php
@@ -1,91 +1,70 @@
accessCheck('trainer');
// Set message.
$msg = '' . getTranslation('trainerinfo_set_yours') . '';
-$user_id = $update['message']['from']['id'];
-$msg .= CR.CR.get_user($user_id, false);
+$user_id = $botUser->userId;
+$msg .= CR . CR . get_user($user_id, false);
// Init empty keys array.
$keys = [];
// Create keys array.
if($config->CUSTOM_TRAINERNAME){
- $keys[0][] =
- [
- 'text' => getTranslation('name'),
- 'callback_data' => '0:trainer_name:0'
- ];
+ $keys[0][] = button(getTranslation('name'), 'trainer_name');
}
if($config->RAID_POLL_SHOW_TRAINERCODE){
- $keys[0][] =
- [
- 'text' => getTranslation('trainercode'),
- 'callback_data' => '0:trainer_code:0'
- ];
+ $keys[0][] = button(getTranslation('trainercode'), 'trainer_code');
}
$keys[] = [
- [
- 'text' => getTranslation('team'),
- 'callback_data' => '0:trainer_team:0'
- ],
- [
- 'text' => getTranslation('level'),
- 'callback_data' => '0:trainer_level:0'
- ]
+ button(getTranslation('team'), 'trainer_team'),
+ button(getTranslation('level'), 'trainer_level')
];
if ($config->RAID_AUTOMATIC_ALARM == false) {
- $q_user = my_query("SELECT auto_alarm FROM users WHERE user_id = '{$user_id}' LIMIT 1");
- $alarm_status = $q_user->fetch()['auto_alarm'];
- $keys[] = [
- [
- 'text' => ($alarm_status == 1 ? getTranslation('switch_alarm_off') . ' ' . EMOJI_NO_ALARM : getTranslation('switch_alarm_on') . ' ' . EMOJI_ALARM),
- 'callback_data' => '0:trainer:a'
- ]
- ];
+ $q_user = my_query('SELECT auto_alarm FROM users WHERE user_id = ? LIMIT 1', [$user_id]);
+ $alarm_status = $q_user->fetch()['auto_alarm'];
+ $buttonText = ($alarm_status == 1 ? getTranslation('switch_alarm_off') . ' ' . EMOJI_NO_ALARM : getTranslation('switch_alarm_on') . ' ' . EMOJI_ALARM);
+ $keys[][] = button($buttonText, ['trainer', 'a' => 1]);
}
if ($config->LANGUAGE_PRIVATE == '') {
- $keys[] = [
- [
- 'text' => getTranslation('bot_lang'),
- 'callback_data' => '0:bot_lang:0'
- ]
- ];
+ $keys[][] = button(getTranslation('bot_lang'), 'bot_lang');
+}
+if ($config->ENABLE_GYM_AREAS == true) {
+ $keys[][] = button(getTranslation('default_gymarea'), 'trainerGymarea');
}
// Check access.
-$access = bot_access_check($update, 'trainer-share', true, true);
+$access = $botUser->accessCheck('trainer-share', true);
// Display sharing options for admins and users with trainer-share permissions
-if($access && (is_file(ROOT_PATH . '/access/' . $access) || $access == 'BOT_ADMINS')) {
- // Add sharing keys.
- $share_keys = [];
- $share_keys[] = universal_inner_key($keys, '0', 'trainer_add', '0', getTranslation('trainer_message_share'));
- $share_keys[] = universal_inner_key($keys, '0', 'trainer_delete', '0', getTranslation('trainer_message_delete'));
+if($access) {
+ // Add sharing keys.
+ $share_keys = [];
+ $share_keys[] = button(getTranslation('trainer_message_share'), 'trainer_add');
+ $share_keys[] = button(getTranslation('trainer_message_delete'), 'trainer_delete');
- // Get the inline key array.
- $keys[] = $share_keys;
+ // Get the inline key array.
+ $keys[] = $share_keys;
- // Add message.
- $msg .= CR . CR . getTranslation('trainer_message_share_or_delete');
+ // Add message.
+ $msg .= CR . CR . getTranslation('trainer_message_share_or_delete');
}
// Add abort key.
$nav_keys = [];
-$nav_keys[] = universal_inner_key($keys, '0', 'exit', '0', getTranslation('abort'));
+$nav_keys[] = button(getTranslation('done'), 'exit');
// Get the inline key array.
$keys[] = $nav_keys;
// Send message.
-send_message($update['message']['chat']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
-
-?>
+send_message(create_chat_object([$update['message']['chat']['id']]), $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
diff --git a/commands/tutorial.php b/commands/tutorial.php
index 3b8b7695..6be95479 100644
--- a/commands/tutorial.php
+++ b/commands/tutorial.php
@@ -7,26 +7,15 @@
//debug_log($data);
// Check access.
-bot_access_check($update, 'tutorial');
+$botUser->accessCheck('tutorial');
// Tutorial
if(is_file(ROOT_PATH . '/config/tutorial.php')) {
- require_once(ROOT_PATH . '/config/tutorial.php');
+ require_once(ROOT_PATH . '/config/tutorial.php');
}
-$new_user = new_user($update['message']['from']['id']);
-if($new_user) {
- $msg = $tutorial[0]['msg_new'];
-}else {
- $msg = $tutorial[0]['msg'];
-}
-$keys = [
-[
- [
- 'text' => getTranslation("next"),
- 'callback_data' => '0:tutorial:1'
- ]
-]
-];
+// New user can already be set if this file was included from start.php. If not, set it here
+$new_user = $new_user ?? new_user($update['message']['from']['id']);
+$msg = ($new_user) ? $tutorial[0]['msg_new'] : $tutorial[0]['msg'];
+$keys[][] = button(getTranslation('next'), ['tutorial', 'p' => 1]);
$photo = $tutorial[0]['photo'];
-send_photo($update['message']['from']['id'], $photo, $msg, $keys, ['disable_web_page_preview' => 'true'],false);
-?>
\ No newline at end of file
+send_photo(create_chat_object([$update['message']['from']['id']]), $photo, false, $msg, $keys, ['disable_web_page_preview' => 'true'],false);
diff --git a/config/config.json.example b/config/config.json.example
index 7e2e5ea9..8114a7f4 100644
--- a/config/config.json.example
+++ b/config/config.json.example
@@ -19,6 +19,5 @@
"RAID_PICTURE": false,
"RAID_PICTURE_AUTOEXTEND": false,
"RAID_PICTURE_STORE_GYM_IMAGES_LOCALLY": true,
- "RAID_PICTURE_URL":"https://example.com/raid/raidpicture.php",
"RAID_POLL_UI_TEMPLATE":[["alone","extra","extra_alien","remote","inv_plz","can_inv","ex_inv"],["teamlvl"],["time"],["pokemon"],["refresh","alarm","here","late","done","cancel"]]
}
diff --git a/config/defaults-config.json b/config/defaults-config.json
index 8c7f7b6d..977fbb50 100644
--- a/config/defaults-config.json
+++ b/config/defaults-config.json
@@ -16,7 +16,7 @@
"APIKEY_HASH":"",
"ENABLE_DDOS_PROTECTION": true,
"DDOS_MAXIMUM":"10",
- "BRIDGE_MODE": false,
+ "CURL_IPRESOLVE_V4": false,
"CURL_USEPROXY": false,
"CURL_PROXYSERVER":"http://example.com:8080",
"MAINTAINER":"",
@@ -30,6 +30,7 @@
"MAPS_LOOKUP": false,
"MAPS_API_KEY":"",
"OSM_LOOKUP": false,
+ "OSM_URL": "https://nominatim.openstreetmap.org",
"AUTO_REFRESH_POLLS":false,
"ENABLE_BOSS_AUTO_UPDATE": true,
"CUSTOM_TRAINERNAME": true,
@@ -38,14 +39,22 @@
"RAID_VIA_LOCATION": true,
"RAID_VIA_LOCATION_FUNCTION": "create",
"RAID_EGG_DURATION":"60",
+ "RAID_EGG_DURATION_ELITE":"1440",
+ "RAID_BOSS_LIST": false,
+ "RAID_BOSS_LIST_TITLE": "Raidbosses:",
+ "RAID_BOSS_LIST_RAID_LEVELS": [5,7,8,10],
+ "RAID_BOSS_LIST_ROW_LIMIT": "4",
"RAID_DURATION":"45",
+ "RAID_DURATION_ELITE":"30",
"RAID_DURATION_CLOCK_STYLE": true,
"RAID_CUSTOM_GYM_LETTERS":"",
"RAID_EXCLUDE_EXRAID_DUPLICATION": true,
+ "RAID_EXCLUDE_ELITE_DUPLICATION": true,
"RAID_EXCLUDE_EVENT_DUPLICATION": true,
"RAID_LOCATION": false,
"RAID_SLOTS":"15",
"RAID_DIRECT_START": false,
+ "RAID_RSVP_SLOTS": false,
"RAID_FIRST_START":"5",
"RAID_LAST_START":"5",
"RAID_ANYTIME": false,
@@ -67,7 +76,6 @@
"RAID_PICTURE_SHOW_SHINY": true,
"RAID_DEFAULT_PICTURE":"images/gym_default.png",
"RAID_PICTURE_STORE_GYM_IMAGES_LOCALLY": true,
- "RAID_PICTURE_URL":"https://example.com/raid/raidpicture.php",
"RAID_PICTURE_FONT_GYM":"NotoSans-Bold.ttf",
"RAID_PICTURE_FONT_EX_GYM":"NotoSans-Regular.ttf",
"RAID_PICTURE_FONT_TEXT":"NotoSans-Regular.ttf",
@@ -94,11 +102,13 @@
"RAID_EX_GYM_MARKER":"icon",
"RAID_CREATION_EX_GYM_MARKER": true,
"UPGRADE_SQL_AUTO": true,
- "TRAINER_MAX_LEVEL":"50",
- "TRAINER_BUTTONS_TOGGLE": false,
+ "TRAINER_MAX_LEVEL":"80",
"TRAINER_CHATS":"",
"SHARE_CHATS":"",
"SHARE_CHATS_LEVEL_X":"",
+ "SHARE_CHATS_LEVEL_9":"",
+ "SHARE_CHATS_LEVEL_8":"",
+ "SHARE_CHATS_LEVEL_7":"",
"SHARE_CHATS_LEVEL_6":"",
"SHARE_CHATS_LEVEL_5":"",
"SHARE_CHATS_LEVEL_4":"",
@@ -108,24 +118,32 @@
"WEBHOOK_CREATOR":"bot_or_user_id",
"WEBHOOK_CREATE_ONLY": false,
"WEBHOOK_CHATS_ALL_LEVELS":"",
+ "WEBHOOK_CHATS_LEVEL_9":"",
+ "WEBHOOK_CHATS_LEVEL_8":"",
+ "WEBHOOK_CHATS_LEVEL_7":"",
"WEBHOOK_CHATS_LEVEL_6":"",
"WEBHOOK_CHATS_LEVEL_5":"",
"WEBHOOK_CHATS_LEVEL_4":"",
"WEBHOOK_CHATS_LEVEL_3":"",
"WEBHOOK_CHATS_LEVEL_2":"",
"WEBHOOK_CHATS_LEVEL_1":"",
+ "WEBHOOK_CHATS_LEVEL_9_0":"",
+ "WEBHOOK_CHATS_LEVEL_8_0":"",
+ "WEBHOOK_CHATS_LEVEL_7_0":"",
"WEBHOOK_CHATS_LEVEL_6_0":"",
"WEBHOOK_CHATS_LEVEL_5_0":"",
"WEBHOOK_CHATS_LEVEL_4_0":"",
"WEBHOOK_CHATS_LEVEL_3_0":"",
"WEBHOOK_CHATS_LEVEL_2_0":"",
"WEBHOOK_CHATS_LEVEL_1_0":"",
+ "WEBHOOK_CHATS_LEVEL_7_1":"",
"WEBHOOK_CHATS_LEVEL_6_1":"",
"WEBHOOK_CHATS_LEVEL_5_1":"",
"WEBHOOK_CHATS_LEVEL_4_1":"",
"WEBHOOK_CHATS_LEVEL_3_1":"",
"WEBHOOK_CHATS_LEVEL_2_1":"",
"WEBHOOK_CHATS_LEVEL_1_1":"",
+ "WEBHOOK_CHATS_BY_POKEMON" : [],
"WEBHOOK_EXCLUDE_UNKNOWN": false,
"WEBHOOK_EXCLUDE_RAID_LEVEL":"1,2,3",
"WEBHOOK_EXCLUDE_POKEMON":"",
diff --git a/config/defaults-telegram.json b/config/defaults-telegram.json
index fa9bd880..7cccb0d7 100644
--- a/config/defaults-telegram.json
+++ b/config/defaults-telegram.json
@@ -1,4 +1,4 @@
-{
+{
"ALLOWED_TELEGRAM_CONFIG":"RAID_EGG_DURATION,RAID_DURATION,ENABLE_BOSS_AUTO_UPDATE",
"ALLOW_ONLY_TRUE_FALSE":"ENABLE_BOSS_AUTO_UPDATE",
"ALLOW_ONLY_NUMBERS":"RAID_EGG_DURATION,RAID_DURATION"
diff --git a/config/tutorial.php.example b/config/tutorial.php.example
index bec2229b..694ec8e0 100644
--- a/config/tutorial.php.example
+++ b/config/tutorial.php.example
@@ -14,5 +14,3 @@ $tutorial[2]['photo'] = '';// A photo url must be set!
$tutorial_done = 'Message that is left to user after completing the tutorial.';
$tutorial_grant_level = 1; // The tutorial value set to user in db (int)0-9
-
-?>
\ No newline at end of file
diff --git a/constants.php b/constants.php
index eedf0507..41eafe8c 100644
--- a/constants.php
+++ b/constants.php
@@ -1,16 +1,114 @@
1,
+ '3' => 3,
+ '4' => 4,
+ '5' => 5,
+ '6' => 'MEGA',
+ '7' => 'MEGA_5',
+ '8' => 'ULTRA_BEAST',
+ '9' => 'ELITE',
+ '10' => 'PRIMAL',
+ '11' => '1_SHADOW',
+ '13' => '3_SHADOW',
+ '15' => '5_SHADOW',
+ '16' => 'SUPER_MEGA_4', // Pokebattler currently uses MEGA_5 for super mega raids. This needs to be changed if they start using their own tier for super mega raids
+ '17' => 'SUPER_MEGA_5', // Pokebattler currently uses MEGA_5 for super mega raids. This needs to be changed if they start using their own tier for super mega raids
+];
+
+$pokebattler_pokemon_map = [
+ 'HO_OH' => 'HO-OH',
+ 'GIRATINA' => 'GIRATINA_ALTERED',
+ 'ZACIAN' => 'ZACIAN_HERO_FORM',
+ 'ZAMAZENTA' => 'ZAMAZENTA_HERO_FORM',
+];
+
+// Storing Primal Kyogre and Groudon for now. These are not needed if Pokebattler starts using own raid tier for primals
+define('PRIMAL_MONS', [382, 383]);
+
+// Limit the tiers of upcoming raid bosses imported from PokeBattler to legendary and mega
+$pokebattler_import_future_tiers = [5, 6, 7, 8, 9, 10, 15];
+
+define('TYPE_MAP_PROTO_TO_ID', [
+ 'POKEMON_TYPE_NORMAL' => 1,
+ 'POKEMON_TYPE_FIGHTING' => 2,
+ 'POKEMON_TYPE_FLYING' => 3,
+ 'POKEMON_TYPE_POISON' => 4,
+ 'POKEMON_TYPE_GROUND' => 5,
+ 'POKEMON_TYPE_ROCK' => 6,
+ 'POKEMON_TYPE_BUG' => 7,
+ 'POKEMON_TYPE_GHOST' => 8,
+ 'POKEMON_TYPE_STEEL' => 9,
+ 'POKEMON_TYPE_FIRE' => 10,
+ 'POKEMON_TYPE_WATER' => 11,
+ 'POKEMON_TYPE_GRASS' => 12,
+ 'POKEMON_TYPE_ELECTRIC' => 13,
+ 'POKEMON_TYPE_PSYCHIC' => 14,
+ 'POKEMON_TYPE_ICE' => 15,
+ 'POKEMON_TYPE_DRAGON' => 16,
+ 'POKEMON_TYPE_DARK' => 17,
+ 'POKEMON_TYPE_FAIRY' => 18,
+]);
+
+// Default language.
+defined('DEFAULT_LANGUAGE') or define('DEFAULT_LANGUAGE', 'EN');
+
+// Telegram language code => Language files.
+$languages = array(
+ 'nl' => 'NL',
+ 'de' => 'DE',
+ 'en' => 'EN',
+ 'it' => 'IT',
+ 'pt' => 'PT-BR',
+ 'ru' => 'RU',
+ 'fr' => 'FR',
+ 'fi' => 'FI',
+ 'es' => 'ES',
+);
// Value used for denoting anytime attendance
define('ANYTIME', '1970-01-01 00:00:00');
-define('ANYTIME_TS', preg_replace("/[^0-9]/", "", ANYTIME));
-
-// Ex-raid event ID
-defined('EVENT_ID_EX') or define('EVENT_ID_EX', '999');
+define('ANYTIME_TS', preg_replace('/[^0-9]/', '', ANYTIME));
// Icons.
defined('TEAM_B') or define('TEAM_B', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F499)));
@@ -28,6 +126,9 @@
defined('EMOJI_STAR') or define('EMOJI_STAR', iconv('UCS-4LE', 'UTF-8', pack('V', 0x2B50)));
defined('EMOJI_INVITE') or define('EMOJI_INVITE', iconv('UCS-4LE', 'UTF-8', pack('V', 0x2709)));
defined('EMOJI_INFO') or define('EMOJI_INFO', iconv('UCS-4LE', 'UTF-8', pack('V', 0x2139)));
+defined('EMOJI_DELETE') or define('EMOJI_DELETE', iconv('UCS-4LE', 'UTF-8', pack('V', 0x274C)));
+defined('EMOJI_MAP') or define('EMOJI_MAP', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F5FA)));
+defined('EMOJI_PENCIL') or define('EMOJI_PENCIL', iconv('UCS-4LE', 'UTF-8', pack('V', 0x270F)));
defined('EMOJI_EGG') or define('EMOJI_EGG', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F95A)));
defined('EMOJI_CLOCK') or define('EMOJI_CLOCK', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F551)));
defined('EMOJI_CAMERA') or define('EMOJI_CAMERA', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F4F7)));
@@ -38,6 +139,7 @@
defined('EMOJI_IN_PERSON') or define('EMOJI_IN_PERSON', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F9E1)));
defined('EMOJI_ALIEN') or define('EMOJI_ALIEN', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F47D)));
defined('EMOJI_CAN_INVITE')or define('EMOJI_CAN_INVITE', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F695)));
+defined('EMOJI_SHINY') or define('EMOJI_SHINY', iconv('UCS-4LE', 'UTF-8', pack('V', 0x2728)));
// Weather Icons.
defined('EMOJI_W_SUNNY') or define('EMOJI_W_SUNNY', iconv('UCS-4LE', 'UTF-8', pack('V', 0x2600)));
@@ -49,33 +151,35 @@
defined('EMOJI_W_SNOW') or define('EMOJI_W_SNOW', iconv('UCS-4LE', 'UTF-8', pack('V', 0x2744)));
defined('EMOJI_W_FOG') or define('EMOJI_W_FOG', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F301)));
+defined('EMOJI_WARN') or define('EMOJI_WARN', iconv('UCS-4LE', 'UTF-8', pack('V', 0x26A0)));
+defined('EMOJI_DISK') or define('EMOJI_DISK', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F4BE)));
+defined('EMOJI_NEW') or define('EMOJI_NEW', iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F195)));
+defined('EMOJI_CLIPPY') or define('EMOJI_CLIPPY',iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F4CE)));
+defined('EMOJI_DISABLED') or define('EMOJI_DISABLED',iconv('UCS-4LE', 'UTF-8', pack('V', 0x1F645)));
+
+// Carriage return.
+defined('CR') or define('CR', "\n");
+defined('CR2') or define('CR2', "\n");
+// Space.
+defined('SP') or define('SP', ' ');
+
// Weather.
$weather = array(
- '1' => EMOJI_W_SUNNY,
- '2' => EMOJI_W_CLEAR,
- '3' => EMOJI_W_RAIN,
- '4' => EMOJI_W_PARTLY_CLOUDY,
- '5' => EMOJI_W_CLOUDY,
- '6' => EMOJI_W_WINDY,
- '7' => EMOJI_W_SNOW,
- '8' => EMOJI_W_FOG
+ '1' => EMOJI_W_SUNNY,
+ '2' => EMOJI_W_CLEAR,
+ '3' => EMOJI_W_RAIN,
+ '4' => EMOJI_W_PARTLY_CLOUDY,
+ '5' => EMOJI_W_CLOUDY,
+ '6' => EMOJI_W_WINDY,
+ '7' => EMOJI_W_SNOW,
+ '8' => EMOJI_W_FOG
);
// Teams.
$teams = array(
- 'mystic' => TEAM_B,
- 'valor' => TEAM_R,
- 'instinct' => TEAM_Y,
- 'unknown' => TEAM_UNKNOWN,
- 'cancel' => TEAM_CANCEL
-);
-
-// Raid eggs.
-$eggs = array(
- '9996', // Level 6 / Mega
- '9995', // Level 5
- '9994', // Level 4
- '9993', // Level 3
- '9992', // Level 2
- '9991' // Level 1
+ 'mystic' => TEAM_B,
+ 'valor' => TEAM_R,
+ 'instinct' => TEAM_Y,
+ 'unknown' => TEAM_UNKNOWN,
+ 'cancel' => TEAM_CANCEL
);
diff --git a/core/bot/apikey.php b/core/bot/apikey.php
index 5f20335d..e2b845cd 100644
--- a/core/bot/apikey.php
+++ b/core/bot/apikey.php
@@ -2,32 +2,27 @@
/**
* Verify a GET param apikey and return a provided update Array
- * @return Array
+ * @return array
*/
function get_verified_update(){
- global $config;
+ global $config, $argv;
// Get api key from get parameters.
- if(isset($_GET['apikey'])) {
- $apiKey = $_GET['apikey'];
- // Get api key from argv.
- } elseif(!empty($argv[1])) {
- $apiKey = $argv[1];
- } else {
- debug_log('Called without apikey, returning empty content.');
- http_response_code(204); // HTTP 204: No Content
- exit();
+ if(!isset($_GET['apikey'])) {
+ debug_log('Called without apikey, returning empty content.');
+ http_response_code(204); // HTTP 204: No Content
+ exit();
}
+ $apiKey = $_GET['apikey'];
// Check if hashed api key is matching config.
- if (hash('sha512', $apiKey) == strtolower($config->APIKEY_HASH)) {
- // Set constants.
- define('API_KEY', $apiKey);
- } else {
- info_log('Incorrect apikey provided! This is most likely a misconfiguration you should fix.');
- http_response_code(403); // HTTP 403: Forbidden
- exit();
+ if (hash('sha512', $apiKey) != strtolower($config->APIKEY_HASH)) {
+ info_log('Incorrect apikey provided! This is most likely a misconfiguration you should fix.');
+ http_response_code(403); // HTTP 403: Forbidden
+ exit();
}
+ // Set constants.
+ define('API_KEY', $apiKey);
// Get content from POST data.
$update = null;
@@ -36,12 +31,6 @@ function get_verified_update(){
if($content) {
// Decode the json string.
$update = json_decode($content, true);
- } elseif(!empty($argv[2])) {
- $arg_content = addslashes($argv[2]);
- $update = json_decode($argv[2], true);
- }
-
- if ($update) {
debug_log_incoming($update, '<');
}
diff --git a/core/bot/cleanup_collect.php b/core/bot/cleanup_collect.php
index f416f5ab..68364e53 100644
--- a/core/bot/cleanup_collect.php
+++ b/core/bot/cleanup_collect.php
@@ -6,30 +6,42 @@
// Init ID.
$cleanup_id = 0;
$message = null;
-// Channel
+// Channel
if(isset($update['channel_post']['text'])) {
- $message = $update['channel_post'];
+ $message = $update['channel_post'];
// Supergroup
} else if (isset($update['message']['text']) && ($update['message']['chat']['type'] == "supergroup" || $update['message']['chat']['type'] == "group")) {
- $message = $update['message'];
+ $message = $update['message'];
}
if($message != null) {
- // Get chat_id and message_id
- $chat_id = $message['chat']['id'];
- $message_id = $message['message_id'];
- if(isset($message['reply_markup']['inline_keyboard'])) {
- $split_data = explode(':', $message['reply_markup']['inline_keyboard'][0][0]['callback_data']);
- $cleanup_id = $split_data[0];
- }else {
- // Get id from text.
- $cleanup_id = substr($message['text'],strpos($message['text'], substr(strtoupper($config->BOT_ID), 0, 1) . '-ID = ') + 7);
+ // Get chat_id and message_id
+ $chat_id = $message['chat']['id'];
+ $message_id = $message['message_id'];
+ $thread_id = $message['message_thread_id'] ?? NULL;
+ if(isset($message['reply_markup']['inline_keyboard'])) {
+ $splitData = explode('|', $message['reply_markup']['inline_keyboard'][0][0]['callback_data']);
+ // Search for raid id in the first button of the message
+ for($i=1;$i/setconfig' . SP . getTranslation('option_value') . '' . CR;
- foreach($json as $cfg_name => $cfg_value) {
- // Only allowed configs
- if(in_array($cfg_name, $allowed)) {
- // Is alias set?
- $alias = '';
- if(isset($ajson[$cfg_name])){
- $alias = $ajson[$cfg_name];
- }
- // Config name / Alias + value
- $msg .= '/set' . SP . (empty($alias) ? $cfg_name : $alias) . SP . (empty($cfg_value) ? '' . getTranslation('no_value') . '' : $cfg_value);
-
- // Only bool?
- if(in_array($cfg_name, $allowed_bool)) {
- $msg .= SP . '(' . getTranslation('help_only_bool') . ')' . CR;
-
- // Only numbers?
- } else if(in_array($cfg_name, $allowed_numbers)) {
- $msg .= SP . '(' . getTranslation('help_only_numbers') . ')' . CR;
-
- // Any type
- } else {
- $msg .= CR;
- }
- }
- }
- } else {
- $msg .= getTranslation('not_supported');
- }
- debug_log('Unsupported request for a telegram config change: ' . $input);
-}
-
-// Send message.
-send_message($update['message']['chat']['id'], $msg);
-
-?>
diff --git a/core/lang/help.json b/core/lang/help.json
deleted file mode 100644
index 55218974..00000000
--- a/core/lang/help.json
+++ /dev/null
@@ -1,80 +0,0 @@
-{
- "help_config-get": {
- "NL": "/get - laat bot configuratie zien",
- "DE": "/get - Bot-Konfiguration anzeigen",
- "EN": "/get - Show bot configuration",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "/get - Näytä botin asetukset",
- "ES": "/get - Ver configuración del bot"
- },
- "help_config-set": {
- "NL": "/set - Verander bot configuratie",
- "DE": "/set - Bot-Konfiguration bearbeiten",
- "EN": "/set - Edit bot configuration",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "/set - Muokkaa botin asetuksia",
- "ES": "/set - Editar configuración del bot"
- },
- "help_only_bool": {
- "NL": "Alleen true/false of 0/1",
- "DE": "nur true/false oder 0/1",
- "EN": "only true/false or 0/1",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "vain true/false tai 0/1",
- "ES": "solo true/false o 0/1"
- },
- "help_only_numbers": {
- "NL": "Alleen nummers",
- "DE": "nur Zahlen",
- "EN": "only numbers",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "vain numeroita",
- "ES": "solo números"
- },
- "help_bool_expected": {
- "NL": "Toegestaande waarde: true/false of 0/1",
- "DE": "Zulässige Werte: true/false oder 0/1",
- "EN": "Allowed values: true/false or 0/1",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Sallitut arvot: true/false tai 0/1",
- "ES": "Valores validos: true/false o 0/1"
- },
- "help_number_expected": {
- "NL": "Toegestaande waarde: Nummers groter dan 0",
- "DE": "Zulässiger Wert: Zahlen größer 0",
- "EN": "Allowed value: Numbers greater than 0",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Sallittu arvo: 0 suuremmat luvut",
- "ES": "Valores validos: Números mayores que 0"
- }
-}
diff --git a/core/lang/language.json b/core/lang/language.json
deleted file mode 100644
index 153b90f3..00000000
--- a/core/lang/language.json
+++ /dev/null
@@ -1,782 +0,0 @@
-{
- "lang_name": {
- "NL": "Nederlands",
- "DE": "Deutsch",
- "EN": "English",
- "IT": "Italiano",
- "PT-BR": "Português",
- "RU": "Русский",
- "NO": "Norsk",
- "FR": "Français",
- "PL": "Polski",
- "FI": "Suomi",
- "ES": "Español"
- },
- "weekday_1": {
- "NL": "Maandag",
- "DE": "Montag",
- "EN": "Monday",
- "IT": "Lunedì",
- "PT-BR": "segunda-feira",
- "RU": "Понедельник",
- "NO": "Mandag",
- "FR": "Lundi",
- "PL": "Poniedziałek",
- "FI": "Maanantai",
- "ES": "Lunes"
- },
- "weekday_2": {
- "NL": "Dinsdag",
- "DE": "Dienstag",
- "EN": "Tuesday",
- "IT": "Martedì",
- "PT-BR": "terça-feira",
- "RU": "Вторник",
- "NO": "Tirsdag",
- "FR": "Mardi",
- "PL": "Wtorek",
- "FI": "Tiistai",
- "ES": "Martes"
- },
- "weekday_3": {
- "NL": "Woensdag",
- "DE": "Mittwoch",
- "EN": "Wednesday",
- "IT": "Mercoledì",
- "PT-BR": "quarta-feira",
- "RU": "Среда",
- "NO": "Onsdag",
- "FR": "Mercredi",
- "PL": "Środa",
- "FI": "Keskiviikko",
- "ES": "Miércoles"
- },
- "weekday_4": {
- "NL": "Donderdag",
- "DE": "Donnerstag",
- "EN": "Thursday",
- "IT": "Giovedì",
- "PT-BR": "quinta-feira",
- "RU": "Четверг",
- "NO": "Torsdag",
- "FR": "Jeudi",
- "PL": "Czwartek",
- "FI": "Torstai",
- "ES": "Jueves"
- },
- "weekday_5": {
- "NL": "Vrijdag",
- "DE": "Freitag",
- "EN": "Friday",
- "IT": "Venerdì",
- "PT-BR": "sexta-feira",
- "RU": "Пятница",
- "NO": "Fredag",
- "FR": "Vendredi",
- "PL": "Piątek",
- "FI": "Perjantai",
- "ES": "Viernes"
- },
- "weekday_6": {
- "NL": "Zaterdag",
- "DE": "Samstag",
- "EN": "Saturday",
- "IT": "Sabato",
- "PT-BR": "sábado",
- "RU": "Суббота",
- "NO": "Lørdag",
- "FR": "Samedi",
- "PL": "Sobota",
- "FI": "Lauantai",
- "ES": "Sábado"
- },
- "weekday_7": {
- "NL": "Zondag",
- "DE": "Sonntag",
- "EN": "Sunday",
- "IT": "Domenica",
- "PT-BR": "domingo",
- "RU": "Воскресение",
- "NO": "Søndag",
- "FR": "Dimanche",
- "PL": "Niedziela",
- "FI": "Sunnuntai",
- "ES": "Domingo"
- },
- "month_01": {
- "NL": "Januari",
- "DE": "Januar",
- "EN": "January",
- "IT": "Gennaio",
- "PT-BR": "Janeiro",
- "RU": "Январь",
- "NO": "Januar",
- "FR": "Janvier",
- "PL": "Styczeń",
- "FI": "Tammikuu",
- "ES": "Enero"
- },
- "month_02": {
- "NL": "Februari",
- "DE": "Februar",
- "EN": "February",
- "IT": "Febbraio",
- "PT-BR": "Fevereiro",
- "RU": "Февраль",
- "NO": "Februar",
- "FR": "Février",
- "PL": "Luty",
- "FI": "Helmikuu",
- "ES": "Febrero"
- },
- "month_03": {
- "NL": "Maart",
- "DE": "März",
- "EN": "March",
- "IT": "Marzo",
- "PT-BR": "Março",
- "RU": "Март",
- "NO": "Mars",
- "FR": "Mars",
- "PL": "Marzec",
- "FI": "Maaliskuu",
- "ES": "Marzo"
- },
- "month_04": {
- "NL": "April",
- "DE": "April",
- "EN": "April",
- "IT": "Aprile",
- "PT-BR": "Abril",
- "RU": "Апрель",
- "NO": "April",
- "FR": "Avril",
- "PL": "Kwiecień",
- "FI": "Huhtikuu",
- "ES": "Abril"
- },
- "month_05": {
- "NL": "Mei",
- "DE": "Mai",
- "EN": "May",
- "IT": "Maggio",
- "PT-BR": "Maio",
- "RU": "Май",
- "NO": "Mai",
- "FR": "Mai",
- "PL": "Maj",
- "FI": "Toukokuu",
- "ES": "Mayo"
- },
- "month_06": {
- "NL": "Juni",
- "DE": "Juni",
- "EN": "June",
- "IT": "Giugno",
- "PT-BR": "Junho",
- "RU": "Июнь",
- "NO": "Juni",
- "FR": "Juin",
- "PL": "Czerwiec",
- "FI": "Kesäkuu",
- "ES": "Junio"
- },
- "month_07": {
- "NL": "Juli",
- "DE": "Juli",
- "EN": "July",
- "IT": "Luglio",
- "PT-BR": "Julho",
- "RU": "Июль",
- "NO": "Juli",
- "FR": "Juillet",
- "PL": "Lipiec",
- "FI": "Heinäkuu",
- "ES": "Julio"
- },
- "month_08": {
- "NL": "Augustus",
- "DE": "August",
- "EN": "August",
- "IT": "Agosto",
- "PT-BR": "Agosto",
- "RU": "Август",
- "NO": "August",
- "FR": "Août",
- "PL": "Sierpień",
- "FI": "Elokuu",
- "ES": "Agosto"
- },
- "month_09": {
- "NL": "September",
- "DE": "September",
- "EN": "September",
- "IT": "Settembre",
- "PT-BR": "Setembro",
- "RU": "Сентябрь",
- "NO": "September",
- "FR": "Septembre",
- "PL": "Wrzesień",
- "FI": "Syyskuu",
- "ES": "Septiembre"
- },
- "month_10": {
- "NL": "Oktober",
- "DE": "Oktober",
- "EN": "October",
- "IT": "Ottobre",
- "PT-BR": "Outubro",
- "RU": "Октябрь",
- "NO": "Oktober",
- "FR": "Octobre",
- "PL": "Październik",
- "FI": "Lokakuu",
- "ES": "Octubre"
- },
- "month_11": {
- "NL": "November",
- "DE": "November",
- "EN": "November",
- "IT": "Novembre",
- "PT-BR": "Novembro",
- "RU": "Ноябрь",
- "NO": "November",
- "FR": "Novembre",
- "PL": "Listopad",
- "FI": "Marraskuu",
- "ES": "Noviembre"
- },
- "month_12": {
- "NL": "December",
- "DE": "Dezember",
- "EN": "December",
- "IT": "Dicembre",
- "PT-BR": "Dezembro",
- "RU": "Декабрь",
- "NO": "Desember",
- "FR": "Décembre",
- "PL": "Grudzień",
- "FI": "Joulukuu",
- "ES": "Diciembre"
- },
- "bot_access_denied": {
- "NL": "Je hebt geen toegang tot deze functie of bot!",
- "DE": "Sie haben keine Berechtigung diesen Befehl oder Bot zu nutzen!",
- "EN": "You are not allowed to use this command or bot!",
- "IT": "Non hai i permessi necessari per usare questo comando o bot!",
- "PT-BR": "Você não tem permissão para utilizar esse comando ou bot!",
- "RU": "Вы не можете использовать эту команду или бота!",
- "NO": "Du har ikke tillatelse til å bruke denne kommandoen eller boten!",
- "FR": "Tu n'es pas autorisé à utiliser cette commande !",
- "PL": "Nie masz uprawnień do korzystania z tej komendy lub bota!",
- "FI": "Sinulla ei ole oikeutta tähän komentoon tai bottiin!",
- "ES": "¡No está autorizado a utilizar este comando o bot!"
- },
- "forest": {
- "NL": "Routebeschrijving",
- "DE": "Wegbeschreibung",
- "EN": "Directions",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Reittiohje",
- "ES": "Abrir mapa"
- },
- "pokemon": {
- "NL": "Pokemon",
- "DE": "Pokemon",
- "EN": "Pokemon",
- "IT": "Pokemon",
- "PT-BR": "Pokemon",
- "RU": "Pokemon",
- "NO": "Pokemon",
- "FR": "Pokemon",
- "PL": "Pokemon",
- "FI": "Pokemon",
- "ES": "Pokémon"
- },
- "pokemon_types": {
- "NL": "Pokemon Types",
- "DE": "Pokemon-Typen",
- "EN": "Pokemon Types",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Pokemon Tyypit",
- "ES": "Tipos de Pokémon"
- },
- "yes": {
- "NL": "Ja",
- "DE": "Ja",
- "EN": "Yes",
- "IT": "Sì",
- "PT-BR": "Sim",
- "RU": "Да",
- "NO": "Ja",
- "FR": "Oui",
- "PL": "Tak",
- "FI": "Kyllä",
- "ES": "Si"
- },
- "no": {
- "NL": "Nee",
- "DE": "Nein",
- "EN": "No",
- "IT": "No",
- "PT-BR": "Não",
- "RU": "Нет",
- "NO": "Nei",
- "FR": "Non",
- "PL": "Nie",
- "FI": "Ei",
- "ES": "No"
- },
- "or": {
- "NL": "of",
- "DE": "oder",
- "EN": "or",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "tai",
- "ES": "o"
- },
- "not_supported": {
- "NL": "Niet ondersteund",
- "DE": "Nicht unterstützt",
- "EN": "Not supported",
- "IT": "Non compatibile",
- "PT-BR": "Não compatível",
- "RU": "Не поддерживается",
- "NO": "Ikke støttet",
- "FR": "Non compatible",
- "PL": "Nieobsługiwane",
- "FI": "Ei tuettu",
- "ES": "No soportado"
- },
- "abort": {
- "NL": "Afbreken",
- "DE": "Abbrechen",
- "EN": "Abort",
- "IT": "Cancella",
- "PT-BR": "Abortar",
- "RU": "Прервать",
- "NO": "Avbryt",
- "FR": "Abandonner",
- "PL": "Anuluj",
- "FI": "Peruuta",
- "ES": "Cancelar"
- },
- "action_aborted": {
- "NL": "Het proces is afgebroken!",
- "DE": "Der Vorgang wurde abgebrochen!",
- "EN": "The process was aborted!",
- "IT": "Il processo è stato cancellato!",
- "PT-BR": "O processo foi abortado!",
- "RU": "Процесс был прерван!",
- "NO": "Handlingen ble avbrutt!",
- "FR": "Le processus à échoué !",
- "PL": "Zadanie zostało anulowane",
- "FI": "Prosessi peruutettiin!",
- "ES": "¡El proceso fue cancelado!"
- },
- "select_action": {
- "NL": "Selecteer actie:",
- "DE": "Aktion auswählen:",
- "EN": "Select action:",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Valitse toiminto:",
- "ES": "Selecciona la acción:"
- },
- "back": {
- "NL": "Terug",
- "DE": "Zurück",
- "EN": "Back",
- "IT": "Precedente",
- "PT-BR": "Voltar",
- "RU": "Назад",
- "NO": "Tilbake",
- "FR": "Retour",
- "PL": "Wstecz",
- "FI": "Takaisin",
- "ES": "Volver"
- },
- "next": {
- "NL": "Volgende",
- "DE": "Weiter",
- "EN": "Next",
- "IT": "Successivo",
- "PT-BR": "Próximo",
- "RU": "Вперед",
- "NO": "Neste",
- "FR": "Suivant",
- "PL": "Dalej",
- "FI": "Seuraava",
- "ES": "Siguiente"
- },
- "done": {
- "NL": "Klaar",
- "DE": "Fertig",
- "EN": "Done",
- "IT": "Completato",
- "PT-BR": "Feito",
- "RU": "Готово",
- "NO": "Ferdig",
- "FR": "Terminé",
- "PL": "Zrobione",
- "FI": "Valmis",
- "ES": "Hecho"
- },
- "add": {
- "NL": "Toevoegen",
- "DE": "Hinzufügen",
- "EN": "Add",
- "IT": "Aggiungi",
- "PT-BR": "Adicionar",
- "RU": "Добавить",
- "NO": "Legg til",
- "FR": "Ajouter",
- "PL": "Dodaj",
- "FI": "Lisää",
- "ES": "Añadir"
- },
- "replace": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Replace",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Korvaa",
- "ES": "Reemplazar"
- },
- "delete": {
- "NL": "Verwijder",
- "DE": "Löschen",
- "EN": "Delete",
- "IT": "Elimina",
- "PT-BR": "Deletar",
- "RU": "Удалить",
- "NO": "Slett",
- "FR": "Supprimer",
- "PL": "Usuń",
- "FI": "Poista",
- "ES": "Borrar"
- },
- "edit": {
- "NL": "Bewerken",
- "DE": "Bearbeiten",
- "EN": "Edit",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Muokkaa",
- "ES": "Editar"
- },
- "list": {
- "NL": "Lijst",
- "DE": "Anzeigen",
- "EN": "List",
- "IT": "Lista",
- "PT-BR": "Lista",
- "RU": "Список",
- "NO": "List",
- "FR": "Liste",
- "PL": "Pokaż",
- "FI": "Listaa",
- "ES": "Lista"
- },
- "reset": {
- "NL": "Reset",
- "DE": "Reset",
- "EN": "Reset",
- "IT": "Reset",
- "PT-BR": "Resetar",
- "RU": "Сброс",
- "NO": "Reset",
- "FR": "Remise à zéro",
- "PL": "Resetuj",
- "FI": "Resetoi",
- "ES": "Reiniciar"
- },
- "created_by": {
- "NL": "Aangemaakt door",
- "DE": "Erstellt von",
- "EN": "Created by",
- "IT": "Creato da",
- "PT-BR": "Criada por",
- "RU": "Создано",
- "NO": "Postet av",
- "FR": "Créé par",
- "PL": "Stworzone przez",
- "FI": "Luonut",
- "ES": "Creado por"
- },
- "updated": {
- "NL": "Bijgewerkt",
- "DE": "Aktualisiert",
- "EN": "Updated",
- "IT": "Aggiornato",
- "PT-BR": "Atualizada",
- "RU": "Обновлено",
- "NO": "Oppdatert",
- "FR": "Mis à jour",
- "PL": "Zaktualizowano",
- "FI": "Päivitetty",
- "ES": "Actualizado"
- },
- "share": {
- "NL": "Delen",
- "DE": "Teilen",
- "EN": "Share",
- "IT": "Condividi",
- "PT-BR": "Compartilhar",
- "RU": "Поделиться",
- "NO": "Del",
- "FR": "Partager",
- "PL": "Udostępnij",
- "FI": "Jaa",
- "ES": "Compartir"
- },
- "share_with": {
- "NL": "Delen met",
- "DE": "Teilen mit",
- "EN": "Share with",
- "IT": "Condividi con",
- "PT-BR": "Compartilhar com",
- "RU": "Поделиться с",
- "NO": "Del med",
- "FR": "Partager avec",
- "PL": "Przekaż dalej",
- "FI": "Jaa ryhmään",
- "ES": "Compartir con"
- },
- "successfully_shared": {
- "NL": "Succesvol gedeeld!",
- "DE": "Erfolgreich geteilt!",
- "EN": "Successfully shared!",
- "IT": "Condiviso con successo!",
- "PT-BR": "Compartilhado com sucesso!",
- "RU": "Успешно отправлено!",
- "NO": "Deling velykket!",
- "FR": "Partagé avec succès !",
- "PL": "Pomyślnie udostępniono",
- "FI": "Jaettu onnistuneesti!",
- "ES": "¡Compartido con éxito!"
- },
- "config": {
- "NL": "Configuratie",
- "DE": "Konfiguration",
- "EN": "Configuration",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Asetukset",
- "ES": "Configuración"
- },
- "config_updated": {
- "NL": "Configuratie ge-update",
- "DE": "Konfiguration aktualisiert",
- "EN": "Configuration updated",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Asetukset päivitetty",
- "ES": "Configuración actualizada"
- },
- "resetted": {
- "NL": "Gereset",
- "DE": "Zurückgesetzt",
- "EN": "Resetted",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Resetoitu",
- "ES": "Reiniciado"
- },
- "option_value": {
- "NL": "Configuratie optie waarde",
- "DE": "Konfigurationsoption Wert",
- "EN": "Configurationoption value",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Asetuksen arvo",
- "ES": "Valor de la opción de configuración"
- },
- "no_value": {
- "NL": "Geen waarde",
- "DE": "Kein Wert",
- "EN": "No value",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Ei arvoa",
- "ES": "Sin valor"
- },
- "new_value": {
- "NL": "Nieuwe waarde:",
- "DE": "Neuer Wert:",
- "EN": "New value:",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Uusi arvo:",
- "ES": "Nuevo valor:"
- },
- "old_value": {
- "NL": "Oude waarde:",
- "DE": "Alter Wert:",
- "EN": "Old value:",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Vanha arvo:",
- "ES": "Antiguo valor:"
- },
- "personal_help": {
- "NL": "Alle commando's voor de bot:",
- "DE": "Deine persönliche Bot-Hilfe:",
- "EN": "Your personal bot help:",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Henkilökohtainen bottiapu:",
- "ES": "Tu bot personal ayuda:"
- },
- "invalid_input": {
- "NL": "Ongeldige input!",
- "DE": "Ungültige Eingabe!",
- "EN": "Invalid input!",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Epäkelpo arvo!",
- "ES": "¡Entrada inválida!"
- },
- "internal_error": {
- "NL": "Internal error!",
- "DE": "Interner Fehler!",
- "EN": "Internal error!",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Sisäinen virhe!",
- "ES": "¡Error interno!"
- },
- "expand": {
- "NL": "Uitklappen",
- "DE": "Ausklappen",
- "EN": "Expand",
- "IT": "Espandi",
- "PT-BR": "Expandir",
- "RU": "Развернуть",
- "NO": "Flere valg",
- "FR": "Agrandir",
- "PL": "Rozwiń",
- "FI": "Laajenna",
- "ES": "Expandir"
- },
- "none": {
- "NL": "Geen",
- "DE": "Keine",
- "EN": "None",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "ei mitään",
- "ES": "Nada"
- },
- "other": {
- "NL": "Anders",
- "DE": "Sonstiges",
- "EN": "Other",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Muu",
- "ES": "Otro"
- },
- "tutorial_vote_failed": {
- "NL": "Je kan niet meedoen voordat je de tutorial hebt doorlopen.",
- "DE": "TRANSLATE",
- "EN": "You can't vote before going through the tutorial.",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Et voi äänestää ennen kuin olet käynyt ohjeen läpi.",
- "ES": "No puedes votar antes de seguir el tutorial."
- },
- "tutorial_command_failed": {
- "NL": "Je kan dit commando niet gebruiken voordat je de tutorial hebt doorlopen.",
- "DE": "TRANSLATE",
- "EN": "You can't use this command before going through the tutorial.",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Et voi käyttää tätä käskyä ennen kuin olet käynyt ohjeen läpi.",
- "ES": "No puede usar este comando antes de seguir el tutorial."
- }
-}
diff --git a/core/lang/pokemon_forms.json b/core/lang/pokemon_forms.json
deleted file mode 100644
index a44c8157..00000000
--- a/core/lang/pokemon_forms.json
+++ /dev/null
@@ -1,829 +0,0 @@
-{
- "pokemon_form_alola": {
- "NL": "Alolan",
- "DE": "Alola",
- "EN": "Alolan",
- "IT": "TRANSLATE",
- "PT-BR": "de Alola",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Alolan",
- "FI": "Alolan",
- "ES": "Alola"
- },
- "pokemon_form_galarian": {
- "NL": "Galarian",
- "DE": "Galar",
- "EN": "Galarian",
- "IT": "Galarian",
- "PT-BR": "Galarian",
- "RU": "Galarian",
- "NO": "Galarian",
- "FR": "Galarian",
- "PL": "Galarian",
- "FI": "Galarian",
- "ES": "Galar"
- },
- "pokemon_form_hisuian": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Hisuian",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Hisuian",
- "ES": "TRANSLATE"
- },
- "pokemon_form_mega": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Mega",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Mega",
- "ES": "Mega"
- },
- "pokemon_form_mega_x": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Mega X",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Mega X",
- "ES": "Mega X"
- },
- "pokemon_form_mega_y": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Mega Y",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Mega Y",
- "ES": "Mega Y"
- },
- "pokemon_form_armored": {
- "NL": "Armored",
- "DE": "Rüstungsform",
- "EN": "Armored",
- "IT": "Armatura",
- "PT-BR": "Armadura",
- "RU": "Bronya",
- "NO": "Rustning",
- "FR": "Armure",
- "ES": "Acorazado"
- },
- "pokemon_form_attack": {
- "NL": "Attack",
- "DE": "Angriffsform",
- "EN": "Attack",
- "IT": "TRANSLATE",
- "PT-BR": "Ataque",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Attack",
- "ES": "Ataque"
- },
- "pokemon_form_defense": {
- "NL": "Defense",
- "DE": "Verteidigungsform",
- "EN": "Defense",
- "IT": "TRANSLATE",
- "PT-BR": "Defesa",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Defense",
- "ES": "Defensa"
- },
- "pokemon_form_speed": {
- "NL": "Speed",
- "DE": "Initiativeform",
- "EN": "Speed",
- "IT": "TRANSLATE",
- "PT-BR": "Velocidade",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Speed",
- "ES": "Velocidad"
- },
- "pokemon_form_plant": {
- "NL": "Plant",
- "DE": "Pflanzenumhang",
- "EN": "Plant",
- "IT": "TRANSLATE",
- "PT-BR": "Planta",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Plant",
- "ES": "Planta"
- },
- "pokemon_form_sandy": {
- "NL": "Sandy",
- "DE": "Sandumhang",
- "EN": "Sandy",
- "IT": "TRANSLATE",
- "PT-BR": "Areia",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Sandy",
- "ES": "Arena"
- },
- "pokemon_form_trash": {
- "NL": "Trash",
- "DE": "Lumpenumhang",
- "EN": "Trash",
- "IT": "TRANSLATE",
- "PT-BR": "Lixo",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Trash",
- "ES": "Basura"
- },
- "pokemon_form_overcast": {
- "NL": "Overcast",
- "DE": "Wolkenform",
- "EN": "Overcast",
- "IT": "TRANSLATE",
- "PT-BR": "Negativo",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Overcast",
- "ES": "Encapotada"
- },
- "pokemon_form_sunny": {
- "NL": "Sunny",
- "DE": "Sonnenform",
- "EN": "Sunny",
- "IT": "TRANSLATE",
- "PT-BR": "Positivo",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Sunny",
- "ES": "Soleada"
- },
- "pokemon_form_rainy": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Rainy",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_snowy": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Snowy",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_east_sea": {
- "NL": "East",
- "DE": "Ostform",
- "EN": "East",
- "IT": "TRANSLATE",
- "PT-BR": "Leste",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "East",
- "ES": "Este"
- },
- "pokemon_form_west_sea": {
- "NL": "West",
- "DE": "Westform",
- "EN": "West",
- "IT": "TRANSLATE",
- "PT-BR": "Oeste",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "West",
- "ES": "Oeste"
- },
- "pokemon_form_fan": {
- "NL": "Fan",
- "DE": "Wirbel-Form",
- "EN": "Fan",
- "IT": "TRANSLATE",
- "PT-BR": "Ventilador",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Fan",
- "ES": "Ventilador"
- },
- "pokemon_form_frost": {
- "NL": "Frost",
- "DE": "Frost-Form",
- "EN": "Frost",
- "IT": "TRANSLATE",
- "PT-BR": "Congelado",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Frost",
- "ES": "Frío"
- },
- "pokemon_form_heat": {
- "NL": "Heat",
- "DE": "Hitze-Form",
- "EN": "Heat",
- "IT": "TRANSLATE",
- "PT-BR": "Calor",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Heat",
- "ES": "Calor"
- },
- "pokemon_form_mow": {
- "NL": "Mow",
- "DE": "Schneid-Form",
- "EN": "Mow",
- "IT": "TRANSLATE",
- "PT-BR": "Cortador",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Mow",
- "ES": "Corte"
- },
- "pokemon_form_wash": {
- "NL": "Wash",
- "DE": "Wasch-Form",
- "EN": "Wash",
- "IT": "TRANSLATE",
- "PT-BR": "Lavagem",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Wash",
- "ES": "Lavado"
- },
- "pokemon_form_altered": {
- "NL": "Altered",
- "DE": "Wandelform",
- "EN": "Altered",
- "IT": "TRANSLATE",
- "PT-BR": "Alterado",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Altered",
- "ES": "Modificada"
- },
- "pokemon_form_origin": {
- "NL": "Origin",
- "DE": "Urform",
- "EN": "Origin",
- "IT": "TRANSLATE",
- "PT-BR": "Original",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Origin",
- "ES": "Origen"
- },
- "pokemon_form_land": {
- "NL": "Land",
- "DE": "Landform",
- "EN": "Land",
- "IT": "TRANSLATE",
- "PT-BR": "Terrestre",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Land",
- "ES": "Tierra"
- },
- "pokemon_form_sky": {
- "NL": "Sky",
- "DE": "Zenitform",
- "EN": "Sky",
- "IT": "TRANSLATE",
- "PT-BR": "Celeste",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Sky",
- "ES": "Cielo"
- },
- "pokemon_form_bug": {
- "NL": "Bug",
- "DE": "Käfer-Form",
- "EN": "Bug",
- "IT": "TRANSLATE",
- "PT-BR": "Inseto",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Bug",
- "ES": "Bicho"
- },
- "pokemon_form_dark": {
- "NL": "Dark",
- "DE": "Unlicht-Form",
- "EN": "Dark",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Dark",
- "ES": "Siniestro"
- },
- "pokemon_form_dragon": {
- "NL": "Dragon",
- "DE": "Drache-Form",
- "EN": "Dragon",
- "IT": "TRANSLATE",
- "PT-BR": "Dragão",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Dragon",
- "ES": "Dragón"
- },
- "pokemon_form_electric": {
- "NL": "Electric",
- "DE": "Elektro-Form",
- "EN": "Electric",
- "IT": "TRANSLATE",
- "PT-BR": "Elétrico",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Electric",
- "ES": "Eléctrico"
- },
- "pokemon_form_fairy": {
- "NL": "Fairy",
- "DE": "Fee-Form",
- "EN": "Fairy",
- "IT": "TRANSLATE",
- "PT-BR": "Fada",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Fairy",
- "ES": "Hada"
- },
- "pokemon_form_flying": {
- "NL": "Flying",
- "DE": "Flug-Form",
- "EN": "Flying",
- "IT": "TRANSLATE",
- "PT-BR": "Voador",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Flying",
- "ES": "Volador"
- },
- "pokemon_form_fighting": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Fighting",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_fire": {
- "NL": "Fire",
- "DE": "Feuer-Form",
- "EN": "Fire",
- "IT": "TRANSLATE",
- "PT-BR": "Fogo",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Fire",
- "ES": "Fuego"
- },
- "pokemon_form_ghost": {
- "NL": "Ghost",
- "DE": "Geist-Form",
- "EN": "Ghost",
- "IT": "TRANSLATE",
- "PT-BR": "Fantasma",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Ghost",
- "ES": "Fantasma"
- },
- "pokemon_form_grass": {
- "NL": "Grass",
- "DE": "Pflanze-Form",
- "EN": "Grass",
- "IT": "TRANSLATE",
- "PT-BR": "Planta",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Grass",
- "ES": "Planta"
- },
- "pokemon_form_ground": {
- "NL": "Ground",
- "DE": "Boden-Form",
- "EN": "Ground",
- "IT": "TRANSLATE",
- "PT-BR": "Terra",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Ground",
- "ES": "Tierra"
- },
- "pokemon_form_ice": {
- "NL": "Ice",
- "DE": "Eis-Form",
- "EN": "Ice",
- "IT": "TRANSLATE",
- "PT-BR": "Gelo",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Ice",
- "ES": "Hielo"
- },
- "pokemon_form_poison": {
- "NL": "Poison",
- "DE": "Gift-Form",
- "EN": "Poison",
- "IT": "TRANSLATE",
- "PT-BR": "Veneno",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Poison",
- "ES": "Veneno"
- },
- "pokemon_form_psychic": {
- "NL": "Psychic",
- "DE": "Psycho-Form",
- "EN": "Psychic",
- "IT": "TRANSLATE",
- "PT-BR": "Psíquico",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Psychic",
- "ES": "Psíquico"
- },
- "pokemon_form_rock": {
- "NL": "Rock",
- "DE": "Gestein-Form",
- "EN": "Rock",
- "IT": "TRANSLATE",
- "PT-BR": "Pedra",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Rock",
- "ES": "Roca"
- },
- "pokemon_form_steel": {
- "NL": "Steel",
- "DE": "Stahl-Form",
- "EN": "Steel",
- "IT": "TRANSLATE",
- "PT-BR": "Metálico",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Steel",
- "ES": "Acero"
- },
- "pokemon_form_water": {
- "NL": "Water",
- "DE": "Wasser-Form",
- "EN": "Water",
- "IT": "TRANSLATE",
- "PT-BR": "Água",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Water",
- "ES": "Agua"
- },
- "pokemon_form_incarnate": {
- "NL": "Incarnate",
- "DE": "Inkarnationsform",
- "EN": "Incarnate",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Incarnate",
- "ES": "Avatar"
- },
- "pokemon_form_therian": {
- "NL": "Therian",
- "DE": "Tiergeistform",
- "EN": "Therian",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Therian",
- "ES": "Tótem"
- },
- "pokemon_form_ordinary": {
- "NL": "Ordinary",
- "DE": "Standardform",
- "EN": "Ordinary",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Ordinary",
- "ES": "Normal"
- },
- "pokemon_form_resolute": {
- "NL": "Resolute",
- "DE": "Resolutform",
- "EN": "Resolute",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "Resolute",
- "ES": "Brío"
- },
- "pokemon_form_burn": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Burn",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_chill": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Chill",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_douse": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Douse",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_shock": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Shock",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_black": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Black",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_white": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "White",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_hero": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Hero",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_crowned_sword": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Crowned Sword",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_crowned_shield": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Crowned Shield",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_zen": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Zen",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_galarian_zen": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Galarian Zen",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_male": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Male",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_female": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Female",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_blue_striped": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Blue Striped",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_red_striped": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Red Striped",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_autumn": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Autumn",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_spring": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Spring",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_summer": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Summer",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_winter": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
- "EN": "Winter",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "ES": "TRANSLATE"
- },
- "pokemon_form_exclamation_point": {
- "EN": "!"
- },
- "pokemon_form_question_mark": {
- "EN": "?"
- }
-}
diff --git a/core/lang/requirements.txt b/core/lang/requirements.txt
deleted file mode 100644
index b998a06a..00000000
--- a/core/lang/requirements.txt
+++ /dev/null
@@ -1 +0,0 @@
-absl-py
diff --git a/core/lang/translate.py b/core/lang/translate.py
deleted file mode 100644
index 465b3e98..00000000
--- a/core/lang/translate.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python3
-
-from absl import flags, app, logging
-import json
-
-FLAGS = flags.FLAGS
-
-flags.DEFINE_string('from_language', 'EN', 'Language to use as translation hint')
-flags.DEFINE_string('to', None, 'Language to translate into')
-flags.DEFINE_string('input', 'language.json', 'File to read base translation from.')
-flags.DEFINE_string('output', 'language.json', 'File to keep saving changes to.')
-flags.DEFINE_boolean('incremental', True, 'Update only strings missing translations.')
-flags.DEFINE_boolean('sort_keys', False, 'Whether to output sorted or not.')
-flags.mark_flag_as_required('to')
-
-
-def main(argv):
- with open(FLAGS.input, encoding='utf8') as f:
- trans = json.load(f)
-
- logging.info('Creating placeholders for missing strings for language {0}'.format(FLAGS.to))
- for key in trans.keys():
- if FLAGS.to not in trans[key]:
- trans[key][FLAGS.to] = 'TRANSLATE'
- flush(trans)
- print('Press ^D or ^C to stop. Leave a translation empty to skip.')
-
-
- if FLAGS.incremental:
- logging.info('Iterating over strings that have not been translated to language {0}'.format(FLAGS.to))
- for key in trans.keys():
- if trans[key][FLAGS.to] == 'TRANSLATE':
- translate(trans, key)
- flush(trans)
-
- else:
- logging.info('Iterating over all strings of language {0}'.format(FLAGS.to))
- for key in trans.keys():
- translate(trans, key)
- flush(trans)
-
-# Flush current changes to output file to avoid losing changes
-def flush(trans):
- logging.debug('flushing into {0}'.format(FLAGS.output))
- with open(FLAGS.output, 'w', encoding='utf8') as f:
- # We dump without ASCII ensurance to get unicode output for example for Russian
- json.dump(trans, f, indent=2, sort_keys=FLAGS.sort_keys, ensure_ascii=False)
-
-# Print from string, request to string and update it to trans
-def translate(trans, key):
- print('{0}[{1}]: {2}'.format(key, FLAGS.from_language, trans[key][FLAGS.from_language]))
- translation = input('{0}[{1}]: '.format(key, FLAGS.to))
- if translation:
- trans[key][FLAGS.to] = translation
-
-
-if __name__ == '__main__':
- app.run(main)
diff --git a/core/telegram/functions.php b/core/telegram/functions.php
index 6a10d0a0..88de4c5b 100644
--- a/core/telegram/functions.php
+++ b/core/telegram/functions.php
@@ -6,8 +6,8 @@
*/
function is_valid_target($chat_id, $message_id, $no_chat = false, $no_message = false){
if($chat_id === null && isset($message_id)) {
- debug_log("Inline message id received, skipping chat id check: {$message_id}");
- return true;
+ debug_log("Inline message id received, skipping chat id check: {$message_id}");
+ return true;
}
debug_log("Checking for validity chat_id:{$chat_id} and message_id:{$message_id}");
// First check that both are numbers, if they are required
@@ -24,60 +24,66 @@ function is_valid_target($chat_id, $message_id, $no_chat = false, $no_message =
info_log("chat_id:{$chat_id}, message_id:{$message_id}", 'ERROR: Unhandled pair of chat_id & message_id, this is a bug:');
return true;
}
-
+function create_chat_object($arr) {
+ $return = [];
+ $return['id'] = $arr[0] ?? 0;
+ $return['thread'] = $arr[1] ?? 0;
+ return $return;
+}
/**
* Send message.
- * @param int $chat_id
- * @param array $text
+ * @param array $chatObj
+ * @param string $text
* @param mixed $inline_keyboard
- * @param array $merge_args
- * @param array|false $multicurl
+ * @param array|bool $merge_args
+ * @param array|bool $multicurl
* @param int|string $identifier
* @return mixed
*/
-function send_message($chat_id, $text = [], $inline_keyboard = false, $merge_args = [], $multicurl = false, $identifier = false)
+function send_message($chatObj, $text = [], $inline_keyboard = false, $merge_args = [], $multicurl = false, $identifier = false)
{
- // Create response content array.
- $reply_content = [
- 'method' => 'sendMessage',
- 'chat_id' => $chat_id,
- 'parse_mode' => 'HTML',
- 'text' => $text
- ];
- if(!is_valid_target($chat_id, null, false, true)){
- info_log($chat_id, 'ERROR: Cannot send to invalid chat id:');
- info_log($reply_content, 'ERROR: data would have been:');
- exit();
- }
+ // Create response content array.
+ $reply_content = [
+ 'method' => 'sendMessage',
+ 'chat_id' => $chatObj['id'],
+ 'parse_mode' => 'HTML',
+ 'text' => $text
+ ];
+ if(isset($chatObj['thread'])) $reply_content['message_thread_id'] = $chatObj['thread'];
+ if(!is_valid_target($chatObj['id'], null, false, true)){
+ info_log($chatObj['id'], 'ERROR: Cannot send to invalid chat id:');
+ info_log($reply_content, 'ERROR: data would have been:');
+ exit();
+ }
- // Write to log.
- debug_log('KEYS');
- debug_log($inline_keyboard);
+ // Write to log.
+ debug_log('KEYS');
+ debug_log($inline_keyboard);
- if ($inline_keyboard != false) {
- $reply_content['reply_markup'] = ['inline_keyboard' => $inline_keyboard];
- }
+ if ($inline_keyboard != false) {
+ $reply_content['reply_markup'] = ['inline_keyboard' => $inline_keyboard];
+ }
- if (is_array($merge_args) && count($merge_args)) {
- $reply_content = array_merge_recursive($reply_content, $merge_args);
- }
+ if (is_array($merge_args) && count($merge_args)) {
+ $reply_content = array_merge_recursive($reply_content, $merge_args);
+ }
- // Encode data to json.
- $reply_json = json_encode($reply_content);
+ // Encode data to json.
+ $reply_json = json_encode($reply_content);
- // Set header to json.
- header('Content-Type: application/json');
+ // Set header to json.
+ header('Content-Type: application/json');
- // Write to log.
- debug_log($reply_json, '>');
+ // Write to log.
+ debug_log($reply_json, '>');
- // Send request to telegram api.
- return curl_request($reply_json, $multicurl, $identifier);
+ // Send request to telegram api.
+ return curl_request($reply_json, $multicurl, $identifier);
}
/**
* Send venue.
- * @param $chat_id
+ * @param $chatObj
* @param $lat
* @param $lon
* @param $title
@@ -87,102 +93,105 @@ function send_message($chat_id, $text = [], $inline_keyboard = false, $merge_arg
* @param $identifier
* @return mixed
*/
-function send_venue($chat_id, $lat, $lon, $title, $address, $inline_keyboard = false, $multicurl = false, $identifier = false)
+function send_venue($chatObj, $lat, $lon, $title, $address, $inline_keyboard = false, $multicurl = false, $identifier = false)
{
- // Create reply content array.
- $reply_content = [
- 'method' => 'sendVenue',
- 'chat_id' => $chat_id,
- 'latitude' => $lat,
- 'longitude' => $lon,
- 'title' => $title,
- 'address' => $address
- ];
- if(!is_valid_target($chat_id, null, false, true)){
- info_log($chat_id, 'ERROR: Cannot send to invalid chat id:');
- info_log($reply_content, 'ERROR: data would have been:');
- exit();
- }
+ // Create reply content array.
+ $reply_content = [
+ 'method' => 'sendVenue',
+ 'chat_id' => $chatObj['id'],
+ 'latitude' => $lat,
+ 'longitude' => $lon,
+ 'title' => $title,
+ 'address' => $address
+ ];
+ if(isset($chatObj['thread'])) $reply_content['message_thread_id'] = $chatObj['thread'];
+ if(!is_valid_target($chatObj['id'], null, false, true)){
+ info_log($chatObj['id'], 'ERROR: Cannot send to invalid chat id:');
+ info_log($reply_content, 'ERROR: data would have been:');
+ exit();
+ }
- // Write to log.
- debug_log('KEYS');
- debug_log($inline_keyboard);
+ // Write to log.
+ debug_log('KEYS');
+ debug_log($inline_keyboard);
- if (is_array($inline_keyboard)) {
- $reply_content['reply_markup'] = ['inline_keyboard' => $inline_keyboard];
- }
+ if (is_array($inline_keyboard)) {
+ $reply_content['reply_markup'] = ['inline_keyboard' => $inline_keyboard];
+ }
- // Encode data to json.
- $reply_json = json_encode($reply_content);
+ // Encode data to json.
+ $reply_json = json_encode($reply_content);
- // Set header to json.
- header('Content-Type: application/json');
+ // Set header to json.
+ header('Content-Type: application/json');
- // Write to log.
- debug_log($reply_json, '>');
+ // Write to log.
+ debug_log($reply_json, '>');
- // Send request to telegram api and return response.
- return curl_request($reply_json, $multicurl, $identifier);
+ // Send request to telegram api and return response.
+ return curl_request($reply_json, $multicurl, $identifier);
}
/**
* Echo message.
- * @param $chat_id
+ * @param $chatObj
* @param $text
*/
-function sendMessageEcho($chat_id, $text)
+function sendMessageEcho($chatObj, $text)
{
- // Create reply content array.
- $reply_content = [
- 'method' => 'sendMessage',
- 'chat_id' => $chat_id,
- 'parse_mode' => 'HTML',
- 'text' => $text
- ];
- if(!is_valid_target($chat_id, null, false, true)){
- info_log($chat_id, 'ERROR: Cannot send to invalid chat id:');
- info_log($reply_content, 'ERROR: data would have been:');
- exit();
- }
+ // Create reply content array.
+ $reply_content = [
+ 'method' => 'sendMessage',
+ 'chat_id' => $chatObj['id'],
+ 'parse_mode' => 'HTML',
+ 'text' => $text
+ ];
+ if(isset($chatObj['thread'])) $reply_content['message_thread_id'] = $chatObj['thread'];
+ if(!is_valid_target($chatObj['id'], null, false, true)){
+ info_log($chatObj['id'], 'ERROR: Cannot send to invalid chat id:');
+ info_log($reply_content, 'ERROR: data would have been:');
+ exit();
+ }
- // Encode data to json.
- $reply_json = json_encode($reply_content);
+ // Encode data to json.
+ $reply_json = json_encode($reply_content);
- // Set header to json.
- header('Content-Type: application/json');
+ // Set header to json.
+ header('Content-Type: application/json');
- // Write to log.
- debug_log($reply_json, '>');
+ // Write to log.
+ debug_log($reply_json, '>');
- // Echo json.
- echo($reply_json);
+ // Echo json.
+ echo($reply_json);
}
/**
* Answer callback query.
- * @param $query_id
- * @param $text
+ * @param int $query_id
+ * @param string $text
+ * @param bool $multicurl
*/
function answerCallbackQuery($query_id, $text, $multicurl = false)
{
- // Create response array.
- $response = [
- 'method' => 'answerCallbackQuery',
- 'callback_query_id' => $query_id,
- 'text' => $text
- ];
+ // Create response array.
+ $response = [
+ 'method' => 'answerCallbackQuery',
+ 'callback_query_id' => $query_id,
+ 'text' => $text
+ ];
- // Encode response to json format.
- $json_response = json_encode($response);
+ // Encode response to json format.
+ $json_response = json_encode($response);
- // Set header to json.
- header('Content-Type: application/json');
+ // Set header to json.
+ header('Content-Type: application/json');
- // Write to log.
- debug_log($json_response, '>');
+ // Write to log.
+ debug_log($json_response, '>');
- // Send request to telegram api.
- return curl_request($json_response, $multicurl);
+ // Send request to telegram api.
+ return curl_request($json_response, $multicurl);
}
/**
@@ -192,50 +201,50 @@ function answerCallbackQuery($query_id, $text, $multicurl = false)
*/
function answerInlineQuery($query_id, $contents)
{
- // Init empty result array.
- $results = [];
-
- // For each content.
- foreach($contents as $key => $row) {
- $text = $contents[$key]['text'];
- $title = $contents[$key]['title'];
- $desc = $contents[$key]['desc'];
- $inline_keyboard = $contents[$key]['keyboard'];
-
- // Create input message content array.
- $input_message_content = [
- 'parse_mode' => 'HTML',
- 'message_text' => $text,
- 'disable_web_page_preview' => true
- ];
-
- // Fill results array.
- $results[] = [
- 'type' => 'article',
- 'id' => $query_id . $key,
- 'title' => $title,
- 'description' => $desc,
- 'input_message_content' => $input_message_content,
- 'reply_markup' => [
- 'inline_keyboard' => $inline_keyboard
- ]
- ];
- }
+ // Init empty result array.
+ $results = [];
+
+ // For each content.
+ foreach($contents as $key => $row) {
+ $text = $contents[$key]['text'];
+ $title = $contents[$key]['title'];
+ $desc = $contents[$key]['desc'];
+ $inline_keyboard = $contents[$key]['keyboard'];
+
+ // Create input message content array.
+ $input_message_content = [
+ 'parse_mode' => 'HTML',
+ 'message_text' => $text,
+ 'disable_web_page_preview' => true
+ ];
- // Create reply content array.
- $reply_content = [
- 'method' => 'answerInlineQuery',
- 'inline_query_id' => $query_id,
- 'is_personal' => true,
- 'cache_time' => 10,
- 'results' => $results
+ // Fill results array.
+ $results[] = [
+ 'type' => 'article',
+ 'id' => $query_id . $key,
+ 'title' => $title,
+ 'description' => $desc,
+ 'input_message_content' => $input_message_content,
+ 'reply_markup' => [
+ 'inline_keyboard' => $inline_keyboard
+ ]
];
+ }
- // Encode to json
- $reply_json = json_encode($reply_content);
+ // Create reply content array.
+ $reply_content = [
+ 'method' => 'answerInlineQuery',
+ 'inline_query_id' => $query_id,
+ 'is_personal' => true,
+ 'cache_time' => 10,
+ 'results' => $results
+ ];
- // Send request to telegram api.
- return curl_request($reply_json);
+ // Encode to json
+ $reply_json = json_encode($reply_content);
+
+ // Send request to telegram api.
+ return curl_request($reply_json);
}
/**
@@ -243,17 +252,15 @@ function answerInlineQuery($query_id, $contents)
* @param $update
* @param $message
* @param $keys
- * @param bool $merge_args
+ * @param array|bool $merge_args
* @param $multicurl
*/
function edit_message($update, $message, $keys, $merge_args = false, $multicurl = false)
{
- if (isset($update['callback_query']['inline_message_id'])) {
- $json_response = editMessageText($update['callback_query']['inline_message_id'], $message, $keys, NULL, $merge_args, $multicurl);
- } else {
- $json_response = editMessageText($update['callback_query']['message']['message_id'], $message, $keys, $update['callback_query']['message']['chat']['id'], $merge_args, $multicurl);
- }
- return $json_response;
+ if (isset($update['callback_query']['inline_message_id'])) {
+ return editMessageText($update['callback_query']['inline_message_id'], $message, $keys, NULL, $merge_args, $multicurl);
+ }
+ return editMessageText($update['callback_query']['message']['message_id'], $message, $keys, $update['callback_query']['message']['chat']['id'], $merge_args, $multicurl);
}
/**
@@ -261,54 +268,54 @@ function edit_message($update, $message, $keys, $merge_args = false, $multicurl
* @param $id_val
* @param $text_val
* @param $markup_val
- * @param null $chat_id
+ * @param int|null $chat_id
* @param mixed $merge_args
* @param $multicurl
*/
function editMessageText($id_val, $text_val, $markup_val, $chat_id = NULL, $merge_args = false, $multicurl = false)
{
- // Create response array.
- $response = [
- 'method' => 'editMessageText',
- 'text' => $text_val,
- 'parse_mode' => 'HTML',
- 'reply_markup' => [
- 'inline_keyboard' => $markup_val
- ]
- ];
-
- if ($markup_val == false) {
- unset($response['reply_markup']);
- $response['remove_keyboard'] = true;
- }
+ // Create response array.
+ $response = [
+ 'method' => 'editMessageText',
+ 'text' => $text_val,
+ 'parse_mode' => 'HTML',
+ 'reply_markup' => [
+ 'inline_keyboard' => $markup_val
+ ]
+ ];
+
+ if ($markup_val == false) {
+ unset($response['reply_markup']);
+ $response['remove_keyboard'] = true;
+ }
- // Valid chat id.
- if ($chat_id != null) {
- $response['chat_id'] = $chat_id;
- $response['message_id'] = $id_val;
- } else {
- $response['inline_message_id'] = $id_val;
- }
+ // Valid chat id.
+ if ($chat_id != null) {
+ $response['chat_id'] = $chat_id;
+ $response['message_id'] = $id_val;
+ } else {
+ $response['inline_message_id'] = $id_val;
+ }
- // Write to log.
- //debug_log($merge_args, 'K');
- //debug_log($response, 'K');
+ // Write to log.
+ //debug_log($merge_args, 'K');
+ //debug_log($response, 'K');
- if (is_array($merge_args) && count($merge_args)) {
- $response = array_merge_recursive($response, $merge_args);
- }
+ if (is_array($merge_args) && count($merge_args)) {
+ $response = array_merge_recursive($response, $merge_args);
+ }
- if(!is_valid_target($chat_id, $id_val, true, false)){
- info_log("{$chat_id}/{$id_val}", 'ERROR: Cannot edit invalid chat/message id:');
- info_log($response, 'ERROR: data would have been:');
- exit();
- }
- debug_log($response, '<-');
+ if(!is_valid_target($chat_id, $id_val, true, false)){
+ info_log("{$chat_id}/{$id_val}", 'ERROR: Cannot edit invalid chat/message id:');
+ info_log($response, 'ERROR: data would have been:');
+ exit();
+ }
+ debug_log($response, '<-');
- // Encode response to json format.
- $json_response = json_encode($response);
- // Send request to telegram api.
- return curl_request($json_response, $multicurl);
+ // Encode response to json format.
+ $json_response = json_encode($response);
+ // Send request to telegram api.
+ return curl_request($json_response, $multicurl);
}
/**
@@ -321,12 +328,12 @@ function editMessageText($id_val, $text_val, $markup_val, $chat_id = NULL, $merg
*/
function edit_caption($update, $message, $keys, $merge_args = false, $multicurl = false)
{
- if (isset($update['callback_query']['inline_message_id'])) {
- $json_response = editMessageCaption($update['callback_query']['inline_message_id'], $message, $keys, NULL, $merge_args, $multicurl);
- } else {
- $json_response = editMessageCaption($update['callback_query']['message']['message_id'], $message, $keys, $update['callback_query']['message']['chat']['id'], $merge_args, $multicurl);
- }
- return $json_response;
+ if (isset($update['callback_query']['inline_message_id'])) {
+ $json_response = editMessageCaption($update['callback_query']['inline_message_id'], $message, $keys, NULL, $merge_args, $multicurl);
+ } else {
+ $json_response = editMessageCaption($update['callback_query']['message']['message_id'], $message, $keys, $update['callback_query']['message']['chat']['id'], $merge_args, $multicurl);
+ }
+ return $json_response;
}
/**
@@ -334,51 +341,51 @@ function edit_caption($update, $message, $keys, $merge_args = false, $multicurl
* @param $id_val
* @param $text_val
* @param $markup_val
- * @param null $chat_id
+ * @param int|null $chat_id
* @param mixed $merge_args
* @param $multicurl
*/
function editMessageCaption($id_val, $text_val, $markup_val, $chat_id = NULL, $merge_args = false, $multicurl = false)
{
- // Create response array.
- $response = [
- 'method' => 'editMessageCaption',
- 'caption' => $text_val,
- 'parse_mode' => 'HTML',
- 'reply_markup' => [
- 'inline_keyboard' => $markup_val
- ]
- ];
-
- if ($markup_val == false) {
- unset($response['reply_markup']);
- $response['remove_keyboard'] = true;
- }
+ // Create response array.
+ $response = [
+ 'method' => 'editMessageCaption',
+ 'caption' => $text_val,
+ 'parse_mode' => 'HTML',
+ 'reply_markup' => [
+ 'inline_keyboard' => $markup_val
+ ]
+ ];
+
+ if ($markup_val == false) {
+ unset($response['reply_markup']);
+ $response['remove_keyboard'] = true;
+ }
- // Valid chat id.
- if ($chat_id != null) {
- $response['chat_id'] = $chat_id;
- $response['message_id'] = $id_val;
- } else {
- $response['inline_message_id'] = $id_val;
- }
+ // Valid chat id.
+ if ($chat_id != null) {
+ $response['chat_id'] = $chat_id;
+ $response['message_id'] = $id_val;
+ } else {
+ $response['inline_message_id'] = $id_val;
+ }
- if (is_array($merge_args) && count($merge_args)) {
- $response = array_merge_recursive($response, $merge_args);
- }
+ if (is_array($merge_args) && count($merge_args)) {
+ $response = array_merge_recursive($response, $merge_args);
+ }
- if(!is_valid_target($chat_id, $id_val, true, false)){
- info_log("{$chat_id}/{$id_val}", 'ERROR: Cannot edit invalid chat/message id:');
- info_log($response, 'ERROR: data would have been:');
- exit();
- }
- debug_log($response, '<-');
+ if(!is_valid_target($chat_id, $id_val, true, false)){
+ info_log("{$chat_id}/{$id_val}", 'ERROR: Cannot edit invalid chat/message id:');
+ info_log($response, 'ERROR: data would have been:');
+ exit();
+ }
+ debug_log($response, '<-');
- // Encode response to json format.
- $json_response = json_encode($response);
+ // Encode response to json format.
+ $json_response = json_encode($response);
- // Send request to telegram api.
- return curl_request($json_response, $multicurl);
+ // Send request to telegram api.
+ return curl_request($json_response, $multicurl);
}
/**
@@ -390,33 +397,33 @@ function editMessageCaption($id_val, $text_val, $markup_val, $chat_id = NULL, $m
*/
function editMessageReplyMarkup($id_val, $markup_val, $chat_id, $multicurl = false)
{
- // Create response array.
- $response = [
- 'method' => 'editMessageReplyMarkup',
- 'reply_markup' => [
- 'inline_keyboard' => $markup_val
- ]
- ];
-
- // Valid chat id.
- if ($chat_id != null) {
- $response['chat_id'] = $chat_id;
- $response['message_id'] = $id_val;
-
- } else {
- $response['inline_message_id'] = $id_val;
- }
- if(!is_valid_target($chat_id, $id_val)){
- info_log("{$chat_id}/{$id_val}", 'ERROR: Cannot edit invalid chat/message id:');
- info_log($response, 'ERROR: data would have been:');
- exit();
- }
- debug_log($response, '->');
+ // Create response array.
+ $response = [
+ 'method' => 'editMessageReplyMarkup',
+ 'reply_markup' => [
+ 'inline_keyboard' => $markup_val
+ ]
+ ];
+
+ // Valid chat id.
+ if ($chat_id != null) {
+ $response['chat_id'] = $chat_id;
+ $response['message_id'] = $id_val;
+
+ } else {
+ $response['inline_message_id'] = $id_val;
+ }
+ if(!is_valid_target($chat_id, $id_val)){
+ info_log("{$chat_id}/{$id_val}", 'ERROR: Cannot edit invalid chat/message id:');
+ info_log($response, 'ERROR: data would have been:');
+ exit();
+ }
+ debug_log($response, '->');
// Encode response to json format.
- $json_response = json_encode($response);
+ $json_response = json_encode($response);
- // Send request to telegram api.
- return curl_request($json_response, $multicurl);
+ // Send request to telegram api.
+ return curl_request($json_response, $multicurl);
}
/**
@@ -428,36 +435,36 @@ function editMessageReplyMarkup($id_val, $markup_val, $chat_id, $multicurl = fal
*/
function edit_message_keyboard($id_val, $markup_val, $chat_id, $multicurl = false)
{
- // Create response array.
- $response = [
- 'method' => 'editMessageReplyMarkup',
- 'reply_markup' => [
- 'inline_keyboard' => $markup_val
- ]
- ];
-
- // Valid chat id.
- if ($chat_id != null) {
- $response['chat_id'] = $chat_id;
- $response['message_id'] = $id_val;
-
- } else {
- $response['inline_message_id'] = $id_val;
- }
- if(!is_valid_target($chat_id, $id_val)){
- info_log("{$chat_id}/{$id_val}", 'ERROR: Cannot edit invalid chat/message id:');
- info_log($response, 'ERROR: data would have been:');
- exit();
- }
+ // Create response array.
+ $response = [
+ 'method' => 'editMessageReplyMarkup',
+ 'reply_markup' => [
+ 'inline_keyboard' => $markup_val
+ ]
+ ];
+
+ // Valid chat id.
+ if ($chat_id != null) {
+ $response['chat_id'] = $chat_id;
+ $response['message_id'] = $id_val;
+
+ } else {
+ $response['inline_message_id'] = $id_val;
+ }
+ if(!is_valid_target($chat_id, $id_val)){
+ info_log("{$chat_id}/{$id_val}", 'ERROR: Cannot edit invalid chat/message id:');
+ info_log($response, 'ERROR: data would have been:');
+ exit();
+ }
- // Encode response to json format.
- $json_response = json_encode($response);
+ // Encode response to json format.
+ $json_response = json_encode($response);
- // Write to log.
- debug_log($response, '->');
+ // Write to log.
+ debug_log($response, '->');
- // Send request to telegram api.
- return curl_request($json_response, $multicurl);
+ // Send request to telegram api.
+ return curl_request($json_response, $multicurl);
}
/**
@@ -468,29 +475,29 @@ function edit_message_keyboard($id_val, $markup_val, $chat_id, $multicurl = fals
*/
function delete_message($chat_id, $message_id, $multicurl = false)
{
- // Create response content array.
- $reply_content = [
- 'method' => 'deleteMessage',
- 'chat_id' => $chat_id,
- 'message_id' => $message_id,
- ];
- if(!is_valid_target($chat_id, $message_id)){
- info_log("{$chat_id}/{$message_id}", 'ERROR: Cannot delete invalid chat/message id:');
- info_log($reply_content, 'ERROR: data would have been:');
- exit();
- }
+ // Create response content array.
+ $reply_content = [
+ 'method' => 'deleteMessage',
+ 'chat_id' => $chat_id,
+ 'message_id' => $message_id,
+ ];
+ if(!is_valid_target($chat_id, $message_id)){
+ info_log("{$chat_id}/{$message_id}", 'ERROR: Cannot delete invalid chat/message id:');
+ info_log($reply_content, 'ERROR: data would have been:');
+ exit();
+ }
- // Encode data to json.
- $reply_json = json_encode($reply_content);
+ // Encode data to json.
+ $reply_json = json_encode($reply_content);
- // Set header to json.
- header('Content-Type: application/json');
+ // Set header to json.
+ header('Content-Type: application/json');
- // Write to log.
- debug_log($reply_json, '>');
+ // Write to log.
+ debug_log($reply_json, '>');
- // Send request to telegram api.
- return curl_request($reply_json, $multicurl);
+ // Send request to telegram api.
+ return curl_request($reply_json, $multicurl);
}
/**
@@ -500,28 +507,28 @@ function delete_message($chat_id, $message_id, $multicurl = false)
*/
function get_chat($chat_id, $multicurl = false)
{
- // Create response content array.
- $reply_content = [
- 'method' => 'getChat',
- 'chat_id' => $chat_id,
- ];
- if(!is_valid_target($chat_id, null, false, true)){
- info_log($chat_id, 'ERROR: Cannot get invalid chat id:');
- info_log($reply_content, 'ERROR: data would have been:');
- exit();
- }
+ // Create response content array.
+ $reply_content = [
+ 'method' => 'getChat',
+ 'chat_id' => $chat_id,
+ ];
+ if(!is_valid_target($chat_id, null, false, true)){
+ info_log($chat_id, 'ERROR: Cannot get invalid chat id:');
+ info_log($reply_content, 'ERROR: data would have been:');
+ exit();
+ }
- // Encode data to json.
- $reply_json = json_encode($reply_content);
+ // Encode data to json.
+ $reply_json = json_encode($reply_content);
- // Set header to json.
- header('Content-Type: application/json');
+ // Set header to json.
+ header('Content-Type: application/json');
- // Write to log.
- debug_log($reply_json, '>');
+ // Write to log.
+ debug_log($reply_json, '>');
- // Send request to telegram api.
- return curl_request($reply_json, $multicurl);
+ // Send request to telegram api.
+ return curl_request($reply_json, $multicurl);
}
/**
@@ -531,28 +538,28 @@ function get_chat($chat_id, $multicurl = false)
*/
function get_admins($chat_id, $multicurl = false)
{
- // Create response content array.
- $reply_content = [
- 'method' => 'getChatAdministrators',
- 'chat_id' => $chat_id,
- ];
- if(!is_valid_target($chat_id, null, false, true)){
- info_log($chat_id, 'ERROR: Cannot get invalid chat id:');
- info_log($reply_content, 'ERROR: data would have been:');
- exit();
- }
+ // Create response content array.
+ $reply_content = [
+ 'method' => 'getChatAdministrators',
+ 'chat_id' => $chat_id,
+ ];
+ if(!is_valid_target($chat_id, null, false, true)){
+ info_log($chat_id, 'ERROR: Cannot get invalid chat id:');
+ info_log($reply_content, 'ERROR: data would have been:');
+ exit();
+ }
- // Encode data to json.
- $reply_json = json_encode($reply_content);
+ // Encode data to json.
+ $reply_json = json_encode($reply_content);
- // Set header to json.
- header('Content-Type: application/json');
+ // Set header to json.
+ header('Content-Type: application/json');
- // Write to log.
- debug_log($reply_json, '>');
+ // Write to log.
+ debug_log($reply_json, '>');
- // Send request to telegram api.
- return curl_request($reply_json, $multicurl);
+ // Send request to telegram api.
+ return curl_request($reply_json, $multicurl);
}
/**
@@ -563,201 +570,207 @@ function get_admins($chat_id, $multicurl = false)
*/
function get_chatmember($chat_id, $user_id, $multicurl = false)
{
- // Create response content array.
- $reply_content = [
- 'method' => 'getChatMember',
- 'chat_id' => $chat_id,
- 'user_id' => $user_id,
- ];
- if(!is_valid_target($chat_id, null, false, true)){
- info_log($chat_id, 'ERROR: Cannot get invalid chat id:');
- info_log($reply_content, 'ERROR: data would have been:');
- exit();
- }
+ // Create response content array.
+ $reply_content = [
+ 'method' => 'getChatMember',
+ 'chat_id' => $chat_id,
+ 'user_id' => $user_id,
+ ];
+ if(!is_valid_target($chat_id, null, false, true)){
+ info_log($chat_id, 'ERROR: Cannot get invalid chat id:');
+ info_log($reply_content, 'ERROR: data would have been:');
+ exit();
+ }
- // Encode data to json.
- $reply_json = json_encode($reply_content);
+ // Encode data to json.
+ $reply_json = json_encode($reply_content);
- // Set header to json.
- header('Content-Type: application/json');
+ // Set header to json.
+ header('Content-Type: application/json');
- // Write to log.
- debug_log($reply_json, '>');
+ // Write to log.
+ debug_log($reply_json, '>');
- // Send request to telegram api.
- return curl_request($reply_json, $multicurl);
+ // Send request to telegram api.
+ return curl_request($reply_json, $multicurl);
}
/**
* Send photo.
- * @param $chat_id
- * @param $photo_url
- * @param array $text
- * @param mixed $inline_keyboard
+ * @param $chatObj
+ * @param string $media_content content of the media file.
+ * @param bool $content_type true = photo file, false = file_id
+ * @param string|bool $text
+ * @param array|bool $inline_keyboard
* @param array $merge_args
- * @param array $multicurl
- * @param int $identifier
+ * @param array|bool $multicurl
+ * @param int|bool $identifier
*/
-function send_photo($chat_id, $photo_url, $text = array(), $inline_keyboard = false, $merge_args = [], $multicurl = false, $identifier = false)
+function send_photo($chatObj, $media_content, $content_type, $text = '', $inline_keyboard = false, $merge_args = [], $multicurl = false, $identifier = false)
{
- // Create response content array.
- $reply_content = [
- 'method' => 'sendPhoto',
- 'chat_id' => $chat_id,
- 'photo' => $photo_url,
- 'parse_mode' => 'HTML',
- 'caption' => $text
- ];
- if(!is_valid_target($chat_id, null, false, true)){
- info_log($chat_id, 'ERROR: Cannot send to invalid chat id:');
- info_log($reply_content, 'ERROR: data would have been:');
- exit();
- }
+ // Create response content array.
+ $post_contents = [
+ 'method' => 'sendPhoto',
+ 'chat_id' => $chatObj['id'],
+ 'reply_markup' => json_encode(['inline_keyboard' => $inline_keyboard]),
+ ];
+ if($text != '') {
+ $post_contents['caption'] = $text;
+ $post_contents['parse_mode'] = 'HTML';
+ }
+ if(isset($chatObj['thread'])) $post_contents['message_thread_id'] = $chatObj['thread'];
+ if(!is_valid_target($chatObj['id'], null, false, true)){
+ info_log($chatObj['id'], 'ERROR: Cannot send to invalid chat id:');
+ info_log(print_r($post_contents, true), 'ERROR: data would have been:');
+ exit();
+ }
- debug_log($inline_keyboard, 'KEYS:');
+ $post_contents['photo'] = ($content_type) ? new CURLStringFile($media_content, 'photo') : $media_content;
- if (isset($inline_keyboard)) {
- $reply_content['reply_markup'] = ['inline_keyboard' => $inline_keyboard];
- }
-
- if (is_array($merge_args) && count($merge_args)) {
- $reply_content = array_merge_recursive($reply_content, $merge_args);
- }
+ debug_log($inline_keyboard, 'KEYS:');
- // Encode data to json.
- $reply_json = json_encode($reply_content);
- header('Content-Type: application/json');
+ if (is_array($merge_args) && count($merge_args)) {
+ $post_contents = array_merge_recursive($post_contents, $merge_args);
+ }
- debug_log($reply_json, '>');
+ // Don't log the binary portion
+ $log_contents = array_merge(array(), $post_contents);
+ $log_contents['photo'] = '[binary data]';
+ debug_log(print_r($log_contents, true), '>');
- // Send request to telegram api.
- return curl_request($reply_json, $multicurl, $identifier);
+ // Send request to telegram api.
+ return curl_request($post_contents, $multicurl, $identifier);
}
/**
* Edit message media and text.
* @param $id_val
* @param $text_val
- * @param $url
+ * @param string $media_content content of the media file.
+ * @param bool $content_type true = photo file, false = file_id/url
* @param $markup_val
- * @param null $chat_id
+ * @param int|null $chat_id
* @param mixed $merge_args
* @param $multicurl
*/
-function editMessageMedia($id_val, $text_val, $url, $markup_val, $chat_id = NULL, $merge_args = false, $multicurl = false)
+function editMessageMedia($id_val, $text_val, $media_content, $content_type, $inline_keyboard = false, $chat_id = NULL, $merge_args = false, $multicurl = false, $identifier = false)
{
- // Create response array.
- $response = [
- 'method' => 'editMessageMedia',
- 'media' => [
- 'type' => 'photo',
- 'media' => $url,
- 'caption' => $text_val,
- 'parse_mode'=> 'HTML'
- ],
- 'reply_markup' => [
- 'inline_keyboard' => $markup_val
- ]
- ];
-
- if ($markup_val == false) {
- unset($response['reply_markup']);
- $response['remove_keyboard'] = true;
- }
- if ($chat_id != null) {
- $response['chat_id'] = $chat_id;
- $response['message_id'] = $id_val;
- } else {
- $response['inline_message_id'] = $id_val;
- }
- if (is_array($merge_args) && count($merge_args)) {
- $response = array_merge_recursive($response, $merge_args);
- }
- if(!is_valid_target($chat_id, $id_val, true, false)){
- info_log("{$chat_id}/{$id_val}", 'ERROR: Cannot edit media of invalid chat/message id:');
- info_log($response, 'ERROR: data would have been:');
- exit();
- }
+ // Create response array.
+ $post_contents = [
+ 'method' => 'editMessageMedia',
+ 'media' => [
+ 'type' => 'photo',
+ 'caption' => $text_val,
+ 'parse_mode'=> 'HTML'
+ ]
+ ];
+
+ if ($inline_keyboard !== false) {
+ $post_contents['reply_markup'] = json_encode(['inline_keyboard' => $inline_keyboard]);
+ }else {
+ $post_contents['remove_keyboard'] = true;
+ }
+ if ($chat_id != null) {
+ $post_contents['chat_id'] = $chat_id;
+ $post_contents['message_id'] = $id_val;
+ } else {
+ $post_contents['inline_message_id'] = $id_val;
+ }
+ if (is_array($merge_args) && count($merge_args)) {
+ $post_contents = array_merge_recursive($post_contents, $merge_args);
+ }
+ if(!is_valid_target($chat_id, $id_val, true, false)){
+ info_log("{$chat_id}/{$id_val}", 'ERROR: Cannot edit media of invalid chat/message id:');
+ info_log(print_r($post_contents, true), 'ERROR: data would have been:');
+ exit();
+ }
- // Encode response to json format.
- $json_response = json_encode($response);
- debug_log($response, '<-');
+ // Encode response to json format.
+ if($content_type) {
+ $post_contents['photo'] = new CURLStringFile($media_content, 'photo');
+ $post_contents['media']['media'] = 'attach://photo';
+ } else {
+ $post_contents['media']['media'] = $media_content;
+ }
+ $post_contents['media'] = json_encode($post_contents['media']);
+ debug_log("Editing message ".$post_contents['message_id']." media: ".$post_contents['media'], '->');
- // Send request to telegram api.
- return curl_request($json_response, $multicurl);
+ // Send request to telegram api.
+ return curl_request($post_contents, $multicurl, $identifier);
}
/**
* Send request to telegram api - single or multi?.
- * @param $json
+ * @param $post_contents
* @param $multicurl
* @param $identifier
* @return mixed
*/
-function curl_request($json, $multicurl = false, $identifier = false)
+function curl_request($post_contents, $multicurl = false, $identifier = false)
{
- // Send request to telegram api.
- if($multicurl == true) {
- return ['json' => $json, 'identifier' => $identifier];
- } else {
- return curl_json_request($json, $identifier);
- }
+ // Send request to telegram api.
+ if($multicurl == true) {
+ return ['post_contents' => $post_contents, 'identifier' => $identifier];
+ } else {
+ return curl_json_request($post_contents, $identifier);
+ }
}
/**
* Send request to telegram api.
- * @param $json
+ * @param $post_contents
* @param $identifier
* @return mixed
*/
-function curl_json_request($json, $identifier)
+function curl_json_request($post_contents, $identifier)
{
- global $config;
- // Bridge mode?
- if($config->BRIDGE_MODE) {
- // Add bot folder name to callback data
- debug_log('Adding bot folder name "' . basename(ROOT_PATH) . '" to callback data');
- $search = '"callback_data":"';
- $replace = $search . basename(ROOT_PATH) . ':';
- $json = str_replace($search,$replace,$json);
- }
+ global $config;
+
+ // Telegram
+ $URL = 'https://api.telegram.org/bot' . API_KEY . '/';
+ $curl = curl_init($URL);
+
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+ if(!is_array($post_contents)) curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
+ curl_setopt($curl, CURLOPT_POST, true);
+ curl_setopt($curl, CURLOPT_POSTFIELDS, $post_contents);
+ curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
+ curl_setopt($curl, CURLOPT_TIMEOUT, 10);
+
+ // Use Proxyserver for curl if configured
+ if ($config->CURL_USEPROXY && !empty($config->CURL_PROXYSERVER)) {
+ curl_setopt($curl, CURLOPT_PROXY, $config->CURL_PROXYSERVER);
+ }
+ // Use only ipv4 if configured
+ if($config->CURL_IPRESOLVE_V4) {
+ curl_setopt($curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ }
- // Telegram
- $URL = 'https://api.telegram.org/bot' . API_KEY . '/';
- $curl = curl_init($URL);
-
- curl_setopt($curl, CURLOPT_HEADER, false);
- curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curl, CURLOPT_HTTPHEADER, array("Content-type: application/json"));
- curl_setopt($curl, CURLOPT_POST, true);
- curl_setopt($curl, CURLOPT_POSTFIELDS, $json);
- curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 5);
- curl_setopt($curl, CURLOPT_TIMEOUT, 10);
-
- // Use Proxyserver for curl if configured
- if ($config->CURL_USEPROXY && !empty($config->CURL_PROXYSERVER)) {
- curl_setopt($curl, CURLOPT_PROXY, $config->CURL_PROXYSERVER);
- }
+ // Write to log.
+ if(is_array($post_contents)) debug_log(print_r($post_contents,true), '->');
+ else debug_log($post_contents, '->');
- // Write to log.
- debug_log($json, '->');
+ // Execute curl request.
+ $json_response = curl_exec($curl);
- // Execute curl request.
- $json_response = curl_exec($curl);
+ if($json_response === false) {
+ info_log(curl_error($curl));
+ curl_close($curl);
+ return false;
+ }
- if($json_response === false) {
- info_log(curl_error($curl));
- }
+ // Close connection.
+ curl_close($curl);
- // Close connection.
- curl_close($curl);
+ // Process response from telegram api.
+ responseHandler($json_response, $post_contents);
- // Process response from telegram api.
- $response = curl_json_response($json_response, $json, $identifier);
+ $responseArray = json_decode($json_response, true);
+ collectCleanup($responseArray, $post_contents, $identifier);
- // Return response.
- return $response;
+ // Return response.
+ return $responseArray;
}
/**
@@ -767,81 +780,191 @@ function curl_json_request($json, $identifier)
*/
function curl_json_multi_request($json)
{
- global $config;
- // Set URL.
- $URL = 'https://api.telegram.org/bot' . API_KEY . '/';
-
- // Curl handles.
- $curly = array();
-
- // Curl response.
- $response = array();
-
- // Init multi handle.
- $mh = curl_multi_init();
-
- // Loop through json array, create curl handles and add them to the multi-handle.
- foreach ($json as $id => $data) {
- // Init.
- $curly[$id] = curl_init();
-
- // Curl options.
- curl_setopt($curly[$id], CURLOPT_URL, $URL);
- curl_setopt($curly[$id], CURLOPT_HEADER, false);
- curl_setopt($curly[$id], CURLOPT_HTTPHEADER, array("Content-type: application/json"));
- curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, true);
- curl_setopt($curly[$id], CURLOPT_CONNECTTIMEOUT, 5);
- curl_setopt($curly[$id], CURLOPT_TIMEOUT, 10);
-
- // Use Proxyserver for curl if configured.
- if($config->CURL_USEPROXY && !empty($config->CURL_PROXYSERVER)) {
- curl_setopt($curly[$id], CURLOPT_PROXY, $config->CURL_PROXYSERVER);
- }
-
- // Bridge mode?
- if($config->BRIDGE_MODE) {
- // Add bot folder name to callback data
- debug_log('Adding bot folder name "' . basename(ROOT_PATH) . '" to callback data');
- $search = '"callback_data":"';
- $replace = $search . basename(ROOT_PATH) . ':';
- array_push($data['json'], str_replace($search,$replace,$data['json']));
- }
-
- // Curl post.
- curl_setopt($curly[$id], CURLOPT_POST, true);
- curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $data['json']);
-
- // Add multi handle.
- curl_multi_add_handle($mh, $curly[$id]);
-
- // Write to log.
- debug_log($data['json'], '->');
+ global $config;
+ // Set URL.
+ $URL = 'https://api.telegram.org/bot' . API_KEY . '/';
+
+ // Curl handles.
+ $curly = array();
+
+ // Curl response.
+ $response = array();
+
+ // Init multi handle.
+ $mh = curl_multi_init();
+
+ // Loop through json array, create curl handles and add them to the multi-handle.
+ foreach ($json as $id => $data) {
+ // Init.
+ $curly[$id] = curl_init();
+
+ // Curl options.
+ curl_setopt($curly[$id], CURLOPT_URL, $URL);
+ curl_setopt($curly[$id], CURLOPT_HEADER, false);
+ if(!is_array($data['post_contents'])) curl_setopt($curly[$id], CURLOPT_HTTPHEADER, array("Content-type: application/json"));
+ curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, true);
+ curl_setopt($curly[$id], CURLOPT_CONNECTTIMEOUT, 5);
+ curl_setopt($curly[$id], CURLOPT_TIMEOUT, 10);
+
+ // Use Proxyserver for curl if configured.
+ if($config->CURL_USEPROXY && !empty($config->CURL_PROXYSERVER)) {
+ curl_setopt($curly[$id], CURLOPT_PROXY, $config->CURL_PROXYSERVER);
+ }
+ // Use only ipv4 if configured
+ if($config->CURL_IPRESOLVE_V4) {
+ curl_setopt($curly[$id], CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
+ }
+
+ // Curl post.
+ curl_setopt($curly[$id], CURLOPT_POST, true);
+ curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $data['post_contents']);
+
+ // Add multi handle.
+ curl_multi_add_handle($mh, $curly[$id]);
+
+ // Don't log the binary data of a photo
+ $content = $data['post_contents'];
+ $log_content = $content;
+ if(is_array($content)) {
+ if(isset($content['photo']) && is_object($content['photo']) or isBinary($content['photo']) ) {
+ $log_content = array_merge([],$content);
+ $log_content['photo'] = '[binary content]';
+ }
+ } else {
+ if(isBinary($content)) {
+ $log_content = '[binary content]';
+ }
+ }
+ if(is_array($log_content)) debug_log(print_r($log_content, true), '->');
+ else debug_log($log_content, '->');
+ }
+
+ // Get content and remove handles.
+ $retry = false;
+ $maxRetries = 3;
+ $retryCount = 0;
+ $sleep = 0;
+ do {
+ // On the second pass and onwards sleep before executing curls
+ if($retry === true) {
+ $retry = false;
+ $sleep = 0;
+ $retryCount++;
+ debug_log('Retrying in '.$sleep.' seconds');
+ sleep($sleep);
+ debug_log('Retry count: '.($retryCount).'...');
}
// Execute the handles.
$running = null;
do {
- curl_multi_select($mh);
- $status = curl_multi_exec($mh, $running);
+ $status = curl_multi_exec($mh, $running);
+ curl_multi_select($mh);
} while($running > 0 && $status === CURLM_OK);
if ($status != CURLM_OK) {
- info_log(curl_multi_strerror($status));
+ info_log(curl_multi_strerror($status));
}
- // Get content and remove handles.
foreach($curly as $id => $content) {
- $response[$id] = curl_multi_getcontent($content);
- curl_multi_remove_handle($mh, $content);
- }
+ $response[$id] = curl_multi_getcontent($content);
+ curl_multi_remove_handle($mh, $content);
+ $responseResults = responseHandler($response[$id], $json[$id]['post_contents']);
+ // Handle errors
+ if(is_array($responseResults) && $responseResults[0] === 'retry') {
+ $retry = true;
+ // Use the highest sleep value returned by TG
+ $sleep = $responseResults[1] > $sleep ? $responseResults[1] : $sleep;
+ // Re-add this handle with the same info
+ curl_multi_add_handle($mh, $curly[$id]);
+ continue;
+ }
+
+ unset($curly[$id]);
+ }
+ }while($retry === true && $retryCount < $maxRetries);
+
+ $responseArrays = [];
+ // Process response from telegram api.
+ foreach($response as $id => $json_response) {
+ $responseArrays[$id] = json_decode($response[$id], true);
+ collectCleanup($responseArrays[$id], $json[$id]['post_contents'], $json[$id]['identifier']);
+ }
- // Process response from telegram api.
- foreach($response as $id => $json_response) {
- $response[$id] = curl_json_response($response[$id], $json[$id]['json'], $json[$id]['identifier']);
- debug_log_incoming($json_response, '<-');
- }
+ // Return response.
+ return $responseArrays;
+}
+if($metrics) {
+ $tg_response_code = $metrics->registerCounter($namespace, 'tg_response_count', 'Counters of response codes from Telegram', ['code', 'method', 'description']);
+}
- // Return response.
- return $response;
+/**
+ * Determine whether the given value is a binary string by checking to see if it has detectable character encoding.
+ * Non-strings are treated as binary.
+ *
+ * @param string $value
+ *
+ * @return bool
+ */
+function isBinary($value): bool
+{
+ if(is_string($value)){
+ return false === mb_detect_encoding((string)$value, null, true);
+ }
+ return true;
}
+/**
+ * Process response from Telegram.
+ * @param $jsonResponse string JSON string returned by Telegram
+ * @param $request string|array The request we sent to Telegram
+ * @return mixed
+ */
+function responseHandler($jsonResponse, $request) {
+ global $metrics, $tg_response_code;
+ // Write to log.
+ debug_log_incoming($jsonResponse, '<-');
+
+ // Decode json objects
+ $request_array = is_array($request) ? $request : json_decode($request, true);
+ $response = json_decode($jsonResponse, true);
+ if ($metrics){
+ $code = 200;
+ $method = $request_array['method'];
+ $description = null;
+ if (isset($response['error_code'])) {
+ $code = $response['error_code'];
+ # We have to also include the description because TG overloads error codes
+ $description = $response['description'];
+ }
+ $tg_response_code->inc([$code, $method, $description]);
+ }
+ // Validate response.
+ if ((isset($response['ok']) && $response['ok'] != true) || isset($response['update_id'])) {
+ if(is_array($request)) $json = json_encode($request); else $json = $request;
+ // Handle some specific errors
+ if($response['description'] == 'Bad Request: message to edit not found' || $response['description'] == 'Bad Request: message to delete not found') {
+ // Loop through tables where we store sent messages
+ $table = ['cleanup', 'overview', 'trainerinfo'];
+ $i = 0;
+ do {
+ $q = my_query('DELETE FROM '.$table[$i].' WHERE chat_id = :chatId AND message_id = :messageId',['chatId' => $request_array['chat_id'], ':messageId' => $request_array['message_id']]);
+ $i++;
+ } while($q->rowCount() == 0 && $i < count($table));
+ info_log($table[$i-1], 'A message was deleted by someone else than us. Deleting info from database table:');
+ info_log($request_array['chat_id'], 'chat_id:');
+ info_log($request_array['message_id'], 'message_id:');
+ return true;
+ }
+ if(substr($response['description'], 0, 30) == 'Too Many Requests: retry after') {
+ return [
+ 'retry',
+ ($response['parameters']['retry_after'] + 1),
+ ];
+ }
+ info_log("{$json} -> {$jsonResponse}", 'ERROR:');
+ // Log unhandled errors
+ return false;
+ }
+ return true;
+}
diff --git a/core/tools/automate_raid_hour_creation/config.json.example b/core/tools/automate_raid_hour_creation/config.json.example
index 61312b10..8c8d7da3 100644
--- a/core/tools/automate_raid_hour_creation/config.json.example
+++ b/core/tools/automate_raid_hour_creation/config.json.example
@@ -6,10 +6,12 @@
"RAID_HOUR_EVENT_ID":"2",
"RAID_CREATOR_ID":"",
"CHAT_ID": "",
+ "TIMEZONE": "Europe/Helsinki",
"GYM_INFOS": [
- [1,"<-Gym id there and event note for 1st gym here"],
- [2,"<-Gym id there and event note for 2nd gym here"],
- [3,"<-Gym id there and event note for 3rd gym here"]
- ],
- "URL": "https://www.yourhost.com/PokemonRaidBot/index.php?apikey=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11"
+ [1,"<-Gym id there and event note for 1st gym here"],
+ [2,"<-Gym id there and event note for 2nd gym here"],
+ [3,"<-Gym id there and event note for 3rd gym here"]
+ ],
+ "URL": "https://www.yourhost.com/PokemonRaidBot/index.php?apikey=123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11",
+ "EXTRA_DATES":[]
}
diff --git a/core/tools/automate_raid_hour_creation/raid_hour_creator.php b/core/tools/automate_raid_hour_creation/raid_hour_creator.php
index c7aa6695..95bfcb78 100644
--- a/core/tools/automate_raid_hour_creation/raid_hour_creator.php
+++ b/core/tools/automate_raid_hour_creation/raid_hour_creator.php
@@ -11,13 +11,16 @@
die('Config file not valid JSON, cannot continue.');
}
+$tz = $config->TIMEZONE;
+date_default_timezone_set($tz);
+
// Establish mysql connection.
// TODO(artanicus): This should be centralized & imported instead of duplicated
$dbh = new PDO('mysql:host=' . $config->DB_HOST . ';dbname=' . $config->DB_NAME . ';charset=utf8mb4', $config->DB_USER, $config->DB_PASSWORD, array(PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION));
$dbh->setAttribute(PDO::ATTR_ORACLE_NULLS, PDO::NULL_EMPTY_STRING);
$dbh->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
-$link = 'https://raw.githubusercontent.com/ccev/pogoinfo/v2/active/events.json';
+$link = 'https://raw.githubusercontent.com/bigfoott/ScrapedDuck/refs/heads/data/events.min.json';
$data = curl_get_contents($link);
$raids = $dbh->prepare("SELECT start_time FROM raids WHERE event = '" . $config->RAID_HOUR_EVENT_ID . "'");
$raids->execute();
@@ -25,6 +28,7 @@
$offset = date('Z');
$interval = DateInterval::createFromDateString($offset.' seconds');
$raid_to_create = [];
+$datesToCreate = [];
$data = json_decode($data,true);
if($data !== false) {
$now = new DateTime('18:00');
@@ -37,8 +41,15 @@
$end->sub($interval);
$event_start = $start->format('Y-m-d H:i:s');
$event_end = $end->format('Y-m-d H:i:s');
- if($event['type'] == 'raid-hour' && (($raids->rowcount() > 0 && !in_array($event_start, $raids_res)) || $raids->rowcount() === 0)) {
- $mon_name = trim(str_replace('Raid Hour','',str_replace('Forme','',$event['name'])));
+ $notePrefix = null;
+ if($event['eventType'] == 'raid-hour' && $start > $now && (($raids->rowcount() > 0 && !in_array($event_start, $raids_res)) || $raids->rowcount() === 0)) {
+ if(preg_match('/&/', $event['name'])) {
+ $notePrefix = $event['name'] . PHP_EOL;
+ $raid_to_create[] = [9995, 0, $event_start, $event_end, '5', $notePrefix];
+ $datesToCreate[] = $event_start;
+ continue;
+ }
+ $mon_name = trim(preg_replace('/Forme|Form|Raid Hour|[()]/','',$event['name']));
$mon_split = explode(' ',$mon_name);
$part_count = count($mon_split);
$mon_query_input = [];
@@ -66,61 +77,79 @@
if($mon === false) continue;
$pokemon = $mon[0];
$pokemon_form = $mon[1];
+ $notePrefix = $event['name'] . PHP_EOL;
}
- $raid_to_create[] = [$pokemon, $pokemon_form,$event_start,$event_end];
+ $raid_to_create[] = [$pokemon, $pokemon_form,$event_start,$event_end, '5', $notePrefix];
+ $datesToCreate[] = $event_start;
}
}
- if($now->format('w') == 3 && !in_array($now->format('Y-m-d H:i:s'),$raids_res)) {
+ if(($now->format('w') == 3 || in_array($now->format('Y-m-d'), $config->EXTRA_DATES)) && !in_array($now->format('Y-m-d H:i:s'), $raids_res) && !in_array($now->format('Y-m-d H:i:s'), $datesToCreate)) {
$start_time = gmdate('Y-m-d H:i:s',mktime(18,0,0));
$end_time = gmdate('Y-m-d H:i:s',mktime(19,0,0));
$mon = get_current_bosses($start_time);
- if($mon !== false) $raid_to_create[] = [$mon[0], $mon[1] ,$start_time, $end_time];
+ if($mon !== false) $raid_to_create[] = [$mon[0], $mon[1] ,$start_time, $end_time, $mon[2], null];
}
}
try {
- $query = $dbh->prepare('INSERT INTO raids (
- user_id,
- pokemon,
- pokemon_form,
- spawn,
- level,
- start_time,
- end_time,
- gym_id,
- event,
- event_note
- )
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
- ');
+ $query = $dbh->prepare('
+ INSERT INTO raids (
+ user_id,
+ pokemon,
+ pokemon_form,
+ spawn,
+ level,
+ start_time,
+ end_time,
+ gym_id,
+ event,
+ event_note
+ )
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
+ ');
+ $now = gmdate('Y-m-d H:i:s');
foreach($raid_to_create as $raid_info) {
foreach($config->GYM_INFOS as $t) {
- $now = gmdate('Y-m-d H:i:s');
- $query->execute([$config->RAID_CREATOR_ID,$raid_info[0],$raid_info[1],$now,'5',$raid_info[2],$raid_info[3],$t[0],$config->RAID_HOUR_EVENT_ID,$t[1]]);
+ $query->execute([
+ $config->RAID_CREATOR_ID,
+ $raid_info[0],
+ $raid_info[1],
+ $now,
+ $raid_info[4],
+ $raid_info[2],
+ $raid_info[3],
+ $t[0],
+ $config->RAID_HOUR_EVENT_ID,
+ $raid_info[5] . $t[1]
+ ]);
}
}
}
catch (PDOException $exception) {
echo($exception->getMessage());
- $dbh = null;
exit;
}
-$dbh = null;
function get_current_bosses($spawn) {
global $dbh;
- $pk = $dbh->prepare('SELECT pokedex_id,pokemon_form_id FROM raid_bosses WHERE raid_level = \'5\' AND \''.$spawn.'\' BETWEEN date_start AND date_end');
- $pk->execute();
- $res = $pk->fetch();
- if($pk->rowCount()==1) {
- $pokemon = $res['pokedex_id'];
- $pokemon_form = $res['pokemon_form_id'];
- }elseif($pk->rowCount()>1) {
- $pokemon = 9995;
- $pokemon_form = 0;
- }else {
- return false;
+ $i = 0;
+ $levels = [5, 7, 8]; // Search potential raid hour bosses from these raid levels
+ $pokemon = $pokemon_form = false;
+ foreach($levels as $level) {
+ $pk = $dbh->prepare('SELECT pokedex_id,pokemon_form_id FROM raid_bosses WHERE raid_level = ? AND ? BETWEEN date_start AND date_end and disabled = 0');
+ $pk->execute([$level, $spawn]);
+ $res = $pk->fetch();
+ if($pk->rowCount() == 1) {
+ $pokemon = $res['pokedex_id'];
+ $pokemon_form = $res['pokemon_form_id'];
+ break;
+ }elseif($pk->rowCount() > 1) {
+ $pokemon = 999 . $level;
+ $pokemon_form = 0;
+ break;
+ }
}
- return [$pokemon,$pokemon_form];
+ if($pokemon === false) return false;
+ return [$pokemon, $pokemon_form, $level];
}
function curl_get_contents($url)
{
@@ -139,5 +168,3 @@ function curl_get_contents($url)
curl_close($ch);
return $content;
}
-
-?>
diff --git a/core/tools/automate_raid_hour_creation/share_event_raids.php b/core/tools/automate_raid_hour_creation/share_event_raids.php
index 13bd629b..255110bc 100644
--- a/core/tools/automate_raid_hour_creation/share_event_raids.php
+++ b/core/tools/automate_raid_hour_creation/share_event_raids.php
@@ -49,6 +49,3 @@
// Close connection.
curl_close($curl);
}
-
-$dbh = null;
-?>
diff --git a/core/tools/hash.php b/core/tools/hash.php
index 8fea50c1..bf087ec1 100644
--- a/core/tools/hash.php
+++ b/core/tools/hash.php
@@ -1,4 +1,3 @@
diff --git a/core/tools/set_commands.php b/core/tools/set_commands.php
index 2054f1c6..7cdc1bcd 100644
--- a/core/tools/set_commands.php
+++ b/core/tools/set_commands.php
@@ -48,7 +48,7 @@
$request = json_encode([
'method'=>'deleteMyCommands',
'scope'=>$scope,
-
+
]);
$response = curl_json_request($request);
}
diff --git a/core/tools/webhook.html b/core/tools/webhook.html
index 92bf78f3..2e03f318 100644
--- a/core/tools/webhook.html
+++ b/core/tools/webhook.html
@@ -15,6 +15,11 @@
+ +
+
@@ -64,6 +69,7 @@
el: '#app',
data: {
token: '123456:ABC-DEF1234ghIkl-zyx57W2v1u123ew11',
+ botname: '',
maxconnection: '80',
port: '',
host: 'https://' + window.location.hostname + location.pathname.replace(/[^/]*$/, '')
@@ -94,6 +100,9 @@
var bot = document.createElement('a');
bot.href = this.host;
bot_string = bot.origin + port_string + bot.pathname.replace(/\/?$/, '/') + 'index.php?apikey=' + this.token;
+ if (this.botname) {
+ bot_string = bot_string + '&bot_name=' + this.botname
+ }
return bot_string
}
diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml
index d37257ee..727b33fb 100644
--- a/docker/docker-compose.yml
+++ b/docker/docker-compose.yml
@@ -1,7 +1,6 @@
-version: "3.7"
-
services:
raidbot:
+ container_name: raidbot
ports:
- 8088:80
depends_on:
@@ -9,8 +8,10 @@ services:
restart: always
volumes:
# These are just example paths, change them to where you have stored the data!
- - ./PokemonRaidBot/config/:/var/www/html/config/
- ./PokemonRaidBot/access/:/var/www/html/access/
+ - ./PokemonRaidBot/config/config.json:/var/www/html/config/config.json
+ - ./PokemonRaidBot/custom/:/var/www/html/custom/
+ - ./PokemonRaidBot/images/gyms/:/var/www/html/images/gyms
- ./PokemonRaidBot/images/pokemon_PokeMiners/:/var/www/html/images/pokemon_PokeMiners
- ./tg-logs/:/var/log/tg-bots/
environment:
@@ -26,7 +27,8 @@ services:
ofelia.job-exec.raidbot-overview.command: /usr/bin/curl -s -k -d '{"callback_query":{"data":"0:overview_refresh:0"}}' https://raidbot.example.com/index.php?apikey=changeme
raidbot-db:
- image: mariadb:10.3
+ container_name: raidbot-db
+ image: mariadb:10.11
restart: always
command: ['mysqld', '--character-set-server=utf8mb4', '--collation-server=utf8mb4_unicode_ci']
volumes:
@@ -41,6 +43,7 @@ services:
MYSQL_PASSWORD:
ofelia:
+ container_name: raidbot-ofelia
image: mcuadros/ofelia:latest
depends_on:
- raidbot
diff --git a/docker/entrypoint.sh b/docker/entrypoint.sh
index acb25a8c..3eb00bd1 100755
--- a/docker/entrypoint.sh
+++ b/docker/entrypoint.sh
@@ -34,7 +34,7 @@ env | egrep -q '^POKEMONRAIDBOT_' && \
| tee -a config/config.json)
# Do some permission setting for any data that might've been volume mounted in, otherwise stuff will fail in weird ways.
-chown -R www-data:www-data config/config.json access/ custom/ images/pokemon*
+chown -R www-data:www-data config/config.json access/ custom/ images/gyms/ images/pokemon*
# Ensure we now have a valid config
if [[ ! -a /var/www/html/config/config.json ]]; then
diff --git a/docs/config.rst b/docs/config.rst
index 49476b55..e2637f18 100644
--- a/docs/config.rst
+++ b/docs/config.rst
@@ -47,7 +47,6 @@ it's already prepended to the right length.
.. code-block::
- {
*snip*
"chat": {
"id": -1002233445566,
@@ -95,6 +94,22 @@ How to make a Supergroup
* Once a group has been converted to a Supergroup it cannot go back to a normal Group, even if you change back the option that caused it to convert.
* Be aware that the group ID will change completely when the group gets converted so you'll need to find it again!
+Configuring multiple bots
+-------------------------
+
+If you want to run multiple Telegram bots using this directory, you can create for each of them config and access files by prepending them with a unique name:
+
+.. code-block::
+
+ access/bot1-creator111222333
+ access/bot2-creator111222333
+ config/bot1-config.json
+ config/bot1-geoconfig.json
+ config/bot2-config.json
+ config/bot2-geoconfig.json
+
+When setting webhook to Telegram using ``webhook.html`` you must set the matching bot name.
+
Database connection
-------------------
@@ -111,8 +126,6 @@ Set ``APIKEY_HASH`` to the hashed value of your bot token (preferably lowercase)
Set ``DDOS_MAXIMUM`` to the amount of callback queries each user is allowed to do each minute. If the amount is reached any further callback query is rejected by the DDOS check. Default value: 10.
-Set ``BRIDGE_MODE`` to true when you're using the PokemonBotBridge. If you're not using the PokemonBotBridge the default value of false is used. PokemonBotBridge: https://github.com/pokepark/PokemonBotBridge
-
More config options
-------------------
@@ -138,6 +151,7 @@ You can set several languages for the bot. Available languages are (A-Z):
* DE (German)
* EN (English)
+* ES (Spanish)
* FI (Finnish)
* FR (French)
* IT (Italian)
@@ -194,6 +208,8 @@ OpenStreetMap API
To use OpenStreetMap's Nominatim API to lookup addresses of gyms, set ``OSM_LOOKUP`` to ``true`` and ``MAPS_LOOKUP`` to ``false``.
+You can set a custom nominatim server address in ``OSM_URL``, e.g. ``http://localhost:8090``.
+
Quote from `Nominatim documentation Latitude,Longitude om de nieuwe gym toe te voegen!",
- "DE": "Fehler! Bitte übermittle die Koordinaten im Format Breitengrad,Längengrad zum Hinzufügen einer neuen Arena!",
- "EN": "Error! Please submit the coordinates in the format Latitude,Longitude to add a new gym!",
+ "gym_coordinates": {
+ "NL": "Coordinaten",
+ "DE": "Koordinaten",
+ "EN": "Coordinates",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Coordonnées",
"PL": "TRANSLATE",
- "FI": "Virhe! Anna koordinaatit muotossa Leveysaste,Pituusaste lisätäksesi uuden salin!",
- "ES": "¡Error! ¡Envía las coordenadas en el formato latitud,longitud para agregar un nuevo gimnasio!"
+ "FI": "Koordinaatit",
+ "ES": "TRANSLATE"
+ },
+ "gym_edit_coordinates": {
+ "NL": "Wijzig coordinaten",
+ "DE": "Koordinaten bearbeiten",
+ "EN": "Edit coordinates",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Modifier les coordonnées",
+ "PL": "TRANSLATE",
+ "FI": "Muokkaa koordinaatteja",
+ "ES": "TRANSLATE"
},
- "gym_coordinates_format_example": {
- "NL": "Als voorbeeld: /addgym 51.516263,4.377755",
- "DE": "Zum Beispiel: /addgym 52.516263,13.377755",
- "EN": "For example: /addgym 52.516263,13.377755",
+ "gym_coordinates_format_error": {
+ "NL": "Error! Stuur de coordinaten in het volgende formaat Latitude,Longitude om de nieuwe gym toe te voegen!",
+ "DE": "Fehler! Bitte übermittle die Koordinaten im Format Breitengrad,Längengrad zum Hinzufügen einer neuen Arena!",
+ "EN": "Error! Please submit the coordinates in the format Latitude,Longitude to add a new gym!",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Erreur! Insérez les coordonnées au format Latitude,Longitude pour ajouter une nouvelle arène!",
"PL": "TRANSLATE",
- "FI": "Esimerkiksi: /addgym 52.516263,13.377755",
- "ES": "Por ejemplo: /addgym 52.516263,13.377755"
+ "FI": "Virhe! Anna koordinaatit muotossa Leveysaste,Pituusaste lisätäksesi uuden salin!",
+ "ES": "¡Error! ¡Envía las coordenadas en el formato latitud,longitud para agregar un nuevo gimnasio!"
},
"gym_gps_coordinates_format_error": {
"NL": "Error! Stuur de coordinaten in het volgende formaat: Latitude,Longitude",
@@ -1736,62 +3087,36 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Erreur! Inscrivez les coordonnées au format suivant: Latitude,Longitude",
"PL": "TRANSLATE",
- "FI": "Virhe! Virhe! Anna koordinaatit seuraavassa muodossa: Leveysaste,Pituusaste",
+ "FI": "Virhe! Anna koordinaatit seuraavassa muodossa: Leveysaste,Pituusaste",
"ES": "¡Error! Envía las coordenadas en el siguiente formato: latitud,longitud"
},
"gym_gps_instructions": {
- "NL": "Om de gym coordinaten te veranderen stuur /gymgps gym id, nieuwe gym coordinaten!",
- "DE": "Zum Ändern der Arena-Koordinaten bitte /gymgps Arena-ID, neue Arena-Koordinaten eingeben!",
- "EN": "To change the coordinates of a gym please enter /gymgps gym id, new gym coordinates!",
+ "NL": "Stuur me de gym coordinaten in de volgende format: Latitude,Longitude",
+ "DE": "Bitte die Arena-Koordinaten in folgendem Format senden: Latitude,Longitude",
+ "EN": "Send me the gym coordinates in the following format: Latitude,Longitude",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Envoyez-moi les coordonnées de l'arène au format suivant: Latitude,Longitude",
"PL": "TRANSLATE",
- "FI": "Muuttaaksesi salin koordinaatteja komenna gymgps salin id, uudet koordinaatit!",
- "ES": "¡Para cambiar las coordenadas de un gimnasio, ingresa /gymgps gym id, nuevas coordenadas de gimnasio!"
+ "FI": "Lähetä minulle salin koordinaatit muodossa: Leveysaste,Pituusaste",
+ "ES": "TRANSLATE"
},
"gym_gps_example": {
- "NL": "Als voorbeeld: /gymgps 34, 51.516263,4.377755",
- "DE": "Zum Beispiel: /gymgps 34, 52.516263,13.377755",
- "EN": "For example: /gymgps 34, 52.516263,13.377755",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Esimerkiksi: /gymgps 34, 52.516263,13.377755",
- "ES": "Por ejemplo: /gymgps 34, 52.516263,13.377755"
- },
- "gym_gps_added": {
- "NL": "Gym coordinaten succesvol toegevoegd!",
- "DE": "Arena-Koordinaten erfolgreich hinzugefügt!",
- "EN": "Gym coordinates successfully added!",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Salin koordinaatit lisätty onnistuneesti!",
- "ES": "¡Se agregaron con éxito las coordenadas del gimnasio!"
- },
- "gym_id_gps_missing": {
- "NL": "Error! gym id of coordinaten mist!",
- "DE": "Fehler! Arena-ID oder Koordinaten fehlen!",
- "EN": "Error! Gym id or coordinates are missing!",
+ "NL": "Als voorbeeld: 51.516263,4.377755",
+ "DE": "Zum Beispiel: 52.516263,13.377755",
+ "EN": "For example: 52.516263,13.377755",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Par exemple: 52.516263,13.377755",
"PL": "TRANSLATE",
- "FI": "Virhe! Salin id tai koordinaatit puuttuvat!",
- "ES": "¡Error! ¡Faltan el gym id o las coordenadas!"
+ "FI": "Esimerkiksi: 52.516263,13.377755",
+ "ES": "Por ejemplo: 52.516263,13.377755"
},
"gymname_then_location": {
"NL": "Gebruik het commando /gymname Naam van de gym om deze aan de coordinaten vast te zetten. Daarna kan je weer een locatie delen!",
@@ -1801,7 +3126,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Utilisez la commande /gymname Nom de l'arène pour définir un nom d'arène pour les coordonnées soumises précédemment. Vous pourrez ensuite envoyer une nouvelle position!",
"PL": "TRANSLATE",
"FI": "Käytä komentoa /gymname Salin nimi asettaaksesi salinimen aiemmin annetuille koordinaateille. Sitten voit antaa jälleen sijainnin!",
"ES": "Utiliza el comando /gymname Nombre del gimnasio para establecer un nombre de gimnasio para las coordenadas enviadas recientemente. ¡Entonces podrás volver a enviar una ubicación!"
@@ -1814,11 +3139,24 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Arène ajoutée avec succès!",
"PL": "TRANSLATE",
"FI": "Sali lisätty onnistuneesti!",
"ES": "¡Se agregó con éxito el gimnasio!"
},
+ "gym_create": {
+ "NL": "Maak een nieuwe gym",
+ "DE": "Neue Arena erstellen",
+ "EN": "Create a new gym",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Créer une nouvelle arène",
+ "PL": "TRANSLATE",
+ "FI": "Luo uusi sali",
+ "ES": "TRANSLATE"
+ },
"gym_updated": {
"NL": "De gym is succesvol aangepast!",
"DE": "Arena erfolgreich aktualisiert!",
@@ -1827,7 +3165,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Arène mise à jour avec succès!",
"PL": "TRANSLATE",
"FI": "Sali päivitetty onnistuneesti!",
"ES": "¡Se actualizó con éxito el gimnasio!"
@@ -1840,7 +3178,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Supprimer l'arène",
"PL": "TRANSLATE",
"FI": "Poista sali",
"ES": "Eliminar gimnasio"
@@ -1853,7 +3191,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Vraiment supprimer cette arène?",
"PL": "TRANSLATE",
"FI": "Vahvista salin poisto?",
"ES": "¿De verdad eliminar este gimnasio?"
@@ -1866,7 +3204,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Arène supprimée avec succès!",
"PL": "TRANSLATE",
"FI": "Sali poistettu onnistuneesti!",
"ES": "¡Se eliminó con éxito este gimnasio!"
@@ -1879,7 +3217,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Détails de l'arène",
"PL": "TRANSLATE",
"FI": "Salin yksityiskohdat",
"ES": "Detalles del gimnasio"
@@ -1892,205 +3230,114 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Afficher les détails de l'arène",
"PL": "TRANSLATE",
"FI": "Näytä salin yksityiskohdat",
"ES": "Ver detalles del gimnasio"
},
- "gym_note_added": {
- "NL": "Gym info toegevoegd!",
- "DE": "Arena-Notiz erfolgreich hinzugefügt!",
- "EN": "Gym note successfully added!",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Salin muistiinpano tallennettu onnistuneesti!",
- "ES": "¡Nota del gimnasio añadida con éxito!"
- },
- "gym_note_deleted": {
- "NL": "Gym info verwijderd!",
- "DE": "Arena-Notiz erfolgreich gelöscht!",
- "EN": "Gym note successfully deleted!",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "alin muistiinpano poistettu onnistuneesti!",
- "ES": "¡Nota del gimnasio eliminada con éxito!"
- },
- "gym_note_new": {
- "NL": "Nieuwe gym info:",
- "DE": "Neue Arena-Notiz:",
- "EN": "New gym note:",
+ "gym_edit_text_too_long": {
+ "NL": "Error! niet meer dan 255 tekens!",
+ "DE": "Fehler! Es sind maximal 255 Zeichen erlaubt!",
+ "EN": "Error! The maximum text length is 255 characters!",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Erreur! La longueur maximale du texte est de 255 caractères!",
"PL": "TRANSLATE",
- "FI": "Uusi sali muistiinpano:",
- "ES": "Nueva nota del gimnasio:"
+ "FI": "Virhe! Tekstin enimmäispituus on 255 merkkiä!",
+ "ES": "TRANSLATE"
},
- "gym_id_note_missing": {
- "NL": "Error! Gym id of info mist!",
- "DE": "Fehler! Arena-ID oder Notiz fehlt!",
- "EN": "Error! Gym id or note is missing!",
+ "gym_add_edit_note": {
+ "NL": "gym note",
+ "DE": "Arena-Notiz",
+ "EN": "gym note",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Notice d'arène",
"PL": "TRANSLATE",
- "FI": "Virhe! Salin id tai muistiinpano puuttuu!",
- "ES": "¡Error! ¡Faltan gym id o nota!"
+ "FI": "lisätietoja",
+ "ES": "TRANSLATE"
},
"gym_note_instructions": {
- "NL": "Om de gym info te veranderen stuur /gymnote gym id, nieuwe gym info!",
- "DE": "Zum Ändern einer Arena-Notiz bitte /gymnote Arena-ID, neue Arena-Notiz eingeben!",
- "EN": "To change the note of a gym please enter /gymnote gym id, new gym note!",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Vaihtaaksesi salin muistiinpanoa komenna /gymnote salin id, uusi muistiinpano!",
- "ES": "¡Para cambiar la nota de un gimnasio, escribe /gymnote gym id, nueva nota de gimnasio!"
- },
- "gym_note_example": {
- "NL": "Als voorbeeld: /gymnote 34, ontmoetingsplek: achter het gebouw!",
- "DE": "Zum Beispiel: /gymnote 34, Treffpunkt: Hinter dem Gebäude",
- "EN": "For example: /gymnote 34, Meeting point: Behind the building!",
+ "NL": "Stuur me een nieuwe gym notitie (maximaal 255 tekens):",
+ "DE": "Neue Arena-Notiz eingeben (max. 255 Zeichen)",
+ "EN": "Send me the new gym note (max 255 characters):",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Envoyez-moi la nouvelle notice d'arène (max 255 caractères):",
"PL": "TRANSLATE",
- "FI": "Esimerkiksi: /gymnote 34, Tapaamispiste: Rakennuksen takana!",
- "ES": "Por ejemplo: /gymnote 34, Meeting point: Behind the building"
+ "FI": "Lähetä minulle salin uudet lisätiedot (max 255 merkkiä):",
+ "ES": "TRANSLATE"
},
- "gym_note_reset": {
- "NL": "Om de gym info te verwijderen stuur /gymnote gym id, reset.",
- "DE": "Zum Löschen einer Arena-Notiz /gymnote Arena-ID, reset eingeben.",
- "EN": "To delete a gym note enter /gymnote gym id, reset.",
+ "gym_address": {
+ "NL": "Gym adres",
+ "DE": "Arena-Adresse",
+ "EN": "gym address",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Adresse de l'arène",
"PL": "TRANSLATE",
- "FI": "Poistaaksesi salin muistiinpanon komenna /gymnote salin id, reset.",
- "ES": "Para eliminar la nota de un gimnasio, escribe /gymnote gym id, reset."
+ "FI": "salin osoite",
+ "ES": "TRANSLATE"
},
- "gym_note_reset_example": {
- "NL": "Als voorbeeld: /gymnote 34, reset.",
- "DE": "Zum Beispiel: /gymnote 34, reset",
- "EN": "For example: /gymnote 34, reset",
+ "gym_stored_address": {
+ "NL": "Opgeslagen adres",
+ "DE": "Gespeicherte Adresse",
+ "EN": "Stored address",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Adresse enregistrée",
"PL": "TRANSLATE",
- "FI": "Esimerkiksi: /gymnote 34, reset",
- "ES": "Por ejemplo: /gymnote 34, reset"
+ "FI": "Tallennettu osoite",
+ "ES": "TRANSLATE"
},
"gym_address_instructions": {
- "NL": "Om het adres aan te passen stuur /gymaddress gym id, het nieuwe gym adres!",
- "DE": "Zum Ändern einer Arena-Adresse bitte /gymaddress Arena-ID, neue Arena-Adresse eingeben!",
- "EN": "To change the address of a gym please enter /gymaddress gym id, new gym address!",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Vaihtaaksesi salin osoitetta komenna /gymaddress salin id, uusi salin osoite!",
- "ES": "¡Para cambiar la dirección de un gimnasio, escribe /gymaddress gym id, nueva dirección de gimnasio!"
- },
- "gym_address_example": {
- "NL": "Als voorbeeld /gymaddress 34, Markt 61, 3131 CR Vlaardingen !",
- "DE": "Zum Beispiel: /gymaddress 34, Großer Stern, 10557 Berlin",
- "EN": "For example: /gymaddress 34, Großer Stern, 10557 Berlin!",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Esimeriksi: /gymaddress 34, Mannerheiminkatu, 49400 Hamina!",
- "ES": "Por ejemplo: /gymaddress 34, Großer Stern, 10557 Berlin"
- },
- "gym_address_reset": {
- "NL": "Om het gym adres te verwijderen stuur /gymaddress gym id, reset.",
- "DE": "Zum Löschen einer Arena-Adresse /gymaddress Arena-ID, reset eingeben.",
- "EN": "To delete a gym address enter /gymaddress gym id, reset.",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Poistaaksesi salin osoitteen komenna /gymaddress salin id, reset.",
- "ES": "Para eliminar la dirección de un gimnasio, escribe /gymaddress gym id, reset."
- },
- "gym_address_reset_example": {
- "NL": "Als voorbeeld /gymaddress 34, reset",
- "DE": "Zum Beispiel: /gymaddress 34, reset",
- "EN": "For example: /gymaddress 34, reset",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Esimerkiksi: /gymaddress 34, reset",
- "ES": "Por ejemplo: /gymaddress 34, reset"
- },
- "gym_address_added": {
- "NL": "Gym adres succesvol toegevoegd!",
- "DE": "Arena-Adresse erfolgreich hinzugefügt!",
- "EN": "Gym address successfully added!",
+ "NL": "Stuur me het nieuwe gym adres:",
+ "DE": "Neue Arena-Adresse eingeben:",
+ "EN": "Send me the new gym address:",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Envoyez-moi l'adresse de la nouvelle arène:",
"PL": "TRANSLATE",
- "FI": "Salin osoite tallennettu onnistuneesti!",
- "ES": "¡Dirección del gimnasio añadida con éxito!"
+ "FI": "Lähetä minulle salin uusi osoite:",
+ "ES": "TRANSLATE"
},
- "gym_id_address_missing": {
- "NL": "Error! gym id of adres mist!",
- "DE": "Fehler! Arena-ID oder Adresse fehlt!",
- "EN": "Error! Gym id or address is missing!",
+ "gym_address_lookup_result": {
+ "NL": "Opgezochte adres",
+ "DE": "Ergebnis der Adresssuche",
+ "EN": "Address lookup result",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Résultat de la recherche d'adresse",
"PL": "TRANSLATE",
- "FI": "Virhe! Salin id tai osoite puuttuu!",
- "ES": "¡Error! Faltan gym id o dirreción!"
+ "FI": "Osoitehaun tulos",
+ "ES": "TRANSLATE"
},
- "gym_address_deleted": {
- "NL": "Gym adres succesvol verwijderd!",
- "DE": "Arena-Adresse erfolgreich gelöscht!",
- "EN": "Gym address successfully deleted!",
+ "gym_save_lookup_result": {
+ "NL": "Sla opgezochte resultaat op",
+ "DE": "Ergebnis der Adresssuche speichern",
+ "EN": "Save lookup result",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Enregistrer le résultat de la recherche d'adresse",
"PL": "TRANSLATE",
- "FI": "Salin osoite poistettu onnistuneesti!",
- "ES": "¡Dirección del gimnasio eliminada con éxito!"
+ "FI": "Tallenna osoitehaun tulos",
+ "ES": "TRANSLATE"
},
"select_raid_boss": {
"NL": "Selecteer Raid baas",
@@ -2100,7 +3347,7 @@
"PT-BR": "Escolha o Pokémon chefe da raid",
"RU": "Выберите Рейд босса",
"NO": "Velg raid boss",
- "FR": "Sélectionne un boss de raid",
+ "FR": "Sélectionnez un boss de raid",
"PL": "Wybierz Bossa Rajdu",
"FI": "Valitse raidibossi",
"ES": "Selecciona el jefe de incursión"
@@ -2113,7 +3360,7 @@
"PT-BR": "Escolha o Pokémon",
"RU": "Укажите Покемона",
"NO": "Velg Pokemon",
- "FR": "Sélectionne un Pokémon",
+ "FR": "Sélectionnez un Pokémon",
"PL": "Wybierz Pokemona",
"FI": "Valitse Pokemoni",
"ES": "Selecciona Pokémon"
@@ -2126,11 +3373,24 @@
"PT-BR": "Raid salva:",
"RU": "Рейд сохранен:",
"NO": "Raid lagret",
- "FR": "Raid sauvegardé",
+ "FR": "Raid enregistré:",
"PL": "Rajd zapisany",
"FI": "Raidi tallennettu:",
"ES": "Incursión guardada:"
},
+ "featured_pokemon": {
+ "NL": "Pokemon",
+ "DE": "Rampenlicht-Pokemon",
+ "EN": "Featured Pokemon",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Pokémon vedette",
+ "PL": "TRANSLATE",
+ "FI": "Tapahtuman Pokemon",
+ "ES": "TRANSLATE"
+ },
"raid_boss": {
"NL": "Raid baas",
"DE": "Raid-Boss",
@@ -2152,7 +3412,7 @@
"PT-BR": "Chefe da raid salvo!",
"RU": "Рейд Босс сохранен!",
"NO": "Raid boss lagret!",
- "FR": "Boss de raid sauvegardé",
+ "FR": "Boss de raid enregistré!",
"PL": "Boss Rajdu zapisany!",
"FI": "Raidibossi tallennettu!",
"ES": "¡Jefe de incursión guardado!"
@@ -2165,7 +3425,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Boss de raid exclus de l'importation:",
"PL": "TRANSLATE",
"FI": "Tuonnista poissuljetut raidibossit:",
"ES": "Jefes de incursión excluidos de importación:"
@@ -2178,7 +3438,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Sélectionnez le boss de raid à exclure de l'importation ou terminez l'importation avec 'Enregistrer'",
"PL": "TRANSLATE",
"FI": "Valitse tuonnista poissuljettavat raidibossit tai lopeta tuonti valitsemalla 'Tallenna'",
"ES": "Selecciona el jefe de incursión a excluir de la importación o finaliza la importación con 'Guardar'"
@@ -2191,7 +3451,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Importer les boss de raid?",
"PL": "TRANSLATE",
"FI": "Tuo raidibossit?",
"ES": "¿Importar jefes de incursión?"
@@ -2204,7 +3464,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Importation terminée!",
"PL": "TRANSLATE",
"FI": "Tuonti valmis!",
"ES": "¡Importación finalizada!"
@@ -2217,7 +3477,7 @@
"PT-BR": "Opcional - Nome do gínasio e nome do time",
"RU": "Опционально - Название Гима и Команда Гима",
"NO": "Valgfri - Gym navn og gym team:",
- "FR": "Optionnel - Couleur de l'arène",
+ "FR": "Optionnel - Nom et équipe de l'arène:",
"PL": "Opcjonalnie - Nazwa Areny i kolor Areny",
"FI": "Valinnainen - Salin nimi ja salin joukkue:",
"ES": "Opcional - Nombre del gimnasio y equipo del gimnasio:"
@@ -2235,32 +3495,6 @@
"FI": "/gymname Salin nimi",
"ES": "/gymname Nombre del gimnasio"
},
- "set_gym_team": {
- "NL": "Optioneel - zet Gym en Team",
- "DE": "Optional - Arena Team setzen",
- "EN": "Optional - set Gym and Team",
- "IT": "Opzionale - imposta Palestra e Team",
- "PT-BR": "Opcional - escolha o gínasio e time",
- "RU": "Опционально - указать Гим и Команду",
- "NO": "Valgfri - Fortell hvilken Gym og Team",
- "FR": "Optionnel - choisir la couleur de l'arène",
- "PL": "Opcjonalnie - Wybierz kolor Areny",
- "FI": "Valinnainen - aseta sali ja joukkue",
- "ES": "Opcional - Poner gimnasio y equipo"
- },
- "set_gym_team_command": {
- "NL": "/team Mystic/Valor/Instinct/Blauw/Rood/Geel",
- "DE": "/team Mystic/Valor/Instinct/Blau/Rot/Gelb",
- "EN": "/team Mystic/Valor/Instinct/Blue/Red/Yellow",
- "IT": "/team Saggezza/Valore/Istinto/Blu/Rosso/Giallo",
- "PT-BR": "/team Mystic/Valor/Instinct/Azul/Vermelho/Amarelo",
- "RU": "/team Mystic/Valor/Instinct/Синий/Красный/Желтый",
- "NO": "/team Mystic/Valor/Instinct/Blue/Red/Yellow",
- "FR": "/team Sagesse/Bravoure/Intuition/Bleu/Rouge/Jaune",
- "PL": "/team Niebieski/Czerowny/Żółty",
- "FI": "/team Mystic/Valor/Instinct/Blue/Red/Yellow",
- "ES": "/team Sabiduría/Valor/Instinto/Azul/Rojo/Amarillo"
- },
"mystic": {
"NL": "Mystic/Blauw",
"DE": "Weisheit/Blau",
@@ -2308,7 +3542,7 @@
"PT-BR": "Hora de começar determinada para",
"RU": "Установить время начала",
"NO": "Startid satt til",
- "FR": "Heure de début réglée à",
+ "FR": "Heure de commencement réglée à",
"PL": "Czas startu ustawiony na",
"FI": "Aloitusaika asetettu klo",
"ES": "Hora de inicio establecida en"
@@ -2334,7 +3568,7 @@
"PT-BR": "Select the date of the raid:",
"RU": "Указать дату рейда:",
"NO": "Velg dato for raidet:",
- "FR": "Sélectionne la date du raid",
+ "FR": "Sélectionnez la date du raid:",
"PL": "Wybierz date Rajdu",
"FI": "Valitse raidin päivämäärä:",
"ES": "Selecciona la fecha de la incursión:"
@@ -2347,7 +3581,7 @@
"PT-BR": "Select the hour of the raid:",
"RU": "Указать час рейда:",
"NO": "Velg tid>/b> for raidet:",
- "FR": "Sélectionne l'heure du raid",
+ "FR": "Sélectionnez l'heure du raid:",
"PL": "Wybierz godzinę rajdu:",
"FI": "Valitse raidin tunti:",
"ES": "Selecciona la hora de la incursión:"
@@ -2360,7 +3594,7 @@
"PT-BR": "Select the start time of the raid:",
"RU": "Указать Время начала рейда:",
"NO": "Velg når raidet starter:",
- "FR": "Sélectionne l'heure de POP du raid",
+ "FR": "Sélectionnez l'heure de commencement du raid:",
"PL": "WYbierz czas startu Rajdu",
"FI": "Valitse raidin aloitusaika:",
"ES": "Selecciona la hora de inicio de la incursión:"
@@ -2399,7 +3633,7 @@
"PT-BR": "Quando a raid irá começar?",
"RU": "Когда начало рейда?",
"NO": "Når starter raidet?",
- "FR": "Quand démarre le raid ?",
+ "FR": "Quand commence le raid?",
"PL": "Kiedy Rajd się zaczyna?",
"FI": "Mihin aikaan raidi alkaa?",
"ES": "¿Cuando va a empezar la incursión?"
@@ -2412,7 +3646,7 @@
"PT-BR": "Em quantos minutos a raid irá começar?",
"RU": "Через сколько минут рейд начинается?",
"NO": "Hvor mange minutter til raidet starter?",
- "FR": "Dans combien de minutes le raid commence ?",
+ "FR": "Dans combien de minutes le raid commence?",
"PL": "Za ile minut zacznie się Rajd?",
"FI": "Monenko minuutin päästä raidi alkaa?",
"ES": "¿En cuantos minutos va empezar la incursión?"
@@ -2425,7 +3659,7 @@
"PT-BR": "Ver horário",
"RU": "Просмотр времени",
"NO": "Klokkevisning",
- "FR": "Voir l'heure",
+ "FR": "Vue horaire",
"PL": "Widok zegara",
"FI": "Kellonaika näkymä",
"ES": "Ver horario"
@@ -2438,7 +3672,7 @@
"PT-BR": "Ver minutos",
"RU": "Просмотр минут",
"NO": "Minuttvisning",
- "FR": "Voir les minutes",
+ "FR": "Afficher les minutes",
"PL": "Pokaż minuty",
"FI": "Minuutti näkymä",
"ES": "Ver minutos"
@@ -2451,7 +3685,7 @@
"PT-BR": "Visualização mudou!",
"RU": "Просмотр изменен!",
"NO": "Visning endret!",
- "FR": "L'affichage du temps à changé !",
+ "FR": "La vue horaire a changé!",
"PL": "Widok zmieniony!",
"FI": "Näkymä vaihdettu!",
"ES": "¡Vista cambiada!"
@@ -2464,7 +3698,7 @@
"PT-BR": "A raid já está ativa!",
"RU": "Рейд уже активен!",
"NO": "Raidet er allerede aktivt!",
- "FR": "Le raid est déjà en cours",
+ "FR": "Le raid est déjà en cours!",
"PL": "Rajd się już zaczął",
"FI": "Raidi on jo aktiivinen!",
"ES": "¡Ya está activa!"
@@ -2477,7 +3711,7 @@
"PT-BR": "Você não tem permissão para editar esta raid!",
"RU": "Вы не можете редактировать этот рейд!",
"NO": "Du har ikke tillatelse til å redigere dette raidet!",
- "FR": "Tu n'es pas autorisé à modifier ce raid",
+ "FR": "Vous n'êtes pas autorisé à modifier ce raid!",
"PL": "Nie masz uprawnień aby edytować Rajd!",
"FI": "Et voi muuttaa tätä raidia!",
"ES": "¡No tienes permiso para editar esta incursión!"
@@ -2490,7 +3724,7 @@
"PT-BR": "Nenhuma raid ativa encontrada no sistema!",
"RU": "Не найдено активных рейдов в системе!",
"NO": "Ingen aktive raid i systemet!",
- "FR": "Aucun raid en cours trouvé dans le système",
+ "FR": "Aucun raid en cours n'a été trouvé dans le système!",
"PL": "W tym momencie nie ma żadnych aktywnych Rajdów w systemie",
"FI": "Järjestelmästä ei löytynyt aktiivisia raideja!",
"ES": "¡No se han encontrado incursiones activas en el sistema!"
@@ -2503,7 +3737,7 @@
"PT-BR": "Nenhuma das raids ativas foi compartilhada!",
"RU": "Активными рейдами не делились!",
"NO": "Ingen av de aktive raidene ble delt!",
- "FR": "Aucun raid en cours n'a été partagé",
+ "FR": "Aucun raid en cours n'a été partagé!",
"PL": "Żaden z aktywnych rajdów nie został udostępniony!",
"FI": "Yhtäkään aktiivista raidia ei ole jaettu!",
"ES": "¡Ninguna de las incursiones activas fue compartida!"
@@ -2516,7 +3750,7 @@
"PT-BR": "Nenhuma raid ativa no momento!",
"RU": "Нету текущих активных рейдов!",
"NO": "Det er ingen aktive raid akkurat nå!",
- "FR": "Aucun raid en cours",
+ "FR": "Aucun raid en cours actuellement!",
"PL": "Brak aktywnych Rajdów w tej chwili!",
"FI": "Ei aktiivisia raideja tällä hetkellä!",
"ES": "¡Actualmente no hay incursiones activas!"
@@ -2529,7 +3763,7 @@
"PT-BR": "Pokemon salvo ",
"RU": "Покемон сохранен:",
"NO": "Pokemon lagret:",
- "FR": "Pokémon enregistré",
+ "FR": "Pokémon enregistré: ",
"PL": "Pokemon zapisany:",
"FI": "Pokemoni tallennettu:",
"ES": "Pokémon guardado:"
@@ -2542,7 +3776,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Modifier Pokémon",
"PL": "TRANSLATE",
"FI": "Muuta Pokemonia",
"ES": "Editar Pokémon"
@@ -2555,7 +3789,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Afficher, modifier et importer des boss de raid",
"PL": "TRANSLATE",
"FI": "Listaa, muuta ja tuo raidibosseja",
"ES": "Ver, editar e importar jefes de incursión"
@@ -2568,7 +3802,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Afficher les boss de raid actuels",
"PL": "TRANSLATE",
"FI": "Listaa tämänhetkiset raidibossit",
"ES": "Ver actuales jefes de incursión"
@@ -2581,7 +3815,7 @@
"PT-BR": "Lista de todos os Pokémon.",
"RU": "Список всех покемонов",
"NO": "Liste over alle pokemon",
- "FR": "Liste de tous les Pokémon",
+ "FR": "Liste de tous les Pokémon.",
"PL": "Lista wszystkich Pokemonów.",
"FI": "Listaa kaikki Pokemonit.",
"ES": "Lista de todos los Pokémon."
@@ -2594,7 +3828,7 @@
"PT-BR": "Erro! Nenhum pokemon encontrado!",
"RU": "Ошибка! Покемон не найден!",
"NO": "Feil: Ingen pokemon funnet!",
- "FR": "Erreur, aucun Pokémon trouvé !",
+ "FR": "Erreur! Aucun Pokémon trouvé!",
"PL": "Błąd! Pokemona nie znaleziono!",
"FI": "Virhe! Pokemoneja ei löytynyt!",
"ES": "¡Error! ¡No se encontró ningún Pokémon!"
@@ -2607,7 +3841,7 @@
"PT-BR": "Selecione o chefe de raid para modificar:",
"RU": "Выберите рейд босса для редактирования",
"NO": "Velg raid boss som skal redigeres:",
- "FR": "Sélectionne un boss de raid à modifier",
+ "FR": "Sélectionnez un boss de raid à modifier:",
"PL": "Wybierz Bossa Rajdu żeby edytować:",
"FI": "Valitse raidibossi muokattavaksi:",
"ES": "Selecciona jefe de incursión para editar:"
@@ -2620,7 +3854,7 @@
"PT-BR": "Nível da reide",
"RU": "Уровень рейда",
"NO": "Raid level",
- "FR": "Niveau du raid",
+ "FR": "Niveau de raid",
"PL": "Poziom Rajdu",
"FI": "Raidin taso",
"ES": "Nivel de incursión"
@@ -2633,7 +3867,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Tous les niveaux de raid",
"PL": "TRANSLATE",
"FI": "Kaikki raiditasot",
"ES": "Todos niveles de incursión"
@@ -2659,7 +3893,7 @@
"PT-BR": "Nível atual da reide",
"RU": "Текущий уровень рейда",
"NO": "Nåværende raid level:",
- "FR": "Niveau actuel du raid",
+ "FR": "Niveau actuel de raid:",
"PL": "Aktualny poziom Rajdu:",
"FI": "Nykyinen raiditaso:",
"ES": "Nivel de incursión actual:"
@@ -2672,7 +3906,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Nouveau statut",
"PL": "TRANSLATE",
"FI": "Uusi arvo",
"ES": "Nuevo estado"
@@ -2685,7 +3919,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Statut actuel:",
"PL": "TRANSLATE",
"FI": "Nykyinen arvo:",
"ES": "Estado actual:"
@@ -2698,7 +3932,7 @@
"PT-BR": "Selecione a opção para modificar:",
"RU": "Выберите функцию для изменения:",
"NO": "Velg egenskap som skal endres:",
- "FR": "Sélectionne l'option à changer",
+ "FR": "Sélectionnez l'option à modifier:",
"PL": "Wybierz aby edytować:",
"FI": "Valitse muutettava ominaisuus:",
"ES": "Selecciona la característica a cambiar:"
@@ -2711,7 +3945,7 @@
"PT-BR": "PC:",
"RU": "CP",
"NO": "CP:",
- "FR": "PC",
+ "FR": "PC:",
"PL": "CP",
"FI": "CP:",
"ES": "PC:"
@@ -2724,7 +3958,7 @@
"PT-BR": "Min PC",
"RU": "Min CP",
"NO": "Min CP",
- "FR": "PC Min",
+ "FR": "PC min.",
"PL": "Min CP",
"FI": "Min CP",
"ES": "Mín. PC"
@@ -2737,7 +3971,7 @@
"PT-BR": "Max PC",
"RU": "Max CP",
"NO": "Maks CP",
- "FR": "PC Max",
+ "FR": "PC max.",
"PL": "Max CP",
"FI": "Max CP",
"ES": "Máx. PC"
@@ -2750,7 +3984,7 @@
"PT-BR": "PC mín. potenciado",
"RU": "Min boosted CP",
"NO": "Min boostet CP",
- "FR": "PC Min boosté",
+ "FR": "PC min. renforcés",
"PL": "Min boosted CP",
"FI": "Min buustattu CP",
"ES": "Mín. PC potenciado"
@@ -2763,7 +3997,7 @@
"PT-BR": "PC máx. potenciado",
"RU": "Max boosted CP",
"NO": "Maks boostet CP",
- "FR": "PC Max boosté",
+ "FR": "PC max. renforcés",
"PL": "Max Boosted CP",
"FI": "Max buustattu CP",
"ES": "Máx. PC potenciado"
@@ -2776,7 +4010,7 @@
"PT-BR": "PC atual:",
"RU": "Текущий CP:",
"NO": "Nåværende CP:",
- "FR": "PC actuel",
+ "FR": "PC actuels:",
"PL": "Aktualne CP",
"FI": "Nykyinen CP:",
"ES": "PC actual:"
@@ -2802,7 +4036,7 @@
"PT-BR": "Clima atual:",
"RU": "Текущая погода:",
"NO": "Værforhold:",
- "FR": "Météo actuelle",
+ "FR": "Météo actuelle:",
"PL": "Aktualna pogoda:",
"FI": "Tämänhetkinen sää:",
"ES": "Clima actual:"
@@ -2815,7 +4049,7 @@
"PT-BR": "Novo clima:",
"RU": "Новая погода:",
"NO": "Været har endret seg:",
- "FR": "Nouvelle météo",
+ "FR": "Nouvelle météo:",
"PL": "Nowa pogoda:",
"FI": "Uusi sää:",
"ES": "Nuevo clima:"
@@ -2828,7 +4062,7 @@
"PT-BR": "Quanto tempo a reide vai durar",
"RU": "Как долго рейд будет идти?",
"NO": "Hvor lenge varer raidet?",
- "FR": "Dans combien de temps termine le raid ?",
+ "FR": "Dans combien de temps se termine le raid?",
"PL": "Jak długo Rajd będzie trwać?",
"FI": "Kauanko raidi kestää?",
"ES": "¿Cuánto durará la incursión?"
@@ -2848,13 +4082,13 @@
},
"select_gym_name": {
"NL": "Selecteer Gym:",
- "DE": "Bitte Gym auswählen:",
+ "DE": "Bitte Arena auswählen:",
"EN": "Please select Gym:",
"IT": "Seleziona Palestra:",
"PT-BR": "Escolha o ginásio:",
"RU": "Выберите Гим:",
"NO": "Velg Gym:",
- "FR": "Sélectionne l'arène",
+ "FR": "Sélectionnez l'arène:",
"PL": "Wybierz Arene:",
"FI": "Valitse sali:",
"ES": "Por favor, selecciona el gimnasio:"
@@ -2867,7 +4101,7 @@
"PT-BR": "Bora arrasar!",
"RU": "А вот и мы!",
"NO": "Kjør på!",
- "FR": "C'est parti !",
+ "FR": "C'est parti!",
"PL": "Zaczynamy!",
"FI": "Nyt mennään!",
"ES": "¡Aquí vamos!"
@@ -2893,7 +4127,7 @@
"PT-BR": "Coordenadas enviadas com sucesso!",
"RU": "Координаты успешно отправлены!",
"NO": "Koordinater ble lagt til!",
- "FR": "Coordonnées créés avec succès ",
+ "FR": "Coordonnées envoyées avec succès!",
"PL": "Koordynaty dodano pomyślnie!",
"FI": "Koordinaatit lähetetty onnistuneesti!",
"ES": "¡Coordenadas enviadas con éxito!"
@@ -2906,7 +4140,7 @@
"PT-BR": "Atualizar chefe da reide",
"RU": "Обновить рейд босса",
"NO": "Oppdater raid boss",
- "FR": "Mise à jour boss de raid",
+ "FR": "Mettre à jour boss de raid",
"PL": "Aktualizacja Bossa Rajdu",
"FI": "Päivitä raidibossi",
"ES": "Actualizar jefe de incursión"
@@ -2919,7 +4153,7 @@
"PT-BR": "Atualizar Pokemon",
"RU": "Обновить Покемона",
"NO": "Oppdater Pokemon",
- "FR": "Mise à jour Pokémon",
+ "FR": "Mettre à jour Pokémon",
"PL": "Aktualizacja Pokemona",
"FI": "Päivitä Pokemoni",
"ES": "Actualizar Pokémon"
@@ -2945,7 +4179,7 @@
"PT-BR": "Por favor, antes me envie a localização.",
"RU": "Или отправить мне локацию",
"NO": "Eller send meg lokasjonen din ved å trykke på bindersen",
- "FR": "Ou envoi moi la localisation",
+ "FR": "Ou envoyez-moi la localisation.",
"PL": "Albo wyślij mi swoje położenie",
"FI": "Tai lähetä minulle sijainti.",
"ES": "O envíame una ubicación."
@@ -2958,7 +4192,7 @@
"PT-BR": "Ou escolha uma raid por ginásio:",
"RU": "Сделать рейд, выбрав гим:",
"NO": "Opprett raid ved å velge fra gym listen",
- "FR": "Faire une sélection de raid par arène",
+ "FR": "Créer un raid en sélectionnant une arène:",
"PL": "Wygeneruj nowy Rajd, wybierając Arene:",
"FI": "Luo raidi salivalinnan mukaan:",
"ES": "Crear incursión con selección de gimnasio:"
@@ -3010,7 +4244,7 @@
"PT-BR": "Time do ginásio escolhido para",
"RU": "Команду гима:",
"NO": "Gym Team endret til:",
- "FR": "Couleur d'arène réglée sur",
+ "FR": "Équipe d'arène réglée sur:",
"PL": "Kolor Areny zmieniony na:",
"FI": "Salin joukkueeksi asetettu:",
"ES": "Equipo de gimnasio puesto en:"
@@ -3023,7 +4257,7 @@
"PT-BR": "Nome de time inválido - escreva: Mystic, Valor, Instinct ou Blue, Red, Yellow",
"RU": "Неверное имя команд - напишите: Mystic, Valor, Instinct или Синий, Красный, Желтый",
"NO": "Ugyldig team navn - skriv: Mystic, Valor, Instinct or Blue, Red, Yellow",
- "FR": "Couleur invalide - écrit : Sagesse, Bravoure, Intuition ou Bleu, Rouge, Jaune",
+ "FR": "Équipe invalide - écrivez : Sagesse, Bravoure, Intuition ou Bleu, Rouge, Jaune ",
"PL": "Zła nazwa Teamu - napisz: niebieski, czerwony albo żółty",
"FI": "Virheellinen joukkueen nimi - kirjoita: Mystic, Valor, Instinct tai Blue, Red, Yellow",
"ES": "Nombre de equipo invalido - escribe: Sabiduría, Valor, Instinto o Azul, Rojo, Amarillo"
@@ -3036,7 +4270,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Utilisez les commandes suivantes pour modifier davantage l'arène:",
"PL": "TRANSLATE",
"FI": "Käytä seuraavia komentoja muokataksesi salia enemmän:",
"ES": "Utiliza los siguientes comandos para editar más el gimnasio:"
@@ -3049,49 +4283,36 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Pour obtenir l'identifiant de l'arène et plus de détails, utilisez la commande /gym.",
"PL": "TRANSLATE",
"FI": "Saataksesi salin id numeron tai muita tietoja, käytä /gym -komentoa.",
"ES": "Para obtener la identificación y más detalles del gimnasio, usa el comando /gym."
},
- "gym_name_instructions": {
- "NL": "Om de gym naam aan te passen stuur /gymname gym id, nieuwe gym naam!",
- "DE": "Zum Ändern eines Arena-Namen bitte /gymname Arena-ID, neuer Arena-Name eingeben!",
- "EN": "To change the name of a gym please enter /gymname gym id, new gym name!",
- "IT": "TRANSLATE",
- "PT-BR": "TRANSLATE",
- "RU": "TRANSLATE",
- "NO": "TRANSLATE",
- "FR": "TRANSLATE",
- "PL": "TRANSLATE",
- "FI": "Vaihtaaksesi salin nimeä komenna /gymname salin id, uusi salin nimi!",
- "ES": "Para cambiar el nombre de un gimnasio, escribe /gymname gym id, nuevo nombre de gimnasio."
- },
"gym_name_example": {
- "NL": "Als voorbeeld: /gymname 34, Markt 61, 3131 CR Vlaardingen ",
- "DE": "Zum Beispiel: /gymname 34, Wasserfall im Park",
- "EN": "For example: /gymname 34, Waterfall in the park!",
+ "NL": "Als voorbeeld: /gymname Markt 61, 3131 CR Vlaardingen ",
+ "DE": "Zum Beispiel: /gymname Wasserfall im Park",
+ "EN": "For example: /gymname Waterfall in the park!",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Par exemple: /gymname Fontaine du parc!",
"PL": "TRANSLATE",
- "FI": "Esimerkiksi: /gymname 34, Vapauden Muistomerkki!",
- "ES": "Por ejemplo: /gymname 34, Waterfall in the park"
+ "FI": "Esimerkiksi: /gymname Vapauden Muistomerkki!",
+ "ES": "Por ejemplo: /gymname Waterfall in the park"
},
"gym_id_name_missing": {
- "NL": "Error! Gym id of naam mist!",
- "DE": "Fehler! Arena-ID oder Name fehlt!",
- "EN": "Error! Gym id or name is missing!",
+ "NL": "Error! Gym naam mist!",
+ "DE": "Fehler! Arena-Name fehlt!",
+ "EN": "Error! Gym name is missing!",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Erreur! Le nom de l'arène est manquant!",
"PL": "TRANSLATE",
- "FI": "Virhe! Salin id numero tai nimi puuttuu!",
- "ES": "¡Error! ¡Faltan gym id o nombre!"
+ "FI": "Virhe! Salin nimi puuttuu!",
+ "ES": "TRANSLATE"
},
"gym_name_updated": {
"NL": "Gym naam aangepast.",
@@ -3101,11 +4322,37 @@
"PT-BR": "Nome do ginásio atualizado.",
"RU": "Название гима обновлено.",
"NO": "Gym navn oppdatert.",
- "FR": "Nom de l'arène mis à jour",
+ "FR": "Nom de l'arène mis à jour.",
"PL": "Nazwa Areny zaktualizowana",
"FI": "Salin nimi päivitetty.",
"ES": "Nombre del gimnasio actualizado."
},
+ "gym_name_edit": {
+ "NL": "Gym naam aanpassen",
+ "DE": "Arena-Name bearbeiten",
+ "EN": "Edit gym name",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Modifier le nom de l'arène",
+ "PL": "TRANSLATE",
+ "FI": "Muokkaa salin nimeä",
+ "ES": "TRANSLATE"
+ },
+ "gym_name_instructions": {
+ "NL": "Stuur me de gym naam:",
+ "DE": "Arena-Name eingeben:",
+ "EN": "Send me the gym name:",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Envoyez-moi le nom de l'arène:",
+ "PL": "TRANSLATE",
+ "FI": "Lähetä minulle salin nimi:",
+ "ES": "TRANSLATE"
+ },
"overview_share": {
"NL": "Overzicht delen",
"DE": "Übersicht teilen",
@@ -3140,7 +4387,7 @@
"PT-BR": "Mostrar raids ativas como lista",
"RU": "Показать активные рейды списком",
"NO": "Vis aktive raid som liste",
- "FR": "Voir les raids en cours",
+ "FR": "Afficher les raids en cours sous forme de liste",
"PL": "Pokaż liste aktywnych rajdów",
"FI": "Näytä aktiiviset raidit listana",
"ES": "Mostrar incursiones activas como lista"
@@ -3153,7 +4400,7 @@
"PT-BR": "Compartilhar / deletar detalhes de raid por chat",
"RU": "поделиться / удалить обзор рейда через чат",
"NO": "Del / slett raid oversikten per chat",
- "FR": "Partager / supprimer l'aperçu des raids par conversation",
+ "FR": "Partager / supprimer l'aperçu de raid par conversation",
"PL": "Udostępnij / usuń liste przez czat",
"FI": "Jaa / poista raidiyleiskatsaus per chatti",
"ES": "Compartir / eliminar la descripción general de la incursión por chat"
@@ -3192,7 +4439,7 @@
"PT-BR": "Deletar detalhe de raid para",
"RU": "Удалить обзор рейда для",
"NO": "Slett raid oversikt for",
- "FR": "Supprimer l'aperçu du raid pour",
+ "FR": "Supprimer l'aperçu de raid pour",
"PL": "Usuń podgląd Rajdu dla",
"FI": "Poista raidiyleiskatsaus chatista",
"ES": "Eliminar descripción general de incursión para"
@@ -3205,7 +4452,7 @@
"PT-BR": "Nenhum detalhe de raid encontrado no sistema!",
"RU": "В системе нет обзора рейдов!",
"NO": "Ingen oppsummering funnet i systemet!",
- "FR": "Aucun aperçu de raid trouvé dans le système",
+ "FR": "Aucun aperçu de raid trouvé dans le système!",
"PL": "Brak podglądów Rajdów w systemie!",
"FI": "Järjestelmästä ei löytynyt raidi yleiskatsauksia!",
"ES": "¡No se han encontrado descripciones generales en el sistema!"
@@ -3218,7 +4465,7 @@
"PT-BR": "Detalhe de raid deletado com sucesso!",
"RU": "Обзор рейдов успешно удален!",
"NO": "Raid oppsummeringen ble slettet!",
- "FR": "L'aperçu de raid a été supprimé",
+ "FR": "L'aperçu de raid a été supprimé!",
"PL": "Podgląd Rajdu usunięty!",
"FI": "Raidi yleiskatsaus poistettu onnistuneesti!",
"ES": "¡Descripción general eliminada con éxito!"
@@ -3231,7 +4478,7 @@
"PT-BR": "O deletamento dos detalhes da raid foi cancelado!",
"RU": "Удаление обзора рейда было отменено!",
"NO": "Sletting av raid oppsummeringen ble avbrutt!",
- "FR": "La suppression de l'aperçu du raid a été annulée",
+ "FR": "La suppression de l'aperçu de raid a été annulée!",
"PL": "Usuwanie podglądu anulowane!",
"FI": "Raidi yleiskatsauksen poisto peruutettiin!",
"ES": "¡Eliminación de la descripción general de la incursión cancelada!"
@@ -3257,7 +4504,7 @@
"PT-BR": "Realmente deletar esta raid?",
"RU": "Действительно удалить этот рейд?",
"NO": "Skal du virkelig slette raidet?",
- "FR": "Supprimer ce raid ?",
+ "FR": "Vraiment supprimer ce raid?",
"PL": "Na pewno usunąć ten Rajd?",
"FI": "Varmasti poista tämä raidi?",
"ES": "¿De verdad eliminar esta incursión?"
@@ -3270,7 +4517,7 @@
"PT-BR": "O deletamento da raid foi cancelado!",
"RU": "Удаление рейда было отменено!",
"NO": "Sletting av raidet ble avbrutt!",
- "FR": "La suppression du raid a été annulée",
+ "FR": "La suppression du raid a été annulée!",
"PL": "Usuwanie Rajdu anulowane!",
"FI": "Raidin poisto peruutettiin!",
"ES": "¡Eliminación de la incursión fue cancelada!"
@@ -3283,7 +4530,7 @@
"PT-BR": "Raid deletado com sucesso!",
"RU": "Рейд был успешно удален!",
"NO": "Raidet ble slettet",
- "FR": "Le raid a été annulé",
+ "FR": "Le raid a été supprimé avec succès!",
"PL": "Rajd usunięty!",
"FI": "Raidi poistettiin onnistuneesti!",
"ES": "¡Incursión eliminada con éxito!"
@@ -3296,7 +4543,7 @@
"PT-BR": "A qualquer momento",
"RU": "В любое время",
"NO": "Alle tider passer",
- "FR": "A tout moment",
+ "FR": "À tout moment",
"PL": "W każdej chwili",
"FI": "Milloin tahansa",
"ES": "Cualquiera hora"
@@ -3322,7 +4569,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Notifications de raid désactivées!",
"PL": "TRANSLATE",
"FI": "Raidihäly pois käytöstä!",
"ES": "¡Alertas de incursión desactivadas!"
@@ -3335,33 +4582,33 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Notifications de raid activées!",
"PL": "TRANSLATE",
"FI": "Raidihäly käytössä!",
"ES": "¡Alertas de incursión activadas!"
},
"switch_alarm_on": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
+ "NL": "Zet automatische raid alarm aan",
+ "DE": "Automatische Raid-Alarme aktivieren",
"EN": "Enable automatic raid alerts",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Activer les notifications de raid automatiques",
"PL": "TRANSLATE",
"FI": "Automaattinen raidihäly päälle",
"ES": "Activar alertas automáticas de incursiones"
},
"switch_alarm_off": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
+ "NL": "Zet automatisch raid alarm uit",
+ "DE": "Automatische Raid-Alarme deaktivieren",
"EN": "Disable automatic raid alerts",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Désactiver les notifications de raid automatiques",
"PL": "TRANSLATE",
"FI": "Automaattinen raidihäly pois päältä",
"ES": "Desactivar alertas automáticas de incursiones"
@@ -3374,20 +4621,20 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Dresseur supplémentaire!",
"PL": "TRANSLATE",
"FI": "Uusi osallistuja!",
"ES": "¡Entrenador adicional!"
},
"alert_add_alien_trainer": {
"NL": "Een gebruiker is uitgenodigd buiten deze groep!",
- "DE": "TRANSLATE",
+ "DE": "Trainer lädt Spieler außerhalb der Gruppe ein!",
"EN": "User is inviting a player from outside the group!",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "L'utilisateur invite un dresseur en dehors du groupe!",
"PL": "TRANSLATE",
"FI": "Pelaaja kutsuu kaverin ryhmän ulkopuolelta!",
"ES": "¡Usuario está invitando a un entrenador fuera del grupo!"
@@ -3400,7 +4647,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Dresseur en retard!",
"PL": "TRANSLATE",
"FI": "Myöhästyvä osallistuja!",
"ES": "¡Entrenador tarda!"
@@ -3413,7 +4660,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Annulation!",
"PL": "TRANSLATE",
"FI": "Peruutus!",
"ES": "¡Cancelación!"
@@ -3426,7 +4673,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Vient pour",
"PL": "TRANSLATE",
"FI": "Ilmoittautuneet,",
"ES": "Viene para"
@@ -3439,7 +4686,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Ne vient PAS pour",
"PL": "TRANSLATE",
"FI": "Peruuttaneet,",
"ES": "NO viene para"
@@ -3447,14 +4694,14 @@
"alert_every_poke": {
"NL": "Komt voor",
"DE": "Kommt für jeden Raid-Boss",
- "EN": "Coming for",
+ "EN": "Coming for any boss",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Vient pour tout boss de raid",
"PL": "TRANSLATE",
- "FI": "Ilmoittautuneet,",
+ "FI": "Osallistuu mihin tahansa bossiin",
"ES": "Viene para"
},
"alert_new_att": {
@@ -3465,7 +4712,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Nouvelle participation!",
"PL": "TRANSLATE",
"FI": "Uusi osallistuja!",
"ES": "¡Nueva participación!"
@@ -3478,7 +4725,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Participation à distance!",
"PL": "TRANSLATE",
"FI": "Etäosallistuminen!",
"ES": "¡Participación remota!"
@@ -3491,7 +4738,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Pas plus de participants à distance!",
"PL": "TRANSLATE",
"FI": "Ei enää etäosallistujia!",
"ES": "¡No más participación remota!"
@@ -3504,7 +4751,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Le raid commence maintenant!",
"PL": "TRANSLATE",
"FI": "Raidi alkaa nyt!",
"ES": "¡La incursión empieza ahora!"
@@ -3517,7 +4764,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Voici comment participer au combat:",
"PL": "TRANSLATE",
"FI": "Näin pääset taisteluun:",
"ES": "Cómo entrar en la batalla:"
@@ -3530,7 +4777,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Groupe de raid privé!",
"PL": "TRANSLATE",
"FI": "Yksityinen raidiryhmä!",
"ES": "¡Grupo de incursión privado!"
@@ -3543,7 +4790,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Groupe de raid publique!",
"PL": "TRANSLATE",
"FI": "Julkinen raidiryhmä!",
"ES": "¡Grupo de incursión público!"
@@ -3556,7 +4803,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Nouvelle heure de participation!",
"PL": "TRANSLATE",
"FI": "Uusi aika!",
"ES": "¡Nueva hora de participación!"
@@ -3569,7 +4816,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Boss de raid mis à jour!",
"PL": "TRANSLATE",
"FI": "Raidibossi päivitetty!",
"ES": "¡Jefe de incursión actualizado!"
@@ -3582,59 +4829,59 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Pas plus de dresseurs supplémentaires!",
"PL": "TRANSLATE",
"FI": "Ei ylimääräisiä kouluttajia!",
"ES": "¡Sin entrenadores adicionales!"
},
"alert_want_invite": {
"NL": "Wenst uitgenodigd te worden.",
- "DE": "TRANSLATE",
+ "DE": "Möchte eingeladen werden.",
"EN": "Wishes to be invited.",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Souhaite être invité.",
"PL": "TRANSLATE",
"FI": "Toivoo tulevansa kutsutuksi.",
"ES": "Desea ser invitado."
},
"alert_no_want_invite": {
"NL": "Wil niet langer worden uitgenodigd.",
- "DE": "TRANSLATE",
+ "DE": "Möchte nicht länger eingeladen werden.",
"EN": "No longer wishes to be invited.",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Ne souhaite plus être invité.",
"PL": "TRANSLATE",
"FI": "Ei enää toivo kutsua.",
"ES": "Ya no desea ser invitado."
},
"alert_can_invite": {
"NL": "Doet niet mee, maar kan wel invites versturen.",
- "DE": "TRANSLATE",
+ "DE": "Spielt selbst nicht mit, kann aber einladen.",
"EN": "Is not attending but can send invites.",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Ne participe pas mais peut envoyer des invitations.",
"PL": "TRANSLATE",
"FI": "Ei osallistu raidiin, mutta voi lähettää kutsuja.",
"ES": "No asiste pero puede enviar invitaciones."
},
"alert_no_can_invite": {
"NL": "Kan niet langer andere uitnodigingen versturen.",
- "DE": "TRANSLATE",
+ "DE": "Kann nicht länger andere einladen.",
"EN": "Is no longer able to invite others.",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Ne peut plus envoyer des invitations.",
"PL": "TRANSLATE",
"FI": "Ei enää pysty kutsumaan muita.",
"ES": "Ya no puede invitar a otros."
@@ -3647,46 +4894,46 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Événement",
"PL": "TRANSLATE",
"FI": "Tapahtuma",
"ES": "Evento"
},
"event_note": {
"NL": "Event info",
- "DE": "Event Notiz",
+ "DE": "Event-Notiz",
"EN": "Event note",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Notice d'événement",
"PL": "TRANSLATE",
"FI": "Tapahtuman lisätiedot",
"ES": "Nota de evento"
},
"event_note_add": {
"NL": "Voeg event infot toe",
- "DE": "Event Notiz hinzufügen",
+ "DE": "Event-Notiz hinzufügen",
"EN": "Add event note",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Ajouter notice d'événement",
"PL": "TRANSLATE",
"FI": "Lisää raiditapahtumaan lisätietoja",
"ES": "Añadir nota de evento"
},
"event_note_edit": {
"NL": "Wijzig de event info",
- "DE": "Event Notiz ändern",
+ "DE": "Event-Notiz bearbeiten",
"EN": "Edit event note",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Modifier notice d'événement",
"PL": "TRANSLATE",
"FI": "Muokkaa raiditapahtuman lisätietoja",
"ES": "Editar nota de evento"
@@ -3699,11 +4946,154 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Ajouter plus d'informations pour cette annonce d'événement. (par exemple: itinéraire)",
"PL": "TRANSLATE",
"FI": "Lisää ilmoituskohtaisia lisätietoja tapahtumaan liittyen. (esim. reitti)",
"ES": "Agrega más información para este anuncio específico sobre el evento. (por ejemplo: ruta)"
},
+ "events_manage": {
+ "NL": "Event manager",
+ "DE": "Event verwalten",
+ "EN": "Manage events",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Gérer les événements",
+ "PL": "TRANSLATE",
+ "FI": "Hallitse tapahtumia",
+ "ES": "TRANSLATE"
+ },
+ "events_create": {
+ "NL": "Maak een nieuw event",
+ "DE": "Neues Event erstellen",
+ "EN": "Create a new event",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Créer un nouvel événement",
+ "PL": "TRANSLATE",
+ "FI": "Luo uusi tapahtuma",
+ "ES": "TRANSLATE"
+ },
+ "events_created": {
+ "NL": "Event succesvol aangemaakt!",
+ "DE": "Event erfolgreich erstellt!",
+ "EN": "Event created succesfully!",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Événement créé avec succès!",
+ "PL": "TRANSLATE",
+ "FI": "Tapahtuma luotu onnistuneesti!",
+ "ES": "TRANSLATE"
+ },
+ "events_give_name": {
+ "NL": "Geef het event een naam",
+ "DE": "Event-Name eingeben",
+ "EN": "Give the event a name",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Nommer l'événement",
+ "PL": "TRANSLATE",
+ "FI": "Anna tapahtuman nimi",
+ "ES": "TRANSLATE"
+ },
+ "events_give_description": {
+ "NL": "Geef de omschrijving van het event",
+ "DE": "Event-Beschreibung eingeben",
+ "EN": "Give the event a description",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Décrire l'événement",
+ "PL": "TRANSLATE",
+ "FI": "Anna tapahtuman lisätiedot",
+ "ES": "TRANSLATE"
+ },
+ "events_no_description": {
+ "NL": "Geen omschrijving",
+ "DE": "Keine Beschreibung",
+ "EN": "No description",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Aucune description",
+ "PL": "TRANSLATE",
+ "FI": "Ei kuvausta",
+ "ES": "TRANSLATE"
+ },
+ "events_edit_name": {
+ "NL": "Wijzig event naam",
+ "DE": "Event-Name bearbeiten",
+ "EN": "Edit event name",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Modifier le nom de l'événement",
+ "PL": "TRANSLATE",
+ "FI": "Muokkaa tapahtuman nimeä",
+ "ES": "TRANSLATE"
+ },
+ "events_edit_description": {
+ "NL": "Wijzig de event omschrijving",
+ "DE": "Event-Beschreibung bearbeiten",
+ "EN": "Edit event description",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Modifier la description de l'événement",
+ "PL": "TRANSLATE",
+ "FI": "Muokkaa tapahtuman kuvausta",
+ "ES": "TRANSLATE"
+ },
+ "events_edit_raid_poll": {
+ "NL": "Wijzig event raid poll",
+ "DE": "Event-Raid-Abstimmung bearbeiten",
+ "EN": "Edit event raid poll",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Modifier l'annonce de l'événement de raid",
+ "PL": "TRANSLATE",
+ "FI": "Muokkaa tapahtuman raidi-ilmoitusta",
+ "ES": "TRANSLATE"
+ },
+ "events_delete": {
+ "NL": "Verwijder event",
+ "DE": "Event löschen",
+ "EN": "Delete event",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Supprimer l'événement",
+ "PL": "TRANSLATE",
+ "FI": "Poista tapahtuma",
+ "ES": "TRANSLATE"
+ },
+ "events_delete_confirmation": {
+ "NL": "Wil je dit event echt verwijderen?",
+ "DE": "Dieses Event wirklich löschen?",
+ "EN": "Do you really want to delete this event?",
+ "IT": "TRANSLATE",
+ "PT-BR": "TRANSLATE",
+ "RU": "TRANSLATE",
+ "NO": "TRANSLATE",
+ "FR": "Vraiment supprimer cet événement?",
+ "PL": "TRANSLATE",
+ "FI": "Haluatko varmasti poistaa tämän tapahtuman?",
+ "ES": "TRANSLATE"
+ },
"Participate": {
"NL": "Deelnemer",
"DE": "Teilnehmen",
@@ -3712,7 +5102,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Participer",
"PL": "TRANSLATE",
"FI": "Osallistu",
"ES": "Participar"
@@ -3725,7 +5115,7 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Participe",
"PL": "TRANSLATE",
"FI": "Osallistuu",
"ES": "Participando"
@@ -3738,87 +5128,87 @@
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Vous n'avez pas encore enregistré vos informations de dresseur. Voulez-vous le faire maintenant?",
"PL": "TRANSLATE",
"FI": "Et ole vielä tallentanut tietoja pelihahmostasi. Haluaisitko tehdä sen nyt?",
"ES": "Aún no has guardado la información de tu entrenador. ¿Te gustaría hacerlo ahora?"
},
"history_title": {
"NL": "Zie raid poll geschiedenis",
- "DE": "TRANSLATE",
+ "DE": "Raid-Historie ansehen",
"EN": "View raid poll history.",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Afficher l'historique des annonces de raid.",
"PL": "TRANSLATE",
"FI": "Katsele vanhoja raidi-ilmoituksia.",
"ES": "Ver historial de anuncios de incursiones."
},
"history_displaying_month": {
"NL": "Momenteel worden er raids weergegeven voor",
- "DE": "TRANSLATE",
+ "DE": "Zeigt derzeit Raids an für",
"EN": "Currently displaying raids for",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Affichage en cours des raids pour",
"PL": "TRANSLATE",
"FI": "Tällä hetkellä näytetään",
"ES": "Actualmente se muestran incursiones para"
},
"history_select_raid": {
"NL": "Selecteer raid",
- "DE": "TRANSLATE",
+ "DE": "Raid auswählen",
"EN": "Select raid",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Choisir un raid",
"PL": "TRANSLATE",
"FI": "Valitse raidi",
"ES": "Selecciona incursión"
},
"history_no_raids_found": {
"NL": "Geen raids met spelers gevonden!",
- "DE": "TRANSLATE",
+ "DE": "Keine Raids mit Teilnehmern gefunden!",
"EN": "No raids with attendees found!",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Aucun raid avec participants trouvé!",
"PL": "TRANSLATE",
"FI": "Yhtään raidia ei löytynyt jossa olisi osallistujia!",
"ES": "¡No se encontraron incursiones con los asistentes!"
},
"date": {
- "NL": "TRANSLATE",
+ "NL": "Datum",
"DE": "Datum",
"EN": "Date",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Date",
"PL": "TRANSLATE",
"FI": "Päivämäärä",
"ES": "Fecha"
},
"current_gymarea": {
- "NL": "TRANSLATE",
- "DE": "TRANSLATE",
+ "NL": "Gym gebied",
+ "DE": "Aktuelles Arena-Gebiet",
"EN": "Current gymarea",
"IT": "TRANSLATE",
"PT-BR": "TRANSLATE",
"RU": "TRANSLATE",
"NO": "TRANSLATE",
- "FR": "TRANSLATE",
+ "FR": "Zone actuelle",
"PL": "TRANSLATE",
"FI": "Salit alueelta",
"ES": "Zona de gimnasio actual"
}
-}
\ No newline at end of file
+}
diff --git a/core/lang/pokemon.json b/lang/pokemon.json
similarity index 83%
rename from core/lang/pokemon.json
rename to lang/pokemon.json
index b1470fd8..e524d521 100644
--- a/core/lang/pokemon.json
+++ b/lang/pokemon.json
@@ -138,7 +138,7 @@
},
"pokemon_id_24": {
"EN": "Arbok",
- "RU": "Арбок"
+ "RU": "Эрбок"
},
"pokemon_id_25": {
"EN": "Pikachu",
@@ -199,7 +199,7 @@
"pokemon_id_37": {
"EN": "Vulpix",
"FR": "Goupix",
- "RU": "Валпикс"
+ "RU": "Вульпикс"
},
"pokemon_id_38": {
"EN": "Ninetales",
@@ -402,7 +402,7 @@
"pokemon_id_73": {
"EN": "Tentacruel",
"DE": "Tentoxa",
- "RU": "Тентакрул"
+ "RU": "Тентакруэль"
},
"pokemon_id_74": {
"EN": "Geodude",
@@ -414,7 +414,7 @@
"EN": "Graveler",
"FR": "Gravalanch",
"DE": "Georok",
- "RU": "Гравелер"
+ "RU": "Грейвлер"
},
"pokemon_id_76": {
"EN": "Golem",
@@ -461,7 +461,7 @@
"FR": "Canarticho",
"DE": "Porenta",
"IT": "Farfetch’d",
- "RU": "Фарфетчд"
+ "RU": "Фарфетч'т"
},
"pokemon_id_84": {
"EN": "Doduo",
@@ -483,7 +483,7 @@
"EN": "Dewgong",
"FR": "Lamantine",
"DE": "Jugong",
- "RU": "Дьюгонг"
+ "RU": "Дюгонг"
},
"pokemon_id_88": {
"EN": "Grimer",
@@ -534,7 +534,7 @@
"EN": "Drowzee",
"FR": "Soporifik",
"DE": "Traumato",
- "RU": "Драузи"
+ "RU": "Дроузи"
},
"pokemon_id_97": {
"EN": "Hypno",
@@ -554,7 +554,7 @@
"EN": "Voltorb",
"FR": "Voltorbe",
"DE": "Voltobal",
- "RU": "Волторб"
+ "RU": "Вальторб"
},
"pokemon_id_101": {
"EN": "Electrode",
@@ -566,7 +566,7 @@
"EN": "Exeggcute",
"FR": "Noeunoeuf",
"DE": "Owei",
- "RU": "Эксегкьют"
+ "RU": "Экзегкьют"
},
"pokemon_id_103": {
"EN": "Exeggutor",
@@ -602,7 +602,7 @@
"EN": "Lickitung",
"FR": "Excelangue",
"DE": "Schlurp",
- "RU": "Ликитанг"
+ "RU": "Ликитунг"
},
"pokemon_id_109": {
"EN": "Koffing",
@@ -727,7 +727,7 @@
"EN": "Gyarados",
"FR": "Léviator",
"DE": "Garados",
- "RU": "Гиарадос"
+ "RU": "Гиардос"
},
"pokemon_id_131": {
"EN": "Lapras",
@@ -874,7 +874,7 @@
"pokemon_id_157": {
"EN": "Typhlosion",
"DE": "Tornupto",
- "RU": "Тайфложн"
+ "RU": "Тифложн"
},
"pokemon_id_158": {
"EN": "Totodile",
@@ -892,7 +892,7 @@
"EN": "Feraligatr",
"FR": "Aligatueur",
"DE": "Impergator",
- "RU": "Фералигейтор"
+ "RU": "Фералигатор"
},
"pokemon_id_161": {
"EN": "Sentret",
@@ -971,11 +971,11 @@
},
"pokemon_id_175": {
"EN": "Togepi",
- "RU": "Тогэпи"
+ "RU": "Тогепи"
},
"pokemon_id_176": {
"EN": "Togetic",
- "RU": "Тогэтик"
+ "RU": "Тогетик"
},
"pokemon_id_177": {
"EN": "Natu",
@@ -983,7 +983,7 @@
},
"pokemon_id_178": {
"EN": "Xatu",
- "RU": "Ксату"
+ "RU": "Зату"
},
"pokemon_id_179": {
"EN": "Mareep",
@@ -1010,7 +1010,7 @@
},
"pokemon_id_183": {
"EN": "Marill",
- "RU": "Мэрилл"
+ "RU": "Марилл"
},
"pokemon_id_184": {
"EN": "Azumarill",
@@ -1130,7 +1130,7 @@
"EN": "Pineco",
"FR": "Pomdepik",
"DE": "Tannza",
- "RU": "Пайнеко"
+ "RU": "Пинеко"
},
"pokemon_id_205": {
"EN": "Forretress",
@@ -1148,7 +1148,7 @@
"EN": "Gligar",
"FR": "Scorplane",
"DE": "Skorgla",
- "RU": "Глайгар"
+ "RU": "Глигар"
},
"pokemon_id_208": {
"EN": "Steelix",
@@ -1161,7 +1161,7 @@
},
"pokemon_id_210": {
"EN": "Granbull",
- "RU": "Грэнбулл"
+ "RU": "Гранбулл"
},
"pokemon_id_211": {
"EN": "Qwilfish",
@@ -1190,7 +1190,7 @@
"EN": "Sneasel",
"FR": "Farfuret",
"DE": "Sniebel",
- "RU": "Снизел"
+ "RU": "Снизель"
},
"pokemon_id_216": {
"EN": "Teddiursa",
@@ -1276,15 +1276,15 @@
},
"pokemon_id_231": {
"EN": "Phanpy",
- "RU": "Фэнпи"
+ "RU": "Фанпи"
},
"pokemon_id_232": {
"EN": "Donphan",
- "RU": "Донфэн"
+ "RU": "Донфан"
},
"pokemon_id_233": {
"EN": "Porygon2",
- "RU": "Поригон-2"
+ "RU": "Поригон2"
},
"pokemon_id_234": {
"EN": "Stantler",
@@ -1302,7 +1302,7 @@
"EN": "Tyrogue",
"FR": "Debugant",
"DE": "Rabauz",
- "RU": "Тайрог"
+ "RU": "Тироуг"
},
"pokemon_id_237": {
"EN": "Hitmontop",
@@ -1346,7 +1346,7 @@
},
"pokemon_id_245": {
"EN": "Suicune",
- "RU": "Суикун"
+ "RU": "Суйкун"
},
"pokemon_id_246": {
"EN": "Larvitar",
@@ -1356,7 +1356,7 @@
"pokemon_id_247": {
"EN": "Pupitar",
"FR": "Ymphect",
- "RU": "Пьюпитар"
+ "RU": "Пупитар"
},
"pokemon_id_248": {
"EN": "Tyranitar",
@@ -1452,7 +1452,7 @@
"EN": "Linoone",
"FR": "Linéon",
"DE": "Geradaks",
- "RU": "Лайнун"
+ "RU": "Линун"
},
"pokemon_id_265": {
"EN": "Wurmple",
@@ -1533,7 +1533,7 @@
"pokemon_id_278": {
"EN": "Wingull",
"FR": "Goélise",
- "RU": "Вингалл"
+ "RU": "Вингулл"
},
"pokemon_id_279": {
"EN": "Pelipper",
@@ -1544,7 +1544,7 @@
"EN": "Ralts",
"FR": "Tarsal",
"DE": "Trasla",
- "RU": "Ролтс"
+ "RU": "Ральтс"
},
"pokemon_id_281": {
"EN": "Kirlia",
@@ -1553,7 +1553,7 @@
"pokemon_id_282": {
"EN": "Gardevoir",
"DE": "Guardevoir",
- "RU": "Гардевойр"
+ "RU": "Гардевуар"
},
"pokemon_id_283": {
"EN": "Surskit",
@@ -1583,7 +1583,7 @@
"EN": "Slakoth",
"FR": "Parecool",
"DE": "Bummelz",
- "RU": "Слакот"
+ "RU": "Слякот"
},
"pokemon_id_288": {
"EN": "Vigoroth",
@@ -1645,7 +1645,7 @@
"EN": "Nosepass",
"FR": "Tarinor",
"DE": "Nasgnet",
- "RU": "Ноузпасс"
+ "RU": "Ноуспасс"
},
"pokemon_id_300": {
"EN": "Skitty",
@@ -1655,13 +1655,13 @@
"pokemon_id_301": {
"EN": "Delcatty",
"DE": "Enekoro",
- "RU": "Делкатти"
+ "RU": "Деликэтти"
},
"pokemon_id_302": {
"EN": "Sableye",
"FR": "Ténéfix",
"DE": "Zobiris",
- "RU": "Сэйблай"
+ "RU": "Сабляй"
},
"pokemon_id_303": {
"EN": "Mawile",
@@ -1714,17 +1714,17 @@
"pokemon_id_311": {
"EN": "Plusle",
"FR": "Posipi",
- "RU": "Пласл"
+ "RU": "Плюсл"
},
"pokemon_id_312": {
"EN": "Minun",
"FR": "Négapi",
- "RU": "Майнун"
+ "RU": "Минун"
},
"pokemon_id_313": {
"EN": "Volbeat",
"FR": "Muciole",
- "RU": "Волбит"
+ "RU": "Вольбит"
},
"pokemon_id_314": {
"EN": "Illumise",
@@ -1740,7 +1740,7 @@
"EN": "Gulpin",
"FR": "Gloupti",
"DE": "Schluppuck",
- "RU": "Гальпин"
+ "RU": "Гульпин"
},
"pokemon_id_317": {
"EN": "Swalot",
@@ -1760,28 +1760,28 @@
},
"pokemon_id_320": {
"EN": "Wailmer",
- "RU": "Вэйлмер"
+ "RU": "Вейлмер"
},
"pokemon_id_321": {
"EN": "Wailord",
- "RU": "Вэйлорд"
+ "RU": "Вейлорд"
},
"pokemon_id_322": {
"EN": "Numel",
"FR": "Chamallot",
"DE": "Camaub",
- "RU": "Намел"
+ "RU": "Нумел"
},
"pokemon_id_323": {
"EN": "Camerupt",
"FR": "Camérupt",
- "RU": "Камерапт"
+ "RU": "Камерупт"
},
"pokemon_id_324": {
"EN": "Torkoal",
"FR": "Chartor",
"DE": "Qurtel",
- "RU": "Торкол"
+ "RU": "Торкоал"
},
"pokemon_id_325": {
"EN": "Spoink",
@@ -1818,7 +1818,7 @@
"pokemon_id_331": {
"EN": "Cacnea",
"DE": "Tuska",
- "RU": "Какнея"
+ "RU": "Какния"
},
"pokemon_id_332": {
"EN": "Cacturne",
@@ -1829,11 +1829,11 @@
"EN": "Swablu",
"FR": "Tylton",
"DE": "Wablu",
- "RU": "Сваблу"
+ "RU": "Сваблю"
},
"pokemon_id_334": {
"EN": "Altaria",
- "RU": "Алтария"
+ "RU": "Альтария"
},
"pokemon_id_335": {
"EN": "Zangoose",
@@ -1863,7 +1863,7 @@
"EN": "Barboach",
"FR": "Barloche",
"DE": "Schmerbe",
- "RU": "Барбоч"
+ "RU": "Барбоуч"
},
"pokemon_id_340": {
"EN": "Whiscash",
@@ -1881,7 +1881,7 @@
"EN": "Crawdaunt",
"FR": "Colhomard",
"DE": "Krebutack",
- "RU": "Крадонт"
+ "RU": "Краудонт"
},
"pokemon_id_343": {
"EN": "Baltoy",
@@ -1924,7 +1924,7 @@
"pokemon_id_350": {
"EN": "Milotic",
"FR": "Milobellus",
- "RU": "Майлотик"
+ "RU": "Милотик"
},
"pokemon_id_351": {
"EN": "Castform",
@@ -1966,7 +1966,7 @@
"EN": "Chimecho",
"FR": "Éoko",
"DE": "Palimpalim",
- "RU": "Чаймеко"
+ "RU": "Чимечо"
},
"pokemon_id_359": {
"EN": "Absol",
@@ -2040,7 +2040,7 @@
"EN": "Bagon",
"FR": "Draby",
"DE": "Kindwurm",
- "RU": "Бейгон"
+ "RU": "Багон"
},
"pokemon_id_372": {
"EN": "Shelgon",
@@ -2058,7 +2058,7 @@
"EN": "Beldum",
"FR": "Terhal",
"DE": "Tanhel",
- "RU": "Белдам"
+ "RU": "Белдум"
},
"pokemon_id_375": {
"EN": "Metang",
@@ -2216,7 +2216,7 @@
"pokemon_id_405": {
"EN": "Luxray",
"DE": "Luxtra",
- "RU": "Лаксрэй"
+ "RU": "Лаксрей"
},
"pokemon_id_406": {
"EN": "Budew",
@@ -2226,7 +2226,7 @@
},
"pokemon_id_407": {
"EN": "Roserade",
- "RU": "Розрейд"
+ "RU": "Розерейд"
},
"pokemon_id_408": {
"EN": "Cranidos",
@@ -2238,7 +2238,7 @@
"EN": "Rampardos",
"FR": "Charkos",
"DE": "Rameidon",
- "RU": "Рэмпардос"
+ "RU": "Рампардос"
},
"pokemon_id_410": {
"EN": "Shieldon",
@@ -2288,7 +2288,7 @@
"EN": "Buizel",
"FR": "Mustébouée",
"DE": "Bamelin",
- "RU": "Буизел"
+ "RU": "Буизель"
},
"pokemon_id_419": {
"EN": "Floatzel",
@@ -2300,7 +2300,7 @@
"EN": "Cherubi",
"FR": "Ceribou",
"DE": "Kikugi",
- "RU": "Чераби"
+ "RU": "Черуби"
},
"pokemon_id_421": {
"EN": "Cherrim",
@@ -2341,7 +2341,7 @@
"EN": "Buneary",
"FR": "Laporeille",
"DE": "Haspiror",
- "RU": "Бунири"
+ "RU": "Банири"
},
"pokemon_id_428": {
"EN": "Lopunny",
@@ -2359,13 +2359,13 @@
"EN": "Honchkrow",
"FR": "Corboss",
"DE": "Kramshef",
- "RU": "Хончкроу"
+ "RU": "Ханчкроу"
},
"pokemon_id_431": {
"EN": "Glameow",
"FR": "Chaglam",
"DE": "Charmian",
- "RU": "Глеймяу"
+ "RU": "Гламяу"
},
"pokemon_id_432": {
"EN": "Purugly",
@@ -2410,7 +2410,7 @@
"pokemon_id_439": {
"EN": "Mime Jr.",
"DE": "Pantimimi",
- "RU": "Майм-Джуниор"
+ "RU": "Майм-джуниор"
},
"pokemon_id_440": {
"EN": "Happiny",
@@ -2427,7 +2427,7 @@
"pokemon_id_442": {
"EN": "Spiritomb",
"DE": "Kryppuk",
- "RU": "Спиритум"
+ "RU": "Спиритомб"
},
"pokemon_id_443": {
"EN": "Gible",
@@ -2521,7 +2521,7 @@
"EN": "Snover",
"FR": "Blizzi",
"DE": "Shnebedeck",
- "RU": "Сноувер"
+ "RU": "Сновер"
},
"pokemon_id_460": {
"EN": "Abomasnow",
@@ -2556,7 +2556,7 @@
"EN": "Tangrowth",
"FR": "Bouldeneu",
"DE": "Tangoloss",
- "RU": "Тэнгроут"
+ "RU": "Тангроут"
},
"pokemon_id_466": {
"EN": "Electivire",
@@ -2594,7 +2594,7 @@
"EN": "Gliscor",
"FR": "Scorvol",
"DE": "Skorgro",
- "RU": "Глайскор"
+ "RU": "Глискор"
},
"pokemon_id_473": {
"EN": "Mamoswine",
@@ -2604,7 +2604,7 @@
},
"pokemon_id_474": {
"EN": "Porygon-Z",
- "RU": "Поригон-Z"
+ "RU": "ПоригонZ"
},
"pokemon_id_475": {
"EN": "Gallade",
@@ -2651,7 +2651,7 @@
"EN": "Azelf",
"FR": "Créfadet",
"DE": "Tobutz",
- "RU": "Азелф"
+ "RU": "Азельф"
},
"pokemon_id_483": {
"EN": "Dialga",
@@ -2765,7 +2765,7 @@
"EN": "Watchog",
"FR": "Miradar",
"DE": "Kukmarda",
- "RU": "Уочхог"
+ "RU": "Вочхог"
},
"pokemon_id_506": {
"EN": "Lillipup",
@@ -2777,7 +2777,7 @@
"EN": "Herdier",
"FR": "Ponchien",
"DE": "Terribark",
- "RU": "Хардиер"
+ "RU": "Хердиер"
},
"pokemon_id_508": {
"EN": "Stoutland",
@@ -2795,7 +2795,7 @@
"EN": "Liepard",
"FR": "Léopardus",
"DE": "Kleoparda",
- "RU": "Лайпард"
+ "RU": "Липард"
},
"pokemon_id_511": {
"EN": "Pansage",
@@ -2860,7 +2860,7 @@
"EN": "Unfezant",
"FR": "Déflaisan",
"DE": "Fasasnob",
- "RU": "Унфезант"
+ "RU": "Анфезант"
},
"pokemon_id_522": {
"EN": "Blitzle",
@@ -2908,7 +2908,7 @@
"EN": "Drilbur",
"FR": "Rototaupe",
"DE": "Rotomurf",
- "RU": "Дрилбур"
+ "RU": "Дрильбур"
},
"pokemon_id_530": {
"EN": "Excadrill",
@@ -2926,7 +2926,7 @@
"EN": "Timburr",
"FR": "Charpenti",
"DE": "Praktibalk",
- "RU": "Тимбёрр"
+ "RU": "Тимбурр"
},
"pokemon_id_533": {
"EN": "Gurdurr",
@@ -2938,7 +2938,7 @@
"EN": "Conkeldurr",
"FR": "Bétochef",
"DE": "Meistagrif",
- "RU": "Конкельдар"
+ "RU": "Конкльдурр"
},
"pokemon_id_535": {
"EN": "Tympole",
@@ -2950,13 +2950,13 @@
"EN": "Palpitoad",
"FR": "Batracné",
"DE": "Mebrana",
- "RU": "Палпитоуд"
+ "RU": "Палпитоад"
},
"pokemon_id_537": {
"EN": "Seismitoad",
"FR": "Crapustule",
"DE": "Branawarz",
- "RU": "Сейсмитоуд"
+ "RU": "Сейсмитоад"
},
"pokemon_id_538": {
"EN": "Throh",
@@ -3064,7 +3064,7 @@
"EN": "Darmanitan",
"FR": "Darumacho",
"DE": "Flampivian",
- "RU": "Дарманитан"
+ "RU": "Дармантан"
},
"pokemon_id_556": {
"EN": "Maractus",
@@ -3174,19 +3174,19 @@
"EN": "Gothita",
"FR": "Scrutella",
"DE": "Mollimorba",
- "RU": "Гофита"
+ "RU": "Готита"
},
"pokemon_id_575": {
"EN": "Gothorita",
"FR": "Mesmérella",
"DE": "Hypnomorba",
- "RU": "Гофорита"
+ "RU": "Готорита"
},
"pokemon_id_576": {
"EN": "Gothitelle",
"FR": "Sidérella",
"DE": "Morbitesse",
- "RU": "Гофителль"
+ "RU": "Готителль"
},
"pokemon_id_577": {
"EN": "Solosis",
@@ -3388,13 +3388,13 @@
"EN": "Axew",
"FR": "Coupenotte",
"DE": "Milza",
- "RU": "Эксью"
+ "RU": "Аксью"
},
"pokemon_id_611": {
"EN": "Fraxure",
"FR": "Incisache",
"DE": "Sharfax",
- "RU": "Фрэкшур"
+ "RU": "Фрэксюр"
},
"pokemon_id_612": {
"EN": "Haxorus",
@@ -3538,7 +3538,7 @@
"EN": "Hydreigon",
"FR": "Trioxhydre",
"DE": "Trikephalo",
- "RU": "Хайдрайгон"
+ "RU": "Хайдрагон"
},
"pokemon_id_636": {
"EN": "Larvesta",
@@ -3568,7 +3568,7 @@
"EN": "Virizion",
"FR": "Viridium",
"DE": "Viridium",
- "RU": "Вирижион"
+ "RU": "Виризион"
},
"pokemon_id_641": {
"EN": "Tornadus",
@@ -3598,7 +3598,7 @@
},
"pokemon_id_646": {
"EN": "Kyurem",
- "RU": "Курем"
+ "RU": "Кьюрем"
},
"pokemon_id_647": {
"EN": "Keldeo",
@@ -3610,7 +3610,7 @@
},
"pokemon_id_649": {
"EN": "Genesect",
- "RU": "Дженесект"
+ "RU": "Генесект"
},
"pokemon_id_650": {
"EN": "Chespin",
@@ -4132,21 +4132,18 @@
"RU": "Крабролер"
},
"pokemon_id_740": {
- "PT-BR": "Crabominável",
"EN": "Crabominable",
"DE": "Krawell",
"IT": "Crabominabile",
"RU": "Крабаминабл"
},
"pokemon_id_741": {
- "PT-BR": "Oricório",
"EN": "Oricorio",
"FR": "Plumeline",
"DE": "Choreogel",
"RU": "Орикорио"
},
"pokemon_id_742": {
- "PT-BR": "Fofinho",
"EN": "Cutiefly",
"FR": "Bombydou",
"DE": "Wommel",
@@ -4391,19 +4388,19 @@
"EN": "Jangmo-o",
"FR": "Bébécaille",
"DE": "Miniras",
- "RU": "Джангмо-о"
+ "RU": "Джангмоо"
},
"pokemon_id_783": {
"EN": "Hakamo-o",
"FR": "Écaïd",
"DE": "Mediras",
- "RU": "Хакамо-o"
+ "RU": "Хакамоo"
},
"pokemon_id_784": {
"EN": "Kommo-o",
"FR": "Ékaïser",
"DE": "Grandiras",
- "RU": "Коммо-o"
+ "RU": "Коммоo"
},
"pokemon_id_785": {
"EN": "Tapu Koko",
@@ -5059,5 +5056,813 @@
"FR": "Sylveroy",
"DE": "Coronospa",
"RU": "Калирекс"
+ },
+ "pokemon_id_899": {
+ "EN": "Wyrdeer",
+ "FR": "Cerbyllin",
+ "DE": "Damythir",
+ "RU": "Вирдир"
+ },
+ "pokemon_id_900": {
+ "EN": "Kleavor",
+ "FR": "Hachécateur",
+ "DE": "Axantor",
+ "RU": "Кливор"
+ },
+ "pokemon_id_901": {
+ "EN": "Ursaluna",
+ "FR": "Ursaking",
+ "RU": "Урсалуна"
+ },
+ "pokemon_id_902": {
+ "EN": "Basculegion",
+ "FR": "Paragruel",
+ "DE": "Salmagnis",
+ "RU": "Баскулиджен"
+ },
+ "pokemon_id_903": {
+ "EN": "Sneasler",
+ "FR": "Farfurex",
+ "DE": "Snieboss",
+ "RU": "Снизлер"
+ },
+ "pokemon_id_904": {
+ "EN": "Overqwil",
+ "FR": "Qwilpik",
+ "DE": "Myriador",
+ "RU": "Оверквил"
+ },
+ "pokemon_id_905": {
+ "EN": "Enamorus",
+ "FR": "Amovénus",
+ "DE": "Cupidos",
+ "RU": "Энаморус"
+ },
+ "pokemon_id_906": {
+ "EN": "Sprigatito",
+ "FR": "Poussacha",
+ "DE": "Felori",
+ "RU": "Спригатито"
+ },
+ "pokemon_id_907": {
+ "EN": "Floragato",
+ "FR": "Matourgeon",
+ "DE": "Feliospa",
+ "RU": "Флорагато"
+ },
+ "pokemon_id_908": {
+ "EN": "Meowscarada",
+ "FR": "Miascarade",
+ "DE": "Maskagato",
+ "RU": "Мяускарада"
+ },
+ "pokemon_id_909": {
+ "EN": "Fuecoco",
+ "FR": "Chochodile",
+ "DE": "Krokel",
+ "RU": "Фуэкоко"
+ },
+ "pokemon_id_910": {
+ "EN": "Crocalor",
+ "FR": "Crocogril",
+ "DE": "Lokroko",
+ "RU": "Крокалор"
+ },
+ "pokemon_id_911": {
+ "EN": "Skeledirge",
+ "FR": "Flâmigator",
+ "DE": "Skelokrok",
+ "RU": "Скеледирж"
+ },
+ "pokemon_id_912": {
+ "EN": "Quaxly",
+ "FR": "Coiffeton",
+ "DE": "Kwaks",
+ "RU": "Куаксли"
+ },
+ "pokemon_id_913": {
+ "EN": "Quaxwell",
+ "FR": "Canarbello",
+ "DE": "Fuentente",
+ "RU": "Куаксвелл"
+ },
+ "pokemon_id_914": {
+ "EN": "Quaquaval",
+ "FR": "Palmaval",
+ "DE": "Bailonda",
+ "RU": "Куаквавал"
+ },
+ "pokemon_id_915": {
+ "EN": "Lechonk",
+ "FR": "Gourmelet",
+ "DE": "Ferkuli",
+ "RU": "Лечонк"
+ },
+ "pokemon_id_916": {
+ "EN": "Oinkologne",
+ "FR": "Fragroin",
+ "DE": "Fragrunz",
+ "RU": "Ойнколон"
+ },
+ "pokemon_id_917": {
+ "EN": "Tarountula",
+ "FR": "Tissenboule",
+ "DE": "Tarundel",
+ "RU": "Тараунтула"
+ },
+ "pokemon_id_918": {
+ "EN": "Spidops",
+ "FR": "Filentrappe",
+ "DE": "Spinsidias",
+ "RU": "Спайдопс"
+ },
+ "pokemon_id_919": {
+ "EN": "Nymble",
+ "FR": "Lilliterelle",
+ "DE": "Micrick",
+ "RU": "Нимбл"
+ },
+ "pokemon_id_920": {
+ "EN": "Lokix",
+ "FR": "Gambex",
+ "DE": "Lextremo",
+ "RU": "Локикс"
+ },
+ "pokemon_id_921": {
+ "EN": "Pawmi",
+ "FR": "Pohm",
+ "DE": "Pamo",
+ "RU": "Поми"
+ },
+ "pokemon_id_922": {
+ "EN": "Pawmo",
+ "FR": "Pohmotte",
+ "DE": "Pamamo",
+ "RU": "Помо"
+ },
+ "pokemon_id_923": {
+ "EN": "Pawmot",
+ "FR": "Pohmarmotte",
+ "DE": "Pamomamo",
+ "RU": "Помот"
+ },
+ "pokemon_id_924": {
+ "EN": "Tandemaus",
+ "FR": "Compagnol",
+ "DE": "Zwieps",
+ "RU": "Тандемаус"
+ },
+ "pokemon_id_925": {
+ "EN": "Maushold",
+ "FR": "Famignol",
+ "DE": "Famieps",
+ "RU": "Маусхолд"
+ },
+ "pokemon_id_926": {
+ "EN": "Fidough",
+ "FR": "Pâtachiot",
+ "DE": "Hefel",
+ "RU": "Файдо"
+ },
+ "pokemon_id_927": {
+ "EN": "Dachsbun",
+ "FR": "Briochien",
+ "DE": "Backel",
+ "RU": "Даксбан"
+ },
+ "pokemon_id_928": {
+ "EN": "Smoliv",
+ "FR": "Olivini",
+ "DE": "Olini",
+ "RU": "Смолив"
+ },
+ "pokemon_id_929": {
+ "EN": "Dolliv",
+ "FR": "Olivado",
+ "DE": "Olivinio",
+ "RU": "Доллив"
+ },
+ "pokemon_id_930": {
+ "EN": "Arboliva",
+ "DE": "Olithena",
+ "RU": "Арболива"
+ },
+ "pokemon_id_931": {
+ "EN": "Squawkabilly",
+ "FR": "Tapatoès",
+ "DE": "Krawalloro",
+ "RU": "Сквакабилли"
+ },
+ "pokemon_id_932": {
+ "EN": "Nacli",
+ "FR": "Selutin",
+ "DE": "Geosali",
+ "RU": "Накли"
+ },
+ "pokemon_id_933": {
+ "EN": "Naclstack",
+ "FR": "Amassel",
+ "DE": "Sedisal",
+ "RU": "Наклстак"
+ },
+ "pokemon_id_934": {
+ "EN": "Garganacl",
+ "FR": "Gigansel",
+ "DE": "Saltigant",
+ "RU": "Гарганакл"
+ },
+ "pokemon_id_935": {
+ "EN": "Charcadet",
+ "FR": "Charbambin",
+ "DE": "Knarbon",
+ "RU": "Чаркадет"
+ },
+ "pokemon_id_936": {
+ "EN": "Armarouge",
+ "FR": "Carmadura",
+ "DE": "Crimanzo",
+ "RU": "Армаруж"
+ },
+ "pokemon_id_937": {
+ "EN": "Ceruledge",
+ "FR": "Malvalame",
+ "DE": "Azugladis",
+ "RU": "Серуледж"
+ },
+ "pokemon_id_938": {
+ "EN": "Tadbulb",
+ "FR": "Têtampoule",
+ "DE": "Blipp",
+ "RU": "Тадбалб"
+ },
+ "pokemon_id_939": {
+ "EN": "Bellibolt",
+ "FR": "Ampibidou",
+ "DE": "Wampitz",
+ "RU": "Беллиболт"
+ },
+ "pokemon_id_940": {
+ "EN": "Wattrel",
+ "FR": "Zapétrel",
+ "DE": "Voltrel",
+ "RU": "Ваттрел"
+ },
+ "pokemon_id_941": {
+ "EN": "Kilowattrel",
+ "FR": "Fulgulairo",
+ "DE": "Voltrean",
+ "RU": "Киловаттрел"
+ },
+ "pokemon_id_942": {
+ "EN": "Maschiff",
+ "FR": "Grondogue",
+ "DE": "Mobtiff",
+ "RU": "Масчифф"
+ },
+ "pokemon_id_943": {
+ "EN": "Mabosstiff",
+ "FR": "Dogrino",
+ "DE": "Mastifioso",
+ "RU": "Мабосстифф"
+ },
+ "pokemon_id_944": {
+ "EN": "Shroodle",
+ "FR": "Gribouraigne",
+ "DE": "Sproxi",
+ "RU": "Шрудл"
+ },
+ "pokemon_id_945": {
+ "EN": "Grafaiai",
+ "FR": "Tag-Tag",
+ "DE": "Affiti",
+ "RU": "Графайай"
+ },
+ "pokemon_id_946": {
+ "EN": "Bramblin",
+ "FR": "Virovent",
+ "DE": "Weherba",
+ "RU": "Брамблин"
+ },
+ "pokemon_id_947": {
+ "EN": "Brambleghast",
+ "FR": "Virevorreur",
+ "DE": "Horrerba",
+ "RU": "Брамблгаст"
+ },
+ "pokemon_id_948": {
+ "EN": "Toedscool",
+ "FR": "Terracool",
+ "DE": "Tentagra",
+ "RU": "Тодскул"
+ },
+ "pokemon_id_949": {
+ "EN": "Toedscruel",
+ "FR": "Terracruel",
+ "DE": "Tenterra",
+ "RU": "Тодскрул"
+ },
+ "pokemon_id_950": {
+ "EN": "Klawf",
+ "FR": "Craparoi",
+ "DE": "Klibbe",
+ "RU": "Клоф"
+ },
+ "pokemon_id_951": {
+ "EN": "Capsakid",
+ "FR": "Pimito",
+ "DE": "Chilingel",
+ "RU": "Капсакид"
+ },
+ "pokemon_id_952": {
+ "EN": "Scovillain",
+ "FR": "Scovilain",
+ "DE": "Halupenjo",
+ "RU": "Сковиллен"
+ },
+ "pokemon_id_953": {
+ "EN": "Rellor",
+ "FR": "Léboulérou",
+ "DE": "Relluk",
+ "RU": "Реллор"
+ },
+ "pokemon_id_954": {
+ "EN": "Rabsca",
+ "FR": "Bérasca",
+ "DE": "Skarabaks",
+ "RU": "Рабска"
+ },
+ "pokemon_id_955": {
+ "EN": "Flittle",
+ "FR": "Flotillon",
+ "DE": "Flattutu",
+ "RU": "Флиттл"
+ },
+ "pokemon_id_956": {
+ "EN": "Espathra",
+ "FR": "Cléopsytra",
+ "DE": "Psiopatra",
+ "RU": "Эспатра"
+ },
+ "pokemon_id_957": {
+ "EN": "Tinkatink",
+ "FR": "Forgerette",
+ "DE": "Forgita",
+ "RU": "Тинкатинк"
+ },
+ "pokemon_id_958": {
+ "EN": "Tinkatuff",
+ "FR": "Forgella",
+ "DE": "Tafforgita",
+ "RU": "Тинкатафф"
+ },
+ "pokemon_id_959": {
+ "EN": "Tinkaton",
+ "FR": "Forgelina",
+ "DE": "Granforgita",
+ "RU": "Тинкатон"
+ },
+ "pokemon_id_960": {
+ "EN": "Wiglett",
+ "FR": "Taupikeau",
+ "DE": "Schligda",
+ "RU": "Виглетт"
+ },
+ "pokemon_id_961": {
+ "EN": "Wugtrio",
+ "FR": "Triopikeau",
+ "DE": "Schligdri",
+ "RU": "Вагтрио"
+ },
+ "pokemon_id_962": {
+ "EN": "Bombirdier",
+ "FR": "Lestombaile",
+ "DE": "Adebom",
+ "RU": "Бомбердир"
+ },
+ "pokemon_id_963": {
+ "EN": "Finizen",
+ "FR": "Dofin",
+ "DE": "Normifin",
+ "RU": "Финизен"
+ },
+ "pokemon_id_964": {
+ "EN": "Palafin",
+ "FR": "Superdofin",
+ "DE": "Delfinator",
+ "RU": "Палафин"
+ },
+ "pokemon_id_965": {
+ "EN": "Varoom",
+ "FR": "Vrombi",
+ "DE": "Knattox",
+ "RU": "Варум"
+ },
+ "pokemon_id_966": {
+ "EN": "Revavroom",
+ "FR": "Vrombotor",
+ "DE": "Knattatox",
+ "RU": "Реваврум"
+ },
+ "pokemon_id_967": {
+ "EN": "Cyclizar",
+ "FR": "Motorizard",
+ "DE": "Mopex",
+ "RU": "Сайклизар"
+ },
+ "pokemon_id_968": {
+ "EN": "Orthworm",
+ "FR": "Ferdeter",
+ "DE": "Schlurm",
+ "RU": "Ортворм"
+ },
+ "pokemon_id_969": {
+ "EN": "Glimmet",
+ "FR": "Germéclat",
+ "DE": "Lumispross",
+ "RU": "Глиммет"
+ },
+ "pokemon_id_970": {
+ "EN": "Glimmora",
+ "FR": "Floréclat",
+ "DE": "Lumiflora",
+ "RU": "Глиммора"
+ },
+ "pokemon_id_971": {
+ "EN": "Greavard",
+ "FR": "Toutombe",
+ "DE": "Gruff",
+ "RU": "Гриверд"
+ },
+ "pokemon_id_972": {
+ "EN": "Houndstone",
+ "FR": "Tomberro",
+ "DE": "Friedwuff",
+ "RU": "Хаундстоун"
+ },
+ "pokemon_id_973": {
+ "EN": "Flamigo",
+ "FR": "Flamenroule",
+ "DE": "Flaminkno",
+ "RU": "Фламиго"
+ },
+ "pokemon_id_974": {
+ "EN": "Cetoddle",
+ "FR": "Piétacé",
+ "DE": "Flaniwal",
+ "RU": "Сетоддл"
+ },
+ "pokemon_id_975": {
+ "EN": "Cetitan",
+ "FR": "Balbalèze",
+ "DE": "Kolowal",
+ "RU": "Сетайтан"
+ },
+ "pokemon_id_976": {
+ "EN": "Veluza",
+ "FR": "Délestin",
+ "DE": "Agiluza",
+ "RU": "Велуза"
+ },
+ "pokemon_id_977": {
+ "EN": "Dondozo",
+ "FR": "Oyacata",
+ "DE": "Heerashai",
+ "RU": "Дондозо"
+ },
+ "pokemon_id_978": {
+ "EN": "Tatsugiri",
+ "FR": "Nigirigon",
+ "DE": "Nigiragi",
+ "RU": "Тацугири"
+ },
+ "pokemon_id_979": {
+ "EN": "Annihilape",
+ "FR": "Courrousinge",
+ "DE": "Epitaff",
+ "RU": "Аннаялейп"
+ },
+ "pokemon_id_980": {
+ "EN": "Clodsire",
+ "FR": "Terraiste",
+ "DE": "Suelord",
+ "RU": "Клодсайр"
+ },
+ "pokemon_id_981": {
+ "EN": "Farigiraf",
+ "RU": "Фарижираф"
+ },
+ "pokemon_id_982": {
+ "EN": "Dudunsparce",
+ "FR": "Deusolourdo",
+ "DE": "Dummimisel",
+ "RU": "Даданспарс"
+ },
+ "pokemon_id_983": {
+ "EN": "Kingambit",
+ "FR": "Scalpereur",
+ "DE": "Gladimperio",
+ "RU": "Кингамбит"
+ },
+ "pokemon_id_984": {
+ "PT-BR": "Presa Grande",
+ "EN": "Great Tusk",
+ "FR": "Fort-Ivoire",
+ "DE": "Riesenzahn",
+ "IT": "Grandizanne",
+ "RU": "Великий Бивень",
+ "ES": "Colmilargo"
+ },
+ "pokemon_id_985": {
+ "PT-BR": "Cauda Brado",
+ "EN": "Scream Tail",
+ "FR": "Hurle-Queue",
+ "DE": "Brüllschweif",
+ "IT": "Codaurlante",
+ "RU": "Кричащий Хвост",
+ "ES": "Colagrito"
+ },
+ "pokemon_id_986": {
+ "PT-BR": "Capuz Bruto",
+ "EN": "Brute Bonnet",
+ "FR": "Fongus-Furie",
+ "DE": "Wutpilz",
+ "IT": "Fungofurioso",
+ "RU": "Свирепый Гриб",
+ "ES": "Furioseta"
+ },
+ "pokemon_id_987": {
+ "PT-BR": "Juba Sopro",
+ "EN": "Flutter Mane",
+ "FR": "Flotte-Mèche",
+ "DE": "Flatterhaar",
+ "IT": "Crinealato",
+ "RU": "Волнистая Грива",
+ "ES": "Melenaleteo"
+ },
+ "pokemon_id_988": {
+ "PT-BR": "Asa Rasteira",
+ "EN": "Slither Wing",
+ "FR": "Rampe-Ailes",
+ "DE": "Kriechflügel",
+ "IT": "Alirasenti",
+ "RU": "Ползущее Крыло",
+ "ES": "Reptalada"
+ },
+ "pokemon_id_989": {
+ "PT-BR": "Choque Areia",
+ "EN": "Sandy Shocks",
+ "FR": "Pelage-Sablé",
+ "DE": "Sandfell",
+ "IT": "Peldisabbia",
+ "RU": "Магнитные Вихры",
+ "ES": "Pelarena"
+ },
+ "pokemon_id_990": {
+ "PT-BR": "Trilho Férreo",
+ "EN": "Iron Treads",
+ "FR": "Roue-de-Fer",
+ "DE": "Eisenrad",
+ "IT": "Solcoferreo",
+ "RU": "Железные Гусеницы",
+ "ES": "Ferrodada"
+ },
+ "pokemon_id_991": {
+ "PT-BR": "Pacote Férreo",
+ "EN": "Iron Bundle",
+ "FR": "Hotte-de-Fer",
+ "DE": "Eisenbündel",
+ "IT": "Saccoferreo",
+ "RU": "Железный Мешок",
+ "ES": "Ferrosaco"
+ },
+ "pokemon_id_992": {
+ "PT-BR": "Mãos Férreas",
+ "EN": "Iron Hands",
+ "FR": "Paume-de-Fer",
+ "DE": "Eisenhand",
+ "IT": "Manoferrea",
+ "RU": "Железные Руки",
+ "ES": "Ferropalmas"
+ },
+ "pokemon_id_993": {
+ "PT-BR": "Jugulares Férreas",
+ "EN": "Iron Jugulis",
+ "FR": "Têtes-de-Fer",
+ "DE": "Eisenhals",
+ "IT": "Colloferreo",
+ "RU": "Железные Головы",
+ "ES": "Ferrocuello"
+ },
+ "pokemon_id_994": {
+ "PT-BR": "Mariposa Férrea",
+ "EN": "Iron Moth",
+ "FR": "Mite-de-Fer",
+ "DE": "Eisenfalter",
+ "IT": "Falenaferrea",
+ "RU": "Железный Мотылёк",
+ "ES": "Ferropolilla"
+ },
+ "pokemon_id_995": {
+ "PT-BR": "Espinhos Férreos",
+ "EN": "Iron Thorns",
+ "FR": "Épine-de-Fer",
+ "DE": "Eisendorn",
+ "IT": "Spineferree",
+ "RU": "Железные Шипы",
+ "ES": "Ferropúas"
+ },
+ "pokemon_id_996": {
+ "EN": "Frigibax",
+ "FR": "Frigodo",
+ "DE": "Frospino",
+ "RU": "Фриджибакс"
+ },
+ "pokemon_id_997": {
+ "EN": "Arctibax",
+ "FR": "Cryodo",
+ "DE": "Cryospino",
+ "RU": "Арктибакс"
+ },
+ "pokemon_id_998": {
+ "EN": "Baxcalibur",
+ "FR": "Glaivodo",
+ "DE": "Espinodon",
+ "RU": "Бакскалибур"
+ },
+ "pokemon_id_999": {
+ "EN": "Gimmighoul",
+ "FR": "Mordudor",
+ "DE": "Gierspenst",
+ "RU": "Гиммигул"
+ },
+ "pokemon_id_1000": {
+ "EN": "Gholdengo",
+ "FR": "Gromago",
+ "DE": "Monetigo",
+ "RU": "Голденго"
+ },
+ "pokemon_id_1001": {
+ "EN": "Wo-Chien",
+ "FR": "Chongjian",
+ "DE": "Chongjian",
+ "RU": "Во-Чиен"
+ },
+ "pokemon_id_1002": {
+ "EN": "Chien-Pao",
+ "FR": "Baojian",
+ "DE": "Baojian",
+ "RU": "Чиен-Пао"
+ },
+ "pokemon_id_1003": {
+ "EN": "Ting-Lu",
+ "FR": "Dinglu",
+ "DE": "Dinglu",
+ "RU": "Тинг-Лу"
+ },
+ "pokemon_id_1004": {
+ "EN": "Chi-Yu",
+ "FR": "Yuyu",
+ "DE": "Yuyu",
+ "RU": "Чи-Ю"
+ },
+ "pokemon_id_1005": {
+ "PT-BR": "Lua Estrondo",
+ "EN": "Roaring Moon",
+ "FR": "Rugit-Lune",
+ "DE": "Donnersichel",
+ "IT": "Lunaruggente",
+ "RU": "Ревущий Месяц",
+ "ES": "Bramaluna"
+ },
+ "pokemon_id_1006": {
+ "PT-BR": "Valentia Férrea",
+ "EN": "Iron Valiant",
+ "FR": "Garde-de-Fer",
+ "DE": "Eisenkrieger",
+ "IT": "Eroeferreo",
+ "RU": "Железный Воин",
+ "ES": "Ferropaladín"
+ },
+ "pokemon_id_1007": {
+ "EN": "Koraidon",
+ "RU": "Корайдон"
+ },
+ "pokemon_id_1008": {
+ "EN": "Miraidon",
+ "RU": "Мирайдон"
+ },
+ "pokemon_id_1009": {
+ "PT-BR": "Onda Ando",
+ "EN": "Walking Wake",
+ "FR": "Serpente-Eau",
+ "DE": "Windewoge",
+ "IT": "Acquecrespe",
+ "RU": "Вздымающаяся Волна",
+ "ES": "Ondulagua"
+ },
+ "pokemon_id_1010": {
+ "PT-BR": "Folhas Férreas",
+ "EN": "Iron Leaves",
+ "FR": "Vert-de-Fer",
+ "DE": "Eisenblatt",
+ "IT": "Fogliaferrea",
+ "RU": "Железные Листья",
+ "ES": "Ferroverdor"
+ },
+ "pokemon_id_1011": {
+ "EN": "Dipplin",
+ "FR": "Pomdramour",
+ "DE": "Sirapfel",
+ "RU": "Дипплин"
+ },
+ "pokemon_id_1012": {
+ "EN": "Poltchageist",
+ "DE": "Mortcha",
+ "RU": "Полчагейст"
+ },
+ "pokemon_id_1013": {
+ "EN": "Sinistcha",
+ "FR": "Théffroyable",
+ "DE": "Fatalitcha",
+ "RU": "Синисча"
+ },
+ "pokemon_id_1014": {
+ "EN": "Okidogi",
+ "FR": "Félicanis",
+ "DE": "Boninu",
+ "RU": "Окидоги"
+ },
+ "pokemon_id_1015": {
+ "EN": "Munkidori",
+ "FR": "Fortusimia",
+ "DE": "Benesaru",
+ "RU": "Манкидори"
+ },
+ "pokemon_id_1016": {
+ "EN": "Fezandipiti",
+ "FR": "Favianos",
+ "DE": "Beatori",
+ "RU": "Фезандипити"
+ },
+ "pokemon_id_1017": {
+ "EN": "Ogerpon",
+ "RU": "Огерпон"
+ },
+ "pokemon_id_1018": {
+ "EN": "Archaludon",
+ "FR": "Pondralugon",
+ "DE": "Briduradon",
+ "RU": "Архалюдон"
+ },
+ "pokemon_id_1019": {
+ "EN": "Hydrapple",
+ "FR": "Pomdorochi",
+ "DE": "Hydrapfel",
+ "RU": "Гидраппл"
+ },
+ "pokemon_id_1020": {
+ "PT-BR": "Fogo Corrosão",
+ "EN": "Gouging Fire",
+ "DE": "Keilflamme",
+ "IT": "Vampeaguzze",
+ "RU": "Пронзающее Пламя",
+ "ES": "Flamariete"
+ },
+ "pokemon_id_1021": {
+ "PT-BR": "Raio Fúria",
+ "EN": "Raging Bolt",
+ "FR": "Ire-Foudre",
+ "DE": "Furienblitz",
+ "IT": "Furiatonante",
+ "RU": "Яростная Молния",
+ "ES": "Electrofuria"
+ },
+ "pokemon_id_1022": {
+ "PT-BR": "Rocha Férrea",
+ "EN": "Iron Boulder",
+ "FR": "Roc-de-Fer",
+ "DE": "Eisenfels",
+ "IT": "Massoferreo",
+ "RU": "Железный Валун",
+ "ES": "Ferromole"
+ },
+ "pokemon_id_1023": {
+ "PT-BR": "Chifres Férreos",
+ "EN": "Iron Crown",
+ "FR": "Chef-de-Fer",
+ "DE": "Eisenhaupt",
+ "IT": "Capoferreo",
+ "RU": "Железный Вождь",
+ "ES": "Ferrotesta"
+ },
+ "pokemon_id_1024": {
+ "EN": "Terapagos",
+ "RU": "Терапагос"
+ },
+ "pokemon_id_1025": {
+ "EN": "Pecharunt",
+ "FR": "Pêchaminus",
+ "DE": "Infamomo",
+ "RU": "Печарант"
}
}
\ No newline at end of file
diff --git a/lang/pokemon_forms.json b/lang/pokemon_forms.json
new file mode 100644
index 00000000..d17afe1d
--- /dev/null
+++ b/lang/pokemon_forms.json
@@ -0,0 +1,2631 @@
+{
+ "pokemon_form_1": {
+ "EN": "A"
+ },
+ "pokemon_form_2": {
+ "EN": "B"
+ },
+ "pokemon_form_3": {
+ "EN": "C"
+ },
+ "pokemon_form_4": {
+ "EN": "D"
+ },
+ "pokemon_form_5": {
+ "EN": "E"
+ },
+ "pokemon_form_6": {
+ "EN": "F"
+ },
+ "pokemon_form_7": {
+ "EN": "G"
+ },
+ "pokemon_form_8": {
+ "EN": "H"
+ },
+ "pokemon_form_9": {
+ "EN": "I"
+ },
+ "pokemon_form_10": {
+ "EN": "J"
+ },
+ "pokemon_form_11": {
+ "EN": "K"
+ },
+ "pokemon_form_12": {
+ "EN": "L"
+ },
+ "pokemon_form_13": {
+ "EN": "M"
+ },
+ "pokemon_form_14": {
+ "EN": "N"
+ },
+ "pokemon_form_15": {
+ "EN": "O"
+ },
+ "pokemon_form_16": {
+ "EN": "P"
+ },
+ "pokemon_form_17": {
+ "EN": "Q"
+ },
+ "pokemon_form_18": {
+ "EN": "R"
+ },
+ "pokemon_form_19": {
+ "EN": "S"
+ },
+ "pokemon_form_20": {
+ "EN": "T"
+ },
+ "pokemon_form_21": {
+ "EN": "U"
+ },
+ "pokemon_form_22": {
+ "EN": "V"
+ },
+ "pokemon_form_23": {
+ "EN": "W"
+ },
+ "pokemon_form_24": {
+ "EN": "X"
+ },
+ "pokemon_form_25": {
+ "EN": "Y"
+ },
+ "pokemon_form_26": {
+ "EN": "Z"
+ },
+ "pokemon_form_27": {
+ "EN": "Exclamation Point",
+ "FR": "!",
+ "DE": "!",
+ "RU": "!"
+ },
+ "pokemon_form_28": {
+ "EN": "Question Mark",
+ "FR": "?",
+ "DE": "?",
+ "RU": "?"
+ },
+ "pokemon_form_30": {
+ "EN": "Sunny",
+ "FR": "Solaire",
+ "DE": "Sonnenform",
+ "RU": "Солнечная форма"
+ },
+ "pokemon_form_31": {
+ "EN": "Rainy",
+ "FR": "Eau de pluie",
+ "DE": "Regenform",
+ "RU": "Дождливая форма"
+ },
+ "pokemon_form_32": {
+ "EN": "Snowy",
+ "FR": "Blizzard",
+ "DE": "Schneeform",
+ "RU": "Снежная форма"
+ },
+ "pokemon_form_34": {
+ "PT-BR": "Ataque",
+ "EN": "Attack",
+ "FR": "Attaque",
+ "DE": "Angriffsform",
+ "IT": "Attacco",
+ "RU": "Атакующая форма",
+ "ES": "Ataque"
+ },
+ "pokemon_form_35": {
+ "PT-BR": "Defesa",
+ "EN": "Defense",
+ "FR": "Défense",
+ "DE": "Verteidigungsform",
+ "IT": "Difesa",
+ "RU": "Защитная форма",
+ "ES": "Defensa"
+ },
+ "pokemon_form_36": {
+ "PT-BR": "Velocidade",
+ "EN": "Speed",
+ "FR": "Vitesse",
+ "DE": "Initiativeform",
+ "IT": "Velocità",
+ "RU": "Скоростная форма",
+ "ES": "Velocidad"
+ },
+ "pokemon_form_37": {
+ "EN": "01"
+ },
+ "pokemon_form_38": {
+ "EN": "02"
+ },
+ "pokemon_form_39": {
+ "EN": "03"
+ },
+ "pokemon_form_40": {
+ "EN": "04"
+ },
+ "pokemon_form_41": {
+ "EN": "05"
+ },
+ "pokemon_form_42": {
+ "EN": "06"
+ },
+ "pokemon_form_43": {
+ "EN": "07"
+ },
+ "pokemon_form_44": {
+ "EN": "08"
+ },
+ "pokemon_form_46": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_48": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_50": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_52": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_54": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_56": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_58": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_60": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_62": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_64": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_66": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_68": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_70": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_72": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_74": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_76": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_78": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_80": {
+ "EN": "Alola",
+ "RU": "Алольская форма"
+ },
+ "pokemon_form_82": {
+ "PT-BR": "Rotom Congelante",
+ "EN": "Frost Rotom",
+ "FR": "Motisma Froid",
+ "DE": "Frost",
+ "IT": "Rotom Gelo",
+ "RU": "Холодильник",
+ "ES": "Rotom Frío"
+ },
+ "pokemon_form_83": {
+ "PT-BR": "Rotom Ventilador",
+ "EN": "Fan Rotom",
+ "FR": "Motisma Hélice",
+ "DE": "Wirbel",
+ "IT": "Rotom Vortice",
+ "RU": "Вентилятор",
+ "ES": "Rotom Ventilador"
+ },
+ "pokemon_form_84": {
+ "PT-BR": "Rotom Corte",
+ "EN": "Mow Rotom",
+ "FR": "Motisma Tonte",
+ "DE": "Schneid",
+ "IT": "Rotom Taglio",
+ "RU": "Газонокосилка",
+ "ES": "Rotom Corte"
+ },
+ "pokemon_form_85": {
+ "PT-BR": "Rotom Lavagem",
+ "EN": "Wash Rotom",
+ "FR": "Motisma Lavage",
+ "DE": "Wasch",
+ "IT": "Rotom Lavaggio",
+ "RU": "Стиралка",
+ "ES": "Rotom Lavado"
+ },
+ "pokemon_form_86": {
+ "PT-BR": "Rotom Calor",
+ "EN": "Heat Rotom",
+ "FR": "Motisma Chaleur",
+ "DE": "Hitze",
+ "IT": "Rotom Calore",
+ "RU": "Обогреватель",
+ "ES": "Rotom Calor"
+ },
+ "pokemon_form_87": {
+ "PT-BR": "Manto Vegetal",
+ "EN": "Plant Cloak",
+ "FR": "Plante",
+ "DE": "Pflanzenumhang",
+ "IT": "Manto Pianta",
+ "RU": "Растительный покров",
+ "ES": "Tronco Planta"
+ },
+ "pokemon_form_88": {
+ "PT-BR": "Manto Arenoso",
+ "EN": "Sandy Cloak",
+ "FR": "Cape Sable",
+ "DE": "Sandumhang",
+ "IT": "Manto Sabbia",
+ "RU": "Песчанный покров",
+ "ES": "Tronco Arena"
+ },
+ "pokemon_form_89": {
+ "PT-BR": "Manto de Lixo",
+ "EN": "Trash Cloak",
+ "FR": "Cape Déchet",
+ "DE": "Lumpenumhang",
+ "IT": "Manto Scarti",
+ "RU": "Мусорный покров",
+ "ES": "Tronco Basura"
+ },
+ "pokemon_form_90": {
+ "PT-BR": "Forma Alterada",
+ "EN": "Altered Forme",
+ "FR": "Forme Alternative",
+ "DE": "Wandel",
+ "IT": "Forma Alterata",
+ "RU": "Изменённая форма",
+ "ES": "Forma Modificada"
+ },
+ "pokemon_form_91": {
+ "PT-BR": "Forma Origem",
+ "EN": "Origin Forme",
+ "FR": "Forme Originelle",
+ "DE": "Ur",
+ "IT": "Forma Originale",
+ "RU": "Исходная форма",
+ "ES": "Forma Origen"
+ },
+ "pokemon_form_92": {
+ "PT-BR": "Forma Céu",
+ "EN": "Sky Forme",
+ "FR": "Forme Céleste",
+ "DE": "Zenit",
+ "IT": "Forma Cielo",
+ "RU": "Небесная форма",
+ "ES": "Forma Cielo"
+ },
+ "pokemon_form_93": {
+ "PT-BR": "Forma Terrestre",
+ "EN": "Land Forme",
+ "FR": "Forme Terrestre",
+ "DE": "Land",
+ "IT": "Forma Terra",
+ "RU": "Земная форма",
+ "ES": "Forma Tierra"
+ },
+ "pokemon_form_94": {
+ "PT-BR": "Forma Nublada",
+ "EN": "Overcast Form",
+ "FR": "Temps Couvert",
+ "DE": "Wolkenform",
+ "IT": "Forma Nuvola",
+ "RU": "Пасмурная форма",
+ "ES": "Forma Encapotado"
+ },
+ "pokemon_form_95": {
+ "EN": "Sunny",
+ "FR": "Temps Ensoleillé",
+ "DE": "Sonnenform",
+ "RU": "Солнечная форма"
+ },
+ "pokemon_form_96": {
+ "PT-BR": "Mar Ocidental",
+ "EN": "West Sea",
+ "FR": "Mer Occident",
+ "DE": "Westliches Meer",
+ "IT": "Mare Ovest",
+ "RU": "Западно-морская форма",
+ "ES": "Mar Oeste"
+ },
+ "pokemon_form_97": {
+ "PT-BR": "Mar Leste",
+ "EN": "East Sea",
+ "FR": "Mer Orient",
+ "DE": "Östliches Meer",
+ "IT": "Mare Est",
+ "RU": "Восточно-морская форма",
+ "ES": "Mar Este"
+ },
+ "pokemon_form_98": {
+ "PT-BR": "Mar Ocidental",
+ "EN": "West Sea",
+ "FR": "Mer Occident",
+ "DE": "Westliches Meer",
+ "IT": "Mare Ovest",
+ "RU": "Западно-морская форма",
+ "ES": "Mar Oeste"
+ },
+ "pokemon_form_99": {
+ "PT-BR": "Mar Leste",
+ "EN": "East Sea",
+ "FR": "Mer Orient",
+ "DE": "Östliches Meer",
+ "IT": "Mare Est",
+ "RU": "Восточно-морская форма",
+ "ES": "Mar Este"
+ },
+ "pokemon_form_101": {
+ "PT-BR": "Lutador",
+ "EN": "Fighting",
+ "FR": "Combat",
+ "DE": "Kampf",
+ "IT": "Lotta",
+ "RU": "Боевая форма",
+ "ES": "Lucha"
+ },
+ "pokemon_form_102": {
+ "PT-BR": "Voador",
+ "EN": "Flying",
+ "FR": "Vol",
+ "DE": "Flug",
+ "IT": "Volante",
+ "RU": "Летающая форма",
+ "ES": "Volador"
+ },
+ "pokemon_form_103": {
+ "PT-BR": "Venenoso",
+ "EN": "Poison",
+ "DE": "Gift",
+ "IT": "Veleno",
+ "RU": "Ядовитая форма",
+ "ES": "Veneno"
+ },
+ "pokemon_form_104": {
+ "PT-BR": "Terrestre",
+ "EN": "Ground",
+ "FR": "Sol",
+ "DE": "Boden",
+ "IT": "Terra",
+ "RU": "Земленая форма",
+ "ES": "Tierra"
+ },
+ "pokemon_form_105": {
+ "PT-BR": "Pedra",
+ "EN": "Rock",
+ "FR": "Roche",
+ "DE": "Gestein",
+ "IT": "Roccia",
+ "RU": "Каменная форма",
+ "ES": "Roca"
+ },
+ "pokemon_form_106": {
+ "PT-BR": "Inseto",
+ "EN": "Bug",
+ "FR": "Insecte",
+ "DE": "Käfer",
+ "IT": "Coleottero",
+ "RU": "Жучья форма",
+ "ES": "Bicho"
+ },
+ "pokemon_form_107": {
+ "PT-BR": "Fantasma",
+ "EN": "Ghost",
+ "FR": "Spectre",
+ "DE": "Geist",
+ "IT": "Spettro",
+ "RU": "Призрачная форма",
+ "ES": "Fantasma"
+ },
+ "pokemon_form_108": {
+ "PT-BR": "Aço",
+ "EN": "Steel",
+ "FR": "Acier",
+ "DE": "Stahl",
+ "IT": "Acciaio",
+ "RU": "Стальная форма",
+ "ES": "Acero"
+ },
+ "pokemon_form_109": {
+ "PT-BR": "Fogo",
+ "EN": "Fire",
+ "FR": "Feu",
+ "DE": "Feuer",
+ "IT": "Fuoco",
+ "RU": "Огненная форма",
+ "ES": "Fuego"
+ },
+ "pokemon_form_110": {
+ "PT-BR": "Água",
+ "EN": "Water",
+ "FR": "Eau",
+ "DE": "Wasser",
+ "IT": "Acqua",
+ "RU": "Водная форма",
+ "ES": "Agua"
+ },
+ "pokemon_form_111": {
+ "PT-BR": "Planta",
+ "EN": "Grass",
+ "FR": "Plante",
+ "DE": "Pflanze",
+ "IT": "Erba",
+ "RU": "Травяная форма",
+ "ES": "Planta"
+ },
+ "pokemon_form_112": {
+ "PT-BR": "Elétrico",
+ "EN": "Electric",
+ "FR": "Électrik",
+ "DE": "Elektro",
+ "IT": "Elettro",
+ "RU": "Электрическая форма",
+ "ES": "Eléctrico"
+ },
+ "pokemon_form_113": {
+ "PT-BR": "Psíquico",
+ "EN": "Psychic",
+ "FR": "Psy",
+ "DE": "Psycho",
+ "IT": "Psico",
+ "RU": "Психическая форма",
+ "ES": "Psíquico"
+ },
+ "pokemon_form_114": {
+ "PT-BR": "Gelo",
+ "EN": "Ice",
+ "FR": "Glace",
+ "DE": "Eis",
+ "IT": "Ghiaccio",
+ "RU": "Ледяная форма",
+ "ES": "Hielo"
+ },
+ "pokemon_form_115": {
+ "PT-BR": "Dragão",
+ "EN": "Dragon",
+ "DE": "Drache",
+ "IT": "Drago",
+ "RU": "Драконья форма",
+ "ES": "Dragón"
+ },
+ "pokemon_form_116": {
+ "PT-BR": "Sombrio",
+ "EN": "Dark",
+ "FR": "Ténèbres",
+ "DE": "Unlicht",
+ "IT": "Buio",
+ "RU": "Темная форма",
+ "ES": "Siniestro"
+ },
+ "pokemon_form_117": {
+ "PT-BR": "Fada",
+ "EN": "Fairy",
+ "FR": "Fée",
+ "DE": "Fee",
+ "IT": "Folletto",
+ "RU": "Феечная форма",
+ "ES": "Hada"
+ },
+ "pokemon_form_118": {
+ "PT-BR": "Manto Vegetal",
+ "EN": "Plant Cloak",
+ "FR": "Cape Plante",
+ "DE": "Pflanzenumhang",
+ "IT": "Manto Pianta",
+ "RU": "Растительный покров",
+ "ES": "Tronco Planta"
+ },
+ "pokemon_form_119": {
+ "PT-BR": "Manto Arenoso",
+ "EN": "Sandy Cloak",
+ "FR": "Cape Sable",
+ "DE": "Sandumhang",
+ "IT": "Manto Sabbia",
+ "RU": "Песчанный покров",
+ "ES": "Tronco Arena"
+ },
+ "pokemon_form_120": {
+ "PT-BR": "Manto de Lixo",
+ "EN": "Trash Cloak",
+ "FR": "Cape Déchet",
+ "DE": "Lumpenumhang",
+ "IT": "Manto Scarti",
+ "RU": "Мусорный покров",
+ "ES": "Tronco Basura"
+ },
+ "pokemon_form_121": {
+ "EN": "09"
+ },
+ "pokemon_form_122": {
+ "EN": "10"
+ },
+ "pokemon_form_123": {
+ "EN": "11"
+ },
+ "pokemon_form_124": {
+ "EN": "12"
+ },
+ "pokemon_form_125": {
+ "EN": "13"
+ },
+ "pokemon_form_126": {
+ "EN": "14"
+ },
+ "pokemon_form_127": {
+ "EN": "15"
+ },
+ "pokemon_form_128": {
+ "EN": "16"
+ },
+ "pokemon_form_129": {
+ "EN": "17"
+ },
+ "pokemon_form_130": {
+ "EN": "18"
+ },
+ "pokemon_form_131": {
+ "EN": "19"
+ },
+ "pokemon_form_132": {
+ "EN": "20"
+ },
+ "pokemon_form_133": {
+ "EN": "A",
+ "FR": "Armure",
+ "DE": "Rüstung"
+ },
+ "pokemon_form_136": {
+ "PT-BR": "Listras Vermelhas",
+ "EN": "Red-Striped",
+ "FR": "Motif Rouge",
+ "DE": "Rotlinig",
+ "IT": "Forma Linearossa",
+ "RU": "Красно-полосатая форма",
+ "ES": "Forma Raya Roja"
+ },
+ "pokemon_form_137": {
+ "PT-BR": "Listras Azuis",
+ "EN": "Blue-Striped",
+ "FR": "Motif Bleu",
+ "DE": "Blaulinig",
+ "IT": "Forma Lineablu",
+ "RU": "Сине-полосатая форма",
+ "ES": "Forma Raya Azul"
+ },
+ "pokemon_form_138": {
+ "EN": "Standard",
+ "RU": "Обычная форма"
+ },
+ "pokemon_form_139": {
+ "EN": "Zen",
+ "DE": "Trance",
+ "RU": "Дзен"
+ },
+ "pokemon_form_140": {
+ "PT-BR": "Forma Materializada",
+ "EN": "Incarnate Forme",
+ "FR": "Forme Avatar",
+ "DE": "Inkarnation",
+ "IT": "Forma Incarnazione",
+ "RU": "Воплощённая форма",
+ "ES": "Forma Avatar"
+ },
+ "pokemon_form_141": {
+ "PT-BR": "Forma Therian",
+ "EN": "Therian Forme",
+ "FR": "Forme Totémique",
+ "DE": "Tiergeist",
+ "IT": "Forma Totem",
+ "RU": "Териан форма",
+ "ES": "Forma Tótem"
+ },
+ "pokemon_form_142": {
+ "PT-BR": "Forma Materializada",
+ "EN": "Incarnate Forme",
+ "FR": "Forme Avatar",
+ "DE": "Inkarnation",
+ "IT": "Forma Incarnazione",
+ "RU": "Воплощённая форма",
+ "ES": "Forma Avatar"
+ },
+ "pokemon_form_143": {
+ "PT-BR": "Forma Therian",
+ "EN": "Therian Forme",
+ "FR": "Forme Totémique",
+ "DE": "Tiergeist",
+ "IT": "Forma Totem",
+ "RU": "Териан форма",
+ "ES": "Forma Tótem"
+ },
+ "pokemon_form_144": {
+ "PT-BR": "Forma Materializada",
+ "EN": "Incarnate Forme",
+ "FR": "Forme Avatar",
+ "DE": "Inkarnation",
+ "IT": "Forma Incarnazione",
+ "RU": "Воплощённая форма",
+ "ES": "Forma Avatar"
+ },
+ "pokemon_form_145": {
+ "PT-BR": "Forma Therian",
+ "EN": "Therian Forme",
+ "FR": "Forme Totémique",
+ "DE": "Tiergeist",
+ "IT": "Forma Totem",
+ "RU": "Териан форма",
+ "ES": "Forma Tótem"
+ },
+ "pokemon_form_147": {
+ "PT-BR": "Kyurem Preto",
+ "EN": "Black Kyurem",
+ "FR": "Kyurem Noir",
+ "DE": "Schwarz",
+ "IT": "Kyurem Nero",
+ "RU": "Чёрный Кьюрем",
+ "ES": "Kyurem Negro"
+ },
+ "pokemon_form_148": {
+ "PT-BR": "Kyurem Branco",
+ "EN": "White Kyurem",
+ "FR": "Kyurem Blanc",
+ "DE": "Weiß",
+ "IT": "Kyurem Bianco",
+ "RU": "Белый Кьюрем",
+ "ES": "Kyurem Blanco"
+ },
+ "pokemon_form_149": {
+ "PT-BR": "Forma Comum",
+ "EN": "Ordinary Form",
+ "FR": "Aspect Normal",
+ "DE": "Standard",
+ "IT": "Forma Normale",
+ "RU": "Обычная форма",
+ "ES": "Forma Habitual"
+ },
+ "pokemon_form_150": {
+ "PT-BR": "Forma Resoluta",
+ "EN": "Resolute Form",
+ "FR": "Resolute",
+ "DE": "Resolut",
+ "IT": "Forma Risoluta",
+ "RU": "Решительная форма",
+ "ES": "Forma Brío"
+ },
+ "pokemon_form_151": {
+ "PT-BR": "Forma Ária",
+ "EN": "Aria Forme",
+ "FR": "Forme Chant",
+ "DE": "Gesang",
+ "IT": "Forma Canto",
+ "RU": "Форма Арии",
+ "ES": "Forma Lírica"
+ },
+ "pokemon_form_152": {
+ "PT-BR": "Forma Pirueta",
+ "EN": "Pirouette Forme",
+ "FR": "Pirouette",
+ "DE": "Tanz",
+ "IT": "Forma Danza",
+ "RU": "Форма Пируэта",
+ "ES": "Forma Danza"
+ },
+ "pokemon_form_585": {
+ "PT-BR": "Forma Primavera",
+ "EN": "Spring Form",
+ "FR": "Forme Printemps",
+ "DE": "Frühling",
+ "IT": "Forma Primavera",
+ "RU": "Весенняя форма",
+ "ES": "Forma Primavera"
+ },
+ "pokemon_form_586": {
+ "PT-BR": "Forma Verão",
+ "EN": "Summer Form",
+ "FR": "Forme Été",
+ "DE": "Sommer",
+ "IT": "Forma Estate",
+ "RU": "Летняя форма",
+ "ES": "Forma Verano"
+ },
+ "pokemon_form_587": {
+ "PT-BR": "Forma Outono",
+ "EN": "Autumn Form",
+ "FR": "Forme Automne",
+ "DE": "Herbst",
+ "IT": "Forma Autunno",
+ "RU": "Осенняя форма",
+ "ES": "Forma Otoño"
+ },
+ "pokemon_form_588": {
+ "PT-BR": "Forma Inverno",
+ "EN": "Winter Form",
+ "FR": "Forme Hiver",
+ "DE": "Winter",
+ "IT": "Forma Inverno",
+ "RU": "Зимняя форма",
+ "ES": "Forma Invierno"
+ },
+ "pokemon_form_589": {
+ "PT-BR": "Forma Primavera",
+ "EN": "Spring Form",
+ "FR": "Forme Printemps",
+ "DE": "Frühling",
+ "IT": "Forma Primavera",
+ "RU": "Весенняя форма",
+ "ES": "Forma Primavera"
+ },
+ "pokemon_form_590": {
+ "PT-BR": "Forma Verão",
+ "EN": "Summer Form",
+ "FR": "Forme Été",
+ "DE": "Sommer",
+ "IT": "Forma Estate",
+ "RU": "Летняя форма",
+ "ES": "Forma Verano"
+ },
+ "pokemon_form_591": {
+ "PT-BR": "Forma Outono",
+ "EN": "Autumn Form",
+ "FR": "Forme Automne",
+ "DE": "Herbst",
+ "IT": "Forma Autunno",
+ "RU": "Осенняя форма",
+ "ES": "Forma Otoño"
+ },
+ "pokemon_form_592": {
+ "PT-BR": "Forma Inverno",
+ "EN": "Winter Form",
+ "FR": "Forme Hiver",
+ "DE": "Winter",
+ "IT": "Forma Inverno",
+ "RU": "Зимняя форма",
+ "ES": "Forma Invierno"
+ },
+ "pokemon_form_594": {
+ "EN": "Shock",
+ "FR": "Module Choc",
+ "DE": "Blitzmodul",
+ "RU": "Электрический привод"
+ },
+ "pokemon_form_595": {
+ "EN": "Burn",
+ "FR": "Module Pyro",
+ "DE": "Flammenmodul",
+ "RU": "Огненный привод"
+ },
+ "pokemon_form_596": {
+ "EN": "Chill",
+ "FR": "Module Cryo",
+ "DE": "Gefriermodul",
+ "RU": "Ледяной привод"
+ },
+ "pokemon_form_597": {
+ "EN": "Douse",
+ "FR": "Module Aqua",
+ "DE": "Aquamodul",
+ "RU": "Водный привод"
+ },
+ "pokemon_form_599": {
+ "EN": "Noevolve"
+ },
+ "pokemon_form_601": {
+ "EN": "Noevolve"
+ },
+ "pokemon_form_603": {
+ "EN": "Noevolve"
+ },
+ "pokemon_form_604": {
+ "EN": "Noevolve"
+ },
+ "pokemon_form_605": {
+ "EN": "Noevolve"
+ },
+ "pokemon_form_606": {
+ "EN": "Noevolve"
+ },
+ "pokemon_form_607": {
+ "EN": "Noevolve"
+ },
+ "pokemon_form_608": {
+ "EN": "Noevolve"
+ },
+ "pokemon_form_609": {
+ "EN": "Noevolve"
+ },
+ "pokemon_form_894": {
+ "EN": "Fall 2019",
+ "FR": "Automne 2019",
+ "DE": "Herbst 2019"
+ },
+ "pokemon_form_895": {
+ "EN": "Fall 2019",
+ "FR": "Automne 2019",
+ "DE": "Herbst 2019"
+ },
+ "pokemon_form_896": {
+ "EN": "Fall 2019",
+ "FR": "Automne 2019",
+ "DE": "Herbst 2019"
+ },
+ "pokemon_form_897": {
+ "EN": "Fall 2019",
+ "FR": "Automne 2019",
+ "DE": "Herbst 2019"
+ },
+ "pokemon_form_901": {
+ "EN": "Vs 2019"
+ },
+ "pokemon_form_944": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_946": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_948": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_949": {
+ "EN": "Copy 2019",
+ "FR": "Clone 2019",
+ "RU": "Клон 2019"
+ },
+ "pokemon_form_950": {
+ "EN": "Copy 2019",
+ "FR": "Clone 2019",
+ "RU": "Клон 2019"
+ },
+ "pokemon_form_951": {
+ "EN": "Copy 2019",
+ "FR": "Clone 2019",
+ "RU": "Клон 2019"
+ },
+ "pokemon_form_952": {
+ "EN": "Copy 2019",
+ "FR": "Clone 2019",
+ "RU": "Клон 2019"
+ },
+ "pokemon_form_2327": {
+ "EN": "Spring 2020",
+ "FR": "Printemps 2020",
+ "DE": "Frühjahr 2020",
+ "RU": "Весна 2020"
+ },
+ "pokemon_form_2328": {
+ "EN": "Spring 2020",
+ "FR": "Printemps 2020",
+ "DE": "Frühjahr 2020",
+ "RU": "Весна 2020"
+ },
+ "pokemon_form_2329": {
+ "EN": "Spring 2020",
+ "FR": "Printemps 2020",
+ "DE": "Frühjahr 2020",
+ "RU": "Весна 2020"
+ },
+ "pokemon_form_2330": {
+ "PT-BR": "Fêmea",
+ "EN": "Female",
+ "FR": "Femelle",
+ "DE": "Weiblich",
+ "IT": "Femmina",
+ "RU": "Женская форма",
+ "ES": "Hembra"
+ },
+ "pokemon_form_2331": {
+ "PT-BR": "Fêmea",
+ "EN": "Female",
+ "FR": "Femelle",
+ "DE": "Weiblich",
+ "IT": "Femmina",
+ "RU": "Женская форма",
+ "ES": "Hembra"
+ },
+ "pokemon_form_2332": {
+ "EN": "Costume 2020",
+ "DE": "Kostüm 2020",
+ "RU": "Костюм 2020"
+ },
+ "pokemon_form_2333": {
+ "EN": "Costume 2020",
+ "DE": "Kostüm 2020",
+ "RU": "Костюм 2020"
+ },
+ "pokemon_form_2334": {
+ "EN": "Costume 2020",
+ "DE": "Kostüm 2020",
+ "RU": "Костюм 2020"
+ },
+ "pokemon_form_2335": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2336": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2337": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2338": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2339": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2340": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2341": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2342": {
+ "EN": "Galarian Standard",
+ "DE": "Galar Normal",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2343": {
+ "EN": "Galarian Zen",
+ "DE": "Galar Trance",
+ "RU": "Галарская форма Дзен"
+ },
+ "pokemon_form_2344": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2345": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2463": {
+ "PT-BR": "Forma Grave",
+ "EN": "Low Key Form",
+ "DE": "Tief-Form",
+ "IT": "Forma Basso",
+ "RU": "Сдержанная форма",
+ "ES": "Forma Grave"
+ },
+ "pokemon_form_2464": {
+ "PT-BR": "Forma Aguda",
+ "EN": "Amped Form",
+ "DE": "Hoch-Form",
+ "IT": "Forma Melodia",
+ "RU": "Восторженная форма",
+ "ES": "Forma Aguda"
+ },
+ "pokemon_form_2477": {
+ "PT-BR": "Forma Falsificada",
+ "EN": "Phony Form",
+ "FR": "Forme Contrefaçon",
+ "DE": "Fälschungsform",
+ "IT": "Forma Contraffatta",
+ "RU": "Фальшивая форма",
+ "ES": "Forma Falsificada"
+ },
+ "pokemon_form_2478": {
+ "PT-BR": "Forma Autêntica",
+ "EN": "Antique Form",
+ "FR": "Forme Authentique",
+ "DE": "Originalform",
+ "IT": "Forma Autentica",
+ "RU": "Антикварная форма",
+ "ES": "Forma Genuina"
+ },
+ "pokemon_form_2480": {
+ "PT-BR": "Forma Falsificada",
+ "EN": "Phony Form",
+ "FR": "Forme Contrefaçon",
+ "DE": "Fälschungsform",
+ "IT": "Forma Contraffatta",
+ "RU": "Фальшивая форма",
+ "ES": "Forma Falsificada"
+ },
+ "pokemon_form_2481": {
+ "PT-BR": "Forma Autêntica",
+ "EN": "Antique Form",
+ "FR": "Forme Authentique",
+ "DE": "Originalform",
+ "IT": "Forma Autentica",
+ "RU": "Антикварная форма",
+ "ES": "Forma Genuina"
+ },
+ "pokemon_form_2540": {
+ "PT-BR": "Cara de Gelo",
+ "EN": "Ice Face",
+ "DE": "Tiefkühlkopf",
+ "IT": "Gelofaccia",
+ "RU": "Ледяное лицо",
+ "ES": "Cara de Hielo"
+ },
+ "pokemon_form_2541": {
+ "PT-BR": "Cara Degelada",
+ "EN": "Noice Face",
+ "DE": "Wohlfühlkopf",
+ "IT": "Liquefaccia",
+ "RU": "Неледяное лицо",
+ "ES": "Cara Deshielo"
+ },
+ "pokemon_form_2542": {
+ "PT-BR": "Macho",
+ "EN": "Male",
+ "FR": "Mâle",
+ "DE": "Männlich",
+ "IT": "Maschio",
+ "RU": "Мужская форма",
+ "ES": "Macho"
+ },
+ "pokemon_form_2543": {
+ "PT-BR": "Fêmea",
+ "EN": "Female",
+ "FR": "Femelle",
+ "DE": "Weiblich",
+ "IT": "Femmina",
+ "RU": "Женская форма",
+ "ES": "Hembra"
+ },
+ "pokemon_form_2544": {
+ "EN": "Full Belly",
+ "DE": "Pappsatt",
+ "RU": "Режим Полный Живот"
+ },
+ "pokemon_form_2545": {
+ "EN": "Hangry",
+ "DE": "Kohldampf",
+ "RU": "Злоголодный режим"
+ },
+ "pokemon_form_2576": {
+ "EN": "Crowned Sword",
+ "DE": "König des Schwertes",
+ "RU": "Коронованный Меч"
+ },
+ "pokemon_form_2577": {
+ "EN": "Hero",
+ "DE": "Heldenhafter Krieger",
+ "RU": "Герой многих битв"
+ },
+ "pokemon_form_2578": {
+ "EN": "Crowned Shield",
+ "DE": "König des Schildes",
+ "RU": "Коронованный Щит"
+ },
+ "pokemon_form_2579": {
+ "EN": "Hero",
+ "DE": "Heldenhafter Krieger",
+ "RU": "Герой многих битв"
+ },
+ "pokemon_form_2580": {
+ "EN": "Eternamax",
+ "DE": "Unendynamax",
+ "RU": "Этернамакс"
+ },
+ "pokemon_form_2582": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2583": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2584": {
+ "EN": "Galarian",
+ "DE": "Galar",
+ "RU": "Галарская форма"
+ },
+ "pokemon_form_2585": {
+ "EN": "Costume 2020",
+ "DE": "Kostüm 2020",
+ "RU": "Костюм 2020"
+ },
+ "pokemon_form_2586": {
+ "EN": "Costume 2020",
+ "DE": "Kostüm 2020",
+ "RU": "Костюм 2020"
+ },
+ "pokemon_form_2588": {
+ "PT-BR": "Fêmea",
+ "EN": "Female",
+ "FR": "Femelle",
+ "DE": "Weiblich",
+ "IT": "Femmina",
+ "RU": "Женская форма",
+ "ES": "Hembra"
+ },
+ "pokemon_form_2590": {
+ "PT-BR": "Fêmea",
+ "EN": "Female",
+ "FR": "Femelle",
+ "DE": "Weiblich",
+ "IT": "Femmina",
+ "RU": "Женская форма",
+ "ES": "Hembra"
+ },
+ "pokemon_form_2591": {
+ "EN": "Ten Percent",
+ "DE": "10%",
+ "RU": "10% форма"
+ },
+ "pokemon_form_2592": {
+ "EN": "Fifty Percent",
+ "DE": "50%",
+ "RU": "50% форма"
+ },
+ "pokemon_form_2593": {
+ "EN": "Complete",
+ "DE": "Optimum",
+ "RU": "Завершенная форма"
+ },
+ "pokemon_form_2594": {
+ "EN": "Archipelago",
+ "DE": "Archipel",
+ "RU": "Островная форма"
+ },
+ "pokemon_form_2595": {
+ "EN": "Continental",
+ "DE": "Kontinental",
+ "RU": "Континентальная форма"
+ },
+ "pokemon_form_2596": {
+ "EN": "Elegant",
+ "DE": "Prunk",
+ "RU": "Элегантная форма"
+ },
+ "pokemon_form_2597": {
+ "EN": "Fancy",
+ "RU": "Изысканная форма"
+ },
+ "pokemon_form_2598": {
+ "EN": "Garden",
+ "DE": "Ziergarten",
+ "RU": "Садовая форма"
+ },
+ "pokemon_form_2599": {
+ "EN": "High Plains",
+ "DE": "Dürre",
+ "RU": "Равнинная форма"
+ },
+ "pokemon_form_2600": {
+ "EN": "Icy Snow",
+ "DE": "Frost",
+ "RU": "Ледяная форма"
+ },
+ "pokemon_form_2601": {
+ "EN": "Jungle",
+ "DE": "Dschungel",
+ "RU": "Форма джунглей"
+ },
+ "pokemon_form_2602": {
+ "EN": "Marine",
+ "DE": "Aquamarin",
+ "RU": "Морская форма"
+ },
+ "pokemon_form_2603": {
+ "EN": "Meadow",
+ "DE": "Blumenmeer",
+ "RU": "Луговая форма"
+ },
+ "pokemon_form_2604": {
+ "EN": "Modern",
+ "DE": "Innovation",
+ "RU": "Современная форма"
+ },
+ "pokemon_form_2605": {
+ "EN": "Monsoon",
+ "DE": "Monsun",
+ "RU": "Муссонная форма"
+ },
+ "pokemon_form_2606": {
+ "EN": "Ocean",
+ "DE": "Ozean",
+ "RU": "Океаническая форма"
+ },
+ "pokemon_form_2607": {
+ "EN": "Pokeball",
+ "RU": "Форма покебола"
+ },
+ "pokemon_form_2608": {
+ "EN": "Polar",
+ "DE": "Schneefeld",
+ "RU": "Полярная форма"
+ },
+ "pokemon_form_2609": {
+ "EN": "River",
+ "DE": "Flussdelta",
+ "RU": "Речная форма"
+ },
+ "pokemon_form_2610": {
+ "EN": "Sandstorm",
+ "DE": "Sand",
+ "RU": "Форма песчанной бури"
+ },
+ "pokemon_form_2611": {
+ "EN": "Savanna",
+ "DE": "Savanne",
+ "RU": "Саванновая форма"
+ },
+ "pokemon_form_2612": {
+ "PT-BR": "Ensolarada",
+ "EN": "Sunny",
+ "FR": "Sun",
+ "DE": "Sonne",
+ "IT": "Sole",
+ "RU": "Солнечная форма",
+ "ES": "Sol"
+ },
+ "pokemon_form_2613": {
+ "EN": "Tundra",
+ "DE": "Flocke",
+ "RU": "Тундровая форма"
+ },
+ "pokemon_form_2614": {
+ "EN": "Red Flower",
+ "FR": "Red",
+ "DE": "Rotblütler",
+ "RU": "Красная форма"
+ },
+ "pokemon_form_2615": {
+ "EN": "Yellow Flower",
+ "FR": "Yellow",
+ "DE": "Gelbblütler",
+ "RU": "Желтая форма"
+ },
+ "pokemon_form_2616": {
+ "EN": "Orange Flower",
+ "FR": "Orange",
+ "DE": "Orangeblütler",
+ "RU": "Oранжевая форма"
+ },
+ "pokemon_form_2617": {
+ "EN": "Blue Flower",
+ "FR": "Blue",
+ "DE": "Blaublütler",
+ "RU": "Синяя форма"
+ },
+ "pokemon_form_2618": {
+ "EN": "White Flower",
+ "FR": "White",
+ "DE": "Weißblütler",
+ "RU": "Белая форма"
+ },
+ "pokemon_form_2619": {
+ "EN": "Red Flower",
+ "FR": "Red",
+ "DE": "Rotblütler",
+ "RU": "Красная форма"
+ },
+ "pokemon_form_2620": {
+ "EN": "Yellow Flower",
+ "FR": "Yellow",
+ "DE": "Gelbblütler",
+ "RU": "Желтая форма"
+ },
+ "pokemon_form_2621": {
+ "EN": "Orange Flower",
+ "FR": "Orange",
+ "DE": "Orangeblütler",
+ "RU": "Оранжевая форма"
+ },
+ "pokemon_form_2622": {
+ "EN": "Blue Flower",
+ "FR": "Blue",
+ "DE": "Blaublütler",
+ "RU": "Синяя форма"
+ },
+ "pokemon_form_2623": {
+ "EN": "White Flower",
+ "FR": "White",
+ "DE": "Weißblütler",
+ "RU": "Белая форма"
+ },
+ "pokemon_form_2624": {
+ "EN": "Red Flower",
+ "FR": "Red",
+ "DE": "Rotblütler",
+ "RU": "Красная форма"
+ },
+ "pokemon_form_2625": {
+ "EN": "Yellow Flower",
+ "FR": "Yellow",
+ "DE": "Gelbblütler",
+ "RU": "Желтая форма"
+ },
+ "pokemon_form_2626": {
+ "EN": "Orange Flower",
+ "FR": "Orange",
+ "DE": "Orangeblütler",
+ "RU": "Оранжевая форма"
+ },
+ "pokemon_form_2627": {
+ "EN": "Blue Flower",
+ "FR": "Blue",
+ "DE": "Blaublütler",
+ "RU": "Синяя форма"
+ },
+ "pokemon_form_2628": {
+ "EN": "White Flower",
+ "FR": "White",
+ "DE": "Weißblütler",
+ "RU": "Белая форма"
+ },
+ "pokemon_form_2629": {
+ "EN": "Natural",
+ "DE": "Zottelform",
+ "RU": "Исходная форма"
+ },
+ "pokemon_form_2630": {
+ "EN": "Heart Trim",
+ "FR": "Heart",
+ "DE": "Herzchenschnitt",
+ "RU": "Сердечная форма"
+ },
+ "pokemon_form_2631": {
+ "EN": "Star Trim",
+ "FR": "Star",
+ "DE": "Sternchenschnitt",
+ "RU": "Звездная форма"
+ },
+ "pokemon_form_2632": {
+ "EN": "Diamond Trim",
+ "FR": "Diamond",
+ "DE": "Diamantenschnitt",
+ "RU": "Бриллиантовая форма"
+ },
+ "pokemon_form_2633": {
+ "EN": "Debutante Trim",
+ "FR": "Debutante",
+ "DE": "Fräuleinschnitt",
+ "RU": "Дебютантская форма"
+ },
+ "pokemon_form_2634": {
+ "EN": "Matron Trim",
+ "FR": "Matron",
+ "DE": "Damenschnitt",
+ "RU": "Матронская форма"
+ },
+ "pokemon_form_2635": {
+ "EN": "Dandy Trim",
+ "FR": "Dandy",
+ "DE": "Kavaliersschnitt",
+ "RU": "Светская форма"
+ },
+ "pokemon_form_2636": {
+ "EN": "La Reine Trim",
+ "FR": "La Reine",
+ "DE": "Königinnenschnitt",
+ "RU": "Форма Ла Рейне"
+ },
+ "pokemon_form_2637": {
+ "EN": "Kabuki Trim",
+ "FR": "Kabuki",
+ "DE": "Kabuki-Schnitt",
+ "RU": "Форма кабуки"
+ },
+ "pokemon_form_2638": {
+ "EN": "Pharaoh Trim",
+ "FR": "Pharaoh",
+ "DE": "Herrscherschnitt",
+ "RU": "Форма фараона"
+ },
+ "pokemon_form_2639": {
+ "EN": "Shield",
+ "DE": "Schild",
+ "RU": "Форма щита"
+ },
+ "pokemon_form_2640": {
+ "EN": "Blade",
+ "DE": "Schwert",
+ "RU": "Форма меча"
+ },
+ "pokemon_form_2641": {
+ "EN": "Small",
+ "FR": "Mini",
+ "DE": "S",
+ "RU": "Маленькая форма"
+ },
+ "pokemon_form_2642": {
+ "EN": "Average",
+ "FR": "Normale",
+ "DE": "M",
+ "RU": "Средняя форма"
+ },
+ "pokemon_form_2643": {
+ "EN": "Large",
+ "FR": "Maxi",
+ "DE": "L",
+ "RU": "Большая форма"
+ },
+ "pokemon_form_2644": {
+ "EN": "Super",
+ "FR": "Ultra",
+ "DE": "XL",
+ "RU": "Огромная форма"
+ },
+ "pokemon_form_2645": {
+ "EN": "Small",
+ "FR": "Mini",
+ "DE": "S",
+ "RU": "Маленькая форма"
+ },
+ "pokemon_form_2646": {
+ "EN": "Average",
+ "FR": "Normale",
+ "DE": "M",
+ "RU": "Средняя форма"
+ },
+ "pokemon_form_2647": {
+ "EN": "Large",
+ "FR": "Maxi",
+ "DE": "L",
+ "RU": "Большая форма"
+ },
+ "pokemon_form_2648": {
+ "EN": "Super",
+ "FR": "Ultra",
+ "DE": "XL",
+ "RU": "Огромная форма"
+ },
+ "pokemon_form_2649": {
+ "EN": "Neutral",
+ "RU": "Нейтральная форма"
+ },
+ "pokemon_form_2650": {
+ "EN": "Active",
+ "DE": "Aktiv",
+ "RU": "Активная форма"
+ },
+ "pokemon_form_2651": {
+ "EN": "Confined",
+ "DE": "Beschränkt",
+ "RU": "Невольная форма"
+ },
+ "pokemon_form_2652": {
+ "EN": "Unbound",
+ "DE": "Ungebunden",
+ "RU": "Высвобожденная форма"
+ },
+ "pokemon_form_2666": {
+ "EN": "Costume 2020 Deprecated",
+ "DE": "Kostüm 2020 Deprecated",
+ "RU": "Костюм 2020 Устаревший"
+ },
+ "pokemon_form_2668": {
+ "EN": "Costume 2020",
+ "DE": "Kostüm 2020",
+ "RU": "Костюм 2020"
+ },
+ "pokemon_form_2669": {
+ "EN": "Adventure Hat 2020",
+ "DE": "Abenteuerhut 2020"
+ },
+ "pokemon_form_2670": {
+ "EN": "Winter 2020",
+ "FR": "Hiver 2020",
+ "RU": "Зима 2020"
+ },
+ "pokemon_form_2671": {
+ "EN": "Winter 2020",
+ "FR": "Hiver 2020",
+ "RU": "Зима 2020"
+ },
+ "pokemon_form_2672": {
+ "EN": "Winter 2020",
+ "FR": "Hiver 2020",
+ "RU": "Зима 2020"
+ },
+ "pokemon_form_2673": {
+ "EN": "2020"
+ },
+ "pokemon_form_2674": {
+ "EN": "2021"
+ },
+ "pokemon_form_2675": {
+ "EN": "Kariyushi",
+ "RU": "Кариюши"
+ },
+ "pokemon_form_2676": {
+ "EN": "Pop Star",
+ "RU": "Поп-звезда"
+ },
+ "pokemon_form_2677": {
+ "EN": "Rock Star",
+ "RU": "Рок-звезда"
+ },
+ "pokemon_form_2678": {
+ "EN": "Flying 5th Anniv",
+ "DE": "Fliegendes 5. Jubiläum",
+ "RU": "Пятилетняя годовщина"
+ },
+ "pokemon_form_2679": {
+ "PT-BR": "Estilo Flamenco",
+ "EN": "Baile Style",
+ "FR": "Style Flamenco",
+ "DE": "Flamenco",
+ "IT": "Stile Flamenco",
+ "RU": "Бальный стиль",
+ "ES": "Estilo Apasionado"
+ },
+ "pokemon_form_2680": {
+ "PT-BR": "Estilo Animado",
+ "EN": "Pom-Pom Style",
+ "FR": "Style Pom-Pom",
+ "DE": "Cheerleading",
+ "IT": "Stile Cheerdance",
+ "RU": "Стиль Пом-Пом",
+ "ES": "Estilo Animado"
+ },
+ "pokemon_form_2681": {
+ "PT-BR": "Estilo Hula",
+ "EN": "Pa’u Style",
+ "FR": "Style Hula",
+ "DE": "Hula",
+ "IT": "Stile Hula",
+ "RU": "Стиль Пау",
+ "ES": "Estilo Plácido"
+ },
+ "pokemon_form_2683": {
+ "PT-BR": "Estilo Elegante",
+ "EN": "Sensu Style",
+ "FR": "Style Buyô",
+ "DE": "Buyo",
+ "IT": "Stile Buyō",
+ "RU": "Чувственный стиль",
+ "ES": "Estilo Refinado"
+ },
+ "pokemon_form_2684": {
+ "PT-BR": "Forma Diurna",
+ "EN": "Midday Form",
+ "FR": "Forme Diurne",
+ "DE": "Tag",
+ "IT": "Forma Giorno",
+ "RU": "Полуденная форма",
+ "ES": "Forma Diurna"
+ },
+ "pokemon_form_2685": {
+ "PT-BR": "Forma Noturna",
+ "EN": "Midnight Form",
+ "FR": "Forme Nocturne",
+ "DE": "Nacht",
+ "IT": "Forma Notte",
+ "RU": "Полуночная форма",
+ "ES": "Forma Nocturna"
+ },
+ "pokemon_form_2686": {
+ "PT-BR": "Forma Crepúsculo",
+ "EN": "Dusk Form",
+ "FR": "Forme Crépusculaire",
+ "DE": "Zwielicht",
+ "IT": "Forma Crepuscolo",
+ "RU": "Сумеречная форма",
+ "ES": "Forma Crepuscular"
+ },
+ "pokemon_form_2687": {
+ "PT-BR": "Forma Individual",
+ "EN": "Solo Form",
+ "DE": "Einzel",
+ "IT": "Forma Individuale",
+ "RU": "Форма соло",
+ "ES": "Forma Individual"
+ },
+ "pokemon_form_2688": {
+ "PT-BR": "Forma Cardume",
+ "EN": "School Form",
+ "DE": "Schwarm",
+ "IT": "Forma Banco",
+ "RU": "Форма стая",
+ "ES": "Forma Banco"
+ },
+ "pokemon_form_2690": {
+ "PT-BR": "Inseto",
+ "EN": "Bug",
+ "FR": "Insecte",
+ "DE": "Käfer",
+ "IT": "Coleottero",
+ "RU": "Жучья форма",
+ "ES": "Bicho"
+ },
+ "pokemon_form_2691": {
+ "PT-BR": "Sombrio",
+ "EN": "Dark",
+ "FR": "Ténèbres",
+ "DE": "Unlicht",
+ "IT": "Buio",
+ "RU": "Темная форма",
+ "ES": "Siniestro"
+ },
+ "pokemon_form_2692": {
+ "PT-BR": "Dragão",
+ "EN": "Dragon",
+ "DE": "Drache",
+ "IT": "Drago",
+ "RU": "Драконья форма",
+ "ES": "Dragón"
+ },
+ "pokemon_form_2693": {
+ "PT-BR": "Elétrico",
+ "EN": "Electric",
+ "FR": "Électrik",
+ "DE": "Elektro",
+ "IT": "Elettro",
+ "RU": "Электрическая форма",
+ "ES": "Eléctrico"
+ },
+ "pokemon_form_2694": {
+ "PT-BR": "Fada",
+ "EN": "Fairy",
+ "FR": "Fée",
+ "DE": "Fee",
+ "IT": "Folletto",
+ "RU": "Феечная форма",
+ "ES": "Hada"
+ },
+ "pokemon_form_2695": {
+ "PT-BR": "Lutador",
+ "EN": "Fighting",
+ "FR": "Combat",
+ "DE": "Kampf",
+ "IT": "Lotta",
+ "RU": "Боевая форма",
+ "ES": "Lucha"
+ },
+ "pokemon_form_2696": {
+ "PT-BR": "Fogo",
+ "EN": "Fire",
+ "FR": "Feu",
+ "DE": "Feuer",
+ "IT": "Fuoco",
+ "RU": "Огненная форма",
+ "ES": "Fuego"
+ },
+ "pokemon_form_2697": {
+ "PT-BR": "Voador",
+ "EN": "Flying",
+ "FR": "Vol",
+ "DE": "Flug",
+ "IT": "Volante",
+ "RU": "Летающая форма",
+ "ES": "Volador"
+ },
+ "pokemon_form_2698": {
+ "PT-BR": "Fantasma",
+ "EN": "Ghost",
+ "FR": "Spectre",
+ "DE": "Geist",
+ "IT": "Spettro",
+ "RU": "Призрачная форма",
+ "ES": "Fantasma"
+ },
+ "pokemon_form_2699": {
+ "PT-BR": "Planta",
+ "EN": "Grass",
+ "FR": "Plante",
+ "DE": "Pflanze",
+ "IT": "Erba",
+ "RU": "Травяная форма",
+ "ES": "Planta"
+ },
+ "pokemon_form_2700": {
+ "PT-BR": "Terrestre",
+ "EN": "Ground",
+ "FR": "Sol",
+ "DE": "Boden",
+ "IT": "Terra",
+ "RU": "Земляная форма",
+ "ES": "Tierra"
+ },
+ "pokemon_form_2701": {
+ "PT-BR": "Gelo",
+ "EN": "Ice",
+ "FR": "Glace",
+ "DE": "Eis",
+ "IT": "Ghiaccio",
+ "RU": "Ледяная форма",
+ "ES": "Hielo"
+ },
+ "pokemon_form_2702": {
+ "PT-BR": "Venenoso",
+ "EN": "Poison",
+ "DE": "Gift",
+ "IT": "Veleno",
+ "RU": "Ядовитая форма",
+ "ES": "Veneno"
+ },
+ "pokemon_form_2703": {
+ "PT-BR": "Psíquico",
+ "EN": "Psychic",
+ "FR": "Psy",
+ "DE": "Psycho",
+ "IT": "Psico",
+ "RU": "Психическая форма",
+ "ES": "Psíquico"
+ },
+ "pokemon_form_2704": {
+ "PT-BR": "Pedra",
+ "EN": "Rock",
+ "FR": "Roche",
+ "DE": "Gestein",
+ "IT": "Roccia",
+ "RU": "Каменная форма",
+ "ES": "Roca"
+ },
+ "pokemon_form_2705": {
+ "PT-BR": "Aço",
+ "EN": "Steel",
+ "FR": "Acier",
+ "DE": "Stahl",
+ "IT": "Acciaio",
+ "RU": "Стальная форма",
+ "ES": "Acero"
+ },
+ "pokemon_form_2706": {
+ "PT-BR": "Água",
+ "EN": "Water",
+ "FR": "Eau",
+ "DE": "Wasser",
+ "IT": "Acqua",
+ "RU": "Водная форма",
+ "ES": "Agua"
+ },
+ "pokemon_form_2707": {
+ "EN": "Meteor Blue",
+ "DE": "Meteor",
+ "RU": "Метеорная форма"
+ },
+ "pokemon_form_2708": {
+ "PT-BR": "Plumagem Azul",
+ "EN": "Blue Plumage",
+ "FR": "Plumage Bleu",
+ "DE": "Blau",
+ "IT": "Piume Azzurre",
+ "RU": "Голубая форма",
+ "ES": "Plumaje Azul"
+ },
+ "pokemon_form_2709": {
+ "PT-BR": "Plumagem Verde",
+ "EN": "Green Plumage",
+ "FR": "Plumage Vert",
+ "DE": "Grün",
+ "IT": "Piume Verdi",
+ "RU": "Зеленая форма",
+ "ES": "Plumaje Verde"
+ },
+ "pokemon_form_2710": {
+ "EN": "Indigo",
+ "DE": "Hellblau",
+ "RU": "Индиго форма"
+ },
+ "pokemon_form_2711": {
+ "EN": "Orange",
+ "RU": "Оранжевая форма"
+ },
+ "pokemon_form_2712": {
+ "EN": "Red",
+ "DE": "Rot",
+ "RU": "Красная форма"
+ },
+ "pokemon_form_2713": {
+ "EN": "Violet",
+ "DE": "Violett",
+ "RU": "Фиолетовая форма"
+ },
+ "pokemon_form_2714": {
+ "PT-BR": "Plumagem Amarela",
+ "EN": "Yellow Plumage",
+ "FR": "Plumage Jaune",
+ "DE": "Gelb",
+ "IT": "Piume Gialle",
+ "RU": "Желтая форма",
+ "ES": "Plumaje Amarillo"
+ },
+ "pokemon_form_2715": {
+ "PT-BR": "Forma Desmascarada",
+ "EN": "Busted Form",
+ "DE": "Entlarvt",
+ "IT": "Forma Smascherata",
+ "RU": "Сломанная форма",
+ "ES": "Forma Descubierta"
+ },
+ "pokemon_form_2716": {
+ "PT-BR": "Forma Mascarada",
+ "EN": "Disguised Form",
+ "DE": "Standard",
+ "IT": "Forma Mascherata",
+ "RU": "Замаскированная форма",
+ "ES": "Forma Encubierta"
+ },
+ "pokemon_form_2718": {
+ "EN": "Dusk Mane",
+ "DE": "Abendmähne",
+ "RU": "Грива заката"
+ },
+ "pokemon_form_2719": {
+ "EN": "Dawn Wings",
+ "DE": "Morgenschwingen",
+ "RU": "Крылья рассвета"
+ },
+ "pokemon_form_2720": {
+ "EN": "Ultra",
+ "RU": "Ультра форма"
+ },
+ "pokemon_form_2722": {
+ "EN": "Original Color",
+ "DE": "Originalfarbe",
+ "RU": "Исходный цвет"
+ },
+ "pokemon_form_2723": {
+ "PT-BR": "Estilo Golpe Decisivo",
+ "EN": "Single Strike Style",
+ "FR": "Style Poing Final",
+ "DE": "Fokussierter Stil",
+ "IT": "Stile Singolcolpo",
+ "RU": "Фома одного удара",
+ "ES": "Estilo Brusco"
+ },
+ "pokemon_form_2724": {
+ "PT-BR": "Estilo Golpe Fluido",
+ "EN": "Rapid Strike Style",
+ "FR": "Style Mille Poings",
+ "DE": "Fließender Stil",
+ "IT": "Stile Pluricolpo",
+ "RU": "Форма множества ударов",
+ "ES": "Estilo Fluido"
+ },
+ "pokemon_form_2726": {
+ "EN": "Ice Rider",
+ "DE": "Schimmelreiter",
+ "RU": "Ледяной всадник"
+ },
+ "pokemon_form_2727": {
+ "EN": "Shadow Rider",
+ "RU": "Теневой всадник"
+ },
+ "pokemon_form_2728": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2729": {
+ "EN": "S"
+ },
+ "pokemon_form_2730": {
+ "EN": "S"
+ },
+ "pokemon_form_2731": {
+ "EN": "S"
+ },
+ "pokemon_form_2732": {
+ "EN": "S"
+ },
+ "pokemon_form_2733": {
+ "EN": "S"
+ },
+ "pokemon_form_2734": {
+ "EN": "2022"
+ },
+ "pokemon_form_2735": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2736": {
+ "EN": "Flying Okinawa"
+ },
+ "pokemon_form_2737": {
+ "PT-BR": "Forma Crepúsculo",
+ "EN": "Dusk Form",
+ "FR": "Forme Crépusculaire",
+ "DE": "Zwielichtform",
+ "IT": "Forma Crepuscolo",
+ "RU": "Сумеречная Форма",
+ "ES": "Forma Crepuscular"
+ },
+ "pokemon_form_2739": {
+ "EN": "Meteor Green"
+ },
+ "pokemon_form_2740": {
+ "EN": "Meteor Indigo"
+ },
+ "pokemon_form_2741": {
+ "EN": "Meteor Orange"
+ },
+ "pokemon_form_2742": {
+ "EN": "Meteor Red"
+ },
+ "pokemon_form_2743": {
+ "EN": "Meteor Violet"
+ },
+ "pokemon_form_2744": {
+ "EN": "Meteor Yellow"
+ },
+ "pokemon_form_2745": {
+ "EN": "Archipelago"
+ },
+ "pokemon_form_2746": {
+ "EN": "Continental"
+ },
+ "pokemon_form_2747": {
+ "EN": "Elegant"
+ },
+ "pokemon_form_2748": {
+ "EN": "Fancy"
+ },
+ "pokemon_form_2749": {
+ "EN": "Garden"
+ },
+ "pokemon_form_2750": {
+ "EN": "High Plains"
+ },
+ "pokemon_form_2751": {
+ "EN": "Icy Snow"
+ },
+ "pokemon_form_2752": {
+ "EN": "Jungle"
+ },
+ "pokemon_form_2753": {
+ "EN": "Marine"
+ },
+ "pokemon_form_2754": {
+ "EN": "Meadow"
+ },
+ "pokemon_form_2755": {
+ "EN": "Modern"
+ },
+ "pokemon_form_2756": {
+ "EN": "Monsoon"
+ },
+ "pokemon_form_2757": {
+ "EN": "Ocean"
+ },
+ "pokemon_form_2758": {
+ "EN": "Pokeball"
+ },
+ "pokemon_form_2759": {
+ "EN": "Polar"
+ },
+ "pokemon_form_2760": {
+ "EN": "River"
+ },
+ "pokemon_form_2761": {
+ "EN": "Sandstorm"
+ },
+ "pokemon_form_2762": {
+ "EN": "Savanna"
+ },
+ "pokemon_form_2763": {
+ "PT-BR": "Ensolarada",
+ "EN": "Sunny",
+ "FR": "Solaire",
+ "DE": "Sonnenform",
+ "IT": "Sole",
+ "RU": "Солнечная Форма",
+ "ES": "Sol"
+ },
+ "pokemon_form_2764": {
+ "EN": "Tundra"
+ },
+ "pokemon_form_2765": {
+ "EN": "Archipelago"
+ },
+ "pokemon_form_2766": {
+ "EN": "Continental"
+ },
+ "pokemon_form_2767": {
+ "EN": "Elegant"
+ },
+ "pokemon_form_2768": {
+ "EN": "Fancy"
+ },
+ "pokemon_form_2769": {
+ "EN": "Garden"
+ },
+ "pokemon_form_2770": {
+ "EN": "High Plains"
+ },
+ "pokemon_form_2771": {
+ "EN": "Icy Snow"
+ },
+ "pokemon_form_2772": {
+ "EN": "Jungle"
+ },
+ "pokemon_form_2773": {
+ "EN": "Marine"
+ },
+ "pokemon_form_2774": {
+ "EN": "Meadow"
+ },
+ "pokemon_form_2775": {
+ "EN": "Modern"
+ },
+ "pokemon_form_2776": {
+ "EN": "Monsoon"
+ },
+ "pokemon_form_2777": {
+ "EN": "Ocean"
+ },
+ "pokemon_form_2778": {
+ "EN": "Pokeball"
+ },
+ "pokemon_form_2779": {
+ "EN": "Polar"
+ },
+ "pokemon_form_2780": {
+ "EN": "River"
+ },
+ "pokemon_form_2781": {
+ "EN": "Sandstorm"
+ },
+ "pokemon_form_2782": {
+ "EN": "Savanna"
+ },
+ "pokemon_form_2783": {
+ "PT-BR": "Ensolarada",
+ "EN": "Sunny",
+ "FR": "Solaire",
+ "DE": "Sonnenform",
+ "IT": "Sole",
+ "RU": "Солнечная Форма",
+ "ES": "Sol"
+ },
+ "pokemon_form_2784": {
+ "EN": "Tundra"
+ },
+ "pokemon_form_2785": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2786": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2787": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2788": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2789": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2790": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2791": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2792": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2793": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2794": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2795": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2796": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2797": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2798": {
+ "EN": "Hisuian"
+ },
+ "pokemon_form_2799": {
+ "EN": "Galarian"
+ },
+ "pokemon_form_2800": {
+ "EN": "Galarian"
+ },
+ "pokemon_form_2801": {
+ "EN": "Galarian"
+ },
+ "pokemon_form_2802": {
+ "PT-BR": "Forma Materializada",
+ "EN": "Incarnate Forme",
+ "FR": "Forme Avatar",
+ "DE": "Inkarnationsform",
+ "IT": "Forma Incarnazione",
+ "RU": "Воплощённая Форма",
+ "ES": "Forma Avatar"
+ },
+ "pokemon_form_2803": {
+ "PT-BR": "Forma Therian",
+ "EN": "Therian Forme",
+ "FR": "Forme Totémique",
+ "DE": "Tiergeistform",
+ "IT": "Forma Totem",
+ "RU": "Териан-Форма",
+ "ES": "Forma Tótem"
+ },
+ "pokemon_form_2804": {
+ "PT-BR": "Listras Brancas",
+ "EN": "White-Striped",
+ "FR": "Motif Blanc",
+ "DE": "Weißlinig",
+ "IT": "Forma Lineabianca",
+ "RU": "Белая Полосатая Форма",
+ "ES": "Raya Blanca"
+ },
+ "pokemon_form_2805": {
+ "EN": "Gofest 2022"
+ },
+ "pokemon_form_2806": {
+ "EN": "Wcs 2022"
+ },
+ "pokemon_form_2808": {
+ "PT-BR": "Fêmea",
+ "EN": "Female",
+ "FR": "Femelle",
+ "DE": "Weiblich",
+ "IT": "Femmina",
+ "RU": "Женская Особь",
+ "ES": "Hembra"
+ },
+ "pokemon_form_2813": {
+ "EN": "Tshirt 01"
+ },
+ "pokemon_form_2814": {
+ "EN": "Tshirt 02"
+ },
+ "pokemon_form_2815": {
+ "EN": "Flying 01"
+ },
+ "pokemon_form_2816": {
+ "EN": "Flying 02"
+ },
+ "pokemon_form_2820": {
+ "EN": "Winter 2020"
+ },
+ "pokemon_form_2821": {
+ "EN": "S"
+ },
+ "pokemon_form_2822": {
+ "EN": "S"
+ },
+ "pokemon_form_2823": {
+ "EN": "Complete Ten Percent"
+ },
+ "pokemon_form_2824": {
+ "EN": "Complete Fifty Percent"
+ },
+ "pokemon_form_2825": {
+ "EN": "Gotour 2024 A"
+ },
+ "pokemon_form_2826": {
+ "EN": "Gotour 2024 B"
+ },
+ "pokemon_form_2827": {
+ "EN": "Gotour 2024 A 02"
+ },
+ "pokemon_form_2828": {
+ "EN": "Gotour 2024 B 02"
+ },
+ "pokemon_form_2829": {
+ "PT-BR": "Forma Origem",
+ "EN": "Origin Forme",
+ "FR": "Forme Originelle",
+ "DE": "Urform",
+ "IT": "Forma Originale",
+ "RU": "Исходная Форма",
+ "ES": "Forma Origen"
+ },
+ "pokemon_form_2830": {
+ "PT-BR": "Forma Origem",
+ "EN": "Origin Forme",
+ "FR": "Forme Originelle",
+ "DE": "Urform",
+ "IT": "Forma Originale",
+ "RU": "Исходная Форма",
+ "ES": "Forma Origen"
+ },
+ "pokemon_form_2832": {
+ "EN": "Tshirt 03"
+ },
+ "pokemon_form_2833": {
+ "EN": "Flying 04"
+ },
+ "pokemon_form_2834": {
+ "EN": "Tshirt 04"
+ },
+ "pokemon_form_2835": {
+ "EN": "Tshirt 05"
+ },
+ "pokemon_form_2836": {
+ "EN": "Tshirt 06"
+ },
+ "pokemon_form_2837": {
+ "EN": "Tshirt 07"
+ },
+ "pokemon_form_2838": {
+ "EN": "Flying 05"
+ },
+ "pokemon_form_2839": {
+ "EN": "Flying 06"
+ },
+ "pokemon_form_2840": {
+ "EN": "Flying 07"
+ },
+ "pokemon_form_2841": {
+ "EN": "Flying 08"
+ },
+ "pokemon_form_2842": {
+ "EN": "Horizons"
+ },
+ "pokemon_form_2843": {
+ "EN": "Gofest 2024 Stiara"
+ },
+ "pokemon_form_2844": {
+ "EN": "Gofest 2024 Mtiara"
+ },
+ "pokemon_form_2845": {
+ "EN": "Gofest 2024 Stiara"
+ },
+ "pokemon_form_2846": {
+ "EN": "Gofest 2024 Mtiara"
+ },
+ "pokemon_form_2847": {
+ "EN": "Gofest 2024 Sscarf"
+ },
+ "pokemon_form_2848": {
+ "EN": "Gofest 2024 Mscarf"
+ },
+ "pokemon_form_2849": {
+ "EN": "Wildarea 2024"
+ },
+ "pokemon_form_2850": {
+ "EN": "Diwali 2024"
+ },
+ "pokemon_form_2856": {
+ "EN": "Gotour 2025 A"
+ },
+ "pokemon_form_2857": {
+ "EN": "Gotour 2025 B"
+ },
+ "pokemon_form_2858": {
+ "EN": "Gotour 2025 A 02"
+ },
+ "pokemon_form_2859": {
+ "EN": "Gotour 2025 B 02"
+ },
+ "pokemon_form_2863": {
+ "EN": "Kurta"
+ },
+ "pokemon_form_2864": {
+ "EN": "Gofest 2025 Goggles Red"
+ },
+ "pokemon_form_2865": {
+ "EN": "Gofest 2025 Goggles Blue"
+ },
+ "pokemon_form_2866": {
+ "EN": "Gofest 2025 Goggles Yellow"
+ },
+ "pokemon_form_2867": {
+ "EN": "Gofest 2025 Monocle Red"
+ },
+ "pokemon_form_2868": {
+ "EN": "Gofest 2025 Monocle Blue"
+ },
+ "pokemon_form_2869": {
+ "EN": "Gofest 2025 Monocle Yellow"
+ },
+ "pokemon_form_2870": {
+ "EN": "Gofest 2025 Train Conductor"
+ },
+ "pokemon_form_2871": {
+ "EN": "Counterfeit"
+ },
+ "pokemon_form_2872": {
+ "EN": "Artisan"
+ },
+ "pokemon_form_2873": {
+ "EN": "Unremarkable"
+ },
+ "pokemon_form_2874": {
+ "EN": "Masterpiece"
+ },
+ "pokemon_form_2875": {
+ "EN": "Teal"
+ },
+ "pokemon_form_2876": {
+ "EN": "Wellspring"
+ },
+ "pokemon_form_2877": {
+ "EN": "Hearthflame"
+ },
+ "pokemon_form_2879": {
+ "EN": "Cornerstone"
+ },
+ "pokemon_form_2881": {
+ "EN": "Terastal"
+ },
+ "pokemon_form_2882": {
+ "EN": "Stellar"
+ },
+ "pokemon_form_2982": {
+ "PT-BR": "Fêmea",
+ "EN": "Female",
+ "FR": "Femelle",
+ "DE": "Weiblich",
+ "IT": "Femmina",
+ "RU": "Женская Особь",
+ "ES": "Hembra"
+ },
+ "pokemon_form_2983": {
+ "EN": "Family Of Three"
+ },
+ "pokemon_form_2984": {
+ "EN": "Family Of Four"
+ },
+ "pokemon_form_2985": {
+ "PT-BR": "Plumagem Verde",
+ "EN": "Green Plumage",
+ "FR": "Plumage Vert",
+ "DE": "Grüngefiedert",
+ "IT": "Piume Verdi",
+ "RU": "Зелёное Оперение",
+ "ES": "Plumaje Verde"
+ },
+ "pokemon_form_2986": {
+ "PT-BR": "Plumagem Azul",
+ "EN": "Blue Plumage",
+ "FR": "Plumage Bleu",
+ "DE": "Blaugefiedert",
+ "IT": "Piume Azzurre",
+ "RU": "Синее Оперение",
+ "ES": "Plumaje Azul"
+ },
+ "pokemon_form_2987": {
+ "PT-BR": "Plumagem Amarela",
+ "EN": "Yellow Plumage",
+ "FR": "Plumage Jaune",
+ "DE": "Gelbgefiedert",
+ "IT": "Piume Gialle",
+ "RU": "Жёлтое Оперение",
+ "ES": "Plumaje Amarillo"
+ },
+ "pokemon_form_2988": {
+ "EN": "White"
+ },
+ "pokemon_form_2989": {
+ "PT-BR": "Forma Zero",
+ "EN": "Zero Form",
+ "FR": "Forme Ordinaire",
+ "DE": "Alltagsform",
+ "IT": "Forma Ingenua",
+ "RU": "Нулевая Форма",
+ "ES": "Forma Ingenua"
+ },
+ "pokemon_form_2990": {
+ "EN": "Hero"
+ },
+ "pokemon_form_2991": {
+ "PT-BR": "Forma Curvada",
+ "EN": "Curly Form",
+ "FR": "Forme Courbée",
+ "DE": "Gebogene Form",
+ "IT": "Forma Arcuata",
+ "RU": "Изогнутая Форма",
+ "ES": "Forma Curvada"
+ },
+ "pokemon_form_2992": {
+ "PT-BR": "Forma Pendular",
+ "EN": "Droopy Form",
+ "FR": "Forme Affalée",
+ "DE": "Hängende Form",
+ "IT": "Forma Adagiata",
+ "RU": "Свисающая Форма",
+ "ES": "Forma Lánguida"
+ },
+ "pokemon_form_2993": {
+ "PT-BR": "Forma Estendida",
+ "EN": "Stretchy Form",
+ "FR": "Forme Raide",
+ "DE": "Gestreckte Form",
+ "IT": "Forma Tesa",
+ "RU": "Вытянутая Форма",
+ "ES": "Forma Recta"
+ },
+ "pokemon_form_2994": {
+ "PT-BR": "Forma Bissegmentar",
+ "EN": "Two-Segment Form",
+ "FR": "Forme Double",
+ "DE": "Zweisegmentform",
+ "IT": "Forma Bimetamero",
+ "RU": "Двухсегментная Форма",
+ "ES": "Forma Binodular"
+ },
+ "pokemon_form_2995": {
+ "PT-BR": "Forma Trissegmentar",
+ "EN": "Three-Segment Form",
+ "FR": "Forme Triple",
+ "DE": "Dreisegmentform",
+ "IT": "Forma Trimetamero",
+ "RU": "Трёхсегментная Форма",
+ "ES": "Forma Trinodular"
+ },
+ "pokemon_form_2996": {
+ "PT-BR": "Versão Plena",
+ "EN": "Apex Build",
+ "FR": "Forme Finale",
+ "DE": "Vollkommene Gestalt",
+ "IT": "Foggia Integrale",
+ "RU": "Финальная Форма",
+ "ES": "Fisonomía Plena"
+ },
+ "pokemon_form_2997": {
+ "PT-BR": "Modo Supremo",
+ "EN": "Ultimate Mode",
+ "FR": "Mode Ultime",
+ "DE": "Kompletter Modus",
+ "IT": "Assetto Completo",
+ "RU": "Полноценный Режим",
+ "ES": "Modo Pleno"
+ },
+ "pokemon_form_3001": {
+ "EN": "Summer 2023"
+ },
+ "pokemon_form_3002": {
+ "EN": "Summer 2023 A"
+ },
+ "pokemon_form_3003": {
+ "EN": "Summer 2023 B"
+ },
+ "pokemon_form_3004": {
+ "EN": "Summer 2023 C"
+ },
+ "pokemon_form_3005": {
+ "EN": "Summer 2023 D"
+ },
+ "pokemon_form_3006": {
+ "PT-BR": "Espécie de Combate",
+ "EN": "Combat Breed",
+ "FR": "Race Combative",
+ "DE": "Gefechtvariante",
+ "IT": "Varietà Combattiva",
+ "RU": "Порода Сражение",
+ "ES": "Variedad Combatiente"
+ },
+ "pokemon_form_3007": {
+ "PT-BR": "Espécie Labareda",
+ "EN": "Blaze Breed",
+ "FR": "Race Flamboyante",
+ "DE": "Flammenvariante",
+ "IT": "Varietà Infuocata",
+ "RU": "Порода Пламя",
+ "ES": "Variedad Ardiente"
+ },
+ "pokemon_form_3008": {
+ "PT-BR": "Espécie Aquática",
+ "EN": "Aqua Breed",
+ "FR": "Race Aquatique",
+ "DE": "Flutenvariante",
+ "IT": "Varietà Acquatica",
+ "RU": "Порода Аква",
+ "ES": "Variedad Acuática"
+ },
+ "pokemon_form_3009": {
+ "EN": "Paldea"
+ },
+ "pokemon_form_3010": {
+ "EN": "Summer 2023 E"
+ },
+ "pokemon_form_3011": {
+ "EN": "Flying 03"
+ },
+ "pokemon_form_3012": {
+ "EN": "Jeju"
+ },
+ "pokemon_form_3013": {
+ "EN": "Doctor"
+ },
+ "pokemon_form_3014": {
+ "EN": "Wcs 2023"
+ },
+ "pokemon_form_3015": {
+ "EN": "Wcs 2024"
+ },
+ "pokemon_form_3017": {
+ "EN": "Wcs 2025"
+ },
+ "pokemon_form_3018": {
+ "EN": "Coin A1"
+ },
+ "pokemon_form_3019": {
+ "EN": "Swim 2025"
+ },
+ "pokemon_form_3021": {
+ "EN": "Wildarea 2025"
+ },
+ "pokemon_form_3315": {
+ "EN": "Winter 2025"
+ },
+ "pokemon_form_3316": {
+ "EN": "Winter 2025"
+ },
+ "pokemon_form_3317": {
+ "EN": "Winter 2025"
+ },
+ "pokemon_form_3318": {
+ "EN": "Gotour 2026 A"
+ },
+ "pokemon_form_3319": {
+ "EN": "Gotour 2026 A 02"
+ },
+ "pokemon_form_3320": {
+ "EN": "Gotour 2026 B"
+ },
+ "pokemon_form_3321": {
+ "EN": "Gotour 2026 B 02"
+ },
+ "pokemon_form_3322": {
+ "EN": "Gotour 2026 C"
+ },
+ "pokemon_form_3323": {
+ "EN": "Gotour 2026 C 02"
+ },
+ "pokemon_form_3337": {
+ "EN": "Spring 2026 A"
+ },
+ "pokemon_form_3338": {
+ "EN": "Spring 2026 B"
+ },
+ "pokemon_form_3339": {
+ "EN": "Spring 2026"
+ },
+ "pokemon_form_3340": {
+ "EN": "Bb 2026"
+ },
+ "pokemon_form_3341": {
+ "EN": "Visor 2026"
+ }
+}
\ No newline at end of file
diff --git a/core/lang/pokemon_moves.json b/lang/pokemon_moves.json
similarity index 67%
rename from core/lang/pokemon_moves.json
rename to lang/pokemon_moves.json
index e9078e0a..2f0bafb6 100644
--- a/core/lang/pokemon_moves.json
+++ b/lang/pokemon_moves.json
@@ -2,10 +2,6 @@
"pokemon_move_1": {
"PT-BR": "Trovoada de Choques",
"EN": "Thunder Shock",
- "FI": "Thunder Shock",
- "NL": "Thunder Shock",
- "NO": "Thunder Shock",
- "PL": "Thunder Shock",
"FR": "Éclair",
"DE": "Donnerschock",
"IT": "Tuonoshock",
@@ -15,10 +11,6 @@
"pokemon_move_2": {
"PT-BR": "Ataque Rápido",
"EN": "Quick Attack",
- "FI": "Quick Attack",
- "NL": "Quick Attack",
- "NO": "Quick Attack",
- "PL": "Quick Attack",
"FR": "Vive-Attaque",
"DE": "Ruckzuckhieb",
"IT": "Attacco Rapido",
@@ -28,10 +20,6 @@
"pokemon_move_3": {
"PT-BR": "Arranhão",
"EN": "Scratch",
- "FI": "Scratch",
- "NL": "Scratch",
- "NO": "Scratch",
- "PL": "Scratch",
"FR": "Griffe",
"DE": "Kratzer",
"IT": "Graffio",
@@ -41,10 +29,6 @@
"pokemon_move_4": {
"PT-BR": "Brasa",
"EN": "Ember",
- "FI": "Ember",
- "NL": "Ember",
- "NO": "Ember",
- "PL": "Ember",
"FR": "Flammèche",
"DE": "Glut",
"IT": "Braciere",
@@ -54,25 +38,16 @@
"pokemon_move_5": {
"PT-BR": "Chicote de Vinha",
"EN": "Vine Whip",
- "FI": "Vine Whip",
- "NL": "Vine Whip",
- "NO": "Vine Whip",
- "PL": "Vine Whip",
"FR": "Fouet Lianes",
"DE": "Rankenhieb",
"IT": "Frustata",
- "RU": "Плеть-Лиана",
+ "RU": "Плеть-лиана",
"ES": "Látigo Cepa"
},
"pokemon_move_6": {
"PT-BR": "Investida",
"EN": "Tackle",
- "FI": "Tackle",
- "NL": "Tackle",
- "NO": "Tackle",
- "PL": "Tackle",
"FR": "Charge",
- "DE": "Tackle",
"IT": "Azione",
"RU": "Бросок",
"ES": "Placaje"
@@ -80,10 +55,6 @@
"pokemon_move_7": {
"PT-BR": "Folha Navalha",
"EN": "Razor Leaf",
- "FI": "Razor Leaf",
- "NL": "Razor Leaf",
- "NO": "Razor Leaf",
- "PL": "Razor Leaf",
"FR": "Tranch’Herbe",
"DE": "Rasierblatt",
"IT": "Foglielama",
@@ -93,10 +64,6 @@
"pokemon_move_8": {
"PT-BR": "Desmantelar",
"EN": "Take Down",
- "FI": "Take Down",
- "NL": "Take Down",
- "NO": "Take Down",
- "PL": "Take Down",
"FR": "Bélier",
"DE": "Bodycheck",
"IT": "Riduttore",
@@ -106,10 +73,6 @@
"pokemon_move_9": {
"PT-BR": "Revólver d'Água",
"EN": "Water Gun",
- "FI": "Water Gun",
- "NL": "Water Gun",
- "NO": "Water Gun",
- "PL": "Water Gun",
"FR": "Pistolet à O",
"DE": "Aquaknarre",
"IT": "Pistolacqua",
@@ -119,10 +82,6 @@
"pokemon_move_10": {
"PT-BR": "Mordida",
"EN": "Bite",
- "FI": "Bite",
- "NL": "Bite",
- "NO": "Bite",
- "PL": "Bite",
"FR": "Morsure",
"DE": "Biss",
"IT": "Morso",
@@ -132,10 +91,6 @@
"pokemon_move_11": {
"PT-BR": "Pancada",
"EN": "Pound",
- "FI": "Pound",
- "NL": "Pound",
- "NO": "Pound",
- "PL": "Pound",
"FR": "Écras’Face",
"DE": "Klaps",
"IT": "Botta",
@@ -145,10 +100,6 @@
"pokemon_move_12": {
"PT-BR": "Tapa Duplo",
"EN": "Double Slap",
- "FI": "Double Slap",
- "NL": "Double Slap",
- "NO": "Double Slap",
- "PL": "Double Slap",
"FR": "Torgnoles",
"DE": "Duplexhieb",
"IT": "Doppiasberla",
@@ -158,10 +109,6 @@
"pokemon_move_13": {
"PT-BR": "Embrulho",
"EN": "Wrap",
- "FI": "Wrap",
- "NL": "Wrap",
- "NO": "Wrap",
- "PL": "Wrap",
"FR": "Ligotage",
"DE": "Wickel",
"IT": "Avvolgibotta",
@@ -171,10 +118,6 @@
"pokemon_move_14": {
"PT-BR": "Hiper-raio",
"EN": "Hyper Beam",
- "FI": "Hyper Beam",
- "NL": "Hyper Beam",
- "NO": "Hyper Beam",
- "PL": "Hyper Beam",
"FR": "Ultralaser",
"DE": "Hyperstrahl",
"IT": "Iper Raggio",
@@ -184,10 +127,6 @@
"pokemon_move_15": {
"PT-BR": "Lambida",
"EN": "Lick",
- "FI": "Lick",
- "NL": "Lick",
- "NO": "Lick",
- "PL": "Lick",
"FR": "Léchouille",
"DE": "Schlecker",
"IT": "Leccata",
@@ -197,10 +136,6 @@
"pokemon_move_16": {
"PT-BR": "Pulso Sombrio",
"EN": "Dark Pulse",
- "FI": "Dark Pulse",
- "NL": "Dark Pulse",
- "NO": "Dark Pulse",
- "PL": "Dark Pulse",
"FR": "Vibrobscur",
"DE": "Finsteraura",
"IT": "Neropulsar",
@@ -210,23 +145,13 @@
"pokemon_move_17": {
"PT-BR": "Nevoeiro de Fumaça",
"EN": "Smog",
- "FI": "Smog",
- "NL": "Smog",
- "NO": "Smog",
- "PL": "Smog",
"FR": "Purédpois",
- "DE": "Smog",
- "IT": "Smog",
"RU": "Дым",
"ES": "Polución"
},
"pokemon_move_18": {
"PT-BR": "Ataque de Lama",
"EN": "Sludge",
- "FI": "Sludge",
- "NL": "Sludge",
- "NO": "Sludge",
- "PL": "Sludge",
"FR": "Détritus",
"DE": "Schlammbad",
"IT": "Fango",
@@ -236,10 +161,6 @@
"pokemon_move_19": {
"PT-BR": "Garra de Metal",
"EN": "Metal Claw",
- "FI": "Metal Claw",
- "NL": "Metal Claw",
- "NO": "Metal Claw",
- "PL": "Metal Claw",
"FR": "Griffe Acier",
"DE": "Metallklaue",
"IT": "Ferrartigli",
@@ -249,10 +170,6 @@
"pokemon_move_20": {
"PT-BR": "Agarramento Compressor",
"EN": "Vise Grip",
- "FI": "Vise Grip",
- "NL": "Vise Grip",
- "NO": "Vise Grip",
- "PL": "Vise Grip",
"FR": "Force Poigne",
"DE": "Klammer",
"IT": "Presa",
@@ -262,10 +179,6 @@
"pokemon_move_21": {
"PT-BR": "Roda de Fogo",
"EN": "Flame Wheel",
- "FI": "Flame Wheel",
- "NL": "Flame Wheel",
- "NO": "Flame Wheel",
- "PL": "Flame Wheel",
"FR": "Roue de Feu",
"DE": "Flammenrad",
"IT": "Ruotafuoco",
@@ -275,10 +188,6 @@
"pokemon_move_22": {
"PT-BR": "Megachifre",
"EN": "Megahorn",
- "FI": "Megahorn",
- "NL": "Megahorn",
- "NO": "Megahorn",
- "PL": "Megahorn",
"FR": "Mégacorne",
"DE": "Vielender",
"IT": "Megacorno",
@@ -288,10 +197,6 @@
"pokemon_move_23": {
"PT-BR": "Ataque de Asa",
"EN": "Wing Attack",
- "FI": "Wing Attack",
- "NL": "Wing Attack",
- "NO": "Wing Attack",
- "PL": "Wing Attack",
"FR": "Cru-Ailes",
"DE": "Flügelschlag",
"IT": "Attacco d’Ala",
@@ -301,10 +206,6 @@
"pokemon_move_24": {
"PT-BR": "Lança-chamas",
"EN": "Flamethrower",
- "FI": "Flamethrower",
- "NL": "Flamethrower",
- "NO": "Flamethrower",
- "PL": "Flamethrower",
"FR": "Lance-Flammes",
"DE": "Flammenwurf",
"IT": "Lanciafiamme",
@@ -314,10 +215,6 @@
"pokemon_move_25": {
"PT-BR": "Soco Enganador",
"EN": "Sucker Punch",
- "FI": "Sucker Punch",
- "NL": "Sucker Punch",
- "NO": "Sucker Punch",
- "PL": "Sucker Punch",
"FR": "Coup Bas",
"DE": "Tiefschlag",
"IT": "Sbigoattacco",
@@ -327,10 +224,6 @@
"pokemon_move_26": {
"PT-BR": "Cavar",
"EN": "Dig",
- "FI": "Dig",
- "NL": "Dig",
- "NO": "Dig",
- "PL": "Dig",
"FR": "Tunnel",
"DE": "Schaufler",
"IT": "Fossa",
@@ -340,10 +233,6 @@
"pokemon_move_27": {
"PT-BR": "Rasteira",
"EN": "Low Kick",
- "FI": "Low Kick",
- "NL": "Low Kick",
- "NO": "Low Kick",
- "PL": "Low Kick",
"FR": "Balayage",
"DE": "Fußkick",
"IT": "Colpo Basso",
@@ -353,10 +242,6 @@
"pokemon_move_28": {
"PT-BR": "Golpe Cruzado",
"EN": "Cross Chop",
- "FI": "Cross Chop",
- "NL": "Cross Chop",
- "NO": "Cross Chop",
- "PL": "Cross Chop",
"FR": "Coup Croix",
"DE": "Kreuzhieb",
"IT": "Incrocolpo",
@@ -366,10 +251,6 @@
"pokemon_move_29": {
"PT-BR": "Corte Psíquico",
"EN": "Psycho Cut",
- "FI": "Psycho Cut",
- "NL": "Psycho Cut",
- "NO": "Psycho Cut",
- "PL": "Psycho Cut",
"FR": "Coupe Psycho",
"DE": "Psychoklinge",
"IT": "Psicotaglio",
@@ -379,10 +260,6 @@
"pokemon_move_30": {
"PT-BR": "Feixe Psíquico",
"EN": "Psybeam",
- "FI": "Psybeam",
- "NL": "Psybeam",
- "NO": "Psybeam",
- "PL": "Psybeam",
"FR": "Rafale Psy",
"DE": "Psystrahl",
"IT": "Psicoraggio",
@@ -392,10 +269,6 @@
"pokemon_move_31": {
"PT-BR": "Terremoto",
"EN": "Earthquake",
- "FI": "Earthquake",
- "NL": "Earthquake",
- "NO": "Earthquake",
- "PL": "Earthquake",
"FR": "Séisme",
"DE": "Erdbeben",
"IT": "Terremoto",
@@ -405,10 +278,6 @@
"pokemon_move_32": {
"PT-BR": "Gume de Pedra",
"EN": "Stone Edge",
- "FI": "Stone Edge",
- "NL": "Stone Edge",
- "NO": "Stone Edge",
- "PL": "Stone Edge",
"FR": "Lame de Roc",
"DE": "Steinkante",
"IT": "Pietrataglio",
@@ -418,10 +287,6 @@
"pokemon_move_33": {
"PT-BR": "Soco de Gelo",
"EN": "Ice Punch",
- "FI": "Ice Punch",
- "NL": "Ice Punch",
- "NO": "Ice Punch",
- "PL": "Ice Punch",
"FR": "Poing Glace",
"DE": "Eishieb",
"IT": "Gelopugno",
@@ -431,23 +296,15 @@
"pokemon_move_34": {
"PT-BR": "Estampa de Coração",
"EN": "Heart Stamp",
- "FI": "Heart Stamp",
- "NL": "Heart Stamp",
- "NO": "Heart Stamp",
- "PL": "Heart Stamp",
"FR": "Crève-Cœur",
"DE": "Herzstempel",
"IT": "Cuorestampo",
- "RU": "Печать-Сердце",
+ "RU": "ПечатьСердце",
"ES": "Arrumaco"
},
"pokemon_move_35": {
"PT-BR": "Descarga",
"EN": "Discharge",
- "FI": "Discharge",
- "NL": "Discharge",
- "NO": "Discharge",
- "PL": "Discharge",
"FR": "Coup d’Jus",
"DE": "Ladungsstoß",
"IT": "Scarica",
@@ -457,10 +314,6 @@
"pokemon_move_36": {
"PT-BR": "Canhão de Flash",
"EN": "Flash Cannon",
- "FI": "Flash Cannon",
- "NL": "Flash Cannon",
- "NO": "Flash Cannon",
- "PL": "Flash Cannon",
"FR": "Luminocanon",
"DE": "Lichtkanone",
"IT": "Cannonflash",
@@ -470,10 +323,6 @@
"pokemon_move_37": {
"PT-BR": "Bicada",
"EN": "Peck",
- "FI": "Peck",
- "NL": "Peck",
- "NO": "Peck",
- "PL": "Peck",
"FR": "Picpic",
"DE": "Pikser",
"IT": "Beccata",
@@ -483,10 +332,6 @@
"pokemon_move_38": {
"PT-BR": "Bico Broca",
"EN": "Drill Peck",
- "FI": "Drill Peck",
- "NL": "Drill Peck",
- "NO": "Drill Peck",
- "PL": "Drill Peck",
"FR": "Bec Vrille",
"DE": "Bohrschnabel",
"IT": "Perforbecco",
@@ -496,10 +341,6 @@
"pokemon_move_39": {
"PT-BR": "Raio Congelante",
"EN": "Ice Beam",
- "FI": "Ice Beam",
- "NL": "Ice Beam",
- "NO": "Ice Beam",
- "PL": "Ice Beam",
"FR": "Laser Glace",
"DE": "Eisstrahl",
"IT": "Geloraggio",
@@ -509,12 +350,6 @@
"pokemon_move_40": {
"PT-BR": "Nevasca",
"EN": "Blizzard",
- "FI": "Blizzard",
- "NL": "Blizzard",
- "NO": "Blizzard",
- "PL": "Blizzard",
- "FR": "Blizzard",
- "DE": "Blizzard",
"IT": "Bora",
"RU": "Метель",
"ES": "Ventisca"
@@ -522,10 +357,6 @@
"pokemon_move_41": {
"PT-BR": "Golpe de Ar",
"EN": "Air Slash",
- "FI": "Air Slash",
- "NL": "Air Slash",
- "NO": "Air Slash",
- "PL": "Air Slash",
"FR": "Lame d’Air",
"DE": "Luftschnitt",
"IT": "Eterelama",
@@ -535,10 +366,6 @@
"pokemon_move_42": {
"PT-BR": "Onda de Calor",
"EN": "Heat Wave",
- "FI": "Heat Wave",
- "NL": "Heat Wave",
- "NO": "Heat Wave",
- "PL": "Heat Wave",
"FR": "Canicule",
"DE": "Hitzewelle",
"IT": "Ondacalda",
@@ -548,10 +375,6 @@
"pokemon_move_43": {
"PT-BR": "Agulha Dupla",
"EN": "Twineedle",
- "FI": "Twineedle",
- "NL": "Twineedle",
- "NO": "Twineedle",
- "PL": "Twineedle",
"FR": "Double Dard",
"DE": "Duonadel",
"IT": "Doppio Ago",
@@ -561,10 +384,6 @@
"pokemon_move_44": {
"PT-BR": "Golpe Envenenado",
"EN": "Poison Jab",
- "FI": "Poison Jab",
- "NL": "Poison Jab",
- "NO": "Poison Jab",
- "PL": "Poison Jab",
"FR": "Direct Toxik",
"DE": "Gifthieb",
"IT": "Velenpuntura",
@@ -574,10 +393,6 @@
"pokemon_move_45": {
"PT-BR": "Ás dos Ares",
"EN": "Aerial Ace",
- "FI": "Aerial Ace",
- "NL": "Aerial Ace",
- "NO": "Aerial Ace",
- "PL": "Aerial Ace",
"FR": "Aéropique",
"DE": "Aero-Ass",
"IT": "Aeroassalto",
@@ -587,10 +402,6 @@
"pokemon_move_46": {
"PT-BR": "Furação",
"EN": "Drill Run",
- "FI": "Drill Run",
- "NL": "Drill Run",
- "NO": "Drill Run",
- "PL": "Drill Run",
"FR": "Tunnelier",
"DE": "Schlagbohrer",
"IT": "Giravvita",
@@ -600,10 +411,6 @@
"pokemon_move_47": {
"PT-BR": "Nevasca de Pétalas",
"EN": "Petal Blizzard",
- "FI": "Petal Blizzard",
- "NL": "Petal Blizzard",
- "NO": "Petal Blizzard",
- "PL": "Petal Blizzard",
"FR": "Tempête Florale",
"DE": "Blütenwirbel",
"IT": "Fiortempesta",
@@ -613,23 +420,15 @@
"pokemon_move_48": {
"PT-BR": "Megadreno",
"EN": "Mega Drain",
- "FI": "Mega Drain",
- "NL": "Mega Drain",
- "NO": "Mega Drain",
- "PL": "Mega Drain",
"FR": "Méga-Sangsue",
"DE": "Megasauger",
"IT": "Megassorbimento",
- "RU": "Мега-Осушение",
+ "RU": "Мега-осушение",
"ES": "Megaagotar"
},
"pokemon_move_49": {
"PT-BR": "Zumbido de Inseto",
"EN": "Bug Buzz",
- "FI": "Bug Buzz",
- "NL": "Bug Buzz",
- "NO": "Bug Buzz",
- "PL": "Bug Buzz",
"FR": "Bourdon",
"DE": "Käfergebrumm",
"IT": "Ronzio",
@@ -639,10 +438,6 @@
"pokemon_move_50": {
"PT-BR": "Presa Venenosa",
"EN": "Poison Fang",
- "FI": "Poison Fang",
- "NL": "Poison Fang",
- "NO": "Poison Fang",
- "PL": "Poison Fang",
"FR": "Crochet Venin",
"DE": "Giftzahn",
"IT": "Velenodenti",
@@ -652,10 +447,6 @@
"pokemon_move_51": {
"PT-BR": "Talho Noturno",
"EN": "Night Slash",
- "FI": "Night Slash",
- "NL": "Night Slash",
- "NO": "Night Slash",
- "PL": "Night Slash",
"FR": "Tranche-Nuit",
"DE": "Nachthieb",
"IT": "Nottesferza",
@@ -665,10 +456,6 @@
"pokemon_move_52": {
"PT-BR": "Talho",
"EN": "Slash",
- "FI": "Slash",
- "NL": "Slash",
- "NO": "Slash",
- "PL": "Slash",
"FR": "Tranche",
"DE": "Schlitzer",
"IT": "Lacerazione",
@@ -678,10 +465,6 @@
"pokemon_move_53": {
"PT-BR": "Jato de Bolhas",
"EN": "Bubble Beam",
- "FI": "Bubble Beam",
- "NL": "Bubble Beam",
- "NO": "Bubble Beam",
- "PL": "Bubble Beam",
"FR": "Bulles d’O",
"DE": "Blubbstrahl",
"IT": "Bollaraggio",
@@ -691,10 +474,6 @@
"pokemon_move_54": {
"PT-BR": "Submissão",
"EN": "Submission",
- "FI": "Submission",
- "NL": "Submission",
- "NO": "Submission",
- "PL": "Submission",
"FR": "Sacrifice",
"DE": "Überroller",
"IT": "Sottomissione",
@@ -704,10 +483,6 @@
"pokemon_move_55": {
"PT-BR": "Golpe de Caratê",
"EN": "Karate Chop",
- "FI": "Karate Chop",
- "NL": "Karate Chop",
- "NO": "Karate Chop",
- "PL": "Karate Chop",
"FR": "Poing Karaté",
"DE": "Karateschlag",
"IT": "Colpokarate",
@@ -717,10 +492,6 @@
"pokemon_move_56": {
"PT-BR": "Movimento Baixo",
"EN": "Low Sweep",
- "FI": "Low Sweep",
- "NL": "Low Sweep",
- "NO": "Low Sweep",
- "PL": "Low Sweep",
"FR": "Balayette",
"DE": "Fußtritt",
"IT": "Calciobasso",
@@ -730,10 +501,6 @@
"pokemon_move_57": {
"PT-BR": "Aqua Jato",
"EN": "Aqua Jet",
- "FI": "Aqua Jet",
- "NL": "Aqua Jet",
- "NO": "Aqua Jet",
- "PL": "Aqua Jet",
"FR": "Aqua-Jet",
"DE": "Wasserdüse",
"IT": "Acquagetto",
@@ -743,10 +510,6 @@
"pokemon_move_58": {
"PT-BR": "Aqua Cauda",
"EN": "Aqua Tail",
- "FI": "Aqua Tail",
- "NL": "Aqua Tail",
- "NO": "Aqua Tail",
- "PL": "Aqua Tail",
"FR": "Hydro-Queue",
"DE": "Nassschweif",
"IT": "Idrondata",
@@ -756,23 +519,15 @@
"pokemon_move_59": {
"PT-BR": "Bomba de Sementes",
"EN": "Seed Bomb",
- "FI": "Seed Bomb",
- "NL": "Seed Bomb",
- "NO": "Seed Bomb",
- "PL": "Seed Bomb",
"FR": "Canon Graine",
"DE": "Samenbomben",
"IT": "Semebomba",
- "RU": "Семя-Бомба",
+ "RU": "Семя-бомба",
"ES": "Bomba Germen"
},
"pokemon_move_60": {
"PT-BR": "Choque Psíquico",
"EN": "Psyshock",
- "FI": "Psyshock",
- "NL": "Psyshock",
- "NO": "Psyshock",
- "PL": "Psyshock",
"FR": "Choc Psy",
"DE": "Psychoschock",
"IT": "Psicoshock",
@@ -782,10 +537,6 @@
"pokemon_move_61": {
"PT-BR": "Lançamento de Rocha",
"EN": "Rock Throw",
- "FI": "Rock Throw",
- "NL": "Rock Throw",
- "NO": "Rock Throw",
- "PL": "Rock Throw",
"FR": "Jet-Pierres",
"DE": "Steinwurf",
"IT": "Sassata",
@@ -795,10 +546,6 @@
"pokemon_move_62": {
"PT-BR": "Poder Ancestral",
"EN": "Ancient Power",
- "FI": "Ancient Power",
- "NL": "Ancient Power",
- "NO": "Ancient Power",
- "PL": "Ancient Power",
"FR": "Pouvoir Antique",
"DE": "Antik-Kraft",
"IT": "Forzantica",
@@ -808,10 +555,6 @@
"pokemon_move_63": {
"PT-BR": "Tumba de Rochas",
"EN": "Rock Tomb",
- "FI": "Rock Tomb",
- "NL": "Rock Tomb",
- "NO": "Rock Tomb",
- "PL": "Rock Tomb",
"FR": "Tomberoche",
"DE": "Felsgrab",
"IT": "Rocciotomba",
@@ -821,10 +564,6 @@
"pokemon_move_64": {
"PT-BR": "Deslize de Pedras",
"EN": "Rock Slide",
- "FI": "Rock Slide",
- "NL": "Rock Slide",
- "NO": "Rock Slide",
- "PL": "Rock Slide",
"FR": "Éboulement",
"DE": "Steinhagel",
"IT": "Frana",
@@ -834,10 +573,6 @@
"pokemon_move_65": {
"PT-BR": "Gema Poderosa",
"EN": "Power Gem",
- "FI": "Power Gem",
- "NL": "Power Gem",
- "NO": "Power Gem",
- "PL": "Power Gem",
"FR": "Rayon Gemme",
"DE": "Juwelenkraft",
"IT": "Gemmoforza",
@@ -847,10 +582,6 @@
"pokemon_move_66": {
"PT-BR": "Furtividade nas Sombras",
"EN": "Shadow Sneak",
- "FI": "Shadow Sneak",
- "NL": "Shadow Sneak",
- "NO": "Shadow Sneak",
- "PL": "Shadow Sneak",
"FR": "Ombre Portée",
"DE": "Schattenstoß",
"IT": "Furtivombra",
@@ -860,23 +591,15 @@
"pokemon_move_67": {
"PT-BR": "Soco Sombrio",
"EN": "Shadow Punch",
- "FI": "Shadow Punch",
- "NL": "Shadow Punch",
- "NO": "Shadow Punch",
- "PL": "Shadow Punch",
"FR": "Poing Ombre",
"DE": "Finsterfaust",
"IT": "Pugnodombra",
- "RU": "Теневой Кулак",
+ "RU": "Теневая форма Кулак",
"ES": "Puño Sombra"
},
"pokemon_move_68": {
"PT-BR": "Garra Sombria",
"EN": "Shadow Claw",
- "FI": "Shadow Claw",
- "NL": "Shadow Claw",
- "NO": "Shadow Claw",
- "PL": "Shadow Claw",
"FR": "Griffe Ombre",
"DE": "Dunkelklaue",
"IT": "Ombrartigli",
@@ -886,10 +609,6 @@
"pokemon_move_69": {
"PT-BR": "Vento Ominoso",
"EN": "Ominous Wind",
- "FI": "Ominous Wind",
- "NL": "Ominous Wind",
- "NO": "Ominous Wind",
- "PL": "Ominous Wind",
"FR": "Vent Mauvais",
"DE": "Unheilböen",
"IT": "Funestovento",
@@ -899,10 +618,6 @@
"pokemon_move_70": {
"PT-BR": "Bola Sombria",
"EN": "Shadow Ball",
- "FI": "Shadow Ball",
- "NL": "Shadow Ball",
- "NO": "Shadow Ball",
- "PL": "Shadow Ball",
"FR": "Ball’Ombre",
"DE": "Spukball",
"IT": "Palla Ombra",
@@ -912,10 +627,6 @@
"pokemon_move_71": {
"PT-BR": "Soco Projétil",
"EN": "Bullet Punch",
- "FI": "Bullet Punch",
- "NL": "Bullet Punch",
- "NO": "Bullet Punch",
- "PL": "Bullet Punch",
"FR": "Pisto-Poing",
"DE": "Patronenhieb",
"IT": "Pugnoscarica",
@@ -925,10 +636,6 @@
"pokemon_move_72": {
"PT-BR": "Bomba Ímã",
"EN": "Magnet Bomb",
- "FI": "Magnet Bomb",
- "NL": "Magnet Bomb",
- "NO": "Magnet Bomb",
- "PL": "Magnet Bomb",
"FR": "Bombe Aimant",
"DE": "Magnetbombe",
"IT": "Bombagnete",
@@ -938,10 +645,6 @@
"pokemon_move_73": {
"PT-BR": "Asa de Aço",
"EN": "Steel Wing",
- "FI": "Steel Wing",
- "NL": "Steel Wing",
- "NO": "Steel Wing",
- "PL": "Steel Wing",
"FR": "Ailes d’Acier",
"DE": "Stahlflügel",
"IT": "Alacciaio",
@@ -951,10 +654,6 @@
"pokemon_move_74": {
"PT-BR": "Cabeça de Ferro",
"EN": "Iron Head",
- "FI": "Iron Head",
- "NL": "Iron Head",
- "NO": "Iron Head",
- "PL": "Iron Head",
"FR": "Tête de Fer",
"DE": "Eisenschädel",
"IT": "Metaltestata",
@@ -964,10 +663,6 @@
"pokemon_move_75": {
"PT-BR": "Ataque Parabólico",
"EN": "Parabolic Charge",
- "FI": "Parabolic Charge",
- "NL": "Parabolic Charge",
- "NO": "Parabolic Charge",
- "PL": "Parabolic Charge",
"FR": "Parabocharge",
"DE": "Parabolladung",
"IT": "Caricaparabola",
@@ -977,10 +672,6 @@
"pokemon_move_76": {
"PT-BR": "Faísca",
"EN": "Spark",
- "FI": "Spark",
- "NL": "Spark",
- "NO": "Spark",
- "PL": "Spark",
"FR": "Étincelle",
"DE": "Funkensprung",
"IT": "Scintilla",
@@ -990,10 +681,6 @@
"pokemon_move_77": {
"PT-BR": "Soco Trovoada",
"EN": "Thunder Punch",
- "FI": "Thunder Punch",
- "NL": "Thunder Punch",
- "NO": "Thunder Punch",
- "PL": "Thunder Punch",
"FR": "Poing Éclair",
"DE": "Donnerschlag",
"IT": "Tuonopugno",
@@ -1003,10 +690,6 @@
"pokemon_move_78": {
"PT-BR": "Trovão",
"EN": "Thunder",
- "FI": "Thunder",
- "NL": "Thunder",
- "NO": "Thunder",
- "PL": "Thunder",
"FR": "Fatal-Foudre",
"DE": "Donner",
"IT": "Tuono",
@@ -1016,10 +699,6 @@
"pokemon_move_79": {
"PT-BR": "Relâmpago",
"EN": "Thunderbolt",
- "FI": "Thunderbolt",
- "NL": "Thunderbolt",
- "NO": "Thunderbolt",
- "PL": "Thunderbolt",
"FR": "Tonnerre",
"DE": "Donnerblitz",
"IT": "Fulmine",
@@ -1027,12 +706,7 @@
"ES": "Rayo"
},
"pokemon_move_80": {
- "PT-BR": "Twister",
"EN": "Twister",
- "FI": "Twister",
- "NL": "Twister",
- "NO": "Twister",
- "PL": "Twister",
"FR": "Ouragan",
"DE": "Windhose",
"IT": "Tornado",
@@ -1042,10 +716,6 @@
"pokemon_move_81": {
"PT-BR": "Sopro do Dragão",
"EN": "Dragon Breath",
- "FI": "Dragon Breath",
- "NL": "Dragon Breath",
- "NO": "Dragon Breath",
- "PL": "Dragon Breath",
"FR": "Draco-Souffle",
"DE": "Feuerodem",
"IT": "Dragospiro",
@@ -1055,10 +725,6 @@
"pokemon_move_82": {
"PT-BR": "Pulso do Dragão",
"EN": "Dragon Pulse",
- "FI": "Dragon Pulse",
- "NL": "Dragon Pulse",
- "NO": "Dragon Pulse",
- "PL": "Dragon Pulse",
"FR": "Draco-Choc",
"DE": "Drachenpuls",
"IT": "Dragopulsar",
@@ -1068,10 +734,6 @@
"pokemon_move_83": {
"PT-BR": "Garra de Dragão",
"EN": "Dragon Claw",
- "FI": "Dragon Claw",
- "NL": "Dragon Claw",
- "NO": "Dragon Claw",
- "PL": "Dragon Claw",
"FR": "Draco-Griffe",
"DE": "Drachenklaue",
"IT": "Dragartigli",
@@ -1081,10 +743,6 @@
"pokemon_move_84": {
"PT-BR": "Voz Desarmante",
"EN": "Disarming Voice",
- "FI": "Disarming Voice",
- "NL": "Disarming Voice",
- "NO": "Disarming Voice",
- "PL": "Disarming Voice",
"FR": "Voix Enjôleuse",
"DE": "Säuselstimme",
"IT": "Incantavoce",
@@ -1094,10 +752,6 @@
"pokemon_move_85": {
"PT-BR": "Beijo Drenante",
"EN": "Draining Kiss",
- "FI": "Draining Kiss",
- "NL": "Draining Kiss",
- "NO": "Draining Kiss",
- "PL": "Draining Kiss",
"FR": "Vampibaiser",
"DE": "Diebeskuss",
"IT": "Assorbibacio",
@@ -1107,10 +761,6 @@
"pokemon_move_86": {
"PT-BR": "Clarão Deslumbrante",
"EN": "Dazzling Gleam",
- "FI": "Dazzling Gleam",
- "NL": "Dazzling Gleam",
- "NO": "Dazzling Gleam",
- "PL": "Dazzling Gleam",
"FR": "Éclat Magique",
"DE": "Zauberschein",
"IT": "Magibrillio",
@@ -1120,10 +770,6 @@
"pokemon_move_87": {
"PT-BR": "Explosão Lunar",
"EN": "Moonblast",
- "FI": "Moonblast",
- "NL": "Moonblast",
- "NO": "Moonblast",
- "PL": "Moonblast",
"FR": "Pouvoir Lunaire",
"DE": "Mondgewalt",
"IT": "Forza Lunare",
@@ -1133,10 +779,6 @@
"pokemon_move_88": {
"PT-BR": "Jogo Duro",
"EN": "Play Rough",
- "FI": "Play Rough",
- "NL": "Play Rough",
- "NO": "Play Rough",
- "PL": "Play Rough",
"FR": "Câlinerie",
"DE": "Knuddler",
"IT": "Carineria",
@@ -1146,10 +788,6 @@
"pokemon_move_89": {
"PT-BR": "Corte-veneno",
"EN": "Cross Poison",
- "FI": "Cross Poison",
- "NL": "Cross Poison",
- "NO": "Cross Poison",
- "PL": "Cross Poison",
"FR": "Poison Croix",
"DE": "Giftstreich",
"IT": "Velenocroce",
@@ -1159,10 +797,6 @@
"pokemon_move_90": {
"PT-BR": "Bomba de Lodo",
"EN": "Sludge Bomb",
- "FI": "Sludge Bomb",
- "NL": "Sludge Bomb",
- "NO": "Sludge Bomb",
- "PL": "Sludge Bomb",
"FR": "Bombe Beurk",
"DE": "Matschbombe",
"IT": "Fangobomba",
@@ -1172,10 +806,6 @@
"pokemon_move_91": {
"PT-BR": "Onda de Lama",
"EN": "Sludge Wave",
- "FI": "Sludge Wave",
- "NL": "Sludge Wave",
- "NO": "Sludge Wave",
- "PL": "Sludge Wave",
"FR": "Cradovague",
"DE": "Schlammwoge",
"IT": "Fangonda",
@@ -1185,10 +815,6 @@
"pokemon_move_92": {
"PT-BR": "Tiro de Sujeira",
"EN": "Gunk Shot",
- "FI": "Gunk Shot",
- "NL": "Gunk Shot",
- "NO": "Gunk Shot",
- "PL": "Gunk Shot",
"FR": "Détricanon",
"DE": "Mülltreffer",
"IT": "Sporcolancio",
@@ -1198,10 +824,6 @@
"pokemon_move_93": {
"PT-BR": "Tiro de Lama",
"EN": "Mud Shot",
- "FI": "Mud Shot",
- "NL": "Mud Shot",
- "NO": "Mud Shot",
- "PL": "Mud Shot",
"FR": "Tir de Boue",
"DE": "Lehmschuss",
"IT": "Colpodifango",
@@ -1211,10 +833,6 @@
"pokemon_move_94": {
"PT-BR": "Bastão de Osso",
"EN": "Bone Club",
- "FI": "Bone Club",
- "NL": "Bone Club",
- "NO": "Bone Club",
- "PL": "Bone Club",
"FR": "Massd’Os",
"DE": "Knochenkeule",
"IT": "Ossoclava",
@@ -1224,10 +842,6 @@
"pokemon_move_95": {
"PT-BR": "Tremor",
"EN": "Bulldoze",
- "FI": "Bulldoze",
- "NL": "Bulldoze",
- "NO": "Bulldoze",
- "PL": "Bulldoze",
"FR": "Piétisol",
"DE": "Dampfwalze",
"IT": "Battiterra",
@@ -1237,10 +851,6 @@
"pokemon_move_96": {
"PT-BR": "Bomba de Lama",
"EN": "Mud Bomb",
- "FI": "Mud Bomb",
- "NL": "Mud Bomb",
- "NO": "Mud Bomb",
- "PL": "Mud Bomb",
"FR": "Boue-Bombe",
"DE": "Schlammbombe",
"IT": "Pantanobomba",
@@ -1250,10 +860,6 @@
"pokemon_move_97": {
"PT-BR": "Cortador de Fúria",
"EN": "Fury Cutter",
- "FI": "Fury Cutter",
- "NL": "Fury Cutter",
- "NO": "Fury Cutter",
- "PL": "Fury Cutter",
"FR": "Taillade",
"DE": "Zornklinge",
"IT": "Tagliofuria",
@@ -1263,10 +869,6 @@
"pokemon_move_98": {
"PT-BR": "Picada",
"EN": "Bug Bite",
- "FI": "Bug Bite",
- "NL": "Bug Bite",
- "NO": "Bug Bite",
- "PL": "Bug Bite",
"FR": "Piqûre",
"DE": "Käferbiss",
"IT": "Coleomorso",
@@ -1276,10 +878,6 @@
"pokemon_move_99": {
"PT-BR": "Feixe Sinalizador",
"EN": "Signal Beam",
- "FI": "Signal Beam",
- "NL": "Signal Beam",
- "NO": "Signal Beam",
- "PL": "Signal Beam",
"FR": "Rayon Signal",
"DE": "Ampelleuchte",
"IT": "Segnoraggio",
@@ -1289,23 +887,15 @@
"pokemon_move_100": {
"PT-BR": "Tesoura X",
"EN": "X-Scissor",
- "FI": "X-Scissor",
- "NL": "X-Scissor",
- "NO": "X-Scissor",
- "PL": "X-Scissor",
"FR": "Plaie Croix",
"DE": "Kreuzschere",
"IT": "Forbice X",
- "RU": "Икс-Ножницы",
+ "RU": "Икс-ножницы",
"ES": "Tijera X"
},
"pokemon_move_101": {
"PT-BR": "Ataque de Chamas",
"EN": "Flame Charge",
- "FI": "Flame Charge",
- "NL": "Flame Charge",
- "NO": "Flame Charge",
- "PL": "Flame Charge",
"FR": "Nitrocharge",
"DE": "Nitroladung",
"IT": "Nitrocarica",
@@ -1315,10 +905,6 @@
"pokemon_move_102": {
"PT-BR": "Rajada de Chamas",
"EN": "Flame Burst",
- "FI": "Flame Burst",
- "NL": "Flame Burst",
- "NO": "Flame Burst",
- "PL": "Flame Burst",
"FR": "Rebondifeu",
"DE": "Funkenflug",
"IT": "Pirolancio",
@@ -1328,10 +914,6 @@
"pokemon_move_103": {
"PT-BR": "Rajada de Fogo",
"EN": "Fire Blast",
- "FI": "Fire Blast",
- "NL": "Fire Blast",
- "NO": "Fire Blast",
- "PL": "Fire Blast",
"FR": "Déflagration",
"DE": "Feuersturm",
"IT": "Fuocobomba",
@@ -1341,10 +923,6 @@
"pokemon_move_104": {
"PT-BR": "Salmoura",
"EN": "Brine",
- "FI": "Brine",
- "NL": "Brine",
- "NO": "Brine",
- "PL": "Brine",
"FR": "Saumure",
"DE": "Lake",
"IT": "Acquadisale",
@@ -1354,10 +932,6 @@
"pokemon_move_105": {
"PT-BR": "Pulso d'Água",
"EN": "Water Pulse",
- "FI": "Water Pulse",
- "NL": "Water Pulse",
- "NO": "Water Pulse",
- "PL": "Water Pulse",
"FR": "Vibraqua",
"DE": "Aquawelle",
"IT": "Idropulsar",
@@ -1367,10 +941,6 @@
"pokemon_move_106": {
"PT-BR": "Escaldada",
"EN": "Scald",
- "FI": "Scald",
- "NL": "Scald",
- "NO": "Scald",
- "PL": "Scald",
"FR": "Ébullition",
"DE": "Siedewasser",
"IT": "Idrovampata",
@@ -1380,10 +950,6 @@
"pokemon_move_107": {
"PT-BR": "Jato d'Água",
"EN": "Hydro Pump",
- "FI": "Hydro Pump",
- "NL": "Hydro Pump",
- "NO": "Hydro Pump",
- "PL": "Hydro Pump",
"FR": "Hydrocanon",
"DE": "Hydropumpe",
"IT": "Idropompa",
@@ -1393,10 +959,6 @@
"pokemon_move_108": {
"PT-BR": "Psíquico",
"EN": "Psychic",
- "FI": "Psychic",
- "NL": "Psychic",
- "NO": "Psychic",
- "PL": "Psychic",
"FR": "Psyko",
"DE": "Psychokinese",
"IT": "Psichico",
@@ -1406,10 +968,6 @@
"pokemon_move_109": {
"PT-BR": "Golpe Psíquico",
"EN": "Psystrike",
- "FI": "Psystrike",
- "NL": "Psystrike",
- "NO": "Psystrike",
- "PL": "Psystrike",
"FR": "Frappe Psy",
"DE": "Psychostoß",
"IT": "Psicobotta",
@@ -1419,10 +977,6 @@
"pokemon_move_110": {
"PT-BR": "Caco de Gelo",
"EN": "Ice Shard",
- "FI": "Ice Shard",
- "NL": "Ice Shard",
- "NO": "Ice Shard",
- "PL": "Ice Shard",
"FR": "Éclats Glace",
"DE": "Eissplitter",
"IT": "Geloscheggia",
@@ -1432,10 +986,6 @@
"pokemon_move_111": {
"PT-BR": "Vento Congelante",
"EN": "Icy Wind",
- "FI": "Icy Wind",
- "NL": "Icy Wind",
- "NO": "Icy Wind",
- "PL": "Icy Wind",
"FR": "Vent Glace",
"DE": "Eissturm",
"IT": "Ventogelato",
@@ -1445,10 +995,6 @@
"pokemon_move_112": {
"PT-BR": "Respiração de Gelo",
"EN": "Frost Breath",
- "FI": "Frost Breath",
- "NL": "Frost Breath",
- "NO": "Frost Breath",
- "PL": "Frost Breath",
"FR": "Souffle Glacé",
"DE": "Eisesodem",
"IT": "Alitogelido",
@@ -1458,10 +1004,6 @@
"pokemon_move_113": {
"PT-BR": "Absorção",
"EN": "Absorb",
- "FI": "Absorb",
- "NL": "Absorb",
- "NO": "Absorb",
- "PL": "Absorb",
"FR": "Vole-Vie",
"DE": "Absorber",
"IT": "Assorbimento",
@@ -1471,23 +1013,15 @@
"pokemon_move_114": {
"PT-BR": "Gigadreno",
"EN": "Giga Drain",
- "FI": "Giga Drain",
- "NL": "Giga Drain",
- "NO": "Giga Drain",
- "PL": "Giga Drain",
"FR": "Giga-Sangsue",
"DE": "Gigasauger",
"IT": "Gigassorbimento",
- "RU": "Гига-Осушение",
+ "RU": "Гига-осушение",
"ES": "Gigadrenado"
},
"pokemon_move_115": {
"PT-BR": "Soco de Fogo",
"EN": "Fire Punch",
- "FI": "Fire Punch",
- "NL": "Fire Punch",
- "NO": "Fire Punch",
- "PL": "Fire Punch",
"FR": "Poing Feu",
"DE": "Feuerschlag",
"IT": "Fuocopugno",
@@ -1497,10 +1031,6 @@
"pokemon_move_116": {
"PT-BR": "Raio Solar",
"EN": "Solar Beam",
- "FI": "Solar Beam",
- "NL": "Solar Beam",
- "NO": "Solar Beam",
- "PL": "Solar Beam",
"FR": "Lance-Soleil",
"DE": "Solarstrahl",
"IT": "Solarraggio",
@@ -1510,23 +1040,15 @@
"pokemon_move_117": {
"PT-BR": "Lâmina de Folha",
"EN": "Leaf Blade",
- "FI": "Leaf Blade",
- "NL": "Leaf Blade",
- "NO": "Leaf Blade",
- "PL": "Leaf Blade",
"FR": "Lame Feuille",
"DE": "Laubklinge",
"IT": "Fendifoglia",
- "RU": "Лист-Лезвие",
+ "RU": "Лист-лезвие",
"ES": "Hoja Aguda"
},
"pokemon_move_118": {
"PT-BR": "Chicote Poderoso",
"EN": "Power Whip",
- "FI": "Power Whip",
- "NL": "Power Whip",
- "NO": "Power Whip",
- "PL": "Power Whip",
"FR": "Mégafouet",
"DE": "Blattgeißel",
"IT": "Vigorcolpo",
@@ -1536,23 +1058,14 @@
"pokemon_move_119": {
"PT-BR": "Borrifada",
"EN": "Splash",
- "FI": "Splash",
- "NL": "Splash",
- "NO": "Splash",
- "PL": "Splash",
"FR": "Trempette",
"DE": "Platscher",
- "IT": "Splash",
"RU": "Всплеск",
"ES": "Salpicadura"
},
"pokemon_move_120": {
"PT-BR": "Ácido",
"EN": "Acid",
- "FI": "Acid",
- "NL": "Acid",
- "NO": "Acid",
- "PL": "Acid",
"FR": "Acide",
"DE": "Säure",
"IT": "Acido",
@@ -1562,10 +1075,6 @@
"pokemon_move_121": {
"PT-BR": "Cortador de Ar",
"EN": "Air Cutter",
- "FI": "Air Cutter",
- "NL": "Air Cutter",
- "NO": "Air Cutter",
- "PL": "Air Cutter",
"FR": "Tranch’Air",
"DE": "Windschnitt",
"IT": "Aerasoio",
@@ -1575,10 +1084,6 @@
"pokemon_move_122": {
"PT-BR": "Furacão",
"EN": "Hurricane",
- "FI": "Hurricane",
- "NL": "Hurricane",
- "NO": "Hurricane",
- "PL": "Hurricane",
"FR": "Vent Violent",
"DE": "Orkan",
"IT": "Tifone",
@@ -1588,10 +1093,6 @@
"pokemon_move_123": {
"PT-BR": "Quebra-telha",
"EN": "Brick Break",
- "FI": "Brick Break",
- "NL": "Brick Break",
- "NO": "Brick Break",
- "PL": "Brick Break",
"FR": "Casse-Brique",
"DE": "Durchbruch",
"IT": "Breccia",
@@ -1601,10 +1102,6 @@
"pokemon_move_124": {
"PT-BR": "Cortar",
"EN": "Cut",
- "FI": "Cut",
- "NL": "Cut",
- "NO": "Cut",
- "PL": "Cut",
"FR": "Coupe",
"DE": "Zerschneider",
"IT": "Taglio",
@@ -1614,10 +1111,6 @@
"pokemon_move_125": {
"PT-BR": "Ataque Veloz",
"EN": "Swift",
- "FI": "Swift",
- "NL": "Swift",
- "NO": "Swift",
- "PL": "Swift",
"FR": "Météores",
"DE": "Sternschauer",
"IT": "Comete",
@@ -1627,10 +1120,6 @@
"pokemon_move_126": {
"PT-BR": "Ataque de Chifre",
"EN": "Horn Attack",
- "FI": "Horn Attack",
- "NL": "Horn Attack",
- "NO": "Horn Attack",
- "PL": "Horn Attack",
"FR": "Koud’Korne",
"DE": "Hornattacke",
"IT": "Incornata",
@@ -1640,10 +1129,6 @@
"pokemon_move_127": {
"PT-BR": "Pisotear",
"EN": "Stomp",
- "FI": "Stomp",
- "NL": "Stomp",
- "NO": "Stomp",
- "PL": "Stomp",
"FR": "Écrasement",
"DE": "Stampfer",
"IT": "Pestone",
@@ -1653,10 +1138,6 @@
"pokemon_move_128": {
"PT-BR": "Cabeçada",
"EN": "Headbutt",
- "FI": "Headbutt",
- "NL": "Headbutt",
- "NO": "Headbutt",
- "PL": "Headbutt",
"FR": "Coup d’Boule",
"DE": "Kopfnuss",
"IT": "Bottintesta",
@@ -1666,10 +1147,6 @@
"pokemon_move_129": {
"PT-BR": "Hiperpresa",
"EN": "Hyper Fang",
- "FI": "Hyper Fang",
- "NL": "Hyper Fang",
- "NO": "Hyper Fang",
- "PL": "Hyper Fang",
"FR": "Croc de Mort",
"DE": "Hyperzahn",
"IT": "Iperzanna",
@@ -1679,12 +1156,7 @@
"pokemon_move_130": {
"PT-BR": "Pancada Brusca",
"EN": "Slam",
- "FI": "Slam",
- "NL": "Slam",
- "NO": "Slam",
- "PL": "Slam",
"FR": "Souplesse",
- "DE": "Slam",
"IT": "Schianto",
"RU": "Таранный Удар",
"ES": "Atizar"
@@ -1692,10 +1164,6 @@
"pokemon_move_131": {
"PT-BR": "Pancada Corporal",
"EN": "Body Slam",
- "FI": "Body Slam",
- "NL": "Body Slam",
- "NO": "Body Slam",
- "PL": "Body Slam",
"FR": "Plaquage",
"DE": "Bodyslam",
"IT": "Corposcontro",
@@ -1705,10 +1173,6 @@
"pokemon_move_132": {
"PT-BR": "Descansar",
"EN": "Rest",
- "FI": "Rest",
- "NL": "Rest",
- "NO": "Rest",
- "PL": "Rest",
"FR": "Repos",
"DE": "Erholung",
"IT": "Riposo",
@@ -1718,10 +1182,6 @@
"pokemon_move_133": {
"PT-BR": "Insistência",
"EN": "Struggle",
- "FI": "Struggle",
- "NL": "Struggle",
- "NO": "Struggle",
- "PL": "Struggle",
"FR": "Lutte",
"DE": "Verzweifler",
"IT": "Scontro",
@@ -1731,10 +1191,6 @@
"pokemon_move_134": {
"PT-BR": "Escaldada",
"EN": "Scald",
- "FI": "Scald",
- "NL": "Scald",
- "NO": "Scald",
- "PL": "Scald",
"FR": "Ébullition",
"DE": "Siedewasser",
"IT": "Idrovampata",
@@ -1744,10 +1200,6 @@
"pokemon_move_135": {
"PT-BR": "Jato d'Água",
"EN": "Hydro Pump",
- "FI": "Hydro Pump",
- "NL": "Hydro Pump",
- "NO": "Hydro Pump",
- "PL": "Hydro Pump",
"FR": "Hydrocanon",
"DE": "Hydropumpe",
"IT": "Idropompa",
@@ -1757,10 +1209,6 @@
"pokemon_move_136": {
"PT-BR": "Embrulho",
"EN": "Wrap",
- "FI": "Wrap",
- "NL": "Wrap",
- "NO": "Wrap",
- "PL": "Wrap",
"FR": "Ligotage",
"DE": "Wickel",
"IT": "Avvolgibotta",
@@ -1770,10 +1218,6 @@
"pokemon_move_137": {
"PT-BR": "Embrulho",
"EN": "Wrap",
- "FI": "Wrap",
- "NL": "Wrap",
- "NO": "Wrap",
- "PL": "Wrap",
"FR": "Ligotage",
"DE": "Wickel",
"IT": "Avvolgibotta",
@@ -1783,10 +1227,6 @@
"pokemon_move_200": {
"PT-BR": "Cortador de Fúria",
"EN": "Fury Cutter",
- "FI": "Fury Cutter",
- "NL": "Fury Cutter",
- "NO": "Fury Cutter",
- "PL": "Fury Cutter",
"FR": "Taillade",
"DE": "Zornklinge",
"IT": "Tagliofuria",
@@ -1796,10 +1236,6 @@
"pokemon_move_201": {
"PT-BR": "Picada",
"EN": "Bug Bite",
- "FI": "Bug Bite",
- "NL": "Bug Bite",
- "NO": "Bug Bite",
- "PL": "Bug Bite",
"FR": "Piqûre",
"DE": "Käferbiss",
"IT": "Coleomorso",
@@ -1809,10 +1245,6 @@
"pokemon_move_202": {
"PT-BR": "Mordida",
"EN": "Bite",
- "FI": "Bite",
- "NL": "Bite",
- "NO": "Bite",
- "PL": "Bite",
"FR": "Morsure",
"DE": "Biss",
"IT": "Morso",
@@ -1822,10 +1254,6 @@
"pokemon_move_203": {
"PT-BR": "Soco Enganador",
"EN": "Sucker Punch",
- "FI": "Sucker Punch",
- "NL": "Sucker Punch",
- "NO": "Sucker Punch",
- "PL": "Sucker Punch",
"FR": "Coup Bas",
"DE": "Tiefschlag",
"IT": "Sbigoattacco",
@@ -1835,10 +1263,6 @@
"pokemon_move_204": {
"PT-BR": "Sopro do Dragão",
"EN": "Dragon Breath",
- "FI": "Dragon Breath",
- "NL": "Dragon Breath",
- "NO": "Dragon Breath",
- "PL": "Dragon Breath",
"FR": "Draco-Souffle",
"DE": "Feuerodem",
"IT": "Dragospiro",
@@ -1848,10 +1272,6 @@
"pokemon_move_205": {
"PT-BR": "Trovoada de Choques",
"EN": "Thunder Shock",
- "FI": "Thunder Shock",
- "NL": "Thunder Shock",
- "NO": "Thunder Shock",
- "PL": "Thunder Shock",
"FR": "Éclair",
"DE": "Donnerschock",
"IT": "Tuonoshock",
@@ -1861,10 +1281,6 @@
"pokemon_move_206": {
"PT-BR": "Faísca",
"EN": "Spark",
- "FI": "Spark",
- "NL": "Spark",
- "NO": "Spark",
- "PL": "Spark",
"FR": "Étincelle",
"DE": "Funkensprung",
"IT": "Scintilla",
@@ -1874,10 +1290,6 @@
"pokemon_move_207": {
"PT-BR": "Rasteira",
"EN": "Low Kick",
- "FI": "Low Kick",
- "NL": "Low Kick",
- "NO": "Low Kick",
- "PL": "Low Kick",
"FR": "Balayage",
"DE": "Fußkick",
"IT": "Colpo Basso",
@@ -1887,10 +1299,6 @@
"pokemon_move_208": {
"PT-BR": "Golpe de Caratê",
"EN": "Karate Chop",
- "FI": "Karate Chop",
- "NL": "Karate Chop",
- "NO": "Karate Chop",
- "PL": "Karate Chop",
"FR": "Poing Karaté",
"DE": "Karateschlag",
"IT": "Colpokarate",
@@ -1900,10 +1308,6 @@
"pokemon_move_209": {
"PT-BR": "Brasa",
"EN": "Ember",
- "FI": "Ember",
- "NL": "Ember",
- "NO": "Ember",
- "PL": "Ember",
"FR": "Flammèche",
"DE": "Glut",
"IT": "Braciere",
@@ -1913,10 +1317,6 @@
"pokemon_move_210": {
"PT-BR": "Ataque de Asa",
"EN": "Wing Attack",
- "FI": "Wing Attack",
- "NL": "Wing Attack",
- "NO": "Wing Attack",
- "PL": "Wing Attack",
"FR": "Cru-Ailes",
"DE": "Flügelschlag",
"IT": "Attacco d’Ala",
@@ -1926,10 +1326,6 @@
"pokemon_move_211": {
"PT-BR": "Bicada",
"EN": "Peck",
- "FI": "Peck",
- "NL": "Peck",
- "NO": "Peck",
- "PL": "Peck",
"FR": "Picpic",
"DE": "Pikser",
"IT": "Beccata",
@@ -1939,10 +1335,6 @@
"pokemon_move_212": {
"PT-BR": "Lambida",
"EN": "Lick",
- "FI": "Lick",
- "NL": "Lick",
- "NO": "Lick",
- "PL": "Lick",
"FR": "Léchouille",
"DE": "Schlecker",
"IT": "Leccata",
@@ -1952,10 +1344,6 @@
"pokemon_move_213": {
"PT-BR": "Garra Sombria",
"EN": "Shadow Claw",
- "FI": "Shadow Claw",
- "NL": "Shadow Claw",
- "NO": "Shadow Claw",
- "PL": "Shadow Claw",
"FR": "Griffe Ombre",
"DE": "Dunkelklaue",
"IT": "Ombrartigli",
@@ -1965,23 +1353,15 @@
"pokemon_move_214": {
"PT-BR": "Chicote de Vinha",
"EN": "Vine Whip",
- "FI": "Vine Whip",
- "NL": "Vine Whip",
- "NO": "Vine Whip",
- "PL": "Vine Whip",
"FR": "Fouet Lianes",
"DE": "Rankenhieb",
"IT": "Frustata",
- "RU": "Плеть-Лиана",
+ "RU": "Плеть-лиана",
"ES": "Látigo Cepa"
},
"pokemon_move_215": {
"PT-BR": "Folha Navalha",
"EN": "Razor Leaf",
- "FI": "Razor Leaf",
- "NL": "Razor Leaf",
- "NO": "Razor Leaf",
- "PL": "Razor Leaf",
"FR": "Tranch’Herbe",
"DE": "Rasierblatt",
"IT": "Foglielama",
@@ -1991,10 +1371,6 @@
"pokemon_move_216": {
"PT-BR": "Tiro de Lama",
"EN": "Mud Shot",
- "FI": "Mud Shot",
- "NL": "Mud Shot",
- "NO": "Mud Shot",
- "PL": "Mud Shot",
"FR": "Tir de Boue",
"DE": "Lehmschuss",
"IT": "Colpodifango",
@@ -2004,10 +1380,6 @@
"pokemon_move_217": {
"PT-BR": "Caco de Gelo",
"EN": "Ice Shard",
- "FI": "Ice Shard",
- "NL": "Ice Shard",
- "NO": "Ice Shard",
- "PL": "Ice Shard",
"FR": "Éclats Glace",
"DE": "Eissplitter",
"IT": "Geloscheggia",
@@ -2017,10 +1389,6 @@
"pokemon_move_218": {
"PT-BR": "Respiração de Gelo",
"EN": "Frost Breath",
- "FI": "Frost Breath",
- "NL": "Frost Breath",
- "NO": "Frost Breath",
- "PL": "Frost Breath",
"FR": "Souffle Glacé",
"DE": "Eisesodem",
"IT": "Alitogelido",
@@ -2030,10 +1398,6 @@
"pokemon_move_219": {
"PT-BR": "Ataque Rápido",
"EN": "Quick Attack",
- "FI": "Quick Attack",
- "NL": "Quick Attack",
- "NO": "Quick Attack",
- "PL": "Quick Attack",
"FR": "Vive-Attaque",
"DE": "Ruckzuckhieb",
"IT": "Attacco Rapido",
@@ -2043,10 +1407,6 @@
"pokemon_move_220": {
"PT-BR": "Arranhão",
"EN": "Scratch",
- "FI": "Scratch",
- "NL": "Scratch",
- "NO": "Scratch",
- "PL": "Scratch",
"FR": "Griffe",
"DE": "Kratzer",
"IT": "Graffio",
@@ -2056,12 +1416,7 @@
"pokemon_move_221": {
"PT-BR": "Investida",
"EN": "Tackle",
- "FI": "Tackle",
- "NL": "Tackle",
- "NO": "Tackle",
- "PL": "Tackle",
"FR": "Charge",
- "DE": "Tackle",
"IT": "Azione",
"RU": "Бросок",
"ES": "Placaje"
@@ -2069,10 +1424,6 @@
"pokemon_move_222": {
"PT-BR": "Pancada",
"EN": "Pound",
- "FI": "Pound",
- "NL": "Pound",
- "NO": "Pound",
- "PL": "Pound",
"FR": "Écras’Face",
"DE": "Klaps",
"IT": "Botta",
@@ -2082,10 +1433,6 @@
"pokemon_move_223": {
"PT-BR": "Cortar",
"EN": "Cut",
- "FI": "Cut",
- "NL": "Cut",
- "NO": "Cut",
- "PL": "Cut",
"FR": "Coupe",
"DE": "Zerschneider",
"IT": "Taglio",
@@ -2095,10 +1442,6 @@
"pokemon_move_224": {
"PT-BR": "Golpe Envenenado",
"EN": "Poison Jab",
- "FI": "Poison Jab",
- "NL": "Poison Jab",
- "NO": "Poison Jab",
- "PL": "Poison Jab",
"FR": "Direct Toxik",
"DE": "Gifthieb",
"IT": "Velenpuntura",
@@ -2108,10 +1451,6 @@
"pokemon_move_225": {
"PT-BR": "Ácido",
"EN": "Acid",
- "FI": "Acid",
- "NL": "Acid",
- "NO": "Acid",
- "PL": "Acid",
"FR": "Acide",
"DE": "Säure",
"IT": "Acido",
@@ -2121,10 +1460,6 @@
"pokemon_move_226": {
"PT-BR": "Corte Psíquico",
"EN": "Psycho Cut",
- "FI": "Psycho Cut",
- "NL": "Psycho Cut",
- "NO": "Psycho Cut",
- "PL": "Psycho Cut",
"FR": "Coupe Psycho",
"DE": "Psychoklinge",
"IT": "Psicotaglio",
@@ -2134,10 +1469,6 @@
"pokemon_move_227": {
"PT-BR": "Lançamento de Rocha",
"EN": "Rock Throw",
- "FI": "Rock Throw",
- "NL": "Rock Throw",
- "NO": "Rock Throw",
- "PL": "Rock Throw",
"FR": "Jet-Pierres",
"DE": "Steinwurf",
"IT": "Sassata",
@@ -2147,10 +1478,6 @@
"pokemon_move_228": {
"PT-BR": "Garra de Metal",
"EN": "Metal Claw",
- "FI": "Metal Claw",
- "NL": "Metal Claw",
- "NO": "Metal Claw",
- "PL": "Metal Claw",
"FR": "Griffe Acier",
"DE": "Metallklaue",
"IT": "Ferrartigli",
@@ -2160,10 +1487,6 @@
"pokemon_move_229": {
"PT-BR": "Soco Projétil",
"EN": "Bullet Punch",
- "FI": "Bullet Punch",
- "NL": "Bullet Punch",
- "NO": "Bullet Punch",
- "PL": "Bullet Punch",
"FR": "Pisto-Poing",
"DE": "Patronenhieb",
"IT": "Pugnoscarica",
@@ -2173,10 +1496,6 @@
"pokemon_move_230": {
"PT-BR": "Revólver d'Água",
"EN": "Water Gun",
- "FI": "Water Gun",
- "NL": "Water Gun",
- "NO": "Water Gun",
- "PL": "Water Gun",
"FR": "Pistolet à O",
"DE": "Aquaknarre",
"IT": "Pistolacqua",
@@ -2186,23 +1505,14 @@
"pokemon_move_231": {
"PT-BR": "Borrifada",
"EN": "Splash",
- "FI": "Splash",
- "NL": "Splash",
- "NO": "Splash",
- "PL": "Splash",
"FR": "Trempette",
"DE": "Platscher",
- "IT": "Splash",
"RU": "Всплеск",
"ES": "Salpicadura"
},
"pokemon_move_232": {
"PT-BR": "Revólver d'Água",
"EN": "Water Gun",
- "FI": "Water Gun",
- "NL": "Water Gun",
- "NO": "Water Gun",
- "PL": "Water Gun",
"FR": "Pistolet à O",
"DE": "Aquaknarre",
"IT": "Pistolacqua",
@@ -2212,10 +1522,6 @@
"pokemon_move_233": {
"PT-BR": "Tapa de Lama",
"EN": "Mud-Slap",
- "FI": "Mud-Slap",
- "NL": "Mud-Slap",
- "NO": "Mud-Slap",
- "PL": "Mud-Slap",
"FR": "Coud’Boue",
"DE": "Lehmschelle",
"IT": "Fangosberla",
@@ -2225,10 +1531,6 @@
"pokemon_move_234": {
"PT-BR": "Cabeçada Zen",
"EN": "Zen Headbutt",
- "FI": "Zen Headbutt",
- "NL": "Zen Headbutt",
- "NO": "Zen Headbutt",
- "PL": "Zen Headbutt",
"FR": "Psykoud’Boul",
"DE": "Zen-Kopfstoß",
"IT": "Cozzata Zen",
@@ -2238,10 +1540,6 @@
"pokemon_move_235": {
"PT-BR": "Confusão",
"EN": "Confusion",
- "FI": "Confusion",
- "NL": "Confusion",
- "NO": "Confusion",
- "PL": "Confusion",
"FR": "Choc Mental",
"DE": "Konfusion",
"IT": "Confusione",
@@ -2251,10 +1549,6 @@
"pokemon_move_236": {
"PT-BR": "Ferrão Venenoso",
"EN": "Poison Sting",
- "FI": "Poison Sting",
- "NL": "Poison Sting",
- "NO": "Poison Sting",
- "PL": "Poison Sting",
"FR": "Dard-Venin",
"DE": "Giftstachel",
"IT": "Velenospina",
@@ -2264,10 +1558,6 @@
"pokemon_move_237": {
"PT-BR": "Bolha",
"EN": "Bubble",
- "FI": "Bubble",
- "NL": "Bubble",
- "NO": "Bubble",
- "PL": "Bubble",
"FR": "Écume",
"DE": "Blubber",
"IT": "Bolla",
@@ -2277,10 +1567,6 @@
"pokemon_move_238": {
"PT-BR": "Ataque Dissimulado",
"EN": "Feint Attack",
- "FI": "Feint Attack",
- "NL": "Feint Attack",
- "NO": "Feint Attack",
- "PL": "Feint Attack",
"FR": "Feinte",
"DE": "Finte",
"IT": "Finta",
@@ -2290,10 +1576,6 @@
"pokemon_move_239": {
"PT-BR": "Asa de Aço",
"EN": "Steel Wing",
- "FI": "Steel Wing",
- "NL": "Steel Wing",
- "NO": "Steel Wing",
- "PL": "Steel Wing",
"FR": "Ailes d’Acier",
"DE": "Stahlflügel",
"IT": "Alacciaio",
@@ -2303,10 +1585,6 @@
"pokemon_move_240": {
"PT-BR": "Presas de Fogo",
"EN": "Fire Fang",
- "FI": "Fire Fang",
- "NL": "Fire Fang",
- "NO": "Fire Fang",
- "PL": "Fire Fang",
"FR": "Crocs Feu",
"DE": "Feuerzahn",
"IT": "Rogodenti",
@@ -2316,10 +1594,6 @@
"pokemon_move_241": {
"PT-BR": "Esmagamento de Pedras",
"EN": "Rock Smash",
- "FI": "Rock Smash",
- "NL": "Rock Smash",
- "NO": "Rock Smash",
- "PL": "Rock Smash",
"FR": "Éclate-Roc",
"DE": "Zertrümmerer",
"IT": "Spaccaroccia",
@@ -2329,10 +1603,6 @@
"pokemon_move_242": {
"PT-BR": "Transformação",
"EN": "Transform",
- "FI": "Transform",
- "NL": "Transform",
- "NO": "Transform",
- "PL": "Transform",
"FR": "Morphing",
"DE": "Wandler",
"IT": "Trasformazione",
@@ -2342,10 +1612,6 @@
"pokemon_move_243": {
"PT-BR": "Contra-atacar",
"EN": "Counter",
- "FI": "Counter",
- "NL": "Counter",
- "NO": "Counter",
- "PL": "Counter",
"FR": "Riposte",
"DE": "Konter",
"IT": "Contrattacco",
@@ -2355,10 +1621,6 @@
"pokemon_move_244": {
"PT-BR": "Neve em Pó",
"EN": "Powder Snow",
- "FI": "Powder Snow",
- "NL": "Powder Snow",
- "NO": "Powder Snow",
- "PL": "Powder Snow",
"FR": "Poudreuse",
"DE": "Pulverschnee",
"IT": "Polneve",
@@ -2368,11 +1630,6 @@
"pokemon_move_245": {
"PT-BR": "Corpo-a-corpo",
"EN": "Close Combat",
- "FI": "Close Combat",
- "NL": "Close Combat",
- "NO": "Close Combat",
- "PL": "Close Combat",
- "FR": "Close Combat",
"DE": "Nahkampf",
"IT": "Zuffa",
"RU": "Ближний Бой",
@@ -2381,10 +1638,6 @@
"pokemon_move_246": {
"PT-BR": "Soco Dinâmico",
"EN": "Dynamic Punch",
- "FI": "Dynamic Punch",
- "NL": "Dynamic Punch",
- "NO": "Dynamic Punch",
- "PL": "Dynamic Punch",
"FR": "Dynamo-Poing",
"DE": "Wuchtschlag",
"IT": "Dinamipugno",
@@ -2394,10 +1647,6 @@
"pokemon_move_247": {
"PT-BR": "Explosão Focalizada",
"EN": "Focus Blast",
- "FI": "Focus Blast",
- "NL": "Focus Blast",
- "NO": "Focus Blast",
- "PL": "Focus Blast",
"FR": "Exploforce",
"DE": "Fokusstoß",
"IT": "Focalcolpo",
@@ -2407,10 +1656,6 @@
"pokemon_move_248": {
"PT-BR": "Raio Aurora",
"EN": "Aurora Beam",
- "FI": "Aurora Beam",
- "NL": "Aurora Beam",
- "NO": "Aurora Beam",
- "PL": "Aurora Beam",
"FR": "Onde Boréale",
"DE": "Aurorastrahl",
"IT": "Raggiaurora",
@@ -2420,10 +1665,6 @@
"pokemon_move_249": {
"PT-BR": "Carga de Raio",
"EN": "Charge Beam",
- "FI": "Charge Beam",
- "NL": "Charge Beam",
- "NO": "Charge Beam",
- "PL": "Charge Beam",
"FR": "Rayon Chargé",
"DE": "Ladestrahl",
"IT": "Raggioscossa",
@@ -2433,10 +1674,6 @@
"pokemon_move_250": {
"PT-BR": "Troca Elétrica",
"EN": "Volt Switch",
- "FI": "Volt Switch",
- "NL": "Volt Switch",
- "NO": "Volt Switch",
- "PL": "Volt Switch",
"FR": "Change Éclair",
"DE": "Voltwechsel",
"IT": "Invertivolt",
@@ -2446,10 +1683,6 @@
"pokemon_move_251": {
"PT-BR": "Ataque Selvagem",
"EN": "Wild Charge",
- "FI": "Wild Charge",
- "NL": "Wild Charge",
- "NO": "Wild Charge",
- "PL": "Wild Charge",
"FR": "Éclair Fou",
"DE": "Stromstoß",
"IT": "Sprizzalampo",
@@ -2459,10 +1692,6 @@
"pokemon_move_252": {
"PT-BR": "Canhão Zap",
"EN": "Zap Cannon",
- "FI": "Zap Cannon",
- "NL": "Zap Cannon",
- "NO": "Zap Cannon",
- "PL": "Zap Cannon",
"FR": "Élecanon",
"DE": "Blitzkanone",
"IT": "Falcecannone",
@@ -2472,10 +1701,6 @@
"pokemon_move_253": {
"PT-BR": "Cauda do Dragão",
"EN": "Dragon Tail",
- "FI": "Dragon Tail",
- "NL": "Dragon Tail",
- "NO": "Dragon Tail",
- "PL": "Dragon Tail",
"FR": "Draco-Queue",
"DE": "Drachenrute",
"IT": "Codadrago",
@@ -2483,13 +1708,7 @@
"ES": "Cola Dragón"
},
"pokemon_move_254": {
- "PT-BR": "Avalanche",
"EN": "Avalanche",
- "FI": "Avalanche",
- "NL": "Avalanche",
- "NO": "Avalanche",
- "PL": "Avalanche",
- "FR": "Avalanche",
"DE": "Lawine",
"IT": "Slavina",
"RU": "Лавина",
@@ -2498,10 +1717,6 @@
"pokemon_move_255": {
"PT-BR": "Golpe de Ar",
"EN": "Air Slash",
- "FI": "Air Slash",
- "NL": "Air Slash",
- "NO": "Air Slash",
- "PL": "Air Slash",
"FR": "Lame d’Air",
"DE": "Luftschnitt",
"IT": "Eterelama",
@@ -2511,10 +1726,6 @@
"pokemon_move_256": {
"PT-BR": "Pássaro Bravo",
"EN": "Brave Bird",
- "FI": "Brave Bird",
- "NL": "Brave Bird",
- "NO": "Brave Bird",
- "PL": "Brave Bird",
"FR": "Rapace",
"DE": "Sturzflug",
"IT": "Baldeali",
@@ -2524,10 +1735,6 @@
"pokemon_move_257": {
"PT-BR": "Ataque do Céu",
"EN": "Sky Attack",
- "FI": "Sky Attack",
- "NL": "Sky Attack",
- "NO": "Sky Attack",
- "PL": "Sky Attack",
"FR": "Piqué",
"DE": "Himmelsfeger",
"IT": "Aeroattacco",
@@ -2537,10 +1744,6 @@
"pokemon_move_258": {
"PT-BR": "Fosso de Areia",
"EN": "Sand Tomb",
- "FI": "Sand Tomb",
- "NL": "Sand Tomb",
- "NO": "Sand Tomb",
- "PL": "Sand Tomb",
"FR": "Tourbi-Sable",
"DE": "Sandgrab",
"IT": "Sabbiotomba",
@@ -2550,10 +1753,6 @@
"pokemon_move_259": {
"PT-BR": "Explosão de Rocha",
"EN": "Rock Blast",
- "FI": "Rock Blast",
- "NL": "Rock Blast",
- "NO": "Rock Blast",
- "PL": "Rock Blast",
"FR": "Boule Roc",
"DE": "Felswurf",
"IT": "Cadutamassi",
@@ -2563,10 +1762,6 @@
"pokemon_move_260": {
"PT-BR": "Infestação",
"EN": "Infestation",
- "FI": "Infestation",
- "NL": "Infestation",
- "NO": "Infestation",
- "PL": "Infestation",
"FR": "Harcèlement",
"DE": "Plage",
"IT": "Assillo",
@@ -2576,10 +1771,6 @@
"pokemon_move_261": {
"PT-BR": "Ira de Inseto",
"EN": "Struggle Bug",
- "FI": "Struggle Bug",
- "NL": "Struggle Bug",
- "NO": "Struggle Bug",
- "PL": "Struggle Bug",
"FR": "Survinsecte",
"DE": "Käfertrutz",
"IT": "Entomoblocco",
@@ -2589,10 +1780,6 @@
"pokemon_move_262": {
"PT-BR": "Vento Prateado",
"EN": "Silver Wind",
- "FI": "Silver Wind",
- "NL": "Silver Wind",
- "NO": "Silver Wind",
- "PL": "Silver Wind",
"FR": "Vent Argenté",
"DE": "Silberhauch",
"IT": "Ventargenteo",
@@ -2602,10 +1789,6 @@
"pokemon_move_263": {
"PT-BR": "Abismar",
"EN": "Astonish",
- "FI": "Astonish",
- "NL": "Astonish",
- "NO": "Astonish",
- "PL": "Astonish",
"FR": "Étonnement",
"DE": "Erstauner",
"IT": "Sgomento",
@@ -2615,10 +1798,6 @@
"pokemon_move_264": {
"PT-BR": "Feitiço",
"EN": "Hex",
- "FI": "Hex",
- "NL": "Hex",
- "NO": "Hex",
- "PL": "Hex",
"FR": "Châtiment",
"DE": "Bürde",
"IT": "Sciagura",
@@ -2628,10 +1807,6 @@
"pokemon_move_265": {
"PT-BR": "Sombra Noturna",
"EN": "Night Shade",
- "FI": "Night Shade",
- "NL": "Night Shade",
- "NO": "Night Shade",
- "PL": "Night Shade",
"FR": "Ombre Nocturne",
"DE": "Nachtnebel",
"IT": "Ombra Notturna",
@@ -2641,10 +1816,6 @@
"pokemon_move_266": {
"PT-BR": "Cauda de Ferro",
"EN": "Iron Tail",
- "FI": "Iron Tail",
- "NL": "Iron Tail",
- "NO": "Iron Tail",
- "PL": "Iron Tail",
"FR": "Queue de Fer",
"DE": "Eisenschweif",
"IT": "Codacciaio",
@@ -2654,23 +1825,15 @@
"pokemon_move_267": {
"PT-BR": "Girobola",
"EN": "Gyro Ball",
- "FI": "Gyro Ball",
- "NL": "Gyro Ball",
- "NO": "Gyro Ball",
- "PL": "Gyro Ball",
"FR": "Gyroballe",
"DE": "Gyroball",
"IT": "Vortexpalla",
- "RU": "Гиро-Шар",
+ "RU": "Гиро-шар",
"ES": "Giro Bola"
},
"pokemon_move_268": {
"PT-BR": "Golpe Pesado",
"EN": "Heavy Slam",
- "FI": "Heavy Slam",
- "NL": "Heavy Slam",
- "NO": "Heavy Slam",
- "PL": "Heavy Slam",
"FR": "Tacle Lourd",
"DE": "Rammboss",
"IT": "Pesobomba",
@@ -2680,10 +1843,6 @@
"pokemon_move_269": {
"PT-BR": "Chama Furacão",
"EN": "Fire Spin",
- "FI": "Fire Spin",
- "NL": "Fire Spin",
- "NO": "Fire Spin",
- "PL": "Fire Spin",
"FR": "Danse Flammes",
"DE": "Feuerwirbel",
"IT": "Turbofuoco",
@@ -2693,10 +1852,6 @@
"pokemon_move_270": {
"PT-BR": "Superaquecimento",
"EN": "Overheat",
- "FI": "Overheat",
- "NL": "Overheat",
- "NO": "Overheat",
- "PL": "Overheat",
"FR": "Surchauffe",
"DE": "Hitzekoller",
"IT": "Vampata",
@@ -2706,10 +1861,6 @@
"pokemon_move_271": {
"PT-BR": "Projétil de Semente",
"EN": "Bullet Seed",
- "FI": "Bullet Seed",
- "NL": "Bullet Seed",
- "NO": "Bullet Seed",
- "PL": "Bullet Seed",
"FR": "Balle Graine",
"DE": "Kugelsaat",
"IT": "Semitraglia",
@@ -2719,10 +1870,6 @@
"pokemon_move_272": {
"PT-BR": "Nó de Grama",
"EN": "Grass Knot",
- "FI": "Grass Knot",
- "NL": "Grass Knot",
- "NO": "Grass Knot",
- "PL": "Grass Knot",
"FR": "Nœud Herbe",
"DE": "Strauchler",
"IT": "Laccioerboso",
@@ -2732,10 +1879,6 @@
"pokemon_move_273": {
"PT-BR": "Bola de Energia",
"EN": "Energy Ball",
- "FI": "Energy Ball",
- "NL": "Energy Ball",
- "NO": "Energy Ball",
- "PL": "Energy Ball",
"FR": "Éco-Sphère",
"DE": "Energieball",
"IT": "Energipalla",
@@ -2745,10 +1888,6 @@
"pokemon_move_274": {
"PT-BR": "Extrassensorial",
"EN": "Extrasensory",
- "FI": "Extrasensory",
- "NL": "Extrasensory",
- "NO": "Extrasensory",
- "PL": "Extrasensory",
"FR": "Extrasenseur",
"DE": "Sondersensor",
"IT": "Extrasenso",
@@ -2758,10 +1897,6 @@
"pokemon_move_275": {
"PT-BR": "Visão do Futuro",
"EN": "Future Sight",
- "FI": "Future Sight",
- "NL": "Future Sight",
- "NO": "Future Sight",
- "PL": "Future Sight",
"FR": "Prescience",
"DE": "Seher",
"IT": "Divinazione",
@@ -2771,10 +1906,6 @@
"pokemon_move_276": {
"PT-BR": "Casaco Espelhado",
"EN": "Mirror Coat",
- "FI": "Mirror Coat",
- "NL": "Mirror Coat",
- "NO": "Mirror Coat",
- "PL": "Mirror Coat",
"FR": "Voile Miroir",
"DE": "Spiegelcape",
"IT": "Specchiovelo",
@@ -2784,10 +1915,6 @@
"pokemon_move_277": {
"PT-BR": "Ultraje",
"EN": "Outrage",
- "FI": "Outrage",
- "NL": "Outrage",
- "NO": "Outrage",
- "PL": "Outrage",
"FR": "Colère",
"DE": "Wutanfall",
"IT": "Oltraggio",
@@ -2797,10 +1924,6 @@
"pokemon_move_278": {
"PT-BR": "Rosnado",
"EN": "Snarl",
- "FI": "Snarl",
- "NL": "Snarl",
- "NO": "Snarl",
- "PL": "Snarl",
"FR": "Aboiement",
"DE": "Standpauke",
"IT": "Urlorabbia",
@@ -2810,10 +1933,6 @@
"pokemon_move_279": {
"PT-BR": "Mastigada",
"EN": "Crunch",
- "FI": "Crunch",
- "NL": "Crunch",
- "NO": "Crunch",
- "PL": "Crunch",
"FR": "Mâchouille",
"DE": "Knirscher",
"IT": "Sgranocchio",
@@ -2823,10 +1942,6 @@
"pokemon_move_280": {
"PT-BR": "Jogo Sujo",
"EN": "Foul Play",
- "FI": "Foul Play",
- "NL": "Foul Play",
- "NO": "Foul Play",
- "PL": "Foul Play",
"FR": "Tricherie",
"DE": "Schmarotzer",
"IT": "Ripicca",
@@ -2836,10 +1951,6 @@
"pokemon_move_281": {
"PT-BR": "Poder Oculto",
"EN": "Hidden Power",
- "FI": "Hidden Power",
- "NL": "Hidden Power",
- "NO": "Hidden Power",
- "PL": "Hidden Power",
"FR": "Puissance Cachée",
"DE": "Kraftreserve",
"IT": "Introforza",
@@ -2849,10 +1960,6 @@
"pokemon_move_282": {
"PT-BR": "Desmantelar",
"EN": "Take Down",
- "FI": "Take Down",
- "NL": "Take Down",
- "NO": "Take Down",
- "PL": "Take Down",
"FR": "Bélier",
"DE": "Bodycheck",
"IT": "Riduttore",
@@ -2862,10 +1969,6 @@
"pokemon_move_283": {
"PT-BR": "Cachoeira",
"EN": "Waterfall",
- "FI": "Waterfall",
- "NL": "Waterfall",
- "NO": "Waterfall",
- "PL": "Waterfall",
"FR": "Cascade",
"DE": "Kaskade",
"IT": "Cascata",
@@ -2875,25 +1978,13 @@
"pokemon_move_284": {
"PT-BR": "Surfar",
"EN": "Surf",
- "FI": "Surf",
- "NL": "Surf",
- "NO": "Surf",
- "PL": "Surf",
- "FR": "Surf",
"DE": "Surfer",
- "IT": "Surf",
- "RU": "Сёрф",
- "ES": "Surf"
+ "RU": "Сёрф"
},
"pokemon_move_285": {
"PT-BR": "Meteoro do Dragão",
"EN": "Draco Meteor",
- "FI": "Draco Meteor",
- "NL": "Draco Meteor",
- "NO": "Draco Meteor",
- "PL": "Draco Meteor",
"FR": "Draco-Météore",
- "DE": "Draco Meteor",
"IT": "Dragobolide",
"RU": "Метеор Дракона",
"ES": "Cometa Draco"
@@ -2901,10 +1992,6 @@
"pokemon_move_286": {
"PT-BR": "Desejo Cruel",
"EN": "Doom Desire",
- "FI": "Doom Desire",
- "NL": "Doom Desire",
- "NO": "Doom Desire",
- "PL": "Doom Desire",
"FR": "Carnareket",
"DE": "Kismetwunsch",
"IT": "Obbliderio",
@@ -2914,10 +2001,6 @@
"pokemon_move_287": {
"PT-BR": "Bocejo",
"EN": "Yawn",
- "FI": "Yawn",
- "NL": "Yawn",
- "NO": "Yawn",
- "PL": "Yawn",
"FR": "Bâillement",
"DE": "Gähner",
"IT": "Sbadiglio",
@@ -2927,10 +2010,6 @@
"pokemon_move_288": {
"PT-BR": "Impulso Psíquico",
"EN": "Psycho Boost",
- "FI": "Psycho Boost",
- "NL": "Psycho Boost",
- "NO": "Psycho Boost",
- "PL": "Psycho Boost",
"FR": "Psycho-Boost",
"DE": "Psyschub",
"IT": "Psicoslancio",
@@ -2940,10 +2019,6 @@
"pokemon_move_289": {
"PT-BR": "Pulso Original",
"EN": "Origin Pulse",
- "FI": "Origin Pulse",
- "NL": "Origin Pulse",
- "NO": "Origin Pulse",
- "PL": "Origin Pulse",
"FR": "Onde Originelle",
"DE": "Ursprungswoge",
"IT": "Primopulsar",
@@ -2953,10 +2028,6 @@
"pokemon_move_290": {
"PT-BR": "Lâmina Abissal",
"EN": "Precipice Blades",
- "FI": "Precipice Blades",
- "NL": "Precipice Blades",
- "NO": "Precipice Blades",
- "PL": "Precipice Blades",
"FR": "Lame Pangéenne",
"DE": "Abgrundsklinge",
"IT": "Spade Telluriche",
@@ -2966,10 +2037,6 @@
"pokemon_move_291": {
"PT-BR": "Presente",
"EN": "Present",
- "FI": "Present",
- "NL": "Present",
- "NO": "Present",
- "PL": "Present",
"FR": "Cadeau",
"DE": "Geschenk",
"IT": "Regalino",
@@ -2979,10 +2046,6 @@
"pokemon_move_292": {
"PT-BR": "Esfera Climática",
"EN": "Weather Ball",
- "FI": "Weather Ball",
- "NL": "Weather Ball",
- "NO": "Weather Ball",
- "PL": "Weather Ball",
"FR": "Ball’Météo",
"DE": "Meteorologe",
"IT": "Palla Clima",
@@ -2992,10 +2055,6 @@
"pokemon_move_293": {
"PT-BR": "Esfera Climática",
"EN": "Weather Ball",
- "FI": "Weather Ball",
- "NL": "Weather Ball",
- "NO": "Weather Ball",
- "PL": "Weather Ball",
"FR": "Ball’Météo",
"DE": "Meteorologe",
"IT": "Palla Clima",
@@ -3005,10 +2064,6 @@
"pokemon_move_294": {
"PT-BR": "Esfera Climática",
"EN": "Weather Ball",
- "FI": "Weather Ball",
- "NL": "Weather Ball",
- "NO": "Weather Ball",
- "PL": "Weather Ball",
"FR": "Ball’Météo",
"DE": "Meteorologe",
"IT": "Palla Clima",
@@ -3018,10 +2073,6 @@
"pokemon_move_295": {
"PT-BR": "Esfera Climática",
"EN": "Weather Ball",
- "FI": "Weather Ball",
- "NL": "Weather Ball",
- "NO": "Weather Ball",
- "PL": "Weather Ball",
"FR": "Ball’Météo",
"DE": "Meteorologe",
"IT": "Palla Clima",
@@ -3031,10 +2082,6 @@
"pokemon_move_296": {
"PT-BR": "Planta Mortal",
"EN": "Frenzy Plant",
- "FI": "Frenzy Plant",
- "NL": "Frenzy Plant",
- "NO": "Frenzy Plant",
- "PL": "Frenzy Plant",
"FR": "Végé-Attaque",
"DE": "Flora-Statue",
"IT": "Radicalbero",
@@ -3044,10 +2091,6 @@
"pokemon_move_297": {
"PT-BR": "Derrubada",
"EN": "Smack Down",
- "FI": "Smack Down",
- "NL": "Smack Down",
- "NO": "Smack Down",
- "PL": "Smack Down",
"FR": "Anti-Air",
"DE": "Katapult",
"IT": "Abbattimento",
@@ -3057,10 +2100,6 @@
"pokemon_move_298": {
"PT-BR": "Queimadura Explosiva",
"EN": "Blast Burn",
- "FI": "Blast Burn",
- "NL": "Blast Burn",
- "NO": "Blast Burn",
- "PL": "Blast Burn",
"FR": "Rafale Feu",
"DE": "Lohekanonade",
"IT": "Incendio",
@@ -3070,10 +2109,6 @@
"pokemon_move_299": {
"PT-BR": "Hidro Canhão",
"EN": "Hydro Cannon",
- "FI": "Hydro Cannon",
- "NL": "Hydro Cannon",
- "NO": "Hydro Cannon",
- "PL": "Hydro Cannon",
"FR": "Hydroblast",
"DE": "Aquahaubitze",
"IT": "Idrocannone",
@@ -3083,10 +2118,6 @@
"pokemon_move_300": {
"PT-BR": "Último Recurso",
"EN": "Last Resort",
- "FI": "Last Resort",
- "NL": "Last Resort",
- "NO": "Last Resort",
- "PL": "Last Resort",
"FR": "Dernier Recours",
"DE": "Zuflucht",
"IT": "Ultimascelta",
@@ -3096,10 +2127,6 @@
"pokemon_move_301": {
"PT-BR": "Meteoro Esmagador",
"EN": "Meteor Mash",
- "FI": "Meteor Mash",
- "NL": "Meteor Mash",
- "NO": "Meteor Mash",
- "PL": "Meteor Mash",
"FR": "Poing Météore",
"DE": "Sternenhieb",
"IT": "Meteorpugno",
@@ -3109,10 +2136,6 @@
"pokemon_move_302": {
"PT-BR": "Quebra-crânio",
"EN": "Skull Bash",
- "FI": "Skull Bash",
- "NL": "Skull Bash",
- "NO": "Skull Bash",
- "PL": "Skull Bash",
"FR": "Coud’Krâne",
"DE": "Schädelwumme",
"IT": "Capocciata",
@@ -3122,10 +2145,6 @@
"pokemon_move_303": {
"PT-BR": "Spray Ácido",
"EN": "Acid Spray",
- "FI": "Acid Spray",
- "NL": "Acid Spray",
- "NO": "Acid Spray",
- "PL": "Acid Spray",
"FR": "Bombe Acide",
"DE": "Säurespeier",
"IT": "Acidobomba",
@@ -3135,10 +2154,6 @@
"pokemon_move_304": {
"PT-BR": "Poder da Terra",
"EN": "Earth Power",
- "FI": "Earth Power",
- "NL": "Earth Power",
- "NO": "Earth Power",
- "PL": "Earth Power",
"FR": "Telluriforce",
"DE": "Erdkräfte",
"IT": "Geoforza",
@@ -3148,10 +2163,6 @@
"pokemon_move_305": {
"PT-BR": "Martelo Caranguejo",
"EN": "Crabhammer",
- "FI": "Crabhammer",
- "NL": "Crabhammer",
- "NO": "Crabhammer",
- "PL": "Crabhammer",
"FR": "Pince-Masse",
"DE": "Krabbhammer",
"IT": "Martellata",
@@ -3161,10 +2172,6 @@
"pokemon_move_306": {
"PT-BR": "Estocada",
"EN": "Lunge",
- "FI": "Lunge",
- "NL": "Lunge",
- "NO": "Lunge",
- "PL": "Lunge",
"FR": "Furie-Bond",
"DE": "Anfallen",
"IT": "Assalto",
@@ -3174,10 +2181,6 @@
"pokemon_move_307": {
"PT-BR": "Garra Esmagadora",
"EN": "Crush Claw",
- "FI": "Crush Claw",
- "NL": "Crush Claw",
- "NO": "Crush Claw",
- "PL": "Crush Claw",
"FR": "Éclate Griffe",
"DE": "Zermalmklaue",
"IT": "Tritartigli",
@@ -3187,23 +2190,12 @@
"pokemon_move_308": {
"PT-BR": "Polvo-canhão",
"EN": "Octazooka",
- "FI": "Octazooka",
- "NL": "Octazooka",
- "NO": "Octazooka",
- "PL": "Octazooka",
- "FR": "Octazooka",
- "DE": "Octazooka",
- "IT": "Octazooka",
"RU": "Чернильная Пушка",
"ES": "Pulpocañón"
},
"pokemon_move_309": {
"PT-BR": "Tiro no Espelho",
"EN": "Mirror Shot",
- "FI": "Mirror Shot",
- "NL": "Mirror Shot",
- "NO": "Mirror Shot",
- "PL": "Mirror Shot",
"FR": "Miroi-Tir",
"DE": "Spiegelsalve",
"IT": "Cristalcolpo",
@@ -3213,10 +2205,6 @@
"pokemon_move_310": {
"PT-BR": "Superpoder",
"EN": "Superpower",
- "FI": "Superpower",
- "NL": "Superpower",
- "NO": "Superpower",
- "PL": "Superpower",
"FR": "Surpuissance",
"DE": "Kraftkoloss",
"IT": "Troppoforte",
@@ -3226,10 +2214,6 @@
"pokemon_move_311": {
"PT-BR": "Ferrão Letal",
"EN": "Fell Stinger",
- "FI": "Fell Stinger",
- "NL": "Fell Stinger",
- "NO": "Fell Stinger",
- "PL": "Fell Stinger",
"FR": "Dard Mortel",
"DE": "Stachelfinale",
"IT": "Pungiglione",
@@ -3239,10 +2223,6 @@
"pokemon_move_312": {
"PT-BR": "Tornado de Folhas",
"EN": "Leaf Tornado",
- "FI": "Leaf Tornado",
- "NL": "Leaf Tornado",
- "NO": "Leaf Tornado",
- "PL": "Leaf Tornado",
"FR": "Phytomixeur",
"DE": "Grasmixer",
"IT": "Vorticerba",
@@ -3252,10 +2232,6 @@
"pokemon_move_313": {
"PT-BR": "Suga-vidas",
"EN": "Leech Life",
- "FI": "Leech Life",
- "NL": "Leech Life",
- "NO": "Leech Life",
- "PL": "Leech Life",
"FR": "Vampirisme",
"DE": "Blutsauger",
"IT": "Sanguisuga",
@@ -3265,10 +2241,6 @@
"pokemon_move_314": {
"PT-BR": "Soco Dreno",
"EN": "Drain Punch",
- "FI": "Drain Punch",
- "NL": "Drain Punch",
- "NO": "Drain Punch",
- "PL": "Drain Punch",
"FR": "Vampi-Poing",
"DE": "Ableithieb",
"IT": "Assorbipugno",
@@ -3278,10 +2250,6 @@
"pokemon_move_315": {
"PT-BR": "Osso Sombrio",
"EN": "Shadow Bone",
- "FI": "Shadow Bone",
- "NL": "Shadow Bone",
- "NO": "Shadow Bone",
- "PL": "Shadow Bone",
"FR": "Os Ombre",
"DE": "Schattenknochen",
"IT": "Ossotetro",
@@ -3291,10 +2259,6 @@
"pokemon_move_316": {
"PT-BR": "Água Barrenta",
"EN": "Muddy Water",
- "FI": "Muddy Water",
- "NL": "Muddy Water",
- "NO": "Muddy Water",
- "PL": "Muddy Water",
"FR": "Ocroupi",
"DE": "Lehmbrühe",
"IT": "Fanghiglia",
@@ -3304,10 +2268,6 @@
"pokemon_move_317": {
"PT-BR": "Chute Labareda",
"EN": "Blaze Kick",
- "FI": "Blaze Kick",
- "NL": "Blaze Kick",
- "NO": "Blaze Kick",
- "PL": "Blaze Kick",
"FR": "Pied Brûleur",
"DE": "Feuerfeger",
"IT": "Calciardente",
@@ -3317,10 +2277,6 @@
"pokemon_move_318": {
"PT-BR": "Concha Navalha",
"EN": "Razor Shell",
- "FI": "Razor Shell",
- "NL": "Razor Shell",
- "NO": "Razor Shell",
- "PL": "Razor Shell",
"FR": "Coqui-Lame",
"DE": "Kalkklinge",
"IT": "Conchilama",
@@ -3330,10 +2286,6 @@
"pokemon_move_319": {
"PT-BR": "Soco Empoderador",
"EN": "Power-Up Punch",
- "FI": "Power-Up Punch",
- "NL": "Power-Up Punch",
- "NO": "Power-Up Punch",
- "PL": "Power-Up Punch",
"FR": "Poing Boost",
"DE": "Steigerungshieb",
"IT": "Crescipugno",
@@ -3343,10 +2295,6 @@
"pokemon_move_320": {
"PT-BR": "Encantar",
"EN": "Charm",
- "FI": "Charm",
- "NL": "Charm",
- "NO": "Charm",
- "PL": "Charm",
"FR": "Charme",
"DE": "Charme",
"IT": "Fascino",
@@ -3356,25 +2304,14 @@
"pokemon_move_321": {
"PT-BR": "Gigaimpacto",
"EN": "Giga Impact",
- "FI": "Giga Impact",
- "NL": "Giga Impact",
- "NO": "Giga Impact",
- "PL": "Giga Impact",
- "FR": "Giga Impact",
"DE": "Gigastoß",
"IT": "Gigaimpatto",
- "RU": "Гига-Удар",
+ "RU": "Гига-удар",
"ES": "Gigaimpacto"
},
"pokemon_move_322": {
"PT-BR": "Frustração",
"EN": "Frustration",
- "FI": "Frustration",
- "NL": "Frustration",
- "NO": "Frustration",
- "PL": "Frustration",
- "FR": "Frustration",
- "DE": "Frustration",
"IT": "Frustrazione",
"RU": "Фрустрация",
"ES": "Frustración"
@@ -3382,10 +2319,6 @@
"pokemon_move_323": {
"PT-BR": "Retorno",
"EN": "Return",
- "FI": "Return",
- "NL": "Return",
- "NO": "Return",
- "PL": "Return",
"FR": "Retour",
"DE": "Rückkehr",
"IT": "Ritorno",
@@ -3395,10 +2328,6 @@
"pokemon_move_324": {
"PT-BR": "Barulho Sincronizado",
"EN": "Synchronoise",
- "FI": "Synchronoise",
- "NL": "Synchronoise",
- "NO": "Synchronoise",
- "PL": "Synchronoise",
"FR": "Synchropeine",
"DE": "Synchrolärm",
"IT": "Sincrumore",
@@ -3408,10 +2337,6 @@
"pokemon_move_325": {
"PT-BR": "Mirar",
"EN": "Lock-On",
- "FI": "Lock-On",
- "NL": "Lock-On",
- "NO": "Lock-On",
- "PL": "Lock-On",
"FR": "Verrouillage",
"DE": "Zielschuss",
"IT": "Localizza",
@@ -3421,10 +2346,6 @@
"pokemon_move_326": {
"PT-BR": "Presa Trovejante",
"EN": "Thunder Fang",
- "FI": "Thunder Fang",
- "NL": "Thunder Fang",
- "NO": "Thunder Fang",
- "PL": "Thunder Fang",
"FR": "Crocs Éclair",
"DE": "Donnerzahn",
"IT": "Fulmindenti",
@@ -3434,10 +2355,6 @@
"pokemon_move_327": {
"PT-BR": "Presa de Gelo",
"EN": "Ice Fang",
- "FI": "Ice Fang",
- "NL": "Ice Fang",
- "NO": "Ice Fang",
- "PL": "Ice Fang",
"FR": "Crocs Givre",
"DE": "Eiszahn",
"IT": "Gelodenti",
@@ -3447,10 +2364,6 @@
"pokemon_move_328": {
"PT-BR": "Chifre Broca",
"EN": "Horn Drill",
- "FI": "Horn Drill",
- "NL": "Horn Drill",
- "NO": "Horn Drill",
- "PL": "Horn Drill",
"FR": "Empal’Korne",
"DE": "Hornbohrer",
"IT": "Perforcorno",
@@ -3460,10 +2373,6 @@
"pokemon_move_329": {
"PT-BR": "Fissura",
"EN": "Fissure",
- "FI": "Fissure",
- "NL": "Fissure",
- "NO": "Fissure",
- "PL": "Fissure",
"FR": "Abîme",
"DE": "Geofissur",
"IT": "Abisso",
@@ -3473,10 +2382,6 @@
"pokemon_move_330": {
"PT-BR": "Espada Sagrada",
"EN": "Sacred Sword",
- "FI": "Sacred Sword",
- "NL": "Sacred Sword",
- "NO": "Sacred Sword",
- "PL": "Sacred Sword",
"FR": "Lame Sainte",
"DE": "Sanctoklinge",
"IT": "Spadasolenne",
@@ -3486,12 +2391,6 @@
"pokemon_move_331": {
"PT-BR": "Aperto Voador",
"EN": "Flying Press",
- "FI": "Flying Press",
- "NL": "Flying Press",
- "NO": "Flying Press",
- "PL": "Flying Press",
- "FR": "Flying Press",
- "DE": "Flying Press",
"IT": "Schiacciatuffo",
"RU": "Летающий Пресс",
"ES": "Plancha Voladora"
@@ -3499,10 +2398,6 @@
"pokemon_move_332": {
"PT-BR": "Aura Esférica",
"EN": "Aura Sphere",
- "FI": "Aura Sphere",
- "NL": "Aura Sphere",
- "NO": "Aura Sphere",
- "PL": "Aura Sphere",
"FR": "Aurasphère",
"DE": "Aurasphäre",
"IT": "Forzasfera",
@@ -3512,10 +2407,6 @@
"pokemon_move_333": {
"PT-BR": "Revide",
"EN": "Payback",
- "FI": "Payback",
- "NL": "Payback",
- "NO": "Payback",
- "PL": "Payback",
"FR": "Représailles",
"DE": "Gegenstoß",
"IT": "Rivincita",
@@ -3525,10 +2416,6 @@
"pokemon_move_334": {
"PT-BR": "Demolidor de Pedras",
"EN": "Rock Wrecker",
- "FI": "Rock Wrecker",
- "NL": "Rock Wrecker",
- "NO": "Rock Wrecker",
- "PL": "Rock Wrecker",
"FR": "Roc-Boulet",
"DE": "Felswerfer",
"IT": "Devastomasso",
@@ -3538,10 +2425,6 @@
"pokemon_move_335": {
"PT-BR": "Explosão Aérea",
"EN": "Aeroblast",
- "FI": "Aeroblast",
- "NL": "Aeroblast",
- "NO": "Aeroblast",
- "PL": "Aeroblast",
"FR": "Aéroblast",
"DE": "Luftstoß",
"IT": "Aerocolpo",
@@ -3551,10 +2434,6 @@
"pokemon_move_336": {
"PT-BR": "Rajada Tecnológica",
"EN": "Techno Blast",
- "FI": "Techno Blast",
- "NL": "Techno Blast",
- "NO": "Techno Blast",
- "PL": "Techno Blast",
"FR": "Techno-Buster",
"DE": "Techblaster",
"IT": "Tecnobotto",
@@ -3564,10 +2443,6 @@
"pokemon_move_337": {
"PT-BR": "Rajada Tecnológica",
"EN": "Techno Blast",
- "FI": "Techno Blast",
- "NL": "Techno Blast",
- "NO": "Techno Blast",
- "PL": "Techno Blast",
"FR": "Techno-Buster",
"DE": "Techblaster",
"IT": "Tecnobotto",
@@ -3577,10 +2452,6 @@
"pokemon_move_338": {
"PT-BR": "Rajada Tecnológica",
"EN": "Techno Blast",
- "FI": "Techno Blast",
- "NL": "Techno Blast",
- "NO": "Techno Blast",
- "PL": "Techno Blast",
"FR": "Techno-Buster",
"DE": "Techblaster",
"IT": "Tecnobotto",
@@ -3590,10 +2461,6 @@
"pokemon_move_339": {
"PT-BR": "Rajada Tecnológica",
"EN": "Techno Blast",
- "FI": "Techno Blast",
- "NL": "Techno Blast",
- "NO": "Techno Blast",
- "PL": "Techno Blast",
"FR": "Techno-Buster",
"DE": "Techblaster",
"IT": "Tecnobotto",
@@ -3603,10 +2470,6 @@
"pokemon_move_340": {
"PT-BR": "Rajada Tecnológica",
"EN": "Techno Blast",
- "FI": "Techno Blast",
- "NL": "Techno Blast",
- "NO": "Techno Blast",
- "PL": "Techno Blast",
"FR": "Techno-Buster",
"DE": "Techblaster",
"IT": "Tecnobotto",
@@ -3616,10 +2479,6 @@
"pokemon_move_341": {
"PT-BR": "Voar",
"EN": "Fly",
- "FI": "Fly",
- "NL": "Fly",
- "NO": "Fly",
- "PL": "Fly",
"FR": "Vol",
"DE": "Fliegen",
"IT": "Volo",
@@ -3629,10 +2488,6 @@
"pokemon_move_342": {
"PT-BR": "Criação V",
"EN": "V-create",
- "FI": "V-create",
- "NL": "V-create",
- "NO": "V-create",
- "PL": "V-create",
"FR": "Coup Victoire",
"DE": "V-Generator",
"IT": "Generatore V",
@@ -3642,10 +2497,6 @@
"pokemon_move_343": {
"PT-BR": "Tempestade de Folhas",
"EN": "Leaf Storm",
- "FI": "Leaf Storm",
- "NL": "Leaf Storm",
- "NO": "Leaf Storm",
- "PL": "Leaf Storm",
"FR": "Tempête Verte",
"DE": "Blättersturm",
"IT": "Verdebufera",
@@ -3655,10 +2506,6 @@
"pokemon_move_344": {
"PT-BR": "Triataque",
"EN": "Tri Attack",
- "FI": "Tri Attack",
- "NL": "Tri Attack",
- "NO": "Tri Attack",
- "PL": "Tri Attack",
"FR": "Triplattaque",
"DE": "Triplette",
"IT": "Tripletta",
@@ -3668,10 +2515,6 @@
"pokemon_move_345": {
"PT-BR": "Lufada de Vento",
"EN": "Gust",
- "FI": "Gust",
- "NL": "Gust",
- "NO": "Gust",
- "PL": "Gust",
"FR": "Tornade",
"DE": "Windstoß",
"IT": "Raffica",
@@ -3681,36 +2524,45 @@
"pokemon_move_346": {
"PT-BR": "Incinerar",
"EN": "Incinerate",
- "FI": "Incinerate",
- "NL": "Incinerate",
- "NO": "Incinerate",
- "PL": "Incinerate",
"FR": "Calcination",
"DE": "Einäschern",
"IT": "Bruciatutto",
- "RU": " Превращение в Пепел",
+ "RU": "Превращение в Пепел",
"ES": "Calcinación"
},
+ "pokemon_move_347": {
+ "EN": "Dark Void",
+ "RU": "Темная Бездна"
+ },
"pokemon_move_348": {
"PT-BR": "Dança das Penas",
"EN": "Feather Dance",
- "FI": "Feather Dance",
- "NL": "Feather Dance",
- "NO": "Feather Dance",
- "PL": "Feather Dance",
"FR": "Danse Plumes",
"DE": "Daunenreigen",
"IT": "Danzadipiume",
"RU": "Танец с Перьями",
"ES": "Danza Pluma"
},
+ "pokemon_move_349": {
+ "EN": "Fiery Dance",
+ "RU": "Горячий Танец"
+ },
+ "pokemon_move_350": {
+ "PT-BR": "Vento de Fada",
+ "EN": "Fairy Wind",
+ "FR": "Vent Féérique",
+ "DE": "Feenbrise",
+ "IT": "Vento di Fata",
+ "RU": "Ветер Фей",
+ "ES": "Viento Feérico"
+ },
+ "pokemon_move_351": {
+ "EN": "Relic Song",
+ "RU": "Древняя Песня"
+ },
"pokemon_move_352": {
"PT-BR": "Esfera Climática",
"EN": "Weather Ball",
- "FI": "Weather Ball",
- "NL": "Weather Ball",
- "NO": "Weather Ball",
- "PL": "Weather Ball",
"FR": "Ball’Météo",
"DE": "Meteorologe",
"IT": "Palla Clima",
@@ -3720,11 +2572,7 @@
"pokemon_move_353": {
"PT-BR": "Caninos Psíquicos",
"EN": "Psychic Fangs",
- "FI": "Psychic Fangs",
- "NL": "Psychic Fangs",
- "NO": "Psychic Fangs",
- "PL": "Psychic Fangs",
- "FR": "Psychic Fangs",
+ "FR": "Psycho-Croc",
"DE": "Psychobeißer",
"IT": "Psicozanna",
"RU": "Психоклыки",
@@ -3733,10 +2581,6 @@
"pokemon_move_354": {
"PT-BR": "Fúria de Hiperespaço",
"EN": "Hyperspace Fury",
- "FI": "Hyperspace Fury",
- "NL": "Hyperspace Fury",
- "NO": "Hyperspace Fury",
- "PL": "Hyperspace Fury",
"FR": "Furie Dimension",
"DE": "Dimensionswahn",
"IT": "Urtodimensionale",
@@ -3746,23 +2590,24 @@
"pokemon_move_355": {
"PT-BR": "Fenda de Hiperespaço",
"EN": "Hyperspace Hole",
- "FI": "Hyperspace Hole",
- "NL": "Hyperspace Hole",
- "NO": "Hyperspace Hole",
- "PL": "Hyperspace Hole",
"FR": "TrouDimensionnel",
"DE": "Dimensionsloch",
"IT": "Forodimensionale",
"RU": "Гиперпространственная Дыра",
"ES": "Paso Dimensional"
},
+ "pokemon_move_356": {
+ "PT-BR": "Chute Duplo",
+ "EN": "Double Kick",
+ "FR": "Double Pied",
+ "DE": "Doppelkick",
+ "IT": "Doppiocalcio",
+ "RU": "Двойной Пинок",
+ "ES": "Doble Patada"
+ },
"pokemon_move_357": {
"PT-BR": "Folha Mágica",
"EN": "Magical Leaf",
- "FI": "Magical Leaf",
- "NL": "Magical Leaf",
- "NO": "Magical Leaf",
- "PL": "Magical Leaf",
"FR": "Feuille Magik",
"DE": "Zauberblatt",
"IT": "Fogliamagica",
@@ -3772,10 +2617,6 @@
"pokemon_move_358": {
"PT-BR": "Fogo Sagrado",
"EN": "Sacred Fire",
- "FI": "Sacred Fire",
- "NL": "Sacred Fire",
- "NO": "Sacred Fire",
- "PL": "Sacred Fire",
"FR": "Feu Sacré",
"DE": "Läuterfeuer",
"IT": "Magifuoco",
@@ -3785,10 +2626,6 @@
"pokemon_move_359": {
"PT-BR": "Lança Congelada",
"EN": "Icicle Spear",
- "FI": "Icicle Spear",
- "NL": "Icicle Spear",
- "NO": "Icicle Spear",
- "PL": "Icicle Spear",
"FR": "Stalactite",
"DE": "Eisspeer",
"IT": "Gelolancia",
@@ -3798,10 +2635,6 @@
"pokemon_move_360": {
"PT-BR": "Explosão Aérea+",
"EN": "Aeroblast+",
- "FI": "Aeroblast+",
- "NL": "Aeroblast+",
- "NO": "Aeroblast+",
- "PL": "Aeroblast+",
"FR": "Aéroblast+",
"DE": "Luftstoß+",
"IT": "Aerocolpo+",
@@ -3811,10 +2644,6 @@
"pokemon_move_361": {
"PT-BR": "Explosão Aérea++",
"EN": "Aeroblast++",
- "FI": "Aeroblast++",
- "NL": "Aeroblast++",
- "NO": "Aeroblast++",
- "PL": "Aeroblast++",
"FR": "Aéroblast++",
"DE": "Luftstoß++",
"IT": "Aerocolpo++",
@@ -3824,10 +2653,6 @@
"pokemon_move_362": {
"PT-BR": "Fogo Sagrado+",
"EN": "Sacred Fire+",
- "FI": "Sacred Fire+",
- "NL": "Sacred Fire+",
- "NO": "Sacred Fire+",
- "PL": "Sacred Fire+",
"FR": "Feu Sacré+",
"DE": "Läuterfeuer+",
"IT": "Magifuoco+",
@@ -3837,10 +2662,6 @@
"pokemon_move_363": {
"PT-BR": "Fogo Sagrado++",
"EN": "Sacred Fire++",
- "FI": "Sacred Fire++",
- "NL": "Sacred Fire++",
- "NO": "Sacred Fire++",
- "PL": "Sacred Fire++",
"FR": "Feu Sacré++",
"DE": "Läuterfeuer++",
"IT": "Magifuoco++",
@@ -3848,16 +2669,1149 @@
"ES": "Fuego Sagrado++"
},
"pokemon_move_364": {
- "PT-BR": "Acrobatics",
+ "PT-BR": "Acrobático",
"EN": "Acrobatics",
- "FI": "Acrobatics",
- "NL": "Acrobatics",
- "NO": "Acrobatics",
- "PL": "Acrobatics",
- "FR": "Acrobatics",
- "DE": "Acrobatics",
- "IT": "Acrobatics",
+ "FR": "Acrobatie",
+ "DE": "Akrobatik",
+ "IT": "Acrobazia",
"RU": "Акробатика",
- "ES": "Acrobatics"
+ "ES": "Acróbata"
+ },
+ "pokemon_move_365": {
+ "PT-BR": "Purga de Esplendor",
+ "EN": "Luster Purge",
+ "FR": "Lumi-Éclat",
+ "DE": "Scheinwerfer",
+ "IT": "Abbagliante",
+ "RU": "Генеральная Чистка",
+ "ES": "Resplandor"
+ },
+ "pokemon_move_366": {
+ "PT-BR": "Bola de Névoa",
+ "EN": "Mist Ball",
+ "FR": "Ball’Brume",
+ "DE": "Nebelball",
+ "IT": "Foschisfera",
+ "RU": "Шар Тумана",
+ "ES": "Bola Neblina"
+ },
+ "pokemon_move_367": {
+ "PT-BR": "Balanço Violento",
+ "EN": "Brutal Swing",
+ "FR": "Centrifugifle",
+ "DE": "Wirbler",
+ "IT": "Vorticolpo",
+ "RU": "Резкий Поворот",
+ "ES": "Giro Vil"
+ },
+ "pokemon_move_368": {
+ "PT-BR": "Rolagem",
+ "EN": "Rollout",
+ "FR": "Roulade",
+ "DE": "Walzer",
+ "IT": "Rotolamento",
+ "RU": "Перекат",
+ "ES": "Desenrollar"
+ },
+ "pokemon_move_369": {
+ "PT-BR": "Semente Ofuscante",
+ "EN": "Seed Flare",
+ "FR": "Fulmigraine",
+ "DE": "Schocksamen",
+ "IT": "Infuriaseme",
+ "RU": "Сияние Семени",
+ "ES": "Fogonazo"
+ },
+ "pokemon_move_370": {
+ "PT-BR": "Obstruir",
+ "EN": "Obstruct",
+ "FR": "Blocage",
+ "DE": "Abblocker",
+ "IT": "Sbarramento",
+ "RU": "Преграда",
+ "ES": "Obstrucción"
+ },
+ "pokemon_move_371": {
+ "PT-BR": "Força das Sombras",
+ "EN": "Shadow Force",
+ "FR": "Revenant",
+ "DE": "Schemenkraft",
+ "IT": "Oscurotuffo",
+ "RU": "Сумеречная Сила",
+ "ES": "Golpe Umbrío"
+ },
+ "pokemon_move_372": {
+ "PT-BR": "Raio Meteórico",
+ "EN": "Meteor Beam",
+ "FR": "Laser Météore",
+ "DE": "Meteorstrahl",
+ "IT": "Raggiometeora",
+ "RU": "Метеоритный Луч",
+ "ES": "Rayo Meteórico"
+ },
+ "pokemon_move_373": {
+ "PT-BR": "Estrela Ninja de Água",
+ "EN": "Water Shuriken",
+ "FR": "Sheauriken",
+ "DE": "Wasser-Shuriken",
+ "IT": "Acqualame",
+ "RU": "Водяной Сюрикен",
+ "ES": "Shuriken de Agua"
+ },
+ "pokemon_move_374": {
+ "PT-BR": "Raio de Fusão",
+ "EN": "Fusion Bolt",
+ "FR": "Éclair Croix",
+ "DE": "Kreuzdonner",
+ "IT": "Incrotuono",
+ "RU": "Термоядерный Разряд",
+ "ES": "Rayo Fusión"
+ },
+ "pokemon_move_375": {
+ "PT-BR": "Chama da Fusão",
+ "EN": "Fusion Flare",
+ "FR": "Flamme Croix",
+ "DE": "Kreuzflamme",
+ "IT": "Incrofiamma",
+ "RU": "Ядерная Вспышка",
+ "ES": "Llama Fusión"
+ },
+ "pokemon_move_376": {
+ "EN": "Poltergeist",
+ "FR": "Esprit Frappeur",
+ "RU": "Полтергейст"
+ },
+ "pokemon_move_377": {
+ "PT-BR": "Potência Equina",
+ "EN": "High Horsepower",
+ "FR": "Cavalerie Lourde",
+ "DE": "Pferdestärke",
+ "IT": "Forza Equina",
+ "RU": "Лошадиная Сила",
+ "ES": "Fuerza Equina"
+ },
+ "pokemon_move_378": {
+ "PT-BR": "Glaciar",
+ "EN": "Glaciate",
+ "FR": "Ère Glaciaire",
+ "DE": "Eiszeit",
+ "IT": "Gelamondo",
+ "RU": "Замораживание",
+ "ES": "Mundo Gélido"
+ },
+ "pokemon_move_379": {
+ "PT-BR": "Golpe Deslizante",
+ "EN": "Breaking Swipe",
+ "FR": "Abattage",
+ "DE": "Breitseite",
+ "IT": "Vastoimpatto",
+ "RU": "Разбивающий Удар",
+ "ES": "Vasto Impacto"
+ },
+ "pokemon_move_380": {
+ "PT-BR": "Rajada Explosiva",
+ "EN": "Boomburst",
+ "FR": "Bang Sonique",
+ "DE": "Überschallknall",
+ "IT": "Ondaboato",
+ "RU": "Громкий Взрыв",
+ "ES": "Estruendo"
+ },
+ "pokemon_move_381": {
+ "PT-BR": "Pancada de Ferro Dupla",
+ "EN": "Double Iron Bash",
+ "FR": "Écrous d’Poing",
+ "DE": "Panzerfäuste",
+ "IT": "Pugni Corazzati",
+ "RU": "Двойной Стальной Таран",
+ "ES": "Ferropuño Doble"
+ },
+ "pokemon_move_382": {
+ "PT-BR": "Fogo Místico",
+ "EN": "Mystical Fire",
+ "FR": "Feu Ensorcelé",
+ "DE": "Magieflamme",
+ "IT": "Magifiamma",
+ "RU": "Мистический Огонь",
+ "ES": "Llama Embrujada"
+ },
+ "pokemon_move_383": {
+ "PT-BR": "Aquaríete",
+ "EN": "Liquidation",
+ "FR": "Aqua-Brèche",
+ "DE": "Aquadurchstoß",
+ "IT": "Idrobreccia",
+ "RU": "Ликвидация",
+ "ES": "Hidroariete"
+ },
+ "pokemon_move_384": {
+ "PT-BR": "Ascenção do Dragão",
+ "EN": "Dragon Ascent",
+ "FR": "Draco Ascension",
+ "DE": "Zenitstürmer",
+ "IT": "Ascesa del Drago",
+ "RU": "Взлёт Дракона",
+ "ES": "Ascenso Draco"
+ },
+ "pokemon_move_385": {
+ "PT-BR": "Folhagem",
+ "EN": "Leafage",
+ "FR": "Feuillage",
+ "DE": "Blattwerk",
+ "IT": "Fogliame",
+ "RU": "Облиствление",
+ "ES": "Follaje"
+ },
+ "pokemon_move_386": {
+ "PT-BR": "Tempestade de Magma",
+ "EN": "Magma Storm",
+ "FR": "Vortex Magma",
+ "DE": "Lavasturm",
+ "IT": "Magmaclisma",
+ "RU": "Магма-Буря",
+ "ES": "Lluvia Ígnea"
+ },
+ "pokemon_move_387": {
+ "PT-BR": "Geomancia",
+ "EN": "Geomancy",
+ "FR": "Géo-Contrôle",
+ "DE": "Geokontrolle",
+ "IT": "Geocontrollo",
+ "RU": "Геомантия",
+ "ES": "Geocontrol"
+ },
+ "pokemon_move_388": {
+ "PT-BR": "Laceração Espacial",
+ "EN": "Spacial Rend",
+ "FR": "Spatio-Rift",
+ "DE": "Raumschlag",
+ "IT": "Fendispazio",
+ "RU": "Пространственный Разрыв",
+ "ES": "Corte Vacío"
+ },
+ "pokemon_move_389": {
+ "PT-BR": "Asa do Esquecimento",
+ "EN": "Oblivion Wing",
+ "FR": "Mort-Ailes",
+ "DE": "Unheilsschwingen",
+ "IT": "Ali del Fato",
+ "RU": "Крылья Забвения",
+ "ES": "Ala Mortífera"
+ },
+ "pokemon_move_390": {
+ "PT-BR": "Ira da Natureza",
+ "EN": "Nature’s Madness",
+ "FR": "Ire de la Nature",
+ "DE": "Naturzorn",
+ "IT": "Ira della Natura",
+ "RU": "Безумие Природы",
+ "ES": "Furia Natural"
+ },
+ "pokemon_move_391": {
+ "PT-BR": "Pinote Triplo",
+ "EN": "Triple Axel",
+ "DE": "Dreifach-Axel",
+ "IT": "Triplo Axel",
+ "RU": "Тройной Аксель"
+ },
+ "pokemon_move_392": {
+ "PT-BR": "Desbravar",
+ "EN": "Trailblaze",
+ "FR": "Désherbaffe",
+ "DE": "Wegbereiter",
+ "IT": "Apripista",
+ "RU": "Новый Путь",
+ "ES": "Abrecaminos"
+ },
+ "pokemon_move_393": {
+ "PT-BR": "Areias Ardentes",
+ "EN": "Scorching Sands",
+ "FR": "Sable Ardent",
+ "DE": "Brandsand",
+ "IT": "Sabbiardente",
+ "RU": "Раскалённый Песок",
+ "ES": "Arenas Ardientes"
+ },
+ "pokemon_move_394": {
+ "PT-BR": "Rugido do Tempo",
+ "EN": "Roar of Time",
+ "FR": "Hurle-Temps",
+ "DE": "Zeitenlärm",
+ "IT": "Fragortempo",
+ "RU": "Рёв Времени",
+ "ES": "Distorsión"
+ },
+ "pokemon_move_395": {
+ "PT-BR": "Tempestade Álgida",
+ "EN": "Bleakwind Storm",
+ "FR": "Typhon Hivernal",
+ "DE": "Polarorkan",
+ "IT": "Tempesta Boreale",
+ "RU": "Ледяная Буря",
+ "ES": "Vendaval Gélido"
+ },
+ "pokemon_move_396": {
+ "PT-BR": "Tempestade Saibrosa",
+ "EN": "Sandsear Storm",
+ "FR": "Typhon Pyrosable",
+ "DE": "Wüstenorkan",
+ "IT": "Tempesta Ardente",
+ "RU": "Обжигающая Буря",
+ "ES": "Simún de Arena"
+ },
+ "pokemon_move_397": {
+ "PT-BR": "Tempestade Chocante",
+ "EN": "Wildbolt Storm",
+ "FR": "Typhon Fulgurant",
+ "DE": "Donnerorkan",
+ "IT": "Tempesta Tonante",
+ "RU": "Громовая Буря",
+ "ES": "Electormenta"
+ },
+ "pokemon_move_398": {
+ "PT-BR": "Manilha Sombria",
+ "EN": "Spirit Shackle",
+ "FR": "Tisse Ombre",
+ "DE": "Schattenfessel",
+ "IT": "Cucitura d’Ombra",
+ "RU": "Спиритические Оковы",
+ "ES": "Puntada Sombría"
+ },
+ "pokemon_move_399": {
+ "PT-BR": "Investida Trovão",
+ "EN": "Volt Tackle",
+ "FR": "Électacle",
+ "DE": "Volttackle",
+ "IT": "Locomovolt",
+ "RU": "Вольт-Бросок",
+ "ES": "Placaje Eléctrico"
+ },
+ "pokemon_move_400": {
+ "PT-BR": "Lariat Escuro",
+ "EN": "Darkest Lariat",
+ "FR": "Dark Lariat",
+ "DE": "Dark Lariat",
+ "IT": "Braccioteso",
+ "RU": "Тёмное Лассо",
+ "ES": "Lariat Oscuro"
+ },
+ "pokemon_move_401": {
+ "PT-BR": "Onda Psíquica",
+ "EN": "Psywave",
+ "FR": "Vague Psy",
+ "DE": "Psywelle",
+ "IT": "Psiconda",
+ "RU": "Психоволны",
+ "ES": "Psicoonda"
+ },
+ "pokemon_move_402": {
+ "PT-BR": "Som de Metal",
+ "EN": "Metal Sound",
+ "FR": "Strido-Son",
+ "DE": "Metallsound",
+ "IT": "Ferrostrido",
+ "RU": "Металлический Звук",
+ "ES": "Eco Metálico"
+ },
+ "pokemon_move_403": {
+ "PT-BR": "Ataque de Areia",
+ "EN": "Sand Attack",
+ "FR": "Jet de Sable",
+ "DE": "Sandwirbel",
+ "IT": "Turbosabbia",
+ "RU": "Песчаная Атака",
+ "ES": "Ataque Arena"
+ },
+ "pokemon_move_404": {
+ "PT-BR": "Ataque Solaraço",
+ "EN": "Sunsteel Strike",
+ "FR": "Choc Météore",
+ "DE": "Stahlgestirn",
+ "IT": "Astrocarica",
+ "RU": "Солнечно-Стальной Удар",
+ "ES": "Meteoimpacto"
+ },
+ "pokemon_move_405": {
+ "PT-BR": "Feixe Espectral",
+ "EN": "Moongeist Beam",
+ "FR": "Rayon Spectral",
+ "DE": "Schattenstrahl",
+ "IT": "Raggio d’Ombra",
+ "RU": "Луч Лунного Духа",
+ "ES": "Rayo Umbrío"
+ },
+ "pokemon_move_406": {
+ "PT-BR": "Roda de Aura",
+ "EN": "Aura Wheel",
+ "FR": "Roue Libre",
+ "DE": "Aura-Rad",
+ "IT": "Ruota d’Aura",
+ "RU": "Колесо Ауры",
+ "ES": "Rueda Aural"
+ },
+ "pokemon_move_407": {
+ "PT-BR": "Roda de Aura",
+ "EN": "Aura Wheel",
+ "FR": "Roue Libre",
+ "DE": "Aura-Rad",
+ "IT": "Ruota d’Aura",
+ "RU": "Колесо Ауры",
+ "ES": "Rueda Aural"
+ },
+ "pokemon_move_408": {
+ "PT-BR": "Chute de Pulo Alto",
+ "EN": "High Jump Kick",
+ "FR": "Pied Voltige",
+ "DE": "Turmkick",
+ "IT": "Calcinvolo",
+ "RU": "Прыжок-Удар",
+ "ES": "Patada Salto Alta"
+ },
+ "pokemon_move_409": {
+ "PT-BR": "Chama Max",
+ "EN": "Max Flare",
+ "FR": "Pyromax",
+ "DE": "Dyna-Brand",
+ "IT": "Dynafiammata",
+ "RU": "Вспышка Макс",
+ "ES": "Maxignición"
+ },
+ "pokemon_move_410": {
+ "PT-BR": "Nuvem de Inseto Max",
+ "EN": "Max Flutterby",
+ "FR": "Insectomax",
+ "DE": "Dyna-Schwarm",
+ "IT": "Dynainsetto",
+ "RU": "Бабочка Макс",
+ "ES": "Maxinsecto"
+ },
+ "pokemon_move_411": {
+ "PT-BR": "Raio Max",
+ "EN": "Max Lightning",
+ "FR": "Fulguromax",
+ "DE": "Dyna-Gewitter",
+ "IT": "Dynasaetta",
+ "RU": "Молния Макс",
+ "ES": "Maxitormenta"
+ },
+ "pokemon_move_412": {
+ "PT-BR": "Golpe Max",
+ "EN": "Max Strike",
+ "FR": "Normalomax",
+ "DE": "Dyna-Angriff",
+ "IT": "Dynattacco",
+ "RU": "Удар Макс",
+ "ES": "Maxiataque"
+ },
+ "pokemon_move_413": {
+ "PT-BR": "Punho Max",
+ "EN": "Max Knuckle",
+ "FR": "Pugilomax",
+ "DE": "Dyna-Faust",
+ "IT": "Dynapugno",
+ "RU": "Кулак Макс",
+ "ES": "Maxipuño"
+ },
+ "pokemon_move_414": {
+ "PT-BR": "Espectro Max",
+ "EN": "Max Phantasm",
+ "FR": "Spectromax",
+ "DE": "Dyna-Spuk",
+ "IT": "Dynavuoto",
+ "RU": "Иллюзия Макс",
+ "ES": "Maxiespectro"
+ },
+ "pokemon_move_415": {
+ "PT-BR": "Temporal de Granizo Max",
+ "EN": "Max Hailstorm",
+ "FR": "Cryomax",
+ "DE": "Dyna-Frost",
+ "IT": "Dynagelo",
+ "RU": "Град Макс",
+ "ES": "Maxihelada"
+ },
+ "pokemon_move_416": {
+ "PT-BR": "Corrosão Max",
+ "EN": "Max Ooze",
+ "FR": "Toxinomax",
+ "DE": "Dyna-Giftschwall",
+ "IT": "Dynacorrosione",
+ "RU": "Токсины Макс",
+ "ES": "Maxiácido"
+ },
+ "pokemon_move_417": {
+ "PT-BR": "Gêiser Max",
+ "EN": "Max Geyser",
+ "FR": "Hydromax",
+ "DE": "Dyna-Flut",
+ "IT": "Dynaflusso",
+ "RU": "Гейзер Макс",
+ "ES": "Maxichorro"
+ },
+ "pokemon_move_418": {
+ "PT-BR": "Corrente de Ar Max",
+ "EN": "Max Airstream",
+ "FR": "Aéromax",
+ "DE": "Dyna-Düse",
+ "IT": "Dynajet",
+ "RU": "Вихрь Макс",
+ "ES": "Maxiciclón"
+ },
+ "pokemon_move_419": {
+ "PT-BR": "Queda Estelar Max",
+ "EN": "Max Starfall",
+ "FR": "Enchantomax",
+ "DE": "Dyna-Zauber",
+ "IT": "Dynafata",
+ "RU": "Волшебство Макс",
+ "ES": "Maxiestela"
+ },
+ "pokemon_move_420": {
+ "PT-BR": "Bafo Dracônico Max",
+ "EN": "Max Wyrmwind",
+ "FR": "Dracomax",
+ "DE": "Dyna-Wyrm",
+ "IT": "Dynadragone",
+ "RU": "Дракон Макс",
+ "ES": "Maxidraco"
+ },
+ "pokemon_move_421": {
+ "PT-BR": "Tempestade Mental Max",
+ "EN": "Max Mindstorm",
+ "FR": "Psychomax",
+ "DE": "Dyna-Kinese",
+ "IT": "Dynapsiche",
+ "RU": "Психокинез Макс",
+ "ES": "Maxionda"
+ },
+ "pokemon_move_422": {
+ "PT-BR": "Desabamento Max",
+ "EN": "Max Rockfall",
+ "FR": "Lithomax",
+ "DE": "Dyna-Brocken",
+ "IT": "Dynamacigno",
+ "RU": "Камнепад Макс",
+ "ES": "Maxilito"
+ },
+ "pokemon_move_423": {
+ "PT-BR": "Oscilação Max",
+ "EN": "Max Quake",
+ "FR": "Sismomax",
+ "DE": "Dyna-Erdstoß",
+ "IT": "Dynasisma",
+ "RU": "Землетрясение Макс",
+ "ES": "Maxitemblor"
+ },
+ "pokemon_move_424": {
+ "PT-BR": "Escuridão Max",
+ "EN": "Max Darkness",
+ "FR": "Sinistromax",
+ "DE": "Dyna-Dunkel",
+ "IT": "Dynatenebre",
+ "RU": "Темнота Макс",
+ "ES": "Maxisombra"
+ },
+ "pokemon_move_425": {
+ "PT-BR": "Flora Max",
+ "EN": "Max Overgrowth",
+ "FR": "Phytomax",
+ "DE": "Dyna-Flora",
+ "IT": "Dynaflora",
+ "RU": "Рост Макс",
+ "ES": "Maxiflora"
+ },
+ "pokemon_move_426": {
+ "PT-BR": "Espinho de Aço Max",
+ "EN": "Max Steelspike",
+ "FR": "Métallomax",
+ "DE": "Dyna-Stahlzacken",
+ "IT": "Dynametallo",
+ "RU": "Остриё Макс",
+ "ES": "Maximetal"
+ },
+ "pokemon_move_427": {
+ "PT-BR": "Queimada G-Max",
+ "EN": "G-Max Wildfire",
+ "FR": "Fournaise G-Max",
+ "DE": "Giga-Feuerflug",
+ "IT": "Gigavampa",
+ "RU": "Лесной Пожар G-Макс",
+ "ES": "Gigallamarada"
+ },
+ "pokemon_move_428": {
+ "PT-BR": "Perturbação G-Max",
+ "EN": "G-Max Befuddle",
+ "FR": "Illusion G-Max",
+ "DE": "Giga-Benebelung",
+ "IT": "Gigastupore",
+ "RU": "Одурманивание G-Макс",
+ "ES": "Gigaestupor"
+ },
+ "pokemon_move_429": {
+ "PT-BR": "Trovoada G-Max",
+ "EN": "G-Max Volt Crash",
+ "FR": "Foudre G-Max",
+ "DE": "Giga-Blitzhagel",
+ "IT": "Gigapikafolgori",
+ "RU": "Вольт-Таран G-Макс",
+ "ES": "Gigatronada"
+ },
+ "pokemon_move_430": {
+ "PT-BR": "Corrida do Ouro G-Max",
+ "EN": "G-Max Gold Rush",
+ "FR": "Pactole G-Max",
+ "DE": "Giga-Münzregen",
+ "IT": "Gigamonete",
+ "RU": "Золотая Лихорадка G-Макс",
+ "ES": "Gigamonedas"
+ },
+ "pokemon_move_431": {
+ "PT-BR": "Golpe Chi G-Max",
+ "EN": "G-Max Chi Strike",
+ "FR": "Frappe G-Max",
+ "DE": "Giga-Fokusschlag",
+ "IT": "Gigapugnointuito",
+ "RU": "Кулак G-Макс",
+ "ES": "Gigapuñición"
+ },
+ "pokemon_move_432": {
+ "PT-BR": "Terror G-Max",
+ "EN": "G-Max Terror",
+ "FR": "Hantise G-Max",
+ "DE": "Giga-Spuksperre",
+ "IT": "Gigaillusione",
+ "RU": "Ужас G-Макс",
+ "ES": "Gigaaparición"
+ },
+ "pokemon_move_433": {
+ "PT-BR": "Explosão de Espuma G-Max",
+ "EN": "G-Max Foam Burst",
+ "FR": "Bulles G-Max",
+ "DE": "Giga-Schaumbad",
+ "IT": "Gigaschiuma",
+ "RU": "Пена G-Макс",
+ "ES": "Gigaespuma"
+ },
+ "pokemon_move_434": {
+ "PT-BR": "Ressonância G-Max",
+ "EN": "G-Max Resonance",
+ "FR": "Résonance G-Max",
+ "DE": "Giga-Melodie",
+ "IT": "Gigamelodia",
+ "RU": "Мелодия G-Макс",
+ "ES": "Gigamelodía"
+ },
+ "pokemon_move_435": {
+ "PT-BR": "Ternura G-Max",
+ "EN": "G-Max Cuddle",
+ "FR": "Câlin G-Max",
+ "DE": "Giga-Gekuschel",
+ "IT": "Gigabbraccio",
+ "RU": "Обнимашки G-Макс",
+ "ES": "Gigaternura"
+ },
+ "pokemon_move_436": {
+ "PT-BR": "Reabastecer G-Max",
+ "EN": "G-Max Replenish",
+ "FR": "Récolte G-Max",
+ "DE": "Giga-Recycling",
+ "IT": "Gigarinnovamento",
+ "RU": "Пополнение Запаса G-Макс",
+ "ES": "Gigarreciclaje"
+ },
+ "pokemon_move_437": {
+ "PT-BR": "Pestilência G-Max",
+ "EN": "G-Max Malodor",
+ "FR": "Pestilence G-Max",
+ "DE": "Giga-Gestank",
+ "IT": "Gigafetore",
+ "RU": "Зловоние G-Макс",
+ "ES": "Gigapestilencia"
+ },
+ "pokemon_move_438": {
+ "PT-BR": "Derretimento G-Max",
+ "EN": "G-Max Meltdown",
+ "FR": "Fonte G-Max",
+ "DE": "Giga-Schmelze",
+ "IT": "Gigaliquefazione",
+ "RU": "Разрушение G-Макс",
+ "ES": "Gigafundido"
+ },
+ "pokemon_move_439": {
+ "PT-BR": "Intempérie G-Max",
+ "EN": "G-Max Wind Rage",
+ "FR": "Rafale G-Max",
+ "DE": "Giga-Sturmstoß",
+ "IT": "Gigaciclone",
+ "RU": "Ярость Ветра G-Макс",
+ "ES": "Gigahuracán"
+ },
+ "pokemon_move_440": {
+ "PT-BR": "Seriedade G-Max",
+ "EN": "G-Max Gravitas",
+ "FR": "Ondes G-Max",
+ "DE": "Giga-Astrowellen",
+ "IT": "Gigagravitoforza",
+ "RU": "Сила Тяжести G-Макс",
+ "ES": "Gigabóveda"
+ },
+ "pokemon_move_441": {
+ "PT-BR": "Enxurrada de Rochas",
+ "EN": "G-Max Stonesurge",
+ "FR": "Récif G-Max",
+ "DE": "Giga-Geröll",
+ "IT": "Gigarocciagetto",
+ "RU": "Каменный Импульс G-Макс",
+ "ES": "Gigatrampa Rocas"
+ },
+ "pokemon_move_442": {
+ "PT-BR": "Rocha Vulcânica G-Max",
+ "EN": "G-Max Volcalith",
+ "FR": "Téphra G-Max",
+ "DE": "Giga-Schlacke",
+ "IT": "Gigalapilli",
+ "RU": "Вулкалит G-Макс",
+ "ES": "Gigarroca Ígnea"
+ },
+ "pokemon_move_443": {
+ "PT-BR": "Acidez G-Max",
+ "EN": "G-Max Tartness",
+ "FR": "Corrosion G-Max",
+ "DE": "Giga-Säureguss",
+ "IT": "Gigattaccoacido",
+ "RU": "Кислотность G-Макс",
+ "ES": "Gigacorrosión"
+ },
+ "pokemon_move_444": {
+ "PT-BR": "Néctar G-Max",
+ "EN": "G-Max Sweetness",
+ "FR": "Nectar G-Max",
+ "DE": "Giga-Nektarflut",
+ "IT": "Gigambrosia",
+ "RU": "Сладость G-Макс",
+ "ES": "Giganéctar"
+ },
+ "pokemon_move_445": {
+ "PT-BR": "Jorro de Areia G-Max",
+ "EN": "G-Max Sandblast",
+ "FR": "Enlisement G-Max",
+ "DE": "Giga-Sandstoß",
+ "IT": "Gigavortisabbia",
+ "RU": "Песчаная Струя G-Макс",
+ "ES": "Gigapolvareda"
+ },
+ "pokemon_move_446": {
+ "PT-BR": "Eletrocutar G-Max",
+ "EN": "G-Max Stun Shock",
+ "FR": "Choc G-Max",
+ "DE": "Giga-Voltschlag",
+ "IT": "Gigatoxiscossa",
+ "RU": "Ошеломление G-Макс",
+ "ES": "Gigadescarga"
+ },
+ "pokemon_move_447": {
+ "PT-BR": "Centiferno G-Max",
+ "EN": "G-Max Centiferno",
+ "FR": "Combustion G-Max",
+ "DE": "Giga-Feuerkessel",
+ "IT": "Gigamillefiamme",
+ "RU": "Сентиферно G-Макс",
+ "ES": "Gigacienfuegos"
+ },
+ "pokemon_move_448": {
+ "PT-BR": "Castigo G-Max",
+ "EN": "G-Max Smite",
+ "FR": "Sentence G-Max",
+ "DE": "Giga-Sanktion",
+ "IT": "Gigacastigo",
+ "RU": "Наказание G-Макс",
+ "ES": "Gigacastigo"
+ },
+ "pokemon_move_449": {
+ "PT-BR": "Cochilo G-Max",
+ "EN": "G-Max Snooze",
+ "FR": "Torpeur G-Max",
+ "DE": "Giga-Gähnzwang",
+ "IT": "Gigatorpore",
+ "RU": "Дрёма G-Макс",
+ "ES": "Gigasopor"
+ },
+ "pokemon_move_450": {
+ "PT-BR": "Grande Final G-Max",
+ "EN": "G-Max Finale",
+ "FR": "Cure G-Max",
+ "DE": "Giga-Lichtblick",
+ "IT": "Gigagranfinale",
+ "RU": "Финал G-Макс",
+ "ES": "Gigacolofón"
+ },
+ "pokemon_move_451": {
+ "PT-BR": "Enxurrada de Aço G-Max",
+ "EN": "G-Max Steelsurge",
+ "FR": "Percée G-Max",
+ "DE": "Giga-Stahlschlag",
+ "IT": "Gigaferroaculei",
+ "RU": "Стальные Шипы G-Макс",
+ "ES": "Gigatrampa Acero"
+ },
+ "pokemon_move_452": {
+ "PT-BR": "Esgotamento G-Max",
+ "EN": "G-Max Depletion",
+ "FR": "Usure G-Max",
+ "DE": "Giga-Dämpfer",
+ "IT": "Gigalogoramento",
+ "RU": "Опустошение G-Макс",
+ "ES": "Gigadesgaste"
+ },
+ "pokemon_move_453": {
+ "PT-BR": "Chicotada G-Max",
+ "EN": "G-Max Vine Lash",
+ "FR": "Fouet G-Max",
+ "DE": "Giga-Geißel",
+ "IT": "Gigasferzata",
+ "RU": "Удар Лозами G-Макс",
+ "ES": "Gigalianas"
+ },
+ "pokemon_move_454": {
+ "PT-BR": "Bombardeamento G-Max",
+ "EN": "G-Max Cannonade",
+ "FR": "Canonnade G-Max",
+ "DE": "Giga-Beschuss",
+ "IT": "Gigacannonata",
+ "RU": "Канонада G-Макс",
+ "ES": "Gigacañonazo"
+ },
+ "pokemon_move_455": {
+ "PT-BR": "Solo de Tambores G-Max",
+ "EN": "G-Max Drum Solo",
+ "FR": "Percussion G-Max",
+ "DE": "Giga-Getrommel",
+ "IT": "Gigarullio",
+ "RU": "Соло на Барабанах G-Макс",
+ "ES": "Gigarredoble"
+ },
+ "pokemon_move_456": {
+ "PT-BR": "Bola de Chamas G-Max",
+ "EN": "G-Max Fireball",
+ "FR": "Pyroball G-Max",
+ "DE": "Giga-Brandball",
+ "IT": "Gigafiammopalla",
+ "RU": "Огненный Шар G-Макс",
+ "ES": "Gigaesfera Ígnea"
+ },
+ "pokemon_move_457": {
+ "PT-BR": "Hidroatirador G-Max",
+ "EN": "G-Max Hydrosnipe",
+ "FR": "Gâchette G-Max",
+ "DE": "Giga-Schütze",
+ "IT": "Gigasparomirato",
+ "RU": "Гидроснайпер G-Макс",
+ "ES": "Gigadisparo"
+ },
+ "pokemon_move_458": {
+ "PT-BR": "Golpe Único G-Max",
+ "EN": "G-Max One Blow",
+ "FR": "Coup Final G-Max",
+ "DE": "Giga-Einzelhieb",
+ "IT": "Gigasingolcolpo",
+ "RU": "Единый Удар G-Макс",
+ "ES": "Gigagolpe Brusco"
+ },
+ "pokemon_move_459": {
+ "PT-BR": "Fluxo Veloz G-Max",
+ "EN": "G-Max Rapid Flow",
+ "FR": "Multicoup G-Max",
+ "DE": "Giga-Multihieb",
+ "IT": "Gigapluricolpo",
+ "RU": "Серийный Поток G-Макс",
+ "ES": "Gigagolpe Fluido"
+ },
+ "pokemon_move_460": {
+ "EN": "Vn Bm 052"
+ },
+ "pokemon_move_461": {
+ "EN": "Vn Bm 053"
+ },
+ "pokemon_move_462": {
+ "PT-BR": "Palma da Força",
+ "EN": "Force Palm",
+ "FR": "Forte-Paume",
+ "DE": "Kraftwelle",
+ "IT": "Palmoforza",
+ "RU": "Сильная Ладонь",
+ "ES": "Palmeo"
+ },
+ "pokemon_move_463": {
+ "PT-BR": "Aria Cintilante",
+ "EN": "Sparkling Aria",
+ "FR": "Aria de l’Écume",
+ "DE": "Schaumserenade",
+ "IT": "Canto Effimero",
+ "RU": "Искрящаяся Ария",
+ "ES": "Aria Burbuja"
+ },
+ "pokemon_move_464": {
+ "PT-BR": "Punho Feroz",
+ "EN": "Rage Fist",
+ "FR": "Poing de Colère",
+ "DE": "Zornesfaust",
+ "IT": "Pugno Furibondo",
+ "RU": "Кулак Ярости",
+ "ES": "Puño Furia"
+ },
+ "pokemon_move_465": {
+ "PT-BR": "Truque Floral",
+ "EN": "Flower Trick",
+ "FR": "Magie Florale",
+ "DE": "Blumentrick",
+ "IT": "Prestigiafiore",
+ "RU": "Цветочный Фокус",
+ "ES": "Truco Floral"
+ },
+ "pokemon_move_466": {
+ "PT-BR": "Choque Congelante",
+ "EN": "Freeze Shock",
+ "FR": "Éclair Gelé",
+ "DE": "Frostvolt",
+ "IT": "Elettrogelo",
+ "RU": "Холодовой Удар",
+ "ES": "Rayo Gélido"
+ },
+ "pokemon_move_467": {
+ "PT-BR": "Queimadura de Gelo",
+ "EN": "Ice Burn",
+ "FR": "Feu Glacé",
+ "DE": "Frosthauch",
+ "IT": "Vampagelida",
+ "RU": "Ледяной Ожог",
+ "ES": "Llama Gélida"
+ },
+ "pokemon_move_468": {
+ "PT-BR": "Canção Ardente",
+ "EN": "Torch Song",
+ "FR": "Chant Flamboyant",
+ "DE": "Loderlied",
+ "IT": "Canzone Ardente",
+ "RU": "Пение Пламени",
+ "ES": "Canto Ardiente"
+ },
+ "pokemon_move_469": {
+ "PT-BR": "Espada Colossal",
+ "EN": "Behemoth Blade",
+ "FR": "Gladius Maximus",
+ "DE": "Gigantenhieb",
+ "IT": "Taglio Maestoso",
+ "RU": "Меч Левиафана",
+ "ES": "Tajo Supremo"
+ },
+ "pokemon_move_470": {
+ "PT-BR": "Pancada Colossal",
+ "EN": "Behemoth Bash",
+ "FR": "Aegis Maxima",
+ "DE": "Gigantenstoß",
+ "IT": "Colpo Maestoso",
+ "RU": "Удар Левиафана",
+ "ES": "Embate Supremo"
+ },
+ "pokemon_move_471": {
+ "PT-BR": "Supermão",
+ "EN": "Upper Hand",
+ "FR": "Prio-Parade",
+ "DE": "Schnellkonter",
+ "IT": "Colpo di Mano",
+ "RU": "Ручной Выстрел",
+ "ES": "Palma Rauda"
+ },
+ "pokemon_move_472": {
+ "PT-BR": "Prisão Elétrica",
+ "EN": "Thunder Cage",
+ "FR": "Voltageôle",
+ "DE": "Blitzgefängnis",
+ "IT": "Elettrogabbia",
+ "RU": "Громовая Клетка",
+ "ES": "Electrojaula"
+ },
+ "pokemon_move_473": {
+ "PT-BR": "Indefeso",
+ "EN": "Guard",
+ "FR": "Garde",
+ "DE": "Wall",
+ "IT": "Barriera",
+ "RU": "Защита",
+ "ES": "Barrera"
+ },
+ "pokemon_move_474": {
+ "PT-BR": "Espírito",
+ "EN": "Spirit",
+ "FR": "Régé",
+ "DE": "Kampfgeist",
+ "IT": "Spirito",
+ "RU": "Дух",
+ "ES": "Espíritu"
+ },
+ "pokemon_move_475": {
+ "PT-BR": "Indefeso",
+ "EN": "Guard",
+ "FR": "Garde",
+ "DE": "Wall",
+ "IT": "Barriera",
+ "RU": "Защита",
+ "ES": "Barrera"
+ },
+ "pokemon_move_476": {
+ "PT-BR": "Espírito",
+ "EN": "Spirit",
+ "FR": "Régé",
+ "DE": "Kampfgeist",
+ "IT": "Spirito",
+ "RU": "Дух",
+ "ES": "Espíritu"
+ },
+ "pokemon_move_477": {
+ "PT-BR": "Indefeso",
+ "EN": "Guard",
+ "FR": "Garde",
+ "DE": "Wall",
+ "IT": "Barriera",
+ "RU": "Защита",
+ "ES": "Barrera"
+ },
+ "pokemon_move_478": {
+ "PT-BR": "Espírito",
+ "EN": "Spirit",
+ "FR": "Régé",
+ "DE": "Kampfgeist",
+ "IT": "Spirito",
+ "RU": "Дух",
+ "ES": "Espíritu"
+ },
+ "pokemon_move_479": {
+ "PT-BR": "Espada Colossal",
+ "EN": "Behemoth Blade",
+ "FR": "Gladius Maximus",
+ "DE": "Gigantenhieb",
+ "IT": "Taglio Maestoso",
+ "RU": "Меч Левиафана",
+ "ES": "Tajo Supremo"
+ },
+ "pokemon_move_480": {
+ "PT-BR": "Pancada Colossal",
+ "EN": "Behemoth Bash",
+ "FR": "Aegis Maxima",
+ "DE": "Gigantenstoß",
+ "IT": "Colpo Maestoso",
+ "RU": "Удар Левиафана",
+ "ES": "Embate Supremo"
+ },
+ "pokemon_move_481": {
+ "EN": "Thunder Cage Fast"
+ },
+ "pokemon_move_482": {
+ "PT-BR": "Canhão Dinamax",
+ "EN": "Dynamax Cannon",
+ "FR": "Canon Dynamax",
+ "DE": "Dynamax-Kanone",
+ "IT": "Cannone Dynamax",
+ "RU": "Динамакс-Пушка",
+ "ES": "Cañón Dinamax"
+ },
+ "pokemon_move_483": {
+ "PT-BR": "Canhão Dinamax",
+ "EN": "Dynamax Cannon",
+ "FR": "Canon Dynamax",
+ "DE": "Dynamax-Kanone",
+ "IT": "Cannone Dynamax",
+ "RU": "Динамакс-Пушка",
+ "ES": "Cañón Dinamax"
+ },
+ "pokemon_move_484": {
+ "PT-BR": "Batida de Escamas",
+ "EN": "Clanging Scales",
+ "FR": "Vibrécaille",
+ "DE": "Schuppenrasseln",
+ "IT": "Clamorsquame",
+ "RU": "Лязгающая Чешуя",
+ "ES": "Fragor Escamas"
+ },
+ "pokemon_move_485": {
+ "PT-BR": "Aperto Esmagador",
+ "EN": "Crush Grip",
+ "FR": "Presse",
+ "DE": "Quetschgriff",
+ "IT": "Sbriciolmano",
+ "RU": "Сокрушительная Хватка",
+ "ES": "Agarrón"
+ },
+ "pokemon_move_486": {
+ "PT-BR": "Energia Dracônica",
+ "EN": "Dragon Energy",
+ "FR": "Draco-Énergie",
+ "DE": "Drachenkräfte",
+ "IT": "Dragoenergia",
+ "RU": "Энергия Дракона",
+ "ES": "Dracoenergía"
+ },
+ "pokemon_move_487": {
+ "PT-BR": "Passo Aquático",
+ "EN": "Aqua Step",
+ "FR": "Danse Aquatique",
+ "DE": "Wogentanz",
+ "IT": "Idroballetto",
+ "RU": "Танец Воды",
+ "ES": "Danza Acuática"
+ },
+ "pokemon_move_488": {
+ "PT-BR": "Água Fria",
+ "EN": "Chilling Water",
+ "FR": "Douche Froide",
+ "DE": "Kalte Dusche",
+ "IT": "Doccia Fredda",
+ "RU": "Холодный Душ",
+ "ES": "Agua Fría"
+ },
+ "pokemon_move_489": {
+ "PT-BR": "Espada Secreta",
+ "EN": "Secret Sword",
+ "FR": "Lame Ointe",
+ "DE": "Mystoschwert",
+ "IT": "Spadamistica",
+ "RU": "Тайный Меч",
+ "ES": "Sable Místico"
+ },
+ "pokemon_move_490": {
+ "PT-BR": "Bico Explosivo",
+ "EN": "Beak Blast",
+ "FR": "Bec-Canon",
+ "DE": "Schnabelkanone",
+ "IT": "Cannonbecco",
+ "RU": "Взрывоопасный Клюв",
+ "ES": "Pico Cañón"
+ },
+ "pokemon_move_491": {
+ "PT-BR": "Explosão Mental",
+ "EN": "Mind Blown",
+ "FR": "Caboche-Kaboum",
+ "DE": "Knallkopf",
+ "IT": "Sbalorditesta",
+ "RU": "Взрыв Разума",
+ "ES": "Cabeza Sorpresa"
+ },
+ "pokemon_move_492": {
+ "PT-BR": "Toque do Tambor",
+ "EN": "Drum Beating",
+ "FR": "Tambour Battant",
+ "DE": "Trommelschläge",
+ "IT": "Tamburattacco",
+ "RU": "Барабанный Бой",
+ "ES": "Batería Asalto"
+ },
+ "pokemon_move_493": {
+ "PT-BR": "Bola Incendiária",
+ "EN": "Pyro Ball",
+ "FR": "Ballon Brûlant",
+ "DE": "Feuerball",
+ "IT": "Palla Infuocata",
+ "RU": "Огнешар",
+ "ES": "Balón Ígneo"
}
}
\ No newline at end of file
diff --git a/logic.php b/logic.php
index 35d4c6f4..3665c3d3 100644
--- a/logic.php
+++ b/logic.php
@@ -4,61 +4,11 @@
// Any new logic functions should be included directly where they are needed,
// NOT via this file!
-include('logic/active_raid_duplication_check.php');
-include('logic/alarm.php');
-include('logic/check_time.php');
-include('logic/cp_keys.php');
-include('logic/curl_json_response.php');
-include('logic/delete_raid.php');
-include('logic/delete_trainerinfo.php');
-include('logic/disable_raid_level.php');
-include('logic/edit_pokedex_keys.php');
-include('logic/get_chat_title_username.php');
-include('logic/get_formatted_pokemon_cp.php');
-include('logic/get_gym_by_telegram_id.php');
-include('logic/get_gym_details.php');
-include('logic/get_gym.php');
-include('logic/get_local_pokemon_name.php');
-include('logic/get_overview.php');
-include('logic/get_pokemon_by_table_id.php');
-include('logic/get_pokemon_cp.php');
-include('logic/get_pokemon_form_name.php');
-include('logic/get_pokemon_id_by_name.php');
-include('logic/get_pokemon_info.php');
-include('logic/get_pokemon_weather.php');
-include('logic/get_pokemon_shiny_status.php');
-include('logic/get_raid.php');
-include('logic/get_raid_times.php');
-include('logic/get_remote_users_count.php');
-include('logic/get_user.php');
-include('logic/get_weather_icons.php');
-include('logic/group_code_keys.php');
-include('logic/insert_cleanup.php');
-include('logic/insert_overview.php');
-include('logic/insert_trainerinfo.php');
-include('logic/keys_event.php');
-include('logic/keys_trainerinfo.php');
-include('logic/keys_vote.php');
-include('logic/mapslink.php');
-include('logic/new_user.php');
-include('logic/pokemon_keys.php');
-include('logic/raid_access_check.php');
-include('logic/raid_edit_gym_keys.php');
-include('logic/raid_edit_gyms_first_letter_keys.php');
-include('logic/raid_edit_raidlevel_keys.php');
-include('logic/raid_get_gyms_list_keys.php');
-include('logic/raid_level.php');
-include('logic/raid_list.php');
-include('logic/raid_poll_message.php');
-include('logic/sendalarmnotice.php');
-include('logic/send_trainerinfo.php');
-include('logic/send_vote_remote_users_limit_reached.php');
-include('logic/send_vote_time_first.php');
-include('logic/send_vote_time_future.php');
-include('logic/show_raid_poll.php');
-include('logic/show_raid_poll_small.php');
-include('logic/show_trainerinfo.php');
-include('logic/user_tutorial.php');
-include('logic/weather_keys.php');
-include('logic/curl_get_contents.php');
-?>
+require_once('logic/date_util.php');
+require_once('logic/geo_api.php');
+require_once('logic/key_util.php');
+require_once('logic/language.php');
+require_once('logic/collectCleanup.php');
+require_once('logic/get_local_pokemon_name.php');
+require_once('logic/get_raid.php');
+require_once('logic/new_user.php');
diff --git a/logic/active_raid_duplication_check.php b/logic/active_raid_duplication_check.php
index 9f6ee6dc..a9993583 100644
--- a/logic/active_raid_duplication_check.php
+++ b/logic/active_raid_duplication_check.php
@@ -1,35 +1,44 @@
(UTC_TIMESTAMP() - INTERVAL 5 MINUTE)
- AND gym_id = {$gym_id}
- ORDER BY event IS NOT NULL
- "
- );
- $active = 0;
- while($raid = $rs->fetch()) {
- if($config->RAID_EXCLUDE_EXRAID_DUPLICATION && $raid['event'] == EVENT_ID_EX) {
- continue;
- }
- if($config->RAID_EXCLUDE_EVENT_DUPLICATION && $raid['event'] !== NULL && $raid['event'] != EVENT_ID_EX) {
- continue;
- }
- $active = $raid['id'];
- break;
+ $levelSql = '';
+ $args = [$gym_id];
+ if($level !== false) {
+ $levelSql = 'AND level = ?';
+ $args[] = $level;
+ }
+ // Build query.
+ $rs = my_query('
+ SELECT id, event, level, pokemon, pokemon_form, spawn
+ FROM raids
+ WHERE end_time > UTC_TIMESTAMP()
+ AND gym_id = ?
+ ' . $levelSql . '
+ ORDER BY end_time, event IS NOT NULL
+ ', $args
+ );
+ while($raid = $rs->fetch()) {
+ // In some cases (ex-raids, event raids and elite raids) gyms can have multiple raids saved to them.
+ // We ignore these raids when performing the duplication check.
+ if( ($config->RAID_EXCLUDE_EXRAID_DUPLICATION && $raid['event'] == EVENT_ID_EX)
+ or ($level != 9 && $config->RAID_EXCLUDE_ELITE_DUPLICATION && $raid['level'] == 9)
+ or ($config->RAID_EXCLUDE_EVENT_DUPLICATION && $raid['event'] !== NULL && $raid['event'] != EVENT_ID_EX)) {
+ debug_log("Ignoring any duplication at {$gym_id} due to event/ex raid: {$raid['id']}");
+ continue;
}
- return $active;
+ debug_log("Duplicate raid found at {$gym_id}: {$raid['id']}");
+ if($returnArray === true) return $raid;
+ else return $raid['id'];
+ }
+ return 0;
}
-
-?>
diff --git a/logic/alarm.php b/logic/alarm.php
index c13f1641..ca242ed8 100644
--- a/logic/alarm.php
+++ b/logic/alarm.php
@@ -1,4 +1,6 @@
fetch();
- // Get Trainername
- $answer_quests = check_trainername($answer_quests);
- $username = '' . $answer_quests['name'] . '';
- // Get Trainercode
- $trainercode = $answer_quests['trainercode'];
- }
+ // Get user info if it's needed for the alarm
+ if(!empty($user_id)) {
+ // Name of the user, which executes a status update
+ $requestUserinfo = my_query('SELECT * FROM users WHERE user_id = ? LIMIT 1', [$user_id]);
+ $answer_quests = $requestUserinfo->fetch();
+ // Get Trainername
+ $answer_quests = check_trainername($answer_quests);
+ $username = '' . $answer_quests['name'] . '';
+ // Get Trainercode
+ $trainercode = $answer_quests['trainercode'];
+ }else {
+ // Set this to 0 so we get every attendee from database
+ $user_id = 0;
+ }
- // Gym name and raid times
- if(is_array($raid_id_array)) {
- $raid = $raid_id_array;
- }else {
- $raid = get_raid($raid_id_array);
- }
- $raid_id = $raid['id'];
+ // Gym name and raid times
+ $raid = (is_array($raid_id_array) ? $raid_id_array : get_raid($raid_id_array));
- $gymname = $raid['gym_name'];
- $raidtimes = str_replace(CR, '', str_replace(' ', '', get_raid_times($raid, false, true)));
+ $raid_id = $raid['id'];
- // Get attend time.
- if(!in_array($action, ['new_att','new_boss','change_time','group_code_private','group_code_public'])) {
- $r = my_query("SELECT DISTINCT attend_time FROM attendance WHERE raid_id = {$raid_id} and user_id = {$user_id}");
- $a = $r->fetch();
- if(isset($a['attend_time'])) {
- $attendtime = $a['attend_time'];
- }else {
- $attendtime = 0;
- }
- }
+ $gymname = $raid['gym_name'];
- if($action == 'group_code_public' or $action == 'group_code_private') {
- $request = my_query(" SELECT DISTINCT attendance.user_id, attendance.remote, users.lang
- FROM attendance
- LEFT JOIN users
- ON users.id = attendance.user_id
- WHERE raid_id = {$raid_id}
- AND attend_time = (SELECT attend_time from attendance WHERE raid_id = {$raid_id} AND user_id = {$user_id})
- ");
- }else {
- $request = my_query(" SELECT DISTINCT attendance.user_id, users.lang
- FROM attendance
- LEFT JOIN users
- ON users.id = attendance.user_id
- WHERE raid_id = {$raid_id}
- AND attendance.user_id != {$user_id}
- AND cancel = 0
- AND raid_done = 0
- AND alarm = 1
- ");
- }
+ // Get attend time.
+ if(!in_array($action, ['new_att','new_boss','change_time','group_code_private','group_code_public'])) {
+ $r = my_query('SELECT DISTINCT attend_time FROM attendance WHERE raid_id = ? and user_id = ? LIMIT 1', [$raid_id, $user_id]);
+ $a = $r->fetch();
- while($answer = $request->fetch())
- {
- if(!isset($answer['lang']) or empty($answer['lang'])) $recipient_language = $config->LANGUAGE_PUBLIC;
- else $recipient_language = $answer['lang'];
- // Adding a guest
- if($action == "extra") {
- debug_log('Alarm additional trainer: ' . $info);
- $icons = ['alien' => EMOJI_ALIEN, 'in_person' => EMOJI_IN_PERSON];
+ $attendtime = isset($a['attend_time']) ? $a['attend_time'] : 0;
+ }
- // Sending message
- if($info == 'alien') {
- $msg_text = '' . getTranslation('alert_add_alien_trainer', true, $recipient_language) . '' . CR;
- }else {
- $msg_text = '' . getTranslation('alert_add_trainer', true, $recipient_language) . '' . CR;
- }
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . SP . '+' . $icons[$info] . CR;
- $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime);
- $msg_text .= create_traincode_msg($trainercode);
+ if($action == 'group_code_public' or $action == 'group_code_private') {
+ $request = my_query('
+ SELECT DISTINCT attendance.user_id, attendance.remote, users.lang
+ FROM attendance
+ LEFT JOIN users
+ ON users.user_id = attendance.user_id
+ WHERE raid_id = :raidId
+ AND attend_time = (SELECT attend_time from attendance WHERE raid_id = :raidId AND user_id = :userId)
+ ', ['raidId' => $raid_id, 'userId' => $user_id]);
+ }else {
+ $request = my_query('
+ SELECT DISTINCT attendance.user_id, users.lang
+ FROM attendance
+ LEFT JOIN users
+ ON users.user_id = attendance.user_id
+ WHERE raid_id = :raidId
+ AND attendance.user_id != :userId
+ AND cancel = 0
+ AND raid_done = 0
+ AND alarm = 1
+ ', ['raidId' => $raid_id, 'userId' => $user_id]);
+ }
- // Updating status - here or cancel
- } else if($action == "status") {
- // If trainer changes state (to late or cancelation)
- if($info == 'late') {
- debug_log('Alarm late: ' . $info);
- // Send message.
- $msg_text = '' . getTranslation('alert_later', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime);
- $msg_text .= create_traincode_msg($trainercode);
- } else if($info == 'cancel') {
- debug_log('Alarm cancel: ' . $info);
- $msg_text = '' . getTranslation('alert_cancel', true, $recipient_language) . '' . CR;
- $msg_text .= TEAM_CANCEL . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime);
- }
+ while($answer = $request->fetch())
+ {
+ if(!isset($answer['lang']) or empty($answer['lang'])) $recipient_language = $config->LANGUAGE_PUBLIC;
+ else $recipient_language = $GLOBALS['languages'][$answer['lang']];
+ $raidtimes = str_replace(CR, '', str_replace(' ', '', get_raid_times($raid, $recipient_language, true)));
+ // Adding a guest
+ if($action == 'extra') {
+ debug_log('Alarm additional trainer: ' . $info);
+ $icons = ['alien' => EMOJI_ALIEN, 'in_person' => EMOJI_IN_PERSON];
- // Updating pokemon
- } else if($action == "pok_individual") {
- debug_log('Alarm Pokemon: ' . $info);
+ // Sending message
+ if($info == 'alien') {
+ $msg_text = '' . getTranslation('alert_add_alien_trainer', $recipient_language) . '' . CR;
+ }else {
+ $msg_text = '' . getTranslation('alert_add_trainer', $recipient_language) . '' . CR;
+ }
+ $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . SP . '+' . $icons[$info] . CR;
+ $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime, $recipient_language);
+ $msg_text .= create_traincode_msg($trainercode);
- // Only a specific pokemon
- if($info != '0') {
- $pokemon = explode("-",$info,2);
- $poke_name = get_local_pokemon_name($pokemon[0],$pokemon[1]);
- $msg_text = '' . getTranslation('alert_individual_poke', true, $recipient_language) . SP . $poke_name . '' . CR;
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime);
- $msg_text .= create_traincode_msg($trainercode);
- // Any pokemon
- } else {
- $msg_text = '' . getTranslation('alert_every_poke', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime);
- $msg_text .= create_traincode_msg($trainercode);
- }
+ // Updating status - here or cancel
+ } else if($action == 'status') {
+ // If trainer changes state (to late or cancelation)
+ if($info == 'late') {
+ debug_log('Alarm late: ' . $info);
+ // Send message.
+ $msg_text = '' . getTranslation('alert_later', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime, $recipient_language);
+ $msg_text .= create_traincode_msg($trainercode);
+ } else if($info == 'cancel') {
+ debug_log('Alarm cancel: ' . $info);
+ $msg_text = '' . getTranslation('alert_cancel', $recipient_language) . '' . CR;
+ $msg_text .= TEAM_CANCEL . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime, $recipient_language);
+ }
- // Cancel pokemon
- } else if($action == "pok_cancel_individual") {
- debug_log('Alarm Pokemon: ' . $info);
- $pokemon = explode("-",$info,2);
- $poke_name = get_local_pokemon_name($pokemon[0],$pokemon[1]);
- $msg_text = '' . getTranslation('alert_cancel_individual_poke', true, $recipient_language) . SP . $poke_name . '' . CR;
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime);
- $msg_text .= create_traincode_msg($trainercode);
+ // Updating pokemon
+ } else if($action == 'pok_individual') {
+ debug_log('Alarm Pokemon: ' . $info);
- } else if($action == "new_boss") {
- $msg_text = '' . getTranslation('alert_raid_boss') . '' . CR;
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_EGG . SP . '' . get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form']) . '' . CR;
+ if($info != '0') {
+ // Only a specific pokemon
+ $pokemon = explode("-",$info,2);
+ $poke_name = get_local_pokemon_name($pokemon[0], $pokemon[1], $recipient_language);
+ $msg_text = '' . getTranslation('alert_individual_poke', $recipient_language) . SP . $poke_name . '' . CR;
+ } else {
+ // Any pokemon
+ $msg_text = '' . getTranslation('alert_every_poke', $recipient_language) . '' . CR;
+ }
+ $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime, $recipient_language);
+ $msg_text .= create_traincode_msg($trainercode);
- // New attendance
- } else if($action == "new_att") {
- debug_log('Alarm new attendance: ' . $info);
- // Will Attend
- $msg_text = '' . getTranslation('alert_new_att', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . check_time($info);
- $msg_text .= create_traincode_msg($trainercode);
+ // Cancel pokemon
+ } else if($action == 'pok_cancel_individual') {
+ debug_log('Alarm Pokemon: ' . $info);
+ $pokemon = explode("-",$info,2);
+ $poke_name = get_local_pokemon_name($pokemon[0], $pokemon[1], $recipient_language);
+ $msg_text = '' . getTranslation('alert_cancel_individual_poke', $recipient_language) . SP . $poke_name . '' . CR;
+ $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime, $recipient_language);
+ $msg_text .= create_traincode_msg($trainercode);
- // Attendance time change
- } else if($action == "change_time") {
- debug_log('Alarm changed attendance time: ' . $info);
- // Changes Time
- $msg_text = '' . getTranslation('alert_change_time', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . '' . check_time($info) . '';
- $msg_text .= create_traincode_msg($trainercode);
+ } else if($action == 'new_boss') {
+ $msg_text = '' . getTranslation('alert_raid_boss', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_EGG . SP . '' . get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form'], $recipient_language) . '' . CR;
- // Attendance from remote
- } else if($action == "remote") {
- debug_log('Alarm remote attendance changed: ' . $info);
- // Changes Time
- $msg_text = '' . getTranslation('alert_remote', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_REMOTE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime) . '';
- $msg_text .= create_traincode_msg($trainercode);
+ // New attendance
+ } else if($action == 'new_att') {
+ debug_log('Alarm new attendance: ' . $info);
+ // Will Attend
+ $msg_text = '' . getTranslation('alert_new_att', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . check_time($info, $recipient_language);
+ $msg_text .= create_traincode_msg($trainercode);
- // Attendance no longer from remote
- } else if($action == "no_remote") {
- debug_log('Alarm remote attendance changed: ' . $info);
- // Changes Time
- $msg_text = '' . getTranslation('alert_no_remote', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_REMOTE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime) . '';
+ // Attendance time change
+ } else if($action == 'change_time') {
+ debug_log('Alarm changed attendance time: ' . $info);
+ // Changes Time
+ $msg_text = '' . getTranslation('alert_change_time', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . '' . check_time($info, $recipient_language) . '';
+ $msg_text .= create_traincode_msg($trainercode);
- // No additional trainer
- } else if($action == "extra_alone") {
- debug_log('Alarm no additional trainers: ' . $info);
- $msg_text = '' . getTranslation('alert_extra_alone', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime);
- $msg_text .= create_traincode_msg($trainercode);
+ // Attendance from remote
+ } else if($action == 'remote') {
+ debug_log('Alarm remote attendance changed: ' . $info);
+ // Changes Time
+ $msg_text = '' . getTranslation('alert_remote', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_REMOTE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime, $recipient_language) . '';
+ $msg_text .= create_traincode_msg($trainercode);
- // Group code public
- } else if($action == "group_code_public") {
- debug_log('Alarm for group code: ' . $info);
- $msg_text = '' . getTranslation('alert_raid_starts_now', true, $recipient_language) . CR . getTranslation('alert_raid_get_in', true, $recipient_language) . '' . CR . CR;
- $msg_text .= '' . getTranslation('alert_public_group', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_REMOTE . SP . $info;
+ // Attendance no longer from remote
+ } else if($action == 'no_remote') {
+ debug_log('Alarm remote attendance changed: ' . $info);
+ // Changes Time
+ $msg_text = '' . getTranslation('alert_no_remote', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_REMOTE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime, $recipient_language) . '';
- // Group code private
- } else if($action == "group_code_private") {
- debug_log('Alarm for group code: ' . $info);
- $msg_text = '' . getTranslation('alert_raid_starts_now', true, $recipient_language) . CR . getTranslation('alert_raid_get_in', true, $recipient_language) . '' . CR . CR;
- $msg_text .= '' . getTranslation('alert_private_group', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ // No additional trainer
+ } else if($action == 'extra_alone') {
+ debug_log('Alarm no additional trainers: ' . $info);
+ $msg_text = '' . getTranslation('alert_extra_alone', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . check_time($attendtime, $recipient_language);
+ $msg_text .= create_traincode_msg($trainercode);
- // Send code to remote raiders
- if($answer['remote'] == 1) {
- $msg_text .= EMOJI_REMOTE . SP . '' . $info . '';
- }
+ // Group code public
+ } else if($action == 'group_code_public') {
+ debug_log('Alarm for group code: ' . $info);
+ $msg_text = '' . getTranslation('alert_raid_starts_now', $recipient_language) . CR . getTranslation('alert_raid_get_in', $recipient_language) . '' . CR . CR;
+ $msg_text .= '' . getTranslation('alert_public_group', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_REMOTE . SP . $info;
- // Send message to local raiders
- if($answer['remote'] == 0) {
- $msg_text .= EMOJI_REMOTE . SP . '' . getTranslation('group_code_only_for_remote_raiders', true, $recipient_language) . '';
- }
- // Attendance from remote
- } else if($action == "want_invite") {
- debug_log('Alarm invite begging changed: ' . $info);
- $msg_text = '' . getTranslation('alert_want_invite', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_WANT_INVITE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime) . '';
- $msg_text .= create_traincode_msg($trainercode);
+ // Group code private
+ } else if($action == 'group_code_private') {
+ debug_log('Alarm for group code: ' . $info);
+ $msg_text = '' . getTranslation('alert_raid_starts_now', $recipient_language) . CR . getTranslation('alert_raid_get_in', $recipient_language) . '' . CR . CR;
+ $msg_text .= '' . getTranslation('alert_private_group', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_HERE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- // Attendance no longer from remote
- } else if($action == "no_want_invite") {
- debug_log('Alarm invite begging changed: ' . $info);
- $msg_text = '' . getTranslation('alert_no_want_invite', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_WANT_INVITE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime) . '';
- $msg_text .= create_traincode_msg($trainercode);
+ // Send code to remote raiders
+ if($answer['remote'] == 1) {
+ $msg_text .= EMOJI_REMOTE . SP . '' . $info . '';
+ }
- // Let others know you are not playing, but can invite others
- } else if($action == "can_invite") {
- debug_log('Alarm: ' . $action);
- $msg_text = '' . getTranslation('alert_can_invite', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_CAN_INVITE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime) . '';
- $msg_text .= create_traincode_msg($trainercode);
+ // Send message to local raiders
+ if($answer['remote'] == 0) {
+ $msg_text .= EMOJI_REMOTE . SP . '' . getTranslation('group_code_only_for_remote_raiders', $recipient_language) . '';
+ }
+ // Attendance from remote
+ } else if($action == 'want_invite') {
+ debug_log('Alarm invite begging changed: ' . $info);
+ $msg_text = '' . getTranslation('alert_want_invite', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_WANT_INVITE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime, $recipient_language) . '';
+ $msg_text .= create_traincode_msg($trainercode);
- // Let others know you are not longer able to invite them
- } else if($action == "no_can_invite") {
- debug_log('Alarm: ' . $action);
- $msg_text = '' . getTranslation('alert_no_can_invite', true, $recipient_language) . '' . CR;
- $msg_text .= EMOJI_CAN_INVITE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
- $msg_text .= EMOJI_SINGLE . SP . $username . CR;
- $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime) . '';
- $msg_text .= create_traincode_msg($trainercode);
- }
- $tg_json[] = send_message($answer['user_id'], $msg_text, false, false, true);
+ // Attendance no longer from remote
+ } else if($action == 'no_want_invite') {
+ debug_log('Alarm invite begging changed: ' . $info);
+ $msg_text = '' . getTranslation('alert_no_want_invite', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_WANT_INVITE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime, $recipient_language) . '';
+ $msg_text .= create_traincode_msg($trainercode);
+
+ // Let others know you are not playing, but can invite others
+ } else if($action == 'can_invite') {
+ debug_log('Alarm: ' . $action);
+ $msg_text = '' . getTranslation('alert_can_invite', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_CAN_INVITE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime, $recipient_language) . '';
+ $msg_text .= create_traincode_msg($trainercode);
+
+ // Let others know you are not longer able to invite them
+ } else if($action == 'no_can_invite') {
+ debug_log('Alarm: ' . $action);
+ $msg_text = '' . getTranslation('alert_no_can_invite', $recipient_language) . '' . CR;
+ $msg_text .= EMOJI_CAN_INVITE . SP . $gymname . SP . '(' . $raidtimes . ')' . CR;
+ $msg_text .= EMOJI_SINGLE . SP . $username . CR;
+ $msg_text .= EMOJI_CLOCK . SP . '' . check_time($attendtime, $recipient_language) . '';
+ $msg_text .= create_traincode_msg($trainercode);
}
- return $tg_json;
+ $tg_json[] = send_message(create_chat_object([$answer['user_id']]), $msg_text, false, false, true);
+ }
+ return $tg_json;
}
/**
@@ -271,9 +268,21 @@ function create_traincode_msg($trainercode){
global $config;
$message = '';
if($config->RAID_POLL_SHOW_TRAINERCODE == true && !is_null($trainercode)) {
- $message = CR . EMOJI_FRIEND . SP . '' . $trainercode . '';
+ $message = CR . EMOJI_FRIEND . SP . '' . $trainercode . '';
}
return $message;
}
-?>
+/**
+ * Check attendance time against anytime.
+ * @param $time
+ * @param $recipientLanguage
+ */
+function check_time($time, $recipientLanguage)
+{
+ // Raid anytime?
+ if(strcmp($time, ANYTIME)===0){
+ return getTranslation('anytime', $recipientLanguage);
+ }
+ return dt2time($time);
+}
diff --git a/logic/bearer_token.php b/logic/bearer_token.php
new file mode 100644
index 00000000..77f6d085
--- /dev/null
+++ b/logic/bearer_token.php
@@ -0,0 +1,34 @@
+ $version), botSpecificConfigFile('config.json'));
+}
+
+/**
+ * Get current code revision from git state, or 'manual' if no git state exists.
+ * @return string
+ */
+function get_rev()
+{
+ if (!file_exists(ROOT_PATH . '/.git/HEAD')){
+ debug_log('No .git/HEAD present, marking revision as manual');
+ return 'manual';
+ }
+ $ref = trim(file_get_contents(ROOT_PATH . '/.git/HEAD'));
+ if (ctype_xdigit($ref)){
+ // Is already a hex string and thus valid rev
+ // Return first 6 digits of the hash
+ return substr($ref, 0, 6);
+ }
+ // strip 'ref: ' to get file path
+ $ref_file = ROOT_PATH . '/.git/' . substr($ref, 5);
+ if (file_exists($ref_file)){
+ // Return first 6 digits of the hash, this matches our naming of docker image tags
+ return substr(file_get_contents($ref_file), 0, 6);
+ }
+ error_log("Git ref found but we cannot resolve it to a revision ({$ref_file}). Was the .git folder mangled?");
+ return 'manual';
+}
+
+/**
+ * Bot upgrade check
+ * @param $current
+ * @param $latest
+ * @return
+ */
+function bot_upgrade_check($current, $latest)
+{
+ global $config, $metrics, $namespace, $dbh;
+ $orig = $current; // we may have to do multiple upgrades
+ if ($metrics){
+ // This is the one place where we have full knowledge of version information & upgrades
+ $version_info = $metrics->registerGauge($namespace, 'version_info', 'Schema and revision information', ['current_schema', 'required_schema', 'rev', 'upgraded_timestamp', 'upgraded_from']);
+ }
+
+ $upgrade_verdict = null;
+ $manual_upgrade_verdict = null;
+ // Same version?
+ if($current == $latest) {
+ return;
+ }
+ $upgrade_verdict = true;
+ if ($metrics && IS_INIT){
+ // record initial version even if we don't do upgrades.
+ $version_info->set(1, [$current, $latest, get_rev(), null, null]);
+ }
+ // Check if upgrade files exist.
+ $upgrade_files = array();
+ $upgrade_files = str_replace(UPGRADE_PATH . '/','', glob(UPGRADE_PATH . '/*.sql'));
+ if(!is_array($upgrade_files) or count($upgrade_files) == 0 or !in_array($latest . '.sql', $upgrade_files)) {
+ // No upgrade files found! Since the version now would only go up with upgrade files, something is off.
+ // It could be the user has bumped the VERSION file manually, or omitted upgrade files.
+ $error = 'NO SQL UPGRADE FILES FOUND FOR LATEST SCHEMA, THIS SHOULD NOT HAPPEN';
+ throw new Exception($error);
+ }
+ // Check each sql filename.
+ foreach ($upgrade_files as $ufile)
+ {
+ $target = str_replace('.sql', '', $ufile);
+ // Skip every older sql file from array.
+ if($target <= $current) continue;
+
+ if (!$config->UPGRADE_SQL_AUTO){
+ $manual_upgrade_verdict = true;
+ debug_log("There's a schema upgrade to {$target} we could have run, but auto-upgrades have been disabled!");
+ break;
+ }
+ info_log('PERFORMING AUTO SQL UPGRADE: ' . UPGRADE_PATH . '/' . $ufile, '!');
+ require_once('sql_utils.php');
+ if (!run_sql_file(UPGRADE_PATH . '/' . $ufile)) {
+ $manual_upgrade_verdict = true;
+ $error = 'AUTO UPGRADE FAILED: ' . UPGRADE_PATH . '/' . $ufile;
+ throw new Exception($error);
+ }
+ $manual_upgrade_verdict = false;
+ upgrade_config_version($target);
+ if ($metrics){
+ $version_info->set(1, [$target, $latest, get_rev(), time(), $current]);
+ }
+ $current = $target;
+ }
+ // If previous sql upgrades had to be done and were successful, update also pokemon table
+ if($upgrade_verdict === true && $manual_upgrade_verdict === false) {
+ require_once(ROOT_PATH . '/mods/getdb.php');
+ }
+
+ // Signal whether manual action is required or not.
+ if ($manual_upgrade_verdict === true){
+ $error = "The bot has pending schema upgrades ({$current} -> {$latest}) but you've disabled automatic upgrades. Nothing will work until you go do the upgrade(s) manually. You'll find them in the dir sql/upgrade/";
+ throw new Exception($error);
+ }
+}
diff --git a/logic/check_time.php b/logic/check_time.php
deleted file mode 100644
index f1e6af25..00000000
--- a/logic/check_time.php
+++ /dev/null
@@ -1,16 +0,0 @@
-
diff --git a/logic/collectCleanup.php b/logic/collectCleanup.php
new file mode 100644
index 00000000..b6a321a5
--- /dev/null
+++ b/logic/collectCleanup.php
@@ -0,0 +1,81 @@
+ $save_id,
+ ':unique_id' => $unique_id,
+ ':pokedex_id' => $identifier['pokemon'],
+ ':form_id' => $identifier['pokemon_form'],
+ ':raid_id' => ($identifier['raid_ended'] ? 0 : $identifier['id']), // No need to save raid id if raid has ended
+ ':ended' => $identifier['raid_ended'],
+ ':start_time' => ($identifier['raid_ended'] ? NULL : $identifier['start_time']),
+ ':end_time' => ($identifier['raid_ended'] ? NULL : $identifier['end_time']),
+ ':gym_id' => $identifier['gym_id'],
+ ':standalone' => $standalone_photo,
+ ]
+ );
+ }
+ $raid_id = is_array($identifier) ? $identifier['id'] : $identifier;
+ insert_cleanup($chat_id, $message_id, $thread_id, $raid_id, $type, $unique_id);
+ // Return response.
+ return $response;
+}
diff --git a/logic/config_chats.php b/logic/config_chats.php
new file mode 100644
index 00000000..468a4894
--- /dev/null
+++ b/logic/config_chats.php
@@ -0,0 +1,87 @@
+CHATS_SHARE)) {
+ $chat_vars = ['TRAINER_CHATS','SHARE_CHATS','WEBHOOK_CHATS'];
+ $chatsTemp = [];
+ foreach(get_object_vars($config) as $var => $value) {
+ foreach($chat_vars as $start) {
+ if(!is_string($var) || strpos(trim($var), $start) === false) continue;
+ if($var == 'WEBHOOK_CHATS_BY_POKEMON') continue;
+ if(is_string($config->{$var})) {
+ array_merge($chatsTemp, explode(',', $config->{$var}));
+ continue;
+ }elseif(is_int($config->{$var})) {
+ $chatsTemp[] = $config->{$var};
+ continue;
+ }
+ array_merge($chatsTemp, $config->{$var});
+ }
+ }
+ foreach(array_unique($chatsTemp) as $chat) {
+ $chats[] = create_chat_object([$chat]);
+ }
+ }else {
+ $chats = [];
+ if(isset($config->CHATS_SHARE['manual_share'])) {
+ foreach($config->CHATS_SHARE['manual_share'] as $chatGroup) {
+ foreach($chatGroup as $chat) {
+ $chats = add_chat($chats, $chat);
+ }
+ }
+ }
+ if(isset($config->CHATS_SHARE['after_attendance'])) {
+ foreach($config->CHATS_SHARE['after_attendance'] as $chat) {
+ $chats = add_chat($chats, $chat);
+ }
+ }
+ if(isset($config->CHATS_SHARE['webhook'])) {
+ if(isset($config->CHATS_SHARE['webhook']['all'])) {
+ foreach($config->CHATS_SHARE['webhook']['all'] as $chat) {
+ $chats = add_chat($chats, $chat);
+ }
+ }
+ if(isset($config->CHATS_SHARE['webhook']['by_pokemon'])) {
+ foreach($config->CHATS_SHARE['webhook']['by_pokemon'] as $chatGroup) {
+ foreach($chatGroup['chats'] as $chat) {
+ $chats = add_chat($chats, $chat);
+ }
+ }
+ }
+ if(isset($config->CHATS_SHARE['webhook']['geofences'])) {
+ foreach($config->CHATS_SHARE['webhook']['geofences'] as $geofence) {
+ foreach($geofence as $chatGroup) {
+ foreach($chatGroup as $chat) {
+ $chats = add_chat($chats, $chat);
+ }
+ }
+ }
+ }
+ }
+ }
+ return $chats;
+}
+
+function get_config_chat_by_chat_and_thread_id($chat_id, $thread_id) {
+ foreach(list_config_chats_by_short_id() as $chat) {
+ if($chat['id'] == $chat_id && ($thread_id == NULL && !isset($chat['thread']) || (isset($chat['thread']) && $chat['thread'] == $thread_id)))
+ return $chat;
+ }
+}
+
+function add_chat($chats, $chatToAdd) {
+ foreach($chats as $chat) {
+ if(
+ $chat['id'] == $chatToAdd['id'] && !isset($chat['thread']) ||
+ $chat['id'] == $chatToAdd['id'] && isset($chat['thread']) && isset($chatToAdd['thread']) && $chat['thread'] == $chatToAdd['thread']
+ ) return $chats;
+ }
+ $chats[] = $chatToAdd;
+ return $chats;
+}
+
+function get_config_chat_by_short_id($id) {
+ $chats = list_config_chats_by_short_id();
+ return $chats[$id];
+}
diff --git a/logic/cp_keys.php b/logic/cp_keys.php
deleted file mode 100644
index 0d68cc1a..00000000
--- a/logic/cp_keys.php
+++ /dev/null
@@ -1,106 +0,0 @@
- $i,
- 'callback_data' => $pokedex_id . ':' . $action . ':' . $new_cp
- );
- }
-
- // 4 5 6
- for ($i = 4; $i <= 6; $i = $i + 1) {
- // Set new cp
- $new_cp = $cp_add . ($old_cp == 0 ? '' : $old_cp) . $i;
-
- // Set keys.
- $keys[] = array(
- 'text' => $i,
- 'callback_data' => $pokedex_id . ':' . $action . ':' . $new_cp
- );
- }
-
- // 1 2 3
- for ($i = 1; $i <= 3; $i = $i + 1) {
- // Set new cp
- $new_cp = $cp_add . ($old_cp == 0 ? '' : $old_cp) . $i;
-
- // Set keys.
- $keys[] = array(
- 'text' => $i,
- 'callback_data' => $pokedex_id . ':' . $action . ':' . $new_cp
- );
- }
-
- // 0
- if($old_cp != 0) {
- // Set new cp
- $new_cp = $cp_add . $old_cp . '0';
- } else {
- $new_cp = $reset_arg;
- }
-
- // Set keys.
- $keys[] = array(
- 'text' => '0',
- 'callback_data' => $pokedex_id . ':' . $action . ':' . $new_cp
- );
- }
-
- // Save
- $keys[] = array(
- 'text' => EMOJI_DISK,
- 'callback_data' => $pokedex_id . ':' . $action . ':' . $save_arg
- );
-
- // Reset
- $keys[] = array(
- 'text' => getTranslation('reset'),
- 'callback_data' => $pokedex_id . ':' . $action . ':' . $reset_arg
- );
-
- // Get the inline key array.
- $keys = inline_key_array($keys, 3);
-
- return $keys;
-}
-
-?>
diff --git a/logic/createRaidBossList.php b/logic/createRaidBossList.php
new file mode 100644
index 00000000..c5f4a9c9
--- /dev/null
+++ b/logic/createRaidBossList.php
@@ -0,0 +1,82 @@
+RAID_BOSS_LIST_RAID_LEVELS). ')';
+ $q = my_query('
+ SELECT
+ pokedex_id, pokemon_form_id, date_start, date_end, raid_level,
+ CONCAT(DATE_FORMAT(date_start,"%d%m%y%k"), DATE_FORMAT(date_end,"%d%m%y%k")) AS arrkey,
+ CASE WHEN date(date_start) = date(date_end) THEN 1 ELSE 0 END AS sameDay
+ FROM raid_bosses
+ WHERE raid_level IN ' . $levelList . '
+ AND date_end > DATE_SUB(NOW(), INTERVAL 1 HOUR)
+ AND disabled = 0
+ ORDER BY sameDay, date_start, date_end
+ ');
+ $list = '';
+ $prevStartDate = '';
+ $data[0] = $data[1] = [];
+ // Save the results in easy to process format
+ foreach($q->fetchAll() as $row) {
+ $data[$row['sameDay']][$row['arrkey']][] = $row;
+ }
+ if($q->rowCount() == 0) return '';
+ $i = 1;
+ $list = $config->RAID_BOSS_LIST_TITLE;
+ // Print list of bosses that run for multiple days
+ foreach($data[0] as $tempRow) {
+ $list .= PHP_EOL . '- ';
+ foreach($tempRow as $num => $row) {
+ $pokemonName = get_local_pokemon_name($row['pokedex_id'], $row['pokemon_form_id'], $config->LANGUAGE_PUBLIC);
+ if(in_array($row['raid_level'], RAID_LEVEL_SHADOW)) $pokemonName .= ' ' . getPublicTranslation('shadow');
+ if($num != 0) $list .= ', ';
+ $list .= $pokemonName;
+ }
+ $dateStart = new dateTime($row['date_start']);
+ $dateEnd = new dateTime($row['date_end']);
+ $list .= ' ' . $dateStart->format($dateFormat) . ' - '. $dateEnd->format($dateFormat);
+ $i++;
+ if($i > $config->RAID_BOSS_LIST_ROW_LIMIT) break;
+ }
+
+ // Print list of one day bosses
+ foreach($data[1] as $arrkey => $tempRow) {
+ $startDate = substr($arrkey, 0, 6);
+ if($list != '' && $prevStartDate != $startDate) $list.= PHP_EOL . PHP_EOL;
+ foreach($tempRow as $num => $row) {
+ $dateStart = new dateTime($row['date_start']);
+ $dateEnd = new dateTime($row['date_end']);
+ if($num == 0){
+ if($prevStartDate != $startDate) {
+ $list .= $dateStart->format($dateFormat);
+ }
+ $list .= PHP_EOL . '- ';
+ }
+ $pokemonName = get_local_pokemon_name($row['pokedex_id'], $row['pokemon_form_id'], $config->LANGUAGE_PUBLIC);
+ if($num != 0) $list .= ', ';
+ $list .= $pokemonName;
+ $prevStartDate = $startDate;
+ }
+ $list .= ' ' . $dateStart->format($timeFormat) . ' - ' . $dateEnd->format($timeFormat);
+ }
+ return $list;
+}
+?>
\ No newline at end of file
diff --git a/logic/curl_get_contents.php b/logic/curl_get_contents.php
index 1f32f4db..2f829770 100644
--- a/logic/curl_get_contents.php
+++ b/logic/curl_get_contents.php
@@ -1,22 +1,20 @@
diff --git a/logic/curl_json_response.php b/logic/curl_json_response.php
deleted file mode 100644
index 7c0855e8..00000000
--- a/logic/curl_json_response.php
+++ /dev/null
@@ -1,56 +0,0 @@
- {$json_response}", 'ERROR:');
- } else {
- if($identifier != false) {
- if (isset($response['result']['chat']['type']) && in_array($response['result']['chat']['type'], ['channel','group','supergroup'])) {
- // Set chat and message_id
- $chat_id = $response['result']['chat']['id'];
- $message_id = $response['result']['message_id'];
- debug_log('Return data: Chat id: '.$chat_id.', message_id: '.$message_id.', type: '.$identifier);
- if($identifier == 'trainer') {
- debug_log('Adding trainermessage info to database now!');
- insert_trainerinfo($chat_id, $message_id);
- }else if ($identifier == 'overview') {
- debug_log('Adding overview info to database now!');
- $chat_title = $response['result']['chat']['title'];
- $chat_username = isset($response['result']['chat']['username']) ? $response['result']['chat']['username'] : '';
-
- insert_overview($chat_id, $message_id, $chat_title, $chat_username);
- }else {
- if(isset($response['result']['text']) && !empty($response['result']['text'])) {
- $type = 'poll_text';
- } else if(isset($response['result']['caption']) && !empty($response['result']['caption'])) {
- $type = 'poll_photo';
- } else if(isset($response['result']['venue']) && !empty($response['result']['venue'])) {
- $type = 'poll_venue';
- }else if(isset($response['result']['photo']) && !isset($response['result']['caption'])) {
- $type = 'photo';
- }
- insert_cleanup($chat_id, $message_id, $identifier, $type);
- }
- }
- }
- }
-
- // Return response.
- return $response;
-}
-
-?>
diff --git a/logic/date_util.php b/logic/date_util.php
new file mode 100644
index 00000000..f8af7bb2
--- /dev/null
+++ b/logic/date_util.php
@@ -0,0 +1,101 @@
+format('Y-m-d');
+}
+
+/**
+ * Get current utc datetime.
+ * @param $format
+ * @return string
+ */
+function utcnow($format = 'Y-m-d H:i:s')
+{
+ // Create a object with UTC timezone
+ $datetime = new DateTime('now', new DateTimeZone('UTC'));
+
+ return $datetime->format($format);
+}
+
+/**
+ * Format utc time from datetime value.
+ * @param $datetime_value
+ * @param $format
+ * @return string
+ */
+function utctime($datetime_value, $format = 'H:i')
+{
+ // Create a object with UTC timezone
+ $datetime = new DateTime($datetime_value, new DateTimeZone('UTC'));
+
+ return $datetime->format($format);
+}
+
+/**
+ * Get date from datetime value.
+ * @param $datetime_value
+ * @param $tz
+ * @return string
+ */
+function dt2date($datetime_value, $tz = NULL)
+{
+ global $config;
+ if($tz == NULL){
+ $tz = $config->TIMEZONE;
+ }
+ // Create a object with UTC timezone
+ $datetime = new DateTime($datetime_value, new DateTimeZone('UTC'));
+
+ // Change the timezone of the object without changing it's time
+ $datetime->setTimezone(new DateTimeZone($tz));
+
+ return $datetime->format('Y-m-d');
+}
+
+/**
+ * Get time from datetime value.
+ * @param $datetime_value
+ * @param $format
+ * @param $tz
+ * @return string
+ */
+function dt2time($datetime_value, $format = 'H:i', $tz = NULL)
+{
+ global $config;
+ if($tz == NULL){
+ $tz = $config->TIMEZONE;
+ }
+ // Create a object with UTC timezone
+ $datetime = new DateTime($datetime_value, new DateTimeZone('UTC'));
+
+ // Change the timezone of the object without changing it's time
+ $datetime->setTimezone(new DateTimeZone($tz));
+
+ return $datetime->format($format);
+}
+
+function tz_diff($src = 'UTC', $dst = NULL) {
+ global $config;
+ if($dst == NULL){
+ $dst = $config->TIMEZONE;
+ }
+ $dateTimeZoneSrc = new DateTimeZone($src);
+ $dateTimeZoneDst = new DateTimeZone($dst);
+ $dateTimeSrc = new datetime('now',$dateTimeZoneSrc);
+ $diff = $dateTimeZoneDst->getOffset($dateTimeSrc);
+
+ $hours = str_pad(floor($diff/60/60),2,'0',STR_PAD_LEFT);
+ $minutes = str_pad(floor(($diff-$hours*60*60)/60),2,'0',STR_PAD_LEFT);
+ if($diff < 0) {
+ return '-'.$hours.':'.$minutes;
+ }
+ return '+'.$hours.':'.$minutes;
+}
diff --git a/logic/debug.php b/logic/debug.php
new file mode 100644
index 00000000..34098356
--- /dev/null
+++ b/logic/debug.php
@@ -0,0 +1,144 @@
+DEBUG_LOGFILE,
+ $config->LOGGING_INFO_LOGFILE,
+ $config->DEBUG_LOGFILE,
+ $config->DEBUG_INCOMING_LOGFILE,
+ $config->DEBUG_SQL_LOGFILE,
+ $config->CLEANUP_LOGFILE,
+ ];
+
+ # Collect unique paths that house logfiles
+ $paths = [];
+ foreach($logfiles as $logfile){
+ $dirname = pathinfo($logfile, PATHINFO_DIRNAME);
+ if(!in_array($dirname, $paths)){
+ $paths[] = $dirname;
+ }
+ }
+
+ # Create the necessary paths
+ foreach($paths as $path){
+ if (!file_exists($path)) {
+ mkdir($path, 770, true);
+ }
+ }
+}
+/**
+ * Write any log level.
+ * @param $val
+ * @param string $type
+ */
+function generic_log($val, $type, $logfile)
+{
+ $date = @date('Y-m-d H:i:s');
+ $usec = microtime(true);
+ $date = $date . '.' . str_pad(substr($usec, 11, 4), 4, '0', STR_PAD_RIGHT);
+
+ $bt = debug_backtrace();
+ $bl = '';
+
+ // How many calls back to print
+ // Increasing this makes it easier to hunt down issues, but increases log line length
+ $layers = 1;
+
+ while ($btl = array_shift($bt)) {
+ // Ignore generic_log and it's calling function in the call stack
+ // Not sure why it works exactly like that, but it does.
+ if ($btl['function'] == __FUNCTION__){
+ continue;
+ }
+ --$layers;
+ $bl = $bl . '[' . basename($btl['file']) . ':' . $btl['line'] . ']';
+ if($layers <= 0) {
+ $bl = $bl . ' ';
+ break;
+ }
+ }
+
+ if (gettype($val) != 'string') $val = var_export($val, 1);
+ $rows = explode("\n", $val);
+ foreach ($rows as $v) {
+ error_log('[' . $date . '][' . getmypid() . '] ' . $bl . $type . ' ' . $v . "\n", 3, $logfile);
+ }
+}
+
+/**
+ * Write debug log.
+ * @param $val
+ * @param string $type
+ */
+function debug_log($message, $type = '*')
+{
+ global $config;
+ // Write to log only if debug is enabled.
+ if ($config->DEBUG === false){
+ return;
+ }
+ generic_log($message, $type, $config->DEBUG_LOGFILE);
+}
+
+/**
+ * Write cleanup log.
+ * @param $message
+ * @param string $type
+ */
+function cleanup_log($message, $type = '*'){
+ global $config;
+ // Write to log only if cleanup logging is enabled.
+ if ($config->CLEANUP_LOG === false){
+ return;
+ }
+ generic_log($message, $type, $config->CLEANUP_LOGFILE);
+}
+
+/**
+ * Write sql debug log.
+ * @param $message
+ * @param string $type
+ */
+function debug_log_sql($message, $type = '%'){
+ global $config;
+ // Write to log only if debug is enabled.
+ if ($config->DEBUG_SQL === false){
+ return;
+ }
+ generic_log($message, $type, $config->DEBUG_SQL_LOGFILE);
+}
+
+/**
+ * Write incoming stream debug log.
+ * @param $message
+ * @param string $type
+ */
+function debug_log_incoming($message, $type = '<'){
+ global $config;
+ // Write to log only if debug is enabled.
+ if ($config->DEBUG_INCOMING === false){
+ return;
+ }
+ generic_log($message, $type, $config->DEBUG_INCOMING_LOGFILE);
+}
+
+/**
+ * Write INFO level log.
+ * @param $message
+ * @param string $type
+ */
+function info_log($message, $type = '[I]'){
+ global $config;
+ // Write to log only if info logging is enabled.
+ if ($config->LOGGING_INFO === false){
+ return;
+ }
+ generic_log($message, $type, $config->LOGGING_INFO_LOGFILE);
+}
diff --git a/logic/delete_raid.php b/logic/delete_raid.php
deleted file mode 100644
index ade9f0f3..00000000
--- a/logic/delete_raid.php
+++ /dev/null
@@ -1,63 +0,0 @@
- 0
- "
- );
-
- // Counter
- $counter = 0;
-
- // Delete every telegram message
- while ($row = $rs->fetch()) {
- // Delete telegram message.
- debug_log('Deleting telegram message ' . $row['message_id'] . ' from chat ' . $row['chat_id'] . ' for raid ' . $row['raid_id']);
- delete_message($row['chat_id'], $row['message_id']);
- $counter = $counter + 1;
- }
-
- // Nothing to delete on telegram.
- if ($counter == 0) {
- debug_log('Raid with ID ' . $raid_id . ' was not found in the cleanup table! Skipping deletion of telegram messages!');
- }
-
- // Delete raid from cleanup table.
- debug_log('Deleting raid ' . $raid_id . ' from the cleanup table:');
- $rs_cleanup = my_query(
- "
- DELETE FROM cleanup
- WHERE raid_id = '{$raid_id}'
- "
- );
-
- // Delete raid from attendance table.
- debug_log('Deleting raid ' . $raid_id . ' from the attendance table:');
- $rs_attendance = my_query(
- "
- DELETE FROM attendance
- WHERE raid_id = '{$raid_id}'
- "
- );
-
- // Delete raid from raid table.
- debug_log('Deleting raid ' . $raid_id . ' from the raid table:');
- $rs_raid = my_query(
- "
- DELETE FROM raids
- WHERE id = '{$raid_id}'
- "
- );
-}
-
-
-?>
diff --git a/logic/delete_trainerinfo.php b/logic/delete_trainerinfo.php
index 46d88d1c..587bcace 100644
--- a/logic/delete_trainerinfo.php
+++ b/logic/delete_trainerinfo.php
@@ -6,18 +6,15 @@
*/
function delete_trainerinfo($chat_id, $message_id)
{
- // Delete telegram message.
- debug_log('Deleting trainer info telegram message ' . $message_id . ' from chat ' . $chat_id);
- delete_message($chat_id, $message_id);
+ // Delete telegram message.
+ debug_log('Deleting trainer info telegram message ' . $message_id . ' from chat ' . $chat_id);
+ delete_message($chat_id, $message_id);
- // Delete trainer info from database.
- debug_log('Deleting trainer information from database for Chat_ID: ' . $chat_id);
- $rs = my_query(
- "
- DELETE FROM trainerinfo
- WHERE chat_id = '{$chat_id}'
- "
- );
+ // Delete trainer info from database.
+ debug_log('Deleting trainer information from database for Chat_ID: ' . $chat_id);
+ my_query('
+ DELETE FROM trainerinfo
+ WHERE chat_id = ?
+ ', [$chat_id]
+ );
}
-
-?>
diff --git a/logic/disable_raid_level.php b/logic/disable_raid_level.php
index 55fd8fe3..977591a4 100644
--- a/logic/disable_raid_level.php
+++ b/logic/disable_raid_level.php
@@ -1,19 +1,15 @@
diff --git a/logic/download_Portal_Image.php b/logic/download_Portal_Image.php
new file mode 100644
index 00000000..67e42b5e
--- /dev/null
+++ b/logic/download_Portal_Image.php
@@ -0,0 +1,40 @@
+ $gym_id, 'a' => 'show', 'v' => $arg_show]),
+ button($text_ex_button, ['gym_edit_details', 'g' => $gym_id, 'a' => 'ex', 'v' => $arg_ex])
+ ];
+ if($botUser->accessCheck('gym-name', true)) {
+ $keys[][] = button(EMOJI_PENCIL . ' ' . getTranslation('gym_name_edit'), ['gym_edit_details', 'g' => $gym_id, 'a' => 'name']);
+ }
+ if($botUser->accessCheck('gym-edit', true)) {
+ $keys[][] = button(
+ EMOJI_INFO . ' ' . (!empty($gym_note) ? getTranslation('edit') : getTranslation('add') ) . ' ' . getTranslation('gym_add_edit_note'),
+ ['gym_edit_details', 'g' => $gym_id, 'a' => 'note']
+ );
+ $keys[][] = button(
+ EMOJI_MAP . ' ' . ((!empty($gym_address) && $gym_address != getTranslation('directions')) ? getTranslation('edit') : getTranslation('add')) . ' ' . getTranslation('gym_address'),
+ ['gym_edit_details', 'g' => $gym_id, 'a' => 'addr']
+ );
+ $keys[][] = button(
+ EMOJI_HERE . ' ' . getTranslation('gym_edit_coordinates'),
+ ['gym_edit_details', 'g' => $gym_id, 'a' => 'gps']
+ );
+ }
+ if($botUser->accessCheck('gym-delete', true)) {
+ $keys[][] = button(EMOJI_DELETE . ' ' . getTranslation('gym_delete'), ['gym_delete', 'g' => $gym_id, 'c' => 0]);
+ }
+ $keys[][] = button(getTranslation('done'), ['exit', 'd' => '1']);
+
+ return $keys;
+}
diff --git a/logic/edit_pokedex_keys.php b/logic/edit_pokedex_keys.php
index 05a7ca4c..20471f3d 100644
--- a/logic/edit_pokedex_keys.php
+++ b/logic/edit_pokedex_keys.php
@@ -2,103 +2,73 @@
/**
* Pokedex edit pokemon keys.
* @param $limit
- * @param $action
* @return array
*/
-function edit_pokedex_keys($limit, $action)
+function edit_pokedex_keys($limit)
{
- // Number of entries to display at once.
- $entries = 10;
-
- // Number of entries to skip with skip-back and skip-next buttons
- $skip = 50;
-
- // Module for back and next keys
- $module = "pokedex";
-
- // Init empty keys array.
- $keys = [];
-
- // Get all pokemon from database
- $rs = my_query(
- "
- SELECT pokedex_id, pokemon_form_id
- FROM pokemon
- ORDER BY pokedex_id, pokemon_form_name != 'normal', pokemon_form_name
- LIMIT $limit, $entries
- "
- );
-
- // Number of entries
- $cnt = my_query(
- "
- SELECT COUNT(*) AS count
- FROM pokemon
- "
- );
-
- // Number of database entries found.
- $sum = $cnt->fetch();
- $count = $sum['count'];
-
- // List users / moderators
- while ($mon = $rs->fetch()) {
- $pokemon_name = get_local_pokemon_name($mon['pokedex_id'], $mon['pokemon_form_id']);
- $keys[] = array(
- 'text' => $mon['pokedex_id'] . SP . $pokemon_name,
- 'callback_data' => $mon['pokedex_id'] . '-' . $mon['pokemon_form_id'] . ':pokedex_edit_pokemon:0'
- );
- }
-
- // Empty backs and next keys
- $keys_back = [];
- $keys_next = [];
-
- // Add back key.
- if ($limit > 0) {
- $new_limit = $limit - $entries;
- $empty_back_key = [];
- $back = universal_key($empty_back_key, $new_limit, $module, $action, getTranslation('back') . " (-" . $entries . ")");
- $keys_back[] = $back[0][0];
- }
-
- // Add skip back key.
- if ($limit - $skip > 0) {
- $new_limit = $limit - $skip - $entries;
- $empty_back_key = [];
- $back = universal_key($empty_back_key, $new_limit, $module, $action, getTranslation('back') . " (-" . $skip . ")");
- $keys_back[] = $back[0][0];
- }
-
- // Add next key.
- if (($limit + $entries) < $count) {
- $new_limit = $limit + $entries;
- $empty_next_key = [];
- $next = universal_key($empty_next_key, $new_limit, $module, $action, getTranslation('next') . " (+" . $entries . ")");
- $keys_next[] = $next[0][0];
- }
-
- // Add skip next key.
- if (($limit + $skip + $entries) < $count) {
- $new_limit = $limit + $skip + $entries;
- $empty_next_key = [];
- $next = universal_key($empty_next_key, $new_limit, $module, $action, getTranslation('next') . " (+" . $skip . ")");
- $keys_next[] = $next[0][0];
- }
-
- // Exit key
- $empty_exit_key = [];
- $key_exit = universal_key($empty_exit_key, "0", "exit", "0", getTranslation('abort'));
-
- // Get the inline key array.
- $keys = inline_key_array($keys, 1);
- $keys_back = inline_key_array($keys_back, 2);
- $keys_next = inline_key_array($keys_next, 2);
- $keys = array_merge($keys_back, $keys);
- $keys = array_merge($keys, $keys_next);
- $keys = array_merge($keys, $key_exit);
-
- return $keys;
+ // Number of entries to display at once.
+ $entries = 10;
+
+ // Number of entries to skip with skip-back and skip-next buttons
+ $skip = 50;
+
+ // Init empty keys array.
+ $pokemonKeys = [];
+
+ // Get all pokemon from database
+ $rs = my_query('
+ SELECT pokedex_id, pokemon_form_id
+ FROM pokemon
+ ORDER BY pokedex_id, pokemon_form_name != \'normal\', pokemon_form_name
+ LIMIT ' . $limit . ',' . $entries
+ );
+
+ // Number of entries
+ $cnt = my_query('
+ SELECT COUNT(*) AS count
+ FROM pokemon
+ ');
+
+ // Number of database entries found.
+ $sum = $cnt->fetch();
+ $count = $sum['count'];
+
+ // List users / moderators
+ while ($mon = $rs->fetch()) {
+ $pokemon_name = get_local_pokemon_name($mon['pokedex_id'], $mon['pokemon_form_id']);
+ $pokemonKeys[][] = button($mon['pokedex_id'] . SP . $pokemon_name, ['pokedex_edit_pokemon', 'p' => $mon['pokedex_id'] . '-' . $mon['pokemon_form_id']]);
+ }
+
+ // Empty backs and next keys
+ $keys_back = $keys_next = [];
+
+ // Add back key.
+ if ($limit > 0) {
+ $new_limit = $limit - $entries;
+ $keys_back[0][] = button(getTranslation('back') . ' (-' . $entries . ')',['pokedex', 'l' => $new_limit]);
+ }
+
+ // Add skip back key.
+ if ($limit - $skip > 0) {
+ $new_limit = $limit - $skip - $entries;
+ $keys_back[0][] = button(getTranslation('back') . ' (-' . $skip . ')', ['pokedex', 'l' => $new_limit]);
+ }
+
+ // Add next key.
+ if (($limit + $entries) < $count) {
+ $new_limit = $limit + $entries;
+ $keys_next[0][] = button(getTranslation('next') . ' (+' . $entries . ')', ['pokedex', 'l' => $new_limit]);
+ }
+
+ // Add skip next key.
+ if (($limit + $skip + $entries) < $count) {
+ $new_limit = $limit + $skip + $entries;
+ $keys_next[0][] = button(getTranslation('next') . ' (+' . $skip . ')', ['pokedex', 'l' => $new_limit]);
+ }
+
+ // Get the inline key array.
+ $keys = array_merge($keys_back, $pokemonKeys, $keys_next);
+ $keys[][] = button(getTranslation('abort'), 'exit');
+
+ return $keys;
}
-
-?>
diff --git a/logic/geo_api.php b/logic/geo_api.php
new file mode 100644
index 00000000..370bbc0c
--- /dev/null
+++ b/logic/geo_api.php
@@ -0,0 +1,240 @@
+MAPS_LOOKUP && !empty($config->MAPS_API_KEY)) {
+ // Init defaults.
+ $location = [];
+ $location['street'] = '';
+ $location['street_number'] = '';
+ $location['postal_code'] = '';
+ $location['district'] = '';
+
+ // Set maps geocode url.
+ $language = strtolower($config->LANGUAGE_PUBLIC);
+ $MapsApiKey = $config->MAPS_API_KEY;
+ $url = 'https://maps.googleapis.com/maps/api/geocode/json?latlng=' . $lat . ',' . $lon . '&language=' . $language;
+ $url .= '&key=' . $MapsApiKey;
+
+ // Curl request.
+ $curl = curl_init($url);
+ curl_setopt($curl, CURLOPT_HEADER, false);
+ curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+
+ // Proxy server?
+ // Use Proxyserver for curl if configured
+ if ($config->CURL_USEPROXY) {
+ curl_setopt($curl, CURLOPT_PROXY, $config->CURL_PROXYSERVER);
+ }
+
+ // Curl response.
+ $json_response = curl_exec($curl);
+
+ // Write request and response to log.
+ debug_log($url, 'G>');
+ debug_log($json_response, '' . (float)$gym['lat'] . ',' . (float)$gym['lon'].'';
- return $msg;
+ return $msg;
}
-
-?>
diff --git a/logic/get_local_pokemon_name.php b/logic/get_local_pokemon_name.php
index 2d8de959..f5118775 100644
--- a/logic/get_local_pokemon_name.php
+++ b/logic/get_local_pokemon_name.php
@@ -1,53 +1,48 @@
fetch();
- $pokemon_form_name = $res['pokemon_form_name'] ?? 'normal';
+ global $config, $botUser;
+ $q = my_query('SELECT pokemon_name, pokemon_form_name FROM pokemon WHERE pokedex_id = ? AND pokemon_form_id = ?', [$pokemon_id, $pokemon_form_id]);
+ $res = $q->fetch();
+ $pokemon_form_name = $res['pokemon_form_name'] ?? 'normal';
- debug_log('Pokemon_form: ' . $pokemon_form_name);
-
- // Get translation type
- if($override_language == true) {
- $getTypeTranslation = 'getPublicTranslation';
- } else {
- $getTypeTranslation = 'getTranslation';
- }
- // Init pokemon name and define fake pokedex ids used for raid eggs
- $pokemon_name = '';
- $eggs = $GLOBALS['eggs'];
+ debug_log('Pokemon_form: ' . $pokemon_form_name);
+ if($language === null) $language = $botUser->userLanguage;
- // Get eggs from normal translation.
- if(in_array($pokemon_id, $eggs)) {
- $pokemon_name = $getTypeTranslation('egg_' . substr($pokemon_id, -1));
- } else {
- $pokemon_name = $getTypeTranslation('pokemon_id_' . $pokemon_id);
- }
- if ($pokemon_form_name != 'normal') {
- $pokemon_form_name = $getTypeTranslation('pokemon_form_' . $pokemon_form_name);
- }
- // Fallback 1: Valid pokedex id or just a raid egg?
- if($pokemon_id === "NULL" || $pokemon_id == 0) {
- $pokemon_name = $getTypeTranslation('egg_0');
+ // Init pokemon name and define fake pokedex ids used for raid eggs
+ $pokemon_name = '';
- // Fallback 2: Get original pokemon name and/or form name from database
- } else if(empty($pokemon_name) or empty($pokemon_form_name)) {
- // Pokemon name
- $pokemon_name = (empty($pokemon_name)?$res['pokemon_name']:$pokemon_name);
- // Pokemon form
- if(empty($pokemon_form_name) && $res['pokemon_form_name'] != 'normal') {
- $pokemon_form_name = ucfirst(str_replace("_"," ",$res['pokemon_form_name']));
- }
- }
+ // Get eggs from normal translation.
+ $pokemon_name = (in_array($pokemon_id, EGGS)) ?
+ getTranslation('egg_' . str_replace('999', '', $pokemon_id), $language) :
+ getTranslation('pokemon_id_' . $pokemon_id, $language);
- return $pokemon_name . ($pokemon_form_name != "normal" ? " " . $pokemon_form_name : "");
+ $skipFallback = false;
+ if ($pokemon_form_name != 'normal') {
+ $pokemon_form_name = getTranslation('pokemon_form_' . $pokemon_form_id, $language);
+ // Use only form name if form name contains Pokemon name
+ // e.g. Black Kyurem, Frost Rotom
+ if(strpos($pokemon_form_name, $pokemon_name, 0)) {
+ $pokemon_name = $pokemon_form_name;
+ $pokemon_form_name = '';
+ $skipFallback = true;
+ }
+ }
+ // If we didn't find Pokemon name or form name from translation files, use the name from database as fallback
+ if(empty($pokemon_name) or empty($pokemon_form_name) && !$skipFallback) {
+ // Pokemon name
+ $pokemon_name = (empty($pokemon_name) ? $res['pokemon_name'] : $pokemon_name);
+ // Pokemon form
+ if(empty($pokemon_form_name) && $res['pokemon_form_name'] != 'normal') {
+ $pokemon_form_name = ucfirst(str_replace('_',' ',$res['pokemon_form_name']));
+ }
+ }
+ return $pokemon_name . ($pokemon_form_name != "normal" ? " " . $pokemon_form_name : "");
}
-
-?>
diff --git a/logic/get_overview.php b/logic/get_overview.php
index 2db0c738..966ed576 100644
--- a/logic/get_overview.php
+++ b/logic/get_overview.php
@@ -1,110 +1,120 @@
' . getPublicTranslation('raid_overview_for_chat') . ' ' . $chat_title . ' ' . getPublicTranslation('from') . ' '. dt2time('now') . '' . CR . CR;
+ $msg = '' . getPublicTranslation('raid_overview_for_chat') . ' ' . $chat_title . ' ' . getPublicTranslation('from') . ' '. dt2time('now') . '' . CR . CR;
- $now = utcnow();
-
- if(count($active_raids) == 0) {
- $msg .= getPublicTranslation('no_active_raids') . CR . CR;
- }else {
- foreach($active_raids as $row) {
- // Set variables for easier message building.
- $raid_id = $row['id'];
- $resolved_boss = resolve_raid_boss($row['pokemon'], $row['pokemon_form'], $row['spawn'], $row['level']);
- $row['pokemon'] = $resolved_boss['pokedex_id'];
- $row['pokemon_form'] = $resolved_boss['pokemon_form_id'];
- $pokemon = get_local_pokemon_name($row['pokemon'], $row['pokemon_form'], true);
- $gym = $row['gym_name'];
- $ex_gym = $row['ex_gym'];
- $ex_raid_gym_marker = (strtolower($config->RAID_EX_GYM_MARKER) == 'icon') ? EMOJI_STAR : '' . $config->RAID_EX_GYM_MARKER . '';
- $start_time = $row['start_time'];
- $time_left = $row['t_left'];
+ if(count($active_raids) == 0) {
+ $msg .= getPublicTranslation('no_active_raids') . CR . CR;
+ if($config->RAID_BOSS_LIST) {
+ $msg .= createRaidBossList() . CR . CR;
+ }
+ //Add custom message from the config.
+ if (!empty($config->RAID_PIN_MESSAGE)) {
+ $msg .= $config->RAID_PIN_MESSAGE;
+ }
+ return $msg;
+ }
+ $now = utcnow();
+ foreach($active_raids as $row) {
+ // Set variables for easier message building.
+ $raid_id = $row['id'];
+ $resolved_boss = resolve_raid_boss($row['pokemon'], $row['pokemon_form'], $row['spawn'], $row['level']);
+ $row['pokemon'] = $resolved_boss['pokedex_id'];
+ $row['pokemon_form'] = $resolved_boss['pokemon_form_id'];
+ $pokemon = get_local_pokemon_name($row['pokemon'], $row['pokemon_form'], $config->LANGUAGE_PUBLIC);
+ $gym = $row['gym_name'];
+ $ex_raid_gym_marker = (strtolower($config->RAID_EX_GYM_MARKER) == 'icon') ? EMOJI_STAR : '' . $config->RAID_EX_GYM_MARKER . '';
+ $start_time = $row['start_time'];
+ $time_left = $row['t_left'];
- debug_log($pokemon . '@' . $gym . ' found for overview.');
- // Build message and add each gym in this format - link gym_name to raid poll chat_id + message_id if possible
- /* Example:
- * Raid Overview from 18:18h
- *
- * Train Station Gym
- * Raikou - still 0:24h
- *
- * Bus Station Gym
- * Level 5 Egg 18:41 to 19:26
- */
- // Gym name.
- $msg .= $ex_gym ? $ex_raid_gym_marker . SP : '';
- $msg .= !empty($chat_username) ? '' . htmlspecialchars($gym) . '' : $gym;
- $msg .= CR;
+ debug_log($pokemon . '@' . $gym . ' found for overview.');
+ // Build message and add each gym in this format - link gym_name to raid poll chat_id + message_id if possible
+ /* Example:
+ * Raid Overview from 18:18h
+ *
+ * Train Station Gym
+ * Raikou - still 0:24h
+ *
+ * Bus Station Gym
+ * Level 5 Egg 18:41 to 19:26
+ */
+ // Gym name.
+ $msg .= $row['ex_gym'] ? $ex_raid_gym_marker . SP : '';
+ $msg .= !empty($chat_username) ? '' . htmlspecialchars($gym) . '' : $gym;
+ $msg .= CR;
- if(isset($row['event_name']) && $row['event_name'] != "") {
- $msg .= "" . $row['event_name'] . "" . CR;
- }
+ if(isset($row['event_name']) && $row['event_name'] != '') {
+ $msg .= '' . $row['event_name'] . '' . CR;
+ }
- // Raid has not started yet - adjust time left message
- if ($now < $start_time) {
- $msg .= get_raid_times($row, true);
- // Raid has started already
- } else {
- // Add time left message.
- $msg .= $pokemon . ' — ' . getPublicTranslation('still') . SP . $time_left . 'h' . CR;
- }
- $exclude_pokemon_sql = "";
- if(!in_array($row['pokemon'], $GLOBALS['eggs'])) {
- $exclude_pokemon_sql = 'AND (pokemon = \''.$row['pokemon'].'-'.$row['pokemon_form'].'\' or pokemon = \'0\')';
- }
- // Count attendances
- $rs_att = my_query(
- "
- SELECT count(attend_time) AS count,
- sum(want_invite = 0 && remote = 0 && can_invite = 0) + sum(case when want_invite = 0 && remote = 0 then attendance.extra_in_person else 0 end) AS count_in_person,
- sum(want_invite = 0 && remote = 1 && can_invite = 0) + sum(case when want_invite = 0 && remote = 1 then attendance.extra_in_person else 0 end) AS count_remote,
- sum(case when want_invite = 0 && can_invite = 0 then attendance.extra_alien else 0 end) AS extra_alien,
- sum(case when want_invite = 1 && can_invite = 0 then 1 + attendance.extra_in_person else 0 end) AS count_want_invite,
- sum(can_invite = 1) AS count_can_invite
- FROM (
- SELECT DISTINCT attend_time, user_id, extra_in_person, extra_alien, remote, want_invite, can_invite
- FROM attendance
- WHERE raid_id = {$raid_id}
- AND attend_time IS NOT NULL
- AND ( attend_time > UTC_TIMESTAMP() or attend_time = '" . ANYTIME . "' )
- AND raid_done != 1
- AND cancel != 1
- {$exclude_pokemon_sql}
- ) as attendance
- LEFT JOIN users
- ON attendance.user_id = users.user_id
- "
- );
+ // Raid has not started yet - adjust time left message
+ if ($now < $start_time) {
+ $msg .= get_raid_times($row, $config->LANGUAGE_PUBLIC);
+ // Raid has started already
+ } else {
+ // Add time left message.
+ $msg .= $pokemon . ' — ' . getPublicTranslation('still') . SP . $time_left . 'h' . CR;
+ }
+ $exclude_pokemon_sql = '';
+ if(!in_array($row['pokemon'], EGGS)) {
+ $exclude_pokemon_sql = 'AND (pokemon = \''.$row['pokemon'].'-'.$row['pokemon_form'].'\' or pokemon = \'0\')';
+ }
+ // Count attendances
+ $rs_att = my_query('
+ SELECT
+ count(attend_time) AS count,
+ sum(want_invite = 0 && remote = 0 && can_invite = 0) + sum(case when want_invite = 0 && remote = 0 then attendance.extra_in_person else 0 end) AS count_in_person,
+ sum(want_invite = 0 && remote = 1 && can_invite = 0) + sum(case when want_invite = 0 && remote = 1 then attendance.extra_in_person else 0 end) AS count_remote,
+ sum(case when want_invite = 0 && can_invite = 0 then attendance.extra_alien else 0 end) AS extra_alien,
+ sum(case when want_invite = 1 && can_invite = 0 then 1 + attendance.extra_in_person else 0 end) AS count_want_invite,
+ sum(can_invite = 1) AS count_can_invite
+ FROM (
+ SELECT DISTINCT attend_time, user_id, extra_in_person, extra_alien, remote, want_invite, can_invite
+ FROM attendance
+ WHERE raid_id = ?
+ AND attend_time IS NOT NULL
+ AND ( attend_time > UTC_TIMESTAMP() or attend_time = \'' . ANYTIME . '\' )
+ AND raid_done != 1
+ AND cancel != 1
+ ' .$exclude_pokemon_sql . '
+ ) as attendance
+ LEFT JOIN users
+ ON attendance.user_id = users.user_id
+ ', [$raid_id]
+ );
- $att = $rs_att->fetch();
+ $att = $rs_att->fetch();
- // Add to message.
- if ($att['count'] > 0) {
- $msg .= EMOJI_GROUP . ' ' . ($att['count_in_person'] + $att['count_remote'] + $att['extra_alien'] + $att['count_want_invite']) . ' — ';
- $msg .= ((($att['count_can_invite']) > 0) ? EMOJI_CAN_INVITE . ($att['count_can_invite']) . ' ' : '');
- $msg .= ((($att['count_in_person']) > 0) ? EMOJI_IN_PERSON . ($att['count_in_person']) . ' ' : '');
- $msg .= ((($att['count_remote']) > 0) ? EMOJI_REMOTE . ($att['count_remote']) . ' ' : '');
- $msg .= ((($att['extra_alien']) > 0) ? EMOJI_ALIEN . ($att['extra_alien']) . ' ' : '');
- $msg .= (($att['count_want_invite'] > 0) ? EMOJI_WANT_INVITE . $att['count_want_invite'] : '');
- $msg .= CR;
- }
- $msg .= CR;
- }
- }
- //Add custom message from the config.
- if (!empty($config->RAID_PIN_MESSAGE)) {
- $msg .= $config->RAID_PIN_MESSAGE;
+ if ($att['count'] == 0) {
+ $msg .= CR;
+ continue;
}
- return $msg;
+ // Add to message.
+ $msg .= EMOJI_GROUP . ' ' . ($att['count_in_person'] + $att['count_remote'] + $att['extra_alien'] + $att['count_want_invite']) . ' — ';
+ $msg .= ((($att['count_can_invite']) > 0) ? EMOJI_CAN_INVITE . ($att['count_can_invite']) . ' ' : '');
+ $msg .= ((($att['count_in_person']) > 0) ? EMOJI_IN_PERSON . ($att['count_in_person']) . ' ' : '');
+ $msg .= ((($att['count_remote']) > 0) ? EMOJI_REMOTE . ($att['count_remote']) . ' ' : '');
+ $msg .= ((($att['extra_alien']) > 0) ? EMOJI_ALIEN . ($att['extra_alien']) . ' ' : '');
+ $msg .= (($att['count_want_invite'] > 0) ? EMOJI_WANT_INVITE . $att['count_want_invite'] : '');
+ $msg .= CR . CR;
+ }
+ if($config->RAID_BOSS_LIST) {
+ $msg .= createRaidBossList() . CR . CR;
+ }
+ //Add custom message from the config.
+ if (!empty($config->RAID_PIN_MESSAGE)) {
+ $msg .= $config->RAID_PIN_MESSAGE;
+ }
+ return $msg;
}
-?>
diff --git a/logic/get_pokemon_by_table_id.php b/logic/get_pokemon_by_table_id.php
index a917cb79..16bd49c1 100644
--- a/logic/get_pokemon_by_table_id.php
+++ b/logic/get_pokemon_by_table_id.php
@@ -5,13 +5,14 @@
* @return array
*/
function get_pokemon_by_table_id($pokemon_table_id) {
- $q = my_query("
- SELECT pokedex_id,
- pokemon_form_id
- FROM pokemon
- WHERE id = {$pokemon_table_id}
- LIMIT 1
- ");
- $return = $q->fetch();
- return $return;
-}
\ No newline at end of file
+ $q = my_query('
+ SELECT pokedex_id,
+ pokemon_form_id
+ FROM pokemon
+ WHERE id = ?
+ LIMIT 1
+ ', [$pokemon_table_id]
+ );
+ $return = $q->fetch();
+ return $return;
+}
diff --git a/logic/get_pokemon_cp.php b/logic/get_pokemon_cp.php
deleted file mode 100644
index 0e496fd0..00000000
--- a/logic/get_pokemon_cp.php
+++ /dev/null
@@ -1,25 +0,0 @@
-fetch();
-
- return $cp;
-}
-
-?>
diff --git a/logic/get_pokemon_form_name.php b/logic/get_pokemon_form_name.php
index 64e81bd7..44705126 100644
--- a/logic/get_pokemon_form_name.php
+++ b/logic/get_pokemon_form_name.php
@@ -7,30 +7,32 @@
*/
function get_pokemon_form_name($pokedex_id, $pokemon_form_id)
{
- debug_log($pokedex_id.'-'.$pokemon_form_id, 'Finding Pokemon form name for:');
+ debug_log($pokedex_id.'-'.$pokemon_form_id, 'Finding Pokemon form name for:');
- $pokemon_form_name = 'normal';
- // Make sure $dex_id is numeric
- if(is_numeric($pokedex_id) && is_numeric($pokemon_form_id)) {
- // Get raid level from database
- $rs = my_query(
- "
- SELECT pokemon_form_name
- FROM pokemon
- WHERE pokedex_id = {$pokedex_id}
- AND pokemon_form_id = '{$pokemon_form_id}'
- LIMIT 1
- "
- );
-
- $level = $rs->fetch();
- $pokemon_form_name = $level['pokemon_form_name'];
+ $pokemon_form_name = 'normal';
+ // Make sure $dex_id is numeric
+ if(!is_numeric($pokedex_id) || !is_numeric($pokemon_form_id)) {
+ debug_log('Faulty dex_id or form_id, defaulting to normal.');
+ return $pokemon_form_name;
+ }
+ // Get raid level from database
+ $rs = my_query('
+ SELECT pokemon_form_name
+ FROM pokemon
+ WHERE pokedex_id = ?
+ AND pokemon_form_id = ?
+ LIMIT 1
+ ', [$pokedex_id, $pokemon_form_id]
+ );
- debug_log($pokemon_form_name, 'Per db, level is:');
- } else {
- debug_log('Faulty dex_id or form_id, defaulting to normal.');
- }
+ $level = $rs->fetch();
+ if($level) {
+ $pokemon_form_name = $level['pokemon_form_name'];
+ } else {
+ $error = "pokemon_form_name unknown for pokedex_id: {$pokedex_id}, pokemon_form_id: {$pokemon_form_id}";
+ throw new Exception($error);
+ }
+ debug_log($pokemon_form_name, 'Per db, level is:');
- return $pokemon_form_name;
+ return $pokemon_form_name;
}
-?>
diff --git a/logic/get_pokemon_id_by_name.php b/logic/get_pokemon_id_by_name.php
index d828f0e7..12a53c92 100644
--- a/logic/get_pokemon_id_by_name.php
+++ b/logic/get_pokemon_id_by_name.php
@@ -1,140 +1,142 @@
$pokemon_name, 'form_name' => '%'.$pokemon_form_name.'%']
+ );
+ $pokemon_form_id = 0;
+ if($query->rowCount() > 0) {
+ $res = $query->fetch();
+ $pokemon_form_id = $res['pokemon_form_id'];
+ $pokemon_id = $res['pokedex_id'];
}
+ // Write to log.
+ debug_log($pokemon_id,'P:');
+ debug_log($pokemon_form_name.' (ID: '.$pokemon_form_id.')','P:');
- // Explode if delimiter was found.
- $poke_name = $pokemon_name;
- $poke_form = "";
- if($delimiter != '') {
- $pokemon_name_form = explode($delimiter,$pokemon_name,2);
- $poke_name = trim($pokemon_name_form[0]);
- $poke_name = strtolower($poke_name);
- $poke_form = trim($pokemon_name_form[1]);
- $poke_form = strtolower($poke_form);
- debug_log($poke_name,'P NAME:');
- debug_log($poke_form,'P FORM:');
- }
-
- // Init id and write name to search to log.
- $pokemon_id = 0;
- $pokemon_form = ($poke_form!="")?$poke_form:"normal";
-
- // Set language
- $language = USERLANGUAGE;
- if($get_from_db) {
- // Fetch Pokemon form ID from database
- $stmt = $dbh->prepare("
- SELECT pokedex_id, pokemon_form_id
- FROM pokemon
- WHERE pokemon_name = :poke_name
- AND pokemon_form_name = :form_name
- LIMIT 1
- ");
- $stmt->execute(['poke_name' => $poke_name, 'form_name' => $pokemon_form]);
- $res = $stmt->fetch();
- if($stmt->rowCount() > 0) {
- $pokemon_form_id = $res['pokemon_form_id'];
- $pokemon_id = $res['pokedex_id'];
- }else {
- $pokemon_form_id = 0;
- }
- }else {
- // Get translation file
- $str = file_get_contents(CORE_LANG_PATH . '/pokemon.json');
- $json = json_decode($str, true);
- $search_result = "";
- foreach($json as $title => $translations) {
- // Try to find translation for userlanguage
- if(isset($translations[$language]) && ucfirst($poke_name) == $translations[$language]) {
- $search_result = $title;
- debug_log('Translation found for lang: '.$language, 'P:');
- debug_log('Translation result: '.$title, 'P:');
- break;
- // Also look for fallback in default language
- }elseif(ucfirst($poke_name) == $translations[DEFAULT_LANGUAGE]) {
- $search_result = $title;
- }
- }
- if($search_result != "") {
- $pokemon_id = str_replace('pokemon_id_','', $search_result);
- }else {
- // Debug log.
- info_log('Error! Pokedex ID could not be found for pokemon with name: ' . $poke_name);
- }
+ // Return pokemon_id and pokemon_form_id
+ return [$pokemon_id, $pokemon_form_id];
+ }
+ debug_log($pokemon_name,'P:');
- // Get form.
- // Works like this: Search form in language file via language, e.g. 'DE' and local form translation, e.g. 'Alola' for 'DE'.
- // In additon we are searching the DEFAULT_LANGUAGE and the key name for the form name.
- // Once we found the key name, e.g. 'pokemon_form_attack', get the form name 'attack' from it via str_replace'ing the prefix 'pokemon_form'.
- if($pokemon_id != 0 && isset($poke_form) && !empty($poke_form) && $poke_form != 'normal') {
- debug_log('Searching for pokemon form: ' . $poke_form);
+ // Explode pokemon name in case we have a form too.
+ $delimiter = '';
+ if (strpos($pokemon_name, '-') !== false) {
+ $delimiter = '-';
+ } else if (strpos($pokemon_name, ',') !== false) {
+ $delimiter = ',';
+ } else if (strpos($pokemon_name, '_') !== false) {
+ $delimiter = '_';
+ }
- // Get forms translation file
- $str_form = file_get_contents(CORE_LANG_PATH . '/pokemon_forms.json');
- $json_form = json_decode($str_form, true);
+ // Explode if delimiter was found.
+ $poke_name = $pokemon_name;
+ $poke_form = "";
+ if($delimiter != '') {
+ $pokemon_name_form = explode($delimiter,$pokemon_name,2);
+ $poke_name = trim($pokemon_name_form[0]);
+ $poke_name = strtolower($poke_name);
+ $poke_form = trim($pokemon_name_form[1]);
+ $poke_form = strtolower($poke_form);
+ debug_log($poke_name,'P NAME:');
+ debug_log($poke_form,'P FORM:');
+ }
- // Search pokemon form in json
- foreach($json_form as $key_form => $jform) {
- // Stop search if we found it.
- if ($jform[$language] === ucfirst($poke_form)) {
- $pokemon_form = str_replace('pokemon_form_','',$key_form);
- debug_log('Found pokemon form by user language: ' . $language);
- break;
+ $pokemon_form = ($poke_form != "") ? $poke_form : "normal";
- // Try DEFAULT_LANGUAGE too.
- } else if ($jform[DEFAULT_LANGUAGE] === ucfirst($poke_form)) {
- $pokemon_form = str_replace('pokemon_form_','',$key_form);
- debug_log('Found pokemon form by default language: ' . DEFAULT_LANGUAGE);
- break;
+ // Set language
+ $language = $botUser->userLanguage;
- // Try key name.
- } else if ($key_form === ('pokemon_form_' . $poke_form)) {
- $pokemon_form = str_replace('pokemon_form_','',$key_form);
- debug_log('Found pokemon form by json key name: pokemon_form_' . $key_form);
- break;
- }
- }
- }
- // Fetch Pokemon form ID from database
- $stmt = $dbh->prepare("
- SELECT pokemon_form_id
- FROM pokemon
- WHERE pokedex_id = :pokedex_id
- AND pokemon_form_name = :form_name
- LIMIT 1
- ");
- $stmt->execute(['pokedex_id' => $pokemon_id, 'form_name' => $pokemon_form]);
- $res = $stmt->fetch();
- $pokemon_form_id = isset($res['pokemon_form_id']) ? $res['pokemon_form_id'] : '';
+ // Get translation file
+ $str = file_get_contents(BOT_LANG_PATH . '/pokemon.json');
+ $json = json_decode($str, true);
+ $search_result = "";
+ foreach($json as $title => $translations) {
+ // Try to find translation for userlanguage
+ if(isset($translations[$language]) && ucfirst($poke_name) == $translations[$language]) {
+ $search_result = $title;
+ debug_log('Translation found for lang: '.$language, 'P:');
+ debug_log('Translation result: '.$title, 'P:');
+ break;
+ // Also look for fallback in default language
+ }elseif(ucfirst($poke_name) == $translations[DEFAULT_LANGUAGE]) {
+ $search_result = $title;
}
+ }
+ if($search_result != "") {
+ $pokemon_id = str_replace('pokemon_id_','', $search_result);
+ }else {
+ // Debug log.
+ info_log('Error! Pokedex ID could not be found for pokemon with name: ' . $poke_name);
+ }
- // Write to log.
- debug_log($pokemon_id,'P:');
- debug_log($pokemon_form.' (ID: '.$pokemon_form_id.')','P:');
+ // Get form.
+ // Works like this: Search form in language file via language, e.g. 'DE' and local form translation, e.g. 'Alola' for 'DE'.
+ // In additon we are searching the DEFAULT_LANGUAGE and the key name for the form name.
+ // Once we found the key name, e.g. 'pokemon_form_attack', get the form name 'attack' from it via str_replace'ing the prefix 'pokemon_form'.
+ if($pokemon_id != 0 && isset($poke_form) && !empty($poke_form) && $poke_form != 'normal') {
+ debug_log('Searching for pokemon form: ' . $poke_form);
- // Set pokemon form.
- $pokemon_id = $pokemon_id . '-' . $pokemon_form_id;
+ // Get forms translation file
+ $str_form = file_get_contents(BOT_LANG_PATH . '/pokemon_forms.json');
+ $json_form = json_decode($str_form, true);
- // Return pokemon_id
- return $pokemon_id;
-}
+ // Search pokemon form in json
+ foreach($json_form as $key_form => $jform) {
+ // Stop search if we found it.
+ if ($jform[$language] === ucfirst($poke_form)) {
+ $pokemon_form = str_replace('pokemon_form_','',$key_form);
+ debug_log('Found pokemon form by user language: ' . $language);
+ break;
+
+ // Try DEFAULT_LANGUAGE too.
+ } else if ($jform[DEFAULT_LANGUAGE] === ucfirst($poke_form)) {
+ $pokemon_form = str_replace('pokemon_form_','',$key_form);
+ debug_log('Found pokemon form by default language: ' . DEFAULT_LANGUAGE);
+ break;
+
+ // Try key name.
+ } else if ($key_form === ('pokemon_form_' . $poke_form)) {
+ $pokemon_form = str_replace('pokemon_form_','',$key_form);
+ debug_log('Found pokemon form by json key name: pokemon_form_' . $key_form);
+ break;
+ }
+ }
+ }
+ // Fetch Pokemon form ID from database
+ $query = my_query('
+ SELECT pokemon_form_id
+ FROM pokemon
+ WHERE pokedex_id = :pokedex_id
+ AND pokemon_form_name = :form_name
+ LIMIT 1
+ ', ['pokedex_id' => $pokemon_id, 'form_name' => $pokemon_form]
+ );
+ $res = $query->fetch();
+ $pokemon_form_id = isset($res['pokemon_form_id']) ? $res['pokemon_form_id'] : 0;
+
+ // Write to log.
+ debug_log($pokemon_id,'P:');
+ debug_log($pokemon_form.' (ID: '.$pokemon_form_id.')','P:');
-?>
+ // Return pokemon_id and pokemon_form_id
+ return [$pokemon_id, $pokemon_form_id];
+}
diff --git a/logic/get_pokemon_info.php b/logic/get_pokemon_info.php
index 19c575aa..295d87fe 100644
--- a/logic/get_pokemon_info.php
+++ b/logic/get_pokemon_info.php
@@ -5,26 +5,24 @@
* @param $pokemon_form_id
* @return array
*/
-function get_pokemon_info($pokemon_id, $pokemon_form_id)
+function get_pokemon_info($pokedex_id, $pokemon_form_id)
{
- /** Example:
- * Raid boss: Mewtwo (#ID)
- * Weather: Icons
- * CP: CP values (Boosted CP values)
- * Shiny: Shiny
- */
- $info = '';
- $info .= getTranslation('raid_boss') . ': ' . get_local_pokemon_name($pokemon_id, $pokemon_form_id) . ' (#' . $pokemon_id . ')' . CR . CR;
- $poke_raid_level = get_raid_level($pokemon_id, $pokemon_form_id);
- $poke_cp = get_formatted_pokemon_cp($pokemon_id, $pokemon_form_id);
- $poke_weather = get_pokemon_weather($pokemon_id, $pokemon_form_id);
- $poke_shiny = get_pokemon_shiny_status($pokemon_id, $pokemon_form_id);
- $info .= getTranslation('pokedex_raid_level') . ': ' . getTranslation($poke_raid_level . 'stars') . CR;
- $info .= (empty($poke_cp)) ? (getTranslation('pokedex_cp') . CR) : $poke_cp . CR;
- $info .= getTranslation('pokedex_weather') . ': ' . get_weather_icons($poke_weather) . CR;
- $info .= (($poke_shiny == 1) ? (getTranslation('shiny')) : (getTranslation('not_shiny'))) . CR . CR;
-
- return $info;
+ $query = my_query('
+ SELECT id, min_cp, max_cp, min_weather_cp, max_weather_cp, weather, shiny,
+ (SELECT raid_level
+ FROM raid_bosses
+ WHERE pokedex_id = :pokedex_id
+ AND pokemon_form_id = :pokemon_form_id
+ AND scheduled = 0 LIMIT 1) as raid_level
+ FROM pokemon
+ WHERE pokedex_id = :pokedex_id
+ AND pokemon_form_id = :pokemon_form_id
+ LIMIT 1
+ ', [
+ 'pokedex_id' => $pokedex_id,
+ 'pokemon_form_id' => $pokemon_form_id
+ ]);
+ $result = $query->fetch();
+ if(is_array($result) && $result['raid_level'] == NULL) $result['raid_level'] = 0;
+ return $result;
}
-
-?>
diff --git a/logic/get_pokemon_shiny_status.php b/logic/get_pokemon_shiny_status.php
deleted file mode 100644
index 0c2c9527..00000000
--- a/logic/get_pokemon_shiny_status.php
+++ /dev/null
@@ -1,31 +0,0 @@
-fetch();
- debug_log($shiny, 'Per db, shiny status is:');
-
- return $shiny['shiny'];
- } else {
- return 0;
- }
-}
-
-?>
diff --git a/logic/get_pokemon_weather.php b/logic/get_pokemon_weather.php
deleted file mode 100644
index fa4a95b5..00000000
--- a/logic/get_pokemon_weather.php
+++ /dev/null
@@ -1,30 +0,0 @@
-fetch();
-
- return $ww['weather'];
- } else {
- return 0;
- }
-}
-
-?>
diff --git a/logic/get_raid.php b/logic/get_raid.php
index d4f3e352..0628a464 100644
--- a/logic/get_raid.php
+++ b/logic/get_raid.php
@@ -4,52 +4,57 @@
* @param $raid_id
* @return array
*/
+require_once(LOGIC_PATH . '/get_user.php');
require_once(LOGIC_PATH . '/resolve_raid_boss.php');
function get_raid($raid_id)
{
- global $dbh;
- // Remove all non-numeric characters
- $raidid = preg_replace( '/[^0-9]/', '', $raid_id );
+ // Remove all non-numeric characters
+ $raidid = preg_replace( '/[^0-9]/', '', $raid_id );
- // Get the raid data by id.
- $rs = my_query(
- '
- SELECT raids.pokemon, raids.pokemon_form, raids.id, raids.user_id, raids.spawn, raids.start_time, raids.end_time, raids.gym_team, raids.gym_id, raids.level, raids.move1, raids.move2, raids.gender, raids.event, raids.costume, raids.event_note,
- gyms.lat, gyms.lon, gyms.address, gyms.gym_name, gyms.ex_gym, gyms.gym_note,
- users.name, users.trainername, users.nick,
- events.name as event_name, events.description as event_description, events.vote_key_mode as event_vote_key_mode, events.time_slots as event_time_slots, events.raid_duration as event_raid_duration, events.hide_raid_picture as event_hide_raid_picture, events.poll_template as event_poll_template,
- TIME_FORMAT(TIMEDIFF(end_time, UTC_TIMESTAMP()) + INTERVAL 1 MINUTE, \'%k:%i\') AS t_left
- FROM raids
- LEFT JOIN gyms
- ON raids.gym_id = gyms.id
- LEFT JOIN users
- ON raids.user_id = users.user_id
- LEFT JOIN events
- ON events.id = raids.event
- WHERE raids.id = '.$raidid.'
- LIMIT 1
- '
- );
- // Get the row.
- $raid = $rs->fetch();
+ // Get the raid data by id.
+ $rs = my_query('
+ SELECT raids.pokemon, raids.pokemon_form, raids.id, raids.user_id, raids.spawn, raids.start_time, raids.end_time, raids.gym_team, raids.gym_id, raids.level, raids.move1, raids.move2, raids.gender, raids.event, raids.costume, raids.event_note,
+ gyms.lat, gyms.lon, gyms.address, gyms.gym_name, gyms.ex_gym, gyms.gym_note,
+ users.name, users.trainername, users.nick, users.display_name,
+ events.name as event_name, events.description as event_description, events.vote_key_mode as event_vote_key_mode, events.time_slots as event_time_slots, events.raid_duration as event_raid_duration, events.hide_raid_picture as event_hide_raid_picture, events.pokemon_title as event_pokemon_title, events.poll_template as event_poll_template,
+ TIME_FORMAT(TIMEDIFF(end_time, UTC_TIMESTAMP()) + INTERVAL 1 MINUTE, \'%k:%i\') AS t_left,
+ IF(UTC_TIMESTAMP() > end_time, 1, 0) as raid_ended
+ FROM raids
+ LEFT JOIN gyms
+ ON raids.gym_id = gyms.id
+ LEFT JOIN users
+ ON raids.user_id = users.user_id
+ LEFT JOIN events
+ ON events.id = raids.event
+ WHERE raids.id = ?
+ LIMIT 1
+ ', [$raidid]
+ );
+ // Get the row.
+ $raid = $rs->fetch();
- // Resolve the boss id
- $resolved_boss = resolve_raid_boss($raid['pokemon'], $raid['pokemon_form'], $raid['spawn'], $raid['level']);
- $raid['pokemon'] = $resolved_boss['pokedex_id'];
- $raid['pokemon_form'] = $resolved_boss['pokemon_form_id'];
+ if ($rs->rowCount() == 0) {
+ // Fail gracefully when a raid id is unknown
+ edit_message($GLOBALS['update'], getTranslation('internal_error'), []);
+ exit;
+ }
+ // Resolve the boss id
+ $resolved_boss = resolve_raid_boss($raid['pokemon'], $raid['pokemon_form'], $raid['spawn'], $raid['level']);
+ $raid['pokemon'] = $resolved_boss['pokedex_id'];
+ $raid['pokemon_form'] = $resolved_boss['pokemon_form_id'];
- if (!$raid){
- $rs = my_query("SELECT * FROM raids WHERE raids.id = {$raid_id}");
- $row = json_encode($rs->fetch());
- throw new Exception("Failed to fetch raid id {$raid_id}, data we do have on it: {$row}");
- }
+ $raid['shadow'] = in_array($raid['level'], RAID_LEVEL_SHADOW) ? 1 : 0;
- // Check trainername
- $raid = check_trainername($raid);
+ if (!$raid){
+ $rs = my_query('SELECT * FROM raids WHERE raids.id = ?', [$raid_id]);
+ $row = json_encode($rs->fetch());
+ throw new Exception("Failed to fetch raid id {$raid_id}, data we do have on it: {$row}");
+ }
- debug_log($raid);
+ // Check trainername
+ $raid = check_trainername($raid);
- return $raid;
-}
+ debug_log($raid);
-?>
+ return $raid;
+}
diff --git a/logic/get_raid_times.php b/logic/get_raid_times.php
index 255589f8..6f408e6e 100644
--- a/logic/get_raid_times.php
+++ b/logic/get_raid_times.php
@@ -1,21 +1,14 @@
RAID_POLL_POKEMON_NAME_FIRST_LINE == true) {
- $msg .= get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form'], $override_language) . ':' . SP;
+ $msg .= get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form'], $language) . ':' . SP;
} else {
- $msg .= $getTypeTranslation('raid') . ':' . SP;
+ $msg .= getTranslation('raid', $language) . ':' . SP;
}
}
// Is the raid in the same week?
@@ -67,7 +60,7 @@ function get_raid_times($raid, $override_language = true, $unformatted = false)
// Adds 'at 17:00' to the output.
if($unformatted == false) {
- $msg .= SP . $getTypeTranslation('raid_egg_opens_at');
+ $msg .= SP . getTranslation('raid_egg_opens_at', $language);
}
$msg .= SP . dt2time($raid['start_time']);
} else {
@@ -89,5 +82,3 @@ function get_raid_times($raid, $override_language = true, $unformatted = false)
return $msg;
}
-
-?>
diff --git a/logic/get_remote_users_count.php b/logic/get_remote_users_count.php
index 1ab72065..f5c98aa3 100644
--- a/logic/get_remote_users_count.php
+++ b/logic/get_remote_users_count.php
@@ -6,44 +6,48 @@
* @param $attend_time
* @return int
*/
-function get_remote_users_count($raid_id, $user_id, $attend_time = false)
+function get_remote_users_count($raidId, $userId, $attendTime = false)
{
- global $config;
+ global $config;
- if(!$attend_time) {
- // If attend time is not given, get the one user has already voted for from database
- $att_sql = "(
- SELECT attend_time
- FROM attendance
- WHERE raid_id = {$raid_id}
- AND user_id = {$user_id}
- LIMIT 1
- )";
- }else {
- // Use given attend time (needed when voting for new time)
- $att_sql = "'{$attend_time}'";
- }
+ $attBinds['userId'] = $userId;
+ if($attendTime) {
+ $attSql = ':attTime';
+ $attBinds['attTime'] = $attendTime;
+ }else {
+ // If attend time is not given, get the one user has already voted for from database
+ $attSql = '(
+ SELECT attend_time
+ FROM attendance
+ WHERE raid_id = :raidId
+ AND user_id = :userId
+ LIMIT 1
+ )';
+ $attBinds['raidId'] = $raidId;
+ $attBinds['userId'] = $userId;
+ }
- // Check if max remote users limit is already reached!
- // Ignore max limit if attend time is 'Anytime'
- $rs = my_query(
- "
- SELECT IF(attend_time = '" . ANYTIME . "', 0, sum(1 + extra_in_person)) AS remote_users
- FROM (SELECT DISTINCT user_id, extra_in_person, attend_time FROM attendance WHERE remote = 1 AND cancel = 0 AND raid_done = 0) as T
- WHERE attend_time = {$att_sql}
- GROUP BY attend_time
- "
- );
+ // Check if max remote users limit is already reached!
+ // Ignore max limit if attend time is 'Anytime'
+ $rs = my_query(
+ '
+ SELECT CASE WHEN attend_time = \'' . ANYTIME . '\'
+ THEN 0
+ ELSE
+ sum(CASE WHEN remote = 1 THEN 1 + extra_in_person ELSE 0 END + extra_alien) END AS remote_users
+ FROM (SELECT DISTINCT user_id, extra_in_person, extra_alien, remote, attend_time FROM attendance WHERE (remote = 1 or extra_alien > 0) AND cancel = 0 AND raid_done = 0 and user_id != :userId) as T
+ WHERE attend_time = ' . $attSql . '
+ GROUP BY attend_time
+ ', $attBinds
+ );
- // Get the answer.
- $answer = $rs->fetch();
- $remote_users = empty($answer) ? 0 : $answer['remote_users'];
+ // Get the answer.
+ $answer = $rs->fetch();
+ $remoteUsers = empty($answer) ? 0 : $answer['remote_users'];
- // Write to log.
- debug_log($remote_users, 'Remote participants so far:');
- debug_log($config->RAID_REMOTEPASS_USERS_LIMIT, 'Maximum remote participants:');
+ // Write to log.
+ debug_log($remoteUsers, 'Remote participants so far:');
+ debug_log($config->RAID_REMOTEPASS_USERS_LIMIT, 'Maximum remote participants:');
- return $remote_users;
+ return $remoteUsers;
}
-
-?>
diff --git a/logic/get_user.php b/logic/get_user.php
index 46c554a3..99bf1db4 100644
--- a/logic/get_user.php
+++ b/logic/get_user.php
@@ -4,65 +4,52 @@
* @param $user_id
* @param $public
* @param $return_row
- * @return message
+ * @return array|string message
*/
function get_user($user_id, $public = true, $return_row = false)
{
- global $config;
- // Get user details.
- $rs = my_query(
- "
- SELECT *
- FROM users
- WHERE user_id = {$user_id}
- "
- );
+ global $config;
+ // Get user details.
+ $rs = my_query('
+ SELECT *
+ FROM users
+ WHERE user_id = ?
+ ', [$user_id]
+ );
+ // Fetch the row.
+ $row = $rs->fetch();
+ // Build message string.
+ $msg = '';
- // Fetch the row.
- $row = $rs->fetch();
- // Build message string.
- $msg = '';
+ $display_name = ['',''];
+ if(!$public) $display_name[intval($row['display_name'])] = '-> ';
- $display_name = ['',''];
- if(!$public) $display_name[intval($row['display_name'])] = '-> ';
+ // Add name.
+ $msg .= $display_name[0] . getTranslation('name') . ': ' . htmlspecialchars($row['name']) . '' . CR;
+ // Add name.
+ $msg .= $display_name[1] . getTranslation('trainername') . ': ' . (check_for_empty_string($row['trainername']) ? getTranslation('not_set') : $row['trainername'] ) . CR;
- // Add name.
- $msg .= $display_name[0] . getTranslation('name') . ': ' . htmlspecialchars($row['name']) . '' . CR;
- // Add name.
- $msg .= $display_name[1] . getTranslation('trainername') . ': ' . (check_for_empty_string($row['trainername']) ? getTranslation('not_set') : $row['trainername'] ) . CR;
+ if($config->RAID_POLL_SHOW_TRAINERCODE){ // is Trainercode enabled?
+ $trainercode = ($row['trainercode'] === NULL ? getTranslation('not_set') : $row['trainercode']);
+ $msg .= getTranslation('trainercode') . ': ' . $trainercode . CR;
+ }
- if($config->RAID_POLL_SHOW_TRAINERCODE){ // is Trainercode enabled?
- // Unknown trainercode.
- if ($row['trainercode'] === NULL) {
- $msg .= getTranslation('trainercode') . ': ' . getTranslation('not_set') . CR;
- // Known Trainercode.
- } else {
- $msg .= getTranslation('trainercode') . ': ' . $row['trainercode'] . CR;
- }
- }
+ $team = ($row['team'] === NULL) ? $GLOBALS['teams']['unknown'] : $GLOBALS['teams'][$row['team']];
+ $msg .= getTranslation('team') . ': ' . $team . CR;
- // Unknown team.
- if ($row['team'] === NULL) {
- $msg .= getTranslation('team') . ': ' . $GLOBALS['teams']['unknown'] . CR;
- // Known team.
- } else {
- $msg .= getTranslation('team') . ': ' . $GLOBALS['teams'][$row['team']] . CR;
- }
-
- // Add level.
- if ($row['level'] != 0) {
- $msg .= getTranslation('level') . ': ' . $row['level'] . '' . CR . CR;
- }
- if(!$public) $msg .= getTranslation('display_name_explanation') . CR;
+ // Add level.
+ if ($row['level'] != 0) {
+ $msg .= getTranslation('level') . ': ' . $row['level'] . '' . CR . CR;
+ }
+ if(!$public) $msg .= getTranslation('display_name_explanation') . CR;
- if($return_row) {
- return [
- 'message' => $msg,
- 'row' => $row
- ];
- }else {
- return $msg;
- }
+ if($return_row) {
+ return [
+ 'message' => $msg,
+ 'row' => $row
+ ];
+ }
+ return $msg;
}
/**
@@ -71,22 +58,22 @@ function get_user($user_id, $public = true, $return_row = false)
* @return array $row
*/
function check_trainername($row){
- global $config;
- // if Custom Trainername is enabled by config
- if($config->CUSTOM_TRAINERNAME == false || check_for_empty_string($row['trainername']) || (isset($row['display_name']) && $row['display_name'] != 1)){ // trainername not set by user
- // check if Telegram-@Nick is set
- if(!check_for_empty_string($row['nick']) && $config->RAID_POLL_SHOW_NICK_OVER_NAME){
- // set Telegram-@Nick as Name inside the bot
- $row['name'] = $row['nick'];
- }else{
- // leave Telegram-name as it is (Trainername and Telegram-@Nick were not configured by user)
- }
+ global $config;
+ // if Custom Trainername is enabled by config
+ if($config->CUSTOM_TRAINERNAME == false || check_for_empty_string($row['trainername']) || $row['display_name'] != 1){ // trainername not set by user
+ // check if Telegram-@Nick is set
+ if(!check_for_empty_string($row['nick']) && $config->RAID_POLL_SHOW_NICK_OVER_NAME){
+ // set Telegram-@Nick as Name inside the bot
+ $row['name'] = $row['nick'];
}else{
- // Trainername is configured by User
- $row['name'] = $row['trainername'];
+ // leave Telegram-name as it is (Trainername and Telegram-@Nick were not configured by user)
}
+ }else{
+ // Trainername is configured by User
+ $row['name'] = $row['trainername'];
+ }
- return $row;
+ return $row;
}
/**
@@ -100,4 +87,3 @@ function check_for_empty_string($string){
}
return false;
}
-?>
diff --git a/logic/get_weather_icons.php b/logic/get_weather_icons.php
index 1d6461f6..7b642ba1 100644
--- a/logic/get_weather_icons.php
+++ b/logic/get_weather_icons.php
@@ -6,28 +6,23 @@
*/
function get_weather_icons($weather_value)
{
- if($weather_value > 0) {
- // Get length of arg and split arg
- $weather_value_length = strlen((string)$weather_value);
- $weather_value_string = str_split((string)$weather_value);
+ if($weather_value == 0) return '';
+ // Get length of arg and split arg
+ $weather_value_length = strlen((string)$weather_value);
+ $weather_value_string = str_split((string)$weather_value);
- // Init weather icons string.
- $weather_icons = '';
+ // Init weather icons string.
+ $weather_icons = '';
- // Add icons to string.
- for ($i = 0; $i < $weather_value_length; $i = $i + 1) {
- // Get weather icon from constants
- $weather_icons .= $GLOBALS['weather'][$weather_value_string[$i]];
- $weather_icons .= ' ';
- }
+ // Add icons to string.
+ for ($i = 0; $i < $weather_value_length; $i = $i + 1) {
+ // Get weather icon from constants
+ $weather_icons .= $GLOBALS['weather'][$weather_value_string[$i]];
+ $weather_icons .= ' ';
+ }
- // Trim space after last icon
- $weather_icons = rtrim($weather_icons);
- } else {
- $weather_icons = '';
- }
+ // Trim space after last icon
+ $weather_icons = rtrim($weather_icons);
- return $weather_icons;
+ return $weather_icons;
}
-
-?>
diff --git a/logic/group_code_keys.php b/logic/group_code_keys.php
index 82b14723..6974311e 100644
--- a/logic/group_code_keys.php
+++ b/logic/group_code_keys.php
@@ -8,61 +8,48 @@
*/
function group_code_keys($raid_id, $action, $arg)
{
- global $config;
-
- // Get current group code
- $data = explode("-", $arg);
- $poke1 = $data[0];
- $poke2 = $data[1];
- $poke3 = $data[2];
- $code_action = $data[3];
-
- // Send and reset values
- $reset_arg = '0-0-0-add';
- $send_arg = $poke1 . '-' . $poke2 . '-' . $poke3 . '-send';
-
- // Init empty keys array.
- $keys = [];
-
- // Show group code buttons?
- if($poke3 == 0) {
-
- // Add keys 1 to 9, where 1 = first pokemon, 9 = last pokemon
- /**
- * 1 2 3
- * 4 5 6
- * 7 8 9
- */
-
- $rc_poke = (explode(',',$config->RAID_CODE_POKEMON));
- foreach($rc_poke as $i) {
- // New code
- $new_code = ($poke1 == 0) ? ($i . '-0-0-add') : (($poke2 == 0) ? ($poke1 . '-' . $i . '-0-add') : (($poke3 == 0) ? ($poke1 . '-' . $poke2 . '-' . $i . '-add') : ($poke1 . '-' . $poke2 . '-' . $poke3 . '-send')));
- // Set keys.
- $keys[] = array(
- 'text' => get_local_pokemon_name($i, '0'),
- 'callback_data' => $raid_id . ':' . $action . ':' . $new_code
- );
- }
- } else {
- // Send
- $keys[] = array(
- 'text' => EMOJI_INVITE,
- 'callback_data' => $raid_id . ':' . $action . ':' . $send_arg
- );
+ global $config;
+
+ // Get current group code
+ $data = explode('-', $arg);
+ $poke1 = $data[0];
+ $poke2 = $data[1];
+ $poke3 = $data[2];
+
+ // Send and reset values
+ $reset_arg = '0-0-0-add';
+ $send_arg = $poke1 . '-' . $poke2 . '-' . $poke3 . '-send';
+
+ // Init empty keys array.
+ $keys = [];
+
+ // Show group code buttons?
+ if($poke3 == 0) {
+
+ // Add keys 1 to 9, where 1 = first pokemon, 9 = last pokemon
+ /**
+ * 1 2 3
+ * 4 5 6
+ * 7 8 9
+ */
+
+ $rc_poke = (explode(',',$config->RAID_CODE_POKEMON));
+ foreach($rc_poke as $i) {
+ // New code
+ $new_code = ($poke1 == 0) ? ($i . '-0-0-add') : (($poke2 == 0) ? ($poke1 . '-' . $i . '-0-add') : (($poke3 == 0) ? ($poke1 . '-' . $poke2 . '-' . $i . '-add') : ($poke1 . '-' . $poke2 . '-' . $poke3 . '-send')));
+ // Set keys.
+ $keys[] = button(get_local_pokemon_name($i, '0'), [$action, 'r' => $raid_id, 'a' => $new_code]);
}
+ } else {
+ // Send
+ $keys[] = button(EMOJI_INVITE, [$action, 'r' => $raid_id, 'a' => $send_arg]);
+ }
- // Reset
- $keys[] = array(
- 'text' => getTranslation('reset'),
- 'callback_data' => $raid_id . ':' . $action . ':' . $reset_arg
- );
+ // Reset
+ $keys[] = button(getTranslation('reset'), [$action, 'r' => $raid_id, 'a' => $reset_arg]);
- // Get the inline key array.
- $keys = inline_key_array($keys, 3);
+ // Get the inline key array.
+ $keys = inline_key_array($keys, 3);
- return $keys;
+ return $keys;
}
-
-
-?>
diff --git a/logic/gymMenu.php b/logic/gymMenu.php
new file mode 100644
index 00000000..f97ab654
--- /dev/null
+++ b/logic/gymMenu.php
@@ -0,0 +1,285 @@
+ 'edit_raidlevel',
+ 'list' => 'list_raid',
+ 'gym' => 'gym_edit_details',
+];
+
+function resolveDefaultGymarea($userId) {
+ global $config;
+ if(!$config->ENABLE_GYM_AREAS) return false;
+ $q = my_query('SELECT gymarea FROM users WHERE user_id = ? LIMIT 1', [$userId]);
+ $userGymarea = $q->fetch()['gymarea'];
+ return $userGymarea !== NULL ? $userGymarea : $config->DEFAULT_GYM_AREA;
+}
+/**
+ * Raid gym first letter selection
+ * @param string $buttonAction Action that is performed by gym letter keys
+ * @param bool $showHidden Show only hidden gyms?
+ * @param int $stage
+ * @param string $firstLetter
+ * @param int|false $gymareaId
+ * @return array
+ */
+function gymMenu($buttonAction, $showHidden, $stage, $firstLetter = false, $gymareaId = false) {
+
+ global $config, $botUser;
+ // Stage 0: Only gym area keys
+ // Stage 1: Gym letter keys (or just gym names if 20 or less gyms were found) with areas under them
+ // Stage 2: Gym names
+ $stage = ($config->ENABLE_GYM_AREAS && $stage == 1 && $gymareaId == false) ? 0 : $stage;
+ [$gymareaName, $gymareaKeys, $gymareaQuery] = ($config->ENABLE_GYM_AREAS) ? getGymareas($gymareaId, $stage, $buttonAction) : ['', [], ''];
+ if($stage == 2 && $firstLetter != '')
+ $gymKeys = createGymListKeysByFirstLetter($firstLetter, $showHidden, $gymareaQuery, $buttonAction, $gymareaId);
+ else
+ $gymKeys = createGymKeys($buttonAction, $showHidden, $gymareaId, $gymareaQuery, $stage);
+ $keys = ($stage == 0) ? [] : $gymKeys[0];
+ if($stage == 0) {
+ $title = getTranslation('select_gym_area');
+ }elseif($stage == 1) {
+ if($config->ENABLE_GYM_AREAS) {
+ $title = $gymKeys[1] === true ? getTranslation('select_gym_first_letter_or_gym_area') : getTranslation('select_gym_name_or_gym_area');
+ }else {
+ $title = $gymKeys[1] === true ? getTranslation('select_gym_first_letter') : getTranslation('select_gym_name');
+ }
+ }else {
+ $title = getTranslation('select_gym_name');
+ }
+ $gymareaTitle = '' . $title . '' . CR;
+ $gymareaTitle.= ($gymareaName != '') ? CR . CR . getTranslation('current_gymarea') . ': ' . $gymareaName : '';
+
+ $gymareaTitle.= ($config->RAID_VIA_LOCATION && $buttonAction == 'create' ? (CR . CR . getTranslation('send_location')) : '');
+
+ if($config->RAID_VIA_LOCATION_FUNCTION == 'remote' && $buttonAction == 'list') {
+ $query_remote = my_query('SELECT count(*) as count FROM raids LEFT JOIN gyms on raids.gym_id = gyms.id WHERE raids.end_time > (UTC_TIMESTAMP() - INTERVAL 10 MINUTE) AND temporary_gym = 1');
+ if($query_remote->fetch()['count'] > 0) {
+ $keys[][] = button(getTranslation('remote_raids'), 'list_remote_gyms');
+ }
+ }
+ // Merge keys.
+ if(($stage < 2 or ($stage == 2 && $firstLetter == '')) && $showHidden == 0) {
+ $keys = array_merge($keys, inline_key_array($gymareaKeys, 2));
+ }
+ // Add key for hidden gyms.
+ if($buttonAction == 'gym') {
+ if($stage == 1 && $showHidden == 0) {
+ // Add key for hidden gyms.
+ $h_keys[][] = button(getTranslation('hidden_gyms'), ['gymMenu', 'h' => 1, 'a' => 'gym', 'ga' => $gymareaId]);
+ $keys = array_merge($h_keys, $keys);
+ }
+ if($stage == 0 or $stage == 1 && $botUser->accessCheck('gym-add', true)) {
+ $keys[][] = button(getTranslation('gym_create'), 'gym_create');
+ }
+ }
+ if((($stage == 1 or ($stage == 2 && $firstLetter == '')) && $config->DEFAULT_GYM_AREA === false)) {
+ $backKey = button(getTranslation('back'), ['gymMenu', 'stage' => 0, 'a' => $buttonAction]);
+ }elseif($stage == 2 && $firstLetter !== '') {
+ $backKey = button(getTranslation('back'), ['gymMenu', 'stage' => 1, 'a' => $buttonAction, 'h' => $showHidden, 'ga' => $gymareaId]);
+ }
+ $abortKey = button(getTranslation('abort'), 'exit');
+ if (isset($backKey)) {
+ $keys[] = [$backKey, $abortKey];
+ }else{
+ $keys[] = [$abortKey];}
+ return ['keys' => $keys, 'gymareaTitle' => $gymareaTitle];
+}
+
+/**
+ * @param int $gymareaId
+ * @param int $stage
+ * @param string $buttonAction
+ * @return array [$gymareaName, $gymareaKeys, $query]
+ */
+function getGymareas($gymareaId, $stage, $buttonAction) {
+ $gymareaKeys = $points = [];
+ $gymareaName = '';
+ $json = json_decode(file_get_contents(botSpecificConfigFile('geoconfig_gym_areas.json')), 1);
+ foreach($json as $area) {
+ if($gymareaId == $area['id']) {
+ foreach($area['path'] as $point) {
+ $points[] = $point[0].' '.$point[1];
+ }
+ $gymareaName = $area['name'];
+ if($points[0] != $points[count($points)-1]) $points[] = $points[0];
+ }
+ if ($stage != 0 && $gymareaId == $area['id']) continue;
+ $gymareaKeys[] = button($area['name'], ['gymMenu', 'a' => $buttonAction, 'stage' => 1, 'ga' => $area['id']]);
+
+ }
+ if(count($gymareaKeys) > 6 && $stage != 0) {
+ // If list of area buttons is getting too large, replace it with a key that opens a submenu
+ $gymareaKeys[] = button(getTranslation('gymareas'), ['gymMenu', 'a' => $buttonAction, 'stage' => 0]);
+ }
+ $polygon_string = implode(',', $points);
+ $query = count($points) > 0 ? 'AND ST_CONTAINS(ST_GEOMFROMTEXT(\'POLYGON(('.$polygon_string.'))\'), ST_GEOMFROMTEXT(CONCAT(\'POINT(\',lat,\' \',lon,\')\')))' : '';
+ return [$gymareaName, $gymareaKeys, $query];
+}
+
+/**
+ * @param string $buttonAction
+ * @param bool $showHidden
+ * @param int $gymareaId
+ * @param string $gymareaQuery
+ * @param int $stage
+ * @return array [keyArray, isArrayListOfLetters]
+ */
+function createGymKeys($buttonAction, $showHidden, $gymareaId, $gymareaQuery, $stage) {
+ global $config, $menuActions, $botUser;
+ // Show hidden gyms?
+ $show_gym = $showHidden ? 0 : 1;
+
+ if ($buttonAction == 'list') {
+ // Select only gyms with active raids
+ $queryConditions = '
+ LEFT JOIN raids
+ ON raids.gym_id = gyms.id
+ WHERE show_gym = ' . $show_gym . '
+ AND end_time > UTC_TIMESTAMP() ';
+ $eventQuery = 'event IS NULL';
+ if($botUser->accessCheck('ex-raids', true)) {
+ if($botUser->accessCheck('event-raids', true))
+ $eventQuery = '';
+ else
+ $eventQuery .= ' OR event = ' . EVENT_ID_EX;
+ }elseif($botUser->accessCheck('event-raids', true)) {
+ $eventQuery = 'event != ' . EVENT_ID_EX .' OR event IS NULL';
+ }
+ $eventQuery = ($eventQuery == '') ? ' ' : ' AND ('.$eventQuery.') ';
+ }else {
+ $eventQuery = ' ';
+ $queryConditions = ' WHERE show_gym = ' . $show_gym;
+ }
+ $rs_count = my_query('SELECT COUNT(gym_name) as count FROM gyms ' . $queryConditions . $eventQuery . $gymareaQuery);
+ $gym_count = $rs_count->fetch();
+
+ // Found 20 or less gyms, print gym names
+ if($gym_count['count'] <= 20) {
+ $keys = createGymListKeysByFirstLetter('', $showHidden, $gymareaQuery, $buttonAction, $gymareaId);
+ return $keys;
+ }
+
+ // If found over 20 gyms, print letters
+ $select = 'SELECT DISTINCT UPPER(SUBSTR(gym_name, 1, 1)) AS first_letter';
+ $group_order = ' ORDER BY 1';
+ // Special/Custom gym letters?
+ if(!empty($config->RAID_CUSTOM_GYM_LETTERS)) {
+ // Explode special letters.
+ $special_keys = explode(',', $config->RAID_CUSTOM_GYM_LETTERS);
+ $select = 'SELECT CASE ';
+ foreach($special_keys as $letter)
+ {
+ $letter = trim($letter);
+ debug_log($letter, 'Special gym letter:');
+ // Fix chinese chars, prior: $length = strlen($letter);
+ $length = strlen(mb_convert_encoding($letter, 'ISO-8859-1'));
+ $select .= SP . 'WHEN UPPER(LEFT(gym_name, ' . $length . ')) = \'' . $letter . '\' THEN UPPER(LEFT(gym_name, ' . $length . '))' . SP;
+ }
+ $select .= 'ELSE UPPER(LEFT(gym_name, 1)) END AS first_letter';
+ $group_order = ' GROUP BY 1 ORDER BY gym_name';
+ }
+ $rs = my_query(
+ $select .
+ ' FROM gyms ' .
+ $queryConditions . ' ' .
+ $gymareaQuery .
+ $group_order
+ );
+ while ($gym = $rs->fetch()) {
+ // Add first letter to keys array
+ $keys[] = button($gym['first_letter'], ['gymMenu', 'a' => $buttonAction, 'stage' => $stage+1, 'fl' => $gym['first_letter'], 'h' => $showHidden, 'ga' => $gymareaId]);
+ }
+
+ // Get the inline key array.
+ return [inline_key_array($keys, 4), true];
+}
+/**
+ * Raid edit gym keys with active raids marker.
+ * @param string $firstLetter
+ * @param bool $showHidden
+ * @param string $gymareaQuery
+ * @param string $buttonAction
+ * @return array
+ */
+function createGymListKeysByFirstLetter($firstLetter, $showHidden, $gymareaQuery = '', $buttonAction = '', $gymareaId = false) {
+ global $config, $menuActions, $botUser;
+ // Length of first letter.
+ // Fix chinese chars, prior: $first_length = strlen($first);
+ $first_length = strlen(mb_convert_encoding($firstLetter, 'ISO-8859-1'));
+
+ // Special/Custom gym letters?
+ $not = '';
+ if(!empty($config->RAID_CUSTOM_GYM_LETTERS) && $first_length == 1) {
+ // Explode special letters.
+ $special_keys = explode(',', $config->RAID_CUSTOM_GYM_LETTERS);
+
+ foreach($special_keys as $letter)
+ {
+ $letter = trim($letter);
+ debug_log($letter, 'Special gym letter:');
+ // Fix chinese chars, prior: $length = strlen($letter);
+ $length = strlen(mb_convert_encoding($letter, 'ISO-8859-1'));
+ $not .= SP . 'AND UPPER(LEFT(gym_name, ' . $length . ')) != UPPER(\'' . $letter . '\')' . SP;
+ }
+ }
+ $show_gym = $showHidden ? 0 : 1;
+
+ $eventQuery = 'event IS NULL';
+ if($botUser->accessCheck('ex-raids', true)) {
+ if($botUser->accessCheck('event-raids', true))
+ $eventQuery = '';
+ else
+ $eventQuery .= ' OR event = ' . EVENT_ID_EX;
+ }elseif($botUser->accessCheck('event-raids', true)) {
+ $eventQuery = 'event != ' . EVENT_ID_EX .' OR event IS NULL';
+ }
+ $eventQuery = ($eventQuery == '') ? ' ' : ' AND ('.$eventQuery.') ';
+
+ $letterQuery = ($firstLetter != '') ? 'AND UPPER(LEFT(gym_name, ' . $first_length . ')) = UPPER(\'' . $firstLetter . '\')' : '';
+
+ $query_collate = ($config->MYSQL_SORT_COLLATE != '') ? 'COLLATE ' . $config->MYSQL_SORT_COLLATE : '';
+ // Get gyms from database
+ $rs = my_query('
+ SELECT gyms.id, gyms.gym_name, gyms.ex_gym,
+ case when (select 1 from raids where gym_id = gyms.id and end_time > utc_timestamp() '.$eventQuery.' LIMIT 1) = 1 then 1 else 0 end as active_raid
+ FROM gyms
+ WHERE show_gym = ?
+ ' . $letterQuery . '
+ ' . $not . '
+ ' . $gymareaQuery . '
+ ORDER BY gym_name ' . $query_collate
+ , [$show_gym]
+ );
+
+ // Init empty keys array.
+ $keys = [];
+
+ while ($gym = $rs->fetch()) {
+ if ($buttonAction == 'list' && $gym['active_raid'] == 0) continue;
+ // Show Ex-Gym-Marker?
+ if($config->RAID_CREATION_EX_GYM_MARKER && $gym['ex_gym'] == 1) {
+ $ex_raid_gym_marker = (strtolower($config->RAID_EX_GYM_MARKER) == 'icon') ? EMOJI_STAR : $config->RAID_EX_GYM_MARKER;
+ $gym_name = $ex_raid_gym_marker . SP . $gym['gym_name'];
+ } else {
+ $gym_name = $gym['gym_name'];
+ }
+ // Add warning emoji for active raid
+ if ($gym['active_raid'] == 1) {
+ $gym_name = EMOJI_WARN . SP . $gym_name;
+ }
+ $callback = [
+ $menuActions[$buttonAction],
+ 'g' => $gym['id'],
+ 'ga' => $gymareaId,
+ 'fl' => $firstLetter,
+ 'h' => $showHidden,
+ ];
+ $keys[] = button($gym_name, $callback);
+ }
+
+ // Get the inline key array.
+ $keys = inline_key_array($keys, 1);
+
+ return [$keys, false];
+
+}
diff --git a/logic/history.php b/logic/history.php
index 2c243157..493940a1 100644
--- a/logic/history.php
+++ b/logic/history.php
@@ -1,50 +1,42 @@
rowcount() == 0) return false;
- while($date = $q->fetch()) {
- $day_keys[] = [
- 'text' => $date['day_disp'],
- 'callback_data' => $date['day'] . ':history:' . $date['current_y_m']
- ];
- if($current_y_m == '') $current_y_m = $date['current_y_m'];
- if($prev == false) $prev = $date['prev'];
- if($next == false) $next = $date['next'];
- }
- $keys = inline_key_array($day_keys,4);
+ if(strlen($current) == 7) {
+ // Reformat YYYY-MM to DATETIME
+ $current = '\''.$current.'-01 00:00:00\'';
+ }
+ $q = my_query('
+ SELECT DISTINCT DATE_FORMAT(start_time, "%d") as day, DATE_FORMAT(start_time, "%e") as day_disp, DATE_FORMAT('.$current.', "%Y-%m") as current_y_m,
+ if((SELECT count(*) FROM raids left join attendance on attendance.raid_id = raids.id where end_time < UTC_TIMESTAMP() and date_format(start_time, "%Y-%m") = date_format(DATE_SUB('.$current.', INTERVAL 1 MONTH), "%Y-%m") and attendance.id is not null limit 1), date_format(DATE_SUB('.$current.', INTERVAL 1 MONTH), "%Y-%m"), 0) as prev,
+ if((SELECT count(*) FROM raids left join attendance on attendance.raid_id = raids.id where end_time < UTC_TIMESTAMP() and date_format(start_time, "%Y-%m") = date_format(DATE_ADD('.$current.', INTERVAL 1 MONTH), "%Y-%m") and attendance.id is not null limit 1), date_format(DATE_ADD('.$current.', INTERVAL 1 MONTH), "%Y-%m"), 0) as next
+ FROM raids
+ LEFT JOIN attendance
+ ON attendance.raid_id = raids.id
+ WHERE end_time < UTC_TIMESTAMP()
+ AND date_format(start_time, "%Y-%m") = DATE_FORMAT('.$current.', "%Y-%m")
+ AND attendance.id IS NOT NULL
+ ORDER BY DATE_FORMAT(start_time, "%d") ASC
+ ');
+ $day_keys = [];
+ $current_y_m = '';
+ $prev = $next = false;
+ if($q->rowcount() == 0) return false;
+ while($date = $q->fetch()) {
+ $day_keys[] = button($date['day_disp'], ['history', 'd' => $date['day'], 'm' => $date['current_y_m']]);
+ if($current_y_m == '') $current_y_m = $date['current_y_m'];
+ if($prev == false) $prev = $date['prev'];
+ if($next == false) $next = $date['next'];
+ }
+ $keys = inline_key_array($day_keys,4);
- $msg = getTranslation('history_title') . CR . CR;
- $msg .= getTranslation('history_displaying_month') . ' ' . getTranslation('month_'.substr($current_y_m,5)) . CR . CR . getTranslation('raid_select_date');
+ $msg = getTranslation('history_title') . CR . CR;
+ $msg .= getTranslation('history_displaying_month') . ' ' . getTranslation('month_'.substr($current_y_m,5)) . CR . CR . getTranslation('raid_select_date');
- $nav_keys = [];
- if($prev != 0) $nav_keys[0][] = ['text' => getTranslation('month_'.substr($prev,5)),'callback_data' => '0:history:' . $prev];
- if($next != 0) $nav_keys[0][] = ['text' => getTranslation('month_'.substr($next,5)),'callback_data' => '0:history:' . $next];
+ $nav_keys = [];
+ if($prev != 0) $nav_keys[0][] = button(getTranslation('month_'.substr($prev,5)),['history', 'm' => $prev]);
+ if($next != 0) $nav_keys[0][] = button(getTranslation('month_'.substr($next,5)),['history', 'm' => $next]);
- $keys = array_merge($keys, $nav_keys);
- $keys[] = [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
- return [$msg, $keys];
+ $keys = array_merge($keys, $nav_keys);
+ $keys[][] = button(getTranslation('abort'), 'exit');
+ return [$msg, $keys];
}
-?>
\ No newline at end of file
diff --git a/logic/insert_cleanup.php b/logic/insert_cleanup.php
index b77b6fdc..6d3f04ef 100644
--- a/logic/insert_cleanup.php
+++ b/logic/insert_cleanup.php
@@ -1,34 +1,44 @@
0)) {
- // Build query for cleanup table to add cleanup info to database
- debug_log('Adding cleanup info to database:');
- $rs = my_query(
- "
- INSERT INTO cleanup
- SET raid_id = '{$raid_id}',
- chat_id = '{$chat_id}',
- message_id = '{$message_id}',
- type = '{$type}'
- "
- );
- } else {
- debug_log('Invalid input for cleanup preparation!');
- }
-}
+ if (!is_numeric($chat_id) || !is_numeric($message_id) || !is_numeric($raid_id) || $raid_id < 1) {
+ debug_log('Invalid input for cleanup preparation!');
+ return;
+ }
-?>
+ // Build query for cleanup table to add cleanup info to database
+ debug_log('Adding cleanup info to database:');
+ my_query('
+ REPLACE INTO cleanup
+ SET raid_id = :raid_id,
+ chat_id = :chat_id,
+ message_id = :message_id,
+ thread_id = :thread_id,
+ type = :type,
+ media_unique_id = :media_unique_id
+ ', [
+ ':raid_id' => $raid_id,
+ ':chat_id' => $chat_id,
+ ':message_id' => $message_id,
+ ':thread_id' => $thread_id,
+ ':type' => $type,
+ ':media_unique_id' => $photo_id,
+ ]
+ );
+}
diff --git a/logic/insert_overview.php b/logic/insert_overview.php
index ea79a141..425c4106 100644
--- a/logic/insert_overview.php
+++ b/logic/insert_overview.php
@@ -1,42 +1,55 @@
fetch();
+ $row = $rs->fetch();
- // Overview already in database or new
- if (empty($row['count'])) {
- // Build query for overview table to add overview info to database
- debug_log('Adding new overview information to database overview list!');
- $rs = my_query(
- "
- INSERT INTO overview
- SET chat_id = '{$chat_id}',
- message_id = '{$message_id}',
- chat_title = '{$chat_title}',
- chat_username = '{$chat_username}',
- updated = DATE(NOW())
- "
- );
- } else {
- // Nothing to do - overview information is already in database.
- debug_log('Overview information is already in database! Nothing to do...');
- }
+ // Overview already in database or new
+ if (!empty($row['count'])) {
+ // Nothing to do - overview information is already in database.
+ debug_log('Overview information is already in database! Nothing to do...');
+ return;
+ }
+ // Build query for overview table to add overview info to database
+ debug_log('Adding new overview information to database overview list!');
+ my_query(
+ '
+ INSERT INTO overview
+ SET chat_id = :chat_id,
+ message_id = :message_id,
+ thread_id = :thread_id,
+ chat_title = :chat_title,
+ chat_username = :chat_username,
+ updated = DATE(NOW())
+ ', [
+ 'chat_id' => $chat_id,
+ 'message_id' => $message_id,
+ 'thread_id' => $thread_id,
+ 'chat_title' => $chat_title,
+ 'chat_username' => $chat_username,
+ ]
+ );
}
-
-?>
diff --git a/logic/insert_trainerinfo.php b/logic/insert_trainerinfo.php
index 210f0e71..351a4dd6 100644
--- a/logic/insert_trainerinfo.php
+++ b/logic/insert_trainerinfo.php
@@ -1,37 +1,35 @@
fetch();
+ $row = $rs->fetch();
- // Trainer info already in database or new
- if (empty($row['count'])) {
- // Build query for trainerinfo table to add trainer info to database
- debug_log('Adding new trainer information to database trainer info list!');
- $rs = my_query(
- "
- INSERT INTO trainerinfo
- SET chat_id = '{$chat_id}',
- message_id = '{$message_id}'
- "
- );
- } else {
- // Nothing to do - trainer information is already in database.
- debug_log('Trainer information is already in database! Nothing to do...');
- }
+ // Trainer info already in database or new
+ if (!empty($row['count'])) {
+ // Nothing to do - trainer information is already in database.
+ debug_log('Trainer information is already in database! Nothing to do...');
+ return;
+ }
+ // Build query for trainerinfo table to add trainer info to database
+ debug_log('Adding new trainer information to database trainer info list!');
+ my_query('
+ INSERT INTO trainerinfo
+ SET chat_id = ?,
+ message_id = ?,
+ thread_id = ?
+ ', [$chat_id, $message_id, $thread_id]
+ );
}
-
-?>
diff --git a/logic/key_util.php b/logic/key_util.php
new file mode 100644
index 00000000..9fe14a68
--- /dev/null
+++ b/logic/key_util.php
@@ -0,0 +1,164 @@
+= $columns) {
+ $row++;
+ $col = 0;
+ }
+ }
+ return $result;
+}
+
+/**
+ * Share keys. Has own logic for fetching chat id's if used to generate share keys for raids.
+ * @param int|false $id Id to pass to callback query
+ * @param string $action Action to pass to callback query
+ * @param array $update Update from Telegram
+ * @param int $raidLevel Raid level if sharing a raid
+ * @param array $chats List of chats if using alternative list
+ * @param bool $hideGeneralShare Leave out the general share button
+ * @return array
+ */
+function share_keys($id, $action, $update, $raidLevel = '', $chats = [], $hideGeneralShare = false)
+{
+ global $config, $botUser;
+ $keys = [];
+ // Check access.
+ $share_access = $botUser->accessCheck('share-any-chat', true);
+
+ // Add share button if not restricted to allow sharing to any chat.
+ if ($share_access == true && $hideGeneralShare == false) {
+ debug_log('Adding general share key to inline keys');
+ // Set the keys.
+ $keys[][] = [
+ 'text' => getTranslation('share'),
+ 'switch_inline_query' => basename(ROOT_PATH) . ':' . strval($id)
+ ];
+ }
+
+ // Start share_chats backwards compatibility
+ if(!isset($config->CHATS_SHARE)) {
+ // Add buttons for predefined sharing chats.
+ // Default SHARE_CHATS or special chat list via $chats?
+ if(empty($chats)) {
+ if(!empty($raidLevel)) {
+ // find chats to share ourselves, if we can
+ debug_log($raidLevel, 'Did not get specific chats to share to, checking level specific for: ');
+ $level_chat = 'SHARE_CHATS_LEVEL_' . $raidLevel;
+ $chats = [];
+ if(!empty($config->{$level_chat})) {
+ $chat_array = explode(',', $config->{$level_chat});
+ debug_log($config->{$level_chat}, 'Found level specific chats to share to: ');
+ } else {
+ $chat_array = explode(',', $config->SHARE_CHATS);
+ debug_log($config->SHARE_CHATS, 'Chats not specified for level, sharing to globals: ');
+ }
+ } else {
+ $chat_array = explode(',', $config->SHARE_CHATS);
+ debug_log($config->SHARE_CHATS, 'Level not given, sharing to globals: ');
+ }
+ foreach($chat_array as $chat) {
+ $chats[] = ['id' => $chat];
+ }
+ }
+ // End chats_share backwards compatibility
+ } else {
+ if(empty($chats)) {
+ if(!empty($raidLevel)) {
+ // find chats to share ourselves, if we can
+ debug_log($raidLevel, 'Did not get specific chats to share to, checking level specific for: ');
+ $chats = [];
+ if(!empty($config->CHATS_SHARE['manual_share'][$raidLevel])) {
+ $chats = $config->CHATS_SHARE['manual_share'][$raidLevel];
+ } else {
+ $chats = $config->CHATS_SHARE['manual_share']['all'];
+ }
+ } else {
+ $chats = $config->CHATS_SHARE['manual_share']['all'];
+ }
+ }
+ }
+ // Add keys for each chat.
+ if(empty($chats)) {
+ debug_log('Aint got any chats to share to!');
+ return [];
+ }
+ if($raidLevel == '') {
+ // If raid level is not set we are sharing something else than a raid.
+ $sharedChats = [];
+ } else {
+ $queryShared = my_query('
+ SELECT DISTINCT chat_id
+ FROM cleanup
+ WHERE raid_id = ?',
+ [$id]
+ );
+ $sharedChats = $queryShared->fetchAll(PDO::FETCH_COLUMN, 0);
+ }
+ foreach($chats as $chat) {
+ if(in_array($chat['id'], $sharedChats)) continue;
+ // Get chat object
+ debug_log("Getting chat object for '" . $chat['id'] . "'");
+ $chat_obj = get_chat($chat['id']);
+
+ // Check chat object for proper response.
+ if ($chat_obj['ok'] != true) {
+ info_log($chat, 'Invalid chat id in your configuration:');
+ continue;
+ }
+ $chatTitle = $chat['title'] ?? $chat_obj['result']['title'];
+ debug_log('Proper chat object received, continuing to add key for this chat: ' . $chatTitle);
+ $shareData = [0 => $action, 'c' => $chat['id']];
+ $shareData['t'] = $chat['thread'] ?? '';
+ if($id !== false) $shareData['r'] = $id;
+ $keys[][] = button(getTranslation('share_with') . ' ' . $chatTitle, $shareData);
+ }
+
+ return $keys;
+}
+
+/**
+ * Format
+ * @param array $array
+ * @return string Formated
+ */
+function formatCallbackData($array)
+{
+ $return = $array[0] . '|';
+ unset($array[0]);
+ foreach($array as $key => $value) {
+ if($value !== 0 && (!isset($value) or $value === false)) continue;
+ $return .= $key . '=' . $value . '|';
+ }
+ return rtrim($return, '|');
+}
+
+/**
+ * Return a button element
+ * @param string Button text
+ * @param string|array Callback data
+ * @return array Button
+ */
+function button($text, $callbackData)
+{
+ $callback = is_array($callbackData) ? formatCallbackData($callbackData) : $callbackData;
+ $button = [
+ 'text' => $text,
+ 'callback_data' => $callback
+ ];
+ return $button;
+}
diff --git a/logic/keys_event.php b/logic/keys_event.php
index 388cb409..96278cac 100644
--- a/logic/keys_event.php
+++ b/logic/keys_event.php
@@ -1,34 +1,36 @@
fetch()) {
- if(!empty($event['name'])) {
- $keys[] = array(
- 'text' => $event['name'],
- 'callback_data' => $gym_id_plus_letter . ':' . $action . ':' . $event['id']
- );
- }else {
- info_log('Invalid event name on event '. $event['id']);
- }
+ if(empty($event['name'])) {
+ info_log('Invalid event name on event '. $event['id']);
+ continue;
+ }
+ $callbackData['e'] = $event['id'];
+ $keys[] = button($event['name'], $callbackData);
}
- $keys[] = array(
- 'text' => getTranslation("Xstars"),
- 'callback_data' => $gym_id_plus_letter . ':' . $action . ':X'
- );
- // Get the inline key array.
- $keys = inline_key_array($keys, 1);
+ }
+ if($admin_access[0] === true) {
+ $callbackData['e'] = EVENT_ID_EX;
+ $keys[] = button(getTranslation(RAID_ID_EX . 'stars'), $callbackData);
+ }
+ // Get the inline key array.
+ $keys = inline_key_array($keys, 1);
- return $keys;
+ return $keys;
}
-?>
\ No newline at end of file
diff --git a/logic/keys_trainerinfo.php b/logic/keys_trainerinfo.php
index aea1d9c6..4bf93c11 100644
--- a/logic/keys_trainerinfo.php
+++ b/logic/keys_trainerinfo.php
@@ -6,61 +6,26 @@
*/
function keys_trainerinfo($show = false)
{
- global $config;
- // Toggle state.
- $status = 'show';
- if($show || !$config->TRAINER_BUTTONS_TOGGLE) {
- // Always show buttons?
- if(($show == true && !$config->TRAINER_BUTTONS_TOGGLE) || $config->TRAINER_BUTTONS_TOGGLE) {
- $status = 'hide';
- }
+ global $config;
+ // Toggle state.
+ $status = 'show';
+ if(!$show) {
+ // Key to show/hide trainer info.
+ $keys[][] = button(getPublicTranslation('trainerinfo'), ['vote_level', 'a' => 'trainer', 's' => $status]);
+ return $keys;
+ }
+ // Always show buttons?
+ if($show == true) {
+ $status = 'hide';
+ }
- // Keys to set team and level
- $keys = [
- [
- [
- 'text' => getPublicTranslation('trainerinfo'),
- 'callback_data' => 'trainer:vote_level:' . $status
- ],
- ],
- [
- [
- 'text' => getPublicTranslation('team') . SP . TEAM_B,
- 'callback_data' => 'trainer:vote_team:mystic'
- ],
- [
- 'text' => getPublicTranslation('team') . SP . TEAM_R,
- 'callback_data' => 'trainer:vote_team:valor'
- ],
- [
- 'text' => getPublicTranslation('team') . SP . TEAM_Y,
- 'callback_data' => 'trainer:vote_team:instinct'
- ],
- ],
- [
- [
- 'text' => getPublicTranslation('level') . ' +',
- 'callback_data' => 'trainer:vote_level:up'
- ],
- [
- 'text' => getPublicTranslation('level') . ' -',
- 'callback_data' => 'trainer:vote_level:down'
- ]
- ]
- ];
- } else {
- // Key to show/hide trainer info.
- $keys = [
- [
- [
- 'text' => getPublicTranslation('trainerinfo'),
- 'callback_data' => 'trainer:vote_level:' . $status
- ],
- ]
- ];
- }
+ // Keys to set team and level
+ $keys[0][0] = button(getPublicTranslation('trainerinfo'), ['vote_level', 'a' => 'trainer', 's' => $status]);
+ $keys[1][0] = button(getPublicTranslation('team') . SP . TEAM_B, ['vote_team', 'a' => 'trainer', 't' => 'mystic']);
+ $keys[1][1] = button(getPublicTranslation('team') . SP . TEAM_R, ['vote_team', 'a' => 'trainer', 't' => 'valor']);
+ $keys[1][2] = button(getPublicTranslation('team') . SP . TEAM_Y, ['vote_team', 'a' => 'trainer', 't' => 'instinct']);
+ $keys[2][0] = button(getPublicTranslation('level') . ' +', ['vote_level', 'a' => 'trainer', 'l' => 'up']);
+ $keys[2][1] = button(getPublicTranslation('level') . ' -', ['vote_level', 'a' => 'trainer', 'l' => 'down']);
- return $keys;
+ return $keys;
}
-
-?>
diff --git a/logic/keys_vote.php b/logic/keys_vote.php
index 6d9baf1b..95adc12c 100644
--- a/logic/keys_vote.php
+++ b/logic/keys_vote.php
@@ -1,4 +1,5 @@
RAID_ENDED_HIDE_KEYS) {
- $keys = [];
- }else {
- $keys = [
- [
- [
- 'text' => getPublicTranslation('raid_done'),
- 'callback_data' => $raid['id'] . ':vote_refresh:1'
- ]
- ]
- ];
- }
- // Raid is still running.
+ global $config;
+ // Init keys_time array.
+ $keys_time = [];
+
+ // Get current UTC time and raid UTC times.
+ $now = utcnow();
+
+ // Write to log.
+ debug_log($now, 'UTC NOW:');
+ debug_log($raid['end_time'], 'UTC END:');
+ debug_log($raid['start_time'], 'UTC START:');
+
+ // Raid ended already.
+ if ($raid['raid_ended']) {
+ if($config->RAID_ENDED_HIDE_KEYS) return [];
+ $button[][] = button(getPublicTranslation('raid_done'), ['vote_refresh', 'r' => $raid['id']]);
+ return $button;
+ }
+ // Raid is still running.
+ // Get current pokemon
+ $raid_pokemon_id = $raid['pokemon'];
+ $raid_pokemon_form_id = $raid['pokemon_form'];
+ $raid_pokemon = $raid_pokemon_id . "-" . $raid_pokemon_form_id;
+
+ // Get raid level
+ $raid_level = $raid['level'];
+
+ // Are remote players allowed for this raid?
+ $raid_local_only = in_array($raid_level, RAID_LEVEL_LOCAL_ONLY);
+
+ // Hide buttons for raid levels and pokemon
+ $hide_buttons_raid_level = explode(',', $config->RAID_POLL_HIDE_BUTTONS_RAID_LEVEL);
+ $hide_buttons_pokemon = explode(',', $config->RAID_POLL_HIDE_BUTTONS_POKEMON);
+
+ // Show buttons to users?
+ if(in_array($raid_level, $hide_buttons_raid_level) || in_array(($raid_pokemon_id . "-" . get_pokemon_form_name($raid_pokemon_id,$raid_pokemon_form_id)), $hide_buttons_pokemon) || in_array($raid_pokemon_id, $hide_buttons_pokemon)) {
+ return [];
+ }
+ // Extra Keys
+ $buttons['alone'] = button(EMOJI_SINGLE, ['vote_extra', 'r' => $raid['id']]);
+ $buttons['extra'] = button('+ ' . EMOJI_IN_PERSON, ['vote_extra', 'r' => $raid['id'], 'a' => 'in_person']);
+
+ // Show buttons regarding remote participation only if raid level allows it
+ $buttons['extra_alien'] = $buttons['can_inv'] = $buttons['remote'] = $buttons['inv_plz'] = [];
+ if(!$raid_local_only) {
+ $buttons['extra_alien'] = button('+ ' . EMOJI_ALIEN, ['vote_extra', 'r' => $raid['id'], 'a' => 'alien']);
+
+ // Can invite key
+ $buttons['can_inv'] = button(EMOJI_CAN_INVITE, ['vote_can_invite', 'r' => $raid['id']]);
+
+ // Remote Raid Pass key
+ $buttons['remote'] = button(EMOJI_REMOTE, ['vote_remote', 'r' => $raid['id']]);
+
+ // Want invite key
+ $buttons['inv_plz'] = button(EMOJI_WANT_INVITE, ['vote_want_invite', 'r' => $raid['id']]);
+ }
+
+ // Team and level keys.
+ $buttons['teamlvl'][0][] = button('Team', ['vote_team', 'r' => $raid['id']]);
+ $buttons['teamlvl'][0][] = button('Lvl +', ['vote_level', 'r' => $raid['id'], 'l' => 'up']);
+ $buttons['teamlvl'][0][] = button('Lvl -', ['vote_level', 'r' => $raid['id'], 'l' => 'down']);
+
+ // Ex-Raid Invite key
+ $buttons['ex_inv'] = [];
+ if ($raid['event'] == EVENT_ID_EX) {
+ $buttons['ex_inv'] = button(EMOJI_INVITE, ['vote_invite', 'r' => $raid['id']]);
+ }
+
+ // Show icon, icon + text or just text.
+ // Icon.
+ if($config->RAID_VOTE_ICONS && !$config->RAID_VOTE_TEXT) {
+ $text_here = EMOJI_HERE;
+ $text_late = EMOJI_LATE;
+ $text_done = TEAM_DONE;
+ $text_cancel = TEAM_CANCEL;
+ // Icon + text.
+ } else if($config->RAID_VOTE_ICONS && $config->RAID_VOTE_TEXT) {
+ $text_here = EMOJI_HERE . getPublicTranslation('here');
+ $text_late = EMOJI_LATE . getPublicTranslation('late');
+ $text_done = TEAM_DONE . getPublicTranslation('done');
+ $text_cancel = TEAM_CANCEL . getPublicTranslation('cancellation');
+ // Text.
+ } else {
+ $text_here = getPublicTranslation('here');
+ $text_late = getPublicTranslation('late');
+ $text_done = getPublicTranslation('done');
+ $text_cancel = getPublicTranslation('cancellation');
+ }
+
+ // Status keys.
+ $buttons['alarm'] = button(EMOJI_ALARM, ['vote_status', 'r' => $raid['id'], 'a' => 'alarm']);
+ $buttons['here'] = button($text_here, ['vote_status', 'r' => $raid['id'], 'a' => 'arrived']);
+ $buttons['late'] = button($text_late, ['vote_status', 'r' => $raid['id'], 'a' => 'late']);
+ $buttons['done'] = button($text_done, ['vote_status', 'r' => $raid['id'], 'a' => 'raid_done']);
+ $buttons['cancel'] = button($text_cancel, ['vote_status', 'r' => $raid['id'], 'a' => 'cancel']);
+
+ $buttons['refresh'] = [];
+ if(!$config->AUTO_REFRESH_POLLS) {
+ $buttons['refresh'] = button(EMOJI_REFRESH, ['vote_refresh', 'r' => $raid['id']]);
+ }
+
+ if($raid['event_vote_key_mode'] == 1) {
+ $keys_time[] = button(getPublicTranslation('Participate'), ['vote_time', 'r' => $raid['id'], 't' => utctime($raid['start_time'], 'YmdHis')]);
+ }else {
+ $RAID_SLOTS = ($raid['event_time_slots'] > 0) ? $raid['event_time_slots'] : $config->RAID_SLOTS;
+ $keys_time = generateTimeslotKeys($RAID_SLOTS, $raid);
+ }
+ // Add time keys.
+ $buttons['time'] = inline_key_array($keys_time, 4);
+
+ // Hidden participants?
+ $hide_users_sql = '';
+ if($config->RAID_POLL_HIDE_USERS_TIME > 0) {
+ if($config->RAID_ANYTIME) {
+ $hide_users_sql = 'AND (attend_time > (UTC_TIMESTAMP() - INTERVAL ' . $config->RAID_POLL_HIDE_USERS_TIME . ' MINUTE) OR attend_time = \''.ANYTIME.'\')';
} else {
- // Get current pokemon
- $raid_pokemon_id = $raid['pokemon'];
- $raid_pokemon_form_id = $raid['pokemon_form'];
- $raid_pokemon = $raid_pokemon_id . "-" . $raid_pokemon_form_id;
-
- // Get raid level
- $raid_level = $raid['level'];
-
- // Hide buttons for raid levels and pokemon
- $hide_buttons_raid_level = explode(',', $config->RAID_POLL_HIDE_BUTTONS_RAID_LEVEL);
- $hide_buttons_pokemon = explode(',', $config->RAID_POLL_HIDE_BUTTONS_POKEMON);
-
- // Show buttons to users?
- if(in_array($raid_level, $hide_buttons_raid_level) || in_array(($raid_pokemon_id . "-" . get_pokemon_form_name($raid_pokemon_id,$raid_pokemon_form_id)), $hide_buttons_pokemon) || in_array($raid_pokemon_id, $hide_buttons_pokemon)) {
- $keys = [];
- } else {
- // Extra Keys
- $buttons_alone = [
- 'text' => EMOJI_SINGLE,
- 'callback_data' => $raid['id'] . ':vote_extra:0'
- ];
- $buttons_extra = [
- 'text' => '+ ' . EMOJI_IN_PERSON,
- 'callback_data' => $raid['id'] . ':vote_extra:in_person'
- ];
- $buttons_extra_alien = [
- 'text' => '+ ' . EMOJI_ALIEN,
- 'callback_data' => $raid['id'] . ':vote_extra:alien'
- ];
-
- // Can invite key
- $buttons_can_inv = [
- 'text' => EMOJI_CAN_INVITE,
- 'callback_data' => $raid['id'] . ':vote_can_invite:0'
- ];
-
- // Remote Raid Pass key
- $buttons_remote = [
- 'text' => EMOJI_REMOTE,
- 'callback_data' => $raid['id'] . ':vote_remote:0'
- ];
-
- // Want invite key
- $buttons_inv_plz = [
- 'text' => EMOJI_WANT_INVITE,
- 'callback_data' => $raid['id'] . ':vote_want_invite:0'
- ];
-
- // Team and level keys.
- $buttons_teamlvl = [
- [
- [
- 'text' => 'Team',
- 'callback_data' => $raid['id'] . ':vote_team:0'
- ],
- [
- 'text' => 'Lvl +',
- 'callback_data' => $raid['id'] . ':vote_level:up'
- ],
- [
- 'text' => 'Lvl -',
- 'callback_data' => $raid['id'] . ':vote_level:down'
- ]
- ]
- ];
-
- // Ex-Raid Invite key
- if ($raid['event'] == EVENT_ID_EX) {
- $buttons_ex_inv = [
- 'text' => EMOJI_INVITE,
- 'callback_data' => $raid['id'] . ':vote_invite:0'
- ];
- }else {
- $buttons_ex_inv = [];
- }
-
- // Show icon, icon + text or just text.
- // Icon.
- if($config->RAID_VOTE_ICONS && !$config->RAID_VOTE_TEXT) {
- $text_here = EMOJI_HERE;
- $text_late = EMOJI_LATE;
- $text_done = TEAM_DONE;
- $text_cancel = TEAM_CANCEL;
- // Icon + text.
- } else if($config->RAID_VOTE_ICONS && $config->RAID_VOTE_TEXT) {
- $text_here = EMOJI_HERE . getPublicTranslation('here');
- $text_late = EMOJI_LATE . getPublicTranslation('late');
- $text_done = TEAM_DONE . getPublicTranslation('done');
- $text_cancel = TEAM_CANCEL . getPublicTranslation('cancellation');
- // Text.
- } else {
- $text_here = getPublicTranslation('here');
- $text_late = getPublicTranslation('late');
- $text_done = getPublicTranslation('done');
- $text_cancel = getPublicTranslation('cancellation');
- }
-
- // Status keys.
- $buttons_alarm = [
- 'text' => EMOJI_ALARM,
- 'callback_data' => $raid['id'] . ':vote_status:alarm'
- ];
- $buttons_here = [
- 'text' => $text_here,
- 'callback_data' => $raid['id'] . ':vote_status:arrived'
- ];
- $buttons_late = [
- 'text' => $text_late,
- 'callback_data' => $raid['id'] . ':vote_status:late'
- ];
- $buttons_done = [
- 'text' => $text_done,
- 'callback_data' => $raid['id'] . ':vote_status:raid_done'
- ];
- $buttons_cancel = [
- 'text' => $text_cancel,
- 'callback_data' => $raid['id'] . ':vote_status:cancel'
- ];
-
- if(!$config->AUTO_REFRESH_POLLS) {
- $buttons_refresh = [
- 'text' => EMOJI_REFRESH,
- 'callback_data' => $raid['id'] . ':vote_refresh:0'
- ];
- }else {
- $buttons_refresh = [];
- }
-
- if($raid['event_vote_key_mode'] == 1) {
- $keys_time = [
- [
- 'text' => getPublicTranslation("Participate"),
- 'callback_data' => $raid['id'] . ':vote_time:0'
- ]
- ];
- }else {
- if($raid['event_time_slots'] > 0) {
- $RAID_SLOTS = $raid['event_time_slots'];
- }else {
- $RAID_SLOTS = $config->RAID_SLOTS;
- }
- // Get current time.
- $now_helper = new DateTimeImmutable('now', new DateTimeZone('UTC'));
- $now_helper = $now_helper->format('Y-m-d H:i') . ':00';
- $dt_now = new DateTimeImmutable($now_helper, new DateTimeZone('UTC'));
-
- // Get direct start slot
- $direct_slot = new DateTimeImmutable($start_time, new DateTimeZone('UTC'));
-
- // Get first raidslot rounded up to the next 5 minutes
- // Get minute and convert modulo raidslot
- $five_slot = new DateTimeImmutable($start_time, new DateTimeZone('UTC'));
- $minute = $five_slot->format("i");
- $minute = $minute % 5;
-
- // Count minutes to next 5 multiple minutes if necessary
- if($minute != 0)
- {
- // Count difference
- $diff = 5 - $minute;
- // Add difference
- $five_slot = $five_slot->add(new DateInterval("PT".$diff."M"));
- }
-
- // Add $config->RAID_FIRST_START minutes to five minutes slot
- //$five_plus_slot = new DateTime($five_slot, new DateTimeZone('UTC'));
- $five_plus_slot = $five_slot;
- $five_plus_slot = $five_plus_slot->add(new DateInterval("PT".$config->RAID_FIRST_START."M"));
-
- // Get first regular raidslot
- // Get minute and convert modulo raidslot
- $first_slot = new DateTimeImmutable($start_time, new DateTimeZone('UTC'));
- $minute = $first_slot->format("i");
- $minute = $minute % $config->RAID_SLOTS;
-
- // Count minutes to next raidslot multiple minutes if necessary
- if($minute != 0)
- {
- // Count difference
- $diff = $config->RAID_SLOTS - $minute;
- // Add difference
- $first_slot = $first_slot->add(new DateInterval("PT".$diff."M"));
- }
-
- // Compare times slots to add them to keys.
- // Example Scenarios:
- // Raid 1: Start = 17:45, $config->RAID_FIRST_START = 10, $config->RAID_SLOTS = 15
- // Raid 2: Start = 17:36, $config->RAID_FIRST_START = 10, $config->RAID_SLOTS = 15
- // Raid 3: Start = 17:35, $config->RAID_FIRST_START = 10, $config->RAID_SLOTS = 15
- // Raid 4: Start = 17:31, $config->RAID_FIRST_START = 10, $config->RAID_SLOTS = 15
- // Raid 5: Start = 17:40, $config->RAID_FIRST_START = 10, $config->RAID_SLOTS = 15
- // Raid 6: Start = 17:32, $config->RAID_FIRST_START = 5, $config->RAID_SLOTS = 5
-
- // Write slots to log.
- debug_log($direct_slot, 'Direct start slot:');
- debug_log($five_slot, 'Next 5 Minute slot:');
- debug_log($first_slot, 'First regular slot:');
-
- // Add first slot only, as all slot times are identical
- if($direct_slot == $five_slot && $direct_slot == $first_slot) {
- // Raid 1: 17:45 (17:45 == 17:45 && 17:45 == 17:45)
-
- // Add first slot
- if($first_slot >= $dt_now) {
- $slot = $first_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
-
- // Add either five and first slot or only first slot based on RAID_FIRST_START
- } else if($direct_slot == $five_slot && $five_slot < $first_slot) {
- // Raid 3: 17:35 == 17:35 && 17:35 < 17:45
- // Raid 5: 17:40 == 17:40 && 17:40 < 17:45
-
- // Add next five minutes slot and first regular slot
- if($five_plus_slot <= $first_slot) {
- // Raid 3: 17:35, 17:45 (17:35 + 10min <= 17:45)
-
- // Add five minutes slot
- if($five_slot >= $dt_now) {
- $slot = $five_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
-
- // Add first slot
- if($first_slot >= $dt_now) {
- $slot = $first_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
-
- // Add only first regular slot
- } else {
- // Raid 5: 17:45
-
- // Add first slot
- if($first_slot >= $dt_now) {
- $slot = $first_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
- }
-
- // Add direct slot and first slot
- } else if($direct_slot < $five_slot && $five_slot == $first_slot) {
- // Raid 6: 17:32 < 17:35 && 17:35 == 17:35
- // Some kind of special case for a low value of RAID_SLOTS
-
- // Add direct slot?
- if($config->RAID_DIRECT_START) {
- if($direct_slot >= $dt_now) {
- $slot = $direct_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
- }
-
- // Add first slot
- if($first_slot >= $dt_now) {
- $slot = $first_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
-
-
- // Add either all 3 slots (direct slot, five minutes slot and first regular slot) or
- // 2 slots (direct slot and first slot) as $config->RAID_FIRST_START does not allow the five minutes slot to be added
- } else if($direct_slot < $five_slot && $five_slot < $first_slot) {
- // Raid 2: 17:36 < 17:40 && 17:40 < 17:45
- // Raid 4: 17:31 < 17:35 && 17:35 < 17:45
-
- // Add all 3 slots
- if($five_plus_slot <= $first_slot) {
- // Raid 4: 17:31, 17:35, 17:45
-
- // Add direct slot?
- if($config->RAID_DIRECT_START) {
- if($direct_slot >= $dt_now) {
- $slot = $direct_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
- }
-
- // Add five minutes slot
- if($five_slot >= $dt_now) {
- $slot = $five_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
-
- // Add first slot
- if($first_slot >= $dt_now) {
- $slot = $first_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
- // Add direct slot and first regular slot
- } else {
- // Raid 2: 17:36, 17:45
-
- // Add direct slot?
- if($config->RAID_DIRECT_START) {
- if($direct_slot >= $dt_now) {
- $slot = $direct_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
- }
-
- // Add first slot
- if($first_slot >= $dt_now) {
- $slot = $first_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
- }
-
- // We missed all possible cases or forgot to include them in future else-if-clauses :D
- // Try to add at least the direct slot.
- } else {
- // Add direct slot?
- if($config->RAID_DIRECT_START) {
- if($first_slot >= $dt_now) {
- $slot = $direct_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
- }
- }
-
-
- // Init last slot time.
- $last_slot = new DateTimeImmutable($start_time, new DateTimeZone('UTC'));
-
- // Get regular slots
- // Start with second slot as first slot is already added to keys.
- $second_slot = $first_slot->add(new DateInterval("PT".$RAID_SLOTS."M"));
- $dt_end = new DateTimeImmutable($end_time, new DateTimeZone('UTC'));
- $regular_slots = new DatePeriod($second_slot, new DateInterval('PT'.$RAID_SLOTS.'M'), $dt_end);
-
- // Add regular slots.
- foreach($regular_slots as $slot){
- $slot_end = $slot->add(new DateInterval('PT'.$config->RAID_LAST_START.'M'));
- // Slot + $config->RAID_LAST_START before end_time?
- if($slot_end < $dt_end) {
- debug_log($slot, 'Regular slot:');
- // Add regular slot.
- if($slot >= $dt_now) {
- $slot = $slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
-
- // Set last slot for later.
- $last_slot = new DateTimeImmutable($slot, new DateTimeZone('UTC'));
- } else {
- // Set last slot for later.
- $slot = $slot->format('Y-m-d H:i:s');
- $last_slot = new DateTimeImmutable($slot, new DateTimeZone('UTC'));
- }
- }
- }
-
- // Add raid last start slot
- // Set end_time to last extra slot, subtract $config->RAID_LAST_START minutes and round down to earlier 5 minutes.
- $last_extra_slot = $dt_end;
- $last_extra_slot = $last_extra_slot->sub(new DateInterval('PT'.$config->RAID_LAST_START.'M'));
- $s = 5 * 60;
- $last_extra_slot = $last_extra_slot->setTimestamp($s * floor($last_extra_slot->getTimestamp() / $s));
- //$time_to_last_slot = $last_extra_slot->diff($last_slot)->format("%a");
-
- // Last extra slot not conflicting with last slot and time to last regular slot larger than RAID_LAST_START?
- //if($last_extra_slot > $last_slot && $time_to_last_slot > $config->RAID_LAST_START)
-
- // Log last and last extra slot.
- debug_log($last_slot, 'Last slot:');
- debug_log($last_extra_slot, 'Last extra slot:');
-
- // Last extra slot not conflicting with last slot
- if($last_extra_slot > $last_slot) {
- // Add last extra slot
- if($last_extra_slot >= $dt_now) {
- $slot = $last_extra_slot->format('Y-m-d H:i:s');
- $keys_time[] = array(
- 'text' => dt2time($slot),
- 'callback_data' => $raid['id'] . ':vote_time:' . utctime($slot, 'YmdHis')
- );
- }
- }
-
- // Attend raid at any time
- if($config->RAID_ANYTIME)
- {
- $keys_time[] = array(
- 'text' => getPublicTranslation('anytime'),
- 'callback_data' => $raid['id'] . ':vote_time:0'
- );
- }
- }
- // Add time keys.
- $buttons_time = inline_key_array($keys_time, 4);
-
- // Hidden participants?
- if($config->RAID_POLL_HIDE_USERS_TIME > 0) {
- if($config->RAID_ANYTIME) {
- $hide_users_sql = "AND (attend_time > (UTC_TIMESTAMP() - INTERVAL " . $config->RAID_POLL_HIDE_USERS_TIME . " MINUTE) OR attend_time = '".ANYTIME."')";
- } else {
- $hide_users_sql = "AND attend_time > (UTC_TIMESTAMP() - INTERVAL " . $config->RAID_POLL_HIDE_USERS_TIME . " MINUTE)";
- }
- } else {
- $hide_users_sql = "";
- }
-
- // Get participants
- $rs = my_query(
- "
- SELECT count(attend_time) AS count,
- sum(pokemon = '0') AS count_any_pokemon,
- sum(pokemon = '{$raid_pokemon}') AS count_raid_pokemon
- FROM attendance
- WHERE raid_id = {$raid['id']}
- $hide_users_sql
- AND attend_time IS NOT NULL
- AND raid_done != 1
- AND cancel != 1
- "
- );
-
- $row = $rs->fetch();
-
- // Count participants and participants by pokemon
- $count_pp = $row['count'];
- $count_any_pokemon = $row['count_any_pokemon'];
- $count_raid_pokemon = $row['count_raid_pokemon'];
-
- // Write to log.
- debug_log('Participants for raid with ID ' . $raid['id'] . ': ' . $count_pp);
- debug_log('Participants who voted for any pokemon: ' . $count_any_pokemon);
- debug_log('Participants who voted for ' . $raid_pokemon . ': ' . $count_raid_pokemon);
-
- // Zero Participants? Show only time buttons!
- if($count_pp == 0) {
- $keys = $buttons_time;
- } else {
- // Init keys pokemon array.
- $buttons_pokemon = [];
-
- // Show pokemon keys only if the raid boss is an egg
- if(in_array($raid_pokemon_id, $GLOBALS['eggs'])) {
- // Get pokemon from database
- $raid_spawn = dt2time($raid['spawn'], 'Y-m-d H:i'); // Convert utc spawntime to local time
- $raid_bosses = get_raid_bosses($raid_spawn, $raid_level);
-
- // Get eggs.
- $eggs = $GLOBALS['eggs'];
-
- if(count($raid_bosses) > 2) {
- // Add key for each raid level
- foreach($raid_bosses as $pokemon) {
- if(in_array($pokemon['pokedex_id'], $eggs)) continue;
- $buttons_pokemon[] = array(
- 'text' => get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id'], true),
- 'callback_data' => $raid['id'] . ':vote_pokemon:' . $pokemon['pokedex_id'] . '-' . $pokemon['pokemon_form_id']
- );
- }
-
- // Add button if raid boss does not matter
- $buttons_pokemon[] = array(
- 'text' => getPublicTranslation('any_pokemon'),
- 'callback_data' => $raid['id'] . ':vote_pokemon:0'
- );
-
- // Finally add pokemon to keys
- $buttons_pokemon = inline_key_array($buttons_pokemon, 2);
- }
- }
-
- // Init keys array
- $keys = [];
-
- if($raid['event_poll_template'] != null) $template = json_decode($raid['event_poll_template']);
- else $template = $config->RAID_POLL_UI_TEMPLATE;
- $r=0;
- foreach($template as $row) {
- foreach($row as $key) {
- $v_name = 'buttons_'.$key;
- if($key == 'teamlvl' or $key == 'pokemon' or $key == 'time') {
- // Some button variables are "blocks" of keys, process them here
- if(empty(${$v_name})) continue;
- foreach(${$v_name} as $teamlvl) {
- if(!isset($keys[$r])) $keys[$r] = [];
- $keys[$r] = array_merge($keys[$r],$teamlvl);
- $r++;
- }
- $r--;
- }else {
- if(empty(${$v_name})) continue;
- $keys[$r][] = ${$v_name};
- }
- }
- if(!empty($keys[$r][0])) $r++;
- }
- }
+ $hide_users_sql = 'AND attend_time > (UTC_TIMESTAMP() - INTERVAL ' . $config->RAID_POLL_HIDE_USERS_TIME . ' MINUTE)';
+ }
+ }
+
+ // Get participants
+ $rs = my_query('
+ SELECT count(attend_time) AS count,
+ sum(pokemon = 0) AS count_any_pokemon,
+ sum(pokemon = ?) AS count_raid_pokemon
+ FROM attendance
+ WHERE raid_id = ?
+ ' . $hide_users_sql . '
+ AND attend_time IS NOT NULL
+ AND raid_done != 1
+ AND cancel != 1
+ ', [$raid_pokemon, $raid['id']]
+ );
+
+ $row = $rs->fetch();
+
+ // Count participants and participants by pokemon
+ $count_pp = $row['count'];
+ $count_any_pokemon = $row['count_any_pokemon'];
+ $count_raid_pokemon = $row['count_raid_pokemon'];
+
+ // Write to log.
+ debug_log('Participants for raid with ID ' . $raid['id'] . ': ' . $count_pp);
+ debug_log('Participants who voted for any pokemon: ' . $count_any_pokemon);
+ debug_log('Participants who voted for ' . $raid_pokemon . ': ' . $count_raid_pokemon);
+
+ // Zero Participants? Show only time buttons!
+ if($row['count'] == 0) {
+ return $buttons['time'];
+ }
+
+ // Init keys pokemon array.
+ $buttons['pokemon'] = [];
+ // Show pokemon keys only if the raid boss is an egg
+ if(in_array($raid_pokemon_id, EGGS)) {
+ // Get pokemon from database
+ $raid_spawn = dt2time($raid['spawn'], 'Y-m-d H:i'); // Convert utc spawntime to local time
+ $raid_bosses = get_raid_bosses($raid_spawn, $raid_level);
+
+ if(count($raid_bosses) > 2) {
+ // Add key for each raid level
+ foreach($raid_bosses as $pokemon) {
+ if(in_array($pokemon['pokedex_id'], EGGS)) continue;
+ $buttons['pokemon'][] = button(
+ get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id'], $config->LANGUAGE_PUBLIC),
+ ['vote_pokemon', 'r' => $raid['id'], 'p' => $pokemon['pokedex_id'] . '-' . $pokemon['pokemon_form_id']]
+ );
+ }
+
+ // Add button if raid boss does not matter
+ $buttons['pokemon'][] = button(getPublicTranslation('any_pokemon'), ['vote_pokemon', 'r' => $raid['id']]);
+
+ // Finally add pokemon to keys
+ $buttons['pokemon'] = inline_key_array($buttons['pokemon'], 2);
+ }
+ }
+
+ // Init keys array
+ $keys = [];
+
+ $template = $config->RAID_POLL_UI_TEMPLATE;
+ if($raid['event_poll_template'] != null) $template = json_decode($raid['event_poll_template']);
+ $r = 0;
+ foreach($template as $row) {
+ foreach($row as $key) {
+ if(!isset($buttons[$key]) or empty($buttons[$key])) continue;
+ if($key == 'teamlvl' or $key == 'pokemon' or $key == 'time') {
+ // Some button variables are "blocks" of keys, process them here
+ foreach($buttons[$key] as $teamlvl) {
+ if(!isset($keys[$r])) $keys[$r] = [];
+ $keys[$r] = array_merge($keys[$r],$teamlvl);
+ $r++;
}
+ $r--;
+ continue;
+ }
+ $keys[$r][] = $buttons[$key];
}
+ if(!empty($keys[$r][0])) $r++;
+ }
+
+ // Return the keys.
+ return $keys;
+}
- // Return the keys.
- return $keys;
+/**
+ * Get active raid bosses at a certain time.
+ * @param string $time - string, datetime, local time
+ * @param int $raid_level
+ * @return array
+ */
+function get_raid_bosses($time, $raid_level)
+{
+ // Get raid level from database
+ $rs = my_query('
+ SELECT DISTINCT pokedex_id, pokemon_form_id
+ FROM raid_bosses
+ WHERE ? BETWEEN date_start AND date_end
+ AND raid_level = ?
+ ', [$time, $raid_level]);
+ debug_log('Checking active raid bosses for raid level '.$raid_level.' at '.$time.':');
+ $raid_bosses = [];
+ $egg_found = false;
+ while ($result = $rs->fetch()) {
+ $raid_bosses[] = $result;
+ if($result['pokedex_id'] == '999'.$raid_level) $egg_found = true;
+ debug_log('Pokedex id: '.$result['pokedex_id'].' | Form id: '.$result['pokemon_form_id']);
+ }
+ if(!$egg_found) $raid_bosses[] = ['pokedex_id' => '999'.$raid_level, 'pokemon_form_id' => 0]; // Add egg if it wasn't found from db
+ return $raid_bosses;
}
-?>
+/**
+ * Get active raid bosses at a certain time.
+ * @param int $RAID_SLOTS Length of the timeslot
+ * @param array $raid
+ * @return array
+ */
+function generateTimeslotKeys($RAID_SLOTS, $raid) {
+ global $config;
+ // Get current time.
+ $dt_now = DateTimeImmutable::createFromFormat('Y-m-d H:i', date('Y-m-d H:i'));
+
+ // Get direct start slot
+ $direct_slot = new DateTimeImmutable($raid['start_time'], new DateTimeZone('UTC'));
+ $directStartMinutes = $direct_slot->format('i');
+
+ // Get first raidslot rounded up to the next 5 minutes
+ $minute = $directStartMinutes % 5;
+ $diff = ($minute != 0) ? 5 - $minute : 0;
+ $five_slot = $direct_slot->add(new DateInterval('PT'.$diff.'M'));
+
+ // Add $config->RAID_FIRST_START minutes to five minutes slot
+ $five_plus_slot = $five_slot;
+ $five_plus_slot = $five_plus_slot->add(new DateInterval("PT".$config->RAID_FIRST_START."M"));
+
+ // Get first regular raidslot
+ $firstSlotMinute = $directStartMinutes % $RAID_SLOTS;
+ $firstSlotDiff = ($firstSlotMinute != 0) ? $RAID_SLOTS - ($firstSlotMinute) : 0;
+ $first_slot = $direct_slot->add(new DateInterval('PT'.$firstSlotDiff.'M'));
+
+ // Write slots to log.
+ debug_log($direct_slot, 'Direct start slot:');
+ debug_log($five_slot, 'Next 5 Minute slot:');
+ debug_log($first_slot, 'First regular slot:');
+ $keys_time = [];
+ // Add button for direct start if needed
+ if(($config->RAID_DIRECT_START && !$config->RAID_RSVP_SLOTS) && $direct_slot != $five_slot && $direct_slot >= $dt_now) {
+ $keys_time[$direct_slot->format('YmdHi')] = button(timeslot_label($direct_slot), ['vote_time', 'r' => $raid['id'], 't' => $direct_slot->format('YmdHis')]);
+ }
+
+ // Add button for first five minutes if needed
+ if($five_slot < $first_slot && $five_plus_slot <= $first_slot && $five_slot >= $dt_now) {
+ $keys_time[$five_slot->format('YmdHi')] = button(timeslot_label($five_slot), ['vote_time', 'r' => $raid['id'], 't' => $five_slot->format('YmdHis')]);
+ }
+
+ // Get regular slots
+ // Start with second slot as first slot is already added to keys.
+ $dt_end = new DateTimeImmutable($raid['end_time'], new DateTimeZone('UTC'));
+ $regular_slots = new DatePeriod($first_slot, new DateInterval('PT'.$RAID_SLOTS.'M'), $dt_end->sub(new DateInterval('PT'.$config->RAID_LAST_START.'M')));
+
+ // Add regular slots.
+ foreach($regular_slots as $slot){
+ debug_log($slot, 'Regular slot:');
+ // Add regular slot.
+ if($slot >= $dt_now) {
+ $keys_time[$slot->format('YmdHi')] = button(timeslot_label($slot), ['vote_time', 'r' => $raid['id'], 't' => $slot->format('YmdHis')]);
+ }
+ // Set last slot for later.
+ $last_slot = $slot;
+ }
+
+ // Add raid last start slot
+ // Set end_time to last extra slot, subtract $config->RAID_LAST_START minutes and round down to earlier 5 minutes.
+ $last_extra_slot = $dt_end->sub(new DateInterval('PT'.$config->RAID_LAST_START.'M'));
+ $s = 5 * 60;
+ $last_extra_slot = $last_extra_slot->setTimestamp($s * floor($last_extra_slot->getTimestamp() / $s));
+
+ // Log last and last extra slot.
+ if(isset($last_slot)) debug_log($last_slot, 'Last slot:');
+ debug_log($last_extra_slot, 'Last extra slot:');
+
+ // Last extra slot not conflicting with last slot
+ if($last_extra_slot >= $dt_now &&
+ ((isset($last_slot) && $last_extra_slot > $last_slot && $last_extra_slot != $last_slot) ||
+ !isset($last_slot))) {
+ // Add last extra slot
+ $keys_time[$last_extra_slot->format('YmdHi')] = button(timeslot_label($last_extra_slot), ['vote_time', 'r' => $raid['id'], 't' => $last_extra_slot->format('YmdHis')]);
+ }
+
+ if($config->RAID_RSVP_SLOTS) {
+ $rsvp_slots = new DatePeriod($direct_slot, new DateInterval('PT15M'), 2);
+ foreach($rsvp_slots as $slot){
+ debug_log($slot, 'RSVP slot:');
+ if($slot < $dt_now) continue;
+ // Add RSVP slot.
+ $keys_time[$slot->format('YmdHi')] = button(timeslot_label($slot), ['vote_time', 'r' => $raid['id'], 't' => $slot->format('YmdHis')]);
+ }
+ }
+
+ // Sort keys by time and reindex array
+ asort($keys_time);
+ $keys_time = array_values($keys_time);
+
+ // Attend raid at any time
+ if($config->RAID_ANYTIME) {
+ $keys_time[] = button(getPublicTranslation('anytime'), ['vote_time', 'r' => $raid['id']]);
+ }
+ return $keys_time;
+}
+
+/**
+ * Generate timeslot label in local time.
+ * @param DateTime $datetime
+ * @return string
+ */
+function timeslot_label($datetime)
+{
+ global $config;
+ $tz = $config->TIMEZONE;
+ // Change the timezone of the object without changing it's time
+ $new = $datetime->setTimezone(new DateTimeZone($tz));
+ return $new->format('H:i');
+}
\ No newline at end of file
diff --git a/logic/language.php b/logic/language.php
new file mode 100644
index 00000000..3f3545da
--- /dev/null
+++ b/logic/language.php
@@ -0,0 +1,105 @@
+ false,
+ 'pokemonNames' => false,
+ 'pokemonMoves' => false,
+ 'pokemonForms' => false,
+ 'botHelp' => false,
+ 'custom' => false,
+ ];
+ static $fileMap = [
+ 'botLang' => 'language',
+ 'pokemonNames' => 'pokemon',
+ 'pokemonMoves' => 'pokemon_moves',
+ 'pokemonForms' => 'pokemon_forms',
+ 'botHelp' => 'help',
+ ];
+ $translation = $savedTranslations[$translationTitle];
+
+ // Return translation if it's in memory already
+ if($translation !== false) return $translation;
+
+ // Load translations from this file
+ $fileContents = file_get_contents(BOT_LANG_PATH . '/' . $fileMap[$translationTitle] . '.json');
+ $translation = json_decode($fileContents, true);
+
+ // Has custom translation already been processed?
+ if($savedTranslations['custom'] === false) {
+ $savedTranslations['custom'] = [];
+ // Load custom language file if it exists
+ if(is_file(CUSTOM_PATH . '/language.json')) {
+ $customContents = file_get_contents(CUSTOM_PATH . '/language.json');
+ $savedTranslations['custom'] = json_decode($customContents, true);
+ }
+ }
+
+ foreach($savedTranslations['custom'] as $title => $value) {
+ if(key_exists($title, $translation)) {
+ debug_log($title, 'Found custom translation for');
+ // Only overwrite the translation for languages that are present
+ foreach($value as $lang => $newValue) {
+ $translation[$title][$lang] = $newValue;
+ }
+ unset($savedTranslations['custom'][$title]);
+ }
+ }
+ $savedTranslations[$translationTitle] = $translation;
+
+ return $translation;
+}
+
+/**
+ * Call the translation function with override parameters.
+ * @param string $text
+ * @return string translation
+ */
+function getPublicTranslation($text)
+{
+ global $config;
+ return getTranslation($text, $config->LANGUAGE_PUBLIC);
+}
+
+/**
+ * Gets a table translation out of the json file.
+ * @param string $text
+ * @param string $override_language
+ * @return string translation
+ */
+function getTranslation($text, $language = false)
+{
+ global $botUser;
+ if($language === false) $language = $botUser->userLanguage;
+ $text = trim($text);
+
+ $tfile = 'botLang';
+ // Pokemon name?
+ if(strpos($text, 'pokemon_id_') === 0) $tfile = 'pokemonNames';
+
+ // Pokemon form?
+ if(strpos($text, 'pokemon_form_') === 0) $tfile = 'pokemonForms';
+
+ // Pokemon moves?
+ if(strpos($text, 'pokemon_move_') === 0) $tfile = 'pokemonMoves';
+
+ // Pokemon moves?
+ if(strpos($text, 'help_') === 0) $tfile = 'botHelp';
+
+ $translations = getTranslationFile($tfile);
+
+ // Fallback to English when there is no language key or translation is not yet done.
+ if(isset($translations[$text][$language]) && $translations[$text][$language] != 'TRANSLATE')
+ $translation = $translations[$text][$language];
+ elseif(isset($translations[$text][DEFAULT_LANGUAGE]))
+ $translation = $translations[$text][DEFAULT_LANGUAGE];
+
+ // No translation found
+ elseif($tfile == 'botHelp' or $tfile == 'pokemonForms')
+ $translation = false;
+ else
+ $translation = $text;
+
+ debug_log("$text @ $tfile -> $translation", 'T:');
+ return $translation;
+}
diff --git a/logic/mapslink.php b/logic/mapslink.php
index cff5f41b..ad4ad728 100644
--- a/logic/mapslink.php
+++ b/logic/mapslink.php
@@ -21,7 +21,7 @@ function mapslink($gym, $gym_address = '0'){
switch ($gym_address) {
case '1':
//using gym address as maps link
- $gym['address'] = 'https://maps.google.com/?daddr=' . $gym['lat'] . ',' . $gym['lon'];
+ $gym['address'] = 'https://maps.google.com/?daddr=' . $gym['lat'] . '%2C' . $gym['lon'];
break;
case '0':
// do nothing -> getting default address from gym/raid
@@ -33,13 +33,12 @@ function mapslink($gym, $gym_address = '0'){
if($maps_route){
// getting link for route calculation
- $maps_link = '' . $gym['address'] . '';
+ $maps_link = '' . $gym['address'] . '';
}else{
// getting link for normal maps point
- $maps_link = '' . $gym['address'] . '';
+ $maps_link = '' . $gym['address'] . '';
}
// returning Maps Link
return $maps_link;
}
-?>
diff --git a/logic/new_user.php b/logic/new_user.php
index b42867ab..f5e0f408 100644
--- a/logic/new_user.php
+++ b/logic/new_user.php
@@ -5,8 +5,23 @@
* @return bool
*/
function new_user($user_id) {
- global $config;
- if(!$config->TUTORIAL_MODE || user_tutorial($user_id) < $config->TUTORIAL_LEVEL_REQUIREMENT) return true;
- else return false;
+ global $config, $botUser;
+ if($config->TUTORIAL_MODE && in_array("force-tutorial", $botUser->userPrivileges['privileges']) && user_tutorial($user_id) < $config->TUTORIAL_LEVEL_REQUIREMENT)
+ return true;
+ return false;
+}
+
+/**
+ * Return the tutorial value from users table
+ * @param $user_id
+ * @return int
+ */
+function user_tutorial($user_id) {
+ debug_log('Reading user\'s tutorial value: '.$user_id);
+ $query = my_query('SELECT tutorial FROM users WHERE user_id = :user_id LIMIT 1', [":user_id"=>$user_id]);
+ $res = $query->fetch();
+ $result = 0;
+ if($query->rowCount() > 0) $result = $res['tutorial'];
+ debug_log('Result: '.$result);
+ return $result;
}
-?>
\ No newline at end of file
diff --git a/logic/pokemon_keys.php b/logic/pokemon_keys.php
index f282ef54..e18c5392 100644
--- a/logic/pokemon_keys.php
+++ b/logic/pokemon_keys.php
@@ -1,52 +1,50 @@
RAID_EGG_DURATION.' MINUTE) between date_start and date_end
- OR DATE_ADD(\'' . $time_now . '\', INTERVAL '.$config->RAID_DURATION.' MINUTE) between date_start and date_end
- )
- UNION
- SELECT id, pokedex_id, pokemon_form_id
- FROM pokemon
- WHERE pokedex_id = \'' . $egg_id . '\'
- ORDER BY pokedex_id
- ';
- $rs = my_query($query);
- // Add key for each raid level
- while ($pokemon = $rs->fetch()) {
- $keys[] = array(
- 'text' => get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id']),
- 'callback_data' => $gym_id_plus_letter . ':' . $action . ':' . (($event_id!==false) ? $event_id . ',' . $raid_level . ',' : '') . $pokemon['id']
- );
- }
+ // Get pokemon from database
+ $rs = my_query('
+ SELECT pokemon.id, pokemon.pokedex_id, pokemon.pokemon_form_id
+ FROM raid_bosses
+ LEFT JOIN pokemon
+ ON pokemon.pokedex_id = raid_bosses.pokedex_id
+ AND pokemon.pokemon_form_id = raid_bosses.pokemon_form_id
+ WHERE raid_bosses.raid_level = :raidLevel
+ AND (
+ DATE_SUB(\'' . $time_now . '\', INTERVAL '.$config->RAID_EGG_DURATION.' MINUTE) between date_start and date_end
+ OR DATE_ADD(\'' . $time_now . '\', INTERVAL '.$config->RAID_DURATION.' MINUTE) between date_start and date_end
+ )
+ UNION
+ SELECT id, pokedex_id, pokemon_form_id
+ FROM pokemon
+ WHERE pokedex_id = :eggId
+ ORDER BY pokedex_id
+ ', ['raidLevel' => $raid_level, 'eggId' => $egg_id]
+ );
+ // Add key for each raid level
+ $callbackData[0] = $action;
+ while ($pokemon = $rs->fetch()) {
+ $callbackData['p'] = $pokemon['id'];
+ $keys[] = button(get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id']), $callbackData);
+ }
- // Get the inline key array.
- $keys = inline_key_array($keys, 1);
+ // Get the inline key array.
+ $keys = inline_key_array($keys, 1);
- return $keys;
+ return $keys;
}
-
-?>
diff --git a/logic/raid_access_check.php b/logic/raid_access_check.php
deleted file mode 100644
index 203a0dad..00000000
--- a/logic/raid_access_check.php
+++ /dev/null
@@ -1,53 +0,0 @@
-fetch();
-
- // Check permissions
- if ($rs->rowCount() == 0 or $update['callback_query']['from']['id'] != $raid['user_id']) {
- // Check "-all" permission
- debug_log('Checking permission:' . $permission . '-all');
- $permission = $permission . '-all';
- $raid_access = bot_access_check($update, $permission, $return_result);
- } else {
- // Check "-own" permission
- debug_log('Checking permission:' . $permission . '-own');
- $permission_own = $permission . '-own';
- $permission_all = $permission . '-all';
- $raid_access = bot_access_check($update, $permission_own, true);
-
- // Check "-all" permission if we get "access denied"
- // Maybe necessary if user has only "-all" configured, but not "-own"
- if(!$raid_access) {
- debug_log('Permission check for ' . $permission_own . ' failed! Maybe the access is just granted via ' . $permission . '-all ?');
- debug_log('Checking permission:' . $permission_all);
- $raid_access = bot_access_check($update, $permission_all, $return_result);
- } else {
- $raid_access = bot_access_check($update, $permission_own, $return_result);
- }
- }
-
- // Return result
- return $raid_access;
-}
-
-
-?>
diff --git a/logic/raid_edit_gym_keys.php b/logic/raid_edit_gym_keys.php
deleted file mode 100644
index 5868b04a..00000000
--- a/logic/raid_edit_gym_keys.php
+++ /dev/null
@@ -1,128 +0,0 @@
-RAID_CUSTOM_GYM_LETTERS) && $first_length == 1) {
- // Explode special letters.
- $special_keys = explode(',', $config->RAID_CUSTOM_GYM_LETTERS);
-
- foreach($special_keys as $id => $letter)
- {
- $letter = trim($letter);
- debug_log($letter, 'Special gym letter:');
- // Fix chinese chars, prior: $length = strlen($letter);
- $length = strlen(utf8_decode($letter));
- $not .= SP . "AND UPPER(LEFT(gym_name, " . $length . ")) != UPPER('" . $letter . "')" . SP;
- }
- }
- $gymarea_query = '';
- if($gymarea_id != false) {
- $json = json_decode(file_get_contents(CONFIG_PATH . '/geoconfig_gym_areas.json'),1);
- $points = [];
- foreach($json as $area) {
- if($gymarea_id == $area['id']) {
- foreach($area['path'] as $point) {
- $points[] = $point[0].' '.$point[1];
- }
- if($points[0] != $points[count($points)-1]) $points[] = $points[0];
- break;
- }
- }
- $polygon_string = implode(',', $points);
- $gymarea_query = "AND ST_CONTAINS(ST_GEOMFROMTEXT('POLYGON((".$polygon_string."))'), ST_GEOMFROMTEXT(CONCAT('POINT(',lat,' ',lon,')')))";
- }
- // Show hidden gyms?
- if($hidden == true) {
- $show_gym = 0;
- } else {
- $show_gym = 1;
- }
- $query_collate = "";
- if($config->MYSQL_SORT_COLLATE != "") {
- $query_collate = "COLLATE " . $config->MYSQL_SORT_COLLATE;
- }
- // Get gyms from database
- $rs = my_query(
- "
- SELECT gyms.id, gyms.gym_name, gyms.ex_gym,
- CASE WHEN SUM(raids.end_time > UTC_TIMESTAMP() - INTERVAL 10 MINUTE) THEN 1 ELSE 0 END AS active_raid
- FROM gyms
- LEFT JOIN raids
- ON raids.gym_id = gyms.id
- WHERE UPPER(LEFT(gym_name, $first_length)) = UPPER('{$first}')
- $not
- $gymarea_query
- AND gyms.show_gym = {$show_gym}
- GROUP BY gym_name, raids.gym_id, gyms.id, gyms.ex_gym
- ORDER BY gym_name " . $query_collate . "
- "
- );
-
- // Init empty keys array.
- $keys = [];
-
- while ($gym = $rs->fetch()) {
- // Add delete argument to keys
- if ($delete == true) {
- $arg = $gym['id'] . '-delete';
- } else {
- $arg = $gym['id'];
- }
-
- // List action to list only gyms with active raids, so always continue at the end
- if ($action == 'list_raid') {
- if ($gym['active_raid'] == 1) {
- $keys[] = array(
- 'text' => $gym['gym_name'],
- 'callback_data' => '0:' . $action . ':' . $arg
- );
- }
- // Continue always in case of list action
- continue;
- }
-
- // Write to log.
- // debug_log($gym);
-
- $active_raid = active_raid_duplication_check($gym['id']);
-
- // Show Ex-Gym-Marker?
- if($config->RAID_CREATION_EX_GYM_MARKER && $gym['ex_gym'] == 1) {
- $ex_raid_gym_marker = (strtolower($config->RAID_EX_GYM_MARKER) == 'icon') ? EMOJI_STAR : $config->RAID_EX_GYM_MARKER;
- $gym_name = $ex_raid_gym_marker . SP . $gym['gym_name'];
- } else {
- $gym_name = $gym['gym_name'];
- }
- // Add warning emoji for active raid
- if ($active_raid > 0) {
- $gym_name = EMOJI_WARN . SP . $gym_name;
- }
- $keys[] = array(
- 'text' => $gym_name,
- 'callback_data' => $first . ':' . $action . ':' . $arg
- );
- }
-
- // Get the inline key array.
- $keys = inline_key_array($keys, 1);
-
- return $keys;
-
-}
-
-?>
diff --git a/logic/raid_edit_gyms_first_letter_keys.php b/logic/raid_edit_gyms_first_letter_keys.php
deleted file mode 100644
index c5c02206..00000000
--- a/logic/raid_edit_gyms_first_letter_keys.php
+++ /dev/null
@@ -1,179 +0,0 @@
-ENABLE_GYM_AREAS) {
- $json = json_decode(file_get_contents(CONFIG_PATH . '/geoconfig_gym_areas.json'),1);
- $points = [];
- foreach($json as $area) {
- $gymarea_id = ($gymarea_id !== false) ? $gymarea_id : $config->DEFAULT_GYM_AREA;
- if($gymarea_id !== false && $gymarea_id == $area['id']) {
- foreach($area['path'] as $point) {
- $points[] = $point[0].' '.$point[1];
- }
- $gymarea_name = $area['name'];
- if($points[0] != $points[count($points)-1]) $points[] = $points[0];
- $skip_letter_keys = false;
- } else {
- $gymarea_keys[] = [
- 'text' => $area['name'],
- 'callback_data' => $area['id'] . ':' . $gymarea_action . ':' . $action
- ];
- }
- }
- $polygon_string = implode(',', $points);
- $gymarea_query = "AND ST_CONTAINS(ST_GEOMFROMTEXT('POLYGON((".$polygon_string."))'), ST_GEOMFROMTEXT(CONCAT('POINT(',lat,' ',lon,')')))";
- }
- // Init empty keys array.
- $keys = [];
-
- if(!$skip_letter_keys or !$config->ENABLE_GYM_AREAS or $hidden) {
- // Special/Custom gym letters?
- if(!empty($config->RAID_CUSTOM_GYM_LETTERS)) {
- // Explode special letters.
- $special_keys = explode(',', $config->RAID_CUSTOM_GYM_LETTERS);
- $select = 'SELECT CASE ';
- foreach($special_keys as $letter)
- {
- $letter = trim($letter);
- debug_log($letter, 'Special gym letter:');
- // Fix chinese chars, prior: $length = strlen($letter);
- $length = strlen(utf8_decode($letter));
- $select .= SP . "WHEN UPPER(LEFT(gym_name, " . $length . ")) = '" . $letter . "' THEN UPPER(LEFT(gym_name, " . $length . "))" . SP;
- }
- $select .= 'ELSE UPPER(LEFT(gym_name, 1)) END AS first_letter';
- $group_order = 'GROUP BY 1 ORDER BY gym_name';
- }else {
- $select = 'SELECT DISTINCT UPPER(SUBSTR(gym_name, 1, 1)) AS first_letter';
- $group_order = 'ORDER BY 1';
- }
- // Show hidden gyms?
- $show_gym = $hidden ? 0 : 1;
-
- if($action == 'list_by_gym') {
- // Select only gyms with active raids
- $query_condition = '
- LEFT JOIN raids
- ON raids.gym_id = gyms.id
- WHERE end_time > UTC_TIMESTAMP()
- AND show_gym = ' . $show_gym;
- }else {
- $query_condition = 'WHERE show_gym = ' . $show_gym;
- }
-
- $rs_count = my_query("SELECT COUNT(gym_name) as count FROM gyms {$query_condition} {$gymarea_query}");
- $gym_count = $rs_count->fetch();
- $rs = my_query(
- "
- {$select}
- FROM gyms
- {$query_condition}
- {$gymarea_query}
- {$group_order}
- "
- );
- // If found over 20 gyms, print letters
- if($gym_count['count'] > 20) {
- while ($gym = $rs->fetch()) {
- // Add first letter to keys array
- $keys[] = array(
- 'text' => $gym['first_letter'],
- 'callback_data' => $show_gym . ':' . $action . ':' . $gym['first_letter'] . (($gymarea_id !== 'n') ? ',' .$gymarea_id : '')
- );
- }
-
- // Get the inline key array.
- $keys = inline_key_array($keys, 4);
- $letters = true;
- }else {
- // If less than 20 gyms was found, print gym names
- if($action == 'list_by_gym') {
- // Select only gyms with active raids
- $query_condition = '
- WHERE end_time > UTC_TIMESTAMP()
- AND show_gym = ' . $show_gym;
- }else {
- $query_condition = 'WHERE show_gym = ' . $show_gym;
- }
- $query_collate = '';
- if($config->MYSQL_SORT_COLLATE != "") {
- $query_collate = "COLLATE " . $config->MYSQL_SORT_COLLATE;
- }
- $rs = my_query(
- "
- SELECT gyms.id, gyms.gym_name, gyms.ex_gym,
- CASE WHEN SUM(raids.end_time > UTC_TIMESTAMP() - INTERVAL 10 MINUTE) THEN 1 ELSE 0 END AS active_raid
- FROM gyms
- LEFT JOIN raids
- ON raids.gym_id = gyms.id
- {$query_condition}
- {$gymarea_query}
- GROUP BY gym_name, raids.gym_id, gyms.id, gyms.ex_gym
- ORDER BY gym_name " . $query_collate . "
- "
- );
- // Init empty keys array.
- $keys = [];
-
- while ($gym = $rs->fetch()) {
- if($gym['id'] != NULL) {
- $active_raid = active_raid_duplication_check($gym['id']);
-
- // Show Ex-Gym-Marker?
- if($config->RAID_CREATION_EX_GYM_MARKER && $gym['ex_gym'] == 1) {
- $ex_raid_gym_marker = (strtolower($config->RAID_EX_GYM_MARKER) == 'icon') ? EMOJI_STAR : $config->RAID_EX_GYM_MARKER;
- $gym_name = $ex_raid_gym_marker . SP . $gym['gym_name'];
- } else {
- $gym_name = $gym['gym_name'];
- }
- // Add warning emoji for active raid
- if ($active_raid > 0) {
- $gym_name = EMOJI_WARN . SP . $gym_name;
- }
- $keys[] = array(
- 'text' => $gym_name,
- 'callback_data' => 'gl' . $gymarea_id . ':' . $gym_name_action . ':' . $gym['id']
- );
- }
- }
-
- // Get the inline key array.
- $keys = inline_key_array($keys, 1);
- }
- }
-
- // Add back navigation key.
- if($hidden == false) {
- if($config->RAID_VIA_LOCATION_FUNCTION == 'remote') {
- $query_remote = my_query('SELECT count(*) as count FROM raids LEFT JOIN gyms on raids.gym_id = gyms.id WHERE raids.end_time > (UTC_TIMESTAMP() - INTERVAL 10 MINUTE) AND temporary_gym = 1');
- if($query_remote->fetch()['count'] > 0) {
- $keys[][] = array(
- 'text' => getTranslation('remote_raids'),
- 'callback_data' => '0:list_remote_gyms:0'
- );
- }
- }
- $nav_keys = [];
- if(!empty($gymarea_keys) && ($config->DEFAULT_GYM_AREA !== false || $gymarea_id === false)) $keys = array_merge($keys, inline_key_array($gymarea_keys, 2));
-
- // Get the inline key array.
- $keys[] = $nav_keys;
- }
-
- return ['keys' => $keys, 'gymarea_name' => $gymarea_name, 'letters' => $letters];
-}
-
-?>
diff --git a/logic/raid_edit_raidlevel_keys.php b/logic/raid_edit_raidlevel_keys.php
index f06d0cab..3f783fcc 100644
--- a/logic/raid_edit_raidlevel_keys.php
+++ b/logic/raid_edit_raidlevel_keys.php
@@ -1,90 +1,84 @@
RAID_EGG_DURATION.' MINUTE) between date_start and date_end
+ OR DATE_ADD(UTC_TIMESTAMP(), INTERVAL '.$config->RAID_DURATION.' MINUTE) between date_start and date_end
+ )
+ '.$query_event.'
+ GROUP BY raid_bosses.raid_level
+ ORDER BY (CASE WHEN raid_level = ' . RAID_ID_EX . ' THEN 0 ELSE 1 END) DESC, raid_level DESC
+ ';
+ // Get all raid levels from database
+ $rs_counts = my_query($query_counts);
- if($event === false) {
- // Set event ID to null if no event was selected
- $event_id = 'N';
- $query_event = 'AND raid_bosses.raid_level != \'X\'';
- }else {
- $event_id = $event;
- $query_event = '';
- }
- $query_counts = '
- SELECT raid_level, COUNT(*) AS raid_level_count
- FROM raid_bosses
- WHERE (
- DATE_SUB(\'' . $time_now . '\', INTERVAL '.$config->RAID_EGG_DURATION.' MINUTE) between date_start and date_end
- OR DATE_ADD(\'' . $time_now . '\', INTERVAL '.$config->RAID_DURATION.' MINUTE) between date_start and date_end
- )
- '.$query_event.'
- GROUP BY raid_bosses.raid_level
- ORDER BY FIELD(raid_bosses.raid_level, \'6\', \'5\', \'4\', \'3\', \'2\', \'1\', \'X\')
- ';
- // Get all raid levels from database
- $rs_counts = my_query($query_counts);
-
- // Init empty keys array.
- $keys = [];
-
- // Add key for each raid level
- while ($level = $rs_counts->fetch()) {
- // Raid level and action
- $raid_level = $level['raid_level'];
+ // Init empty keys array.
+ $keys = [];
- // Add key for pokemon if we have just 1 pokemon for a level
- if($level['raid_level_count'] == 1) {
- $query_mon = my_query('
- SELECT pokemon.id, pokemon.pokedex_id, pokemon.pokemon_form_id
- FROM raid_bosses
- LEFT JOIN pokemon
- ON pokemon.pokedex_id = raid_bosses.pokedex_id
- AND pokemon.pokemon_form_id = raid_bosses.pokemon_form_id
- WHERE (
- DATE_SUB(\'' . $time_now . '\', INTERVAL '.$config->RAID_EGG_DURATION.' MINUTE) between date_start and date_end
- OR DATE_ADD(\'' . $time_now . '\', INTERVAL '.$config->RAID_DURATION.' MINUTE) between date_start and date_end
- )
- AND raid_level = \''.$raid_level.'\'
- '.$query_event.'
- LIMIT 1
- ');
- $pokemon = $query_mon->fetch();
- // Add key for pokemon
- $keys[] = array(
- 'text' => get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id']),
- 'callback_data' => $gym_id . ',' . $gym_first_letter . ':edit_starttime:' . $event_id . ',' . $raid_level . ',' . $pokemon['id']
- );
- } else {
- // Add key for raid level
- $keys[] = array(
- 'text' => getTranslation($raid_level . 'stars'),
- 'callback_data' => $gym_id . ',' . $gym_first_letter . ':edit_pokemon:' . $event_id . ',' . $raid_level
- );
- }
+ // Add key for each raid level
+ $buttonData = $callbackData;
+ while ($level = $rs_counts->fetch()) {
+ if ($level['raid_level'] == 9 && $excludeElite) continue;
+ // Add key for pokemon if we have just 1 pokemon for a level
+ if($level['raid_level_count'] != 1) {
+ // Raid level and action
+ $buttonData[0] = 'edit_pokemon';
+ $buttonData['rl'] = $level['raid_level'];
+ // Add key for raid level
+ $keys[] = button(getTranslation($level['raid_level'] . 'stars'), $buttonData);
+ continue;
}
- // Add key for raid event if user allowed to create event raids
- if($admin_access[1] === true && $event === false) {
- $keys[] = array(
- 'text' => getTranslation('event'),
- 'callback_data' => $gym_id . ',' . $gym_first_letter . ':edit_event:0'
- );
- }
-
- // Get the inline key array.
- $keys = inline_key_array($keys, 3);
+ $query_mon = my_query('
+ SELECT pokemon.id, pokemon.pokedex_id, pokemon.pokemon_form_id
+ FROM raid_bosses
+ LEFT JOIN pokemon
+ ON pokemon.pokedex_id = raid_bosses.pokedex_id
+ AND pokemon.pokemon_form_id = raid_bosses.pokemon_form_id
+ WHERE (
+ DATE_SUB(UTC_TIMESTAMP(), INTERVAL '.$config->RAID_EGG_DURATION.' MINUTE) between date_start and date_end
+ OR DATE_ADD(UTC_TIMESTAMP(), INTERVAL '.$config->RAID_DURATION.' MINUTE) between date_start and date_end
+ )
+ AND raid_level = ?
+ '.$query_event.'
+ LIMIT 1
+ ', [$level['raid_level']]
+ );
+ $pokemon = $query_mon->fetch();
+ $buttonData[0] = 'edit_starttime';
+ $buttonData['rl'] = $level['raid_level'];
+ $buttonData['p'] = $pokemon['id'];
+ // Add key for pokemon
+ $keys[] = button(get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id']), $buttonData);
+ unset($buttonData['p']);
+ }
+ // Add key for raid event if user allowed to create event raids
+ if(($admin_access[1] === true or $admin_access[0] === true) && $event === false) {
+ $eventData = $callbackData;
+ $eventData[0] = 'edit_event';
+ $keys[] = button(getTranslation('event'), $eventData);
+ }
- return $keys;
-}
+ // Get the inline key array.
+ $keys = inline_key_array($keys, 3);
-?>
+ return $keys;
+}
diff --git a/logic/raid_get_gyms_list_keys.php b/logic/raid_get_gyms_list_keys.php
index 5d99b73e..111e7f12 100644
--- a/logic/raid_get_gyms_list_keys.php
+++ b/logic/raid_get_gyms_list_keys.php
@@ -6,54 +6,36 @@
*/
function raid_get_gyms_list_keys($searchterm)
{
- // Init empty keys array.
- $keys = [];
-
- // Make sure the search term is not empty
- if(!empty($searchterm)) {
- // Get gyms from database
- $rs = my_query(
- "
- SELECT id, gym_name
- FROM gyms
- WHERE gym_name LIKE '$searchterm%'
- AND show_gym LIKE 1
- OR gym_name LIKE '%$searchterm%'
- AND show_gym LIKE 1
- ORDER BY
- CASE
- WHEN gym_name LIKE '$searchterm%' THEN 1
- WHEN gym_name LIKE '%$searchterm%' THEN 2
- ELSE 3
- END
- LIMIT 15
- "
- );
-
- while ($gym = $rs->fetch()) {
- $first = strtoupper(substr($gym['gym_name'], 0, 1));
- $keys[] = array(
- 'text' => $gym['gym_name'],
- 'callback_data' => $first . ':edit_raidlevel:' . $gym['id']
- );
- }
- }
-
- // Add abort key.
- if($keys) {
- // Get the inline key array.
- $keys = inline_key_array($keys, 1);
-
- // Add back navigation key.
- $nav_keys = [];
- $nav_keys[] = universal_inner_key($keys, '0', 'exit', '0', getTranslation('abort'));
-
- // Get the inline key array.
- $keys[] = $nav_keys;
- }
-
- return $keys;
+ // Get gyms from database
+ $rs = my_query('
+ SELECT id, gym_name
+ FROM gyms
+ WHERE gym_name LIKE \'' . $searchterm . '%\'
+ AND show_gym LIKE 1
+ OR gym_name LIKE \'% ' .$searchterm . '%\'
+ AND show_gym LIKE 1
+ ORDER BY
+ CASE
+ WHEN gym_name LIKE \'' . $searchterm . '%\' THEN 1
+ WHEN gym_name LIKE \'%' . $searchterm . '%\' THEN 2
+ ELSE 3
+ END
+ LIMIT 15
+ '
+ );
+ // Init empty keys array.
+ $keys = [];
+
+ while ($gym = $rs->fetch()) {
+ $first = strtoupper(substr($gym['gym_name'], 0, 1));
+ $keys[] = button($gym['gym_name'], ['edit_raidlevel', 'g' => $gym['id'], 'fl' => $first]);
+ }
+
+ // Add abort key.
+ if($keys) {
+ // Get the inline key array.
+ $keys = inline_key_array($keys, 1);
+ }
+
+ return $keys;
}
-
-
-?>
diff --git a/logic/raid_level.php b/logic/raid_level.php
deleted file mode 100644
index a46d0f9a..00000000
--- a/logic/raid_level.php
+++ /dev/null
@@ -1,64 +0,0 @@
-fetch()) {
- $raid_level = $level['raid_level'];
- }
- debug_log("Resolved level of {$pokedex_id}({$pokemon_form_id}) to {$raid_level}");
- } else {
- info_log("Could not resolve level of {$pokedex_id}({$pokemon_form_id}), defaulting to 0!");
- $raid_level = '0';
- }
-
- return $raid_level;
-}
-
-/**
- * Get active raid bosses at a certain time.
- * @param $time - string, datetime, local time
- * @param $raid_level - ENUM('1', '2', '3', '4', '5', '6', 'X')
- * @return string
- */
-function get_raid_bosses($time, $raid_level)
-{
- // Get raid level from database
- $rs = my_query(
- '
- SELECT pokedex_id, pokemon_form_id
- FROM raid_bosses
- WHERE \''.$time.'\' BETWEEN date_start AND date_end
- AND raid_level = \''.$raid_level.'\'
- ');
- debug_log('Checking active raid bosses for raid level '.$raid_level.' at '.$time.':');
- $raid_bosses = [];
- $egg_found = false;
- while ($result = $rs->fetch()) {
- $raid_bosses[] = $result;
- if($result['pokedex_id'] == '999'.$raid_level) $egg_found = true;
- debug_log('Pokedex id: '.$result['pokedex_id'].' | Form id: '.$result['pokemon_form_id']);
- }
- if(!$egg_found) $raid_bosses[] = ['pokedex_id' => '999'.$raid_level, 'pokemon_form_id' => 0]; // Add egg if it wasn't found from db
- return $raid_bosses;
-}
-
-?>
diff --git a/logic/raid_list.php b/logic/raid_list.php
index 904f6546..e9eab645 100644
--- a/logic/raid_list.php
+++ b/logic/raid_list.php
@@ -1,66 +1,58 @@
UTC_TIMESTAMP()
- ORDER BY id DESC LIMIT 2
- "
- );
- while ($answer_raids = $request->fetch()) {
- $rows[] = get_raid($answer_raids['id']);
- }
+ global $config;
+ // Init raid id.
+ $iqq = 0;
+
+ // Botname:raid_id received?
+ if (substr_count($update['inline_query']['query'], ':') == 1) {
+ // Botname: received, is there a raid_id after : or not?
+ if(strlen(explode(':', $update['inline_query']['query'])[1]) != 0) {
+ // Raid ID.
+ $iqq = intval(explode(':', $update['inline_query']['query'])[1]);
}
-
-
- // Init array.
- $contents = array();
-
- // For each rows.
- foreach ($rows as $key => $row) {
- // Get raid poll.
- $contents[$key]['text'] = show_raid_poll($row, true)['full'];
-
- // Set the title.
- $contents[$key]['title'] = get_local_pokemon_name($row['pokemon'],$row['pokemon_form'], true) . ' ' . getPublicTranslation('from') . ' ' . dt2time($row['start_time']) . ' ' . getPublicTranslation('to') . ' ' . dt2time($row['end_time']);
-
- // Get inline keyboard.
- $contents[$key]['keyboard'] = keys_vote($row);
-
- // Set the description.
- $contents[$key]['desc'] = strval($row['gym_name']);
- }
-
- debug_log($contents);
- answerInlineQuery($update['inline_query']['id'], $contents);
+ }
+
+ // Inline list polls.
+ $ids = [['id' => $iqq]];
+ if ($iqq == 0) {
+ // If no id was given, search for two raids saved by the user
+ $request = my_query('
+ SELECT id
+ FROM raids
+ WHERE user_id = ?
+ AND end_time>UTC_TIMESTAMP()
+ ORDER BY id DESC LIMIT 2
+ ', [$update['inline_query']['from']['id']]
+ );
+ $ids = $request->fetchAll();
+ }
+
+ $contents = [];
+ $i = 0;
+ foreach ($ids as $raid) {
+ $row = get_raid($raid['id']);
+ // Get raid poll.
+ $contents[$i]['text'] = show_raid_poll($row, true)['full'];
+
+ // Set the title.
+ $contents[$i]['title'] = get_local_pokemon_name($row['pokemon'],$row['pokemon_form'], $config->LANGUAGE_PUBLIC) . ' ' . getPublicTranslation('from') . ' ' . dt2time($row['start_time']) . ' ' . getPublicTranslation('to') . ' ' . dt2time($row['end_time']);
+
+ // Get inline keyboard.
+ $contents[$i]['keyboard'] = keys_vote($row);
+
+ // Set the description.
+ $contents[$i]['desc'] = strval($row['gym_name']);
+ $i++;
+ }
+
+ debug_log($contents);
+ answerInlineQuery($update['inline_query']['id'], $contents);
}
-
-?>
diff --git a/logic/raid_picture.php b/logic/raid_picture.php
index bee70152..44218d9c 100644
--- a/logic/raid_picture.php
+++ b/logic/raid_picture.php
@@ -1,36 +1,678 @@
$raid['id'],
+ ':gym_id' => $raid['gym_id'],
+ ':pokedex_id' => $raid['pokemon'],
+ ':pokemon_form' => $raid['pokemon_form'],
+ ':standalone' => $standalone_photo,
+ ':ended' => $raid['raid_ended'],
+ ];
+ $timeQuery = '';
+ if($raid['raid_ended'] == 0) {
+ $timeQuery = '
+ AND start_time = :start_time
+ AND end_time = :end_time';
+ $binds['start_time'] = $raid['start_time'];
+ $binds['end_time'] = $raid['end_time'];
+ }
+ $query_cache = my_query('
+ SELECT id, unique_id
+ FROM photo_cache
+ WHERE raid_id = :raid_id
+ AND gym_id = :gym_id
+ AND pokedex_id = :pokedex_id
+ AND form_id = :pokemon_form
+ ' . $timeQuery . '
+ AND ended = :ended
+ AND standalone = :standalone
+ LIMIT 1', $binds
+ );
+
+ if($query_cache->rowCount() > 0) {
+ $result = $query_cache->fetch();
+ return [false, $result['id'], $result['unique_id']];
+ }
+ return [true, create_raid_picture($raid, $standalone_photo)];
+}
/**
- * Get full raidpicture.php URL
+ * Create a raid picture and return it as a string
* @param array $raid Raid array from get_raid()
- * @param bool $standalone Clear the bottom right corner of the photo from text
+ * @param bool $standalone_photo Clear the bottom right corner of the photo from text
+ * @param bool $debug Add debug features to the photo
* @return string
*/
-function raid_picture_url($raid, $standalone = false)
-{
+function create_raid_picture($raid, $standalone_photo = false, $debug = false) {
global $config;
+ if ($GLOBALS['metrics']){
+ $GLOBALS['requests_total']->inc(['raidpicture']);
+ }
- // If any params go missing from the url the image generated will likely be served from cache
- // So let's warn people if were generating bogus URLs
- foreach (array('pokemon', 'pokemon_form', 'start_time', 'end_time', 'gym_id') as $key) {
- if (!array_key_exists($key, $raid) || $raid[$key] == '' || $raid[$key] == '-') {
- error_log("raid_picture; Insufficient parameters for raidpicture: '{$key}:{$raid[$key]}'");
- }
+ // Query missing raid info
+ $q_pokemon_info = my_query('
+ SELECT
+ pokemon_name, pokemon_form_name, min_cp, max_cp, min_weather_cp, max_weather_cp, weather, shiny, type, type2,
+ (SELECT img_url FROM gyms WHERE id=:gymId LIMIT 1) as img_url
+ FROM pokemon
+ WHERE pokedex_id = :pokemonId
+ AND pokemon_form_id = :pokemonForm LIMIT 1
+ ',[
+ 'gymId' => $raid['gym_id'],
+ 'pokemonId' => $raid['pokemon'],
+ 'pokemonForm' => $raid['pokemon_form'],
+ ]);
+ if($q_pokemon_info->rowCount() == 0) {
+ info_log("Something wrong with the raid data provided!");
+ info_log(print_r($raid,true));
+ exit();
}
+ $raid = array_merge($raid, $q_pokemon_info->fetch());
- if(utcnow() > $raid['end_time']) {
- // We'll set raid start and end times to 0 to get a new image for when the raid has ended.
- // Setting thetimes to 0 also makes it so TG can cache the raid ended -images and reuse them
- $start_time = $end_time = 0;
+ // Fonts
+ $font_gym = FONTS_PATH . '/' . $config->RAID_PICTURE_FONT_GYM;
+ $font_text = FONTS_PATH . '/' . $config->RAID_PICTURE_FONT_TEXT;
+ $font_ex_gym = FONTS_PATH . '/' . $config->RAID_PICTURE_FONT_EX_GYM;
+
+ // Canvas size
+ $canvas_width = 700;
+ $canvas_height = 356;
+
+ // Creating an empty canvas
+ $canvas = imagecreatetruecolor($canvas_width,$canvas_height);
+ imagesavealpha($canvas,true);
+
+ // Background color
+ // Default: White
+ $bg_rgb = [255,255,255];
+ $config_bg_color = explode(',',$config->RAID_PICTURE_BG_COLOR);
+ if(count($config_bg_color) == 3) {
+ $bg_rgb = $config_bg_color;
+ } else {
+ info_log($config->RAID_PICTURE_BG_COLOR, 'Invalid value RAID_PICTURE_BG_COLOR:');
+ }
+ $bg_color = imagecolorallocate($canvas,$bg_rgb[0],$bg_rgb[1], $bg_rgb[2]);
+ imagefill($canvas, 0, 0, $bg_color);
+
+ // Text / Font color
+ // Default: Black
+ $font_rgb = [0,0,0];
+ $config_font_color = explode(',',$config->RAID_PICTURE_TEXT_COLOR);
+ if(count($config_font_color) == 3) {
+ $font_rgb = $config_font_color;
+ } else {
+ info_log($config->RAID_PICTURE_TEXT_COLOR, 'Invalid value RAID_PICTURE_TEXT_COLOR:');
+ }
+ $font_color = imagecolorallocate($canvas,$font_rgb[0],$font_rgb[1],$font_rgb[2]);
+
+ // Defining RBG values that are used to create transparent color
+ // Should be different from RAID_PICTURE_BG_COLOR and RAID_PICTURE_TEXT_COLOR
+ $transparent_rgb = [0,255,0];
+
+ // Gym image
+ $gym_url = $raid['img_url'];
+ $gym_image_path = '';
+ if($config->RAID_PICTURE_STORE_GYM_IMAGES_LOCALLY && !empty($gym_url)) {
+ if(substr($gym_url, 0, 7) == 'file://') {
+ $gym_image_path = $gym_url;
+ debug_log($gym_image_path, 'Found an image imported via a portal bot: ');
+ }else {
+ $file_name = explode('/', $gym_url)[3];
+ $gym_image_path = PORTAL_IMAGES_PATH .'/'. $file_name.'.png';
+ debug_log($gym_image_path, 'Attempting to use locally stored gym image');
+ if(!file_exists($gym_image_path)) {
+ debug_log($gym_url, 'Gym image not found, attempting to downloading it from: ');
+ if(is_writable(PORTAL_IMAGES_PATH)) {
+ download_Portal_Image($gym_url, PORTAL_IMAGES_PATH, $file_name . '.png');
+ }else {
+ $gym_image_path = $gym_url;
+ info_log(PORTAL_IMAGES_PATH, 'Failed to write new gym image, incorrect permissions in directory ');
+ }
+ }
+ }
}else {
- $start_time = strtotime($raid['start_time']);
- $end_time = strtotime($raid['end_time']);
- }
- if($raid['event'] == EVENT_ID_EX) $ex_raid = '1'; else $ex_raid = '0';
- $picture_url = "{$config->RAID_PICTURE_URL}?pokemon={$raid['pokemon']}&pokemon_form={$raid['pokemon_form']}&gym_id={$raid['gym_id']}&start_time={$start_time}&end_time={$end_time}&ex_raid={$ex_raid}";
- if($standalone) $picture_url .= '&sa=1';
- if($raid['costume'] != 0) $picture_url .= '&costume='.$raid['costume'];
- debug_log('raid_picture_url: ' . $picture_url);
- return $picture_url;
+ $img_gym = false;
+ if (!empty($gym_url)) {
+ $gym_image_path = $gym_url;
+ }
+ }
+ $img_gym = $gym_image_path != '' ? grab_img($gym_image_path) : false;
+ if($img_gym == false) {
+ info_log($gym_image_path, 'Loading the gym image failed, using default gym image');
+ if(is_file($config->RAID_DEFAULT_PICTURE)) {
+ $img_gym = grab_img($config->RAID_DEFAULT_PICTURE);
+ } else {
+ info_log($config->RAID_DEFAULT_PICTURE, 'Cannot read default gym image:');
+ $img_gym = grab_img(IMAGES_PATH . "/gym_default.png");
+ }
+ }
+
+ // Get the width and height of the gym picture
+ $gym_w = imagesx($img_gym);
+ $gym_h = imagesy($img_gym);
+
+ // Crop gym image
+ if($gym_w > $gym_h) {
+ $size = $gym_h;
+ $crop_x = floor((($gym_w/2)-($gym_h/2)));
+ $crop_y = 0;
+ } else {
+ $size = $gym_w;
+ $crop_x = 0;
+ $crop_y = floor((($gym_h/2)-($gym_w/2)));
+ }
+
+ // Create mask
+ $new_w = 300;
+ $new_h = 300;
+ $mask = imagecreatetruecolor($new_w,$new_h);
+
+ // Fill the mask with background color
+ $bg = imagecolorallocate($mask,$bg_rgb[0],$bg_rgb[1], $bg_rgb[1]);
+ imagefill($mask,0,0,$bg);
+
+ // Define transparent color for the mask
+ $transparent = imagecolorallocate($mask,$transparent_rgb[0],$transparent_rgb[1],$transparent_rgb[2]);
+ imagecolortransparent($mask,$transparent);
+
+ // Creating the orange circle around the gym photo
+ $color_ellipse = imagecolorallocate($mask,254,193,161);
+ imagefilledellipse($mask,$new_w/2,$new_h/2,$new_w-9,$new_h-9,$color_ellipse);
+ imagefilledellipse($mask,$new_w/2,$new_h/2,$new_w-16,$new_h-16,$bg);
+
+ // Creating a circle that is filled with transparent color
+ imagefilledellipse($mask,$new_w/2,$new_h/2,$new_w-30,$new_h-30,$transparent);
+
+ // Merging the desired part of the gym picture with canvas
+ imagecopyresampled($canvas,$img_gym,0,0,$crop_x,$crop_y,$new_w,$new_h, $size,$size);
+
+ // Merging the mask with a circular cutout to the canvas
+ imagecopymerge($canvas, $mask, 0, 0, 0, 0, $new_w, $new_h, 100);
+
+
+
+ // Is ex gym?
+ if($raid['ex_gym'] == 1) {
+ $ex_text_size = 20;
+ $ex_text_angle = 0;
+ $corner = 16; // Roundness of the corners
+ $extra = $ex_text_size/5+1; // Some extra height
+
+ $ex_mark_bg_color = [94,169,190];
+ $ex_mark_text_color = [255,255,255];
+
+ // Get the text with local translation for EX Raid gym
+ $ex_raid_gym_text = strtoupper(getPublicTranslation('ex_gym'));
+ // Finding out the size of text
+ $ex_text_box = imagettfbbox($ex_text_size,$ex_text_angle,$font_ex_gym,$ex_raid_gym_text);
+
+ $ex_logo_width = $ex_text_box[2]+($corner);
+ $ex_logo_height = $ex_text_size+$extra;
+
+ // Create the canvas for EX RAID indicator
+ $ex_logo = imagecreatetruecolor($ex_logo_width,$ex_logo_height);
+ // Defining the transparent color
+ $ex_transparent = imagecolorallocate($ex_logo,$transparent_rgb[0],$transparent_rgb[1],$transparent_rgb[2]);
+ imagecolortransparent($ex_logo,$ex_transparent);
+ // Defining background color
+ $ex_logo_bg = imagecolorallocate($mask,$ex_mark_bg_color[0],$ex_mark_bg_color[1], $ex_mark_bg_color[2]);
+ $ex_text_color = imagecolorallocate($ex_logo,$ex_mark_text_color[0],$ex_mark_text_color[1],$ex_mark_text_color[2]);
+
+ //Filling the canvas with transparent color
+ imagefill($ex_logo,0,0,$ex_transparent);
+
+ // Creating 4 balls, one in each corner
+ imagefilledellipse($ex_logo,$corner/2,$corner/2,$corner,$corner,$ex_logo_bg);
+ imagefilledellipse($ex_logo,$corner/2,$ex_logo_height-$corner/2,$corner,$corner,$ex_logo_bg);
+ imagefilledellipse($ex_logo,$ex_logo_width-$corner/2,$corner/2,$corner,$corner,$ex_logo_bg);
+ imagefilledellipse($ex_logo,$ex_logo_width-$corner/2,$ex_logo_height-$corner/2,$corner,$corner,$ex_logo_bg);
+ // And two rectangles to fill the rest
+ imagefilledrectangle($ex_logo,$corner/2,0,$ex_logo_width-($corner/2),$ex_logo_height,$ex_logo_bg);
+ imagefilledrectangle($ex_logo,0,$corner/2,$ex_logo_width,$ex_logo_height-($corner/2),$ex_logo_bg);
+
+ // Draw the text
+ imagettftext($ex_logo,$ex_text_size,$ex_text_angle,$corner/2,$ex_text_size+1,$ex_text_color,$font_ex_gym,$ex_raid_gym_text);
+
+ // Copy icon into canvas
+ imagecopy($canvas,$ex_logo,20,20,0,0,$ex_logo_width,$ex_logo_height);
+ }
+
+
+ $show_boss_pokemon_types = false;
+ // Raid running
+ if(!$raid['raid_ended']) {
+ // Raid Egg
+ if($raid['pokemon'] > 9990) {
+ // Getting the actual icon
+ $img_pokemon = grab_img(IMAGES_PATH . "/raid_eggs/pokemon_icon_" . $raid['pokemon'] . "_00.png");
+
+ // Position and size of the picture
+ $dst_x = $dst_y = 150;
+ $dst_w = $dst_h = 200;
+ if(in_array($raid['level'], RAID_LEVEL_SHADOW))
+ $src_w = $src_h = 150;
+ else
+ $src_w = $src_h = 128;
+
+ //Pokemon
+ } else {
+ // Check pokemon icon source and create image
+ $img_file = null;
+ $addressableFilename = $uiconsFilename = ['','','','','',''];
+ $p_sources = explode(',', $config->RAID_PICTURE_POKEMON_ICONS);
+
+ $addressableFilename[0] = 'pm'.$raid['pokemon'];
+ $uiconsFilename[0] = $raid['pokemon'];
+ if($raid['pokemon_form_name'] != 'normal') {
+ $addressableFilename[1] = '.f' . strtoupper($raid['pokemon_form_name']);
+ $addressableFilename[5] = '.f' . str_replace(strtoupper($raid['pokemon_name']).'_', '', strtoupper($raid['pokemon_form_name']));
+ $uiconsFilename[1] = '_f' . $raid['pokemon_form'];
+ }
+
+ // Add costume info for every mon except megas
+ if($raid['costume'] != 0 && $raid['pokemon_form'] >= 0) {
+ $costume = json_decode(file_get_contents(ROOT_PATH . '/protos/costume.json'), true);
+ $costumeName = array_search($raid['costume'],$costume);
+ if(!empty($costumeName)) {
+ $addressableFilename[2] = '.c' . $costumeName;
+ $uiconsFilename[2] = '_c' . $raid['costume'];
+ }
+ }
+ if($raid['shiny'] == 1 && $config->RAID_PICTURE_SHOW_SHINY) {
+ $addressableFilename[3] = '.s';
+ $uiconsFilename[3] = '_s';
+ $shiny_icon = grab_img(IMAGES_PATH . "/shinystars.png");
+ }
+ $addressableFilename[4] = '.icon.png';
+ $uiconsFilename[4] = '.png';
+ $imageFilenames = createFilenameList($addressableFilename, $uiconsFilename);
+ foreach($p_sources as $p_dir) {
+ // Icon dir named 'pokemon'? Then change path to not add '_repo-owner' to icon folder name
+ if($p_dir == 'pokemon') $asset_dir = 'pokemon'; else $asset_dir = 'pokemon_' . $p_dir;
+ // Set pokemon icon dir
+ $p_img_base_path = IMAGES_PATH . "/" . $asset_dir;
+
+ // Check if file exists in this collection
+ foreach($imageFilenames as $filename) {
+ if(file_exists($p_img_base_path . "/" . $filename) && filesize($p_img_base_path . "/" . $filename) > 0) {
+ $img_file = $p_img_base_path . "/" . $filename;
+ break 2;
+ }
+ }
+ }
+
+ // If no image was found, substitute with a fallback
+ if($img_file === null) {
+ info_log(join($addressableFilename) . ' ' . join($uiconsFilename), 'Failed to find an image in any pokemon image collection for:');
+ $img_fallback_file = null;
+ // If we know the raid level, fallback to egg image
+ if(array_key_exists('level', $raid) && $raid['level'] !== null && $raid['level'] != 0) {
+ $img_fallback_file = IMAGES_PATH . "/raid_eggs/pokemon_icon_999" . $raid['level'] . "_00.png";
+ } else {
+ info_log('Unknown raid level, using fallback icon.');
+ $img_fallback_file = $config->RAID_PICTURE_POKEMON_FALLBACK;
+ }
+ $img_file = $img_fallback_file;
+ }
+
+ $img_pokemon = grab_img($img_file);
+
+ // Position and size of the picture
+ $dst_x = $dst_y = 100;
+ $dst_w = $dst_h = 256;
+ [$src_w, $src_h] = getimagesize($img_file);
+
+ if($raid['type'] != '') $show_boss_pokemon_types = true;
+ }
+
+ // Raid ended
+ } else {
+ // Raid won image
+ $img_pokemon = grab_img(IMAGES_PATH . "/raidwon.png");
+
+ // Position and size of the picture
+ $dst_x = $dst_y = 172;
+ $src_w = 444;
+ $src_h = 512;
+ $dst_w = 160;
+ $dst_h = floor($dst_w/$src_w*$src_h);
+ }
+
+ // Create pokemon image.
+ imagesavealpha($img_pokemon,true);
+
+ // Debug - Add border around pokemon image
+ if($debug) {
+ $im = imagecreate($src_w,$src_h);
+ $black = imagecolorallocate($im,0,0,0);
+ imagerectangle($img_pokemon,0,0,$src_w-1,$src_h-1,$black);
+ }
+
+ // Add pokemon to image
+ imagecopyresampled($canvas,$img_pokemon,$dst_x,$dst_y,0,0,$dst_w,$dst_h,$src_w,$src_h);
+ if(isset($raid['shadow']) && $raid['shadow'] && !in_array($raid['pokemon'], EGGS)) {
+ $img_shadow = grab_img(IMAGES_PATH . '/shadow.png');
+ $icon_x = 275;
+ imagecopyresampled($canvas,$img_shadow,$icon_x,275,0,0,75,75,55,62);
+ $icon_x -= 45;
+ }
+
+ // Add pokemon types
+ if($config->RAID_PICTURE_POKEMON_TYPES && $show_boss_pokemon_types) {
+ $img_type = grab_img(IMAGES_PATH . "/types/".$raid['type'].".png");
+ $icon_x = $icon_x ?? 300;
+ imagesavealpha($img_type, true);
+ if($raid['type2'] != '') {
+ $img_type2 = grab_img(IMAGES_PATH . "/types/".$raid['type2'].".png");
+ imagesavealpha($img_type2, true);
+ imagecopyresampled($canvas,$img_type2,$icon_x,300,0,0,40,40,64,64);
+ $icon_x -= 50;
+ }
+ imagecopyresampled($canvas,$img_type,$icon_x,300,0,0,40,40,64,64);
+ }
+ if(isset($shiny_icon)) {
+ imagesavealpha($shiny_icon,true);
+ $light_white = imagecolorallocatealpha($canvas, 255,255,255,50);
+ imagefilledellipse($canvas, $icon_x-35 ,320,40,40,$light_white);
+ imagecopyresampled($canvas,$shiny_icon,$icon_x-52,301,0,0,35,35,100,100);
+ }
+
+ // Ex-Raid?
+ if($raid['event'] == EVENT_ID_EX) {
+ $img_expass = grab_img(IMAGES_PATH . "/expass.png");
+ imagesavealpha($img_expass,true);
+
+ // Debug - Add border around expass image
+ if($debug) {
+ $im = imagecreate(256,256);
+ $black = imagecolorallocate($im,0,0,0);
+ imagerectangle($img_expass,0,0,255,255,$black);
+ }
+ imagecopyresampled($canvas,$img_expass,0,225,0,0,100,100,256,256);
+ }
+
+
+
+ // Adding the gym name to the image
+ $text_size = 23; // Font size of additional text
+ $text_size_cp_weather = 20;// Font size of weather cp text
+ $left_after_poke = 356; // First left position behind the pokemon icon.
+ $angle = 0; // Angle of the text
+ $spacing = 10; // Spacing between lines
+ $spacing_right = 10; // Empty space on the right for weather icons and CP text
+
+
+
+ // Gym name
+ // Largest gym name we found so far for testing:
+ //$gym_name = 'Zentrum für Junge Erwachsene der Kirche Jesu Christi der Heiligen der Letzten Tage Pfahl Düsseldorf';
+ $gym_name = mb_convert_encoding($raid['gym_name'], 'ISO-8859-1');
+
+ // Get length, the shortest and largest word of the gym name
+ $gym_name_words = explode(SP, $gym_name);
+ $gym_name_word_lengths = array_map('strlen', $gym_name_words);
+ $gym_name_word_largest = max($gym_name_word_lengths);
+ $gym_name_total_chars = strlen(mb_convert_encoding($gym_name, 'ISO-8859-1', 'UTF-8'));
+
+ // Number of rows based on number of words or total chars
+ $gym_name_rows = 1;
+ if(count($gym_name_words) > 1 && $gym_name_total_chars >= 18 && $gym_name_total_chars <= 50) {
+ $gym_name_rows = 2;
+ } else if($gym_name_total_chars > 50) {
+ $gym_name_rows = 3;
+ }
+
+ // Wrap gym name to multiple lines if too long
+ $gym_name_lines = explode(PHP_EOL,wordwrap(trim($gym_name),floor(($gym_name_total_chars+$gym_name_word_largest)/$gym_name_rows),PHP_EOL));
+
+ debug_log($gym_name_total_chars, 'Gym name length:');
+ debug_log($gym_name_lines, 'Gym name lines:');
+
+ // Target width and height
+ $targetWidth = imagesx($canvas) - imagesx($mask) - $spacing_right;
+ $targetHeight = 95;
+ $rowHeight = $targetHeight/$gym_name_rows;
+
+ // Get largest possible fontsize for each gym name line
+ $fontsize_gym = 0;
+ for($l=0; $l' . $att_row['trainercode'] . ' ': '');
-
- $msg = raid_poll_message($msg, CR);
-
- // Prepare next result
- $previous_att_time = $current_att_time;
- $previous_pokemon = $current_pokemon;
- }
- if(!empty($string_trainernames)) {
- $msg = raid_poll_message($msg, '' . $string_trainernames . '' . CR);
- }
- }
+ if(isset($att_row['trainername']) && $config->RAID_POLL_SHOW_TRAINERNAME_STRING && $att_row['want_invite']) {
+ if(!empty($string_trainernames)) $string_trainernames .= ',';
+ $string_trainernames .= $att_row['trainername'];
}
+ // Add users: ARRIVED --- TEAM -- LEVEL -- NAME -- INVITE -- EXTRAPEOPLE
+ $msg = raid_poll_message($msg, ($att_row['arrived']) ? (EMOJI_HERE . ' ') : (($att_row['late']) ? (EMOJI_LATE . ' ') : '└ '));
+ $msg = raid_poll_message($msg, ($att_row['team'] === NULL) ? ($GLOBALS['teams']['unknown'] . ' ') : ($GLOBALS['teams'][$att_row['team']] . ' '));
+ $msg = raid_poll_message($msg, ($att_row['level'] == 0) ? ('00 ') : (($att_row['level'] < 10) ? ('0' . $att_row['level'] . ' ') : ('' . $att_row['level'] . ' ')));
+ $msg = raid_poll_message($msg, $trainername);
+ $msg = raid_poll_message($msg, ($att_row['remote']) ? (EMOJI_REMOTE) : '');
+ $msg = raid_poll_message($msg, ($raid['event'] == EVENT_ID_EX && $att_row['invite']) ? (EMOJI_INVITE . ' ') : '');
+ $msg = raid_poll_message($msg, ($att_row['extra_in_person']) ? ('+' . $att_row['extra_in_person'] . EMOJI_IN_PERSON . ' ') : '');
+ $msg = raid_poll_message($msg, ($att_row['extra_alien']) ? ('+' . $att_row['extra_alien'] . EMOJI_ALIEN . ' ') : '');
+ $msg = raid_poll_message($msg, ($att_row['want_invite']) ? (EMOJI_WANT_INVITE) : '');
+ $msg = raid_poll_message($msg, ($att_row['can_invite']) ? (EMOJI_CAN_INVITE) : '');
+ $msg = raid_poll_message($msg, ($config->RAID_POLL_SHOW_TRAINERCODE && ($att_row['want_invite'] || $att_row['can_invite']) && !is_null($att_row['trainercode'])) ? ' ' . $att_row['trainercode'] . ' ': '');
+
+ $msg = raid_poll_message($msg, CR);
+
+ // Prepare next result
+ $previous_att_time = $current_att_time;
+ $previous_pokemon = $current_pokemon;
+ }
+ if(!empty($string_trainernames)) {
+ $msg = raid_poll_message($msg, '' . $string_trainernames . '' . CR);
+ }
}
+ }
+ }
- // Canceled or done?
- if(!$config->RAID_POLL_HIDE_DONE_CANCELED && ($cnt_cancel > 0 || $cnt_done > 0)) {
- // Init cancel_done value.
- $cancel_done = 'CANCEL';
- $array_cancel_done = array_merge($cancel_array,$done_array);
- // For each canceled / done.
- foreach ($array_cancel_done as $row) {
- // Attend time.
- $dt_att_time = dt2time($row['attend_time']);
-
- // Add section/header for canceled
- if($row['cancel'] == 1 && $cancel_done == 'CANCEL') {
- $msg = raid_poll_message($msg, CR . TEAM_CANCEL . ' ' . getPublicTranslation('cancelled') . ': ' . '[' . $cnt_cancel . ']' . CR);
- $cancel_done = 'DONE';
- }
-
- // Add section/header for canceled
- if($row['raid_done'] == 1 && $cancel_done == 'CANCEL' || $row['raid_done'] == 1 && $cancel_done == 'DONE') {
- $msg = raid_poll_message($msg, CR . TEAM_DONE . ' ' . getPublicTranslation('finished') . ': ' . '[' . $cnt_done . ']' . CR);
- $cancel_done = 'END';
- }
- if($config->RAID_POLL_ENABLE_HYPERLINKS_IN_NAMES) {
- $trainername = '' . htmlspecialchars($row['name']) . ' ';
- }else {
- $trainername = htmlspecialchars($row['name']) . ' ';
- }
-
- // Add users: TEAM -- LEVEL -- NAME -- CANCELED/DONE -- EXTRAPEOPLE
- $msg = raid_poll_message($msg, ($row['team'] === NULL) ? ('└ ' . $GLOBALS['teams']['unknown'] . ' ') : ('└ ' . $GLOBALS['teams'][$row['team']] . ' '));
- $msg = raid_poll_message($msg, ($row['level'] == 0) ? ('00 ') : (($row['level'] < 10) ? ('0' . $row['level'] . ' ') : ('' . $row['level'] . ' ')));
- $msg = raid_poll_message($msg, $trainername);
- $msg = raid_poll_message($msg, ($raid['event'] == EVENT_ID_EX && $row['invite']) ? (EMOJI_INVITE . ' ') : '');
- if($raid['event_vote_key_mode'] != 1) {
- $msg = raid_poll_message($msg, ($row['cancel'] == 1 || $row['raid_done'] == 1) ? ('[' . (($row['attend_time'] == ANYTIME) ? (getPublicTranslation('anytime')) : ($dt_att_time)) . '] ') : '');
- }
- $msg = raid_poll_message($msg, ($row['extra_in_person']) ? ('+' . $row['extra_in_person'] . EMOJI_IN_PERSON . ' ') : '');
- $msg = raid_poll_message($msg, ($row['extra_alien']) ? ('+' . $row['extra_alien'] . EMOJI_ALIEN . ' ') : '');
- $msg = raid_poll_message($msg, CR);
- }
+ // Canceled or done?
+ if(!$config->RAID_POLL_HIDE_DONE_CANCELED && ($cnt_cancel > 0 || $cnt_done > 0)) {
+ // Init cancel_done value.
+ $cancel_done = 'CANCEL';
+ $array_cancel_done = array_merge($cancel_array,$done_array);
+ // For each canceled / done.
+ foreach ($array_cancel_done as $row) {
+ // Attend time.
+ $dt_att_time = dt2time($row['attend_time']);
+
+ // Add section/header for canceled
+ if($row['cancel'] == 1 && $cancel_done == 'CANCEL') {
+ $msg = raid_poll_message($msg, CR . TEAM_CANCEL . ' ' . getPublicTranslation('cancelled') . ': ' . '[' . $cnt_cancel . ']' . CR);
+ $cancel_done = 'DONE';
}
- // Add no attendance found message.
- if ($cnt_all + $cnt_cancel + $cnt_done == 0) {
- $msg = raid_poll_message($msg, CR . getPublicTranslation('no_participants_yet') . CR);
+ // Add section/header for canceled
+ if($row['raid_done'] == 1 && $cancel_done == 'CANCEL' || $row['raid_done'] == 1 && $cancel_done == 'DONE') {
+ $msg = raid_poll_message($msg, CR . TEAM_DONE . ' ' . getPublicTranslation('finished') . ': ' . '[' . $cnt_done . ']' . CR);
+ $cancel_done = 'END';
+ }
+ if($config->RAID_POLL_ENABLE_HYPERLINKS_IN_NAMES) {
+ $trainername = '' . htmlspecialchars($row['name']) . ' ';
+ }else {
+ $trainername = htmlspecialchars($row['name']) . ' ';
}
- }
-
- //Add custom message from the config.
- if (!empty($config->MAP_URL)) {
- $msg = raid_poll_message($msg, CR . $config->MAP_URL);
- }
- // Display creator.
- if($config->RAID_POLL_SHOW_CREATOR) {
- $msg = raid_poll_message($msg, ($raid['user_id'] && $raid['name']) ? (CR . getPublicTranslation('created_by') . ': ' . htmlspecialchars($raid['name']) . '') : '');
+ // Add users: TEAM -- LEVEL -- NAME -- CANCELED/DONE -- EXTRAPEOPLE
+ $msg = raid_poll_message($msg, ($row['team'] === NULL) ? ('└ ' . $GLOBALS['teams']['unknown'] . ' ') : ('└ ' . $GLOBALS['teams'][$row['team']] . ' '));
+ $msg = raid_poll_message($msg, ($row['level'] == 0) ? ('00 ') : (($row['level'] < 10) ? ('0' . $row['level'] . ' ') : ('' . $row['level'] . ' ')));
+ $msg = raid_poll_message($msg, $trainername);
+ $msg = raid_poll_message($msg, ($raid['event'] == EVENT_ID_EX && $row['invite']) ? (EMOJI_INVITE . ' ') : '');
+ if($raid['event_vote_key_mode'] != 1) {
+ $msg = raid_poll_message($msg, ($row['cancel'] == 1 || $row['raid_done'] == 1) ? ('[' . (($row['attend_time'] == ANYTIME) ? (getPublicTranslation('anytime')) : ($dt_att_time)) . '] ') : '');
+ }
+ $msg = raid_poll_message($msg, ($row['extra_in_person']) ? ('+' . $row['extra_in_person'] . EMOJI_IN_PERSON . ' ') : '');
+ $msg = raid_poll_message($msg, ($row['extra_alien']) ? ('+' . $row['extra_alien'] . EMOJI_ALIEN . ' ') : '');
+ $msg = raid_poll_message($msg, CR);
+ }
}
- // Add update time and raid id to message.
- $msg = raid_poll_message($msg, CR . '' . getPublicTranslation('updated') . ': ' . dt2time('now', 'H:i:s') . '');
- if($inline && ($buttons_hidden or ($raid['end_time'] < $time_now && $config->RAID_ENDED_HIDE_KEYS))) {
- // Only case this is needed anymore is a poll shared via inline that has no vote keys
- $msg = raid_poll_message($msg, SP . SP . substr(strtoupper($config->BOT_ID), 0, 1) . '-ID = ' . $raid['id']);
+ // Add no attendance found message.
+ if ($cnt_all + $cnt_cancel + $cnt_done == 0) {
+ $msg = raid_poll_message($msg, CR . getPublicTranslation('no_participants_yet') . CR);
}
- // Return the message.
- return $msg;
+ }
+
+ //Add custom message from the config.
+ if (!empty($config->MAP_URL)) {
+ $msg = raid_poll_message($msg, CR . $config->MAP_URL);
+ }
+
+ // Display creator.
+ if($config->RAID_POLL_SHOW_CREATOR) {
+ $msg = raid_poll_message($msg, ($raid['user_id'] && $raid['name']) ? (CR . getPublicTranslation('created_by') . ': ' . htmlspecialchars($raid['name']) . '') : '');
+ }
+
+ // Add update time and raid id to message.
+ $msg = raid_poll_message($msg, CR . '' . getPublicTranslation('updated') . ': ' . dt2time('now', 'H:i:s') . '');
+ if($inline && ($buttons_hidden or ($raid['raid_ended'] && $config->RAID_ENDED_HIDE_KEYS))) {
+ // Only case this is needed anymore is a poll shared via inline that has no vote keys
+ $msg = raid_poll_message($msg, SP . SP . substr(strtoupper($config->BOT_ID), 0, 1) . '-ID = ' . $raid['id']);
+ }
+ // Return the message.
+ return $msg;
}
/**
* Print counts to raid poll headers.
- * @param $msg - The array containing short and long poll messages
- * @param $cnt_array - A row of cnt_array created in show_raid_poll for specific time/pokemon
+ * @param array $msg The array containing short and long poll messages
+ * @param array $cnt_array A row of cnt_array created in show_raid_poll for specific time/pokemon
* @return array
*/
function raid_poll_print_counts($msg, $cnt_array) {
- // Attendance counts
- $count_in_person = $cnt_array['in_person'];
- $count_remote = $cnt_array['remote'];
- $count_extra_alien = $cnt_array['extra_alien'];
- $count_want_invite = $cnt_array['want_invite'];
- $count_late = $cnt_array['late'];
- $count_total = (is_numeric($cnt_array['total'])?$cnt_array['total']:0);
-
- // Add to message.
- $msg = raid_poll_message($msg, ' [' . ($count_total) . '] — ');
- $msg = raid_poll_message($msg, (($count_in_person > 0) ? EMOJI_IN_PERSON . $count_in_person . ' ' : ''));
- $msg = raid_poll_message($msg, (($count_remote > 0) ? EMOJI_REMOTE . $count_remote . ' ' : ''));
- $msg = raid_poll_message($msg, (($count_extra_alien > 0) ? EMOJI_ALIEN . $count_extra_alien . ' ' : ''));
- $msg = raid_poll_message($msg, (($count_want_invite > 0) ? EMOJI_WANT_INVITE . $count_want_invite . ' ' : ''));
- $msg = raid_poll_message($msg, (($count_late > 0) ? EMOJI_LATE . $count_late . ' ' : ''));
- $msg = raid_poll_message($msg, CR);
- return $msg;
+ // Attendance counts
+ $count_in_person = $cnt_array['in_person'];
+ $count_remote = $cnt_array['remote'];
+ $count_extra_alien = $cnt_array['extra_alien'];
+ $count_want_invite = $cnt_array['want_invite'];
+ $count_late = $cnt_array['late'];
+ $count_total = (is_numeric($cnt_array['total'])?$cnt_array['total']:0);
+
+ // Add to message.
+ $msg = raid_poll_message($msg, ' [' . ($count_total) . '] — ');
+ $msg = raid_poll_message($msg, (($count_in_person > 0) ? EMOJI_IN_PERSON . $count_in_person . ' ' : ''));
+ $msg = raid_poll_message($msg, (($count_remote > 0) ? EMOJI_REMOTE . $count_remote . ' ' : ''));
+ $msg = raid_poll_message($msg, (($count_extra_alien > 0) ? EMOJI_ALIEN . $count_extra_alien . ' ' : ''));
+ $msg = raid_poll_message($msg, (($count_want_invite > 0) ? EMOJI_WANT_INVITE . $count_want_invite . ' ' : ''));
+ $msg = raid_poll_message($msg, (($count_late > 0) ? EMOJI_LATE . $count_late . ' ' : ''));
+ $msg = raid_poll_message($msg, CR);
+ return $msg;
}
-?>
diff --git a/logic/show_raid_poll_small.php b/logic/show_raid_poll_small.php
index df738477..6f328709 100644
--- a/logic/show_raid_poll_small.php
+++ b/logic/show_raid_poll_small.php
@@ -1,74 +1,75 @@
' . $raid['gym_name'] . '' . CR;
- }
+ // Gym Name
+ if(!empty($raid['gym_name'])) {
+ $msg .= '' . $raid['gym_name'] . '' . CR;
+ }
- // Address found.
- if (!empty($raid['address'])) {
- $msg .= '' . $raid['address'] . '' . CR2;
- }
+ // Address found.
+ if (!empty($raid['address'])) {
+ $msg .= '' . $raid['address'] . '' . CR2;
+ }
- // Pokemon
- if(!empty($raid['pokemon'])) {
- $msg .= '' . get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form']) . ' ' . CR;
- }
- // Start time and end time
- if(!empty($raid['start_time']) && !empty($raid['end_time'])) {
- // Get raid times message.
- $msg .= get_raid_times($raid, $override_language);
- }
+ if(isset($raid['event_name']) && !empty($raid['event_name'])) {
+ $msg .= $raid['event_name'] . CR;
+ }
+ // Pokemon
+ if(!empty($raid['pokemon'])) {
+ $msg .= '' . get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form']) . (isset($raid['shadow']) && $raid['shadow'] && !in_array($raid['pokemon'], EGGS) ? ' ' . getPublicTranslation('pokemon_form_shadow') : '') . ' ' . CR;
+ }
+ // Start time and end time
+ if(!empty($raid['start_time']) && !empty($raid['end_time'])) {
+ // Get raid times message.
+ $msg .= get_raid_times($raid, $botUser->userLanguage);
+ }
- // Count attendances
- $rs = my_query(
- "
- SELECT count(attend_time) AS count,
- sum(remote = 0) AS count_in_person,
- sum(remote = 1) + sum(case when remote = 1 then extra_in_person else 0 end) AS count_remote,
- sum(case when remote = 0 then extra_in_person else 0 end) AS extra_in_person,
- sum(extra_alien) AS extra_alien
- FROM attendance
- LEFT JOIN users
- ON attendance.user_id = users.user_id
- WHERE raid_id = {$raid['id']}
- AND attend_time IS NOT NULL
- AND raid_done != 1
- AND cancel != 1
- "
- );
+ // Count attendances
+ $rs = my_query('
+ SELECT count(attend_time) AS count,
+ sum(remote = 0) AS count_in_person,
+ sum(remote = 1) + sum(case when remote = 1 then extra_in_person else 0 end) AS count_remote,
+ sum(case when remote = 0 then extra_in_person else 0 end) AS extra_in_person,
+ sum(extra_alien) AS extra_alien
+ FROM attendance
+ LEFT JOIN users
+ ON attendance.user_id = users.user_id
+ WHERE raid_id = ?
+ AND attend_time IS NOT NULL
+ AND raid_done != 1
+ AND cancel != 1
+ ', [$raid['id']]
+ );
- $row = $rs->fetch();
+ $row = $rs->fetch();
- // Add to message.
- if ($row['count'] > 0) {
- // Count by team.
- $count_in_person = $row['count_in_person'];
- $count_remote = $row['count_remote'];
- $extra_in_person = $row['extra_in_person'];
- $extra_alien = $row['extra_alien'];
+ // Add to message.
+ if ($row['count'] < 1) {
+ $msg .= getTranslation('no_participants') . CR;
+ return $msg;
+ }
+ // Count by team.
+ $count_in_person = $row['count_in_person'];
+ $count_remote = $row['count_remote'];
+ $extra_in_person = $row['extra_in_person'];
+ $extra_alien = $row['extra_alien'];
- // Add to message.
- $msg .= EMOJI_GROUP . ' ' . ($count_in_person + $count_remote + $extra_in_person + $extra_alien) . ' — ';
- $msg .= (($count_in_person > 0) ? EMOJI_IN_PERSON . ($count_in_person + $extra_in_person) . ' ' : '');
- $msg .= (($count_remote > 0) ? EMOJI_REMOTE . $count_remote . ' ' : '');
- $msg .= (($extra_alien > 0) ? EMOJI_ALIEN . $extra_alien . ' ' : '');
- $msg .= CR;
- } else {
- $msg .= getTranslation('no_participants') . CR;
- }
+ // Add to message.
+ $msg .= EMOJI_GROUP . ' ' . ($count_in_person + $count_remote + $extra_in_person + $extra_alien) . ' — ';
+ $msg .= (($count_in_person > 0) ? EMOJI_IN_PERSON . ($count_in_person + $extra_in_person) . ' ' : '');
+ $msg .= (($count_remote > 0) ? EMOJI_REMOTE . $count_remote . ' ' : '');
+ $msg .= (($extra_alien > 0) ? EMOJI_ALIEN . $extra_alien . ' ' : '');
+ $msg .= CR;
- return $msg;
+ return $msg;
}
-
-?>
diff --git a/logic/show_trainerinfo.php b/logic/show_trainerinfo.php
index 70765af1..bd3e298e 100644
--- a/logic/show_trainerinfo.php
+++ b/logic/show_trainerinfo.php
@@ -1,4 +1,5 @@
' . getPublicTranslation('trainerinfo') . ':' . CR;
- $msg .= getPublicTranslation('trainer_set_your_info') . CR . CR;
- $msg .= getPublicTranslation('trainer_set_your_info_done') . CR . CR;
+ // Instructions
+ $msg = '' . getPublicTranslation('trainerinfo') . ':' . CR;
+ $msg .= getPublicTranslation('trainer_set_your_info') . CR . CR;
+ $msg .= getPublicTranslation('trainer_set_your_info_done') . CR . CR;
- // Show user info?
- if($show) {
- $msg .= '' . getPublicTranslation('your_trainer_info') . '' . CR;
- $msg .= get_user($update['callback_query']['from']['id']) . CR;
- }
+ // Show user info?
+ if($show) {
+ $msg .= '' . getPublicTranslation('your_trainer_info') . '' . CR;
+ $msg .= get_user($update['callback_query']['from']['id']) . CR;
+ }
- $msg .= '' . getPublicTranslation('updated') . ': ' . dt2time('now', 'H:i:s') . '';
+ $msg .= '' . getPublicTranslation('updated') . ': ' . dt2time('now', 'H:i:s') . '';
- return $msg;
+ return $msg;
}
-
-?>
diff --git a/core/bot/logic/sql_utils.php b/logic/sql_utils.php
similarity index 52%
rename from core/bot/logic/sql_utils.php
rename to logic/sql_utils.php
index c95c1218..a3dc2417 100644
--- a/core/bot/logic/sql_utils.php
+++ b/logic/sql_utils.php
@@ -9,11 +9,10 @@ function run_sql_file($file) {
if (!$dbh) {
error_log('No DB handle!');
return false;
- }
+ }
try {
$query = file_get_contents($file);
- $statement = $dbh->prepare( $query );
- $statement->execute();
+ $dbh->exec( $query );
}
catch (PDOException $exception) {
info_log('DB upgrade failed: ' . $exception->getMessage());
@@ -27,40 +26,41 @@ function run_sql_file($file) {
/**
* DB query wrapper that supports binds.
- * @param $query
- * @param binds
+ * @param $query string
+ * @param $binds Array
* @return PDOStatement
*/
function my_query($query, $binds=null)
{
- global $dbh;
- global $config;
+ global $dbh;
+ global $config;
+ require_once(ROOT_PATH . '/logic/debug.php');
- try {
- $stmt = $dbh->prepare($query);
- $stmt->execute($binds);
- } catch (PDOException $exception) {
- // The message will be output in the global handler, we just need to extract the failing query
- error_log('The following query failed:');
- log_query($stmt, $binds, 'error_log');
- throw $exception;
- } finally {
- debug_log_sql('Query success', '$');
- if($config->DEBUG_SQL) {
- log_query($stmt, $binds, 'debug_log_sql');
- }
+ try {
+ $stmt = $dbh->prepare($query);
+ $stmt->execute($binds);
+ } catch (PDOException $exception) {
+ // The message will be output in the global handler, we just need to extract the failing query
+ error_log('The following query failed:');
+ log_query($stmt, print_r($binds, true), 'error_log');
+ throw $exception;
+ } finally {
+ debug_log_sql('Query success', '$');
+ if($config->DEBUG_SQL) {
+ log_query($stmt, print_r($binds, true), 'debug_log_sql');
}
- return $stmt;
+ }
+ return $stmt;
}
// Debug log the full statement with parameters
function log_query($stmt, $binds, $logger='debug_log_sql'){
- ob_start();
- $stmt->debugDumpParams();
- $debug = ob_get_contents();
- ob_end_clean();
- $logger($debug);
- $logger('The parameters bound were:');
- if($binds === null) $binds = 'null';
- $logger($binds);
+ ob_start();
+ $stmt->debugDumpParams();
+ $debug = ob_get_contents();
+ ob_end_clean();
+ $logger($debug);
+ $logger('The parameters bound were:');
+ if($binds === null) $binds = 'null';
+ $logger($binds);
}
diff --git a/logic/update_raid_poll.php b/logic/update_raid_poll.php
index b1420f64..4357d518 100644
--- a/logic/update_raid_poll.php
+++ b/logic/update_raid_poll.php
@@ -1,4 +1,6 @@
null,
- 'message_id' => $update['callback_query']['inline_message_id'],
- 'type' => 'poll_text',
- ];
- // For updating a poll
- }else if(isset($update['push'])) {
- $chat_and_message[] = [
- 'chat_id' => $update['push']['chat_id'],
- 'message_id' => $update['push']['message_id'],
- 'type' => $update['push']['type'],
- ];
- }
- // If neither of the methods above yielded results, or update came from a inline poll, check cleanup table for chat messages to update
- if(empty($chat_and_message) or isset($update['callback_query']['inline_message_id'])) {
- $rs_chann = my_query('
- SELECT chat_id, message_id, type
- FROM cleanup
- WHERE raid_id = ' . $raid_id
- );
- if ($rs_chann->rowCount() > 0) {
- while($chat = $rs_chann->fetch()) {
- $chat_and_message[] = ['chat_id' => $chat['chat_id'], 'message_id' => $chat['message_id'], 'type' => $chat['type']];
- }
- }else {
- if(is_array($tg_json)) return $tg_json;
- else return [];
+ global $config;
+ $chat_and_message = [];
+ // Parsing the update type here, since the callback_query can come from regular message or inline message
+ if(isset($update['callback_query']['inline_message_id'])) {
+ $chat_and_message[] = [
+ 'chat_id' => null,
+ 'message_id' => $update['callback_query']['inline_message_id'],
+ 'type' => 'poll_text',
+ ];
+ // For updating a poll
+ }else if(isset($update['push'])) {
+ $chat_and_message[] = $update['push'];
+ }
+ // If neither of the methods above yielded results, or update came from a inline poll, check cleanup table for chat messages to update
+ if(empty($chat_and_message) or isset($update['callback_query']['inline_message_id'])) {
+ if($update_photo) $photo_query = 'AND (type = \'photo\' OR type = \'poll_photo\')'; else $photo_query = '';
+ $rs_chann = my_query('
+ SELECT chat_id, message_id, thread_id, type, media_unique_id
+ FROM cleanup
+ WHERE raid_id = ?
+ ' . $photo_query,[$raid_id]
+ );
+ if ($rs_chann->rowCount() > 0 || false) {
+ while($chat = $rs_chann->fetch()) {
+ $chat_and_message[] = $chat;
+ }
+ }else {
+ if($update === false) {
+ if(is_array($tg_json)) return $tg_json;
+ else return [];
+ }
+ $chatId = $update[$update['type']]['message']['chat']['id'];
+ $messageId = $update[$update['type']]['message']['message_id'];
+ if(isset($update[$update['type']]['message']['text']) && !empty($update[$update['type']]['message']['text'])) {
+ $type = 'poll_text';
+ }else if(isset($update[$update['type']]['message']['caption']) && !empty($update[$update['type']]['message']['caption'])) {
+ $type = 'poll_photo';
+ }else if(isset($update[$update['type']]['message']['venue']) && !empty($update[$update['type']]['message']['venue'])) {
+ $type = 'poll_venue';
+ }else if(isset($update[$update['type']]['message']['photo']) && !isset($update[$update['type']]['message']['caption'])) {
+ $type = 'photo';
+ }
+ $unique_id = null;
+ if(isset($update[$update['type']]['message']['photo'])) {
+ $largest_size = 0;
+ foreach($update[$update['type']]['message']['photo'] as $photo) {
+ if($photo['file_size'] < $largest_size) continue;
+ $largest_size = $photo['file_size'];
+ $save_id = $photo['file_id'];
+ $unique_id = $photo['file_unique_id'];
}
+ }
+ $chat_and_message[] = ['chat_id' => $chatId, 'message_id' => $messageId, 'type' => $type, 'media_unique_id' => $unique_id];
}
- // Get the raid data by id.
- if($raid == false) $raid = get_raid($raid_id);
+ }
+ // Get the raid data by id.
+ if($raid == false) $raid = get_raid($raid_id);
- // Message - make sure to not exceed Telegrams 1024 characters limit for caption
- $text = show_raid_poll($raid);
- $post_text = false;
- if(array_key_exists('short', $text)) {
- $msg_short_len = strlen(utf8_decode($text['short']));
- debug_log($msg_short_len, 'Raid poll short message length:');
- // Message short enough?
- if($msg_short_len >= 1024) {
- // Use full text and reset text to true regardless of prior value
- $post_text = true;
- }
- } else {
- // Use full text and reset text to true regardless of prior value
- $post_text = true;
+ // Message - make sure to not exceed Telegrams 1024 characters limit for caption
+ $text = show_raid_poll($raid);
+ $post_text = false;
+ if(array_key_exists('short', $text)) {
+ $msg_short_len = strlen(mb_convert_encoding($text['short'], 'ISO-8859-1'));
+ debug_log($msg_short_len, 'Raid poll short message length:');
+ // Message short enough?
+ if($msg_short_len >= 1024) {
+ // Use full text and reset text to true regardless of prior value
+ $post_text = true;
}
- $keys = keys_vote($raid);
+ } else {
+ // Use full text and reset text to true regardless of prior value
+ $post_text = true;
+ }
+ $keys = keys_vote($raid);
- // Telegram JSON array.
- if($tg_json == false) $tg_json = [];
- if($config->RAID_PICTURE) {
- require_once(LOGIC_PATH . '/raid_picture.php');
- }
+ // Telegram JSON array.
+ if($tg_json == false) $tg_json = [];
- foreach($chat_and_message as $chat_id_msg_id) {
- $chat = $chat_id_msg_id['chat_id'];
- $message = $chat_id_msg_id['message_id'];
- $type = $chat_id_msg_id['type'];
- if($type == 'poll_photo') {
- $picture_url = raid_picture_url($raid);
- // If the poll message gets too long, we'll replace it with regular text based poll
- if($post_text == true) {
- // Delete raid picture and caption.
- $tg_json[] = delete_message($chat, $message, true);
- my_query("DELETE FROM cleanup WHERE chat_id = '{$chat}' AND message_id = '{$message}'");
+ foreach($chat_and_message as $chat_id_msg_id) {
+ $chat = $chat_id_msg_id['chat_id'];
+ $message = $chat_id_msg_id['message_id'];
+ $thread_id = $chat_id_msg_id['thread_id'] ?? null;
+ $type = $chat_id_msg_id['type'];
+ if ($type == 'poll_text') {
+ $raid_picture_hide_level = explode(",",$config->RAID_PICTURE_HIDE_LEVEL);
+ $raid_picture_hide_pokemon = explode(",",$config->RAID_PICTURE_HIDE_POKEMON);
- // Resend raid poll as text message.
- send_photo($chat, $picture_url, '', [], [], false, $raid_id);
- send_message($chat, $text['full'], $keys, ['disable_web_page_preview' => 'true'], false, $raid_id);
- } else {
- // Edit the picture and caption
- if(!$skip_picture_update) {
- $tg_json[] = editMessageMedia($message, $text['short'], $picture_url, $keys, $chat, ['disable_web_page_preview' => 'true'], true);
- }else {
- // Edit the caption.
- $tg_json[] = editMessageCaption($message, $text['short'], $keys, $chat, ['disable_web_page_preview' => 'true'], true);
- }
- }
- }else if ($type == 'poll_text') {
- $raid_picture_hide_level = explode(",",$config->RAID_PICTURE_HIDE_LEVEL);
- $raid_picture_hide_pokemon = explode(",",$config->RAID_PICTURE_HIDE_POKEMON);
+ // If poll type was text, and RAID_PICUTRE_AUTO_EXTEND is set true in config, we most likely want to update the poll with the short message
+ // Exceptions are: inline poll (chat = null) and events with raid picture hidden
+ if($config->RAID_PICTURE && $config->RAID_PICTURE_AUTOEXTEND && $raid['event_hide_raid_picture'] != 1 && $chat != null && !in_array($raid['level'], $raid_picture_hide_level) && !in_array($raid['pokemon'], $raid_picture_hide_pokemon) && !in_array($raid['pokemon'].'-'.$raid['pokemon_form'], $raid_picture_hide_pokemon)) {
+ $tg_json[] = editMessageText($message, $text['short'], $keys, $chat, ['disable_web_page_preview' => 'true'], true);
+ }else {
+ $tg_json[] = editMessageText($message, $text['full'], $keys, $chat, ['disable_web_page_preview' => 'true'], true);
+ }
+ continue;
+ }
+ require_once(LOGIC_PATH . '/raid_picture.php');
+ if($type == 'poll_photo') {
+ // If the poll message gets too long, we'll replace it with regular text based poll
+ if($post_text == true) {
+ // Delete raid picture and caption.
+ $tg_json[] = delete_message($chat, $message, true);
+ my_query('DELETE FROM cleanup WHERE chat_id = ? AND message_id = ?', [$chat, $message]);
- // If poll type was text, and RAID_PICUTRE_AUTO_EXTEND is set true in config, we most likely want to update the poll with the short message
- // Exceptions are: inline poll (chat = null) and events with raid picture hidden
- if($config->RAID_PICTURE && $config->RAID_PICTURE_AUTOEXTEND && $raid['event_hide_raid_picture'] != 1 && $chat != null && !in_array($raid['level'], $raid_picture_hide_level) && !in_array($raid['pokemon'], $raid_picture_hide_pokemon) && !in_array($raid['pokemon'].'-'.$raid['pokemon_form'], $raid_picture_hide_pokemon)) {
- $tg_json[] = editMessageText($message, $text['short'], $keys, $chat, ['disable_web_page_preview' => 'true'], true);
- }else {
- $tg_json[] = editMessageText($message, $text['full'], $keys, $chat, ['disable_web_page_preview' => 'true'], true);
- }
- }else if ($type == 'photo' && !$skip_picture_update) {
- $picture_url = raid_picture_url($raid, 1);
- $tg_json[] = editMessageMedia($message, '', $picture_url, '', $chat, [], true);
- }
+ $media_content = get_raid_picture($raid, true);
+ $raid['standalone_photo'] = true; // Inject this into raid array so we can pass it all the way to photo cache
+ // Resend raid poll as text message.
+ send_photo(create_chat_object([$chat, $thread_id]), $media_content[1], $media_content[0], '', [], [], false, $raid);
+ send_message(create_chat_object([$chat, $thread_id]), $text['full'], $keys, ['disable_web_page_preview' => 'true'], false, $raid_id);
+ continue;
+ }
+ $media_content = get_raid_picture($raid);
+ // Edit the picture and caption
+ if(!isset($media_content[2]) or $media_content[2] != $chat_id_msg_id['media_unique_id']) {
+ $tg_json[] = editMessageMedia($message, $text['short'], $media_content[1], $media_content[0], $keys, $chat, ['disable_web_page_preview' => 'true'], true, $raid);
+ }else {
+ // Edit the caption.
+ $tg_json[] = editMessageCaption($message, $text['short'], $keys, $chat, ['disable_web_page_preview' => 'true'], true);
+ }
+ }else if ($type == 'photo' && $update_photo) {
+ $media_content = get_raid_picture($raid, 1);
+ $raid['standalone_photo'] = true; // Inject this into raid array so we can pass it all the way to photo cache
+ if(!isset($media_content[2]) or $media_content[2] != $chat_id_msg_id['media_unique_id']) {
+ $tg_json[] = editMessageMedia($message, '', $media_content[1], $media_content[0], false, $chat, false, true, $raid);
+ }
}
- return $tg_json;
+ }
+ return $tg_json;
}
-?>
\ No newline at end of file
diff --git a/logic/user_tutorial.php b/logic/user_tutorial.php
deleted file mode 100644
index 8548bcd1..00000000
--- a/logic/user_tutorial.php
+++ /dev/null
@@ -1,25 +0,0 @@
-prepare( $query );
- $statement->execute([":user_id"=>$user_id]);
- $res = $statement->fetch();
- if($statement->rowCount() > 0) $result = $res['tutorial'];
- else $result = 0;
- debug_log("Result: ".$result);
- return $result;
- } catch (PDOException $exception) {
- error_log($exception->getMessage());
- $dbh = null;
- exit;
- }
-}
-?>
\ No newline at end of file
diff --git a/logic/weather_keys.php b/logic/weather_keys.php
index 43272bb9..c52c1b45 100644
--- a/logic/weather_keys.php
+++ b/logic/weather_keys.php
@@ -1,72 +1,50 @@
$GLOBALS['weather'][$i],
- 'callback_data' => $pokedex_id . ':' . $action . ':' . $new_weather
- );
- }
+ // Get the type, level and cp
+ $weather_value = $data['w'] ?? '';
+
+ // Init empty keys array.
+ $keys = [];
+
+ // Max amount of weathers a pokemon raid boss can have is 3 which means 999
+ // Keys will be shown up to 99 and when user is adding one more weather we exceed 99, so we remove the keys then
+ // This means we do not exceed the max amout of 3 weathers a pokemon can have :)
+ // And no, 99 is not a typo if you read my comment above :P
+ if($weather_value <= 99) {
+ // Get last number from weather array
+ end($GLOBALS['weather']);
+ $last = key($GLOBALS['weather']);
+ $buttonData = $data;
+ // Add buttons for each weather.
+ for ($i = 1; $i <= $last; $i = $i + 1) {
+ // Continue if weather got already selected
+ if (preg_match('/'.$i.'/', $weather_value))
+ continue;
+
+ // Set new weather.
+ $buttonData['w'] = $weather_value . $i;
+
+ // Set keys.
+ $keys[] = button($GLOBALS['weather'][$i], $buttonData);
}
-
- // Get the inline key array.
- $keys = inline_key_array($keys, 3);
-
- // Save and Reset key
- $keys[] = array(
- array(
- 'text' => EMOJI_DISK,
- 'callback_data' => $pokedex_id . ':' . $action . ':' . $save_arg
- ),
- array(
- 'text' => getTranslation('reset'),
- 'callback_data' => $pokedex_id . ':' . $action . ':' . $reset_arg
- )
- );
-
- return $keys;
+ }
+ // Get the inline key array.
+ $keys = inline_key_array($keys, 3);
+
+ $saveData = $resetData = $data;
+ $saveData['a'] = 'save';
+ unset($resetData['w']);
+ // Save and Reset key
+ $keys[] = array(
+ button(EMOJI_DISK, $saveData),
+ button(getTranslation('reset'), $resetData)
+ );
+
+ return $keys;
}
-
-?>
diff --git a/metrics/index.php b/metrics/index.php
index e30c31dc..e5214954 100644
--- a/metrics/index.php
+++ b/metrics/index.php
@@ -7,9 +7,9 @@
use Prometheus\RenderTextFormat;
require_once __DIR__ . '/../core/bot/paths.php';
-require_once(CORE_BOT_PATH . '/logic/debug.php');
-require_once(CORE_BOT_PATH . '/logic/bearer_token.php');
require_once(CORE_BOT_PATH . '/config.php');
+require_once(ROOT_PATH . '/logic/debug.php');
+require_once(ROOT_PATH . '/logic/bearer_token.php');
// Authentication is done based on a Bearer Token provided as a header
$bearer_token = getBearerToken();
diff --git a/mods/bot_lang.php b/mods/bot_lang.php
index 15d3ec64..e289a53d 100644
--- a/mods/bot_lang.php
+++ b/mods/bot_lang.php
@@ -7,55 +7,38 @@
//debug_log($data);
// Access check.
-bot_access_check($update, 'trainer');
-
+$botUser->accessCheck('trainer');
$keys = [];
-if($data['arg'] != '0') {
- $query = "
- UPDATE users
- SET lang_manual = 1,
- lang= :lang
- WHERE user_id = :user_id
- ";
- $q = $dbh->prepare($query);
- $q->execute([
- 'lang' => $data['arg'],
- 'user_id' => $update['callback_query']['from']['id']
- ]);
- $new_lang_internal = $languages[$data['arg']];
- $msg = getTranslation('new_lang_saved', true, $new_lang_internal);
- $keys[] = [
- [
- 'text' => getTranslation('back', true, $new_lang_internal),
- 'callback_data' => '0:trainer:0'
- ],
- [
- 'text' => getTranslation('done', true, $new_lang_internal),
- 'callback_data' => '0:exit:1'
- ]
- ];
- $callback_msg = $msg;
+if(isset($data['l'])) {
+ $query = my_query('
+ UPDATE users
+ SET lang_manual = 1,
+ lang= :lang
+ WHERE user_id = :user_id
+ ',[
+ 'lang' => $data['l'],
+ 'user_id' => $update['callback_query']['from']['id'],
+ ]);
+ $new_lang_internal = $languages[$data['l']];
+ $msg = getTranslation('new_lang_saved', $new_lang_internal);
+ $keys[0][] = button(getTranslation('back', $new_lang_internal), 'trainer');
+ $keys[0][] = button(getTranslation('done', $new_lang_internal), ['exit', 'd' => '1']);
+ $callback_msg = $msg;
} else {
- foreach($languages as $lang_tg => $lang_internal) {
- $keys[][] = [
- 'text' => getTranslation('lang_name', true, $lang_internal),
- 'callback_data' => '0:bot_lang:'.$lang_tg
- ];
- }
- $keys[] = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => '0:trainer:0'
- ],
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ];
- $msg = getTranslation('change_lang').':';
- $callback_msg = getTranslation('change_lang');
+ $displayedLanguages = [];
+ foreach($languages as $lang_tg => $lang_internal) {
+ if(in_array($lang_internal, $displayedLanguages)) continue;
+ $keys[][] = button(getTranslation('lang_name', $lang_internal), ['bot_lang', 'l' => $lang_tg]);
+ $displayedLanguages[] = $lang_internal;
+ }
+ $keys[] = [
+ button(getTranslation('back'), 'trainer'),
+ button(getTranslation('done'), ['exit', 'd' => '1'])
+ ];
+ $msg = getTranslation('change_lang').':';
+ $callback_msg = getTranslation('change_lang');
}
// Answer callback.
@@ -63,9 +46,3 @@
// Edit message.
edit_message($update, $msg, $keys, false);
-
-// Exit.
-$dbh = null;
-exit();
-
-?>
\ No newline at end of file
diff --git a/mods/change_trainercode.php b/mods/change_trainercode.php
index b8aa396b..f3a0141b 100644
--- a/mods/change_trainercode.php
+++ b/mods/change_trainercode.php
@@ -7,37 +7,25 @@
$trainercode = preg_replace('/\D/', '', $update['message']['text']);
// Check that Code is 12 digits long
-if(strlen($trainercode)==12){
- // Store new Trainercode to DB
- my_query(
- "
- UPDATE users
- SET trainercode = '{$trainercode}'
- WHERE user_id = {$target_user_id}
- "
- );
-
- // Remove back button from previous message to avoid confusion
- edit_message_keyboard($modifiers['old_message_id'], [], $target_user_id);
-
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => '0:trainer:0'
- ],
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ]
- ];
-
- // confirm Trainercode-Change
- send_message($target_user_id, getTranslation('trainercode_success').' '.$trainercode.'', $keys);
-}else{
- // Trainer Code got unallowed Chars -> Error-Message
- send_message($target_user_id, getTranslation('trainercode_fail'));
- exit();
+if(strlen($trainercode) != 12){
+ // Trainer Code got unallowed Chars -> Error-Message
+ send_message(create_chat_object([$target_user_id]), getTranslation('trainercode_fail'));
+ exit();
}
+// Store new Trainercode to DB
+my_query('
+ UPDATE users
+ SET trainercode = ?
+ WHERE user_id = ?
+ ', [$trainercode, $target_user_id]
+);
+
+// Remove back button from previous message to avoid confusion
+edit_message_keyboard($modifiers['old_message_id'], [], $target_user_id);
+
+// Create the keys.
+$keys[0][0] = button(getTranslation('back'), 'trainer');
+$keys[0][1] = button(getTranslation('done'), ['exit', 'd' => '1']);
+
+// confirm Trainercode-Change
+send_message(create_chat_object([$target_user_id]), getTranslation('trainercode_success').' '.$trainercode.'', $keys);
diff --git a/mods/change_trainername.php b/mods/change_trainername.php
index 7d0abb4a..02c35bfd 100644
--- a/mods/change_trainername.php
+++ b/mods/change_trainername.php
@@ -5,40 +5,27 @@
$returnValue = preg_match('/^[A-Za-z0-9]{0,15}$/', $update['message']['text']);
// Only numbers and alphabetic character allowed
-if($returnValue){
- $trainername = $update['message']['text'];
- // Store new Gamer-Name to DB
- my_query(
- "
- UPDATE users
- SET trainername = '{$trainername}',
- display_name = IF(trainername is null, 0, 1)
- WHERE user_id = {$userid}
- "
- );
-
- // Remove back button from previous message to avoid confusion
- edit_message_keyboard($modifiers['old_message_id'], [], $userid);
+if(!$returnValue){
+ // Trainer Name got unallowed Chars -> Error-Message
+ send_message(create_chat_object([$userid]), getTranslation('trainername_fail'));
+ exit();
+}
+$trainername = $update['message']['text'];
+// Store new Gamer-Name to DB
+my_query('
+ UPDATE users
+ SET trainername = ?,
+ display_name = IF(trainername is null, 0, 1)
+ WHERE user_id = ?
+ ', [$trainername, $userid]
+);
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => '0:trainer:0'
- ],
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ]
- ];
+// Remove back button from previous message to avoid confusion
+edit_message_keyboard($modifiers['old_message_id'], [], $userid);
- // confirm Name-Change
- send_message($userid, getTranslation('trainername_success').' '.$trainername.'', $keys);
-}else{
- // Trainer Name got unallowed Chars -> Error-Message
- send_message($userid, getTranslation('trainername_fail'));
- exit();
-}
+// Create the keys.
+$keys[0][] = button(getTranslation('back'), 'trainer');
+$keys[0][] = button(getTranslation('done'), ['exit', 'd' => '1']);
+// confirm Name-Change
+send_message(create_chat_object([$userid]), getTranslation('trainername_success').' '.$trainername.'', $keys);
diff --git a/mods/code.php b/mods/code.php
index 407905e2..d984497d 100644
--- a/mods/code.php
+++ b/mods/code.php
@@ -1,6 +1,7 @@
accessCheck('list');
// Set the raid id.
-$raid_id = $data['id'];
+$raid_id = $data['r'];
// Set the arg.
-$arg = $data['arg'];
+$arg = $data['a'] ?? '';
// Telegram JSON array.
$tg_json = array();
@@ -23,7 +24,7 @@
$raid = get_raid($raid_id);
$gym_name = $raid['gym_name'];
if(empty($gym_name)) {
- $gym_name = '';
+ $gym_name = '';
}
$msg = $gym_name . CR;
$raid_day = dt2date($raid['start_time']);
@@ -35,114 +36,102 @@
// Public or private raid group?
if($arg == 'public-unconfirmed' || $arg == 'public-send') {
- // Log
- debug_log('Public raid group');
- if($arg == 'public-send') {
- // Groupcode
- $group_code = getTranslation('start_raid_public') . SP . getTranslation('no_group_code');
-
- // Send code via alarm function
- $tg_json = alarm($raid_id,$update['callback_query']['from']['id'],'group_code_public',$group_code, $tg_json);
-
- // Init empty keys array.
- $keys = [];
-
- // Build callback message string.
- $callback_response = getTranslation('code_send');
-
- // Set the message.
- $msg .= '' . getTranslation('code_send') . '' . CR . CR;
- $msg .= getTranslation('group_code') . ':' . CR;
- $msg .= $group_code;
- } else {
- // Init empty keys array.
- $keys = [];
-
- // Back and abort.
- $keys[] = [
- [
- 'text' => EMOJI_INVITE,
- 'callback_data' => $raid_id . ':code:public-send'
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
-
- // Build callback message string.
- $callback_response = 'OK';
-
- // Set the message.
- $msg .= '' . getTranslation('start_raid_now') . ':' . CR . CR;
- }
+ // Log
+ debug_log('Public raid group');
+ if($arg == 'public-send') {
+ // Groupcode
+ $group_code = getTranslation('start_raid_public') . SP . getTranslation('no_group_code');
+
+ // Send code via alarm function
+ $tg_json = alarm($raid_id,$update['callback_query']['from']['id'],'group_code_public',$group_code, $tg_json);
+
+ // Init empty keys array.
+ $keys = [];
+
+ // Build callback message string.
+ $callback_response = getTranslation('code_send');
+
+ // Set the message.
+ $msg .= '' . getTranslation('code_send') . '' . CR . CR;
+ $msg .= getTranslation('group_code') . ':' . CR;
+ $msg .= $group_code;
+ } else {
+ // Init empty keys array.
+ $keys = [];
+
+ // Back and abort.
+ $keys[0][0] = button(EMOJI_INVITE, ['code' ,'r' => $raid_id, 'a' => 'public-send']);
+ $keys[0][1] = button(getTranslation('abort'), 'exit');
+
+ // Build callback message string.
+ $callback_response = 'OK';
+
+ // Set the message.
+ $msg .= '' . getTranslation('start_raid_now') . ':' . CR . CR;
+ }
} else {
- // Get the current code
- $data = explode("-", $arg);
- $c1 = $data[0];
- $c2 = $data[1];
- $c3 = $data[2];
-
- // Get pokemon names.
- $p1 = ($c1 > 0) ? get_local_pokemon_name($c1, 0) : '';
- $p2 = ($c2 > 0) ? get_local_pokemon_name($c2, 0) : '';
- $p3 = ($c3 > 0) ? get_local_pokemon_name($c3, 0) : '';
-
- // Action to do: Ask to send or add code?
- $action = $data[3];
-
- // Log
- debug_log('Code #1: ' . $c1 . SP . '(' . $p1 . ')');
- debug_log('Code #2: ' . $c2 . SP . '(' . $p2 . ')');
- debug_log('Code #3: ' . $c3 . SP . '(' . $p3 . ')');
- debug_log('Action: ' . $action);
-
- // Add digits to cp
- if($action == 'add') {
- // Init empty keys array.
- $keys = [];
-
- // Get the keys.
- $keys = group_code_keys($raid_id, 'code', $arg);
-
- // Back and abort.
- $keys[] = [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
-
- // Build callback message string.
- $callback_response = 'OK';
-
- // Set the message.
- $msg .= '' . getTranslation('group_code') . ':' . CR;
- $msg .= ($c1 > 0) ? ($p1 . CR) : '';
- $msg .= ($c2 > 0) ? ($p2 . CR) : '';
- $msg .= ($c3 > 0) ? ($p3 . CR . CR . '' . getTranslation('start_raid_now') . ':' . CR) : '';
-
- // Send code to users
- } else if($action == 'send') {
- // Groupcode
- $group_code = $p1 . '--' . SP;
- $group_code .= $p2 . '--' . SP;
- $group_code .= $p3 . CR;
-
- // Send code via alarm function
- $tg_json = alarm($raid_id,$update['callback_query']['from']['id'],'group_code_private',$group_code, $tg_json);
-
- // Init empty keys array.
- $keys = [];
-
- // Build callback message string.
- $callback_response = getTranslation('code_send');
-
- // Set the message.
- $msg .= '' . getTranslation('code_send') . '' . CR . CR;
- $msg .= getTranslation('group_code') . ':' . CR;
- $msg .= $group_code;
- }
+ // Get the current code
+ $data = explode("-", $arg);
+ $c1 = $data[0];
+ $c2 = $data[1];
+ $c3 = $data[2];
+
+ // Get pokemon names.
+ $p1 = ($c1 > 0) ? get_local_pokemon_name($c1, 0) : '';
+ $p2 = ($c2 > 0) ? get_local_pokemon_name($c2, 0) : '';
+ $p3 = ($c3 > 0) ? get_local_pokemon_name($c3, 0) : '';
+
+ // Action to do: Ask to send or add code?
+ $action = $data[3];
+
+ // Log
+ debug_log('Code #1: ' . $c1 . SP . '(' . $p1 . ')');
+ debug_log('Code #2: ' . $c2 . SP . '(' . $p2 . ')');
+ debug_log('Code #3: ' . $c3 . SP . '(' . $p3 . ')');
+ debug_log('Action: ' . $action);
+
+ // Add digits to cp
+ if($action == 'add') {
+ require_once(LOGIC_PATH . '/group_code_keys.php');
+ // Init empty keys array.
+ $keys = [];
+
+ // Get the keys.
+ $keys = group_code_keys($raid_id, 'code', $arg);
+
+ // Back and abort.
+ $keys[][] = button(getTranslation('abort'), 'exit');
+
+ // Build callback message string.
+ $callback_response = 'OK';
+
+ // Set the message.
+ $msg .= '' . getTranslation('group_code') . ':' . CR;
+ $msg .= ($c1 > 0) ? ($p1 . CR) : '';
+ $msg .= ($c2 > 0) ? ($p2 . CR) : '';
+ $msg .= ($c3 > 0) ? ($p3 . CR . CR . '' . getTranslation('start_raid_now') . ':' . CR) : '';
+
+ // Send code to users
+ } else if($action == 'send') {
+ // Groupcode
+ $group_code = $p1 . '--' . SP;
+ $group_code .= $p2 . '--' . SP;
+ $group_code .= $p3 . CR;
+
+ // Send code via alarm function
+ $tg_json = alarm($raid_id,$update['callback_query']['from']['id'],'group_code_private',$group_code, $tg_json);
+
+ // Init empty keys array.
+ $keys = [];
+
+ // Build callback message string.
+ $callback_response = getTranslation('code_send');
+
+ // Set the message.
+ $msg .= '' . getTranslation('code_send') . '' . CR . CR;
+ $msg .= getTranslation('group_code') . ':' . CR;
+ $msg .= $group_code;
+ }
}
// Answer callback.
@@ -153,6 +142,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/code_start.php b/mods/code_start.php
index 73b88923..f69849b1 100644
--- a/mods/code_start.php
+++ b/mods/code_start.php
@@ -8,7 +8,7 @@
// Allow anyone to use /code
// Check access.
-//bot_access_check($update, 'list');
+//$botUser->accessCheck('list');
// Get raid
$raid = get_raid($code_raid_id);
@@ -23,49 +23,32 @@
// Raid ended already.
if ($end_time > $now) {
- // Set text and keys.
- $gym_name = $raid['gym_name'];
- if(empty($gym_name)) {
- $gym_name = '';
- }
-
- $text .= $gym_name . CR;
- $raid_day = dt2date($raid['start_time']);
- $now = utcnow();
- $today = dt2date($now);
- $start = dt2time($raid['start_time']);
- $end = dt2time($raid['end_time']);
- $text .= get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form']) . SP . '-' . SP . (($raid_day == $today) ? '' : ($raid_day . ', ')) . $start . SP . getTranslation('to') . SP . $end . CR . CR;
-
- // Add exit key.
- $keys = [
- [
- [
- 'text' => getTranslation('start_raid_public'),
- 'callback_data' => $raid['id'] . ':code:public-unconfirmed'
- ],
- [
- 'text' => getTranslation('start_raid_private'),
- 'callback_data' => $raid['id'] . ':code:0-0-0-add'
- ]
- ],
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
-
- // Build message.
- $msg = '' . getTranslation('start_raid_now') . ':' . CR . CR;
- $msg .= $text;
+ // Set text and keys.
+ $gym_name = $raid['gym_name'];
+ if(empty($gym_name)) {
+ $gym_name = '';
+ }
+
+ $text .= $gym_name . CR;
+ $raid_day = dt2date($raid['start_time']);
+ $now = utcnow();
+ $today = dt2date($now);
+ $start = dt2time($raid['start_time']);
+ $end = dt2time($raid['end_time']);
+ $text .= get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form']) . SP . '-' . SP . (($raid_day == $today) ? '' : ($raid_day . ', ')) . $start . SP . getTranslation('to') . SP . $end . CR . CR;
+
+ // Add exit key.
+ $keys[0][] = button(getTranslation('start_raid_public'), ['code', 'r' => $raid['id'], 'a' => 'public-unconfirmed']);
+ $keys[0][] = button(getTranslation('start_raid_private'), ['code', 'r' => $raid['id'], 'a' => '0-0-0-add']);
+ $keys[1][] = button(getTranslation('abort'), 'exit');
+
+ // Build message.
+ $msg = '' . getTranslation('start_raid_now') . ':' . CR . CR;
+ $msg .= $text;
} else {
- $msg = '' . getTranslation('group_code_share') . ':' . CR;
- $msg .= '' . getTranslation('no_active_raids_found') . '';
+ $msg = '' . getTranslation('group_code_share') . ':' . CR;
+ $msg .= '' . getTranslation('no_active_raids_found') . '';
}
// Send message.
-send_message($update['message']['chat']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
-
-?>
+send_message(create_chat_object([$update['message']['chat']['id']]), $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
diff --git a/mods/delete_scheduled_entry.php b/mods/delete_scheduled_entry.php
deleted file mode 100644
index 012bf1d0..00000000
--- a/mods/delete_scheduled_entry.php
+++ /dev/null
@@ -1,52 +0,0 @@
-fetch();
- $msg = getTranslation('delete_scheduled_confirmation') . CR . CR;
- $msg .= $pokemon['date_start'] . ' - ' . $pokemon['date_end'] . ':' . CR;
- $msg .= getTranslation($pokemon['raid_level'] . 'stars') . ': ';
- $msg .= get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id']);
-
- $keys[] = [
- [
- 'text' => getTranslation('yes'),
- 'callback_data' => $id . ':' . 'delete_scheduled_entry' . ':1'
- ],
- [
- 'text' => getTranslation('no'),
- 'callback_data' => '0:pokedex_list_raids:0'
- ],
- ];
-}
-
-// Build callback message string.
-$callback_response = 'OK';
-
-// Telegram JSON array.
-$tg_json = array();
-
-// Answer callback.
-$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
-
-// Edit message.
-$tg_json[] = edit_message($update, $msg, $keys, false, true);
-
-// Telegram multicurl request.
-curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
-
-?>
diff --git a/mods/edit_date.php b/mods/edit_date.php
index 90acab81..d83985c6 100644
--- a/mods/edit_date.php
+++ b/mods/edit_date.php
@@ -7,85 +7,70 @@
//debug_log($data);
// Check access.
-bot_access_check($update, 'ex-raids');
+$botUser->accessCheck('create');
-// Set the id.
-$id = $data['id'];
-$gym_id = explode(',',$data['id'])[0];
-
-// Get the argument.
-$arg = $data['arg'];
-$arg_data = explode(',', $arg);
-$event_id = $arg_data[0];
-$raid_level = $arg_data[1];
-$pokemon_id = $arg_data[2];
-$raid_time = $arg_data[3];
+$raid_time = $data['t'];
// Init empty keys array and set keys count.
$keys = [];
$keys_count = 2;
-// Received: Year-Month-Day / 1970-01-01 / 2x "-"
-if (substr_count($raid_time, '-') == 2) {
- debug_log('Generating buttons for each hour of the day');
- // Buttons for each hour
- for ($i = 0; $i <= 23; $i = $i + 1) {
- // Create the keys.
- $keys[] = array(
- // Just show the time, no text - not everyone has a phone or tablet with a large screen...
- 'text' => str_pad($i, 2, '0', STR_PAD_LEFT) . ':xx',
- 'callback_data' => $id . ':edit_date:' . $arg . ' ' . str_pad($i, 2, '0', STR_PAD_LEFT) . '-'
- );
- }
- // Set keys count and message.
- $keys_count = 4;
- $msg = getTranslation('raid_select_hour');
-// Received: Year-Month-Day Hour- / 1970-01-01 00- / 3x "-"
-} else if (substr_count($raid_time, '-') == 3) {
- debug_log('Generating buttons for minute of the hour');
- $hour = explode(" ", $raid_time);
- $hour = $hour[1];
- // Buttons for each minute
- for ($i = 0; $i <= 45; $i = $i + 15) {
- // Create the keys.
- $keys[] = array(
- // Just show the time, no text - not everyone has a phone or tablet with a large screen...
- 'text' => substr($hour, 0, -1) . ':' . str_pad($i, 2, '0', STR_PAD_LEFT),
- 'callback_data' => $id . ':edit_date:' . $arg . str_pad($i, 2, '0', STR_PAD_LEFT) . '-00'
- );
- }
- // Set keys count and message.
- $keys_count = 4;
- $msg = getTranslation('raid_select_start_time');
-// Received: Year-Month-Day Hour-Minute-Second / 1970-01-01 00-00-00 / 4x "-"
-} else if (substr_count($raid_time, '-') == 4) {
- debug_log('Received the following date for the raid: ' . $raid_time);
-
- // Format date, e.g 14 April 2019, 15:15h
- $tz = $config->TIMEZONE;
- $tz_raid_time = DateTimeImmutable::createFromFormat('Y-m-d H-i-s', $raid_time, new DateTimeZone($tz));
- $date_tz = $tz_raid_time->format('Y-m-d');
- $text_split = explode('-', $date_tz);
- $text_day = $text_split[2];
- $text_month = getTranslation('month_' . $text_split[1]);
- $text_year = $text_split[0];
- $time_tz = $tz_raid_time->format('H:i') . 'h';
-
- // Raid time in UTC
- $utc_raid_time = $tz_raid_time->setTimezone(new DateTimeZone('UTC'));
- $utc_raid_time = $utc_raid_time->format('Y-m-d H-i-s');
- debug_log('Converting date to UTC to store in database');
- debug_log('UTC date for the raid: ' . $utc_raid_time);
- debug_log('Waiting for confirmation to save the raid');
-
- // Adding button to continue with next step in raid creation
- $keys[] = array(
- 'text' => getTranslation('next'),
- 'callback_data' => $id . ':edit_time:' . $event_id . ','. $raid_level . ',' . $pokemon_id . ',' . $utc_raid_time . ',X,0'
- );
-
- // Set message.
- $msg = getTranslation('start_date_time') . ':' . CR .'' . $text_day . SP . $text_month . SP . $text_year . ',' . SP . $time_tz . '';
+$buttonData = $data;
+// Received: YearMonthDay / 19700101
+if (strlen($raid_time) == 8) {
+ debug_log('Generating buttons for each hour of the day');
+ // Buttons for each hour
+ $buttonData[0] = 'edit_date';
+ for ($i = 0; $i <= 23; $i = $i + 1) {
+ $buttonData['t'] = $data['t'] . str_pad($i, 2, '0', STR_PAD_LEFT);
+ // Create the keys.
+ $keys[] = button(str_pad($i, 2, '0', STR_PAD_LEFT) . ':xx', $buttonData);
+ }
+ // Set keys count and message.
+ $keys_count = 4;
+ $msg = getTranslation('raid_select_hour');
+// Received: YearMonthDayHour / 1970010100
+} else if (strlen($raid_time) == 10) {
+ debug_log('Generating buttons for minute of the hour');
+ $hour = substr($raid_time,8,2);
+ // Buttons for each minute
+ $buttonData[0] = 'edit_date';
+ for ($i = 0; $i <= 45; $i = $i + 15) {
+ $buttonData['t'] = $data['t'] . str_pad($i, 2, '0', STR_PAD_LEFT);
+ // Create the keys.
+ $keys[] = button($hour . ':' . str_pad($i, 2, '0', STR_PAD_LEFT), $buttonData);
+ }
+ // Set keys count and message.
+ $keys_count = 4;
+ $msg = getTranslation('raid_select_start_time');
+// Received: YearMonthDayHourMinute / 197001010000
+} else if (strlen($raid_time) == 12) {
+ debug_log('Received the following date for the raid: ' . $raid_time);
+
+ // Format date, e.g 14 April 2019, 15:15h
+ $tz = $config->TIMEZONE;
+ $tz_raid_time = DateTimeImmutable::createFromFormat('YmdHi', $raid_time, new DateTimeZone($tz));
+ $date_tz = $tz_raid_time->format('Y-m-d');
+ $text_split = explode('-', $date_tz);
+ $text_day = $text_split[2];
+ $text_month = getTranslation('month_' . $text_split[1]);
+ $text_year = $text_split[0];
+ $time_tz = $tz_raid_time->format('H:i') . 'h';
+
+ // Raid time in UTC
+ $utc_raid_time = $tz_raid_time->setTimezone(new DateTimeZone('UTC'));
+ $utc_raid_time = $utc_raid_time->format('YmdHi');
+ debug_log('Converting date to UTC to store in database');
+ debug_log('UTC date for the raid: ' . $utc_raid_time);
+ debug_log('Waiting for confirmation to save the raid');
+
+ // Adding button to continue with next step in raid creation
+ $buttonData[0] = 'edit_time';
+ $buttonData['t'] = $utc_raid_time;
+ $keys[] = button(getTranslation('next'), $buttonData);
+
+ // Set message.
+ $msg = getTranslation('start_date_time') . ':' . CR .'' . $text_day . SP . $text_month . SP . $text_year . ',' . SP . $time_tz . '';
}
// Get the inline key array.
@@ -96,13 +81,13 @@
// Back key id, action and arg
if(substr_count($raid_time, '-') == 1 || substr_count($raid_time, '-') == 4) {
- $back_id = $id;
- $back_action = 'edit_starttime';
- $back_arg = $arg;
- $nav_keys[] = universal_inner_key($nav_keys, $back_id, $back_action, $back_arg, getTranslation('back'));
+ $backData = $data;
+ $backData[0] = 'edit_starttime';
+ unset($backData['t']);
+ $nav_keys[] = button(getTranslation('back'), $backData);
}
-$nav_keys[] = universal_inner_key($nav_keys, $gym_id, 'exit', '2', getTranslation('abort'));
+$nav_keys[] = button(getTranslation('abort'), 'exit');
$nav_keys = inline_key_array($nav_keys, 2);
// Merge keys.
@@ -122,6 +107,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/edit_event.php b/mods/edit_event.php
index 256da3fe..bd1caae8 100644
--- a/mods/edit_event.php
+++ b/mods/edit_event.php
@@ -1,46 +1,31 @@
accessCheck('ex-raids', true);
+// Check access - user must be admin for raid event creation
+$admin_access[1] = $botUser->accessCheck('event-raids', true);
// Get the keys.
-$keys = keys_event($gym_id_plus_letter, "edit_event_raidlevel");
-
-// No keys found.
-if (!$keys) {
- $keys = [
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
-} else {
- // Back key id, action and arg
- $back_id_arg = explode(',', $gym_id_plus_letter);
- $back_id = $back_id_arg[1];
- $back_action = 'edit_raidlevel';
- $back_arg = $back_id_arg[0];
-
- // Add navigation keys.
- $nav_keys = [];
- $nav_keys[] = universal_inner_key($nav_keys, $back_id, $back_action, $back_arg, getTranslation('back'));
- $nav_keys[] = universal_inner_key($nav_keys, $back_arg, 'exit', '2', getTranslation('abort'));
- $nav_keys = inline_key_array($nav_keys, 2);
-
- // Merge keys.
- $keys = array_merge($keys, $nav_keys);
-}
+$keys = keys_event($data, 'edit_event_raidlevel', $admin_access);
+
+$backData = $data;
+$backData[0] = 'edit_raidlevel';
+
+// Add navigation keys.
+$keys[] = [
+ button(getTranslation('back'), $backData),
+ button(getTranslation('abort'), 'exit')
+];
+
// Build callback message string.
$callback_response = 'OK';
@@ -56,6 +41,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
\ No newline at end of file
diff --git a/mods/edit_event_note.php b/mods/edit_event_note.php
index 5ceb9fba..c24ae268 100644
--- a/mods/edit_event_note.php
+++ b/mods/edit_event_note.php
@@ -1,68 +1,61 @@
$raid_id,"old_message_id"=>$update['callback_query']['message']['message_id'])); // Save the raid id and the message id to db so we can delete it later
- $handler = "save_event_note"; // call for mods/save_event_note.php after user posts the answer
-
- my_query("INSERT INTO user_input SET user_id='{$userid}', modifiers='{$modifiers}', handler='{$handler}'");
-}elseif($mode == "cancel") {
- my_query("DELETE FROM user_input WHERE user_id='{$userid}'");
- $data['arg'] = 0;
- require_once("edit_save.php");
-}else {
- if($raid['event'] == EVENT_ID_EX) {
- $event_name = getTranslation('Xstars');
- }else {
- $q = my_query("SELECT * FROM events WHERE id='{$raid['event']}'");
- $res = $q->fetch();
- $event_name = $res['name'];
- }
+if($mode == 'e') {
+ $msg.= getTranslation('event_note_edit') . ': ';
+
+ // Create an entry to user_input table
+ $modifiers = json_encode(array('id' => $raid_id, 'old_message_id' => $update['callback_query']['message']['message_id'])); // Save the raid id and the message id to db so we can delete it later
+ $handler = 'save_event_note'; // call for mods/save_event_note.php after user posts the answer
- $msg.= getTranslation("event") . ": ".$event_name."".CR;
- $msg.= getTranslation("event_add_note_description");
-
- // Create an entry to user_input table
- $modifiers = json_encode(array("id"=>$raid_id,"old_message_id"=>$update['callback_query']['message']['message_id'])); // Save the raid id and the message id to db so we can delete it later
- $handler = "save_event_note"; // call for mods/save_event_note.php after user posts the answer
-
- my_query("INSERT INTO user_input SET user_id='{$userid}', modifiers='{$modifiers}', handler='{$handler}'");
+ my_query('INSERT INTO user_input SET user_id=:userId, modifiers=:modifiers, handler=:handler', ['userId' => $userid, 'modifiers' => $modifiers, 'handler' => $handler]);
+}elseif($mode == 'c') {
+ my_query('DELETE FROM user_input WHERE user_id = ?', [$userid]);
+ require_once('edit_save.php');
+ exit();
+}else {
+ if($raid['event'] == EVENT_ID_EX) {
+ $event_name = getTranslation('Xstars');
+ }else {
+ $q = my_query('SELECT name FROM events WHERE id = ?', [$raid['event']]);
+ $res = $q->fetch();
+ $event_name = $res['name'];
+ }
+
+ $msg.= getTranslation('event') . ': ' . $event_name . '' . CR;
+ $msg.= getTranslation('event_add_note_description');
+
+ // Create an entry to user_input table
+ $modifiers = json_encode(array('id' => $raid_id, 'old_message_id' => $update['callback_query']['message']['message_id'])); // Save the raid id and the message id to db so we can delete it later
+ $handler = 'save_event_note'; // call for mods/save_event_note.php after user posts the answer
+
+ my_query('INSERT INTO user_input SET user_id = :userId, modifiers = :modifiers, handler = :handler', ['userId' => $userid, 'modifiers' => $modifiers, 'handler' => $handler]);
}
-$keys[] = [
- [
- 'text' => getTranslation('cancel'),
- 'callback_data' => $raid_id . ':edit_event_note:'. $arg[0] . ',cancel'
- ]
- ];
+$keys[][] = button(getTranslation('cancel'), ['edit_event_note', 'r' => $raid_id, 'm' => 'c']);
// Answer callback.
answerCallbackQuery($update['callback_query']['id'], $callback_response);
// Edit message.
edit_message($update, $msg, $keys, false);
-
-exit();
\ No newline at end of file
diff --git a/mods/edit_event_raidlevel.php b/mods/edit_event_raidlevel.php
index f952d0e3..df4b9af5 100644
--- a/mods/edit_event_raidlevel.php
+++ b/mods/edit_event_raidlevel.php
@@ -1,70 +1,51 @@
accessCheck('ex-raids', true);
+// Check access - user must be admin for raid event creation
+$admin_access[1] = $botUser->accessCheck('event-raids', true);
// Get the keys.
-$keys = raid_edit_raidlevel_keys($gym_id, $gym_first_letter, $admin_access, $event_id);
-
-// No keys found.
-if (!$keys) {
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
-} else {
- // Add navigation keys.
- $nav_keys = [];
- $nav_keys[] = universal_inner_key($nav_keys, $back_id, $back_action, $back_arg, getTranslation('back'));
- $nav_keys[] = universal_inner_key($nav_keys, $gym_id, 'exit', '2', getTranslation('abort'));
- $nav_keys = inline_key_array($nav_keys, 2);
- // Merge keys.
- $keys = array_merge($keys, $nav_keys);
-}
-// Get event info
-$q = my_query("SELECT name, description FROM events WHERE id='{$event_id}' LIMIT 1");
+$keys = raid_edit_raidlevel_keys($data, $admin_access, $event_id);
+
+$backData = $data;
+$backData[0] = 'edit_event';
+// Add navigation keys.
+$keys[] = [
+ button(getTranslation('back'), $backData),
+ button(getTranslation('abort'), 'exit')
+];
+
+// Get event info
+$q = my_query('SELECT name, description FROM events WHERE id = ? LIMIT 1', [$event_id]);
$rs = $q->fetch();
// Build message.
-if($event_id == 'X') {
- $msg = "".getTranslation('Xstars')."".CR;
+if($event_id == EVENT_ID_EX) {
+ $msg = '' . getTranslation(RAID_ID_EX . 'stars') . '' . CR;
}else {
- $msg = "{$rs['name']}".CR."{$rs['description']}".CR;
+ $msg = '' . $rs['name'] . '' . CR . $rs['description'] . CR;
}
-$msg.= getTranslation('create_raid') . ': ' . (($gym['address']=="") ? $gym['gym_name'] : $gym['address']) . '';
+$msg .= getTranslation('create_raid') . ': ' . (($gym['address']=='') ? $gym['gym_name'] : $gym['address']) . '';
// Build callback message string.
$callback_response = getTranslation('gym_saved');
@@ -77,7 +58,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
-
diff --git a/mods/edit_pokemon.php b/mods/edit_pokemon.php
index 28d21453..af480315 100644
--- a/mods/edit_pokemon.php
+++ b/mods/edit_pokemon.php
@@ -1,4 +1,5 @@
accessCheck('create');
// Set the raid level and event.
-$event_id = $arg_data[0];
-$raid_level = $arg_data[1];
+$eventId = $data['e'] ?? NULL;
+$raidLevel = $data['rl'];
// Check if we are creating an event
-if($event_id != "N") {
- // If yes, go to date selection
- $action = "edit_time";
+if($eventId != NULL) {
+ // If yes, go to date selection
+ $action = "edit_time";
}else {
- // If not, select start time
- $action = "edit_starttime";
+ // If not, select start time
+ $action = "edit_starttime";
}
// Get the keys.
-$keys = pokemon_keys($gym_id_plus_letter, $raid_level, "edit_starttime", $event_id);
-
-// No keys found.
-if (!$keys) {
- $keys = [
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
-} else {
- if($event_id == "N") {
- $back_id_arg = explode(',', $gym_id_plus_letter);
- $back_id = $back_id_arg[1];
- $back_action = 'edit_raidlevel';
- $back_arg = $back_id_arg[0];
- }else {
- $back_id = $gym_id_plus_letter;
- $back_action = 'edit_event_raidlevel';
- $back_arg = $event_id;
- }
+$keys = pokemon_keys($data, $raidLevel, 'edit_starttime', $eventId);
- // Add navigation keys.
- $nav_keys = [];
- $nav_keys[] = universal_inner_key($nav_keys, $back_id, $back_action, $back_arg, getTranslation('back'));
- $nav_keys[] = universal_inner_key($nav_keys, $back_arg, 'exit', '2', getTranslation('abort'));
- $nav_keys = inline_key_array($nav_keys, 2);
+$back_action = ($eventId == NULL) ? 'edit_raidlevel' : 'edit_event_raidlevel';
- // Merge keys.
- $keys = array_merge($keys, $nav_keys);
-}
+// Add navigation keys.
+$backData = $data;
+$backData[0] = $back_action;
+$keys[] = [
+ button(getTranslation('back'), $backData),
+ button(getTranslation('abort'), 'exit')
+];
// Build callback message string.
$callback_response = 'OK';
@@ -73,13 +47,10 @@
// Edit the message.
if (isset($update['callback_query']['inline_message_id'])) {
- $tg_json[] = editMessageText($update['callback_query']['inline_message_id'], getTranslation('select_raid_boss') . ':', $keys, NULL, false, true);
+ $tg_json[] = editMessageText($update['callback_query']['inline_message_id'], getTranslation('select_raid_boss') . ':', $keys, NULL, false, true);
} else {
- $tg_json[] = editMessageText($update['callback_query']['message']['message_id'], getTranslation('select_raid_boss') . ':', $keys, $update['callback_query']['message']['chat']['id'], $keys, true);
+ $tg_json[] = editMessageText($update['callback_query']['message']['message_id'], getTranslation('select_raid_boss') . ':', $keys, $update['callback_query']['message']['chat']['id'], $keys, true);
}
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/edit_raidlevel.php b/mods/edit_raidlevel.php
index 71015904..8b00281c 100644
--- a/mods/edit_raidlevel.php
+++ b/mods/edit_raidlevel.php
@@ -1,108 +1,105 @@
accessCheck('create');
-// Get gym data via ID in arg
-$gym_id = $data['arg'];
+$gym_id = $data['g'];
$gym = get_gym($gym_id);
-// Back key id, action and arg
-if(substr($data['id'],0,2) == 'gl') {
- $back_id = substr($data['id'],2);
- $back_action = 'raid_by_gym_letter';
- $back_arg = '0';
-}else {
- $back_id = 0;
- $back_action = 'raid_by_gym';
- $back_arg = $data['id'];
+$showBackButton = true;
+if(isset($data['z'])) {
+ $showBackButton = false;
+ unset($data['z']);
}
-$gym_first_letter = $back_arg;
// Telegram JSON array.
$tg_json = array();
+//Initialize admin rights table [ ex-raid , raid-event ]
+$admin_access = [false,false];
+// Check access - user must be admin for raid_level X
+$admin_access[0] = $botUser->accessCheck('ex-raids', true);
+// Check access - user must be admin for raid event creation
+$admin_access[1] = $botUser->accessCheck('event-raids', true);
+
// Active raid?
$duplicate_id = active_raid_duplication_check($gym_id);
if ($duplicate_id > 0) {
- $keys = [];
+ $keys = [];
+ // In case gym has already a normal raid saved to it and user has privileges to create an event raid, create a special menu
+ if($admin_access[0] == true || $admin_access[1] == true) {
+ $msg = EMOJI_WARN . SP . getTranslation('raid_already_exists') . CR;
+ $msg .= getTranslation('inspect_raid_or_create_event') . ':';
+
+ $eventData = $backData = $data;
+ $eventData[0] = 'edit_event';
+ $backData[0] = 'gymMenu';
+ $backData['stage'] = 2;
+ $backData['a'] = 'create';
+ $keys[0][0] = button(getTranslation('saved_raid'), ['raids_list', 'r' => $duplicate_id]);
+ $keys[1][0] = button(getTranslation('create_event_raid'), $eventData);
+ $keys[2][0] = button(getTranslation('back'), $backData);
+ $keys[2][1] = button(getTranslation('abort'), 'exit');
+ } else {
$raid_id = $duplicate_id;
$raid = get_raid($raid_id);
$msg = EMOJI_WARN . SP . getTranslation('raid_already_exists') . SP . EMOJI_WARN . CR . show_raid_poll_small($raid);
-
- // Check if the raid was already shared.
- $rs_share = my_query(
- "
- SELECT COUNT(*) AS raid_count
- FROM cleanup
- WHERE raid_id = '{$raid_id}'
- "
- );
-
- $shared = $rs_share->fetch();
-
- // Add keys for sharing the raid.
- if($shared['raid_count'] == 0) {
- $keys = share_keys($raid_id, 'raid_share', $update);
-
- // Exit key
- $empty_exit_key = [];
- $key_exit = universal_key($empty_exit_key, '0', 'exit', '0', getTranslation('abort'));
- $keys = array_merge($keys, $key_exit);
+ $keys = share_keys($raid_id, 'raid_share', $update, $raid['level']);
+ if($botUser->raidaccessCheck($raid['id'], 'pokemon', true)) {
+ $keys[][] = button(getTranslation('update_pokemon'), ['raid_edit_poke', 'r' => $raid['id'], 'rl' => $raid['level']]);
+ }
+ if($botUser->raidaccessCheck($raid['id'], 'delete', true)) {
+ $keys[][] = button(getTranslation('delete'), ['raids_delete', 'r' => $raid['id']]);
}
+ $keys[][] = button(getTranslation('abort'), 'exit');
+ }
- // Answer callback.
- $tg_json[] = answerCallbackQuery($update['callback_query']['id'], getTranslation('raid_already_exists'), true);
+ // Answer callback.
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], getTranslation('raid_already_exists'), true);
- // Edit the message.
- $tg_json[] = edit_message($update, $msg, $keys, false, true);
+ // Edit the message.
+ $tg_json[] = edit_message($update, $msg, $keys, false, true);
- // Telegram multicurl request.
- curl_json_multi_request($tg_json);
+ // Telegram multicurl request.
+ curl_json_multi_request($tg_json);
- // Exit.
- exit();
+ // Exit.
+ exit();
}
-//Initialize admin rights table [ ex-raid , raid-event ]
-$admin_access = [false,false];
-// Check access - user must be admin for raid_level X
-$admin_access[0] = bot_access_check($update, 'ex-raids', true);
-// Check access - user must be admin for raid event creation
-$admin_access[1] = bot_access_check($update, 'event-raids', true);
-
+$eliteId = active_raid_duplication_check($gym_id, 9);
+$excludeElite = $eliteId == 0 ? false : true;
// Get the keys.
-$keys = raid_edit_raidlevel_keys($gym_id, $gym_first_letter, $admin_access);
-
-// No keys found.
-if (!$keys) {
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
-} else {
- // Add navigation keys.
- $nav_keys = [];
- $nav_keys[] = universal_inner_key($nav_keys, $back_id, $back_action, $back_arg, getTranslation('back'));
- $nav_keys[] = universal_inner_key($nav_keys, $gym_id, 'exit', '2', getTranslation('abort'));
- $nav_keys = inline_key_array($nav_keys, 2);
- // Merge keys.
- $keys = array_merge($keys, $nav_keys);
+$keys = raid_edit_raidlevel_keys($data, $admin_access, false, $excludeElite);
+
+if($eliteId > 0) {
+ $keys[][] = button(getTranslation('saved_raid'), ['raids_list', 'r' => $eliteId]);
}
+$lastRow = [];
+if($showBackButton) {
+ $backData = $data;
+ $backData[0] = 'gymMenu';
+ $backData['a'] = 'create';
+ $backData['stage'] = 2;
+ // Add navigation keys.
+ $lastRow[] = button(getTranslation('back'), $backData);
+}
+$lastRow[] = button(getTranslation('abort'), 'exit');
+$keys[] = $lastRow;
+
// Build message.
-$msg = getTranslation('create_raid') . ': ' . (($gym['address']=="") ? $gym['gym_name'] : $gym['address']) . '';
+$msg = getTranslation('create_raid') . ': ' . (($gym['address'] == '') ? $gym['gym_name'] : $gym['address']) . '';
// Build callback message string.
$callback_response = getTranslation('gym_saved');
@@ -115,7 +112,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
-
diff --git a/mods/edit_save.php b/mods/edit_save.php
index 0c55b065..56d6b02b 100644
--- a/mods/edit_save.php
+++ b/mods/edit_save.php
@@ -1,170 +1,78 @@
accessCheck('create');
+
+// Set raid id
+$id = $data['r'];
// Set the user id.
$userid = $update['callback_query']['from']['id'];
-// Update only if time is not equal to RAID_DURATION
-if($arg != $config->RAID_DURATION && $arg != 0) {
-
- // Build query.
- my_query(
- "
- UPDATE raids
- SET end_time = DATE_ADD(start_time, INTERVAL {$arg} MINUTE)
- WHERE id = {$id}
- "
- );
-}
-
-// Fast forward to raid sharing.
-if(substr_count($data['id'], ',') == 1) {
- // Write to log.
- debug_log('Doing a fast forward now!');
- debug_log('Changing data array first...');
-
- // Reset data array
- $data = [];
- $data['id'] = $id;
- $data['action'] = 'raid_share';
- $data['arg'] = $chat;
-
- // Write to log.
- debug_log($data, '* NEW DATA= ');
-
- // Set module path by sent action name.
- $module = ROOT_PATH . '/mods/raid_share.php';
-
- // Write module to log.
- debug_log($module);
-
- // Check if the module file exists.
- if (file_exists($module)) {
- // Dynamically include module file and exit.
- include_once($module);
- exit();
- } else {
- info_log($module, 'Error! Fast forward failed as file does not exist:');
- exit();
- }
+// Update raid end time
+if(isset($data['d'])) {
+ my_query('
+ UPDATE raids
+ SET end_time = DATE_ADD(start_time, INTERVAL :duration MINUTE)
+ WHERE id = :id
+ ', [
+ 'id' => $id,
+ 'duration' => $data['d']
+ ]
+ );
}
// Telegram JSON array.
$tg_json = array();
-// Init keys.
-$keys = [];
-
-// Add delete to keys.
-$keys = [
- [
- [
- 'text' => getTranslation('delete'),
- 'callback_data' => $id . ':raids_delete:0'
- ]
- ]
-];
+// Add delete and done to keys.
+$keys[][] = button(getTranslation('delete'), ['raids_delete', 'r' => $id]);
+$keys[][] = button(getTranslation('done'), ['exit', 'd' => 1]);
// Check access level prior allowing to change raid time
-$admin_access = bot_access_check($update, 'raid-duration', true);
-if($admin_access) {
- // Add time change to keys.
- $keys_time = [
- [
- [
- 'text' => getTranslation('change_raid_duration'),
- 'callback_data' => $id . ':edit_time:0,0,0,0,more,1'
- ]
- ]
- ];
- $keys = array_merge($keys, $keys_time);
+if($botUser->accessCheck('raid-duration', true)) {
+ // Add time change to keys.
+ $keys[][] = button(getTranslation('change_raid_duration'), ['edit_time', 'r' => $id, 'o' => 'm']);
}
// Get raid times.
-$raid = get_raid($data['id']);
+$raid = get_raid($id);
// Get raid level.
$raid_level = $raid['level'];
-$const = 'SHARE_CHATS_LEVEL_' . $raid_level;
-$const_chats = $config->{$const};
-
-// Debug.
-//debug_log($const,'CONSTANT NAME:');
-//debug_log(constant($const),'CONSTANT VALUE:');
-
-// Special sharing keys for raid level?
-if(!empty($const_chats)) {
- $chats = $const_chats;
- debug_log('Special sharing keys detected for raid level ' . $raid_level);
-} else {
- $chats = '';
-}
-if($raid['event']!==NULL) {
- if($raid['event_note']==NULL) {
- $event_button_text = getTranslation("event_note_add");
- }else {
- $event_button_text = getTranslation("event_note_edit");
- }
- $keys_edit_event_note = [
- [
- [
- 'text' => $event_button_text,
- 'callback_data' => $id . ':edit_event_note:0'
- ]
- ]
- ];
- $keys = array_merge($keys, $keys_edit_event_note);
+if($raid['event'] !== NULL) {
+ $event_button_text = ($raid['event_note'] == NULL) ? getTranslation("event_note_add") : getTranslation("event_note_edit");
+ $keys[][] = button($event_button_text, ['edit_event_note', 'r' => $id, 'm' => 'e']);
}
// Add keys to share.
-$keys_share = share_keys($id, 'raid_share', $update, $chats);
+$keys_share = share_keys($id, 'raid_share', $update, $raid_level);
$keys = array_merge($keys, $keys_share);
// Build message string.
$msg = '';
$msg .= getTranslation('raid_saved') . CR;
-$msg .= show_raid_poll_small($raid, false) . CR;
+$msg .= show_raid_poll_small($raid) . CR;
// User_id tag.
$user_id_tag = '#' . $update['callback_query']['from']['id'];
// Gym Name
-if(!empty($raid['gym_name']) && ($raid['gym_name'] != $user_id_tag)) {
-$msg .= getTranslation('set_gym_team') . CR2;
-} else {
- $msg .= getTranslation('set_gym_name_and_team') . CR2;
- $msg .= getTranslation('set_gym_name_command') . CR;
+if(!empty($raid['gym_name']) && ($raid['gym_name'] == $user_id_tag)) {
+ $msg .= getTranslation('set_gym_name_and_team') . CR2;
+ $msg .= getTranslation('set_gym_name_command') . CR;
}
-$msg .= getTranslation('set_gym_team_command');
// Build callback message string.
-if($arg == 0) {
- $callback_response = 'OK';
-}else {
- $callback_response = getTranslation('end_time') . ' ' . $data['arg'] . ' ' . getTranslation('minutes');
-}
+$callback_response = 'OK';
// Answer callback.
$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
@@ -174,6 +82,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/edit_scheduled_entry.php b/mods/edit_scheduled_entry.php
new file mode 100644
index 00000000..6ef5e98d
--- /dev/null
+++ b/mods/edit_scheduled_entry.php
@@ -0,0 +1,70 @@
+accessCheck('pokedex');
+$id = $data['i'];
+
+$query = my_query('SELECT pokedex_id, pokemon_form_id, date_start, date_end, raid_level, disabled FROM raid_bosses WHERE id = ? LIMIT 1', [$id]);
+$pokemon = $query->fetch();
+if(isset($data['s']) && $data['s'] == 1) {
+ my_query('UPDATE raid_bosses SET disabled = NOT disabled WHERE id = ?', [$id]);
+ $pokemon['disabled'] = ($pokemon['disabled'] == 1) ? 0 : 1;
+}
+if(isset($data['s']) && $data['s'] == 2) {
+ $msg = getTranslation('delete_scheduled_confirmation') . CR . CR;
+ $msg .= $pokemon['date_start'] . ' - ' . $pokemon['date_end'] . ':' . CR;
+ $msg .= getTranslation($pokemon['raid_level'] . 'stars') . ': ';
+ $msg .= get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id']) . CR;
+ $msg .= '' . ($pokemon['disabled'] ? getTranslation('disabled') : getTranslation('enabled')) .'';
+ $keys[0][0] = button(getTranslation('yes'), ['edit_scheduled_entry', 'i' => $id, 's' => 3]);
+ $keys[0][1] = button(getTranslation('no'), ['edit_scheduled_entry', 'i' => $id]);
+ // Build callback message string.
+ $callback_response = 'OK';
+
+ // Telegram JSON array.
+ $tg_json = array();
+
+ // Answer callback.
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
+
+ // Edit message.
+ $tg_json[] = edit_message($update, $msg, $keys, false, true);
+
+ // Telegram multicurl request.
+ curl_json_multi_request($tg_json);
+ exit();
+}
+if(isset($data['s']) && $data['s'] == 3) {
+ my_query('DELETE FROM raid_bosses WHERE id = ?', [$id]);
+ include(ROOT_PATH . '/mods/pokedex_list_raids.php');
+ exit();
+}
+$msg = getTranslation('edit_scheduled_entry') . ':' . CR . CR;
+$msg .= EMOJI_CLOCK . SP . $pokemon['date_start'] . ' - ' . $pokemon['date_end'] . CR;
+$msg .= getTranslation($pokemon['raid_level'] . 'stars') . ': ';
+$msg .= get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id']) . CR;
+$msg .= '' . ($pokemon['disabled'] ? getTranslation('disabled') : getTranslation('enabled')) .'';
+
+$keys[0][] = button(
+ ($pokemon['disabled'] ? getTranslation('enable') : getTranslation('disable')),
+ ['edit_scheduled_entry', 'i' => $id, 's' => 1]
+);
+$keys[1][] = button(getTranslation('delete'), ['edit_scheduled_entry', 'i' => $id, 's' => 2]);
+$keys[2][] = button(getTranslation('back'), 'pokedex_list_raids');
+
+// Build callback message string.
+$callback_response = 'OK';
+
+// Telegram JSON array.
+$tg_json = array();
+
+// Answer callback.
+$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
+
+// Edit message.
+$tg_json[] = edit_message($update, $msg, $keys, false, true);
+
+// Telegram multicurl request.
+curl_json_multi_request($tg_json);
diff --git a/mods/edit_starttime.php b/mods/edit_starttime.php
index 8de3c303..f573c0bf 100644
--- a/mods/edit_starttime.php
+++ b/mods/edit_starttime.php
@@ -7,174 +7,145 @@
//debug_log($data);
// Check access.
-bot_access_check($update, 'create');
+$botUser->accessCheck('create');
// Get the argument.
-$arg_data = explode(",", $data['arg']);
-$event_id = $arg_data[0];
-$raid_level = $arg_data[1];
-$pokemon_id = $arg_data[2];
-$arg = "";
-// Check for options.
-if (isset($arg_data[3]))
-{
- // Switch time display ( min / clock )
- $arg = $arg_data[3];
-}
+$event_id = $data['e'] ?? NULL;
+$raid_level = $data['rl'];
+$arg = $data['o'] ?? '';
+
// Set the id.
-$gym_id_plus_letter = $data['id'];
-$gym_id = explode(',', $data['id'])[0];
+$gym_id = $data['g'];
// Are we creating an event?
-if($event_id != 'N') {
- // Init empty keys array.
- $keys = [];
-
- // Current time from the user
- // We let the user pick the raid date and time and convert to UTC afterwards in edit_date.php
- $tz = $config->TIMEZONE;
- $today = new DateTimeImmutable('now', new DateTimeZone($tz));
-
- // Next 14 days.
- for ($d = 0; $d <= 14; $d = $d + 1) {
- // Add day to today.
- $today_plus_d = $today->add(new DateInterval("P".$d."D"));
-
- // Format date, e.g 14 April 2019
- $date_tz = $today_plus_d->format('Y-m-d');
- $text_split = explode('-', $date_tz);
- $text_day = $text_split[2];
- $text_month = getTranslation('month_' . $text_split[1]);
- $text_year = $text_split[0];
-
- // Add keys.
- $cb_date = $today_plus_d->format('Y-m-d');
- $keys[] = array(
- 'text' => $text_day . SP . $text_month . SP . $text_year,
- 'callback_data' => $gym_id_plus_letter . ':edit_date:' . $event_id . ',' . $raid_level . ',' . $pokemon_id . ',' . $cb_date
- );
- }
-
- // Get the inline key array.
- $keys = inline_key_array($keys, 2);
+if($event_id != NULL or $raid_level == 9) {
+ // Init empty keys array.
+ $keys = [];
+
+ // Current time from the user
+ // We let the user pick the raid date and time and convert to UTC afterwards in edit_date.php
+ $tz = $config->TIMEZONE;
+ $today = new DateTimeImmutable('now', new DateTimeZone($tz));
+
+ // Create date buttons. Two days for Elite Raids, 15 days for EX raids.
+ $days = ($raid_level == 9) ? 1 : 14;
+ unset($data['o']);
+ $buttonData = $data;
+ $buttonData[0] = 'edit_date';
+ // Drop these from callback_data string, these are no longer needed
+ unset($buttonData['fl']);
+ unset($buttonData['ga']);
+ for ($d = 0; $d <= $days; $d++) {
+ // Add day to today.
+ $today_plus_d = $today->add(new DateInterval("P".$d."D"));
+
+ // Format date, e.g 14 April 2019
+ $date_tz = $today_plus_d->format('Ymd');
+ $text_day = $today_plus_d->format('d');
+ $text_month = getTranslation('month_' . $today_plus_d->format('m'));
+ $text_year = $today_plus_d->format('Y');
+
+ // Add keys.
+ $buttonData['t'] = $date_tz;
+ $keys[] = button($text_day . SP . $text_month . SP . $text_year, $buttonData);
+ }
+
+ // Get the inline key array.
+ $keys = inline_key_array($keys, 2);
// Not creating an event
} else {
- if ($arg != "min" && $arg != "clock") {
- // Get default raid duration style from config
- if ($config->RAID_DURATION_CLOCK_STYLE) {
- $arg = "clock";
- } else {
- $arg = "min";
- }
- }
-
- // Init empty keys array.
- $keys = [];
-
- // Now
- $now = utcnow();
-
- if ($arg == "min") {
- // Set switch view.
- $switch_text = getTranslation('raid_starts_when_clocktime_view');
- $switch_view = "clock";
- $key_count = 5;
-
- for ($i = 1; $i <= $config->RAID_EGG_DURATION; $i = $i + 1) {
- // Create new DateTime object, add minutes and convert back to string.
- $now_plus_i = new DateTime($now, new DateTimeZone('UTC'));
- $now_plus_i->add(new DateInterval('PT'.$i.'M'));
- $now_plus_i = $now_plus_i->format("Y-m-d H:i:s");
- // Create the keys.
- $keys[] = array(
- // Just show the time, no text - not everyone has a phone or tablet with a large screen...
- 'text' => floor($i / 60) . ':' . str_pad($i % 60, 2, '0', STR_PAD_LEFT),
- 'callback_data' => $gym_id_plus_letter . ':edit_time:' . $event_id . ',' . $raid_level . ',' . $pokemon_id . ',' . utctime($now_plus_i,"H-i")
- );
- }
+ if ($arg != "min" && $arg != "clock") {
+ // Get default raid duration style from config
+ if ($config->RAID_DURATION_CLOCK_STYLE) {
+ $arg = "clock";
} else {
- // Set switch view.
- $switch_text = getTranslation('raid_starts_when_minutes_view');
- $switch_view = "min";
- // Small screen fix
- $key_count = 4;
-
- for ($i = 1; $i <= $config->RAID_EGG_DURATION; $i = $i + 1) {
- // Create new DateTime object, add minutes and convert back to string.
- $now_plus_i = new DateTime($now, new DateTimeZone('UTC'));
- $now_plus_i->add(new DateInterval('PT'.$i.'M'));
- $now_plus_i = $now_plus_i->format("Y-m-d H:i:s");
- // Create the keys.
- $keys[] = array(
- // Just show the time, no text - not everyone has a phone or tablet with a large screen...
- 'text' => dt2time($now_plus_i),
- 'callback_data' => $gym_id_plus_letter . ':edit_time:' . $event_id . ',' . $raid_level . ',' . $pokemon_id . ',' . utctime($now_plus_i,"H-i")
- );
- }
+ $arg = "min";
}
+ }
+
+ // Init empty keys array.
+ $keys = [];
+
+ // Now
+ $now = utcnow();
+
+ // Copy received callbackData to new variable that we can edit
+ $buttonData = $data;
+ $buttonData[0] = 'edit_time';
+ if ($arg == "min") {
+ // Set switch view.
+ $switch_text = getTranslation('raid_starts_when_clocktime_view');
+ $switch_view = "clock";
+ $key_count = 5;
+
+ } else {
+ // Set switch view.
+ $switch_text = getTranslation('raid_starts_when_minutes_view');
+ $switch_view = "min";
+ // Small screen fix
+ $key_count = 4;
+ }
+ $now_plus_i = new DateTime($now, new DateTimeZone('UTC'));
+ for ($i = 1; $i <= $config->RAID_EGG_DURATION; $i = $i + 1) {
+ $now_plus_i->add(new DateInterval('PT1M'));
+ $buttonData['t'] = $now_plus_i->format("YmdHi");
+ if ($arg == 'min')
+ $buttonText = floor($i / 60) . ':' . str_pad($i % 60, 2, '0', STR_PAD_LEFT);
+ else
+ $buttonText = dt2time($now_plus_i->format('Y-m-d H:i:s'));
- // Get the inline key array.
- $keys = inline_key_array($keys, $key_count);
-
- // Init empty keys other options array.
- $keys_opt = [];
-
- // Raid already running
- $keys_opt[] = array(
- 'text' => getTranslation('is_raid_active'),
- 'callback_data' => $gym_id_plus_letter . ':edit_time:' . $event_id . ',' . $raid_level . ',' . $pokemon_id . ',' . utctime($now,"H-i").",more,0"
- );
-
- // Switch view: clocktime / minutes until start
- $keys_opt[] = array(
- 'text' => $switch_text,
- 'callback_data' => $gym_id_plus_letter . ':edit_starttime:' . $event_id . ',' . $raid_level . ',' . $pokemon_id . ',' . $switch_view
- );
-
- // Get the inline key array.
- $keys_opt = inline_key_array($keys_opt, 2);
-
- // Merge keys
- $keys = array_merge($keys, $keys_opt);
-
- // Write to log.
- debug_log($keys);
+ // Create the keys.
+ $keys[] = button($buttonText, $buttonData);
+ }
+
+ // Get the inline key array.
+ $keys = inline_key_array($keys, $key_count);
+
+ // Init empty keys other options array.
+ $keys_opt = [];
+ $keyData = $data;
+ $keyData[0] = 'edit_time';
+ $keyData['o'] = 'm';
+ $keyData['t'] = utctime($now,"YmdHi");
+ // Raid already running
+ $keys_opt[] = button(getTranslation('is_raid_active'), $keyData);
+ $keyData[0] = 'edit_starttime';
+ $keyData['o'] = $switch_view;
+ unset($keyData['t']);
+ // Switch view: clocktime / minutes until start
+ $keys_opt[] = button($switch_text, $keyData);
+
+ // Get the inline key array.
+ $keys_opt = inline_key_array($keys_opt, 2);
+
+ // Merge keys
+ $keys = array_merge($keys, $keys_opt);
+
+ // Write to log.
+ debug_log($keys);
}
// No keys found.
if (!$keys) {
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
+ // Create the keys.
+ $keys[][] = button(getTranslation('abort'), 'exit');
} else {
- // Back key id, action and arg
- $back_id = $gym_id_plus_letter;
- $back_action = 'edit_pokemon';
- $back_arg = $event_id . ',' . $raid_level;
-
- // Add navigation keys.
- $nav_keys = [];
- $nav_keys[] = universal_inner_key($nav_keys, $back_id, $back_action, $back_arg, getTranslation('back'));
- $nav_keys[] = universal_inner_key($nav_keys, $gym_id, 'exit', '2', getTranslation('abort'));
- $nav_keys = inline_key_array($nav_keys, 2);
-
- // Merge keys.
- $keys = array_merge($keys, $nav_keys);
+ $backData = $data;
+ $backData[0] = 'edit_pokemon';
+ // Add navigation keys.
+ $keys[] = [
+ button(getTranslation('back'), formatCallbackData($backData)),
+ button(getTranslation('abort'), 'exit')
+ ];
}
// Build callback message string.
if ($arg != "min" && $arg != "clock") {
- $callback_response = getTranslation('pokemon_saved');
+ $callback_response = getTranslation('pokemon_saved');
} else {
- $callback_response = getTranslation('raid_starts_when_view_changed');
+ $callback_response = getTranslation('raid_starts_when_view_changed');
}
// Telegram JSON array.
@@ -185,12 +156,12 @@
// Set the message.
if ($arg == 'min') {
- $msg = getTranslation('raid_starts_when_minutes');
+ $msg = getTranslation('raid_starts_when_minutes');
} else if ($event_id == EVENT_ID_EX) {
- $msg = getTranslation('raid_starts_when');
- $msg .= CR . CR . getTranslation('raid_select_date');
+ $msg = getTranslation('raid_starts_when');
+ $msg .= CR . CR . getTranslation('raid_select_date');
} else {
- $msg = getTranslation('raid_starts_when');
+ $msg = getTranslation('raid_starts_when');
}
// Edit the message.
@@ -198,6 +169,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/edit_time.php b/mods/edit_time.php
index a6bd203b..01a5ca98 100644
--- a/mods/edit_time.php
+++ b/mods/edit_time.php
@@ -1,56 +1,24 @@
accessCheck('create');
-// Count 3 means we received pokemon_table_id and starttime
-// Count 4 means we received pokemon_table_id, starttime and an optional argument
-// Count 5 means we received pokemon_table_id, starttime, optional argument and slot switch
-$arg_data = explode(',', $data['arg']);
-$count_arg = count($arg_data);
-$event_id = $arg_data[0];
-$raid_level = $arg_data[1];
-$opt_arg = 'new-raid';
-$slot_switch = 0;
-if($count_arg >= 4) {
- $pokemon_table_id = $arg_data[2];
- $starttime = $arg_data[3];
-}
-if($count_arg >= 5) {
- $opt_arg = $arg_data[4];
-}
-if($count_arg >= 6) {
- $slot_switch = $arg_data[5];
-}
-
-// Write to log.
-debug_log('count_id: ' . $count_id);
-debug_log('count_arg: ' . $count_arg);
-debug_log('opt_arg: ' . $opt_arg);
-debug_log('slot_switch: ' . $slot_switch);
+$raid_id = $data['r'] ?? 0;
+$gym_id = $data['g'] ?? 0;
+$event_id = $data['e'] ?? NULL;
+$raid_level = $data['rl'] ?? 0;
+$pokemon_table_id = $data['p'] ?? 0;
+$starttime = $data['t'] ?? 0;
+$opt_arg = $data['o'] ?? 'new-raid';
// Telegram JSON array.
$tg_json = array();
@@ -59,181 +27,147 @@
// raid_id is 0, means we did not create it yet
// gym_id is not 0, means we have a gym_id for creation
if ($raid_id == 0 && $gym_id != 0) {
- // Replace "-" with ":" to get proper time format
- debug_log('Formatting the raid time properly now.');
- $arg_time = str_replace('-', ':', $starttime);
-
- // Event Raid or normal/EX raid?
- if($event_id == 'X') {
- debug_log('Ex-Raid time :D ... Setting raid date to ' . $arg_time);
- $start_date_time = $arg_time;
- $duration = $config->RAID_DURATION;
- }elseif($event_id != 'N') {
- debug_log('Event time :D ... Setting raid date to ' . $arg_time);
- $start_date_time = $arg_time;
- $query = my_query("SELECT raid_duration FROM events WHERE id = '{$event_id}' LIMIT 1");
- $result = $query->fetch();
- $duration = $result['raid_duration'];
- } else {
- // Current date
- $current_date = date('Y-m-d', strtotime('now'));
- debug_log('Today is a raid day! Setting raid date to ' . $current_date);
- // Raid time
- $start_date_time = $current_date . ' ' . $arg_time . ':00';
- debug_log('Received the following time for the raid: ' . $start_date_time);
- $duration = $config->RAID_DURATION;
+ // Replace "-" with ":" to get proper time format
+ debug_log('Formatting the raid time properly now.');
+
+ // Date was received in format YearMonthDayHourMinute so we need to reformat it to datetime
+ $start_date_time = substr($starttime,0,4) . '-' . substr($starttime,4,2) . '-' . substr($starttime,6,2) . ' ' . substr($starttime,8,2) . ':' . substr($starttime,10,2) . ':00';
+ // Event raids
+ if($event_id != NULL) {
+ debug_log('Event time :D ... Setting raid date to ' . $start_date_time);
+ $query = my_query('SELECT raid_duration FROM events WHERE id = ? LIMIT 1', [$event_id]);
+ $result = $query->fetch();
+ $duration = $result['raid_duration'] == 0 ? $config->RAID_DURATION : $result['raid_duration'];
+ $egg_duration = $config->RAID_EGG_DURATION;
+
+ // Elite raids
+ }elseif($raid_level == 9) {
+ debug_log('Elite Raid time :D ... Setting raid date to ' . $start_date_time);
+ $duration = $config->RAID_DURATION_ELITE;
+ $egg_duration = $config->RAID_EGG_DURATION_ELITE;
+
+ // Normal raids
+ } else {
+ debug_log('Received the following time for the raid: ' . $start_date_time);
+ $duration = $config->RAID_DURATION;
+ $egg_duration = $config->RAID_EGG_DURATION;
+ }
+
+ // Check for duplicate raid
+ $duplicate_id = active_raid_duplication_check($gym_id);
+
+ // Tell user the raid already exists and exit!
+ // Unless we are creating an event raid
+ if($duplicate_id != 0 &&
+ !($event_id == EVENT_ID_EX && $botUser->accessCheck('ex-raids', true)) &&
+ !($event_id != EVENT_ID_EX && $event_id != NULL && $botUser->accessCheck('event-raids', true))
+ ) {
+ $keys = [];
+ $raid_id = $duplicate_id;
+ $raid = get_raid($raid_id);
+ $msg = EMOJI_WARN . SP . getTranslation('raid_already_exists') . SP . EMOJI_WARN . CR . show_raid_poll_small($raid);
+
+ $keys = share_keys($raid_id, 'raid_share', $update, $raid['level']);
+
+ // Add keys for sharing the raid.
+ if(!empty($keys)) {
+ // Exit key
+ $keys[][] = button(getTranslation('abort'), 'exit');
}
- // Check for duplicate raid
- $duplicate_id = 0;
- if($raid_id == 0) {
- $duplicate_id = active_raid_duplication_check($gym_id);
- }
-
- // Continue with raid creation
- if($duplicate_id == 0) {
- // Now.
- $now = utcnow();
-
- $pokemon_id_formid = get_pokemon_by_table_id($pokemon_table_id);
-
- // Saving event info to db. N = null
- $event = (($event_id == "N") ? "NULL" : (($event_id=="X") ? EVENT_ID_EX : $event_id ));
- debug_log("Event: ".$event);
- debug_log("Event-id: ".$event_id);
- debug_log("Raid level: ".$raid_level);
- debug_log("Pokemon: ".$pokemon_id_formid['pokedex_id']."-".$pokemon_id_formid['pokemon_form_id']);
-
- // Create raid in database.
- $rs = my_query(
- "
- INSERT INTO raids
- SET user_id = {$update['callback_query']['from']['id']},
- pokemon = '{$pokemon_id_formid['pokedex_id']}',
- pokemon_form = '{$pokemon_id_formid['pokemon_form_id']}',
- start_time = '{$start_date_time}',
- spawn = DATE_SUB(start_time, INTERVAL ".$config->RAID_EGG_DURATION." MINUTE),
- end_time = DATE_ADD(start_time, INTERVAL {$duration} MINUTE),
- gym_id = '{$gym_id}',
- level = '{$raid_level}',
- event = {$event}
- "
- );
-
- // Get last insert id from db.
- $raid_id = $dbh->lastInsertId();
-
- // Write to log.
- debug_log('ID=' . $raid_id);
-
- // Tell user the raid already exists and exit!
- } else {
- $keys = [];
- $raid_id = $duplicate_id;
- $raid = get_raid($raid_id);
- $msg = EMOJI_WARN . SP . getTranslation('raid_already_exists') . SP . EMOJI_WARN . CR . show_raid_poll_small($raid);
-
- // Check if the raid was already shared.
- $rs_share = my_query(
- "
- SELECT COUNT(*) AS raid_count
- FROM cleanup
- WHERE raid_id = '{$raid_id}'
- "
- );
-
- $shared = $rs_share->fetch();
-
- // Add keys for sharing the raid.
- if($shared['raid_count'] == 0) {
- $keys = share_keys($raid_id, 'raid_share', $update);
-
- // Exit key
- $empty_exit_key = [];
- $key_exit = universal_key($empty_exit_key, '0', 'exit', '0', getTranslation('abort'));
- $keys = array_merge($keys, $key_exit);
- }
-
- // Answer callback.
- $tg_json[] = answerCallbackQuery($update['callback_query']['id'], getTranslation('raid_already_exists'), true);
-
- // Edit the message.
- $tg_json[] = edit_message($update, $msg, $keys, false, true);
-
- // Telegram multicurl request.
- curl_json_multi_request($tg_json);
-
- // Exit.
- exit();
- }
+ // Answer callback.
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], getTranslation('raid_already_exists'), true);
+
+ // Edit the message.
+ $tg_json[] = edit_message($update, $msg, $keys, false, true);
+
+ // Telegram multicurl request.
+ curl_json_multi_request($tg_json);
+
+ // Exit.
+ exit();
+ }
+ // Continue with raid creation
+ $pokemon_id_formid = get_pokemon_by_table_id($pokemon_table_id);
+
+ // Saving event info to db. N = null
+ debug_log("Event-id: ".$event_id);
+ debug_log("Raid level: ".$raid_level);
+ debug_log("Pokemon: ".$pokemon_id_formid['pokedex_id']."-".$pokemon_id_formid['pokemon_form_id']);
+
+ // Create raid in database.
+ $rs = my_query('
+ INSERT INTO raids
+ SET user_id = :userId,
+ pokemon = :pokemon,
+ pokemon_form = :pokemonForm,
+ start_time = :startTime,
+ spawn = DATE_SUB(start_time, INTERVAL ' . $egg_duration . ' MINUTE),
+ end_time = DATE_ADD(start_time, INTERVAL ' . $duration . ' MINUTE),
+ gym_id = :gymId,
+ level = :level,
+ event = :event
+ ', [
+ 'userId' => $update['callback_query']['from']['id'],
+ 'pokemon' => $pokemon_id_formid['pokedex_id'],
+ 'pokemonForm' => $pokemon_id_formid['pokemon_form_id'],
+ 'startTime' => $start_date_time,
+ 'gymId' => $gym_id,
+ 'level' => $raid_level,
+ 'event' => $event_id,
+ ]);
+
+ // Get last insert id from db.
+ $raid_id = $dbh->lastInsertId();
+
+ // Write to log.
+ debug_log('ID=' . $raid_id);
}
// Init empty keys array.
$keys = [];
// Raid pokemon duration short or 1 Minute / 5 minute time slots
-if($opt_arg == 'more') {
- // 1-minute selection
- $slotsize = 1;
-
- $slotmax = $config->RAID_DURATION;
-
- for ($i = $slotmax; $i >= 15; $i = $i - $slotsize) {
- // Create the keys.
- $keys[] = array(
- // Just show the time, no text - not everyone has a phone or tablet with a large screen...
- 'text' => floor($i / 60) . ':' . str_pad($i % 60, 2, '0', STR_PAD_LEFT),
- 'callback_data' => $raid_id . ':edit_save:' . $i
- );
- }
+if($opt_arg == 'm') {
+ // 1-minute selection
+ $slotsize = 1;
+
+ $slotmax = $config->RAID_DURATION;
+
+ for ($i = $slotmax; $i >= 15; $i = $i - $slotsize) {
+ // Create the keys.
+ $buttonText = floor($i / 60) . ':' . str_pad($i % 60, 2, '0', STR_PAD_LEFT);
+ $keys[] = button($buttonText, ['edit_save', 'd' => $i, 'r' => $raid_id]);
+ }
} else {
- debug_log('Comparing slot switch and argument for fast forward');
- if ($slot_switch == 0) {
- $raidduration = $config->RAID_DURATION;
-
- // Write to log.
- debug_log('Doing a fast forward now!');
- debug_log('Changing data array first...');
-
- // Reset data array
- $data = [];
- $data['id'] = $raid_id;
- $data['action'] = 'edit_save';
- $data['arg'] = $raidduration;
-
- // Write to log.
- debug_log($data, '* NEW DATA= ');
-
- // Set module path by sent action name.
- $module = ROOT_PATH . '/mods/edit_save.php';
-
- // Write module to log.
- debug_log($module);
-
- // Check if the module file exists.
- if (file_exists($module)) {
- // Dynamically include module file and exit.
- include_once($module);
- exit();
- }
- } else {
-
- // Use raid pokemon duration short.
- // Use normal raid duration.
- $keys[] = array(
- 'text' => '0:' . $config->RAID_DURATION,
- 'callback_data' => $raid_id . ':edit_save:' . $config->RAID_DURATION
- );
-
- // Button for more options.
- $keys[] = array(
- 'text' => getTranslation('expand'),
- 'callback_data' => $raid_id . ':edit_time:' . $pokemon_id . ',' . $start_time . ',more,' . $slot_switch
- );
-
-
- }
+ debug_log('Comparing slot switch and argument for fast forward');
+ $raidduration = $config->RAID_DURATION;
+
+ // Write to log.
+ debug_log('Doing a fast forward now!');
+ debug_log('Changing data array first...');
+
+ // Reset data array
+ $data = [];
+ $data['r'] = $raid_id;
+ $data[0] = 'edit_save';
+
+ // Write to log.
+ debug_log($data, '* NEW DATA= ');
+
+ // Set module path by sent action name.
+ $module = ROOT_PATH . '/mods/edit_save.php';
+
+ // Write module to log.
+ debug_log($module);
+
+ // Check if the module file exists.
+ if (file_exists($module)) {
+ // Dynamically include module file and exit.
+ include_once($module);
+ exit();
+ }
}
// Get the inline key array.
@@ -243,10 +177,10 @@
debug_log($keys);
// Build callback message string.
-if ($opt_arg != 'more' && $event_id == 'N') {
- $callback_response = getTranslation('start_date_time') . ' ' . $arg_time;
+if ($opt_arg != 'more' && $event_id == NULL) {
+ $callback_response = 'OK';
} else {
- $callback_response = getTranslation('raid_starts_when_view_changed');
+ $callback_response = getTranslation('raid_starts_when_view_changed');
}
// Answer callback.
@@ -257,6 +191,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/end_remote_raid.php b/mods/end_remote_raid.php
index 31c78416..bf25577e 100644
--- a/mods/end_remote_raid.php
+++ b/mods/end_remote_raid.php
@@ -1,14 +1,13 @@
diff --git a/mods/events.php b/mods/events.php
new file mode 100644
index 00000000..4da5ef71
--- /dev/null
+++ b/mods/events.php
@@ -0,0 +1,36 @@
+accessCheck('event-manage');
+
+$keys = [];
+$callback_response = 'OK';
+
+// Manage events
+$q = my_query('SELECT * FROM events');
+$msg = '' . getTranslation('events_manage') . '' . CR;
+foreach($q->fetchAll() as $event) {
+ if($event['id'] == EVENT_ID_EX) $event['name'] = getTranslation('Xstars');
+ if(empty($event['description'])) $event['description'] = '' . getTranslation('events_no_description') . '';
+ $msg .= '' . $event['name'] . '' . CR;
+ $msg .= $event['description'] . CR . CR;
+ $keys[][] = button($event['name'], ['events_manage', 'e' => $event['id']]);
+}
+$keys[][] = button(getTranslation('done'), ['exit', 'd' => '1']);
+
+$tg_json = [];
+
+// Answer callback.
+$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
+
+// Edit the message.
+$tg_json[] = edit_message($update, $msg, $keys, false, true);
+
+// Telegram multicurl request.
+curl_json_multi_request($tg_json);
diff --git a/mods/events_add.php b/mods/events_add.php
new file mode 100644
index 00000000..c10d61e6
--- /dev/null
+++ b/mods/events_add.php
@@ -0,0 +1,60 @@
+accessCheck('event-manage');
+
+$abort = $data['a'] ?? 0;
+
+$keys = [];
+$callback_response = 'OK';
+$userId = $update['callback_query']['from']['id'] ?? $update['message']['from']['id'];
+
+if(isset($modifiers)) {
+ $value = htmlspecialchars(trim($update['message']['text']));
+ my_query('INSERT INTO events SET name=?, description=""',[$value]);
+ $eventId = $dbh->lastInsertId();
+ $callback_response = getTranslation('done');
+ editMessageText($modifiers['old_message_id'], getTranslation('events_created'), [], $userId);
+ $msg = '' . getTranslation('events_created') . '' . CR;
+ $msg .= $value;
+ $keys[][] = button(getTranslation('next'), ['events_manage', 'e' => $eventId]);
+}else {
+ if($abort == 0) {
+ // Add a new event
+ $msg = '' . getTranslation('events_create') . '' . CR;
+ $msg .= getTranslation('events_give_name') . ':';
+
+ $modifiers = json_encode(['old_message_id'=>$update['callback_query']['message']['message_id']]);
+ $userId = $update['callback_query']['from']['id'];
+
+ // Data for handling response from the user
+ my_query('INSERT INTO user_input SET user_id = ?, handler = \'events_add\', modifiers = ?', [$userId, $modifiers]);
+
+ $keys[][] = button(getTranslation('abort'), ['events_add', 'a' => 1]);
+ }elseif($abort == 1) {
+ my_query('DELETE FROM user_input WHERE user_id = ?', [$userId]);
+ answerCallbackQuery($update['callback_query']['id'], 'OK');
+ editMessageText($update['callback_query']['message']['message_id'], getTranslation('action_aborted'), [], $userId);
+ exit;
+ }
+}
+
+$tg_json = [];
+
+if(isset($update['callback_query'])) {
+ // Answer callback.
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
+ // Edit the message.
+ $tg_json[] = edit_message($update, $msg, $keys, false, true);
+}else {
+ $tg_json[] = send_message(create_chat_object([$update['message']['chat']['id']]), $msg, $keys, false, true);
+}
+
+// Telegram multicurl request.
+curl_json_multi_request($tg_json);
diff --git a/mods/events_manage.php b/mods/events_manage.php
new file mode 100644
index 00000000..97cb6906
--- /dev/null
+++ b/mods/events_manage.php
@@ -0,0 +1,194 @@
+accessCheck('event-manage');
+
+$columnSettings = [
+ 'vote_key_mode' => ['allowed' => [0,1], 'default' => 0, 'nullable' => false],
+ 'pokemon_title' => ['allowed' => [0,1,2], 'default' => 1, 'nullable' => false],
+ 'hide_raid_picture' => ['allowed' => [0,1], 'default' => 0, 'nullable' => false],
+ 'time_slots' => ['nullable' => true],
+ 'raid_duration' => ['nullable' => false],
+ 'poll_template' => ['nullable' => true],
+];
+
+$eventId = $data['e'] ?? false;
+$action = $data['a'] ?? false;
+$keys = [];
+$callback_response = 'OK';
+$userId = $update['callback_query']['from']['id'] ?? $update['message']['from']['id'];
+
+// Process user input
+if(isset($modifiers) && isset($modifiers['action'])) {
+ $value = htmlspecialchars(trim($update['message']['text']));
+ if($modifiers['action'] == 1) {
+ // User input is new event name
+ $column = 'name';
+ $action = 0;
+ }else if($modifiers['action'] == 2) {
+ // User input is new description
+ $column = 'description';
+ $action = 0;
+ }else if($modifiers['action'] == 3) {
+ // User input is raid poll settings
+ $column = $modifiers['column'];
+ // Validate input
+ if($columnSettings[$column]['nullable'] && strtolower($value) == 'null') {
+ $value = NULL;
+ }
+ if(in_array($column, ['vote_key_mode','time_slots','raid_duration','hide_raid_picture','pokemon_title']) && $value != NULL) {
+ $value = preg_replace('/\D/', '', $value);
+ if(isset($columnSettings[$column]['allowed']) && !in_array($value, $columnSettings[$column]['allowed'])) $value = $columnSettings[$column]['default'];
+ }elseif($column == 'poll_template' && $value != NULL) {
+ $rows = preg_split("/\r\n|\n|\r/", $value);
+ $inputArray = [];
+ $i = 0;
+ // Convert input into json array
+ foreach($rows as $row) {
+ $buttons = explode(',', $row);
+ foreach($buttons as $button) {
+ $button = trim($button);
+ if(in_array($button, ['alone', 'extra', 'extra_alien', 'remote', 'inv_plz', 'can_inv', 'ex_inv', 'teamlvl', 'time', 'pokemon', 'refresh', 'alarm', 'here', 'late', 'done', 'cancel'])) {
+ $inputArray[$i][] = $button;
+ }
+ }
+ $i++;
+ }
+ $value = (strtolower($value) == 'null' ? NULL : json_encode($inputArray));
+ }
+ $action = 3;
+ }
+ $eventId = $modifiers['eventId'];
+ my_query('UPDATE events SET ' . $column . ' = ? WHERE id=?', [$value, $eventId]);
+ $callback_response = getTranslation('done');
+ editMessageText($modifiers['old_message_id'], getTranslation('updated'), [], $userId);
+}
+
+$q = my_query('SELECT * FROM events where id = ?', [$eventId]);
+$event = $q->fetch();
+if($eventId == EVENT_ID_EX) {
+ $event['name'] = getTranslation('Xstars');
+}
+if(empty($event['description'])) $event['description'] = '' . getTranslation('events_no_description') . '';
+
+$msg = '' . getTranslation('events_manage') . '' . CR . CR;
+$msg .= '' . $event['name'] . '' . CR;
+$msg .= $event['description'] . CR . CR;
+
+if($action == 0 || $action == 'a') {
+ if($action == 'a') {
+ my_query('DELETE FROM user_input WHERE user_id=?', [$userId]);
+ $callback_response = getTranslation('action_aborted');
+ }
+ if($eventId != EVENT_ID_EX)
+ $keys[][] = button(getTranslation('events_edit_name'), ['events_manage', 'e' => $eventId, 'a' => 1]);
+ $keys[][] = button(getTranslation('events_edit_description'), ['events_manage', 'e' => $eventId, 'a' => 2]);
+ $keys[][] = button(getTranslation('events_edit_raid_poll'), ['events_manage', 'e' => $eventId, 'a' => 3]);
+ if($eventId != EVENT_ID_EX)
+ $keys[][] = button(getTranslation('events_delete'), ['events_manage', 'e' => $eventId, 'a' => 4]);
+
+ $keys[] = [
+ button(getTranslation('back'), 'events'),
+ button(getTranslation('done'), 'exit')
+ ];
+
+// Edit event name
+}else if($action == 1) {
+ $modifiers = json_encode(['old_message_id'=>$update['callback_query']['message']['message_id'],'action'=>1,'eventId'=>$eventId]);
+ my_query('INSERT INTO user_input SET user_id=?, handler=\'events_manage\', modifiers=?', [$userId, $modifiers]);
+
+ $msg .= '' . getTranslation('events_edit_name') . '' . CR;
+ $msg .= getTranslation('events_give_name') . ':' . CR;
+ $keys[][] = button(getTranslation('abort'), ['events_manage', 'e' => $eventId, 'a' => 'a']);
+
+// Edit event description
+}else if($action == 2) {
+ $modifiers = json_encode(['old_message_id'=>$update['callback_query']['message']['message_id'],'action'=>2,'eventId'=>$eventId]);
+ my_query('INSERT INTO user_input SET user_id=?, handler=\'events_manage\', modifiers=?', [$userId, $modifiers]);
+ $msg .= '' . getTranslation('events_edit_description') . '' . CR;
+ $msg .= getTranslation('events_give_description') . ':';
+ $keys[][] = button(getTranslation('abort'), ['events_manage', 'e' => $eventId, 'a' => 'a']);
+
+// Edt event raid poll settings
+}else if($action == 3) {
+ my_query('DELETE FROM user_input WHERE user_id=?', [$userId]);
+ $templateArray = ($event['poll_template'] == NULL) ? $config->RAID_POLL_UI_TEMPLATE : json_decode($event['poll_template'], true);
+ $event['poll_template'] = templateJsonToString($templateArray);
+ $printColumns = ['vote_key_mode','time_slots','raid_duration','hide_raid_picture','pokemon_title','poll_template'];
+
+ $msg .= 'https://pokemonraidbot.readthedocs.io/en/latest/config.html#event-raids' . CR;
+ $msg .= 'https://pokemonraidbot.readthedocs.io/en/latest/config.html#raid-poll-design-and-layout' . CR . CR;
+ foreach($printColumns as $column) {
+ $msg .= $column . ': ';
+ $msg .= ($column == 'poll_template' ? CR : '');
+ $msg .= '' . ($event[$column] === NULL ? 'NULL' : $event[$column]) . '' . CR;
+ $keys[][] = button($column, ['events_manage', 'e' => $eventId, 'a' => 'e', 'c' => $column]);
+ }
+ $keys[] = [
+ button(getTranslation('back'), ['events_manage', 'e' => $eventId, 'a' => 0]),
+ button(getTranslation('done'), ['exit', 'd' => 1]),
+ ];
+
+// Delete event confirmation
+}else if($action == 4) {
+ $msg .= '' . getTranslation('events_delete_confirmation') . '' . CR;
+ $keys[] = [
+ button(getTranslation('yes'), ['events_manage', 'e' => $eventId, 'a' => 'd']),
+ button(getTranslation('no'), ['events_manage', 'e' => $eventId, 'a' => 0]),
+ ];
+
+// Delete event
+}else if($action == 'd') {
+ if($eventId != EVENT_ID_EX) my_query('DELETE FROM events WHERE id=?', [$eventId]);
+ include(ROOT_PATH . '/mods/events.php');
+ exit;
+
+// Prompt for raid poll value editing
+}else if($action == 'e') {
+ $valueToEdit = $data['c'];
+ $modifiers = json_encode(['old_message_id'=>$update['callback_query']['message']['message_id'],'action'=>3,'column'=>$valueToEdit,'eventId'=>$eventId]);
+ my_query('INSERT INTO user_input SET user_id=?, handler=\'events_manage\', modifiers=?', [$userId, $modifiers]);
+
+ if($valueToEdit == 'poll_template') {
+ $templateArray = ($event['poll_template'] == NULL) ? $config->RAID_POLL_UI_TEMPLATE : json_decode($event['poll_template'], true);
+ $event['poll_template'] = templateJsonToString($templateArray);
+ }
+
+ $msg .= $valueToEdit . CR;
+ $msg .= getTranslation('old_value') . CR;
+ $msg .= '' . ($event[$valueToEdit] === NULL ? 'NULL' : $event[$valueToEdit]) . '' . CR . CR;
+ $msg .= getTranslation('new_value');
+ $keys[][] = button(getTranslation('back'), ['events_manage', 'e' => $eventId, 'a' => 3]);
+
+}
+
+$tg_json = [];
+
+if(isset($update['callback_query'])) {
+ // Answer callback.
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
+ // Edit the message.
+ $tg_json[] = edit_message($update, $msg, $keys, false, true);
+}else {
+ $tg_json[] = send_message(create_chat_object([$update['message']['chat']['id']]), $msg, $keys, false, true);
+}
+
+// Telegram multicurl request.
+curl_json_multi_request($tg_json);
+
+function templateJsonToString($templateArray) {
+ $templateString = '';
+ foreach($templateArray as $line) {
+ foreach($line as $button) {
+ $templateString .= $button . ',';
+ }
+ $templateString = rtrim($templateString, ',') . CR;
+ }
+ return $templateString;
+}
diff --git a/mods/exit.php b/mods/exit.php
index c1d5dee2..953e057a 100644
--- a/mods/exit.php
+++ b/mods/exit.php
@@ -8,9 +8,10 @@
// Set empty keys.
$keys = [];
+$arg = $data['d'] ?? 0;
// Build message string.
-$msg = ($data['arg'] == 1) ? (getTranslation('done') . '!') : (getTranslation('action_aborted'));
+$msg = ($arg == 1) ? (getTranslation('done') . '!') : (getTranslation('action_aborted'));
// Telegram JSON array.
$tg_json = array();
@@ -23,6 +24,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/getdb.php b/mods/getdb.php
index f2d80b19..03309505 100644
--- a/mods/getdb.php
+++ b/mods/getdb.php
@@ -1,388 +1,213 @@
$pokemon_name,
- 'pokemon_form_name'=>$form_name,
- 'pokemon_form_id'=>0,
- 'asset_suffix'=>0,
- 'shiny'=>0,
- 'min_cp'=>0,
- 'max_cp'=>0,
- 'min_weather_cp'=>0,
- 'max_weather_cp'=>0,
- 'type' => '',
- 'type2' => '',
- 'shiny'=>0,
- 'weather'=>0
- ];
- }
- $i = 0;
- $SQL = '';
- foreach($pokemon_array as $id => $forms) {
- $pokemon_id = $id;
- foreach($forms as $form=>$data) {
- // Check that data is set, if not the mon is probably not in the game yet and there's no point in having them in a broken state
- if(isset($data['weather']) && isset($data['min_cp']) && isset($data['max_cp']) && isset($data['min_weather_cp']) && isset($data['max_weather_cp'])) {
- $poke_form = $form;
-
- $poke_name = $data['pokemon_name'];
- $form_id = $data['pokemon_form_id'];
- $form_asset_suffix = $data['asset_suffix'];
- $poke_min_cp = $data['min_cp'];
- $poke_max_cp = $data['max_cp'];
- $poke_min_weather_cp = $data['min_weather_cp'];
- $poke_max_weather_cp = $data['max_weather_cp'];
- $poke_type = $data['type'];
- $poke_type2 = $data['type2'];
- $poke_weather = $data['weather'];
-
- if($pokemon_id == 150 && $data['pokemon_form_name']=="a") {
- // Because logic and consistency
- $poke_form = 'armored';
- }else {
- $poke_form = strtolower($data['pokemon_form_name']);
- }
- if($i==0) $i=1; else $SQL .= ",";
- $SQL .= PHP_EOL . "(\"${pokemon_id}\", \"${poke_name}\", \"${poke_form}\", \"${form_id}\", \"${form_asset_suffix}\", \"${poke_min_cp}\", \"${poke_max_cp}\", \"${poke_min_weather_cp}\", \"${poke_max_weather_cp}\", \"${poke_type}\", \"${poke_type2}\", \"${poke_weather}\")";
- }
- }
- }
- ## MySQL 8 compatible
- #$SQL = $PRE . $SQL . ' as new' . PHP_EOL;
- #$SQL .= 'ON DUPLICATE KEY UPDATE pokedex_id = new.pokedex_id, pokemon_name = new.pokemon_name, pokemon_form_name = new.pokemon_form_name,' . PHP_EOL;
- #$SQL .= 'pokemon_form_id = new.pokemon_form_id, asset_suffix = new.asset_suffix, min_cp = new.min_cp, max_cp = new.max_cp,' . PHP_EOL;
- #$SQL .= 'min_weather_cp = new.min_weather_cp, max_weather_cp = new.max_weather_cp, type = new.type, type2 = new.type2, weather = new.weather;';
- $SQL = $PRE . $SQL . PHP_EOL;
- $SQL .= 'ON DUPLICATE KEY UPDATE pokedex_id = VALUES(pokedex_id), pokemon_name = VALUES(pokemon_name), pokemon_form_name = VALUES(pokemon_form_name),' . PHP_EOL;
- $SQL .= 'pokemon_form_id = VALUES(pokemon_form_id), asset_suffix = VALUES(asset_suffix), min_cp = VALUES(min_cp),' . PHP_EOL;
- $SQL .= 'max_cp = VALUES(max_cp), min_weather_cp = VALUES(min_weather_cp), max_weather_cp = VALUES(max_weather_cp),' . PHP_EOL;
- $SQL .= 'type = VALUES(type), type2 = VALUES(type2), weather = VALUES(weather);' . PHP_EOL;
- try {
- $prep = $dbh->prepare($SQL);
- $prep->execute();
- } catch (Exception $e) {
- if(isset($update['message']['from']['id'])) $error = $e;
- }
- }
- }else {
- $error = 'Failed to write costume data to protos/costume.json';
- }
-} else {
- $error = 'Failed to get protos.';
+# We only have an update if the call came from TG
+if(!isset($update)){
+ $update = false;
}
-if(!$error) {
- $msg = 'Updated successfully!' . CR;
- $msg.= $prep->rowCount() . ' rows required updating!';
- // Sometimes Nia can push form id's a bit later than other stats, so the script may insert incomplete rows
- // This hopefully clears those faulty rows out when the complete data is received without effecting any actual data
- my_query('
- DELETE t1 FROM pokemon t1
- INNER JOIN pokemon t2
- WHERE
- t1.pokedex_id = t2.pokedex_id
- AND t1.pokemon_form_name = t2.pokemon_form_name
- AND t1.pokemon_form_name <> \'normal\'
- AND t1.pokemon_form_id = 0
- ');
- $callback_msg = 'OK!';
-}else {
- $msg = $error;
- info_log('Pokemon table update failed: ' . $error);
- $callback_msg = 'Error!';
+
+// Parse the game master data together with form ids into format we can use
+[$pokemon_array, $costume_data] = parse_master_data($game_master_url);
+if(!$pokemon_array) {
+ sendResults('Failed to open game master file.', $update, true);
}
-if(isset($update['callback_query']['id'])) {
- // Answer callback.
- $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_msg, true);
- // Edit the message.
- $tg_json[] = editMessageText($update['callback_query']['message']['message_id'], $msg, [], $update['callback_query']['message']['chat']['id'], false, true);
+// Save our core datasets to json files for further use
+if(!file_put_contents(ROOT_PATH.'/protos/costume.json', json_encode($costume_data, JSON_PRETTY_PRINT))) {
+ sendResults('Failed to write costume data to protos/costume.json', $update, true);
+}
- // Telegram multicurl request.
- curl_json_multi_request($tg_json);
+// Craft egg data
+$PRE = 'INSERT INTO `pokemon`' . PHP_EOL;
+$PRE .= '(pokedex_id, pokemon_name, pokemon_form_name, pokemon_form_id, min_cp, max_cp, min_weather_cp, max_weather_cp, type, type2, weather) VALUES';
+foreach(EGGS as $egg) {
+ $pokemon_id = $egg;
+ $pokemon_name = 'Level '. str_replace('999', '', $egg) .' Egg';
+ $pokemon_array[$pokemon_id]['normal'] = [
+ 'pokemon_name' => $pokemon_name,
+ 'pokemon_form_name' => 'normal',
+ 'pokemon_form_id' => 0,
+ 'shiny' => 0,
+ 'min_cp' => 0,
+ 'max_cp' => 0,
+ 'min_weather_cp' => 0,
+ 'max_weather_cp' => 0,
+ 'type' => '',
+ 'type2' => '',
+ 'weather' => 0,
+ ];
+}
- // Exit.
- $dbh = null;
+// Craft the rest of the pokemon data
+$i = 0;
+$dataSql = '';
+foreach($pokemon_array as $pokemon_id => $forms) {
+ foreach($forms as $form => $data) {
+ // Check that data is set, if not the mon is probably not in the game yet and there's no point in having them in a broken state
+ if(!isset($data['weather']) || !isset($data['min_cp']) || !isset($data['max_cp']) || !isset($data['min_weather_cp']) || !isset($data['max_weather_cp']) || !isset($data['pokemon_name'])) continue;
+ $insertData = [$pokemon_id, $data['pokemon_name'], $data['pokemon_form_name'], $data['pokemon_form_id'], $data['min_cp'], $data['max_cp'], $data['min_weather_cp'], $data['max_weather_cp'], $data['type'], $data['type2'], $data['weather']];
+ $dataSql .= PHP_EOL . '("' . implode('","', $insertData) . '"),';
+ }
+}
+## MySQL 8 compatible
+#$SQL = $PRE . $SQL . ' as new' . PHP_EOL;
+#$SQL .= 'ON DUPLICATE KEY UPDATE pokedex_id = new.pokedex_id, pokemon_name = new.pokemon_name, pokemon_form_name = new.pokemon_form_name,' . PHP_EOL;
+#$SQL .= 'pokemon_form_id = new.pokemon_form_id, min_cp = new.min_cp, max_cp = new.max_cp,' . PHP_EOL;
+#$SQL .= 'min_weather_cp = new.min_weather_cp, max_weather_cp = new.max_weather_cp, type = new.type, type2 = new.type2, weather = new.weather;';
+$SQL = $PRE . rtrim($dataSql, ',') . PHP_EOL;
+$SQL .= 'ON DUPLICATE KEY UPDATE pokedex_id = VALUES(pokedex_id), pokemon_name = VALUES(pokemon_name), pokemon_form_name = VALUES(pokemon_form_name),' . PHP_EOL;
+$SQL .= 'pokemon_form_id = VALUES(pokemon_form_id), min_cp = VALUES(min_cp),' . PHP_EOL;
+$SQL .= 'max_cp = VALUES(max_cp), min_weather_cp = VALUES(min_weather_cp), max_weather_cp = VALUES(max_weather_cp),' . PHP_EOL;
+$SQL .= 'type = VALUES(type), type2 = VALUES(type2), weather = VALUES(weather);' . PHP_EOL;
+try {
+ $prep = $dbh->prepare($SQL);
+ $prep->execute();
+} catch (Exception $e) {
+ sendResults($e, $update, true);
+}
+$msg = 'Updated successfully!' . CR;
+$msg.= $prep->rowCount() . ' rows required updating!';
+// Sometimes Nia can push form id's a bit later than other stats, so the script may insert incomplete rows
+// This hopefully clears those faulty rows out when the complete data is received without effecting any actual data
+my_query('
+ DELETE t1 FROM pokemon t1
+ INNER JOIN pokemon t2
+ WHERE
+ t1.pokedex_id = t2.pokedex_id
+ AND t1.pokemon_form_name = t2.pokemon_form_name
+ AND t1.pokemon_form_name <> \'normal\'
+ AND t1.pokemon_form_id = 0
+');
+sendResults($msg, $update);
+
+function sendResults($msg, $update, $error = false) {
+ if($error) {
+ info_log('Pokemon table update failed: ' . $msg);
+ }else if(!isset($update['callback_query']['id'])) {
+ info_log($msg);
exit();
+ }
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], (!$error) ? 'OK!' : 'Error!', true);
+ $tg_json[] = editMessageText($update['callback_query']['message']['message_id'], $msg, [], $update['callback_query']['message']['chat']['id'], false, true);
+ curl_json_multi_request($tg_json);
+ exit;
}
-
function calculate_cps($base_stats) {
- // CP = (Attack * Defense^0.5 * Stamina^0.5 * CP_Multiplier^2) / 10
- $cp_multiplier = array(20 => 0.5974 ,25 =>0.667934 );
- $min = floor((($base_stats['baseAttack']+10)*(($base_stats['baseDefense']+10)**0.5)*(($base_stats['baseStamina']+10)**0.5)*$cp_multiplier[20]**2)/10);
- $max = floor((($base_stats['baseAttack']+15)*(($base_stats['baseDefense']+15)**0.5)*(($base_stats['baseStamina']+15)**0.5)*$cp_multiplier[20]**2)/10);
- $min_weather = floor((($base_stats['baseAttack']+10)*(($base_stats['baseDefense']+10)**0.5)*(($base_stats['baseStamina']+10)**0.5)*$cp_multiplier[25]**2)/10);
- $max_weather = floor((($base_stats['baseAttack']+15)*(($base_stats['baseDefense']+15)**0.5)*(($base_stats['baseStamina']+15)**0.5)*$cp_multiplier[25]**2)/10);
- return [$min,$max,$min_weather,$max_weather];
-}
-
-function get_protos($proto_url) {
- //Parse the form ID's from pogoprotos
- if(!$proto_file = curl_get_contents($proto_url)) return false;
- $proto = preg_split('/\r\n|\r|\n/', $proto_file);
- $count = count($proto);
- $form_ids = $costume = array();
- $data_array = false;
- for($i=0;$i<$count;$i++) {
- $line = trim($proto[$i]);
- if($data_array != false) {
- $data = explode('=',str_replace(';','',$line));
- // End of pokemon data, no need to loop further
- if(trim($data[0]) == '}') {
- $data_array = false;
- if(count($form_ids) > 0 && count($costume) > 0) {
- // We found what we needed so we can stop looping through proto file and exit
- break;
- }
- }else if(count($data) == 2) {
- ${$data_array}[trim($data[0])] = trim($data[1]);
- }
- }else {
- if($line == 'enum Costume {') {
- $data_array = 'costume';
- }
- if($line == 'enum Form {') {
- $data_array = 'form_ids';
- }
- }
- }
- unset($proto);
- return [$form_ids, $costume];
+ // CP = (Attack * Defense^0.5 * Stamina^0.5 * CP_Multiplier^2) / 10
+ $cp_multiplier = array(20 => 0.5974, 25 => 0.667934);
+ $min = floor((($base_stats['attack']+10)*(($base_stats['defense']+10)**0.5)*(($base_stats['stamina']+10)**0.5)*$cp_multiplier[20]**2)/10);
+ $max = floor((($base_stats['attack']+15)*(($base_stats['defense']+15)**0.5)*(($base_stats['stamina']+15)**0.5)*$cp_multiplier[20]**2)/10);
+ $min_weather = floor((($base_stats['attack']+10)*(($base_stats['defense']+10)**0.5)*(($base_stats['stamina']+10)**0.5)*$cp_multiplier[25]**2)/10);
+ $max_weather = floor((($base_stats['attack']+15)*(($base_stats['defense']+15)**0.5)*(($base_stats['stamina']+15)**0.5)*$cp_multiplier[25]**2)/10);
+ return [$min,$max,$min_weather,$max_weather];
}
-function parse_master_into_pokemon_table($form_ids, $game_master_url) {
- // Set ID's for mega evolutions
- // Using negative to prevent mixup with actual form ID's
- // Collected from pogoprotos (hoping they won't change, so hard coding them here)
- $mega_ids = array('MEGA'=>-1,'MEGA_X'=>-2,'MEGA_Y'=>-3);
-
- $weatherboost_table = array(
- 'POKEMON_TYPE_BUG' => '3',
- 'POKEMON_TYPE_DARK' => '8',
- 'POKEMON_TYPE_DRAGON' => '6',
- 'POKEMON_TYPE_ELECTRIC' => '3',
- 'POKEMON_TYPE_FAIRY' => '5',
- 'POKEMON_TYPE_FIGHTING' => '5',
- 'POKEMON_TYPE_FIRE' => '12',
- 'POKEMON_TYPE_FLYING' => '6',
- 'POKEMON_TYPE_GHOST' => '8',
- 'POKEMON_TYPE_GRASS' => '12',
- 'POKEMON_TYPE_GROUND' => '12',
- 'POKEMON_TYPE_ICE' => '7',
- 'POKEMON_TYPE_NORMAL' => '4',
- 'POKEMON_TYPE_POISON' => '5',
- 'POKEMON_TYPE_PSYCHIC' => '6',
- 'POKEMON_TYPE_ROCK' => '4',
- 'POKEMON_TYPE_STEEL' => '7',
- 'POKEMON_TYPE_WATER' => '3'
- );
- if(!$master_file = curl_get_contents($game_master_url)) return false;
- $master = json_decode($master_file, true);
- foreach($master as $row) {
- $part = explode('_',$row['templateId']);
- $form_data = [];
- $pokemon_id = '';
- if(count($part)<2) continue;
- if($part[0] == 'FORMS' && $part[2] == 'POKEMON') {
- // Found Pokemon form data
-
- // Get pokemon ID
- $pokemon_id = ltrim(str_replace('V','',$part[1]),'0');
- unset($part[0]);
- unset($part[1]);
- unset($part[2]);
-
- // Pokemon name
- $pokemon_name = implode('_',$part);
- // Get pokemon forms
- if(!isset($row['data']['formSettings']['forms']) or empty($row['data']['formSettings']['forms'][0])) {
- $form_data[] = array('form'=>$pokemon_name.'_NORMAL');
- }else {
- $form_data = $row['data']['formSettings']['forms'];
- }
- foreach($form_data as $form) {
- $form_name = strtolower(str_replace($pokemon_name.'_','',$form['form']));
- if($form_name != 'purified' && $form_name != 'shadow') {
-
- // Nidoran
- $poke_name = ucfirst(strtolower(str_replace(['_FEMALE','_MALE'],['♀','♂'],$row['data']['formSettings']['pokemon'])));
- // Ho-oh
- $poke_name = str_replace('_','-',$poke_name);
-
- if(!isset($form_ids[$form['form']])) {
- $form_id = 0;
- }else {
- $form_id = $form_ids[$form['form']];
- }
- $form_asset_suffix = (isset($form['assetBundleValue']) ? $form['assetBundleValue'] : (isset($form['assetBundleSuffix'])?$form['assetBundleSuffix']:'00'));
-
- $pokemon_array[$pokemon_id][$form_name] = [ 'pokemon_name'=>$poke_name,
- 'pokemon_form_name'=>$form_name,
- 'pokemon_form_id'=>$form_id,
- 'asset_suffix'=>$form_asset_suffix
- ];
-
- }
- }
- }else if($part[0] == 'TEMPORARY' && $part[1] == 'EVOLUTION') {
- // Found Mega pokemon data
- // Get pokemon ID
- $pokemon_id = ltrim(str_replace('V','',$part[2]),'0');
- unset($part[0]);
- unset($part[1]);
- unset($part[2]);
- unset($part[3]);
-
- // Pokemon name
- $pokemon_name = implode("_",$part);
- $form_data = $row['data']['temporaryEvolutionSettings']['temporaryEvolutions'];
- foreach($form_data as $form) {
- // Nidoran
- $poke_name = ucfirst(strtolower(str_replace(["_FEMALE","_MALE"],["♀","♂"],$pokemon_name)));
- // Ho-oh
- $poke_name = str_replace("_","-",$poke_name);
-
- $form_name = str_replace("TEMP_EVOLUTION_","",$form['temporaryEvolutionId']);
- $form_asset_suffix = $form['assetBundleValue'];
- $form_id = $mega_ids[$form_name];
-
- $pokemon_array[$pokemon_id][$form_name] = [ "pokemon_name"=>$poke_name,
- "pokemon_form_name"=>$form_name,
- "pokemon_form_id"=>$form_id,
- "asset_suffix"=>$form_asset_suffix
- ];
- }
- }else if ($part[1] == "POKEMON" && $part[0][0] == "V" && isset($row['data']['pokemonSettings'])) {
- // Found Pokemon data
- $pokemon_id = (int)str_replace("V","",$part[0]);
- $form_name = str_replace($row['data']['pokemonSettings']['pokemonId']."_","",substr($row['data']['templateId'],14));
- if($form_name != 'PURIFIED' && $form_name != 'SHADOW' && $form_name != 'NORMAL'
- && isset($pokemon_array[$pokemon_id])
- && isset($row['data']['pokemonSettings']['stats']['baseAttack'])
- && isset($row['data']['pokemonSettings']['stats']['baseDefense'])
- && isset($row['data']['pokemonSettings']['stats']['baseStamina'])) {
- if($form_name == $row['data']['pokemonSettings']['pokemonId']) {
- $form_name = "normal";
- }else {
- $form_name = strtolower($form_name);
- }
- $CPs = calculate_cps($row['data']['pokemonSettings']['stats']);
- $min_cp = $CPs[0];
- $max_cp = $CPs[1];
- $min_weather_cp = $CPs[2];
- $max_weather_cp = $CPs[3];
-
- $type = strtolower(str_replace('POKEMON_TYPE_','', $row['data']['pokemonSettings']['type']));
- $type2 = '';
-
- $weather = $weatherboost_table[$row['data']['pokemonSettings']['type']];
- if(isset($row['data']['pokemonSettings']['type2'])) {
- $type2 = strtolower(str_replace('POKEMON_TYPE_','', $row['data']['pokemonSettings']['type2']));
-
- # Add type2 weather boost only if there is a second type and it's not the same weather as the first type!
- if($weatherboost_table[$row['data']['pokemonSettings']['type2']] != $weatherboost_table[$row['data']['pokemonSettings']['type']]) {
- $weather .= $weatherboost_table[$row['data']['pokemonSettings']['type2']];
- }
- }
- if(isset($pokemon_array[$pokemon_id][$form_name])) {
- $pokemon_array[$pokemon_id][$form_name]['min_cp'] = $min_cp;
- $pokemon_array[$pokemon_id][$form_name]['max_cp'] = $max_cp;
- $pokemon_array[$pokemon_id][$form_name]['min_weather_cp'] = $min_weather_cp;
- $pokemon_array[$pokemon_id][$form_name]['max_weather_cp'] = $max_weather_cp;
- $pokemon_array[$pokemon_id][$form_name]['weather'] = $weather;
- $pokemon_array[$pokemon_id][$form_name]['type'] = $type;
- $pokemon_array[$pokemon_id][$form_name]['type2'] = $type2;
- }else {
- // Fill data for Pokemon that have form data but no stats for forms specifically
- foreach($pokemon_array[$pokemon_id] as $form=>$data) {
- $pokemon_array[$pokemon_id][$form]['min_cp'] = $min_cp;
- $pokemon_array[$pokemon_id][$form]['max_cp'] = $max_cp;
- $pokemon_array[$pokemon_id][$form]['min_weather_cp'] = $min_weather_cp;
- $pokemon_array[$pokemon_id][$form]['max_weather_cp'] = $max_weather_cp;
- $pokemon_array[$pokemon_id][$form]['weather'] = $weather;
- $pokemon_array[$pokemon_id][$form]['type'] = $type;
- $pokemon_array[$pokemon_id][$form]['type2'] = $type2;
- }
- }
- if(isset($row['data']['pokemonSettings']['tempEvoOverrides'])) {
- foreach($row['data']['pokemonSettings']['tempEvoOverrides'] as $temp_evolution) {
- if(isset($temp_evolution['tempEvoId'])) {
- $form_name = str_replace('TEMP_EVOLUTION_','',$temp_evolution['tempEvoId']);
- // We only override the types for megas
- // weather info is used to display boosts for caught mons, which often are different from mega's typing
- $typeOverride = strtolower(str_replace('POKEMON_TYPE_','', $temp_evolution['typeOverride1']));
- $typeOverride2 = '';
-
- if(isset($temp_evolution['typeOverride2'])) {
- $typeOverride2 = strtolower(str_replace('POKEMON_TYPE_','', $temp_evolution['typeOverride2']));
- }
- $pokemon_array[$pokemon_id][$form_name]['min_cp'] = $min_cp;
- $pokemon_array[$pokemon_id][$form_name]['max_cp'] = $max_cp;
- $pokemon_array[$pokemon_id][$form_name]['min_weather_cp'] = $min_weather_cp;
- $pokemon_array[$pokemon_id][$form_name]['max_weather_cp'] = $max_weather_cp;
- $pokemon_array[$pokemon_id][$form_name]['weather'] = $weather;
- $pokemon_array[$pokemon_id][$form_name]['type'] = $typeOverride;
- $pokemon_array[$pokemon_id][$form_name]['type2'] = $typeOverride2;
- }
- }
- }
- }
- }
+function parse_master_data($game_master_url) {
+ // Set ID's for mega evolutions
+ // Using negative to prevent mixup with actual form ID's
+ // Collected from pogoprotos (hoping they won't change, so hard coding them here)
+ $mega_names = array(-1 => 'mega', -2 => 'mega_x', -3 => 'mega_y', -4 => 'primal');
+ $pokemon_array = [];
+ $weatherboost_table = array(
+ 1 => '4',
+ 2 => '5',
+ 3 => '6',
+ 4 => '5',
+ 5 => '12',
+ 6 => '4',
+ 7 => '3',
+ 8 => '8',
+ 9 => '7',
+ 10 => '12',
+ 11 => '3',
+ 12 => '12',
+ 13 => '3',
+ 14 => '6',
+ 15 => '7',
+ 16 => '6',
+ 17 => '8',
+ 18 => '5',
+ );
+ if(!$master_file = curl_get_contents($game_master_url)) return false;
+ $master = json_decode($master_file, true);
+ foreach($master['pokemon'] as $row) {
+ $pokemon_id = $row['pokedexId'];
+ $pokemon_name = $row['name'];
+ if(!isset($row['stats']['attack']) || !isset($row['stats']['defense']) || !isset($row['stats']['stamina'])) {
+ continue;
}
- return $pokemon_array;
-}
-
-// Fetch the latest version of proto files.
-// vbase.proto has only the latest fully deobfuscated protos,
-// but we only need the latest form and costume data which is available in the partially obfuscated protofiles
-function getProtoURL() {
- $repo_owner = 'Furtif';
- $repo_name = 'POGOProtos';
- $content_dir = 'base';
-
- $repo_content = 'https://api.github.com/repos/' . $repo_owner . '/' . $repo_name . '/contents/' . $content_dir;
- // Git tree lookup
- $tree = curl_get_contents($repo_content);
- $leaf = json_decode($tree, true);
- // Detect rate-limiting and die gracefully
- if(is_array($leaf) && in_array('message', $leaf)) {
- die('Failed to download repo index: ' . $leaf['message']);
+ $pokemon_types = array_keys($row['types']);
+ $weather = $weatherboost_table[$pokemon_types[0]];
+ if(!isset($pokemon_types[1]))
+ $pokemon_types[1] = '';
+ elseif($weatherboost_table[$pokemon_types[0]] != $weatherboost_table[$pokemon_types[1]])
+ $weather .= $weatherboost_table[$pokemon_types[1]];
+ foreach($row['forms'] as $formData) {
+ if($formData['name'] == 'Shadow' || $formData['name'] == 'Purified') continue;
+ if($formData['name'] == 'Normal') {
+ $pokemon_array[$pokemon_id]['protoName'] = str_replace('_NORMAL', '', $formData['proto']);
+ $form_name = 'normal';
+ }else {
+ if(isset($pokemon_array[$pokemon_id]['protoName']))
+ $form_name = str_replace($pokemon_array[$pokemon_id]['protoName'].'_', '', $formData['proto']);
+ else
+ $form_name = ($formData['proto'] == 'FORM_UNSET') ? 'normal' : $formData['proto'];
+ }
+ [$min_cp, $max_cp, $min_weather_cp, $max_weather_cp] = (isset($formData['stats'])) ? calculate_cps($formData['stats']) : calculate_cps($row['stats']);
+ $form_id = $formData['form'];
+ $pokemon_array[$pokemon_id][$form_name] = [
+ 'pokemon_name' => $pokemon_name,
+ 'pokemon_form_name' => $form_name,
+ 'pokemon_form_id' => $form_id,
+ 'min_cp' => $min_cp,
+ 'max_cp' => $max_cp,
+ 'min_weather_cp' => $min_weather_cp,
+ 'max_weather_cp' => $max_weather_cp,
+ 'weather' => $weather,
+ 'type' => $pokemon_types[0],
+ 'type2' => $pokemon_types[1],
+ ];
}
- $highest = 0;
- $url = '';
- foreach($leaf as $l) {
- $version = trim(preg_replace('/\D/', '', substr($l['name'], 3)));
- if($version > $highest) {
- $split = explode(".",$l['name']);
- // Only allow fully or partially deobfuscated iterations of the proto file
- if($split[2] == 'x' or $split[2] == 'x_p_obf') {
- $highest = $version;
- $url = $l['download_url'];
- }
- }
+ if(!isset($row['tempEvolutions'])) continue;
+ foreach($row['tempEvolutions'] as $tempData) {
+ if(isset($tempData['unreleased']) && $tempData['unreleased']) continue;
+ $form_id = -$tempData['tempEvoId'];
+ $form_name = $mega_names[$form_id];
+ if(isset($tempData['types'])) {
+ $pokemon_types = array_keys($tempData['types']);
+ $weather = $weatherboost_table[$pokemon_types[0]];
+ if(!isset($pokemon_types[1]))
+ $pokemon_types[1] = '';
+ elseif($weatherboost_table[$pokemon_types[0]] != $weatherboost_table[$pokemon_types[1]])
+ $weather .= $weatherboost_table[$pokemon_types[1]];
+ }
+ [$min_cp, $max_cp, $min_weather_cp, $max_weather_cp] = calculate_cps($row['stats']);
+ $pokemon_array[$pokemon_id][$form_name] = [
+ 'pokemon_name' => $pokemon_name,
+ 'pokemon_form_name' => $form_name,
+ 'pokemon_form_id' => $form_id,
+ 'min_cp' => $min_cp,
+ 'max_cp' => $max_cp,
+ 'min_weather_cp' => $min_weather_cp,
+ 'max_weather_cp' => $max_weather_cp,
+ 'weather' => $weather,
+ 'type' => $pokemon_types[0],
+ 'type2' => $pokemon_types[1],
+ ];
}
- return $url;
+ }
+ $costume_data = [];
+ foreach($master['costumes'] as $costume) {
+ $costume_data[$costume['proto']] = $costume['id'];
+ }
+ return [$pokemon_array, $costume_data];
}
-
-?>
diff --git a/mods/gymMenu.php b/mods/gymMenu.php
new file mode 100644
index 00000000..0562be60
--- /dev/null
+++ b/mods/gymMenu.php
@@ -0,0 +1,29 @@
+accessCheck('gym-add');
+
+function insertUserInput($userId, $stage, $oldMessageId, $gymId = 0) {
+ global $dbh;
+ // Create an entry to user_input table
+ $modifierArray = ['stage' => $stage + 1, 'oldMessageId' => $oldMessageId];
+ if($gymId !== 0) $modifierArray['gymId'] = $gymId;
+ $modifiers = json_encode($modifierArray);
+ $handler = 'gym_create';
+
+ my_query('INSERT INTO user_input SET user_id = :userId, modifiers = :modifiers, handler = :handler', [':userId' => $userId, ':modifiers' => $modifiers, ':handler' => $handler]);
+ return $dbh->lastInsertId();
+}
+function respondToUser($userId, $oldMessageId = 0, $editMsg = '', $editKeys = [], $sendMsg = '', $sendKeys = [], $callbackMsg = '', $callbackId = 0) {
+ if($callbackId != 0) answerCallbackQuery($callbackId, $callbackMsg);
+ if($editMsg != '') editMessageText($oldMessageId, $editMsg, $editKeys, $userId, ['disable_web_page_preview' => 'true']);
+ if($sendMsg != '') send_message(create_chat_object([$userId]), $sendMsg, $sendKeys, ['disable_web_page_preview' => 'true']);
+}
+// Set keys.
+$keys = [];
+
+$stage = $modifiers['stage'] ?? 1;
+
+if(isset($data['a'])) {
+ my_query('DELETE FROM user_input WHERE id = :deleteId', ['deleteId' => $data['a']]);
+ $msg = getTranslation('action_aborted');
+ editMessageText($update['callback_query']['message']['message_id'], $msg, [], $update['callback_query']['from']['id']);
+ exit;
+}
+if($stage == 1) {
+ $callbackResponse = getTranslation('here_we_go');
+ $callbackId = $update['callback_query']['id'];
+
+ $userId = $update['callback_query']['from']['id'];
+ $oldMessageId = $update['callback_query']['message']['message_id'];
+
+ $userInputId = insertUserInput($userId, $stage, $oldMessageId);
+
+ $editMsg = getTranslation('gym_create') . ':';
+ $editKeys[0][] = button(getTranslation('abort'), ['gym_create', 'a' => $userInputId]);
+ $sendMsg = EMOJI_HERE . getTranslation('gym_gps_instructions') . CR;
+ $sendMsg .= getTranslation('gym_gps_example');
+ respondToUser($userId, $oldMessageId, $editMsg, $editKeys, $sendMsg, [], $callbackResponse, $callbackId);
+ exit;
+}
+$userId = $update['message']['from']['id'];
+$oldMessageId = $modifiers['oldMessageId'];
+
+if($stage == 2) {
+ $input = $update['message']['text'];
+ $reg_exp_coordinates = '^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$^';
+ if(preg_match($reg_exp_coordinates, $input)) {
+ [$lat,$lon] = explode(',', $input, 2);
+ my_query('INSERT INTO gyms (gym_name, lat, lon) VALUES (\'unknown\', :lat, :lon)', [':lat' => $lat, ':lon' => $lon]);
+ $gymId = $dbh->lastInsertId();
+
+ $userInputId = insertUserInput($userId, $stage, $oldMessageId, $gymId);
+ $msg = EMOJI_PENCIL . getTranslation('gym_name_instructions');
+ respondToUser($userId, 0, '', [], $msg);
+ }else {
+ $msg = getTranslation('gym_gps_coordinates_format_error');
+ respondToUser($userId, 0, '', [], $msg);
+ }
+ exit;
+}
+if($stage == 3) {
+ $input = trim($update['message']['text']);
+ if(strlen($input) <= 255) {
+ $gymId = $modifiers['gymId'];
+ my_query('UPDATE gyms SET gym_name = :gym_name WHERE id = :gymId', [':gym_name' => $input, ':gymId' => $gymId]);
+
+ $msg = getTranslation('gym_added');
+ $keys[][] = button(getTranslation('show_gym_details'), ['gym_details', 'g' => $gymId]);
+ respondToUser($userId, $oldMessageId, 'OK', [], $msg, $keys);
+ }else {
+ $msg = getTranslation('gym_edit_text_too_long');
+ respondToUser($userId, 0, '', [], $msg);
+ }
+ exit;
+}
diff --git a/mods/gym_delete.php b/mods/gym_delete.php
index ae2c5a31..1d0b6d86 100644
--- a/mods/gym_delete.php
+++ b/mods/gym_delete.php
@@ -1,74 +1,50 @@
accessCheck('gym-delete');
// Get the arg.
-$arg = $data['arg'];
+$gymId = $data['g'];
+$confirm = $data['c'] == 1 ? true : false;
-// Delete?
-if(substr_count($arg, '-') == 1) {
- $split_arg = explode('-', $arg);
- $new_arg = $split_arg[0];
- $delete = true;
- $confirm = false;
-} else if(substr_count($arg, '-') == 2) {
- $split_arg = explode('-', $arg);
- $new_arg = $split_arg[0];
- $delete = true;
- $confirm = true;
-} else {
- $msg = 'ERROR!';
- $keys = [];
-}
+$keys = [];
+if ($gymId > 0 && $confirm == false) {
+ $gym = get_gym($gymId);
-if ($new_arg > 0 && $delete == true && $confirm == false) {
- $gym = get_gym($new_arg);
-
- // Set message
- $msg = EMOJI_WARN . SP . '' . getTranslation('delete_this_gym') . '' . SP . EMOJI_WARN;
- $msg .= CR . get_gym_details($gym);
+ // Set message
+ $msg = EMOJI_WARN . SP . '' . getTranslation('delete_this_gym') . '' . SP . EMOJI_WARN;
+ $msg .= CR . get_gym_details($gym);
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('yes'),
- 'callback_data' => '0:gym_delete:' . $new_arg . '-delete-yes'
- ]
- ],
- [
- [
- 'text' => getTranslation('no'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
+ // Create the keys.
+ $keys[][] = button(getTranslation('yes'), ['gym_delete', 'g' => $gymId, 'c' => 1]);
+ $keys[][] = button(getTranslation('no'), ['gym_edit_details', 'g' => $gymId]);
// Delete the gym.
-} else if ($new_arg > 0 && $delete == true && $confirm == true) {
- debug_log('Deleting gym with ID ' . $new_arg);
- // Get gym.
- $gym = get_gym($new_arg);
-
- // Set message
- $msg = '' . getTranslation('deleted_this_gym') . '' . CR;
- $msg .= get_gym_details($gym);
- $keys = [];
-
- // Delete gym.
- my_query(
- "
- DELETE FROM gyms
- WHERE id = {$new_arg}
- "
- );
+} else if ($gymId > 0 && $confirm == true) {
+ require_once(LOGIC_PATH . '/get_gym_details.php');
+ require_once(LOGIC_PATH . '/get_gym.php');
+ debug_log('Deleting gym with ID ' . $gymId);
+ // Get gym.
+ $gym = get_gym($gymId);
+
+ // Set message
+ $msg = '' . getTranslation('deleted_this_gym') . '' . CR;
+ $msg .= get_gym_details($gym);
+
+ // Delete gym.
+ my_query('
+ DELETE FROM gyms
+ WHERE id = ?
+ ', [$gymId]
+ );
}
// Build callback message string.
@@ -85,6 +61,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/gym_details.php b/mods/gym_details.php
index 58279cba..2c091497 100644
--- a/mods/gym_details.php
+++ b/mods/gym_details.php
@@ -1,110 +1,28 @@
accessCheck('gym-details');
// Get the arg.
-$args = explode(',',$data['arg'],2);
-$arg = $args[0];
-$gymarea_id = (count($args) > 1) ? $args[1] : false;
+$arg = $data['g'];
// Get the id.
-$id = $data['id'];
-
-// ID or Arg = 0 ?
-if($arg == 0 || $id == '0' || $id == '1') {
- // Get hidden gyms?
- if($id == 0) {
- $hidden = true;
- } else {
- $hidden = false;
- }
-
- // Get the keys.
- $keys = raid_edit_gym_keys($arg, $gymarea_id, 'gym_details', false, $hidden);
-
- // Set keys.
- $msg = '' . getTranslation('show_gym_details') . CR . CR . getTranslation('select_gym_name') . '';
-
- // No keys found.
- if (!$keys) {
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
- } else {
- // Add navigation keys.
- $nav_keys = [];
- $nav_keys[] = universal_inner_key($nav_keys, $gymarea_id, 'gym_letter', 'gym_details', getTranslation('back'));
- $nav_keys[] = universal_inner_key($nav_keys, '0', 'exit', '0', getTranslation('abort'));
- $nav_keys = inline_key_array($nav_keys, 2);
- // Merge keys.
- $keys = array_merge($keys, $nav_keys);
- }
+$id = $data['g'];
// Get gym info.
-} else {
- $gym = get_gym($arg);
- $msg = get_gym_details($gym, true);
- $msg .= CR . CR . '' . getTranslation('change_extended_gym_details') . '';
-
- // Hide gym?
- if($gym['show_gym'] == 1) {
- $text_show_button = getTranslation('hide_gym');
- $arg_show = 0;
+$gym = get_gym($arg);
+$msg = get_gym_details($gym, true);
- // Show gym?
- } else {
- $text_show_button = getTranslation('show_gym');
- $arg_show = 1;
- }
-
- // Normal gym?
- if($gym['ex_gym'] == 1) {
- $text_ex_button = getTranslation('normal_gym');
- $arg_ex = 0;
-
- // Ex-raid gym?
- } else {
- $text_ex_button = getTranslation('ex_gym');
- $arg_ex = 1;
- }
-
- // Add buttons to show/hide the gym and add/remove ex-raid flag
- $keys = [];
- $keys[] = array(
- 'text' => $text_show_button,
- 'callback_data' => $arg . ':gym_edit_details:show-' . $arg_show
- );
- $keys[] = array(
- 'text' => $text_ex_button,
- 'callback_data' => $arg . ':gym_edit_details:ex-' . $arg_ex
- );
- if(bot_access_check($update, 'gym-delete', true)) {
- $keys[] = array(
- 'text' => getTranslation("gym_delete"),
- 'callback_data' => '0:gym_delete:'.$arg.'-delete'
- );
- }
- $keys[] = array(
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- );
-
- // Get the inline key array.
- $keys = inline_key_array($keys, 1);
-}
+$keys = edit_gym_keys($update, $arg, $gym['show_gym'], $gym['ex_gym'], $gym['gym_note'], $gym['address']);
// Build callback message string.
$callback_response = getTranslation('here_we_go');
@@ -120,6 +38,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/gym_edit_details.php b/mods/gym_edit_details.php
index 20842d7f..862f50e1 100644
--- a/mods/gym_edit_details.php
+++ b/mods/gym_edit_details.php
@@ -1,86 +1,91 @@
accessCheck('gym-edit');
// Get the id.
-$id = $data['id'];
-
-// Get the arg.
-$arg = $data['arg'];
+$gym_id = $data['g'];
// Split the arg.
-$split_arg = explode('-', $arg);
-$action = $split_arg[0];
-$value = $split_arg[1];
+$action = $data['a'] ?? '';
+$value = $data['v'] ?? false;
+$delete_id = $data['d'] ?? false;
// Set keys.
$keys = [];
-// Update gym info.
-if($action == 'show' || $action == 'ex') {
- $gym = get_gym($id);
-
- // Set message
- $msg = get_gym_details($gym, true);
- $msg .= CR . CR . '' . getTranslation('new_extended_gym_detail') . '';
-
- // New extended gym detail.
- if($action == 'show' && $value == 0) {
- $msg .= CR . '-' . SP . getTranslation('hide_gym');
- } else if($action == 'show' && $value == 1) {
- $msg .= CR . '-' . SP . getTranslation('show_gym');
- } else if($action == 'ex' && $value == 0) {
- $msg .= CR . '-' . SP . getTranslation('normal_gym');
- } else if($action == 'ex' && $value == 1) {
- $msg .= CR . '-' . SP . getTranslation('ex_gym');
+debug_log('Changing the details for the gym with ID ' . $gym_id);
+
+$gym = get_gym($gym_id);
+
+// Did we receive a call to edit some gym data that requires a text input
+if(in_array($action, ['name','note','gps','addr'])) {
+ if($value == 'd') {
+ my_query('DELETE FROM user_input WHERE id = :id', ['id' => $delete_id]);
+ if($action == 'note') {
+ my_query('UPDATE gyms SET gym_note = NULL WHERE id = :id', ['id' => $gym_id]);
+ $gym['gym_note'] = '';
}
- $msg .= CR . CR . '' . getTranslation('change_extended_gym_details') . '';
-
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('yes'),
- 'callback_data' => $id . ':gym_edit_details:' . 'confirm' . $action . '-' . $value
- ]
- ],
- [
- [
- 'text' => getTranslation('no'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
-
-} else if($action == 'confirmshow' || $action == 'confirmex') {
- debug_log('Changing the details for the gym with ID ' . $id);
- // Show or ex?
- $table = 'show_gym';
- if($action == 'confirmex') {
- $table = 'ex_gym';
+ $msg = get_gym_details($gym, true);
+ $keys = edit_gym_keys($update, $gym_id, $gym['show_gym'], $gym['ex_gym'], $gym['gym_note'], $gym['address']);
+ }elseif($value == 'e') {
+ my_query('DELETE FROM user_input WHERE id = ?', [$delete_id]);
+ if($action == 'addr') {
+ $addr = format_address(get_address($gym['lat'], $gym['lon']));
+ my_query('UPDATE gyms SET address = :addr WHERE id = :id', ['addr' => $addr, 'id' => $gym_id]);
+ $gym['address'] = $addr;
}
+ $msg = get_gym_details($gym, true);
+ $keys = edit_gym_keys($update, $gym_id, $gym['show_gym'], $gym['ex_gym'], $gym['gym_note'], $gym['address']);
+ }else {
+ // Create an entry to user_input table
+ $userid = $update['callback_query']['from']['id'];
+ $modifiers = json_encode(array('id' => $gym_id, 'value' => $action, 'old_message_id' => $update['callback_query']['message']['message_id']));
+ $handler = 'save_gym_info';
- my_query(
- "
- UPDATE gyms
- SET $table = $value
- WHERE id = {$id}
- "
- );
+ my_query('INSERT INTO user_input SET user_id = :userid, modifiers = :modifiers, handler = :handler', [':userid' => $userid, ':modifiers' => $modifiers, ':handler' => $handler]);
- // Get gym.
- $gym = get_gym($id);
-
- // Set message.
- $msg = '' . getTranslation('gym_saved') . '';
- $msg .= CR . get_gym_details($gym, true);
+ $msg = get_gym_details($gym, true);
+ if($action == 'addr') $instructions = 'gym_address_instructions'; else $instructions = 'gym_'.$action.'_instructions';
+ $msg .= CR . CR . '' . getTranslation($instructions) . '';
+ if($action == 'gps') $msg .= CR. getTranslation('gym_gps_example');
+
+ $keys[0][] = button(getTranslation('abort'), ['gym_edit_details', 'g' => $gym_id, 'a' => 'abort', 'd' => $dbh->lastInsertId()]);
+ if($action == 'note' && !empty($gym['gym_note'])) {
+ $keys[0][] = button(getTranslation('delete'), ['gym_edit_details', 'g' => $gym_id, 'a' => 'note', 'd' => $dbh->lastInsertId()]);
+ }
+ if($action == 'addr') {
+ $keys[0][] = button(getTranslation('gym_save_lookup_result'), ['gym_edit_details', 'g' => $gym_id, 'a' => 'addr', 'd' => $dbh->lastInsertId()]);
+ }
+ }
+}else {
+ if($action == 'show') {
+ $table = 'show_gym';
+ }else if($action == 'ex') {
+ $table = 'ex_gym';
+ }else if($action == 'abort') {
+ my_query('DELETE FROM user_input WHERE id = :delete_id', ['delete_id' => $delete_id]);
+ }
+ if(isset($table)) {
+ my_query('
+ UPDATE gyms
+ SET ' . $table . ' = :value
+ WHERE id = :gym_id
+ ', ['value' => $value, 'gym_id' => $gym_id]
+ );
+ $gym[$table] = $value;
+ }
+ $msg = get_gym_details($gym, true);
+ $keys = edit_gym_keys($update, $gym_id, $gym['show_gym'], $gym['ex_gym'], $gym['gym_note'], $gym['address']);
}
// Build callback message string.
@@ -97,6 +102,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/gym_hidden_letter.php b/mods/gym_hidden_letter.php
deleted file mode 100644
index 716fc069..00000000
--- a/mods/gym_hidden_letter.php
+++ /dev/null
@@ -1,67 +0,0 @@
-' . getTranslation('gym_delete') . SP . '—' . SP . getTranslation('select_gym_first_letter') . '';
-} else {
- // Force set arg.
- $arg = 'gym_details';
-
- // Check access.
- bot_access_check($update, 'gym-details');
-
- // Set message.
- $msg = '' . getTranslation('show_gym_details') . SP . '—' . SP . getTranslation('select_gym_first_letter') . '';
-}
-
-// Set keys.
-
-$keys_and_gymarea = raid_edit_gyms_first_letter_keys($arg, true, $data['id'], 'gym_letter', 'gym_details');
-$keys = $keys_and_gymarea['keys'];
-
-// Set message.
-if(!$keys) {
- $msg = CR . '' . getTranslation('no_hidden_gyms') . '';
-}
-
-// Add navigation keys.
-$nav_keys = [];
-$nav_keys[] = universal_inner_key($nav_keys, $data['id'], 'gym_letter', $arg, getTranslation('back'));
-$nav_keys[] = universal_inner_key($nav_keys, '0', 'exit', '0', getTranslation('abort'));
-$nav_keys = inline_key_array($nav_keys, 2);
-
-// Merge keys.
-$keys = array_merge($keys, $nav_keys);
-
-// Build callback message string.
-$callback_response = getTranslation('here_we_go');
-
-// Telegram JSON array.
-$tg_json = array();
-
-// Answer callback.
-$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
-
-// Edit the message.
-$tg_json[] = edit_message($update, $msg, $keys, ['disable_web_page_preview' => 'true'], true);
-
-// Telegram multicurl request.
-curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
-
-?>
diff --git a/mods/gym_letter.php b/mods/gym_letter.php
deleted file mode 100644
index 1bb15303..00000000
--- a/mods/gym_letter.php
+++ /dev/null
@@ -1,76 +0,0 @@
-' . getTranslation('gym_delete') . CR . getTranslation('select_gym_first_letter') . '';
- $msg.= (($keys_and_gymarea['gymarea_name'] != '') ? CR . CR . getTranslation('current_gymarea') . ': ' . $keys_and_gymarea['gymarea_name'] : '');
-} else {
- // Force set arg.
- $arg = 'gym_details';
-
- // Check access.
- bot_access_check($update, 'gym-details');
-
- // Set message.
- $msg = '' . getTranslation('show_gym_details') . CR . getTranslation('select_gym_first_letter') . '';
- $msg.= (($keys_and_gymarea['gymarea_name'] != '') ? CR . CR . getTranslation('current_gymarea') . ': ' . $keys_and_gymarea['gymarea_name'] : '');
-}
-
-$nav_keys = [];
-
-if($data['id'] != 'n' or $config->ENABLE_GYM_AREAS === false) {
- $nav_keys[] = [
- 'text' => getTranslation('back'),
- 'callback_data' => 'n:gym_letter:gym_details'
- ];
- // Add key for hidden gyms.
- $h_keys = [];
- $h_keys[] = universal_inner_key($h_keys, $data['id'], 'gym_hidden_letter', $arg, getTranslation('hidden_gyms'));
- $h_keys = inline_key_array($h_keys, 1);
- // Merge keys.
- $keys = array_merge($h_keys, $keys);
-}
-$nav_keys[] = [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ];
-$nav_keys = inline_key_array($nav_keys, 2);
-// Merge keys.
-$keys = array_merge($keys, $nav_keys);
-
-// Build callback message string.
-$callback_response = getTranslation('here_we_go');
-
-// Telegram JSON array.
-$tg_json = array();
-
-// Answer callback.
-$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
-
-// Edit the message.
-$tg_json[] = edit_message($update, $msg, $keys, ['disable_web_page_preview' => 'true'], true);
-
-// Telegram multicurl request.
-curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
-
-?>
diff --git a/mods/history.php b/mods/history.php
index a895c989..331beee3 100644
--- a/mods/history.php
+++ b/mods/history.php
@@ -7,84 +7,73 @@
//debug_log($data);
// Check access.
-bot_access_check($update, 'history');
+$botUser->accessCheck('history');
// Expected callback data: [Day number (0-31), DD]:history:[Year and month, YYYY-MM]
require_once(LOGIC_PATH .'/history.php');
-$current_day = $data['id'];
-$current_year_month = $data['arg'];
+$current_day = $data['d'] ?? 0;
+$current_year_month = $data['m'] ?? '';
if($current_day == 0) {
- $msg_keys = create_history_date_msg_keys($current_year_month);
- $msg = $msg_keys[0];
- $keys = $msg_keys[1];
+ $msg_keys = create_history_date_msg_keys($current_year_month);
+ $msg = $msg_keys[0];
+ $keys = $msg_keys[1];
}else {
- $msg = getTranslation('history_title') . CR . CR;
- $msg.= '' . getTranslation('date') . ': ' . getTranslation('month_' . substr($current_year_month,5)) . ' ' . $current_day . CR . CR;
- $msg.= getTranslation('select_gym_first_letter');
- // Special/Custom gym letters?
- if(!empty($config->RAID_CUSTOM_GYM_LETTERS)) {
- // Explode special letters.
- $special_keys = explode(',', $config->RAID_CUSTOM_GYM_LETTERS);
- $select_query = 'CASE';
- foreach($special_keys as $id => $letter)
- {
- $letter = trim($letter);
- debug_log($letter, 'Special gym letter:');
- // Fix chinese chars, prior: $length = strlen($letter);
- $length = strlen(utf8_decode($letter));
- $select_query .= SP . "WHEN UPPER(LEFT(gym_name, " . $length . ")) = '" . $letter . "' THEN UPPER(LEFT(gym_name, " . $length . "))" . SP;
- }
- $select_query .= 'ELSE UPPER(LEFT(gym_name, 1)) END';
- }else {
- $select_query = 'DISTINCT UPPER(SUBSTR(gym_name, 1, 1))';
+ $msg = getTranslation('history_title') . CR . CR;
+ $msg.= '' . getTranslation('date') . ': ' . getTranslation('month_' . substr($current_year_month,5)) . ' ' . $current_day . CR . CR;
+ $msg.= getTranslation('select_gym_first_letter');
+ // Special/Custom gym letters?
+ if(!empty($config->RAID_CUSTOM_GYM_LETTERS)) {
+ // Explode special letters.
+ $special_keys = explode(',', $config->RAID_CUSTOM_GYM_LETTERS);
+ $select_query = 'CASE';
+ foreach($special_keys as $id => $letter)
+ {
+ $letter = trim($letter);
+ debug_log($letter, 'Special gym letter:');
+ // Fix chinese chars, prior: $length = strlen($letter);
+ $length = strlen(mb_convert_encoding($letter, 'ISO-8859-1'));
+ $select_query .= SP . "WHEN UPPER(LEFT(gym_name, " . $length . ")) = '" . $letter . "' THEN UPPER(LEFT(gym_name, " . $length . "))" . SP;
}
- $date = $current_year_month.'-'.$current_day;
-
- $rs = my_query(
- '
- SELECT '.$select_query.' AS first_letter
- FROM raids
- LEFT JOIN gyms
- ON raids.gym_id = gyms.id
- LEFT JOIN attendance
- ON attendance.raid_id = raids.id
- WHERE date_format(start_time, "%Y-%m-%d") = \''.$date.'\'
- AND raids.end_time < UTC_TIMESTAMP()
- AND attendance.id IS NOT NULL
- AND gyms.gym_name IS NOT NULL
- ORDER BY first_letter
- '
- );
-
- // Init empty keys array.
- $keys = [];
-
- while ($gym = $rs->fetch()) {
+ $select_query .= 'ELSE UPPER(LEFT(gym_name, 1)) END';
+ }else {
+ $select_query = 'DISTINCT UPPER(SUBSTR(gym_name, 1, 1))';
+ }
+ $date = $current_year_month.'-'.$current_day;
+
+ $rs = my_query('
+ SELECT '.$select_query.' AS first_letter
+ FROM raids
+ LEFT JOIN gyms
+ ON raids.gym_id = gyms.id
+ LEFT JOIN attendance
+ ON attendance.raid_id = raids.id
+ WHERE date_format(start_time, "%Y-%m-%d") = ?
+ AND raids.end_time < UTC_TIMESTAMP()
+ AND attendance.id IS NOT NULL
+ AND gyms.gym_name IS NOT NULL
+ ORDER BY first_letter
+ ', [$date]);
+
+ // Init empty keys array.
+ $keys = [];
+
+ while ($gym = $rs->fetch()) {
// Add first letter to keys array
- $keys[] = array(
- 'text' => $gym['first_letter'],
- 'callback_data' => $date . ':history_gyms:' . $gym['first_letter']
- );
- }
- // Format buttons
- $keys = inline_key_array($keys, 4);
-
- $nav_keys = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => '0:history:' . $current_year_month
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
-
- // Get the inline key array.
- $keys[] = $nav_keys;
+ $keys[] = button($gym['first_letter'],['history_gyms', 'd' => $date, 'fl' => $gym['first_letter']]);
+ }
+ // Format buttons
+ $keys = inline_key_array($keys, 4);
+
+ $nav_keys = [
+ button(getTranslation('back'), ['history', 'm' => $current_year_month]),
+ button(getTranslation('abort'), 'exit')
+ ];
+
+ // Get the inline key array.
+ $keys[] = $nav_keys;
}
@@ -98,7 +87,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
-?>
diff --git a/mods/history_gyms.php b/mods/history_gyms.php
index 10c3e701..ebea6a5d 100644
--- a/mods/history_gyms.php
+++ b/mods/history_gyms.php
@@ -7,12 +7,12 @@
//debug_log($data);
// Check access.
-bot_access_check($update, 'history');
+$botUser->accessCheck('history');
// Expected callback data: [Date, YYYY-MM-DD]:history_gyms:[GYM_LETTER]
-$current_date = $data['id'];
-$first = $data['arg'];
+$current_date = $data['d'];
+$first = $data['fl'];
$split_date = explode('-', $current_date);
$current_day = $split_date[2];
@@ -20,69 +20,58 @@
// Length of first letter.
// Fix chinese chars, prior: $first_length = strlen($first);
-$first_length = strlen(utf8_decode($first));
+$first_length = strlen(mb_convert_encoding($first, 'ISO-8859-1'));
// Special/Custom gym letters?
$not = '';
if(!empty($config->RAID_CUSTOM_GYM_LETTERS) && $first_length == 1) {
- // Explode special letters.
- $special_keys = explode(',', $config->RAID_CUSTOM_GYM_LETTERS);
-
- foreach($special_keys as $id => $letter)
- {
- $letter = trim($letter);
- debug_log($letter, 'Special gym letter:');
- // Fix chinese chars, prior: $length = strlen($letter);
- $length = strlen(utf8_decode($letter));
- $not .= SP . "AND UPPER(LEFT(gym_name, " . $length . ")) != UPPER('" . $letter . "')" . SP;
- }
+ // Explode special letters.
+ $special_keys = explode(',', $config->RAID_CUSTOM_GYM_LETTERS);
+
+ foreach($special_keys as $id => $letter)
+ {
+ $letter = trim($letter);
+ debug_log($letter, 'Special gym letter:');
+ // Fix chinese chars, prior: $length = strlen($letter);
+ $length = strlen(mb_convert_encoding($letter, 'ISO-8859-1'));
+ $not .= SP . "AND UPPER(LEFT(gym_name, " . $length . ")) != UPPER('" . $letter . "')" . SP;
+ }
}
$query_collate = "";
-if($config->MYSQL_SORT_COLLATE != "") {
- $query_collate = "COLLATE " . $config->MYSQL_SORT_COLLATE;
+if($config->MYSQL_SORT_COLLATE != '') {
+ $query_collate = 'COLLATE ' . $config->MYSQL_SORT_COLLATE;
}
// Get gyms from database
-$rs = my_query(
- '
- SELECT gyms.id, gyms.gym_name, gyms.ex_gym
- FROM gyms
- LEFT JOIN raids
- ON raids.gym_id = gyms.id
- LEFT JOIN attendance
- ON attendance.raid_id = raids.id
- WHERE UPPER(LEFT(gym_name, ' . $first_length . ')) = UPPER("' . $first . '")
- AND date_format(start_time, "%Y-%m-%d") = "' . $current_date . '"
- AND raids.end_time < UTC_TIMESTAMP()
- AND attendance.id IS NOT NULL
- ' . $not . '
- GROUP BY gym_name, raids.gym_id, gyms.id, gyms.ex_gym
- ORDER BY gym_name ' . $query_collate
-
+$rs = my_query('
+ SELECT gyms.id, gyms.gym_name, gyms.ex_gym
+ FROM gyms
+ LEFT JOIN raids
+ ON raids.gym_id = gyms.id
+ LEFT JOIN attendance
+ ON attendance.raid_id = raids.id
+ WHERE UPPER(LEFT(gym_name, ' . $first_length . ')) = UPPER("' . $first . '")
+ AND date_format(start_time, "%Y-%m-%d") = "' . $current_date . '"
+ AND raids.end_time < UTC_TIMESTAMP()
+ AND attendance.id IS NOT NULL
+ ' . $not . '
+ GROUP BY gym_name, raids.gym_id, gyms.id, gyms.ex_gym
+ ORDER BY gym_name ' . $query_collate
);
while ($gym = $rs->fetch()) {
- // Show Ex-Gym-Marker?
- if($config->RAID_CREATION_EX_GYM_MARKER && $gym['ex_gym'] == 1) {
- $ex_raid_gym_marker = (strtolower($config->RAID_EX_GYM_MARKER) == 'icon') ? EMOJI_STAR : $config->RAID_EX_GYM_MARKER;
- $gym_name = $ex_raid_gym_marker . SP . $gym['gym_name'];
- } else {
- $gym_name = $gym['gym_name'];
- }
- $keys[][] = [
- 'text' => $gym_name,
- 'callback_data' => $current_date . '/' . $first . ':history_raids:' . $gym['id']
- ];
+ // Show Ex-Gym-Marker?
+ if($config->RAID_CREATION_EX_GYM_MARKER && $gym['ex_gym'] == 1) {
+ $ex_raid_gym_marker = (strtolower($config->RAID_EX_GYM_MARKER) == 'icon') ? EMOJI_STAR : $config->RAID_EX_GYM_MARKER;
+ $gym_name = $ex_raid_gym_marker . SP . $gym['gym_name'];
+ } else {
+ $gym_name = $gym['gym_name'];
+ }
+ $keys[][] = button($gym_name, ['history_raids', 'd' => $current_date, 'fl' => $first, 'g' => $gym['id']]);
}
$nav_keys = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => $current_day.':history:' . $current_year_month
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
+ button(getTranslation('back'), ['history', 'd' => $current_day, 'm' => $current_year_month]),
+ button(getTranslation('abort'), 'exit')
];
$keys[] = $nav_keys;
@@ -99,5 +88,3 @@
curl_json_multi_request($tg_json);
exit();
-
-?>
\ No newline at end of file
diff --git a/mods/history_raid.php b/mods/history_raid.php
index 5b518abe..dcd519a8 100644
--- a/mods/history_raid.php
+++ b/mods/history_raid.php
@@ -1,19 +1,16 @@
accessCheck('history');
-// Expected callback data: [Date, YYYY-MM-DD]/[GYM_LETTER]:history_raid:[GYM_ID]/[RAID_ID]
-
-$arg_data = explode('/',$data['arg']);
-$gym_id = $arg_data[0];
-$raid_id = $arg_data[1];
+$raid_id = $data['r'];
$raid = get_raid($raid_id);
@@ -25,15 +22,11 @@
// Answer callback.
$tg_json[] = answerCallbackQuery($update['callback_query']['id'], 'OK', true);
+$backData = $data;
+$backData[0] = 'history_raids';
$keys[] = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => $data['id'] . ':history_raids:' . $gym_id
- ],
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
+ button(getTranslation('back'), $backData),
+ button(getTranslation('done'), ['exit', 'd' => '1'])
];
// Edit message.
@@ -41,8 +34,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
-
-?>
\ No newline at end of file
diff --git a/mods/history_raids.php b/mods/history_raids.php
index 42cb6c27..996462e3 100644
--- a/mods/history_raids.php
+++ b/mods/history_raids.php
@@ -7,49 +7,38 @@
//debug_log($data);
// Check access.
-bot_access_check($update, 'history');
+$botUser->accessCheck('history');
-// Expected callback data: [Date, YYYY-MM-DD]/[GYM_LETTER]:history_raids:[GYM_ID]
-
-$id_data = explode('/',$data['id']);
-$current_date = $id_data[0];
-$gym_first_letter = $id_data[1];
-
-$gym_id = $data['arg'];
+$current_date = $data['d'];
+$gym_first_letter = $data['fl'];
+$gym_id = $data['g'];
// Get raids from database
-$rs = my_query(
- '
- SELECT gyms.gym_name, raids.id, raids.start_time, raids.pokemon, raids.pokemon_form
- FROM gyms
- LEFT JOIN raids
- ON raids.gym_id = gyms.id
- LEFT JOIN attendance
- ON attendance.raid_id = raids.id
- WHERE gyms.id = "'.$gym_id.'"
- AND raids.end_time < UTC_TIMESTAMP()
- AND attendance.id IS NOT NULL
- GROUP BY raids.id, raids.start_time, raids.pokemon, raids.pokemon_form, gyms.gym_name
- ORDER BY start_time
- '
+$rs = my_query('
+ SELECT gyms.gym_name, raids.id, raids.start_time, raids.pokemon, raids.pokemon_form
+ FROM gyms
+ LEFT JOIN raids
+ ON raids.gym_id = gyms.id
+ LEFT JOIN attendance
+ ON attendance.raid_id = raids.id
+ WHERE gyms.id = ?
+ AND raids.end_time < UTC_TIMESTAMP()
+ AND attendance.id IS NOT NULL
+ GROUP BY raids.id, raids.start_time, raids.pokemon, raids.pokemon_form, gyms.gym_name
+ ORDER BY start_time
+ ', [$gym_id]
);
while ($raid = $rs->fetch()) {
- $keys[][] = [
- 'text' => dt2time($raid['start_time']) . ': ' . get_local_pokemon_name($raid['pokemon'],$raid['pokemon_form']),
- 'callback_data' => $data['id'] . ':history_raid:' . $gym_id .'/' . $raid['id']
- ];
- $gym_name = $raid['gym_name'];
- $start_time = $raid['start_time'];
+ $newData = $data;
+ $newData[0] = 'history_raid';
+ $newData['r'] = $raid['id'];
+ $keys[][] = button(dt2time($raid['start_time']) . ': ' . get_local_pokemon_name($raid['pokemon'],$raid['pokemon_form']), $newData);
+ $gym_name = $raid['gym_name'];
+ $start_time = $raid['start_time'];
}
$nav_keys = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => $current_date . ':history_gyms:' . $gym_first_letter
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
+ button(getTranslation('back'), ['history_gyms', 'd' => $current_date, 'fl' => $gym_first_letter]),
+ button(getTranslation('abort'), 'exit')
];
$keys[] = $nav_keys;
@@ -67,5 +56,3 @@
curl_json_multi_request($tg_json);
exit();
-
-?>
\ No newline at end of file
diff --git a/mods/import_future_bosses.php b/mods/import_future_bosses.php
index ac2b1e9a..25462d3d 100644
--- a/mods/import_future_bosses.php
+++ b/mods/import_future_bosses.php
@@ -7,77 +7,54 @@
//debug_log($data);
// Check access.
-bot_access_check($update, 'pokedex');
+$botUser->accessCheck('pokedex');
require_once(LOGIC_PATH . '/read_upcoming_bosses.php');
-$id = $data['id'];
-$arg = $data['arg'];
+$action = $data['a'] ?? 0;
-if($arg == '1') {
- try {
- $sql = 'DELETE FROM raid_bosses WHERE scheduled = 1;';
- $sql .= read_upcoming_bosses(true);
- $query = $dbh->prepare($sql);
- $query->execute();
- $msg = getTranslation('import_done');
- }catch (PDOException $exception) {
- $msg = getTranslation('internal_error') . CR;
- $msg.= $exception->getMessage();
- info_log($exception->getMessage());
+if($action == '1') {
+ $sql = 'DELETE FROM raid_bosses WHERE scheduled = 1;';
+ $sql .= read_upcoming_bosses('sql');
+ $query = my_query($sql);
+ $msg = getTranslation('import_done');
+ $tg_json = array();
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], 'OK', true);
+ $tg_json[] = edit_message($update, $msg, [], false, true);
+ curl_json_multi_request($tg_json);
+ exit();
+}
+$list = read_upcoming_bosses();
+$msg = '';
+if(!empty($list)) {
+ $now = new DateTime('now', new DateTimeZone($config->TIMEZONE));
+ $query = my_query("
+ SELECT id, pokedex_id, pokemon_form_id, raid_level, scheduled, DATE_FORMAT(date_start, '%e.%c. ".getTranslation('raid_egg_opens_at')." %H:%i') as date_start, DATE_FORMAT(date_end, '%e.%c. ".getTranslation('raid_egg_opens_at')." %H:%i') as date_end FROM raid_bosses
+ WHERE date_end > '" . $now->format('Y-m-d H:i:s') . "'
+ AND scheduled = 1
+ ORDER BY date_start, raid_level, pokedex_id, pokemon_form_id
+ ");
+ $prev_start = $prev_rl = '';
+ $msg = '' . getTranslation('current_scheduled_bosses') . ':';
+ foreach($query->fetchAll() as $result) {
+ if($prev_start != $result['date_start']) {
+ $msg.= CR . EMOJI_CLOCK . ' ' . $result['date_start'] . ' — ' . $result['date_end'] . ':' . CR;
+ $prev_rl = '';
}
- $keys = [];
-}else {
- $list = read_upcoming_bosses();
- $msg = '';
- if(!empty($list)) {
- $now = new DateTime('now', new DateTimeZone($config->TIMEZONE));
- $query = my_query("
- SELECT * FROM raid_bosses
- WHERE date_end > '" . $now->format('Y-m-d H:i:s') . "'
- AND scheduled = 1
- ORDER BY date_start, raid_level, pokedex_id, pokemon_form_id
- ");
- $prev_start = $prev_rl = '';
- $msg = '' . getTranslation('current_scheduled_bosses') . ':';
- foreach($query->fetchAll() as $result) {
- if($prev_start != $result['date_start']) {
- $msg.= CR . '' . $result['date_start'] . ' - ' . $result['date_end'] . ':' . CR;
- }
- if($prev_rl != $result['raid_level']) {
- $msg.= '' . getTranslation($result['raid_level'] . 'stars') .':' . CR;
- }
- $msg.= get_local_pokemon_name($result['pokedex_id'], $result['pokemon_form_id']) . CR;
- $prev_start = $result['date_start'];
- $prev_rl = $result['raid_level'];
- }
- $msg .= CR . CR . '' . getTranslation('found_upcoming_bosses') . ':';
- $msg .= $list;
- $msg .= CR . CR . getTranslation('confirm_replace_upcoming');
- $keys = [
- [
- [
- 'text' => getTranslation('replace'),
- 'callback_data' => '1:import_future_bosses:1'
- ]
- ],
- [
- [
- 'text'=>getTranslation('back'),
- 'callback_data' => '0:pokedex_import:0'
- ]
- ]
- ];
- }else {
- $msg .= getTranslation('upcoming_bosses_not_found');
- $keys = [
- [
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ]
- ];
+ if($prev_rl != $result['raid_level']) {
+ $msg.= '' . getTranslation($result['raid_level'] . 'stars') .':' . CR;
}
+ $msg.= get_local_pokemon_name($result['pokedex_id'], $result['pokemon_form_id']) . CR;
+ $prev_start = $result['date_start'];
+ $prev_rl = $result['raid_level'];
+ }
+ $msg .= CR . CR . '' . getTranslation('found_upcoming_bosses') . ':';
+ $msg .= $list;
+ $msg .= CR . CR . getTranslation('confirm_replace_upcoming');
+ $keys[][] = button(getTranslation('replace'), ['import_future_bosses', 'a' => 1]);
+ $keys[][] = button(getTranslation('back'), 'pokedex_import');
+}else {
+ $msg .= getTranslation('upcoming_bosses_not_found');
+ $keys[][] = button(getTranslation('done'), ['exit', 'd' => '1']);
}
// Callback message string.
@@ -94,8 +71,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-$dbh = null;
-exit();
-
-?>
\ No newline at end of file
diff --git a/mods/import_shinyinfo.php b/mods/import_shinyinfo.php
index bc5c1217..233de82d 100644
--- a/mods/import_shinyinfo.php
+++ b/mods/import_shinyinfo.php
@@ -1,22 +1,23 @@
accessCheck('pokedex');
$link = 'https://fight.pokebattler.com/raids';
$pb_data = curl_get_contents($link);
+if($pb_data === false) {
+ $callback_response = getTranslation('internal_error');
+ answerCallbackQuery($update['callback_query']['id'], $callback_response);
+ exit();
+}
$pb_data = json_decode($pb_data,true);
// Init empty keys array.
@@ -24,107 +25,34 @@
$msg = '';
$shinydata = [];
foreach($pb_data['tiers'] as $tier) {
-
- // Raid level and message.
- $rl = str_replace('RAID_LEVEL_','', $tier['tier']);
- if($rl == "MEGA") $raid_level_id = 6; else $raid_level_id = $rl;
- $rl_parts = explode('_', $rl);
- if($rl_parts[count($rl_parts)-1] == 'FUTURE') continue;
- #$msg .= '' . getTranslation('pokedex_raid_level') . SP . $rl . ':' . CR;
-
- // Get raid bosses for each raid level.
- foreach($tier['raids'] as $raid) {
- if(!isset($raid['pokemon']) || $raid['shiny'] != 'true') continue;
- // Pokemon name ending with "_FORM" ?
- if(substr_compare($raid['pokemon'], '_FORM', -strlen('_FORM')) === 0) {
- debug_log('Pokemon with a special form received: ' . $raid['pokemon']);
- // Remove "_FORM"
- $pokemon = str_replace('_FORM', '', $raid['pokemon']);
-
- // Get pokemon name and form.
- $name = explode("_", $pokemon, 2)[0];
- $form = explode("_", $pokemon, 2)[1];
-
- // Fix for MEWTWO_A_FORM
- if($name == 'MEWTWO' && $form == 'A') {
- $form = 'ARMORED';
- }
-
- // Pokemon name ending with "_MALE" ?
- } else if(substr_compare($raid['pokemon'], '_MALE', -strlen('_MALE')) === 0) {
- debug_log('Pokemon with gender MALE received: ' . $raid['pokemon']);
- // Remove "_MALE"
- $pokemon = str_replace('_MALE', '', $raid['pokemon']);
-
- // Get pokemon name and form.
- $name = explode("_", $pokemon, 2)[0] . '♂';
- $form = 'normal';
-
- // Pokemon name ending with "_FEMALE" ?
- } else if(substr_compare($raid['pokemon'], '_FEMALE', -strlen('_FEMALE')) === 0) {
- debug_log('Pokemon with gender FEMALE received: ' . $raid['pokemon']);
- // Remove "_FEMALE"
- $pokemon = str_replace('_FEMALE', '', $raid['pokemon']);
-
- // Get pokemon name and form.
- $name = explode("_", $pokemon, 2)[0] . '♀';
- $form = 'normal';
-
- // Mega pokemon ?
- }else if(substr_compare($raid['pokemon'], '_MEGA', -strlen('_MEGA')) === 0 or substr_compare($raid['pokemon'], '_MEGA_X', -strlen('_MEGA_X')) === 0 or substr_compare($raid['pokemon'], '_MEGA_Y', -strlen('_MEGA_Y')) === 0) {
- debug_log('Mega Pokemon received: ' . $raid['pokemon']);
-
- // Get pokemon name and form.
- $name_form = explode("_", $raid['pokemon'], 2);
- $name = $name_form[0];
- $form = $name_form[1];
-
- // Normal pokemon without form or gender.
- } else {
- // Fix pokemon like "HO_OH"...
- if(substr_count($raid['pokemon'], '_') >= 1) {
- $pokemon = str_replace('_', '-', $raid['pokemon']);
- } else {
- $pokemon = $raid['pokemon'];
- }
- // Name and form.
- $name = $pokemon;
- $form = 'normal';
-
- // Fix for GIRATINA as the actual GIRATINA_ALTERED_FORM is just GIRATINA
- if($name == 'GIRATINA' && $form == 'normal') {
- $form = 'ALTERED';
- }
- }
- if($form != 'normal') continue;
- // Get ID and form name used internally.
- debug_log('Getting dex id and form for pokemon ' . $name . ' with form ' . $form);
- $dex_id_form = get_pokemon_id_by_name($name . '-' . $form, true);
- $dex_id = explode('-', $dex_id_form, 2)[0];
- $dex_form = explode('-', $dex_id_form, 2)[1];
-
- // Make sure we received a valid dex id.
- if(!is_numeric($dex_id) || $dex_id == 0) {
- info_log('Failed to get a valid pokemon dex id: '. $dex_id .' Continuing with next raid boss...');
- continue;
- }
-
- $shinydata[] = [':dex_id' => $dex_id, ':dex_form' => $dex_form];
+ // Raid level and message.
+ $rl = str_replace('RAID_LEVEL_','', $tier['tier']);
+ if($rl == "MEGA") $raid_level_id = 6; else $raid_level_id = $rl;
+ $rl_parts = explode('_', $rl);
+ if($rl_parts[count($rl_parts)-1] == 'FUTURE') continue;
+
+ // Get raid bosses for each raid level.
+ foreach($tier['raids'] as $raid) {
+ if(!isset($raid['pokemon']) || $raid['shiny'] != 'true') continue;
+
+ // Get ID and form name used internally.
+ [$dex_id, $dex_form] = resolvePokebattlerNameToIds($raid['pokemon']);
+
+ // Make sure we received a valid dex id.
+ if(!is_numeric($dex_id) || $dex_id == 0) {
+ info_log('Failed to get a valid pokemon dex id: '. $dex_id .', pokemon: ' . $raid['pokemon'] . '. Continuing with next raid boss...', 'Import shinyinfo:');
+ continue;
}
- $msg .= CR;
+ $shinydata[] = [':dex_id' => $dex_id, ':dex_form' => $dex_form];
+ }
}
- // Back button.
- $keys[] = [
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ];
+// Back button.
+$keys[][] = button(getTranslation('done'), ['exit', 'd' => '1']);
if(count($shinydata) > 0) {
- $query = $dbh->prepare("UPDATE pokemon SET shiny = 1 WHERE pokedex_id = :dex_id AND pokemon_form_id = :dex_form");
- foreach($shinydata as $row_data) {
- $query->execute($row_data);
- }
+ $query = $dbh->prepare("UPDATE pokemon SET shiny = 1 WHERE pokedex_id = :dex_id AND pokemon_form_id = :dex_form");
+ foreach($shinydata as $row_data) {
+ $query->execute($row_data);
+ }
}
$msg .= 'Updated '.count($shinydata).' rows'.CR;
@@ -143,6 +71,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/importal.php b/mods/importal.php
index fa589151..621c3d15 100644
--- a/mods/importal.php
+++ b/mods/importal.php
@@ -1,153 +1,126 @@
accessCheck('portal-import');
function escape($value){
- $search = array("\\", "\x00", "\n", "\r", "'", '"', "\x1a");
- $replace = array("\\\\","\\0","\\n", "\\r", "\'", '\"', "\\Z");
+ $search = array("\\", "\x00", "\n", "\r", "'", '"', "\x1a");
+ $replace = array("\\\\","\\0","\\n", "\\r", "\'", '\"', "\\Z");
- return str_replace($search, $replace, $value);
+ return str_replace($search, $replace, $value);
}
// Import allowed?
-if($config->PORTAL_IMPORT) {
-
- // Process message for portal information.
- require_once(CORE_BOT_PATH . '/importal.php');
-
- // Insert gym.
- try {
-
- global $dbh;
-
- // Gym name.
- $gym_name = $portal;
- if(empty($portal)) {
- $gym_name = '#' . $update['message']['from']['id'];
- }
-
- // Gym image.
- if($config->RAID_PICTURE_STORE_GYM_IMAGES_LOCALLY) {
- $no_spaces_gym_name = str_replace(array(' ', '\''), array('_', ''), $gym_name) . '.png';
- $gym_image = download_Portal_Image($portal_image, PORTAL_IMAGES_PATH, $no_spaces_gym_name);
- if($gym_image) {
- $gym_image = "file://" . $gym_image;
- }
- } else {
- $gym_image = $portal_image;
- }
-
- $gym_name_no_spec = escape($portal); // Convert special characters in gym name
- // Build query to check if gym is already in database or not
- // First check if gym is found by portal id
- $gym_query = 'SELECT id FROM gyms WHERE gym_id = :gym_id LIMIT 1';
- $gym_statement = $dbh->prepare($gym_query);
- $gym_statement->execute(['gym_id' => $portal_id]);
- if($gym_statement->rowCount() == 1) {
- $row = $gym_statement->fetch();
- $update_where_condition = 'gym_id = :gym_id';
- $update_values = '';
- }else {
- // If portal id wasn't found, check by gym name
- $gym_query_by_name = 'SELECT id FROM gyms WHERE gym_name = :gym_name LIMIT 1';
- $gym_statement_by_name = $dbh->prepare($gym_query_by_name);
- $gym_statement_by_name->execute(['gym_name' => $gym_name_no_spec]);
- $row = $gym_statement_by_name->fetch();
- $update_where_condition = 'gym_name = :gym_name';
- $update_values = 'gym_id = :gym_id, ';
- }
-
- // Gym already in database or new
- if (empty($row['id'])) {
- // insert gym in table.
- debug_log('Gym not found in database gym list! Inserting gym "' . $gym_name . '" now.');
- $query = '
- INSERT INTO gyms (gym_name, lat, lon, address, show_gym, img_url, gym_id)
- VALUES (:gym_name, :lat, :lon, :address, 0, :gym_image, :gym_id)
- ';
- $msg = getTranslation('gym_added');
-
- } else {
- // Update gyms table to reflect gym changes.
- debug_log('Gym found in database gym list! Updating gym "' . $gym_name . '" now.');
- $query = '
- UPDATE gyms
- SET lat = :lat,
- lon = :lon,
- address = :address,
- ' . $update_values . '
- img_url = :gym_image
- WHERE ' . $update_where_condition . '
- ';
- $msg = getTranslation('gym_updated');
- $gym_id = $row['id'];
- }
-
- // Insert / Update.
- $statement = $dbh->prepare($query);
- $statement->execute([
- 'gym_name' => $gym_name,
- 'lat' => $lat,
- 'lon' => $lon,
- 'address' => $address,
- 'gym_image' => $gym_image,
- 'gym_id' => $portal_id
- ]);
- } catch (PDOException $exception) {
- error_log($exception->getMessage());
- $dbh = null;
- exit();
- }
-
- // Get last insert id.
- if (empty($row['id'])) {
- $gym_id = $dbh->lastInsertId();
- }
-
- // Gym details.
- if($gym_id > 0) {
- $gym = get_gym($gym_id);
- $msg .= CR . CR . get_gym_details($gym);
- }
-
- // Gym photo.
- if($gym_image) {
- $msg .= EMOJI_CAMERA . SP . $no_spaces_gym_name;
- }
-
- // Set keys.
- $keys = [
- [
- [
- 'text' => getTranslation('delete'),
- 'callback_data' => $gym_name[0] . ':gym_delete:' . $gym_id . '-delete'
- ],
- [
- 'text' => getTranslation('show_gym'),
- 'callback_data' => $gym_id . ':gym_edit_details:show-1'
- ]
- ],
- [
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ]
- ];
+if(!$config->PORTAL_IMPORT) {
+ $msg = getTranslation('bot_access_denied');
+ $keys = [];
+ send_message(create_chat_object([$update['message']['chat']['id']]), $msg, $keys, ['disable_web_page_preview' => 'true']);
+ exit;
+}
+
+// Process message for portal information.
+require_once(CORE_BOT_PATH . '/importal.php');
+// Gym name.
+$gym_name = $portal;
+if(empty($portal)) {
+ $gym_name = '#' . $update['message']['from']['id'];
+}
+
+// Gym image.
+if($config->RAID_PICTURE_STORE_GYM_IMAGES_LOCALLY) {
+ $no_spaces_gym_name = str_replace(array(' ', '\''), array('_', ''), $gym_name) . '.png';
+ $gym_image = download_Portal_Image($portal_image, PORTAL_IMAGES_PATH, $no_spaces_gym_name);
+ if($gym_image) {
+ $gym_image = "file://" . $gym_image;
+ }
} else {
- $msg = getTranslation('bot_access_denied');
- $keys = [];
+ $gym_image = $portal_image;
}
-// Send the message.
-send_message($update['message']['chat']['id'], $msg, $keys, ['disable_web_page_preview' => 'true']);
+$gym_name_no_spec = escape($portal); // Convert special characters in gym name
+// Build query to check if gym is already in database or not
+// First check if gym is found by portal id
+$gym_statement = my_query('SELECT id FROM gyms WHERE gym_id = :gym_id LIMIT 1', ['gym_id' => $portal_id]);
+if($gym_statement->rowCount() == 1) {
+ $row = $gym_statement->fetch();
+ $update_where_condition = 'gym_id = :gym_id';
+ $update_values = '';
+}else {
+ // If portal id wasn't found, check by gym name
+ $gym_statement_by_name = my_query('SELECT id FROM gyms WHERE gym_name = :gym_name LIMIT 1', ['gym_name' => $gym_name_no_spec]);
+ $row = $gym_statement_by_name->fetch();
+ $update_where_condition = 'gym_name = :gym_name';
+ $update_values = 'gym_id = :gym_id, ';
+}
+
+// Gym already in database or new
+if (empty($row['id'])) {
+ // insert gym in table.
+ debug_log('Gym not found in database gym list! Inserting gym "' . $gym_name . '" now.');
+ $query = '
+ INSERT INTO gyms (gym_name, lat, lon, address, show_gym, img_url, gym_id)
+ VALUES (:gym_name, :lat, :lon, :address, 0, :gym_image, :gym_id)
+ ';
+ $msg = getTranslation('gym_added');
-?>
+} else {
+ // Update gyms table to reflect gym changes.
+ debug_log('Gym found in database gym list! Updating gym "' . $gym_name . '" now.');
+ $query = '
+ UPDATE gyms
+ SET lat = :lat,
+ lon = :lon,
+ gym_name = :gym_name,
+ address = :address,
+ ' . $update_values . '
+ img_url = :gym_image
+ WHERE ' . $update_where_condition . '
+ ';
+ $msg = getTranslation('gym_updated');
+ $gym_id = $row['id'];
+}
+
+// Insert / Update.
+$statement = my_query(
+ $query,[
+ 'gym_name' => $gym_name_no_spec,
+ 'lat' => $lat,
+ 'lon' => $lon,
+ 'address' => $address,
+ 'gym_image' => $gym_image,
+ 'gym_id' => $portal_id
+]);
+
+
+// Get last insert id.
+if (empty($row['id'])) {
+ $gym_id = $dbh->lastInsertId();
+}
+
+// Gym details.
+if($gym_id > 0) {
+ $gym = get_gym($gym_id);
+ $msg .= CR . CR . get_gym_details($gym);
+}
+
+// Gym photo.
+if($config->RAID_PICTURE_STORE_GYM_IMAGES_LOCALLY && $gym_image) {
+ $msg .= EMOJI_CAMERA . SP . $no_spaces_gym_name;
+}
+
+// Set keys.
+$keys[][] = button(getTranslation('delete'), ['gym_delete', 'fl' => $gym_name[0], 'g' => $gym_id, 'c' => 0]);
+$keys[][] = button(getTranslation('show_gym'), ['gym_edit_details', 'g' => $gym_id, 'a' => 'show', 'v' => 1]);
+$keys[][] = button(getTranslation('done'), ['exit', 'd' => '1']);
+
+// Send the message.
+send_message(create_chat_object([$update['message']['chat']['id']]), $msg, $keys, ['disable_web_page_preview' => 'true']);
diff --git a/mods/list_by_gym.php b/mods/list_by_gym.php
deleted file mode 100644
index cac040a2..00000000
--- a/mods/list_by_gym.php
+++ /dev/null
@@ -1,62 +0,0 @@
- 1) ? $args[1] : false;
-
-// Back key id, action and arg
-$back_id = 'n';
-$back_action = 'list_by_gym_letter';
-$back_arg = 0;
-
-// Get the keys.
-$keys = raid_edit_gym_keys($first, $gymarea_id, 'list_raid');
-
-// No keys found.
-if (!$keys) {
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
-} else {
- // Add navigation keys.
- $nav_keys = [];
- $nav_keys[] = universal_inner_key($nav_keys, $back_id, $back_action, $back_arg, getTranslation('back'));
- $nav_keys[] = universal_inner_key($nav_keys, '0', 'exit', '0', getTranslation('abort'));
- $nav_keys = inline_key_array($nav_keys, 2);
- // Merge keys.
- $keys = array_merge($keys, $nav_keys);
-}
-
-// Build callback message string.
-$callback_response = getTranslation('here_we_go');
-
-// Telegram JSON array.
-$tg_json = array();
-
-// Answer callback.
-$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
-
-// Edit the message.
-$tg_json[] = edit_message($update, getTranslation('select_gym_name'), $keys, false, true);
-
-// Telegram multicurl request.
-curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/list_by_gym_letter.php b/mods/list_by_gym_letter.php
deleted file mode 100644
index 24a703ad..00000000
--- a/mods/list_by_gym_letter.php
+++ /dev/null
@@ -1,72 +0,0 @@
- getTranslation('not_supported'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
-}
-
-// Build callback message string.
-$callback_response = getTranslation('select_gym');
-
-// Telegram JSON array.
-$tg_json = array();
-
-// Answer callback.
-$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
-
-// Edit the message.
-$msg = '' . getTranslation('list_all_active_raids') . '' . CR;
-if($config->ENABLE_GYM_AREAS) {
- if($keys_and_gymarea['gymarea_name'] == '') {
- $msg .= '' . getTranslation('select_gym_area') . '' . CR;
- }else {
- if($keys_and_gymarea['letters']) {
- $msg .= '' . getTranslation('select_gym_first_letter_or_gym_area') . '' . CR;
- }else {
- $msg .= '' . getTranslation('select_gym_name_or_gym_area') . '' . CR;
- }
- }
-}elseif($keys_and_gymarea['letters']) {
- $msg .= '' . getTranslation('select_gym_first_letter') . '' . CR;
-}else {
- $msg .= '' . getTranslation('select_gym_name') . '' . CR;
-}
-$msg.= (($keys_and_gymarea['gymarea_name'] != '') ? CR . CR . getTranslation('current_gymarea') . ': ' . $keys_and_gymarea['gymarea_name'] : '');
-$tg_json[] = edit_message($update, $msg, $keys, false, true);
-
-// Telegram multicurl request.
-curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/list_raid.php b/mods/list_raid.php
index e675a827..0dcf85ba 100644
--- a/mods/list_raid.php
+++ b/mods/list_raid.php
@@ -1,106 +1,97 @@
accessCheck('list');
// Get gym ID.
-$gym_id = $data['arg'];
-$raid_id = $data['id'];
+$gym_id = $data['g'] ?? 0;
+$raid_id = $data['r'] ?? 0;
// Get raid details.
if($raid_id != 0) {
- $sql_condition = 'AND raids.id = ? LIMIT 1';
- $binds = [$raid_id];
+ $sql_condition = 'AND raids.id = ? LIMIT 1';
+ $binds = [$raid_id];
}else {
- $sql_condition = 'AND gyms.id = ?';
- $binds = [$gym_id];
+ $eventQuery = 'event IS NULL';
+ if($botUser->accessCheck('ex-raids', true)) {
+ if($botUser->accessCheck('event-raids', true))
+ $eventQuery = '';
+ else
+ $eventQuery .= ' OR event = ' . EVENT_ID_EX;
+ }elseif($botUser->accessCheck('event-raids', true)) {
+ $eventQuery = 'event != ' . EVENT_ID_EX .' OR event IS NULL';
+ }
+ $eventQuery = ($eventQuery == '') ? ' ' : ' AND ('.$eventQuery.') ';
+ $sql_condition = 'AND gyms.id = ? ' . $eventQuery;
+ $binds = [$gym_id];
}
-$rs = my_query(
- "
- SELECT raids.id
- FROM raids
- LEFT JOIN gyms
- ON raids.gym_id = gyms.id
- WHERE end_time > UTC_TIMESTAMP() - INTERVAL 10 MINUTE
- {$sql_condition}
- ",
- $binds
+$rs = my_query('
+ SELECT raids.id
+ FROM raids
+ LEFT JOIN gyms
+ ON raids.gym_id = gyms.id
+ WHERE end_time > UTC_TIMESTAMP()
+ ' . $sql_condition
+ ,$binds
);
if($rs->rowcount() == 1) {
- // Get the row.
- $raid_fetch = $rs->fetch();
- $raid = get_raid($raid_fetch['id']);
+ // Get the row.
+ $raid_fetch = $rs->fetch();
+ $raid = get_raid($raid_fetch['id']);
- debug_log($raid);
+ debug_log($raid);
- // Create keys array.
- $keys = [
- [
- [
- 'text' => getTranslation('expand'),
- 'callback_data' => $raid['id'] . ':vote_refresh:0',
- ]
- ],
- [
- [
- 'text' => getTranslation('update_pokemon'),
- 'callback_data' => $raid['id'] . ':raid_edit_poke:' . $raid['level'],
- ]
- ],
- [
- [
- 'text' => getTranslation('delete'),
- 'callback_data' => $raid['id'] . ':raids_delete:0'
- ]
- ]
- ];
+ // Create keys array.
+ $keys = [];
+ // Probably unused feature. Will fix if someone needs this
+ // $keys[][] = button(getTranslation('expand'), ['vote_refresh', 'r' => $raid['id']]);
+ if($botUser->raidaccessCheck($raid['id'], 'pokemon', true)) {
+ $keys[][] = button(getTranslation('update_pokemon'), ['raid_edit_poke', 'r' => $raid['id'], 'rl' => $raid['level']]);
+ }
+ if($botUser->raidaccessCheck($raid['id'], 'delete', true)) {
+ $keys[][] = button(getTranslation('delete'), ['raids_delete', 'r' => $raid['id']]);
+ }
- // Add keys to share.
- debug_log($raid, 'raw raid data for share: ');
- $keys_share = share_keys($raid['id'], 'raid_share', $update, '', '', false, $raid['level']);
- if(is_array($keys_share)) {
- $keys = array_merge($keys, $keys_share);
- } else {
- debug_log('There are no groups to share to, is SHARE_CHATS set?');
- }
- // Exit key
- $empty_exit_key = [];
- $key_exit = universal_key($empty_exit_key, '0', 'exit', '1', getTranslation('done'));
- $keys = array_merge($keys, $key_exit);
+ // Add keys to share.
+ debug_log($raid, 'raw raid data for share: ');
+ $keys_share = share_keys($raid['id'], 'raid_share', $update, $raid['level']);
+ if(!empty($keys_share)) {
+ $keys = array_merge($keys, $keys_share);
+ } else {
+ debug_log('There are no groups to share to, is SHARE_CHATS set?');
+ }
+ // Exit key
+ $keys[][] = button(getTranslation('done'), ['exit', 'd' => 1]);
- // Get message.
- $msg = show_raid_poll_small($raid);
+ // Get message.
+ $msg = show_raid_poll_small($raid);
}else {
- $msg = getTranslation('list_all_active_raids').':'. CR;
- $keys = [];
- $i = 1;
- while($raid_fetch = $rs->fetch()) {
- $raid = get_raid($raid_fetch['id']);
- $raid_pokemon_name = get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form']);
- $msg .= '' . $i .'. ' . $raid_pokemon_name . '' . CR;
- if(!empty($raid['event_name'])) $msg .= $raid['event_name'] . CR;
- $msg .= get_raid_times($raid,false, true) . CR . CR;
- $keys[] = [
- [
- 'text' => $i . '. ' . $raid_pokemon_name,
- 'callback_data' => $raid['id'] . ':list_raid:0'
- ]
- ];
- $i++;
- }
- $keys[] = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => '0:list_by_gym:' . $raid['gym_name'][0]
- ]
- ];
+ $msg = getTranslation('list_all_active_raids').':'. CR;
+ $keys = [];
+ $i = 1;
+ while($raid_fetch = $rs->fetch()) {
+ $raid = get_raid($raid_fetch['id']);
+ $raid_pokemon_name = get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form']);
+ $msg .= '' . $i .'. ' . $raid_pokemon_name . '' . CR;
+ if(!empty($raid['event_name'])) $msg .= $raid['event_name'] . CR;
+ $msg .= get_raid_times($raid, $botUser->userLanguage, true) . CR . CR;
+ $keys[][] = button($i . '. ' . $raid_pokemon_name,['list_raid', 'r' => $raid['id']]);
+ $i++;
+ }
+ $backData = $data;
+ $backData[0] = 'gymMenu';
+ $backData['stage'] = 2;
+ $backData['a'] = 'list';
+ $keys[][] = button(getTranslation('back'), $backData);
}
// Build callback message string.
@@ -117,6 +108,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/list_remote_gyms.php b/mods/list_remote_gyms.php
index 24326b5d..1837f41d 100644
--- a/mods/list_remote_gyms.php
+++ b/mods/list_remote_gyms.php
@@ -6,30 +6,22 @@
//debug_log($update);
//debug_log($data);
-// Back key id, action and arg
-$back_id = 0;
-$back_action = 'list_by_gym_letter';
-$back_arg = 0;
-
$user_id = $update['callback_query']['from']['id'];
// Get the keys.
+$keys = [];
$query_remote = my_query('SELECT raids.id, gyms.gym_name, raids.start_time, raids.end_time FROM gyms LEFT JOIN raids on raids.gym_id = gyms.id WHERE raids.end_time > (UTC_TIMESTAMP() - INTERVAL 10 MINUTE) AND temporary_gym = 1');
while($gym = $query_remote->fetch()) {
- $keys[][] = [
- 'text' => $gym['gym_name'],
- 'callback_data' => $gym['id'] . ':list_raid:'
- ];
-}
+ $keys[][] = button($gym['gym_name'], ['list_raid', 'r' => $gym['id']]);
+}
// Add navigation keys.
$nav_keys = [];
-$nav_keys[] = universal_inner_key($nav_keys, $back_id, $back_action, $back_arg, getTranslation('back'));
-$nav_keys[] = universal_inner_key($nav_keys, '0', 'exit', '0', getTranslation('abort'));
+$nav_keys[] = button(getTranslation('back'), ['gymMenu', 'a' => 'list']);
+$nav_keys[] = button(getTranslation('abort'), 'exit');
$nav_keys = inline_key_array($nav_keys, 2);
// Merge keys.
$keys = array_merge($keys, $nav_keys);
-
// Build callback message string.
$callback_response = getTranslation('here_we_go');
@@ -44,6 +36,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/listall.php b/mods/listall.php
deleted file mode 100644
index 480eef17..00000000
--- a/mods/listall.php
+++ /dev/null
@@ -1,67 +0,0 @@
-' . getTranslation('list_all_active_raids') . '' . CR;
-if($config->ENABLE_GYM_AREAS) {
- if($keys_and_gymarea['gymarea_name'] == '') {
- $msg .= '' . getTranslation('select_gym_area') . '' . CR;
- }elseif($config->DEFAULT_GYM_AREA !== false) {
- if($keys_and_gymarea['letters']) {
- $msg .= '' . getTranslation('select_gym_first_letter_or_gym_area') . '' . CR;
- }else {
- $msg .= '' . getTranslation('select_gym_name_or_gym_area') . '' . CR;
- }
- }else {
- if($keys_and_gymarea['letters']) {
- $msg .= '' . getTranslation('select_gym_first_letter') . '' . CR;
- }else {
- $msg .= '' . getTranslation('select_gym_name') . '' . CR;
- }
- }
-}else {
- if($keys_and_gymarea['letters']) {
- $msg .= '' . getTranslation('select_gym_first_letter') . '' . CR;
- }else {
- $msg .= '' . getTranslation('select_gym_name') . '' . CR;
- }
-}
-$msg.= (($keys_and_gymarea['gymarea_name'] != '') ? CR . getTranslation('current_gymarea') . ': ' . $keys_and_gymarea['gymarea_name'] : '');
-$tg_json[] = edit_message($update, $msg, $keys, false, true);
-
-// Telegram multicurl request.
-curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/overview_delete.php b/mods/overview_delete.php
index 9c600bfe..ed20c4a8 100644
--- a/mods/overview_delete.php
+++ b/mods/overview_delete.php
@@ -1,115 +1,102 @@
accessCheck('overview');
// Telegram JSON array.
$tg_json = array();
// Get all or specific overview
-if ($chat_id == 0) {
- $request_overviews = my_query(
- "
- SELECT *
- FROM overview
- "
- );
-
- // Count results.
- $count = 0;
-
- while ($rowOverviews = $request_overviews->fetch()) {
- // Counter++
- $count = $count + 1;
-
- // Get info about chat for title.
- debug_log('Getting chat object for chat_id: ' . $rowOverviews['chat_id']);
- $chat_obj = get_chat($rowOverviews['chat_id']);
- $chat_title = '';
-
- // Set title.
- if ($chat_obj['ok'] == 'true') {
- $chat_title = $chat_obj['result']['title'];
- debug_log('Title of the chat: ' . $chat_obj['result']['title']);
- }
-
- // Build message string.
- $msg = '' . getTranslation('delete_raid_overview_for_chat') . ' ' . $chat_title . '?';
-
- // Set keys - Delete button.
- $keys = [
- [
- [
- 'text' => getTranslation('yes'),
- 'callback_data' => '0:overview_delete:' . $rowOverviews['chat_id']
- ],
- [
- 'text' => getTranslation('no'),
- 'callback_data' => '0:overview_delete:1'
- ]
- ]
- ];
-
- // Send the message, but disable the web preview!
- $tg_json[] = send_message($update['callback_query']['message']['chat']['id'], $msg, $keys, false, true);
+if ($action == 0) {
+ $request_overviews = my_query('
+ SELECT *
+ FROM overview
+ ');
+
+ while ($rowOverviews = $request_overviews->fetch()) {
+
+ // Get info about chat for title.
+ debug_log('Getting chat object for chat_id: ' . $rowOverviews['chat_id']);
+ $chat_obj = get_config_chat_by_chat_and_thread_id($rowOverviews['chat_id'], $rowOverviews['thread_id']);
+ if(!isset($chat_obj['title'])) {
+ $chat_info = get_chat($rowOverviews['chat_id']);
+ $chat_title = '';
+
+ // Set title.
+ if ($chat_info['ok'] == 'true') {
+ $chat_title = $chat_info['result']['title'];
+ debug_log('Title of the chat: ' . $chat_info['result']['title']);
+ }
+ }else {
+ $chat_title = $chat_obj['title'];
}
- // Set message.
- if($count == 0) {
- $callback_msg = '' . getTranslation('no_overviews_found') . '';
- } else {
- $callback_msg = '' . getTranslation('list_all_overviews') . ':';
- }
-} else if ($chat_id == 1) {
- // Write to log.
- debug_log('Deletion of the raid overview was canceled!');
-
- // Set message.
- $callback_msg = '' . getTranslation('overview_deletion_was_canceled') . '';
+ // Build message string.
+ $msg = '' . getTranslation('delete_raid_overview_for_chat') . ' ' . $chat_title . '?';
+
+ // Set keys - Delete button.
+ $keys[0][0] = button(getTranslation('yes'), ['overview_delete', 'o' => $rowOverviews['id'], 'a' => 3]);
+ $keys[0][1] = button(getTranslation('no'), ['overview_delete', 'a' => 1]);
+
+ // Send the message, but disable the web preview!
+ $tg_json[] = send_message(create_chat_object([$update['callback_query']['message']['chat']['id']]), $msg, $keys, false, true);
+ }
+
+ // Set message.
+ if($request_overviews->rowCount() == 0) {
+ $callback_msg = '' . getTranslation('no_overviews_found') . '';
+ } else {
+ $callback_msg = '' . getTranslation('list_all_overviews') . ':';
+ }
+} else if ($action == 1) {
+ // Write to log.
+ debug_log('Deletion of the raid overview was canceled!');
+
+ // Set message.
+ $callback_msg = '' . getTranslation('overview_deletion_was_canceled') . '';
} else {
- // Write to log.
- debug_log('Triggering deletion of overview for Chat_ID ' . $chat_id);
-
- // Get chat and message ids for overview.
- $request_overviews = my_query(
- "
- SELECT *
- FROM overview
- WHERE chat_id = '{$chat_id}'
- "
- );
-
- $overview = $request_overviews->fetch();
-
- // Delete overview
- $chat_id = $overview['chat_id'];
- $message_id = $overview['message_id'];
-
- // Delete telegram message.
- debug_log('Deleting overview telegram message ' . $message_id . ' from chat ' . $chat_id);
- delete_message($chat_id, $message_id);
-
- // Delete overview from database.
- debug_log('Deleting overview information from database for Chat_ID: ' . $chat_id);
- $rs = my_query(
- "
- DELETE FROM overview
- WHERE chat_id = '{$chat_id}'
- "
- );
-
- // Set message.
- $callback_msg = '' . getTranslation('overview_successfully_deleted') . '';
+
+ // Get chat and message ids for overview.
+ $request_overviews = my_query('
+ SELECT *
+ FROM overview
+ WHERE id = ?
+ ', [$overview_id]
+ );
+
+ $overview = $request_overviews->fetch();
+
+ // Delete overview
+ $chat_id = $overview['chat_id'];
+ $message_id = $overview['message_id'];
+ // Write to log.
+ debug_log('Triggering deletion of overview for Chat_ID ' . $chat_id);
+
+ // Delete telegram message.
+ debug_log('Deleting overview telegram message ' . $message_id . ' from chat ' . $chat_id);
+ delete_message($chat_id, $message_id);
+
+ // Delete overview from database.
+ debug_log('Deleting overview information from database for Chat_ID: ' . $chat_id . ', thread_id: ' . $overview['thread_id']);
+ $rs = my_query('
+ DELETE FROM overview
+ WHERE id = ?
+ ', [$overview_id]
+ );
+
+ // Set message.
+ $callback_msg = '' . getTranslation('overview_successfully_deleted') . '';
}
// Set keys.
@@ -126,7 +113,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-$dbh = null;
-exit();
diff --git a/mods/overview_refresh.php b/mods/overview_refresh.php
index 2428bba1..9fc18d8e 100644
--- a/mods/overview_refresh.php
+++ b/mods/overview_refresh.php
@@ -1,6 +1,8 @@
fetchAll();
@@ -31,71 +30,67 @@
$active_raids = [];
$tg_json = [];
foreach($overviews as $overview_row) {
- $request_raids = my_query('
- SELECT raids.pokemon, raids.pokemon_form, raids.spawn, raids.level, raids.id, raids.start_time, raids.end_time, raids.gym_id,
- MAX(cleanup.message_id) as message_id,
- events.name as event_name,
- gyms.lat, gyms.lon, gyms.address, gyms.gym_name, gyms.ex_gym,
- TIME_FORMAT(TIMEDIFF(end_time, UTC_TIMESTAMP()) + INTERVAL 1 MINUTE, \'%k:%i\') AS t_left
- FROM cleanup
- LEFT JOIN raids
- ON raids.id = cleanup.raid_id
- LEFT JOIN gyms
- ON raids.gym_id = gyms.id
- LEFT JOIN events
- ON events.id = raids.event
- WHERE cleanup.chat_id = \'' . $overview_row['chat_id'] . '\'
- AND raids.end_time>UTC_TIMESTAMP()
- GROUP BY raids.id, raids.pokemon, raids.pokemon_form, raids.start_time, raids.end_time, raids.gym_id, gyms.lat, gyms.lon, gyms.address, gyms.gym_name, gyms.ex_gym, events.name
- ORDER BY raids.end_time ASC, gyms.gym_name
- ');
- // Write active raids to array
- $active_raids = $request_raids->fetchAll();
- debug_log('Active raids:');
- debug_log($active_raids);
+ $request_raids = my_query('
+ SELECT raids.pokemon, raids.pokemon_form, raids.spawn, raids.level, raids.id, raids.start_time, raids.end_time, raids.gym_id,
+ MAX(cleanup.message_id) as message_id,
+ events.name as event_name,
+ gyms.lat, gyms.lon, gyms.address, gyms.gym_name, gyms.ex_gym,
+ TIME_FORMAT(TIMEDIFF(end_time, UTC_TIMESTAMP()) + INTERVAL 1 MINUTE, \'%k:%i\') AS t_left
+ FROM cleanup
+ LEFT JOIN raids
+ ON raids.id = cleanup.raid_id
+ LEFT JOIN gyms
+ ON raids.gym_id = gyms.id
+ LEFT JOIN events
+ ON events.id = raids.event
+ WHERE cleanup.chat_id = ?
+ AND raids.end_time>UTC_TIMESTAMP()
+ GROUP BY raids.id, raids.pokemon, raids.pokemon_form, raids.start_time, raids.end_time, raids.gym_id, gyms.lat, gyms.lon, gyms.address, gyms.gym_name, gyms.ex_gym, events.name
+ ORDER BY raids.end_time ASC, gyms.gym_name
+ ', [$overview_row['chat_id']]
+ );
+ // Write active raids to array
+ $active_raids = $request_raids->fetchAll();
+ debug_log('Active raids:');
+ debug_log($active_raids);
- if($overview_row['update_needed'] == 1) {
- $chat_title_username = get_chat_title_username($overview_row['chat_id']);
- $chat_title = $chat_title_username[0];
- $chat_username = $chat_title_username[1];
- my_query('
- UPDATE overview
- SET chat_title = \''.$chat_title.'\',
- chat_username = \''.$chat_username.'\',
- updated = DATE(NOW())
- WHERE chat_id = \''.$overview_row['chat_id'].'\'
- ');
- }else {
- $chat_title = $overview_row['chat_title'];
- $chat_username = $overview_row['chat_username'];
- }
- $overview_message = get_overview($active_raids, $chat_title, $chat_username);
- // Triggered from user or cronjob?
- if (!empty($update['callback_query']['id'])) {
- // Answer the callback.
- answerCallbackQuery($update['callback_query']['id'], 'OK');
- $message_id = $update['callback_query']['message']['message_id'];
- $chat_id = $update['callback_query']['from']['id'];
- $keys[] = [
- [
- 'text' => EMOJI_REFRESH,
- 'callback_data' => '0:overview_refresh:' . $overview_row['chat_id']
- ],
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ];
- }else {
- $message_id = $overview_row['message_id'];
- $chat_id = $overview_row['chat_id'];
- $keys = [];
+ if($overview_row['update_needed'] == 1) {
+ [$chat_title, $chat_username] = get_chat_title_username($overview_row['chat_id']);
+ if($chat_title != '' && $chat_username != '') {
+ my_query('
+ UPDATE overview
+ SET chat_title = ?,
+ chat_username = ?,
+ updated = DATE(NOW())
+ WHERE chat_id = ?
+ ',[$chat_title, $chat_username, $overview_row['chat_id']]
+ );
}
+ }else {
+ $chat_title = $overview_row['chat_title'];
+ $chat_username = $overview_row['chat_username'];
+ }
+ $overview_message = get_overview($active_raids, $chat_title, $chat_username);
+ // Triggered from user or cronjob?
+ if (!empty($update['callback_query']['id'])) {
+ // Answer the callback.
+ answerCallbackQuery($update['callback_query']['id'], 'OK');
+ $message_id = $update['callback_query']['message']['message_id'];
+ $chat_id = $update['callback_query']['from']['id'];
+ $keys[] = [
+ button(EMOJI_REFRESH, ['overview_refresh', 'c' => $overview_row['chat_id']]),
+ button(getTranslation('done'), ['exit', 'd' => '1'])
+ ];
+ }else {
+ $message_id = $overview_row['message_id'];
+ $chat_id = $overview_row['chat_id'];
+ $keys = [];
+ }
- $tg_json[] = editMessageText($message_id, $overview_message, $keys, $chat_id, ['disable_web_page_preview' => 'true'], true);
+ $tg_json[] = editMessageText($message_id, $overview_message, $keys, $chat_id, ['disable_web_page_preview' => 'true'], true);
}
// Telegram multicurl request.
curl_json_multi_request($tg_json);
$dbh=null;
-exit;
\ No newline at end of file
+exit;
diff --git a/mods/overview_share.php b/mods/overview_share.php
index 2e4aedf6..6bc7d2ee 100644
--- a/mods/overview_share.php
+++ b/mods/overview_share.php
@@ -1,123 +1,107 @@
accessCheck('overview');
// Get chat ID from data
-$chat_id = 0;
-$chat_id = $data['arg'];
-
-// Get all or specific overview
-$query_chat = "";
-if ($chat_id != 0) {
- $query_chat = "AND chat_id = '{$chat_id}'";
-}
-// Get active raids.
-$request_active_raids = my_query(
- "
- SELECT
- cleanup.chat_id, cleanup.message_id,
- raids.*,
- gyms.lat, gyms.lon, gyms.address, gyms.gym_name, gyms.ex_gym,
- TIME_FORMAT(TIMEDIFF(end_time, UTC_TIMESTAMP()) + INTERVAL 1 MINUTE, '%k:%i') AS t_left
- FROM cleanup
- LEFT JOIN raids
- ON raids.id = cleanup.raid_id
- LEFT JOIN gyms
- ON raids.gym_id = gyms.id
- WHERE raids.end_time>UTC_TIMESTAMP()
- {$query_chat}
- ORDER BY cleanup.chat_id, raids.end_time ASC, gyms.gym_name
- "
-);
-// Collect results in an array
-$active_raids = $request_active_raids->fetchAll(PDO::FETCH_GROUP);
+$chat_id = $data['c'] ?? NULL;
$tg_json = [];
// Share an overview
-if($chat_id != 0) {
- $chat_title_username = get_chat_title_username($chat_id);
- $overview_message = get_overview($active_raids[$chat_id], $chat_title_username[1], $chat_title_username[0]);
- // Shared overview
- $keys = [];
+if($chat_id != NULL) {
+ $query_chat = '';
+ $chatObj = get_config_chat_by_short_id($chat_id);
+ $query_chat = 'AND chat_id = ?';
+ $binds[] = $chatObj['id'];
+ if(isset($chatObj['thread'])) {
+ $query_chat .= ' AND thread_id = ?';
+ $binds[] = $chatObj['thread'];
+ }
+ // Get active raids.
+ $request_active_raids = my_query('
+ SELECT
+ cleanup.chat_id, cleanup.thread_id, cleanup.message_id,
+ raids.*,
+ gyms.lat, gyms.lon, gyms.address, gyms.gym_name, gyms.ex_gym,
+ TIME_FORMAT(TIMEDIFF(end_time, UTC_TIMESTAMP()) + INTERVAL 1 MINUTE, \'%k:%i\') AS t_left
+ FROM cleanup
+ LEFT JOIN raids
+ ON raids.id = cleanup.raid_id
+ LEFT JOIN gyms
+ ON raids.gym_id = gyms.id
+ WHERE raids.end_time>UTC_TIMESTAMP()
+ ' . $query_chat . '
+ ORDER BY cleanup.chat_id, raids.end_time ASC, gyms.gym_name
+ ', $binds);
+ // Collect results in an array
+ $active_raids = $request_active_raids->fetchAll();
+ [$chat_title, $chat_username] = get_chat_title_username($chatObj['id']);
+ $title = $chatObj['title'] ?? $chat_title;
+ $overview_message = get_overview($active_raids, $title, $chat_username);
+ // Shared overview
+ $keys = [];
- // Set callback message string.
- $msg_callback = getTranslation('successfully_shared');
+ // Set callback message string.
+ $msg_callback = getTranslation('successfully_shared');
- // Answer the callback.
- $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $msg_callback, true);
+ // Answer the callback.
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $msg_callback, true);
- // Edit the message, but disable the web preview!
- $tg_json[] = edit_message($update, $msg_callback, $keys, ['disable_web_page_preview' => 'true'], true);
+ // Edit the message, but disable the web preview!
+ $tg_json[] = edit_message($update, $msg_callback, $keys, ['disable_web_page_preview' => 'true'], true);
- // Send the message, but disable the web preview!
- $tg_json[] = send_message($chat_id, $overview_message, $keys, ['disable_web_page_preview' => 'true'], true, 'overview');
-}else {
- // List all overviews to user
- foreach( array_keys($active_raids) as $chat_id ) {
- // Make sure it's not already shared
- $rs = my_query(
- "
- SELECT chat_id, message_id, chat_title, chat_username
- FROM overview
- WHERE chat_id = '{$chat_id}'
- LIMIT 1
- "
- );
- // Already shared
- if($rs->rowCount() > 0 ) {
- $keys = [
- [
- [
- 'text' => EMOJI_REFRESH,
- 'callback_data' => '0:overview_refresh:' . $chat_id
- ],
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ]
- ];
- $res = $rs->fetch();
- $chat_title = $res['chat_title'];
- $chat_username = $res['chat_username'];
- }else {
- $chat_title_username = get_chat_title_username($chat_id);
- $chat_title = $chat_title_username[0];
- $chat_username = $chat_title_username[1];
- $keys = [
- [
- [
- 'text' => getTranslation('share_with') . ' ' . $chat_title,
- 'callback_data' => '0:overview_share:' . $chat_id
- ]
- ]
- ];
- }
- $overview_message = get_overview($active_raids[$chat_id], $chat_title, $chat_username);
- // Send the message, but disable the web preview!
- $tg_json[] = send_message($update['callback_query']['message']['chat']['id'], $overview_message, $keys, ['disable_web_page_preview' => 'true'], true);
- }
- // Set the callback message and keys
- $callback_keys = [];
- $callback_msg = '' . getTranslation('list_all_overviews') . ':';
+ // Send the message, but disable the web preview!
+ $tg_json[] = send_message($chatObj, $overview_message, $keys, ['disable_web_page_preview' => 'true'], true, 'overview');
+ // Telegram multicurl request.
+ curl_json_multi_request($tg_json);
- // Answer the callback.
- $tg_json[] = answerCallbackQuery($update['callback_query']['id'], 'OK', true);
+ exit;
+}
+$keys = [];
+// List all overviews to user
+foreach( list_config_chats_by_short_id() as $short_id => $chat ) {
+ $binds = [$chat['id']];
+ $threadQuery = ' = ?';
+ if(!isset($chat['thread']) or $chat['thread'] == 0) {
+ $threadQuery = 'IS NULL';
+ }else {
+ $binds[] = $chat['thread'];
+ }
+ // Make sure it's not already shared
+ $rs = my_query('
+ SELECT chat_id, thread_id, message_id, chat_title, chat_username
+ FROM overview
+ WHERE chat_id = ?
+ AND thread_id ' . $threadQuery . '
+ LIMIT 1
+ ', $binds
+ );
+ // Already shared
+ if($rs->rowCount() > 0 ) continue;
- // Edit the message.
- $tg_json[] = edit_message($update, $callback_msg, $callback_keys, false, true);
+ [$chat_title, $chat_username] = get_chat_title_username($chat['id']);
+ $title = $chat['title'] ?? $chat_title;
+ $keys[][] = button(getTranslation('share_with') . ' ' . $title, ['overview_share', 'c' => $short_id]);
}
+// Set the callback message and keys
+$msg = '' . getTranslation('list_all_overviews') . ':';
+$keys[][] = button(getTranslation('abort'), ['exit', 'd' => '0']);
+
+// Answer the callback.
+$tg_json[] = answerCallbackQuery($update['callback_query']['id'], 'OK', true);
+
+// Edit the message.
+$tg_json[] = edit_message($update, $msg, $keys, false, true);
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-$dbh = null;
-exit;
\ No newline at end of file
diff --git a/mods/pogoinfo.php b/mods/pogoinfo.php
index 47f1c840..4ee997cb 100644
--- a/mods/pogoinfo.php
+++ b/mods/pogoinfo.php
@@ -1,344 +1,228 @@
accessCheck('pokedex');
// Levels available for import
$levels = array('6', '5', '3', '1');
-
-// Get raid levels
-$id = $data['id'];
-
-// Exclude pokemon
-$arg = $data['arg'];
+$id = $data['rl'] ?? 0;
+$action = $data['a'] ?? '';
// Raid level selection
if($id == 0) {
- // Set message.
- $msg = '' . getTranslation('import') . SP . '(ccev pogoinfo)' . '' . CR . CR;
- $msg .= '' . getTranslation('select_raid_level') . ':';
-
- // Init empty keys array.
- $keys = [];
-
- // All raid level keys.
- $keys[][] = array(
- 'text' => getTranslation('pokedex_all_raid_level'),
- 'callback_data' => RAID_LEVEL_ALL . ':pogoinfo:ex#0,0,0'
- );
-
- // Add key for each raid level
- foreach($levels as $l) {
- $keys[][] = array(
- 'text' => getTranslation($l . 'stars'),
- 'callback_data' => $l . ':pogoinfo:ex#0,0,0'
- );
- }
- $keys[][] = array(
- 'text' => getTranslation('1stars') . ' & ' . getTranslation('3stars'),
- 'callback_data' => '3,1:pogoinfo:ex#0,0,0'
- );
-
- // Add back and abort buttons
- $keys[] = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => '0:pokedex_import:0'
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
-
-} else if($id > 0) {
- // Set message and init message to exclude raid bosses.
- $msg = '' . getTranslation('import') . SP . '(ccev pogoinfo)' . '' . CR . CR;
- $ex_msg = '';
-
- // Get pogoinfo data.
- debug_log('Getting raid bosses from pogoinfo repository now...');
- $link = 'https://raw.githubusercontent.com/ccev/pogoinfo/v2/active/raids.json';
- $data = curl_get_contents($link);
- $data = json_decode($data,true);
-
- // All raid levels?
- if($id == RAID_LEVEL_ALL) {
- $get_levels = $levels;
- $clear = "'6','5','3','1'";
- } else {
- $get_levels = explode(",", $id);
- $clear = $id;
- }
+ // Set message.
+ $msg = '' . getTranslation('import') . SP . '(ccev pogoinfo)' . '' . CR . CR;
+ $msg .= '' . getTranslation('select_raid_level') . ':';
+
+ // Init empty keys array.
+ $keys = [];
+
+ // All raid level keys.
+ $keys[][] = button(getTranslation('pokedex_all_raid_level'), ['pogoinfo', 'rl' => 'all']);
+
+ // Add key for each raid level
+ foreach($levels as $l) {
+ $keys[][] = button(getTranslation($l . 'stars'), ['pogoinfo', 'rl' => $l]);
+ }
+ $keys[][] = button(getTranslation('1stars') . ' & ' . getTranslation('3stars'), ['pogoinfo', 'rl' => '1,3']);
+
+ // Add back and abort buttons
+ $keys[] = [
+ button(getTranslation('back'), 'pokedex_import'),
+ button(getTranslation('abort'), 'exit')
+ ];
+
+ // Callback message string.
+ $callback_response = 'OK';
+
+ // Telegram JSON array.
+ $tg_json = array();
+
+ // Answer callback.
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
+
+ // Edit message.
+ $tg_json[] = edit_message($update, $msg, $keys, false, true);
+
+ // Telegram multicurl request.
+ curl_json_multi_request($tg_json);
+ exit;
+}
+// Set message and init message to exclude raid bosses.
+$msg = '' . getTranslation('import') . SP . '(ccev pogoinfo)' . '' . CR . CR;
+$ex_msg = '';
+
+// Get pogoinfo data.
+debug_log('Getting raid bosses from pogoinfo repository now...');
+$link = 'https://raw.githubusercontent.com/ccev/pogoinfo/v2/active/raids.json';
+$raiddata = curl_get_contents($link);
+$raiddata = json_decode($raiddata,true);
+
+// All raid levels?
+if($id == 'all') {
+ $get_levels = $levels;
+ $clear = "'6','5','3','1'";
+} else {
+ $get_levels = explode(",", $id);
+ $clear = $id;
+}
+
+// New request
+$exclusions = isset($data['e']) ? explode('#', $data['e']) : [];
+if(!empty($exclusions[0])) {
+ debug_log('Excluded raid bosses: ' . implode(', ', $exclusions));
+}
- // Prefix for exclusion.
- $prefix = 'ex#';
-
- // New request
- if($arg == 'ex#0,0,0') {
- $poke1 = 0;
- $poke2 = 0;
- $poke3 = 0;
-
- // Get raid bosses to exclude.
- } else if(strpos($arg, 'ex#') === 0 || strpos($arg, 'save#') === 0) {
- $poke_ids = explode('#', $arg);
- $poke_ids = explode(',', $poke_ids[1]);
- $poke1 = $poke_ids[0];
- $poke2 = $poke_ids[1];
- $poke3 = $poke_ids[2];
- debug_log('Excluded raid boss #1: ' . $poke1);
- debug_log('Excluded raid boss #2: ' . $poke2);
- debug_log('Excluded raid boss #3: ' . $poke3);
+// Clear old raid bosses.
+if($action == 's') {
+ require_once(LOGIC_PATH . '/disable_raid_level.php');
+ debug_log('Disabling old raid bosses for levels: '. $clear);
+ disable_raid_level($clear);
+}
+
+// Raid tier array
+debug_log('Processing the following raid levels:');
+debug_log($get_levels);
+
+// Process raid tier(s)
+debug_log('Processing received ccev pogoinfo raid bosses for each raid level');
+foreach($raiddata as $tier => $tier_pokemon) {
+ // Process raid level?
+ if(!in_array($tier,$get_levels)) {
+ continue;
+ }
+ // Raid level and message.
+ $msg .= '' . getTranslation('pokedex_raid_level') . SP . $tier . ':' . CR;
+
+ // Count raid bosses and add raid egg later if 2 or more bosses.
+ $bosscount = 0;
+
+ // Get raid bosses for each raid level.
+ foreach($tier_pokemon as $raid_id_form) {
+ if(!isset($raid_id_form['id'])) continue;
+ $dex_id = $raid_id_form['id'];
+ $dex_form = 0;
+ if(isset($raid_id_form['temp_evolution_id'])) {
+ $dex_form = '-'.$raid_id_form['temp_evolution_id'];
+ }elseif(isset($raid_id_form['form'])) {
+ $dex_form = $raid_id_form['form'];
+ }else {
+ // If no form id is provided, let's check our db for normal form
+ $query_form_id = my_query('SELECT pokemon_form_id FROM pokemon WHERE pokedex_id = ? and pokemon_form_name = \'normal\' LIMIT 1', [$dex_id]);
+ if($query_form_id->rowCount() == 0) {
+ // If normal form doesn't exist in our db, use the smallest form id as a fallback
+ $query_form_id = my_query('SELECT min(pokemon_form_id) as pokemon_form_id FROM pokemon WHERE pokedex_id = ? LIMIT 1', [$dex_id]);
+ }
+ $result = $query_form_id->fetch();
+ $dex_form = $result['pokemon_form_id'];
}
- // Clear old raid bosses.
- if(strpos($arg, 'save#') === 0) {
- debug_log('Disabling old raid bosses for levels: '. $clear);
- disable_raid_level($clear);
+ $pokemon_arg = $dex_id . $dex_form;
+
+ // Make sure we received a valid dex id.
+ if(!is_numeric($dex_id) || $dex_id == 0) {
+ info_log('Failed to get a valid pokemon dex id: '. $dex_id .' Continuing with next raid boss...');
+ continue;
}
- // Init empty keys array.
- $keys = [];
-
- // Raid tier array
- debug_log('Processing the following raid levels:');
- debug_log($get_levels);
-
- // Process raid tier(s)
- debug_log('Processing received ccev pogoinfo raid bosses for each raid level');
- foreach($data as $tier => $tier_pokemon) {
- // Process raid level?
- if(!in_array($tier,$get_levels)) {
- continue;
- }
- // Raid level and message.
- $msg .= '' . getTranslation('pokedex_raid_level') . SP . $tier . ':' . CR;
-
- // Count raid bosses and add raid egg later if 2 or more bosses.
- $bosscount = 0;
-
- // Get raid bosses for each raid level.
- foreach($tier_pokemon as $raid_id_form) {
- $dex_id = $raid_id_form['id'];
- $dex_form = 0;
- if(isset($raid_id_form['temp_evolution_id'])) {
- $dex_form = '-'.$raid_id_form['temp_evolution_id'];
- }elseif(isset($raid_id_form['form'])) {
- $dex_form = $raid_id_form['form'];
- }else {
- // If no form id is provided, let's check our db for normal form
- $query_form_id = my_query("SELECT pokemon_form_id FROM pokemon WHERE pokedex_id='".$dex_id."' and pokemon_form_name='normal' LIMIT 1");
- if($query_form_id->rowCount() == 0) {
- // If normal form doesn't exist in our db, use the smallest form id as a fallback
- $query_form_id = my_query("SELECT min(pokemon_form_id) as pokemon_form_id FROM pokemon WHERE pokedex_id='".$dex_id."' LIMIT 1");
- }
- $result = $query_form_id->fetch();
- $dex_form = $result['pokemon_form_id'];
- }
-
- $pokemon_arg = $dex_id . $dex_form;
-
- // Get ID and form name used internally.
- $local_pokemon = get_local_pokemon_name($dex_id, $dex_form);
- debug_log('Got this pokemon dex id: ' . $dex_id);
- debug_log('Got this pokemon dex form: ' . $dex_form);
- debug_log('Got this local pokemon name and form: ' . $local_pokemon);
-
- // Make sure we received a valid dex id.
- if(!is_numeric($dex_id) || $dex_id == 0) {
- info_log('Failed to get a valid pokemon dex id: '. $dex_id .' Continuing with next raid boss...');
- continue;
- }
-
- // Build new arg.
- // Exclude 1 pokemon
- if($poke1 == '0') {
- $new_arg = $prefix . $pokemon_arg . ',0,0';
-
- // Exclude 2 pokemon
- } else if ($poke1 != '0' && $poke2 == '0') {
- $new_arg = $prefix . $poke1 . ',' . $pokemon_arg . ',0';
-
- // Exclude 3 pokemon
- } else if ($poke1 != '0' && $poke2 != '0' && $poke3 == '0') {
- $new_arg = $prefix . $poke1 . ',' . $poke2 . ',' . $pokemon_arg;
- }
-
- // Exclude pokemon?
- if($pokemon_arg == $poke1 || $pokemon_arg == $poke2 || $pokemon_arg == $poke3) {
- // Add pokemon to exclude message.
- $ex_msg .= $local_pokemon . SP . '(#' . $dex_id . ')' . CR;
-
- } else {
- // Add pokemon to message.
- $msg .= $local_pokemon . SP . '(#' . $dex_id . ')' . CR;
-
- // Counter.
- $bosscount = $bosscount + 1;
-
- // Save to database?
- if(strpos($arg, 'save#') === 0) {
- // Update raid level of pokemon
- my_query(
- "
- INSERT INTO raid_bosses (pokedex_id, pokemon_form_id, raid_level)
- VALUES ('{$dex_id}', '{$dex_form}', '{$tier}')
- "
- );
- continue;
- }
-
- // Are 3 raid bosses already selected?
- if($poke1 == '0' || $poke2 == '0' || $poke3 == '0') {
- // Add raid level to pokemon name
- if($id == RAID_LEVEL_ALL) {
- // Add key to exclude pokemon from import.
- $keys[] = array(
- 'text' => '[' . ($tier) . ']' . SP . $local_pokemon,
- 'callback_data' => $id . ':pogoinfo:' . $new_arg
- );
- } else {
- // Add key to exclude pokemon from import.
- $keys[] = array(
- 'text' => $local_pokemon,
- 'callback_data' => $id . ':pogoinfo:' . $new_arg
- );
- }
- }
- }
- }
-
- $msg .= CR;
+ // Save to database?
+ if($action == 's') {
+ // Update raid level of pokemon
+ my_query('
+ INSERT INTO raid_bosses (pokedex_id, pokemon_form_id, raid_level)
+ VALUES (?, ?, ?)
+ ', [$dex_id, $dex_form, $tier]
+ );
}
- // Get the inline key array.
- $keys = inline_key_array($keys, 2);
-
- // Saved raid bosses?
- if(strpos($arg, 'save#') === 0) {
- // Get all pokemon with raid levels from database.
- $rs = my_query(
- "
- SELECT raid_bosses.pokedex_id, raid_bosses.pokemon_form_id, raid_bosses.raid_level
- FROM raid_bosses
- LEFT JOIN pokemon
- ON raid_bosses.pokedex_id = pokemon.pokedex_id
- AND raid_bosses.pokemon_form_id = pokemon.pokemon_form_id
- WHERE raid_bosses.raid_level IN ({$clear})
- AND raid_bosses.scheduled = 0
- ORDER BY raid_bosses.raid_level, raid_bosses.pokedex_id, pokemon.pokemon_form_name != 'normal', pokemon.pokemon_form_name, raid_bosses.pokemon_form_id
- "
- );
-
- // Init empty keys array.
- $keys = [];
-
- // Init message and previous.
- $msg = 'Pogoinfo' . SP . '—' . SP . getTranslation('import_done') . '' . CR;
- $previous = '';
-
- // Build the message
- while ($pokemon = $rs->fetch()) {
- // Set current level
- $current = $pokemon['raid_level'];
-
- // Add header for each raid level
- if($previous != $current) {
- $msg .= CR . '' . getTranslation($pokemon['raid_level'] . 'stars') . ':' . CR ;
- }
-
- // Add pokemon with id and name.
- $dex_id = $pokemon['pokedex_id'];
- $pokemon_form_id = $pokemon['pokemon_form_id'];
- $poke_name = get_local_pokemon_name($dex_id, $pokemon_form_id);
- $msg .= $poke_name . ' (#' . $dex_id . ')' . CR;
-
- // Add button to edit pokemon.
- if($id == RAID_LEVEL_ALL) {
- $keys[] = array(
- 'text' => '[' . $pokemon['raid_level'] . ']' . SP . $poke_name,
- 'callback_data' => $dex_id . "-" . $pokemon_form_id . ':pokedex_edit_pokemon:0'
- );
- } else {
- $keys[] = array(
- 'text' => $poke_name,
- 'callback_data' => $dex_id . "-" . $pokemon_form_id . ':pokedex_edit_pokemon:0'
- );
- }
-
- // Prepare next run.
- $previous = $current;
- }
-
- // Inline key array.
- $keys = inline_key_array($keys, 2);
-
- // Navigation keys.
- $nav_keys = [];
-
- // Abort button.
- $nav_keys[] = array(
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- );
-
- // Keys.
- $nav_keys = inline_key_array($nav_keys, 1);
- $keys = array_merge($keys, $nav_keys);
-
- // User is still on the import.
+ // Get ID and form name used internally.
+ $local_pokemon = get_local_pokemon_name($dex_id, $dex_form);
+ debug_log('Got this pokemon dex id: ' . $dex_id);
+ debug_log('Got this pokemon dex form: ' . $dex_form);
+ debug_log('Got this local pokemon name and form: ' . $local_pokemon);
+
+ // Exclude pokemon?
+ if(in_array($pokemon_arg, $exclusions)) {
+ // Add pokemon to exclude message.
+ $ex_msg .= $local_pokemon . SP . '(#' . $dex_id . ')' . CR;
+
} else {
- $msg .= '' . getTranslation('excluded_raid_bosses') . '' . CR;
- $msg .= (empty($ex_msg) ? (getTranslation('none') . CR) : $ex_msg) . CR;
-
- // Import or select more pokemon to exclude?
- if($poke1 == '0' || $poke2 == '0' || $poke3 == '0') {
- $msg .= '' . getTranslation('exclude_raid_boss_or_import') . ':';
- } else {
- $msg .= '' . getTranslation('import_raid_bosses') . '';
- }
-
- // Navigation keys.
- $nav_keys = [];
-
- // Back button.
- $nav_keys[] = array(
- 'text' => getTranslation('back'),
- 'callback_data' => '0:pogoinfo:0'
- );
-
- // Save button.
- $nav_keys[] = array(
- 'text' => EMOJI_DISK,
- 'callback_data' => $id . ':pogoinfo:save#' . $poke1 . ',' . $poke2 . ',' . $poke3
- );
-
- // Reset button.
- if($poke1 != 0) {
- $nav_keys[] = array(
- 'text' => getTranslation('reset'),
- 'callback_data' => $id . ':pogoinfo:ex#0,0,0'
- );
- }
-
- // Abort button.
- $nav_keys[] = array(
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- );
-
- // Get the inline key array and merge keys.
- $nav_keys = inline_key_array($nav_keys, 2);
- $keys = array_merge($keys, $nav_keys);
+ // Add pokemon to message.
+ $msg .= $local_pokemon . SP . '(#' . $dex_id . ')' . CR;
+
+ // Counter.
+ $bosscount = $bosscount + 1;
+
+ // Are 3 raid bosses already selected?
+ if(count($exclusions) == 3) continue;
+
+ $keyText = $local_pokemon;
+ if($id == 'all') {
+ $keyText = '[' . ($tier) . ']' . SP . $local_pokemon;
+ }
+ $e = $exclusions;
+ $e[] = $pokemon_arg;
+ $keyAction = ($action == 's') ?
+ ['pokedex_edit_pokemon', 'p' => $dex_id . "-" . $dex_form] :
+ ['pogoinfo', 'rl' => $id, 'e' => implode('#', $e)];
+ // Add key
+ $keys[] = button($keyText, $keyAction);
}
+ }
+ $msg .= CR;
+}
+
+// Get the inline key array.
+$keys = inline_key_array($keys, 2);
+
+// Saved raid bosses?
+if($action == 's') {
+ $msg .= '' . getTranslation('import_done') . '' . CR;
+ $msg .= CR . '' . getTranslation('pokedex_edit_pokemon') . '';
+
+ // Abort button.
+ $nav_keys[][] = button(getTranslation('done'), ['exit', 'd' => 1]);
+
+// User is still on the import.
+} else {
+ $msg .= '' . getTranslation('excluded_raid_bosses') . '' . CR;
+ $msg .= (empty($ex_msg) ? (getTranslation('none') . CR) : $ex_msg) . CR;
+
+ // Import or select more pokemon to exclude?
+ if(!isset($exclusions[2])) {
+ $msg .= '' . getTranslation('exclude_raid_boss_or_import') . ':';
+ } else {
+ $msg .= '' . getTranslation('import_raid_bosses') . '';
+ }
+
+ // Navigation keys.
+ $nav_keys = [];
+
+ // Back button.
+ $nav_keys[] = button(getTranslation('back'), 'pogoinfo');
+
+ // Save button.
+ $nav_keys[] = button(EMOJI_DISK, ['pogoinfo', 'rl' => $id, 'a' => 's', 'e' => implode('#', $exclusions)]);
+
+ // Reset button.
+ if(isset($exclusions[0])) {
+ $nav_keys[] = button(getTranslation('reset'), ['pogoinfo', 'rl' => $id]);
+ }
+
+ // Abort button.
+ $nav_keys[] = button(getTranslation('abort'), 'exit');
+
+ // Get the inline key array and merge keys.
+ $nav_keys = inline_key_array($nav_keys, 2);
}
+$keys = array_merge($keys, $nav_keys);
// Callback message string.
$callback_response = 'OK';
@@ -354,6 +238,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/pokebattler.php b/mods/pokebattler.php
index 72620f77..b1b1b14f 100644
--- a/mods/pokebattler.php
+++ b/mods/pokebattler.php
@@ -1,382 +1,254 @@
accessCheck('pokedex');
include(LOGIC_PATH . '/resolve_boss_name_to_ids.php');
-// Levels available for import at PokeBattler
-$levels = array('6', '5', '3', '1');
-
// Get raid levels
-$id = $data['id'];
-
-// Exclude pokemon
-$arg = $data['arg'];
+$id = $data['rl'] ?? 0;
+$action = $data['a'] ?? '';
// Raid level selection
if($id == 0) {
- // Set message.
- $msg = '' . getTranslation('import') . SP . '(Pokebattler)' . '' . CR . CR;
- $msg .= '' . getTranslation('select_raid_level') . ':';
-
- // Init empty keys array.
- $keys = [];
-
- // All raid level keys.
- $keys[][] = array(
- 'text' => getTranslation('pokedex_all_raid_level'),
- 'callback_data' => RAID_LEVEL_ALL . ':pokebattler:ex#0,0,0'
- );
-
- // Add key for each raid level
- foreach($levels as $l) {
- $keys[][] = array(
- 'text' => getTranslation($l . 'stars'),
- 'callback_data' => $l . ':pokebattler:ex#0,0,0'
- );
- }
- $keys[][] = array(
- 'text' => getTranslation('1stars') . ' & ' . getTranslation('3stars'),
- 'callback_data' => '3,1:pokebattler:ex#0,0,0'
- );
-
- // Add back and abort buttons
- $keys[] = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => '0:pokedex_import:0'
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
-
-} else if($id > 0) {
- // Set message and init message to exclude raid bosses.
- $msg = '' . getTranslation('import') . SP . '(Pokebattler)' . '' . CR . CR;
- $ex_msg = '';
-
- // Get pokebattler data.
- debug_log('Getting raid bosses from pokebattler.com now...');
- $link = 'https://fight.pokebattler.com/raids';
- $pb_data = curl_get_contents($link);
- $pb_data = json_decode($pb_data,true);
-
- // All raid levels?
- if($id == RAID_LEVEL_ALL) {
- $get_levels = $levels;
- $clear = "'6','5','3','1'";
- } else {
- $get_levels = explode(",", $id);
- $clear = $id;
- }
+ // Set message.
+ $msg = '' . getTranslation('import') . SP . '(Pokebattler)' . '' . CR . CR;
+ $msg .= '' . getTranslation('select_raid_level') . ':';
+
+ // Init empty keys array.
+ $keys = [];
+
+ // All raid level keys.
+ $keys[][] = button(getTranslation('pokedex_all_raid_level'), ['pokebattler', 'rl' => implode(",", $pokebattler_levels)]);
+
+ // Add key for each raid level
+ foreach($pokebattler_levels as $l) {
+ $keys[][] = button(getTranslation($l . 'stars'), ['pokebattler', 'rl' => $l]);
+ }
+ $keys[][] = button(getTranslation('1stars') . ' & ' . getTranslation('3stars'), ['pokebattler', 'rl' => '1,3']);
+
+ // Add back and abort buttons
+ $keys[] = [
+ button(getTranslation('back'), 'pokedex_import'),
+ button(getTranslation('abort'), 'exit')
+ ];
+ // Callback message string.
+ $callback_response = 'OK';
+
+ // Telegram JSON array.
+ $tg_json = array();
+
+ // Answer callback.
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
+
+ // Edit message.
+ $tg_json[] = edit_message($update, $msg, $keys, false, true);
+
+ // Telegram multicurl request.
+ curl_json_multi_request($tg_json);
+ exit;
+}
+// Set message and init message to exclude raid bosses.
+$msg = '' . getTranslation('import') . SP . '(Pokebattler)' . '' . CR . CR;
+$ex_msg = '';
+
+// Get pokebattler data.
+debug_log('Getting raid bosses from pokebattler.com now...');
+$link = 'https://fight.pokebattler.com/raids';
+$pb_data = curl_get_contents($link);
+$pb_data = json_decode($pb_data,true);
+
+$get_levels = explode(',', $id);
+$clear = $id;
+
+// New request
+$exclusions = isset($data['e']) ? explode('#', $data['e']) : [];
+if(!empty($exclusions[0])) {
+ debug_log('Excluded raid bosses: ' . implode(', ', $exclusions));
+}
- // Prefix for exclusion.
- $prefix = 'ex#';
-
- // New request
- if($arg == 'ex#0,0,0') {
- $poke1 = 0;
- $poke2 = 0;
- $poke3 = 0;
-
- // Get raid bosses to exclude.
- } else if(strpos($arg, 'ex#') === 0 || strpos($arg, 'save#') === 0) {
- $poke_ids = explode('#', $arg);
- $poke_ids = explode(',', $poke_ids[1]);
- $poke1 = $poke_ids[0];
- $poke2 = $poke_ids[1];
- $poke3 = $poke_ids[2];
- debug_log('Excluded raid boss #1: ' . $poke1);
- debug_log('Excluded raid boss #2: ' . $poke2);
- debug_log('Excluded raid boss #3: ' . $poke3);
- }
+// Clear old raid bosses.
+if($action == 's') {
+ require_once(LOGIC_PATH . '/disable_raid_level.php');
+ debug_log('Disabling old raid bosses for levels: '. $clear);
+ disable_raid_level($clear);
+}
- // Clear old raid bosses.
- if(strpos($arg, 'save#') === 0) {
- debug_log('Disabling old raid bosses for levels: '. $clear);
- disable_raid_level($clear);
- }
+// Init empty keys array.
+$keys = [];
- // Init empty keys array.
- $keys = [];
-
- // Raid tier array
- debug_log('Processing the following raid levels:');
- $raidlevels = array();
- foreach($get_levels as $level) {
- if($level == 6) {
- $level = 'MEGA'; // PB uses RAID_LEVEL_MEGA instead of RAID_LEVEL_6
- }
- $raidlevels[] = 'RAID_LEVEL_' . $level;
- }
- debug_log($raidlevels);
- $levels_processed = [];
- $bosses = [];
- // Process breaking news section
- $now = new DateTime('now', new DateTimeZone($config->TIMEZONE));
- $ph = new dateTimeZone('America/Phoenix');
- foreach($pb_data['breakingNews'] as $news) {
- if($news['type'] == 'RAID_TYPE_RAID') {
- $rl = str_replace('RAID_LEVEL_','', $news['tier']);
- if($rl == "MEGA") $raid_level_id = 6; else $raid_level_id = $rl;
- $starttime = new DateTime("@".substr($news['startDate'],0,10));
- $endtime = new DateTime("@".substr($news['endDate'],0,10));
- $starttime->setTimezone($ph);
- $endtime->setTimezone($ph);
-
- if(in_array($news['tier'], $raidlevels) && $starttime->getTimestamp() < $now->getTimestamp() && $endtime->getTimestamp() > $now->getTimestamp()) {
- $levels_processed[$raid_level_id] = $news['tier'];
- $dex_id_form = resolve_boss_name_to_ids($news['pokemon']);
- $bosses[$raid_level_id][] = ['id' => $dex_id_form, 'shiny' => $news['shiny']];
- }
- }
+// Raid tier array
+debug_log('Processing the following raid levels:');
+$raidlevels = array();
+foreach($get_levels as $level) {
+ $raidlevels[] = 'RAID_LEVEL_' . $pokebattler_level_map[$level];
+}
+debug_log($raidlevels);
+$levels_processed = $bosses = [];
+// Process breaking news section
+$now = new DateTime('now', new DateTimeZone($config->TIMEZONE));
+$ph = new dateTimeZone('America/Los_Angeles');
+foreach($pb_data['breakingNews'] as $news) {
+ if($news['type'] != 'RAID_TYPE_RAID') continue;
+
+ $rl = str_replace('RAID_LEVEL_','', $news['tier']);
+ $raid_level_id = array_search($rl, $pokebattler_level_map);
+ $starttime = new DateTime("@".substr($news['startDate'],0,10));
+ $endtime = new DateTime("@".substr($news['endDate'],0,10));
+ $starttime->setTimezone($ph);
+ $endtime->setTimezone($ph);
+
+ $tierHolder = $news['tier'];
+ [$dex_id, $form_id] = resolve_boss_name_to_ids($news['pokemon']);
+ if(in_array($dex_id, PRIMAL_MONS) && $news['tier'] == 'RAID_LEVEL_MEGA_5') {
+ $raid_level_id = 10;
+ $tierHolder = 'RAID_LEVEL_PRIMAL';
+ }elseif(in_array($form_id, [-1,-2,-3]) && $news['tier'] == 'RAID_LEVEL_MEGA_5') {
+ $raid_level_id = 16;
+ $tierHolder = 'RAID_LEVEL_SUPER_MEGA_4';
+ }
+ if(in_array($tierHolder, $raidlevels) && $starttime->getTimestamp() < $now->getTimestamp() && $endtime->getTimestamp() > $now->getTimestamp()) {
+ $levels_processed[$raid_level_id] = $news['tier'];
+ $bosses[$raid_level_id][] = ['dex_id' => $dex_id, 'form_id' => $form_id, 'shiny' => $news['shiny']];
+ }
+}
+// Process raid tier(s)
+debug_log('Processing received pokebattler raid bosses for each raid level');
+foreach($pb_data['tiers'] as $tier) {
+ $rl = str_replace('RAID_LEVEL_','', $tier['tier']);
+ $raid_level_id = array_search($rl, $pokebattler_level_map);
+ // Skip this raid level if the boss data was already collected from breaking news or raid level doesn't interest us
+ if(!in_array($tier['tier'], $raidlevels) or isset($levels_processed[$raid_level_id])) {
+ continue;
+ }
+ // Get raid bosses for each raid level.
+ foreach($tier['raids'] as $raid) {
+ // Raid level
+ if (!array_key_exists('id', $raid) or $raid['id'] == 0) {
+ debug_log('Skipping raid boss ' . $raid['pokemon'] . ' since it has no id, it\'s likely in the future!');
+ continue;
}
+ [$dex_id, $form_id] = resolve_boss_name_to_ids($raid['pokemon']);
+ $bosses[$raid_level_id][] = ['dex_id' => $dex_id, 'form_id' => $form_id, 'shiny' => $raid['shiny']];
+ }
+}
- // Process raid tier(s)
- debug_log('Processing received pokebattler raid bosses for each raid level');
- foreach($pb_data['tiers'] as $tier) {
- $rl = str_replace('RAID_LEVEL_','', $tier['tier']);
- if($rl == "MEGA") $raid_level_id = 6; else $raid_level_id = $rl;
- // Skip this raid level if the boss data was already collected from breaking news or raid level doesn't interest us
- if(!in_array($tier['tier'], $raidlevels) or isset($levels_processed[$raid_level_id])) {
- continue;
- }
- // Get raid bosses for each raid level.
- foreach($tier['raids'] as $raid) {
- // Raid level
- if ($raid['id'] == 0) {
- debug_log("Skipping raid boss {$raid['pokemon']} since it has no id, it's likely in the future!");
- continue;
- }
- $dex_id_form = resolve_boss_name_to_ids($raid['pokemon']);
- $bosses[$raid_level_id][] = ['id' => $dex_id_form, 'shiny' => $raid['shiny']];
- }
+foreach($get_levels as $raid_level_id) {
+ if(!isset($bosses[$raid_level_id])) continue;
+ if($raid_level_id > 5) $raid_level_text = getTranslation($raid_level_id . 'stars_short'); else $raid_level_text = $raid_level_id;
+ $msg .= '' . getTranslation('pokedex_raid_level') . SP . $raid_level_text . ':' . CR;
+ foreach($bosses[$raid_level_id] as $dex_id_form) {
+ $dex_id = $dex_id_form['dex_id'];
+ $dex_form = $dex_id_form['form_id'];
+ $pokemon_arg = $dex_id . (($dex_form != 'normal') ? ('-' . $dex_form) : '-0');
+ $local_pokemon = get_local_pokemon_name($dex_id, $dex_form);
+ debug_log('Got this pokemon dex id: ' . $dex_id);
+ debug_log('Got this pokemon dex form: ' . $dex_form);
+ debug_log('Got this local pokemon name and form: ' . $local_pokemon);
+
+ // Make sure we received a valid dex id.
+ if(!is_numeric($dex_id) || $dex_id == 0) {
+ info_log('Failed to get a valid pokemon dex id: '. $dex_id .' Continuing with next raid boss...');
+ continue;
}
- $count = count($get_levels)-1;
- for($i=$count;$i>=0;$i--) {
- $raid_level_id = $get_levels[$i];
- if($raid_level_id == 6) $rl = "MEGA"; else $rl = $raid_level_id;
- $msg .= '' . getTranslation('pokedex_raid_level') . SP . $rl . ':' . CR;
- foreach($bosses[$raid_level_id] as $dex_id_form) {
- $dex_id = explode('-', $dex_id_form['id'], 2)[0];
- $dex_form = explode('-', $dex_id_form['id'], 2)[1];
- $pokemon_arg = $dex_id . (($dex_form != 'normal') ? ('-' . $dex_form) : '-0');
- $local_pokemon = get_local_pokemon_name($dex_id, $dex_form);
- debug_log('Got this pokemon dex id: ' . $dex_id);
- debug_log('Got this pokemon dex form: ' . $dex_form);
- debug_log('Got this local pokemon name and form: ' . $local_pokemon);
-
- // Make sure we received a valid dex id.
- if(!is_numeric($dex_id) || $dex_id == 0) {
- info_log('Failed to get a valid pokemon dex id: '. $dex_id .' Continuing with next raid boss...');
- continue;
- }
-
- // Build new arg.
- // Exclude 1 pokemon
- if($poke1 == '0') {
- $new_arg = $prefix . $pokemon_arg . ',0,0';
-
- // Exclude 2 pokemon
- } else if ($poke1 != '0' && $poke2 == '0') {
- $new_arg = $prefix . $poke1 . ',' . $pokemon_arg . ',0';
-
- // Exclude 3 pokemon
- } else if ($poke1 != '0' && $poke2 != '0' && $poke3 == '0') {
- $new_arg = $prefix . $poke1 . ',' . $poke2 . ',' . $pokemon_arg;
- }
-
- // Exclude pokemon?
- if($pokemon_arg == $poke1 || $pokemon_arg == $poke2 || $pokemon_arg == $poke3) {
- // Add pokemon to exclude message.
- $ex_msg .= $local_pokemon . SP . '(#' . $dex_id . ')' . CR;
-
- } else {
- // Add pokemon to message.
- $msg .= $local_pokemon . SP . '(#' . $dex_id . ')' . CR;
-
- // Shiny?
- $shiny = 0;
- if($dex_id_form['shiny'] == 'true') {
- $shiny = 1;
- }
-
- // Save to database?
- if(strpos($arg, 'save#') === 0) {
- // Update raid level of pokemon
- my_query(
- "
- UPDATE pokemon
- SET shiny = {$shiny}
- WHERE pokedex_id = {$dex_id}
- AND pokemon_form_id = '{$dex_form}'
- "
- );
- my_query(
- "
- INSERT INTO raid_bosses (pokedex_id, pokemon_form_id, raid_level)
- VALUES ('{$dex_id}', '{$dex_form}', '{$raid_level_id}')
- "
- );
- continue;
- }
-
- // Are 3 raid bosses already selected?
- if($poke1 == '0' || $poke2 == '0' || $poke3 == '0') {
- // Add raid level to pokemon name
- if($id == RAID_LEVEL_ALL) {
- // Add key to exclude pokemon from import.
- $keys[] = array(
- 'text' => '[' . ($rl) . ']' . SP . $local_pokemon,
- 'callback_data' => $id . ':pokebattler:' . $new_arg
- );
- } else {
- // Add key to exclude pokemon from import.
- $keys[] = array(
- 'text' => $local_pokemon,
- 'callback_data' => $id . ':pokebattler:' . $new_arg
- );
- }
- }
- }
- }
- $msg .= CR;
+ // Save to database?
+ if($action == 's') {
+ // Shiny?
+ $shiny = ($dex_id_form['shiny'] == 'true') ? 1 : 0;
+ // Update raid level of pokemon
+ my_query('
+ UPDATE pokemon
+ SET shiny = ?
+ WHERE pokedex_id = ?
+ AND pokemon_form_id = ?
+ ', [$shiny, $dex_id, $dex_form]
+ );
+ my_query('
+ INSERT INTO raid_bosses (pokedex_id, pokemon_form_id, raid_level)
+ VALUES (?, ?, ?)
+ ', [$dex_id, $dex_form, $raid_level_id]
+ );
}
- // Get the inline key array.
- $keys = inline_key_array($keys, 2);
-
- // Saved raid bosses?
- if(strpos($arg, 'save#') === 0) {
- // Get all pokemon with raid levels from database.
- $rs = my_query(
- "
- SELECT raid_bosses.pokedex_id, raid_bosses.pokemon_form_id, raid_bosses.raid_level
- FROM raid_bosses
- LEFT JOIN pokemon
- ON raid_bosses.pokedex_id = pokemon.pokedex_id
- AND raid_bosses.pokemon_form_id = pokemon.pokemon_form_id
- WHERE raid_bosses.raid_level IN ({$clear})
- AND raid_bosses.scheduled = 0
- ORDER BY raid_bosses.raid_level, raid_bosses.pokedex_id, pokemon.pokemon_form_name != 'normal', pokemon.pokemon_form_name, raid_bosses.pokemon_form_id
- "
- );
-
- // Init empty keys array.
- $keys = [];
-
- // Init message and previous.
- $msg = 'Pokebattler' . SP . '—' . SP . getTranslation('import_done') . '' . CR;
- $previous = '';
-
- // Build the message
- while ($pokemon = $rs->fetch()) {
- // Set current level
- $current = $pokemon['raid_level'];
-
- // Add header for each raid level
- if($previous != $current) {
- $msg .= CR . '' . getTranslation($pokemon['raid_level'] . 'stars') . ':' . CR ;
- }
-
- // Add pokemon with id and name.
- $dex_id = $pokemon['pokedex_id'];
- $pokemon_form_id = $pokemon['pokemon_form_id'];
- $poke_name = get_local_pokemon_name($dex_id, $pokemon_form_id);
- $msg .= $poke_name . ' (#' . $dex_id . ')' . CR;
-
- // Add button to edit pokemon.
- if($id == RAID_LEVEL_ALL) {
- $keys[] = array(
- 'text' => '[' . $pokemon['raid_level'] . ']' . SP . $poke_name,
- 'callback_data' => $dex_id . "-" . $pokemon_form_id . ':pokedex_edit_pokemon:0'
- );
- } else {
- $keys[] = array(
- 'text' => $poke_name,
- 'callback_data' => $dex_id . "-" . $pokemon_form_id . ':pokedex_edit_pokemon:0'
- );
- }
-
- // Prepare next run.
- $previous = $current;
- }
-
- // Message.
- $msg .= CR . '' . getTranslation('pokedex_edit_pokemon') . '';
-
- // Inline key array.
- $keys = inline_key_array($keys, 2);
-
- // Navigation keys.
- $nav_keys = [];
-
- // Abort button.
- $nav_keys[] = array(
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- );
-
- // Keys.
- $nav_keys = inline_key_array($nav_keys, 1);
- $keys = array_merge($keys, $nav_keys);
-
- // User is still on the import.
+ // Exclude pokemon?
+ if(in_array($pokemon_arg, $exclusions)) {
+ // Add pokemon to exclude message.
+ $ex_msg .= $local_pokemon . SP . '(#' . $dex_id . ')' . CR;
+
} else {
- $msg .= '' . getTranslation('excluded_raid_bosses') . '' . CR;
- $msg .= (empty($ex_msg) ? (getTranslation('none') . CR) : $ex_msg) . CR;
-
- // Import or select more pokemon to exclude?
- if($poke1 == '0' || $poke2 == '0' || $poke3 == '0') {
- $msg .= '' . getTranslation('exclude_raid_boss_or_import') . ':';
- } else {
- $msg .= '' . getTranslation('import_raid_bosses') . '';
- }
-
- // Navigation keys.
- $nav_keys = [];
-
- // Back button.
- $nav_keys[] = array(
- 'text' => getTranslation('back'),
- 'callback_data' => '0:pokebattler:0'
- );
-
- // Save button.
- $nav_keys[] = array(
- 'text' => EMOJI_DISK,
- 'callback_data' => $id . ':pokebattler:save#' . $poke1 . ',' . $poke2 . ',' . $poke3
- );
-
- // Reset button.
- if($poke1 != 0) {
- $nav_keys[] = array(
- 'text' => getTranslation('reset'),
- 'callback_data' => $id . ':pokebattler:ex#0,0,0'
- );
- }
-
- // Abort button.
- $nav_keys[] = array(
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- );
-
- // Get the inline key array and merge keys.
- $nav_keys = inline_key_array($nav_keys, 2);
- $keys = array_merge($keys, $nav_keys);
+ // Add pokemon to message.
+ $msg .= $local_pokemon . SP . '(#' . $dex_id . ')' . CR;
+
+ // Add key to exclude pokemon from import.
+ $button_text_prefix = '';
+ if($id == implode(',', $pokebattler_levels)) {
+ // Add raid level to pokemon name
+ $button_text_prefix = '[' . ($raid_level_text) . ']';
+ }
+ $e = $exclusions;
+ $e[] = $pokemon_arg;
+ // Are 3 raid bosses already selected?
+ if(count($exclusions) == 3) continue;
+ $keyAction = ($action == 's') ?
+ ['pokedex_edit_pokemon', 'p' => $dex_id . "-" . $dex_form] :
+ ['pokebattler', 'rl' => $id, 'e' => implode('#', $e)];
+ $keys[] = button($button_text_prefix . SP . $local_pokemon, $keyAction);
}
+ }
+ $msg .= CR;
}
+// Get the inline key array.
+$keys = inline_key_array($keys, 2);
+
+// Saved raid bosses?
+if($action == 's') {
+ $msg .= '' . getTranslation('import_done') . '' . CR;
+ $msg .= CR . '' . getTranslation('pokedex_edit_pokemon') . '';
+
+ // Abort button.
+ $nav_keys[][] = button(getTranslation('done'), ['exit', 'd' => 1]);
+
+// User is still on the import.
+} else {
+ $msg .= '' . getTranslation('excluded_raid_bosses') . '' . CR;
+ $msg .= (empty($ex_msg) ? (getTranslation('none') . CR) : $ex_msg) . CR;
+
+ // Import or select more pokemon to exclude?
+ if(!isset($exclusions[2])) {
+ $msg .= '' . getTranslation('exclude_raid_boss_or_import') . ':';
+ } else {
+ $msg .= '' . getTranslation('import_raid_bosses') . '';
+ }
+
+ // Navigation keys.
+ $nav_keys = [];
+
+ // Back button.
+ $nav_keys[] = button(getTranslation('back'), 'pokebattler');
+
+ // Save button.
+ $nav_keys[] = button(EMOJI_DISK, ['pokebattler', 'rl' => $id, 'a' => 's', 'e' => implode('#', $exclusions)]);
+
+ // Reset button.
+ if(isset($exclusions[0])) {
+ $nav_keys[] = button(getTranslation('reset'), ['pokebattler', 'rl' => $id]);
+ }
+
+ // Abort button.
+ $nav_keys[] = button(getTranslation('abort'), 'exit');
+
+ // Get the inline key array and merge keys.
+ $nav_keys = inline_key_array($nav_keys, 2);
+}
+$keys = array_merge($keys, $nav_keys);
// Callback message string.
$callback_response = 'OK';
@@ -391,6 +263,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/pokedex.php b/mods/pokedex.php
index ed05d4dd..06fef626 100644
--- a/mods/pokedex.php
+++ b/mods/pokedex.php
@@ -1,47 +1,37 @@
accessCheck('pokedex');
// Get the limit.
-$limit = $data['id'];
+$limit = $data['l'] ?? 0;
-// Get the action.
-$action = $data['arg'];
+// Set message.
+$msg = getTranslation('pokedex_list_of_all') . CR . CR . '' . getTranslation('pokedex_edit_pokemon') . '';
-if ($update['callback_query']['message']['chat']['type'] == 'private') {
- // Set message.
- $msg = getTranslation('pokedex_list_of_all') . CR . CR . '' . getTranslation('pokedex_edit_pokemon') . '';
+// Get pokemon.
+$keys = edit_pokedex_keys($limit);
- // Get pokemon.
- $keys = edit_pokedex_keys($limit, $action);
+// Empty keys?
+if (!$keys) {
+ $msg = getTranslation('pokedex_not_found');
+}
- // Empty keys?
- if (!$keys) {
- $msg = getTranslation('pokedex_not_found');
- }
+// Telegram JSON array.
+$tg_json = array();
- // Build callback message string.
- $callback_response = 'OK';
+// Answer callback.
+$tg_json[] = answerCallbackQuery($update['callback_query']['id'], 'OK', true);
- // Telegram JSON array.
- $tg_json = array();
+// Edit message.
+$tg_json[] = edit_message($update, $msg, $keys, false, true);
- // Answer callback.
- $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
-
- // Edit message.
- $tg_json[] = edit_message($update, $msg, $keys, false, true);
-
- // Telegram multicurl request.
- curl_json_multi_request($tg_json);
-}
-
-// Exit.
-exit();
+// Telegram multicurl request.
+curl_json_multi_request($tg_json);
diff --git a/mods/pokedex_disable_raids.php b/mods/pokedex_disable_raids.php
index 0e4db6a6..300324fb 100644
--- a/mods/pokedex_disable_raids.php
+++ b/mods/pokedex_disable_raids.php
@@ -7,135 +7,114 @@
//debug_log($data);
// Check access.
-bot_access_check($update, 'pokedex');
+$botUser->accessCheck('pokedex');
// Get raid levels.
-$id = $data['id'];
+$id = $data['rl'] ?? 0;
// Get argument.
-$arg = $data['arg'];
+$arg = $data['a'] ?? 0;
+
+// Specify raid levels.
+$levels = RAID_LEVEL_ALL;
// All raid levels?
-if($id == 'X' . RAID_LEVEL_ALL) {
- // TODO(artanicus): get this from somewhere instead of hardcoded
- $clear = "'X','6','5','3','1'";
+if($id == 'all') {
+ $clear = "'" . implode("','", $levels) . "'";
} else {
- $clear = "'" . $id . "'";
+ $clear = "'" . $id . "'";
}
-// Specify raid levels.
-// TODO(artanicus): get this from somewhere instead of hardcoded
-$levels = array('X', '6', '5', '3', '1');
-
// Raid level selection
if($arg == 0) {
- // Set message.
- $msg = '' . getTranslation('disable_raid_level') . ':';
-
- // Init empty keys array.
- $keys = [];
-
- // All raid level keys.
- $keys[] = array(
- 'text' => getTranslation('pokedex_all_raid_level'),
- 'callback_data' => 'X' . RAID_LEVEL_ALL . ':pokedex_disable_raids:1'
- );
-
- // Add key for each raid level
- foreach($levels as $l) {
- $keys[] = array(
- 'text' => getTranslation($l . 'stars'),
- 'callback_data' => $l . ':pokedex_disable_raids:1'
- );
- }
+ // Set message.
+ $msg = '' . getTranslation('disable_raid_level') . ':';
+
+ // Init empty keys array.
+ $keys = [];
- // Add abort button
- $keys[] = array(
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- );
+ // All raid level keys.
+ $keys[][] = button(getTranslation('pokedex_all_raid_level'), ['pokedex_disable_raids', 'rl' => 'all', 'a' => 1]);
- // Get the inline key array.
- $keys = inline_key_array($keys, 1);
+ // Add key for each raid level
+ foreach($levels as $l) {
+ $keys[][] = button(getTranslation($l . 'stars'), ['pokedex_disable_raids', 'rl' => $l, 'a' => 1]);
+ }
+
+ // Add abort button
+ $keys[][] = button(getTranslation('abort'), 'exit');
// Confirmation to disable raid level
} else if($arg == 1) {
- // Get all pokemon with raid levels from database.
- $rs = my_query(
- "
- SELECT pokemon.pokedex_id, pokemon.pokemon_form_name, pokemon.pokemon_form_id, raid_bosses.raid_level
- FROM raid_bosses
- LEFT JOIN pokemon
- ON pokemon.pokedex_id = raid_bosses.pokedex_id
- AND pokemon.pokemon_form_id = raid_bosses.pokemon_form_id
- WHERE raid_bosses.raid_level IN ({$clear})
- AND raid_bosses.scheduled = 0
- ORDER BY raid_level, pokedex_id, pokemon_form_name != 'normal', pokemon_form_name
- "
- );
-
- // Init empty keys array.
- $keys = [];
-
- // Init message and previous.
- $msg = '' . getTranslation('disable_raid_level') . '?' . CR;
- $previous = '';
-
- // Build the message
- while ($pokemon = $rs->fetch()) {
- // Set current level
- $current = $pokemon['raid_level'];
-
- // Add header for each raid level
- if($previous != $current) {
- $msg .= CR . '' . getTranslation($pokemon['raid_level'] . 'stars') . ':' . CR ;
- }
-
- // Add pokemon with id and name.
- $dex_id = $pokemon['pokedex_id'];
- $poke_name = get_local_pokemon_name($dex_id, $pokemon['pokemon_form_id']);
- $msg .= $poke_name . ' (#' . $dex_id . ')' . CR;
-
- // Prepare next run.
- $previous = $current;
+ // Get all pokemon with raid levels from database.
+ $rs = my_query('
+ SELECT pokemon.pokedex_id, pokemon.pokemon_form_name, pokemon.pokemon_form_id, raid_bosses.raid_level
+ FROM raid_bosses
+ LEFT JOIN pokemon
+ ON pokemon.pokedex_id = raid_bosses.pokedex_id
+ AND pokemon.pokemon_form_id = raid_bosses.pokemon_form_id
+ WHERE raid_bosses.raid_level IN (' . $clear . ')
+ AND raid_bosses.scheduled = 0
+ ORDER BY raid_level, pokedex_id, pokemon_form_name != \'normal\', pokemon_form_name
+ ');
+
+ // Init empty keys array.
+ $keys = [];
+
+ // Init message and previous.
+ $msg = '' . getTranslation('disable_raid_level') . '?' . CR;
+ $previous = '';
+
+ // Build the message
+ while ($pokemon = $rs->fetch()) {
+ // Set current level
+ $current = $pokemon['raid_level'];
+
+ // Add header for each raid level
+ if($previous != $current) {
+ $msg .= CR . '' . getTranslation($pokemon['raid_level'] . 'stars') . ':' . CR ;
}
- // Disable.
- $keys[] = array(
- 'text' => getTranslation('yes'),
- 'callback_data' => $id . ':pokedex_disable_raids:2'
- );
+ // Add pokemon with id and name.
+ $dex_id = $pokemon['pokedex_id'];
+ $poke_name = get_local_pokemon_name($dex_id, $pokemon['pokemon_form_id']);
+ $msg .= $poke_name . ' (#' . $dex_id . ')' . CR;
+
+ // Prepare next run.
+ $previous = $current;
+ }
+
+ // Disable.
+ $keys[] = button(getTranslation('yes'), ['pokedex_disable_raids', 'rl' => $id, 'a' => 2]);
- // Abort.
- $keys[] = array(
- 'text' => getTranslation('no'),
- 'callback_data' => '0:exit:0'
- );
+ // Abort.
+ $keys[] = button(getTranslation('no'), 'exit');
- // Inline keys array.
- $keys = inline_key_array($keys, 2);
+ // Inline keys array.
+ $keys = inline_key_array($keys, 2);
// Disable raid level
} else if($arg == 2) {
- debug_log('Disabling old raid bosses for levels: '. $clear);
- disable_raid_level($clear);
+ require_once(LOGIC_PATH . '/disable_raid_level.php');
+ debug_log('Disabling old raid bosses for levels: '. $clear);
+ disable_raid_level($clear);
- // Message.
- $msg = '' . getTranslation('disabled_raid_level') . ':' . CR;
+ // Message.
+ $msg = '' . getTranslation('disabled_raid_level') . ':' . CR;
- // All levels
- if($id == 'X' . RAID_LEVEL_ALL) {
- foreach($levels as $lv) {
- $msg .= getTranslation($lv . 'stars') . CR;
- }
+ // All levels
+ if($id == 'all') {
+ foreach($levels as $lv) {
+ $msg .= getTranslation($lv . 'stars') . CR;
+ }
- // Specific level
- } else {
- $msg .= getTranslation($id . 'stars');
- }
+ // Specific level
+ } else {
+ $msg .= getTranslation($id . 'stars');
+ }
- // Empty keys.
- $keys = [];
+ // Empty keys.
+ $keys = [];
}
// Build callback message string.
@@ -152,6 +131,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/pokedex_edit_pokemon.php b/mods/pokedex_edit_pokemon.php
index 59156f5f..aa3071af 100644
--- a/mods/pokedex_edit_pokemon.php
+++ b/mods/pokedex_edit_pokemon.php
@@ -1,119 +1,60 @@
accessCheck('pokedex');
// Set the id.
-$poke_id_form = $data['id'];
-$dex_id_form = explode('-',$data['id'],2);
-$pokedex_id = $dex_id_form[0];
-$pokemon_form = $dex_id_form[1];
-
-// Set the arg.
-$arg = $data['arg'];
-
-// Init empty keys array.
-$keys = [];
+$poke_id_form = $data['p'];
+[$pokedex_id, $pokemon_form_id] = explode('-',$poke_id_form,2);
// Set the message.
-$msg = get_pokemon_info($pokedex_id, $pokemon_form);
+$pokemon = get_pokemon_info($pokedex_id, $pokemon_form_id);
+$poke_cp = get_formatted_pokemon_cp($pokemon);
+$msg = getTranslation('raid_boss') . ': ' . get_local_pokemon_name($pokedex_id, $pokemon_form_id) . ' (#' . $pokedex_id . ')' . CR . CR;
+$msg .= getTranslation('pokedex_raid_level') . ': ' . getTranslation($pokemon['raid_level'] . 'stars') . CR;
+$msg .= (empty($poke_cp)) ? (getTranslation('pokedex_cp') . CR) : $poke_cp . CR;
+$msg .= getTranslation('pokedex_weather') . ': ' . get_weather_icons($pokemon['weather']) . CR;
+$msg .= (($pokemon['shiny'] == 1) ? (EMOJI_SHINY . SP . getTranslation('shiny')) : (getTranslation('not_shiny'))) . CR . CR;
$msg .= '' . getTranslation('pokedex_select_action') . '';
// Create keys array.
-$keys = [
- [
- [
- 'text' => getTranslation('pokedex_raid_level'),
- 'callback_data' => $poke_id_form . ':pokedex_set_raid_level:setlevel'
- ]
- ]
-];
+$keys[][] = button(getTranslation('pokedex_raid_level'), ['pokedex_set_raid_level', 'p' => $poke_id_form]);
// Raid-Egg? Hide specific options!
-$eggs = $GLOBALS['eggs'];
-if(!in_array($pokedex_id, $eggs)) {
- $keys_cp_weather = [
- [
- [
- 'text' => getTranslation('pokedex_min_cp'),
- 'callback_data' => $poke_id_form . ':pokedex_set_cp:min-20-add-0'
- ]
- ],
- [
- [
- 'text' => getTranslation('pokedex_max_cp'),
- 'callback_data' => $poke_id_form . ':pokedex_set_cp:max-20-add-0'
- ]
- ],
- [
- [
- 'text' => getTranslation('pokedex_min_weather_cp'),
- 'callback_data' => $poke_id_form . ':pokedex_set_cp:min-25-add-0'
- ]
- ],
- [
- [
- 'text' => getTranslation('pokedex_max_weather_cp'),
- 'callback_data' => $poke_id_form . ':pokedex_set_cp:max-25-add-0'
- ]
- ],
- [
- [
- 'text' => getTranslation('pokedex_weather'),
- 'callback_data' => $poke_id_form . ':pokedex_set_weather:add-0'
- ]
- ],
- [
- [
- 'text' => getTranslation('shiny'),
- 'callback_data' => $poke_id_form . ':pokedex_set_shiny:setshiny'
- ]
- ]
- ];
-
- $keys = array_merge($keys, $keys_cp_weather);
+if(!in_array($pokedex_id, EGGS)) {
+ $keys[][] = button(getTranslation('pokedex_min_cp'), ['pokedex_set_cp', 'p' => $poke_id_form, 'a' => 'add', 'l' => 20, 't' => 'min']);
+ $keys[][] = button(getTranslation('pokedex_max_cp'), ['pokedex_set_cp', 'p' => $poke_id_form, 'a' => 'add', 'l' => 20, 't' => 'max']);
+ $keys[][] = button(getTranslation('pokedex_min_weather_cp'), ['pokedex_set_cp', 'p' => $poke_id_form, 'a' => 'add', 'l' => 25, 't' => 'min']);
+ $keys[][] = button(getTranslation('pokedex_max_weather_cp'), ['pokedex_set_cp', 'p' => $poke_id_form, 'a' => 'add', 'l' => 25, 't' => 'max']);
+ $keys[][] = button(getTranslation('pokedex_weather'), ['pokedex_set_weather', 'p' => $poke_id_form]);
+ $keys[][] = button(getTranslation('shiny'), ['pokedex_set_shiny', 'p' => $poke_id_form]);
}
// Back and abort.
$keys[] = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => '0:pokedex:0'
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
+ button(getTranslation('back'), 'pokedex'),
+ button(getTranslation('abort'), 'exit')
];
-// Send message.
-if($arg == 'id-or-name') {
- // Send message.
- send_message($update['message']['chat']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
+// Build callback message string.
+$callback_response = 'OK';
-// Edit message.
-} else {
- // Build callback message string.
- $callback_response = 'OK';
-
- // Telegram JSON array.
- $tg_json = array();
-
- // Answer callback.
- $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
+// Telegram JSON array.
+$tg_json = array();
- // Edit message.
- $tg_json[] = edit_message($update, $msg, $keys, false, true);
+// Answer callback.
+$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
- // Telegram multicurl request.
- curl_json_multi_request($tg_json);
-}
+// Edit message.
+$tg_json[] = edit_message($update, $msg, $keys, false, true);
-// Exit.
-exit();
+// Telegram multicurl request.
+curl_json_multi_request($tg_json);
diff --git a/mods/pokedex_import.php b/mods/pokedex_import.php
index a500a65f..f775e023 100644
--- a/mods/pokedex_import.php
+++ b/mods/pokedex_import.php
@@ -7,47 +7,17 @@
//debug_log($data);
// Check access.
-bot_access_check($update, 'pokedex');
+$botUser->accessCheck('pokedex');
-$id = $data['id'];
-$arg = $data['arg'];
+$msg = 'Import data from community maintained sources:'.CR;
+$msg.= 'ccev\'s github repository'.CR;
+$msg.= 'Pokebattler';
-$msg = "Import data from community maintained sources:".CR;
-$msg.= "ccev's github repository".CR;
-$msg.= "Pokebattler";
-
-$keys = [
- [
- [
- 'text' => getTranslation('import') . SP . '(Pokebattler)',
- 'callback_data' => '0:pokebattler:0'
- ]
- ],
- [
- [
- 'text' => getTranslation('import') . SP . getTranslation('upcoming') . SP . '(Pokebattler)',
- 'callback_data' => '0:import_future_bosses:0'
- ]
- ],
- [
- [
- 'text' => getTranslation('import') . SP . getTranslation('shiny') . SP . '(Pokebattler)',
- 'callback_data' => '0:import_shinyinfo:0'
- ]
- ],
- [
- [
- 'text' => getTranslation('import') . SP . '(ccev pogoinfo)',
- 'callback_data' => '0:pogoinfo:0'
- ]
- ],
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
+$keys[][] = button(getTranslation('import') . SP . '(Pokebattler)', 'pokebattler');
+$keys[][] = button(getTranslation('import') . SP . getTranslation('upcoming') . SP . '(Pokebattler)', 'import_future_bosses');
+$keys[][] = button(getTranslation('import') . SP . getTranslation('shiny') . SP . '(Pokebattler)', 'import_shinyinfo');
+$keys[][] = button(getTranslation('import') . SP . '(ccev pogoinfo)', 'pogoinfo');
+$keys[][] = button(getTranslation('abort'), 'exit');
// Callback message string.
$callback_response = 'OK';
@@ -64,7 +34,4 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-$dbh = null;
exit();
-
-?>
\ No newline at end of file
diff --git a/mods/pokedex_list_raids.php b/mods/pokedex_list_raids.php
index cad3b361..e6dac581 100644
--- a/mods/pokedex_list_raids.php
+++ b/mods/pokedex_list_raids.php
@@ -7,19 +7,24 @@
//debug_log($data);
// Check access.
-bot_access_check($update, 'pokedex');
+$botUser->accessCheck('pokedex');
// Get all pokemon with raid levels from database.
-$rs = my_query(
- "
- SELECT raid_bosses.id, raid_bosses.pokedex_id, raid_bosses.pokemon_form_id, raid_bosses.raid_level, raid_bosses.date_start, raid_bosses.date_end, raid_bosses.scheduled
- FROM raid_bosses
- LEFT JOIN pokemon
- ON raid_bosses.pokedex_id = pokemon.pokedex_id
- AND raid_bosses.pokemon_form_id = pokemon.pokemon_form_id
- ORDER BY raid_bosses.date_start, raid_bosses.date_end, raid_bosses.raid_level, raid_bosses.pokedex_id, pokemon.pokemon_form_name != 'normal', pokemon.pokemon_form_name, raid_bosses.pokemon_form_id
- "
- );
+$rs = my_query('
+ SELECT raid_bosses.id,
+ raid_bosses.pokedex_id,
+ raid_bosses.pokemon_form_id,
+ raid_bosses.raid_level,
+ DATE_FORMAT(date_start, \'%e.%c. ' . getTranslation('raid_egg_opens_at') . ' %H:%i\') as date_start,
+ DATE_FORMAT(date_end, \'%e.%c. ' . getTranslation('raid_egg_opens_at') . ' %H:%i\') as date_end,
+ raid_bosses.scheduled,
+ raid_bosses.disabled
+ FROM raid_bosses
+ LEFT JOIN pokemon
+ ON raid_bosses.pokedex_id = pokemon.pokedex_id
+ AND raid_bosses.pokemon_form_id = pokemon.pokemon_form_id
+ ORDER BY raid_bosses.date_start, raid_bosses.date_end, raid_bosses.raid_level, raid_bosses.pokedex_id, pokemon.pokemon_form_name != \'normal\', pokemon.pokemon_form_name, raid_bosses.pokemon_form_id
+');
// Init empty keys array.
$keys = [];
@@ -31,74 +36,66 @@
$previous_date_end = '';
// Build the message
while ($pokemon = $rs->fetch()) {
- // Set current level
- $current_level = $pokemon['raid_level'];
- $current_date_start = $pokemon['date_start'];
- $current_date_end = $pokemon['date_end'];
- if($previous_date_start != $current_date_start || $previous_date_end != $current_date_end || $previous_date_start == 'FIRST_RUN') {
- // Formatting.
- if($previous_date_start != 'FIRST_RUN') {
- $msg .= CR;
- }
- // Add header.
- if($pokemon['scheduled'] == 0) {
- $msg .= '' . getTranslation('unscheduled_bosses') . ':' . CR;
- }else {
- $msg .= EMOJI_CLOCK . ' ' . $pokemon['date_start'] . ' - ' . $pokemon['date_end'] . ':' . CR ;
- }
- $previous_level = 'FIRST_RUN';
+ // Set current level
+ $current_level = $pokemon['raid_level'];
+ $current_date_start = $pokemon['date_start'];
+ $current_date_end = $pokemon['date_end'];
+ if($previous_date_start != $current_date_start || $previous_date_end != $current_date_end || $previous_date_start == 'FIRST_RUN') {
+ // Formatting.
+ if($previous_date_start != 'FIRST_RUN') {
+ $msg .= CR;
}
- // Add header for each raid level
- if($previous_level != $current_level || $previous_level == 'FIRST_RUN') {
- // Formatting.
- if($previous_level != 'FIRST_RUN') {
- $msg .= CR;
- }
- // Add header.
- $msg .= '' . getTranslation($pokemon['raid_level'] . 'stars') . ':' . CR ;
+ // Add header.
+ if($pokemon['scheduled'] == 0) {
+ $msg .= '' . getTranslation('unscheduled_bosses') . ':' . CR;
+ }else {
+ $msg .= EMOJI_CLOCK . ' ' . $pokemon['date_start'] . ' — ' . $pokemon['date_end'] . ':' . CR ;
}
- // Add pokemon with id and name.
- $poke_name = get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id']);
- $msg .= $poke_name . ' (#' . $pokemon['pokedex_id'] . ')' . CR;
-
- // Add button to edit pokemon.
- if($pokemon['scheduled'] == 1) {
- $keys[] = array(
- 'text' => EMOJI_CLOCK . ' [' . $pokemon['raid_level'] . ']' . SP . $poke_name,
- 'callback_data' => $pokemon['id'] . ':delete_scheduled_entry:0'
- );
- } else {
- $keys[] = array(
- 'text' => '[' . $pokemon['raid_level'] . ']' . SP . $poke_name,
- 'callback_data' => $pokemon['pokedex_id'] . '-' . $pokemon['pokemon_form_id'] . ':pokedex_edit_pokemon:0'
- );
+ $previous_level = 'FIRST_RUN';
+ }
+ // Add header for each raid level
+ if($previous_level != $current_level || $previous_level == 'FIRST_RUN') {
+ // Formatting.
+ if($previous_level != 'FIRST_RUN') {
+ $msg .= CR;
}
-
- // Prepare next run.
- $previous_level = $current_level;
- $previous_date_start = $current_date_start;
- $previous_date_end = $current_date_end;
+ // Add header.
+ $msg .= '' . getTranslation($pokemon['raid_level'] . 'stars') . ':' . CR ;
+ }
+ // Add pokemon with id and name.
+ $poke_name = get_local_pokemon_name($pokemon['pokedex_id'], $pokemon['pokemon_form_id']);
+ $msg .= $poke_name . ' (#' . $pokemon['pokedex_id'] . ')' . CR;
+
+ // Add button to edit pokemon.
+ if($pokemon['scheduled'] == 1) {
+ $keys[] = button(
+ EMOJI_CLOCK . ($pokemon['disabled'] == 1 ? EMOJI_DISABLED : '').' [' . $pokemon['raid_level'] . ']' . SP . $poke_name,
+ ['edit_scheduled_entry', 'i' => $pokemon['id']]
+ );
+ } else {
+ $keys[] = button('[' . $pokemon['raid_level'] . ']' . SP . $poke_name, ['pokedex_edit_pokemon', 'p' => $pokemon['pokedex_id'] . '-' . $pokemon['pokemon_form_id']]);
+ }
+
+ // Prepare next run.
+ $previous_level = $current_level;
+ $previous_date_start = $current_date_start;
+ $previous_date_end = $current_date_end;
}
if(!empty($msg)) {
- // Set the message.
- $msg .= CR . '' . getTranslation('pokedex_edit_pokemon') . '';
- // Set the keys.
- $keys = inline_key_array($keys, 2);
+ // Set the message.
+ $msg .= CR . '' . getTranslation('pokedex_edit_pokemon') . '';
+ // Set the keys.
+ $keys = inline_key_array($keys, 2);
- // Done key.
- $keys[] = [
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ];
+ // Done key.
+ $keys[][] = button(getTranslation('done'), ['exit', 'd' => '1']);
} else {
- // Set empty keys.
- $keys = [];
+ // Set empty keys.
+ $keys = [];
- // Set the message.
- $msg = getTranslation('pokedex_not_found');
+ // Set the message.
+ $msg = getTranslation('pokedex_not_found');
}
// Build callback message string.
@@ -115,6 +112,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/pokedex_set_cp.php b/mods/pokedex_set_cp.php
index 7421ee8a..b9feca5a 100644
--- a/mods/pokedex_set_cp.php
+++ b/mods/pokedex_set_cp.php
@@ -1,16 +1,17 @@
accessCheck('pokedex');
// Set the id.
-$pokedex_id = $data['id'];
+$pokedex_id = $data['p'];
// Split pokedex_id and form
$dex_id_form = explode('-',$pokedex_id,2);
@@ -18,25 +19,19 @@
$dex_form = $dex_id_form[1];
// Get the type, level and cp
-$arg = $data['arg'];
-$data = explode("-", $arg);
-$cp_type = $data[0];
-$cp_level = $data[1];
-$cp_value = $data[3];
+$cp_type = $data['t'];
+$cp_level = $data['l'];
+$cp_value = $data['cp'] ?? 0;
// Set boosted string
-if($cp_level == 25) {
- $boosted = '_weather_cp';
-} else {
- $boosted = '_cp';
-}
+$boosted = ($cp_level == 25) ? '_weather_cp' : '_cp';
// Action to do: Save or add digits to cp
-$action = $data[2];
+$action = $data['a'];
// Get current CP values
-$cp_old = get_pokemon_cp($dex_id, $dex_form);
-$current_cp = $cp_old[$cp_type . $boosted];
+$pokemon = get_pokemon_info($dex_id, $dex_form);
+$current_cp = $pokemon[$cp_type . $boosted];
// Log
debug_log('New CP Type: ' . $cp_type);
@@ -47,78 +42,51 @@
// Add digits to cp
if($action == 'add') {
- // Init empty keys array.
- $keys = [];
-
- // Get the keys.
- $keys = cp_keys($pokedex_id, 'pokedex_set_cp', $arg);
-
- // Back and abort.
- $keys[] = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => $pokedex_id . ':pokedex_edit_pokemon:0'
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
-
- // Build callback message string.
- $callback_response = 'OK';
-
- // Set the message.
- $msg = getTranslation('raid_boss') . ': ' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR;
- $msg .= getTranslation('pokedex_current_cp') . ' ' . $current_cp . CR . CR;
- $msg .= '' .getTranslation('pokedex_' . $cp_type . $boosted) . ': ' . $cp_value . '';
+ // Init empty keys array.
+ $keys = [];
+
+ // Get the keys.
+ $keys = cp_keys($data);
+
+ // Back and abort.
+ $keys[] = [
+ button(getTranslation('back'), ['pokedex_edit_pokemon', 'p' => $pokedex_id]),
+ button(getTranslation('abort'), 'exit')
+ ];
+
+ // Build callback message string.
+ $callback_response = 'OK';
+
+ // Set the message.
+ $msg = getTranslation('raid_boss') . ': ' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR;
+ $msg .= getTranslation('pokedex_current_cp') . ' ' . $current_cp . CR . CR;
+ $msg .= '' .getTranslation('pokedex_' . $cp_type . $boosted) . ': ' . $cp_value . '';
// Save cp to database
} else if($action == 'save') {
- // Set IV level for database
- if($cp_level == 25) {
- $weather = 'weather_cp';
- } else {
- $weather = 'cp';
- }
-
- // Set column name.
- $cp_column = $cp_type . '_' . $weather;
-
- // Update cp of pokemon.
- $rs = my_query(
- "
- UPDATE pokemon
- SET $cp_column = {$cp_value}
- WHERE pokedex_id = {$dex_id}
- AND pokemon_form_id = '{$dex_form}'
- "
- );
-
- // Init empty keys array.
- $keys = [];
-
- // Back to pokemon and done keys.
- $keys = [
- [
- [
- 'text' => getTranslation('back') . ' (' . get_local_pokemon_name($dex_id, $dex_form) . ')',
- 'callback_data' => $pokedex_id . ':pokedex_edit_pokemon:0'
- ],
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ]
- ];
-
- // Build callback message string.
- $callback_response = getTranslation('pokemon_saved') . ' ' . get_local_pokemon_name($pokedex_id);
-
- // Set the message.
- $msg = getTranslation('pokemon_saved') . CR;
- $msg .= '' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR . CR;
- $msg .= getTranslation('pokedex_' . $cp_type . $boosted) . ': ' . $cp_value . '';
+ // Set column name.
+ $cp_column = $cp_type . $boosted;
+
+ // Update cp of pokemon.
+ $rs = my_query('
+ UPDATE pokemon
+ SET ' . $cp_column . ' = ?
+ WHERE pokedex_id = ?
+ AND pokemon_form_id = ?
+ ', [$cp_value, $dex_id, $dex_form]
+ );
+
+ // Back to pokemon and done keys.
+ $keys[0][0] = button(getTranslation('back') . ' (' . get_local_pokemon_name($dex_id, $dex_form) . ')', ['pokedex_edit_pokemon', 'p' => $pokedex_id]);
+ $keys[0][1] = button(getTranslation('done') . ' (' . get_local_pokemon_name($dex_id, $dex_form) . ')', ['exit', 'd' => '1']);
+
+ // Build callback message string.
+ $callback_response = getTranslation('pokemon_saved') . ' ' . get_local_pokemon_name($dex_id, $dex_form);
+
+ // Set the message.
+ $msg = getTranslation('pokemon_saved') . CR;
+ $msg .= '' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR . CR;
+ $msg .= getTranslation('pokedex_' . $cp_type . $boosted) . ': ' . $cp_value . '';
}
// Telegram JSON array.
@@ -133,5 +101,53 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-// Exit.
-exit();
+function cp_keys($data)
+{
+ // Get the type, level and cp
+ $old_cp = $data['cp'] ?? '';
+
+ // Save and reset values
+ $saveData = $resetData = $data;
+ $saveData['a'] = 'save';
+ unset($resetData['cp']);
+
+ // Init empty keys array.
+ $keys = [];
+
+ // Max CP is 9999 and no the value 999 is not a typo!
+ // Keys will be shown up to 999 and when user is adding one more number we exceed 999, so we remove the keys then
+ // This means we do not exceed a Max CP of 9999 :)
+ if($old_cp <= 999) {
+ $buttonData = $data;
+ // Add keys 0 to 9
+ /**
+ * 7 8 9
+ * 4 5 6
+ * 1 2 3
+ * 0
+ */
+
+ // 7 8 9
+ foreach ([7, 8, 9, 4, 5, 6, 1, 2, 3] as $i) {
+ // Set new cp
+ $buttonData['cp'] = $old_cp . $i;
+ // Set keys.
+ $keys[] = button($i, $buttonData);
+ }
+
+ // 0
+ $buttonData['cp'] = $old_cp . '0';
+ $keys[] = button('0', $buttonData);
+ }
+
+ // Save
+ $keys[] = button(EMOJI_DISK, $saveData);
+
+ // Reset
+ $keys[] = button(getTranslation('reset'), $resetData);
+
+ // Get the inline key array.
+ $keys = inline_key_array($keys, 3);
+
+ return $keys;
+}
diff --git a/mods/pokedex_set_raid_level.php b/mods/pokedex_set_raid_level.php
index 4812bc4c..e9350057 100644
--- a/mods/pokedex_set_raid_level.php
+++ b/mods/pokedex_set_raid_level.php
@@ -1,107 +1,85 @@
accessCheck('pokedex');
// Set the id.
-$pokedex_id = $data['id'];
+$pokedex_id = $data['p'];
// Get the raid level.
-$arg = $data['arg'];
+$newLevel = $data['l'] ?? false;
// Split pokedex_id and form
$dex_id_form = explode('-',$pokedex_id,2);
$dex_id = $dex_id_form[0];
$dex_form = $dex_id_form[1];
+$pokemon = get_pokemon_info($dex_id, $dex_form);
+
// Set raid level or show raid levels?
-if($data['arg'] == "setlevel") {
- $raid_levels = [0,1,3,5,6,'X'];
-
- // Init empty keys array.
- $keys = [];
-
- // Create keys array.
- foreach($raid_levels as $lv) {
- $keys[] = [
- array(
- 'text' => getTranslation($lv . 'stars'),
- 'callback_data' => $pokedex_id . ':pokedex_set_raid_level:' . $lv
- )
- ];
- }
-
- // Back and abort.
- $keys[] = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => $pokedex_id . ':pokedex_edit_pokemon:0'
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
-
- // Build callback message string.
- $callback_response = getTranslation('select_raid_level');
-
- // Set the message.
- $msg = getTranslation('raid_boss') . ': ' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR;
- $old_raid_level = get_raid_level($dex_id, $dex_form);
- $msg .= getTranslation('pokedex_current_raid_level') . ' ' . getTranslation($old_raid_level . 'stars') . CR . CR;
- $msg .= '' . getTranslation('pokedex_new_raid_level') . ':';
+if($newLevel === false) {
+ $raid_levels = array_merge([0], RAID_LEVEL_ALL);
+
+ // Init empty keys array.
+ $keys = [];
+
+ // Create keys array.
+ foreach($raid_levels as $lv) {
+ $keys[][] = button(getTranslation($lv . 'stars'), ['pokedex_set_raid_level', 'p' => $pokedex_id, 'l' => $lv]);
+ }
+
+ // Back and abort.
+ $keys[] = [
+ button(getTranslation('back'), ['pokedex_edit_pokemon', 'p' => $pokedex_id]),
+ button(getTranslation('abort'), 'exit')
+ ];
+
+ // Build callback message string.
+ $callback_response = getTranslation('select_raid_level');
+
+ // Set the message.
+ $msg = getTranslation('raid_boss') . ': ' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR;
+ $msg .= getTranslation('pokedex_current_raid_level') . ' ' . getTranslation($pokemon['raid_level'] . 'stars') . CR . CR;
+ $msg .= '' . getTranslation('pokedex_new_raid_level') . ':';
} else {
- // Update raid level of pokemon.
- if($arg == 0 && get_raid_level($dex_id, $dex_form) != 0) {
- $rs = my_query(
- "
- DELETE FROM raid_bosses
- WHERE pokedex_id = '{$dex_id}'
- AND pokemon_form_id = '{$dex_form}'
- AND scheduled = 0
- "
- );
- }else {
- $rs = my_query(
- "
- INSERT INTO raid_bosses (pokedex_id, pokemon_form_id, raid_level)
- VALUES ('{$dex_id}', '{$dex_form}', '{$arg}')
- "
- );
- }
-
- // Init empty keys array.
- $keys = [];
-
- // Back to pokemon and done keys.
- $keys = [
- [
- [
- 'text' => getTranslation('back') . ' (' . get_local_pokemon_name($dex_id, $dex_form) . ')',
- 'callback_data' => $pokedex_id . ':pokedex_edit_pokemon:0'
- ],
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ]
- ];
-
- // Build callback message string.
- $callback_response = getTranslation('pokemon_saved') . ' ' . get_local_pokemon_name($dex_id, $dex_form);
-
- // Set the message.
- $msg = getTranslation('pokemon_saved') . CR;
- $msg .= '' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR . CR;
- $msg .= getTranslation('pokedex_new_raid_level') . ':' . CR;
- $msg .= '' . getTranslation($arg . 'stars') . '';
+ // Update raid level of pokemon.
+ my_query('
+ DELETE FROM raid_bosses
+ WHERE pokedex_id = ?
+ AND pokemon_form_id = ?
+ AND scheduled = 0
+ ', [$dex_id, $dex_form]
+ );
+ if($newLevel != 0) {
+ my_query('
+ INSERT INTO raid_bosses (pokedex_id, pokemon_form_id, raid_level)
+ VALUES (?, ?, ?)
+ ',
+ [$dex_id, $dex_form, $newLevel]
+ );
+ }
+
+ // Back to pokemon and done keys.
+ $keys[] = [
+ button(getTranslation('back') . ' (' . get_local_pokemon_name($dex_id, $dex_form) . ')', ['pokedex_edit_pokemon', 'p' => $pokedex_id]),
+ button(getTranslation('done'), ['exit', 'd' => '1'])
+ ];
+
+ // Build callback message string.
+ $callback_response = getTranslation('pokemon_saved') . ' ' . get_local_pokemon_name($dex_id, $dex_form);
+
+ // Set the message.
+ $msg = getTranslation('pokemon_saved') . CR;
+ $msg .= '' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR . CR;
+ $msg .= getTranslation('pokedex_new_raid_level') . ':' . CR;
+ $msg .= '' . getTranslation($newLevel . 'stars') . '';
}
// Telegram JSON array.
@@ -115,6 +93,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/pokedex_set_shiny.php b/mods/pokedex_set_shiny.php
index f3a74f4d..adaeb604 100644
--- a/mods/pokedex_set_shiny.php
+++ b/mods/pokedex_set_shiny.php
@@ -1,19 +1,20 @@
accessCheck('pokedex');
// Set the id.
-$pokedex_id = $data['id'];
+$pokedex_id = $data['p'];
// Get the shiny status.
-$arg = $data['arg'];
+$arg = $data['s'] ?? 'setshiny';
// Split pokedex_id and form
$dex_id_form = explode('-',$pokedex_id,2);
@@ -21,90 +22,48 @@
$dex_form = $dex_id_form[1];
// Set shiny or ask to set?
-if($data['arg'] == "setshiny") {
- // Get current shiny status from database.
- $shiny = get_pokemon_shiny_status($dex_id, $dex_form);
-
- // Init empty keys array.
- $keys = [];
-
- // Create keys array.
- if($shiny == 0) {
- // Enable shiny.
- $old_shiny_status = getTranslation('not_shiny');
- $keys[] = [
- array(
- 'text' => getTranslation('shiny'),
- 'callback_data' => $pokedex_id . ':pokedex_set_shiny:1'
- )
- ];
-
- } else {
- // Disable shiny.
- $old_shiny_status = getTranslation('shiny');
- $keys[] = [
- array(
- 'text' => getTranslation('not_shiny'),
- 'callback_data' => $pokedex_id . ':pokedex_set_shiny:0'
- )
- ];
- }
-
- // Back and abort.
- $keys[] = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => $pokedex_id . ':pokedex_edit_pokemon:0'
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
-
- // Build callback message string.
- $callback_response = getTranslation('select_shiny_status');
-
- // Set the message.
- $msg = getTranslation('raid_boss') . ': ' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR;
- $msg .= getTranslation('pokedex_current_status') . SP . $old_shiny_status . CR . CR;
- $msg .= '' . getTranslation('pokedex_new_status') . ':';
+if($arg == 'setshiny') {
+ // Get current shiny status from database.
+ $pokemon = get_pokemon_info($dex_id, $dex_form);
+
+ $shinyText = ($pokemon['shiny'] == 0) ? 'shiny' : 'not_shiny';
+ $old_shiny_status = ($pokemon['shiny'] == 0) ? getTranslation('not_shiny') : EMOJI_SHINY . SP . getTranslation('shiny');
+ $newShinyValue = ($pokemon['shiny'] == 0) ? 1 : 0;
+
+ // Back and abort.
+ $keys[][] = button(getTranslation($shinyText), ['pokedex_set_shiny', 'p' => $pokedex_id, 's' => $newShinyValue]);
+ $keys[][] = button(getTranslation('back'), ['pokedex_edit_pokemon', 'p' => $pokedex_id]);
+ $keys[][] = button(getTranslation('abort'), 'exit');
+
+ // Build callback message string.
+ $callback_response = getTranslation('select_shiny_status');
+
+ // Set the message.
+ $msg = getTranslation('raid_boss') . ': ' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR;
+ $msg .= getTranslation('pokedex_current_status') . SP . $old_shiny_status . CR . CR;
+ $msg .= '' . getTranslation('pokedex_new_status') . ':';
} else {
- // Update shiny status of pokemon.
- $rs = my_query(
- "
- UPDATE pokemon
- SET shiny = '{$arg}'
- WHERE pokedex_id = {$dex_id}
- AND pokemon_form_id = '{$dex_form}'
- "
- );
-
- // Init empty keys array.
- $keys = [];
-
- // Back to pokemon and done keys.
- $keys = [
- [
- [
- 'text' => getTranslation('back') . ' (' . get_local_pokemon_name($dex_id, $dex_form) . ')',
- 'callback_data' => $pokedex_id . ':pokedex_edit_pokemon:0'
- ],
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ]
- ];
-
- // Build callback message string.
- $callback_response = getTranslation('pokemon_saved') . ' ' . get_local_pokemon_name($dex_id, $dex_form);
-
- // Set the message.
- $msg = getTranslation('pokemon_saved') . CR;
- $msg .= '' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR . CR;
- $msg .= getTranslation('pokedex_new_status') . ':' . CR;
- $msg .= '' . (($arg == 1) ? (getTranslation('shiny')) : (getTranslation('not_shiny'))) . '';
+ // Update shiny status of pokemon.
+ $rs = my_query('
+ UPDATE pokemon
+ SET shiny = ?
+ WHERE pokedex_id = ?
+ AND pokemon_form_id = ?
+ ', [$arg, $dex_id, $dex_form]
+ );
+
+ // Back to pokemon and done keys.
+ $keys[0][0] = button(getTranslation('back') . ' (' . get_local_pokemon_name($dex_id, $dex_form) . ')', ['pokedex_edit_pokemon', 'p' => $pokedex_id]);
+ $keys[0][1] = button(getTranslation('done'), ['exit', 'd' => '1']);
+
+ // Build callback message string.
+ $callback_response = getTranslation('pokemon_saved') . ' ' . get_local_pokemon_name($dex_id, $dex_form);
+
+ // Set the message.
+ $msg = getTranslation('pokemon_saved') . CR;
+ $msg .= '' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR . CR;
+ $msg .= getTranslation('pokedex_new_status') . ':' . CR;
+ $msg .= '' . (($arg == 1) ? (getTranslation('shiny')) : (getTranslation('not_shiny'))) . '';
}
// Telegram JSON array.
@@ -118,6 +77,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/pokedex_set_weather.php b/mods/pokedex_set_weather.php
index d671aa4e..dc803d60 100644
--- a/mods/pokedex_set_weather.php
+++ b/mods/pokedex_set_weather.php
@@ -1,16 +1,19 @@
accessCheck('pokedex');
// Set the id.
-$pokedex_id = $data['id'];
+$pokedex_id = $data['p'];
// Split pokedex_id and form
$dex_id_form = explode('-',$pokedex_id,2);
@@ -18,82 +21,62 @@
$dex_form = $dex_id_form[1];
// Get the action, old and new weather
-$arg = $data['arg'];
-$data = explode("-", $arg);
-$action = $data[0];
-$new_weather = $data[1];
-$old_weather = get_pokemon_weather($dex_id, $dex_form);
+$action = $data['a'] ?? 'add';
+$new_weather = $data['w'] ?? 0;
+
+$pokemon = get_pokemon_info($dex_id, $dex_form);
+$old_weather = $pokemon['weather'];
// Log
debug_log('Action: ' . $action);
debug_log('Old weather: ' . $old_weather);
debug_log('New weather: ' . $new_weather);
+// Init empty keys array.
+$keys = [];
// Add weather
if($action == 'add') {
- // Init empty keys array.
- $keys = [];
-
- // Get the keys.
- $keys = weather_keys($pokedex_id, 'pokedex_set_weather', $arg);
-
- // Build callback message string.
- $callback_response = 'OK';
-
- // Back and abort.
- $keys[] = [
- [
- 'text' => getTranslation('back'),
- 'callback_data' => $pokedex_id . ':pokedex_edit_pokemon:0'
- ],
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
-
- // Set the message.
- $msg = getTranslation('raid_boss') . ': ' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR;
- $msg .= getTranslation('pokedex_current_weather') . ' ' . get_weather_icons($old_weather) . CR . CR;
- $msg .= '' . getTranslation('pokedex_new_weather') . ' ' . get_weather_icons($new_weather);
+
+ // Get the keys.
+ $keys = weather_keys($data);
+
+ // Build callback message string.
+ $callback_response = 'OK';
+
+ // Back and abort.
+ $keys[] = [
+ button(getTranslation('back'), ['pokedex_edit_pokemon', 'p' => $pokedex_id]),
+ button(getTranslation('abort'), 'exit')
+ ];
+
+ // Set the message.
+ $msg = getTranslation('raid_boss') . ': ' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR;
+ $msg .= getTranslation('pokedex_current_weather') . ' ' . get_weather_icons($old_weather) . CR . CR;
+ $msg .= '' . getTranslation('pokedex_new_weather') . ' ' . get_weather_icons($new_weather);
// Save weather to database
} else if($action == 'save') {
- // Update weather of pokemon.
- $rs = my_query(
- "
- UPDATE pokemon
- SET weather = {$new_weather}
- WHERE pokedex_id = {$dex_id}
- AND pokemon_form_id = '{$dex_form}'
- "
- );
-
- // Init empty keys array.
- $keys = [];
-
- // Back to pokemon and done keys.
- $keys = [
- [
- [
- 'text' => getTranslation('back') . ' (' . get_local_pokemon_name($dex_id, $dex_form) . ')',
- 'callback_data' => $pokedex_id . ':pokedex_edit_pokemon:0'
- ],
- [
- 'text' => getTranslation('done'),
- 'callback_data' => '0:exit:1'
- ]
- ]
- ];
-
- // Build callback message string.
- $callback_response = getTranslation('pokemon_saved') . ' ' . get_local_pokemon_name($dex_id, $dex_form);
-
- // Set the message.
- $msg = getTranslation('pokemon_saved') . CR;
- $msg .= '' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR . CR;
- $msg .= getTranslation('pokedex_weather') . ':' . CR;
- $msg .= '' . get_weather_icons($new_weather) . '';
+ // Update weather of pokemon.
+ $rs = my_query('
+ UPDATE pokemon
+ SET weather = ?
+ WHERE pokedex_id = ?
+ AND pokemon_form_id = ?
+ ', [$new_weather, $dex_id, $dex_form]
+ );
+
+ // Back to pokemon and done keys.
+ $keys[0][0] = button(getTranslation('back') . ' (' . get_local_pokemon_name($dex_id, $dex_form) . ')', ['pokedex_edit_pokemon', 'p' => $pokedex_id]);
+ $keys[0][1] = button(getTranslation('abort'), ['exit', 'd' => '1']);
+
+ // Build callback message string.
+ $callback_response = getTranslation('pokemon_saved') . ' ' . get_local_pokemon_name($dex_id, $dex_form);
+
+ // Set the message.
+ $msg = getTranslation('pokemon_saved') . CR;
+ $msg .= '' . get_local_pokemon_name($dex_id, $dex_form) . ' (#' . $dex_id . ')' . CR . CR;
+ $msg .= getTranslation('pokedex_weather') . ':' . CR;
+ $msg .= '' . get_weather_icons($new_weather) . '';
}
// Telegram JSON array.
@@ -107,6 +90,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/post_raid.php b/mods/post_raid.php
index a165074d..6de616c8 100644
--- a/mods/post_raid.php
+++ b/mods/post_raid.php
@@ -14,10 +14,7 @@
$chat = $data['arg'];
require_once(LOGIC_PATH . '/send_raid_poll.php');
-$tg_json = send_raid_poll($id, $chat);
+$tg_json = send_raid_poll($id, [create_chat_object([$chat])]);
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/raid_by_gym.php b/mods/raid_by_gym.php
deleted file mode 100644
index 58916693..00000000
--- a/mods/raid_by_gym.php
+++ /dev/null
@@ -1,62 +0,0 @@
- 1) ? $args[1] : false;
-
-// Back key id, action and arg
-$back_id = $gymarea_id;
-$back_action = 'raid_by_gym_letter';
-$back_arg = 0;
-
-// Get the keys.
-$keys = raid_edit_gym_keys($first, $gymarea_id);
-
-// No keys found.
-if (!$keys) {
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
-} else {
- // Add navigation keys.
- $nav_keys = [];
- $nav_keys[] = universal_inner_key($nav_keys, $back_id, $back_action, $back_arg, getTranslation('back'));
- $nav_keys[] = universal_inner_key($nav_keys, '0', 'exit', '0', getTranslation('abort'));
- $nav_keys = inline_key_array($nav_keys, 2);
- // Merge keys.
- $keys = array_merge($keys, $nav_keys);
-}
-
-// Build callback message string.
-$callback_response = getTranslation('here_we_go');
-
-// Telegram JSON array.
-$tg_json = array();
-
-// Answer callback.
-$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
-
-// Edit the message.
-$tg_json[] = edit_message($update, getTranslation('select_gym_name'), $keys, false, true);
-
-// Telegram multicurl request.
-curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/raid_by_gym_letter.php b/mods/raid_by_gym_letter.php
deleted file mode 100644
index a8be56b7..00000000
--- a/mods/raid_by_gym_letter.php
+++ /dev/null
@@ -1,83 +0,0 @@
- getTranslation('not_supported'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
-}
-
-// Build callback message string.
-$callback_response = getTranslation('select_gym');
-
-// Telegram JSON array.
-$tg_json = array();
-
-// Answer callback.
-$tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
-
-$msg = '';
-// Edit the message.
-if($config->ENABLE_GYM_AREAS) {
- if($keys_and_gymarea['gymarea_name'] == '') {
- $msg .= '' . getTranslation('select_gym_area') . '' . CR;
- }elseif($config->DEFAULT_GYM_AREA !== false) {
- if($keys_and_gymarea['letters']) {
- $msg .= '' . getTranslation('select_gym_first_letter_or_gym_area') . '' . CR;
- }else {
- $msg .= '' . getTranslation('select_gym_name_or_gym_area') . '' . CR;
- }
- }else {
- if($keys_and_gymarea['letters']) {
- $msg .= '' . getTranslation('select_gym_first_letter') . '' . CR;
- }else {
- $msg .= '' . getTranslation('select_gym_name') . '' . CR;
- }
- }
-}elseif($keys_and_gymarea['letters']) {
- $msg .= '' . getTranslation('select_gym_first_letter') . '' . CR;
-}else {
- $msg .= '' . getTranslation('select_gym_name') . '' . CR;
-}
-$msg.= (($keys_and_gymarea['gymarea_name'] != '') ? CR . CR . getTranslation('current_gymarea') . ': ' . $keys_and_gymarea['gymarea_name'] : '');
-$tg_json[] = edit_message($update, $msg, $keys, false, true);
-
-// Telegram multicurl request.
-curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/raid_by_location.php b/mods/raid_by_location.php
index a7ddf3df..f0761373 100644
--- a/mods/raid_by_location.php
+++ b/mods/raid_by_location.php
@@ -1,32 +1,35 @@
accessCheck('create');
// Enabled?
if(!$config->RAID_VIA_LOCATION) {
- debug_log('Creating raids by sharing a location is not enabled in config! Exiting!');
- send_message($update['message']['chat']['id'], '' . getTranslation('bot_access_denied') . '');
- exit();
+ debug_log('Creating raids by sharing a location is not enabled in config! Exiting!');
+ send_message(create_chat_object([$update['message']['chat']['id']]), '' . getTranslation('bot_access_denied') . '');
+ exit();
}
$reg_exp_coordinates = '^[-+]?([1-8]?\d(\.\d+)?|90(\.0+)?),\s*[-+]?(180(\.0+)?|((1[0-7]\d)|([1-9]?\d))(\.\d+)?)$^';
// Get latitude / longitude values from Telegram
if(isset($update['message']['location']) && preg_match($reg_exp_coordinates, $update['message']['location']['latitude'] . ',' . $update['message']['location']['longitude'])) {
- $lat = $update['message']['location']['latitude'];
- $lon = $update['message']['location']['longitude'];
+ $lat = $update['message']['location']['latitude'];
+ $lon = $update['message']['location']['longitude'];
} else if(isset($update['callback_query']) && preg_match($reg_exp_coordinates, $data['id'] . ',' . $data['arg'])) {
- $lat = $data['id'];
- $lon = $data['arg'];
+ $lat = $data['id'];
+ $lon = $data['arg'];
} else {
- send_message($update['message']['chat']['id'], '' . getTranslation('invalid_input') . '');
- exit();
+ send_message(create_chat_object([$update['message']['chat']['id']]), '' . getTranslation('invalid_input') . '');
+ exit();
}
// Debug
@@ -39,103 +42,96 @@
// Temporary gym_name
if($config->RAID_VIA_LOCATION_FUNCTION == 'remote') {
- $gym_name = getPublicTranslation('remote_raid') . ': '.$addr['district'];
- $gym = false;
- $gym_letter = substr($gym_name, 0, 1);
+ $gym_name = getPublicTranslation('remote_raid') . ': '.$addr['district'];
+ $gym = false;
+ $gym_letter = substr($gym_name, 0, 1);
}else {
- $gym_name = '#' . $update['message']['chat']['id'];
- $gym_letter = substr($gym_name, 0, 1);
- // Get gym by temporary name.
- $gym = get_gym_by_telegram_id($gym_name);
+ $gym_name = '#' . $update['message']['chat']['id'];
+ $gym_letter = substr($gym_name, 0, 1);
+ // Get gym by temporary name.
+ $gym = get_gym_by_telegram_id($gym_name);
}
// If gym is already in the database, make sure no raid is active before continuing!
if($gym) {
- debug_log('Gym found in the database! Checking for active raid now!');
- $gym_id = $gym['id'];
+ debug_log('Gym found in the database! Checking for active raid now!');
+ $gym_id = $gym['id'];
- // Check for duplicate raid
- $duplicate_id = 0;
- $duplicate_id = active_raid_duplication_check($gym_id);
+ // Check for duplicate raid
+ $duplicate_id = 0;
+ $duplicate_id = active_raid_duplication_check($gym_id);
- // Continue with raid creation
- if($duplicate_id > 0) {
- debug_log('Active raid is in progress!');
- debug_log('Tell user to update the gymname and exit!');
+ // Continue with raid creation
+ if($duplicate_id > 0) {
+ debug_log('Active raid is in progress!');
+ debug_log('Tell user to update the gymname and exit!');
- // Show message that a raid is active on that gym.
- $raid_id = $duplicate_id;
- $raid = get_raid($raid_id);
+ // Show message that a raid is active on that gym.
+ $raid_id = $duplicate_id;
+ $raid = get_raid($raid_id);
- // Build message.
- $msg = EMOJI_WARN . SP . getTranslation('raid_already_exists') . SP . EMOJI_WARN . CR . show_raid_poll_small($raid);
+ // Build message.
+ $msg = EMOJI_WARN . SP . getTranslation('raid_already_exists') . SP . EMOJI_WARN . CR . show_raid_poll_small($raid);
- // Tell user to update the gymname first to create another raid by location
- $msg .= getTranslation('gymname_then_location');
- $keys = [];
+ // Tell user to update the gymname first to create another raid by location
+ $msg .= getTranslation('gymname_then_location');
+ $keys = [];
- // Send message.
- send_message($update['message']['chat']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
+ // Send message.
+ send_message(create_chat_object([$update['message']['chat']['id']]), $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
- exit();
- } else {
- debug_log('No active raid found! Continuing now ...');
- }
+ exit();
+ } else {
+ debug_log('No active raid found! Continuing now ...');
+ }
} else {
- // Set gym_id to 0
- $gym_id = 0;
- debug_log('No gym found in the database! Continuing now ...');
+ // Set gym_id to 0
+ $gym_id = 0;
+ debug_log('No gym found in the database! Continuing now ...');
}
// Insert / update gym.
-try {
-
- global $dbh;
-
- // Build query to check if gym is already in database or not
- $rs = my_query("
- SELECT COUNT(*) AS count
- FROM gyms
- WHERE gym_name = '{$gym_name}'
- ");
-
- $row = $rs->fetch();
- $parameters = [ 'gym_name' => $gym_name,
- 'lat' => $lat,
- 'lon' => $lon,
- 'address' => $address,
- ];
- // Gym already in database or new
- if (empty($row['count']) or $config->RAID_VIA_LOCATION_FUNCTION == 'remote') {
- // insert gym in table.
- debug_log('Gym not found in database gym list! Inserting gym "' . $gym_name . '" now.');
- $parameters['img_url'] = 'file://' . IMAGES_PATH . '/gym_default.png';
- $query = '
- INSERT INTO gyms (gym_name, lat, lon, address, show_gym, img_url, temporary_gym)
- VALUES (:gym_name, :lat, :lon, :address, 0, :img_url, 1)
- ';
- } else {
- // Update gyms table to reflect gym changes.
- debug_log('Gym found in database gym list! Updating gym "' . $gym_name . '" now.');
- $query = '
- UPDATE gyms
- SET lat = :lat,
- lon = :lon,
- address = :address
- WHERE gym_name = :gym_name
- ';
- }
- $statement = $dbh->prepare($query);
- $statement->execute($parameters);
- // Get gym id from insert.
- if($gym_id == 0) {
- $gym_id = $dbh->lastInsertId();
- }
-} catch (PDOException $exception) {
-
- error_log($exception->getMessage());
- $dbh = null;
- exit();
+
+// Build query to check if gym is already in database or not
+$rs = my_query('
+ SELECT COUNT(*) AS count
+ FROM gyms
+ WHERE gym_name = ?
+ ',[$gym_name]
+);
+
+$row = $rs->fetch();
+$parameters = [
+ 'gym_name' => $gym_name,
+ 'lat' => $lat,
+ 'lon' => $lon,
+ 'address' => $address,
+];
+// Gym already in database or new
+if (empty($row['count']) or $config->RAID_VIA_LOCATION_FUNCTION == 'remote') {
+ // insert gym in table.
+ debug_log('Gym not found in database gym list! Inserting gym "' . $gym_name . '" now.');
+ $parameters['img_url'] = 'file://' . IMAGES_PATH . '/gym_default.png';
+ $parameters['temp'] = ($config->RAID_VIA_LOCATION_FUNCTION == 'remote') ? 1 : 0;
+ $query = '
+ INSERT INTO gyms (gym_name, lat, lon, address, show_gym, img_url, temporary_gym)
+ VALUES (:gym_name, :lat, :lon, :address, 0, :img_url, :temp)
+ ';
+} else {
+ // Update gyms table to reflect gym changes.
+ debug_log('Gym found in database gym list! Updating gym "' . $gym_name . '" now.');
+ $query = '
+ UPDATE gyms
+ SET lat = :lat,
+ lon = :lon,
+ address = :address
+ WHERE gym_name = :gym_name
+ ';
+}
+$statement = my_query($query, $parameters);
+// Get gym id from insert.
+if($gym_id == 0) {
+ $gym_id = $dbh->lastInsertId();
}
// Write to log.
@@ -143,46 +139,31 @@
debug_log('Gym Name: ' . $gym_name);
// Create the keys.
-$keys = [
- [
- [
- 'text' => getTranslation('next'),
- 'callback_data' => $gym_letter . ':edit_raidlevel:' . $gym_id
- ]
- ],
- [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => $gym_id . ':exit:2'
- ]
- ]
-];
+$keys[][] = button(getTranslation('next'), ['edit_raidlevel', 'gl' => $gym_letter, 'g' => $gym_id, 'z' => 1]);
+$keys[][] = button(getTranslation('abort'), 'exit');
// Answer location message.
if(isset($update['message']['location'])) {
- // Build message.
- $msg = getTranslation('create_raid') . ': ' . $address . '';
+ // Build message.
+ $msg = getTranslation('create_raid') . ': ' . $address . '';
- // Send message.
- send_message($update['message']['chat']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
+ // Send message.
+ send_message(create_chat_object([$update['message']['chat']['id']]), $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
// Answer forwarded location message from geo_create.
} else if(isset($update['callback_query'])) {
- // Build callback message string.
- $callback_response = getTranslation('here_we_go');
+ // Build callback message string.
+ $callback_response = getTranslation('here_we_go');
- // Telegram JSON array.
- $tg_json = array();
+ // Telegram JSON array.
+ $tg_json = array();
- // Answer callback.
- $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
+ // Answer callback.
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
- // Edit the message.
- $tg_json[] = edit_message($update, getTranslation('select_gym_name'), $keys, false, true);
+ // Edit the message.
+ $tg_json[] = edit_message($update, getTranslation('select_gym_name'), $keys, false, true);
- // Telegram multicurl request.
- curl_json_multi_request($tg_json);
+ // Telegram multicurl request.
+ curl_json_multi_request($tg_json);
}
-
-// Exit.
-exit();
diff --git a/mods/raid_edit_poke.php b/mods/raid_edit_poke.php
index 546f1833..83b3c2af 100644
--- a/mods/raid_edit_poke.php
+++ b/mods/raid_edit_poke.php
@@ -1,4 +1,5 @@
raidaccessCheck($raid_id, 'pokemon');
// Get raid level
-$raid_level = $data['arg'];
+$raid_level = $data['rl'];
debug_log('Raid level of pokemon: ' . $raid_level);
// Level found
if ($raid_level != '0') {
- // Get the keys.
- $keys = pokemon_keys($raid_id, $raid_level, 'raid_set_poke');
-
- // Add navigation keys.
- $nav_keys = [];
- $nav_keys[] = universal_inner_key($nav_keys, '0', 'exit', '0', getTranslation('abort'));
- $nav_keys = inline_key_array($nav_keys, 1);
+ // Get the keys.
+ $keys = pokemon_keys($data, $raid_level, 'raid_set_poke');
- // Merge keys.
- $keys = array_merge($keys, $nav_keys);
+ $keys[][] = button(getTranslation('abort'), 'exit');
} else {
- // Create the keys.
- $keys = [
- [
- [
- 'text' => getTranslation('not_supported'),
- 'callback_data' => '0:exit:0'
- ]
- ]
- ];
+ // Create the keys.
+ $keys[][] = button(getTranslation('not_supported'), 'exit');
}
// Build callback message string.
@@ -55,13 +43,10 @@
$msg = getTranslation('raid_boss') . ':' . SP . get_local_pokemon_name($raid['pokemon'],$raid['pokemon_form']) . CR . CR;
$msg .= '' . getTranslation('select_raid_boss') . ':';
if (isset($update['callback_query']['inline_message_id'])) {
- $tg_json[] = editMessageText($update['callback_query']['inline_message_id'], $msg, $keys, NULL, false, true);
+ $tg_json[] = editMessageText($update['callback_query']['inline_message_id'], $msg, $keys, NULL, false, true);
} else {
- $tg_json[] = editMessageText($update['callback_query']['message']['message_id'], $msg, $keys, $update['callback_query']['message']['chat']['id'], $keys, true);
+ $tg_json[] = editMessageText($update['callback_query']['message']['message_id'], $msg, $keys, $update['callback_query']['message']['chat']['id'], $keys, true);
}
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/raid_set_poke.php b/mods/raid_set_poke.php
index 0bd7f9ee..2d880362 100644
--- a/mods/raid_set_poke.php
+++ b/mods/raid_set_poke.php
@@ -1,30 +1,33 @@
raidaccessCheck($raidId, 'pokemon');
-// Set the id.
-$id = $data['id'];
-$pokemon_id_form = get_pokemon_by_table_id($data['arg']);
+$pokemon_id_form = get_pokemon_by_table_id($data['p']);
// Update pokemon in the raid table.
-my_query(
- "
- UPDATE raids
- SET pokemon = '{$pokemon_id_form['pokedex_id']}',
- pokemon_form = '{$pokemon_id_form['pokemon_form_id']}'
- WHERE id = {$id}
- "
+my_query('
+ UPDATE raids
+ SET pokemon = ?,
+ pokemon_form = ?
+ WHERE id = ?
+ ',[$pokemon_id_form['pokedex_id'], $pokemon_id_form['pokemon_form_id'], $raidId]
);
// Get raid times.
-$raid = get_raid($data['id']);
+$raid = get_raid($raidId);
// Create the keys.
$keys = [];
@@ -48,13 +51,10 @@
// Update the shared raid polls.
require_once(LOGIC_PATH .'/update_raid_poll.php');
-$tg_json = update_raid_poll($id, $raid, false, $tg_json, false);
+$tg_json = update_raid_poll($raidId, $raid, false, $tg_json, true);
// Alert users.
$tg_json = alarm($raid, $update['callback_query']['from']['id'], 'new_boss', '', $tg_json);
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/raid_share.php b/mods/raid_share.php
index d8bd51be..5588cf2b 100644
--- a/mods/raid_share.php
+++ b/mods/raid_share.php
@@ -7,16 +7,17 @@
//debug_log($update);
//debug_log($data);
-// Access check.
-raid_access_check($update, $data, 'share');
-
// Get raid id.
-$id = $data['id'];
+$raidId = $data['r'];
-// Get chat id.
-$chat = $data['arg'];
+// Access check.
+$botUser->raidaccessCheck($raidId, 'share');
-$tg_json = send_raid_poll($id, $chat);
+// Get chat id.
+$chat = $data['c'];
+$thread = $data['t'] ?? '';
+$chatObj = [['id' => $chat, 'thread' => $thread]];
+$tg_json = send_raid_poll($raidId, $chatObj);
// Set callback keys and message
$callback_msg = getTranslation('successfully_shared');
@@ -30,7 +31,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-$dbh = null;
-exit();
diff --git a/mods/raids_delete.php b/mods/raids_delete.php
index a6d377f2..e422c280 100644
--- a/mods/raids_delete.php
+++ b/mods/raids_delete.php
@@ -1,68 +1,105 @@
Confirmation required
// 1 -> Cancel deletion
// 2 -> Execute deletion
-$action = $data['arg'];
+$action = $data['a'] ?? 0;
// Get the raid id.
-$id = $data['id'];
+$raidId = $data['r'];
+
+// Access check.
+$botUser->raidaccessCheck($raidId, 'delete');
// Execute the action.
if ($action == 0) {
- // Get raid.
- $raid = get_raid($id);
-
- // Write to log.
- debug_log('Asking for confirmation to delete the following raid:');
- debug_log($raid);
-
- // Create keys array.
- $keys = [
- [
- [
- 'text' => getTranslation('yes'),
- 'callback_data' => $raid['id'] . ':raids_delete:2'
- ],
- [
- 'text' => getTranslation('no'),
- 'callback_data' => $raid['id'] . ':raids_delete:1'
- ]
- ]
- ];
-
- // Set message.
- $msg = EMOJI_WARN . ' ' . getTranslation('delete_this_raid') . ' ' . EMOJI_WARN . CR . CR;
- $msg .= show_raid_poll_small($raid);
-} else if ($action == 1) {
- debug_log('Raid deletion for ' . $id . ' was canceled!');
- // Set message.
- $msg = '' . getTranslation('raid_deletion_was_canceled') . '';
+ // Get raid.
+ $raid = get_raid($raidId);
- // Set keys.
- $keys = [];
-} else if ($action == 2) {
- debug_log('Confirmation to delete raid ' . $id . ' was received!');
- // Set message.
- $msg = getTranslation('raid_successfully_deleted');
+ // Write to log.
+ debug_log('Asking for confirmation to delete the following raid:');
+ debug_log($raid);
- // Set keys.
- $keys = [];
+ // Create keys array.
+ $keys[0][0] = button(getTranslation('yes'), ['raids_delete', 'r' => $raid['id'], 'a' => 2]);
+ $keys[0][1] = button(getTranslation('no'), ['raids_delete', 'r' => $raid['id'], 'a' => 1]);
- // Delete raid from database.
- delete_raid($id);
+ // Set message.
+ $msg = EMOJI_WARN . ' ' . getTranslation('delete_this_raid') . ' ' . EMOJI_WARN . CR . CR;
+ $msg .= show_raid_poll_small($raid);
+} else if ($action == 1) {
+ debug_log('Raid deletion for ' . $raidId . ' was canceled!');
+ // Set message.
+ $msg = '' . getTranslation('raid_deletion_was_canceled') . '';
+
+ // Set keys.
+ $keys = [];
+} else if ($action == 2) {
+ debug_log('Confirmation to delete raid ' . $raidId . ' was received!');
+ // Delete telegram messages for raid.
+ $rs = my_query('
+ SELECT *
+ FROM cleanup
+ WHERE raid_id = ?
+ AND chat_id <> 0
+ ', [$raidId]
+ );
+
+ // Counter
+ $counter = 0;
+
+ // Delete every telegram message
+ while ($row = $rs->fetch()) {
+ // Delete telegram message.
+ debug_log('Deleting telegram message ' . $row['message_id'] . ' from chat ' . $row['chat_id'] . ' for raid ' . $row['raid_id']);
+ delete_message($row['chat_id'], $row['message_id']);
+ $counter = $counter + 1;
+ }
+
+ // Nothing to delete on telegram.
+ if ($counter == 0) {
+ debug_log('Raid with ID ' . $raidId . ' was not found in the cleanup table! Skipping deletion of telegram messages!');
+ }
+
+ // Delete raid from cleanup table.
+ debug_log('Deleting raid ' . $raidId . ' from the cleanup table:');
+ my_query('
+ DELETE FROM cleanup
+ WHERE raid_id = ?
+ ', [$raidId]
+ );
+
+ // Delete raid from attendance table.
+ debug_log('Deleting raid ' . $raidId . ' from the attendance table:');
+ my_query('
+ DELETE FROM attendance
+ WHERE raid_id = ?
+ ', [$raidId]
+ );
+
+ // Delete raid from raid table.
+ debug_log('Deleting raid ' . $raidId . ' from the raid table:');
+ my_query('
+ DELETE FROM raids
+ WHERE id = ?
+ ', [$raidId]
+ );
+
+ // Set message.
+ $msg = getTranslation('raid_successfully_deleted');
+
+ // Set keys.
+ $keys = [];
}
-
+
// Build callback message string.
$callback_response = 'OK';
@@ -77,6 +114,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/raids_list.php b/mods/raids_list.php
index a247e7a1..b14c9e97 100644
--- a/mods/raids_list.php
+++ b/mods/raids_list.php
@@ -1,54 +1,42 @@
accessCheck('list');
// Get raid details.
-$raid = get_raid($id);
+$raid = get_raid($raidId);
// Create keys array.
-$keys = [
- [
- [
- 'text' => getTranslation('expand'),
- 'callback_data' => $raid['id'] . ':vote_refresh:0',
- ]
- ],
- [
- [
- 'text' => getTranslation('update_pokemon'),
- 'callback_data' => $raid['id'] . ':raid_edit_poke:' . $raid['level'],
- ]
- ],
- [
- [
- 'text' => getTranslation('delete'),
- 'callback_data' => $raid['id'] . ':raids_delete:0'
- ]
- ]
-];
+$keys = [];
+// Probably unused feature. Will fix if someone needs this
+// $keys[][] = button(getTranslation('expand'), ['vote_refresh', 'r' => $raid['id']]);
+if($botUser->raidaccessCheck($raidId, 'pokemon', true)) {
+ $keys[][] = button(getTranslation('update_pokemon'), ['raid_edit_poke', 'r' => $raid['id'], 'rl' => $raid['level']]);
+}
+if($botUser->raidaccessCheck($raidId, 'delete', true)) {
+ $keys[][] = button(getTranslation('delete'), ['raids_delete', 'r' => $raid['id']]);
+}
// Add keys to share.
debug_log($raid, 'raw raid data for share: ');
-$keys_share = share_keys($raid['id'], 'raid_share', $update, '', '', false, $raid['level']);
-if(is_array($keys_share)) {
- $keys = array_merge($keys, $keys_share);
+$keys_share = share_keys($raid['id'], 'raid_share', $update, $raid['level']);
+if(!empty($keys_share)) {
+ $keys = array_merge($keys, $keys_share);
} else {
- debug_log('There are no groups to share to, is SHARE_CHATS set?');
+ debug_log('There are no groups to share to, is SHARE_CHATS set?');
}
// Exit key
-$empty_exit_key = [];
-$key_exit = universal_key($empty_exit_key, '0', 'exit', '1', getTranslation('done'));
-$keys = array_merge($keys, $key_exit);
+$keys[][] = button(getTranslation('done'), 'exit');
// Get message.
$msg = show_raid_poll_small($raid);
@@ -67,6 +55,3 @@
// Telegram multicurl request.
curl_json_multi_request($tg_json);
-
-// Exit.
-exit();
diff --git a/mods/refresh_polls.php b/mods/refresh_polls.php
index d3d58f73..acac4e23 100644
--- a/mods/refresh_polls.php
+++ b/mods/refresh_polls.php
@@ -1,39 +1,37 @@
AUTO_REFRESH_POLLS) {
- if(strlen($data['id']) > 5) $where_chat = 'chat_id = '.$data['id']; else $where_chat = 'chat_id != 0';
- if(!empty($config->RAID_POLL_HIDE_BUTTONS_RAID_LEVEL)) $level_exclude = 'AND raids.level NOT IN ('.$config->RAID_POLL_HIDE_BUTTONS_RAID_LEVEL.')'; else $level_exclude = '';
- $query_messages = my_query("
- SELECT cleanup.*
- FROM cleanup
- LEFT JOIN raids
- ON cleanup.raid_id = raids.id
- WHERE {$where_chat}
- AND cleanup.type IN ('poll_text', 'poll_photo')
- AND raids.start_time <= UTC_TIMESTAMP()
- AND raids.end_time > DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 MINUTE)
- AND message_id != 0
- {$level_exclude}
- ");
- debug_log("REFRESH POLLS:");
- debug_log("Num rows: ".$query_messages->rowCount());
- $tg_json = [];
- while($res_messages = $query_messages->fetch()) {
+if(!$config->AUTO_REFRESH_POLLS) {
+ info_log("Automatic refresh of raid polls failed, AUTO_REFRESH_POLLS is set to false in config.");
+ exit();
+}
+if(strlen($data['id']) > 5) $where_chat = 'chat_id = '.$data['id']; else $where_chat = 'chat_id != 0';
+if(!empty($config->RAID_POLL_HIDE_BUTTONS_RAID_LEVEL)) $level_exclude = 'AND raids.level NOT IN ('.$config->RAID_POLL_HIDE_BUTTONS_RAID_LEVEL.')'; else $level_exclude = '';
+$query_messages = my_query('
+ SELECT cleanup.raid_id, cleanup.chat_id, cleanup.thread_id, cleanup.message_id, cleanup.type, cleanup.media_unique_id
+ FROM cleanup
+ LEFT JOIN raids
+ ON cleanup.raid_id = raids.id
+ WHERE ' .$where_chat . '
+ AND cleanup.type IN (\'poll_text\', \'poll_photo\', \'photo\')
+ AND raids.start_time <= UTC_TIMESTAMP()
+ AND raids.end_time > DATE_SUB(UTC_TIMESTAMP(), INTERVAL 1 MINUTE)
+ AND message_id != 0
+ ' . $level_exclude
+);
+debug_log("REFRESH POLLS:");
+debug_log("Num rows: ".$query_messages->rowCount());
+$tg_json = [];
+while($res_messages = $query_messages->fetch()) {
- debug_log("message id: ".$res_messages['message_id']);
- debug_log("chat id: ".$res_messages['chat_id']);
- debug_log("raid id: ".$res_messages['raid_id']);
+ debug_log("message id: ".$res_messages['message_id']);
+ debug_log("chat id: ".$res_messages['chat_id']);
+ debug_log("raid id: ".$res_messages['raid_id']);
- $data_poll['push']['message_id']=$res_messages['message_id'];
- $data_poll['push']['chat_id']=$res_messages['chat_id'];
- $data_poll['push']['type']=$res_messages['type'];
+ $data_poll['push'] = $res_messages;
- require_once(LOGIC_PATH . '/update_raid_poll.php');
- $tg_json = update_raid_poll($res_messages['raid_id'], false, $data_poll, $tg_json, false);
- }
- curl_json_multi_request($tg_json);
-}else {
- info_log("Automatic refresh of raid polls failed, AUTO_REFRESH_POLLS is set to false in config.");
+ require_once(LOGIC_PATH . '/update_raid_poll.php');
+ $tg_json = update_raid_poll($res_messages['raid_id'], get_raid($res_messages['raid_id']), $data_poll, $tg_json);
}
-exit();
\ No newline at end of file
+curl_json_multi_request($tg_json);
+exit();
diff --git a/mods/save_event_note.php b/mods/save_event_note.php
index f00cb97f..43be6af5 100644
--- a/mods/save_event_note.php
+++ b/mods/save_event_note.php
@@ -1,6 +1,7 @@
prepare("UPDATE raids SET event_note=:text WHERE id = :id");
-$query->execute([':text' => $update['message']['text'], ':id' => $raid_id]);
+my_query('UPDATE raids SET event_note=:text WHERE id = :id', [':text' => $update['message']['text'], ':id' => $raid_id]);
// Remove back button from previous message to avoid confusion
edit_message_keyboard($modifiers['old_message_id'], [], $user_id);
// Return message to user
+$raid = get_raid($raid_id);
$msg = '';
$msg .= getTranslation('raid_saved') . CR;
$msg .= CR.getTranslation('event_note').': '.$update['message']['text'].CR2;
-$msg .= show_raid_poll_small(get_raid($raid_id)) . CR;
+$msg .= show_raid_poll_small($raid) . CR;
debug_log($msg);
-$keys = [
- [
- [
- 'text' => getTranslation('event_note_edit'),
- 'callback_data' => $raid_id . ':edit_event_note:edit'
- ]
- ],
- [
- [
- 'text' => getTranslation('delete'),
- 'callback_data' => $raid_id . ':raids_delete:0'
- ]
- ]
-];
-$keys_share = share_keys($raid_id, 'raid_share', $update, $chats);
+$keys[][] = button(getTranslation('event_note_edit'), ['edit_event_note', 'r' => $raid_id, 'm' => 'e']);
+$keys[][] = button(getTranslation('delete'), ['raids_delete', 'r' => $raid_id]);
+$keys_share = share_keys($raid_id, 'raid_share', $update, $raid['level']);
$keys = array_merge($keys, $keys_share);
debug_log($keys);
// Send response message to user
-send_message($user_id, $msg, $keys, []);
+send_message(create_chat_object([$user_id]), $msg, $keys, []);
diff --git a/mods/save_gym_info.php b/mods/save_gym_info.php
new file mode 100644
index 00000000..2d8140da
--- /dev/null
+++ b/mods/save_gym_info.php
@@ -0,0 +1,55 @@
+ $lat,
+ ':lon' => $lon,
+ ':id' => $gym_id,
+ ];
+ $gym['lat'] = $lat;
+ $gym['lon'] = $lon;
+}else if(in_array($action, ['addr','name','note'])) {
+ if(strlen($input) > 255) {
+ send_message(create_chat_object([$user_id]), getTranslation('gym_edit_text_too_long'));
+ exit();
+ }
+ $column_map = ['addr' => 'address', 'name' => 'gym_name', 'note' => 'gym_note'];
+ $query = 'UPDATE gyms SET ' . $column_map[$action] . ' = :value WHERE id = :id';
+ $binds = [
+ ':value' => $input,
+ ':id' => $gym_id,
+ ];
+ $gym[$column_map[$action]] = $input;
+}
+if($query !== false) {
+ my_query($query, $binds);
+
+ $msg = get_gym_details($gym, true);
+ $msg .= CR . CR . getTranslation('gym_saved');
+ $update['callback_query']['from']['id'] = $user_id;
+ $keys = edit_gym_keys($update, $gym_id, $gym['show_gym'], $gym['ex_gym'], $gym['gym_note'], $gym['address']);
+}
+// Remove back button from previous message to avoid confusion
+editMessageText($modifiers['old_message_id'], $msg, $keys, $user_id, ['disable_web_page_preview' => 'true']);
diff --git a/mods/share_raid_by_location.php b/mods/share_raid_by_location.php
index 2f542ee0..2435d262 100644
--- a/mods/share_raid_by_location.php
+++ b/mods/share_raid_by_location.php
@@ -1,155 +1,140 @@
' . getTranslation('invalid_input') . '');
- exit();
- }
- $gps_diff = (float)0.01;
-
- // Build query.
- $rs = my_query(
- '
- SELECT raids.*,
- gyms.lat, gyms.lon, gyms.address, gyms.gym_name, gyms.ex_gym,
- users.name,
- TIME_FORMAT(TIMEDIFF(raids.end_time, UTC_TIMESTAMP()) + INTERVAL 1 MINUTE, \'%k:%i\') AS t_left
- FROM raids
- LEFT JOIN gyms
- ON raids.gym_id = gyms.id
- LEFT JOIN users
- ON raids.user_id = users.user_id
- WHERE raids.end_time>UTC_TIMESTAMP()
- AND gyms.lat BETWEEN \''.($lat-$gps_diff).'\' AND \''.($lat+$gps_diff).'\'
- AND gyms.lon BETWEEN \''.($lon-$gps_diff).'\' AND \''.($lon+$gps_diff).'\'
- ORDER BY raids.end_time ASC LIMIT 20
- '
- );
-
- // Count results.
- $count = 0;
-
- // Init text and keys.
- $text = '';
- $keys = [];
-
- // Get raids.
- while ($raid = $rs->fetch()) {
- // Set text and keys.
- $gym_name = $raid['gym_name'];
- if(empty($gym_name)) {
- $gym_name = '';
- }
-
- $text .= $gym_name . CR;
- $raid_day = dt2date($raid['start_time']);
- $now = utcnow();
- $today = dt2date($now);
- $start = dt2time($raid['start_time']);
- $end = dt2time($raid['end_time']);
- $time_left = $raid['t_left'];
- if ($now < $start) {
- $text .= get_raid_times($raid, true);
- // Raid has started already
- } else {
- // Add time left message.
- $text .= get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form']) . ' — ' . getPublicTranslation('still') . SP . $time_left . 'h' . CR . CR;
- }
-
-
- // Split pokemon and form to get the pokedex id.
- $pokedex_id = explode('-', $raid['pokemon'])[0];
-
- // Pokemon is an egg?
- $eggs = $GLOBALS['eggs'];
- if(in_array($pokedex_id, $eggs)) {
- $keys_text = EMOJI_EGG . SP . $gym_name;
- } else {
- $keys_text = $gym_name;
- }
-
- $keys[] = array(
- 'text' => $keys_text,
- 'callback_data' => $raid['id'] . ':share_raid_by_location:1'
- );
-
- // Counter++
- $count = $count + 1;
- }
-
- // Set message.
- if($count == 0) {
- $msg = '' . getTranslation('no_active_raids_found') . '';
- } else {
- // Get the inline key array.
- $keys = inline_key_array($keys, 1);
-
- // Add exit key.
- $keys[] = [
- [
- 'text' => getTranslation('abort'),
- 'callback_data' => '0:exit:0'
- ]
- ];
-
- // Build message.
- $msg = '' . getTranslation('list_all_active_raids') . ':' . CR;
- $msg .= $text;
- $msg .= '' . getTranslation('select_gym_name') . '' . CR;
- }
-
- // Send message.
- send_message($update['message']['chat']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
+$botUser->accessCheck('share-all');
+
+if(isset($data['a']) && $data['a'] == 1) {
+ $raid_id = $data['r'];
+
+ // Get raid details.
+ $raid = get_raid($raid_id);
+
+ $keys = [];
+
+ // Add keys to share.
+ debug_log($raid, 'raw raid data for share: ');
+ $keys_share = share_keys($raid['id'], 'raid_share', $update, $raid['level']);
+ if(!empty($keys_share)) {
+ $keys = array_merge($keys, $keys_share);
+ } else {
+ debug_log('There are no groups to share to, is SHARE_CHATS set?');
+ }
+ // Exit key
+ $keys[][] = button(getTranslation('done'), ['exit', 'd' => 1]);
+
+ // Get message.
+ $msg = show_raid_poll_small($raid);
+
+ // Build callback message string.
+ $callback_response = 'OK';
+
+ // Telegram JSON array.
+ $tg_json = array();
+
+ // Answer callback.
+ $tg_json[] = answerCallbackQuery($update['callback_query']['id'], $callback_response, true);
+
+ // Edit message.
+ $tg_json[] = edit_message($update, $msg, $keys, false, true);
+
+ // Telegram multicurl request.
+ curl_json_multi_request($tg_json);
+ exit;
+}
+if(!isset($update['message']['location'])) {
+ send_message(create_chat_object([$update['message']['chat']['id']]), '' . getTranslation('invalid_input') . '');
+ exit();
+}
+$lat = (float)$update['message']['location']['latitude'];
+$lon = (float)$update['message']['location']['longitude'];
+$gps_diff = (float)0.01;
+
+// Build query.
+$rs = my_query('
+ SELECT raids.*,
+ gyms.lat, gyms.lon, gyms.address, gyms.gym_name, gyms.ex_gym,
+ users.name,
+ TIME_FORMAT(TIMEDIFF(raids.end_time, UTC_TIMESTAMP()) + INTERVAL 1 MINUTE, \'%k:%i\') AS t_left
+ FROM raids
+ LEFT JOIN gyms
+ ON raids.gym_id = gyms.id
+ LEFT JOIN users
+ ON raids.user_id = users.user_id
+ WHERE raids.end_time>UTC_TIMESTAMP()
+ AND gyms.lat BETWEEN \''.($lat-$gps_diff).'\' AND \''.($lat+$gps_diff).'\'
+ AND gyms.lon BETWEEN \''.($lon-$gps_diff).'\' AND \''.($lon+$gps_diff).'\'
+ ORDER BY raids.end_time ASC LIMIT 20
+');
+
+// Count results.
+$count = 0;
+
+// Init text and keys.
+$text = '';
+$keys = [];
+
+// Get raids.
+while ($raid = $rs->fetch()) {
+ // Set text and keys.
+ $gym_name = $raid['gym_name'];
+ if(empty($gym_name)) {
+ $gym_name = '';
+ }
+
+ $text .= $gym_name . CR;
+ $raid_day = dt2date($raid['start_time']);
+ $now = utcnow();
+ $today = dt2date($now);
+ $start = dt2time($raid['start_time']);
+ $end = dt2time($raid['end_time']);
+ $time_left = $raid['t_left'];
+ if ($now < $start) {
+ $text .= get_raid_times($raid, $botUser->userLanguage);
+ // Raid has started already
+ } else {
+ // Add time left message.
+ $text .= get_local_pokemon_name($raid['pokemon'], $raid['pokemon_form']) . ' — ' . getPublicTranslation('still') . SP . $time_left . 'h' . CR . CR;
+ }
+
+ // Split pokemon and form to get the pokedex id.
+ $pokedex_id = explode('-', $raid['pokemon'])[0];
+
+ // Pokemon is an egg?
+ if(in_array($pokedex_id, EGGS)) {
+ $keys_text = EMOJI_EGG . SP . $gym_name;
+ } else {
+ $keys_text = $gym_name;
+ }
+
+ $keys[] = button($keys_text, ['share_raid_by_location', 'r' => $raid['id'], 'a' => 1]);
+
+ // Counter++
+ $count = $count + 1;
+}
+
+// Set message.
+if($count == 0) {
+ $msg = '' . getTranslation('no_active_raids_found') . '';
+} else {
+ // Get the inline key array.
+ $keys = inline_key_array($keys, 1);
+
+ // Add exit key.
+ $keys[][] = button(getTranslation('abort'), 'exit');
+
+ // Build message.
+ $msg = '' . getTranslation('list_all_active_raids') . ':' . CR;
+ $msg .= $text;
+ $msg .= '' . getTranslation('select_gym_name') . '' . CR;
}
-?>
+
+// Send message.
+send_message(create_chat_object([$update['message']['chat']['id']]), $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]);
diff --git a/mods/trainer.php b/mods/trainer.php
index fb3187b9..2db8f149 100644
--- a/mods/trainer.php
+++ b/mods/trainer.php
@@ -1,102 +1,72 @@
accessCheck('trainer');
$user_id = $update['callback_query']['from']['id'];
-if($data['arg'] == "a") {
- my_query("UPDATE users SET auto_alarm = IF(auto_alarm = 1, 0, 1) WHERE user_id = {$user_id}");
+if(isset($data['a']) && $data['a'] == 1) {
+ my_query('UPDATE users SET auto_alarm = IF(auto_alarm = 1, 0, 1) WHERE user_id = ?', [$user_id]);
}
// Set message.
$msg = '' . getTranslation('trainerinfo_set_yours') . '';
-$msg .= CR.CR.get_user($user_id, false);
+$msg .= CR . CR . get_user($user_id, false);
// Init empty keys array.
$keys = [];
// Create keys array.
-if($config->CUSTOM_TRAINERNAME){
- $keys[0][] =
- [
- 'text' => getTranslation('name'),
- 'callback_data' => '0:trainer_name:0'
- ];
+if($config->CUSTOM_TRAINERNAME) {
+ $keys[0][] = button(getTranslation('name'), 'trainer_name');
}
-if($config->RAID_POLL_SHOW_TRAINERCODE){
- $keys[0][] =
- [
- 'text' => getTranslation('trainercode'),
- 'callback_data' => '0:trainer_code:0'
- ];
+if($config->RAID_POLL_SHOW_TRAINERCODE) {
+ $keys[0][] = button(getTranslation('trainercode'), 'trainer_code');
}
$keys[] = [
- [
- 'text' => getTranslation('team'),
- 'callback_data' => '0:trainer_team:0'
- ],
- [
- 'text' => getTranslation('level'),
- 'callback_data' => '0:trainer_level:0'
- ]
+ button(getTranslation('team'), 'trainer_team'),
+ button(getTranslation('level'), 'trainer_level')
];
-if ($config->RAID_AUTOMATIC_ALARM == false) {
- $q_user = my_query("SELECT auto_alarm FROM users WHERE user_id = '{$user_id}' LIMIT 1");
- $alarm_status = $q_user->fetch()['auto_alarm'];
- $keys[] = [
- [
- 'text' => ($alarm_status == 1 ? getTranslation('switch_alarm_off') . ' ' . EMOJI_NO_ALARM : getTranslation('switch_alarm_on') . ' ' . EMOJI_ALARM),
- 'callback_data' => '0:trainer:a'
- ]
- ];
+if($config->RAID_AUTOMATIC_ALARM == false) {
+ $q_user = my_query('SELECT auto_alarm FROM users WHERE user_id = ? LIMIT 1', [$user_id]);
+ $alarm_status = $q_user->fetch()['auto_alarm'];
+ $keys[][] = button(
+ ($alarm_status == 1 ? getTranslation('switch_alarm_off') . ' ' . EMOJI_NO_ALARM : getTranslation('switch_alarm_on') . ' ' . EMOJI_ALARM),
+ ['trainer', 'a' => 1]
+ );
}
-if ($config->LANGUAGE_PRIVATE == '') {
- $keys[] = [
- [
- 'text' => getTranslation('bot_lang'),
- 'callback_data' => '0:bot_lang:0'
- ]
- ];
+if($config->LANGUAGE_PRIVATE == '') {
+ $keys[][] = button(getTranslation('bot_lang'), 'bot_lang');
+}
+if ($config->ENABLE_GYM_AREAS == true) {
+ $keys[][] = button(getTranslation('default_gymarea'), 'trainerGymarea');
}
-
-// Check access.
-$access = bot_access_check($update, 'trainer-share', true, true);
// Display sharing options for admins and users with trainer-share permissions
-if($access && (is_file(ROOT_PATH . '/access/' . $access) || $access == 'BOT_ADMINS')) {
- // Add sharing keys.
- $share_keys = [];
- $share_keys[] = universal_inner_key($keys, '0', 'trainer_add', '0', getTranslation('trainer_message_share'));
- $share_keys[] = universal_inner_key($keys, '0', 'trainer_delete', '0', getTranslation('trainer_message_delete'));
+if($botUser->accessCheck('trainer-share', true)) {
+ // Add sharing keys.
+ $share_keys = [];
+ $share_keys[] = button(getTranslation('trainer_message_share'), 'trainer_add');
+ $share_keys[] = button(getTranslation('trainer_message_delete'), 'trainer_delete');
- // Get the inline key array.
- $keys[] = $share_keys;
+ // Get the inline key array.
+ $keys[] = $share_keys;
- // Add message.
- $msg .= CR . CR . getTranslation('trainer_message_share_or_delete');
+ // Add message.
+ $msg .= CR . CR . getTranslation('trainer_message_share_or_delete');
}
-// Add abort key.
-$nav_keys = [];
-$nav_keys[] = universal_inner_key($keys, '0', 'exit', '0', getTranslation('abort'));
-
// Get the inline key array.
-$keys[] = $nav_keys;
+$keys[][] = button(getTranslation('done'), ['exit', 'd' => 1]);
// Answer callback.
answerCallbackQuery($update['callback_query']['id'], 'OK');
// Edit message.
edit_message($update, $msg, $keys, false);
-
-// Exit.
-$dbh = null;
-exit();
-
-?>
\ No newline at end of file
diff --git a/mods/trainerGymarea.php b/mods/trainerGymarea.php
new file mode 100644
index 00000000..f011c5d3
--- /dev/null
+++ b/mods/trainerGymarea.php
@@ -0,0 +1,48 @@
+accessCheck('trainer');
+
+$gymarea = $data['i'] ?? false;
+
+if($gymarea !== false) {
+ my_query('UPDATE users SET gymarea = ? WHERE user_id = ?',[$gymarea, $botUser->userId]);
+}else {
+ $q = my_query('SELECT gymarea FROM users WHERE user_id = ? LIMIT 1', [$botUser->userId]);
+ $gymarea = $q->fetch()['gymarea'];
+}
+
+// Init empty keys array.
+$keys = [];
+
+$json = json_decode(file_get_contents(botSpecificConfigFile('geoconfig_gym_areas.json')), 1);
+$gymareaName = '';
+foreach($json as $area) {
+ if($area['id'] == $gymarea) $gymareaName = $area['name'];
+ $keys[] = button($area['name'], ['trainerGymarea', 'i' => $area['id']]);
+
+}
+$keys = inline_key_array($keys, 2);
+$keys[] = [
+ button(getTranslation('back'), ['trainer', 'arg' => 0]),
+ button(getTranslation('done'), ['exit', 'd' => 1])
+];
+// Set message.
+$msg = '' . getTranslation('trainerinfo_set_yours') . '';
+
+$msg .= CR . CR . get_user($botUser->userId, true);
+$msg .= '' . getTranslation('default_gymarea') . ': ';
+$msg .= $gymareaName;
+
+// Answer callback.
+answerCallbackQuery($update['callback_query']['id'], 'OK');
+
+// Edit message.
+edit_message($update, $msg, $keys, false);
diff --git a/mods/trainer_add.php b/mods/trainer_add.php
index baf1b208..d83ac3f0 100644
--- a/mods/trainer_add.php
+++ b/mods/trainer_add.php
@@ -1,104 +1,71 @@
accessCheck('trainer-share');
// Init keys and chat list.
$keys = [];
-$chat_list = '';
-// $config->TRAINER_CHATS ?
-if(!empty($config->TRAINER_CHATS)) {
- $chat_list = $config->TRAINER_CHATS;
- debug_log($chat_list, 'Added trainer chats to the chat list:');
-}
-
-// $config->SHARE_CHATS ?
-if(!empty($config->SHARE_CHATS) && !empty($chat_list)) {
- $chat_list .= ',' . $config->SHARE_CHATS;
- debug_log($chat_list, 'Added share chats to the chat list:');
-} else if(!empty($config->SHARE_CHATS) && empty($chat_list)) {
- $chat_list = $config->SHARE_CHATS;
- debug_log($chat_list, 'Added share chats to the chat list:');
-}
-
-// Get chats from config and add to keys.
-for($i = 1; $i <= 6; $i++) {
- // Raid level adjustment
- if($i == 6) {
- $raid_level = 'X';
- } else {
- $raid_level = $i;
- }
- $const = 'SHARE_CHATS_LEVEL_' . $raid_level;
- $const_chats = $config->{$const};
-
- // Sharing keys for this raid level?
- if(!empty($const_chats)) {
- debug_log('Found chats by level, adding them');
- // Add chats.
- if(!empty($chat_list)) {
- $chat_list .= ',' . $const_chats;
- debug_log($chat_list, 'Added ' . $const . ' chats to the chat list:');
- } else {
- $chat_list = $const_chats;
- debug_log($chat_list, 'Added ' . $const . ' chats to the chat list:');
- }
- }
-}
-
-// Delete duplicate chats.
-debug_log($chat_list, 'Searching and removing duplicates from chat list:');
-$chat_list = explode(',', $chat_list);
-$chats = array_unique($chat_list);
+$chats = list_config_chats_by_short_id();
// Get chats already in the database.
debug_log('Searching and removing chats already having the trainer message');
-$rs = my_query(
- "
- SELECT chat_id
- FROM trainerinfo
- "
-);
-
-$chats_db = [];
-while ($row = $rs->fetch()) {
- $chats_db[] = $row['chat_id'];
+$rs = my_query('
+ SELECT chat_id, thread_id
+ FROM trainerinfo
+');
+
+$chats_db = $rs->fetchAll();
+for($i=0;$i