[L4D2] Play as infected in coop

Post Python examples to help other users.
RenardDev
Junior Member
Posts: 5
Joined: Mon Jan 27, 2025 12:04 pm

[L4D2] Play as infected in coop

Postby RenardDev » Mon Jan 27, 2025 12:15 pm

Syntax: Select all

from core import echo_console
from memory import make_object, find_binary
from entities.entity import Entity
from players.entity import Player
from memory import find_binary, make_object, Convention, DataType
from memory.manager import CustomType, manager
from events.hooks import PreEvent, EventAction
from players.helpers import index_from_userid
from filters.players import PlayerIter
from listeners.tick import Delay
from memory.manager import CustomType, manager
from memory import find_binary, make_object, Convention, DataType
from entities.entity import Entity
from filters.players import PlayerIter
from random import randint
from messages import SayText
from commands.client import ClientCommand
from commands import CommandReturn
from commands import get_command_index
from entities.helpers import basehandle_from_inthandle, baseentity_from_basehandle, index_from_baseentity
from memory.hooks import PreHook, PostHook, use_pre_registers
from mathlib import Vector
import time

serverlib = find_binary('server')

#############################################################################################
#############################################################################################

class PlayerRaw(CustomType, metaclass=manager):
    SetStasis = manager.virtual_function(38, [DataType.BOOL], DataType.VOID, Convention.THISCALL)
    Spawn = manager.virtual_function(24, [], DataType.VOID, Convention.THISCALL)
    Respawn = manager.virtual_function(124, [], DataType.VOID, Convention.THISCALL)
    ForceRespawn = manager.virtual_function(347, [], DataType.VOID, Convention.THISCALL)
    InitialSpawn = manager.virtual_function(348, [], DataType.VOID, Convention.THISCALL)
    RoundRespawn = manager.virtual_function(514, [], DataType.VOID, Convention.THISCALL)
    OnEnterGhostState = manager.virtual_function(536, [], DataType.VOID, Convention.THISCALL)
    SetClass = manager.virtual_function(581, [DataType.INT], DataType.VOID, Convention.THISCALL)
    PlayerZombieAbortControl = manager.virtual_function(584, [DataType.INT, DataType.FLOAT], DataType.VOID, Convention.THISCALL)
    HandleCommand_JoinClass = manager.virtual_function(519, [DataType.INT], DataType.VOID, Convention.THISCALL)
    HandleCommand_JoinTeam = manager.virtual_function(562, [DataType.INT, DataType.INT, DataType.BOOL], DataType.VOID, Convention.THISCALL)

#############################################################################################
#############################################################################################

CCSPlayer_State_Transition = serverlib[b'\x55\x8B\xEC\x56\x8B\xF1\x8B\x2A\x2A\x2A\x2A\x2A\x57\x8B\x7D\x08\x85\xC0\x74\x2A\x83'].make_function(
    Convention.THISCALL,
    [
        DataType.POINTER,
        DataType.INT
    ],
    DataType.INT
)

CCSPlayer_BecomeGhost = serverlib[b'\x55\x8B\xEC\x53\x8B\x5D\x08\x56\x53\x8B\xF1\xE8\x2A\x2A\x2A\x2A\x84\xC0\x75\x2A\x83'].make_function(
    Convention.THISCALL,
    [
        DataType.POINTER,
        DataType.INT
    ],
    DataType.VOID
)

CBaseAbility_CreateForPlayer = serverlib[b'\x55\x8B\xEC\x83\xEC\x0C\x56\x8B\x75\x08\x85\xF6\x0F\x2A\x2A\x2A\x2A\x2A\x8B\xCE\xE8\x2A\x2A\x2A\x2A\x83\xF8\x03'].make_function(
    Convention.THISCALL,
    [
        DataType.POINTER
    ],
    DataType.POINTER
)

Tank_LeaveStasis = serverlib[b'\x56\x57\x8B\xF9\x80\xBF\x2A\x2A\x2A\x2A\x2A\x8D\xB7\x2A\x2A\x2A\x2A\x74\x2A\x8B\x86\x2A\x2A\x2A\x2A\x8B\x90\x2A\x2A\x2A\x2A\x8D\x8E\x2A\x2A\x2A\x2A\x56\xFF\xD2\xC6\x06\x02\x8B\x07\x8B\x90\x2A\x2A\x2A\x2A\x8B\xCF'].make_function(
    Convention.THISCALL,
    [
        DataType.POINTER,
    ],
    DataType.VOID
)

