【插件資訊】插件來源:原創
使用指令:cs_set_user_model
安裝路徑:addons/amxmodx/modules/
【插件介紹】本文針對 CStrike 模塊裡的一個 native 函數嘗試作出一些簡單修正
複製程式
static cell AMX_NATIVE_CALL cs_set_user_model(AMX *amx, cell *params) // cs_set_user_model(index, const model[]); = 2 params
cs_set_user_model 這個函數也許你已經很熟悉, 它讓插件可以給玩家定義一個新的模型.
但有時候, 當你給大量玩家調用這函數時可能會產生一些問題, 最常見是當每局開始時一些玩家會從伺服器中被踢出, 此類錯誤通常被稱為SVC_BAD錯誤.
在這情況下, 發生錯誤的原因往往是因為它在同一刻裡改變大量玩家的模型所造成的. 而在模塊中所用改變模型的方法亦可能也是原因之一.
以下為 CStrike 模塊的一些 C++ 源碼
複製程式
static cell AMX_NATIVE_CALL cs_set_user_model(AMX *amx, cell *params)
{
// ... ...
strcpy(model, MF_GetAmxString(amx, params[2], 0, &len));
g_players[params[1]].SetModel(model);
g_players[params[1]].SetModelled(true);
SETCLIENTKEYVALUE(params[1], GETINFOKEYBUFFER(pPlayer), "model", (char*)g_players[params[1]].GetModel());
return 1;
}
它通過SETCLIENTKEYVALUE去改變玩家的模型, 情況就像你在插件裡使用 set_user_info( player, "model", "xxx" ) 或在遊戲中使用指令 model "xxx" 一樣, 但只是這樣做是不足夠的, 因為幾乎立即就會被 CS 重置成原來的模型.
複製程式
void PlayerPostThink(edict_t* pPlayer) {
int entityIndex = ENTINDEX(pPlayer);
if(g_players[entityIndex].GetModelled()) {
if (g_players[entityIndex].GetInspectModel() && strcmp(g_players[entityIndex].GetModel(), GETCLIENTKEYVALUE(GETINFOKEYBUFFER(pPlayer), "model")) != 0) {
SETCLIENTKEYVALUE(entityIndex, GETINFOKEYBUFFER(pPlayer), "model", (char*)g_players[entityIndex].GetModel());
g_players[entityIndex].SetInspectModel(false);
}
}
RETURN_META(MRES_IGNORED);
}
問題就在這裡, 為了防止CS重置玩家的模型, 它所使用的對策是在玩家的每個 PostThink 事件中檢查模型是否被改變, 如果被 CS 改變了就立即設回新的模型. 但不是上策, 更可能會令到問題惡化.
就此我對源碼作了一些修改, 並移除了使用 PostThink, 改用一些更可行的做法, 詳細不多解釋.
這個版本(也許)能減少此類問題的發生, 但我不能保證(畢竟我找不到32個玩家來測試)
目前只編譯 Windows 的版本
建議預先備份原始的 cstrike_amxx.dll 否則後果自負
[此文章售價 1 雅幣已有 31 人購買]
若發現會員採用欺騙的方法獲取財富,請立刻舉報,我們會對會員處以2-N倍的罰金,嚴重者封掉ID!