Сшей красное с красным желтое с желтым белое с белым наверняка будет хорошо

Обновлено: 11.04.2024

Facebook Если у вас не работает этот способ авторизации, сконвертируйте свой аккаунт по ссылке ВКонтакте Google RAMBLER&Co ID

Авторизуясь в LiveJournal с помощью стороннего сервиса вы принимаете условия Пользовательского соглашения LiveJournal

Ведьмак. Оксенфуртский студент-медик в процессе операции на колене.

Кого-то оперирую.
— Поздравляю дам и себя с удачной резекцией тонкого и толстого кишечника, спленектомией и сшивкой печени. Обращаю внимание на время, понадобившееся нам, чтобы ликвидировать последствия того, что за доли секунды было сотворено нашему пациенту во время боя… Советую это воспринять как материал для философских размышлений. А теперь мазель Шани зашьет нам пациента.
— Но я этого еще никогда не делала, господин Русти.
— Когда–то надобно начинать. Шейте красное с красным, желтое с желтым, белое с белым. Так наверняка будет хорошо…

Жизнь медика полна встреч с интересными людьми.
Система хирургии замечательная, наглядная до такой степени, что иногда блевать тянуло от рваных ран и кривых швов.
Университет и профессура - как всегда. Получала огромное удовольствие от наблюдения за ними. Получила докторскую степень, скрывала эльфское происхождение (беретом уши прикрыл - и вперед).
Кто б мог подумать, что доведется увидеть ту сцену, где захватчики города врываются в лекарскую палатку с намерением перерезать всех, как только что, снаружи - и как профессор-медикус Аластор, не отрываясь от операции, орёт на них и изгоняет вон.

Шани прожила после битвы семьдесят два года. Ушла из жизни знаменитой, всеми уважаемой — деканом кафедры медицины Оксенфуртского университета. Многие поколения будущих хирургов повторяли ее знаменитую шутку: «Сшей красное с красным, желтое с желтым, белое с белым. Наверняка будет хорошо».
Мало кто замечал, как, произнося эту истину, госпожа декан украдкой утирала слезы.
Мало кто.

16 августа 2019 г. 12:05

5 Сшей красное с красным, желтое с желтым, белое с белым. Наверняка будет хорошо.

Первую треть книги я думала, что поставлю четвёрку. Вторая треть стала дилеммой между четвёркой и пятёркой, поэтому я планировала поставить четыре с половиной. А потом случилась кульминация, развязка и конец. И вот мы имеем пятёрку)

И, кстати, это конец.
Да, здесь заканчивается история Геральта, Цири и Йеннифер. В этой части читателя помотает эмоционально. В конце я вообще сидела с открытым ртом и чуть не плакала. Этот цикл определённо обзавёлся ещё одним фанатом.

Мне очень нравится стиль пана Сапковского. То как он описывает события от лица разных людей, как он переплетает прошлое с настоящим и будущим, тем самым показывая практически всю жизнь (ну, не всю, скорее ключевые моменты) персонажа за раз. И всё гармонично - совершенно не возникает диссонанса.

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

Сложно описать происходящее в этой книге, не проспойлерив ничего, потому что она насыщена яркими моментами. Так что поверьте мне на слово - это очень круто!

– Это дитя ни в чем не виновно.
– Я сказал – безопасность государства. Безопасность государства не имеет ничего общего со справедливостью.

Статья является продолжением Реверс черного тессеракта. , без прочтения которой, единственный вопрос, на который именно тут дается ответ - "почему на КДПВ этого цикла статей везде картинки авторства Евгения Тихоновича Мигунова?".
Отвечаю. Потому, что по странному совпадению, всеми книгами, которые он иллюстрировал, в детстве я зачитывался. Как художник, на мой взгляд, он великолепен, и выбранные цитаты его творчества, на мой взгляд, очень хорошо ложатся на темы конкретных статей. Единственное "но", его подходящие иллюстрации книг не всегда соответствуют строгому альбомному видению КДПВ Хабра. Посему, необрезанный оригинал я всё же приведу и под катом.

