Git Product home page Git Product logo

discord_vigilante's Introduction

Overview

DiscordSidekick is a process that executes a Lua script to provide rich presence data for a target process.

The sidekick process will attach to the target process ID and execute the script at scripts/<game_id>.lua. The target process ID and game_id are specified on the command line: DiscordSidekick_x86.exe <pid> <game_id>. (The x86 in DiscordSidekick_x86.exe refers to the architecture of the target process -- the x86 executable cannot target 64-bit processes and vice versa.)

Any game_id can be used for testing (1 is perfectly fine). For the Discord client to automatically launch a sidekick process in production, a script for the game ID from Discord's game database entry must be present at scripts/<game_id>.lua.

Lua

Standard Library

The basic (with the exception of dofile, loadfile, and load), coroutine, table, string, math, and utf8Lua standard libraries are available (notably absent are the package, io, and os libraries).

Sidekick API

Architecture

The Architecture global variable is set to either x86 or x64 depending on the architecture of the target process.

Read(address, length)

Returns length bytes of data at address as a string (or nil on failure).

Find(pattern, [begin_address[, [end_address, [executable_only]]])

Returns the address of the first occurence of pattern within the specified range (the entire process if unspecified), or nil on failure. If exutable_only is true (the default behavior), only executable pages will be searched.

pattern is a string with the format 11223344......AABBCC, where NN is a hexadecimal byte and .. represents a wildcard.

GetModuleInfo(name)

Returns a (base address, size) tuple for the specified module name, or nil on failure.

Sidekick Interface

get_presence()

The game script must define a global function named get_presence. It should return nil if presence data is unavailable (for example, because a signature failed to resolve), or a table with the following optional fields:

  • state
  • details
  • largeImageKey
  • largeImageText
  • smallImageKey
  • smallImageText
  • partyId
  • matchSecret
  • joinSecret
  • spectateSecret

For information on these fields, see Update Presence Payload Fields.

Guidelines

  • If your script targets a game that can run as either a 32-bit or 64-bit process, make sure it checks Architecture.
  • If your script makes use of GetModuleInfo for a module besides the main executable, make sure it handles the case where the module has not been loaded yet.
  • Try not to include absolute addresses or relative offsets in your script. Instead, make use of Find.
  • If possible, cache the result of Find instead of calling it every time get_presence is called.
  • If possible, implement a sanity check that prevents any work from being done in get_presence once it fails.

Example

function read_dword(addr)
    local data = Read(addr, 4)
    if data == nil then
        return nil
    end

    local result = string.byte(data, 1);
    result |= string.byte(data, 2) << 8;
    result |= string.byte(data, 3) << 16;
    result |= string.byte(data, 4) << 24;

    return result;
end

function read_string(addr, max_size)
    local data = Read(addr, max_size)
    if data == nil then
        return nil
    end

    for i = 1, max_size do
        if data:byte(i) == 0 then
            return data:sub(1, i)
        end
    end

    return data
end

local prev_client_addr = nil
local str_addr = nil

function get_presence()
    local client_addr, client_size = GetModuleInfo("client.dll")

    if client_addr ~= prev_client_addr then
        str_adder = nil
    end

    if client_addr == nil then
        return nil
    end

    local client_end_addr = client_addr + client_size

    if str_addr == nil
        local addr = Find("8D8F........8BD0680401", client_addr, client_end_addr)
        if addr == nil then
            return nil
        end

        str_addr = read_dword(addr + 2)
    end

    local name = read_string(str_addr, 256)

    return {
        state="Playing as " .. name,
        details="hello",
        largeImageKey="foo",
        largeImageText="foo",
        smallImageKey="bar",
        smallImageText="bar"
    }
end

discord_vigilante's People

Contributors

ramsey32 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.