Регистрация Главная Сообщество
Сообщения за день Справка Регистрация
Навигация
Zhyk.org LIVE! Реклама на Zhyk.org Правила Форума Награды и достижения Доска "почета"

Ответ
 
Опции темы
Старый 11.03.2014, 18:20   #1
Читер-спонсор
 Пехотинец
Аватар для .Master.
 
.Master. трижды герой Советского Союза.Master. трижды герой Советского Союза.Master. трижды герой Советского Союза.Master. трижды герой Советского Союза.Master. трижды герой Советского Союза.Master. трижды герой Советского Союза.Master. трижды герой Советского Союза.Master. трижды герой Советского Союза.Master. трижды герой Советского Союза.Master. трижды герой Советского Союза.Master. трижды герой Советского Союза
Регистрация: 21.07.2012
Сообщений: 95
Популярность: 6380
Сказал(а) спасибо: 631
Поблагодарили 460 раз(а) в 379 сообщениях
 
По умолчанию Пишем игровой интернет сервер.

Что же нам понадобится для реализации?

1. Хостинг с поддержкой php.
2. Игра с работоспособным сетевым кодом.

Итак, есть у нас в интернете домен на котором размещен наш скрипт "арены". Так же есть - игра-клиент, которой нужно узнать кол-во доступных серверов, а при необходимости - создать свой.

Что нам требуется от "арены"? - Получить список серверов в виде "IP:Port IP:Port IP:Port..." и в свою очередь зарегистрировать новый. Происходить все это будет посредством HTTP запросов.

Ну что же, давайте попробуем реализовать нашу задумку. Работу с "ареной" разделим на две части:

1. Подача HTTP запросов и обработка ответов игрой.
2. Обработка запроса скриптом на арене.

Всего у нас с вами будет 2-ва вида запросов: view и ping.

VIEW - нам нужен для получения списка серверов. Выглядит это так:


Цитата:
Запрос: [Ссылки могут видеть только зарегистрированные пользователи. ].
Ответ : 212.100.15.45:25666 192.10.38.212:25666.

В ответе мы можем наблюдать, что на данный момент на арене находятся 2 сервера на портах 25666.

PING - для оповещения арены о том что сервер жив и удалять его из списка пока нет никакой необходимости.


Цитата:
Запрос: [Ссылки могут видеть только зарегистрированные пользователи. ]
Ответ: нам не требуется

Давайте теперь попробуем реализовать это на стороне игры:

Что нам теперь требуется знать? - Как отправить HTTP запрос и получить на него ответ.

Приведу всего одну процедуру использующую возможности WinSock:


Цитата:
function Arena(const mode: string; get: boolean): string;
const
host = 'host.ru';
port = 25666;
var
wData : WSADATA;
addr : sockaddr_in;
sock : integer;
error : integer;
buf : array [0..1023] of Char;
str : string;
phe : PHostEnt;
begin
//Инициализация сокета
Result := '';
WSAStartup($0101, wData);
phe := gethostbyname(PChar(string(host)));
if phe = nil then
begin
WSACleanup;
Exit;
end;

sock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

if sock = INVALID_SOCKET then
begin
WSACleanup;
Exit;
end;

addr.sin_family := AF_INET;
addr.sin_port := htons(80);
addr.sin_addr := PInAddr(phe.h_addr_list^)^;

error := connect(sock, addr, sizeof(addr));
if error = SOCKET_ERROR then
begin
closesocket(sock);
WSACleanup;
Exit;
end;

// Составляем строку запроса
str := 'GET [Ссылки могут видеть только зарегистрированные пользователи. ] + host + '/?action=arena&mode=' + mode;
if mode = 'ping'
then str := str + '&port=' + IntToStr(port);
str := str + ' HTTP/1.0'#13#10#13#10;

// отправляем
send(sock, str[1], Length(str), 0);

// Если нужен ответ то принимаем
if get then
begin
ZeroMemory(@buf, 1024);
error := recv(sock, buf, 1024, 0);
while error > 0 do
begin
Result := Result + Copy(buf, 0, error);
error := recv(sock, buf, 1024, 0);
end;
end;
// Закрываем сокет – завершаем работу с сетью
closesocket(sock);
WSACleanup;

