Fixed spell descriptions
This commit is contained in:
@@ -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
|
||||||
);
|
);
|
||||||
@@ -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()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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) })
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -35,6 +35,6 @@ diesel::table! {
|
|||||||
guilds (id) {
|
guilds (id) {
|
||||||
id -> BigInt,
|
id -> BigInt,
|
||||||
bot_id -> BigInt,
|
bot_id -> BigInt,
|
||||||
volume -> Float8,
|
volume -> Integer,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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,
|
||||||
|
|||||||
@@ -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
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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%' },
|
||||||
|
|||||||
@@ -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.type == 'list' ? (
|
// {e.list ? (
|
||||||
<ul>
|
// <ul>
|
||||||
{e.items.map((text) => (
|
// {e.list.map((text) => (
|
||||||
<li>{parseText(text)}</li>
|
// <li>{parseText(text)}</li>
|
||||||
|
// ))}
|
||||||
|
// </ul>
|
||||||
|
// ) : (
|
||||||
|
// <></>
|
||||||
|
// )}
|
||||||
|
// </>
|
||||||
|
// )
|
||||||
|
<>
|
||||||
|
{e.text && <p>{parseText(e.text)}</p>}
|
||||||
|
{e.list && (
|
||||||
|
<ul>
|
||||||
|
{e.list.map((text) => (
|
||||||
|
<li>{parseText(text)}</li>
|
||||||
|
))}
|
||||||
|
</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>
|
||||||
))}
|
))}
|
||||||
</ul>
|
</tbody>
|
||||||
) : (
|
</table>
|
||||||
<></>
|
)}
|
||||||
)}
|
</>
|
||||||
</>
|
))}
|
||||||
)
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user