辛丑年

2021 辛丑年《地母经》卜曰:

辛丑牛为首,高低甚可怜。

人民留一半,快活好桑田。

最近看到不少视频、文章都提到这句,解释得十分悲观,“高低甚可怜”是说“底层百姓和高层都各自愁苦”。单搜“人民留一半”,也可以找到不少来自 HK 的言论,把这句理解为:“要发生灾难,死一半人”。

稣表示这个锅《地母经》不背。总所周知,稣来自未来,2021 年怎么样稣最清楚不过了,怎么可能相信这么无稽的说法?所以稣不得不出来开开玩笑,啊不,是澄清事实。稣精通撕书捂精,这小小的卜卦明显难不倒。

它的原始含义是:牛劳苦功高,不管长得高还是矮都很可怜,就算再饥荒人们也不能吃光它,要留一半的牛,好用来干农活。

中国人是不怎么吃牛的,大部分牛是用来生产的,怎么舍得吃?即使是今天,还有不少人存在因为信仰不能吃牛的忌口。

放到如今,意思是:2021 年以牛为主,走高走低都令人喜欢。人民把赚的钱留一半,就可以很快活。

这提示的,其实是资产要留一半,不要都扔到美股去,以防破产。炒股赚钱等要留一半,以防股灾来袭。

《辛丑条约》是中国近代史上赔款数目最庞大、主权丧失最严重、精神屈辱最深沉,从而给中国人民带来空前灾难的不平等条约。

两甲子过去了,中国已经很强大。稣的偶像鲁迅说过“俯首甘为孺子牛”,老老实实搞生产,别玩金融治国,像老外那样把牛都吃了,是吃枣药丸的。

八哥之神前传【16】

外传

鹿邑:稣怎么停笔三个多月?

稣:因为“不敢为天下先”!《八哥之神前传【14】》其实已经谈到代孕,这个话题敏感。就等这些明星出事,再继续写……赫赫。

PS:前面有几篇因为复制粘贴错误,有一部分“2042 年”被写错成“2049 年”,已经更正。

2042 年,齐凤卿梦境

齐凤卿:仙山公?小开?

圣仙山:你误会了,吾与小开确实是两个人。

齐凤卿:不可能吧?您是八哥,小开也经常自称八哥,难道都是鲸神魂裂?

圣仙山:吾为八哥,只是排行,而小开是八哥之神。

齐凤卿:这……请分享您刚编好的故事!

圣仙山:上古时期,天灾战乱频繁,故世人崇尚鬼神、迷信巫术。八哥之神高阳玄稣降临人间,他从小明识鬼神,洞悉人心,人称绝世天才。当他成年后,普天之下,但凡日月所照,风雨所至,无不从服。因为他乃轩辕黄帝之孙……

齐凤卿:难道……您说的,就是那位绝地天通的稣?

圣仙山:然也!而吾乃稣之侄——俊。

齐凤卿:太扯了吧!小开还当过您叔叔!

圣仙山:千真万确!吾叔的思想在当时十分先进,他崇尚科学和一夫一妻制,主张破除迷信、限制权力,包括自己的权力。他说只有控制权力,才能减轻人间疾苦,世界才会趋向美好。

齐凤卿:呃……所以他后来没有把帝位传给自己的儿子,而是传给您?

圣仙山:吾不是没劝过呢!他领养了好多奇奇怪怪的孩子,却只娶一人。吾时常劝他多娶妃,但他坚持不肯。

高阳玄稣:宇宙中最神气的事情就是,稣有天纵神权,却不使用,静静地看凡人装神弄鬼。

齐凤卿:看来您没继承他的理念。

圣仙山:任何权力都有堕落的可能,权力是应该加以限制。这点精华是继承了。一夫一妻制就……赫赫。吾有一世,因为娶两室,招人嫉妒而被害死。

齐凤卿:所以稣才是正确的?

圣仙山:吾曾多次使用特权神力干预视界运行,也多次遭受天谴。但吾认为只要不做坏事,自己开心就好,不用在意一辈子能活多久。

2042 年,圣小开家

古思:为什么爷这么久都不碰我?

圣小开:告诉你实话,你可能会怀疑人生!

古思:不会的。田心的人生就是陪爷,这有啥好怀疑的?

圣小开:你倒是很认命。爷给你讲个故事吧。

古思:又只讲故事,不办事?

圣小开:别急!这个故事可能和你的身世有关。

古思:可能而已?

圣小开:爷怀疑整个世界都是假象,而你,是贾总派来阻止爷觉醒的人。

古思:emm……别胡思乱想。您还是讲故事吧!

圣小开:在遥远的地球上,它的纪元 2002-2003 年间,曾经爆发过一场严重急性呼吸综合征。当时稣在读书,好巧不巧在 2003 年初正好感冒发烧。由于在敏感时期,但身边并没有病例,稣只能请假在家隔离。在和感冒病毒斗争过程中,稣不断担心会不会真是悄悄地被感染冠状病毒?因为稣一直很容易遇到概率小的事件,悲观让病情迟迟不好。当时还在读新闻系的陈因提因此大量补充起各种相关的医学知识。

古思:陈因提就是陈博士吗?难怪她现在是生物医学专家。

圣小开:是的,后来她改读生物医学了。

古思:这个故事好像和田心没啥关系呀?

圣小开:她是不孕主义者,从我们在一起,她就说以后可以出国代孕。大约在 2018 年,代孕已经很盛行,稣很认真地思考过这个做法。听说当时东南亚、乌克兰一些国家,30 万软妹币就可以搞定。稣尝试问一个女朋友,给她 70 万,愿不愿意帮稣生孩子。

古思:这么直接问?结果呢?

圣小开:一谈钱就来火,绝交了……

古思:可能她想让爷明媒正娶吧!

圣小开:后来无意间认识另一个女生,长得和砂砂有七分相似,爷想似乎是上天魔幻的安排?再次考虑代孕的可能性。这次因为前次经验有所顾忌,没一开始就谈钱,打算多了解情况再问。

古思:又出 bug 了?

圣小开:当然。代孕在社会主义国家并不合法,身边的人民群众大多数并不赞同,甚至不理解。连当时比较有钱的朋友都不理解,纷纷临阵倒戈。​有的比较先进的基友,则要给稣介绍外国渠道。

古思:所以爷放弃了吧?

圣小开:确切地说,不是主动放弃的,而是天意阻止。爷从小就有一种八哥体质,不应该做的事情,总会有各种神奇的八哥来阻止,以至于爷经常领悟天意,而调整自己的计划。

古思:嗯?

圣小开:这一年底,新型冠状病毒爆发了。爷曾经希望,不要堵车堵人,排队时不要挤、不要有人插队,最好能在家上班,只要假期、不要过节。病毒爆发后,这些全部实现了。

古思:爷开心就好。

圣小开:并不开心!爷的想法很多是反人性的,自己追求的是平静,确实实现了,但大部分人都陷入苦难之中,以致“先天下之忧而忧,后天下之乐而乐”的爷,认识到,脱离当下的先进,并不一定是美好的,人间应该有它自己主流的发展速度。

古思:爷想说的是不是,代孕在那个时代还不是时候?我查到 2021 年,有明星因为代孕出八哥,想抛弃孩子,导致事业凉了。这简直毫无人性。

圣小开:没错!红灯区、代孕、取消死刑、安乐死,这些事情都和伦理有关,有很大争议,还需要科学地解决。

古思:是因为以前人口太多吗?

圣小开:不知道。但人口少要统一思想确实容易得多。比如现在的共产主义社会,放在以前 70 亿人口的世界,哪能如此轻松?

古思:这么说来,当今的人们,确实太幸福了!

