...

суббота, 6 августа 2016 г.

MirrorMoon EP — в поисках заветной планеты

MirrorMoon EP
Осторожно, спойлеры и артхаус! Если вы в тупике и отчаянии, то эта статья должна помочь вам пройти игру. Плюс, технические подробности.


Предисловие


Это была самая странная, долгая и познавательная охота за ачивкой. Был изучен код игры, воссоздан API и реализован звездный навигатор для этой бесконечной космической одиссеи. Весь путь я проклинал разработчиков. Ведь, по сути, игра длится всего 10 минут. А дальше, дальше только пустота и надежда. Но как я рад теперь! Благодаря разработчикам и моему стремлению я многое узнал. Далее само прохождение.



Обсерватория


Перейдя на сторону B, мы начинаем путешествие. Поначалу, кажется, оно не имеет цели, но найдя первую обсерваторию, мы видим кружок. Это наша цель. В обсерватории мы наблюдаем созвездия. Выбрав ближайшие звезды, начинаем на них охоту. Если эти звезды уже открыты, то мы можем запускать навигатор и вычислять цель.


MirrorMoon EP Constellation


Звезды


Названия звезд генерируются из трех букв и двух случайных чисел. Буквы привязаны к координатам. Найдите любую звезду, где первые две буквы будут совпадать с искомой звездой. Прыгайте туда и ищите, непосредственно, нужную вам звезду. Она должна быть рядом. Пометив нужные звезды, идем в навигатор.


Финал


Выбираем сезон. Помечаем все нужные звезды. Находясь на планете с обсерваторией, включаем режим OBS. Просчитываем расположение звезд, перекрестие должно указывать на загадочную планету. Выходим из режима OBS. Включаем ортогональную проекцию. Теперь мы видим карту как в игре. Идем в игру и подгоняем вид. Где-то в центре мы найдем далекую звезду и прыгнем туда, в надежде..


MirrorMoon EP Observer


Реализация


MirrorMoon EP создан на Unity 3D. Поэтому было не сложно декомпилировать код. Алгоритм следующий. Открываем урл — http://ift.tt/2aJhkU3. Нас интересует последняя строчка. В ней находится кол-во сезонов. Это число используется для генерации хэша. Также нам потребуется секретный ключ thankyouforhackingmysecretkey1234568. О нет, нас раскусили :)


string getHash(string text) {
    MD5 md5Hash = MD5.Create ();
    byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(text));
    StringBuilder sBuilder = new StringBuilder();
    for (int i = 0; i < data.Length; i++)
        sBuilder.Append(data[i].ToString("x2"));
    return sBuilder.ToString();
}

string availableSeasons = urlopen("http://ift.tt/2aJhkU3").Split('\n')[6];
string hash = getHash (availableSeasons + secretKey);

Теперь мы можем получить список сезонов: 1_000022,2_000077,3_000100,4_000099… Пары из номера и сида, разделенные запятыми.


string baseUrl = "http://ift.tt/2aJgtmg";
string url = string.Format ("seasons.php?Seasons={0}&hash={1}", availableSeasons, hash);
string data = Utils.urlopen (baseUrl + url);

Похожим образом получаем звезды в выбранном сезоне:


string hash = Utils.getHash (seed + secretKey);
string url = string.Format ("full_star.php?Seed={0}&hash={1}", seed, hash);
string data = Utils.urlopen(baseUrl + url);
foreach (string pair in data.Split(',')) {
    string name = pair.Substring(16, 6).Trim();
    string pos = pair.Substring(22);
    float x = Convert.ToSingle(pos.Substring(0, 3));
    float y = Convert.ToSingle(pos.Substring(3, 3));
    float z = Convert.ToSingle(pos.Substring(6));

    GameObject star = Instantiate(starPrefab) as GameObject;
    star.GetComponent<Star>().title = name;
    star.transform.position = new Vector3(x, y, z);
    stars.Add(star);
}

Это пары из координат и название звезды — 000022349205629_LIAMD 349205629,000022490453661_PAX4 490453661,000022570586427_RHUMB 570586427...


Пожалуй, это всё… или нет? За кулисами остался алгоритм добавления звезд. Это я оставлю истинным ценителям цифрового творчества. Не хулиганьте.


P.S.: Прохождение актуально только для онлайн режима. Навигатор можно скачать здесь, исходники там же.


P.P.S.: Описанные события произошли в марте 2014 года. Больше двух лет пост лежал в черновиках, потому что не было технической части в рассказе. Теперь это исправлено.

Комментарии (0)

    Let's block ads! (Why?)

    Комментариев нет:

    Отправить комментарий