Блок типа 0x0D

В первой части файл carindb нарезали на части, следующий шаг - выбрать какой-то из типов блоков и посмотреть его попристальнее.


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

А потом - наверняка будет хорошо (с).

Напомню карту блоков из прошлой статьи, надо чем-то руководствоваться при выборе препарируемого типа.

Например, возьму тип 0x0D - и от начала недалёк (смещение 0x3000), и всего три по количеству - не сильно много, но есть рядом разные представители того же типа для проверки гипотез разметки.

Поехали. В темплейте прыгаю на адрес 0x3000, и объявляю переменную block_0x0D типа структуры BT_0x0D, объявленной выше.


PTR и LIST

После указанного стрелочкой DWORD, заметьте, каждые 3 DWORD начинается явное повторение сходных значений. На картинке выше синим выделил второе из повторений, перед ним и после - явно что-то очень похожее.

Добавляю в структуру BT_0x0D переменную UINT unknown с зеленым фоном, и после неё массив из 2042 структур BT_0x0D__triple, которая состоит из 3-х UINT разных цветов - удобно на глаз анализировать соответствие соседей. Количество 2024 подобрал, визуально контролируя окончание блока. (Во вкладке Variables раскрываю struct BT_0x0D block_0x0D, раскрываю дочернюю struct BL_HEAD head, кликаю на строку uchar here_last_byte - и фокус в окне hex перемещается на самый конец данного блока. Меняю число элементов массива, нажимаю F5, применить темплейт, если перебор - закрашиваются hex после конца, уменьшить число, и пока не закрасятся значащие байты.)

Структуре BT_0x0D добавляю локальную переменную size - расчетный размер блока в байтах.


Значение 2042 в шестнадцатеричной форме выглядит, как 0x7FA. А следующий сразу за head UINT unknown с зеленым фоном = 0x0c07fa.

Причем, и массив array[0x7FA] начинается со смещения 0x0c от начала блока. Пара значений: указатель на массив и количество элементов массива за указателем явно неспроста рядом.

Новый тип данных в "inc_common.bt" PTR - указатель на данные внутри блока. Структура ищет у родительской переменную с размером структуры exists(parentof(this).size) , и если её значение больше size, цвет фона - красный и запись в лог о несоответствии значения возможному. Хоть какая-то проверка.

Объявляет ushort ptr - смещение относительно начала блока.
Если ptr ненулевой, и, если у родителя есть переменная с именем offset, по рассчитанному абсолютному адресу оставляет метку - байтик here на голубеньком фоне, кликая на него в Variables - в окне hex отобразится это место. Read_PTR - отображается во вкладке Variables в колонке Values.

Новый тип данных в "inc_common.bt" LIST - список указатель на начало массива и количество элементов. Локальные offset, size транзитом идут для следующей PTR ptr, но потом offset этой структуры

И вот теперь в структуре BT_0x0D переменную UINT unknown с зеленым фоном заменяю на LIST p_data, правя количество элементов BT_0x0D__triple main_array[cnt] на p_data.cnt, массиву добавлю атрибут optimize=false - иначе 010Editor схитрит, всем расчетным элементам присваивая значения первого. И в структуре парсинга блока BT_0x0D последним добавлю яркий byte after_parsed_block_info - и визуально в окне hex видно, где окончился парсинг, и прыгнуть на неё выбором в Variables можно.

В самой структуре BT_0x0D__triple тоже изменения, при сохраненном размере:

Первый UINT unknown1 в структуре - BL_ADDR, как адреса блоков они все валидны.

Сразу за адресом, похоже, char ch, его значения лежат в промежутке, что и ASCII кода символов от '0' до 'z'.

За ним еще один char seems_always_eq_1 - вставлю проверку, а правда ли всегда seems_always_eq_1 == 1

UINT unknown3 остается по-прежнему

