Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

update 17.9.0 #682

Merged
merged 5 commits into from
Aug 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ jobs:

# set env variables
- name: set variables
run: |
echo "APK_URL=https://www.dropbox.com/scl/fi/jc7uhpvb2xa5094lcv0gr/twitch-17.0.0.apk\?rlkey=4wkiikz6wfbvvh9kiywvmivfb\&st=1fzwygd9\&dl=1" >> $GITHUB_ENV
run: |
echo "APK_URL=https://www.dropbox.com/scl/fi/mlm7vzjy7da4g9wp72gzl/twitch-17.9.0.apk\?rlkey=b5fedom0wslvlyxkjkmrf9xt3\&st=kjpp5ly3\&dl=1" >> $GITHUB_ENV

# get keystore.kjs from secret
- name: create keystore.kjs from secret
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ A mod of the Twitch Android Mobile<sup><a href="#no-tv">1</a></sup> App adding B

# Build it yourself

> This patch is meant to be applied to version **16.9.1** of the official twitch app
> This patch is meant to be applied to version **17.9.0** of the official twitch app
> Make sure you use this version before you create an issue!

## Easy way: Docker
Expand Down Expand Up @@ -128,7 +128,7 @@ Made with ♥️ by [@FoseFx](https://github.com/FoseFx) and contributors. MIT L
[license-badge]: https://img.shields.io/github/license/bttv-android/bttv?style=flat-square
[license-file]: ./LICENSE
[bttv-version]: https://img.shields.io/github/v/release/bttv-android/bttv?style=flat-square
[base-version]: https://img.shields.io/badge/build%20on-v16.9.1-blueviolet?style=flat-square
[base-version]: https://img.shields.io/badge/build%20on-v17.9.0-blueviolet?style=flat-square
[downloads-latest]: https://img.shields.io/github/downloads/bttv-android/bttv/latest/total?color=yellow&style=flat-square
[downloads-total]: https://img.shields.io/github/downloads/bttv-android/bttv/total?color=yellowgreen&label=downloads%20total&style=flat-square
[latest-release]: https://github.com/bttv-android/bttv/releases/latest
Expand Down
4 changes: 2 additions & 2 deletions mod/app/src/main/java/bttv/Badges.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import okhttp3.Response;
import okhttp3.ResponseBody;
import tv.twitch.android.models.chat.MessageBadge;
import tv.twitch.chat.ChatMessageInfo;
import tv.twitch.chat.library.model.ChatMessageInfo;

public class Badges {
public static final String TAG = "LBTTVBadges";
Expand All @@ -32,7 +32,7 @@ public class Badges {
* Appends our badges to the list of badges if the user has any
*/
public static void appendToBadges(ChatMessageInfo chatMessageInfo, List<MessageBadge> originalBadges) {
String userId = String.valueOf(chatMessageInfo.userId);
String userId = String.valueOf(chatMessageInfo.getUserInfo().getUserId());

List<BTTVBadge> ourBadges = userToBadgesMap.get(userId);

Expand Down
19 changes: 11 additions & 8 deletions mod/app/src/main/java/bttv/ChommentModelDelegateWrapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@

import java.util.List;

import javax.inject.Provider;

import bttv.highlight.Highlight;
import tv.twitch.android.shared.chat.ChatMessageParserSdk;
import tv.twitch.android.shared.chat.pub.model.messages.MessageToken;
import tv.twitch.android.models.chomments.ChommentModel;
import tv.twitch.android.shared.chat.pub.model.ChatMessageTokenizerWrapper;
Expand All @@ -20,16 +23,16 @@ public class ChommentModelDelegateWrapper extends ChommentModelDelegate {
private Boolean BTTVshouldHighlightB = null;

public ChommentModelDelegateWrapper(ChommentModel chommentModel,
SDKServicesController sdkServicesController,
ChatMessageParser chatMessageParser,
ExperimentHelper experimentHelper,
ChatMessageTokenizerWrapper chatMessageTokenizerWrapper) {
Provider<ChatMessageParserSdk> chatMessageParserSdkProvider,
Provider<tv.twitch.android.shared.chat.ChatMessageParser> chatMessageParserProvider,
ChatMessageTokenizerWrapper chatMessageTokenizerWrapper,
tv.twitch.android.shared.chat.KmpChatExperiment kpmChatExperiment) {
super(
chommentModel,
sdkServicesController,
chatMessageParser,
experimentHelper,
chatMessageTokenizerWrapper
chatMessageParserSdkProvider,
chatMessageParserProvider,
chatMessageTokenizerWrapper,
kpmChatExperiment
);
}

Expand Down
165 changes: 140 additions & 25 deletions mod/app/src/main/java/bttv/Tokenizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
import tv.twitch.android.shared.chat.ChatMessageDelegate;
import tv.twitch.chat.AutoModFlags;
import tv.twitch.chat.ChatEmoticonToken;
import tv.twitch.chat.ChatMessageInfo;
import tv.twitch.chat.ChatMessageToken;
import tv.twitch.chat.ChatMessageTokenType;
import tv.twitch.chat.ChatTextToken;
import tv.twitch.chat.library.model.ChatMessageInfo;

public class Tokenizer {

Expand All @@ -45,7 +45,7 @@ public static Pair<List<MessageToken>, Boolean> tokenize(List<MessageToken> orig
for (MessageToken token : orig) {
// possible issue: emotes won't work in e.g. MentionToken or BitsToken
if (!(token instanceof TextToken)) {
if (token instanceof EmoticonToken && newTokens.size() > 0) {
if (token instanceof EmoticonToken && !newTokens.isEmpty()) {
if (newTokens.get(newTokens.size() - 1) instanceof EmoticonToken) {
newTokens.add(new TextToken(" ", new AutoModMessageFlags()));
}
Expand Down Expand Up @@ -94,10 +94,11 @@ public static Pair<List<MessageToken>, Boolean> tokenize(List<MessageToken> orig
return new Pair<>(newTokens, shouldHighlight);
}

/** @noinspection unused */
public static void retokenizeLiveChatMessage(ChatMessageInterface chatMessageInterface) {
if (chatMessageInterface instanceof ChatMessageDelegate) {
ChatMessageDelegate delegate = (ChatMessageDelegate) chatMessageInterface;
retokenizeLiveChatMessage(delegate.mChatMessage);
retokenizeLiveChatMessage(delegate.chatMessage);
} else {
Log.w(
"LBTTV",
Expand All @@ -106,33 +107,123 @@ public static void retokenizeLiveChatMessage(ChatMessageInterface chatMessageInt
}
}

/** @noinspection unused */
public static void retokenizeLiveChatMessage(tv.twitch.chat.ChatMessageInfo info) {
try {
Context ctx = Data.ctx;
int channel = Data.currentBroadcasterId;

ArrayList<tv.twitch.chat.ChatMessageToken> newTokens = new ArrayList<>(info.tokens.length + 10);

boolean shouldHighlight = false;
boolean shouldBlock = false;

for (tv.twitch.chat.ChatMessageToken token : info.tokens) {
Log.d("LBTTV", "retokenizeLiveChatMessage: " + token);
if (!isTextTokenOld(token)) {
if (isEmoteTokenOld(token) && !newTokens.isEmpty()) {
tv.twitch.chat.ChatMessageToken prevToken = newTokens.get(newTokens.size() - 1);
if (prevToken != null && !endsWithSpaceOld(prevToken)) {
ChatTextToken spaceToken = new ChatTextToken();
spaceToken.text = " ";
spaceToken.autoModFlags = new AutoModFlags();
newTokens.add(spaceToken);
}
}
newTokens.add(token);
continue;
}

ChatTextToken textToken = (ChatTextToken) token;
String text = textToken.text;

if (text.equals(" ")) {
// " ".split(" ") will produce an empty array
// this is why we need to handle this edge-case
newTokens.add(textToken);
continue;
}
String[] tokens = text.split(" ");

StringBuilder currentText = new StringBuilder();
for (String word : tokens) {
if (Blacklist.shouldBlock(word)) {
shouldBlock = true;
}
if (Highlight.shouldHighlight(word)) {
shouldHighlight = true;
}
Emote emote = Emotes.getEmote(ctx, word, channel);
if (emote == null) {
currentText.append(word).append(" ");
continue;
}
// emote found
String before = currentText.toString();
if (!before.isEmpty()) {
ChatTextToken everythingBeforeEmote = new ChatTextToken();
everythingBeforeEmote.text = before;
everythingBeforeEmote.autoModFlags = textToken.autoModFlags;
newTokens.add(everythingBeforeEmote);
}
ChatEmoticonToken emoteToken = new ChatEmoticonToken();
emoteToken.emoticonText = word;
emoteToken.emoticonId = "BTTV-" + emote.id;
newTokens.add(emoteToken);

// prepare next TextToken
currentText.setLength(0);
currentText.append(' ');
}
String before = currentText.toString();
if (!before.trim().isEmpty()) {
ChatTextToken everything = new ChatTextToken();
everything.text = before;
everything.autoModFlags = textToken.autoModFlags;
newTokens.add(everything);
}
}

info.tokens = newTokens.toArray(new ChatMessageToken[0]);

if (shouldBlock) {
info.messageType = "bttv-blocked-message";
} else if (shouldHighlight) {
info.messageType = "bttv-highlighted-message";
}
} catch (Throwable throwable) {
Log.e("LBTTV", "retokenizeLiveChatMessage: " + throwable.getMessage());
}
}

public static void retokenizeLiveChatMessage(ChatMessageInfo info) {
Context ctx = Data.ctx;
int channel = Data.currentBroadcasterId;

ArrayList<ChatMessageToken> newTokens = new ArrayList<>(info.tokens.length + 10);
ArrayList<tv.twitch.chat.library.model.MessageToken> newTokens = new ArrayList<>(info.tokens.size() + 10);

boolean shouldHighlight = false;
boolean shouldBlock = false;

for (ChatMessageToken token : info.tokens) {
for (tv.twitch.chat.library.model.MessageToken token : info.tokens) {
Log.d("LBTTV", "retokenizeLiveChatMessage: " + token);
if (!isTextToken(token)) {
if (isEmoteToken(token) && !newTokens.isEmpty()) {
ChatMessageToken prevToken = newTokens.get(newTokens.size() - 1);
tv.twitch.chat.library.model.MessageToken prevToken = newTokens.get(newTokens.size() - 1);
if (prevToken != null && !endsWithSpace(prevToken)) {
ChatTextToken spaceToken = new ChatTextToken();
spaceToken.text = " ";
spaceToken.autoModFlags = new AutoModFlags();
tv.twitch.chat.library.model.MessageToken.TextToken spaceToken = new tv.twitch.chat.library.model.MessageToken.TextToken(
" ",
new tv.twitch.chat.library.model.AutoModFlags()
);
newTokens.add(spaceToken);
}
}
newTokens.add(token);
continue;
}

ChatTextToken textToken = (ChatTextToken) token;
String text = textToken.text;
tv.twitch.chat.library.model.MessageToken.TextToken textToken = (tv.twitch.chat.library.model.MessageToken.TextToken) token;
String text = textToken.getText();

if (text.equals(" ")) {
// " ".split(" ") will produce an empty array
Expand All @@ -158,14 +249,10 @@ public static void retokenizeLiveChatMessage(ChatMessageInfo info) {
// emote found
String before = currentText.toString();
if (!before.isEmpty()) {
ChatTextToken everythingBeforeEmote = new ChatTextToken();
everythingBeforeEmote.text = before;
everythingBeforeEmote.autoModFlags = textToken.autoModFlags;
tv.twitch.chat.library.model.MessageToken.TextToken everythingBeforeEmote = new tv.twitch.chat.library.model.MessageToken.TextToken(before, textToken.getFlags());
newTokens.add(everythingBeforeEmote);
}
ChatEmoticonToken emoteToken = new ChatEmoticonToken();
emoteToken.emoticonId = "BTTV-" + emote.id;
emoteToken.emoticonText = word;
tv.twitch.chat.library.model.MessageToken.EmoteToken emoteToken = new tv.twitch.chat.library.model.MessageToken.EmoteToken(word, "BTTV-" + emote.id);
newTokens.add(emoteToken);

// prepare next TextToken
Expand All @@ -174,14 +261,14 @@ public static void retokenizeLiveChatMessage(ChatMessageInfo info) {
}
String before = currentText.toString();
if (!before.trim().isEmpty()) {
ChatTextToken everything = new ChatTextToken();
everything.text = before;
everything.autoModFlags = textToken.autoModFlags;
tv.twitch.chat.library.model.MessageToken.TextToken everything = new tv.twitch.chat.library.model.MessageToken.TextToken(
before, textToken.getFlags()
);
newTokens.add(everything);
}
}

info.tokens = newTokens.toArray(new ChatMessageToken[0]);
info.tokens = newTokens;

if (shouldBlock) {
info.messageType = "bttv-blocked-message";
Expand All @@ -190,27 +277,55 @@ public static void retokenizeLiveChatMessage(ChatMessageInfo info) {
}
}

private static boolean endsWithSpace(@NotNull ChatMessageToken token) {
private static boolean endsWithSpace(@NotNull tv.twitch.chat.library.model.MessageToken token) {
if (!(token instanceof tv.twitch.chat.library.model.MessageToken.TextToken)) {
return false;
}
tv.twitch.chat.library.model.MessageToken.TextToken textToken = (tv.twitch.chat.library.model.MessageToken.TextToken) token;
String text = textToken.getText();
if (text.isEmpty()) {
return false;
}
char lastChar = text.charAt(text.length() - 1);
return lastChar == ' ';
}

private static boolean endsWithSpaceOld(@NotNull tv.twitch.chat.ChatMessageToken token) {
if (token.type.getValue() != ChatMessageTokenType.Text.getValue()) {
return false;
}
ChatTextToken textToken = (ChatTextToken) token;
String text = textToken.text;
if (text.length() == 0) {
if (text.isEmpty()) {
return false;
}
char lastChar = text.charAt(text.length() - 1);
return lastChar == ' ';
}

private static boolean isTextToken(ChatMessageToken token) {
private static boolean isTextToken(tv.twitch.chat.library.model.MessageToken token) {
if (token == null) {
return false;
}
return token instanceof tv.twitch.chat.library.model.MessageToken.TextToken;
}

private static boolean isTextTokenOld(tv.twitch.chat.ChatMessageToken token) {
if (token == null) {
return false;
}
return token.type.getValue() == ChatMessageTokenType.Text.getValue();
}

private static boolean isEmoteToken(ChatMessageToken token) {

private static boolean isEmoteToken(tv.twitch.chat.library.model.MessageToken token) {
if (token == null) {
return false;
}
return token instanceof tv.twitch.chat.library.model.MessageToken.EmoteToken;
}

private static boolean isEmoteTokenOld(tv.twitch.chat.ChatMessageToken token) {
if (token == null) {
return false;
}
Expand Down
4 changes: 3 additions & 1 deletion mod/app/src/main/java/bttv/api/Badges.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@
import java.util.List;

import tv.twitch.android.models.chat.MessageBadge;
import tv.twitch.chat.ChatMessageInfo;
import tv.twitch.chat.library.model.ChatMessageInfo;

public class Badges {
public static final String TAG = "LBTTVBadges";
/** @noinspection unused */
public static void appendToBadges(ChatMessageInfo chatMessageInfo, List<MessageBadge> originalBadges) {
try {
bttv.Badges.appendToBadges(chatMessageInfo, originalBadges);
Expand All @@ -17,6 +18,7 @@ public static void appendToBadges(ChatMessageInfo chatMessageInfo, List<MessageB
}
}

/** @noinspection unused */
public static String getUrl(int channelId, String badgeName, String badgeVersion) {
try {
return bttv.Badges.getUrl(channelId, badgeName, badgeVersion);
Expand Down
9 changes: 8 additions & 1 deletion mod/app/src/main/java/bttv/api/Blacklist.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@
import tv.twitch.android.shared.chat.pub.messages.ui.ChatMessageInterface;
import tv.twitch.android.shared.chat.ChatMessageDelegate;

/** @noinspection ALL */
public class Blacklist {
/** @noinspection unused*/
public static boolean isBlocked(ChatMessageInterface chatMessageInterface) {
if (chatMessageInterface instanceof ChatMessageDelegate) {
ChatMessageDelegate delegate = (ChatMessageDelegate) chatMessageInterface;
return delegate.mChatMessage.messageType.equals("bttv-blocked-message");
if (delegate.chatMessage.messageType != null) {
return delegate.chatMessage.messageType.equals("bttv-blocked-message");
} else {
Log.w("LBTTV", "isBlocked: messageType == null");
return false;
}
} else {
Log.w(
"LBTTV",
Expand Down
Loading
Loading