Parse ATCP

Post Reply
User avatar
Akaya
Posts: 414
Joined: Thu Apr 19, 2012 1:36 am

Parse ATCP

Post 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?

User avatar
kevutian
Posts: 217
Joined: Fri Aug 20, 2010 8:18 pm
Location: United Kingdom
Contact:

Re: Parse ATCP

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

User avatar
Akaya
Posts: 414
Joined: Thu Apr 19, 2012 1:36 am

Re: Parse ATCP

Post 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

User avatar
Heiko
Site Admin
Posts: 1548
Joined: Wed Mar 11, 2009 6:26 pm

Re: Parse ATCP

Post 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

Splork
Posts: 11
Joined: Tue Nov 17, 2009 1:00 am

Re: Parse ATCP

Post 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

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: Parse ATCP

Post by Vadi »

ATCP to MSDP?

User avatar
Heiko
Site Admin
Posts: 1548
Joined: Wed Mar 11, 2009 6:26 pm

Re: Parse ATCP

Post by Heiko »

Upcoming Mudlet 3.0 has built-in support for MSDP.

User avatar
Belgarath
Posts: 232
Joined: Fri Jul 26, 2013 7:19 am
Discord: macjabeth#7149

Re: Parse ATCP

Post 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)?

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: Parse ATCP

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

Post Reply