Игровой Центр@Mail.Ru

от автора

Здравствуй, хабр! Мой прошлый пост «Как мы читы разрабатывали или кого сгубила жадность» вызвал у многих мракобесие, и в одном из советов от меня требовали конкретики. Требовали — держите мануал о том, как можно заменить Игровой Центр 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/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *