MAATRIX GAMES / Блог / Terraria: краш плагина на TShock-сервере

Terraria: краш плагина на TShock-сервере

MAATRIX GAMES

Сервер на TShock стоял ровно, ты поставил новый плагин под сезонное событие или апдейт баланса — и через пару минут (а то и сразу при старте) процесс падает, в консоли мелькает исключение на незнакомом английском, а игроки снова стучатся в дискорд с «сервер офлайн». Знакомая ситуация — TShock живёт поверх Terraria через OTAPI-хуки, и любой плагин, который лезет не туда или написан под старую версию API, способен уронить весь процесс, а не только свою функциональность. Разберём рабочую методику: что искать в логах, как вычислить виновника среди установленных плагинов и почему чаще всего дело именно в версии TShock, под которую плагин собирался.

Сначала пойми: краш при старте или краш во время игры

Это разные сценарии, и метод поиска для них отличается.

Краш при загрузке сервера — самый частый случай с плагинами. TShock построчно выводит в консоль список загружаемых сборок из ServerPlugins/ сразу после запуска: Loading plugin ИмяПлагина v1.2.3 by Автор. Если сразу после одной из таких строк идёт System.MissingMethodException, System.TypeLoadException или просто обрыв процесса без финальной ошибки — виновник почти наверняка тот самый последний упомянутый плагин. Это классика несовместимости версий: плагин пытается вызвать метод TShock API, которого больше нет или у которого изменилась сигнатура.

Краш во время игры — сервер стартует и работает нормально, но падает при конкретном действии: взрыв, спавн босса, вызов команды плагина, срабатывание таймера. Здесь виновата логика самого плагина (необработанное исключение в обработчике события), а не сам факт загрузки. Стектрейс в этом случае обычно есть и явно указывает на namespace плагина — с ним разбираться проще, чем с молчаливым падением при старте.

Если по консоли/логам вообще непонятно, где искать — переходи сразу к отключению плагинов по одному (раздел ниже), это работает в обоих случаях.

Логи: что смотреть в tshock/logs и в ServerPlugins

TShock хранит два независимых источника информации, и оба стоит проверять при каждом падении.

Файлы логов лежат в папке tshock/logs/ рядом с исполняемым файлом сервера, по одному файлу на день: Log-2026-08-30.txt. В отличие от консоли, которая исчезает вместе с закрывшимся окном/сессией, лог остаётся на диске и после краша — открывай его сразу после падения:

tail -n 150 tshock/logs/Log-$(date +%F).txt

Ищи в конце файла блок с Unhandled Exception или Stack trace: — первая строка после заголовка исключения обычно называет класс и метод, где всё сломалось. Если сервер запущен через systemd, дополнительно проверь код завершения:

journalctl -u terraria --since "30 minutes ago"

