Initial work on connecting to servers
This commit is contained in:
parent
189c063f67
commit
fd4df88c32
|
@ -2,8 +2,8 @@
|
|||
name = "steven_openssl"
|
||||
version = "0.0.1"
|
||||
dependencies = [
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"openssl-sys 0.7.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -16,11 +16,10 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.13"
|
||||
name = "gdi32-sys"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"advapi32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -29,6 +28,11 @@ name = "libc"
|
|||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libressl-pnacl-sys"
|
||||
version = "2.1.6"
|
||||
|
@ -39,13 +43,14 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.6.5"
|
||||
version = "0.7.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"gcc 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"gdi32-sys 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libc 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"libressl-pnacl-sys 2.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pkg-config 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"user32-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -79,6 +84,15 @@ dependencies = [
|
|||
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "user32-sys"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.3"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#![feature(unique)]
|
||||
#![allow(dead_code)]
|
||||
extern crate libc;
|
||||
use std::mem;
|
||||
|
@ -54,7 +55,7 @@ extern {
|
|||
}
|
||||
|
||||
pub struct EVPCipher {
|
||||
internal: *mut EVP_CIPHER_CTX,
|
||||
internal: ptr::Unique<EVP_CIPHER_CTX>,
|
||||
|
||||
block_size: usize,
|
||||
}
|
||||
|
@ -62,17 +63,17 @@ pub struct EVPCipher {
|
|||
impl EVPCipher {
|
||||
pub fn new(key: &Vec<u8>, iv: &Vec<u8>, decrypt: bool) -> EVPCipher {
|
||||
unsafe {
|
||||
let e = EVPCipher {
|
||||
internal: EVP_CIPHER_CTX_new(),
|
||||
let mut e = EVPCipher {
|
||||
internal: ptr::Unique::new(EVP_CIPHER_CTX_new()),
|
||||
block_size: EVP_CIPHER_block_size(EVP_aes_128_cfb8()) as usize,
|
||||
};
|
||||
EVP_CIPHER_CTX_init(e.internal);
|
||||
EVP_CIPHER_CTX_init(e.internal.get_mut());
|
||||
if decrypt {
|
||||
if EVP_DecryptInit_ex(e.internal, EVP_aes_128_cfb8(), ptr::null_mut(), key.as_ptr(), iv.as_ptr()) == 0 {
|
||||
if EVP_DecryptInit_ex(e.internal.get_mut(), EVP_aes_128_cfb8(), ptr::null_mut(), key.as_ptr(), iv.as_ptr()) == 0 {
|
||||
panic!("Init error");
|
||||
}
|
||||
} else {
|
||||
if EVP_EncryptInit_ex(e.internal, EVP_aes_128_cfb8(), ptr::null_mut(), key.as_ptr(), iv.as_ptr()) == 0 {
|
||||
if EVP_EncryptInit_ex(e.internal.get_mut(), EVP_aes_128_cfb8(), ptr::null_mut(), key.as_ptr(), iv.as_ptr()) == 0 {
|
||||
panic!("Init error");
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +85,7 @@ impl EVPCipher {
|
|||
unsafe {
|
||||
let mut out = Vec::with_capacity(data.len());
|
||||
let mut out_len: libc::c_int = 0;
|
||||
if EVP_DecryptUpdate(self.internal, out.as_mut_ptr(), &mut out_len, data.as_ptr(), data.len() as libc::c_int) == 0 {
|
||||
if EVP_DecryptUpdate(self.internal.get_mut(), out.as_mut_ptr(), &mut out_len, data.as_ptr(), data.len() as libc::c_int) == 0 {
|
||||
panic!("Decrypt error")
|
||||
}
|
||||
out.set_len(out_len as usize);
|
||||
|
@ -96,7 +97,7 @@ impl EVPCipher {
|
|||
unsafe {
|
||||
let mut out = Vec::with_capacity(data.len());
|
||||
let mut out_len: libc::c_int = 0;
|
||||
if EVP_EncryptUpdate(self.internal, out.as_mut_ptr(), &mut out_len, data.as_ptr(), data.len() as libc::c_int) == 0 {
|
||||
if EVP_EncryptUpdate(self.internal.get_mut(), out.as_mut_ptr(), &mut out_len, data.as_ptr(), data.len() as libc::c_int) == 0 {
|
||||
panic!("Encrypt error")
|
||||
}
|
||||
out.set_len(out_len as usize);
|
||||
|
@ -109,8 +110,8 @@ impl EVPCipher {
|
|||
impl Drop for EVPCipher {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
EVP_CIPHER_CTX_cleanup(self.internal);
|
||||
EVP_CIPHER_CTX_free(self.internal);
|
||||
EVP_CIPHER_CTX_cleanup(self.internal.get_mut());
|
||||
EVP_CIPHER_CTX_free(self.internal.get_mut());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
49
src/main.rs
49
src/main.rs
|
@ -52,6 +52,8 @@ pub mod chunk_builder;
|
|||
|
||||
use std::sync::{Arc, RwLock, Mutex};
|
||||
use std::marker::PhantomData;
|
||||
use std::thread;
|
||||
use std::sync::mpsc;
|
||||
|
||||
const CL_BRAND: console::CVar<String> = console::CVar {
|
||||
ty: PhantomData,
|
||||
|
@ -73,6 +75,51 @@ pub struct Game {
|
|||
|
||||
server: server::Server,
|
||||
chunk_builder: chunk_builder::ChunkBuilder,
|
||||
|
||||
connect_reply: Option<mpsc::Receiver<Result<server::Server, protocol::Error>>>,
|
||||
}
|
||||
|
||||
impl Game {
|
||||
pub fn connect_to(&mut self, address: &str) {
|
||||
let (tx, rx) = mpsc::channel();
|
||||
self.connect_reply = Some(rx);
|
||||
let address = address.to_owned();
|
||||
let resources = self.resource_manager.clone();
|
||||
thread::spawn(move || {
|
||||
tx.send(server::Server::connect(resources, &address)).unwrap();
|
||||
});
|
||||
}
|
||||
|
||||
pub fn tick(&mut self) {
|
||||
let mut clear_reply = false;
|
||||
if let Some(ref recv) = self.connect_reply {
|
||||
if let Ok(server) = recv.try_recv() {
|
||||
clear_reply = true;
|
||||
match server {
|
||||
Ok(val) => {
|
||||
self.screen_sys.pop_screen();
|
||||
self.server = val;
|
||||
},
|
||||
Err(err) => {
|
||||
let msg = match err {
|
||||
protocol::Error::Disconnect(val) => val,
|
||||
err => {
|
||||
let mut msg = format::TextComponent::new(&format!("{}", err));
|
||||
msg.modifier.color = Some(format::Color::Red);
|
||||
format::Component::Text(msg)
|
||||
},
|
||||
};
|
||||
self.screen_sys.replace_screen(Box::new(screen::ServerList::new(
|
||||
Some(msg)
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if clear_reply {
|
||||
self.connect_reply = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
@ -135,6 +182,7 @@ fn main() {
|
|||
should_close: false,
|
||||
mouse_pos: (0, 0),
|
||||
chunk_builder: chunk_builder::ChunkBuilder::new(textures),
|
||||
connect_reply: None,
|
||||
};
|
||||
|
||||
while !game.should_close {
|
||||
|
@ -157,6 +205,7 @@ fn main() {
|
|||
game.renderer.camera.yaw = 0.0;
|
||||
}
|
||||
|
||||
game.tick();
|
||||
game.server.tick();
|
||||
|
||||
game.chunk_builder.tick(&mut game.server.world, &mut game.renderer);
|
||||
|
|
|
@ -631,6 +631,7 @@ pub enum State {
|
|||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
Err(String),
|
||||
Disconnect(format::Component),
|
||||
IOError(io::Error),
|
||||
}
|
||||
|
||||
|
@ -644,6 +645,7 @@ impl ::std::error::Error for Error {
|
|||
fn description(&self) -> &str {
|
||||
match *self {
|
||||
Error::Err(ref val) => &val[..],
|
||||
Error::Disconnect(_) => "Disconnect",
|
||||
Error::IOError(ref e) => e.description(),
|
||||
}
|
||||
}
|
||||
|
@ -653,6 +655,7 @@ impl ::std::fmt::Display for Error {
|
|||
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
|
||||
match *self {
|
||||
Error::Err(ref val) => write!(f, "protocol error: {}", val),
|
||||
Error::Disconnect(ref val) => write!(f, "{}", val),
|
||||
Error::IOError(ref e) => e.fmt(f),
|
||||
}
|
||||
}
|
||||
|
@ -660,10 +663,10 @@ impl ::std::fmt::Display for Error {
|
|||
|
||||
pub struct Conn {
|
||||
stream: TcpStream,
|
||||
host: String,
|
||||
port: u16,
|
||||
pub host: String,
|
||||
pub port: u16,
|
||||
direction: Direction,
|
||||
state: State,
|
||||
pub state: State,
|
||||
|
||||
cipher: Option<openssl::EVPCipher>,
|
||||
|
||||
|
|
|
@ -317,6 +317,10 @@ impl Renderer {
|
|||
self.ui.tick(width, height);
|
||||
}
|
||||
|
||||
pub fn clear_chunks(&mut self) {
|
||||
self.chunks.clear();
|
||||
}
|
||||
|
||||
fn ensure_element_buffer(&mut self, size: usize) {
|
||||
if self.element_buffer_size < size {
|
||||
let (data, ty) = self::generate_element_buffer(size);
|
||||
|
|
|
@ -0,0 +1,101 @@
|
|||
// Copyright 2016 Matthew Collins
|
||||
//
|
||||
// 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.
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
use ui;
|
||||
use render;
|
||||
use format::{self, Component, TextComponent};
|
||||
|
||||
pub struct Connecting {
|
||||
elements: Option<UIElements>,
|
||||
target: String,
|
||||
}
|
||||
|
||||
struct UIElements {
|
||||
logo: ui::logo::Logo,
|
||||
elements: ui::Collection,
|
||||
}
|
||||
|
||||
|
||||
impl Connecting {
|
||||
pub fn new(target: &str) -> Connecting {
|
||||
Connecting {
|
||||
elements: None,
|
||||
target: target.to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl super::Screen for Connecting {
|
||||
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();
|
||||
|
||||
let mut connect_msg = ui::Formatted::new(
|
||||
renderer,
|
||||
Component::Text(TextComponent::new("Connecting to")),
|
||||
0.0, -16.0
|
||||
);
|
||||
connect_msg.set_v_attach(ui::VAttach::Middle);
|
||||
connect_msg.set_h_attach(ui::HAttach::Center);
|
||||
elements.add(ui_container.add(connect_msg));
|
||||
|
||||
let mut msg = TextComponent::new(&self.target);
|
||||
msg.modifier.color = Some(format::Color::Yellow);
|
||||
let mut server_msg = ui::Formatted::new(
|
||||
renderer,
|
||||
Component::Text(msg),
|
||||
0.0, 16.0
|
||||
);
|
||||
server_msg.set_v_attach(ui::VAttach::Middle);
|
||||
server_msg.set_h_attach(ui::HAttach::Center);
|
||||
elements.add(ui_container.add(server_msg));
|
||||
|
||||
// Disclaimer
|
||||
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));
|
||||
|
||||
self.elements = Some(UIElements {
|
||||
logo: logo,
|
||||
elements: elements,
|
||||
});
|
||||
}
|
||||
fn on_deactive(&mut self, _renderer: &mut render::Renderer, ui_container: &mut ui::Container) {
|
||||
// Clean up
|
||||
{
|
||||
let elements = self.elements.as_mut().unwrap();
|
||||
elements.logo.remove(ui_container);
|
||||
elements.elements.remove_all(ui_container);
|
||||
}
|
||||
self.elements = None
|
||||
}
|
||||
|
||||
fn tick(&mut self,
|
||||
_delta: f64,
|
||||
renderer: &mut render::Renderer,
|
||||
ui_container: &mut ui::Container) {
|
||||
let elements = self.elements.as_mut().unwrap();
|
||||
|
||||
elements.logo.tick(renderer, ui_container);
|
||||
}
|
||||
}
|
|
@ -16,6 +16,7 @@ mod server_list;
|
|||
pub use self::server_list::*;
|
||||
mod login;
|
||||
pub use self::login::*;
|
||||
pub mod connecting;
|
||||
|
||||
use std::rc::Rc;
|
||||
|
||||
|
|
|
@ -179,8 +179,9 @@ impl ServerList {
|
|||
});
|
||||
}));
|
||||
|
||||
back.add_click_func(Rc::new(move |_, _| {
|
||||
println!("Connecting to {}", address);
|
||||
back.add_click_func(Rc::new(move |game, _| {
|
||||
game.screen_sys.replace_screen(Box::new(super::connecting::Connecting::new(&address)));
|
||||
game.connect_to(&address);
|
||||
}));
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,42 @@ pub struct Server {
|
|||
}
|
||||
|
||||
impl Server {
|
||||
|
||||
pub fn connect(resources: Arc<RwLock<resources::Manager>>, address: &str) -> Result<Server, protocol::Error> {
|
||||
let mut conn = try!(protocol::Conn::new(address));
|
||||
|
||||
let host = conn.host.clone();
|
||||
let port = conn.port;
|
||||
try!(conn.write_packet(protocol::packet::handshake::serverbound::Handshake {
|
||||
protocol_version: protocol::VarInt(protocol::SUPPORTED_PROTOCOL),
|
||||
host: host,
|
||||
port: port,
|
||||
next: protocol::VarInt(2),
|
||||
}));
|
||||
conn.state = protocol::State::Login;
|
||||
try!(conn.write_packet(protocol::packet::login::serverbound::LoginStart {
|
||||
username: "Thinkofdeath".to_owned()
|
||||
}));
|
||||
|
||||
let packet = match conn.read_packet().unwrap() {
|
||||
protocol::packet::Packet::EncryptionRequest(val) => val,
|
||||
protocol::packet::Packet::LoginDisconnect(val) => {
|
||||
return Err(protocol::Error::Disconnect(val.reason));
|
||||
},
|
||||
val => panic!("Wrong packet: {:?}", val),
|
||||
};
|
||||
|
||||
unimplemented!();
|
||||
|
||||
let version = resources.read().unwrap().version();
|
||||
Ok(Server {
|
||||
conn: Some(conn),
|
||||
world: world::World::new(),
|
||||
resources: resources,
|
||||
version: version,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn dummy_server(resources: Arc<RwLock<resources::Manager>>) -> Server {
|
||||
let mut world = world::World::new();
|
||||
let mut rng = rand::thread_rng();
|
||||
|
|
Loading…
Reference in New Issue