Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add MPI parsing to login screen #674

Merged
merged 7 commits into from
Dec 17, 2022
Merged

Conversation

Loonesbury
Copy link
Contributor

@Loonesbury Loonesbury commented Dec 13, 2022

Kinda sorta responds to #620.

Abusing {&cmd} and {&arg} to store descriptor and hostname feels bad, but you can't define MPI variables from outside of do_parse_mesg and since the only player we have is One (or whoever welcome_mpi_who is) it's the only information we have to work with.

This allows future dbref sysparms that use NOTYPE to work properly.
This switches the previous ad-hoc list read over to the same functions
used for MPI, which reduces code duplication and allows us to be handle
more potential list formats.

It also puts them through a common output mechanism.
This adds MPI parsing to the login screen, for the welcome proplist and
welcome.txt.

New @Tunes:

    do_welcome_parsing: enables this behavior
                        (only works if do_mpi_parsing is true)
    welcome_mpi_who:    effective "me" (defaults to One)
    welcome_mpi_what:   effective "this" (defaults to Room Zero)

MPI variables:

    cmd:    viewer's descriptor
    arg:    viewer's hostname

These are set here because it's the only information we actually have
about the user at this point, so we might as well.
@tanabi
Copy link
Collaborator

tanabi commented Dec 13, 2022

I would say this actually completes #620 because you can always use the muf macro to run a MUF via MPI. I'm not sure there's a benefit to separate MUF support in addition to MPI, so I think when we merge this, we close #620 as complete.

That said, I wanna test some of the weirder MPI prims (like aforementioned muf, delay, and a few other oddballs) to make sure this doesn't have any weird edge cases that could cause problems. Some of these prims might not 'work right' and that is okay, but I want to make sure that a) nothing causes the MUCK to crash and b) as many oddball things are documented and understood as odd as we can.

I'd think most things would work okay, though. I'll find some time tonight or tomorrow to put this through the paces.

@wyld-sw
Copy link
Member

wyld-sw commented Dec 13, 2022

Agreed, this looks very good. I haven't looked at do_parse_mesg in a while, but I'm wondering if its possible (or worth it) to optionally pass in an additional environment so variables could be set, Maybe a corner case though.

@wyld-sw
Copy link
Member

wyld-sw commented Dec 13, 2022

I've seen implementations of this where - on the MUF side - instead of "player", muf prims would use a #define that basically was "player, but OWNER(program) if player isn't valid), The solution proposed here might be more robust.

@tanabi
Copy link
Collaborator

tanabi commented Dec 13, 2022

Agreed, this looks very good. I haven't looked at do_parse_mesg in a while, but I'm wondering if its possible (or worth it) to optionally pass in an additional environment so variables could be set, Maybe a corner case though.

There's potential value in this, because if we make additional versions of parseprop (parseprop_ex I think would fit in with other similar prims) and the other MPI parsing prims, we can allow MUF to pass additional variables to MPI, which could be useful. That said, I'd say that would be a separate issue, I wouldn't tack it on to this PR. I think @Loonesbury 's use of cmd and arg make reasonable sense. I agree it's "janky" but I also think its in line with how MPI does stuff so I have no issue with the existing approach.

So I think test this thoroughly, merge this PR, and then maybe add a new issue to add variable passing to do_parse_mesg and related MUF prims.

@Loonesbury
Copy link
Contributor Author

Loonesbury commented Dec 13, 2022

I would say this actually completes #620 because you can always use the muf macro to run a MUF via MPI. I'm not sure there's a benefit to separate MUF support in addition to MPI, so I think when we merge this, we close #620 as complete.

After some thought, I must begrudgingly agree -- MPI alone is more than adequate for and the only reason you'd want MUF is interactivity, like MOO's $do_login_command(), but you'd basically have to restructure or duplicate the entire READ event system to allow for per-descriptor input and per-player input (unless you get rid of multiple connections and do everything on a per-descriptor basis) and that... does not seem worth the number of practical use cases for an interactive login screen.

@tanabi
Copy link
Collaborator

tanabi commented Dec 15, 2022

Just letting you guys know I haven't forgotten about this -- I had a SURPRSIE! Wednesday demo for something that I wound up basically working all my waking hours to prepare for work :) So I haven't had much free time for this. I probably won't get to testing it until the weekend.

