Complete protocol implementation

This commit is contained in:
Thinkofdeath 2015-09-12 20:31:26 +01:00
parent e392dafd82
commit ab2336ffca
16 changed files with 2640 additions and 106 deletions

1
.gitignore vendored
View File

@ -1,2 +1 @@
*.lock
target/

384
Cargo.lock generated Normal file
View File

@ -0,0 +1,384 @@
[root]
name = "steven"
version = "0.0.1"
dependencies = [
"byteorder 0.3.13 (registry+https://github.com/rust-lang/crates.io-index)",
"flate2 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
"glfw 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"hyper 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"steven_gl 0.0.1",
"steven_openssl 0.0.1",
]
[[package]]
name = "advapi32-sys"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.2 (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 = "bitflags"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "byteorder"
version = "0.3.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cookie"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"openssl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "enum_primitive"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "flate2"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gcc"
version = "0.3.13"
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.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gl_common"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "gl_generator"
version = "0.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"khronos_api 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"xml-rs 0.1.26 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glfw"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"enum_primitive 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"glfw-sys 3.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
"semver 0.1.20 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "glfw-sys"
version = "3.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hpack"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "httparse"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hyper"
version = "0.6.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cookie 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)",
"httparse 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
"language-tags 0.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mime 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"num_cpus 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"openssl 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
"solicit 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)",
"traitobject 0.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"typeable 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicase 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"url 0.2.37 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "kernel32-sys"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi 0.2.2 (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 = "khronos_api"
version = "0.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "language-tags"
version = "0.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "lazy_static"
version = "0.1.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libressl-pnacl-sys"
version = "2.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"pnacl-build-helper 1.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "matches"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "mime"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "miniz-sys"
version = "0.1.6"
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)",
]
[[package]]
name = "num"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num_cpus"
version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "openssl"
version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.1.14 (registry+https://github.com/rust-lang/crates.io-index)",
"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)",
]
[[package]]
name = "openssl-sys"
version = "0.6.5"
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)",
"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)",
]
[[package]]
name = "pkg-config"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pnacl-build-helper"
version = "1.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"tempdir 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.3.11"
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)",
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rustc-serialize"
version = "0.3.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "semver"
version = "0.1.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num 0.1.27 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "solicit"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hpack 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "steven_gl"
version = "0.0.1"
dependencies = [
"gl_common 0.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"gl_generator 0.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
"khronos_api 0.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "steven_openssl"
version = "0.0.1"
dependencies = [
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "tempdir"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rand 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "time"
version = "0.1.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "traitobject"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "typeable"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "unicase"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "url"
version = "0.2.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-serialize 0.3.16 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "winapi"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi-build"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "xml-rs"
version = "0.1.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
]

View File

@ -1,6 +1,5 @@
[package]
name = "steven_rust"
name = "steven"
version = "0.0.1"
authors = [ "Thinkofdeath <thinkofdeath@spigotmc.org>" ]
@ -20,3 +19,6 @@ version = "0"
[dependencies.steven_openssl]
path = "./openssl"
version = "0"
[[bin]]
name = "steven"

210
log.log Normal file
View File

@ -0,0 +1,210 @@
Compression: 256
Login: Think b1184d43-1684-41cf-a212-8b9a3df3b6ab
JoinGame(JoinGame { entity_id: 47, gamemode: 1, dimension: 0, difficulty: 1, max_players: 20, level_type: "default", reduced_debug_info: false })
PluginMessageClientbound(PluginMessageClientbound { channel: "REGISTER", data: [87, 69, 67, 85, 73, 0] })
PluginMessageClientbound(PluginMessageClientbound { channel: "MC|Brand", data: [11, 67, 114, 97, 102, 116, 66, 117, 107, 107, 105, 116] })
ServerDifficulty(ServerDifficulty { difficulty: 1 })
SpawnPosition(SpawnPosition { location: <202,64,-93> })
PlayerAbilities(PlayerAbilities { flags: 13, flying_speed: 0.05, walking_speed: 0.1 })
SetCurrentHotbarSlot(SetCurrentHotbarSlot { slot: 5 })
EntityAction(EntityAction { entity_id: 47, action_id: 28 })
Statistics(Statistics { statistices: [] })
MSG: Think joined the game
PlayerInfo(PlayerInfo { inner: PlayerInfoData { action: 0, players: [Add { uuid: UUID(5000938010188400878, 10192164627100470560), name: "Thinkofdeath", properties: [PlayerProperty { name: "textures", value: "eyJ0aW1lc3RhbXAiOjE0NDIwODM5NDgxMjMsInByb2ZpbGVJZCI6IjQ1NjZlNjlmYzkwNzQ4ZWU4ZDcxZDdiYTVhYTAwZDIwIiwicHJvZmlsZU5hbWUiOiJUaGlua29mZGVhdGgiLCJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvMTNlODFiOWUxOWFiMWVmMTdhOTBjMGFhNGUxMDg1ZmMxM2NkNDdjZWQ1YTdhMWE0OTI4MDNiMzU2MWU0YTE1YiJ9LCJDQVBFIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvYTc4OTMyNzBmN2RmNjdhMjBlYTljOGFiNTJkN2FmZjIzMjcwZmM0M2ExMWZiM2RhZTYyMjkxNjM0YWY0MjQifX19", signature: Some("FUTqRMhKeZkCsFVBXlK5qJfB+7lxHBpHT0mHx1sZO32ml3TObw6ZLSqkOJvgj8lSstV3Zg248Ld08z+mEsVPR9qFjibQeFU2S1YKgEglfZOIlIWLrFmlpi2QEEAiUg43a/KpZh8ydNPiNrrhgz7LoHoKHg+lQFeuwqc/Q+pgIMCXsKTqVMOR36LMkMYDuoyhyJs2kop7JxYLE2puibwhki6RwLjU93I+UenVEtBygcu0Eo5FXM0s4kshwS97o6NsvkVq0n4QDLDm9pCVNQ//krLtrrdaq4ZmINBVroOy6XBiMy5Yct8H2EK7KXua1QTeihQwWYg2eWi6Wrjs11gzb9t0OaTv0deB9nljdjIl1ee2bpY320/OcOfFCtmPjb6baDUb34Gl0ZZEK4jQC1JXPpNGXoFPD7iYHYfIR2uqyWCvFqJufNx6XHYjFWFnk4nFJmalDliz3vRPzWC/X1m+1k25HNom+xY88NPGZPSsybBwa/DgunToQxSfy3W1cYti0RVCsAThW25OTZ32ZmRuRswcA9RAifAKa9B0uzrmh5jBJiYVLMM7uP2D6vMB6G4PEczwM56VsEs9eppiPYR9EQ+AKqR7wWPDeQck0n4SVOAYy0gLCgJqayg5xwMQikh8RdhVaNW1nfNRxiAaCs6WZoYmot/YRsTxB3aEw088YmI=") }], gamemode: 1, ping: 0, display: None }] } })
PlayerInfo(PlayerInfo { inner: PlayerInfoData { action: 0, players: [Add { uuid: UUID(12761034494690214351, 11678550278305724075), name: "Think", properties: [PlayerProperty { name: "textures", value: "eyJ0aW1lc3RhbXAiOjE0NDIwODM5NTk4NTMsInByb2ZpbGVJZCI6ImIxMTg0ZDQzMTY4NDQxY2ZhMjEyOGI5YTNkZjNiNmFiIiwicHJvZmlsZU5hbWUiOiJUaGluayIsInRleHR1cmVzIjp7fX0=", signature: Some("c8KfMdq65VLdsBVrW1dtnIJM+OtCFXk5uCKvUZ7aTeBeQVQh2gSRNe303hbLkYNGtbY64nHcB1Pm2NF0P85Sl3S7MZDxWJmrGIQbnsS4Ptd+Y90Ub51eQxUy5EG78xYPvmTC6UBqVkQfhLfCQBkKLaYFb6ec8pMdmGubfttp0FTOIyQ6HU9x+kfx7K53McumV8P1LCzsjNGfm9tB1zg698LoPJHn5srSvUCAA1OLGsXpw/Zo8j8BwPpdHwq4KhSe0OYQD0xdw7EF3ih7eSPnBgfWADzCYsUC6AReAvbKo5uBtEtI+DGT33YGmJFhXCEo7B9EyXGZHQ+Yn+RXmXF4+l+e2A7I0GhvdjOi+REZvCksH5U9Ac8jqVr8BgtlJCPJD1xa3WteCngmovCyGb8ldeb0Ni27l0UqW0v6RbB9TQGfktwxJE7zZjU5pV2wV8XQq2VCwFzRy7KGyF4TFGoQtq2o9Spw6VWsT1rDQuJXJ8/XaSq624Sj8UkRm2RpJ6LesM6j+N8Q/ISetXHwreiR0SYHgoWCQuznAsELsSWcV7Af/7XfNEu5YmkWqzquEjx/LAlLWfLo5KwvlXjj9FOhcQXMqdNLJeoEsvlndtVUtY6yTfwZbLF7mG3UO06iRxP2GsO3rIFDmAqgD4iztcXW8wZASFsllPh9BN4+KhhkKDQ=") }], gamemode: 1, ping: 0, display: None }] } })
PlayerInfo(PlayerInfo { inner: PlayerInfoData { action: 0, players: [Add { uuid: UUID(12761034494690214351, 11678550278305724075), name: "Think", properties: [PlayerProperty { name: "textures", value: "eyJ0aW1lc3RhbXAiOjE0NDIwODM5NTk4NTMsInByb2ZpbGVJZCI6ImIxMTg0ZDQzMTY4NDQxY2ZhMjEyOGI5YTNkZjNiNmFiIiwicHJvZmlsZU5hbWUiOiJUaGluayIsInRleHR1cmVzIjp7fX0=", signature: Some("c8KfMdq65VLdsBVrW1dtnIJM+OtCFXk5uCKvUZ7aTeBeQVQh2gSRNe303hbLkYNGtbY64nHcB1Pm2NF0P85Sl3S7MZDxWJmrGIQbnsS4Ptd+Y90Ub51eQxUy5EG78xYPvmTC6UBqVkQfhLfCQBkKLaYFb6ec8pMdmGubfttp0FTOIyQ6HU9x+kfx7K53McumV8P1LCzsjNGfm9tB1zg698LoPJHn5srSvUCAA1OLGsXpw/Zo8j8BwPpdHwq4KhSe0OYQD0xdw7EF3ih7eSPnBgfWADzCYsUC6AReAvbKo5uBtEtI+DGT33YGmJFhXCEo7B9EyXGZHQ+Yn+RXmXF4+l+e2A7I0GhvdjOi+REZvCksH5U9Ac8jqVr8BgtlJCPJD1xa3WteCngmovCyGb8ldeb0Ni27l0UqW0v6RbB9TQGfktwxJE7zZjU5pV2wV8XQq2VCwFzRy7KGyF4TFGoQtq2o9Spw6VWsT1rDQuJXJ8/XaSq624Sj8UkRm2RpJ6LesM6j+N8Q/ISetXHwreiR0SYHgoWCQuznAsELsSWcV7Af/7XfNEu5YmkWqzquEjx/LAlLWfLo5KwvlXjj9FOhcQXMqdNLJeoEsvlndtVUtY6yTfwZbLF7mG3UO06iRxP2GsO3rIFDmAqgD4iztcXW8wZASFsllPh9BN4+KhhkKDQ=") }], gamemode: 1, ping: 0, display: None }] } })
UpdateBlockEntity(UpdateBlockEntity { location: <31,95,-116>, action: 5, nbt: Some(NamedTag("", Compound({"y": Int(95), "x": Int(31), "z": Int(-116), "Item": Int(38), "Data": Int(1), "id": String("FlowerPot")}))) })
UpdateBlockEntity(UpdateBlockEntity { location: <31,95,-117>, action: 5, nbt: Some(NamedTag("", Compound({"z": Int(-117), "id": String("FlowerPot"), "y": Int(95), "Item": Int(38), "x": Int(31), "Data": Int(0)}))) })
UpdateBlockEntity(UpdateBlockEntity { location: <30,95,-116>, action: 5, nbt: Some(NamedTag("", Compound({"Data": Int(2), "id": String("FlowerPot"), "Item": Int(38), "z": Int(-116), "y": Int(95), "x": Int(30)}))) })
UpdateBlockEntity(UpdateBlockEntity { location: <28,92,-119>, action: 3, nbt: Some(NamedTag("", Compound({"Lock": String(""), "x": Int(28), "z": Int(-119), "Secondary": Int(0), "Primary": Int(0), "id": String("Beacon"), "y": Int(92), "Levels": Int(0)}))) })
UpdateBlockEntity(UpdateBlockEntity { location: <28,95,-116>, action: 3, nbt: Some(NamedTag("", Compound({"Primary": Int(1), "Levels": Int(1), "y": Int(95), "id": String("Beacon"), "Lock": String(""), "z": Int(-116), "Secondary": Int(0), "x": Int(28)}))) })
SpawnMob(SpawnMob { entity_id: 0, uuid: UUID(8318773244061304819, 12224757210753227758), ty: 90, x: 782, y: 3008, z: -3601, yaw: -126, pitch: -28, head_pitch: 125, velocity_x: 0, velocity_y: -627, velocity_z: 0, metadata: Metadata[ 3=Bool(false), 6=Float(10), 10=Byte(0), 1=Int(300), 11=Bool(false), 5=Byte(0), 9=Int(0), 8=Bool(false), 0=Byte(0), 12=Bool(false), 7=Int(0), 4=Bool(false), 2=String(""), ] })
EntityMetadata(EntityMetadata { entity_id: 0, metadata: Metadata[ 2=String(""), 10=Byte(0), 4=Bool(false), 5=Byte(0), 8=Bool(false), 9=Int(0), 6=Float(10), 3=Bool(false), 11=Bool(false), 12=Bool(false), 1=Int(300), 7=Int(0), 0=Byte(0), ] })
StatusRequest(StatusRequest { empty: () })
EntityHeadLook(EntityHeadLook { entity_id: 0, head_yaw: 125 })
SpawnMob(SpawnMob { entity_id: 1, uuid: UUID(15638293629224504267, 10167566484811300374), ty: 91, x: 817, y: 3008, z: -3634, yaw: 61, pitch: -28, head_pitch: 101, velocity_x: 0, velocity_y: -627, velocity_z: 0, metadata: Metadata[ 6=Float(8), 7=Int(0), 0=Byte(0), 1=Int(300), 9=Int(0), 3=Bool(false), 8=Bool(false), 4=Bool(false), 10=Byte(0), 11=Bool(false), 2=String("Steven The Sheep"), 12=Byte(0), 5=Byte(0), ] })
EntityMetadata(EntityMetadata { entity_id: 1, metadata: Metadata[ 8=Bool(false), 9=Int(0), 10=Byte(0), 0=Byte(0), 11=Bool(false), 2=String("Steven The Sheep"), 12=Byte(0), 4=Bool(false), 3=Bool(false), 5=Byte(0), 1=Int(300), 7=Int(0), 6=Float(8), ] })
StatusRequest(StatusRequest { empty: () })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 101 })
SpawnPlayer(SpawnPlayer { entity_id: 46, uuid: UUID(5000938010188400878, 10192164627100470560), x: 777, y: 3072, z: -3686, yaw: -26, pitch: 25, metadata: Metadata[ 5=Byte(0), 3=Bool(false), 4=Bool(false), 0=Byte(0), 1=Int(300), 8=Bool(true), 10=Float(0), 7=Int(8171462), 9=Int(0), 13=Byte(1), 6=Float(20), 11=Int(0), 2=String(""), 12=Byte(127), ] })
EntityMetadata(EntityMetadata { entity_id: 46, metadata: Metadata[ 6=Float(20), 3=Bool(false), 12=Byte(127), 1=Int(300), 0=Byte(0), 5=Byte(0), 7=Int(8171462), 13=Byte(1), 10=Float(0), 11=Int(0), 8=Bool(true), 2=String(""), 9=Int(0), 4=Bool(false), ] })
StatusRequest(StatusRequest { empty: () })
EntityEquipment(EntityEquipment { entity_id: 46, slot: 0, item: Some(Stack { id: 165, count: 64, damage: 0, tag: None }) })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -27 })
StatusRequest(StatusRequest { empty: () })
MSG: <Think> Hello world
TeleportPlayer(TeleportPlayer { x: 28.4464725021921, y: 95, z: -116.30000001192093, yaw: -178.90189, pitch: 37.049976, flags: 0 })
WorldBorder(WorldBorder { action: 3, old_radius: Some(0), new_radius: Some(0), speed: Some(65), x: Some(-0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000063061072628375414), z: Some(-0.0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000630610726283749), portal_boundary: Some(29999984), warning_time: Some(5), warning_blocks: Some(15) })
TimeUpdate(TimeUpdate { world_age: 7683709, time_of_day: 7872174 })
StatusRequest(StatusRequest { empty: () })
WindowItems(WindowItems { id: 0, items: [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, Some(Stack { id: 50, count: 64, damage: 0, tag: None }), Some(Stack { id: 1, count: 64, damage: 0, tag: None }), Some(Stack { id: 1, count: 64, damage: 0, tag: None }), Some(Stack { id: 12, count: 64, damage: 0, tag: None }), Some(Stack { id: 2, count: 64, damage: 0, tag: None }), Some(Stack { id: 276, count: 64, damage: 0, tag: None }), None, None, None, None] })
WindowSetSlot(WindowSetSlot { id: 255, property: -1, item: None })
WindowSetSlot(WindowSetSlot { id: 0, property: 36, item: Some(Stack { id: 50, count: 64, damage: 0, tag: None }) })
WindowSetSlot(WindowSetSlot { id: 0, property: 37, item: Some(Stack { id: 1, count: 64, damage: 0, tag: None }) })
WindowSetSlot(WindowSetSlot { id: 0, property: 38, item: Some(Stack { id: 1, count: 64, damage: 0, tag: None }) })
WindowSetSlot(WindowSetSlot { id: 0, property: 39, item: Some(Stack { id: 12, count: 64, damage: 0, tag: None }) })
WindowSetSlot(WindowSetSlot { id: 0, property: 40, item: Some(Stack { id: 2, count: 64, damage: 0, tag: None }) })
WindowSetSlot(WindowSetSlot { id: 0, property: 41, item: Some(Stack { id: 276, count: 64, damage: 0, tag: None }) })
EntityMetadata(EntityMetadata { entity_id: 47, metadata: Metadata[ 1=Int(300), 8=Bool(false), 9=Int(0), 7=Int(0), 10=Float(0), 3=Bool(false), 5=Byte(0), 12=Byte(0), 0=Byte(0), 11=Int(0), 13=Byte(1), 4=Bool(false), 6=Float(20), 2=String(""), ] })
StatusRequest(StatusRequest { empty: () })
MSG: Welcome, Think!
MSG: Type /help for a list of commands.
MSG: Type /list to see who else is online.
MSG: Players online: 2 - World time: 6:10 AM
MSG: You have no new mail.
TimeUpdate(TimeUpdate { world_age: 7683712, time_of_day: 7872177 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityLook(EntityLook { entity_id: 0, yaw: -126, pitch: 0, on_ground: true })
EntityMove(EntityMove { entity_id: 46, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
EntityLook(EntityLook { entity_id: 1, yaw: 61, pitch: 0, on_ground: true })
TimeUpdate(TimeUpdate { world_age: 7683732, time_of_day: 7872197 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityMove(EntityMove { entity_id: 0, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
EntityMove(EntityMove { entity_id: 1, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
KeepAliveClientbound(KeepAliveClientbound { id: 37196518 })
TimeUpdate(TimeUpdate { world_age: 7683752, time_of_day: 7872217 })
BlockChange(BlockChange { location: <-9,85,-235>, block_id: 624 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityLook(EntityLook { entity_id: 0, yaw: -126, pitch: -29, on_ground: true })
StatusRequest(StatusRequest { empty: () })
StatusRequest(StatusRequest { empty: () })
StatusRequest(StatusRequest { empty: () })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 79 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 58 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 37 })
TimeUpdate(TimeUpdate { world_age: 7683772, time_of_day: 7872237 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 23 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityMove(EntityMove { entity_id: 46, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 39 })
KeepAliveClientbound(KeepAliveClientbound { id: 37198568 })
TimeUpdate(TimeUpdate { world_age: 7683792, time_of_day: 7872257 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityMove(EntityMove { entity_id: 0, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
EntityMove(EntityMove { entity_id: 1, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
SoundEffect(SoundEffect { name: "mob.sheep.say", x: 204, y: 752, z: -908, volume: 1, pitch: 58 })
TimeUpdate(TimeUpdate { world_age: 7683812, time_of_day: 7872277 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityLook(EntityLook { entity_id: 0, yaw: -126, pitch: 0, on_ground: true })
KeepAliveClientbound(KeepAliveClientbound { id: 37200618 })
TimeUpdate(TimeUpdate { world_age: 7683832, time_of_day: 7872297 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityMove(EntityMove { entity_id: 46, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
StatusRequest(StatusRequest { empty: () })
StatusRequest(StatusRequest { empty: () })
StatusRequest(StatusRequest { empty: () })
EntityLook(EntityLook { entity_id: 0, yaw: -126, pitch: -29, on_ground: true })
TimeUpdate(TimeUpdate { world_age: 7683852, time_of_day: 7872317 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityMove(EntityMove { entity_id: 0, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
EntityMove(EntityMove { entity_id: 1, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
EntityLook(EntityLook { entity_id: 46, yaw: -46, pitch: 17, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -35 })
EntityLook(EntityLook { entity_id: 46, yaw: -58, pitch: 9, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -53 })
EntityLook(EntityLook { entity_id: 46, yaw: -71, pitch: 5, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -67 })
EntityLook(EntityLook { entity_id: 46, yaw: -90, pitch: 5, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -77 })
EntityLookAndMove(EntityLookAndMove { entity_id: 46, delta_x: 0, delta_y: 0, delta_z: -10, yaw: -95, pitch: 4, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -95 })
SoundEffect(SoundEffect { name: "mob.pig.say", x: 195, y: 752, z: -900, volume: 1, pitch: 57 })
EntityMove(EntityMove { entity_id: 46, delta_x: 7, delta_y: 0, delta_z: -9, on_ground: true })
SoundEffect(SoundEffect { name: "step.grass", x: 197, y: 768, z: -927, volume: 0.15, pitch: 63 })
TimeUpdate(TimeUpdate { world_age: 7683872, time_of_day: 7872337 })
KeepAliveClientbound(KeepAliveClientbound { id: 37202669 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityLookAndMove(EntityLookAndMove { entity_id: 46, delta_x: 12, delta_y: 0, delta_z: -8, yaw: -85, pitch: 8, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -89 })
EntityHeadLook(EntityHeadLook { entity_id: 0, head_yaw: -122 })
EntityLookAndMove(EntityLookAndMove { entity_id: 46, delta_x: 5, delta_y: 0, delta_z: -4, yaw: -78, pitch: 11, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -83 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 60 })
EntityLook(EntityLook { entity_id: 46, yaw: -52, pitch: 18, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -66 })
EntityLookAndMove(EntityLookAndMove { entity_id: 46, delta_x: -4, delta_y: 0, delta_z: 14, yaw: -46, pitch: 19, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -47 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 82 })
EntityMove(EntityMove { entity_id: 46, delta_x: -2, delta_y: 0, delta_z: 6, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 103 })
EntityLook(EntityLook { entity_id: 46, yaw: -39, pitch: 22, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -42 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 124 })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -37 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: -115 })
EntityLook(EntityLook { entity_id: 46, yaw: -32, pitch: 23, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -32 })
TimeUpdate(TimeUpdate { world_age: 7683892, time_of_day: 7872357 })
EntityLook(EntityLook { entity_id: 0, yaw: -126, pitch: 0, on_ground: true })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityMove(EntityMove { entity_id: 46, delta_x: -1, delta_y: 0, delta_z: 2, on_ground: true })
EntityLook(EntityLook { entity_id: 46, yaw: 13, pitch: 18, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: -20 })
EntityLook(EntityLook { entity_id: 46, yaw: 29, pitch: 19, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: 29 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 120 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 109 })
TimeUpdate(TimeUpdate { world_age: 7683912, time_of_day: 7872377 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityMove(EntityMove { entity_id: 0, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
EntityMove(EntityMove { entity_id: 1, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
KeepAliveClientbound(KeepAliveClientbound { id: 37204718 })
StatusRequest(StatusRequest { empty: () })
StatusRequest(StatusRequest { empty: () })
StatusRequest(StatusRequest { empty: () })
TimeUpdate(TimeUpdate { world_age: 7683932, time_of_day: 7872397 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 88 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 67 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 59 })
TimeUpdate(TimeUpdate { world_age: 7683952, time_of_day: 7872417 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
KeepAliveClientbound(KeepAliveClientbound { id: 37206768 })
SoundEffect(SoundEffect { name: "mob.sheep.say", x: 204, y: 752, z: -908, volume: 1, pitch: 66 })
EntityMove(EntityMove { entity_id: 46, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -653, velocity_y: -627, velocity_z: 502 })
EntityLook(EntityLook { entity_id: 0, yaw: -105, pitch: 0, on_ground: true })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 399, velocity_y: -627, velocity_z: -363 })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -597, velocity_y: -627, velocity_z: 879 })
EntityLook(EntityLook { entity_id: 0, yaw: -63, pitch: 0, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 0, head_yaw: -109 })
BlockChange(BlockChange { location: <-72,10,-189>, block_id: 624 })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -647, velocity_y: -627, velocity_z: 607 })
EntityLook(EntityLook { entity_id: 0, yaw: -97, pitch: 0, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 0, head_yaw: -95 })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -166, velocity_y: -627, velocity_z: 140 })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 0, velocity_y: -627, velocity_z: 0 })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -695, velocity_y: -627, velocity_z: 686 })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 396, velocity_y: -627, velocity_z: -399 })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -141, velocity_y: -627, velocity_z: 0 })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 0, velocity_y: -627, velocity_z: 0 })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -689, velocity_y: -627, velocity_z: 604 })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 400, velocity_y: -627, velocity_z: -397 })
TimeUpdate(TimeUpdate { world_age: 7683972, time_of_day: 7872437 })
BlockAction(BlockAction { location: <26,95,-117>, byte1: 1, byte2: 0, block_type: 130 })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: 0, velocity_y: -627, velocity_z: 141 })
EntityMove(EntityMove { entity_id: 0, delta_x: 0, delta_y: 0, delta_z: 2, on_ground: true })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 0, velocity_y: -627, velocity_z: 0 })
EntityMove(EntityMove { entity_id: 1, delta_x: 0, delta_y: 0, delta_z: 0, on_ground: true })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -604, velocity_y: -627, velocity_z: 689 })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 397, velocity_y: -627, velocity_z: -400 })
SoundEffect(SoundEffect { name: "mob.pig.step", x: 195, y: 752, z: -899, volume: 0.15, pitch: 63 })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -141, velocity_y: -627, velocity_z: 0 })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 0, velocity_y: -627, velocity_z: 0 })
EntityLook(EntityLook { entity_id: 46, yaw: 26, pitch: 27, on_ground: true })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -689, velocity_y: -627, velocity_z: 604 })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 399, velocity_y: -627, velocity_z: -397 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 51 })
EntityLook(EntityLook { entity_id: 46, yaw: 21, pitch: 31, on_ground: true })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: 24 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 37 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 23 })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: 0, velocity_y: -627, velocity_z: 141 })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 0, velocity_y: -627, velocity_z: 0 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 16 })
EntityHeadLook(EntityHeadLook { entity_id: 46, head_yaw: 20 })
EntityVelocity(EntityVelocity { entity_id: 0, velocity_x: -604, velocity_y: -627, velocity_z: 689 })
EntityVelocity(EntityVelocity { entity_id: 1, velocity_x: 397, velocity_y: -627, velocity_z: -400 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: 9 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: -5 })
EntityHeadLook(EntityHeadLook { entity_id: 1, head_yaw: -20 })

12
openssl/Cargo.lock generated Normal file
View File

@ -0,0 +1,12 @@
[root]
name = "steven_openssl"
version = "0.0.1"
dependencies = [
"libc 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "libc"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"

View File

@ -1,10 +1,7 @@
extern crate glfw;
extern crate steven;
pub mod bit;
pub mod protocol;
pub mod format;
mod gl;
use steven::*;
use glfw::{Action, Context, Key};
fn main() {

View File

@ -4,8 +4,7 @@ use std::fmt;
#[derive(Debug)]
pub enum Component {
Text(TextComponent),
None
Text(TextComponent)
}
impl Component {
@ -16,7 +15,7 @@ impl Component {
} else if v.find("text").is_some(){
Component::Text(TextComponent::from_value(v, modifier))
} else {
Component::None
Component::Text(TextComponent{text: "".to_owned(), modifier: modifier})
}
}
@ -29,18 +28,17 @@ impl fmt::Display for Component {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Component::Text(ref txt) => write!(f, "{}", txt),
Component::None => Result::Ok(()),
}
}
}
impl Default for Component {
fn default() -> Self {
Component::None
Component::Text(TextComponent{text: "".to_owned(), modifier: Default::default()})
}
}
#[derive(Debug)]
#[derive(Debug, Default)]
pub struct Modifier {
pub extra: Option<Vec<Component>>,
pub bold: Option<bool>,

54
src/item.rs Normal file
View File

@ -0,0 +1,54 @@
extern crate byteorder;
use nbt;
use protocol::{Serializable};
use std::io;
use std::io::{Read, Write};
use self::byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
#[derive(Debug)]
pub struct Stack {
id: isize,
count: isize,
damage: isize,
tag: Option<nbt::NamedTag>,
}
impl Default for Stack {
fn default() -> Stack {
Stack {
id: -1,
count: 0,
damage: 0,
tag: None,
}
}
}
impl Serializable for Option<Stack> {
fn read_from(buf: &mut io::Read) -> Result<Option<Stack>, io::Error> {
let id = try!(buf.read_i16::<BigEndian>());
if id == -1 {
return Ok(None);
}
Ok(Some(Stack{
id: id as isize,
count: try!(buf.read_u8()) as isize,
damage: try!(buf.read_i16::<BigEndian>()) as isize,
tag: try!(Serializable::read_from(buf)),
}))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
match *self {
Some(ref val) => {
try!(buf.write_i16::<BigEndian>(val.id as i16));
try!(buf.write_u8(val.count as u8));
try!(buf.write_i16::<BigEndian>(val.damage as i16));
try!(val.tag.write_to(buf));
},
None => try!(buf.write_i16::<BigEndian>(-1)),
}
Result::Ok(())
}
}

8
src/lib.rs Normal file
View File

@ -0,0 +1,8 @@
#![cfg_attr(test, allow(dead_code))]
pub mod bit;
pub mod protocol;
pub mod format;
pub mod nbt;
pub mod item;
pub mod gl;
pub mod types;

274
src/nbt/mod.rs Normal file
View File

@ -0,0 +1,274 @@
extern crate byteorder;
use std::collections::HashMap;
use std::io;
use std::io::{Read, Write};
use super::protocol::{Serializable};
use super::protocol;
use self::byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
#[derive(Debug)]
pub enum Tag {
End,
Byte(i8),
Short(i16),
Int(i32),
Long(i64),
Float(f32),
Double(f64),
ByteArray(Vec<u8>),
String(String),
List(Vec<Tag>),
Compound(HashMap<String, Tag>),
IntArray(Vec<i32>),
}
#[derive(Debug)]
pub struct NamedTag(pub String, pub Tag);
impl Tag {
pub fn new_compound() -> Tag {
Tag::Compound(HashMap::new())
}
pub fn new_list() -> Tag {
Tag::List(Vec::new())
}
/// Returns the tag with the given name from the compound.
///
/// # Panics
/// Panics when the tag isn't a compound.
pub fn get(&self, name: &str) -> Option<&Tag> {
match *self {
Tag::Compound(ref val) => val.get(name),
_ => panic!("not a compound tag"),
}
}
/// Places the tag into the compound using the given name.
///
/// # Panics
/// Panics when the tag isn't a compound.
pub fn put(&mut self, name: &str, tag: Tag) {
match *self {
Tag::Compound(ref mut val) => val.insert(name.to_owned(), tag),
_ => panic!("not a compound tag"),
};
}
pub fn is_compound(&self) -> bool {
match *self {
Tag::Compound(_) => true,
_ => false,
}
}
pub fn as_byte(&self) -> Option<i8> {
match *self {
Tag::Byte(val) => Some(val),
_ => None,
}
}
pub fn as_short(&self) -> Option<i16> {
match *self {
Tag::Short(val) => Some(val),
_ => None,
}
}
pub fn as_int(&self) -> Option<i32> {
match *self {
Tag::Int(val) => Some(val),
_ => None,
}
}
pub fn as_long(&self) -> Option<i64> {
match *self {
Tag::Long(val) => Some(val),
_ => None,
}
}
pub fn as_float(&self) -> Option<f32> {
match *self {
Tag::Float(val) => Some(val),
_ => None,
}
}
pub fn as_double(&self) -> Option<f64> {
match *self {
Tag::Double(val) => Some(val),
_ => None,
}
}
pub fn as_byte_array(&self) -> Option<&[u8]> {
match *self {
Tag::ByteArray(ref val) => Some(&val[..]),
_ => None,
}
}
pub fn as_string(&self) -> Option<&str> {
match *self {
Tag::String(ref val) => Some(&val[..]),
_ => None,
}
}
pub fn as_list(&self) -> Option<&[Tag]> {
match *self {
Tag::List(ref val) => Some(&val[..]),
_ => None,
}
}
pub fn as_compound(&self) -> Option<&HashMap<String, Tag>> {
match *self {
Tag::Compound(ref val) => Some(val),
_ => None,
}
}
pub fn as_int_array(&self) -> Option<&[i32]> {
match *self {
Tag::IntArray(ref val) => Some(&val[..]),
_ => None,
}
}
fn internal_id(&self) -> u8 {
match *self {
Tag::End => 0,
Tag::Byte(_) => 1,
Tag::Short(_) => 2,
Tag::Int(_) => 3,
Tag::Long(_) => 4,
Tag::Float(_) => 5,
Tag::Double(_) => 6,
Tag::ByteArray(_) => 7,
Tag::String(_) => 8,
Tag::List(_) => 9,
Tag::Compound(_) => 10,
Tag::IntArray(_) => 11,
}
}
fn read_type(id: u8, buf: &mut io::Read) -> Result<Tag, io::Error> {
match id {
0 => unreachable!(),
1 => Ok(Tag::Byte(try!(buf.read_i8()))),
2 => Ok(Tag::Short(try!(buf.read_i16::<BigEndian>()))),
3 => Ok(Tag::Int(try!(buf.read_i32::<BigEndian>()))),
4 => Ok(Tag::Long(try!(buf.read_i64::<BigEndian>()))),
5 => Ok(Tag::Float(try!(buf.read_f32::<BigEndian>()))),
6 => Ok(Tag::Double(try!(buf.read_f64::<BigEndian>()))),
7 => Ok(Tag::ByteArray({
let len : i32 = try!(Serializable::read_from(buf));
let mut data = Vec::with_capacity(len as usize);
try!(buf.take(len as u64).read_to_end(&mut data));
data
})),
8 => Ok(Tag::String(try!(read_string(buf)))),
9 => {
let mut l = Vec::new();
let ty = try!(buf.read_u8());
let len : i32 = try!(Serializable::read_from(buf));
for _ in 0 .. len {
l.push(try!(Tag::read_type(ty, buf)));
}
Ok(Tag::List(l))
},
10 => {
let mut c = Tag::new_compound();
loop {
let ty = try!(buf.read_u8());
if ty == 0 {
break;
}
let name: String = try!(read_string(buf));
c.put(&name[..], try!(Tag::read_type(ty, buf)));
}
Ok(c)
},
11 => Ok(Tag::IntArray({
let len : i32 = try!(Serializable::read_from(buf));
let mut data = Vec::with_capacity(len as usize);
for _ in 0 .. len {
data.push(try!(buf.read_i32::<BigEndian>()));
}
data
})),
_ => Err(io::Error::new(io::ErrorKind::InvalidData, protocol::Error::Err("invalid tag".to_owned()))),
}
}
}
impl Serializable for Tag {
fn read_from(buf: &mut io::Read) -> Result<Tag, io::Error> {
Tag::read_type(10, buf)
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
match *self {
Tag::End => {},
Tag::Byte(val) => try!(buf.write_i8(val)),
Tag::Short(val) => try!(buf.write_i16::<BigEndian>(val)),
Tag::Int(val) => try!(buf.write_i32::<BigEndian>(val)),
Tag::Long(val) => try!(buf.write_i64::<BigEndian>(val)),
Tag::Float(val) => try!(buf.write_f32::<BigEndian>(val)),
Tag::Double(val) => try!(buf.write_f64::<BigEndian>(val)),
Tag::ByteArray(ref val) => {
try!((val.len() as i32).write_to(buf));
try!(buf.write_all(val));
},
Tag::String(ref val) => try!(write_string(buf, val)),
Tag::List(ref val) => {
if val.is_empty() {
try!(buf.write_u8(0));
try!(buf.write_i32::<BigEndian>(0));
} else {
try!(buf.write_u8(val[0].internal_id()));
try!(buf.write_i32::<BigEndian>(val.len() as i32));
for e in val {
try!(e.write_to(buf));
}
}
},
Tag::Compound(ref val) => {
for (k, v) in val {
try!(v.internal_id().write_to(buf));
try!(write_string(buf, k));
try!(v.write_to(buf));
}
try!(buf.write_u8(0));
},
Tag::IntArray(ref val) => {
try!((val.len() as i32).write_to(buf));
for v in val {
try!(v.write_to(buf));
}
},
}
Result::Ok(())
}
}
pub fn write_string(buf: &mut io::Write, s: &String)-> io::Result<()> {
let data = s.as_bytes();
try!((data.len() as i16).write_to(buf));
buf.write_all(data)
}
pub fn read_string(buf: &mut io::Read) -> io::Result<String> {
let len: i16 = try!(buf.read_i16::<BigEndian>());
let mut ret = String::new();
try!(buf.take(len as u64).read_to_string(&mut ret));
Result::Ok(ret)
}

View File

@ -7,7 +7,9 @@ extern crate serde_json;
pub mod mojang;
use nbt;
use format;
use std::fmt;
use std::default;
use std::net::TcpStream;
use std::io;
@ -21,7 +23,8 @@ use self::flate2::read::{ZlibDecoder, ZlibEncoder};
macro_rules! state_packets {
($($state:ident $stateName:ident {
$($dir:ident $dirName:ident {
$($name:ident => $id:expr {
$(
$name:ident => $id:expr {
$($field:ident: $field_type:ty = $(when ($cond:expr))*, )+
})*
})+
@ -29,6 +32,7 @@ macro_rules! state_packets {
use protocol::*;
use std::io;
#[derive(Debug)]
pub enum Packet {
$(
$(
@ -47,9 +51,12 @@ macro_rules! state_packets {
use protocol::*;
use std::io;
use format;
use nbt;
use types;
use item;
$(
#[derive(Default)]
#[derive(Default, Debug)]
pub struct $name {
$(pub $field: $field_type),+,
}
@ -58,7 +65,7 @@ macro_rules! state_packets {
fn packet_id(&self) -> i32{ $id }
fn write(self, buf: &mut Vec<u8>) -> Result<(), io::Error> {
fn write(self, buf: &mut io::Write) -> Result<(), io::Error> {
$(
if true $(&& ($cond(&self)))* {
try!(self.$field.write_to(buf));
@ -76,7 +83,7 @@ macro_rules! state_packets {
/// Returns the packet for the given state, direction and id after parsing the fields
/// from the buffer.
pub fn packet_by_id(state: State, dir: Direction, id: i32, mut buf: &mut io::Cursor<Vec<u8>>) -> Result<Option<Packet>, io::Error> {
pub fn packet_by_id(state: State, dir: Direction, id: i32, mut buf: &mut io::Read) -> Result<Option<Packet>, io::Error> {
match state {
$(
State::$stateName => {
@ -115,6 +122,42 @@ pub trait Serializable {
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error>;
}
impl Serializable for Vec<u8> {
fn read_from(buf: &mut io::Read) -> Result<Vec<u8> , io::Error> {
let mut v = Vec::new();
try!(buf.read_to_end(&mut v));
Ok(v)
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
buf.write_all(&self[..])
}
}
impl Serializable for Option<nbt::NamedTag>{
fn read_from(buf: &mut io::Read) -> Result<Option<nbt::NamedTag>, io::Error> {
let ty = try!(buf.read_u8());
if ty == 0 {
Result::Ok(None)
} else {
let name = try!(nbt::read_string(buf));
let tag = try!(nbt::Tag::read_from(buf));
Result::Ok(Some(nbt::NamedTag(name, tag)))
}
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
match *self {
Some(ref val) => {
try!(buf.write_u8(10));
try!(nbt::write_string(buf, &val.0));
try!(val.1.write_to(buf));
}
None => try!(buf.write_u8(0)),
}
Result::Ok(())
}
}
impl <T> Serializable for Option<T> where T : Serializable {
fn read_from(buf: &mut io::Read) -> Result<Option<T>, io::Error> {
Result::Ok(Some(try!(T::read_from(buf))))
@ -159,46 +202,6 @@ impl Serializable for format::Component {
}
}
pub struct Position(u64);
impl Position {
fn new(x: i32, y: i32, z: i32) -> Position {
Position(
(((x as u64) & 0x3FFFFFF) << 38) |
(((y as u64) & 0xFFF) << 26) |
((z as u64) & 0x3FFFFFF)
)
}
fn get_x(&self) -> i32 {
((self.0 as i64) >> 38) as i32
}
fn get_y(&self) -> i32 {
(((self.0 as i64) >> 26) & 0xFFF) as i32
}
fn get_z(&self) -> i32 {
((self.0 as i64) << 38 >> 38) as i32
}
}
impl Default for Position {
fn default() -> Position {
Position(0)
}
}
impl Serializable for Position {
fn read_from(buf: &mut io::Read) -> Result<Position, io::Error> {
Result::Ok(Position(try!(buf.read_u64::<BigEndian>())))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_u64::<BigEndian>(self.0));
Result::Ok(())
}
}
impl Serializable for () {
fn read_from(_: &mut io::Read) -> Result<(), io::Error> {
Result::Ok(())
@ -218,6 +221,16 @@ impl Serializable for bool {
}
}
impl Serializable for i8 {
fn read_from(buf: &mut io::Read) -> Result<i8, io::Error> {
Result::Ok(try!(buf.read_i8()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_i8(*self));
Result::Ok(())
}
}
impl Serializable for i16 {
fn read_from(buf: &mut io::Read) -> Result<i16, io::Error> {
Result::Ok(try!(buf.read_i16::<BigEndian>()))
@ -268,7 +281,54 @@ impl Serializable for u16 {
}
}
pub trait Lengthable : Serializable + Into<usize> + From<usize> + Copy + Default {}
impl Serializable for f32 {
fn read_from(buf: &mut io::Read) -> Result<f32, io::Error> {
Result::Ok(try!(buf.read_f32::<BigEndian>()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_f32::<BigEndian>(*self));
Result::Ok(())
}
}
impl Serializable for f64 {
fn read_from(buf: &mut io::Read) -> Result<f64, io::Error> {
Result::Ok(try!(buf.read_f64::<BigEndian>()))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_f64::<BigEndian>(*self));
Result::Ok(())
}
}
#[derive(Debug)]
pub struct UUID(u64, u64);
impl Default for UUID {
fn default() -> Self { UUID(0, 0) }
}
impl Serializable for UUID {
fn read_from(buf: &mut io::Read) -> Result<UUID, io::Error> {
Result::Ok(
UUID(
try!(buf.read_u64::<BigEndian>()),
try!(buf.read_u64::<BigEndian>()),
)
)
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_u64::<BigEndian>(self.0));
try!(buf.write_u64::<BigEndian>(self.1));
Result::Ok(())
}
}
pub trait Lengthable : Serializable + Copy + Default {
fn into(self) -> usize;
fn from(usize) -> Self;
}
pub struct LenPrefixed<L: Lengthable, V> {
len: L,
@ -296,7 +356,7 @@ impl <L: Lengthable, V: Serializable> Serializable for LenPrefixed<L, V> {
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
let len_data : L = self.data.len().into();
let len_data : L = L::from(self.data.len());
try!(len_data.write_to(buf));
let ref data = self.data;
for val in data {
@ -306,6 +366,7 @@ impl <L: Lengthable, V: Serializable> Serializable for LenPrefixed<L, V> {
}
}
impl <L: Lengthable, V: Default> Default for LenPrefixed<L, V> {
fn default() -> Self {
LenPrefixed {
@ -315,12 +376,94 @@ impl <L: Lengthable, V: Default> Default for LenPrefixed<L, V> {
}
}
impl <L: Lengthable, V: fmt::Debug> fmt::Debug for LenPrefixed<L, V> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.data.fmt(f)
}
}
// Optimization
pub struct LenPrefixedBytes<L: Lengthable> {
len: L,
pub data: Vec<u8>
}
impl <L: Lengthable> LenPrefixedBytes<L> {
fn new(data: Vec<u8>) -> LenPrefixedBytes<L> {
return LenPrefixedBytes {
len: Default::default(),
data: data,
}
}
}
impl <L: Lengthable> Serializable for LenPrefixedBytes<L> {
fn read_from(buf: &mut io::Read) -> Result<LenPrefixedBytes<L>, io::Error> {
let len_data : L = try!(Serializable::read_from(buf));
let len : usize = len_data.into();
let mut data : Vec<u8> = Vec::with_capacity(len);
try!(buf.take(len as u64).read_to_end(&mut data));
Result::Ok(LenPrefixedBytes{len: len_data, data: data})
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
let len_data : L = L::from(self.data.len());
try!(len_data.write_to(buf));
try!(buf.write_all(&self.data[..]));
Result::Ok(())
}
}
impl <L: Lengthable> Default for LenPrefixedBytes<L> {
fn default() -> Self {
LenPrefixedBytes {
len: default::Default::default(),
data: default::Default::default()
}
}
}
impl <L: Lengthable> fmt::Debug for LenPrefixedBytes<L> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
self.data.fmt(f)
}
}
impl Lengthable for i16 {
fn into(self) -> usize {
self as usize
}
fn from(u: usize) -> i16 {
u as i16
}
}
impl Lengthable for i32 {
fn into(self) -> usize {
self as usize
}
fn from(u: usize) -> i32 {
u as i32
}
}
/// VarInt have a variable size (between 1 and 5 bytes) when encoded based
/// on the size of the number
#[derive(Clone, Copy)]
pub struct VarInt(i32);
pub struct VarInt(pub i32);
impl Lengthable for VarInt {}
impl Lengthable for VarInt {
fn into(self) -> usize {
self.0 as usize
}
fn from(u: usize) -> VarInt {
VarInt(u as i32)
}
}
impl Serializable for VarInt {
/// Decodes a VarInt from the Reader
@ -333,7 +476,7 @@ impl Serializable for VarInt {
val |= (b & PART) << (size * 7);
size+=1;
if size > 5 {
return Result::Err(io::Error::new(io::ErrorKind::InvalidInput, Error::Err("VarInt too big".to_string())))
return Result::Err(io::Error::new(io::ErrorKind::InvalidInput, Error::Err("VarInt too big".to_owned())))
}
if (b & 0x80) == 0 {
break
@ -362,15 +505,70 @@ impl default::Default for VarInt {
fn default() -> VarInt { VarInt(0) }
}
impl convert::Into<usize> for VarInt {
fn into(self) -> usize {
self.0 as usize
impl fmt::Debug for VarInt {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
impl convert::From<usize> for VarInt {
fn from(u: usize) -> VarInt {
VarInt(u as i32)
/// VarLong have a variable size (between 1 and 10 bytes) when encoded based
/// on the size of the number
#[derive(Clone, Copy)]
pub struct VarLong(pub i64);
impl Lengthable for VarLong {
fn into(self) -> usize {
self.0 as usize
}
fn from(u: usize) -> VarLong {
VarLong(u as i64)
}
}
impl Serializable for VarLong {
/// Decodes a VarLong from the Reader
fn read_from(buf: &mut io::Read) -> Result<VarLong, io::Error> {
const PART : u64 = 0x7F;
let mut size = 0;
let mut val = 0u64;
loop {
let b = try!(buf.read_u8()) as u64;
val |= (b & PART) << (size * 7);
size+=1;
if size > 10 {
return Result::Err(io::Error::new(io::ErrorKind::InvalidInput, Error::Err("VarLong too big".to_owned())))
}
if (b & 0x80) == 0 {
break
}
}
Result::Ok(VarLong(val as i64))
}
/// Encodes a VarLong into the Writer
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
const PART : u64 = 0x7F;
let mut val = self.0 as u64;
loop {
if (val & !PART) == 0 {
try!(buf.write_u8(val as u8));
return Result::Ok(());
}
try!(buf.write_u8(((val & PART) | 0x80) as u8));
val >>= 7;
}
}
}
impl default::Default for VarLong {
fn default() -> VarLong { VarLong(0) }
}
impl fmt::Debug for VarLong {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{}", self.0)
}
}
@ -516,13 +714,12 @@ impl Conn {
Some(val) => {
let pos = buf.position() as usize;
let ibuf = buf.into_inner();
if ibuf.len() < pos {
if ibuf.len() != pos {
return Result::Err(Error::Err(format!("Failed to read all of packet 0x{:X}, had {} bytes left", id, ibuf.len() - pos)))
}
Result::Ok(val)
},
// FIXME
None => Result::Ok(packet::Packet::StatusRequest(packet::status::serverbound::StatusRequest{empty:()}))//Result::Err(Error::Err("missing packet".to_string()))
None => Result::Err(Error::Err("missing packet".to_owned()))
}
}
@ -592,25 +789,25 @@ impl Clone for Conn {
pub trait PacketType {
fn packet_id(&self) -> i32;
fn write(self, buf: &mut Vec<u8>) -> Result<(), io::Error>;
fn write(self, buf: &mut io::Write) -> Result<(), io::Error>;
}
#[test]
fn test() {
// #[test]
pub fn test() {
let mut c = Conn::new("localhost:25565").unwrap();
c.write_packet(packet::handshake::serverbound::Handshake{
protocol_version: VarInt(69),
host: "localhost".to_string(),
protocol_version: VarInt(71),
host: "localhost".to_owned(),
port: 25565,
next: VarInt(2),
}).unwrap();
c.state = State::Login;
c.write_packet(packet::login::serverbound::LoginStart{username: "Think".to_string()}).unwrap();
c.write_packet(packet::login::serverbound::LoginStart{username: "Think".to_owned()}).unwrap();
let packet = match c.read_packet().unwrap() {
packet::Packet::EncryptionRequest(val) => val,
_ => panic!("Wrong packet"),
val => panic!("Wrong packet: {:?}", val),
};
let mut key = openssl::PublicKey::new(&packet.public_key.data);
@ -620,17 +817,17 @@ fn test() {
let token_e = key.encrypt(&packet.verify_token.data);
let profile = mojang::Profile{
username: "Think".to_string(),
id: "b1184d43168441cfa2128b9a3df3b6ab".to_string(),
access_token: "".to_string()
username: "Think".to_owned(),
id: "b1184d43168441cfa2128b9a3df3b6ab".to_owned(),
access_token: "".to_owned()
};
profile.join_server(&packet.server_id, &shared, &packet.public_key.data);
c.write_packet(packet::login::serverbound::EncryptionResponse{
shared_secret: LenPrefixed::new(shared_e),
verify_token: LenPrefixed::new(token_e),
});
shared_secret: LenPrefixedBytes::new(shared_e),
verify_token: LenPrefixedBytes::new(token_e),
}).unwrap();
let mut read = c.clone();
let mut write = c.clone();
@ -660,12 +857,13 @@ fn test() {
let mut count = 0;
loop { match read.read_packet().unwrap() {
packet::Packet::ServerMessage(val) => println!("MSG: {}", val.message),
_ => {
packet::Packet::ChunkData(_) => {},
val => {
println!("{:?}", val);
if first {
println!("got packet");
write.write_packet(packet::play::serverbound::ChatMessage{
message: "Hello world".to_string(),
});
message: "Hello world".to_owned(),
}).unwrap();
first = false;
}
count += 1;

File diff suppressed because it is too large Load Diff

6
src/type/mod.rs Normal file
View File

@ -0,0 +1,6 @@
mod blockpos;
pub use self::blockpos::*;
mod metadata;
pub use self::metadata::*;

54
src/types/blockpos.rs Normal file
View File

@ -0,0 +1,54 @@
extern crate byteorder;
use std::fmt;
use protocol::{Serializable};
use std::io;
use std::io::{Read, Write};
use self::byteorder::{BigEndian, WriteBytesExt, ReadBytesExt};
#[derive(Clone, Copy)]
pub struct Position(u64);
impl Position {
fn new(x: i32, y: i32, z: i32) -> Position {
Position(
(((x as u64) & 0x3FFFFFF) << 38) |
(((y as u64) & 0xFFF) << 26) |
((z as u64) & 0x3FFFFFF)
)
}
fn get_x(&self) -> i32 {
((self.0 as i64) >> 38) as i32
}
fn get_y(&self) -> i32 {
(((self.0 as i64) >> 26) & 0xFFF) as i32
}
fn get_z(&self) -> i32 {
((self.0 as i64) << 38 >> 38) as i32
}
}
impl Default for Position {
fn default() -> Position {
Position(0)
}
}
impl fmt::Debug for Position {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "<{},{},{}>", self.get_x(), self.get_y(), self.get_z())
}
}
impl Serializable for Position {
fn read_from(buf: &mut io::Read) -> Result<Position, io::Error> {
Result::Ok(Position(try!(buf.read_u64::<BigEndian>())))
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
try!(buf.write_u64::<BigEndian>(self.0));
Result::Ok(())
}
}

380
src/types/metadata.rs Normal file
View File

@ -0,0 +1,380 @@
use std::collections::HashMap;
use std::marker::PhantomData;
use std::io;
use std::io::{Read, Write};
use std::fmt;
use protocol;
use protocol::{Serializable};
use format;
use item;
pub struct MetadataKey<T: MetaValue> {
index: i32,
ty: PhantomData<T>,
}
impl <T: MetaValue> MetadataKey<T> {
// TODO: Make const later when possible
/*const*/ fn new(index: i32) -> MetadataKey<T> {
MetadataKey {
index: index,
ty: PhantomData,
}
}
}
pub struct Metadata {
map: HashMap<i32, Value>,
}
impl Metadata {
pub fn new() -> Metadata {
Metadata { map: HashMap::new() }
}
pub fn get<T: MetaValue>(&self, key: &MetadataKey<T>) -> Option<&T> {
self.map.get(&key.index).map(T::unwrap)
}
pub fn put<T: MetaValue>(&mut self, key: &MetadataKey<T>, val: T) {
self.map.insert(key.index, val.wrap());
}
fn put_raw<T: MetaValue>(&mut self, index: i32, val: T) {
self.map.insert(index, val.wrap());
}
}
impl Serializable for Metadata {
fn read_from(buf: &mut io::Read) -> Result<Self, io::Error> {
let mut m = Metadata::new();
loop {
let index = try!(u8::read_from(buf)) as i32;
if index == 0xFF {
break;
}
let ty = try!(u8::read_from(buf));
match ty {
0 => m.put_raw(index, try!(i8::read_from(buf))),
1 => m.put_raw(index, try!(protocol::VarInt::read_from(buf)).0),
2 => m.put_raw(index, try!(f32::read_from(buf))),
3 => m.put_raw(index, try!(String::read_from(buf))),
4 => m.put_raw(index, try!(format::Component::read_from(buf))),
5 => m.put_raw(index, try!(Option::<item::Stack>::read_from(buf))),
6 => m.put_raw(index, try!(bool::read_from(buf))),
7 => m.put_raw(index, [
try!(f32::read_from(buf)),
try!(f32::read_from(buf)),
try!(f32::read_from(buf))
]),
8 => m.put_raw(index, try!(super::Position::read_from(buf))),
9 => {
if try!(bool::read_from(buf)) {
m.put_raw(index, try!(Option::<super::Position>::read_from(buf)));
} else {
m.put_raw::<Option<super::Position>>(index, None);
}
},
10 => m.put_raw(index, try!(protocol::VarInt::read_from(buf))),
11 => {
if try!(bool::read_from(buf)) {
m.put_raw(index, try!(Option::<protocol::UUID>::read_from(buf)));
} else {
m.put_raw::<Option<protocol::UUID>>(index, None);
}
},
12 => m.put_raw(index, try!(protocol::VarInt::read_from(buf)).0 as u16),
_ => return Err(io::Error::new(io::ErrorKind::InvalidInput, protocol::Error::Err("unknown metadata type".to_owned()))),
}
}
Ok(m)
}
fn write_to(&self, buf: &mut io::Write) -> Result<(), io::Error> {
for (k, v) in &self.map {
try!((*k as u8).write_to(buf));
match *v {
Value::Byte(ref val) => {
try!(u8::write_to(&0, buf));
try!(val.write_to(buf));
},
Value::Int(ref val) => {
try!(u8::write_to(&1, buf));
try!(protocol::VarInt(*val).write_to(buf));
},
Value::Float(ref val) => {
try!(u8::write_to(&2, buf));
try!(val.write_to(buf));
},
Value::String(ref val) => {
try!(u8::write_to(&3, buf));
try!(val.write_to(buf));
},
Value::FormatComponent(ref val) => {
try!(u8::write_to(&4, buf));
try!(val.write_to(buf));
},
Value::OptionalItemStack(ref val) => {
try!(u8::write_to(&5, buf));
try!(val.write_to(buf));
},
Value::Bool(ref val) => {
try!(u8::write_to(&6, buf));
try!(val.write_to(buf));
},
Value::Vector(ref val) => {
try!(u8::write_to(&7, buf));
try!(val[0].write_to(buf));
try!(val[1].write_to(buf));
try!(val[2].write_to(buf));
},
Value::Position(ref val) => {
try!(u8::write_to(&8, buf));
try!(val.write_to(buf));
},
Value::OptionalPosition(ref val) => {
try!(u8::write_to(&9, buf));
try!(val.is_some().write_to(buf));
try!(val.write_to(buf));
},
Value::Direction(ref val) => {
try!(u8::write_to(&10, buf));
try!(val.write_to(buf));
}
Value::OptionalUUID(ref val) => {
try!(u8::write_to(&11, buf));
try!(val.is_some().write_to(buf));
try!(val.write_to(buf));
},
Value::Block(ref val) => {
try!(u8::write_to(&11, buf));
try!(protocol::VarInt(*val as i32).write_to(buf));
}
}
}
try!(u8::write_to(&0xFF, buf));
Ok(())
}
}
impl fmt::Debug for Metadata {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "Metadata[ "));
for (k, v) in &self.map {
try!(write!(f, "{:?}={:?}, ", k, v));
}
write!(f, "]")
}
}
impl Default for Metadata {
fn default() -> Metadata {
Metadata::new()
}
}
#[derive(Debug)]
enum Value {
Byte(i8),
Int(i32),
Float(f32),
String(String),
FormatComponent(format::Component),
OptionalItemStack(Option<item::Stack>),
Bool(bool),
Vector([f32; 3]),
Position(super::Position),
OptionalPosition(Option<super::Position>),
Direction(protocol::VarInt), // TODO: Proper type
OptionalUUID(Option<protocol::UUID>),
Block(u16), // TODO: Proper type
}
pub trait MetaValue {
fn unwrap(&Value) -> &Self;
fn wrap(self) -> Value;
}
impl MetaValue for i8 {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::Byte(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::Byte(self)
}
}
impl MetaValue for i32 {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::Int(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::Int(self)
}
}
impl MetaValue for f32 {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::Float(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::Float(self)
}
}
impl MetaValue for String {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::String(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::String(self)
}
}
impl MetaValue for format::Component {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::FormatComponent(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::FormatComponent(self)
}
}
impl MetaValue for Option<item::Stack> {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::OptionalItemStack(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::OptionalItemStack(self)
}
}
impl MetaValue for bool {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::Bool(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::Bool(self)
}
}
impl MetaValue for [f32; 3] {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::Vector(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::Vector(self)
}
}
impl MetaValue for super::Position {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::Position(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::Position(self)
}
}
impl MetaValue for Option<super::Position> {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::OptionalPosition(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::OptionalPosition(self)
}
}
impl MetaValue for protocol::VarInt {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::Direction(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::Direction(self)
}
}
impl MetaValue for Option<protocol::UUID> {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::OptionalUUID(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::OptionalUUID(self)
}
}
impl MetaValue for u16 {
fn unwrap(value: &Value) -> &Self {
match *value {
Value::Block(ref val) => val,
_ => panic!("incorrect key"),
}
}
fn wrap(self) -> Value {
Value::Block(self)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::marker::PhantomData;
const TEST: MetadataKey<String> =
MetadataKey {
index: 0,
ty: PhantomData,
};
#[test]
fn basic() {
let mut m = Metadata::new();
m.put(&TEST, "Hello world".to_owned());
match m.get(&TEST) {
Some(val) => {
assert!(val == "Hello world");
}
None => panic!("failed"),
}
}
}

6
src/types/mod.rs Normal file
View File

@ -0,0 +1,6 @@
mod blockpos;
pub use self::blockpos::*;
mod metadata;
pub use self::metadata::*;