TRIM 发表于 2024-1-30 12:48:13

原神白屏启动器2.0.3版本优化更新发布啦!

本帖最后由 TRIM 于 2024-5-1 09:23 编辑

## 原神白屏启动器
### 一款用于恶搞的小软件!
以下就是原神白屏启动器的使用说明了!
网站只做了电脑版的:(http://trim.wyylkjs.top/works/gwl)
*网站寒假不开,暂停在线更新支持*
### 下载链接
[原神白屏启动器.zip <-点击这里下载!](https://www.yuanxiapi.cn/api/lanzou/?url=https://qrm5106.lanzoul.com/itB7i1msvbsh&type=down)
[备用链接](https://qrm5106.lanzoul.com/itB7i1msvbsh)
*由于文件太大,不能上传到社区,本链接为蓝奏云网盘下载*
*放心,免登录不限速下载*
### 更新内容
1.优化“关闭程序.bat”文件,每次启动会根据程序名自动刷新,增加错误反馈,去除不必要的“按任意键继续”提示
2.增加程序多开检测。利用启动时新建lockfile文件,关闭时删除来实现功能。避免软件多开造成严重卡顿
3.图片绘制刷新优化,自动适应刷新间隔,图片显示更流畅
4.程序逻辑优化,增加更多注释
更新功能示例:


### 使用说明
初次启动时间可能较长,请耐心等待。程序会尝试**补全文件**,文件夹中的“设置”文件可修改,请按照其中的提示修改。
打开程序后,等待提示出现,程序即在**后台运行**
当亮度到达用户设定值以上,会“启动原神”
启动亮度阈值、动画时长等均可在“设置”文件中修改
程序仍有许多没有完善,修改设置后,请**重启程序**以使修改生效
***若要关闭程序,请运行文件夹中的“关闭程序.bat”***
***不建议在任务管理器中直接结束进程(程序多开检测无法恢复)***
### 使用示例




### FAQ
**# 为什么屏幕明明全白了,还是没有“启动”?**
      这可能是因为屏幕亮度实际上还没达到用户设定的触发阈值,或者有某些程序抢占权限使其无法置顶窗口
**# 为什么有时屏幕没有全白还是会自己“启动”?**
      触发亮度阈值太小,请适当增大,推荐值在248~252之间
**# 为什么无法关闭程序?关闭程序提示“找不到进程”?**
      程序通过结束进程关闭。请不要在程序运行中修改程序名,以便顺利关闭程序(其他时候怎么改都行,已经做了相关优化)
      当一个小黑框(命令行窗口)一闪而过,这个程序就已经被关闭了!
**# 为什么“启动”一次后不能再次“启动”?(指的是图片的显示)**
      为了防止重复“启动”造成卡顿,当屏幕亮度下降到用户设定值的95%以下,程序才会继续下一次检测

如果有其它疑问或建议可向作者提出。联系方式**51064683@qq.com**
### 往期优化内容
1.增加了设置,触发阈值、动画时长、启动提示、自动更新、图片等都可自定义
2.自动修复,文件缺失或损坏将自动补全
3.所有屏幕适配,增加了屏幕及图片大小检测转换,无论多么奇葩的屏幕比例,“原神”二字一定可以准确清晰地显示出来
4.程序隐藏在后台运行,若运行在别人电脑里,对方丝毫察觉不到(别用来干坏事哦~)
5.凑字数,原神,启动!
### 演示
可以看到,衔接非常丝滑!


### 源代码
由于代码中有内置文件,故不全部展示,请自行下载:
[源码.zip <-点击这里下载!](https://qrm5106.lanzoul.com/iWrDN1msvbuj)
大部分源代码展示
import sys# 用于sys.exit()
import os# 用于获取路径及文件处理
import glob# 查找文件
import time# 时间
import configparser# 读取配置文件
import base64# 处理图片解码
import pygame# 创建窗口 原神启动
import mss# 一个快速截屏库
import numpy as np# 图像处理
import ctypes# 用于SetWindowPos函数 改变窗口顺序
import requests # 在线更新用
import webbrowser# 在线更新用
import tkinter as tk# 用于显示提示框
from tkinter import messagebox# 用于显示提示框


# 显示选择对话框
def show_select_window(title, message, yes_action, no_action):
    tip_window_root = tk.Tk()
    tip_window_root.withdraw()
    update_select_result = messagebox.askyesno(title, message)
    tip_window_root.destroy()
    if update_select_result == True:
      if yes_action != "pass":
            exec(yes_action)
    else:
      if no_action != "pass":
            exec(no_action)


# 显示提示对话框
def show_tips_window(title, message, action):
    tip_window_root = tk.Tk()
    tip_window_root.withdraw()
    messagebox.showinfo(title, message)
    tip_window_root.destroy()
    if action != "pass":
      exec(action)



# 获取自身exe文件名
exe_file_name = os.path.basename(sys.argv)
# 检查是否已经有lockfile文件,防止程序被重复启动
if os.path.exists("lockfile"):
    show_select_window(title="初始化", message="已有相同的程序正在运行,是否将其关闭?\n点击【是】将关闭正在运行的原神白屏启动器,请稍后再打开程序\n点击【否】将直接退出,不关闭正在运行的原神白屏启动器\n\n如果你连续两次以上看到这条消息,并且确认电脑上目前真的没有该程序在运行,请删除“lockfile”文件后重试。或将此错误报告开发者51064683@qq.com", yes_action="os.system(\"关闭程序.bat\")", no_action="pass")
    sys.exit()
else:
    with open(r"lockfile", "w", encoding="UTF8") as fill_file:
      fill_file.write("此文件用于防止程序被重复启动,请不要随意删除\nDO NOT DELETE THIS LOCK FILE CASUALLY, WHICH USED TO AVOID REPEATED STARTUP.")

# 保存一些内置文件数据,补全文件需要使用。包含转义字符串,阅读起来应该很不方便吧
此处省略
此处省略
此处省略

# 补全文件
ini_file_list = glob.glob("*.ini")# 找ini文件
if len(ini_file_list) == 0:
    with open(r"设置.ini", "w", encoding="UTF8") as fill_file:
      fill_file.write(config_file_data)
    ini_file_name = "设置.ini"
else:
    ini_file_name = ini_file_list# 只读取第一个ini文件

if len(glob.glob("1.png")) == 0:# 找那张图片
    with open("1.png", "wb") as img_file:
      img_file.write(base64.b64decode(image_data))

with open(r"关闭程序.bat", "w", encoding="GBK") as fill_file:# 刷新“关闭程序.bat”文件中关闭的进程名
    fill_file.write(quit_bat)

# 初始化pygame
pygame.init()
clock = pygame.time.Clock()
flags = pygame.DOUBLEBUF | pygame.HWSURFACE | pygame.FULLSCREEN | pygame.NOFRAME
# 获取屏幕的大小
screen_info = pygame.display.Info()
screen_width = screen_info.current_w
screen_height = screen_info.current_h
# 加载那张图片
image = pygame.image.load("1.png")
# 计算图片绘制的位置及转换图片大小
image_height = image.get_height()
image_width = image.get_width()
image_position = (0, 0)
if image_height / image_width >= screen_height / screen_width:# 判断长宽比
    image = pygame.transform.scale(image, (screen_height / image_height * image_width, screen_height))# 调整适应大小
    image_position = ((screen_width - (screen_height / image_height * image_width)) / 2, 0)# 计算图片左上坐标
elif image_height / image_width < screen_height / screen_width:
    image = pygame.transform.scale(image, (screen_width, screen_width * image_height / image_width))
    image_position = (0, (screen_height - (screen_width * image_height / image_width)) / 2)
image_x = image_position
image_y = image_position

# 读取ini文件
try:
    config = configparser.ConfigParser()
    with open(ini_file_name, 'r', encoding='utf-8') as utf_file:
      config.read_file(utf_file)
except:# 就怕某些人乱改,专门搞的
    fill_file = open(r"设置.ini", "w", encoding="UTF8")
    fill_file.write(config_file_data)
    fill_file.close()
    ini_file_name = "设置.ini"
    config = configparser.ConfigParser()
    with open(ini_file_name, 'r', encoding='utf-8') as utf_file:
      config.read_file(utf_file)
    show_tips_window(title="一个小错误", message="配置文件读取异常\n已为您重新生成\n请在新文件中修改", action="pass")
    try:
      os.remove("lockfile")
    except:
      pass
    sys.exit()

# 获取配置文件中的设置
launch_value = float(config.get("普通设置", "触发阈值"))
front_shake_time = float(config.get("普通设置", "前摇时长"))
show_time = float(config.get("普通设置", "显现时长"))
back_shake_time = float(config.get("普通设置", "后摇时长"))

check_update = config.get("其他设置", "检查更新")
if check_update == "False":
    check_update = False
else:
    check_update = True
grab_times = int(config.get("其他设置", "每秒检测次数"))

if check_update:
    update_quit = False
    # 检查更新
    try:
      response = requests.get("http://trim.wyylkjs.top/networkprogramsupport/gwl/update",timeout=2.5)# 最多一坤秒
      updateinfo = eval(response.text)# 转换成字典格式,不想用json了
      if updateinfo["version"] > 20003:# 版本号2.0.3
            show_select_window(title="更新提示", message=updateinfo["tips"], yes_action=updateinfo["yes_action"], no_action=updateinfo["no_action"])
            update_quit = True
    except:
      pass

    # 不更新就别想用!(只要提示框出现过,pygame窗口就不能置顶了,只好这样了。我也不知道为什么,非常抱歉)
    if update_quit:
      try:
            os.remove("lockfile")
      except:
            pass
      sys.exit()

font_35 = pygame.font.SysFont("simhei", 35)
font_20 = pygame.font.SysFont("simhei", 20)
font_15 = pygame.font.SysFont("simhei", 15)# 获取系统字体
# 创建小窗口
screen = pygame.display.set_mode((560, 250))
pygame.display.set_caption("原神白屏启动器--初始化成功")
hwnd = pygame.display.get_wm_info()["window"]
# 先全白再说
screen.fill((255, 255, 255))
pygame.display.flip()
# 系统将这个窗口置顶
ctypes.windll.user32.SetWindowPos(hwnd, -1, 0, 0, 0, 0, 0x0001)

max_avg_color = 0
min_avg_color = 255
avg_color = 0

# 渲染文字
tip_1 = font_35.render("按任意键关闭提示框,进入后台运行", True, "red")
tip_2 = font_20.render("点击任意区域也可以哦", True, "red")
tip_3 = font_20.render("如需关闭程序,请使用程序文件夹中的“关闭程序.bat”文件", True, "black")
tip_4 = font_20.render("为了成功关闭程序,请不要在程序运行过程中修改程序名", True, "black")
tip_5 = font_20.render("屏幕大小"+str(screen_width)+"x"+str(screen_height), True, "black")
tip_6 = font_20.render("当前屏幕亮度"+str(avg_color), True, "black")
tip_7 = font_20.render("最大屏幕亮度"+str(max_avg_color), True, "black")
tip_8 = font_20.render("最小屏幕亮度"+str(min_avg_color), True, "black")
tip_9 = font_15.render(" 2.0.3 | TRIM | TRIM5829 | 错误反馈51064683@qq.com", True, "black")
# 显示文字
screen.fill((255,255,255))
screen.blit(tip_1, (0, 0))
screen.blit(tip_2, (0, 45))
screen.blit(tip_3, (0, 75))
screen.blit(tip_4, (0, 100))
screen.blit(tip_5, (0, 125))
screen.blit(tip_6, (0, 150))
screen.blit(tip_7, (0, 175))
screen.blit(tip_8, (0, 200))
screen.blit(tip_9, (0, 225))
pygame.display.flip()

with mss.mss() as sct:
    tip_running = True
    while tip_running:
      for event in pygame.event.get():
            if event.type == pygame.QUIT:
                tip_running = False
            if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1:
                tip_running = False
            if event.type == pygame.KEYDOWN:
                tip_running = False

      # 渲染文字
      tip_6 = font_20.render("当前屏幕亮度"+str(avg_color), True, "black")
      tip_7 = font_20.render("最大屏幕亮度"+str(max_avg_color), True, "black")
      tip_8 = font_20.render("最小屏幕亮度"+str(min_avg_color), True, "black")
      # 显示文字
      pygame.draw.rect(screen, "white", (0, 150, 560, 75))
      screen.blit(tip_6, (0, 150))
      screen.blit(tip_7, (0, 175))
      screen.blit(tip_8, (0, 200))
      pygame.display.update()

      img = np.array(sct.grab(sct.monitors))
      avg_color = np.mean(img)
      if avg_color > max_avg_color:
            max_avg_color = avg_color
      if avg_color < min_avg_color:
            min_avg_color = avg_color

      time.sleep(0.1)
    pygame.display.quit()


    # 开始检测!
    while True:
      # 获取屏幕截图
      img = np.array(sct.grab(sct.monitors))
      # 计算屏幕图像的平均亮度
      avg_color = np.mean(img)
      if avg_color >= launch_value:
            # 创建大窗口
            screen = pygame.display.set_mode((screen_width, screen_height), flags)
            pygame.display.set_caption("原神白屏启动器")
            hwnd = pygame.display.get_wm_info()["window"]
            # 先全白再说
            screen.fill((255, 255, 255))
            pygame.display.flip()
            # 系统将这个窗口置顶
            ctypes.windll.user32.SetWindowPos(hwnd, -1, 0, 0, 0, 0, 0x0001)
            time.sleep(front_shake_time)
            start_time = time.time()
            # 原神,启动!(透明度逐渐降低)
            while time.time() - start_time <= show_time:
                alpha = int((time.time() - start_time) / show_time * 255)
                image.set_alpha(alpha)
                screen.fill((255,255,255))
                screen.blit(image, (image_x, image_y))
                pygame.display.flip()
            # 最终绘制上去
            image.set_alpha(255)
            screen.fill((255,255,255))
            screen.blit(image, (image_x, image_y))
            pygame.display.flip()
            time.sleep(back_shake_time)
            pygame.display.quit()
            # 等待亮度降到用户设定的95%以下再继续检测,避免重复启动造成电脑卡死
            next_grab = False
            while next_grab == False:
                img = np.array(sct.grab(sct.monitors))
                # 计算屏幕图像的平均亮度
                avg_color = np.mean(img)
                if avg_color <= launch_value * 0.95:
                  next_grab = True
                # 每秒检测次数
                clock.tick(grab_times)
      # 每秒检测次数
      clock.tick(grab_times)
"""
作者:TRIM | @TRIM5829 | 51064683@qq.com
此代码仅用于个人学习目的
如需修改代码,请不要修改或删除此注释中的内容
在引用或转载时,请注明出处
"""

零刻工作室 发表于 2024-1-31 13:30:58

你用内网穿透整网站肯定会崩网啊

TRIM 发表于 2024-2-6 11:49:24

零刻工作室 发表于 2024-1-31 13:30
你用内网穿透整网站肯定会崩网啊
这个内网穿透确实天天被攻击,但比起买服务器这个显然更省。寒假了就懒得开服务器了
页: [1]
查看完整版本: 原神白屏启动器2.0.3版本优化更新发布啦!