mirror of
https://gitee.com/gfdgd-xi/deep-wine-runner
synced 2026-08-06 10:43:56 +08:00
初步多终端实现
This commit is contained in:
+15
-10
@@ -19,6 +19,15 @@ import urllib.parse as parse
|
||||
|
||||
def CleanTerminal():
|
||||
os.system("clear")
|
||||
print('''
|
||||
mm mmmm m
|
||||
## mmmm mmmm #" " mm#mm mmm m mm mmm
|
||||
# # #" "# #" "# "#mmm # #" "# #" " #" #
|
||||
#mm# # # # # "# # # # # #""""
|
||||
# # ##m#" ##m#" "mmm#" "mm "#m#" # "#mm"
|
||||
# #
|
||||
" "
|
||||
''')
|
||||
print("本软件源来自腾讯软件管家,只会下载文件后缀为“.exe”的文件")
|
||||
print("请输入要搜索的内容,如果要结束,请输入“exit”或点击右上角“×”关闭")
|
||||
print("无法保证从这里下载的安装包能正常安装/运行")
|
||||
@@ -37,15 +46,6 @@ if __name__ == "__main__":
|
||||
sys.exit()
|
||||
|
||||
CleanTerminal()
|
||||
print('''
|
||||
mm mmmm m
|
||||
## mmmm mmmm #" " mm#mm mmm m mm mmm
|
||||
# # #" "# #" "# "#mmm # #" "# #" " #" #
|
||||
#mm# # # # # "# # # # # #""""
|
||||
# # ##m#" ##m#" "mmm#" "mm "#m#" # "#mm"
|
||||
# #
|
||||
" "
|
||||
''')
|
||||
while True:
|
||||
search = input(">")
|
||||
if search.replace(" ", "").replace("\n", "") == "":
|
||||
@@ -54,7 +54,12 @@ if __name__ == "__main__":
|
||||
break # 结束程序
|
||||
|
||||
# 获取初步 API
|
||||
apiReturn = json.loads(requests.get(f"https://s.pcmgr.qq.com/tapi/web/searchcgi.php?type=search&callback=searchCallback&keyword={parse.quote(search)}&page=1&pernum=30").text[:-2][15:])
|
||||
try:
|
||||
apiReturn = json.loads(requests.get(f"https://s.pcmgr.qq.com/tapi/web/searchcgi.php?type=search&callback=searchCallback&keyword={parse.quote(search)}&page=1&pernum=30").text[:-2][15:])
|
||||
except:
|
||||
input("无法连接服务器,按回车键继续")
|
||||
CleanTerminal()
|
||||
continue
|
||||
option = 0
|
||||
downloadUrl = []
|
||||
if not "list" in apiReturn:
|
||||
|
||||
+9
-6
@@ -17,6 +17,7 @@ import traceback
|
||||
import requests
|
||||
import PyQt5.QtWidgets as QtWidgets
|
||||
from UI.AutoConfig import *
|
||||
from Model import *
|
||||
|
||||
urlSources = "https://code.gitlink.org.cn/gfdgd_xi/wine-runner-list/raw/branch/master/auto"
|
||||
lists = []
|
||||
@@ -60,18 +61,20 @@ class Connect:
|
||||
QtWidgets.QMessageBox.critical(window, "错误", "无法获取配置文件")
|
||||
return
|
||||
# 执行脚本
|
||||
process = QtCore.QProcess()
|
||||
process.start(f"{programPath}/launch.sh", ["deepin-terminal", "-e", "env", f"WINE={wine}", f"WINEPREFIX={wineprefix}", f"{programPath}/ConfigLanguareRunner.py", "/tmp/wine-runner-auto-config.wsh", "--system"])
|
||||
process.waitForFinished()
|
||||
OpenTerminal(f"env WINE='{wine}' WINEPREFIX='{wineprefix}' '{programPath}/ConfigLanguareRunner.py' '/tmp/wine-runner-auto-config.wsh' --system")
|
||||
#process = QtCore.QProcess()
|
||||
#process.start(f"{programPath}/launch.sh", ["deepin-terminal", "-e", "env", f"WINE={wine}", f"WINEPREFIX={wineprefix}", f"{programPath}/ConfigLanguareRunner.py", "/tmp/wine-runner-auto-config.wsh", "--system"])
|
||||
#process.waitForFinished()
|
||||
|
||||
def OpenFile_Triggered():
|
||||
path = QtWidgets.QFileDialog.getOpenFileName(window, "提示", homePath, "配置文件(*.sh *.wsh);;全部文件(*.*)")
|
||||
if path[0] == "":
|
||||
return
|
||||
# 执行脚本
|
||||
process = QtCore.QProcess()
|
||||
process.start(f"{programPath}/launch.sh", ["deepin-terminal", "-e", "env", f"WINE={wine}", f"WINEPREFIX={wineprefix}", f"{programPath}/ConfigLanguareRunner.py", path[0], "--system"])
|
||||
process.waitForFinished()
|
||||
OpenTerminal(f"env WINE='{wine}' WINEPREFIX='{wineprefix}' '{programPath}/ConfigLanguareRunner.py' '{path[0]}' --system")
|
||||
#process = QtCore.QProcess()
|
||||
#process.start(f"{programPath}/launch.sh", ["deepin-terminal", "-e", "env", f"WINE={wine}", f"WINEPREFIX={wineprefix}", f"{programPath}/ConfigLanguareRunner.py", path[0], "--system"])
|
||||
#process.waitForFinished()
|
||||
|
||||
# 读取文本文档
|
||||
def readtxt(path):
|
||||
|
||||
@@ -15,6 +15,11 @@ import sys
|
||||
import json
|
||||
import traceback
|
||||
import requests
|
||||
def exit():
|
||||
if __name__ == "__main__":
|
||||
input("按回车键退出")
|
||||
sys.exit()
|
||||
sys.exit()
|
||||
# 获取云列表
|
||||
url = "https://code.gitlink.org.cn/gfdgd_xi/wine-runner-list/raw/branch/master/dlls"
|
||||
print("获取列表中……", end="")
|
||||
|
||||
+4
-1
@@ -86,5 +86,8 @@ if __name__ == "__main__":
|
||||
os.system(f"aria2c -x 16 -s 16 -d '{homePath}/.cache/deepin-wine-runner/font' -o '{fontList[choose][0]}' \"{fontList[choose][1]}\"")
|
||||
if os.path.exists(f"{sys.argv[1]}/drive_c/windows/Fonts/{fontList[choose][2]}"):
|
||||
print("字体已存在,覆盖")
|
||||
shutil.copy(f"{homePath}/.cache/deepin-wine-runner/font/{fontList[choose][0]}", f"{sys.argv[1]}/drive_c/windows/Fonts/{fontList[choose][2]}")
|
||||
try:
|
||||
shutil.copy(f"{homePath}/.cache/deepin-wine-runner/font/{fontList[choose][0]}", f"{sys.argv[1]}/drive_c/windows/Fonts/{fontList[choose][2]}")
|
||||
except:
|
||||
print("拷贝失败!")
|
||||
input("安装结束,按回车键继续")
|
||||
@@ -0,0 +1,31 @@
|
||||
import os
|
||||
def OpenTerminal(command):
|
||||
if terminalEnd[terminal][1]:
|
||||
os.system(f"\"{terminal}\" \"{terminalEnd[terminal][0]}\" \"{command}\"")
|
||||
return
|
||||
os.system(f"\"{terminal}\" \"{terminalEnd[terminal][0]}\" {command}")
|
||||
programPath = os.path.split(os.path.realpath(__file__))[0] # 返回 string
|
||||
# 对终端的获取
|
||||
# 为什么 openkylin 只有 mate-terminal
|
||||
# 优先为深度终端
|
||||
terminal = ""
|
||||
terminalList = [
|
||||
"deepin-terminal1",
|
||||
"mate-terminal1",
|
||||
"gnome-terminal"
|
||||
]
|
||||
terminalEnd = {
|
||||
f"{programPath}/launch.sh\" \"deepin-terminal": ["-e", 0],
|
||||
"mate-terminal": ["-e", 1],
|
||||
"gnome-terminal": ["--", 0]
|
||||
}
|
||||
for i in terminalList:
|
||||
if not os.system(f"which {i}"):
|
||||
if i == "deepin-terminal":
|
||||
i = f"{programPath}/launch.sh\" \"deepin-terminal"
|
||||
terminal = i
|
||||
break
|
||||
if terminal == "":
|
||||
print("无法识别到以下的任意一个终端")
|
||||
print(" ".join(terminalList))
|
||||
exit()
|
||||
Binary file not shown.
@@ -5,6 +5,7 @@ Homepage: https://gitee.com/gfdgd-xi/deep-wine-runner
|
||||
Architecture: all
|
||||
Priority: optional
|
||||
Depends: python3, python3-pil, python3-pil.imagetk, python3-pyquery, deepin-terminal, aria2, curl, unrar, unzip, python3-requests, fakeroot, bash, python3-pyqt5, python3-psutil
|
||||
Section: utils
|
||||
Conflicts: spark.deepin-venturi-setter, spark-deepin-wine5-application-packer, spark-deepin-wine-runner-52
|
||||
Replaces: spark.deepin-venturi-setter, spark-deepin-wine5-application-packer, spark-deepin-wine-runner-52
|
||||
Installed-Size: 24928
|
||||
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 11 KiB |
Executable
+231
@@ -0,0 +1,231 @@
|
||||
#!/usr/bin/env bash
|
||||
function wait(){
|
||||
echo ""
|
||||
}
|
||||
# default directories
|
||||
dxvk_lib32=${dxvk_lib32:-"x32"}
|
||||
dxvk_lib64=${dxvk_lib64:-"x64"}
|
||||
|
||||
# figure out where we are
|
||||
basedir=$(dirname "$(readlink -f $0)")
|
||||
|
||||
# figure out which action to perform
|
||||
action="$1"
|
||||
|
||||
case "$action" in
|
||||
install)
|
||||
;;
|
||||
uninstall)
|
||||
;;
|
||||
*)
|
||||
echo "Unrecognized action: $action"
|
||||
echo "Usage: $0 [install|uninstall] [--without-dxgi] [--with-d3d10] [--symlink]"
|
||||
wait
|
||||
exit 1
|
||||
esac
|
||||
|
||||
# process arguments
|
||||
shift
|
||||
|
||||
with_dxgi=true
|
||||
with_d3d10=false
|
||||
file_cmd="cp -v"
|
||||
|
||||
while (($# > 0)); do
|
||||
case "$1" in
|
||||
"--without-dxgi")
|
||||
with_dxgi=false
|
||||
;;
|
||||
"--with-d3d10")
|
||||
with_d3d10=true
|
||||
;;
|
||||
"--symlink")
|
||||
file_cmd="ln -s -v"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# check wine prefix before invoking wine, so that we
|
||||
# don't accidentally create one if the user screws up
|
||||
if [ -n "$WINEPREFIX" ] && ! [ -f "$WINEPREFIX/system.reg" ]; then
|
||||
echo "$WINEPREFIX:"' Not a valid wine prefix.' >&2
|
||||
wait
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# find wine executable
|
||||
export WINEDEBUG=-all
|
||||
# disable mscoree and mshtml to avoid downloading
|
||||
# wine gecko and mono
|
||||
export WINEDLLOVERRIDES="mscoree,mshtml="
|
||||
# 专门添加,为了可以使用自定义的 wine
|
||||
wine=$WINE
|
||||
wine64=$WINE64
|
||||
wineboot="$WINE wineboot"
|
||||
if [[ $WINE == "" ]];then
|
||||
wine="wine"
|
||||
fi
|
||||
if [[ $WINE64 == "" ]];then
|
||||
wine64="wine64"
|
||||
fi
|
||||
|
||||
# $PATH is the way for user to control where wine is located (including custom Wine versions).
|
||||
# Pure 64-bit Wine (non Wow64) requries skipping 32-bit steps.
|
||||
# In such case, wine64 and winebooot will be present, but wine binary will be missing,
|
||||
# however it can be present in other PATHs, so it shouldn't be used, to avoid versions mixing.
|
||||
wine_path=$(dirname "$(which $wineboot)")
|
||||
wow64=true
|
||||
if ! [ -f "$wine_path/$wine" ]; then
|
||||
wine=$wine64
|
||||
wow64=false
|
||||
wineboot="$wine64 wineboot"
|
||||
fi
|
||||
|
||||
# resolve 32-bit and 64-bit system32 path
|
||||
winever=$($wine --version | grep wine)
|
||||
if [ -z "$winever" ]; then
|
||||
echo "$wine:"' Not a wine executable. Check your $wine.' >&2
|
||||
wait
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ensure wine placeholder dlls are recreated
|
||||
# if they are missing
|
||||
$wineboot -u
|
||||
|
||||
win64_sys_path=$($wine64 winepath -u 'C:\windows\system32' 2> /dev/null)
|
||||
win64_sys_path="${win64_sys_path/$'\r'/}"
|
||||
if $wow64; then
|
||||
win32_sys_path=$($wine winepath -u 'C:\windows\system32' 2> /dev/null)
|
||||
win32_sys_path="${win32_sys_path/$'\r'/}"
|
||||
fi
|
||||
|
||||
if [ -z "$win32_sys_path" ] && [ -z "$win64_sys_path" ]; then
|
||||
echo 'Failed to resolve C:\windows\system32.' >&2
|
||||
wait
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# create native dll override
|
||||
overrideDll() {
|
||||
$wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v $1 /d native /f >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "Failed to add override for $1"
|
||||
wait
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# remove dll override
|
||||
restoreDll() {
|
||||
$wine reg delete 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v $1 /f > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to remove override for $1"
|
||||
fi
|
||||
}
|
||||
|
||||
# copy or link dxvk dll, back up original file
|
||||
installFile() {
|
||||
dstfile="${1}/${3}.dll"
|
||||
srcfile="${basedir}/${2}/${3}.dll"
|
||||
|
||||
if [ -f "${srcfile}.so" ]; then
|
||||
srcfile="${srcfile}.so"
|
||||
fi
|
||||
|
||||
if ! [ -f "${srcfile}" ]; then
|
||||
echo "${srcfile}: File not found. Skipping." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
if [ -f "${dstfile}" ] || [ -h "${dstfile}" ]; then
|
||||
if ! [ -f "${dstfile}.old" ]; then
|
||||
mv -v "${dstfile}" "${dstfile}.old"
|
||||
else
|
||||
rm -v "${dstfile}"
|
||||
fi
|
||||
$file_cmd "${srcfile}" "${dstfile}"
|
||||
else
|
||||
echo "${dstfile}: File not found in wine prefix" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# remove dxvk dll, restore original file
|
||||
uninstallFile() {
|
||||
dstfile="${1}/${3}.dll"
|
||||
srcfile="${basedir}/${2}/${3}.dll"
|
||||
|
||||
if [ -f "${srcfile}.so" ]; then
|
||||
srcfile="${srcfile}.so"
|
||||
fi
|
||||
|
||||
if ! [ -f "${srcfile}" ]; then
|
||||
echo "${srcfile}: File not found. Skipping." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! [ -f "${dstfile}" ] && ! [ -h "${dstfile}" ]; then
|
||||
echo "${dstfile}: File not found. Skipping." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -f "${dstfile}.old" ]; then
|
||||
rm -v "${dstfile}"
|
||||
mv -v "${dstfile}.old" "${dstfile}"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
install() {
|
||||
installFile "$win64_sys_path" "$dxvk_lib64" "$1"
|
||||
inst64_ret="$?"
|
||||
|
||||
inst32_ret=-1
|
||||
if $wow64; then
|
||||
installFile "$win32_sys_path" "$dxvk_lib32" "$1"
|
||||
inst32_ret="$?"
|
||||
fi
|
||||
|
||||
if (( ($inst32_ret == 0) || ($inst64_ret == 0) )); then
|
||||
overrideDll "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
uninstallFile "$win64_sys_path" "$dxvk_lib64" "$1"
|
||||
uninst64_ret="$?"
|
||||
|
||||
uninst32_ret=-1
|
||||
if $wow64; then
|
||||
uninstallFile "$win32_sys_path" "$dxvk_lib32" "$1"
|
||||
uninst32_ret="$?"
|
||||
fi
|
||||
|
||||
if (( ($uninst32_ret == 0) || ($uninst64_ret == 0) )); then
|
||||
restoreDll "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# skip dxgi during install if not explicitly
|
||||
# enabled, but always try to uninstall it
|
||||
if $with_dxgi || [ "$action" == "uninstall" ]; then
|
||||
$action dxgi
|
||||
fi
|
||||
|
||||
$action d3d9
|
||||
|
||||
if $with_d3d10 || [ "$action" == "uninstall" ]; then
|
||||
$action d3d10
|
||||
$action d3d10_1
|
||||
fi
|
||||
|
||||
$action d3d10core
|
||||
$action d3d11
|
||||
wait
|
||||
Executable
+232
@@ -0,0 +1,232 @@
|
||||
#!/usr/bin/env bash
|
||||
function wait(){
|
||||
echo Press Enter To Exit
|
||||
read
|
||||
}
|
||||
# default directories
|
||||
dxvk_lib32=${dxvk_lib32:-"x32"}
|
||||
dxvk_lib64=${dxvk_lib64:-"x64"}
|
||||
|
||||
# figure out where we are
|
||||
basedir=$(dirname "$(readlink -f $0)")
|
||||
|
||||
# figure out which action to perform
|
||||
action="$1"
|
||||
|
||||
case "$action" in
|
||||
install)
|
||||
;;
|
||||
uninstall)
|
||||
;;
|
||||
*)
|
||||
echo "Unrecognized action: $action"
|
||||
echo "Usage: $0 [install|uninstall] [--without-dxgi] [--with-d3d10] [--symlink]"
|
||||
wait
|
||||
exit 1
|
||||
esac
|
||||
|
||||
# process arguments
|
||||
shift
|
||||
|
||||
with_dxgi=true
|
||||
with_d3d10=false
|
||||
file_cmd="cp -v"
|
||||
|
||||
while (($# > 0)); do
|
||||
case "$1" in
|
||||
"--without-dxgi")
|
||||
with_dxgi=false
|
||||
;;
|
||||
"--with-d3d10")
|
||||
with_d3d10=true
|
||||
;;
|
||||
"--symlink")
|
||||
file_cmd="ln -s -v"
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# check wine prefix before invoking wine, so that we
|
||||
# don't accidentally create one if the user screws up
|
||||
if [ -n "$WINEPREFIX" ] && ! [ -f "$WINEPREFIX/system.reg" ]; then
|
||||
echo "$WINEPREFIX:"' Not a valid wine prefix.' >&2
|
||||
wait
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# find wine executable
|
||||
export WINEDEBUG=-all
|
||||
# disable mscoree and mshtml to avoid downloading
|
||||
# wine gecko and mono
|
||||
export WINEDLLOVERRIDES="mscoree,mshtml="
|
||||
# 专门添加,为了可以使用自定义的 wine
|
||||
wine=$WINE
|
||||
wine64=$WINE64
|
||||
wineboot="$WINE wineboot"
|
||||
if [[ $WINE == "" ]];then
|
||||
wine="wine"
|
||||
fi
|
||||
if [[ $WINE64 == "" ]];then
|
||||
wine64="wine64"
|
||||
fi
|
||||
|
||||
# $PATH is the way for user to control where wine is located (including custom Wine versions).
|
||||
# Pure 64-bit Wine (non Wow64) requries skipping 32-bit steps.
|
||||
# In such case, wine64 and winebooot will be present, but wine binary will be missing,
|
||||
# however it can be present in other PATHs, so it shouldn't be used, to avoid versions mixing.
|
||||
wine_path=$(dirname "$(which $wineboot)")
|
||||
wow64=true
|
||||
if ! [ -f "$wine_path/$wine" ]; then
|
||||
wine=$wine64
|
||||
wow64=false
|
||||
wineboot="$wine64 wineboot"
|
||||
fi
|
||||
|
||||
# resolve 32-bit and 64-bit system32 path
|
||||
winever=$($wine --version | grep wine)
|
||||
if [ -z "$winever" ]; then
|
||||
echo "$wine:"' Not a wine executable. Check your $wine.' >&2
|
||||
wait
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# ensure wine placeholder dlls are recreated
|
||||
# if they are missing
|
||||
$wineboot -u
|
||||
|
||||
win64_sys_path=$($wine64 winepath -u 'C:\windows\system32' 2> /dev/null)
|
||||
win64_sys_path="${win64_sys_path/$'\r'/}"
|
||||
if $wow64; then
|
||||
win32_sys_path=$($wine winepath -u 'C:\windows\system32' 2> /dev/null)
|
||||
win32_sys_path="${win32_sys_path/$'\r'/}"
|
||||
fi
|
||||
|
||||
if [ -z "$win32_sys_path" ] && [ -z "$win64_sys_path" ]; then
|
||||
echo 'Failed to resolve C:\windows\system32.' >&2
|
||||
wait
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# create native dll override
|
||||
overrideDll() {
|
||||
$wine reg add 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v $1 /d native /f >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "Failed to add override for $1"
|
||||
wait
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# remove dll override
|
||||
restoreDll() {
|
||||
$wine reg delete 'HKEY_CURRENT_USER\Software\Wine\DllOverrides' /v $1 /f > /dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
echo "Failed to remove override for $1"
|
||||
fi
|
||||
}
|
||||
|
||||
# copy or link dxvk dll, back up original file
|
||||
installFile() {
|
||||
dstfile="${1}/${3}.dll"
|
||||
srcfile="${basedir}/${2}/${3}.dll"
|
||||
|
||||
if [ -f "${srcfile}.so" ]; then
|
||||
srcfile="${srcfile}.so"
|
||||
fi
|
||||
|
||||
if ! [ -f "${srcfile}" ]; then
|
||||
echo "${srcfile}: File not found. Skipping." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
if [ -f "${dstfile}" ] || [ -h "${dstfile}" ]; then
|
||||
if ! [ -f "${dstfile}.old" ]; then
|
||||
mv -v "${dstfile}" "${dstfile}.old"
|
||||
else
|
||||
rm -v "${dstfile}"
|
||||
fi
|
||||
$file_cmd "${srcfile}" "${dstfile}"
|
||||
else
|
||||
echo "${dstfile}: File not found in wine prefix" >&2
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# remove dxvk dll, restore original file
|
||||
uninstallFile() {
|
||||
dstfile="${1}/${3}.dll"
|
||||
srcfile="${basedir}/${2}/${3}.dll"
|
||||
|
||||
if [ -f "${srcfile}.so" ]; then
|
||||
srcfile="${srcfile}.so"
|
||||
fi
|
||||
|
||||
if ! [ -f "${srcfile}" ]; then
|
||||
echo "${srcfile}: File not found. Skipping." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! [ -f "${dstfile}" ] && ! [ -h "${dstfile}" ]; then
|
||||
echo "${dstfile}: File not found. Skipping." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -f "${dstfile}.old" ]; then
|
||||
rm -v "${dstfile}"
|
||||
mv -v "${dstfile}.old" "${dstfile}"
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
install() {
|
||||
installFile "$win64_sys_path" "$dxvk_lib64" "$1"
|
||||
inst64_ret="$?"
|
||||
|
||||
inst32_ret=-1
|
||||
if $wow64; then
|
||||
installFile "$win32_sys_path" "$dxvk_lib32" "$1"
|
||||
inst32_ret="$?"
|
||||
fi
|
||||
|
||||
if (( ($inst32_ret == 0) || ($inst64_ret == 0) )); then
|
||||
overrideDll "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
uninstall() {
|
||||
uninstallFile "$win64_sys_path" "$dxvk_lib64" "$1"
|
||||
uninst64_ret="$?"
|
||||
|
||||
uninst32_ret=-1
|
||||
if $wow64; then
|
||||
uninstallFile "$win32_sys_path" "$dxvk_lib32" "$1"
|
||||
uninst32_ret="$?"
|
||||
fi
|
||||
|
||||
if (( ($uninst32_ret == 0) || ($uninst64_ret == 0) )); then
|
||||
restoreDll "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
# skip dxgi during install if not explicitly
|
||||
# enabled, but always try to uninstall it
|
||||
if $with_dxgi || [ "$action" == "uninstall" ]; then
|
||||
$action dxgi
|
||||
fi
|
||||
|
||||
$action d3d9
|
||||
|
||||
if $with_d3d10 || [ "$action" == "uninstall" ]; then
|
||||
$action d3d10
|
||||
$action d3d10_1
|
||||
fi
|
||||
|
||||
$action d3d10core
|
||||
$action d3d11
|
||||
wait
|
||||
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
Executable
BIN
Binary file not shown.
+59
-44
@@ -26,6 +26,7 @@ import urllib.parse as parse
|
||||
import PyQt5.QtGui as QtGui
|
||||
import PyQt5.QtCore as QtCore
|
||||
import PyQt5.QtWidgets as QtWidgets
|
||||
from Model import *
|
||||
###################
|
||||
# 程序所需事件
|
||||
###################
|
||||
@@ -158,18 +159,21 @@ class Runexebutton_threading(QtCore.QThread):
|
||||
return
|
||||
os.remove(f"{programPath}/dlls-arm.7z")
|
||||
if setting["TerminalOpen"]:
|
||||
res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"] + "\" --keep-open" + wineUsingOption], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
res = ""
|
||||
OpenTerminal("env WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"])
|
||||
#res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"] + "\" --keep-open" + wineUsingOption], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
else:
|
||||
res = subprocess.Popen(["WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + e2.currentText() + "' " + setting["WineOption"]], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
# 实时读取程序返回
|
||||
#
|
||||
while res.poll() is None:
|
||||
try:
|
||||
text = res.stdout.readline().decode("utf8")
|
||||
except:
|
||||
text = ""
|
||||
self.signal.emit(text)
|
||||
print(text, end="")
|
||||
if not setting["TerminalOpen"]:
|
||||
while res.poll() is None:
|
||||
try:
|
||||
text = res.stdout.readline().decode("utf8")
|
||||
except:
|
||||
text = ""
|
||||
self.signal.emit(text)
|
||||
print(text, end="")
|
||||
if len(findExeHistory) == 0 or findExeHistory[-1] != wineBottonPath:
|
||||
findExeHistory.append(wineBottonPath) # 将记录写进数组
|
||||
write_txt(get_home() + "/.config/deepin-wine-runner/FindExeHistory.json", str(json.dumps(ListToDictionary(findExeHistory)))) # 将历史记录的数组转换为字典并写入
|
||||
@@ -352,13 +356,13 @@ def KillProgram():
|
||||
os.system("killall winedbg -9")
|
||||
|
||||
def InstallWine():
|
||||
threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -e \"{programPath}/AllInstall.py\""]).start()
|
||||
threading.Thread(target=OpenTerminal, args=[f"'{programPath}/AllInstall.py'"]).start()
|
||||
|
||||
def InstallWineOnDeepin23():
|
||||
threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -e \"{programPath}/InstallWineOnDeepin23.py\""]).start()
|
||||
threading.Thread(target=OpenTerminal, args=[f"'{programPath}/InstallWineOnDeepin23.py'"]).start()
|
||||
|
||||
def InstallWineHQ():
|
||||
threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -e \"{programPath}/InstallNewWineHQ.sh\""]).start()
|
||||
threading.Thread(target=OpenTerminal, args=[f"{programPath}/InstallNewWineHQ.sh"]).start()
|
||||
|
||||
def OpenWineBotton():
|
||||
if e1.currentText() == "":
|
||||
@@ -408,17 +412,20 @@ class RunWineProgramThread(QtCore.QThread):
|
||||
return
|
||||
os.remove(f"{programPath}/dlls-arm.7z")
|
||||
if setting["TerminalOpen"]:
|
||||
res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + self.wineProgram + "' " + setting["WineOption"] + " " + wineUsingOption + "\" --keep-open"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
res = ""
|
||||
OpenTerminal(f"env WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + self.wineProgram + "' " + setting["WineOption"] + " " + wineUsingOption)
|
||||
#res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + self.wineProgram + "' " + setting["WineOption"] + " " + wineUsingOption + "\" --keep-open"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
else:
|
||||
res = subprocess.Popen(["WINEPREFIX='" + wineBottonPath + "' " + option + wine[o1.currentText()] + " '" + self.wineProgram + "' " + setting["WineOption"]], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
# 实时读取程序返回
|
||||
while res.poll() is None:
|
||||
try:
|
||||
text = res.stdout.readline().decode("utf8")
|
||||
except:
|
||||
text = ""
|
||||
self.signal.emit(text)
|
||||
print(text, end="")
|
||||
if not setting["TerminalOpen"]:
|
||||
while res.poll() is None:
|
||||
try:
|
||||
text = res.stdout.readline().decode("utf8")
|
||||
except:
|
||||
text = ""
|
||||
self.signal.emit(text)
|
||||
print(text, end="")
|
||||
if self.history:
|
||||
if len(findExeHistory) == 0 or findExeHistory[-1] != wineBottonPath:
|
||||
findExeHistory.append(wineBottonPath) # 将记录写进数组
|
||||
@@ -469,7 +476,10 @@ class RunWinetricksThread(QtCore.QThread):
|
||||
return
|
||||
os.remove(f"{programPath}/dlls-arm.7z")
|
||||
if setting["TerminalOpen"]:
|
||||
res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='{wineBottonPath}' {option} WINE=" + subprocess.getoutput(f"which {wine[o1.currentText()]}").replace(" ", "").replace("\n", "") + f" winetricks --gui {wineUsingOption}\" --keep-open"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
res = ""
|
||||
# 用终端开应该不用返回输出内容了
|
||||
OpenTerminal(f"WINEPREFIX='{wineBottonPath}' {option} WINE=" + subprocess.getoutput(f"which {wine[o1.currentText()]}").replace(" ", "").replace("\n", "") + f" winetricks --gui {wineUsingOption}")
|
||||
#res = subprocess.Popen([f"'{programPath}/launch.sh' deepin-terminal -C \"WINEPREFIX='{wineBottonPath}' {option} WINE=" + subprocess.getoutput(f"which {wine[o1.currentText()]}").replace(" ", "").replace("\n", "") + f" winetricks --gui {wineUsingOption}\" --keep-open"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
else:
|
||||
res = subprocess.Popen([f"WINEPREFIX='{wineBottonPath}' {option} WINE='" + subprocess.getoutput(f"which {wine[o1.currentText()]}").replace(" ", "").replace("\n", "") + "' winetricks --gui"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
# 实时读取程序返回
|
||||
@@ -506,21 +516,21 @@ def CleanWineBottonByUOS():
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
os.system(f"'{programPath}/launch.sh' deepin-terminal -C \"WINE='{wine[o1.currentText()]}' '{programPath}/cleanbottle.sh' '{wineBottonPath}'; echo 按回车退出; read; read; exit;\"")
|
||||
OpenTerminal(f"env WINE='{wine[o1.currentText()]}' '{programPath}/cleanbottle.sh' '{wineBottonPath}'")
|
||||
|
||||
def FontAppStore():
|
||||
if e1.currentText() == "":
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
os.system(f"WINE='{programPath}/launch.sh' deepin-terminal -e '{programPath}/InstallFont.py' '{wineBottonPath}' {int(setting['RuntimeCache'])}")
|
||||
OpenTerminal(f"env WINE='{programPath}/launch.sh' '{programPath}/InstallFont.py' '{wineBottonPath}' {int(setting['RuntimeCache'])}")
|
||||
|
||||
def GetDllFromInternet():
|
||||
if e1.currentText() == "":
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
os.system(f"WINE='{programPath}/launch.sh' deepin-terminal -e '{programPath}/InstallDll.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
|
||||
OpenTerminal(f"env WINE='{programPath}/launch.sh' '{programPath}/InstallDll.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
|
||||
|
||||
def WineBottonAutoConfig():
|
||||
if e1.currentText() == "":
|
||||
@@ -534,28 +544,28 @@ def InstallMonoGecko(program):
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
os.system(f"'{programPath}/launch.sh' deepin-terminal -e '{programPath}/InstallMono.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {program} {int(setting['RuntimeCache'])}")
|
||||
OpenTerminal(f"'{programPath}/InstallMono.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {program} {int(setting['RuntimeCache'])}")
|
||||
|
||||
def InstallNetFramework():
|
||||
if e1.currentText() == "":
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
os.system(f"'{programPath}/launch.sh' deepin-terminal -e '{programPath}/InstallNetFramework.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
|
||||
OpenTerminal(f"'{programPath}/InstallNetFramework.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
|
||||
|
||||
def InstallVisualStudioCPlusPlus():
|
||||
if e1.currentText() == "":
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
os.system(f"'{programPath}/launch.sh' deepin-terminal -e '{programPath}/InstallVisualCPlusPlus.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
|
||||
OpenTerminal(f"'{programPath}/InstallVisualCPlusPlus.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
|
||||
|
||||
def InstallMSXML():
|
||||
if e1.currentText() == "":
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
os.system(f"'{programPath}/launch.sh' deepin-terminal -e '{programPath}/InstallMsxml.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
|
||||
OpenTerminal(f"'{programPath}/InstallMsxml.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
|
||||
|
||||
def InstallDXVK():
|
||||
if not os.path.exists(f"{programPath}/dxvk"):
|
||||
@@ -567,10 +577,11 @@ def InstallDXVK():
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
process = QtCore.QProcess()
|
||||
process.startDetached(f"{programPath}/launch.sh", ["deepin-terminal", "-e",
|
||||
"env", f"WINE={wine[o1.currentText()]}", f"WINE64={wine[o1.currentText()]}", f"WINEPREFIX={wineBottonPath}", "bash",
|
||||
f"{programPath}/dxvk/setup_dxvk.sh", "install"])
|
||||
OpenTerminal(f"env WINE='{wine[o1.currentText()]}' WINE64='{wine[o1.currentText()]}' WINEPREFIX='{wineBottonPath}' '{programPath}/dxvk/setup_dxvk.sh' install")
|
||||
#process = QtCore.QProcess()
|
||||
#process.startDetached(f"{programPath}/launch.sh", ["deepin-terminal", "-e",
|
||||
#"env", f"WINE={wine[o1.currentText()]}", f"WINE64={wine[o1.currentText()]}", f"WINEPREFIX={wineBottonPath}", "bash",
|
||||
#f"{programPath}/dxvk/setup_dxvk.sh", "install"])
|
||||
|
||||
def UninstallDXVK():
|
||||
if not os.path.exists(f"{programPath}/dxvk"):
|
||||
@@ -582,24 +593,25 @@ def UninstallDXVK():
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
process = QtCore.QProcess()
|
||||
process.startDetached(f"{programPath}/launch.sh", ["deepin-terminal", "-e",
|
||||
"env", f"WINE={wine[o1.currentText()]}", f"WINE64={wine[o1.currentText()]}", f"WINEPREFIX={wineBottonPath}",
|
||||
f"{programPath}/dxvk/setup_dxvk.sh", "uninstall"])
|
||||
OpenTerminal(f"env WINE='{wine[o1.currentText()]}' WINE64='{wine[o1.currentText()]}' WINEPREFIX='{wineBottonPath}' '{programPath}/dxvk/setup_dxvk.sh' uninstall")
|
||||
#process = QtCore.QProcess()
|
||||
#process.startDetached(f"{programPath}/launch.sh", ["deepin-terminal", "-e",
|
||||
#"env", f"WINE={wine[o1.currentText()]}", f"WINE64={wine[o1.currentText()]}", f"WINEPREFIX={wineBottonPath}",
|
||||
#f"{programPath}/dxvk/setup_dxvk.sh", "uninstall"])
|
||||
|
||||
def MiniAppStore():
|
||||
if e1.currentText()== "":
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
os.system(f"'{programPath}/launch.sh' deepin-terminal -e '{programPath}/AppStore.py' '{wineBottonPath}' '{wine[o1.currentText()]}'")
|
||||
OpenTerminal(f"'{programPath}/AppStore.py' '{wineBottonPath}' '{wine[o1.currentText()]}'")
|
||||
|
||||
def InstallOther():
|
||||
if e1.currentText()== "":
|
||||
wineBottonPath = setting["DefultBotton"]
|
||||
else:
|
||||
wineBottonPath = e1.currentText()
|
||||
os.system(f"'{programPath}/launch.sh' deepin-terminal -e '{programPath}/InstallOther.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
|
||||
OpenTerminal(f"'{programPath}/InstallOther.py' '{wineBottonPath}' '{wine[o1.currentText()]}' {int(setting['RuntimeCache'])}")
|
||||
|
||||
def BuildExeDeb():
|
||||
if e1.currentText() == "":
|
||||
@@ -629,7 +641,7 @@ def SetDeepinFileDialogDefult():
|
||||
QtWidgets.QMessageBox.information(widget, "提示", "设置完成!")
|
||||
|
||||
def SetDeepinFileDialogRecovery():
|
||||
threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -C 'pkexec \"{programPath}/deepin-wine-venturi-setter.py\" recovery' --keep-open"]).start()
|
||||
threading.Thread(target=OpenTerminal, args=[f"pkexec '{programPath}/deepin-wine-venturi-setter.py' recovery"]).start()
|
||||
|
||||
def DeleteDesktopIcon():
|
||||
if os.path.exists(f"{get_home()}/.local/share/applications/wine"):
|
||||
@@ -662,13 +674,13 @@ def ThankWindow():
|
||||
def InstallWineFont():
|
||||
# 筛选 apt
|
||||
if not os.system("which aptss"):
|
||||
threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -C 'echo 这些字体来自星火应用商店 && sudo aptss install ms-core-fonts -y' --keep-open"]).start()
|
||||
threading.Thread(target=OpenTerminal, args=[f"sudo aptss install ms-core-fonts -y"]).start()
|
||||
elif not os.system("which ss-apt-fast"):
|
||||
threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -C 'echo 这些字体来自星火应用商店 && sudo ss-apt-fast update && sudo ss-apt-fast install ms-core-fonts -y' --keep-open"]).start()
|
||||
threading.Thread(target=OpenTerminal, args=[f"sudo ss-apt-fast install ms-core-fonts -y"]).start()
|
||||
elif not os.system("which apt-fast"):
|
||||
threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -C 'echo 这些字体来自星火应用商店 && sudo apt-fast install ms-core-fonts -y' --keep-open"]).start()
|
||||
threading.Thread(target=OpenTerminal, args=[f"sudo apt-fast install ms-core-fonts -y"]).start()
|
||||
else:
|
||||
threading.Thread(target=os.system, args=[f"'{programPath}/launch.sh' deepin-terminal -C 'echo 这些字体来自星火应用商店 && sudo apt install ms-core-fonts -y' --keep-open"]).start()
|
||||
threading.Thread(target=OpenTerminal, args=[f"sudo apt install ms-core-fonts -y"]).start()
|
||||
|
||||
def WineRunnerBugUpload():
|
||||
threading.Thread(target=os.system, args=[f"'{programPath}/deepin-wine-runner-update-bug'"]).start()
|
||||
@@ -707,7 +719,7 @@ def RunVM():
|
||||
threading.Thread(target=os.system, args=[f"bash '{programPath}/RunVM.sh'"]).start()
|
||||
|
||||
def CleanProgram():
|
||||
os.system(f"'{programPath}/launch.sh' deepin-terminal -e \"{programPath}/clean-unuse-program.py\"")
|
||||
OpenTerminal(f"{programPath}/clean-unuse-program.py")
|
||||
|
||||
class UpdateWindow():
|
||||
data = {}
|
||||
@@ -766,7 +778,7 @@ zenity --info --text=\"更新完毕!\" --ellipsize
|
||||
except:
|
||||
traceback.print_exc()
|
||||
QtWidgets.QMessageBox.critical(None, "出现错误,无法继续更新", traceback.format_exc())
|
||||
os.system(f"'{programPath}/launch.sh' deepin-terminal -e pkexec bash /tmp/spark-deepin-wine-runner/update.sh")
|
||||
OpenTerminal("pkexec bash /tmp/spark-deepin-wine-runner/update.sh")
|
||||
|
||||
class GetDllFromWindowsISO:
|
||||
wineBottonPath = get_home() + "/.wine"
|
||||
@@ -1210,6 +1222,8 @@ class ProgramSetting():
|
||||
return
|
||||
QtWidgets.QMessageBox.information(ProgramSetting.message, "提示", "保存完毕!")
|
||||
|
||||
|
||||
|
||||
###########################
|
||||
# 加载配置
|
||||
###########################
|
||||
@@ -1411,6 +1425,7 @@ except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
###########################
|
||||
# 窗口创建
|
||||
###########################
|
||||
|
||||
Regular → Executable
+5
-1
@@ -98,7 +98,11 @@ def ReadLocalInformation():
|
||||
def ReadInternetInformation():
|
||||
global internetJsonList
|
||||
# C++ 版本是用 curl 的,考虑到 Python 用 requests 反而方便,于是不用 curl
|
||||
internetJsonList = json.loads(requests.get(f"{internetWineSource}/information.json").text)
|
||||
try:
|
||||
internetJsonList = json.loads(requests.get(f"{internetWineSource}/information.json").text)
|
||||
except:
|
||||
QtWidgets.QMessageBox.critical(window, "错误", "无法连接服务器!")
|
||||
return
|
||||
nmodel = QtGui.QStandardItemModel(window)
|
||||
for i in internetJsonList:
|
||||
item = QtGui.QStandardItem(i[0])
|
||||
|
||||
Reference in New Issue
Block a user