Half-Life и Adrenaline Gamer форум

Всё об игре в Халф-Лайф и АГ
Текущее время: 28 мар 2024, 16:28

Часовой пояс: UTC + 5 часов [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 12 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Перехват консоли HLDS на Windows
СообщениеДобавлено: 04 дек 2014, 01:58 
Не в сети
Аватара пользователя
Зарегистрирован:
21 мар 2012, 13:21
Последнее посещение:
27 дек 2023, 02:51
Сообщения: 165
Решил написать утилиту, которая позволит запустить консольный процесс с перехватом данных вывода (StdIn) и позволит отправлять команды в этот консольный процесс (StdOut). Что-то вроде аналога Screen под Linux, но только для Windows.

В качестве основы взял вот это - http://www.codenet.ru/progr/bcb/pipes.php

Получилась вполне рабочая программа, которая при тестировании перехватывала cmd и позволяла отправлять команды в запущенный процесс.

Но вот проблема. При запуске hlds создается еще один дочерний процесс, а первоначальный процесс завершается.

Сама программа:
Вложение:
screen.zip [129.67 КБ]
Скачиваний: 229


Исходник:
Вложение:
screen_source.zip [3.48 КБ]
Скачиваний: 244


Немного поясню принцип работы программы:

Запуск процесс с перехватом данных осуществляется командой:
Код:
screen.exe -t start -S hlds -c "C:\servers\hlds\hlds.exe -console -game valve +ip 127.0.0.1 +port 27015 +map crossfire"
screen.exe -t start -S hlds -c "C:\Windows\System32\cmd.exe"

Получение содержимого консоли:
Код:
screen.exe -t get_console -S hlds

Отправка в консоль:
Код:
screen.exe -t send_command -S hlds -c "changelevel stalkyard"
screen.exe -t send_command -S hlds -c "help"

Завершение:
Код:
screen.exe -t kill -S hlds

Как я написал выше, с cmd всё работает, но при запуске HLDS через эту утилиту оно будет завершено.
Хотел бы спросить у знатоков aghl. Куда мне копать чтобы получить содержимое консоли HLDS?


Последний раз редактировалось ImperNik 04 дек 2014, 04:53, всего редактировалось 1 раз.

Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Перехват консоли HLDS на Windows
СообщениеДобавлено: 04 дек 2014, 03:03 
Не в сети
Site Admin
Зарегистрирован:
01 июн 2010, 01:27
Последнее посещение:
26 мар 2024, 21:42
Сообщения: 6864
ImperNik писал(а):
screen.exe -t start -S hlds -c "C:\servers\hlds\hlds.exe -game valve +ip 127.0.0.1 +port 27015 +map crossfire"
-console параметр не добавил.


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Перехват консоли HLDS на Windows
СообщениеДобавлено: 04 дек 2014, 04:05 
Не в сети
Аватара пользователя
Зарегистрирован:
21 мар 2012, 13:21
Последнее посещение:
27 дек 2023, 02:51
Сообщения: 165
Да, это здесь не добавил. С -console также не работает.

_________________
Портал Half-Life DeathMatch


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Перехват консоли HLDS на Windows
СообщениеДобавлено: 04 дек 2014, 05:50 
Не в сети
Site Admin
Зарегистрирован:
01 июн 2010, 01:27
Последнее посещение:
26 мар 2024, 21:42
Сообщения: 6864
Там вроде не должно быть дочернего процесса, по крайней мере с -console.
Не ковырял работу с консолью в хлдс. Если судить по описанному, то есть такие варианты:
    отловить создание процесса, перехватить ввод-вывод в нем при этом;
    хукнуть функции по работе с консолью в движке;
    скорее всего консоль там через какой-нить интерфейс реализована (чтобы можно было в GUI выводить) - можно интерфейс перехватить;


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Перехват консоли HLDS на Windows
СообщениеДобавлено: 04 дек 2014, 06:08 
Не в сети
Аватара пользователя
Зарегистрирован:
21 мар 2012, 13:21
Последнее посещение:
27 дек 2023, 02:51
Сообщения: 165
Lev писал(а):
отловить создание процесса, перехватить ввод-вывод в нем при этом;[/list]
Не представляю как это сделать.
Ведь изначально созданы пайпы (один на вывод, другой на ввод) для запускаемого процесса. Как узнать, что дочерним процессом создан еще один? Где получить дескрипторы на еще один создаваемый процесс?

Lev писал(а):
скорее всего консоль там через какой-нить интерфейс реализована (чтобы можно было в GUI выводить) - можно интерфейс перехватить;[/list]
Скорее всего так и есть. Но, опять же, как узнать, что имеем дело с GUI, и как создать пайпы на него?


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Перехват консоли HLDS на Windows
СообщениеДобавлено: 04 дек 2014, 06:13 
Не в сети
Site Admin
Зарегистрирован:
01 июн 2010, 01:27
Последнее посещение:
26 мар 2024, 21:42
Сообщения: 6864
На деле, хлдс не создает никаких дочерних процессов. Сколько в дебаге с ним просидел, никогда такого не было.
Стало быть процесс всё же один.
А тебе надо GUI хлдс хукнуть или всё же консольный? Мне почему-то кажется что консольный.
Так или иначе, если возиться с хуками - надо туда инжектиться, а в таком варианте проще уж сразу просто модуль под метамод написать.
С интрефейсами, если захотеть, можно поразбираться, получить экземпляр можно через экспортируемую функцию, а дальше надо понять как его использовать.


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Перехват консоли HLDS на Windows
СообщениеДобавлено: 04 дек 2014, 06:50 
Не в сети
Аватара пользователя
Зарегистрирован:
21 мар 2012, 13:21
Последнее посещение:
27 дек 2023, 02:51
Сообщения: 165
Хукнуть нужно именно консольный, но с HLDS это не получается.
Новый процесс запускается функцией:
Код:
CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)

