1use std::io::prelude::*;
4use std::net::TcpStream;
5use std::io::BufReader;
6use std::cmp::{min, max};
7
8#[cfg(test)]
9mod tests {
10
11 #[test]
12 fn development_test() {
13 }
14}
15
16pub struct Minecraft {
18 conn:Connection
19}
20
21struct Connection {
22 stream:TcpStream
23}
24
25pub struct Player<'a> {
27 conn:&'a mut Connection
28}
29
30pub struct Entity<'a> {
31 conn:&'a mut Connection
32}
33
34#[derive(Debug)]
36pub struct TileVec3 {
37 pub x:i32,
38 pub y:i32,
39 pub z:i32
40}
41
42#[derive(Debug)]
44pub struct Vec3 {
45 pub x:f32,
46 pub y:f32,
47 pub z:f32
48}
49
50impl TileVec3 {
51 pub fn from(x:i32, y:i32, z:i32) -> TileVec3 {
53 TileVec3 {
54 x,
55 y,
56 z
57 }
58 }
59 pub fn from_vector(vec:&Vec<i32>) -> TileVec3 {
63 TileVec3 {
64 x: vec[0],
65 y: vec[1],
66 z: vec[2]
67 }
68 }
69}
70
71impl Vec3 {
72 pub fn from(x:f32, y:f32, z:f32) -> Vec3 {
74 Vec3 {
75 x,
76 y,
77 z
78 }
79 }
80 pub fn from_vector(vec:&Vec<f32>) -> Vec3 {
84 Vec3{
85 x: vec[0],
86 y: vec[1],
87 z: vec[2]
88 }
89 }
90}
91
92impl Connection {
93 pub fn send(&mut self, msg:&str) {
94 self.stream.write(&format!("{}\n", msg).as_bytes()).expect("Failed to send! Is MCPI still running?");
95 }
96
97 pub fn receive(&mut self) -> String {
98 let mut reader = BufReader::new(&self.stream);
99 let mut line = String::new();
100 reader.read_line(&mut line).expect("Failed to receive! Is MCPI still running?");
101 line.replace('\n',"")
102 }
103
104 pub fn send_receive(&mut self, msg:&str) -> String {
105 self.send(msg);
106 self.receive()
107 }
108}
109impl Minecraft {
113 pub fn post_to_chat(&mut self, msg:&str) {
115 self.conn.send(&format!("chat.post({})", msg));
116 }
117 pub fn get_block(&mut self, pos:&TileVec3) -> u8 {
119 self.conn.send_receive(&format!("world.getBlock({},{},{})", pos.x, pos.y, pos.z)).parse::<u8>().unwrap()
120 }
121 pub fn get_block_with_data(&mut self, pos:&TileVec3) -> Vec<u8> {
123 self.conn.send_receive(&format!("world.getBlockWithData({},{},{})", pos.x, pos.y, pos.z)).split(',').map(|s| s.parse()).collect::<Result<Vec<u8>, _>>().unwrap()
124 }
125 pub fn get_blocks(&mut self, pos1:&TileVec3, pos2:&TileVec3) -> Vec<u8> {
127 let mut results:Vec<u8> = vec![];
128 for y in min(pos1.y, pos2.y)..max(pos1.y, pos2.y)+1 {
129 for x in min(pos1.x, pos2.x)..max(pos1.x, pos2.x)+1 {
130 for z in min(pos1.z, pos2.z)..max(pos1.z, pos2.z) + 1 {
131 results.push(self.conn.send_receive(&format!("world.getBlock({},{},{})", x,y,z)).parse::<u8>().unwrap());
132 }
133 }
134 }
135 results
136 }
137 pub fn get_blocks_with_data(&mut self, pos1:&TileVec3, pos2:&TileVec3) -> Vec<Vec<u8>> {
139 let mut results:Vec<Vec<u8>> = vec![];
140 for y in min(pos1.y, pos2.y)..max(pos1.y, pos2.y)+1 {
141 for x in min(pos1.x, pos2.x)..max(pos1.x, pos2.x)+1 {
142 for z in min(pos1.z, pos2.z)..max(pos1.z, pos2.z) + 1 {
143 results.push(self.conn.send_receive(&format!("world.getBlockWithData({},{},{})", x,y,z)).split(',').map(|s| s.parse()).collect::<Result<Vec<u8>, _>>().unwrap());
144 }
145 }
146 }
147 results
148 }
149 pub fn set_block(&mut self, pos:&TileVec3, blocktype:u8, blockdata:u8) {
151 self.conn.send(&format!("world.setBlock({},{},{},{},{})", pos.x, pos.y, pos.z, blocktype, blockdata));
152 }
153 pub fn set_blocks(&mut self, pos1:&TileVec3, pos2:&TileVec3, blocktype:u8, blockdata:u8) {
155 self.conn.send(&format!("world.setBlocks({},{},{},{},{},{},{},{})", pos1.x,pos1.y,pos1.z,pos2.x,pos2.y,pos2.z,blocktype,blockdata));
156 }
157 pub fn get_height(&mut self, pos:&TileVec3) -> i8 {
159 self.conn.send_receive(&format!("world.getHeight({},{})", pos.x,pos.z)).parse::<i8>().unwrap()
160 }
161 pub fn save_checkpoint(&mut self) {
163 self.conn.send("world.checkpoint.save()");
164 }
165 pub fn restore_checkpoint(&mut self) {
167 self.conn.send("world.checkpoint.restore()");
168 }
169 pub fn setting(&mut self, setting:&str, status:bool) {
172 self.conn.send(&format!("world.setting({},{})",setting,if status == true {1} else {0}));
173 }
174 pub fn get_player_entity_ids(&mut self) -> Vec<u16> {
176 self.conn.send_receive(&format!("world.getPlayerIds()")).split("|").map(|s| s.parse()).collect::<Result<Vec<u16>, _>>().unwrap()
177 }
178 pub fn player(&mut self) -> Player {
180 Player {
181 conn: &mut self.conn
182 }
183 }
184
185 pub fn entity(&mut self) -> Entity {
186 Entity {
187 conn: &mut self.conn
188 }
189 }
190}
191impl Player<'_> {
195 pub fn get_pos(&mut self) -> Vec3 {
197 Vec3::from_vector(&self.conn.send_receive(&format!("player.getPos()")).split(',').map(|s| s.parse()).collect::<Result<Vec<f32>, _>>().unwrap())
198 }
199 pub fn set_pos(&mut self, pos:&Vec3) {
201 self.conn.send(&format!("player.setPos({},{},{})", pos.x, pos.y, pos.z));
202 }
203 pub fn get_tile_pos(&mut self) -> TileVec3 {
205 let vec:Vec<i32> = self.conn.send_receive(&format!("player.getTile()")).split(',').map(|s| s.parse()).collect::<Result<Vec<i32>, _>>().unwrap();
206 TileVec3::from_vector(&vec)
207 }
208 pub fn set_tile_pos(&mut self, pos:&TileVec3) {
210 self.conn.send(&format!("player.setTile({},{},{})", pos.x, pos.y, pos.z))
211 }
212 pub fn setting(&mut self, setting:&str, status:bool) {
215 self.conn.send(&format!("player.setting({},{})",setting,if status {1} else {0}));
216 }
217}
218
219impl Entity<'_> {
220 pub fn get_pos(&mut self, id:u16) -> Vec3 {
222 Vec3::from_vector(&self.conn.send_receive(&format!("entity.getPos({})", id)).split(',').map(|s| s.parse()).collect::<Result<Vec<f32>, _>>().unwrap())
223 }
224 pub fn set_pos(&mut self, id:u16, pos:&Vec3) {
226 self.conn.send(&format!("entity.setPos({},{},{},{})", id, pos.x, pos.y, pos.z));
227 }
228 pub fn get_tile_pos(&mut self, id:u16) -> TileVec3 {
230 let vec:Vec<i32> = self.conn.send_receive(&format!("entity.getTile({})", id)).split(',').map(|s| s.parse()).collect::<Result<Vec<i32>, _>>().unwrap();
231 TileVec3::from_vector(&vec)
232 }
233 pub fn set_tile_pos(&mut self, id:u16, pos:&TileVec3) {
235 self.conn.send(&format!("entity.setTile({},{},{},{})",id, pos.x, pos.y, pos.z))
236 }
237}
238
239pub fn create(adress:&str) -> Minecraft {
250 let stream = TcpStream::connect(adress);
251 match stream {
252 Ok(_) => {}
253 Err(_) => {
254 panic!("Failed to connect to the API! Is Minecraft running?")
255 }
256 }
257 Minecraft {
258 conn: Connection {
259 stream: stream.unwrap()
260 }
261 }
262}