daemitus / SomethingNeedDoing

85 stars 58 forks source link

/send CONTRL+V not working #108

Closed WilliamW1979 closed 1 year ago

WilliamW1979 commented 1 year ago

So when you do a line like:

/send CONTROL+V

It give this error:

[SND] Unexpected error.

I even tried using code directly from the github (compiling it myself and replacing the files) but the error is still the same.

Now I experimented and these all work:

/send CONTROL /send LCONTROL /send RCONTROL /send v

When I do this:

/send

I get [SND] Syntax error: /send

Researching your code, the only type the Unexpected error comes up is when you are in the RunMacro function and you are catching the second Exception.

That should give you an idea on where the problem lies.

private void RunMacro(MacroNode node) { try { Service.MacroManager.EnqueueMacro(node); } catch (MacroSyntaxError ex) { Service.ChatManager.PrintError($"{ex.Message}"); } catch (Exception ex) { Service.ChatManager.PrintError($"Unexpected error"); PluginLog.Error(ex, "Unexpected error"); } }

When I commented out that catch, it stopped sending the error but did not do the CONTROL+V as it should so your problem is somewhere in your function in the try statement (Service.MacroManager.EnqueueMacro(node)).

Considering that the function is:

public void EnqueueMacro(MacroNode node) { this.macroStack.Push(new ActiveMacro(node)); this.pausedWaiter.Set(); }

That means your problem is either the Push or the Set function causing some error that it is throwing the exception. Hopefully this helps you figure out what is happening.

WilliamW1979 commented 1 year ago

I was wrong, the error is definitely in the Parse function, it never reaches the Push().

I threw in some Lines to log to a log.txt file and it definitely got into the Parse function but it never got to the Push:

public static SendCommand Parse(string text) { string path = @"D:\Log.txt"; using (FileStream fs = File.OpenWrite(path)) { byte[] bytes = Encoding.UTF8.GetBytes("We Got Here (Parse)!"); fs.Write(bytes, 0, bytes.Length); } _ = WaitModifier.TryParse(ref text, out var waitModifier);

var match = Regex.Match(text);
if (!match.Success)
    throw new MacroSyntaxError(text);

var nameValue = ExtractAndUnquote(match, "name");
var vkCodes = nameValue.Split("+")
    .Select(name =>
    {
        if (!Enum.TryParse<VirtualKey>(nameValue, true, out var vkCode))
            throw new MacroCommandError("Invalid virtual key");

        return vkCode;
    })
    .ToArray();

return new SendCommand(text, vkCodes, waitModifier);

}

I will throw in some more log files to pin down the exact point of the problem

WilliamW1979 commented 1 year ago

Okay, pinned the problem for you!

public static SendCommand Parse(string text) { string path = @"D:\Log.txt"; using (FileStream fs = File.OpenWrite(path)) { byte[] bytes = Encoding.UTF8.GetBytes("We Got Here (Parse)!"); fs.Write(bytes, 0, bytes.Length); } _ = WaitModifier.TryParse(ref text, out var waitModifier);

using (FileStream fs = File.OpenWrite(path))
{
    byte[] bytes = Encoding.UTF8.GetBytes("We Got Here (Pre Regex)!");
    fs.Write(bytes, 0, bytes.Length);
}

var match = Regex.Match(text);
if (!match.Success)
    throw new MacroSyntaxError(text);

using (FileStream fs = File.OpenWrite(path))
{
    byte[] bytes = Encoding.UTF8.GetBytes("We Got Here (After Regex)!");
    fs.Write(bytes, 0, bytes.Length);
}

var nameValue = ExtractAndUnquote(match, "name");

using (FileStream fs = File.OpenWrite(path))
{
    byte[] bytes = Encoding.UTF8.GetBytes("We Got Here (Pre +)!");
    fs.Write(bytes, 0, bytes.Length);
}

var vkCodes = nameValue.Split("+")
    .Select(name =>
    {
        if (!Enum.TryParse<VirtualKey>(nameValue, true, out var vkCode))
            throw new MacroCommandError("Invalid virtual key");

        return vkCode;
    })
    .ToArray();

using (FileStream fs = File.OpenWrite(path))
{
    byte[] bytes = Encoding.UTF8.GetBytes("We Got Here (Post +)!");
    fs.Write(bytes, 0, bytes.Length);
}

return new SendCommand(text, vkCodes, waitModifier);

}

So your problem is definitely in this line:

var vkCodes = nameValue.Split("+") .Select(name => { if (!Enum.TryParse(nameValue, true, out var vkCode)) throw new MacroCommandError("Invalid virtual key");

    return vkCode;
})
.ToArray();

This is what you need to fix as it is causing an error. The log files get to the (Pre +) but never reach the (Post +) so somewhere between, that line, is causing your problems.

WilliamW1979 commented 1 year ago

Okay, for now I replaced your code with this:

for (int myCount = 0; myCount < mySub.Count(); myCount++) { switch (mySub[myCount]) { case "CONTROL": vkCodes[myCount] = VirtualKey.CONTROL; break; case "V": vkCodes[myCount] = VirtualKey.V; break; case "SHIFT": vkCodes[myCount] = VirtualKey.SHIFT; break; default: throw new MacroSyntaxError("Virtual Key not in the list!"); } }

It is crude but it works properly. I would literally have to add everything in there to get other keys to work but for now it should give you an idea of what is the problem and how to fix it.

WilliamW1979 commented 1 year ago

Sorry, I just got an earful from my student that I messed up her other macro because I messed up the other virtual keys. So I fixed it so her old macros will work now with the new code. This is the finished part:


    {
        _ = WaitModifier.TryParse(ref text, out var waitModifier);

        var match = Regex.Match(text);
        if (!match.Success)
            throw new MacroSyntaxError(text);

        var nameValue = ExtractAndUnquote(match, "name");

        int freq = nameValue.Count(f => (f == '+'));
        string[] mySub = nameValue.Split('+');
        var vkCodes = new VirtualKey[mySub.Count()];
        if (freq > 0)
        {

            for (int myCount = 0; myCount < mySub.Count(); myCount++)
            {
                switch (mySub[myCount])
                {
                    case "CONTROL":
                        vkCodes[myCount] = VirtualKey.CONTROL;
                        break;
                    case "V":
                        vkCodes[myCount] = VirtualKey.V;
                        break;
                    case "SHIFT":
                        vkCodes[myCount] = VirtualKey.SHIFT;
                        break;
                    default:
                        throw new MacroSyntaxError("Virtual Key not in the list!");
                }
            }
        }
        else
        {
            vkCodes = nameValue.Split("+").Select(name =>
            {
                if (!Enum.TryParse<VirtualKey>(nameValue, true, out var vkCode))
                    throw new MacroCommandError("Invalid virtual key");

                return vkCode;
            })
            .ToArray();
        }

        return new SendCommand(text, vkCodes, waitModifier);
    }```
daemitus commented 1 year ago

when it explodes, pull up /xldebug and see if theres a stacktrace in there with something more specific. I haven't been subbed for a while.

On Thu, Dec 15, 2022 at 7:37 PM WilliamW1979 @.***> wrote:

Sorry, I just got an earful from my student that I messed up her other macro because I messed up the other virtual keys. So I fixed it so her old macros will work now with the new code. This is the finished part:

{
    _ = WaitModifier.TryParse(ref text, out var waitModifier);

    var match = Regex.Match(text);
    if (!match.Success)
        throw new MacroSyntaxError(text);

    var nameValue = ExtractAndUnquote(match, "name");

    int freq = nameValue.Count(f => (f == '+'));
    string[] mySub = nameValue.Split('+');
    var vkCodes = new VirtualKey[mySub.Count()];
    if (freq > 0)
    {

        for (int myCount = 0; myCount < mySub.Count(); myCount++)
        {
            switch (mySub[myCount])
            {
                case "CONTROL":
                    vkCodes[myCount] = VirtualKey.CONTROL;
                    break;
                case "V":
                    vkCodes[myCount] = VirtualKey.V;
                    break;
                case "SHIFT":
                    vkCodes[myCount] = VirtualKey.SHIFT;
                    break;
                default:
                    throw new MacroSyntaxError("Virtual Key not in the list!");
            }
        }
    }
    else
    {
        vkCodes = nameValue.Split("+").Select(name =>
        {
            if (!Enum.TryParse<VirtualKey>(nameValue, true, out var vkCode))
                throw new MacroCommandError("Invalid virtual key");

            return vkCode;
        })
        .ToArray();
    }

    return new SendCommand(text, vkCodes, waitModifier);
}```

