本文介绍了读取控制台缓冲区/输出C ++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题很简单,但是解决方案似乎绝对不可能找到。



我有一个专用的游戏服务器(JEDI ACADEMY JAMPDED)控制台应用程序。它连续写入一些信息,我想以某种方式处理数据。这将是很容易,如果我可以读取它的输出与外部。



问题:它不写入标准输出,所以不能管道与批处理文件和popen不起作用。



所以我想使用WINAPI。



我试过这些:






  • 这样总结:



    这不只是为了Jedi Academy专用服务器,



    更改WriteFile函数以写入STDOUT(-11是stdout):





    修复同步问题:





    它是为JampDed 1.00,所以如果你想使用它的另一个版本的JK或另一个游戏,你必须自己找到这些地址。最佳实践(在我看来)如果你通过调用更深入的代码。你可以从你发现的任何消息开始,然后再深入。



    我以这种方式记录了整个调试过程:

      004429a7是(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所在的位置。

     <$ c $ 

    c> jampDed.exe | stdout.exe

    可以轻松地为服务器创建自己的mod。或任何你想要的。 :)


    My question is quite simple, but the solution seems absolutely impossible for me to find.

    I have a dedicated game server (JEDI ACADEMY JAMPDED), which is a console application. It writes some information continously and I want to handle the data somehow. It would be easy if I could read the output of it with external.

    Problem: It does not write to Standard Output, so can't be piped with batch file and popen does not work also.

    So I wanted to do with WINAPI. I was able to create the process, but still can't read the output.

    I tried these:

    This is the jampded.exe:

    I got a visual-basic code from my friend, who reads ConsoleInput from Ingame, so I'm pretty sure, that it is possible to read the console:

    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 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
    

    Maybe this could help me and others too :)

    解决方案

    Hans Passant was right. It does not write to stdout, but I could fix it with assembly. So he was not right in that.

    After this the output was unsynced, but it could be successfully fixed with exchanging a jump to nops. More: stackoverflow.com/questions/23811572/writefile-function-with-assembly-debugging-syncing

    So sum everything up:

    It is not just for Jedi Academy Dedicated Server, it can be useful for any binary file that stores output, but not to STDOUT.

    Changing WriteFile function to write to STDOUT (-11 is stdout):

    Fix syncing problem:

    It is for JampDed 1.00, so if you want to use it for another version of JK, or for another game, you must find these addresses yourself. Best practise (in my opinion) if you go call by call deeper in the code. You may start from any message you find, then go deeper.

    I have logged the whole debugging process this way:

    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])
    

    And if you notice the last one is where WriteFile is located. And 2 before that is where the logsync stuff is located

    So now

    jampDed.exe | stdout.exe
    

    works, and you can start creating your own mod for the server easily. Or anything you want. :)

    这篇关于读取控制台缓冲区/输出C ++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-19 12:01