$return_codes[] = 1006;
                error_log(__FILE__ . '::' . __LINE__ . " Query execution failed: (" . $db->get_db()->errno . ") " . $db->get_db()->error);
                break;
            }
        } else {
            // Insert
            if (!($st = $db->get_db()->prepare("insert into player_cargo (player, good, amount, bought) values (?, ?, ?, ?)"))) {
                $db->get_db()->rollback();
                $db->get_db()->autocommit(true);
                error_log(__FILE__ . '::' . __LINE__ . "Prepare failed: (" . $db->get_db()->errno . ") " . $db->get_db()->error);
                $return_codes[] = 1006;
                break;
            }
            $st->bind_param("iiii", $player_id, $good_id, $amount, $amount);
            if (!$st->execute()) {
                $db->get_db()->rollback();
                $db->get_db()->autocommit(true);
                $return_codes[] = 1006;
                error_log(__FILE__ . '::' . __LINE__ . " Query execution failed: (" . $db->get_db()->errno . ") " . $db->get_db()->error);
                break;
            }
            $cargo_id = $db->last_insert_id('player_cargo');
        }
        $db->get_db()->commit();
        $db->get_db()->autocommit(true);
        $action = $spacegame['actions'][$action_prefix . 'buy'];
        player_log($player_id, $action, $amount, $place_id);
        $return_codes[] = 1026;
        $return_vars['amt'] = $credits;
    }
} while (false);
/**
 * Performs an attack on a player
 *
 * @return boolean true if player is dead
 */
