<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Bluore</title><description>在这里写写画画</description><link>https://bluore.cn/</link><language>zh_CN</language><item><title>Linux常用命令 - 小记</title><link>https://bluore.cn/posts/archlinuxnote/</link><guid isPermaLink="true">https://bluore.cn/posts/archlinuxnote/</guid><pubDate>Sun, 08 Mar 2026 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;网络&lt;/h1&gt;
&lt;h2&gt;ip address 命令&lt;/h2&gt;
&lt;p&gt;查看本机网络接口&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;┬─[bluore@ArchLinux-bluore:~]─[04:24:18 PM]
╰─&amp;gt;$ ip a
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute
       valid_lft forever preferred_lft forever
2: enp4s0: &amp;lt;NO-CARRIER,BROADCAST,MULTICAST,UP&amp;gt; mtu 1500qdisc fq_codel state DOWN group default qlen 1000
    link/ether 1c:83:41:ce:04:ea brd ff:ff:ff:ff:ff:ff
    altname enx1c8341ce04ea
3: wlo1: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 98:bd:80:34:02:a6 brd ff:ff:ff:ff:ff:ff
    altname wlp3s0
    altname wlx98bd803402a6
    inet 10.218.0.141/15 brd 10.219.255.255 scope global dynamic noprefixroute wlo1
       valid_lft 603914sec preferred_lft 603914sec
    inet6 fe80::6ff3:52be:8bcf:c275/64 scope link noprefixroute
       valid_lft forever preferred_lft forever
4: singbox_tun: &amp;lt;POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP&amp;gt; mtu 9000 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none
    inet 172.18.0.1/30 brd 172.18.0.3 scope global singbox_tun
       valid_lft forever preferred_lft forever
    inet6 fe80::3dd2:db03:6ace:55c5/64 scope link stable-privacy proto kernel_ll
       valid_lft forever preferred_lft forever`
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;上面是开启了&lt;code&gt;TUN（虚拟网卡）&lt;/code&gt;代理的运行情况，如果需要卸载&lt;code&gt;虚拟网卡&lt;/code&gt;执行&lt;code&gt;ip link delete &amp;lt;虚拟网卡名&amp;gt;&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;iwd 连接网络&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;iwctl
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;device list
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;# 填写你扫描到的设备
station wlan0 scan
station wlan0 get-networks
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;station wlan0 connect &amp;lt;网络名称&amp;gt;
# 回车后输入密码
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;示例：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;┬─[bluore@ArchLinux-bluore:~]─[05:17:44 PM]
╰─&amp;gt;$ iwctl
NetworkConfigurationEnabled: disabled
StateDirectory: /var/lib/iwd
Version: 3.11
[iwd]# device list
                                    Devices                                   *
--------------------------------------------------------------------------------
  Name                  Address               Powered     Adapter     Mode
--------------------------------------------------------------------------------
  wlan0                 98:bd:80:34:02:a6     on          phy0        station

[iwd]# station wlan0 scan
[iwd]# station wlan0 get-networks
                               Available networks                             *
--------------------------------------------------------------------------------
      Network name                      Security            Signal
--------------------------------------------------------------------------------
      NSU-SDN                           open                ****
      此消彼长                          psk                 ****
      Bluore&apos;s phone                    psk                 ****
      来蹭你爹的网                      psk                 ****

[iwd]# station wlan0 connect &quot;Bluore&apos;s phone&quot;
Type the network passphrase for Bluore&apos;s phone psk.
Passphrase: ********
[iwd]# exit
&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;分区&lt;/h1&gt;
&lt;h2&gt;lsblk&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;lsblk -f
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;┬─[bluore@ArchLinux-bluore:~]─[06:15:02 PM]
╰─&amp;gt;$ lsblk -f
NAME FSTYPE FSVER LABEL    UUID      FSAVAIL FSUSE% MOUNTPOINTS
zram0
     swap   1     zram0    9fb3a373-be98-4e93-aba6-88fdb3a6f25c                [SWAP]
nvme0n1
│
├─nvme0n1p1
│    vfat   FAT32          7049-B703       140.4M    30% /efi
├─nvme0n1p2
│
├─nvme0n1p3
│    ntfs         System   249A76BE9A768C54
├─nvme0n1p4
│    ntfs                  E29473BC94739231
├─nvme0n1p5
│    ntfs         Software B65659F95659BB37
├─nvme0n1p6
│    btrfs                 032c17e9-7417-4345-b04f-5ee0561a7ced   30.6G    83% /home
│                     /
└─nvme0n1p7
     btrfs                 9fea03d7-4c78-47cc-83ea-940ff1afc944
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;fdisk &amp;amp; cfdisk&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;fdisk -l
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;┬─[bluore@ArchLinux-bluore:~]─[06:16:43 PM]
╰─&amp;gt;$ sudo fdisk -l
Disk /dev/nvme0n1: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors
Disk model: KINGSTON SNV2S1000G
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: C1F0B2B5-3ACF-4502-A82D-5DB9C5B64466

Device              Start        End   Sectors   Size Type
/dev/nvme0n1p1         40     409639    409600   200M EFI System
/dev/nvme0n1p2     409640     442407     32768    16M Microsoft reserved
/dev/nvme0n1p3     444416  313382911 312938496 149.2G Microsoft basic data
/dev/nvme0n1p4  313382912  315015167   1632256   797M Windows recovery environment
/dev/nvme0n1p5  315015168 1124514447 809499280   386G Microsoft basic data
/dev/nvme0n1p6 1544091648 1953523711 409432064 195.2G Linux filesystem
/dev/nvme0n1p7 1124515840 1544091647 419575808 200.1G Linux filesystem

Partition table entries are not in disk order.


Disk /dev/zram0: 30.52 GiB, 32769048576 bytes, 8000256 sectors
Units: sectors of 1 * 4096 = 4096 bytes
Sector size (logical/physical): 4096 bytes / 4096 bytes
I/O size (minimum/optimal): 4096 bytes / 4096 bytes
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;GRUB 更新&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;grub-install --target=x86_64-efi --efi-directory=&amp;lt;EFI挂载目录&amp;gt; --bootloader-id=&amp;lt;启动项名称&amp;gt;
grub-mkconfig -o /boot/grub/grub.cfg
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;可用于在 live 环境中修复EFI启动项&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;杂项&lt;/h1&gt;
&lt;h2&gt;配置镜像源 &lt;strong&gt;pacman&lt;/strong&gt;&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;#
reflector -a 12 -c cn -f 10 --sort score --v --save /etc/pacman.d/mirrorlist
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;获取系统相关信息&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;uanme -a
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;fastfetch
&lt;/code&gt;&lt;/pre&gt;
</content:encoded></item><item><title>模仿赛机 - abc题目快捷提交</title><link>https://bluore.cn/posts/submit-help/</link><guid isPermaLink="true">https://bluore.cn/posts/submit-help/</guid><pubDate>Wed, 28 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;关于&lt;code&gt;submit&lt;/code&gt;的原理和使用&lt;/p&gt;
&lt;h1&gt;实现原理&lt;/h1&gt;
&lt;p&gt;使用时执行这个命令&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;submit abc123d.cpp
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;会创建一个本地的服务器，监听&lt;code&gt;9974&lt;/code&gt;端口，浏览器插件通过http轮训&lt;code&gt;localhost:9974&lt;/code&gt;来获取提交的文件（最多监听10s）&lt;/p&gt;
&lt;p&gt;浏览器插件可以通过文件名推断atcoder的对应题目的提交链接（使用cph的短名称自动命名），模拟输入代码和点击提交按钮（默认等待5s用来过cloudflare的人机验证）&lt;/p&gt;
&lt;p&gt;:::warning
由于chorme对于插件有一定的限制，会在后台10s内杀掉插件，所以需要点击插件进入监听页面
:::&lt;/p&gt;
&lt;h1&gt;下载和使用&lt;/h1&gt;
&lt;p&gt;将编译好的exe程序添加到环境变量PATH中&lt;/p&gt;
&lt;p&gt;:::tip
下载方式：&lt;a href=&quot;https://github.com/bluore/submit&quot;&gt;Github&lt;/a&gt;
::github{repo=&quot;Bluore/submit&quot;}
:::&lt;/p&gt;
&lt;p&gt;浏览器安装插件，使用时点击插件图标进入监听页面&lt;/p&gt;
&lt;p&gt;:::tip
下载方式：&lt;a href=&quot;https://github.com/bluore/submit-plugin&quot;&gt;Github&lt;/a&gt;
::github{repo=&quot;Bluore/submit-plugin&quot;}
:::&lt;/p&gt;
&lt;p&gt;使用时在控制台中输入命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;submit &amp;lt;filename&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;:::warning
仅支持&lt;code&gt;AtCoder Beginner Contest&lt;/code&gt;上的题目，且文件名使用&lt;code&gt;Competitive Programming Helper (cph)&lt;/code&gt;插件的短文件名格式
:::&lt;/p&gt;
</content:encoded></item><item><title>我做了个视奸我自己的网站 - CheckMe</title><link>https://bluore.cn/posts/checkme/</link><guid isPermaLink="true">https://bluore.cn/posts/checkme/</guid><description>记录一下制作这个网站所遇到的问题和解决方案</description><pubDate>Sun, 18 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;关于我做了个视奸我自己的网站 me.bluore.top&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;本文记录一下纯小白的我在写这个项目中遇到的困难&lt;/p&gt;
&lt;p&gt;能够实时视奸自己的网页是如何完成的呢，首先我想到的困难就是数据获取的问题，以及如何长期后台保活的问题&lt;/p&gt;
&lt;h1&gt;获取数据&lt;/h1&gt;
&lt;p&gt;如果是Windows系统中，这个问题就很简单，可以写一个简单的py脚本即可获取并传递数据，将文件添加快捷方式到&lt;code&gt;C:\Users\&amp;lt;用户名&amp;gt;\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup&lt;/code&gt;的文件夹下系统就会开机自启动该程序&lt;/p&gt;
&lt;p&gt;不过如果是Android系统该如果获取数据呢？&lt;/p&gt;
&lt;p&gt;最开始想的是，是否可以通过写一个App，通过申请无障碍权限来进行获取数据，并尽可能后台保活，可是不会Java和Android开发的我很快放弃了这个想法，不过正巧最近换了新的手机 ~（旧的没有放到转转）~ ，顺手刷了机，于是这个问题就简单了&lt;/p&gt;
&lt;p&gt;下面记录一下我去是如何获取Android系统中的数据，并后台长期保活&lt;/p&gt;
&lt;h2&gt;应用进程数据如何获取 ？&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;sudo dumpsys activity top | grep ACTIVITY
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;示例输出 ( MT资源管理器模拟终端 )&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;➜ sdcard sudo dumpsys activity top | grep ACTIVITY
  ACTIVITY com.v2ray.ang/.ui.MainActivity b6cc31a pid=(not running) userId=0 uid=10334 displayId=0(type=INTERNAL)
  ACTIVITY me.weishu.kernelsu/.ui.MainActivity 3246fc5 pid=(not running) userId=0 uid=10413 displayId=0(type=INTERNAL)
  ACTIVITY org.lsposed.manager/.ui.activity.MainActivity b5ee8f8 pid=(not running) userId=0 uid=10335 displayId=0(type=INTERNAL)
  ACTIVITY com.taobao.taobao/com.taobao.tao.welcome.Welcome f6a9a8c pid=(not running) userId=0 uid=10349 displayId=0(type=INTERNAL)
  ACTIVITY com.jingdong.app.mall/com.jd.lib.productdetail.ProductDetailActivity b14b607 pid=(not running) userId=0 uid=10396 displayId=0(type=INTERNAL)
  ACTIVITY com.tencent.mobileqq/.activity.SplashActivity cfc32cb pid=20711 userId=0 uid=10358 displayId=0(type=INTERNAL)
  ACTIVITY com.suda.yzune.wakeupschedule/.schedule.ScheduleActivity 5364210 pid=7721 userId=0 uid=10432 displayId=0(type=INTERNAL)
  ACTIVITY tv.danmaku.bili/.MainActivityV2 1e0fc74 pid=16964 userId=0 uid=10336 displayId=0(type=INTERNAL)
  ACTIVITY com.twitter.android/com.twitter.app.main.MainActivity 3b31223 pid=528 userId=0 uid=10402 displayId=0(type=INTERNAL)
  ACTIVITY com.google.android.youtube/.app.honeycomb.Shell$HomeActivity 88a1c87 pid=7596 userId=0 uid=10365 displayId=0(type=INTERNAL)
  ACTIVITY com.tencent.mm/.ui.LauncherUI 905c54c pid=24420 userId=0 uid=10356 displayId=0(type=INTERNAL)
  ACTIVITY mark.via/.Shell d839efd pid=666 userId=0 uid=10385 displayId=0(type=INTERNAL)
  ACTIVITY com.android.launcher/.Launcher 4818b2c pid=5268 userId=0 uid=10222 displayId=0(type=INTERNAL)
  ACTIVITY bin.mt.plus/l.ᩳۛ᩵ 27fd27e pid=11838 userId=0 uid=10398 displayId=0(type=INTERNAL)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个命令可以获取所有的活动的应用进程的包名，不过当前活动的进程包名是哪一个?&lt;/p&gt;
&lt;p&gt;经过数据的实践和统计发现，最后一行的包名正是当前正在使用的应用的包名，所以先通过&lt;code&gt;tail -1&lt;/code&gt;筛选最近使用的应用的进程信息，再进行正则表达式进行匹配&lt;code&gt;s/.*ACTIVITY \([^/]*\)\/.*/\1/p&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;完整的命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dumpsys activity top | grep ACTIVITY | tail -1 | sed -n &apos;s/.*ACTIVITY \([^/]*\)\/.*/\1/p&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;➜ sdcard sudo dumpsys activity top | grep ACTIVITY | tail -1 | sed -n &apos;s/.*ACTIVITY \([^/]*\)\/.*/\1/p&apos;
bin.mt.plus
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;获取手机电量&lt;/h2&gt;
&lt;h3&gt;通用方法&lt;/h3&gt;
&lt;p&gt;通过&lt;code&gt;dumpsys battery&lt;/code&gt;通用的方法可以获取到手机的电量&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;测试机型: &lt;em&gt;一加 Ace5 ( 版本号：PKG110_15.0.0.840(CN01) )&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;➜ sdcard sudo dumpsys battery
Current OPLUS Battery Service state:
  Charger voltage : 4757
  Battery current : -1589
  ChargerTechnology: 0
  ChargeFastCharger: false
  PlugType: 2
  UpdatesStopped: false
  UsbHwStatus: 0
  BatteryHwStatus: -2147483648
  HwStatusIsSet: 1
  BatteryIcStatus: -2147483648
  IcStatusIsSet: 1

  mUsbStatus: 0
  PhoneTemp: 330
  ThermalFeatureOn: true
Current Battery Service state:
  AC powered: false
  USB powered: true
  Wireless powered: false
  Dock powered: false
  Max charging current: 2000000
  Max charging voltage: 5000000
  Charge counter: 4864000
  status: 2
  health: 2
  present: true
  level: 87
  scale: 100
  voltage: 4402
  temperature: 325
  technology: Li-ion
  Charging state: 0
  Charging policy: 0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里的&lt;code&gt;level: 87&lt;/code&gt;就是手机显示的电量，完整筛选后的命令：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dumpsys battery | grep level | awk &apos;{print $2}&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code&gt;➜ sdcard sudo dumpsys battery | grep level | awk &apos;{print $2}&apos;
88
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样就直接获取到了当前的面板电量&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;不过这里获取到的手机电量可能并不是真实的手机电量，而是显示的面板电量(即：手机厂商想让你看到的手机电量)&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;手机真实电量&lt;/h3&gt;
&lt;p&gt;这里就不展开说了，目前本机型的 $\mathrm{面板电量} \ne  \mathrm{实际电量}$&lt;/p&gt;
&lt;h2&gt;获取当前播放的媒体标题&lt;/h2&gt;
&lt;p&gt;有了前面的经验，这次就顺利多了，使用&lt;code&gt;dumpsys media_session&lt;/code&gt;获取到一大堆信息后用&lt;code&gt;sed -n &apos;/User Records:/,/Controller Records:/p&apos;&lt;/code&gt;筛选到用户进程，然后取第一个媒体的数据&lt;code&gt;grep -m 1 &apos;metadata:&apos;&lt;/code&gt;( 因为最近播放的媒体会把之前后台播放的给顶掉，直接获取第一个即可 )，拿到媒体的标题&lt;code&gt;sed &apos;s/.*description=//&apos;&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;执行结果：&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;➜ sdcard sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos;
The Bird Song (with Em Beihold), Noah Floersch/Em Beihold, The Bird Song (with Em Beihold)      
➜ sdcard sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos;
何御, 李姿逸RizRea, 何御
➜ sdcard sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos;
小画家！, 自动连播, null
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&quot;./1.png&quot; alt=&quot;运行图&quot; /&gt;&lt;/p&gt;
&lt;p&gt;可以看到，歌曲名重复了一遍&lt;/p&gt;
&lt;p&gt;如果是播放B站视频，则歌曲名最后会显示null，这样并不美观而且会让获取的数据冗余，所以我通过&lt;code&gt;cut -d&apos;,&apos; -f1&lt;/code&gt;进行截取第一项（歌曲名）和第二项（作者名）&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos; | cut -d&apos;,&apos; -f1
sudo dumpsys media_session | sed -n &apos;/User Records:/,/Controller Records:/p&apos; | grep -m 1 &apos;metadata:&apos; | sed &apos;s/.*description=//&apos; | cut -d&apos;,&apos; -f2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这两行，分别获取标题（歌曲名、视频标题）和作者（作者名、B站状态）&lt;/p&gt;
&lt;p&gt;这样，在安卓系统中的Root环境我们便可以获取数据了&lt;/p&gt;
&lt;h2&gt;如何发送数据并后台保活&lt;/h2&gt;
&lt;p&gt;正巧我使用的设备是刷上KSU的Root设备，所以我使用的方案是写一个&lt;code&gt;mksh&lt;/code&gt;的Shell脚本，打包成一个模块，刷入到Root管理器中，开机自启动且不会被杀后台（我没遇到过）&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./2.png&quot; alt=&quot;刷入模块&quot; /&gt;&lt;/p&gt;
&lt;p&gt;其实&lt;strong&gt;ADB权限&lt;/strong&gt;也是可以的，不过会有一些限制，我就没试了 （￣︶￣） &amp;lt;-懒&lt;/p&gt;
&lt;h1&gt;代码编写&lt;/h1&gt;
&lt;p&gt;解决了核心问题，其他的就简单了&lt;/p&gt;
&lt;p&gt;后端选择&lt;code&gt;Golang&lt;/code&gt;语言，&lt;code&gt;Gin&lt;/code&gt;框架+&lt;code&gt;MySQL&lt;/code&gt;数据库，前端选择&lt;code&gt;Vue&lt;/code&gt;然后&lt;code&gt;Deepseek&lt;/code&gt;自己写 ~( vscode，你已经是一个成熟的ide了，该自己写代码了 )~ ，对于没有写过项目的我来说（刚速通完golang语法），顺便练习一下写代码的能力，所以后端边学边写，关掉了goland的整行提示 ~折磨自己~ ，自己去慢慢搓代码 ~(导致写一堆自己不想修复的Bug)~&lt;/p&gt;
&lt;p&gt;本仓库使用前后端分开部署，使用不同域名（或使用Nginx来路由），桌面端支持&lt;strong&gt;Windows&lt;/strong&gt;，手机端支持&lt;strong&gt;Root + Android&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;欢迎大家来部署玩玩&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Bluore/CheckMe&quot;&gt;CheckMe - Github&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h1&gt;效果演示&lt;/h1&gt;
&lt;p&gt;桌面端&amp;amp;移动端&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./3.png&quot; alt=&quot;桌面端&amp;amp;移动端&quot; /&gt;&lt;/p&gt;
&lt;p&gt;::github{repo=&quot;Bluore/CheckMe&quot;}&lt;/p&gt;
</content:encoded></item><item><title>NSU校园网自动连接的教程</title><link>https://bluore.cn/posts/nsunetwork/</link><guid isPermaLink="true">https://bluore.cn/posts/nsunetwork/</guid><pubDate>Thu, 24 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;:::note&lt;/p&gt;
&lt;p&gt;本文主要讲程序的使用&lt;/p&gt;
&lt;p&gt;:::&lt;/p&gt;
&lt;p&gt;为了解决校园网连接很麻烦，且一段时间后还会自动断开连接的问题，于是写了一个py程序用来自动连接校园网来简化操作和防止断开&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./image-1.png&quot; alt=&quot;校园网连接&quot; /&gt;&lt;/p&gt;
&lt;p&gt;当时写的石山代码:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;import requests
import time
import json
import os

loginKey = { #默认配置
    &quot;username&quot; : &apos;学号&apos;,
    &quot;password&quot; : &apos;一次性密钥&apos;,       #网页登录后cookie中获取
    &quot;testtime&quot; : 5,                 #检测网络连接状况时差（单位s）
    &quot;timeout&quot; : 5,                  #超时连接失败失败（单位s）
    &quot;outInFirstRequest&quot; : False,    #第一次请求就连接成功是否退出程序
    &quot;autoOutOtherIp&quot; : True,        #自动踢出其他正在连接的IP
    &quot;networkName&quot; : &quot;学生-移动-100M&quot; #自动连接的网络名称
}

def information(type):
    if type==&apos;loginKey&apos;:
        return &apos;&apos;&apos;
{ #默认配置
    &quot;username&quot; : &apos;学号&apos;,             #填写自己登录校园网的学号
    &quot;password&quot; : &apos;一次性密钥&apos;,       #网页登录后cookie中获取
    &quot;testtime&quot; : 5,                 #检测网络连接状况时差（单位s）
    &quot;timeout&quot; : 5,                  #超时连接失败失败（单位s）
    &quot;outInFirstRequest&quot; : False,    #第一次请求就连接成功是否退出程序
    &quot;autoOutOtherIp&quot; : True,        #自动踢出其他正在连接的IP
    &quot;networkName&quot; : &quot;学生-移动-100M&quot; #自动连接的网络名称
}
        &apos;&apos;&apos;

if(not os.path.exists(&quot;data.txt&quot;)):
    print(&quot;不存在配置文件，尝试创建文件&quot;)
    with open(&quot;data.txt&quot;, &apos;w&apos;, encoding=&apos;utf-8&apos;) as file:
        json.dump(loginKey, file, ensure_ascii=False, indent=4)
    print(information(&apos;loginKey&apos;))
    print(&quot;已经创建配置文件，请编辑同文件夹下data.txt填写账户和一次性密钥后【重新启动】此程序&quot;)
    time.sleep(120)
    exit()

with open(&apos;data.txt&apos;, &apos;r&apos;, encoding=&apos;utf-8&apos;) as file:
    loginKey = json.load(file)



def testIPState(username,passwordCode):
    urlTest = &quot;https://cc.nsu.edu.cn/Auth.ashx&quot;
    headersTest = {
        &quot;content-type&quot;: &quot;application/json; charset=utf-8&quot;,
        &quot;x-powered-by&quot;: &quot;ASP.NET&quot;,
        &quot;server&quot;:&quot;Microsoft-IIS/10.0&quot;
    }
    postTest = {
        &quot;DoWhat&quot;: &quot;Check&quot;
    }
    cookieTest = {
        &quot;username&quot;: username,
        &quot;password&quot;: passwordCode
    }
    result = requests.post(urlTest, headers=headersTest, json=postTest, cookies=cookieTest, timeout=loginKey[&apos;timeout&apos;])
    return result.json()


def linkNetwork(username,passwordCode):
    urlLink = &quot;https://cc.nsu.edu.cn/Auth.ashx&quot;
    headersLink = {
        &quot;content-type&quot;: &quot;application/json; charset=utf-8&quot;,
        &quot;x-powered-by&quot;: &quot;ASP.NET&quot;,
        &quot;server&quot;:&quot;Microsoft-IIS/10.0&quot;
    }
    postLink = {
        &quot;DoWhat&quot;: &quot;OpenNet&quot;,
        &quot;Package&quot;: loginKey[&apos;networkName&apos;]              #&quot;学生-移动-100M&quot;
    }
    cookieLink = {
        &quot;username&quot;: username,
        &quot;password&quot;: passwordCode
    }
    result = requests.post(urlLink, headers=headersLink, json=postLink, cookies=cookieLink, timeout=loginKey[&apos;timeout&apos;])
    print(result.text)
    return result.json()

def loginNetwork(username,passwordCode):
    urlLink = &quot;https://cc.nsu.edu.cn/Auth.ashx&quot;
    headersLink = {
        &quot;content-type&quot;: &quot;application/json; charset=utf-8&quot;,
        &quot;x-powered-by&quot;: &quot;ASP.NET&quot;,
        &quot;server&quot;:&quot;Microsoft-IIS/10.0&quot;
    }
    postLink = {
        &quot;DoWhat&quot;: &quot;Login&quot;,
        &quot;remember&quot;:True,
        &quot;username&quot;:username,
        &quot;password&quot;:passwordCode
    }
    cookieLink = {
        &quot;username&quot;: username,
        &quot;password&quot;: passwordCode
    }
    result = requests.post(urlLink, headers=headersLink, json=postLink, cookies=cookieLink, timeout=loginKey[&apos;timeout&apos;])
    print(result.text)

def listLinkNetwork(username,passwordCode):
    urlLink = &quot;https://cc.nsu.edu.cn/Auth.ashx&quot;
    headersLink = {
        &quot;content-type&quot;: &quot;application/json; charset=utf-8&quot;,
        &quot;x-powered-by&quot;: &quot;ASP.NET&quot;,
        &quot;server&quot;:&quot;Microsoft-IIS/10.0&quot;
    }
    postLink = {
        &quot;DoWhat&quot;: &quot;GetInfo&quot;
    }
    cookieLink = {
        &quot;username&quot;: username,
        &quot;password&quot;: passwordCode
    }
    result = requests.post(urlLink, headers=headersLink, json=postLink, cookies=cookieLink, timeout=loginKey[&apos;timeout&apos;])
    print(result.text)
    return result.json()

def delLinkNetwork(username,passwordCode,ip):
    urlLink = &quot;https://cc.nsu.edu.cn/Auth.ashx&quot;
    headersLink = {
        &quot;content-type&quot;: &quot;application/json; charset=utf-8&quot;,
        &quot;x-powered-by&quot;: &quot;ASP.NET&quot;,
        &quot;server&quot;:&quot;Microsoft-IIS/10.0&quot;
    }
    postLink = {
        &quot;DoWhat&quot;: &quot;CloseNet&quot;,
        &quot;IP&quot;: ip
    }
    cookieLink = {
        &quot;username&quot;: username,
        &quot;password&quot;: passwordCode
    }
    result = requests.post(urlLink, headers=headersLink, json=postLink, cookies=cookieLink, timeout=loginKey[&apos;timeout&apos;])
    print(result.text)
    return result.json()

exitFlag = False
if loginKey[&apos;outInFirstRequest&apos;]:
    try:
        getStste = testIPState(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;])
        print(&quot;已连接网络，3秒后自动退出&quot;)
        exitFlag = True
        time.sleep(3)
    except:
        print(&quot;!&amp;gt;&amp;gt;something error&quot;)
        time.sleep(3)

while 1:
    if exitFlag == True:
        break
    try:
        getStste = testIPState(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;])
        #print(getStste)
        print(&apos;&amp;gt;&amp;gt;&amp;gt;&apos;+getStste[&apos;Message&apos;])
        time.sleep(0.1)
        if getStste[&apos;Result&apos;]:
            if getStste[&apos;Message&apos;] == &apos;已上线IP，免认证！&apos;:
                time.sleep(loginKey[&apos;testtime&apos;])
                continue
            if getStste[&apos;Message&apos;] == &apos;已登录IP，免认证！&apos;:
                print(&quot;!&amp;gt;&amp;gt;尝试上线本机&quot;)
                getStste = linkNetwork(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;])
                if getStste[&apos;Message&apos;] == &apos;同时登录数已达上限！&apos;:
                    if not loginKey[&apos;autoOutOtherIp&apos;]:
                        time.sleep(loginKey[&apos;testtime&apos;])
                        continue
                    #print(&quot;其他设备正在上线中，将在10秒后重试&quot;)
                    print(&quot;&amp;gt;&amp;gt;&amp;gt;其他设备正在上线中，正在尝试查询其他设备&quot;)
                    getStste = listLinkNetwork(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;])
                    time.sleep(0.1)
                    print(&quot;&amp;gt;&amp;gt;&amp;gt;其他设备正在上线中，正在尝试查询其他设备&quot;)
                    getStste = delLinkNetwork(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;], getStste[&apos;Data&apos;][&apos;OIA&apos;][0][&apos;IP&apos;])
                    if(getStste[&apos;Result&apos;]):
                        print(f&quot;&amp;gt;&amp;gt;&amp;gt;已成功下线IP({getStste[&apos;IP&apos;]})，正在尝试上线本设备&quot;)
                        time.sleep(0.1)
                        continue
                    print(f&quot;&amp;gt;&amp;gt;&amp;gt;下线IP({getStste[&apos;IP&apos;]})失败，请求返回信息{getStste[&apos;Message&apos;]}&quot;)
                    time.sleep(5)
                continue
        if getStste[&apos;Result&apos;] == &apos;needLogin&apos;:
            print(&quot;!&amp;gt;&amp;gt;尝试自动登录&quot;)
            loginNetwork(loginKey[&apos;username&apos;], loginKey[&apos;password&apos;])
        if not getStste[&apos;Result&apos;]:
            if getStste[&apos;Message&apos;] == &apos;请求太频繁，请稍后再试...&apos;:
                print(&quot;3秒后重试&quot;)
                time.sleep(3)
    except:
        print(&quot;!&amp;gt;&amp;gt;something error&quot;)
        time.sleep(3)

exit()
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;::github{repo=&quot;Bluore/NSUnetwork&quot;}&lt;/p&gt;
&lt;h1&gt;使用方法&lt;/h1&gt;
&lt;p&gt;下载程序&lt;a href=&quot;https://github.com/Bluore/NSUnetwork/releases/tag/main&quot;&gt;Github&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;:::tip
&lt;code&gt;nsunetowrk_console.exe&lt;/code&gt;版本运行后会有控制台输出&lt;/p&gt;
&lt;p&gt;&lt;code&gt; nsunetowrk_NO-console.exe&lt;/code&gt;版本运行后没有控制台输出，后台无感运行
:::&lt;/p&gt;
&lt;h2&gt;使用软件&lt;/h2&gt;
&lt;p&gt;首次打开时会出现提示：&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;不存在配置文件，尝试创建文件

{ #默认配置
    &quot;username&quot; : &apos;学号&apos;,             #填写自己登录校园网的学号
    &quot;password&quot; : &apos;一次性密钥&apos;,       #网页登录后cookie中获取
    &quot;testtime&quot; : 5,                 #检测网络连接状况时差（单位s）
    &quot;timeout&quot; : 5,                  #超时连接失败失败（单位s）
    &quot;outInFirstRequest&quot; : False,    #第一次请求就连接成功是否退出程序
    &quot;autoOutOtherIp&quot; : True,        #自动踢出其他正在连接的IP
    &quot;networkName&quot; : &quot;学生-移动-100M&quot; #自动连接的网络名称
}

已经创建配置文件，请编辑同文件夹下data.txt填写账户和一次性密钥后【重新启动】此程序
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开文件目录下的&lt;code&gt;data.txt&lt;/code&gt;文件按提示编辑，如何填写请看后文&lt;/p&gt;
&lt;p&gt;填写完成后请再次运行程序即可自动连接&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;autoOutOtherIp&lt;/code&gt; 为 &lt;code&gt;True&lt;/code&gt;时会自动踢出其他设备&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;获取&lt;code&gt;username&lt;/code&gt;和&lt;code&gt;password&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;先登录账号&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-2.png&quot; alt=&quot;1&quot; /&gt;&lt;/p&gt;
&lt;p&gt;按下&lt;code&gt;F12&lt;/code&gt;打开控制台，进入&lt;code&gt;存储&lt;/code&gt;栏(也可能叫&lt;code&gt;应用&lt;/code&gt;、&lt;code&gt;Application&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image-3.png&quot; alt=&quot;2&quot; /&gt;&lt;/p&gt;
&lt;p&gt;复制值到配置文件即可&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;image.png&quot; alt=&quot;3&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;如何开机自启动&lt;/h2&gt;
&lt;p&gt;按下&lt;code&gt;Win + R&lt;/code&gt;按键打开运行面板，输入&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;shell:startup
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;打开文件夹，将程序的快捷方式放入该文件夹即可&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;文章实际发布时间&lt;code&gt;2026-1-19&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</content:encoded></item></channel></rss>