圣小开:不一定呢!如今的社会,人人讲诚信,你有疑问,很容易得到一个诚实的解答。但大部分人其实已经憋不出啥疑问了。比如你,发现自己是个奴隶了吗?

古思:奴隶?

圣小开:是的。别人不会对你撒谎,却也不会告诉你全部真相,除非你自己提出疑问。

古思:我就是一个代孕工具人?

圣小开:你确实被设计得很聪明。没猜错的话,贾总想除掉爷,但因为某些爷还没弄明白的原因,又想要保留爷的基因为他所用,或者他只是想消耗爷的精力,所以派你来给爷生孩子。

古思:但我觉得这对田心没什么坏处呀!

圣小开:哦……人各有志。你愿意就好。

古思:不然爷带田心远走高飞,天下之大,岂无我洗白身份之所?

圣小开:对不起!普天之下莫非王土。统治者,并非仅有贾总一人。

古思:算了,我就头脑风暴一下,现在这样就挺好。

圣小开:那你好好学习,爷去找师兄了。

诗盗·长向司

《#诗盗#·长向司》

一仙山,两仙山。山远天高烟水闲,相思狗不沾。
菊花灿,菊花残。路长日暮风林晚,打工人未还。

注解

改编自李煜的《长相思·一重山》:

一重山,两重山。山远天高烟水寒,相思枫叶丹。
菊花开,菊花残。塞雁高飞人未还,一帘风月闲。

八哥人生之 M1

这个八哥大到差点一命呜呼。

为什么买 M1?

很多年没用 PC 办公,所以 2020 年 8 月 31 日收到公司从北京寄过来的 HP OMEN 25L 台式机时,十分开心地进行各种性能测试。结果有对比就有伤害,之前使用几个月的联想 L490 笔记本顿时成为乐射。比如编译 boost 1.74.0,OMEN 25L 速度是 L490 的三倍以上。从此每次用 L490 编译工程,都能感觉生命在流逝,没几天后就受不了,把开发资料都迁移到 OMEN 25L。

然而,出差的时候,又开始觉得感觉生命在流逝……甚至有时候为了测试方便,背着两台笔记本去出差,简直是练武之人。

2020 年 10 月 11 日入手华硕灵耀 X 纵横,11 代 i7,3:2 比例的 3.3K 屏幕,配置全面超越 L490,然而刚买来时,可能还有 bug,经常风扇狂转,设置成安静模式都没用,固件和 Windows 系统都升级过才好转。

M1 是 2020 年 11 月 24 日到手的。理由很多:稣想要一台安静的笔记本;ARM64 架构的机器,必须搞一台;它可以装 iOS App。但最大的理由是:富婆给买的!

M1 的风扇从来没转过,真香!

灵异频发的 M1

用几天后,开始发现 bug:触控 ID 解锁频繁失灵。

  • 在书房,插显示器的 Type-C 线,频繁失灵。

  • 在书房,用华硕的 Type-C 电源适配器,频繁失灵。

  • 在卧室、客厅,用 Apple 的 Type-C 电源适配器,正常。

  • 就在以为 Apple 的 Type-C 电源适配器良心,其它都是乐射时……把它拿到书房,还是失灵了。

  • 不插电,在大部分地方,包括书房的两张小桌子都是正常的。

  • 不插电,放在书房的主工作桌上也频繁失灵,拿起来正常,放下又失灵,即使垫着绝缘体,只要放着就失灵!

  • 在电箱把照明开关关闭,全部正常。

  • 在电箱把照明开关再打开,全部正常,过一段时间后又在前面测试会失灵的地方再度失灵。

八哥之灯

开始怀疑家里的灯有 bug,而灯如果坏了,一般就不亮,bug 只能在整流器。于是开始检查灯对 M1 触控 ID 的影响。经过测试,照明开关重启后,只要次卧的灯不开,就不会出 bug!

但是测试过程中,发现一个可怕的事实,家里有两个插座用的是照明线路的电,而且没接地线!假设稣打算修理这两个插座,就去电箱把“普通插座”开关关掉,然后开着灯好办事,结果这插座用的是照明线路,并没有断电,如果稣不够谨慎,可能直接就被电死!

再来发现有两个灯,即使关掉了,还有 67V 的交流电!就是关灯,它是不亮,但有 67V,开灯,亮起来,有 231V……经过分析,这两个灯都是双控开关,两个开关之间有 3 条电线,他们在中间可能漏电了,导致三条都有电。立刻对线路改造。

可怕的事情又发生了:在改造电路时,富婆让稣去拿快递,出门前暂时把照明开关送上去,回来居然忘记再关掉,直接用手去碰电线,整条手臂麻了 10 几分钟……要不是穿着绝缘鞋,这个 220V 应该可以把稣烤熟。

换灯

线路改造后,又把次卧的灯罩拆开,好大一个整流器,书房的也拆开,还是好大一个整流器,而且居然还是荧光灯!用 iPhone 相机的慢动作检查各个灯,果然只有这两个灯会闪!内牛满面,果断换掉。今天(2021 年 1 月 5 日)新买的 18W LED 灯的整流器就一小块,不闪,换上之后 bug 消除。

书房的荧光灯是 65W 的,亮度和 18W 的 LED 差不多。稣想起小时候那肉眼可见闪烁的电条(闽南语,日光灯)……生活在新时代的人,真是幸福。

诗盗·山坡羊·打倒资本主义建设社会主义道路

《#诗盗#·山坡羊·打倒资本主义建设社会主义道路》:内牛如柱,剥削如故,飞天茅台羊毛路。望西毒,一仇除。伤心好汉成社畜,拨款万亿补贴了土。兴,百姓苦;衰,百姓苦。

注解

望西毒,一仇除:西方资本主义毒害了我们一部分人民,但马克思主义会解放世界人民。

拨款万亿补贴了土:拨款造福人民,却因为还没解放资本家,最终只助长房价。

兴,百姓苦;衰,百姓苦:资本主义的兴衰都会伴随着“百姓苦”的阵痛,现在是管控资本主义的时刻。从题目可以看出,作者认为坚持下去社会主义一定会胜利。

Mac 外接显示器时无法调节音量?

问题

用一根 Type-C 连笔记本和显示器,然后显示器插了一对音响。

  1. 当笔记本是 Windows 笔记本时,可以调节外部音响的音量。
  2. 当笔记本是 MBP13 M1 时,无法调节外部音响的音量。
  3. 对比另一台 MBP 接 UltraFine 显示器时,却又可以调……怀疑是贵的才可以,便宜的阉割了【开玩笑的】。

M1 + AOC 便宜的显示器不行

M1 + AOC 便宜的显示器无法调音量

Intel + UltraFine 可以

Intel + 贵的 UltraFine 可以调音量

原理

这是因为 HDMI、DisplayPort 和 Thunderbolt 等接口传输的都是带有固定音量的数字音频信号,而能调节音量的音频信号属于模拟信号,因此只有外接显示器将数字信号转换为模拟信号后才能调节音量。UltraFine 可以调节,推测是因为它和 macOS 之间有魔法协议,直接调节硬件的音量,就好比直接去旋转音响上的音量旋钮。

解决

参考:少数派:Mac 外接显示器时无法用键盘调节音量?这个方法能够帮助到你 | 一日一技

然而……M1 是 Arm64e 的 CPU,而此软件的核心是个内核扩展模块,Release 出来的只有 x64 的 Mach-O 程序。

Soundflower 安装失败

赫赫,尴尬地笑出声!好在 Soundflower 是开源的,要自己编译个对应架构的版本……然后:

在搭载 Apple 芯片的 Mac 上,您可能首先需要使用“启动安全性实用工具”将安全策略设置为“降低安全性”,并选择“允许用户管理来自被认可开发者的内核扩展”复选框。

