這幾日, 頻頻看見有人喊被AntiGate誤踢事件,
於是乎, 我終於忍不住我的好奇心,
去看一下為何發生誤踢事件, 看完程式之後,
我知道原因了, so, 跟大家分享一下,
我想, 這裏面透漏一個很重要的訊息, AntiGate所引發的誤踢事件,
其實是背下一個大黑鍋, 所有人仔細看,
如果你有屬於以下的部份原因者,
趕快換掉吧, 你老早被踢的東倒西歪而不自知,
今天AntiGate不過是把問題彰顯出來而已.
這是純粹從程式的角度來觀看這一件事情,
並非要幫AntiGate解釋什麼,
而是以客觀的角度來看AntiGate的踢人規則.
AntiGate 第一個版本是MoRpH,
所以我先去找了MoRpH 的source code 來看,
然後跟下載的MoRpH AntiGate source code 比對,
呵呵, 其實AntiGate 只改了幾行而已,
然後我又下載官版AntiGate 跟Sivka AntiGate 都查同樣的位置,
於是乎, 很快得到一個結論,
整個AntiGate 踢人系統是來自MoRpH 的,
而Sivka 版的AntiGate 也將是最嚴苛的踢人法則,
原因是, Sivka 本身另有一套踢人系統,
結果又加上MoRpH 踢人系統,
所以, 總共有兩套踢人系統在Sivka 版裏面.
這還不包括原本eMule 官版的踢人系統,
也就是說, 踢人系統總共三大套:
1. eMule 官版踢人系統
2. MoRpH 版踢人系統
3. Sivka 版踢人系統.
從上面可以知道, 除了Sivka 版是三者加起來以外,
其餘的都是MoRpH + eMule 官版的踢人系統. 以下是程式碼:
引用:
--------------------------------------------------------------------------------
if (StrStrI(m_pszUsername,"$GAM3R$") ||
StrStrI(m_pszUsername,"G@m3r") ||
StrStrI(m_pszUsername,"$WAREZ$") ||
StrStrI(m_pszUsername,"RAMMSTEIN") ||
StrStrI(m_pszUsername,"Leecha") ||
StrStrI(m_pszUsername,"energyfaker") ||
StrStrI(m_pszUsername,"edevil") ||
StrStrI(m_pszUsername,"darkmule") ||
StrStrI(m_pszUsername,"phArAo") ||
StrStrI(m_pszUsername,"Reverse") ||
StrStrI(m_pszUsername,"eVortex") ||
StrStrI(m_pszUsername,"|eVorte|X|") ||
StrStrI(m_pszUsername,"Chief") ||
StrStrI(m_pszUsername,"celinesexy") ||
StrStrI(m_pszUsername,"妖?#93;電?#91;") || // <-------------------
StrStrI(m_pszUsername,"妖?#93;聖?#91;") || // <-------------------
//StrStrI(m_pszUsername,"Mison")|| //Temporaly desactivated, ban only on mod tag
//StrStrI(m_pszUsername,"toXic")|| //removed for the moment
StrStrI(m_clientModString,"Freeza") ||
StrStrI(m_clientModString,"d-unit") ||
StrStrI(m_clientModString,"NOS") ||
StrStrI(m_clientModString,"imperator")||
StrStrI(m_clientModString,"SpeedLoad")||
StrStrI(m_clientModString,"gt mod") ||
StrStrI(m_clientModString,"egomule") ||
StrStrI(m_clientModString,"darkmule") ||
StrStrI(m_clientModString,"LegoLas") ||
StrStrI(m_clientModString,"DM-") || //hotfix
StrStrI(m_clientModString,"|X|") ||
StrStrI(m_clientModString,"eVortex") ||
StrStrI(m_clientModString,"Mison") ||
StrStrI(m_clientModString,"father") ||
StrStrI(m_clientModString,"Dragon") ||
StrStrI(m_clientModString,"booster") || //Temporaly added, must check the tag
GateCheck((LPCTSTR)m_clientVerString,m_nUserID)|| //AntiGate <----------------------
(StrStrI(m_clientModString,"Morph") && StrStrI(m_clientModString,"Max"))||
((GetVersion()>589) && (GetSourceExchangeVersion()>0) && (GetClientSoft()==51))) //LSD, edonkey user with eMule property
--------------------------------------------------------------------------------
對於不懂程式設計的人, 上面的內容可能很難理解, 我大約解釋一下.
m_pszUsername <---- 用戶的名字.
只要出現在這個後面的那一串名字跟你的名字一部份一樣,
那你就是被各MODs 踢著玩的用戶. 例如:
StrStrI(m_clientModString,"Chief") || <---- 這一行多可怕阿
如果有人的名字是:???Chief???, 請注意喔,
名字中間出現特定連續字母, 嘿嘿, 你已經被踢掉了.
而AntiGate 加入踢的只有兩種名字,
"妖魔電騾" 跟 "妖魔聖騾", 所以呢,
如果你很好心的把名字取為: "請不要使用妖魔電騾, 謝謝!",
不好意思, 你也被踢掉了.
這跟原來eMule MODs 的踢人法是一樣的,
名字部份相似, 就被踢掉了.
so, 名字千萬別把四個字照用阿,
必死無疑, 切記切記 !!!
m_clientModString <--- 這個則是版本號碼,
只要你用的版本不是這兒所列的, 就不會有事情.
而AntiGate 在版本號碼這兒的檢查就躲到DLL 裏面去了,
也就是, 不給看了. 他呼叫GateCheck (....),
但是, 既然是版本號碼,
當然就是現在他踢除的所有版本的字串囉.
至於他為何要躲入DLL ?
嗯... 我有一些猜測, 後面補述.
好了, 上面的程式碼已經說明了一切,
很多明明不是被AntiGate 公告的區域或版本為何被踢?
其實答案很簡單, 只要符合上述任何一個內容者,
都面臨遭受踢除的危機,
而AntiGate 在符合上述任何一個條件下,
則進一步檢查credit system, 所以, 就這樣的角度來看,
即使是妖魔電騾或妖魔聖騾,
只要他有傳給你, 你就必須還債,
這也是新版推出後, 有人反應說, 會出現妖魔版而不踢.
我想這是合理的, 你既然從人家那兒取得東西,
不管他是不是不守規矩,
你先償還你的債務, 你才有資格去踢人.
而進一步檢查credit system 是AntiGate 加上去的,
原始的MoRpH or Sivka 並沒有檢查這一段,
so, 這部份的確是AntiGate製作小組加入的.
而AntiGate 如何踢人, 以及如何通知被踢的人呢? 程式碼是:
引用:
--------------------------------------------------------------------------------
void CUpDownClient::Ban(){
m_bBanned = true;
theApp.uploadqueue->UpdateBanCount();
theApp.emuledlg->transferwnd.ShowQueueCount(theApp.uploadqueue->GetWaitingUserCount());
m_dwBanTime = ::GetTickCount();
theApp.emuledlg->transferwnd.queuelistctrl.RefreshClient(this);
theApp.emuledlg->AddDebugLogLine(false,GetResString(IDS_CLIENTBLOCKED),GetUserName());
}
void CUpDownClient::BanLeecher(){
m_bLeecher = true;
this->Ban();
// Ban notification AntiGate
theApp.emuledlg->chatwnd.chatselector.StartSession(this, TRUE);
theApp.emuledlg->chatwnd.chatselector.SendMessage (
"You're being banned , because Taiwan-Gate forum stealing this version , Or you are using the Gate leecher mod .\n"
"由於被妖?#93;盜用, 或是你使用了違反規定的妖?#93;版, 你己被踢除.\n"
"蚕衾掩毦藹聒蚚, 麼岆斕妏蚚賸峊毀寞隅腔毦藹唳, 斕撩掩杺壺.\n"
"antigate.cn.st" );
theApp.emuledlg->chatwnd.chatselector.EndSession(this);
}
--------------------------------------------------------------------------------
我一樣只解釋重點:
void CUpDownClient::Ban() <---- 這是官版的踢人系統
void CUpDownClient::BanLeecher() <----- 這是MoRpH 版的踢人系統
仔細看, BanLeecher 裏面會呼叫Ban,
也就是, 其實MoRpH 踢人系統並沒有真的執行踢人動作,
而是把最終如何踢掉一個人交給eMule 官版的程式碼去處理.
MoRpH 踢人系統只是負責判斷,
而AntiGate 加上去的就是BanLeecher 裏面那一堆字串,
他用來發出訊息給被踢的人, 告知他被踢了.
好了, 這兒我們也得到第二個解釋,
為何非AntiGate 公告的人被踢, 也會收到同樣的訊息呢?
因為AntiGate 製作小組是直接在踢除時通知,
而踢除原因很多,
其中只有符合AntiGate 小組所公告的部份是AntiGate 所踢的,
而其餘的是原來的MoRpH 系統所踢的,
只是, 得到同樣的公告訊息就是了.
so, 我到處亂逛得到的誤踢訊息總共有:
1. 我是eMule 官版, 但是被踢了.
2. 有人在海外論壇看到海外人士捱了一腳
3. 自己是AntiGate 版, 也被踢了
4. eDonkey, 怎也被踢了
上面林林總總, 其實都不是AntiGate 踢的,
而是MoRpH 踢人系統判定要踢的,
至於為何判定要踢? 嗯.... 請看第一段程式碼吧.
當然, 除了第一段程式碼, 還有屬於Spam 的也會踢,
但是我沒有列出來, 因為那一段一樣AntiGate 並沒有改變,
是MoRpH 系統原來會踢的.
看懂為何誤踢之後, 我們再來探究DLL 的目的.
AntiGate 小組網頁上寫的很清楚,
DLL 用來辨別emule 是不是被修改過.
呵呵, 這個方法其實也挺有趣的,
大家玩驢子這麼久, hash 的觀念清楚的很吧,
不用想也知道,
他一定用某一種hash 運算去辨認執行檔是否被修改.
我想, 他的目的一定是不讓妖魔去修改他的版本,
然後換躲到AntiGate 底下. 其實這個方法也不錯,
如果eMule 原始設計有這麼一手,
就不會發生現在被盜用MODs 名稱的問題了.
好, 既然要保護DLL, 為何要把檢查的動作也躲到DLL 內呢?
其實我剛開始也百思不解, 後來我想通了一件很重要的事情,
根據GPL 規範, AntiGate 其實遊走規範邊緣, 怎麼說呢?
如果今天直接修改emule的程式碼, 他一定得Open source,
就如同我可以找到程式碼來解析一番一樣,
那一旦open source, 除了前面的保護機制失效外,
其實還會引發另一件更可怕的事情 (後面再說, 先說完GPL).
所以, 他把程式碼藏入DLL 裏面,
在GPL 規範內, 拿open source 可以恣意修改,
但是要把source 再open 出來,
如果引用open source 的程式碼片段, 也需要open.
但是, 並沒有規定搭配open source 的程式必須open source.
舉個例子, Linux 必須open source,
但是, 你可以開發AP 執行於Linux 環境中,
但是, 你不一定要把你的AP open source.
so, AntiGate 只要保證他的DLL 裏面的程式碼全部是他自己撰寫,
而沒有抄襲eMule 的任何程式碼或者其他open source 的程式碼,
那他是可以有權力不公開source code的.
這也是他說, 在GPL 規範下,
他們獨立開發的DLL 可以不open source.
其實這也是很多商業團體所使用的手法哩, 呵呵
好, 再回頭看為何檢查版本的程式碼也需要躲起來,
經過我一番思索, 我個人認為, 他要保護兩岸三地的IP偵測方法.
怎麼說呢?
官網上明確說明,
檢查特定版本的動作會根據IP決定踢除與否 (除了第一代妖魔版必踢之外),
換句話說, 如果他把這一段直接寫在eMule 裏面,
那隨著open source 的結果,
所有人都知道AntiGate 根據哪一種方法正確判斷兩岸三地的IP,
這份資料如果是open 的, 那是粉恐怖的,
國外任何一個MODs 作者可以立刻收錄,
就直接把兩岸三地踢出全球P2P 的範圍外了.
所以, 我大膽推測, 他們把檢查版本的動作也藏起來,
就是為了保護IP偵測方法. 不然其他都open 了,
檢查版本的功能一堆MODs 都有, 沒有必要大費周章去隱藏.
好了, AntiGate 也解析完畢了,
其餘都是不重要的改MODs 版本名稱的code.
主要的踢人系統就是如此而已.
當然, 這兒也間接看出某個問題的答案,
某些人說的,
既然踢人, 為何單向踢, 而不是要踢人, 就不要向對方下載.
其實, 這個問題或許問eMule 官版作者比較快.
因為最終如何把人踢掉, 所有的MODs 都是靠官版踢人系統踢掉的.
而這版AntiGate把踢人系統合理化的部份,
就是欠債無論如何不踢, 包括原來MoRpH 必踢的,
這兒也會因為欠債而不踢. 當然, 也包括有人說,
他看到妖魔電騾卻沒踢的問題了.
AntiGate 使不使用見仁見智, 純粹看個人如何看待妖魔版的1:8 吧.
有妖魔版捍衛者說, 為何獨抗議電騾不抗議聖騾,
我想, 程式碼說明一切, 聖騾照踢不誤, 並沒有厚此薄彼.
至於1:1 還債方式是不是嚴苛? 我個人沒有答案.
我唯一能引述的資料是, 從eMule 官網的陳述,
eMule 利用credit system 是作為排隊的依據,
不是作為還債的依據.
也就是, 上傳的多, 下載的少者, 可以獲得插隊的權力,
而且, 是採用2倍加權計算的法則(詳情請自己去eMule 網站看).
從eMule 官網的陳述裏面, 我們可以清楚的了解,
eMule 本身並不是用欠多少需要償還多少,
而是因為積欠, 所以需要給予優先權,
而優先權又需要跟排隊時間混合計算,
也就是, 排隊時間夠久, 一樣得到足夠的優先權.
這與償債的觀念將是完全不同的, 請務必留意.
當然, 這也引發另一個問題,
AntiGate根據此點作為1:1 ban 人的條件何不合理?
或者應該用更高的償還額度看待?
我想, 這部份每個人都會有不一樣的想法,
我也不太方便多說啥, 我只是覺得, 1:1 看起來已經很公平了.
這兒補述一點: 在eMule 裏面目前出現幾個數據
1:4
這是指網路上傳多少頻寬, 可以取得多少下載頻寬.
這是上限, 並非絕對值. 也就是, 上傳3K, 最大下載12K,
可以低於此值, 不得高於此值.
1:2
這是關於上下傳差值的加權值的一部分.
整個也不是很單純的1:2, 還要經過數學式計算.
1:1
這是AntiGate 新想出來的償債不踢模式.
在還完債以前, 無論如何不能踢掉人, 即使有深仇大恨.
1:8
這是妖魔版想出來的,
所謂造福小水管? (我也是小水管, 我卻反而很痛苦@_@),
他的條件跟1:4 一樣, 只是設定上限, 沒有下限.
10:無限大
這是指大於10K 上傳, 下傳沒有限制, 看你線路有多快.
一樣的, 他是上限, 沒有下限, 說更白一點,
可能10:100, 也可能10:0, 也可能10:5000
(如果能發生的話, 我要向這個人膜拜一下, 他可能同時下載了1000部A 片...... 哈哈)
目前對AntiGate 感冒的人多數是源自於閉著眼睛踢掉幾個MODs,
這點我個人也沒有答案, 因為, 從技術面去看,
妖魔X螺確實無法辨識, 對於無法辨識的,
只有簡單的選擇, 一個是能可錯殺,
另一個是寧可錯放, 而目前是根據credit system 1:1 決定要不要殺.
我想, 原始eMule 以及各MODs 作者,
都不會想到有人會玩這種盜用版本名稱的遊戲.
從上面一缸子版本被踢掉的情形去看,
老外還是很可愛的, 即使明知道自己的版本可能不被接受,
依然勇於立自己的版號. 其實也沒錯,
因為官版沒有任何因為MODs 版本而踢人的作法,
會根據MODs 版本踢人的, 都是一些MODs 版.
so, 立自己的版號, 也只會被MODs 踢,
而不會被官版踢, 也不會被eDonkey 踢,
so, 立自己的版號也沒啥好懼怕的.
只是... 台灣人卻不敢立版號.... 呵呵... 奈何呢?
這篇文章純談AntiGate 的技術面,
至於支持AntiGate 與否, 由各位自己去判斷吧.
我也不發表個人意見, 讓這篇文章變成純粹中立的文章.
我個人素來不涉足其他論壇,
除了曾經破例在Cyndi 發過一篇文之外, 我也不想再次破例,
無論如何, 這篇文章歡迎轉載, 要不要註明誰寫的都可以.
離開TWed2k, 認得我的也沒幾個人,
so, 名字也不重要. 解析這段程式碼也沒啥,
學過幾天程式設計的人都能看的懂, 刻意列出來,
其實只是要讓不懂技術的人能夠了解AntiGate 怎樣來的,
也嚐試讓被誤踢的人了解, 其實他老早被踢了,
只是以前的eMule 不會通知被踹一腳而已.
當然, 我不是AntiGate 的作者, 我只是好玩去抓來瞧一瞧,
看看到底發生了啥事情的好奇人士而已.
so, 對於DLL 的部份我只能從各種角度去推敲與臆測,
是否猜錯我可沒把握.
至於對於eMule 的部份則不至於弄錯,
因為是擺在那兒供眾人觀看的程式碼哩, 呵呵
原作者Acute.