{"id":329125,"date":"2022-02-05T15:00:54","date_gmt":"2022-02-05T15:00:54","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=329125"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=329125","title":{"rendered":"<span>ULE \u2014 \u0441\u0430\u043c\u043e\u043f\u0438\u0441\u043d\u043e\u0435 MC Java \u044f\u0434\u0440\u043e. \u0427\u0430\u0441\u0442\u044c #1.1 \u2014 HelloWorld \u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f\u2026<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u0423\u0436\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0440\u043e\u0448\u043b\u043e \u0441 <a href=\"https:\/\/habr.com\/ru\/post\/646483\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438<\/a>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f \u043f\u0438\u0441\u0430\u043b \u043f\u0440\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u0432\u043e\u0435\u0439 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u043d\u0430 Go, \u043a\u0430\u043a \u0432\u0441\u0435\u0433\u0434\u0430 <a href=\"https:\/\/github.com\/Distemi\/ULE\" rel=\"noopener noreferrer nofollow\">\u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 GitHub<\/a>. \u0421\u0440\u0430\u0437\u0443 \u0434\u0443\u043c\u0430\u044e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0437\u0430 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u043f\u0435\u043b \u0443\u0436\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u043b\u0438\u043d\u0443\u043a\u0441(Mint Cinnamon), \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 GPU, \u043d\u043e \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u044f \u0441\u043c\u043e\u0433 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u043e\u043c \u043e\u0442 JetBrains \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0441 Go \u043d\u0430 Rust, \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a-\u043a\u0430\u043a \u044f \u0434\u0443\u043c\u0430\u043b \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u0440\u0430\u0441\u0442\u0435, \u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c&#8230; \u041d\u043e \u0432\u043e\u0442 \u0438 \u0431\u044b\u043b \u0441\u0434\u0435\u043b\u0430\u043d \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0441 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f\u043c\u0438 \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0442\u0430\u043a \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439!)<\/p>\n<h3>\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0441 Go \u043d\u0430 Rust<\/h3>\n<ol>\n<li>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u0437\u0430\u0434\u0443\u043c\u044b\u0432\u0430\u043b\u0441\u044f \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u0430 \u043d\u0451\u043c, \u043d\u043e \u043d\u0435 \u043c\u043e\u0433 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0434 \u043d\u0430 \u0440\u0430\u0441\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0440\u0430\u0437\u044b \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0435\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c \u0432 \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445&#8230;)<\/p>\n<\/li>\n<\/ol>\n<h3>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u0443\u0442\u043e\u0447\u043d\u0435\u043d\u0438\u0439<\/h3>\n<p>\u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043d\u0430 Rust \u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a, \u0442\u0430\u043a-\u043a\u0430\u043a \u0435\u0433\u043e \u0437\u043d\u0430\u044e\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e, \u0430 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0435\u0441\u043b\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u0440\u0443\u0441\u0441\u043a\u043e\u0433\u043e &#8212; \u0441\u043c\u043e\u0436\u0435\u0442 \u0432\u043f\u043e\u043b\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0438\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u0432\u0441\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u0438 \u043a\u043e\u0434\u0435 \u043d\u0430 GitHub \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438 \u043c\u043d\u043e\u0433\u043e \u043e\u0448\u0438\u0431\u043e\u043a&#8230; \u041f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u0430\u043a-\u0436\u0435 \u043c\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u043e\u0432, \u043d\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0447\u0442\u0438 \u043f\u0443\u0441\u0442\u044b\u0435 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044c\u0435\u0434\u0438\u043d\u044f\u044e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u043a\u043e\u0434.<\/p>\n<h2>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 #1.1<\/h2>\n<p>\u041a\u043e\u0434 \u043d\u0430 \u0440\u0430\u0441\u0442\u0435 \u0432\u044b\u0448\u0435\u043b \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u0432 \u0440\u0430\u0437\u044b \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u0430\u043a-\u043a\u0430\u043a \u044f \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u0432\u043e\u0435\u0433\u043e, \u043d\u043e \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u0434\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043c\u043d\u043e\u0433\u043e, \u043d\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b \u0438\u0445 \u0432 Cargo.toml:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 Cargo.toml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"markdown\">[package] name = \"ule\" version = \"0.1.0\" edition = \"2021\" publish = true authors = [     \"Distemi &lt;distemi.bot@mail.ru>\" ] homepage = \"https:\/\/github.com\/Distemi\/ULE\" repository = \"https:\/\/github.com\/Distemi\/ULE\"  [dependencies] # \u0411\u044b\u0441\u0442\u0440\u044b\u0439 HashMap \u0438 \u0434\u0440\u0443\u0433\u043e\u0435. ahash = \"0.7.6\" # \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 lazy_static = \"1.4.0\" # Struct &lt;-> JSON serde = { version = \"1.0.136\", features = [\"derive\"] } serde_json = \"1.0.78\" # \u0423\u0442\u0438\u043b\u0438\u0442\u044b \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f log = \"0.4.14\" fern = { version = \"0.6\", features = [\"colored\"] } # \u0412\u0440\u0435\u043c\u044f chrono = \"0.4.19\" # \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c(\u0441\u043a\u043e\u0440\u043e \u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f) async-std = \"1.10.0\"  # \u041e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u044b\u0439 TCP \u0438 UDP \u0441\u0435\u0440\u0432\u0435\u0440 [dependencies.mio] version = \"0.8.0\" default-features = false features = [     \"os-ext\",     \"net\" ]   [profile.release] opt-level = \"z\" <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041a\u0430\u043a \u0440\u0430\u0437 \u043d\u0430\u0448 Cargo.toml \u044f\u0432\u043b\u044f\u0435\u0442\u044c\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430 \u0441\u043b\u0435\u0434\u044e\u0449\u0438\u0439 \u043f\u043e \u0432\u0430\u0436\u043d\u043e\u0441\u0442\u0438 src\/main.rs:<\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u0430\u0448 main.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">#![allow(unused_must_use)] use crate::config::{ADDRESS, ADDRESS_PORT}; use crate::logger::start_input_handler; use crate::network::network_server_start; use fern::colors::Color; use std::error::Error; use std::process; use std::sync::mpsc::channel; use std::sync::Arc; use std::time::SystemTime; use std::{fmt, thread}; use utils::logger;  \/\/ Use a macros from serde(Serialize and Deserialize), log(Logging) and lazy_static(Global variables) #[macro_use] extern crate serde; #[macro_use] extern crate log; #[macro_use] extern crate lazy_static;  pub mod config; pub mod network; pub mod utils;  \/\/ Main function of application fn main() {     let start = SystemTime::now();     \/\/ Initialize logger     println!(\"Starting ULE v1.0.0...\");     if let Err(err) = logger::setup_logger() {         eprintln!(\"Failed to initialize logger: {}\", err);         process::exit(1);     }     \/\/ Creating channel for multithreading communication with main's thread and network's thread     let (tx, rx) = channel::&lt;bool>();     \/\/ Generate server's address and make it accessible with thread safe     let address = Arc::new(String::from(format!(         \"{}:{}\",         ADDRESS,         ADDRESS_PORT.to_string()     )));     \/\/ Start network in another thread     thread::spawn({         let address = address.to_string();         move || {             \/\/ Start network             \/\/ If failed to start when return error             if let Err(err) = network_server_start(address, &amp;tx) {                 error!(\"{}\", err);                 tx.send(false);             }         }     });     \/\/ Wait for status from server's network     if rx.recv().unwrap_or(false) {         \/\/ If Server successful started         info!(\"Server started at {}\", address);         \/\/ Showing about the full launch and showing the time to start         {             let elapsed = start.elapsed().unwrap();             info!(                 \"The server was successfully started in {}\",                 if elapsed.as_secs() >= 1 {                     format!(\"{}s\", elapsed.as_secs())                 } else if elapsed.as_millis() >= 1 {                     format!(\"{}ms\", elapsed.as_millis())                 } else {                     format!(\"{}ns\", elapsed.as_nanos())                 }             );             drop(elapsed);         };     } else {         \/\/ If Failed to start Server         error!(\"Failed to start server on {}.\", address);         process::exit(1);     }     \/\/ Remove channel     std::mem::drop(rx);     \/\/ Start console input handler(input commands)     start_input_handler(); }  \/\/ Custom error(yes, not std::io:Error) #[derive(Debug)] pub struct SimpleError(String, Option&lt;std::io::Error>);  impl Error for SimpleError {}  impl fmt::Display for SimpleError {     fn fmt(&amp;self, f: &amp;mut fmt::Formatter) -> fmt::Result {         \/\/ Check is error provided         if self.1.is_some() {             write!(f, \"{}: {:?}\", self.0, self.1)         } else {             write!(f, \"{}\", self.0)         }     } }  \/\/ Custom Result with custom Error pub type SResult&lt;T> = Result&lt;T, SimpleError>; <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c main.rs \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043e\u0442\u0441\u0447\u0451\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0441\u043a\u043e\u0440\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430. \u041f\u043e\u0442\u043e\u043c \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0433\u0435\u0440(fern + log), \u043f\u0440\u0438 \u043d\u0435\u0443\u0434\u0430\u0447\u0435 &#8212; \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u0438 &#171;\u0443\u0431\u0438\u0432\u0430\u0435\u043c&#187; \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0443 \u043d\u0430\u0441 \u0438\u0434\u0451\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0435\u043a\u043e\u0433\u043e \u043a\u0430\u043d\u0430\u043b\u0430, \u0430 \u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0430\u0434\u0440\u0435\u0441\u0441\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u043e \u043a\u0430\u043d\u0430\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u043e \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u043a\u0430\u043a UDP, \u043d\u043e \u0441 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043e\u043d \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0436\u0434\u0451\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043e\u0442 \u043f\u043e\u0442\u043e\u043a\u0430 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430(TCP \u0441\u0435\u0440\u0432\u0435\u0440), \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c &#8212; \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u0437\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u043e\u0441\u044c, \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0435 &#8212; \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448 TCP \u0441\u0435\u0440\u0432\u0435\u0440, \u0442\u043e \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043d\u0430\u0448 \u043a\u0430\u043d\u0430\u043b \u0441\u0432\u044f\u0437\u0438 \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u0432\u0432\u043e\u0434 \u0441 \u043a\u043e\u043d\u0441\u043e\u043b\u0438. \u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0435\u0441\u0442\u044c \u0442\u0438\u043f\u044b SResul(\u0438\u0437 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f SimpleResult) \u0438 SimpleError, \u043f\u0435\u0440\u0432\u044b\u0439 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0441\u0430\u043c \u0437\u0430 \u0441\u0435\u0431\u044f, \u043a\u0430\u043a \u0438 \u0432\u0442\u043e\u0440\u043e\u0439, \u043d\u043e \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u0434\u0451\u0442 \u043f\u0440\u0438\u043c\u0438\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043d\u044b\u0445 trait \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430 \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<p>\u041d\u0430\u0448 \u043c\u0435\u0442\u043e\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0433\u0435\u0440\u0430 \u043b\u0435\u0436\u0438\u0442 \u0432 \u0444\u0430\u0439\u043b\u0435 src\/utils\/logger\/input.rs, \u043d\u043e \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0442\u0430\u043a-\u0436\u0435 src\/utils\/mod.rs \u0438 src\/utils\/logger\/mod.rs, \u0442\u0430\u043a-\u043a\u0430\u043a \u043e\u043d\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b:<\/p>\n<details class=\"spoiler\">\n<summary>src\/utils\/mod.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">pub mod chat; pub mod logger;<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u0438 \u0447\u0430\u0442\u0430 \u0438 \u043b\u043e\u0433\u0433\u0435\u0440\u0430 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>src\/utils\/logger\/mod.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">mod input; mod log_lib;  pub use {input::start_input_handler, log_lib::setup_logger};<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0438\u0434\u0451\u0442 \u0438\u043c\u043f\u043e\u0440\u0442 input.rs \u0438 log_lib.rs, \u0430 \u0442\u0430\u043a-\u0436\u0435 \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 start_input_handler \u0438 setup_logger<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0433\u0435\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">use crate::Color; use fern::colors::ColoredLevelConfig; use std::fs;  \/\/ Logger's initialize(fern, color and log) pub fn setup_logger() -> Result&lt;(), fern::InitError> {     \/\/ Removing latest log if exists     fs::remove_file(\"latest.log\");     \/\/ Setting colors     let colors = ColoredLevelConfig::new()         .info(Color::BrightBlack)         .warn(Color::Yellow)         .error(Color::Red)         .trace(Color::BrightRed);     \/\/ Setting fern     fern::Dispatch::new()         \/\/ Setting custom format to logging         .format(move |out, message, record| {             out.finish(format_args!(                 \"{} [{}] {}\",                 chrono::Local::now().format(\"[%m-%d %H:%M:%S]\"),                 colors.color(record.level()),                 message             ))         })         \/\/ Setting log-level         .level(log::LevelFilter::Info)         \/\/ Setting target's logger         .chain(std::io::stdout())         \/\/ Setting log's file         .chain(fern::log_file(\"latest.log\")?)         \/\/ Applying settings         .apply()?;     \/\/ If successful setting - returning ok     Ok(()) }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0435\u0440\u0430 \u043c\u044b \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0444\u0430\u0439\u043b \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043b\u043e\u0433\u0430 <strong>latest.log<\/strong>, \u043f\u043e\u0442\u043e\u043c \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043b\u043e\u0433\u0430 \u0441\u0432\u043e\u0439 \u0446\u0432\u0435\u0442(INFO = \u0441\u0435\u0440\u044b\u0439, WARN &#8212; \u0436\u0451\u043b\u0442\u044b\u0439, ERROR &#8212; \u043a\u0440\u0430\u0441\u043d\u044b\u0439, TRACE &#8212; \u044f\u0440\u043a\u043e-\u043a\u0440\u0430\u0441\u043d\u044b\u0439). \u041f\u043e\u0437\u0436\u0435 \u0438\u0434\u0451\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u043b\u043e\u0433\u0433\u0435\u0440\u0430 fern \u0438 \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442: [\u0414\u0410\u0422\u0410] [\u0423\u0420\u041e\u0412\u0415\u041d\u042c] \u0421\u041e\u041e\u0411\u0429\u0415\u041d\u0418\u0415, \u0446\u0432\u0435\u0442 \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0440\u043e\u0432\u0435\u043d\u044c, \u0430 \u0434\u0430\u0442\u0430 \u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0446\u0432\u0432\u0435\u0442\u043e\u043c \u043a\u043e\u043d\u0441\u043e\u043b\u0438. \u0414\u043b\u044f \u043b\u043e\u0433\u0433\u0435\u0440\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432\u044b\u0432\u043e\u0434 \u0432 stdout(\u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0432\u044b\u0432\u043e\u0434\u0430), \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u044b\u0432\u043e\u0434\u0430 &#8212; INFO, \u0430 \u0442\u0430\u043a-\u0436\u0435 \u0432\u044b\u0432\u043e\u0434 \u0432 \u043b\u043e\u0433-\u0444\u0430\u0439\u043b \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u044d\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0438 \u044d\u0442\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u0445 &#8212; \u0432\u043e\u0437\u0440\u0430\u0449\u044f\u0435\u043c \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u043f\u0443\u0441\u0442\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0443 \u043d\u0430\u0441 \u0447\u0435\u0440\u0435\u0437 main.rs \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f <a href=\"https:\/\/doc.rust-lang.org\/std\/sync\/mpsc\/\" rel=\"noopener noreferrer nofollow\">\u043a\u0430\u043d\u0430\u043b mpsc<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 TCP \u0438 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 network_server_start \u0438\u0437 \u043f\u0430\u043a\u0435\u0442\u0430 network, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0433\u043e &#171;\u043f\u0443\u0441\u0442\u044b\u0445&#187; \u0444\u0430\u0439\u043b\u043e\u0432, \u043d\u043e \u043e\u0442\u0442\u0443\u0434\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u043b\u0438\u0448\u044c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b, \u0441\u0435\u0440\u0432\u0435\u0440, \u0431\u0443\u0444\u0435\u0440\u044b \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438. \u0421\u0430\u043c \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u043f\u0443\u0442\u0438 src\/network\/server.rs: <\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">use crate::network::handler::{handshaking, status_handler}; use crate::network::network_client::ConnectionType::HANDSHAKING; use crate::network::network_client::NetworkClient; use ahash::AHashMap; use mio::net::TcpListener; use mio::{Events, Interest, Poll, Token}; use std::io; use std::sync::mpsc::Sender; use std::sync::Mutex; use std::time::Duration;  \/\/ Declare global variables lazy_static! {     \/\/ Server need to shut down? (true - yes, needs to shutdown network server).     pub static ref SHUTDOWN_SERVER: Mutex&lt;bool> = Mutex::new(false);     \/\/ Server's works status.     pub static ref NET_SERVER_WORKS: Mutex&lt;bool> = Mutex::new(true); }  \/\/ Server's Token(ID) const SERVER: Token = Token(0);  \/\/ Next Token fn next(current: &amp;mut Token) -> Token {     let next = current.0;     current.0 += 1;     Token(next) }  \/\/ Start a network server pub fn network_server_start(address: String, tx: &amp;Sender&lt;bool>) -> std::io::Result&lt;()> {     \/\/ Creating Network Pool     let mut poll = Poll::new()?;     \/\/ Creating Network Events Pool     let mut events = Events::with_capacity(256);     \/\/ Converting String's address to SocketAddr     let addr = address.parse().unwrap();     \/\/ Starting a Network Listener     let mut server = TcpListener::bind(addr)?;     \/\/ Register server's Token     poll.registry()         .register(&amp;mut server, SERVER, Interest::READABLE)?;      \/\/ Creating a list of connections     let mut connections: AHashMap&lt;Token, NetworkClient> = AHashMap::new();     \/\/ Creating a variable with latest token.     let mut unique_token = Token(SERVER.0 + 1);     \/\/ Send over the channel that the server has been successfully started     tx.send(true);      \/\/ Network Events getting timeout     let timeout = Some(Duration::from_millis(10));     \/\/ Infinity loop(while true) to handing events     loop {         \/\/ Checks whether it is necessary to shutdown the network server         if *SHUTDOWN_SERVER.lock().unwrap() {             *NET_SERVER_WORKS.lock().unwrap() = false;             info!(\"Network Server Stopped!\");             return Ok(());         }         \/\/ Getting a events from pool to event's pool with timeout         poll.poll(&amp;mut events, timeout)?;         \/\/ Handing a events         for event in events.iter() {             \/\/ Handing event by token             match event.token() {                 \/\/ If it server's event                 \/\/ Reading a all incoming connection                 SERVER => loop {                     \/\/ Accepting connection                     let (mut connection, _) = match server.accept() {                         \/\/ If successful                         Ok(v) => v,                         \/\/ If not exists incoming connection                         Err(e) if e.kind() == io::ErrorKind::WouldBlock => {                             break;                         }                         \/\/ If failed to get incoming connection                         Err(e) => {                             return Err(e);                         }                     };                      \/\/ Generating new token for this connection                     let token = next(&amp;mut unique_token);                     \/\/ Registering connection with token                     poll.registry().register(                         &amp;mut connection,                         token,                         Interest::READABLE.add(Interest::WRITABLE),                     )?;                     \/\/ Pushing connection into connection's list                     connections.insert(                         token,                         NetworkClient {                             stream: connection,                             conn_type: HANDSHAKING,                         },                     );                 },                 \/\/ Handing event from client                 token => {                     \/\/ Handing event by connection's stage                     let done = if let Some(connection) = connections.get_mut(&amp;token) {                         let m = match &amp;connection.conn_type {                             HANDSHAKING => handshaking,                             _ => status_handler,                         };                         \/\/ Trying to handing                         m(connection, &amp;event).unwrap_or(false)                     } else {                         false                     };                     \/\/ If needs to close connection - removing from list, unregister and close connection's stream                     if done {                         if let Some(mut connection) = connections.remove(&amp;token) {                             poll.registry().deregister(&amp;mut connection.stream)?;                             connections.remove(&amp;token);                         }                     }                 }             }         }     } }<\/code><\/pre>\n<p>\u0414\u0430, \u0443\u0436\u0435 \u0446\u0435\u043b\u044b\u0445 125 \u0441\u0442\u0440\u043e\u0447\u0435\u043a, \u043d\u043e \u044d\u0442\u043e \u0435\u0449\u0451 \u043c\u0430\u043b\u043e<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u043d\u0451\u043c \u043c\u044b \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f lazy_static, \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0442\u0438\u043f bool \u0437\u0430\u0432\u0451\u0440\u043d\u0443\u0442 \u0432 \u043e\u0431\u043e\u043b\u043e\u0447\u043a\u0443 <abbr title=\"\u041f\u0440\u0438\u043c\u0438\u0442\u0438\u0432 \u0432\u0437\u0430\u0438\u043c\u043d\u043e\u0433\u043e \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043f\u043e\u043b\u0435\u0437\u043d\u044b\u0439 \u0434\u043b\u044f \u0437\u0430\u0449\u0438\u0442\u044b \u043e\u0431\u0449\u0438\u0445 \u0434\u0430\u043d\u043d\u044b\u0445\">Mutex<\/abbr>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u043c\u0443\u043b\u044c\u0442\u0438\u043f\u043e\u0442\u043e\u0447\u043d\u044b\u0439 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439, \u043a \u0447\u0442\u0435\u043d\u0438\u0438 \u0438 \u0437\u0430\u043f\u0438\u0441\u0438, \u043d\u043e \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0442\u043e\u043a \u043e\u0436\u0438\u0434\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438. \u0421\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u0442\u0430\u043a-\u0436\u0435 \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u0430\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 SERVER, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0430\u0439\u0434\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 \u0441\u0435\u0442\u0435\u0432\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u0414\u0430\u043b\u0435\u0435 \u0438\u0434\u0451\u0442 next, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a ++ \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445<code>(\u0432 \u0440\u0430\u0441\u0442\u0435 \u043d\u0435 ++, \u0430 +=1)<\/code>, \u0430 \u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0437\u0430 \u044d\u0442\u043e\u0439 \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439 \u0443\u0436\u0435 \u0434\u0440\u0443\u0433\u0430\u044f &#8212; network_server_start. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430 \u0441\u0442\u0430\u0440\u0442\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0434\u0432\u0430 \u043f\u0443\u043b\u0430, \u043e\u0434\u0438\u043d \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438 \u0434\u0430\u043b\u044c\u0448\u0435 \u0438\u0434\u0451\u0442 \u043f\u0430\u0440\u0441\u0438\u043d\u0433 \u0441\u0442\u0440\u043e\u043a\u0438 \u0432 <abbr title=\"SocketAddr\">\u0430\u0434\u0440\u0435\u0441\u0441<\/abbr>, \u0430 \u0441\u043b\u0435\u0434\u043e\u043c \u043f\u043e\u043f\u044b\u0442\u043a\u0430 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c TCP \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 \u044d\u0442\u043e\u043c \u0430\u0434\u0440\u0435\u0441\u0441\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0435\u0433\u0435\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0432 \u043f\u0443\u043b\u0435 \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e-\u0447\u0442\u0435\u043d\u0438\u0435, \u043f\u043e\u0441\u043b\u0435 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439 \u0438 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0442\u043e\u043a\u0435\u043d \u043d\u0430 \u043d\u043e\u0432\u043e\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u043e\u0448\u0438\u0431\u043e\u043a, \u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u043a\u0430\u043d\u0430\u043b \u0441\u0432\u044f\u0437\u0438 &#8212; true, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043e\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043e \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435. \u041f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u0430\u044f timeout \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043a\u0430\u043a \u043b\u0438\u043c\u0438\u0442 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0446\u0438\u043a\u043b \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u0432 \u0437\u0430\u043d\u043e\u0433\u043e, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0432 \u0446\u0438\u043a\u043b\u0435: \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043d\u0430 \u043d\u0443\u0436\u0434\u0443 \u0432 \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u0435\u0441\u043b\u0438 \u043d\u0430\u0434\u043e, \u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u0442\u0430\u0442\u0443\u0441, \u0447\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d \u0438 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0446\u0438\u043a\u043b, \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u0443\u044e \u0440\u0430\u0431\u043e\u0442\u0443 \u043f\u043e \u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0438 \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044f \u0438 \u0442\u0434 \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0430\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440. \u0415\u0441\u043b\u0438 \u0436\u0435 \u043e\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0442\u044c \u043d\u0430\u043c \u043d\u0435 \u043d\u0430\u0434\u043e, \u0442\u043e \u043c\u044b \u0436\u0434\u0451\u043c \u0434\u043e 10\u043c\u0441 \u0441\u0435\u0442\u0435\u0432\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0438 \u043f\u043e\u0437\u0436\u0435 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0435\u043c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f. \u0421\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0431\u044b\u0432\u0430\u044e\u0442 \u0442\u043e\u043b\u044c\u043a\u043e &#8212; \u043f\u0440\u0438\u043d\u044f\u0442\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0435\u0449\u0451 \u0446\u0438\u043a\u043b \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u0432\u0441\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0435\u043c \u0438\u0445. \u0412 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c\u0438(\u043f\u0440\u0438\u0441\u043b\u0430\u043d\u043d\u044b\u0439 \u043f\u0430\u043a\u0435\u0442 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440) &#8212; \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0438\u043f\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f(HandShaking, Status \u0438 \u0442\u0434) \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u043c \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0435\u043c\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0443 \u0438 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0435\u0441\u043b\u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0432\u043e\u0437\u0440\u0430\u0449\u0430\u0435\u0442 true, \u0442\u043e \u043c\u044b \u0440\u0430\u0437\u0440\u044b\u0432\u0430\u0435\u043c \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u0438\u0435 \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0435\u0433\u043e \u0438\u0437 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439.<\/p>\n<h3>\u041f\u0440\u043e\u0442\u043e\u043a\u043e\u043b, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u0447\u0442\u0435\u043d\u0438\u0435 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u043e\u0432<\/h3>\n<p>\u0422\u0430\u043a-\u043a\u0430\u043a \u044f\u0434\u0440\u043e \u044f \u043f\u044b\u0442\u0430\u044e\u0441\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043c\u0435\u043d\u0435\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b\u043c \u043e\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a, \u0442\u043e \u0434\u043b\u044f \u0447\u0430\u0442\u0430 \u0438 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u0441\u0451 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043e \u0441 0 \u0438 \u0434\u043b\u044f \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0435\u043d\u0438\u044f \u0431\u043e\u043b\u044c\u0448\u0435\u0433\u043e \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u044f \u043d\u0430\u0434 \u0447\u0442\u0435\u043d\u0438\u0435\u043c \u0438 \u0437\u0430\u043f\u0438\u0441\u044c\u044e.<\/p>\n<p>\u0411\u044b\u043b\u043e \u0440\u0435\u0448\u0435\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0431\u0443\u0444\u0435\u0440\u044b \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0432 \u0432\u0438\u0434\u0435 \u0432\u0435\u043a\u0442\u043e\u0440\u043e\u0432 \u043a \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u044b \u043c\u0435\u0442\u043e\u0434\u044b \u0447\u0442\u0435\u043d\u0438\u044f \u0438 \u0437\u0430\u043f\u0438\u0441\u0438(\u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f Vec&lt;u8>):<\/p>\n<details class=\"spoiler\">\n<summary>\u0427\u0442\u0435\u043d\u0438\u0435 \u0431\u0443\u0444\u0435\u0440\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">use crate::{SResult, SimpleError};  \/\/\/ Reader [Vec] of bytes pub trait PacketReader {     \/\/ 1-Byte     fn get_u8(&amp;mut self) -> u8;     fn get_i8(&amp;mut self) -> i8;     \/\/ 2-Byte     fn get_u16(&amp;mut self) -> u16;     fn get_i16(&amp;mut self) -> i16;     \/\/ 4-Byte     fn get_varint(&amp;mut self) -> SResult&lt;i32>;     \/\/ 8-Byte     fn get_i64(&amp;mut self) -> i64;     \/\/ Another     fn get_string(&amp;mut self) -> SResult&lt;String>;     fn read_base(&amp;mut self) -> SResult&lt;(i32, i32)>; }  \/\/ Apply reader to Vec impl PacketReader for Vec&lt;u8> {     \/\/ Read a single byte as u8 ( 8-Bit Unsigned Integer )     fn get_u8(&amp;mut self) -> u8 {         self.remove(0)     }      \/\/ Read a single byte as i8 ( 8-Bit Integer )     fn get_i8(&amp;mut self) -> i8 {         self.remove(1) as i8     }      \/\/ Read a two bytes as u16 ( 16-Bit Unsigned Integer )     fn get_u16(&amp;mut self) -> u16 {         u16::from_be_bytes([self.get_u8(), self.get_u8()])     }      \/\/ Read a two bytes as i16 ( 16-Bit Integer )     fn get_i16(&amp;mut self) -> i16 {         i16::from_be_bytes([self.get_u8(), self.get_u8()])     }      \/\/ Read a VarInt ( Dynamic-length 32-Bit Integer )     fn get_varint(&amp;mut self) -> SResult&lt;i32> {         \/\/ Result variable         let mut ans = 0;         \/\/ Read up to 4 bytes         for i in 0..4 {             \/\/ Read one byte             let buf = self.get_u8();             \/\/ Calculate res with bit moving and another             ans |= ((buf &amp; 0b0111_1111) as i32) &lt;&lt; 7 * i;             \/\/ If it's limit when stop reading             if buf &amp; 0b1000_0000 == 0 {                 break;             }         }         \/\/ Return result as successful         Ok(ans)     }      \/\/ Read a Long ( 64-Bit Integer )     fn get_i64(&amp;mut self) -> i64 {         \/\/ Yes, read 8 bytes         i64::from_be_bytes([             self.get_u8(),             self.get_u8(),             self.get_u8(),             self.get_u8(),             self.get_u8(),             self.get_u8(),             self.get_u8(),             self.get_u8(),         ])     }      \/\/ Read a String ( VarInt as len; bytes[::len] )     fn get_string(&amp;mut self) -> SResult&lt;String> {         \/\/ Getting string-length         let len = self.get_varint()?;         \/\/ Create String's bytes buffer         let mut buf = Vec::new();         \/\/ Reading Bytes         for _ in 0..len {             buf.push(self.get_u8())         }         \/\/ Convert Bytes to UTF8 String         match String::from_utf8(buf) {             Ok(v) => Ok(v),             Err(_) => Err(SimpleError(String::from(\"Failed to parse chars\"), None)),         }     }     \/\/ Read first two VarInt(Packet's length and id)     fn read_base(&amp;mut self) -> SResult&lt;(i32, i32)> {         let len = self.get_varint()?;         let pid = self.get_varint()?;         Ok((len, pid))     } }<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0447\u0442\u0435\u043d\u0438\u0435 VarInt, String, Long \u0438 \u0434\u0440\u0443\u0433\u043e\u0435, \u0447\u0442\u043e \u043f\u043e\u043a\u0430 \u043d\u0430\u0434\u043e \u0431\u044b\u043b\u043e \u043f\u0440\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0438 \u044f\u0434\u0440\u0430.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u043f\u0438\u0441\u044c \u0432 \u0431\u0443\u0444\u0435\u0440\u044b \u043f\u0430\u043a\u0435\u0442\u043e\u0432<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/\/ Writer [Vec] of bytes pub trait PacketWriter {     \/\/ 1-Byte     fn write_u8(&amp;mut self, value: u8);     fn write_i8(&amp;mut self, value: i8);     \/\/ 2-Byte     fn write_u16(&amp;mut self, value: u16);     fn write_i16(&amp;mut self, value: i16);     \/\/ 4-Byte     fn write_varint(&amp;mut self, value: i32);     \/\/ 8-Byte     fn write_i64(&amp;mut self, value: i64);     \/\/ Another     fn write_vec_bytes(&amp;mut self, bytes: Vec&lt;u8>);     fn write_string(&amp;mut self, value: String);     fn create_packet(&amp;mut self, pid: i32) -> Vec&lt;u8>; }  impl PacketWriter for Vec&lt;u8> {     \/\/ Writing byte     fn write_u8(&amp;mut self, value: u8) {         self.push(value);     }      \/\/ Writing byte     fn write_i8(&amp;mut self, value: i8) {         self.push(value as u8)     }      \/\/ Writing 2-byte unsigned integer     fn write_u16(&amp;mut self, value: u16) {         self.extend_from_slice(&amp;value.to_be_bytes());     }      \/\/ Writing 2-byte unsigned integer     fn write_i16(&amp;mut self, value: i16) {         self.extend_from_slice(&amp;value.to_be_bytes());     }      \/\/ Writing bytes as VarInt     fn write_varint(&amp;mut self, mut value: i32) {         \/\/ Bytes buffer         let mut buf = vec![0u8; 1];         \/\/ Byte's length         let mut n = 0;         \/\/ Converts value to bytes         loop {             \/\/ Break if it's limit             if value &lt;= 127 || n >= 8 {                 break;             }             \/\/ Pushing a byte to buffer             buf.insert(n, (0x80 | (value &amp; 0x7F)) as u8);             \/\/ Moving value's bits on 7             value >>= 7;             value -= 1;             n += 1;         }         \/\/ Pushing byte, because it lower that 256(&lt;256)         buf.insert(n, value as u8);         n += 1;         \/\/ Pushing converted bytes into byte's buffer         self.extend_from_slice(&amp;buf.as_slice()[..n])     }      \/\/ Writing Long ( 64-Bit Integer )     fn write_i64(&amp;mut self, value: i64) {         self.extend_from_slice(value.to_be_bytes().as_slice())     }      \/\/ Alias of extend_from_slice, but works with Vec, not Slice     fn write_vec_bytes(&amp;mut self, mut bytes: Vec&lt;u8>) {         self.append(&amp;mut bytes);     }      \/\/ Write String (VarInt as len and string's bytes)     fn write_string(&amp;mut self, value: String) {         \/\/ Getting String as Bytes         let bytes = value.as_bytes();         \/\/ Writing to buffer a length as VarInt         self.write_varint(bytes.len() as i32);         \/\/ Writing to buffer a string's bytes         self.extend_from_slice(bytes);     }      \/\/ Packet's base builder     fn create_packet(&amp;mut self, pid: i32) -> Vec&lt;u8> {         \/\/ Creating empty packet's buffer         let mut packet = Vec::new();         \/\/ Creating length's bytes buffer and fill it as VarInt         let mut len_bytes: Vec&lt;u8> = Vec::new();         len_bytes.write_varint(pid);         \/\/ Writing full packet's length(content + length's bytes)         packet.write_varint((self.len() + len_bytes.len()) as i32);         \/\/ Writing length bytes         packet.extend_from_slice(len_bytes.as_slice());         \/\/ Drop(Free) length bytes buffer         drop(len_bytes);         \/\/ Writing some packet's content         packet.extend_from_slice(self.as_slice());         \/\/ Returning result         packet     } }<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0438\u0441\u044c \u043a \u0431\u0443\u0444\u0435\u0440\u0430\u043c \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0432 \u0440\u0430\u0437\u044b \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u0435\u0439 \u0438\u0437-\u0437\u0430 \u0431\u043e\u043b\u044c\u0448\u0438\u0445 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0439 \u043a \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443 \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b\u0430 MineCraft.<\/p>\n<\/div>\n<\/details>\n<p>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u043d\u0430 \u0441\u0442\u0430\u0442\u0443\u0441\u044b 0(HandShaking) \u0438 1(Status) \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435 src\/network\/handler.rs \u0438 \u0432 \u043d\u0451\u043c \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u0441\u0432\u043e\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f.<\/p>\n<p>\u0412\u043e\u0442 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 HandShaking:<\/p>\n<pre><code class=\"rust\">pub fn handshaking(conn: &amp;mut NetworkClient, event: &amp;Event) -> SResult&lt;bool> {     \/\/ Checking if we can read the package     if !event.is_readable() {         return Ok(false);     }     \/\/ Reading packet     let handshake = read_handshake_packet(conn);     \/\/ Checking if is error     if handshake.is_err() {         return Ok(true);     }     \/\/ Getting results     let (_, _, _, next_state) = handshake.unwrap();     \/\/ Change types     conn.conn_type = match next_state {         1 => STATUS,         _ => STATUS,     };     Ok(false) }<\/code><\/pre>\n<p>\u0425\u043e\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438 \u0438\u043c\u0435\u0435\u0442 20 \u0441\u0442\u0440\u043e\u0447\u0435\u043a, \u043d\u043e \u0432 \u043d\u0435\u0439 \u043c\u044b \u0442\u0440\u0435\u0431\u0443\u0435\u043c \u043b\u0438\u0448\u044c \u0447\u0442\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043f\u0430\u043a\u0435\u0442\u0430 \u0434\u043b\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u043d\u0443 \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0447\u0442\u0435\u043d\u0438\u0435 \u043f\u0430\u043a\u0435\u0442\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 read_handshake_packet:<\/p>\n<details class=\"spoiler\">\n<summary>\u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0447\u0442\u0435\u043d\u0438\u044f HandShake<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">pub fn read_handshake_packet(client: &amp;mut NetworkClient) -> SResult&lt;(u32, String, u16, u32)> {     \/\/ Read bytes from client     let (ok, p, err) = match client.read() {         Ok((ok, p)) => (ok, Some(p), None),         Err(err) => (false, None, Some(err)),     };     \/\/ If failed to read when...     if !ok || err.is_some() {         return Err(SimpleError(             String::from(\"Failed to read packet\"),             if err.is_some() { err.unwrap().1 } else { None },         ));     }     \/\/ Reading packet     let mut p: Vec&lt;u8> = p.unwrap();     \/\/ Try to read Length and PacketID from packet(on handshaking stage only 0x00)     p.read_base()?;     \/\/ Reading version, address and etc.     let ver = p.get_varint()? as u32;     let address = p.get_string()?;     let port = p.get_u16();     let next_state = p.get_varint()? as u32;     \/\/ States can be only 1 - status, 2 - play     if next_state >= 3 {         return Err(SimpleError(String::from(\"Invalid client\"), None));     }     \/\/ Returning results     Ok((ver, address, port, next_state)) }<\/code><\/pre>\n<p>\u041c\u044b \u0447\u0438\u0442\u0430\u0435\u043c \u043f\u0430\u043a\u0435\u0442 \u0438 \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0435 \u0432\u043e\u0437\u0440\u0430\u0449\u0430\u0435\u043c \u0435\u0451, \u0430 \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e, \u0442\u043e \u0438 \u0432\u043e\u0437\u0440\u0430\u0449\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u0447\u0442\u0435\u043d\u0438\u044f.<\/p>\n<\/div>\n<\/details>\n<p>\u0414\u043b\u044f \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0438\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f:<\/p>\n<pre><code class=\"rust\">pub fn status_handler(conn: &amp;mut NetworkClient, event: &amp;Event) -> SResult&lt;bool> {     \/\/ Checking if we can read and write     if !event.is_readable() || !event.is_writable() {         return Ok(false);     }     \/\/ Getting a input's bytes     let (ok, p, err) = match conn.read() {         Ok((ok, p)) => (ok, Some(p), None),         Err(err) => (false, None, Some(err)),     };     \/\/ Checking if a read or not     if !ok {         return Ok(err.is_some());     }     \/\/ Packet's bytes     let mut p: Vec&lt;u8> = p.unwrap();     \/\/ Cloning bytes(for ping-pong)     let bytes = p.clone();     \/\/ Reading a packet's length(and remove...) and PacketID     let (_, pid) = p.read_base()?;     match pid {         \/\/ Is Ping List         0x00 => {             drop(bytes);             conn.stream.write_all(&amp;*create_server_list_ping_response());         }         \/\/ Is Ping-Pong         0x01 => {             conn.stream.write_all(bytes.as_slice());             match conn.stream.peer_addr() {                 Ok(v) => info!(\"Server pinged from {}\", v),                 Err(_) => {                     info!(\"Server pinged.\")                 }             }         }         _ => {}     }     Ok(false) }<\/code><\/pre>\n<p>\u0412 \u043d\u0435\u0439 \u0441\u043d\u043e\u0432\u0430 \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0447\u0442\u0435\u043d\u0438\u044f, \u043d\u043e \u0438 \u0437\u0430\u043f\u0438\u0441\u0438 \u0442\u0430\u043a-\u043a\u0430\u043a \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u044b \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0442\u0434\u0430\u0451\u043c \u043d\u0435\u043a\u0438\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0421\u043d\u043e\u0432\u0430 \u0447\u0438\u0442\u0430\u0435\u043c \u0431\u0443\u0444\u0444\u0435\u0440 \u0438 \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0435\u0433\u043e \u043d\u0430\u0447\u0430\u043b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0432 \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0430\u0439\u0434\u0438 \u043f\u0430\u043a\u0435\u0442\u0430(0x00 &#8212; \u0421\u043f\u0438\u0441\u043e\u043a, 0x01 &#8212; \u041f\u0438\u043d\u0433-\u041f\u043e\u043d\u0433) \u044f \u0442\u0430\u043a-\u0436\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0431\u0443\u0444\u0444\u0435\u0440\u0430 \u0434\u043b\u044f \u0441\u043f\u0438\u0441\u043a\u0430:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u0430\u043c \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043e\u0442\u0432\u0435\u0442\u0430 \u043d\u0430 \u0441\u043f\u0438\u0441\u043e\u043a<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">\/\/ Structs for status MOTD response #[derive(Debug, Serialize)] pub struct ListPingResponse {     pub version: ListPingResponseVersion,     pub players: ListPingResponsePlayers,     pub description: ChatMessage, }  #[derive(Debug, Serialize)] pub struct ListPingResponseVersion {     pub name: String,     pub protocol: u32, }  #[derive(Debug, Serialize)] pub struct ListPingResponsePlayers {     pub max: u32,     pub online: u32,     pub sample: Vec&lt;ListPingResponsePlayerSample>, }  #[derive(Debug, Serialize)] pub struct ListPingResponsePlayerSample {     pub name: String,     pub id: String, } \/\/\/ Build packet's bytes as result pub fn create_server_list_ping_response() -> Vec&lt;u8> {     \/\/ Initialize empty byte's vector     let mut bytes = Vec::new();     \/\/ Generating String and convert to bytes.     \/\/ String generated as JSON by serde and serde_json libraries     bytes.write_string(         serde_json::to_string(&amp;ListPingResponse {             version: ListPingResponseVersion {                 name: String::from(\"ULE\"),                 protocol: PROTOCOL_VERSION,             },             players: ListPingResponsePlayers {                 max: 10,                 online: 0,                 sample: vec![],             },             \/\/ Some clients can read colors and so on without convert into JSON             description: ChatMessage::str(\"&amp;a&amp;lHello!\"),         })         .unwrap(),     );     \/\/ Build completed packet. Server List Ping - PacketID is 0x00     bytes.create_packet(0x00) }<\/code><\/pre>\n<p>\u0414\u043b\u044f \u043d\u0435\u0433\u043e \u043c\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u043e\u043c \u043a\u0430\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c JSON \u043e\u0442\u0432\u0435\u0442\u0430 \u0438 \u0434\u043b\u044f \u043e\u0442\u0432\u0435\u0442\u0430 \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u043f\u0443\u0441\u0442\u043e\u0439 \u0431\u0443\u0444\u0444\u0435\u0440, \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c \u0431\u0430\u0439\u0442\u044b \u043f\u0435\u0440\u0435\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0439 \u0441\u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u0432 JSON \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u043f\u0430\u043a\u0435\u0442 \u0441 \u0430\u0439\u0434\u0438 0x00. \u0414\u043b\u044f \u0441\u0435\u0440\u0435\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c serde \u0438 serde_json.<\/p>\n<\/div>\n<\/details>\n<p>\u0415\u0441\u043b\u0438 \u043f\u0438\u043d\u0433\u0430\u043d\u0443\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u043f\u0438\u043d\u0433-\u043f\u043e\u043d\u0433 \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043a\u043e\u043f\u0438\u044e \u0431\u0443\u0444\u0435\u0440\u0430 \u0442\u0430\u043a-\u043a\u0430\u043a \u044d\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u044d\u043a\u043e\u043d\u043e\u043c\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0442\u0430\u043a-\u043a\u0430\u043a \u0438\u043d\u0430\u0447\u0435 \u0431\u044b \u043f\u0440\u0438\u0448\u043b\u043e\u0441\u044c \u0447\u0438\u0442\u0430\u0442\u044c Long \u0438 \u0434\u0440\u0443\u0433\u043e\u0435, \u0447\u0442\u043e \u043d\u0430\u0433\u0440\u0443\u0436\u0430\u043b\u043e \u0431\u044b \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0440 \u0438 \u041e\u0417\u0423 \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043e\u043f\u0438\u044f \u0431\u0443\u0444\u0444\u0435\u0440\u0430.<\/p>\n<h2>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435&#8230; Input \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u0438  \u0438\u043b\u0438 \u0436\u0435 STDIN.<\/h2>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u044f\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0438\u0437 main.rs &#8212; \u0432\u0432\u043e\u0434 \u043a\u043e\u043c\u043c\u0430\u043d\u0434, \u043f\u043e\u043a\u0430 \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u044b\u0439 \u0438 \u0438\u043c\u0435\u0442\u044c \u0432\u0441\u0435\u0433\u043e stop \u0438 \u0432\u044b\u0432\u043e\u0434 \u0432\u0432\u0435\u0434\u0451\u043d\u043d\u043e\u0433\u043e. \u0422\u0430\u043a-\u043a\u0430\u043a \u0438\u043c\u0435\u0435\u0442\u0441\u044f \u043d\u0435 \u0442\u0430\u043a \u043c\u043d\u043e\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439 \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b, \u0442\u043e \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u0432\u0430\u0436\u043d\u043e\u0433\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u043d\u043e \u043d\u0435\u0442! \u041e\u043d \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u043c \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432\u043e\u0437\u0432\u043e\u043b\u044f\u044f \u0435\u043c\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0432\u0435\u0434\u044c \u0435\u0441\u043b\u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u0431\u0443\u0434\u0435\u0442 \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d, \u0442\u043e \u0438 \u0432\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043e\u0441\u043d\u043e\u0432\u0438\u0442\u044c\u0441\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0442\u0430\u043a:<\/p>\n<pre><code class=\"rust\">use crate::network::{NET_SERVER_WORKS, SHUTDOWN_SERVER}; use std::time::Duration; use std::{io, process, thread};  \/\/ Loop for handling input pub fn start_input_handler() -> std::io::Result&lt;()> {     \/\/ Input buffer     let mut inp = String::new();     \/\/ STDIN - os input     let stdin = io::stdin();     \/\/ loop for infinity handling     loop {         \/\/ Before write buffer we need to clear buffer         inp.clear();         \/\/ Reading a line         stdin.read_line(&amp;mut inp)?;         \/\/ Clearing input's buffer         inp = inp.replace(\"\\n\", \"\");         \/\/ Simple realisation of stop command, but in updates be removed from here in another place         if inp.starts_with(\"stop\") {             \/\/ Sending status to shutdown network server             *SHUTDOWN_SERVER.lock().unwrap() = true;             info!(\"Stopping server...\");             \/\/ Running process killing in 6 secs if failed to common shutdown             thread::spawn(|| {                 thread::sleep(Duration::from_secs(6));                 process::exit(0);             });             \/\/ Waiting for shutdown network's server             loop {                 if *NET_SERVER_WORKS.lock().unwrap() == true {                     thread::sleep(Duration::from_millis(25));                 } else {                     break;                 }             }             \/\/ Disabling the input             return Ok(());         }         \/\/ If it's not stop command - when display buffer, but in updates be removed         info!(\"Entered: {}\", inp);     } }<\/code><\/pre>\n<p>\u041c\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0431\u0443\u0444\u0444\u0435\u0440 \u0438 stdin, \u0430 \u0442\u0430\u043a-\u0436\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0446\u0438\u043a\u043b \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043e\u0447\u0438\u0449\u0430\u0435\u043c \u0431\u0443\u0444\u0444\u0435\u0440 \u043e\u0442 \u043f\u0440\u043e\u0448\u043b\u043e\u0433\u043e \u0432\u0432\u043e\u0434\u0430 \u0438 \u043f\u043e\u0442\u043e\u043c \u0431\u043b\u043e\u043a\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0442\u043e\u043a \u0432 \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u0438 \u0432\u0432\u043e\u0434\u0430. \u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0432\u0432\u043e\u0434\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c \u043d\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u043c\u0438\u043e\u0435 \u0438 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e stop, \u0442\u043e \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0441\u0435\u0442\u0435\u0432\u043e\u043c\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0432\u044b\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0441\u043b\u0443\u0448\u0430\u0442\u0435\u043b\u044c \u0438 \u0434\u043e\u0436\u0438\u0434\u0430\u0435\u043c\u0441\u044f \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f, \u043d\u043e \u0435\u0441\u043b\u0438 \u0437\u0430 6 \u0441\u0435\u043a\u0443\u043d\u0434 \u043d\u0435 \u043f\u0440\u043e\u0438\u0437\u043e\u0448\u043b\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f &#8212; \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441 \u043a\u043e\u0434\u043e\u043c 0, \u0435\u0441\u043b\u0438 \u0436\u0435 \u0443 \u043d\u0430\u0441 \u0431\u044b\u043b\u0430 \u0432\u0432\u0435\u0434\u0435\u043d\u0430 \u0438\u043d\u0430\u044f \u043a\u043e\u043c\u043c\u0430\u043d\u0434\u0430, \u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0435\u0451 \u0432 \u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0441 \u0443\u0440\u043e\u0432\u043d\u0435\u043c INFO, \u0434\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u043c.<\/p>\n<h2>\u0418\u0442\u043e\u0433 \u0447\u0430\u0441\u0442\u0438 #1.1<\/h2>\n<p>\u0414\u0430\u043d\u043d\u0430\u044f \u0447\u0430\u0441\u0442\u044c \u0431\u044b\u043b\u0430 \u043a\u0430\u043a-\u0431\u044b \u0437\u0430\u043c\u0435\u043d\u043e\u0439 #1 \u0438 \u0432 \u0434\u0430\u043d\u043d\u043e\u0439 \u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0438\u0437 \u0432\u0430\u0436\u043d\u043e\u0433\u043e \u0431\u044b\u043b\u043e:<\/p>\n<ol>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043d\u0430 Rust \u0441 \u044f\u0437\u044b\u043a\u0430 Go<\/p>\n<\/li>\n<li>\n<p>\u041e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u044f\u0437\u044b\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0430 &#8212; \u0410\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439<\/p>\n<\/li>\n<li>\n<p>\u0423\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u0435 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0432 \u0440\u0430\u0437\u044b \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f Rust<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043b\u043e\u0433\u0433\u0435\u0440\u0430 \u0438 \u0432\u0432\u043e\u0434\u0430<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u044f\u0434\u0440\u0430 \u043f\u043e\u043a\u0430 \u0432 2 \u043f\u043e\u0442\u043e\u043a\u0430\u0445, \u0430 \u043d\u0435 \u043a\u0430\u043a \u0432\u044b\u0445\u043e\u0434\u0438\u043b\u043e \u0432 Go<\/p>\n<\/li>\n<\/ol>\n<p>\u0412\u043e\u0442 \u0442\u0430\u043a\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u044f \u0434\u0443\u043c\u0430\u044e \u0441\u0442\u043e\u0438\u043b\u0438 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430, \u0442\u0435\u043c \u0431\u043e\u043b\u0435\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e Rust \u043c\u043d\u0435 \u0431\u043e\u043b\u044c\u0448\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u044c\u0441\u044f \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0441\u0432\u043e\u0435\u0439 \u043f\u0440\u0438\u0431\u043b\u0438\u0436\u0451\u043d\u043d\u043e\u0441\u0442\u0438 \u043a \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u0443 \u0438 \u043e\u0442\u043b\u0438\u0447\u043d\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430 \u0441 \u041e\u0417\u0423:<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" alt=\"\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u043f\u0438\u043d\u0433\u0435\" title=\"\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u043f\u0438\u043d\u0433\u0435\" height=\"56\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/3c4\/42e\/61f\/3c442e61fd80e60876d84e15adc51898.png\" data-width=\"533\"\/><figcaption>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u043f\u0440\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u043c \u043f\u0438\u043d\u0433\u0435<\/figcaption><\/figure>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"\/img\/image-loader.svg\" alt=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u0438 \u043f\u0438\u043d\u0433\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u041f\u043e\u0447\u0442\u0438 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438.\" title=\"\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u0438 \u043f\u0438\u043d\u0433\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u041f\u043e\u0447\u0442\u0438 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438.\" height=\"63\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/61e\/ea6\/8b7\/61eea68b7491d3d5138ea164ace0481f.png\" data-width=\"604\"\/><figcaption>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043f\u0440\u0438 \u043f\u0438\u043d\u0433\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u041f\u043e\u0447\u0442\u0438 \u0442\u043e\u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 \u0432 \u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0447\u0430\u0441\u0442\u0438.<\/figcaption><\/figure>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 \u043f\u0438\u043d\u0433\u0443\u0435\u0442\u0441\u044f \u043b\u0435\u0433\u043a\u043e, \u043f\u043e\u0442\u0440\u0435\u0431\u043b\u044f\u044f 128\u041a\u0411 \u043d\u0430 Linux, \u0430 \u043d\u0430 \u043c\u043e\u0451\u043c 4300U \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u043b\u0441\u044f \u0437\u0430 735236ns.<\/p>\n<hr\/>\n<p>\u042f \u043d\u0430\u0434\u0435\u044e\u0441\u044c \u0432\u0430\u043c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e \u0447\u0438\u0442\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u044c\u0438 \u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u044f\u0434\u0440\u0430 \u0438 \u0441\u043d\u043e\u0432\u0430 \u0441\u043a\u0430\u0436\u0443:<\/p>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u044f\u0434\u0440\u0430 <a href=\"https:\/\/github.com\/Distemi\/ULE\" rel=\"noopener noreferrer nofollow\">\u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 GitHub<\/a> \u0438 \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043c\u0435\u043d\u044f \u0432\u0430\u043b\u044e\u0442\u043e\u0439, \u0442\u043e \u0443 \u043c\u0435\u043d\u044f <a href=\"https:\/\/www.patreon.com\/user?u=64366641\" rel=\"noopener noreferrer nofollow\">\u0435\u0441\u0442\u044c patreon<\/a>. <\/p>\n<blockquote>\n<p>\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u043c\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430 \u0432\u0430\u0448\u0435 \u043c\u043d\u0435\u043d\u0438\u0435 \u043e \u043c\u043e\u0451\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435. \u0411\u0443\u0434\u0443 \u0441\u0442\u0430\u0440\u0430\u0442\u044c\u0441\u044f \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u043d\u0430 \u0432\u0441\u0435.<\/p>\n<\/blockquote>\n<p>\u0412\u0437\u0430\u0440\u0430\u043d\u0435\u0435 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0441\u043a\u043e\u0440\u043e \u0431\u0443\u0434\u0443 \u0432\u0432\u043e\u0434\u0438\u0442\u044c \u0438 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 WASM, \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0434\u0432\u0438\u0436\u043a\u0443 Wasmer.<\/p>\n<\/div>\n<\/div>\n<\/div>\n<div class=\"v-portal\" style=\"display:none;\"><\/div>\n<\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/post\/649779\/\"> https:\/\/habr.com\/ru\/post\/649779\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0412\u0441\u0435\u043c \u043f\u0440\u0438\u0432\u0435\u0442! \u0423\u0436\u0435 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u043f\u0440\u043e\u0448\u043b\u043e \u0441 <a href=\"https:\/\/habr.com\/ru\/post\/646483\/\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e\u0448\u043b\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438<\/a>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u044f \u043f\u0438\u0441\u0430\u043b \u043f\u0440\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u0432\u043e\u0435\u0439 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438, \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u0439 \u043d\u0430 Go, \u043a\u0430\u043a \u0432\u0441\u0435\u0433\u0434\u0430 <a href=\"https:\/\/github.com\/Distemi\/ULE\" rel=\"noopener noreferrer nofollow\">\u0438\u0441\u0445\u043e\u0434\u043d\u044b\u0439 \u043a\u043e\u0434 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043d\u0430 GitHub<\/a>. \u0421\u0440\u0430\u0437\u0443 \u0434\u0443\u043c\u0430\u044e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0437\u0430 \u044d\u0442\u043e \u0432\u0440\u0435\u043c\u044f \u0443\u0441\u043f\u0435\u043b \u0443\u0436\u0435 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u043d\u0430 \u043b\u0438\u043d\u0443\u043a\u0441(Mint Cinnamon), \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0439 GPU, \u043d\u043e \u0432 \u043a\u043e\u043d\u0446\u0435 \u043a\u043e\u043d\u0446\u043e\u0432 \u043d\u0430\u043a\u043e\u043d\u0435\u0446 \u044f \u0441\u043c\u043e\u0433 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u043e\u043c \u043e\u0442 JetBrains \u0438 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0441 Go \u043d\u0430 Rust, \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u0442\u0430\u043a-\u043a\u0430\u043a \u044f \u0434\u0443\u043c\u0430\u043b \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0430 \u0440\u0430\u0441\u0442\u0435, \u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u0442\u0438\u0447\u043d\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c&#8230; \u041d\u043e \u0432\u043e\u0442 \u0438 \u0431\u044b\u043b \u0441\u0434\u0435\u043b\u0430\u043d \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u0441 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f\u043c\u0438 \u043a\u0430\u043a \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0442\u0430\u043a \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439!)<\/p>\n<h3>\u041f\u0440\u0438\u0447\u0438\u043d\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0441 Go \u043d\u0430 Rust<\/h3>\n<ol>\n<li>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u044f \u0437\u0430\u0434\u0443\u043c\u044b\u0432\u0430\u043b\u0441\u044f \u043e \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043d\u0430 \u043d\u0451\u043c, \u043d\u043e \u043d\u0435 \u043c\u043e\u0433 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043e\u0434 \u043d\u0430 \u0440\u0430\u0441\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0432 \u0440\u0430\u0437\u044b \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0438 \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u0435\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0438\u0437\u043c\u0435\u0440\u044f\u0442\u044c \u0432 \u043d\u0430\u043d\u043e\u0441\u0435\u043a\u0443\u043d\u0434\u0430\u0445&#8230;)<\/p>\n<\/li>\n<\/ol>\n<h3>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u0443\u0442\u043e\u0447\u043d\u0435\u043d\u0438\u0439<\/h3>\n<p>\u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043d\u0430 Rust \u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0441\u0442\u043e\u0438\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u043f\u043e-\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a, \u0442\u0430\u043a-\u043a\u0430\u043a \u0435\u0433\u043e \u0437\u043d\u0430\u044e\u0442 \u0431\u043e\u043b\u044c\u0448\u0438\u043d\u0441\u0442\u0432\u043e, \u0430 \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u0435\u0441\u043b\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u0440\u0443\u0441\u0441\u043a\u043e\u0433\u043e &#8212; \u0441\u043c\u043e\u0436\u0435\u0442 \u0432\u043f\u043e\u043b\u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0438\u0437-\u0437\u0430 \u044d\u0442\u043e\u0433\u043e \u0432\u0441\u0435 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438 \u0432 \u0441\u0442\u0430\u0442\u044c\u0435 \u0438 \u043a\u043e\u0434\u0435 \u043d\u0430 GitHub \u0431\u0443\u0434\u0443\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u044b \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u044f\u0437\u044b\u043a\u0435, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438 \u043c\u043d\u043e\u0433\u043e \u043e\u0448\u0438\u0431\u043e\u043a&#8230; \u041f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u0430\u043a-\u0436\u0435 \u043c\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u043e\u0432, \u043d\u043e \u0435\u0441\u0442\u044c \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0447\u0442\u0438 \u043f\u0443\u0441\u0442\u044b\u0435 \u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044c\u0435\u0434\u0438\u043d\u044f\u044e\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043c\u043e\u0434\u0443\u043b\u0435\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u044f \u043d\u0435 \u0431\u0443\u0434\u0443 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0441\u0442\u0430\u0432\u043b\u044e \u043a\u043e\u0434.<\/p>\n<h2>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 #1.1<\/h2>\n<p>\u041a\u043e\u0434 \u043d\u0430 \u0440\u0430\u0441\u0442\u0435 \u0432\u044b\u0448\u0435\u043b \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u0432 \u0440\u0430\u0437\u044b \u0431\u043e\u043b\u044c\u0448\u0435 \u0442\u0430\u043a-\u043a\u0430\u043a \u044f \u043f\u044b\u0442\u0430\u043b\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0431\u043e\u043b\u044c\u0448\u0435 \u0441\u0432\u043e\u0435\u0433\u043e, \u043d\u043e \u0432\u0441\u0451-\u0442\u0430\u043a\u0438 \u0434\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b \u043c\u043d\u043e\u0433\u043e, \u043d\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a \u0438 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b \u0438\u0445 \u0432 Cargo.toml:<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 Cargo.toml<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"markdown\">[package] name = \"ule\" version = \"0.1.0\" edition = \"2021\" publish = true authors = [     \"Distemi &lt;distemi.bot@mail.ru>\" ] homepage = \"https:\/\/github.com\/Distemi\/ULE\" repository = \"https:\/\/github.com\/Distemi\/ULE\"  [dependencies] # \u0411\u044b\u0441\u0442\u0440\u044b\u0439 HashMap \u0438 \u0434\u0440\u0443\u0433\u043e\u0435. ahash = \"0.7.6\" # \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 lazy_static = \"1.4.0\" # Struct &lt;-> JSON serde = { version = \"1.0.136\", features = [\"derive\"] } serde_json = \"1.0.78\" # \u0423\u0442\u0438\u043b\u0438\u0442\u044b \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f log = \"0.4.14\" fern = { version = \"0.6\", features = [\"colored\"] } # \u0412\u0440\u0435\u043c\u044f chrono = \"0.4.19\" # \u0410\u0441\u0438\u043d\u0445\u0440\u043e\u043d\u043d\u043e\u0441\u0442\u044c(\u0441\u043a\u043e\u0440\u043e \u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f) async-std = \"1.10.0\"  # \u041e\u0434\u043d\u043e\u043f\u043e\u0442\u043e\u0447\u043d\u044b\u0439 TCP \u0438 UDP \u0441\u0435\u0440\u0432\u0435\u0440 [dependencies.mio] version = \"0.8.0\" default-features = false features = [     \"os-ext\",     \"net\" ]   [profile.release] opt-level = \"z\" <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041a\u0430\u043a \u0440\u0430\u0437 \u043d\u0430\u0448 Cargo.toml \u044f\u0432\u043b\u044f\u0435\u0442\u044c\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u0438\u0437 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430 \u0441\u043b\u0435\u0434\u044e\u0449\u0438\u0439 \u043f\u043e \u0432\u0430\u0436\u043d\u043e\u0441\u0442\u0438 src\/main.rs:<\/p>\n<details class=\"spoiler\">\n<summary>\u041d\u0430\u0448 main.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">#![allow(unused_must_use)] use crate::config::{ADDRESS, ADDRESS_PORT}; use crate::logger::start_input_handler; use crate::network::network_server_start; use fern::colors::Color; use std::error::Error; use std::process; use std::sync::mpsc::channel; use std::sync::Arc; use std::time::SystemTime; use std::{fmt, thread}; use utils::logger;  \/\/ Use a macros from serde(Serialize and Deserialize), log(Logging) and lazy_static(Global variables) #[macro_use] extern crate serde; #[macro_use] extern crate log; #[macro_use] extern crate lazy_static;  pub mod config; pub mod network; pub mod utils;  \/\/ Main function of application fn main() {     let start = SystemTime::now();     \/\/ Initialize logger     println!(\"Starting ULE v1.0.0...\");     if let Err(err) = logger::setup_logger() {         eprintln!(\"Failed to initialize logger: {}\", err);         process::exit(1);     }     \/\/ Creating channel for multithreading communication with main's thread and network's thread     let (tx, rx) = channel::&lt;bool>();     \/\/ Generate server's address and make it accessible with thread safe     let address = Arc::new(String::from(format!(         \"{}:{}\",         ADDRESS,         ADDRESS_PORT.to_string()     )));     \/\/ Start network in another thread     thread::spawn({         let address = address.to_string();         move || {             \/\/ Start network             \/\/ If failed to start when return error             if let Err(err) = network_server_start(address, &amp;tx) {                 error!(\"{}\", err);                 tx.send(false);             }         }     });     \/\/ Wait for status from server's network     if rx.recv().unwrap_or(false) {         \/\/ If Server successful started         info!(\"Server started at {}\", address);         \/\/ Showing about the full launch and showing the time to start         {             let elapsed = start.elapsed().unwrap();             info!(                 \"The server was successfully started in {}\",                 if elapsed.as_secs() >= 1 {                     format!(\"{}s\", elapsed.as_secs())                 } else if elapsed.as_millis() >= 1 {                     format!(\"{}ms\", elapsed.as_millis())                 } else {                     format!(\"{}ns\", elapsed.as_nanos())                 }             );             drop(elapsed);         };     } else {         \/\/ If Failed to start Server         error!(\"Failed to start server on {}.\", address);         process::exit(1);     }     \/\/ Remove channel     std::mem::drop(rx);     \/\/ Start console input handler(input commands)     start_input_handler(); }  \/\/ Custom error(yes, not std::io:Error) #[derive(Debug)] pub struct SimpleError(String, Option&lt;std::io::Error>);  impl Error for SimpleError {}  impl fmt::Display for SimpleError {     fn fmt(&amp;self, f: &amp;mut fmt::Formatter) -> fmt::Result {         \/\/ Check is error provided         if self.1.is_some() {             write!(f, \"{}: {:?}\", self.0, self.1)         } else {             write!(f, \"{}\", self.0)         }     } }  \/\/ Custom Result with custom Error pub type SResult&lt;T> = Result&lt;T, SimpleError>; <\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u0412 \u043d\u0430\u0448\u0435\u043c main.rs \u0432 \u0441\u0430\u043c\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0435 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u043e\u0442\u0441\u0447\u0451\u0442 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0441\u043a\u043e\u0440\u0435 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430 \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430. \u041f\u043e\u0442\u043e\u043c \u043c\u044b \u043f\u044b\u0442\u0430\u0435\u043c\u0441\u044f \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043b\u043e\u0433\u0433\u0435\u0440(fern + log), \u043f\u0440\u0438 \u043d\u0435\u0443\u0434\u0430\u0447\u0435 &#8212; \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443 \u0438 &#171;\u0443\u0431\u0438\u0432\u0430\u0435\u043c&#187; \u043f\u0440\u043e\u0446\u0435\u0441\u0441. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0443 \u043d\u0430\u0441 \u0438\u0434\u0451\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u0435\u043a\u043e\u0433\u043e \u043a\u0430\u043d\u0430\u043b\u0430, \u0430 \u043f\u043e\u0441\u043b\u0435 \u0441\u0442\u0440\u043e\u043a\u0438 \u0430\u0434\u0440\u0435\u0441\u0441\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u043e \u043a\u0430\u043d\u0430\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u043e \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u043a\u0430\u043a UDP, \u043d\u043e \u0441 \u0431\u043b\u043e\u043a\u0438\u0440\u043e\u0432\u043a\u043e\u0439 \u043f\u043e\u0442\u043e\u043a\u043e\u0432, \u043e\u043d \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043e\u0436\u0438\u0434\u0430\u043d\u0438\u044f \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0433\u043e \u043f\u043e\u0442\u043e\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0436\u0434\u0451\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043e\u0442 \u043f\u043e\u0442\u043e\u043a\u0430 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430(TCP \u0441\u0435\u0440\u0432\u0435\u0440), \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c &#8212; \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e\u0431 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u0437\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u043b\u043e\u0441\u044c, \u043f\u0440\u0438 \u043e\u0448\u0438\u0431\u043a\u0435 &#8212; \u0432\u044b\u0432\u043e\u0434\u0438\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430. \u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u0430\u0448 TCP \u0441\u0435\u0440\u0432\u0435\u0440, \u0442\u043e \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u043d\u0430\u0448 \u043a\u0430\u043d\u0430\u043b \u0441\u0432\u044f\u0437\u0438 \u0438 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441\u043b\u0443\u0448\u0430\u0442\u044c \u0432\u0432\u043e\u0434 \u0441 \u043a\u043e\u043d\u0441\u043e\u043b\u0438. \u041a\u0430\u043a \u0432\u0438\u0434\u043d\u043e \u0435\u0441\u0442\u044c \u0442\u0438\u043f\u044b SResul(\u0438\u0437 \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f SimpleResult) \u0438 SimpleError, \u043f\u0435\u0440\u0432\u044b\u0439 \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u0441\u0430\u043c \u0437\u0430 \u0441\u0435\u0431\u044f, \u043a\u0430\u043a \u0438 \u0432\u0442\u043e\u0440\u043e\u0439, \u043d\u043e \u0434\u043b\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438\u0434\u0451\u0442 \u043f\u0440\u0438\u043c\u0438\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043d\u044b\u0445 trait \u0434\u043b\u044f \u043f\u043e\u043a\u0430\u0437\u0430 \u043e\u0448\u0438\u0431\u043e\u043a.<\/p>\n<p>\u041d\u0430\u0448 \u043c\u0435\u0442\u043e\u0434 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0433\u0435\u0440\u0430 \u043b\u0435\u0436\u0438\u0442 \u0432 \u0444\u0430\u0439\u043b\u0435 src\/utils\/logger\/input.rs, \u043d\u043e \u044f \u043f\u043e\u043a\u0430\u0436\u0443 \u0442\u0430\u043a-\u0436\u0435 src\/utils\/mod.rs \u0438 src\/utils\/logger\/mod.rs, \u0442\u0430\u043a-\u043a\u0430\u043a \u043e\u043d\u0438 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u044b:<\/p>\n<details class=\"spoiler\">\n<summary>src\/utils\/mod.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">pub mod chat; pub mod logger;<\/code><\/pre>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043c\u043e\u0434\u0443\u043b\u0438 \u0447\u0430\u0442\u0430 \u0438 \u043b\u043e\u0433\u0433\u0435\u0440\u0430 \u043f\u0443\u0431\u043b\u0438\u0447\u043d\u043e<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>src\/utils\/logger\/mod.rs<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">mod input; mod log_lib;  pub use {input::start_input_handler, log_lib::setup_logger};<\/code><\/pre>\n<p>\u0422\u0443\u0442 \u0438\u0434\u0451\u0442 \u0438\u043c\u043f\u043e\u0440\u0442 input.rs \u0438 log_lib.rs, \u0430 \u0442\u0430\u043a-\u0436\u0435 \u044d\u043a\u0441\u043f\u043e\u0440\u0442 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 start_input_handler \u0438 setup_logger<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0444\u0430\u0439\u043b\u0430 \u0441 \u043c\u0435\u0442\u043e\u0434\u043e\u043c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0433\u0435\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">use crate::Color; use fern::colors::ColoredLevelConfig; use std::fs;  \/\/ Logger's initialize(fern, color and log) pub fn setup_logger() -> Result&lt;(), fern::InitError> {     \/\/ Removing latest log if exists     fs::remove_file(\"latest.log\");     \/\/ Setting colors     let colors = ColoredLevelConfig::new()         .info(Color::BrightBlack)         .warn(Color::Yellow)         .error(Color::Red)         .trace(Color::BrightRed);     \/\/ Setting fern     fern::Dispatch::new()         \/\/ Setting custom format to logging         .format(move |out, message, record| {             out.finish(format_args!(                 \"{} [{}] {}\",                 chrono::Local::now().format(\"[%m-%d %H:%M:%S]\"),                 colors.color(record.level()),                 message             ))         })         \/\/ Setting log-level         .level(log::LevelFilter::Info)         \/\/ Setting target's logger         .chain(std::io::stdout())         \/\/ Setting log's file         .chain(fern::log_file(\"latest.log\")?)         \/\/ Applying settings         .apply()?;     \/\/ If successful setting - returning ok     Ok(()) }<\/code><\/pre>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043b\u043e\u0433\u0435\u0440\u0430 \u043c\u044b \u0432 \u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0443\u0434\u0430\u043b\u044f\u0435\u043c \u0444\u0430\u0439\u043b \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043b\u043e\u0433\u0430 <strong>latest.log<\/strong>, \u043f\u043e\u0442\u043e\u043c \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u043b\u043e\u0433\u0430 \u0441\u0432\u043e\u0439 \u0446\u0432\u0435\u0442(INFO = \u0441\u0435\u0440\u044b\u0439, WARN &#8212; \u0436\u0451\u043b\u0442\u044b\u0439, ERROR &#8212; \u043a\u0440\u0430\u0441\u043d\u044b\u0439, TRACE &#8212; \u044f\u0440\u043a\u043e-\u043a\u0440\u0430\u0441\u043d\u044b\u0439). \u041f\u043e\u0437\u0436\u0435 \u0438\u0434\u0451\u0442 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u043b\u043e\u0433\u0433\u0435\u0440\u0430 fern \u0438 \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0444\u043e\u0440\u043c\u0430\u0442: [\u0414\u0410\u0422\u0410] [\u0423\u0420\u041e\u0412\u0415\u041d\u042c] \u0421\u041e\u041e\u0411\u0429\u0415\u041d\u0418\u0415, \u0446\u0432\u0435\u0442 \u0438\u043c\u0435\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0440\u043e\u0432\u0435\u043d\u044c, \u0430 \u0434\u0430\u0442\u0430 \u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u043c \u0446\u0432\u0432\u0435\u0442\u043e\u043c \u043a\u043e\u043d\u0441\u043e\u043b\u0438. \u0414\u043b\u044f \u043b\u043e\u0433\u0433\u0435\u0440\u0430 \u0443\u0441\u0442\u0430\u043d\u0430\u0432\u043b\u0438\u0432\u0430\u0435\u043c \u0432\u044b\u0432\u043e\u0434 \u0432 stdout(\u043a\u043e\u043d\u0441\u043e\u043b\u044c \u0432\u044b\u0432\u043e\u0434\u0430), \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0443\u0440\u043e\u0432\u0435\u043d\u044c \u0432\u044b\u0432\u043e\u0434\u0430 &#8212; INFO, \u0430 \u0442\u0430\u043a-\u0436\u0435 \u0432\u044b\u0432\u043e\u0434 \u0432 \u043b\u043e\u0433-\u0444\u0430\u0439\u043b \u0438 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u043c \u044d\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u0415\u0441\u043b\u0438 \u043d\u0435 \u0431\u044b\u043b\u043e \u043e\u0448\u0438\u0431\u043e\u043a \u043f\u0440\u0438 \u044d\u0442\u0438\u0445 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f\u0445 &#8212; \u0432\u043e\u0437\u0440\u0430\u0449\u044f\u0435\u043c \u0443\u0441\u043f\u0435\u0448\u043d\u044b\u0439 \u043f\u0443\u0441\u0442\u043e\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442.<\/p>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0443 \u043d\u0430\u0441 \u0447\u0435\u0440\u0435\u0437 main.rs \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f <a href=\"https:\/\/doc.rust-lang.org\/std\/sync\/mpsc\/\" rel=\"noopener noreferrer nofollow\">\u043a\u0430\u043d\u0430\u043b mpsc<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u0442\u043e\u043a \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430 TCP \u0438 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 network_server_start \u0438\u0437 \u043f\u0430\u043a\u0435\u0442\u0430 network, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u043c\u043d\u043e\u0433\u043e &#171;\u043f\u0443\u0441\u0442\u044b\u0445&#187; \u0444\u0430\u0439\u043b\u043e\u0432, \u043d\u043e \u043e\u0442\u0442\u0443\u0434\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u043b\u0438\u0448\u044c \u043f\u0440\u043e\u0442\u043e\u043a\u043e\u043b, \u0441\u0435\u0440\u0432\u0435\u0440, \u0431\u0443\u0444\u0435\u0440\u044b \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438. \u0421\u0430\u043c \u0441\u0435\u0442\u0435\u0432\u043e\u0439 \u0441\u0435\u0440\u0432\u0435\u0440 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f \u043f\u043e \u043f\u0443\u0442\u0438 src\/network\/server.rs: <\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u0435\u0442\u0435\u0432\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"rust\">use crate::network::handler::{handshaking, status_handler}; use crate::network::network_client::ConnectionType::HANDSHAKING; use crate::network::network_client::NetworkClient; use ahash::AHashMap; use mio::net::TcpListener; use mio::{Events, Interest, Poll, Token}; use std::io; use std::sync::mpsc::Sender; use std::sync::Mutex; use std::time::Duration;  \/\/ Declare global variables lazy_static! {     \/\/ Server need to shut down? (true - yes, needs to shutdown network server).     pub static ref SHUTDOWN_SERVER: Mutex&lt;bool> = Mutex::new(false);     \/\/ Server's works status.     pub static ref NET_SERVER_WORKS: Mutex&lt;bool> = Mutex::new(true); }  \/\/ Server's Token(ID) const SERVER: Token = Token(0);  \/\/ Next Token fn next(current: &amp;mut Token) -> Token {     let next = current.0;     current.0 += 1;     Token(next) }  \/\/ Start a network server pub fn network_server_start(address: String, tx: &amp;Sender&lt;bool>) -><\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-329125","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/329125","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=329125"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/329125\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=329125"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=329125"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=329125"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}