TheLord 发表于 2023-7-3 11:12

【Python+C#】CSGO配置文件替换工具

本帖最后由 TheLord 于 2023-7-3 11:14 编辑

## 0x00_Inital

> 省流:软件官网:https://cfg.laosepi.cool/
>
> 下载地址:https://mrdeng.lanzoue.com/b0133wrfc (密码:awrr)

作为一个CSGO官匹玩家,最难受的事情莫过于上网吧的时候调配置。尤其是准星,准星不对劲完全打不到人;好在各大对战平台都提供了便捷的配置文件上传下载功能,但是每次在网吧登录都需要等待平台更新,验证环境等等,而且手机上得有对战平台的APP才能异地登录,较为繁琐。

于是就想自己写一个简单的配置下载工具,它可以自动扫描Steam目录,下载解压配置文件后释放配置文件。由于直接在服务器保存配置文件不太安全,且我的小服务器也承受不了太多用户,所以采用了WebDav的方式下载配置文件,我的服务器仅储存用户的WebDav配置信息用于下载。~~后续可能支持一键更新上传~~

大概思路是这样的:

1. 初始化程序,检测Steam进程是否存在,若无则提示用户启动Steam;
2. ,扫描软件根目录下是否存在配置文件压缩包,若有则解压释放,从中获取用户好友ID,若无则弹出登录框联网获取WebDav信息;
3. 用户登录从服务器获取信息,若有WebDav配置信息则进行显示,若无则提示添加配置;若查询不到该用户则引导注册并添加WebDav配置信息;
4. 在添加或修改WebDav配置信息时,先进行测试下载,确认配置无误后才解锁上传按钮,避免储存错误配置;

本来想的是使用Python+PyQt的方式实现,但是考虑到Python项目打包后庞大的体积就放弃了。所幸在大二的时候学过一点点C#的皮毛,并且编译后的体积非常小巧,所以考虑使用C#制作桌面应用,使用Flask作为后端。