Just letting you guys know because that's outside of my original plan! @wyld-sw if you want to give it a test -- I'm particularly concerned about the MPI muf macro but delay, tell, etc. might also be weird -- and you have the time, then feel free to hit it as well. I see a lot of ways this thing could potentially crash the MUCK server by 'things not being in a state that we assume it's in' kind of problems.

I'm guessing prim_toadplayer used the 'result' temp var in the past, and
when it was removed, this check wasn't updated - so it was just checking
against whatever 'result' was set to by another primitive.
@tanabi
Copy link
Collaborator

tanabi commented Dec 17, 2022

Finally starting to test these, let you guys know how it goes.

@wyld-sw
Copy link
Member

wyld-sw commented Dec 17, 2022

It's been a busy end-of-year, but I can help test this weekend; just let me know what I can do. I'm wondering if there are cases where we need to store the fact that a MUF call came from the login screen and have certain prims act differently (or fail gracefully) if so.

I also wonder if there's need of a {descrtell:{descr},} function for some cases in the future.

@Loonesbury
Copy link
Contributor Author

Loonesbury commented Dec 17, 2022

Bug 1: welcome_mpi_who and welcome_mpi_what don't show up in the @tune list. And yeah, I'm on as One so I should be able to see MLEV_GOD items. I, for instance, can see the hidden SSL parameters like ssl_keyfile_password which are MLEV_GOD restricted items.

This bug is probably not exclusive to these 2 parameters, it's probably a problem with the @tune command, so maybe we fork this off to a separate issue. do_mpi_parsing does show up on the @tune list correctly.

What other tunes aren't showing up? They're appearing fine on my system with minimal.db:

% Connected to (unnamed2).
#$#mcp version: "2.1" to: "2.1"
           ,...                          ,,                   ,,    ,,
         .d' ""                         *MM                 `7MM  `7MM
         dM`                             MM                   MM    MM
        mMMmm`7MM  `7MM  M"""MMV M"""MMV MM,dMMb.   ,6"Yb.    MM    MM
         MM    MM    MM  '  AMV  '  AMV  MM    `Mb 8)   MM    MM    MM
         MM    MM    MM    AMV     AMV   MM     M8  ,pm9MM    MM    MM
         MM    MM    MM   AMV  ,  AMV  , MM.   ,M9 8M   MM    MM    MM
       .JMML.  `Mbod"YML.AMMmmmM AMMmmmM P^YbmdP'  `Moo9^Yo..JMML..JMML.

             `7MMM.     ,MMF'`7MMF'   `7MF' .g8"""bgd `7MMF' `YMM'
               MMMb    dPMM    MM       M .dP'     `M   MM   .M'
               M YM   ,M MM    MM       M dM'       `   MM .d"
               M  Mb  M' MM    MM       M MM            MMMMM.
               M  YM.P'  MM    MM       M MM.           MM  VMA
               M  `YM'   MM    YM.     ,M `Mb.     ,'   MM   `MM.
             .JML. `'  .JMML.   `bmmmmd"'   `"bmmmd'  .JMML.   MMb.


To connect to your character use 'connect <playername> <password>'
To create a new character use 'create <playername> <password>'

'WHO' and 'help' also work in this context.
co one potrzebie
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Room Zero(#0R)
You are in Room Zero. It's very dark here.
@tune *welcome*
(bool) do_welcome_parsing   = no [default]
(str)  file_welcome_screen  = data/welcome.txt [default]
(ref)  welcome_mpi_what     = One(#1PWM3) [default]
(ref)  welcome_mpi_who      = One(#1PWM3) [default]
*done*

@tanabi
Copy link
Collaborator

tanabi commented Dec 17, 2022

Deleting my bug -- that was actually my fault. My restart script was using a hard coded path and not a relative path, so I was picking up an old fbmuck version.

@wyld-sw
Copy link
Member

wyld-sw commented Dec 17, 2022

@Loonesbury beat me to it, though I did also notice that the welcome tunes don't show up in MAN SYSPARM, but that could be a help re-generation issue.

@tanabi
Copy link
Collaborator

tanabi commented Dec 17, 2022

@Loonesbury Is there anything special I need to do to get MPI parsing to work? I have do_welcome_parsing on:

(bool) do_welcome_parsing   = yes

And I just put some basic MPI in my welcome screen but I'm seeing it unparsed:

#$#mcp version: "2.1" to: "2.1"
           ,...                          ,,                   ,,    ,,
         .d' ""                         *MM                 7MM  7MM
         dM                             MM                   MM    MM  
        mMMmm7MM  7MM  M"""MMV M"""MMV MM,dMMb.   ,6"Yb.    MM    MM
         MM    MM    MM  '  AMV  '  AMV  MM    Mb 8)   MM    MM    MM
         MM    MM    MM    AMV     AMV   MM     M8  ,pm9MM    MM    MM
         MM    MM    MM   AMV  ,  AMV  , MM.   ,M9 8M   MM    MM    MM
       .JMML.  Mbod"YML.AMMmmmM AMMmmmM P^YbmdP'  Moo9^Yo..JMML..JMML.
 
             7MMM.     ,MMF'7MMF'   7MF' .g8"""bgd 7MMF' YMM'
               MMMb    dPMM    MM       M .dP'     M   MM   .M'
               M YM   ,M MM    MM       M dM'          MM .d"
               M  Mb  M' MM    MM       M MM            MMMMM.
               M  YM.P'  MM    MM       M MM.           MM  VMA
               M  YM'   MM    YM.     ,M Mb.     ,'   MM   MM.
             .JML. '  .JMML.   bmmmmd"'   "bmmmd'  .JMML.   MMb.
 
 
