mirror of
https://github.com/timvisee/lazymc.git
synced 2025-05-18 20:30:23 -07:00
Various fixes and improvements
This commit is contained in:
parent
a500f50064
commit
a1324d22a7
5
TODO.md
5
TODO.md
@ -25,8 +25,3 @@
|
|||||||
- hold back packets (whitelist), forward to server at connect before joining
|
- hold back packets (whitelist), forward to server at connect before joining
|
||||||
- add support for forge (emulate mod list communication)
|
- add support for forge (emulate mod list communication)
|
||||||
- on login plugin request during login state, respond with empty payload, not supported
|
- on login plugin request during login state, respond with empty payload, not supported
|
||||||
|
|
||||||
# Extra
|
|
||||||
|
|
||||||
- simply don't occupy in lobby if we don't have probed data
|
|
||||||
- dont use mutex for server data
|
|
||||||
|
13
src/forge.rs
13
src/forge.rs
@ -38,6 +38,10 @@ pub const CHANNEL_LOGIN_WRAPPER: &str = "fml:loginwrapper";
|
|||||||
/// Forge handshake channel.
|
/// Forge handshake channel.
|
||||||
pub const CHANNEL_HANDSHAKE: &str = "fml:handshake";
|
pub const CHANNEL_HANDSHAKE: &str = "fml:handshake";
|
||||||
|
|
||||||
|
/// Timeout for draining Forge plugin responses from client.
|
||||||
|
#[cfg(feature = "lobby")]
|
||||||
|
const CLIENT_DRAIN_FORGE_TIMEOUT: Duration = Duration::from_secs(5);
|
||||||
|
|
||||||
/// Respond with Forge login wrapper packet.
|
/// Respond with Forge login wrapper packet.
|
||||||
pub async fn respond_forge_login_packet(
|
pub async fn respond_forge_login_packet(
|
||||||
client: &Client,
|
client: &Client,
|
||||||
@ -165,14 +169,14 @@ pub async fn replay_login_payload(
|
|||||||
debug!(target: "lazymc::lobby", "Replaying Forge login procedure for lobby client...");
|
debug!(target: "lazymc::lobby", "Replaying Forge login procedure for lobby client...");
|
||||||
|
|
||||||
// Replay each Forge packet
|
// Replay each Forge packet
|
||||||
for packet in server.forge_payload.lock().await.as_slice() {
|
for packet in server.forge_payload.read().await.as_slice() {
|
||||||
inbound.write_all(packet).await.map_err(|err| {
|
inbound.write_all(packet).await.map_err(|err| {
|
||||||
error!(target: "lazymc::lobby", "Failed to send Forge join payload to lobby client, will likely cause issues: {}", err);
|
error!(target: "lazymc::lobby", "Failed to send Forge join payload to lobby client, will likely cause issues: {}", err);
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Drain all responses
|
// Drain all responses
|
||||||
let count = server.forge_payload.lock().await.len();
|
let count = server.forge_payload.read().await.len();
|
||||||
drain_forge_responses(client, inbound, inbound_buf, count).await?;
|
drain_forge_responses(client, inbound, inbound_buf, count).await?;
|
||||||
|
|
||||||
trace!(target: "lazymc::lobby", "Forge join payload replayed");
|
trace!(target: "lazymc::lobby", "Forge join payload replayed");
|
||||||
@ -197,10 +201,9 @@ async fn drain_forge_responses(
|
|||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: move timeout into constant
|
// Read packet from stream with timeout
|
||||||
let read_packet_task = packet::read_packet(client, buf, &mut reader);
|
let read_packet_task = packet::read_packet(client, buf, &mut reader);
|
||||||
let timeout = time::timeout(Duration::from_secs(5), read_packet_task).await;
|
let timeout = time::timeout(CLIENT_DRAIN_FORGE_TIMEOUT, read_packet_task).await;
|
||||||
|
|
||||||
let read_packet_task = match timeout {
|
let read_packet_task = match timeout {
|
||||||
Ok(result) => result,
|
Ok(result) => result,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
|
@ -37,7 +37,7 @@ pub async fn occupy(
|
|||||||
|
|
||||||
/// Check whether we still have to probe before we can use the lobby.
|
/// Check whether we still have to probe before we can use the lobby.
|
||||||
async fn must_still_probe(config: &Config, server: &Server) -> bool {
|
async fn must_still_probe(config: &Config, server: &Server) -> bool {
|
||||||
must_probe(config) && server.probed_join_game.lock().await.is_none()
|
must_probe(config) && server.probed_join_game.read().await.is_none()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check whether we must have probed data.
|
/// Check whether we must have probed data.
|
||||||
|
@ -53,7 +53,7 @@ pub async fn probe(config: Arc<Config>, server: Arc<Server>) -> Result<(), ()> {
|
|||||||
|
|
||||||
// Connect to server, record Forge payload
|
// Connect to server, record Forge payload
|
||||||
let forge_payload = connect_to_server(&config, &server).await?;
|
let forge_payload = connect_to_server(&config, &server).await?;
|
||||||
*server.forge_payload.lock().await = forge_payload;
|
*server.forge_payload.write().await = forge_payload;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -277,7 +277,11 @@ async fn connect_to_server_no_timeout(
|
|||||||
let join_game_data =
|
let join_game_data =
|
||||||
wait_for_server_join_game(&tmp_client, &tmp_client_info, &mut outbound, &mut buf)
|
wait_for_server_join_game(&tmp_client, &tmp_client_info, &mut outbound, &mut buf)
|
||||||
.await?;
|
.await?;
|
||||||
server.probed_join_game.lock().await.replace(join_game_data);
|
server
|
||||||
|
.probed_join_game
|
||||||
|
.write()
|
||||||
|
.await
|
||||||
|
.replace(join_game_data);
|
||||||
|
|
||||||
// Gracefully close connection
|
// Gracefully close connection
|
||||||
let _ = net::close_tcp_stream(outbound).await;
|
let _ = net::close_tcp_stream(outbound).await;
|
||||||
|
@ -106,11 +106,10 @@ pub async fn lobby_send(
|
|||||||
server: &Server,
|
server: &Server,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
let status = server.status().await;
|
let status = server.status().await;
|
||||||
let join_game = server.probed_join_game.lock().await;
|
let join_game = server.probed_join_game.read().await;
|
||||||
|
|
||||||
// Get dimension codec and build lobby dimension
|
// Get dimension codec and build lobby dimension
|
||||||
let dimension_codec: CompoundTag =
|
let dimension_codec: CompoundTag = if let Some(join_game) = join_game.as_ref() {
|
||||||
if let Some(join_game) = server.probed_join_game.lock().await.as_ref() {
|
|
||||||
join_game
|
join_game
|
||||||
.dimension_codec
|
.dimension_codec
|
||||||
.clone()
|
.clone()
|
||||||
|
@ -81,10 +81,13 @@ pub struct Server {
|
|||||||
#[cfg(feature = "rcon")]
|
#[cfg(feature = "rcon")]
|
||||||
rcon_last_stop: Mutex<Option<Instant>>,
|
rcon_last_stop: Mutex<Option<Instant>>,
|
||||||
|
|
||||||
// TODO: dont use mutex, do not make public, dont use bytesmut
|
/// Probed join game data.
|
||||||
pub forge_payload: Mutex<Vec<Vec<u8>>>,
|
pub probed_join_game: RwLock<Option<JoinGameData>>,
|
||||||
// TODO: dont use mutex, do not make public, dont use bytesmut
|
|
||||||
pub probed_join_game: Mutex<Option<JoinGameData>>,
|
/// Forge payload.
|
||||||
|
///
|
||||||
|
/// Sent to clients when they connect to lobby. Recorded from server by probe.
|
||||||
|
pub forge_payload: RwLock<Vec<Vec<u8>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Server {
|
impl Server {
|
||||||
@ -372,8 +375,8 @@ impl Default for Server {
|
|||||||
rcon_lock: Semaphore::new(1),
|
rcon_lock: Semaphore::new(1),
|
||||||
#[cfg(feature = "rcon")]
|
#[cfg(feature = "rcon")]
|
||||||
rcon_last_stop: Default::default(),
|
rcon_last_stop: Default::default(),
|
||||||
forge_payload: Default::default(),
|
|
||||||
probed_join_game: Default::default(),
|
probed_join_game: Default::default(),
|
||||||
|
forge_payload: Default::default(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user