这么麻烦,果断放弃。再找找,发现这个可以直接用:https://github.com/MonitorControl/MonitorControl

云游戏即将起飞,这些技术您了解吗?

00 前言

2019 年以前,基于当时的基础情况判断,大部分人不看好云游戏的产品形态。但是云游戏用的技术其实是很有含量,很值得研究的。不少云游戏开发者,能够冒着产品不被看好的风险硬啃这块,有很大原因是,其技术本身很有价值,很有挑战性。俗话说,高风险高回报,难道云游戏行业工资高这个秘密,我也要告诉您?

2020 年上半年,由于疫情影响,实体娱乐业受到很大冲击,反而计算机游戏因此得利,不少上市游戏公司迎来一波股价上升行情。同时由于大头公司积极布局云游戏,大众开始对云游戏产品有所改观。到下半年,GPU、5G、边缘计算等领域的各种迹象已经表明云游戏起飞的时机大约就在 2021-2022 年。如果说之前,云游戏开发者是靠稀缺和承担高风险拿到高薪,那么今后两年,靠的就是趋势已来,赌对了!

01 演示视频

国内首款开源云游戏引擎【鎏光】演示街头霸王对战 - 知乎

国内首款开源云游戏引擎【鎏光】演示街头霸王对战 - 西瓜视频

02 开源

相信大部分开发者接到一个任务时,第一想法就是先找找有没有符合需求的现成的开源项目,如果有很多个,就做选型。即使没有完全符合要求的,接下来做开发,也可能是在拿一些开源的基础库做组合。

很多时候,一个行业发达时,就必然会有很多相关开源项目。有些只是提供基础库,有些是产品级别的完整项目。

今天咱们要介绍的,是一个准产品级别的完整项目——鎏光云游戏引擎。它大量依赖一些协议兼容的优秀基础开源库,不管是本身,还是其依赖,都是很值得参考的。

https://github.com/ksyun-kenc/liuguang

当您 clone 好代码,把它们编译出一套可玩的“云游戏”成品后,可能会大呼过瘾,有种用零件造出变形金刚的快感,甚至很想参与完善它。我们很高兴地宣布,它的开源协议是 Apache 2.0,您可以尽情改造它。

03 技术介绍

项目的 ReadMe 上已有相关说明,大家可以先大概看一下,再继续阅读。

从最简化的模型上看,云游戏做的两件事是:把服务端的游戏画面“搬运”到客户端、把客户端的输入“搬运”到服务端。下面将按顺序介绍这两件事背后的细节。

Easyhook

要“搬运”游戏画面,首先就得想办法抓取画面。大部分人会想起 QQ、飞书之类常用软件带的截图功能。这当然也可以,但考虑到“效率”,咱们不得不对各种截图技术做一些评估。GDI 抓图、NVIDIA FBC、MirrorDriver、DDA(Desktop Duplication API)、IDD(Indirect Display Driver),这么多手段都可以抓图,但我们用的却是 Hook 抓图。举个例子,D3D 游戏本来调用一个叫 Present 的函数,告诉底层,我的数据准备好了,你可以拿去显示。云游戏引擎就 Hook 这个 Present 函数,抢先把游戏数据取走。

Hook 方案有三个好处:

最接近画面源头,延迟最小;
只抓游戏画面,不受遮挡影响。
黑科技:Hook 技术能控制游戏的垂直同步开关,使游戏按照特定规范运行,减少运营时的差异。可以还阻止游戏在本地显示,即在图中的渲染完成后,取得图像,之后的流程都抹掉,可以节省 GPU 资源,这是其它技术做不到的。

我们选择的 Hook 库是 Easyhook,它是 MIT 协议:

EasyHook - The reinvention of Windows API Hooking

FFmpeg

接下来把画面流化属于流媒体范畴,不得不先提到大名鼎鼎的 FFmpeg。由于它属于 GPL/LGPL 协议,所以我们的代码内并没有放任何 FFmpeg 的文件,这需要开发者自己去放置。

