Ваш разделённый туннель исключает лаунчер, а не игру
Лаунчер запускает для матча другой исполняемый файл, и у этого процесса свои сокеты. Найдите настоящий процесс, сопоставьте правильный идентификатор, затем проверьте.
Вы добавляете лаунчер в список исключений, загрузка ускоряется, а матч всё равно оказывается на удалённом сервере. Ничего не сломано. Лаунчер и игра — два процесса с двумя наборами сокетов, и исключение одного ничего не говорит о другом. Загрузка ускорилась, потому что это был трафик лаунчера; матч — чужое соединение, открытое исполняемым файлом, которого ваше правило никогда не видело.
Один установщик, много процессов
Современное игровое ПО — небольшое созвездие. Есть клиент, который выполняет вход, обновление, которое загружает контент, лаунчер, который запускает игру, и исполняемый файл игры, который сам может создать второй процесс для античита или для слоя подбора матчей. Каждый из них может держать свои соединения со своими адресатами.
Правило исключения обычно называет один из них. Какой именно — полностью зависит от идентификатора, поддерживаемого VPN-клиентом, и это та часть, которую пользователи редко проверяют. Одни клиенты сопоставляют путь к исполняемому файлу, другие — идентификатор пакета или bundle, третьи — имя процесса, которое могут разделять два несвязанных бинарника. Прочитайте правило до списка процессов, потому что правило ограничивает даже то, что вы можете выразить.
Поэтому симптом не «разделённый туннель сломан». Он — «правило охватывает процесс, который не является тем, что несёт важный для меня трафик», а это гораздо более узкое и гораздо легче исправимое утверждение. Как только вы скажете это так, следующий шаг перестаёт быть догадкой.
Найдите процесс, которому принадлежит соединение матча
Запустите игру, войдите в матч и посмотрите, кому принадлежат сокеты, а не что на экране. В Windows список процессов плюс запрос сокетов для каждого процесса отвечают на это двумя командами:
Get-Process | Where-Object { $_.ProcessName -match 'launcher|game|client' } | Select-Object Id,ProcessName,Path
Get-NetTCPConnection -State Established | Select-Object OwningProcess,RemoteAddress,RemotePort | Sort-Object OwningProcess
Вторая команда выводит идентификатор процесса, а не имя, поэтому объедините два вывода по идентификатору. Строка, которую вы ищете, — та, чей удалённый адрес принадлежит игровому сервису, а владеющий ею процесс — исполняемый файл, который должно назвать ваше правило.
В Linux тот же вопрос требует одной команды на каждый тип сокета, и стоит проверить оба, потому что соединение матча может быть UDP, пока всё остальное — TCP:
ss -tunp state established | grep -i game
ss -tunp | awk 'NR==1 || /udp/'
Если игра работает в контейнере или слое совместимости, найденный процесс может быть shim, а не установленный вами бинарник. В этом случае важен идентификатор, который видит клиент, и это может быть путь shim, и никакое редактирование исходного файла на это не повлияет.
Сопоставьте идентификатор, который поддерживает ваш клиент
Прочитайте документацию клиента о правиле исключения, прежде чем что-то добавлять. Три обычные модели ведут себя по-разному, и одна из них — ловушка.
| Identifier | How it behaves | Failure mode |
|---|---|---|
| Executable path | Matches exactly the file at that path | Breaks when an update moves the binary |
| Process name | Matches any binary with that name | Too broad; catches unrelated software |
| Package or bundle id | Matches a signed application group | May include services you did not intend |
Правила пути самые точные и самые хрупкие. Обновление лаунчера, которое перемещает исполняемый файл, оставляет правило указывающим на файл, который больше не запускается, и симптом возвращается без явных изменений. Правила пакета это переживают, и они же могут тихо охватывать вспомогательные процессы, о которых вы никогда не думали, что удобно или тревожно в зависимости от помощника.
Что бы ни поддерживал клиент, не добавляйте записи для каждого найденного исполняемого файла. Список, собранный методом проб и ошибок до тех пор, пока одна сессия не заработала, невозможно проверить, и он будет тихо накапливать исключения для несвязанного ПО. Назовите найденный процесс и запишите, для чего он был.
Проверяйте на матче, а не на загрузке
Скорость загрузки лаунчера — худшая возможная проверка, потому что она задействует именно тот процесс, который уже был исключён. Используйте то, что не работало, и проверяйте маршрут, а не собственный дисплей производительности игры:
ip route get 203.0.113.55
Get-NetTCPConnection -State Established | Where-Object RemotePort -eq 27015
Первой команде нужен адрес, в который разрешился сервер матча, и его может дать журнал соединений игры или ваш клиент. Если маршрут называет физический интерфейс, правило работает. Вторая показывает, существует ли сессия вообще, что отделяет «исключено, но сервер недоступен» от «не исключено».
Держите регион и сеть доступа неизменными во время проверки. Матч, который каждый раз попадает в другой дата-центр, даёт разные адреса, и вы в итоге будете гоняться за движущейся целью вместо проверки правила. Два запуска с одним адресом ценнее десяти с разными.
Перепроверьте после следующего обновления
Любое правило на основе пути имеет срок годности, измеряемый циклами исправлений. Когда через месяц игра перестаёт соблюдать исключение, первое, что нужно проверить, — переместился ли исполняемый файл, а второе — не появился ли рядом новый вспомогательный процесс.
Модель исключения приложений, документированная одним клиентом, — разумный ориентир для описания таких правил, хотя детали различаются между продуктами. Прочитайте свою, запишите использованный идентификатор и отметьте дату. Именно эта запись превращает загадку в пятиминутное исправление в следующий раз, когда лаунчер выпустит обновление.
Если клиент просто не может выразить нужную границу, одобренная более широкая политика лучше кучи недокументированных исключений. Широкое и понятное побеждает узкое и ошибочное, особенно когда узкая версия — это то, что все считают действующим.