Chr_小屋 - 编程
type: channel
link: https://blog.chrxw.com/tag/编程/
items: 使用C#源生成器自动完成服务注册
items: 油猴脚本不求人！零基础油猴脚本编写指南
items: EXAPUNKS附加任务攻略（未完结）
items: 51单片机猜数字游戏
items: Python爬取信息学在线题库

使用C#源生成器自动完成服务注册
type: item
date: 2024-01-24T11:28:19+08:00
description: 前言 完整项目地址: https://github.com/chr233/XinjingdailyBot 因为项目之前是使用运行时反射来完成服务的动态注册，而源生成器是在编译前完成代码生成并参与编译，完全没有运行时的性能开销 运行时反射 - 旧的方案 标记特性 首先创建一个 Attribute, 用来标注需要扫描的服务类 namespace XinjingdailyBot.Infrastructure.Attribute; /// /// 标记服务 /// 1、如果服务是本身 直接在类上使用[AppService] /// 2、如果服务是接口 在类上使用 [AppService(ServiceType = typeof(实现接口))] /// [AttributeUsage(AttributeTargets.Class, Inherited = false)] public sealed class AppServiceAttribute : System.Attribute { /// /// 服务声明周期 /// 不给默认值的话注册的是AddSingleton /// public LifeTime ServiceLifetime { get; set; } = LifeTime.Scoped; /// /// 指定服务类型 /// public Type? ServiceType { get; set; } /// /// 是否可以从第一个接口获取服务类型 /// public bool InterfaceServiceType { get; set; } /// /// 标记服务 /// /// public AppServiceAttribute(LifeTime serviceLifetime) { ServiceLifetime = serviceLifetime; } /// /// 标记服务 /// /// /// public AppServiceAttribute(Type? serviceType, LifeTime serviceLifetime) { ServiceLifetime = serviceLifetime; ServiceType = serviceType; } /// /// 标记服务 /// /// /// /// public AppServiceAttribute(Type? serviceType, LifeTime serviceLifetime, bool interfaceServiceType) { ServiceLifetime = serviceLifetime; ServiceType = serviceType; InterfaceServiceType = interfaceServiceType; } } /// /// 生命周期 /// public enum LifeTime { /// /// 瞬时 /// Transient, /// /// 范围 /// Scoped, /// /// 单例 /// Singleton } 基于反射的服务扫描器 然后再主项目启动的时候使用反射扫描添加了该 Attribute 的所有 Class 并注册服务 using System.Diagnostics.CodeAnalysis; using System.Reflection; using XinjingdailyBot.Infrastructure.Attribute; namespace XinjingdailyBot.WebAPI.Extensions; /// /// 动态注册服务扩展 /// public static class AppServiceExtensions { private static readonly NLog.Logger _logger = NLog.LogManager.GetCurrentClassLogger(); /// /// 注册引用程序域中所有有AppService标记的类的服务 /// /// [RequiresUnreferencedCode("不兼容剪裁")] public static void AddAppService(this IServiceCollection services) { var cls = new string[] { "XinjingdailyBot.Repository", "XinjingdailyBot.Service", "XinjingdailyBot.Command", "XinjingdailyBot.WebAPI", }; foreach (var item i…

