question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Recompiling JSM scripts

See original GitHub issue

I started writing support for JSM codes. I do it in a separate assembly, without changing the existing code. Currently ported Deling code to C#. I dunno how much is enough for me, but I hope to finish AST and nice formatting.

  • Investigation of Opcodes ⬛⬛⬛⬛⬛⬛⬜⬜⬜⬜ 60% We have an article on the wiki, a ready-made Deling and Garden sources, topics on the Qhimm forum and reverse engineering. Half the opcodes aren’t documented.

  • Disassembling of instructions ⬛⬛⬛⬛⬛⬛⬛⬛⬛⬛ 100% Handling the stack leads to a lot of errors. It is necessary to go from opcodes to a sequence of high-level instructions. PSHN_L(0); PSHN_L(127); MUSICVOL => SetMusicVolume(channel: 0, volume: 127) There was a lot of work done in Deling. Unfortunately, only basic instructions are described. The rest will have to finish. Currently, the stack sizes have been clarified for all instructions that were in valid files (several files don’t correspond to the JSM standard or contain obvious errors [invalid jumps in test files], they will have to be processed separately).

  • Building of abstract syntax tree ⬛⬛⬛⬛⬛⬛⬛⬛⬛⬛ 100% The bulk of the work has already been done in Deling. It is necessary to eliminate crutches that hide bugs and remove spaghetti from the code.

  • Print decompiled sources ⬛⬛⬛⬛⬛⬛⬛⬛⬜⬜ 80% Similar to the previous paragraph. Bugs less, spaghetti more. Need to refactor code. Instead of pseudocode, it is better to use C# syntax.

if var622_ubyte == 128 begin
	if var599_ubyte == 32 begin
		var1041_ubyte = 1
	end
else if var622_ubyte < 128 begin
	if var622_ubyte > 1 begin
		var622_ubyte = 2
	else if var622_ubyte == 1 begin
		var622_ubyte = 1
	else if var617_ubyte > 1 begin
		var622_ubyte = 2
	else if var617_ubyte == 1 begin
		var622_ubyte = 1
	else if var618_ubyte > 1 begin
		var622_ubyte = 2
	else if var618_ubyte == 1 begin
		var622_ubyte = 1
	else if var620_ubyte > 1 begin
		var622_ubyte = 2
	else if var620_ubyte == 1 begin
		var622_ubyte = 1
	else if var621_ubyte > 1 begin
		var622_ubyte = 2
	else if var621_ubyte == 1 begin
		var622_ubyte = 1
	else if var616_ubyte > 1 begin
		var622_ubyte = 2
	else if var616_ubyte == 1 begin
		var622_ubyte = 1
	else
		var599_ubyte = 32
	end
end
ret(8)
  • Translate to expression tree / IL Code / Custom execution logic ⬛⬛⬛⬛⬛⬛⬛⬜⬜⬜ 60% The easiest way to execute code without creating your own state machine is to translate instructions into IL code or Expressions. But to support such a thing is difficult. If we choose this path, it is necessary to cover each expression with tests. But we can use Roslyn, after generating a C# code, and then parsing it.

  • Parsing of scripts ⬜⬜⬜⬜⬜⬜⬜⬜⬜⬜ 0% To support modifications, it is necessary to learn how to parse the text representation of scripts, which is easy for players to edit. If we can use .NET Core and Roslyn, the easiest way is to write scripts in C# and parse them as Syntax Tree.

  • Testing ⬛⬛⬛⬛⬜⬜⬜⬜⬜⬜ 40% The current version enumerates all fileds and generates pseudo-code for them. There is one known bug that I am going to fix soon. In the future, it is necessary to cover with tests all the mechanisms for working with JSM, in order to eliminate bugs in this segment. Analyzing errors in it is VERY difficult.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:12

github_iconTop GitHub Comments

2reactions
Albeoriscommented, Apr 23, 2019

