Página 1 de 2

[Cleo/Lua] Mostrar dados do GTA SA no Discord (Rich Presence)

Enviado: 07 Fev 2019, 03:34
por Israel
Atualizado
  • Corrigido crash ao dirigir veículos com nome longo (16/06/2021)
  • Corrigido Camera e Night Vision com nomes alternados (16/06/2021)
  • Mod refeito em Cleo (Pode conter bugs. Avise.) (26/04/2021)

Atualizado (07/02/2019)
  • Agora também mostra informações do servidor de SAMP (Necessário SAMPFuncs);
  • Corrigido um bug na informação de kills.

Com este mod simples, alguns dados do seu GTA SA aparecerão para os outros no seu Rich Presence no Discord.
Estes dados são:
  • HP / Max HP
  • Colete / Max Colete
  • Arma / Munição
  • Dinheiro
  • Zona no mapa
  • Veículo
  • Assassinatos
  • Nível de procurado
  • Status de preso ou morto
  • SAMP ou single-player
  • Nome e endereço do servidor de SAMP (Necessário SAMPFuncs)
Preview:
Imagem
Source (Cleo)Abrir

Código: Selecionar tudo

{$Cleo}
0AA2: 0@ = load_dynamic_library "discord-rpc.asi"

0AC8: 1@ = allocate_memory_size 65 // sizeof(struct DiscordRichPresence)
0A8C: write_memory 1@ size 65 value 0 virtual_protect 0 // clear

const
    details = 0x04
    startTimestamp = 0x08
    largeImageKey = 0x18
    largeImageText = 0x1C
    smallImageKey = 0x20
    smallImageText = 0x24
    
    GetModuleHandleA = 0x0081E406
    strlen = 0x00826330
    time = 0x00824106
    
    single = 0
    samp = 1
    sampfuncs = 2
    
    kills = 121
end

0AA4: 2@ = get_dynamic_library_procedure "Discord_Initialize" library 0@
0AA4: 3@ = get_dynamic_library_procedure "Discord_UpdatePresence" library 0@

0AA5: call_function 2@ num_params 4 pop 4 optionalSteamId 0 autoRegister 0 handlers 0 applicationId "542214983115866116"

0AA7: call_function time num_params 1 pop 1 0 -> 6@

0A8E: 4@ = 1@ + startTimestamp
0A8C: write_memory 4@ size 4 value 6@ virtual_protect 0

0652: 7@ = integer_stat kills    

0AA7: call_function GetModuleHandleA num_params 1 pop 0 "samp.dll" -> 33@

if 33@ > 0
then
    0AA7: call_function GetModuleHandleA num_params 1 pop 0 "sampfuncs.asi" -> 33@
      
    if 33@ > 0
    then 8@ = sampfuncs
    else 8@ = samp
    end
end

repeat
    wait 80
until 0256:   player 0 defined

0AC8: 9@ = allocate_memory_size 320 // strings buffer
0A8C: write_memory 9@ size 320 value 0 virtual_protect 0 // clear
0085: 28@ = 9@
    
while true
    if 0118:   actor $Player_Actor dead
    then 
        0AD3: 9@ = format "game_icon_wasted"
    else 
        if 0741:   actor $Player_Actor busted
        then
            0AD3: 9@ = format "game_icon_busted"   
        else
            if or
            8@ == samp
            8@ == sampfuncs
            then
                0AD3: 9@ = format "samp_icon"
            else
                0AD3: 9@ = format "game_icon"
            end
        end
    end
    
    0A8E: 4@ = 1@ + largeImageKey
    0A8C: write_memory 4@ size 4 value 9@ virtual_protect 0
    
    if 10@ == true
    then 
        if 8@ == sampfuncs
        then
            0B4F: samp 11@ = get_gamestate
                   
            0AC6: 16@ = label @Temp offset
            0A8E: 28@ = 9@ + 18
            
            if or
            11@ == 3
            11@ == 4
            then
                0B39: samp get_current_server_address 16@ port 12@
                0AD3: 28@ = format "Address: %s:%d" 16@ 12@
            else
                0AD3: 32@s = format "SAMPST%d" 11@
                0ADE: 30@v = text_by_GXT_entry 32@s
                0AD3: 28@ = format "State: %s" 30@v
            end
            
            0A8C: write_memory 1@ size 4 value 28@ virtual_protect 0 // state
            
            0B3A: samp 16@ = get_current_server_name
            
            0A8E: 28@ = 9@ + 60            
            0AD3: 28@ = format "Server: %s" 16@
            
            0A8E: 4@ = 1@ + details
            0A8C: write_memory 4@ size 4 value 28@ virtual_protect 0
        else
            if 8@ == single
            then
                01C0: 13@ = player 0 wanted_level
                0AD3: 14@s = format "WTDLVL%d" 13@
                
                0AC6: 16@ = label @Temp offset
                0ADE: 16@ = text_by_GXT_entry 14@s
                
                0A8E: 28@ = 9@ + 18
                0AD3: 28@ = format "Wanted Level: %s" 16@
                0A8C: write_memory 1@ size 4 value 28@ virtual_protect 0 // state
    
                0652: 19@ = integer_stat kills
                0062: 19@ -= 7@
                
                0A8E: 28@ = 9@ + 40
                0AD3: 28@ = format "Kills: %d" 19@
                
                0A8E: 4@ = 1@ + details
                0A8C: write_memory 4@ size 4 value 28@ virtual_protect 0
            end
        end
        
        0AA7: call_function_return time num_params 1 pop 1 0 -> 20@
        
        if 002D: 20@ > 6@
        then
            10@ = false
            0085: 6@ = 20@
            6@ += 5
        end
    else 
        00A0: store_actor $Player_Actor position_to 21@ 22@ 23@
        0843: get_zone_at 21@ 22@ 23@ nameA_to 21@s
        
        0AC6: 29@ = label @Temp offset
        0ADE: 29@ = text_by_GXT_entry 21@s
         
        23@ = false

        if 8@ == sampfuncs
        then
            0B4F: samp 24@ = get_gamestate
            
            if or
            24@ == 3
            24@ == 4
            then
                23@ = true
            end
        else
            23@ = true
        end
        
        if 23@ == true
        then
            0A8E: 28@ = 9@ + 120
            
            if 00DF:   actor $Player_Actor driving
            then
                03C0: 24@ = actor $Player_Actor car
                0441: 24@ = car 24@ model
                0ADB: 24@s = car_model 24@ name
                
                0AA7: call_function_return strlen num_params 1 pop 1 29@ -> 26@
                0A8E: 26@ = 29@ + 26@
                26@++ 
                0ADE: 26@ = text_by_GXT_entry 24@s

                0AD3: 28@ = format "Driving %s in %s" 26@ 29@
            else
                0AD3: 28@ = format "Walking in %s" 29@
            end
            
            0A8C: write_memory 1@ size 4 value 28@ virtual_protect 0 // state
    
            010B: 33@ = player 0 money
            
            0A8E: 28@ = 9@ + 200
            0AD3: 28@ = format "Money: $%d" 33@
             
            0A8E: 4@ = 1@ + details
            0A8C: write_memory 4@ size 4 value 28@ virtual_protect 0
        end
        
        0AA7: call_function_return time num_params 1 pop 1 0 -> 20@

        if 002D: 20@ > 6@
        then
            10@ = true
            0085: 6@ = 20@
            6@ += 5
        end    
    end
    
    04DD: 30@ = actor $Player_Actor armour
    0945: get_player 0 max_armour_to 31@

    0226: 32@ = actor $Player_Actor health
    0A96: 33@ = actor $Player_Actor struct
    33@ += 0x544 // CPed->m_fMaxHealth
    0A8D: 33@ = read_memory 33@ size 4 virtual_protect 0
    0092: 33@ = float 33@ to_integer
    
    0A8E: 28@ = 9@ + 220
    
    if 30@ > 0
    then
        0AD3: 28@ = format "Armour: %d / %d Health: %d / %d" 30@ 31@ 32@ 33@
    else
        0AD3: 28@ = format "Health: %d / %d" 32@ 33@
    end
    
    0A8E: 4@ = 1@ + largeImageText
    0A8C: write_memory 4@ size 4 value 28@ virtual_protect 0
    
    0470: 2@ = actor $Player_Actor current_weapon
    
    0A8E: 28@ = 9@ + 260
    
    if 2@ > 46
    then
        0AD3: 28@ = format "weap_added" 2@
    else
        0AD3: 28@ = format "weap_%d" 2@
    end
    
    0A8E: 4@ = 1@ + smallImageKey
    0A8C: write_memory 4@ size 4 value 28@ virtual_protect 0
    
    0782: get_weapon_with_ID 2@ weapon_group_to 30@

    0A96: 29@ = actor $Player_Actor struct
    29@ += 0x5A0 // CPed->m_aWeapons
    
    0A90: 0@ = 30@ * 0x1C // sizeof(CWeapons)
    005A: 29@ += 0@
    29@ += 0x08 // m_nAmmoInClip
    0A8D: 29@ = read_memory 29@ size 4 virtual_protect 0
    
    041A: 31@ = actor $Player_Actor weapon 2@ ammo
    
    0AC6: 0@ = label @Temp offset
    0ADE: 0@ = text_by_GXT_entry 28@
    
    0A8E: 28@ = 9@ + 280
    
    if or
    30@ <= 1
    30@ >= 10
    then 
        0AD3: 28@ = format 0@    
    end
    
    if or
    30@ == 3
    30@ == 6
    30@ == 7
    30@ == 8
    then
        0AD3: 28@ = format "%s %d" 0@ 31@
    end
  
    if or
    30@ == 2
    30@ == 4
    30@ == 5
    30@ == 9
    then
        0062: 31@ -= 29@
        0AD3: 28@ = format "%s %d / %d" 0@ 29@ 31@
    end
    
    0A8E: 4@ = 1@ + smallImageText
    0A8C: write_memory 4@ size 4 value 28@ virtual_protect 0
    
    0AA5: call_function 3@ num_params 1 pop 1 presence 1@
    wait 150