油猴脚本不求人！零基础油猴脚本编写指南
type: item
date: 2021-02-08T22:57:00+08:00
description: 前言 本文首发于我的博客和其乐论坛，未经授权禁止转载 本文全程使用原生JavaScript进行编程，不使用像jQuery这样的第三方库 视频链接 零基础油猴脚本编写指南【上】 （对应0x01~0x05） 0x00 前置知识 本节简单的介绍一下一些名词的概念，了解为主，直接跳过也是可以的 HTML、CSS和JS HTML即超文本标记语言，它用来描述各种网页元素，类似与一份清单，浏览器读取以后根据它来加载对应的资源 CSS即层叠样式表，它只用来描述网页元素的外观，还可以添加少许动画，但是不影响功能 JS即JavaScript，它是一种网页脚本语言，用来让静态的网页能够响应各种动作，还可以挖矿 如果把HTML比作木偶，那么CSS就是木偶的衣服，JS就是木偶的提线，用来操控木偶 油猴和浏览器 当你访问链接的时候，浏览器会先下载链接对应的文件（通常是一个HTML文件），然后根据HTML描述的对象列表，来下载图片、视频等资源，有的CSS和JS内嵌在HTML文件里，有的则是单独的文件，等必要的资源加载完成以后，浏览器才能生成可以交互的网页 油猴实际上是一个加载器，它把用户脚本安插在最开始获取到的HTML文件中，这样浏览器加载网页的时候，也会加载特定的用户脚本，这样我们就能够通过编写用户脚本来修改网页了 HTML5和DOM HTML5是现行的HTML标准，DOM即文档对象模型，是一用对象表示HTML标签的方法，通过DOM，我们可以简单的修改文档对象的属性，来轻松修改HTML标签的内容 0x01 初识开发者工具 工欲善其事必先利其器，本节简单的介绍一下开发者工具的使用。 本节以我的博客作为演示，地址：chrxw.com 个人比较喜欢Firefox的开发者工具，以下介绍均使用Firefox进行演示，如果使用Chrome的话可能布局会有细微差异，不过功能是类似的。 Chrome自带的开发者工具貌似没有汉化，建议使用别的Chromium内核的浏览器（比如新版Edge），功能都差不多。 在浏览器中按F12即可打开开发者工具 查看器，左侧可以查看页面的HTML内容，右侧显示的是选中的DOM元素的CSS 控制台，可以运行自己编写的JS代码。 也可以在设置里打开“分离式控制台”，这样就可以在所有TAB里都显示控制台了。 调试器，可以用来单步调试JS 网络，可以查看浏览器的网络请求 储存，在这个TAB中可以查看网站在本地保存的内容，最常用的是Cookie，其次是LocalStorge（本地储存），还有个由浏览器自动管理的Session（会话储存），JS可以访问的只有Cookie和LocalStorge。 0x02 初识DOM 本节通过使用开发者工具，简单的演示一下如何操作DOM元素，以我的博客作为演示，地址：chrxw.com 首先打开开发者工具，然后激活选择器，然后点击“标题”，这样在右边的查看器中就会显示我们点击的对象 右键高亮的元素，然后点击“在控制台使用”（如果是Chromium或者Chrome，点击“复制”/“Copy”->“复制JS路径”/“Copy JS path”，然后把复制结果粘贴到控制台中） Firefox自动创建了一个temp0变量，按一下回车，可以看到控制台输出了一个DOM元素，点一下左边的箭头展开，可以看到这个对象的各种属性。 接下来我们尝试修改一下它的内容 temp0.textContent = 'hello world'; 按回车执行，然后可以看到，网页的标题已经被修改了 接着我们修改一下CSS，让它居中显示 temp0.style.textAlign='center'; 接下来我们创建一个新的DOM元素，然后插入到网页中 let btn = document.createElement('button'); btn.textContent = '按钮'; btn.addEventListener('click',() => { alert('hello world'); }); temp0.appendChild(btn); 点一下新出现的按钮，可以看到消息弹窗 代码讲解： PS： document 也是DOM元素，它代表整个网页，其他DOM元素都是它的子集。 let btn = document.createElement('button'); btn.textContent = '按钮'; 这两行代码创建了一个button对象，它内部的文本为按钮，由浏览器自动生成的HTML表达式为 按钮 btn.addEventListener('click',() => { alert('hello world'); }); 这三行代码为btn对象添加了事件监听器，addEventListener的第一个参数是事件监听器的名称，第二个参数…

