Files
2021-07-15 13:04:11 +05:30

4.9 KiB
Raw Permalink Blame History

id, title, challengeType, forumTopicId, dashedName
id title challengeType forumTopicId dashedName
5e601c775ac9d0ecd8b94aff 安全的实时多人游戏 4 462375 secure-real-time-multiplayer-game

--description--

使用 HTML Canvas API 和 Socket.io 开发一个 2D 实时多人游戏,其功能与此类似:https://secure-real-time-multiplayer-game.freecodecamp.rocks/。 在这个项目中,你将使用以下方法之一编写你的代码:

完成本项目后,请将一个正常运行的 demo项目演示托管在可以公开访问的平台。 然后在 Solution Link 框中提交你的项目 URL。 此外,还可以将项目的源码提交到 GitHub Link 中。

--instructions--

注意 helmet@^3.21.3 是用户故事所必需的。 这意味着你需要使用以前版本的 Helmet 的文档,了解如何实现用户故事的信息。

--hints--

提交自己的项目,而不是示例的 URL。

(getUserInput) => {
  assert(
    !/.*\/secure-real-time-multiplayer-game\.freecodecamp\.rocks/.test(
      getUserInput('url')
    )
  );
};

多个玩家可以连接到一台服务器游玩。


每个玩家都有头像。


每个玩家都由在 Player.mjs 中创建的 Player 类对象来代表。


至少,每个玩家对象应该包含一个唯一的 id、一个 score,以及代表玩家当前位置的 xy 坐标。


游戏至少有一种类型的可收藏物品。 在 Collectible.mjs 中完成 Collectible 类来实现这一点。


至少,每个由 Collectible 类创建的可收集物品对象应该包含一个唯一的 id、一个 value,以及代表该物品当前位置的 xy 坐标。


玩家可以使用 WASD 或方向键移动头像。 完成 Player.mjs 中的 movePlayer 方法来实现这一功能。


movePlayer 方法应该接受两个参数:一个是 “up”、“down”、“left” 或 “right” 的字符串,另一个是玩家角色位置应该改变的像素数量。 movePlayer 应该调整它所调用的玩家对象的 xy 坐标。


用玩家的分数来计算他们相对其他玩家的名次。 在 Player 类中完成 calculateRank 方法来实现这个。


calculateRank 方法应该接受一个代表所有在线玩家的对象数组,并返回字符串 Rank: currentRanking/totalPlayers。 例如,在一局有两个玩家的游戏中,如果玩家 A 的分数是 3玩家 B 的分数是 5那么玩家 A 的 calculateRank 应该返回 Rank: 2/2


玩家可以与可收集物品发生碰撞。 完成 Player.mjs 中的 collision 方法来实现这一点。


collision 方法应该接受一个可收集物品的对象作为参数。 如果玩家的头像与物品相交,collision 方法应该返回 true


所有玩家都保持游戏状态同步。


玩家可以随时断开与游戏的连接。


阻止客户端试图猜测/嗅探 MIME 类型。

async (getUserInput) => {
  const data = await fetch(getUserInput('url') + '/_api/app-info');
  const parsed = await data.json();
  assert.equal(parsed.headers['x-content-type-options'], 'nosniff');
};

防止跨站脚本XSS攻击。

async (getUserInput) => {
  const data = await fetch(getUserInput('url') + '/_api/app-info');
  const parsed = await data.json();
  assert.equal(parsed.headers['x-xss-protection'], '1; mode=block');
};

客户端没有缓存任何网站内容。

async (getUserInput) => {
  const data = await fetch(getUserInput('url') + '/_api/app-info');
  const parsed = await data.json();
  assert.equal(parsed.headers['surrogate-control'], 'no-store');
  assert.equal(
    parsed.headers['cache-control'],
    'no-store, no-cache, must-revalidate, proxy-revalidate'
  );
  assert.equal(parsed.headers['pragma'], 'no-cache');
  assert.equal(parsed.headers['expires'], '0');
};

请求头显示该网站是由 “PHP 7.4.3” 驱动的,尽管实际并非如此(作为一种安全防御措施)。

async (getUserInput) => {
  const data = await fetch(getUserInput('url') + '/_api/app-info');
  const parsed = await data.json();
  assert.equal(parsed.headers['x-powered-by'], 'PHP 7.4.3');
};

--solutions--

/**
  Backend challenges don't need solutions,
  because they would need to be tested against a full working project.
  Please check our contributing guidelines to learn more.
*/