homework 发表于 2010-11-3 16:26:27

【已解决】高手帮忙看下这段代码哪里错了chinese_id_2

本帖最后由 homework 于 2012-10-27 01:12 编辑

源码如下 老友记的 chinese_id_2/*
   名称:CS中文ID插件
   作者:PooHoo@老友记
   来源:http://cs-friends.com.cn
   (AMXX1.76 以上测试通过)

   功能:
      实现 CS 中文ID功能
      简单的样例插件,从文本文件里读取中文ID设置
      如果数据量大,建议改用数据库比较理想,管理也比较方便

   插件安装说明:
      1,需要使用 ig 修改过的 fakemeta_amxx.dll 模块配合使用
         替换你原来的`fakemeta_amxx.dll 即可,不影响 fakemeta 里的任何功能
      2,chinese_id.ini 为中文ID设置文件,放到 \amxmodx\configs\ 目录下
         按里面的说明添加信息,记住要保存为 UTF8 无签名格式
      3,把本插件配置放到 plugin.ini 文件的最上面

   插件开发使用者说明:
      1,主要是使用 ig_setname 函数,实现中文ID的名字更换
         其他更好的方法?等待你来发掘。。。
      2,在你的 fakemeta.ini 里最下面增加下面的函数定义,否则无法编译
         // 设置玩家名字
         // name = 玩家新的名字(超过31个字节无效)
         native ig_setname(id, const newname[])

   中文ID使用的已知问题:
      1,按麦克风通话时,中文ID的玩家名字为乱码,无法正确显示。
      2,玩家在游戏里的改名功能被禁用,如果要改名,需要离线改好再进。
      3,是否有其他问题???

   鸣谢:
       的技术支持与帮助
      http://cs-friends.com.cn

        修改by Nicky.xu
   经过修改后,只需要swds.dll文件支持中文ID,Fakemeta这个模块可以用amxx自带的原版
        玩家无论在死亡还是存活,都可以即时改名
        如果担心暴力+改名作弊器,请把
       register_forward(FM_ClientUserInfoChanged, "FM_client_userinfochanged")注释掉..
        同时把
        public FM_client_userinfochanged(id, iBuffer)及其以下那些代码删掉即可
       

*/


new const PLUGINNAME[] = "中文ID"
new const VERSION[]    = "2.1"
new const AUTHORS[]    = "poohoo @ 老友记"

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>


new g_SetName
new g_SetAllow
new FILE

public plugin_init()
{
   register_plugin(PLUGINNAME, VERSION, AUTHORS)

   new configsdir
   get_configsdir(configsdir, sizeof(configsdir)-1)
   formatex(FILE, sizeof(FILE)-1, "%s/chinese_id.ini", configsdir)

   register_forward(FM_ClientUserInfoChanged, "FM_client_userinfochanged")
   if (!file_exists(FILE))
      set_fail_state("File (configs/chinese_id.ini) open error.")
}



// 设置 id 需要的名字
public set_name(id, const newname[])
{
   if (strlen(newname)<1)
      return

   g_SetAllow = 1
   copy(g_SetName, 31, newname)
   //one_name(id, g_SetName, 31)
   set_user_info(id, "name", g_SetName)
}

public client_connect(id)
{
   remove_task(id)
   g_SetAllow = 0
}

public client_putinserver(id)
{
   // 延时足够的时间,等待 admin 权限认证插件完成权限设置后,再执行更换名字
   set_task(random_float(3.0,3.0), "get_name_from_file", id)
}

// 从文件里检查是否有对应的中文ID
public get_name_from_file(id)
{
   if (!is_user_connected(id))
      return
   
   new name
   get_user_name(id, name, 31)

   new set = 0
   new hFile = fopen(FILE, "r")
   if (hFile)
   {
      new line, tmpName, tmpNameCN

      while (fgets(hFile, line, sizeof(line)-1))
      {
         tmpName = ""
         tmpNameCN = ""
         trim(line)
         if (line==';' || line=='/') continue

         parse(line, tmpName,sizeof(tmpName)-1, tmpNameCN,sizeof(tmpNameCN)-1)
         trim(tmpName)
         trim(tmpNameCN)

         if (strcmp(name, tmpName)==0)
         {
            copy(name, 31, tmpNameCN)
            set = 1
            break
         }
      }
   }
   fclose(hFile)

   // 完成后,设置新的名字
   if (set)
      set_name(id, name)
}



