11:35
ОбновитьСмайлыУправление мини-чатом
МИНИ-ЧАТ
Главная страница!

 



 
          





Рекомендуем:





Последние Файлы GTA 4 Последние Файлы GTA-MP Реклама
Скрипт GTA 4 элементы Watch... 07.09.2014
Ferrari 360 Spider [EPM con... 13.12.2013
Porsche Cayenne Turbo 2012 ... 13.12.2013
Shelby Terlingua Mustang v1... 13.12.2013
Hamann Lamborghini Gallardo... 27.10.2013
[GM] The Big PEN1:LS v2.00 ... 04.12.2017
Dgun (AvnanceRP,SampRP,Dimo... 19.03.2016
SAMP скрипт SX Events (MySQ... 03.03.2016
Карта ASL мэрия для SAMP се... 03.03.2016
AIM для SA-MP 0.3.7 22.02.2016
  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: Dima-kun  
Форум SAMP о мультиплеерах для GTA. »   » Wiki-Samp-Rus » [Tutorial] Создание сис-мы регистрации (MySQL)
[Tutorial] Создание сис-мы регистрации (MySQL)
SatelliteДата: Пятница, 23.03.2012, 23:58 | Сообщение # 1
Местный
Группа: Продвинутые
Сообщений: 622
Награды: 10
Город: Хмельницкий
Замечания: 20%
Статус:
В этой теме я расскажу Вам, как можно написать систему регистрации с нуля (можно и адаптировать под Ваш Godfather мод).

Итак, для этого нам понадобятся следующие вещи:
1. Denwer — через эту программу мы будем запускать и администрировать наш MySQL сервер.
Скачать!
2. MySQL Plugin от g-stylezzz — плагин для работы с базой данных.
Это кинуть в папку Plugins
Это кинуть в папку с сервером + в server.cfg добавить строку plugins mysql sscanf
[URL=http://files.g-stylezzz.com/mysql/rel/R6/a_mysql.inc]Это кинуть в папку Pawno\Includes[/URL]
3. Sscanf Plugin — плагин, при помощи которого нам будет удобней и быстрей извлекать данные из результата при выборке из таблицы.
Скачать!

Начнём.
> Устанавливаем Denwer, запускаем сервер (на рабочем столе появится ярлык «Start Denwer»).
> Заходим в браузер и в адресной строке вводим «localhost» (без кавычек).
> Спускаемся ниже и переходим по ссылке: http://localhost/Tools/CODEmyadmin/index.CODE
> Итак, вы видите CODEmyadmin, сейчас мы можем управлять базой данных.
> Создаём таблицу:
>> Примерно в центре есть «Create new database».
>>> Я назвал свою БД «pawno», кодировку выбрал «cp1251_bin».

>>> БД создана

>>>> Теперь нам нужно создать таблицу для аккаунтов.

Name — Название таблицы, Number of Fields — количество полей.
Мы используем 3 поля,
1. ID аккаунта, чтобы можно было его распознать в таблице, можно, конечно использовать ник, но с ИД удобней;
2. Ник игрока, думаю тут всё ясно;
3. Пароль игрока.
>>>> Таблица создана, сейчас мы настроим наши поля.

Нажимаем Save.
Все нужное я выделил красным, теперь расскажу, что за что отвечает.
Field — название поля;
Type — тип данных, есть integer (целые числа), string (VARCHAR, TEXT), float, DATE, DATETIME, TIME и т.д., в общем как в павно, тут я использую VARCHAR для строк, и INT для целых чисел.
Length/Values — сколько «ячеек» мы выделяем для поля, для ника 24 (MAX_PLAYER_NAME), для пароля — 64.
Collation — кодировка.
AUTO_INCREMENT — генерирует значения для ID игрока в порядке возрастания (1, 2, 3...).

>>>> Так будет выглядеть пустая, без аккаунтов таблица:

> Базу данных и таблицу мы подготовили, теперь перейдем к моду.

>> Сверху мода, где вы подключаете все инклюды, добавляем эти строки:
Code
#include <a_mysql> // SQL функции.
#include <sscanf2> // Извлечение данных.

>> Чуть ниже задефайним парметры БД:
Code
#define SQL_HOST  "localhost" // IP адресс БД.
#define SQL_USER  "root" // Login БД.       
#define SQL_DB    "pawno" // Название БД.            
#define SQL_PASS  "" // Пароль БД.

>> Дефайны для ID'ов диалогов и цвета сообщений.
Code

#define DIALOG_LOGIN   1
#define DIALOG_REGISTER  2
#define DIALOG_WRONGPAS     3
#define COLOR_LIGHTRED   0xFF6347AA
#define COLOR_YELLOW   0xFFFF00AA

>> Создадим массив для хранения данных аккаунта.
Code

enum Variables {
    aID,
    aName[MAX_PLAYER_NAME],
    aPassword[64],
    bool: aLogged,
    aWrongPassword,
};
new playerVariable[100][Variables]; // 100 - моё кол-во слотов для игроков на сервере.

>> Создадим функцию для подключения и отключения к БД.
Code

ConnectMySQL() { // В OnGameModeInIt вставьте ConnectMySQL();
       mysql_connect(SQL_HOST, SQL_USER, SQL_DB, SQL_PASS); // Тут мы используем все данные, которые мы дефайнили.
       switch(mysql_ping()) { // Проверка на то, что мы подключены к БД.
     case 1: print("MySQL connection: alive."); // Если подключена БД.
     case -1: print("MySQL connection: dead."); // Если не подключена БД.
    }
    return 1;
}

DisconnectMySQL() { // Вставьте DisconnectMySQL(); в OnGameModeExit, отключаемся от БД.
    mysql_close();
    print("MySQL connection closed.");
}

CheckMySQLConnection() { // Этот сток мы будем использовать для проверки, подключена ли БД перед её использованием.
    if(mysql_ping() == -1) mysql_reconnect();
    return 1;
}

>> Тут у нас стоки для регистрации и логина.
Code

CreateAccount(playerid, password[]) {
    new
        query[128], // Для запроса.
     sqlname[MAX_PLAYER_NAME],
        sqlpassword[32];
    mysql_real_escape_string(playerVariable[playerid][aName], sqlname); // Защитит от sql inject
    mysql_real_escape_string(password, sqlpassword); // Защитит от sql inject
    format(query, sizeof(query), "INSERT INTO `Accounts` (`Nickname`, `Password`) VALUE ('%s', '%s')", sqlname, sqlpassword); // Добавляем в таблицу запись.
    // INSERT - добавление записи в таблицу, 1. () — поля. 2. VALUE — значения этих полей.
    mysql_query(query); // Отправляем запрос.
       playerVariable[playerid][aID] = mysql_insert_id(); // Узнаём ИД аккаунта, будет использоваться для сохранения и прочих операций.
       strmid(playerVariable[playerid][aPassword], password, 0, 64, 255); // Внедряем в массив аккаунта введенный игроком пароль.
    playerVariable[playerid][aLogged] = true; // Мы авторизованы.
    return 1;
}
LoadAccount(playerid, password[]) {
    new
     query[128],
      sqlpass[32],
      result[5+24+64],
      dialog[128];
    mysql_real_escape_string(password, sqlpass); // Защита от SQL Inject, шифрует кодировку.
     format(query, sizeof(query), "SELECT * FROM `Accounts` WHERE `Password` = '%s' AND `ID` = '%i'", sqlpass, playerVariable[playerid][aID]);
    // SELECT * - выбрать, FROM - с таблицы, WHERE - где, пароль равен введенному паролю и ID равен иду ника человека.
     mysql_query(query); // Отправляем запрос.
     mysql_store_result(); // Смотрим записи, которые мы выбрали запросом выше.
     if(mysql_num_rows() == 1) { // Если выбрало только 1 аккаунт с таким паролем и ИД - успех, пароль введен верно, загружаем данные в массив.
           mysql_fetch_row_format(result, "|"); // split, данные в результате записываются типо "1|Snoowker|parol"
           sscanf(result, "p<|>is[24]s[32]", // i - ид (int), s[размер] - string, ник и пароль.
      playerVariable[playerid][aID],
      playerVariable[playerid][aName],
      playerVariable[playerid][aPassword]);
     playerVariable[playerid][aLogged] = true;
     mysql_free_result(); // Очищаем память.
     return 1;
    }
     else { // Мы ввели неверный пароль.
         if(playerVariable[playerid][aWrongPassword] == 4) {
      SendClientMessage(playerid, COLOR_LIGHTRED, "Вы 3 раза ввели неверный пароль и были отключены от сервера.");
      Kick(playerid);
      return 1;
     }
                   playerVariable[playerid][aWrongPassword] ++;
     format(dialog, sizeof(dialog),
      "Вы ввели неверный пароль.\n\
      У Вас осталось %i/3 попыток ввода.", 3 - playerVariable[playerid][aWrongPassword]);
     ShowPlayerDialog(playerid, DIALOG_WRONGPAS, DIALOG_STYLE_MSGBOX, "Ошибка.", dialog, "Повтор", "Отмена");
     }
     return 1;
}
GetAccountID(playerid) {
    new
     query[128];
    format(query, sizeof(query),"SELECT `ID` FROM `Accounts` WHERE `Nickname` = '%s'", playerVariable[playerid][aName]);
    // Выбираем ID, с таблицы Accounts, где Ник равен нику игрока.
    mysql_query(query); // Отправляем запрос.
    mysql_store_result(); // Видим
    if(mysql_num_rows() == 1) { // Если у нас в результате выбрало 1 запись, т.е. аккаунт игрока.
     playerVariable[playerid][aID] = mysql_fetch_int(); // ИД игрока равен номеру записи.
     mysql_free_result(); // Очищаем память.
     return playerVariable[playerid][aID]; // Возвращаем ИД игрока.
    }
    return 0;
}

SaveAccount(playerid) { // Сохранение аккаунта.
    if(playerVariable[playerid][aLogged] == true) { // Проверка, если аккаунт авторизован.
        CheckMySQLConnection(); // Проверяем, подключена ли БД.
     new    
      query[186],
      sqlname[MAX_PLAYER_NAME],
      sqlpass[64];
     mysql_real_escape_string(playerVariable[playerid][aName], sqlname);
     mysql_real_escape_string(playerVariable[playerid][aPassword], sqlpass);
     format(query, sizeof(query), "UPDATE `Accounts` SET `Nickname` = '%s', `Password` = '%s' WHERE `ID` = '%i'", sqlname, sqlpass, playerVariable[playerid][aID]);
     mysql_query(query); // Отправляем запрос
    }
    return 1;
}

Создадим сток для очистки массивов при коннекте/дисконнекте.
Code
RemovePlayerVariables(playerid) {
    playerVariable[playerid][aWrongPassword] = 0;
    playerVariable[playerid][aID] = 0;
    playerVariable[playerid][aLogged] = false;
    return 1;
}

Наши диалоги:
Code

public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) {
    switch(dialogid) {
     case DIALOG_LOGIN: { // Диалог авторизации.
         if(!response) { // Если нажал «Отмена».
       SendClientMessage(playerid, COLOR_YELLOW, "* Введите /q(uit), чтобы выйти из игры.");
       Kick(playerid);
       return 1;
      }
         if(!strlen(inputtext)) { // Если поле ввода пустое.
             new dialog[134+MAX_PLAYER_NAME];
          format(dialog, sizeof(dialog),
        "Добро пожаловать на Сервер!\n\
        Этот аккаунт зарегистрирован.\n\n\
        Логин: %s\n\
        Введите пароль:",
         playerVariable[playerid][aName]);
       ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT, "Авторизация.", dialog, "Войти", "Отмена");
       return 1;
      }
      LoadAccount(playerid, inputtext); // Пробуем его авторизовать.
     }
     case DIALOG_REGISTER: { // Диалог регистрации.
         if(!response) { // Если нажал "Отмена".
       SendClientMessage(playerid, COLOR_YELLOW, "* Введите /q(uit), чтобы выйти из игры.");
       Kick(playerid);
       return 1;
      }
      if(!strlen(inputtext) || strlen(inputtext) < 6 || strlen(inputtext) > 64) { // Если пустое поле ввода или пароль имеет меньше 6 или больше 64 символов
        new dialog[380+24+10];
       format(dialog, sizeof(dialog),
        "Добро пожаловать на Сервер!\n\
           Этот аккаунт не зарегистрирован.\n\n\
           Логин: %s\n\
        Введите пароль и нажмите \"Далее\".\n\n\
          Примечания:\n\
           - Пароль чувствительный к регистру.\n\
           - Длина пароля от 6 до 32 символов.\n\
           - В пароле можно использовать символы на кириллице и латинице.\n", playerVariable[playerid][aName]);
       ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "Регистрация.", dialog, "Далее", "Отмена");
       return 1;
      }
      CreateAccount(playerid, inputtext); // Создаём аккаунт.
      playerVariable[playerid][aLogged] = true; // Авторизуем игрока. <img rel="usm" src="http://www.samp-rus.com/Smiles_for_forum/1.gif" border="0" align="absmiddle" alt=":)" />
     }
     case DIALOG_WRONGPAS: { // Если неверный пароль.
      if(response) {
       new dialog[134+MAX_PLAYER_NAME];
       format(dialog, sizeof(dialog),
        "Добро пожаловать на Сервер!\n\
        Этот аккаунт зарегистрирован.\n\n\
        Логин: %s\n\
        Введите пароль:",
        playerVariable[playerid][aName]);
       ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT, "Авторизация.", dialog, "Войти", "Отмена");
       return 1;
      }
      else { // Если нажал "Отмена".
       Kick(playerid);
       return 1;
      }
     }
    }
    return 1;
}

