本文讲述了如何在Screeps中玩家与玩家之间通讯的建立和基础的通讯协议,当然这个协议并未得到广泛使用,但有必要的话,你可以了解一下。
优缺陷
在目前的版本下进行通讯需要借助终端(Terminal),每次在建立通讯时会消耗1能量。
但使用终端也能因为终端所带有的冷却防止有人恶意大量请求,并且终端发送的连接数据可以起到很好的保密效果。
应用场景
- 唠嗑
- 玩家组织使用共同的Bot进行协同工作时进行自动交流通讯
协议概述
受限于Screeps共享数据的机制,通讯在传输数据上是主动轮询模式。
会话建立
每个会话(Session)的地址数据被储存在公共的PublicSegment中(以下称Sp,其余地址类似),通讯时数据被储存在对应的segment中。通讯过程先由发起会话端(以下称A端)使用终端向被通讯端(以下称B端)的终端发送一个附带Header连接请求信息(包括A端的通讯地址,例如S6)并消耗1能量和0.02CPU,B端需要开启Server服务并轮询终端的请求信息,接受连接后在Sp中标注分配给该次连接的通讯地址,例如S1。A端拉取B端的Sp信息,获取到B端的通讯地址S1。至此,会话建立成功。
数据传输
A端只需要在自己的S6上写入附带tick信息的数据,供B端轮询。
同理,B端也只需要在自己的S1上写入附带tick信息的数据,供A端轮询。
结束通讯
任意一端可以在自己会话Segment中写入不带tick信息的数据,表示会话结束。
会话安全
建立会话时,A端可以发送一个字节流偏移数据x(密匙)给B端,由于是终端交易这个字节码是仅双方可见的。之后的数据传输会将数据转换为字节流序列,并根据密匙进行相应的数据偏移,解密需要恢复偏移并进行反序列。通过此方式可以对传输数据进行保护。
耗时
建立会话:1tick
终端发送数据没有延迟,所以B端能够立即响应,但返回在Sp上的信息需要1tick延迟A端才能获取。
进行通讯:1tick
因为双方共同轮询数据,所以A端发送的数据B端在下一个tick就能收到。
进行通讯,使用以下代码
//该数据用于本地访问该对话并对该对话进行操作
let localTag = '本地通讯访问标识';
//请求连接
Comnc.requestConnect('playername',{
localTag:localTag,
host:'玩家名称',//必须填写你的游戏名,否则服务端无法返回消息给你
header:{},//头部信息
recevieCallback:funtion(data){
console.log(data.host+data.content);
},
success:function(){
//发送数据
Comnc.sessions[localTag].send({
content:'hello wrold',
});
}
});
接受通讯端代码
Comnc.server({
onRequestConnect:function(host,header){
//这里可以判断请求或进行其他操作,并拒绝或接受连接
return true;
},
onReceive:function(data){
console.log(data.tag+data.host+data.content);
}
});
网友评论