# 奥日

腾空感的营造

奥日中的跳跃的腾空感很好,实际上,它的角色在空中的最高处也会有一个较为明显的停顿,这种停顿让人感觉到了空中的腾空感。

但是这样的处理却没有让玩家感受到奇怪,最主要的原因是,奥日的跳跃跳跃到了最顶点的时候,角色会将腿抬起,这个动作让人感觉到了空中的停顿是合理的。实际上,角色的高度并没有变化,但是却让人感觉到了仍然在上升的腾空感。

# 耳机

背景

不知道从什么时候起,我也变成了耳机的发烧友,可能这和我喜欢听歌以及asmr有关。

反正就是,正好,因为以前一直觉得有线的那种小耳塞耳机怎么可能音质上比得过头戴式的呢,所以一直都是用的头戴式的耳机。但是就是我现在的头戴式耳机,在有线连接的时候没有麦克风有点麻烦,所以说就打算换一个音质更好的耳机。

水月雨梅-壁纸.jpg

于是我就想买一个纯有线的头戴式耳机,但是发现貌似没有这个品类,各大品牌的有线耳机基本上都是“游戏耳机”即只是追求低延时,而对于音质的追求并不高。而上了大300的价位,就直接变成无线的耳机了,但是对于无线使用,不如我的tws耳机方便,所以我就不想买无线的耳机。

所以我就开始寻找有线的耳机,那么就只有一种选择了,那就是有线耳塞耳机。所以我就开始寻找一些耳塞耳机的测评,然后就发现了水月雨梅这个耳机。

说实话,这个价格还是有点贵的,但是我还是买了,因为我觉得这个耳机的音质应该是不错的,而且这个耳机的外观也是我喜欢的。而且它还有二次元的元素,我个人认为这个是一个加分项目。

整个耳机的话,在我使用过后,性价比其实还是可以的,因为实际上这个耳机的音质非常优秀,然后这个耳机附带的配件的耳机线是内置DSP的,也就是说,内置一个可以调控的音频解码器(我自己买了一个小尾巴,大概是70¥,然后支持内置调音的话,估计想要单独买100¥上下,实际上,官网单独卖它的那根线确实是价格在120¥)。

音质

总体来说音质非常好,比我之前的那个头戴式耳机好不少,更何况这个耳机支持freeDSP,所以说,音质的调节是非常方便的。

真的要挑刺的话,这个耳机的低频还是有点小问题,毕竟是耳塞耳机,所以说低频的表现还是不如头戴式耳机的,但是这个耳机的高频和中频表现非常好。

佩戴感

因为其采用的是耳挂式的设计,比起头戴式来说是真的无感,而且头戴式的耳机会存在一些压迫感,以及闷汗的问题,而这个耳机就没有这个问题。

freeDSP

是什么

freeDSP是一种音频解码器,它可以通过调节音频的参数来调节音质。

怎么使用

使用freeDSP需要耳机,耳机线都支持freeDSP,然后需要一个支持freeDSP的软件,然后就可以通过软件来调节音质。

通过调节不同频率的声音的增益,可以调节整体的音质。理论上来说,耳机素质够好的话,能够通过调音来实现任意耳机的音质效果。

阅读全文 »

���������???, �����������???.
阅读全文 »

# 杂项技术

背景

我们有的时候只是涉及到一些小文件,比如一些配置文件,一些小的图片等等,这些文件的内容不是很大,但是我们又不想直接把这些文件放到项目中,这个时候我们可以使用链接来直接存储这些小文件的内容。

而url支持使用 data 协议来使用base64格式直接存储小文件的内容,这样我们就可以直接使用链接来存储小文件的内容。

使用

我们可以使用如下的方式来存储小文件的内容:

1
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAA/0lEQVQ4jZXTsUoDQRDG8d8Q9" alt="Red dot" />

这里的 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAACXBIWXMAAAsSAAALEgHS3X78AAAA/0lEQVQ4jZXTsUoDQRDG8d8Q9 就是一个base64格式的图片内容,我们可以直接使用这个链接来展示图片。

然后我写了一个简单的脚本来生成base64格式的图片内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#include <fstream>
#include <vector>
#include <string>
#include <iostream>

const std::string base64_chars =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
"0123456789+/";

#include <chrono>

std::string base64_encode(const std::vector<unsigned char>& buffer) {
std::string encoded;
int i = 0;
int j = 0;
unsigned char char_array_3[3];
unsigned char char_array_4[4];

int totalBytes = buffer.size();
int progressInterval = totalBytes / 10; // Update progress every 10% of the total bytes

for (const auto& byte : buffer) {
char_array_3[i++] = byte;
if (i == 3) {
char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
char_array_4[3] = char_array_3[2] & 0x3f;

for (i = 0; (i < 4); i++)
encoded += base64_chars[char_array_4[i]];
i = 0;

// Update progress
if (encoded.size() % progressInterval == 0) {
int progress = (encoded.size() * 100) / totalBytes;
std::cout << "Progress: " << progress << "%" << std::endl;
}
}
}

if (i) {
for (j = i; j < 3; j++)
char_array_3[j] = '\0';

char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);

for (j = 0; (j < i + 1); j++)
encoded += base64_chars[char_array_4[j]];

while ((i++ < 3))
encoded += '=';
}

return encoded;
}

void fileToBase64(const std::string& path) {
std::ifstream file(path, std::ios::binary);
std::vector<unsigned char> buffer(std::istreambuf_iterator<char>(file), {});

std::string base64 = base64_encode(buffer);
std::string dataUrl = "data:application/x-rar-compressed;base64," + base64;
//输出到 “downloadLink_”+文件名.md文件

//1.获取不带路径的文件名
std::string::size_type iPos = path.find_last_of('\\') + 1;
std::string fileName = path.substr(iPos, path.length() - iPos);
std::cout << fileName << std::endl;

//2.获取不带后缀的文件名
std::string fileNameWithoutExtension = fileName.substr(0, fileName.rfind("."));
std::cout << fileNameWithoutExtension << std::endl;

//3.获取后缀名
std::string suffix_str = fileName.substr(fileName.find_last_of('.') + 1);
std::cout << suffix_str << std::endl;

std::string outputFileName = "downloadLink_" + fileNameWithoutExtension + ".md";
std::ofstream output(outputFileName);
//输出到md文件
//为md文件添加属性
//---
// title: downloadLink_下载文件名称
// date: 2024-05-02 17:36
// mathjax: false
// tags:
// - Download
// ---
output << "---" << std::endl;
output << "title: " << fileName << std::endl;
output << "date: 2024-03-01 17:36" << std::endl;
output << "mathjax: false" << std::endl;
output << "tags:" << std::endl;
output << " - Download" << std::endl;
output << "---" << std::endl;
//输出下载链接,文件名为原文件名
//以按钮的形式显示下载链接
output << "<a href=\"" << dataUrl << "\" download=\""<< fileName <<"\">点击下载</a>";
output.close();

//再在文件夹“DownloadLink”里添加一个只有属性但是不包含下载链接的md文件
std::string outputFileName2 = "downloadLink_" + fileNameWithoutExtension + ".md";
std::ofstream output2("DownloadLink\\" + outputFileName2);
//输出到md文件
//为md文件添加属性
//---
// title: downloadLink_下载文件名称
// date: 2024-05-02 17:36
// mathjax: false
// tags:
// - Download
// ---
output2 << "---" << std::endl;
output2 << "title: " << fileName << std::endl;
output2 << "mathjax: false" << std::endl;
output2 << "date: 2024-03-01 17:36" << std::endl;
output2 << "tags:" << std::endl;
output2 << " - Download" << std::endl;
output2 << "---" << std::endl;
output2.close();

std::cout << "Output file: " << outputFileName << std::endl;
}

//接收文件位置参数
int main(int argc, char* argv[]) {
//检查参数
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " file1 [file2] [file3] ..." << std::endl;
return 1;
}
//支持多个文件
for (int i = 1; i < argc; i++){
//显示进度条
std::cout << "Processing " << argv[i] << "..." << std::endl;
fileToBase64(argv[i]);
}

