Skip to content

Commit 954be16

Browse files
authored
Merge pull request #33 from Gikkman/0.6.3
Merge branch 0.6.3
2 parents 3fc4ba4 + 9d8a6da commit 954be16

18 files changed

Lines changed: 603 additions & 151 deletions

README.md

Lines changed: 38 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Java-Twirk
22
[![](https://jitpack.io/v/Gikkman/Java-Twirk.svg)](https://jitpack.io/#Gikkman/Java-Twirk)
3-
You can contact us via the [Discord Server](https://discord.gg/8NXaEyV)
43

54
Small, library for creating an IRC connection to the Twitch chat.
65

7-
The library is intended to make communication via Twitch chat as easy as possible, and uses Java objects to represent most events that can occur in Twitch chat.
6+
The library is intended to make communication via Twitch chat as easy as possible, and uses Java objects to represent
7+
most events that can occur in Twitch chat.
88

99
Java 8 compatible.
1010

@@ -21,14 +21,25 @@ Include the following in your pom.xml
2121
<dependencies>
2222
<dependency>
2323
<groupId>com.github.gikkman</groupId>
24-
<artifactId>Java-Twirk</artifactId>
25-
<version>0.6.2</version>
24+
<artifactId>Java-Twirk</artifactId>
25+
<version>0.6.3</version>
2626
</dependency>
2727
</dependencies>
2828
```
2929
Or simply download the latest version of the library jar from the release page.
3030

3131
## Changes
32+
### 0.6.3
33+
Some pretty big changes behind the scenes, but they should be fully backwards compatible. Below is a list of changes:
34+
* `Cheer.getImageURL(...)` should now return a proper URL. Fix #30
35+
* You can now set a custom PING interval, for how often the connection should ping Twitch.
36+
See `TwirkBuilder.setPingInterval` Fix #29
37+
* You can now assign custom log methods to Twirk, in case you use some kind of logging framework. You can also set
38+
different log levels, which gives a bit more control of what to log.
39+
See `TwirkBuilder.setLogLevel` and`TwirkBuilder.setXXXLogMethod`. Fix #28 (thanks to PR #31).
40+
* Calling connect after a disconnect should now work. Fix #26
41+
* You don't need to include the '#' anymore in the channel name. Fix #21
42+
3243
### 0.6.2
3344
Hotfix release since some emote IDs were still not parsed correctly (see #22). This hotfix should hopefully fix this issue.
3445
Please report any further issues with parsing emotes.
@@ -40,12 +51,15 @@ There has only been minor changes between 0.5 and 0.6. Nothing that should break
4051
* Fixed SockerClosedException stacktrace printing on some locales
4152
* I think I fixed it at least, but this one is hard to test since there are so many locales.
4253
* Updated the emotes parse for a safer and faster implementation.
43-
* This deprecates a previously public method (`EmoteParse.parseEmote(String, String)`), and the new method is package private. There isn't really any need to call these methods from outside the library
54+
* This deprecates a previously public method (`EmoteParse.parseEmote(String, String)`), and the new method is package
55+
private. There isn't really any need to call these methods from outside the library
4456
* Twirk will not only show the "User X was not online" or "User X was already online", when in verbose mode.
45-
* This happened when we see a leave/part message but didn't track the user correctly. I felt like it was not needed unless you want the verbose output
57+
* This happened when we see a leave/part message but didn't track the user correctly. I felt like it was not needed
58+
unless you want the verbose output
4659
* Updated the example a bit
4760
* Started to move towards proper JUnit tests
48-
* My home rolled test setup wasn't very user friendly, so now I started moving to user regular `@Test` tests. I'll eventually convert all tests to this format
61+
* My home rolled test setup wasn't very user friendly, so now I started moving to user regular `@Test` tests. I'll
62+
eventually convert all tests to this format
4963

5064
And probably some more...
5165

@@ -68,21 +82,34 @@ message with a "pong USER_NAME".
6882
} );
6983
```
7084

71-
For a more complex example, which shows how to connect properly and how to write simple bot commands, check out the example code in `src/example/java`
85+
For a more complex example, which shows how to connect properly and how to write simple bot commands, check out the
86+
example code in `src/example/java`
7287

7388
#### Extendable
74-
You can make Twirk use your own implementation of all event types by using custom builder classes. By extending the types Builder interface, and then passing an instance of your custom builder to the TwirkBuilder, you can use your own custom implementation of whichever type you want.
89+
You can make Twirk use your own implementation of all event types by using custom builder classes. By extending the
90+
types Builder interface, and then passing an instance of your custom builder to the TwirkBuilder, you can use your own
91+
custom implementation of whichever type you want.
7592
```Java
7693
final Twirk twirk = new TwirkBuilder(channel, SETTINGS.MY_NICK, SETTINGS.MY_PASS)
7794
.setClearChatBuilder( new MyClearChatBuilder() )
7895
.build();
7996
```
8097
This will make the Twirk instance build instances of your custom implementation of `ClearChat` events
8198

99+
# Known / Verified bot
100+
If your bot requires a very high message rate limit, you can request a verified bot account. It will increase the
101+
bots message rate limits: https://dev.twitch.tv/docs/irc/guide#known-and-verified-bots
102+
This isn't strictly necessary if you are just making a bot for your own account, as you might not reach the message
103+
limits. For larger/more frequently used bots, it might
104+
be necessary.
105+
82106
# Contribute
83-
If you find any issues, or have suggestions for features (which does not clutter the library), feel free to submit an [Issue](https://github.com/Gikkman/Java-Twirk/issues) or make a pull request. You can also reach me on [Twitter](https://twitter.com/gikkman) or on [Twitch](http://twitch.com/gikkman)
107+
If you find any issues, or have suggestions for features (which does not clutter the library), feel free to submit
108+
an [Issue](https://github.com/Gikkman/Java-Twirk/issues) or make a pull request. You can also reach me
109+
on [Twitter](https://twitter.com/gikkman) or on [Twitch](http://twitch.com/gikkman)
84110

85111

86112
# License
87-
This library is licensed under the [MIT License](https://tldrlegal.com/license/mit-license). If you use it, a link to this GitHub page is also greatly appriciated, if possible :)
113+
This library is licensed under the [MIT License](https://tldrlegal.com/license/mit-license). If you use it, a link to
114+
this GitHub page is also greatly appriciated, if possible :)
88115

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
<groupId>com.gikk</groupId>
66
<artifactId>twirc</artifactId>
7-
<version>0.6.2</version>
7+
<version>0.6.3</version>
88
<packaging>jar</packaging>
99

1010
<name>twirc</name>
@@ -97,7 +97,7 @@
9797
<dependency>
9898
<groupId>junit</groupId>
9999
<artifactId>junit</artifactId>
100-
<version>4.11</version>
100+
<version>4.13.1</version>
101101
<scope>test</scope>
102102
</dependency>
103103
</dependencies>

src/example/java/com/gikk/twirk/BotExample.java

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
import com.gikk.twirk.events.TwirkListener;
66
import java.io.IOException;
77
import java.io.InputStreamReader;
8+
import java.nio.charset.StandardCharsets;
89
import java.util.Scanner;
910

1011
/**Simple example of how Twirk can be used. <br><br>
@@ -22,29 +23,45 @@ public static void main(String[] args) throws IOException, InterruptedException{
2223
System.out.println("Welcome to this Bot example. In this example you will be able \n"
2324
+ "to send and receive messages from a Twitch chat channel. You will \n"
2425
+ "make all input directly here in the command prompt. \n\n"
25-
+ "Enter channel to join (leave out the #):");
26-
Scanner scanner = new Scanner(new InputStreamReader(System.in, "UTF-8"));
27-
String channel = "#" + scanner.nextLine();
26+
+ "Enter channel to join:");
27+
Scanner scanner = new Scanner(new InputStreamReader(System.in, StandardCharsets.UTF_8));
28+
String channel = scanner.nextLine();
2829

2930
final Twirk twirk = new TwirkBuilder(channel, SETTINGS.MY_NICK, SETTINGS.MY_PASS)
30-
.setVerboseMode(true) //We want to print everything we receive from Twitch
31-
.build(); //Create the Twirk object
31+
.setVerboseMode(true)
32+
.build();
3233

3334
twirk.addIrcListener( getOnDisconnectListener(twirk) );
3435
twirk.addIrcListener( new PatternCommandExample(twirk) );
3536
twirk.addIrcListener( new PrefixCommandExample(twirk) );
3637

37-
System.out.println("\nTo exit this example, type .quit and press Enter\n");
38+
System.out.println("To send a message to the channel, type it in the console and press Enter");
39+
System.out.println("To reconnect to Twitch, type .reconnect and press Enter");
40+
System.out.println("To exit this example, type .quit and press Enter");
3841

42+
Thread.sleep(2000);
3943
twirk.connect(); //Connect to Twitch
4044

4145
//As long as we don't type .quit into the command prompt, send everything we type as a message to twitch
4246
String line;
43-
while( !(line = scanner.nextLine()).matches(".quit") )
44-
twirk.channelMessage(line);
45-
47+
while( (line = scanner.nextLine()) != null ) {
48+
if(".quit".equals(line)) {
49+
//Close the connection to Twitch, and release all resources. This will not fire the onDisconnect
50+
//method
51+
twirk.close();
52+
break;
53+
}
54+
else if(".reconnect".equals(line)) {
55+
//Close the connection to Twitch, and release all resources. This will fire the onDisconnect method
56+
//however, which will cause us to reconnect to Twitch.
57+
twirk.disconnect();
58+
}
59+
else {
60+
twirk.channelMessage(line);
61+
}
62+
}
63+
4664
scanner.close(); //Close the scanner
47-
twirk.close(); //Close the connection to Twitch, and release all resources
4865
}
4966

5067
private static TwirkListener getOnDisconnectListener(final Twirk twirk) {
@@ -62,7 +79,7 @@ public void onDisconnect() {
6279
//If reconnection threw an IO exception, close the connection and release resources.
6380
twirk.close();
6481
}
65-
catch (InterruptedException e) { }
82+
catch (InterruptedException ignored) { }
6683
}
6784
};
6885
}

src/main/java/com/gikk/twirk/InputThread.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,8 @@ public void run() {
4242
try{
4343
connection.incommingMessage(line);
4444
} catch (Exception e) {
45-
System.err.println("Error in handling the incomming Irc Message");
46-
e.printStackTrace();
45+
connection.logger.error("Error in handling the incoming Irc Message");
46+
Util.printError(connection.logger, e);
4747
}
4848
}
4949
//If we reach this line, it means the line was null. That only happens if the end of the stream's been reached
@@ -67,10 +67,10 @@ public void run() {
6767
if( (message.toLowerCase().contains("socket closed")) ){
6868
//Ignore
6969
} else if ( message.contains("connection reset") || message.contains("stream closed")) {
70-
System.err.println( message );
70+
connection.logger.warn( e.getMessage() );
7171
}
7272
else {
73-
e.printStackTrace();
73+
Util.printError(connection.logger, e);
7474
}
7575
isConnected = false;
7676
}
@@ -81,7 +81,7 @@ public void run() {
8181
* inner catch-blocks. That should be very rare, but can occur if the thread is interrupted while
8282
* handling another exception
8383
*/
84-
e.printStackTrace();
84+
Util.printError(connection.logger, e);
8585
}
8686

8787
//If we have been disconnected, we close the connection and clean up the resources held by the IrcConnection.

src/main/java/com/gikk/twirk/OutputThread.java

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,10 @@ public void run(){
6868
/**Circumvents the message queue completely and attempts to send the message at once. Should only be used for sending
6969
* PING responses.
7070
*
71-
* @param message
71+
* @param message the message to send
7272
*/
7373
public void quickSend(String message) {
74-
try {
75-
sendLine(message);
76-
} catch (SocketException e) {
77-
System.err.println("Could not QuickSend message. Socket was closed (OutputThread @ Twirk)");
78-
}
74+
sendLine(message);
7975
}
8076

8177
/**Tells the thread to stop execution. Future messages written to the {@code OutputQueue} will
@@ -104,23 +100,20 @@ void setMessageDelay(int millis){
104100
//***********************************************************************************************
105101

106102
/**Sends a message AS IS, without modifying it in any way. Users of this method are responsible for
107-
* formating the string correctly:
103+
* formatting the string correctly:
108104
* <br>
109105
* That means, who ever uses this method has to manually assign channel data and the similar to the
110106
* message.
111107
*
112108
* @param message The message to write to out BufferedWriter
113109
*/
114-
private void sendLine(String message) throws SocketException{
110+
private void sendLine(String message) {
115111
if( !isConnected ){
116-
System.err.println("Twirk is not connected! Sending messages will not succeed!");
112+
connection.logger.error("Twirk is not connected! Sending messages will not succeed!");
117113
}
114+
connection.logger.debug("OUT " + message);
118115

119-
if(connection.verboseMode) {
120-
System.out.println("OUT " + message);
121-
}
122-
123-
/**An IRC message may not be longer than 512 characters. Also, they must end with \r\n,
116+
/* An IRC message may not be longer than 512 characters. Also, they must end with \r\n,
124117
* so if the supplied message is longer than 510 characters, we have to cut it short.
125118
*
126119
* While it might be an alternative to split the message and send it in different batches,
@@ -137,11 +130,12 @@ private void sendLine(String message) throws SocketException{
137130
writer.flush();
138131
}
139132
} catch (IOException e){
140-
if( e.getMessage().matches("Stream closed") ){
141-
System.err.println("Cannot send message: " + message +" Stream closed");
142-
return;
133+
if( e.getMessage().toLowerCase().matches("stream closed") ){
134+
connection.logger.warn("Cannot send message: \"" + message + "\" Stream closed");
135+
}
136+
else {
137+
Util.printError(connection.logger, e);
143138
}
144-
e.printStackTrace();
145139
}
146140
}
147141
}
Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,26 @@
11
package com.gikk.twirk;
22

3+
import javax.net.ssl.SSLSocketFactory;
34
import java.io.IOException;
45
import java.net.Socket;
56

6-
/**
7+
/** Factory method for creating a {@link Socket} for the Twirk instance. The socket is later used to connect to Twitch
78
*
89
* @author Gikkman
910
*/
11+
@FunctionalInterface
1012
public interface SocketFactory {
11-
public Socket createSocket() throws IOException;
13+
14+
/**
15+
* Given a server and a port, creates {@link Socket} that can be used to connect to Twitch's IRC interface
16+
* @param server the server
17+
* @param port the port
18+
* @return a {@link Socket}
19+
* @throws IOException if a {@link Socket} cannot be created
20+
*/
21+
Socket createSocket(String server, int port) throws IOException;
22+
23+
static SocketFactory getDefault(boolean useSSL) {
24+
return useSSL ? SSLSocketFactory.getDefault()::createSocket : Socket::new;
25+
}
1226
}

0 commit comments

Comments
 (0)