После запуска есть цикл, в котором имеется проверка:
Код:
GetExitCodeProcess(pi.hProcess,&exit); //пока дочерний процесс не закрыт
if (exit != STILL_ACTIVE)
      break;

При запуске простого консольного приложения, будь то cmd.exe или cout << "Hello, world"; sleep(2000); никаких проблем нет. Переменная exit имеет значение STILL_ACTIVE, но при запуске hlds оно имеет значение отличное от STILL_ACTIVE, если быть точнее, то 4294967295.

Проверку убрал и перехват на радость заработал. Правда при запуске через моё приложение сервер не запускается:
Код:
Console initialized.
FATAL ERROR (shutting down): W_LoadWadFile: couldn't load gfx.wad
Using breakpad crash handler
Setting breakpad minidump AppID = 70
Forcing breakpad minidump interfaces to load
Looking up breakpad interfaces from steamclient
Calling BreakpadMiniDumpSystemInit
Я так понимаю где-то нужно задать рабочую директорию.


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Перехват консоли HLDS на Windows
СообщениеДобавлено: 04 дек 2014, 07:00 
Не в сети
Site Admin
Зарегистрирован:
01 июн 2010, 01:27
Последнее посещение:
26 мар 2024, 21:42
Сообщения: 6864
Можно из одной папки запускать, можно в CreateProcess передать параметр, можно рабочую директорию сменить программно.
Насчет проверки, -1 возвращает - какая-то ошибка, скорее всего. Можешь GetLastError проверить. Или попробуй GetProcessId вместо этого.


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Перехват консоли HLDS на Windows
СообщениеДобавлено: 04 дек 2014, 07:20 
Не в сети
Аватара пользователя
Зарегистрирован:
21 мар 2012, 13:21
Последнее посещение:
27 дек 2023, 02:51
Сообщения: 165
В CreateProcess 8-ой параметр и есть директория, передал директорию и сервер запустился, порт слушает, подключиться возможно.

При запуске через screen.exe создается пустое окошко hlds. Как я понял, это из-за того, что данные уходят в другое место.
Вложение:
Windows.png
Windows.png [ 44.46 КБ | Просмотров: 4349 ]


Перехват содержимого консоли работает нормально, но вот отправка команд не работает. Не работает если отправлять через screen.exe и если вписывать в пустое окошко hlds.

Добавлено спустя 24 минуты 45 секунд:
Как я понял, проблема кроется в символах окончания строки. Когда в HLDS срабатывает отправка команды? Когда в строке есть символ \n, \r? Или как-то по другому?
Просто и то и другое испробовал, а результат нулевой.


Вернуться к началу
 Профиль 
  
 Заголовок сообщения: Re: Перехват консоли HLDS на Windows
СообщениеДобавлено: 05 дек 2014, 01:56 
Не в сети
Site Admin
Зарегистрирован:
01 июн 2010, 01:27
Последнее посещение:
26 мар 2024, 21:42
Сообщения: 6864
Команды в движок засылаются из hlds.exe через IDedicatedServerAPI интерфейс.
В hlds.exe используются GetNumberOfConsoleInputEvents и ReadConsoleInput для чтения команд в методе CTextConsoleWin32::GetLine, там же реализовано редактирование команды.
Судя по всему переопределенный stdin не влияет на ReadConsoleInput.

Можно попробовать пойти другим путем. У hlds.exe есть фича для управления вводом/выводом посредством параметров запуска -HFILE -HPARENT -HCHILD. Под это дело, в HLSDK, в utils, есть проект serverctrl. Можешь его поковырять.

Ещё можно попробовать
Код:
   FreeConsole();
   if (!AttachConsole(pi.dwProcessId))
Этот кусок кода работает, и, возможно, после этого можно будет читать/писать в консоль сервера напрямую.


Вернуться к началу
 Профиль 
  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 12 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 5 часов [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB