SourceTV Listener

Please post any questions about developing your plugin here. Please use the search function before posting!
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

SourceTV Listener

Postby decompile » Thu Jul 07, 2016 1:19 pm

Hello, is there something like SourceTV listener?

Would be great to use OnBroadcastActive or OnBroadcastEnd,

Im currently using tv_autorecord and creating a system behind it.

When an autorecord demo ends, it prints "Completed SourceTV demo "auto-20160707-1514-de_dust2.dem", recording time 22.3"

When an autorecord demo starts, it prints "SourceTV broadcast active."

It would be nice to get like the demo name, timestamp when it start, recording time etc.

The only way to get its timestamp is by using this:

Syntax: Select all

demoname = 'auto-20160707-1514-de_dust2.dem'
timepart = "-".join(basename.split("-")[1:3])
savetime = time.mktime(time.strptime(timepart,"%Y%m%d-%H%M"))
User avatar
La Muerte
Administrator
Posts: 180
Joined: Sun Jul 15, 2012 1:48 pm
Location: Belgium
Contact:

Re: SourceTV Listener

Postby La Muerte » Sat Jul 09, 2016 9:58 pm

I can't answer your question, but it'd be damn nice if you could implement a way to automatically upload said demo's to a webserver so that people can download, review and give feedback on them.
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: SourceTV Listener

Postby L'In20Cible » Sun Jul 10, 2016 4:17 am

I didn't dig into the binaries but, there is certainly a way to hook those. For now, you could simply add your own callbacks to those specific commands and listen to them doing whatever you need to do.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: SourceTV Listener

Postby decompile » Sun Jul 10, 2016 9:50 am

La Muerte wrote:I can't answer your question, but it'd be damn nice if you could implement a way to automatically upload said demo's to a webserver so that people can download, review and give feedback on them.


Syntax: Select all

from ftplib import FTP

USER = ''
PASS = ''
SERVER = ''
PORT = 21

def connect_ftp():
ftp = FTP()
ftp.connect(SERVER, PORT)
ftp.login(USER, PASS)
return ftp

def upload_file(ftp_connetion, upload_file_path):

#Open the file
try:
upload_file = open(upload_file_path, 'r')

#get the name
path_split = upload_file_path.split('/')
final_file_name = path_split[len(path_split)-1]

#transfer the file
print('Uploading ' + final_file_name + '...')

ftp_connetion.storbinary('STOR '+ final_file_name, upload_file)

print('Upload finished.')

except IOError:
print ("File not found")
ftp_conn = connect_ftp()

demo_file_path = "E:\\GameServers\\css\cstrike\\demo1.dem"
upload_file(ftp_conn, demo_file_path)
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: SourceTV Listener

Postby decompile » Sun Jul 10, 2016 9:54 am

L'In20Cible wrote:I didn't dig into the binaries but, there is certainly a way to hook those. For now, you could simply add your own callbacks to those specific commands and listen to them doing whatever you need to do.


Yes, just wrote my own listener, which just "manually" records the demos instead of using tv_autorecord.
Simply tv_record "xxxxxxx" and when the map ends it just executes tv_stoprecord. Atleast you have the demo name & the start time and endtime if needed.
User avatar
iPlayer
Developer
Posts: 590
Joined: Sat Nov 14, 2015 8:37 am
Location: Moscow
Contact:

Re: SourceTV Listener

Postby iPlayer » Sun Jul 10, 2016 10:01 am

decompile wrote:Yes, just wrote my own listener, which just "manually" records the demos instead of using tv_autorecord.
Simply tv_record "xxxxxxx" and when the map ends it just executes tv_stoprecord. Atleast you have the demo name & the start time and endtime if needed.

That's neat. As far as I can remember, demos are a bit broken in CS:S, you can't skip back and forth them that easy. With your manual approach, it's possible to make smaller demos, say, every 10 minutes.
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
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: SourceTV Listener

Postby Ayuto » Mon Jul 11, 2016 7:23 pm

Tested with CS:S on Windows:

Syntax: Select all

# =============================================================================
# >> IMPORTS
# =============================================================================
# Python
import time

# Source.Python
import memory

from memory import DataType

from memory.manager import CustomType
from memory.manager import manager

from memory.hooks import PostHook

from core import PLATFORM
from engines.server import global_vars

from listeners import ListenerManager
from listeners import ListenerManagerDecorator


# =============================================================================
# >> GLOBAL VARIABLES
# =============================================================================
engine = memory.find_binary('bin/engine')

if PLATFORM == 'windows':
DEMO_RECORDER_OFFSET = 19680
hltv_ptr = engine.find_pointer(
b'\x55\x8B\xEC\x81\xEC\x1C\x01\x00\x00\x8D\x85\xE4\xFE\xFF\xFF\x68\x04\x01\x00\x00',
33,
2
)
else:
DEMO_RECORDER_OFFSET = 19652
hltv_ptr = engine.find_pointer('hltv', level=1)

if not hltv_ptr:
# Can happen if tv_enable is not set to 1
raise ValueError('HLTV Server is NULL.')


# =============================================================================
# >> CLASSES
# =============================================================================
class CHLTVDemoRecorder(CustomType, metaclass=manager):
get_demo_file = manager.virtual_function(0, [], DataType.STRING)
get_recording_tick = manager.virtual_function(1, [], DataType.INT)
start_recording = manager.virtual_function(2, [DataType.STRING, DataType.BOOL])
set_signon_state = manager.virtual_function(3, [])
is_recording = manager.virtual_function(4, [], DataType.BOOL)
pause_recording = manager.virtual_function(5, [])
resume_recording = manager.virtual_function(6, [])
stop_recording = manager.virtual_function(7, [])
record_command = manager.virtual_function(8, [DataType.STRING])
record_user_input = manager.virtual_function(9, [DataType.INT])
record_messages = manager.virtual_function(10, [DataType.POINTER, DataType.INT])
record_packet = manager.virtual_function(11, [])
record_server_classes = manager.virtual_function(12, [DataType.POINTER])
record_string_tables = manager.virtual_function(13, [])
reset_demo_interpolation = manager.virtual_function(14, [])

@property
def recording_time(self):
"""Return the recording time in seconds."""
return self.get_recording_tick() * global_vars.interval_per_tick

@property
def start_time(self):
"""Return the time when the record has been started."""
return time.time() - self.recording_time

demo_recorder = memory.make_object(
CHLTVDemoRecorder, hltv_ptr + DEMO_RECORDER_OFFSET)


class OnDemoStarted(ListenerManagerDecorator):
manager = ListenerManager()

class OnDemoStopped(ListenerManagerDecorator):
manager = ListenerManager()


# =============================================================================
# >> HOOKS
# =============================================================================
@PostHook(demo_recorder.start_recording)
def pre_start_recording(args, return_value):
OnDemoStarted.manager.notify()

@PostHook(demo_recorder.stop_recording)
def pre_stop_recording(args, return_value):
OnDemoStopped.manager.notify()


# =============================================================================
# >> TESTS
# =============================================================================
if not demo_recorder.is_recording():
raise ValueError('SourceTV is not recording.')

print('Demo file :', demo_recorder.get_demo_file())
print('Recording time:', divmod(demo_recorder.recording_time, 60))
print('Start time :', time.ctime(demo_recorder.start_time))

@OnDemoStarted
def on_demo_started():
print('Demo started:', demo_recorder.get_demo_file())

@OnDemoStopped
def on_demo_stopped():
print('Demo stopped:', demo_recorder.get_demo_file())

Edit: Added OnDemoStarted and OnDemoStopped decorators.
Edit2: Fixed plugin for Linux.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: SourceTV Listener

Postby decompile » Fri Jul 15, 2016 7:00 pm

Thank you Ayuto!!

Just noticed that OnDemoStarted isnt working, is it just me or someone else has it too?
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: SourceTV Listener

