feat: expose speedgame to commands

This commit is contained in:
Anna 2021-08-20 18:21:05 -04:00
parent 6257e7e57a
commit ae36d47738
4 changed files with 56 additions and 8 deletions

View File

@ -61,6 +61,8 @@ pub struct State {
pub rhai: Engine,
pub script_cache: parking_lot::RwLock<HashMap<String, rhai::AST>>,
pub runtime: Handle,
pub speedgame: RwLock<(Option<String>, Option<String>)>,
}
impl State {
@ -129,6 +131,8 @@ impl State {
.register_get("moderator", ExecutorState::moderator)
.register_get("vip", ExecutorState::vip)
.register_get("subscriber", ExecutorState::subscriber)
.register_get("speedgame_name", ExecutorState::speedgame_name)
.register_get("speedgame_category", ExecutorState::speedgame_category)
.register_fn("get_username", ExecutorState::get_username::<&str>)
.register_fn("get_user_id", ExecutorState::get_user_id::<&str>)
.register_fn("get_channel_info", ExecutorState::get_channel_info::<&str>);
@ -156,6 +160,8 @@ impl State {
rhai,
script_cache: Default::default(),
runtime,
speedgame: RwLock::new((None, None)),
});
// start web task

View File

@ -32,6 +32,9 @@ pub struct ExecutorState {
pub vip: bool,
/// Always false if this is a channel point reward event
pub subscriber: bool,
pub speedgame_name: Option<String>,
pub speedgame_category: Option<String>,
}
impl ExecutorState {
@ -64,6 +67,20 @@ impl ExecutorState {
self.subscriber
}
pub fn speedgame_name(&mut self) -> rhai::Dynamic {
match &self.speedgame_name {
Some(name) => name.clone().into(),
None => ().into(),
}
}
pub fn speedgame_category(&mut self) -> rhai::Dynamic {
match &self.speedgame_category {
Some(cat) => cat.clone().into(),
None => ().into(),
}
}
pub fn get_username<S: Into<UserId>>(&mut self, id: S) -> rhai::Dynamic {
self.state.runtime.block_on(self.state.get_user_from_id(id))
.ok()

View File

@ -106,6 +106,8 @@ async fn on_privmsg(state: Arc<State>, event: &Message, message: &str) -> anyhow
match &command.executor {
CommandExecutor::Text(t) => { state.irc_queue.send(t.to_string()).ok(); }
CommandExecutor::Rhai(t) => {
let (speedgame_name, speedgame_category) = state.speedgame.read().await.clone();
let fn_state = ExecutorState {
state: Arc::clone(&state),
args,
@ -115,6 +117,8 @@ async fn on_privmsg(state: Arc<State>, event: &Message, message: &str) -> anyhow
moderator,
vip,
subscriber,
speedgame_name,
speedgame_category,
};
crate::app::run_rhai(Arc::clone(&state), t, fn_state);
}
@ -153,6 +157,8 @@ pub async fn handle_pubsub(state: Arc<State>, event: WsMessage) -> anyhow::Resul
None => return Ok(()),
};
let (speedgame_name, speedgame_category) = state.speedgame.read().await.clone();
let args = redemption.user_input
.map(|input| input.split(' ').map(ToOwned::to_owned).map(rhai::Dynamic::from).collect())
.unwrap_or_default();
@ -165,6 +171,8 @@ pub async fn handle_pubsub(state: Arc<State>, event: WsMessage) -> anyhow::Resul
moderator: false,
vip: false,
subscriber: false,
speedgame_name,
speedgame_category,
};
crate::app::run_rhai(Arc::clone(&state), &action.rhai, fn_state);

View File

@ -21,7 +21,7 @@ pub fn livesplit_routes(state: Arc<State>) -> BoxedFilter<(impl Reply, )> {
struct RewardPauseInfo {
id: &'static str,
games: &'static [(&'static str, isize)],
games: &'static [(&'static str, &'static str, isize)],
}
const REWARDS: &[RewardPauseInfo] = &[
@ -30,7 +30,7 @@ const REWARDS: &[RewardPauseInfo] = &[
id: "8ac47f16-2396-4c2d-9c43-d30bd9074a4f",
games: &[
// in RCT1, only enable after the third split
("RollerCoaster Tycoon 1", 3),
("RollerCoaster Tycoon 1", "All Base Scenarios (OpenRCT2)", 3),
],
},
@ -39,7 +39,7 @@ const REWARDS: &[RewardPauseInfo] = &[
id: "0da50268-3237-4832-9849-9baac518e4de",
games: &[
// in RCT1, only enable after the third split
("RollerCoaster Tycoon 1", 3),
("RollerCoaster Tycoon 1", "All Base Scenarios (OpenRCT2)", 3),
],
},
];
@ -61,12 +61,19 @@ async fn set_rewards_paused(state: Arc<State>, data: LiveSplitBody, paused: bool
let mut results = Vec::with_capacity(REWARDS.len());
for info in REWARDS {
let is_paused = state.rewards_paused.read().await.get(info.id).copied();
let should_apply = match info.games.iter().find(|(name, _)| data.run.game_name.as_deref().map(|run_name| run_name == *name).unwrap_or_default()) {
Some((_, split_idx)) => {
let should_apply = match info.games
.iter()
.find(|&&(name, category, _)| {
let game_matches = data.run.game_name.as_deref().map(|run_name| run_name == name).unwrap_or_default();
let category_matches = data.run.category_name.as_deref().map(|cat_name| cat_name == category).unwrap_or_default();
game_matches && category_matches
})
{
Some(&(_, _, split_idx)) => {
// if we're unpausing and the current split index is gte to the configured index for this game
if !paused && data.current_split_index >= *split_idx {
if !paused && data.current_split_index >= split_idx {
true
} else if !paused && data.current_split_index < *split_idx {
} else if !paused && data.current_split_index < split_idx {
false
} else {
true
@ -119,7 +126,17 @@ fn livesplit_route(state: Arc<State>, path: &'static str, paused: bool) -> Boxed
.and(warp::body::json())
.and_then(move |body: LiveSplitBody| {
let state = Arc::clone(&state);
rewards_filter(state, body, paused)
async move {
let mut speedgame = state.speedgame.write().await;
if body.run.game_name.is_some() || body.run.category_name.is_some() {
*speedgame = (
body.run.game_name.clone(),
body.run.category_name.clone(),
);
}
drop(speedgame);
rewards_filter(state, body, paused).await
}
})
.untuple_one()
.map(|| warp::reply())