>> Отключаем возможность писать в чат неавторизованному.
Code

public OnPlayerText(playerid, text[])
{
    if(playerVariable[playerid][aLogged] == false) return 0;
    return 1;
}

>> Наш OnPlayerConnect.
Code

public OnPlayerConnect(playerid)
{
    RemovePlayerVariables(playerid);
//------------------------------------------------------------------------------
    GetPlayerName(playerid, playerVariable[playerid][aName], MAX_PLAYER_NAME);
//------------------------------------------------------------------------------
    if(GetAccountID(playerid)) { // Аккаунт зарегистрирован
     new dialog[128+MAX_PLAYER_NAME];
     format(dialog, sizeof(dialog),
      "Добро пожаловать на Сервер!\n\
      Этот аккаунт зарегистрирован.\n\n\
      Логин: %s\n\
      Введите пароль:",
       playerVariable[playerid][aName]);
     ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_INPUT, "Авторизация.", dialog, "Войти", "Отмена");
    }
    else { // Аккаунт не зарегистрирован (return 0, в функции GetAccountID, т.е. не нашло записи с аккаунтом).
     new dialog[344+MAX_PLAYER_NAME];
     format(dialog, sizeof(dialog),
      "Добро пожаловать на Сервер!\n\
         Этот аккаунт не зарегистрирован.\n\n\
         Логин: %s\n\
      Введите пароль и нажмите \"Далее\".\n\n\
        Примечания:\n\
      - Пароль чувствительный к регистру.\n\
         - Длина пароля от 6 до 32 символов.\n\
         - В пароле можно использовать символы на кириллице и латинице.\n", playerVariable[playerid][aName]);
     ShowPlayerDialog(playerid, DIALOG_REGISTER, DIALOG_STYLE_INPUT, "Регистрация.", dialog, "Далее", "Отмена");
    }
    return 1;
}