public FM_client_userinfochanged(id, iBuffer)
{
   // 玩家是否依然在线?
   if (!is_user_connected(id))
      return FMRES_IGNORED // 离开,则返回

   // 获取名字改变情况
   static szOldName, szNewName
   get_user_name(id, szOldName, 31)
   engfunc(EngFunc_InfoKeyValue, iBuffer, "name", szNewName, 31)

   // 检查是否改名字?(Death change name by VEN)
   if (equal(szNewName, szOldName)) // 如果名字没有改变,则返回
      return FMRES_IGNORED

   // * CS 默认状态下,如果玩家在死亡状态,更换名字是不被执行的
   // 所以在这里检查,如果玩家在死亡状态更换名字,则发送一次名字更换消息
   // 让名字更换,在死亡状态下也可以正常显示/执行,方便查看玩家名字
   if (!is_user_alive(id))
   {
      message_begin(MSG_BROADCAST, get_user_msgid("SayText"))
      write_byte(id)
      write_string("#Cstrike_Name_Change")
      write_string(szOldName)
      write_string(szNewName)
      message_end()
      return FMRES_SUPERCEDE
   }

   return FMRES_IGNORED
}

错误提示如下://AMXXPC compile.exe
// by the AMX Mod X Dev Team


//// chinese_id_2.sma
// G:\HLServer\cstrike\addons\amxmodx\scripting\chinese_id_2.sma(1) : error 010:
invalid function or declaration
//
// 1 Error.
// Could not locate output file G:\HLServer\cstrike\addons\amxmodx\scripting\com
piled\chinese_id_2.amx (compile failed).
//
// Compilation Time: 0.31 sec
// ----------------------------------------

Press enter to exit ...请高手帮忙看下哪个地方错了,谢谢。。。:'(

cuikejie 发表于 2010-11-4 05:44:59

*/


new const PLUGINNAME[] = "中文ID"
new const VERSION[]    = "2.1"
new const AUTHORS[]    = "poohoo @ 老友记"

#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <memhack>

new g_RetryOnce
new g_SetName
new g_SetAllow
new FILE

public plugin_init()
{
   register_plugin(PLUGINNAME, VERSION, AUTHORS)

   new configsdir
   get_configsdir(configsdir, sizeof(configsdir)-1)
   formatex(FILE, sizeof(FILE)-1, "%s/chinese_id.ini", configsdir)

   if (!file_exists(FILE))
      set_fail_state("File (configs/chinese_id.ini) open error.")
}

// 名字更改消息
public client_infochanged(id)
{
   if (!is_user_connected(id))
      return PLUGIN_CONTINUE

   // 更换限制标记
   if (!g_SetAllow)
   {
      new oldname, newname
      get_name(id, oldname, 31)
      get_user_info(id, "name", newname, 31)

      if (strcmp(newname, oldname)==0)
         return PLUGIN_CONTINUE

      // 兼容 sXe 改名
      if (equal(newname, "", 10))
      {
         replace(oldname, 31, " ", "")
         formatex(newname, 31, " %s", oldname)
         ig_setname(id, newname)
      }
      else
         ig_setname(id, oldname)

      return PLUGIN_CONTINUE
   }

   g_SetAllow = 0
   ig_setname(id, g_SetName)

   return PLUGIN_CONTINUE
}

// 重名检查
one_name(id, name[], len)
{
   new sample, s
   copy(sample, 31, name)

   for (new i=0; i<33; i++)
   {
      if (s>0)
         formatex(sample, 31, "(%d)%s", s, name)

      if (!is_name_inuse(id, sample))
         break

      s++
   }
   copy(name, len, sample)
}

