From 91bc594aca596227d79dd34e15a77a4f23dec8ae Mon Sep 17 00:00:00 2001 From: Krzyhau Date: Fri, 11 Aug 2023 14:21:10 +0200 Subject: [PATCH] jhgdasjbhgdsjbhgsd --- docs/tas_proto.txt | 13 +++-- src/Features/Tas/TasProtocol.cpp | 85 ++++++++++++++++++-------------- src/Features/Tas/TasProtocol.hpp | 10 +++- 3 files changed, 67 insertions(+), 41 deletions(-) diff --git a/docs/tas_proto.txt b/docs/tas_proto.txt index 3409e3ae8..f2c439a31 100644 --- a/docs/tas_proto.txt +++ b/docs/tas_proto.txt @@ -1,13 +1,14 @@ -TAS server protocol +TAS protocol =================== -Connect to a TCP socket on localhost:6555. +The following specification lists packets that can be sent between the player (SAR client capable of playing TAS scripts) and controller (external software capable of controlling the player through the protocol like VSC extension or bruteforcer server) +SAR (the player) can act as both the client (connecting to a controller server) and server (listening for controller client connections). Every packet consists of a one-byte (u8) ID, followed by some extra data. the extra data is specified here under the packet name; if there's nothing specified, there's no extra data. The server should always send a packet with ID 255 first; it'll never send this again. -server (SAR) -> client (VSC extension): +player -> controller: [0] set active len1: u32 filename1: [len1]u8 // relative to "Portal 2/tas/", so the same as the arg you'd give to sar_tas_play @@ -47,7 +48,7 @@ server (SAR) -> client (VSC extension): location: [len]u8 // a string like "/home/mlugg/.steam/steam/steamapps/common/Portal 2", used so that the plugin knows whether it has the right script folder open -client (VSC extension) -> server (SAR): +controller -> player: [0] request playback len1: u32 filename1: [len1]u8 // relative to "Portal 2/tas/", so the same as the arg you'd give to sar_tas_play @@ -85,3 +86,7 @@ client (VSC extension) -> server (SAR): [100] request entity info len: u32 entity_selector: [len]u8 + + [101] set continouos entity info + len: u32 + entity_selector: [len]u8 // send empty string to disable continouos entity info diff --git a/src/Features/Tas/TasProtocol.cpp b/src/Features/Tas/TasProtocol.cpp index 8d2f0977e..77d7de7e3 100644 --- a/src/Features/Tas/TasProtocol.cpp +++ b/src/Features/Tas/TasProtocol.cpp @@ -40,15 +40,6 @@ using namespace TasProtocol; -namespace TasProtocol { - // Has to be defined here because something something MVSC suck my dick - struct ConnectionData { - SOCKET sock; - std::deque cmdbuf; - }; -} - - static SOCKET g_listen_sock = INVALID_SOCKET; static std::vector g_connections; static std::atomic g_should_stop; @@ -212,8 +203,9 @@ static bool processCommands(ConnectionData &cl) { if (cl.cmdbuf.size() == 0) return true; size_t extra = cl.cmdbuf.size() - 1; + uint8_t packetId = cl.cmdbuf[0]; - switch (cl.cmdbuf[0]) { + switch (packetId) { case RECV_PLAY_SCRIPT: if (extra < 8) return true; { @@ -340,6 +332,7 @@ static bool processCommands(ConnectionData &cl) { } break; case RECV_ENTITY_INFO: + case RECV_SET_CONT_ENTITY_INFO: if (extra < 4) return true; { std::deque copy = cl.cmdbuf; @@ -356,34 +349,11 @@ static bool processCommands(ConnectionData &cl) { cl.cmdbuf = copy; - std::vector buf; - buf.push_back(SEND_ENTITY_INFO); - - CEntInfo *entInfo = entityList->QuerySelector(entSelector.c_str()); - if (entInfo != NULL) { - buf.push_back(1); - ServerEnt* ent = (ServerEnt*)entInfo->m_pEntity; - - Vector position = ent->abs_origin(); - encodeRawFloat(buf, position.x); - encodeRawFloat(buf, position.y); - encodeRawFloat(buf, position.z); - - QAngle angles = ent->abs_angles(); - encodeRawFloat(buf, angles.x); - encodeRawFloat(buf, angles.y); - encodeRawFloat(buf, angles.z); - - Vector velocity = ent->abs_velocity(); - encodeRawFloat(buf, velocity.x); - encodeRawFloat(buf, velocity.y); - encodeRawFloat(buf, velocity.z); - + if (packetId == RECV_SET_CONT_ENTITY_INFO) { + cl.contInfoEntSelector = entSelector; } else { - buf.push_back(0); + SendEntityInfo(cl, entSelector); } - - send(cl.sock, (const char *)buf.data(), buf.size(), 0); } break; @@ -616,6 +586,18 @@ void TasProtocol::SetStatus(Status s) { g_status_mutex.lock(); g_current_status = s; g_status_mutex.unlock(); + + if (s.active) { + for (auto &cl : g_connections) { + if (cl.contInfoEntSelector.length() == 0) continue; + + std::vector buf{SEND_CURRENT_TICK}; + encodeRaw32(buf, s.playback_tick); + send(cl.sock, (const char *)buf.data(), buf.size(), 0); + + SendEntityInfo(cl, cl.contInfoEntSelector); + } + } } void TasProtocol::SendProcessedScript(uint8_t slot, std::string scriptString) { @@ -635,6 +617,37 @@ void TasProtocol::SendProcessedScript(uint8_t slot, std::string scriptString) { sendAll(buf); } +void TasProtocol::SendEntityInfo(TasProtocol::ConnectionData &conn, std::string entSelector) { + std::vector buf; + buf.push_back(SEND_ENTITY_INFO); + + CEntInfo *entInfo = entityList->QuerySelector(entSelector.c_str()); + if (entInfo != NULL) { + buf.push_back(1); + ServerEnt *ent = (ServerEnt *)entInfo->m_pEntity; + + Vector position = ent->abs_origin(); + encodeRawFloat(buf, position.x); + encodeRawFloat(buf, position.y); + encodeRawFloat(buf, position.z); + + QAngle angles = ent->abs_angles(); + encodeRawFloat(buf, angles.x); + encodeRawFloat(buf, angles.y); + encodeRawFloat(buf, angles.z); + + Vector velocity = ent->abs_velocity(); + encodeRawFloat(buf, velocity.x); + encodeRawFloat(buf, velocity.y); + encodeRawFloat(buf, velocity.z); + + } else { + buf.push_back(0); + } + + send(conn.sock, (const char *)buf.data(), buf.size(), 0); +} + ON_EVENT(FRAME) { g_status_mutex.lock(); if (g_current_status.active) { diff --git a/src/Features/Tas/TasProtocol.hpp b/src/Features/Tas/TasProtocol.hpp index 0fd4ce8a9..a9be502ef 100644 --- a/src/Features/Tas/TasProtocol.hpp +++ b/src/Features/Tas/TasProtocol.hpp @@ -21,7 +21,8 @@ namespace TasProtocol { RECV_SET_PAUSE_TICK = 6, RECV_ADVANCE_TICK = 7, RECV_PLAY_SCRIPT_PROTOCOL = 10, - RECV_ENTITY_INFO = 100 + RECV_ENTITY_INFO = 100, + RECV_SET_CONT_ENTITY_INFO = 101 }; enum SendMsg : uint8_t { @@ -46,7 +47,14 @@ namespace TasProtocol { int playback_tick; }; + struct ConnectionData { + uintptr_t sock; + std::deque cmdbuf; + std::string contInfoEntSelector; + }; + void SetStatus(Status s); void SendProcessedScript(uint8_t slot, std::string scriptString); + void SendEntityInfo(ConnectionData& conn, std::string entSelector); } // namespace TasProtocol