Форк клиента собирается из исходников, модзагрузчик встроен в игру
Проект начинается с двух вещей: клиент, который мы действительно собрали, и загрузчик, который является его частью, а не чем-то рядом. Форк - prepare-game.ps1 пересобирает клиент целиком: ванильный jar, SRG и MCP, SpecialSource, FernFlower, патчи, автофиксеры, javac. Идемпотентен. - Свой код игры лежит в src-overlay, потому что src пересоздаётся при каждой сборке и всё написанное вручную там погибает. - 116 патчей в patches/decompiler-fixes.txt. Каждый сверялся с оригинальным байткодом через javap: компиляция не ловит ошибки декомпиляции. - struct_diff.py сравнивает исходный байткод с нашей сборкой по классам, интерфейсам, суперклассам, методам и полям, и отдельно проверяет, что пропавшие классы действительно никому не нужны. Загрузчик - Собирается и тестируется без игры: build.ps1 не использует classpath вообще, поэтому SelfTest из 128 проверок проходит без запущенного форка. - Клиентский API не содержит ни одного игрового типа, реализацию даёт игра. - Политика: мод меняет то, что клиент показывает, но никогда то, что истинно в мире. Мир, предметы, игроки и сеть принадлежат серверу. - Capability приведены в соответствие с этой политикой: осталось шесть, и за каждым стоит реальная проверка. Прежние WORLD, PLAYER, NETWORK, TEXT, INPUT и COMMAND выдавались, но ничего не проверяли. - Команды модов имеют область CLIENT, SERVER или BOTH. Серверные не выполняются на клиенте никогда. - Свой jar загрузчика лежит в classpath игры и сборки форка. Инструменты - add_patch.py, чтобы каждое исправление переживало передекомпиляцию - find_self_comparisons.py, find_remove_index_bugs.py, find_callers.py - stage_run.py и fetch_missing.py для запуска клиента
This commit is contained in:
@@ -0,0 +1,32 @@
|
||||
package net.rustnotmc.api.client;
|
||||
|
||||
/**
|
||||
* The client the mod is running in.
|
||||
*
|
||||
* This is the whole surface a client mod gets, and it is deliberately small: it
|
||||
* describes what the client shows, what the keyboard and mouse are doing, and
|
||||
* where to add commands. There is no path from here to a block, an item, a
|
||||
* player or a packet, because the server owns those and a client mod is not
|
||||
* allowed to decide them.
|
||||
*
|
||||
* A mod that needs something genuinely outside this boundary is expected to say
|
||||
* so, and reach for the reflective escape hatch deliberately, with the operator's
|
||||
* consent, rather than finding a back door.
|
||||
*/
|
||||
public interface ClientServices {
|
||||
|
||||
/** The display state, never null. */
|
||||
Screen screen();
|
||||
|
||||
/** Keyboard and mouse state, never null. */
|
||||
Input input();
|
||||
|
||||
/** The mod command table, never null. */
|
||||
Commands commands();
|
||||
|
||||
/** Ticks since the client started, driven by the game loop. */
|
||||
long tick();
|
||||
|
||||
/** Frames drawn, which at a steady frame rate is a better clock than tick. */
|
||||
long frame();
|
||||
}
|
||||
Reference in New Issue
Block a user