moved a bunch of reconnecting logic over to sourcemod again and just simply give the bot more time for connecting than previous
This commit is contained in:
parent
44e5af3586
commit
783657d95b
@ -14,19 +14,9 @@ import json
|
|||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
import glob
|
import glob
|
||||||
|
import pwd
|
||||||
|
|
||||||
restart_time = datetime.datetime.now() + datetime.timedelta(hours=3)
|
restart_time = datetime.datetime.now() + datetime.timedelta(hours=3)
|
||||||
block_connection = False
|
|
||||||
the_undesired_crash_counter = 0 #hate this monkey solution
|
|
||||||
shoot_distance = 450.0
|
|
||||||
shoot_burst_cycles = 4
|
|
||||||
enemy_chase_distance = 450.0
|
|
||||||
team_follow_distance = 800.0
|
|
||||||
infect_chase_distance = 300.0
|
|
||||||
momentum_hold_seconds = 1.4
|
|
||||||
min_forward_wait = 6
|
|
||||||
max_forward_wait = 12
|
|
||||||
last_forward_time = 0.0
|
|
||||||
|
|
||||||
whoami = subprocess.getoutput("whoami")
|
whoami = subprocess.getoutput("whoami")
|
||||||
with open(f'/home/{whoami}/ze_runner/config.json') as jsonfile:
|
with open(f'/home/{whoami}/ze_runner/config.json') as jsonfile:
|
||||||
@ -49,10 +39,6 @@ def writeCfgInput(Input_user):
|
|||||||
time.sleep(0.35)
|
time.sleep(0.35)
|
||||||
open(looptestPath, 'w').close() #clearing file.
|
open(looptestPath, 'w').close() #clearing file.
|
||||||
|
|
||||||
def close_observer(observer):
|
|
||||||
observer.stop()
|
|
||||||
observer.join() #supposedly needed to clear resources again.
|
|
||||||
|
|
||||||
def clean_up_files():
|
def clean_up_files():
|
||||||
#deleting POSIX shared memory objects, as long as one process has them open they exist. THis is to prevent /dev/shm from being full
|
#deleting POSIX shared memory objects, as long as one process has them open they exist. THis is to prevent /dev/shm from being full
|
||||||
#due to steam child processes.
|
#due to steam child processes.
|
||||||
@ -61,8 +47,12 @@ def clean_up_files():
|
|||||||
for pattern in ["/tmp/steam*", "/tmp/dbus*", "/tmp/pressure*", "/tmp/tigervnc*", "/tmp/dumps*", "/dev/shm/u100*"]:
|
for pattern in ["/tmp/steam*", "/tmp/dbus*", "/tmp/pressure*", "/tmp/tigervnc*", "/tmp/dumps*", "/dev/shm/u100*"]:
|
||||||
for path in glob.glob(pattern):
|
for path in glob.glob(pattern):
|
||||||
subprocess.run(["rm", "-rf", path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
subprocess.run(["rm", "-rf", path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
#users should only have permissions to delete their own files probably
|
|
||||||
|
|
||||||
|
#clean up the game cache as it otherwise just keeps growing in gigabyte size
|
||||||
|
subprocess.run(["rm", "-rf", f"/home/{whoami}/.steam/steam/steamapps/common/Counter-Strike Source/cstrike/cache"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
|
|
||||||
|
def check_if_bz2_downloading():
|
||||||
|
#users should only have permissions to delete their own files probably
|
||||||
#check if any bz2 files left over.
|
#check if any bz2 files left over.
|
||||||
for f in glob.glob(f"/home/{whoami}/.steam/steam/steamapps/common/Counter-Strike Source/cstrike/download/**/*.bz2", recursive=True):
|
for f in glob.glob(f"/home/{whoami}/.steam/steam/steamapps/common/Counter-Strike Source/cstrike/download/**/*.bz2", recursive=True):
|
||||||
file_size = None
|
file_size = None
|
||||||
@ -77,8 +67,14 @@ def clean_up_files():
|
|||||||
break
|
break
|
||||||
file_size = cur_file_size
|
file_size = cur_file_size
|
||||||
|
|
||||||
#clean up the game cache as it otherwise just keeps growing in gigabyte size
|
def delete_bsp_files():
|
||||||
subprocess.run(["rm", "-rf", f"/home/{whoami}/.steam/steam/steamapps/common/Counter-Strike Source/cstrike/cache"], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
#quite a more radical approach to just always delete all maps, well the download should be quick and the remaining bots have the bsp in memory...
|
||||||
|
#the bots would have struggle connecting sometimes due to bsp files that were already downloaded before hand (maybe corrupted?)
|
||||||
|
for f in glob.glob(f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/download/maps/*"):
|
||||||
|
#ai slop IF statement for checking if file modified less than 10 minutes ago.
|
||||||
|
if time.time() - os.path.getmtime(f) < 600:
|
||||||
|
continue
|
||||||
|
subprocess.run(["rm", "-rf", f], stdout=subprocess.PIPE)
|
||||||
|
|
||||||
def exit_handler():
|
def exit_handler():
|
||||||
print('reached exithandler')
|
print('reached exithandler')
|
||||||
@ -87,90 +83,11 @@ def exit_handler():
|
|||||||
kill_owned_process("pidof xterm")
|
kill_owned_process("pidof xterm")
|
||||||
|
|
||||||
clean_up_files()
|
clean_up_files()
|
||||||
|
check_if_bz2_downloading()
|
||||||
|
delete_bsp_files()
|
||||||
|
|
||||||
subprocess.getoutput(f"pkill -9 -u {whoami}")
|
subprocess.getoutput(f"pkill -9 -u {whoami}")
|
||||||
|
|
||||||
def bot_process_movement(input_line):
|
|
||||||
try:
|
|
||||||
dist_target = input_line[input_line.index("dist_target:") + len("dist_target:"):input_line.index("enemy_distance")]
|
|
||||||
enemy_distance = input_line[input_line.index("enemy_distance:") + len("enemy_distance:"):input_line.index("targeteam:")]
|
|
||||||
targeteam = input_line[input_line.index("targeteam:") + len("targeteam:"):input_line.index("state:")]
|
|
||||||
state = input_line[input_line.index("state:") + len("state:"):]
|
|
||||||
|
|
||||||
state = int(state.strip())
|
|
||||||
dist_target = float(dist_target)
|
|
||||||
enemy_distance = float(enemy_distance)
|
|
||||||
targeteam = int(targeteam)
|
|
||||||
except (ValueError, IndexError):
|
|
||||||
# Ignore malformed movement packets instead of crashing the main loop.
|
|
||||||
return
|
|
||||||
|
|
||||||
global last_forward_time
|
|
||||||
strInput = "cl_minmodels 1; wait 2; "
|
|
||||||
|
|
||||||
if targeteam == 3:
|
|
||||||
strInput = "cl_minmodels 1; wait 2; "
|
|
||||||
|
|
||||||
def forward_burst(wait_ticks):
|
|
||||||
return f"+forward; wait {wait_ticks}; -forward; "
|
|
||||||
|
|
||||||
is_aggressive_state = state >= 3 or state == 1 or state == 8
|
|
||||||
far_from_team = dist_target > team_follow_distance
|
|
||||||
enemy_close = enemy_distance <= enemy_chase_distance
|
|
||||||
enemy_very_close = enemy_distance <= infect_chase_distance
|
|
||||||
very_close_to_team = dist_target < (team_follow_distance * 0.35)
|
|
||||||
momentum_active = time.time() - last_forward_time < momentum_hold_seconds
|
|
||||||
|
|
||||||
# Decide one primary forward burst to avoid conflicting movement bursts in a single packet.
|
|
||||||
forward_ticks = 0
|
|
||||||
if far_from_team:
|
|
||||||
# Strong regroup push when separated from teammates.
|
|
||||||
forward_ticks = random.randint(min_forward_wait, max_forward_wait + 2)
|
|
||||||
elif enemy_close:
|
|
||||||
# Controlled chase pressure when enemy is in range.
|
|
||||||
forward_ticks = random.randint(min_forward_wait - 1, max_forward_wait - 1)
|
|
||||||
elif is_aggressive_state or momentum_active:
|
|
||||||
# Keep motion alive without overcommitting.
|
|
||||||
forward_ticks = 2
|
|
||||||
|
|
||||||
# Prevent overshooting teammates when no nearby threat.
|
|
||||||
if very_close_to_team and not enemy_close:
|
|
||||||
forward_ticks = min(forward_ticks, 2)
|
|
||||||
|
|
||||||
if forward_ticks > 0:
|
|
||||||
strInput += forward_burst(forward_ticks)
|
|
||||||
last_forward_time = time.time()
|
|
||||||
else:
|
|
||||||
strInput += "wait 2;"
|
|
||||||
|
|
||||||
if enemy_very_close:
|
|
||||||
# Close-range commit with a short firing hold.
|
|
||||||
strInput += "+attack; wait 16; -attack; wait 4; "
|
|
||||||
|
|
||||||
if dist_target <= team_follow_distance and not enemy_very_close:
|
|
||||||
# Lighter, steadier strafes while maintaining formation.
|
|
||||||
strafe_pulses = 1 if very_close_to_team else 2
|
|
||||||
strInput = strinput_append(strInput, strafe_pulses)
|
|
||||||
if enemy_distance <= shoot_distance:
|
|
||||||
for _ in range(shoot_burst_cycles):
|
|
||||||
strInput += "+attack; wait 12; -attack; wait 4; "
|
|
||||||
#print('strInput final:', strInput)
|
|
||||||
writeCfgInput(strInput)
|
|
||||||
|
|
||||||
def strinput_append(strInput, nth):
|
|
||||||
if nth <= 0:
|
|
||||||
return strInput
|
|
||||||
|
|
||||||
direction_left = random.choice([True, False])
|
|
||||||
for _ in range(nth):
|
|
||||||
# Keep direction for a pulse to reduce jitter, occasionally switch.
|
|
||||||
if direction_left:
|
|
||||||
strInput += f" +moveleft; wait {random.randint(10, 16)}; -moveleft; "
|
|
||||||
else:
|
|
||||||
strInput += f" +moveright; wait {random.randint(10, 16)}; -moveright; "
|
|
||||||
if random.random() < 0.30:
|
|
||||||
direction_left = not direction_left
|
|
||||||
return strInput
|
|
||||||
|
|
||||||
def kill_user_owned_pid(pid):
|
def kill_user_owned_pid(pid):
|
||||||
#print('pid: ', pid, ' killed')
|
#print('pid: ', pid, ' killed')
|
||||||
pid = int(pid.strip())
|
pid = int(pid.strip())
|
||||||
@ -226,97 +143,12 @@ def cpulimit_pid_of_game():
|
|||||||
#cmd = f"cpulimit --pid={pid} --limit=55 --background > /dev/null 2>&1"
|
#cmd = f"cpulimit --pid={pid} --limit=55 --background > /dev/null 2>&1"
|
||||||
subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).communicate()[0]
|
subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE).communicate()[0]
|
||||||
|
|
||||||
def my_file_created_function(event_path):
|
time.sleep(3)
|
||||||
#print(f"New file created: {event_path}")
|
for source_engine_lock in glob.glob("/tmp/source_engine_*"):
|
||||||
if event_path.startswith("/tmp/source_engine") and event_path.endswith(".lock"):
|
subprocess.run(["rm", "-rf", source_engine_lock], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||||
subprocess.run(["rm", "-rf", event_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
overwrite_file_access()
|
||||||
return
|
|
||||||
if not event_path.lower().endswith(".bsp.bz2"):
|
|
||||||
return
|
|
||||||
|
|
||||||
global block_connection
|
|
||||||
block_connection = True
|
|
||||||
overwrite_file_access() #set chmod once for the bsp bz2 file.
|
|
||||||
file_size = None
|
|
||||||
|
|
||||||
while True:
|
|
||||||
if not os.path.exists(event_path):
|
|
||||||
print(f'finished the bz2 file {event_path}')
|
|
||||||
break
|
|
||||||
|
|
||||||
owner = pwd.getpwuid(os.stat(event_path).st_uid).pw_name
|
|
||||||
if whoami == owner: # we are the user that owns the file on disk
|
|
||||||
cur_file_size = os.path.getsize(event_path)
|
|
||||||
if file_size == cur_file_size:
|
|
||||||
print(f"Deleting {event_path} due to being stuck on download.")
|
|
||||||
subprocess.run(["rm", "-rf", event_path], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
|
||||||
continue
|
|
||||||
file_size = cur_file_size
|
|
||||||
else:
|
|
||||||
writeCfgInput("disconnect;")
|
|
||||||
time.sleep(10)
|
|
||||||
|
|
||||||
overwrite_file_access() #set chmod for the actual bsp file
|
|
||||||
global the_undesired_crash_counter
|
|
||||||
the_undesired_crash_counter = 0
|
|
||||||
block_connection = False
|
|
||||||
|
|
||||||
class NewFileHandler(FileSystemEventHandler):
|
|
||||||
def on_created(self, event):
|
|
||||||
my_file_created_function(event.src_path)
|
|
||||||
|
|
||||||
def handle_temp_files():
|
|
||||||
#mostly its just downloading maps that we will be doing
|
|
||||||
root_dir = f"/tmp"
|
|
||||||
event_handler = NewFileHandler()
|
|
||||||
observer = Observer()
|
|
||||||
# Schedule the observer to watch the root directory and its subdirectories recursively
|
|
||||||
observer.schedule(event_handler, root_dir, recursive=True)
|
|
||||||
observer.start()
|
|
||||||
return observer
|
|
||||||
|
|
||||||
def handle_bz2_files():
|
|
||||||
#mostly its just downloading maps that we will be doing
|
|
||||||
root_dir = f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/download"
|
|
||||||
event_handler = NewFileHandler()
|
|
||||||
observer = Observer()
|
|
||||||
# Schedule the observer to watch the root directory and its subdirectories recursively
|
|
||||||
observer.schedule(event_handler, root_dir, recursive=True)
|
|
||||||
observer.start()
|
|
||||||
return observer
|
|
||||||
|
|
||||||
def bot_process_surf(input_line):
|
|
||||||
# Placeholder to avoid crashes until surfing behavior is implemented.
|
|
||||||
return
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
|
||||||
atexit.register(exit_handler)
|
|
||||||
local_port = data_ports['udp_port']
|
|
||||||
external_port_messages = data_ports['chat_external_port']
|
|
||||||
buffer_size = 4096 #potentially not large enough?
|
|
||||||
|
|
||||||
clean_up_files()
|
|
||||||
observer = handle_bz2_files()
|
|
||||||
observer1 = handle_temp_files()
|
|
||||||
|
|
||||||
maps_folder_size = subprocess.Popen(["du", "-sh", f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/download/maps"], stdout=subprocess.PIPE).communicate()[0].decode().split("\t")[0]
|
|
||||||
#deleting when maps folder larger than some GB
|
|
||||||
if maps_folder_size.endswith("G"):
|
|
||||||
maps_folder_size = float(maps_folder_size[:-1])
|
|
||||||
if maps_folder_size > 40.0:
|
|
||||||
for f in glob.glob(f"/home/{whoami}/.steam/debian-installation/steamapps/common/Counter-Strike Source/cstrike/download/maps/*"):
|
|
||||||
subprocess.run(["rm", "-rf", f], stdout=subprocess.PIPE)
|
|
||||||
|
|
||||||
restart_sdl_and_steam()
|
|
||||||
is_bot_connected_to_ze2 = False
|
|
||||||
|
|
||||||
print('preparing to launch game....')
|
|
||||||
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
||||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
|
||||||
sock.bind(("", local_port))
|
|
||||||
sock.settimeout(5.0)
|
|
||||||
messager_name = ""
|
|
||||||
|
|
||||||
|
def launch_game():
|
||||||
#give the game some time to launch
|
#give the game some time to launch
|
||||||
fail_safe = 5
|
fail_safe = 5
|
||||||
while return_user_owned_pid("pidof cstrike_linux64") is None:
|
while return_user_owned_pid("pidof cstrike_linux64") is None:
|
||||||
@ -329,6 +161,28 @@ if __name__ == '__main__':
|
|||||||
time.sleep(10)
|
time.sleep(10)
|
||||||
cpulimit_pid_of_game()
|
cpulimit_pid_of_game()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
atexit.register(exit_handler)
|
||||||
|
local_port = data_ports['udp_port']
|
||||||
|
external_port_messages = data_ports['chat_external_port']
|
||||||
|
buffer_size = 4096 #potentially not large enough?
|
||||||
|
|
||||||
|
clean_up_files()
|
||||||
|
check_if_bz2_downloading()
|
||||||
|
delete_bsp_files()
|
||||||
|
|
||||||
|
restart_sdl_and_steam()
|
||||||
|
is_bot_connected_to_ze2 = False
|
||||||
|
print('preparing to launch game....')
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||||
|
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||||
|
sock.bind(("", local_port))
|
||||||
|
sock.settimeout(5.0)
|
||||||
|
messager_name = ""
|
||||||
|
|
||||||
|
failed_connect_count = 0
|
||||||
|
|
||||||
|
launch_game()
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
try:
|
try:
|
||||||
@ -353,52 +207,37 @@ if __name__ == '__main__':
|
|||||||
writeCfgInput(response_msg)
|
writeCfgInput(response_msg)
|
||||||
if ip != data_ports['ovh_ip']:
|
if ip != data_ports['ovh_ip']:
|
||||||
continue
|
continue
|
||||||
elif data == "rtv":
|
|
||||||
response_msg = "say rtv"
|
|
||||||
writeCfgInput(response_msg)
|
|
||||||
elif data == "bot kicked server full":
|
elif data == "bot kicked server full":
|
||||||
print('bot kicked server full: ', datetime.datetime.now().time())
|
print('bot kicked server full: ', datetime.datetime.now().time())
|
||||||
elif "autismo connected to ze" == data:
|
elif "autismo connected to ze" == data:
|
||||||
print('Bot connected to ze!')
|
print('Bot connected to ze!')
|
||||||
is_bot_connected_to_ze2 = False
|
is_bot_connected_to_ze2 = False
|
||||||
the_undesired_crash_counter = 0
|
failed_connect_count = 0
|
||||||
elif "not connected to ze2" == data:
|
elif "not connected to ze2" == data:
|
||||||
is_bot_connected_to_ze2 = False
|
is_bot_connected_to_ze2 = False
|
||||||
elif "autismo connected to ze2" == data:
|
elif "autismo connected to ze2" == data:
|
||||||
print('Bot connected to ze2!')
|
print('Bot connected to ze2!')
|
||||||
the_undesired_crash_counter = 0
|
|
||||||
is_bot_connected_to_ze2 = True
|
is_bot_connected_to_ze2 = True
|
||||||
|
failed_connect_count = 0
|
||||||
elif "connect to ze" == data or ("connect to ze2" == data and not is_bot_connected_to_ze2):
|
elif "connect to ze" == data or ("connect to ze2" == data and not is_bot_connected_to_ze2):
|
||||||
if datetime.datetime.now() >= restart_time or return_user_owned_pid("pidof cstrike_linux64") is None or the_undesired_crash_counter >= 5:
|
if datetime.datetime.now() >= restart_time or return_user_owned_pid("pidof cstrike_linux64") is None:
|
||||||
#it already finished downloading the contnet, it just cant connect. probably stuck. shitty solution welp
|
|
||||||
kill_owned_process("pidof cstrike_linux64")
|
kill_owned_process("pidof cstrike_linux64")
|
||||||
sock.close()
|
sock.close()
|
||||||
close_observer(observer)
|
print('exiting after running for several hours.')
|
||||||
close_observer(observer1)
|
|
||||||
print('exiting after running the game for several hours or game being stuck on map change.')
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
elif not block_connection: #need this check to prevent connection spam during content downloading.
|
print('data: ', data)
|
||||||
print('data: ', data, ' the_undesired_crash_counter: ', the_undesired_crash_counter)
|
overwrite_file_access()
|
||||||
the_undesired_crash_counter += 1
|
|
||||||
bot_connect(data)
|
bot_connect(data)
|
||||||
|
failed_connect_count += 1
|
||||||
|
if failed_connect_count >= 2:
|
||||||
|
kill_owned_process("pidof cstrike_linux64")
|
||||||
|
sock.close()
|
||||||
|
print('exiting after running for several hours.')
|
||||||
|
sys.exit(1)
|
||||||
elif "clientmessage:" in data:
|
elif "clientmessage:" in data:
|
||||||
messager_name = data.split("clientmessage:", 1)[1].split(f" {data_ports['magic_secret']}")[0]
|
messager_name = data.split("clientmessage:", 1)[1].split(f" {data_ports['magic_secret']}")[0]
|
||||||
databyte_send_message = messager_name + data.split(f"{data_ports['magic_secret']}")[1]
|
databyte_send_message = messager_name + data.split(f"{data_ports['magic_secret']}")[1]
|
||||||
sock.sendto(databyte_send_message.encode(), (data_ports["discord_bot_ip"], external_port_messages))
|
sock.sendto(databyte_send_message.encode(), (data_ports["discord_bot_ip"], external_port_messages))
|
||||||
#print('databyte_send_message: ', databyte_send_message)
|
#print('databyte_send_message: ', databyte_send_message)
|
||||||
elif data.startswith("dist_target:"):
|
|
||||||
bot_process_movement(data)
|
|
||||||
elif data.startswith("surfing:"):
|
|
||||||
bot_process_surf(data)
|
|
||||||
elif data.startswith("hull info:"):
|
|
||||||
hull_info = data[data.index("hull info:") + len("hull info:"):]
|
|
||||||
strInput = ""
|
|
||||||
if hull_info == "jump":
|
|
||||||
strInput += "+jump; wait 5; -jump; +duck; wait 50; -duck; wait 5; "
|
|
||||||
elif hull_info == "crouch":
|
|
||||||
strInput += "+duck; wait 50; -duck; wait 5; "
|
|
||||||
writeCfgInput(strInput)
|
|
||||||
finally:
|
finally:
|
||||||
sock.close()
|
sock.close()
|
||||||
close_observer(observer)
|
|
||||||
close_observer(observer1)
|
|
||||||
|
|||||||
@ -29,8 +29,6 @@ int g_WriteHead[MAXPLAYERS+1]; // where were writing next
|
|||||||
int g_FrameCount[MAXPLAYERS+1]; // total frames captured
|
int g_FrameCount[MAXPLAYERS+1]; // total frames captured
|
||||||
int g_DelayTicks = 128; // delay
|
int g_DelayTicks = 128; // delay
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int ports[7] = {48470, 48471, 48472, 48473, 48474, 48479, 48480}; //last three indexes are ports its sending udp from in plugin
|
int ports[7] = {48470, 48471, 48472, 48473, 48474, 48479, 48480}; //last three indexes are ports its sending udp from in plugin
|
||||||
int server_ports[2] = {27015, 27035}; //server ports: ze, ze2
|
int server_ports[2] = {27015, 27035}; //server ports: ze, ze2
|
||||||
|
|
||||||
@ -66,7 +64,7 @@ public void OnPluginStart()
|
|||||||
connect_socket();
|
connect_socket();
|
||||||
chat_cooldown = false;
|
chat_cooldown = false;
|
||||||
|
|
||||||
g_hTimer_bot_connect = CreateTimer(90.0, bot_check_connect, _, TIMER_REPEAT);
|
g_hTimer_bot_connect = CreateTimer(60.0, bot_check_connect, _, TIMER_REPEAT);
|
||||||
g_hTimer_pressing = CreateTimer(2.0, check_team, _, TIMER_REPEAT);
|
g_hTimer_pressing = CreateTimer(2.0, check_team, _, TIMER_REPEAT);
|
||||||
|
|
||||||
target_client[1] = -1;
|
target_client[1] = -1;
|
||||||
@ -95,6 +93,30 @@ public void OnPluginEnd()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnMapEnd()
|
||||||
|
{
|
||||||
|
int autism_bot_counter = 0;
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (IsValidClient(i) && specific_bot_player[i] != -1)
|
||||||
|
{
|
||||||
|
autism_bot_counter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 1; i <= MaxClients; i++)
|
||||||
|
{
|
||||||
|
if (autism_bot_counter <= 1)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (IsValidClient(i) && specific_bot_player[i] != -1)
|
||||||
|
{
|
||||||
|
KickClient(i);
|
||||||
|
autism_bot_counter--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2])
|
public void OnPlayerRunCmdPost(int client, int buttons, int impulse, const float vel[3], const float angles[3], int weapon, int subtype, int cmdnum, int tickcount, int seed, const int mouse[2])
|
||||||
{
|
{
|
||||||
if (!IsValidClient(client) || IsFakeClient(client))
|
if (!IsValidClient(client) || IsFakeClient(client))
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user