>>> Наш OnPlayerDisconnect.
Code
public OnPlayerDisconnect(playerid, reason)
{
     if(playerVariable[playerid][aLogged] == true) SaveAccount(playerid);
     return 1;
}


Готово, у нас есть система регистрации.
Вот так выглядит таблица с аккаунтами:


Основу дал, объяснил. Дальше дорабатывайте сами под свой лад.

Защиту от съезда полей (из-за sscanf) сами делайте, опять же, тут разжевал основу. new_russian

Автор урока: Snoowker (на SRC — Satellite).

Копирование материала на посторонние сайты без указания автора строго запрещено.



Сообщение отредактировал Satellite - Суббота, 24.03.2012, 16:17
NyawkaДата: Суббота, 24.03.2012, 00:38 | Сообщение # 2
Освоившийся
Группа: I'm V.I.P.
Сообщений: 113
Награды: 0
Город: Киев
Репутация: 131
Замечания: 40%
Статус:
Полезный урок,возможно на своем моде сделаю такую регу,а так плюсегГг лови,молодец!


LatronДата: Суббота, 24.03.2012, 02:25 | Сообщение # 3
Группа: I'm V.I.P.
Сообщений: 2115
Награды: 22
Город: Орел
Репутация: 1604
Замечания: 0%
Статус:
Довольно таки неплохо, но код лучше бы на пастебин.
Короче так держать , + .



