LmeSzinc / StarRailCopilot

崩坏:星穹铁道脚本 | Honkai: Star Rail auto bot (简体中文/繁體中文/English/Español)
GNU General Public License v3.0
2.97k stars 146 forks source link

云星穹铁道适配 | Support cloud HSR #300

Open LmeSzinc opened 7 months ago

LmeSzinc commented 7 months ago

要做的肯定是网页端,有跨平台优势,web生态也丰富。因为云游戏是画面串流,所以你可以在无 GPU 的服务器上运行并且占用很低,对,就是那种常见的云服务器。这下游戏都完全上云了,让我看看谁还在玩星穹铁道

目前还在选择技术栈,需要决定的事情:

  1. 无头浏览器的选择:Playwright / Puppeteer / DrissionPage,selenium已死,需要评估获取画面和操作网页的性能
  2. 画面捕获方式的选择:全屏截图/解码串流画面。全屏截图的话,性能肯定就差点。解码的话,还得再研究一下,未来也要看米桑脸色,改了接口啥的也要跟着更新
Asxcvbn commented 7 months ago

仅以当前版本的云铁道而言,这个方式已经可以获取截图:

function getscreenshot(){
    const video = document.querySelector('.game-player__video');

    // Create a canvas element
    const canvas = document.createElement('canvas');
    canvas.width = video.videoWidth;
    canvas.height = video.videoHeight;

    // Draw the video frame onto the canvas
    const ctx = canvas.getContext('2d');
    ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

    // Convert the canvas content to a data URL
    const dataURL = canvas.toDataURL('image/png');

    // Create a link for downloading the screenshot
    const a = document.createElement('a');
    a.href = dataURL;
    a.download = 'screenshot.png';
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
};
getscreenshot();

运行后会下载一个图片。。 但是不排除什么时候米忽悠会把“.game-player__video”这个video元素名称改掉那样肯定也要跟着改

运行一下得200ms, 似乎有点慢= =

console.time('screenshot');
getscreenshot();
console.timeEnd('screenshot')
screenshot:219 毫秒 - 倒计时结束

当前采用的1920x1080分辨率,降低分辨率也许可以提高速度。。

Asxcvbn commented 7 months ago

不过话说回来我把画质调到最低,得到的canvas还是1920x1080的

aaahai00 commented 7 months ago

我感觉全屏截图好点,性能虽然差点,但胜在稳定

aaahai00 commented 7 months ago

仅以当前版本的云铁道而言,这个方式已经可以获取截图:

function getscreenshot(){
  const video = document.querySelector('.game-player__video');

  // Create a canvas element
  const canvas = document.createElement('canvas');
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;

  // Draw the video frame onto the canvas
  const ctx = canvas.getContext('2d');
  ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

  // Convert the canvas content to a data URL
  const dataURL = canvas.toDataURL('image/png');

  // Create a link for downloading the screenshot
  const a = document.createElement('a');
  a.href = dataURL;
  a.download = 'screenshot.png';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
};
getscreenshot();

运行后会下载一个图片。。 但是不排除什么时候米忽悠会把“.game-player__video”这个video元素名称改掉那样肯定也要跟着改

运行一下得200ms, 似乎有点慢= =

console.time('screenshot');
getscreenshot();
console.timeEnd('screenshot')
screenshot:219 毫秒 - 倒计时结束

当前采用的1920x1080分辨率,降低分辨率也许可以提高速度。。

后面应该会把分辨率限制成1280×720,毕竟现在模拟器运行的就是这个,分辨率一致的话没那么容易出奇怪的问题

Asxcvbn commented 7 months ago

问题就是游戏内改画质死活都是1920x1080,似乎改不动分辨率,虽然也可能是我没测试到,但是我测试结果是没法改分辨率,实际要改可能只能做点hack什么的,那就更不好支持了

jerrita commented 7 months ago

方便抽象个接口来适应不同后端吗,就不用管后端是安卓、web串流还是pc触屏版了

wing1215 commented 5 months ago

模拟器云崩铁,云崩铁有个客户端,可以手机下载,当使用模拟器运行云崩铁时,不就和正常的差不太多了吗,网页云崩铁太玄幻了。而且我试了一下,竟然可以完美运行,牛逼!! ![Uploading {B5119996-DE06-49fa-8F31-3F7627B47959}.png…]()

aaahai00 commented 5 months ago

模拟器云崩铁,云崩铁有个客户端,可以手机下载,当使用模拟器运行云崩铁时,不就和正常的差不太多了吗,网页云崩铁太玄幻了。而且我试了一下,竟然可以完美运行,牛逼!! ![Uploading {B5119996-DE06-49fa-8F31-3F7627B47959}.png…]()

出错强制关闭游戏就翻车了,他会直接启动正常的客户端,而且这里应该是想用网页后台全自动运行,这样就不用挂个模拟器那么麻烦的东西了而且还占性能

aaahai00 commented 5 months ago

模拟器云崩铁,云崩铁有个客户端,可以手机下载,当使用模拟器运行云崩铁时,不就和正常的差不太多了吗,网页云崩铁太玄幻了。而且我试了一下,竟然可以完美运行,牛逼!! ![Uploading {B5119996-DE06-49fa-8F31-3F7627B47959}.png…]()

我一开始提的也是这么运行的,只要跟国际服一样做一个单独支持比较简单就可以搞定,替换启动游戏的包名,在单独识别启动游戏和排队的页面,后面启动游戏流程就差不多了

但开发者提的这想法如果实行它可以在一些性能比较烂的服务器上运行,并且可以轻松多开,不用忍受模拟器那一大坨的性能占用了

aaahai00 commented 3 months ago

模拟器云崩铁,云崩铁有个客户端,可以手机下载,当使用模拟器运行云崩铁时,不就和正常的差不太多了吗,网页云崩铁太玄幻了。而且我试了一下,竟然可以完美运行,牛逼!! ![Uploading {B5119996-DE06-49fa-8F31-3F7627B47959}.png…]()

踢一脚,其实早就支持了,但我没发现

shunia commented 3 months ago

如果是要获取网页端的图像,不需要用2L的方法,性能太低,而且图片落盘后还需要再通过IO读取。

context.getImageData()这个API可以获取canvas指定区域的图像数据-一个一维的RGBA数组,其实也就是bitmap,拿到这个数据之后其实就可以做图像处理了。

如果只能依赖png或者jpeg编码的话可以拿这个图像数据再处理。