Есть набор библиотек (движок свеженькой игры Might & Magic X, написанный на C#).
Хочется внести изменения в отдельнные классы, методы этих библиотек (модостроительство).
Вопрос — как это лучше всего реализовать? Сейчас набирает популярность dependency injection (кем бы они ни были). Может ли эта штука помочь?
Интересует простой (ака надежный) способ, не затрагивающий вообще или минимально затрагивающий оригинальные dll.
Заранее спасибо всем за хорошие советы!
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Хм... тоесть выглядеть это будет примерно так:
Создаем новую библиотеку, добавляем в референсы старую.
Создаем новую версию интересующего типа. Измененные методы \ свойства помечаем аттрибутом.
При помощи Mono.Cecil загружаем обе библиотеки.
В новой перебираем типы.
Находим в них помеченные аттрибутом элементы.
Ищем их аналоги в оригинальной библиотеке. Заменяем на новую реализацию. Сохраняем измененную сборку.
Я верно понял концепцию?
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Re[3]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
Здравствуйте, Albeoris, Вы писали:
A>Хм... тоесть выглядеть это будет примерно так: A>Создаем новую библиотеку, добавляем в референсы старую. A>Создаем новую версию интересующего типа. Измененные методы \ свойства помечаем аттрибутом.
A>При помощи Mono.Cecil загружаем обе библиотеки. A>В новой перебираем типы. A>Находим в них помеченные аттрибутом элементы. A>Ищем их аналоги в оригинальной библиотеке. Заменяем на новую реализацию. Сохраняем измененную сборку.
A>Я верно понял концепцию?
Можно и так, но я бы поступил по-другому.
Зачем помечать атрибутом изменённые методы / свойства, можно просто положить класс в одинаковый namespace и вставлять в оригинальную библиотеку всё содержимое.
Если не собираетесь копировать декомпилированный класс целиком для модификации, то появляется проблема что делать с полями и свойствами классов.
Проверьте, не нарушаете ли вы условия лицензирования, а то могут быть потом проблемы.
Re[4]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
Хм... а нет возможности просто подключить оригинальную библиотеку в референсы новой и, отлавливая MissingType, MissingMethod exception, перенаправлять вызовы в оригинальную?..
MN>Можно и так, но я бы поступил по-другому.
MN>Зачем помечать атрибутом изменённые методы / свойства, можно просто положить класс в одинаковый namespace и вставлять в оригинальную библиотеку всё содержимое. MN>Если не собираетесь копировать декомпилированный класс целиком для модификации, то появляется проблема что делать с полями и свойствами классов. MN>Проверьте, не нарушаете ли вы условия лицензирования, а то могут быть потом проблемы.
Тут имеем палку о двух концах. Когда MS отобрали возможность множественного наследования и приведения дочернего типа к базовому, их решение было обосновано.
Но в нашей ситуации, чем меньше вносимые изменения — тем лучше. Потому что внутри существуют огромные порятнки типов. Так у одного модмейкера будет возможность изменить один метод, например, отвечающий за передвижение между клетками, а у другого — изменить логику определения видимости объектов. Впрочем, понятно, что конфликтов в этом случае не оберёшься... Нужно как-то договариваться с разработчиками о выдаче исходников для полноценной интеграции плагинов в те области, которые понадобятся разработчикам плагинов и самостоятельно клепать API.
Впрочем, не для комерческого же использования. А раз они сами нам, на блюдечке, исходники игры выдали (давно такого никто не делал), то можно сделать лицо кирпичом и с фанатичным блеском в глазах твердить о том, что это и есть обещанная возможность модификации (как я искренне и считаю, да-да-да).
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Re: Подмена отдельного класса \ методав чужой не обфусцированной сборке
Здравствуйте, Albeoris, Вы писали:
A>Всем доброго времени суток!
A>Есть набор библиотек (движок свеженькой игры Might & Magic X, написанный на C#). A>Хочется внести изменения в отдельнные классы, методы этих библиотек (модостроительство).
A>Интересует простой (ака надежный) способ, не затрагивающий вообще или минимально затрагивающий оригинальные dll.
A>Заранее спасибо всем за хорошие советы!
Спасибо за совет! Но пока кажется не лучшим из вариантов. Пример завести так и не удалось (не хучится) (причем, проблема там, кажется, не с инъекцией, а с реализацией com-объекта :D). Ну да не суть.
Не суть. Если что — можно допилить. Но, как и всё, что связано с COM, очень громоздко, неудобно, и с массой подводных камней. Хочется чего-нибудь более дружелюбного. Но на заметку взял. В массы бы я его не пустил, а для одиночного написания API можно попробовать.
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Re[3]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
Здравствуйте, Albeoris, Вы писали:
G>>Можно попробовать через CLR Profiler API, при помощи него, кроме всего прочего, можно внедрять свой код. Пример использования: CLR dynamic hook injection
A>Спасибо за совет! Но пока кажется не лучшим из вариантов. Пример завести так и не удалось (не хучится) (причем, проблема там, кажется, не с инъекцией, а с реализацией com-объекта :D). Ну да не суть.
О вспомнил! На Хабре была статья: Инъекция кода в .NET CLR: изменение IL-кода во время выполнения программы
Удачи в исследованиях.
Re[4]: Подмена отдельного класса \ методав чужой не обфусцированной сборке
Хм... если есть возможность отловить вызовы несуществующих типов и методов — вариант неплохой (хотя, после прочтения, создалось ощущение, что всё это держится на одном, не очень честном слове). А вот если нет — совершенно ничем нам не поможет, потому что работает со сборками, загруженными в текущий AppDomain. Динамически генерировать IL-код чужой сборки не имеющей никакого отношения к нашему процессу, нет.
"Хаос всегда побеждает порядок, поскольку лучше организован." (с) Терри Пратчетт
Re: Подмена отдельного класса \ методав чужой не обфусцированной сборке
Здравствуйте, Albeoris, Вы писали:
A>Вопрос — как это лучше всего реализовать?
Декомпилируешь в пакетном режиме в IL, заменяешь исходники, потом компилируешь обратно в сборку. Если у сборок есть strong name, придется заменять подпись на свою и править все референсы.
A> Сейчас набирает популярность dependency injection (кем бы они ни были). Может ли эта штука помочь?
Нет.
... << RSDN@Home 1.2.0 alpha 5 rev. 100 on Windows 8 6.2.9200.0>>