Моё портфолио

Мои работы:
[ Lesson ] Операторы в PAWN.
[ Lesson ] Переменная.
[ GM ] RegSys. ( Last update: 21.04.2012 )


МолорищеДата: Суббота, 24.03.2012, 10:38 | Сообщение # 4
Молор
Группа: Продвинутые
Сообщений: 427
Награды: 11
Город: Санкт Петербург
Замечания: 0%
Статус:
Вот у меня вопрос, файловая система регистрации отличается от MySQL только скоростью? Или еще чем?


Мне нечего делать.
EmiGrantДата: Суббота, 24.03.2012, 12:32 | Сообщение # 5
Долгожитель
Группа: Продвинутые
Сообщений: 1362
Награды: 34
Город: Пятигорск
Репутация: 1653
Замечания: 40%
Статус:
Quote (Fiskar)
Вот у меня вопрос, файловая система регистрации отличается от MySQL только скоростью? Или еще чем?

Скорость зависит от самого кода в моде. Мускул от файлов отличается только возможностями и удобством, ну если в нем разобраться :)





Если человек несет бред, то здесь 2 варианта: либо он очень умный либо очень тупой © EmiGrant
SatelliteДата: Суббота, 24.03.2012, 16:18 | Сообщение # 6
Местный
Группа: Продвинутые
Сообщений: 622
Награды: 10
Город: Хмельницкий
Замечания: 20%
Статус:
Quote (Fiskar)
Вот у меня вопрос, файловая система регистрации отличается от MySQL только скоростью? Или еще чем?

