2016-03-16 14:25:35 -04:00
|
|
|
// Copyright 2016 Matthew Collins
|
2015-09-28 18:37:14 -04:00
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
//
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
//
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
// limitations under the License.
|
|
|
|
|
2016-03-20 16:17:21 -04:00
|
|
|
use std::sync::{Arc, Mutex};
|
2015-09-28 18:37:14 -04:00
|
|
|
|
2016-03-20 19:43:31 -04:00
|
|
|
use std::cell::Cell;
|
|
|
|
use std::rc::Rc;
|
|
|
|
use std::sync::mpsc;
|
|
|
|
use std::thread;
|
|
|
|
|
|
|
|
use rand::{self, Rng};
|
|
|
|
|
2015-09-27 14:38:58 -04:00
|
|
|
use ui;
|
|
|
|
use render;
|
2016-03-20 16:17:21 -04:00
|
|
|
use console;
|
2016-03-20 19:43:31 -04:00
|
|
|
use protocol;
|
|
|
|
use protocol::mojang;
|
|
|
|
use auth;
|
2015-09-27 14:38:58 -04:00
|
|
|
|
|
|
|
pub struct Login {
|
2015-10-07 14:36:59 -04:00
|
|
|
elements: Option<UIElements>,
|
2016-03-20 16:17:21 -04:00
|
|
|
console: Arc<Mutex<console::Console>>,
|
2015-09-27 14:38:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
struct UIElements {
|
2015-10-07 14:36:59 -04:00
|
|
|
logo: ui::logo::Logo,
|
|
|
|
elements: ui::Collection,
|
2016-03-20 19:43:31 -04:00
|
|
|
|
|
|
|
login_btn: ui::ElementRef<ui::Button>,
|
|
|
|
login_btn_text: ui::ElementRef<ui::Text>,
|
|
|
|
login_error: ui::ElementRef<ui::Text>,
|
|
|
|
username_txt: ui::ElementRef<ui::TextBox>,
|
|
|
|
password_txt: ui::ElementRef<ui::TextBox>,
|
|
|
|
try_login: Rc<Cell<bool>>,
|
|
|
|
refresh: bool,
|
|
|
|
login_res: Option<mpsc::Receiver<Result<mojang::Profile, protocol::Error>>>,
|
|
|
|
|
|
|
|
profile: mojang::Profile,
|
2015-09-27 14:38:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
impl Login {
|
2016-03-20 16:17:21 -04:00
|
|
|
pub fn new(console: Arc<Mutex<console::Console>>) -> Login {
|
|
|
|
Login { elements: None, console: console }
|
2015-10-07 14:36:59 -04:00
|
|
|
}
|
2015-09-27 14:38:58 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl super::Screen for Login {
|
2015-10-07 14:36:59 -04:00
|
|
|
fn on_active(&mut self, renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
|
|
|
let logo = ui::logo::Logo::new(renderer.resources.clone(), renderer, ui_container);
|
|
|
|
let mut elements = ui::Collection::new();
|
2015-09-27 14:38:58 -04:00
|
|
|
|
2016-03-20 19:43:31 -04:00
|
|
|
let try_login = Rc::new(Cell::new(false));
|
|
|
|
|
2016-03-20 16:17:21 -04:00
|
|
|
// Login
|
|
|
|
let (mut login, mut txt) = super::new_button_text(renderer, "Login", 0.0, 100.0, 400.0, 40.0);
|
2015-10-07 14:36:59 -04:00
|
|
|
login.set_v_attach(ui::VAttach::Middle);
|
|
|
|
login.set_h_attach(ui::HAttach::Center);
|
|
|
|
let re = ui_container.add(login);
|
|
|
|
txt.set_parent(&re);
|
|
|
|
let tre = ui_container.add(txt);
|
2016-03-20 19:43:31 -04:00
|
|
|
let tl = try_login.clone();
|
2015-10-07 14:36:59 -04:00
|
|
|
super::button_action(ui_container,
|
|
|
|
re.clone(),
|
|
|
|
Some(tre.clone()),
|
2016-03-20 19:43:31 -04:00
|
|
|
move |_, _| {
|
|
|
|
tl.set(true);
|
|
|
|
});
|
|
|
|
let login_btn = elements.add(re);
|
|
|
|
let login_btn_text = elements.add(tre);
|
|
|
|
|
|
|
|
// Login Error
|
|
|
|
let mut login_error = ui::Text::new(renderer, "", 0.0, 150.0, 255, 50, 50);
|
|
|
|
login_error.set_v_attach(ui::VAttach::Middle);
|
|
|
|
login_error.set_h_attach(ui::HAttach::Center);
|
|
|
|
let login_error = elements.add(ui_container.add(login_error));
|
2015-09-27 17:18:49 -04:00
|
|
|
|
2016-03-20 16:17:21 -04:00
|
|
|
// Username
|
|
|
|
let mut username = ui::TextBox::new(renderer, "", 0.0, -20.0, 400.0, 40.0);
|
|
|
|
username.set_v_attach(ui::VAttach::Middle);
|
|
|
|
username.set_h_attach(ui::HAttach::Center);
|
|
|
|
username.add_submit_func(|_, ui| {
|
|
|
|
ui.cycle_focus();
|
|
|
|
});
|
|
|
|
let ure = ui_container.add(username);
|
|
|
|
let mut username_label = ui::Text::new(renderer, "Username/Email:", 0.0, -18.0, 255, 255, 255);
|
|
|
|
username_label.set_parent(&ure);
|
2016-03-20 19:43:31 -04:00
|
|
|
let username_txt = elements.add(ure);
|
2016-03-20 16:17:21 -04:00
|
|
|
elements.add(ui_container.add(username_label));
|
|
|
|
|
|
|
|
// Password
|
|
|
|
let mut password = ui::TextBox::new(renderer, "", 0.0, 40.0, 400.0, 40.0);
|
|
|
|
password.set_v_attach(ui::VAttach::Middle);
|
|
|
|
password.set_h_attach(ui::HAttach::Center);
|
|
|
|
password.set_password(true);
|
2016-03-20 19:43:31 -04:00
|
|
|
let tl = try_login.clone();
|
|
|
|
password.add_submit_func(move |_, _| {
|
|
|
|
tl.set(true);
|
2016-03-20 16:17:21 -04:00
|
|
|
});
|
|
|
|
let pre = ui_container.add(password);
|
|
|
|
let mut password_label = ui::Text::new(renderer, "Password:", 0.0, -18.0, 255, 255, 255);
|
|
|
|
password_label.set_parent(&pre);
|
2016-03-20 19:43:31 -04:00
|
|
|
let password_txt = elements.add(pre);
|
2016-03-20 16:17:21 -04:00
|
|
|
elements.add(ui_container.add(password_label));
|
|
|
|
|
|
|
|
// Disclaimer
|
2015-10-07 14:36:59 -04:00
|
|
|
let mut warn = ui::Text::new(renderer,
|
|
|
|
"Not affiliated with Mojang/Minecraft",
|
|
|
|
5.0,
|
|
|
|
5.0,
|
|
|
|
255,
|
|
|
|
200,
|
|
|
|
200);
|
|
|
|
warn.set_v_attach(ui::VAttach::Bottom);
|
|
|
|
warn.set_h_attach(ui::HAttach::Right);
|
|
|
|
elements.add(ui_container.add(warn));
|
2015-09-27 14:38:58 -04:00
|
|
|
|
2016-03-20 19:43:31 -04:00
|
|
|
let console = self.console.lock().unwrap();
|
|
|
|
let profile = mojang::Profile {
|
|
|
|
username: console.get(auth::CL_USERNAME).clone(),
|
|
|
|
id: console.get(auth::CL_UUID).clone(),
|
|
|
|
access_token: console.get(auth::AUTH_TOKEN).clone(),
|
|
|
|
};
|
|
|
|
let refresh = profile.is_complete();
|
|
|
|
try_login.set(refresh);
|
|
|
|
|
2015-10-07 14:36:59 -04:00
|
|
|
self.elements = Some(UIElements {
|
|
|
|
logo: logo,
|
|
|
|
elements: elements,
|
2016-03-20 19:43:31 -04:00
|
|
|
profile: profile,
|
|
|
|
login_btn: login_btn,
|
|
|
|
login_btn_text: login_btn_text,
|
|
|
|
login_error: login_error,
|
|
|
|
try_login: try_login,
|
|
|
|
refresh: refresh,
|
|
|
|
login_res: None,
|
|
|
|
|
|
|
|
username_txt: username_txt,
|
|
|
|
password_txt: password_txt,
|
2015-10-07 14:36:59 -04:00
|
|
|
});
|
|
|
|
}
|
|
|
|
fn on_deactive(&mut self, _renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
2016-03-20 16:17:21 -04:00
|
|
|
// Clean up
|
2015-10-07 14:36:59 -04:00
|
|
|
{
|
|
|
|
let elements = self.elements.as_mut().unwrap();
|
|
|
|
elements.logo.remove(ui_container);
|
|
|
|
elements.elements.remove_all(ui_container);
|
|
|
|
}
|
|
|
|
self.elements = None
|
|
|
|
}
|
2015-09-27 14:38:58 -04:00
|
|
|
|
2015-10-07 14:36:59 -04:00
|
|
|
fn tick(&mut self,
|
2016-03-18 11:19:21 -04:00
|
|
|
_delta: f64,
|
2015-10-07 14:36:59 -04:00
|
|
|
renderer: &mut render::Renderer,
|
2016-03-20 19:43:31 -04:00
|
|
|
ui_container: &mut ui::Container) -> Option<Box<super::Screen>> {
|
2015-10-07 14:36:59 -04:00
|
|
|
let elements = self.elements.as_mut().unwrap();
|
2015-09-27 14:38:58 -04:00
|
|
|
|
2016-03-20 19:43:31 -04:00
|
|
|
if elements.try_login.get() && elements.login_res.is_none() {
|
|
|
|
elements.try_login.set(false);
|
|
|
|
let (tx, rx) = mpsc::channel();
|
|
|
|
elements.login_res = Some(rx);
|
|
|
|
{
|
|
|
|
let btn = ui_container.get_mut(&elements.login_btn);
|
|
|
|
btn.set_disabled(true);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let txt = ui_container.get_mut(&elements.login_btn_text);
|
|
|
|
txt.set_text(renderer, "Logging in...");
|
|
|
|
}
|
|
|
|
let mut console = self.console.lock().unwrap();
|
|
|
|
let mut client_token = console.get(auth::AUTH_CLIENT_TOKEN).clone();
|
|
|
|
if client_token.is_empty() {
|
|
|
|
client_token = rand::thread_rng().gen_ascii_chars().take(20).collect::<String>();
|
|
|
|
console.set(auth::AUTH_CLIENT_TOKEN, client_token);
|
|
|
|
}
|
|
|
|
let client_token = console.get(auth::AUTH_CLIENT_TOKEN).clone();
|
|
|
|
let username = {
|
|
|
|
let txt = ui_container.get(&elements.username_txt);
|
|
|
|
txt.get_input()
|
|
|
|
};
|
|
|
|
let password = {
|
|
|
|
let txt = ui_container.get(&elements.password_txt);
|
|
|
|
txt.get_input()
|
|
|
|
};
|
|
|
|
let refresh = elements.refresh;
|
|
|
|
let profile = elements.profile.clone();
|
|
|
|
thread::spawn(move || {
|
|
|
|
if refresh {
|
|
|
|
tx.send(profile.refresh(&client_token)).unwrap();
|
|
|
|
} else {
|
|
|
|
tx.send(mojang::Profile::login(&username, &password, &client_token)).unwrap();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
let mut done = false;
|
|
|
|
if let Some(rx) = elements.login_res.as_ref() {
|
|
|
|
if let Ok(res) = rx.try_recv() {
|
|
|
|
done = true;
|
|
|
|
{
|
|
|
|
let btn = ui_container.get_mut(&elements.login_btn);
|
|
|
|
btn.set_disabled(false);
|
|
|
|
}
|
|
|
|
{
|
|
|
|
let txt = ui_container.get_mut(&elements.login_btn_text);
|
|
|
|
txt.set_text(renderer, "Login");
|
|
|
|
}
|
|
|
|
match res {
|
|
|
|
Ok(val) => {
|
|
|
|
let mut console = self.console.lock().unwrap();
|
|
|
|
console.set(auth::CL_USERNAME, val.username.clone());
|
|
|
|
console.set(auth::CL_UUID, val.id.clone());
|
|
|
|
console.set(auth::AUTH_TOKEN, val.access_token.clone());
|
|
|
|
elements.profile = val;
|
|
|
|
return Some(Box::new(super::ServerList::new(None)));
|
|
|
|
},
|
|
|
|
Err(err) => {
|
|
|
|
let login_error = ui_container.get_mut(&elements.login_error);
|
|
|
|
login_error.set_text(renderer, &format!("{}", err));
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if done {
|
|
|
|
elements.login_res = None;
|
|
|
|
}
|
|
|
|
|
2015-10-07 14:36:59 -04:00
|
|
|
elements.logo.tick(renderer, ui_container);
|
2016-03-20 19:43:31 -04:00
|
|
|
None
|
2015-10-07 14:36:59 -04:00
|
|
|
}
|
|
|
|
}
|