Simple GMCP plugin

Posted by Solara on Wed 01 Oct 2014 04:27 PM — 73 posts, 224,079 views.

USA #0
Hi I'm trying to enable very simple GMCP data capture from a mud.

I downloaded Twisol's plugin that he posted in another thread (now closed or else I'd have replied to that post). It can be downloaded here: http://jonathan.com/mushclient-achaea-plugins

So I enabled the plugin and it seems to work since it shows the GMCP data when I enable debug by typing "gmcp debug".

My question is, how do I capture that data into variables? I can write simple lua scripts using aliases/triggers. But trying to look through his other xml and lua files for other plugins using GMCP data is a bit confusing for this non-programmer.

The GMCP data I get from the mud is as follows when I turn debug on:

"message"="Char.Vitals"
"data":
"fatigue"=0
"mana"=100
"hp"=100
"bleeding"=0

"message"="Char.Team"
"data":
1:
"name"="Chiara"
"pos"="0"
"leader"="0"
"hp"="100"
"blood"="0"
2:
"name"="Nicole"
"pos"="1"
"leader"="1"
"hp"="100"
"blood"="0"

I would like to capture all the Char.Vitals into individual variables to display, as well as the hp/blood for Char.Team for Chiara.

Is there a simple alias/trigger script someone can show me that can capture the data using Twisol's GMCP plugin please?
Australia Forum Administrator #1
Looks like your private message to Twisol bounced.
Australia Forum Administrator #2
It's been a while since I worked on this, but it looks like you have a table of data. Check out inside where the debugging is displayed. If all that is in one table, just extract stuff out in the usual Lua way.
USA #3
His plugin consists of a very short plugin.xml, debug.xml, a main.lua, a plugger.xml, and ppi.lua.

I can decipher simple aliases/trigger scripts, but can't understand complex plugins like main.lua and ppi.lua.

Surely there must be a simple function or variable that I can call from within an alias or trigger for each of the gmcp data?

I can paste the contents of each file if it makes it easier for people to decipher the plugin, but a couple lua files seem rather large and I don't want to waste space on this forum.
Amended on Thu 02 Oct 2014 01:16 AM by Solara
Australia Forum Administrator #4
There's another thread about mappers, coincidentally:

http://www.gammon.com.au/forum/?id=12601&reply=12#reply12

Try getting rid of those plugins and installing the ATCP_NJG one, and see what sort of debugging you get out of it.

Twisol does tend to split his code between various plugins and files.
USA #5
I'll take a look at the links tomorrow, but fyi, i had already tried the aardwof gmcp plugin that's available using the gmcp_handler.xml.

I also tried to look at your gmcp_demo.xml (http://www.gammon.com.au/forum/?id=12479) that you posted on this thread and changing a few things, but there are hooks/calls in there that relate only to the aardwolf gmcp plugin so it didn't work for the one I'm using.

The reason I ended up using Twisol is because it is the only one that actual seems to work and show data when debug is turned on.


Addendum: Okay well I decided to go back and retry the aardwolf gmcp plugin and turning on gmcpdebug 1 and 2 I do get the data.

This is the simple debug data I get returned during debug:

Char.Vitals { "hp":100, "mana":100, "fatigue":0, "bleeding":0 }
Char.Team [{"blood":"0", "hp":"100", "leader":"0", "name":"Kami", "pos":"0"}, {"blood":"0", "hp":"100", "leader":"1", "name":"Pringle", "pos":"1"}]

I enabled your GMCP_Demo.xml that you made referencing the aardwolf gmcp plugin but it errors out probably because it has data there that does not pertain to the mud I'm playing.
Amended on Thu 02 Oct 2014 04:33 AM by Solara
USA #6
So I modified your GMCP_Demo.xml to eliminate data that this mud doesn't send and changed vitals that it does and it does work, showing a status bar for hp, mana, fatigue, bleeding.


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


function ShowHealth ()
  hp          = tonumber (fulldata.Vitals.hp)
  mana        = tonumber (fulldata.Vitals.mana)
  fatigue     = tonumber (fulldata.Vitals.fatigue)
  bleeding    = tonumber (fulldata.Vitals.bleeding)

  SetStatus ("Health: " .. hp .. " Mana: " .. mana .. " Fatigue = " .. fatigue .. " Bleeding = " .. bleeding )
  
end -- ShowHealth

]]>
</script>
</muclient>


So I am one step closer to doing what I want, which is to capture the data into variables to put into a miniwindow using simple aliases/trigger (I am only used to writing those, not actual plugin xml files). And I'd like to capture the Char.Team data as well.
Amended on Thu 02 Oct 2014 05:00 AM by Nick Gammon
USA #7
Okay so trying to capture the data into variables so I can use it for other triggers/scripts I tried to change the ShowHealth function to this in the GMCP_Demo.xml:

function ShowHealth ()
hp = tonumber (fulldata.Vitals.hp)
mana = tonumber (fulldata.Vitals.mana)
fatigue = tonumber (fulldata.Vitals.fatigue)
bleeding = tonumber (fulldata.Vitals.bleeding)

SetVariable ("Health", hp)
SetVariable ("Mana", mana)
SetVariable ("Fatigue", fatigue)
SetVariable ("Bleeding", bleeding )

end -- ShowHealth


But that did not work. Under variables I don't see any of those set at all. I can do Note (hp) from within the plugin and it does send the correct data to the screen. How do you use SetVariable in a plugin file?

I also tried to add a second ShowHealthTeam function to capture the team hp/blood/position by adding these lines but the plugin errored out:

-- print ("GMCP packet = ", text)
if (text == "Char.Vitals" or text == "Char.Team") 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
if text == "Char.Team" then
ShowHealthTeam ()
end -- if
end
end
end
.
.
.

function ShowHealthTeam ()
hp2 = tonumber (fulldata.Team.hp)
position = tonumber (fulldata.Team.pos)
blood = tonumber (fulldata.Team.blood)

SetVariable ("Health2", hp2)
SetVariable ("Position", position)
SetVariable ("Bleeding", blood )

end -- ShowHealth


I'm thinking it errored out because Char.Team has hp/blood/pos/leader data for each team member, so how do I go about pulling name "Chiara"'s numbers?
Australia Forum Administrator #8
What do you mean it didn't work? Variables are local to plugins. You can get them from other plugins or the main world file by using GetPluginVariable.

http://www.gammon.com.au/scripts/doc.php?function=GetPluginVariable

Another approach a plugin can use is to "Execute" a string like: "plugin-info: health now 456"

Then make an alias in your main world file to "catch" such a string.
USA #9
Okay so after a bit more reading it seems it's difficult to push a plugins' variable to the world's global variable. Easier to pull it with GetPluginVariable. And using Notify within the plugin to notify the world.

