Page 1 of 1

BumpWeapon

Posted: Sat Mar 14, 2015 3:25 pm
by MrMalina
I use this code:

Syntax: Select all

# =============================================================================
# >> IMPORTS
# =============================================================================
# Memory
import memory

from memory import DataType
from memory import Convention

from memory.hooks import PreHook

# Players
from weapons.entity import WeaponEntity
from players.helpers import userid_from_pointer
from players.helpers import index_from_userid

# Core
from core import PLATFORM


# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
# Get the server binary
server = memory.find_binary('cstrike/bin/server')

if PLATFORM == 'windows':
identifier = b'\x55\x8B\xEC\x83\xEC\x38\x89\x4D\xF4'
else:
identifier = '_ZN9CCSPlayer10BumpWeaponEP17CBaseCombatWeapon'

BUMP_WEAPON = server[identifier].make_function(
Convention.THISCALL,
(DataType.POINTER, DataType.POINTER, DataType.POINTER, DataType.INT),
DataType.VOID
)


# =============================================================================
# >> CALLBACKS
# =============================================================================
@PreHook(BUMP_WEAPON)
def pre_bump_weapon(args):
index = index_from_userid(userid_from_pointer(args[0]))

test = memory.make_object(WeaponEntity, args[1])

return True


But when I return True or False at the end of the event, I get the following:
The attachment Безымянный.jpg is no longer available

https://www.dropbox.com/s/o0npfgl6e1umupb/no_name.png?dl=0

I used the data from the source python extension:

Code: Select all

[CCSPlayer::BumpWeapon]
shortname = "BumpWeapon"
sig = " 55 8B EC 83 EC 38 89 4D F4"
symbol = "_ZN9CCSPlayer10BumpWeaponEP17CBaseCombatWeapon"
param = "pp)i"
convention = "thiscall"

Posted: Sat Mar 14, 2015 3:41 pm
by satoon101
Why are you using index_from_userid and userid_from_pointer instead of just using index_from_pointer? And, I don't believe your WeaponEntity line would work either. Just get the index from the weapon's pointer and use that to get the WeaponEntity instance.

Also, CBasePlayer::BumpWeapon is a virtual function that is already implemented for both orangebox and csgo within the entities data.

Posted: Sat Mar 14, 2015 3:53 pm
by MrMalina

Syntax: Select all

from players.helpers import index_from_pointer

Posted: Sat Mar 14, 2015 3:56 pm
by Ayuto
The problem is that your arguments tuple is wrong. The WeaponEntity line just just work fine, because it inherits from BaseEntity.

Syntax: Select all

# =============================================================================
# >> IMPORTS
# =============================================================================
# Memory
import memory

from memory import DataType
from memory import Convention

from memory.hooks import PreHook

# Players
from weapons.entity import WeaponEntity
from players.entity import PlayerEntity

# Core
from core import PLATFORM


# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
# Get the server binary
server = memory.find_binary('cstrike/bin/server')

if PLATFORM == 'windows':
identifier = b'\x55\x8B\xEC\x83\xEC\x38\x89\x4D\xF4'
else:
identifier = '_ZN9CCSPlayer10BumpWeaponEP17CBaseCombatWeapon'

BUMP_WEAPON = server[identifier].make_function(
Convention.THISCALL,
(DataType.POINTER, DataType.POINTER),
DataType.BOOL
)


# =============================================================================
# >> CALLBACKS
# =============================================================================
@PreHook(BUMP_WEAPON)
def pre_bump_weapon(args):
player = memory.make_object(PlayerEntity, args[0])
weapon = memory.make_object(WeaponEntity, args[1])

print(player.name)
print(weapon.classname)

# Return False to prevent the player from picking up the weapon. True
# would tell the engine that the player has picked it up, so this might
# causes weird behaviour.
return False

Posted: Sat Mar 14, 2015 4:00 pm
by MrMalina
How further to learn, what arguments to use?

This code gives me the same error:

Syntax: Select all

# =============================================================================
# >> IMPORTS
# =============================================================================
# Memory
import memory

from memory import DataType
from memory import Convention

from memory.hooks import PreHook

# Players
from weapons.entity import WeaponEntity
from players.entity import PlayerEntity

# Core
from core import PLATFORM


# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
# Get the server binary
server = memory.find_binary('cstrike/bin/server')

if PLATFORM == 'windows':
identifier = b'\x55\x8B\xEC\x83\xEC\x38\x89\x4D\xF4'
else:
identifier = '_ZN9CCSPlayer10BumpWeaponEP17CBaseCombatWeapon'

BUMP_WEAPON = server[identifier].make_function(
Convention.THISCALL,
(DataType.POINTER, DataType.POINTER),
DataType.BOOL
)


# =============================================================================
# >> CALLBACKS
# =============================================================================
@PreHook(BUMP_WEAPON)
def pre_bump_weapon(args):
player = memory.make_object(PlayerEntity, args[0])
weapon = memory.make_object(WeaponEntity, args[1])

print(player.name)
print(weapon.classname)

# Return False to prevent the player from picking up the weapon. True
# would tell the engine that the player has picked it up, so this might
# causes weird behaviour.
return False


Even if I return True, there is an error

https://www.dropbox.com/s/qmqbf4fuih87pj8/2.png?dl=0

Posted: Sat Mar 14, 2015 4:07 pm
by Ayuto
Just take a look at the function's prototype:[cpp]bool CBasePlayer::BumpWeapon( CBaseCombatWeapon *pWeapon )[/cpp]As you can this this is a method, which takes one argument (a CBaseCombatWeapon pointer) and returns a boolean. Since this is a member function, there is another argument, which is called the "this" pointer. It's the same like Python's "self" argument in class methods. This is why there are two elements in the arguments tuple.

Edit: Just tested this on my server and it's working fine.

Posted: Sat Mar 14, 2015 4:13 pm
by MrMalina
I restarted the server after a couple of falls and it worked : / Thank you.

Posted: Sat Mar 14, 2015 4:15 pm
by satoon101
We made some changes recently to remove duplicate import locations. All <type>_from_<othertype> functions that were in both players.helpers and entities.helpers are now only forwarded to entities.helpers.

As far as BaseEntity classes and make_object, if you don't pass in the index, it never stores the private attributes for index, edict, or pointer. How does it access them if they are never stored?

Posted: Sat Mar 14, 2015 4:20 pm
by Ayuto
make_object() calls <class>._obj(<ptr>) and we have added this as a class method to BaseEntity. https://github.com/Source-Python-Dev-Team/Source.Python/blob/master/addons/source-python/packages/source-python/entities/entity.py#L149

Posted: Sat Mar 14, 2015 4:23 pm
by satoon101
Oh yeah, totally spaced that... That's what I get for replying while busy at work.