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",
|
"type": "BuiltIn",
|
||||||
"built_in": "TotalUsers"
|
"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;
|
let chat_system = self.chat.system().await;
|
||||||
log::debug!("Got message `{}` from user {} (@ {} to {})", message_text.string, user.public_id(), chat_loc, username.string);
|
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())
|
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) {
|
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 self.config.is_command_channel(&channel) {
|
||||||
if let Some(user_handle) = self.online_users.get(user.public_id()) {
|
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) {
|
} else if let Some(room) = self.chats.get(&channel) {
|
||||||
let event_params = crate::events::chat_message::PublicMessage {
|
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 {
|
let event_params = crate::events::chat_message::PublicMessage {
|
||||||
sender_name: self.config.command_username().to_owned(),
|
sender_name: self.config.command_username().to_owned(),
|
||||||
sender_display_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_dev: false,
|
||||||
is_mod: false,
|
is_mod: false,
|
||||||
is_admin: 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 });
|
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 self.config.is_command_user(&recipient) {
|
||||||
if let Some(user_handle) = self.online_users.get(user.public_id()) {
|
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) {
|
} else if let Some(recipient_handle) = self.online_users.get(&recipient) {
|
||||||
let private_msg = crate::events::chat_message::PrivateMessage {
|
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 {
|
let event_params = crate::events::chat_message::PrivateMessage {
|
||||||
sender_name: self.config.command_username().to_owned(),
|
sender_name: self.config.command_username().to_owned(),
|
||||||
sender_display_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_dev: false,
|
||||||
is_mod: false,
|
is_mod: false,
|
||||||
is_admin: false,
|
is_admin: false,
|
||||||
@@ -182,4 +182,8 @@ impl ChatSystem {
|
|||||||
pub fn is_user_online(&self, display_name: &str) -> bool {
|
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)
|
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)]
|
#[derive(Clone, Copy)]
|
||||||
struct CommandContext<'a, 'b> {
|
struct CommandContext<'a, 'b> {
|
||||||
chat_system: &'a super::ChatSystem,
|
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 {
|
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 {
|
let ctx = CommandContext {
|
||||||
chat_system,
|
chat_system,
|
||||||
user,
|
user,
|
||||||
};
|
};
|
||||||
for cmd in self.commands.iter() {
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,8 +65,12 @@ impl ChatCommand {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn perform_if_match(&self, text: &str, ctx: CommandContext) -> Option<String> {
|
async fn perform_if_match<'b, 'c>(&self, text: &str, ctx: CommandContext<'b, 'c>) -> Option<String> {
|
||||||
self.regex.captures(text).map(|cap| self.op.perform_command(cap, ctx))
|
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 {
|
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::Custom => "{not implemented}".to_owned(),
|
||||||
Self::Nop => "{no op}".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 {
|
enum BuiltIn {
|
||||||
OnlineUsers,
|
OnlineUsers,
|
||||||
TotalUsers,
|
TotalUsers,
|
||||||
|
Help,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuiltIn {
|
impl BuiltIn {
|
||||||
@@ -104,10 +117,15 @@ impl BuiltIn {
|
|||||||
match b_in {
|
match b_in {
|
||||||
oj_rc_core::persist::BuiltInChatOperation::OnlineUsers => Self::OnlineUsers,
|
oj_rc_core::persist::BuiltInChatOperation::OnlineUsers => Self::OnlineUsers,
|
||||||
oj_rc_core::persist::BuiltInChatOperation::TotalUsers => Self::TotalUsers,
|
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 {
|
match self {
|
||||||
Self::OnlineUsers => {
|
Self::OnlineUsers => {
|
||||||
let online_count = ctx.chat_system.user_count();
|
let online_count = ctx.chat_system.user_count();
|
||||||
@@ -118,8 +136,35 @@ impl BuiltIn {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
Self::TotalUsers => {
|
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 {
|
pub enum BuiltInChatOperation {
|
||||||
OnlineUsers,
|
OnlineUsers,
|
||||||
TotalUsers,
|
TotalUsers,
|
||||||
|
Help,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1337,4 +1337,15 @@ impl super::ChatUser for UserData {
|
|||||||
Err(crate::data::error_codes::ChatErrorCodes::DoesNotExist as i16)
|
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 has_pending_sanctions(&self) -> Result<bool, i16>;
|
||||||
async fn get_sanctions(&self, username: String) -> Result<polariton::operation::Typed<()>, i16>;
|
async fn get_sanctions(&self, username: String) -> Result<polariton::operation::Typed<()>, i16>;
|
||||||
async fn set_sanction(&self, sanction: SetSanction) -> Result<(), 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 {
|
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> {
|
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()
|
crate::schema::user::Entity::find()
|
||||||
.filter(crate::schema::user::Column::DisplayName.eq(public_id))
|
.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",
|
"type": "BuiltIn",
|
||||||
"built_in": "TotalUsers"
|
"built_in": "TotalUsers"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"regex": "\\?help",
|
||||||
|
"op": {
|
||||||
|
"type": "BuiltIn",
|
||||||
|
"built_in": "Help"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user