is_name_inuse(id, const sample[])
{
   new name
   for (new i=1; i<=get_maxplayers(); i++)
   {
      if (!is_user_connected(i)) continue
      if (id==i) continue

      get_user_name(i, name, 31)
      if (strcmp(name, sample)==0)
         return 1
   }

   return 0
}

// 设置 id 需要的名字
public set_name(id, const newname[])
{
   if (strlen(newname)<1)
      return

   g_SetAllow = 1
   copy(g_SetName, 31, newname)
   one_name(id, g_SetName, 31)
   set_user_info(id, "name", g_SetName)
}

public client_connect(id)
{
   remove_task(id)
   g_SetAllow = 0

   // 强制重新连接一次,以解决因为换中文ID后,换图会出现权限认证问题
   if (!g_RetryOnce)
   {
      g_RetryOnce = 1
      client_cmd(id, "retry")
   }
}

public client_putinserver(id)
{
   // 延时足够的时间,等待 admin 权限认证插件完成权限设置后,再执行更换名字
   set_task(random_float(3.0,3.0), "get_name_from_file", id)
}

// 从文件里检查是否有对应的中文ID
public get_name_from_file(id)
{
   if (!is_user_connected(id))
      return
   
   new name
   get_name(id, name, 31)

   new set = 0
   new hFile = fopen(FILE, "r")
   if (hFile)
   {
      new line, tmpName, tmpNameCN

      while (fgets(hFile, line, sizeof(line)-1))
      {
         tmpName = ""
         tmpNameCN = ""
         trim(line)
         if (line==';' || line=='/') continue

         parse(line, tmpName,sizeof(tmpName)-1, tmpNameCN,sizeof(tmpNameCN)-1)
         trim(tmpName)
         trim(tmpNameCN)

         if (strcmp(name, tmpName)==0)
         {
            copy(name, 31, tmpNameCN)
            set = 1
            break
         }
      }
   }
   fclose(hFile)

   // 完成后,设置新的名字
   if (set)
      set_name(id, name)
}