Завершает внутренности структуры 16битный aligment: явно данные выравнивают по границе 32бита.

Как видите, в консоли, во вкладке Output, - множество намеков, что seems_always_eq_1 - вовсе не всегда равна 1, бывает и 0.
Поправляю условие проверки if((seems_always_eq_1 != 1)&&(seems_always_eq_1 != 0) ) , после чего парсинг проходит без замечаний в логе. Значение always_zero, похоже, действительно предназначена для выравнивания данных по границе 32 бита. Добавляю проверку в BT_0x0D__triple: BL_ADDR bl_type_0c действительно ссылается всегда на тип 0x0C?


Нет, не всегда, говорит консоль. Чтобы визуально выделить те элементы, где тип блока bl_type_0c не 0xC, а 0xD , выделяю ярким нераскрашенный seems_always_eq_1.

Результат неожиданнен: в блоке типа 0xD в BT_0x0D__triple seems_always_eq_1 всегда ==1, если bl_type_0c ведёт "наружу", является типом 0xC, и всегда ==0, если bl_type_0c.type == 0xD, то есть на тот же тип. Является bool - ссылка "наружу", или "внутрь", самое имя ей is_ptr_out.

Но, если часть ссылок ведёт внутрь, то на какие именно значения они указывают? Переписываю функцию, для отображения в Variables значения BT_0x0D__triple. Если is_ptr_out ==0, то в цикле "собираются" far_away.cnt символов ch из BT_0x0D__triple, начиная с адреса far_away.offset. Дерево?


Блоки типа 0x0B, 0x0D, 0x0F и 0x11

Все данные блока типа 0x0D размечены, но когда в руки попадает ухватистый молоток, то трудно остановиться и не продолжать этим молотком забивать всё, что попадает под руку и хоть чуть-чуть похоже на гвоздь.

С минимальными изменениями, ранее сохраненный темплейт "util_vdo_stat.bt" выводит все варианты типов блоков в виде вызовов функции block().

Копипащу в основной темплейт, применяю, получаю в Variables представителей всех типов блоков. Визуально пытаюсь найти сходство сырых данных разных типов с данными в блоке 0x0D, похожие пытаюсь распарсить структурой BT_0x0D.

Перед тем, как понять рекурсию, надо понять рекурсию

Из блока типа 0xB "внешние" "ссылки" ведут в 0xA. Из блока 0xD ссылки ведут в 0xC. Из 0x0F в 0x0E. Из 0x11 в 0x10. Везде получается ссылки ведут или в тот же тип блока, из которого вызываются, (по сути ссылаясь на массивы того же типа данных BT_0x0D__triple), или в тип блока на единицу меньший.

Добавляю перед описанием структуры BT_0x0D__triple её forward declaration для рекурсивного описания.

Переименовываю BL_ADDR bl_type_0c -> bl_more_info

Добавляю local en_BL_TYPE en_curr_bl_type = head.type; текущий блок

Проверка раскараски фона is_ptr_out меняется if(bl_more_info.type == (en_curr_bl_type-1) )1)

Если !is_ptr_out, т.е. ссылка идет "внутрь" - создаётся массив дочерних структур BT_0x0D__triple (рекурсия, у дочерних так же создадутся дочерние и т.д. и т.п.)

Устройства ввода-вывода автонавигации.

А ведь я видел нечто похожее в автонавигаторе.

Для ввода адреса пункта назначения необходимо последовательно ввести в четыре поля - страна, город, улица, дом (на экране они называются Country, City, Road, Number) строковые значения. Буквы для ввода последовательно выбираются на всплывающей при редактировании поля экранной клавиатуре энкодером, причем на этой QWERTY-клавиатуре доступны к выбору не все буквы, а лишь некоторые.

Перемещение фокуса по буквам клавиатуры - вращением энкодера, выбор буквы - нажатием того же энкодера.

