Room State Management #44

Manually merged
projectmoon merged 11 commits from room-state-management into master 2020-11-10 20:58:50 +00:00
2 changed files with 28 additions and 4 deletions
Showing only changes of commit 9ed2a81dd3 - Show all commits

View File

@ -9,7 +9,8 @@ use matrix_sdk::{
room::message::{MessageEventContent, TextMessageEventContent}, room::message::{MessageEventContent, TextMessageEventContent},
StrippedStateEvent, SyncMessageEvent, SyncStateEvent, StrippedStateEvent, SyncMessageEvent, SyncStateEvent,
}, },
EventEmitter, SyncRoom, identifiers::RoomId,
Client, EventEmitter, SyncRoom,
}; };
//use matrix_sdk_common_macros::async_trait; //use matrix_sdk_common_macros::async_trait;
use super::DiceBot; use super::DiceBot;
@ -92,6 +93,19 @@ fn should_process_event(db: &Database, room_id: &str, event_id: &str) -> bool {
}) })
} }
async fn get_users_in_room(client: &Client, room_id: &RoomId) -> Vec<String> {
if let Some(joined_room) = client.get_joined_room(room_id).await {
let joined_room: matrix_sdk::Room = joined_room.read().await.clone();
joined_room
.joined_members
.keys()
.map(|user_id| format!("@{}:{}", user_id.localpart(), user_id.server_name()))
.collect()
} else {
vec![]
}
}
/// This event emitter listens for messages with dice rolling commands. /// This event emitter listens for messages with dice rolling commands.
/// Originally adapted from the matrix-rust-sdk examples. /// Originally adapted from the matrix-rust-sdk examples.
#[async_trait] #[async_trait]
@ -124,7 +138,12 @@ impl EventEmitter for DiceBot {
self.db.rooms.clear_info(room_id) self.db.rooms.clear_info(room_id)
} else if event_affects_us && adding_user { } else if event_affects_us && adding_user {
info!("Joined room {}; recording user information", room_id); info!("Joined room {}; recording user information", room_id);
Ok(()) let usernames = get_users_in_room(&self.client, &room.room_id).await;
usernames
.into_iter()
.filter(|username| username != &event.state_key)
.map(|username| self.db.rooms.add_user_to_room(&username, room_id))
.collect() //Make use of collect impl on Result.
} else if !event_affects_us && adding_user { } else if !event_affects_us && adding_user {
info!("Adding user {} to room ID {}", username, room_id); info!("Adding user {} to room ID {}", username, room_id);
self.db.rooms.add_user_to_room(username, room_id) self.db.rooms.add_user_to_room(username, room_id)

View File

@ -1,7 +1,7 @@
use crate::db::errors::DataError; use crate::db::errors::DataError;
use crate::db::schema::convert_u64; use crate::db::schema::convert_u64;
use byteorder::BigEndian; use byteorder::BigEndian;
use log::{error, log_enabled, trace}; use log::{debug, error, log_enabled, trace};
use sled::transaction::TransactionalTree; use sled::transaction::TransactionalTree;
use sled::Transactional; use sled::Transactional;
use sled::{CompareAndSwapError, Tree}; use sled::{CompareAndSwapError, Tree};
@ -134,12 +134,14 @@ mod timestamp_index {
) -> Result<(), DataError> { ) -> Result<(), DataError> {
let parts: Vec<&[u8]> = key.split(|&b| b == 0xff).collect(); let parts: Vec<&[u8]> = key.split(|&b| b == 0xff).collect();
if let [room_id, event_id] = parts[..] { if let [room_id, event_id] = parts[..] {
let event_id = str::from_utf8(event_id)?;
debug!("Adding event ID {} to timestamp index", event_id);
let mut ts_key = room_id.to_vec(); let mut ts_key = room_id.to_vec();
ts_key.push(0xff); ts_key.push(0xff);
ts_key.extend_from_slice(&timestamp_bytes); ts_key.extend_from_slice(&timestamp_bytes);
trace_index_record(room_id, event_id, &timestamp_bytes); trace_index_record(room_id, event_id, &timestamp_bytes);
let event_id = str::from_utf8(event_id)?;
hashset_tree::add_to_set(roomtimestamp_eventid, &ts_key, event_id.to_owned())?; hashset_tree::add_to_set(roomtimestamp_eventid, &ts_key, event_id.to_owned())?;
Ok(()) Ok(())
} else { } else {
@ -234,6 +236,7 @@ impl Rooms {
} }
pub fn add_user_to_room(&self, username: &str, room_id: &str) -> Result<(), DataError> { pub fn add_user_to_room(&self, username: &str, room_id: &str) -> Result<(), DataError> {
debug!("Adding user {} to room {}", username, room_id);
(&self.username_roomids, &self.roomid_usernames).transaction( (&self.username_roomids, &self.roomid_usernames).transaction(
|(tx_username_rooms, tx_room_usernames)| { |(tx_username_rooms, tx_room_usernames)| {
let username_key = &username.as_bytes(); let username_key = &username.as_bytes();
@ -250,6 +253,7 @@ impl Rooms {
} }
pub fn remove_user_from_room(&self, username: &str, room_id: &str) -> Result<(), DataError> { pub fn remove_user_from_room(&self, username: &str, room_id: &str) -> Result<(), DataError> {
debug!("Removing user {} from room {}", username, room_id);
(&self.username_roomids, &self.roomid_usernames).transaction( (&self.username_roomids, &self.roomid_usernames).transaction(
|(tx_username_rooms, tx_room_usernames)| { |(tx_username_rooms, tx_room_usernames)| {
let username_key = &username.as_bytes(); let username_key = &username.as_bytes();
@ -266,6 +270,7 @@ impl Rooms {
} }
pub fn clear_info(&self, room_id: &str) -> Result<(), DataError> { pub fn clear_info(&self, room_id: &str) -> Result<(), DataError> {
debug!("Clearing all information for room {}", room_id);
(&self.username_roomids, &self.roomid_usernames).transaction( (&self.username_roomids, &self.roomid_usernames).transaction(
|(tx_username_roomids, tx_roomid_usernames)| { |(tx_username_roomids, tx_roomid_usernames)| {
let roomid_key = room_id.as_bytes(); let roomid_key = room_id.as_bytes();