Raised This Month: $12 Target: $400
 3% 

Some question about Virtual Offset


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Dekart
Junior Member
Join Date: Mar 2012
Old 03-12-2012 , 03:35   Some question about Virtual Offset
Reply With Quote #1

I write plugin for Meta Mod:Source for CS:S game. My plugin based on sample_mm plugin from source codes of Meta Mod from this download page http://www.sourcemm.net/downloads.

I want make simple plugin, that able enable flash effect for all players by entering command in the console, for example "flashbang".

I modified "Hook_ClientCommand" function in sample_mm.cpp:

Code:
#if SOURCE_ENGINE >= SE_ORANGEBOX
void SamplePlugin::Hook_ClientCommand(edict_t *pEntity, const CCommand &args)
#else
void SamplePlugin::Hook_ClientCommand(edict_t *pEntity)
#endif
{
#if SOURCE_ENGINE <= SE_DARKMESSIAH
	CCommand args;
#endif

	if (!pEntity || pEntity->IsFree())
	{
		return;
	}

	const char *cmd = args.Arg(0);
	if (strcmp(cmd, "flashbang") == 0)
	{
		int i;
		edict_t *pEnt;
		for (i=1; i<=64; i++)
		{
			pEnt = engine->PEntityOfEntIndex(i);
			if (pEnt && !pEnt->IsFree() && FStrEq(pEnt->GetClassName(), "player"))
			{
				gVFuncs.SomeFunc(pEnt->GetUnknown()->GetBaseEntity());
			}
		}
		
		RETURN_META(MRES_SUPERCEDE);
	}
}
and I make "VFuncs" class as in this example http://wiki.alliedmods.net/Virtual_O..._(Source_Mods)

but my "VFuncs" class have single function, that enable flash effect for certain player entity
Code:
void VFuncs::SomeFunc(CBaseEntity *pThisPtr)
{
	void **this_ptr = *(void ***)&pThisPtr;
	void **vtable = *(void ***)pThisPtr;
	void *func = vtable[348]; 
 
	union {void (VfuncEmptyClass::*mfpnew)();
	#ifndef __linux__
			void *addr;	} u; 	u.addr = func;
	#else // GCC's member function pointers all contain a this pointer adjustor. You'd probably set it to 0 
				struct {void *addr; intptr_t adjustor;} s; } u; u.s.addr = func; u.s.adjustor = 0;
	#endif
 
	(void) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)();
 
}
In this code 348 is offset CCSPlayer::FlashlightTurnOn() function in Virtual Table from Virtual Table Offset List page.

I have successfully compiled plugin, and started server with Metamod plugin and my plugin. But when I enter into client console "flashbang" command nothing happens.

In what may be a problem?
Dekart is offline
donrevan
AlliedModders Donor
Join Date: Jul 2010
Old 03-12-2012 , 16:47   Re: Some question about Virtual Offset
Reply With Quote #2

Seems like you Mixed Client commands with Server commands. They are Not the same.
I assum(because of the loop thru each Client) you want to create the Server command "flashlight" to enable the flashlight of each Player. Just use the "CON_COMMAND" MACRO to create One.

Code:
CON_COMMAND(flashlight,"Turns on flashlight for each player")
{
//Code here
}

Last edited by donrevan; 03-12-2012 at 16:48.
donrevan is offline
Dekart
Junior Member
Join Date: Mar 2012
Old 03-13-2012 , 00:53   Re: Some question about Virtual Offset
Reply With Quote #3

I added this code to code of my plugin:
Code:
CON_COMMAND(flashbang, "flashbang") 
{
	int i;
	int j;
	edict_t *pEnt;
	for (i=1; i<=64; i++)
	{
		pEnt = engine->PEntityOfEntIndex(i);
		if (pEnt && !pEnt->IsFree() && FStrEq(pEnt->GetClassName(), "player"))
		{
			gVFuncs.SomeFunc(pEnt->GetUnknown()->GetBaseEntity());
		}
	}
}
This function get control when I write command "flashbang" into server console.
(I checked this with the debugger in Visual Studio)

And then function
Code:
gVFuncs.SomeFunc(pEnt->GetUnknown()->GetBaseEntity());
also get control.

and function
Code:
(void) (reinterpret_cast<VfuncEmptyClass*>(this_ptr)->*u.mfpnew)();
get control too.

But nothing happens again

I think problem into call to virtual function, and I cannot understand why this is so.

Last edited by Dekart; 03-13-2012 at 00:57.
Dekart is offline
Dekart
Junior Member
Join Date: Mar 2012
Old 03-13-2012 , 03:45   Re: Some question about Virtual Offset
Reply With Quote #4

hm... I solved this problem, but i have new question.

How to control player's money or control the player's buying of ammunition (weapons & vests) in CS:S?
Dekart is offline
Emil
Junior Member
Join Date: May 2010
Location: Skövde, Sweden
Old 03-15-2012 , 15:44   Re: Some question about Virtual Offset
Reply With Quote #5

you can control the players money thru "CCSPlayer.m_iAccount", and helmet and west thru "CCSPlayer.m_bHasHelmet" and "CCSPlayer.m_ArmorValue"

