Browse Source

Implement slashcommands for discord api

pull/127/head
clienthax 1 month ago
parent
commit
1d0a8b7088
  1. 6
      Dockerfile
  2. 10
      resources/patches/slashcommands/87202-pre.sh
  3. 13
      resources/patches/slashcommands/87202.patch
  4. 6
      resources/patches/slashcommands/code/.gitignore
  5. 28
      resources/patches/slashcommands/code/build.gradle
  6. BIN
      resources/patches/slashcommands/code/gradle/wrapper/gradle-wrapper.jar
  7. 5
      resources/patches/slashcommands/code/gradle/wrapper/gradle-wrapper.properties
  8. 185
      resources/patches/slashcommands/code/gradlew
  9. 89
      resources/patches/slashcommands/code/gradlew.bat
  10. 2
      resources/patches/slashcommands/code/settings.gradle
  11. 309
      resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/CTCCommands.java
  12. 7
      resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/EnableDisableHandler.java
  13. 7
      resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/RawMsgHandler.java
  14. 304
      resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/Replacements.java
  15. 162
      resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/commands/CmdCtc.java
  16. 44
      resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/commands/CmdEmojify.java
  17. 26
      resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/commands/CmdOwo.java
  18. 25
      resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/commands/CmdSpoilerImg.java
  19. 11
      resources/scripts/ctcci/ctcci.py

6
Dockerfile

@ -3,6 +3,9 @@ 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
@ -20,6 +23,9 @@ RUN wget -O ${CTC_FOLDER}/tools/apktool.jar https://f001.backblazeb2.com/file/av
# 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

10
resources/patches/slashcommands/87202-pre.sh

