rewrite
This commit is contained in:
@@ -1 +0,0 @@
|
||||
pub const CLOAKS: &[&str] = &["glitch"];
|
||||
@@ -0,0 +1,18 @@
|
||||
pub struct Player {
|
||||
pub uuid: String,
|
||||
pub cloaks: Vec<String>,
|
||||
pub cloak: String,
|
||||
}
|
||||
|
||||
pub struct Database {
|
||||
pub players: mongodb::sync::Collection<Player>,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub fn new(client: &mongodb::sync::Client) -> Self {
|
||||
let db = client.database("saturn");
|
||||
Self {
|
||||
players: db.collection("players"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
use mongodb::sync::{Client, Collection};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub enum Response {
|
||||
Pong,
|
||||
}
|
||||
|
||||
impl Response {
|
||||
pub fn to_string(&self) -> String {
|
||||
match self {
|
||||
Response::Pong => "pong".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
pub struct Player {
|
||||
pub uuid: String,
|
||||
pub cloaks: Vec<String>,
|
||||
}
|
||||
|
||||
pub struct Database {
|
||||
pub players: Collection<Player>,
|
||||
}
|
||||
|
||||
impl Database {
|
||||
pub fn new(client: &Client) -> Self {
|
||||
let db = client.database("saturn");
|
||||
Self {
|
||||
players: db.collection("players"),
|
||||
}
|
||||
}
|
||||
}
|
||||
+32
-56
@@ -1,68 +1,44 @@
|
||||
pub mod assets;
|
||||
pub mod io;
|
||||
use std::{
|
||||
io::{BufRead, BufReader, Write},
|
||||
net::TcpListener,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
pub mod database;
|
||||
pub mod methods;
|
||||
pub mod parser;
|
||||
|
||||
use std::io::{Read, Write};
|
||||
use std::net::{TcpListener, TcpStream};
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
|
||||
use io::Database;
|
||||
use methods::handle_request;
|
||||
use mongodb::sync::Client;
|
||||
|
||||
const MONGO_URI: &str = "mongodb://admin:admin@localhost/";
|
||||
pub mod response;
|
||||
|
||||
fn main() -> std::io::Result<()> {
|
||||
let client = Client::with_uri_str(MONGO_URI).unwrap();
|
||||
let database = Arc::new(Database::new(&client));
|
||||
let listener = TcpListener::bind("127.0.0.1:8080")?;
|
||||
let client = mongodb::sync::Client::with_uri_str("mongodb://admin:admin@localhost/").unwrap();
|
||||
let database = Arc::new(database::Database::new(&client));
|
||||
|
||||
println!("Server listening on port 8080");
|
||||
let listener = TcpListener::bind("127.0.0.1:8080").unwrap();
|
||||
|
||||
for stream in listener.incoming() {
|
||||
match stream {
|
||||
Ok(stream) => {
|
||||
println!("New connection: {}", stream.peer_addr().unwrap());
|
||||
thread::spawn({
|
||||
let database = Arc::clone(&database);
|
||||
move || handle_client(stream, database)
|
||||
});
|
||||
println!("New connection");
|
||||
let database = Arc::clone(&database);
|
||||
|
||||
std::thread::spawn({
|
||||
move || {
|
||||
let mut stream = stream.unwrap();
|
||||
let mut reader = BufReader::new(stream.try_clone().unwrap());
|
||||
let session = methods::Session::new(&mut reader, database).unwrap();
|
||||
|
||||
loop {
|
||||
let mut request_string = String::new();
|
||||
match reader.read_line(&mut request_string).unwrap() {
|
||||
0 => break,
|
||||
_ => {
|
||||
let (method, params) = parser::parse(&request_string).unwrap();
|
||||
let response = session.handle_request(&method, ¶ms);
|
||||
stream.write_all(response.to_string().as_bytes()).unwrap();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
Err(e) => eprintln!("Connection failed: {}", e),
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn handle_client(mut stream: TcpStream, database: Arc<Database>) {
|
||||
let mut buffer = [0; 512];
|
||||
|
||||
loop {
|
||||
match stream.read(&mut buffer) {
|
||||
Ok(0) => break,
|
||||
Ok(n) => {
|
||||
let recv = String::from_utf8_lossy(&buffer[..n]).to_string();
|
||||
match parser::parse(&recv) {
|
||||
Ok((method, params)) => {
|
||||
match handle_request(Arc::clone(&database), method, params) {
|
||||
Ok(response) => {
|
||||
stream.write_all(response.to_string().as_bytes()).unwrap()
|
||||
}
|
||||
Err(e) => eprintln!("Error handling request: {}", e),
|
||||
}
|
||||
}
|
||||
Err(e) => eprintln!("Error parsing request: {}", e),
|
||||
};
|
||||
}
|
||||
Err(e) => {
|
||||
eprintln!("Error reading from client: {}", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
println!("Client disconnected");
|
||||
}
|
||||
|
||||
+34
-10
@@ -1,14 +1,38 @@
|
||||
use std::{collections::HashMap, sync::Arc};
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
io::{self, BufRead, BufReader},
|
||||
net::TcpStream,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use crate::io::{Database, Response};
|
||||
pub struct Session {
|
||||
pub session_id: String,
|
||||
pub database: Arc<crate::database::Database>,
|
||||
}
|
||||
|
||||
pub fn handle_request(
|
||||
database: Arc<Database>,
|
||||
method: String,
|
||||
params: HashMap<String, String>,
|
||||
) -> Result<Response, String> {
|
||||
match method.as_str() {
|
||||
"ping" => Ok(Response::Pong),
|
||||
_ => Err("Invalid request: ".to_string()),
|
||||
impl Session {
|
||||
pub fn new(
|
||||
reader: &mut BufReader<TcpStream>,
|
||||
database: Arc<crate::database::Database>,
|
||||
) -> io::Result<Self> {
|
||||
let mut session_id = String::new();
|
||||
reader.read_line(&mut session_id)?;
|
||||
|
||||
Ok(Self {
|
||||
session_id,
|
||||
database,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn handle_request(
|
||||
&self,
|
||||
method: &str,
|
||||
params: &HashMap<String, String>,
|
||||
) -> crate::response::Response {
|
||||
match method {
|
||||
"ping" => crate::response::Response::Pong,
|
||||
|
||||
_ => crate::response::Response::Error(crate::response::Error::InvalidRequest),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ impl ParamMap for HashMap<String, String> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse(s: &str) -> Result<(String, HashMap<String, String>), String> {
|
||||
pub fn parse(s: &str) -> std::io::Result<(String, HashMap<String, String>)> {
|
||||
let mut parts = s.split("@");
|
||||
|
||||
let method = parts.next().unwrap().trim().to_lowercase();
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Response {
|
||||
Pong,
|
||||
Error(Error),
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Response {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Response::Pong => write!(f, "Pong"),
|
||||
Response::Error(error) => write!(f, "!{}", error),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Error {
|
||||
InvalidRequest,
|
||||
InvalidMethod,
|
||||
InvalidParameter,
|
||||
ParameterNotFound,
|
||||
InvalidSessionToken,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Error::InvalidRequest => write!(f, "Invalid request"),
|
||||
Error::InvalidMethod => write!(f, "Invalid method"),
|
||||
Error::InvalidParameter => write!(f, "Invalid parameter"),
|
||||
Error::ParameterNotFound => write!(f, "Parameter not found"),
|
||||
Error::InvalidSessionToken => write!(f, "Invalid session token"),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user