Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.

Due to spam on this forum, all posts now need moderator approval.

 Entire forum ➜ MUDs ➜ General ➜ Suggested protocol for server to client "out of band" messages

Suggested protocol for server to client "out of band" messages

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1  2  3  4  5  6 7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #75 on Thu 04 Feb 2010 05:00 AM (UTC)
Message
I think that ATCP is more or less fine with being ignored, but ZMP requires that the 'core' package be implemented. I don't know how well it would work to ignore it. This is another reason why I prefer to modularize the protocol handling: each protocol module can handle its own nuances.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #76 on Thu 04 Feb 2010 05:11 AM (UTC)
Message
Well, I can think of a whole lot of ways this can fail, unfortunately.

Say MUSHclient automagically agrees to the protocol (it just says "yes" regardless).

Then the server sees "I support MCP/ZMP/ATCP" or whatever and sends things down, expecting the client to render them, or show them, or something, and the player wonders why his room descriptions, or battle information don't appear any more.

BTW this wouldn't apply to my suggested changes on page 1, because what I had was purely supplemental, it simply added to what the player saw anyway.

However if the client waits to be "told" by a plugin that it supports (say) ZMP, then we have a few scenarios:


  • The player connects, the server queries, gets told "no", and *then* the player installs the plugin. However the plugin doesn't work because the negotiation is already over.

  • The player installs the plugin first, then connects, and all works OK, until the player removes the plugin. Now the server is committed to sending the extra stuff, but the client now ignores it, as the plugin is gone.

  • The plugin developer keeps re-installing the plugin, causing the plugin to be starting from scratch, but the server thinks it has been there for a while.


How do you solve that now, with the ATCP plugins? Or do they only work properly if you have them installed before connecting?

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #77 on Thu 04 Feb 2010 05:30 AM (UTC)

Amended on Thu 04 Feb 2010 05:33 AM (UTC) by Twisol

Message
Nick Gammon said:
*The player connects, the server queries, gets told "no", and *then* the player installs the plugin. However the plugin doesn't work because the negotiation is already over.

We already deal with this now; it's an inherent feature of the protocols I know of that the query sent by the server is sent on connect. Simply ensure that the protocol plugin is installed beforehand. Out of all the problems ATCP-users have had during troubleshooting, this was not one of them.

Nick Gammon said:
*The player installs the plugin first, then connects, and all works OK, until the player removes the plugin. Now the server is committed to sending the extra stuff, but the client now ignores it, as the plugin is gone.

There's not much you can do about that anyways, unless you mark a plugin as a 'protocol' plugin somehow and prevent users from uninstalling it. My webclient idea would have made protocol plugins entirely separate components in the first place, which I think nicely deals with that, however we don't really have that option here. I don't think it's too much to ask that users not disable the plugin, just like they have to make sure it's enabled before connecting.

Nick Gammon said:
*The plugin developer keeps re-installing the plugin, causing the plugin to be starting from scratch, but the server thinks it has been there for a while.

Ctrl+Shift+K, Ctrl+K: disco/reco. It can be a little annoying, but it's rather difficult to avoid (it's something that affects more than protocols in general), and once you get used to it, it becomes second nature.


Nick Gammon said:
How do you solve that now, with the ATCP plugins? Or do they only work properly if you have them installed before connecting?

