最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

第二代紅警看戲神器是如何實(shí)現(xiàn)的

2023-03-21 23:15 作者:渣渣就是玩兒  | 我要投稿

各位肉人大家好,我是“紅警看戲神器”的作者“渣渣就是玩兒”。

第一代看戲神器在2022年8月推出,作為試水產(chǎn)品,反響不錯(cuò),但有明顯問(wèn)題。本次全新重制,使用方法、技術(shù)原理均不同。

實(shí)現(xiàn)放大器的兩條路線是實(shí)時(shí)方案和后期方案。具體參考

第一代采用了后期方案,需要先錄制視頻,再將視頻傳入軟件,得到放大后的視頻。它開(kāi)發(fā)相對(duì)簡(jiǎn)單,但操作麻煩、耗時(shí),不能用于直播。

第二代采用實(shí)時(shí)方案,在游戲過(guò)程中實(shí)時(shí)放大聊天消息,錄制的素材自然也是放大的,且能用于直播。該方案效果最好,但開(kāi)發(fā)最難,因?yàn)橐紤]到和紅警客戶端的“嫁接”,用今天的代碼和20多年前的游戲?qū)υ?。相比之下,后期方案只要做視頻處理,改進(jìn)到頭也就加個(gè)OCR,都是通用技術(shù)。

本次的看戲神器,整體思路是做一個(gè)抓包程序,一旦發(fā)現(xiàn)紅警聊天數(shù)據(jù)包傳輸,就使用一個(gè)懸浮的透明窗口,同步繪制出其中的文字。

邏輯不難,大坑不少。三個(gè)難題分別是繪制、攔截、解密。

繪制

首先,要證明,自定義的內(nèi)容可以疊加在紅警的游戲畫(huà)面之上。桌面歌詞能懸浮在各種窗口上,但紅警中看不到,這代表游戲畫(huà)面優(yōu)先級(jí)非常高,幾乎沒(méi)有其他視覺(jué)元素能浮在紅警的上方。打游戲就應(yīng)該把其他窗口后置,當(dāng)然沒(méi)問(wèn)題。但這個(gè)習(xí)以為常的現(xiàn)象,給開(kāi)發(fā)帶來(lái)了難題。

我首先想到的是虛擬準(zhǔn)星。很多硬核FPS游戲沒(méi)有準(zhǔn)星,但GitHub上有很多準(zhǔn)星應(yīng)用,專門負(fù)責(zé)在屏幕中央畫(huà)一個(gè)準(zhǔn)星,可以自定義顏色、大小,可以懸浮在游戲畫(huà)面之上。稍加改造一下準(zhǔn)星的代碼,把繪制準(zhǔn)星改為繪制文字,不就解決了嗎?

GitHub上的各種準(zhǔn)星應(yīng)用

如果將紅警窗口化呢?理論上可以,但非常影響游戲體驗(yàn)。鼠標(biāo)移動(dòng)到屏幕邊緣時(shí),會(huì)掉到游戲外面。任務(wù)欄也會(huì)影響視野,就算自動(dòng)隱藏任務(wù)欄,鼠標(biāo)移動(dòng)到屏幕下方,也會(huì)把任務(wù)欄召喚出來(lái)。每次鼠標(biāo)掉出去,會(huì)導(dǎo)致游戲短暫失控,肯定不能忍。

那么,Windows系統(tǒng)里有什么能凌駕在紅警之上呢?我發(fā)現(xiàn)了4個(gè),音量調(diào)節(jié)數(shù)值條、大小寫(xiě)切換的提示圖標(biāo)、Xbox懸浮界面、顯卡彈出的提示。至于顯示器下方那一排物理按鈕觸發(fā)的彈窗,不屬于操作系統(tǒng),無(wú)法開(kāi)發(fā),不做討論。

Xbox能覆蓋在游戲畫(huà)面上方

我也試了OpenGL、GDI+,但它們也運(yùn)行在窗口實(shí)例中,并不能直接在屏幕上繪制像素點(diǎn)。所有窗口都不能懸浮,能懸浮的元素又不開(kāi)放接口。這個(gè)問(wèn)題不突破,實(shí)時(shí)方案永遠(yuǎn)無(wú)法實(shí)現(xiàn)。于是我就鴿了。

直到3月初,我又想起來(lái)這回事,查資料看看有沒(méi)有新的解決方案。發(fā)現(xiàn)紅警渲染器cnc-ddraw在2023年1月17號(hào)發(fā)布了5.0,這不正是對(duì)戰(zhàn)平臺(tái)的默認(rèn)渲染器嗎?放到巖漿里熱熱還能吃!

