分类 线皮标识 最高传输速度
五类 CAT-5 100Mbps
超五类 CAT-5e 1Gbps
六类 CAT-6 1Gbps
超六类 CAT-6a/6e 10Gbps
7类 CAT-7 10Gbps
8类 CAT-8 40Gbps

vscode中安装c++扩展后进行调试

点击最左边Run and Debug,再点击设置图标打开launch.json,点击右下边的Add Configuration。选择gdb launch。
修改program值为生成的可执行程序目录地址。
miDebuggerPath值修改为gdb.exe的目录地址。
回到Run and Debug,点击左上角运行按钮,即可使用断点调试了,左下角的调试按钮不是根据launch.json的配置调试的。

cmake编译项目

安装vscode的cmake扩展。settings.json的”cmake.sourceDirectory”中设置CMakeLists.txt位置。
点击最左侧cmake按钮,点击PROJECT STATUS的Delete Cache and Reconfigure。
点击PROJECT OUTLINE的Build All Projects,完成编译

手动命令编译

没有vscode上面的编译方法的多线程编译,可能编译较慢

1
2
3
# 在build文件夹,".."为上级目录即CMakeLists.txt的所在目录
cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
1
2
3
4
# 其他常用命令
cmake --install .
ctest.exe -VV
cpack -G ZIP

在设置-WiFi和互联网-代理服务器中,使用手动指定的代理服务器配置
http://127.0.0.1端口****
过一会,或者重启chromium生效。

1.生成tags的page

1
hexo new page tags

2.在新生成的文件中增加一行type: tags

1
2
3
title: Tags
date: 2014-12-22 12:39:04
type: tags

3.在_config.next.yml中添加tags的menu

1
2
3
4
menu:
home: / || fa fa-home
archives: /archives/ || fa fa-archive
tags: /tags/ || fa fa-tags

来源

    error_page 404 /index.html;
    location = /404/ {
            root /root/myblog/public;
            internal;
    }

1.新建一个空白的公开仓库

2.登录github,点击https://github.com/apps/utterances,单击 Install 按钮,选择刚才新建的空白仓库

3.运行命令

1
2
3
cd <your-blog>
npm install hexo-theme-next
cp node_modules/hexo-theme-next/_config.yml _config.next.yml

来源1

4.更改语言和主题在_config.yml中

1
2
theme: next
language: zh-CN

5.更改_config.next.yml
活动的评论插件改为utterances,并启用utterances的enable

1
2
3
4
5
6
7
8
comments:
# Choose a comment system to be displayed by default.
# Available values: disqus | disqusjs | changyan | livere | gitalk | utterances
active: utterances
***
***
utterances:
enable: true

来源2

6.注意需要能够正常访问github,而且加载评论会延迟几秒

在_config.next.yml中将busuanzi_count的enable改为true后,还是不显示访问次数统计,打开F12ERR_BLOCKED_BY_CLIENT "busuanzi"报错,google后发现是uBlock Origin广告屏蔽器把他屏蔽了,关掉uBlock Origin和Proxy SwitchyOmega,终于能够正常显示访问次数了。
来源

Worker 部署 VLESS

来到 Cloudflare 首页,点击 Workers 和 Pages ,创建 Work ,自定义名称,然后部署!
而后,编辑代码,清除原先代码,填入如下代码:

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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
// <!--GAMFC-->version base on commit 841ed4e9ff121dde0ed6a56ae800c2e6c4f66056, time is 2024-04-16 18:02:37 UTC<!--GAMFC-END-->.
// @ts-ignore
import { connect } from 'cloudflare:sockets';

// How to generate your own UUID:
// [Windows] Press "Win + R", input cmd and run: Powershell -NoExit -Command "[guid]::NewGuid()"
let userID = 'd342d11e-d424-4583-b36e-524ab1f0afa4';

let proxyIP = 'cdn.xn--b6gac.eu.org';


if (!isValidUUID(userID)) {
throw new Error('uuid is not valid');
}

export default {
/**
* @param {import("@cloudflare/workers-types").Request} request
* @param {{UUID: string, PROXYIP: string}} env
* @param {import("@cloudflare/workers-types").ExecutionContext} ctx
* @returns {Promise<Response>}
*/
async fetch(request, env, ctx) {
try {
userID = env.UUID || userID;
proxyIP = env.PROXYIP || proxyIP;
const upgradeHeader = request.headers.get('Upgrade');
if (!upgradeHeader || upgradeHeader !== 'websocket') {
const url = new URL(request.url);
switch (url.pathname) {
case '/':
return new Response(JSON.stringify(request.cf), { status: 200 });
case `/${userID}`: {
const vlessConfig = getVLESSConfig(userID, request.headers.get('Host'));
return new Response(`${vlessConfig}`, {
status: 200,
headers: {
"Content-Type": "text/plain;charset=utf-8",
}
});
}
default:
return new Response('Not found', { status: 404 });
}
} else {
return await vlessOverWSHandler(request);
}
} catch (err) {
/** @type {Error} */ let e = err;
return new Response(e.toString());
}
},
};




/**
*
* @param {import("@cloudflare/workers-types").Request} request
*/
async function vlessOverWSHandler(request) {

/** @type {import("@cloudflare/workers-types").WebSocket[]} */
// @ts-ignore
const webSocketPair = new WebSocketPair();
const [client, webSocket] = Object.values(webSocketPair);

webSocket.accept();

let address = '';
let portWithRandomLog = '';
const log = (/** @type {string} */ info, /** @type {string | undefined} */ event) => {
console.log(`[${address}:${portWithRandomLog}] ${info}`, event || '');
};
const earlyDataHeader = request.headers.get('sec-websocket-protocol') || '';

const readableWebSocketStream = makeReadableWebSocketStream(webSocket, earlyDataHeader, log);

/** @type {{ value: import("@cloudflare/workers-types").Socket | null}}*/
let remoteSocketWapper = {
value: null,
};
let udpStreamWrite = null;
let isDns = false;

// ws --> remote
readableWebSocketStream.pipeTo(new WritableStream({
async write(chunk, controller) {
if (isDns && udpStreamWrite) {
return udpStreamWrite(chunk);
}
if (remoteSocketWapper.value) {
const writer = remoteSocketWapper.value.writable.getWriter()
await writer.write(chunk);
writer.releaseLock();
return;
}

const {
hasError,
message,
portRemote = 443,
addressRemote = '',
rawDataIndex,
vlessVersion = new Uint8Array([0, 0]),
isUDP,
} = processVlessHeader(chunk, userID);
address = addressRemote;
portWithRandomLog = `${portRemote}--${Math.random()} ${isUDP ? 'udp ' : 'tcp '
} `;
if (hasError) {
// controller.error(message);
throw new Error(message); // cf seems has bug, controller.error will not end stream
// webSocket.close(1000, message);
return;
}
// if UDP but port not DNS port, close it
if (isUDP) {
if (portRemote === 53) {
isDns = true;
} else {
// controller.error('UDP proxy only enable for DNS which is port 53');
throw new Error('UDP proxy only enable for DNS which is port 53'); // cf seems has bug, controller.error will not end stream
return;
}
}
// ["version", "附加信息长度 N"]
const vlessResponseHeader = new Uint8Array([vlessVersion[0], 0]);
const rawClientData = chunk.slice(rawDataIndex);

// TODO: support udp here when cf runtime has udp support
if (isDns) {
const { write } = await handleUDPOutBound(webSocket, vlessResponseHeader, log);
udpStreamWrite = write;
udpStreamWrite(rawClientData);
return;
}
handleTCPOutBound(remoteSocketWapper, addressRemote, portRemote, rawClientData, webSocket, vlessResponseHeader, log);
},
close() {
log(`readableWebSocketStream is close`);
},
abort(reason) {
log(`readableWebSocketStream is abort`, JSON.stringify(reason));
},
})).catch((err) => {
log('readableWebSocketStream pipeTo error', err);
});

return new Response(null, {
status: 101,
// @ts-ignore
webSocket: client,
});
}

/**
* Handles outbound TCP connections.
*
* @param {any} remoteSocket
* @param {string} addressRemote The remote address to connect to.
* @param {number} portRemote The remote port to connect to.
* @param {Uint8Array} rawClientData The raw client data to write.
* @param {import("@cloudflare/workers-types").WebSocket} webSocket The WebSocket to pass the remote socket to.
* @param {Uint8Array} vlessResponseHeader The VLESS response header.
* @param {function} log The logging function.
* @returns {Promise<void>} The remote socket.
*/
async function handleTCPOutBound(remoteSocket, addressRemote, portRemote, rawClientData, webSocket, vlessResponseHeader, log,) {
async function connectAndWrite(address, port) {
/** @type {import("@cloudflare/workers-types").Socket} */
const tcpSocket = connect({
hostname: address,
port: port,
});
remoteSocket.value = tcpSocket;
log(`connected to ${address}:${port}`);
const writer = tcpSocket.writable.getWriter();
await writer.write(rawClientData); // first write, nomal is tls client hello
writer.releaseLock();
return tcpSocket;
}

// if the cf connect tcp socket have no incoming data, we retry to redirect ip
async function retry() {
const tcpSocket = await connectAndWrite(proxyIP || addressRemote, portRemote)
// no matter retry success or not, close websocket
tcpSocket.closed.catch(error => {
console.log('retry tcpSocket closed error', error);
}).finally(() => {
safeCloseWebSocket(webSocket);
})
remoteSocketToWS(tcpSocket, webSocket, vlessResponseHeader, null, log);
}

const tcpSocket = await connectAndWrite(addressRemote, portRemote);

// when remoteSocket is ready, pass to websocket
// remote--> ws
remoteSocketToWS(tcpSocket, webSocket, vlessResponseHeader, retry, log);
}

/**
*
* @param {import("@cloudflare/workers-types").WebSocket} webSocketServer
* @param {string} earlyDataHeader for ws 0rtt
* @param {(info: string)=> void} log for ws 0rtt
*/
function makeReadableWebSocketStream(webSocketServer, earlyDataHeader, log) {
let readableStreamCancel = false;
const stream = new ReadableStream({
start(controller) {
webSocketServer.addEventListener('message', (event) => {
if (readableStreamCancel) {
return;
}
const message = event.data;
controller.enqueue(message);
});

// The event means that the client closed the client -> server stream.
// However, the server -> client stream is still open until you call close() on the server side.
// The WebSocket protocol says that a separate close message must be sent in each direction to fully close the socket.
webSocketServer.addEventListener('close', () => {
// client send close, need close server
// if stream is cancel, skip controller.close
safeCloseWebSocket(webSocketServer);
if (readableStreamCancel) {
return;
}
controller.close();
}
);
webSocketServer.addEventListener('error', (err) => {
log('webSocketServer has error');
controller.error(err);
}
);
// for ws 0rtt
const { earlyData, error } = base64ToArrayBuffer(earlyDataHeader);
if (error) {
controller.error(error);
} else if (earlyData) {
controller.enqueue(earlyData);
}
},

pull(controller) {
// if ws can stop read if stream is full, we can implement backpressure
// https://streams.spec.whatwg.org/#example-rs-push-backpressure
},
cancel(reason) {
// 1. pipe WritableStream has error, this cancel will called, so ws handle server close into here
// 2. if readableStream is cancel, all controller.close/enqueue need skip,
// 3. but from testing controller.error still work even if readableStream is cancel
if (readableStreamCancel) {
return;
}
log(`ReadableStream was canceled, due to ${reason}`)
readableStreamCancel = true;
safeCloseWebSocket(webSocketServer);
}
});

return stream;

}

// https://xtls.github.io/development/protocols/vless.html
// https://github.com/zizifn/excalidraw-backup/blob/main/v2ray-protocol.excalidraw