Generally speaking, the ATCP-using plugins can generally be developed like any other plugin; the disco/reco trick is only necessary when the changes affect protocol-relevant details. With my newer versions of the ATCP plugins (not yet released, I'm hoping to see PPI through first since they rely on it), the ATCP plugin handles all protocol details, and the other plugins just tell it what they want to listen for. I achieve this by enabling all ATCP packages straight off, and just forwarding the received messages to any listeners. It's safe to do this because ATCP doesn't generally require responses or expect certain behavior: it's largely used as an event-push protocol.

I would imagine that ZMP would require a slightly different approach due to the nature of the packages it exposes. It's likely that a ZMP plugin would itself only implement the core package, and leave other plugins to implement other packages. I suppose it would be something of a "ZMP plugin suite", a set of plugins in a "structured .plugin folder" like I laid out in a topic here recently, with one primary plugin that enables/disables the other plugins on demand on connection. That would allow maximum extensibility in the face of new packages.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #78 on Thu 04 Feb 2010 07:09 AM (UTC)
Message
Okay, I don't look for a few hours and there's another page. Let me go catch up.

Telnet negotiation details:
Yeah, this is a pain. The way I solved it with my mudserver was somewhat easier seeing how there were less issues, but the principle is the same. MUSHclient basically needs to remember the negotiation state for the 255 protocols, and track seperately whether it is supporting it for the outgoing data or the incoming one. The biggest problem is abstracting away the protocol details to a level of 'do I want to play ball on Xxx', so scripters do not need to worry about the precise details of when and where to apply/deny. I call them server_offer() and server_request() I believe, and I've got a client_reply() and client_request() as well since sadly, the telnet protocol is a confusing thing in how it is worded and in my experience, each protocol interprets the side with the initiative slightly differently, so simply waiting isn't always an option, nor is always offering or declining in advance.

I think the cleanest way to solve the problem with different protocols and different plugins 'fighting' over the same protocol at is to have the handlers for (sub)negotiation return a boolean 'exclusive'. False basically means you are just listening and not taking actions, true on the other hand means you are taking actions (sending stuff, changing some system state, etc) that would conflict with other plugins. If two plugins both return true, you know there is an incompatibility inbetween plugins. Of course, it depends on plugin authors playing nice and not returning false no matter what they do.

But I haven't fully thought this through yet, so it needs a lot of refining still.

ATCP details:
Always negotiating anything that is offered is a bad thing. ATCP has a seperate layer of authentication, and I know for a fact that the muds in question like to give a spammy shitstorm if you enable it but don't authenticate properly. Apparently changing the authentication logic is how they filter out outdated clients, which leads to five lines of spam every 10 minutes. (Or something like that, don't recall the precise details.)

Thankfully, ATCP in its current usage is pretty stateless. I basically assume it is off until I receive some data, or until I connect and negotiate it. There is no data to lose since the authentication is really a one-time thing.

Oh, and I have (using Ethereal five years back) seen references to file uploading and downloading facilities, likely for their webbased clients, but I think it would also accept custom settings. Either way, I do expect NULL bytes in there.
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #79 on Thu 04 Feb 2010 08:55 AM (UTC)
Message
Worstje: In regards to ATCP authentication, it's interesting to note that Achaea no longer requires it in general. I attempted to use my plugin on a non-Achaea server and it didn't work, though.

As for the uploads/downloads thing, I do know that IRE's Nexus client uses ATCP to transmit the user's settings back and forth. However, it is base64-encoded. (Hooray for Wireshark)

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #80 on Thu 04 Feb 2010 03:59 PM (UTC)
Message
I don't view it as such a bad thing to require the plugin to be installed prior to connection, and to require that the plugin not be uninstalled during connection (or weird things will happen). It's comparable to expecting hardware to work before you have the driver installed, or keeping the hardware plugged in and somehow removing the driver and expecting the hardware to keep working.

I think somebody (Twisol?) mentioned a flag that you could mark plugins with to prevent them from being uninstalled during connection, and that would address the latter problem above, but frankly I don't think we need even that. I'm willing to tell users of a plugin "hey, you did something dumb, just restart your connection".

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #81 on Thu 04 Feb 2010 07:25 PM (UTC)
Message
David Haley said:
I think somebody (Twisol?) mentioned a flag that you could mark plugins with to prevent them from being uninstalled during connection, and that would address the latter problem above, but frankly I don't think we need even that. I'm willing to tell users of a plugin "hey, you did something dumb, just restart your connection".

The flag was more of a thought experiment than anything, I don't think it would work terribly well anyways.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #82 on Thu 04 Feb 2010 07:59 PM (UTC)
Message
Right then. My current implementation seems OK, it is now being tested. Being a rewrite of subnegotiation, everything that used to use it is now possibly broken. For example: MCCP v1, MCCP v2, IAC GA, IAC EOR, IAC IAC sequences, MXP, CHARSET negotiation, NAWS, Terminal type.

As suggested by Worstje, "unknown" negotiation types are now handled by a plugin callback, eg.


function OnPluginTelnetSubnegotiation (type, data)
  Note ("received negotiation: ", type)
  Note ("Received option string ", utils.tohex (data))
end -- function OnPluginTelnetSubnegotiation


So, for example, ATCP stuff would appear here with type 200 and the data in the "data" variable. Unfortunately ZMP with its zero-terminated strings will need special processing.

I am thinking next of allowing the client to respond to the server IAC DO x message by doing another plugin callback (to save mucking around with packet processing). eg.