To connect to your character use 'connect <playername> <password>'
To create a new character use 'create <playername> <password>'
 
'WHO' and 'help' also work in this context.
{name:#1}

@tanabi
Copy link
Collaborator

tanabi commented Dec 17, 2022

Oh interesting. If I put hte MPI at the start of the file, it works:

#$#mcp version: "2.1" to: "2.1"
One
           ,...                          ,,                   ,,    ,,
         .d' ""                         *MM                 7MM  7MM
         dM                             MM                   MM    MM  
        mMMmm7MM  7MM  M"""MMV M"""MMV MM,dMMb.   ,6"Yb.    MM    MM
         MM    MM    MM  '  AMV  '  AMV  MM    Mb 8)   MM    MM    MM
         MM    MM    MM    AMV     AMV   MM     M8  ,pm9MM    MM    MM
         MM    MM    MM   AMV  ,  AMV  , MM.   ,M9 8M   MM    MM    MM
       .JMML.  Mbod"YML.AMMmmmM AMMmmmM P^YbmdP'  Moo9^Yo..JMML..JMML.
 
             7MMM.     ,MMF'7MMF'   7MF' .g8"""bgd 7MMF' YMM'
               MMMb    dPMM    MM       M .dP'     M   MM   .M'
               M YM   ,M MM    MM       M dM'          MM .d"
               M  Mb  M' MM    MM       M MM            MMMMM.
               M  YM.P'  MM    MM       M MM.           MM  VMA
               M  YM'   MM    YM.     ,M Mb.     ,'   MM   MM.
             .JML. '  .JMML.   bmmmmd"'   "bmmmd'  .JMML.   MMb.
 
 
To connect to your character use 'connect <playername> <password>'
To create a new character use 'create <playername> <password>'
 
