Neophyte in need of help regarding bad argument table expected, got string

Posted by Uafasach on Tue 31 Jul 2018 06:16 PM — 8 posts, 26,105 views.

#0
Making an attempt to get the gmcp mapper working with the Family LAN MUD is proving to me just how lacking in LUA knowledge I currently am.
decided to finally break down and ask here if someone can point me in the right direction to figuring this out, or even just point and laugh at
the obivous thing I'm missing.. but still point me in the direction of fixing it. :)

Anyways, fresh install of:

Muschlient 5.05 , GMCP_handler_NJG 1.0 , GMCP_Mapper 1.70, muschclient mapper ver 2.6

I get the error:

   
    Run-time error
Plugin: GMCP_Mapper (called from world: CoffeeTest)
Function/Sub: OnPluginBroadcast called by Plugin GMCP_Mapper
Reason: Executing plugin GMCP_Mapper sub OnPluginBroadcast
[string "Plugin: GMCP_Mapper"]:1273: bad argument #1 to 'concat' (table expected, got string)
stack traceback:
        [C]: in function 'concat'
        [string "Plugin: GMCP_Mapper"]:1273: in function 'f'
        [string "Plugin: GMCP_Mapper"]:1366: in function <[string "Plugin: GMCP_Mapper"]:1313>


After this, I made some quick additions to GMCP_Mapper's OnPluginBroadcat . (Please don't laugh too hard.)

function OnPluginBroadcast (msg, id, name, text)
  if id == "85f72d0e263d75df7bde6f00" then
    local f = handlers [msg]
    if f then
      f (text)
    end -- have handler
  end -- if ATCP message
  
 if id == "74f8c420df7d59ad5aa66246" then  -- GMCP_handler_NJG
  
   -- pull out GMCP message, plus the data belonging to it
    -- hacky debug time
    print ("Pre GMCP pull:" ,message, params) 
   message, params = string.match (text, "([%a.]+)%s+(.*)")
   -- hacky debug time
    print ("Post GMCP pull:" ,message, params) 
  
   -- no match? oops!
   if not message then
      return
   end -- if
   
   -- hacky debug time
    print ("After Match Check:", params)    
	
   -- ensure we have an array or object
   if not string.match (params, "^[%[{]") then
      params =  "[" .. params .. "]"  -- JSON hack, make msg first element of an array.
	  
	  -- hacky debug time
    print ("After check:", params)
	  
   end -- if 
   
   -- decode it
   result = assert (json.decode (params))
   
   -- hacky debug time
    print ("After decode:", result)
   
   -- find a handler for this message type
   local f = GMCP_handlers [message:lower ()]
   
     -- hacky debug time
    print ("After find handler:", f)
   
   -- warn if not found
   if f then
     -- call the handler, pass in whatever we got
	 
	 -- hacky debug time
    print ("After find handler Inside:", f, result)
	 
     f (result)
	 
	 -- hacky debug time
    print ("After result call:", f, result)
	
   end -- no handler
   
  end -- if GMCP message
  
	-- hacky debug time
    print ("After result Outside:", f, result)
  
end


Which then resulted in this:

