Making certain entities invisible to certain players

Post Python examples to help other users.
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Making certain entities invisible to certain players

Postby iPlayer » Sat Sep 17, 2016 10:34 am

... or you could even make certain entities be transmitted only to one player.

Syntax: Select all

from entities import CheckTransmitInfo
from entities.entity import Entity
from entities.helpers import index_from_edict
from entities.hooks import EntityCondition, EntityPreHook
from memory import make_object
from players.entity import Player


def transmit_filter(entity, player):
if player.name != "iPlayer":
return True

if entity.classname != "prop_physics_multiplayer":
return True

return False


# You can define your own entity_condition function that should return
# True for entities whose SetTransmit method we want to hook
entity_condition = EntityCondition.equals_entity_classname(
"prop_physics_multiplayer")


@EntityPreHook(entity_condition, 'set_transmit')
def pre_set_transmit(args):
entity = make_object(Entity, args[0])
edict = make_object(CheckTransmitInfo, args[1]).client
player = Player(index_from_edict(edict))

# We always transmit the player to himself. If we don't, bad things happen.
if player.index == entity.index:
return None

return None if transmit_filter(entity, player) else False


Things to change:

Syntax: Select all

def transmit_filter(entity, player):
if player.name != "iPlayer":
return True

if entity.classname != "prop_physics_multiplayer":
return True

return False

This filter receives two arguments: entity for transmission and the player to transmit this entity to. If transmission should happen, filter must return True, otherwise False.

Syntax: Select all

entity_condition = EntityCondition.equals_entity_classname(
"prop_physics_multiplayer")

Basically, entity_condition is a function that receives an Entity instance and returns True if that's the entity we want to set the hook on. Different entity classes have different SetTransmit methods, so if we set the hook on CBaseCombatCharacter::SetTransmit, transmitting of the CSprite won't get hooked.

If you want to hook player transmission (e.g. make certain players invisible to some other players), you can go with

Syntax: Select all

entity_condition = EntityCondition.is_player


Reference for the first argument SetTransmit receives:
https://github.com/ValveSoftware/source-sdk-2013/blob/master/mp/src/public/iservernetworkable.h#L37

This example has been written after I found the snippet of SM code provided by Bristwex

Syntax: Select all

SDKHook(entity, SDKHook_SetTransmit, Hook_SetTransmit); 

public Action:Hook_SetTransmit(entity, client)
{
if (<entity and client checks>)
{
return Plugin_Continue;
}
return Plugin_Handled;
}
Last edited by iPlayer on Fri May 05, 2017 3:02 pm, edited 3 times in total.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Making certain entities invisible to certain players

Postby iPlayer » Sat Sep 17, 2016 10:54 am

L'In20Cible wrote:https://github.com/Source-Python-Dev-Team/Source.Python/search?utf8=%E2%9C%93&q=set_transmit
https://github.com/Source-Python-Dev-Te ... p.cpp#L513


Thanks, completely missed that. Updated my previous post.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: Making certain entities invisible to certain players

Postby iPlayer » Fri May 05, 2017 3:05 pm

Updated the first post. Added the following check to the hook:

Syntax: Select all

# We always transmit the player to himself. If we don't, bad things happen.
if player.index == entity.index:
return None


In all games "bad things" is player not being able to see themselves moving, i.e. they will be stuck on their screen. Apparently on CS:GO (and only on Windows SRCDS) the server will just disconnect the player with the following error:

Code: Select all

Host_Error: CL_ReadPreserveEnt: u.m_nNewEntity == MAX_EDICTS


To avoid further problems, I decided to enforce this check into this example. There's really no reason not to transmit the player to himself.

Thanks to EmilioK for narrowing down the issue.
Image /id/its_iPlayer
My plugins: Map Cycle • Killstreaker • DeadChat • Infinite Jumping • TripMines • AdPurge • Bot Damage • PLRBots • Entity AntiSpam

Hail, Companion. [...] Hands to yourself, sneak thief. Image
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Making certain entities invisible to certain players

Postby decompile » Mon Apr 09, 2018 2:57 am

Sorry for bumping older threads, but I'm curerently working with it.

How do I actually call "set_transmit"? Or does it get automatically called?

Also in the Hooks, which returns can you use which has effect on the hook? Like "return False", "return None"?
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Making certain entities invisible to certain players

Postby Ayuto » Mon Apr 09, 2018 6:16 am

pre_set_transmit is registered as a hook and gets called automatically.

Possible return values depend on the return type of the hooked function. If the hooked function for example returns an integer, you can return any number in the valid range of that integer type. This will cause the hooked functions not being called and your return value is returned to the caller instead. If you return None or if you simply have no return statement, the original function is called.

If the hooked function has no return type (void), which is the current case, then returning anything except None will block the hooked function from being called.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Making certain entities invisible to certain players

Postby decompile » Mon Apr 09, 2018 6:44 am

Thanks,

so it gets called automatically, but how do I know when/how it gets called? I mean I can debug print it and see it myself, but kind of want to understand it. What does it call and will it just print in an endless loop every frame?
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Making certain entities invisible to certain players

Postby Ayuto » Mon Apr 09, 2018 10:57 am

To understand when it's getting called you need to dig in the SDK or the server binaries. But I can tell you that the function is getting called to set the entities that should be transmitted to which players.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: Making certain entities invisible to certain players

Postby decompile » Tue Apr 10, 2018 11:02 am

Sorry for my miss-leading questions, kind of weird to understand what I kind of want to achieve with it.

To activate or deactivate it, I can simply just do a if else statement in the PreHook?

like

Syntax: Select all

if player.index not in set_transmit_dict:
return


and It would only hide if the index is in set_transmit_dict?
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: Making certain entities invisible to certain players

Postby Ayuto » Tue Apr 10, 2018 4:12 pm

Exactly!

Return to “Code examples / Cookbook”

Who is online

Users browsing this forum: No registered users and 30 guests