mudlet/src/TMxpExpireTagHandler.cpp

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

85 lines
3.3 KiB
C++
Raw Permalink Normal View History

Add: MXP EXPIRE tag support for expiring links (#8383) <!-- Keep the title short & concise so anyone non-technical can understand it, the title appears in PTB changelogs --> #### Brief overview of PR changes/additions Implements support for the MXP (Mud eXtension Protocol) EXPIRE tag, which allows MUD servers to automatically deactivate clickable links when they're no longer relevant. For example, when you move to a new room, the exit links from the previous room are deactivated so you can't accidentally click them. The EXPIRE tag can be used in two ways: - Standalone: `<EXPIRE name>` deactivates all links tagged with that name - As an attribute: `<SEND href="..." EXPIRE="name">` tags a link to be expired later Expired links remain visible in scrollback for historical reference but become non-functional when clicked. #### Motivation for adding to Mudlet This feature was requested by @mfontani in [Discord comments](https://discord.com/channels/279748146316312576/1393998251786768384/1429244386541178911) to improve the MUD playing experience by preventing accidental clicks on outdated navigation links. The MXP v1.0 specification includes EXPIRE tag support, and implementing it brings Mudlet closer to full MXP compliance. StickMUD (stickmud.com:7680) has already implemented server-side support for this feature and uses it to expire room exit links when players move to new rooms. #### Other info (issues closed, discussion etc) - Tested extensively with StickMUD's MXP implementation - All existing unit tests pass - No breaking changes to existing functionality - Links are deactivated but remain visually unchanged in scrollback to preserve historical context --- Video of MXP tags expiring. Clicking on prior room links does nothing, while clicking on existing room links functions. https://github.com/user-attachments/assets/417bb1e7-458a-459b-9529-ca7749744cc5
2025-10-21 05:02:34 -04:00
/***************************************************************************
* Copyright (C) 2025 by Mike Conley - mike.conley@stickmud.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include "TMxpExpireTagHandler.h"
#include "TMxpClient.h"
#include "TMxpContext.h"
#ifdef DEBUG_MXP_PROCESSING
#include <QDebug>
#endif
// Override supports() to add debug output
bool TMxpExpireTagHandler::supports(TMxpContext& ctx, TMxpClient& client, MxpTag* tag)
{
#ifdef DEBUG_MXP_PROCESSING
qDebug() << "TMxpExpireTagHandler::supports() called for tag:" << tag->getName();
#endif
// Call parent class supports() which checks if tag->isNamed("EXPIRE")
bool result = TMxpSingleTagHandler::supports(ctx, client, tag);
#ifdef DEBUG_MXP_PROCESSING
qDebug() << "TMxpExpireTagHandler::supports() returning:" << result;
#endif
return result;
}
// <EXPIRE name>
// Removes all links tagged with the given expire name
TMxpTagHandlerResult TMxpExpireTagHandler::handleStartTag(TMxpContext& ctx, TMxpClient& client, MxpStartTag* tag)
{
Q_UNUSED(ctx)
QString expireName;
#ifdef DEBUG_MXP_PROCESSING
qDebug() << "TMxpExpireTagHandler: Processing EXPIRE tag";
qDebug() << " Attribute count:" << tag->getAttributesCount();
for (int i = 0; i < tag->getAttributesCount(); i++) {
auto attr = tag->getAttribute(i);
qDebug() << " Attribute" << i << ":" << attr.getName() << "=" << attr.getValue();
}
#endif
// The expire name can be specified in different ways:
// <EXPIRE name> or <EXPIRE name="name">
if (tag->getAttributesCount() > 0) {
if (tag->hasAttribute(qsl("name"))) {
expireName = tag->getAttributeValue(qsl("name"));
} else {
// First attribute without a value is the name
expireName = tag->getAttribute(0).getName();
}
}
if (expireName.isEmpty()) {
#ifdef DEBUG_MXP_PROCESSING
qDebug() << "TMxpExpireTagHandler: No expire name found, not handling";
#endif
return MXP_TAG_NOT_HANDLED;
}
#ifdef DEBUG_MXP_PROCESSING
qDebug() << "TMxpExpireTagHandler: Expiring links with name:" << expireName;
#endif
client.expireLinks(expireName);
return MXP_TAG_HANDLED;
}