{"action":"created","comment":{"url":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/comments/26235517","id":26235517,"diff_hunk":"@@ -0,0 +1,102 @@\n+//! MC Server List Ping protocol.\n+//!\n+//! Reference: http://wiki.vg/Server_List_Ping\n+\n+use std::fs::File;\n+use std::io::prelude::*;\n+use std::io;\n+use std::net::TcpStream;\n+use std::ops::Sub; // Sub for Timespec\n+use std::path::Path;\n+\n+use packet::{self, PacketRead, PacketWrite};\n+\n+use rustc_serialize::base64::{ToBase64, STANDARD};\n+use rustc_serialize::json;\n+use time;\n+\n+#[derive(RustcDecodable, RustcEncodable)]\n+pub struct Version {\n+    pub name: String,\n+    pub protocol: i32,\n+}\n+\n+#[derive(RustcDecodable, RustcEncodable)]\n+pub struct Players {\n+    pub max: i32,\n+    pub online: i32,\n+    // sample is optional\n+}\n+\n+#[derive(RustcDecodable, RustcEncodable)]\n+pub struct Description {\n+    pub text: String,\n+}\n+\n+/// Response sent to clients as JSON.\n+#[derive(RustcDecodable, RustcEncodable)]\n+pub struct Response {\n+    pub version: Version,\n+    pub players: Players,\n+    pub description: Description,\n+    pub favicon: String,\n+}\n+\n+// FIXME(toqueteos): This is yelling to be a method of a Server struct or\n+// something more useful. We need the Handshake's `next_state` field in order\n+// to perform login for a player.\n+pub fn handler(mut stream: &mut TcpStream) -> io::Result<()> {\n+    // C->S: Status Request packet\n+    let sr = match try!(packet::status::serverbound::Packet::read(stream)) {\n+        packet::status::serverbound::Packet::StatusRequest(sr) => sr,\n+        wrong_packet => panic!(\"Expecting status::serverbound::StatusRequest packet, got {:?}\", wrong_packet)\n+    };\n+\n+    // S->C: Status Response packet\n+    let mut file = try!(File::open(&Path::new(\"favicon.png\")));\n+    let mut contents = Vec::new();\n+    try!(file.read_to_end(&mut contents));\n+    let favicon = contents.as_slice().to_base64(STANDARD);\n+    // FIXME(toqueteos): Micro-optimization? We could totally drop JSON\n+    // encoding and just replace player values (online & max) with format! all\n+    // other values are static.\n+    let resp = Response{\n+        version: Version{\n+            name: \"1.8.1\".to_string(),\n+            protocol: 47,\n+        },\n+        players: Players{\n+            // FIXME(toqueteos): This is value should be a internal counter of server\n+            online: 0,\n+            // FIXME(toqueteos): This is value read from server.properties file\n+            max: 20,\n+        },\n+        description: Description{\n+            text: \"With custom favicons! Woot :D\".to_string(),\n+        },\n+        favicon: format!(\"data:image/png;base64,{:}\", favicon),\n+    };\n+    let sr = packet::status::clientbound::StatusResponse{\n+        response: json::encode(&resp).unwrap()\n+    };\n+    try!(sr.write(&mut stream));\n+\n+    // FIXME(toqueteos): Ping is optional, how we deal with that?\n+\n+    // Optional.\n+    // C->S: Ping packet\n+    let start = time::now().to_timespec();\n+    let sp = match try!(packet::status::serverbound::Packet::read(stream)) {\n+        packet::status::serverbound::Packet::Ping(sr) => sr,\n+        wrong_packet => panic!(\"Expecting status::serverbound::Ping packet, got {:?}\", wrong_packet)\n+    };\n+    let end = time::now().to_timespec();\n+    let elapsed = end.sub(start).num_milliseconds();","path":"src/proto/ping.rs","position":94,"original_position":94,"commit_id":"63dc4930c15815fb4b688a48fcab19dda9147852","original_commit_id":"63dc4930c15815fb4b688a48fcab19dda9147852","user":{"login":"fenhl","id":641386,"avatar_url":"https://avatars.githubusercontent.com/u/641386?v=3","gravatar_id":"","url":"https://api.github.com/users/fenhl","html_url":"https://github.com/fenhl","followers_url":"https://api.github.com/users/fenhl/followers","following_url":"https://api.github.com/users/fenhl/following{/other_user}","gists_url":"https://api.github.com/users/fenhl/gists{/gist_id}","starred_url":"https://api.github.com/users/fenhl/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/fenhl/subscriptions","organizations_url":"https://api.github.com/users/fenhl/orgs","repos_url":"https://api.github.com/users/fenhl/repos","events_url":"https://api.github.com/users/fenhl/events{/privacy}","received_events_url":"https://api.github.com/users/fenhl/received_events","type":"User","site_admin":false},"body":"That's not how ping works. The server should send back the exact same timestamp it received.","created_at":"2015-03-11T17:37:48Z","updated_at":"2015-03-11T17:37:48Z","html_url":"https://github.com/PistonDevelopers/hematite_server/pull/40#discussion_r26235517","pull_request_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/40","_links":{"self":{"href":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/comments/26235517"},"html":{"href":"https://github.com/PistonDevelopers/hematite_server/pull/40#discussion_r26235517"},"pull_request":{"href":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/40"}}},"pull_request":{"url":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/40","id":30864452,"html_url":"https://github.com/PistonDevelopers/hematite_server/pull/40","diff_url":"https://github.com/PistonDevelopers/hematite_server/pull/40.diff","patch_url":"https://github.com/PistonDevelopers/hematite_server/pull/40.patch","issue_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/issues/40","number":40,"state":"open","locked":false,"title":"Basic server features working (ping+login)","user":{"login":"toqueteos","id":699969,"avatar_url":"https://avatars.githubusercontent.com/u/699969?v=3","gravatar_id":"","url":"https://api.github.com/users/toqueteos","html_url":"https://github.com/toqueteos","followers_url":"https://api.github.com/users/toqueteos/followers","following_url":"https://api.github.com/users/toqueteos/following{/other_user}","gists_url":"https://api.github.com/users/toqueteos/gists{/gist_id}","starred_url":"https://api.github.com/users/toqueteos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/toqueteos/subscriptions","organizations_url":"https://api.github.com/users/toqueteos/orgs","repos_url":"https://api.github.com/users/toqueteos/repos","events_url":"https://api.github.com/users/toqueteos/events{/privacy}","received_events_url":"https://api.github.com/users/toqueteos/received_events","type":"User","site_admin":false},"body":"**DO NOT MERGE THIS.**\r\n\r\nJust here for discussion.","created_at":"2015-03-10T16:01:29Z","updated_at":"2015-03-11T17:37:48Z","closed_at":null,"merged_at":null,"merge_commit_sha":"7c99c4e4b9521bf4cac414a2c43188cb6c3c6457","assignee":null,"milestone":{"url":"https://api.github.com/repos/PistonDevelopers/hematite_server/milestones/2","html_url":"https://github.com/PistonDevelopers/hematite_server/milestones/MC%201.8.3","labels_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/milestones/2/labels","id":998942,"number":2,"title":"MC 1.8.3","description":"hematite_server works as a drop-in replacement for MC vanilla server.","creator":{"login":"toqueteos","id":699969,"avatar_url":"https://avatars.githubusercontent.com/u/699969?v=3","gravatar_id":"","url":"https://api.github.com/users/toqueteos","html_url":"https://github.com/toqueteos","followers_url":"https://api.github.com/users/toqueteos/followers","following_url":"https://api.github.com/users/toqueteos/following{/other_user}","gists_url":"https://api.github.com/users/toqueteos/gists{/gist_id}","starred_url":"https://api.github.com/users/toqueteos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/toqueteos/subscriptions","organizations_url":"https://api.github.com/users/toqueteos/orgs","repos_url":"https://api.github.com/users/toqueteos/repos","events_url":"https://api.github.com/users/toqueteos/events{/privacy}","received_events_url":"https://api.github.com/users/toqueteos/received_events","type":"User","site_admin":false},"open_issues":2,"closed_issues":0,"state":"open","created_at":"2015-02-27T15:15:47Z","updated_at":"2015-03-10T16:05:04Z","due_on":null,"closed_at":null},"commits_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/40/commits","review_comments_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/40/comments","review_comment_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/comments{/number}","comments_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/issues/40/comments","statuses_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/statuses/63dc4930c15815fb4b688a48fcab19dda9147852","head":{"label":"toqueteos:newio-server","ref":"newio-server","sha":"63dc4930c15815fb4b688a48fcab19dda9147852","user":{"login":"toqueteos","id":699969,"avatar_url":"https://avatars.githubusercontent.com/u/699969?v=3","gravatar_id":"","url":"https://api.github.com/users/toqueteos","html_url":"https://github.com/toqueteos","followers_url":"https://api.github.com/users/toqueteos/followers","following_url":"https://api.github.com/users/toqueteos/following{/other_user}","gists_url":"https://api.github.com/users/toqueteos/gists{/gist_id}","starred_url":"https://api.github.com/users/toqueteos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/toqueteos/subscriptions","organizations_url":"https://api.github.com/users/toqueteos/orgs","repos_url":"https://api.github.com/users/toqueteos/repos","events_url":"https://api.github.com/users/toqueteos/events{/privacy}","received_events_url":"https://api.github.com/users/toqueteos/received_events","type":"User","site_admin":false},"repo":{"id":30893661,"name":"hematite_server","full_name":"toqueteos/hematite_server","owner":{"login":"toqueteos","id":699969,"avatar_url":"https://avatars.githubusercontent.com/u/699969?v=3","gravatar_id":"","url":"https://api.github.com/users/toqueteos","html_url":"https://github.com/toqueteos","followers_url":"https://api.github.com/users/toqueteos/followers","following_url":"https://api.github.com/users/toqueteos/following{/other_user}","gists_url":"https://api.github.com/users/toqueteos/gists{/gist_id}","starred_url":"https://api.github.com/users/toqueteos/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/toqueteos/subscriptions","organizations_url":"https://api.github.com/users/toqueteos/orgs","repos_url":"https://api.github.com/users/toqueteos/repos","events_url":"https://api.github.com/users/toqueteos/events{/privacy}","received_events_url":"https://api.github.com/users/toqueteos/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/toqueteos/hematite_server","description":"A Minecraft server clone","fork":true,"url":"https://api.github.com/repos/toqueteos/hematite_server","forks_url":"https://api.github.com/repos/toqueteos/hematite_server/forks","keys_url":"https://api.github.com/repos/toqueteos/hematite_server/keys{/key_id}","collaborators_url":"https://api.github.com/repos/toqueteos/hematite_server/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/toqueteos/hematite_server/teams","hooks_url":"https://api.github.com/repos/toqueteos/hematite_server/hooks","issue_events_url":"https://api.github.com/repos/toqueteos/hematite_server/issues/events{/number}","events_url":"https://api.github.com/repos/toqueteos/hematite_server/events","assignees_url":"https://api.github.com/repos/toqueteos/hematite_server/assignees{/user}","branches_url":"https://api.github.com/repos/toqueteos/hematite_server/branches{/branch}","tags_url":"https://api.github.com/repos/toqueteos/hematite_server/tags","blobs_url":"https://api.github.com/repos/toqueteos/hematite_server/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/toqueteos/hematite_server/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/toqueteos/hematite_server/git/refs{/sha}","trees_url":"https://api.github.com/repos/toqueteos/hematite_server/git/trees{/sha}","statuses_url":"https://api.github.com/repos/toqueteos/hematite_server/statuses/{sha}","languages_url":"https://api.github.com/repos/toqueteos/hematite_server/languages","stargazers_url":"https://api.github.com/repos/toqueteos/hematite_server/stargazers","contributors_url":"https://api.github.com/repos/toqueteos/hematite_server/contributors","subscribers_url":"https://api.github.com/repos/toqueteos/hematite_server/subscribers","subscription_url":"https://api.github.com/repos/toqueteos/hematite_server/subscription","commits_url":"https://api.github.com/repos/toqueteos/hematite_server/commits{/sha}","git_commits_url":"https://api.github.com/repos/toqueteos/hematite_server/git/commits{/sha}","comments_url":"https://api.github.com/repos/toqueteos/hematite_server/comments{/number}","issue_comment_url":"https://api.github.com/repos/toqueteos/hematite_server/issues/comments{/number}","contents_url":"https://api.github.com/repos/toqueteos/hematite_server/contents/{+path}","compare_url":"https://api.github.com/repos/toqueteos/hematite_server/compare/{base}...{head}","merges_url":"https://api.github.com/repos/toqueteos/hematite_server/merges","archive_url":"https://api.github.com/repos/toqueteos/hematite_server/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/toqueteos/hematite_server/downloads","issues_url":"https://api.github.com/repos/toqueteos/hematite_server/issues{/number}","pulls_url":"https://api.github.com/repos/toqueteos/hematite_server/pulls{/number}","milestones_url":"https://api.github.com/repos/toqueteos/hematite_server/milestones{/number}","notifications_url":"https://api.github.com/repos/toqueteos/hematite_server/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/toqueteos/hematite_server/labels{/name}","releases_url":"https://api.github.com/repos/toqueteos/hematite_server/releases{/id}","created_at":"2015-02-16T23:23:08Z","updated_at":"2015-03-10T15:54:55Z","pushed_at":"2015-03-10T15:54:55Z","git_url":"git://github.com/toqueteos/hematite_server.git","ssh_url":"git@github.com:toqueteos/hematite_server.git","clone_url":"https://github.com/toqueteos/hematite_server.git","svn_url":"https://github.com/toqueteos/hematite_server","homepage":null,"size":367,"stargazers_count":0,"watchers_count":0,"language":"Rust","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":1,"forks":0,"open_issues":1,"watchers":0,"default_branch":"master"}},"base":{"label":"PistonDevelopers:master","ref":"master","sha":"8d46fbe1513c93fd9fd132eb69b5a7bdd98063ef","user":{"login":"PistonDevelopers","id":7623406,"avatar_url":"https://avatars.githubusercontent.com/u/7623406?v=3","gravatar_id":"","url":"https://api.github.com/users/PistonDevelopers","html_url":"https://github.com/PistonDevelopers","followers_url":"https://api.github.com/users/PistonDevelopers/followers","following_url":"https://api.github.com/users/PistonDevelopers/following{/other_user}","gists_url":"https://api.github.com/users/PistonDevelopers/gists{/gist_id}","starred_url":"https://api.github.com/users/PistonDevelopers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PistonDevelopers/subscriptions","organizations_url":"https://api.github.com/users/PistonDevelopers/orgs","repos_url":"https://api.github.com/users/PistonDevelopers/repos","events_url":"https://api.github.com/users/PistonDevelopers/events{/privacy}","received_events_url":"https://api.github.com/users/PistonDevelopers/received_events","type":"Organization","site_admin":false},"repo":{"id":29402029,"name":"hematite_server","full_name":"PistonDevelopers/hematite_server","owner":{"login":"PistonDevelopers","id":7623406,"avatar_url":"https://avatars.githubusercontent.com/u/7623406?v=3","gravatar_id":"","url":"https://api.github.com/users/PistonDevelopers","html_url":"https://github.com/PistonDevelopers","followers_url":"https://api.github.com/users/PistonDevelopers/followers","following_url":"https://api.github.com/users/PistonDevelopers/following{/other_user}","gists_url":"https://api.github.com/users/PistonDevelopers/gists{/gist_id}","starred_url":"https://api.github.com/users/PistonDevelopers/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/PistonDevelopers/subscriptions","organizations_url":"https://api.github.com/users/PistonDevelopers/orgs","repos_url":"https://api.github.com/users/PistonDevelopers/repos","events_url":"https://api.github.com/users/PistonDevelopers/events{/privacy}","received_events_url":"https://api.github.com/users/PistonDevelopers/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/PistonDevelopers/hematite_server","description":"A Minecraft server clone","fork":false,"url":"https://api.github.com/repos/PistonDevelopers/hematite_server","forks_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/forks","keys_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/keys{/key_id}","collaborators_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/teams","hooks_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/hooks","issue_events_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/issues/events{/number}","events_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/events","assignees_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/assignees{/user}","branches_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/branches{/branch}","tags_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/tags","blobs_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/git/refs{/sha}","trees_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/git/trees{/sha}","statuses_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/statuses/{sha}","languages_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/languages","stargazers_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/stargazers","contributors_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/contributors","subscribers_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/subscribers","subscription_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/subscription","commits_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/commits{/sha}","git_commits_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/git/commits{/sha}","comments_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/comments{/number}","issue_comment_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/issues/comments{/number}","contents_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/contents/{+path}","compare_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/compare/{base}...{head}","merges_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/merges","archive_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/downloads","issues_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/issues{/number}","pulls_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls{/number}","milestones_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/milestones{/number}","notifications_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/labels{/name}","releases_url":"https://api.github.com/repos/PistonDevelopers/hematite_server/releases{/id}","created_at":"2015-01-17T19:02:55Z","updated_at":"2015-03-11T13:35:45Z","pushed_at":"2015-03-11T13:35:45Z","git_url":"git://github.com/PistonDevelopers/hematite_server.git","ssh_url":"git@github.com:PistonDevelopers/hematite_server.git","clone_url":"https://github.com/PistonDevelopers/hematite_server.git","svn_url":"https://github.com/PistonDevelopers/hematite_server","homepage":null,"size":652,"stargazers_count":11,"watchers_count":11,"language":"Rust","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":5,"mirror_url":null,"open_issues_count":12,"forks":5,"open_issues":12,"watchers":11,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/40"},"html":{"href":"https://github.com/PistonDevelopers/hematite_server/pull/40"},"issue":{"href":"https://api.github.com/repos/PistonDevelopers/hematite_server/issues/40"},"comments":{"href":"https://api.github.com/repos/PistonDevelopers/hematite_server/issues/40/comments"},"review_comments":{"href":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/40/comments"},"review_comment":{"href":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/PistonDevelopers/hematite_server/pulls/40/commits"},"statuses":{"href":"https://api.github.com/repos/PistonDevelopers/hematite_server/statuses/63dc4930c15815fb4b688a48fcab19dda9147852"}}}}