/**
*
* @param { ArrayBuffer} vlessBuffer
* @param {string} userID
* @returns
*/
function processVlessHeader(
vlessBuffer,
userID
) {
if (vlessBuffer.byteLength < 24) {
return {
hasError: true,
message: 'invalid data',
};
}
const version = new Uint8Array(vlessBuffer.slice(0, 1));
let isValidUser = false;
let isUDP = false;
if (stringify(new Uint8Array(vlessBuffer.slice(1, 17))) === userID) {
isValidUser = true;
}
if (!isValidUser) {
return {
hasError: true,
message: 'invalid user',
};
}

const optLength = new Uint8Array(vlessBuffer.slice(17, 18))[0];
//skip opt for now

const command = new Uint8Array(
vlessBuffer.slice(18 + optLength, 18 + optLength + 1)
)[0];

// 0x01 TCP
// 0x02 UDP
// 0x03 MUX
if (command === 1) {
} else if (command === 2) {
isUDP = true;
} else {
return {
hasError: true,
message: `command ${command} is not support, command 01-tcp,02-udp,03-mux`,
};
}
const portIndex = 18 + optLength + 1;
const portBuffer = vlessBuffer.slice(portIndex, portIndex + 2);
// port is big-Endian in raw data etc 80 == 0x005d
const portRemote = new DataView(portBuffer).getUint16(0);

let addressIndex = portIndex + 2;
const addressBuffer = new Uint8Array(
vlessBuffer.slice(addressIndex, addressIndex + 1)
);

// 1--> ipv4 addressLength =4
// 2--> domain name addressLength=addressBuffer[1]
// 3--> ipv6 addressLength =16
const addressType = addressBuffer[0];
let addressLength = 0;
let addressValueIndex = addressIndex + 1;
let addressValue = '';
switch (addressType) {
case 1:
addressLength = 4;
addressValue = new Uint8Array(
vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)
).join('.');
break;
case 2:
addressLength = new Uint8Array(
vlessBuffer.slice(addressValueIndex, addressValueIndex + 1)
)[0];
addressValueIndex += 1;
addressValue = new TextDecoder().decode(
vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)
);
break;
case 3:
addressLength = 16;
const dataView = new DataView(
vlessBuffer.slice(addressValueIndex, addressValueIndex + addressLength)
);
// 2001:0db8:85a3:0000:0000:8a2e:0370:7334
const ipv6 = [];
for (let i = 0; i < 8; i++) {
ipv6.push(dataView.getUint16(i * 2).toString(16));
}
addressValue = ipv6.join(':');
// seems no need add [] for ipv6
break;
default:
return {
hasError: true,
message: `invild addressType is ${addressType}`,
};
}
if (!addressValue) {
return {
hasError: true,
message: `addressValue is empty, addressType is ${addressType}`,
};
}

return {
hasError: false,
addressRemote: addressValue,
addressType,
portRemote,
rawDataIndex: addressValueIndex + addressLength,
vlessVersion: version,
isUDP,
};
}


/**
*
* @param {import("@cloudflare/workers-types").Socket} remoteSocket
* @param {import("@cloudflare/workers-types").WebSocket} webSocket
* @param {ArrayBuffer} vlessResponseHeader
* @param {(() => Promise<void>) | null} retry
* @param {*} log
*/
async function remoteSocketToWS(remoteSocket, webSocket, vlessResponseHeader, retry, log) {
// remote--> ws
let remoteChunkCount = 0;
let chunks = [];
/** @type {ArrayBuffer | null} */
let vlessHeader = vlessResponseHeader;
let hasIncomingData = false; // check if remoteSocket has incoming data
await remoteSocket.readable
.pipeTo(
new WritableStream({
start() {
},
/**
*
* @param {Uint8Array} chunk
* @param {*} controller
*/
async write(chunk, controller) {
hasIncomingData = true;
// remoteChunkCount++;
if (webSocket.readyState !== WS_READY_STATE_OPEN) {
controller.error(
'webSocket.readyState is not open, maybe close'
);
}
if (vlessHeader) {
webSocket.send(await new Blob([vlessHeader, chunk]).arrayBuffer());
vlessHeader = null;
} else {
// seems no need rate limit this, CF seems fix this??..
// if (remoteChunkCount > 20000) {
// // cf one package is 4096 byte(4kb), 4096 * 20000 = 80M
// await delay(1);
// }
webSocket.send(chunk);
}
},
close() {
log(`remoteConnection!.readable is close with hasIncomingData is ${hasIncomingData}`);
// safeCloseWebSocket(webSocket); // no need server close websocket frist for some case will casue HTTP ERR_CONTENT_LENGTH_MISMATCH issue, client will send close event anyway.
},
abort(reason) {
console.error(`remoteConnection!.readable abort`, reason);
},
})
)
.catch((error) => {
console.error(
`remoteSocketToWS has exception `,
error.stack || error
);
safeCloseWebSocket(webSocket);
});

// seems is cf connect socket have error,
// 1. Socket.closed will have error
// 2. Socket.readable will be close without any data coming
if (hasIncomingData === false && retry) {
log(`retry`)
retry();
}
}

