Implement Telnet option negotiation

This commit is contained in:
Condorra 2024-11-09 00:55:46 +11:00
parent 6122ac7926
commit c0739262af
3 changed files with 1254 additions and 13 deletions

View File

@ -19,7 +19,13 @@ use crate::{
FrameId, GlobalLayoutCell, GlobalMemoCell,
};
use self::telopt::{
handle_incoming_do, handle_incoming_dont, handle_incoming_will, handle_incoming_wont,
MudWithMemo, Telopt,
};
use super::{call_checking_metatable, list_match_tab, try_unwrap_frame, LuaState};
pub mod telopt;
fn try_unwrap_socketid<'gc>(
ctx: Context<'gc>,
@ -459,24 +465,72 @@ pub(super) fn mudoutput_prompt<'gc>(
}
pub(super) fn mudoutput_will<'gc>(
ctx: Context<'gc>,
_global_memo: &GlobalMemoCell,
global_memo: &GlobalMemoCell,
) -> Callback<'gc> {
Callback::from_fn(&ctx, move |_ctx, _ex, _stack| Ok(CallbackReturn::Return))
let global_memo = global_memo.clone();
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
let (mud, optno): (Table, u8) = stack.consume(ctx)?;
let socket: Value = mud.get(ctx, "socket")?;
let socket: &WebSocketId =
UserData::from_value(ctx, socket)?.downcast::<Rootable![Gc<'_, WebSocketId>]>()?;
let mut mud_memo = MudWithMemo {
memo: global_memo.clone(),
mud: socket.clone(),
};
handle_incoming_will(ctx, &mut mud_memo, &mud, &Telopt(optno));
Ok(CallbackReturn::Return)
})
}
pub(super) fn mudoutput_wont<'gc>(
ctx: Context<'gc>,
_global_memo: &GlobalMemoCell,
global_memo: &GlobalMemoCell,
) -> Callback<'gc> {
Callback::from_fn(&ctx, move |_ctx, _ex, _stack| Ok(CallbackReturn::Return))
let global_memo = global_memo.clone();
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
let (mud, optno): (Table, u8) = stack.consume(ctx)?;
let socket: Value = mud.get(ctx, "socket")?;
let socket: &WebSocketId =
UserData::from_value(ctx, socket)?.downcast::<Rootable![Gc<'_, WebSocketId>]>()?;
let mut mud_memo = MudWithMemo {
memo: global_memo.clone(),
mud: socket.clone(),
};
handle_incoming_wont(ctx, &mut mud_memo, &mud, &Telopt(optno));
Ok(CallbackReturn::Return)
})
}
pub(super) fn mudoutput_do<'gc>(ctx: Context<'gc>, _global_memo: &GlobalMemoCell) -> Callback<'gc> {
Callback::from_fn(&ctx, move |_ctx, _ex, _stack| Ok(CallbackReturn::Return))
pub(super) fn mudoutput_do<'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, optno): (Table, u8) = stack.consume(ctx)?;
let socket: Value = mud.get(ctx, "socket")?;
let socket: &WebSocketId =
UserData::from_value(ctx, socket)?.downcast::<Rootable![Gc<'_, WebSocketId>]>()?;
let mut mud_memo = MudWithMemo {
memo: global_memo.clone(),
mud: socket.clone(),
};
handle_incoming_do(ctx, &mut mud_memo, &mud, &Telopt(optno));
Ok(CallbackReturn::Return)
})
}
pub(super) fn mudoutput_dont<'gc>(
ctx: Context<'gc>,
_global_memo: &GlobalMemoCell,
global_memo: &GlobalMemoCell,
) -> Callback<'gc> {
Callback::from_fn(&ctx, move |_ctx, _ex, _stack| Ok(CallbackReturn::Return))
let global_memo = global_memo.clone();
Callback::from_fn(&ctx, move |ctx, _ex, mut stack| {
let (mud, optno): (Table, u8) = stack.consume(ctx)?;
let socket: Value = mud.get(ctx, "socket")?;
let socket: &WebSocketId =
UserData::from_value(ctx, socket)?.downcast::<Rootable![Gc<'_, WebSocketId>]>()?;
let mut mud_memo = MudWithMemo {
memo: global_memo.clone(),
mud: socket.clone(),
};
handle_incoming_dont(ctx, &mut mud_memo, &mud, &Telopt(optno));
Ok(CallbackReturn::Return)
})
}
pub(super) fn mudoutput_subnegotiation<'gc>(
ctx: Context<'gc>,

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ pub enum TelnetOutput {
Subnegotiation(Vec<u8>),
}
const IAC: u8 = 255;
pub const IAC: u8 = 255;
const NOP: u8 = 241;
const DATA_MARK: u8 = 242;
const BREAK: u8 = 243;
@ -31,10 +31,10 @@ const GOAHEAD: u8 = 249;
const EOR: u8 = 239;
const STARTSUB: u8 = 250;
const ENDSUB: u8 = 240;
const WILL: u8 = 251;
const WONT: u8 = 252;
const DO: u8 = 253;
const DONT: u8 = 254;
pub const WILL: u8 = 251;
pub const WONT: u8 = 252;
pub const DO: u8 = 253;
pub const DONT: u8 = 254;
pub fn parse_telnet_buf(input: &[u8]) -> (Vec<u8>, Option<TelnetOutput>) {
let mut ptr: &[u8] = input;