Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Loups Transparency #165

Merged
merged 27 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
833e43a
Loups request
brostosjoined Jul 19, 2023
768b28b
Delete plugins/resources directory
brostosjoined Jul 21, 2023
e8603f7
Delete discord_richpresence.py
brostosjoined Jul 21, 2023
9f82a40
Add files via upload
brostosjoined Jul 21, 2023
250bc1f
Update discord_richpresence.py
brostosjoined Jul 21, 2023
0af7b4a
Update utilities.json
brostosjoined Jul 21, 2023
e17dccd
Update utilities.json
brostosjoined Jul 21, 2023
97885d7
[ci] auto-format
brostosjoined Jul 21, 2023
4e926ae
Update utilities.json
brostosjoined Jul 21, 2023
05f20a0
Update utilities.json
brostosjoined Jul 21, 2023
e20efd8
work
brostosjoined Jul 21, 2023
81abddf
[ci] apply-version-metadata
brostosjoined Jul 21, 2023
3c83efc
Update discord_richpresence.py
brostosjoined Jul 21, 2023
16b9b54
[ci] auto-format
brostosjoined Jul 21, 2023
8f02db1
Update utilities.json
brostosjoined Jul 21, 2023
c4916e8
[ci] apply-version-metadata
brostosjoined Jul 21, 2023
5bfc25c
Delete discord_richpresence.py
brostosjoined Jul 22, 2023
d9b25ea
Add files via upload
brostosjoined Jul 22, 2023
5f2e53d
[ci] auto-format
brostosjoined Jul 22, 2023
7c07409
hopefully final
brostosjoined Jul 22, 2023
cb86247
[ci] apply-version-metadata
brostosjoined Jul 22, 2023
c74b470
Fixed time on mobile rich presence
brostosjoined Jul 22, 2023
88bb90a
[ci] auto-format
brostosjoined Jul 22, 2023
01f48c5
md5
brostosjoined Jul 23, 2023
e32326d
[ci] auto-format
brostosjoined Jul 23, 2023
90fff9b
Update utilities.json
brostosjoined Jul 23, 2023
da69d3d
[ci] apply-version-metadata
brostosjoined Jul 23, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions plugins/utilities.json
Original file line number Diff line number Diff line change
Expand Up @@ -767,6 +767,12 @@
}
],
"versions": {
"1.1.0": {
"api_version": 8,
"commit_sha": "90fff9b",
"released_on": "23-07-2023",
"md5sum": "69723f76a0114fe99d6c85715ad4eb49"
},
"1.0.0": {
"api_version": 8,
"commit_sha": "230d12d",
Expand Down
242 changes: 149 additions & 93 deletions plugins/utilities/discord_richpresence.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from urllib.request import Request, urlopen, urlretrieve
from pathlib import Path
from os import getcwd, remove
from zipfile import ZipFile
from bauiv1lib.popup import PopupWindow
from babase._mgen.enums import TimeType

Expand All @@ -22,6 +21,7 @@
import time
import threading
import shutil
import hashlib
import babase
import _babase
import bascenev1 as bs
Expand All @@ -42,29 +42,44 @@
# Installing websocket
def get_module():
install_path = Path(f"{getcwd()}/ba_data/python") # For the guys like me on windows
path = Path(f"{install_path}/websocket.zip")
path = Path(f"{install_path}/websocket.tar.gz")
file_path = Path(f"{install_path}/websocket")
source_dir = Path(f"{install_path}/websocket-client-1.6.1/websocket")
if not file_path.exists():
url = "https://github.com/brostosjoined/bombsquadrpc/releases/download/presence-1.0/websocket.zip"
url = "https://files.pythonhosted.org/packages/b1/34/3a5cae1e07d9566ad073fa6d169bf22c03a3ba7b31b3c3422ec88d039108/websocket-client-1.6.1.tar.gz"
try:
filename, headers = urlretrieve(url, filename=path)
with ZipFile(filename) as f:
f.extractall(install_path)
with open(filename, "rb") as f:
content = f.read()
assert hashlib.md5(content).hexdigest() == "86bc69b61947943627afc1b351c0b5db"
shutil.unpack_archive(filename, install_path)
shutil.copytree(source_dir, file_path)
shutil.rmtree(Path(f"{install_path}/websocket-client-1.6.1"))
remove(path)
except:
pass
except Exception as e:
if type(e) == shutil.Error:
shutil.rmtree(Path(f"{install_path}/websocket-client-1.6.1"))
else:
pass
get_module()

from websocket import WebSocketConnectionClosedException
import websocket

heartbeat_interval = int(41250)
resume_gateway_url: str | None = None
session_id: str | None = None

start_time = time.time()

class PresenceUpdate:
def __init__(self):
self.ws = websocket.WebSocketApp("wss://gateway.discord.gg/?encoding=json&v=10",
on_open=self.on_open,
on_message=self.on_message,
on_error=self.on_error,
on_close=self.on_close)
self.heartbeat_interval = int(41250)
self.resume_gateway_url: str | None = None
self.session_id: str | None = None
self.stop_heartbeat_thread = threading.Event()
self.do_once = True
self.state: str | None = "In Game"
self.details: str | None = "Main Menu"
self.start_timestamp = time.time()
Expand Down Expand Up @@ -127,102 +142,137 @@ def presence(self):
],
},
}
ws.send(json.dumps(presencepayload))