Tank_LeaveStasis = serverlib[b'\x56\x57\x8B\xF9\x80\xBF\x2A\x2A\x2A\x2A\x2A\x8D\xB7\x2A\x2A\x2A\x2A\x74\x2A\x8B\x86\x2A\x2A\x2A\x2A\x8B\x90\x2A\x2A\x2A\x2A\x8D\x8E\x2A\x2A\x2A\x2A\x56\xFF\xD2\xC6\x06\x02\x8B\x07\x8B\x90\x2A\x2A\x2A\x2A\x8B\xCF'].make_function(
    Convention.THISCALL,
    [
        DataType.POINTER,
    ],
    DataType.VOID
)

CTerrorPlayer_OnClientSettingsChanged = serverlib[b'\x55\x8b\xEC\x83\xEC\x14\x53\x56\x33\xC0\x57\x8B\xF1\xC7\x45\x2A\x2A\x2A\x2A\x2A\xC7\x45\x2A\x2A\x2A\x2A\x2A\xC7\x45\x2A\x2A\x2A\x2A\x2A\xC7\x45\x2A\x2A\x2A\x2A\x2A\x89\x45\xFC'].make_function(
    Convention.THISCALL,
    [
        DataType.POINTER
    ],
    DataType.VOID
)

ZombieManager_ServerActivate = serverlib[b'\x55\x8B\xEC\x51\xF3\x0F\x10\x05\x2A\x2A\x2A\x2A\x53\x56\x8B\xF1\xC6\x86'].make_function(
    Convention.THISCALL,
    [
        DataType.POINTER
    ],
    DataType.VOID
)

ZombieManager_GetRandomPZSpawnPosition = serverlib[b'\x55\x8B\xEC\x83\xEC\x1C\x53\x57\x8B\x7D\x14\x8B\xD9\x89\x5D\xF8'].make_function(
    Convention.THISCALL,
    [
        DataType.POINTER,
        DataType.INT,
        DataType.POINTER,
        DataType.POINTER
    ],
    DataType.BOOL
)

#############################################################################################
#############################################################################################

def remove_ability(player):
    inthandle = player.get_property_uint('m_customAbility')
    if not inthandle:
        return

    try:
        basehandle = basehandle_from_inthandle(inthandle)
    except:
        player.set_property_uint('m_customAbility', 0)
        return

    if not basehandle:
        player.set_property_uint('m_customAbility', 0)
        return

    try:
        baseentity = baseentity_from_basehandle(basehandle)
    except:
        player.set_property_uint('m_customAbility', 0)
        return

    if not baseentity:
        player.set_property_uint('m_customAbility', 0)
        return

    try:
        index = index_from_baseentity(baseentity)
    except:
        player.set_property_uint('m_customAbility', 0)
        return

    if index == 0 or index == 0xffffffff:
        return

    Entity(index).remove()
    player.set_property_uint('m_customAbility', 0)

def create_ability(player):
    ability = CBaseAbility_CreateForPlayer(player)
    if not ability:
        return

    ability_entity = make_object(Entity, ability)
    player.set_property_uint('m_customAbility', ability_entity.inthandle)

def recreate_ability(player):
    remove_ability(player)
    create_ability(player)

def change_infected_class(player, nclass):
    try:
        player_raw = make_object(PlayerRaw, player)
    except:
        return

    for weapon in player.weapons():
        weapon.remove()

    player_raw.SetClass(nclass)

    recreate_ability(player)

#############################################################################################
#############################################################################################

ZombieManager = None

@PreHook(ZombieManager_ServerActivate)
def PreZombieManager_ServerActivate(args):
    ZombieManager = args[0]

@PreHook(CTerrorPlayer_OnClientSettingsChanged)
def PreCTerrorPlayer_OnClientSettingsChanged(args): # Fix crash
    player = make_object(Player, args[0])
    if not player.is_bot() and player.team == 3:
        return 0

