在有劃分工作執掌的狀況下,伺服器的工程師負責的是伺服器這一端的相關工作。這些工作包含了程式的撰寫以及伺服器維護的相關工作;而客戶端的程式則是負責玩家用來安裝到個人電腦上的程式。線上遊戲就是由伺服器端和客戶端這兩方面的程式合作,資料經由網路在客戶端和伺服器之間傳送。
![]() |
| 【夢幻之星網路版將存檔資料放在玩家端造成大問題】 |
在我們開發線上遊戲的時候,有一句『不要輕易相信客戶端送來的資料』的警語。這句話並不是說擔任客戶端的工程師不可信任,而是提醒擔任伺服器的工程師,要注意所有從客戶端送來的資料。由於客戶端是安裝在玩家的電腦上,從那裡送來的資料很有可能是被動過手腳修改後的資料,如果不檢查這些資料的可信度,很有可能就會被這些修改過的資料所騙。以下簡單舉個例子來說明:
在某個線上遊戲中,工作系統的材料可以透過不斷的合成變成更上一階的材料,然後玩家使用越高階的材料就可以做出更強的裝備。合成的規則是玩家可以將三~五個同樣的材料放到合成寶盒中,然後遊戲會根據玩家放入合成寶盒的材料數量,決定合成的成功率。三個同樣的材料合成上一階的機率是60%、四個則是80%、五個則是100%。根據這個規則,一階木材可以合成為二階木材,二階木材可以合成為三階木材以此類推。
如果有位玩家要將手中的三個一階木材合成為二階木材,會是以下的流程:
(1)玩家將三個一階木材放入合成寶盒送出﹝資料從客戶端傳往伺服器﹞
(2)伺服器收到資料依合成機率60%決定成功與否﹝伺服器進行運算﹞
(3)將合成是否成功的結果傳回客戶端﹝資料從伺服器傳回客戶端﹞
(4)客戶端收到資料進行處理﹝客戶端進行相關程序﹞
在客戶端接到伺服器傳來合成成功/失敗的結果後,如果合成是成功的,那麼玩家會獲得一個二階木材;如果合成是失敗的,那麼玩家什麼都不會獲得。還記得這篇文章的主題嗎?萬一伺服器收到的資料是被玩家修改過的呢?在以上的流程中並沒有檢查玩家身上是否真的有三個一階木材,萬一玩家身上其實沒有三個一階木材;或是玩家身上只有三個一階木材,結果送過來的資料是五個一階木材進行100%成功的合成。如果發生這樣的狀況那就糟糕了。
所以這個流程應該修改為:
(1)玩家將三個一階木材放入合成寶盒送出﹝資料從客戶端傳往伺服器﹞
(2)伺服器判斷玩家身上是否有三個一階木材並且扣除﹝伺服器判斷及處理﹞
(3)伺服器收到資料依合成機率60%決定成功與否﹝伺服器進行運算﹞
(4)將合成是否成功的結果傳回客戶端﹝資料從伺服器傳回客戶端﹞
(5)客戶端收到資料進行處理﹝客戶端進行相關程序﹞
這個第二步驟的動作,就是檢查玩家身上是否有足夠的物品,然後先將它扣掉。如果各位有看過『製作遊戲的兩三事【37】開寶箱設計常見的大漏洞』這篇文章,就會知道銀狐曾經說過在線上遊戲的程式撰寫時,為了避免不可預期的程式被中斷,所以各種系統中的物品產生和消失要遵守『先扣再給』的這個原則。在這個流程中為了避免複雜化,銀狐將判斷背包空間是否足夠的判斷先省掉,我們就假設玩家的背包是有足夠空間的。
或許有人會懷疑,這麼簡單加個檢查就可以做到的事,為什麼會有遊戲不願意這樣做。一個原因是工程師在撰寫程式時候的疏忽,而另一個原因﹝也是最重要的原因﹞是因為什麼都要伺服器檢查確認會加重伺服器的負擔,同時拖慢遊戲執行時的效率。在這裡指的所有動作包含了線上遊戲中大大小小的各種動作,像是角色移動、攻擊敵人以及各式各樣的動作。光以角色移動這一項來說,在一個遊戲的伺服器中同時會有多少玩家的角色在移動,如果每一個移動都要檢查和判斷,會是多大的負擔?
也因為這樣,有許多的遊戲會將一些會造成伺服器負擔較重的動作交給客戶端來判斷,而這些由客戶端判斷的項目若是被玩家給破解了,就可以做出原本應該做不到的動作。像是某些強調動作性的韓國線上遊戲中,總是會出現『瞬移』的外掛就是因為這樣的原因。而某些遊戲中出現不正常的『穿牆』、或是某些玩家的角色具有超過正常攻擊距離的攻擊,也是因為這些由客戶端來進行判斷的動作被玩家破解的結果。
提到客戶端送來的資料是不可信任的這件事,就不得不提起《夢幻之星網路版》這款遊戲。這款從遊樂器平台移植到電腦的遊戲,犯了一個相當致命的錯誤, 那就是它將玩家的存檔資料放在玩家的電腦中。遊樂器算是半封閉的系統,做出這樣的設計並不奇怪。但是移植到個人電腦上還是將資料放在客戶端,等於是給了想 要修改資料的玩家許多的機會。果然這款遊戲後來出現了許多修改資料的『超強角色』,也讓這個遊戲很快的因為營運上的各種問題而消失在市場上。
效能和安全性是無法兼得的,對於越是強調『動作性』和『打擊感』的線上遊戲來說,如果玩家的每一個動作都要送到伺服器來檢查和判斷,那麼遊戲所想要給玩家的感覺就會變得不是很流暢。當這兩者無法兼得時,遊戲設計者就必須要兩者之間做出取捨,而這個取捨則會引發不同程度的後果。至於各位在製作遊戲時該如何選擇,也只能依每個遊戲的設計來作出最適當的取捨吧。