//结束后暂停
std::cout << "Press any key to exit..." << std::endl;
std::cin.get();
return 0;
}

这个脚本可以将指定的文件转换为base64格式的内容,并且生成一个md文件,这个md文件包含了下载链接,我们可以直接使用这个md文件来展示下载链接。

下面就是一个使用这个脚本生成的md文件的例子:

1
2
3
4
5
6
7
8
---
title: test.rar
date: 2024-03-01 17:36
mathjax: false
tags:
- Download
---
<a href="data:application/x-rar-compressed;base64,UEsDBAoAAAAAAKx4pVgvcG0lQAAAAEAAAAAMAAAAtePO0rXjztIudHh05ZOI5ZOI5ZOI77yM5piv5LiN5piv5oy65aW9546p55qEDQoNCuS9v+eUqOmTvuaOpeS8oOi+k+WOi+e8qeWMhVBLAQI/AAoAAAAAAKx4pVgvcG0lQAAAAEAAAAAMACQAAAAAAAAAIAAAAAAAAAC1487StePO0i50eHQKACAAAAAAAAEAGACtFN2Yup7aAVB935i6ntoBiknN7yme2gFQSwUGAAAAAAEAAQBeAAAAagAAAAAA" download="test.zip">点击下载</a>

点击下载

这样我们就可以直接使用这个md文件来展示下载链接了。

# 杂项技术

背景

新版 QQnt 使用了基于 Node.js 的插件架构技术,这种技术可以让开发者通过编写插件来扩展 QQnt 的功能。Node.js 是一种 JavaScript 运行时环境,它可以让开发者使用 JavaScript 编写服务器端应用程序。

其使用了node.js来进行处理的话,就意味着我们可以使用插件,来对最终渲染的内容进行修改。实际上就和 【html网页可以使用js插件进行自定义】或者说【hexo可以使用node.js插件进行自定义一样】。

QQnt 的插件架构技术利用了 Node.js 的模块化特性,将不同的功能模块封装成独立的插件,并通过插件管理器来加载和管理这些插件。LiteLoaderQQnt就为我们提供了这样的一个插件管理器,下面将其简称为LLnt。

使用方式&注意事项

使用方式可以查看他们的github页面,有十分详细的教程,在这里就不过多赘述。 LiteLoaderQQNT

tips:设置里面所做出的更改既无法保存也无法生效

需要注意的是,软件必须获取qqnt安装位置的所有文件访问权限,不然的话,llnt设置里面所做出的更改既无法保存也无法生效。解决这个问题有两种办法:

方法一:调整安装位置

只需要将qq安装位置不要放在默认的program file下即可,因为访问里面的文件需要管理员权限。可以将qq安装到其他目录,比如C盘的根目录或者自定义的文件夹中。这样就可以获得访问权限,llnt设置里面的更改才能保存和生效。

方法二:将qqnt文件夹取消只读,以管理员身份启动qqnt

另一种解决方法是取消qqnt文件夹的只读属性,并以管理员身份启动qqnt。这样可以确保llnt设置里面的更改能够保存和生效。

要取消qqnt文件夹的只读属性,可以按照以下步骤操作:

  1. 在资源管理器中,找到qqnt文件夹的位置。
  2. 右键单击qqnt文件夹,并选择“属性”选项。
  3. 在属性对话框中,取消选中“只读”复选框。
  4. 单击“确定”按钮保存更改。

然后,以管理员身份启动qqnt,可以通过以下步骤完成:

  1. 找到qqnt的快捷方式或可执行文件。
  2. 右键单击快捷方式或可执行文件,并选择“以管理员身份运行”选项。

这样,llnt设置里面的更改就能够保存和生效了。

下面我保存了一些下载链接,虽然说按理来说可以直接上github链接的,但是总是感觉那个不太稳定(作者删库跑路),所以说这里相当于存一份~

阅读全文 »
0%