Многопоточностью, скоростью (при большом кол-ве запросов сервер так не встаёт, как при файлах), большими возможностями и вышеназванным удобством.

Добавлено (24.03.2012, 16:18)
---------------------------------------------
Добавил сохранение аккаунта в OnPlayerDisconnect.

MckenzyДата: Суббота, 24.03.2012, 21:26 | Сообщение # 7
Советчик
Группа: I'm V.I.P.
Сообщений: 1212
Награды: 130
Город: Ярославль
Репутация: 2125
Замечания: 80%
Статус:
Давно же на павну.сру было? Почему раньше не решался выложить тут?)
А так по сабжу, спасибо :)

AlessandrosДата: Суббота, 24.03.2012, 22:24 | Сообщение # 8
Постоялец
Группа: I'm V.I.P.
Сообщений: 409
Награды: 27
Город: GB
Замечания: 20%
Статус:
Да ну. Так-то если код мода писали не пьяные индусы, то и файловая система покатит. Редактировать например данные все же удобнее, и без риска что-либо обрушить(если на что-то не обратил внимание) :)


I <3 Инкогнито
Иногда правда-это все что у нас есть.
[off]тут я вспомнел что я хоть и хландакровен и лихко вывисти из сибяя я принял тежелый выбор што мой атец киллир и па мне тичет кровь лысого киллира с номерным автамабильным знаком на лобке и я скочал с трейкера игру Hitmon blud maney и the balad of gey Tonne
© trollmarcus
[/off]
LatronДата: Суббота, 24.03.2012, 23:12 | Сообщение # 9
Группа: I'm V.I.P.
Сообщений: 2115
Награды: 22
Город: Орел
Репутация: 1604
Замечания: 0%
Статус:
Quote (Alessandros)
Да ну. Так-то если код мода писали не пьяные индусы, то и файловая система покатит. Редактировать например данные все же удобнее, и без риска что-либо обрушить(если на что-то не обратил внимание) :)

Ммм, не согласен ... БД MySQL в разы удобнее ...



Моё портфолио

Мои работы:
[ Lesson ] Операторы в PAWN.
[ Lesson ] Переменная.
[ GM ] RegSys. ( Last update: 21.04.2012 )


