Я решил сделать персонально свой сервер этой игры.
Не смотря на то что
Инструменты
- Любой браузер с инспектором
- Adobe Flash Media Server (старую версию из 2009 так как новые не умеют в флэш. Спокойно ищется на всяких торрент трекерах) или Red5
- Знание ECMAScript
- Декомпиль флешек, я выбрал JPEXS Free Flash Decompiler потому что бесплатно
- Adobe Flash Content Debugger
Логотип
Спасибо за логотип EarthShaker'у
Первые шаги
- Регаемся в игре
- Смотрим в инспекторе какой мусор нам шлет HTTP сервер
- Находим /async/ServerAction и радостно кликаем по добыче
- С удивлением обнаруживаем такую картину. В CDATA какая то муть шифрованная (благодаря друзьям-криптоманьякам выяснилось что это RC4)
Поиски ключа
Вроде бы все уже хорошо, но у нас нет ключа. Поэтому скачиваем base.swf из хтмл страницы игры и открываем его на обследование в декомпиль. Благодаря наличию Адоб Флэша я попробовал данный кусок кода
trace(_root);
который вернул _level0 в лог. Защита от школоанонимусов??
Угадываем что у Шарарама в качестве игрового сервера
Это было сделать не сложно. Всего лишь гуляем по исходникам и обнаруживаем файл FmsAPI. Гуглим че за FMS и…
это к сожалению не то, поэтому гугланём чё-то посерьезнее
Бинго, но я все еще сомневался, поэтому идем в Википедию.
Ну это уже серьезный аргумент. Можно уже 100% утверждать что это оно.
Бороздил гугл, оказалось что еще есть Red5 (да, я пытался сделать и на нем но чето дело не пошло).
Делаем сервак
Для начала напишем серверную сторону.
Мой php-говнокод для /async/* выглядит так (обьяснения в комментах в коде)
<?php
// просто для эстетичности
header("Content-type: text/xml");
// включаем rc4 и остальные мелочи
include "crypto.php";
include "utils.php";
include "settings.php";
// смотрим че нас просят
switch ($_GET["action"]) {
// инфа о юзере
case 'ServerAction':
// данные которые мы зашифруем и спакуем в CDATA-ноды
// конфиг (впринципе можно и не редактировать)
$config = '<config><item Id="1" Parameter="AccessRoleFlags" Value="0" Type="number" /><item Id="3" Parameter="IsPreloaderFast" Value="0" Type="bool" /><item Id="4" Parameter="InitialVolumeValue" Value="30" Type="number" /><item Id="6" Parameter="IsPreloaderEnabled" Value="1" Type="bool" /><item Id="7" Parameter="IsStartupHomeLocation" Value="0" Type="bool" /><item Id="8" Parameter="SwfVersion" Value="" Type="string" /><item Id="9" Parameter="SynchronizeAvatarRotation" Value="1" Type="bool" /><item Id="10" Parameter="StatisticsSendInterval" Value="0" Type="number" /><item Id="12" Parameter="LanguageId" Value="1" Type="number" /><item Id="13" Parameter="SnId" Value="1" Type="number" /><item Id="14" Parameter="IsInternational" Value="0" Type="bool" /><item Id="15" Parameter="AutoServerSelectionAllowed" Value="1" Type="bool" /><item Id="16" Parameter="DaysToFullSoil" Value="28" Type="number" /><item Id="17" Parameter="DaysToHalfSoil" Value="14" Type="number" /><item Id="18" Parameter="CurrentQuest" Value="421" Type="number" /><item Id="20" Parameter="TypeWeapon" Value="3" Type="number" /><item Id="21" Parameter="SkipTutorial" Value="1" Type="bool" /><item Id="23" Parameter="CurrentQuestGroup" Value="6161" Type="string" /><item Id="24" Parameter="IsNewRegistration" Value="1" Type="bool" /><item Id="25" Parameter="IsMotivatingAdsOn" Value="0" Type="bool" /></config>';
// cписок серверов. можно либо вынести инфу о серве в другой файл
// или редачить её тут
// особый смысл имеют TRId (название сервера), RTMPUrl (ссылка на сервер) и в принципе все. Остальное чисто косметическое.
$serversList = '<servers><item Id="1" TRId="'.$gameServer_name.'" RId="5" RTMPUrl="rtmp://'.$gameServer_ip.':'.$gameServer_port.'/'.$gameServer_appname.'" Load="46" QuestLocationLoad="0" FriendsCount="0" ClubsCount="4" Weight="5.1" /></servers>';
// айди, hwid (wtf??), тикет (для фронтэндеров - это типа JWT) и RoleFlags это типа кто юзер (картный, безкартный, модер, админ, etc)
$userData = '<user UserId="1" hwId="'. getGUID() .'" ticketId="'. getGUID() .'" RoleFlags="2" />';
// тут тоже особо ничего редачить не надо
$system = '<system ServerDate="'.date('Y-m-d H:i:s').'" RPath="fs/3p897j5lf4e0j.swf" RVersion="56" />';
// всякая инфа о юзере и наши CData которые мы шифруем прямо там
echo '<?xml version="1.0" encoding="utf-8"?>
<response>
<promotion>
<i MRId="20106" State="1" />
<i MRId="30896" State="7" />
</promotion>
<promotion_banner>
<i MRId="30896" />
</promotion_banner>
<promotion_whats_new>
<i Id="386" TypeId="1" MRId="20143" />
<i Id="611" TypeId="2" MRId="27179" />
<i Id="784" TypeId="2" MRId="30841" />
<i Id="785" TypeId="2" MRId="30895" />
<i Id="786" TypeId="2" MRId="30897" />
</promotion_whats_new>
<preloader>
<i MRId="30894" ShowTime="20;00" />
</preloader>
<sn_status IsBinded="0" />
<phone>
<messages/>
</phone>
<user_name Value="test" />
<postcard>
<messages/>
</postcard>
<licence_promotion>
<item Id="1" GroupId="0" OrderId="0" MRId="14763" />
<item Id="2" GroupId="0" OrderId="1" MRId="14764" />
<item Id="3" GroupId="0" OrderId="2" MRId="14765" />
<item Id="4" GroupId="1" OrderId="0" MRId="14766" />
<item Id="5" GroupId="1" OrderId="1" MRId="14767" />
<item Id="6" GroupId="1" OrderId="2" MRId="14768" />
<item Id="7" GroupId="2" OrderId="0" MRId="20597" />
<item Id="8" GroupId="2" OrderId="1" MRId="20598" />
<item Id="9" GroupId="2" OrderId="2" MRId="20599" />
</licence_promotion>
<flags EntranceCount="2600" />
<tutorial>
<item Id="-1" State="1" />
<item Id="1" State="1" />
<item Id="2" State="1" />
<item Id="3" State="1" />
<item Id="4" State="1" />
<item Id="5" State="1" />
</tutorial>
<miniquest>
<i Id="148515433" MiniquestId="90004" IsPostponed="0" StartDate="2018-06-06T18:58:28.113">
<i Id="298265808" TaskId="900041" IsFinished="0" Counter="3" />
<i Id="298265809" TaskId="900042" IsFinished="0" Counter="0" />
<i Id="298265810" TaskId="900043" IsFinished="1" Counter="0" />
</i>
</miniquest>
<grants ReceivingCount="0" />
<requests ReceivingCount="0" />
<cdata value="'. encrypt($config) .'" />
<cdata value="'. encrypt($system) .'" />
<cdata value="'. encrypt($userData) .'" />
<cdata value="'. encrypt($serversList) .'" />
</response>';
break;
// простой php-пинг
case 'Ping':
echo '<response isPong="true" />';
break;
// add more below
default:
echo "<!-- there's nothing -->";
break;
}
?>
В файле settings.php это
<?php
// php settings
error_reporting(E_ERROR | E_PARSE);
// server settings
$gameServer_ip = "127.0.0.1";
$gameServer_port = 1935;
$gameServer_name = 202; // check http://sharaball.ru/fs/3p897j5lf4e0j.swf for strings you can use (also, you can edit this file in any SWF editor)
$gameServer_appname = "shararam"; // название инстанса на стороне fms
?>
В файле utils.php это
<?php
// http://guid.us/GUID/PHP
function getGUID(){
$charid = strtoupper(md5(uniqid(rand(), true)));
$hyphen = chr(45);// "-"
$uuid = substr($charid, 0, 8).$hyphen
.substr($charid, 8, 4).$hyphen
.substr($charid,12, 4).$hyphen
.substr($charid,16, 4).$hyphen
.substr($charid,20,12);
return $uuid;
}
?>
В crypto.php это
<?php
function rc4( $key_str, $data_str ) {
// convert input string(s) to array(s)
$key = array();
$data = array();
for ( $i = 0; $i < strlen($key_str); $i++ ) {
$key[] = ord($key_str{$i});
}
for ( $i = 0; $i < strlen($data_str); $i++ ) {
$data[] = ord($data_str{$i});
}
// prepare key
$state = array( 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,
32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,
48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,
64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,
80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,
96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,
112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,
240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255 );
$len = count($key);
$index1 = $index2 = 0;
for( $counter = 0; $counter < 256; $counter++ ){
$index2 = ( $key[$index1] + $state[$counter] + $index2 ) % 256;
$tmp = $state[$counter];
$state[$counter] = $state[$index2];
$state[$index2] = $tmp;
$index1 = ($index1 + 1) % $len;
}
// rc4
$len = count($data);
$x = $y = 0;
for ($counter = 0; $counter < $len; $counter++) {
$x = ($x + 1) % 256;
$y = ($state[$x] + $y) % 256;
$tmp = $state[$x];
$state[$x] = $state[$y];
$state[$y] = $tmp;
$data[$counter] ^= $state[($state[$x] + $state[$y]) % 256];
}
// convert output back to a string
$data_str = "";
for ( $i = 0; $i < $len; $i++ ) {
$data_str .= chr($data[$i]);
}
return $data_str;
}
function encrypt($str){
return bin2hex(rc4("_level0", $str));
}
?>
Мой htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteRule ^async/(.*) asyncController.php?action=$1
Код сервера
Это уж слишком старый образец, там уже было шифрование в rc4 на сервере, я новый потерял поэтому придется показать вам этот ужас.
H2CA разбивает строку в массив чтобы сервер её скушал, такова обсфукация
/*
* RolyPolyWorld Server Code
* by Semen Elkin, 2018
*/
function H2CA(hex) {
var _loc3_ = [];
var _loc1_ = hex.substr(0, 2) != "0x" ? 0 : 2;
while (_loc1_ < hex.length) {
_loc3_.push(parseInt(hex.substr(_loc1_, 2), 16));
_loc1_ = _loc1_ + 2;
}
return _loc3_;
}
Client.prototype._LS = function(descriptor, startPoint, startState) {
return "";
}
Client.prototype._NSF = function() {
return "";
}
Client.prototype.$ = function(CMD, srvName, _unknown, __unknown, callback) {
trace("CMD: " + CMD);
if (CMD == "_I") {
// return UserInitData
return [H2CA("e4ba5848485429d25723c62654510684f67e7b2cffb0debd608de7bca09d0b10f8a0c511b52c5fb57adc0321b8edef0b0cde086422a751a8604104a1d6b5bd050e19ac989ec6f44ff7f6998af46ffac822fe0673c54823fd8b1744f6b09907cb69e703cc4941ca27c0783ea6085f35eaf0614ba95507eeca1e2662d40c43857b0fa1cc045851c6a3d8e81cac73468c7ed174731c50b2141576a808f7a4cb7026e2253ebff413b1a3bc5907c9a13783dd8cdeccf636c48720cea4cf3040eb339a4329ca4c731218719e9366d6ce24ec2fee9f67ca586bdf0c6764051deb33972c640a6775bb206c707003e22e078ef18e77faf6e84423332f4212a2ae12ba56a537f05fac4fa7598487dd138396db4db00a85c28a533d3a2645f00fa2a0b1c4ffdd5b5d015c935909e23950a63ae37f2d1345d86296470633f47d8b9c6c423a2d429e6b06b596b4c914cf12b850640aa91f51d456994dc57c2a4cb32116b5b4c4a1d5768eecfa2e158d4c42f64294793c0da42bc5c949ae7f0501b488906bb4609c0443c7c8d3b675605762aec6dcda5b813f3abcf8ec8706c137889c0809bfd90c1e191aacc84d35317b2418e6cfc8429d1f0b0532b0e4ff0e1c57f8a46c64f806cc8b1509691b0266b921f61d670a73480c4e83935438e9f1a84708f755ab3e66e78a6ae3d2a88ee3e8083a994e6212162d388a6df2f100e11ea5d2367b8c016804790cbbb4bcadd1f415dddd8814672a235a6a7236521010596a0abe0e8d8ba9930e4c85c103d8dc12439482c6bde7d215b2f43dd20a3862f191fb134d8a590dda31ddbe4575a197db52170715c6e302038554c953c8a6875a26240452c75e19ba0fdac1c6894a134bb998011fd88b1c175face045a7d192159d84c1d848996a367055c0b5b5efad7827d3dc3e9dd3c361cbc59c915089ed79768f9e1cf6ad60acbd7e418e6c0dfb63389135745bcdb45fb1c83b6471223f0e00f09203f6a580ae863c2c7c1ecd7f8117daa623868e5f040e74ce8c409e2d26ae0b51f8f4c1dfb15114098aa3f7f38703d53d1654d393ae82d6b65a19a0c782373789c9b6f55bfddd224e977bcf8b15a810f5d0888380d4543361c7daaf12f3cdc02f098f044a04c47996439820d82a22dc8439e0a0470cf4989dae13a827fb946ef29271ead58ae31934ba490492f4d4f97a440c3b1983e9eb431050f1e14ead8ac032973ffad1a257cd652976ec9d8a4c8c480be6b254ad017d6e8d25c97edd6723880a50f94860fbc0b5bbd6b9234971a251fd351d17bc12ebf71b47f72c2c393e2d79be2779d27612522942a5629c453f6063c4905d5b64749c1690dd2d918bf7845cba8ff3d9b0726dd724641926f6493a1438af12f1263cf8e9781ef5ac8e9ac4ce63db2e8b2761431d0fdc1f70f8b75908f597697aeaef3849e2b525681d13d493707e45f40f07461cea503ba038ec76981a6abf733bea79eff7121b97515943196417660fb854e43fba68d2bfbb5fc5ecf66f2cfffa9c62dd60731d4f92be76d63da3f4f19ad1a7b41ff7bdcf4c7e6e5629c475b0fed66768681f76d5bab4287c355eb951953a3795d381afed2aed639782fda5377c23d67d90c3f6f5fcea5c41a5567082c32cfb4886fe63aec9a6373ce924072fab5ff340b415470e8d973da687319b9259ccf0ebd78b2c2d05453463f7efb8278188b5a9e6fef9b9c26051af9295521015ec19a8997cd76903e65eca7a2538ff2c4c07f6df5e951485242f171f07bc72f99a69fcd3119dabfaf3e4be78264a32d0f82d2de290ec62b4ed5b9d1db59d42e9ab41bad695ff25a47271cae2ca52013743cf8b72c3315896e65a0f8158ac9b92a010002d4b846d0c984274e65be446e237397633929bd1fdfceeca06deeaa33f6097b8a203042ff8a72d342061487e2a335a688d28334b87313709bd0cc0f99d6dcc961f9f4d628d812a2bb4478263817a714cf9fd50423f28c70c1ed03222764630faf695da3936aa384315b63d2b9b44f1c911df43fba1f8353787eee6ab2be85ae010c2cfd60ce3c8522cdc32df85202abafa4925bea3bf2c5766dfb0f56e0e882847d57ff9e4c9df52b8652319a3008e22becc5a162fb5e90ca62f961f42e342003d0ca98d48eaafa9a698be8734e42db75befc380ff67cdecdc8297315bda07f1c9eebda90ecc128f01e7187eb14971541da50b7878e897bea0ac8ebefd3a4115b3e21a0bc07dd92f5050fca020e63a3c8a9d123327fb8d0200f4d85892cc906bc1f4865e8c75d0b68a43f54e0204d3a18886e125a478a6da9129e5f79f4f4bbb4f4385d84aa3392d752c44dadbdca771a8a8202a22631e02559b7deb2e8f8aaa52eef394")];
} else if (CMD == "_UFG") {
// Friends list get
return ""; quests
} else if (CMD == "_UFR") {
// Friends requests get
return "";
} else if (CMD == "_CM") {
// GetClubMap
return "<clubmap />";
} else if (CMD == "_SNFP") {
// GetFriendPanelData
return '<root><L4><i UserId="3490071" UserName="56" AvatarUrl="https://sharaball.ru/shimg?u275AF9B0E0FB47AE" IsOnline="true" Level="59" RoleFlags="2" IsHomeLocked="true" /><i UserId="22033" UserName="UberSoldat" AvatarUrl="https://sharaballru/shimg?u7705945283620CEC" IsOnline="true" Level="50" RoleFlags="2" IsHomeLocked="false" /><i UserId="26514836" UserName="953" AvatarUrl="https://sharaballru/shimg?u70A0C3FFDC2AE686" IsOnline="true" Level="44" RoleFlags="0" IsHomeLocked="true" /><i UserId="4294784" UserName="-22" AvatarUrl="https://sharaballru/shimg?uA0F2D2940A2C0680" IsOnline="false" Level="66" RoleFlags="0" IsHomeLocked="true" /><i UserId="6514777" UserName=" 7" AvatarUrl="https://sharaballru/shimg?u7633EEBAAC8D8750" IsOnline="false" Level="62" RoleFlags="0" IsHomeLocked="true" /><i UserId="15918373" UserName="Gamer9999" AvatarUrl="https://sharaballru/shimg?u3F6E105179A94CF9" IsOnline="false" Level="60" RoleFlags="2" IsHomeLocked="false" /><i UserId="5499397" UserName="2014" AvatarUrl="https://sharaballru/shimg?uFAA76A3F45E04650" IsOnline="false" Level="59" RoleFlags="0" IsHomeLocked="true" /><i UserId="6765542" UserName="2399" AvatarUrl="https://sharaballru/shimg?uBC8AF14DC9568867" IsOnline="false" Level="57" RoleFlags="0" IsHomeLocked="true" /><i UserId="6091024" UserName="60" AvatarUrl="https://sharaballru/shimg?u6254ABCD6C72BA40" IsOnline="false" Level="55" RoleFlags="0" IsHomeLocked="true" /><i UserId="5335890" UserName="992" AvatarUrl="https://sharaballru/shimg?uB51CD240A8D9A6F8" IsOnline="false" Level="54" RoleFlags="0" IsHomeLocked="true" /><i UserId="7403986" UserName="" AvatarUrl="https://sharaballru/shimg?uAFC6BB4C6CB5523B" IsOnline="false" Level="54" RoleFlags="0" IsHomeLocked="true" /><i UserId="3711098" UserName="12345x" AvatarUrl="https://sharaballru/shimg?u30D03C19372FD998" IsOnline="false" Level="53" RoleFlags="0" IsHomeLocked="true" /><i UserId="2477499" UserName="" AvatarUrl="https://sharaballru/shimg?u2FDDD1060A5F77A4" IsOnline="false" Level="52" RoleFlags="0" IsHomeLocked="true" /><i UserId="6881717" UserName="" AvatarUrl="https://sharaballru/shimg?uA1B439427D7B3055" IsOnline="false" Level="52" RoleFlags="0" IsHomeLocked="true" /><i UserId="3747929" UserName="329" AvatarUrl="https://sharaballru/shimg?uC60A8606BA6F5F20" IsOnline="false" Level="51" RoleFlags="0" IsHomeLocked="true" /><i UserId="491914" UserName="votetu" AvatarUrl="https://sharaballru/shimg?uF843320FF79B6387" IsOnline="false" Level="48" RoleFlags="0" IsHomeLocked="true" /><i UserId="5143339" UserName=" 908" AvatarUrl="https://sharaballru/shimg?u2521238E5E881E10" IsOnline="false" Level="48" RoleFlags="0" IsHomeLocked="true" /><i UserId="7164879" UserName="SuperKohka" AvatarUrl="https://sharaballru/shimg?uDF898434F4FA678A" IsOnline="false" Level="48" RoleFlags="0" IsHomeLocked="true" /><i UserId="21200791" UserName="Alsoa" AvatarUrl="https://sharaballru/shimg?uA418D0DB845DEDF5" IsOnline="false" Level="48" RoleFlags="2" IsHomeLocked="false" /><i UserId="28287949" UserName="630" AvatarUrl="https://sharaballru/shimg?uF02BE2EAF00206CF" IsOnline="false" Level="48" RoleFlags="2" IsHomeLocked="true" /><i UserId="6858621" UserName="200125" AvatarUrl="https://sharaballru/shimg?u02E14C376A340686" IsOnline="false" Level="46" RoleFlags="0" IsHomeLocked="true" /><i UserId="5116798" UserName=" 2" AvatarUrl="https://sharaballru/shimg?uBD09B4CE3AE8832A" IsOnline="false" Level="43" RoleFlags="0" IsHomeLocked="true" /><i UserId="6858399" UserName="wosso" AvatarUrl="https://sharaballru/shimg?uD2CABA24168A42DD" IsOnline="false" Level="43" RoleFlags="0" IsHomeLocked="true" /></L4></root>';
} else if (CMD == "_D") {
// UpdateUserData
return {
callback_uid: callback
};
} else if (CMD == "_LG") {
// GetLocation
return '<location ID="28" IsHome="0" IsClub="0" IsLocked="0" IsVisaAccessPermitted="1" MediaResourceID="30644" x="550.0" y="380.0" Name="test"> <options> <Constraints> <item ID="0" Type="Q" QuestId="390" StepId="23" StateCode="1" Equally="1" Value="2" RoomState="0" /> </Constraints> </options> <object ID="28002" AObjectTypeId="2" AObjectId="61" AObjectRefId="25" MediaResourceID="30648" x="634.0" y="197.0" /> <object ID="28003" AObjectTypeId="2" AObjectId="70" AObjectRefId="19" MediaResourceID.="30645" x="674.0" y="227.0" /> <object ID="28004" AObjectTypeId="2" AObjectId="71" AObjectRefId="30" MediaResourceID="30647" x=".135.0" y="153.0" /> <object ID="28010" AObjectTypeId="2" AObjectId="532" AObjectRefId="54" MediaResourceID="3587" x="130.0" y="33.0.0"> <options> <override AObjectTypeId="18" /> <conditions> <User IsSecretAgent="1" /> </conditions> </options> </object> <object ID="28733" AObjectTypeId="2" AObjectId="733" AObjectRefId="6" MediaResourceID="30646" x="490.0" y="120.0" /> </location>';
} else if (CMD == "_UOG") {
if ( __unknown == "whats_new_data"){
return "1|2|3";
} else if ( __unknown == "pet_battle_news"){
return "1|2|3";
} else {
trace("_UOG OPTION " + __unknown);
}
} else if (CMD == "_UOS") {
// SetUserOption
} else if (CMD == "_GOGI") {
// GetGroupObjectInfo
return '<group_object UOGId="-6163" ObjectGroupId="6163" ObjectGroupTypeId="101" ControllerType="4" Stored="0" ContorollerMRId="30781"> <item Id="6163001" AObjectId="828" AObjectTypeId="2" AObjectRefId="27" MediaResourceID="30775" LocationId="19" X="284" Y="136" IsActive="1" IsInterractable="1" /> <item Id="6163002" AObjectId="3193" AObjectTypeId="50" MediaResourceID="30373" LocationId="27" X="295" Y="332" Frame="F$0" IsActive="1" IsInterractable="1" /> <item Id="6163003" AObjectId="3194" AObjectTypeId="50" MediaResourceID="30774" LocationId="85" X="475" Y="303" Frame="F$0" IsActive="1" IsInterractable="1" /> <item Id="6163004" AObjectId="3195" AObjectTypeId="50" MediaResourceID="30776" LocationId="85" X="116" Y="123" Frame="F$0" IsActive="1" IsInterractable="1" /> <item Id="6163005" AObjectId="3196" AObjectTypeId="50" MediaResourceID="30777" LocationId="85" X="282" Y="100" Frame="F$0" IsActive="1" IsInterractable="1" /> <item Id="6163006" AObjectId="3197" AObjectTypeId="50" MediaResourceID="30778" LocationId="85" X="453" Y="160" Frame="F$0" IsActive="1" IsInterractable="1" /> </group_object>';
} else if (CMD == "_ULNS") {
// SetUserLastNewspaper
return "asd";
} else if (CMD == "_DA") {
return '<kek> <ID>1</ID> <IsSecretAgent>1</IsSecretAgent> <IsMember>1</IsMember> <IsPresent>1</IsPresent> <IsActive>1</IsActive> <Units>5</Units> <MessageID>2</MessageID> </kek >';
} else {
trace("Unknown command: " + CMD);
}
}
Client.prototype._SCD = function(callback) { // get server time
return 123;
}
application.onConnect = function(client) {
this.acceptConnection(client);
}
XML который мы шлем серверу выглядит так. Ничего особенного.
<userInitData>
<user Id="1" RoleFlags="2" Level="100" PositiveEnergy="11" IsMinorSecretAgent="1" MagicTickets="999" UsualTickets="999" />
</userInitData>
<account>
<PhoneCardBalance>123</PhoneCardBalance>
<WeaponsCount>2</WeaponsCount>
<OxigenUnits>5</OxigenUnits>
</account>
<secret_agent>
<StartDate>000</StartDate>
<Number>123</Number>
<Interval>2</Interval>
</secret_agent>
<user_avatar></user_avatar>
<smiles>
<Id>1</Id>
</smiles>
<pets />
<pet_battle_places></pet_battle_places>
<user_magic_abilities>
<Id>1</Id>
<ExpirationDate>DATE</ExpirationDate>
<IsLimited>false</IsLimited>
</user_magic_abilities>
<user_phone>
<BufferSize>1</BufferSize>
<SkinMediaResourceID>112</SkinMediaResourceID>
<PhoneId>2</PhoneId>
<Balance>999</Balance>
</user_phone>
<quests>
<Id>148515433</Id>
<StateCode>90004</StateCode>
<UpdateDate>2018-06-06T18:58:28.113</UpdateDate>
<RecordDate>2018-06-06T18:58:28.113</RecordDate>
<StartDate>2018-06-06T18:58:28.113</StartDate>
<LastFinishedStep>0</LastFinishedStep>
<GamesScore>0</GamesScore>
<GamesCount>0</GamesCount>
<TeleportId>0</TeleportId>
<MRId>1</MRId>
<IconMRId>5</IconMRId>
<EndDate></EndDate>
</quests>
<questgamedata></questgamedata>
<magiclessons></magiclessons>
<ufoquestinfo></ufoquestinfo>
<res_objects></res_objects>
<actions></actions>
<spend_cones></spend_cones>
<options></options>
<mission_dobject></mission_dobject>
<smiles></smiles>
<positive_energy></positive_energy>
<giftbox_digger></giftbox_digger>
<object_groups></object_groups>
<game_award_pack></game_award_pack>
<sn_og_status></sn_og_status>
<notices></notices>
<controller></controller>
<bonus_day></bonus_day>
<informer_bonus></informer_bonus>
<nift></nift>
<sharagent></sharagent>
<stpack></stpack>
<yavideo></yavideo>
Встретимся в следующем эпизоде!
Комментарии (2)
poloart
18.10.2018 10:28Я не могу никак повлиять на репутацию других и пишу один пост в день, но такие посты на хабре я очень люблю. Вот причины
1. Это старый хабр
2. Это исследование того, что «какбе» скрыто
3. Я ничего не знал про игру Шарарам и вряд ли узнаю, но…
Сам этот пост всего лишь то, что я хочу видеть на хабре. Я хочу читать про новые технологии (подробно!), про исследование того, что «скрыто», про умных людей, про подробные гайды в изложении «для всех» и так далее.
Я не хочу видеть на хабре опусы а-ля алазара — убейся об стол!!! И другой «копирайтинг/копипаст» того материала, что я уже прочитал или могу прочитать на ресурсах вроде «газета.ру» и прочих популярных сми.
Мне нужен (а своё мнение вы можете оставить несколько ниже, или просто повесить шпалу — вы ж это тут так любите, шпала без камента, это ж прям черта хабраюзера, зашпалил и в норку) материал чуть ниже или чуть выше уровня обывателей.
VBKesha
Ставлю плюс, хотя думаю это не спасет. ИМХО код надо убрать под спойлеры хотя бы, а лучше на гитхаб. И анализа когда, или хотя бы его его запрос-ответов надо поболее, а так я тут набросал вот это, оно как то работает, не красиво.