diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..094695b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.idea +config.php diff --git a/README.md b/README.md index 0ca0d45..b78ccb1 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,303 @@ -TODO: +# Installation - arrived - set and show time +## Webserver - create raid - check permissions (in group) - create raid moderators - allow create any raid - - geofencing - auto publish to chat - timezones - create api / command - \ No newline at end of file +Preferrably apache2 with php7 and https certificate ( https://www.letsencrypt.org ) + +## Config + +Copy config.php.example to config.php and edit (values explained further) + +## Log files + +Create log dir, e.g. /var/log/tg-bots/ and set it writeable by webserver + +Edit config.php and set `CONFIG_LOGFILE` + +## Bot token + +Start chat with https://t.me/BotFather and create bot token. + +Bot Settings: + - Enable Inline mode + - Allow Groups + - Group Privacy off + +Use https://www.miniwebtool.com/sha512-hash-generator/ and set `CONFIG_HASH` to hashed value of your token (make sure it is lowecase) + +## Sharing raids + +You can share raid polls with any chat in Telegram via a share button. + +Sharing raid polls can be restricted, so only moderators or users or both can be allowed to share a raid poll. + +Therefore it is possible, via a comma-separated list, to specify the chats the raid polls can be shared with. + +A few examples: + +#### Restrict sharing for moderators and users to chats -100111222333 and @RaidChat + +`define('SHARE_MODERATORS', false);` + +`define('SHARE_USERS', false);` + +`define('SHARE_CHATS', '-100111222333,@RaidChat');` + +#### Allow moderators to share with any chat, restrict sharing for users to chat @RaidChat + +`define('SHARE_MODERATORS', true);` + +`define('SHARE_USERS', false);` + +`define('SHARE_CHATS', '@RaidChat');` + +## Raid times + +There are several options to configure the times related to the raid polls: + +Set `RAID_LOCATION` to true to send back the location as message in addition to the raid poll. + +Set `RAID_SLOTS` to the amount of minutes which shall be between the voting slots. + +Set `RAID_LAST_START` to the minutes for the last start option before the a raid ends. + +## Proxy + +In case you are running the bot behind a proxy server, set `CURL_USEPROXY` to `true`. + +Add the proxy server address and port at `CURL_PROXYSERVER`. + +Authentication against the proxy server by username and password is currently not supported. + +## Database + +Create database named for your bot ID (first part of your Telegram bot token) + +Set database password to second part of your TG bot token + +Only allow localhost access + +Import `raid-pokemon-bot.sql` as default DB structure + +## Webhooks + +Set Telegram webhook via https://your-hostname/bot-dir/webhooks.html + +## Google maps API + +Optionally you can you use Google maps API to lookup addresses of gyms based on latitude and longitude + +Therefore get a Google maps API key and set it as `GOOGLE_API_KEY` in your config. + +To get a new API key, navigate to https://console.developers.google.com/apis/credentials and create a new API project, e.g. raid-telegram-bot + +Once the project is created select "API key" from the "Create credentials" dropdown menu - a new API key is created. + +After the key is created, you need to activate it for both: Geocoding and Timezone API + +Therefore go to "Dashboard" on the left navigation pane and afterwards hit "Enable APIs and services" on top of the page. + +Search for Geocoding and Timezone API and enable them. Alternatively use these links to get to Geocoding and Timezone API services: + +https://console.developers.google.com/apis/library/timezone-backend.googleapis.com + +https://console.developers.google.com/apis/library/geocoding-backend.googleapis.com + +Finally check the dashboard again and make sure Google Maps Geocoding API and Google Maps Time Zone API are listed as enabled services. + +## Raid overview + +The bot allows you to list all raids which got shared with one or more chats as a single raid overview message to quickly get an overview of all raids which are currently running and got shared in each chat. You can view and share raid overviews via the /list command - but only if some raids are currently active and if these active raids got shared to any chats! + +To keep this raid overview always up to date when you have it e.g. pinned inside your raid channel, you can setup a cronjob that updates the message by calling the overview_refresh module. + +You can either refresh all shared raid overview messages by calling + +`curl -k -d '{"callback_query":{"data":"0:overview_refresh:0"}}' https://localhost/bot_subdirectory/index.php?apikey=111111111:AABBccddEEFFggHHiijjKKLLmmnnOOPPqq` + +or just refresh the raid overview message you've shared with a specific chat (e.g. -100112233445): + +`curl -k -d '{"callback_query":{"data":"0:overview_refresh:-100112233445"}}' https://localhost/bot_subdirectory/index.php?apikey=111111111:AABBccddEEFFggHHiijjKKLLmmnnOOPPqq` + +To delete a shared raid overview message you can use the /list command too. + +## Cleanup + +The bot features an automatic cleanup of telegram raid poll messages as well as cleanup of the database (attendance and raids tables). + +To activate cleanup you need to change the config and create a cronjob to trigger the cleanup process as follows: + +Set the `CLEANUP` in the config to `true` and define a cleanup secret/passphrase under `CLEANUP_SECRET`. + +Activate the cleanup of telegram messages and/or the database by setting `CLEANUP_TELEGRAM` / `CLEANUP_DATABASE` to true. + +Specify the amount of minutes which need to pass by after raid has ended before the bot executes the cleanup. Times are in minutes in `CLEANUP_TIME_TG` for telegram cleanup and `CLEANUP_TIME_DB` for database cleanup. + +The value for the minutes of the database cleanup `CLEANUP_TIME_DB` must be greater than then one for telegram cleanup `CLEANUP_TIME_TG`. Otherwise cleanup will do nothing and exit due to misconfiguration! + +Finally set up a cronjob to trigger the cleanup. You can also trigger telegram / database cleanup per cronjob: For no cleanup use 0, for cleanup use 1 and to use your config file use 2 or leave "telegram" and "database" out of the request data array. + +A few examples - make sure to replace the URL with yours: + +#### Cronjob using cleanup values from config.php: Just the secret without telegram/database OR telegram = 2 and database = 2 + +`curl -k -d '{"cleanup":{"secret":"your-cleanup-secret/passphrase"}}' https://localhost/index.php?apikey=111111111:AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPP123` + +OR + +`curl -k -d '{"cleanup":{"secret":"your-cleanup-secret/passphrase","telegram":"2","database":"2"}}' https://localhost/index.php?apikey=111111111:AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPP123` + +#### Cronjob to clean up telegram messages only: telegram = 1 and database = 0 + +`curl -k -d '{"cleanup":{"secret":"your-cleanup-secret/passphrase","telegram":"1","database":"0"}}' https://localhost/index.php?apikey=111111111:AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPP123` + +#### Cronjob to clean up telegram messages and database: telegram = 1 and database = 1 + +`curl -k -d '{"cleanup":{"secret":"your-cleanup-secret/passphrase","telegram":"1","database":"1"}}' https://localhost/index.php?apikey=111111111:AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPP123` + +#### Cronjob to clean up database and maybe telegram messages (when specified in config): telegram = 2 and database = 1 + +`curl -k -d '{"cleanup":{"secret":"your-cleanup-secret/passphrase","telegram":"2","database":"1"}}' https://localhost/index.php?apikey=111111111:AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPP123` + +# Access permissions + +## Public access + +When no telegram id, group, supergroup or channel is specified in `BOT_ADMINS` and/or `BOT_ACCESS`, the bot will allow everyone to use it (public access). + +Example for public access: `define('BOT_ACCESS', '');` + +## Restricted access + +With BOT_ADMINS and BOT_ACCESS being used to restrict access, there are several access roles / types. When you do not configure BOT_ACCESS, everyone will have access to your bot (public access). + +Set `BOT_ADMINS` and `BOT_ACCESS` to the name (@Telegram_Groupname) or id (-100123456789) of one or multiple by comma separated individual telegram chat names/ids, groups, supergroups or channels. + +Please note, when you're setting groups, supergroups or channels only administrators (not members!) from these chats will gain access to the bot! So make sure this requirement is fulfilled or add their individual telegram usernames/ids instead. + +Example for restricted access: +`define('BOT_ADMINS', '@YOUR_USERNAME,111222333');` + +`define('BOT_ACCESS', '111222333,@Bot_Access_Groupname,-100112233445,@Superadmins_Bot_Groups');` + +## Access overview + +With your `MAINTAINER_ID` and as a member of `BOT_ADMINS` you have the permissions to do anything. **For performance improvements, it's recommended to add the MAINTAINER and all members of BOT_ADMINS as moderator via /mods command!** + +As a member of `BOT_ACCESS` you can create raid polls, update your own raid polls' pokemon and change the gym team of your last raid poll. `BOT_ACCESS` members who are moderators too, can also change the gym name and update pokemon from other users raid polls. + +Telegram Users can only vote on raid polls, but have no access to other bot functions (unless you configured it for public access). + + +| Access: | | | MAINTAINER_ID | BOT_ADMINS | BOT_ACCESS | BOT_ACCESS | Telegram | +|-----------|------------|----------------------------------|---------------|------------|------------|------------|----------| +| Database: | | | | | Moderator | User | User | +| | **Area** | **Action and /command** | | | | | | +| | Raid poll | Vote | Yes | Yes | Yes | Yes | Yes | +| | | Create `/start`, `/raid`, `/new` | Yes | Yes | Yes | Yes | | +| | | List `/list` | Yes | Yes | Yes | Yes | | +| | | Overview `/list` | Yes | Yes | | | | +| | | Delete ALL raid polls `/delete` | Yes | Yes | Yes | | | +| | | Delete OWN raid polls `/delete` | Yes | Yes | Yes | Yes | | +| | | | | | | | | +| | Pokemon | ALL raid polls `/pokemon` | Yes | Yes | Yes | | | +| | | OWN raid polls `/pokemon` | Yes | Yes | Yes | Yes | | +| | | | | | | | | +| | Gym | Name `/gym` | Yes | Yes | Yes | | | +| | | Team `/team` | Yes | Yes | Yes | Yes | | +| | | | | | | | | +| | Moderators | List `/mods` | Yes | Yes | | | | +| | | Add `/mods` | Yes | Yes | | | | +| | | Delete `/mods` | Yes | Yes | | | | +| | | | | | | | | +| | Help | Show `/help` | Yes | Yes | Yes | Yes | | + +# Updates + +Currently constantly new features, bug fixes and improvements are added to the bot. Since we do not have an update mechanism yet, when updating the bot, please always do the following: + - Add new config variables which got added to the config.php.example to your own config.php! + - If new tables and/or columns got added or changed inside raid-pokemon-bot.sql, please add/alter these tables/columns at your existing installation! + +# Usage + +## Bot commands +#### Command: No command - just send your location to the bot + +The bot will guide you through the creation of the raid poll by asking you for the raid level, the pokemon raid boss, the time until the raids starts and the time left for the raid. Afterwards you can set the gym name and gym team by using the /gym and /team commands. + + +#### Command: /start + +The bot will guide you through the creation of the raid poll by asking you for the gym, raid level, the pokemon raid boss, the time until the raid starts and the time left for the raid. Afterwards you can set the gym team by using the /team command. + + +#### Command: /help + +The bot will answer you "This is a private bot" so you can verify the bot is working and accepting input. + + +#### Command: /mods + +The bot allows you to set some users as moderators. You can list, add and delete moderators from the bot. Note that when you have restricted the access to your bot via BOT_ADMINS and BOT_ACCESS, you need to add the users as administrators of a chat or their Telegram IDs to either BOT_ADMINS or BOT_ACCESS. Otherwise they won't have access to the bot, even though you have added them as moderators! + + +#### Command: /raid + +Create a new raid by gomap-notifier or other input. The raid command expects 8 parameters and an optional 9th parameter as input seperated by comma. + +Additionally the raid command checks for existing raids, so sending the same command multiple times to the bot will result in an update of the pokemon raid boss and gym team and won't create duplicate raids. + +Parameters: Pokemon raid boss, latitude, longitude, raid duration in minutes, gym team, gym name, district or street, district or street, raid pre-hatch egg countdown in minutes (optional) + +Example input: `/raid Entei,52.514545,13.350095,60,Mystic,Siegessäule,Großer Stern,10557 Berlin,30` + + +#### Command: /pokemon + +Update pokemon of an existing raid poll. With this command you can change the pokemon raid boss from e.g. "Level 5 Egg" to "Lugia" once the egg has hatched. + +Based on your access to the bot, you may can only change the pokemon raid boss of raid polls you created yourself and cannot modify the pokemon of raid polls from other bot users. + + +#### Command: /new + +The bot expects latitude and longitude seperated by comma and will then guide you through the creation of the raid poll. + +This command was implemented since the Telegram Desktop Client does not allow to share a location currently. + +Example input: `/new 52.514545,13.350095` + + +#### Command: /list + +The bot will allow you to via a list of the last 20 active raids, share and delete all raids which got shared to channels as a raid overview. + + +#### Command: /delete + +Delete an existing raid poll. With this command you can delete a raid poll from telegram and the database. Use with care! + +Based on your access to the bot, you may can only delete raid polls you created yourself and cannot delete raid polls from other bot users. + + +#### Command: /team + +The bot will set the team to Mystic/Valor/Instinct for the last created raid based on your input. + +Example input: `/team Mystic` + + +#### Command: /gym + +The bot will set the name of gym to your input. + +Example input: `/gym Siegessäule` + +# Debugging +Check your bot logfile and other related log files, e.g. apache/httpd log, php log, and so on. + +# TODO: + +* New gyms: Adding gyms to database without creating a raid via /raid +* Preferred pokemon raid boss: When multiple level 5 raids are available, e.g. Lugia and Zapdos, add buttons to tell that you're coming a) only if Lugia, b) only if Zapdos, c) independently of the pokemon +* Delete incomplete raids automatically: When a bot user starts to create a raid via /start, but does not finish the raid creation, incomplete raid data is stored in the raids table. A method to automatically delete them without interfering with raids just being created would be nice. diff --git a/commands/delete.php b/commands/delete.php new file mode 100644 index 0000000..c3029dc --- /dev/null +++ b/commands/delete.php @@ -0,0 +1,84 @@ +fetch_assoc(); + +// No data found. +if (!$row) { + //sendMessage($update['message']['from']['id'], 'Can\'t determine your location, please participate in at least 1 raid'); + //exit; + $tz = TIMEZONE; +} else { + $tz = $row['timezone']; +} + +// Build query. +$request = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE end_time>NOW() + AND timezone='{$tz}' + ORDER BY end_time ASC LIMIT 20 + " +); + +// Count results. +$count = 0; + +// Get raids. +while ($raid = $request->fetch_assoc()) { + + // Counter++ + $count = $count + 1; + + // Create keys array. + $keys = [ + [ + [ + 'text' => getTranslation('delete'), + 'callback_data' => $raid['id'] . ':raids_delete:0' + ] + ] + ]; + + // Get message. + $msg = show_raid_poll_small($raid); + + // Send message. + send_message($update['message']['from']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]); +} + +// Send message if no active raids were found. +if($count == 0) { + // Set message. + $msg = '' . getTranslation('no_active_raids_found') . ''; + + // Send message. + sendMessage($update['message']['from']['id'], $msg); +} + +exit; diff --git a/commands/gym.php b/commands/gym.php old mode 100644 new mode 100755 index a17ae23..c2055d3 --- a/commands/gym.php +++ b/commands/gym.php @@ -1,44 +1,89 @@ real_escape_string($gym_name).'" WHERE user_id='.$update['message']['from']['id'].' ORDER BY id DESC LIMIT 1'; - my_query($query); - - sendMessage('none',$update['message']['chat']['id'],'Gym name updated'); - - } else { - if ($update['message']['reply_to_message']['text']) { - $lines = explode(CR,$update['message']['reply_to_message']['text']); - $last_line = array_pop($lines); - $pos = strpos($last_line, 'ID = '); - $id = intval(trim(substr($last_line,$pos+5))); - debug_log('Gym ID='.$id.' name='.$gym_name); - - $query = 'SELECT COUNT(*) FROM users WHERE user_id='.$update['message']['from']['id'].' AND moderator=1'; - $rs = my_query($query); - $row = $rs->fetch_row(); - $q = ' AND user_id='.$update['message']['from']['id']; - if ($row[0]) $q = ''; - - $query = 'UPDATE raids SET gym_name="'.$db->real_escape_string($gym_name).'" WHERE id='.$id.' '.$q; - my_query($query); - - $rs = my_query('SELECT *, - UNIX_TIMESTAMP(end_time) AS ts_end, - UNIX_TIMESTAMP(NOW()) as ts_now, - UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left - FROM raids WHERE id='.$id.''); - $raid = $rs->fetch_assoc(); - - $text = show_raid_poll($raid); - $keys = keys_vote($raid); - - editMessageText($update['message']['reply_to_message']['message_id'], $text, $keys, $update['message']['chat']['id']); - } - } - - exit; +// Write to log. +debug_log('SET gym name to ' . $gym_name); + +// Private chat type. +if ($update['message']['chat']['type'] == 'private' || $update['callback_query']['message']['chat']['type'] == 'private') { + // Update gym name in raid table. + my_query( + " + UPDATE raids + SET gym_name = '{$db->real_escape_string($gym_name)}' + WHERE user_id = {$update['message']['from']['id']} + ORDER BY id DESC LIMIT 1 + " + ); + + // Send the message. + sendMessage($update['message']['chat']['id'], getTranslation('gym_name_updated')); + +} else { + if ($update['message']['reply_to_message']['text']) { + + $lines = explode(CR, $update['message']['reply_to_message']['text']); + $last_line = array_pop($lines); + $pos = strpos($last_line, 'ID = '); + $id = intval(trim(substr($last_line, $pos + 5))); + + // Write to log. + debug_log('Gym ID=' . $id . ' name=' . $gym_name); + + // Build query. + $rs = my_query( + " + SELECT COUNT(*) + FROM users + WHERE user_id = {$update['message']['from']['id']} + AND moderator = 1 + " + ); + + $row = $rs->fetch_row(); + + + if ($row[0]) { + // Build query. + my_query( + " + UPDATE raids + SET gym_name = '{$db->real_escape_string($gym_name)}' + WHERE id = {$id} + " + ); + + } else { + // Build query. + my_query( + " + UPDATE raids + SET gym_name = '{$db->real_escape_string($gym_name)}' + WHERE id = {$id} + AND user_id = {$update['message']['from']['id']} + " + ); + } + + $rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = {$id} + " + ); + + $raid = $rs->fetch_assoc(); + + $text = show_raid_poll($raid); + $keys = keys_vote($raid); + + editMessageText($update['message']['reply_to_message']['message_id'], $text, $keys, $update['message']['chat']['id']); + } +} + +exit; diff --git a/commands/help.php b/commands/help.php index edc3cb3..ba1af2c 100644 --- a/commands/help.php +++ b/commands/help.php @@ -1,8 +1,16 @@ fetch_assoc(); - if (!$row) exit; - - sendMessage('none',$update['message']['from']['id'],$row['message']); +$msg = ' +EN Guide on how to create a raid poll raid bot +1) make sure the raid hasn\'t been posted yet in the chat +2) check how much time is left for the raid +3) open new PM with @RaidPokemonBot +4) send your location to the bot (make sure you send the location of where the gym is located) +5) choose the type of raid boss and the time left +6) to ensure an easier way to locate the gym in game/chat, it\'s recommended to use the bot function /gym (name of the gym and/or description of it) +7) press share and choose yourRaid channel +8) wait until the option with the boss name appears and select it +'; +$msg = 'This is a private bot.'; // temp +sendMessage($update['message']['from']['id'], $msg); \ No newline at end of file diff --git a/commands/list.php b/commands/list.php index 3257f40..d023ba5 100644 --- a/commands/list.php +++ b/commands/list.php @@ -1,32 +1,41 @@ fetch_assoc(); - if (!$row) { - sendMessage('none',$update['message']['from']['id'],'Can\'t determine your location, please participate in at least 1 raid'); - exit; - } +// Write to log. +debug_log('LIST'); - $tz = $row['timezone']; +// Check access. +bot_access_check($update, BOT_ACCESS); - $request = my_query('SELECT *, - UNIX_TIMESTAMP(end_time) AS ts_end, - UNIX_TIMESTAMP(NOW()) as ts_now, - UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left - FROM raids WHERE end_time>NOW() AND timezone="'.$tz.'" ORDER BY end_time ASC LIMIT 20'); +// Get the userid and chattype +$userid = $update['message']['from']['id']; +$chattype = $update['message']['chat']['type']; - while($raid = $request->fetch_assoc()) { - $keys = [[[ - 'text' => 'Expand', 'callback_data' => $raid['id'].':vote_refresh:0', - ]]]; - $msg = show_raid_poll_small($raid); - send_message('none',$update['message']['from']['id'],$msg, $keys, - ['reply_markup' => ['selective'=>true, 'one_time_keyboard'=>true]] - ); - } +// Init empty keys array. +$keys = array(); - - exit; +// Create keys array. +$keys = [ + [ + [ + 'text' => getTranslation('list'), + 'callback_data' => $userid . ',' . $chattype . ':raids_list:0' + ] + ], + [ + [ + 'text' => getTranslation('overview_share'), + 'callback_data' => '0:overview_share:0' + ], + [ + 'text' => getTranslation('overview_delete'), + 'callback_data' => '0:overview_delete:0' + ] + ] +]; + +// Set message. +$msg = '' . getTranslation('raids_list_share_overview') . ':'; + +// Send message. +send_message($update['message']['chat']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]); + +exit; diff --git a/commands/mods.php b/commands/mods.php new file mode 100644 index 0000000..2bba34a --- /dev/null +++ b/commands/mods.php @@ -0,0 +1,35 @@ + getTranslation('list'), + 'callback_data' => '0:mods:list' + ], + [ + 'text' => getTranslation('add'), + 'callback_data' => '0:mods:add' + ], + [ + 'text' => getTranslation('delete'), + 'callback_data' => '0:mods:delete' + ] + ] +]; + +// Set message. +$msg = '' . getTranslation('mods_list_add_delete') . ':'; + +// Send message. +send_message($update['message']['chat']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]); + +exit; diff --git a/commands/new.php b/commands/new.php new file mode 100755 index 0000000..42e906e --- /dev/null +++ b/commands/new.php @@ -0,0 +1,34 @@ + getTranslation('create_a_raid'), + 'callback_data' => $userid . ',' . $chattype . ':raid_create:' . $coords, + ] + ] + ]; + +$msg = getTranslation('coordination_succes'); + +// Send message. +send_message($update['message']['from']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]); + +exit; diff --git a/commands/pokemon.php b/commands/pokemon.php new file mode 100755 index 0000000..112866c --- /dev/null +++ b/commands/pokemon.php @@ -0,0 +1,82 @@ +fetch_assoc(); + +// No data found. +if (!$row) { + //sendMessage($update['message']['from']['id'], 'Can\'t determine your location, please participate in at least 1 raid'); + //exit; + $tz = TIMEZONE; +} else { + $tz = $row['timezone']; +} + +// Build query. +$request = my_query( + " + SELECT *, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE end_time>NOW() + AND timezone='{$tz}' + ORDER BY end_time ASC LIMIT 20 + " +); + +// Count results. +$count = 0; + +while ($raid = $request->fetch_assoc()) { + // Create keys array. + $keys = [ + [ + [ + 'text' => getTranslation('update_pokemon'), + 'callback_data' => $raid['id'] . ':raid_edit_poke:' . $raid['pokemon'], + ] + ] + ]; + + // Counter++ + $count = $count + 1; + + // Get message. + $msg = show_raid_poll_small($raid); + + // Send message. + send_message($update['message']['from']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]); +} + +// Send message if no active raids were found. +if($count == 0) { + // Set message. + $msg = '' . getTranslation('no_active_raids_found') . ''; + + // Send message. + sendMessage($update['message']['from']['id'], $msg); +} + +exit; diff --git a/commands/raid.php b/commands/raid.php old mode 100644 new mode 100755 index 72dc6e4..aa9a7f2 --- a/commands/raid.php +++ b/commands/raid.php @@ -1,78 +1,271 @@ setTimeZone(new DateTimeZone($tz)); - $end_time = '"'.$dt->format('Y-m-d H:i:s').'"'; - } - - $q = 'INSERT INTO raids SET - pokemon="'.$db->real_escape_string($data[0]).'", - user_id='.$update['message']['from']['id'].', - lat="'.$lat.'", - lon="'.$lon.'", - first_seen=NOW(), - end_time='.$end_time.', - gym_name="'.$db->real_escape_string($data[4]).'" - '; - - if ($tz!==false) { - $q .= ', timezone="'.$tz.'"'; - } - if ($addr) { - $q .= ', address="'.$db->real_escape_string($addr).'"'; - } - - $rs = my_query($q); - $id = my_insert_id(); - debug_log('ID='.$id); - - $rs = my_query('SELECT *, - UNIX_TIMESTAMP(end_time) AS ts_end, - UNIX_TIMESTAMP(NOW()) as ts_now, - UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left - FROM raids WHERE id='.$id.''); - $raid = $rs->fetch_assoc(); - - $text = show_raid_poll($raid); - $keys = keys_vote($raid); - - - - if ($update['message']['chat']['type']=='private' || $update['callback_query']['message']['chat']['type']=='private') { - - $keys = [[[ - 'text'=>'Share','switch_inline_query'=>strval($id), - ]]]; - - send_message('none',$update['message']['chat']['id'],$text, $keys); - - } else { - $reply_to = $update['message']['chat']['id']; - if ($update['message']['reply_to_message']['message_id']) $reply_to = $update['message']['reply_to_message']['message_id']; - - send_message('none',$update['message']['chat']['id'],$text, $keys, - ['reply_to_message_id'=>$reply_to, 'reply_markup' => ['selective'=>true, 'one_time_keyboard'=>true]] - ); - } - - exit; +// Get data from message text. (remove: "/raid ") +$gym_data = trim(substr($update['message']['text'], 5)); + +// Create data array (max. 9) +$data = explode(',', $gym_data, 9); + +/** + * Info: + * [0] = Boss name + * [1] = latitude + * [2] = longitude + * [3] = raid duration in minutes + * [4] = gym team + * [5] = gym name + * [6] = district (or street) + * [7] = street (or district) + * [8] = optional: raid countdown minutes + */ + +// Invalid data received. +if (count($data) < 8) { + send_message($update['message']['chat']['id'], 'Invalid input', []); + exit; +} + +// Raid boss name +$boss = $data[0]; + +// Get latitude / longitude from data. +$lat = floatval($data[1]); +$lon = floatval($data[2]); + +// Format lat/long values. +$lat = substr($lat, 0, strpos('.', $lat) + 9); +$lon = substr($lon, 0, strpos('.', $lon) + 9); + +// Endtime from input +$endtime = $data[3]; + +// Team +$team = $data[4]; + +// Escape comma in Raidname +$name = str_replace('|',',',$data[5]); + +// Build address string. +if(!empty(GOOGLE_API_KEY)){ + $addr = get_address($lat, $lon); + + // Get full address - Street #, ZIP District + $address = ""; + $address .= (!empty($addr['street']) ? $addr['street'] : ""); + $address .= (!empty($addr['street_number']) ? " " . $addr['street_number'] : ""); + $address .= (!empty($addr) ? ", " : ""); + $address .= (!empty($addr['postal_code']) ? $addr['postal_code'] . " " : ""); + $address .= (!empty($addr['district']) ? $addr['district'] : ""); +} else { + //Based on input order of [6] and [7] it'll be either: Street, District or District, Street + $address = (!empty($data[6]) ? $data[6] : '') . (!empty($data[7]) ? ", " . $data[7] : ""); +} + +// Get countdown minutes when specified, otherwise 0 minutes until raid starts +$countdown = 0; +if (!empty($data[8])) { + $countdown = $data[8]; +} + +// Insert new raid or update existing raid/ex-raid? +$raid_id = raid_duplication_check($name,($endtime + $countdown)); +$ex_raid = false; + +if ($raid_id > 0) { + // Get current pokemon from database for raid. + $rs_ex_raid = my_query( + " + SELECT pokemon + FROM raids + WHERE id = {$raid_id} + " + ); + + // Get row. + $row_ex_raid = $rs_ex_raid->fetch_assoc(); + $poke_name = $row_ex_raid['pokemon']; + debug_log('Comparing the current pokemon to pokemons from ex-raid list now...'); + debug_log('Current Pokemon in database for this raid: ' . $poke_name); + + // Make sure it's not an Ex-Raid before updating the pokemon. + $pokemonlist = $GLOBALS['pokemon']; + foreach($pokemonlist as $level => $levelmons) { + if($level == "X") { + foreach($levelmons as $key => $pokemon) { + if(strtolower($pokemon) == strtolower($poke_name)) { + $ex_raid = true; + debug_log('Current pokemon is an ex-raid pokemon: ' . $poke_name); + debug_log('Pokemon "' .$poke_name . '" will NOT be updated to "' . $boss . '"!'); + break 2; + } + } + } + } + + if ($ex_raid) { + // Ex-Raid! Update only team in raids table. + my_query( + " + UPDATE raids + SET gym_team = '{$db->real_escape_string($team)}' + WHERE id = {$raid_id} + " + ); + } else { + // Update pokemon and team in raids table. + debug_log('Current pokemon is NOT an ex-raid pokemon: ' . $poke_name); + debug_log('Pokemon "' .$poke_name . '" will be updated to "' . $boss . '"!'); + my_query( + " + UPDATE raids + SET pokemon = '{$db->real_escape_string($boss)}', + gym_team = '{$db->real_escape_string($team)}' + WHERE id = {$raid_id} + " + ); + } + + // Debug log + debug_log('Updated raid ID: ' . $raid_id); + + // Build query. + $rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = {$raid_id} + " + ); + + // Get row. + $raid = $rs->fetch_assoc(); + + //Debug + // Set text. + //$text = 'Raid aktualisiert! ID = ' . $raid_id . "" . CR; + //$text .= CR . show_raid_poll($raid); + + // Send the message + //sendMessage($update['message']['chat']['id'], $text); + + // Exit now after update of raid and message. + exit; +} + +// Address found. +if (!empty($address)) { + // Insert gym with address, lat and lon to database if not already in database + $gym2db = insert_gym($name, $lat, $lon, $address); + + // Build the query. + $rs = my_query( + " + INSERT INTO raids + SET pokemon = '{$db->real_escape_string($boss)}', + user_id = {$update['message']['from']['id']}, + lat = '{$lat}', + lon = '{$lon}', + first_seen = NOW(), + start_time = DATE_ADD(first_seen, INTERVAL {$countdown} MINUTE), + end_time = DATE_ADD(start_time, INTERVAL {$endtime} MINUTE), + gym_team = '{$db->real_escape_string($team)}', + gym_name = '{$db->real_escape_string($name)}', + timezone = '{$tz}', + address = '{$db->real_escape_string($address)}' + " + ); +// No address found. +} else { + // Build the query. + $rs = my_query( + " + INSERT INTO raids + SET pokemon = '{$db->real_escape_string($boss)}', + user_id = {$update['message']['from']['id']}, + lat = '{$lat}', + lon = '{$lon}', + first_seen = NOW(), + start_time = DATE_ADD(first_seen, INTERVAL {$countdown} MINUTE), + end_time = DATE_ADD(start_time, INTERVAL {$endtime} MINUTE), + gym_team = '{$db->real_escape_string($team)}', + gym_name = '{$db->real_escape_string($name)}', + timezone = '{$tz}' + " + ); +} + +// Get last insert id from db. +$id = my_insert_id(); + +// Write to log. +debug_log('ID=' . $id); + +// Build query. +$rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = {$id} + " +); + +// Get row. +$raid = $rs->fetch_assoc(); + +if (RAID_LOCATION == true) { + // Send location. + //$loc = send_location($update['message']['chat']['id'], $raid['lat'], $raid['lon']); + $loc = send_venue($update['message']['chat']['id'], $raid['lat'], $raid['lon'], "", !empty($raid['address']) ? $raid['address'] . ', ID = ' . $raid['id'] : $raid['pokemon'] . ', ' . $raid['id']); // DO NOT REMOVE " ID = " --> NEEDED FOR CLEANUP PREPARATION! + + // Write to log. + debug_log('location:'); + debug_log($loc); +} + +// Set text. +$text = show_raid_poll($raid); + +// Private chat type. +if ($update['message']['chat']['type'] == 'private' || $update['callback_query']['message']['chat']['type'] == 'private') { + // Set keys. + $keys = [ + [ + [ + 'text' => getTranslation('share'), + 'switch_inline_query' => strval($id), + ] + ] + ]; + + // Send the message. + send_message($update['message']['chat']['id'], $text, $keys, ['disable_web_page_preview' => 'true']); + +} else { + // Set reply to. + $reply_to = $update['message']['chat']['id']; + + // Set keys. + $keys = keys_vote($raid); + + if ($update['message']['reply_to_message']['message_id']) { + $reply_to = $update['message']['reply_to_message']['message_id']; + } + + // Send the message. + send_message($update['message']['chat']['id'], $text, $keys, ['reply_to_message_id' => $reply_to, 'reply_markup' => ['selective' => true, 'one_time_keyboard' => true], 'disable_web_page_preview' => 'true']); +} + +exit; diff --git a/commands/sethelp.php b/commands/sethelp.php deleted file mode 100644 index 831bc93..0000000 --- a/commands/sethelp.php +++ /dev/null @@ -1,25 +0,0 @@ -fetch_row(); - if (!$row[0]) { - $msg = 'Not allowed'; - sendMessage('none',$update['message']['from']['id'],$msg); - exit; - } - - - if (!$update['message']['reply_to_message']['text']) { - $msg = 'Please reply-to message that you want to set as help text'; - sendMessage('none',$update['message']['from']['id'],$msg); - exit; - } - - $help = $db->real_escape_string($update['message']['reply_to_message']['text']); - - my_query('INSERT INTO help SET id='.$update['message']['chat']['id'].', message="'.$help.'" ON DUPLICATE KEY update message="'.$help.'"'); - - $msg = 'Help text set'; - sendMessage('none',$update['message']['chat']['id'],$msg); - exit; diff --git a/commands/start.php b/commands/start.php old mode 100644 new mode 100755 index 041bbb0..9599dac --- a/commands/start.php +++ b/commands/start.php @@ -1,3 +1,25 @@ Please send location to start Raid announce '); +// Get the userid and chattype +$userid = $update['message']['from']['id']; +$chattype = $update['message']['chat']['type']; + +// Create keys array. +$keys = [ + [ + [ + 'text' => getTranslation('create_a_raid'), + 'callback_data' => $userid . ',' . $chattype . ':raid_by_gym_letter:0', + ] + ] + ]; + +// Set message. +$msg = '' . getTranslation('raid_by_gym') . '' . CR2 . CR . getTranslation('send_location') ; + +// Send message. +send_message($update['message']['chat']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]); + +exit; diff --git a/commands/team.php b/commands/team.php old mode 100644 new mode 100755 index 40af24a..cbfe2f1 --- a/commands/team.php +++ b/commands/team.php @@ -1,26 +1,38 @@ 'mystic', - 'instinct' => 'instinct', - 'valor' => 'valor', - 'red' => 'valor', - 'blue' => 'mystic', - 'yellow' => 'instinct', - 'r' => 'valor', - 'b' => 'mystic', - 'y' => 'instinct', - ); - - if ($teams[$gym_team]) { - $query = 'UPDATE raids SET gym_team="'.$teams[$gym_team].'" WHERE user_id='.$update['message']['from']['id'].' ORDER BY id DESC LIMIT 1'; - my_query($query); - - sendMessage('none',$update['message']['chat']['id'],'Gym team set to '.ucfirst($teams[$gym_team])); - } else { - sendMessage('none',$update['message']['chat']['id'],'Invalid team name - type Mystic, Valor, Instinct or Blue, Red, Yellow'); - } - - \ No newline at end of file +// Match team names. +$teams = array( + 'mystic' => '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 ($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. + sendMessage($update['message']['chat']['id'], getTranslation('gym_team_set_to') . ' ' . ucfirst($teams[$gym_team])); + +// Invalid team name. +} else { + // Send the message. + sendMessage($update['message']['chat']['id'], getTranslation('invalid_team')); +} diff --git a/config.php.example b/config.php.example new file mode 100755 index 0000000..baf7724 --- /dev/null +++ b/config.php.example @@ -0,0 +1,44 @@ + TEAM_B, - 'valor' => TEAM_R, - 'instinct' => TEAM_Y, - 'unknown' => TEAM_UNKNOWN, - 'cancel' => TEAM_CANCEL, + 'mystic' => TEAM_B, + 'valor' => TEAM_R, + 'instinct' => TEAM_Y, + 'unknown' => TEAM_UNKNOWN, + 'cancel' => TEAM_CANCEL ); +// Raid boss pokemon. $pokemon = array( - '5' => array( - 'Articuno', - 'Lugia', - 'Moltres', - 'Zapdos', - ), - '4' => array( - 'Tyranitar', - 'Snorlax', - 'Lapras', - 'Rhydon', - 'Charizard', - 'Venusaur', - 'Blastoise', - ), - '3' => array( - 'Machamp', - 'Vaporeon', - 'Flareon', - 'Jolteon', - 'Alakazam', - 'Arcanine', - 'Gengar', - ), + 'X' => array( + getTranslation('mewtwo') + ), + '5' => array( +// getTranslation('articuno'), + getTranslation('lugia'), +// getTranslation('moltres'), +// getTranslation('zapdos'), +// getTranslation('mew'), + getTranslation('mewtwo'), +// getTranslation('hooh'), +// getTranslation('celebi'), +// getTranslation('raikou'), +// getTranslation('entei'), +// getTranslation('suicune'), +// getTranslation('groudon'), +// getTranslation('rayquaza'), +// getTranslation('kyogre'), +// getTranslation('latios'), +// getTranslation('latias'), +// getTranslation('deoxys'), +// getTranslation('jirachi'), +// getTranslation('regirock'), +// getTranslation('regice'), +// getTranslation('registeel'), + getTranslation('egg_5') + ), + '4' => array( + getTranslation('tyranitar'), + getTranslation('absol'), + getTranslation('aggron'), + getTranslation('golem'), + getTranslation('egg_4') + ), + '3' => array( + getTranslation('machamp'), + getTranslation('jynx'), + getTranslation('jolteon'), + getTranslation('gengar'), + getTranslation('egg_3') + ), + '2' => array( + getTranslation('egg_2') + ), + '1' => array( + getTranslation('egg_1') + ) ); - diff --git a/create_diff b/create_diff deleted file mode 100755 index 87cf318..0000000 --- a/create_diff +++ /dev/null @@ -1,9 +0,0 @@ -#!/bin/bash - -PROJ=_pogo-raid-bot - -git diff --ignore-space-change -U10 --no-prefix > $PROJ.diff -git status > $PROJ.files.diff -chmod 0666 $PROJ.diff -chmod 0666 $PROJ.files.diff -/usr/bin/mcedit $PROJ.diff diff --git a/debug.php b/debug.php index 365a4b9..0e4eff2 100644 --- a/debug.php +++ b/debug.php @@ -1,42 +1,85 @@ insert_id; + return $db->insert_id; } -function my_query($query) { - global $db; - debug_log($query, '?'); - $res = $db->query($query); - if ($db->error) { - debug_log($db->error,'!'); - } - return $res; -} +/** + * Get db query. + * @param $query + * @return bool|mysqli_result + */ +function my_query($query, $cleanup_query = false) +{ + global $db; + + if ($cleanup_query == true) { + debug_log($query, '?', true); + } else { + debug_log($query, '?'); + } + + $res = $db->query($query); + + if ($db->error) { + if ($cleanup_query == true) { + debug_log($db->error, '!', true); + } else { + debug_log($db->error, '!'); + } + } -function debug_log($val, $type = '*') { - $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 = ''; - while($btl=array_shift($bt)) { - if ($btl['function']==__FUNCTION__) continue; - $bl = '['.basename($btl['file']).':'.$btl['line'].'] '; - 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,CONFIG_LOGFILE); - } + return $res; } +/** + * Write debug log. + * @param $val + * @param string $type + */ +function debug_log($val, $type = '*', $cleanup_log = false) +{ + // Write to log only if debug is enabled. + if (DEBUG === true) { + $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 = ''; + + while ($btl = array_shift($bt)) { + if ($btl['function'] == __FUNCTION__) continue; + $bl = '[' . basename($btl['file']) . ':' . $btl['line'] . '] '; + break; + } + + if (gettype($val) != 'string') $val = var_export($val, 1); + $rows = explode("\n", $val); + foreach ($rows as $v) { + if ($cleanup_log == true) { + error_log('[' . $date . '][' . getmypid() . '] ' . $bl . $type . ' ' . $v . "\n", 3, CLEANUP_LOGFILE); + } else { + error_log('[' . $date . '][' . getmypid() . '] ' . $bl . $type . ' ' . $v . "\n", 3, CONFIG_LOGFILE); + } + } + } +} + +/** + * Write cleanup log. + * @param $val + * @param string $type + * @param bool $cleanup_log + */ +function cleanup_log($val, $type = '*') +{ + debug_log($val, $type, $cleanup_log = true); +} diff --git a/functions.php b/functions.php old mode 100644 new mode 100755 index 56623d0..3564be5 --- a/functions.php +++ b/functions.php @@ -1,405 +1,601 @@ - $value) { - $user_count = count($value); - if($user_count>1000000000000) $current_number = round(($user_count/1000000000000),1).' T'; - else if($user_count>1000000000) $current_number = round(($user_count/1000000000),1).' B'; - else if($user_count>1000000) $current_number = round(($user_count/1000000),1).' M'; - else if($user_count>1000) $current_number = round(($user_count/1000),1).' K'; - else $current_number = $user_count; - $inline_keyboard[][] = [ - 'text' => $key.' - '.$current_number, - 'callback_data' => $val['chat_id'].':'.$val['id'].':'.$key, - ]; - - $text .= "\n$key [$current_number]\n"; - foreach ($value as $id => $name) $text .= '└ '.$name."\n"; - } - } else if ($anony == 'y') { - $text .= "\n"; - foreach ($poll_votes[$type] as $key => $value) { - $user_count = count($value); - if($user_count>1000000000000) $current_number = round(($user_count/1000000000000),1).' T'; - else if($user_count>1000000000) $current_number = round(($user_count/1000000000),1).' B'; - else if($user_count>1000000) $current_number = round(($user_count/1000000),1).' M'; - else if($user_count>1000) $current_number = round(($user_count/1000),1).' K'; - else $current_number = $user_count; - $inline_keyboard[][] = [ - 'text' => $key.' - '.$current_number, - 'callback_data' => $val['chat_id'].':'.$val['id'].':'.$key, - ]; - - $text .= "\n$key [$current_number]\n"; - } - } - return ['text' => $text,'inline_keyboard' => $inline_keyboard]; + 'sendMessage', + 'chat_id' => $chat_id, + 'parse_mode' => 'HTML', + 'text' => $text + ]; + + if (isset($inline_keyboard)) { + $reply_content['reply_markup'] = ['inline_keyboard' => $inline_keyboard]; + } + + // Encode data to json. + $reply_json = json_encode($reply_content); + + // Set header to json. + header('Content-Type: application/json'); + + // Write to log. + debug_log($reply_json, '>'); + + // Send request to telegram api. + curl_json_request($reply_json); } -function generate_markup($type,$anony) { - debug_log('Type='.$type); - debug_log('anony='.$anony); - $inline_keyboard = [ - [ - [ - 'text' => 'Vote'.($type == 'vote' ? ' ✅':''), - 'callback_data' => 'comm:vote', - ], - [ - 'text' => 'Doodle'.($type == 'doodle' ? ' ✅':''), - 'callback_data' => 'comm:doodle', - ], - ], - [ - [ - 'text' => 'Anonymous'.($anony == 'y' ? ' ✅':''), - 'callback_data' => 'comm:anony', - ], - [ - 'text' => 'Identified Users'.($anony == 'n' ? ' ✅':''), - 'callback_data' => 'comm:noanony', - ] - ], - ]; - return $inline_keyboard; +/** + * Send message. + * @param $chat_id + * @param array $text + * @param mixed $inline_keyboard + * @param array $merge_args + */ +function send_message($chat_id, $text = array(), $inline_keyboard = false, $merge_args = []) +{ + // Create response content array. + $reply_content = [ + 'method' => 'sendMessage', + 'chat_id' => $chat_id, + 'parse_mode' => 'HTML', + 'text' => $text + ]; + + // Write to log. + debug_log('KEYS'); + debug_log($inline_keyboard); + + 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); + } + + // Encode data to json. + $reply_json = json_encode($reply_content); + + // Set header to json. + header('Content-Type: application/json'); + + // Write to log. + debug_log($reply_json, '>'); + + // Send request to telegram api. + return curl_json_request($reply_json); } -function sendMessage($sampletext,$chat_id,$val = array()) { - switch ($sampletext) { - case 'start': - debug_log($val); - $text = "Hello\nI can help you organize stuff in group chats\nFirst, send me the question and select the poll type with the buttons below.\n"; - $inline_keyboard = generate_markup($val['type'],$val['anony']); - debug_log($inline_keyboard); - break; - case 'enter_first': - $text = "Okay\nNow send me the first vote option"; - break; - case 'enter_more': - $text = "Got it\nKeep sending more vote options or hit /done to publish the poll"; - break; - case 'done': - $message = generate_poll_message($val,false); - $text = $message['text']; - $inline_keyboard = $message['inline_keyboard']; - break; - case 'wrong': - $text = "Unrecognized command\nYou may now correct that or make a new poll using /start ..."; - case 'none': - $text = $val; - break; - } - $reply_content = [ - 'method' => 'sendMessage', - 'chat_id' => $chat_id, - 'parse_mode' => 'HTML', - 'text' => $text, - ]; - - if (isset($inline_keyboard)) { - $reply_content['reply_markup'] = ['inline_keyboard' => $inline_keyboard]; - } - - $reply_json = json_encode($reply_content); - - header('Content-Type: application/json'); - debug_log($reply_json,'>'); - curl_json_request($reply_json); +/** + * Send location. + * @param $chat_id + * @param $lat + * @param $lon + * @param bool $inline_keyboard + * @return mixed + */ +function send_location($chat_id, $lat, $lon, $inline_keyboard = false) +{ + // Create reply content array. + $reply_content = [ + 'method' => 'sendLocation', + 'chat_id' => $chat_id, + 'latitude' => $lat, + 'longitude' => $lon + ]; + + // Write to log. + debug_log('KEYS'); + debug_log($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); + + // Set header to json. + header('Content-Type: application/json'); + + // Write to log. + debug_log($reply_json, '>'); + + // Send request to telegram api and return response. + return curl_json_request($reply_json); } -function send_message($sampletext, $chat_id, $val = array(), $inline_keyboard = false, $merge_args = []) { - switch ($sampletext) { - case 'none': - $text = $val; - break; - } - $reply_content = [ - 'method' => 'sendMessage', - 'chat_id' => $chat_id, - 'parse_mode' => 'HTML', - 'text' => $text, - ]; - - debug_log('KEYS'); - debug_log($inline_keyboard); - 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); - } - - - $reply_json = json_encode($reply_content); - - header('Content-Type: application/json'); - debug_log($reply_json,'>'); - curl_json_request($reply_json); +/** + * Send venue. + * @param $chat_id + * @param $lat + * @param $lon + * @param $title + * @param $address + * @param bool $inline_keyboard + * @return mixed + */ +function send_venue($chat_id, $lat, $lon, $title, $address, $inline_keyboard = false) +{ + // Create reply content array. + $reply_content = [ + 'method' => 'sendVenue', + 'chat_id' => $chat_id, + 'latitude' => $lat, + 'longitude' => $lon, + 'title' => $title, + 'address' => $address + ]; + + // Write to log. + debug_log('KEYS'); + debug_log($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); + + // Set header to json. + header('Content-Type: application/json'); + + // Write to log. + debug_log($reply_json, '>'); + + // Send request to telegram api and return response. + return curl_json_request($reply_json); } -function send_location($sampletext, $chat_id, $lat, $lon, $inline_keyboard = false) { - switch ($sampletext) { - case 'none': - $text = $val; - break; - } - $reply_content = [ - 'method' => 'sendLocation', - 'chat_id' => $chat_id, - 'latitude' => $lat, - 'longitude' => $lon, - ]; - - debug_log('KEYS'); - debug_log($inline_keyboard); - if (is_array($inline_keyboard)) { - $reply_content['reply_markup'] = ['inline_keyboard' => $inline_keyboard]; - } - - $reply_json = json_encode($reply_content); - - header('Content-Type: application/json'); - debug_log($reply_json,'>'); - $resp = curl_json_request($reply_json); - return $resp; +/** + * Echo message. + * @param $chat_id + * @param $text + */ +function sendMessageEcho($chat_id, $text) +{ + // Create reply content array. + $reply_content = [ + 'method' => 'sendMessage', + 'chat_id' => $chat_id, + 'parse_mode' => 'HTML', + 'text' => $text + ]; + + // Encode data to json. + $reply_json = json_encode($reply_content); + + // Set header to json. + header('Content-Type: application/json'); + + // Write to log. + debug_log($reply_json, '>'); + + // Echo json. + echo($reply_json); } - -function sendMessageEcho($sampletext,$chat_id,$val) { - $text = $val; - - $reply_content = [ - 'method' => 'sendMessage', - 'chat_id' => $chat_id, - 'parse_mode' => 'HTML', - 'text' => $text, - ]; - - $reply_json = json_encode($reply_content); - header('Content-Type: application/json'); - debug_log($reply_json,'>'); - echo($reply_json); +/** + * Answer callback query. + * @param $query_id + * @param $text + */ +function answerCallbackQuery($query_id, $text) +{ + // Create response array. + $response = [ + 'method' => 'answerCallbackQuery', + 'callback_query_id' => $query_id, + 'text' => $text + ]; + + // Encode response to json format. + $json_response = json_encode($response); + + // Set header to json. + header('Content-Type: application/json'); + + // Write to log. + debug_log($json_response, '>'); + + // Send request to telegram api. + curl_json_request($json_response); } - - -function answerCallbackQuery($query_id,$val) { - $text = $val; - $response = [ - 'method' => 'answerCallbackQuery', - 'callback_query_id' => $query_id, - 'text' => $text, - ]; - $json_response = json_encode($response); - header('Content-Type: application/json'); - debug_log($json_response,'>'); - curl_json_request($json_response); +/** + * Answer inline query. + * @param $query_id + * @param $contents + */ +function answerInlineQuery($query_id, $contents) +{ + // Init empty result array. + $results = array(); + + // For each content. + foreach ($contents as $key => $row) { + // Get raid poll. + $text = show_raid_poll($row); + + // Get inline keyboard. + $inline_keyboard = keys_vote($row); + + // 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' => ucfirst($row['pokemon']) . ' ' . unix2tz($row['ts_end'], $row['timezone']), + 'description' => strval($row['gym_name']), + 'input_message_content' => $input_message_content, + 'reply_markup' => [ + 'inline_keyboard' => $inline_keyboard + ] + ]; + } + + // Create reply content array. + $reply_content = [ + 'method' => 'answerInlineQuery', + 'inline_query_id' => $query_id, + 'is_personal' => true, + 'cache_time' => 10, + 'results' => $results + ]; + + // Encode to json and send request to telegram api. + curl_json_request(json_encode($reply_content)); } -function answerInlineQuery($query_id,$contents) { - $results = array(); - foreach ($contents as $key => $row) { - //$message = generate_poll_message($row,true); - //$poll = json_decode($row['poll_votes'],true); - //$desc = array_keys($poll)[0].' '.$row['anony'] == 'y' ? 'Anonymous ' : 'Personal '; - //foreach ($poll[array_keys($poll)[0]] as $name => $users) $desc.=$name.', '; - $text = ucfirst($row['pokemon']).' '.substr($row['end_time'],11,5); - $inline_keyboard = [[[]]]; - $input_message_content = [ - 'parse_mode' => 'HTML', - 'message_text' => $text, - 'disable_web_page_preview' => true, - ]; - $results[] = [ - 'type' => 'article', - 'id' => $query_id.$key, - 'title' => ucfirst($row['pokemon']), - 'description' => strval(substr($row['end_time'],11,5)), - 'input_message_content' => $input_message_content, - 'reply_markup' => ['inline_keyboard' => $inline_keyboard], - ]; - } - - - $reply_content = [ - 'method' => 'answerInlineQuery', - 'inline_query_id' => $query_id, - 'results' => $results, - ]; - - debug_log($reply_content,'>'); - curl_json_request(json_encode($reply_content)); +/** + * Edit message text. + * @param $id_val + * @param $text_val + * @param $markup_val + * @param null $chat_id + * @param mixed $merge_args + */ +function editMessageText($id_val, $text_val, $markup_val, $chat_id = NULL, $merge_args = 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; + } + + // 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'); + + if (is_array($merge_args) && count($merge_args)) { + $response = array_merge_recursive($response, $merge_args); + } + + // Write to log. + debug_log($response, 'K'); + + // Encode response to json format. + $json_response = json_encode($response); + + // Write to log. + debug_log($response, '<-'); + + // Send request to telegram api. + curl_json_request($json_response); } - -function answer_inline_query($query_id,$contents) { - $results = array(); - foreach ($contents as $key => $row) { - $text = show_raid_poll($row); - - - //$inline_keyboard = [keys_raid_people($row['id'])]; - $inline_keyboard = keys_vote($row); - $input_message_content = [ - 'parse_mode' => 'HTML', - 'message_text' => $text, - 'disable_web_page_preview' => true, - ]; - - $results[] = [ - 'type' => 'article', - 'id' => $query_id.$key, - 'title' => ucfirst($row['pokemon']).' '.unix2tz($row['ts_end'], $row['timezone']), - 'description' => strval($row['gym_name']), - 'input_message_content' => $input_message_content, - 'reply_markup' => ['inline_keyboard' => $inline_keyboard], - ]; - -/* - $results[] = [ - 'id' => $row['id'], - 'type' => 'location', - 'latitude' => floatval($row['lat']), - 'longitude' => floatval($row['lon']), - 'title' => $input_message_content['message_text'], - 'reply_markup' => ['inline_keyboard' => $inline_keyboard], - ]; -*/ - } - - - $reply_content = [ - 'method' => 'answerInlineQuery', - 'inline_query_id' => $query_id, - 'is_personal' => true, - 'cache_time' => 10, - 'results' => $results, - ]; - - $ret = curl_json_request(json_encode($reply_content)); +/** + * Edit message reply markup. + * @param $id_val + * @param $markup_val + * @param $chat_id + */ +function editMessageReplyMarkup($id_val, $markup_val, $chat_id) +{ + // 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; + } + + // Encode response to json format. + $json_response = json_encode($response); + + // Write to log. + debug_log($response, '->'); + + // Send request to telegram api. + curl_json_request($json_response); } +/** + * Edit message keyboard. + * @param $id_val + * @param $markup_val + * @param $chat_id + */ +function edit_message_keyboard($id_val, $markup_val, $chat_id) +{ + // 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; + } + + // Encode response to json format. + $json_response = json_encode($response); + + // Write to log. + debug_log($response, '->'); + + // Send request to telegram api. + curl_json_request($json_response); +} -function editMessageText($id_val,$text_val,$markup_val,$chat_id = NULL, $merge_args = false) { - $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; - } - - if ($chat_id != null) { - $response['chat_id'] = $chat_id; - $response['message_id'] = $id_val; - } else { - $response['inline_message_id'] = $id_val; - } - - debug_log($merge_args,'K'); - debug_log($response,'K'); - if (is_array($merge_args) && count($merge_args)) { - $response = array_merge_recursive($response, $merge_args); - } - - debug_log($response,'K'); - - $json_response = json_encode($response); - debug_log($response,'->'); - curl_json_request($json_response); +/** + * Edit message. + * @param $update + * @param $message + * @param $keys + * @param bool $merge_args + */ +function edit_message($update, $message, $keys, $merge_args = false) +{ + if (isset($update['callback_query']['inline_message_id'])) { + editMessageText($update['callback_query']['inline_message_id'], $message, $keys, NULL, $merge_args); + } else { + editMessageText($update['callback_query']['message']['message_id'], $message, $keys, $update['callback_query']['message']['chat']['id'], $merge_args); + } } -function editMessageReplyMarkup($id_val,$markup_val,$chat_id) { - $response = [ - 'method' => 'editMessageReplyMarkup', - 'reply_markup' => ['inline_keyboard' => $markup_val], - ]; - - if ($chat_id != null) { - $response['chat_id'] = $chat_id; - $response['message_id'] = $id_val; - } else { - $response['inline_message_id'] = $id_val; - } - - $json_response = json_encode($response); - debug_log($response,'->'); - curl_json_request($json_response); +/** + * Delete message + * @param $chat_id + * @param $message_id + */ +function delete_message($chat_id, $message_id) +{ + // Create response content array. + $reply_content = [ + 'method' => 'deleteMessage', + 'chat_id' => $chat_id, + 'message_id' => $message_id, + 'parse_mode' => 'HTML', + ]; + + // Encode data to json. + $reply_json = json_encode($reply_content); + + // Set header to json. + header('Content-Type: application/json'); + + // Write to log. + debug_log($reply_json, '>'); + + // Send request to telegram api. + return curl_json_request($reply_json); } -function edit_message_keyboard($id_val,$markup_val,$chat_id) { - $response = [ - 'method' => 'editMessageReplyMarkup', - 'reply_markup' => ['inline_keyboard' => $markup_val], - ]; - - if ($chat_id != null) { - $response['chat_id'] = $chat_id; - $response['message_id'] = $id_val; - } else { - $response['inline_message_id'] = $id_val; - } - - $json_response = json_encode($response); - debug_log($response,'->'); - curl_json_request($json_response); +/** + * GetChat + * @param $chatid + */ +function get_chat($chat_id) +{ + // Create response content array. + $reply_content = [ + 'method' => 'getChat', + 'chat_id' => $chat_id, + 'parse_mode' => 'HTML', + ]; + + // Encode data to json. + $reply_json = json_encode($reply_content); + + // Set header to json. + header('Content-Type: application/json'); + + // Write to log. + debug_log($reply_json, '>'); + + // Send request to telegram api. + return curl_json_request($reply_json); } -function edit_message($update, $message, $keys, $merge_args = false) { - if (isset($update['callback_query']['inline_message_id'])) { - editMessageText($update['callback_query']['inline_message_id'],$message, $keys, NULL, $merge_args); - } else { - editMessageText($update['callback_query']['message']['message_id'],$message,$keys,$update['callback_query']['message']['chat']['id'], $merge_args); - } +/** + * GetChatAdministrators + * @param $chatid + */ +function get_admins($chat_id) +{ + // Create response content array. + $reply_content = [ + 'method' => 'getChatAdministrators', + 'chat_id' => $chat_id, + 'parse_mode' => 'HTML', + ]; + + // Encode data to json. + $reply_json = json_encode($reply_content); + + // Set header to json. + header('Content-Type: application/json'); + + // Write to log. + debug_log($reply_json, '>'); + + // Send request to telegram api. + return curl_json_request($reply_json); } +/** + * Send request to telegram api. + * @param $json + * @return mixed + */ +function curl_json_request($json) +{ + $curl = curl_init('https://api.telegram.org/bot' . API_KEY . '/'); + + 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); + + // Use Proxyserver for curl if configured + if (CURL_USEPROXY == true) { + curl_setopt($curl, CURLOPT_PROXY, CURL_PROXYSERVER); + } + + // Write to log. + debug_log($json, '->'); + + // Execute curl request. + $json_response = curl_exec($curl); + + // Write to log. + debug_log($json_response, '<-'); + + // Decode json response. + $response = json_decode($json_response, true); + + // Validate response. + if ($response['ok'] != true || isset($response['update_id'])) { + // Write error to log. + debug_log('ERROR: ' . $json . "\n\n" . $json_response . "\n\n"); + } else { + // Result seems ok, get message_id and chat_id if supergroup or channel message + if ($response['result']['chat']['type'] == "channel" || $response['result']['chat']['type'] == "supergroup") { + // Init raid_id + $raid_id = 0; + + // Set chat and message_id + $chat_id = $response['result']['chat']['id']; + $message_id = $response['result']['message_id']; + + // Get raid id from $json + $json_message = json_decode($json, true); + + // Write to log that message was shared with channel or supergroup + debug_log('Message was shared with ' . $response['result']['chat']['type'] . ' ' . $response['result']['chat']['title']); + debug_log('Checking input for cleanup info now...'); + + // Check if callback_data is present to get the raid_id and reply_to_message_id is set to filter only raid messages + if (!empty($json_message['reply_markup']['inline_keyboard']['0']['0']['callback_data']) && !empty($json_message['reply_to_message_id'])) { + $split_callback_data = explode(':', $json_message['reply_markup']['inline_keyboard']['0']['0']['callback_data']); + $raid_id = $split_callback_data[0]; + + // Check if it's a venue and get raid id + } else if (!empty($response['result']['venue']['address'])) { + // Get raid_id from address. + $raid_id = substr(strrchr($response['result']['venue']['address'], "ID = "), 5); + } + + // Trigger Cleanup when raid_id was found + if ($raid_id != 0) { + debug_log('Found Raid_ID for cleanup preparation from callback_data or venue!'); + debug_log('Raid_ID: ' . $raid_id); + debug_log('Chat_ID: ' . $chat_id); + debug_log('Message_ID: ' . $message_id); + + // Trigger cleanup preparation process when necessary id's are not empty and numeric + if (!empty($chat_id) && !empty($message_id) && !empty($raid_id)) { + debug_log('Calling cleanup preparation now!'); + insert_cleanup($chat_id, $message_id, $raid_id); + } else { + debug_log('Missing input! Cannot call cleanup preparation!'); + } + } else { + debug_log('No cleanup info found! Skipping cleanup preparation!'); + } + + // Check if text starts with getTranslation('raid_overview_for_chat') and inline keyboard is empty + $translation = getTranslation('raid_overview_for_chat'); + $translation_length = strlen($translation); + $text = substr($response['result']['text'], 0, $translation_length); + if ($text == $translation && empty($json_message['reply_markup']['inline_keyboard'])) { + debug_log('Detected overview message!'); + debug_log('Chat_ID: ' . $chat_id); + debug_log('Message_ID: ' . $message_id); + + // Write raid overview data to database + debug_log('Adding overview info to database now!'); + insert_overview($chat_id, $message_id); + } + } + } -function typing($chat_id) { - $response = [ - 'method' => 'sendChatAction', - 'chat_id' => $chat_id, - 'action' => 'typing', - ]; - $json_response = json_encode($response); - debug_log($response,'->'); - curl_json_request($json_response); + // Return response. + return $response; } -function curl_json_request($json) { - $curl = curl_init('https://api.telegram.org/bot'.API_KEY.'/'); - - 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); - - debug_log($json,'->'); - $json_response = curl_exec($curl); - debug_log($json_response,'<-'); - $response = json_decode($json_response,true); - if ($response['ok']!=true || isset($response['update_id'])) debug_log('ERROR: '.$json."\n\n".$json_response."\n\n"); - return $response; +/** + * Gets a table translation out of the json file. + * @param $text + * @return translation + */ +function getTranslation($text) +{ + debug_log($text); + + $str = file_get_contents('./language.json'); + + $json = json_decode($str, true); + $translation = $json[$text][LANGUAGE]; + + return $translation; } - diff --git a/geo_api.php b/geo_api.php old mode 100644 new mode 100755 index f735f49..ac39e4d --- a/geo_api.php +++ b/geo_api.php @@ -1,55 +1,126 @@ '); - $json_response = curl_exec($curl); - debug_log($json_response,''); - $json_response = curl_exec($curl); - debug_log($json_response,''); + + $json_response = curl_exec($curl); + + debug_log($json_response, 'status) && $data->status == 'OK' && !empty($data->results)) { + + // Init vars. + $locality = ''; + $sublocalityLv2 = ''; + $sublocality = ''; + + // Iterate each result. + foreach ($data->results as $result) { + + // Check for address components. + if (!empty($result->address_components)) { + // Iterate each address component. + foreach ($result->address_components as $address_component) { + + // Street found. + if (in_array('route', $address_component->types) && !empty($address_component->long_name)) { + // Set street by first found. + $location['street'] = empty($location['street']) ? $address_component->long_name : $location['street']; + } + + // Street number found. + if (in_array('street_number', $address_component->types) && !empty($address_component->long_name)) { + // Set street by first found. + $location['street_number'] = empty($location['street_number']) ? $address_component->long_name : $location['street_number']; + } + + // Postal code found. + if (in_array('postal_code', $address_component->types) && !empty($address_component->long_name)) { + // Set street by first found. + $location['postal_code'] = empty($location['postal_code']) ? $address_component->long_name : $location['postal_code']; + } + + // Sublocality level2 found. + if (in_array('sublocality_level_2', $address_component->types) && !empty($address_component->long_name)) { + // Set sublocality level 2 by first found. + $sublocalityLv2 = empty($sublocalityLv2) ? $address_component->long_name : $sublocalityLv2; + } + + // Sublocality found. + if (in_array('sublocality', $address_component->types) && !empty($address_component->long_name)) { + // Set sublocality by first found. + $sublocality = empty($sublocality) ? $address_component->long_name : $sublocality; + } + + // Locality found. + if (in_array('locality', $address_component->types) && !empty($address_component->long_name)) { + // Set sublocality by first found. + $locality = empty($sublocality) ? $address_component->long_name : $sublocality; + } + } + } + break; + } + + // Set district by priority. + if (!empty($sublocalityLv2)) { + $location['district'] = $sublocalityLv2; + + } else if ($sublocality) { + $location['district'] = $sublocality; + + } else if ($locality) { + $location['district'] = $locality; + } + + // Rename street responses. + switch ($location['street']) { + case 'Unnamed Road': + $location['street'] = getTranslation('forest'); + break; + } + + // Return the location array. + return $location; + + } else { + return false; + } +} diff --git a/hash.php b/hash.php new file mode 100644 index 0000000..bae7365 --- /dev/null +++ b/hash.php @@ -0,0 +1,3 @@ +set_charset('utf8mb4'); + +// Error connecting to db. +if ($db->connect_errno) { + // Write connection error to log. + debug_log("Failed to connect to Database!" . $db->connect_error(), '!'); + // Echo data. + sendMessage($update['message']['chat']['id'], "Failed to connect to Database!\nPlease contact " . MAINTAINER . " and forward this message...\n"); +} + +// Update the user. +$userUpdate = update_user($update); + +// Write to log. +debug_log('Update user: ' . $userUpdate); + +// Cleanup request received. +if (isset($update['cleanup']) && CLEANUP == true) { + cleanup_log('Cleanup process request received...'); + // Check access to cleanup of bot + if ($update['cleanup']['secret'] == CLEANUP_SECRET) { + // Get telegram cleanup value if specified. + if (isset($update['cleanup']['telegram'])) { + $telegram = $update['cleanup']['telegram']; + } else { + $telegram = 2; + } + // Get database cleanup value if specified. + if (isset($update['cleanup']['database'])) { + $database = $update['cleanup']['database']; } else { - sendMessageEcho('none',MAINTAINER_ID,$_SERVER['REMOTE_ADDR'].' '.$_SERVER['HTTP_X_FORWARDED_FOR'].' '.$apikey); - exit('Nop'); + $database = 2; } + // Run cleanup + cleanup_log('Calling cleanup process now!'); + run_cleanup($telegram, $database); + } else { + cleanup_log('Error! Wrong cleanup secret supplied!', '!'); + } + // Exit after cleanup + exit(); +} - $content = file_get_contents('php://input'); +// Callback query received. +if (isset($update['callback_query'])) { + // Init empty data array. + $data = array(); - $update = json_decode($content, true); - if (!$update) { - debug_log($content, '!'); - } else { - debug_log($update,'<'); - } + // Callback data found. + if ($update['callback_query']['data']) { + // Split callback data and assign to data array. + $splitData = explode(':', $update['callback_query']['data']); + $data['id'] = $splitData[0]; + $data['action'] = $splitData[1]; + $data['arg'] = $splitData[2]; + } - $command = NULL; + // Write data to log. + debug_log('DATA='); + debug_log($data); - $db = new mysqli('localhost',BOT_ID,BOT_KEY,BOT_ID); - if ($db->connect_errno) { - debug_log("Failed to connect to Database!".$db->connect_error(), '!'); - sendMessage('none',$update['message']['chat']['id'],"Failed to connect to Database!\nPlease contact ".MAINTAINER." and forward this message...\n"); - } + // Set module path by sent action name. + $module = 'modules/' . basename($data['action']) . '.php'; - update_user($update); - if (isset($update['callback_query'])) { - if ($update['callback_query']['data']) { - $d = explode(':', $update['callback_query']['data']); - $data['id'] = $d[0]; - $data['action'] = $d[1]; - $data['arg'] = $d[2]; - } - debug_log('DATA='); - debug_log($data); - - $module = 'modules/'.basename($data['action']).'.php'; - debug_log($module); - if (file_exists($module)) { - include_once($module); - exit; - } else { - debug_log('No action'); - } - - - } else if (isset($update['inline_query'])){ - /* INLINE - LIST POLLS */ - raid_list($update); - exit; - } else if (isset($update['message']['location'])) { - include_once('modules/raid_create.php'); - exit(); - - } else if (isset($update['message']['new_chat_member'])) { - include_once('modules/join.php'); - exit(); - - } else if (isset($update['message'])) { - if (substr($update['message']['text'],0,1) == '/') { - $command = strtolower(str_replace('/','',str_replace(BOT_NAME,'',explode(' ',$update['message']['text'])[0]))); - $module = 'commands/'.basename($command).'.php'; - debug_log($module); - - if (file_exists($module)) { - include_once($module); - exit; - } - - sendMessage('none',$update['message']['chat']['id'],'Please send location to start Raid announce '); - } - } + // 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(); + + // Module file is missing. + } else { + // Write to log. + debug_log('No action'); + } + +// Inline query received. +} else if (isset($update['inline_query'])) { + // Check access to the bot + bot_access_check($update); + // List polls and exit. + raid_list($update); + exit(); + +// Location received. +} else if (isset($update['message']['location'])) { + // Check access to the bot + bot_access_check($update); + // Create raid and exit. + include_once('modules/raid_create.php'); + exit(); + +// Cleanup collection from channel/supergroup messages. +} else if ($update['channel_post']['chat']['type'] == "channel" || $update['message']['chat']['type'] == "supergroup") { + // Write to log. + debug_log('Collecting cleanup preparation information...'); + // Init raid_id. + $raid_id = 0; + + // Channel + if(isset($update['channel_post'])) { + // Get chat_id and message_id + $chat_id = $update['channel_post']['chat']['id']; + $message_id = $update['channel_post']['message_id']; + + // Get raid_id from text. + $raid_id = substr(strrchr($update['channel_post']['text'], "ID = "), 5); + + // Supergroup + } else if ($update['message']['chat']['type'] == "supergroup") { + // Get chat_id and message_id + $chat_id = $update['message']['chat']['id']; + $message_id = $update['message']['message_id']; + + // Get raid_id from text. + $raid_id = substr(strrchr($update['message']['text'], "ID = "), 5); + } + + // Write cleanup info to database. + debug_log('Calling cleanup preparation now!'); + insert_cleanup($chat_id, $message_id, $raid_id); + exit(); + +// Message is required to check for commands. +} else if (isset($update['message'])) { + // Check access to the bot + bot_access_check($update); + // Check message text for a leading slash. + if (substr($update['message']['text'], 0, 1) == '/') { + // Get command name. + $com = strtolower(str_replace('/', '', str_replace(BOT_NAME, '', explode(' ', $update['message']['text'])[0]))); + + // Set command path. + $command = 'commands/' . basename($com) . '.php'; + + // Write to log. + debug_log($command); + + // Check if command file exits. + if (file_exists($command)) { + // Dynamically include command file and exit. + include_once($command); + exit(); + } + // Echo bot response. + sendMessage($update['message']['chat']['id'], '' . getTranslation('send_location') . ''); + } +} diff --git a/language.json b/language.json new file mode 100755 index 0000000..397a651 --- /dev/null +++ b/language.json @@ -0,0 +1,1167 @@ +{ + "5stars" : { + "NL": "5 Sterren Raid", + "DE": "5 Sterne Raid", + "EN": "5 Star Raid", + "PT-BR": "Raid nível 5" + }, + "4stars" : { + "NL": "4 Sterren Raid", + "DE": "4 Sterne Raid", + "EN": "4 Star Raid", + "PT-BR": "Raid nível 4" + }, + "3stars" : { + "NL": "3 Sterren Raid", + "DE": "3 Sterne Raid", + "EN": "3 Star Raid", + "PT-BR": "Raid nível 3" + }, + "2stars" : { + "NL": "2 Sterren Raid", + "DE": "2 Sterne Raid", + "EN": "2 Star Raid", + "PT-BR": "Raid nível 2" + }, + "1stars" : { + "NL": "1 Sterren Raid", + "DE": "1 Sterne Raid", + "EN": "1 Star Raid", + "PT-BR": "Raid nível 1" + }, + "back" : { + "NL": "Terug", + "DE": "Zurück", + "EN": "Back", + "PT-BR": "Voltar" + }, + "next" : { + "NL": "Next", + "DE": "Weiter", + "EN": "Next", + "PT-BR": "Próximo" + }, + "alone" : { + "NL": "Alleen", + "DE": "Alleine", + "EN": "Alone", + "PT-BR": "Sozinho" + }, + "raid_done" : { + "NL": "Raid beëindigd", + "DE": "Raid beendet.", + "EN": "Raid done", + "PT-BR": "Raid completa" + }, + "here" : { + "NL": "Ben er", + "DE": "Bin da", + "EN": "Here", + "PT-BR": "Aqui" + + }, + "done" : { + "NL": "Klaar", + "DE": "Fertig", + "EN": "Done", + "PT-BR": "Feito" + }, + "cancellation" : { + "NL": "Afwezig", + "DE": "Absage", + "EN": "Cancellation", + "PT-BR": "Cancelada" + }, + "vote_updated" : { + "NL": "Stem geüpdatet", + "DE": "Abstimmung aktualisiert", + "EN": "Vote updated", + "PT-BR": "Votos atualizados" + }, + "monday" : { + "NL": "Maandag", + "DE": "Montag", + "EN": "Monday", + "PT-BR": "Segunda-feira" + }, + "tuesday" : { + "NL": "Dinsdag", + "DE": "Dienstag", + "EN": "Tuesday", + "PT-BR": "Terça-feira" + }, + "wednesday" : { + "NL": "Woensdag", + "DE": "Mittwoch", + "EN": "Wednesday", + "PT-BR": "Quarta-feira" + }, + "thursday" : { + "NL": "Donderdag", + "DE": "Donnerstag", + "EN": "Thursday", + "PT-BR": "Quinta-feira" + }, + "friday" : { + "NL": "Vrijdag", + "DE": "Freitag", + "EN": "Friday", + "PT-BR": "Sexta-feira" + }, + "saturday" : { + "NL": "Zaterdag", + "DE": "Samstag", + "EN": "Saturday", + "PT-BR": "Sábado" + }, + "sunday" : { + "NL": "Zondag", + "DE": "Sonntag", + "EN": "Sunday", + "PT-BR": "Domingo" + }, + "month_01" : { + "NL": "Januari", + "DE": "Januar", + "EN": "January", + "PT-BR": "Janeiro" + }, + "month_02" : { + "NL": "Februari", + "DE": "Februar", + "EN": "February", + "PT-BR": "Fevereiro" + }, + "month_03" : { + "NL": "Maart", + "DE": "März", + "EN": "March", + "PT-BR": "Março" + }, + "month_04" : { + "NL": "April", + "DE": "April", + "EN": "April", + "PT-BR": "Abril" + }, + "month_05" : { + "NL": "Meer", + "DE": "Mai", + "EN": "May", + "PT-BR": "Mais" + }, + "month_06" : { + "NL": "Juni", + "DE": "Juni", + "EN": "June", + "PT-BR": "Junho" + }, + "month_07" : { + "NL": "Juli", + "DE": "Juli", + "EN": "July", + "PT-BR": "Julho" + }, + "month_08" : { + "NL": "Augustus", + "DE": "August", + "EN": "August", + "PT-BR": "Agosto" + }, + "month_09" : { + "NL": "September", + "DE": "September", + "EN": "September", + "PT-BR": "Setembro" + }, + "month_10" : { + "NL": "Oktober", + "DE": "Oktober", + "EN": "October", + "PT-BR": "Outubro" + }, + "month_11" : { + "NL": "November", + "DE": "November", + "EN": "November", + "PT-BR": "Novembro" + }, + "month_12" : { + "NL": "December", + "DE": "Dezember", + "EN": "December", + "PT-BR": "Dezembro" + }, + "still" : { + "NL": "nog", + "DE": "noch", + "EN": "still" + }, + "raid_egg_opens" : { + "NL": "Raid ei gaat open", + "DE": "Raid-Ei öffnet sich um", + "EN": "Raid egg opens up", + "PT-BR": "Ovo eclode" + }, + "raid_egg_opens_day" : { + "NL": "Raid ei gaat open", + "DE": "Raid-Ei öffnet sich am", + "EN": "Raid egg opens on", + "PT-BR": "Ovo eclode em" + }, + "raid_egg_opens_at" : { + "NL": "om", + "DE": "um", + "EN": "at", + "PT-BR": "em" + }, + "raid_until" : { + "NL": "Raid tot", + "DE": "Raid bis", + "EN": "Raid until", + "PT-BR": "Raid até" + }, + "exraid_pass" : { + "NL": "DEELNAME IS ALLEEN MOGELIJK MET EX-RAID PASS", + "DE": "TEILNAHME IST NUR MIT EX-RAID-PASS MÖGLICH", + "EN": "PARTICIPATION IS POSSIBLE ONLY WITH EX-RAID PASS", + "PT-BR": "PARTICIPAÇÃO APENAS COM PASSE EX" + }, + "no_participants_yet" : { + "NL": "Nog geen deelnemers", + "DE": "Noch keine Teilnehmer.", + "EN": "No participants yet", + "PT-BR": "Ainda sem participantes" + }, + "finished" : { + "NL": "Klaar", + "DE": "Fertig", + "EN": "Finished", + "PT-BR": "Finalizada" + }, + "cancel" : { + "NL": "Annuleren", + "DE": "Abgesagt", + "EN": "Cancel", + "PT-BR": "Cancelar" + }, + "created_by" : { + "NL": "Aangemaakt door", + "DE": "Erstellt von", + "EN": "Created by", + "PT-BR": "Criada por" + }, + "updated" : { + "NL": "Bijgewerkt", + "DE": "Aktualisiert", + "EN": "Updated", + "PT-BR": "Atualizada" + }, + "from" : { + "NL": "van", + "DE": "von", + "EN": "from", + "PT-BR": "de" + }, + "to" : { + "NL": "tot", + "DE": "bis", + "EN": "to", + "PT-BR": "para" + }, + "no_participants" : { + "NL": "Geen deelnemers", + "DE": "Keine Teilnehmer", + "EN": "No participants", + "PT-BR": "Sem participantes" + }, + "mew" : { + "NL": "Mew", + "DE": "Mew", + "EN": "Mew", + "PT-BR": "Mew" + }, + "mewtwo" : { + "NL": "Mewtwo", + "DE": "Mewtu", + "EN": "Mewtwo", + "PT-BR": "Mewtwo" + }, + "lugia" : { + "NL": "Lugia", + "DE": "Lugia", + "EN": "Lugia", + "PT-BR": "Lugia" + }, + "zapdos" : { + "NL": "Zapdos", + "DE": "Zapdos", + "EN": "Zapdos", + "PT-BR": "Zapdos" + }, + "hooh" : { + "NL": "Ho-oh", + "DE": "Ho-oh", + "EN": "Ho-oh", + "PT-BR": "Ho-oh" + }, + "celebi" : { + "NL": "Celebi", + "DE": "Celebi", + "EN": "Celebi", + "PT-BR": "Celebi" + }, + "raikou" : { + "NL": "Raikou", + "DE": "Raikou", + "EN": "Raikou", + "PT-BR": "Raikou" + }, + "entei" : { + "NL": "Entei", + "DE": "Entei", + "EN": "Entei", + "PT-BR": "Entei" + }, + "suicune" : { + "NL": "Suicune", + "DE": "Suicune", + "EN": "Suicune", + "PT-BR": "Suicune" + }, + "moltres" : { + "NL": "Moltres", + "DE": "Lavados", + "EN": "Moltres", + "PT-BR": "Moltres" + }, + "articuno" : { + "NL": "Articuno", + "DE": "Arktos", + "EN": "Articuno", + "PT-BR": "Articuno" + }, + "groudon" : { + "NL": "Groudon", + "DE": "Groudon", + "EN": "Groudon", + "PT-BR": "Groudon" + }, + "kyogre" : { + "NL": "Kyogre", + "DE": "Kyogre", + "EN": "Kyogre", + "PT-BR": "Kyogre" + }, + "rayquaza" : { + "NL": "Rayquaza", + "DE": "Rayquaza", + "EN": "Rayquaza", + "PT-BR": "Rayquaza" + }, + "latios" : { + "NL": "Latios", + "DE": "Latios", + "EN": "Latios", + "PT-BR": "Latios" + }, + "latias" : { + "NL": "Latias", + "DE": "Latias", + "EN": "Latias", + "PT-BR": "Latias" + }, + "deoxys" : { + "NL": "Deoxys", + "DE": "Deoxys", + "EN": "Deoxys", + "PT-BR": "Deoxys" + }, + "jirachi" : { + "NL": "Jirachi", + "DE": "Jirachi", + "EN": "Jirachi", + "PT-BR": "Jirachi" + }, + "regirock" : { + "NL": "Regirock", + "DE": "Regirock", + "EN": "Regirock", + "PT-BR": "Regirock" + }, + "regice" : { + "NL": "Regice", + "DE": "Regice", + "EN": "Regice", + "PT-BR": "Regice" + }, + "registeel" : { + "NL": "Registeel", + "DE": "Registeel", + "EN": "Registeel", + "PT-BR": "Registeel" + }, + "jynx" : { + "NL": "Jynx", + "DE": "Rossana", + "EN": "Jynx", + "PT-BR": "Jynx" + }, + "azumarill" : { + "NL": "Azumarill", + "DE": "Azumarill", + "EN": "Azumarill", + "PT-BR": "Azumarill" + }, + "piloswine" : { + "NL": "Piloswine", + "DE": "Keifel", + "EN": "Piloswine", + "PT-BR": "Piloswine" + }, + "salamence" : { + "NL": "Salamence", + "DE": "Brutalanda", + "EN": "Salamence", + "PT-BR": "Salamence" + }, + "feraligatr" : { + "NL": "Feraligatr", + "DE": "Impergator", + "EN": "Feraligatr", + "PT-BR": "Feraligatr" + }, + "meganium" : { + "NL": "Meganium", + "DE": "Meganie", + "EN": "Meganium", + "PT-BR": "Meganium" + }, + "typhlosion" : { + "NL": "Typhlosion", + "DE": "Tornupto", + "EN": "Typhlosion", + "PT-BR": "Typhlosion" + }, + "jolteon" : { + "NL": "Jolteon", + "DE": "Blitza", + "EN": "Jolteon", + "PT-BR": "Jolteon" + }, + "egg_5" : { + "NL": "Level 5 Ei", + "DE": "Level 5 Ei", + "EN": "Level 5 Egg", + "PT-BR": "Ovo de Nível 5" + }, + "egg_4" : { + "NL": "Level 4 Ei", + "DE": "Level 4 Ei", + "EN": "Level 4 Egg", + "PT-BR": "Ovo de Nível 4" + }, + "egg_3" : { + "NL": "Level 3 Ei", + "DE": "Level 3 Ei", + "EN": "Level 3 Egg", + "PT-BR": "Ovo de Nível 3" + }, + "egg_2" : { + "NL": "Level 2 Ei", + "DE": "Level 2 Ei", + "EN": "Level 2 Egg", + "PT-BR": "Ovo de Nível 2" + }, + "egg_1" : { + "NL": "Level 1 Ei", + "DE": "Level 1 Ei", + "EN": "Level 1 Egg", + "PT-BR": "Ovo de Nível 1" + }, + "lapras" : { + "NL": "Lapras", + "DE": "Lapras", + "EN": "Lapras", + "PT-BR": "Lapras" + }, + "nidoqueen" : { + "NL": "Nidoqueen", + "DE": "Nidoqueen", + "EN": "Nidoqueen", + "PT-BR": "Nidoqueen" + }, + "nidoking" : { + "NL": "Nidoking", + "DE": "Nidoking", + "EN": "Nidoking", + "PT-BR": "Nidoking" + }, + "absol" : { + "NL": "Absol", + "DE": "Absol", + "EN": "Absol", + "PT-BR": "Absol" + }, + "aggron" : { + "NL": "Aggron", + "DE": "Stolloss", + "EN": "Aggron", + "PT-BR": "Aggron" + }, + "tyranitar" : { + "NL": "Tyranitar", + "DE": "Despotar", + "EN": "Tyranitar", + "PT-BR": "Tyranitar" + }, + "snorlax" : { + "NL": "Snorlax", + "DE": "Relaxo", + "EN": "Snorlax", + "PT-BR": "Snorlax" + }, + "golem" : { + "NL": "Golem", + "DE": "Geowaz", + "EN": "Golem", + "PT-BR": "Golem" + }, + "rhydon" : { + "NL": "Rhydon", + "DE": "Rizeros", + "EN": "Rhydon", + "PT-BR": "Rhydon" + }, + "porygon" : { + "NL": "Porygon", + "DE": "Porygon", + "EN": "Porygon", + "PT-BR": "Porygon" + }, + "gengar" : { + "NL": "Gengar", + "DE": "Gengar", + "EN": "Gengar", + "PT-BR": "Gengar" + }, + "poliwrath" : { + "NL": "Poliwrath", + "DE": "Quappo", + "EN": "Poliwrath", + "PT-BR": "Poliwrath" + }, + "victreebel" : { + "NL": "Victreebel", + "DE": "Sarzenia", + "EN": "Victreebel", + "PT-BR": "Victreebel" + }, + "arcanine" : { + "NL": "Arcanine", + "DE": "Arkani", + "EN": "Arcanine", + "PT-BR": "Arcanine" + }, + "starmie" : { + "NL": "Starmie", + "DE": "Starmie", + "EN": "Starmie", + "PT-BR": "Starmie" + }, + "charizard" : { + "NL": "Charizard", + "DE": "Glurak", + "EN": "Charizard", + "PT-BR": "Charizard" + }, + "aerodactyl" : { + "NL": "Aerodactyl", + "DE": "Aerodactyl", + "EN": "Aerodactyl", + "PT-BR": "Aerodactyl" + }, + "claydol" : { + "NL": "Claydol", + "DE": "Lepumentas", + "EN": "Claydol", + "PT-BR": "Claydol" + }, + "machamp" : { + "NL": "Machamp", + "DE": "Machomei", + "EN": "Machamp", + "PT-BR": "Machamp" + }, + "alakazam" : { + "NL": "Alakazam", + "DE": "Simsala", + "EN": "Alakazam", + "PT-BR": "Alakazam" + }, + "scyther" : { + "NL": "Scyther", + "DE": "Sichlor", + "EN": "Scyther", + "PT-BR": "Schyther" + }, + "omastar" : { + "NL": "Omastar", + "DE": "Amoroso", + "EN": "Omastar", + "PT-BR": "Omastar" + }, + "ninetails" : { + "NL": "Ninetails", + "DE": "Vulnona", + "EN": "Ninetails", + "PT-BR": "Ninetails" + }, + "forest" : { + "NL": "Ergens in het bos", + "DE": "Irgendwo im Wald", + "EN": "Somewhere in the forest", + "PT-BR": "Em algum lugar na floresta" + }, + "select_gym_first_letter" : { + "NL": "Selecteer alstublieft de eerste letter van de gym:", + "DE": "Bitte Anfangsbuchstabe der Arena auswählen:", + "EN": "Please select the first letter of the gym:", + "PT-BR": "Por favor escolha a primeira letra do ginásio:" + }, + "select_gym" : { + "NL": "Beginletter geselecteerd.", + "DE": "Anfangsbuchstabe ausgewählt.", + "EN": "First letter selected.", + "PT-BR": "Primeira letra escolhida.:" + }, + "raid_creation_started_at" : { + "NL": "Raid aanmaak is gestart om", + "DE": "Das Raid wird angelegt seit", + "EN": "Raid creation was started at", + "PT-BR": "Criação da raid em" + }, + "raid_being_created_by_other_user" : { + "NL": "Een andere gebruiker is een raid voor deze gym aan het maken:", + "DE": "Ein Raid für diese Arena wird gerade angelegt von:", + "EN": "Another user is currently creating a raid for this gym:", + "PT-BR": "Outro usuário está criando uma raid para este ginásio:" + }, + "raid_already_exists" : { + "NL": "Raid bestaat al!", + "DE": "Raid existiert bereits!", + "EN": "Raid already exists!", + "PT-BR": "A raid já existe!" + }, + "create_raid" : { + "NL": "Begin Raid in", + "DE": "Erstelle Raid in", + "EN": "Create Raid in", + "PT-BR": "Criar raid em" + }, + "raid_creation_in_progress_warning" : { + "NL": "Je kan een raid aanmaken, maar de huidig aangemaakte raid zal worden overscheven. Deze wijziging kunnen niet ongedaan gemaakt worden dit is NIET AAN TE RADEN!", + "DE": "Das Raid kann weiter angelegt werden, aber dies wird das Raid welches gerade zeitgleich erstellt wird überschreiben und ist daher definitiv NICHT EMPFOHLEN!", + "EN": "You can continue with the raid creation, but this will overwrite the raid which is concurrently being created and is definitely NOT RECOMMENDED!", + "PT-BR": "Você pode continuar a criar a raid, mas você substituirá outra raid que está sendo criada e isso NÃO É RECOMENDADO!" + }, + "raid_creation_in_progress" : { + "NL": "Raid wordt momenteel aangemaakt", + "DE": "Raid wird gerade erstellt", + "EN": "Raid creation in progress", + "PT-BR": "Criação da raid em andamento" + }, + "select_raid_level_to_continue" : { + "NL": "Om echt door te gaan, selecteer een raid level", + "DE": "Um wirklich fortzufahren, bitte Raid Level auswählen", + "EN": "To really continue, please select raid level", + "PT-BR": "Para continuar, escolha o nível da raid" + }, + "select_raid_level" : { + "NL": "Selecteer Raid level", + "DE": "Bitte Raid Level auswählen", + "EN": "Select raid level", + "PT-BR": "Escolha o nível da raid" + }, + "gym" : { + "NL": "Gym", + "DE": "Arena", + "EN": "Gym", + "PT-BR": "Ginásio" + }, + "gym_saved" : { + "NL": "Gym opgeslagen.", + "DE": "Arena gespeichert.", + "EN": "Gym saved.", + "PT-BR": "Ginásio salvo." + }, + "select_raid_boss" : { + "NL": "Selecteer Raid baas", + "DE": "Raid Boss auswählen", + "EN": "Select Raid boss", + "PT-BR": "Escolha o Pokémon chefe da raid" + }, + "select_pokemon" : { + "NL": "Selecteer Pokemon", + "DE": "Pokemon auswählen", + "EN": "Select Pokemon", + "PT-BR": "Escolha o Pokémon" + }, + "raid_saved" : { + "NL": "Raid opgeslagen:", + "DE": "Raid gespeichert:", + "EN": "Raid saved:", + "PT-BR": "Raid salva:" + + }, + "raid_boss" : { + "NL": "#Raid baas", + "DE": "Raid-Boss", + "EN": "Raid boss", + "PT-BR": "Chefe da raid" + }, + "raid_boss_saved" : { + "NL": "Raid baas opgeslagen!", + "DE": "Raid-Boss gespeichert!", + "EN": "Raid boss saved!", + "PT-BR": "Chefe da raid salvo!" + }, + "not_supported" : { + "NL": "Niet ondersteund", + "DE": "Nicht unterstützt", + "EN": "Not supported", + "PT-BR": "Não compatível" + }, + "share" : { + "NL": "Delen", + "DE": "Teilen", + "EN": "Share", + "PT-BR": "Compartilhar" + }, + "share_with" : { + "NL": "Delen met", + "DE": "Teilen mit", + "EN": "Share with", + "PT-BR": "Compartilhar com" + }, + "set_gym_name_and_team" : { + "NL": "Optioneel - Gym naam and Gym Team:", + "DE": "Optional - Arena Name und Arena Team:", + "EN": "Optional - Gym name and Gym Team:", + "PT-BR": "Opcional - Nome do gínasio e nome do time" + }, + "set_gym_name_command" : { + "NL": "/gym Naam van de Gym", + "DE": "/gym Name der Arena", + "EN": "/gym Name of the Gym", + "PT-BR": "/gym Nome do ginásio" + }, + "set_gym_team" : { + "NL": "Optioneel - zet Gym en Team", + "DE": "Optional - Arena Team setzen", + "EN": "Optional - set Gym and Team", + "PT-BR": "Opcional - escolha o gínasio e time" + }, + "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", + "PT-BR": "/team Mystic/Valor/Instinct/Azul/Vermelho/Amarelo" + }, + "start_date_time" : { + "NL": "Starttijd gezet op", + "DE": "Startzeit gesetzt auf", + "EN": "Starttime set to", + "PT-BR": "Hora de começar determinada para" + }, + "end_time" : { + "NL": "Eindtijd gezet op ", + "DE": "Ablaufzeit gesetzt auf ", + "EN": "Endtime set to ", + "PT-BR": "Hora de término determinada para " + }, + "raid_select_date" : { + "NL": "Selecteer de datum van de raid:", + "DE": "Datum des Raids auswählen:", + "EN": "Select the date of the raid:", + "PT-BR": "Select the date of the raid:" + }, + "raid_select_hour" : { + "NL": "Selecteer het uur van de raid:", + "DE": "Stunde des Raids auswählen:", + "EN": "Select the hour of the raid:", + "PT-BR": "Select the hour of the raid:" + }, + "raid_select_start_time" : { + "NL": "Selecteer de start tijd van de raid:", + "DE": "Startzeit des Raids auswählen:", + "EN": "Select the start time of the raid:", + "PT-BR": "Select the start time of the raid:" + }, + "minutes" : { + "NL": "minuten", + "DE": "Minuten", + "EN": "minutes", + "PT-BR": "minutos" + }, + "raid_starts_when" : { + "NL": "Wanneer gaat het Raid ei open?", + "DE": "Wann beginnt der Raid?", + "EN": "When will the Raid begin?", + "PT-BR": "Quando a raid irá começar?" + }, + "raid_starts_when_minutes" : { + "NL": "Wanneer begint de Raid?", + "DE": "In wie viel Minuten beginnt der Raid?", + "EN": "In how many minutes does the raid begin?", + "PT-BR": "Em quantos minutos a raid irá começar?" + }, + "raid_starts_when_clocktime_view" : { + "NL": "klok", + "DE": "Uhrzeit-Ansicht", + "EN": "Clock time view", + "PT-BR": "Ver horário" + }, + "raid_starts_when_minutes_view" : { + "NL": "Minuten", + "DE": "Minuten-Ansicht", + "EN": "Minutes view", + "PT-BR": "Ver minutos" + }, + "raid_starts_when_view_changed" : { + "NL": "Overzicht verandert!", + "DE": "Ansicht geändert!", + "EN": "View changed!", + "PT-BR": "Visualização mudou!" + }, + "is_raid_active" : { + "NL": "Raid is al actief!", + "DE": "Raid läuft schon!", + "EN": "Raid is already active!", + "PT-BR": "A raid já está ativa!" + }, + "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!", + "PT-BR": "Você não tem permissão para utilizar esse comando ou bot!" + }, + "raid_access_denied" : { + "NL": "Je hebt geen rechten om deze raid aan te passen!", + "DE": "Sie haben keine Berechtigung dieses Raid zu bearbeiten!", + "EN": "You are not allowed to edit this raid!", + "PT-BR": "Você não tem permissão para editar esta raid!" + }, + "no_active_raids_found" : { + "NL": "Geen actieve raids gevonden!", + "DE": "Aktuell sind keine laufenden Raids im System!", + "EN": "No active raids found in the system!", + "PT-BR": "Nenhuma raid ativa encontrada no sistema!" + }, + "no_active_raids_shared" : { + "NL": "Geen van de actieve raid is gedeeld!", + "DE": "Keines der aktiven Raids wurde geteilt!", + "EN": "None of the active raids was shared!", + "PT-BR": "Nenhuma das raids ativas foi compartilhada!" + }, + "no_active_raids" : { + "NL": "Geen actieve raids!", + "DE": "Aktuell gibt es keine Raids!", + "EN": "No active raids currently!", + "PT-BR": "Nenhuma raid ativa no momento!" + }, + "expand" : { + "NL": "Uitklappen", + "DE": "Ausklappen", + "EN": "Expand", + "PT-BR": "Expandir" + }, + "pokemon_saved" : { + "NL": "Pokemon opgeslagen: ", + "DE": "Pokemon gespeichert: ", + "EN": "Pokemon saved: ", + "PT-BR": "Pokemon salvo " + }, + "how_long_raid" : { + "NL": "Hoe lang duurt de Raid?", + "DE": "Wie lange dauert der Raid?", + "EN": "How long will the raid last?", + "PT-BR": "Quanto tempo a raid vai durar" + }, + "lead_time_set_to" : { + "NL": "Doorlooptijd ingesteld op", + "DE": "Vorlaufzeit gesetzt auf", + "EN": "Lead time set to", + "PT-BR": "Tempo principal configurado para" + }, + "select_gym_name" : { + "NL": "Selecteer Gym:", + "DE": "Bitte Arena auswählen:", + "EN": "Select Gym:", + "PT-BR": "Escolha o ginásio:" + }, + "here_we_go" : { + "NL": "Hier gaan we!", + "DE": "Los gehts!", + "EN": "Here we go!", + "PT-BR": "Bora arrasar!" + }, + "create_a_raid" : { + "NL": "Maak een Raid", + "DE": "Raid anlegen", + "EN": "Create a Raid", + "PT-BR": "Criar a raid" + }, + "coordination_succes" : { + "NL": "Coördinatie geslaagd!", + "DE": "Koordinaten erfolgreich übermittelt!", + "EN": "Coordinates successfully submitted!", + "PT-BR": "Coordenadas enviadas com sucesso!" + }, + "update_pokemon" : { + "NL": "Pokemon vernieuwen", + "DE": "Pokemon aktualisieren", + "EN": "Update Pokemon", + "PT-BR": "Atualizar Pokemon" + }, + "send_location" : { + "NL": "Of stuur me alsjeblieft een locatie.", + "DE": "Oder sende mir einen Standort.", + "EN": "Or send me a location.", + "PT-BR": "Por favor, antes me envie a localização." + }, + "raid_by_gym" : { + "NL": "Maak een raid door een Gym te selecteren:", + "DE": "Lege ein Raid per Arena-Auswahl an:", + "EN": "Make a raid per gym selection:", + "PT-BR": "Ou escolha uma raid por ginásio:" + }, + "red" : { + "NL": "rood", + "DE": "rot", + "EN": "red", + "PT-BR": "vermelho" + }, + "yellow" : { + "NL": "geel", + "DE": "gelb", + "EN": "yellow", + "PT-BR": "amarelo" + }, + "blue" : { + "NL": "blauw", + "DE": "blau", + "EN": "blue", + "PT-BR": "azul" + }, + "gym_team_set_to" : { + "NL": "Gym Team gezet op:", + "DE": "Arena Team gesetzt auf:", + "EN": "Gym Team set to:", + "PT-BR": "Time do ginásio escolhido para" + }, + "invalid_team" : { + "NL": "Ongeldige team naam: schrijf: Mystic, Valor, Instinct or Blauw, Rood, Geel ", + "DE": "Ungültiger Team Name - schreibe: Mystic, Valor, Instinct oder Blau, Rot, Gelb", + "EN": "Invalid team name - write: Mystic, Valor, Instinct or Blue, Red, Yellow ", + "PT-BR": "Nome de time inválido - escreva: Mystic, Valor, Instinct ou Blue, Red, Yellow" + }, + "gym_name_updated" : { + "NL": "Gym naam aangepast.", + "DE": "Der Arena Name wurde aktualisiert.", + "EN": "Gym name updated.", + "PT-BR": "Nome do ginásio atualizado." + }, + "mods_details" : { + "NL": "Selecteer moderator voor meer informatie:", + "DE": "Für Details Moderator auswählen:", + "EN": "Select moderator for details:", + "PT-BR": "Escolha moderador para detalhes:" + }, + "mods_add_new" : { + "NL": "Nieuwe moderator toevoegen:", + "DE": "Neuen Moderator hinzufügen:", + "EN": "Add new moderator:", + "PT-BR": "Adicionar novo moderador:" + }, + "mods_delete" : { + "NL": "Moderator verwijderen:", + "DE": "Moderator löschen:", + "EN": "Delete moderator:", + "PT-BR": "Excluir moderador:" + }, + "mods_list_of_all" : { + "NL": "Lijst met alle moderators.", + "DE": "Liste aller Moderatoren.", + "EN": "List of all moderators.", + "PT-BR": "Lista de todos os moderadores." + }, + "mods_list_add_delete" : { + "NL": "Lijst, toevoegen of verwijderen van moderators", + "DE": "Moderatoren anzeigen, hinzufügen oder löschen", + "EN": "List, add or remove moderators", + "PT-BR": "Listar, adicionar ou remover moderadores" + }, + "mods_not_found" : { + "NL": "Error! Geen Moderator of gebruiker gevonden!", + "DE": "Fehler! Keine Moderatoren oder Benutzer gefunden!", + "EN": "Error! No moderators or users found!", + "PT-BR": "Erro! Nenhum moderador ou usuário encontrado!" + }, + "mods_saved_mod" : { + "NL": "Moderator opgeslagen!", + "DE": "Moderator gespeichert!", + "EN": "Moderator saved!", + "PT-BR": "Moderador salvo!" + }, + "mods_delete_mod" : { + "NL": "Moderator verwijderd!", + "DE": "Moderator gelöscht!", + "EN": "Moderator deleted!", + "PT-BR": "Moderador excluído!" + }, + "mods_info_about_mod" : { + "NL": "Informatie over deze moderator:", + "DE": "Infos zum diesem Moderator:", + "EN": "Info about this moderator:", + "PT-BR": "Informações sobre esse moderador:" + }, + "overview_share" : { + "NL": "Overzicht delen", + "DE": "Übersicht teilen", + "EN": "Share overview", + "PT-BR": "Detalhes de compartilhamento" + }, + "overview_delete" : { + "NL": "Vewijder overzicht", + "DE": "Übersicht löschen", + "EN": "Delete overview", + "PT-BR": "Deletar detalhes" + }, + "raids_list_share_overview" : { + "NL": "Geef de actieve raid weer als een lijst of deel / verwijder het raid overzicht", + "DE": "Aktive Raids als Liste anzeigen oder die Raid-Übersicht pro Chat teilen / löschen", + "EN": "Show active raids as list or share / delete the raid overview per chat", + "PT-BR": "Mostrar raids ativas como lista ou compartilhar / deletar detalhes de raid por chat" + }, + "list_all_active_raids" : { + "NL": "Alle actieve raids", + "DE": "Alle aktiven Raids", + "EN": "All active raids", + "PT-BR": "Todas as raids ativas" + }, + "list_all_overviews" : { + "NL": "Totaal raid overzicht", + "DE": "Alle Raid-Übersichten", + "EN": "All raid overviews", + "PT-BR": "Todos os detalhes de raid" + }, + "delete_raid_overview_for_chat" : { + "NL": "Verwijder raid overzicht voor", + "DE": "Raid-Übersicht löschen für", + "EN": "Delete raid overview for", + "PT-BR": "Deletar detalhe de raid para" + }, + "no_overviews_found" : { + "NL": "Geen raid overzicht gevonden in het systeem!", + "DE": "Keine Raid-Übersichten im System gefunden!", + "EN": "No raid overviews found in the system!", + "PT-BR": "Nenhum detalhe de raid encontrado no sistema!" + }, + "overview_successfully_deleted" : { + "NL": "Raid overzicht is succesvol verwijderd!", + "DE": "Raid-Übersicht wurde erfolgreich gelöscht!", + "EN": "Raid overview was successfully deleted!", + "PT-BR": "Detalhe de raid deletado com sucesso!" + }, + "overview_deletion_was_canceled" : { + "NL": "Het verwijderen van het raid overzicht is gestopt!", + "DE": "Löschung der Raid-Übersicht wurde abgebrochen!", + "EN": "Deletion of the raid overview was canceled!", + "PT-BR": "O deletamento dos detalhes da raid foi cancelado!" + }, + "raid_overview_for_chat" : { + "NL": "Raid overzicht voor", + "DE": "Raid-Übersicht für", + "EN": "Overview of raids for", + "PT-BR": "Detalhes de raids para" + }, + "successfully_shared" : { + "NL": "Succesvol gedeeld!", + "DE": "Erfolgreich geteilt!", + "EN": "Successfully shared!", + "PT-BR": "Compartilhado com sucesso!" + }, + "delete_this_raid" : { + "NL": "Verwijder deze raid?", + "DE": "Dieses Raid wirklich löschen?", + "EN": "Really delete this raid?", + "PT-BR": "Realmente deletar esta raid?" + }, + "raid_deletion_was_canceled" : { + "NL": "Het verwijderen van het raid is gestopt!", + "DE": "Löschung des Raids wurde abgebrochen!", + "EN": "Deletion of the raid was canceled!", + "PT-BR": "O deletamento da raid foi cancelado!" + }, + "raid_successfully_deleted" : { + "NL": "Raid is succesvol verwijderd!", + "DE": "Raid wurde erfolgreich gelöscht!", + "EN": "Raid was successfully deleted!", + "PT-BR": "Raid deletado com sucesso!" + }, + "action_aborted" : { + "NL": "Het proces is afgebroken!", + "DE": "Der Vorgang wurde abgebrochen!", + "EN": "The process was aborted!", + "PT-BR": "O processo foi abortado!" + }, + "any" : { + "NL": "Elk", + "DE": "Egal", + "EN": "Any", + "PT-BR": "Qualquer" + }, + "any_pokemon" : { + "NL": "Elke raid baas", + "DE": "Jeder Raid-Boss", + "EN": "Any raid boss", + "PT-BR": "Qualquer chefe da raid" + }, + "yes" : { + "NL": "Ja", + "DE": "Ja", + "EN": "Yes", + "PT-BR": "Sim" + }, + "no" : { + "NL": "Nee", + "DE": "Nein", + "EN": "No", + "PT-BR": "Não" + }, + "abort" : { + "NL": "Afbreken", + "DE": "Abbrechen", + "EN": "Abort", + "PT-BR": "Abortar" + }, + "list" : { + "NL": "Lijst", + "DE": "Anzeigen", + "EN": "List", + "PT-BR": "Lista" + }, + "add" : { + "NL": "Toevoegen", + "DE": "Hinzufügen", + "EN": "Add", + "PT-BR": "Adicionar" + }, + "delete" : { + "NL": "Verwijder", + "DE": "Löschen", + "EN": "Delete", + "PT-BR": "Deletar" + } +} diff --git a/logic.php b/logic.php old mode 100644 new mode 100755 index 341bfe7..e4b5b19 --- a/logic.php +++ b/logic.php @@ -1,347 +1,2527 @@ -fetch_assoc(); - if ($update['callback_query']['from']['id']!=$raid['user_id']) { - $query = 'SELECT COUNT(*) FROM users WHERE user_id='.$update['callback_query']['from']['id'].' AND moderator=1'; - $rs = my_query($query); - $row = $rs->fetch_row(); - if ($row['0']) return true; - - $callback_response = 'You are not allowed to edit this raid'; - answerCallbackQuery($update['callback_query']['id'],$callback_response); - exit; +' . getTranslation('bot_access_denied') . ''; + // Edit message or send new message based on value of $update_type + if ($update_type == 'callback_query') { + $keys = []; + // Edit message. + edit_message($update, $response_msg, $keys); + // Answer the callback. + answerCallbackQuery($update[$update_type]['id'], getTranslation('bot_access_denied')); + } else { + sendMessage($update[$update_type]['from']['id'], $response_msg); + } + exit; + } + } else { + $msg = ''; + $msg .= !empty($update['message']['from']['id']) ? "Id: " . $update['message']['from']['id'] . CR : ''; + $msg .= !empty($update['message']['from']['username']) ? "Username: " . $update['message']['from']['username'] . CR : ''; + $msg .= !empty($update['message']['from']['first_name']) ? "First Name: " . $update['message']['from']['first_name'] . CR : ''; + debug_log("Bot access is not restricted! Allowing access for user: " . CR . $msg); + return true; + } } +/** + * Raid access check. + * @param $update + * @param $data + * @return bool + */ +function raid_access_check($update, $data, $return_result = false) +{ + // Default: Deny access to raids + $raid_access = false; -function inline_key_array($buttons, $columns) { - $result = array(); - $col = 0; - $row = 0; - foreach ($buttons as $v) { - $result[$row][$col] = $v; - $col++; - if ($col>=$columns) { - $row++; - $col=0; - } + // Build query. + $rs = my_query( + " + SELECT * + FROM raids + WHERE id = {$data['id']} + " + ); + + $raid = $rs->fetch_assoc(); + + if ($update['callback_query']['from']['id'] != $raid['user_id']) { + // Build query. + $rs = my_query( + " + SELECT COUNT(*) + FROM users + WHERE user_id = {$update['callback_query']['from']['id']} + AND moderator = 1 + " + ); + + $row = $rs->fetch_row(); + + if (empty($row['0'])) { + $admin_access = bot_access_check($update, BOT_ADMINS, true); + if ($admin_access) { + // Allow raid access + $raid_access = true; + } + } else { + // Allow raid access + $raid_access = true; + } + } else { + // Allow raid access + $raid_access = true; + } + + // Allow or deny access to the raid and log result + if ($raid_access && !$return_result) { + debug_log("Allowing access to the raid"); + } else if ($raid_access && $return_result) { + debug_log("Allowing access to the raid"); + return $raid_access; + } else if (!$raid_access && $return_result) { + debug_log("Denying access to the raid"); + return $raid_access; + } else { + $keys = []; + if (isset($update['callback_query']['inline_message_id'])) { + editMessageText($update['callback_query']['inline_message_id'], '' . getTranslation('raid_access_denied') . '', $keys); + } else { + editMessageText($update['callback_query']['message']['message_id'], '' . getTranslation('raid_access_denied') . '', $keys, $update['callback_query']['message']['chat']['id'], $keys); + } + answerCallbackQuery($update['callback_query']['id'], getTranslation('raid_access_denied')); + exit; + } +} + +/** + * Raid duplication check. + * @param $gym + * @param $end + * @return $raid['id'] or 0 + */ +function raid_duplication_check($gym,$end) +{ + // Build query. + $rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE gym_name = '{$gym}' + ORDER BY id DESC + LIMIT 1 + " + ); + + // Get row. + $raid = $rs->fetch_assoc(); + + // Set duplicate ID to 0 + $duplicate_id = 0; + + // If gym is in database and new end_time matches existing end_time the updated duplicate ID to raid ID from database + if ($raid) { + // Timezone - maybe there's a more elegant solution as date_default_timezone_set?! + $tz = TIMEZONE; + date_default_timezone_set($tz); + + // Now + $now = time(); + + // Compare time - check minutes before and after database value + $beforeAfter = 15; + $extendBefore = 180; + + // Seems raid is being created at the moment + if ($raid['ts_end'] === NULL) { + // Compare via start_time. + $compare = "start"; + $time4compare = $now; + + // Set compare values. + $ts_compare_before = $raid['ts_start'] - ($beforeAfter*60); + $ts_compare_after = $raid['ts_start'] + ($beforeAfter*60); + } else { + // Compare via end_time. + $compare = "end"; + $time4compare = $now + $end*60; + + // Set compare values. + // Extend compare time for raid times if $time4compare is equal to $now which means $end must be 0 + $ts_compare_before = ($time4compare == $now) ? ($raid['ts_end'] - ($extendBefore*60)) : ($raid['ts_end'] - ($beforeAfter*60)); + $ts_compare_after = $raid['ts_end'] + ($beforeAfter*60); } - return $result; + + // Debug log unix times + debug_log('Unix timestamp of ' . $compare . 'time new raid: ' . $time4compare); + debug_log('Unix timestamp of ' . $compare . 'time -' . (($time4compare == $now) ? $extendBefore : $beforeAfter) . ' minutes of existing raid: ' . $ts_compare_before); + debug_log('Unix timestamp of ' . $compare . 'time +' . $beforeAfter . ' minutes of existing raid: ' . $ts_compare_after); + + // Debug log + debug_log('Searched database for raids at ' . $raid['gym_name']); + debug_log('Database raid ID of last raid at '. $raid['gym_name'] . ': ' . $raid['id']); + debug_log('New raid at ' . $raid['gym_name'] . ' will ' . $compare . ': ' . unix2tz($time4compare,$tz)); + debug_log('Existing raid at ' . $raid['gym_name'] . ' will ' . $compare . ' between ' . unix2tz($ts_compare_before,$tz) . ' and ' . unix2tz($ts_compare_after,$tz)); + + // Check if end_time of new raid is between plus minus the specified minutes of existing raid + if($time4compare >= $ts_compare_before && $time4compare <= $ts_compare_after){ + // Update existing raid. + // Negative raid ID if compare method is start and not end time + $duplicate_id = ($compare == "start") ? (0-$raid['id']) : $raid['id']; + debug_log('New raid matches ' . $compare . 'time of existing raid!'); + debug_log('Updating raid ID: ' . $duplicate_id); + } else { + // Create new raid. + debug_log('New raid ' . $compare . 'time does not match the ' . $compare . 'time of existing raid.'); + debug_log('Creating new raid at gym: ' . $raid['gym_name']); + } + } else { + debug_log("Gym '" . $gym . "' not found in database!"); + debug_log("Creating new raid at gym: " . $gym); + } + + // Return ID, -ID or 0 + return $duplicate_id; } -function raid_edit_start_keys($id) { - $keys = - [[[ - 'text' => 'Legendary Raid *****','callback_data' => $id.':edit:type_5', - ]],[[ - 'text' => '4 Star Raid ****', 'callback_data' => $id.':edit:type_4', - ],[ - 'text' => '3 Star Raid ***', 'callback_data' => $id.':edit:type_3', - ]],[[ - 'text' => '2 Star Raid **', 'callback_data' => $id.':edit:type_2', - ],[ - 'text' => '1 Star Raid *', 'callback_data' => $id.':edit:type_1', - ]]]; - return $keys; +/** + * Insert gym. + * @param $gym_name + * @param $latitude + * @param $longitude + * @param $address + */ +function insert_gym($name, $lat, $lon, $address) +{ + global $db; + + // Build query to check if gym is already in database or not + $rs = my_query( + " + SELECT COUNT(*) + FROM gyms + WHERE gym_name = '{$name}' + " + ); + + $row = $rs->fetch_row(); + + // Gym already in database or new + if (empty($row['0'])) { + // Build query for gyms table to add gym to database + debug_log('Gym not found in database gym list! Adding gym "' . $name . '" to the database gym list.'); + $rs = my_query( + " + INSERT INTO gyms + SET lat = '{$lat}', + lon = '{$lon}', + gym_name = '{$db->real_escape_string($name)}', + address = '{$db->real_escape_string($address)}' + " + ); + } else { + // Update gyms table to reflect gym changes. + debug_log('Gym found in database gym list! Updating gym "' . $name . '" now.'); + $rs = my_query( + " + UPDATE gyms + SET lat = '{$lat}', + lon = '{$lon}', + address = '{$db->real_escape_string($address)}' + WHERE gym_name = '{$name}' + " + ); + } } -function keys_raid_people($data) { - if (!is_array($data)) $data=array('id'=>$data); - - $keys = [[ - 'text' => '+1', 'callback_data' => $data['id'].':vote:1', - ],[ - 'text' => '+2', 'callback_data' => $data['id'].':vote:2' - ],[ - 'text' => '+3', 'callback_data' => $data['id'].':vote:3' - ],[ - 'text' => '+4', 'callback_data' => $data['id'].':vote:4' - ],[ - 'text' => '+5', 'callback_data' => $data['id'].':vote:5' - ]]; - return $keys; +/** + * Get gym. + * @param $id + * @return array + */ +function get_gym($id) +{ + // Get gyms from database + $rs = my_query( + " + SELECT * + FROM gyms + WHERE id = {$id} + " + ); + + $gym = $rs->fetch_assoc(); + + return $gym; } -function keys_vote($raid) { - $keys_team = []; - $keys_time = []; - - $end_time = $raid['ts_end']; - $now = $raid['ts_now']; - - $keys = [[[ - 'text' => '+1', 'callback_data' => $raid['id'].':vote:1', - ],[ - 'text' => '+2', 'callback_data' => $raid['id'].':vote:2' - ],[ - 'text' => '+3', 'callback_data' => $raid['id'].':vote:3' - ],[ - 'text' => '+4', 'callback_data' => $raid['id'].':vote:4' - ],[ - 'text' => '+5', 'callback_data' => $raid['id'].':vote:5' - ]],[[ - 'text' => TEAM_B.' Mystic', 'callback_data' => $raid['id'].':vote_team:mystic', - ],[ - 'text' => TEAM_R.' Valor', 'callback_data' => $raid['id'].':vote_team:valor', - ],[ - 'text' => TEAM_Y.' Instinct', 'callback_data' => $raid['id'].':vote_team:instinct', - ]]]; - - if ($end_time<$now) { - $keys[] = [array('text'=>'Raid Finished','callback_data'=>$raid['id'].':vote_time:'.(ceil(time()/300)*300))]; - } else { - $col = 1; - for ($i=ceil($now/300)*300; $i<=($end_time-300); $i=$i+300) { - if ($col++>=5) { - $keys[] = $keys_time; - $keys_time = []; - $col = 1; - } - $keys_time[] = array('text' => unix2tz($i,$raid['timezone']), 'callback_data' => $raid['id'].':vote_time:'.$i); - } - $keys[] = $keys_time; - } +/** + * Get user. + * @param $user_id + * @return message + */ +function get_user($user_id) +{ + // Get user details. + $rs = my_query( + " + SELECT * + FROM users + WHERE user_id = {$user_id} + " + ); + // Fetch the row. + $row = $rs->fetch_assoc(); - $keys[] = [ - ['text' => EMOJI_REFRESH, 'callback_data' => $raid['id'].':vote_refresh:0'], - ['text' => 'Arrived', 'callback_data' => $raid['id'].':vote_arrived:0'], - ['text' => 'Done', 'callback_data' => $raid['id'].':vote_done:0'], - ['text' => 'Won\'t come', 'callback_data' => $raid['id'].':vote_cancel:0'], - ]; - if ($end_time<$now) { - $keys = [[['text'=>'Raid Finished','callback_data'=>$raid['id'].':vote_refresh:0']]]; - } - return $keys; + // Build message string. + $msg = ''; + + // Add name. + $msg .= 'Name: ' . htmlspecialchars($row['name']) . '' . CR; + + // Unknown team. + if ($row['team'] === NULL) { + $msg .= 'Team: ' . $GLOBALS['teams']['unknown'] . CR; + + // Known team. + } else { + $msg .= 'Team: ' . $GLOBALS['teams'][$row['team']] . CR; + } + + // Add level. + if ($row['level'] != 0) { + $msg .= 'Level: ' . $row['level'] . CR; + } + + return $msg; } +/** + * Moderator keys. + * @param $limit + * @param $action + * @return array + */ +function edit_moderator_keys($limit, $action) +{ + // Number of entries to display at once. + $entries = 10; -function update_user($update) { - global $db; - - $name = ''; - $sep = ''; + // Init empty keys array. + $keys = array(); - if ($update['message']) { - $msg = $update['message']['from']; - } + // Get moderators from database + if ($action == "list" || $action == "delete") { + $rs = my_query( + " + SELECT * + FROM users + WHERE moderator = 1 + ORDER BY name + LIMIT $limit, $entries + " + ); - if ($update['callback_query']) { - $msg = $update['callback_query']['from']; - } + // Number of entries + $cnt = my_query( + " + SELECT COUNT(*) + FROM users + WHERE moderator = 1 + " + ); + } else if ($action == "add") { + $rs = my_query( + " + SELECT * + FROM users + WHERE (moderator = 0 OR moderator IS NULL) + ORDER BY name + LIMIT $limit, $entries + " + ); - if ($update['inline_query']) { - $msg = $update['inline_query']['from']; - } + // Number of entries + $cnt = my_query( + " + SELECT COUNT(*) + FROM users + WHERE (moderator = 0 OR moderator IS NULL) + " + ); + } - $id = $msg['id']; - if (!$id) { - debug_log('No id','!'); - debug_log($update,'!'); - return false; - } + // Number of database entries found. + $sum = $cnt->fetch_row(); + $count = $sum['0']; + // List users / moderators + while ($mod = $rs->fetch_assoc()) { + $keys[] = array( + 'text' => $mod['name'], + 'callback_data' => '0:mods_' . $action . ':' . $mod['user_id'] + ); + } - if ($msg['first_name']) { - $name = $msg['first_name']; - $sep = ' '; - } - if ($msg['last_name']) $name .= $sep.$msg['last_name']; - - - $request = my_query('INSERT INTO users SET - user_id='.$id.', - nick="'.$db->real_escape_string($msg['username']).'", - name="'.$db->real_escape_string($name).'" - ON DUPLICATE KEY UPDATE - nick="'.$db->real_escape_string($msg['username']).'", - name="'.$db->real_escape_string($name).'" - '); - return $request; + // Add back key. + if ($limit > 0) { + $new_limit = $limit - $entries; + $empty_back_key = array(); + $key_back = back_key($empty_back_key, $new_limit, "mods", $action); + $key_back = $key_back[0]; + $keys = array_merge($key_back, $keys); + } + + // Add next key. + if (($limit + $entries) < $count) { + $new_limit = $limit + $entries; + $empty_next_key = array(); + $key_next = next_key($empty_next_key, $new_limit, "mods", $action); + $key_next = $key_next[0]; + $keys = array_merge($keys, $key_next); + } + + // Get the inline key array. + $keys = inline_key_array($keys, 1); + + return $keys; } -function send_response_vote($update, $data, $new=false) { - $rs = my_query('SELECT *, - UNIX_TIMESTAMP(end_time) AS ts_end, - UNIX_TIMESTAMP(NOW()) as ts_now, - UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left - FROM raids WHERE id='.$data['id'].''); - $raid = $rs->fetch_assoc(); - - $msg = show_raid_poll($raid); - $keys = keys_vote($raid); - - if ($new) { - $loc = send_location('none',$update['callback_query']['message']['chat']['id'],$raid['lat'], $raid['lon']); - debug_log('location:'); - debug_log($loc); - $msg = send_message('none',$update['callback_query']['message']['chat']['id'],$msg."\n", $keys, ['reply_to_message_id'=>$loc['result']['message_id']]); - answerCallbackQuery($update['callback_query']['id'],$msg); - } else { - edit_message($update, $msg, $keys); - $msg = 'Raid attendance updated'; - answerCallbackQuery($update['callback_query']['id'],$msg); - } - exit; +/** + * Inline key array. + * @param $buttons + * @param $columns + * @return array + */ +function inline_key_array($buttons, $columns) +{ + $result = array(); + $col = 0; + $row = 0; + + foreach ($buttons as $v) { + $result[$row][$col] = $v; + $col++; + + if ($col >= $columns) { + $row++; + $col = 0; + } + } + return $result; } +/** + * Raid edit start keys. + * @param $id + * @return array + */ +function raid_edit_start_keys($id) +{ + // Init empty keys array. + $keys = array(); + + // Create start keys based on levels in constants + $pokemonlist = $GLOBALS['pokemon']; + foreach($pokemonlist as $level => $levelmons) { + if($level == "X") continue; + $keys[] = array( + 'text' => getTranslation($level . 'stars'), + 'callback_data' => $id . ':edit:' . $level + ); + } + + // Get the inline key array. + $keys = inline_key_array($keys, 3); + +// OLD, static code: +/* + $keys = [ + [ + [ + 'text' => getTranslation('5stars'), + 'callback_data' => $id . ':edit:5' + ] + ], + [ + [ + 'text' => getTranslation('4stars'), + 'callback_data' => $id . ':edit:4' + ], + [ + 'text' => getTranslation('3stars'), + 'callback_data' => $id . ':edit:3' + ] + ], + [ + [ + 'text' => getTranslation('2stars'), + 'callback_data' => $id . ':edit:2' + ], + [ + 'text' => getTranslation('1stars'), + 'callback_data' => $id . ':edit:1' + ] + ] + ]; +*/ -function unix2tz($unix, $tz, $format = 'H:i') { - if (!$unix) return false; - $dt = new DateTime('@'.$unix); - $dt->setTimeZone(new DateTimeZone($tz)); - return $dt->format($format); + return $keys; } -function show_raid_poll($raid) { - $time_left = floor($raid['t_left']/60); - $time_left = floor($time_left/60).':'.str_pad($time_left%60,2,'0',STR_PAD_LEFT).' left'; +/** + * Raid gym first letter selection + * @param $chat_id + * @param $chattype + * @return $keys array + */ +function raid_edit_gyms_first_letter_keys($chatid, $chattype) { + // Get gyms from database + $rs = my_query( + " + SELECT * + FROM gyms + ORDER BY gym_name + " + ); - $msg = ''; - if ($raid['gym_name'] || $raid['gym_team']) { - $msg .= 'Gym: '.$raid['gym_name'].''; - if ($raid['gym_team']) $msg .= ' '.$GLOBALS['teams'][$raid['gym_team']].' '.ucfirst($raid['gym_team']); - $msg .= CR; - } - if ($raid['address']) { - $addr = explode(',',$raid['address'],4); - array_pop($addr); - $addr = implode(',',$addr); - $msg .= ''.$addr.''.CR2; - } - $msg .= '#Raid '.ucfirst($raid['pokemon']).''.CR2; - //$msg .= CR; - if ($time_left<0) { - $msg .= 'Raid Finished'.CR2; - } else { - //$msg .= ''.$time_left.' until '.substr($raid['end_time'],11,5)."\n\n"; - $msg .= ''.$time_left.' until '.unix2tz($raid['ts_end'],$raid['timezone'])."\n\n"; + // Init empty keys array. + $keys = array(); + + // Init previous first letter + $previous = null; + + while ($gym = $rs->fetch_assoc()) { + $first = strtoupper(substr($gym['gym_name'], 0, 1)); + // Add first letter to keys array + if($previous !== $first) { + $keys[] = array( + 'text' => $first, + 'callback_data' => $chatid . ',' . $chattype . ':raid_by_gym:' . $first + ); } - $msg .= 'Location: https://maps.google.com/?q='.$raid['lat'].','.$raid['lon'].CR; - - $query = 'SELECT *, UNIX_TIMESTAMP(attend_time) AS ts_att FROM attendance WHERE raid_id='.$raid['id'].' ORDER BY cancel ASC, raid_done DESC, team ASC, arrived DESC, attend_time ASC'; - $rs = my_query($query); - $data = array(); - - while ($row = $rs->fetch_assoc()) { - if ($row['cancel']) $row['team']='cancel'; - if ($row['raid_done']) $row['team']='done'; - if (!$row['team']) $row['team']='unknown'; - $data[$row['team']][] = $row; - if ($row['extra_people']) { - for ($i=1; $i<=$row['extra_people']; $i++) { - $data[$row['team']][] = false; - } - } + $previous = $first; + } + + // Get the inline key array. + $keys = inline_key_array($keys, 4); + + return $keys; +} + +/** + * Raid edit gym keys. + * @param $chat_id + * @param $chattype + * @param $first + * @return $keys array + */ +function raid_edit_gym_keys($chatid, $chattype, $first) +{ + // Get gyms from database + $rs = my_query( + " + SELECT * + FROM gyms + WHERE UPPER(LEFT(gym_name, 1)) = UPPER('{$first}') + ORDER BY gym_name + " + ); + + // Init empty keys array. + $keys = array(); + + while ($gym = $rs->fetch_assoc()) { + $keys[] = array( + 'text' => $gym['gym_name'], + 'callback_data' => $chatid . ',' . $chattype . ':raid_create:ID,' . $gym['id'] + ); + } + + // Get the inline key array. + $keys = inline_key_array($keys, 1); + + return $keys; +} + +/** + * Pokemon keys. + * @param $raid_id + * @param $raid_level + * @return array + */ +function pokemon_keys($raid_id, $raid_level, $pokemonlist, $action) +{ + // Init empty keys array. + $keys = array(); + + // Iterate thru the pokemon list to create the keys + foreach($pokemonlist as $level => $levelmons) { + if($level == $raid_level) { + // Create the keys. + foreach($levelmons as $key => $pokemon) { + $keys[] = array( + 'text' => $pokemon, + 'callback_data' => $raid_id . ':' . $action . ':' . $pokemon + ); + } } + } - debug_log($data); - - if (count($data)==0) { - $msg .= CR.'No participants yet.'.CR; + // Get the inline key array. + $keys = inline_key_array($keys, 3); + + return $keys; +} + +/** + * Back key. + * @param $keys + * @param $id + * @param $action + * @param $arg + * @return array + */ +function back_key($keys, $id, $action, $arg) +{ + $keys[] = [ + array( + 'text' => getTranslation('back'), + 'callback_data' => $id . ':' . $action . ':' . $arg + ) + ]; + + return $keys; +} + +/** + * Next key. + * @param $keys + * @param $id + * @param $action + * @param $arg + * @return array + */ +function next_key($keys, $id, $action, $arg) +{ + $keys[] = [ + array( + 'text' => getTranslation('next'), + 'callback_data' => $id . ':' . $action . ':' . $arg + ) + ]; + + return $keys; +} + +/** + * Share keys. + * @param $raid_id + * @param $user_id + * @return array + */ +function share_keys($raid_id, $user_id) +{ + // Moderator or not? + debug_log("Checking if user is moderator: " . $user_id); + $rs = my_query( + " + SELECT moderator + FROM users + WHERE user_id = {$user_id} + " + ); + + // Fetch user data. + $user = $rs->fetch_assoc(); + + // Check moderator status. + $mod = $user['moderator']; + debug_log('User is ' . (($mod == 1) ? '' : 'not ') . 'a moderator: ' . $user_id); + + // Add share button if not restricted. + if ((SHARE_MODERATORS == true && $mod == 1) || SHARE_USERS == true) { + debug_log('Adding general share key to inline keys'); + // Set the keys. + $keys[] = [ + [ + 'text' => getTranslation('share'), + 'switch_inline_query' => strval($raid_id) + ] + ]; + } + + // Add buttons for predefined sharing chats. + if (!empty(SHARE_CHATS)) { + // Add keys for each chat. + $chats = explode(',', SHARE_CHATS); + foreach($chats as $chat) { + // Get chat object + debug_log("Getting chat object for '" . $chat . "'"); + $chat_obj = get_chat($chat); + + // Check chat object for proper response. + if ($chat_obj['ok'] == true) { + debug_log('Proper chat object received, continuing to add key for this chat: ' . $chat_obj['result']['title']); + $keys[] = [ + [ + 'text' => getTranslation('share_with') . ' ' . $chat_obj['result']['title'], + 'callback_data' => $raid_id . ':raid_share:' . $chat + ] + ]; + } + } + } + + return $keys; +} + +/** + * Insert cleanup info to database. + * @param $chat_id + * @param $message_id + * @param $raid_id + */ +function insert_cleanup($chat_id, $message_id, $raid_id) +{ + // Log ID's of raid, chat and message + debug_log('Raid_ID: ' . $raid_id); + debug_log('Chat_ID: ' . $chat_id); + debug_log('Message_ID: ' . $message_id); + + if ((is_numeric($chat_id)) && (is_numeric($message_id)) && (is_numeric($raid_id)) && ($raid_id > 0)) { + global $db; + + // Get raid times. + $rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = {$raid_id} + " + ); + + // Fetch raid data. + $raid = $rs->fetch_assoc(); + // Init found. + $found = false; + + // Insert cleanup info to database + if ($raid) { + // Check if cleanup info is already in database or not + // Needed since raids can be shared to multiple channels / supergroups! + $rs = my_query( + " + SELECT * + FROM cleanup + WHERE raid_id = '{$raid_id}' + " + ); + + // Chat_id and message_id equal to info from database + while ($cleanup = $rs->fetch_assoc()) { + // Leave while loop if cleanup info is already in database + if(($cleanup['chat_id'] == $chat_id) && ($cleanup['message_id'] == $message_id)) { + debug_log('Cleanup preparation info is already in database!'); + $found = true; + break; + } + } } + + // Insert into database when raid found but no cleanup info found + if ($raid && !$found) { + // 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}' + " + ); + } + } else { + debug_log('Invalid input for cleanup preparation!'); + } +} + +/** + * Run cleanup. + * @param $telegram + * @param $database + */ +function run_cleanup ($telegram = 2, $database = 2) { + // Check configuration, cleanup of telegram needs to happen before database cleanup! + if (CLEANUP_TIME_TG > CLEANUP_TIME_DB) { + cleanup_log('Configuration issue! Cleanup time for telegram messages needs to be lower or equal to database cleanup time!'); + cleanup_log('Stopping cleanup process now!'); + exit; + } + + /* Check input + * 0 = Do nothing + * 1 = Cleanup + * 2 = Read from config + */ + + // Get cleanup values from config per default. + if ($telegram == 2) { + $telegram = (CLEANUP_TELEGRAM == true) ? 1 : 0; + } + + if ($database == 2) { + $database = (CLEANUP_DATABASE == true) ? 1 : 0; + } + + // Start cleanup when at least one parameter is set to trigger cleanup + if ($telegram == 1 || $database == 1) { + // Query for telegram cleanup without database cleanup + if ($telegram == 1 && $database == 0) { + // Get cleanup info. + $rs = my_query( + " + SELECT * + FROM cleanup + WHERE chat_id <> 0 + ORDER BY id DESC + LIMIT 0, 100 + ", true + ); + // Query for database cleanup without telegram cleanup + } else if ($telegram == 0 && $database == 1) { + // Get cleanup info. + $rs = my_query( + " + SELECT * + FROM cleanup + WHERE chat_id = 0 + LIMIT 0, 100 + ", true + ); + // Query for telegram and database cleanup + } else { + // Get cleanup info. + $rs = my_query( + " + SELECT * + FROM cleanup + LIMIT 0, 100 + ", true + ); + } + + // Init empty cleanup jobs array. + $cleanup_jobs = array(); + + // Fill array with cleanup jobs. + while ($rowJob = $rs->fetch_assoc()) { + $cleanup_jobs[] = $rowJob; + } + + // Write to log. + cleanup_log($cleanup_jobs); + + // Init previous raid id. + $prev_raid_id = "FIRST_RUN"; + + foreach ($cleanup_jobs as $row) { + // Set current raid id. + $current_raid_id = ($row['raid_id'] == 0) ? $row['cleaned'] : $row['raid_id']; + + // Write to log. + cleanup_log("Cleanup ID: " . $row['id']); + cleanup_log("Chat ID: " . $row['chat_id']); + cleanup_log("Message ID: " . $row['message_id']); + cleanup_log("Raid ID: " . $row['raid_id']); + + // Make sure raid exists + $rs = my_query( + " + SELECT UNIX_TIMESTAMP(end_time) AS ts_end + FROM raids + WHERE id = {$current_raid_id} + ", true + ); + $rr = $rs->fetch_row(); + + // No raid found - set cleanup to 0 and continue with next raid + if (empty($rr['0'])) { + cleanup_log('No raid found with ID: ' . $current_raid_id, '!'); + cleanup_log('Updating cleanup information.'); + my_query( + " + UPDATE cleanup + SET chat_id = 0, + message_id = 0 + WHERE id = {$row['id']} + ", true + ); + + // Continue with next raid + continue; + } + + // Get raid data only when raid_id changed compared to previous run + if ($prev_raid_id != $current_raid_id) { + // Get the raid data by id. + $rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = {$current_raid_id} + ", true + ); + + // Fetch raid data. + $raid = $rs->fetch_assoc(); + + // Set times. + $end = $raid['ts_end']; + $tz = $raid['timezone']; + $now = $raid['ts_now']; + $cleanup_time_tg = 60*CLEANUP_TIME_TG; + $cleanup_time_db = 60*CLEANUP_TIME_DB; + + // Write times to log. + cleanup_log("Current time: " . unix2tz($now,$tz,"Y-m-d H:i:s")); + cleanup_log("Raid end time: " . unix2tz($end,$tz,"Y-m-d H:i:s")); + cleanup_log("Telegram cleanup time: " . unix2tz(($end + $cleanup_time_tg),$tz,"Y-m-d H:i:s")); + cleanup_log("Database cleanup time: " . unix2tz(($end + $cleanup_time_db),$tz,"Y-m-d H:i:s")); + + // Write unix timestamps to log. + cleanup_log(CR . "Unix timestamps:"); + cleanup_log("Current time: " . $now); + cleanup_log("Raid end time: " . $end); + cleanup_log("Telegram cleanup time: " . ($end + $cleanup_time_tg)); + cleanup_log("Database cleanup time: " . ($end + $cleanup_time_db)); + } + + // Time for telegram cleanup? + if (($end + $cleanup_time_tg) < $now) { + // Delete raid poll telegram message if not already deleted + if ($telegram == 1 && $row['chat_id'] != 0 && $row['message_id'] != 0) { + // Delete telegram message. + cleanup_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']); + // Set database values of chat_id and message_id to 0 so we know telegram message was deleted already. + cleanup_log('Updating telegram cleanup information.'); + my_query( + " + UPDATE cleanup + SET chat_id = 0, + message_id = 0 + WHERE id = {$row['id']} + ", true + ); + } else { + if ($telegram == 1) { + cleanup_log('Telegram message is already deleted!'); + } else { + cleanup_log('Telegram cleanup was not triggered! Skipping...'); + } + } + } else { + cleanup_log('Skipping cleanup of telegram for this raid! Cleanup time has not yet come...'); + } + + // Time for database cleanup? + if (($end + $cleanup_time_db) < $now) { + // Delete raid from attendance table. + // Make sure to delete only once - raid may be in multiple channels/supergroups, but only 1 time in database + if (($database == 1) && $row['raid_id'] != 0 && ($prev_raid_id != $current_raid_id)) { + // Delete raid from attendance table. + cleanup_log('Deleting attendances for raid ' . $current_raid_id); + my_query( + " + DELETE FROM attendance + WHERE id = {$row['raid_id']} + ", true + ); + + // Set database value of raid_id to 0 so we know attendance info was deleted already + // Use raid_id in where clause since the same raid_id can in cleanup more than once + cleanup_log('Updating database cleanup information.'); + my_query( + " + UPDATE cleanup + SET raid_id = 0, + cleaned = {$row['raid_id']} + WHERE raid_id = {$row['raid_id']} + ", true + ); + } else { + if ($database == 1) { + cleanup_log('Attendances are already deleted!'); + } else { + cleanup_log('Attendance cleanup was not triggered! Skipping...'); + } + } + + // Delete raid from cleanup table and raid table once every value is set to 0 and cleaned got updated from 0 to the raid_id + // In addition trigger deletion only when previous and current raid_id are different to avoid unnecessary sql queries + if ($row['raid_id'] == 0 && $row['chat_id'] == 0 && $row['message_id'] == 0 && $row['cleaned'] != 0 && ($prev_raid_id != $current_raid_id)) { + // Delete raid from raids table. + cleanup_log('Deleting raid ' . $row['cleaned'] . ' from database.'); + my_query( + " + DELETE FROM raids + WHERE id = {$row['cleaned']} + ", true + ); + + // Get all cleanup jobs which will be deleted now. + cleanup_log('Removing cleanup info from database:'); + $rs_cl = my_query( + " + SELECT * + FROM cleanup + WHERE cleaned = {$row['cleaned']} + ", true + ); + + // Log each cleanup ID which will be deleted. + while($rs_cleanups = $rs_cl->fetch_assoc()) { + cleanup_log('Cleanup ID: ' . $rs_cleanups['id'] . ', Former Raid ID: ' . $rs_cleanups['cleaned']); + } + + // Finally delete from cleanup table. + my_query( + " + DELETE FROM cleanup + WHERE cleaned = {$row['cleaned']} + ", true + ); + } else { + if ($prev_raid_id != $current_raid_id) { + cleanup_log('Time for complete removal of raid from database has not yet come.'); + } else { + cleanup_log('Complete removal of raid from database was already done!'); + } + } + } else { + cleanup_log('Skipping cleanup of database for this raid! Cleanup time has not yet come...'); + } - foreach ($GLOBALS['teams'] as $k=>$v) { - if (!count($data[$k])) continue; - $msg .= CR.$v.' '.ucfirst($k).': '.count($data[$k]).''."\n"; - foreach ($data[$k] as $vv) { - if ($vv===false) continue; - if ($vv['raid_done']) continue; - $query = 'SELECT * FROM users WHERE user_id='.$vv['user_id']; - $rs = my_query($query); - $row = $rs->fetch_assoc(); - $name = '@'.$row['nick']; - if ($name=='@') $name = $row['name']; - if ($name=='') $name = $vv['user_id']; - $msg .= ' - '.$name.' '; - if ($vv['arrived']) { - $msg .= '[arrived '.unix2tz($vv['ts_att'],$raid['timezone']).'] '; - } else if ($vv['cancel']) { - $msg .= '[cancel] '; - } else { -// $msg .= '['.substr($vv['attend_time'],11,5).'] '; - $msg .= '['.unix2tz($vv['ts_att'],$raid['timezone']).'] '; - } - if ($vv['extra_people']) $msg .= '+'.$vv['extra_people']; - - $msg .= CR; + // Store current raid id as previous id for next loop + $prev_raid_id = $current_raid_id; + } + + // Write to log. + cleanup_log('Finished with cleanup process!'); + } +} + +/** + * Keys vote. + * @param $raid + * @return array + */ +function keys_vote($raid) +{ + // Init keys time array. + $keys_time = []; + + $end_time = $raid['ts_end']; + $now = $raid['ts_now']; + $start_time = $raid['ts_start']; + + $keys = [ + [ + [ + 'text' => getTranslation('alone'), + 'callback_data' => $raid['id'] . ':vote:1' + ], + [ + 'text' => '+1', + 'callback_data' => $raid['id'] . ':vote:2' + ], + [ + 'text' => '+2', + 'callback_data' => $raid['id'] . ':vote:3' + ], + [ + 'text' => '+3', + 'callback_data' => $raid['id'] . ':vote:4' + ], + [ + 'text' => '+4', + 'callback_data' => $raid['id'] . ':vote:5' + ] + ], + [ + [ + 'text' => TEAM_B, + 'callback_data' => $raid['id'] . ':vote_team:mystic' + ], + [ + 'text' => TEAM_R, + 'callback_data' => $raid['id'] . ':vote_team:valor' + ], + [ + 'text' => TEAM_Y, + 'callback_data' => $raid['id'] . ':vote_team:instinct' + ], + [ + 'text' => 'Lvl +', + 'callback_data' => $raid['id'] . ':vote_level:up' + ], + [ + 'text' => 'Lvl -', + 'callback_data' => $raid['id'] . ':vote_level:down' + ] + ] + ]; + + if ($end_time < $now) { + $keys[] = [ + array( + 'text' => getTranslation('raid_done'), + 'callback_data' => $raid['id'] . ':vote_time:' . (ceil(time() / 900) * 900) + ) + ]; + + } else { + $timePerSlot = 60*RAID_SLOTS; + $timeBeforeEnd = 60*RAID_LAST_START; + $col = 1; + // Old stuff, left for possible future use or in case of bugs: + //for ($i = ceil($now / $timePerSlot) * $timePerSlot; $i <= ($end_time - $timeBeforeEnd); $i = $i + $timePerSlot) { + //for ($i = ceil($start_time / $timePerSlot) * $timePerSlot; $i <= ($end_time - $timeBeforeEnd); $i = $i + $timePerSlot) { + + // Make start_time a possible vote_time: + // start_time minus 60 for a voting option e.g. 13:30 when an egg opens right at 13:30. Without minus 60, the first voting option would be 13:45 for example (assuming RAID_SLOTS = 15) + for ($i = ceil(($start_time - 60) / $timePerSlot) * $timePerSlot; $i <= ($end_time - $timeBeforeEnd); $i = $i + $timePerSlot) { + + if ($col++ >= 4) { + $keys[] = $keys_time; + $keys_time = []; + $col = 1; + } + + // Plus 60 seconds, so vote button for e.g. 10:00 will disappear after 10:00:59 / at 10:01:00 and not right after 09:59:59 / at 10:00:00 + if (($i + 60) > $now) { + // Display vote buttons for now + 1 additional minute + $keys_time[] = array( + 'text' => unix2tz($i, $raid['timezone']), + 'callback_data' => $raid['id'] . ':vote_time:' . $i + ); + } + + // This is our last run of the for loop since $i + timePerSlot are ahead of $end_time - $timeBeforeEnd + // Offer a last raid, which is x minutes before the raid ends, x = $timeBeforeEnd + if (($i + $timePerSlot) > ($end_time - $timeBeforeEnd)) { + // Set the time for the last possible raid and add vote key if there is enough time left + $timeLastRaid = $end_time - $timeBeforeEnd; + if($timeLastRaid > $i + $timeBeforeEnd && ($timeLastRaid >= $now)){ + // Round last raid time to 5 minutes to avoid crooked voting times + $near5 = 5*60; + $timeLastRaid = round($timeLastRaid / $near5) * $near5; + $keys_time[] = array( + 'text' => unix2tz($timeLastRaid, $raid['timezone']), + 'callback_data' => $raid['id'] . ':vote_time:' . $timeLastRaid + ); } - } - if (count($data['done'])) { - $msg .= CR.' Done: '.count($data['done']).''.CR; - } + } + } + + $keys[] = $keys_time; + + // Init keys pokemon array. + $keys_poke = []; + + // Get current pokemon + $raid_pokemon = $raid['pokemon']; + + // Init raid level and level found + $raid_level = 0; + $level_found = false; + + // Ignore level X raid bosses + $ignore_X = []; + $X_list = $GLOBALS['pokemon']['X']; + foreach($X_list as $pokemon) { + $ignore_X[] = strtolower($pokemon); + debug_log('Adding pokemon to keys ignore list: ' . $pokemon); + } + + // Iterate thru the pokemon list to get raid level + $pokemonlist = $GLOBALS['pokemon']; + foreach($pokemonlist as $level => $levelmons) { + if($level == "X") continue; + //debug_log("Searching raid boss '" . $raid_pokemon . "' in level " . $level . " raids"); + // Compare pokemon by pokemon to get raid level + foreach($levelmons as $key => $pokemon) { + if(strtolower($raid_pokemon) == strtolower($pokemon)) { + // Stop if pokemon is in level X too. + if(in_array(strtolower($raid_pokemon), $ignore_X)) { + break 2; + } else { + $level_found = true; + $raid_level = $level; + //debug_log("Found raid boss '" . $pokemon . "' in level " . $level . " raids"); + break 2; + } + } + } + } + + // 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']} + AND attend_time IS NOT NULL + AND raid_done != 1 + AND cancel != 1 + " + ); + + $row = $rs->fetch_assoc(); + + // Count participants and participants by pokemon + $count_pp = $row['count']; + $count_any_pokemon = $row['count_any_pokemon']; + $count_raid_pokemon = $row['count_raid_pokemon']; - $msg .= CR.'Updated: '.unix2tz(time(), $raid['timezone'], 'H:i:s').' ID = '.$raid['id']; + // 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); - return $msg; + // Hide keys for specific cases + $show_keys = true; + // Make sure raid boss is not an egg + if (strtolower($raid_pokemon) != strtolower(getTranslation('egg_' . $level))) { + // Make sure we either have no participants + // OR all participants voted for "any" raid boss + // OR all participants voted for the hatched raid boss + // OR all participants voted for "any" or the hatched raid boss + if($count_pp == 0 || $count_pp == $count_any_pokemon || $count_pp == $count_raid_pokemon || $count_pp == ($count_any_pokemon + $count_raid_pokemon)) { + $show_keys = false; + } + } + + // Add pokemon keys if we found the raid boss + if ($level_found && $show_keys) { + // Init counter. + $count = 0; + + foreach($pokemonlist as $level => $levelmons) { + if($level == $raid_level) { + foreach($levelmons as $key => $pokemon) { + // Ignore raid eggs and level X pokemon + if(strtolower($pokemon) == strtolower(getTranslation('egg_' . $level))) continue; + if(in_array(strtolower($pokemon), $ignore_X)) continue; + + // Add pokemon to keys + $keys_poke[] = array( + 'text' => $pokemon, + 'callback_data' => $raid['id'] . ':vote_pokemon:' . $pokemon + ); + + // Counter + $count = $count + 1; + } + } + } + + // Add pokemon keys if we have two or more pokemon + if($count >= 2) { + // Add button if raid boss does not matter + $keys_poke[] = array( + 'text' => getTranslation('any'), + 'callback_data' => $raid['id'] . ':vote_pokemon:0' + ); + + // Finally add pokemon to keys + $keys_poke = inline_key_array($keys_poke, 3); + $keys = array_merge($keys, $keys_poke); + } + } + } + + $keys[] = [ + [ + 'text' => EMOJI_REFRESH, + 'callback_data' => $raid['id'] . ':vote_refresh:0' + ], + [ + 'text' => getTranslation('here'), + 'callback_data' => $raid['id'] . ':vote_arrived:0' + ], + [ + 'text' => getTranslation('done'), + 'callback_data' => $raid['id'] . ':vote_done:0' + ], + [ + 'text' => getTranslation('cancellation'), + 'callback_data' => $raid['id'] . ':vote_cancel:0' + ], + ]; + + if ($end_time < $now) { + $keys = [ + [ + [ + 'text' => getTranslation('raid_done'), + 'callback_data' => $raid['id'] . ':vote_refresh:0' + ] + ] + ]; + } + return $keys; } -function show_raid_poll_small($raid) { - $time_left = floor($raid['t_left']/60); - $time_left = floor($time_left/60).':'.str_pad($time_left%60,2,'0',STR_PAD_LEFT).' left'; +/** + * Update user. + * @param $update + * @return bool|mysqli_result + */ +function update_user($update) +{ + global $db; - $msg = ''.ucfirst($raid['pokemon']).' '.$time_left.' '.$raid['gym_name'].''.CR; - if ($raid['address']) { - $addr = explode(',',$raid['address'],4); - array_pop($addr); - $addr = implode(',',$addr); - $msg .= ''.$addr.''.CR2; - } - - $query = 'SELECT team, COUNT(*) AS cnt, SUM(extra_people) AS extra FROM attendance WHERE raid_id='.$raid['id'].' AND (cancel=0 OR cancel IS NULL) AND (raid_done=0 OR raid_done IS NULL) GROUP BY team'; - $rs = my_query($query); - $data = array(); - - $total = 0; - $sep = ''; - while ($row = $rs->fetch_assoc()) { - $sum = $row['cnt']+$row['extra']; - if ($sum==0) continue; - $msg .= $sep.$GLOBALS['teams'][$row['team']].' '.$sum; - $sep = ' | '; - $total += $sum; - } - if (!$total) { - $msg .= ' No participants'.CR; - } else { - $msg .= ' = '.$total.''.CR; + $name = ''; + $nick = ''; + $sep = ''; + + if (isset($update['message'])) { + $msg = $update['message']['from']; + } + + if (isset($update['callback_query'])) { + $msg = $update['callback_query']['from']; + } + + if (isset($update['inline_query'])) { + $msg = $update['inline_query']['from']; + } + + if (!empty($msg['id'])) { + $id = $msg['id']; + + } else { + debug_log('No id', '!'); + debug_log($update, '!'); + return false; + } + + if ($msg['first_name']) { + $name = $msg['first_name']; + $sep = ' '; + } + + if (isset($msg['last_name'])) { + $name .= $sep . $msg['last_name']; + } + + if (isset($msg['username'])) { + $nick = $msg['username']; + } + + // Create or update the user. + $request = my_query( + " + INSERT INTO users + SET user_id = {$id}, + nick = '{$db->real_escape_string($nick)}', + name = '{$db->real_escape_string($name)}' + ON DUPLICATE KEY + UPDATE nick = '{$db->real_escape_string($nick)}', + name = '{$db->real_escape_string($name)}' + " + ); + + return $request; +} + +/** + * Send response vote. + * @param $update + * @param $data + * @param bool $new + */ +function send_response_vote($update, $data, $new = false) +{ + // Get the raid data by id. + $rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = {$data['id']} + " + ); + + // Get the row. + $raid = $rs->fetch_assoc(); + + $msg = show_raid_poll($raid); + $keys = keys_vote($raid); + + // Write to log. + debug_log($keys); + + if ($new) { + $loc = send_location($update['callback_query']['message']['chat']['id'], $raid['lat'], $raid['lon']); + + // Write to log. + debug_log('location:'); + debug_log($loc); + + // Send the message. + send_message($update['callback_query']['message']['chat']['id'], $msg . "\n", $keys, ['reply_to_message_id' => $loc['result']['message_id']]); + // Answer the callback. + answerCallbackQuery($update['callback_query']['id'], $msg); + + } else { + // Edit the message. + edit_message($update, $msg, $keys, ['disable_web_page_preview' => 'true']); + // Change message string. + $msg = getTranslation('vote_updated'); + // Answer the callback. + answerCallbackQuery($update['callback_query']['id'], $msg); + } + + exit; +} + +/** + * Insert overview. + * @param $chat_id + * @param $message_id + */ +function insert_overview($chat_id, $message_id) +{ + global $db; + + // Build query to check if overview details are already in database or not + $rs = my_query( + " + SELECT COUNT(*) + FROM overview + WHERE chat_id = '{$chat_id}' + " + ); + + $row = $rs->fetch_row(); + + // Overview already in database or new + if (empty($row['0'])) { + // 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}' + " + ); + } else { + // Nothing to do - overview information is already in database. + debug_log('Overview information is already in database! Nothing to do...'); + } +} + +/** + * Delete overview. + * @param $chat_id + * @param $message_id + */ +function delete_overview($chat_id, $message_id) +{ + global $db; + + // 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}' + " + ); +} + +/** + * Get overview data to Share or refresh. + * @param $update + * @param $chats_active + * @param $raids_active + * @param $action - refresh or share + * @param $chat_id + */ +function get_overview($update, $chats_active, $raids_active, $action = 'refresh', $chat_id = 0) +{ + // Add pseudo array for last run to active chats array + $last_run = array(); + $last_run[chat_id] = 'LAST_RUN'; + $chats_active[] = $last_run; + + // Init previous chat_id + $previous = 'FIRST_RUN'; + + // Any active raids currently? + if (empty($raids_active)) { + // Init keys. + $keys = array(); + $keys = []; + + // Refresh active overview messages with 'no_active_raids_currently' or send 'no_active_raids_found' message to user. + $rs = my_query( + " + SELECT * + FROM overview + " + ); + + // Refresh active overview messages. + while ($row_overview = $rs->fetch_assoc()) { + $chat_id = $row_overview['chat_id']; + $message_id = $row_overview['message_id']; + + // Get info about chat for title. + debug_log('Getting chat object for chat_id: ' . $row_overview['chat_id']); + $chat_obj = get_chat($row_overview['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']); + } + + // Set the message. + $msg = '' . getTranslation('raid_overview_for_chat') . ' ' . $chat_title . ':' . CR . CR; + $msg .= getTranslation('no_active_raids'); + $msg .= CR . CR . '' . getTranslation('updated') . ': ' . unix2tz(time(), TIMEZONE, 'H:i:s') . ''; + + // Edit the message, but disable the web preview! + debug_log('Updating overview:' . CR . 'Chat_ID: ' . $chat_id . CR . 'Message_ID: ' . $message_id); + editMessageText($message_id, $msg, $keys, $chat_id); + } + + // Triggered from user or cronjob? + if (!empty($update['callback_query']['id'])) { + // Send no active raids message to the user. + $msg = getTranslation('no_active_raids'); + + // Edit the message, but disable the web preview! + edit_message($update, $msg, $keys); + + // Answer the callback. + answerCallbackQuery($update['callback_query']['id'], $msg); + } + + // Exit here. + exit; + } + + // Share or refresh each chat. + foreach ($chats_active as $row) { + $current = $row['chat_id']; + + // Are any raids shared? + if ($previous == "FIRST_RUN" && $current == "LAST_RUN") { + // Send no active raids message to the user. + $msg = getTranslation('no_active_raids_shared'); + + // Edit the message, but disable the web preview! + edit_message($update, $msg, $keys); + + // Answer the callback. + answerCallbackQuery($update['callback_query']['id'], $msg); + } + + // Send message if not first run and previous not current + if ($previous !== 'FIRST_RUN' && $previous !== $current) { + // Add keys. + $keys = array(); + + // Add update timestamp to msg. + $msg .= '' . getTranslation('updated') . ': ' . unix2tz(time(), $tz, 'H:i:s') . ''; + + // Share or refresh? + if ($action == 'share') { + if ($chat_id == 0) { + // Make sure it's not already shared + $rs = my_query( + " + SELECT COUNT(*) + FROM overview + WHERE chat_id = '{$previous}' + " + ); + + $row = $rs->fetch_row(); + + if (empty($row['0'])) { + // Not shared yet - Share button + $keys[] = [ + [ + 'text' => getTranslation('share_with') . ' ' . $chat_obj['result']['title'], + 'callback_data' => '0:overview_share:' . $previous + ] + ]; + } else { + // Already shared - refresh button + $keys[] = [ + [ + 'text' => EMOJI_REFRESH, + 'callback_data' => '0:overview_refresh:' . $previous + ] + ]; + } + + // Send the message, but disable the web preview! + send_message($update['callback_query']['message']['chat']['id'], $msg, $keys, ['disable_web_page_preview' => 'true']); + + // Set the callback message and keys + $callback_keys = array(); + $callback_keys = []; + $callback_msg = '' . getTranslation('list_all_overviews') . ':'; + + // Edit the message. + edit_message($update, $callback_msg, $callback_keys); + + // Answer the callback. + answerCallbackQuery($update['callback_query']['id'], 'OK'); + } else { + // Shared overview + $keys = []; + + // Set callback message string. + $msg_callback = getTranslation('successfully_shared'); + + // Edit the message, but disable the web preview! + edit_message($update, $msg_callback, $keys, ['disable_web_page_preview' => 'true']); + + // Answer the callback. + answerCallbackQuery($update['callback_query']['id'], $msg_callback); + + // Send the message, but disable the web preview! + send_message($chat_id, $msg, $keys, ['disable_web_page_preview' => 'true']); + } + } else { + // Refresh overview messages. + $keys = []; + + // Get active overviews + $rs = my_query( + " + SELECT message_id + FROM overview + WHERE chat_id = '{$previous}' + " + ); + + // Edit text for all messages, but disable the web preview! + while ($row_msg_id = $rs->fetch_assoc()) { + // Set message_id. + $message_id = $row_msg_id['message_id']; + debug_log('Updating overview:' . CR . 'Chat_ID: ' . $previous . CR . 'Message_ID: ' . $message_id); + editMessageText($message_id, $msg, $keys, $previous, ['disable_web_page_preview' => 'true']); + } + + // Triggered from user or cronjob? + if (!empty($update['callback_query']['id'])) { + // Answer the callback. + answerCallbackQuery($update['callback_query']['id'], 'OK'); + } + } + } + + // End if last run + if ($current == 'LAST_RUN') { + break; + } + + // Create message for each raid_id + if($previous !== $current) { + // Get info about chat for username. + debug_log('Getting chat object for chat_id: ' . $row['chat_id']); + $chat_obj = get_chat($row['chat_id']); + $chat_username = ''; + + // Set username if available. + if ($chat_obj['ok'] == 'true' && isset($chat_obj['result']['username'])) { + $chat_username = $chat_obj['result']['username']; + debug_log('Username of the chat: ' . $chat_obj['result']['username']); + } + + $msg = '' . getTranslation('raid_overview_for_chat') . ' ' . $chat_obj['result']['title'] . ':' . CR . CR; + } + + // Set variables for easier message building. + $raid_id = $row['raid_id']; + $pokemon = $raids_active[$raid_id]['pokemon']; + $gym = $raids_active[$raid_id]['gym_name']; + $now = $raids_active[$raid_id]['ts_now']; + $tz = $raids_active[$raid_id]['timezone']; + $start_time = $raids_active[$raid_id]['ts_start']; + $time_left = floor($raids_active[$raid_id]['t_left'] / 60); + + // 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 opens up 18:41h + */ + // Gym name. + $msg .= !empty($chat_username) ? '' . htmlspecialchars($gym) . '' : $gym; + $msg .= CR; + + // Raid has not started yet - adjust time left message + if ($now < $start_time) { + $weekday_now = date('N', $now); + $weekday_start = date('N', $start_time); + $raid_day = weekday_number2name ($weekday_start); + if ($weekday_now == $weekday_start) { + $msg .= getTranslation('raid_egg_opens') . ' ' . unix2tz($start_time, $tz) . CR; + } else { + $msg .= getTranslation('raid_egg_opens_day') . ' ' . $raid_day . ' ' . getTranslation('raid_egg_opens_at') . ' ' . unix2tz($start_time, $tz) . CR; + } + + // Raid has started already + } else { + // Add time left message. + $msg .= $pokemon . ' — ' . getTranslation('still') . ' ' . floor($time_left / 60) . ':' . str_pad($time_left % 60, 2, '0', STR_PAD_LEFT) . 'h' . CR; + } + + // Count attendances + $rs_att = my_query( + " + SELECT count(attend_time) AS count, + sum(team = 'mystic') AS count_mystic, + sum(team = 'valor') AS count_valor, + sum(team = 'instinct') AS count_instinct, + sum(team IS NULL) AS count_no_team, + sum(extra_people) AS extra + FROM attendance + WHERE raid_id = {$raid_id} + AND attend_time IS NOT NULL + AND raid_done != 1 + AND cancel != 1 + " + ); + + $att = $rs_att->fetch_assoc(); + + // Add to message. + if ($att['count'] > 0) { + $msg .= EMOJI_GROUP . ' ' . ($att['count'] + $att['extra']) . ' — '; + $msg .= (($att['count_mystic'] > 0) ? TEAM_B . $att['count_mystic'] . ' ' : ''); + $msg .= (($att['count_valor'] > 0) ? TEAM_R . $att['count_valor'] . ' ' : ''); + $msg .= (($att['count_instinct'] > 0) ? TEAM_Y . $att['count_instinct'] . ' ' : ''); + $msg .= ((($att['count_no_team'] + $att['extra']) > 0) ? TEAM_UNKNOWN . ($att['count_no_team'] + $att['extra']) : ''); + $msg .= CR; + } + + // Add CR to message now since we don't know if attendances got added or not + $msg .= CR; + + // Prepare next iteration + $previous = $current; + } +} +/** + * Convert unix timestamp to time string by timezone settings. + * @param $unix + * @param $tz + * @param string $format + * @return bool|string + */ +function unix2tz($unix, $tz, $format = 'H:i') +{ + // Unix timestamp is required. + if (!empty($unix)) { + // Create dateTime object. + $dt = new DateTime('@' . $unix); + + // Set the timezone. + $dt->setTimeZone(new DateTimeZone($tz)); + + // Return formatted time. + return $dt->format($format); + + } else { + return false; + } +} + +/** + * Weekday number to weekday name + * @param weekdaynumber + */ +function weekday_number2name ($weekdaynumber) +{ + // Numeric value below 7 is required + if(is_numeric($weekdaynumber) && $weekdaynumber <= 7) { + switch($weekdaynumber) { + case 1: + $weekday = getTranslation('monday'); + break; + case 2: + $weekday = getTranslation('tuesday'); + break; + case 3: + $weekday = getTranslation('wednesday'); + break; + case 4: + $weekday = getTranslation('thursday'); + break; + case 5: + $weekday = getTranslation('friday'); + break; + case 6: + $weekday = getTranslation('saturday'); + break; + case 7: + $weekday = getTranslation('sunday'); + break; } + } + // Return the weekday + return $weekday; +} + +/** + * Delete raid. + * @param $raid_id + */ +function delete_raid($raid_id) +{ + global $db; + + // Delete telegram messages for raid. + $rs = my_query( + " + SELECT * + FROM cleanup + WHERE raid_id = '{$raid_id}' + AND chat_id <> 0 + " + ); + + // Counter + $counter = 0; - return $msg; + // Delete every telegram message + while ($row = $rs->fetch_assoc()) { + // 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}' + OR cleaned = '{$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}' + " + ); } -function raid_list($update) { - /* INLINE - LIST POLLS */ - - if ($update['inline_query']['query']) { - /* By ID */ - $request = my_query('SELECT *, - UNIX_TIMESTAMP(end_time) AS ts_end, - UNIX_TIMESTAMP(NOW()) as ts_now, - UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left - FROM raids WHERE id='.intval($update['inline_query']['query'])); - $rows = array(); - while($answer = $request->fetch_assoc()) { - $rows[] = $answer; - } - debug_log($rows); - answer_inline_query($update['inline_query']['id'], $rows); +/** + * Show raid poll. + * @param $raid + * @return string + */ +function show_raid_poll($raid) +{ + // Init empty message string. + $msg = ''; + + // Display gym details. + if ($raid['gym_name'] || $raid['gym_team']) { + // Add gym name to message. + if ($raid['gym_name']) { + $msg .= getTranslation('gym') . ': ' . $raid['gym_name'] . ''; + } + // Add team to message. + if ($raid['gym_team']) { + + // FB: Korrekt Team Color + $team = ''; + if ($raid['gym_team'] == 'valor') + $team = TEAM_R; + else if ($raid['gym_team'] == 'instinct') + $team = TEAM_Y; + else if ($raid['gym_team'] == 'mystic') + $team = TEAM_B; + $msg .= ' ' . $team; + } + + $msg .= CR; + } + + // Add google maps link to message. + if (!empty($raid['address'])) { + $msg .= '' . $raid['address'] . '' . CR; + } else { + $msg .= 'http://maps.google.com/maps?q=' . $raid['lat'] . ',' . $raid['lon'] . '' . CR; + } + + // Display raid boss name. + $msg .= getTranslation('raid_boss') . ': ' . ucfirst($raid['pokemon']) . '' . CR; + + $time_left = floor($raid['t_left'] / 60); + if ( strpos(str_pad($time_left % 60, 2, '0', STR_PAD_LEFT) , '-' ) !== false ) { + // $time_left = 'beendet'; <-- REPLACED BY $tl_msg, so if clause below is still working ($time_left < 0) + $tl_msg = '' . getTranslation('raid_done') . ''; + } else { + // Replace $time_left with $tl_msg too + $tl_msg = ' — ' . getTranslation('still') . ' ' . floor($time_left / 60) . ':' . str_pad($time_left % 60, 2, '0', STR_PAD_LEFT) . 'h'; + } + + // Raid has not started yet - adjust time left message + if ($raid['ts_now'] < $raid['ts_start']) { + $weekday_now = date('N', $raid['ts_now']); + $weekday_start = date('N', $raid['ts_start']); + $raid_day = weekday_number2name ($weekday_start); + if ($weekday_now == $weekday_start) { + $msg .= '' . getTranslation('raid_egg_opens') . ' ' . unix2tz($raid['ts_start'], $raid['timezone']) . '' . CR; } else { - /* By user */ - $request = my_query('SELECT *, - UNIX_TIMESTAMP(end_time) AS ts_end, - UNIX_TIMESTAMP(NOW()) as ts_now, - UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left - FROM raids WHERE user_id = '.$update['inline_query']['from']['id'].' ORDER BY id DESC LIMIT 3;'); - $rows = array(); - while($answer = $request->fetch_assoc()) { - $rows[] = $answer; - } - - debug_log($rows); - answer_inline_query($update['inline_query']['id'], $rows); + $msg .= '' . getTranslation('raid_egg_opens_day') . ' ' . $raid_day . ' ' . getTranslation('raid_egg_opens_at') . ' ' . unix2tz($raid['ts_start'], $raid['timezone']) . '' . CR; + } + + // Raid has started and active or already ended + } else { + + // Add raid is done message. + // FIXED - $time_left got changed to text above, so added $tl_msg + if ($time_left < 0) { + $msg .= $tl_msg . CR2; + + // Add time left message. + } else { + $msg .= getTranslation('raid_until') . ' ' . unix2tz($raid['ts_end'], $raid['timezone']); + $msg .= $tl_msg . CR; + } + } + + // Get attendance for this raid. + $rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(attend_time) AS ts_att + FROM attendance + WHERE raid_id = {$raid['id']} + ORDER BY cancel ASC, + raid_done DESC, + team ASC, + arrived DESC, + attend_time ASC + " + ); + + // Init empty data array. + $data = array(); + + // For each attendance. + while ($row = $rs->fetch_assoc()) { + // Set cancel text. + if ($row['cancel']) { + $row['team'] = 'cancel'; + } + // Set done text. + if ($row['raid_done']) { + $row['team'] = 'done'; + } + if (!$row['team']) { + $row['team'] = 'unknown'; + } + + $data[$row['team']][] = $row; + + if ($row['extra_people']) { + for ($i = 1; $i <= $row['extra_people']; $i++) { + $data[$row['team']][] = false; + } + } + } + + debug_log($data); + + // Add Ex-Raid Message if Pokemon is in Ex-Raid-List. + $pokemonlist = $GLOBALS['pokemon']; + foreach($pokemonlist as $level => $levelmons) { + if($level == "X") { + foreach($levelmons as $key => $pokemon) { + if(strtolower($pokemon) == strtolower($raid['pokemon'])) { + $msg.= CR . EMOJI_WARN . ' ' . getTranslation('exraid_pass') . ' ' . EMOJI_WARN; + break 2; + } + } + } + } + + // Add no attendance found message. + if (count($data) == 0) { + $msg .= CR . getTranslation('no_participants_yet') . CR; + } + + $rs = my_query( + " + SELECT DISTINCT UNIX_TIMESTAMP(attend_time) AS ts_att, + count(attend_time) AS count, + sum(team = 'mystic') AS count_mystic, + sum(team = 'valor') AS count_valor, + sum(team = 'instinct') AS count_instinct, + sum(team IS NULL) AS count_no_team, + sum(extra_people) AS extra, + sum(pokemon = '0') AS count_any_pokemon, + sum(pokemon = '{$raid['pokemon']}') AS count_raid_pokemon, + attend_time + FROM attendance + WHERE raid_id = {$raid['id']} + AND attend_time IS NOT NULL + AND raid_done != 1 + AND cancel != 1 + GROUP BY attend_time + ORDER BY attend_time ASC + " + ); + + // Init empty time slots array. + $timeSlots = array(); + + while ($row = $rs->fetch_assoc()) { + $timeSlots[] = $row; + } + + // Write to log. + debug_log($timeSlots); + + // TIMES + foreach ($timeSlots as $ts) { + // Add to message. + $msg .= CR . '' . unix2tz($ts['ts_att'], $raid['timezone']) . '' . ' [' . ($ts['count'] + $ts['extra']) . ']'; + if ($ts['count'] > 0) { + $msg .= ' — '; + $msg .= (($ts['count_mystic'] > 0) ? TEAM_B . $ts['count_mystic'] . ' ' : ''); + $msg .= (($ts['count_valor'] > 0) ? TEAM_R . $ts['count_valor'] . ' ' : ''); + $msg .= (($ts['count_instinct'] > 0) ? TEAM_Y . $ts['count_instinct'] . ' ' : ''); + $msg .= ((($ts['count_no_team'] + $ts['extra']) > 0) ? TEAM_UNKNOWN . ($ts['count_no_team'] + $ts['extra']) : ''); + $msg .= CR; } + + // Get pokemon + $poke_rs = my_query( + " + SELECT * + FROM attendance + WHERE raid_id = {$raid['id']} + GROUP BY pokemon + " + ); + + // Init empty pokemon array. + $voted_poke = array(); + + // Count pokemons which users voted for. + while ($rowPoke = $poke_rs->fetch_assoc()) { + $voted_poke[] = $rowPoke; + } + + // Get users for each pokemon. + foreach ($voted_poke as $pp) { + // Get users. + $user_rs = my_query( + " + SELECT * + FROM attendance + WHERE UNIX_TIMESTAMP(attend_time) = {$ts['ts_att']} + AND raid_done != 1 + AND cancel != 1 + AND raid_id = {$raid['id']} + AND pokemon = '{$pp['pokemon']}' + ORDER BY team ASC, arrived ASC + " + ); + + // Init empty attend users array. + $att_users = array(); + + while ($rowUsers = $user_rs->fetch_assoc()) { + $att_users[] = $rowUsers; + } + + // Get participants for voted time and pokemon. + $participants_rs = my_query( + " + SELECT count(attend_time) AS count, + sum(team = 'mystic') AS count_mystic, + sum(team = 'valor') AS count_valor, + sum(team = 'instinct') AS count_instinct, + sum(team IS NULL) AS count_no_team, + sum(extra_people) AS extra, + attend_time + FROM attendance + WHERE UNIX_TIMESTAMP(attend_time) = {$ts['ts_att']} + AND raid_done != 1 + AND cancel != 1 + AND raid_id = {$raid['id']} + AND pokemon = '{$pp['pokemon']}' + " + ); + + $row_pp = $participants_rs->fetch_assoc(); + + if($row_pp['count'] == 0) { + // No users voted for this pokemon, continue + continue; + } else { + // Count all attendances, attendances for "any" pokemon and attendances for the raid boss + $count_pp = $ts['count']; + $count_any_pokemon = $ts['count_any_pokemon']; + $count_raid_pokemon = $ts['count_raid_pokemon']; + + // Write to log. + debug_log('Summary for timeslot: ' . unix2tz($ts['ts_att'], $raid['timezone'])); + 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); + + // Show attendances when multiple pokemon are selected, unless all attending users voted for the raid boss + any pokemon + if($count_pp != ($count_any_pokemon + $count_raid_pokemon)) { + // Add participants message. + $msg .= $pp['pokemon'] == '0' ? '' . getTranslation('any_pokemon') . '' : '' . $pp['pokemon'] . ''; + $msg .= ' [' . ($row_pp['count'] + $row_pp['extra']) . '] — '; + $msg .= (($row_pp['count_mystic'] > 0) ? TEAM_B . $row_pp['count_mystic'] . ' ' : ''); + $msg .= (($row_pp['count_valor'] > 0) ? TEAM_R . $row_pp['count_valor'] . ' ' : ''); + $msg .= (($row_pp['count_instinct'] > 0) ? TEAM_Y . $row_pp['count_instinct'] . ' ' : ''); + $msg .= ((($row_pp['count_no_team'] + $row_pp['extra']) > 0) ? TEAM_UNKNOWN . ($row_pp['count_no_team'] + $row_pp['extra']) : ''); + $msg .= CR; + } + } + + // Write to log. + debug_log($att_users); + + foreach ($att_users as $vv) { + + // Write to log. + debug_log($vv['user_id']); + + // Get user data. + $rs = my_query( + " + SELECT * + FROM users + WHERE user_id = {$vv['user_id']} + " + ); + + // Get the row. + $row = $rs->fetch_assoc(); + + // Always use name. + $name = '' . htmlspecialchars($row['name']) . ''; + + // Unknown team. + if ($row['team'] === NULL) { + $msg .= ' └ ' . $GLOBALS['teams']['unknown'] . ' '; + + // Known team. + } else { + $msg .= ' └ ' . $GLOBALS['teams'][$row['team']] . ' '; + } + + // Add level. + if ($row['level'] != 0) { + $msg .= ''.$row['level'].''; + $msg .= ' '; + } + + // Add name. + $msg .= $name; + $msg .= ' '; + + // Arrived. + if ($vv['arrived']) { + // No time is displayed, but undefined_index error in log, so changed it: + //$msg .= '[Bin da' . unix2tz($vv['ts_att'], $raid['timezone']) . '] '; + $msg .= '[' . getTranslation('here') . '] '; + + // Cancelled. + } else if ($vv['cancel']) { + $msg .= '[' . getTranslation('cancel') . '] '; + } + + // Add extra people. + if ($vv['extra_people']) { + $msg .= '+' . $vv['extra_people']; + } + + $msg .= CR; + } + } + } + + // DONE + if (isset($data['done']) ? count($data['done']) : '' ) { + //if (count($data['done'])) { + // Add to message. + $msg .= CR . TEAM_DONE . ' ' . getTranslation('finished') . ': ' . ' [' . count($data['done']) . ']' . CR; + + foreach ($data['done'] as $vv) { + + if (!$vv['raid_done']) continue; + + $rs = my_query( + " + SELECT * + FROM users + WHERE user_id = {$vv['user_id']} + " + ); + + $row = $rs->fetch_assoc(); + + $name = '' . htmlspecialchars($row['name']) . ''; + + // Add to message. + $msg .= ' └ ' . $GLOBALS['teams'][$row['team']] . ' ' . $name . ' '; + + // Done. + if ($vv['raid_done']) { + $msg .= '[' . unix2tz($vv['ts_att'], $raid['timezone']) . '] '; + } + // Add extra people. + if ($vv['extra_people']) { + $msg .= '+' . $vv['extra_people']; + } + + $msg .= CR; + } + } + + // CANCEL + if (isset($data['cancel']) ? count($data['cancel']) : '' ) { + //if (count($data['cancel'])) { + // Add to message. + $msg .= CR . TEAM_CANCEL . ' ' . getTranslation('cancel') . ': ' . ' [' . count($data['cancel']) . ']' . CR; + + foreach ($data['cancel'] as $vv) { + + if (!$vv['cancel']) continue; + + $rs = my_query( + " + SELECT * + FROM users + WHERE user_id = {$vv['user_id']} + " + ); + + $row = $rs->fetch_assoc(); + + $name = '' . htmlspecialchars($row['name']) . ''; + + $msg .= ' └ ' . $GLOBALS['teams'][$row['team']] . ' ' . $name . ' '; + + // Cancel. + if ($vv['cancel']) { + $msg .= '[' . unix2tz($vv['ts_att'], $raid['timezone']) . '] '; + } + // Add extra people. + if ($vv['extra_people']) { + $msg .= '+' . $vv['extra_people']; + } + + $msg .= CR; + } + } + + // Display user which created the raid. + // Get user data. + $rs = my_query( + " + SELECT * + FROM users + WHERE user_id = {$raid['user_id']} + " + ); + + // Get the row. + $row = $rs->fetch_assoc(); + + // Display creator. + if ($row['user_id'] && $row['name']) { + $msg .= CR . getTranslation('created_by') . ': ' . htmlspecialchars($row['name']) . ''; + } + + // Add update time and raid id to message. + $msg .= CR . '' . getTranslation('updated') . ': ' . unix2tz(time(), $raid['timezone'], 'H:i:s') . ''; + $msg .= ' ID = ' . $raid['id']; // DO NOT REMOVE! --> NEEDED FOR CLEANUP PREPARATION! + + // Return the message. + return $msg; } + +/** + * Show small raid poll. + * @param $raid + * @return string + */ +function show_raid_poll_small($raid) +{ + // Left for possible future redesign of small raid poll + //$time_left = floor($raid['t_left'] / 60); + //$time_left = 'noch ' . floor($time_left / 60) . ':' . str_pad($time_left % 60, 2, '0', STR_PAD_LEFT); + + // Build message string. + $msg = ''; + // Pokemon + if(!empty($raid['pokemon'])) { + $msg .= '' . ucfirst($raid['pokemon']) . ' '; + } + // Start time and end time + if(!empty($raid['ts_start']) && !empty($raid['ts_end'])) { + $msg .= '' . getTranslation('from') . ' ' . unix2tz($raid['ts_start'], $raid['timezone']) . ' ' . getTranslation('to') . ' ' . unix2tz($raid['ts_end'], $raid['timezone']) . '' . CR; + } + // Gym Name + if(!empty($raid['gym_name'])) { + $msg .= $raid['gym_name'] . CR; + } + + // Address found. + if (!empty($raid['address'])) { + $msg .= '' . $raid['address'] . '' . CR2; + } + + // Count attendances + $rs = my_query( + " + SELECT count(attend_time) AS count, + sum(team = 'mystic') AS count_mystic, + sum(team = 'valor') AS count_valor, + sum(team = 'instinct') AS count_instinct, + sum(team IS NULL) AS count_no_team, + sum(extra_people) AS extra + FROM attendance + WHERE raid_id = {$raid['id']} + AND attend_time IS NOT NULL + AND raid_done != 1 + AND cancel != 1 + " + ); + + $row = $rs->fetch_assoc(); + + // Add to message. + if ($row['count'] > 0) { + $msg .= EMOJI_GROUP . ' ' . ($row['count'] + $row['extra']) . ' — '; + $msg .= (($row['count_mystic'] > 0) ? TEAM_B . $row['count_mystic'] . ' ' : ''); + $msg .= (($row['count_valor'] > 0) ? TEAM_R . $row['count_valor'] . ' ' : ''); + $msg .= (($row['count_instinct'] > 0) ? TEAM_Y . $row['count_instinct'] . ' ' : ''); + $msg .= ((($row['count_no_team'] + $row['extra']) > 0) ? TEAM_UNKNOWN . ($row['count_no_team'] + $row['extra']) : ''); + $msg .= CR; + } else { + $msg .= getTranslation('no_participants') . CR; + } + + return $msg; +} + +/** + * Raid list. + * @param $update + */ +function raid_list($update) +{ + // Init empty rows array. + $rows = array(); + + // Inline list polls. + if ($update['inline_query']['query']) { + + $iqq = intval($update['inline_query']['query']); + + // By ID. + $request = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = {$iqq} + " + ); + + } else { + // By user. + $request = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE user_id = {$update['inline_query']['from']['id']} + ORDER BY id DESC LIMIT 3 + " + ); + } + + while ($answer = $request->fetch_assoc()) { + $rows[] = $answer; + } + + debug_log($rows); + answerInlineQuery($update['inline_query']['id'], $rows); +} + diff --git a/modules/edit.php b/modules/edit.php old mode 100644 new mode 100755 index 83b7b79..8ff3094 --- a/modules/edit.php +++ b/modules/edit.php @@ -1,79 +1,43 @@ 'Articuno', 'callback_data' => $id.':edit_poke:articuno', - ],[ - 'text' => 'Lugia', 'callback_data' => $id.':edit_poke:lugia', - ],[ - 'text' => 'Moltres', 'callback_data' => $id.':edit_poke:moltres', - ],[ - 'text' => 'Zapdos', 'callback_data' => $id.':edit_poke:zapdos', - ]]]; - - } else if ($data['arg']=='type_4') { - $keys = - [[[ - 'text' => 'Tyranitar', 'callback_data' => $id.':edit_poke:tyranitar', - ]],[[ - 'text' => 'Snorlax', 'callback_data' => $id.':edit_poke:snorlax', - ],[ - 'text' => 'Lapras', 'callback_data' => $id.':edit_poke:lapras', - ],[ - 'text' => 'Rhydon', 'callback_data' => $id.':edit_poke:rhydon', - ]],[[ - 'text' => 'Charizard', 'callback_data' => $id.':edit_poke:charizard', - ],[ - 'text' => 'Venusaur', 'callback_data' => $id.':edit_poke:venusaur', - ],[ - 'text' => 'Blastoise', 'callback_data' => $id.':edit_poke:blastoise', - ]]]; - } else if ($data['arg']=='type_3') { - $keys = - [[[ - 'text' => 'Machamp', 'callback_data' => $id.':edit_poke:machamp', - ]],[[ - 'text' => 'Vaporeon', 'callback_data' => $id.':edit_poke:vaporeon', - ],[ - 'text' => 'Flareon', 'callback_data' => $id.':edit_poke:flareon', - ],[ - 'text' => 'Jolteon', 'callback_data' => $id.':edit_poke:jolteon', - ]],[[ - 'text' => 'Alakazam', 'callback_data' => $id.':edit_poke:alakazam', - ],[ - 'text' => 'Arcanine', 'callback_data' => $id.':edit_poke:arcanine', - ],[ - 'text' => 'Gengar', 'callback_data' => $id.':edit_poke:gengar', - ]]]; - } else if ($data['arg']=='type_2') { - $keys = - [[[ - 'text' => 'Muk', 'callback_data' => $id.':edit_poke:muk', - ]]]; - } else if ($data['arg']=='type_1') { - $keys = [[[ 'text' => 'Not supported', 'callback_data' => 'edit:not_supported' ]]]; - } else { - /* Edit pokemon */ - $keys = raid_edit_start_keys(); - } +// Set the pokkemon list +$pokemonlist = $GLOBALS['pokemon']; - if (!$keys) $keys = [[[ 'text' => 'Not supported', 'callback_data' => 'edit:not_supported' ]]]; +// Get the keys. +$keys = pokemon_keys($raid_id, $raid_level, $pokemonlist, "edit_poke"); - if (isset($update['callback_query']['inline_message_id'])) { - editMessageText($update['callback_query']['inline_message_id'],'Choose Raid Boss:',$keys); - } else { - editMessageText($update['callback_query']['message']['message_id'],'Choose Raid Boss',$keys,$update['callback_query']['message']['chat']['id'],$keys); - } - - //edit_message_keyboard($update['callback_query']['message']['message_id'],$keys,$update['callback_query']['message']['chat']['id']); - $callback_response = 'Ok'; - answerCallbackQuery($update['callback_query']['id'],$callback_response); +// No keys found. +if (!$keys) { + $keys = [ + [ + [ + 'text' => getTranslation('not_supported'), + 'callback_data' => 'edit:not_supported' + ] + ] + ]; +} +if (isset($update['callback_query']['inline_message_id'])) { + editMessageText($update['callback_query']['inline_message_id'], getTranslation('select_raid_boss') . ':', $keys); +} else { + editMessageText($update['callback_query']['message']['message_id'], getTranslation('select_raid_boss') . ':', $keys, $update['callback_query']['message']['chat']['id'], $keys); +} + +// Build callback message string. +$callback_response = 'Ok'; + +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_response); diff --git a/modules/edit_date.php b/modules/edit_date.php new file mode 100755 index 0000000..2c89aea --- /dev/null +++ b/modules/edit_date.php @@ -0,0 +1,121 @@ +' . getTranslation('bot_access_denied') . ''; + sendMessage($update['callback_query']['from']['id'], $response_msg); + exit; +} + +// Set the id. +$id = $data['id']; + +// Get the argument. +$arg = $data['arg']; + +// Number of days in month +$days_in_month = date('t', strtotime($arg)); + +// Init empty keys array and set keys count. +$keys = array(); +$keys_count = 2; + +// Check amount of "-" in $arg to add day, hour and minute of ex-raid date +// Received: Year-Month / 1970-01 / 1x "-" +if(substr_count($arg, '-') == 1) { + debug_log('Generating buttons for each day in the given year and month: ' . $arg); + + // Formatting stuff. + $month = substr($arg, -2); + $year = substr($arg, 0, 4); + + // Buttons for each day in the given month + for ($i = 1; $i <= $days_in_month; $i = $i + 1) { + // Create the keys. + $keys[] = array( + //'text' => $arg . '-' . str_pad($i, 2, '0', STR_PAD_LEFT), + 'text' => str_pad($i, 2, '0', STR_PAD_LEFT) . ' ' . getTranslation('month_' . $month) . ' ' . $year, + 'callback_data' => $id . ':edit_date:' . $arg . '-' . str_pad($i, 2, '0', STR_PAD_LEFT) + ); + } + + //Set message + $msg = getTranslation('raid_select_date'); +// Received: Year-Month-Day / 1970-01-01 / 2x "-" +} else if (substr_count($arg, '-') == 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($arg, '-') == 3) { + debug_log('Generating buttons for minute of the hour'); + $hour = explode(" ", $arg); + $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($arg, '-') == 4) { + debug_log('Received the following date for the raid: ' . $arg); + debug_log('Formatting the date now properly...'); + // Replace last 2 occurences of "-" with ":" + $start_dt = explode(" ", $arg); + $date = $start_dt[0]; + $time = str_replace('-', ':', $start_dt[1]); + $start_date_time = $date . ' ' . $time; + debug_log('Writing the formatted date to the database now: ' . $start_date_time); + // Build query. + my_query( + " + UPDATE raids + SET start_time = '{$start_date_time}' + WHERE id = {$id} + " + ); + + // Adding button to continue with next step in raid creation + $keys[] = array( + 'text' => getTranslation('next'), + 'callback_data' => $id . ':edit_start:ex-raid' + ); + + // Set message. + $msg = getTranslation('start_date_time') . ':' . CR .'' . $start_date_time . ''; +} + +// Get the inline key array. +$keys = inline_key_array($keys, $keys_count); + +// Edit the message. +edit_message($update, $msg, $keys); + +// Build callback message string. +$callback_response = 'OK'; + +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_response); diff --git a/modules/edit_left.php b/modules/edit_left.php old mode 100644 new mode 100755 index cc88e7e..40b6228 --- a/modules/edit_left.php +++ b/modules/edit_left.php @@ -1,43 +1,113 @@ 'Share','switch_inline_query'=>strval($id), - ]]]; - - $msg = 'Raid saved.'.CR.'Optional - set gym name and team:'.CR2.'/gym gym name'.CR.'/team Mystic/Valor/Instinct/Blue/Red/Yellow'; - edit_message($update, $msg, $keys, false); + // Add delete to keys. + $keys = [ + [ + [ + 'text' => getTranslation('delete'), + 'callback_data' => $id . ':raids_delete:0' + ] + ] + ]; - $callback_response = 'End time set to '.$data['arg'].' minutes'; - answerCallbackQuery($update['callback_query']['id'],$callback_response); + // Add keys to share. + $keys_share = share_keys($id, $userid); + $keys = array_merge($keys, $keys_share); - } else { + // Get raid times. + $rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = {$data['id']} + " + ); - $rs = my_query('SELECT *, - UNIX_TIMESTAMP(end_time) AS ts_end, - UNIX_TIMESTAMP(NOW()) as ts_now, - UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left - FROM raids WHERE id='.$data['id'].''); - $raid = $rs->fetch_assoc(); - - $text = show_raid_poll($raid); - $keys = keys_vote($raid); + // Fetch the row. + $raid = $rs->fetch_assoc(); - edit_message($update, $text, $keys, $false); + // Build message string. + $msg = ''; + $msg .= getTranslation('raid_saved') . CR; + $msg .= show_raid_poll_small($raid) . CR; - $callback_response = 'End time set to '.$data['arg'].' minutes'; - answerCallbackQuery($update['callback_query']['id'],$callback_response); - } + // Gym Name + if(!empty($raid['gym_name'])) { + $msg .= getTranslation('set_gym_team') . CR2; + } else { + $msg .= getTranslation('set_gym_name_and_team') . CR2; + $msg .= getTranslation('set_gym_name_command') . CR; + } + $msg .= getTranslation('set_gym_team_command'); + + // Edit message. + edit_message($update, $msg, $keys, false); + + // Build callback message string. + $callback_response = getTranslation('end_time') . $data['arg'] . ' ' . getTranslation('minutes'); + + // Answer callback. + answerCallbackQuery($update['callback_query']['id'], $callback_response); + +} else { + // Get raid times. + $rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = {$data['id']} + " + ); + + // Fetch the row. + $raid = $rs->fetch_assoc(); + + // Get text and keys. + $text = show_raid_poll($raid); + $keys = keys_vote($raid); + + // Edit message. + edit_message($update, $text, $keys, false); + + // Build callback message string. + $callback_response = 'End time set to ' . $data['arg'] . ' minutes'; + + // Answer callback. + answerCallbackQuery($update['callback_query']['id'], $callback_response); +} diff --git a/modules/edit_poke.php b/modules/edit_poke.php old mode 100644 new mode 100755 index 38df3b8..ad922d0 --- a/modules/edit_poke.php +++ b/modules/edit_poke.php @@ -1,33 +1,176 @@ =25; $i=$i-5) { - $keys[] = array('text' => floor($i/60).':'.str_pad($i%60,2,'0',STR_PAD_LEFT).' left', 'callback_data' => $id.':edit_left:'.$i); - } - $keys = inline_key_array($keys,4); - debug_log($keys); +// Pokemon in level X? +if(in_array(strtolower($arg), $X_pokemons)) { + // Init empty keys array. + $keys = array(); + // Not sure if necessary, leaving as comment + // Timezone - maybe there's a more elegant solution as date_default_timezone_set?! + //$tz = TIMEZONE; + //date_default_timezone_set($tz); + + // Current month + $current_month = date('Y-m', strtotime('now')); + //$current_month_name = date('F', strtotime('now')); + $current_month_name = getTranslation('month_' . substr($current_month, -2)); + $year_of_current_month_name = substr($current_month, 0, 4); + + // Next month + $next_month = date('Y-m', strtotime('first day of +1 months')); + //$next_month_name = date('F', strtotime('first day of +1 months')); + $next_month_name = getTranslation('month_' . substr($next_month, -2)); + $year_of_next_month_name = substr($next_month, 0, 4); + + // Buttons for current and next month + $keys[] = array( + //'text' => $current_month_name . ' (' . $current_month . ')', + 'text' => $current_month_name . ' ' . $year_of_current_month_name, + 'callback_data' => $id . ':edit_date:' . $current_month + ); + + $keys[] = array( + //'text' => $next_month_name . ' (' . $next_month . ')', + 'text' => $next_month_name . ' ' . $year_of_next_month_name, + 'callback_data' => $id . ':edit_date:' . $next_month + ); + // Get the inline key array. + $keys = inline_key_array($keys, 2); + +// Pokemon not in level X? +} else if (true || $arg == "minutes" || $arg == "clocktime") { + if ($arg != "minutes" && $arg != "clocktime") { + // Get default raid duration style from config + if (RAID_DURATION_CLOCK_STYLE == true) { + $arg = "clocktime"; } else { - /* Edit pokemon */ - $keys = raid_edit_start_keys(); + $arg = "minutes"; } + } + + // Init empty keys array. + $keys = array(); + + if ($arg == "minutes") { + // Set switch view. + $switch_text = getTranslation('raid_starts_when_clocktime_view'); + $switch_view = "clocktime"; + $key_count = 5; + + for ($i = 1; $i <= RAID_EGG_DURATION; $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' => floor($i / 60) . ':' . str_pad($i % 60, 2, '0', STR_PAD_LEFT), + 'callback_data' => $id . ':edit_start:' . $i + ); + } + } else { + // Set switch view. + $switch_text = getTranslation('raid_starts_when_minutes_view'); + $switch_view = "minutes"; + // Small screen fix + $key_count = 4; + + // Timezone - maybe there's a more elegant solution as date_default_timezone_set?! + $tz = TIMEZONE; + date_default_timezone_set($tz); + + // Now + $now = time(); + + for ($i = 1; $i <= RAID_EGG_DURATION; $i = $i + 1) { + $now_plus_i = $now + $i*60; + // Create the keys. + $keys[] = array( + // Just show the time, no text - not everyone has a phone or tablet with a large screen... + 'text' => unix2tz($now_plus_i,$tz,"H:i"), + 'callback_data' => $id . ':edit_start:' . $i + ); + } + } + + // Raid already running + $keys[] = array( + 'text' => getTranslation('is_raid_active'), + 'callback_data' => $id . ':edit_start:0' + ); + + // Switch view: clocktime / minutes until start + $keys[] = array( + 'text' => $switch_text, + 'callback_data' => $id . ':edit_poke:' . $switch_view + ); + + // Get the inline key array. + $keys = inline_key_array($keys, $key_count); + + // Write to log. + debug_log($keys); + +} else { + // Edit pokemon. + $keys = raid_edit_start_keys($id); +} + +// No keys found. +if (!$keys) { + // Create the keys. + $keys = [ + [ + [ + 'text' => getTranslation('not_supported'), + 'callback_data' => 'edit:not_supported' + ] + ] + ]; +} + +// Edit the message. +if ($arg == "minutes") { + edit_message($update, getTranslation('raid_starts_when_minutes'), $keys); +} else { + edit_message($update, getTranslation('raid_starts_when'), $keys); +} - if (!$keys) $keys = [[[ 'text' => 'Not supported', 'callback_data' => 'edit:not_supported' ]]]; - - edit_message($update, 'How much time is left for Raid?', $keys); +// Build callback message string. +if ($arg == "minutes" || $arg == "clocktime") { + $callback_response = getTranslation('raid_starts_when_view_changed'); +} else { + $callback_response = getTranslation('pokemon_saved') . $data['arg']; +} - $callback_response = 'Pokemon set to '.$data['arg']; - answerCallbackQuery($update['callback_query']['id'],$callback_response); +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_response); diff --git a/modules/edit_start.php b/modules/edit_start.php new file mode 100755 index 0000000..e979a81 --- /dev/null +++ b/modules/edit_start.php @@ -0,0 +1,90 @@ += 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' => $id . ':edit_left:' . $i + ); + } + } else { + // Use raid pokemon duration short. + $keys[] = array( + 'text' => '0:' . RAID_POKEMON_DURATION_SHORT, + 'callback_data' => $id . ':edit_left:' . RAID_POKEMON_DURATION_SHORT + ); + + // Button for more options. + $keys[] = array( + 'text' => getTranslation('expand'), + 'callback_data' => $id . ':edit_start:more-options,' . $arg + ); + } + + // Get the inline key array. + $keys = inline_key_array($keys, 5); + + // Write to log. + debug_log($keys); + +} else { + // Edit pokemon. + $keys = raid_edit_start_keys($id); +} + +// Edit the message. +edit_message($update, getTranslation('how_long_raid'), $keys); + +// Build callback message string. +$callback_response = getTranslation('lead_time_set_to') . ' ' . $data['arg'] . ' ' . getTranslation('minutes'); + +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_response); diff --git a/modules/exit.php b/modules/exit.php new file mode 100644 index 0000000..32a386d --- /dev/null +++ b/modules/exit.php @@ -0,0 +1,19 @@ +fetch_assoc(); - if (!$row) exit; - - foreach ($update['message']['new_chat_members'] as $v) { - sendMessage('none',$v['id'],$row['message']); - } - diff --git a/modules/mods.php b/modules/mods.php new file mode 100644 index 0000000..e7d6472 --- /dev/null +++ b/modules/mods.php @@ -0,0 +1,49 @@ +' . getTranslation('mods_saved_mod') . '' . CR . CR; + $msg .= get_user($user_id); + + // Create the keys. + $keys = []; + + // Edit message. + edit_message($update, $msg, $keys, false); + + // Build callback message string. + $callback_response = getTranslation('mods_saved_mod'); + + // Answer callback. + answerCallbackQuery($update['callback_query']['id'], $callback_response); + +} diff --git a/modules/mods_delete.php b/modules/mods_delete.php new file mode 100644 index 0000000..37eec3e --- /dev/null +++ b/modules/mods_delete.php @@ -0,0 +1,37 @@ +' . getTranslation('mods_delete_mod') . '' . CR; + $msg .= get_user($user_id); + + // Create the keys. + $keys = []; + + // Edit message. + edit_message($update, $msg, $keys, false); + + // Build callback message string. + $callback_response = getTranslation('mods_delete_mod'); + + // Answer callback. + answerCallbackQuery($update['callback_query']['id'], $callback_response); + +} diff --git a/modules/mods_list.php b/modules/mods_list.php new file mode 100644 index 0000000..8834a25 --- /dev/null +++ b/modules/mods_list.php @@ -0,0 +1,30 @@ +fetch_assoc()) { + // 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! + send_message($update['callback_query']['message']['chat']['id'], $msg, $keys); + } + + // 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') . ''; +} 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_assoc(); + + // Delete overview + delete_overview($overview['chat_id'], $overview['message_id']); + + // Set message. + $callback_msg = '' . getTranslation('overview_successfully_deleted') . ''; +} + +// Init keys. +$callback_keys = array(); + +// Set keys. +$callback_keys = []; + +// Edit message. +edit_message($update, $callback_msg, $callback_keys, false); + +// Build callback message string. +$callback_response = 'OK'; + +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_response); diff --git a/modules/overview_refresh.php b/modules/overview_refresh.php new file mode 100644 index 0000000..340d14d --- /dev/null +++ b/modules/overview_refresh.php @@ -0,0 +1,138 @@ +fetch_assoc(); + + // No data found. + if (!$row) { + //sendMessage($update['message']['from']['id'], 'Can\'t determine your location, please participate in at least 1 raid'); + //exit; + $tz = TIMEZONE; + } else { + $tz = $row['timezone']; + } +} else { + $tz = TIMEZONE; +} + +// Get active raids. +$request_active_raids = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE end_time>NOW() + AND timezone='{$tz}' + ORDER BY end_time ASC + " +); + +// Count active raids. +$count_active_raids = 0; + +// Init empty active raids and raid_ids array. +$raids_active = array(); +$raid_ids_active = array(); + +// Get all active raids into array. +while ($rowRaids = $request_active_raids->fetch_assoc()) { + // Use current raid_id as key for raids array + $current_raid_id = $rowRaids['id']; + $raids_active[$current_raid_id] = $rowRaids; + + // Build array with raid_ids to query cleanup table later + $raid_ids_active[] = $rowRaids['id']; + + // Counter for active raids + $count_active_raids = $count_active_raids + 1; +} + +// Write to log. +debug_log('Active raids:'); +debug_log($raids_active); + +// Init empty active chats array. +$chats_active = array(); + +// Make sure we have active raids. +if ($count_active_raids > 0) { + // Implode raid_id's of all active raids. + $raid_ids_active = implode(',',$raid_ids_active); + + // Write to log. + debug_log('IDs of active raids:'); + debug_log($raid_ids_active); + + // Get all or specific overview + if ($chat_id == 0) { + $request_overviews = my_query( + " + SELECT chat_id + FROM overview + " + ); + } else { + $request_overviews = my_query( + " + SELECT chat_id + FROM overview + WHERE chat_id = '{$chat_id}' + " + ); + } + + while ($rowOverviews = $request_overviews->fetch_assoc()) { + // Set chat_id. + $chat_id = $rowOverviews['chat_id']; + + // Get chats. + $request_active_chats = my_query( + " + SELECT * + FROM cleanup + WHERE raid_id IN ({$raid_ids_active}) + AND chat_id = '{$chat_id}' + ORDER BY chat_id, FIELD(raid_id, {$raid_ids_active}) + " + ); + + // Get all chats. + while ($rowChats = $request_active_chats->fetch_assoc()) { + $chats_active[] = $rowChats; + } + } +} + +// Write to log. +debug_log('Active chats:'); +debug_log($chats_active); + +// Get raid overviews +get_overview($update, $chats_active, $raids_active, $action = 'refresh', $chat_id); +exit; diff --git a/modules/overview_share.php b/modules/overview_share.php new file mode 100644 index 0000000..89c9bfd --- /dev/null +++ b/modules/overview_share.php @@ -0,0 +1,128 @@ +fetch_assoc(); + +// No data found. +if (!$row) { + //sendMessage($update['message']['from']['id'], 'Can\'t determine your location, please participate in at least 1 raid'); + //exit; + $tz = TIMEZONE; +} else { + $tz = $row['timezone']; +} + +// Get active raids. +$request_active_raids = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE end_time>NOW() + AND timezone='{$tz}' + ORDER BY end_time ASC + " +); + +// Count active raids. +$count_active_raids = 0; + +// Init empty active raids and raid_ids array. +$raids_active = array(); +$raid_ids_active = array(); + +// Get all active raids into array. +while ($rowRaids = $request_active_raids->fetch_assoc()) { + // Use current raid_id as key for raids array + $current_raid_id = $rowRaids['id']; + $raids_active[$current_raid_id] = $rowRaids; + + // Build array with raid_ids to query cleanup table later + $raid_ids_active[] = $rowRaids['id']; + + // Counter for active raids + $count_active_raids = $count_active_raids + 1; +} + +// Write to log. +debug_log('Active raids:'); +debug_log($raids_active); + +// Init empty active chats array. +$chats_active = array(); + +// Make sure we have active raids. +if ($count_active_raids > 0) { + // Implode raid_id's of all active raids. + $raid_ids_active = implode(',',$raid_ids_active); + + // Write to log. + debug_log('IDs of active raids:'); + debug_log($raid_ids_active); + + // Get chat for active raids. + if ($chat_id == 0) { + $request_active_chats = my_query( + " + SELECT * + FROM cleanup + WHERE raid_id IN ({$raid_ids_active}) + ORDER BY chat_id, FIELD(raid_id, {$raid_ids_active}) + " + ); + } else { + $request_active_chats = my_query( + " + SELECT * + FROM cleanup + WHERE raid_id IN ({$raid_ids_active}) + AND chat_id = '{$chat_id}' + ORDER BY chat_id, FIELD(raid_id, {$raid_ids_active}) + " + ); + } + + // Get all chats. + while ($rowChats = $request_active_chats->fetch_assoc()) { + $chats_active[] = $rowChats; + } +} + +// Write to log. +debug_log('Active chats:'); +debug_log($chats_active); + +// Get raid overviews +if ($chat_id == 0) { + get_overview($update, $chats_active, $raids_active, $action = 'share'); +} else { + get_overview($update, $chats_active, $raids_active, $action = 'share', $chat_id); +} +exit; diff --git a/modules/raid_by_gym.php b/modules/raid_by_gym.php new file mode 100755 index 0000000..fb7e7bd --- /dev/null +++ b/modules/raid_by_gym.php @@ -0,0 +1,66 @@ + getTranslation('not_supported'), + 'callback_data' => 'edit:not_supported' + ] + ] + ]; +} else { + $keys = back_key($keys, $back_id, $back_action, $back_arg); +} + +// Edit the message. +edit_message($update, getTranslation('select_gym_name'), $keys); + +// Build callback message string. +$callback_response = getTranslation('here_we_go'); + +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_response); + +exit(); diff --git a/modules/raid_by_gym_letter.php b/modules/raid_by_gym_letter.php new file mode 100755 index 0000000..13d162c --- /dev/null +++ b/modules/raid_by_gym_letter.php @@ -0,0 +1,57 @@ + getTranslation('not_supported'), + 'callback_data' => 'edit:not_supported' + ] + ] + ]; +} + +// Edit the message. +edit_message($update, getTranslation('select_gym_first_letter'), $keys); + +// Build callback message string. +$callback_response = getTranslation('select_gym'); + +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_response); + +exit(); diff --git a/modules/raid_create.php b/modules/raid_create.php old mode 100644 new mode 100755 index a0a0fb5..005bfd6 --- a/modules/raid_create.php +++ b/modules/raid_create.php @@ -1,40 +1,309 @@ real_escape_string($addr).'"'; - } - - $rs = my_query($q); - $id = my_insert_id(); - debug_log('ID='.$id); - - $keys = raid_edit_start_keys($id); - - $msg = 'Create Raid at '.$addr.''; - - if ($update['message']['chat']['type']=='private') { - send_message('none',$update['message']['chat']['id'],$msg.CR.'Choose Raid level:', $keys); - } else { - $reply_to = $update['message']['chat']['id']; - if ($update['message']['reply_to_message']['message_id']) $reply_to = $update['message']['reply_to_message']['message_id']; - - send_message('none',$update['message']['chat']['id'],$msg.CR.'Choose Raid level:', $keys, - ['reply_to_message_id'=>$reply_to, 'reply_markup' => ['selective'=>true, 'one_time_keyboard'=>true]] - ); - } - exit(); +$tz = TIMEZONE; + +// Get latitude / longitude values from Telegram Mobile Client +if (isset($update['message']['location']['latitude'])) { + $lat = $update['message']['location']['latitude']; +} +if (isset($update['message']['location']['longitude'])) { + $lon = $update['message']['location']['longitude']; +} + +// Get Userid and chatid from message or set below in case we get latitude and longitude by text message +if (isset($update['message']['from']['id'])) { + $userid = $update['message']['from']['id']; +} +if (isset($update['message']['chat']['id'])) { + $chatid = $update['message']['chat']['id']; +} +if (isset($update['message']['chat']['type'])) { + $chattype = $update['message']['chat']['type']; +} + +// Init gym and gym_id +$gym = 0; +$gym_id = 0; + +// Get latitude / longitude from message text if empty +// Necessary for Telegram Desktop Client as you cannot send a location :( +if (empty($lat) && empty($lon)) { + // Get the userid, chat id and type + $id_type = $data['id']; + + // Create data array (max. 2) + $userdata = explode(',', $id_type, 2); + + // Set userid, chat id and type + $userid = $userdata[0]; + $chatid = $userid; + $chattype = $userdata[1]; + + // Debug + debug_log('User ID=' . $userid); + debug_log('Chat type=' . $chatid); + debug_log('Chat type=' . $chattype); + + // Get lat and lon from message text + $coords = $data['arg']; + + // Create data array (max. 2) + $data = explode(',', $coords, 2); + + // Latitude and longitude or Gym ID? + if($data[0] == "ID") { + $gym_id = $data[1]; + $gym = get_gym($gym_id); + } else { + // Set latitude / longitude + $lat = $data[0]; + $lon = $data[1]; + + // Debug + debug_log('Lat=' . $lat); + debug_log('Lon=' . $lon); + } +} + +// Init address and gym name +$fullAddress = ""; +$gym_name = ""; + +// Address and gym name based on input +if($gym_id > 0) { + // Set name and coordinates. + $gym_name = $gym['gym_name']; + $lat = $gym['lat']; + $lon = $gym['lon']; + + // Get the address. + $addr = get_address($lat, $lon); + + // Get full address - Street #, ZIP District + $fullAddress = ""; + $fullAddress .= (!empty($addr['street']) ? $addr['street'] : ""); + $fullAddress .= (!empty($addr['street_number']) ? " " . $addr['street_number'] : ""); + $fullAddress .= (!empty($fullAddress) ? ", " : ""); + $fullAddress .= (!empty($addr['postal_code']) ? $addr['postal_code'] . " " : ""); + $fullAddress .= (!empty($addr['district']) ? $addr['district'] : ""); + + // Fallback: Get address from database + if(empty($fullAddress)) { + $fullAddress = $gym['address']; + } + debug_log('Gym ID: ' . $gym_id); + debug_log('Gym Name: ' . $gym_name); + debug_log('Gym Address: ' . $fullAddress); + debug_log('Lat=' . $lat); + debug_log('Lon=' . $lon); +} else { + // Get the address. + $addr = get_address($lat, $lon); + + // Get full address - Street #, ZIP District + $fullAddress = ""; + $fullAddress .= (!empty($addr['street']) ? $addr['street'] : ""); + $fullAddress .= (!empty($addr['street_number']) ? " " . $addr['street_number'] : ""); + $fullAddress .= (!empty($fullAddress) ? ", " : ""); + $fullAddress .= (!empty($addr['postal_code']) ? $addr['postal_code'] . " " : ""); + $fullAddress .= (!empty($addr['district']) ? $addr['district'] : ""); +} + +// Insert new raid or warn about existing raid? +if (!empty($gym_name)) { + $raid_id = raid_duplication_check($gym_name,0); +} + +// Insert new raid +if ($raid_id != 0) { + // Check raid ID + // Positive ID: Raid is completely created + // Negative ID: Raid is being created at the moment + $raid_status = (substr($raid_id, 0, 1) == '-') ? 'start' : 'end'; + + // Change negative raid ID to positive ID + $raid_id = ($raid_status == "start") ? (ltrim($raid_id, '-')) : $raid_id; + + // Get the raid data by id. + $rs = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = {$raid_id} + " + ); + + // Fetch raid data. + $raid = $rs->fetch_assoc(); + + // Create the keys. + if ($raid_status == "end") { + $msg = getTranslation('raid_already_exists') . CR . show_raid_poll_small($raid); + // Init keys. + $keys = array(); + + // Update pokemon and delete raid + $keys = [ + [ + [ + 'text' => getTranslation('delete'), + 'callback_data' => $raid['id'] . ':raids_delete:0' + ] + ], + [ + [ + 'text' => getTranslation('update_pokemon'), + 'callback_data' => $raid['id'] . ':raid_edit_poke:' . $raid['pokemon'], + ] + ] + ]; + + // Add keys to share. + $keys_share = share_keys($raid['id'], $userid); + $keys = array_merge($keys, $keys_share); + } else { + // Set message string + $msg_main = getTranslation('raid_being_created_by_other_user') . CR; + $msg_main .= getTranslation('gym') . ': ' . $raid['gym_name'] . CR . get_user($raid['user_id']); + $msg_main .= getTranslation('raid_creation_started_at') . " " . unix2tz($raid['ts_start'], $raid['timezone']) . '.'; + $access_msg_header = ''; + $access_msg_footer = ''; + + // Check access to overwrite raid. + $raid_access = raid_access_check($update, $raid, true); + if ($raid_access) { + // Update user_id and start_time to ensure correct time selection + $rs = my_query( + " + UPDATE raids + SET start_time = NOW() + WHERE id = {$raid_id} + " + ); + + // Add message header, footer and keys + $access_msg_header .= CR . EMOJI_WARN . "" . getTranslation('raid_creation_in_progress') . "" . EMOJI_WARN . CR; + $access_msg_header .= CR . "" . getTranslation('raid_creation_in_progress_warning') . "" . CR . CR; + $access_msg_footer .= CR . CR . getTranslation('select_raid_level_to_continue') . ':'; + $keys = raid_edit_start_keys($raid['id']); + $key_exit = [ + [ + [ + 'text' => getTranslation('abort'), + 'callback_data' => '0:exit:0' + ] + ] + ]; + $keys = array_merge($keys, $key_exit); + } else { + $keys = []; + } + + // Build message string. + $msg = $access_msg_header . $msg_main . $access_msg_footer; + } + + // Edit the message. + edit_message($update, $msg, $keys); + + // Build callback message string. + $callback_response = 'OK'; + + // Answer callback. + answerCallbackQuery($update['callback_query']['id'], $callback_response); + + exit(); +} + +// Address found. +if (!empty($fullAddress)) { + // Create raid with address. + $rs = my_query( + " + INSERT INTO raids + SET user_id = {$userid}, + lat = '{$lat}', + lon = '{$lon}', + first_seen = NOW(), + start_time = NOW(), + gym_name = '{$db->real_escape_string($gym_name)}', + timezone = '{$tz}', + address = '{$db->real_escape_string($fullAddress)}' + " + ); + +// No address found. +} else { + // Create raid without address. + $rs = my_query( + " + INSERT INTO raids + SET user_id = {$userid}, + lat = '{$lat}', + lon = '{$lon}', + first_seen = NOW(), + start_time = NOW(), + gym_name = '{$db->real_escape_string($gym_name)}', + timezone = '{$tz}' + " + ); +} + +// Get last insert id from db. +$id = my_insert_id(); + +// Write to log. +debug_log('ID=' . $id); + +// Get the keys. +$keys = raid_edit_start_keys($id); + +// No keys found. +if (!$keys) { + // Create the keys. + $keys = [ + [ + [ + 'text' => getTranslation('not_supported'), + 'callback_data' => 'edit:not_supported' + ] + ] + ]; +} + +// Build message. +$msg = getTranslation('create_raid') . ': ' . $fullAddress . ''; + +// Answer callback or send message based on input prior raid creation +if($gym_id != 0 || (empty($update['message']['location']['latitude']) && empty($update['message']['location']['longitude']))) { + // Edit the message. + edit_message($update, $msg . CR . getTranslation('select_raid_level') . ':', $keys); + + // Build callback message string. + $callback_response = getTranslation('gym_saved'); + + // Answer callback. + answerCallbackQuery($update['callback_query']['id'], $callback_response); +} else { + // Private chat type. + if ($chattype == 'private') { + // Send the message. + send_message($chatid, $msg . CR . getTranslation('select_raid_level') . ':', $keys); + + } else { + //$reply_to = $update['message']['chat']['id']; + $reply_to = $chatid; + if ($update['message']['reply_to_message']['message_id']) { + $reply_to = $update['message']['reply_to_message']['message_id']; + } + + // Send the message. + send_message($chatid, $msg . CR . getTranslation('select_raid_level') . ':', $keys, ['reply_to_message_id' => $reply_to, 'reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]); + } + + exit(); +} + diff --git a/modules/raid_edit_poke.php b/modules/raid_edit_poke.php new file mode 100755 index 0000000..ac553fb --- /dev/null +++ b/modules/raid_edit_poke.php @@ -0,0 +1,61 @@ + $levelmons) { + if($level == "X") continue; + debug_log("Searching raid boss '" . $old_pokemon . "' in level " . $level . " raids"); + // Compare pokemon by pokemon to get raid level + foreach($levelmons as $key => $pokemon) { + if(strtolower($old_pokemon) == strtolower($pokemon)) { + $level_found = true; + $raid_level = $level; + debug_log("Found raid boss '" . $pokemon . "' in level " . $level . " raids"); + break 2; + } + } +} + +if ($level_found) { + // Get the keys. + $keys = pokemon_keys($raid_id, $raid_level, $pokemonlist, "raid_set_poke"); +} else { + // Create the keys. + $keys = [ + [ + [ + 'text' => 'Not supported', + 'callback_data' => 'edit:not_supported' + ] + ] + ]; +} + +if (isset($update['callback_query']['inline_message_id'])) { + editMessageText($update['callback_query']['inline_message_id'], getTranslation('select_raid_boss') . ':', $keys); +} else { + editMessageText($update['callback_query']['message']['message_id'], getTranslation('select_raid_boss') . ':', $keys, $update['callback_query']['message']['chat']['id'], $keys); +} + +// Build callback message string. +$callback_response = getTranslation('select_pokemon'); + +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_response); diff --git a/modules/raid_set_poke.php b/modules/raid_set_poke.php new file mode 100755 index 0000000..184243f --- /dev/null +++ b/modules/raid_set_poke.php @@ -0,0 +1,56 @@ +fetch_assoc(); + + // Create the keys. + $keys = []; + + // Build message string. + $msg = ''; + $msg .= getTranslation('raid_saved') . CR; + $msg .= show_raid_poll_small($raid); + + // Edit message. + edit_message($update, $msg, $keys, false); + + // Build callback message string. + $callback_response = getTranslation('raid_boss_saved'); + + // Answer callback. + answerCallbackQuery($update['callback_query']['id'], $callback_response); + +} diff --git a/modules/raid_share.php b/modules/raid_share.php new file mode 100755 index 0000000..183a95b --- /dev/null +++ b/modules/raid_share.php @@ -0,0 +1,58 @@ +fetch_assoc(); + +// Get text and keys. +$text = show_raid_poll($raid); +$keys = keys_vote($raid); + +// Send the message. +send_message($chat, $text, $keys, ['reply_to_message_id' => $chat, 'disable_web_page_preview' => 'true']); + +// Send location. +if (RAID_LOCATION == true) { + // Send location. + $loc = send_venue($chat, $raid['lat'], $raid['lon'], "", !empty($raid['address']) ? $raid['address'] . ', ID = ' . $raid['id'] : $raid['pokemon'] . ', ' . $raid['id']); // DO NOT REMOVE " ID = " --> NEEDED FOR CLEANUP PREPARATION! + + // Write to log. + debug_log('location:'); + debug_log($loc); +} + +// Set callback keys and message +$callback_msg = getTranslation('successfully_shared'); + +// Edit message. +edit_message($update, $callback_msg, $callback_keys, false); + +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_msg); + +exit; diff --git a/modules/raids_delete.php b/modules/raids_delete.php new file mode 100644 index 0000000..1987930 --- /dev/null +++ b/modules/raids_delete.php @@ -0,0 +1,86 @@ + Confirmation required +// 1 -> Cancel deletion +// 2 -> Execute deletion +$action = $data['arg']; + +// Get the raid id. +$id = $data['id']; + +// Execute the action. +if ($action == 0) { + // Build query. + $request = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE id = '{$id}' + " + ); + + // Get raid. + $raid = $request->fetch_assoc(); + + // 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') . ''; + + // Set keys. + $keys = []; +} else if ($action == 2) { + debug_log('Confirmation to delete raid ' . $id . ' was received!'); + // Set message. + $msg = getTranslation('raid_successfully_deleted'); + + // Set keys. + $keys = []; + + // Delete raid from database. + delete_raid($id); +} + +// Edit message. +edit_message($update, $msg, $keys, false); + +// Build callback message string. +$callback_response = 'OK'; + +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_response); + +exit; diff --git a/modules/raids_list.php b/modules/raids_list.php new file mode 100644 index 0000000..f5c8368 --- /dev/null +++ b/modules/raids_list.php @@ -0,0 +1,108 @@ +fetch_assoc(); + +// No data found. +if (!$row) { + //sendMessage($update['message']['from']['id'], 'Can\'t determine your location, please participate in at least 1 raid'); + //exit; + $tz = TIMEZONE; +} else { + $tz = $row['timezone']; +} + +// Build query. +$request = my_query( + " + SELECT *, + UNIX_TIMESTAMP(end_time) AS ts_end, + UNIX_TIMESTAMP(start_time) AS ts_start, + UNIX_TIMESTAMP(NOW()) AS ts_now, + UNIX_TIMESTAMP(end_time)-UNIX_TIMESTAMP(NOW()) AS t_left + FROM raids + WHERE end_time>NOW() + AND timezone='{$tz}' + ORDER BY end_time ASC LIMIT 20 + " +); + +// Count results. +$count = 0; + +// Get raids. +while ($raid = $request->fetch_assoc()) { + + // Counter++ + $count = $count + 1; + + // 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['pokemon'], + ] + ], + [ + [ + 'text' => getTranslation('delete'), + 'callback_data' => $raid['id'] . ':raids_delete:0' + ] + ] + ]; + + // Add keys to share. + $keys_share = share_keys($raid['id'], $update['callback_query']['from']['id']); + $keys = array_merge($keys, $keys_share); + + // Get message. + $msg = show_raid_poll_small($raid); + + // Send message. + send_message($update['callback_query']['from']['id'], $msg, $keys, ['reply_markup' => ['selective' => true, 'one_time_keyboard' => true]]); +} + +// Set message. +if($count == 0) { + //sendMessage($update['callback_query']['from']['id'], '' . getTranslation('no_active_raids_found') . ''); + $msg = '' . getTranslation('no_active_raids_found') . ''; +} else { + $msg = '' . getTranslation('list_all_active_raids') . ':'; +} + +// Set message. +$keys = []; + +// Edit message. +edit_message($update, $msg, $keys, false); + +// Build callback message string. +$callback_response = 'OK'; + +// Answer callback. +answerCallbackQuery($update['callback_query']['id'], $callback_response); + +exit; diff --git a/modules/vote.php b/modules/vote.php index 5c29ae7..d724a01 100644 --- a/modules/vote.php +++ b/modules/vote.php @@ -1,23 +1,67 @@ fetch_assoc(); - debug_log($answer); - - $rs = my_query('SELECT * FROM users WHERE user_id='.$update['callback_query']['from']['id'].''); - $row=$rs->fetch_assoc(); - - $qq = 'extra_people='.intval($data['arg']-1); - if ($row['team']) $qq .= ', team="'.$row['team'].'"'; - debug_log($row); - debug_log($qq); - - if (!$answer) { - my_query('INSERT INTO attendance SET raid_id='.$data['id'].', user_id='.$update['callback_query']['from']['id'].', '.$qq); - } else { - my_query('UPDATE attendance SET '.$qq.' WHERE raid_id='.$data['id'].' AND user_id='.$update['callback_query']['from']['id'].''); - } - - send_response_vote($update, $data); - +// Get the answer. +$answer = $rs->fetch_assoc(); +// Write to log. +debug_log($answer); + +// Build the query. +$rs = my_query( + " + SELECT * + FROM users + WHERE user_id = {$update['callback_query']['from']['id']} + " +); + +// Get the row. +$row = $rs->fetch_assoc(); + +// Get extra people. +$extraPeople = intval($data['arg'] - 1); + +// Check if we found the users team. +$team = !empty($row['team']) ? "'" . $row['team'] . "'" : "NULL"; + +// Write to log. +debug_log($row); + +// User has voted before. +if (!empty($answer)) { + // Update attendance. + my_query( + " + UPDATE attendance + SET extra_people = {$extraPeople}, + team = {$team} + WHERE raid_id = {$data['id']} + AND user_id = {$update['callback_query']['from']['id']} + " + ); + +// User has not voted before. +} else { + // Create attendance. + my_query( + " + INSERT INTO attendance + SET raid_id = {$data['id']}, + user_id = {$update['callback_query']['from']['id']}, + extra_people = {$extraPeople}, + team = {$team} + " + ); +} + +// Send vote response. +send_response_vote($update, $data); diff --git a/modules/vote_arrived.php b/modules/vote_arrived.php index d4d772f..bf26c12 100644 --- a/modules/vote_arrived.php +++ b/modules/vote_arrived.php @@ -1,18 +1,65 @@ fetch_assoc(); - debug_log($answer); - - if (!$answer) { - $query = 'SELECT * FROM users WHERE user_id='.$update['callback_query']['from']['id']; - $rs = my_query($query); - $row = $rs->fetch_assoc(); - - my_query('INSERT INTO attendance SET raid_id='.$data['id'].', user_id='.$update['callback_query']['from']['id'].', arrived=1, team="'.$row['team'].'", attend_time=NOW()'); - } else { - my_query('UPDATE attendance SET arrived=1,raid_done=0,cancel=0,attend_time=NOW() WHERE raid_id='.$data['id'].' AND user_id='.$update['callback_query']['from']['id'].''); - } - - send_response_vote($update, $data); - +// Get the answer. +$answer = $rs->fetch_assoc(); + +// Write to log. +debug_log($answer); + +// User has voted before. +if (!empty($answer)) { + // Update attendance. + my_query( + " + UPDATE attendance + SET arrived = 1, + raid_done = 0, + cancel = 0 + WHERE raid_id = {$data['id']} + AND user_id = {$update['callback_query']['from']['id']} + " + ); + +// User has not voted before. +} else { + /* + // Get users data. + $rs = my_query( + " + SELECT * + FROM users + WHERE user_id = {$update['callback_query']['from']['id']} + " + ); + + // Get the row. + $row = $rs->fetch_assoc(); + + // Check if we found the users team. + $team = !empty($row['team']) ? "'" . $row['team'] . "'" : NULL; + + // Create attendance. + my_query( + " + INSERT INTO attendance + SET raid_id = {$data['id']}, + user_id = {$update['callback_query']['from']['id']}, + arrived = 1, + team = {$team}, + attend_time = NOW() + " + ); +*/ +} + +// Send vote response. +send_response_vote($update, $data); diff --git a/modules/vote_cancel.php b/modules/vote_cancel.php index ea0c33f..f6746d1 100644 --- a/modules/vote_cancel.php +++ b/modules/vote_cancel.php @@ -1,14 +1,49 @@ fetch_assoc(); - debug_log($answer); - - if (!$answer) { - my_query('INSERT INTO attendance SET raid_id='.$data['id'].', user_id='.$update['callback_query']['from']['id'].', cancel=1, attend_time=NULL'); - } else { - my_query('UPDATE attendance SET cancel=1, raid_done=0, arrived=0, attend_time=NULL WHERE raid_id='.$data['id'].' AND user_id='.$update['callback_query']['from']['id'].''); - } - - send_response_vote($update, $data); - +// Check if the user has voted for this raid before. +$rs = my_query( + " + SELECT * + FROM attendance + WHERE raid_id = {$data['id']} + AND user_id = {$update['callback_query']['from']['id']} + " +); +// Get the answer. +$answer = $rs->fetch_assoc(); + +// Write to log. +debug_log($answer); + +// User has voted before. +if (!empty($answer)) { + // Update attendance. + my_query( + " + UPDATE attendance + SET cancel = 1, + raid_done = 0, + arrived = 0 + WHERE raid_id = {$data['id']} + AND user_id = {$update['callback_query']['from']['id']} + " + ); + +// User has not voted before. +} else { + /* + // Create attendance. + my_query( + " + INSERT INTO attendance + SET raid_id = {$data['id']}, + user_id = {$update['callback_query']['from']['id']}, + cancel = 1, + attend_time = NULL + " + ); + */ +} + +// Send the vote response. +send_response_vote($update, $data); diff --git a/modules/vote_done.php b/modules/vote_done.php index a8e975f..88015ac 100644 --- a/modules/vote_done.php +++ b/modules/vote_done.php @@ -1,14 +1,46 @@ fetch_assoc(); - debug_log($answer); - - if (!$answer) { - my_query('INSERT INTO attendance SET raid_id='.$data['id'].', user_id='.$update['callback_query']['from']['id'].', raid_done=1'); - } else { - my_query('UPDATE attendance SET raid_done=1 WHERE raid_id='.$data['id'].' AND user_id='.$update['callback_query']['from']['id'].''); - } - - send_response_vote($update, $data); - +// Get the answer. +$answer = $rs->fetch_assoc(); + +// Write to log. +debug_log($answer); + +// User has voted before. +if (!empty($answer)) { + // Update attendance. + my_query( + " + UPDATE attendance + SET raid_done = 1 + WHERE raid_id = {$data['id']} + AND user_id = {$update['callback_query']['from']['id']} + " + ); + +// User has not voted before. +} else { + /* + // Create attendance. + my_query( + " + INSERT INTO attendance + SET raid_id = {$data['id']}, + user_id = {$update['callback_query']['from']['id']}, + raid_done = 1 + " + ); + */ +} + +// Send vote response. +send_response_vote($update, $data); diff --git a/modules/vote_edit.php b/modules/vote_edit.php index f122dd5..3a3fbc3 100644 --- a/modules/vote_edit.php +++ b/modules/vote_edit.php @@ -1,4 +1,4 @@ 0 + " + ); +} + +// Send vote response. +send_response_vote($update, $data); \ No newline at end of file diff --git a/modules/vote_pokemon.php b/modules/vote_pokemon.php new file mode 100644 index 0000000..5d1871b --- /dev/null +++ b/modules/vote_pokemon.php @@ -0,0 +1,63 @@ +fetch_assoc(); + +// Write to log. +debug_log($answer); + +// User has voted before. +if (!empty($answer)) { + // Update attendance. + my_query( + " + UPDATE attendance + SET pokemon = '{$db->real_escape_string($data['arg'])}' + WHERE raid_id = {$data['id']} + AND user_id = {$update['callback_query']['from']['id']} + " + ); + +// User has not voted before. +// Disabled since user shall vote for the time first! +/* +} else { + + // Get users data. + $rs = my_query( + " + SELECT * + FROM users + WHERE user_id = {$update['callback_query']['from']['id']} + " + ); + + // Get the row. + $row = $rs->fetch_assoc(); + + // Check if we found the users team. + $team = !empty($row['team']) ? "'" . $row['team'] . "'" : "NULL"; + + // Create attendance. + my_query( + " + INSERT INTO attendance + SET raid_id = {$data['id']}, + user_id = {$update['callback_query']['from']['id']}, + pokemon = '{$db->real_escape_string($data['arg'])}', + team = {$team} + " + ); +*/ +} +// Send vote response. +send_response_vote($update, $data); diff --git a/modules/vote_refresh.php b/modules/vote_refresh.php index f122dd5..3a3fbc3 100644 --- a/modules/vote_refresh.php +++ b/modules/vote_refresh.php @@ -1,4 +1,4 @@ fetch_assoc(); - debug_log($answer); - - if (!$answer) { - my_query('INSERT INTO attendance SET raid_id='.$data['id'].', user_id='.$update['callback_query']['from']['id'].', team="'.$data['arg'].'"'); - } else { - my_query('UPDATE attendance SET team="'.$data['arg'].'" WHERE raid_id='.$data['id'].' AND user_id='.$update['callback_query']['from']['id'].''); - } - - my_query('UPDATE users SET team="'.$data['arg'].'" WHERE user_id='.$update['callback_query']['from']['id'].''); - - send_response_vote($update, $data); +// Get the answer. +$answer = $rs->fetch_assoc(); + +// Write to log. +debug_log($answer); + +// User has voted before. +if (!empty($answer)) { + // Update attendance. + my_query( + " + UPDATE attendance + SET team = '{$data['arg']}' + WHERE raid_id = {$data['id']} + AND user_id = {$update['callback_query']['from']['id']} + " + ); + +// User has not voted before. +// Do nothing to avoid that the same person appears twice in raid attendances when quickly pressing a team and a voting time button +/*} else { + // Create attendance. + my_query( + " + INSERT INTO attendance + SET raid_id = {$data['id']}, + user_id = {$update['callback_query']['from']['id']}, + team = '{$data['arg']}' + " + ); +*/ +} + +// Update users team. +my_query( + " + UPDATE users + SET team = '{$data['arg']}' + WHERE user_id = {$update['callback_query']['from']['id']} + " +); + +// Send vote response. +send_response_vote($update, $data); diff --git a/modules/vote_time.php b/modules/vote_time.php index 4393aa2..1478264 100644 --- a/modules/vote_time.php +++ b/modules/vote_time.php @@ -1,18 +1,64 @@ fetch_assoc(); - debug_log($answer); - - if (!$answer) { - $query = 'SELECT * FROM users WHERE user_id='.$update['callback_query']['from']['id']; - $rs = my_query($query); - $row = $rs->fetch_assoc(); - - my_query('INSERT INTO attendance SET raid_id='.$data['id'].', user_id='.$update['callback_query']['from']['id'].', attend_time=FROM_UNIXTIME('.$data['arg'].'), team="'.$row['team'].'"'); - } else { - my_query('UPDATE attendance SET attend_time=FROM_UNIXTIME('.$data['arg'].'), cancel=0, arrived=0,raid_done=0 WHERE raid_id='.$data['id'].' AND user_id='.$update['callback_query']['from']['id'].''); - } - - send_response_vote($update, $data); - +// Get the answer. +$answer = $rs->fetch_assoc(); + +// Write to log. +debug_log($answer); + +// User has voted before. +if (!empty($answer)) { + // Update attendance. + my_query( + " + UPDATE attendance + SET attend_time = FROM_UNIXTIME({$data['arg']}), + cancel = 0, + arrived = 0, + raid_done = 0 + WHERE raid_id = {$data['id']} + AND user_id = {$update['callback_query']['from']['id']} + " + ); + +// User has not voted before. +} else { + + // Get users data. + $rs = my_query( + " + SELECT * + FROM users + WHERE user_id = {$update['callback_query']['from']['id']} + " + ); + + // Get the row. + $row = $rs->fetch_assoc(); + + // Check if we found the users team. + $team = !empty($row['team']) ? "'" . $row['team'] . "'" : "NULL"; + + // Create attendance. + my_query( + " + INSERT INTO attendance + SET raid_id = {$data['id']}, + user_id = {$update['callback_query']['from']['id']}, + attend_time = FROM_UNIXTIME({$data['arg']}), + team = {$team} + " + ); +} + +// Send vote response. +send_response_vote($update, $data); diff --git a/raid-pokemon-bot.sql b/raid-pokemon-bot.sql index 1a53b38..64ccdaf 100644 --- a/raid-pokemon-bot.sql +++ b/raid-pokemon-bot.sql @@ -1,20 +1,33 @@ -/* -SQLyog Community v8.8 Beta2 -MySQL - 5.7.19-0ubuntu0.16.04.1 : Database - 437562092 -********************************************************************* -*/ +-- phpMyAdmin SQL Dump +-- version 4.2.12deb2+deb8u2 +-- http://www.phpmyadmin.net +-- +-- Host: localhost +-- Erstellungszeit: 23. Feb 2018 um 13:27 +-- Server Version: 5.5.58-0+deb8u1 +-- PHP-Version: 5.6.33-0+deb8u1 +SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; +SET time_zone = "+00:00"; + + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; -/*!40101 SET SQL_MODE=''*/; +-- +-- Datenbank: `raidbot` +-- -/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; -/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; -/*Table structure for table `attendance` */ +-- -------------------------------------------------------- -CREATE TABLE `attendance` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, +-- +-- Tabellenstruktur für Tabelle `attendance` +-- + +CREATE TABLE IF NOT EXISTS `attendance` ( +`id` int(10) unsigned NOT NULL, `user_id` bigint(20) DEFAULT NULL, `raid_id` int(10) unsigned DEFAULT NULL, `attend_time` datetime DEFAULT NULL, @@ -25,52 +38,133 @@ CREATE TABLE `attendance` ( `extra_2_team` enum('mystic','valor','instinct') DEFAULT NULL, `extra_3_team` enum('mystic','valor','instinct') DEFAULT NULL, `extra_4_team` enum('mystic','valor','instinct') DEFAULT NULL, - `arrived` tinyint(1) unsigned DEFAULT NULL, - `raid_done` tinyint(1) unsigned DEFAULT NULL, - `cancel` tinyint(1) unsigned DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=1860 DEFAULT CHARSET=utf8; + `arrived` tinyint(1) unsigned DEFAULT '0', + `raid_done` tinyint(1) unsigned DEFAULT '0', + `cancel` tinyint(1) unsigned DEFAULT '0', + `pokemon` varchar(12) DEFAULT '0' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `cleanup` +-- + +CREATE TABLE IF NOT EXISTS `cleanup` ( +`id` int(10) unsigned NOT NULL, + `raid_id` int(10) unsigned NOT NULL, + `chat_id` bigint(20) NOT NULL, + `message_id` bigint(20) unsigned NOT NULL, + `cleaned` int(10) unsigned DEFAULT '0' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `gyms` +-- + +CREATE TABLE IF NOT EXISTS `gyms` ( +`id` int(10) unsigned NOT NULL, + `lat` varchar(11) DEFAULT NULL, + `lon` varchar(11) DEFAULT NULL, + `address` varchar(255) DEFAULT NULL, + `gym_name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- -/*Table structure for table `raids` */ +-- +-- Tabellenstruktur für Tabelle `overview` +-- -CREATE TABLE `raids` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, +CREATE TABLE IF NOT EXISTS `overview` ( +`id` int(10) unsigned NOT NULL, + `chat_id` bigint(20) NOT NULL, + `message_id` bigint(20) unsigned NOT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- + +-- +-- Tabellenstruktur für Tabelle `raids` +-- + +CREATE TABLE IF NOT EXISTS `raids` ( +`id` int(10) unsigned NOT NULL, `user_id` bigint(20) DEFAULT NULL, `pokemon` varchar(12) DEFAULT NULL, `lat` varchar(11) DEFAULT NULL, `lon` varchar(11) DEFAULT NULL, `first_seen` datetime DEFAULT NULL, + `start_time` datetime DEFAULT NULL, `end_time` datetime DEFAULT NULL, `timezone` char(30) DEFAULT NULL, `address` varchar(255) DEFAULT NULL, - `gym_name` varchar(255) DEFAULT NULL, - `gym_team` enum('mystic','valor','instinct') DEFAULT NULL, - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=549 DEFAULT CHARSET=utf8; + `gym_name` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL, + `gym_team` enum('mystic','valor','instinct') DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; -/*Table structure for table `users` */ +-- -------------------------------------------------------- -CREATE TABLE `users` ( - `id` int(10) unsigned NOT NULL AUTO_INCREMENT, +-- +-- Tabellenstruktur für Tabelle `users` +-- + +CREATE TABLE IF NOT EXISTS `users` ( +`id` int(10) unsigned NOT NULL, `user_id` bigint(20) DEFAULT NULL, - `nick` varchar(100) DEFAULT NULL, - `name` varchar(200) DEFAULT NULL, + `nick` varchar(100) CHARACTER SET utf8mb4 DEFAULT NULL, + `name` varchar(200) CHARACTER SET utf8mb4 DEFAULT NULL, `team` enum('mystic','valor','instinct') DEFAULT NULL, `moderator` tinyint(1) unsigned DEFAULT NULL, `timezone` int(10) DEFAULT NULL, `lang` varchar(5) DEFAULT NULL, `alert_lat` varchar(12) DEFAULT NULL, `alert_lon` varchar(12) DEFAULT NULL, - PRIMARY KEY (`id`), - UNIQUE KEY `i_userid` (`user_id`) -) ENGINE=InnoDB AUTO_INCREMENT=12891 DEFAULT CHARSET=utf8; - -CREATE TABLE `help` ( - `id` bigint(20) NOT NULL, - `message` text, - PRIMARY KEY (`id`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 - -/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; -/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; -/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + `level` int(10) unsigned DEFAULT '0' +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- +-- Indizes der exportierten Tabellen +-- + +-- +-- Indizes für die Tabelle `attendance` +-- +ALTER TABLE `attendance` + ADD PRIMARY KEY (`id`), ADD KEY `raid_id` (`raid_id`); + +-- +-- Indizes für die Tabelle `cleanup` +-- +ALTER TABLE `cleanup` + ADD PRIMARY KEY (`id`); + +-- +-- Indizes für die Tabelle `gyms` +-- +ALTER TABLE `gyms` + ADD PRIMARY KEY (`id`); + +-- +-- Indizes für die Tabelle `overview` +-- +ALTER TABLE `overview` + ADD PRIMARY KEY (`id`); + +-- +-- Indizes für die Tabelle `raids` +-- +ALTER TABLE `raids` + ADD PRIMARY KEY (`id`), ADD KEY `end_time` (`end_time`), ADD KEY `user_id` (`user_id`); + +-- +-- Indizes für die Tabelle `users` +-- +ALTER TABLE `users` + ADD PRIMARY KEY (`id`), ADD UNIQUE KEY `i_userid` (`user_id`); + +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; diff --git a/webhook.html b/webhook.html new file mode 100644 index 0000000..4fd2491 --- /dev/null +++ b/webhook.html @@ -0,0 +1,40 @@ + + + Set Webhooks + + + + +
+
+ Enter your Bot Token:
+ Enter your Bot Url:
+ MAX Connections?:
+ Enter your Certificate (only if self-signed):
+
+ +
+
+ + +