
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Saturday, August 04, 2012, 7:54 PM -->
<!-- MuClient version 4.81 -->

<!-- Plugin "Imperian_GMCP" generated by Plugin Wizard -->

<muclient>
<plugin
   name="Imperian_GMCP"
   author="Jorachim"
   id="62bfc6193517f6e5ac11017d"
   language="Lua"
   purpose="Handles GMCP In Imperian"
   save_state="n"
   date_written="2012-08-18"
   requires="4.81"
   version="2.0"
   >

   <description trim="y">
	Modified version of the GMCP Plugin for Aardwolf.
	
	To get out the GMCP data, put the following function in your character script.
	
	function getGMCP()
		gmcp = {}
		assert(loadstring(GetPluginVariable("62bfc6193517f6e5ac11017d", "gmcp")))()
		return gmcp
	end
	
	If there's an easier way, let me know at codeacula@codeacula.com
	
	Original author: Lasher
	URL: http://www.aardwolf.com/wiki/index.php/Clients/MushclientGMCP
   </description>
</plugin>

<aliases>
<alias
   script="gmcpdebug"
   match="^gmcpdebug (.*)?$"
   enabled="y"
   regexp="y"
   sequence="100"
   ignore_case="y"
  >
  </alias>

  <alias
   match="sendgmcp *"
   script="GMCP_Alias"
   enabled="y"
   send_to="12"
   sequence="100"
  >
  </alias>

</aliases>

<!--  Script  -->


<script>
<![CDATA[

require "json"
require "serialize"
require "tprint"

-- Telnet codes for later
local IAC, SB, SE, DO = 0xFF, 0xFA, 0xF0, 0xFD
local GMCPCode  = 201
local GMCPDebug = 0

-- GMCP Data. It's stored here so previous values are kept
gmcp = {
	Char = {
		Items = {},
		Name = {},
		Rift = {},
		Skills = {},
		Status = {},
		StatusVars = {},
		Vitals = {}
	},
	Comm = {
		Channels = {}
	},
	Room = {
		Info = {}
	}
}

-- Send a GMCP command to the MUD
function GMCP_Alias(name, line, wildcards)
	if (wildcards[1] ~= nil) then
		Send_GMCP_Packet(wildcards[1]) -- in gmcphelper
	end
end 

-- Handle turning on/off debugging
function gmcpdebug(name, line, wildcards)
	newval = tonumber(wildcards[1])
	
	if not newval or newval > 2 or newval < 0 then
		ColourNote("lightgreen", "", "GMCPDebug valid values are: 0 - off, 1 - simple, 2 - verbose")
		return
	end
	
	GMCPDebug = newval
	local msg = "off"
	
	if GMCPDebug == 1 then
		msg = "simple"
	elseif GMCPDebug == 2 then
		msg = "verbose"
	end
	
	ColourNote ("lightgreen", "", "GMCPDebug: " .. msg)
end

function OnPluginCommand(command)
	if command == "ir" then
		Send_GMCP_Packet("IRE.Rift.Request")
	elseif command == "ab" then
		Send_GMCP_Packet("Char.Skills.Get")
	end
	return true -- process it
end

function OnPluginInstall()
      BroadcastPlugin(1, "reload") -- reload basically tells other plugins "clear all your gmcp data"
end

function OnPluginSave()
	SetVariable("gmcp", "")
end
 
-- When we get SB data
function OnPluginTelnetSubnegotiation (msg_type, data)
	-- Don't bother if the DB data isn't GMCP
	if msg_type ~= GMCPCode then
		return
	end -- if not GMCPCode

	-- If we're doing any debugging, dump the data we got back
	if GMCPDebug > 0 then ColourNote ("lightgreen", "", data) end

	-- Split the data into name/info
	message, params = string.match (data, "([%a.]+)%s+(.*)")

	-- If there's no name, don't bother
	if not message then
		return
	end

	-- This checks to see if we need to hack the params to parse through JSON
	if not string.match (params, "^[%[{]") then
		params =  "[" .. params .. "]"
	end

	-- Decode the data
	local t = json.decode(params)
	
	if type(t) == "table" then
		-- Save the older version in old_gmcp
		SetVariable("old_gmcp", serialize.save("gmcp"))
		
		-- If we're working on items
		if message == "Char.Items.Add" then
			gmcp.Char.Items[t.location] = gmcp.Char.Items[t.location] or {}
			gmcp.Char.Items[t.location][t.item.id] = t.item
		elseif message == "Char.Items.List" then
			gmcp.Char.Items[t.location] = {}
			
			for _, item in ipairs(t.items) do
				gmcp.Char.Items[t.location][item.id] = item	
			end
		elseif message == "Char.Items.Remove" then
			if gmcp.Char.Items[t.location][t.item] then
				gmcp.Char.Items[t.location][t.item] = false
			end
		elseif message == "Char.Skills.Groups" then
			for _, skill in pairs(t) do
				if not gmcp.Char.Skills[skill.name] then
					setupSkill(skill.name)
				end
				
				requestSkill(skill.name)
			end
		elseif message == "Char.Skills.List" then
			setupSkill(t.group)
			gmcp.Char.Skills[t.group].abilities = {}
			for _, skill in ipairs(t.list) do
				gmcp.Char.Skills[t.group].abilities[skill] = true
			end
		elseif message == "Comm.Channel.List" then
			for _, channel in pairs(t) do
				gmcp.Comm.Channels[channel.name] = channel
			end
		elseif message == "IRE.Rift.List" then
			for _, riftable in ipairs(t) do
				gmcp.Char.Rift[riftable.name] = riftable
			end
		elseif message == "IRE.Rift.Change" then
			gmcp.Char.Rift[t.name] = t
		else
			-- Get to the right part of the GMCP data
			local current = gmcp
			for v in string.gmatch(message, "%a+") do
				current[v] = current[v] or {}
				current = current[v]
			end
			
			-- Set the GMCP info
			for k, v in pairs(t) do
				current[k] = v
			end
		end
		
		SetVariable("gmcp", serialize.save("gmcp"))
		if GMCPDebug > 1 then print ("gmcpdata serialized: " .. serialize.save_simple(gmcp)) end

		BroadcastPlugin(1, "GMCP Updated: "..message)
	end -- if
end -- function OnPluginTelnetSubnegotiation

function OnPluginTelnetRequest (msg_type, data)

  if msg_type == GMCPCode and data == "WILL" then
    return true
  end -- if
  
  if msg_type == GMCPCode and data == "SENT_DO" then
    ColourNote("lightgreen", "", "Enabling GMCP.") 
    -- This hard-coded block may need to be made into a config table as we add more message types.
    Send_GMCP_Packet (string.format ('Core.Hello { "client": "MUSHclient", "version": "%s" }', Version ()))
    Send_GMCP_Packet ('Core.Supports.Set [ "Char 1", "Char.Skills 1", "Char.Items 1", "Comm 1", "Comm.Channel 1", "Room 1", "IRE.Rift 1" ]')
    return true
  end -- if GMCPCode login needed (just sent DO)
  
  return false

end -- function OnPluginTelnetRequest

function requestSkill(skillGroup, skillName)
	assert(skillGroup, "requestSkill was not sent a skill group")
	
	local skillBlock = string.format('"group": "%s"', skillGroup)
	if skillname then skillBlock = skillBlock..string.format(' "name": "%s"', skillName) end
	
	Send_GMCP_Packet(string.format("Char.Skills.Get {%s}", skillBlock))
end

function Send_GMCP_Packet(what)
   assert (what, "Send_GMCP_Packet passed a nil message.")

   SendPkt (string.char (IAC, SB, GMCPCode) .. 
           (string.gsub (what, "\255", "\255\255")) ..  -- IAC becomes IAC IAC
            string.char (IAC, SE))
end

function setupSkill(skill)
	if gmcp.Char.Skills[skill] then return gmcp.Char.Skills[skill] end
	
	gmcp.Char.Skills[skill] = {}
	gmcp.Char.Skills[skill].rank = skill.rank
	gmcp.Char.Skills[skill].abilities = {}
	
	return gmcp.Char.Skills[skill] 
end

]]>
</script>


</muclient>