function OnPluginTelnetRequest (type, data)
  Note ("received negotiation: ", type)
  Note ("Received option string ", data)

  if type == 200 and data == "WILL" then
    return true
  else
    return false
  end -- if
end -- function OnPluginTelnetRequest


This lets a plugin inform the server that it is interested in subnegotiation packets for that particular type.

This low-level plugin callback basically lets you implement any protocol you like (you could, for example, ignore my earlier suggestions). However it should simplify your ATCP plugins.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #83 on Thu 04 Feb 2010 08:24 PM (UTC)
Message
I'm confused, are we talking about the Lua protocol thingy or something else entirely at this point?

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #84 on Thu 04 Feb 2010 08:30 PM (UTC)

Amended on Thu 04 Feb 2010 08:32 PM (UTC) by Worstje

Message
@Nick:

Awesome. Again pretty much the way I suggested. (The OnPluginTelnetRequest bit, that is.)

What about world functions like GetTelnetOptionInfo(opt, telnet.negotiatedclient) and other bits (or negotiated serverside) of info regarding telnet negotiation a plugin author might want to know without being in a plugin callback itself?

Also... Lua supports \0 bytes, so the only thing you need to do is figure out how to properly send over a 'pascal' style string to the WSH engine, correct?

@David Haley:

The discussion is now on the framework that allows plugin authors to implement any form of telnet protocol themselves. Basically the framework that would make the LNL or ZMP implementable.
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #85 on Thu 04 Feb 2010 08:30 PM (UTC)
Message
In the case of:


IAC SB x <data> IAC SE


You will receive <data> (and x). What you do with it is up to you. This is consistent with my Lua suggestion, as you could process the data through the Lua interpreter. Or not.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #86 on Thu 04 Feb 2010 08:33 PM (UTC)
Message
Oh, and while we are on the topic of the plugin callbacks. Could it be a reasonable thing to request the help page for plugin callbacks to get split up in different pages, with the index having each different plugin callback listed. There is no order to it, and finding a specific callback has been getting progressively more difficult with each added callback in the last few years.
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #87 on Thu 04 Feb 2010 08:48 PM (UTC)
Message
I guess I should have been more precise in my question; a component of my question was: had we "finished" the "LNL" protocol discussion?

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Worstje   Netherlands  (899 posts)  Bio
Date Reply #88 on Thu 04 Feb 2010 08:55 PM (UTC)
Message
I think we discussed as much as we could possibly discuss. Lasher isn't taking part in the discussion, and he'd pretty much be the key part of any implementation.
Top

Posted by Nick Gammon   Australia  (23,165 posts)  Bio   Forum Administrator
Date Reply #89 on Thu 04 Feb 2010 09:36 PM (UTC)
Message
Worstje said:

Also... Lua supports \0 bytes, so the only thing you need to do is figure out how to properly send over a 'pascal' style string to the WSH engine, correct?


Yes, and it doesn't seem to be working. :(

After a bit of tweaking of data types it is successfully passing the string with an imbedded \0 into the Lua engine. However there doesn't seem to be a variant type (correct me if I am wrong anyone) that supports null-terminated strings, and variants are what the WSH engine uses.

I got to the stage of setting the string data type for the parameters to the WSH call, and carefully passed the string *and* the length to it, ending up (using the debugger) here:


const COleVariant& COleVariant::operator=(const CString& strSrc)
{
	USES_CONVERSION;
	// Free up previous VARIANT
	Clear();

	vt = VT_BSTR;
	bstrVal = ::SysAllocString(T2COLE(strSrc));
	if (bstrVal == NULL)
		AfxThrowMemoryException();

	return *this;
}


Now the CString has the correct length inside it. But when creating the BSTR value it uses SysAllocString and the documentation for that says:


Parameter

sz

A zero-terminated string to copy. The sz parameter must be a Unicode string in 32-bit applications, and an ANSI string in 16-bit applications.


So it doesn't look possible. Hey, and this is why you don't use 0x00 as an internal delimiter when defining a protocol. :P

I can work around it, whilst I still have the string with the nulls, break it up myself at the nulls, create a table, and call the callback with that table.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


928,612 views.

This is page 6, subject is 23 pages long:  [Previous page]  1  2  3  4  5  6 7  8  9  10  11  12  13  14  15  16  17  18  19  20  21  22  23  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.