end

:Temp
hex
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
end
DOWNLOAD (Versão Cleo)
Source (Lua)Abrir

Código: Selecionar tudo

script_name("SA Discord RPC")
script_properties(
    "work-in-pause",
    "forced-reloading-only"
)

local ffi = require("ffi")

ffi.cdef([[
    typedef struct {
        const char* state;
        const char* details;
        int64_t startTimestamp;
        int64_t endTimestamp;
        const char* largeImageKey;
        const char* largeImageText;
        const char* smallImageKey;
        const char* smallImageText;
        const char* partyId;
        int partySize;
        int partyMax;
        const char* matchSecret;
        const char* joinSecret;
        const char* spectateSecret;
        int8_t instance;
    } DiscordRichPresence;

    void Discord_Initialize(const char* applicationId,
        int handlers,
        int autoRegister,
        const char* optionalSteamId);

    void Discord_UpdatePresence(const DiscordRichPresence* presence);

    typedef struct {
        int type;
        int state;
        int ammoInClip;
        int totalAmmo;
        char field_10[0x0C];
    } CWeapon;

    typedef struct {
        char field_0[0x544];
        float maxHealth;
        char field_548[0x58];
        CWeapon weapons[13];
    } CPed;
]])

local weapons = {
    [0] = "Fist",
    [1] = "Brass Knuckles",
    [2] = "Golf Club",
    [3] = "Night Stick",
    [4] = "Knife",
    [5] = "Bat",
    [6] = "Shovel",
    [7] = "Pool Cue",
    [8] = "Katana",
    [9] = "Chainsaw",
    [10] = "Purple Dildo",
    [11] = "Dildo",
    [12] = "Vibrator",
    [13] = "Silver Vibrator",
    [14] = "Flowers",
    [15] = "Cane",
    [16] = "Grenade",
    [17] = "Teargas",
    [18] = "Molotov",
    [19] = "Unused",
    [20] = "Unused",
    [21] = "Unused",
    [22] = "Colt 45",
    [23] = "Silenced Pistol",
    [24] = "Desert Eagle",
    [25] = "Shotgun",
    [26] = "Sawnoff-Shotgun",
    [27] = "Combat Shotgun",
    [28] = "Uzi",
    [29] = "MP5",
    [30] = "AK-47",
    [31] = "M4",
    [32] = "Tec-9",
    [33] = "Country Rifle",
    [34] = "Sniper Rifle",
    [35] = "Rocket Launcher",
    [36] = "Heat-Seeking RPG",
    [37] = "Flamethrower",
    [38] = "Minigun",
    [39] = "Satchel Charges",
    [40] = "Detonator",
    [41] = "Spray Can",
    [42] = "Fire Extinguisher",
    [43] = "Camera",
    [44] = "Night Vision",
    [45] = "Thermal Goggles",
    [46] = "Parachute",
    [47] = "Fake Pistol",
--  [ID] = "Weapon Name",
}

