Sourcemod CSGO获取玩家手中的武器属性

Sourcemod CSGO获取玩家手中的武器属性

Sourcemod 获取玩家手中的武器 想要获取玩家手中的武器,就需要了解起源引擎中的entity prop,也就是一些数据 通过sourcemod给我们的API,可以了解到有个方法GetEntProp 可以用来读取指定属性 这个方法需要提供三个参数 entity: 就是实体的ID,传入玩家id c

Sourcemod 获取玩家手中的武器

想要获取玩家手中的武器,就需要了解起源引擎中的entity prop,也就是一些数据

通过sourcemod给我们的API,可以了解到有个方法GetEntProp 可以用来读取指定属性

这个方法需要提供三个参数

  • entity: 就是实体的ID,传入玩家id client即可

  • PropType: 属性的类型,有两种: Prop_SendProp_Data . 根据Sourcemod官方的解释, Prop_Send是联网数据, Prop_Data 是用来储存游戏字段的。我看到的大多数都是用 Prop_Send

  • PropName: 这个就是属性的名称。想要获取属性名称,需要用到sourcemod官方的工具

    在服务器控制台中打 sm_dump_netprops dump.txt ,就可以在服务器的csgo目录下生成一个 dump.txt ,里面存有基本上所有的联网属性名,格式大概如下

    CFireSmoke - _firesmoke
    - m_flStartScale (Offset 912) (Save)(4 Bytes)
    - m_flScale (Offset 916) (Save)(4 Bytes)
    - m_flScaleTime (Offset 920) (Save)(4 Bytes)
    - m_nFlags (Offset 924) (Save)(4 Bytes)
    - m_nFlameModelIndex (Offset 928) (Save)(4 Bytes)
    - m_nFlameFromAboveModelIndex (Offset 932) (Save)(4 Bytes)
    - m_flStartScale (Offset 912) (Save)(4 Bytes)
    - m_flScale (Offset 916) (Save)(4 Bytes)
    - m_flScaleTime (Offset 920) (Save)(4 Bytes)
    - m_nFlags (Offset 924) (Save)(4 Bytes)
    - m_iClassname (Offset 96) (Save|Key)(4 Bytes) - classname
    - m_iGlobalname (Offset 540) (Global|Save|Key)(4 Bytes) - globalname
    - m_iParent (Offset 544) (Save|Key)(4 Bytes) - parentname
    - m_nMinCPULevel (Offset 520) (Save|Key)(1 Bytes) - mincpulevel
    - m_nMaxCPULevel (Offset 521) (Save|Key)(1 Bytes) - maxcpulevel
    - m_nMinGPULevel (Offset 522) (Save|Key)(1 Bytes) - mingpulevel
    - m_nMaxGPULevel (Offset 523) (Save|Key)(1 Bytes) - maxgpulevel
    - m_iHammerID (Offset 548) (Save|Key)(4 Bytes) - hammerid
    - m_flSpeed (Offset 552) (Save|Key)(4 Bytes) - speed
    

有了这个我们就可以获取玩家手中的武器了,

从文件中可以找到一个

- m_hActiveWeapon (Offset 2388) (Save)(4 Bytes)

这就是我们要找的属性名

最开始我是直接用的 GetEntProp 方法读取的这个属性,但是读取出来一串很怪的地址,随后就试着用了 GetEntPropEnt 这个方法读取,成功读取到武器,代码如下

int entity = GetEntPropEnt(client, Prop_Send, "m_hActiveWeapon", 0);

具体的原因查了一下, GetEntProp 读取的是int值,而 GetEntPropEnt 读取的是一个Entity Index,武器在csgo里属于entity

拿到武器的entity index就等于拿到武器本身这个entity了,接下来要做的就是读取这个entity的属性

int defIndex = GetEntProp(entity, Prop_Send, "m_iItemDefinitionIndex");

这一段代码相当于读取了武器entity的 m_iItemDefinitionIndex 属性,查了一下这个属性是在 Table: m_Item 里的,他还有一些其他属性,比如 m_iEntityQuality m_szCustomName 等,这些都是可以读取的

有了defIndex就可以知道是什么武器了,以下是读取的代码(抄自CSGO皮肤插件的源码):

