mcpi-rs开发日记

This article was last updated on <span id="expire-date"></span> days ago, the information described in the article may be outdated.

代码地址及文档

代码

文档

背景

其实mcpi-rs的开发灵感来自于Adventures in Minecraft (由中文Minecraft Wiki翻译团队译)中的mcpi api

这本书是我的编程启蒙书,当时买这本书的时间是2018年的早春,我还依稀记得由于某个字母没有大写而调了一个下午的美妙地狱过程,而如今我有编程能力了,所以我想试试把这个东西Rust化。

过程

一开始我手里只有python写的api(本人并不怎么擅长python,只认识基本语法),然后我就卡在drain这个函数上了

def drain(self):
    """Drains the socket of incoming data"""
    while True:
        readable, _, _ = select.select([self.socket], [], [], 0.0)
        if not readable:
            break
        data = self.socket.recv(1500)
        e =  "Drained Data: <%s>\n"%data.strip()
        e += "Last Message: <%s>\n"%self.lastSent.strip()
        sys.stderr.write(e)

我一开始不知道啥意思,所以我就去Rust forum问了一下

然后看着dalao给的solution完全读不懂。

然而,后来我搞到了java的api…

void drain(BufferedReader in) throws IOException {
    while (in.ready()) {
        int c = in.read();
        System.err.print((char) c);
    }
}

再一看论坛给的solution

我趣,原来这么简单

Rust代码

    /// drains the socket of incoming data
    pub fn drain(self) {
        self.socket
            .set_nonblocking(true)
            .expect("Failed to set non-blocking mode");
        let mut c: [u8; 1] = [0];
        while self.clone().socket.read(&mut c).is_ok() {
            eprint!("{}", c[0]);
        }
    }
//注: Connection的成员只有一个TcpStream

第二个难住我的是receive函数

java api

String receive() {
    try {
        return in.readLine();
    } catch (IOException e) {
        throw new ConnectionException(e);
    }
}

然而Rust没有这个api啊…

所以我去百度了一下。然后发现有一个神奇的东西叫做BufReader,他提供了Readline函数。

顺便,由于在阻塞模式下不能读取stream,所以需要把阻塞模式关掉

Rust代码

/// receive the data of the address
/// # Example
/// ```
/// use mcpi_rs::prelude::*;
/// let c = Connection::new("127.0.0.1:1000");
/// c.send_s("This string will let the server send back some data");
/// println!("receive: {}",c.receive());
/// ```
pub fn receive(self) -> String {
    self.socket
        .try_clone()
        .unwrap()
        .set_nonblocking(false)
        .unwrap();
    let mut b: BufReader<TcpStream> = BufReader::new(self.socket.try_clone().unwrap());
    let mut s = String::new();
    b.read_line(&mut s).expect("Failed to read line");
    s
}

剩下的基本就是照抄非常简单了

问题(未解决)

  • 中点画圆法3D版本(McDrawing需要)

Author: Caviar-X

Permalink: https://blog.pigeons.cyou/2021/11/20/mcpi-rs-dev-talking/

Comments