Вначале доступно к заполнению только поле страна, на остальные перейти нельзя. Для официального диска Восточной Европы при заполнении страны на клавиатуре активны и доступны буквы B, C, E, L, M, P, R, S, остальные неактивны. При выборе L (энкодер с нажатием) появляется меню выбора, LATVIJA или LIETUVA. А если выбрать P - поле страна сразу заполняется значением POLAND и фокус переходит на поле город, заполнение которого происходит аналогичным способом: последовательным вводом букв из предложенных на клавиатуре. Набрать можно только те города, которые расположены в Польше. После курсор уходит на поле улица, которая заполняется так же, невозможно для Poland, Olsztyn набрать название улицы, которой в Ольштыне нет.
Нагляднее описано в мануале на VDO VDO DAYTON PN 6000 на 18 странице, модель, картинка другие, но логика и данные те самые.

Предварительная гипотеза - а не функционал ли ввода адреса и обеспечивают рассматриваемые типы?

По количеству блоков, по последовательности расположения в carindb можно тогда предположить, что 0xB - выбор букв для страны, тогда 0xA - страна. Тогда следующая пара 0xD и 0xC - город, 0xF-0xE - улица, 0x11-0x10 - дом.

Итоги

Результаты статьи суммарно:

Структура PTR, псевдо-интеллектуальный указатель внутри блока

Структура LIST - указатель на массив, с количеством элементов

Рекурсивная структура с неэстетичным временным названием BT_0x0D__triple, описывающая единицу информации в блоках 0x0B, 0x0D, 0x0F, 0x11

Найдены блоки, которые описываются одной и той же структурой.

Структура BT_0x0B_0x0D_0x0F_0x11 полностью размечает всё содержимое блоков с типами 0x0B, 0x0D, 0x0F, 0x11

Рекурсивные структуры данных 010Editor

Гипотеза о ~существовании обитаемых миров~ функциональном назначении распарсенных данных

Данные не только BigEndian, но еще выравниваются по границе 32 бита.

Темплейт работает и на официальных картах carindb_ee carindb_bnl (с учетом, что там блоки 0x0B, 0x0D, 0x0F, 0x11 находятся по другим адресам)

Чтобы уйти от привязки к "волшебным цифрам" отступа при вызове функции block(), напишу в инклюд "inc_block.bt" функцию FindBlockByType(en_BL_TYPE type), возвращающую адрес типа BL_ADDR первого попавшегося блока с подходящим типом. Нельзя возвращать смещение, потому что при ненахождении функция возвращает 0.

В основном темплейте теперь для объявления блока необходимого типа на любых исходных carindb достаточно такой конструкции: block(FindBlockByType(0x0B)); // 0B 1 BT_0x0B_0x0D_0x0F_0x11

Проверено на грамотность

А теперь мазель Шани зашьет нам пациента.
— Но я этого еще никогда не делала, господин Русти.
— Когда–то надобно начинать. Шейте красное с красным, желтое с желтым, белое с белым. Так наверняка будет хорошо…

  • Главы:
  • Для любителей клавиатуры:
  • «Ctrl+стрелка влево» - предыдущая глава
  • «Ctrl+стрелка вправо» - следующая глава

— Нильфгаард! — снова крикнул солдат высоким, дрожащим голосом. — Господа фершела! Не слышите, что ль, что говорю-то? Нильфгаард прорвал королевскую линию, идет и крошит! Бегииитя!

Русти взял у меня иглу, сделал первый стежок. Оперируемый уже долгое время не двигался. Но сердце билось. Это было видно.

— Не хочу умирать! — заорал кто-то из находившихся в сознании раненых. Солдат выругался, прыгнул к выходу, что-то крикнул, рухнул назад и, разбрызгивая кровь, свалился на глинобитный пол. Иоля, стоявшая на коленях у носилок, вскочила на ноги, попятилась.

Неожиданно стало тихо.

«Скверно, — подумал Русти, увидев, кто входит в палатку. — Эльфы. Серебряная Молния. Бригада "Врихедд". Прославленная бригада «Врихедд».

