Skip to content

Commit 08bfd50

Browse files
feat: Added logging setting
1 parent 65b6a5c commit 08bfd50

File tree

7 files changed

+159
-45
lines changed

7 files changed

+159
-45
lines changed

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
name = "mc-oauth"
33
version = "0.1.9"
44
edition = "2021"
5+
authors = ["AndcoolSystems"]
6+
license = "MIT"
57

68
[dependencies]
79
tokio = { version = "1.43.0", features = ["full"] }

README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@ After the project is fully built, the binary file for your OS will be available
6464
For the server to work, create a `config.toml` file in the same directory as the executable with the following contents:
6565

6666
```toml
67+
[global]
68+
# Server logging level. Possible values:
69+
# debug, info, warn, error, trace
70+
logging_level = "info"
71+
6772
[api]
6873
# API address
6974
addr = "0.0.0.0"

config.example.toml

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,85 @@
1+
[global]
2+
# Server logging level. Possible values:
3+
# debug, info, warn, error, trace
4+
logging_level = "info"
5+
16
[api]
7+
# API address
28
addr = "0.0.0.0"
9+
10+
# API port
311
port = 8008
12+
13+
# Life time of assigned code
414
code_life_time = 300
15+
16+
# Length of generated code
517
code_length = 6
618

719
[server]
20+
# Minecraft server address
821
addr = "0.0.0.0"
22+
23+
# Minecraft server port
924
port = 25565
10-
timeout = 20
11-
server_ip = "localhost" # Change or remove before production use!
12-
support_1_19 = false # READ: https://github.com/Andcool-Systems/mc-oauth-rs/issues/1
25+
26+
# Server connection timeout
27+
# Sets the maximum time a client can stay connected to the server. Used to prevent idle or junk connections.
28+
timeout = 10
29+
30+
# [Optional] This parameter defines the server host to which the clients connect.
31+
# This is necessary to prevent proxy bypass or spoofing.
32+
server_ip = "localhost"
33+
34+
# Enable partial support of 1.19-1.19.2 clients
35+
# https://github.com/Andcool-Systems/mc-oauth-rs/issues/1
36+
support_1_19 = false
1337

1438
[server.config]
39+
# Minecraft server name (used for internal auth; can be empty)
1540
server_name = "mc-oauth-rs"
41+
42+
# Protocol version (`0` for auto)
43+
# If set to 0, the protocol version that the client uses will be applied.
1644
protocol = 0
45+
46+
# Minecraft version string (In fact, it's just a stub)
1747
version = "1.21"
48+
49+
# Session Auth URL
50+
# `{{NAME}}` in string will be replaced by the client nickname
51+
# `{{HASH}}` will be replaced by the generated client hash
1852
auth_url = "https://sessionserver.mojang.com/session/minecraft/hasJoined?username={{NAME}}&serverId={{HASH}}"
1953

2054
[server.status]
55+
# Server description (you can use MOTD)
2156
description = "§6mc-oauth.andcool.ru"
57+
58+
# Max players count, displayed in server list
2259
players_max = 0
60+
61+
# Online players count, displayed in server list
2362
players_online = 0
63+
64+
# Path to the server icon (can be empty)
65+
# Should be in .png format and 64x64 pixels in size
2466
icon_path = "server_icon.png"
2567

2668
[messages]
69+
# Message for successful auth
70+
# `{{NAME}}` will be replaced by the client nickname
71+
# `{{UUID}}` will be replaced by the client UUID
72+
# `{{CODE}}` will be replaced by the generated code
2773
success = "Hello, §6{{NAME}}§r! Your code is: §a{{CODE}}"
74+
75+
# Message for Mojang API error
2876
bad_session = "§cFailed to login: Invalid session (Try restarting your game and the launcher)"
77+
78+
# Message for bad server address (`server_ip` setting)
2979
using_proxy = "§cYou are using a proxy!"
80+
81+
# Message for internal server error
3082
internal_error = "§cSorry, internal server error occurred"
83+
84+
# Message for unsupported client version
3185
unsupported_client_version = "§cYou are using unsupported version of client!"

src/config/types.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ use serde::Deserialize;
22

33
#[derive(Deserialize, Debug)]
44
pub struct Config {
5+
/// Global APP config
6+
pub global: GlobalConfig,
7+
58
/// API config
69
pub api: API,
710

@@ -16,6 +19,12 @@ pub struct Config {
1619
pub image: Option<String>,
1720
}
1821

22+
#[derive(Deserialize, Debug)]
23+
pub struct GlobalConfig {
24+
/// Logging level
25+
pub logging_level: String,
26+
}
27+
1928
#[derive(Deserialize, Debug)]
2029
pub struct API {
2130
/// API address

src/logging.rs

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
use tracing::{subscriber::set_global_default, Level};
2+
use tracing_subscriber::{
3+
filter::LevelFilter,
4+
fmt::format::{Compact, DefaultFields, Format},
5+
prelude::*,
6+
reload::{self, Handle},
7+
FmtSubscriber,
8+
};
9+
10+
type ReloadHandle = Handle<LevelFilter, FmtSubscriber<DefaultFields, Format<Compact, ()>>>;
11+
12+
/**
13+
Init logger with provided level
14+
*/
15+
pub fn init_logger(initial_level: Level) -> ReloadHandle {
16+
let filter = LevelFilter::from_level(initial_level);
17+
let (filter_layer, reload_handle) = reload::Layer::new(filter);
18+
19+
let subscriber = FmtSubscriber::builder()
20+
.with_max_level(Level::TRACE)
21+
.compact()
22+
.without_time()
23+
.finish()
24+
.with(filter_layer);
25+
26+
set_global_default(subscriber).expect("Failed to set global default subscriber");
27+
28+
reload_handle
29+
}
30+
31+
/**
32+
Set logging level for existing logger
33+
*/
34+
pub fn set_log_level(handle: ReloadHandle, level: tracing::Level) {
35+
handle
36+
.modify(|filter| *filter = LevelFilter::from_level(level))
37+
.expect("Failed to change log level");
38+
}
39+
40+
/**
41+
Get log level from string
42+
*/
43+
pub fn str_to_log_level(level: &str) -> Option<Level> {
44+
match level.to_lowercase().as_str() {
45+
"trace" => Some(Level::TRACE),
46+
"debug" => Some(Level::DEBUG),
47+
"info" => Some(Level::INFO),
48+
"warn" => Some(Level::WARN),
49+
"error" => Some(Level::ERROR),
50+
_ => None,
51+
}
52+
}

src/main.rs

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ mod config;
1010
mod encryption;
1111
mod generators;
1212
mod handlers;
13+
mod logging;
1314
mod map;
1415
mod mojang;
1516
mod packets;
@@ -28,30 +29,25 @@ use generators::generate_key_pair;
2829
use server::MinecraftServer;
2930
use tokio::{net::TcpListener, sync::Notify};
3031
use tokio::{signal, time::timeout};
31-
use tracing::{error, info};
32-
33-
fn init_logger(level: tracing::Level) {
34-
use tracing_subscriber::FmtSubscriber;
35-
36-
tracing::subscriber::set_global_default(
37-
FmtSubscriber::builder()
38-
.compact()
39-
.with_max_level(level)
40-
.without_time()
41-
.finish(),
42-
)
43-
.expect("Fail to set global default subscriber");
44-
}
32+
use tracing::{debug, error, info, Level};
33+
34+
use crate::logging::{init_logger, set_log_level, str_to_log_level};
4535

4636
#[tokio::main]
4737
async fn main() -> anyhow::Result<()> {
4838
// Set up logger
49-
init_logger(tracing::Level::DEBUG);
39+
let reload_handle = init_logger(tracing::Level::DEBUG);
5040

5141
// Load config from file
5242
config::load("config.toml").await?;
5343
let config = config::get_config().await;
5444

45+
// Set logging level from config
46+
set_log_level(
47+
reload_handle,
48+
str_to_log_level(&config.global.logging_level).unwrap_or(Level::INFO),
49+
);
50+
5551
// Generate key pair
5652
let keys = Arc::new(generate_key_pair());
5753
map::init_map();
@@ -105,10 +101,18 @@ async fn main() -> anyhow::Result<()> {
105101
let timeout_duration = Duration::from_secs(config.server.timeout);
106102
tokio::spawn(async move {
107103
// Setting client timeout
108-
timeout(
109-
timeout_duration,
110-
client.run()
111-
).await.unwrap_or_else(|_| {error!("Connection from {} has been timed out", addr);})
104+
match timeout(timeout_duration, client.run()).await {
105+
Ok(Ok(_)) => {
106+
debug!("Connection from {} closed successfully", addr)
107+
}
108+
Ok(Err(e)) => {
109+
let _ = client
110+
.send_disconnect(config.messages.internal_error.clone())
111+
.await;
112+
error!("Internal error occurred: {}", e)
113+
}
114+
Err(e) => error!("Connection from {} has been timed out ({})", addr, e),
115+
}
112116
});
113117
},
114118
Err(e) => {

src/server.rs

Lines changed: 11 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use aes::Aes128;
99
use anyhow::{anyhow, Result};
1010
use bytes::{Buf, BufMut, BytesMut};
1111
use cfb8::Encryptor;
12-
use std::{net::SocketAddr, sync::Arc, time::Duration};
13-
use tokio::net::TcpStream;
12+
use std::{sync::Arc, time::Duration};
13+
use tokio::{io, net::TcpStream};
1414
use tracing::{debug, error, info};
1515
use uuid::Uuid;
1616

@@ -31,11 +31,10 @@ pub struct Session {
3131
pub secret: Option<Vec<u8>>, // Shared secret,
3232
pub verify_token: [u8; 4],
3333
pub cipher: Option<Encryptor<Aes128>>,
34-
pub addr: SocketAddr,
3534
}
3635

3736
impl Session {
38-
pub async fn new(addr: SocketAddr) -> Self {
37+
pub async fn new() -> Self {
3938
let config = get_config().await;
4039

4140
Self {
@@ -47,7 +46,6 @@ impl Session {
4746
secret: None,
4847
verify_token: generate_verify_token(),
4948
cipher: None,
50-
addr,
5149
}
5250
}
5351
}
@@ -63,30 +61,15 @@ pub struct MinecraftServer {
6361
impl MinecraftServer {
6462
pub async fn new(stream: TcpStream, keys: Arc<rsa::RsaPrivateKey>) -> Result<Self> {
6563
Ok(Self {
66-
session: Session::new(stream.peer_addr()?).await,
64+
session: Session::new().await,
6765
buffer: BytesMut::new(),
6866
config: get_config().await,
6967
stream,
7068
keys,
7169
})
7270
}
7371

74-
pub async fn run(&mut self) {
75-
match self._run().await {
76-
Ok(_) => info!(
77-
"Connection from {:?} closed successfully",
78-
self.session.addr
79-
),
80-
Err(e) => {
81-
let _ = self
82-
.send_disconnect(self.config.messages.internal_error.clone())
83-
.await;
84-
error!("Internal error occurred: {}", e)
85-
}
86-
}
87-
}
88-
89-
async fn _run(&mut self) -> Result<()> {
72+
pub async fn run(&mut self) -> Result<()> {
9073
loop {
9174
self.stream.readable().await?;
9275
let mut temp_buf = vec![0; 1024];
@@ -100,7 +83,12 @@ impl MinecraftServer {
10083
self.buffer.put_slice(&temp_buf[..n]);
10184
self.handle_packet().await?;
10285
}
103-
Err(_) => {}
86+
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {
87+
continue;
88+
}
89+
Err(e) => {
90+
error!("Read error: {}", e)
91+
}
10492
}
10593
self.buffer.clear();
10694
}

0 commit comments

Comments
 (0)