@ -0,0 +1,10 @@
#!/bin/bash
cd /opt/ctc/gitrepo/resources/patches/slashcommands/code
chmod +x gradlew
rm -rf build
./gradlew build
cd build/libs
/lib/android-sdk/build-tools/debian/dx --dex --output ctccommands.apk ctccommands-1.0-SNAPSHOT.jar
java -jar /opt/ctc/tools/apktool.jar d ctccommands.apk
cp -r ctccommands/smali/* ${DISTOK_EXTRACTED_DISCORD_PATH}/smali/

13
resources/patches/slashcommands/87202.patch

@ -0,0 +1,13 @@
diff -crB com.discord-base/smali/com/discord/stores/BuiltInCommands.smali com.discord/smali/com/discord/stores/BuiltInCommands.smali
*** com.discord-base/smali/com/discord/stores/BuiltInCommands.smali 2021-08-15 15:01:18.951758400 +0100
--- com.discord/smali/com/discord/stores/BuiltInCommands.smali 2021-08-15 15:02:36.852775500 +0100
***************
*** 305,310 ****
--- 305,312 ----
iput-object v12, p0, Lcom/discord/stores/BuiltInCommands;->builtInApplication:Lcom/discord/models/commands/Application;
+ invoke-static {p0}, Lcom/cutthecord/commands/CTCCommands;->CreateCTCCommands(Lcom/discord/stores/BuiltInCommands;)V
+
return-void
.end method

6
resources/patches/slashcommands/code/.gitignore

@ -0,0 +1,6 @@
.gradle
.idea
build
libs
out

28
resources/patches/slashcommands/code/build.gradle

@ -0,0 +1,28 @@
plugins {
id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
compileJava.options.encoding = 'UTF-8'
tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
apply plugin: 'java'
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
implementation files('/tmp/cutthecord/discord-base-jar/discord-base.jar', 'libs/discord87202.jar')
}
test {
useJUnitPlatform()
}

BIN
resources/patches/slashcommands/code/gradle/wrapper/gradle-wrapper.jar

5
resources/patches/slashcommands/code/gradle/wrapper/gradle-wrapper.properties

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

185
resources/patches/slashcommands/code/gradlew

@ -0,0 +1,185 @@
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"

89
resources/patches/slashcommands/code/gradlew.bat

@ -0,0 +1,89 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

2
resources/patches/slashcommands/code/settings.gradle

@ -0,0 +1,2 @@
rootProject.name = 'ctccommands'

309
resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/CTCCommands.java

@ -0,0 +1,309 @@
package com.cutthecord.commands;
import com.cutthecord.commands.commands.CmdCtc;
import com.cutthecord.commands.commands.CmdEmojify;
import com.cutthecord.commands.commands.CmdOwo;
import com.cutthecord.commands.commands.CmdSpoilerImg;
import com.discord.api.commands.ApplicationCommandType;
import com.discord.api.commands.CommandChoice;
import com.discord.models.commands.ApplicationCommand;
import com.discord.models.commands.ApplicationCommandOption;
import com.discord.stores.BuiltInCommands;
import d0.z.d.m;
import d0.z.d.o;
import kotlin.jvm.functions.Function1;
import kotlin.jvm.internal.DefaultConstructorMarker;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@SuppressWarnings("SameParameterValue")
public class CTCCommands {
static long ID = -100;
// Helper class for replacements
public static class StrPair {
final String a;
final String b;
public StrPair(String a, String b) {
this.a = a;
this.b = b;
}
}
// Need to inject a call at end of init for p0 to this class in BuiltinCommands.smali
// Create commands
@SuppressWarnings({"unused"})
public static void CreateCTCCommands(BuiltInCommands builtIn) {
// Used in command creation in BuiltinCommands, one more than the last reference
// Add existing commands
ArrayList<ApplicationCommand> commands = new ArrayList<>(builtIn.getBuiltInCommands());
// Add our commands
commands.add(createWrappedSlashCommand("st", "Puts a strikethrough the message", "Message", "~~", "~~")); // Strikethrough
commands.add(createWrappedSlashCommand("bold", "Makes text bold", "Message", "**", "**")); // Bold
commands.add(createWrappedSlashCommand("slap", "Slaps people with a large trout", "Message", "*Slaps ", " around a bit with a large trout.*")); // Slap
commands.add(createReplaceTextSlashCommand("clap", "Please \uD83D\uDC4F clap", "Message", Collections.singletonList(new StrPair(" ", ":clap:")))); // Clap
commands.add(createReplaceTextSlashCommand("flip", "Flips text (like “ʇɥıs”)", "Message", Replacements.FLIP)); // Flip
commands.add(createReplaceTextSlashCommand("fw", "Makes text fullwidth (like “Sent from my Android Device”)", "Message", Replacements.FULL_WIDTH)); // fw
commands.add(createReplaceTextSlashCommand("morse", "Converts text into morse code", "Message", Replacements.MORSE, Case.UPPER)); // morse
commands.add(createReplaceTextSlashCommand("gordon", "\uD835\uDDDB\uD835\uDDF2\uD835\uDDF9\uD835\uDDF9\uD835\uDDFC,\uD835\uDDDA\uD835\uDDFC\uD835\uDDFF\uD835\uDDF1\uD835\uDDFC\uD835\uDDFB!", "Message", Replacements.GORDON)); // gordon
commands.add(createReplaceTextSlashCommand("small", "Makes text smaller (like “ᴛʜɪs”)", "Message", Replacements.SMALL, Case.LOWER)); // small
commands.add(createReplaceTextSlashCommand("smaller", "Makes text even smaller (like “ᵗʰvˢ”)", "Message", Replacements.SMALLER, Case.LOWER)); // smaller
//noinspection unchecked
commands.add(createReplaceTextSlashCommand("upper", "Makes text uppercase", "Message", Collections.EMPTY_LIST, Case.UPPER)); // upper
//noinspection unchecked
commands.add(createReplaceTextSlashCommand("lower", "Makes text lowercase", "Message", Collections.EMPTY_LIST, Case.LOWER)); // lower
commands.add(createAppendToEndCommand("lenny", "( ͡° ͜ʖ ͡°)", "Message", " ( \u0361\u00B0 \u035C\u0296 \u0361\u00B0)")); // lenny
commands.add(createHandleRawMessageCommand("owo", "Myakes tyext reawwy owo-ly, nya :3", "Message", new CmdOwo())); // owo
commands.add(createHandleRawMessageCommand("emojify", "Emojify text", "Message", new CmdEmojify())); // emojify
commands.add(createHandleRawMessageCommand("spoilerimg", "Prepends SPOILER_ to names of all images attached to the message that starts with this, causing them to get marked as spoiler", "Message", new CmdSpoilerImg()));
commands.add(createEnableDisableCommand("channelleak", "Shows all hidden channels", new CmdCtc.CmdCtcChannelLeak()));
commands.add(createEnableDisableCommand("showtyping", "Change typing event so that its visible/not when you type", new CmdCtc.CmdCtcShowTyping()));
commands.add(createEnableDisableCommand("nodelete", "Disables handling of message delete events", new CmdCtc.CmdCtcNoDelete()));
commands.add(createHandleRawMessageCommand("gettoken", "Get current token, DO NOT USE IN PUBLIC", null, new CmdCtc.CmdCtcGetToken()));
commands.add(createHandleRawMessageCommand("settoken", "Set current token, DO NOT USE IN PUBLIC", "Token", new CmdCtc.CmdCtcSetToken()));
commands.add(createHandleRawMessageCommand("switchaccount", "Switch to specified account, DO NOT USE IN PUBLIC", "Name", new CmdCtc.CmdCtcSwitchAccount()));
// TODO addaccount
// Builtin list is non modifiable, lets hijack it instead :)
try {
Field commandListField = BuiltInCommands.class.getDeclaredField("builtInCommands");
commandListField.setAccessible(true);
commandListField.set(builtIn, commands);
} catch (Exception e) {
System.out.println("Failed to replace buildInCommands");
e.printStackTrace();
}
}
// Wrapper for naming
public static class CTCCommand extends ApplicationCommand {
public CTCCommand(String id, long applicationID, String name, String description, Integer descriptionRes, List<ApplicationCommandOption> options, boolean builtIn, Long guildId, String version, Boolean defaultPermissions, Map map, Function1 handler, int flags, DefaultConstructorMarker defaultConstructorMarker) {
super(id, applicationID, name, description, descriptionRes, options, builtIn, guildId, version, defaultPermissions, map, handler, flags, defaultConstructorMarker);
}
}
// Wrapper for naming
public static ApplicationCommandOption makeOption(ApplicationCommandType type, String name, String description, Integer descriptionRes, boolean required, boolean defaultOpt, List<CommandChoice> choices, List<ApplicationCommandOption> options) {
return new ApplicationCommandOption(type, name, description, descriptionRes, required, defaultOpt, choices, options);
}
// Wrapper for naming
public static ApplicationCommandOption makeOption(ApplicationCommandType type, String name, String description, Integer descriptionRes, boolean required, boolean defaultOpt, List<CommandChoice> choices, List<ApplicationCommandOption> options, int flags, DefaultConstructorMarker marker) {
return new ApplicationCommandOption(type, name, description, descriptionRes, required, defaultOpt, choices, options, flags, marker);
/*
Flags
4 - description = null
8 - descriptionRes = null
64 - choices = null
128 - options = null
*/
}
// Wrapper for naming
public static ApplicationCommand makeCtcCommand(String name, String cmdDesc, List<ApplicationCommandOption> options, Function1<? super Map<String, ? extends Object>, String> handler) {
m.checkNotNullParameter(name, "name");
m.checkNotNullParameter(options, "options");
return new CTCCommand(String.valueOf(ID--), -1L, name, cmdDesc, null, options, true, null, null, null, null, handler, 1936, null);
/*
Flags
8 - description = null
16 - descriptionRes = null
64 - builtIn = false
128 - guildID = null
256 - version = null
512 - defaultPermissions = false
1024 - permissions = null
2048 - handler = null
1928 = 1024, 512, 256, 128, 8
// Lets try 1936 for out purposes
*/
}
static final class WrapTextCommand extends o<String> implements Function1<Map<String, ?>, String> {
public final String prefix;
public final String suffix;
public WrapTextCommand(String prefix, String suffix) {
super(1);
this.prefix = prefix;
this.suffix = suffix;
}
public final String invoke(Map<String, ?> options) {
m.checkNotNullParameter(options, "commandOptions");
StringBuilder newMessage = new StringBuilder();
newMessage.append(this.prefix);
Object originalMessage = options.get("message");
if (originalMessage == null) {
originalMessage = "";
}
newMessage.append(originalMessage);
newMessage.append(this.suffix);
return newMessage.toString();
}
}
@SuppressWarnings("SameParameterValue")
private static ApplicationCommand createWrappedSlashCommand(String name, String cmdDesc, String optionDesc, String prefix, String suffix) {
return makeCtcCommand(name, cmdDesc, Collections.singletonList(
makeOption(ApplicationCommandType.STRING, "message", optionDesc, null, true, false, null, null, 192, null)
), new WrapTextCommand(prefix, suffix));
}
final static class AppendToEndCommand extends o<String> implements Function1<Map<String, ?>, String> {
public String suffix;
public AppendToEndCommand(String suffix) {
super(1);
this.suffix = suffix;
}
public final String invoke(Map<String, ?> options) {
m.checkNotNullParameter( options, "commandOptions");
StringBuilder newMessage = new StringBuilder();
Object originalMessage = options.get("message");
if (originalMessage == null) {
originalMessage = "";
}
newMessage.append(originalMessage);
newMessage.append(' ');
newMessage.append(this.suffix);
return newMessage.toString();
}
}
@SuppressWarnings("SameParameterValue")
private static ApplicationCommand createAppendToEndCommand(String name, String cmdDesc, String optionDesc, String suffix) {
return makeCtcCommand(name, cmdDesc, Collections.singletonList(
makeOption(ApplicationCommandType.STRING, "message", optionDesc, null, false, false, null, null, 192, null)
), new AppendToEndCommand(suffix));
}
final static class ReplaceMatchesCommand extends o<String> implements Function1<Map<String, ?>, String> {
public final List<StrPair> replacements;
public final Case c;
public ReplaceMatchesCommand(List<StrPair> replacements, Case c) {
super(1);
this.replacements = replacements;
this.c = c;
}
public final String invoke(Map<String, ?> options) {
m.checkNotNullParameter(options, "commandOptions");
StringBuilder newMessage = new StringBuilder();
Object originalMessage = options.get("message");
if (originalMessage == null) {
originalMessage = "";
}
if (c == Case.UPPER) {
originalMessage = ((String)originalMessage).toUpperCase();
} else if (c == Case.LOWER) {
originalMessage = ((String)originalMessage).toLowerCase();
}
for (StrPair replacement : replacements) {
originalMessage = ((String)originalMessage).replace(replacement.a, replacement.b);
}
newMessage.append(originalMessage);
return newMessage.toString();
}
}
enum Case {
UPPER,
LOWER,
ORIGINAL
}
private static ApplicationCommand createReplaceTextSlashCommand(String name, String cmdDesc, String optionDesc, List<StrPair> replaceList, Case c) {
return makeCtcCommand(name, cmdDesc, Collections.singletonList(
makeOption(ApplicationCommandType.STRING, "message", optionDesc, null, true, true, null, null, 192, null)
), new ReplaceMatchesCommand(replaceList, c));
}
private static ApplicationCommand createReplaceTextSlashCommand(String name, String cmdDesc, String optionDesc, List<StrPair> replaceList) {
return createReplaceTextSlashCommand(name, cmdDesc, optionDesc, replaceList, Case.ORIGINAL);
}
final static class RawMessageCommand extends o<String> implements Function1<Map<String, ?>, String> {
public final RawMsgHandler handler;
public RawMessageCommand(RawMsgHandler handler) {
super(1);
this.handler = handler;
}
public final String invoke(Map<String, ?> options) {
m.checkNotNullParameter(options, "commandOptions");
StringBuilder newMessage = new StringBuilder();
Object originalMessage = options.get("message");
if (originalMessage == null) {
originalMessage = "";
}
newMessage.append(handler.processRawMessage((String) originalMessage));
return newMessage.toString();
}
}
final static class EnableDisableCommand extends o<String> implements Function1<Map<String, ?>, String> {
public final EnableDisableHandler handler;
public EnableDisableCommand(EnableDisableHandler handler) {
super(1);
this.handler = handler;
}
public final String invoke(Map<String, ?> options) {
m.checkNotNullParameter(options, "commandOptions");
StringBuilder newMessage = new StringBuilder();
boolean enabled = (boolean) options.get("enabled");
newMessage.append(handler.processEnableDisable(enabled));
return newMessage.toString();
}
}
private static ApplicationCommand createHandleRawMessageCommand(String name, String cmdDesc, String optionDesc, RawMsgHandler handler) {
boolean required = true;
if (optionDesc == null) {
required = false;
}
return makeCtcCommand(name, cmdDesc, Collections.singletonList(
makeOption(ApplicationCommandType.STRING, "message", optionDesc, null, required, required, null, null, 192, null)
), new RawMessageCommand(handler));
}
private static ApplicationCommand createEnableDisableCommand(String name, String cmdDesc, EnableDisableHandler handler) {
ArrayList<CommandChoice> truefalse = new ArrayList<>();
truefalse.add(new CommandChoice("on", "true"));
truefalse.add(new CommandChoice("off", "false"));
return makeCtcCommand(name, cmdDesc, Collections.singletonList(
makeOption(ApplicationCommandType.BOOLEAN, "enabled", "Enable/Disable", null, true, true, truefalse, null, 192, null)
), new EnableDisableCommand(handler));
}
}

