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 ➜ how to get ATCP work for Avalon-Mud

how to get ATCP work for Avalon-Mud

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


Posted by Couto   (15 posts)  Bio
Date Wed 22 Feb 2012 07:33 PM (UTC)

Amended on Wed 22 Feb 2012 07:55 PM (UTC) by Couto

Message
Hi guys,

at first i want to thank Nick for this amazing client. I love to use it for years. And now i try to get ATCP working for Avalon-Mud (german :)). Its no problem for me to run triggers/timers/alias and simple scripts, but i cant get ATCP work and maybe you can help me :).

Recently i downloaded Twisols ATCP Plugin (http://www.mushclient.com/forum/bbshowpost.php?id=9395&page=3). And i've modified a standardplugin for healthbars, which comes along with mushclient since few versions, for my needs (http://pastebin.com/ABPFGrBm).

As you can see, i trigger TP (Hitpoints), ZP (Spellpoints), AP (Actionpoints) and Mana from promptline at the moment and i want to get this over ATCP.

Mud sends the following over ATCP:

Numbers are examples :)

Avalon.TP 404
Avalon.SP 96 (SP for ZP)
Avalon.MP 2000
Avalon.AP 130
Avalon.MAX_TP 404
Avalon.MAX_SP 305
Avalon.MAX_AP 130

How can i use this and build it into the healthbar-plugin?


Additionally Avalon provides channels for ATCP. The client can activate this by sending 'set_ava_channel 1'.

Then ATCP will send each message on channels
Avalon.Channel <channel> <text>

How can i catch this and put it into a coollooking extra windows with tabs and scrollbars? :]


Thanking you in anticipation
Couto aka Dragoon@Avalon
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #1 on Wed 22 Feb 2012 08:38 PM (UTC)

Amended on Wed 22 Feb 2012 08:39 PM (UTC) by Twisol

Message
Hi Couto. Glad to see my plugins are still getting some use. :) That version is actually outdated though. In particular, it only supports a certain selection of ATCP messages that the Iron Realms MUDs provide.

I provide a more up-to-date version on my website at <http://jonathan.com/mushclient-achaea-plugins>. This version can receive and transmit any arbitrary ATCP message. Make sure to read the instructions on that page for installation, because the plugins use a directory structure instead of a single-file format.

You can download one of the GMCP-dependent plugins (such as the Gauges plugin) to get an idea of how to access the protocol data. They say GMCP-based, but they include handlers for both GMCP and ATCP, so just look for the one that makes mention of 'atcp' instead. For example, from my Gauges plugin:
local atcp_stats = {H = "hp", M = "mp", E = "ep", W = "wp", NL = "nl"}
PPI.OnLoad("7c08e2961c5e20e5bdbf7fc5", function(atcp)
  atcp.Listen("Char.Vitals", function(message, content)
    for stat, curr, max in string.gmatch(content, "(%w+):(%d+)/(%d+)") do
      gauges.stats[atcp_stats[stat]].curr = curr
      gauges.stats[atcp_stats[stat]].max = max
    end
    
    gauges.draw()
  end)
end)


The PPI.OnLoad() call is what registers your plugin with PPI (which is that communication mechanism I mentioned). When the plugin at the given ID (this one is for the ATCP plugin) is known to be loaded and available, it executes the callback with a special interface object. You can use that to call the other plugin's interface methods, which for ATCP are Send, Listen, and GetContent (which you don't normally need).

As you can see above, atcp.Listen() is being called. This tells the ATCP plugin what message you want to listen for. When that message is received, it will pass your callback the message name and its contents. This is where you would update your gauges display.


Here's a couple links to previous discussions about topics I've mentioned. If you have any questions, let me know!

Directory structure for plugins: http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=10081

Plugin-to-Plugin Interface: http://www.gammon.com.au/forum/bbshowpost.php?bbsubject_id=9970

'Soludra' on Achaea

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

Posted by Couto   (15 posts)  Bio
Date Reply #2 on Wed 22 Feb 2012 09:51 PM (UTC)
Message
Thanks for your fast anwser. I will try this, but it will take some time. Of course i'll ask again for further questions on this topic, if i cant handle it with your advices.
Top

Posted by Couto   (15 posts)  Bio
Date Reply #3 on Fri 24 Feb 2012 08:20 PM (UTC)

Amended on Sat 25 Feb 2012 01:07 AM (UTC) by Couto

Message
I think i got a bit how this works. But i still have few questions.

What exactly does the projekt.kpf in your folders? Do i need them?



I'll write some status reports, maybe u are interested in my proceedings^^.

<old Status>
At the moment i try to communicate over ATCP in the simplest way. But it wont work

What i did for now:

I downloaded your ATCP plugin and installed it.
I downloaded gauges plugin and tried to understand how this structure system works :].

I copied your structure and modified it with a new plugin called test.
I copied your example scripts/main.lua
Normally the mud should send a Room.Brief but it wont work properly. Shouldnt it note the content and the message in my output window each time Room.Brief fires?

I expected something like:
Dies ist ein Raum
Room.Brief


-- Used to load the ATCP interface
PPI = require("ppi")

-- Will contain the ATCP interface
atcp = nil


-- Executed when you get an ATCP message!
OnRoomBrief = function(message, content)
  SetStatus(content .. ".")
  Note(content)
  Note(message)
end

-- Loads the ATCP library
OnPluginListChanged = function()
  local atcp, reloaded = PPI.Load("7c08e2961c5e20e5bdbf7fc5")
  if not atcp then
    Note("ATCP funktioniert nicht!")
  elseif reloaded then
    -- Registers a function to call when Room.Brief is received.
    atcp.Listen("Room.Brief", OnRoomBrief)
  end
end


<old status>
How can i activate the debug function on ATCP.plugin? --> already got it (with atcp debug ^^)
but it doesnt note anything. I think ATCP doesnt work properly and i dont know why.

<latest status>
After some hours of try and error i modified the ATCP.plugin the following way.


OnPluginTelnetRequest = function(type, data)
  Note(type)
  Note(data)
  if type == codes.ATCP then
    -- do not authenticate if we're connected to Vadi's System
    if GetInfo(61) == "127.0.0.1" then
      Note("Vadis System")
      return
    end
    if data == "DO" then
      Note("DO")
      return true
    elseif data == "WILL" then
      Note("WILL")
      return true
    elseif data == "SENT_DO" then
      SendPkt(codes.IAC_SB_ATCP .. hello_msg .. codes.IAC_SE)
      Note("SENT_DO")
      return true
    end
  end
  Note("nothing happened")
  return false
end


I found out that the mud seems to require a additional DO before SENT_DO and now my little plugin works as intented. Now i think i can use this, thanks a lot for your help :).
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #4 on Sat 25 Feb 2012 03:23 AM (UTC)
Message
Couto said:
What exactly does the projekt.kpf in your folders? Do i need them?

It might mention it in the readme file, depending on which plugin you're looking at, but it's a project file for Komodo Edit, the editor I used when writing the plugins. It isn't useful unless you're using Komodo, so feel free to junk it.


Couto said:
I found out that the mud seems to require a additional DO before SENT_DO and now my little plugin works as intented. Now i think i can use this, thanks a lot for your help :).

I don't see any extra DO being sent in that patch. Unless you mean the server is sending a DO, and expecting the client to respond with a WILL, which it really should not be doing at all. I guess if it works, it works... but the server's doing something it shouldn't be. :/

'Soludra' on Achaea

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

Posted by Couto   (15 posts)  Bio
Date Reply #5 on Sat 25 Feb 2012 07:26 AM (UTC)

Amended on Sat 25 Feb 2012 08:03 AM (UTC) by Couto

Message
It seems, the mud always sends on ATCP and it didnt need to toggle on.

OnPluginTelnetRequest = function(type, data)
  Note(data)
  Note(type)
  return true
end

Edit: its not advisable to return always true, i changed that already to only return true if type == codes.ATCP ^^

As notes i get:
DO
200
SENT_WILL
200
and if i idle, i get something like:
DO
6
SENT_WILL
6

Whatever, it's enough to make the following work:

-- Used to load the ATCP interface
PPI = require("ppi")

-- Will contain the ATCP interface
atcp = nil

-- Executed when you get an ATCP message!

OnAvalonTP = function(message, content)
  Note("TP: "..content)
end
OnAvalonSP = function(message, content)
  Note("ZP: "..content)
end
OnAvalonAP = function(message, content)
  Note("AP: "..content)
end
OnAvalonMP = function(message, content)
  Note("Mana: "..content)
end
OnRoomBrief = function(message, content)
  Note(content)
  Note(message)
end


-- Loads the ATCP library
OnPluginListChanged = function()
  local atcp, reloaded = PPI.Load("7c08e2961c5e20e5bdbf7fc5")
  if not atcp then
    Note("ATCP funktioniert nicht!")
  elseif reloaded then
    -- Registers a function to call when Room.Brief is received.
    atcp.Listen("Avalon.TP", OnAvalonTP)
    atcp.Listen("Avalon.SP", OnAvalonSP)
    atcp.Listen("Avalon.AP", OnAvalonAP)
    atcp.Listen("Avalon.MP", OnAvalonMP)
    atcp.Listen("Room.Brief", OnRoomBrief)
  end
end

I get the correct notes for TP, SP, AP and MP, but i dont get a roombrief ._. Yesterday that worked once too, but i didnt remind what i have done different. In my opinion i didnt changed something on the room.brief part.
Top

Posted by Xtian   (53 posts)  Bio
Date Reply #6 on Sat 25 Feb 2012 10:27 AM (UTC)

Amended on Tue 07 Apr 2015 01:40 AM (UTC) by Nick Gammon

Message
Hi Couto, hi Twisol,

Twisol said:

I don't see any extra DO being sent in that patch. Unless you mean the server is sending a DO, and expecting the client to respond with a WILL, which it really should not be doing at all. I guess if it works, it works... but the server's doing something it shouldn't be. :/


Actually, in the standard document:
http://www.ironrealms.com/rapture/manual/files/FeatATCP-txt.html
[EDIT: or also] mudstandards.org/ATCP_Enabling

this is exactly what the server should be doing, no?

What is your plugin doing differently? Is it making the client initiate the hand-shake?

[EDIT] (April 2015) Warning: Domain name mudstandards.org has been abandoned. That site is now an adult products shop.
Top

Posted by Couto   (15 posts)  Bio
Date Reply #7 on Sat 25 Feb 2012 10:37 AM (UTC)

Amended on Sat 25 Feb 2012 10:48 AM (UTC) by Couto

Message
As far as i understand the code of the atcp-plugin as a ordinary person, i think it expects WILL or SENT_DO. After receiving SENT_DO it sends something like the following


IAC SB ATCP hello_msg = "hello " .. client_data .. "\n" ..
                  "auth 1\n" ..
                  "char_name 1\n" ..
                  "char_vitals 1\n" ..
                  "room_brief 1\n" ..
                  "room_exits 1\n" ..
                  "map_display 1\n" ..
                  "composer 1\n" ..
                  "keepalive 1\n" ..
                  "topvote 1\n" ..
                  "ping 1\n"
IAC SE


Maybe SENT_DO instead of DO?
Top

Posted by Couto   (15 posts)  Bio
Date Reply #8 on Sat 25 Feb 2012 03:34 PM (UTC)

Amended on Sat 25 Feb 2012 03:35 PM (UTC) by Couto

Message
Proceeding of my experiments:

After talking to xtian, i used the root ATCP plugin and added just a minor-part.


OnPluginTelnetRequest = function(type, data)
  if type == codes.ATCP then
    -- do not authenticate if we're connected to Vadi's System
    if GetInfo(61) == "127.0.0.1" then
      return
    end

    if data == "DO" then            -- I ADDED THIS LINE
      return true                   -- I ADDED THIS LINE
    elseif data == "WILL" then      -- I CHANGED THIS FROM if to elseif
      return true
    elseif data == "SENT_DO" then
      SendPkt(codes.IAC_SB_ATCP .. hello_msg .. codes.IAC_SE)
      return true
    end
  end

  return false
end


This works fine for now. Also with Room.Brief.
I also adjusted my healthbar-plugin to use ATCP.
(http://pastebin.com/GKyCFW1G)
--> certainly not really good code, but it works :]

Now i'm trying to send something over ATCP.
Twisol, can u give me an example to send something with your ATCP Plugin?

I tried the following in a script, but the Mud anwsered with an error message.


-- Used to load the ATCP interface
PPI = require("ppi")

-- Will contain the ATCP interface
atcp = nil


function OnPluginInstall ()

local atcp, reloaded = PPI.Load("7c08e2961c5e20e5bdbf7fc5")
  if not atcp then
    Note("ATCP funktioniert nicht!")
  elseif reloaded then
--    atcp.Send("ava_set_mapper 1")
    atcp.Send("ava_set_channel 1")
--    atcp.Send("ava_set_comm 1")
--    atcp.Send("ava_set_rcomm 1")

  end
end -- OnPluginInstall

--> as result i got the following from atcp debug:
Avalon.Error SET ERROR UNKNOWN:
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #9 on Sun 26 Feb 2012 01:37 AM (UTC)

Amended on Sun 26 Feb 2012 01:42 AM (UTC) by Twisol

Message
Xtian said:
What is your plugin doing differently? Is it making the client initiate the hand-shake?

Thanks for the link, Xtian. It looks like you're right about the server sending a DO. It's strange though, because the side sending a "WILL" (in this case the client) is the one that's supposed to be providing the protocol. It's pretty clear that the MUD server is actually the one sending the data, and the client is just a recipient, so I expected it to be the reverse.

By the way, it doesn't matter who initiates the handshake. Whether the client sends WILL first, or the server sends DO first, it doesn't matter according to Telnet. Once both sides understand that they both want the option enabled, it should be enabled.

The reason for the odd WILL/DO divide is that some options can be negotiated both ways. For example, MCCP. If the client says DO and the server says WILL, then the server->client stream is compressed. That's been the case 100% of the time in practice. But it's possible for the client to say WILL and the server to say DO, in which case the proper behavior is to compress the client->server stream - in other words, player input.

And that's why this ATCP server-sends-DO client-sends-WILL thing is so strange. Sorry about the confusion, in any event.

(It's interesting to note that I never had an issue with my ATCP plugin, and I haven't changed it in -ages-, so... very strange indeed.)

'Soludra' on Achaea

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

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #10 on Sun 26 Feb 2012 01:42 AM (UTC)

Amended on Sun 26 Feb 2012 01:51 AM (UTC) by Twisol

Message
Couto said:

-- atcp.Send("ava_set_mapper 1")
atcp.Send("ava_set_channel 1")
-- atcp.Send("ava_set_comm 1")
-- atcp.Send("ava_set_rcomm 1")

Are these player commands, or ATCP messages? They don't look like ATCP messages, so you should probably be using MUSHclient's normal Send() function instead. You only use atcp.Send("msg", "content") when you're actually communicating with the server through ATCP.

I'd put in a SENT_WILL clause, by the way. Should do the same as SENT_DO, what with sending a hello message. But I don't know how different Avalon's flavor of ATCP is.

Ah, and just to explain, "SENT_DO" isn't something MUSHclient receives. It's just a way for MUSHclient to allow the plugin to do something after MUSHclient sends a DO. Like when you return true after "WILL", MUSHclient sends a DO, then calls immediately again telling you "SENT_DO".

'Soludra' on Achaea

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

Posted by Couto   (15 posts)  Bio
Date Reply #11 on Sun 26 Feb 2012 02:35 AM (UTC)
Message
I think i have to send "ava_set_channel 1" via ATCP to activate the client to send me chatmessages over atcp.

So i'll try atcp.Send("ava_set_channel","1")

Twisol said:

Ah, and just to explain, "SENT_DO" isn't something MUSHclient receives. It's just a way for MUSHclient to allow the plugin to do something after MUSHclient sends a DO. Like when you return true after "WILL", MUSHclient sends a DO, then calls immediately again telling you "SENT_DO".


Thanks for the explanation. Almost got it^^.
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.


37,966 views.

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.