So how do I set a Notify command within the gmpc_demo.xml to notify the world that the variables have been updated?

And I'm still stumped as to how to pull Char.Team gmcp data (hp, blood, pos) for a specific or all team members.
USA #10
Hi Solara (and Nick - long time no see!),

I saw your comment on my blog, but I figured I'd respond here since you already have a thread. It'd been a while since I last used these plugins, but let me see if I can help.

My GMCP plugin is only useful to other plugins, so you'll want to modify an existing plugin. I usually recommend my RoomName.plugin, since it's so minimal but has all the parts necessary to work. You'd just want to make sure to modify its plugin.xml so it has a unique ID, and probably change the name and author. :P

In your case, you'll want to modify the listening code (lines 10-12 of RoomName.plugin/scripts/main.lua) to include one Listen block for each message you're interested in. You can then create exposed variables in the plugin with GetVariable(), and access them from anywhere (such as your non-plugin aliases, triggers, etc.) using GetPluginVariable() and the ID you gave your plugin.

I'll subscribe to this thread, so let me know if you have any issues. I see you're looking into the Aardwolf plugin as well, but in either case, I hope you find something that works for you!

[EDIT]:
Quote:
So how do I set a Notify command within the gmpc_demo.xml to notify the world that the variables have been updated?
Unless something has changed since the last time I actively developed in MUSHclient, there's no pleasant way to do that. The whole point of GMCP.plugin and the PPI module is to allow other plugins to be notified on just such occasions, but the "world" scripts are more limited in this respect.

[EDIT]: I don't consider Execute a pleasant way. :D
Amended on Thu 02 Oct 2014 06:17 AM by Twisol
Australia Forum Administrator #11
Like I said, Execute a command like "variables changed".

Then make an alias in the main world that matches "variables changed". Problem solved.

Template:function=Execute
Execute

The documentation for the Execute script function is available online. It is also in the MUSHclient help file.

USA #12
this is now my modified ShowHealth function within gmcp_demo:

function ShowHealth ()
hp = tonumber (fulldata.Vitals.hp)
mana = tonumber (fulldata.Vitals.mana)
fatigue = tonumber (fulldata.Vitals.fatigue)
bleeding = tonumber (fulldata.Vitals.bleeding)

end -- ShowHealth


This is the content of my alias to try to pull those variables and display them. I get nil errors.

hp = GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "hp")
mana = GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "mana")
fatigue = GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "fatigue")
bleeding = GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "bleeding")

note (hp)
note (mana)
note (fatigue)
note (bleeding)
USA #13
"Note" is case-sensitive. You have to use it like: Note(hp).
Amended on Thu 02 Oct 2014 06:28 AM by Twisol
USA #14
Ha, yeah embarrasing error. I don't get any errors now after changing to Note, but all variables are still 'nil'. I know the gmcp data is being rceived and I didn't change anything within thte gmcp_demo.xml except to remove the SetStatus commands.

Edit: Okay figured out the problem. I have to actually do SetVariable within the plugin for it to be called:

function ShowHealth ()
  hp          = tonumber (fulldata.Vitals.hp)
  mana        = tonumber (fulldata.Vitals.mana)
  fatigue     = tonumber (fulldata.Vitals.fatigue)
  bleeding    = tonumber (fulldata.Vitals.bleeding)

  SetVariable ("Health_gmcp", hp)
  SetVariable ("Mana_gmcp", mana)
  SetVariable ("Fatigue_gmcp", fatigue)
  SetVariable ("Bleeding_gmcp", bleeding)

end -- ShowHealth



Now, can anyone help me pull the gmcp data for the Char.Team? It seems it's Char.Team.1 for first team member, Char.Team.2 for second team member, etc.

Here's the verbose gmcp data from the mud:

Char.Vitals { "hp":100, "mana":100, "fatigue":0, "bleeding":0 }
gmcpdata serialized: {
  Char = {
    Team = {
      [1] = {
        name = "Chiara",
        blood = "0",
        hp = "100",
        leader = "0",
        pos = "0",
        },
      [2] = {
        name = "Nicole",
        blood = "0",
        hp = "100",
        leader = "1",
        pos = "1",
        },
      },
    Vitals = {
      fatigue = "0",
      mana = "100",
      hp = "100",
      bleeding = "0",
      },
    },
  }
Char.Team [{"blood":"0", "hp":"100", "leader":"0", "name":"Chiara", "pos":"0"}, {"blood":"0", "hp":"100", "leader":"1", "name":"Nicole", "pos":"1"}]
gmcpdata serialized: {
  Char = {
    Team = {
      [1] = {
        name = "Chiara",
        blood = "0",
        hp = "100",
        leader = "0",
        pos = "0",
        },
      [2] = {
        name = "Nicole",
        blood = "0",
        hp = "100",
        leader = "1",
        pos = "1",
        },
      },
    Vitals = {
      fatigue = "0",
      mana = "100",
      hp = "100",
      bleeding = "0",
      },
    },
  }
Amended on Thu 02 Oct 2014 08:17 PM by Solara
USA #15
The other issue is that a GetVariable "plugin variable" and a "script variable" are two different kinds of things. You're setting script variables in ShowHealth, but trying to access plugin variables in your alias.

Solution: In ShowHealth, do something like this for each variable instead:
SetVariable("hp", fulldata.Vitals.hp)
USA #16
Solara said:
Edit: Okay figured out the problem. I have to actually do SetVariable within the plugin for it to be called:
Prefer replying instead of editing if you have something new to add. I didn't see your edit because I had already posted a reply which wrapped onto the second page of the thread.

Solara said:
Now, can anyone help me pull the gmcp data for the Char.Team? It seems it's Char.Team.1 for first team member, Char.Team.2 for second team member, etc.
If you're using the GMCP_Demo.xml plugin, you'll need to edit OnPluginBroadcast to have it check for each individual message and call a new function instead of ShowHealth. If you're editing RoomName.plugin, you add a new GMCP.Listen() block for each message you're interested in, and you get the data as a parameter.

I'm not familiar with the Aardwolf GMCP plugin, and it uses opaque techniques (loadstring in particular) to bring arbitrary variables into scope, so it's hard to tell what OnPluginBroadcast is actually doing here.
Amended on Thu 02 Oct 2014 07:10 AM by Twisol
Australia Forum Administrator #17
Solara said:

this is now my modified ShowHealth function within gmcp_demo:


It's best to post the complete plugin and the complete alias. You may be doing something wrong like not using the right plugin ID.

Template:copying
For advice on how to copy aliases, timers or triggers from within MUSHclient, and paste them into a forum message, please see Copying XML.