local drpc = ffi.load("moonloader/lib/discord-rpc.dll")
local rpc = ffi.new("DiscordRichPresence")

function main()
    drpc.Discord_Initialize("542214983115866116", 0, 0, "")
    
    repeat
        wait(0)
    until isPlayerPlaying(playerHandle)
    
    rpc.startTimestamp = os.time()
    
    local stat = getIntStat(121)
    local time = os.time()
    local flag = false
    local samp = 0
    
    if isSampLoaded() then
        if isSampfuncsLoaded() then
            samp = 2
        else
            print("Sampfuncs required to work on samp mode.")
            samp = 1
        end
    end
    
    local cped = ffi.cast("CPed*", getCharPointer(playerPed))

    while true do
        if isCharDead(playerPed) or hasCharBeenArrested(playerPed) then
            rpc.largeImageKey = "game_icon_" .. (isCharDead(playerPed) and "wasted" or "busted")
        else
            rpc.largeImageKey = (samp >= 1 and "samp" or "game") .. "_icon"
        end

        if flag then
            if samp == 2 then
                local gameState = {
                    "None",
                    "Wait Connect",
                    "Await Join",
                    "Connected",
                    "Restarting",
                    "Disconnected"
                }

                local state = sampGetGamestate()
                
                if state == 3 or state == 4 then
                    local ip, port = sampGetCurrentServerAddress()
                    rpc.state = "Address: " .. ip .. ':' .. port
                else
                    rpc.state = "State: " .. gameState[sampGetGamestate()]
                end
                
                rpc.details = "Server: " .. sampGetCurrentServerName()
            elseif samp == 0 then
                local res, wLevel = storeWantedLevel(playerHandle)
                local stars = ""
    
                if wLevel > 0 then
                    for i = 1, wLevel do
                        stars = stars .. "☆"
                    end
                else
                    stars = "Safe"
                end
    
                rpc.state = "Wanted Level: " .. stars
                rpc.details = "Kills: " .. getIntStat(121) - stat
            end
            
            if os.time() > time + 5 then
                flag = false
                time = os.time()
            end
        else
            local zone = getGxtText(getNameOfZone(getCharCoordinates(playerPed)))
            local show = false
            
            if samp == 2 then
                local state = sampGetGamestate()
                
                if state == 3 or state == 4 then
                    show = true
                end
            else 
                show = true
            end
            
            if show then
                if isCharSittingInAnyCar(playerPed) then
                    local currCar = storeCarCharIsInNoSave(playerPed)
                    local gxtModel = getNameOfVehicleModel(getCarModel(currCar))
                    rpc.state = string.format("Driving %s in %s", getGxtText(gxtModel), zone)
                else
                    rpc.state = "Walking in " .. zone
                end

                rpc.details = "Money: $" .. getPlayerMoney(playerHandle)
            end
            
            if os.time() > time + 5 then
                flag = true
                time = os.time()
            end
        end

        local armour = getCharArmour(playerPed)
        local maxArmour = getPlayerMaxArmour(playerHandle)

        local health = getCharHealth(playerPed)
        local maxHealth = cped.maxHealth

        if armour > 0 then
            rpc.largeImageText = string.format("Armour: %.01f / %.01f Health: %.01f / %.01f",
                armour, maxArmour, health, maxHealth)
        else
            rpc.largeImageText = string.format("Health: %.01f / %.01f", health, maxHealth)
        end

        local currWeap = getCurrentCharWeapon(playerPed)
        local wpName = weapons[currWeap] or ""
        
        rpc.smallImageKey = "weap_" .. (wpName ~= "" and currWeap or "added")

        local slot = getWeapontypeSlot(currWeap)
        local clip = cped.weapons[slot].ammoInClip
        local total = cped.weapons[slot].totalAmmo

        if slot <= 1 or slot >= 10 then
            rpc.smallImageText = wpName
        end

        if slot == 3 or slot == 6 or slot == 7 or slot == 8 then
            rpc.smallImageText = string.format("%s %d", wpName, total)
        end

        if slot == 2 or slot == 4 or slot == 5 or slot == 9 then
            rpc.smallImageText = string.format("%s %d / %d", wpName, clip, total - clip)
        end

        drpc.Discord_UpdatePresence(rpc)
        wait(150)
    end
