【插件资讯】插件来源:原创
使用指令: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!