summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/RPC/jsonrpc.js20
-rw-r--r--docs/RPC/rpc_data.md32
-rw-r--r--modules/rpc/rpc_data.cpp233
3 files changed, 188 insertions, 97 deletions
diff --git a/docs/RPC/jsonrpc.js b/docs/RPC/jsonrpc.js
index b726678a2..357cbc844 100644
--- a/docs/RPC/jsonrpc.js
+++ b/docs/RPC/jsonrpc.js
@@ -49,10 +49,11 @@ class AnopeRPC {
*
* Requires the rpc_data module to be loaded.
*
+ * @param {string} The level of detail to request.
* @returns {array} An array of channel names.
*/
- listChannels() {
- return this.run("anope.listChannels");
+ listChannels(detail = "name") {
+ return this.run("anope.listChannels", detail);
}
/**
@@ -72,10 +73,11 @@ class AnopeRPC {
*
* Requires the rpc_data module to be loaded.
*
+ * @param {string} The level of detail to request.
* @returns {array} An array of channel names.
*/
- listOpers() {
- return this.run("anope.listOpers");
+ listOpers(detail = "name") {
+ return this.run("anope.listOpers", detail);
}
/**
@@ -95,10 +97,11 @@ class AnopeRPC {
*
* Requires the rpc_data module to be loaded.
*
+ * @param {string} The level of detail to request.
* @returns {array} An array of servers names.
*/
- listServers() {
- return this.run("anope.listServers");
+ listServers(detail = "name") {
+ return this.run("anope.listServers", detail);
}
/**
@@ -118,10 +121,11 @@ class AnopeRPC {
*
* Requires the rpc_data module to be loaded.
*
+ * @param {string} The level of detail to request.
* @returns {array} An array of channel names.
*/
- listUsers() {
- return this.run("anope.listUsers");
+ listUsers(detail = "name") {
+ return this.run("anope.listUsers", detail);
}
/**
diff --git a/docs/RPC/rpc_data.md b/docs/RPC/rpc_data.md
index 9ba1ae8ac..6aa16bd3a 100644
--- a/docs/RPC/rpc_data.md
+++ b/docs/RPC/rpc_data.md
@@ -6,11 +6,15 @@ Lists all channels that exist on the network.
### Parameters
-*None*
+Index | Description
+----- | -----------
+0 | If specified then the level of detail to retrieve. Can be set to "full" to retrieve all detail or "name" to just retrieve the channel names. Defaults to "name".
### Errors
-*Only standard RPC errors*
+Code | Description
+------ | -----------
+-32099 | The specified detail level does not exist.
### Result
@@ -81,11 +85,15 @@ Lists all services operators that exist on the network.
### Parameters
-*None*
+Index | Description
+----- | -----------
+0 | If specified then the level of detail to retrieve. Can be set to "full" to retrieve all detail or "name" to just retrieve the services operator nicknames. Defaults to "name".
### Errors
-*Only standard RPC errors*
+Code | Description
+------ | -----------
+-32099 | The specified detail level does not exist.
### Result
@@ -154,11 +162,15 @@ Lists all servers that exist on the network.
### Parameters
-*None*
+Index | Description
+----- | -----------
+0 | If specified then the level of detail to retrieve. Can be set to "full" to retrieve all detail or "name" to just retrieve the server names. Defaults to "name".
### Errors
-*Only standard RPC errors*
+Code | Description
+------ | -----------
+-32099 | The specified detail level does not exist.
### Result
@@ -222,11 +234,15 @@ Lists all users that exist on the network.
### Parameters
-*None*
+Index | Description
+----- | -----------
+0 | If specified then the level of detail to retrieve. Can be set to "full" to retrieve all detail or "name" to just retrieve the user nicknames. Defaults to "name".
### Errors
-*Only standard RPC errors*
+Code | Description
+------ | -----------
+-32099 | The specified detail level does not exist.
### Result
diff --git a/modules/rpc/rpc_data.cpp b/modules/rpc/rpc_data.cpp
index 1f74b8179..5f7a14e63 100644
--- a/modules/rpc/rpc_data.cpp
+++ b/modules/rpc/rpc_data.cpp
@@ -13,6 +13,9 @@ enum
{
// Used by anope.channel, anope.oper, anope.server, and anope.user
ERR_NO_SUCH_TARGET = RPC::ERR_CUSTOM_START,
+
+ // Used by anope.listChannels, anope.listOpers, anope.listServers, and anope.listUsers
+ ERR_NO_SUCH_DETAIL = RPC::ERR_CUSTOM_START,
};
class AnopeListChannelsRPCEvent final
@@ -24,34 +27,8 @@ public:
{
}
- bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
+ static void GetInfo(Channel *c, RPC::Map &root)
{
- auto &root = request.Root<RPC::Array>();
- for (auto &[_, c] : ChannelList)
- root.Reply(c->name);
- return true;
- }
-};
-
-class AnopeChannelRPCEvent final
- : public RPC::Event
-{
-public:
- AnopeChannelRPCEvent(Module *o)
- : RPC::Event(o, "anope.channel", 1)
- {
- }
-
- bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
- {
- auto *c = Channel::Find(request.data[0]);
- if (!c)
- {
- request.Error(ERR_NO_SUCH_TARGET, "No such channel");
- return true;
- }
-
- auto &root = request.Root();
root.Reply("created", c->creation_time)
.Reply("name", c->name)
.Reply("registered", !!c->ci);
@@ -103,48 +80,65 @@ public:
auto &users = root.ReplyArray("users");
for (const auto &[_, uc] : c->users)
users.Reply(uc->status.BuildModePrefixList() + uc->user->nick);
+ }
+ bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
+ {
+ const auto detail = request.data.empty() ? "name" : request.data[0];
+ if (detail.equals_ci("name"))
+ {
+ auto &root = request.Root<RPC::Array>();
+ for (auto &[_, c] : ChannelList)
+ root.Reply(c->name);
+ }
+ else if (detail.equals_ci("full"))
+ {
+ auto &root = request.Root<RPC::Map>();
+ for (auto &[_, c] : ChannelList)
+ GetInfo(c, root.ReplyMap(c->name));
+ }
+ else
+ {
+ request.Error(ERR_NO_SUCH_DETAIL, "No such detail level");
+ }
return true;
}
};
-class AnopeListOpersRPCEvent final
+class AnopeChannelRPCEvent final
: public RPC::Event
{
public:
- AnopeListOpersRPCEvent(Module *o)
- : RPC::Event(o, "anope.listOpers")
+ AnopeChannelRPCEvent(Module *o)
+ : RPC::Event(o, "anope.channel", 1)
{
}
bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
{
- auto &root = request.Root<RPC::Array>();
- for (auto *oper : Oper::opers)
- root.Reply(oper->name);
+ auto *c = Channel::Find(request.data[0]);
+ if (!c)
+ {
+ request.Error(ERR_NO_SUCH_TARGET, "No such channel");
+ return true;
+ }
+
+ AnopeListChannelsRPCEvent::GetInfo(c, request.Root());
return true;
}
};
-class AnopeOperRPCEvent final
+class AnopeListOpersRPCEvent final
: public RPC::Event
{
public:
- AnopeOperRPCEvent(Module *o)
- : RPC::Event(o, "anope.oper", 1)
+ AnopeListOpersRPCEvent(Module *o)
+ : RPC::Event(o, "anope.listOpers")
{
}
- bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
+ static void GetInfo(Oper *o, RPC::Map &root)
{
- auto *o = Oper::Find(request.data[0]);
- if (!o)
- {
- request.Error(ERR_NO_SUCH_TARGET, "No such oper");
- return true;
- }
-
- auto &root = request.Root();
root
.Reply("name", o->name)
.Reply("operonly", o->require_oper)
@@ -184,48 +178,65 @@ public:
root.Reply("vhost", nullptr);
else
root.Reply("vhost", o->vhost);
+ }
+ bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
+ {
+ const auto detail = request.data.empty() ? "name" : request.data[0];
+ if (detail.equals_ci("name"))
+ {
+ auto &root = request.Root<RPC::Array>();
+ for (auto *o : Oper::opers)
+ root.Reply(o->name);
+ }
+ else if (detail.equals_ci("full"))
+ {
+ auto &root = request.Root<RPC::Map>();
+ for (auto *o : Oper::opers)
+ GetInfo(o, root.ReplyMap(o->name));
+ }
+ else
+ {
+ request.Error(ERR_NO_SUCH_DETAIL, "No such detail level");
+ }
return true;
}
};
-class AnopeListServersRPCEvent final
+class AnopeOperRPCEvent final
: public RPC::Event
{
public:
- AnopeListServersRPCEvent(Module *o)
- : RPC::Event(o, "anope.listServers")
+ AnopeOperRPCEvent(Module *o)
+ : RPC::Event(o, "anope.oper", 1)
{
}
bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
{
- auto &root = request.Root<RPC::Array>();
- for (auto &[_, s] : Servers::ByName)
- root.Reply(s->GetName());
+ auto *o = Oper::Find(request.data[0]);
+ if (!o)
+ {
+ request.Error(ERR_NO_SUCH_TARGET, "No such oper");
+ return true;
+ }
+
+ AnopeListOpersRPCEvent::GetInfo(o, request.Root());
return true;
}
};
-class AnopeServerRPCEvent final
+class AnopeListServersRPCEvent final
: public RPC::Event
{
public:
- AnopeServerRPCEvent(Module *o)
- : RPC::Event(o, "anope.server")
+ AnopeListServersRPCEvent(Module *o)
+ : RPC::Event(o, "anope.listServers")
{
}
- bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
+ static void GetInfo(Server *s, RPC::Map &root)
{
- auto *s = Server::Find(request.data[0]);
- if (!s)
- {
- request.Error(ERR_NO_SUCH_TARGET, "No such server");
- return true;
- }
-
- auto &root = request.Root();
root.Reply("description", s->GetDescription())
.Reply("juped", s->IsJuped())
.Reply("name", s->GetName())
@@ -245,48 +256,65 @@ public:
root.Reply("uplink", s->GetUplink()->GetName());
else
root.Reply("uplink", nullptr);
+ }
+ bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
+ {
+ const auto detail = request.data.empty() ? "name" : request.data[0];
+ if (detail.equals_ci("name"))
+ {
+ auto &root = request.Root<RPC::Array>();
+ for (auto &[_, s] : Servers::ByName)
+ root.Reply(s->GetName());
+ }
+ else if (detail.equals_ci("full"))
+ {
+ auto &root = request.Root<RPC::Map>();
+ for (auto &[_, s] : Servers::ByName)
+ GetInfo(s, root.ReplyMap(s->GetName()));
+ }
+ else
+ {
+ request.Error(ERR_NO_SUCH_DETAIL, "No such detail level");
+ }
return true;
}
};
-class AnopeListUsersRPCEvent final
+class AnopeServerRPCEvent final
: public RPC::Event
{
public:
- AnopeListUsersRPCEvent(Module *o)
- : RPC::Event(0, "anope.listUsers")
+ AnopeServerRPCEvent(Module *o)
+ : RPC::Event(o, "anope.server")
{
}
bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
{
- auto &root = request.Root<RPC::Array>();
- for (auto &[_, u] : UserListByNick)
- root.Reply(u->nick);
+ auto *s = Server::Find(request.data[0]);
+ if (!s)
+ {
+ request.Error(ERR_NO_SUCH_TARGET, "No such server");
+ return true;
+ }
+
+ AnopeListServersRPCEvent::GetInfo(s, request.Root());
return true;
}
};
-class AnopeUserRPCEvent final
+class AnopeListUsersRPCEvent final
: public RPC::Event
{
public:
- AnopeUserRPCEvent(Module *o)
- : RPC::Event(o, "anope.user", 1)
+ AnopeListUsersRPCEvent(Module *o)
+ : RPC::Event(0, "anope.listUsers")
{
}
- bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
+ static void GetInfo(User *u, RPC::Map &root)
{
- auto *u = User::Find(request.data[0]);
- if (!u)
- {
- request.Error(ERR_NO_SUCH_TARGET, "No such user");
- return true;
- }
-
- auto &root = request.Root();
root.Reply("address", u->ip.addr())
.Reply("host", u->host)
.Reply("ident", u->GetIdent())
@@ -355,7 +383,50 @@ public:
root.Reply("vident", nullptr);
else
root.Reply("vident", u->GetIdent());
+ }
+
+ bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
+ {
+ const auto detail = request.data.empty() ? "name" : request.data[0];
+ if (detail.equals_ci("name"))
+ {
+ auto &root = request.Root<RPC::Array>();
+ for (auto &[_, u] : UserListByNick)
+ root.Reply(u->nick);
+ }
+ else if (detail.equals_ci("full"))
+ {
+ auto &root = request.Root<RPC::Map>();
+ for (auto &[_, u] : UserListByNick)
+ GetInfo(u, root.ReplyMap(u->nick));
+ }
+ else
+ {
+ request.Error(ERR_NO_SUCH_DETAIL, "No such detail level");
+ }
+ return true;
+ }
+};
+
+class AnopeUserRPCEvent final
+ : public RPC::Event
+{
+public:
+ AnopeUserRPCEvent(Module *o)
+ : RPC::Event(o, "anope.user", 1)
+ {
+ }
+
+ bool Run(RPC::ServiceInterface *iface, HTTPClient *client, RPC::Request &request) override
+ {
+ auto *u = User::Find(request.data[0]);
+ if (!u)
+ {
+ request.Error(ERR_NO_SUCH_TARGET, "No such user");
+ return true;
+ }
+ AnopeListUsersRPCEvent::GetInfo(u, request.Root());
return true;
}
};