全部 / 技术交流 · 2023年1月11日 0

Steam游戏信息查询程序设计(node.js)

本文最后更新于 469 天前,其中的信息可能已经有所发展或改变。

另一种实现方案

使用Vgtime的检索后,这个插件仍然存在几个问题:

  • Vgtime本身的搜索功能就比较垃圾(这是编辑老师说的..)
  • 游戏范围限定在了Steam平台,这对于主机群来说太致命了
  • 据使用者反馈,Steam的官方API在国内访问十分缓慢,时常出现请求失败

想解决它们,必须换一种思路。

不仅白嫖搜索框,还要白嫖游戏库!

其实在我的手机上,二柄的游戏检索功能可能是体验最好的,它可以实现中英文搜索、词汇联想,甚至是拼写纠正。但在使用app的搜索功能时,貌似需要登陆账号,尝试对其进行抓包:

>> 本文件内容为 https://v2.diershoubing.com/eb/combine_game/versions/?src=ios&version=9.54&auth=//&game_id=104808&plat_name=psn&platform_info=1 的请求抓包详情,供您分析和定位问题。

1. 请求内容 Request:

GET /eb/combine_game/versions/?src=ios&version=9.54&auth=c930cae3aa14cbae19a688c3f70d7b12&game_id=104808&plat_name=psn&platform_info=1 HTTP/1.1
Host: v2.diershoubing.com
Accept: */*
Cookie: //
User-Agent: erbinghd/9.54 (com.diershoubing.erbing; build:187; iOS 16.3.0) Alamofire/5.6.2
Accept-Language: zh-Hans-CN;q=1.0
Accept-Encoding: br;q=1.0, gzip;q=0.9, deflate;q=0.8
Connection: keep-alive
Markdown

惊讶地发现,调用其搜索功能时并不需要加上Cookie,于是事情就容易多了

const response = await axios.get(`https://v2.diershoubing.com/eb/combine_game/search/?src=ios&version=9.54&search_name=${text}`);
    const gamedata = response.data.combine_games
    const chinese_name = gamedata[0].name
    const game_id = gamedata[0].game_id
    signal = true;
  session.send(`\n猜你想搜:${chinese_name}\n\n如果您对搜索结果不满意,请回复“错误的”`);
  session.execute(`id ${game_id}`);
  signal = false;
  session.prompt((session) => {
    const appid = session.content;
if (appid == "错误的") {
const games = gamedata.slice(0, 10).map((game) => `游戏名称:${game.name},name_id:${game.game_id}`).join('\n')

  session.send(games + "\n\n请输入您需要的name_id");
  session.prompt((session) => {
       const appid = session.content.match(/\d+/);
if (appid) {
     session.execute(`id ${appid}`);
     signal = false;
} else {
  return session.send("请输入正确的name_id");
}
});
} else {
  return;
}
});
  });
JavaScript

首先调用搜索功能,默认获取第一个游戏的ID,并执行下一个命令“id”查询具体信息,如果错误再显示全部搜索结果。下面定义ID命令:

ctx
    .command("id <appid>", "检索游戏的game_id")
    .alias('id:', 'ID' , 'game_id')
  .action(async ({ session }, appid) => {
      let response;
    const link = `https://v2.diershoubing.com/eb/combine_game/detail/${appid}/?src=ios&version=9.54&pf=1`;
    response = await axios.get(link)
   if (response.ret === "-1") {
        return 'name_id不存在!';
   }else{
    const data = response.data.combine_game;
    const values = [];
    
    if (data.name) {
      values.push(`名称:${data.name}`);
    }

 if (data.desc && config.desc) {
      values.push(`简介:${data.desc}`);
    }
    
    if (config.is_cn) {
        if(data.is_cn){
      values.push(`中文支持:True`);
        }else{
            values.push(`中文支持:False`);
        }
    }
    
    if (data.release_date && config.date) {
      let dateString = data.release_date;
      let date = new Date(dateString);
      let formattedDate = date.toLocaleDateString("zh-cn", {year: 'numeric', month: 'long', day: 'numeric'});
      values.push(`发售日期:${formattedDate}`);
    }

    if (data.tag && config.tag) {
      values.push(`标签:${data.tag}`);
      
}

    if (data.price_detail && config.price ) {
      let priceDetails = data.price_detail.map(price => 
        `平台名称: ${price.platform_name},史低:${price.history_price},原价:${price.origin_price},现价: ${price.price}\n`
      );
      values.push(`全区售价:${priceDetails.join('')
      }`);
    }
if (data.played_rating && config.played_rating) {
      values.push(`玩家评分:${data.played_rating}`);
    }
    
    
    
     if (response.data.medium_ratings && config.medium_ratings ) {
    const ratings = response.data.medium_ratings.map(rating => 
        `媒体: ${rating.source_name},评分:${rating.rating}\n`
      );
values.push(`\n${ratings.join('')}`);

}
let imageData = null;
    let image1 = null;

    if (data.game_photo) {
      imageData = await ctx.http.get(data.game_photo, { responseType: 'arraybuffer' });
    }

    if (data.img) {
      image1 = await ctx.http.get(data.img, { responseType: 'arraybuffer' });
}

// 将图片数据拼接在返回的字符串中

let result = values.join('\n');

if (imageData) {
  result += koishi_1.segment.image(imageData);
}

if (image1) {
  result += koishi_1.segment.image(image1);
}

return result;
    
  } 
JavaScript

到了这里,实现了全平台游戏、强大的中文检索、无需科学环境三个目标!

还有更多

进一步抓包可以发现,二柄app内似乎所有的内容未经加密,甚至不需要cookie,那意味着它们全部可以为己所用。

if (config.comments) {
      const link = `https://v2.diershoubing.com/eb/combine_comment/list/game/${appid}/?src=ios&version=9.54&has_filter=1&is_load_steam_review=1&pn=0&rn=20`;
    response = await axios.get(link)
    if(response.data.combine_comments){
    const data_comments = response.data.combine_comments;
    const comments = data_comments.splice(0, 3).map(comment => 
        `${comment.content}\n`
      );
      values.push(`评论:${comments.join('')}`);
    }
JavaScript

以上代码调用了评论的接口,在返回游戏信息上加上评论!

ctx
    .command("打折游戏", "查询精选的打折作品")
  .action(async ({ session }) => {
      const url = (`https://v2.diershoubing.com/eb/combine_game/discount/?src=ios&version=9.54&rn=20`);
      const response = await axios.get(url);
      const ratings = response.data.combine_games.slice(0,config.limit).map(game => 
        `【名称: 《${game.name}》,平台:${game.plat_name},原价: ${game.origin_price},折后价: ${game.price},优惠期截至: ${game.price_expired}\n\n`
      );
      const values = [];
          let imageData = null;
    let image1 = null;
      values.push(`近期优惠一览:${ratings.join('')}`);
       if (response.data.combine_games[0].img) {
      imageData = await ctx.http.get(response.data.combine_games[0].img, { responseType: 'arraybuffer' });
    }

    if (response.data.combine_games[1].img) {
      image1 = await ctx.http.get(response.data.combine_games[1].img, { responseType: 'arraybuffer' });
}
let result = values.join('\n');

if (imageData) {
  result += koishi_1.segment.image(imageData);
}

if (image1) {
  result += koishi_1.segment.image(image1);
}

return result;
JavaScript

又或者是调出二柄整理好的打折清单,可以做到的事情太多了。

实现效果

总结与未来

npm

插件上线一周内,它的下载了已经突破了一千,我也收到不少用户反馈,这篇文章中的代码已是多次迭代后的结果,未来一定会更加完善。

既然游戏查询完成了,那么一个查询用户的插件如何?当群内发现逆天言论时,不妨查查他的成分,若是看见某款开发时间RPG游戏,那一切可能就顺理成章了~

但无论是Steam、Xbox、PS还是NS,官方都没有提供任何有关用户信息的接口,需要自己想办法实现。我也发现了一个可能成功的库。

psn-api - npm
A well-tested library that lets you get trophy, user, and game data from the PlayStation Network.. Latest version: 2.8.3, last published: 23 days ago. Start using psn-api in your project by running `npm i psn-api`. There is 1 other project in the npm registry using psn-api.
www.npmjs.com
文章分页:上一页 1 2 3
页面: 1 2 3