Created
April 5, 2021 01:51
-
-
Save kulinacs/c087d6ac27ac9e0ddc6d67ca010023f8 to your computer and use it in GitHub Desktop.
slippi discord bot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import json | |
import sys | |
import frida | |
import requests | |
WEBHOOK = "" | |
def get_player(uid): | |
return requests.get(f"https://users-rest-dot-slippi.uc.r.appspot.com/user/{uid}").json() | |
def send_results(content): | |
players = {player["uid"]: get_player(player["uid"]) for player in content["players"]} | |
title = " vs. ".join(f"{player['displayName']} ({player['connectCode']})" for player in players.values()) | |
message = { | |
"content": title, | |
"embeds": [ | |
{ | |
"title": title, | |
"description": "Slippi Netplay Match Stats", | |
"fields": [ | |
{ | |
"name": "Match Number", | |
"value": content["gameIndex"] | |
}, | |
{ | |
"name": "Duration", | |
"value": f"{content['gameDurationFrames'] / 60} seconds" | |
} | |
] | |
} | |
] | |
} | |
for player in content["players"]: | |
message["embeds"][0]["fields"].append( | |
{ | |
"name": f"{players[player['uid']]['displayName']} ({players[player['uid']]['connectCode']})", | |
"value": f"Damage Done: {player['damageDone']}\nStocks Remaining: {player['stocksRemaining']}", | |
"inline": True | |
}) | |
requests.post(WEBHOOK, json=message) | |
def on_message(message, data): | |
try: | |
payload = message['payload'] | |
if payload['type'] == 'matchResult': | |
send_results(json.loads(payload['content'])) | |
except KeyError: | |
print("unable to handled malformed message") | |
def main(): | |
session = frida.attach("Slippi Dolphin.exe") | |
script = session.create_script(""" | |
console.log("starting script"); | |
var CurlEasySetOpt = ptr('0xeecef0'); // function address pulled from Ghidra | |
Interceptor.attach(CurlEasySetOpt, { | |
onEnter: function (args) { | |
let opt = args[1].toInt32() | |
if (opt == 10015) { | |
console.log("Match completed, sending webhook") | |
send({"type": "matchResult", "content": args[2].readCString()}) | |
} | |
}, | |
// When function is finished | |
onLeave: function (retval) { | |
} | |
}); | |
""") | |
script.on('message', on_message) | |
script.load() | |
print("[!] Ctrl+D on UNIX, Ctrl+Z on Windows/cmd.exe to detach from instrumented program.\n\n") | |
sys.stdin.read() | |
session.detach() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment