scriptsdk/CSharp-ScriptSDK-Legacy

GetContextMenuRec gives MarshalDirectiveException

Opened this issue · 1 comments

Calling "Stealth.Client.GetContextMenuRec();" gives the following exception:

System.Runtime.InteropServices.MarshalDirectiveException: Type System.Collections.Generic.List`1<StealthAPI.ContextMenuEntry> which is passed to unmanaged code must have a StructLayout attribute.
  at at (wrapper unknown) StealthAPI.ContextMenu:PtrToStructure (intptr,object)
  at at (wrapper managed-to-native) System.Runtime.InteropServices.Marshal:PtrToStructure (intptr,System.Type)
  at StealthAPI.Marshaler.MarshalToObject (System.Byte[] buffer, System.Type type) [0x00098] in /ScriptSDK/ScriptSDK/Stealth API/Marshaler.cs:40
  at StealthAPI.Marshaler.MarshalToObject[T] (System.Byte[] buffer) [0x0000c] in /ScriptSDK/ScriptSDK/Stealth API/Marshaler.cs:19
  at StealthAPI.StealthClient.WaitReply[T] (StealthAPI.PacketType type) [0x0007a] in /ScriptSDK/ScriptSDK/Stealth API/Network/StealthClient.cs:247
  at StealthAPI.StealthClient.SendPacket[T] (StealthAPI.PacketType packetType, System.Object[] parameters) [0x00061] in /ScriptSDK/ScriptSDK/Stealth API/Network/StealthClient.cs:230
  at StealthAPI.Stealth.GetContextMenuRec () [0x00012] in /ScriptSDK/ScriptSDK/Stealth API/Stealth.cs:2814
  at MyScript.MainClass.OpenContextMenu () [0x0011f] in /MyScript/MyScript.cs:113
  at MyScript.MainClass.run (System.String[] args) [0x00070] in /MyScript/MyScript.cs:79
  at MyScript.MainClass.Main (System.String[] args) [0x0002e] in /MyScript/MyScript.cs:25

I've tried to work around it but it seems that the ContextMenuEntries aren't send by StealthClient:

Stealth.Network: Send packet. Type: SCRequestContextMenu, Param: E3,17,04,00
Stealth.Network: Send packet. Type: SCGetContextMenuRec, Param: 
Stealth.Network: Read packet. Type: SCReturnValue, Param: 59,01,E3,17,04,00,06,01,00,00,01
public struct ContextMenu
{
    public uint ID { get; set; }
    public byte EntriesNumber { get; set; }
    public bool NewCliloc { get; set; }
    public List<ContextMenuEntry> Entries { get; set; }
}

The SCReturnValue seems to consist of:
59,01, <-- SCGetContextMenuRec number
E3,17,04,00, <-- "ID": Vendor I requested the ContextMenuRec for
06, <-- "EntriesNumber": 6 Entries are in the ContextMenuRec
01, <-- "NewCliloc": no idea what this does
00,00,01 <-- too short to be a list of ContextMenuEntries...

Bosek commented

The issue is about trying to marshall List type. It should be solvable by de-serializing it manually. However, I had the same problem with data seemingly not making much sense. And since there is no documentation about these packets, you shouldn't really use Stealth.Client.GetContextMenuRec(), but use Item.AttachContextMenu() instead.

I have to admit I had really hard time trying to learn how to use ContextMenu properly in ScriptSDK:

  1. You need to call ScriptSDK.Configuration.ContextOptions.Initialize() or just ScriptSDK.SDK.Initialize()
  2. Get Item or Mobile instance and call .AttachContextMenu() on it.
  3. Access entries using .ContextMenu.Entries and send clicks with .ContextMenu.Click()