하꼬 게임이 다 그렇듯이 정보가 원체 없어서 아마 뭘 해보고 싶어도 머가리 들이박다 포기하는 사람들 있을텐데
모딩에 관심 있는 사람들을 위해서 모드 작동원리 + 개발 방법에 대해서 간단히 정리하고자 함.
1. 뭘 알아야 하나
첫째로 DSP는 유니티 엔진으로 제작 되었고 유니티 엔진은 C# 기반으로 API를 제공하기 때문에 당연히 C#에 대한 지식이 필요함.
둘째로 1인 개발자 수준까진 아니더라도 어느정도는 유니티 엔진에 대한 이해가 필요하다.
엔진이 돌아가는 꼬라지를 잘 모르면 뭘 해야하는지 파악할 수가 없기 때문인데 그 이유는 바로 밑에 서술하겠음.
2. DSP 모드의 작동원리
DSP는 공식 모드 API가 없다. 개발사 차원에서 모딩이 지원되지 않는다는 뜻이다.
개발사에서 모딩을 공식적으로 지원하지 않으므로 당연히 기본적으로는 게임을 모딩할 수단이 없는데
원래 인간의 본성이라는게 시키지도 않은 일을 만들어서 하는 것 아니겠는가.
모드에 목이 말라비틀어진 망자들의 탐욕은 상상 이상이라서 DSP가 아니라 아예 유니티엔진 모드로더를 만들어놨다.
바로 Unity DoorStop이라는 프로젝트다.
Unity Doorstop은 유니티 엔진 초기화 과정 중간에 끼어들어서 임의의 C# 모듈을 게임 프로세스에 로드할 수 있게 해준다.
C# 같은 IL 기반 언어의 특성상 일단 내가 만든 C# 모듈이 올라가기만 하면 내부 코드를 패치하는건 무척 쉽기 때문에
대부분 유니티엔진 기반 게임의 모드로더들은 이런 애들을 이용해서 자기자신을 게임 프로세스에다 로드함.
유니티엔진의 공식 기능도 아니고 겜 실행파일을 건들지도 않는데 존나 어떻게 이런 개짓거리가 가능한건지
머가리에 물음표를 띄우는 사람도 많을텐데, 별거 없고 DLL 하이재킹 원리를 이용한다. 구체적으로는...
1. 유니티엔진이 시동 될 때 이런저런 자기가 쓸 dll들을 로드하려고 든다.
2. 그럼 당연히 그 dll 파일의 위치와 이름을 알아야 그놈을 읽어서 로드를 하던가 말던가 하겠지?
3. dll을 불러오는 API 함수를 호출할 때 파일이름만 써놓고 절대경로를 안박을 수 있음.
절대경로를 안알려주면 함수는 일단 실행파일과 같은 폴더에서 dll 파일을 찾아보고,
동일경로에도 없다면 다른 정해진 폴더들을 뒤져보게 되어 있다.
4. 유니티엔진이 불러오는 dll 중에 winhttp.dll이라는 놈이 있음. Unity Doorstop은 이 dll의 내부구성을 완벽히 모방해서
실행파일과 동일한 경로에 winhttp.dll로 위치하게 됨. 지금 모드 쓰는 애들도 겜 설치폴더 가보면 실행파일과 같은 폴더에
winhttp.dll이라는 파일이 뜬금없이 있을거임. 그게 Unity Doorstop이다.
5. 그럼 당연히 유니티엔진은 winhttp.dll을 로드할 때 진짜 dll이 아니라 위장한 Unity Doorstop을 로드하게 되어 잠입이 성공한다.
6. 근데 잠입만 하고 뒷처리를 안해주면 당연히 winhttp.dll을 쓰는 모든 기능이 마비되고 심하면 프로세스가 터진다.
그래서 Unity Doorstop 내부에서 진짜 winhttp.dll을 로드하고 실제 winhttp.dll의 함수들을 대리호출해줌으로써 빵꾸난걸 메꾼다.
결과적으로 유니티엔진은 아무것도 모르고 Unity Doorstop을 품은 채 정상실행이 된다!
Q. 근데 이거 굳이 알아야됨??
A. 이걸 알아야 너네가 모드에서 가능한 작업과 불가능한 작업을 구분할 수 있음. 원리 알아서 나쁠거 없다.
"아무튼 그래 이해했음 Unity Doorstop의 도움으로 임의의 C# 모듈을 로드할 수 있구나 그럼 얘 갖고 모드 로드 시키면 되겠네?"
그건 아님. 이새낀 말 그대로 임의의 C# 모듈을 로드 시켜줄 뿐이고 구체적인 모드 구현을 돕는 기능은 없다.
그럼 뭘 로드시키는가 하니, 같은 폴더에 있는 doorstop_config.ini 파일에 비밀이 숨어있다.
중간에 targetAssembly=BepInExcoreBepInEx.Preloader.dll 라는 문자열이 보일텐데 이거는 아마 모드질 해본 애들은 많이 봤을거임.
BepInEx(Bepis Injector Extensible)
Git : https://github.com/BepInEx/BepInEx
얘가 바로 우리가 그토록 찾아헤매던 모딩 프레임워크임. Unity Doorstop을 통해 얘가 로드 되면서 모드를 구동할 밑밥을 깔아놓고,
그제서야 우리가 알고 있는 그 모드 파일들의 실제 로드가 진행된다.
그럼 씨발 한패 할 때 깔으라던 r2modman 이건 필요도 없었네??? 그건 아니고 r2modman은 걍 모드관리툴 같은거임.
지금 위에 써놓은 저 세팅을 알아서 다 해주고 BepInEx 기반 모드들을 쉽게 찾게 해주는 다이소 같은 것이므로 쓰는게 좋음.
3. 그래서 개발 어케함?
위에서도 말했다시피 우리가 모드라고 알고 있는 것들은 실제로는 Unity Doorstop을 통해 작동하는 BepInEx 기반 모드들임.
그래서 아래의 BepInEx 링크 타고 가면 모드 작성법에 대한 구체적인 내용이 정리가 되어 있음.
https://docs.bepinex.dev/master/articles/dev_guide/plugin_tutorial/index.html
진짜 딱 저거대로만 하면 됨. 왜냐하면 모드로딩은 위에 저것들이 알아서 하고 모드 구현에 필요한 라이브러리도 BepInEx가 전부 로드를 해주므로
개좆같이 Harmony 링크하고 어쩌고 이럴 필요가 없기 때문임. 누구나 쉽게 시작할 수 있다.
존경함 귀한정보임 이건 - dc App
기초추