09 Apr, 2010, Kaz wrote in the 21st comment:
Votes: 0
KaVir said:
Scandum said:
1. Two way MSDP communication negotiation is now clearly defined, with additional restrictions that should prevent infinite telnet loops.

Server: IAC WILL MSDP
Client: IAC DO MSDP
Server: IAC DO MSDP
Client: IAC WILL MSDP

That really doesn't look right to me.


Indeed, it seems almost certainly wrong in an asymmetrical protocol. A transmitted WILL X says "I am willing to perform the server-side part of option X, and wish you to perform the client-side portion." A transmitted DO X says, "I am willing to perform the client-side part of option X, and I wish you to perform the server-side portion."

You can look at NAWS for inspiration for this (although it's probably a bad example, because in the cases we're interested in, the NAWS server is the mud client and vice versa). If NAWS were to follow the pattern described above, then both the mud server and mud client would be sending information about their screen sizes to each other.
09 Apr, 2010, Scandum wrote in the 22nd comment:
Votes: 0
KaVir said:
Scandum said:
Probably best to stick with a simple Server: IAC WILL MSDP, Client: IAC DO MSDP, and assume two way communication enabled.

The problem then is that a client which correctly implements the protocol won't work - it'll be waiting for the server to send IAC DO MSDP before it sends any requests of its own.

Hrm, some miscommunication I think.

What I wonder about is if the current unusual approach is worth the confusion? MSDP can simply use the same negotiation as MSSP and state in the spec that after server: WILL MSDP, client: DO MSDP, two way communication is fully enabled.
09 Apr, 2010, Scandum wrote in the 23rd comment:
Votes: 0
Kaz said:
Indeed, it seems almost certainly wrong in an asymmetrical protocol. A transmitted WILL X says "I am willing to perform the server-side part of option X, and wish you to perform the client-side portion." A transmitted DO X says, "I am willing to perform the client-side part of option X, and I wish you to perform the server-side portion."

That's not how the MSDP specification specifies it however. It's very simple: the server states whether it sends and receives sub negotiations, and the client in turn does the same, no confirmations, TCP guarantees the data arrives correctly pretty much 100% of the time.

This however isn't how telnet options are traditionally dealt with, so I'm most likely going to do drop that and do things the traditional way, as I probably wouldn't hear the end of it if I don't, and other implementations will likely do whatever, which would probably be a random mix between a state exchange and a handshake.

Regarding MSSP and protocols, MSSP doesn't allow for the client to communicate back which protocols it supports. But I guess MSSP could be used to find out what protocols a server supports, and MSDP to request said support to be enabled if the client wants to use it. Would: ENABLE PROTOCOL <array of protocol names>, and DISABLE PROTOCOL <array of protocol names> be a good way to go about it?
10 Apr, 2010, KaVir wrote in the 24th comment:
Votes: 0
Scandum said:
MSDP can simply use the same negotiation as MSSP and state in the spec that after server: WILL MSDP, client: DO MSDP, two way communication is fully enabled.

This is what I do at the moment, but I don't mind changing it. I'd rather wait until the spec is more finalised first though, as one of my players is trying to use it, and I don't want to keep messing up his script.

The same player also requested an PROMPT command that would parse the value as if it were a regular prompt and return the result. Not sure if it's worth adding to the standard, but it seems like a nice easy option, as most players are fairly familiar with the prompt options for their particular mud.

I'm not convinced about the PROTOCOL option, but it would be pretty simple to add. If the client wishes to enable certain protocols then I think that should be done through regular negotiation - in fact it's likely that the server will already have negotiated everything else at the same time as MSDP. If you can think of scenarios where that's not the case then perhaps a simple NEGOTIATE query command would be sufficent (returning 1 if the server is willing to accept the client initiating negotiation).
10 Apr, 2010, Scandum wrote in the 25th comment:
Votes: 0
I went ahead and returned the spec to mimic MSSP. After IAC WILL MSDP (server) and IAC DO MSDP (client) both can send MSDP sub-negotiations.

What I think will work best is for the client to send MSDP_VAR "LIST" MSDP_VAL "PROTOCOLS" and the server to send MSDP_VAR "PROTOCOLS" MSDP_VAL "UTF-8" MSDP_VAL "XTERM 256 COLORS". If the client wants to enable any of the given protocols, for example XTERM 256 COLORS it would send: MSDP_VAR "XTERM 256 COLORS" MSDP_VAL "1"

Right now there's no transparent way to negotiate XTERM 256 COLOR support.

