Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
Skins
  • Light
  • Brite
  • 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 1.7k 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

          Hello! It looks like you're interested in this conversation, but you don't have an account yet.

          Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

          With your input, this post could be even better 💗

          Register Login
          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