Hydranix_ Posted April 6, 2016 Share Posted April 6, 2016 (edited) I wrote a small program which automatically queries macrodox and processes the results. If someone is found to be Hyperscrolling, it announces it in game chat. If someone is found to have a very high perf, with a very high or default fps_max, it announces it in chat. Update: 4/9/2016 Big thanks to tfreeman451 for informing me that the 'mdx_stats @all' command is unreliable when there are more than 19 players on the server. When there are more than 19 players, 'mdx_stats @all' will still only return 19 results, the remaining players results are truncated and never displayed. File updated. This tool now reliably processes every single players mdx_stats. It allows you to pay attention to other things, or play the game and not need to worry about checking macrodox. A few things to note: It runs on Windows x86_64 This is for CSS It only works when the game is focused. It runs independently of the server and it's plugins. It requires a single keybind. Currently the F8 key and is not yet configurable. It also requires a couple convars to be set, and sets them automatically. If you have any suggestions or any issues/bugs let me know via PM or in this thread. How to setup: Download and unzip exe file and save it somewhere. Run the exe, and press yes on the UAC dialog. It should instruct you to add "+exec HNx" to CSS's launch options Open steam to the Libraries page. Right click Counter-Strike Source and click properties Click Set Launch Options... Add '+exec HNx' to the end of the Launch Options and click ok. Restart CSS and run the exe again, it should now say it's waiting for the game to take focus. Enter an [HG] server which has macrodox enabled and you should be set. To check if it's working, wait about a minute and alt tab to the console window of the exe. You should see Macrodox output in the console. If you do, it's working. Here an example of it in action: 0 do work son<68><[u:1:3707848]><> Avg: 9.382871/178.964874 Perf: 0.043983 cs_crackhouse_hg_a2 10263.503906 -46.968750 372.031250 Last: 5 15 19 18 15 14 5 5 2 4 3 17 10 9 19 1 1 1 1 1 1 1 1 1 1 1 2 13 16 14 CSS_MDX_Stats.zipFetching info... Edited April 10, 2016 by Hydranix_ 4 Quote Link to comment Share on other sites More sharing options...
Short Posted April 7, 2016 Share Posted April 7, 2016 How does this work, are you hooking the game in some way? Quote Link to comment Share on other sites More sharing options...
Thomasjosif Posted April 7, 2016 Share Posted April 7, 2016 Hi there. We all love the coding world and I would please like to ask you to post your sourcecode here as well, or you can PM me it. We do not want any malicious programs going out Quote Link to comment Share on other sites More sharing options...
Hydranix_ Posted April 7, 2016 Author Share Posted April 7, 2016 (edited) On 4/7/2016 at 12:16 AM, Short said: How does this work, are you hooking the game in some way? No game hooking, manipulation of the game process or any modules being loaded. This simply reads the console.log file which I'll explain below. First, a summary of how this tool works. It tries to find where steam is installed by first checking the default install path, if that fails, it reads steams registry entry for InstallPath, and if that fails it asks the user to locate the cstrike folder (not yet implemented). Once it gets the directory, it remembers the location by saving its own entry in the registry, so it doesn't have to ever search again. (unless steam is reinstalled somewhere different at some point in the future) Then it creates a couple .cfg files in ".\cstrike\cfg". The first, HNx.cfg:unbind F8 bind F8 "exec dyncmd" con_logfile Conlog\console.log The other .cfg file is empty (for now) and is called dyncmd.cfg (short for dynamic command). It uses this file to execute console commands in the game without having to have a bunch of different keybindings. It also sets the ConVar "con_logfile 'ConLog\console.log'" which causes Counter-strike to write the contents of the in game console to a file in real time. Using DynCmd, it executes "mdx_stats @all" once about every minute so long as CSS is the focused window, otherwise is goes idle. If a player has high perf percentage, it executes "get_fps_max <name>" and looks for values which make certain perf percentages impossible physically to obtain without scripted help. If the numbers indicate a clear cheater, it announces in all_chat the name of the scripter and how severe their cheating is. So far I've detected about 5-6 different people using scripts, and each time it was a valid detection. More often than not the detection is so quick that the player immediately stops using their scripts, and a few have even apologized. If this tool proves useful I plan to update the program to work with CS:GO and other games that support macrodox as well. On 4/7/2016 at 12:16 AM, Thomasjosif said: Hi there. We all love the coding world and I would please like to ask you to post your sourcecode here as well, or you can PM me it. We do not want any malicious programs going out Nothing malicious here. The source is a bit of a mess though and I'm currently cleaning it up. I'll pm you the current state of the source if you're worried of my evil intentions. Here some of the cleaner code: // MDX_Output.hpp #pragma once #include <string> // Upon construction, this class extracts the relevant macrodox information from // the mdx_stats console output // note that this uses very unsophisticated string manipulation class MDX_Stats { public: MDX_Stats(const std::string &line); ~MDX_Stats(); /* MDX_Stats(const MDX_Stats &from); */ // player identification std::string name(); std::string steamId(); // the main variable worth watching float perf(); // 2 more variables worth including float avgJumps(); float avgSpeed(); // highest jumps per hop of last thirty hops (hyperscrollers) int lastHighest(); private: std::string _PlayerName; std::string _SteamId; float _perf; float _avgJumps; float _avgSpeed; int _Last[30]; }; // MDX_Output.cpp #include "MDX_Output.hpp" #include "Util.hpp" // example of one line of the MDX output // 0 [HG] Hydranix<764><[u:1:201393689]><> Avg: 1.004638/176.456207 Perf: 0.073529 cs_crackhouse_hg_a2 10017.465820 -784.924560 372.031250 Last: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 MDX_Stats::MDX_Stats(const std::string &line) { auto vLine = split(line, ' '); int PlayerIndex; for (int i = 1; i < vLine.size(); i++) { if (vLine[i].compare("Avg:") == 0) { PlayerIndex = i - 1; break; } } // Extract SteamID first size_t pos = vLine[PlayerIndex].find_last_of('[') + 1; size_t len = vLine[PlayerIndex].find_last_of(']') - pos; _SteamId = vLine[PlayerIndex].substr(pos, len); // Now get the name _PlayerName = vLine[1]; if (PlayerIndex > 1) { int i = 1; while(true) { i++; if (vLine[i].compare("Avg:") == 0) { break; } _PlayerName.push_back(' '); _PlayerName += vLine[i]; } } // remove extra crap from name for (int i = 0; i < 3; i++) _PlayerName.erase(_PlayerName.find_last_of('<')); // get average values auto avg = split(vLine[PlayerIndex + 2], '/'); _avgJumps = std::stof(avg[0], nullptr); _avgSpeed = std::stof(avg[1], nullptr); // now find perf size_t PerfIndex; for (size_t i = 0; i < vLine.size(); i++) { if (vLine[i].compare("Perf:") == 0) { PerfIndex = i + 1; break; } } _perf = std::stof(vLine[PerfIndex], nullptr); // finally get last thirty jumps-per-hop auto vri = vLine.rbegin(); for (int i = 0; i < 30; ++vri, i++) { _Last[29-i] = std::stoi(*vri, nullptr, 10); } } MDX_Stats::~MDX_Stats() { } /* MDX_Stats::MDX_Stats(const MDX_Stats &from) { _PlayerName = new std::string(from.name()); _SteamId = new std::string(from.steamId()); } */ std::string MDX_Stats::name() { return _PlayerName; } std::string MDX_Stats::steamId() { return _SteamId; } float MDX_Stats::perf() { return _perf; } float MDX_Stats::avgJumps() { return _avgJumps; } float MDX_Stats::avgSpeed() { return _avgSpeed; } int MDX_Stats::lastHighest() { int highest = 0; for (int i = 1; i < 29; i++) { if (_Last[highest] < _Last[i]) highest = i; } return _Last[highest]; } Edit: Cleaned up this post, was in a rush earlier when I first posted it. Edited April 7, 2016 by Hydranix_ 1 Quote Link to comment Share on other sites More sharing options...
nielsfalko Posted April 7, 2016 Share Posted April 7, 2016 I find this a relly good idea it makes admins not have to check every seccond Quote Link to comment Share on other sites More sharing options...
Thomasjosif Posted April 7, 2016 Share Posted April 7, 2016 Ok looks fine for me. Although I would like to talk to you with some integration with something I had in mind. Quote Link to comment Share on other sites More sharing options...
Sirius Posted April 7, 2016 Share Posted April 7, 2016 Great idea and concept but rather than something that needs to be installed on a client PC, could you look in to making it a SM plugin? 1 Quote Link to comment Share on other sites More sharing options...
jonmac5037 Posted April 7, 2016 Share Posted April 7, 2016 0 do work son<68><[U:1:3707848]><> Avg: 9.382871/178.964874 Perf: 0.043983 cs_crackhouse_hg_a2 10263.503906 -46.968750 372.031250 Last: 5 15 19 18 15 14 5 5 2 4 3 17 10 9 19 1 1 1 1 1 1 1 1 1 1 1 2 13 16 14 His AVG doesn't match his Last and his perf is 0.04. Quote Link to comment Share on other sites More sharing options...
Hydranix_ Posted April 7, 2016 Author Share Posted April 7, 2016 (edited) On 4/7/2016 at 12:17 PM, Thomasjosif said: Ok looks fine for me. Although I would like to talk to you with some integration with something I had in mind. Sure, that's only a part of the code, it's nearly halfway finished cleaning up. On 4/7/2016 at 12:41 PM, sirius said: Great idea and concept but rather than something that needs to be installed on a client PC, could you look in to making it a SM plugin? An sm plugin or even an extension of macrodox itself sounds interesting. Being able to have direct access to the macrodox variables would make it much easier and a lot more powerful. On 4/7/2016 at 8:49 PM, jonmac5037 said: 0 do work son<68><[U:1:3707848]><> Avg: 9.382871/178.964874 Perf: 0.043983 cs_crackhouse_hg_a2 10263.503906 -46.968750 372.031250 Last: 5 15 19 18 15 14 5 5 2 4 3 17 10 9 19 1 1 1 1 1 1 1 1 1 1 1 2 13 16 14 His AVG doesn't match his Last and his perf is 0.04. But he was hyperscrolling, but only just started using it, so didn't get a good perf built up. The Avg is based on the entire session, rather than the last 30 IIRC. It's not possible without an unlocked mousewheel or script to get over 11-12 scrolls per hop several times in a row. Edited April 7, 2016 by Hydranix_ Quote Link to comment Share on other sites More sharing options...
Hydranix_ Posted April 9, 2016 Author Share Posted April 9, 2016 Code cleanup is done and most bugs have been dealt with, Updating first post with new file. 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.