Replave give and take modes with admin_access mode

This commit is contained in:
Jeff 2024-07-11 11:43:52 -04:00
parent e622ab1add
commit 658cde2be3
2 changed files with 53 additions and 37 deletions

View File

@ -71,3 +71,11 @@ podman build . -t trade_bot
``` ```
Then follow the [above](#running) steps with the tag "trade_bot" instead of "git.jeffa.io/jeff/trade_bot". Then follow the [above](#running) steps with the tag "trade_bot" instead of "git.jeffa.io/jeff/trade_bot".
### In-Game Commands
The bot is able to respond to the following commands, which must be sent via "/tell".
- `price [search term]`: Returns the buy/sell offers of any item whose item definition ID contains the search term.
- `admin_access`: Admin-only, prompts the bot to send a trade invite, after which it will give away and accept any items until the trade ends.
- `sort [count (optional)]`: Admin-only, sorts the inventory once or the given number of times.

View File

@ -127,8 +127,13 @@ impl Bot {
if let Some((_, trade, _)) = self.client.pending_trade() { if let Some((_, trade, _)) = self.client.pending_trade() {
match self.trade_mode { match self.trade_mode {
TradeMode::AdminAccess => {
if !trade.is_empty_trade() {
self.client
.perform_trade_action(TradeAction::Accept(trade.phase));
}
}
TradeMode::Trade => self.handle_trade(trade.clone())?, TradeMode::Trade => self.handle_trade(trade.clone())?,
TradeMode::Take => self.handle_take(trade.clone())?,
} }
} else if self.client.pending_invites().is_empty() { } else if self.client.pending_invites().is_empty() {
self.client.accept_invite(); self.client.accept_invite();
@ -171,26 +176,39 @@ impl Bot {
match command { match command {
"price" => { "price" => {
for item_name in split_content { for item_name in split_content {
self.send_price_info(&sender, &item_name.to_lowercase())?;
is_correct_format = true; is_correct_format = true;
self.send_price_info(&sender, &item_name.to_lowercase())?;
} }
} }
"take" => { "sort" => {
let sender_uuid = self if self.is_user_admin(&sender)? {
.find_uuid(&sender) is_correct_format = true;
.ok_or("Failed to find uuid")?
.to_string();
let sender_name = self.find_name(&sender).ok_or("Failed to find name")?;
let sender_is_admin =
self.admins.contains(&sender_uuid) || self.admins.contains(sender_name);
if sender_is_admin && !self.client.is_trading() { if let Some(sort_count) = split_content.next() {
self.trade_mode = TradeMode::Take; let sort_count = sort_count
.parse::<u8>()
.map_err(|error| error.to_string())?;
log::debug!("Sorting inventory {sort_count} times");
for _ in 0..sort_count {
self.client.sort_inventory();
}
} else {
log::debug!("Sorting inventory");
self.client.sort_inventory();
}
}
}
"admin_access" => {
if self.is_user_admin(&sender)? && !self.client.is_trading() {
log::debug!("Providing admin access");
is_correct_format = true;
self.trade_mode = TradeMode::AdminAccess;
self.client.send_invite(sender, InviteKind::Trade); self.client.send_invite(sender, InviteKind::Trade);
} }
is_correct_format = true;
} }
_ => {} _ => {}
} }
@ -250,7 +268,7 @@ impl Bot {
log::info!("End of trade with {their_name}: {result:?}"); log::info!("End of trade with {their_name}: {result:?}");
if let TradeMode::Take = self.trade_mode { if let TradeMode::AdminAccess = self.trade_mode {
self.trade_mode = TradeMode::Trade; self.trade_mode = TradeMode::Trade;
} }
@ -485,26 +503,6 @@ impl Bot {
Ok(()) Ok(())
} }
fn handle_take(&mut self, trade: PendingTrade) -> Result<(), String> {
let my_offer_index = trade
.which_party(self.client.uid().ok_or("Failed to get uid")?)
.ok_or("Failed to get offer index")?;
let their_offer_index = if my_offer_index == 0 { 1 } else { 0 };
let (my_offer, their_offer) = {
(
&trade.offers[my_offer_index],
&trade.offers[their_offer_index],
)
};
if my_offer.is_empty() && !their_offer.is_empty() {
self.client
.perform_trade_action(TradeAction::Accept(trade.phase));
}
Ok(())
}
fn send_price_info(&mut self, target: &Uid, item_name: &str) -> Result<(), String> { fn send_price_info(&mut self, target: &Uid, item_name: &str) -> Result<(), String> {
let player_name = self let player_name = self
.find_name(target) .find_name(target)
@ -560,6 +558,16 @@ impl Bot {
Ok(()) Ok(())
} }
fn is_user_admin(&self, uid: &Uid) -> Result<bool, String> {
let sender_uuid = self
.find_uuid(uid)
.ok_or("Failed to find uuid")?
.to_string();
let sender_name = self.find_name(uid).ok_or("Failed to find name")?;
Ok(self.admins.contains(sender_name) || self.admins.contains(&sender_uuid))
}
fn find_name<'a>(&'a self, uid: &Uid) -> Option<&'a String> { fn find_name<'a>(&'a self, uid: &Uid) -> Option<&'a String> {
self.client.player_list().iter().find_map(|(id, info)| { self.client.player_list().iter().find_map(|(id, info)| {
if id == uid { if id == uid {
@ -618,7 +626,7 @@ impl Bot {
} }
enum TradeMode { enum TradeMode {
Take, AdminAccess,
Trade, Trade,
} }