function players_attack_player($player_id, $hitters = array(), $already_in_a_transaction = false)
{
    if (!is_numeric($player_id) || $player_id <= 0) {
        error_log(__FILE__ . '::' . __LINE__ . ' - Player id is not a positive number greater than zero.');
        return false;
    }
    global $spacegame;
    global $db;
    $db = isset($db) ? $db : new DB();
    if (!$already_in_a_transaction) {
        $db->get_db()->autocommit(false);
    }
    $player = array();
    $rs = $db->get_db()->query("select caption, shields, armor, ship_type, ship_name from players where record_id = '{$player_id}'");
    $rs->data_seek(0);
    if ($row = $rs->fetch_assoc()) {
        $player = $row;
    }
    if ($player['ship_type'] <= 0) {
        // Player is in a pod, no further attacks necessary.
        if (!$already_in_a_transaction) {
            $db->get_db()->rollback();
            $db->get_db()->autocommit(true);
        }
        return true;
    }
    // Loop through hitters and attack player one by one
    foreach ($hitters as $hitter) {
        $shield_damage = 0;
        $armor_damage = 0;
        // Apply shield damage
        if (isset($hitter['shield_damage'])) {
            if ($player['shields'] > 0) {
                if ($player['shields'] >= $hitter['shield_damage']) {
                    $player['shields'] -= $hitter['shield_damage'];
                    $shield_damage += $hitter['shield_damage'];
                } else {
                    $shield_damage += $player['shields'];
                    $player['shields'] = 0;
                }
            }
        }
        // Apply general damage
        if (isset($hitter['damage'])) {
            // Buffer for extra damage to armor when shields are depleted
            $carryover = $hitter['damage'];
            if ($player['shields'] >= $hitter['damage']) {
                $player['shields'] -= $hitter['damage'];
                $shield_damage += $hitter['damage'];
                $carryover = 0;
            } else {
                $shield_damage += $player['shields'];
                $carryover = $hitter['damage'] - $player['shields'];
                $player['shields'] = 0;
            }
            if ($player['shields'] <= 0) {
                if ($player['armor'] >= $carryover) {
                    $player['armor'] -= $carryover;
                    $armor_damage += $carryover;
                } else {
                    $armor_damage += $player['armor'];
                    $player['armor'] = 0;
                }
            }
        }
        // Apply armor damage
        if (isset($hitter['armor_damage'])) {
            if ($player['shields'] <= 0) {
                if ($player['armor'] >= $hitter['armor_damage']) {
                    $player['armor'] -= $hitter['armor_damage'];
                    $armor_damage += $hitter['armor_damage'];
                } else {
                    $armor_damage += $player['armor'];
                    $player['armor'] = 0;
                }
            }
        }
        player_log($hitter['hitter'], $spacegame['actions']['damage'], $shield_damage + $armor_damage, $player_id);
        if ($player['armor'] <= 0) {
            // Dead player
            if (!($st = $db->get_db()->prepare('update players set ship_type = null, shields = 0, armor = 0, attack_rating = 1, shields_bonus = 0, armor_bonus = 0 where record_id = ?'))) {
                error_log(__FILE__ . '::' . __LINE__ . " Prepare failed: (" . $db->get_db()->errno . ") " . $db->get_db()->error);
                $return_codes[] = 1006;
                $db->get_db()->rollback();
                $db->get_db()->autocommit(true);
                return true;
            }
            $st->bind_param('i', $player_id);
            if (!$st->execute()) {
                $return_codes[] = 1006;
                error_log(__FILE__ . '::' . __LINE__ . " Query execution failed: (" . $st->errno . ") " . $st->error);
                $db->get_db()->rollback();
                $db->get_db()->autocommit(true);
                return true;
            }
            if (!($st = $db->get_db()->prepare('update player_cargo set amount = 0 where player = ?'))) {
                error_log(__FILE__ . '::' . __LINE__ . " Prepare failed: (" . $db->get_db()->errno . ") " . $db->get_db()->error);
                $return_codes[] = 1006;
                $db->get_db()->rollback();
                $db->get_db()->autocommit(true);
                return true;
            }
            $st->bind_param('i', $player_id);
            if (!$st->execute()) {
                $return_codes[] = 1006;
                error_log(__FILE__ . '::' . __LINE__ . " Query execution failed: (" . $st->errno . ") " . $st->error);
                $db->get_db()->rollback();
                $db->get_db()->autocommit(true);
                return true;
            }
            if (!$spacegame['gold']) {
                if (!($st = $db->get_db()->prepare("delete from solutions where player = ?"))) {
                    $db->get_db()->rollback();
                    $db->get_db()->autocommit(true);
                    error_log(__FILE__ . '::' . __LINE__ . " Prepare failed: (" . $db->get_db()->errno . ") " . $db->get_db()->error);
                    $return_codes[] = 1006;
                    break 2;
                }
                $st->bind_param("i", $player_id);
                if (!$st->execute()) {
                    $db->get_db()->rollback();
                    $db->get_db()->autocommit(true);
                    $return_codes[] = 1006;
                    error_log(__FILE__ . '::' . __LINE__ . " Query execution failed: (" . $db->get_db()->errno . ") " . $db->get_db()->error);
                    break 2;
                }
            }
            if (!$already_in_a_transaction) {
                if (!$db->get_db()->commit()) {
                    error_log(__FILE__ . '::' . __LINE__ . " Commit failed: (" . $db->get_db()->errno . ") " . $db->get_db()->error);
                }
                $db->get_db()->autocommit(true);
            }
            return true;
        }
        // Damage player
        if (!($st = $db->get_db()->prepare('update players set shields = ?, armor = ? where record_id = ?'))) {
            error_log(__FILE__ . '::' . __LINE__ . " Prepare failed: (" . $db->get_db()->errno . ") " . $db->get_db()->error);
            $return_codes[] = 1006;
            $db->get_db()->rollback();
            $db->get_db()->autocommit(true);
            break;
        }
        $st->bind_param('iii', $player['shields'], $player['armor'], $player_id);
        if (!$st->execute()) {
            $return_codes[] = 1006;
            error_log(__FILE__ . '::' . __LINE__ . " Query execution failed: (" . $st->errno . ") " . $st->error);
            $db->get_db()->rollback();
            $db->get_db()->autocommit(true);
            break;
        }
    }
    if (!$already_in_a_transaction) {
        if (!$db->get_db()->commit()) {
            error_log(__FILE__ . '::' . __LINE__ . " Commit failed: (" . $db->get_db()->errno . ") " . $db->get_db()->error);
        }
        $db->get_db()->autocommit(true);
    }
    return $player['armor'] <= 0;
}
            $total_damage = $hit_amount * DRONE_ATTACK_DAMAGE;
            if ($total_damage > 0) {
                $hitters[] = array('hitter' => $row['owner'], 'damage' => $total_damage);
                $return_vars['dmg'] = 'true';
            }
            $complete_count += $hit_amount;
            $complete_damage += $total_damage;
            // Message drone owners about potential damage to ship
            $message = '';
            $message .= 'Player ' . $spacegame['player']['caption'] . ' ';
            $message .= 'detected and engaged by ' . $hit_amount;
            $message .= ' drones in sector ' . $rx . ',' . $ry;
            $message .= ' causing ' . $total_damage . ' damage.';
            $targets = array($row['owner']);
            send_message($message, $targets, MESSAGE_EXPIRATION, 4);
        }
        // Message player about getting hit.
        if ($complete_damage > 0) {
            $message = '';
            $message .= 'You were engaged by ' . $complete_count . ' drones in sector ';
            $message .= $rx . ',' . $ry . ' causing ' . $complete_damage . ' damage.';
            $targets = array($player_id);
            send_message($message, $targets, MESSAGE_EXPIRATION, 4);
        }
        if (players_attack_player($player_id, $hitters)) {
            $serial = $ry * 1000 + $rx;
            player_log($player_id, $spacegame['actions']['death'], $complete_damage, $serial);
            break;
        }
    }
} while (false);
            $complete_count += $hit_amount;
            $complete_damage += $total_damage;
            // Message drone owners about potential damage to ship
            $message = '';
            $message .= 'Player ' . $spacegame['player']['caption'] . ' ';
            $message .= 'detected and engaged by ' . $hit_amount;
            $message .= ' drones in sector ' . $spacegame['player']['x'] . ',' . $spacegame['player']['y'];
            $message .= ' causing ' . $total_damage . ' damage.';
            if (players_attack_player($spacegame['player']['record_id'], $hitters)) {
                // Player is dead
                $serial = $spacegame['player']['y'] * 1000 + $spacegame['player']['x'];
                player_log($spacegame['player']['record_id'], $spacegame['actions']['death'], $total_damage, $serial);
            }
            $targets = array($player['record_id'], $spacegame['player']['record_id']);
            send_message($message, $targets, MESSAGE_EXPIRATION, 4);
        }
        $return_codes[] = 1205;
        $return_vars['amt'] = $total_damage;
    } else {
        $hitters[] = array('hitter' => $spacegame['player']['record_id'], 'shield_damage' => $player['shields'] - $player_shields, 'armor_damage' => $player['armor'] - $player_armor);
        if (players_attack_player($player_id, $hitters)) {
            // Player is dead
            $serial = $spacegame['player']['y'] * 1000 + $spacegame['player']['x'];
            player_log($player_id, $spacegame['actions']['death'], $total_damage, $serial);
        }
        $targets = array($player['record_id'], $spacegame['player']['record_id']);
        send_message($message, $targets, MESSAGE_EXPIRATION, 4);
        $return_codes[] = 1204;
        $return_vars['amt'] = $total_damage;
    }
} while (false);