Aardwolf GMCP plugin - partial refreshes of data

Posted by Sickent on Sun 08 Jun 2014 04:36 PM — 7 posts, 27,165 views.

USA #0
http://www.aardwolf.com/wiki/index.php/Clients/MushclientGMCP
http://www.aardwolf.com/gmcp/gmcp-plugin.zip

I've started using this plugin in my systems on IRE games. I've seen it suggested in other threads and it's worked so far. I couldn't find a forum post for FAQs and updates, so I'm asking here.

This plugin explains:
--
Purpose is to receive incoming GMCP messages and populate the global table 'gmcpdata' with the values as received so that GMCP under Mushclient can use partial refreshes of data. For example, we might receive:

char.vitals { "hp": 100000, "mana": 90000, "moves": 41599 }

Then next time, if only HP and Mana have changed, receive:

char.vitals { "hp": 100000, "mana": 85000 }

The previous value for 'moves' will be remembered and available until it is refreshed.
--

This is specifically bad with Aetolia and its Char.Afflictions and Char.Afflictions.list (I think they end up being the same thing). When you cure an affliction, the original global table isn't updating because it's not supposed to by design. I can't clear this table from local script, and I'm not really understanding how/when the plugin builds the original table.

In the above example, what I'd want:
--
We might receive from char.vitals:

char.vitals { "hp": 100000, "mana": 90000, "moves": 41599 }

Then next time receive:

char.vitals { "hp": 100000, "mana": 85000 }

The previous value vitals.moves is nil, as it was deleted when we received new information from char.vitals.
--

Any help would be appreciated. Thank you.
Amended on Sun 08 Jun 2014 04:42 PM by Sickent
Australia Forum Administrator #1
I can't reproduce that. If I install the GMCP_handler plugin, and then turn on debugging:


gmcpdebug 2


I then send a test packet (Ctrl+Shift+F12):


\FF\FA\C9char.vitals { "hp": 100000, "mana": 90000, "moves": 41599 }\FF\F0


I get the debug message:


gmcpdata serialized: {
  char = {
    vitals = {
      mana = "90000",
      hp = "100000",
      moves = "41599",
      },
    },
  }


Now if I send the second packet with no change to moves:


\FF\FA\C9char.vitals { "hp": 200000, "mana": 85000 }\FF\F0


The debug says:


char.vitals { "hp": 200000, "mana": 85000 }
gmcpdata serialized: {
  char = {
    vitals = {
      mana = "85000",
      hp = "200000",
      moves = "41599",
      },
    },
  }


So the moves are still there.

You will have to post your code and show what you are doing and what you are displaying. Just describing it doesn't let us help you.
Amended on Sun 08 Jun 2014 09:49 PM by Nick Gammon
USA #2
I can't demonstrate the issue without showing what's incoming from the MU* _without_ the plugin, and the only tool I know that'll do that is Wireshark. And incoming from the MU* is spitting gibberish to me, with exception to the loggin.

So, the example I'd provide, you'd have to trust that I'm not talking out of my rump or that the game isn't behaving like it shouldn't.

Three seconds for the later, unless you know how to work Wireshark.
Australia Forum Administrator #3
Sickent said:

And incoming from the MU* is spitting gibberish to me, with exception to the loggin.



Can you copy and paste this gibberish? I don't know what you are telling me here.

I made a new character on Aetolia and with gmcpdebug set to level 1, I see this every time the MUD sends something:


Char.Vitals { "hp": "343", "maxhp": "343", "mp": "357", "maxmp": "357", "ep": "615", "maxep": "615", "wp": "600", "maxwp": "600", "nl": "0", "xp": "0", "maxxp": "5001", "blood": "100", "bleeding": "0", "blind": "0", "deaf": "0", "prone": "1", "cloak": "0", "fangbarrier": "0", "flying": "0", "herb": "1", "salve": "1", "pipe": "1", "elixir": "1", "moss": "1", "tree": "1", "renew": "1", "affelixir": "1", "focus": "1", "soul": "100", "residual": "0", "madness": "0", "status": "living", "balance": "1", "equilibrium": "1", "left_arm": "1", "right_arm": "1", "wield_left": "", "wield_right": "", "class": "ascendril", "mounted": "0", "burrowed": "no", "string": "H:343/343 M:357/357 E:615/615 W:600/600 NL:0/100 " }
[][]


It doesn't look to me like it is sending a subset of the data. Also for you to use the plugin you need to have your own plugin that receives the data. So I'm not sure what you are trying to do, what you expect to happen, and what is actually happening.
Australia Forum Administrator #4
Sickent said:

Three seconds for the later, unless you know how to work Wireshark.


MUSHclient has a packet debug mode (see the Edit menu). That tells you exactly what is arriving.
Australia Forum Administrator #5
This small plugin demonstrates how you might use GMCP. I tested it in Aetolia.

Template:saveplugin=GMCP_demo
To save and install the GMCP_demo plugin do this:
  1. Copy the code below (in the code box) to the Clipboard
  2. Open a text editor (such as Notepad) and paste the plugin code into it
  3. Save to disk on your PC, preferably in your plugins directory, as GMCP_demo.xml
    • The "plugins" directory is usually under the "worlds" directory inside where you installed MUSHclient.
  4. Go to the MUSHclient File menu -> Plugins
  5. Click "Add"
  6. Choose the file GMCP_demo.xml (which you just saved in step 3) as a plugin
  7. Click "Close"
  8. Save your world file, so that the plugin loads next time you open it.



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

<muclient>
<plugin
   name="GMCP_demo"
   author="Nick Gammon"
   id="b9171e77bc4ed6d2926eebdc"
   language="Lua"
   purpose="GMCP demonstration"
   date_written="2014-06-09"
   requires="4.73"
   version="1.0"
>
</plugin>

<!--  Script  -->

<script>
<![CDATA[

fulldata = {}

--=================================================================================
-- Called when plugin receives telnet data - main entry point for actually running
-- the plugin.
--=================================================================================
function OnPluginBroadcast (msg, id, name, text)

   -- Look for GMCP handler.
   if (id == '3e7dedbe37e44942dd46d264') then
      if (text == 'reload') then
         -- invalidate current data
         fulldata = {} 
         return
      end
     -- print ("GMCP packet = ", text)
      if (text == "Char.Base" or text == "Char.Vitals" or text == "Char.Status" or text == "Char.Maxstats") then
         res, gmcparg = CallPlugin("3e7dedbe37e44942dd46d264","gmcpval","Char")

         luastmt = "gmcpdata = " .. gmcparg
         assert (loadstring (luastmt or "")) ()

         -- copy into fulldata
         for k, v in pairs (gmcpdata) do
           fulldata [k] = v
         end -- for
      
      if text == "Char.Vitals" then
        ShowHealth ()
      end -- if
      end
   end
end

oldequilibrium = 0
oldbalance = 0

function ShowHealth ()
  hp          = tonumber (fulldata.Vitals.hp)
  maxhp       = tonumber (fulldata.Vitals.maxhp)
  equilibrium = tonumber (fulldata.Vitals.equilibrium)
  balance     = tonumber (fulldata.Vitals.balance)

  SetStatus ("Health: " .. hp .. "/" .. maxhp .. " Equilibrium = " .. equilibrium .. " Balance = " .. balance )
  
  if equilibrium == 1 and oldequilibrium == 0 then
    ColourNote ("darkgreen", "", "You have regained equilibrium")
  elseif equilibrium == 0 and oldequilibrium == 1 then
    ColourNote ("darkred", "", "You have lost equilibrium")
  end --if
  oldequilibrium = equilibrium
  
  if balance == 1 and oldbalance == 0 then
    ColourNote ("darkgreen", "", "You have regained balance")
  elseif balance == 0 and oldbalance == 1 then
    ColourNote ("darkred", "", "You have lost balance")
  end --if
  oldbalance = balance
  
end -- ShowHealth

]]>
</script>
</muclient>


This gets the stats from the GMCP data, and in the function ShowHealth updates the status bar with your hit points, and shows a message when you gain or lose equilibrium or balance.
Amended on Mon 09 Jun 2014 05:32 AM by Nick Gammon
USA #6
Your plugin is easier to understand and I can do what I want from it. I don't need to make that example anymore.

Thank you for the base code. I'll copy here or in a pastebin what I'm doing with your example when I figure out how to use this new direction.