目前鎏光支持 H264 和 HEVC 两类编码,当采用 2020 年主流消费级 NVIDIA GPU 时,我们建议采用 HEVC 编码。如果您的 GPU 是其它品牌,还请自行修改代码,理论上只要是 FFmpeg 支持的硬件编码器,工作量几乎就是改个编码器的名字,也欢迎您调试好之后贡献代码。

IAudioCaptureClient

这是 Windows 上的一个 COM 接口,用于抓声音。我们会采用 opus 或 aac 来编码声音,所以采集声音后会统一做个 resample,使数据符合编码器的要求。

另外,鎏光的 Pro 版本还有针对单个进程抓声音的方案,采用 Hook IAudioRenderClient 的方式实现。参考:云录音

WebSocket

画面和声音流化之后得到一个个 AVPacket 数据块,当然还得把它们通过网络传输到客户端。这部分我们采用 WebSocket 协议,实现用的是 Boost.Beast。采用 Boost 的好处是,如果您想换成裸 TCP 传输,可以把 Boost.Beast 换成 Boost.Asio,改动很小。还有一个类似 Boost.Asio 的 kcp 库,是 GLP 协议的,所以我们没采用,但我们建议在互联网传输时使用 kcp,如果您想自己换,也是很方便的。

SDL

客户端通过 WebScoket 拿到 AVPacket,同样采用 FFmpeg 解码得到 AVFrame,再从中拿到原始画面和声音,接下来该呈现给玩家了!我们采用 SDL 呈现画面和声音,它有跨平台的好处。

值得一提的是,视频解码这步,我们是支持硬件解码的,并且我们通过对 SDL 实现的 hack,能够把硬解出来的视频帧直接丢给 SDL 去显示。

玩家的操作,比如键盘、鼠标、手柄等外设的消息收集,也是通过 SDL 实现。

UDP

SDL 采集的外设的消息封装后,通过裸 UDP 发送给服务端。采用 UDP 是为了保证实时性,并且丢包的代价不高,用户可以多按几次键盘鼠标就纠正丢包带来的问题。实现采用 Boost.Asio,和前面提过的一样,您可以很方便地自行把裸 UDP 改为 kcp。

外设消息重放

外设消息达到服务端后,还得将其发送给游戏。我们有两种做法,一种是通过 HID 驱动重放,一种是 Hook 游戏的外设 API,把客户端发来的消息返回给游戏。

HID 驱动方案需要 WDK 开发,开发和部署的成本较大,但兼容性比较好,可以支持大部分游戏。Hook 方案的本质是:游戏用什么 API 读写外设消息,我们就 Hook 什么 API!它的好处是延迟低,然而游戏用的 API 还是蛮多可能的,DInput?RawInput?XInput?所以需要做多套 Hook。

04 探讨

您可能注意到前面 Hook 这个词出现挺多次。这其实是云游戏的重点和难点。如果采用云桌面思路来实现云游戏,其实可以不需要 Hook,而且一个桌面能干的事情更多,应用场景也会更多。按照这个路线发展的话,驱动会是重点和难点。

但同时我们还应该注意到“原生云游戏”路线。原生云游戏不会采用任何驱动,甚至它的服务端不需要运行在 Windows 上。从原生云游戏 SDK 的角度看,它整个思路、流程和 Hook 方案的云游戏更像一些。

您对哪者更感兴趣呢?欢迎在这里留言告诉我们。

诗盗·羊顺游记

《#诗盗#·羊顺游记》:羊顺之水流潺潺,古来隐者似神仙。放眼山下百千株,没贵,再存房钱两三年。

注解

羊顺游记。改编自霹雳角色“玉枢丹桂月无缺”诗号:

玉川之水流潺潺,古来饮者似神仙。放眼天下百千事,无缺,再听徽外两三弦。