Regarding a prompt command, that would be a less steep learning curve, but I predict scripts using REPORT will be easier to extend, require less bandwidth, and work better across MUDs. An interesting thing to note is that TinTin++ interface scripts already parse the prompt, update the status bar(s), and gag the prompt. So for a user who wants to do that MSDP isn't required.
11 Apr, 2010, KaVir wrote in the 26th comment:
Votes: 0
Scandum said:
Regarding a prompt command, that would be a less steep learning curve, but I predict scripts using REPORT will be easier to extend, require less bandwidth, and work better across MUDs.

I agree, but I don't have REPORT in yet. I mostly added it to encourage the player to switch from ZMP to MSDP, as he was using the zmp.prompt command I'd added.

In regard to REPORT, I'm thinking of having it replace the previously REPORTed variables - so if you do:

IAC SB MSDP MSDP_VAR REPORT MSDP_VAL HEALTH IAC SE

Then the server will start reporting whenever your health changes, but if you then do:

IAC SB MSDP MSDP_VAR REPORT MSDP_VAL MANA IAC SE

Then server will report when mana changes, but no longer report health. If you want both you should do:

IAC SB MSDP MSDP_VAR REPORT MSDP_VAL HEALTH MSDP_VAL MANA IAC SE

And to switch it off, you'd just do:

IAC SB MSDP MSDP_VAR REPORT IAC SE

This way the script doesn't have to keep track of which variables are being reported or worry about unreporting them.

Scandum said:
An interesting thing to note is that TinTin++ interface scripts already parse the prompt, update the status bar(s), and gag the prompt. So for a user who wants to do that MSDP isn't required.

Well this doesn't actually retrieve their current prompt - it allows them to parse a line of text as though it were a custom prompt. In theory you could do the same with a sequence of variables, but players already tend to be familiar with the options available for a custom prompt, so I don't see the harm in leaving it in as an option.
11 Apr, 2010, Scandum wrote in the 27th comment:
Votes: 0
KaVir said:
This way the script doesn't have to keep track of which variables are being reported or worry about unreporting them.

Sounds good to me. I'll update the spec with more verbose documentation when I have time.

KaVir said:
Well this doesn't actually retrieve their current prompt - it allows them to parse a line of text as though it were a custom prompt. In theory you could do the same with a sequence of variables, but players already tend to be familiar with the options available for a custom prompt, so I don't see the harm in leaving it in as an option.

I see, normally I get rid of the prompt once I have a tactical interface going. Could be an idea to implement this as a function call and see if a function like concept will work.
12 Apr, 2010, KaVir wrote in the 28th comment:
Votes: 0
Regarding the latest spec, the example you provide states:

server - IAC WILL MSDP
client - IAC DO MSDP
server - IAC SB MSDP MSDP_VAR "COMMANDS" MSDP_VAL "LIST" MSDP_VAL "REPORT" MSDP_VAL "SEND" IAC SE
client - IAC SB MSDP MSDP_VAR "LIST" MSDP_VAL "VARIABLES" IAC SE
server - IAC SB MSDP MSDP_VAR "VARIABLES" MSDP_VAL "HINT" IAC SE
client - IAC SB MSDP MSDP_VAR "SEND" MSDP_VAL "HINT" IAC SE
server - IAC SB MSDP MSDP_VAR "HINT" MSDP_VAL "THE GAME" IAC SE
This seems to imply that the server should offer its COMMANDS as soon as the handshake has been made - but the handshake section only mentions that "Once the server receives IAC DO MSDP both the client and the server can send MSDP sub-negotiations."

Is the above really just one possible example (i.e., the server may choose to send its COMMANDS immediately after the handshake), or should it automatically send the COMMANDS following a handshake, or is there a missing IAC SB MSDP MSDP_VAR "LIST" MSDP_VAL "COMMANDS" IAC SE sequence in the example? As the "LIST" command specifically allows the client to request the "COMMANDS", would I be correct in assuming that the server doesn't need to send them until asked?

Also, if the client sends IAC SB MSDP MSDP_VAR "SEND" MSDP_VAL "HINT" IAC SE and the server doesn't recognise the "HINT" variable, should it return something to indicate failure or should it not return anything at all, or is that up to the server to decide? Right now my mud sends back IAC SB MSDP MSDP_VAR "HINT" MSDP_VAL "UNDEFINED" IAC SE, because I forward the variable on to the character object and just transmits whatever value it returns.
12 Apr, 2010, KaVir wrote in the 29th comment:
Votes: 0
So I've started looking into these standard variables. Some of them I can add okay, others are a bit of a stretch…these are my thoughts so far:

MUD TIME: I guess it's okay to use the game time of the world the player is currently in.

AFFECTS: Presumably this just returns an array of affect names. Is it worth also having a way to view the attributes of a specific affect?

ALIGNMENT: Hard to think of anything for this. Perhaps an array of personality traits?

EXPERIENCE: Primal + Safe Primal? Or an array containing both? The two are combined when training things.
EXPERIENCE TNL: Lowest of "primal to age" and "primal to gain a power" (as you can spend primal on either)? Or perhaps return both?

MAX MOVEMENT: Maximum action points
MOVEMENT: Action points (used to perform combat moves, although not to actually move around)

OPPONENT LEVEL: Opponent's age
OPPONENT STRENGTH: Indicate if the opponent gives primal if you kill them (boolean).

AREA NAME: I'm thinking of doing a recursive check outside of your current location until you've reached the outermost location (which should be a "world") and find the name of the area (if any) at that particular location. Thus if you're in the Realm (the newbie world) inside Glyphstone Village, "AREA NAME" should always return "Glyphstone Village", even if you enter the guardhouse, watchtower, etc.

ROOM NAME: The easiest way would be just to return the name of whatever you're currently inside, so if you're in the guardhouse it would return "the guardhouse". The drawback is that once you step outside it would simply report your location as "the Realm" (i.e., the name of the world itself). I guess it could instead return the AREA NAME if you're inside a world?

What I'll likely do is provide a list of variables on the website somewhere, describing them in detail. I imagine other muds might want to do the same. Would it be worth having an option for returning such a website url?

Maybe something like:

client - IAC SB MSDP MSDP_VAR "LIST" MSDP_VAL "INFO" IAC SE
server - IAC SB MSDP MSDP_VAR "INFO" MSDP_VAL "Some general notes and info about the mud, I can write whatever I like here. Maybe it'll contain some useful links?" IAC SE

P.S.: There's a typo in the spec: "OPPONENT HEATLH"
13 Apr, 2010, Scandum wrote in the 30th comment:
Votes: 0
It's a bit of a chicken and the egg question when it comes to "LIST" and "COMMANDS". The client doesn't know if the server supports the LIST command, and the server doesn't know if the client supports the COMMANDS command. I think it's safe to suggest that both the client and server send "COMMANDS" when connecting, if they support it. If there's no support it should be treated as a variable, and as such it's not a violation of the protocol.

Regarding a request for an unknown variable, I think not responding would be the best approach, as this will leave the variable on the client side in an undefined state, which tt++ can easily detect.

Quote
AFFECTS: Presumably this just returns an array of affect names. Is it worth also having a way to view the attributes of a specific affect?

Possibly. Do you have any suggestions on how to handle this in an easy manner without adding nesting support to the protocol? One way is sending: AFFECTS_NAMES -> ARRAY followed by AFFECTS_DURATION -> ARRAY so the client can color code affects based on their duration.

Quote
ALIGNMENT: Hard to think of anything for this. Perhaps an array of personality traits?

Typically it's Good, Neutral, or Evil. You can always create a custom variable named PERSONALITY.

Quote
EXPERIENCE: Primal + Safe Primal? Or an array containing both? The two are combined when training things.
EXPERIENCE TNL: Lowest of "primal to age" and "primal to gain a power" (as you can spend primal on either)? Or perhaps return both?

I'd use PRIMAL if your system differs substantially from the norm, but if compatibility is your goal you should definitely not return an array and return the best possible match. I'll add MAX EXPERIENCE so a percentage can be returned.

How about having the "SPECIFICATION" variable, which holds an url to the specification?

I'll fix the typo.
13 Apr, 2010, KaVir wrote in the 31st comment:
Votes: 0
Scandum said:
It's a bit of a chicken and the egg question when it comes to "LIST" and "COMMANDS". The client doesn't know if the server supports the LIST command, and the server doesn't know if the client supports the COMMANDS command. I think it's safe to suggest that both the client and server send "COMMANDS" when connecting, if they support it. If there's no support it should be treated as a variable, and as such it's not a violation of the protocol.

Both server and client will presumably be able to handle unrecognised variables, so I can't see it being a problem whichever approach is used. However the spec seems to imply that only the client supports the "COMMANDS" command.

Personally I would prefer it if neither side were required to send anything after the initial handshake. This keeps the spec simple, it means "LIST COMMANDS" isn't redundant, and I suspect most plugins/scripts would just ignore the commands anyway. If a client wishes to retrieve the commands for some reason then a mechanism is already in place for them, and if the server doesn't support it…well, I think they're just as likely not to send "COMMANDS" at all in that case.

Scandum said:
Regarding a request for an unknown variable, I think not responding would be the best approach, as this will leave the variable on the client side in an undefined state, which tt++ can easily detect.

