extern crate ozelot;
extern crate getopts;
extern crate rpassword;
use std::{thread, time};
use std::sync::mpsc::{channel, Sender};
use std::process::exit;
use std::io;
use std::env;
use ozelot::{Client, serverbound, mojang, utils};
use ozelot::clientbound::*;
use getopts::Options;
fn main() {
let args: Vec<String> = env::args().collect();
let mut opts = Options::new();
opts.reqopt("u", "username", "your username", "C4K3");
opts.reqopt("h", "host", "the server's hostname", "minecraft.example.com");
opts.optopt("p", "port", "the server's port", "25565");
opts.optflag("", "unauthenticated", "connect unauthenticated instead of authenticated");
let matches = opts.parse(&args[1..]).unwrap();
let username = matches.opt_str("username").expect("unreachable");
let host = matches.opt_str("host").expect("unreachable");
let port = if let Some(x) = matches.opt_str("port") {
x.parse::<u16>().unwrap()
} else {
25565
};
let authenticated: bool = matches.opt_present("unauthenticated") == false;
let mut client = if authenticated {
let password = rpassword::prompt_password_stdout("Enter password: ").unwrap();
let auth = mojang::Authenticate::new(username, password).perform().unwrap();
match Client::connect_authenticated(&host, port, &auth) {
Ok(x) => x,
Err(e) => {
println!("Error connecting to {}:{}: {:?}", host, port, e);
exit(1);
},
}
} else {
match Client::connect_unauthenticated(&host, port, &username) {
Ok(x) => x,
Err(e) => {
println!("Error connecting unauthenticated to {}:{}: {:?}", host, port, e);
exit(1);
},
}
};
let (tx, rx) = channel();
thread::spawn(move || {
read_stdin(tx);
});
'main: loop {
let packets = client.read().unwrap();
for packet in packets {
match packet {
ClientboundPacket::PlayDisconnect(ref p) => {
println!("Got disconnect packet, exiting ...");
println!("Reason: {}", utils::chat_to_str(p.get_reason()).unwrap());
break 'main;
},
ClientboundPacket::ChatMessage(ref p) => {
let msg = utils::chat_to_str(p.get_chat()).unwrap();
println!("{}", msg);
},
_ => (),
}
}
if let Ok(msg) = rx.try_recv() {
let msg = msg.trim_right().to_string();
let chat = serverbound::ChatMessage::new(msg);
client.send(chat).unwrap();
}
thread::sleep(time::Duration::from_millis(50));
}
}
fn read_stdin(tx: Sender<String>) {
loop {
let mut tmp = String::new();
let _: usize = io::stdin().read_line(&mut tmp).unwrap();
tx.send(tmp).unwrap();
}
}