MUSHclient mapper installed, version 2.6
Added plugin C:\Users\macki\Documents\MUSHclient\worlds\plugins\GMCP_Mapper.xml
comm.tick { }
Pre GMCP pull: nil nil
Post GMCP pull: comm.tick { }
After Match Check: { }
After decode: table: 02FE4020
After find handler: nil
After result Outside: nil table: 02FE4020
n
room.info {"num":1079696970,"id":"Archon Abode#5","name":"Kitchen","zone":"Archon Abode","desc":"","terrain":"stone","details":"","exits":{"S":-1079696975,"NE":-1079696968,"SW":-1079696969},"coord":{"id":0,"x":-1,"y":-1,"cont":0}}
Pre GMCP pull: comm.tick { }
Post GMCP pull: room.info {"num":1079696970,"id":"Archon Abode#5","name":"Kitchen","zone":"Archon Abode","desc":"","terrain":"stone","details":"","exits":{"S":-1079696975,"NE":-1079696968,"SW":-1079696969},"coord":{"id":0,"x":-1,"y":-1,"cont":0}}
After Match Check: {"num":1079696970,"id":"Archon Abode#5","name":"Kitchen","zone":"Archon Abode","desc":"","terrain":"stone","details":"","exits":{"S":-1079696975,"NE":-1079696968,"SW":-1079696969},"coord":{"id":0,"x":-1,"y":-1,"cont":0}}
After decode: table: 02FE7790
After find handler: function: 02FC4EA0
After find handler Inside: function: 02FC4EA0 table: 02FE7790
Added room 1079696970 to database. Name: Kitchen
Run-time error
Plugin: GMCP_Mapper (called from world: CoffeeTest)
Function/Sub: OnPluginBroadcast called by Plugin GMCP_Mapper
Reason: Executing plugin GMCP_Mapper sub OnPluginBroadcast
[string "Plugin: GMCP_Mapper"]:1273: bad argument #1 to 'concat' (table expected, got string)
stack traceback:
        [C]: in function 'concat'
        [string "Plugin: GMCP_Mapper"]:1273: in function 'f'
        [string "Plugin: GMCP_Mapper"]:1366: in function <[string "Plugin: GMCP_Mapper"]:1313>



My lack of LUA knowledge puts me in the postion of not knowing if this is an issue of the GMCP data being sent incorrectly from the MUD,
(CoffeeMud, which I can access and change the code as I am more familiar with java coding then just inform the codebase developer of the issue)
or some obvious and simple change in the mapper that I am missing thats causing the parsing to get bungled. Anyways, any help, either directly or
pointing me in the right direction to work it out myself would be greatly appreciated.

oh, and in case I missed some info that pertains to the issue, here a link to a vid capture of me gathering the debug info:

https://www.youtube.com/watch?v=cWuTcJSnXos
Australia Forum Administrator #1
Quote:

1273: bad argument #1 to 'concat' (table expected, got string)


Look at line 1273 in the plugin. Actually you need to find the start of the <script> section and add 1273 to that, as the line count is from the start of the script. So, if the script starts at line 50 in the plugin, then check line 1323 of the plugin (or thereabouts).

Quote:

Which then resulted in this:


The error message suggests you are doing a table.concat somewhere, but that isn't in the code you posted.
#2
Shortly after posting I went into the code again following the line numbers, I originally quickly only glanced at it as it was code I hadn't touched and had mistakenly assumed the error had to be caused by the input from the mud causing an issue 'further down the line'. Even more so with this happening in the handlers of room_click.

Realizing I was getting out of my depth even further at this point, I figured I'd see if I could get even a simple telnet parsing mapper to function then work my way back to gmcp and possible database issues.

Thanks for taking a look, though.
#3
Darn, didn't realize the line count starts from <script> and my curiosity got the better of me. Jumped back into the rabbit hole.

The offending code seems to be:
if info.details then
	print("info.details:",info.details)
    got_info (table.concat (info.details, ","))
  end -- if


part of the greater:
-- we got room info, eg. : shops,postoffice
function got_info (s)
  
  if not current_room then
    return
  end -- if
  
  local room = rooms [current_room]
  
  -- not cached - see if in database
  if not room then
    room = load_room_from_database (current_room)
  end -- not in cache
  
  if room and room.info == nil then
    save_info_to_database (current_room, s)
    mapper.draw (tostring (current_room))    -- redraw room with info
  end -- need to save environment

end -- got_info

handlers = {
  [1] = got_vitals,             -- eg. "H:496/496 M:412/412 E:1380/1380 W:960/960 NL:89/100"
                                --      health    mana      endurance   willpower experience
  [2] = got_room_name,          -- eg. "Continuing on the Parade of Zarathustra"
  [3] = got_room_exit,          -- eg. "n,s"
  [4] = got_room_number,        -- eg. "401"
  [5] = got_room_full_exits,    -- eg. "ne(8564),w(8428)"
  [6] = got_environment,        -- eg. "Urban"
  [7] = got_coordinates,        -- eg. "38,3,1,0"
  [8] = got_info,               -- eg. "shops,postoffice"
  }

function gotRoomInfo (info)
  
  if info.num then
    got_room_number (info.num)
  end -- if

  if info.name then
    got_room_name (info.name)
  end -- if
  
  if info.exits then
    local t = {}
    for k, v in pairs (info.exits) do
      table.insert (t, k .. "(" .. v .. ")")
    end -- for
    
    got_room_full_exits (table.concat (t, ","))
  end -- if
  
  if info.environment then
  --hackydebug
	print("info.environment:",info.environment)
    got_environment (info.environment)
  end -- if
  
  if info.coords then
  --hackydebug
	print("info.coords:",info.coords)
    got_coordinates (info.coords)
  end -- if
  
  if info.details then
    --hackydebug
	print("info.details:",info.details)
    got_info (table.concat (info.details, ","))
  end -- if


Did my usual throwing a bunch of print statements to see where it was stopping at what data it was dealing with:

room.info {"num":496521362,"id":"Midgaard#3025","name":"The Common Square","zone":"Midgaard","desc":"The common square, people pass you, talking to each other.  To the west is the poor alley and to the east is the dark alley.  To the north, this square is connected to the market square.  From the south you notice a nasty smell.","terrain":"city","details":"","exits":{"N":496521330,"S":496521388,"E":496521363,"W":496521361},"coord":{"id":0,"x":-1,"y":-1,"cont":0}}
Added room 496521362 to database. Name: The Common Square
Added exit E from room 496521362 to room 496521363 to database.
Added exit W from room 496521362 to room 496521361 to database.
Added exit S from room 496521362 to room 496521388 to database.
Added exit N from room 496521362 to room 496521330 to database.
info.details: 
Run-time error
Plugin: GMCP_Mapper (called from world: CoffeeTest)
Function/Sub: OnPluginBroadcast called by Plugin GMCP_Mapper
Reason: Executing plugin GMCP_Mapper sub OnPluginBroadcast
[string "Plugin: GMCP_Mapper"]:1279: bad argument #1 to 'concat' (table expected, got string)
stack traceback:
        [C]: in function 'concat'
        [string "Plugin: GMCP_Mapper"]:1279: in function 'f'
        [string "Plugin: GMCP_Mapper"]:1351: in function <[string "Plugin: GMCP_Mapper"]:1319>
Area  : Midgaard


curious thing is, if I remove:
if info.details then
    --hackydebug
	print("info.details:",info.details)
    got_info (table.concat (info.details, ","))
  end -- if


No errors, the visual map doesn't update other than the name of the room at the top(still just has a single square/room in the center) yet whenever I enter a new room, it 'appears' to be updating the database.

<2317Hp 820m 588mv>
char.vitals {"hp":2317,"mana":820,"moves":588}
w
room.info {"num":496521361,"id":"Midgaard#3024","name":"Eastern End of Poor Alley","zone":"Midgaard","desc":"You are at the poor alley. South of here is the Grubby Inn and to the east you see common square. Melancholy`s map shop is north. The alley continues  further west.","terrain":"city","details":"","exits":{"N":496522442,"S":496521427,"E":496521362,"W":496521423},"coord":{"id":0,"x":-1,"y":-1,"cont":0}}
Added room 496521361 to database. Name: Eastern End of Poor Alley
Added exit E from room 496521361 to room 496521362 to database.
Added exit W from room 496521361 to room 496521423 to database.
Added exit S from room 496521361 to room 496521427 to database.
Added exit N from room 496521361 to room 496522442 to database.
Area  : Midgaard
RoomID: Midgaard#3024
CityStreet: CITY  <> 1mv
Eastern End of Poor Alley 
Australia Forum Administrator #4
Looking at this JSON:


"details":"","exits":{"S":-1079696975,"NE":-1079696968,"SW":-1079696969}
          ^^          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        string                         table


The Lua JSON decoder turns things in brackets into Lua tables, so the exits will become a table (key=direction, value=roomID). However the details, not being in brackets, are just a string.

Since the details are empty you could omit the lines that process them, or maybe do this:


if info.details and info.details ~= "" then
    print("info.details:",info.details)
    got_info (table.concat (info.details, ","))
  end -- if


Or maybe:


if info.details and type (info.details) == "table" then
    print("info.details:",info.details)
    got_info (table.concat (info.details, ","))
  end -- if
#5
and now onto the next issue. :)

The mappers current behavior is while the debug text shows the rooms and exits being added to the database properly, it only ever draws the single room in the center of the map with no apparent exits.Yet, hovering over the room in the map itself brings up the tooltip showing the correct info, both roomid and list of exits. The one hint as to the possible issue is the debug line of expected exit that occurs even when going back and forth between rooms:

<2317Hp 820m 594mv>
Just moved n
expected exit for this direction is to room nil
n
Hacky Debug:Looking up room
Time to draw 1 rooms = 0.003 seconds, search depth = 1
Total times map drawn = 11, average time to draw = 0.003 seconds
Added room 496521304 to database. Name: The Bakery
Hacky Debug:Looking up room
Time to draw 1 rooms = 0.003 seconds, search depth = 1
Total times map drawn = 12, average time to draw = 0.003 seconds
Added exit S from room 496521304 to room 496521329 to database.
Hacky Debug:Looking up room
Time to draw 1 rooms = 0.003 seconds, search depth = 1
Total times map drawn = 13, average time to draw = 0.003 seconds
Area  : Midgaard
RoomID: Midgaard#3009
WoodRoom: WOODEN  <> 1mv
The Bakery 


Yet, from the map tooltip, and looking into the database itself:

exitid,dir,fromuid,touid,date_added
1,E,496522290,496522291,2018-08-01 16:07:08
2,W,496522290,496522289,2018-08-01 16:07:08
3,S,496522290,496524367,2018-08-01 16:07:08
4,N,496522290,496522263,2018-08-01 16:07:08
5,E,496522289,496522290,2018-08-01 16:07:16
6,W,496522289,496522288,2018-08-01 16:07:16
7,E,496522288,496522289,2018-08-01 16:07:25
8,W,496522288,496522287,2018-08-01 16:07:25
9,S,496522288,496522295,2018-08-01 16:07:25


It at least appears I'm pulling the exit data correctly.

Tried the mapper as is on both Achaea and aardmud. Achaea, as expected worked as expected and with no errors. Looking in the database everything seemed to match up with my local mud database with the exception of coords being in the room data, and the case of direction in the exit entries. (lowercase for both achaea and aardmud, upper for the local.) When using the mapper on Aardmud, the results seemed to be between the two others.
It would only draw the single room your in, but with the difference being it drew the exits as the faded 'possible' exits, and attached rooms as faded 'possible' rooms.

About to dive back in and start throwing in debug print messages everywhere to see where things are breaking down on parsing/tracking the exits now. If anyone has any suggestions on possible points of failure, feel free to chime in. :)

Would have started more debugging last night, but after the quick test on Aardmud... Umm, I had to install the personalized Aardmud mushclient and do some *cough* research *cough* on how they handle the new user experience, and as I like to be thorough in my research it kept me busy for a few hours.
Amended on Wed 01 Aug 2018 04:55 PM by Uafasach
Australia Forum Administrator #6
A possible issue (see the other recent thread about the mapper) is whether the exits are strings or numbers. In Lua they will look the same in debugging, but in Lua this will not compare equal:


if 123 == '123' then ...   -- not equal


You may need to tweak the plugin, in particular after reading from the database, to do a "tonumber" on the room IDs (assuming they are always numbers).
#7
Uafasach said:

, and the case of direction in the exit entries. (lowercase for both achaea and aardmud, upper for the local.)


Its working now, just have to fix some of the other stuff I sorta broke tracking it down. Yep, the fact that Coffeemud was sending the directions in caps, and me not thinking it mattered is what broke everything.

I'm going to go grab a beer and cry in the corner for a while before fixing it up and posting it for any other Coffeemud users to play with.