#############################################################################################
#############################################################################################

@PreEvent('player_spawn')
def on_player_spawn(game_event):
    userid = int(game_event['userid'])

    try:
        player = Player(index_from_userid(userid))
    except:
        return EventAction.CONTINUE

    if player.team != 3:
        return EventAction.CONTINUE
    
    if not player.is_bot():
        return EventAction.CONTINUE
    
    if player.get_property_int('m_zombieClass') != 8:
        return EventAction.CONTINUE

    Delay(1, Tank_LeaveStasis, (player, ))

    return EventAction.CONTINUE

@PreEvent('player_death')
def on_player_death(game_event):
    userid = int(game_event['userid'])

    try:
        player = Player(index_from_userid(userid))
    except:
        return EventAction.CONTINUE

    if player.team != 3:
        return EventAction.CONTINUE

    if player.is_bot():
        return EventAction.CONTINUE

    def respawn(player):
        CCSPlayer_State_Transition(player, 8)
        CCSPlayer_BecomeGhost(player, 1)
        CCSPlayer_State_Transition(player, 6)
        CCSPlayer_BecomeGhost(player, 1)

        if randint(1, 8) == 8:
            zombie_class = 8 # Tank
        else:
            zombie_class = randint(1, 6) # Smoker, Boomer, Hunter, Slitter, Jockey, Charger

        if ZombieManager:
            origin = Vector(0.0, 0.0, 0.0)
            if ZombieManager_GetRandomPZSpawnPosition(ZombieManager, zombie_class, 5, player, origin):
                player.teleport(origin)

        change_infected_class(player, zombie_class)

    Delay(3, respawn, (player, ))

    return EventAction.CONTINUE

@PreEvent('round_start')
def on_round_start(game_event):
    for player in PlayerIter('all'):
        if player.team != 3:
            continue

        if player.is_bot():
            continue

        def respawn(player):
            CCSPlayer_State_Transition(player, 8)
            CCSPlayer_BecomeGhost(player, 1)
            CCSPlayer_State_Transition(player, 6)
            CCSPlayer_BecomeGhost(player, 1)

            if randint(1, 8) == 8:
                zombie_class = 8 # Tank
            else:
                zombie_class = randint(1, 6) # Smoker, Boomer, Hunter, Slitter, Jockey, Charger

            if ZombieManager:
                origin = Vector(0.0, 0.0, 0.0)
                if ZombieManager_GetRandomPZSpawnPosition(ZombieManager, zombie_class, 5, player, origin):
                    player.teleport(origin)

            change_infected_class(player, zombie_class)

        Delay(3, respawn, (player, ))

    return EventAction.CONTINUE

#############################################################################################
#############################################################################################

# 1 - smoker
# 2 - boomer
# 3 - hunter
# 4 - slitter
# 5 - jockey
# 6 - charger
# 8 - tank

@ClientCommand('joininfected')
def on_joininfected(command, index):
    player = Player(index)
    if player.team == 3 and player.steamid != 'STEAM_1:0:X': # Change admin STEAMID
        return CommandReturn.BLOCK

    player.team = 3

    CCSPlayer_State_Transition(player, 8)
    CCSPlayer_BecomeGhost(player, 1)
    CCSPlayer_State_Transition(player, 6)
    CCSPlayer_BecomeGhost(player, 1)

    if randint(1, 8) == 8:
        zombie_class = 8 # Tank
    else:
        zombie_class = randint(1, 6) # Smoker, Boomer, Hunter, Slitter, Jockey, Charger

    if ZombieManager:
        origin = Vector(0.0, 0.0, 0.0)
        if ZombieManager_GetRandomPZSpawnPosition(ZombieManager, zombie_class, 5, player, origin):
            player.teleport(origin)

    change_infected_class(player, zombie_class)

    return CommandReturn.BLOCK

@ClientCommand('joinsurvival')
def on_joinsurvival(command, index):
    player = Player(index)

    player.client_command('jointeam 2')
    player.client_command('sb_takecontrol')

    return CommandReturn.BLOCK

Return to “Code examples / Cookbook”

Who is online

Users browsing this forum: No registered users and 110 guests