Okay.

Scandum said:
Quote
AFFECTS: Presumably this just returns an array of affect names. Is it worth also having a way to view the attributes of a specific affect?

Possibly. Do you have any suggestions on how to handle this in an easy manner without adding nesting support to the protocol? One way is sending: AFFECTS_NAMES -> ARRAY followed by AFFECTS_DURATION -> ARRAY so the client can color code affects based on their duration.


Two options spring to mind. My mud already allows me to retrieve abilities like this:

IAC SB MSDP MSDP_VAR "SEND" MSDP_VAL "TALENT:SURE FOOTED" IAC SE
IAC SB MSDP MSDP_VAR "SEND" MSDP_VAL "POWER:FERAL SENSES" IAC SE

So in theory I could retrieve affects in the same way:

IAC SB MSDP MSDP_VAR "SEND" MSDP_VAL "AFFECT:INDEX/IDENTIFIER" IAC SE

However I wonder if it might be more appropriate to do it like this:

IAC SB MSDP MSDP_VAR "SEND" MSDP_VAL "AFFECT" MSDP_VAL "INDEX/IDENTIFIER" IAC SE

Note that I support duplicate affects, so I can't really use the affect name as the identifier.

I think it would be nice if the mud returned the affect as a series of variable/value pairs in the same way as MSSP. The problem is we only have MSDP_VAR and MSDP_VAL, and the first would already be used for AFFECT.

Scandum said:
Quote
ALIGNMENT: Hard to think of anything for this. Perhaps an array of personality traits?

Typically it's Good, Neutral, or Evil. You can always create a custom variable named PERSONALITY.

Well the personality traits aren't really very important. I was just trying to think what I could use for the ALIGNMENT variable. Perhaps this one will need to be blank.

Scandum said:
Quote
EXPERIENCE: Primal + Safe Primal? Or an array containing both? The two are combined when training things.
EXPERIENCE TNL: Lowest of "primal to age" and "primal to gain a power" (as you can spend primal on either)? Or perhaps return both?

I'd use PRIMAL if your system differs substantially from the norm, but if compatibility is your goal you should definitely not return an array and return the best possible match. I'll add MAX EXPERIENCE so a percentage can be returned.

Primal is basically exp, with Safe Primal earned from quests (so named because it's safe from being stolen through PK). It makes sense for EXPERIENCE to show the combined total, because Primal and Safe Primal are pooled for the purposes of training stats and powers. There is also a Primal Cap which works much like MAX EXPERIENCE, except that (1) your Primal can exceed your Primal Cap (you just can't earn any more Primal after that point) and (2) Safe Primal doesn't count towards the Primal Cap.

Scandum said:
How about having the "SPECIFICATION" variable, which holds an url to the specification?

Do you mean the MSDP specification itself, or the extensions offered by the specific server? Both could be useful, although I imagine you'd only need the former if the mud didn't supply the latter.
13 Apr, 2010, Scandum wrote in the 32nd comment:
Votes: 0
Guess I can have the example use "LIST".

I'll also look into some form of nesting and how to deal with that with an event interface tomorrow. I feel like I'm re-inventing ZMP, but on the bright side, servers can keep things basic and only provide straight forward high level data.

Regarding the "SPECIFICATION" variable, this would point to the extensions offered by the specific server.
13 Apr, 2010, KaVir wrote in the 33rd comment:
Votes: 0
Scandum said:
I'll also look into some form of nesting and how to deal with that with an event interface tomorrow.

Do you mean for the affects? I'm not sure that it's really necessary, particularly if you want to keep the spec simple. I could easily implement something like:

Client: IAC SB MSDP MSDP_VAR "SEND" MSDP_VAL "AFFECT:1" IAC SE

Server: IAC SB MSDP MSDP_VAR "AFFECT:1" MSDP_VAL "Name" MSDP_VAL "Forcefield" MSDP_VAL "Duration" MSDP_VAL "45 seconds" MSDP_VAL "Bonus:Defence" MSDP_VAL "50" MSDP_VAL "Bonus:Deflection" MSDP_VAL "1" IAC SE

And provide the instructions on my website, which the client could retrieve via the "SPECIFICATION" variable.

I was mostly just wondering whether the idea should be extended. I don't know if anyone would really want to use it, though, but if they did it could easily be implemented within the spec as it stands.

One other thing: I don't want to have a REPORT option for every variable. Is it worth having a separate LIST option for them?
13 Apr, 2010, Scandum wrote in the 34th comment:
Votes: 0
Guess there could be a list of reportable variables. Use "LIST" VAL "REPORTABLE VARIABLES" ? Can't think of a better keyword.

