4

私の質問は非常に単純ですが、解決策を見つけるのは絶対に不可能に思えます。

コンソール アプリケーションである専用のゲーム サーバー (JEDI ACADEMY JAMPDED) があります。いくつかの情報を継続的に書き込みます。データを何らかの方法で処理したいと考えています。その出力を外部で読めるようになれば簡単です。

問題: 標準出力に書き込まれないため、バッチ ファイルでパイプできず、popen も機能しません。

だから私はWINAPIでやりたかった。プロセスを作成できましたが、まだ出力を読み取ることができません。

私はこれらを試しました:

これは jampded.exe です。 コンソール

Ingame から ConsoleInput を読み取る友人からビジュアルベーシック コードを入手したので、コンソールを読み取ることができると確信しています。

スニペット:

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 from


Procedure 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

たぶん、これは私や他の人にも役立つかもしれません:)

4

1 に答える 1

1

ハンス・パッサンは正しかった。stdout には書き込みませんが、アセンブリで修正できました。したがって、彼はその点で正しくありませんでした。

この後、出力は同期されませんでしたが、ジャンプを nops に交換することで正常に修正できました。詳細: stackoverflow.com/questions/23811572/writefile-function-with-assembly-debugging-syncing

すべてを要約すると、次のようになります。

これは、Jedi Academy Dedicated Server だけでなく、出力を保存するバイナリ ファイルにも役立ちますが、STDOUT には役立ちません。

WriteFile 関数を STDOUT に書き込むように変更します (-11 は stdout です):

ここに画像の説明を入力

同期の問題を修正:

ここに画像の説明を入力

これは 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

動作し、サーバー用の独自の mod の作成を簡単に開始できます。またはあなたが望むもの。:)

于 2014-05-24T07:27:12.720 に答える