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 ➜ MUSHclient ➜ Plugins ➜ Adapting GMCP Handler to ATCP2 on Geas

Adapting GMCP Handler to ATCP2 on Geas

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


Pages: 1 2  3  

Posted by Chaotzin   (19 posts)  Bio
Date Thu 19 Jul 2018 09:43 AM (UTC)

Amended on Thu 19 Jul 2018 09:48 AM (UTC) by Chaotzin

Message
So just this week the admins over at Geas MUD (geas.de) implemented an upgrade that will provide players with ATCP2 data that can enable some really sweet mapping to happen.

It's exciting stuff and I'm keen to try my hand at adapting the MUSHclient mapping capability for Geas.
There's just one issue; I'm struggling to get the handler plugin to function correctly (or to understand whether it is working correctly) and, while I'm comfortable with basic lua scripts now, I feel a bit out of my depth with this one. I've had a crack at it before coming to the forums here but haven't gotten very far.

Firstly, Geas describes this in terms of ATCP2 rather than GMCP. To be honest, I don't understand the implications of that difference except that I've been told they're basically the same thing.

Assuming that they are the same (and I'm very unsure of that assumption), I've been trying to understand how a GMCP handler plugin would work on the MUD.

Here are the steps I've taken so far:
I'm currently watching Trace and Debug Packets while I connect to the MUD and move to a new room.

And I'm using two of Nick's plugins listed on this GMCP thread https://www.gammon.com.au/gmcp
1. GMCP_handler_NJG
2. GMCP_message_receiver_test

How I'm interpretting things is that there's some initial TelnetSubnegotiation going on at connection time but then it ceases when the client doesn't return a sufficient response to the server. Here's the connection sequence I've monitored...

On connecting to the MUD:
Quote:

TRACE: Executing Plugin GMCP_handler_NJG script "OnPluginTelnetRequest"
TRACE: Executing Plugin GMCP_handler_NJG script "OnPluginTelnetRequest"
Enabling GMCP.



Client then sends from GMCP_handler_NJC:

Send_GMCP_Packet (string.format ('Core.Hello { "client": "MUSHclient", "version": "%s" }', Version()))
Send_GMCP_Packet ('Core.Supports.Set [ "Char 1", "Comm 1", "Room 1" ]')


Server then sends (Debug Packets):
Quote:

APS ["AP","LI","CV"]



Client receives and handler broadcasts to all plugins:
Quote:

TRACE: Executing Plugin GMCP_handler_NJG script "OnPluginTelnetSubnegotiation"
APS ["AP","LI","CV"]


GMCP_message_receiver_test plugin receives broadcast:
Quote:

TRACE: Executing Plugin GMCP_message_receiver_test script "OnPluginBroadcast"


Debugging from GMCP_message_receiver_test plugin echoes the message in the world window:
Quote:

GMCP: APS


But there's no handler table set up for that message in the test plugin:
Quote:

Warning: No handler for: APS


Now, by comparison, here is what guidance Geas provides in their ATCP2 helpfile:

Quote:

Telnet Protocol Codes:
Name Code
IAC 255
DO 253 DONT 254
WILL 251 WONT 252
SB 250 SE 240
ATCP2 201

ATCP2 packages:

CORE 065 080 # 'AP'
LOCATION 076 073 # 'LI' info about the characters surrounding
VITALS 067 086 # 'CV' info about the characters vitals

Server-tags:
SUPPORTS 083 032 # 'S ' Server send a list of supported features
DATA 068 032 # 'D ' Server sends data

Client-tags:
BEGIN 066 # 'B' Server should send data then changes detected
END 069 # 'E' Server should stop send data
REQUEST 082 # 'R' Server should send actual data

LOCATION-package DATA

"exits" -> mapping of exits with exit type
"hash" -> hash-id of the room (if avaibale)
"links" -> hash-id of linked rooms (if avaibale)
"inside" -> send by inside rooms
"short" -> short desc of the room (if not normal)
"temperature" -> temperature in the room
"type" -> type of the room

exit-types:
undefined -1
room-type 1-13
road 100
door 101 (closed -101)
TRACE: Matched trigger "\b(manhole|door|gate)\b"
hall 102
yard 103
path 104

room types:
water 1
under water 2
air 3
desert 4
arctic 5
mountain 6
meadow 7
forest 8
beach 9
swamp 10
town 11
jungle 12
cave 13

temperature-level
very cold -2
cold -1
hot 1
very hot 2

VITALS-package DATA:

"fatigue" -> 1-20 fatigue level see 'help fatigue'
"health" -> 1-11 health level, see ' help hitpoints'
"intox" -> 1-10 intoxicated level
"mana" -> 1-11 mana level, see 'help mana'
"soaked" -> 1-6 soaked level
"stamina" -> 1-9 stamina level, seel help 'stamina'
"stuffed" -> 1-10 stuffed level


EXAMPLE
Server IAC WILL ATCP
Client IAC DO ATCP2
Server IAC SB ATCP2 CORE SUPPORTS [CORE,LOCATION,VITALS] IAC SE
Client IAC SB ATCP2 LOCATION REQUEST IAC SE
Server IAC SB ATCP2 LOCATION DATA"{"exits":{"north":8,
"northeast":8,"northwest":100,"south":100,"west":8},
"hash":"1A8549F81F6C","links":{"north":"F48B49A87E40",
"northeast":"6AEF4FA8EBE3","northwest":"838C44A84ED6",
"south":"060949403E41","west":"710E44F00ED7"},
"short":"The entrance to a light forest","temperature":-1,
"type":8} IAC SE