char g_WeaponClasses[][] = {
/* 0*/ "weapon_awp", /* 1*/ "weapon_ak47", /* 2*/ "weapon_m4a1", /* 3*/ "weapon_m4a1_silencer", /* 4*/ "weapon_deagle", /* 5*/ "weapon_usp_silencer", /* 6*/ "weapon_hkp2000", /* 7*/ "weapon_glock", /* 8*/ "weapon_elite", 
/* 9*/ "weapon_p250", /*10*/ "weapon_cz75a", /*11*/ "weapon_fiveseven", /*12*/ "weapon_tec9", /*13*/ "weapon_revolver", /*14*/ "weapon_nova", /*15*/ "weapon_xm1014", /*16*/ "weapon_mag7", /*17*/ "weapon_sawedoff", 
/*18*/ "weapon_m249", /*19*/ "weapon_negev", /*20*/ "weapon_mp9", /*21*/ "weapon_mac10", /*22*/ "weapon_mp7", /*23*/ "weapon_ump45", /*24*/ "weapon_p90", /*25*/ "weapon_bizon", /*26*/ "weapon_famas", /*27*/ "weapon_galilar", 
/*28*/ "weapon_ssg08", /*29*/ "weapon_aug", /*30*/ "weapon_sg556", /*31*/ "weapon_scar20", /*32*/ "weapon_g3sg1", /*33*/ "weapon_knife_karambit", /*34*/ "weapon_knife_m9_bayonet", /*35*/ "weapon_bayonet", 
/*36*/ "weapon_knife_survival_bowie", /*37*/ "weapon_knife_butterfly", /*38*/ "weapon_knife_flip", /*39*/ "weapon_knife_push", /*40*/ "weapon_knife_tactical", /*41*/ "weapon_knife_falchion", /*42*/ "weapon_knife_gut",
/*43*/ "weapon_knife_ursus", /*44*/ "weapon_knife_gypsy_jackknife", /*45*/ "weapon_knife_stiletto", /*46*/ "weapon_knife_widowmaker", /*47*/ "weapon_mp5sd", /*48*/ "weapon_knife_css", /*49*/ "weapon_knife_cord", 
/*50*/ "weapon_knife_canis", /*51*/ "weapon_knife_outdoor", /*52*/ "weapon_knife_skeleton"
};

int g_iWeaponDefIndex[] = {
/* 0*/ 9, /* 1*/ 7, /* 2*/ 16, /* 3*/ 60, /* 4*/ 1, /* 5*/ 61, /* 6*/ 32, /* 7*/ 4, /* 8*/ 2, 
/* 9*/ 36, /*10*/ 63, /*11*/ 3, /*12*/ 30, /*13*/ 64, /*14*/ 35, /*15*/ 25, /*16*/ 27, /*17*/ 29, 
/*18*/ 14, /*19*/ 28, /*20*/ 34, /*21*/ 17, /*22*/ 33, /*23*/ 24, /*24*/ 19, /*25*/ 26, /*26*/ 10, /*27*/ 13, 
/*28*/ 40, /*29*/ 8, /*30*/ 39, /*31*/ 38, /*32*/ 11, /*33*/ 507, /*34*/ 508, /*35*/ 500, 
/*36*/ 514, /*37*/ 515, /*38*/ 505, /*39*/ 516, /*40*/ 509, /*41*/ 512, /*42*/ 506,
/*43*/ 519, /*44*/ 520, /*45*/ 522, /*46*/ 523, /*47*/ 23, /*48*/ 503, /*49*/ 517,
/*50*/ 518, /*51*/ 521, /*52*/ 525
};

bool ClassByDefIndex(int index, char[] class, int size)
{
	switch(index)
	{
		case 42:
		{
			FormatEx(class, size, "weapon_knife");
			return true;
		}
		case 59:
		{
			FormatEx(class, size, "weapon_knife_t");
			return true;
		}
		default:
		{
			for(int i = 0; i < sizeof(g_iWeaponDefIndex); i++)
			{
				if(g_iWeaponDefIndex[i] == index)
				{
					FormatEx(class, size, g_WeaponClasses[i]);
					return true;
				}
			}
		}
	}
	return false;
}

然后调用里面的 ClassByDefIndex 方法就可以读取出类型了

char weaponClass[32];
ClassByDefIndex(defIndex, weaponClass, sizeof(weaponClass));

Comment