Мой вопрос довольно прост, но решение кажется абсолютно невозможным для меня.
У меня есть выделенный игровой сервер (JEDI ACADEMY JAMPDED), который является консольным приложением. Он постоянно пишет некоторую информацию, и я хочу как-то обработать данные. Было бы легко, если бы я мог прочитать вывод с внешнего.
Проблема: он не записывает в стандартный вывод, поэтому не может быть передан с помощью пакетного файла, и popen также не работает.
Поэтому я хотел сделать с WINAPI. Я смог создать процесс, но все еще не могу прочитать вывод.
Я попробовал это:
Как мне вызвать :: CreateProcess в c ++ для запуска исполняемого файла Windows?
CreateProcess и CreatePipe для выполнения процесса и возврата вывода в виде строки в VC ++
И официальный пример MSDN, но все равно ничего.
Это jampded.exe:
Я получил базовый визуальный код от моего друга, который читает ConsoleInput из Ingame, поэтому я почти уверен, что консоль можно прочитать:
SNIPPET:
Global hWnd = FindWindow_(#Null,"Jedi Knight Academy MP Console") ;console window
Global hWnd2 = FindWindow_(#Null,"Jedi Knight®: Jedi Academy (MP)") ;actual game window
Global inputhWnd = FindWindowEx_(hwnd,0,"edit",0) ;the one to send stuff to
Global consolehWnd = FindWindowEx_(hwnd,inputhWnd,"edit",0) ;the one to read the console fromProcedure checkConsole()
Protected wholetext.s, oldtext.s,text.s, checkname.s
Repeat
wholetext = getText()
If wholetext
text = StringField(wholetext,CountString(wholetext,#CRLF$),#CRLF$)
If oldtext <> text
oldtext = text
analyseConsole(@text)
EndIf
EndIf
Delay(20)
writePreferences()
Until quit
EndProcedure
Procedure.s getText()
Protected wholetext.s
If hWnd And hWnd2
If Not inputhWnd Or Not consolehWnd
inputhWnd = FindWindowEx_(hWnd,0,"edit",0)
consolehWnd = FindWindowEx_(hWnd,inputhWnd,"edit",0)
EndIf
length = SendMessage_(consolehWnd, #WM_GETTEXTLENGTH, 0, 0)
wholetext = Space(length)
SendMessage_(consolehWnd,#WM_GETTEXT,length + SizeOf(Character),@wholetext)
ProcedureReturn wholetext
Else
If FindWindow_(#Null,"Jedi Knight Academy MP Console")
hWnd = FindWindow_(#Null,"Jedi Knight Academy MP Console")
hWnd2 = FindWindow_(#Null,"Jedi Knight®: Jedi Academy (MP)")
inputhWnd = FindWindowEx_(hwnd,0,"edit",0)
consolehWnd = FindWindowEx_(hwnd,inputhWnd,"edit",0)
EndIf
ProcedureReturn ""EndIf
If @wholetext > 0
FreeMemory(@wholetext)
EndIf
EndProcedure
Может быть, это может помочь мне и другим тоже 🙂
Ханс Пассант был прав. Он не пишет в стандартный вывод, но я мог бы исправить это с помощью сборки. Так что он был не прав в этом.
После этого выходные данные были не синхронизированы, но их можно было успешно исправить, изменив переход на nops. Больше: stackoverflow.com/questions/23811572/writefile-function-with-assembly-debugging-syncing
Итак, подведите итог:
Это не только для выделенного сервера Jedi Academy, это может быть полезно для любого двоичного файла, в котором хранятся выходные данные, но не для STDOUT.
Изменение функции WriteFile для записи в STDOUT (-11 — это стандартный вывод):
Исправить проблему синхронизации:
Он предназначен для JampDed 1.00, поэтому, если вы хотите использовать его для другой версии JK или для другой игры, вы должны найти эти адреса самостоятельно. Лучшая практика (на мой взгляд), если вы идете, позвоните по телефону глубже в коде. Вы можете начать с любого сообщения, которое найдете, а затем углубиться.
Я записал весь процесс отладки следующим образом:
004429a7 is (call 0043d440)
- 0043d44e (call 00422720)
-- 004227dD (call edx) - 2008F1B0
--- 2008f103 (call 2008cad0)
---- 2008c4d0
----- 2008c569 (call 2008b030)
------ 200a25f7 DWORD PTR DS:[20106A28] - 00422540
------- 0042254b (CALL DWORD PTR DS:[ECX+4]) - 0043d590
-------- 0043d8aa (call 0040fb40)
--------- 0040FC39 (call 0044b7a0)
---------- 0044b66c (call 004964dd)
----------- 00496500 (call 0049a4ba)
------------ 0049a4cd (call 00497d66)
------------- 00497d92 (call 0049e18c)
-------------- 0049e26f (CALL DWORD PTR DS:[4A715C])
И если вы заметите, последний находится там, где находится WriteFile. И 2 до этого, где находится материал logsync
А сейчас
jampDed.exe | stdout.exe
работает, и вы можете легко начать создавать свой собственный мод для сервера. Или что угодно. 🙂
Других решений пока нет …