我有一个建立在流星框架上的游戏。一个游戏文档是这样的:
{
...
participants : [
{
"name":"a",
"character":"fighter",
"weapon" : "sword"
},
{
"name":"b",
"character":"wizard",
"weapon" : "book"
},
...
],
...
}我希望战士字符不要看到"b“用户的字符。(和b字符没有看到a)有大约10个领域,如字符和武器,他们的价值可以在游戏中改变,这样的限制。
现在,我使用会话变量来不显示该信息。然而,这并不是一个非常安全的想法。如何根据字符的值订阅/发布文档?
这里有两个可能的解决方案: 1.发布针对不同字段值的所有组合,并根据用户的当前状态进行订阅。但是,在呈现页面之前,我将使用铁路由器的waitOn功能来加载订阅。所以我不太相信我可以在游戏中改变订阅。此外,因为这是一个时间敏感的游戏,我想改变订阅将需要时间,在游戏期间,破坏游戏的乐趣。
到控制台并查看其他用户的字段。如果我把我的集合名称更改为很难找到的东西,有人能发现集合名吗?找不到在客户端查找集合的命令。
发布于 2015-10-27 06:27:10
在“流星”中,解决这个问题的方法通常是使用两种出版物。如果您的游戏状态是由单个文档表示的,那么很容易实现这一点可能会有问题,因此为了举一个示例,我将暂时假设您有一个Participants集合,您将在其中存储相应的数据。
因此,无论如何,你应该有一个订阅与所有球员可用的数据,例如。
Meteor.publish('players', function (gameId) {
return Participants.find({ gameId: gameId }, { fields: {
// exclude the "character" field from the result
character: 0
}});
});以及另一项私人播放器数据的订阅:
Meteor.publish('myPrivateData', function (gameId) {
// NOTE: not excluding anything, because we are only
// publishing a single document here, whose owner
// is the current user ...
return Participants.find({
userId: this.userId,
gameId: gameId,
});
});现在,在客户端,唯一需要做的事情是订阅这两个数据集,因此:
Meteor.subscribe('players', myGameId);
Meteor.subscribe('myPrivateData', myGameId);Meteor将足够聪明地将传入的数据合并到一个Participants集合中,在该集合中,其他参与者的文档将不包含character字段。
编辑
如果您的字段可见性将动态更改,我建议采用以下方法:
observe将该集合集成到本地播放器表示中,以便更容易地访问数据。数据模型
例如,集合可能如下所示:
PlayerProperties = new Mongo.Collection('playerProperties');
/* schema:
userId : String
gameId : String
key : String
value : *
whoCanSee : [String]
*/发布数据
首先,您需要向每个玩家公开自己的属性。
Meteor.publish('myProperties', function (gameId) {
return PlayerProperties.find({
userId: this.userId,
gameId: gameId
});
});然后其他玩家属性:
Meteor.publish('otherPlayersProperties', function (gameId) {
if (!this.userId) return [];
return PlayerProperties.find({
gameId: gameId,
whoCanSee: this.userId,
});
});现在,您在游戏中需要做的唯一一件事就是确保一旦用户能够看到该属性,就将相应的userId添加到whoCanSee数组中。
改进
为了保持数据的有序性,我建议拥有一个只有客户端的集合,例如IntegratedPlayerData,您可以使用该集合将播放器属性安排到一些可管理的结构中:
var IntegratedPlayerData = new Mongo.Collection(null);
var cache = {};
PlayerProperties.find().observe({
added: function (doc) {
IntegratedPlayerData.upsert({ _id : doc.userId }, {
$set: _.object([ doc.key ], [ doc.value ])
});
},
changed: function (doc) {
IntegratedPlayerData.update({ _id : doc.userId }, {
$set: _.object([ doc.key ], [ doc.value ])
});
},
removed: function (doc) {
IntegratedPlayerData.update({ _id : doc.userId }, {
$unset: _.object([ doc.key ], [ true ])
});
}
});这种数据“集成”只是一个草案,可以用许多不同的方式加以改进。它可以使用自定义发布方法在服务器端完成。
https://stackoverflow.com/questions/33356437
复制相似问题