mirror of
https://github.com/MeshEnvy/lobbs.git
synced 2026-11-03 03:22:21 +01:00
feat(meshtastic): extract LoBBS plugin library
This commit is contained in:
1 parent
1f7ded8f3f
commit
5bffe8d259
124 files changed
+10907
-39
No files matched your search
@@ -0,0 +1,200 @@
|
||||
#if !MESHTASTIC_EXCLUDE_LOBBS
|
||||
|
||||
#include "ConfigCommands.h"
|
||||
#include "../../LoBBSCommandRegistry.h"
|
||||
#include "../../LoBBSHooks.h"
|
||||
#include "../../LoBBSModule.h"
|
||||
#include "../../LoBBSReplyCache.h"
|
||||
#include "../../LoBBSResponse.h"
|
||||
#include "../AppUtil.h"
|
||||
#include "ConfigCommon.h"
|
||||
#include "ConfigDal.h"
|
||||
#include "ConfigRecords.h"
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <strings.h>
|
||||
|
||||
#include "LoBBSStackGuard.h"
|
||||
|
||||
static uint32_t gLobbsPagerTtlSec = LOBBS_REPLY_CACHE_TTL_SEC;
|
||||
|
||||
uint32_t lobbsReplyCacheTtlSec()
|
||||
{
|
||||
return gLobbsPagerTtlSec;
|
||||
}
|
||||
|
||||
static void filterConfigKeysPager(LoBBSCommandCtx *ctx, std::vector<LoScalar> &keys, const LoScalar &args)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)args;
|
||||
lobbsConfigPushKey(keys, "pager.ttl", LOBBS_REPLY_CACHE_TTL_SEC, 60, 3600, "Seconds /pN cache lasts");
|
||||
}
|
||||
|
||||
static void filterConfigValidateRange(LoBBSCommandCtx *ctx, LoScalar &value, const LoScalar &args)
|
||||
{
|
||||
(void)ctx;
|
||||
std::string existing;
|
||||
if (value.getString(LODB_F_ERROR, existing) && !existing.empty())
|
||||
return;
|
||||
uint32_t proposed = 0;
|
||||
uint32_t minV = 0;
|
||||
uint32_t maxV = 0;
|
||||
if (!value.getUint32(ConfigValidateField::FIELD_VALUE, proposed))
|
||||
return;
|
||||
if (!args.getUint32(ConfigKeyField::FIELD_MIN, minV) || !args.getUint32(ConfigKeyField::FIELD_MAX, maxV))
|
||||
return;
|
||||
if (proposed < minV || proposed > maxV) {
|
||||
char buf[48];
|
||||
snprintf(buf, sizeof(buf), "Must be %u-%u.", (unsigned)minV, (unsigned)maxV);
|
||||
value.setString(LODB_F_ERROR, buf);
|
||||
}
|
||||
}
|
||||
|
||||
static void actionConfigChangedPager(LoBBSCommandCtx *ctx, const LoScalar &args)
|
||||
{
|
||||
(void)ctx;
|
||||
std::string key;
|
||||
if (!args.getString(LODB_F_TITLE, key) || key != "pager.ttl")
|
||||
return;
|
||||
uint32_t ttl = LOBBS_REPLY_CACHE_TTL_SEC;
|
||||
args.getUint32(ConfigValidateField::FIELD_VALUE, ttl);
|
||||
gLobbsPagerTtlSec = ttl;
|
||||
}
|
||||
|
||||
static void handleConfig(LoBBSCommandCtx &ctx)
|
||||
{
|
||||
if (!lobbsCommandRequireSysop(ctx))
|
||||
return;
|
||||
ConfigDal &cfg = ctx.mod->config().dal();
|
||||
const char *key = lobbsArgShift(ctx);
|
||||
if (!key) {
|
||||
LoBBSResponse resp;
|
||||
lobbsRecordPush(resp.records, "Use /help config key for details");
|
||||
for (const LoScalar &def : cfg.keyDefs(ctx)) {
|
||||
std::string name;
|
||||
if (!def.getString(LODB_F_TITLE, name))
|
||||
continue;
|
||||
uint32_t minV = 0;
|
||||
uint32_t maxV = 0;
|
||||
def.getUint32(ConfigKeyField::FIELD_MIN, minV);
|
||||
def.getUint32(ConfigKeyField::FIELD_MAX, maxV);
|
||||
uint32_t val = cfg.effectiveValue(ctx, name.c_str());
|
||||
char line[96];
|
||||
snprintf(line, sizeof(line), "%s %u (%u-%u)", name.c_str(), (unsigned)val, (unsigned)minV, (unsigned)maxV);
|
||||
lobbsRecordPush(resp.records, line);
|
||||
}
|
||||
lobbsCommandReplyResponse(ctx, resp);
|
||||
return;
|
||||
}
|
||||
|
||||
const char *next = lobbsArgPeek(ctx);
|
||||
if (!next) {
|
||||
cfg.ensureRegistry(ctx);
|
||||
const LoScalar *def = cfg.findKeyDef(key);
|
||||
if (!def) {
|
||||
lobbsCommandReplyError(ctx, "Unknown setting.");
|
||||
return;
|
||||
}
|
||||
uint32_t val = cfg.effectiveValue(ctx, key);
|
||||
uint32_t defV = 0;
|
||||
uint32_t minV = 0;
|
||||
uint32_t maxV = 0;
|
||||
std::string help;
|
||||
def->getUint32(ConfigKeyField::FIELD_DEFAULT, defV);
|
||||
def->getUint32(ConfigKeyField::FIELD_MIN, minV);
|
||||
def->getUint32(ConfigKeyField::FIELD_MAX, maxV);
|
||||
def->getString(LODB_F_DESCRIPTION, help);
|
||||
char line[128];
|
||||
snprintf(line, sizeof(line), "%s = %u (default %u, %u-%u). %s", key, (unsigned)val, (unsigned)defV, (unsigned)minV,
|
||||
(unsigned)maxV, help.c_str());
|
||||
lobbsCommandReply(ctx, line);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strcasecmp(next, "reset") == 0) {
|
||||
lobbsArgShift(ctx);
|
||||
if (lobbsArgHasMore(ctx)) {
|
||||
lobbsCommandReplyError(ctx, "Usage: /config key reset");
|
||||
return;
|
||||
}
|
||||
if (const char *err = cfg.resetKey(ctx, key)) {
|
||||
lobbsCommandReplyError(ctx, err);
|
||||
return;
|
||||
}
|
||||
char reply[64];
|
||||
snprintf(reply, sizeof(reply), "%s reset.", key);
|
||||
lobbsCommandReply(ctx, reply);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t value = 0;
|
||||
if (!lobbsArgShiftUint(ctx, value) || lobbsArgHasMore(ctx)) {
|
||||
lobbsCommandReplyError(ctx, "Usage: /config key value");
|
||||
return;
|
||||
}
|
||||
if (const char *err = cfg.validateAndSet(ctx, key, value)) {
|
||||
lobbsCommandReplyError(ctx, err);
|
||||
return;
|
||||
}
|
||||
char reply[64];
|
||||
snprintf(reply, sizeof(reply), "%s = %u.", key, (unsigned)value);
|
||||
lobbsCommandReply(ctx, reply);
|
||||
}
|
||||
|
||||
static void slashConfig(LoBBSCommandCtx *ctx, const LoScalar &args)
|
||||
{
|
||||
if (!ctx || !lobbsSlashVerbIs(args, "config"))
|
||||
return;
|
||||
handleConfig(*ctx);
|
||||
}
|
||||
|
||||
static const LoBBSVerb configHelpVerbs[] = {
|
||||
{"config", nullptr, LOBBS_V_SYSOP, "config — sysop: list/get/set/reset settings (/help config key explains one)"},
|
||||
};
|
||||
|
||||
static void filterConfigHelpTopics(LoBBSCommandCtx *ctx, std::vector<LoScalar> &topics, const LoScalar &args)
|
||||
{
|
||||
(void)ctx;
|
||||
(void)args;
|
||||
lobbsRecordPush(topics, "config", "sysop settings");
|
||||
}
|
||||
|
||||
static void filterConfigHelpForTopic(LoBBSCommandCtx *ctx, LoScalar &value, const LoScalar &args)
|
||||
{
|
||||
lobbsHelpForTable(ctx, value, args, "config", configHelpVerbs, sizeof(configHelpVerbs) / sizeof(configHelpVerbs[0]));
|
||||
if (!ctx || !ctx->mod || value.has(LODB_F_DESCRIPTION) || !lobbsCtxIsSysop(*ctx))
|
||||
return;
|
||||
std::string query;
|
||||
if (!args.getString(LODB_F_TITLE, query) || strncasecmp(query.c_str(), "config ", 7) != 0)
|
||||
return;
|
||||
const char *key = query.c_str() + 7;
|
||||
ConfigDal &cfg = ctx->mod->config().dal();
|
||||
cfg.ensureRegistry(*ctx);
|
||||
const LoScalar *def = cfg.findKeyDef(key);
|
||||
if (!def)
|
||||
return;
|
||||
std::string help;
|
||||
uint32_t defV = 0;
|
||||
uint32_t minV = 0;
|
||||
uint32_t maxV = 0;
|
||||
def->getString(LODB_F_DESCRIPTION, help);
|
||||
def->getUint32(ConfigKeyField::FIELD_DEFAULT, defV);
|
||||
def->getUint32(ConfigKeyField::FIELD_MIN, minV);
|
||||
def->getUint32(ConfigKeyField::FIELD_MAX, maxV);
|
||||
char buf[128];
|
||||
snprintf(buf, sizeof(buf), "%s: %s. Default %u, range %u-%u.", key, help.c_str(), (unsigned)defV, (unsigned)minV,
|
||||
(unsigned)maxV);
|
||||
value.setString(LODB_F_DESCRIPTION, buf);
|
||||
}
|
||||
|
||||
void lobbsConfigRegisterCommands()
|
||||
{
|
||||
lobbsAddFilter("config_keys", filterConfigKeysPager, LOBBS_HOOK_PRIORITY_HELP);
|
||||
lobbsAddFilter("config_validate", filterConfigValidateRange, LOBBS_HOOK_PRIORITY_HELP);
|
||||
lobbsAddAction("config_changed", actionConfigChangedPager, LOBBS_HOOK_PRIORITY_HELP);
|
||||
lobbsAddAction("slash_cmd", slashConfig, LOBBS_HOOK_PRIORITY_FEATURE);
|
||||
lobbsAddFilter("help_topics", filterConfigHelpTopics, LOBBS_HOOK_PRIORITY_FEATURE);
|
||||
lobbsAddFilter("help_for_topic", filterConfigHelpForTopic, LOBBS_HOOK_PRIORITY_FEATURE);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in new issue
Block a user