— Reply to this email directly, view it on GitHub https://github.com/daemitus/SomethingNeedDoing/issues/108#issuecomment-1353975895, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFMTBBZSNKV3OY547BTVPTWNO2WNANCNFSM6AAAAAATAG4B5Q . You are receiving this because you are subscribed to this thread.Message ID: @.***>

WilliamW1979 commented 1 year ago

That works now for when there isn't a + in there as your code in the else works perfectly for that, and then when there is a +, uses the other code. My advice would be to make an enum or a list of all the virtual keys so you want to utilize so that you can search and verify them. This would clean up the code a lot. Once again sorry for throwing all that data at you as I went but at least I took the time to come up with a working solution for now until you can come out with your own update.

WilliamW1979 commented 1 year ago

Oh, so there is no one that can really update this then. Would you like me to work on an update for you?

daemitus commented 1 year ago
        vkCodes = nameValue.Split("+").Select(name =>
        {
            if (!Enum.TryParse<VirtualKey>(nameValue, true, out var vkCode))

It should be parsing name not nameValue. NameValue is the original unsplit string. name is each split portion.

On Thu, Dec 15, 2022 at 7:40 PM WilliamW1979 @.***> wrote:

That works now for when there isn't a + in there as your code in the else works perfectly for that, and then when there is a +, uses the other code. My advice would be to make an enum or a list of all the virtual keys so you want to utilize so that you can search and verify them. This would clean up the code a lot. Once again sorry for throwing all that data at you as I went but at least I took the time to come up with a working solution for now until you can come out with your own update.

— Reply to this email directly, view it on GitHub https://github.com/daemitus/SomethingNeedDoing/issues/108#issuecomment-1353988092, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFMTBD7FSSCAZIVWNZDGDDWNO3ANANCNFSM6AAAAAATAG4B5Q . You are receiving this because you commented.Message ID: @.***>

daemitus commented 1 year ago

I'd love a PR if you're up for it. Once its working, just bump the version in the csproj file and if the CI hasn't broke, it should take care of everything else :D

Otherwise I can go download Dalamud again and recompile manually.

On Thu, Dec 15, 2022 at 7:41 PM WilliamW1979 @.***> wrote:

Oh, so there is no one that can really update this then. Would you like me to work on an update for you?

— Reply to this email directly, view it on GitHub https://github.com/daemitus/SomethingNeedDoing/issues/108#issuecomment-1353994921, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFMTBBSYY24DEMZOR55PG3WNO3FHANCNFSM6AAAAAATAG4B5Q . You are receiving this because you commented.Message ID: @.***>

WilliamW1979 commented 1 year ago

You were right, I changed what you suggested and your code worked. You will want to change the nameValue in the Enum to name. So have it look like this:

var vkCodes = nameValue.Split("+").Select(name =>
        {
            if (!Enum.TryParse<VirtualKey>(name, true, out var vkCode))
                throw new MacroCommandError("Invalid virtual key");

            return vkCode;
        })
           .ToArray();

And that will fix all the errors and have it access all the Virtual keys.

WilliamW1979 commented 1 year ago

I don't use github much, I am mostly of an old school programmer (trained in 1998 by the US Air Force). So I don't use Github much. I created a fork, put the updates in. Also did it to your site. How do I send the binaries up to you?

daemitus commented 1 year ago

If you hit the pull request tab up top on GitHub and make a new one, it should let you target your fork

On Thu, Dec 15, 2022, 8:38 PM WilliamW1979 @.***> wrote:

I don't use github much, I am most of an old school programmer. So I created a fork, put the updates in. Also did it to your site. How do I send the binaries up to you?

— Reply to this email directly, view it on GitHub https://github.com/daemitus/SomethingNeedDoing/issues/108#issuecomment-1354057061, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAFMTBDFNSXIN3Q5F2PI7OLWNPB2PANCNFSM6AAAAAATAG4B5Q . You are receiving this because you commented.Message ID: @.***>

WilliamW1979 commented 1 year ago

Okay done, I think I did it right.