Compare commits

..

No commits in common. "2021-05-31" and "master" have entirely different histories.

3968 changed files with 1769 additions and 2815168 deletions

2
.gitattributes vendored
View File

@ -1,2 +0,0 @@
* text=auto eol=lf

12
.gitignore vendored
View File

@ -1,14 +1,2 @@
patches/*/*-custom.patch
patches/*/*.patch-failed
resources/distok/versionlogs/*
!resources/distok/versionlogs/.gitkeep
resources/fdroid/repo/icons/*.xml
resources/fonts/*.ttf
resources/fonts/*.otf
resources/icons/others/*
!resources/icons/others/.gitkeep
resources/ringtones/*
!resources/ringtones/.gitkeep
resources/keystores/*
!resources/keystores/.gitkeep
*.apk

View File

@ -2,7 +2,7 @@
#### Toolchain setup
- Get apktool (use [this self-built version](//f001.backblazeb2.com/file/avepub/apktool-cli-all.jar) which is master + [this pr](https://github.com/iBotPeaches/Apktool/pull/2463)).
- Get apktool (due to 2 bugs present in v2.3.4, you're strongly recommended to use v2.4.0 or higher, I compile latest from source).
- Get a keystore, see [here](https://stackoverflow.com/a/14994354/3286892), step 1.
- Get apksigner, it's part of android build tools.
- If you want Mutant Standard emoji patches, get 72x72 PNG copies of latest version of mutant standard emojis with codepoints. I have a zip [here](https://mutant.lavatech.top/72x72.zip).
@ -21,8 +21,9 @@ CTCCI requires python3.6+, and also likely requires Linux (I haven't tried it on
#### Initial setup
- Follow the "Toolchain setup" steps above in case you haven't already.
- Install dependencies (`python3 -m pip install -Ur requirements.txt`)
- Copy `ctcci/ctcconfig.example.py` to `ctcci/ctcconfig.py` and configure contents to your local data and your personal preferences.
- If you don't want to always automatically be required to use the latest discord version, edit the `$REPO_FOLDER/patchport-state.json` file.
- If you don't want to always automatically be required to use the latest discord version, set `LOCAL_STATE` to `True` and point `STATE_FILE` to a `state.json` file that looks like this: `{"android": {"com.discord": {"version": 909}}}`.
- Set up a local distok-style file storage for your APKs, and copy your APKs on it, and name them properly (the format is `$DISTOK_FOLDER/android/$PACKAGE_ID-$VERSION_NUMBER.apk`, example: `/home/ave/distok/android/com.discord-909.apk`).
#### Environment Variables
@ -60,11 +61,11 @@ To get the diff, run `diff -crB -x "dist" -x "res/raw" -x "build" CleanFolder Pa
#### Porting patches
You can use `patchport.py` to easily attempt to port patches. This is what I use to port between every single version. Note that while CTCCI requires python3.6+, `patchport.py` requires python3.7+.
You can use `patchport.py` to easily attempt to port patches. This is what I use to port between every single version.
It's not really intelligent and doesn't do much more than manually preparing necessary patch, checking if an existing patch can be applied to a given version, replacing relevant variables required for porting various patches and eliminating offsets caused by updates, but it saves a lot of time if used carefully.
Example command: `python3.7 patchport.py /home/ave/workbench/ctc/com.discord-968`
Example command: `python3 patchport.py /home/ave/workbench/ctc/com.discord-968`
#### Figuring out which patch is causing your build to break

View File

@ -1,68 +0,0 @@
FROM ubuntu:21.04
# Install needed packages
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install python3 android-sdk-build-tools wget unzip imagemagick git patch software-properties-common
# Mirror is being weird currently so install this seperatly
RUN apt-get update
RUN DEBIAN_FRONTEND=noninteractive apt-get -y install zipmerge
# Install fdroid
RUN add-apt-repository ppa:fdroid/fdroidserver
RUN apt-get update
RUN apt-get -y install fdroidserver
# Create resources folder for tools/images etc
ENV CTC_FOLDER=/opt/ctc
RUN mkdir ${CTC_FOLDER}
# Grab modified apktool
RUN mkdir ${CTC_FOLDER}/tools
RUN wget -O ${CTC_FOLDER}/tools/apktool.jar https://f001.backblazeb2.com/file/avepub/apktool-cli-all.jar
# Grab xml-patch (https://github.com/dnault/xml-patch)
RUN wget -O ${CTC_FOLDER}/tools/xml-patch.jar https://jcenter.bintray.com/com/github/dnault/xml-patch/0.3.1/xml-patch-0.3.1.jar
# Grab dex2jar (https://github.com/Aliucord/dex2jar)
RUN wget -O ${CTC_FOLDER}/tools/dex2jar.jar https://github.com/Aliucord/dex2jar/releases/download/v19-fork2/dex2jar.jar
# Grab emoji sets
ENV EMOJI_PATH=${CTC_FOLDER}/emojis
ENV EMOJI_MUTANT_PATH=${EMOJI_PATH}/mutant
ENV EMOJI_BLOBMOJIS_PATH=${EMOJI_PATH}/blobmojis
RUN mkdir ${EMOJI_PATH}
# Mutant emojis
RUN mkdir ${EMOJI_MUTANT_PATH}
WORKDIR ${EMOJI_MUTANT_PATH}
RUN wget https://mutant.lavatech.top/72x72.zip
RUN unzip 72x72.zip
RUN mv 72x72/*.png .
RUN rm -rf 72x72
RUN rm 72x72.zip
# Blobmojis
RUN mkdir ${EMOJI_BLOBMOJIS_PATH}
RUN mkdir /tmp/blobmoji
WORKDIR /tmp/blobmoji
RUN wget https://github.com/C1710/blobmoji/archive/refs/heads/main.zip
RUN 7za x main.zip
WORKDIR /tmp/blobmoji/blobmoji-main/svg
RUN find ./*.svg -exec mogrify -format png -resize 72x72 -path ${EMOJI_BLOBMOJIS_PATH} {} \; ; exit 0
# Generate self signed KS
RUN mkdir ${CTC_FOLDER}/keystores
WORKDIR ${CTC_FOLDER}/keystores
RUN keytool -genkey -alias test \
-keyalg RSA -keystore keystore.jks \
-dname "CN=Test, OU=Test, O=Test, L=Test, S=Test, C=Test" \
-storepass password -keypass password
# Make folder for git repo
RUN mkdir ${CTC_FOLDER}/gitrepo
WORKDIR ${CTC_FOLDER}/gitrepo
# paths in ctcconfig in docker
# container fs
# /opt/ctc/gitrepo
# /opt/ctc/keystores/keystore.jks not specified by default

View File

@ -2,17 +2,11 @@
Modular Client Mod for Discord's Android app.
**THIS IS A WORK IN PROGRESS BRANCH! SOME PATCHES ARE MISSING (tokenlogin, hideunusableemojis, plus showtag has a bug)!**
Current state is good enough™ for an RC release, and there's currently RC releases in the repo. Update away!
For status updates and support on the project, join #cutthecord on https://libera.chat. WebIRC link: https://web.libera.chat/#cutthecord
**Latest supported Discord Android version:** 87.2 - Alpha (87202), released on 2021-08-04.
**Latest supported Discord Android version:** 34.0 (1213), released on 2020-07-29.
New patch development will be done for the latest supported version.
![A CutTheCord screenshot](https://elixi.re/t/m16z287iw.png)
![A CutTheCord screenshot](https://elixi.re/t/mh3eirsy9.png)
Check out [README.md in patches folder to see what patches are available and what each of them do](patches/README.md)!
@ -29,8 +23,3 @@ If you fail recaptcha, [follow this](https://gitdab.com/distok/cutthecord/issues
## Building
See [BUILDING.md](BUILDING.md).
## License
- CTCCI, patchport and other scripts are AGPLv3.
- We chose to not license the patches, and are therefore "All Rights Reserved". However, you're allowed to use it to build your own version of CutTheCord, fork CutTheCord, develop your own patches etc, and we kindly ask you to send us any patches you develop that you think may be helpful. You're free to distribute binaries (apks) including CutTheCord patches as long as you give appropriate credit to the CutTheCord project.

1
ctcci/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
ctcconfig.py

124
resources/scripts/ctcci/ctcci.py → ctcci/ctcci.py Executable file → Normal file
View File

@ -14,20 +14,14 @@ FORCE = False
DEFAULT_PATCHES = ["necessary", "branding", "customversion"]
OPTIONAL_PATCHES = ["necessary", "blobs"]
def xmlpatch(patch_file, workdir, patch_name=""):
if not os.path.exists(patch_file):
# Allow missing patches
return
print(f"Applying {patch_file}")
subprocess.run(f"{XML_PATCH_BIN} com.github.dnault.xmlpatch.BatchPatcher --patch {patch_file} --srcdir {workdir}",
shell=True, check=True, cwd=workdir)
def patch(patch_file, workdir, patch_name=""):
if not os.path.exists(patch_file):
# Allow missing patches
return
# Allow missing optional patches
if patch_name in OPTIONAL_PATCHES:
return
raise FileNotFoundError(f"No patches with name \"{patch_file}\" :(")
print(f"Applying {patch_file}")
@ -43,15 +37,11 @@ os.environ["DISTOK_EXTRACTED_DISCORD_PATH"] = WORK_APK_PATH
os.makedirs(WORK_FOLDER, exist_ok=True)
with open(os.path.join(REPO_FOLDER, "resources/patchport-state.json")) as f:
with open(os.path.join(REPO_FOLDER, "patchport-state.json")) as f:
STATE = json.load(f)
VERSION = STATE["versioncode"]
BASE_APK_PATH = os.path.join(WORK_FOLDER, f"discord-base-{VERSION}")
BASE_JAR_PATH = os.path.join(WORK_FOLDER, f"discord-base-{VERSION}-jar")
# Wipe and recreate the base jar folder
if os.path.exists(BASE_JAR_PATH):
shutil.rmtree(BASE_JAR_PATH)
# Prepare names of input and output APKs
INPUT_FILE = os.path.join(DISTOK_FOLDER, "android",
@ -79,49 +69,51 @@ if DO_GITPULL:
# Extract the APK if it's not already extracted to base cache
if not os.path.exists(BASE_APK_PATH):
subprocess.run(f"{APKTOOL_BIN} d --no-dummy {INPUT_FILE} -o {BASE_APK_PATH} -f",
subprocess.run(f"{APKTOOL_BIN} d {INPUT_FILE} -o {BASE_APK_PATH} -f",
shell=True,
cwd=WORK_FOLDER)
# Convert the dexs to a jar (for slashcommands etc) TODO versionise gradle/this
if not os.path.exists(BASE_JAR_PATH):
subprocess.run(f"unzip -j {INPUT_FILE} *.dex -d {BASE_JAR_PATH}", shell=True, cwd=WORK_FOLDER)
subprocess.run(f"{DEX2JAR_BIN} *.dex", shell=True, cwd=BASE_JAR_PATH)
subprocess.run(f"zipmerge discord-base.jar classes*dex2jar.jar", shell=True, cwd=BASE_JAR_PATH)
# Copy the base cache to work on it
shutil.copytree(BASE_APK_PATH, WORK_APK_PATH)
# Go through patches and apply every single one of them
for patch_name in PATCHES:
pre_script = os.path.join(REPO_FOLDER, "resources/patches", patch_name, f"{VERSION}-pre.sh")
pre_script = os.path.join(REPO_FOLDER, "patches",
patch_name, f"{VERSION}-pre.sh")
if os.path.exists(pre_script):
subprocess.run(f"bash {pre_script}", shell=True, cwd=WORK_APK_PATH)
pre_script = os.path.join(REPO_FOLDER, "resources/xmlpatches", patch_name, f"{VERSION}-pre.sh")
if os.path.exists(pre_script):
subprocess.run(f"bash {pre_script}", shell=True, cwd=WORK_APK_PATH)
subprocess.run(f"bash {pre_script}",
shell=True,
cwd=WORK_APK_PATH)
# Apply custom emoji patches
if patch_name in ["mutant", "blobs"]:
print(f"Applying {patch_name} emoji patch")
patch_script = os.path.join(REPO_FOLDER, "resources/patches", patch_name, "emojireplace.py")
subprocess.run(f"{PYTHON_BIN} {patch_script}", shell=True, cwd=WORK_APK_PATH)
patch_script = os.path.join(REPO_FOLDER, "patches",
patch_name, "emojireplace.py")
subprocess.run(f"{PYTHON_BIN} {patch_script}",
shell=True,
cwd=WORK_APK_PATH)
# Apply custom emoji patches
elif patch_name == "customtheme":
print(f"Applying splash patch")
splash = os.path.join(REPO_FOLDER, "resources/patches", patch_name, "asset_loading.png")
patch_script = os.path.join(REPO_FOLDER, "resources/patches", patch_name, "fixsplash.sh")
splash = os.path.join(REPO_FOLDER, "patches",
patch_name, "asset_loading.png")
patch_script = os.path.join(REPO_FOLDER, "patches",
patch_name, "fixsplash.sh")
subprocess.run(f"bash {patch_script} {splash}", shell=True, cwd=WORK_APK_PATH)
subprocess.run(f"bash {patch_script} {splash}",
shell=True,
cwd=WORK_APK_PATH)
patch_file = os.path.join(REPO_FOLDER, "resources/patches", patch_name, f"{VERSION}.patch")
xml_patch_file = os.path.join(REPO_FOLDER, "resources/xmlpatches", patch_name, f"{VERSION}.xml")
patch_file = os.path.join(REPO_FOLDER, "patches",
patch_name, f"{VERSION}.patch")
# Apply custom version patches
if patch_name == "customversion":
print(f"Applying custom version")
patch_script = os.path.join(REPO_FOLDER, "resources/patches", patch_name, "addpatch.py")
patch_script = os.path.join(REPO_FOLDER, "patches",
patch_name, "addpatch.py")
subprocess.run(f"{PYTHON_BIN} {patch_script} {patch_file} "
f"{' '.join(PATCHES)}",
@ -134,27 +126,44 @@ for patch_name in PATCHES:
print(f"Applying branding icon patch")
if BRANCH in ICONS:
shutil.copyfile(ICONS[BRANCH],
os.path.join(WORK_APK_PATH, "res", "mipmap-xxxhdpi", "logo_debug.png"))
os.path.join(WORK_APK_PATH, "res",
"mipmap-xxxhdpi", "logo_debug.png"))
elif "default" in ICONS:
shutil.copyfile(ICONS["default"],
os.path.join(WORK_APK_PATH, "res", "mipmap-xxxhdpi", "logo_debug.png"))
os.path.join(WORK_APK_PATH, "res",
"mipmap-xxxhdpi", "logo_debug.png"))
if BRANCH in DYN_ICONS:
shutil.copyfile(DYN_ICONS[BRANCH]["bg"],
os.path.join(WORK_APK_PATH, "res",
"mipmap-xxxhdpi",
"ic_launcher_background.png"))
shutil.copyfile(DYN_ICONS[BRANCH]["fg"],
os.path.join(WORK_APK_PATH, "res", "mipmap-xxxhdpi", "ic_launcher_foreground.png"))
os.path.join(WORK_APK_PATH, "res",
"mipmap-xxxhdpi",
"ic_launcher_foreground.png"))
elif "default" in ICONS:
shutil.copyfile(DYN_ICONS["default"]["bg"],
os.path.join(WORK_APK_PATH, "res",
"mipmap-xxxhdpi",
"ic_launcher_background.png"))
shutil.copyfile(DYN_ICONS["default"]["fg"],
os.path.join(WORK_APK_PATH, "res", "mipmap-xxxhdpi", "ic_launcher_foreground.png"))
os.path.join(WORK_APK_PATH, "res",
"mipmap-xxxhdpi",
"ic_launcher_foreground.png"))
patch_script = os.path.join(REPO_FOLDER, "resources/patches", patch_name, "customicon.sh")
patch_script = os.path.join(REPO_FOLDER, "patches",
patch_name, "customicon.sh")
subprocess.run(f"bash {patch_script}", shell=True, cwd=WORK_APK_PATH)
patch_script = os.path.join(REPO_FOLDER, "resources/patches", patch_name, "customdynamicicon.sh")
patch_script = os.path.join(REPO_FOLDER, "patches",
patch_name, "customdynamicicon.sh")
subprocess.run(f"bash {patch_script}", shell=True, cwd=WORK_APK_PATH)
patch_script = os.path.join(REPO_FOLDER, "resources/patches", patch_name, "addpatch.py")
patch_script = os.path.join(REPO_FOLDER, "patches",
patch_name, "addpatch.py")
# Hell code
app_name = APP_NAMES.get(BRANCH, APP_NAMES.get("default", "CutTheCord"))
@ -167,9 +176,13 @@ for patch_name in PATCHES:
patch(patch_file.replace(".patch", "-custom.patch"), WORK_APK_PATH)
elif patch_name in ["bettertm", "bettertmlight"]:
print(f"Applying bettertm emoji patch")
patch_dir = os.path.join(REPO_FOLDER, "resources/patches", patch_name)
patch_script = os.path.join(REPO_FOLDER, "resources/patches", patch_name, "bettertm.sh")
subprocess.run(f"bash {patch_script} {patch_dir}", shell=True, cwd=WORK_APK_PATH)
patch_dir = os.path.join(REPO_FOLDER, "patches",
patch_name)
patch_script = os.path.join(REPO_FOLDER, "patches",
patch_name, "bettertm.sh")
subprocess.run(f"bash {patch_script} {patch_dir}",
shell=True,
cwd=WORK_APK_PATH)
# Apply custom ringtone
elif patch_name == "customring":
print(f"Applying custom ringtone")
@ -178,7 +191,9 @@ for patch_name in PATCHES:
else:
CUSTOM_RINGTONE = RINGTONES["default"]
shutil.copyfile(CUSTOM_RINGTONE, os.path.join(WORK_APK_PATH, "res", "raw", "call_ringing.mp3"))
shutil.copyfile(CUSTOM_RINGTONE,
os.path.join(WORK_APK_PATH, "res",
"raw", "call_ringing.mp3"))
# Apply custom fonts
elif patch_name == "customfont":
print(f"Applying custom font")
@ -188,18 +203,19 @@ for patch_name in PATCHES:
fonts = FONTS["default"]
for font in fonts:
shutil.copyfile(fonts[font], os.path.join(WORK_APK_PATH, "res", "font", font))
shutil.copyfile(fonts[font],
os.path.join(WORK_APK_PATH, "res",
"font", font))
# Apply any other patches
else:
patch(patch_file, WORK_APK_PATH, patch_name)
xmlpatch(xml_patch_file, WORK_APK_PATH, patch_name)
post_script = os.path.join(REPO_FOLDER, "resources/patches", patch_name, f"{VERSION}-post.sh")
post_script = os.path.join(REPO_FOLDER, "patches",
patch_name, f"{VERSION}-post.sh")
if os.path.exists(post_script):
subprocess.run(f"bash {post_script}", shell=True, cwd=WORK_APK_PATH)
post_script = os.path.join(REPO_FOLDER, "resources/xmlpatches", patch_name, f"{VERSION}-post.sh")
if os.path.exists(post_script):
subprocess.run(f"bash {post_script}", shell=True, cwd=WORK_APK_PATH)
subprocess.run(f"bash {post_script}",
shell=True,
cwd=WORK_APK_PATH)
# Pack the APK
subprocess.run(f"{APKTOOL_BIN} b discord",

View File

@ -1,35 +1,33 @@
import os
APKTOOL_BIN = "java -jar /opt/ctc/tools/apktool.jar"
DEX2JAR_BIN = "java -jar /opt/ctc/tools/dex2jar.jar"
XML_PATCH_BIN = "java -cp /opt/ctc/tools/xml-patch.jar"
APKTOOL_BIN = "java -jar /home/ave/apktool-cli-all.jar" # use latest
# APKs must be placed under $DISTOK_FOLDER/android/$PACKAGE_ID-$VERSION_NUMBER.apk
# Example: /home/ave/distok/android/com.discord-909.apk
DISTOK_FOLDER = "/opt/ctc/gitrepo/resources/distok"
DISTOK_FOLDER = "/home/ave/distok"
# Set if F-Droid repo should be automatically updated or not
# If set to False, you can leave FDROID_FOLDER empty
DO_FDROID = True
FDROID_FOLDER = "/opt/ctc/gitrepo/resources/fdroid"
FDROID_FOLDER = "/var/www/fdroid/seabear"
# This is where APKs will be placed
RESULT_FOLDER = FDROID_FOLDER + "/repo"
# Repo for CutTheCord (https://gitdab.com/distok/cutthecord)
DO_GITPULL = False
REPO_FOLDER = "/opt/ctc/gitrepo"
DO_GITPULL = True
REPO_FOLDER = "/home/ave/distokrepos/cutthecord"
# If false, jarsigner will be used for signing the apk.
DO_APKSIGNER = True
# Keystore file, alias and pass. Required.
KEYSTORE_FILE = "/opt/ctc/keystores/keystore.jks"
KEYSTORE_ALIAS = "test"
KEYSTORE_PASS = "password"
KEYSTORE_FILE = "/home/ave/oof.keystore"
KEYSTORE_ALIAS = "distok"
KEYSTORE_PASS = "redacted"
# Set this to the python version you want to use. Needs to be 3.6+.
PYTHON_BIN = "python3"
PYTHON_BIN = "python3.6"
# Folder where the apk will be extracted to, patched in, and packed back on
# You're not recommended to touch WORK_APK_PATH.
@ -44,15 +42,18 @@ PACKAGE_ID = "com.discord"
FORCE = False
# Custom ringtones, default = applied to all the ones not explicitly stated
RINGTONES = {"default": "/opt/ctc/gitrepo/resources/ringtones/removeskype.mp3"}
RINGTONES = {"ave": "/home/ave/sans.mp3",
"default": "/home/ave/removeskype.mp3"}
# Custom icons, default = applied to all the ones not explicitly stated
ICONS = {"ave": "/opt/ctc/gitrepo/resources/icons/ctclogoave.png",
"default": "/opt/ctc/gitrepo/resources/icons/ctclogo.png"}
ICONS = {"ave": "/home/ave/ctclogoave.png",
"default": "/home/ave/ctclogo.png"}
# Custom dynamic icons, default = applied to all the ones not explicitly stated
DYN_ICONS = {"ave": {"fg": "/opt/ctc/gitrepo/resources/icons/fg.png"},
"default": {"fg": "/opt/ctc/gitrepo/resources/icons/dcfg.png"}}
DYN_ICONS = {"ave": {"bg": "/home/ave/distokrepos/cutthecord/icons/bg.png",
"fg": "/home/ave/distokrepos/cutthecord/icons/fg.png"},
"default": {"bg": "/home/ave/dcbg.png",
"fg": "/home/ave/dcfg.png"}}
# Custom app names, default = applied to all the ones not explicitly stated
# Needs to be one word, __ gets replaced with space
@ -62,11 +63,14 @@ APP_NAMES = {"ave": "CutTheCord__Ave",
"default": "CutTheCord"}
# Custom fonts, default = applied to all the ones not explicitly stated
FONTS = {"ave": {"sourcecodepro_semibold.ttf": "/opt/ctc/gitrepo/resources/fonts/comic.ttf",
"ginto_bold.ttf": "/opt/ctc/gitrepo/resources/fonts/whitney_bold.ttf",
"ginto_medium.ttf": "/opt/ctc/gitrepo/resources/fonts/whitney_semibold.ttf",
"ginto_regular.ttf": "/opt/ctc/gitrepo/resources/fonts/whitney_medium.ttf"},
"default": {}}
# Amount of last builds cleanartifacts.py should keep
CLEAN_ARTIFACT_KEEP_COUNT = 2
FONTS = {"ellie": {"whitney_bold.ttf": "/home/ave/fonts/GoogleSans-Bold.ttf",
"whitney_semibold.ttf": "/home/ave/fonts/GoogleSans-Medium.ttf",
"whitney_medium.ttf": "/home/ave/fonts/GoogleSans-Regular.ttf"},
"dyslexic": {"whitney_bold.ttf": "/home/ave/fonts/OpenDyslexic3-Bold.ttf",
"whitney_semibold.ttf": "/home/ave/fonts/OpenDyslexic3-Bold.ttf",
"whitney_medium.ttf": "/home/ave/fonts/OpenDyslexic3-Regular.ttf"},
"murm": {"whitney_bold.ttf": "/home/ave/fonts/comicbd.ttf",
"whitney_semibold.ttf": "/home/ave/fonts/comicbd.ttf",
"whitney_medium.ttf": "/home/ave/fonts/comic.ttf"},
"ave": {"sourcecodepro_semibold.ttf": "/home/ave/fonts/comic.ttf"},
"default": {}}

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 578 KiB

After

Width:  |  Height:  |  Size: 578 KiB

View File

Before

Width:  |  Height:  |  Size: 638 KiB

After

Width:  |  Height:  |  Size: 638 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 10 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 9.9 KiB

After

Width:  |  Height:  |  Size: 9.9 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 44 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 8.5 KiB

After

Width:  |  Height:  |  Size: 8.5 KiB

View File

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

Before

Width:  |  Height:  |  Size: 21 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 43 KiB

View File

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

View File

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 63 KiB

View File

Before

Width:  |  Height:  |  Size: 48 KiB

After

Width:  |  Height:  |  Size: 48 KiB

View File

Before

Width:  |  Height:  |  Size: 578 KiB

After

Width:  |  Height:  |  Size: 578 KiB

View File

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 56 KiB

View File

Before

Width:  |  Height:  |  Size: 591 KiB

After

Width:  |  Height:  |  Size: 591 KiB

View File

Before

Width:  |  Height:  |  Size: 51 KiB

After

Width:  |  Height:  |  Size: 51 KiB

View File

@ -9,9 +9,3 @@ Here's why these patches are no longer maintained in this form:
- compact: It's just a pain to maintain.
- smalltime: It's just a pain to maintain.
- customdefaultemoji: There doesn't seem to be default emojis anymore?
- noprofilestrip: UI changes removed the profile strip.
- nonearby: Didn't add much anyways.
- squareavatars: Moved to xml-patchs
- betterrotation: Moved to xml-patchs
- noblocked: Moved to xml-patchs
- slashcommands: Moved to dynamic patch due to discord api supporting this now

Some files were not shown because too many files have changed in this diff Show More