MckenzyДата: Суббота, 24.03.2012, 23:32 | Сообщение # 10
Советчик
Группа: I'm V.I.P.
Сообщений: 1212
Награды: 130
Город: Ярославль
Репутация: 2125
Замечания: 80%
Статус:
Quote (Alessandros)
Редактировать например данные все же удобнее

Редактировать данные в галимом блокноте удобнее, чем в пхпадмин панели, с красивым оформлением и продуманным интерфейсом?
Quote (Alessandros)
и без риска что-либо обрушить

Мускул надежнее, в файлах большая вероятность утерять что либо.

SatelliteДата: Суббота, 24.03.2012, 23:38 | Сообщение # 11
Местный
Группа: Продвинутые
Сообщений: 622
Награды: 10
Город: Хмельницкий
Замечания: 20%
Статус:
Quote (Mckenzy)
Давно же на павну.сру было? Почему раньше не решался выложить тут?)

Я и не думал сюда выкладывать, пока кое-кто не предложил сделать это за меня. Лучше сам выложу, чем кто-то. crazy

KämpferДата: Суббота, 24.03.2012, 23:56 | Сообщение # 12
Освоившийся
Группа: Продвинутые
Сообщений: 114
Награды: 15
Город: /
Репутация: 163
Замечания: 40%
Статус:
Quote (Alessandros)
Да ну. Так-то если код мода писали не пьяные индусы, то и файловая система покатит. Редактировать например данные все же удобнее, и без риска что-либо обрушить(если на что-то не обратил внимание)

чушь, причем полнейшая!



Гитлер капут

Можно сопротивляться вторжению армий, вторжению идей сопротивляться невозможно. ©

Оплачиваемая личная помощь, исправление и оптимизация кода, написание небольших скриптов.
skype: kampfer_88
AlessandrosДата: Понедельник, 26.03.2012, 09:54 | Сообщение # 13
Постоялец
Группа: I'm V.I.P.
Сообщений: 409
Награды: 27
Город: GB
Замечания: 20%
Статус:
Quote (Mckenzy)
чем в пхпадмин панели, с красивым оформлением и продуманным интерфейсом?

yes

Quote (Kämpfer)
чушь, причем полнейшая!

ну-ка обоснуй :D



I <3 Инкогнито
Иногда правда-это все что у нас есть.
[off]тут я вспомнел что я хоть и хландакровен и лихко вывисти из сибяя я принял тежелый выбор што мой атец киллир и па мне тичет кровь лысого киллира с номерным автамабильным знаком на лобке и я скочал с трейкера игру Hitmon blud maney и the balad of gey Tonne
© trollmarcus
[/off]
AndrejsДата: Понедельник, 26.03.2012, 16:05 | Сообщение # 14
Группа: I'm V.I.P.
Сообщений: 1801
Награды: 37
Город: Tallinn
Репутация: 2282
Замечания: 20%
Статус:
Quote (Alessandros)
Редактировать например данные все же удобнее, и без риска что-либо обрушить(если на что-то не обратил внимание)

Пиздёшь и провокация, БД как раз таки в плане меньшего риска превосходит файлы. При правильной настройке всё будет работать, как часы.
А на счёт редактирования данных... Удобнее редактировать всё, через пхпадмин, я уже не говорю о возможности создания нормальной UCP






Сообщение отредактировал Andrejs - Понедельник, 26.03.2012, 16:06
MihailSarbonovДата: Пятница, 06.04.2012, 03:59 | Сообщение # 15
Освоившийся
Группа: Пользователи
Сообщений: 83
Награды: 0
Город: Нижний Новгород
Репутация: 7
Замечания: 0%
Статус:
Можно ли с компьютера подключится? Не используя денвер, а уже активную базу mysql?
Я уже не знаю какой урок выполняю, и сам все делал, все равно не подключается к Базе.



"Иногда смотришь на многих людей и не понимаешь, почему они о себе так много о думают?"
http://s53.radikal.ru/i142/1107/0d/9f50ca1274c9.jpg (посмотри)
Занял в конкурсе 3 место. :)
Форум SAMP о мультиплеерах для GTA. »   » Wiki-Samp-Rus » [Tutorial] Создание сис-мы регистрации (MySQL)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:





 


 


 
Хостинг от uCoz samp.at.ua