If I'm reading this right, the message currently being received:

APS ["AP","LI","CV"]

is actually this:

Server IAC SB ATCP2 CORE SUPPORTS [CORE,LOCATION,VITALS] IAC SE

However, it's not decoded.

So, where is it all going wrong? Are there some changes need to GMCP_handler_NJG to be compatible with the ATCP2 info set out by Geas?

Very appreciative of any insight.
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #1 on Sat 21 Jul 2018 02:07 AM (UTC)

Amended on Sat 21 Jul 2018 02:10 AM (UTC) by Nick Gammon

Message
Their documentation is rather unclear. I can answer your question about APS. If you add this to the commands table in GMCP_message_receiver_test.xml:


  ["aps"] = gotAPS,


And above it put a function to handle that:


function gotAPS (what)
  tprint (what)
end -- gotAPS


Then you see in the output window:


GMCP: APS
1="AP"
2="LI"
3="CV"


So that has handled the APS message from the server.

However it isn't clear from the help how to get something like location data.

The help seems to suggest doing this:


Server IAC SB ATCP2 CORE SUPPORTS [CORE,LOCATION,VITALS] IAC SE
Client IAC SB ATCP2 LOCATION REQUEST IAC SE
Server IAC SB ATCP2 LOCATION DATA"{"exits":{"north":8,


But is "LOCATION REQUEST" the characters "LI"?

I tried this but nothing happened:


CallPlugin ( "74f8c420df7d59ad5aa66246", "Send_GMCP_Packet" , "LI")


Maybe the request has to be in JSON mode, but the example above doesn't really clarify what that would be.

Maybe you can contact the developer and ask what the format is to trigger room information.

- Nick Gammon

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

Posted by Chaotzin   (19 posts)  Bio
Date Reply #2 on Sat 21 Jul 2018 05:26 AM (UTC)

Amended on Sat 21 Jul 2018 07:47 AM (UTC) by Chaotzin

Message
Thanks Nick.

I've just tried a few combinations of Send_GMCP_Packet and from how I'm understanding it:


AP = CORE
LI = LOCATION
CV = VITALS
S = SUPPORTS
D = DATA
B = BEGIN
E = END
R = REQUEST


So APS = CORE SUPPORTS

Following that logic:


CallPlugin ( "74f8c420df7d59ad5aa66246", "Send_GMCP_Packet" , "LIR")


Results in LOCATION REQUEST and the server returns LOCATION DATA:
Quote:

TRACE: Executing Plugin GMCP_handler_NJG script "OnPluginTelnetSubnegotiation"
LID {"exits":{"east":101},"hash":"F52A6420E4E2","inside":1,"links":{"east":"62F863203D6A"},"short":"In a keep"}
TRACE: Executing Plugin GMCP_message_receiver_test script "OnPluginBroadcast"
GMCP: LID
Warning: No handler for: LID


EDIT:
I've gone ahead and created handlers in table for LID and CVD. LID contains everything I want to use in the mapper. Just trying to understand now how to tell the server to send LID when that data changes. At the moment I can only get it to supply the data when I manually requested it via Send_GMCP_Packet.
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #3 on Sat 21 Jul 2018 07:42 AM (UTC)

Amended on Sat 21 Jul 2018 07:45 AM (UTC) by Nick Gammon

Message
Oh, wow! I think you've cracked it. Therefore LIB is "begin sending data when it changes".

So, add a handler for LID to the table in the example plugin:


 -- for geas

  ["aps"] = gotAPS,
  ["lid"] = gotLID,



And a handler:


function gotLID (what)
  tprint (what)
end -- gotLID


Now when I send:


CallPlugin ( "74f8c420df7d59ad5aa66246", "Send_GMCP_Packet" , 'LIR')


I get:


LID {"exits":{"south":101,"up":201},"hash":"68E44AA06B9E","inside":1,"links":{"south":"06164A0B1248","up":"F1ED4AA03A24"},"short":"The 'Golden Dragon Inn'"}
GMCP: LID
"hash"="68E44AA06B9E"
"exits":
  "up"=201
  "south"=101
"short"="The 'Golden Dragon Inn'"
"links":
  "up"="F1ED4AA03A24"
  "south"="06164A0B1248"
"inside"=1


The bottom part is a table returned by the LID call, which means you can now find the room hash.

For example, change the handler to:


function gotLID (LID)
  print ("Room is now", LID.hash)
end -- gotLID


Ask for the room information and you see printed:


Room is now B3464F0B4BAA


This means you can now catch the message broadcasts in other plugins, and using a similar technique find out the room hash.

It doesn't seem to automatically tell you when the room changes, but detecting a room change should be simple enough, then you just ask for the room information.

- Nick Gammon

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

Posted by Chaotzin   (19 posts)  Bio
Date Reply #4 on Sat 21 Jul 2018 07:51 AM (UTC)
Message
Ah, things are becoming slightly clearer now.

The following seems to enable the automatic updating on info (both just done manually by me):

Just sending DO first:

CallPlugin ( "74f8c420df7d59ad5aa66246", "Send_GMCP_Packet" , 'DO')


Followed by LOCATION BEGIN:

CallPlugin ( "74f8c420df7d59ad5aa66246", "Send_GMCP_Packet" , 'LIB')


And VITALS BEGIN:

CallPlugin ( "74f8c420df7d59ad5aa66246", "Send_GMCP_Packet" , 'CVB')


Now, where to place these in the plugin to have it complete this sequence upon connection...
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #5 on Sat 21 Jul 2018 07:56 AM (UTC)
Message
I think the developer at Geas has misunderstood the GMCP spec a bit. If you advertise that you support "LI" then the "LI" message should work. Thus "LI" "data" should really be "LI.D".

Alternatively (since the "supports" message is only sent once) make it explicit:


Core.Supports ["Core", "Core.Supports", "LI.D", "LI.R", 
               "CV.D", "CV.R"]


Making up a new message "APS" seems a bit strange, because the "core" message should be "Core.Supports" so that a client can find out which messages actually work.

Unfortunately the project to standardize all this disintegrated before all this could be finalized properly.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #6 on Sat 21 Jul 2018 07:59 AM (UTC)
Message
Really, now you should move the "test" plugin stuff into your mapper plugin. Maybe at startup time it tells the server to send the messages, and then processes the room information when you change rooms.

"Broadcast" messages go to all plugins. You don't have to try to squeeze the mapper functionality into the "GMCP test" plugin.

- Nick Gammon

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

Posted by Chaotzin   (19 posts)  Bio
Date Reply #7 on Sun 22 Jul 2018 12:47 AM (UTC)
Message
Thanks for your help Nick. I'm looking ahead at what the mapper plugin will need and I may have a few more kinks to work out there... such as, how to draw the 26 possible directions Geas' rooms support (all laterals like n, ne, e plus their up/down variants like u, nu, neu)

I've noticed something odd about this port now though.

GMCP is only enabled for Geas.de on port 3334. When connecting on that port I am finding that stacked commands (whether from world aliases, plugins or typed into the immediate command line) are not being properly 'interpreted' beyond the second command in a stack.

For example, an alias to send:

say one
say two
say three
say four
say five


Results in:
Quote:

You say in Common: one
You say in Common: two
say three
say four
say five


Three to five are not command echoes. They're mud output, complete with colour bleeding, of the commands I just sent.

Very odd! Looks specific to port 3334 and occurs with or without any GMCP plugins firing behind the scenes. Is this likely to be a MUD dev/server issue or something to do with playing on a port with GMCP?
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #8 on Sun 22 Jul 2018 03:15 AM (UTC)
Message
Looking at the packet debug, there doesn't seem to be any misbehaviour on the client side:



Sent  packet: 8 (9 bytes) at Sunday, July 22, 2018, 2:10:03 PM

say one..          73 61 79 20 6f 6e 65 0d 0a

Sent  packet: 9 (9 bytes) at Sunday, July 22, 2018, 2:10:03 PM

say two..          73 61 79 20 74 77 6f 0d 0a

Sent  packet: 10 (11 bytes) at Sunday, July 22, 2018, 2:10:03 PM

say three..        73 61 79 20 74 68 72 65 65 0d 0a

Sent  packet: 11 (10 bytes) at Sunday, July 22, 2018, 2:10:03 PM

say four..         73 61 79 20 66 6f 75 72 0d 0a

Sent  packet: 12 (10 bytes) at Sunday, July 22, 2018, 2:10:03 PM

say five..         73 61 79 20 66 69 76 65 0d 0a

Incoming packet: 8 (28 bytes) at Sunday, July 22, 2018, 2:10:03 PM

You say in Commo   59 6f 75 20 73 61 79 20 69 6e 20 43 6f 6d 6d 6f
n: one.[0m.>       6e 3a 20 6f 6e 65 1b 5b 30 6d 0a 3e

Incoming packet: 9 (59 bytes) at Sunday, July 22, 2018, 2:10:04 PM

You say in Commo   59 6f 75 20 73 61 79 20 69 6e 20 43 6f 6d 6d 6f
n: two..say thre   6e 3a 20 74 77 6f 0d 0a 73 61 79 20 74 68 72 65
e..say four..say   65 0d 0a 73 61 79 20 66 6f 75 72 0d 0a 73 61 79
 five.[0m.>        20 66 69 76 65 1b 5b 30 6d 0a 3e


It looks like the server has taken the second packet (say two) and then treated the other three as part of it. This looks like a server bug to me.

To be honest, if they have just started implementing this, they are probably ironing bugs out of it. I suggest making a bug report to the admins.

You might also suggest that they implement some message type that notifies you when you have changed rooms. Then you can query what the new room number is. When I was testing it didn't seem to do that, unless I had never visited the room before, which was only partly helpful.

- Nick Gammon

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

Posted by Chaotzin   (19 posts)  Bio
Date Reply #9 on Sun 22 Jul 2018 10:07 AM (UTC)
Message
I've just sent them a report on that one. Currently getting around it by throttling all commands down to 0.4seconds. Automatic supply of LOCATION DATA is now working on movement now too.

But in other matters, I'm having a harder time than I expected adapting a mapper plugin to this.

The two examples I'm working with are the GMCP_Mapper configured for IRE muds: https://github.com/nickgammon/plugins/blob/master/GMCP_Mapper.xml

...and the Aardwolf GMCP mapper.

I'm finding the Aardwolf plugin in particular very hard to follow and probably far more complicated than I'm cut out for.

But I'm also having a hard to finding which content in the IRE GMCP_Mapper I can use (eg drawing rooms, saving room info to database) and what I need to configure myself for the Geas GMCP info (eg handlers).

The functionality of these two plugins in action is fantastic though so I'd love to be able to preserve as much of that as possible.

I was hoping it'd be as simple as renaming the handlers around the OnPluginBroadcast function, but I'm not getting very far with that approach.

So, should I be attempting to work from an example like these two plugins or would it actually be easier to start with something almost blank?
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #10 on Mon 23 Jul 2018 12:05 AM (UTC)
Message
The names of the handlers doesn't really matter. Each handler just handles a high-level ATCP message (eg. "LID") and you can call a function of whatever name you want, which takes a table argument.

The table will be the JSON message sent, converted into a Lua table.

Quote:

So, should I be attempting to work from an example like these two plugins or would it actually be easier to start with something almost blank?


It depends a bit on your objectives. I think starting minimalist and understanding everything is better in the long run:

http://gammon.com.au/forum/?id=12635


However the existing mappers already handle a lot of stuff for you like storing rooms in a database.

The trouble is, the existing mappers (especially the Aardwolf one) are quite sophisticated, and if something goes wrong (because of your changes) you might take a while to work out how to fix it.

Really, though, something like the GMCP mapper should be possible to get working with minimal effort, because the only major difference is the interface to the ATCP stuff, which might be quite a small change.

- Nick Gammon

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

Posted by Chaotzin   (19 posts)  Bio
Date Reply #11 on Mon 23 Jul 2018 10:53 AM (UTC)

Amended on Mon 23 Jul 2018 10:56 AM (UTC) by Chaotzin

Message
Ah that's the article I had seen before but couldn't find. Thanks for that link and for your patience, Nick. I know the forums are flooded with questions about the mapper so I'll try to ask only what I can't find through searching.

I've persisted with working through the GMCP_Mapper plugin and there are now two sections that I'm not certain I'm understanding.

Part of what I'm doing is substituting parts of the GotRoomInfo function to match what LID provides. But I'm confused by the inclusion of the following:

function gotRoomInfo (info)
  
  if info.num then
    got_room_number (info.num)
  end -- if

  if info.name then
    got_room_name (info.name)
  end -- if
  
  if info.exits then
    local t = {}
    for k, v in pairs (info.exits) do
      table.insert (t, k .. "(" .. v .. ")")
    end -- for
    
    got_room_full_exits (table.concat (t, ","))
  end -- if
  
  if info.environment then
    got_environment (info.environment)
  end -- if
  
  if info.coords then
    got_coordinates (info.coords)
  end -- if
  
  if info.details then
    got_info (table.concat (info.details, ","))
  end -- if
  
  if info.area then
    areas [current_area] = info.area:sub (1, 1):upper () .. info.area:sub (2)
  end -- if 
  
end  -- gotRoomInfo


For the bolded if statement I've substituted info.exits with LID.links, and have done similar for the other relevant info such as LID.hash for info.num. But what is the relevance of having a got_room_full_exits function in addition to a got_room_exit function elsewhere in the code? I can't really see what the latter does.

The second issue is I think what is preventing the mapper from actually drawing a room, and that is the fact that Geas room hashes come as a string of numbers and letters (eg, A1AB6FF0E88E), and the plugin currently requires the hash as a number:

-- here when location changes, eg. : Room.Num 7476
function got_room_number (s)
  
  local room_number = tonumber (s)
    
  if not room_number then
    return
  end -- no room number

  current_room = room_number
  mapper.draw (tostring (room_number))
  
  if expected_exit == "0" and from_room then
    fix_up_exit ()
  end -- exit was wrong

end -- got_room_number


At the moment it's not getting a number so the action stops there, no rooms drawn. Removing 'tonumber' and leaving as it comes results in several errors. Is there something about it being in number format that is critical and I'm just missing it?
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #12 on Tue 24 Jul 2018 04:34 AM (UTC)
Message
I think in that case the vnums (room numbers) really were numbers and there were times when it was comparing a string (eg. "12345") to a number (eg. 12345) which would not compare equal, thus doing a tonumber makes sure that they are. In your case as hashes are strings, just don't do a "tonumber" on them).

As for the exits, that MUD sent two messages, "room info" which included exits, and just the exits, so to save duplicating the code, the room info message turned the exits into a message that looked like it had got the exits message.

- Nick Gammon

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

Posted by Chaotzin   (19 posts)  Bio
Date Reply #13 on Sun 29 Jul 2018 04:27 AM (UTC)
Message
Progress update, I've successfully gotten the mapper up and going and it's super nice. :) :) :)

Had to go through with a very keen eye to change a few key little things that were causing errors - and learned a ton in the process.

Here's a little error I'm coming across now though and I believe it relates to how exit "touid"s are being saved to or loaded the database.

Occasionally, along a path I'll see that a room has mapped a 'break' in the path surround a single room. All rooms surrounding it will identify a one-way exit to that room but no path back from it.

When I enter the mystery room it maps one-way exits to all its surrounding rooms.

The cause is the room uid hash:

"060949403E41"

I've told the plugin to treat these hashes as strings rather than numbers, and it's working fine for most, except in this case where the hash begins with a "0".

Interestingly, it's correctly recording the room uid when I stand in it, but not when reading the exit data. Exit data instead reads it as:

"6.0949403e+48"

For a temp fix I can change the exits like so:

Quote:
Modified exit Southeast --> 6.0949403e+48 from room 710E44F00ED7 to be to room 060949403E41 in database.


And it stays corrected while that room is cached. But as soon as I reload things from the database it's back to being "6.0949403e+48"

Now, I'm not sure what the underlying issue is here as I've got it reading it as a string. Is there any obvious reason why it'd be doing this?

I can paste some relevant chunks of the code if needed.

Cheers
C
Top

Posted by Nick Gammon   Australia  (23,173 posts)  Bio   Forum Administrator
Date Reply #14 on Sun 29 Jul 2018 05:20 AM (UTC)

Amended on Sun 29 Jul 2018 05:22 AM (UTC) by Nick Gammon

Message
It looks like the database loading is the issue. Please post the code which loads the exits from the database and puts them into a table.

Or, possibly, the way it is saving to the database.

- 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.


109,047 views.

This is page 1, subject is 3 pages long: 1 2  3  [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.