Day22 高阶网路应用 GPS 和 Ender Modem

今天来看 CC: Tweaked 最後一个网路应用 GPS
用途是让电脑可以取得自己的座标
而这个座标系统是可以完全自定义的,有 x y z 座标
当然这座标数字不是随便乱打,如果输入不合理的数字,GPS 系统还是会无法运作
或是取得奇怪的座标

这是网路上找到的图片
CC: Tweaked GPS System
所以我就依样画葫芦,建立一座自己的 GPS 系统
CC: Tweaked GPS System
稍微目测计算一下後,用 gps 指令(/rom/programs/gps.lua)各自定义座标
我的四台电脑分别给予座标如下

gps host 3 0 258
gps host -3 0 258
gps host 0 -3 255
gps host 0 3 255

这样就完成了一座 GPS 卫星定位系统!
在这无线范围内的电脑,只要也安装 Wireless Modem,就可以查询自己的座标

gps locate

CC: Tweaked GPS Locate
是不是很简单呢?

为何要谈 Ender Modem ?

Ender Modem 可说是 CC: Tweaked 最强大的数据机!
是怎麽强法?!
Ender 这个命名,我不确定是不是终界使者安德的意思?
Minecraft Ender

根据官方文件,它的强大来自两个特点:

  1. 可传输 2,147,483,647 (2^31-1) 个方块!这太扯了,根本无距离限制,一个 Ender Modem 传遍所有角落,爱传多远就传多远
    CC: Tweaked Ender Modem
  2. 可进行 Cross-Dimension 传输 ..... 这我找了好久,始终没找到 demo,我其实没搞懂 Cross-Dimension 的意思 XD

但是我猜测,Cross-Dimension 传输指的是,我可以从原本的世界传讯到地狱,或是反过来从地狱传来讯息 ~~~ (听起来有点可怕)
实测的结果,每次进出地狱,电脑就 reboot 重开机,所以这部分我也无法向大家介绍了 :P

回到正题,为何要扯 Ender Modem?
想像一下你要建造一个超大范围 GPS 系统,而根据之前实测,Wireless Modem 传输距离大约 64 格方块,难不成你要为此到处放 Repeater 来延展讯号吗?!那不累死 ...
所以,你 GPS 系统的四台电脑,都应该要搭配 Ender Modem
这样只要你在非常遥远的电脑也是安装 Ender Modem,就可以随时取得座标了!

电脑不会动,取得座标干嘛?!

电脑虽然不会动,取得座标意义似乎不大?
但到目前为止,我还有一个重要角色没介绍,那就是 Turtle 小乌龟!
它是可以到处移动的电脑!很多之前介绍过的指令,它也都可以用
如果你的小乌龟在远处挖矿砍树不知去哪了,你就可以设计小乌龟绑 Ender Modem
并每隔一段时间回传自己座标,是不是很可爱 XD

除了 Turtle 小乌龟,还有手持装置 Pocket Computer 也可能会需要取得自己的座标

CC: Tweaked GPS 设计原理

最後,我来挖一下到底它 GPS 系统怎麽实作的
先看 /rom/programs/gps.lua
以下我删去很多细节程序码

if sCommand == "locate" then
    -- Just locate this computer (this will print the results)
    gps.locate(2, true)

elseif sCommand == "host" then
    -- 判断是否为 Pocket Computer,是的话就报错,GPS 的基地台电脑位置必须固定

    -- 寻找 Wireless Modem / Ender Modem,如果没有就报错

    -- 取得玩家输入的 x y z 座标

    -- Open a channel
    local modem = peripheral.wrap(sModemSide)
    modem.open(gps.CHANNEL_GPS)     -- 特殊 Channel,65534

    -- Serve requests indefinately
    local nServed = 0
    while true do
        local e, p1, p2, p3, p4, p5 = os.pullEvent("modem_message")
        if e == "modem_message" then
            -- We received a message from a modem
            local sSide, sChannel, sReplyChannel, sMessage, nDistance = p1, p2, p3, p4, p5
            if sSide == sModemSide and sChannel == gps.CHANNEL_GPS and sMessage == "PING" and nDistance then
                -- We received a ping message on the GPS channel, send a response
                modem.transmit(sReplyChannel, gps.CHANNEL_GPS, { x, y, z })
            end
        end
    end
end

可以看到 gps host 指令的实作,仍然是去监听底层的 modem_message 事件
并判断是否为特定 GPS Channel,以及讯息是否为 "PING"
是的话,就回应自己的 x y z 座标

至於 gps.locate
则要参考 /rom/apis/gps.lua
以下是非常简略地解释其逻辑

-- 收到 locate 指令,会向 GPS Channel 发出 "PING" 讯息
modem.transmit(CHANNEL_GPS, CHANNEL_GPS, "PING")

while true do
    local e, p1, p2, p3, p4, p5 = os.pullEvent()
    if e == "modem_message" then
        -- 收到回应後,判断是否为 GPS Channel,是的话就将座标暂存
        -- 当座标至少有 3 组或以上,就可以计算出目前电脑的 GPS 座标
    end
end

大家可以看到整个 GPS 的应用底层逻辑
也是完全依靠 Modem API
那麽 CC: Tweaked 的网路应用就介绍到这里
下一回来玩玩新的道具~


<<:  Day 23 : Linux - 如何在Ubuntu的英文介面下使用新酷音中文输入法?

>>:  Android学习笔记28

Day28 实作todoList(三)新增事项到State

Header、Button、List元件完成後,我们在根元件App.js依序引入使用, todoLi...

Day 4 ( 入门 ) 鱼儿水中游

鱼儿水中游 教学原文参考:鱼儿水中游 这篇文章会介绍,如何在 Scratch 3 里使用角色移动、重...

他可以坚持,或许我也可以

最近对於自己的未来产生了另一个茫然。 自己会什麽,能给别人什麽,别人又怎麽样会觉得那很棒。 每当遇到...

线性串列的循环/双向链式储存 - DAY 6

线性串列的循环链式储存 定义 线性串列的链式结构,尾节点的指标会指回首节点 优缺 优点: 任一节点都...

#9 Web Crawler 2

We are going to start coding!! 想法 这个爬虫的想法很简单,对於每个 ...