Code:
void getOffsetInTable(SendTable* table, const std::string& propertyName, int* offset)
{
  int NumProps = table->GetNumProps();
  std::string propName = propertyName.substr(0, propertyName.find_first_of("."));

  for(int i=0; i<NumProps; i++)
  {
    SendProp* prop = table->GetProp(i);
    const char* name = prop->GetName();
    if(FStrEq(prop->GetName(), propName.c_str())){
      *offset = *offset + prop->GetOffset();
      if(prop->GetType() == DPT_DataTable){
        if(propertyName.length() > propName.length() + 1){
          getOffsetInTable(prop->GetDataTable(), propertyName.substr(propName.length() + 1), offset);
        }
      }
      return;
    }
  }
}



int findNetOffset(const std::string& className, const std::string& propertyName)
{
  ServerClass *sc = m_serverdll->GetAllServerClasses();
  while (sc)
  {
    if(FStrEq(sc->GetName(), className.c_str()))
    {
      int offset = 0;
      getOffsetInTable(sc->m_pTable, propertyName, &offset);
      return offset;
    }
    sc = sc->m_pNext;
  }

  return 0;
}



// Set the cash amount of player
void setPlayerCash(edict_t* player, int cash)
{
  m_cashOffset = findNetOffset("CCSPlayer", "m_iAccount");

  if(player && m_cashOffset){
    int* cashPtr = (int*)((unsigned char*)player->GetUnknown()->GetBaseEntity() + m_cashOffset);
    *cashPtr = cash;
  }
}



//Sets wheter or not a player is wearing a helmet
void setPlayerHelmet(edict_t* player, bool hasHelmet)
{
  m_helmetOffset = findNetOffset("CCSPlayer", "m_bHasHelmet");

  if(player && m_helmetOffset){
    bool* helmetPtr = (bool*)((unsigned char*)player->GetUnknown()->GetBaseEntity() + m_helmetOffset);
    *helmetPtr = hasHelmet;
  }
}



//Sets a players armor
void setPlayerArmor(edict_t* player, int armor)
{
  m_armorOffset = findNetOffset("CCSPlayer", "m_ArmorValue");

  if(player && m_armorOffset){
    int* armorPtr = (int*)((unsigned char*)player->GetUnknown()->GetBaseEntity() + m_armorOffset);
    *armorPtr = armor;
  }
}
You can give a player a weapon with CCSPlayer::GiveNamedItem

CSS weapon names are
  • weapon_ak47
  • weapon_aug
  • weapon_awp
  • weapon_c4
  • weapon_deagle
  • weapon_elite
  • weapon_famas
  • weapon_fiveseven
  • weapon_flashbang
  • weapon_g3sg1
  • weapon_galil
  • weapon_glock
  • weapon_hegrenade
  • weapon_knife
  • weapon_m249
  • weapon_m3
  • weapon_m4a1
  • weapon_mac10
  • weapon_mp5navy
  • weapon_p228
  • weapon_p90
  • weapon_scout
  • weapon_sg550
  • weapon_sg552
  • weapon_smokegrenade
  • weapon_tmp
  • weapon_ump45
  • weapon_usp
  • weapon_xm1014

Code:
extern CBaseEntity* CCSPlayer_GiveNamedItem(CBasePlayer *pCBE, char const* itemName, int iSubType = 0);

//392	CCSPlayer::GiveNamedItem(char  const*,int)
VFUNC_CALL2(392, CBaseEntity *, CBasePlayer, CCSPlayer_GiveNamedItem, char const*, int);



void giveItem(edict_t* player, const char* name)
{
  if(player){
    CCSPlayer_GiveNamedItem((CBasePlayer *) player->GetUnknown()->GetBaseEntity(), name);
  }
}

Last edited by Emil; 03-15-2012 at 15:45.
Emil is offline
Send a message via Skype™ to Emil
asherkin
SourceMod Developer
Join Date: Aug 2009
Location: OnGameFrame()
Old 03-15-2012 , 17:45   Re: Some question about Virtual Offset
Reply With Quote #6

Quote:
Originally Posted by Emil View Post
stuff
You shouldn't be using libstdc++ stuff (STL classes) if you're planing on releasing a Linux version.
__________________
asherkin is offline
Dekart
Junior Member
Join Date: Mar 2012
Old 03-20-2012 , 00:22   Re: Some question about Virtual Offset
Reply With Quote #7

Thank you all for your help.
Dekart is offline
Dekart
Junior Member
Join Date: Mar 2012
Old 03-21-2012 , 04:10   Re: Some question about Virtual Offset
Reply With Quote #8

I continue work above my plugin, and now i need change name of player in the game.

I found in wiki function in CCSPlayer class, that can change player name, and i found some information about this function. http://wiki.alliedmods.net/CCSPlayer#ChangeName

Code:
void CCSPlayer::ChangeName(const char* Name)
But i can't found information about how use it.

Could you tell where i can to find an examples the using it?

Last edited by Dekart; 03-21-2012 at 04:12.
Dekart is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 13:56.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode