diff options
author | Colin Reeder | 2022-04-19 22:09:46 -0600 |
---|---|---|
committer | Colin Reeder | 2022-04-19 22:09:46 -0600 |
commit | 239e2e7cc1e3604a0d8986e17b4c30f89f3b9e91 (patch) | |
tree | 3389aca9cd06d021321f69aea90917e8410cf227 | |
parent | e6471f3af5b9d008e2327995a92cc56402bc8baa (diff) | |
download | aur-239e2e7cc1e3604a0d8986e17b4c30f89f3b9e91.tar.gz |
Update to 7.15.2, use fairy-stockfish for offline play
-rw-r--r-- | .SRCINFO | 15 | ||||
-rw-r--r-- | PKGBUILD | 27 | ||||
-rw-r--r-- | README.md | 2 | ||||
-rw-r--r-- | index.js | 9 | ||||
-rw-r--r-- | native-stockfish.patch | 152 | ||||
-rw-r--r-- | preload.js | 27 |
6 files changed, 218 insertions, 14 deletions
@@ -1,20 +1,23 @@ pkgbase = lichobile-electron pkgdesc = lichess.org mobile application, packaged with electron - pkgver = 7.11.3 - pkgrel = 3 + pkgver = 7.15.2 + pkgrel = 4 url = https://lichess.org/mobile arch = any license = GPL-3.0-or-later makedepends = npm - depends = electron - source = https://github.com/veloce/lichobile/archive/refs/tags/v7.11.3.tar.gz + source = https://github.com/veloce/lichobile/archive/refs/tags/v7.15.2.tar.gz source = appconfig.prod.json source = run.sh source = lichobile-electron.desktop source = lichesslogowhite.svg source = hide-scrollbar.patch + source = native-stockfish.patch source = index.js - sha256sums = 27719c7be577931e8b2020d6e27760a00982b55efd1d6a507128e0f2168224a6 + source = preload.js + sha256sums = 62d2922ee28d706e7a164629e41e516d203772fc69a3f7a30dc19239f2fb352b + sha256sums = SKIP + sha256sums = SKIP sha256sums = SKIP sha256sums = SKIP sha256sums = SKIP @@ -23,3 +26,5 @@ pkgbase = lichobile-electron sha256sums = SKIP pkgname = lichobile-electron + depends = electron + depends = fairy-stockfish @@ -1,23 +1,34 @@ +shopt -s globstar + _pkgname=lichobile pkgname="$_pkgname-electron" -pkgver=7.11.3 -pkgrel=3 +pkgver=7.15.2 +pkgrel=4 pkgdesc="lichess.org mobile application, packaged with electron" arch=(any) url="https://lichess.org/mobile" license=("GPL-3.0-or-later") -depends=(electron) makedepends=(npm) -source=("https://github.com/veloce/lichobile/archive/refs/tags/v$pkgver.tar.gz" "appconfig.prod.json" "run.sh" "lichobile-electron.desktop" "lichesslogowhite.svg" "hide-scrollbar.patch" "index.js") -sha256sums=("27719c7be577931e8b2020d6e27760a00982b55efd1d6a507128e0f2168224a6" "SKIP" "SKIP" "SKIP" "SKIP" "SKIP" "SKIP") +source=("https://github.com/veloce/lichobile/archive/refs/tags/v$pkgver.tar.gz" "appconfig.prod.json" "run.sh" "lichobile-electron.desktop" "lichesslogowhite.svg" "hide-scrollbar.patch" "native-stockfish.patch" "index.js" "preload.js") +sha256sums=('62d2922ee28d706e7a164629e41e516d203772fc69a3f7a30dc19239f2fb352b' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP' + 'SKIP') prepare() { cd "$_pkgname-$pkgver" - npm install cp ../appconfig.prod.json ./ patch -Np1 -i ../hide-scrollbar.patch + patch -Np1 -i ../native-stockfish.patch + + npm install } build() { @@ -26,6 +37,8 @@ build() { } package() { + depends=(electron fairy-stockfish) + cd "$_pkgname-$pkgver" install -d "$pkgdir"/usr/share/webapps/$_pkgname @@ -37,6 +50,6 @@ package() { install -Dm644 -t "$pkgdir"/usr/share/applications ../lichobile-electron.desktop install -Dm644 -t "$pkgdir"/usr/share/icons/hicolor/scalable/apps ../lichesslogowhite.svg - install -Dm644 -t "$pkgdir"/usr/lib/$pkgname ../index.js + install -Dm644 -t "$pkgdir"/usr/lib/$pkgname ../index.js ../preload.js ln -s /usr/share/webapps/$_pkgname "$pkgdir"/usr/lib/$pkgname/www } diff --git a/README.md b/README.md index 8d27da60637b..b3992317cdd1 100644 --- a/README.md +++ b/README.md @@ -5,4 +5,4 @@ A set of files to allow the lichess mobile app to run on linux mobile platforms Currently an Arch package is provided, but it should be possible to do something similar for other distros. ## Known Issues -- Local Stockfish doesn't work +- AI sometimes plays multiple moves in offline games @@ -1,7 +1,14 @@ const { app, BrowserWindow } = require("electron"); +const path = require("path"); app.whenReady().then(() => { - const mainWindow = new BrowserWindow({autoHideMenuBar: true, backgroundColor: "#161512"}); + const mainWindow = new BrowserWindow({ + autoHideMenuBar: true, + backgroundColor: "#161512", + webPreferences: { + preload: path.join(app.getAppPath(), "preload.js"), + }, + }); mainWindow.loadFile("www/index.html"); mainWindow.webContents.session.webRequest.onBeforeSendHeaders( {urls: ["wss://socket.lichess.org/*"]}, diff --git a/native-stockfish.patch b/native-stockfish.patch new file mode 100644 index 000000000000..8457babc9669 --- /dev/null +++ b/native-stockfish.patch @@ -0,0 +1,152 @@ +diff --git a/src/stockfish/index.ts b/src/stockfish/index.ts +index 75cf3ec01..0adb23643 100644 +--- a/src/stockfish/index.ts ++++ b/src/stockfish/index.ts +@@ -1,58 +1,69 @@ +-import { Capacitor, registerPlugin } from '@capacitor/core' +-import { Stockfish, StockfishPlugin as IStockfishPlugin } from 'capacitor-stockfish' + import { VariantKey } from '../lichess/interfaces/variant' +-import settings from '../settings' + +-export const StockfishVariants = registerPlugin<IStockfishPlugin>('StockfishVariants', { +- web: () => import('./StockfishVariantsWeb').then(m => new m.StockfishVariantsWeb()), +-}) ++// stub for externally used functionality ++export const StockfishVariants = { ++ getMaxMemory: () => Promise.reject("unimplemented"), ++ getCPUArch: () => Promise.reject("unimplemented"), ++}; ++ ++interface INativeEngine { ++ send(line: string): void; ++ addListener(listener: (line: string) => void): void; ++ removeListener(listener: (line: string) => void): void; ++ kill(): boolean; ++} ++ ++declare const startStockfish: () => INativeEngine; + + export class StockfishPlugin { +- private plugin: IStockfishPlugin ++ private engine: INativeEngine | undefined ++ private startPromise: Promise<{ engineName: string }> | undefined + + constructor(readonly variant: VariantKey) { +- this.plugin = !this.isVariant() && +- canUseNNUE() && +- settings.analyse.cevalUseNNUE() ? Stockfish : StockfishVariants + } + + public async start(): Promise<{ engineName: string }> { +- return new Promise((resolve) => { +- let engineName = 'Stockfish' +- const listener = (e: Event) => { +- const line = (e as any).output +- console.debug('[stockfish >>] ' + line) +- if (line.startsWith('id name ')) { +- engineName = line.substring('id name '.length) +- } +- if (line.startsWith('uciok')) { +- window.removeEventListener('stockfish', listener, false) +- resolve({ engineName }) +- } +- } +- window.addEventListener('stockfish', listener, { passive: true }) +- this.plugin.start() +- .then(() => this.send('uci')) +- }) ++ console.log('trying to start stockfish') ++ if(typeof this.startPromise === 'undefined') { ++ this.startPromise = new Promise<{engineName: string}>((resolve) => { ++ let engineName = 'Stockfish' ++ this.engine = startStockfish(); ++ ++ const listener = (line: string) => { ++ console.debug('[stockfish >>] ' + line) ++ if (line.startsWith('id name ')) { ++ engineName = line.substring('id name '.length) ++ } ++ if (line.startsWith('uciok')) { ++ this.engine!.removeListener(listener) ++ resolve({ engineName }) ++ } ++ } ++ this.engine.addListener(listener) ++ this.send('uci') ++ }) ++ } ++ ++ return this.startPromise + } + + public isReady(): Promise<void> { + return new Promise((resolve) => { +- const listener = (e: Event) => { +- const line = (e as any).output ++ const listener = (line: string) => { + if (line.startsWith('readyok')) { +- window.removeEventListener('stockfish', listener, false) ++ this.engine!.removeListener(listener) + resolve() + } + } +- window.addEventListener('stockfish', listener, { passive: true }) ++ this.engine!.addListener(listener) + this.send('isready') + }) + } + + public send(text: string): Promise<void> { + console.debug('[stockfish <<] ' + text) +- return this.plugin.cmd({ cmd: text }) ++ this.engine!.send(text) ++ return Promise.resolve() + } + + public setOption(name: string, value: string | number | boolean): Promise<void> { +@@ -61,10 +72,8 @@ export class StockfishPlugin { + + public setVariant(): Promise<void> { + if (this.isVariant()) { +- if (Capacitor.getPlatform() !== 'web' && this.variant === 'threeCheck') ++ if (this.variant === 'threeCheck') + return this.setOption('UCI_Variant', '3check') +- if (Capacitor.getPlatform() === 'web' && this.variant === 'antichess') +- return this.setOption('UCI_Variant', 'giveaway') + else + return this.setOption('UCI_Variant', this.variant.toLowerCase()) + } else { +@@ -73,7 +82,11 @@ export class StockfishPlugin { + } + + public exit(): Promise<void> { +- return this.plugin.exit() ++ if(this.engine!.kill()) { ++ return Promise.resolve() ++ } else { ++ return Promise.reject('Failed to kill process') ++ } + } + + private isVariant() { +@@ -95,11 +108,13 @@ export function getNbCores(): number { + } + + export function canUseNNUE(): boolean { +- if (Capacitor.getPlatform() === 'android') { +- return window.lichess.cpuArch === 'arm64-v8a' +- } else if (Capacitor.getPlatform() === 'ios') { +- return true +- } else { +- return false +- } ++ // TODO maybe later ++ return false + } ++ ++window.addEventListener("stockfish-outer" as any, (evt: CustomEvent) => { ++ const newEvent = new CustomEvent("stockfish"); ++ (newEvent as any).output = evt.detail; ++ ++ window.dispatchEvent(newEvent); ++}); diff --git a/preload.js b/preload.js new file mode 100644 index 000000000000..ae186cf8a16a --- /dev/null +++ b/preload.js @@ -0,0 +1,27 @@ +const childProcess = require("child_process"); +const { contextBridge } = require("electron"); +const readline = require("readline"); + +function startStockfish() { + const proc = childProcess.exec("fairy-stockfish"); + const reader = readline.createInterface(proc.stdout); + + console.log("starting stockfish"); + + reader.on("line", line => { + const evt = new CustomEvent("stockfish-outer", {detail: line}); + window.dispatchEvent(evt); + }); + + return { + send: line => { + console.log("sending", line); + proc.stdin.write(line + "\r\n"); + }, + addListener: listener => reader.on("line", listener), + removeListener: listener => reader.off("line", listener), + kill: () => proc.kill(), + }; +} + +contextBridge.exposeInMainWorld("startStockfish", startStockfish); |