<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="ATCP"
   author="Trevize"
   id="431a11163c945fb1f7663d3e"
   language="Lua"
   purpose="ATCP data"
   date_written="2008-09-18"
   requires="4.35"
   version="1.0"
   >
</plugin>

<script><![CDATA[

-- this script borrows heavily from Keldar's ATCP plugin

Z = {
  tpairs = function (tbl)
    local i = 0
    return function ()
      i = i + 1
      if tbl[i] ~= nil then return tbl[i] end
    end -- func
  end, -- func
  }

tpairs = Z.tpairs



client_id =  "Muclient ".. Version()

nexus_opts = {
  {"hello", client_id},
  {"auth", "1"},
  {"char_name", "1"},
  {"char_vitals", "1"},
  {"room_brief", "1"},
  {"room_exits", "1"},
}

codes = {
  ["IAC WILL ATCP"] = "\255\251\200",
  ["IAC WONT ATCP"] = "\255\252\200",
  ["IAC DO ATCP"]   = "\255\253\200",
  ["IAC DONT ATCP"] = "\255\254\200",
  ["IAC SB ATCP"]   = "\255\250\200",
  ["IAC SE"]        = "\255\240",
  ["IAC DO EOR"]    = "\255\253\025",
  ["IAC WILL EOR"]  = "\255\251\025",
  ["IAC GA"]        = "\255\249",
}


DoNote = function (msg)
  Note(msg)
end

SendATCP = function (msg)
  SendPkt(codes["IAC SB ATCP"] .. msg .. codes["IAC SE"])
end

leftovers = ""

PAT = codes["IAC SB ATCP"] .. "(.-)" .. codes["IAC SE"]



OnPluginConnect = function ()
  local msg = ""
  for v in tpairs(nexus_opts) do
    msg = msg .. v[1] .. " " .. v[2] .. "\10"
  end 
  msg = string.sub(msg, 1, -2)
  SendPkt(codes["IAC DO ATCP"] .. codes["IAC SB ATCP"] .. msg .. codes["IAC SE"])
end



OnPluginPacketReceived = function (packet)
  local orig_packet = packet
  if string.find (packet, codes["IAC WILL ATCP"]) then
    DoNote ("ATCP enabled.")
    packet = string.gsub (packet, "(.-)" .. codes["IAC WILL ATCP"] .. "(.-)", "%1%2")
  end
  if string.find (packet, codes["IAC WONT ATCP"]) then
    DoNote ("ATCP disabled.")
  end
  if string.find (packet, codes["IAC WILL EOR"]) then
    packet = string.gsub (packet, "(.-)" .. codes["IAC WILL EOR"] .. "(.-)", "%1%2")
  end
  local packet, atcp, parsed = parseATCP (packet)
  if parsed["Auth.Request CH"] then
    SendATCP ("auth " .. tostring (atcp_auth (parsed["Auth.Request CH"])) .. " " .. client_id)
  end
  if parsed["Auth.Request ON"] then
    DoNote ("Authorization accepted.")
  end
  if parsed["Char.Vitals"] ~= nil then
    BroadcastPlugin (1, parsed["Char.Vitals"])
  end
  if parsed["Room.Brief"] ~= nil then
    BroadcastPlugin (2, parsed["Room.Brief"])
  end
  if parsed["Room.Exits"] ~= nil then
    BroadcastPlugin (3, parsed["Room.Exits"])
  end
  return packet
end



get_room = function (msg, tab)
  local s,e,what,cont = string.find (msg, "^(Room%.%w+) (.-)$")
  if s then
    tab[what] = cont
    return tab
  else 
    return nil
  end
end



function get_vitals (msg, tab)
  local asplit = utils.split (msg, "\10")
  tab[asplit[1]] = asplit[2] or ""
  return tab
end



function parseATCP (packet)
  local packet = leftovers .. packet
  leftovers = ""

  local s,e,prev,msg,nxt,asplit
  local atcp, parsed = {}, {}

  local new_packet = ""
  new_packet = string.gsub (packet, PAT, function(cap)
      local ret = get_room (cap, parsed)
      if ret then
        parsed = ret
      else
        parsed = get_vitals (cap, parsed)
      end
      table.insert (atcp, cap)
      return ""
      end)

  s,e,msg = string.find (new_packet, "(\255[^\255]-\255?)$")
  if s then
    if (#msg == 1) or ( (#msg > 2) and string.find (msg, "^\255\250\200") ) 
       or ( (#msg > 1) and string.find (msg, "^\255\250") ) then 
      leftovers = msg
      new_packet = string.sub (new_packet, 1, s-1)
    end
  end
  packet = new_packet
  return packet, atcp, parsed
end 



atcp_auth = function (seed)
  local a,i = 17, 0
  local n
  
  for letter in string.gmatch (seed, ".") do
    n = string.byte (letter)-96
    if math.fmod (i,2) == 0 then
      a = a+n*(bit.bor (i,13))
    else
      a = a-n*(bit.bor (i,11))
    end
    i = i+1
  end
  return a
end



]]></script> 

</muclient>
