Page 1 of 1

Parse ATCP

Posted: Fri Jan 18, 2013 5:14 am
by Akaya
The mud I'm currently using sends information to the user via atcp.

This is similar to how achaea sends information via gmcp.

After you set up the exchange, the information is live and you can set up event handlers for each variable.

A few examples are:
MSDPCHARACTER_NAME is your character's name
MSDPOPPONENT_HEALTH is your opponent's health
MSDPSTR for your strength stat

These variables can also be pulled from the atcp table via atcp.MSDPCHARACTER_NAME
My problem is that some of these variables are giant strings that need to be parsed.
An example being MSDPAFFECTS (Affects in this mud are kinda like afflictions in IRE games )
MSDPAFFECTS doesn't hold a single value, but multiple. And none of it is parsed!

I need to parse the information in this variable so that I can use it in an event handler like the rest.

Here's what a few of the variables look like:
Image

As you can see, variables like the room name and damage roll are simple. But the MSDPAFFECTS variable needs to be broken up.

I was given the following code taken from a Godwars user that parses the information succesfully and then utilizes it in a UI. I can't figure out how to adapt this to my own scripting:
Code: [show] | [select all] lua
local AffectName = {}
local AffectDuration = {}
local AffectMax = 0

function init_affects (data)

  index = 0
  startpos = 1
  max = 0
  for i=startpos,string.len(data),1 do
    if string.byte(data,i) == 1 or i == string.len(data) then
      if string.byte(data,i) == 1 then
        endpos = 1
      else
        endpos = 0
      end -- if
      variable = string.sub(data,startpos,i-endpos)
      startpos = i+1
      index = index + 1

      pos1 = string.find(variable, "\002")
      if pos1 ~= nil then
        AffectName[index] = string.sub(variable, 1, pos1-1)
        AffectDuration[index] = string.sub(variable, pos1+1)
      end -- if
    end -- if
  end -- for

  -- AffectMax is the highest EVER number - we need to keep track of all created icons
  if index < AffectMax then
    for i=index+1,AffectMax,1 do
      AffectName[i] = nil
      win = "affect_window_"..i
      WindowShow (win, false)
    end -- for
    AffectMax = index
  elseif index > AffectMax then
    AffectMax = index
  end -- if

end -- function


function draw_affects ()

  affects = msdp["AFFECTS"]
  if affects == nil or affects == "None" then
    for i=1,AffectMax,1 do
      WindowShow ("affect_window_"..i, false)
    end -- for
    AffectMax = 0
    return
  end -- if

  init_affects (affects)

  offset_x = 0
  offset_y = 0

  for i=1,AffectMax,1 do
    if AffectName[i] ~= nil then
      win = "affect_window_"..i
      affect = "affect_"..i

      -- draw the icons left to right, top to bottom
      if i > 1 then
        if offset_x == 0 then
          offset_x = 36
        elseif offset_x == 36 then
          offset_x = 72
        elseif offset_x == 72 then
          offset_x = 108
        else
          offset_x = 0
          offset_y = offset_y + 36
        end -- if
      end -- if

      colour = colourGold

      -- make a miniwindow under the text
      check (WindowCreate (win,   -- window ID
                    14+offset_x,  -- left
                    383+offset_y, -- top
                    34,           -- width
                    34,           -- depth
                    12,           -- center it (ignored anyway) 
                    2,            -- draw underneath (1) + absolute location (2)
                    colourBlack))      -- background colour

      -- load the icon
      if WindowLoadImage (win, affect, GetInfo (66) .. "Generic/affects/" .. AffectName[i] .. ".png") == eOK then
        check (WindowDrawImage (win, affect, 1, 1, 33, 33, 2))  -- draw the icon
      elseif WindowLoadImage (win, affect, GetInfo (66) .. "Generic/affects/default.png") == eOK then
        check (WindowDrawImage (win, affect, 1, 1, 33, 33, 2))  -- draw the default icon instead
      else -- even the default spell icon is missing
        Note( "Missing spell icons.")
        return
      end -- if

      if tonumber(AffectDuration[i]) < 10 then
        offset = 9
      elseif tonumber(AffectDuration[i]) < 100 then
        offset = 5
      else -- two digits
        offset = 1
      end -- if

      if tonumber(AffectDuration[i]) < 0 then
        -- draw an infinity symbol
        outlined_text (colour, win, "O", 6, 4, 21, 0)
        outlined_text (colour, win, "O", 6, 9, 21, 0)
        -- go over the first 'O' again, removing the outline from the second 'O'
        WindowFont(win,'f','Times New Roman',6,1,0,0,0)
        WindowText(win,'f',"O",4,21,0,0,colour,0)
      else -- write the duration
        outlined_text (colour, win, AffectDuration[i], 6, 4, 21, 0)
      end -- if

      -- show the window
      WindowShow (win, true)

      -- create a hotspot over the timer
      WindowAddHotspot(win, "hs_affect_"..i, 0, 0, 34, 34, "", "", "", "", "", AffectName[i], 1, 0)
    end -- if
  end -- for

end -- draw_affects
Help?

Re: Parse ATCP

Posted: Fri Jan 18, 2013 5:39 am
by kevutian
Those functions seem redundant to me, personally. I'd find it much easier to just parse it to a string (If it is not already), and split it with the basic string split function. Much, much easier.

Re: Parse ATCP

Posted: Fri Jan 18, 2013 7:08 am
by Akaya
string.split() does seem much easier but its not separated by the same character every time. Here's the string when I have a few affects:
Image
I can't actually type those characters in this forum which makes it difficult to explain.

Ideally, I'd like it to separate into a table like so:
{
"dark cloak",
"1796",
"aegis",
"1796"
}

Or something similar

Re: Parse ATCP

Posted: Sat Jan 19, 2013 10:08 am
by Heiko
Your MUDs is obviously using Kavir's MSDP over ATCP snippet. The characters are MSDP item seperators. To find out the ACII codes look at the MSDP specs. http://tintin.sourceforge.net/msdp/
You need to write a small MSDP parser which isn't hard. Check out this also: http://www.mudbytes.net/index.php?a=top ... 20&p=64209

Re: Parse ATCP

Posted: Fri Sep 27, 2013 1:07 am
by Splork
I've been gone for a bit and was wondering if anyone had written a parser for Kavir's atcp to msdp snippet?

Nice to see everyone!

Splork

Re: Parse ATCP

Posted: Fri Sep 27, 2013 2:24 am
by Vadi
ATCP to MSDP?

Re: Parse ATCP

Posted: Fri Sep 27, 2013 7:54 am
by Heiko
Upcoming Mudlet 3.0 has built-in support for MSDP.

Re: Parse ATCP

Posted: Fri Sep 27, 2013 9:44 am
by Belgarath
Heiko wrote:Upcoming Mudlet 3.0 has built-in support for MSDP.
Hello Heiko! Will there be, in any future releases of Mudlet, a better, all-in-one mapper to use (that'll support both GMCP and non-GMCP)?

Re: Parse ATCP

Posted: Fri Sep 27, 2013 10:29 am
by Vadi
The mapper supports everything and and nothing.

What you're asking is 'will there be a mapper that'll work for any MUD on any engine out there?'. I'd love to know a way that work, but I can't. So we went with a design where support for X types of MUDs can be added in by users.