def on_message(ws, message):
global heartbeat_interval, resume_gateway_url, session_id
message = json.loads(message)
try:
heartbeat_interval = message["d"]["heartbeat_interval"]
except:
pass
try:
resume_gateway_url = message["d"]["resume_gateway_url"]
session_id = message["d"]["session_id"]
except:
pass

def on_error(ws, error):
babase.print_exception(error)

def on_close(ws, close_status_code, close_msg):
# print("### closed ###")
pass
try:
self.ws.send(json.dumps(presencepayload))
except WebSocketConnectionClosedException:
pass

def on_open(ws):
print("Connected to Discord Websocket")

def heartbeats():
"""Sending heartbeats to keep the connection alive"""
global heartbeat_interval
if babase.do_once():
heartbeat_payload = {
"op": 1,
"d": 251,
} # step two keeping connection alive by sending heart beats and receiving opcode 11
ws.send(json.dumps(heartbeat_payload))

def identify():
"""Identifying to the gateway and enable by using user token and the intents we will be using e.g 256->For Presence"""
with open(f"{getcwd()}/token.txt", 'r') as f:
token = bytes.fromhex(f.read()).decode('utf-8')
identify_payload = {
"op": 2,
"d": {
"token": token,
"properties": {
"os": "linux",
"browser": "Discord Android",
"device": "android",
def on_message(self, ws, message):
message = json.loads(message)
try:
self.heartbeat_interval = message["d"]["heartbeat_interval"]
except:
pass
try:
self.resume_gateway_url = message["d"]["resume_gateway_url"]
self.session_id = message["d"]["session_id"]
except:
pass

def on_error(self, ws, error):
babase.print_exception(error)

def on_close(self, ws, close_status_code, close_msg):
print("Closed Discord Connection Successfully")

def on_open(self, ws):
print("Connected to Discord Websocket")

def heartbeats():
"""Sending heartbeats to keep the connection alive"""
if self.do_once:
heartbeat_payload = {
"op": 1,
"d": 251,
} # step two keeping connection alive by sending heart beats and receiving opcode 11
self.ws.send(json.dumps(heartbeat_payload))
self.do_once = False

def identify():
"""Identifying to the gateway and enable by using user token and the intents we will be using e.g 256->For Presence"""
with open(f"{getcwd()}/token.txt", 'r') as f:
token = bytes.fromhex(f.read()).decode('utf-8')
identify_payload = {
"op": 2,
"d": {
"token": token,
"properties": {
"os": "linux",
"browser": "Discord Android",
"device": "android",
},
"intents": 256,
},
"intents": 256,
},
} # step 3 send an identify
ws.send(json.dumps(identify_payload))
identify()
while True:
heartbeat_payload = {"op": 1, "d": heartbeat_interval}
ws.send(json.dumps(heartbeat_payload))
time.sleep(heartbeat_interval / 1000)

threading.Thread(target=heartbeats, daemon=True, name="heartbeat").start()

# websocket.enableTrace(True)
ws = websocket.WebSocketApp(
"wss://gateway.discord.gg/?encoding=json&v=10",
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close,
)
if Path(f"{getcwd()}/token.txt").exists():
threading.Thread(target=ws.run_forever, daemon=True, name="websocket").start()
} # step 3 send an identify
self.ws.send(json.dumps(identify_payload))
identify()
while True:
heartbeat_payload = {"op": 1, "d": self.heartbeat_interval}

try:
self.ws.send(json.dumps(heartbeat_payload))
time.sleep(self.heartbeat_interval / 1000)
except:
pass

if self.stop_heartbeat_thread.is_set():
self.stop_heartbeat_thread.clear()
break

threading.Thread(target=heartbeats, daemon=True, name="heartbeat").start()

def start(self):
if Path(f"{getcwd()}/token.txt").exists():
threading.Thread(target=self.ws.run_forever, daemon=True, name="websocket").start()

def close(self):
self.stop_heartbeat_thread.set()
self.do_once = True
self.ws.close()


if not ANDROID:
# installing pypresence
def get_module():
install_path = Path(f"{getcwd()}/ba_data/python")
path = Path(f"{install_path}/pypresence.zip")
path = Path(f"{install_path}/pypresence.tar.gz")
file_path = Path(f"{install_path}/pypresence")
source_dir = Path(f"{install_path}/pypresence-4.3.0/pypresence")
if not file_path.exists():
url = "https://github.com/brostosjoined/bombsquadrpc/releases/download/presence-1.0/pypresence.zip"
url = "https://files.pythonhosted.org/packages/f4/2e/d110f862720b5e3ba1b0b719657385fc4151929befa2c6981f48360aa480/pypresence-4.3.0.tar.gz"
try:
filename, headers = urlretrieve(url, filename=path)
with ZipFile(filename) as f:
f.extractall(install_path)
with open(filename, "rb") as f:
content = f.read()
assert hashlib.md5(content).hexdigest() == "f7c163cdd001af2456c09e241b90bad7"
shutil.unpack_archive(filename, install_path)
shutil.copytree(source_dir, file_path)
shutil.rmtree(Path(f"{install_path}/pypresence-4.3.0"))
remove(path)
except:
pass
get_module()

# Updating pypresence
# Make modifications for it to work on windows
if babase.app.classic.platform == "windows":
with open(Path(f"{getcwd()}/ba_data/python/pypresence/utils.py"), "r") as file:
data = file.readlines()
data[45] = """
def get_event_loop(force_fresh=False):
loop = asyncio.ProactorEventLoop() if sys.platform == 'win32' else asyncio.new_event_loop()
if force_fresh:
return loop
try:
from pypresence import PipeClosed, DiscordError, DiscordNotFound
except ImportError:
shutil.rmtree(Path(f"{getcwd()}/ba_data/python/pypresence"))
get_module()
running = asyncio.get_running_loop()
except RuntimeError:
return loop
if running.is_closed():
return loop
else:
if sys.platform in ('linux', 'darwin'):
return running
if sys.platform == 'win32':
if isinstance(running, asyncio.ProactorEventLoop):
return running
else:
return loop"""

with open(Path(f"{getcwd()}/ba_data/python/pypresence/utils.py"), "w") as file:
for number, line in enumerate(data):
if number not in range(46, 56):
file.write(line)
get_module()

from pypresence import PipeClosed, DiscordError, DiscordNotFound
from pypresence.utils import get_event_loop
import pypresence
import socket
Expand Down Expand Up @@ -608,7 +658,7 @@ def login(self):
bui.getsound('shieldDown').play()
bui.screenmessage("Account successfully removed!!", (0.10, 0.10, 1.00))
self.on_bascenev1libup_cancel()
ws.close()
PresenceUpdate().ws.close()


run_once = False
Expand Down Expand Up @@ -667,6 +717,7 @@ def on_app_running(self) -> None:
1, bs.WeakCall(self.update_status), repeat=True
)
if ANDROID:
self.rpc_thread.start()
self.update_timer = bs.AppTimer(
4, bs.WeakCall(self.update_status), repeat=True
)
Expand All @@ -685,9 +736,14 @@ def on_app_shutdown(self) -> None:
if not ANDROID and self.rpc_thread.is_discord_running():
self.rpc_thread.rpc.close()
self.rpc_thread.should_close = True
else:
# stupid code
ws.close()

def on_app_pause(self) -> None:
self.rpc_thread.close()

def on_app_resume(self) -> None:
global start_time
start_time = time.time()
self.rpc_thread.start()

def _get_current_activity_name(self) -> str | None:
act = bs.get_foreground_host_activity()
Expand Down