![](https://imgsrc.baidu.com/forum/pic/item/35a85edf8db1cb13a9d573dc9854564e93584b45.gif)

## 0x01_The Front End

首先是制作桌面应用,C#桌面应用可以在Visual Studio中直接拖拽设计并绑定按钮函数,非常方便。下面简单介绍一下各个页面的设计思路。

### 0x01-1 启动页面

![](https://s1.ax1x.com/2023/07/03/pCr1HW4.png)

启动页面就三个按钮,一个项目地址跳转链接和用于显示扫描到Steam地址的TextEdit。在初始化完成前,“替换CFG”和“替换视频设置”的按钮是禁用状态,避免程序找不到对应的配置文件而出错。当初始化完成后,在下方的TextEdit中显示扫描到的CSGO配置文件夹地址。

![](https://s1.ax1x.com/2023/07/03/pCr1OyR.png)

![](https://s1.ax1x.com/2023/07/03/pCr1Ll9.png)

下面是伪代码思路:

```C#
public string[] UnzipFile()
    if (根目录存在cfg.zip) 解压cfg.zip
    else{
      if(弹出提示框“当前目录不存在cfg.zip,点击是登录,点击否打开软件根目录”) 弹出登录框
      else 打开软件根目录
    }
      return 解压后文件中的子文件夹名称或空值

public void CopyFile(string CFG_Path, string Local_Path, string Target)
      if(软件根目录存在“cfg”文件夹) 删除原有cfg文件夹
      释放下载的配置文件夹
    移动配置文件夹中的 Target 文件到本地CSGO配置文件夹 Local_Path
   
private void Init_Btn_Click()
    if(Steam进程是否存在)
    {
      if(调用UnzipFile) 从返回值拼接配置文件夹路径
      else 弹出提示
    }
   
private void CFG_Btn_Click()
    if(存在config.cfg) 删除config.cfg
    CopyFile(CFG_Path, Local_Path, "config.cfg")
   
private void Vid_Btn_Click()
    if(存在video.txt) 删除video.txt
    CopyFile(CFG_Path, Local_Path, "video.txt")
```

### 0x01-2 登录页面

在点击初始化按钮后,在根目录找不到配置文件压缩包后,弹出登录页面

![](https://s1.ax1x.com/2023/07/03/pCr3Z0P.png)

!(https://s1.ax1x.com/2023/07/03/pCr3AOI.png)

这个页面就更加简洁了,就两个输入框,两个按钮。原本是打算使用网页进行注册的,但是我的前端水平实在有限,写出来的Demo我自己都看不下去,就放弃了,直接在软件内进行注册。然后在保持登录状态这一点,使用了Session的方式,在登录成功时将用户邮箱写入Session["email"]中,用于后续查询配置操作。同时在此窗口内新建一个HttpClient对象,并在调用注册和WebDav编辑页面时将它传入,用以保持登录信息。

```c#
private void SignUp_Btn_Click()
    调起 注册页面(HttpClient)
   
public void DownLoad(string url, string username, string password)
    WebClient client = new WebClient();
    client.Credentials = new NetworkCredential(username, password);
    client.DownloadFile(url, localPath);
   
private async void Login_Btn_Click()
    if(验证账号和密码输入框不为空)
    {
      构造登录信息表单 UserData
      res = await HttpClient.post(服务器, UserData)
      if(res) 调起 WebDav配置页面(HttpClient)
      else 账号不存在或密码错误
    }
```

### 0x01-3注册页面

!(https://s1.ax1x.com/2023/07/03/pCr3k6A.png)

注册页面也较为简洁,在点击“验证”按钮前锁定注册按钮,同时对邮箱输入框进行了简单的判断,防止有用户输错邮箱。

```C#
private bool IsValidEmail(string input)
    if(input符合邮箱地址的格式)return true
    else return false
   
async private void Ver_Btn_Click()
    禁用邮箱输入框,禁用验证按钮,启用注册按钮
    //此处有Timer对验证按钮进行倒计时显示,代码略
    if(IsValidEmail(邮件框))
    {
      构造注册邮箱数据表 EmailData
      res = await post(服务器验证码接口, EmailData)
      if(res == "success") 显示 注册成功
      else if(res == "error") 显示 该邮箱已注册
      else 显示 无法连接至邮件服务器
    }else 提示邮箱格式错误

async private void SignUp_Btn_Click()
    if(密码框文字长度<6) 提示密码过短
    else if(验证码长度<6) 提示验证码不正确
    else
    {
      构造注册信息表单 SignUpData
      res = await HttpClient.post(服务器注册接口, SignUpData)
    }
      if(res == "success") 提示注册成功,调起配置页面(HttpClient)
    else 提示注册失败或无法连接到服务器
```

### 0x01-4WebDav配置修改页面

!(https://s1.ax1x.com/2023/07/03/pCr3Vmt.png)

配置修改页面主要为三个输入框和两个按钮。这里采用了一个防呆设计,“保存配置”的按钮是默认禁用的,得通过下载测试后,才使能该按钮。在该页面初始化时,会向服务器配置信息接口请求一次用户WebDav配置。

```C#
private void Test_Btn_Click()
    if(三个输入框均不为空)
    {
      if(当前目录存在cfg.zip) 删除cfg.zip
      try 根据输入框信息下载配置文件
      catch WebException 提示配置信息有误,return
      if(当前目录存在cfg.zip) 提示下载成功,禁用输入框,使能保存按钮
    }else 提示配置栏不能留空

async private void Save_Btn_Click()
    构造WebDav配置信息表 CFGData
    res = HttpClient.post(服务器配置信息接口, CFGData)
    if(res) 提示上传成功,关闭此窗口
    else 提示上传失败
```

以上为桌面应用的设计,由于对于C#不是太熟悉,所以对于登录表单的校验等工作基本上都是交由后端完成的,并且注册页面有一个bug是验证按钮的倒计时Timer,在倒计时结束前如果关闭注册窗口会导致程序崩溃,是由于Timer更新UI的线程丢失,而引起的崩溃,暂时还没想到什么好的解决办法,也请评论区的大神们指点一二。

## 0x02_The Back End

再来简单介绍一下后端,这一部分使用了Flask框架进行构建,也比较简单,就全部放在了一个main.py中,使用了sqlite作为数据库,便于部署。以下为简化后的伪代码:

```python
# 发邮件函数
def send_subscribe_mail(mail_data):
    从 mail_data 中获取数据
    发送邮件
   
@app.route('/', methods=['GET']) # 定义主页路由
def index():
    在数据库查询总用户数和总下载数
    returnrender_template('index.html', Users=len(Users)-1, Count=Count)

@app.route('/login', methods=['POST']) # 定义登录接口
def login():
    从请求表单获取信息
    if 在数据库中查询用户:
      写入Session
      在数据库中查询用户配置信息 CFG
      return jsonify(CFG)
    else:
      return "None"

@app.route('/email', methods=['POST']) # 定义验证码邮件接口
def email():
    if 请求邮箱地址 email == 系统邮箱地址:
      return "error"
    if 在数据库中查询email:
      return "error"
    code = 生成6位验证码
    code,email 存入Session
    发送验证码邮件
    return "success"

@app.route('/register', methods=['POST']) # 定义 注册接口
def register():
    if 请求表单中的验证码 == Session中的验证码:
      将用户信息写入数据库
      return "success"
    else:
      return "error"
   
@app.route('/cfg', methods=['GET', 'POST']) # 定义配置接口
def cfg():
    if request.method == 'GET':# 请求下载配置
      if session['email']:# 如果已经登录或从注册页面进入
            try:
                  从数据库中查询email匹配的配置信息 CFG
                  return jsonify(CFG)
            except IndexError:# 查询失败报错
                              return ""# 无配置返回空
    elif request.method == 'POST':
      try:
            数据库写入请求表单数据
            return "success"
      except E:
            return "error"
```

## 0x03_Usage

在设计的时候,软件的初始化操作有两步,第一步是检测Steam进程从而找到Steam.exe的路径,以此找到Steam安装文件夹中的Userdata文件夹;第二步是尝试解压软件根目录下的“cfg.zip”,因此本软件可以直接打包好配置文件压缩包一起移动,省去登录下载的时间,亦或者是上传到坚果云等支持WebDav的免费网盘中,将配置信息填写好联网下载。

限于篇幅这里不做过多赘述,详细使用信息见GitHub:(https://github.com/Lord2333/CSGO_CFG)

## 0x04_Another Thing

这个软件是我花了两天时间一边百度一边GPT写出来的,很粗糙,也不好看,勉强够用的水平。

由于V社的官方SDK要交100刀注册成为开发者才能使用,所以就用了一个笨办法在配置文件夹中获取用户的好友ID以定位本地的配置文件夹,后续尝试一下能不能像Steam++那样自动识别(但是好像它也是用的Steam的SDK实现的)。

此外由于打包配置文件夹的过程较为繁琐,且每次修改配置后都需要重新手动打包,不太方便,后续将尝试自动打包上传到WebDav服务器。

最后,欢迎各位留言,提Issue~

头号玩家 发表于 2023-7-3 11:39

咱就是说,这个真的方便吗?

TheLord 发表于 2023-7-3 11:46

头号玩家 发表于 2023-7-3 11:39
咱就是说,这个真的方便吗?

看动图,十秒钟就下好了。平台登录要扫码要验证环境完了才能同步配置

Taichiwah 发表于 2023-7-3 12:15

不错收藏备用了!!!

vethenc 发表于 2023-7-3 12:44

感谢分享,666

blindcat 发表于 2023-7-3 13:16

不玩游戏,纯支持一下

Pojawa 发表于 2023-7-3 15:44

又一个返璞归真的……………………都不用steam自动同步和exec加载的{:1_925:}

TheLord 发表于 2023-7-3 17:31

Pojawa 发表于 2023-7-3 15:44
又一个返璞归真的……………………都不用steam自动同步和exec加载的

首先感谢评论,您要是觉得我写的工具不好,可以直接右上角,没必要进来秀优越感。对于经常接触编程的人来说可能敲控制台不算事,那么对于那些没有了解过的人来说,他会不会是一件复杂的事情?2023年了都还有人卸载软件是直接删除快捷方式,那么敲控制台设置autoexec对于这类玩家来说是不是较为复杂?如果V社真的做的足够简单,那也就轮不到各大对战平台和我来做配置同步。不是所有家庭都可以把房子租出去然后开滴滴赚钱的。

Pojawa 发表于 2023-7-3 22:12

TheLord 发表于 2023-7-3 17:31
首先感谢评论,您要是觉得我写的工具不好,可以直接右上角,没必要进来秀优越感。对于经常接触编程的人来 ...

emmmmmmmmmm 懂了,人类的本质是套娃,一层套一层,打破套娃就是在秀优越感,大师,我悟了……
另外 autoexec 是在启动项设置,控制台一次只能执行一条命令,但是你可以自己编辑好对应的命令集合成cfg文件然后在控制台读取(exec)一遍,达到一条命令执行多条命令的效果,类似于做开发时候的抽象封包。
汗一个吧

Harmon666 发表于 2023-7-5 18:57

感谢分享
页: [1] 2
查看完整版本: 【Python+C#】CSGO配置文件替换工具