end
DOWNLOAD (Versão Lua) 

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 07 Fev 2019, 10:39
por Grinch_
nice

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 10 Fev 2019, 22:15
por Junior_Djjr
Pediram para mostrar informações do servidor do SAMP, é realmente uma ótima ideia para as pessoas irem jogar junto com você etc.

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 11 Fev 2019, 01:22
por Vanguar
Ai sim, bora esperar uma de SAMP rs.

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 11 Fev 2019, 21:51
por Israel
Vanguar escreveu:
11 Fev 2019, 01:22
Ai sim, bora esperar uma de SAMP rs.
Atualizado.

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 22 Fev 2019, 10:54
por Jacobi
E informações de cheats utilizados? :peepo5:

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 22 Fev 2019, 15:00
por Israel
Jacobi escreveu:
22 Fev 2019, 10:54
E informações de cheats utilizados? :peepo5:
Elabore.  :peepo8:

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 22 Fev 2019, 19:44
por Junior_Djjr
Acho bem desnecessário mostrar cheats.
Outras coisas poderiam ser interessantes, como o nome do carro que está dirigindo, e, só.

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 23 Fev 2019, 17:35
por Israel
Junior_Djjr escreveu:
22 Fev 2019, 19:44
como o nome do carro que está dirigindo
Mas isso já aparece:
Imagem

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 23 Fev 2019, 21:39
por XANARCHY
maneira de adicionar novos "ícones" para armas?


Exemplo:



 

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 24 Fev 2019, 02:29
por Israel
XANARCHY escreveu:
23 Fev 2019, 21:39
maneira de adicionar novos "ícones" para armas?
A API é limitada, não dá essa possibilidade.

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 17 Mai 2019, 12:45
por CanerKaraca
On the SAMP server, healthy and armor seems wrong. I have 146/146 healthy and 150/150 armor in server but plugin shows such. I don't have SAMPFUNCS.

Imagem

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 17 Mai 2019, 13:01
por CanerKaraca
Edited.

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 11 Ago 2019, 00:44
por Lockou
Não está funcionando para mim, não sei o porque

Re: [Lua] Mostrar dados do GTA no discord (Rich Presence)

Enviado: 16 Ago 2019, 11:53
por Israel
Lockou escreveu:
11 Ago 2019, 00:44
Não está funcionando para mim, não sei o porque
Mande o moonloader.log.