Здравствуй, хабр! Мой прошлый пост «Как мы читы разрабатывали или кого сгубила жадность» вызвал у многих мракобесие, и в одном из советов от меня требовали конкретики. Требовали — держите мануал о том, как можно заменить Игровой Центр Mail.Ru(заодно расскажу про систему авторизации в Игровом Центре Mail.ru). Поехали!
Вы просили больше конкретики — держите! Итак, приступим.
Что нам понадобится?
Во-первых, нам нужен сервер с установленным на него PHP.
Во-вторых, нам нужна Visual Studio для разработки на C#
В-третьих, как можно было догадаться, нам нужна ОС Windows.
Разберемся с авторизацией Игрового Центра
(далее ГЦ)
1. Первым делом ГЦ отправляет на сервер запрос с логином/мэйлом и паролем пользователя(обращается к php-скрипту).
2. В ответе скрипт отсылает xml-данные в виде simple-xml, содержащий GcToken
3. ГЦ отправляет второй запрос на сервер параметром GcAuth
4. В ответе скрипт отсылает xml, содержащий SessionKey, Uid, Token, MinVersion и Timestamp
5. ГЦ запускает игру с Токеном, номером сервера и Uid
Начинаем разработку
Сначала напишем веб-интерфейс для управления программой
Создаем простую html-страничку с кнопкой «Start» и пишем JS-код для отправки POST-запросов и получения данных.
<html> <head> <title>Центр Игр</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <script type="text/javascript"> function gcauth(){ $.post("gcauth.php", { email: "тут email", password: "тут пароль" }, // Авторизуемся как ГЦ function(data){ var str = data.replace('"',''); var spl = str.split(""%""); var gcToken = spl[2]; //var uid = spl[1]; //alert(); $.post("autologin.php", { gctoken: gcToken }, // Уже с токеном ГЦ авторизуемся в игре function(logindata){ logindata = logindata.split("%"); var uid = logindata[0]; var token = logindata[1]; var link = "starter:" + logindata+";"; window.location.href = link; //alert(link); }) }); } </script> </head> <body> <button onclick="gcauth()">Start</button> </body> </html>
Регистрируем протокол, по которому будем осуществлять связь с программой
Создаем файл starter.reg
REGEDIT4 [HKEY_CLASSES_ROOT\starter] @="URL:Starter Protocol" "URL Protocol"="starter" [HKEY_CLASSES_ROOT\starter\shell] [HKEY_CLASSES_ROOT\starter\shell\open] [HKEY_CLASSES_ROOT\starter\shell\open\command] @="\"C:\\GameCenter@Mail.Ru.exe\" \"%1\""
Откроем файл и добавим данные в реестр
Пишем клиентское приложение на C#
1.Создаем новый проект Windows Forms в Visual Studio
2. Редактируем файл Program.cs
using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics; using System.Linq; using System.Net; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using System.Windows.Input; namespace WindowsFormsApplication1 { static class Program { /// <summary> /// Главная точка входа для приложения. /// </summary> static String ProcessInput(string s) { return s; } [STAThread] private static void Main(string[] args) //объявляем параметры(аргументы) { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); foreach (string s in args) { string[] arguments; // параметры string[] arr; // массив string uid; // ID юзера string token;// токен(уникальный ключ) arguments = ProcessInput(s).Split(':'); arr = arguments[1].Split(','); uid = arr[0]; token = arr[1]; /*- Далее добавляем переменные среды, если их не существует -*/ if (Environment.GetEnvironmentVariable("GC_PROJECT_ID") == null) // GC_PROJECT_ID 1177 Environment.SetEnvironmentVariable("GC_PROJECT_ID", "1177"); if (Environment.GetEnvironmentVariable("GC_TYPE_ID") == null) // GC_TYPE_ID 0 Environment.SetEnvironmentVariable("GC_TYPE_ID", "0"); if (Environment.GetEnvironmentVariable("GC_PIPE_NAME") == null) // GC_PIPE_NAME GameCenterV3 Environment.SetEnvironmentVariable("GC_PIPE_NAME", "GameCenterV3"); if (Environment.GetEnvironmentVariable("GC_GCLAY_PATHNAME") == null) // GC_GCLAY_PATHNAME C:\...\Local\Mail.Ru\GameCenter\GCLay.dll Environment.SetEnvironmentVariable("GC_GCLAY_PATHNAME", @"Путь к \GameCenter\GCLay.dll"); // Здесь указываем путь к GCLay.dll if (Environment.GetEnvironmentVariable("CHROME_ALLOCATOR") == null) // CHROME_ALLOCATOR TCMALLOC Environment.SetEnvironmentVariable("CHROME_ALLOCATOR", "TCMALLOC"); Environment.SetEnvironmentVariable("MOZ_CRASHREPORTER_DATA_DIRECTORY", ""); Environment.SetEnvironmentVariable("MOZ_CRASHREPORTER_RESTART_ARG_0", ""); Environment.SetEnvironmentVariable("MOZ_CRASHREPORTER_STRINGS_OVERRIDE", ""); Process.Start("C:\\GamesMailRu\\Warface\\Bin32Release\\Game.exe", "--shard_id=0 +online_server s0.warface.ru -uid "+uid+" -token "+token); // Запускаем Warface с параметрами MessageBox.Show("Click [OK] to close"); // Тормозим завершение программы } } } }
Настраиваем серверную часть
Пишем PHP-скрипты для получения токенов и т.д.
*Мы не будем снифферить отправляемые и принимаемые заголовки, а используем те, которые уже были получены
Создаем файл gcauth.php
<?php header('Content-type: text/html; charset=utf-8'); // вход в систему // имя хоста, куда будем заходить $hostname = 'authdl.mail.ru'; $email = $_POST['email']; $password = $_POST['password']; // инициализация cURL $ch = curl_init('https://'.$hostname.'/ec.php?hint=GcAuth'); // получать заголовки curl_setopt ($ch, CURLOPT_HEADER, 1); // если ведется проверка HTTP User-agent, то передаем один из возможных допустимых вариантов: curl_setopt ($ch, CURLOPT_USERAGENT, 'Downloader/4000'); // елси проверятся откуда пришел пользователь, то указываем допустимый заголовок HTTP Referer: curl_setopt ($ch, CURLOPT_REFERER, $hostname); // использовать метод POST curl_setopt ($ch, CURLOPT_POST, 1); // сохранять информацию Cookie в файл, чтобы потом можно было ее использовать curl_setopt ($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); // передаем поля формы curl_setopt ($ch, CURLOPT_POSTFIELDS, '<?xml version="1.0" encoding="UTF-8"?><GcAuth Username="'.$email.'" Password="'.$password.'" ChannelId="0"/>'); // возвращать результат работы curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); // не проверять SSL сертификат curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); // не проверять Host SSL сертификата curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); // это необходимо, чтобы cURL не высылал заголовок на ожидание // выполнить запрос curl_exec ($ch); // получить результат работы $result = curl_multi_getcontent ($ch); $data = curl_exec($ch); $xml = htmlspecialchars($result); preg_match('/SessionKey=["\']?([^"\' ]*)["\' ]/is',$xml,$sessionKeyArr); // Выделяем SessionKey из ответа регулярками preg_match('/Uid=["\']?([^"\' ]*)["\' ]/is',$xml,$uidArr); // То же самое с ID юзера preg_match('/Token=["\']?([^"\' ]*)["\' ]/is',$xml,$tokenArr); // ... с Токеном preg_match('/MinVersion=["\']?([^"\' ]*)["\' ]/is',$xml,$minVersionArr); // Минимальная версия, нам это не понадобится //preg_match('/Timestamp=["\']?([^"\' ]*)["\' ]/is',$xml,$timestampArr); // Время, нам тоже не нужно $SessionKey = str_replace("\"", "",$sessionKeyArr[1]); $Uid = str_replace("\"", "",$uidArr[1]); $Token = str_replace("\"", "",$tokenArr[1]); $replace_quotes = array('"', "'"); $MinVersion = str_replace($replace_quotes, "", $minVersionArr[1]); /*- Выводим данные -*/ echo $SessionKey; echo "%"; echo $Uid; echo "%"; echo $Token; echo "%"; echo trim($MinVersion); //echo $Timestamp; //echo $xml; //echo $matches; // закрыть сессию работы с cURL curl_close ($ch); ?>
Теперь создадим autologin.php
<?php header('Content-type: text/html; charset=utf-8'); $GcToken = $_POST['gctoken']; // вход в систему // имя хоста, куда будем заходить $hostname = 'authdl.mail.ru'; // инициализация cURL $ch = curl_init('https://'.$hostname.'/sz.php?hint=AutoLogin'); // получать заголовки curl_setopt ($ch, CURLOPT_HEADER, 1); // если ведется проверка HTTP User-agent, то передаем один из возможных допустимых вариантов: curl_setopt ($ch, CURLOPT_USERAGENT, 'Downloader/4000'); // елси проверятся откуда пришел пользователь, то указываем допустимый заголовок HTTP Referer: curl_setopt ($ch, CURLOPT_REFERER, $hostname); // использовать метод POST curl_setopt ($ch, CURLOPT_POST, 1); // сохранять информацию Cookie в файл, чтобы потом можно было ее использовать curl_setopt ($ch, CURLOPT_COOKIEJAR, 'cookie.txt'); // передаем поля формы $postfield = '<?xml version="1.0" encoding="UTF-8"?><AutoLogin ProjectId="1177" SubProjectId="0" ShardId="0" GcToken="'.$GcToken.'"/>'; curl_setopt ($ch, CURLOPT_POSTFIELDS, $postfield); // возвращать результат работы curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1); // не проверять SSL сертификат curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); // не проверять Host SSL сертификата curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); // это необходимо, чтобы cURL не высылал заголовок на ожидание // выполнить запрос curl_exec ($ch); // получить результат работы $result = curl_multi_getcontent ($ch); $data = curl_exec($ch); $xml = htmlspecialchars($result); preg_match('/PersId=["\']?([^"\' ]*)["\' ]/is',$xml,$persIdArr); // Выделяем PersId из массива полученных данных preg_match('/Key=["\']?([^"\' ]*)["\' ]/is',$xml,$keyArr); // то же самое с Key $PersId = str_replace(""", "",$persIdArr[1]); $Key = str_replace(""", "",$keyArr[1]); /*- Выводим полученные данные -*/ echo $PersId; echo "%"; echo $Key; // закрыть сессию работы с cURL curl_close ($ch); ?>
Теперь осталось лишь залить все на сервер и испытать. На время написания статьи могла быть написана какая-либо проверка еще на что-то.
Спасибо за прочтение мануала. Надеюсь, в чем-то я вам помог, удачи!
Разработчикам Mail.Ru советую доработать клиентское приложение, чтобы исходящие соединения не показывались.
ссылка на оригинал статьи http://habrahabr.ru/post/231157/
Добавить комментарий