Fixed spell descriptions

This commit is contained in:
Benjamin Sherriff
2023-10-08 18:16:03 -04:00
parent 6c3d29d705
commit 09925251dd
12 changed files with 106 additions and 51 deletions

View File

@@ -1,5 +1,5 @@
CREATE TABLE IF NOT EXISTS guilds ( CREATE TABLE IF NOT EXISTS guilds (
id BIGINT PRIMARY KEY NOT NULL, id BIGINT PRIMARY KEY NOT NULL,
bot_id BIGINT NOT NULL, bot_id BIGINT NOT NULL,
volume DOUBLE PRECISION NOT NULL volume INTEGER NOT NULL
); );

View File

@@ -291,16 +291,17 @@ async fn set_volume(path: web::Path<String>, volume: web::Json::<SetVolume>, dat
} }
}; };
let bound_volume = volume.volume.parse::<f32>().unwrap_or(0.0); let volume = volume.volume.parse::<i32>().unwrap_or(0);
let manager = Arc::clone(&data.songbird);
let _ = InsertGuild::update_audio(guild_id as i64, bound_volume as f64); let http = Arc::clone(&data.http);
let guild = match http.get_guild(guild_id).await {
if let Some(handler_lock) = data.songbird.get(guild_id) { Ok(guild) => guild,
let handler = handler_lock.lock().await; Err(err) => {
for (_, track_handle) in handler.queue().current_queue().iter().enumerate() { warn!("Could not get guild: {:?}", err);
let _ = track_handle.set_volume(bound_volume); return ResponseError::error_response(&ServiceError { status: 422, message: err.to_string() })
}
} }
};
crate::bot::commands::audio::volume::set_volume(manager, guild.id, volume).await;
HttpResponse::Ok().finish() HttpResponse::Ok().finish()
} }

View File