Template:codetag
To make your code more readable please use [code] tags as described here.
Australia Forum Administrator #18
Twisol said:

Hi Solara (and Nick - long time no see!),


Hi Twisol!

How's the new client going?
USA #19
So this is my updated GMPC_Demo.xml to try to grab the Char.Team numbers.

<?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.Vitals" or text == "Char.Team") 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

      if text == "Char.Team" then
        ShowHealthTeam ()
      end -- if
      end
   end
end


function ShowHealth ()

  SetVariable ("HP_gmcp", fulldata.Vitals.hp)
  SetVariable ("Mana_gmcp", fulldata.Vitals.mana)
  SetVariable ("Fatigue_gmcp", fulldata.Vitals.fatigue)
  SetVariable ("Bleeding_gmcp", fulldata.Vitals.bleeding)

end -- ShowHealth

function ShowHealthTeam ()

  SetVariable ("HP_Team_1", fulldata.Team.hp)
  SetVariable ("Bleed_Team_1", fulldata.Team..blood)
  SetVariable ("Pos_Team_1", fulldata.Team..pos)

end -- ShowHealthTeam

]]>
</script>
</muclient>


I get this error when loading the plugin: [string "Plugin"]:51: bad argument #2 to 'SetVariable' (string expected, got nil)

This is the data I receive when gmpcdebug 1 is set:
Char.Vitals { "hp":100, "mana":100, "fatigue":0, "bleeding":0 }
Char.Team [{"blood":"0", "hp":"100", "leader":"0", "name":"Chiara", "pos":"0"}, {"blood":"0", "hp":"100", "leader":"1", "name":"Nicole", "pos":"1"}]


So I'm not sure how to modify the CallPlugin for Char.Team as it contains the same stats for different team members. Supposedly Char.Vitals and Char.Team should be pulled together since they both have Char as the top level. Any ideas?
Amended on Thu 02 Oct 2014 09:34 PM by Solara
Australia Forum Administrator #20

  SetVariable ("Bleed_Team_1", fulldata.Team..blood)


What are the two dots?
Australia Forum Administrator #21
Try doing a tprint for debugging. It might become clearer:


require "tprint"
tprint (fulldata)
USA #22
Nick Gammon said:


  SetVariable ("Bleed_Team_1", fulldata.Team..blood)


What are the two dots?


Bad typing on my part, but despite correcting it I still get the same error code:

[string "Plugin"]:50: bad argument #2 to 'SetVariable' (string expected, got nil)

There's just no data in Char.Team.hp I guess. I know the data's there since gmcpdebug 1 shows it as listed above.

And this what I get when I enable tprint and have it print the fulldata.

"Team":
  1:
    "name"="Chiara"
    "pos"="0"
    "leader"="0"
    "hp"="100"
    "blood"="0"
  2:
    "name"="Nicole"
    "pos"="1"
    "leader"="1"
    "hp"="100"
    "blood"="0"
"Vitals":
  "fatigue"="0"
  "mana"="50"
  "hp"="100"
  "bleeding"="0"


How do I grab that nested data within Team.1 and Team.2 using the GMCP_Demo.xml code?
Amended on Thu 02 Oct 2014 10:44 PM by Solara
USA #23
Solara said:
Team.1 and Team.2

You might want to try calling them Team[1] and Team[2] instead. :)
USA #24
Nick Gammon said:
Hi Twisol!

How's the new client going?

Between work and a double-major at college, I haven't been able to spend any time on it for a long time now. It's in a usable state (full Telnet functionality, ANSI rendering with word wrapping, multi-line input), but the alias support is minimal, and there is no trigger functionality yet.

I should probably just upload it somewhere and let people try it. Unlike my original design, there's no need for a third-party proxy server: it runs entirely on your computer. The only requirement is that the MUD you're connecting to must have a WebSocket gateway, like the IRE games do.
USA #25
Twisol said:

Solara said:
Team.1 and Team.2

You might want to try calling them Team[1] and Team[2] instead. :)


Haha, awesome, that worked! Thanks for the help Nick and Twisol!
USA #26
Okay so on a similar note, I'm trying to set variables for up to 5 team members if the data is there.

I use this to set if if the Name for a team member # is not nil, but I get an error:

attempt to index field '?' (a nil value)
stack traceback:


If there are 2 team members, it seems to point to the line to set variables for Team[3] data as being nil.

Here's the portion of the plugin that errors out:
function ShowHealthTeam ()

if fulldata.Team[1].name ~= nil then
  SetVariable ("T1_Name", fulldata.Team[1].name)
  SetVariable ("T1_HP", fulldata.Team[1].hp)
  SetVariable ("T1_Blood", fulldata.Team[1].blood)
  SetVariable ("T1_Pos", fulldata.Team[1].pos)
end -- if

if fulldata.Team[2].name ~= nil then
  SetVariable ("T2_Name", fulldata.Team[2].name)
  SetVariable ("T2_HP", fulldata.Team[2].hp)
  SetVariable ("T2_Blood", fulldata.Team[2].blood)
  SetVariable ("T2_Pos", fulldata.Team[2].pos)

if fulldata.Team[3].name ~= nil then
  SetVariable ("T3_Name", fulldata.Team[3].name)
  SetVariable ("T3_HP", fulldata.Team[3].hp)
  SetVariable ("T3_Blood", fulldata.Team[3].blood)
  SetVariable ("T3_Pos", fulldata.Team[3].pos)
end -- if
end -- if


Do I have the syntax correct there?

I've tried these variations with the same error:

if not fulldata.Team[3].name then

if fulldata.Team[3].name ~= nil or "" then
Amended on Fri 03 Oct 2014 10:52 PM by Solara
USA #27
Try checking fulldata.Team[1] instead of fulldata.Team[1].name (for each team though, not just the 1st). If there is no 1st team, you'll basically have nil.name, which will cause your error.
USA #28
Awesome, thanks again! That seems to have worked.

NOW just to play around and try to make for cleaner code, is it possible to do this? Instead of 8 instances of the same if/then groups, do a loop and replace the variable name with the number?

for x=1,8 do

if fulldata.Team&[x] ~= nil then
  SetVariable ("Ti_Name", fulldata.Team[x].name)
  SetVariable ("Ti_HP", fulldata.Team[x].hp)
  SetVariable ("Ti_Blood", fulldata.Team[x].blood)

  if fulldata.Team[x].pos == "0" then SetVariable ("Tx_Pos", "Front")
  else SetVariable ("Tx_Pos", "Back")
  end
end -- if
end


What I wrote there doesn't work and I suspect it's not replacing the numbers for i into the variables.
Amended on Sat 04 Oct 2014 02:34 PM by Solara
USA #29
Oh and another question. The GMCP_Demo.xml plugin seems to maintain the table of data grabbed from the mud GMCP. So when a team member is no longer in the team, the plugin still seems to send old data?

I am almost sure that the MUD is not sending old data because gmcpdebug 1 or 2 shows the correct data.

Is there a command I can put into the plugin for it to erase/refresh the table of GMCP data each time it runs?
USA #30
Make sure you escape any [i] you put in your code before you paste it into the forum, or you'll see weird italicized text like what happened in your post. Just replace [ with \[ and it'll display properly.

At any rate, it is a good idea to do a loop for this kind of thing. The reason "Ti_Name" doesn't turn into "T1_Name" is because the 'i' is in a string. Strings are just characters, and the scripting language doesn't change strings at all. You have to format the string in other ways. One way is
"T"..i.."_Name"
Another, which personally I prefer, is
("T%u_Name"):format(i)
Amended on Sat 04 Oct 2014 02:45 AM by Twisol
USA #31
Solara said:
Is there a command I can put into the plugin for it to erase/refresh the table of GMCP data each time it runs?


Put this just after the -- print ("GMCP packet = ", text) line:
if text == "Char.Team" then
  fulldata.Team = nil
end
USA #32
So I was able to clean up the code and use a loop to define the variables, and it seems to be working as far as I can tell:

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

<muclient>
<plugin
   name="Xyllo_Vitals"
   author="LP"
   id="b9171e77bc4ed6d2926eebdc"
   language="Lua"
   purpose="GMCP Vitals for Xyllomer"
   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.Team" then
         fulldata.Team = nil
      end
      if (text == "Char.Vitals" or text == "Char.Team") 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
      if text == "Char.Team" then
        ShowHealthTeam ()
      end -- if
      end
   end
end


function ShowHealth ()

  SetVariable ("HP_gmcp", fulldata.Vitals.hp)
  SetVariable ("Mana_gmcp", fulldata.Vitals.mana)
  SetVariable ("Fatigue_gmcp", fulldata.Vitals.fatigue)
  SetVariable ("Bleeding_gmcp", fulldata.Vitals.bleeding)

end -- ShowHealth

function ShowHealthTeam ()

for x=1,8 do

if fulldata.Team[x] ~= nil then
  SetVariable ("T"..x.."_Name", fulldata.Team[x].name)
  SetVariable ("T"..x.."_HP", fulldata.Team[x].hp)
  SetVariable ("T"..x.."_Blood", fulldata.Team[x].blood)

  if fulldata.Team[x].pos == "0" then SetVariable ("T"..x.."_Pos", "Front")
  else SetVariable ("T"..x.."_Pos", "Back")
  end

end -- if
end -- loop
end -- ShowHealthTeam


]]>
</script>
</muclient>


But adding "if text == "Char.Team" then fulldata.Team = nil end" didn't seem to have erased the table? Unless I need to reset all the variables that I set as well? I'm not sure the variables I set for prevous team members carry over with each update of the gmcp data/table?
Amended on Sat 04 Oct 2014 02:35 PM by Solara
USA #33
Solara said:

But adding "if text == "Char.Team" then fulldata.Team = nil end" didn't seem to have erased the table? Unless I need to reset all the variables that I set as well? I'm not sure the variables I set for prevous team members carry over with each update of the gmcp data/table?

Sorry, you're right - my error. The table itself will be cleared and repopulated every time, and you can remove the code I suggested. The problem is, indeed, that the variables from a previous Team update stay set if you don't alter them in the future.

Does your MUD have a maximum to the number of teams you can be notified of? If so, you can just write a second loop before the first that clears the variables for all possible teams. DeleteVariable("T"..i.."_name"), etc. would do it.
USA #34
Maybe it's the mud still sending old data (though when I'm not teamed with anyone, gmcpdebug 1 or 2 only shows Char.Vitals and no Char.Team data).

I added this to the beginning of the plugin:
for i=1,8 do
  DeleteVariable ("T"..i.."_Name")
  DeleteVariable ("T"..i.."_HP")
  DeleteVariable ("T"..i.."_Blood")
  DeleteVariable ("T"..i.."_Pos")
end -- loop

function OnPluginBroadcast (msg, id, name, text)


But still getting old/static previous team member data.
Amended on Sat 04 Oct 2014 05:20 PM by Solara
USA #35
If you put code outside of any function, it will only be called once, when the plugin loads. You need to put it in ShowHealthTeam.
USA #36
Hmm I seem to have been wrong in one of my previous statements.
When I removed myself from a team, gmcpdebug 1 shows only Char.Vitals. But gmcpdebug 2 shows old Char.Team data still.

So I guess the mud's not updating the Char.Team and it's not the plugin's fault?

Addendum: I just tried a ReloadPlugin ("b9171e77bc4ed6d2926eebdc") command (via an alias I type, not part of plugin) to test and it did seem to remove old Char.Team data. So could it be the GMPC_Handler plugin that's maintaining old team data?

Btw, moving the DeleteVariable routines down to the ShowHealthTeam function did not seem to update Char.Teams. So what's ReloadPlugin doing that I am not doing within the plugin? Clearing out GMPC_Handler old table somewhere?
Amended on Sat 04 Oct 2014 05:42 PM by Solara
USA #37
Reloading a plugin clears all of its "SetVariable" variables. (This is not true in all cases, but is certainly true of this plugin.)

Can you post the full plugin again, with the DeleteVariable loop inside ShowHealthTeam?
Amended on Sat 04 Oct 2014 05:36 PM by Twisol
USA #38
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="Xyllo_Vitals"
   author="LP"
   id="b9171e77bc4ed6d2926eebdc"
   language="Lua"
   purpose="GMCP Vitals for Xyllomer"
   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.Vitals" or text == "Char.Team") 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
      if text == "Char.Team" then
        ShowHealthTeam ()
      end -- if
      end
   end
end


function ShowHealth ()

  SetVariable ("HP_gmcp", fulldata.Vitals.hp)
  SetVariable ("Mana_gmcp", fulldata.Vitals.mana)
  SetVariable ("Fatigue_gmcp", fulldata.Vitals.fatigue)
  SetVariable ("Bleeding_gmcp", fulldata.Vitals.bleeding)

end -- ShowHealth

function ShowHealthTeam ()

for x=1,8 do
  DeleteVariable ("T"..x.."_Name")
  DeleteVariable ("T"..x.."_HP")
  DeleteVariable ("T"..x.."_Blood")
  DeleteVariable ("T"..x.."_Pos")
end -- loop

for x=1,8 do

if fulldata.Team[x] ~= nil then
  SetVariable ("T"..x.."_Name", fulldata.Team[x].name)
  SetVariable ("T"..x.."_HP", fulldata.Team[x].hp)
  SetVariable ("T"..x.."_Blood", fulldata.Team[x].blood)

  if fulldata.Team[x].pos == "0" then SetVariable ("T"..x.."_Pos", "Front")
  else SetVariable ("T"..x.."_Pos", "Back")
  end

end -- if
end -- loop
end -- ShowHealthTeam


]]>
</script>
</muclient>
USA #39
It appears that the Aardwolf GMCP plugin does in fact "remember" previous data sent by the server, making it impossible to detect the removal of GMCP data:

Quote:
Aardwolf GMCP Handler.

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.

It may be simpler for you to use my GMCP.plugin, which leaves such "remembering" up to the user, and modify my RoomName.plugin. In fact, here is a modified RoomName.plugin/scripts/main.lua to match what we've done so far:

local PPI = require("ppi")

local function ShowHealth(message, Vitals)
  SetVariable("HP_gmcp", Vitals.hp)
  SetVariable("Mana_gmcp", Vitals.mana)
  SetVariable("Fatigue_gmcp", Vitals.fatigue)
  SetVariable("Bleeding_gmcp", Vitals.bleeding)
end

local function ShowHealthTeam(message, Team)
  for i=1,8 do
    if Team[i] then
      SetVariable("T"..i.."_Name", Team[i].name)
      SetVariable("T"..i.."_HP", Team[i].hp)
      SetVariable("T"..i.."_Blood", Team[i].blood)

      if Team[i].pos == "0" then
        SetVariable("T"..i.."_Pos", "Front")
      else
        SetVariable("T"..i.."_Pos", "Back")
      end
    else
      DeleteVariable("T"..i.."_Name")
      DeleteVariable("T"..i.."_HP")
      DeleteVariable("T"..i.."_Blood")
      DeleteVariable("T"..i.."_Pos")
    end
  end
end

-- (ID, on_success, on_failure)
PPI.OnLoad("29a4c0721bef6ae11c3e9a82", function(gmcp)
  gmcp.Listen("Char.Vitals", ShowHealth)
  gmcp.Listen("Room.Info", ShowHealthTeam)
end, function(reason)
  -- Do nothing if GMCP.plugin is not present.
end)

function OnPluginListChanged()
  PPI.Refresh()
end
Amended on Sat 04 Oct 2014 06:35 PM by Twisol
USA #40
Trying to switch over to your plugins but I'm a bit confused.

Do I download and enable both the GMCP plugin AND the modified RoomInfo plugin?

They both contain the same filenames (plugger.xml, PPI.lua, plugin.xml, main.lua).
I renamed RoomInfo's plugin.xml to xyllo.xml, but replacing GMCP's main.lua with the modified main.lua with what you typed above errors out.

It's a bit hard to decipher with the plugins pulling from PPI.lua, plugger.xml, plugin.xml, main.lua.

If I need to keep both GMCP and RoomInfo plugins enabled, which files for RoomInfo contains the link to 'main.lua' that I can rename so I can put both GMCP's main.lua and RoomInfo's renamed main.lua into the same subfolder?

Edit: Okay so figuring that maybe it doesn't look for filename but the plugin ID, i just reanmed RoomInfo's main.lua to xyllo.lua and put it in the script subfolder. No errors, but my triggers are not finding the info - gets nil.

I have my triggers pull from plugin ID for RoomInfo's main.lua: ("e94f6bd8509a2b00d10cb226",
Amended on Sat 04 Oct 2014 07:56 PM by Solara
USA #41
Yes, you need everything, and both plugins need to be enabled. Just drop the GMCP.plugin and RoomName.plugin directories into your plugins location. There's no need to modify GMCP.plugin at all, and you only need to add each one's plugin.xml to MUSHclient from the Plugins dialog.

See here for a discussion of the "structured plugin" format that my plugins use: http://www.gammon.com.au/forum/?id=10011 . Not everything is in the first post, so you may need to read through a little bit.

The upshot is that plugins.xml is just metadata, and the plugin scripts are in the scripts/ directory. You can ignore libraries/ files - that's just used for static libraries used by the plugin. (This is why ppi.lua appears in both GMCP.plugin and RoomName.plugin: GMCP and RoomName use the PPI module to communicate, so they both need the library.)

There's no need to rename anything. Just replace the contents of RoomName.plugin's main.lua with the code I posted previously. You probably also want to edit some of the metadata in RoomName.plugin/plugin.xml, like the author, name, unique id.
Amended on Sat 04 Oct 2014 07:57 PM by Twisol
USA #42
Okay so copying all the folders straight over and not renaming anything, plugins are working BUT none of the char.team info is being pulled correctly (no errors or nil). It thinks everything is nil for char.team.

What you wrote here, does it mean if Team[x] is NOT nil, then set?

    if Team[x] then
      SetVariable("T"..x.."_Name", Team[x].name)
      SetVariable("T"..x.."_HP", Team[x].hp)
      SetVariable("T"..x.."_Blood", Team[x].blood)


Bah I don't know how to escape out the [ i ] so changing it to x.
Amended on Sat 04 Oct 2014 08:10 PM by Solara
USA #43
You're making your job out to be much more invasive than it needs to be. :) The idea of the "structured plugin" is to make it easy to change only the parts that need to be changed. Our region of concern is RoomName.plugin/scripts/main.lua, as that is where the plugin's main code lives. It's the equivalent of the Lua code you already saw in GMCP_Demo.xml, but without the XML wrapper.

The XML wrapper itself is one directory up, and is called plugin.xml. This is what it should always be named; if you want to rebrand it, rename RoomName.plugin to WhateverYourNameIs.plugin. This file contains plugin metadata, like the author and your plugin's unique ID. This is the ID you'd use in GetPluginVariable, because - after all - you're going to be asking this plugin for its variables.

Everything else is support. Plugger.xml handles loading main.lua and supports using require() to load scripts in scripts/ and libraries. It's totally generic and never needs to be modified.

PPI.lua is a library that supports communications between plugins. GMCP.plugin uses it to expose an interface for other plugins to be notified of GMCP messages. RoomName.plugin uses it to tell GMCP.plugin it wants to be told about Room.Name messages. PPI.lua never needs to be modified.
Amended on Sat 04 Oct 2014 08:06 PM by Twisol
USA #44
Solara said:
What you wrote here, does it mean if Team is NOT nil, then set?

Yes, it's a convenient shorthand. (Technically, if Team is not nil and not false.)

Solara said:
It thinks everything is nil for char.team.

Did you replace the original contents of RoomName.plugin/scripts/main.lua with the script I posted previously? Don't rename it to xyllo.lua - it needs to be called main.lua.
USA #45
Yeah extracted over all files from GMCP.plugin.zip and RoomName.plugin.zip.

Copy/pasted what you posted above for the revised main.lua in /plugins/RoomName.plugin/scripts.

Changed all my triggers to GetPluginVariable ("e94f6bd8509a2b00d10cb226".

My test alias should send all team member's info but it returns a message indicating T1_Name is nil.

It does pull the Char.Vitals info correctly though.
Amended on Sat 04 Oct 2014 08:25 PM by Solara
Australia Forum Administrator #46
Post your new setup if you want help with it. What is sending and what is receiving.
USA #47
In no particular order, try these things:

* Make sure the original Aardwolf GMCP plugin is not loaded in MUSHclient.

* Use the GMCP DEBUG alias to enable/disable GMCP output.

* Add print("Hello!") to ShowHealthTeam to make sure it's getting called at all.

* Restart MUSHclient.
USA #48
Only GMCP plugin and RoomInfo plugins are active. Reloaded Mushclient, added this line to RoomInfo's main.lua:

local PPI = require("ppi")

local function ShowHealth(message, Vitals)
  SetVariable("HP_gmcp", Vitals.hp)
  SetVariable("Mana_gmcp", Vitals.mana)
  SetVariable("Fatigue_gmcp", Vitals.fatigue)
  SetVariable("Bleeding_gmcp", Vitals.bleeding)
end

local function ShowHealthTeam(message, Team)
print ("hello!")
  for x=1,8 do
    if Team[x] then
      SetVariable("T"..x.."_Name", Team[x].name)
      SetVariable("T"..x.."_HP", Team[x].hp)
      SetVariable("T"..x.."_Blood", Team[x].blood)

      if Team[x].pos == "0" then
        SetVariable("T"..x.."_Pos", "Front")
      else
        SetVariable("T"..x.."_Pos", "Back")
      end
    else
      DeleteVariable("T"..x.."_Name")
      DeleteVariable("T"..x.."_HP")
      DeleteVariable("T"..x.."_Blood")
      DeleteVariable("T"..x.."_Pos")
    end
  end
end

-- (ID, on_success, on_failure)
PPI.OnLoad("29a4c0721bef6ae11c3e9a82", function(gmcp)
  gmcp.Listen("Char.Vitals", ShowHealth)
  gmcp.Listen("Room.Info", ShowHealthTeam)
end, function(reason)
  -- Do nothing if GMCP.plugin is not present.
end)

function OnPluginListChanged()
  PPI.Refresh()
end


Does NOT print "hello!". gmcpdebug still shows incoming data with both char.vitals and char.team.

My scripts to show char.vitals to a miniwindow are still working. Does not show any char.team data.
Amended on Sat 04 Oct 2014 08:40 PM by Solara
USA #49
Ahh, my fault. I see the problem.

gmcp.Listen("Room.Info", ShowHealthTeam)

Do you?
USA #50
Interesting enough, when I force someone to leave the team, or they rejoin, then the script kicks in and sends the "hello!" - but data is still nil for char.team variables.

The mud DOES send data every few secs and after every command that gets sent to the mud so it's rather weird that this plugin only seems to kick in when someone joins or leaves the team?
USA #51
Haha, yeah that was the problem. I didn't lok very carefully there. Thanks!
USA #52
Okay well, we're back to the original problem with the aardwolf plugin again. Does NOT seem that the char.team data gets updated either for this one.

With the aardwolf plugin, if I sent a ReloadPlugin command for the GMCP_Demo plugin (not the GMCP_Handler), then it gets updated.

Very bizarre because this plugin should delete/nil out the variables - and my script pulls the variables directly from the plugins - i do not set any global variables that I'm forgetting to update by mistake.
USA #53
I'd like to take a look at this myself. What MUD are you developing against?
USA #54
Well I might just have to live with this quirk, unless someone can figure it out - may need to put in some Reloadplugin commands for some triggers.

Updated main.lua for RoomInfo.plugin

local PPI = require("ppi")

local function ShowHealth(message, Vitals)
  SetVariable("HP_gmcp", Vitals.hp)
  SetVariable("Mana_gmcp", Vitals.mana)
  SetVariable("Fatigue_gmcp", Vitals.fatigue)
  SetVariable("Bleeding_gmcp", Vitals.bleeding)
end

local function ShowHealthTeam(message, Team)
  for x=1,8 do
    if Team[x] then
      SetVariable("T"..x.."_Name", Team[x].name)
      SetVariable("T"..x.."_HP", Team[x].hp)
      SetVariable("T"..x.."_Blood", Team[x].blood)

      if Team[x].pos == "0" then
        SetVariable("T"..x.."_Pos", "Front")
      else
        SetVariable("T"..x.."_Pos", "Back")
      end
    else
      DeleteVariable("T"..x.."_Name")
      DeleteVariable("T"..x.."_HP")
      DeleteVariable("T"..x.."_Blood")
      DeleteVariable("T"..x.."_Pos")
    end
  end
end

-- (ID, on_success, on_failure)
PPI.OnLoad("29a4c0721bef6ae11c3e9a82", function(gmcp)
  gmcp.Listen("Char.Vitals", ShowHealth)
  gmcp.Listen("Char.Team", ShowHealthTeam)
end, function(reason)
  -- Do nothing if GMCP.plugin is not present.
end)

function OnPluginListChanged()
  PPI.Refresh()
end



Most recent GMCP_Demo.xml using Aardwolf GMPC_Handler.xml
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>

<muclient>
<plugin
   name="Xyllo_Vitals"
   author="LP, modified from Nick Gammon"
   id="b9171e77bc4ed6d2926eebdc"
   language="Lua"
   purpose="GMCP Vitals for Xyllomer"
   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.Vitals" or text == "Char.Team") 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
      if text == "Char.Team" then
        ShowHealthTeam ()
      end -- if
      end
   end
end


function ShowHealth ()

  SetVariable ("HP_gmcp", fulldata.Vitals.hp)
  SetVariable ("Mana_gmcp", fulldata.Vitals.mana)
  SetVariable ("Fatigue_gmcp", fulldata.Vitals.fatigue)
  SetVariable ("Bleeding_gmcp", fulldata.Vitals.bleeding)

end -- ShowHealth

function ShowHealthTeam ()

for x=1,8 do

if fulldata.Team[x] ~= nil then
  SetVariable ("T"..x.."_Name", fulldata.Team[x].name)
  SetVariable ("T"..x.."_HP", fulldata.Team[x].hp)
  SetVariable ("T"..x.."_Blood", fulldata.Team[x].blood)

  if fulldata.Team[x].pos == "0" then SetVariable ("T"..x.."_Pos", "Front")
  else SetVariable ("T"..x.."_Pos", "Back")
  end

end -- if
end -- loop
end -- ShowHealthTeam


]]>
</script>
</muclient>
USA #55
Twisol said:

I'd like to take a look at this myself. What MUD are you developing against?


Xyllomer.mud.de.3000
USA #56
While I wait for my password, could you export the aliases/triggers you're using to access the plugin's variables and paste them here?

[EDIT]: Just FYI, you can go to the Edit -> Convert Clipboard Forum Codes menu in MUSHclient to convert any [i]-like things that you've copied to \[i].
Amended on Sat 04 Oct 2014 09:07 PM by Twisol
USA #57
This is the main miniwindow script where I display the plugin variables. This action gets executed by several triggers.

WindowDelete ("battle")
win = "battle" .. GetPluginID ()
WindowCreate (win, 0, 0, 180, 210, miniwin.pos_bottom_right, 0, ColourNameToRGB("blue"))
WindowShow (win,  true)

WindowFont (win, "f", "Trebuchet MS", 12, true, false, true, false)
WindowFont (win, "f1", "Trebuchet MS", 12, true, false, false, false)
WindowText (win, "f", "Battle Status", 45, 5, 0, 0, ColourNameToRGB ("yellow"), false)

WindowText (win, "f1", "Weap:  "..GetVariable("bweapon"), 10, 35, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", "HP:  "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "HP_gmcp")..", "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "Bleeding_gmcp"), 10, 55, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", "Mana:  "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "Mana_gmcp"), 10, 75, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", "Fatigue:  "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "Fatigue_gmcp"), 10, 95, 0, 0, ColourNameToRGB ("yellow"), false)

if GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Name") == nil then
WindowText (win, "f1", "-NOT TEAMED-", 10, 125, 0, 0, ColourNameToRGB ("white"), false)
end

if GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Name") == "Pringle" then
WindowText (win, "f1", GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_Name")..": "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_HP")..", "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_Blood"), 10, 118, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_Name")..": "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_Pos"), 10, 138, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", "Me:  "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Pos"), 10, 158, 0, 0, ColourNameToRGB ("yellow"), false)

elseif GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_Name") == "Pringle" then
WindowText (win, "f1", GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Name")..": "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_HP")..", "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Blood"), 10, 118, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Name")..": "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Pos"), 10, 138, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", "Me:  "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_Pos"), 10, 158, 0, 0, ColourNameToRGB ("yellow"), false)

elseif GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T3_Name") == "Pringle" then
WindowText (win, "f1", GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Name")..": "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_HP")..", "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Blood"), 10, 118, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_Name")..": "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_HP")..", "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_Blood"), 10, 138, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", "Me:  "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T3_Pos"), 10, 158, 0, 0, ColourNameToRGB ("yellow"), false)

elseif GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T4_Name") == "Pringle" then
WindowText (win, "f1", GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Name")..": "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_HP")..", "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Blood"), 10, 118, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_Name")..": "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_HP")..", "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T2_Blood"), 10, 138, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T3_Name")..": "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T3_HP")..", "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T3_Blood"), 10, 138, 0, 0, ColourNameToRGB ("yellow"), false)
WindowText (win, "f1", "Me:  "..GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T4_Pos"), 10, 158, 0, 0, ColourNameToRGB ("yellow"), false)

else
end
USA #58
This is just a testing script to let me know if the variables are there or not:

for i=1,8 do
if GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T"..i.."_Name") ~= nil then
TiName = GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T"..i.."_Name")
TiHP = GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T"..i.."_HP")
TiBlood = GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T"..i.."_Blood")
TiPos = GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T"..i.."_Pos")

Note (i.."- "..TiName.." | "..TiPos.." | Health: "..TiHP.." | Blood: "..TiBlood)

end -- if
end -- loop

if GetPluginVariable ("b9171e77bc4ed6d2926eebdc", "T1_Name") == nil then
Note ("Not Teamed")
end


Now the mud does have known problems with it's GMCP data - small mud with not many active admins, so not sure if it'll ever get fixed.

1st quirk - depending on who's in the team all team members will have -1HP listed (seems to occur when wolves/elementals are in team only).

Now when I said earlier that the ReloadPlugin command seemed to fix/update the char.team correctly - that is true for most situations, but when an elemental/wolf is put into the team, when they leave the team, it doesn't look like the char.team is updated ever even after disbanding the team - it shows phantom 3rd teamemember - quirk of gmcp from mud likely then). What's weird is (went back to using aardwolf plugin for testing - it shows only 2 team members when using debug 1, but shows 3 when using debug 2. Anyways, not sure anyone could figure any of this out with a not-completely bug-free mud gmcp data stream.
Amended on Sat 04 Oct 2014 09:42 PM by Solara
USA #59
Unless you changed the ID of RoomName.plugin in its XML file, you need to change "b9171e77bc4ed6d2926eebdc" to "e94f6bd8509a2b00d10cb226".
USA #60
Twisol said:

Unless you changed the ID of RoomName.plugin in its XML file, you need to change "b9171e77bc4ed6d2926eebdc" to "e94f6bd8509a2b00d10cb226".


Oh I had gone back to aardwolf plugins to do some testing when I pasted those codes - have 2 separate game files for each plugin.

And an update - seems it's not just wolf/elemental, but even other players - the char.team is NOT updated even after using the ReloadPlugin. The ReloadPlugin command seemed to help when it was just 2 people in the team, but 3 or more I think it doesn't help. So the problem is likely on the MUD side??
USA #61
What do you see when GMCP DEBUG is active? Does the output make sense, or does it also exhibit the same issue?
USA #62
Okay so I went back to using your plugin Twisol and now everything seems to be updating fine!

Switched between the two plugins several times and aardwolf consistently does NOT update char.team but yours does.

But there are problems for both plugins when it comes to elementals/wolves being in the team. With aardwolf plugin, when they enter the team, all HP for team members is shown as -1HP. The non-updating of the char.team does not depend on who is in the team.

With your plugin Twisol, I get the following message with elemental/wolf in the team:

Run-time error
Plugin: XylloVitals (called from world: Xyllomer)
Function/Sub: PPI_INVOKE called by Plugin XylloVitals
Reason: Executing plugin XylloVitals sub PPI_INVOKE
...ient\worlds\plugins\RoomName.plugin\scripts\main.lua:13: bad argument #2 to 'SetVariable' (string expected, got nil)
stack traceback:
        [C]: in function 'SetVariable'
        ...ient\worlds\plugins\RoomName.plugin\scripts\main.lua:13: in function 'func'
        ...ent\worlds\plugins\RoomName.plugin\libraries\ppi.lua:379: in function <...ent\worlds\plugins\RoomName.plugin\libraries\ppi.lua:362>


Here's the full debug when elementals enter the team for Twisol's plugin:

"message"="Char.Vitals"
"data":
  "fatigue"=0
  "mana"=100
  "hp"=100
  "bleeding"=0

"message"="Char.Team"
"data":
  1:
    "name"="Kami"
    "pos"="0"
    "leader"="0"
    "hp"="100"
    "blood"="0"
  2:
    "name"="An earth elemental"
    "pos"="0"
    "leader"="0"
    "hp"="100"
    "blood"="0"
  3:
    "name"="Pringle"
    "pos"="1"
    "leader"="1"
    "hp"="100"
    "blood"="0"

"message"="Char.Team"
"data":
  1:
    "pos"="0"
    "leader"="0"
    "hp"="-1"
    "blood"="0"
  2:
    "pos"="0"
    "leader"="0"
    "hp"="-1"
    "blood"="0"
  3:
    "pos"="1"
    "leader"="1"
    "hp"="-1"
    "blood"="0"


The mud seems to send two batches of char.team data - first one is correct, second one has -1 for HP and name appears to be nil on the second batch. So with aardwolf's plugin because old char.team.name is not wiped, it still allows my script to run and shows -1HP for each. With Twisol's more dynamic plugin, since name is now 'nil', it errors out - though I'm not sure why since the routine to set variables is checking for nil.
Amended on Sat 04 Oct 2014 11:03 PM by Solara
USA #63
So the MUD expects you to remember at least some details about the team, such as the team members' names, so it doesn't have to repeat itself.

Assuming the 'name' field is the only one that behaves this way, change this line:
SetVariable("T"..i.."_Name", Team[i].name)
to this:
if Team[i].name then
  SetVariable("T"..i.."_Name", Team[i].name)
end
USA #64
And since 'hp' is inexplicably -1, do a similar thing here:
if Team[i].hp ~= "-1" then
  SetVariable("T"..i.."_HP", Team[i].hp)
end

You probably see the pattern. At this point, we're just dealing with the idiosyncrasies of the MUD, rather than any actual bugs in the plugins.
Amended on Sat 04 Oct 2014 10:57 PM by Twisol
USA #65
Yeah we're pretty much dealing with a MUD error now. Plugin works great otherwise except for that specific situation.

Now changing main.lua to this, I only ever get char.vitals and NO char.team ever gets set to variables I can pull.

local PPI = require("ppi")

local function ShowHealth(message, Vitals)
  SetVariable("HP_gmcp", Vitals.hp)
  SetVariable("Mana_gmcp", Vitals.mana)
  SetVariable("Fatigue_gmcp", Vitals.fatigue)
  SetVariable("Bleeding_gmcp", Vitals.bleeding)
end

local function ShowHealthTeam(message, Team)
  for x=1,8 do
    if Team[x] then
      SetVariable("T"..x.."_Blood", Team[x].blood)

      if Team[x].name then
        SetVariable("T"..x.."_HP", Team[x].name)
      end
      
      if Team[x].hp ~= "-1" then
        SetVariable("T"..x.."_HP", Team[x].hp)
      end

      if Team[x].pos == "0" then
        SetVariable("T"..x.."_Pos", "Front")
      else
        SetVariable("T"..x.."_Pos", "Back")
      end
    else
      DeleteVariable("T"..x.."_Name")
      DeleteVariable("T"..x.."_HP")
      DeleteVariable("T"..x.."_Blood")
      DeleteVariable("T"..x.."_Pos")
    end
  end
end

-- (ID, on_success, on_failure)
PPI.OnLoad("29a4c0721bef6ae11c3e9a82", function(gmcp)
  gmcp.Listen("Char.Vitals", ShowHealth)
  gmcp.Listen("Char.Team", ShowHealthTeam)
end, function(reason)
  -- Do nothing if GMCP.plugin is not present.
end)

function OnPluginListChanged()
  PPI.Refresh()
end


Okay noticed my typing error after I posted. Works now!

if Team[x].name then
        SetVariable("T"..x.."_HP", Team[x].name)
      end


should be:

if Team[x].name then
        SetVariable("T"..x.."_Name", Team[x].name)
      end
Amended on Sat 04 Oct 2014 11:15 PM by Solara
USA #66
[EDIT]: Ah, that would do it. Ignore the below.

Use tprint to print out the data that you're working with in the loop. Put this before the loop inside ShowHealthTeam.
local tprint = require("tprint")
tprint(Team)
Amended on Sat 04 Oct 2014 11:18 PM by Twisol
USA #67
Thanks for all your help Twisol, works very nicely now.

A minor cosmetic question for the miniwindows so the words can fit better. How do I query the TName variable I just set in the plugin to screen for any anmes with 'elemental' in it, and then reassign it so it does not contain the 'elemental' word?

I tried with this command but it doesn't seem to work?

      if Team[x].name then
        SetVariable("T"..x.."_Name", Team[x].name)
        string.gsub ("T"..x.."_Name", "elemental", "")
      end
Amended on Sat 04 Oct 2014 11:30 PM by Solara
USA #68
Changed to this but still not working.

      if Team[x].name then
        SetVariable("T"..x.."_Name", Team[x].name)
        string.gsub (GetVariable("T"..x.."_Name"), "elemental", "")
      end
USA #69
You can't very well change an e-mail you've already sent. Put the gsub call before the SetVariable call.
USA #70
I'm probably not understanding, but this didn't seem to work either. No errors in script though and everything still works, just no truncation of any elemental team names.

      if Team[x].name then
        string.gsub (Team[x].name, "elemental", "")
        SetVariable("T"..x.."_Name", Team[x].name)
      end


tried this variation also:

      if Team[x].name then
        if string.find (Team[x].name, "elemental") then
          string.gsub (Team[x].name, "elemental", "")
        end
        SetVariable("T"..x.."_Name", Team[x].name)
      end


Not sure if Team[x] is considered a string or not. And if not, I'd have to set it to a variable first before substituting it - which is what I did with my original attempt?
USA #71
In Lua, functions cannot modify their parameters unless they are tables. Copies are made instead. Since strings aren't tables, the only way gsub could do its job is to have its result be its return value.

I'm being coy because this, in particular, is fundamental. You should understand what's happening, not merely be told about it.

There's no shame in asking once more if you still don't understand. :)

[EDIT]: I will point out, though, that Team, Team[i], and Team[i].name all give different values. The first and second give tables, though the first is treated as an array. The third gives a string.
Amended on Sun 05 Oct 2014 12:43 AM by Twisol
USA #72
Haha such a dumb mistake. Works now.

      if Team[x].name then
        Team[x].name = string.gsub(Team[x].name, "elemental", "")
        SetVariable("T"..x.."_Name", Team[x].name)
      end