Connect to same host by default - and show message if closed.

This commit is contained in:
Condorra 2024-11-01 13:55:44 +11:00
parent d5a360b61f
commit 73b59a8254
4 changed files with 114 additions and 9 deletions

View File

@ -226,6 +226,7 @@ pub fn install_lua_globals(
}; };
} }
register_handler!(mudoutput); register_handler!(mudoutput);
register_handler!(mudclose);
let classes_table = Table::new(&ctx); let classes_table = Table::new(&ctx);
ctx.set_global("classes", classes_table); ctx.set_global("classes", classes_table);
@ -279,6 +280,7 @@ pub fn install_lua_globals(
register_class_function!(mud_class_table, mudoutput_dont); register_class_function!(mud_class_table, mudoutput_dont);
register_class_function!(mud_class_table, mudoutput_subnegotiation); register_class_function!(mud_class_table, mudoutput_subnegotiation);
register_class_function!(mud_class_table, mudinput_line); register_class_function!(mud_class_table, mudinput_line);
register_class_function!(mud_class_table, "closed", mudclass_closed);
register_stateless_class_function!(mud_class_table, "new", new_mud); register_stateless_class_function!(mud_class_table, "new", new_mud);
macro_rules! register_class_nop { macro_rules! register_class_nop {

View File

@ -5,11 +5,12 @@ use piccolo::{
SequenceReturn, StashedTable, StashedUserData, StashedValue, Table, UserData, Value, SequenceReturn, StashedTable, StashedUserData, StashedValue, Table, UserData, Value,
}; };
use wasm_bindgen::JsValue; use wasm_bindgen::JsValue;
use web_sys::console; use web_sys::{console, window};
use yew::UseStateSetter; use yew::UseStateSetter;
use crate::{ use crate::{
command_handler::execute_queue, command_handler::execute_queue,
echo_to_term_frame,
id_intern::{intern_id, unintern_id}, id_intern::{intern_id, unintern_id},
logging::{start_deleting_logs, start_downloading_logs, start_listing_logs}, logging::{start_deleting_logs, start_downloading_logs, start_listing_logs},
match_table::{create_match_table, match_table_add, match_table_remove}, match_table::{create_match_table, match_table_add, match_table_remove},
@ -68,6 +69,27 @@ pub fn handle_websocket_output(
.map_err(|err| format!("{}", err)) .map_err(|err| format!("{}", err))
} }
pub(super) fn mudclose<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -> Callback<'gc> {
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
let mud: Value<'gc> = stack
.pop_front()
.ok_or_else(|| anyhow::Error::msg("Missing argument to mudclose"))?;
let conntab: Table<'gc> = Table::from_value(
ctx,
Table::from_value(ctx, ctx.get_global("muds")?)?.get_value(ctx, mud),
)?;
let seq = piccolo::async_sequence(&ctx, |locals, mut seq| {
let conntab = locals.stash(&ctx, conntab);
async move {
call_checking_metatable::<StashedTable>(&mut seq, conntab.clone(), "closed", &[])
.await?;
Ok(piccolo::SequenceReturn::Return)
}
});
Ok(piccolo::CallbackReturn::Sequence(seq))
})
}
pub fn handle_websocket_output_log_err( pub fn handle_websocket_output_log_err(
socket: &WebSocketId, socket: &WebSocketId,
globals: &GlobalMemoCell, globals: &GlobalMemoCell,
@ -107,7 +129,7 @@ pub fn handle_websocket_close_log_err(socket: &WebSocketId, globals: &GlobalMemo
match handle_websocket_close(socket, &mut globals.lua_engine.borrow_mut()) { match handle_websocket_close(socket, &mut globals.lua_engine.borrow_mut()) {
Ok(()) => {} Ok(()) => {}
Err(e) => console::log_2( Err(e) => console::log_2(
&JsValue::from_str("An error occurred calling the WebSocket input handler"), &JsValue::from_str("An error occurred calling the WebSocket close handler"),
&JsValue::from_str(&e), &JsValue::from_str(&e),
), ),
} }
@ -484,6 +506,31 @@ pub(super) fn mudinput_line<'gc>(
}) })
} }
pub(super) fn mudclass_closed<'gc>(
ctx: Context<'gc>,
global_memo: &GlobalMemoCell,
) -> Callback<'gc> {
let global_memo = global_memo.clone();
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
let mud: Table = stack.consume(ctx)?;
let frameroutes: Table = mud.get(ctx, "frameroutes")?;
let default_frame: Value = frameroutes
.iter()
.map(|(_k, v)| Ok::<Table, Error>(Table::from_value(ctx, v)?))
.next()
.unwrap_or_else(|| Ok(ctx.get_global::<Table>("frames")?.get(ctx, 1_i64)?))?
.get(ctx, "frame")?;
let default_frame: FrameId = try_unwrap_frame(ctx, &default_frame)?;
echo_to_term_frame(
&global_memo,
&default_frame,
&format!("Connection to {} lost.\r\n", name_mud(ctx, &mud)),
)
.map_err(anyhow::Error::msg)?;
Ok(CallbackReturn::Return)
})
}
pub(super) fn new_mud<'gc>(ctx: Context<'gc>) -> Callback<'gc> { pub(super) fn new_mud<'gc>(ctx: Context<'gc>) -> Callback<'gc> {
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| { Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
let mud: Table = Table::from_value( let mud: Table = Table::from_value(
@ -633,6 +680,33 @@ pub(super) fn mud_untrigger(ctx: Context<'_>) -> Callback<'_> {
}) })
} }
fn name_mud<'gc>(ctx: Context<'gc>, mud: &Table<'gc>) -> String {
fn name_mud_internal<'gc>(ctx: Context<'gc>, mud: &Table<'gc>) -> anyhow::Result<String> {
let socket: Value<'gc> = mud.get(ctx, "socket")?;
let socket: &'gc WebSocketId =
UserData::from_value(ctx, socket)?.downcast::<Rootable![Gc<'_, WebSocketId>]>()?;
for (k, v) in ctx.get_global::<Table>("muds")?.iter() {
if let Ok(v) = UserData::from_value(ctx, v)
.map_err(anyhow::Error::from)
.and_then(|ud| {
ud.downcast::<Rootable![Gc<'_, WebSocketId>]>()
.map_err(anyhow::Error::from)
})
{
if v.0 == socket.0 {
return Ok(piccolo::String::from_value(ctx, k)?.to_str()?.to_owned());
}
}
}
Err(anyhow::Error::msg("No match"))
}
match name_mud_internal(ctx, mud) {
Ok(name) => name,
Err(_) => "unknown MUD".to_owned(),
}
}
pub(super) fn mud_log<'gc>( pub(super) fn mud_log<'gc>(
ctx: Context<'gc>, ctx: Context<'gc>,
global_memo: &GlobalMemoCell, global_memo: &GlobalMemoCell,
@ -795,3 +869,27 @@ pub(super) fn cmd_download_logs<'gc>(
Ok(CallbackReturn::Return) Ok(CallbackReturn::Return)
}) })
} }
pub fn connect_default_mud(global_memo: &GlobalMemoCell) -> anyhow::Result<()> {
if let Some(window) = window() {
if let Ok(host) = window.location().host() {
let mut engine = global_memo.lua_engine.borrow_mut();
let engine: &mut LuaState = &mut engine;
engine.try_set_current_frame(&FrameId(1))?;
engine.interp.try_enter(|ctx| {
let connect_function: Function = ctx
.get_global::<Table>("commands")?
.get(ctx, "connect_mud")?;
ctx.fetch(&engine.exec).restart(
ctx,
connect_function,
("-trust", "default", format!("wss://{}/ws", &host)),
);
Ok(())
})?;
engine.interp.execute::<()>(&engine.exec)?;
}
}
Ok(())
}

