Implement Telnet option negotiation
This commit is contained in:
parent
6122ac7926
commit
c0739262af
@ -19,7 +19,13 @@ use crate::{
|
|||||||
FrameId, GlobalLayoutCell, GlobalMemoCell,
|
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};
|
use super::{call_checking_metatable, list_match_tab, try_unwrap_frame, LuaState};
|
||||||
|
pub mod telopt;
|
||||||
|
|
||||||
fn try_unwrap_socketid<'gc>(
|
fn try_unwrap_socketid<'gc>(
|
||||||
ctx: Context<'gc>,
|
ctx: Context<'gc>,
|
||||||
@ -459,24 +465,72 @@ pub(super) fn mudoutput_prompt<'gc>(
|
|||||||
}
|
}
|
||||||
pub(super) fn mudoutput_will<'gc>(
|
pub(super) fn mudoutput_will<'gc>(
|
||||||
ctx: Context<'gc>,
|
ctx: Context<'gc>,
|
||||||
_global_memo: &GlobalMemoCell,
|
global_memo: &GlobalMemoCell,
|
||||||
) -> Callback<'gc> {
|
) -> 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>(
|
pub(super) fn mudoutput_wont<'gc>(
|
||||||
ctx: Context<'gc>,
|
ctx: Context<'gc>,
|
||||||
_global_memo: &GlobalMemoCell,
|
global_memo: &GlobalMemoCell,
|
||||||
) -> Callback<'gc> {
|
) -> 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> {
|
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))
|
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>(
|
pub(super) fn mudoutput_dont<'gc>(
|
||||||
ctx: Context<'gc>,
|
ctx: Context<'gc>,
|
||||||
_global_memo: &GlobalMemoCell,
|
global_memo: &GlobalMemoCell,
|
||||||
) -> Callback<'gc> {
|
) -> 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>(
|
pub(super) fn mudoutput_subnegotiation<'gc>(
|
||||||
ctx: Context<'gc>,
|
ctx: Context<'gc>,
|
||||||
|
1187
src/lua_engine/muds/telopt.rs
Normal file
1187
src/lua_engine/muds/telopt.rs
Normal file
File diff suppressed because it is too large
Load Diff
@ -18,7 +18,7 @@ pub enum TelnetOutput {
|
|||||||
Subnegotiation(Vec<u8>),
|
Subnegotiation(Vec<u8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
const IAC: u8 = 255;
|
pub const IAC: u8 = 255;
|
||||||
const NOP: u8 = 241;
|
const NOP: u8 = 241;
|
||||||
const DATA_MARK: u8 = 242;
|
const DATA_MARK: u8 = 242;
|
||||||
const BREAK: u8 = 243;
|
const BREAK: u8 = 243;
|
||||||
@ -31,10 +31,10 @@ const GOAHEAD: u8 = 249;
|
|||||||
const EOR: u8 = 239;
|
const EOR: u8 = 239;
|
||||||
const STARTSUB: u8 = 250;
|
const STARTSUB: u8 = 250;
|
||||||
const ENDSUB: u8 = 240;
|
const ENDSUB: u8 = 240;
|
||||||
const WILL: u8 = 251;
|
pub const WILL: u8 = 251;
|
||||||
const WONT: u8 = 252;
|
pub const WONT: u8 = 252;
|
||||||
const DO: u8 = 253;
|
pub const DO: u8 = 253;
|
||||||
const DONT: u8 = 254;
|
pub const DONT: u8 = 254;
|
||||||
|
|
||||||
pub fn parse_telnet_buf(input: &[u8]) -> (Vec<u8>, Option<TelnetOutput>) {
|
pub fn parse_telnet_buf(input: &[u8]) -> (Vec<u8>, Option<TelnetOutput>) {
|
||||||
let mut ptr: &[u8] = input;
|
let mut ptr: &[u8] = input;
|
||||||
|
Loading…
Reference in New Issue
Block a user