dedmen / TodoStuff

The stuff I gotta do some day. Finally getting organized
0 stars 0 forks source link

ArmaDebugEngine VS Code integration #24

Open dedmen opened 6 years ago

dedmen commented 6 years ago

Integrate https://github.com/dedmen/ArmaDebugEngine into VS Code via a Debugger plugin.

@SkaceKamen Feels like this is the easiest way to contact you. My JS is not good enough and I never wrote a VS Code plugin. Are you maybe interested in this? The API is JSON over a NamedPipe.

dedmen commented 6 years ago

https://gist.github.com/dedmen/cde954f26c1221ae0aa2ea91d1959240 https://gist.github.com/dedmen/12d693bc5992177fe349dd214dbc955e https://gist.github.com/dedmen/a324279f022cbac1bcf18ff08b890dff https://gist.github.com/dedmen/ba36f8621f14c63cb2911cdd0d79447b https://gist.github.com/dedmen/b3079dbd22d761c0c98e1b957432672e

SkaceKamen commented 6 years ago

Hey, I wanted to do this some time ago, but the plugin wasn't working (it was shortly after some update). Is it working now?

dedmen commented 6 years ago

Ported it to Intercept today. Will have to check if everything works. But the basic setting a breakpoint and it breaking with callstack was working yesterday

SkaceKamen commented 6 years ago

Ok nice, I'll take a look then

dedmen commented 6 years ago

How can I communicate with you better? I could make a Discord server if you have Discord. That way the guys that make integrations for other IDE's can also be in there and I don't need to explain everything twice ;D

Still working on fixes for x64 currently.. Last time it worked x64 was just out and barely used.

dedmen commented 6 years ago

Here is a example breakpoint hit for

{
    private _fnc_scriptNameParent = if (isNil '_fnc_scriptName') then {'CBA_fnc_currentUnit'} else {_fnc_scriptName};
    private _fnc_scriptName = 'CBA_fnc_currentUnit';
    scriptName _fnc_scriptName;

#line 1 "\x\cba\addons\common\fnc_currentUnit.sqf [CBA_fnc_currentUnit]"
_myVar = "test";
missionNamespace getVariable ["bis_fnc_moduleRemoteControl_unit", player]
}

https://gist.github.com/dedmen/747a8d2eb7c0e2a82b90c60a810a2987

Ignore the callstack->compiled entry. That are the compiled VM instructions.. Will probably disable them as they are kinda useless.

As you can seeyou also get all local variable of each scope. and via the scopes ip (current instruction) you can go into compiled[ip-1] and get the filename and line of the instruction that is currently being executed in that scope.

In this example. last scope is at IP 20 which is the constant string "bis_fnc_moduleRemoteControl_unit" Next scope higher is at instruction 3. Which is a script function which is named call. If you look one higher you can see that there is a GameInstructionVariable which retrieves the variable cba_fnc_currentunit So you know the function was called by someone executing call cba_fnc_currentunit. Sadly we don't know which file called it. Arma doesn't give me that data because the function was compiled from bare string and not from preprocessFileLineNumbers.

If your IDE doesn't have the file that just triggered a breakpoint. There is also a API function to retrieve the full source code of the file. so that you can display it in a temp file

SkaceKamen commented 6 years ago

Do you have build somewhere? So I can test it?

If you want to share info with other devs, best would be to put the most informations to github wiki or something. But I can join you on discord if you want.

dedmen commented 6 years ago

@ArmaDebugEngine.zip

Here is a full build. x64 only. no battleye.

In my test I'm using CBA_fnc_currentUnit but changed the function to

_myVar = "test";
missionNamespace getVariable ["bis_fnc_moduleRemoteControl_unit", player]

That's because of a really nasty Arma bug..

/* #line1
comments #line2
*/ #line3
#include "script_component" #Line4
code #Line1773

versus

#include "script_component" #Line1
/* #line2
comments #line3
*/ #line4
code #Line5

include after a block comment completly fucks the preprocessor's line numbers. And if the IDE doesn't or can't think of that you'll be waaaay off. Don't have a good solution for that yet.

Here is the JSON api transaction SEND {"command":1} //Hello! RECV {"HI":{"Alive":true,"EnMouse":true,"InstrBP":true,"PreCon":false,"PreDef":true,"ScrAass":false,"ScrErr":false,"ScrHalt":true,"SvmCon":true,"SvmSimEn":true,"SvmSimSt":true,"WMEVE":true,"WMEVS":true,"WSim":true},"arch":"X64","build":13371337,"command":1,"gameType":"","gameVersion":"1.82.144709","version":"1.0.0.dev"} //Hey you! Here is my integrity check data so you know if I'm working correctly.

Then the debugger waits for commands. Adding a breakpoint in my scripts Line 2. SEND {"command":2,"data":{"action":{"code":null,"basePath":null,"type":2},"condition":null,"filename":"\\x\\cba\\addons\\common\\fnc_currentUnit.sqf","line":2}} you can use condition as a SQF script condition that is evaluated each time the BP is hit that has to return true/false. action is a.. well. action. You can execute a log command or a SQF script when a breakpoint is hit. Just like in visual studio.

next the debugger answers with the gist link I posted above.

dedmen commented 6 years ago

Was just writing that when you posted that :D I don't have time for a comprehensive wiki. I'll just make a Discord server so that you can directly ask stuff.

https://discord.gg/vbFje5B