packet id constants
This commit is contained in:
parent
fbcb1ce123
commit
0c9f9dbf0c
@ -17,7 +17,7 @@ pub mod protocol;
|
|||||||
// Ошибки сервера
|
// Ошибки сервера
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ServerError {
|
pub enum ServerError {
|
||||||
UnknownPacket(String), // Неизвестный пакет, в строке указана ситуация в которой он неизвестен
|
UnexpectedPacket, // Неожиданный пакет
|
||||||
Protocol(ProtocolError), // Ошибка в протоколе при работе с rust_mc_proto
|
Protocol(ProtocolError), // Ошибка в протоколе при работе с rust_mc_proto
|
||||||
ConnectionClosed, // Соединение закрыто, единственная ошибка которая не логируется у handle_connection
|
ConnectionClosed, // Соединение закрыто, единственная ошибка которая не логируется у handle_connection
|
||||||
SerTextComponent, // Ошибка при сериализации текст-компонента
|
SerTextComponent, // Ошибка при сериализации текст-компонента
|
||||||
|
@ -107,7 +107,7 @@ impl ClientContext {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_packet(self: &Arc<Self>) -> Result<Packet, ServerError> {
|
pub fn read_any_packet(self: &Arc<Self>) -> Result<Packet, ServerError> {
|
||||||
let state = self.state();
|
let state = self.state();
|
||||||
|
|
||||||
let mut conn = self.conn.read().unwrap().try_clone()?; // так можно делать т.к сокет это просто поинтер
|
let mut conn = self.conn.read().unwrap().try_clone()?; // так можно делать т.к сокет это просто поинтер
|
||||||
@ -127,6 +127,15 @@ impl ClientContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn read_packet(self: &Arc<Self>, id: u8) -> Result<Packet, ServerError> {
|
||||||
|
let packet = self.read_any_packet()?;
|
||||||
|
if packet.id() != id {
|
||||||
|
Err(ServerError::UnexpectedPacket)
|
||||||
|
} else {
|
||||||
|
Ok(packet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn close(self: &Arc<Self>) {
|
pub fn close(self: &Arc<Self>) {
|
||||||
self.conn.write().unwrap().close();
|
self.conn.write().unwrap().close();
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,23 @@ use rust_mc_proto::{DataReader, DataWriter, Packet};
|
|||||||
|
|
||||||
use crate::{server::data::text_component::TextComponent, trigger_event};
|
use crate::{server::data::text_component::TextComponent, trigger_event};
|
||||||
|
|
||||||
|
// Тут будут все айди пакетов
|
||||||
|
|
||||||
|
pub const HANDSHAKE_ID: u8 = 0x00;
|
||||||
|
pub const STATUS_REQUEST_ID: u8 = 0x00;
|
||||||
|
pub const STATUS_RESPONSE_ID: u8 = 0x00;
|
||||||
|
pub const STATUS_PING_REQUEST_ID: u8 = 0x01;
|
||||||
|
pub const STATUS_PING_RESPONSE_ID: u8 = 0x01;
|
||||||
|
pub const LOGIN_START_ID: u8 = 0x00;
|
||||||
|
pub const LOGIN_SET_COMPRESSION_ID: u8 = 0x03;
|
||||||
|
pub const LOGIN_SUCCESS_ID: u8 = 0x02;
|
||||||
|
pub const LOGIN_ACKNOWLEDGED_ID: u8 = 0x03;
|
||||||
|
pub const CONFIGURATION_SERVERBOUND_PLUGIN_MESSAGE_ID: u8 = 0x02;
|
||||||
|
pub const CONFIGURATION_CLIENT_INFORMATION_ID: u8 = 0x00;
|
||||||
|
pub const CONFIGURATION_FINISH_ID: u8 = 0x03;
|
||||||
|
pub const CONFIGURATION_ACKNOWLEDGE_FINISH_ID: u8 = 0x03;
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum ConnectionState {
|
pub enum ConnectionState {
|
||||||
Handshake,
|
Handshake,
|
||||||
@ -21,11 +38,7 @@ pub fn handle_connection(
|
|||||||
// Получение пакетов производится через client.conn(),
|
// Получение пакетов производится через client.conn(),
|
||||||
// ВАЖНО: не помещать сам client.conn() в переменные,
|
// ВАЖНО: не помещать сам client.conn() в переменные,
|
||||||
// он должен сразу убиваться иначе соединение гдето задедлочится
|
// он должен сразу убиваться иначе соединение гдето задедлочится
|
||||||
let mut packet = client.read_packet()?;
|
let mut packet = client.read_packet(HANDSHAKE_ID)?;
|
||||||
|
|
||||||
if packet.id() != 0x00 {
|
|
||||||
return Err(ServerError::UnknownPacket(format!("Неизвестный пакет рукопожатия")));
|
|
||||||
} // Айди пакета не рукопожатное - выходим из функции
|
|
||||||
|
|
||||||
let protocol_version = packet.read_varint()?; // Получаем версия протокола, может быть отрицательным если наш клиент дэбил
|
let protocol_version = packet.read_varint()?; // Получаем версия протокола, может быть отрицательным если наш клиент дэбил
|
||||||
let server_address = packet.read_string()?; // Получаем домен/адрес сервера к которому пытается подключиться клиент, например "play.example.com", а не айпи
|
let server_address = packet.read_string()?; // Получаем домен/адрес сервера к которому пытается подключиться клиент, например "play.example.com", а не айпи
|
||||||
@ -40,11 +53,11 @@ pub fn handle_connection(
|
|||||||
|
|
||||||
loop {
|
loop {
|
||||||
// Чтение запроса
|
// Чтение запроса
|
||||||
let packet = client.read_packet()?;
|
let mut packet = client.read_any_packet()?;
|
||||||
|
|
||||||
match packet.id() {
|
match packet.id() {
|
||||||
0x00 => { // Запрос статуса
|
STATUS_REQUEST_ID => { // Запрос статуса
|
||||||
let mut packet = Packet::empty(0x00);
|
let mut packet = Packet::empty(STATUS_RESPONSE_ID);
|
||||||
|
|
||||||
// Дефолтный статус
|
// Дефолтный статус
|
||||||
let mut status = "{
|
let mut status = "{
|
||||||
@ -63,13 +76,16 @@ pub fn handle_connection(
|
|||||||
|
|
||||||
client.write_packet(&packet)?;
|
client.write_packet(&packet)?;
|
||||||
},
|
},
|
||||||
0x01 => { // Пинг
|
STATUS_PING_REQUEST_ID => { // Пинг
|
||||||
|
// Раньше мы просто отправляли ему его-же пакет, но сейчас,
|
||||||
|
// С приходом к власти констант айди-пакетов, нам приходится делать такое непотребство
|
||||||
|
let timestamp = packet.read_long()?;
|
||||||
|
let mut packet = Packet::empty(STATUS_PING_RESPONSE_ID);
|
||||||
|
packet.write_long(timestamp)?;
|
||||||
client.write_packet(&packet)?;
|
client.write_packet(&packet)?;
|
||||||
// Просто отправляем этот же пакет обратно
|
|
||||||
// ID такой-же, содержание тоже, так почему бы и нет?
|
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при чтении запросов статуса")));
|
return Err(ServerError::UnexpectedPacket);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -78,7 +94,7 @@ pub fn handle_connection(
|
|||||||
client.set_state(ConnectionState::Login)?; // Мы находимся в режиме Login
|
client.set_state(ConnectionState::Login)?; // Мы находимся в режиме Login
|
||||||
|
|
||||||
// Читаем пакет Login Start
|
// Читаем пакет Login Start
|
||||||
let mut packet = client.read_packet()?;
|
let mut packet = client.read_packet(LOGIN_START_ID)?;
|
||||||
|
|
||||||
let name = packet.read_string()?;
|
let name = packet.read_string()?;
|
||||||
let uuid = packet.read_uuid()?;
|
let uuid = packet.read_uuid()?;
|
||||||
@ -91,52 +107,39 @@ pub fn handle_connection(
|
|||||||
|
|
||||||
// Отправляем пакет Set Compression если сжатие указано
|
// Отправляем пакет Set Compression если сжатие указано
|
||||||
if let Some(threshold) = client.server.config.server.compression_threshold {
|
if let Some(threshold) = client.server.config.server.compression_threshold {
|
||||||
client.write_packet(&Packet::build(0x03, |p| p.write_usize_varint(threshold))?)?;
|
client.write_packet(&Packet::build(LOGIN_SET_COMPRESSION_ID, |p| p.write_usize_varint(threshold))?)?;
|
||||||
client.set_compression(Some(threshold)); // Устанавливаем сжатие на соединении
|
client.set_compression(Some(threshold)); // Устанавливаем сжатие на соединении
|
||||||
}
|
}
|
||||||
|
|
||||||
// Отправка пакета Login Success
|
// Отправка пакета Login Success
|
||||||
client.write_packet(&Packet::build(0x02, |p| {
|
client.write_packet(&Packet::build(LOGIN_SUCCESS_ID, |p| {
|
||||||
p.write_uuid(&uuid)?;
|
p.write_uuid(&uuid)?;
|
||||||
p.write_string(&name)?;
|
p.write_string(&name)?;
|
||||||
p.write_varint(0)
|
p.write_varint(0)
|
||||||
})?)?;
|
})?)?;
|
||||||
|
|
||||||
let packet = client.read_packet()?;
|
client.read_packet(LOGIN_ACKNOWLEDGED_ID)?; // Пакет Login Acknowledged
|
||||||
|
|
||||||
if packet.id() != 0x03 {
|
|
||||||
return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при ожидании Login Acknowledged")));
|
|
||||||
}
|
|
||||||
|
|
||||||
client.set_state(ConnectionState::Configuration)?; // Мы перешли в режим Configuration
|
client.set_state(ConnectionState::Configuration)?; // Мы перешли в режим Configuration
|
||||||
|
|
||||||
// Получение бренда клиента из Serverbound Plugin Message
|
// Получение бренда клиента из Serverbound Plugin Message
|
||||||
// Identifier канала откуда берется бренд: minecraft:brand
|
// Identifier канала откуда берется бренд: minecraft:brand
|
||||||
let brand = loop {
|
let brand = loop {
|
||||||
let mut packet = client.read_packet()?;
|
let mut packet = client.read_packet(CONFIGURATION_SERVERBOUND_PLUGIN_MESSAGE_ID)?; // Пакет Serverbound Plugin Message
|
||||||
|
|
||||||
if packet.id() == 0x02 { // Пакет Serverbound Plugin Message
|
let identifier = packet.read_string()?;
|
||||||
let identifier = packet.read_string()?;
|
|
||||||
|
|
||||||
let mut data = Vec::new();
|
let mut data = Vec::new();
|
||||||
packet.get_mut().read_to_end(&mut data).unwrap();
|
packet.get_mut().read_to_end(&mut data).unwrap();
|
||||||
|
|
||||||
if identifier == "minecraft:brand" {
|
if identifier == "minecraft:brand" {
|
||||||
break String::from_utf8_lossy(&data).to_string();
|
break String::from_utf8_lossy(&data).to_string();
|
||||||
} else {
|
|
||||||
trigger_event!(client, plugin_message, &identifier, &data);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при ожидании Serverbound Plugin Message")));
|
trigger_event!(client, plugin_message, &identifier, &data);
|
||||||
};
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut packet = client.read_packet()?;
|
let mut packet = client.read_packet(CONFIGURATION_CLIENT_INFORMATION_ID)?; // Пакет Client Information
|
||||||
|
|
||||||
// Пакет Client Information
|
|
||||||
if packet.id() != 0x00 {
|
|
||||||
return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при ожидании Client Information")));
|
|
||||||
}
|
|
||||||
|
|
||||||
let locale = packet.read_string()?; // for example: en_us
|
let locale = packet.read_string()?; // for example: en_us
|
||||||
let view_distance = packet.read_signed_byte()?; // client-side render distance in chunks
|
let view_distance = packet.read_signed_byte()?; // client-side render distance in chunks
|
||||||
@ -163,22 +166,17 @@ pub fn handle_connection(
|
|||||||
|
|
||||||
// TODO: Заюзать Listener'ы чтобы они подмешивали сюда чото
|
// TODO: Заюзать Listener'ы чтобы они подмешивали сюда чото
|
||||||
|
|
||||||
client.write_packet(&Packet::empty(0x03))?;
|
client.write_packet(&Packet::empty(CONFIGURATION_FINISH_ID))?;
|
||||||
|
client.read_packet(CONFIGURATION_ACKNOWLEDGE_FINISH_ID)?;
|
||||||
let packet = client.read_packet()?;
|
|
||||||
|
|
||||||
if packet.id() != 0x03 {
|
|
||||||
return Err(ServerError::UnknownPacket(format!("Неизвестный пакет при ожидании Acknowledge Finish Configuration")));
|
|
||||||
}
|
|
||||||
|
|
||||||
client.set_state(ConnectionState::Play)?; // Мы перешли в режим Play
|
client.set_state(ConnectionState::Play)?; // Мы перешли в режим Play
|
||||||
|
|
||||||
// Дальше работаем с режимом игры
|
// Дальше работаем с режимом игры
|
||||||
handle_play_state(client)?;
|
handle_play_state(client)?;
|
||||||
},
|
},
|
||||||
_ => {
|
_ => { // Тип подключения не рукопожатный
|
||||||
return Err(ServerError::UnknownPacket(format!("Неизвестный NextState при рукопожатии")));
|
return Err(ServerError::UnexpectedPacket);
|
||||||
} // Тип подключения не рукопожатный
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user