@@ -1,8 +1,11 @@
use std::sync::Arc;
use log::{error, warn}; use log::{error, warn};
use serenity::prelude::*; use serenity::{prelude::*, model::prelude::GuildId};
use serenity::builder::CreateApplicationCommand; use serenity::builder::CreateApplicationCommand;
use serenity::model::application::interaction::application_command::ApplicationCommandInteraction; use serenity::model::application::interaction::application_command::ApplicationCommandInteraction;
use songbird::Songbird;
use crate::db::guilds::InsertGuild; use crate::db::guilds::InsertGuild;
@@ -13,7 +16,7 @@ pub async fn run(ctx: &Context, command: &ApplicationCommandInteraction) {
let volume = match command.data.options.get(0) { let volume = match command.data.options.get(0) {
Some(t) => match &t.value { Some(t) => match &t.value {
Some(v) => match v.as_i64() { Some(v) => match v.as_i64() {
Some(p) => std::cmp::min(100, std::cmp::max(0, p)), Some(p) => p as i32,
None => { None => {
warn!("Unable to get volume option as a string"); warn!("Unable to get volume option as a string");
if let Err(why) = create_response(&ctx, &command, format!("Volume option is missing")).await { if let Err(why) = create_response(&ctx, &command, format!("Volume option is missing")).await {
@@ -39,9 +42,6 @@ pub async fn run(ctx: &Context, command: &ApplicationCommandInteraction) {
} }
}; };
// Format volume to f32 bound between 0.0 and 1.0
let bound_volume = volume as f32 / 100.0;
// Create the initial response // Create the initial response
if let Err(why) = create_response(&ctx, &command, "Processing command...".to_string()).await { if let Err(why) = create_response(&ctx, &command, "Processing command...".to_string()).await {
error!("Failed to create response message: {}", why); error!("Failed to create response message: {}", why);
@@ -57,17 +57,25 @@ pub async fn run(ctx: &Context, command: &ApplicationCommandInteraction) {
return; return;
} }
}; };
let _ = InsertGuild::update_audio(guild_id.0 as i64, bound_volume as f64);
let manager = get_songbird(ctx).await; let manager = get_songbird(ctx).await;
set_volume(manager, guild_id, volume).await;
if let Err(why) = edit_response(&ctx, &command, format!("Setting the volume to {}", volume)).await {
error!("Failed to set the volume: {}", why);
}
}
pub async fn set_volume(manager: Arc<Songbird>, guild_id: GuildId, volume: i32) {
// Format volume to f32 bound between 0.0 and 1.0
let volume = std::cmp::min(100, std::cmp::max(0, volume));
let bound_volume = volume as f32 / 100.0;
let _ = InsertGuild::update_audio(guild_id.0 as i64, volume);
if let Some(handler_lock) = manager.get(guild_id) { if let Some(handler_lock) = manager.get(guild_id) {
let handler = handler_lock.lock().await; let handler = handler_lock.lock().await;
for (_, track_handle) in handler.queue().current_queue().iter().enumerate() { for (_, track_handle) in handler.queue().current_queue().iter().enumerate() {
let _ = track_handle.set_volume(bound_volume); let _ = track_handle.set_volume(bound_volume);
} }
} }
if let Err(why) = edit_response(&ctx, &command, format!("Setting the volume to {}", volume)).await {
error!("Failed to set the volume: {}", why);
}
} }
pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand { pub fn register(command: &mut CreateApplicationCommand) -> &mut CreateApplicationCommand {

View File

@@ -77,7 +77,7 @@ impl EventHandler for Handler {
let _ = InsertGuild::insert(InsertGuild { let _ = InsertGuild::insert(InsertGuild {
id: (guild.id.0 as i64), id: (guild.id.0 as i64),
bot_id: ctx.cache.current_user().id.0 as i64, bot_id: ctx.cache.current_user().id.0 as i64,
volume: 100.0 volume: 100
}); });
let commands = guild.id.set_application_commands(&ctx.http, |commands| { let commands = guild.id.set_application_commands(&ctx.http, |commands| {
commands.create_application_command(|command: &mut serenity::builder::CreateApplicationCommand| { commands::ping::register(command) }) commands.create_application_command(|command: &mut serenity::builder::CreateApplicationCommand| { commands::ping::register(command) })

View File

@@ -9,7 +9,7 @@ use crate::db::{schema::guilds, connection};
pub struct QueryGuild { pub struct QueryGuild {
pub id: i64, pub id: i64,
pub bot_id: i64, pub bot_id: i64,
pub volume: f64 pub volume: i32
} }
impl QueryGuild { impl QueryGuild {
@@ -25,7 +25,7 @@ impl QueryGuild {
pub struct InsertGuild { pub struct InsertGuild {
pub id: i64, pub id: i64,
pub bot_id: i64, pub bot_id: i64,
pub volume: f64 pub volume: i32
} }
impl InsertGuild { impl InsertGuild {
@@ -35,7 +35,7 @@ impl InsertGuild {
Ok(guild) Ok(guild)
} }
pub fn update_audio(id: i64, volume: f64) -> Result<QueryGuild, ServiceError> { pub fn update_audio(id: i64, volume: i32) -> Result<QueryGuild, ServiceError> {
let mut conn = connection()?; let mut conn = connection()?;
let guild = diesel::update(guilds::table.filter(guilds::id.eq(id))).set(guilds::volume.eq(volume)).get_result(&mut conn)?; let guild = diesel::update(guilds::table.filter(guilds::id.eq(id))).set(guilds::volume.eq(volume)).get_result(&mut conn)?;
Ok(guild) Ok(guild)

View File

@@ -35,6 +35,6 @@ diesel::table! {
guilds (id) { guilds (id) {
id -> BigInt, id -> BigInt,
bot_id -> BigInt, bot_id -> BigInt,
volume -> Float8, volume -> Integer,
} }
} }

View File

@@ -6,7 +6,7 @@ use crate::db::{schema::spells::{self}, classes::AbilityType, conditions::Condit
use super::{SchoolType, CastingTime, SpellAttackType, SpellDamageType, Range, Area, Components, Duration, Source, Description, DurationType, Effect}; use super::{SchoolType, CastingTime, SpellAttackType, SpellDamageType, Range, Area, Components, Duration, Source, Description, DurationType, Effect};
#[derive(Queryable, QueryableByName, Serialize, Deserialize)] #[derive(Debug, Queryable, QueryableByName, Serialize, Deserialize)]
#[diesel(table_name = spells)] #[diesel(table_name = spells)]
pub struct QuerySpell { pub struct QuerySpell {
pub id: i32, pub id: i32,
@@ -163,7 +163,7 @@ impl QuerySpell {
} }
} }
#[derive(Insertable, AsChangeset)] #[derive(Debug, Insertable, AsChangeset)]
#[diesel(table_name = spells)] #[diesel(table_name = spells)]
pub struct InsertSpell { pub struct InsertSpell {
pub name: String, pub name: String,

View File

@@ -263,7 +263,7 @@ pub struct Description {
#[derive(Debug)] #[derive(Debug)]
pub struct Entry { pub struct Entry {
pub text: Option<Vec<String>>, pub text: Option<String>,
pub list: Option<Vec<String>>, pub list: Option<Vec<String>>,
pub table: Option<EntryTable> pub table: Option<EntryTable>
} }
@@ -279,11 +279,18 @@ impl<'de> Deserialize<'de> for Entry {
let value = serde_json::Value::deserialize(deserializer)?; let value = serde_json::Value::deserialize(deserializer)?;
match value { match value {
serde_json::Value::String(s) => Ok(Entry { serde_json::Value::String(s) => Ok(Entry {
text: Some(vec![s]), text: Some(s),
list: None, list: None,
table: None, table: None,
}), }),
serde_json::Value::Object(o) => { serde_json::Value::Object(o) => {
let text = match o.get("text") {
Some(t) => match t.as_str() {
Some(s) => Some(s.to_string()),
None => return Err(serde::de::Error::custom("Invalid entry text"))
},
None => None
};
let list = match o.get("list") { let list = match o.get("list") {
Some(i) => match i.as_array() { Some(i) => match i.as_array() {
Some(a) => { Some(a) => {
@@ -352,7 +359,7 @@ impl<'de> Deserialize<'de> for Entry {
None => None None => None
}; };
Ok(Entry { Ok(Entry {
text: None, text,
list, list,
table table
}) })

View File

@@ -61,14 +61,21 @@ export interface Source {
} }
export interface Description { export interface Description {
entries: EntryType[]; // entries: EntryType[];
entries: Entry[];
} }
type EntryType = string | Entry; // type EntryType = string | Entry;
export interface Entry { export interface Entry {
type: string; text?: string;
items: string[]; list?: string[];
table?: EntryTable;
}
export interface EntryTable {
headers: string[];
rows: string[][];
} }
export interface GetSpellResponse { export interface GetSpellResponse {

View File

@@ -4,6 +4,7 @@ import {
getGuilds, getGuilds,
getTextChannels, getTextChannels,
getVoiceChannels, getVoiceChannels,
getVolume,
pauseTrack, pauseTrack,
playTrack, playTrack,
resumeTrack, resumeTrack,
@@ -22,6 +23,7 @@ export default function Page() {
const [activeGuild, setActiveGuild] = useState<GuildInfo | null>(null); const [activeGuild, setActiveGuild] = useState<GuildInfo | null>(null);
const [textChannels, setTextChannels] = useState<GuildChannel[]>([]); const [textChannels, setTextChannels] = useState<GuildChannel[]>([]);
const [voiceChannels, setVoiceChannels] = useState<GuildChannel[]>([]); const [voiceChannels, setVoiceChannels] = useState<GuildChannel[]>([]);
const [guildVolume, setGuildVolume] = useState<number>(50.0);
useEffect(() => { useEffect(() => {
getGuilds().then((g) => { getGuilds().then((g) => {
@@ -36,6 +38,7 @@ export default function Page() {
if (activeGuild) { if (activeGuild) {
getTextChannels(activeGuild.id).then((c) => setTextChannels(c)); getTextChannels(activeGuild.id).then((c) => setTextChannels(c));
getVoiceChannels(activeGuild.id).then((c) => setVoiceChannels(c)); getVoiceChannels(activeGuild.id).then((c) => setVoiceChannels(c));
getVolume(activeGuild.id).then((v) => setGuildVolume(v));
} }
}, [activeGuild]); }, [activeGuild]);
@@ -117,7 +120,7 @@ export default function Page() {
onSubmit={playForm.onSubmit((values) => setVolume(activeGuild!.id, values.volume))} onSubmit={playForm.onSubmit((values) => setVolume(activeGuild!.id, values.volume))}
> >
<Slider <Slider
defaultValue={50} defaultValue={guildVolume}
{...playForm.getInputProps('volume')} {...playForm.getInputProps('volume')}
marks={[ marks={[
{ value: 25, label: '25%' }, { value: 25, label: '25%' },

View File

@@ -129,23 +129,53 @@ function SpellDescription({ spell }: { spell: Spell }) {
<> <>
{spell.description && ( {spell.description && (
<> <>
{spell.description.entries.map((e) => {spell.description.entries.map((e) => (
typeof e === 'string' ? ( // typeof e === 'string' ? (
<p>{parseText(e)}</p> // <p>{parseText(e)}</p>
) : ( // ) : (
// <>
// {e.list ? (
// <ul>
// {e.list.map((text) => (
// <li>{parseText(text)}</li>
// ))}
// </ul>
// ) : (
// <></>
// )}
// </>
// )
<> <>
{e.type == 'list' ? ( {e.text && <p>{parseText(e.text)}</p>}
{e.list && (
<ul> <ul>
{e.items.map((text) => ( {e.list.map((text) => (
<li>{parseText(text)}</li> <li>{parseText(text)}</li>
))} ))}
</ul> </ul>
) : ( )}
<></> {e.table && (
<table>
<thead>
<tr>
{e.table.headers.map((label) => (
<th>{label}</th>
))}
</tr>
</thead>
<tbody>
{e.table.rows.map((row) => (
<tr>
{row.map((cell) => (
<td>{parseText(cell)}</td>
))}
</tr>
))}
</tbody>
</table>
)} )}
</> </>
) ))}
)}
</> </>
)} )}
</> </>

View File

@@ -18,6 +18,5 @@ export function rollDice(dice: string): number[] {
for (let i = 0; i < parseInt(count); i++) { for (let i = 0; i < parseInt(count); i++) {
rolls.push(Math.floor(Math.random() * parseInt(sides)) + 1); rolls.push(Math.floor(Math.random() * parseInt(sides)) + 1);
} }
console.log(rolls);
return rolls; return rolls;
} }