我用新版渲染器覆蓋了對(duì)戰(zhàn)平臺(tái)的紅警客戶端中的渲染器,電腦瞬間閃出萬(wàn)道金光(誤)!稍加配置,紅警的行為就像正常窗口一樣了,甚至網(wǎng)易云都能懸浮在它上面。這樣就妥了,做一個(gè)背景透明的、置頂?shù)摹⒉荒鼙稽c(diǎn)擊的窗口,就可以作為聊天消息的輸出端了!我對(duì)比了幾種文字繪制的效果,OpenGL語(yǔ)句太復(fù)雜,而且有點(diǎn)大材小用;GDI+在透明背景上,開(kāi)了抗鋸齒,文字有白邊,不開(kāi)就有鋸齒,簡(jiǎn)直簡(jiǎn)直了!最終選取了PyQt,文字造型非常之優(yōu)美。

我沒(méi)咋用過(guò)PyQt,所以剩下的工作就交給AI了,我負(fù)責(zé)提需求和拼裝代碼,它寫(xiě)具體業(yè)務(wù)代碼。別看AI聊社會(huì)人文有一些空話套話(當(dāng)時(shí)用的GPT3.5),寫(xiě)代碼是真不含糊,優(yōu)雅命名變量,舉一反三,貼心解釋,媽問(wèn)跪。對(duì)于有想法的路人,寫(xiě)代碼的門檻進(jìn)一步降低,懂點(diǎn)編程,能拆解需求,就能親手實(shí)現(xiàn)一個(gè)創(chuàng)意了。對(duì)程序員,能通過(guò)和AI對(duì)話,快速學(xué)習(xí)新的語(yǔ)言或開(kāi)發(fā)框架。我很看好此事,畢竟我當(dāng)年也是為了實(shí)現(xiàn)某創(chuàng)意,被迫寫(xiě)代碼的,這又是另一個(gè)故事了。

首次啟動(dòng)看戲神器,全盤搜索包含gamemd.exe的文件夾,將其視為游戲文件夾,注入新版渲染器及其配置,同時(shí)緩存這些路徑。由于使用了os.scandir()方法,廣度優(yōu)先,且限制搜索深度為3層(沒(méi)人會(huì)把紅警安裝在一個(gè)特別深的文件夾里吧,不會(huì)吧不會(huì)吧,又不是學(xué)習(xí)資料),搜索速度很快,幾乎感知不到。每次啟動(dòng)神器的時(shí)候,也會(huì)校驗(yàn)一遍渲染器。

繪制時(shí),讓每條消息停留8.5秒,方可和游戲中同步。游戲速度不影響聊天消息的停留時(shí)間。

攔截

在開(kāi)發(fā)第一代的時(shí)候,已經(jīng)有了相關(guān)積累。我知道聊天流量包的特征:UDP協(xié)議,長(zhǎng)度為483字節(jié)。如果聊天內(nèi)容不滿483,也會(huì)發(fā)來(lái)483的包;如果超過(guò)483,會(huì)在客戶端輸入的時(shí)候自動(dòng)截?cái)唷?/p>

但通過(guò)ip.addr(WireShark的搜索語(yǔ)法)很難判斷,因?yàn)閷?duì)戰(zhàn)平臺(tái)的IP有很多,每次對(duì)戰(zhàn)都會(huì)變。本地IP和端口也因人而異,不排除有直接拿公網(wǎng)IP玩游戲的用戶。

于是只能通過(guò)UDP和483字節(jié)這兩個(gè)線索,制作攔截器。為了減少不必要的監(jiān)聽(tīng),使用父子線程方案。父線程監(jiān)聽(tīng)紅警客戶端進(jìn)程,子線程監(jiān)聽(tīng)網(wǎng)絡(luò)包。看戲神器啟動(dòng)后,先啟動(dòng)父線程,輪詢紅警客戶端進(jìn)程是否啟動(dòng)。若是,啟動(dòng)子線程,監(jiān)聽(tīng)長(zhǎng)度為483的UDP包。一旦父線程發(fā)現(xiàn)紅警客戶端關(guān)閉,子線程結(jié)束監(jiān)聽(tīng)。

可以通過(guò)進(jìn)程名稱,確定游戲客戶端是否已啟動(dòng)。無(wú)論原版還是尤里,進(jìn)程名都叫做gamemd-spawn.exe,都是尤里的紫色圖標(biāo)。實(shí)際上,每次開(kāi)始游戲,都會(huì)創(chuàng)建一個(gè)新的gamemd-spawn.exe,全新安裝的紅警沒(méi)有這個(gè)文件。上文提到的gamemd.exe則是游戲客戶端的本體,全新安裝的紅警也有,且不會(huì)隨著每局游戲發(fā)生變化。