/**
*
* @param {string} base64Str
* @returns
*/
function base64ToArrayBuffer(base64Str) {
if (!base64Str) {
return { error: null };
}
try {
// go use modified Base64 for URL rfc4648 which js atob not support
base64Str = base64Str.replace(/-/g, '+').replace(/_/g, '/');
const decode = atob(base64Str);
const arryBuffer = Uint8Array.from(decode, (c) => c.charCodeAt(0));
return { earlyData: arryBuffer.buffer, error: null };
} catch (error) {
return { error };
}
}

/**
* This is not real UUID validation
* @param {string} uuid
*/
function isValidUUID(uuid) {
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[4][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
return uuidRegex.test(uuid);
}

const WS_READY_STATE_OPEN = 1;
const WS_READY_STATE_CLOSING = 2;
/**
* Normally, WebSocket will not has exceptions when close.
* @param {import("@cloudflare/workers-types").WebSocket} socket
*/
function safeCloseWebSocket(socket) {
try {
if (socket.readyState === WS_READY_STATE_OPEN || socket.readyState === WS_READY_STATE_CLOSING) {
socket.close();
}
} catch (error) {
console.error('safeCloseWebSocket error', error);
}
}

const byteToHex = [];
for (let i = 0; i < 256; ++i) {
byteToHex.push((i + 256).toString(16).slice(1));
}
function unsafeStringify(arr, offset = 0) {
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
}
function stringify(arr, offset = 0) {
const uuid = unsafeStringify(arr, offset);
if (!isValidUUID(uuid)) {
throw TypeError("Stringified UUID is invalid");
}
return uuid;
}


/**
*
* @param {import("@cloudflare/workers-types").WebSocket} webSocket
* @param {ArrayBuffer} vlessResponseHeader
* @param {(string)=> void} log
*/
async function handleUDPOutBound(webSocket, vlessResponseHeader, log) {

let isVlessHeaderSent = false;
const transformStream = new TransformStream({
start(controller) {

},
transform(chunk, controller) {
// udp message 2 byte is the the length of udp data
// TODO: this should have bug, beacsue maybe udp chunk can be in two websocket message
for (let index = 0; index < chunk.byteLength;) {
const lengthBuffer = chunk.slice(index, index + 2);
const udpPakcetLength = new DataView(lengthBuffer).getUint16(0);
const udpData = new Uint8Array(
chunk.slice(index + 2, index + 2 + udpPakcetLength)
);
index = index + 2 + udpPakcetLength;
controller.enqueue(udpData);
}
},
flush(controller) {
}
});

// only handle dns udp for now
transformStream.readable.pipeTo(new WritableStream({
async write(chunk) {
const resp = await fetch('https://1.1.1.1/dns-query',
{
method: 'POST',
headers: {
'content-type': 'application/dns-message',
},
body: chunk,
})
const dnsQueryResult = await resp.arrayBuffer();
const udpSize = dnsQueryResult.byteLength;
// console.log([...new Uint8Array(dnsQueryResult)].map((x) => x.toString(16)));
const udpSizeBuffer = new Uint8Array([(udpSize >> 8) & 0xff, udpSize & 0xff]);
if (webSocket.readyState === WS_READY_STATE_OPEN) {
log(`doh success and dns message length is ${udpSize}`);
if (isVlessHeaderSent) {
webSocket.send(await new Blob([udpSizeBuffer, dnsQueryResult]).arrayBuffer());
} else {
webSocket.send(await new Blob([vlessResponseHeader, udpSizeBuffer, dnsQueryResult]).arrayBuffer());
isVlessHeaderSent = true;
}
}
}
})).catch((error) => {
log('dns udp has error' + error)
});

const writer = transformStream.writable.getWriter();

return {
/**
*
* @param {Uint8Array} chunk
*/
write(chunk) {
writer.write(chunk);
}
};
}

/**
*
* @param {string} userID
* @param {string | null} hostName
* @returns {string}
*/
function getVLESSConfig(userID, hostName) {
const vlessMain = `vless://${userID}\u0040${hostName}:443?encryption=none&security=tls&sni=${hostName}&fp=randomized&type=ws&host=${hostName}&path=%2F%3Fed%3D2048#${hostName}`
return `
################################################################
v2ray
---------------------------------------------------------------
${vlessMain}
---------------------------------------------------------------
################################################################
clash-meta
---------------------------------------------------------------
- type: vless
name: ${hostName}
server: ${hostName}
port: 443
uuid: ${userID}
network: ws
tls: true
udp: false
sni: ${hostName}
client-fingerprint: chrome
ws-opts:
path: "/?ed=2048"
headers:
host: ${hostName}
---------------------------------------------------------------
################################################################
`;
}

来源

用 V2rayN 生成一个UUID。
在设置-变量-环境变量中设置UUID。
关于 proxyIPs ,是用于转发CF的一些流量,所以,若是存在套了CF的一些网站无法打开,请更换其中的其他网址,也就是第九行中的部分网址!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
白嫖哥维护
workers.cloudflare.cyou

Mingyu维护
my-telegram-is-herocore.onecf.eu.org
sg.ipdb.rr.nu
nl.ipdb.rr.nu
hk.ipdb.rr.nu
jp.ipdb.rr.nu
us.ipdb.rr.nu

小一维护
hk.cf.zhetengsha.eu.org
sg.cf.zhetengsha.eu.org
us.cf.zhetengsha.eu.org
jp.cf.zhetengsha.eu.org

设置自定义域

找到设置 – 触发器,添加自定义域

IP 优选工具使用

若是速度不理想,可以自行优选 CF IP ,来进行提速!CF 优选 IP Windows 工具:点击下载

运行 IP 优选的时候,请关闭代理,这样会更准确!记得不要使用 TLS 优选!

原文地址

安装hysteria

1
bash <(curl -fsSL https://get.hy2.sh/)

服务器端配置/etc/hysteria/config.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
listen: :<服务器端口号>
tls:
cert: <公钥地址>
key: <私钥地址>

auth:
type: password
password: <密码>

masquerade:
type: file
file:
dir: <伪装网站文件地址>

客户端配置config.yaml

1
2
3
4
5
6
7
8
9
server: waol.tk:<服务器端口>

auth: <密码>

socks5:
listen: 127.0.0.1:<本地端口>

http:
listen: 127.0.0.1:<本地端口2>

systemd启动hysteria

1
systemctl start hysteria-server

一、本文适合解决的问题

若你试图通过硬盘、光盘或U盘,进行Win10本地升级安装,并且希望更改版本时保留原有软件和个人文件。但安装程序可能会提示无法选择“保留个人文件和应用”。

推测造成该问题的其中一个原因是当前硬盘上已经安装的Win10版本与打算安装的版本属于不同的分支,Win10安装程序认为无法进行覆盖安装,因此无法保留文件和应用程序。经过尝试,本人修改了注册表中系统版本的键值,“欺骗”升级程序,达到完全保留“个人文件和应用”的目的。

二、详细操作步骤

升级前版本:神州网信政企版,即Win10 Enterprise G,代号1809。

期望升级到:Win10 Enterprise LTSC(长期支持版),代号21H1。

需要修改当前操作系统的注册表键值,稳妥起见,我把Win10大版本升级的历史键值也改了,分别位于

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion

HKEY_LOCAL_MACHINE\SYSTEM\Step\Source OS(xxx)(你更新了几次大版本,就会有几个,也可能一个也没有。)

其实我也不知道哪些是真正需要改的键值,反正我改了这几项。务必注意,如果你不是升级到企业LTSC版,请绝对不要按下表第三列修改,应该改成你想要升级那个版本的英文代号。如果你不知道需要的代号,最好是去已经安装了该版本的电脑看一下注册表,对照修改。

键名 更改前 更改后
BuildBranch rs5_release vb_release
BuildLab xxx.rs5_release.xxx xxx.vb_release.xxx
CompositionEditionID EnterpriseG EnterpriseS
EditionID EnterpriseG EnterpriseS
ProductName Windows 10 Enterprise G Windows 10 Enterprise
upgrade

更改后应该不需要重启,就可以从虚拟光驱运行Win10 Setup安装程序。如果你看到可选“保留个人文件和应用”就大功告成了。经本人实测,升级更换版本后,原来安装的所有程序都可以正常运行。

如果还不行,则还需要探索其它原因。另外,升级后可能造成激活密钥不可用等小问题,请自行解决😂😂😂

按橙白、橙、绿白、蓝、蓝白、绿、棕白、棕接水晶头。
按网线插座的B种颜色接插座

0%