You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
502 lines
19 KiB
502 lines
19 KiB
package sig.modules;
|
|
|
|
import java.awt.Color;
|
|
import java.awt.Graphics;
|
|
import java.awt.Graphics2D;
|
|
import java.awt.Rectangle;
|
|
import java.awt.event.WindowEvent;
|
|
import java.awt.geom.Rectangle2D;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.net.MalformedURLException;
|
|
import java.net.URL;
|
|
import java.text.DateFormat;
|
|
import java.util.ArrayList;
|
|
import java.util.Arrays;
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
|
|
import javax.imageio.ImageIO;
|
|
import javax.swing.SwingUtilities;
|
|
|
|
import com.mb3364.twitch.api.handlers.ChannelFollowsResponseHandler;
|
|
import com.mb3364.twitch.api.handlers.StreamResponseHandler;
|
|
import com.mb3364.twitch.api.handlers.UserResponseHandler;
|
|
import com.mb3364.twitch.api.models.ChannelFollow;
|
|
import com.mb3364.twitch.api.models.Stream;
|
|
import com.mb3364.twitch.api.models.User;
|
|
|
|
import sig.Module;
|
|
import sig.sigIRC;
|
|
import sig.modules.Twitch.Announcement;
|
|
import sig.modules.Twitch.FancyNumber;
|
|
import sig.utils.DrawUtils;
|
|
import sig.utils.FileUtils;
|
|
import sig.utils.SoundUtils;
|
|
import sig.utils.TextUtils;
|
|
import sig.utils.TimeUtils;
|
|
|
|
public class TwitchModule extends Module{
|
|
public String console="Twitch module goes here.";
|
|
final public static String USERDIR = sigIRC.BASEDIR+"sigIRC/users/";
|
|
final public static String SOUNDSDIR = sigIRC.BASEDIR+"sigIRC/follower_sounds/";
|
|
final public static String FOLLOWERQUEUEFILE = USERDIR+"followers.txt";
|
|
public static boolean streamOnline = false;
|
|
static BufferedImage follower_img;
|
|
BufferedImage followerUserLogo;
|
|
List<Announcement> follower_queue = new ArrayList<Announcement>();
|
|
final static int FOLLOWERCHECKTIMER = 900;
|
|
int lastFollowerCheck=300;
|
|
final static int FOLLOWERANNOUNCEMENTTIME = 300;
|
|
int lastFollowerAnnouncement=0;
|
|
User announcedFollowerUser;
|
|
String[] followersounds = new String[]{"Glaceon_cry.wav"};
|
|
FancyNumber viewers_numb;
|
|
FancyNumber followers_numb;
|
|
FancyNumber views_numb;
|
|
Date uptime = Calendar.getInstance().getTime();
|
|
String currentlyPlaying=" ";
|
|
final public static int ARROWTIMER = 3000;
|
|
public static BufferedImage UPARROWIMAGE;
|
|
public static BufferedImage DOWNARROWIMAGE;
|
|
public static BufferedImage UPTIMEIMAGE;
|
|
|
|
public TwitchModule(Rectangle2D bounds, String moduleName) {
|
|
this(bounds,moduleName,true);
|
|
}
|
|
|
|
public TwitchModule(Rectangle2D bounds, String moduleName, boolean enabled) {
|
|
super(bounds, moduleName, enabled);
|
|
Initialize();
|
|
}
|
|
|
|
private void Initialize() {
|
|
boolean firstTime = false;
|
|
InitializeImages();
|
|
InitializeStatistics();
|
|
InitializeFollowerSounds();
|
|
firstTime = CreateUserFolder();
|
|
if (firstTime) {
|
|
CreateFollowerQueueLog();
|
|
}
|
|
/*manager.streams().get("theduckishot", new StreamResponseHandler() {
|
|
|
|
@Override
|
|
public void onFailure(Throwable arg0) {
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(int arg0, String arg1, String arg2) {
|
|
System.out.println(arg0+","+arg1+","+arg2);
|
|
}
|
|
|
|
@Override
|
|
public void onSuccess(Stream arg0) {
|
|
//System.out.println("Stream data is available! "+arg0);
|
|
if (arg0==null) {
|
|
System.out.println("Stream is offline.");
|
|
} else {
|
|
System.out.println("Stream is online.");
|
|
}
|
|
}
|
|
|
|
});*/
|
|
/*manager.channels().getFollows(TextUtils.getActualChannelName(), new ChannelFollowsResponseHandler() {
|
|
@Override
|
|
public void onSuccess(int total, java.util.List<ChannelFollow> follows) {
|
|
//System.out.println("Successfully found followers for channel "+sigIRC.channel+". Total: "+total);
|
|
//console = "Last Follower: "+follows.get(0).getUser().getDisplayName();
|
|
follows.get(0).
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(Throwable arg0) {
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(int arg0, String arg1, String arg2) {
|
|
System.out.println(arg0+","+arg1+","+arg2);
|
|
}
|
|
}
|
|
);*/
|
|
/*SwingUtilities.invokeLater(new Runnable() {
|
|
public void run() {
|
|
System.out.println("Follower Queue Size: "+follower_queue.size()+", Contents: "+follower_queue);
|
|
}
|
|
});*/
|
|
}
|
|
|
|
private void InitializeFollowerSounds() {
|
|
File follower_sounds_dir = new File(SOUNDSDIR);
|
|
String[] files = filterFiles(follower_sounds_dir.list());
|
|
followersounds = files;
|
|
//System.out.println(Arrays.toString(followersounds));
|
|
}
|
|
|
|
private static String[] filterFiles(String[] files) {
|
|
List<String> finallist = new ArrayList<String>();
|
|
for (String file : files) {
|
|
if (!file.equalsIgnoreCase("README.txt")) {
|
|
File f = new File(SOUNDSDIR+file);
|
|
if (!f.isDirectory()) {
|
|
finallist.add(file);
|
|
}
|
|
}
|
|
}
|
|
return finallist.toArray(new String[finallist.size()]);
|
|
}
|
|
|
|
private void InitializeStatistics() {
|
|
viewers_numb = new FancyNumber("icon_viewers_count.png",0);
|
|
views_numb = new FancyNumber("icon_views_count.png",0);
|
|
followers_numb = new FancyNumber("icon_follower_count.png",0);
|
|
}
|
|
|
|
public void run() {
|
|
if (lastFollowerCheck--<=0) {
|
|
lastFollowerCheck = FOLLOWERCHECKTIMER;
|
|
getFollowers(false);
|
|
popFollowerFromQueue();
|
|
isStreamOnline(true);
|
|
}
|
|
if (lastFollowerAnnouncement>0) {
|
|
lastFollowerAnnouncement--;
|
|
}
|
|
//System.out.println(lastFollowerCheck);
|
|
}
|
|
|
|
public void ApplyConfigWindowProperties() {
|
|
sigIRC.twitchmodule_X=(int)position.getX();
|
|
sigIRC.twitchmodule_Y=(int)position.getY();
|
|
sigIRC.config.setInteger("TWITCH_module_X", sigIRC.twitchmodule_X);
|
|
sigIRC.config.setInteger("TWITCH_module_Y", sigIRC.twitchmodule_Y);
|
|
}
|
|
|
|
private void popFollowerFromQueue() {
|
|
if (sigIRC.testMode) {
|
|
User user = new User();
|
|
user.setDisplayName("Test User"+((int)Math.random()*100000));
|
|
user.setBio("I am an awesome test subject.");
|
|
user.setName(user.getDisplayName());
|
|
user.setLogo("http://45.33.13.215/sigIRCv2/sigIRC/sigIRCicon.png");
|
|
DisplayFollowerAnnouncement(user,true);
|
|
} else
|
|
if (follower_queue.size()>0) {
|
|
if (isStreamOnline()) {
|
|
//We have a follower to announce!
|
|
Announcement a = follower_queue.remove(0);
|
|
User user = a.getUser();
|
|
if (user.getDisplayName().length()>0 &&
|
|
!user.getDisplayName().contains("?")) {
|
|
DisplayFollowerAnnouncement(user,true);
|
|
} else {
|
|
DisplayFollowerAnnouncement(user,false);
|
|
}
|
|
} else {
|
|
//Store away all remaining followers in the queue....We can't announce them right now.
|
|
StoreRemainingFollowers();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void windowClosed(WindowEvent ev) {
|
|
StoreRemainingFollowers();
|
|
}
|
|
|
|
private void StoreRemainingFollowers() {
|
|
for (Announcement a : follower_queue) {
|
|
FileUtils.logToFile(Long.toString(a.getUser().getId()), FOLLOWERQUEUEFILE);
|
|
}
|
|
follower_queue.clear();
|
|
}
|
|
|
|
private void DisplayFollowerAnnouncement(User user, boolean useNickname) {
|
|
lastFollowerAnnouncement = FOLLOWERANNOUNCEMENTTIME;
|
|
if (!useNickname) {
|
|
user.setDisplayName(user.getName());
|
|
}
|
|
announcedFollowerUser = user;
|
|
String followerAnnouncement = user.getDisplayName()+" is now following the stream!";
|
|
String userlogo = USERDIR+user.getId()+"_logo";
|
|
if (user.getLogo()!=null && !user.getLogo().equalsIgnoreCase("null")) {
|
|
try {
|
|
org.apache.commons.io.FileUtils.copyURLToFile(new URL(user.getLogo()),new File(userlogo));
|
|
File logo = new File(userlogo);
|
|
if (logo.exists()) {
|
|
followerUserLogo = ImageIO.read(logo);
|
|
} else {
|
|
followerUserLogo=null;
|
|
}
|
|
} catch (MalformedURLException e) {
|
|
e.printStackTrace();
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
} else {
|
|
followerUserLogo = null;
|
|
}
|
|
LogMessageToFile(followerAnnouncement);
|
|
System.out.println(followerAnnouncement);
|
|
SoundUtils.playSound(SOUNDSDIR+followersounds[(int)(Math.random()*followersounds.length)]);
|
|
}
|
|
|
|
private void InitializeImages() {
|
|
try {
|
|
follower_img = ImageIO.read(new File(sigIRC.BASEDIR+sigIRC.twitchmodule_follower_img));
|
|
UPARROWIMAGE = ImageIO.read(new File(sigIRC.BASEDIR+"sigIRC/icon_up_arrow.png"));
|
|
DOWNARROWIMAGE = ImageIO.read(new File(sigIRC.BASEDIR+"sigIRC/icon_down_arrow.png"));
|
|
UPTIMEIMAGE = ImageIO.read(new File(sigIRC.BASEDIR+"sigIRC/icon_uptime.png"));
|
|
//System.out.println("Initialized Follower Image successfully.");
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
private void CreateFollowerQueueLog() {
|
|
String dir = FOLLOWERQUEUEFILE;
|
|
File filer = new File(dir);
|
|
if (!filer.exists()) {
|
|
try {
|
|
filer.createNewFile();
|
|
System.out.println("Follower Queue Log does not exist. Creating in "+USERDIR+".");
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
}
|
|
|
|
private void getFollowers(boolean firstTime) {
|
|
sigIRC.manager.channels().getFollows(TextUtils.getActualChannelName(), new ChannelFollowsResponseHandler() {
|
|
@Override
|
|
public void onSuccess(int total, java.util.List<ChannelFollow> follows) {
|
|
//System.out.println("Successfully found followers for channel "+sigIRC.channel+". Total: "+total);
|
|
//console = "Last Follower: "+follows.get(0).getUser().getDisplayName();
|
|
for (ChannelFollow f : follows) {
|
|
addFollower(f,isStreamOnline(),firstTime);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(Throwable arg0) {
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(int arg0, String arg1, String arg2) {
|
|
System.out.println(arg0+","+arg1+","+arg2);
|
|
}
|
|
}
|
|
);
|
|
if (isStreamOnline()) {/*System.out.println("Stream is Online...Clearing Follower Queue.");*/ClearFollowerAnnouncerQueue();}
|
|
}
|
|
|
|
private void ClearFollowerAnnouncerQueue() {
|
|
String[] contents = FileUtils.readFromFile(FOLLOWERQUEUEFILE);
|
|
//System.out.println("Contents: "+Arrays.toString(contents));
|
|
FileUtils.deleteFile(FOLLOWERQUEUEFILE);
|
|
for (String s : contents) {
|
|
if (s.length()>0) {
|
|
int twitchID = Integer.parseInt(s);
|
|
AddFollowerToQueue(twitchID);
|
|
}
|
|
}
|
|
}
|
|
private boolean isStreamOnline() {
|
|
return isStreamOnline(false);
|
|
}
|
|
|
|
private boolean isStreamOnline(boolean update) {
|
|
if (update) {
|
|
sigIRC.manager.streams().get(TextUtils.getActualChannelName(), new StreamResponseHandler() {
|
|
|
|
@Override
|
|
public void onFailure(Throwable arg0) {
|
|
TwitchModule.streamOnline=false;
|
|
}
|
|
|
|
@Override
|
|
public void onFailure(int arg0, String arg1, String arg2) {
|
|
System.out.println(arg0+","+arg1+","+arg2);
|
|
TwitchModule.streamOnline=false;
|
|
}
|
|
|
|
@Override
|
|
public void onSuccess(Stream arg0) {
|
|
//System.out.println("Stream data is available! "+arg0);
|
|
if (arg0==null) {
|
|
TwitchModule.streamOnline=false;
|
|
} else {
|
|
TwitchModule.streamOnline=true;
|
|
UpdateAllStreamStatistics(arg0);
|
|
}
|
|
}
|
|
|
|
private void UpdateAllStreamStatistics(Stream data) {
|
|
if (data!=null) {
|
|
if (data.getGame()!=null && data.getGame().length()>0) {
|
|
currentlyPlaying = data.getGame();
|
|
}
|
|
if (data.getCreatedAt()!=null) {
|
|
uptime = data.getCreatedAt();
|
|
}
|
|
viewers_numb.updateValue(data.getViewers());
|
|
views_numb.updateValue((int)data.getChannel().getViews());
|
|
followers_numb.updateValue(data.getChannel().getFollowers());
|
|
}
|
|
}
|
|
|
|
});
|
|
return TwitchModule.streamOnline;
|
|
} else {
|
|
return TwitchModule.streamOnline;
|
|
}
|
|
//TwitchModule.streamOnline=true;
|
|
//return true;
|
|
}
|
|
|
|
protected void addFollower(ChannelFollow f, boolean streamOnline, boolean silent) {
|
|
String filename = USERDIR+f.getUser().getId();
|
|
File userProfile = new File(filename);
|
|
if (!userProfile.exists()) {
|
|
if (!silent) { //If we got in here, this isn't the initial follower setup, so we are good to go with announcing these followers.
|
|
if (!streamOnline) {
|
|
//Save their ID to a queue.
|
|
FileUtils.logToFile(Long.toString(f.getUser().getId()), FOLLOWERQUEUEFILE);
|
|
} else {
|
|
//Announce it now.
|
|
//System.out.println("Stream is online...");
|
|
AnnounceFollower(f);
|
|
}
|
|
}
|
|
CreateUserProfile(f, filename, userProfile);
|
|
}
|
|
}
|
|
|
|
private void CreateUserProfile(ChannelFollow f, String filename, File userProfile) {
|
|
try {
|
|
userProfile.createNewFile();
|
|
FileUtils.logToFile(DateFormat.getDateInstance().format(f.getCreatedAt()), filename);
|
|
FileUtils.logToFile(f.getUser().getBio(), filename);
|
|
FileUtils.logToFile(f.getUser().getDisplayName(), filename);
|
|
FileUtils.logToFile(f.getUser().getLogo(), filename);
|
|
FileUtils.logToFile(f.getUser().getName(), filename);
|
|
FileUtils.logToFile(f.getUser().getType(), filename);
|
|
FileUtils.logToFile(DateFormat.getDateInstance().format(f.getUser().getUpdatedAt()), filename);
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
private void AnnounceFollower(ChannelFollow f) {
|
|
//System.out.println("Thanks for following "+f.getUser().getDisplayName()+"!");
|
|
AddFollowerToQueue(f.getUser());
|
|
}
|
|
|
|
private void AddFollowerToQueue(int id) {
|
|
follower_queue.add(new Announcement(id));
|
|
}
|
|
|
|
private void AddFollowerToQueue(User user) {
|
|
follower_queue.add(new Announcement(user));
|
|
}
|
|
|
|
private boolean CreateUserFolder() {
|
|
File userDir = new File(USERDIR);
|
|
if (!userDir.exists()) {
|
|
userDir.mkdir();
|
|
System.out.println("Could not find Twitch User directory. Creating in "+USERDIR+".");
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private void LogMessageToFile(String message) {
|
|
Calendar cal = Calendar.getInstance();
|
|
FileUtils.logToFile(message, sigIRC.BASEDIR+"sigIRC/logs/log_"+(cal.get(Calendar.MONTH)+1)+"_"+cal.get(Calendar.DAY_OF_MONTH)+"_"+cal.get(Calendar.YEAR)+".txt",true);
|
|
}
|
|
|
|
public void draw(Graphics g){
|
|
super.draw(g);
|
|
//DrawUtils.drawText(g, bounds.getX(), bounds.getY()+24, Color.RED, console);
|
|
DrawFollowerAnnouncement(g);
|
|
if (streamOnline) {
|
|
DrawStatisticsBar(g);
|
|
}
|
|
}
|
|
|
|
private void DrawStatisticsBar(Graphics g) {
|
|
g.setColor(new Color(25,25,25));
|
|
int xoffset = (int)position.getX()+4;
|
|
int yoffset = (int)(position.getY()+follower_img.getHeight()+sigIRC.twitchmodule_newfollowerImgLogoSize);
|
|
g.fillPolygon(new int[]{(int)position.getX(),(int)(position.getX()+position.getWidth()),(int)(position.getX()+position.getWidth()),(int)position.getX()},
|
|
new int[]{yoffset-4,yoffset-4,yoffset+16,yoffset+16},
|
|
4);
|
|
if (currentlyPlaying!=null && currentlyPlaying.length()>0) {
|
|
DrawUtils.drawOutlineText(g, sigIRC.panel.userFont, xoffset, yoffset+TextUtils.calculateStringBoundsFont(currentlyPlaying, sigIRC.panel.userFont).getHeight()/2+3, 2, g.getColor(), new Color(195,195,195), currentlyPlaying);xoffset+=TextUtils.calculateStringBoundsFont(currentlyPlaying, sigIRC.panel.userFont).getWidth()+16;
|
|
}
|
|
Rectangle offsets = DrawUptime(g, xoffset, yoffset);xoffset+=offsets.getWidth();
|
|
offsets = views_numb.draw(g, xoffset, yoffset);xoffset+=offsets.getWidth();
|
|
offsets = followers_numb.draw(g, xoffset, yoffset);xoffset+=offsets.getWidth();
|
|
offsets = viewers_numb.draw(g, xoffset, yoffset);xoffset+=offsets.getWidth();
|
|
}
|
|
|
|
private Rectangle DrawUptime(Graphics g, int x, int y) {
|
|
int xoffset = 0;
|
|
int yoffset = 0;
|
|
g.drawImage(UPTIMEIMAGE, x+xoffset, y+yoffset-2, sigIRC.panel);xoffset+=UPTIMEIMAGE.getWidth()+4;
|
|
String timediff = TimeUtils.GetTimeDifferenceFromCurrentDate(uptime);
|
|
if (timediff.length()>0) {
|
|
DrawUtils.drawTextFont(g, sigIRC.panel.userFont, x+xoffset, y+yoffset+TextUtils.calculateStringBoundsFont(timediff, sigIRC.panel.userFont).getHeight()/2+3,new Color(184,181,192),timediff);xoffset+=TextUtils.calculateStringBoundsFont(timediff, sigIRC.panel.userFont).getWidth()+12;
|
|
}
|
|
yoffset+=16;
|
|
return new Rectangle(x,y,xoffset,yoffset);
|
|
}
|
|
|
|
private void DrawFollowerAnnouncement(Graphics g) {
|
|
if (lastFollowerAnnouncement>0) {
|
|
final int ticksPassed = FOLLOWERANNOUNCEMENTTIME-lastFollowerAnnouncement;
|
|
final int yAlteration =
|
|
(sigIRC.twitchmodule_follower_img_animation)
|
|
? Math.max(0,(int)(200-(ticksPassed*(200d/30))))
|
|
: 0;
|
|
final int canvasYOffset =
|
|
(sigIRC.twitchmodule_follower_img_animation)
|
|
? Math.min(follower_img.getHeight(),yAlteration)
|
|
: 0;
|
|
final int xAlteration =
|
|
(sigIRC.twitchmodule_follower_img_animation)
|
|
? (ticksPassed>=270)?(int)(-((ticksPassed-270)*(500d/30))):0
|
|
: 0;
|
|
final int canvasXOffset =
|
|
(sigIRC.twitchmodule_follower_img_animation)
|
|
? Math.min(follower_img.getWidth(),xAlteration)
|
|
: 0;
|
|
//System.out.println(yAlteration);
|
|
//g.drawImage(follower_img, (int)bounds.getX()+xAlteration, (int)bounds.getY()+yAlteration, sigIRC.panel);
|
|
//g.drawImage(follower_img, (int)bounds.getX(), (int)bounds.getY(), , , sigIRC.panel)
|
|
g.drawImage(follower_img, (int)position.getX(), (int)position.getY()+canvasYOffset, (int)position.getX()+follower_img.getWidth()+canvasXOffset, (int)position.getY()+follower_img.getHeight(),
|
|
-xAlteration, 0, follower_img.getWidth(), follower_img.getHeight()-yAlteration, sigIRC.panel);
|
|
Rectangle2D usernameTextsize = TextUtils.calculateStringBoundsFont(announcedFollowerUser.getDisplayName(), sigIRC.panel.programFont);
|
|
int textY = (int)position.getY()+sigIRC.twitchmodule_followerText_Y+yAlteration;
|
|
int textX = (int)position.getX()+sigIRC.twitchmodule_followerText_centerX+xAlteration;
|
|
if (textY<position.getY()+position.getHeight() && textX+usernameTextsize.getWidth()>position.getX()) {
|
|
DrawUtils.drawCenteredText(g, sigIRC.panel.programFont, (int)position.getX()+sigIRC.twitchmodule_followerText_centerX+xAlteration, (int)position.getY()+sigIRC.twitchmodule_followerText_Y+yAlteration, Color.BLACK, announcedFollowerUser.getDisplayName());
|
|
}
|
|
if (announcedFollowerUser.getBio()!=null && !announcedFollowerUser.getBio().equalsIgnoreCase("null")) {
|
|
if (followerUserLogo!=null) {
|
|
final int image_size = sigIRC.twitchmodule_newfollowerImgLogoSize;
|
|
int img_startx = (int)(position.getX()+position.getWidth()-ticksPassed*3-(image_size+4));
|
|
int img_starty = (int)(position.getY()+follower_img.getHeight()+2-image_size/2);
|
|
//g.setColor(Color.BLACK);
|
|
//g.drawRect(img_startx, img_starty, image_size, image_size);
|
|
g.drawImage(followerUserLogo, img_startx, img_starty, img_startx+image_size, img_starty+image_size, 0, 0, followerUserLogo.getWidth(), followerUserLogo.getHeight(), TextUtils.convertStringToColor(sigIRC.twitchmodule_newfollowerImgBackgroundColor), sigIRC.panel);
|
|
}
|
|
if (announcedFollowerUser.getBio()!=null && announcedFollowerUser.getBio().length()>0) {
|
|
DrawUtils.drawOutlineText(g, sigIRC.panel.userFont, position.getX()+position.getWidth()-ticksPassed*3, position.getY()+follower_img.getHeight()+2+8, 2, TextUtils.convertStringToColor(sigIRC.twitchmodule_newfollowerTextColor), TextUtils.convertStringToColor(sigIRC.twitchmodule_newfollowerShadowTextColor), announcedFollowerUser.getBio());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|