function sn_RestoreFleetToPlanet(&$fleet_row, $start = true, $only_resources = false, $safe_fleet = false, &$result) { sn_db_transaction_check(true); $result = CACHE_NOTHING; if (!is_array($fleet_row)) { return $result; } $prefix = $start ? 'start' : 'end'; // Поскольку эта функция может быть вызвана не из обработчика флотов - нам надо всё заблокировать вроде бы НЕ МОЖЕТ!!! // TODO Проеверить от многократного срабатывания !!! // Тут не блокируем пока - сначала надо заблокировать пользователя, что бы не было дедлока // $fleet_row = doquery("SELECT * FROM {{fleets}} WHERE `fleet_id`='{$fleet_row['fleet_id']}' LIMIT 1", true); // Узнаем ИД владельца планеты - без блокировки // TODO поменять на владельца планеты - когда его будут возвращать всегда !!! $user_id = db_planet_by_vector($fleet_row, "fleet_{$prefix}_", false, 'id_owner'); $user_id = $user_id['id_owner']; // Блокируем пользователя $user = db_user_by_id($user_id, true); // Блокируем планету $planet_arrival = db_planet_by_vector($fleet_row, "fleet_{$prefix}_", true); // Блокируем флот // $fleet_row = doquery("SELECT * FROM {{fleets}} WHERE `fleet_id`='{$fleet_row['fleet_id']}' LIMIT 1 FOR UPDATE;", true); // Если флот уже обработан - не существует или возращается - тогда ничего не делаем if (!$fleet_row || !is_array($fleet_row) || $fleet_row['fleet_mess'] == 1 && $only_resources) { return $result; } // Флот, который возвращается на захваченную планету, пропадает if ($start && $fleet_row['fleet_mess'] == 1 && $planet_arrival['id_owner'] != $fleet_row['fleet_owner']) { doquery("DELETE FROM {{fleets}} WHERE `fleet_id`='{$fleet_row['fleet_id']}' LIMIT 1;"); return $result; } //pdump($planet_arrival); $db_changeset = array(); if (!$only_resources) { flt_destroy($fleet_row); if ($fleet_row['fleet_owner'] == $planet_arrival['id_owner']) { $fleet_array = sys_unit_str2arr($fleet_row['fleet_array']); foreach ($fleet_array as $ship_id => $ship_count) { if ($ship_count) { $db_changeset['unit'][] = sn_db_unit_changeset_prepare($ship_id, $ship_count, $user, $planet_arrival['id']); } } } else { return CACHE_NOTHING; } } else { // flt_send_back($fleet_row); doquery("UPDATE {{fleets}} SET fleet_resource_metal = 0, fleet_resource_crystal = 0, fleet_resource_deuterium = 0, fleet_mess = 1 WHERE `fleet_id`='{$fleet_row['fleet_id']}' LIMIT 1;"); } if (!empty($db_changeset)) { db_changeset_apply($db_changeset); } db_planet_set_by_id($planet_arrival['id'], "`metal` = `metal` + '{$fleet_row['fleet_resource_metal']}', `crystal` = `crystal` + '{$fleet_row['fleet_resource_crystal']}', `deuterium` = `deuterium` + '{$fleet_row['fleet_resource_deuterium']}'"); $result = CACHE_FLEET | ($start ? CACHE_PLANET_SRC : CACHE_PLANET_DST); return $result; }
function db_player_name_exists($player_name_unsafe) { sn_db_transaction_check(true); $player_name_safe = classSupernova::$db->db_escape($player_name_unsafe); $player_name_exists = classSupernova::$db->doquery("SELECT * FROM `{{player_name_history}}` WHERE `player_name` = '{$player_name_safe}' LIMIT 1 FOR UPDATE", true); return !empty($player_name_exists); }
/** * Copyright (c) 2009-2010 by Gorlum for http://supernova.ws * OpenSource as long as you don't remove this Copyright * V3 2009-11-13 * V2 2009-10-10 */ function coe_o_missile_calculate() { sn_db_transaction_check(true); global $lang; $iraks = doquery("SELECT * FROM {{iraks}} WHERE `fleet_end_time` <= " . SN_TIME_NOW . " FOR UPDATE;"); while ($fleetRow = db_fetch($iraks)) { set_time_limit(15); $db_changeset = array(); $targetUser = db_user_by_id($fleetRow['fleet_target_owner'], true); $target_planet_row = sys_o_get_updated($targetUser, array('galaxy' => $fleetRow['fleet_end_galaxy'], 'system' => $fleetRow['fleet_end_system'], 'planet' => $fleetRow['fleet_end_planet'], 'planet_type' => PT_PLANET), SN_TIME_NOW); $target_planet_row = $target_planet_row['planet']; $rowAttacker = db_user_by_id($fleetRow['fleet_owner'], true); if ($target_planet_row['id']) { $planetDefense = array(); foreach (sn_get_groups('defense_active') as $unit_id) { $planetDefense[$unit_id] = array(mrc_get_level($targetUser, $target_planet_row, $unit_id, true, true)); } $message = ''; $interceptors = mrc_get_level($targetUser, $target_planet_row, UNIT_DEF_MISSILE_INTERCEPTOR, true, true); //$target_planet_row[$interceptor_db_name]; // Number of interceptors $missiles = $fleetRow['fleet_amount']; // Number of MIP if ($interceptors >= $missiles) { $message = $lang['mip_all_destroyed']; $db_changeset['unit'][] = sn_db_unit_changeset_prepare(UNIT_DEF_MISSILE_INTERCEPTOR, -$missiles, $targetUser, $target_planet_row['id']); } else { if ($interceptors) { $message = sprintf($lang['mip_destroyed'], $interceptors); $db_changeset['unit'][] = sn_db_unit_changeset_prepare(UNIT_DEF_MISSILE_INTERCEPTOR, -$interceptors, $targetUser, $target_planet_row['id']); } // $message .= $lang['mip_defense_destroyed']; $attackResult = COE_missileAttack($targetUser, $rowAttacker, $missiles - $interceptors, $planetDefense, $fleetRow['primaer']); foreach ($attackResult['structures'] as $key => $structure) { $destroyed = $planetDefense[$key][0] - $structure[0]; if ($destroyed) { $db_changeset['unit'][] = sn_db_unit_changeset_prepare($key, -$destroyed, $targetUser, $target_planet_row['id']); $message .= " {$lang['tech'][$key]} - {$destroyed} {$lang['quantity']}<br>"; } } if (!empty($message)) { $message = $lang['mip_defense_destroyed'] . $message . "{$lang['mip_recycled']}{$lang['Metal']}: {$attackResult['metal']}, {$lang['Crystal']}: {$attackResult['crystal']}<br>"; db_planet_set_by_id($target_planet_row['id'], "`metal` = `metal` + {$attackResult['metal']}, `crystal` = `crystal` + {$attackResult['crystal']}"); } // $message .= "{$lang['mip_recycled']}{$lang['Metal']}: {$attackResult['metal']}, {$lang['Crystal']}: {$attackResult['crystal']}<br>"; } db_changeset_apply($db_changeset); $fleetRow['fleet_start_type'] = PT_PLANET; $sourcePlanet = db_planet_by_vector($fleetRow, 'fleet_start_', false, 'name'); $message_vorlage = sprintf($lang['mip_body_attack'], $fleetRow['fleet_amount'], addslashes($sourcePlanet['name']), $fleetRow['fleet_start_galaxy'], $fleetRow['fleet_start_system'], $fleetRow['fleet_start_planet'], addslashes($target_planet_row['name']), $fleetRow['fleet_end_galaxy'], $fleetRow['fleet_end_system'], $fleetRow['fleet_end_planet']); empty($message) ? $message = $lang['mip_no_defense'] : false; // empty($message) && ($message = $lang['mip_no_defense']); msg_send_simple_message($fleetRow['fleet_owner'], '', SN_TIME_NOW, MSG_TYPE_SPY, $lang['mip_sender_amd'], $lang['mip_subject_amd'], $message_vorlage . $message); msg_send_simple_message($fleetRow['fleet_target_owner'], '', SN_TIME_NOW, MSG_TYPE_SPY, $lang['mip_sender_amd'], $lang['mip_subject_amd'], $message_vorlage . $message); } doquery("DELETE FROM {{iraks}} WHERE id = '{$fleetRow['id']}';"); } }
function que_process(&$user, $planet = null, $on_time = SN_TIME_NOW) { sn_db_transaction_check(true); $que = array(); // Блокируем пользователя. Собственно, запись о нём нам не нужна - будем использовать старую $user = db_user_by_id($user['id'], true); $time_left[$user['id']][0] = max(0, $on_time - $user['que_processed']); if ($planet === null && !$time_left[$user['id']][0]) { // TODO return $que; } // Определяем, какие очереди нам нужны и получаем их $que_type_id = $planet === null ? QUE_RESEARCH : false; $planet = intval(is_array($planet) ? $planet['id'] : $planet); // В $planet у нас теперь только её ID или шаблон null/0/false $que = que_get($user['id'], $planet, $que_type_id, true); //pdump($que); if (empty($que['items'])) { return $que; } $planet_list = array(); if ($planet !== null) { // Если нужно изменять данные на планетах - блокируем планеты и получаем данные о них // TODO - от них не надо ничего, кроме ID и que_processed // $planet_query = db_planet_list_by_user_or_planet($user['id'], $planet); // foreach($planet_query as $planet_row) $planet_row = db_planet_list_by_user_or_planet($user['id'], $planet); $planet_list[$planet_row['id']] = $planet_row; $time_left[$planet_row['id_owner']][$planet_row['id']] = max(0, $on_time - $planet_row['que_processed']); } // pdump($time_left); // Теперь в $time_left лежит время обсчета всех очередей по каждой из планеты if (array_sum($time_left[$user['id']]) == 0) { return $que; } // pdump($que); $db_changeset = array(); $unit_changes = array(); foreach ($que['items'] as &$que_item) { $que_player_id =& $que_item['que_player_id']; $que_planet_id = intval($que_item['que_planet_id']); // $que_type = &$que_item['que_type']; $que_time_left =& $que['time_left'][$que_player_id][$que_planet_id][$que_item['que_type']]; if (!isset($que_time_left)) { $que_time_left = $time_left[$que_player_id][$que_planet_id]; } if ($que_time_left <= 0 || $que_item['que_unit_amount'] <= 0) { continue; } // Дальше мы идем, если только осталось время в очереди И юниты к постройке // Вычисляем, сколько целых юнитов будет построено - от 0 до количества юнитов в очереди $unit_processed = min($que_item['que_unit_amount'] - 1, floor($que_time_left / $que_item['que_unit_time'])); // Вычитаем это время из остатков $que_time_left -= $unit_processed * $que_item['que_unit_time']; // Теперь работаем с остатком времени на юните. Оно не может быть равно или меньше нуля // Если времени в очереди осталось не меньше, чем время текущего юнита - значит мы достроили юнит if ($que_time_left >= $que_item['que_time_left']) { // Увеличиваем количество отстроенных юнитов $unit_processed++; // Вычитаем из времени очереди потраченное на постройку время $que_time_left -= $que_item['que_time_left']; // Полное время юнита равно времени нового юнита $que_item['que_time_left'] = $que_item['que_unit_time']; // Тут у нас может остатся время очереди - если постройка была не последняя } // Изменяем количество оставшихся юнитов $que_item['que_unit_amount'] -= $unit_processed; // Если еще остались юниты - значит ВСЁ оставшееся время приходится на достройку следующего юнита if ($que_item['que_unit_amount'] > 0) { $que_item['que_time_left'] = $que_item['que_time_left'] - $que_time_left; $que_time_left = 0; } if ($que_item['que_unit_amount'] <= 0) { $db_changeset['que'][] = array('action' => SQL_OP_DELETE, P_VERSION => 1, 'where' => array("que_id" => $que_item['que_id'])); } else { $db_changeset['que'][] = array('action' => SQL_OP_UPDATE, P_VERSION => 1, 'where' => array("que_id" => $que_item['que_id']), 'fields' => array('que_unit_amount' => array('delta' => -$unit_processed), 'que_time_left' => array('set' => $que_item['que_time_left']))); } if ($unit_processed) { $unit_processed_delta = $unit_processed * ($que_item['que_unit_mode'] == BUILD_CREATE ? 1 : -1); $unit_changes[$que_player_id][$que_planet_id][$que_item['que_unit_id']] += $unit_processed_delta; } } foreach ($time_left as $player_id => $planet_data) { foreach ($planet_data as $planet_id => $time_on_planet) { $table = $planet_id ? 'planets' : 'users'; $id = $planet_id ? $planet_id : $player_id; $db_changeset[$table][] = array('action' => SQL_OP_UPDATE, P_VERSION => 1, 'where' => array("id" => $id), 'fields' => array('que_processed' => array('set' => $on_time))); if (is_array($unit_changes[$player_id][$planet_id])) { foreach ($unit_changes[$player_id][$planet_id] as $unit_id => $unit_amount) { $db_changeset['unit'][] = sn_db_unit_changeset_prepare($unit_id, $unit_amount, $user, $planet_id ? $planet_id : null); } } } } //pdump($db_changeset, '$db_changeset'); $que = que_recalculate($que); //pdump($que, '$que'); // TODO: Re-enable quests for Alliances if (!empty($unit_changes) && !$user['user_as_ally']) { $quest_list = qst_get_quests($user['id']); $quest_triggers = qst_active_triggers($quest_list); $quest_rewards = array(); $xp_incoming = array(); foreach ($unit_changes as $user_id => $planet_changes) { foreach ($planet_changes as $planet_id => $changes) { $planet_this = $planet_id ? classSupernova::db_get_record_by_id(LOC_PLANET, $planet_id) : array(); foreach ($changes as $unit_id => $unit_value) { $que_id = que_get_unit_que($unit_id); $unit_level_new = mrc_get_level($user, $planet_this, $unit_id, false, true) + $unit_value; if ($que_id == QUE_STRUCTURES || $que_id == QUE_RESEARCH) { $build_data = eco_get_build_data($user, $planet_this, $unit_id, $unit_level_new - 1); $build_data = $build_data[BUILD_CREATE]; foreach (sn_get_groups('resources_loot') as $resource_id) { $xp_incoming[$que_id] += $build_data[$resource_id]; // TODO - добавить конверсию рейтов обмена } } if (is_array($quest_triggers)) { // TODO: Check mutiply condition quests $quest_trigger_list = array_keys($quest_triggers, $unit_id); if (is_array($quest_trigger_list)) { foreach ($quest_trigger_list as $quest_id) { if ($quest_list[$quest_id]['quest_status_status'] != QUEST_STATUS_COMPLETE && $quest_list[$quest_id]['quest_unit_amount'] <= $unit_level_new) { $quest_rewards[$quest_id][$user_id][$planet_id] = $quest_list[$quest_id]['quest_rewards_list']; $quest_list[$quest_id]['quest_status_status'] = QUEST_STATUS_COMPLETE; } } } } } } } // TODO: Изменить начисление награды за квесты на ту планету, на которой происходил ресеч qst_reward($user, $quest_rewards, $quest_list); foreach ($xp_incoming as $que_id => $xp) { rpg_level_up($user, $que_id == QUE_RESEARCH ? RPG_TECH : RPG_STRUCTURE, $xp / 1000); } } db_changeset_apply($db_changeset); // TODO Сообщения о постройке // $user = db_user_by_id($user['id'], true); return $que; /* // $local_que['time_left'][QUE_RESEARCH][0] = $time_left[QUE_RESEARCH][0]; //pdump($user_time_left, '$user_time_left'); print('1'); //foreach($local_que as $que_id => &$que_data) //{ // if(!intval($que_id))continue; foreach(sn_get_groups('que') as $que_id => $que_info) { if(!isset($que['ques'][$que_id]))continue; foreach($que_data as $owner_id => &$que_items) { foreach($que_items as &$que_item) { // Вычисляем, сколько целых юнитов будет построено - от 0 до количества юнитов в очереди $unit_processed = min($que_item['que_unit_amount'] - 1, floor($local_que['time_left'][$que_id][$owner_id] / $que_item['que_unit_time'])); // Вычитаем это время из остатков $local_que['time_left'][$que_id][$owner_id] -= $unit_processed * $que_item['que_unit_time']; // Теперь работаем с остатком времени на юните. Оно не может быть равно или меньше нуля // Вычитаем остаток времени работы очереди с времени постройки юнита if($que_item['que_time_left'] <= $local_que['time_left'][$que_id][$owner_id]) { // Если время постройки - неположительное, значит мы достроили юнит // Увеличиваем количество отстроенных юнитов $unit_processed++; // Вычитаем из времени очереди потраченное на постройку время $local_que['time_left'][$que_id][$owner_id] -= $que_item['que_time_left']; $que_item['que_time_left'] = $que_item['que_unit_time']; // Тут у нас может остатся время очереди - если постройка была не последняя } // Изменяем количество оставшихся юнитов $que_item['que_unit_amount'] -= $unit_processed; if($que_item['que_unit_amount']) { $que_item['que_time_left'] = $que_item['que_time_left'] - $local_que['time_left'][$que_id][$owner_id]; $local_que['time_left'][$que_id][$owner_id] = 0; } if(!$que_item['que_unit_amount']) { $db_changeset['que'][$que_item['que_id']] = array( 'action' => SQL_OP_DELETE, 'where' => array( "`que_id` = {$que_item['que_id']}", ), ); } else { $db_changeset['que'][$que_item['que_id']] = array( 'action' => SQL_OP_UPDATE, 'where' => array( "`que_id` = {$que_item['que_id']}", ), 'fields' => array( 'que_unit_amount' => array( 'delta' => -$unit_processed ), 'que_time_left' => array( 'set' => $que_item['que_time_left'] ), ), ); } if($unit_processed) { $unit_processed_delta = $unit_processed * ($que_item['que_unit_mode'] == BUILD_CREATE ? 1 : -1); $unit_changes[$owner_id][$que_item['que_unit_id']] += $unit_processed_delta; } // Если на очереди времени не осталось - выходим if(!$local_que['time_left'][$que_id][$owner_id]) { break; } } } } die(); // TODO: Re-enable quests for Alliances if(!empty($unit_changes) && !$user['user_as_ally'] && $user['id_planet']) { $planet = db_planet_by_id($user['id_planet'], true); $quest_list = qst_get_quests($user['id']); $quest_triggers = qst_active_triggers($quest_list); } else { $planet = array(); } $quest_rewards = array(); $xp_incoming = 0; foreach($unit_changes as $owner_id => $changes) { // $user_id_sql = $owner_id ? $owner_id : $user['id']; $planet_id_sql = $owner_id ? $owner_id : null; foreach($changes as $unit_id => $unit_value) { $db_changeset['unit'][] = sn_db_unit_changeset_prepare($unit_id, $unit_value, $user, $planet_id_sql); // TODO: Изменить согласно типу очереди $unit_level_new = mrc_get_level($user, array(), $unit_id, false, true) + $unit_value; $build_data = eco_get_build_data($user, array(), $unit_id, $unit_level_new - 1); $build_data = $build_data[BUILD_CREATE]; foreach(sn_get_groups('resources_loot') as $resource_id) { $xp_incoming += $build_data[$resource_id]; } if($planet['id']) { // TODO: Check mutiply condition quests $quest_trigger_list = array_keys($quest_triggers, $unit_id); foreach($quest_trigger_list as $quest_id) { if($quest_list[$quest_id]['quest_status_status'] != QUEST_STATUS_COMPLETE && $quest_list[$quest_id]['quest_unit_amount'] <= $unit_level_new) { $quest_rewards[$quest_id] = $quest_list[$quest_id]['quest_rewards']; $quest_list[$quest_id]['quest_status_status'] = QUEST_STATUS_COMPLETE; } } } } } // TODO: Изменить согласно типу очереди rpg_level_up($user, RPG_TECH, $xp_incoming / 1000); // TODO: Изменить начисление награды за квесты на ту планету, на которой происходил ресеч qst_reward($user, $planet, $quest_rewards, $quest_list); db_changeset_apply($db_changeset); // Сообщения о постройке $user = db_user_by_id($user['id'], true); // TODO Так же пересчитывать планеты // sn_db_transaction_commit(); // TODO поменять que_processed у планеты и юзера return $local_que; */ }
function player_create($username_unsafe, $email_unsafe, $options) { sn_db_transaction_check(true); global $config, $lang; static $player_options_string = 'opt_mnl_spy^1|opt_email_mnl_spy^0|opt_email_mnl_joueur^0|opt_email_mnl_alliance^0|opt_mnl_attaque^1|opt_email_mnl_attaque^0|opt_mnl_exploit^1|opt_email_mnl_exploit^0|opt_mnl_transport^1|opt_email_mnl_transport^0|opt_email_msg_admin^1|opt_mnl_expedition^1|opt_email_mnl_expedition^0|opt_mnl_buildlist^1|opt_email_mnl_buildlist^0|opt_int_navbar_resource_force^1|'; empty($options['planet_options']) ? $options['planet_options'] = array() : false; $field_set = array('server_name' => SN_ROOT_VIRTUAL, 'register_time' => SN_TIME_NOW, 'user_bot' => $options['user_bot'] = empty($options['user_bot']) ? USER_BOT_PLAYER : $options['total_points'], 'username' => $username_unsafe, 'email' => $email_unsafe, 'email_2' => $email_unsafe, 'lang' => $options['language_iso'] ? $options['language_iso'] : DEFAULT_LANG, 'dpath' => DEFAULT_SKINPATH, 'total_points' => $options['total_points'] = empty($options['total_points']) ? 0 : $options['total_points'], 'options' => (empty($options['options']) ? $player_options_string : $options['options']) . (empty($options['options_extra']) ? '' : $options['options_extra']), 'galaxy' => $options['galaxy'] = intval($options['galaxy'] ? $options['galaxy'] : 0), 'system' => $options['system'] = intval($options['system'] ? $options['system'] : 0), 'planet' => $options['planet'] = intval($options['planet'] ? $options['planet'] : 0)); !empty($options['salt']) ? $field_set['salt'] = $options['salt'] : false; !empty($options['password_encoded_unsafe']) ? $field_set['password'] = $options['password_encoded_unsafe'] : false; $user_new = classSupernova::db_ins_field_set(LOC_USER, $field_set); if (!($options['galaxy'] && $options['system'] && $options['planet'])) { $options['galaxy'] = $config->LastSettedGalaxyPos; $options['system'] = $config->LastSettedSystemPos; $segment_size = floor($config->game_maxPlanet / 3); $segment = floor($config->LastSettedPlanetPos / $segment_size); $segment++; $options['planet'] = mt_rand(1 + $segment * $segment_size, ($segment + 1) * $segment_size); // $new_planet_id = 0; while (true) { if ($options['planet'] > $config->game_maxPlanet) { $options['planet'] = mt_rand(0, $segment_size - 1) + 1; $options['system']++; } if ($options['system'] > $config->game_maxSystem) { $options['system'] = 1; $options['galaxy']++; } $options['galaxy'] > $config->game_maxGalaxy ? $options['galaxy'] = 1 : false; $galaxy_row = db_planet_by_gspt($options['galaxy'], $options['system'], $options['planet'], PT_PLANET, true, 'id'); if (!$galaxy_row['id']) { $config->db_saveItem(array('LastSettedGalaxyPos' => $options['galaxy'], 'LastSettedSystemPos' => $options['system'], 'LastSettedPlanetPos' => $options['planet'])); // $new_planet_id = uni_create_planet($options['galaxy'], $options['system'], $options['planet'], $user_new['id'], $username_unsafe . ' ' . $lang['sys_capital'], true, $options['planet_options']); break; } $options['planet'] += 3; } } $new_planet_id = uni_create_planet($options['galaxy'], $options['system'], $options['planet'], $user_new['id'], $lang['sys_capital'], true, $options['planet_options']); // db_user_set_by_id($user_new['id'], // "`id_planet` = '{$new_planet_id}', `current_planet` = '{$new_planet_id}', // `galaxy` = '{$options['galaxy']}', `system` = '{$options['$system']}', `planet` = '{$options['$planet']}', // `parent_account_id` = {$account['account_id']}" // ); db_user_set_by_id($user_new['id'], "`id_planet` = '{$new_planet_id}', `current_planet` = '{$new_planet_id}',\n `galaxy` = '{$options['galaxy']}', `system` = '{$options['system']}', `planet` = '{$options['planet']}'"); $config->db_saveItem('users_amount', $config->users_amount + 1); $username_safe = db_escape($username_unsafe); doquery("REPLACE INTO {{player_name_history}} SET `player_id` = {$user_new['id']}, `player_name` = '{$username_safe}'"); if (!empty($options['partner_id']) && ($referral_row = db_user_by_id($options['partner_id'], true))) { doquery("INSERT INTO {{referrals}} SET `id` = {$user_new['id']}, `id_partner` = {$options['partner_id']}"); } sys_player_new_adjust($user_new['id'], $new_planet_id); return $result = db_user_by_id($user_new['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); }
function sys_o_get_updated($user, $planet, $UpdateTime, $simulation = false, $no_user_update = false) { sn_db_transaction_check(true); $no_data = array('user' => false, 'planet' => false, 'que' => false); if (!$planet) { return $no_data; } if (!$no_user_update) { $user = intval(is_array($user) && $user['id'] ? $user['id'] : $user); if (!$user) { // TODO - Убрать позже print '<h1>СООБЩИТЕ ЭТО АДМИНУ: sys_o_get_updated() - USER пустой!</h1>'; $backtrace = debug_backtrace(); array_shift($backtrace); pdump($backtrace); die; } $user = db_user_by_id($user, !$simulation, '*', true); } if (empty($user['id'])) { return $no_data; } if (is_array($planet) && isset($planet['galaxy']) && $planet['galaxy']) { $planet = db_planet_by_vector($planet, '', !$simulation); } else { $planet = intval(is_array($planet) && isset($planet['id']) ? $planet['id'] : $planet); $planet = db_planet_by_id($planet, !$simulation); } if (!is_array($planet) || !isset($planet['id'])) { return $no_data; } $que = que_process($user, $planet, $UpdateTime); $ProductionTime = max(0, $UpdateTime - $planet['last_update']); $planet['prev_update'] = $planet['last_update']; $planet['last_update'] += $ProductionTime; /* $que = eco_que_process($user, $planet, $ProductionTime); $hangar_built = $ProductionTime && !$simulation ? eco_bld_que_hangar($user, $planet, $ProductionTime) : array(); */ // TODO ЭТО НАДО ДЕЛАТЬ ТОЛЬКО ПРИ СПЕЦУСЛОВИЯХ $caps_real = eco_get_planet_caps($user, $planet, $ProductionTime); $resources_increase = array(RES_METAL => 0, RES_CRYSTAL => 0, RES_DEUTERIUM => 0); switch ($planet['planet_type']) { case PT_PLANET: foreach ($resources_increase as $resource_id => &$increment) { $resource_name = pname_resource_name($resource_id); $increment = $caps_real['total'][$resource_id] * $ProductionTime / 3600; $store_free = $caps_real['total_storage'][$resource_id] - $planet[$resource_name]; $increment = min($increment, max(0, $store_free)); if ($planet[$resource_name] + $increment < 0 && !$simulation) { global $debug; $debug->warning("Player ID {$user['id']} have negative resources on ID {$planet['id']}.{$planet['planet_type']} [{$planet['galaxy']}:{$planet['system']}:{$planet['planet']}]. Difference {$planet[$resource_name]} of {$resource_name}", 'Negative Resources', 501); } $planet[$resource_name] += $increment; $planet[$resource_name . '_perhour'] = $caps_real['total'][$resource_id]; } break; case PT_MOON: default: $planet['metal_perhour'] = 0; $planet['crystal_perhour'] = 0; $planet['deuterium_perhour'] = 0; $planet['energy_used'] = 0; $planet['energy_max'] = 0; break; } // TODO пересчитывать размер планеты только при постройке чего-нибудь и при покупке сектора $planet['field_current'] = 0; $sn_group_build_allow = sn_get_groups('build_allow'); if (is_array($sn_group_build_allow[$planet['planet_type']])) { foreach ($sn_group_build_allow[$planet['planet_type']] as $building_id) { $planet['field_current'] += mrc_get_level($user, $planet, $building_id, !$simulation, true); } } if ($simulation) { return array('user' => $user, 'planet' => $planet, 'que' => $que); } db_planet_set_by_id($planet['id'], "`last_update` = '{$planet['last_update']}', `field_current` = {$planet['field_current']},\n `metal` = `metal` + '{$resources_increase[RES_METAL]}', `crystal` = `crystal` + '{$resources_increase[RES_CRYSTAL]}', `deuterium` = `deuterium` + '{$resources_increase[RES_DEUTERIUM]}',\n `metal_perhour` = '{$planet['metal_perhour']}', `crystal_perhour` = '{$planet['crystal_perhour']}', `deuterium_perhour` = '{$planet['deuterium_perhour']}',\n `energy_used` = '{$planet['energy_used']}', `energy_max` = '{$planet['energy_max']}'"); return array('user' => $user, 'planet' => $planet, 'que' => $que); }