Main process exited, code=killed, status=11/SEGV указывает на падение в нативной части (реже у чистых C#-плагинов, но бывает при использовании нативных биндингов), а Exited (0) без ошибок в логе — на исключение, которое сам процесс поймал и завершился штатно, тогда всё внимание на текстовый лог.

Папка ServerPlugins/ сама по себе не хранит логов, но именно порядок файлов в ней определяет порядок загрузки при старте — полезно, когда нужно понять, какой плагин загружался прямо перед обрывом консоли. Список .dll-файлов там же пригодится на шаге бисекции: ls ServerPlugins/*.dll.

Поднять сервер Terraria за пару минут

Готовый образ MAATRIX GAMES: NVMe, AMD EPYC, DDoS-защита, панель управления. Локации UK, US, RU. Оплата картой РФ, СБП или криптой.

Создать сервер

Читаем список плагинов и стектрейс при старте

При каждом запуске TShock печатает в консоль (и дублирует в лог) полный список успешно загруженных плагинов с версиями:

Loading plugin EssentialsPlus v2.1.0 by SomeDev
Loading plugin CustomEconomy v1.4.2 by AnotherDev
Loading plugin RegionProtect v3.0.1 by ThirdDev

Если краш происходит при старте, сравни этот список до и после установки нового плагина — виновник почти всегда последний, что успел напечататься перед обрывом. Если исключение всё-таки долетело до лога, обычно оно выглядит так:

System.MissingMethodException: Method not found: 'Void TShockAPI.TSPlayer.SendErrorMessage(System.String)'
   at CustomEconomy.EconomyPlugin.OnPlayerCommand(CommandArgs args)
   at TShockAPI.Commands.HandleCommand(TSPlayer player, String text)

Класс из namespace плагина (CustomEconomy.EconomyPlugin в примере) прямо называет виновника. MissingMethodException и TypeLoadException — почти гарантированный признак того, что плагин собран под другую версию TShock API (подробнее в разделе про совместимость версий ниже). Если же исключение указывает на класс из TShockAPI или OTAPI без упоминания стороннего плагина, а сам краш начался ровно после установки нового .dll — подозревай конфликт двух плагинов, переопределяющих одни и те же хуки, а не баг в ядре.

Отключаем плагины по одному: метод бисекции

Когда стектрейса нет или он неинформативен, самый надёжный способ — временно убрать часть плагинов из ServerPlugins/ и проверить, воспроизводится ли краш.

TShock подхватывает всё, что лежит непосредственно в папке ServerPlugins/, поэтому отключение сводится к переносу файла за её пределы:

mkdir -p ServerPlugins_disabled
mv ServerPlugins/CustomEconomy.dll ServerPlugins_disabled/

Перезапускаешь сервер, воспроизводишь условия падения (или просто ждёшь, если краш был при старте) и смотришь результат. Если плагинов много и подозреваемый неочевиден — не перебирай их по одному последовательно, а дели пополам: вынеси половину .dll-файлов разом, проверь, повторился ли краш, и в зависимости от результата продолжай делить именно ту половину, где проблема осталась. На коллекции из 15-20 плагинов это находит виновника за 4-5 перезапусков вместо пятнадцати.

Отдельно ускоряет поиск фиксация условий краша до начала бисекции: происходит ли он сразу при старте, при заходе конкретного игрока, при использовании команды, через фиксированное время. Если краш привязан к команде или событию — можно не гонять полноценный боевой рестарт с игроками, а воспроизвести триггер вручную на тестовом инстансе с тем же набором плагинов и меньшим maxplayers.

Полезно держать под рукой рабочий список зависимостей плагинов друг от друга — если у сервера настроены группы прав через отдельный permissions-плагин (см. настройку групп и прав), проверяй в первую очередь именно связку «новый плагин + permissions-плагин»: конфликты вокруг проверки прав — частый источник падений на команде, а не на старте.

Частые причины: несовместимость версий TShock API

TShock не всегда строго держит обратную совместимость API между релизами — особенно после обновлений самого Terraria, когда меняется формат мира, сети или добавляются новые типы предметов/тайлов. Несколько типовых причин, на которые стоит смотреть в первую очередь:

  • Плагин собран под старую мажорную версию TShock. Если между версией плагина и версией сервера прошло больше года — велика вероятность, что автор компилировал .dll против устаревшей сборки TShockAPI.dll, и часть методов уже удалена или изменила сигнатуру. Проверить версию своего сервера просто: команда /version в игре или флаг -help при запуске покажут версию TShock, а её стоит сверить с тем, что заявлено на странице плагина.
  • Terraria обновилась быстрее TShock. TShock всегда догоняет официальные апдейты Terraria с задержкой в дни, иногда недели — если ты обновил сам Terraria-сервер раньше, чем вышла соответствующая сборка TShock, несовместимость возможна уже на уровне ядра, а не конкретного плагина. Стоит сначала проверить changelog TShock на GitHub, прежде чем разбирать плагины по одному.
  • Плагин зависит от другого плагина, которого нет или он другой версии. Некоторые пакеты (экономика, кастомные боссы, ивенты) требуют отдельно подключённую библиотеку-зависимость. Без неё падение может случиться не с внятной ошибкой отсутствия зависимости, а с тем же MissingMethodException — потому что вызов уходит не туда.
  • Два плагина переопределяют одни и те же хуки/команды без вызова оригинала. Например, два разных экономических плагина или два плагина защиты территории (см. защиту от гриферов), одновременно перехватывающие один ивент — результат непредсказуем и зависит от порядка загрузки, который сам по себе может смениться при простом обновлении одного из плагинов.
  • Плагин обращается к своей базе данных при недоступном подключении. Если экономика или статистика хранится в MySQL, а сервис базы не запущен или недоступен на старте — некоторые плагины падают вместо того, чтобы выдать вменяемую ошибку подключения (см. настройку MySQL для игровых плагинов).

Похожая логика диагностики применима и к другим играм с плагинной архитектурой — если параллельно администрируешь Minecraft-сервер, общий подход к поиску конфликта между плагином и модом разобран в отдельной статье.

Проверяем обновления плагина: Discord и GitHub автора

Прежде чем чинить плагин руками или писать патч самому, стоит проверить, не решена ли проблема уже автором.

  • Discord-сервер TShock (ссылка есть в шапке официального репозитория Pryaxis/TShock) — там же часто сидят и авторы популярных плагинов, в разделе поддержки плагинов можно быстро узнать, известна ли уже проблема с конкретной версией.
  • GitHub-страница плагина, если она есть — смотри вкладку Issues на совпадение по тексту ошибки (MissingMethodException, название метода из стектрейса) и вкладку Releases на дату последнего билда относительно даты выхода твоей версии TShock. Плагин, не обновлявшийся больше полугода при том, что TShock за это время выпустил несколько релизов под новые версии Terraria, — кандидат номер один на несовместимость.
  • Форум/страница на TShock Plugin Repository или tModLoader-подобных каталогах, если плагин публиковался там — иногда там есть комментарии других админов с той же ошибкой раньше тебя.
  • Если апстрим заброшен, а исходники плагина открыты — проверь форки на GitHub: у популярных заброшенных плагинов Terraria-сообщество нередко держит неофициально обновлённую версию под актуальный TShock API.

Если исходников нет и автор не отвечает, а плагин критичен для сервера — иногда быстрее подобрать функциональную замену среди активно поддерживаемых плагинов, чем ждать фикса или разбирать чужой скомпилированный .dll реверс-инжинирингом.

Поднять сервер Terraria за пару минут

Готовый образ MAATRIX GAMES: NVMe, AMD EPYC, DDoS-защита, панель управления. Локации UK, US, RU. Оплата картой РФ, СБП или криптой.

Создать сервер

Частые вопросы

Сервер падает через несколько часов игры, а не сразу — с чего начать?

Это больше похоже на исключение в обработчике конкретного события (таймер, спавн, команда), чем на несовместимость API при загрузке — такая ошибка убила бы сервер сразу при старте. Смотри лог за период перед крашем: если перед обрывом есть повторяющееся сообщение от одного и того же плагина (предупреждения, débug-вывод), начинай проверку с него.

Можно ли обновить только один плагин, не трогая остальные?

Да, и это стоит делать по одному даже при плановом обновлении набора плагинов — если обновить сразу все .dll в ServerPlugins/ и после рестарта что-то упадёт, вычислить виновника среди пачки одновременных изменений сложнее, чем при последовательном обновлении с проверкой после каждого шага.

TShock ругается на несовместимую версию плагина ещё при старте, но не крашится — это тоже проблема?

Да, стоит воспринимать всерьёз даже предупреждение без краша: часть плагинов при несовпадении версии API продолжают грузиться, но с частично нерабочей функциональностью, и падают позже при обращении к сломанному участку кода — то есть краш просто отложен, а не отменён.

Стоит ли держать резервную копию ServerPlugins/ перед каждым обновлением?

Обязательно — простой .zip папки перед изменениями занимает секунды, а откат при неудачном обновлении плагина сводится к возврату старого набора .dll и рестарту, вместо повторной бисекции с нуля.