上述攔截邏輯,意味著網(wǎng)絡(luò)請(qǐng)求過(guò)多時(shí),有可能延遲或遺漏,所以神器開(kāi)啟后會(huì)彈窗提醒

雖然我覺(jué)得已經(jīng)沒(méi)人用迅雷了,不過(guò)大家一聽(tīng)名字就知道是下載器,還是寫(xiě)上去吧(doge)

解密

開(kāi)發(fā)第一代的時(shí)候嘗試過(guò),奈何數(shù)據(jù)包都是加密的。大神給了我一段代碼,說(shuō)來(lái)自國(guó)外論壇。我稍加改造,支持了中文解碼(紅警用了UTF-16編碼中文)。解碼之后,我發(fā)現(xiàn)之所以聊天流量包永遠(yuǎn)是483字節(jié),是因?yàn)殚L(zhǎng)度不足的時(shí)候會(huì)填一堆空格。

但是,聊天流量包不含玩家顏色信息,只有玩家序號(hào)和聊天內(nèi)容。該如何繪制出不同顏色的文字呢?大神再次出手,告訴我每局游戲開(kāi)始前,都會(huì)在游戲根目錄創(chuàng)建spawn.ini,其中包含了每個(gè)玩家的序號(hào)、昵稱、顏色枚舉值。

這意味著我們可以建立兩份關(guān)系,序號(hào)和顏色、序號(hào)和聊天信息。這樣一來(lái),拿到顏色和聊天信息的關(guān)系,也不在話下。

枚舉值是純數(shù)字,不能一眼看出這個(gè)玩家是什么顏色。數(shù)字和顏色的對(duì)應(yīng)關(guān)系,應(yīng)該藏在紅警客戶端中。

于是我使用XCC Mixer挨個(gè)翻找客戶端中的mix文件,找到了rules.ini,其中包含多處對(duì)顏色的定義。MP應(yīng)該就是multiplayer,即多人游戲。第3-4行的注釋表明這是HSV而非RGB色值,而且H、S、V的取值都是0-255,這場(chǎng)面我真沒(méi)見(jiàn)過(guò),不知道是不是他們自己發(fā)明的規(guī)范。所以又讓ChatGPT幫我寫(xiě)了一個(gè)顏色轉(zhuǎn)換方法。

游戲內(nèi)部的顏色定義

第31行的注釋表明,這段代碼由一個(gè)叫“PCG”的人寫(xiě)于2000年9月10日,如果TA當(dāng)時(shí)是個(gè)20多歲的程序員,現(xiàn)在已經(jīng)年過(guò)半百。

這里的枚舉值和顏色并不完全對(duì)應(yīng),但色值都是準(zhǔn)的,稍加改造就得到了這樣一份枚舉。

我總結(jié)的顏色定義

每次游戲啟動(dòng),就會(huì)檢測(cè)游戲進(jìn)程文件夾中的spawn.ini,一旦有了有效內(nèi)容(需要等幾秒),就分析出每個(gè)玩家的序號(hào)和顏色的對(duì)應(yīng)關(guān)系,暫存起來(lái)。有聊天消息時(shí),結(jié)合聊天消息中序號(hào)和聊天內(nèi)容的對(duì)應(yīng)關(guān)系,便可繪制出正確顏色的文字。游戲結(jié)束時(shí),銷毀暫存的序號(hào)和顏色的對(duì)應(yīng)關(guān)系,免得下一局顏色串了。

怎么樣,是不是坑不少!2分鐘的視頻,背后是我和@感覺(jué)有點(diǎn)方多少個(gè)三天三夜!如果各位覺(jué)得我們的工作有價(jià)值,請(qǐng)不吝點(diǎn)贊三連!視頻沒(méi)點(diǎn)贊的快回去點(diǎn)!


第二代紅警看戲神器是如何實(shí)現(xiàn)的的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
宝清县| 体育| 普兰店市| 伊通| 仪征市| 和龙市| 东乡县| 蒙城县| 新泰市| 桂平市| 汝州市| 永定县| 六安市| 阿克陶县| 德昌县| 石林| 宝丰县| 孟连| 宁晋县| 汤阴县| 宣威市| 黄浦区| 华宁县| 阳高县| 乐都县| 张家界市| 西青区| 柳林县| 博湖县| 高淳县| 丹巴县| 阿坝| 县级市| 滦平县| 岑溪市| 勃利县| 江山市| 景东| 嫩江县| 沈丘县| 广平县|