Postby L'In20Cible » Fri Jul 15, 2016 7:03 pm

Why you remove your post to repost them few hours later?
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: SourceTV Listener

Postby decompile » Sat Jul 16, 2016 11:06 am

L'In20Cible wrote:Why you remove your post to repost them few hours later?


When I posted it I wasnt sure if it was the official code which wasn't working, so I thought maybe I changed something to make it not work, but in the end I tested it only with the code from above and it doesnt work either
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: SourceTV Listener

Postby Ayuto » Sat Jul 16, 2016 2:27 pm

When I tested it OnDemoStarted was working fine. Can you provide the steps to reproduce the issue?
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: SourceTV Listener

Postby decompile » Sat Jul 16, 2016 3:33 pm

Problem solved, my srcds forced 'sv_autorecord 0' after mapchange, checked all cvars server.cfg/autoexec.cfg/srcds parameter + and after I removed them and put them only in autoexec.cfg it worked finally.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: SourceTV Listener

Postby decompile » Sun Jul 24, 2016 11:46 pm

Hey, would this work for cs:go windows/linux too?
Im using this for both games
User avatar
L'In20Cible
Project Leader
Posts: 1533
Joined: Sat Jul 14, 2012 9:29 pm
Location: Québec

Re: SourceTV Listener

Postby L'In20Cible » Mon Jul 25, 2016 12:46 am

This will most likely requires another signatures for CS:GO running on windows.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: SourceTV Listener

Postby decompile » Sat Apr 21, 2018 1:25 pm

Can someone maybe check the offsets/signatures for CS:S Windows/Linux and CS:GO Windows/Linux?

Additionally how are you doing that? Is there any program for that?
12jdlovins
Junior Member
Posts: 17
Joined: Mon Apr 16, 2018 5:11 am

Re: SourceTV Listener

Postby 12jdlovins » Mon Apr 23, 2018 6:08 am

decompile wrote:Can someone maybe check the offsets/signatures for CS:S Windows/Linux and CS:GO Windows/Linux?

Additionally how are you doing that? Is there any program for that?


https://asherkin.github.io/vtable/

this might help? I'm unsure though, that stuff is beyond me at the moment.
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: SourceTV Listener

Postby decompile » Mon Apr 23, 2018 5:47 pm

How would that work, also for CS:GO for example?

I tried to choose CS:S for now, and entered CHLTVDemoRecorder, found actually something but how do I get the offset?
User avatar
Ayuto
Project Leader
Posts: 2193
Joined: Sat Jul 07, 2012 8:17 am
Location: Germany

Re: SourceTV Listener

Postby Ayuto » Mon Apr 23, 2018 6:57 pm

That tool is able to dump virtual function offsets/indexes, so you would be able to use it to update the "manager.virtual_function(...)" parts. However, that is only a part of the solution, because you also need to retrieve the pointer to the instance of CHLTVDemoRecorder. Moreover, symbols have been stripped from the CS:GO binaries, so actually you can't use that tool for CS:GO at all.

I'm using IDA Pro to retrieve this information.

I hope to find some time at the weekend to provide the necessarry information for CS:GO (CS:S should be up to date).
12jdlovins
Junior Member
Posts: 17
Joined: Mon Apr 16, 2018 5:11 am

Re: SourceTV Listener

Postby 12jdlovins » Mon Apr 23, 2018 11:44 pm

I'm actually really interested in making a sourceTV recordinger & uploader however is using the pointers and such needed? Could i just start recording on map start and upload on map end basically with like tv_record mapname-date and such?
decompile
Senior Member
Posts: 416
Joined: Sat Oct 10, 2015 10:37 am
Location: Germany
Contact:

Re: SourceTV Listener

Postby decompile » Tue Apr 24, 2018 12:29 am

You dont need it, but its the official way to also hook auto-created demos, or user generated ones.

Return to “Plugin Development Support”

Who is online

Users browsing this forum: No registered users and 11 guests