You'll save your mental health, and I will save time trying to understand your code. Open an issue, and I will get to it.
The code is total mess that only I can efficiently navigate through, and if someone else adds any-quality code to it, it will only get harder for me.
Any PR will be rejected, sorry.
If PR is suspected to have more than 5% of AI generated code, it will be closed ASAP, and the features will be "really" implemented by someone else, without any association with that PR. No exceptions.
So, before even thinking about putting it through a LLM, open an issue and save yourself the trouble, because others can do it for free and better.
- Don't use inheritance. It makes code even more unreadable.
- Don't use dataclasses, it's too late now, use nested lists and dicts.
- Don't write tests, this cant be tested.
- NO typing!
- Don't refactor, format (other than the existing ruff config), clean or unnecessarily optimize. I like the code the way it is.
- Don't use
requests, it uses 3MB more RAM thanhttp.client. - Use
os.pathinsteadpathlib, its making things weird. - NO
asyncio, this is purethreadingproject. - If you know how to do it, and it's not really hard, do it yourself, don't import large libraries for that.
- setup uv environment if not already:
uv sync --all-groups - Run main.py:
uv run main.py
Endcord is developed in "Modular composition and component-based architecture using singleton services with a central orchestrator". Explanation:
- Modular component-based - program is split into independent modules (classes in separate files), each responsible for a specific thing.
- Composition - main app class contains and uses instances of other classes instead of inheriting from them.
- Singleton services - for each class only one instance is used.
- Central orchestrator - Main app class is controller that: creates all instances, wires them together, does core logic.
debug_events- save all received events from gatewaydebug_guilds_tree- print all tree data in jsons255_curses_bug- this part of the code should be changed after ncurses bug is fixed. If there is no note, just remove the codefix_member_list_selection- properly select member list when figured out how to useidinGUILD_MEMBER_LIST_UPDATE.
Filter for network tab in dev tools:
-.js -css -woff -svg -webp -png -ico -webm -science -txt -mp3
sudo mv /run/user/1000/discord-ipc-0 /run/user/1000/discord-ipc-0.original
sudo socat -t100 -x -v UNIX-LISTEN:/run/user/1000/discord-ipc-0,mode=777,reuseaddr,fork UNIX-CONNECT:/run/user/1000/discord-ipc-0.originalOpen discord web or install discord-development
Or regular discord: in .config/discord/config.json put: "DANGEROUS_ENABLE_DEVTOOLS_ONLY_ENABLE_IF_YOU_KNOW_WHAT_YOURE_DOING": true
Open dev tools: Ctrl+Shift+I
Type: allow pasting
Paste code from here
Go to discord settings, in developer options, logging tab, enable "Logging Gateway Events to Console"
In dev tools console select "Verbose" level (chrome and desktop client only)
https://github.com/discord-userdoccers/discord-userdoccers
https://discord.com/developers/docs/change-log#upcoming-application-command-permission-changes
Standard:
┌────────────────────────────────────────────────┐
│┌─TITLE─┐┌─────────────── TITLE ─────┐┌────────┐│
││ ││ ││ ││
││ ││ ││ MEMBER ││
││ ││ CHAT ││ LIST ││
││ ││ ││ ││
││ ││ ││ ││
││ TREE │└───────────────────────────┘└────────┘│
││ │┌────────────── EXTRA2 ───────────────┐│
││ ││ EXTRA BODY ││
││ │┌────────────── EXTRA1 ───────────────┐│
││ │├────────────── STATUS ───────────────┤│
││ ││[PROMPT]> ││
│└───────┘└─────────────────────────────────────┘│
└────────────────────────────────────────────────┘
Compact:
┌────────────────────────────────────────────────┐
│W TITLE W│WWWWWWWWWWWWWWW TITLE WWWWWWWWWWWWWWWW│
│ │ │ │
│ │ │ │
| │ │ MEMBER │
│ │ CHAT │ LIST │
│ │ │ │
│ │ │ │
│ TREE │ │ │
│ │MMMMMMMMMMMMMMM EXTRA2 MMMMMMMMMMMMMMM│
│ │ EXTRA BODY │
│ │UUUUUUUUUUUUUUU EXTRA1 UUUUUUUUUUUUUUU│
│ │WWWWWWWWWWWWWWW STATUS WWWWWWWWWWWWWWW│
│ │[PROMPT]> │
└────────────────────────────────────────────────┘
> FOLDER
> GUILD
|--> CATEGORY
| |-- CHANNEL
| |--> CHANNEL
| | |-< THREAD
| | \-< THREAD
| | end_channel 1300
| \--> CHANNEL
| end_category 1200
|--> CATEGORY
| end_category 1200
end_guild 1100
end_folder 1000
inflator = zstandard.ZstdDecompressor().decompressobj()
def zstd_decompress(data):
"""Decompress zstd stream"""
buffer = bytearray(data)
try:
return inflator.decompress(buffer)
except zstandard.ZstdError as e:
logger.error(f"zstd error: {e}")
return NoneUse &compress=zstd-stream in gateway url.
import base64
import json
encoded = "STRING_HERE"
decoded = json.loads(base64.b64decode(encoded).decode("utf-8"))
print(json.dumps(decoded, indent=2))In the code, all spacebar fixes can be found as # spacebar_fix - [note].
[note] contains some information on what is changed.
-
/api/v9/users/@me/mentions: /global_name - missing -
/api/v9/users/{my_id}/channels: /recipients/global_name - missing -
/api/v9/users/{user_id}/profile:
/user/avatar_decoration_data - missing
user/flags - missing
/user/global_name - missing
/user/primary_guild - missing -
MESSAGE_CREATE,MESSAGE_UPDATE,/api/v9/channels/{channel_id}/messages,/api/v9/guilds/{guild_id}/messages/searchand/api/v9/channels/{channel_id}/pins: /author/global_name - missing
/referenced_message - should be null only if its pointing to delteted message, otherwise remove this field
/referenced_message/author/global_name - missing
/reactions/emoji/id - missing
/poll - should be removed if itsnull
/interaction - should be removed if itsnull
/mentions/username - missing
/embeds/type - missing
/edited_timestamp - missing for some messages -
READY:
/merged_members/id - should be /merged_members/user_id
/read_state/entries/mention_count - should be0, notnull
/private_channels/recipient_ids - missing, have recipients list instead /users/global_name - missing
/user_guild_settings/entries/channel_overrides/collapsed - missing -
TYPING_START: /member/user/global_name - missing -
GUILD_MEMBER_LIST_UPDATE: /items/member/user/global_name - missing
/item/member/user/global_name - missing -
MESSAGE_REACTION_ADD: /member/user - missing
/emoji/id - missing when its standard emoji -
MESSAGE_REACTION_REMOVE: /emoji/id - missing when its standard emoji -
GUILD_MEMBERS_CHUNK: /members/user/global_name - missing -
PRESENCE_UPDATE: /status - missing -
Misc: Spacebar is still using old
user_settingsinstead new protobuf settings.
Gateway returns error code 4000 if event "update presence" (opcode 3) is sent.
- setup dependencies
- Any python virtual environment manager can be used that can read dependencies from pyproject.toml, here uv is used by default.
- Only python versions 3.12-3.13 can currently build binaries.
uv sync --all-groups- full endcord
Will install all dependencies from pyproject.toml underdependencies,build, andmedia.uv sync --group build- endcord-lite
Will install all dependencies from pyproject.toml underdependenciesandbuild.
- Check if numpy without openblas is already installed, if returns 1 them it must download and build numpy
- Numpy build can be skipped if its impossible, but binary will be few MB larger.
- If building with pyinstaller skip numpy build.
- This command will print
1if openblas is found in numpy, and then it has to be built locally.
uv run python -c "import numpy; print(int(numpy.__config__.show_config('dicts')['Build Dependencies']['blas'].get('found', False)))"- Download and build numpy
- Clang is optional everywhere, but it's recommended as it provides better binary.
export CC=clang
export CXX=clang++
uv pip install pip
.venv/bin/python -m pip uninstall --yes numpy
.venv/bin/python -m pip install --no-cache-dir --no-binary=:all: numpy --config-settings=setup-args=-Dblas=None --config-settings=setup-args=-Dlapack=None
uv pip uninstall pip- Build cython extensions
- Skip this step only if final binary gives error
Dynamic module does not define module export function.
export CC=clang
export CXX=clang++
uv run python setup.py build_ext --inplace- Run patches and cleanups
- run
patch_soundcard()from build.py - required! - run
clean_emoji()from build.py - will remove many non-standard emoji. - run
clean_qrcode()from build.py - will reduce binary by ~100KB.
- Get and run build command
- Build commands can be obtained by running
python build.py --print-cmd, adding other arguments will change the printed command. - Recommended:
python build.py --print-cmd --nuitka --clang.