'WHO' and 'help' also work in this context.
{name:#1}

@tanabi
Copy link
Collaborator

tanabi commented Dec 17, 2022

It works on random lines and not other random lines... for instance:

{name:#1}
           ,...                          ,,                   ,,    ,,
         .d' ""                         *MM                 `7MM  `7MM
         dM`                             MM                   MM    MM  
        mMMmm`7MM  `7MM  M"""MMV M"""MMV MM,dMMb.   ,6"Yb.    MM    MM
         MM    MM    MM  '  AMV  '  AMV  MM    `Mb 8)   MM    MM    MM
         MM    MM    MM    AMV     AMV   MM     M8  ,pm9MM    MM    MM
         MM    MM    MM   AMV  ,  AMV  , MM.   ,M9 8M   MM    MM    MM
       .JMML.  `Mbod"YML.AMMmmmM AMMmmmM P^YbmdP'  `Moo9^Yo..JMML..JMML.
{name:#1}
             `7MMM.     ,MMF'`7MMF'   `7MF' .g8"""bgd `7MMF' `YMM'
               MMMb    dPMM    MM       M .dP'     `M   MM   .M'
               M YM   ,M MM    MM       M dM'       `   MM .d"
               M  Mb  M' MM    MM       M MM            MMMMM.
               M  YM.P'  MM    MM       M MM.           MM  VMA
               M  `YM'   MM    YM.     ,M `Mb.     ,'   MM   `MM.
             .JML. `'  .JMML.   `bmmmmd"'   `"bmmmd'  .JMML.   MMb.
 
{name:#1} 
To connect to your character use 'connect <playername> <password>'
To create a new character use 'create <playername> <password>'
{name:#1}
'WHO' and 'help' also work in this context.
{name:#1}
{name:#1}

results in:

One
           ,...                          ,,                   ,,    ,,
         .d' ""                         *MM                 7MM  7MM
         dM                             MM                   MM    MM  
        mMMmm7MM  7MM  M"""MMV M"""MMV MM,dMMb.   ,6"Yb.    MM    MM
         MM    MM    MM  '  AMV  '  AMV  MM    Mb 8)   MM    MM    MM
         MM    MM    MM    AMV     AMV   MM     M8  ,pm9MM    MM    MM
         MM    MM    MM   AMV  ,  AMV  , MM.   ,M9 8M   MM    MM    MM
       .JMML.  Mbod"YML.AMMmmmM AMMmmmM P^YbmdP'  Moo9^Yo..JMML..JMML.
One
             7MMM.     ,MMF'7MMF'   7MF' .g8"""bgd 7MMF' YMM'
               MMMb    dPMM    MM       M .dP'     M   MM   .M'
               M YM   ,M MM    MM       M dM'          MM .d"
               M  Mb  M' MM    MM       M MM            MMMMM.
               M  YM.P'  MM    MM       M MM.           MM  VMA
               M  YM'   MM    YM.     ,M Mb.     ,'   MM   MM.
             .JML. '  .JMML.   bmmmmd"'   "bmmmd'  .JMML.   MMb.
 
{name:#1} 
To connect to your character use 'connect <playername> <password>'
To create a new character use 'create <playername> <password>'
{name:#1}
'WHO' and 'help' also work in this context.
{name:#1}
{name:#1}

@Loonesbury
Copy link
Contributor Author

Oh interesting. If I put hte MPI at the start of the file, it works:
Looks like the graves in the ASCII art are escaping it?

@tanabi
Copy link
Collaborator

tanabi commented Dec 17, 2022

Oh interesting. If I put hte MPI at the start of the file, it works:
Looks like the graves in the ASCII art are escaping it?

That's it -- I took out the ASCII art and it all came to life.

@tanabi
Copy link
Collaborator

tanabi commented Dec 17, 2022

So some preliminary observations.

If you put invalid MPI in there, you get the default welcome screen and One (or presumably whomever is @tuned) gets the error message. If you put MUF in there, it actually does work, but the tell message goes to One. I just put this MUF in to try it:

: main
  "Hi!" tell
;

However, if you leave something on the stack, it does work, i.e.

: main
  "leave it on the stack"
;

I am starting to suspect it will be unlikely to crash the MUCK with this, but there will probably be a lot of weirdness. I'll stop spamming comments now

@tanabi tanabi closed this Dec 17, 2022
@tanabi tanabi reopened this Dec 17, 2022
@tanabi
Copy link
Collaborator

tanabi commented Dec 17, 2022

And I didn't mean to close it, I just hit enter and apparently github decided that was good enough to close it. :) Anyway, back to more testing, I'll try to be less noisy.

@Loonesbury
Copy link
Contributor Author

Loonesbury commented Dec 17, 2022

Github thinks my shoddy code is flawless! I've fooled them all!

If you put invalid MPI in there, you get the default welcome screen and One (or presumably whomever is @tuned) gets the error message. If you put MUF in there, it actually does work, but the tell message goes to One. I just put this MUF in to try it:

I'm guessing this is because MUF TELLs will go directly to One, since we're pretending One is the triggering player, but {muf} passes the program's return value back to do_parse_mesg and it gets displayed on the login screen. Using DESCRNOTIFY should work fine, though.

I never really thought about using {muf} so I didn't bother coming up with a prettier solution, but I'm open to suggestions.

@wyld-sw
Copy link
Member

wyld-sw commented Dec 17, 2022

Could we have NOTIFY (if parameter is "me", at least) act like DESCRNOTIFY if invoked on the welcome screen? Or at least have a way to opt-in to that behavior?

@Loonesbury
Copy link
Contributor Author

Loonesbury commented Dec 17, 2022

IMO the more appropriate solution would be allowing player = #-1, even if that would require a lot of work on the interpreter -- otherwise you'd have to add a chain of arguments from do_parse_mesg -> interp_loop -> prim_notify, or add a "is welcome screen" global, which feel kinda janky.

@wyld-sw
Copy link
Member

wyld-sw commented Dec 17, 2022

Yeah, that's kind of what Proto did - had a PSafe() macro that was used in the place of "player" - though it changed #-1 to OWNER(program). We would probably need to treat #-1 as descriptor-specific, in at least this case.

@tanabi
Copy link
Collaborator

tanabi commented Dec 17, 2022

I tested most things I thought might break something, and none of them did. From my understanding of the internals, we're unlikely to put the MUCK in a state where it crashes because we are satisfying all the MUCK needs to parse most events. I actually went around and grep'd the code for places where a disembodied descriptor (i.e. a descriptor not associated to a player) could cause a problem, and I believe the way we're passing One in to the MPI parser resolves all the issues I could suss out.

There's a lot of stuff that isn't ideal, but I'm not really worried about that -- I think it's okay for this to be a little jenky at first, as long as it doesn't crash, lock up, or do some other 'massively bad' behavior.

The one 'game breaking' oddity I have found is with MUF 'READ'. It doesn't crash, but it makes the MUF become uneditable:

@edit test.muf
Sorry, this program is currently being edited by someone else.  Try again 
later.

This happened no matter if I logged in / logged out again or whatever, I had to restart the MUCK to clear it. I've never seen that happen before.

It seemed like it was capturing input from both the person on the login screen and One. If the person on the login screen entered something first, One would get this message:

Program Error.  Your program just got the following error.
test.muf(#120), line 2; READ: Program is write-only.
System stack backtrace:
  0) test.muf(#120) line 2, in main(:
  2:   read
*done*

If One entered something first, it seems like it clears up whatever blockage there is, but the output is not sent to the MPI message (which makes sense, because the MPI message is displayed before the READ fires off ... when a MUF goes into a read state, it basically 'context switches' and MPI won't wait for MUF to come back from a context switch).

Putting the MUF in 'background' mode will disable READ and at least for a short MUF will work and whatever's on the stack gets put in the MPI message. However, if a background mode MUF is longer than a certain number of instructions then it will context switch; the MPI won't wait for the context switch and will just output what it's got (which will be an empty string). A hacky fix for this would be to force any MUFs triggered by the welcome screen to be in BACKGROUND mode and it just sucks to be you if your program gets context switched before it displays a message.

People in such a situation can always increase the instr_slice @tune parameter so they're not SOL. I guess that makes it an okay solution maybe?

I feel like leaving 'READ' open will lead to a somewaht annoying bug, as someone could rightfully feel like they could make their own custom login interface by using READ on a welcome-screen MUF. They'll leave their MUCK in a state where it has to be rebooted in order to unblock it which isn't great, but they aren't going to lose data or make a crash which makes it okay-ish. Of course, long term leaving a MUCK in this state, well, I didn't test that. Some wire is crossed in an unholy fashion to make this kind of error, so I'm sure leaving it up for a long time after getting 'stuck' can be problematic.

Off the cuff, I don't know what the best fix for this is. I'm inclined to merge this issue and create a new issue to fix the bug we're introducing with it. I'd be willing to take on that bug as there's a lot of possible ways to fix it and frankly most of the ways are bad, so I feel like that's a 'high end, somebody who really knows the system should take it' grade bug.

@wyld-sw does that sound reasonable to you?

@wyld-sw
Copy link
Member

wyld-sw commented Dec 17, 2022

Definitely sounds reasonable. Thanks for the deep dive into the particulars.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants