mirror of
https://git.ngram.ca/OpenJam/rc-servers
synced 2026-08-23 23:08:52 +00:00
Fix total users chat command, add help command
This commit is contained in:
@@ -1,18 +0,0 @@
|
||||
{
|
||||
"commands": [
|
||||
{
|
||||
"regex": "\\?online",
|
||||
"op": {
|
||||
"type": "BuiltIn",
|
||||
"built_in": "OnlineUsers"
|
||||
}
|
||||
},
|
||||
{
|
||||
"regex": "\\?users",
|
||||
"op": {
|
||||
"type": "BuiltIn",
|
||||
"built_in": "TotalUsers"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -14462,6 +14462,13 @@
|
||||
"type": "BuiltIn",
|
||||
"built_in": "TotalUsers"
|
||||
}
|
||||
},
|
||||
{
|
||||
"regex": "\\?help",
|
||||
"op": {
|
||||
"type": "BuiltIn",
|
||||
"built_in": "Help"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -14539,4 +14546,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ impl <C: Send + 'static> SimpleOperation<C> for PrivateMessageSender {
|
||||
};
|
||||
let chat_system = self.chat.system().await;
|
||||
log::debug!("Got message `{}` from user {} (@ {} to {})", message_text.string, user.public_id(), chat_loc, username.string);
|
||||
chat_system.handle_private_message(user.as_ref().as_ref(), message_text.string, username.string);
|
||||
chat_system.handle_private_message(user.as_ref().as_ref(), message_text.string, username.string).await;
|
||||
}
|
||||
}
|
||||
Ok(params.into())
|
||||
|
||||
@@ -90,7 +90,7 @@ impl ChatSystem {
|
||||
pub async fn handle_public_message(&self, user: &(dyn oj_rc_core::persist::user::User<()> + Send + Sync), text: String, channel: String, channel_ty: crate::data::channel::ChatChannelType) {
|
||||
if self.config.is_command_channel(&channel) {
|
||||
if let Some(user_handle) = self.online_users.get(user.public_id()) {
|
||||
self.handle_public_command(user, text, user_handle, channel, channel_ty);
|
||||
self.handle_public_command(user, text, user_handle, channel, channel_ty).await;
|
||||
}
|
||||
} else if let Some(room) = self.chats.get(&channel) {
|
||||
let event_params = crate::events::chat_message::PublicMessage {
|
||||
@@ -109,11 +109,11 @@ impl ChatSystem {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_public_command(&self, user: &dyn oj_rc_core::persist::user::User<()>, text: String, handle: &super::UserHandle, channel: String, channel_ty: crate::data::channel::ChatChannelType) {
|
||||
async fn handle_public_command(&self, user: &dyn oj_rc_core::persist::user::User<()>, text: String, handle: &super::UserHandle, channel: String, channel_ty: crate::data::channel::ChatChannelType) {
|
||||
let event_params = crate::events::chat_message::PublicMessage {
|
||||
sender_name: self.config.command_username().to_owned(),
|
||||
sender_display_name: self.config.command_username().to_owned(),
|
||||
text: self.config.perform_command(&text, self, user),
|
||||
text: self.config.perform_command(&text, self, user).await,
|
||||
is_dev: false,
|
||||
is_mod: false,
|
||||
is_admin: false,
|
||||
@@ -132,10 +132,10 @@ impl ChatSystem {
|
||||
handle.send(polariton_server::ToSend::Data { data: polariton::packet::Data::Event(event), encrypt: true, channel: 0, reliable: true });
|
||||
}
|
||||
|
||||
pub fn handle_private_message(&self, user: &dyn oj_rc_core::persist::user::User<()>, text: String, recipient: String) {
|
||||
pub async fn handle_private_message(&self, user: &dyn oj_rc_core::persist::user::User<()>, text: String, recipient: String) {
|
||||
if self.config.is_command_user(&recipient) {
|
||||
if let Some(user_handle) = self.online_users.get(user.public_id()) {
|
||||
self.handle_private_command(user, text, user_handle);
|
||||
self.handle_private_command(user, text, user_handle).await;
|
||||
}
|
||||
} else if let Some(recipient_handle) = self.online_users.get(&recipient) {
|
||||
let private_msg = crate::events::chat_message::PrivateMessage {
|
||||
@@ -150,11 +150,11 @@ impl ChatSystem {
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_private_command(&self, user: &dyn oj_rc_core::persist::user::User<()>, text: String, handle: &super::UserHandle) {
|
||||
async fn handle_private_command(&self, user: &dyn oj_rc_core::persist::user::User<()>, text: String, handle: &super::UserHandle) {
|
||||
let event_params = crate::events::chat_message::PrivateMessage {
|
||||
sender_name: self.config.command_username().to_owned(),
|
||||
sender_display_name: self.config.command_username().to_owned(),
|
||||
text: self.config.perform_command(&text, self, user),
|
||||
text: self.config.perform_command(&text, self, user).await,
|
||||
is_dev: false,
|
||||
is_mod: false,
|
||||
is_admin: false,
|
||||
@@ -182,4 +182,8 @@ impl ChatSystem {
|
||||
pub fn is_user_online(&self, display_name: &str) -> bool {
|
||||
self.config.is_command_user(display_name) || self.online_users.get(display_name).map(|x| x.is_online()).unwrap_or(false)
|
||||
}
|
||||
|
||||
pub fn chat_config(&self) -> &'_ super::ChatSystemConfig {
|
||||
&self.config
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ pub struct ChatSystemConfig {
|
||||
#[derive(Clone, Copy)]
|
||||
struct CommandContext<'a, 'b> {
|
||||
chat_system: &'a super::ChatSystem,
|
||||
user: &'b dyn oj_rc_core::persist::user::User<()>,
|
||||
user: &'b dyn oj_rc_core::persist::user::ChatUser,
|
||||
}
|
||||
|
||||
impl ChatSystemConfig {
|
||||
@@ -26,13 +26,13 @@ impl ChatSystemConfig {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn perform_command(&self, text: &str, chat_system: &super::ChatSystem, user: &dyn oj_rc_core::persist::user::User<()>,) -> String {
|
||||
pub async fn perform_command(&self, text: &str, chat_system: &super::ChatSystem, user: &dyn oj_rc_core::persist::user::ChatUser,) -> String {
|
||||
let ctx = CommandContext {
|
||||
chat_system,
|
||||
user,
|
||||
};
|
||||
for cmd in self.commands.iter() {
|
||||
if let Some(result) = cmd.perform_if_match(text, ctx) {
|
||||
if let Some(result) = cmd.perform_if_match(text, ctx).await {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
@@ -65,8 +65,12 @@ impl ChatCommand {
|
||||
})
|
||||
}
|
||||
|
||||
fn perform_if_match(&self, text: &str, ctx: CommandContext) -> Option<String> {
|
||||
self.regex.captures(text).map(|cap| self.op.perform_command(cap, ctx))
|
||||
async fn perform_if_match<'b, 'c>(&self, text: &str, ctx: CommandContext<'b, 'c>) -> Option<String> {
|
||||
if let Some(cap) = self.regex.captures(text) {
|
||||
Some(self.op.perform_command(cap, ctx).await)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,18 +89,27 @@ impl ChatOperation {
|
||||
}
|
||||
}
|
||||
|
||||
fn perform_command<'a>(&self, _captures: regex::Captures<'a>, ctx: CommandContext) -> String {
|
||||
async fn perform_command<'a, 'b, 'c>(&self, _captures: regex::Captures<'a>, ctx: CommandContext<'b, 'c>) -> String {
|
||||
match self {
|
||||
Self::BuiltIn(b_in) => b_in.do_command(ctx),
|
||||
Self::BuiltIn(b_in) => b_in.do_command(ctx).await,
|
||||
Self::Custom => "{not implemented}".to_owned(),
|
||||
Self::Nop => "{no op}".to_owned(),
|
||||
}
|
||||
}
|
||||
|
||||
fn help_str(&self) -> String {
|
||||
match self {
|
||||
Self::BuiltIn(b_in) => b_in.do_help(),
|
||||
Self::Custom => "{not implemented}".to_owned(),
|
||||
Self::Nop => "does nothing".to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum BuiltIn {
|
||||
OnlineUsers,
|
||||
TotalUsers,
|
||||
Help,
|
||||
}
|
||||
|
||||
impl BuiltIn {
|
||||
@@ -104,10 +117,15 @@ impl BuiltIn {
|
||||
match b_in {
|
||||
oj_rc_core::persist::BuiltInChatOperation::OnlineUsers => Self::OnlineUsers,
|
||||
oj_rc_core::persist::BuiltInChatOperation::TotalUsers => Self::TotalUsers,
|
||||
oj_rc_core::persist::BuiltInChatOperation::Help => Self::Help,
|
||||
}
|
||||
}
|
||||
|
||||
fn do_command(&self, ctx: CommandContext) -> String {
|
||||
fn prettify_re<'a>(regex: &'a str) -> &'a str {
|
||||
regex.trim_start_matches("\\")
|
||||
}
|
||||
|
||||
async fn do_command<'b, 'c>(&self, ctx: CommandContext<'b, 'c>) -> String {
|
||||
match self {
|
||||
Self::OnlineUsers => {
|
||||
let online_count = ctx.chat_system.user_count();
|
||||
@@ -118,8 +136,35 @@ impl BuiltIn {
|
||||
}
|
||||
},
|
||||
Self::TotalUsers => {
|
||||
"User count is not supported".to_string()
|
||||
match ctx.user.get_total_registered_users().await {
|
||||
Ok(count) => if count == 1 {
|
||||
"1 user registered".to_owned()
|
||||
} else {
|
||||
format!("{} users registered", count)
|
||||
},
|
||||
Err(e) => e.error_msg().map(|x| x.to_owned()).unwrap_or_else(|| "Failed to retrieve registered users".to_owned()),
|
||||
}
|
||||
},
|
||||
Self::Help => {
|
||||
use core::fmt::Write;
|
||||
let mut msg = String::new();
|
||||
for command in ctx.chat_system.chat_config().commands.iter() {
|
||||
let raw_re = command.regex.to_string();
|
||||
let pretty_name = Self::prettify_re(&raw_re);
|
||||
if let Err(e) = write!(msg, "\n{}: {}", pretty_name, command.op.help_str()) {
|
||||
log::warn!("Failed to construct help for command `{}`: {}", pretty_name, e);
|
||||
}
|
||||
}
|
||||
msg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn do_help(&self) -> String {
|
||||
match self {
|
||||
Self::OnlineUsers => "Show total users online".to_owned(),
|
||||
Self::TotalUsers => "Show total users registered".to_owned(),
|
||||
Self::Help => "Display this message".to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ pub enum ChatOperation {
|
||||
pub enum BuiltInChatOperation {
|
||||
OnlineUsers,
|
||||
TotalUsers,
|
||||
Help,
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1337,4 +1337,15 @@ impl super::ChatUser for UserData {
|
||||
Err(crate::data::error_codes::ChatErrorCodes::DoesNotExist as i16)
|
||||
}
|
||||
}
|
||||
|
||||
async fn get_total_registered_users(&self) -> Result<u64, polariton_server::operations::SimpleOpError> {
|
||||
self.db.user_count().await
|
||||
.map_err(|e| {
|
||||
log::error!("Failed to retrieve total user count for {}: {}", self.account.id, e);
|
||||
polariton_server::operations::SimpleOpError::with_message(
|
||||
crate::data::error_codes::ChatErrorCodes::UnexpectedError as i16,
|
||||
format!("Failed to retrieve total user count: {}", e),
|
||||
)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -211,6 +211,7 @@ pub trait ChatUser: CommonUser {
|
||||
//async fn has_pending_sanctions(&self) -> Result<bool, i16>;
|
||||
async fn get_sanctions(&self, username: String) -> Result<polariton::operation::Typed<()>, i16>;
|
||||
async fn set_sanction(&self, sanction: SetSanction) -> Result<(), i16>;
|
||||
async fn get_total_registered_users(&self) -> Result<u64, polariton_server::operations::SimpleOpError>;
|
||||
}
|
||||
|
||||
pub struct SetSanction {
|
||||
|
||||
@@ -15,6 +15,12 @@ impl Database {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn user_count(&self) -> Result<u64, sea_orm::DbErr> {
|
||||
crate::schema::user::Entity::find()
|
||||
.count(&self.orm)
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn user_by_display_name(&self, public_id: String) -> Result<Option<crate::schema::user::Model>, sea_orm::DbErr> {
|
||||
crate::schema::user::Entity::find()
|
||||
.filter(crate::schema::user::Column::DisplayName.eq(public_id))
|
||||
|
||||
@@ -472,6 +472,13 @@ def main(asset_in, cubes=None, weapons=None, movement=None):
|
||||
"type": "BuiltIn",
|
||||
"built_in": "TotalUsers"
|
||||
}
|
||||
},
|
||||
{
|
||||
"regex": "\\?help",
|
||||
"op": {
|
||||
"type": "BuiltIn",
|
||||
"built_in": "Help"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user