7
resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/EnableDisableHandler.java

@ -0,0 +1,7 @@
package com.cutthecord.commands;
public interface EnableDisableHandler {
String processEnableDisable(boolean enabled);
}

7
resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/RawMsgHandler.java

@ -0,0 +1,7 @@
package com.cutthecord.commands;
public interface RawMsgHandler {
String processRawMessage(String orig);
}

304
resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/Replacements.java

@ -0,0 +1,304 @@
package com.cutthecord.commands;
import java.util.ArrayList;
import java.util.List;
public class Replacements {
public static final List<CTCCommands.StrPair> FLIP = new ArrayList<CTCCommands.StrPair>() {{
add(new CTCCommands.StrPair("a", "ɐ"));
add(new CTCCommands.StrPair("b", "q"));
add(new CTCCommands.StrPair("c", "ɔ"));
add(new CTCCommands.StrPair("d", "p"));
add(new CTCCommands.StrPair("e", "ǝ"));
add(new CTCCommands.StrPair("f", "ɟ"));
add(new CTCCommands.StrPair("g", "ƃ"));
add(new CTCCommands.StrPair("h", "ɥ"));
add(new CTCCommands.StrPair("i", "ı"));
add(new CTCCommands.StrPair("j", "ɾ"));
add(new CTCCommands.StrPair("k", "ʞ"));
add(new CTCCommands.StrPair("l", "ן"));
add(new CTCCommands.StrPair("m", "ɯ"));
add(new CTCCommands.StrPair("n", "u"));
//add(new CTCCommands.StrPair("o", "o"));
add(new CTCCommands.StrPair("p", "d"));
add(new CTCCommands.StrPair("q", "b"));
add(new CTCCommands.StrPair("r", "ɹ"));
//add(new CTCCommands.StrPair("s", "s"));
add(new CTCCommands.StrPair("t", "ʇ"));
add(new CTCCommands.StrPair("u", "n"));
add(new CTCCommands.StrPair("v", "ʌ"));
add(new CTCCommands.StrPair("w", "ʍ"));
//add(new CTCCommands.StrPair("x", "x"));
add(new CTCCommands.StrPair("y", "ʎ"));
//add(new CTCCommands.StrPair("z", "z"));
}};
public static final List<CTCCommands.StrPair> FULL_WIDTH = new ArrayList<CTCCommands.StrPair>() {{
add(new CTCCommands.StrPair(" ", " "));
add(new CTCCommands.StrPair("!", "!"));
add(new CTCCommands.StrPair("#", "#"));
add(new CTCCommands.StrPair("$", "$"));
add(new CTCCommands.StrPair("%", "%"));
add(new CTCCommands.StrPair("&", "&"));
add(new CTCCommands.StrPair("'", "'"));
add(new CTCCommands.StrPair("(", "("));
add(new CTCCommands.StrPair(")", ")"));
add(new CTCCommands.StrPair("*", "*"));
add(new CTCCommands.StrPair("+", "+"));
add(new CTCCommands.StrPair(",", ","));
add(new CTCCommands.StrPair("-", "-"));
add(new CTCCommands.StrPair(".", "."));
add(new CTCCommands.StrPair("/", "/"));
add(new CTCCommands.StrPair("0", "0"));
add(new CTCCommands.StrPair("1", "1"));
add(new CTCCommands.StrPair("2", "2"));
add(new CTCCommands.StrPair("3", "3"));
add(new CTCCommands.StrPair("4", "4"));
add(new CTCCommands.StrPair("5", "5"));
add(new CTCCommands.StrPair("6", "6"));
add(new CTCCommands.StrPair("7", "7"));
add(new CTCCommands.StrPair("8", "8"));
add(new CTCCommands.StrPair("9", "9"));
add(new CTCCommands.StrPair(":", ":"));
add(new CTCCommands.StrPair(";", ";"));
add(new CTCCommands.StrPair("<", "<"));
add(new CTCCommands.StrPair("=", "="));
add(new CTCCommands.StrPair(">", ">"));
add(new CTCCommands.StrPair("?", "?"));
add(new CTCCommands.StrPair("@", "@"));
add(new CTCCommands.StrPair("A", "A"));
add(new CTCCommands.StrPair("B", "B"));
add(new CTCCommands.StrPair("C", "C"));
add(new CTCCommands.StrPair("D", "D"));
add(new CTCCommands.StrPair("E", "E"));
add(new CTCCommands.StrPair("F", "F"));
add(new CTCCommands.StrPair("G", "G"));
add(new CTCCommands.StrPair("H", "H"));
add(new CTCCommands.StrPair("I", "I"));
add(new CTCCommands.StrPair("J", "J"));
add(new CTCCommands.StrPair("K", "K"));
add(new CTCCommands.StrPair("L", "L"));
add(new CTCCommands.StrPair("M", "M"));
add(new CTCCommands.StrPair("N", "N"));
add(new CTCCommands.StrPair("O", "O"));
add(new CTCCommands.StrPair("P", "P"));
add(new CTCCommands.StrPair("Q", "Q"));
add(new CTCCommands.StrPair("R", "R"));
add(new CTCCommands.StrPair("S", "S"));
add(new CTCCommands.StrPair("T", "T"));
add(new CTCCommands.StrPair("U", "U"));
add(new CTCCommands.StrPair("V", "V"));
add(new CTCCommands.StrPair("W", "W"));
add(new CTCCommands.StrPair("X", "X"));
add(new CTCCommands.StrPair("Y", "Y"));
add(new CTCCommands.StrPair("Z", "Z"));
add(new CTCCommands.StrPair("[", "["));
add(new CTCCommands.StrPair("]", "]"));
add(new CTCCommands.StrPair("^", "^"));
add(new CTCCommands.StrPair("_", "_"));
add(new CTCCommands.StrPair("`", "`"));
add(new CTCCommands.StrPair("a", "a"));
add(new CTCCommands.StrPair("b", "b"));
add(new CTCCommands.StrPair("c", "c"));
add(new CTCCommands.StrPair("d", "d"));
add(new CTCCommands.StrPair("e", "e"));
add(new CTCCommands.StrPair("f", "f"));
add(new CTCCommands.StrPair("g", "g"));
add(new CTCCommands.StrPair("h", "h"));
add(new CTCCommands.StrPair("i", "i"));
add(new CTCCommands.StrPair("j", "j"));
add(new CTCCommands.StrPair("k", "k"));
add(new CTCCommands.StrPair("l", "l"));
add(new CTCCommands.StrPair("m", "m"));
add(new CTCCommands.StrPair("n", "n"));
add(new CTCCommands.StrPair("o", "o"));
add(new CTCCommands.StrPair("p", "p"));
add(new CTCCommands.StrPair("q", "q"));
add(new CTCCommands.StrPair("r", "r"));
add(new CTCCommands.StrPair("s", "s"));
add(new CTCCommands.StrPair("t", "t"));
add(new CTCCommands.StrPair("u", "u"));
add(new CTCCommands.StrPair("v", "v"));
add(new CTCCommands.StrPair("w", "w"));
add(new CTCCommands.StrPair("x", "x"));
add(new CTCCommands.StrPair("y", "y"));
add(new CTCCommands.StrPair("z", "z"));
add(new CTCCommands.StrPair("{", "{"));
add(new CTCCommands.StrPair("|", "|"));
add(new CTCCommands.StrPair("}", "}"));
add(new CTCCommands.StrPair("~", "~"));
}};
public static final List<CTCCommands.StrPair> MORSE = new ArrayList<CTCCommands.StrPair>() {{
add(new CTCCommands.StrPair(" ", "/ "));
add(new CTCCommands.StrPair(".", ".-.-.- "));
add(new CTCCommands.StrPair(",", "--..-- "));
add(new CTCCommands.StrPair(":", "---... "));
add(new CTCCommands.StrPair("?", "..--.. "));
add(new CTCCommands.StrPair("'", ".----. "));
add(new CTCCommands.StrPair("-", "-....- "));
add(new CTCCommands.StrPair("/", "-..-. "));
add(new CTCCommands.StrPair("@", ".--.-. "));
add(new CTCCommands.StrPair("=", "-...- "));
add(new CTCCommands.StrPair("A", ".- "));
add(new CTCCommands.StrPair("B", "-... "));
add(new CTCCommands.StrPair("C", "-.-. "));
add(new CTCCommands.StrPair("D", "-.. "));
add(new CTCCommands.StrPair("E", ". "));
add(new CTCCommands.StrPair("F", "..-. "));
add(new CTCCommands.StrPair("G", "--. "));
add(new CTCCommands.StrPair("H", ".... "));
add(new CTCCommands.StrPair("I", ".. "));
add(new CTCCommands.StrPair("J", ".--- "));
add(new CTCCommands.StrPair("K", "-.- "));
add(new CTCCommands.StrPair("L", ".-.. "));
add(new CTCCommands.StrPair("M", "-- "));
add(new CTCCommands.StrPair("N", "-. "));
add(new CTCCommands.StrPair("O", "--- "));
add(new CTCCommands.StrPair("P", ".--. "));
add(new CTCCommands.StrPair("Q", "--.- "));
add(new CTCCommands.StrPair("R", ".-. "));
add(new CTCCommands.StrPair("S", "... "));
add(new CTCCommands.StrPair("T", "- "));
add(new CTCCommands.StrPair("U", "..- "));
add(new CTCCommands.StrPair("V", "...- "));
add(new CTCCommands.StrPair("W", ".-- "));
add(new CTCCommands.StrPair("X", "-..- "));
add(new CTCCommands.StrPair("Y", "-.-- "));
add(new CTCCommands.StrPair("Z", "--.. "));
add(new CTCCommands.StrPair("0", "----- "));
add(new CTCCommands.StrPair("1", ".---- "));
add(new CTCCommands.StrPair("2", "..--- "));
add(new CTCCommands.StrPair("3", "...-- "));
add(new CTCCommands.StrPair("4", "....- "));
add(new CTCCommands.StrPair("5", "..... "));
add(new CTCCommands.StrPair("6", "-.... "));
add(new CTCCommands.StrPair("7", "--... "));
add(new CTCCommands.StrPair("8", "---.. "));
add(new CTCCommands.StrPair("9", "----. "));
}};
public static final List<CTCCommands.StrPair> GORDON = new ArrayList<CTCCommands.StrPair>() {{
add(new CTCCommands.StrPair("a", "𝗮"));
add(new CTCCommands.StrPair("b", "𝗯"));
add(new CTCCommands.StrPair("c", "𝗰"));
add(new CTCCommands.StrPair("d", "𝗱"));
add(new CTCCommands.StrPair("e", "𝗲"));
add(new CTCCommands.StrPair("f", "𝗳"));
add(new CTCCommands.StrPair("g", "𝗴"));
add(new CTCCommands.StrPair("h", "𝗵"));
add(new CTCCommands.StrPair("i", "𝗶"));
add(new CTCCommands.StrPair("j", "𝗷"));
add(new CTCCommands.StrPair("k", "𝗸"));
add(new CTCCommands.StrPair("l", "𝗹"));
add(new CTCCommands.StrPair("m", "𝗺"));
add(new CTCCommands.StrPair("n", "𝗻"));
add(new CTCCommands.StrPair("o", "𝗼"));
add(new CTCCommands.StrPair("p", "𝗽"));
add(new CTCCommands.StrPair("q", "𝗾"));
add(new CTCCommands.StrPair("r", "𝗿"));
add(new CTCCommands.StrPair("s", "𝘀"));
add(new CTCCommands.StrPair("t", "𝘁"));
add(new CTCCommands.StrPair("u", "𝘂"));
add(new CTCCommands.StrPair("v", "𝘃"));
add(new CTCCommands.StrPair("w", "𝘄"));
add(new CTCCommands.StrPair("x", "𝘅"));
add(new CTCCommands.StrPair("y", "𝘆"));
add(new CTCCommands.StrPair("z", "𝘇"));
add(new CTCCommands.StrPair("A", "𝗔"));
add(new CTCCommands.StrPair("B", "𝗕"));
add(new CTCCommands.StrPair("C", "𝗖"));
add(new CTCCommands.StrPair("D", "𝗗"));
add(new CTCCommands.StrPair("E", "𝗘"));
add(new CTCCommands.StrPair("F", "𝗙"));
add(new CTCCommands.StrPair("G", "𝗚"));
add(new CTCCommands.StrPair("H", "𝗛"));
add(new CTCCommands.StrPair("I", "𝗜"));
add(new CTCCommands.StrPair("J", "𝗝"));
add(new CTCCommands.StrPair("K", "𝗞"));
add(new CTCCommands.StrPair("L", "𝗟"));
add(new CTCCommands.StrPair("M", "𝗠"));
add(new CTCCommands.StrPair("N", "𝗡"));
add(new CTCCommands.StrPair("O", "𝗢"));
add(new CTCCommands.StrPair("P", "𝗣"));
add(new CTCCommands.StrPair("Q", "𝗤"));
add(new CTCCommands.StrPair("R", "𝗥"));
add(new CTCCommands.StrPair("S", "𝗦"));
add(new CTCCommands.StrPair("T", "𝗧"));
add(new CTCCommands.StrPair("U", "𝗨"));
add(new CTCCommands.StrPair("V", "𝗩"));
add(new CTCCommands.StrPair("W", "𝗪"));
add(new CTCCommands.StrPair("X", "𝗫"));
add(new CTCCommands.StrPair("Y", "𝗬"));
add(new CTCCommands.StrPair("Z", "𝗭"));
add(new CTCCommands.StrPair("0", "𝟬"));
add(new CTCCommands.StrPair("1", "𝟭"));
add(new CTCCommands.StrPair("2", "𝟮"));
add(new CTCCommands.StrPair("3", "𝟯"));
add(new CTCCommands.StrPair("4", "𝟰"));
add(new CTCCommands.StrPair("5", "𝟱"));
add(new CTCCommands.StrPair("6", "𝟲"));
add(new CTCCommands.StrPair("7", "𝟳"));
add(new CTCCommands.StrPair("8", "𝟴"));
add(new CTCCommands.StrPair("9", "𝟵"));
}};
public static final List<CTCCommands.StrPair> SMALL = new ArrayList<CTCCommands.StrPair>() {{
add(new CTCCommands.StrPair("a", "ᴀ"));
add(new CTCCommands.StrPair("b", "ʙ"));
add(new CTCCommands.StrPair("c", "ᴄ"));
add(new CTCCommands.StrPair("d", "ᴅ"));
add(new CTCCommands.StrPair("e", "ᴇ"));
add(new CTCCommands.StrPair("f", "ꜰ"));
add(new CTCCommands.StrPair("g", "ɢ"));
add(new CTCCommands.StrPair("h", "ʜ"));
add(new CTCCommands.StrPair("i", "ɪ"));
add(new CTCCommands.StrPair("j", "ᴊ"));
add(new CTCCommands.StrPair("k", "ᴋ"));
add(new CTCCommands.StrPair("l", "ʟ"));
add(new CTCCommands.StrPair("m", "ᴍ"));
add(new CTCCommands.StrPair("n", "ɴ"));
add(new CTCCommands.StrPair("o", "ᴏ"));
add(new CTCCommands.StrPair("p", "ᴘ"));
add(new CTCCommands.StrPair("q", "ǫ"));
add(new CTCCommands.StrPair("r", "ʀ"));
//add(new CTCCommands.StrPair("s", "s"));
add(new CTCCommands.StrPair("t", "ᴛ"));
add(new CTCCommands.StrPair("u", "ᴜ"));
add(new CTCCommands.StrPair("v", "ᴠ"));
add(new CTCCommands.StrPair("w", "ᴡ"));
add(new CTCCommands.StrPair("y", "ʏ"));
add(new CTCCommands.StrPair("z", "ᴢ"));
}};
public static final List<CTCCommands.StrPair> SMALLER = new ArrayList<CTCCommands.StrPair>() {{
add(new CTCCommands.StrPair("a", "ᵃ"));
add(new CTCCommands.StrPair("b", "ᵇ"));
add(new CTCCommands.StrPair("c", "ᶜ"));
add(new CTCCommands.StrPair("d", "ᵈ"));
add(new CTCCommands.StrPair("e", "ᵉ"));
add(new CTCCommands.StrPair("f", "ᶠ"));
add(new CTCCommands.StrPair("g", "ᵍ"));
add(new CTCCommands.StrPair("h", "ʰ"));
add(new CTCCommands.StrPair("i", "ᶦ"));
add(new CTCCommands.StrPair("j", "ʲ"));
add(new CTCCommands.StrPair("k", "ᵏ"));
add(new CTCCommands.StrPair("l", "ˡ"));
add(new CTCCommands.StrPair("m", "ᵐ"));
add(new CTCCommands.StrPair("n", "ⁿ"));
add(new CTCCommands.StrPair("o", "ᵒ"));
add(new CTCCommands.StrPair("p", "ᵖ"));
add(new CTCCommands.StrPair("q", "ᑫ"));
add(new CTCCommands.StrPair("r", "ʳ"));
add(new CTCCommands.StrPair("s", "ˢ"));
add(new CTCCommands.StrPair("t", "ᵗ"));
add(new CTCCommands.StrPair("u", "ᵘ"));
add(new CTCCommands.StrPair("v", "ᵛ"));
add(new CTCCommands.StrPair("w", "ʷ"));
add(new CTCCommands.StrPair("x", "ˣ"));
add(new CTCCommands.StrPair("y", "ʸ"));
add(new CTCCommands.StrPair("z", "ᶻ"));
}};
}

