diff --git a/app/build.gradle b/app/build.gradle index 6b9249c..64dd718 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -148,8 +148,8 @@ android { // of the source app. (Data is displayed when the source apk library is built.) minSdkVersion 21 targetSdkVersion 29 - versionCode 1367 - versionName '53.8' + versionCode 1368 + versionName '54.0' } diff --git a/app/src/main/java/com/PatchConfig.java b/app/src/main/java/com/PatchConfig.java index 8a34afc..57c6ef3 100644 --- a/app/src/main/java/com/PatchConfig.java +++ b/app/src/main/java/com/PatchConfig.java @@ -14,7 +14,7 @@ public class PatchConfig { public static final boolean EMBEDLINKS_ENABLED = true; public static final boolean SHOWTAG_ENABLED = true; public static final boolean NONEARBY_ENABLED = true; - public static final boolean NOSPOILER_ENABLED = false; + public static final boolean NOSPOILER_ENABLED = true; public static final boolean DISABLE_MOBILE_INDICATOR_ENABLED = true; public static final boolean HQAVATARS_ENABLED = true; @@ -27,5 +27,9 @@ public class PatchConfig { public static final boolean LITECORD_ENABLED = false; // TODO public static final boolean NOTRACK_ENABLED = true; + public static String getEnabledPatchList() { + // TODO + return ""; + } } diff --git a/app/src/main/java/com/discord/app/AppFragment.java b/app/src/main/java/com/discord/app/AppFragment.java index 641a0df..6f1d72f 100644 --- a/app/src/main/java/com/discord/app/AppFragment.java +++ b/app/src/main/java/com/discord/app/AppFragment.java @@ -11,6 +11,7 @@ import kotlin.jvm.functions.Function0; import lanchon.dexpatcher.annotation.DexIgnore; import rx.subjects.Subject; +@SuppressWarnings("deprecation") @DexIgnore public class AppFragment extends Fragment implements AppComponent, AppPermissions.Requests, MediaPicker.Provider { diff --git a/app/src/main/java/com/discord/models/domain/ModelMessage.java b/app/src/main/java/com/discord/models/domain/ModelMessage.java index c94df8c..3444a6f 100644 --- a/app/src/main/java/com/discord/models/domain/ModelMessage.java +++ b/app/src/main/java/com/discord/models/domain/ModelMessage.java @@ -1,12 +1,106 @@ package com.discord.models.domain; +import androidx.annotation.NonNull; + +import com.discord.models.messages.LocalAttachment; +import com.discord.models.sticker.dto.ModelSticker; +import com.discord.utilities.time.Clock; + import java.io.IOException; +import java.util.LinkedHashMap; +import java.util.List; +import lanchon.dexpatcher.annotation.DexAdd; +import lanchon.dexpatcher.annotation.DexEdit; import lanchon.dexpatcher.annotation.DexIgnore; +import lanchon.dexpatcher.annotation.DexWrap; -@DexIgnore +@DexEdit public class ModelMessage implements Model { + @DexIgnore + public static class Call implements Model { + + @DexIgnore + @Override + public void assignField(JsonReader jsonReader) throws IOException { + + } + + } + + + @DexIgnore + public ModelMessage( + long id, + String nonce, + long channelId, + int type, + String content, + @NonNull ModelUser author, + List mentions, + String timestamp, + String editedTimestamp, + List attachments, + List embeds, + boolean tts, + Call call, + boolean mentionEveryone, + LinkedHashMap reactions, + Boolean pinned, + Long webhookId, + ModelApplication application, + Activity activity, + boolean hit, + List mentionRoles, + boolean hasLocalUploads, + Long flags, + MessageReference messageReference, + ModelAllowedMentions allowedMentions, + List localAttachments, + Long lastManualAttemptTimestamp, + Long initialAttemptTimestamp, + Integer num, + List stickers) { + + } + + @DexAdd + private boolean isCTCMessage = false; + + @DexAdd + public void setCTCMessage(boolean isCTCMessage) { + this.isCTCMessage = isCTCMessage; + } + + @DexWrap + public boolean canResend() { + // Prevent resending of messages from commands that are not public. + return canResend() && !isCTCMessage; + } + + + @DexIgnore + public static ModelMessage createLocalMessage( + String content, + long channelId, + @NonNull ModelUser author, + List mentions, + boolean z2, + boolean hasLocalUploads, + ModelApplication application, + Activity activity, + Clock clock, + List localAttachments, + Long lastManualAttemptTimestamp, + Long initialAttemptTimestamp, + Integer num, + List stickers, + MessageReference messageReference, + ModelAllowedMentions allowedMentions) { + return null; + } + @DexIgnore @Override public void assignField(JsonReader jsonReader) throws IOException { diff --git a/app/src/main/java/com/discord/models/domain/ModelMessageAttachment.java b/app/src/main/java/com/discord/models/domain/ModelMessageAttachment.java new file mode 100644 index 0000000..124ffc4 --- /dev/null +++ b/app/src/main/java/com/discord/models/domain/ModelMessageAttachment.java @@ -0,0 +1,10 @@ +package com.discord.models.domain; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public class ModelMessageAttachment implements Model { + @DexIgnore + @Override + public void assignField(JsonReader jsonReader) {} +} diff --git a/app/src/main/java/com/discord/models/domain/ModelMessageEmbed.java b/app/src/main/java/com/discord/models/domain/ModelMessageEmbed.java index 512210a..97b216e 100644 --- a/app/src/main/java/com/discord/models/domain/ModelMessageEmbed.java +++ b/app/src/main/java/com/discord/models/domain/ModelMessageEmbed.java @@ -24,9 +24,15 @@ public class ModelMessageEmbed implements Model { return false; } + // end of nospoiler patch + + + // Interfaces @DexIgnore @Override public void assignField(JsonReader jsonReader) throws IOException { } + // End of interfaces + } diff --git a/app/src/main/java/com/discord/models/domain/ModelMessageReaction.java b/app/src/main/java/com/discord/models/domain/ModelMessageReaction.java new file mode 100644 index 0000000..f67d786 --- /dev/null +++ b/app/src/main/java/com/discord/models/domain/ModelMessageReaction.java @@ -0,0 +1,16 @@ +package com.discord.models.domain; + +import java.io.IOException; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public class ModelMessageReaction implements Model { + + @DexIgnore + @Override + public void assignField(JsonReader jsonReader) throws IOException { + + } + +} diff --git a/app/src/main/java/com/discord/models/domain/ModelUser.java b/app/src/main/java/com/discord/models/domain/ModelUser.java index b598269..b337a2b 100644 --- a/app/src/main/java/com/discord/models/domain/ModelUser.java +++ b/app/src/main/java/com/discord/models/domain/ModelUser.java @@ -6,6 +6,7 @@ import com.discordtest.BuildConfig; import java.io.IOException; import java.util.Map; +import lanchon.dexpatcher.annotation.DexAdd; import lanchon.dexpatcher.annotation.DexEdit; import lanchon.dexpatcher.annotation.DexIgnore; import lanchon.dexpatcher.annotation.DexWrap; @@ -13,6 +14,41 @@ import lanchon.dexpatcher.annotation.DexWrap; @DexEdit public class ModelUser implements Model { + // add ctc bot + + @DexIgnore + public long id; + + @DexIgnore + public String username; + + @DexIgnore + public int discriminator; + + @DexIgnore + public boolean bot; + + @DexIgnore + public String avatar; + + @DexIgnore + public boolean system; + + @DexAdd + public static final ModelUser CTC_BOT = createCtcBot(); + + @DexAdd + private static ModelUser createCtcBot() { + ModelUser user = new ModelUser(); + user.id = -1; + user.username = "CutTheCord"; + user.discriminator = 1; + user.bot = true; + //user.system = true; + user.avatar = "asset://asset/images/default_avatar_clyde.jpg"; + return user; + } + // showtag patch @DexWrap diff --git a/app/src/main/java/com/discord/models/domain/NonceGenerator.java b/app/src/main/java/com/discord/models/domain/NonceGenerator.java new file mode 100644 index 0000000..ba44170 --- /dev/null +++ b/app/src/main/java/com/discord/models/domain/NonceGenerator.java @@ -0,0 +1,13 @@ +package com.discord.models.domain; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public final class NonceGenerator { + + @DexIgnore + public static final long computeNonce() { + return -1; + } + +} diff --git a/app/src/main/java/com/discord/models/messages/LocalAttachment.java b/app/src/main/java/com/discord/models/messages/LocalAttachment.java new file mode 100644 index 0000000..9471d70 --- /dev/null +++ b/app/src/main/java/com/discord/models/messages/LocalAttachment.java @@ -0,0 +1,7 @@ +package com.discord.models.messages; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public final class LocalAttachment { +} diff --git a/app/src/main/java/com/discord/stores/Dispatcher.java b/app/src/main/java/com/discord/stores/Dispatcher.java new file mode 100644 index 0000000..6bfcff9 --- /dev/null +++ b/app/src/main/java/com/discord/stores/Dispatcher.java @@ -0,0 +1,15 @@ +package com.discord.stores; + +import kotlin.Unit; +import kotlin.jvm.functions.Function0; +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public final class Dispatcher { + + @DexIgnore + public final void schedule(Function0 function0) { + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/discord/stores/StoreMessages$sendMessage$1.java b/app/src/main/java/com/discord/stores/StoreMessages$sendMessage$1.java new file mode 100644 index 0000000..420c251 --- /dev/null +++ b/app/src/main/java/com/discord/stores/StoreMessages$sendMessage$1.java @@ -0,0 +1,23 @@ +package com.discord.stores; + +import com.discord.models.domain.ModelMessage; + +import kotlin.Unit; +import kotlin.jvm.functions.Function0; +import lanchon.dexpatcher.annotation.DexIgnore; +import x.m.c.k; + +@DexIgnore +public final class StoreMessages$sendMessage$1 extends k implements Function0 { + + @DexIgnore + public StoreMessages$sendMessage$1(StoreMessages storeMessages, ModelMessage modelMessage) { + } + + @DexIgnore + @Override + public Unit invoke() { + return null; + } + +} diff --git a/app/src/main/java/com/discord/stores/StoreMessages.java b/app/src/main/java/com/discord/stores/StoreMessages.java index 3114098..f95773e 100644 --- a/app/src/main/java/com/discord/stores/StoreMessages.java +++ b/app/src/main/java/com/discord/stores/StoreMessages.java @@ -5,15 +5,20 @@ import com.discord.models.domain.ModelAllowedMentions; import com.discord.models.domain.ModelApplication; import com.discord.models.domain.ModelMessage; import com.discord.models.domain.ModelUser; +import com.discord.models.domain.NonceGenerator; import com.discord.models.domain.activity.ModelActivity; import com.discord.models.sticker.dto.ModelSticker; import com.discord.utilities.messagesend.MessageResult; +import com.discord.utilities.time.Clock; +import com.discord.utilities.time.TimeUtils; import com.lytefast.flexinput.model.Attachment; import java.util.List; +import cutthecord.commands.CommandHandler; import lanchon.dexpatcher.annotation.DexAdd; import lanchon.dexpatcher.annotation.DexEdit; +import lanchon.dexpatcher.annotation.DexIgnore; import lanchon.dexpatcher.annotation.DexWrap; import rx.Observable; @@ -22,34 +27,48 @@ public final class StoreMessages extends Store { // TODO extra patch that allows @ user selection window to appear when entering a slash command + @DexIgnore + public StoreMessages(StoreStream storeStream, Dispatcher dispatcher, Clock clock2) { + + } + + @DexIgnore + private final Dispatcher dispatcher = null; + + @DexIgnore + private final StoreMessagesHolder holder = new StoreMessagesHolder(); + + @DexIgnore + private final Clock clock = null; + // slashmessages patch // Wrap edit function to check for commands @SuppressWarnings("InfiniteRecursion") // Wrapped method @DexWrap - public final void editMessage(long j, long j2, String str) { + public final void editMessage(long messageId, long channelId, String content) { if (!PatchConfig.SLASH_COMMANDS_ENABLED) { // Patch not enabled - editMessage(j, j2, str); + editMessage(messageId, channelId, content); return; } - String interceptEditMessage = interceptEditMessage(str); - editMessage(j, j2, interceptEditMessage); + String interceptEditMessage = CommandHandler.interceptEditMessage(this, channelId, content); + editMessage(messageId, channelId, interceptEditMessage); } // Wrap send function to check for commands @SuppressWarnings("InfiniteRecursion") // Wrapped method @DexWrap - public final Observable sendMessage(long j, - ModelUser modelUser, + public final Observable sendMessage(long channel, + ModelUser author, String message, - List list, - List> list2, - List list3, + List mentionedUsers, + List> attachments, + List stickers, ModelMessage.MessageReference messageReference, ModelAllowedMentions modelAllowedMentions, - ModelApplication modelApplication, + ModelApplication application, ModelActivity modelActivity, ModelMessage.Activity activity, Long l, @@ -57,444 +76,26 @@ public final class StoreMessages extends Store { Integer num) { if (!PatchConfig.SLASH_COMMANDS_ENABLED) { // Patch not enabled - return sendMessage(j, modelUser, message, list, list2, list3, messageReference, modelAllowedMentions, modelApplication, modelActivity, activity, l, l2, num); + return sendMessage(channel, author, message, mentionedUsers, attachments, stickers, messageReference, modelAllowedMentions, application, modelActivity, activity, l, l2, num); } - String interceptEditMessage = interceptSendMessage(message); - return sendMessage(j, modelUser, interceptEditMessage, list, list2, list3, messageReference, modelAllowedMentions, modelApplication, modelActivity, activity, l, l2, num); + String interceptEditMessage = CommandHandler.interceptSendMessage(this, channel, message); + return sendMessage(channel, author, interceptEditMessage, mentionedUsers, attachments, stickers, messageReference, modelAllowedMentions, application, modelActivity, activity, l, l2, num); } - // Add in helper functions + // Helper methods for slashcommands etc + // Sends a bot message to a channel, only visible by the local client + // TODO for whatever reason these can't be deleted.. when type -1/0 + // this is a big workaround, we add an additional check in ModelMessage to see if this is an internal message or not, to prevent resends, and send internal responses as error messages @DexAdd - public static String interceptEditMessage(String str) { - return str.startsWith("/") ? slashCommands(str) : str; + @StoreThread + public void sendCTCBotMessageToChannel(long channelId, String content) { + long computeNonce = NonceGenerator.computeNonce(); + ModelMessage modelMessage = new ModelMessage(computeNonce, String.valueOf(computeNonce), channelId, -2 /* Send failed */, content, ModelUser.CTC_BOT, null, TimeUtils.currentTimeUTCDateString(clock), null, null, null, false, null, false, null, null, null, null, null, false, null, false, null, null, null, null, null, null, null, null); + modelMessage.setCTCMessage(true); + this.dispatcher.schedule(new StoreMessages$sendMessage$1(this, modelMessage)); } - @DexAdd - public static String interceptSendMessage(String str) { - StoreStream.getUserSettings().setImageSpoiler(false); - return str.startsWith("/") ? slashCommands(str) : str; - } - - @DexAdd - public static String slashCommands(String str) { - String msg = str.trim(); - - String command = ""; - String remaining = ""; - - int spacePos = str.indexOf(" "); - if (spacePos == -1) { - // Assume entire input is command - command = str.substring(1); - } else { - // Split command and remaining - command = str.substring(0, spacePos); - remaining = str.substring(spacePos + 1); - } - - - if (msg.startsWith("/upper ")) { - msg = slashUpper(remaining); - } else if (msg.startsWith("/lower ")) { - msg = slashLower(remaining); - } else if (msg.startsWith("/bold ")) { - msg = slashBold(remaining); - } else if (msg.startsWith("/spoiler ")) { - msg = slashSpoiler(remaining); - } else if (msg.startsWith("/me ")) { - msg = slashMe(remaining); - } else if (msg.startsWith("/st ")) { - msg = slashSt(remaining); - } else if (msg.startsWith("/lenny")) { - msg = slashLenny(remaining); - } else if (msg.startsWith("/fw ")) { - msg = slashFw(remaining); - } else if (msg.startsWith("/small ")) { - msg = slashSmall(remaining); - } else if (msg.startsWith("/smaller ")) { - msg = slashSmaller(remaining); - } else if (msg.startsWith("/flip ")) { - msg = slashFlip(remaining); - } else if (msg.startsWith("/clap ")) { - msg = slashClap(remaining); - } else if (msg.startsWith("/owo ")) { - msg = slashOwo(remaining); - } else if (msg.startsWith("/morse ")) { - msg = slashMorse(remaining); - } else if (msg.startsWith("/spoilerimg")) { - msg = slashSpoilerImg(remaining); - } else if (msg.startsWith("/gordon ")) { - msg = slashGordon(remaining); - } else if (msg.startsWith("/slap ")) { - msg = slashSlap(remaining); - } - return msg.trim(); - } - - @DexAdd - public static String slashSlap(String remaining) { - return "*Slaps "+remaining+" around a bit with a large trout.*"; - } - - @DexAdd - public static String slashBold(String remaining) { - return "**" + remaining + "**"; - } - - @DexAdd - public static String slashClap(String remaining) { - return remaining.replace(" ", " :clap: "); - } - - @DexAdd - public static String slashCtc(String remaining) { - String subcommand = remaining.substring(5); - - if (subcommand.startsWith("channelleak ")) { - StoreStream.getUserSettings().setLeakChannels(subcommand.substring(12).startsWith("false")); - return "CTC: Successfully set channelleak state."; - } else if (subcommand.startsWith("showtyping ")) { - StoreStream.getUserSettings().setShowTyping(subcommand.substring(11).startsWith("true")); - return "CTC: Successfully set showtyping state."; - } else if (subcommand.startsWith("token ")) { - StoreStream.getUserSettings().setStoredToken(subcommand.substring(6)); - return "CTC: Successfully changed token. Please restart application."; - } else if (subcommand.startsWith("token")) { - return StoreStream.getUserSettings().getStoredToken(); - } else { - if (subcommand.startsWith("account ")) { - String trim = subcommand.substring(8).trim(); - StoreUserSettings userSettings = StoreStream.getUserSettings(); - String accountToken = userSettings.getAccountToken(trim); - if (accountToken.startsWith("none")) { - return "CTC: No such account found."; - } - userSettings.setStoredToken(accountToken); - return "CTC: Successfully changed accounts. Please restart application."; - } else if (subcommand.startsWith("addaccount ")) { - String substring2 = subcommand.substring(11); - String substring3 = substring2.substring(substring2.indexOf(" ")); - String trim2 = substring2.replace(substring3, "").trim(); - String trim3 = substring3.trim(); - StoreUserSettings userSettings2 = StoreStream.getUserSettings(); - if (trim2.startsWith("current")) { - trim2 = userSettings2.getStoredToken(); - } - userSettings2.setAccountToken(trim2, trim3); - return "CTC: Added account."; - } else if (subcommand.startsWith("nodelete ")) { - StoreStream.getUserSettings().setNoDelete(subcommand.substring(9).startsWith("true")); - return "CTC: Successfully set nodelete state."; - } else if (!subcommand.startsWith("gifautoplay ")) { - return "CTC: No known command supplied. (available: token, showtyping, channelleak, addaccount, account, nodelete, gifautoplay. Everything except specified token needs to be lowercase)"; - } else { - StoreStream.getUserSettings().setAutoplayGifs(subcommand.substring(12).startsWith("true")); - return "CTC: Successfully set gifautoplay state."; - } - } - } - - @DexAdd - public static String slashFlip(String remaining) { - StringBuilder sb = new StringBuilder(remaining.toLowerCase()); - sb.reverse(); - return sb.toString().replace("a", "ɐ") - .replace("b", "q") - .replace("c", "ɔ") - .replace("d", "p") - .replace("e", "ǝ") - .replace("f", "ɟ") - .replace("g", "ƃ") - .replace("h", "ɥ") - .replace("i", "ı") - .replace("j", "ɾ") - .replace("k", "ʞ") - .replace("l", "ן") - .replace("m", "ɯ") - .replace("n", "u") - .replace("o", "o") - .replace("p", "d") - .replace("q", "b") - .replace("r", "ɹ") - .replace("s", "s") - .replace("t", "ʇ") - .replace("u", "n") - .replace("v", "ʌ") - .replace("w", "ʍ") - .replace("x", "x") - .replace("y", "ʎ") - .replace("z", "z"); - } - - @DexAdd - public static String slashFw(String remaining) { - return remaining.replace(" ", " ") - .replace("!", "!") - .replace("#", "#") - .replace("$", "$") - .replace("%", "%") - .replace("&", "&") - .replace("'", "'") - .replace("(", "(") - .replace(")", ")") - .replace("*", "*") - .replace("+", "+") - .replace(",", ",") - .replace("-", "-") - .replace(".", ".") - .replace("/", "/") - .replace("0", "0") - .replace("1", "1") - .replace("2", "2") - .replace("3", "3") - .replace("4", "4") - .replace("5", "5") - .replace("6", "6") - .replace("7", "7") - .replace("8", "8") - .replace("9", "9") - .replace(":", ":") - .replace(";", ";") - .replace("<", "<") - .replace("=", "=") - .replace(">", ">") - .replace("?", "?") - .replace("@", "@") - .replace("A", "A") - .replace("B", "B") - .replace("C", "C") - .replace("D", "D") - .replace("E", "E") - .replace("F", "F") - .replace("G", "G") - .replace("H", "H") - .replace("I", "I") - .replace("J", "J") - .replace("K", "K") - .replace("L", "L") - .replace("M", "M") - .replace("N", "N") - .replace("O", "O") - .replace("P", "P") - .replace("Q", "Q") - .replace("R", "R") - .replace("S", "S") - .replace("T", "T") - .replace("U", "U") - .replace("V", "V") - .replace("W", "W") - .replace("X", "X") - .replace("Y", "Y") - .replace("Z", "Z") - .replace("[", "[") - .replace("]", "]") - .replace("^", "^") - .replace("_", "_") - .replace("`", "`") - .replace("a", "a") - .replace("b", "b") - .replace("c", "c") - .replace("d", "d") - .replace("e", "e") - .replace("f", "f") - .replace("g", "g") - .replace("h", "h") - .replace("i", "i") - .replace("j", "j") - .replace("k", "k") - .replace("l", "l") - .replace("m", "m") - .replace("n", "n") - .replace("o", "o") - .replace("p", "p") - .replace("q", "q") - .replace("r", "r") - .replace("s", "s") - .replace("t", "t") - .replace("u", "u") - .replace("v", "v") - .replace("w", "w") - .replace("x", "x") - .replace("y", "y") - .replace("z", "z") - .replace("{", "{") - .replace("|", "|") - .replace("}", "}") - .replace("~", "~"); - } - - @DexAdd - public static String slashGordon(String remaining) { - return remaining.replace("a", "𝗮") - .replace("b", "𝗯") - .replace("c", "𝗰") - .replace("d", "𝗱") - .replace("e", "𝗲") - .replace("f", "𝗳") - .replace("g", "𝗴") - .replace("h", "𝗵") - .replace("i", "𝗶") - .replace("j", "𝗷") - .replace("k", "𝗸") - .replace("l", "𝗹") - .replace("m", "𝗺") - .replace("n", "𝗻") - .replace("o", "𝗼") - .replace("p", "𝗽") - .replace("q", "𝗾") - .replace("r", "𝗿") - .replace("s", "𝘀") - .replace("t", "𝘁") - .replace("u", "𝘂") - .replace("v", "𝘃") - .replace("w", "𝘄") - .replace("x", "𝘅") - .replace("y", "𝘆") - .replace("z", "𝘇") - .replace("A", "𝗔") - .replace("B", "𝗕") - .replace("C", "𝗖") - .replace("D", "𝗗") - .replace("E", "𝗘") - .replace("F", "𝗙") - .replace("G", "𝗚") - .replace("H", "𝗛") - .replace("I", "𝗜") - .replace("J", "𝗝") - .replace("K", "𝗞") - .replace("L", "𝗟") - .replace("M", "𝗠") - .replace("N", "𝗡") - .replace("O", "𝗢") - .replace("P", "𝗣") - .replace("Q", "𝗤") - .replace("R", "𝗥") - .replace("S", "𝗦") - .replace("T", "𝗧") - .replace("U", "𝗨") - .replace("V", "𝗩") - .replace("W", "𝗪") - .replace("X", "𝗫") - .replace("Y", "𝗬") - .replace("Z", "𝗭") - .replace("0", "𝟬") - .replace("1", "𝟭") - .replace("2", "𝟮") - .replace("3", "𝟯") - .replace("4", "𝟰") - .replace("5", "𝟱") - .replace("6", "𝟲") - .replace("7", "𝟳") - .replace("8", "𝟴") - .replace("9", "𝟵"); - } - - @DexAdd - public static String slashLenny(String remaining) { - return remaining + " ( ͡° ͜ʖ ͡°)"; - } - - @DexAdd - public static String slashLower(String remaining) { - return remaining.toLowerCase(); - } - - @DexAdd - public static String slashMe(String remaining) { - return "*" + remaining + "*"; - } - - @DexAdd - public static String slashMorse(String remaining) { - return remaining.toUpperCase().replace(" ", "/ ") - .replace(".", ".-.-.- ") - .replace(",", "--..-- ") - .replace(":", "---... ") - .replace("?", "..--.. ") - .replace("'", ".----. ") - .replace("-", "-....- ") - .replace("/", "-..-. ") - .replace("@", ".--.-. ") - .replace("=", "-...- ") - .replace("A", ".- ") - .replace("B", "-... ") - .replace("C", "-.-. ") - .replace("D", "-.. ") - .replace("E", ". ") - .replace("F", "..-. ") - .replace("G", "--. ") - .replace("H", ".... ") - .replace("I", ".. ") - .replace("J", ".--- ") - .replace("K", "-.- ") - .replace("L", ".-.. ") - .replace("M", "-- ") - .replace("N", "-. ") - .replace("O", "--- ") - .replace("P", ".--. ") - .replace("Q", "--.- ") - .replace("R", ".-. ") - .replace("S", "... ") - .replace("T", "- ") - .replace("U", "..- ") - .replace("V", "...- ") - .replace("W", ".-- ") - .replace("X", "-..- ") - .replace("Y", "-.-- ") - .replace("Z", "--.. ") - .replace("0", "----- ") - .replace("1", ".---- ") - .replace("2", "..--- ") - .replace("3", "...-- ") - .replace("4", "....- ") - .replace("5", "..... ") - .replace("6", "-.... ") - .replace("7", "--... ") - .replace("8", "---.. ") - .replace("9", "----. "); - } - - @DexAdd - public static String slashOwo(String remaining) { - return remaining.replaceAll("(?:r|l)", "w") - .replaceAll("(?:R|L)", "W") - .replaceAll("n([aeiou])", "ny$1") - .replaceAll("N([aeiou])", "Ny$1") - .replaceAll("N([AEIOU])", "NY$1") - .replace("ove", "uv"); - } - - @DexAdd - public static String slashSmall(String remaining) { - return remaining.toLowerCase().replace("a", "ᴀ").replace("b", "ʙ").replace("c", "ᴄ").replace("d", "ᴅ").replace("e", "ᴇ").replace("f", "ꜰ").replace("g", "ɢ").replace("h", "ʜ").replace("i", "ɪ").replace("j", "ᴊ").replace("k", "ᴋ").replace("l", "ʟ").replace("m", "ᴍ").replace("n", "ɴ").replace("o", "ᴏ").replace("p", "ᴘ").replace("q", "ǫ").replace("r", "ʀ").replace("s", "s").replace("t", "ᴛ").replace("u", "ᴜ").replace("v", "ᴠ").replace("w", "ᴡ").replace("y", "ʏ").replace("z", "ᴢ"); - } - - @DexAdd - public static String slashSmaller(String remaining) { - return remaining.toLowerCase().replace("a", "ᵃ").replace("b", "ᵇ").replace("c", "ᶜ").replace("d", "ᵈ").replace("e", "ᵉ").replace("f", "ᶠ").replace("g", "ᵍ").replace("h", "ʰ").replace("i", "ᶦ").replace("j", "ʲ").replace("k", "ᵏ").replace("l", "ˡ").replace("m", "ᵐ").replace("n", "ⁿ").replace("o", "ᵒ").replace("p", "ᵖ").replace("q", "ᑫ").replace("r", "ʳ").replace("s", "ˢ").replace("t", "ᵗ").replace("u", "ᵘ").replace("v", "ᵛ").replace("w", "ʷ").replace("x", "ˣ").replace("y", "ʸ").replace("z", "ᶻ"); - } - - @DexAdd - public static String slashSpoiler(String remaining) { - return "||" + remaining + "||"; - } - - @DexAdd - public static String slashSpoilerImg(String remaining) { - StoreStream.getUserSettings().setImageSpoiler(true); - return remaining; - } - - @DexAdd - public static String slashSt(String remaining) { - return "~~" + remaining + "~~"; - } - - @DexAdd - public static String slashUpper(String remaining) { - return remaining.toUpperCase(); - } } diff --git a/app/src/main/java/com/discord/stores/StoreMessagesHolder.java b/app/src/main/java/com/discord/stores/StoreMessagesHolder.java new file mode 100644 index 0000000..e0452d8 --- /dev/null +++ b/app/src/main/java/com/discord/stores/StoreMessagesHolder.java @@ -0,0 +1,22 @@ +package com.discord.stores; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.discord.models.domain.ModelMessage; + +import java.util.List; + +import lanchon.dexpatcher.annotation.DexEdit; +import lanchon.dexpatcher.annotation.DexIgnore; +import lanchon.dexpatcher.annotation.DexWrap; + +@DexEdit +public class StoreMessagesHolder { + + @DexIgnore + public void addMessages(@NonNull List list) { + + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/discord/stores/StoreStream.java b/app/src/main/java/com/discord/stores/StoreStream.java index 398d455..7c2064c 100644 --- a/app/src/main/java/com/discord/stores/StoreStream.java +++ b/app/src/main/java/com/discord/stores/StoreStream.java @@ -24,6 +24,9 @@ public class StoreStream { return null; } + @DexIgnore + public final StoreMessages getMessages() { return null; } + } } diff --git a/app/src/main/java/com/discord/stores/StoreThread.java b/app/src/main/java/com/discord/stores/StoreThread.java new file mode 100644 index 0000000..f4cf069 --- /dev/null +++ b/app/src/main/java/com/discord/stores/StoreThread.java @@ -0,0 +1,16 @@ +package com.discord.stores; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +@Target({ElementType.METHOD}) +@Documented +@Retention(RetentionPolicy.RUNTIME) +public @interface StoreThread { +} \ No newline at end of file diff --git a/app/src/main/java/com/discord/utilities/analytics/AnalyticsTracker.java b/app/src/main/java/com/discord/utilities/analytics/AnalyticsTracker.java index 50dd344..a690372 100644 --- a/app/src/main/java/com/discord/utilities/analytics/AnalyticsTracker.java +++ b/app/src/main/java/com/discord/utilities/analytics/AnalyticsTracker.java @@ -6,7 +6,7 @@ import lanchon.dexpatcher.annotation.DexEdit; import lanchon.dexpatcher.annotation.DexWrap; @DexEdit -public class AnalyticsTracker { +public final class AnalyticsTracker { // notrack patches - TODO toggle diff --git a/app/src/main/java/com/discord/utilities/analytics/AnalyticsUtils.java b/app/src/main/java/com/discord/utilities/analytics/AnalyticsUtils.java index 345c11a..23cf930 100644 --- a/app/src/main/java/com/discord/utilities/analytics/AnalyticsUtils.java +++ b/app/src/main/java/com/discord/utilities/analytics/AnalyticsUtils.java @@ -12,7 +12,7 @@ import lanchon.dexpatcher.annotation.DexIgnore; import lanchon.dexpatcher.annotation.DexWrap; @DexEdit -public class AnalyticsUtils { +public final class AnalyticsUtils { // start of notrack patches diff --git a/app/src/main/java/com/discord/utilities/icon/IconUtils.java b/app/src/main/java/com/discord/utilities/icon/IconUtils.java index e38aca8..76f11f3 100644 --- a/app/src/main/java/com/discord/utilities/icon/IconUtils.java +++ b/app/src/main/java/com/discord/utilities/icon/IconUtils.java @@ -6,7 +6,7 @@ import lanchon.dexpatcher.annotation.DexEdit; import lanchon.dexpatcher.annotation.DexWrap; @DexEdit -public class IconUtils { +public final class IconUtils { // hqaavatars patch diff --git a/app/src/main/java/com/discord/utilities/textprocessing/MessagePreprocessor.java b/app/src/main/java/com/discord/utilities/textprocessing/MessagePreprocessor.java index c35baef..343c241 100644 --- a/app/src/main/java/com/discord/utilities/textprocessing/MessagePreprocessor.java +++ b/app/src/main/java/com/discord/utilities/textprocessing/MessagePreprocessor.java @@ -10,7 +10,7 @@ import lanchon.dexpatcher.annotation.DexIgnore; import lanchon.dexpatcher.annotation.DexWrap; @DexEdit -public class MessagePreprocessor implements f.a.k.b.c.a { +public final class MessagePreprocessor implements f.a.k.b.c.a { // NodeProcessor in dex // Interfaces @DexIgnore diff --git a/app/src/main/java/com/discord/utilities/textprocessing/Rules.java b/app/src/main/java/com/discord/utilities/textprocessing/Rules.java index 5338421..1cc0069 100644 --- a/app/src/main/java/com/discord/utilities/textprocessing/Rules.java +++ b/app/src/main/java/com/discord/utilities/textprocessing/Rules.java @@ -8,28 +8,22 @@ import lanchon.dexpatcher.annotation.DexAdd; import lanchon.dexpatcher.annotation.DexEdit; import lanchon.dexpatcher.annotation.DexIgnore; -@DexIgnore//TODO -public class Rules { +@DexEdit +public final class Rules { // pseudonitro-viewer patch @DexEdit private static Pattern PATTERN_CUSTOM_EMOJI = ctc_getCustomEmojiPattern(); - @DexAdd - private static final Pattern ctc_PATTERN_CUSTOM_EMOJI_ORIGINAL = Pattern.compile("^<(a)?:([a-zA-Z_0-9]+):(\\d+)>"); - - @DexAdd - private static final Pattern ctc_PATTERN_CUSTOM_EMOJI_PSEUDONITRO = Pattern.compile("^<&?​?(a)?:([a-zA-Z_0-9]+):(\\d+)>"); - @DexAdd private static Pattern ctc_getCustomEmojiPattern() { if (!PatchConfig.PSEUDONITRO_VIEWER_ENABLED) { // Patch not enabled - return ctc_PATTERN_CUSTOM_EMOJI_ORIGINAL; + return Pattern.compile("^<(a)?:([a-zA-Z_0-9]+):(\\d+)>"); } - return ctc_PATTERN_CUSTOM_EMOJI_PSEUDONITRO; + return Pattern.compile("^<&?​?(a)?:([a-zA-Z_0-9]+):(\\d+)>"); } } diff --git a/app/src/main/java/com/discord/utilities/textprocessing/node/BasicRenderContext.java b/app/src/main/java/com/discord/utilities/textprocessing/node/BasicRenderContext.java new file mode 100644 index 0000000..d34606c --- /dev/null +++ b/app/src/main/java/com/discord/utilities/textprocessing/node/BasicRenderContext.java @@ -0,0 +1,14 @@ +package com.discord.utilities.textprocessing.node; + +import android.content.Context; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public interface BasicRenderContext { + + @DexIgnore + Context getContext(); + +} + diff --git a/app/src/main/java/com/discord/utilities/textprocessing/node/SpoilerNode.java b/app/src/main/java/com/discord/utilities/textprocessing/node/SpoilerNode.java index 629fb74..5798927 100644 --- a/app/src/main/java/com/discord/utilities/textprocessing/node/SpoilerNode.java +++ b/app/src/main/java/com/discord/utilities/textprocessing/node/SpoilerNode.java @@ -1,14 +1,17 @@ package com.discord.utilities.textprocessing.node; import com.PatchConfig; +import com.discord.simpleast.core.node.Node; import com.discordtest.BuildConfig; +import kotlin.Unit; +import kotlin.jvm.functions.Function1; import lanchon.dexpatcher.annotation.DexEdit; import lanchon.dexpatcher.annotation.DexIgnore; import lanchon.dexpatcher.annotation.DexWrap; -@DexIgnore//TODO -public class SpoilerNode { +@DexEdit +public final class SpoilerNode extends Node implements Spoilerable { // nospoiler patch @@ -25,4 +28,20 @@ public class SpoilerNode { return true; } + // end of nospoiler patch + + // class setup stuff + + @DexIgnore + public interface RenderContext extends BasicRenderContext { + @DexIgnore + int getSpoilerColorRes(); + + @DexIgnore + Function1, Unit> getSpoilerOnClick(); + + @DexIgnore + int getSpoilerRevealedColorRes(); + } + } diff --git a/app/src/main/java/com/discord/utilities/textprocessing/node/Spoilerable.java b/app/src/main/java/com/discord/utilities/textprocessing/node/Spoilerable.java new file mode 100644 index 0000000..52ba5ac --- /dev/null +++ b/app/src/main/java/com/discord/utilities/textprocessing/node/Spoilerable.java @@ -0,0 +1,8 @@ +package com.discord.utilities.textprocessing.node; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public interface Spoilerable { +} + diff --git a/app/src/main/java/com/discord/utilities/time/Clock.java b/app/src/main/java/com/discord/utilities/time/Clock.java new file mode 100644 index 0000000..a26cc91 --- /dev/null +++ b/app/src/main/java/com/discord/utilities/time/Clock.java @@ -0,0 +1,9 @@ +package com.discord.utilities.time; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public interface Clock { + @DexIgnore + long currentTimeMillis(); +} diff --git a/app/src/main/java/com/discord/utilities/time/TimeUtils.java b/app/src/main/java/com/discord/utilities/time/TimeUtils.java new file mode 100644 index 0000000..83378c0 --- /dev/null +++ b/app/src/main/java/com/discord/utilities/time/TimeUtils.java @@ -0,0 +1,13 @@ +package com.discord.utilities.time; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public final class TimeUtils { + + @DexIgnore + public static final String currentTimeUTCDateString(Clock clock) { + return null; + } + +} \ No newline at end of file diff --git a/app/src/main/java/com/discord/utilities/websocket/WebSocket.java b/app/src/main/java/com/discord/utilities/websocket/WebSocket.java index 57be64c..6749358 100644 --- a/app/src/main/java/com/discord/utilities/websocket/WebSocket.java +++ b/app/src/main/java/com/discord/utilities/websocket/WebSocket.java @@ -7,7 +7,7 @@ import lanchon.dexpatcher.annotation.DexAdd; import lanchon.dexpatcher.annotation.DexEdit; @DexEdit -public class WebSocket { +public final class WebSocket { // TODO can be done with wrap diff --git a/app/src/main/java/com/discord/widgets/auth/WidgetAuthLogin.java b/app/src/main/java/com/discord/widgets/auth/WidgetAuthLogin.java index a2e3beb..08dab2e 100644 --- a/app/src/main/java/com/discord/widgets/auth/WidgetAuthLogin.java +++ b/app/src/main/java/com/discord/widgets/auth/WidgetAuthLogin.java @@ -16,7 +16,7 @@ import lanchon.dexpatcher.annotation.DexWrap; @DexEdit @SuppressWarnings({"rawtypes", "unchecked", "ConstantConditions", "FinalPrivateMethod"}) -public class WidgetAuthLogin extends AppFragment { +public final class WidgetAuthLogin extends AppFragment { @DexIgnore public WidgetAuthLogin() {} diff --git a/app/src/main/java/com/discord/widgets/chat/input/TagObject.java b/app/src/main/java/com/discord/widgets/chat/input/TagObject.java new file mode 100644 index 0000000..7f2aec5 --- /dev/null +++ b/app/src/main/java/com/discord/widgets/chat/input/TagObject.java @@ -0,0 +1,21 @@ +package com.discord.widgets.chat.input; + +import com.discord.utilities.mg_recycler.MGRecyclerDataPayload; + +import java.util.regex.Pattern; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public interface TagObject extends MGRecyclerDataPayload { + + @DexIgnore + String getDisplayTag(); + + @DexIgnore + String getTag(); + + @DexIgnore + Pattern getTagRegex(); + +} diff --git a/app/src/main/java/com/discord/widgets/chat/input/WidgetChatInputCommandsModel.java b/app/src/main/java/com/discord/widgets/chat/input/WidgetChatInputCommandsModel.java new file mode 100644 index 0000000..5d2574a --- /dev/null +++ b/app/src/main/java/com/discord/widgets/chat/input/WidgetChatInputCommandsModel.java @@ -0,0 +1,101 @@ +package com.discord.widgets.chat.input; + +import androidx.annotation.Nullable; + +import com.PatchConfig; + +import java.util.Collection; +import java.util.Map; +import java.util.regex.Pattern; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexEdit; +import lanchon.dexpatcher.annotation.DexIgnore; +import lanchon.dexpatcher.annotation.DexWrap; + +@DexEdit +public class WidgetChatInputCommandsModel implements TagObject, Comparable { + + // slashcommands patch + + @DexWrap + private static Collection createBuiltInSlashCommands() { + Collection commands = createBuiltInSlashCommands(); + if (!PatchConfig.SLASH_COMMANDS_ENABLED) { + // Patch not enabled + return commands; + } + + // Naughty workaround to get default slashaction + WidgetChatInputCommandsModel o = (WidgetChatInputCommandsModel) commands.toArray()[0]; + WidgetChatInputSlashAction defaultSlashAction = o.slashAction; + + // Register our info messages + for (Map.Entry infoTexts : CommandHandler.getPopupInfo().entrySet()) { + // TODO fix + commands.add(createSlashCommand(infoTexts.getKey(), "{CTC_COMMAND}", infoTexts.getValue(), defaultSlashAction)); + } + + return commands; + + } + + // end of slashcommands patch + + @DexIgnore + private static WidgetChatInputCommandsModel createSlashCommand(String cmd, String str2, @Nullable String info, WidgetChatInputSlashAction widgetChatInputSlashAction) { + return null; + } + + @DexIgnore + @Nullable + private WidgetChatInputSlashAction slashAction; + + + // Interfaces.... + @DexIgnore + @Override + public String getDisplayTag() { + return null; + } + + @DexIgnore + @Override + public String getTag() { + return null; + } + + @DexIgnore + @Override + public Pattern getTagRegex() { + return null; + } + + @DexIgnore + @Override + public String getKey() { + return null; + } + + @DexIgnore + @Override + public int getType() { + return 0; + } + + @DexIgnore + @Override + public int compareTo(WidgetChatInputCommandsModel o) { + return 0; + } + // End of interfaces + + // Other class methods + + @DexIgnore + @Nullable + public String getSlashOutput() { + return null; + } + +} diff --git a/app/src/main/java/com/discord/widgets/chat/input/WidgetChatInputSlashAction.java b/app/src/main/java/com/discord/widgets/chat/input/WidgetChatInputSlashAction.java new file mode 100644 index 0000000..1c15889 --- /dev/null +++ b/app/src/main/java/com/discord/widgets/chat/input/WidgetChatInputSlashAction.java @@ -0,0 +1,9 @@ +package com.discord.widgets.chat.input; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public interface WidgetChatInputSlashAction { + @DexIgnore + String call(String str, WidgetChatInputCommandsModel widgetChatInputCommandsModel); +} diff --git a/app/src/main/java/com/discord/widgets/chat/input/emoji/EmojiPickerViewModel.java b/app/src/main/java/com/discord/widgets/chat/input/emoji/EmojiPickerViewModel.java index 95272e0..deb882d 100644 --- a/app/src/main/java/com/discord/widgets/chat/input/emoji/EmojiPickerViewModel.java +++ b/app/src/main/java/com/discord/widgets/chat/input/emoji/EmojiPickerViewModel.java @@ -12,7 +12,7 @@ import lanchon.dexpatcher.annotation.DexEdit; import lanchon.dexpatcher.annotation.DexIgnore; import lanchon.dexpatcher.annotation.DexWrap; -@DexIgnore//TODO +@DexIgnore public class EmojiPickerViewModel { @DexEdit @@ -20,9 +20,9 @@ public class EmojiPickerViewModel { // hideunusableemoji patch // filter the list then pass it into the original method - @SuppressWarnings("InfiniteRecursion") + @SuppressWarnings({"FinalPrivateMethod"}) @DexWrap - private List buildEmojiListItems(List list, String str, boolean z) { + private final List buildEmojiListItems(List list, String str, boolean z) { if (!PatchConfig.HIDE_UNUSABLE_EMOJIS_ENABLED) { // Patch not enabled diff --git a/app/src/main/java/com/discord/widgets/friends/NearbyManager.java b/app/src/main/java/com/discord/widgets/friends/NearbyManager.java index a60d655..9bce915 100644 --- a/app/src/main/java/com/discord/widgets/friends/NearbyManager.java +++ b/app/src/main/java/com/discord/widgets/friends/NearbyManager.java @@ -7,7 +7,7 @@ import lanchon.dexpatcher.annotation.DexEdit; import lanchon.dexpatcher.annotation.DexWrap; @DexEdit -public class NearbyManager { +public final class NearbyManager { // nonearby patch @DexWrap diff --git a/app/src/main/java/com/discord/widgets/settings/WidgetSettings.java b/app/src/main/java/com/discord/widgets/settings/WidgetSettings.java index 0192e95..9bca18a 100644 --- a/app/src/main/java/com/discord/widgets/settings/WidgetSettings.java +++ b/app/src/main/java/com/discord/widgets/settings/WidgetSettings.java @@ -13,7 +13,7 @@ import lanchon.dexpatcher.annotation.DexEdit; import lanchon.dexpatcher.annotation.DexIgnore; @DexEdit -public class WidgetSettings extends AppFragment implements OnTabSelectedListener { +public final class WidgetSettings extends AppFragment implements OnTabSelectedListener { // customversion patch diff --git a/app/src/main/java/cutthecord/commands/CommandHandler.java b/app/src/main/java/cutthecord/commands/CommandHandler.java new file mode 100644 index 0000000..2a73345 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/CommandHandler.java @@ -0,0 +1,217 @@ +package cutthecord.commands; + +import androidx.annotation.Nullable; + +import com.discord.models.domain.ModelUser; +import com.discord.stores.StoreMessages; +import com.discord.stores.StoreStream; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; +import java.util.regex.Pattern; + +import cutthecord.commands.commands.CmdBold; +import cutthecord.commands.commands.CmdClap; +import cutthecord.commands.commands.CmdCtc; +import cutthecord.commands.commands.CmdFlip; +import cutthecord.commands.commands.CmdFullWidth; +import cutthecord.commands.commands.CmdGordon; +import cutthecord.commands.commands.CmdLenny; +import cutthecord.commands.commands.CmdLower; +import cutthecord.commands.commands.CmdMe; +import cutthecord.commands.commands.CmdMorse; +import cutthecord.commands.commands.CmdOwo; +import cutthecord.commands.commands.CmdSlap; +import cutthecord.commands.commands.CmdSmall; +import cutthecord.commands.commands.CmdSmaller; +import cutthecord.commands.commands.CmdSpoiler; +import cutthecord.commands.commands.CmdSpoilerImg; +import cutthecord.commands.commands.CmdStrikethrough; +import cutthecord.commands.commands.CmdUpper; +import lanchon.dexpatcher.annotation.DexAdd; + + +// Helper class for additional commands (slashcommands) +@DexAdd +public class CommandHandler { + + @DexAdd + private static final HashMap commands = registerCommands(); + + @DexAdd + public abstract static class Command { + + @DexAdd + private final HashMap subcommands = new HashMap<>(); + + @DexAdd + public void registerSubCommand(String subCmdName, Command command) { + subcommands.put(subCmdName, command); + } + + @DexAdd + public Set getSubCommandNames() { + return subcommands.keySet(); + } + + @DexAdd + public String process(String args) { + // Check for possible subcommands + if (!subcommands.isEmpty()) { + final String[] split = args.split(Pattern.quote(" ")); + if (split.length > 0) { + final String possibleSubCmd = split[0].toLowerCase(); + for (Map.Entry subCommand : subcommands.entrySet()) { + if (subCommand.getKey().equals(possibleSubCmd)) { + + // Account for simple commands with no args + String newArgs = ""; + int i = args.indexOf(" "); + if (i == -1) { + newArgs = ""; + } else { + // Has args + int newSubPos = i + 1; + newArgs = args.substring(newSubPos); + } + + return subCommand.getValue().process(newArgs); + } + } + + } + } + + // Handle command + return handleCommand(args); + } + + @DexAdd + public abstract String handleCommand(String msg); + + @DexAdd + @Nullable + public abstract String getPopupInfo(); + } + + // Like a normal command, but the output is only viewable to the sender + @DexAdd + public abstract static class PrivateCommand extends Command { + + } + + @DexAdd + public static HashMap registerCommands() { + HashMap cmds = new HashMap<>(); + + cmds.put("upper", new CmdUpper()); + cmds.put("lower", new CmdLower()); + cmds.put("bold", new CmdBold()); + cmds.put("clap", new CmdClap()); + cmds.put("flip", new CmdFlip()); + cmds.put("slap", new CmdSlap()); + cmds.put("fw", new CmdFullWidth()); + cmds.put("gordon", new CmdGordon()); + cmds.put("me", new CmdMe()); + cmds.put("lenny", new CmdLenny()); + cmds.put("morse", new CmdMorse()); + cmds.put("owo", new CmdOwo()); + cmds.put("spoiler", new CmdSpoiler()); + cmds.put("spoilerimg", new CmdSpoilerImg()); + cmds.put("small", new CmdSmall()); + cmds.put("smaller", new CmdSmaller()); + cmds.put("st", new CmdStrikethrough()); + + // TODO can we add an CTC user that responds for these? + Command ctcCommand = new CmdCtc(); + ctcCommand.registerSubCommand("channelleak", new CmdCtc.CmdCtcChannelLeak()); + ctcCommand.registerSubCommand("showtyping", new CmdCtc.CmdCtcShowTyping()); + ctcCommand.registerSubCommand("token", new CmdCtc.CmdCtcToken()); + ctcCommand.registerSubCommand("account", new CmdCtc.CmdCtcAccount()); + ctcCommand.registerSubCommand("addaccount", new CmdCtc.CmdCtcAddAccount()); + ctcCommand.registerSubCommand("nodelete", new CmdCtc.CmdCtcNoDelete()); + ctcCommand.registerSubCommand("gifautoplay", new CmdCtc.CmdCtcGifAutoPlay()); + cmds.put("ctc", ctcCommand); + + return cmds; + } + + @DexAdd + public static HashMap getPopupInfo() { + HashMap infoPopups = new HashMap<>(); // Static init order makes things a pain so init in here + for (Map.Entry command : commands.entrySet()) { + String name = command.getKey(); + Command cmd = command.getValue(); + infoPopups.put(name, cmd.getPopupInfo()); + registerPopupInfoChildren(infoPopups, name, cmd); + } + + return infoPopups; + } + + @DexAdd + private static void registerPopupInfoChildren(HashMap infoPopups, String parent, Command parentCmd) { + for (Map.Entry subCommand : parentCmd.subcommands.entrySet()) { + String name = parent+" "+subCommand.getKey(); + infoPopups.put(name, subCommand.getValue().getPopupInfo()); + registerPopupInfoChildren(infoPopups, name, subCommand.getValue()); + } + } + + + @DexAdd + public static String slashCommands(StoreMessages storeMessages, long channelId, String str) { + String msg = str.trim(); + + // TODO check for edge cases like /meh parsing to /me + // TODO don't allow invalid commaands to end up in chat + + // Trim off "/" + msg = msg.substring(1); + + for (Map.Entry commandEntry : commands.entrySet()) { + if (msg.startsWith(commandEntry.getKey())) { + String newArgs = msg; + + // Account for simple commands with no args + int i = msg.indexOf(" "); + if (i == -1) { + newArgs = ""; + } else { + // Has args + int newSubPos = i + 1; + newArgs = msg.substring(newSubPos); + } + + String output = commandEntry.getValue().process(newArgs); + if (commandEntry.getValue() instanceof PrivateCommand) { + // Show message from ctcbot + storeMessages.sendCTCBotMessageToChannel(channelId, output); + + // This is naughty but discord handles it sanely + return null; + } + + return output; + } + } + + return str.trim(); + } + + + + @DexAdd + public static String interceptEditMessage(StoreMessages storeMessages, long channelId, String str) { + return str.startsWith("/") ? slashCommands(storeMessages, channelId, str) : str; + } + + @DexAdd + public static String interceptSendMessage(StoreMessages storeMessages, long channelId, String str) { + StoreStream.getUserSettings().setImageSpoiler(false); + return str.startsWith("/") ? slashCommands(storeMessages, channelId, str) : str; + } + + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdBold.java b/app/src/main/java/cutthecord/commands/commands/CmdBold.java new file mode 100644 index 0000000..2e61802 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdBold.java @@ -0,0 +1,21 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdBold extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return "**" + msg + "**"; + } + + @DexAdd + @Override + public final String getPopupInfo() { + return "Makes text bold"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdClap.java b/app/src/main/java/cutthecord/commands/commands/CmdClap.java new file mode 100644 index 0000000..ea64b1d --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdClap.java @@ -0,0 +1,21 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdClap extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return msg.replace(" ", " :clap: "); + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Please \uD83D\uDC4F clap"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdCtc.java b/app/src/main/java/cutthecord/commands/commands/CmdCtc.java new file mode 100644 index 0000000..d378b4c --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdCtc.java @@ -0,0 +1,174 @@ +package cutthecord.commands.commands; + +import androidx.annotation.Nullable; + +import com.discord.stores.StoreStream; +import com.discord.stores.StoreUserSettings; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdCtc extends CommandHandler.PrivateCommand { + + @DexAdd + @Override + public String handleCommand(String msg) { + // Command only has subcommands + return "CTC: No known command supplied. (available: "+ getSubCommandNames() +". Everything except specified token needs to be lowercase)"; + } + + @DexAdd + @Nullable + @Override + public String getPopupInfo() { + return null; + } + + @DexAdd + public static class CmdCtcChannelLeak extends CommandHandler.PrivateCommand { + + @DexAdd + @Override + public String handleCommand(String msg) { + StoreStream.getUserSettings().setLeakChannels(msg.startsWith("false")); + return "CTC: Successfully set channelleak state."; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Shows all channels, even those you don’t have permissions to view"; + } + + } + + @DexAdd + public static class CmdCtcShowTyping extends CommandHandler.PrivateCommand { + + @DexAdd + @Override + public String handleCommand(String msg) { + StoreStream.getUserSettings().setShowTyping(msg.startsWith("true")); + return "CTC: Successfully set showtyping state."; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Change typing event so that its visible/not when you type"; + } + + } + + @DexAdd + public static class CmdCtcToken extends CommandHandler.PrivateCommand { + + @DexAdd + @Override + public String handleCommand(String msg) { + if (msg.isEmpty()) { + // Print token + return StoreStream.getUserSettings().getStoredToken(); + } + + // Set token + StoreStream.getUserSettings().setStoredToken(msg); + return "CTC: Successfully changed token. Please restart application."; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Gives or sets token"; + } + + } + + @DexAdd + public static class CmdCtcAccount extends CommandHandler.PrivateCommand { + + @DexAdd + @Override + public String handleCommand(String msg) { + String trim = msg.trim(); + StoreUserSettings userSettings = StoreStream.getUserSettings(); + String accountToken = userSettings.getAccountToken(trim); + if (accountToken.startsWith("none")) { + return "CTC: No such account found."; + } + + userSettings.setStoredToken(accountToken); + return "CTC: Successfully changed accounts. Please restart application."; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Switches to the account specified"; + } + + } + + @DexAdd + public static class CmdCtcAddAccount extends CommandHandler.PrivateCommand { + + @DexAdd + @Override + public String handleCommand(String msg) { + String substring3 = msg.substring(msg.indexOf(" ")); + String trim2 = msg.replace(substring3, "").trim(); + String trim3 = substring3.trim(); + StoreUserSettings userSettings2 = StoreStream.getUserSettings(); + if (trim2.startsWith("current")) { + trim2 = userSettings2.getStoredToken(); + } + userSettings2.setAccountToken(trim2, trim3); + return "CTC: Added account."; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Adds an account to the account switcher"; + } + + } + + @DexAdd + public static class CmdCtcNoDelete extends CommandHandler.PrivateCommand { + + @DexAdd + @Override + public String handleCommand(String msg) { + StoreStream.getUserSettings().setNoDelete(msg.startsWith("true")); + return "CTC: Successfully set nodelete state."; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Disables handling of message delete events"; + } + + } + + @DexAdd + public static class CmdCtcGifAutoPlay extends CommandHandler.PrivateCommand { + + @DexAdd + @Override + public String handleCommand(String msg) { + StoreStream.getUserSettings().setAutoplayGifs(msg.startsWith("true")); + return "CTC: Successfully set gifautoplay state."; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Disables auto play of GIFs"; + } + + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdFlip.java b/app/src/main/java/cutthecord/commands/commands/CmdFlip.java new file mode 100644 index 0000000..2e926c1 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdFlip.java @@ -0,0 +1,48 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdFlip extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + StringBuilder sb = new StringBuilder(msg.toLowerCase()); + sb.reverse(); + return sb.toString().replace("a", "ɐ") + .replace("b", "q") + .replace("c", "ɔ") + .replace("d", "p") + .replace("e", "ǝ") + .replace("f", "ɟ") + .replace("g", "ƃ") + .replace("h", "ɥ") + .replace("i", "ı") + .replace("j", "ɾ") + .replace("k", "ʞ") + .replace("l", "ן") + .replace("m", "ɯ") + .replace("n", "u") + //.replace("o", "o") + .replace("p", "d") + .replace("q", "b") + .replace("r", "ɹ") + //.replace("s", "s") + .replace("t", "ʇ") + .replace("u", "n") + .replace("v", "ʌ") + .replace("w", "ʍ") + //.replace("x", "x") + .replace("y", "ʎ"); + //.replace("z", "z"); + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Flips text (like “ʇɥıs”)"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdFullWidth.java b/app/src/main/java/cutthecord/commands/commands/CmdFullWidth.java new file mode 100644 index 0000000..c82c199 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdFullWidth.java @@ -0,0 +1,113 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdFullWidth extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return msg.replace(" ", " ") + .replace("!", "!") + .replace("#", "#") + .replace("$", "$") + .replace("%", "%") + .replace("&", "&") + .replace("'", "'") + .replace("(", "(") + .replace(")", ")") + .replace("*", "*") + .replace("+", "+") + .replace(",", ",") + .replace("-", "-") + .replace(".", ".") + .replace("/", "/") + .replace("0", "0") + .replace("1", "1") + .replace("2", "2") + .replace("3", "3") + .replace("4", "4") + .replace("5", "5") + .replace("6", "6") + .replace("7", "7") + .replace("8", "8") + .replace("9", "9") + .replace(":", ":") + .replace(";", ";") + .replace("<", "<") + .replace("=", "=") + .replace(">", ">") + .replace("?", "?") + .replace("@", "@") + .replace("A", "A") + .replace("B", "B") + .replace("C", "C") + .replace("D", "D") + .replace("E", "E") + .replace("F", "F") + .replace("G", "G") + .replace("H", "H") + .replace("I", "I") + .replace("J", "J") + .replace("K", "K") + .replace("L", "L") + .replace("M", "M") + .replace("N", "N") + .replace("O", "O") + .replace("P", "P") + .replace("Q", "Q") + .replace("R", "R") + .replace("S", "S") + .replace("T", "T") + .replace("U", "U") + .replace("V", "V") + .replace("W", "W") + .replace("X", "X") + .replace("Y", "Y") + .replace("Z", "Z") + .replace("[", "[") + .replace("]", "]") + .replace("^", "^") + .replace("_", "_") + .replace("`", "`") + .replace("a", "a") + .replace("b", "b") + .replace("c", "c") + .replace("d", "d") + .replace("e", "e") + .replace("f", "f") + .replace("g", "g") + .replace("h", "h") + .replace("i", "i") + .replace("j", "j") + .replace("k", "k") + .replace("l", "l") + .replace("m", "m") + .replace("n", "n") + .replace("o", "o") + .replace("p", "p") + .replace("q", "q") + .replace("r", "r") + .replace("s", "s") + .replace("t", "t") + .replace("u", "u") + .replace("v", "v") + .replace("w", "w") + .replace("x", "x") + .replace("y", "y") + .replace("z", "z") + .replace("{", "{") + .replace("|", "|") + .replace("}", "}") + .replace("~", "~"); + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Makes text fullwidth (like “Sent from my Android Device”)"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdGordon.java b/app/src/main/java/cutthecord/commands/commands/CmdGordon.java new file mode 100644 index 0000000..3f9c772 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdGordon.java @@ -0,0 +1,82 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdGordon extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return msg.replace("a", "𝗮") + .replace("b", "𝗯") + .replace("c", "𝗰") + .replace("d", "𝗱") + .replace("e", "𝗲") + .replace("f", "𝗳") + .replace("g", "𝗴") + .replace("h", "𝗵") + .replace("i", "𝗶") + .replace("j", "𝗷") + .replace("k", "𝗸") + .replace("l", "𝗹") + .replace("m", "𝗺") + .replace("n", "𝗻") + .replace("o", "𝗼") + .replace("p", "𝗽") + .replace("q", "𝗾") + .replace("r", "𝗿") + .replace("s", "𝘀") + .replace("t", "𝘁") + .replace("u", "𝘂") + .replace("v", "𝘃") + .replace("w", "𝘄") + .replace("x", "𝘅") + .replace("y", "𝘆") + .replace("z", "𝘇") + .replace("A", "𝗔") + .replace("B", "𝗕") + .replace("C", "𝗖") + .replace("D", "𝗗") + .replace("E", "𝗘") + .replace("F", "𝗙") + .replace("G", "𝗚") + .replace("H", "𝗛") + .replace("I", "𝗜") + .replace("J", "𝗝") + .replace("K", "𝗞") + .replace("L", "𝗟") + .replace("M", "𝗠") + .replace("N", "𝗡") + .replace("O", "𝗢") + .replace("P", "𝗣") + .replace("Q", "𝗤") + .replace("R", "𝗥") + .replace("S", "𝗦") + .replace("T", "𝗧") + .replace("U", "𝗨") + .replace("V", "𝗩") + .replace("W", "𝗪") + .replace("X", "𝗫") + .replace("Y", "𝗬") + .replace("Z", "𝗭") + .replace("0", "𝟬") + .replace("1", "𝟭") + .replace("2", "𝟮") + .replace("3", "𝟯") + .replace("4", "𝟰") + .replace("5", "𝟱") + .replace("6", "𝟲") + .replace("7", "𝟳") + .replace("8", "𝟴") + .replace("9", "𝟵"); + } + + @DexAdd + @Override + public String getPopupInfo() { + return "\uD835\uDDDB\uD835\uDDF2\uD835\uDDF9\uD835\uDDF9\uD835\uDDFC,\uD835\uDDDA\uD835\uDDFC\uD835\uDDFF\uD835\uDDF1\uD835\uDDFC\uD835\uDDFB!"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdLenny.java b/app/src/main/java/cutthecord/commands/commands/CmdLenny.java new file mode 100644 index 0000000..0f7f606 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdLenny.java @@ -0,0 +1,24 @@ +package cutthecord.commands.commands; + +import androidx.annotation.Nullable; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdLenny extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return msg + " ( ͡° ͜ʖ ͡°)"; + } + + @DexAdd + @Nullable + @Override + public String getPopupInfo() { + return null; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdLower.java b/app/src/main/java/cutthecord/commands/commands/CmdLower.java new file mode 100644 index 0000000..67111fb --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdLower.java @@ -0,0 +1,24 @@ +package cutthecord.commands.commands; + +import androidx.annotation.Nullable; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdLower extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return msg.toLowerCase(); + } + + @DexAdd + @Nullable + @Override + public String getPopupInfo() { + return "Makes text lowercase"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdMe.java b/app/src/main/java/cutthecord/commands/commands/CmdMe.java new file mode 100644 index 0000000..5a9d00f --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdMe.java @@ -0,0 +1,21 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdMe extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return "*" + msg + "*"; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Display text with emphasis"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdMorse.java b/app/src/main/java/cutthecord/commands/commands/CmdMorse.java new file mode 100644 index 0000000..5d8ea45 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdMorse.java @@ -0,0 +1,66 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdMorse extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return msg.toUpperCase().replace(" ", "/ ") + .replace(".", ".-.-.- ") + .replace(",", "--..-- ") + .replace(":", "---... ") + .replace("?", "..--.. ") + .replace("'", ".----. ") + .replace("-", "-....- ") + .replace("/", "-..-. ") + .replace("@", ".--.-. ") + .replace("=", "-...- ") + .replace("A", ".- ") + .replace("B", "-... ") + .replace("C", "-.-. ") + .replace("D", "-.. ") + .replace("E", ". ") + .replace("F", "..-. ") + .replace("G", "--. ") + .replace("H", ".... ") + .replace("I", ".. ") + .replace("J", ".--- ") + .replace("K", "-.- ") + .replace("L", ".-.. ") + .replace("M", "-- ") + .replace("N", "-. ") + .replace("O", "--- ") + .replace("P", ".--. ") + .replace("Q", "--.- ") + .replace("R", ".-. ") + .replace("S", "... ") + .replace("T", "- ") + .replace("U", "..- ") + .replace("V", "...- ") + .replace("W", ".-- ") + .replace("X", "-..- ") + .replace("Y", "-.-- ") + .replace("Z", "--.. ") + .replace("0", "----- ") + .replace("1", ".---- ") + .replace("2", "..--- ") + .replace("3", "...-- ") + .replace("4", "....- ") + .replace("5", "..... ") + .replace("6", "-.... ") + .replace("7", "--... ") + .replace("8", "---.. ") + .replace("9", "----. "); + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Converts text into morse code"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdOwo.java b/app/src/main/java/cutthecord/commands/commands/CmdOwo.java new file mode 100644 index 0000000..18bbd59 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdOwo.java @@ -0,0 +1,26 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdOwo extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return msg.replaceAll("(?:r|l)", "w") + .replaceAll("(?:R|L)", "W") + .replaceAll("n([aeiou])", "ny$1") + .replaceAll("N([aeiou])", "Ny$1") + .replaceAll("N([AEIOU])", "NY$1") + .replace("ove", "uv"); + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Myakes tyext reawwy owo-ly, nya :3"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdSlap.java b/app/src/main/java/cutthecord/commands/commands/CmdSlap.java new file mode 100644 index 0000000..c3735fb --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdSlap.java @@ -0,0 +1,21 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdSlap extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return "*Slaps "+msg+" around a bit with a large trout.*"; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Slaps people with a large trout"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdSmall.java b/app/src/main/java/cutthecord/commands/commands/CmdSmall.java new file mode 100644 index 0000000..e2b77b6 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdSmall.java @@ -0,0 +1,46 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdSmall extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return msg.toLowerCase() + .replace("a", "ᴀ") + .replace("b", "ʙ") + .replace("c", "ᴄ") + .replace("d", "ᴅ") + .replace("e", "ᴇ") + .replace("f", "ꜰ") + .replace("g", "ɢ") + .replace("h", "ʜ") + .replace("i", "ɪ") + .replace("j", "ᴊ") + .replace("k", "ᴋ") + .replace("l", "ʟ") + .replace("m", "ᴍ") + .replace("n", "ɴ") + .replace("o", "ᴏ") + .replace("p", "ᴘ") + .replace("q", "ǫ") + .replace("r", "ʀ") + //.replace("s", "s") + .replace("t", "ᴛ") + .replace("u", "ᴜ") + .replace("v", "ᴠ") + .replace("w", "ᴡ") + .replace("y", "ʏ") + .replace("z", "ᴢ"); + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Makes text smaller (like “ᴛʜɪs”)"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdSmaller.java b/app/src/main/java/cutthecord/commands/commands/CmdSmaller.java new file mode 100644 index 0000000..6860fda --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdSmaller.java @@ -0,0 +1,47 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdSmaller extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return msg.toLowerCase() + .replace("a", "ᵃ") + .replace("b", "ᵇ") + .replace("c", "ᶜ") + .replace("d", "ᵈ") + .replace("e", "ᵉ") + .replace("f", "ᶠ") + .replace("g", "ᵍ") + .replace("h", "ʰ") + .replace("i", "ᶦ") + .replace("j", "ʲ") + .replace("k", "ᵏ") + .replace("l", "ˡ") + .replace("m", "ᵐ") + .replace("n", "ⁿ") + .replace("o", "ᵒ") + .replace("p", "ᵖ") + .replace("q", "ᑫ") + .replace("r", "ʳ") + .replace("s", "ˢ") + .replace("t", "ᵗ") + .replace("u", "ᵘ") + .replace("v", "ᵛ") + .replace("w", "ʷ") + .replace("x", "ˣ") + .replace("y", "ʸ") + .replace("z", "ᶻ"); + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Makes text even smaller (like “ᵗʰvˢ”)"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdSpoiler.java b/app/src/main/java/cutthecord/commands/commands/CmdSpoiler.java new file mode 100644 index 0000000..5468698 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdSpoiler.java @@ -0,0 +1,21 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdSpoiler extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return "||" + msg + "||"; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Marks your message as a spoiler"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdSpoilerImg.java b/app/src/main/java/cutthecord/commands/commands/CmdSpoilerImg.java new file mode 100644 index 0000000..9787f0b --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdSpoilerImg.java @@ -0,0 +1,24 @@ +package cutthecord.commands.commands; + +import com.discord.stores.StoreStream; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdSpoilerImg extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + StoreStream.getUserSettings().setImageSpoiler(true); + return msg; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Prepends SPOILER_ to names of all images attached to the message that starts with this, causing them to get marked as spoiler"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdStrikethrough.java b/app/src/main/java/cutthecord/commands/commands/CmdStrikethrough.java new file mode 100644 index 0000000..6957ec8 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdStrikethrough.java @@ -0,0 +1,21 @@ +package cutthecord.commands.commands; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdStrikethrough extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return "~~" + msg + "~~"; + } + + @DexAdd + @Override + public String getPopupInfo() { + return "Puts a strikethrough the message"; + } + +} diff --git a/app/src/main/java/cutthecord/commands/commands/CmdUpper.java b/app/src/main/java/cutthecord/commands/commands/CmdUpper.java new file mode 100644 index 0000000..a587603 --- /dev/null +++ b/app/src/main/java/cutthecord/commands/commands/CmdUpper.java @@ -0,0 +1,24 @@ +package cutthecord.commands.commands; + +import androidx.annotation.Nullable; + +import cutthecord.commands.CommandHandler; +import lanchon.dexpatcher.annotation.DexAdd; + +@DexAdd +public class CmdUpper extends CommandHandler.Command { + + @DexAdd + @Override + public String handleCommand(String msg) { + return msg.toUpperCase(); + } + + @DexAdd + @Nullable + @Override + public String getPopupInfo() { + return "Makes text uppercase"; + } + +} diff --git a/app/src/main/java/f/a/p/b/a/u.java b/app/src/main/java/f/a/p/b/a/u.java new file mode 100644 index 0000000..91d84b7 --- /dev/null +++ b/app/src/main/java/f/a/p/b/a/u.java @@ -0,0 +1,32 @@ +package f.a.p.b.a; + +import com.PatchConfig; +import com.discord.widgets.chat.input.WidgetChatInputCommandsModel; +import com.discord.widgets.chat.input.WidgetChatInputSlashAction; + +import lanchon.dexpatcher.annotation.DexEdit; +import lanchon.dexpatcher.annotation.DexWrap; + +@DexEdit +public final class u implements WidgetChatInputSlashAction { + + // slashcommands patch + + @DexWrap + @Override + public String call(String str, WidgetChatInputCommandsModel widgetChatInputCommandsModel) { + if (!PatchConfig.SLASH_COMMANDS_ENABLED) { + // Patch not enabled + return call(str, widgetChatInputCommandsModel); + } + + // We handle our commands elswhere so bail out here. + if (widgetChatInputCommandsModel.getSlashOutput().equals("{CTC_COMMAND}")) { + return str; + } + + String replaceAll = str.replaceAll(widgetChatInputCommandsModel.getTag(), ""); + return replaceAll + ' ' + widgetChatInputCommandsModel.getSlashOutput(); + } + +} diff --git a/app/src/main/java/kotlin/jvm/functions/Function1.java b/app/src/main/java/kotlin/jvm/functions/Function1.java new file mode 100644 index 0000000..4c27fd8 --- /dev/null +++ b/app/src/main/java/kotlin/jvm/functions/Function1.java @@ -0,0 +1,9 @@ +package kotlin.jvm.functions; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public interface Function1 { + @DexIgnore + R invoke(P1 p1); +} diff --git a/app/src/main/java/kotlin/jvm/functions/Function2.java b/app/src/main/java/kotlin/jvm/functions/Function2.java new file mode 100644 index 0000000..2f66b6d --- /dev/null +++ b/app/src/main/java/kotlin/jvm/functions/Function2.java @@ -0,0 +1,7 @@ +package kotlin.jvm.functions; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public interface Function2 { +} diff --git a/app/src/main/java/x/m/c/g.java b/app/src/main/java/x/m/c/g.java new file mode 100644 index 0000000..1609fd0 --- /dev/null +++ b/app/src/main/java/x/m/c/g.java @@ -0,0 +1,7 @@ +package x.m.c; + +import lanchon.dexpatcher.annotation.DexIgnore; + +@DexIgnore +public interface g { +} diff --git a/app/src/main/java/x/m/c/k.java b/app/src/main/java/x/m/c/k.java new file mode 100644 index 0000000..2495825 --- /dev/null +++ b/app/src/main/java/x/m/c/k.java @@ -0,0 +1,11 @@ +package x.m.c; + +import java.io.Serializable; + +import lanchon.dexpatcher.annotation.DexIgnore; + +// Lambda.kt +@DexIgnore +public abstract class k implements g, Serializable { + +} diff --git a/app/src/main/java/x/q/a.java b/app/src/main/java/x/q/a.java index f7a39c5..4e739da 100644 --- a/app/src/main/java/x/q/a.java +++ b/app/src/main/java/x/q/a.java @@ -7,6 +7,8 @@ import lanchon.dexpatcher.annotation.DexIgnore; @DexIgnore public interface a { + @DexIgnore List getAnnotations(); + }