Вот тогда-то всё для меня и закончилось. Я целительница, мать вашу, я не воин, но если у меня не получается их вылечить — я хотя бы буду их защищать.

Иоля и Шани ничего не успели сделать. Простая волна магии смела первых трех эльфов, но за ними шли другие. Русти что-то орал, не переставая шить — а я тихо опускалась на колени, разглядывая стрелу с черным оперением, вошедшую на два пальца левее середины моей груди.

— Мадам Помфри! Мадам! Поппи, черт возьми! — я очнулась под крики пожилой женщины, которая не справлялась с потоком раненых. Кто такая Поппи и почему я, Марти, в её теле — разбираться было некогда. Из одной битвы я попала в другую, нахожусь в лазарете и, видимо, всё же могу лечить. — Поппи, оборотни! Их слишком много!

Я обвела взглядом зал — раненые были везде, кто-то стонал, кто-то сидя раскачивался из стороны в сторону. Остановив взгляд на девушке немногим младше Шани, зажимавшей руками распоротое бедро — она уже бледнеет, и явно скоро освободит очередь.

— Её на стол, анестезию! Подготовить материалы, зажимы, тампоны!

Я использую магию и шью — яростно, быстро, приговаривая про себя любимую присказку Русти — “сшей белое с белым, красное с красным, желтое с желтым”. Вокруг гибнут люди от ран и от заклятий, но я не замечаю этого.

Когда в моей голове раздается жуткий противный голос и объявляет час для какого-то Гарри Поттера — я выдыхаю и отдаю иглу какой-то девчонке — она утверждает, что её родители — маггловские врачи и, хоть я не понимаю, кто такие магглы, слово врач мне говорит о многом. Девчонка шьет сноровисто и аккуратно.

У нас есть час на то, чтобы проверить раненых в этом зале и собрать остальных.

Час проходит и, когда все высыпают на улицу — я остаюсь в зале. Снова проверяю, закрываю простынями умерших и магией пытаюсь помочь ещё живым.

Когда очкастый парень начинает сражаться с чудищем прямо в зале — единственное, о чем я молюсь — это о раненых. Мне плевать, кто из них победит, но, когда чудище рассыпается в прах и меня начинают обнимать и радостно кричать все, кому не лень — я чувствую облегчение.

Прохожу в угол, где трудится девчонка — я так и не узнала её имя — и вижу там ещё одну. У неё дрожат губы:

— Мадам Помфри, чем я могу помочь?

Я протягиваю ей иглу с ниткой и тампоны:

— Сшей белое с белым, красное с красным и желтое с желтым. Так наверняка будет хорошо.

Ведьмак

Ведьмак

Ведьмак запись закреплена

"Сшей красное с красным, желтое с желтым, белое с белым. Наверняка будет хорошо"

Игорь Ставицкий


Оксана Хохлич

😌

Шани

Данила Мохнаткин


Данила Мохнаткин

Алексей Дроздов

Игорь Миркин


Игорь Миркин ответил Даниле

Андрей Вокуев


Андрей Вокуев ответил Алексею

Алексей Дроздов

Кирилл Чернышев

Анастасия Брянцева


Анастасия Брянцева ответила Кириллу

Кирилл Чернышев

Данил Клюев

Verena List


Verena List ответила Данилу

Василий Липин

Данил Клюев

Verena List


Verena List ответила Данилу

Данила Мохнаткин


Данила Мохнаткин ответил Данилу

Данил, в 3 ведьмаке в глоссарии (где о персонажах написано) о Шани написано, что она произносила эти самые слова, со слезами на глазах.

Крабсбургер Drunkard

Данил, произнося его слова, от воспоминаний прошедшего и ушедших близких людей, ей было больно и наворачивались слезы.

Даааа
Побоище было жестокое
А Русти Рыжик и Шани лечили и своих, и чужих
А когда принесли труп Койона я чуть не остолбенел

Читайте также: