Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Plugins ➜ ATCP plugin for Achaea

ATCP plugin for Achaea

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1  2  3 4  

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #30 on Thu 11 Mar 2010 05:33 PM (UTC)

Amended on Thu 11 Mar 2010 05:34 PM (UTC) by Twisol

Message
Larkin said:
I agree with Nick on two things here: these two plugins are different takes on the same thing and can co-exist peacefully, and the simple solution is often the preferred solution.

In theory, yes. In practice, there are obstacles, but we're slowly breaking those down.

Larkin said:
The PPI code is a means of passing data back and forth between plugins, which I find largely unnecessary. I steer away from plugins as much as possible in my own coding, preferring to have everything in the same shared space. Things like this feel too much like COM to me, and those of us who've dealt with COM programming know the pain it can cause.

I'll suggest that you find PPI unnecessary precisely because you avoid plugins anyways. It becomes necessary for any rich, meaningful interactions between plugins. I don't know what you do, personally, but I write things that I intend to be used by other people, and plugins are indispensable for that. (We've tried having people import sets of XML and add code to their scripting file, and so many people had trouble with it!)

A shared scripting space would probably be better for this in some ways, but having toyed with scripting in WoW, which does this, it's also a bit unsatisfying. I'm working on a sort of half-and-half architecture in my own hobbyist web client, which I think shows promise, but obviously it can't be applied to MUSHclient this late in the game. I just do the best I can with the tools I'm given.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Larkin   (278 posts)  Bio
Date Reply #31 on Thu 11 Mar 2010 05:42 PM (UTC)
Message
For smaller things that are easily modularized, I'm sure it's very useful. For a full-fledged combat system, it's just impractical to pass so many bits of data back and forth between so many modules.

I provide fairly simple instructions to using my scripts, and nearly everyone has zero trouble getting it all installed. I've seen things that are much more plugin-based and had a hard time understanding them myself, not to mention the typical end user who wants to do a few add-ons of his own and doesn't even know where to begin.

To each his own, of course.

And, these new Telnet negotiation ATCP plugins are very helpful! Thanks for the updates, guys. :)
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #32 on Thu 11 Mar 2010 06:44 PM (UTC)

Amended on Thu 11 Mar 2010 07:36 PM (UTC) by Nick Gammon

Message
I got a message today from the programmer at IRE saying that on Imperium Imperian at least, multiple "hello" messages are now respected. The changes may take a few days to flow through to the other IRE games.

Some good has come out of our discussions about ATCP. A limitation that previously had to be worked around, perhaps somewhat laboriously, has now been removed.

Indeed the outcome of most discussions here, even if they may not satisfy everyone, usually result in improvements which benefit all users.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #33 on Thu 11 Mar 2010 06:47 PM (UTC)
Message
Nick Gammon said:
I got a message today from the programmer at IRE saying that on Imperium at least, multiple "hello" messages are now respected. The changes may take a few days to flow through to the other IRE games.

Excellent. I'll look into experimenting later this week, figure out how best to react to the new treatment of 'hello'.

Nick Gammon said:
Imperium

Imperian. ;)

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #34 on Thu 11 Mar 2010 07:27 PM (UTC)
Message
Quote:
PPI is how the data actually gets sent around, and it's integral to the registered-callbacks facility. That's not so much a framework as simply a way to easily get at the data.

Well, no, it kind of is a framework: to get at the ATCP stuff you need the PPI framework, instead of the normal BroadcastPlugin-whatever-it-is. It's not clear to me that this is a bad thing, however it means that you're necessarily getting more than just an ATCP handler.

Quote:
EDIT: I'm not sure what context you're using "framework" in, now that I think about it. Are you referring to my "structured plugin" format, or the ATCP functionality itself?

The structured plugin is another framework thing. ATCP on its own is not really a framework. A framework is a collection of stuff to make some functionality available. You basically have a framework on top of MUSHclient's framework (its standard broadcast function).



Anyhow my point here is really not to argue for or against any particular implementation. My point was that using lines of code alone is a somewhat short-sighted metric. Sometimes more is less, but sometimes more really is more.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #35 on Thu 11 Mar 2010 07:35 PM (UTC)
Message
Twisol said:

Imperian. ;)


Oops.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #36 on Thu 11 Mar 2010 07:42 PM (UTC)
Message
David Haley said:

Anyhow my point here is really not to argue for or against any particular implementation. My point was that using lines of code alone is a somewhat short-sighted metric. Sometimes more is less, but sometimes more really is more.


Well it is time to roll out Gammon's Law:

Quote:

The solution cannot be simpler than the problem.


What that means in essence is that you cannot have a simple solution to a complex problem. Just as an example, if you are going to serve a three-course meal, you need to cook (or otherwise obtain) three different lots of food.

However a corollary may be:

Quote:

The solution should not be more complex than the problem.


In essence, I agree a complex solution (and therefore to a certain extent, lines of code) is required to solve complex problems. However I worry when I see what seems to me to be complexity addressing a simple problem.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #37 on Thu 11 Mar 2010 07:59 PM (UTC)

Amended on Thu 11 Mar 2010 08:01 PM (UTC) by Twisol

Message
Nick Gammon said:
Well it is time to roll out Gammon's Law:
Quote:
The solution cannot be simpler than the problem.


In other words: Simpler than the problem (is) not a solution.
Contrapositive: A solution (is) at least as complex as the problem. (EDIT: More correctly, "not simpler than the problem", but it comes to the same.)

Nick Gammon said:
Quote:
The solution should not be more complex than the problem.


Your corollary is less a corollary and more of an additional refinement. It doesn't follow directly from the original law ;)

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #38 on Thu 11 Mar 2010 08:30 PM (UTC)
Message
Well, even if we grant your law unconditionally, we come to the next problem which is that there is apparently disagreement on what the problem is in the first place.

I think you are being somewhat reductionist when you say that the only problem is to display a health bar. The problem is bigger than that: it's serving up data sent by the server to plugins to do as they will. Some of those plugins might have only simple needs.

Heck, if we look at things only ever so slightly differently, isn't the entire plugin architecture far too complex for this? You could just as easily stick something into the core that intercepts ATCP and puts up a small window with the health bar. It would probably be simpler than the whole plugin architecture, too. So why do we even bother with plugins?

Of course, that solution is far less flexible, and fairly obviously inferior to what we have now.

My point is solely that although your needs today, for the purposes of your example code, are simple, you haven't really argued the case that your needs will always be so simple. Your solution of simply duplicating the code where needed is a little surprising to me, because it's a pretty clear violation of other software design principles.

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #39 on Thu 11 Mar 2010 08:33 PM (UTC)
Message
David Haley said:
Your solution of simply duplicating the code where needed is a little surprising to me, because it's a pretty clear violation of other software design principles.


Granted, my solution also duplicates code; specifically, the libraries the plugin depends on that aren't included with MUSHclient.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by David Haley   USA  (3,881 posts)  Bio
Date Reply #40 on Thu 11 Mar 2010 09:14 PM (UTC)
Message
Well, IMHO that's wrong too. It would be silly for every plugin that uses PPI to have to reimplement PPI. Of course, PPI is the kind of concept that should make it into the core somehow (that discussion kind of fell off the wagon, as it were). The structured plugin stuff is a similar concept that should be in the core. (I use 'concept' to differentiate it from a particular implementation that may or may not be suitable.)

David Haley aka Ksilyan
Head Programmer,
Legends of the Darkstone

http://david.the-haleys.org
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #41 on Fri 12 Mar 2010 07:20 PM (UTC)
Message
Twisol said:

Your corollary is less a corollary and more of an additional refinement. It doesn't follow directly from the original law ;)


True.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #42 on Sat 13 Mar 2010 01:17 AM (UTC)
Message
I've been popping into Achaea a few times every day, and I just checked now, and they've got the new ATCP messages added! Assuming the 'hello' message changes were also applied, I'll probably be tinkering with my ATCP layer soon. I'd like to create an ATCP library (as opposed to plugin, now) that can be included in structured plugins, if things work out.

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Twisol   USA  (2,257 posts)  Bio
Date Reply #43 on Sat 13 Mar 2010 05:39 AM (UTC)

Amended on Sat 13 Mar 2010 05:45 AM (UTC) by Twisol

Message
I just wrote up a small ATCP library. It seems to work quite well, and in a similar fashion to my original ATCP plugin.

Minor problem though, Nick: If I recall, you said that only the plugin that sent the DO gets called with "SENT_DO", right? I think that should be changed in favor of calling all plugins with SENT_DO. WILL would short-circuit at the first plugin to enable it, of course, but any number of other plugins might need to know if it's been enabled, and do their own setup relevant to the protocol. This is particularly an issue with the ATCP library, since it needs to be able to send its "hello" message to guarantee that those modules are enabled.

Here's what I have so far. It's probably not finished - I'd like to fix up the module infrastructure a bit - but it seems to work in testing.

local codes = {
  IAC_DO_ATCP = "\255\253\200", -- enables ATCP communication
  IAC_SB_ATCP = "\255\250\200", -- begins an ATCP packet
  IAC_SE      = "\255\240",     -- ends an ATCP packet
  ATCP        = 200,            -- ATCP protocol number
}

local hello_msg = "hello MUSHclient " .. Version() .. "\n" ..
                  "auth 1\n" ..
                  "char_name 1\n" ..
                  "char_vitals 1\n" ..
                  "room_brief 1\n" ..
                  "room_exits 1\n" ..
                  "map_display 1\n" ..
                  "composer 1\n" ..
                  "keepalive 1\n" ..
                  "topvote 1\n" ..
                  "ping 1\n"

local callbacks = setmetatable({}, {
  __index = function(tbl, key)
    local group = {}
    rawset(tbl, key, group)
    return group
  end,
})


local Register = function(msg, callback)
  if type(msg) ~= "string" then
    error("Message name must be a string")
  elseif type(callback) ~= "function" then
    error("Callback must be a function")
  end
  table.insert(callbacks[msg], callback)
end

local Unregister = function(msg, callback)
  if type(msg) ~= "string" then
    error("Message name must be a string")
  elseif type(callback) ~= "function" then
    error("Callback must be a function")
  end
  
  for k,v in ipairs(callbacks[msg]) do
    if v == callback then
      table.remove(callbacks[msg], k)
      break
    end
  end
end

local Startup = function(type, data)
  if type == codes.ATCP then
    if data == "WILL" then
      return true
    elseif data == "SENT_DO" then
      SendPkt(codes.IAC_DO_ATCP .. codes.IAC_SB_ATCP .. hello_msg .. codes.IAC_SE)
      return true
    end
  end
  
  return false
end

local Handle = function(type, data)
  if type ~= codes.ATCP then
    return
  end

  local message, content
  local separator = data:find("%s")
  if separator then
    message, content = data:sub(1, separator-1), data:sub(separator+1)
  else
    message, content = data, ""
  end
  
  for _,callback in ipairs(callbacks[message]) do
    local ok, err = pcall(callback, message, content)
    if not ok then
      TraceOut("Error while executing ATCP callback " ..
               tostring(callback) .. " for message " .. message ..
              ":\n  " .. (err or ""))
    end
  end
  
  -- send to catch-all handlers as well
  for _,callback in ipairs(callbacks["*"]) do
    local ok, err = pcall(callback, message, content)
    if not ok then
      TraceOut("Error while executing ATCP callback " ..
               tostring(callback) .. " for message " .. message ..
              ":\n  " .. (err or ""))
    end
  end
end

return {
  Register = Register,
  Unregister = Unregister,
  Startup = Startup,
  Handle = Handle,
}



Usage:
ATCP = require("atcp")

foo = function(message, content)
  -- ...
end,

bar = function(message, content)
  -- ...
end,

catchall = function(message, content)
  -- ...
end

OnPluginInstall = function()
  ATCP.Register("Char.Vitals", foo)
  ATCP.Register("Room.Name", bar)
  ATCP.Register("*", catchall) -- receives all messages
end

-- Set up ATCP handlers
OnPluginTelnetRequest = ATCP.Startup
OnPluginTelnetSubnegotiation = ATCP.Handle


-- Alternatively, if you want to handle these events yourself, too:

OnPluginTelnetRequest = function(type, data)
  ATCP.Startup(type, data)
  -- ...
end

OnPluginTelnetSubnegotiation = function(type, data)
  ATCP.Handle(type, data)
  -- ...
end

'Soludra' on Achaea

Blog: http://jonathan.com/
GitHub: http://github.com/Twisol
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #44 on Sat 13 Mar 2010 06:06 AM (UTC)
Message
Twisol said:

Nick: If I recall, you said that only the plugin that sent the DO gets called with "SENT_DO", right? I think that should be changed in favor of calling all plugins with SENT_DO.


You are the one that said we couldn't have multiple logins, and so the SENT_DO is only sent to the first plugin. How are other ones going to know if someone else logged in before them?

Maybe you are right that it should be changed, but this shows what happens if you fiddle around too much trying to solve a problem caused by one particular server design.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


128,906 views.

This is page 3, subject is 4 pages long:  [Previous page]  1  2  3 4  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.