Might be an option to use \t instead of : and \r\n to separate key-value pairs. tt++ should be able to handle that, that'd be MSSP plaintext compatible.
14 Apr, 2010, KaVir wrote in the 35th comment:
Votes: 0
Scandum said:
Guess there could be a list of reportable variables. Use "LIST" VAL "REPORTABLE VARIABLES" ? Can't think of a better keyword.

Could also be REPORTS or REPORTERS. There's also the question of read/write variables - most mud variables can only be read by the client, but I plan to have some (mostly config options) that can also be set by the client.

Scandum said:
Might be an option to use \t instead of : and \r\n to separate key-value pairs. tt++ should be able to handle that, that'd be MSSP plaintext compatible.

That would work too.

I've got REPORT working for a few variables now, and it's pretty nice - looks like it'll really simplify the scripts. I decided to make the server immediately respond to the REPORT with the current values of each reported variable, in the same way as SEND, but after that it only sends an update when a variable changes.

I've also made the whole thing case insensitive.
14 Apr, 2010, Scandum wrote in the 36th comment:
Votes: 0
Might as well settle for "REPORTABLE VARIABLES" and go for something like "CONFIGURABLE VARIABLES" for variables the client can set on the server.
14 Apr, 2010, KaVir wrote in the 37th comment:
Votes: 0
Although my implementation works, I'm still trying to decide the specific rules for negotiation. I want the rules to be crystal clear, as I've seen what happens when protocol specifications are vague or ambiguous, and it's not pretty. I'm currently thinking of doing the following:

  • To establish a handshake, the server may send IAC WILL MSDP at any time, and the client shall respond with IAC DO MSDP, as is already defined in the spec.


  • The server shall not send IAC WILL MSDP if a handshake has already been established.


  • If the client should send IAC DO MSDP of its own volition, and a handshake has not yet been established, then the server shall send IAC WILL MSDP to indicate acceptance of the handshake.


  • If the client sends an MSDP subnegotiation sequence without first establishing a handshake, the server shall assume an implied handshake.


  • If the client sends IAC DONT MSDP at any time then the server shall clear its REPORT variables and immediately stop sending data. Should the client later send an MSDP subnegotiation sequence, the server shall once again assume an implied handshake.


  • A new handshake shall be established every time the client connects or reconnects.


  • If the server resets itself without disconnecting the client (i.e., hotreboot/copyover), then it shall first send IAC WONT MSDP, then reset, and then send IAC WILL MSDP.


  • If the client wishes the server to REPORT variables, it must resend the REPORT command after re-establishing a handshake.
  • 14 Apr, 2010, Scandum wrote in the 38th comment:
    Votes: 0
    I'm not a big fan of client side MSDP disabling and enabling. I'd rather have a PAUSE and RESUME command for the client. While PAUSED the server shouldn't send subnegotiations, though it can disable MSDP.

    I updated the MSDP Spec to cover up till post #36.
    14 Apr, 2010, KaVir wrote in the 39th comment:
    Votes: 0
    Scandum said:
    I'm not a big fan of client side MSDP disabling and enabling.

    Understood, but I'm not suggesting the client should do that - I'm asking what happens if it does. My mud sends IAC WILL MSDP when the player logs on, so the client never needs to initiate negotiation itself.

    But MSDP isn't built in to the client. If someone's script or plugin decides to send IAC DO MSDP the moment they connect then I can either accept it (WILL), reject it (WONT) or ignore it. Likewise, if they explicitly send IAC DONT MSDP, then I really should switch MSDP off.

    Note that none of the points I've mentioned violate the spec, because the spec simply doesn't specify how the server should respond in those situations. It's all well and good to say that the client won't send IAC DO MSDP or IAC DONT MSDP - but I still need to decide how to respond if they do.

    I don't think a client-side PAUSE is necessary, as the client can simply tell the server to REPORT nothing, and as long as it doesn't send the server any more requests the server won't send it anything back.
    15 Apr, 2010, Scandum wrote in the 40th comment:
    Votes: 0
    KaVir said:
    If someone's script or plugin decides to send IAC DO MSDP the moment they connect then I can either accept it (WILL), reject it (WONT) or ignore it. Likewise, if they explicitly send IAC DONT MSDP, then I really should switch MSDP off.

    How about the spec states that the server should abide by client negotiations, but not confirm them, unless the server implements the Q method in RFC 1143.

    KaVir said:
    I don't think a client-side PAUSE is necessary, as the client can simply tell the server to REPORT nothing, and as long as it doesn't send the server any more requests the server won't send it anything back.

    That should do the trick with the current command set.
    20.0/105