// Вырезаем из ответа то что нам нужно, т.е. отрезаем
// HTTP заголовки
if get and Result <> ''
then Result:=Copy(Result, pos(#13#10#13#10, Result)+4,
Length(Result));
end;


В нашу функцию передается всего 2 параметра mode и get. Первый - имя запроса, а второй означает нужен ли нам результат обработки запроса. Вызов этой функции для наших двух запросов будет выглядеть следующим образом:

Цитата:
Str := Arena('view', true); // для получения списка серверов
Arena('ping', false); // сообщить арене что наш сервер
// живее всех живых


После получения списка серверов запросом "view" игра должна разослать им запросы о их текущем состоянии (карта, игроки и т.д.) В этот момент отбрасываются "умершие" сервера, ибо ответа от них не придет.


Реализация со стороны интернета:

С игрой вроде бы все стало ясно, теперь остается написать скрипт. В запросах посылаем ключевое слово "action=arena" благодаря чему помимо арены на данном домене может висеть полноценный сайт. Для того, чтобы определить адресуется ли данный запрос арене, в index.php необходимо (желательно в самом начале) написать следующее:


Цитата:
if ($action == 'arena')
{
include 'arena.php';
die();
}

Вот сам код arena.php:

Цитата:
<?php
//В этом файле будет храниться список активных серверов
$list_file = 'db/arena_list.txt';
// Узнаем IP адрес отправителя запроса
$ip = $_SERVER['REMOTE_ADDR'];
// Читаем номер порта из запроса
$port = intval($_REQUEST['port']);
// Это от хитрых кулхацкеров
if (!($port >= 1024 && $port <= 65500))
$port = 25666;
// Читаем файл-список
$lst = file($list_file);
// В переменной $time теперь хранится текущее время
$time = time();
$j = -1;
$i = 0;
// Удаляем “мертвецов” и попутно ищем адрес отправителя
// в этом списке
while ($i < count($lst)) {
$lst[$i] = trim($lst[$i]);
list($l_ip, $l_port, $l_time) = explode(":", $lst[$i]);
// Если время с предыдущего пинга превысило 45 секунд
// – его явно уже нет
if ($l_time < ($time - 45)) {
for ($t = $i; $t < count($lst) - 1; $t++)
$lst[$t] = $lst[$t + 1];
unset($lst[count($lst) - 1]);
continue;
}
if ($l_ip == $ip) $j = $i;
$i++;
}

// Обработка запроса
switch ($mode) {
case 'view':
for ($i = 0; $i < Count($lst); $i++) {
// Вывод очередного IP:Port из списка
list($l_ip, $l_port, $l_time) = explode(":", $lst[$i]);
echo $l_ip.':'.$l_port.' ';
}
break;
case 'ping':
if ($j == -1)
// Если пингуется впервые, значит новый сервер - добавляем
array_push($lst, $ip.':'.$port.':'.$time);
else {
// Обновляем информацию для сервера
// Заметьте, что при смене порта на сервере
// на арене он тоже изменится
list($l_ip, $l_port, $l_time) = explode(":", $lst[$j]);
$lst[$j] = $l_ip.':'.$port.':'.$time;
}
break;
}

// Обновляем список серверов в файле-списке
$f = fopen($list_file, "a+");
flock($f, LOCK_EX);
ftruncate($f, 0);
for ($i = 0; $i < count($lst); $i++)
fwrite($f, $lst[$i]."\n");
fflush($f);
flock($f, LOCK_UN);
fclose($f);
?>

Файл со списком серверов должен находиться в "db/arena_list.txt" с атрибутами разрешающими его изменение.
________________
[Ссылки могут видеть только зарегистрированные пользователи. ]
http://i.zhyk.ru/images/KM9hf.png
  Ответить с цитированием
Пользователь сказал cпасибо:
=F1= (11.03.2014)
Ответ


Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход

Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Игровой сервер vlad199627 Обсуждение игровых проектов 0 10.03.2014 21:14
Игровой сервер Mu Seven Dante_3343 Прочее 0 13.03.2012 02:24
[Подсказка] Игровой сервер 2к+ Винсент Общение и обсуждение, архив Lineage 2 1 23.05.2011 02:14

Заявление об ответственности / Список мошенников

Часовой пояс GMT +4, время: 02:38.

Пишите нам: [email protected]
Copyright © 2024 vBulletin Solutions, Inc.
Translate: zCarot. Webdesign by DevArt (Fox)
G-gaMe! Team production | Since 2008
Hosted by GShost.net