mirror of
https://github.com/MeshEnvy/lobbs.git
synced 2026-10-31 10:21:59 +01:00
122 lines
3.6 KiB
C++
122 lines
3.6 KiB
C++
#include "HelpCommands.h"
|
|
#include "../../core/LoBBSCommandRegistry.h"
|
|
#include "../../core/LoBBSConfig.h"
|
|
#include "../../core/LoBBSHooks.h"
|
|
#include "../../core/LoBBSResponse.h"
|
|
#include "../../core/LoBBSVersion.h"
|
|
#include <cstring>
|
|
#include <lodb/LoDB.h>
|
|
|
|
#include "core/LoBBSStackGuard.h"
|
|
|
|
static void lobbsTrimRestInPlace(char *s)
|
|
{
|
|
if (!s)
|
|
return;
|
|
char *p = s;
|
|
while (*p == ' ' || *p == '\t')
|
|
p++;
|
|
if (p != s)
|
|
memmove(s, p, strlen(p) + 1);
|
|
size_t len = strlen(s);
|
|
while (len > 0 && (s[len - 1] == ' ' || s[len - 1] == '\t'))
|
|
s[--len] = '\0';
|
|
}
|
|
|
|
static void replyCatalog(LoBBSCommandCtx &ctx)
|
|
{
|
|
std::vector<LoScalar> topics;
|
|
lobbsRecordPush(topics, "help", "this list, or /help topic");
|
|
lobbsRecordPush(topics, "hi", "welcome screen");
|
|
lobbsRecordPush(topics, "pN", "page N of the last reply");
|
|
lobbsApplyFilter("help_topics", ctx, topics, LoScalar());
|
|
|
|
LoBBSResponse resp;
|
|
lobbsRecordPush(resp.records, "LoBBS v" LOBBS_VERSION_SHORT " Help");
|
|
resp.records.insert(resp.records.end(), topics.begin(), topics.end());
|
|
lobbsCommandReplyResponse(ctx, resp);
|
|
}
|
|
|
|
static void replyTopicHelp(LoBBSCommandCtx &ctx, const char *query)
|
|
{
|
|
LoScalar args;
|
|
args.setString(LODB_F_TITLE, query);
|
|
LoScalar topic;
|
|
topic.setString(LODB_F_TITLE, query);
|
|
lobbsApplyFilter("help_for_topic", ctx, topic, args);
|
|
|
|
LoBBSResponse resp;
|
|
std::string body;
|
|
if (!topic.getString(LODB_F_DESCRIPTION, body) || body.empty()) {
|
|
lobbsRecordPush(resp.records, (std::string("No help found for ") + query).c_str());
|
|
lobbsCommandReplyResponse(ctx, resp);
|
|
return;
|
|
}
|
|
size_t start = 0;
|
|
while (start <= body.size()) {
|
|
size_t nl = body.find('\n', start);
|
|
if (nl == std::string::npos)
|
|
nl = body.size();
|
|
lobbsRecordPush(resp.records, body.substr(start, nl - start).c_str());
|
|
start = nl + 1;
|
|
}
|
|
lobbsCommandReplyResponse(ctx, resp);
|
|
}
|
|
|
|
static void replyHi(LoBBSCommandCtx &ctx)
|
|
{
|
|
LoBBSResponse resp;
|
|
lobbsRecordPush(resp.records, "LoBBS v" LOBBS_VERSION_SHORT);
|
|
char uname[LOBBS_USERNAME_BUFFER_SIZE];
|
|
if (lobbsCtxLoggedIn(ctx) && lobbsCtxUsername(ctx, uname, sizeof(uname)))
|
|
lobbsRecordPush(resp.records, (std::string("Welcome back, ") + uname + "!").c_str());
|
|
else
|
|
lobbsRecordPush(resp.records, "Welcome!");
|
|
lobbsRecordPush(resp.records, LOBBS_HELP_HINT);
|
|
lobbsRecordPush(resp.records, "Use /status to see what's happening");
|
|
if (!lobbsCtxLoggedIn(ctx))
|
|
lobbsRecordPush(resp.records, "Use /login to sign in");
|
|
lobbsCommandReplyResponse(ctx, resp);
|
|
}
|
|
|
|
static void slashHelp(LoBBSCommandCtx *ctx, const LoScalar &args)
|
|
{
|
|
if (!ctx)
|
|
return;
|
|
if (lobbsSlashVerbIs(args, "hi")) {
|
|
replyHi(*ctx);
|
|
return;
|
|
}
|
|
if (!lobbsSlashVerbIs(args, "help"))
|
|
return;
|
|
|
|
char work[128];
|
|
work[0] = '\0';
|
|
if (ctx->rest && ctx->rest[0])
|
|
strncpy(work, ctx->rest, sizeof(work) - 1);
|
|
|
|
lobbsTrimRestInPlace(work);
|
|
if (!work[0]) {
|
|
replyCatalog(*ctx);
|
|
return;
|
|
}
|
|
|
|
replyTopicHelp(*ctx, work);
|
|
}
|
|
|
|
static const LoBBSVerb pagingHelpVerbs[] = {
|
|
{"pN", nullptr, 0, "pN — next page of last reply (/p2, /43 p2 machine)"},
|
|
};
|
|
|
|
static void filterHelpForTopic(LoBBSCommandCtx *ctx, LoScalar &value, const LoScalar &args)
|
|
{
|
|
lobbsHelpForTable(ctx, value, args, "pN", pagingHelpVerbs, sizeof(pagingHelpVerbs) / sizeof(pagingHelpVerbs[0]));
|
|
}
|
|
|
|
void lobbsHelpRegisterCommands()
|
|
{
|
|
lobbsAddAction("slash_cmd", slashHelp, LOBBS_HOOK_PRIORITY_HELP);
|
|
lobbsAddFilter("help_for_topic", filterHelpForTopic, LOBBS_HOOK_PRIORITY_HELP);
|
|
}
|
|
|