stock get_name(id, name[], len)
{
        new buffer = engfunc(EngFunc_GetInfoKeyBuffer, id)
        new strtmp1
        copy_infokey_buffer(buffer, strtmp1, 255)
        new offset = contain(strtmp1, "\name\") + 6
        new thischr
        new i
        for (;;i++)
        {
                thischr = memhack_get_char(buffer + offset + i, MEM_NULLBASE, MEMTYPE_DATA, MEM_SIGNED)
                if (thischr == '\' || thischr == 0)
                {
                        name = 0
                        break
                }
                else
                {
                        name = thischr
                }
       
        }
        name = 0
}

homework 发表于 2010-11-4 08:06:12

本帖最后由 homework 于 2010-11-4 08:12 编辑

致 cuikejie 同学:
    用你的代码编译出现下面的错误,能不能发个chinese_id_2.amxx给我啊,我想在AMXX1.8.1下使用,谢谢。//AMXXPC compile.exe
// by the AMX Mod X Dev Team


//// chinses_id2.sma
// G:\HLDS 2010.3.25_1\cstrike\addons\amxmodx\scripting\chinses_id2.sma(1) : err
or 010: invalid function or declaration
//
// 1 Error.
// Could not locate output file G:\HLDS 2010.3.25_1\cstrike\addons\amxmodx\scrip
ting\compiled\chinses_id2.amx (compile failed).
//
// Compilation Time: 0.48 sec
// ----------------------------------------

Press enter to exit ....

jiunnwoei2629 发表于 2010-11-5 00:24:03

刪除有中文文字就可以解決了

homework 发表于 2010-11-5 08:45:48

刪除有中文文字就可以解決了
jiunnwoei2629 发表于 2010-11-5 00:24 http://www.dt-club.net/forum/images/common/back.gif

谢谢指导,按你说的方法,顶楼的代码编译通过,2楼 cuikejie 先生的代码按你说的方法删除中文后还是不能编译通过,错误代码如下://AMXXPC compile.exe
// by the AMX Mod X Dev Team


//// chid2_.sma
// G:\HLServer1.6Yule\cstrike\addons\amxmodx\scripting\chid2_.sma(1) : e
rror 010: invalid function or declaration
// G:\HLServer1.6Yule\cstrike\addons\amxmodx\scripting\chid2_.sma(51) :
error 017: undefined symbol "ig_setname"
// G:\HLServer1.6Yule\cstrike\addons\amxmodx\scripting\chid2_.sma(54) :
error 017: undefined symbol "ig_setname"
// G:\HLServer1.6Yule\cstrike\addons\amxmodx\scripting\chid2_.sma(60) :
error 017: undefined symbol "ig_setname"
//
// 4 Errors.
// Could not locate output file G:\HLServer1.6Yule\cstrike\addons\amxmodx\script
ing\compiled\chid2_.amx (compile failed).
//
// Compilation Time: 0.12 sec
// ----------------------------------------

Press enter to exit ...在把顶楼编译通过的.amxx 发一份上来,需要的同学方便下载。
备注:我没测试过。

jiunnwoei2629 发表于 2010-11-5 14:15:15



谢谢指导,按你说的方法,顶楼的代码编译通过,2楼 cuikejie 先生的代码按你说的方法删除中文后还是不能编译通过,错误代码如下://AMXXPC compile.exe
// by the AMX Mod X Dev Team


//// chid2_.sma
/ ...
homework 发表于 2010-11-5 08:45 http://www.dt-club.net/forum/images/common/back.gif

他沒有給正確的ig_setname函數
導致沒有辦法轉AMXX

homework 发表于 2010-11-6 08:33:07

函数我就不懂了哦,
是不是关于语言方面的东西了哦

现在发布分享出来的中文ID插件好像貌似没有一个完美的,
我在用赛盟的中文ID插件,
赛盟的唯一缺陷就是改名的时候系统发给用户的提示是改成了一串数字
而成绩单上又是中文(按TAB查看成绩的成绩单)
原来用的AMXX1.8.1中文版 TOP15 统计的也是系统提示所改的那串数字的 成绩
用 心静如水 大姐的1.8.2 这个问题到是解决了
请问 jiunnwoei2629, 你怎么解决中文ID支持问题的啊?分享分享啊

yesterday 发表于 2010-11-6 13:10:50

这个需要一个修改过的fakemeta_amxx.dll模块,你在网上搜一下就有,替换原来的

然后在你编译器的amxmodx\scripting\include\fakemeta.inc 中空白行加上
native ig_setname(id, const newname[])
就行了

yesterday 发表于 2010-11-6 13:13:05

还有如果你是单机的话最好删掉
public client_connect(id)
{
   remove_task(id)
   g_SetAllow = 0
   // 强制重新连接一次,以解决因为换中文ID后,换图会出现权限认证问题
   if (!g_RetryOnce)
   {
      g_RetryOnce = 1
      client_cmd(id, "retry")
   }
}
要不然进不去

homework 发表于 2010-11-13 11:52:13

本帖最后由 homework 于 2010-12-14 15:50 编辑

谢谢 yesterday 的耐心解答,再次感谢。。。
这个需要一个修改过的fakemeta_amxx.dll模块,你在网上搜一下就有,替换原来的

然后在你编译器的amxmodx\scripting\include\fakemeta.inc 中空白行加上
native ig_setname(id, const newname[])
就行了 ...
yesterday 发表于 2010-11-6 13:10 http://www.dt-club.net/forum/images/common/back.gif
恩,按你说的方法编译通过,但是运行的时候还是提示:

是不是还需要一个修改好的fakemeta.dll啊?
页: [1] 2
查看完整版本: 【已解决】高手帮忙看下这段代码哪里错了chinese_id_2