Instructions successfully combined into blocks. I caught all the obvious mistakes, but I could not notice anything. We’ll have to test in the future.

The next task is to bring this into a readable form.

Version 3:

public sealed class queen
{
    private readonly IScriptExecutionContext _ctx;

    public queen(IScriptExecutionContext executionContext)
    {
        _ctx = executionContext;
        LBL(Label: 32)
        SETMODEL(_parameter: 8)
        BASEANIME(_parameter: 0, _arg0: PSHN_L(Value: 1), _arg1: PSHN_L(Value: 1))
        if(((UInt16)Global[256] >= 3860))
        {
            SET3(_parameter: 27, _arg0: PSHN_L(Value: 294), _arg1: PSHN_L(Value: -8108), _arg2: PSHN_L(Value: 0))
            DIR(_arg0: PSHN_L(Value: 224))
        }
        else
        {
            UNUSE(_parameter: 0)
        }
        RET(_parameter: 8)
    }

    public void Default()
    {
        LBL(Label: 33)
        HALT(_parameter: 0)
        RET(_parameter: 8)
    }

    public void Talk()
    {
        LBL(Label: 34)
        UCOFF()
        RANIME(_parameter: 2)
        // Queen
        // “It’s been a long time.
        //  Do you wish to challenge me?”
        //☞ Yes
        //☜ No
        AASK(channel: PSHN_L(Value: 0), messageId: PSHN_L(Value: 3), top: PSHN_L(Value: 3), bottom: PSHN_L(Value: 4), begin: PSHN_L(Value: 3), cancel: PSHN_L(Value: 4), posX: PSHN_L(Value: 10), posY: PSHN_L(Value: 10));
        if((Temp[0] == 0))
        {
            // Queen
            // “Permit me to play with
            //  whatever rule I desire.”
            AMESW(channel: PSHN_L(Value: 0), messageId: PSHN_L(Value: 4), posX: PSHN_L(Value: 10), posY: PSHN_L(Value: 10));
            CARDGAME(_arg0: PSHN_L(Value: 1), _arg1: PSHN_L(Value: 222), _arg2: PSHN_L(Value: 1), _arg3: PSHN_L(Value: 100), _arg4: PSHN_L(Value: 23), _arg5: PSHN_L(Value: 4), _arg6: PSHN_L(Value: 127))
            if((Temp[0] < 5))
            {
                // You need 5 or more
                // cards to play.
                AMESW(channel: PSHN_L(Value: 0), messageId: PSHN_L(Value: 34), posX: PSHN_L(Value: 10), posY: PSHN_L(Value: 10));
            }
        }
        UCON()
        RET(_parameter: 8)
    }

    public void Push()
    {
        LBL(Label: 35)
        RET(_parameter: 8)
    }
}
1reaction
Albeoriscommented, May 21, 2019

Fixed, now conditional blocks correctly check conditions before execution!

In addition, I fixed one rare formatting error.

Now successfully executed (of course, with stubs instead of some actions) 57 out of 72 scripts in the bghoke_2 location.

I think I will check the rest tomorrow and start to upload the changes. Due to unforeseen problems, the dates went a bit, so I plan to finish at the end of this week.

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to force recompilation of scripts
I have a setup with several classes defined in groovy scripts. These classes have dependencies, so the change of a class script file...
Read more >
Possibilities of customizing the functionalities o...
Hello, We are currently looking into the possibility of using Jira Service Management in the Data Center version.
Read more >
8.0 Creating and Speaking Messages
... learn how to create your messages within a JAWS script message, (.jsm) file. ... you must recompile each script file that includes...
Read more >
Pre-compile JSM scripts into the shared JSM global rather ...
We currently off-thread pre-compile JSM scripts into xpc::CompilationScope, and then clone them into the module's global scope before executing.
Read more >
11.5 Chapter Exercises
11.5 Chapter Exercises. The following exercises give you practice creating and using messages in the virtual viewer. Before you start these exercises, ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found