Half-Life и Adrenaline Gamer форум http://aghl.ru/forum/ |
|
Перехват консоли HLDS на Windows http://aghl.ru/forum/viewtopic.php?f=38&t=1996 |
Страница 1 из 2 |
Автор: | ImperNik [ 04 дек 2014, 01:58 ] |
Заголовок сообщения: | Перехват консоли HLDS на Windows |
Решил написать утилиту, которая позволит запустить консольный процесс с перехватом данных вывода (StdIn) и позволит отправлять команды в этот консольный процесс (StdOut). Что-то вроде аналога Screen под Linux, но только для Windows. В качестве основы взял вот это - http://www.codenet.ru/progr/bcb/pipes.php Получилась вполне рабочая программа, которая при тестировании перехватывала cmd и позволяла отправлять команды в запущенный процесс. Но вот проблема. При запуске hlds создается еще один дочерний процесс, а первоначальный процесс завершается. Сама программа: Вложение: Исходник: Вложение: Немного поясню принцип работы программы: Запуск процесс с перехватом данных осуществляется командой: Код: 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 get_console -S hlds Отправка в консоль: Код: screen.exe -t send_command -S hlds -c "changelevel stalkyard" Завершение: Код: screen.exe -t kill -S hlds Как я написал выше, с cmd всё работает, но при запуске HLDS через эту утилиту оно будет завершено. Хотел бы спросить у знатоков aghl. Куда мне копать чтобы получить содержимое консоли HLDS? |
Автор: | Lev [ 04 дек 2014, 03:03 ] |
Заголовок сообщения: | Re: Перехват консоли HLDS на Windows |
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 параметр не добавил.
|
Автор: | ImperNik [ 04 дек 2014, 04:05 ] |
Заголовок сообщения: | Re: Перехват консоли HLDS на Windows |
Да, это здесь не добавил. С -console также не работает. |
Автор: | Lev [ 04 дек 2014, 05:50 ] |
Заголовок сообщения: | Re: Перехват консоли HLDS на Windows |
Там вроде не должно быть дочернего процесса, по крайней мере с -console. Не ковырял работу с консолью в хлдс. Если судить по описанному, то есть такие варианты:
хукнуть функции по работе с консолью в движке; скорее всего консоль там через какой-нить интерфейс реализована (чтобы можно было в GUI выводить) - можно интерфейс перехватить; |
Автор: | ImperNik [ 04 дек 2014, 06:08 ] |
Заголовок сообщения: | Re: Перехват консоли HLDS на Windows |
Lev писал(а): отловить создание процесса, перехватить ввод-вывод в нем при этом;[/list] Не представляю как это сделать.Ведь изначально созданы пайпы (один на вывод, другой на ввод) для запускаемого процесса. Как узнать, что дочерним процессом создан еще один? Где получить дескрипторы на еще один создаваемый процесс? Lev писал(а): скорее всего консоль там через какой-нить интерфейс реализована (чтобы можно было в GUI выводить) - можно интерфейс перехватить;[/list] Скорее всего так и есть. Но, опять же, как узнать, что имеем дело с GUI, и как создать пайпы на него?
|
Автор: | Lev [ 04 дек 2014, 06:13 ] |
Заголовок сообщения: | Re: Перехват консоли HLDS на Windows |
На деле, хлдс не создает никаких дочерних процессов. Сколько в дебаге с ним просидел, никогда такого не было. Стало быть процесс всё же один. А тебе надо GUI хлдс хукнуть или всё же консольный? Мне почему-то кажется что консольный. Так или иначе, если возиться с хуками - надо туда инжектиться, а в таком варианте проще уж сразу просто модуль под метамод написать. С интрефейсами, если захотеть, можно поразбираться, получить экземпляр можно через экспортируемую функцию, а дальше надо понять как его использовать. |
Автор: | ImperNik [ 04 дек 2014, 06:50 ] |
Заголовок сообщения: | Re: Перехват консоли HLDS на Windows |
Хукнуть нужно именно консольный, но с HLDS это не получается. Новый процесс запускается функцией: Код: CreateProcess(NULL, szCmdLine, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi) После запуска есть цикл, в котором имеется проверка: Код: GetExitCodeProcess(pi.hProcess,&exit); //пока дочерний процесс не закрыт При запуске простого консольного приложения, будь то cmd.exe или cout << "Hello, world"; sleep(2000); никаких проблем нет. Переменная exit имеет значение STILL_ACTIVE, но при запуске hlds оно имеет значение отличное от STILL_ACTIVE, если быть точнее, то 4294967295. Проверку убрал и перехват на радость заработал. Правда при запуске через моё приложение сервер не запускается: Код: Console initialized.Я так понимаю где-то нужно задать рабочую директорию. |
Автор: | Lev [ 04 дек 2014, 07:00 ] |
Заголовок сообщения: | Re: Перехват консоли HLDS на Windows |
Можно из одной папки запускать, можно в CreateProcess передать параметр, можно рабочую директорию сменить программно. Насчет проверки, -1 возвращает - какая-то ошибка, скорее всего. Можешь GetLastError проверить. Или попробуй GetProcessId вместо этого. |
Автор: | ImperNik [ 04 дек 2014, 07:20 ] |
Заголовок сообщения: | Re: Перехват консоли HLDS на Windows |
В CreateProcess 8-ой параметр и есть директория, передал директорию и сервер запустился, порт слушает, подключиться возможно. При запуске через screen.exe создается пустое окошко hlds. Как я понял, это из-за того, что данные уходят в другое место. Вложение: Перехват содержимого консоли работает нормально, но вот отправка команд не работает. Не работает если отправлять через screen.exe и если вписывать в пустое окошко hlds. Добавлено спустя 24 минуты 45 секунд: Как я понял, проблема кроется в символах окончания строки. Когда в HLDS срабатывает отправка команды? Когда в строке есть символ \n, \r? Или как-то по другому? Просто и то и другое испробовал, а результат нулевой. |
Автор: | Lev [ 05 дек 2014, 01:56 ] |
Заголовок сообщения: | Re: Перехват консоли HLDS на Windows |
Команды в движок засылаются из hlds.exe через IDedicatedServerAPI интерфейс. В hlds.exe используются GetNumberOfConsoleInputEvents и ReadConsoleInput для чтения команд в методе CTextConsoleWin32::GetLine, там же реализовано редактирование команды. Судя по всему переопределенный stdin не влияет на ReadConsoleInput. Можно попробовать пойти другим путем. У hlds.exe есть фича для управления вводом/выводом посредством параметров запуска -HFILE -HPARENT -HCHILD. Под это дело, в HLSDK, в utils, есть проект serverctrl. Можешь его поковырять. Ещё можно попробовать Код: FreeConsole();Этот кусок кода работает, и, возможно, после этого можно будет читать/писать в консоль сервера напрямую. |
Страница 1 из 2 | Часовой пояс: UTC + 5 часов [ Летнее время ] |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |