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 ➜ General ➜ Getting variables from ATCP info?

Getting variables from ATCP info?

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


Pages: 1 2  

Posted by Faedara   (106 posts)  Bio
Date Sun 21 Nov 2010 10:49 AM (UTC)
Message
I'll assume it's possible, since this is scripting and with scripting anything is possible. I want to make an ATCP integrated autosipper, and I want to do as much of it as I can myself, but honestly I've only ever gotten as far as triggers and aliases. This would be my very first script, and in scripts a lot of things are very different, like how I pull variables out of whatever I'm calling using the script.

Hopefully somebody can make sense of this rambling, but if not that's fine too.

The eternally clueless <3
Currently looking for a mentor/tutor to help me learn everything about Lua from the ground up. I can't understand 28*41 until I learn what causes 2+2.
Top

Posted by Nick Gammon   Australia  (23,158 posts)  Bio   Forum Administrator
Date Reply #1 on Sun 21 Nov 2010 07:51 PM (UTC)
Message
To help answer, do you mean variables in general? Or the ATCP variables from the MUD? (which MUD by the way?)

- Nick Gammon

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

Posted by Faedara   (106 posts)  Bio
Date Reply #2 on Sun 21 Nov 2010 11:21 PM (UTC)

Amended on Sun 21 Nov 2010 11:23 PM (UTC) by Faedara

Message
Sorry, it was 5:30 in the morning so my mind was fried.

Basically, I need to get the stats from the ATCP on Achaea and use them as a set of variables for the AutoSipper.

What I've got so far is:

function OnPluginBroadcast (msg, id, name, text)
  if id == "85f72d0e263d75df7bde6f00" then
    if msg == 1 then

    end
  end
end




From what little I do understand this is called a 'hook', but I don't know what that is exactly, and it'll grab the stats from the ATCP message broadcast by the MUD

If I'm anywhere near correct, that means there should be some way to grab this information and put it into variables usable by an AutoSipper. If I can make this AutoSipper then I'll be that much closer to understanding and building healing systems.

The eternally clueless <3
Currently looking for a mentor/tutor to help me learn everything about Lua from the ground up. I can't understand 28*41 until I learn what causes 2+2.
Top

Posted by Nick Gammon   Australia  (23,158 posts)  Bio   Forum Administrator
Date Reply #3 on Mon 22 Nov 2010 12:17 AM (UTC)
Message
Twisol is probably much better in a position to answer this as he plays IRE MUDs and is familiar with ATCP.

My knowledge is a bit out of date, but I'll describe the general idea. You seem to be referring to my ATCP_NJG plugin, described here:

http://www.gammon.com.au/forum/?id=10129


The general idea is that:


  • The MUD chooses to format some stuff (like room info, character stats) into special "hidden" packets, previously called ATCP (Achaea Telnet Control Protocol), but now perhaps GMCP (Generic MUD Control Protocol).

  • They may still support both protocols, based on telnet negotiation done when you connect, I'm not sure.

  • These "hidden" packets (hidden because clients normally don't show telnet subnegotiation packets) are intercepted by a specially designed plugin. The ATCP_NJG plugin is one, I believe there is one for the GMCP packets now.

    If you want a lengthy read, try this thread:

    http://www.gammon.com.au/forum/?id=10363

  • Basically the plugin breaks up the ATCP/GMCP data into manageable chunks (eg. room info, char stats), and decodes the internal protocol (in the case of GMCP, this is JSON.

  • Then the plugin "broadcasts" this decoded information for "catching" by other plugins, if they happen to want to.

  • For example, a mapper plugin might catch room changes, a health bar plugin might catch HP updates.

  • In the case of the ATCP_NJG plugin mentioned above, it sends stats updates as message type 1, room brief descriptions as message type 2, and so on.

  • The stats line still looks like this (as far as I know):

    
    "H:496/496 M:412/412 E:1380/1380 W:960/960 NL:89/100 "
    


  • You then run that through a Lua regular expression (string.match) to pull out the individual numbers (health, max health etc.)

  • You do whatever you like with the resulting numbers.


The bottom line is, for the snippet you posted to work, you at least need the ATCP_NJG plugin installed (if they are still broadcasting those types of messages).


- Nick Gammon

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

Posted by Faedara   (106 posts)  Bio
Date Reply #4 on Mon 22 Nov 2010 12:46 AM (UTC)

Amended on Mon 22 Nov 2010 12:48 AM (UTC) by Faedara

Message
Your ATCP is still up to date, otherwise your mapper wouldn't be working (which it is and I love it).

It's that match.string that I need more information on, because if I'm correct that functions much like the basic "trigger" match line. Am I right?

The eternally clueless <3
Currently looking for a mentor/tutor to help me learn everything about Lua from the ground up. I can't understand 28*41 until I learn what causes 2+2.
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #5 on Mon 22 Nov 2010 01:36 AM (UTC)
Message
Nick's pretty much on the money here. As for string.match, that will capture one instance of a pattern you supply within a string. However, there are multiple things in that line that you'll want, so I'd use string.gmatch instead. You use it like this:

data = "H:496/496 M:412/412 E:1380/1380 W:960/960 NL:89/100 "
for stat, curr, max in string.gmatch(data, "(%w+):(%d+)/(%d+)") do
  curr, max = tonumber(curr), tonumber(max)
  
  -- Now you have the variables:
  -- stat is the stat letter (H, M, etc.)
  -- curr is the current value of the stat
  -- max is the highest value of the stat
end

'Soludra' on Achaea

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

Posted by Nick Gammon   Australia  (23,158 posts)  Bio   Forum Administrator
Date Reply #6 on Mon 22 Nov 2010 01:59 AM (UTC)
Message
I'm probably completely out-of-date here, but this is my test plugin which uses GMCP (with the JSON format):


<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="ATCP2_Logger_MW"
   author="Nick Gammon"
   id="4a33087c6b66ca6c4611afed"
   language="Lua"
   purpose="Displays ATCP2 info"
   date_written="2010-07-14"
   requires="4.40"
   version="1.0"
   >

</plugin>

<!--  Script  -->


<script>
<![CDATA[

require "json"
require "tprint"

local IAC, SB, SE, DO = 0xFF, 0xFA, 0xF0, 0xFD

local ATCP = 200
local ATCP2 = 201

function Send_Telnet_Packet (what)
    SendPkt (string.char (IAC, SB, ATCP2) .. 
             what .. 
             string.char (IAC, SE))
end -- Send_Telnet_Packet

function OnPluginTelnetSubnegotiation (msg_type, data)
  if msg_type ~= ATCP2 then
    return
  end -- if not ATCP2
  
  ColourNote ("darkorange", "", data)
  
  message, params = string.match (data, "([%a.]+) (.*)")
  
  if not message then
    return
  end -- if
  
  if not string.match (params, "[%[{]") then
    params =  "[" .. params .. "]"  -- sigh
  end -- if 

  local t = json.decode (params)
  
  if type (t) == "table" then
    tprint (t)
  end -- if
   
end -- function OnPluginTelnetSubnegotiation

function OnPluginTelnetRequest (msg_type, data)

  if msg_type == ATCP2 and data == "WILL" then
    return true
  end -- if
  
  if msg_type == ATCP2 and data == "SENT_DO" then
    Note ("Enabling ATCP.")
    Send_Telnet_Packet (string.format ('Core.Hello { "client": "MUSHclient", "version": "%s" }', Version ()))
    Send_Telnet_Packet ('Core.Supports.Set [ "Char 1", "Char.Skills 1", "Char.Items 1" ]')
    return true
  end -- if ATCP login needed (just sent DO)
  
  return false

end -- function OnPluginTelnetRequest

]]>
</script>

</muclient>


Now the tprint in that displays this sort of stuff:


Char.Vitals { "hp": "594", "maxhp": "594", "mp": "440", "maxmp": "468", "ep": "1870", "maxep": "1870", "wp": "1240", "maxwp": "1240", "nl": "2", "string": "H:594/594 M:440/468 E:1870/1870 W:1240/1240 NL:2/100 " }
"wp"="1240"
"ep"="1870"
"maxhp"="594"
"hp"="594"
"nl"="2"
"maxep"="1870"
"maxmp"="468"
"mp"="440"
"maxwp"="1240"
"string"="H:594/594 M:440/468 E:1870/1870 W:1240/1240 NL:2/100 "


The bold stuff is the original JSON stuff, and decoded into the table, you can see things like:


"maxhp"="594"
"hp"="594"


So, omitting the debugging displays, and doing a tonumber on it, and then putting it into a nice status bar, you are almost done! I thought I had something that already did that, but it doesn't seem to work any more.

- Nick Gammon

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

Posted by Faedara   (106 posts)  Bio
Date Reply #7 on Mon 22 Nov 2010 02:03 AM (UTC)
Message
I can't use GMCP because I'm using your ATCP Nick, your mapper doesn't seem to work with GMCP so I'm using the plugins from Twilight Sun on a dual ATCP system.

The eternally clueless <3
Currently looking for a mentor/tutor to help me learn everything about Lua from the ground up. I can't understand 28*41 until I learn what causes 2+2.
Top

Posted by Nick Gammon   Australia  (23,158 posts)  Bio   Forum Administrator
Date Reply #8 on Mon 22 Nov 2010 02:13 AM (UTC)
Message
Well in that case take a look at this:

Template:post=10131 Please see the forum thread: http://gammon.com.au/forum/?id=10131.


That shows the health bar. Twisol's idea is nice, in my case I just had a big string.match. It's all in that plugin.

- Nick Gammon

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

Posted by Nick Gammon   Australia  (23,158 posts)  Bio   Forum Administrator
Date Reply #9 on Mon 22 Nov 2010 02:17 AM (UTC)

Amended on Mon 22 Nov 2010 02:22 AM (UTC) by Nick Gammon

Message
In particular, this receives the ATCP data from the broadcast:


function OnPluginBroadcast (msg, id, name, text)
  if id == "85f72d0e263d75df7bde6f00" then
  
    if msg == 1 then
      got_vitals (text)
    end -- if   
 
  end -- if ATCP message
end


And this processes it:


function got_vitals (s)
  stats.health,    stats.maxhealth, 
  stats.mana,      stats.maxmana, 
  stats.endurance, stats.maxendurance, 
  stats.willpower, stats.maxwillpower, 
  stats.exp,       stats.maxexp = 
    string.match (s, "^" ..
      "H:(%d+)/(%d+) " ..
      "M:(%d+)/(%d+) " ..
      "E:(%d+)/(%d+) " ..
      "W:(%d+)/(%d+) " ..
      "NL:(%d+)/(%d+)")
  
  if stats.health then
   
    hp, max_hp               = tonumber (stats.health),     tonumber (stats.maxhealth)
    mana, max_mana           = tonumber (stats.mana),       tonumber (stats.maxmana)
    endurance, max_endurance = tonumber (stats.endurance),  tonumber (stats.maxendurance)
    willpower, max_willpower = tonumber (stats.willpower),  tonumber (stats.maxwillpower)
    exp, max_exp             = tonumber (stats.exp),        tonumber (stats.maxexp)
  
   
    -- draw/process stuff here

  end -- if
end -- function got_vitals


- Nick Gammon

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

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #10 on Mon 22 Nov 2010 02:30 AM (UTC)
Message
Faedara said:

I can't use GMCP because I'm using your ATCP Nick, your mapper doesn't seem to work with GMCP so I'm using the plugins from Twilight Sun on a dual ATCP system.

Yep, that's me. Twisol = Twilight Sun. And yeah, GMCP takes precedence over ATCP on IRE servers, and you can't have both enabled at once. Kind of annoying.

Nick, I have a GMCP plugin hosted on my site, based on the one someone else posted here previously.

'Soludra' on Achaea

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

Posted by Faedara   (106 posts)  Bio
Date Reply #11 on Mon 22 Nov 2010 08:45 AM (UTC)

Amended on Mon 22 Nov 2010 10:32 AM (UTC) by Faedara

Message
Nevermind, looking back over it, stats.xxxxx is the information being received and converted into a number to set the variables in the function. I feel stupid.


However I'm still having a problem calling them...


I've gotten a basic alias down for setting the sip_hp:


<aliases>
  <alias
   name="Test_sip_hp"
   match="^HH (.*?)$"
   enabled="y"
   regexp="y"
   send_to="12"
   sequence="100"
  >
  <send>
if %1 &gt; 99 then
Note ("error: sip_per ust be a value between 1 and 99")
else
SetVariable ("sip_per", %1)
SetVariable ("sip_hp", GetVariable ("max_hp") * GetVariable ("sip_per") * 0.01)
Note ("Sipping at " .. GetVariable ("sip_hp") .. " health")
end
</send>
  </alias>
</aliases>


((I know you two can read that like a book, but for those interested in the process))

I made this alias by multiplying the variables "max_hp" (max health) and "sip_per" (The % health you want to start sipping at, commonly 80% but sometimes differing. Done in % because health values constantly change, and therefor sip_hp should too) and multiplying the resulting number by 0.01 (the equivalent of dividing by 100). This gives us a percent of the max health at which a person will start sipping. I'm not worried about remainders right now, because in my code the remainder just means the number is rounded up.


Now I have a few problems. I want to convert this alias into a script, so that it will automatically update the max_hp and the sip_hp every time max_hp changes, instead of having to go back and retype HH * every time.

Next, I'm having problems setting max_hp using the snippet of code Nick gave me, I'm currently trying and failing to do this:




function OnPluginBroadcast (msg, id, name, text)
  if id == "85f72d0e263d75df7bde6f00" then
  
    if msg == 1 then
      got_vitals (text)
    end -- if   
 
  end -- if ATCP message
end



function got_vitals (s)
  stats.health,    stats.maxhealth, 
  stats.mana,      stats.maxmana, 
  stats.endurance, stats.maxendurance, 
  stats.willpower, stats.maxwillpower, 
  stats.exp,       stats.maxexp = 
    string.match (s, "^" ..
      "H:(%d+)/(%d+) " ..
      "M:(%d+)/(%d+) " ..
      "E:(%d+)/(%d+) " ..
      "W:(%d+)/(%d+) " ..
      "NL:(%d+)/(%d+)")
  
  if stats.health then
   
    hp, max_hp               = tonumber (stats.health),     tonumber (stats.maxhealth)
    mana, max_mana           = tonumber (stats.mana),       tonumber (stats.maxmana)
    endurance, max_endurance = tonumber (stats.endurance),  tonumber (stats.maxendurance)
    willpower, max_willpower = tonumber (stats.willpower),  tonumber (stats.maxwillpower)
    exp, max_exp             = tonumber (stats.exp),        tonumber (stats.maxexp)


    SetVariable ("max_hp", max_hp)

  end -- if
end -- function got_vitals
   


function sipper ()

     sip_hp  = GetVariable ("sip_hp")
     sip_bal = GetVariable ("sip_bal")

  if hp < sip_hp and sip_bal == "1" then
     Send ("sip health")
     SetVariable ("sip_bal", ".5")
  end -- if
end -- function


I'm trying to set the client variable max_hp to align with the script variable max_hp so that the variable will be constantly up-to-date, but something is wrong and the variable isn't changing...

Edit: also, function sipper () serves no purpose yet, just laying down a sort of skeleton for that part.

The eternally clueless <3
Currently looking for a mentor/tutor to help me learn everything about Lua from the ground up. I can't understand 28*41 until I learn what causes 2+2.
Top

Posted by Nick Gammon   Australia  (23,158 posts)  Bio   Forum Administrator
Date Reply #12 on Mon 22 Nov 2010 08:07 PM (UTC)
Message
Well either got_vitals isn't being called at all, or the regular expression isn't matching. I would add a couple of debugging prints, eg.


function got_vitals (s)

print ("in got_vitals, got:", s)

...


and later on:


SetVariable ("max_hp", max_hp)

print ("just set mxp_hp to", max_hp)


- Nick Gammon

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

Posted by Faedara   (106 posts)  Bio
Date Reply #13 on Mon 22 Nov 2010 10:35 PM (UTC)

Amended on Mon 22 Nov 2010 10:36 PM (UTC) by Faedara

Message
I'm getting Nil, not sure why.

The eternally clueless <3
Currently looking for a mentor/tutor to help me learn everything about Lua from the ground up. I can't understand 28*41 until I learn what causes 2+2.
Top

Posted by Nick Gammon   Australia  (23,158 posts)  Bio   Forum Administrator
Date Reply #14 on Tue 23 Nov 2010 02:22 AM (UTC)
Message
Me neither, without seeing more of your code.

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


63,169 views.

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