162
resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/commands/CmdCtc.java

@ -0,0 +1,162 @@
package com.cutthecord.commands.commands;
import com.cutthecord.commands.EnableDisableHandler;
import com.cutthecord.commands.RawMsgHandler;
import com.discord.stores.StoreStream;
import com.discord.stores.StoreUserSettings;
import java.lang.reflect.Method;
public class CmdCtc {
// TODO make token calls write directly to clipboard
// TODO make supplemental inject a interface so we can just cast instead of using reflection
public static class CmdCtcChannelLeak implements EnableDisableHandler {
@Override
public String processEnableDisable(boolean enabled) {
try {
//noinspection JavaReflectionMemberAccess
final Method m = StoreStream.getUserSettings().getClass().getDeclaredMethod("setLeakChannels", Boolean.class);
m.invoke(StoreStream.getUserSettings(), enabled);
} catch (Exception e) {
System.out.println("Failed to call StoreStream.getUserSettings().setLeakChannels");
e.printStackTrace();
}
return "CTC: Successfully set channelleak state."; // TODO use notification
}
}
public static class CmdCtcShowTyping implements EnableDisableHandler {
@Override
public String processEnableDisable(boolean enabled) {
try {
//noinspection JavaReflectionMemberAccess
final Method m = StoreStream.getUserSettings().getClass().getDeclaredMethod("setShowTyping", Boolean.class);
m.invoke(StoreStream.getUserSettings(), enabled);
} catch (Exception e) {
System.out.println("Failed to call StoreStream.getUserSettings().setShowTyping");
e.printStackTrace();
}
return "CTC: Successfully set showtyping state."; // TODO use notification
}
}
public static class CmdCtcNoDelete implements EnableDisableHandler {
@Override
public String processEnableDisable(boolean enabled) {
try {
//noinspection JavaReflectionMemberAccess
final Method m = StoreStream.getUserSettings().getClass().getDeclaredMethod("setNoDelete", Boolean.class);
m.invoke(StoreStream.getUserSettings(), enabled);
} catch (Exception e) {
System.out.println("Failed to call StoreStream.getUserSettings().setNoDelete");
e.printStackTrace();
}
return "CTC: Successfully set nodelete state."; // TODO use notification
}
}
public static class CmdCtcGetToken implements RawMsgHandler {
@Override
public String processRawMessage(String orig) {
try {
//noinspection JavaReflectionMemberAccess
final Method m = StoreStream.getUserSettings().getClass().getDeclaredMethod("getStoredToken");
return (String) m.invoke(StoreStream.getUserSettings()); // TODO notification
} catch (Exception e) {
System.out.println("Failed to call StoreStream.getUserSettings().getStoredToken()");
e.printStackTrace();
}
return "";
}
}
public static class CmdCtcSetToken implements RawMsgHandler {
@Override
public String processRawMessage(String msg) {
try {
//noinspection JavaReflectionMemberAccess
final Method m = StoreStream.getUserSettings().getClass().getDeclaredMethod("setStoredToken", String.class);
m.invoke(StoreStream.getUserSettings(), msg);
} catch (Exception e) {
System.out.println("Failed to call StoreStream.getUserSettings().setStoredToken()");
e.printStackTrace();
}
return "CTC: Successfully changed token. Please restart application.";
}
}
public static class CmdCtcSwitchAccount implements RawMsgHandler {
@Override
public String processRawMessage(String msg) {
String trim = msg.trim();
StoreUserSettings userSettings = StoreStream.getUserSettings();
try {
//noinspection JavaReflectionMemberAccess
final Method m1 = userSettings.getClass().getDeclaredMethod("getAccountToken", String.class);
String accountToken = (String) m1.invoke(userSettings, trim);
if (accountToken.startsWith("none")) {
return "CTC: No such account found.";
}
//noinspection JavaReflectionMemberAccess
final Method m2 = userSettings.getClass().getDeclaredMethod("setStoredToken", String.class);
m2.invoke(userSettings, accountToken);
return "CTC: Successfully changed accounts. Please restart application.";
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
}
public static class CmdCtcAddAccount implements RawMsgHandler {//TODO
@Override
public String processRawMessage(String msg) {
String substring3 = msg.substring(msg.indexOf(" "));
String accName = msg.replace(substring3, "").trim();
String accToken = substring3.trim();
StoreUserSettings userSettings = StoreStream.getUserSettings();
if (accName.startsWith("current")) {
accName = StoreStream.getUsers().getMe().getUsername();
accToken = StoreStream.getUsers().getMe().getToken();
}
try {
final Method m = userSettings.getClass().getDeclaredMethod("setAccountToken", String.class, String.class);
m.invoke(userSettings, accName, accToken);
} catch (Exception e) {
e.printStackTrace();
}
return "CTC: Added account.";
}
}
}

44
resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/commands/CmdEmojify.java

@ -0,0 +1,44 @@
package com.cutthecord.commands.commands;
import com.cutthecord.commands.RawMsgHandler;
public class CmdEmojify implements RawMsgHandler {
@Override
public String processRawMessage(String msg) {
StringBuilder s = new StringBuilder();
for (char c : msg.toCharArray()) {
s.append(emojifyChar(c));
}
return s.toString();
}
final String[] numbers = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
public String emojifyChar(char c) {
if (Character.isDigit(c)) {
int i = Integer.parseInt(Character.toString(c));
return ":" + numbers[i] + ":";
}
if (Character.isAlphabetic(c)) {
if (c == 'b') {
return ":b:";
}
return ":regional_indicator_" + String.valueOf(c).toLowerCase() + ":";
}
switch (c) {
case '.': return ":record_button";
case '?': return ":grey_question:";
case '!': return ":grey_exclamation:";
}
return Character.toString(c);
}
}

26
resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/commands/CmdOwo.java

@ -0,0 +1,26 @@
package com.cutthecord.commands.commands;
import com.cutthecord.commands.RawMsgHandler;
public class CmdOwo implements RawMsgHandler {
static final String[] expressions = {
">_<", ":3", "ʕʘ‿ʘʔ", ":D", "._.",
";3", "xD", "ㅇㅅㅇ", "(人◕ω◕)",
">_>", "ÙωÙ", "UwU", "OwO", ":P",
"(◠‿◠✿)", "^_^", ";_;", "XDDD",
"x3", "(• o •)", "<_<", "(・`ω´・)",
";;w;;", ">w<", "^w^"
};
public String processRawMessage(String msg) {
return msg.replaceAll("[rl]", "w")
.replaceAll("[RL]", "W")
.replaceAll("n([aeiou])", "ny$1")
.replaceAll("N([aeiou])", "Ny$1")
.replaceAll("N([AEIOU])", "NY$1")
.replace("ove", "uv")
.replaceAll("!+", " "+ expressions[(int) Math.floor(Math.random()*expressions.length)]+ " ");
}
}

25
resources/patches/slashcommands/code/src/main/java/com/cutthecord/commands/commands/CmdSpoilerImg.java

@ -0,0 +1,25 @@
package com.cutthecord.commands.commands;
import com.cutthecord.commands.RawMsgHandler;
import com.discord.stores.StoreStream;
import java.lang.reflect.Method;
public class CmdSpoilerImg implements RawMsgHandler {
@Override
public String processRawMessage(String orig) {
try {
// Added by Supplemental patch
//noinspection JavaReflectionMemberAccess
final Method m = StoreStream.getUserSettings().getClass().getDeclaredMethod("setImageSpoiler", Boolean.class);
m.invoke(StoreStream.getUserSettings(), true);
} catch (Exception e) {
System.out.println("Failed to call StoreStream.getUserSettings().setImageSpoiler(true)");
e.printStackTrace();
}
return orig;
}
}

11
resources/scripts/ctcci/ctcci.py

@ -48,6 +48,10 @@ with open(os.path.join(REPO_FOLDER, "resources/patchport-state.json")) as 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-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,6 +83,13 @@ if not os.path.exists(BASE_APK_PATH):
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)
subprocess.run(f"rm classes*dex2jar.jar *.dex", shell=True, cwd=BASE_JAR_PATH)
# Copy the base cache to work on it
shutil.copytree(BASE_APK_PATH, WORK_APK_PATH)

Loading…
Cancel
Save