EXAPUNKS附加任务攻略（未完结）
type: item
date: 2019-10-27T10:05:00+08:00
description: 1. BLOODLUST ONLINE(血之欲 在线) 目标： 终止目标主机中的所有EXA 按要求修改目标主机中的文件 本机的文件300中包含几个有用的单词 每个主机相当于一个玩家阵营，文件200保存了该阵营的ID，类型和状态。 首先要找到文件200中包含TALISMAN的阵营，然后读取MAP后面另一个阵营的名字，文件里还有个UNLOCK单词，也是要用到的。 去那个阵营，杀光所有EXA，相当于让玩家掉线(不然会引起注意) 打开文件200，将CLOCK的值重写为SAFE的值，然后将DOOR的值改成UNLOCK 不留痕迹 程序： XA：GRAB 300 LINK 800 COPY F X # REPL SEARCHHOSTNAME COPY F M COPY M X COPY F M COPY M T REPL SEARCHHOST COPY F M COPY F M SEEK -3 COPY F M COPY T M WIPE JUMP END # MARK SEARCHHOSTNAME COPY 800 T @REP 6 REPL SEARCHER1 ADDI T 1 T @END # MARK SEARCHER1 LINK T GRAB 200 SEEK 1 MARK VERIFYFILELOOP TEST X = F SEEK 2 FJMP VERIFYFILELOOP # COPY M X SEEK -9999 SEEK 1 MARK SEARCHNAMELOOP TEST X = F TJMP FINDHOSTNAME SEEK 2 JUMP SEARCHNAMELOOP # MARK FINDHOSTNAME COPY F M COPY M X SEEK -9999 SEEK 1 MARK SEARCHUNLOCKLOOP TEST X = F TJMP FINDUNLOCK SEEK 2 JUMP SEARCHUNLOCKLOOP # MARK FINDUNLOCK COPY F M JUMP END # MARK REGISTER COPY T M JUMP END # MARK SEARCHHOST COPY 800 T @REP 6 REPL SEARCHER2 ADDI T 1 T @END # MARK SEARCHER2 LINK T HOST T TEST X = T FJMP END # @REP 4 KILL @END GRAB 200 COPY M X SEEK -9999 SEEK 1 MARK SEARCHSAFELOOP TEST X = F TJMP FINDSAFE SEEK 2 JUMP SEARCHSAFELOOP # MARK FINDSAFE COPY M X COPY F T MODE REPL REGISTER SEEK -9999 SEEK 1 MARK SEARCHCLOCKLOOP TEST X = F TJMP FINDCLOCK SEEK 2 JUMP SEARCHCLOCKLOOP # MARK FINDCLOCK COPY M F MODE COPY M X SEEK -9999 SEEK 1 # MARK SEARCHLOCKLOOP TEST X = F TJMP FINDLOCK SEEK 2 JUMP SEARCHLOCKLOOP # MARK FINDLOCK COPY M F # MARK END 2. MOTOR VEHICLE ADMINISTRATION(机动车管理处) 目标： 终止公共区域的所有EXA 按要求修改预约列表 中间是一个模拟的叫号系统，右上角写着下一个轮到的EXA，把被叫到的号码输入#NEXT就能打开链接 中间的每个EXA手里拿着票文件，文件内容是号码，文件号是纯数字号码 我们要找到文件号最小的那个文件，输入#NEXT，然后打开链接 进入左上角以后，#DATE是今天的日期，文件200是预约列表： 你的名字在文件300里 先找到有你的名字的那行，删掉它 读取日期，定位到日期是今天的最后一行 把你的信息写入文件，后面的内容整体后移 不留痕迹 程序： XA： GRAB 300 COPY F X COPY X M COPY M T # MARK REMOTESTORE COPY X M COPY M X COPY T M COPY M T JUMP REMOTESTORE MARK END XB： LINK 800 @REP 5 KILL @END COPY 209 X # MARK GRABLOOP ADDI X 1 X REPL GRAB JUMP GRABLOOP # MARK GRAB GRAB X KILL COPY F #N…

51单片机猜数字游戏
type: item
date: 2019-08-15T09:21:00+08:00
description: 暑假学了点51单片机，顺手撸了个猜数字小游戏。 [...]

Python爬取信息学在线题库
type: item
date: 2019-05-03T19:59:00+08:00
description: 最近在研究用Python写爬虫，老师给了我一个网站练手，正好趁热打铁（笑）。 [...]