/** * @param classConfig $config */ function init_update(&$config) { $update_file = SN_ROOT_PHYSICAL . "includes/update" . DOT_PHP_EX; if (file_exists($update_file)) { if (filemtime($update_file) > $config->db_loadItem('var_db_update') || $config->db_loadItem('db_version') < DB_VERSION) { if (defined('IN_ADMIN')) { sn_db_transaction_start(); // Для защиты от двойного запуска апдейта - начинаем транзакцию. Так запись в базе будет блокирована if (SN_TIME_NOW >= $config->db_loadItem('var_db_update_end')) { $config->db_saveItem('var_db_update_end', SN_TIME_NOW + ($config->upd_lock_time ? $config->upd_lock_time : 300)); sn_db_transaction_commit(); require_once $update_file; sys_refresh_tablelist(); $current_time = time(); $config->db_saveItem('var_db_update', $current_time); $config->db_saveItem('var_db_update_end', $current_time); } elseif (filemtime($update_file) > $config->var_db_update) { $timeout = $config->var_db_update_end - SN_TIME_NOW; die("Обновляется база данных. Рассчетное время окончания - {$timeout} секунд (время обновления может увеличиваться). Пожалуйста, подождите...<br />\n Obnovljaetsja baza dannyh. Rasschetnoe vremya okonchanija - {$timeout} secund. Pozhalujsta, podozhdute...<br />\n Database update in progress. Estimated update time {$timeout} seconds (can increase depending on update process). Please wait..."); } sn_db_transaction_rollback(); } else { die('Происходит обновление сервера - пожалуйста, подождите...<br /> Proishodit obnovlenie servera - pozhalujsta, podozhdute...<br /> Server upgrading now - please wait...<br /> <a href="admin/overview.php">Admin link</a>'); } } } }
function scheduler_process() { global $config, $user, $debug, $lang; $is_admin_request = false; $ts_var_stat_update = strtotime($config->db_loadItem('var_stat_update')); $ts_scheduled_update = sys_schedule_get_prev_run($config->db_loadItem('stats_schedule'), $config->var_stat_update); if (sys_get_param_int('admin_update')) { define('USER_LEVEL', isset($user['authlevel']) ? $user['authlevel'] : -1); if (USER_LEVEL > 0) { $is_admin_request = true; $ts_scheduled_update = SN_TIME_NOW; } } if ($ts_scheduled_update > $ts_var_stat_update) { lng_include('admin'); sn_db_transaction_start(); $ts_var_stat_update_end = strtotime($config->db_loadItem('var_stat_update_end')); if (SN_TIME_NOW > $ts_var_stat_update_end) { $old_server_status = $config->db_loadItem('game_disable'); $config->db_saveItem('game_disable', GAME_DISABLE_STAT); $config->db_saveItem('var_stat_update_end', date(FMT_DATE_TIME_SQL, SN_TIME_NOW + ($config->db_loadItem('stats_minimal_interval') ? $config->stats_minimal_interval : 600))); $config->db_saveItem('var_stat_update_msg', 'Update started'); sn_db_transaction_commit(); $msg = $is_admin_request ? 'admin request' : 'scheduler'; $next_run = date(FMT_DATE_TIME_SQL, sys_schedule_get_prev_run($config->stats_schedule, $config->var_stat_update, true)); $msg = "Running stat updates: {$msg}. Config->var_stat_update = " . $config->var_stat_update . ', $ts_scheduled_update = ' . date(FMT_DATE_TIME_SQL, $ts_scheduled_update) . ', next_stat_update = ' . $next_run; $debug->warning($msg, 'Stat update', LOG_INFO_STAT_PROCESS); $total_time = microtime(true); // require_once('../includes/sys_stat.php'); require_once SN_ROOT_PHYSICAL . 'includes/includes/sys_stat.php'; sys_stat_calculate(); $total_time = microtime(true) - $total_time; $msg = "Stat update complete in {$total_time} seconds."; $debug->warning($msg, 'Stat update', LOG_INFO_STAT_PROCESS); $msg = "{$lang['adm_done']}: {$total_time} {$lang['sys_sec']}."; // . date(FMT_DATE_TIME, $ts_scheduled_update) . ' ' . date(FMT_DATE_TIME, $config->var_stat_update); // TODO: Analyze maintenance result. Add record to log if error. Add record to log if OK $maintenance_result = sys_maintenance(); $config->db_saveItem('var_stat_update', SN_TIME_SQL); $config->db_saveItem('var_stat_update_msg', $msg); $config->db_saveItem('var_stat_update_next', $next_run); $config->db_saveItem('var_stat_update_admin_forced', SN_TIME_SQL); $config->db_saveItem('var_stat_update_end', SN_TIME_SQL); $config->db_saveItem('game_disable', $old_server_status); } elseif ($ts_scheduled_update > $ts_var_stat_update) { $timeout = strtotime($config->db_loadItem('var_stat_update_end')) - SN_TIME_NOW; $msg = $config->db_loadItem('var_stat_update_msg'); $msg = "{$msg} ETA {$timeout} seconds. Please wait..."; } sn_db_transaction_rollback(); } elseif ($is_admin_request) { $msg = 'Stat is up to date'; } return $msg; }
function error($message = 'There is a error on page', $title = 'Internal Error', $error_code = 500, $dump = true) { global $config, $sys_stop_log_hit, $lang, $sys_log_disabled, $user; if (empty(classSupernova::$db->connected)) { // TODO - писать ошибку в файл die('SQL server currently unavailable. Please contact Administration...'); } sn_db_transaction_rollback(); if ($config->debug == 1) { echo "<h2>{$title}</h2><br><font color=red>{$message}</font><br><hr>"; echo "<table>{$this->log}</table>"; } $fatal_error = 'Fatal error: cannot write to `logs` table. Please contact Administration...'; $error_text = db_escape($message); $error_backtrace = $this->dump($dump, true, strpos($message, 'Deadlock') !== false); if (!$sys_log_disabled) { $query = "INSERT INTO `{{logs}}` SET\n `log_time` = '" . time() . "', `log_code` = '" . db_escape($error_code) . "', `log_sender` = '" . db_escape($user['id']) . "',\n `log_username` = '" . db_escape($user['user_name']) . "', `log_title` = '" . db_escape($title) . "', `log_text` = '" . db_escape($message) . "',\n `log_page` = '" . db_escape(strpos($_SERVER['SCRIPT_NAME'], SN_ROOT_RELATIVE) === false ? $_SERVER['SCRIPT_NAME'] : substr($_SERVER['SCRIPT_NAME'], strlen(SN_ROOT_RELATIVE))) . "'" . ($error_backtrace ? ", `log_dump` = '" . db_escape(serialize($error_backtrace)) . "'" : '') . ";"; doquery($query, '', false, true) or die($fatal_error . db_error()); $message = "Пожалуйста, свяжитесь с админом, если ошибка повторится. Ошибка №: <b>" . db_insert_id() . "</b>"; $sys_stop_log_hit = true; $sys_log_disabled = true; !function_exists('message') ? die($message) : message($message, 'Ошибка', '', 0, false); } else { // // TODO Здесь надо писать в файло ob_start(); print "<hr>User ID {$user['id']} raised error code {$error_code} titled '{$title}' with text '{$error_text}' on page {$_SERVER['SCRIPT_NAME']}"; foreach ($error_backtrace as $name => $value) { print '<hr>'; pdump($value, $name); } ob_end_flush(); die; } }
throw new exception($can_teleport['message'], $can_teleport['result']); } rpg_points_change($user['id'], RPG_TELEPORT, -$config->planet_teleport_cost, array(&$lang['ov_teleport_log_record'], $planetrow['name'], $planetrow['id'], uni_render_coordinates($planetrow), uni_render_coordinates($new_coordinates))); $planet_teleport_next = SN_TIME_NOW + $config->planet_teleport_timeout; db_planet_set_by_gspt($planetrow['galaxy'], $planetrow['system'], $planetrow['planet'], PT_ALL, "galaxy = {$new_coordinates['galaxy']}, system = {$new_coordinates['system']}, planet = {$new_coordinates['planet']}, planet_teleport_next = {$planet_teleport_next}"); if ($planetrow['id'] == $user['id_planet']) { db_user_set_by_id($user['id'], "galaxy = {$new_coordinates['galaxy']}, system = {$new_coordinates['system']}, planet = {$new_coordinates['planet']}"); } // $global_data = sys_o_get_updated($user, $planetrow['id'], SN_TIME_NOW); sn_db_transaction_commit(); $user = db_user_by_id($user['id'], true, '*'); $planetrow = db_planet_by_id($planetrow['id'], true, '*'); $result = array('STATUS' => ERR_NONE, 'MESSAGE' => $lang['ov_teleport_err_none']); sys_redirect('overview.php?mode=manage'); } catch (exception $e) { sn_db_transaction_rollback(); $result = array('STATUS' => $e->getCode(), 'MESSAGE' => $e->getMessage()); } } elseif (sys_get_param_str('abandon')) { //if(sec_password_encode(sys_get_param('abandon_confirm'), $user['salt']) == $user['password']) { if (sec_password_check($user, sys_get_param('abandon_confirm'))) { if ($user['id_planet'] != $user['current_planet'] && $user['current_planet'] == $planet_id) { $destroyed = SN_TIME_NOW + 60 * 60 * 24; db_planet_set_by_id($user['current_planet'], "`destruyed`='{$destroyed}', `id_owner`=0"); db_planet_set_by_parent($user['current_planet'], "`destruyed`='{$destroyed}', `id_owner`=0"); db_user_set_by_id($user['id'], '`current_planet` = `id_planet`'); message($lang['ov_delete_ok'], $lang['colony_abandon'], 'overview.php?mode=manage'); } else { message($lang['ov_delete_wrong_planet'], $lang['colony_abandon'], 'overview.php?mode=manage'); } } else {
function flt_flying_fleet_handler($skip_fleet_update = false) { /* [*] Нужно ли заворачивать ВСЕ в одну транзакцию? С одной стороны - да, что бы данные были гарантированно на момент снапшота С другой стороны - нет, потому что при большой активности это все будет блокировать слишком много рядов, да и таймаут будет большой для ожидания всего разлоченного Стоит завернуть каждую миссию отдельно? Это сильно увеличит количество запросов, зато так же сильно снизит количество блокировок. Resume: НЕТ! Надо оставить все в одной транзакции! Так можно будет поддерживать consistency кэша. Там буквально сантисекунды блокировки [*] Убрать кэшированние данных о пользователях и планета. Офигенно освободит память - проследить! НЕТ! Считать, скольким флотам нужна будет инфа и кэшировать только то, что используется больше раза! Заодно можно будет исключить перересчет очередей/ресурсов - сильно ускорит дело! Особенно будет актуально, когда все бонусы будут в одной таблице Ну и никто не заставляет как сейчас брать ВСЕ из таблицы - только по полям. Гемор, но не сильный - сделать запрос по группам sn_data И писать в БД только один раз результат [*] Нужно ли на этом этапе знать полную информацию о флотах? Заблокировать флоты можно и неполным запросом. Блокировка флотов - это не страшно. Ну, не пройдет одна-две отмены - так никто и не гарантировал реалтайма! С одной стороны - да, уменьшит количество запросов С другой стооны - расход памяти Все равно надо будет знать полную инфу о флоте в момент обработки [*] Сделать тестовую БД для расчетов [*] Но не раньше, чем переписать все миссии */ global $config, $debug; if ($config->game_disable != GAME_DISABLE_NONE || $skip_fleet_update) { return; } sn_db_transaction_start(); if ($config->db_loadItem('game_disable') != GAME_DISABLE_NONE || SN_TIME_NOW - strtotime($config->db_loadItem('fleet_update_last')) <= $config->fleet_update_interval) { sn_db_transaction_rollback(); return; } // Watchdog timer if ($config->db_loadItem('fleet_update_lock')) { if (SN_TIME_NOW - strtotime($config->fleet_update_lock) <= mt_rand(240, 300)) { sn_db_transaction_rollback(); return; } else { $debug->warning('Flying fleet handler was locked too long - watchdog unlocked', 'FFH Error', 504); } } $config->db_saveItem('fleet_update_lock', SN_TIME_SQL); $config->db_saveItem('fleet_update_last', SN_TIME_SQL); sn_db_transaction_commit(); //log_file('Начинаем обсчёт флотов'); //log_file('Обсчёт ракет'); sn_db_transaction_start(); coe_o_missile_calculate(); sn_db_transaction_commit(); $fleet_list = array(); $fleet_event_list = array(); $missions_used = array(); sn_db_transaction_start(); //log_file('Запрос на флоты'); $_fleets = doquery("SELECT * FROM `{{fleets}}` WHERE\n (`fleet_start_time` <= " . SN_TIME_NOW . " AND `fleet_mess` = 0)\n OR (`fleet_end_stay` <= " . SN_TIME_NOW . " AND fleet_end_stay > 0 AND `fleet_mess` = 0)\n OR (`fleet_end_time` <= " . SN_TIME_NOW . ")\n FOR UPDATE;"); //log_file('Выборка флотов'); while ($fleet_row = db_fetch($_fleets)) { set_time_limit(15); // Унифицировать код с темплейтным разбором эвентов на планете! $fleet_list[$fleet_row['fleet_id']] = $fleet_row; $missions_used[$fleet_row['fleet_mission']] = 1; if ($fleet_row['fleet_start_time'] <= SN_TIME_NOW && $fleet_row['fleet_mess'] == 0) { $fleet_event_list[] = array('fleet_row' => &$fleet_list[$fleet_row['fleet_id']], 'fleet_time' => $fleet_list[$fleet_row['fleet_id']]['fleet_start_time'], 'fleet_event' => EVENT_FLT_ARRIVE); } if ($fleet_row['fleet_end_stay'] > 0 && $fleet_row['fleet_end_stay'] <= SN_TIME_NOW && $fleet_row['fleet_mess'] == 0) { $fleet_event_list[] = array('fleet_row' => &$fleet_list[$fleet_row['fleet_id']], 'fleet_time' => $fleet_list[$fleet_row['fleet_id']]['fleet_end_stay'], 'fleet_event' => EVENT_FLT_ACOMPLISH); } if ($fleet_row['fleet_end_time'] <= SN_TIME_NOW) { $fleet_event_list[] = array('fleet_row' => &$fleet_list[$fleet_row['fleet_id']], 'fleet_time' => $fleet_list[$fleet_row['fleet_id']]['fleet_end_time'], 'fleet_event' => EVENT_FLT_RETURN); } } sn_db_transaction_commit(); //log_file('Сортировка и подгрузка модулей'); uasort($fleet_event_list, 'flt_flyingFleetsSort'); unset($_fleets); // TODO: Грузить только используемые модули из $missions_used $mission_files = array(MT_ATTACK => 'flt_mission_attack', MT_AKS => 'flt_mission_attack', MT_DESTROY => 'flt_mission_attack', MT_TRANSPORT => 'flt_mission_transport', MT_RELOCATE => 'flt_mission_relocate', MT_HOLD => 'flt_mission_hold', MT_SPY => 'flt_mission_spy', MT_COLONIZE => 'flt_mission_colonize', MT_RECYCLE => 'flt_mission_recycle', MT_EXPLORE => 'flt_mission_explore'); foreach ($missions_used as $mission_id => $cork) { require_once SN_ROOT_PHYSICAL . "includes/includes/{$mission_files[$mission_id]}" . DOT_PHP_EX; } //log_file('Обработка миссий'); $sn_groups_mission = sn_get_groups('missions'); foreach ($fleet_event_list as $fleet_event) { // TODO: Указатель тут потом сделать // TODO: СЕЙЧАС НАДО ПРОВЕРЯТЬ ПО БАЗЕ - А ЖИВОЙ ЛИ ФЛОТ?! $fleet_row = $fleet_event['fleet_row']; if (!$fleet_row) { // Fleet was destroyed in course of previous actions continue; } //log_file('Миссия'); // TODO Обернуть всё в транзакции. Начинать надо заранее, блокируя все таблицы внутренним локом SELECT 1 FROM {{users}} sn_db_transaction_start(); $config->db_saveItem('fleet_update_last', SN_TIME_SQL); $mission_data = $sn_groups_mission[$fleet_row['fleet_mission']]; // Формируем запрос, блокирующий сразу все нужные записи db_flying_fleet_lock($mission_data, $fleet_row); $fleet_row = doquery("SELECT * FROM {{fleets}} WHERE fleet_id = {$fleet_row['fleet_id']} FOR UPDATE", true); if (!$fleet_row || empty($fleet_row)) { // Fleet was destroyed in course of previous actions sn_db_transaction_commit(); continue; } if ($fleet_event['fleet_event'] == EVENT_FLT_RETURN) { // Fleet returns to planet RestoreFleetToPlanet($fleet_row, true, false, true); sn_db_transaction_commit(); continue; } if ($fleet_event['fleet_event'] == EVENT_FLT_ARRIVE && $fleet_row['fleet_mess'] != 0) { // При событии EVENT_FLT_ARRIVE флот всегда должен иметь fleet_mess == 0 // В противном случае это означает, что флот уже был обработан ранее - например, при САБе sn_db_transaction_commit(); continue; } // TODO: Здесь тоже указатели // TODO: Кэширование // TODO: Выбирать только нужные поля // шпионаж не дает нормальный ID fleet_end_planet_id 'dst_planet' $mission_data = array('fleet' => &$fleet_row, 'dst_user' => $mission_data['dst_user'] || $mission_data['dst_planet'] ? db_user_by_id($fleet_row['fleet_target_owner'], true) : null, 'dst_planet' => $mission_data['dst_planet'] ? db_planet_by_vector($fleet_row, 'fleet_end_', true, '`id`, `id_owner`, `name`') : null, 'src_user' => $mission_data['src_user'] || $mission_data['src_planet'] ? db_user_by_id($fleet_row['fleet_owner'], true) : null, 'src_planet' => $mission_data['src_planet'] ? db_planet_by_vector($fleet_row, 'fleet_start_', true, '`id`, `id_owner`, `name`') : null, 'fleet_event' => $fleet_event['fleet_event']); if ($mission_data['dst_planet']) { // $mission_data['dst_planet'] = sys_o_get_updated($mission_data['dst_user'], $mission_data['dst_planet']['id'], $fleet_row['fleet_start_time']); if ($mission_data['dst_planet']['id_owner']) { $mission_data['dst_planet'] = sys_o_get_updated($mission_data['dst_planet']['id_owner'], $mission_data['dst_planet']['id'], $fleet_row['fleet_start_time']); } $mission_data['dst_user'] = $mission_data['dst_user'] ? $mission_data['dst_planet']['user'] : null; $mission_data['dst_planet'] = $mission_data['dst_planet']['planet']; } switch ($fleet_row['fleet_mission']) { // Для боевых атак нужно обновлять по САБу и по холду - таки надо возвращать данные из обработчика миссий! case MT_AKS: case MT_ATTACK: case MT_DESTROY: $attack_result = flt_mission_attack($mission_data); $mission_result = CACHE_COMBAT; break; /* case MT_DESTROY: $attack_result = flt_mission_destroy($mission_data); $mission_result = CACHE_COMBAT; break; */ /* case MT_DESTROY: $attack_result = flt_mission_destroy($mission_data); $mission_result = CACHE_COMBAT; break; */ case MT_TRANSPORT: $mission_result = flt_mission_transport($mission_data); break; case MT_HOLD: $mission_result = flt_mission_hold($mission_data); break; case MT_RELOCATE: $mission_result = flt_mission_relocate($mission_data); break; case MT_EXPLORE: $mission_result = flt_mission_explore($mission_data); break; case MT_RECYCLE: $mission_result = flt_mission_recycle($mission_data); break; case MT_COLONIZE: $mission_result = flt_mission_colonize($mission_data); break; case MT_SPY: $mission_result = flt_mission_spy($mission_data); break; case MT_MISSILE: // Missiles !! break; // default: // doquery("DELETE FROM `{{fleets}}` WHERE `fleet_id` = '{$fleet_row['fleet_id']}' LIMIT 1;"); // break; } sn_db_transaction_commit(); } sn_db_transaction_start(); $config->db_saveItem('fleet_update_last', SN_TIME_SQL); $config->db_saveItem('fleet_update_lock', ''); sn_db_transaction_commit(); // log_file('Закончили обсчёт флотов'); }
function que_delete($que_type, $user = array(), $planet = array(), $clear = false) { $planets_locked = array(); // TODO: Some checks sn_db_transaction_start(); $user = db_user_by_id($user['id'], true); $planet['id'] = $planet['id'] && $que_type !== QUE_RESEARCH ? $planet['id'] : 0; $global_que = que_get($user['id'], $planet['id'], $que_type, true); //pdump($global_que); //pdump($planet['id']); //pdump($global_que[$que_type][$planet['id']]); if (!empty($global_que['ques'][$que_type][$user['id']][$planet['id']])) { $que = array_reverse($global_que['ques'][$que_type][$user['id']][$planet['id']]); foreach ($que as $que_item) { db_que_delete_by_id($que_item['que_id']); if ($que_item['que_planet_id_origin']) { $planet['id'] = $que_item['que_planet_id_origin']; } if (!isset($planets_locked[$planet['id']])) { $planets_locked[$planet['id']] = $planet['id'] ? db_planet_by_id($planet['id'], true) : $planet; } $build_data = sys_unit_str2arr($que_item['que_unit_price']); db_change_units($user, $planets_locked[$planet['id']], array(RES_METAL => $build_data[RES_METAL] * $que_item['que_unit_amount'], RES_CRYSTAL => $build_data[RES_CRYSTAL] * $que_item['que_unit_amount'], RES_DEUTERIUM => $build_data[RES_DEUTERIUM] * $que_item['que_unit_amount'])); if (!$clear) { break; } } if (is_numeric($planet['id'])) { db_planet_set_by_id($planet['id'], "`que_processed` = UNIX_TIMESTAMP(NOW())"); } elseif (is_numeric($user['id'])) { db_user_set_by_id($user['id'], '`que_processed` = UNIX_TIMESTAMP(NOW())'); } sn_db_transaction_commit(); } else { sn_db_transaction_rollback(); } //die(); header("Location: {$_SERVER['PHP_SELF']}?mode={$que_type}" . "&ally_id=" . sys_get_param_id('ally_id')); }
function flt_t_send_fleet($user, &$from, $to, $fleet, $mission, $options = array()) { //ini_set('error_reporting', E_ALL); $internal_transaction = !sn_db_transaction_check(false) ? sn_db_transaction_start() : false; //pdump($internal_transaction); // TODO Потенциальный дедлок - если успела залочится запись пользователя - хозяина планеты $user = db_user_by_id($user['id'], true); $from = sys_o_get_updated($user, $from['id'], SN_TIME_NOW); $from = $from['planet']; $can_attack = flt_can_attack($from, $to, $fleet, $mission, $options); if ($can_attack != ATTACK_ALLOWED) { $internal_transaction ? sn_db_transaction_rollback() : false; return $can_attack; } $fleet_group = isset($options['fleet_group']) ? floatval($options['fleet_group']) : 0; $travel_data = flt_travel_data($user, $from, $to, $fleet, $options['fleet_speed_percent']); $fleet_start_time = SN_TIME_NOW + $travel_data['duration']; if ($mission == MT_EXPLORE || $mission == MT_HOLD) { $stay_duration = $options['stay_time'] * 3600; $stay_time = $fleet_start_time + $stay_duration; } else { $stay_duration = 0; $stay_time = 0; } $fleet_end_time = $fleet_start_time + $travel_data['duration'] + $stay_duration; $fleet_ship_count = 0; $fleet_string = ''; $db_changeset = array(); $planet_fields = array(); foreach ($fleet as $unit_id => $amount) { if (!$amount || !$unit_id) { continue; } if (in_array($unit_id, sn_get_groups('fleet'))) { $fleet_ship_count += $amount; $fleet_string .= "{$unit_id},{$amount};"; $db_changeset['unit'][] = sn_db_unit_changeset_prepare($unit_id, -$amount, $user, $from['id']); } elseif (in_array($unit_id, sn_get_groups('resources_loot'))) { $planet_fields[pname_resource_name($unit_id)]['delta'] -= $amount; } } $to['id_owner'] = intval($to['id_owner']); $QryInsertFleet = "INSERT INTO {{fleets}} SET "; $QryInsertFleet .= "`fleet_owner` = '{$user['id']}', "; $QryInsertFleet .= "`fleet_mission` = '{$mission}', "; $QryInsertFleet .= "`fleet_amount` = '{$fleet_ship_count}', "; $QryInsertFleet .= "`fleet_array` = '{$fleet_string}', "; $QryInsertFleet .= "`fleet_start_time` = '{$fleet_start_time}', "; if ($from['id']) { $QryInsertFleet .= "`fleet_start_planet_id` = '{$from['id']}', "; } $QryInsertFleet .= "`fleet_start_galaxy` = '{$from['galaxy']}', "; $QryInsertFleet .= "`fleet_start_system` = '{$from['system']}', "; $QryInsertFleet .= "`fleet_start_planet` = '{$from['planet']}', "; $QryInsertFleet .= "`fleet_start_type` = '{$from['planet_type']}', "; $QryInsertFleet .= "`fleet_end_time` = '{$fleet_end_time}', "; $QryInsertFleet .= "`fleet_end_stay` = '{$stay_time}', "; if ($to['id']) { $QryInsertFleet .= "`fleet_end_planet_id` = '{$to['id']}', "; } $QryInsertFleet .= "`fleet_end_galaxy` = '{$to['galaxy']}', "; $QryInsertFleet .= "`fleet_end_system` = '{$to['system']}', "; $QryInsertFleet .= "`fleet_end_planet` = '{$to['planet']}', "; $QryInsertFleet .= "`fleet_end_type` = '{$to['planet_type']}', "; $QryInsertFleet .= "`fleet_resource_metal` = " . floatval($fleet[RES_METAL]) . ", "; $QryInsertFleet .= "`fleet_resource_crystal` = " . floatval($fleet[RES_CRYSTAL]) . ", "; $QryInsertFleet .= "`fleet_resource_deuterium` = " . floatval($fleet[RES_DEUTERIUM]) . ", "; $QryInsertFleet .= "`fleet_target_owner` = '{$to['id_owner']}', "; $QryInsertFleet .= "`fleet_group` = '{$fleet_group}', "; $QryInsertFleet .= "`start_time` = " . SN_TIME_NOW . ";"; doquery($QryInsertFleet); $planet_fields[pname_resource_name(RES_DEUTERIUM)]['delta'] -= $travel_data['consumption']; $db_changeset['planets'][] = array('action' => SQL_OP_UPDATE, P_VERSION => 1, 'where' => array('id' => $from['id']), 'fields' => $planet_fields); db_changeset_apply($db_changeset); $internal_transaction ? sn_db_transaction_commit() : false; $from = db_planet_by_id($from['id']); return ATTACK_ALLOWED; //ini_set('error_reporting', E_ALL ^ E_NOTICE); }
protected function register() { // TODO РЕГИСТРАЦИЯ ВСЕГДА ДОЛЖНА ЛОГИНИТЬ ПОЛЬЗОВАТЕЛЯ! $this->flog('Регистрация: начинаем. Провайдер ' . $this->provider_id); try { if (!$this->is_register) { $this->flog('Регистрация: не выставлен флаг регистрации - пропускаем'); throw new Exception(LOGIN_UNDEFINED, ERR_ERROR); } $this->register_validate_input(); sn_db_transaction_start(); // $this->provider_account = new Account($this->db); // $this->account_check_duplicate_name_or_email($this->input_login_unsafe, $this->input_email_unsafe); $this->account->db_get_by_name_or_email($this->input_login_unsafe, $this->input_email_unsafe); if ($this->account->is_exists) { if ($this->account->account_email == $this->input_email_unsafe) { throw new Exception(REGISTER_ERROR_EMAIL_EXISTS, ERR_ERROR); } else { throw new Exception(REGISTER_ERROR_ACCOUNT_NAME_EXISTS, ERR_ERROR); } } // if($this->provider_account->db_get_by_name($this->input_login_unsafe)) { // throw new Exception(REGISTER_ERROR_ACCOUNT_NAME_EXISTS, ERR_ERROR); // } // // if($this->provider_account->db_get_by_email($this->input_email_unsafe)) { // throw new Exception(REGISTER_ERROR_EMAIL_EXISTS, ERR_ERROR); // } // Проблемы с созданием аккаунта - вызовут эксершн и обработается catch() $this->account->db_create($this->input_login_unsafe, $this->input_login_password_raw, $this->input_email_unsafe, $this->input_language_unsafe); // $this->db_account_create( // $this->input_login_unsafe, // $this->input_login_password_raw, // $this->input_email_unsafe, // $this->input_language_unsafe // ); // $this->data[F_ACCOUNT] = $this->db_account_get_by_id($account_id); // Устанавливать не надо - мы дальше пойдем по workflow $this->account_login_status = LOGIN_SUCCESS; $this->cookie_set(); // А вот это пока не нужно. Трансляцией аккаунтов в юзеров и созданием новых юзеров для новозашедших аккаунтов занимается Auth // $this->register_account(); sn_db_transaction_commit(); } catch (Exception $e) { sn_db_transaction_rollback(); $this->account_login_status == LOGIN_UNDEFINED ? $this->account_login_status = $e->getMessage() : false; } return $this->account_login_status; }
function payment_request_response() { global $debug; sn_db_transaction_start(); try { $response = $this->payment_request_process(); } catch (exception $e) { $response['result'] = $e->getCode(); $response['message'] = $e->getMessage(); } if ($response['result'] == SN_PAYMENT_REQUEST_OK) { sn_db_transaction_commit(); // $debug->warning('Результат операции: код ' . $response['result'] . ' сообщение "' . $response['message'] . '"', 'Ошибка платежа', LOG_INFO_PAYMENT); } else { sn_db_transaction_rollback(); $debug->warning('Результат операции: код ' . $response['result'] . ' сообщение "' . $response['message'] . '"', 'Ошибка платежа', LOG_INFO_PAYMENT); } // Переводим код результата из СН в код платежной системы if (is_array($this->result_translations) && !empty($this->result_translations)) { $response['result'] = isset($this->result_translations[$response['result']]) ? $this->result_translations[$response['result']] : $this->result_translations[SN_PAYMENT_REQUEST_UNDEFINED_ERROR]; } return $response; }
function sn_sys_planet_core_transmute(&$user, &$planetrow) { if (!sys_get_param_str('transmute')) { return array(); } global $lang; try { if ($planetrow['planet_type'] != PT_PLANET) { throw new exception($lang['ov_core_err_not_a_planet'], ERR_ERROR); } if ($planetrow['density_index'] == ($new_density_index = sys_get_param_id('density_type'))) { throw new exception($lang['ov_core_err_same_density'], ERR_WARNING); } sn_db_transaction_start(); $user = db_user_by_id($user['id'], true, '*'); $planetrow = db_planet_by_id($planetrow['id'], true, '*'); // $global_data = sys_o_get_updated($user, $planetrow['id'], SN_TIME_NOW); // $user = $global_data['user']; // $planetrow = $global_data['planet']; $planet_density_index = $planetrow['density_index']; $density_price_chart = planet_density_price_chart($planet_density_index); if (!isset($density_price_chart[$new_density_index])) { // Hack attempt throw new exception($lang['ov_core_err_denisty_type_wrong'], ERR_ERROR); } $user_dark_matter = mrc_get_level($user, false, RES_DARK_MATTER); $transmute_cost = get_unit_param(UNIT_PLANET_DENSITY, 'cost'); $transmute_cost = $transmute_cost[RES_DARK_MATTER] * $density_price_chart[$new_density_index]; if ($user_dark_matter < $transmute_cost) { throw new exception($lang['ov_core_err_no_dark_matter'], ERR_ERROR); } $sn_data_planet_density = sn_get_groups('planet_density'); foreach ($sn_data_planet_density as $key => $value) { if ($key == $new_density_index) { break; } $prev_density_index = $key; } $new_density = round(($sn_data_planet_density[$new_density_index][UNIT_PLANET_DENSITY] + $sn_data_planet_density[$prev_density_index][UNIT_PLANET_DENSITY]) / 2); rpg_points_change($user['id'], RPG_PLANET_DENSITY_CHANGE, -$transmute_cost, array('Planet %1$s ID %2$d at coordinates %3$s changed density type from %4$d "%5$s" to %6$d "%7$s". New density is %8$d kg/m3', $planetrow['name'], $planetrow['id'], uni_render_coordinates($planetrow), $planet_density_index, $lang['uni_planet_density_types'][$planet_density_index], $new_density_index, $lang['uni_planet_density_types'][$new_density_index], $new_density)); db_planet_set_by_id($planetrow['id'], "`density` = {$new_density}, `density_index` = {$new_density_index}"); sn_db_transaction_commit(); $planetrow['density'] = $new_density; $planetrow['density_index'] = $new_density_index; $result = array('STATUS' => ERR_NONE, 'MESSAGE' => sprintf($lang['ov_core_err_none'], $lang['uni_planet_density_types'][$planet_density_index], $lang['uni_planet_density_types'][$new_density_index], $new_density)); } catch (exception $e) { sn_db_transaction_rollback(); $result = array('STATUS' => $e->getCode(), 'MESSAGE' => $e->getMessage()); } return $result; }
function mrc_mercenary_hire($mode, $user, $mercenary_id) { global $config, $lang, $sn_powerup_buy_discounts; try { $is_permanent = $mode == UNIT_PLANS || !$config->empire_mercenary_temporary; $cost_alliance_multiplyer = SN_IN_ALLY === true && $mode == UNIT_PLANS ? $config->ali_bonus_members : 1; $cost_alliance_multiplyer = $cost_alliance_multiplyer >= 1 ? $cost_alliance_multiplyer : 1; if (!in_array($mercenary_id, sn_get_groups($mode == UNIT_PLANS ? 'plans' : 'mercenaries'))) { throw new Exception($lang['mrc_msg_error_wrong_mercenary'], ERR_ERROR); } if (!mrc_officer_accessible($user, $mercenary_id)) { throw new Exception($lang['mrc_msg_error_requirements'], ERR_ERROR); } $mercenary_level = sys_get_param_int('mercenary_level'); if ($mercenary_level < 0 || $mercenary_level > get_unit_param($mercenary_id, P_MAX_STACK)) { throw new Exception($lang['mrc_msg_error_wrong_level'], ERR_ERROR); } if ($mercenary_level && !array_key_exists($mercenary_period = sys_get_param_int('mercenary_period'), $sn_powerup_buy_discounts)) { throw new Exception($lang['mrc_msg_error_wrong_period'], ERR_ERROR); } sn_db_transaction_start(); $mercenary_level_old = mrc_get_level($user, $planetrow, $mercenary_id, true, true); if ($config->empire_mercenary_temporary && $mercenary_level_old && $mercenary_level) { throw new Exception($lang['mrc_msg_error_already_hired'], ERR_ERROR); // Can't hire already hired temp mercenary - dismiss first } elseif ($config->empire_mercenary_temporary && !$mercenary_level_old && !$mercenary_level) { throw new Exception('', ERR_NONE); // Can't dismiss (!$mercenary_level) not hired (!$mercenary_level_old) temp mercenary. But no error } if ($mercenary_level) { $darkmater_cost = eco_get_total_cost($mercenary_id, $mercenary_level); if (!$config->empire_mercenary_temporary && $mercenary_level_old) { $darkmater_cost_old = eco_get_total_cost($mercenary_id, $mercenary_level_old); $darkmater_cost[BUILD_CREATE][RES_DARK_MATTER] -= $darkmater_cost_old[BUILD_CREATE][RES_DARK_MATTER]; } $darkmater_cost = ceil($darkmater_cost[BUILD_CREATE][RES_DARK_MATTER] * $mercenary_period * $sn_powerup_buy_discounts[$mercenary_period] / $config->empire_mercenary_base_period); } else { $darkmater_cost = 0; } $darkmater_cost *= $cost_alliance_multiplyer; if (mrc_get_level($user, null, RES_DARK_MATTER) < $darkmater_cost) { throw new Exception($lang['mrc_msg_error_no_resource'], ERR_ERROR); } if ($darkmater_cost && $mercenary_level || !$is_permanent) { $unit_row = db_unit_by_location($user['id'], LOC_USER, $user['id'], $mercenary_id); if (is_array($unit_row) && ($dismiss_left_days = floor((strtotime($unit_row['unit_time_finish']) - SN_TIME_NOW) / PERIOD_DAY))) { $dismiss_full_cost = eco_get_total_cost($mercenary_id, $unit_row['unit_level']); $dismiss_full_cost = $dismiss_full_cost[BUILD_CREATE][RES_DARK_MATTER]; $dismiss_full_days = round((strtotime($unit_row['unit_time_finish']) - strtotime($unit_row['unit_time_start'])) / PERIOD_DAY); /* print(sprintf($lang['mrc_mercenary_dismissed_log'], $lang['tech'][$mercenary_id], $mercenary_id, $dismiss_full_cost, $dismiss_full_days, $unit_row['unit_time_start'], $unit_row['unit_time_finish'], $dismiss_left_days, floor($dismiss_full_cost * $dismiss_left_days / $dismiss_full_days) )); */ rpg_points_change($user['id'], RPG_MERCENARY_DISMISSED, 0, sprintf($lang['mrc_mercenary_dismissed_log'], $lang['tech'][$mercenary_id], $mercenary_id, $dismiss_full_cost, $dismiss_full_days, $unit_row['unit_time_start'], $unit_row['unit_time_finish'], $dismiss_left_days, floor($dismiss_full_cost * $dismiss_left_days / $dismiss_full_days))); } db_unit_list_delete($user['id'], LOC_USER, $user['id'], $mercenary_id); } if ($darkmater_cost && $mercenary_level) { db_unit_set_insert("unit_player_id = {$user['id']},\n unit_location_type = " . LOC_USER . ",\n unit_location_id = {$user['id']},\n unit_type = {$mode},\n unit_snid = {$mercenary_id},\n unit_level = {$mercenary_level},\n unit_time_start = " . (!$is_permanent ? 'FROM_UNIXTIME(' . SN_TIME_NOW . ')' : 'null') . ",\n unit_time_finish = " . (!$is_permanent ? 'FROM_UNIXTIME(' . (SN_TIME_NOW + $mercenary_period) . ')' : 'null')); rpg_points_change($user['id'], $mode == UNIT_PLANS ? RPG_PLANS : RPG_MERCENARY, -$darkmater_cost, sprintf($lang[$mode == UNIT_PLANS ? 'mrc_plan_bought_log' : 'mrc_mercenary_hired_log'], $lang['tech'][$mercenary_id], $mercenary_id, $darkmater_cost, round($mercenary_period / PERIOD_DAY))); } sn_db_transaction_commit(); sys_redirect($_SERVER['REQUEST_URI']); } catch (Exception $e) { sn_db_transaction_rollback(); $operation_result = array('STATUS' => in_array($e->getCode(), array(ERR_NONE, ERR_WARNING, ERR_ERROR)) ? $e->getCode() : ERR_ERROR, 'MESSAGE' => $e->getMessage()); } return $operation_result; }
protected function register_player_db_create($player_name_unsafe) { try { // Проверить корректность имени $this->register_player_name_validate($player_name_unsafe); sn_db_transaction_start(); // Проверить наличие такого имени в истории имён if (db_player_name_exists($player_name_unsafe)) { throw new Exception(REGISTER_ERROR_PLAYER_NAME_EXISTS, ERR_ERROR); } // Узнаем язык и емейл игрока $player_language = ''; $player_email = ''; // TODO - порнография - работа должна происходить над списком аккаунтов, а не только на одном аккаунте... foreach ($this->providers_authorised as $provider) { if (!$player_language && $provider->account->account_language) { $player_language = $provider->account->account_language; } if (!$player_email && $provider->account->account_email) { $player_email = $provider->account->account_email; } } $player_language = sys_get_param_str('lang') ? sys_get_param_str('lang') : $player_language; $player_language = $player_language ? $player_language : DEFAULT_LANG; // TODO - дописать эксепшнов в процедуре создания игрока self::$user = player_create($player_name_unsafe, $player_email, array('partner_id' => $partner_id = sys_get_param_int('id_ref', sys_get_param_int('partner_id')), 'language_iso' => static::$db->db_escape($player_language))); // Зарегестрировать на него аккаунты из self::$accounts_authorised $a_user = self::$user; foreach ($this->providers_authorised as $provider) { // TODO - порнография. Должен быть отдельный класс трансляторов - в т.ч. и кэширующий транслятор // TODO - ну и работа должна происходить над списком аккаунтов, а не только на одном аккаунте... // self::db_translate_register_user($provider->provider_id, $provider->account->account_id, $a_user['id']); PlayerToAccountTranslate::db_translate_register_user($provider->provider_id, $provider->account->account_id, $a_user['id']); } // Установить куку игрока self::cookie_set(self::$user['id']); sn_db_transaction_commit(); $this->register_status = LOGIN_SUCCESS; } catch (Exception $e) { sn_db_transaction_rollback(); // Если старое имя занято self::$user = null; $this->register_status == LOGIN_UNDEFINED ? $this->register_status = $e->getMessage() : false; } }
public function payment_request_response() { global $debug; $this->db = core_auth::$main_provider->db; $this->account = new Account($this->db); // TODO - REPLACE WITH INNATE CALL! sn_db_transaction_start(); try { $response = $this->payment_request_process(); } catch (Exception $e) { $response['result'] = $e->getCode(); $response['message'] = $e->getMessage(); } if ($response['result'] == SN_PAYMENT_REQUEST_OK) { sn_db_transaction_commit(); $debug->warning('Результат операции: код ' . $response['result'] . ' сообщение "' . $response['message'] . '"', 'Успешный платёж', LOG_INFO_PAYMENT); } else { sn_db_transaction_rollback(); $debug->warning('Результат операции: код ' . $response['result'] . ' сообщение "' . $response['message'] . '"', 'Ошибка платежа', LOG_INFO_PAYMENT, true); } // Переводим код результата из СН в код платежной системы if (is_array($this->result_translations) && !empty($this->result_translations)) { $response['result'] = isset($this->result_translations[$response['result']]) ? $this->result_translations[$response['result']] : $this->result_translations[SN_PAYMENT_REQUEST_UNDEFINED_ERROR]; } return $response; }
function sn_sec_login_register($username_unsafe, $password_raw, $email_unsafe, $language, $remember_me = 1, &$result) { global $lang, $config; sn_db_transaction_start(); try { if ($config->game_mode == GAME_BLITZ) { throw new exception(REGISTER_ERROR_USERNAME_WRONG, ERR_ERROR); } if (!$username_unsafe) { throw new exception(REGISTER_ERROR_USERNAME_WRONG, ERR_ERROR); } $username_safe = db_escape($username_unsafe); $db_check = doquery("SELECT `player_id` FROM {{player_name_history}} WHERE `player_name` = '{$username_safe}' LIMIT 1;", true); if (!empty($db_check)) { throw new exception(REGISTER_ERROR_USERNAME_EXISTS, ERR_ERROR); } if (strlen(trim($password_raw)) < 4 || strlen(trim($password_raw)) != strlen($password_raw)) { throw new exception(REGISTER_ERROR_PASSWORD_INSECURE, ERR_ERROR); } $password_raw = trim($password_raw); // $password_repeat_raw = trim(sys_get_param('password_repeat')); // if($password_raw <> $password_repeat_raw) { // throw new exception(REGISTER_ERROR_PASSWORD_DIFFERENT, ERR_ERROR); // } if (db_user_by_email($email_unsafe, true)) { throw new exception(REGISTER_ERROR_EMAIL_EXISTS, ERR_ERROR); } player_create($username_unsafe, $password_raw, $email_unsafe, array('partner_id' => $partner_id = sys_get_param_int('id_ref', sys_get_param_int('partner_id')), 'language_iso' => $language, 'remember_me' => $remember_me)); sn_db_transaction_commit(); $email_message = sprintf($lang['log_reg_email_text'], $config->game_name, SN_ROOT_VIRTUAL, sys_safe_output($username_unsafe), sys_safe_output($password_raw)); @mymail($email_unsafe, sprintf($lang['log_reg_email_title'], $config->game_name), $email_message); // sec_set_cookie_by_fields($user['id'], $user['username'], $user['password'], $remember_me); $result = REGISTER_SUCCESS; } catch (exception $e) { sn_db_transaction_rollback(); $result = $e->getMessage(); } return $result; }