Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse

LiquidBounce Forum

  1. Home
  2. Resources
  3. Scripts
  4. [GPLv3] transaction.js

[GPLv3] transaction.js

Scheduled Pinned Locked Moved Scripts
4 Posts 2 Posters 910 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • C Offline
    C Offline
    commandblock2
    wrote on last edited by commandblock2
    #1
    
    
    function __require(path) {
        if (path.startsWith("@embedded")) {
            return globalThis
        }
    
        if (path.startsWith("@minecraft-yarn-definitions/types/")) {
            return {
                [path.substring(path.lastIndexOf("/") + 1)]: Java.type(path
                    .replaceAll("@minecraft-yarn-definitions/types/", "")
                    .replaceAll("/", ".")
                )
            }
        }
        return require(path);
    }
    var exports = {}
    
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    // imports
    /* eslint-disable unused-imports/no-unused-imports */
    const _embedded_1 = __require("@embedded");
    const CommonPingS2CPacket_1 = __require("@minecraft-yarn-definitions/types/net/minecraft/network/packet/s2c/common/CommonPingS2CPacket");
    // Global variables for storing transaction data
    const transactionQueue = [];
    const MAX_QUEUE_SIZE = 100;
    // Global statistics
    let totalTransactions = 0;
    let lastReportTime = 0;
    const REPORT_INTERVAL = 5000; // Report every 5 seconds
    const PARAMETER_FREQUENCY = {};
    const script = _embedded_1.registerScript.apply({
        name: "transactions",
        version: "1.0.0",
        authors: ["commandblock2"]
    });
    script.registerModule({
        name: "transactions",
        description: "Logs transactions packets for anticheat detection",
        category: "Client",
        settings: {
            reportInterval: _embedded_1.Setting.int({
                name: "ReportInterval",
                default: 5,
                range: [1, 60],
                suffix: "seconds"
            }),
            showParameters: _embedded_1.Setting.boolean({
                name: "ShowParameters",
                default: true
            }),
            logToChat: _embedded_1.Setting.boolean({
                name: "LogToChat",
                default: true
            }),
            verbose: _embedded_1.Setting.boolean({
                name: "Verbose",
                default: false
            })
        }
    }, (mod) => {
        mod.on("enable", () => {
            // Reset statistics
            totalTransactions = 0;
            lastReportTime = Date.now();
            // Clear the queue
            transactionQueue.length = 0;
            // Reset parameter frequency
            for (const key in PARAMETER_FREQUENCY) {
                delete PARAMETER_FREQUENCY[key];
            }
            _embedded_1.Client.displayChatMessage("§a[Transactions] Monitoring started. Use .txstats to see statistics.");
        });
        mod.on("disable", () => {
            _embedded_1.Client.displayChatMessage("§c[Transactions] Monitoring stopped.");
        });
        mod.on("packet", (event) => {
            if (event.packet instanceof CommonPingS2CPacket_1.CommonPingS2CPacket) {
                const parameter = event.packet.getParameter();
                const timestamp = Date.now();
                if (mod.settings.verbose.getValue()) {
                    _embedded_1.Client.displayChatMessage(`§a[Transactions] Received parameter: ${parameter}`);
                }
                // Add to queue
                transactionQueue.push({ timestamp, parameter });
                // Keep queue size limited
                if (transactionQueue.length > MAX_QUEUE_SIZE) {
                    transactionQueue.shift();
                }
                // Update statistics
                totalTransactions++;
                PARAMETER_FREQUENCY[parameter] = (PARAMETER_FREQUENCY[parameter] || 0) + 1;
                // Check if it's time to report
                const currentTime = Date.now();
                const reportIntervalMs = mod.settings.reportInterval.getValue() * 1000;
                if (mod.settings.logToChat.getValue() && currentTime - lastReportTime >= reportIntervalMs) {
                    reportStatistics();
                    lastReportTime = currentTime;
                }
            }
        });
        // Function to report statistics
        function reportStatistics() {
            if (transactionQueue.length === 0) {
                return;
            }
            const packetsPerSecond = calculatePacketsPerSecond();
            _embedded_1.Client.displayChatMessage(`§e[Transactions] §fRate: §a${packetsPerSecond.toFixed(2)} §fpackets/sec | Total: §a${totalTransactions}`);
            if (mod.settings.showParameters.getValue()) {
                const topParameters = getTopParameters(8);
                if (topParameters.length > 0) {
                    _embedded_1.Client.displayChatMessage(`§e[Transactions] §fTop parameters: ${topParameters.map(p => `§a${p.parameter}§f(${p.count})`).join(", ")}`);
                }
            }
        }
        // Calculate packets per second based on queue data
        function calculatePacketsPerSecond() {
            if (transactionQueue.length < 2) {
                return 0;
            }
            const oldestTimestamp = transactionQueue[0].timestamp;
            const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
            const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
            return timeSpanSeconds > 0 ? transactionQueue.length / timeSpanSeconds : 0;
        }
        // Get top N most frequent parameters
        function getTopParameters(n) {
            return Object.entries(PARAMETER_FREQUENCY)
                .map(([parameter, count]) => ({ parameter: parseInt(parameter), count }))
                .sort((a, b) => b.count - a.count)
                .slice(0, n);
        }
    });
    // Register a command to view transaction statistics
    script.registerCommand({
        name: "txstats",
        aliases: ["transactionstats"],
        parameters: [{
                name: "action",
                required: false,
                validate: _embedded_1.ParameterValidator.string
            }],
        onExecute(action) {
            if (action === "clear") {
                // Clear statistics
                totalTransactions = 0;
                transactionQueue.length = 0;
                for (const key in PARAMETER_FREQUENCY) {
                    delete PARAMETER_FREQUENCY[key];
                }
                _embedded_1.Client.displayChatMessage("§a[Transactions] Statistics cleared.");
                return;
            }
            if (transactionQueue.length === 0) {
                _embedded_1.Client.displayChatMessage("§c[Transactions] No transaction data available.");
                return;
            }
            // Display basic statistics
            const packetsPerSecond = calculatePacketsPerSecond();
            _embedded_1.Client.displayChatMessage(`§e[Transactions] §fStatistics:`);
            _embedded_1.Client.displayChatMessage(`§fTotal transactions: §a${totalTransactions}`);
            _embedded_1.Client.displayChatMessage(`§fCurrent rate: §a${packetsPerSecond.toFixed(2)} §fpackets/sec`);
            // Display queue info
            _embedded_1.Client.displayChatMessage(`§fQueue size: §a${transactionQueue.length}/${MAX_QUEUE_SIZE}`);
            // Display top 5 parameters
            const topParameters = getTopParameters(5);
            if (topParameters.length > 0) {
                _embedded_1.Client.displayChatMessage(`§fTop 5 parameters:`);
                topParameters.forEach((p, index) => {
                    _embedded_1.Client.displayChatMessage(`§f  ${index + 1}. Parameter §a${p.parameter}§f: ${p.count} occurrences (${(p.count / totalTransactions * 100).toFixed(1)}%)`);
                });
            }
            // Display time range
            if (transactionQueue.length >= 2) {
                const oldestTimestamp = transactionQueue[0].timestamp;
                const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
                const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
                _embedded_1.Client.displayChatMessage(`§fTime span: §a${timeSpanSeconds.toFixed(2)} §fseconds`);
            }
        }
    });
    // Helper functions for command execution
    function calculatePacketsPerSecond() {
        if (transactionQueue.length < 2) {
            return 0;
        }
        const oldestTimestamp = transactionQueue[0].timestamp;
        const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
        const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
        return timeSpanSeconds > 0 ? transactionQueue.length / timeSpanSeconds : 0;
    }
    function getTopParameters(n) {
        return Object.entries(PARAMETER_FREQUENCY)
            .map(([parameter, count]) => ({ parameter: parseInt(parameter), count }))
            .sort((a, b) => b.count - a.count)
            .slice(0, n);
    }
    

    Note that LiquidBounce cannot run typescript, at least as of now.

    // imports
    /* eslint-disable unused-imports/no-unused-imports */
    import {
        Setting,
        Vec3i,
        Vec3d,
        MathHelper,
        BlockPos,
        Hand,
        RotationAxis,
        mc,
        Client,
        RotationUtil,
        ItemUtil,
        NetworkUtil,
        InteractionUtil,
        BlockUtil,
        MovementUtil,
        ReflectionUtil,
        ParameterValidator,
        UnsafeThread,
        registerScript
    } from "@embedded";
    import { CommonPingS2CPacket } from "@minecraft-yarn-definitions/types/net/minecraft/network/packet/s2c/common/CommonPingS2CPacket";
    /* eslint-enable unused-imports/no-unused-imports */
    // DO NOT TOUCH ANYTHING ABOVE THIS LINE
    
    // Define the TransactionEntry interface for storing packet data
    interface TransactionEntry {
        timestamp: number;
        parameter: number;
    }
    
    // Global variables for storing transaction data
    const transactionQueue: TransactionEntry[] = [];
    const MAX_QUEUE_SIZE = 100;
    
    // Global statistics
    let totalTransactions = 0;
    let lastReportTime = 0;
    const PARAMETER_FREQUENCY: { [key: number]: number } = {};
    
    const script = registerScript.apply({
        name: "transactions",
        version: "1.0.0",
        authors: ["commandblock2"]
    });
    
    script.registerModule({
        name: "transactions",
        description: "Logs transactions packets for anticheat detection",
        category: "Client",
        settings: {
            reportInterval: Setting.int({
                name: "ReportInterval",
                default: 5,
                range: [1, 60],
                suffix: "seconds"
            }),
            showParameters: Setting.boolean({
                name: "ShowParameters",
                default: true
            }),
            logToChat: Setting.boolean({
                name: "LogToChat",
                default: true
            }),
            verbose: Setting.boolean({
                name: "Verbose",
                default: false
            })
        }
    }, (mod) => {
        mod.on("enable", () => {
            // Reset statistics
            totalTransactions = 0;
            lastReportTime = Date.now();
            
            // Clear the queue
            transactionQueue.length = 0;
            
            // Reset parameter frequency
            for (const key in PARAMETER_FREQUENCY) {
                delete PARAMETER_FREQUENCY[key];
            }
            
            Client.displayChatMessage("§a[Transactions] Monitoring started. Use .txstats to see statistics.");
        });
    
        mod.on("disable", () => {
            Client.displayChatMessage("§c[Transactions] Monitoring stopped.");
        });
    
        mod.on("packet", (event) => {
            if (event.packet instanceof CommonPingS2CPacket) {
                const parameter = event.packet.getParameter();
                const timestamp = Date.now();
    
                if (mod.settings.verbose.getValue()) {
                    Client.displayChatMessage(`§a[Transactions] Received parameter: ${parameter}`);
                }
                
                // Add to queue
                transactionQueue.push({ timestamp, parameter });
                
                // Keep queue size limited
                if (transactionQueue.length > MAX_QUEUE_SIZE) {
                    transactionQueue.shift();
                }
                
                // Update statistics
                totalTransactions++;
                PARAMETER_FREQUENCY[parameter] = (PARAMETER_FREQUENCY[parameter] || 0) + 1;
                
                // Check if it's time to report
                const currentTime = Date.now();
                const reportIntervalMs = mod.settings.reportInterval.getValue() * 1000;
                
                if (mod.settings.logToChat.getValue() && currentTime - lastReportTime >= reportIntervalMs) {
                    reportStatistics();
                    lastReportTime = currentTime;
                }
            }
        });
        
        // Function to report statistics
        function reportStatistics() {
            if (transactionQueue.length === 0) {
                return;
            }
            
            const packetsPerSecond = calculatePacketsPerSecond();
            Client.displayChatMessage(`§e[Transactions] §fRate: §a${packetsPerSecond.toFixed(2)} §fpackets/sec | Total: §a${totalTransactions}`);
            
            if (mod.settings.showParameters.getValue()) {
                const topParameters = getTopParameters(8);
                if (topParameters.length > 0) {
                    Client.displayChatMessage(`§e[Transactions] §fTop parameters: ${topParameters.map(p => `§a${p.parameter}§f(${p.count})`).join(", ")}`);
                }
            }
        }
        
        // Calculate packets per second based on queue data
        function calculatePacketsPerSecond(): number {
            if (transactionQueue.length < 2) {
                return 0;
            }
            
            const oldestTimestamp = transactionQueue[0].timestamp;
            const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
            const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
            
            return timeSpanSeconds > 0 ? transactionQueue.length / timeSpanSeconds : 0;
        }
        
        // Get top N most frequent parameters
        function getTopParameters(n: number): { parameter: number, count: number }[] {
            return Object.entries(PARAMETER_FREQUENCY)
                .map(([parameter, count]) => ({ parameter: parseInt(parameter), count }))
                .sort((a, b) => b.count - a.count)
                .slice(0, n);
        }
    });
    
    // Register a command to view transaction statistics
    script.registerCommand({
        name: "txstats",
        aliases: ["transactionstats"],
        parameters: [{
            name: "action",
            required: false,
            validate: ParameterValidator.string
        }],
        onExecute(action: string) {
            if (action === "clear") {
                // Clear statistics
                totalTransactions = 0;
                transactionQueue.length = 0;
                for (const key in PARAMETER_FREQUENCY) {
                    delete PARAMETER_FREQUENCY[key];
                }
                Client.displayChatMessage("§a[Transactions] Statistics cleared.");
                return;
            }
            
            if (transactionQueue.length === 0) {
                Client.displayChatMessage("§c[Transactions] No transaction data available.");
                return;
            }
            
            // Display basic statistics
            const packetsPerSecond = calculatePacketsPerSecond();
            Client.displayChatMessage(`§e[Transactions] §fStatistics:`);
            Client.displayChatMessage(`§fTotal transactions: §a${totalTransactions}`);
            Client.displayChatMessage(`§fCurrent rate: §a${packetsPerSecond.toFixed(2)} §fpackets/sec`);
            
            // Display queue info
            Client.displayChatMessage(`§fQueue size: §a${transactionQueue.length}/${MAX_QUEUE_SIZE}`);
            
            // Display top 5 parameters
            const topParameters = getTopParameters(5);
            if (topParameters.length > 0) {
                Client.displayChatMessage(`§fTop 5 parameters:`);
                topParameters.forEach((p, index) => {
                    Client.displayChatMessage(`§f  ${index + 1}. Parameter §a${p.parameter}§f: ${p.count} occurrences (${(p.count / totalTransactions * 100).toFixed(1)}%)`);
                });
            }
            
            // Display time range
            if (transactionQueue.length >= 2) {
                const oldestTimestamp = transactionQueue[0].timestamp;
                const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
                const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
                Client.displayChatMessage(`§fTime span: §a${timeSpanSeconds.toFixed(2)} §fseconds`);
            }
        }
    });
    
    // Helper functions for command execution
    function calculatePacketsPerSecond(): number {
        if (transactionQueue.length < 2) {
            return 0;
        }
        
        const oldestTimestamp = transactionQueue[0].timestamp;
        const newestTimestamp = transactionQueue[transactionQueue.length - 1].timestamp;
        const timeSpanSeconds = (newestTimestamp - oldestTimestamp) / 1000;
        
        return timeSpanSeconds > 0 ? transactionQueue.length / timeSpanSeconds : 0;
    }
    
    function getTopParameters(n: number): { parameter: number, count: number }[] {
        return Object.entries(PARAMETER_FREQUENCY)
            .map(([parameter, count]) => ({ parameter: parseInt(parameter), count }))
            .sort((a, b) => b.count - a.count)
            .slice(0, n);
    }
    
    
    1 Reply Last reply
    1
    • C Offline
      C Offline
      commandblock2
      wrote on last edited by
      #2

      it was kinda weird, I never see any value starting maybe with -32768 or around, it's always that giant number, is it VFP or just everyone's using the same ac? Btw I even see some server like sending 300ish transactions per second and wtf is that.

      1 Reply Last reply
      0
      • kawaiinekololisK Offline
        kawaiinekololisK Offline
        kawaiinekololis
        Admin
        wrote on last edited by
        #3

        I think it would be helpful for people to have this as ZIP to drop and extract.

        1 Reply Last reply
        0
        • C Offline
          C Offline
          commandblock2
          wrote on last edited by commandblock2
          #4

          transactions.zip Also looking forward to our marketplace, I do know that some development happened on the branch recently, hope to see it soon.

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          About
          • Terms of Service
          • Privacy Policy
          • Status
          • Contact Us
          Downloads
          • Releases
          • Source code
          • License
          Docs
          • Tutorials
          • CustomHUD
          • AutoSettings
          • ScriptAPI
          Community
          • Forum
          • Guilded
          • YouTube
          • Twitter
          • D.Tube
          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups