Compare commits
87 Commits
Author | SHA1 | Date | |
---|---|---|---|
ef3409419a | |||
6aed0296ee | |||
022e2f1b53 | |||
27cf5b077a | |||
c8e0d5042e | |||
82b352d827 | |||
e94ebecfa2 | |||
123fadd7ac | |||
3fbfb38a53 | |||
83e34a983c | |||
53b16c9d35 | |||
4c940403bd | |||
f82d767a19 | |||
d385fdd64c | |||
ce15113a7a | |||
23179c0266 | |||
b8dde0ff52 | |||
3df126d700 | |||
e045169d99 | |||
414681fc0b | |||
691d140db5 | |||
96cf7dfe74 | |||
576470f70a | |||
625e456e6b | |||
|
2a17547da3 | ||
|
fb46147547 | ||
d37c7514f3 | |||
7fe6187f98 | |||
0bbb560b48 | |||
d583c396b1 | |||
2096022bd4 | |||
e3c342c07b | |||
ee6c7c45d8 | |||
76d5d60c2b | |||
00dd3283e9 | |||
b2998ffe80 | |||
579663c32c | |||
717284ad14 | |||
197f0a9dca | |||
b1e455ca48 | |||
86bc122c5f | |||
0ca2e4f01b | |||
4e14f35021 | |||
10d94886a5 | |||
e57ac28cde | |||
5853fc68c2 | |||
aa039277a9 | |||
d759f81905 | |||
a0b673afb0 | |||
b9fd45980f | |||
31aeb66cd4 | |||
896214d2b7 | |||
6df4263107 | |||
373bc98869 | |||
2a9df20b5c | |||
0e4afd90d9 | |||
0dc3a079ee | |||
898f873cec | |||
de79106d61 | |||
543571d66b | |||
f2acfcc4be | |||
5a0aa5160c | |||
|
abf6d4903f | ||
|
5bcb05142c | ||
|
b358b56974 | ||
|
ef1b7800c6 | ||
|
0b2a8e7821 | ||
|
9608ce6bfc | ||
|
0e21b7187d | ||
b277bb25b4 | |||
35416ce12b | |||
8ccd721c98 | |||
0f6f24aa95 | |||
6bdfd5a9ef | |||
27817c824e | |||
06c763d862 | |||
4937e60333 | |||
6775f5433d | |||
eeeff8429a | |||
1d3ca4bf2d | |||
59e2ccfd63 | |||
f716c22e76 | |||
9c86d23d31 | |||
4e3b49007d | |||
0a2c8bbdab | |||
0c1ab111a6 | |||
8092d608c3 |
26
.github/workflows/auto-building.yml
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
name: Auto Building Wine Runner
|
||||
run-name: ${{ github.actor }} Auto Building Wine Runner 🚀
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
jobs:
|
||||
Explore-GitHub-Actions:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Building DEB
|
||||
run: |
|
||||
# 配置环境
|
||||
sudo apt update
|
||||
sudo apt install git dpkg-dev qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools qt5-qmake -y
|
||||
git clone https://github.com/gfdgd-xi/uengine-runner
|
||||
cd uengine-runner
|
||||
make build
|
||||
mv com.gitee.uengine.runner.spark.deb ~
|
||||
- name: upload result
|
||||
uses: actions/upload-artifact@v1
|
||||
with:
|
||||
name: com.gitee.uengine.runner.spark.deb
|
||||
path: /home/runner/com.gitee.uengine.runner.spark.deb
|
||||
|
||||
|
||||
|
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
__pycache__
|
BIN
APK/Via.apk
Normal file
@ -35,9 +35,9 @@ print("""译文:一轮缓缓移动的秋月洒下万里金波,就像那刚
|
||||
我要乘风飞上万里长空,俯视祖国的大好山河。还要砍去月中摇曳的桂树枝柯,人们说,这将使月亮洒下人间的光辉更多。""")
|
||||
print("================================")
|
||||
urlSourcesList = [
|
||||
"https://code.gitlink.org.cn/gfdgd_xi/uengine-runner-list/raw/branch/master/auto", # Gitlink 源
|
||||
"http://config.uengine-runner.gfdgdxi.top/", # Github 源
|
||||
"https://gitee.com/gfdgd-xi/uengine-wine-runner-auto-configuration-script/raw/master/", # Gitee 源
|
||||
"https://gfdgd-xi.github.io/uengine-wine-runner-auto-configuration-script/", # Github 源
|
||||
"https://code.gitlink.org.cn/gfdgd_xi/uengine-runner-list/raw/branch/master/auto", # Gitlink 源
|
||||
"http://gfdgdxi.msns.cn/uengine-runner-list/auto/", # 备用源1,纯 IPv6 源
|
||||
"http://gfdgdxi.free.idcfengye.com/uengine-runner-auto-configuration-script/", # 备用源2
|
||||
"http://gfdgdxi.free.idcfengye.com/uengine-runner-list/auto/", # 备用源 3
|
||||
@ -146,7 +146,7 @@ class InformationWindow():
|
||||
about = f"<h1>关于“{choose}”的介绍</h1>\n<p>暂无此程序的介绍</p>"
|
||||
try:
|
||||
import requests as r
|
||||
fenlists = requests.get(base64.b64decode("aHR0cHM6Ly9jb2RlLmdpdGxpbmsub3JnLmNuL2dmZGdkLXhpLW9yZy93aW5lLXJ1bm5lci1kb3dubG9hZHMtb2YtcnVubmVyL3Jhdy9icmFuY2gvbWFzdGVyL0Jhc2hBcHBGZW4v").decode("utf-8") + urllib.request.quote(fileName) + base64.b64decode("L2FsbC5qc29u").decode("utf-8"), timeout=1000).json()
|
||||
fenlists = requests.get("http://data.download.gfdgdxi.top/BashAppFen/" + urllib.request.quote(fileName) + base64.b64decode("L2FsbC5qc29u").decode("utf-8"), timeout=1000).json()
|
||||
tipsInfo = ""
|
||||
except:
|
||||
fenlists = [0, 0, 0, 0, 0]
|
||||
@ -166,19 +166,19 @@ class InformationWindow():
|
||||
if maxHead > 5:
|
||||
for i in range(end):
|
||||
if webeng:
|
||||
starHtml += f"<img src='https://code.gitlink.org.cn/gfdgd_xi/deep-wine-runner/raw/branch/main/Icon/BadStar.svg' width=50>\n"
|
||||
starHtml += f"<img src='http://wine-runner.gfdgdxi.top/Icon/BadStar.svg' width=50>\n"
|
||||
else:
|
||||
starHtml += f"<img src='{programPath}/Icon/BadStar.svg' width=50>\n"
|
||||
else:
|
||||
for i in range(maxHead):
|
||||
if webeng:
|
||||
starHtml += f"<img src='https://code.gitlink.org.cn/gfdgd_xi/deep-wine-runner/raw/branch/main/Icon/Star.svg' width=50>\n"
|
||||
starHtml += f"<img src='http://wine-runner.gfdgdxi.top/Icon/Star.svg' width=50>\n"
|
||||
else:
|
||||
starHtml += f"<img src='{programPath}/Icon/Star.svg' width=50>\n"
|
||||
head = maxHead
|
||||
for i in range(head, end):
|
||||
if webeng:
|
||||
starHtml += f"<img src='https://code.gitlink.org.cn/gfdgd_xi/deep-wine-runner/raw/branch/main/Icon/UnStar.svg' width=50>"
|
||||
starHtml += f"<img src='http://wine-runner.gfdgdxi.top/Icon/UnStar.svg' width=50>"
|
||||
else:
|
||||
starHtml += f"<img src='{programPath}/Icon/UnStar.svg' width=50>"
|
||||
about += f"\n<hr/><h1>评分情况</h1>\n<p align='center'>{starHtml}</p>\n<p align='center'>{tipsInfo}</p>"
|
||||
@ -260,7 +260,7 @@ class ProgramRunStatusShow():
|
||||
fileName = i[1]
|
||||
break
|
||||
try:
|
||||
fenlists = requests.get(base64.b64decode("aHR0cHM6Ly9jb2RlLmdpdGxpbmsub3JnLmNuL2dmZGdkLXhpLW9yZy93aW5lLXJ1bm5lci1kb3dubG9hZHMtb2YtcnVubmVyL3Jhdy9icmFuY2gvbWFzdGVyL0Jhc2hBcHBGZW4v").decode("utf-8") + urllib.request.quote(fileName) + base64.b64decode("L2FsbC5qc29u").decode("utf-8")).json()
|
||||
fenlists = requests.get("http://data.download.gfdgdxi.top/BashAppFen/" + urllib.request.quote(fileName) + base64.b64decode("L2FsbC5qc29u").decode("utf-8")).json()
|
||||
tipsInfo = ""
|
||||
except:
|
||||
#traceback.print_exc()
|
||||
@ -318,7 +318,7 @@ class ProgramRunStatusShow():
|
||||
else:
|
||||
# 显示最新的3条评论
|
||||
try:
|
||||
all = int(requests.get(f"{base64.b64decode('aHR0cHM6Ly9jb2RlLmdpdGxpbmsub3JnLmNuL2dmZGdkLXhpLW9yZy9iYXNocGlubHVuL3Jhdy9icmFuY2gvbWFzdGVyLw==').decode('utf-8')}{urllib.request.quote(fileName)}/data.txt").text)
|
||||
all = int(requests.get(f"http://bashpinlun.gfdgdxi.top/{urllib.request.quote(fileName)}/data.txt").text)
|
||||
now = all - 3
|
||||
print(all)
|
||||
if all < 3:
|
||||
@ -329,7 +329,7 @@ class ProgramRunStatusShow():
|
||||
uploadList = []
|
||||
for i in range(all - 1, start - 1, -1):
|
||||
print(f"第 {i + 1} 条评论:")
|
||||
info = requests.get(f"{base64.b64decode('aHR0cHM6Ly9jb2RlLmdpdGxpbmsub3JnLmNuL2dmZGdkLXhpLW9yZy9iYXNocGlubHVuL3Jhdy9icmFuY2gvbWFzdGVyLw==').decode('utf-8')}{urllib.request.quote(fileName)}/pf-{i}.txt").text.strip()
|
||||
info = requests.get(f"http://bashpinlun.gfdgdxi.top/{urllib.request.quote(fileName)}/pf-{i}.txt").text.strip()
|
||||
print(info)
|
||||
uploadList.append([f"用户{i + 1}", i + 1, info])
|
||||
Add(uploadList)
|
||||
@ -386,7 +386,7 @@ def UpdateFen():
|
||||
uploadList = []
|
||||
for i in range(now + 2, now - 1, -1):
|
||||
print(f"第 {i + 1} 条评论:")
|
||||
info = requests.get(f"https://code.gitlink.org.cn/gfdgd-xi-org/bashpinlun/raw/branch/master/{urllib.request.quote(fileName)}/pf-{i}.txt").text.strip()
|
||||
info = requests.get(f"http://bashpinlun.gfdgdxi.top/{urllib.request.quote(fileName)}/pf-{i}.txt").text.strip()
|
||||
print(info)
|
||||
uploadList.append([f"用户{i + 1}", i + 1, info])
|
||||
#ProgramRunStatusShow.pingLunLayout.removeItem(ProgramRunStatusShow.pingLunLayout.itemAt(2))
|
||||
@ -525,7 +525,7 @@ def readtxt(path):
|
||||
def ChangeSources():
|
||||
global urlSources
|
||||
global urlSourcesIndex
|
||||
sources = [ui.actionGitlink, ui.actionGitee, ui.actionGithub, ui.action_IPv6, ui.action_2, ui.action_3, ui.action]
|
||||
sources = [ui.actionGithub, ui.actionGitee, ui.actionGitlink, ui.action_IPv6, ui.action_2, ui.action_3, ui.action]
|
||||
for i in range(0, len(sources)):
|
||||
if sources[i].isChecked():
|
||||
old_urlSources = urlSources #先备份
|
||||
@ -541,7 +541,7 @@ def ChangeSources():
|
||||
ui.searchList.setModel(nmodel)
|
||||
urlSourcesIndex = i
|
||||
except:
|
||||
[ui.actionGitlink, ui.actionGitee, ui.actionGithub, ui.action_IPv6, ui.action_2, ui.action_3, ui.action][urlSourcesIndex].setChecked(True)
|
||||
#[ui.actionGitlink, ui.actionGitee, ui.actionGithub, ui.action_IPv6, ui.action_2, ui.action_3, ui.action][urlSourcesIndex].setChecked(True)
|
||||
traceback.print_exc()
|
||||
QtWidgets.QMessageBox.critical(window, "提示", "无法连接服务器")
|
||||
urlSources = old_urlSources #如果源不可用则换回来
|
||||
|
@ -41,8 +41,8 @@ programEnv = [
|
||||
["($PROGRAMPATH)", programPath],
|
||||
["($VERSION)", version],
|
||||
["($THANK)", thankText],
|
||||
["($MAKER)", "RacoonGX 团队,By gfdgd xi"],
|
||||
["($COPYRIGHT)", f"©2020~{time.strftime('%Y')} RacoonGX 团队,By gfdgd xi"],
|
||||
["($MAKER)", "gfdgd xi"],
|
||||
["($COPYRIGHT)", f"©2020~{time.strftime('%Y')} gfdgd xi"],
|
||||
["($?)", "0"],
|
||||
["($PLATFORM)", platform.system()],
|
||||
["($DEBUG)", "1"]
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import base64
|
||||
import requests
|
||||
print("""浣溪沙
|
||||
@ -8,4 +10,7 @@ print("""浣溪沙
|
||||
print("")
|
||||
print("听一支新曲喝一杯美酒,还是去年的天气旧日的亭台,西落的夕阳何时再回来?那花儿落去我也无可奈何,那归来的燕子似曾相识,在小园的花径上独自徘徊。")
|
||||
print("================================")
|
||||
print(requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3VlbmdpbmUtcnVubmVyL0luc3RhbGwucGhwP1ZlcnNpb249").decode("utf-8") + sys.argv[1]).text)
|
||||
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||
with open(f"{programPath}/information.json") as file:
|
||||
version = json.loads(file.read())["Version"]
|
||||
print(requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3VlbmdpbmUtcnVubmVyL0luc3RhbGwucGhwP1ZlcnNpb249").decode("utf-8") + version).text)
|
0
2048/.gitignore → Help/2048/.gitignore
vendored
Before Width: 32px | Height: 32px | Size: 4.2 KiB After Width: 32px | Height: 32px | Size: 4.2 KiB |
Before ![]() (image error) Size: 5.7 KiB After ![]() (image error) Size: 5.7 KiB ![]() ![]() |
Before ![]() (image error) Size: 69 KiB After ![]() (image error) Size: 69 KiB ![]() ![]() |
Before ![]() (image error) Size: 41 KiB After ![]() (image error) Size: 41 KiB ![]() ![]() |
Before (image error) Size: 77 KiB After (image error) Size: 77 KiB |
Before (image error) Size: 94 KiB After (image error) Size: 94 KiB |
0
2048/style/fonts/ClearSans-Light-webfont.woff → Help/2048/style/fonts/ClearSans-Light-webfont.woff
0
2048/style/fonts/ClearSans-Regular-webfont.eot → Help/2048/style/fonts/ClearSans-Regular-webfont.eot
0
2048/style/fonts/ClearSans-Regular-webfont.svg → Help/2048/style/fonts/ClearSans-Regular-webfont.svg
Before (image error) Size: 81 KiB After (image error) Size: 81 KiB |
@ -2,7 +2,7 @@
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width initial-scale=1'>
|
||||
<link rel="shortcut icon" href="../runner.svg">
|
||||
<title>UEngine 程序帮助</title>
|
||||
<title>UEngine 运行器帮助</title>
|
||||
</head>
|
||||
<h1 id="uengine-运行器帮助">UEngine 运行器帮助</h1>
|
||||
<hr>
|
||||
@ -12,6 +12,9 @@
|
||||
</blockquote>
|
||||
<hr>
|
||||
<h2 id="常见问题">常见问题</h2>
|
||||
<h3 id="Deepin 23Alpha2 缺失依赖怎么办?">Deepin 23Alpha2 缺失依赖怎么办?</h3>
|
||||
<p>从 <a href="https://gfdgdxi.lanzoue.com/b01qiu22f">https://gfdgdxi.lanzoue.com/b01qiu22f</a> 拉取依赖</p>
|
||||
<p>密码:dihl</p>
|
||||
<h3 id="出现如下图的情况如何修复?">出现如下图的情况如何修复?</h3>
|
||||
<p><img src="2-1-1.png" alt=""><br>出于安全考虑,您的平板电脑已设置为禁止安装来源不明的应用。 </p>
|
||||
<h4 id="修复方法">修复方法</h4>
|
||||
|
@ -16,6 +16,10 @@
|
||||
|
||||
---
|
||||
## 常见问题
|
||||
### Deepin 23Alpha2 缺失依赖怎么办?
|
||||
从 https://gfdgdxi.lanzoue.com/b01qiu22f 拉取依赖
|
||||
密码:dihl
|
||||
|
||||
### 出现如下图的情况如何修复?
|
||||

|
||||
出于安全考虑,您的平板电脑已设置为禁止安装来源不明的应用。
|
||||
|
@ -1,17 +1,14 @@
|
||||
<head>
|
||||
<title>Wine 运行器程序公告</title>
|
||||
<title>UEngine 运行器程序公告</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>针对在 Ubuntu 安装 UEngine 后狂刷通知的解答(UEngine Installer)</h1>
|
||||
<p>先用如下命令移除掉该组件(在终端输入),然后等待作者修复该问题:</p>
|
||||
<pre><code>s
|
||||
sudo rm /usr/share/applications/uengine-loading-ubuntu.desktop
|
||||
sudo rm /etc/xdg/autostart/uengine-loading-ubuntu.desktop
|
||||
sudo rm /usr/bin/uengine-loading-ubuntu</code></pre>
|
||||
<hr/>
|
||||
<h1>常见链接</h1>
|
||||
<p>程序论坛:<a href="https://gfdgdxi.flarum.cloud/">https://gfdgdxi.flarum.cloud/</a></p>
|
||||
<p>星火应用商店:<a href="https://spark-app.store/">https://spark-app.store/</a></p>
|
||||
<p><a href='https://deepin-community-store.gitee.io/spk-resolv?spk=spk://store/tools/com.gitee.uengine.runner.spark'>点击这里从星火应用商店获取 UEngine 运行器</a></p>
|
||||
<hr/>
|
||||
<p align="center"><img src="https://gitee.com/gfdgd-xi/uengine-runner/widgets/widget_card.svg?colors=eae9d7,2e2f29,272822,484a45,eae9d7,747571"></p>
|
||||
</body>
|
||||
<hr/>
|
||||
<h1>程序安装/打开量</h1>
|
||||
<p align="center"><img src="http://gfdgd-xi.github.io/images/uengine-runner-open.svg"></p>
|
||||
<p align="center"><img src="http://gfdgd-xi.github.io/images/uengine-runner.svg"></p>
|
||||
</body>
|
||||
|
3
Help/shell/index.html
Normal file
@ -0,0 +1,3 @@
|
||||
<!DOCTYPE html><html lang="zh-CN"><head><meta charset="UTF-8"><title>文件目录</title></head><body><h1>文件目录</h1><ul>
|
||||
<li><a href="run_daemon.sh">run_daemon.sh</a></li>
|
||||
</ul></body></html>
|
77
Help/shell/run_daemon.sh
Normal file
@ -0,0 +1,77 @@
|
||||
#/bin/bash
|
||||
# 狗头
|
||||
echo '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
|
||||
echo '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@`***,@@@@@@@@'
|
||||
echo '@@@@^*****,\@@@@@@@@@@@@@@@@@@@@`*.....*\@@@@@@'
|
||||
echo '@@@@*.......**\@[`***......*****.....*..*\@@@@@'
|
||||
echo '@@@@^*..............................***...@@@@@'
|
||||
echo '@@@@@*...............................**..*\@@@@'
|
||||
echo '@@@@@^*..*............................*..*=@@@@'
|
||||
echo '@@@@@^**................................**=@@@@'
|
||||
echo '@@@@@/*..................................*=@@@@'
|
||||
echo '@@@@@*..... ..... ............*@@@@'
|
||||
echo '@@@@`*. .]]]]` ... ]/[[[O/O]`........*,@@@'
|
||||
echo '@@@@*.=` =O.,OO......=` .OOOOOO^........*@@@'
|
||||
echo '@@@^*.\ =OOOOO^.....=` .OOOOOO^........*=@@'
|
||||
echo '@@@^*..,\].=OO/.........,[\]]O/[` ......*=@@'
|
||||
echo '@@@@*...................... .*@@@'
|
||||
echo '@@@@`. ......,]]...... .,@@@'
|
||||
echo '@@@@@*. OOOOOOO^ .*@@@@'
|
||||
echo '@@@@@\*. \OOOO` .*/@@@@'
|
||||
echo '@@@@@@\*. =. / .*/@@@@@'
|
||||
echo '@@@@@@@@`*. ,\OOOOOOO]]OO` .*,@@@@@@@'
|
||||
echo '@@@@@@@@@@`*. . .*,@@@@@@@@@'
|
||||
echo '@@@@@@@@@@@@\**.. ......... ..**/@@@@@@@@@@@'
|
||||
echo '@@@@@@@@@@@@@@@@]`***......***,]@@@@@@@@@@@@@@@'
|
||||
echo '@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@'
|
||||
|
||||
# 使 UEngine 能在 Wayland 下运行
|
||||
export XDG_SESSION_TYPE=x11
|
||||
export QT_QPA_PLATFORM=xcb
|
||||
unset WAYLAND_DISPLAYCOPY
|
||||
# 判断是否是开机后第一次运行(无用)
|
||||
#if [[ ! -f /tmp/uengine-loading-ubuntu ]]; then
|
||||
# # 需等待一段时间等系统全部加载完成
|
||||
# notify-send -i /opt/apps/com.gitee.uengine.runner.spark/files/icon.png "UEngine 服务正在加载" -a uengine-runner
|
||||
# sleep 10
|
||||
# touch /tmp/uengine-loading-ubuntu
|
||||
#fi
|
||||
# 修复程序显示问题
|
||||
XDG_CURRENT_DESKTOP="Deepin"
|
||||
export LD_LIBRARY_PATH=/usr/share/uengine/lib64/
|
||||
# 判断 UEngine 是否被正确安装
|
||||
which uengine
|
||||
if [[ $? != 0 ]]; then
|
||||
notify-send -i /opt/apps/com.gitee.uengine.runner.spark/files/icon.png "未安装 UEngine,结束!" -a uengine-runner
|
||||
exit
|
||||
fi
|
||||
uname -r | grep 5.17.3
|
||||
if [[ $? != 0 ]]; then
|
||||
if [[ -f /usr/bin/uengine-loading-binder ]]; then
|
||||
echo 加载 binder
|
||||
pkexec /usr/bin/uengine-loading-binder
|
||||
fi
|
||||
fi
|
||||
notify-send -i /opt/apps/com.gitee.uengine.runner.spark/files/icon.png "UEngine 服务启动完成" -a uengine-runner
|
||||
bad=0
|
||||
# 守护进程,防止异常退出
|
||||
while [[ true ]]; do
|
||||
uengine session-manager -platformtheme=deepin
|
||||
# 让用户可以强制结束
|
||||
if [[ -f "/tmp/uengine-loading-ubuntu-end" ]]; then
|
||||
rm /tmp/uengine-loading-ubuntu-end
|
||||
echo UEngine 服务异常崩溃,不再重启服务
|
||||
notify-send -i /opt/apps/com.gitee.uengine.runner.spark/files/icon.png "UEngine 服务异常崩溃,不再重启服务" -a uengine-runner
|
||||
exit
|
||||
fi
|
||||
if [[ $bad -gt 9 ]]; then
|
||||
# 错误次数太多,结束
|
||||
notify-send -i /opt/apps/com.gitee.uengine.runner.spark/files/icon.png "UEngine 服务异常崩溃次数过多,不再重启服务" -a uengine-runner
|
||||
echo UEngine 服务异常崩溃次数过多,不再重启服务
|
||||
exit
|
||||
fi
|
||||
bad=$(($bad+1))
|
||||
echo "UEngine 服务异常结束,重新启动($bad次)"
|
||||
notify-send -i /opt/apps/com.gitee.uengine.runner.spark/files/icon.png "UEngine 服务异常结束,重新启动($bad次)" -a uengine-runner
|
||||
|
||||
done
|
BIN
Icon/Program/about-background.png
Executable file
After ![]() (image error) Size: 9.9 KiB |
BIN
Icon/Program/about-icon.png
Executable file
After ![]() (image error) Size: 69 KiB |
BIN
Icon/QR/Alipay.jpg
Normal file
After ![]() (image error) Size: 270 KiB |
BIN
Icon/QR/QQ.png
Normal file
After ![]() (image error) Size: 66 KiB |
BIN
Icon/QR/Wechat.png
Normal file
After ![]() (image error) Size: 76 KiB |
BIN
Icon/QR/advertisement0.jpg
Normal file
After ![]() (image error) Size: 338 KiB |
13
LoadingBinder/load.cpp
Normal file
@ -0,0 +1,13 @@
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
int main(){
|
||||
// 检查是否是 root 用户
|
||||
if(system("[[ `whoami` == root ]]")){
|
||||
cout << "这不是 root 账户,失败!";
|
||||
return 1;
|
||||
}
|
||||
system("modprobe binder_linux");
|
||||
system("mkdir /dev/binderfs");
|
||||
system("mount -t binder binder /dev/binderfs");
|
||||
return 0;
|
||||
}
|
BIN
LoadingBinder/load.out
Executable file
17
LoadingBinder/load.sh
Normal file
@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
if [[ `whoami` != root ]]; then
|
||||
echo 这不是 root 用户,结束
|
||||
exit 1
|
||||
fi
|
||||
if [ -d /dev/binderfs ]; then
|
||||
echo 已启动 binder,end
|
||||
systemctl start uengine-container.service
|
||||
systemctl start uengine-session.service
|
||||
exit
|
||||
fi
|
||||
modprobe binder_linux
|
||||
modprobe ashmem_linux
|
||||
mkdir /dev/binderfs
|
||||
mount -t binder binder /dev/binderfs
|
||||
systemctl start uengine-container.service
|
||||
systemctl start uengine-session.service
|
7
LoadingBinder/uengine
Normal file
@ -0,0 +1,7 @@
|
||||
#!/bin/bash
|
||||
export XDG_SESSION_TYPE=x11
|
||||
export QT_QPA_PLATFORM=xcb
|
||||
unset WAYLAND_DISPLAYCOPY
|
||||
XDG_CURRENT_DESKTOP="Deepin"
|
||||
export LD_LIBRARY_PATH=/usr/share/uengine/lib64/
|
||||
uengine-session "$@" -platformtheme=deepin
|
15
LoadingBinder/uengine-wayland-install.sh
Normal file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
programPath=$(cd $(dirname $0); pwd)
|
||||
if [[ ! -f /usr/bin/uengine ]]; then
|
||||
echo 未安装uengine,请先安装!
|
||||
exit 1
|
||||
fi
|
||||
if [[ -f /usr/bin/uengine-session ]] ;then
|
||||
echo 已经安装补丁,无需重复安装!
|
||||
exit 1
|
||||
fi
|
||||
sudo mv /usr/bin/uengine /usr/bin/uengine-session
|
||||
sudo cp "$programPath/uengine" /usr/bin/uengine
|
||||
sudo chmod +x /usr/bin/uengine
|
||||
sudo systemctl restart uengine-session.service
|
||||
echo 补丁安装完成!
|
15
LoadingBinder/uengine-wayland-uninstall.sh
Normal file
@ -0,0 +1,15 @@
|
||||
#!/bin/bash
|
||||
programPath=$(cd $(dirname $0); pwd)
|
||||
if [[ ! -f /usr/bin/uengine ]]; then
|
||||
echo 未安装uengine,请先安装!
|
||||
exit 1
|
||||
fi
|
||||
if [[ ! -f /usr/bin/uengine-session ]] ;then
|
||||
echo 未安装补丁,无需卸载!
|
||||
exit 1
|
||||
fi
|
||||
rm -fv /usb/bin/uengine
|
||||
sudo mv /usr/bin/uengine-session /usr/bin/uengine
|
||||
sudo chmod +x /usr/bin/uengine
|
||||
sudo systemctl restart uengine-session.service
|
||||
echo 补丁卸载完成!
|
7
Makefile
@ -1,5 +1,6 @@
|
||||
clean:
|
||||
python3 RemovePycacheFile.py
|
||||
rm com.gitee.uengine.runner.spark.deb -fv
|
||||
|
||||
build:
|
||||
echo 别云间
|
||||
@ -56,6 +57,10 @@ build:
|
||||
cp -rv Icon new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/
|
||||
cp -rv CompareVersion.py new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/
|
||||
cp -rv uengine-remove.sh new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/
|
||||
cp -rv pkexec new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/
|
||||
cp -rv LoadingBinder new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/
|
||||
cp -rv aapt new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/
|
||||
cp -rv APK new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/
|
||||
rm -rfv new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/information
|
||||
python3 UpdateTime.py
|
||||
python3 RemovePycacheFile.py #new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/
|
||||
@ -84,4 +89,4 @@ depend:
|
||||
python3 -m pip install --upgrade keyboard --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple
|
||||
|
||||
run:
|
||||
python3 mainwindow.py
|
||||
python3 mainwindow.py
|
||||
|
@ -23,7 +23,7 @@ class ProgramRunStatusShow():
|
||||
try:
|
||||
fenlists = []
|
||||
for i in range(6):
|
||||
fenlists.append(int(requests.get(base64.b64decode("aHR0cHM6Ly9jb2RlLmdpdGxpbmsub3JnLmNuL2dmZGdkLXhpLW9yZy93aW5lLXJ1bm5lci1kb3dubG9hZHMtb2YtcnVubmVyL3Jhdy9icmFuY2gvbWFzdGVyL0Zlbi1VRW5naW5lL0Zlbg==").decode("utf-8") + f"{i}.txt").text))
|
||||
fenlists.append(int(requests.get("http://data.download.gfdgdxi.top/Fen-UEngine/Fen" + f"{i}.txt").text))
|
||||
tipsInfo = ""
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
117
README.md
@ -1,22 +1,23 @@
|
||||
<p width=100px align="center"><img src="runner.svg"></p>
|
||||
<h1 align="center">UEngine 运行器 2.0.1</h1>
|
||||
<h1 align="center">UEngine 运行器 2.2.0.1</h1>
|
||||
<hr>
|
||||
<a href='https://gitee.com/gfdgd-xi-org/uengine-runner/stargazers'><img src='https://gitee.com/gfdgd-xi-org/uengine-runner/badge/star.svg?theme=dark' alt='star'></img></a>
|
||||
<a href='https://gitee.com/gfdgd-xi/uengine-runner/stargazers'><img src='https://gitee.com/gfdgd-xi/uengine-runner/badge/star.svg?theme=dark' alt='star'></img></a>
|
||||
<a href='https://gitee.com/gfdgd-xi/uengine-runner/members'><img src='https://gitee.com/gfdgd-xi/uengine-runner/badge/fork.svg?theme=dark' alt='fork'></img></a>
|
||||
|
||||
## 介绍
|
||||
|
||||
新版本Deepin/UOS发布后,可以在应用商店安装部分官方已适配的安卓应用,对爱好者来说,不能自己安装APK软件包始终差点意思,本程序可以为Deepin/UOS上的UEngine安卓运行环境安装自定义APK软件包,并能发送安装的APK包启动菜单到桌面或系统菜单。
|
||||
虽然通过Deepin/UOS应用商店已经能够安装部分安卓应用,但对于安卓应用爱好者来说,不能自由地安装任意APK软件包实在是不尽如人意。本软件可以实现在Deepin/UOS上安装任意APK软件包,并能将其启动图标发送到系统桌面或启动器中,方便用户快速启动它。
|
||||

|
||||
|
||||
(测试平台:UOS 家庭版 21.3.1,deepin 20.8,UOS 专业版 1050)
|
||||
适配架构:amd64、arm64
|
||||
支持系统:Deepin(amd64)、UOS(amd64/arm64)、Debian(amd64,≥debian 10)、Ubuntu(amd64,≥Ubuntu 20.04)
|
||||
Debian 10、Debian 11、Ubuntu 20.04 需要从 http://dtk.gfdgdxi.top/ 下载 dtk(版本≥5.5)并安装才能通过运行器的安装程序正确安装 UEngine
|
||||
暂不支持 Debian 12
|
||||
|
||||
### 已知问题
|
||||
UEngine 运行器 2.0.0 的 UEngine 安装器故障(正在研究解决方法):
|
||||
https://gitee.com/gfdgd-xi/uengine-runner/issues/I6NTCR
|
||||
https://gitee.com/gfdgd-xi/uengine-runner/issues/I6CKHB
|
||||
QQ 交流群:872491938
|
||||
|
||||
## 在 deepin 23 上安装缺失依赖?
|
||||
依赖下载地址:https://gfdgdxi.lanzv.com/b01rwfgtg 密码:648f
|
||||
|
||||
## 程序相关网站
|
||||
作者个人站:https://www.gfdgdxi.top
|
||||
查询 APK 运行情况:https://gfdgd-xi.github.io/uengine-runner-info/
|
||||
@ -25,12 +26,29 @@ https://gitee.com/gfdgd-xi/uengine-runner/issues/I6CKHB
|
||||
Deepin 官网:https://www.deepin.org
|
||||
Deepin 论坛:https://bbs.deepin.org
|
||||
|
||||
## 在 Deepin 23 Alpha2 安装 UEngine 运行器?
|
||||
## 在 Deepin 23 Alpha2/Beta 安装 UEngine 运行器?
|
||||
> 例如:https://gitee.com/gfdgd-xi/uengine-runner/issues/I6MBBC
|
||||
|
||||
需要从以下链接补充依赖:
|
||||
https://gfdgdxi.lanzoue.com/b01qiu22f
|
||||
密码:dihl
|
||||
或者从星火应用商店下载安装,星火应用商店的源里已经补齐 UEngine 运行器在 Deepin 23 Alpha2/Beta 缺少的依赖
|
||||
然后输入:
|
||||
```bash
|
||||
python3 -m pip install pillow
|
||||
```
|
||||
|
||||
## 上架到的应用商店
|
||||
> 可以从下列应用商店获取 UEngine 运行器
|
||||
### Deepin/UOS 应用商店
|
||||

|
||||
|
||||
### 星火应用商店
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
## 安装前必读
|
||||
|
||||
@ -68,6 +86,73 @@ sudo apt upgrade
|
||||

|
||||
|
||||
### 更新内容
|
||||
#### V2.2.0.1(2023年02月04日)
|
||||
**※1、解决 deepin 23 beta3 缺失依赖的问题**
|
||||
|
||||
#### V2.2.0(2023年01月30日)
|
||||
**※1、支持 deepin 23,不需要强制依赖 aapt**
|
||||
**※2、修复 deepin 23 安装的 APK 无法正常在启动器显示图标的问题**
|
||||
**※3、新增 ARM 架构非飞腾 CPU 识别防止破坏鲲鹏 kbox 环境**
|
||||
**※4、修复部分系统在使用程序的一些功能时发生崩溃的问题**
|
||||
**※5、新增 UEngine For Wayland 补丁**
|
||||
6、优化安装量统计机制
|
||||
7、关于窗口新增赞助页
|
||||
8、新增 QQ 交流群入口
|
||||
9、内置 Via 浏览器
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#### V2.1.2(2023年08月14日)
|
||||
**※1、修复 https://gitee.com/gfdgd-xi/uengine-runner/issues/I6ZRZX**
|
||||
**※2、修复添加应用图标时activity名称错误的问题**
|
||||
**※3、修复 UEngine 运行器在 23 运行时提示缺失 PIL.Image 库的问题**
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||
#### V2.1.1(2023年07月06日)
|
||||
**※1、修复在 Ubuntu/Debian 安装 UEngine 时提示“该脚本不支持 deepin”的问题;**
|
||||
**※2、修复 UEngine 在 debian12 安装无法正常开启 UEngine 的问题;**
|
||||
**※3、修复在 UEngine 程序菜单检查到 UEngine 不存在但是无法安装的问题;**
|
||||
**※4、修复了 https://gitee.com/gfdgd-xi/uengine-runner/issues/I6B6C8 的问题;**
|
||||
**※5、优化了 postinst 和 postrm 脚本;**
|
||||
6、添加 zenity 依赖;
|
||||
7、屏蔽在更新程序过程中杀死程序中输出的错误;
|
||||
8、修改下载 dtk 的网址。
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||

|
||||
|
||||
#### V2.1.0(2023年05月13日)
|
||||
**※1、修复源地址(迁出 Gitlink);**
|
||||
**※2、优化 UEngine 安装器,可以在 Debian/Ubuntu 使用(Debian11/Debian10/Ubuntu20.04 需要安装 dtk(≥5.5),dtk 可以从 https://gitee.com/gfdgd-xi/dtk-sources-for-uos-apt/releases 获取);**
|
||||
**※3、UEngine 安装器不再强制安装 5.17.3 内核以运行 UEngine 运行环境,只要当前使用内核支持 binder 模块即可继续(安装前会进行检测,如果用 2.0.0/2.0.1 安装了 5.17.3 内核也可以继续使用该内核);**
|
||||
**※4、修复 uengine-loading-ubuntu 的问题(参考 #I6CKHB:Ubuntu 22.04 LTS安装运行器并按提示安装UEngine后UEngine服务持续崩溃无法使用 )以及 binder 模块调用问题。**
|
||||
|
||||
|
||||

|
||||
|
||||
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||

|
||||
|
||||
#### V2.0.1(2023年04月29日,劳动节版)
|
||||
**※1、新增移除在 Ubuntu 上安装的 UEngine 及其附属脚本的功能**
|
||||
**※2、优化 Ubuntu 安装器启用和安装逻辑,不允许在 UOS/Deepin 安装移植的 Ubuntu UEngine**
|
||||
@ -486,4 +571,14 @@ make install
|
||||
[](https://gitee.com/spark-community-works-collections/spark-webapp-runtime-runner)
|
||||
[](https://gitee.com/gfdgd-xi/timer)
|
||||
|
||||
### ©2021-Now gfdgd xi
|
||||
### 请作者喝杯茶
|
||||
如果您觉得对你有帮助,可以请作者喝杯茶
|
||||
<img src="Icon/QR/Wechat.png" width="250" />
|
||||
<img src="Icon/QR/Alipay.jpg" width="250" />
|
||||
<img src="Icon/QR/QQ.png" width="250" >
|
||||
|
||||
#### 广告
|
||||
支付宝官方活动,扫描获得支付红包!
|
||||
<p><img src="Icon/QR/advertisement0.jpg" width="250" ></p>
|
||||
|
||||
## ©2021-Now gfdgd xi
|
||||
|
@ -64,13 +64,13 @@ class Ui_MainWindow(object):
|
||||
self.openFile.setObjectName("openFile")
|
||||
self.actionGitlink = QtWidgets.QAction(MainWindow)
|
||||
self.actionGitlink.setCheckable(True)
|
||||
self.actionGitlink.setChecked(True)
|
||||
self.actionGitlink.setObjectName("actionGitlink")
|
||||
self.actionGitee = QtWidgets.QAction(MainWindow)
|
||||
self.actionGitee.setCheckable(True)
|
||||
self.actionGitee.setObjectName("actionGitee")
|
||||
self.actionGithub = QtWidgets.QAction(MainWindow)
|
||||
self.actionGithub.setCheckable(True)
|
||||
self.actionGithub.setChecked(True)
|
||||
self.actionGithub.setObjectName("actionGithub")
|
||||
self.action_IPv6 = QtWidgets.QAction(MainWindow)
|
||||
self.action_IPv6.setCheckable(True)
|
||||
@ -88,9 +88,9 @@ class Ui_MainWindow(object):
|
||||
self.menu.addAction(self.openFile)
|
||||
self.menu.addSeparator()
|
||||
self.menu.addAction(self.exitProgram)
|
||||
self.menu_2.addAction(self.actionGitlink)
|
||||
self.menu_2.addAction(self.actionGitee)
|
||||
self.menu_2.addAction(self.actionGithub)
|
||||
self.menu_2.addAction(self.actionGitee)
|
||||
self.menu_2.addAction(self.actionGitlink)
|
||||
self.menu_2.addAction(self.action_IPv6)
|
||||
self.menu_2.addAction(self.action_2)
|
||||
self.menu_2.addAction(self.action_3)
|
||||
|
BIN
aapt/aapt
Executable file
BIN
aapt/aapt2
Executable file
1
aapt/libaapt.so
Symbolic link
@ -0,0 +1 @@
|
||||
libaapt.so.0
|
BIN
aapt/libaapt.so.0
Normal file
BIN
aapt/libandroidfw.so.0
Normal file
19
aapt/run-aapt.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
# 判断是不是 Deepin23
|
||||
cat /etc/deepin_version | grep 23
|
||||
if [[ $? != 0 ]]; then
|
||||
# 如果不是
|
||||
# 判断系统是否有安装 aapt
|
||||
which aapt > /dev/null
|
||||
if [[ $? == 0 ]]; then
|
||||
# 如果有安装
|
||||
aapt "$@"
|
||||
exit $?
|
||||
fi
|
||||
fi
|
||||
# 如果是
|
||||
programPath=$(cd $(dirname $0); pwd)
|
||||
echo $programPath
|
||||
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$programPath"
|
||||
$programPath/aapt "$@"
|
||||
exit $?
|
@ -6,6 +6,12 @@ import traceback
|
||||
import subprocess
|
||||
from getxmlimg import getsavexml
|
||||
|
||||
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||
|
||||
# 获取用户主目录
|
||||
def get_home()->"获取用户主目录":
|
||||
return os.path.expanduser('~')
|
||||
|
||||
class ProgramInformation:
|
||||
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||
version = "1.6.0Alpha2"
|
||||
@ -49,7 +55,7 @@ class APK:
|
||||
def uninstall(self):
|
||||
return os.system("uengine uninstall --pkg='{}'".format(self.packageName()))
|
||||
def information(self):
|
||||
return subprocess.getoutput("aapt dump badging '{}'".format(self.apkPath))
|
||||
return subprocess.getoutput("'{}/aapt/run-aapt.sh' dump badging '{}'".format(programPath, self.apkPath))
|
||||
def activityName(self):
|
||||
info = self.information()
|
||||
for line in info.split('\n'):
|
||||
|
BIN
bwrap/bwrap_amd64
Executable file
BIN
bwrap/bwrap_arm64
Executable file
0
bwrap/run.sh
Normal file
17
getxmlimg.py
@ -1,13 +1,22 @@
|
||||
import PIL.Image as Image
|
||||
import PIL.ImageDraw as ImageDraw
|
||||
import os
|
||||
try:
|
||||
import PIL.Image as Image
|
||||
import PIL.ImageDraw as ImageDraw
|
||||
except:
|
||||
os.system("python3 -m pip install --upgrade pillow --break-system-packages --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple")
|
||||
os.system("python3 -m pip install --upgrade pillow --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple")
|
||||
import PIL.Image as Image
|
||||
import PIL.ImageDraw as ImageDraw
|
||||
import zipfile
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||
|
||||
class getsavexml():
|
||||
|
||||
def savexml(self,apkFilePath,xmlpath,iconSavePath):
|
||||
cmddumpid = "aapt dump xmltree "+ apkFilePath + " " + xmlpath
|
||||
cmddumpid = f"'{programPath}/aapt/run-aapt.sh' dump xmltree "+ apkFilePath + " " + xmlpath
|
||||
print(cmddumpid)
|
||||
xmltree = subprocess.getoutput(cmddumpid)
|
||||
xmls = xmltree.splitlines()
|
||||
@ -29,7 +38,7 @@ class getsavexml():
|
||||
print(foreimgid)
|
||||
|
||||
# 直接从apk resource文件获取前后两层图片路径及ID字符串
|
||||
resource = subprocess.getoutput("aapt dump --values resources " + apkFilePath + "| grep -iE -A1 " + "\"" + backimgid + "|" + foreimgid + "\"")
|
||||
resource = subprocess.getoutput(f"'{programPath}/aapt/run-aapt.sh' dump --values resources " + apkFilePath + "| grep -iE -A1 " + "\"" + backimgid + "|" + foreimgid + "\"")
|
||||
resourcelines = resource.splitlines()
|
||||
print(resourcelines)
|
||||
|
||||
|
@ -2,11 +2,10 @@
|
||||
"Package": "com.gitee.uengine.runner.spark",
|
||||
"Url": [
|
||||
"https://gitee.com/gfdgd-xi/uengine-runner",
|
||||
"https://github.com/gfdgd-xi/uengine-runner",
|
||||
"https://gitlink.org.cn/gfdgd_xi/uengine-runner"
|
||||
"https://github.com/gfdgd-xi/uengine-runner"
|
||||
],
|
||||
"Version": "2.0.1",
|
||||
"System": "Linux(deepin/UOS/Ubuntu22.04)",
|
||||
"Version": "2.2.0.1",
|
||||
"System": "Linux(deepin/UOS/Ubuntu/Debian)",
|
||||
"Tips": [
|
||||
"更多可见:https://gitee.com/gfdgd-xi/uengine-runner/wikis 或程序的更多帮助",
|
||||
"安装APK:点浏览按钮,选中需要安装的APK,然后点安装按钮",
|
||||
@ -23,6 +22,41 @@
|
||||
"5、如果想要使用adb连接UEngine或其他手机,请使用 1.2.0 以前的版本。(如需连接UEngine请安装adb补丁)"
|
||||
],
|
||||
"Update": [
|
||||
"<b>V2.2.0.1:</b>",
|
||||
"※1、解决 deepin 23 beta3 缺失依赖的问题",
|
||||
"",
|
||||
"<b>V2.2.0:</b>",
|
||||
"※1、支持 deepin 23,不需要强制依赖 aapt",
|
||||
"※2、修复 deepin 23 安装的 APK 无法正常在启动器显示图标的问题",
|
||||
"※3、新增 ARM 架构非飞腾 CPU 识别防止破坏鲲鹏 kbox 环境",
|
||||
"※4、修复部分系统在使用程序的一些功能时发生崩溃的问题",
|
||||
"※5、新增 UEngine For Wayland 补丁",
|
||||
"6、优化安装量统计机制",
|
||||
"7、关于窗口新增赞助页",
|
||||
"8、新增 QQ 交流群入口",
|
||||
"9、内置 Via 浏览器",
|
||||
"",
|
||||
"<b>V2.1.2:</b>",
|
||||
"※1、修复 https://gitee.com/gfdgd-xi/uengine-runner/issues/I6ZRZX",
|
||||
"※2、修复添加应用图标时activity名称错误的问题",
|
||||
"※3、修复 UEngine 运行器在 23 运行时提示缺失 PIL.Image 库的问题",
|
||||
"",
|
||||
"<b>V2.1.1:</b>",
|
||||
"※1、修复在 Ubuntu/Debian 安装 UEngine 时提示“该脚本不支持 deepin”的问题;",
|
||||
"※2、修复 UEngine 在 debian12 安装无法正常开启 UEngine 的问题;",
|
||||
"※3、修复在 UEngine 程序菜单检查到 UEngine 不存在但是无法安装的问题;",
|
||||
"※4、修复了 https://gitee.com/gfdgd-xi/uengine-runner/issues/I6B6C8 的问题;",
|
||||
"※5、优化了 postinst 脚本;",
|
||||
"6、添加 zenity 依赖;",
|
||||
"7、屏蔽在更新程序过程中杀死程序中输出的错误;",
|
||||
"8、修改下载 dtk 的网址。",
|
||||
"",
|
||||
"<b>V2.1.0:</b>",
|
||||
"※1、修复源地址(迁出 Gitlink);",
|
||||
"※2、优化 UEngine 安装器,可以在 Debian/Ubuntu 使用(Debian11/Debian10/Ubuntu20.04 需要安装 dtk(≥5.5),dtk 可以从 https://gitee.com/gfdgd-xi/dtk-sources-for-uos-apt/releases 获取);",
|
||||
"※3、UEngine 安装器不再强制安装 5.17.3 内核以运行 UEngine 运行环境,只要当前使用内核支持 binder 模块即可继续(安装前会进行检测,如果用 2.0.0/2.0.1 安装了 5.17.3 内核也可以继续使用该内核);",
|
||||
"※4、修复 uengine-loading-ubuntu 的问题(参考 #I6CKHB:Ubuntu 22.04 LTS安装运行器并按提示安装UEngine后UEngine服务持续崩溃无法使用 )以及 binder 模块调用问题。",
|
||||
"",
|
||||
"<b>V2.0.1:</b>",
|
||||
"※1、新增移除在 Ubuntu 上安装的 UEngine 及其附属脚本的功能",
|
||||
"※2、优化 Ubuntu 安装器启用和安装逻辑,不允许在 UOS/Deepin 安装移植的 Ubuntu UEngine",
|
||||
@ -247,6 +281,7 @@
|
||||
"Contribute": [
|
||||
"<b>感谢以下用户提供的问题、建议、图标、代码等,如果有遗漏,请及时与开发者联系添加,以及如果侵犯到您的合法权益,也及时与开发者联系:</p>",
|
||||
"<hr>",
|
||||
"感谢 @鹤舞白沙 优化了程序文案",
|
||||
"感谢 @Bail 修复了修复应用商店换源的问题,实现了微型应用商店更新关闭进程的功能",
|
||||
"感谢 RacoonGX 团队的付出和贡献",
|
||||
"感谢 cleverwwh 反馈的 UEngine 打包器在部分系统无法打开的问题",
|
||||
|
172
mainwindow.py
@ -89,8 +89,8 @@ class UninstallProgram(QtCore.QThread):
|
||||
self.error.emit("疑似卸载失败,请检查 UEngine 是否正常安装、运行以及 APK 文件或包名是否正确、完整")
|
||||
DisabledAndEnbled(False)
|
||||
return
|
||||
if os.path.exists("{}/.local/share/applications/uengine/{}.desktop".format(get_home(), package)):
|
||||
os.remove("{}/.local/share/applications/uengine/{}.desktop".format(get_home(), package))
|
||||
if os.path.exists("{}/{}.desktop".format(desktopFilePath, package)):
|
||||
os.remove("{}/{}.desktop".format(desktopFilePath, package))
|
||||
if os.path.exists("{}/{}.desktop".format(get_desktop_path(), package)):
|
||||
os.remove("{}/{}.desktop".format(get_desktop_path(), package))
|
||||
findApkHistory.append(ComboInstallPath.currentText())
|
||||
@ -174,9 +174,9 @@ class InstallApk(QtCore.QThread):
|
||||
try:
|
||||
if not os.path.exists("/tmp/uengine-runner"):
|
||||
os.makedirs("/tmp/uengine-runner")
|
||||
if not os.path.exists("{}/.local/share/applications/uengine/".format(get_home())):
|
||||
if not os.path.exists(desktopFilePath):
|
||||
print("Mkdir")
|
||||
os.makedirs("{}/.local/share/applications/uengine/".format(get_home()))
|
||||
os.makedirs(desktopFilePath)
|
||||
# 读取设置
|
||||
setting = json.loads(readtxt(get_home() + "/.config/uengine-runner/setting.json"))
|
||||
# 安装应用
|
||||
@ -246,7 +246,7 @@ logicalHeight {verticalHeighe}
|
||||
"{}/{}.desktop".format(get_desktop_path(), GetApkPackageName(path)))
|
||||
print("start install apk3")
|
||||
BuildUengineDesktop(GetApkPackageName(path), GetApkActivityName(path), GetApkChineseLabel(path), iconSavePath,
|
||||
"{}/.local/share/applications/uengine/{}.desktop".format(get_home(), GetApkPackageName(path)))
|
||||
"{}/{}.desktop".format(desktopFilePath, GetApkPackageName(path)))
|
||||
print("\nprint install complete")
|
||||
if quit:
|
||||
return
|
||||
@ -266,7 +266,7 @@ def InstallBuildDesktop(iconSavePath):
|
||||
"{}/{}.desktop".format(get_desktop_path(), GetApkPackageName(path)), choose)
|
||||
print("start install apk3")
|
||||
BuildUengineDesktop(GetApkPackageName(path), GetApkActivityName(path), GetApkChineseLabel(path), iconSavePath,
|
||||
"{}/.local/share/applications/uengine/{}.desktop".format(get_home(), GetApkPackageName(path)), choose)
|
||||
"{}/{}.desktop".format(desktopFilePath, GetApkPackageName(path)), choose)
|
||||
print("\nprint install complete")
|
||||
|
||||
def UpdateCombobox(tmp):
|
||||
@ -418,7 +418,7 @@ def write_txt(path: "路径", things: "内容")->"写入文本文档":
|
||||
|
||||
# 获取 aapt 的所有信息
|
||||
def GetApkInformation(apkFilePath: "apk 所在路径")->"获取 aapt 的所有信息":
|
||||
return GetCommandReturn("aapt dump badging '{}'".format(apkFilePath))
|
||||
return GetCommandReturn("'{}/aapt/run-aapt.sh' dump badging '{}'".format(programPath, apkFilePath))
|
||||
|
||||
# 获取 apk Activity
|
||||
def GetApkActivityName(apkFilePath: "apk 所在路径")->"获取 apk Activity":
|
||||
@ -587,8 +587,8 @@ def BackUengineClean()->"清空 uengine 数据":
|
||||
if QtWidgets.QMessageBox.warning(widget, "警告", "清空后数据将会完全丢失,确定要继续吗?", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel) == QtWidgets.QMessageBox.Ok:
|
||||
DisabledAndEnbled(True)
|
||||
try:
|
||||
if os.path.exists("{}/.local/share/applications/uengine/".format(get_home())):
|
||||
shutil.rmtree("{}/.local/share/applications/uengine/".format(get_home()))
|
||||
if os.path.exists(desktopFilePath):
|
||||
shutil.rmtree(desktopFilePath)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
QtWidgets.QMessageBox.critical(widget, "错误", traceback.format_exc())
|
||||
@ -1004,7 +1004,7 @@ class UengineWindowSizeSetting:
|
||||
i.setChecked(True)
|
||||
UengineWindowSizeSetting.setting.setWindowTitle(f"设置 Android 应用的窗口大小缩放设置")
|
||||
UengineWindowSizeSetting.setting.show()
|
||||
UengineWindowSizeSetting.setting.resize(UengineWindowSizeSetting.setting.frameSize().width() * 1.3, UengineWindowSizeSetting.setting.frameSize().height())
|
||||
UengineWindowSizeSetting.setting.resize(int(UengineWindowSizeSetting.setting.frameSize().width() * 1.3), int(UengineWindowSizeSetting.setting.frameSize().height()))
|
||||
|
||||
def ReadSetting():
|
||||
file = open(f"/usr/share/uengine/appetc/{UengineWindowSizeSetting.package}.txt")
|
||||
@ -1153,7 +1153,7 @@ class UpdateWindow():
|
||||
cancel.clicked.connect(UpdateWindow.update.close)
|
||||
ok.setDisabled(True)
|
||||
try:
|
||||
UpdateWindow.data = json.loads(requests.get("https://code.gitlink.org.cn/gfdgd_xi/wine-runner-update-information/raw/branch/master/uengine-runner/update.json").text)
|
||||
UpdateWindow.data = json.loads(requests.get("http://update.gfdgdxi.top/uengine-runner/update.json").text)
|
||||
versionLabel = QtWidgets.QLabel(f"当前版本:{version}\n最新版本:{UpdateWindow.data['Version']}\n更新内容:")
|
||||
if UpdateWindow.data["Version"] == version:
|
||||
updateText.setText("此为最新版本,无需更新")
|
||||
@ -1191,7 +1191,7 @@ class UpdateWindow():
|
||||
UpdateWindow.update.setCentralWidget(updateWidget)
|
||||
UpdateWindow.update.setWindowTitle("检查 UEngine 运行器更新")
|
||||
UpdateWindow.update.setWindowIcon(QtGui.QIcon(iconPath))
|
||||
UpdateWindow.update.resize(updateWidget.frameGeometry().width(), int(updateWidget.frameGeometry().height() * 1.5))
|
||||
UpdateWindow.update.resize(int(updateWidget.frameGeometry().width()), int(updateWidget.frameGeometry().height() * 1.5))
|
||||
UpdateWindow.update.show()
|
||||
|
||||
def Update():
|
||||
@ -1324,7 +1324,7 @@ class ApkInformation():
|
||||
QtWidgets.QMessageBox.critical(widget, "错误", langFile[lang]["Main"]["MainWindow"]["Error"]["ApkFileError"])
|
||||
return
|
||||
try:
|
||||
data = json.loads(requests.get("https://code.gitlink.org.cn/gfdgd_xi/wine-runner-downloads-of-runner/raw/branch/master/uengineapp/" + package +"/data.json").text)
|
||||
data = json.loads(requests.get("http://data.download.gfdgdxi.top/uengineapp/" + package +"/data.json").text)
|
||||
print(data)
|
||||
except:
|
||||
QtWidgets.QMessageBox.information(widget, "提示", "此程序暂时没有评分,欢迎您贡献第一个评分!")
|
||||
@ -1410,7 +1410,7 @@ class ShowTextTipsWindow():
|
||||
ShowTextTipsWindow.messageWindow.setWindowTitle("提示")
|
||||
ShowTextTipsWindow.messageWindow.setWindowIcon(QtGui.QIcon(iconPath))
|
||||
ShowTextTipsWindow.messageWindow.show()
|
||||
ShowTextTipsWindow.messageWindow.resize(ShowTextTipsWindow.messageWindow.frameSize().width() * 2, ShowTextTipsWindow.messageWindow.frameSize().height() * 1.5)
|
||||
ShowTextTipsWindow.messageWindow.resize(int(ShowTextTipsWindow.messageWindow.frameSize().width() * 2), int(ShowTextTipsWindow.messageWindow.frameSize().height() * 1.5))
|
||||
return
|
||||
|
||||
# 添加/删除 uengine 应用快捷方式
|
||||
@ -1462,7 +1462,7 @@ class AddNewUengineDesktopLink():
|
||||
# 添加快捷方式
|
||||
def SaveDesktopLink():
|
||||
try:
|
||||
if os.path.exists("{}/.local/share/applications/uengine/{}.desktop".format(get_home(), packageName.text())):
|
||||
if os.path.exists("{}/{}.desktop".format(desktopFilePath, packageName.text())):
|
||||
if QtWidgets.QMessageBox.question(widget, "提示", "文件已存在,是否要覆盖?") == QtWidgets.QMessageBox.No:
|
||||
return
|
||||
if not os.path.exists("{}/.local/share/icons/hicolor/256x256/apps/".format(get_home())):
|
||||
@ -1470,9 +1470,9 @@ class AddNewUengineDesktopLink():
|
||||
global activityName
|
||||
iconSavePath = "{}/.local/share/icons/hicolor/256x256/apps/{}.png".format(get_home(), packageName.text())
|
||||
shutil.copy(programPath + "/defult.png", iconSavePath)
|
||||
BuildUengineDesktop(packageName.text(), activityName, packageName.text(), iconSavePath,
|
||||
"{}/.local/share/applications/uengine/{}.desktop".format(get_home(), packageName.text()))
|
||||
BuildUengineDesktop(packageName.text(), activityName, packageName.text(), iconSavePath,
|
||||
BuildUengineDesktop(packageName.text(), activityName.text(), packageName.text(), iconSavePath,
|
||||
"{}/{}.desktop".format(desktopFilePath, packageName.text()))
|
||||
BuildUengineDesktop(packageName.text(), activityName.text(), packageName.text(), iconSavePath,
|
||||
"{}/{}.desktop".format(get_desktop_path(), packageName.text()))
|
||||
AddNewUengineDesktopLink.SaveHistory()
|
||||
QtWidgets.QMessageBox.information(widget, "提示", "创建完毕!")
|
||||
@ -1485,13 +1485,13 @@ class AddNewUengineDesktopLink():
|
||||
def DelDesktopLink():
|
||||
try:
|
||||
global packageName
|
||||
if not os.path.exists("{}/.local/share/applications/uengine/{}.desktop".format(get_home(), packageName.text())):
|
||||
QtWidgets.QMessageBox.critical(widget, "错误", "此包名对应的 UEngine 桌面快捷方式不存在!")
|
||||
if not os.path.exists("{}/{}.desktop".format(desktopFilePath, packageName.text())):
|
||||
QtWidgets.QMessageBox.critical(widget, "错误", "此包名对应的 UEngine 快捷方式不存在!")
|
||||
return
|
||||
if QtWidgets.QMessageBox.warning(widget, "警告", "你确定要删除吗?删除后将无法恢复!", QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, QtWidgets.QMessageBox.Cancel) == QtWidgets.QMessageBox.Cancel:
|
||||
return
|
||||
try:
|
||||
os.remove("{}/.local/share/applications/uengine/{}.desktop".format(get_home(), packageName.text()))
|
||||
os.remove("{}/{}.desktop".format(desktopFilePath, packageName.text()))
|
||||
AddNewUengineDesktopLink.SaveHistory()
|
||||
QtWidgets.QMessageBox.information(widget, "提示", "已删除")
|
||||
except:
|
||||
@ -1524,7 +1524,8 @@ class AddNewUengineDesktopLink():
|
||||
|
||||
def GetNewInformation():
|
||||
try:
|
||||
text = requests.get("https://code.gitlink.org.cn/gfdgd_xi/uengine-runner-list/raw/branch/master/information/index.html").text
|
||||
text = requests.get("http://www.gfdgdxi.top/uengine-runner/Help/information/index.html").text
|
||||
print(text)
|
||||
except:
|
||||
traceback.print_exc()
|
||||
text = """<p>无法连接到服务器</p>
|
||||
@ -1558,7 +1559,7 @@ def UseProgram():
|
||||
<p>10、deepin 终端:{}</p>'''.format(subprocess.getoutput("uengine version"),
|
||||
subprocess.getoutput("python3 --version"),
|
||||
QtCore.qVersion,
|
||||
subprocess.getoutput("aapt version"),
|
||||
subprocess.getoutput(f"'{programPath}/aapt/run-aapt.sh' version"),
|
||||
subprocess.getoutput("dpkg --version"),
|
||||
subprocess.getoutput("mkdir --version"),
|
||||
subprocess.getoutput("chmod --version"),
|
||||
@ -1569,6 +1570,26 @@ def BackAPK(choice):
|
||||
global choose
|
||||
choose = choice
|
||||
|
||||
def InstallUEnginePatchForWayland():
|
||||
if os.system("which uengine"):
|
||||
QtWidgets.QMessageBox.critical(window, "错误", "未安装UEngine,请先安装UEngine")
|
||||
return
|
||||
if os.path.exists("/usr/bin/uengine-session"):
|
||||
QtWidgets.QMessageBox.critical(window, "提示", "已安装该补丁,请勿重复安装")
|
||||
return
|
||||
os.system(f"pkexec bash '{programPath}/LoadingBinder/uengine-wayland-install.sh'")
|
||||
QtWidgets.QMessageBox.information(window, "提示", "安装成功!重启电脑后生效")
|
||||
|
||||
def RemoveUEnginePatchForWayland():
|
||||
if os.system("which uengine"):
|
||||
QtWidgets.QMessageBox.critical(window, "错误", "未安装UEngine,请先安装UEngine")
|
||||
return
|
||||
if not os.path.exists("/usr/bin/uengine-session"):
|
||||
QtWidgets.QMessageBox.critical(window, "提示", "已卸载该补丁,无需卸载")
|
||||
return
|
||||
os.system(f"pkexec bash '{programPath}/LoadingBinder/uengine-wayland-uninstall.sh'")
|
||||
QtWidgets.QMessageBox.information(window, "提示", "卸载成功!重启电脑后生效")
|
||||
|
||||
###########################
|
||||
# 程序信息
|
||||
###########################
|
||||
@ -1581,11 +1602,10 @@ if not lang in langFile.keys():
|
||||
programUrl = information["Url"][0]
|
||||
version = information["Version"]
|
||||
goodRunSystem = information["System"]
|
||||
aaptVersion = GetCommandReturn("aapt version")
|
||||
aaptVersion = GetCommandReturn(f"'{programPath}/aapt/run-aapt.sh' version")
|
||||
SystemVersion = GetSystemVersion()
|
||||
iconPath = "{}/runner.svg".format(os.path.split(os.path.realpath(__file__))[0])
|
||||
about = f'''<p align="center"><img width=256 src="{iconPath}"/></p>
|
||||
<p>介绍:一个基于 Python3 的 PyQt5 制作的 UEngine 运行器,在新版本Deepin/UOS发布后,可以在应用商店安装部分官方已适配的安卓应用,对爱好者来说,不能自己安装APK软件包始终差点意思,本程序可以为Deepin/UOS上的UEngine安卓运行环境安装自定义APK软件包,并能发送安装的APK包启动菜单到桌面或系统菜单。</p>
|
||||
about = f'''<p>介绍:虽然通过Deepin/UOS应用商店已经能够安装部分安卓应用,但对于安卓应用爱好者来说,不能自由地安装任意APK软件包实在是不尽如人意。本软件可以实现在Deepin/UOS上安装任意APK软件包,并能将其启动图标发送到系统桌面或启动器中,方便用户快速启动它。 </p>
|
||||
<p>程序开源许可证:GPLV3</p>
|
||||
<p>版本:{version}</p>
|
||||
<p>适用平台:{goodRunSystem}</p>
|
||||
@ -1593,10 +1613,22 @@ about = f'''<p align="center"><img width=256 src="{iconPath}"/></p>
|
||||
<p>程序官网:{programUrl}</p>
|
||||
<p>系统版本:{SystemVersion}</p>
|
||||
<p>安装包构建时间:{information['Time']}</p>
|
||||
<p>QQ 交流群:872491938</p>
|
||||
<h1>©2021-{time.strftime("%Y")} gfdgd xi</h1>'''
|
||||
updateThingsString = ""
|
||||
tips = ""
|
||||
contribute = ""
|
||||
appreciate = f"""<h3>请作者喝杯茶</h3>
|
||||
<p>如果您觉得 UEngine 运行器对你有帮助,可以请作者喝杯茶 </p>
|
||||
<p>
|
||||
<img src="{programPath}/Icon/QR/Wechat.png" width="250" />
|
||||
<img src="{programPath}/Icon/QR/Alipay.jpg" width="250" />
|
||||
<img src="{programPath}/Icon/QR/QQ.png" width="250" >
|
||||
</p>
|
||||
<hr/>
|
||||
<h3>广告</h3>
|
||||
<p>支付宝官方活动,扫描获得支付红包!</p>
|
||||
<p><img src="{programPath}/Icon/QR/advertisement0.jpg" width="250" ></p>"""
|
||||
for i in information["Tips"]:
|
||||
tips += f"<p>{i}</p>"
|
||||
for i in information["Update"]:
|
||||
@ -1610,13 +1642,25 @@ desktop = programPath + "/UengineAndroidProgramList.desktop"
|
||||
desktopName = "UengineAndroidProgramList.desktop"
|
||||
useProgram = ""
|
||||
threading.Thread(target=UseProgram).start()
|
||||
isDeepin23=False
|
||||
# 判断是不是 Deepin23
|
||||
if os.path.exists("/etc/deepin_version"):
|
||||
try:
|
||||
with open(f"/etc/deepin_version") as file:
|
||||
isDeepin23 = "23" in file.read()
|
||||
except:
|
||||
traceback.print_exc()
|
||||
desktopFilePath = f"{get_home()}/.local/share/applications/uengine/"
|
||||
if isDeepin23:
|
||||
desktopFilePath = f"{get_home()}/.local/share/applications/"
|
||||
|
||||
|
||||
###########################
|
||||
# 加载配置
|
||||
###########################
|
||||
app = QtWidgets.QApplication(sys.argv)
|
||||
if not os.path.exists("{}/.local/share/applications/uengine/".format(get_home())):
|
||||
os.makedirs("{}/.local/share/applications/uengine/".format(get_home()))
|
||||
if not os.path.exists(desktopFilePath):
|
||||
os.makedirs(desktopFilePath)
|
||||
if not os.path.exists(get_home() + "/.config/uengine-runner"): # 如果没有配置文件夹
|
||||
os.makedirs(get_home() + "/.config/uengine-runner") # 创建配置文件夹
|
||||
if not os.path.exists(get_home() + "/.config/uengine-runner/FindApkHistory.json"): # 如果没有配置文件
|
||||
@ -1696,10 +1740,10 @@ except:
|
||||
windowflag = "close"
|
||||
def Open():
|
||||
try:
|
||||
lists = json.loads(requests.get("https://code.gitlink.org.cn/gfdgd_xi/wine-runner-downloads-of-runner/raw/branch/master/Open-UEngine/lists.json").text)
|
||||
lists = json.loads(requests.get("https://data.download.gfdgdxi.top/Open-UEngine/lists.json").text)
|
||||
data = []
|
||||
for i in lists:
|
||||
data.append(int(requests.get("https://code.gitlink.org.cn/gfdgd_xi/wine-runner-downloads-of-runner/raw/branch/master/Open-UEngine/{}.txt".format(i)).text))
|
||||
data.append(int(requests.get("https://data.download.gfdgdxi.top/Open-UEngine/{}.txt".format(i)).text))
|
||||
except:
|
||||
QtWidgets.QMessageBox.critical(widget, "错误", "服务器出错!数据获取失败!")
|
||||
return
|
||||
@ -1716,11 +1760,12 @@ def Open():
|
||||
|
||||
def Download():
|
||||
try:
|
||||
lists = json.loads(requests.get("https://code.gitlink.org.cn/gfdgd_xi/wine-runner-downloads-of-runner/raw/branch/master/Install-UEngine/lists.json").text)
|
||||
lists = json.loads(requests.get("https://data.download.gfdgdxi.top/Install-UEngine/lists.json").text)
|
||||
data = []
|
||||
for i in lists:
|
||||
data.append(int(requests.get("https://code.gitlink.org.cn/gfdgd_xi/wine-runner-downloads-of-runner/raw/branch/master/Install-UEngine/{}.txt".format(i)).text))
|
||||
data.append(int(requests.get("https://data.download.gfdgdxi.top/Install-UEngine/{}.txt".format(i)).text))
|
||||
except:
|
||||
traceback.print_exc()
|
||||
QtWidgets.QMessageBox.critical(widget, "错误", "服务器出错!数据获取失败!")
|
||||
return
|
||||
fig = matplotlib.pylab.figure()
|
||||
@ -1743,7 +1788,16 @@ def showhelp():
|
||||
def ChgLog():
|
||||
HelpStr.setHtml(updateThingsString)
|
||||
def ChgAbout(event):
|
||||
HelpStr.setHtml(about)
|
||||
HelpStr.setHtml(f"<p align='center'><a href='https://www.gfdgdxi.top/ChangeIcon'><img width=256 src='{iconPath}'/></a></p>\n" + about)
|
||||
def OpenUrl(url):
|
||||
print(url.url())
|
||||
if url.url() == "https://www.gfdgdxi.top/ChangeIcon":
|
||||
ChgAboutChangeIcon()
|
||||
return
|
||||
webbrowser.open_new_tab(url.url())
|
||||
|
||||
def ChgAboutChangeIcon():
|
||||
HelpStr.setHtml(f"<p align='center'><img width=256 src='{programPath}/Icon/Program/about-icon.png'/></p>\n" + about)
|
||||
def ChgDep():
|
||||
if useProgram == "":
|
||||
BtnZujian.setDisabled(True)
|
||||
@ -1753,7 +1807,8 @@ def showhelp():
|
||||
HelpStr.setHtml(contribute)
|
||||
def ChgTips():
|
||||
HelpStr.setHtml(tips)
|
||||
|
||||
def ChgAppreciate():
|
||||
HelpStr.setHtml(appreciate)
|
||||
def ChgGPLV3():
|
||||
try:
|
||||
with open(f"{programPath}/LICENSE", "r") as file:
|
||||
@ -1776,7 +1831,12 @@ def showhelp():
|
||||
BtnDownN = QtWidgets.QPushButton("程序下载量")
|
||||
BtnOpenN = QtWidgets.QPushButton("程序打开量")
|
||||
BtnGPLV3 = QtWidgets.QPushButton("程序开源许可证")
|
||||
appreciateButton = QtWidgets.QPushButton("赞赏作者")
|
||||
HelpStr = QtWidgets.QTextBrowser()
|
||||
HelpStr.setOpenLinks(False)
|
||||
HelpStr.setHtml(about)
|
||||
HelpStr.setOpenExternalLinks(False)
|
||||
HelpStr.anchorClicked.connect(OpenUrl)
|
||||
# 此功能从 2.0.0 后不再隐藏
|
||||
#BtnDownN.setEnabled("--彩蛋" in sys.argv)
|
||||
BtnReadme.clicked.connect(ChgTips)
|
||||
@ -1787,6 +1847,7 @@ def showhelp():
|
||||
BtnDownN.clicked.connect(Download)
|
||||
BtnGPLV3.clicked.connect(ChgGPLV3)
|
||||
BtnOpenN.clicked.connect(Open)
|
||||
appreciateButton.clicked.connect(ChgAppreciate)
|
||||
|
||||
ChgTips()
|
||||
|
||||
@ -1797,14 +1858,18 @@ def showhelp():
|
||||
helpLayout.addWidget(BtnDownN, 4, 0, 1, 1)
|
||||
helpLayout.addWidget(BtnOpenN, 5, 0, 1, 1)
|
||||
helpLayout.addWidget(BtnGPLV3, 6, 0, 1, 1)
|
||||
helpLayout.addWidget(BtnAbout, 7, 0, 1, 1)
|
||||
helpLayout.addWidget(HelpStr, 0, 1, 10, 1)
|
||||
helpLayout.addWidget(appreciateButton, 7, 0, 1, 1)
|
||||
helpLayout.addWidget(BtnAbout, 8, 0, 1, 1)
|
||||
helpLayout.addWidget(HelpStr, 0, 1, 11, 1)
|
||||
|
||||
helpWidget.setLayout(helpLayout)
|
||||
helpWindow.setCentralWidget(helpWidget)
|
||||
helpWindow.setFixedSize(int(helpWindow.frameSize().width() * 0.9), int(helpWindow.frameSize().height() * 1.5))
|
||||
helpWindow.setWindowTitle("帮助")
|
||||
helpWindow.setWindowIcon(QtGui.QIcon(iconPath))
|
||||
# 设置背景
|
||||
helpWindow.setObjectName("helpWindow")
|
||||
helpWindow.setStyleSheet(f"QWidget#helpWindow {{background: url({programPath}/Icon/Program/about-background.png) no-repeat;background-position: left bottom;}}")
|
||||
helpWindow.show()
|
||||
return
|
||||
|
||||
@ -1814,6 +1879,9 @@ def showhelp():
|
||||
if not os.path.exists("/usr/bin/uengine"):
|
||||
# Deepin/UOS 用户
|
||||
if "deepin" in SystemVersion.lower() or "uos" in SystemVersion.lower() or subprocess.getoutput("arch").replace("\n", "").replace(" ", "") != "x86_64":
|
||||
if not "ft-" in GetCommandReturn("lscpu").lower() and GetCommandReturn("lscpu").replace(" ", "").replace("\n", "") == "aarch64":
|
||||
QtWidgets.QMessageBox.critical(None, "错误", "UEngine 运行器不支持非飞腾 CPU")
|
||||
sys.exit(1)
|
||||
if QtWidgets.QMessageBox.question(None, "提示", "您的电脑没有安装 UEngine,是否安装 UEngine 以便更好的使用\n安装完后重新启动该程序即可") == QtWidgets.QMessageBox.Yes:
|
||||
OpenTerminal(f"pkexec apt install uengine -y")
|
||||
sys.exit(0)
|
||||
@ -1823,15 +1891,24 @@ if not os.path.exists("/usr/bin/uengine"):
|
||||
#QtWidgets.QMessageBox.critical(None, "错误", "请安装 UEngine 后继续")
|
||||
#sys.exit(0)
|
||||
#if QtWidgets.QMessageBox.question(None, "提示", "您的电脑没有安装 UEngine,是否安装 UEngine 以便更好的使用\n这里将会使用 shenmo 提供的脚本进行安装\n安装完后重新启动该程序即可\n提示:无法保证此安装脚本安装的 UEngine 可以使用") == QtWidgets.QMessageBox.Yes:
|
||||
if QtWidgets.QMessageBox.question(None, "提示", "您的电脑没有安装 UEngine,是否安装 UEngine 以便更好的使用\n这里将会安装移植版本(之前由 Shenmo 编写)\n安装完后重新启动该程序即可\n提示:需要在 Ubuntu 22.04 及以上版本才能正常安装") == QtWidgets.QMessageBox.Yes:
|
||||
if QtWidgets.QMessageBox.question(None, "提示", "您的电脑没有安装 UEngine,是否安装 UEngine 以便更好的使用\n这里将会安装移植版本(之前由 Shenmo 编写)\n安装完后重新启动该程序即可\n提示:需要在 Ubuntu 20.04 或 debian10 及以上版本才能正常安装\nUbuntu 20.04 和 debian10 需要手动安装 dtk(≥5.5),可以从 http://dtk.gfdgdxi.top 获取") == QtWidgets.QMessageBox.Yes:
|
||||
#os.system(f"'{programPath}/launch.sh' deepin-terminal -C \"bash '{programPath}/uengine-installer'\"")
|
||||
OpenTerminal(f"bash '{programPath}/uengine-installer'")
|
||||
sys.exit(0)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
###########################
|
||||
# 窗口创建
|
||||
###########################
|
||||
window = QtWidgets.QMainWindow()
|
||||
# 判断系统是不是 Deepin 23、有没有安装 Wayland 补丁、是不是 Wayland 环境
|
||||
if not os.path.exists("/usr/bin/uengine-session") and isDeepin23 and os.getenv("XDG_SESSION_TYPE") == "wayland":
|
||||
# 如果是
|
||||
if QtWidgets.QMessageBox.question(None, "提示", "检测到您使用的是 Deepin 23 + Wayland 环境,建议安装 UEngine For Wayland 补丁以便能正常使用 UEngine,是否安装?") == QtWidgets.QMessageBox.Yes:
|
||||
InstallUEnginePatchForWayland()
|
||||
widget = QtWidgets.QWidget()
|
||||
widgetLayout = QtWidgets.QGridLayout()
|
||||
# 权重
|
||||
@ -1973,9 +2050,12 @@ uengineCheckCpu = QtWidgets.QAction(QtGui.QIcon.fromTheme("cpu"), langFile[lang]
|
||||
uengineDeleteUengineCheck = QtWidgets.QAction(QtWidgets.QApplication.style().standardIcon(40), langFile[lang]["Main"]["MainWindow"]["Menu"][2]["Menu"][9])
|
||||
uengineReinstall = QtWidgets.QAction(langFile[lang]["Main"]["MainWindow"]["Menu"][2]["Menu"][10])
|
||||
uengineUbuntuInstall = QtWidgets.QAction(QtGui.QIcon.fromTheme("ubuntu-logo-icon"), langFile[lang]["Main"]["MainWindow"]["Menu"][2]["Menu"][14])
|
||||
uengineUbuntuRemove = QtWidgets.QAction(QtGui.QIcon.fromTheme("ubuntu-logo-icon"), "移除在 Ubuntu 上安装的 UEngine 及其附属脚本")
|
||||
uengineUbuntuInstallRoot = QtWidgets.QAction(QtGui.QIcon.fromTheme("ubuntu-logo-icon"), "在 Ubuntu 上安装 UEngine(SuperSU 镜像)")
|
||||
uengineUbuntuRemove = QtWidgets.QAction(QtGui.QIcon.fromTheme("ubuntu-logo-icon"), "移除在 Ubuntu/Debian 上安装的 UEngine 及其附属脚本")
|
||||
uengineUbuntuInstallRoot = QtWidgets.QAction(QtGui.QIcon.fromTheme("ubuntu-logo-icon"), "在 Ubuntu/Debian 上安装 UEngine(SuperSU 镜像)")
|
||||
uengineWindowSizeSetting = QtWidgets.QAction(langFile[lang]["Main"]["MainWindow"]["Menu"][2]["Menu"][16])
|
||||
uengineInstallVia = QtWidgets.QAction("安装 Via")
|
||||
installUEnginePatchForWayland = QtWidgets.QAction("安装 UEngine For Wayland 补丁")
|
||||
uninstallUEnginePatchForWayland = QtWidgets.QAction("卸载 UEngine For Wayland 补丁")
|
||||
uengine.addAction(uengineOpenDebBuilder)
|
||||
uengine.addAction(uengineOpenDebBuilderMore)
|
||||
uengine.addAction(uengineKeyboardToMouse)
|
||||
@ -2001,6 +2081,12 @@ uengine.addSeparator()
|
||||
uengine.addAction(uengineDeleteUengineCheck)
|
||||
uengine.addAction(uengineReinstall)
|
||||
uengineRoot = uengine.addMenu(langFile[lang]["Main"]["MainWindow"]["Menu"][2]["Menu"][11]["Name"])
|
||||
uengine.addSeparator()
|
||||
uengine.addAction(uengineInstallVia)
|
||||
uengine.addSeparator()
|
||||
uengine.addAction(installUEnginePatchForWayland)
|
||||
uengine.addAction(uninstallUEnginePatchForWayland)
|
||||
|
||||
#uengineUbuntuInstall.setDisabled(True)
|
||||
# 绑定信号
|
||||
uengineAllowOrDisallowUpdateAndroidApp.triggered.connect(AllowOrDisallowUpdateAndroidApp)
|
||||
@ -2015,6 +2101,14 @@ uengineUbuntuInstallRoot.triggered.connect(UengineUbuntuInstallRoot)
|
||||
uengineDeleteUengineCheck.triggered.connect(DelUengineCheck)
|
||||
uengineReinstall.triggered.connect(ReinstallUengine)
|
||||
uengineWindowSizeSetting.triggered.connect(UengineWindowSizeSetting.ShowWindow)
|
||||
installUEnginePatchForWayland.triggered.connect(InstallUEnginePatchForWayland)
|
||||
uninstallUEnginePatchForWayland.triggered.connect(RemoveUEnginePatchForWayland)
|
||||
|
||||
def InstallVia():
|
||||
ComboInstallPath.setCurrentText(f"{programPath}/APK/Via.apk")
|
||||
Button3Install()
|
||||
|
||||
uengineInstallVia.triggered.connect(InstallVia)
|
||||
|
||||
uengineStart = QtWidgets.QAction(QtGui.QIcon.fromTheme("services"), langFile[lang]["Main"]["MainWindow"]["Menu"][2]["Menu"][2]["Menu"][0])
|
||||
uengineStop = QtWidgets.QAction(QtGui.QIcon.fromTheme("services"), langFile[lang]["Main"]["MainWindow"]["Menu"][2]["Menu"][2]["Menu"][1])
|
||||
|
@ -1,25 +1,14 @@
|
||||
Package: com.gitee.uengine.runner.spark
|
||||
Source: com.gitee.uengine.runner.spark
|
||||
Replaces: spark-uengine-runner, com.gitee.uengine.runner.spark.ubuntu
|
||||
Version: 2.0.1
|
||||
Version: 2.2.0.1
|
||||
Architecture: all
|
||||
Section: utils
|
||||
Installed-Size: 2920
|
||||
Installed-Size: 9384
|
||||
Maintainer: gfdgd xi <3025613752@qq.com>
|
||||
Depends: python3, python3-tk, python3-pip, aapt, python3-setuptools, deepin-terminal | mate-terminal | gnome-terminal | xfce4-terminal, curl, python3-pil, python3-requests, adb, fonts-noto-cjk, python3-numpy, wget, inotify-tools, aria2, python3-pyqt5, python3-matplotlib, python3-urllib3
|
||||
Recommends: uengine, deepin-elf-verify, python3-pyqt5.qtwebengine
|
||||
Depends: python3, python3-tk, python3-pip, python3-setuptools, deepin-terminal | mate-terminal | gnome-terminal | xfce4-terminal, curl, python3-pil, python3-requests, adb, fonts-noto-cjk, python3-numpy, wget, aria2, python3-pyqt5, python3-matplotlib, python3-urllib3, zenity, python3-pil.imagetk
|
||||
Recommends: uengine, deepin-elf-verify, python3-pyqt5.qtwebengine, aapt
|
||||
Priority: optional
|
||||
Conflicts: spark-uengine-apk-builder, com.gitee.uengine.runner.spark.ubuntu
|
||||
Conflicts: spark-uengine-apk-builder, com.gitee.uengine.runner.spark.ubuntu, kbox
|
||||
Homepage: https://gitee.com/gfdgd-xi/uengine-runner
|
||||
Description: UEngine 运行器,2.0.1 更新内容:
|
||||
※1、新增移除在 Ubuntu 上安装的 UEngine 及其附属脚本的功能
|
||||
※2、优化 Ubuntu 安装器启用和安装逻辑,不允许在 UOS/Deepin 安装移植的 Ubuntu UEngine
|
||||
※3、Ubuntu 安装器不允许在非 X86 架构上使用
|
||||
※4、在升级/安装运行器的 deb 时会自动移除安装错误的 UEngine 生成的脚本
|
||||
※5、Ubuntu 安装器进行环境监测
|
||||
※6、修复应用商店换源问题(由@Bail修复)
|
||||
6、修改作者信息
|
||||
7、更新使用帮助
|
||||
8、关于窗口修复系统失败错误的问题并新增安装包构建时间
|
||||
9、移除赞赏功能
|
||||
10、微型应用商店适配了更新关闭进程(由@Bail实现)
|
||||
Description: 新版本Deepin/UOS发布后,可以在应用商店安装部分官方已适配的安卓应用,对爱好者来说,不能自己安装APK软件包始终差点意思,本程序可以为Deepin/UOS上的Uengine安卓运行环境安装/卸载/打包自定义APK软件包,并能发送安装的APK包启动菜单到桌面或系统菜单。
|
||||
|
@ -1,10 +1,10 @@
|
||||
#!/bin/bash
|
||||
# 使用 pip 安装所需库
|
||||
echo 安装组件
|
||||
python3 -m pip install --upgrade pip --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple
|
||||
python3 -m pip install --upgrade ttkthemes --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple
|
||||
python3 -m pip install --upgrade pyautogui --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple
|
||||
python3 -m pip install --upgrade keyboard --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple
|
||||
python3 -m pip install --upgrade ttkthemes --break-system-packages --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple > /dev/null 2>&1 | true
|
||||
python3 -m pip install --upgrade pyautogui --break-system-packages --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple > /dev/null 2>&1 | true
|
||||
python3 -m pip install --upgrade keyboard --break-system-packages --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple > /dev/null 2>&1 | true
|
||||
python3 -m pip install --upgrade pillow --break-system-packages --trusted-host https://repo.huaweicloud.com -i https://repo.huaweicloud.com/repository/pypi/simple > /dev/null 2>&1 | true
|
||||
echo 执行完成
|
||||
# 建立软链接
|
||||
ln -s /opt/apps/com.gitee.uengine.runner.spark/files/uengine-runner /usr/bin/uengine-runner
|
||||
@ -35,28 +35,39 @@ if [[ $? != 0 ]] && [[ -f /usr/bin/uengine-loading-ubuntu ]]; then
|
||||
done
|
||||
fi
|
||||
# 更新 uengine-loading-ubuntu(如果存在)
|
||||
if [[ -f /usr/bin/uengine-loading-ubuntu ]]; then
|
||||
if [[ -f /usr/bin/uengine-loading-ubuntu ]] || [[ -f /usr/bin/uengine-loading-binder ]]; then
|
||||
echo 更新 uengine-loading-ubuntu
|
||||
cp /opt/apps/com.gitee.uengine.runner.spark/files/LoadingBinder/load.sh /usr/bin/uengine-loading-binder
|
||||
if [ -f /tmp/upgrade-uengine-loading-ubuntu ]; then
|
||||
rm /tmp/upgrade-uengine-loading-ubuntu
|
||||
fi
|
||||
# 下载新版
|
||||
aria2c -x 16 -s 16 -d /tmp -o upgrade-uengine-loading-ubuntu https://code.gitlink.org.cn/gfdgd_xi/uengine-installer-bak/raw/branch/master/run_daemon.sh
|
||||
aria2c -x 16 -s 16 -d /tmp -o upgrade-uengine-loading-ubuntu http://uengine-runner.gfdgdxi.top/shell/run_daemon.sh
|
||||
if [ $? == 0 ]; then
|
||||
# 替换
|
||||
cp /tmp/upgrade-uengine-loading-ubuntu /usr/bin/uengine-loading-ubuntu
|
||||
chmod 755 /usr/bin/uengine-loading-ubuntu
|
||||
for username in $(ls /home)
|
||||
do
|
||||
echo /home/$username
|
||||
cp /usr/bin/uengine-loading-ubuntu /home/$username/uengine-launch/run_daemon.sh
|
||||
chmod 755 /home/$username/uengine-launch/run_daemon.sh
|
||||
done
|
||||
|
||||
else
|
||||
cp /opt/apps/com.gitee.uengine.runner.spark/files/Help/shell/run_daemon.sh /usr/bin/uengine-loading-ubuntu
|
||||
fi
|
||||
rm /tmp/upgrade-uengine-loading-ubuntu
|
||||
chmod 755 /usr/bin/uengine-loading-ubuntu
|
||||
for username in $(ls /home)
|
||||
do
|
||||
echo /home/$username
|
||||
cp /usr/bin/uengine-loading-ubuntu /home/$username/uengine-launch/run_daemon.sh
|
||||
chmod 755 /home/$username/uengine-launch/run_daemon.sh
|
||||
done
|
||||
rm -f /tmp/upgrade-uengine-loading-ubuntu
|
||||
fi
|
||||
# 自动往 UEngine 安装 Via(如果 UEngine 已存在)
|
||||
if [[ -f /usr/bin/uengine-session-launch-helper ]]; then
|
||||
# 忽略错误进行安装
|
||||
cp /opt/apps/com.gitee.uengine.runner.spark/files/APK/Via.apk /tmp/Via.apk | true
|
||||
/usr/bin/uengine-session-launch-helper -- uengine install --apk=/tmp/Via.apk | true
|
||||
rm -f /tmp/Via.apk | true
|
||||
fi
|
||||
# 刷新图标缓存
|
||||
# 因为 Ubuntu 的问题,省略
|
||||
gtk-update-icon-cache /usr/share/icons/bloom > /dev/null | true
|
||||
# 向服务器返回安装数加1(不显示内容且忽略错误)
|
||||
python3 /opt/apps/com.gitee.uengine.runner.spark/files/Download.py 2.0.1 > /dev/null | true
|
||||
python3 /opt/apps/com.gitee.uengine.runner.spark/files/Download.py 2.1.2 > /dev/null | true
|
||||
|
@ -22,11 +22,16 @@ rm -fr /opt/apps/com.gitee.uengine.runner.spark/files/api/__pycache__
|
||||
rm -fr /opt/apps/com.gitee.uengine.runner.spark/files/__pycache__
|
||||
rm -f /usr/bin/uengine-runner-applist-launch.sh
|
||||
rm -f /usr/bin/uengine-runner-auto-install-bash
|
||||
rm -f /usr/bin/uengine-loading-ubuntu
|
||||
#rm -f /usr/bin/uengine-loading-ubuntu
|
||||
# 删除软件残留,简单粗暴一点直接全部删掉,防止出现警告
|
||||
# 加判断是为了怕 reinstall 后程序就再也打不开了(除非卸载后重新安装)
|
||||
if [ "$1" = "remove" ] || [ "$1" = "purge" ]; then
|
||||
rm -rf /opt/apps/com.gitee.uengine.runner.spark
|
||||
# 移除 UEngine For 23 Wayland 补丁
|
||||
if [[ -f /usr/bin/uengine-session ]]; then
|
||||
rm -fv /usb/bin/uengine
|
||||
mv -v /usr/bin/uengine-session /usr/bin/uengine
|
||||
fi
|
||||
fi
|
||||
# 删除软件配置文件(只限“purge”)
|
||||
# 配置目录:~/.config/uengine-runner
|
||||
@ -61,7 +66,11 @@ if [ "$1" = "purge" ]; then
|
||||
else
|
||||
echo "非 purge,跳过清理"
|
||||
fi
|
||||
|
||||
# 自动卸载 UEngine 的 Via(如果 UEngine 已存在)
|
||||
if [[ -f /usr/bin/uengine-session-launch-helper ]]; then
|
||||
# 忽略错误进行安装
|
||||
/usr/bin/uengine-session-launch-helper -- uengine uninstall --pkg=mark.via | true
|
||||
fi
|
||||
# 刷新图标缓存
|
||||
# 因为 Ubuntu 的问题,省略
|
||||
gtk-update-icon-cache /usr/share/icons/bloom > /dev/null | true
|
@ -35,9 +35,9 @@ print("""译文:一轮缓缓移动的秋月洒下万里金波,就像那刚
|
||||
我要乘风飞上万里长空,俯视祖国的大好山河。还要砍去月中摇曳的桂树枝柯,人们说,这将使月亮洒下人间的光辉更多。""")
|
||||
print("================================")
|
||||
urlSourcesList = [
|
||||
"https://code.gitlink.org.cn/gfdgd_xi/uengine-runner-list/raw/branch/master/auto", # Gitlink 源
|
||||
"http://config.uengine-runner.gfdgdxi.top/", # Github 源
|
||||
"https://gitee.com/gfdgd-xi/uengine-wine-runner-auto-configuration-script/raw/master/", # Gitee 源
|
||||
"https://gfdgd-xi.github.io/uengine-wine-runner-auto-configuration-script/", # Github 源
|
||||
"https://code.gitlink.org.cn/gfdgd_xi/uengine-runner-list/raw/branch/master/auto", # Gitlink 源
|
||||
"http://gfdgdxi.msns.cn/uengine-runner-list/auto/", # 备用源1,纯 IPv6 源
|
||||
"http://gfdgdxi.free.idcfengye.com/uengine-runner-auto-configuration-script/", # 备用源2
|
||||
"http://gfdgdxi.free.idcfengye.com/uengine-runner-list/auto/", # 备用源 3
|
||||
@ -146,7 +146,7 @@ class InformationWindow():
|
||||
about = f"<h1>关于“{choose}”的介绍</h1>\n<p>暂无此程序的介绍</p>"
|
||||
try:
|
||||
import requests as r
|
||||
fenlists = requests.get(base64.b64decode("aHR0cHM6Ly9jb2RlLmdpdGxpbmsub3JnLmNuL2dmZGdkLXhpLW9yZy93aW5lLXJ1bm5lci1kb3dubG9hZHMtb2YtcnVubmVyL3Jhdy9icmFuY2gvbWFzdGVyL0Jhc2hBcHBGZW4v").decode("utf-8") + urllib.request.quote(fileName) + base64.b64decode("L2FsbC5qc29u").decode("utf-8"), timeout=1000).json()
|
||||
fenlists = requests.get("http://data.download.gfdgdxi.top/BashAppFen/" + urllib.request.quote(fileName) + base64.b64decode("L2FsbC5qc29u").decode("utf-8"), timeout=1000).json()
|
||||
tipsInfo = ""
|
||||
except:
|
||||
fenlists = [0, 0, 0, 0, 0]
|
||||
@ -166,19 +166,19 @@ class InformationWindow():
|
||||
if maxHead > 5:
|
||||
for i in range(end):
|
||||
if webeng:
|
||||
starHtml += f"<img src='https://code.gitlink.org.cn/gfdgd_xi/deep-wine-runner/raw/branch/main/Icon/BadStar.svg' width=50>\n"
|
||||
starHtml += f"<img src='http://wine-runner.gfdgdxi.top/Icon/BadStar.svg' width=50>\n"
|
||||
else:
|
||||
starHtml += f"<img src='{programPath}/Icon/BadStar.svg' width=50>\n"
|
||||
else:
|
||||
for i in range(maxHead):
|
||||
if webeng:
|
||||
starHtml += f"<img src='https://code.gitlink.org.cn/gfdgd_xi/deep-wine-runner/raw/branch/main/Icon/Star.svg' width=50>\n"
|
||||
starHtml += f"<img src='http://wine-runner.gfdgdxi.top/Icon/Star.svg' width=50>\n"
|
||||
else:
|
||||
starHtml += f"<img src='{programPath}/Icon/Star.svg' width=50>\n"
|
||||
head = maxHead
|
||||
for i in range(head, end):
|
||||
if webeng:
|
||||
starHtml += f"<img src='https://code.gitlink.org.cn/gfdgd_xi/deep-wine-runner/raw/branch/main/Icon/UnStar.svg' width=50>"
|
||||
starHtml += f"<img src='http://wine-runner.gfdgdxi.top/Icon/UnStar.svg' width=50>"
|
||||
else:
|
||||
starHtml += f"<img src='{programPath}/Icon/UnStar.svg' width=50>"
|
||||
about += f"\n<hr/><h1>评分情况</h1>\n<p align='center'>{starHtml}</p>\n<p align='center'>{tipsInfo}</p>"
|
||||
@ -260,7 +260,7 @@ class ProgramRunStatusShow():
|
||||
fileName = i[1]
|
||||
break
|
||||
try:
|
||||
fenlists = requests.get(base64.b64decode("aHR0cHM6Ly9jb2RlLmdpdGxpbmsub3JnLmNuL2dmZGdkLXhpLW9yZy93aW5lLXJ1bm5lci1kb3dubG9hZHMtb2YtcnVubmVyL3Jhdy9icmFuY2gvbWFzdGVyL0Jhc2hBcHBGZW4v").decode("utf-8") + urllib.request.quote(fileName) + base64.b64decode("L2FsbC5qc29u").decode("utf-8")).json()
|
||||
fenlists = requests.get("http://data.download.gfdgdxi.top/BashAppFen/" + urllib.request.quote(fileName) + base64.b64decode("L2FsbC5qc29u").decode("utf-8")).json()
|
||||
tipsInfo = ""
|
||||
except:
|
||||
#traceback.print_exc()
|
||||
@ -318,7 +318,7 @@ class ProgramRunStatusShow():
|
||||
else:
|
||||
# 显示最新的3条评论
|
||||
try:
|
||||
all = int(requests.get(f"{base64.b64decode('aHR0cHM6Ly9jb2RlLmdpdGxpbmsub3JnLmNuL2dmZGdkLXhpLW9yZy9iYXNocGlubHVuL3Jhdy9icmFuY2gvbWFzdGVyLw==').decode('utf-8')}{urllib.request.quote(fileName)}/data.txt").text)
|
||||
all = int(requests.get(f"http://bashpinlun.gfdgdxi.top/{urllib.request.quote(fileName)}/data.txt").text)
|
||||
now = all - 3
|
||||
print(all)
|
||||
if all < 3:
|
||||
@ -329,7 +329,7 @@ class ProgramRunStatusShow():
|
||||
uploadList = []
|
||||
for i in range(all - 1, start - 1, -1):
|
||||
print(f"第 {i + 1} 条评论:")
|
||||
info = requests.get(f"{base64.b64decode('aHR0cHM6Ly9jb2RlLmdpdGxpbmsub3JnLmNuL2dmZGdkLXhpLW9yZy9iYXNocGlubHVuL3Jhdy9icmFuY2gvbWFzdGVyLw==').decode('utf-8')}{urllib.request.quote(fileName)}/pf-{i}.txt").text.strip()
|
||||
info = requests.get(f"http://bashpinlun.gfdgdxi.top/{urllib.request.quote(fileName)}/pf-{i}.txt").text.strip()
|
||||
print(info)
|
||||
uploadList.append([f"用户{i + 1}", i + 1, info])
|
||||
Add(uploadList)
|
||||
@ -386,7 +386,7 @@ def UpdateFen():
|
||||
uploadList = []
|
||||
for i in range(now + 2, now - 1, -1):
|
||||
print(f"第 {i + 1} 条评论:")
|
||||
info = requests.get(f"https://code.gitlink.org.cn/gfdgd-xi-org/bashpinlun/raw/branch/master/{urllib.request.quote(fileName)}/pf-{i}.txt").text.strip()
|
||||
info = requests.get(f"http://bashpinlun.gfdgdxi.top/{urllib.request.quote(fileName)}/pf-{i}.txt").text.strip()
|
||||
print(info)
|
||||
uploadList.append([f"用户{i + 1}", i + 1, info])
|
||||
#ProgramRunStatusShow.pingLunLayout.removeItem(ProgramRunStatusShow.pingLunLayout.itemAt(2))
|
||||
@ -525,7 +525,7 @@ def readtxt(path):
|
||||
def ChangeSources():
|
||||
global urlSources
|
||||
global urlSourcesIndex
|
||||
sources = [ui.actionGitlink, ui.actionGitee, ui.actionGithub, ui.action_IPv6, ui.action_2, ui.action_3, ui.action]
|
||||
sources = [ui.actionGithub, ui.actionGitee, ui.actionGitlink, ui.action_IPv6, ui.action_2, ui.action_3, ui.action]
|
||||
for i in range(0, len(sources)):
|
||||
if sources[i].isChecked():
|
||||
old_urlSources = urlSources #先备份
|
||||
@ -541,7 +541,7 @@ def ChangeSources():
|
||||
ui.searchList.setModel(nmodel)
|
||||
urlSourcesIndex = i
|
||||
except:
|
||||
[ui.actionGitlink, ui.actionGitee, ui.actionGithub, ui.action_IPv6, ui.action_2, ui.action_3, ui.action][urlSourcesIndex].setChecked(True)
|
||||
#[ui.actionGitlink, ui.actionGitee, ui.actionGithub, ui.action_IPv6, ui.action_2, ui.action_3, ui.action][urlSourcesIndex].setChecked(True)
|
||||
traceback.print_exc()
|
||||
QtWidgets.QMessageBox.critical(window, "提示", "无法连接服务器")
|
||||
urlSources = old_urlSources #如果源不可用则换回来
|
||||
|
@ -41,8 +41,8 @@ programEnv = [
|
||||
["($PROGRAMPATH)", programPath],
|
||||
["($VERSION)", version],
|
||||
["($THANK)", thankText],
|
||||
["($MAKER)", "RacoonGX 团队,By gfdgd xi"],
|
||||
["($COPYRIGHT)", f"©2020~{time.strftime('%Y')} RacoonGX 团队,By gfdgd xi"],
|
||||
["($MAKER)", "gfdgd xi"],
|
||||
["($COPYRIGHT)", f"©2020~{time.strftime('%Y')} gfdgd xi"],
|
||||
["($?)", "0"],
|
||||
["($PLATFORM)", platform.system()],
|
||||
["($DEBUG)", "1"]
|
||||
|
@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import base64
|
||||
import requests
|
||||
print("""浣溪沙
|
||||
@ -8,4 +10,7 @@ print("""浣溪沙
|
||||
print("")
|
||||
print("听一支新曲喝一杯美酒,还是去年的天气旧日的亭台,西落的夕阳何时再回来?那花儿落去我也无可奈何,那归来的燕子似曾相识,在小园的花径上独自徘徊。")
|
||||
print("================================")
|
||||
print(requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3VlbmdpbmUtcnVubmVyL0luc3RhbGwucGhwP1ZlcnNpb249").decode("utf-8") + sys.argv[1]).text)
|
||||
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||
with open(f"{programPath}/information.json") as file:
|
||||
version = json.loads(file.read())["Version"]
|
||||
print(requests.get(base64.b64decode("aHR0cDovLzEyMC4yNS4xNTMuMTQ0L3VlbmdpbmUtcnVubmVyL0luc3RhbGwucGhwP1ZlcnNpb249").decode("utf-8") + version).text)
|
1
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
||||
.sass-cache/
|
@ -0,0 +1,19 @@
|
||||
{
|
||||
"esnext": true,
|
||||
"indent": 2,
|
||||
"maxlen": 80,
|
||||
"freeze": true,
|
||||
"camelcase": true,
|
||||
"unused": true,
|
||||
"eqnull": true,
|
||||
"proto": true,
|
||||
"supernew": true,
|
||||
"noyield": true,
|
||||
"evil": true,
|
||||
"node": true,
|
||||
"boss": true,
|
||||
"expr": true,
|
||||
"loopfunc": true,
|
||||
"white": true,
|
||||
"maxdepth": 4
|
||||
}
|
33
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/CONTRIBUTING.md
Normal file
@ -0,0 +1,33 @@
|
||||
# Contributing
|
||||
Changes and improvements are more than welcome! Feel free to fork and open a pull request.
|
||||
|
||||
Please follow the house rules to have a bigger chance of your contribution being merged.
|
||||
|
||||
## House rules
|
||||
|
||||
### How to make changes
|
||||
- To make changes, create a new branch based on `master` (do not create one from `gh-pages` unless strictly necessary) and make them there, then create a Pull Request to master.
|
||||
`gh-pages` is different from master in that it contains sharing features, analytics and other things that have no direct bearing with the game. `master` is the "pure" version of the game.
|
||||
- If you want to modify the CSS, please edit the SCSS files present in `style/`: `main.scss` and others. Don't edit the `main.css`, because it's supposed to be generated.
|
||||
In order to compile your SCSS modifications, you need to use the `sass` gem (install it by running `gem install sass` once Ruby is installed).
|
||||
To run SASS, simply use the following command:
|
||||
`sass --unix-newlines --watch style/main.scss`
|
||||
SASS will automatically recompile your css when changed.
|
||||
- `Rakefile` contains some tasks that help during development. Feel free to add useful tasks if needed.
|
||||
- Please use 2-space indentation when editing the JavaScript. A `.jshintrc` file is present, which will help your code to follow the guidelines if you install and run `jshint`.
|
||||
- Please test your modification thoroughly before submitting your Pull Request.
|
||||
|
||||
### Changes that might not be accepted
|
||||
We have to be conservative with the core game. This means that some modifications won't be merged, or will have to be evaluated carefully before being merged:
|
||||
|
||||
- Undo/redo features
|
||||
- Save/reload features
|
||||
- Changes to how the tiles look or their contents
|
||||
- Changes to the layout
|
||||
- Changes to the grid size
|
||||
|
||||
### Changes that are welcome
|
||||
- Bug fixes
|
||||
- Compatibility improvements
|
||||
- "Under the hood" enhancements
|
||||
- Small changes that don't have an impact on the core gameplay
|
@ -0,0 +1,21 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 Gabriele Cirulli
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
@ -0,0 +1,38 @@
|
||||
# 2048
|
||||
A small clone of [1024](https://play.google.com/store/apps/details?id=com.veewo.a1024), based on [Saming's 2048](http://saming.fr/p/2048/) (also a clone).
|
||||
|
||||
Made just for fun. [Play it here!](http://gabrielecirulli.github.io/2048/)
|
||||
|
||||
The official app can also be found on the [Play Store](https://play.google.com/store/apps/details?id=com.gabrielecirulli.app2048) and [App Store!](https://itunes.apple.com/us/app/2048-by-gabriele-cirulli/id868076805)
|
||||
|
||||
### Contributions
|
||||
|
||||
[Anna Harren](https://github.com/iirelu/) and [sigod](https://github.com/sigod) are maintainers for this repository.
|
||||
|
||||
Other notable contributors:
|
||||
|
||||
- [TimPetricola](https://github.com/TimPetricola) added best score storage
|
||||
- [chrisprice](https://github.com/chrisprice) added custom code for swipe handling on mobile
|
||||
- [marcingajda](https://github.com/marcingajda) made swipes work on Windows Phone
|
||||
- [mgarciaisaia](https://github.com/mgarciaisaia) added support for Android 2.3
|
||||
|
||||
Many thanks to [rayhaanj](https://github.com/rayhaanj), [Mechazawa](https://github.com/Mechazawa), [grant](https://github.com/grant), [remram44](https://github.com/remram44) and [ghoullier](https://github.com/ghoullier) for the many other good contributions.
|
||||
|
||||
### Screenshot
|
||||
|
||||
<p align="center">
|
||||
<img src="https://cloud.githubusercontent.com/assets/1175750/8614312/280e5dc2-26f1-11e5-9f1f-5891c3ca8b26.png" alt="Screenshot"/>
|
||||
</p>
|
||||
|
||||
That screenshot is fake, by the way. I never reached 2048 :smile:
|
||||
|
||||
## Contributing
|
||||
Changes and improvements are more than welcome! Feel free to fork and open a pull request. Please make your changes in a specific branch and request to pull into `master`! If you can, please make sure the game fully works before sending the PR, as that will help speed up the process.
|
||||
|
||||
You can find the same information in the [contributing guide.](https://github.com/gabrielecirulli/2048/blob/master/CONTRIBUTING.md)
|
||||
|
||||
## License
|
||||
2048 is licensed under the [MIT license.](https://github.com/gabrielecirulli/2048/blob/master/LICENSE.txt)
|
||||
|
||||
## Donations
|
||||
I made this in my spare time, and it's hosted on GitHub (which means I don't have any hosting costs), but if you enjoyed the game and feel like buying me coffee, you can donate at my BTC address: `1Ec6onfsQmoP9kkL3zkpB6c5sA4PVcXU2i`. Thank you very much!
|
@ -0,0 +1,11 @@
|
||||
require "date"
|
||||
|
||||
namespace :appcache do
|
||||
desc "update the date in the appcache file (in the gh-pages branch)"
|
||||
task :update do
|
||||
appcache = File.read("cache.appcache")
|
||||
updated = "# Updated: #{DateTime.now}"
|
||||
|
||||
File.write("cache.appcache", appcache.sub(/^# Updated:.*$/, updated))
|
||||
end
|
||||
end
|
After Width: 32px | Height: 32px | Size: 4.2 KiB |
@ -0,0 +1,99 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>2048</title>
|
||||
|
||||
<link href="style/main.css" rel="stylesheet" type="text/css">
|
||||
<link rel="shortcut icon" href="favicon.ico">
|
||||
<link rel="apple-touch-icon" href="meta/apple-touch-icon.png">
|
||||
<link rel="apple-touch-startup-image" href="meta/apple-touch-startup-image-640x1096.png" media="(device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2)"> <!-- iPhone 5+ -->
|
||||
<link rel="apple-touch-startup-image" href="meta/apple-touch-startup-image-640x920.png" media="(device-width: 320px) and (device-height: 480px) and (-webkit-device-pixel-ratio: 2)"> <!-- iPhone, retina -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
|
||||
<meta name="HandheldFriendly" content="True">
|
||||
<meta name="MobileOptimized" content="320">
|
||||
<meta name="viewport" content="width=device-width, target-densitydpi=160dpi, initial-scale=1.0, maximum-scale=1, user-scalable=no, minimal-ui">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="heading">
|
||||
<h1 class="title">2048</h1>
|
||||
<div class="scores-container">
|
||||
<div class="score-container">0</div>
|
||||
<div class="best-container">0</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="above-game">
|
||||
<p class="game-intro">Join the numbers and get to the <strong>2048 tile!</strong></p>
|
||||
<a class="restart-button">New Game</a>
|
||||
</div>
|
||||
|
||||
<div class="game-container">
|
||||
<div class="game-message">
|
||||
<p></p>
|
||||
<div class="lower">
|
||||
<a class="keep-playing-button">Keep going</a>
|
||||
<a class="retry-button">Try again</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid-container">
|
||||
<div class="grid-row">
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
</div>
|
||||
<div class="grid-row">
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
</div>
|
||||
<div class="grid-row">
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
</div>
|
||||
<div class="grid-row">
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
<div class="grid-cell"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tile-container">
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p class="game-explanation">
|
||||
<strong class="important">How to play:</strong> Use your <strong>arrow keys</strong> to move the tiles. When two tiles with the same number touch, they <strong>merge into one!</strong>
|
||||
</p>
|
||||
<hr>
|
||||
<p>
|
||||
<strong class="important">Note:</strong> This site is the official version of 2048. You can play it on your phone via <a href="http://git.io/2048">http://git.io/2048.</a> All other apps or sites are derivatives or fakes, and should be used with caution.
|
||||
</p>
|
||||
<hr>
|
||||
<p>
|
||||
Created by <a href="http://gabrielecirulli.com" target="_blank">Gabriele Cirulli.</a> Based on <a href="https://itunes.apple.com/us/app/1024!/id823499224" target="_blank">1024 by Veewo Studio</a> and conceptually similar to <a href="http://asherv.com/threes/" target="_blank">Threes by Asher Vollmer.</a>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<script src="js/bind_polyfill.js"></script>
|
||||
<script src="js/classlist_polyfill.js"></script>
|
||||
<script src="js/animframe_polyfill.js"></script>
|
||||
<script src="js/keyboard_input_manager.js"></script>
|
||||
<script src="js/html_actuator.js"></script>
|
||||
<script src="js/grid.js"></script>
|
||||
<script src="js/tile.js"></script>
|
||||
<script src="js/local_storage_manager.js"></script>
|
||||
<script src="js/game_manager.js"></script>
|
||||
<script src="js/application.js"></script>
|
||||
</body>
|
||||
</html>
|
28
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/js/animframe_polyfill.js
Normal file
@ -0,0 +1,28 @@
|
||||
(function () {
|
||||
var lastTime = 0;
|
||||
var vendors = ['webkit', 'moz'];
|
||||
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
|
||||
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
|
||||
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||
|
||||
window[vendors[x] + 'CancelRequestAnimationFrame'];
|
||||
}
|
||||
|
||||
if (!window.requestAnimationFrame) {
|
||||
window.requestAnimationFrame = function (callback) {
|
||||
var currTime = new Date().getTime();
|
||||
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
|
||||
var id = window.setTimeout(function () {
|
||||
callback(currTime + timeToCall);
|
||||
},
|
||||
timeToCall);
|
||||
lastTime = currTime + timeToCall;
|
||||
return id;
|
||||
};
|
||||
}
|
||||
|
||||
if (!window.cancelAnimationFrame) {
|
||||
window.cancelAnimationFrame = function (id) {
|
||||
clearTimeout(id);
|
||||
};
|
||||
}
|
||||
}());
|
4
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/js/application.js
Normal file
@ -0,0 +1,4 @@
|
||||
// Wait till the browser is ready to render the game (avoids glitches)
|
||||
window.requestAnimationFrame(function () {
|
||||
new GameManager(4, KeyboardInputManager, HTMLActuator, LocalStorageManager);
|
||||
});
|
9
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/js/bind_polyfill.js
Normal file
@ -0,0 +1,9 @@
|
||||
Function.prototype.bind = Function.prototype.bind || function (target) {
|
||||
var self = this;
|
||||
return function (args) {
|
||||
if (!(args instanceof Array)) {
|
||||
args = [args];
|
||||
}
|
||||
self.apply(target, args);
|
||||
};
|
||||
};
|
71
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/js/classlist_polyfill.js
Normal file
@ -0,0 +1,71 @@
|
||||
(function () {
|
||||
if (typeof window.Element === "undefined" ||
|
||||
"classList" in document.documentElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
var prototype = Array.prototype,
|
||||
push = prototype.push,
|
||||
splice = prototype.splice,
|
||||
join = prototype.join;
|
||||
|
||||
function DOMTokenList(el) {
|
||||
this.el = el;
|
||||
// The className needs to be trimmed and split on whitespace
|
||||
// to retrieve a list of classes.
|
||||
var classes = el.className.replace(/^\s+|\s+$/g, '').split(/\s+/);
|
||||
for (var i = 0; i < classes.length; i++) {
|
||||
push.call(this, classes[i]);
|
||||
}
|
||||
}
|
||||
|
||||
DOMTokenList.prototype = {
|
||||
add: function (token) {
|
||||
if (this.contains(token)) return;
|
||||
push.call(this, token);
|
||||
this.el.className = this.toString();
|
||||
},
|
||||
contains: function (token) {
|
||||
return this.el.className.indexOf(token) != -1;
|
||||
},
|
||||
item: function (index) {
|
||||
return this[index] || null;
|
||||
},
|
||||
remove: function (token) {
|
||||
if (!this.contains(token)) return;
|
||||
for (var i = 0; i < this.length; i++) {
|
||||
if (this[i] == token) break;
|
||||
}
|
||||
splice.call(this, i, 1);
|
||||
this.el.className = this.toString();
|
||||
},
|
||||
toString: function () {
|
||||
return join.call(this, ' ');
|
||||
},
|
||||
toggle: function (token) {
|
||||
if (!this.contains(token)) {
|
||||
this.add(token);
|
||||
} else {
|
||||
this.remove(token);
|
||||
}
|
||||
|
||||
return this.contains(token);
|
||||
}
|
||||
};
|
||||
|
||||
window.DOMTokenList = DOMTokenList;
|
||||
|
||||
function defineElementGetter(obj, prop, getter) {
|
||||
if (Object.defineProperty) {
|
||||
Object.defineProperty(obj, prop, {
|
||||
get: getter
|
||||
});
|
||||
} else {
|
||||
obj.__defineGetter__(prop, getter);
|
||||
}
|
||||
}
|
||||
|
||||
defineElementGetter(HTMLElement.prototype, 'classList', function () {
|
||||
return new DOMTokenList(this);
|
||||
});
|
||||
})();
|
272
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/js/game_manager.js
Normal file
@ -0,0 +1,272 @@
|
||||
function GameManager(size, InputManager, Actuator, StorageManager) {
|
||||
this.size = size; // Size of the grid
|
||||
this.inputManager = new InputManager;
|
||||
this.storageManager = new StorageManager;
|
||||
this.actuator = new Actuator;
|
||||
|
||||
this.startTiles = 2;
|
||||
|
||||
this.inputManager.on("move", this.move.bind(this));
|
||||
this.inputManager.on("restart", this.restart.bind(this));
|
||||
this.inputManager.on("keepPlaying", this.keepPlaying.bind(this));
|
||||
|
||||
this.setup();
|
||||
}
|
||||
|
||||
// Restart the game
|
||||
GameManager.prototype.restart = function () {
|
||||
this.storageManager.clearGameState();
|
||||
this.actuator.continueGame(); // Clear the game won/lost message
|
||||
this.setup();
|
||||
};
|
||||
|
||||
// Keep playing after winning (allows going over 2048)
|
||||
GameManager.prototype.keepPlaying = function () {
|
||||
this.keepPlaying = true;
|
||||
this.actuator.continueGame(); // Clear the game won/lost message
|
||||
};
|
||||
|
||||
// Return true if the game is lost, or has won and the user hasn't kept playing
|
||||
GameManager.prototype.isGameTerminated = function () {
|
||||
return this.over || (this.won && !this.keepPlaying);
|
||||
};
|
||||
|
||||
// Set up the game
|
||||
GameManager.prototype.setup = function () {
|
||||
var previousState = this.storageManager.getGameState();
|
||||
|
||||
// Reload the game from a previous game if present
|
||||
if (previousState) {
|
||||
this.grid = new Grid(previousState.grid.size,
|
||||
previousState.grid.cells); // Reload grid
|
||||
this.score = previousState.score;
|
||||
this.over = previousState.over;
|
||||
this.won = previousState.won;
|
||||
this.keepPlaying = previousState.keepPlaying;
|
||||
} else {
|
||||
this.grid = new Grid(this.size);
|
||||
this.score = 0;
|
||||
this.over = false;
|
||||
this.won = false;
|
||||
this.keepPlaying = false;
|
||||
|
||||
// Add the initial tiles
|
||||
this.addStartTiles();
|
||||
}
|
||||
|
||||
// Update the actuator
|
||||
this.actuate();
|
||||
};
|
||||
|
||||
// Set up the initial tiles to start the game with
|
||||
GameManager.prototype.addStartTiles = function () {
|
||||
for (var i = 0; i < this.startTiles; i++) {
|
||||
this.addRandomTile();
|
||||
}
|
||||
};
|
||||
|
||||
// Adds a tile in a random position
|
||||
GameManager.prototype.addRandomTile = function () {
|
||||
if (this.grid.cellsAvailable()) {
|
||||
var value = Math.random() < 0.9 ? 2 : 4;
|
||||
var tile = new Tile(this.grid.randomAvailableCell(), value);
|
||||
|
||||
this.grid.insertTile(tile);
|
||||
}
|
||||
};
|
||||
|
||||
// Sends the updated grid to the actuator
|
||||
GameManager.prototype.actuate = function () {
|
||||
if (this.storageManager.getBestScore() < this.score) {
|
||||
this.storageManager.setBestScore(this.score);
|
||||
}
|
||||
|
||||
// Clear the state when the game is over (game over only, not win)
|
||||
if (this.over) {
|
||||
this.storageManager.clearGameState();
|
||||
} else {
|
||||
this.storageManager.setGameState(this.serialize());
|
||||
}
|
||||
|
||||
this.actuator.actuate(this.grid, {
|
||||
score: this.score,
|
||||
over: this.over,
|
||||
won: this.won,
|
||||
bestScore: this.storageManager.getBestScore(),
|
||||
terminated: this.isGameTerminated()
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
// Represent the current game as an object
|
||||
GameManager.prototype.serialize = function () {
|
||||
return {
|
||||
grid: this.grid.serialize(),
|
||||
score: this.score,
|
||||
over: this.over,
|
||||
won: this.won,
|
||||
keepPlaying: this.keepPlaying
|
||||
};
|
||||
};
|
||||
|
||||
// Save all tile positions and remove merger info
|
||||
GameManager.prototype.prepareTiles = function () {
|
||||
this.grid.eachCell(function (x, y, tile) {
|
||||
if (tile) {
|
||||
tile.mergedFrom = null;
|
||||
tile.savePosition();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// Move a tile and its representation
|
||||
GameManager.prototype.moveTile = function (tile, cell) {
|
||||
this.grid.cells[tile.x][tile.y] = null;
|
||||
this.grid.cells[cell.x][cell.y] = tile;
|
||||
tile.updatePosition(cell);
|
||||
};
|
||||
|
||||
// Move tiles on the grid in the specified direction
|
||||
GameManager.prototype.move = function (direction) {
|
||||
// 0: up, 1: right, 2: down, 3: left
|
||||
var self = this;
|
||||
|
||||
if (this.isGameTerminated()) return; // Don't do anything if the game's over
|
||||
|
||||
var cell, tile;
|
||||
|
||||
var vector = this.getVector(direction);
|
||||
var traversals = this.buildTraversals(vector);
|
||||
var moved = false;
|
||||
|
||||
// Save the current tile positions and remove merger information
|
||||
this.prepareTiles();
|
||||
|
||||
// Traverse the grid in the right direction and move tiles
|
||||
traversals.x.forEach(function (x) {
|
||||
traversals.y.forEach(function (y) {
|
||||
cell = { x: x, y: y };
|
||||
tile = self.grid.cellContent(cell);
|
||||
|
||||
if (tile) {
|
||||
var positions = self.findFarthestPosition(cell, vector);
|
||||
var next = self.grid.cellContent(positions.next);
|
||||
|
||||
// Only one merger per row traversal?
|
||||
if (next && next.value === tile.value && !next.mergedFrom) {
|
||||
var merged = new Tile(positions.next, tile.value * 2);
|
||||
merged.mergedFrom = [tile, next];
|
||||
|
||||
self.grid.insertTile(merged);
|
||||
self.grid.removeTile(tile);
|
||||
|
||||
// Converge the two tiles' positions
|
||||
tile.updatePosition(positions.next);
|
||||
|
||||
// Update the score
|
||||
self.score += merged.value;
|
||||
|
||||
// The mighty 2048 tile
|
||||
if (merged.value === 2048) self.won = true;
|
||||
} else {
|
||||
self.moveTile(tile, positions.farthest);
|
||||
}
|
||||
|
||||
if (!self.positionsEqual(cell, tile)) {
|
||||
moved = true; // The tile moved from its original cell!
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
if (moved) {
|
||||
this.addRandomTile();
|
||||
|
||||
if (!this.movesAvailable()) {
|
||||
this.over = true; // Game over!
|
||||
}
|
||||
|
||||
this.actuate();
|
||||
}
|
||||
};
|
||||
|
||||
// Get the vector representing the chosen direction
|
||||
GameManager.prototype.getVector = function (direction) {
|
||||
// Vectors representing tile movement
|
||||
var map = {
|
||||
0: { x: 0, y: -1 }, // Up
|
||||
1: { x: 1, y: 0 }, // Right
|
||||
2: { x: 0, y: 1 }, // Down
|
||||
3: { x: -1, y: 0 } // Left
|
||||
};
|
||||
|
||||
return map[direction];
|
||||
};
|
||||
|
||||
// Build a list of positions to traverse in the right order
|
||||
GameManager.prototype.buildTraversals = function (vector) {
|
||||
var traversals = { x: [], y: [] };
|
||||
|
||||
for (var pos = 0; pos < this.size; pos++) {
|
||||
traversals.x.push(pos);
|
||||
traversals.y.push(pos);
|
||||
}
|
||||
|
||||
// Always traverse from the farthest cell in the chosen direction
|
||||
if (vector.x === 1) traversals.x = traversals.x.reverse();
|
||||
if (vector.y === 1) traversals.y = traversals.y.reverse();
|
||||
|
||||
return traversals;
|
||||
};
|
||||
|
||||
GameManager.prototype.findFarthestPosition = function (cell, vector) {
|
||||
var previous;
|
||||
|
||||
// Progress towards the vector direction until an obstacle is found
|
||||
do {
|
||||
previous = cell;
|
||||
cell = { x: previous.x + vector.x, y: previous.y + vector.y };
|
||||
} while (this.grid.withinBounds(cell) &&
|
||||
this.grid.cellAvailable(cell));
|
||||
|
||||
return {
|
||||
farthest: previous,
|
||||
next: cell // Used to check if a merge is required
|
||||
};
|
||||
};
|
||||
|
||||
GameManager.prototype.movesAvailable = function () {
|
||||
return this.grid.cellsAvailable() || this.tileMatchesAvailable();
|
||||
};
|
||||
|
||||
// Check for available matches between tiles (more expensive check)
|
||||
GameManager.prototype.tileMatchesAvailable = function () {
|
||||
var self = this;
|
||||
|
||||
var tile;
|
||||
|
||||
for (var x = 0; x < this.size; x++) {
|
||||
for (var y = 0; y < this.size; y++) {
|
||||
tile = this.grid.cellContent({ x: x, y: y });
|
||||
|
||||
if (tile) {
|
||||
for (var direction = 0; direction < 4; direction++) {
|
||||
var vector = self.getVector(direction);
|
||||
var cell = { x: x + vector.x, y: y + vector.y };
|
||||
|
||||
var other = self.grid.cellContent(cell);
|
||||
|
||||
if (other && other.value === tile.value) {
|
||||
return true; // These two tiles can be merged
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
GameManager.prototype.positionsEqual = function (first, second) {
|
||||
return first.x === second.x && first.y === second.y;
|
||||
};
|
@ -0,0 +1,117 @@
|
||||
function Grid(size, previousState) {
|
||||
this.size = size;
|
||||
this.cells = previousState ? this.fromState(previousState) : this.empty();
|
||||
}
|
||||
|
||||
// Build a grid of the specified size
|
||||
Grid.prototype.empty = function () {
|
||||
var cells = [];
|
||||
|
||||
for (var x = 0; x < this.size; x++) {
|
||||
var row = cells[x] = [];
|
||||
|
||||
for (var y = 0; y < this.size; y++) {
|
||||
row.push(null);
|
||||
}
|
||||
}
|
||||
|
||||
return cells;
|
||||
};
|
||||
|
||||
Grid.prototype.fromState = function (state) {
|
||||
var cells = [];
|
||||
|
||||
for (var x = 0; x < this.size; x++) {
|
||||
var row = cells[x] = [];
|
||||
|
||||
for (var y = 0; y < this.size; y++) {
|
||||
var tile = state[x][y];
|
||||
row.push(tile ? new Tile(tile.position, tile.value) : null);
|
||||
}
|
||||
}
|
||||
|
||||
return cells;
|
||||
};
|
||||
|
||||
// Find the first available random position
|
||||
Grid.prototype.randomAvailableCell = function () {
|
||||
var cells = this.availableCells();
|
||||
|
||||
if (cells.length) {
|
||||
return cells[Math.floor(Math.random() * cells.length)];
|
||||
}
|
||||
};
|
||||
|
||||
Grid.prototype.availableCells = function () {
|
||||
var cells = [];
|
||||
|
||||
this.eachCell(function (x, y, tile) {
|
||||
if (!tile) {
|
||||
cells.push({ x: x, y: y });
|
||||
}
|
||||
});
|
||||
|
||||
return cells;
|
||||
};
|
||||
|
||||
// Call callback for every cell
|
||||
Grid.prototype.eachCell = function (callback) {
|
||||
for (var x = 0; x < this.size; x++) {
|
||||
for (var y = 0; y < this.size; y++) {
|
||||
callback(x, y, this.cells[x][y]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Check if there are any cells available
|
||||
Grid.prototype.cellsAvailable = function () {
|
||||
return !!this.availableCells().length;
|
||||
};
|
||||
|
||||
// Check if the specified cell is taken
|
||||
Grid.prototype.cellAvailable = function (cell) {
|
||||
return !this.cellOccupied(cell);
|
||||
};
|
||||
|
||||
Grid.prototype.cellOccupied = function (cell) {
|
||||
return !!this.cellContent(cell);
|
||||
};
|
||||
|
||||
Grid.prototype.cellContent = function (cell) {
|
||||
if (this.withinBounds(cell)) {
|
||||
return this.cells[cell.x][cell.y];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
// Inserts a tile at its position
|
||||
Grid.prototype.insertTile = function (tile) {
|
||||
this.cells[tile.x][tile.y] = tile;
|
||||
};
|
||||
|
||||
Grid.prototype.removeTile = function (tile) {
|
||||
this.cells[tile.x][tile.y] = null;
|
||||
};
|
||||
|
||||
Grid.prototype.withinBounds = function (position) {
|
||||
return position.x >= 0 && position.x < this.size &&
|
||||
position.y >= 0 && position.y < this.size;
|
||||
};
|
||||
|
||||
Grid.prototype.serialize = function () {
|
||||
var cellState = [];
|
||||
|
||||
for (var x = 0; x < this.size; x++) {
|
||||
var row = cellState[x] = [];
|
||||
|
||||
for (var y = 0; y < this.size; y++) {
|
||||
row.push(this.cells[x][y] ? this.cells[x][y].serialize() : null);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
size: this.size,
|
||||
cells: cellState
|
||||
};
|
||||
};
|
139
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/js/html_actuator.js
Normal file
@ -0,0 +1,139 @@
|
||||
function HTMLActuator() {
|
||||
this.tileContainer = document.querySelector(".tile-container");
|
||||
this.scoreContainer = document.querySelector(".score-container");
|
||||
this.bestContainer = document.querySelector(".best-container");
|
||||
this.messageContainer = document.querySelector(".game-message");
|
||||
|
||||
this.score = 0;
|
||||
}
|
||||
|
||||
HTMLActuator.prototype.actuate = function (grid, metadata) {
|
||||
var self = this;
|
||||
|
||||
window.requestAnimationFrame(function () {
|
||||
self.clearContainer(self.tileContainer);
|
||||
|
||||
grid.cells.forEach(function (column) {
|
||||
column.forEach(function (cell) {
|
||||
if (cell) {
|
||||
self.addTile(cell);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
self.updateScore(metadata.score);
|
||||
self.updateBestScore(metadata.bestScore);
|
||||
|
||||
if (metadata.terminated) {
|
||||
if (metadata.over) {
|
||||
self.message(false); // You lose
|
||||
} else if (metadata.won) {
|
||||
self.message(true); // You win!
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
// Continues the game (both restart and keep playing)
|
||||
HTMLActuator.prototype.continueGame = function () {
|
||||
this.clearMessage();
|
||||
};
|
||||
|
||||
HTMLActuator.prototype.clearContainer = function (container) {
|
||||
while (container.firstChild) {
|
||||
container.removeChild(container.firstChild);
|
||||
}
|
||||
};
|
||||
|
||||
HTMLActuator.prototype.addTile = function (tile) {
|
||||
var self = this;
|
||||
|
||||
var wrapper = document.createElement("div");
|
||||
var inner = document.createElement("div");
|
||||
var position = tile.previousPosition || { x: tile.x, y: tile.y };
|
||||
var positionClass = this.positionClass(position);
|
||||
|
||||
// We can't use classlist because it somehow glitches when replacing classes
|
||||
var classes = ["tile", "tile-" + tile.value, positionClass];
|
||||
|
||||
if (tile.value > 2048) classes.push("tile-super");
|
||||
|
||||
this.applyClasses(wrapper, classes);
|
||||
|
||||
inner.classList.add("tile-inner");
|
||||
inner.textContent = tile.value;
|
||||
|
||||
if (tile.previousPosition) {
|
||||
// Make sure that the tile gets rendered in the previous position first
|
||||
window.requestAnimationFrame(function () {
|
||||
classes[2] = self.positionClass({ x: tile.x, y: tile.y });
|
||||
self.applyClasses(wrapper, classes); // Update the position
|
||||
});
|
||||
} else if (tile.mergedFrom) {
|
||||
classes.push("tile-merged");
|
||||
this.applyClasses(wrapper, classes);
|
||||
|
||||
// Render the tiles that merged
|
||||
tile.mergedFrom.forEach(function (merged) {
|
||||
self.addTile(merged);
|
||||
});
|
||||
} else {
|
||||
classes.push("tile-new");
|
||||
this.applyClasses(wrapper, classes);
|
||||
}
|
||||
|
||||
// Add the inner part of the tile to the wrapper
|
||||
wrapper.appendChild(inner);
|
||||
|
||||
// Put the tile on the board
|
||||
this.tileContainer.appendChild(wrapper);
|
||||
};
|
||||
|
||||
HTMLActuator.prototype.applyClasses = function (element, classes) {
|
||||
element.setAttribute("class", classes.join(" "));
|
||||
};
|
||||
|
||||
HTMLActuator.prototype.normalizePosition = function (position) {
|
||||
return { x: position.x + 1, y: position.y + 1 };
|
||||
};
|
||||
|
||||
HTMLActuator.prototype.positionClass = function (position) {
|
||||
position = this.normalizePosition(position);
|
||||
return "tile-position-" + position.x + "-" + position.y;
|
||||
};
|
||||
|
||||
HTMLActuator.prototype.updateScore = function (score) {
|
||||
this.clearContainer(this.scoreContainer);
|
||||
|
||||
var difference = score - this.score;
|
||||
this.score = score;
|
||||
|
||||
this.scoreContainer.textContent = this.score;
|
||||
|
||||
if (difference > 0) {
|
||||
var addition = document.createElement("div");
|
||||
addition.classList.add("score-addition");
|
||||
addition.textContent = "+" + difference;
|
||||
|
||||
this.scoreContainer.appendChild(addition);
|
||||
}
|
||||
};
|
||||
|
||||
HTMLActuator.prototype.updateBestScore = function (bestScore) {
|
||||
this.bestContainer.textContent = bestScore;
|
||||
};
|
||||
|
||||
HTMLActuator.prototype.message = function (won) {
|
||||
var type = won ? "game-won" : "game-over";
|
||||
var message = won ? "You win!" : "Game over!";
|
||||
|
||||
this.messageContainer.classList.add(type);
|
||||
this.messageContainer.getElementsByTagName("p")[0].textContent = message;
|
||||
};
|
||||
|
||||
HTMLActuator.prototype.clearMessage = function () {
|
||||
// IE only takes one value to remove at a time.
|
||||
this.messageContainer.classList.remove("game-won");
|
||||
this.messageContainer.classList.remove("game-over");
|
||||
};
|
144
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/js/keyboard_input_manager.js
Normal file
@ -0,0 +1,144 @@
|
||||
function KeyboardInputManager() {
|
||||
this.events = {};
|
||||
|
||||
if (window.navigator.msPointerEnabled) {
|
||||
//Internet Explorer 10 style
|
||||
this.eventTouchstart = "MSPointerDown";
|
||||
this.eventTouchmove = "MSPointerMove";
|
||||
this.eventTouchend = "MSPointerUp";
|
||||
} else {
|
||||
this.eventTouchstart = "touchstart";
|
||||
this.eventTouchmove = "touchmove";
|
||||
this.eventTouchend = "touchend";
|
||||
}
|
||||
|
||||
this.listen();
|
||||
}
|
||||
|
||||
KeyboardInputManager.prototype.on = function (event, callback) {
|
||||
if (!this.events[event]) {
|
||||
this.events[event] = [];
|
||||
}
|
||||
this.events[event].push(callback);
|
||||
};
|
||||
|
||||
KeyboardInputManager.prototype.emit = function (event, data) {
|
||||
var callbacks = this.events[event];
|
||||
if (callbacks) {
|
||||
callbacks.forEach(function (callback) {
|
||||
callback(data);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
KeyboardInputManager.prototype.listen = function () {
|
||||
var self = this;
|
||||
|
||||
var map = {
|
||||
38: 0, // Up
|
||||
39: 1, // Right
|
||||
40: 2, // Down
|
||||
37: 3, // Left
|
||||
75: 0, // Vim up
|
||||
76: 1, // Vim right
|
||||
74: 2, // Vim down
|
||||
72: 3, // Vim left
|
||||
87: 0, // W
|
||||
68: 1, // D
|
||||
83: 2, // S
|
||||
65: 3 // A
|
||||
};
|
||||
|
||||
// Respond to direction keys
|
||||
document.addEventListener("keydown", function (event) {
|
||||
var modifiers = event.altKey || event.ctrlKey || event.metaKey ||
|
||||
event.shiftKey;
|
||||
var mapped = map[event.which];
|
||||
|
||||
if (!modifiers) {
|
||||
if (mapped !== undefined) {
|
||||
event.preventDefault();
|
||||
self.emit("move", mapped);
|
||||
}
|
||||
}
|
||||
|
||||
// R key restarts the game
|
||||
if (!modifiers && event.which === 82) {
|
||||
self.restart.call(self, event);
|
||||
}
|
||||
});
|
||||
|
||||
// Respond to button presses
|
||||
this.bindButtonPress(".retry-button", this.restart);
|
||||
this.bindButtonPress(".restart-button", this.restart);
|
||||
this.bindButtonPress(".keep-playing-button", this.keepPlaying);
|
||||
|
||||
// Respond to swipe events
|
||||
var touchStartClientX, touchStartClientY;
|
||||
var gameContainer = document.getElementsByClassName("game-container")[0];
|
||||
|
||||
gameContainer.addEventListener(this.eventTouchstart, function (event) {
|
||||
if ((!window.navigator.msPointerEnabled && event.touches.length > 1) ||
|
||||
event.targetTouches.length > 1) {
|
||||
return; // Ignore if touching with more than 1 finger
|
||||
}
|
||||
|
||||
if (window.navigator.msPointerEnabled) {
|
||||
touchStartClientX = event.pageX;
|
||||
touchStartClientY = event.pageY;
|
||||
} else {
|
||||
touchStartClientX = event.touches[0].clientX;
|
||||
touchStartClientY = event.touches[0].clientY;
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
gameContainer.addEventListener(this.eventTouchmove, function (event) {
|
||||
event.preventDefault();
|
||||
});
|
||||
|
||||
gameContainer.addEventListener(this.eventTouchend, function (event) {
|
||||
if ((!window.navigator.msPointerEnabled && event.touches.length > 0) ||
|
||||
event.targetTouches.length > 0) {
|
||||
return; // Ignore if still touching with one or more fingers
|
||||
}
|
||||
|
||||
var touchEndClientX, touchEndClientY;
|
||||
|
||||
if (window.navigator.msPointerEnabled) {
|
||||
touchEndClientX = event.pageX;
|
||||
touchEndClientY = event.pageY;
|
||||
} else {
|
||||
touchEndClientX = event.changedTouches[0].clientX;
|
||||
touchEndClientY = event.changedTouches[0].clientY;
|
||||
}
|
||||
|
||||
var dx = touchEndClientX - touchStartClientX;
|
||||
var absDx = Math.abs(dx);
|
||||
|
||||
var dy = touchEndClientY - touchStartClientY;
|
||||
var absDy = Math.abs(dy);
|
||||
|
||||
if (Math.max(absDx, absDy) > 10) {
|
||||
// (right : left) : (down : up)
|
||||
self.emit("move", absDx > absDy ? (dx > 0 ? 1 : 3) : (dy > 0 ? 2 : 0));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
KeyboardInputManager.prototype.restart = function (event) {
|
||||
event.preventDefault();
|
||||
this.emit("restart");
|
||||
};
|
||||
|
||||
KeyboardInputManager.prototype.keepPlaying = function (event) {
|
||||
event.preventDefault();
|
||||
this.emit("keepPlaying");
|
||||
};
|
||||
|
||||
KeyboardInputManager.prototype.bindButtonPress = function (selector, fn) {
|
||||
var button = document.querySelector(selector);
|
||||
button.addEventListener("click", fn.bind(this));
|
||||
button.addEventListener(this.eventTouchend, fn.bind(this));
|
||||
};
|
63
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/js/local_storage_manager.js
Normal file
@ -0,0 +1,63 @@
|
||||
window.fakeStorage = {
|
||||
_data: {},
|
||||
|
||||
setItem: function (id, val) {
|
||||
return this._data[id] = String(val);
|
||||
},
|
||||
|
||||
getItem: function (id) {
|
||||
return this._data.hasOwnProperty(id) ? this._data[id] : undefined;
|
||||
},
|
||||
|
||||
removeItem: function (id) {
|
||||
return delete this._data[id];
|
||||
},
|
||||
|
||||
clear: function () {
|
||||
return this._data = {};
|
||||
}
|
||||
};
|
||||
|
||||
function LocalStorageManager() {
|
||||
this.bestScoreKey = "bestScore";
|
||||
this.gameStateKey = "gameState";
|
||||
|
||||
var supported = this.localStorageSupported();
|
||||
this.storage = supported ? window.localStorage : window.fakeStorage;
|
||||
}
|
||||
|
||||
LocalStorageManager.prototype.localStorageSupported = function () {
|
||||
var testKey = "test";
|
||||
|
||||
try {
|
||||
var storage = window.localStorage;
|
||||
storage.setItem(testKey, "1");
|
||||
storage.removeItem(testKey);
|
||||
return true;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// Best score getters/setters
|
||||
LocalStorageManager.prototype.getBestScore = function () {
|
||||
return this.storage.getItem(this.bestScoreKey) || 0;
|
||||
};
|
||||
|
||||
LocalStorageManager.prototype.setBestScore = function (score) {
|
||||
this.storage.setItem(this.bestScoreKey, score);
|
||||
};
|
||||
|
||||
// Game state getters/setters and clearing
|
||||
LocalStorageManager.prototype.getGameState = function () {
|
||||
var stateJSON = this.storage.getItem(this.gameStateKey);
|
||||
return stateJSON ? JSON.parse(stateJSON) : null;
|
||||
};
|
||||
|
||||
LocalStorageManager.prototype.setGameState = function (gameState) {
|
||||
this.storage.setItem(this.gameStateKey, JSON.stringify(gameState));
|
||||
};
|
||||
|
||||
LocalStorageManager.prototype.clearGameState = function () {
|
||||
this.storage.removeItem(this.gameStateKey);
|
||||
};
|
@ -0,0 +1,27 @@
|
||||
function Tile(position, value) {
|
||||
this.x = position.x;
|
||||
this.y = position.y;
|
||||
this.value = value || 2;
|
||||
|
||||
this.previousPosition = null;
|
||||
this.mergedFrom = null; // Tracks tiles that merged together
|
||||
}
|
||||
|
||||
Tile.prototype.savePosition = function () {
|
||||
this.previousPosition = { x: this.x, y: this.y };
|
||||
};
|
||||
|
||||
Tile.prototype.updatePosition = function (position) {
|
||||
this.x = position.x;
|
||||
this.y = position.y;
|
||||
};
|
||||
|
||||
Tile.prototype.serialize = function () {
|
||||
return {
|
||||
position: {
|
||||
x: this.x,
|
||||
y: this.y
|
||||
},
|
||||
value: this.value
|
||||
};
|
||||
};
|
BIN
new-deb-build/opt/apps/com.gitee.uengine.runner.spark/files/Help/2048/meta/apple-touch-icon.png
Normal file
After ![]() (image error) Size: 5.7 KiB |