```pawn
// == == == == [ Инклуды ] == == == ==
#include <a_samp>
#include <a_mysql>
#include <Pawn.CMD>
#include <streamer>
#include <foreach>

// == == == == [ Константы и Перечисления ] == == ====

#define MAX_DB_STRING 256

// MySQL БД
new const MYSQL_HOST[] = "127.0.0.1";
new const MYSQL_USER[] = "root";
new const MYSQL_PASS[] = "";
new const MYSQL_DB[] = "new";

// Диалоговые стили
enum DialogStyles {
    DS_LIST = DIALOG_STYLE_LIST,
    DS_INPUT = DIALOG_STYLE_INPUT,
    DS_MSGBOX = DIALOG_STYLE_MSGBOX,
    DS_PASSWORD = DIALOG_STYLE_PASSWORD
};

// Цвета
enum Colors {
    COLOR_BROWN = 0xA52A2AFF,
    COLOR_BLUE = 0x00BFFFFF,
    COLOR_CRIMSON = 0xDC143CFF,
    COLOR_CHOCOLATE = 0xD2691EFF,
    COLOR_FIREBRICK = 0xB22222FF,
    COLOR_GREY = 0x999999FF,
    COLOR_GREEN = 0x008000FF,
    COLOR_LIMEGREEN = 0x00FF00FF,
    COLOR_MAROON = 0x800000FF,
    COLOR_ORANGE = 0xDF8600FF,
    COLOR_ORANGERED = 0xFF4500FF,
    COLOR_PURPLE = 0x800080FF,
    COLOR_RED = 0xFF0000FF,
    COLOR_WHITE = 0xFFFFFFFF,
    COLOR_YELLOW = 0xFFFF00FF,
    COLOR_LIGHTRED = 0xFF463CFF
};

// Макросы
#define TOGGLE_CONTROLLABLE(player, state) TogglePlayerControllable(player, state)
#define KICK_PLAYER(player) SetTimerEx("TimeKick", 80, false, "i", player)
#define IS_NULL(str) ((!(str[0])) || (((str[0]) == '\1') && (!(str[1]))))

// == == == == [ Структуры ] == == ====

// Структура для хранения информации о игроке
struct PlayerInfo {
    int ID;
    char Name[MAX_PLAYER_NAME + 1];
    char Pass[33];
    char Email[47];
    char Referal[MAX_PLAYER_NAME + 1];
    char DateReg[11];
    int Nations;
    int Age;
    int Sex;
    int Skin;
    int Money;
    int Level;
};

// Массив структур для хранения информации об игроках
new PlayerInfo: pInfo[MAX_PLAYERS];

// == == == == [ Переменные ] == == ====

new dbHandle;

// Текстдроиды для логотипа
new Text:Textdraw0, Textdraw1, Textdraw2, Textdraw3, Textdraw4, Textdraw5;

// Переменные для обработки выбора скинов
new number_skin[MAX_PLAYERS];
new bool:login_check[MAX_PLAYERS];

// Таймеры
new update_timer[MAX_PLAYERS];
new login_timer[MAX_PLAYERS];

// Селекторы текстдроев для выбора скина
new Text:select_skin[MAX_PLAYERS][11];

// == == == == [ Функции для базы данных ] == == ====

stock ConnectMySQL() {
    dbHandle = mysql_connect(MYSQL_HOST, MYSQL_USER, MYSQL_DB, MYSQL_PASS);
    if (mysql_errno() == 0) {
        print("MySQL - подключение успешно");
    } else {
        print("MySQL - ошибка подключения: %s", mysql_error());
        return false;
    }
    mysql_set_charset("cp1251");
    return true;
}

stock ExecuteQuery(const query[], bReturn = false, const callback[] = "", const types[] = "", ...) {
    new formattedQuery[MAX_DB_STRING];
    mysql_format(dbHandle, formattedQuery, sizeof(formattedQuery), query, ##arguments);
    mysql_function_query(dbHandle, formattedQuery, bReturn, callback, types);
    return true;
}

// == == == == [ Функции для отображения диалогов ] == == ====

stock ShowLoginDialog(playerid) {
    new string[MAX_DB_STRING];
    format(string, sizeof(string), "{FFFFFF}[Добро пожаловать]\n\nЛогин: {A52A2A}%s{FFFFFF}\nПинг: {A52A2A}%d{FFFFFF}\nАккаунт: {FF0000}[занят]{FFFFFF}\n\n{999999}У вас есть 35 секунд, чтобы ввести{FFFFFF}\nВведите свой пароль:",
        pInfo[playerid].Name, GetPlayerPing(playerid));
    ShowPlayerDialog(playerid, 8, DS_PASSWORD, "Авторизация", string, "•>>", "•><•");
}

stock ShowRegisterDialog(playerid) {
    new string[MAX_DB_STRING];
    format(string, sizeof(string), "{FFFFFF}[Добро пожаловать]\n\nЛогин: {A52A2A}%s{FFFFFF}\nПинг: {A52A2A}%d{FFFFFF}\nАккаунт: {008000}[свободен]{FFFFFF}\n\nПридумайте свой пароль:",
        pInfo[playerid].Name, GetPlayerPing(playerid));
    ShowPlayerDialog(playerid, 1, DS_INPUT, "Регистрация", string, "•>>", "•><•");
}

stock ShowPasswordConfirmationDialog(playerid) {
    ShowPlayerDialog(playerid, 2, DS_PASSWORD, "[Подтверждение пароля]", "{FFFFFF}Подтвердите свой {A52A2A}[Пароль]{FFFFFF}\nЧтобы продолжить {A52A2A}[регистрацию]{FFFFFF}:", "•>>", "•><•");
}

stock ShowEmailDialog(playerid) {
    ShowPlayerDialog(playerid, 3, DS_INPUT, "[Электронная почта]", "{FFFFFF}Укажите правильно свою {A52A2A}[Электронную почту]{FFFFFF}\nВ случае взлома или потери аккаунта{FFFFFF}\nВы сможете восстановить свой {A52A2A}[Аккаунт]{FFFFFF}:\n\n{DF8600}[Подсказка]{FFFFFF}:\n\t{008000}[]{FFFFFF}Электронная почта должна быть от 6 до 46 символов\n\t{008000}[]{FFFFFF}Электронная почта должна содержать '@' и '.'", "•>>", "<<•");
}

stock ShowReferalDialog(playerid) {
    ShowPlayerDialog(playerid, 4, DS_INPUT, "[Реферал]", "{FFFFFF}Введите {A52A2A}[Ник игрока]{FFFFFF}, пригласившего вас\nНа сервер:\n\n{DF8600}[Подсказка]{FFFFFF}:\nДостигнувши {A52A2A}6-го уровня{FFFFFF}, этот игрок:\n\t{008000}[]{FFFFFF}Получит {DF8600}[120.000$]\n\t{008000}[]{FFFFFF}Получит {A52A2A}[VIP] - статус {FFFFFF}на {DF8600}[7 дней]\n\t{008000}[]{FFFFFF}Получит {A52A2A}[Донат] {FFFFFF}в размере {DF8600}[250 рублей]", "•><•", "•>>");
}

stock ShowNationsDialog(playerid) {
    ShowPlayerDialog(playerid, 5, DS_LIST, "[Национальность]", "Американская\nКитайская\nИтальянская\nМексиканская\nРусский\nУкраинская\nФилиппинская\nЯпонская", "•>>", "<<•");
}

stock ShowAgeDialog(playerid) {
    ShowPlayerDialog(playerid, 6, DS_INPUT, "[Возраст]", "{FFFFFF}Введите возраст\nВашего {A52A2A}[Персонажа]{FFFFFF}:\n\n{DF8600}[Подсказка]{FFFFFF}:\n\t{008000}[]{FFFFFF}Возраст от 1 до 99\n\t{008000}[]{FFFFFF}Возраст должен состоять из цифр", "•>>", "<<•");
}

stock ShowSexDialog(playerid) {
    ShowPlayerDialog(playerid, 7, DS_MSGBOX, "[Пол]", "{FFFFFF}Выберите {A52A2A}[Пол]{FFFFFF} вашего персонажа{FFFFFF}:\nЗа которого вы будете играть {A52A2A}[Role Play]{FFFFFF}:", "Мужской", "Женский");
}

// == == == == [ Вспомогательные функции ] == == ====

stock ClearPlayerData(playerid) {
    number_skin[playerid] = 0;
    login_check[playerid] = false;
}

stock KillPlayerTimers(playerid) {
    if (timer[playerid].update_timer) {
        KillTimer(update_timer[playerid]);
    }
    if (timer[playerid].login_timer) {
        KillTimer(login_timer[playerid]);
    }
}

stock SpawnPlayerAfterLogin(playerid) {
    SetPlayerScore(playerid, pInfo[playerid].Level);
    SetPlayerSkin(playerid, pInfo[playerid].Skin);
    SetPlayerPos(playerid, 1154.3717, -1769.2594, 16.5938);
    SetPlayerFacingAngle(playerid, 0.0);
    SetPlayerVirtualWorld(playerid, 0);
    SetPlayerInterior(playerid, 0);
    SetCameraBehindPlayer(playerid);
    return true;
}

stock SavePlayerData(playerid, const field_name[], const value[], type[]) {
    new query[MAX_DB_STRING];
    if (strcmp(type, "d", true) == 0) {
        mysql_format(dbHandle, query, sizeof(query), "UPDATE `users` SET `%s` = '%d' WHERE `ID` = '%d' LIMIT 1",
            field_name, value, pInfo[playerid].ID);
    } else if (strcmp(type, "s", true) == 0) {
        mysql_format(dbHandle, query, sizeof(query), "UPDATE `users` SET `%s` = '%s' WHERE `ID` = '%d' LIMIT 1",
            field_name, value, pInfo[playerid].ID);
    }
    mysql_function_query(dbHandle, query, false, "", "");
}

stock Log(const format[], ...) {
    new logMessage[MAX_DB_STRING];
    format(logMessage, sizeof(logMessage), format, ##arguments);
    print("%s", logMessage);
    // Можно добавить запись в файл или другую систему логирования
}

stock CheckRusText(const str[], size = sizeof(str)) {
    for(new i = 0; i < size; i++) {
        if ((str[i] >= 'А' && str[i] <= 'Я') || (str[i] >= 'а' && str[i] <= 'я') || str[i] == ' ') {
            return true;
        }
    }
    return false;
}

// == == == == [ Функции для создания объектов ] == == ====

stock CreateCustomObject(modelid, x, y, z, rx, ry, rz, world, interior, streamdistance, materialID, textureName[]) {
    new objid = CreateDynamicObject(modelid, x, y, z, rx, ry, rz, world, interior, -1, streamdistance, streamdistance);
    SetDynamicObjectMaterial(objid, 0, materialID, "texture_folder", textureName, 0x00000000);
    return objid;
}

// == == == == [ Главные функции ] == == ====

public OnGameModeInit() {
    SetGameModeText("Role Play");

    if (!ConnectMySQL()) {
        return false; // Остановка режима игры при неудачном подключении к БД
    }

    AddPlayerClass(0, 0.0, 0.0, 0.0, 0.0, 0, 0, 0, 0, 0, 0);

    ShowPlayerMarkers(PLAYER_MARKERS_MODE_STREAMED);
    ShowNameTags(true);
    SetNameTagDrawDistance(20.0);
    DisableInteriorEnterExits();
    EnableStuntBonusForAll(0);

    // Создание объектов интерьера регистрации/авторизации
    new tmpobjid, map_world = -1, map_int = -1;
    tmpobjid = CreateCustomObject(19377, 247.991806, 34.998001, 1006.241271, 0.0, 90.0, 0.0, map_world, map_int, 300.00, 18646, "grey-80-percent");
    tmpobjid = CreateCustomObject(19450, 243.570098, 34.971900, 1007.989501, 0.0, 0.0, 0.0, map_world, map_int, 300.00, 7488, "vgnstonewall1_256");
    // ... добавьте остальные объекты аналогично

    // Пример создания текстурированных текстдроев
    tmpobjid = CreateDynamicObject(19477, 247.338363, 30.848352, 1006.359741, 0.0, -89.299949, -90.199981, map_world, map_int, -1, 300.00, 300.00);
    SetDynamicObjectMaterialText(tmpobjid, 0, "_______", 140, "Ariel", 85, 0, 0xFF000000, 0x00000000, 1);
    tmpobjid = CreateDynamicObject(19477, 247.338821, 30.978340, 1006.361328, 0.0, -89.299949, -90.199981, map_world, map_int, -1, 300.00, 300.00);
    SetDynamicObjectMaterialText(tmpobjid, 0, "Welcome", 140, "Ariel", 80, 0, 0xFF000000, 0x00000000, 1);

    // Инициализация других объектов аналогично...

    return true;
}

public OnGameModeExit() {
    mysql_close(dbHandle);
    return true;
}

public OnPlayerRequestClass(playerid, classid) {
    if (!login_check[playerid]) {
        SendClientMessage(playerid, COLOR_GREY, "Вы должны авторизоваться перед выбором класса.");
        return false;
    }
    return true;
}

public OnPlayerConnect(playerid) {
    // Создание текстдроев логотипа
    CreateLogoTextdraws(playerid);

    // Получение имени игрока
    GetPlayerName(playerid, pInfo[playerid].Name, sizeof(pInfo[playerid].Name));

    // Проверка наличия игрока в базе данных
    new fmt_str[] = "SELECT `ID` FROM `users` WHERE `Name` = '%s' LIMIT 1";
    new query[MAX_DB_STRING];
    mysql_format(dbHandle, query, sizeof(query), fmt_str, pInfo[playerid].Name);
    ExecuteQuery(query, true, "PlayerCheck", "d", playerid);

    ClearPlayerData(playerid);

    return true;
}

public OnPlayerDisconnect(playerid, reason) {
    KillPlayerTimers(playerid);
    return true;
}

public OnPlayerSpawn(playerid) {
    if (login_check[playerid]) {
        SetPlayerSpawn(playerid);
    }
    return true;
}

public OnPlayerDeath(playerid, killerid, reason) {
    return true;
}

public OnVehicleSpawn(vehicleid) {
    return true;
}

public OnVehicleDeath(vehicleid, killerid) {
    return true;
}

public OnPlayerText(playerid, text[]) {
    if (!login_check[playerid]) {
        SendClientMessage(playerid, COLOR_GREY, "Вы не авторизованы.");
        return false;
    }
    return false;
}

public OnPlayerCommandText(playerid, cmdtext[]) {
    if (!login_check[playerid]) {
        SendClientMessage(playerid, COLOR_GREY, "Вы не авторизованы.");
        return false;
    }
    return false;
}

public OnPlayerEnterVehicle(playerid, vehicleid, ispassenger) {
    return true;
}

public OnPlayerExitVehicle(playerid, vehicleid) {
    return true;
}

public OnPlayerStateChange(playerid, newstate, oldstate) {
    return true;
}

public OnPlayerEnterCheckpoint(playerid) {
    return true;
}

public OnPlayerLeaveCheckpoint(playerid) {
    return true;
}

public OnPlayerEnterRaceCheckpoint(playerid) {
    return true;
}

public OnPlayerLeaveRaceCheckpoint(playerid) {
    return true;
}

public OnRconCommand(cmd[]) {
    return true;
}

public OnPlayerRequestSpawn(playerid) {
    return true;
}

public OnObjectMoved(objectid) {
    return true;
}

public OnPlayerObjectMoved(playerid, objectid) {
    return true;
}

public OnPlayerPickUpPickup(playerid, pickupid) {
    return true;
}

public OnVehicleMod(playerid, vehicleid, componentid) {
    return true;
}

public OnVehiclePaintjob(playerid, vehicleid, paintjobid) {
    return true;
}

public OnVehicleRespray(playerid, vehicleid, color1, color2) {
    return true;
}

public OnPlayerSelectedMenuRow(playerid, row) {
    return true;
}

public OnPlayerExitedMenu(playerid) {
    return true;
}

public OnPlayerInteriorChange(playerid, newinteriorid, oldinteriorid) {
    return true;
}

public OnPlayerKeyStateChange(playerid, newkeys, oldkeys) {
    return true;
}

public OnRconLoginAttempt(ip[], password[], success) {
    return true;
}

public OnPlayerUpdate(playerid) {
    return true;
}

public OnPlayerStreamIn(playerid, forplayerid) {
    return true;
}

public OnPlayerStreamOut(playerid, forplayerid) {
    return true;
}

public OnVehicleStreamIn(vehicleid, forplayerid) {
    return true;
}

public OnVehicleStreamOut(vehicleid, forplayerid) {
    return true;
}

// == == == == [ Обработка ответов диалогов ] == == ====

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) {
    if (!response) {
        // Если игрок отменяет диалог
        SendClientMessage(playerid, COLOR_FIREBRICK, "Введите /quit");
        KICK_PLAYER(playerid);
        return true;
    }

    switch(dialogid) {
        case 1: // Регистрация - ввод пароля
            HandlePasswordInput(playerid, inputtext);
            break;
        case 2: // Подтверждение пароля
            HandlePasswordConfirmation(playerid, inputtext);
            break;
        case 3: // Ввод Email
            HandleEmailInput(playerid, inputtext);
            break;
        case 4: // Ввод реферала
            HandleReferalInput(playerid, inputtext);
            break;
        case 5: // Выбор национальности
            HandleNationsSelection(playerid, listitem);
            break;
        case 6: // Ввод возраста
            HandleAgeInput(playerid, inputtext);
            break;
        case 7: // Выбор пола
            HandleSexSelection(playerid, response);
            break;
        case 8: // Авторизация - ввод пароля
            HandleLoginInput(playerid, inputtext);
            break;
    }

    return true;
}

// == == == == [ Обработка ответов диалогов - Основные функции ] == == ====

stock HandlePasswordInput(playerid, const pass[]) {
    new len = strlen(pass);
    if (len == 0) {
        ShowRegisterDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Вы ничего не ввели.");
        return;
    }
    if (len < 6 || len > 32) {
        ShowRegisterDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Неверная длина пароля.");
        return;
    }
    if (CheckRusText(pass, len)) {
        ShowRegisterDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Смените раскладку клавиатуры.");
        return;
    }
    strmid(pInfo[playerid].Pass, pass, 0, len, sizeof(pInfo[playerid].Pass));
    ShowPasswordConfirmationDialog(playerid);
}

stock HandlePasswordConfirmation(playerid, const passConfirm[]) {
    if (strcmp(pInfo[playerid].Pass, passConfirm, true) == 0) {
        ShowEmailDialog(playerid);
    } else {
        SendClientMessage(playerid, COLOR_LIGHTRED, "Неверный пароль.");
        KICK_PLAYER(playerid);
    }
}

stock HandleEmailInput(playerid, const email[]) {
    new len = strlen(email);
    if (len == 0) {
        ShowEmailDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Вы ничего не ввели.");
        return;
    }
    if (len < 6 || len > 46) {
        ShowEmailDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Неверная длина электронной почты.");
        return;
    }
    if (strfind(email, "@", false) == -1 || strfind(email, ".", false) == -1) {
        ShowEmailDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Неверный формат электронной почты.");
        return;
    }
    if (CheckRusText(email, len)) {
        ShowEmailDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Смените раскладку клавиатуры.");
        return;
    }
    strmid(pInfo[playerid].Email, email, 0, len, sizeof(pInfo[playerid].Email));
    ShowReferalDialog(playerid);
}

stock HandleReferalInput(playerid, const referal[]) {
    if (IS_NULL(referal)) {
        ShowReferalDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Вы ничего не ввели.");
        return;
    }
    new fmt_str[] = "SELECT `ID` FROM `users` WHERE `Name` = '%e' LIMIT 1";
    new query[MAX_DB_STRING];
    mysql_format(dbHandle, query, sizeof(query), fmt_str, referal);
    ExecuteQuery(query, true, "CheckReferal", "de", playerid, referal);
}

stock HandleReferalCallback(playerid, const referalName[]) {
    new rows, fields;
    cache_get_data(rows, fields);
    if (!rows) {
        ShowReferalDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Аккаунт не найден.");
        return;
    }
    strmid(pInfo[playerid].Referal, referalName, 0, strlen(referalName), sizeof(pInfo[playerid].Referal));
    ShowNationsDialog(playerid);
}

stock HandleNationsSelection(playerid, listitem) {
    pInfo[playerid].Nations = listitem + 1;
    ShowAgeDialog(playerid);
}

stock HandleAgeInput(playerid, const ageStr[]) {
    new age = strval(ageStr);
    if (IS_NULL(ageStr)) {
        ShowAgeDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Вы ничего не ввели.");
        return;
    }
    if (age < 1 || age > 99) {
        ShowAgeDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Неверный возраст.");
        return;
    }
    pInfo[playerid].Age = age;
    ShowSexDialog(playerid);
}

stock HandleSexSelection(playerid, response) {
    SpawnPlayerAfterLogin(playerid);
    if (response) { // Мужской
        pInfo[playerid].Sex = 1;
        SetPlayerSkin(playerid, 32);
        number_skin[playerid] = 1;
    } else { // Женский
        pInfo[playerid].Sex = 2;
        SetPlayerSkin(playerid, 63);
        number_skin[playerid] = 15;
    }
    SetupSkinSelectionTextdraws(playerid);
    SelectTextDraw(playerid, COLOR_BROWN);
    SetPlayerVirtualWorld(playerid, playerid);
    SetPlayerInterior(playerid, 0);
    SetPlayerPos(playerid, 248.6302, 33.8265, 1007.3272);
    SetPlayerFacingAngle(playerid, 35.4503);
    SetPlayerCameraPos(playerid, 245.2390, 36.4504, 1008.5635);
    SetPlayerCameraLookAt(playerid, 248.6302, 33.8265, 1007.3272);
    Freeze(playerid, false);
}

stock HandleLoginInput(playerid, const passInput[]) {
    if (IS_NULL(passInput)) {
        ShowLoginDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Вы ничего не ввели.");
        return;
    }
    new fmt_str[] = "SELECT * FROM `users` WHERE `ID` = '%d' AND `Pass` = '%e' LIMIT 1";
    new query[MAX_DB_STRING];
    mysql_format(dbHandle, query, sizeof(query), fmt_str, pInfo[playerid].ID, passInput);
    ExecuteQuery(query, true, "PlayerLogin", "d", playerid);
}

// == == == == [ Обработка ответов диалогов - Callback функции ] == == ====

public PlayerCheck(playerid) {
    new rows, fields;
    cache_get_data(rows, fields);
    if (rows) {
        login_timer[playerid] = SetTimerEx("CheckLogin", 1000 * 35, false, "i", playerid);
        pInfo[playerid].ID = cache_get_field_content_int(0, "ID");
        ShowLoginDialog(playerid);
    } else {
        ShowRegisterDialog(playerid);
    }
}

public PlayerLogin(playerid) {
    new rows, fields;
    cache_get_data(rows, fields);
    if (rows) {
        cache_get_field_content(0, "Pass", pInfo[playerid].Pass, dbHandle, sizeof(pInfo[playerid].Pass));
        cache_get_field_content(0, "Email", pInfo[playerid].Email, dbHandle, sizeof(pInfo[playerid].Email));
        cache_get_field_content(0, "Referal", pInfo[playerid].Referal, dbHandle, sizeof(pInfo[playerid].Referal));
        cache_get_field_content(0, "Date Reg", pInfo[playerid].DateReg, dbHandle, sizeof(pInfo[playerid].DateReg));
        pInfo[playerid].Nations = cache_get_field_content_int(0, "Nations");
        pInfo[playerid].Age = cache_get_field_content_int(0, "Age");
        pInfo[playerid].Sex = cache_get_field_content_int(0, "Sex");
        pInfo[playerid].Skin = cache_get_field_content_int(0, "Skin");
        pInfo[playerid].Money = cache_get_field_content_int(0, "Money");
        pInfo[playerid].Level = cache_get_field_content_int(0, "Level");

        login_check[playerid] = true;
        SetTimerEx("FastSpawn", 100, false, "i", playerid);
        update_timer[playerid] = SetTimerEx("UpdateTime", 1000, false, "i", playerid);
        KillTimer(login_timer[playerid]);

        // Проверка рефералов
        new fmt_str[] = "SELECT * FROM `referal` WHERE `Name` = '%s' LIMIT 1";
        new query[MAX_DB_STRING];
        mysql_format(dbHandle, query, sizeof(query), fmt_str, pInfo[playerid].Name);
        ExecuteQuery(query, true, "CheckReferal_2", "d", playerid);
    } else {
        number_skin[playerid]++; // Используется как счетчик попыток авторизации
        if (number_skin[playerid] >= 3) {
            KICK_PLAYER(playerid);
            SendClientMessage(playerid, COLOR_FIREBRICK, "Попытки ввода пароля закончены. Введите /quit.");
            return;
        }
        new string[MAX_DB_STRING];
        format(string, sizeof(string), "Неверный пароль. Осталось попыток: %d", 3 - number_skin[playerid]);
        SendClientMessage(playerid, COLOR_LIGHTRED, string);
        ShowLoginDialog(playerid);
    }
}

public CheckReferal(playerid, name[]) {
    new rows, fields;
    cache_get_data(rows, fields);
    if (!rows) {
        ShowReferalDialog(playerid);
        SendClientMessage(playerid, COLOR_GREY, "Аккаунт не найден.");
        return;
    }
    strmid(pInfo[playerid].Referal, name, 0, strlen(name), sizeof(pInfo[playerid].Referal));
    ShowNationsDialog(playerid);
}

public CheckReferal_2(playerid) {
    new rows, fields;
    cache_get_data(rows, fields);
    if (rows) {
        pInfo[playerid].Money += 100000;
        SavePlayerData(playerid, "Money", pInfo[playerid].Money, "d");
        SendClientMessage(playerid, COLOR_YELLOW, "Вы получаете 100.000$ за приглашенного игрока");

        // Удаление записи реферала
        new fmt_str[] = "DELETE FROM `referal` WHERE `Name` = '%s' LIMIT 1";
        new query[MAX_DB_STRING];
        mysql_format(dbHandle, query, sizeof(query), fmt_str, pInfo[playerid].Name);
        ExecuteQuery(query, false, "");
    }
}

public CheckLogin(playerid) {
    SendClientMessage(playerid, COLOR_FIREBRICK, "Время на авторизацию вышло. Введите /quit.");
    KICK_PLAYER(playerid);
}

public TimeKick(playerid) {
    Kick(playerid);
    return true;
}

public UpdateTime(playerid) {
    if (pInfo[playerid].Money != GetPlayerMoney(playerid)) {
        ResetPlayerMoney(playerid);
        GivePlayerMoney(playerid, pInfo[playerid].Money);
    }
    update_timer[playerid] = SetTimerEx("UpdateTime", 1000, false, "i", playerid);
    return true;
}

public GetID(playerid) {
    pInfo[playerid].ID = cache_insert_id();
    return true;
}

public FastSpawn(playerid) {
    SpawnPlayerAfterLogin(playerid);
    return true;
}

// == == == == [ Функции для создания и управления текстдроями ] == == ====

stock CreateLogoTextdraws(playerid) {
    // Создание текстдроев логотипа
    Textdraw0 = TextDrawCreate(559.058776, 1.166676, "San-Andreas");
    TextDrawLetterSize(Textdraw0, 0.45, 1.6);
    TextDrawAlignment(Textdraw0, 1);
    TextDrawColor(Textdraw0, -5963521);
    TextDrawUseBox(Textdraw0, true);
    TextDrawBoxColor(Textdraw0, 0);
    TextDrawSetShadow(Textdraw0, 0);
    TextDrawSetOutline(Textdraw0, 1);
    TextDrawBackgroundColor(Textdraw0, 51);
    TextDrawFont(Textdraw0, 2);
    TextDrawSetProportional(Textdraw0, true);

    Textdraw1 = TextDrawCreate(557.647033, 15.75, "LD_POOL:ball");
    TextDrawLetterSize(Textdraw1, 0.0, 0.0);
    TextDrawTextSize(Textdraw1, 6.588277, 5.833333);
    TextDrawAlignment(Textdraw1, 1);
    TextDrawColor(Textdraw1, -1);
    TextDrawSetShadow(Textdraw1, 0);
    TextDrawSetOutline(Textdraw1, 0);
    TextDrawFont(Textdraw1, 4);

    Textdraw2 = TextDrawCreate(607.529357, 15.749997, "LD_POOL:ball");
    TextDrawLetterSize(Textdraw2, 0.0, 0.0);
    TextDrawTextSize(Textdraw2, 6.117629, 5.833334);
    TextDrawAlignment(Textdraw2, 1);
    TextDrawColor(Textdraw2, -1);
    TextDrawSetShadow(Textdraw2, 0);
    TextDrawSetOutline(Textdraw2, 0);
    TextDrawFont(Textdraw2, 4);

    Textdraw3 = TextDrawCreate(562.352966, 16.33333, "LD_SPAC:white");
    TextDrawLetterSize(Textdraw3, 0.0, 0.0);
    TextDrawTextSize(Textdraw3, 47.529342, 4.666667);
    TextDrawAlignment(Textdraw3, 1);
    TextDrawColor(Textdraw3, -1);
    TextDrawSetShadow(Textdraw3, 0);
    TextDrawSetOutline(Textdraw3, 0);
    TextDrawFont(Textdraw3, 4);

    Textdraw4 = TextDrawCreate(559.529602, 23.333349, "ROLE PLAY");
    TextDrawLetterSize(Textdraw4, 0.29894, 1.168332);
    TextDrawAlignment(Textdraw4, 1);
    TextDrawColor(Textdraw4, -1);
    TextDrawSetShadow(Textdraw4, 0);
    TextDrawSetOutline(Textdraw4, 1);
    TextDrawBackgroundColor(Textdraw4, 51);
    TextDrawFont(Textdraw4, 2);
    TextDrawSetProportional(Textdraw4, true);

    Textdraw5 = TextDrawCreate(43.29417, 429.333404, "action-rp.ru");
    TextDrawLetterSize(Textdraw5, 0.266, 1.284999);
    TextDrawAlignment(Textdraw5, 1);
    TextDrawColor(Textdraw5, -1);
    TextDrawSetShadow(Textdraw5, 0);
    TextDrawSetOutline(Textdraw5, 1);
    TextDrawBackgroundColor(Textdraw5, 51);
    TextDrawFont(Textdraw5, 2);
    TextDrawSetProportional(Textdraw5, true);
}

stock SetupSkinSelectionTextdraws(playerid) {
    // Создание текстдроев для выбора скина
    select_skin[playerid][0] = TextDrawCreate(535.177124, 334.0, "usebox");
    TextDrawLetterSize(select_skin[playerid][0], 0.0, 8.044445);
    TextDrawTextSize(select_skin[playerid][0], 426.696929, 0.0);
    TextDrawAlignment(select_skin[playerid][0], 1);
    TextDrawColor(select_skin[playerid][0], 0);
    TextDrawUseBox(select_skin[playerid][0], true);
    TextDrawBoxColor(select_skin[playerid][0], 102);
    TextDrawSetShadow(select_skin[playerid][0], 0);
    TextDrawSetOutline(select_skin[playerid][0], 0);
    TextDrawFont(select_skin[playerid][0], 0);

    // Аналогично создаются остальные текстдроиды (1-10)
    // ...

    // Пример для одного текстдроя:
    select_skin[playerid][8] = TextDrawCreate(458.682708, 348.833282, "<");
    TextDrawLetterSize(select_skin[playerid][8], 0.946163, 2.708333);
    TextDrawTextSize(select_skin[playerid][8], 18.935607, 19.916625);
    TextDrawAlignment(select_skin[playerid][8], 2);
    TextDrawColor(select_skin[playerid][8], -1);
    TextDrawSetShadow(select_skin[playerid][8], 0);
    TextDrawSetOutline(select_skin[playerid][8], 2);
    TextDrawBackgroundColor(select_skin[playerid][8], 51);
    TextDrawFont(select_skin[playerid][8], 1);
    TextDrawSetProportional(select_skin[playerid][8], true);
    TextDrawSetSelectable(select_skin[playerid][8], true);

    // Аналогично для остальных кнопок
}

stock CreateLogoTextdraws(playerid) {
    // Функция для создания текстдроев логотипа (используется в OnPlayerConnect)
    // ...
}

// == == == == [ Обработка кликов по текстдроям ] == == ====

public OnPlayerClickTextDraw(playerid, Text: clickedid) {
    if (clickedid == Text:INVALID_TEXT_DRAW && number_skin[playerid] > 0) {
        SelectTextDraw(playerid, COLOR_BROWN);
    }
    if (clickedid == select_skin[playerid][9]) { // Клик по правой стрелке
        number_skin[playerid]++;
        if (pInfo[playerid].Sex == 1) { // Мужской
            if (number_skin[playerid] > 14) number_skin[playerid] = 1;
        } else { // Женский
            if (number_skin[playerid] > 28) number_skin[playerid] = 15;
        }
        UpdatePlayerSkin(playerid);
    }
    if (clickedid == select_skin[playerid][8]) { // Клик по левой стрелке
        number_skin[playerid]--;
        if (pInfo[playerid].Sex == 1) { // Мужской
            if (number_skin[playerid] < 1) number_skin[playerid] = 14;
        } else { // Женский
            if (number_skin[playerid] < 15) number_skin[playerid] = 28;
        }
        UpdatePlayerSkin(playerid);
    }
    if (clickedid == select_skin[playerid][10]) { // Клик по кнопке подтверждения
        FinalizeRegistration(playerid);
    }
    return true;
}

// == == == == [ Обработка выбора скина ] == == ====

stock UpdatePlayerSkin(playerid) {
    switch(number_skin[playerid]) {
        // == == == [ Мужские скины ] == == ==
        case 1: SetPlayerSkin(playerid, 32); break;
        case 2: SetPlayerSkin(playerid, 78); break;
        case 3: SetPlayerSkin(playerid, 79); break;
        case 4: SetPlayerSkin(playerid, 133); break;
        case 5: SetPlayerSkin(playerid, 134); break;
        case 6: SetPlayerSkin(playerid, 135); break;
        case 7: SetPlayerSkin(playerid, 136); break;
        case 8: SetPlayerSkin(playerid, 137); break;
        case 9: SetPlayerSkin(playerid, 160); break;
        case 10: SetPlayerSkin(playerid, 200); break;
        case 11: SetPlayerSkin(playerid, 212); break;
        case 12: SetPlayerSkin(playerid, 213); break;
        case 13: SetPlayerSkin(playerid, 230); break;
        case 14: SetPlayerSkin(playerid, 239); break;
        // == == == [ Женские скины ] == == ==
        case 15: SetPlayerSkin(playerid, 63); break;
        case 16: SetPlayerSkin(playerid, 64); break;
        case 17: SetPlayerSkin(playerid, 75); break;
        case 18: SetPlayerSkin(playerid, 85); break;
        case 19: SetPlayerSkin(playerid, 131); break;
        case 20: SetPlayerSkin(playerid, 152); break;
        case 21: SetPlayerSkin(playerid, 198); break;
        case 22: SetPlayerSkin(playerid, 199); break;
        case 23: SetPlayerSkin(playerid, 201); break;
        case 24: SetPlayerSkin(playerid, 207); break;
        case 25: SetPlayerSkin(playerid, 237); break;
        case 26: SetPlayerSkin(playerid, 238); break;
        case 27: SetPlayerSkin(playerid, 243); break;
        case 28: SetPlayerSkin(playerid, 245); break;
    }
}

stock FinalizeRegistration(playerid) {
    // Скрытие текстдроев выбора скина
    new i;
    for (i = 0; i < 11; i++) {
        TextDrawHideForPlayer(playerid, select_skin[playerid][i]);
    }

    SendClientMessage(playerid, COLOR_WHITE, "Вы успешно зарегистрировались.");
    login_check[playerid] = true;
    update_timer[playerid] = SetTimerEx("UpdateTime", 1000, false, "i", playerid);
    Freeze(playerid, true);
    number_skin[playerid] = 0;
    CancelSelectTextDraw(playerid);

    // Создание аккаунта в базе данных
    new year, month, day;
    getdate(year, month, day);
    format(pInfo[playerid].DateReg, sizeof(pInfo[playerid].DateReg), "%02d/%02d/%02d", day, month, year);

    new fmt_str[] = "INSERT INTO `users` (`Name`, `Pass`, `Email`, `Referal`, `Date Reg`, `Nations`, `Age`, `Sex`, `Skin`, `Level`) VALUES ('%s', '%s', '%s', '%s', '%s', '%d', '%d', '%d', '%d', '%d')";
    new query[MAX_DB_STRING];
    mysql_format(dbHandle, query, sizeof(query), fmt_str, pInfo[playerid].Name, pInfo[playerid].Pass, pInfo[playerid].Email,
        pInfo[playerid].Referal, pInfo[playerid].DateReg, pInfo[playerid].Nations, pInfo[playerid].Age,
        pInfo[playerid].Sex, pInfo[playerid].Skin, pInfo[playerid].Level);
    ExecuteQuery(query, true, "GetID", "i", playerid);

    SpawnPlayer(playerid);
}

// == == == == [ Вспомогательные функции для регистрации ] == == ====

stock CheckRusText(string[], size = sizeof(string)) {
    for (new i = 0; i < size; i++) {
        if ((string[i] >= 'А' && string[i] <= 'Я') || (string[i] >= 'а' && string[i] <= 'я') || string[i] == ' ') {
            return true;
        }
    }
    return false;
}

// == == == == [ Старты и завершения ] == == ====

main() { }
```
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(54) : error 010: invalid function or declaration
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(56) : error 010: invalid function or declaration
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(57) : error 010: invalid function or declaration
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(58) : error 010: invalid function or declaration
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(59) : error 010: invalid function or declaration
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(60) : error 010: invalid function or declaration
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(67) : error 010: invalid function or declaration
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(97) : error 017: undefined symbol "mysql_error"
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(106) : error 035: argument type mismatch (argument 4)
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(107) : error 017: undefined symbol "mysql_function_query"
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(104) : warning 203: symbol is never used: "bReturn"
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(115 -- 116) : warning 213: tag mismatch
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(115 -- 116) : error 001: expected token: ",", but found "."
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(116) : warning 217: loose indentation
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(116) : error 029: invalid expression, assumed zero
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(116) : error 017: undefined symbol "Name"
C:\Users\Admin\Desktop\server\gamemodes\new.pwn(116) : fatal error 107: too many error messages on one line