17 篇回應:
我覺得在某些極端要求回應速度的連線遊戲中,可以設計一套黑白名單系統,當一位玩家選擇相信另一位玩家的時候,就不再對那另一位玩家多作判斷。當然前提是潛在受害者必須是選擇相信的那位玩家。不然有些遊戲只要不順就和不能玩沒什麼兩樣了。
> 我覺得在某些極端要求回應速度的連線遊戲中,
> 可以設計一套黑白名單系統,
> 當一位玩家選擇相信另一位玩家的時候,
> 就不再對那另一位玩家多作判斷。
呃 .... 這整篇文章寫的都是伺服器和客戶端的判斷,
在線上遊戲中就算是玩家和玩家間的攻擊也是伺服器在判斷,
怎麼會有人扯到玩家和玩家間的判斷去了?
閒者你沒看懂這篇文章吧?
如果沒看懂的話, 就不要勉強自己回應了.
這篇文章應該沒講什麼比較複雜的東西吧,不就主客端之間的通信和內部資料處理上的問題...
而且我指的是玩家和玩家間的「信任」提供給伺服器參考
樓上的閒者先生把簡單的事情搞得很複雜,
本來玩家間的互動都是經由伺服器在判斷的,還額外再個白名單黑名單的,結果也是要伺服器判斷。既然都已經是由伺服器判斷了,多加這個資料其實是多餘的。
另外,這個白名單黑名單如果存在玩家端,這玩家也可以做怪;如果是存在伺服器端,同一個玩家在不同的電腦上狀況也不同,可能一台電腦有鬼另一台沒有鬼,所以這個名單也沒有意義,還是得每次判斷送來的資料是否正確。
推測閒者先生並沒有這一方面相關的工作經驗,只是憑自己的想像認為這樣做是可行的。建議閒者先生試著將自己所想的程序寫出來然後自己試著去破解看看,就會知道可不可行了。
> 而且我指的是玩家和玩家間的「信任」提供給伺服器參考
to 閒者 :
都說了客戶端送過來的資料是不可信的,
伺服器怎麼可能還拿玩家端送過來的資料去判斷另一個玩家是否可以信任.
請先想清楚這樣做的後果,
不要為了省工最後造成更嚴重的後果 ....
黑白名單存在本地端就可以了,沒必要存伺服端。而且一次性判斷(要不要和這個人玩)和多次判斷(這個人現在做的事有沒有異常)總有差別吧?
>都說了客戶端送過來的資料是不可信的
所以我前面有一個前提是潛在受害者必須是信任者本身。
當信任者發現對方實際上不可信任的時候總曉得取消白名單改加黑名單吧?
好吧, 如果你要覺得這樣做是可行的就隨便你了,
祝你在你的遊戲中用這樣的作法不會出狀況.
把信任不信任交給玩家去判斷 .... (算了, 懶得和你說了)
如果你覺得我說的沒有道理, 也歡迎你以後不要再來留言.
這一串留言看下來,我很好奇閒者先生是否真的有做過線上遊戲?
不知道閒者先生願不願意好心的告訴我你做過那款遊戲?
最好是那款遊戲有用過你所說的這中黑白名單的信任方式,我好去測試(破解)你的安全性問題來證明你的說法有問題,以閒者先生的留言來看,除非有人證明給你看你的作法是可以破解的,否則你是不會相信你這作法有問題吧。
還是說你從來沒有做過線上遊戲?也沒有從事過相關的工作?這些只是你個人認為可行的作法?
老天,我看到上面的回應差點昏倒‧‧‧
先不說有人把對戰遊戲的黑名單和上面那位不知道有沒有做過遊戲的閒者所說的黑白名單混在一起,這兩個完全不同作用的東西搞在一起,代表著有人根本沒看懂閒者在寫的是什麼。
更不要說有人居然以為對戰遊戲有沒有作弊可以放到玩家端來判斷,如果LOL真的這麼做,早就被破爽爽,整個遊戲的對戰公平性完全消失了呀。這種對戰遊戲更不能放在玩家端做判斷,到時候死得只會更慘。
真是的‧‧‧
to 老骨頭 :
建議別回應那些文章, 那只是浪費自己的時間.
畢竟這不是在工作, 不需要對某些人的言論太在意.
如果是工作時團隊內有這種手下,
喜歡不懂裝懂的這種我一向是豪不留情的砍掉.
不過這不是工作, 這些人也不是你我的手下.
開了部落格沒有辦法避免會有奇怪的人來回應,
特別某些人喜歡裝內行亂說, 不理他們是最好的辦法.
本來不同的人有不同的意見是常見的狀況,
不過某些不懂愛裝懂, 或是特別愛硬坳的網友,
我希望他們不要再來我這裡留言.
生命有太多重要的事, 不要把時間浪費在回應這些留言上.
銀狐先生你好,我好久沒有來這留言了,不過文章的意思我有點看不太懂,從自己也是一個玩家的心態出發,我確實很能夠理解玩家本身也有許多不對得舉動,包含你提出的此篇文章的訊息在內,又或者說玩家本身有不少人是習慣於做這樣的事情的。
但是該怎麼說呢,這情況是在於client端產生後,應該亦是sever端產生影響吧,還是有一些運算的部份其實與將sever與client端的內容分開的?那麼相對於這樣的情況,client端的user也盡可能自己試著嘗試判斷問題是否真的為問題,然後再送到客服那兒?
玩家自身違反規則的情況在現在的網路遊戲中可能會越來越常見,雖然對於修改紀錄或在遊戲上行為的手段感到排斥,卻也覺得許多user本身的自制力在於日後好像會越來越差的樣子...
to 翔翼 :
這一篇在講的其實就是文章標題所寫的,
Server在收到Client送來的資料一定要確認再確認.
雖然文章內沒有寫, 但並不是說Client端都不需要確認,
只是Client的確認是不保險的, 一定要Server端再檢查.
舉例來說, 如果A玩家將身上的東西交易給B玩家,
Client端一定會檢查A玩家身上是否有這個東西,
但是若是在送出來的封包裡把數量給修改了,
然後Server端沒有檢查A玩家身上是否有足夠的數量,
那麼這個交易結束後會發生什麼樣的問題?
至於Client翻譯為客戶端指的是程式而不是玩家,
這種安全性的事情是不需要由User來判斷的,
事實上User也無從判斷.
正是因為現在會在遊戲中亂搞的玩家越來越多,
所以在製作遊戲時要更注意安全性 ....
呵呵 沒想到銀狐會起這一篇 讓我很有感覺
隨著網路發展 傳輸速度越來越快
老實說 真的不可以相信Client傳來的訊息
所以大多數有經驗的程式 都會在Server內去判斷封包內容的合理性
雲端技術也越來越有實行的可能
所以可以把邏輯判斷流程放在Server端
在Client只有放置 介面動畫顯示與操作指令
這樣子可以簡化在Server端的封包判斷條件
也可以簡化遊戲傳輸之間的複雜度 ^^
這是我目前的設計概念 希望能夠拋磚引玉
大家一起互相討論分享看法與心得 ^^
夢幻之星!!!
懷念的好遊戲。
俺還有一套波波波代理的在抽屜裡勒XD
改天拿出來拜拜好了(炸)
HI 銀狐版大您好,
請問可否將此文章轉貼至我的個人粉絲團?
我將完整載名出處、作者,
閱讀完整篇文章感覺受益良多,謝謝!
to Lai :
我在Facebook上有開『銀狐 Silver Fox 的碎碎唸』的粉絲頁,
請直接到粉絲頁使用Facebook的分享功能轉貼吧.
張貼意見