View File

@ -24,7 +24,7 @@ pub mod timer_host;
pub mod websocket; pub mod websocket;
use crate::editor_view::try_run_script; use crate::editor_view::try_run_script;
use crate::frame_view::*; use crate::frame_view::*;
use crate::lua_engine::{install_lua_globals, LuaState}; use crate::lua_engine::{install_lua_globals, muds::connect_default_mud, LuaState};
use crate::split_panel::*; use crate::split_panel::*;
use crate::websocket::RegisteredWebSockets; use crate::websocket::RegisteredWebSockets;
@ -90,6 +90,12 @@ fn app() -> Html {
console::log_1(&format!("Error running init.lua: {}", e).into()); console::log_1(&format!("Error running init.lua: {}", e).into());
} }
} }
match connect_default_mud(&global_memo) {
Ok(_) => {}
Err(e) => {
console::log_1(&format!("Error connecting to default MUD: {}", e).into());
}
}
}); });
html! { html! {

View File

@ -117,6 +117,8 @@ pub fn connect_websocket(
move || match close_globals.ws_registry.borrow_mut().get_mut(&close_id) { move || match close_globals.ws_registry.borrow_mut().get_mut(&close_id) {
None => {} None => {}
Some(closed_socket) => { Some(closed_socket) => {
closed_socket.connection.set_onclose(None);
closed_socket.connection.set_onerror(None);
closed_socket.closed = true; closed_socket.closed = true;
closed_socket.retained_closures = None; closed_socket.retained_closures = None;
handle_websocket_close_log_err(&close_id, &close_globals); handle_websocket_close_log_err(&close_id, &close_globals);
@ -125,14 +127,11 @@ pub fn connect_websocket(
); );
data.connection data.connection
.add_event_listener_with_callback("message", data_closure.as_ref().unchecked_ref()) .set_onmessage(Some(data_closure.as_ref().unchecked_ref()));
.expect("Couldn't set message handler on WebSocket");
data.connection data.connection
.add_event_listener_with_callback("close", close_closure.as_ref().unchecked_ref()) .set_onclose(Some(close_closure.as_ref().unchecked_ref()));
.expect("Couldn't set close handler on WebSocket");
data.connection data.connection
.add_event_listener_with_callback("error", close_closure.as_ref().unchecked_ref()) .set_onerror(Some(close_closure.as_ref().unchecked_ref()));
.expect("Couldn't set error handler on WebSocket");
data.retained_closures = Some((data_closure, close_closure)); data.retained_closures = Some((data_closure, close_closure));
sockets.insert(new_id.clone(), data); sockets.insert(new_id.clone(), data);
Ok(new_id) Ok(new_id)