Skip to content

Commit

Permalink
make it ask twitch for what irc server to connect to. (you can also o…
Browse files Browse the repository at this point in the history
…verride it by specifying an address in the config)
  • Loading branch information
Hyphen-ated committed Mar 18, 2016
1 parent 555e62b commit 3e33342
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 6 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@
<artifactId>dropwizard-assets</artifactId>
<version>${dropwizard.version}</version>
</dependency>
<dependency>
<groupId>io.dropwizard</groupId>
<artifactId>dropwizard-client</artifactId>
<version>${dropwizard.version}</version>
</dependency>


<dependency>
<groupId>pircbot</groupId>
Expand Down
40 changes: 39 additions & 1 deletion src/main/installDir/options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,13 @@ adminPassword: password
# (at some point there may be a real user system with a database and everything, but for now it's just this one user)

#############################################################
# stuff you don't need to care about
# stuff you usually don't need to care about

twitchChatServerAssignmentUrl: http://tmi.twitch.tv/servers?channel=%CHANNEL%

# in case something breaks with the automatic assignment, you can manually set the chat server to connect to here:
# twitchIrcHost: "irc.chat.twitch.tv:80"

logging:

# The default level of all loggers. Can be OFF, ERROR, WARN, INFO, DEBUG, TRACE, or ALL.
Expand Down Expand Up @@ -119,3 +125,35 @@ server:
- type: http
port: 8081

httpClient:
# The socket timeout value. If a read or write to the underlying
# TCP/IP connection hasn't succeeded after this duration, a
# timeout exception is thrown.
timeout: 500ms

# The connection timeout value. If a TCP/IP connection cannot be
# established in this time, a timeout exception is thrown.
connectionTimeout: 500ms

# The time a TCP/IP connection to the server is allowed to
# persist before being explicitly closed.
timeToLive: 1 hour

# If true, cookies will be persisted in memory for the duration
# of the client's lifetime. If false, cookies will be ignored
# entirely.
cookiesEnabled: false

# The maximum number of connections to be held in the client's
# connection pool.
maxConnections: 1024

# The maximum number of connections per "route" to be held in
# the client's connection pool. A route is essentially a
# combination of hostname, port, configured proxies, etc.
maxConnectionsPerRoute: 1024

# The default value for a persistent connection's keep-alive.
# A value of 0 will result in connections being immediately
# closed after a response.
keepAlive: 0s
10 changes: 9 additions & 1 deletion src/main/java/hyphenated/djbot/DjApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
import io.dropwizard.assets.AssetsBundle;
import io.dropwizard.auth.AuthFactory;
import io.dropwizard.auth.basic.BasicAuthFactory;
import io.dropwizard.client.HttpClientBuilder;
import io.dropwizard.setup.Bootstrap;
import io.dropwizard.setup.Environment;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;

import java.io.File;
import java.io.PrintStream;
Expand Down Expand Up @@ -44,11 +46,17 @@ public void initialize(Bootstrap<DjConfiguration> bootstrap) {
@Override
public void run(DjConfiguration configuration,
Environment environment) {
DjResource resource = new DjResource(configuration);

final HttpClient client = new HttpClientBuilder(environment).using(configuration.getHttpClientConfiguration())
.build("http-client");

DjResource resource = new DjResource(configuration, client);
environment.jersey().register(resource);

final ChannelCheck channelCheck = new ChannelCheck(resource);



if(configuration.isDjbotPublic()) {
String adminUsername = configuration.getAdminUsername();
String adminPassword = configuration.getAdminPassword();
Expand Down
37 changes: 37 additions & 0 deletions src/main/java/hyphenated/djbot/DjConfiguration.java
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
package hyphenated.djbot;

import com.fasterxml.jackson.annotation.JsonProperty;
import io.dropwizard.Configuration;
import io.dropwizard.client.HttpClientConfiguration;
import io.dropwizard.client.JerseyClientConfiguration;
import org.hibernate.validator.constraints.NotEmpty;

import javax.validation.Valid;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.List;
import java.util.Locale;

Expand Down Expand Up @@ -46,6 +51,14 @@ public class DjConfiguration extends Configuration {
private String adminUsername;
private String adminPassword;

private String twitchChatServerAssignmentUrl;
private String twitchIrcHost;

@Valid
@NotNull
@JsonProperty
private HttpClientConfiguration httpClient = new HttpClientConfiguration();


//this should be the channel name without the # at the front. (the same as the streamer's twitch account name)
public String getChannel() {
Expand Down Expand Up @@ -261,4 +274,28 @@ public String getAdminPassword() {
public void setAdminPassword(String adminPassword) {
this.adminPassword = adminPassword;
}

public String getTwitchChatServerAssignmentUrl() {
return twitchChatServerAssignmentUrl;
}

public void setTwitchChatServerAssignmentUrl(String twitchChatServerAssignmentUrl) {
this.twitchChatServerAssignmentUrl = twitchChatServerAssignmentUrl;
}

public String getTwitchIrcHost() {
return twitchIrcHost;
}

public void setTwitchIrcHost(String twitchIrcHost) {
this.twitchIrcHost = twitchIrcHost;
}

public HttpClientConfiguration getHttpClientConfiguration() {
return httpClient;
}

public void setHttpClient(JerseyClientConfiguration httpClient) {
this.httpClient = httpClient;
}
}
17 changes: 15 additions & 2 deletions src/main/java/hyphenated/djbot/DjIrcBot.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public class DjIrcBot extends PircBot {
private final DjConfiguration conf;

private final String channel;
private final String twitchHostName;
private final int twitchPort;

final String label_songrequest = "!songrequest";
final String label_sr = "!sr";
Expand All @@ -36,7 +38,7 @@ public class DjIrcBot extends PircBot {

private DjService dj;

public DjIrcBot(DjConfiguration conf) {
public DjIrcBot(DjConfiguration conf, String twitchIrcHost) {
this.conf = conf;
this.channel = "#" + conf.getChannel();
this.setMessageDelay(conf.getMessageDelayMs());
Expand All @@ -46,6 +48,17 @@ public DjIrcBot(DjConfiguration conf) {
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
String[] parts = twitchIrcHost.split(":");
if(parts.length != 2) {
throw new RuntimeException("Twitch irc host '" + twitchIrcHost + "' should have exactly one colon in it, for the port number");
}
twitchHostName = parts[0];
try {
twitchPort = Integer.parseInt(parts[1]);
} catch (NumberFormatException e) {
throw new RuntimeException("The port for the twitch irc host is '" + parts[1] + "', but that's not a valid port number");
}

}


Expand All @@ -65,7 +78,7 @@ private void tryConnect() {
}
while(!isConnected()) {
try {
this.connect("irc.twitch.tv", 6667, conf.getTwitchAccessToken());
this.connect(this.twitchHostName, this.twitchPort, conf.getTwitchAccessToken());
this.sendRawLine("CAP REQ :twitch.tv/membership");
this.joinChannel(channel);
} catch (Exception e) {
Expand Down
32 changes: 30 additions & 2 deletions src/main/java/hyphenated/djbot/DjResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@
import hyphenated.djbot.json.NextResponse;
import hyphenated.djbot.json.SongEntry;
import io.dropwizard.auth.Auth;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.json.JSONArray;
import org.json.JSONObject;

import javax.ws.rs.*;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
Expand All @@ -23,9 +29,19 @@ public class DjResource {
//use user tokens on auth-required endpoints to prevent csrf attack
private Map<String, User> tokenMap = new HashMap<>();

public DjResource(DjConfiguration conf) {
public DjResource(DjConfiguration conf, HttpClient httpClient) {
publicMode = conf.isDjbotPublic();
DjIrcBot irc = new DjIrcBot(conf);

String host = conf.getTwitchIrcHost();
if (StringUtils.isBlank(host)) {
try {
host = getIrcHostFromTwitch(conf, httpClient);
} catch (Exception e) {
throw new RuntimeException("Unable to get irc server host from twitch's api. Try setting 'twitchIrcHost' in options.yaml.", e);
}
}

DjIrcBot irc = new DjIrcBot(conf, host);
dj = new DjService(conf, irc);
irc.setDjService(dj);
irc.startup();
Expand All @@ -34,10 +50,22 @@ public DjResource(DjConfiguration conf) {
dj.nextSong();
}



public DjService getDj() {
return dj;
}

private String getIrcHostFromTwitch(DjConfiguration conf, HttpClient httpClient) throws Exception {
String twitchServerInfoUrl = conf.getTwitchChatServerAssignmentUrl().replace("%CHANNEL%", conf.getChannel());
HttpGet httpGet = new HttpGet(twitchServerInfoUrl);
InputStream resultStream = httpClient.execute(httpGet).getEntity().getContent();
String result = IOUtils.toString(resultStream);
JSONObject json = new JSONObject(result);
JSONArray servers = json.getJSONArray("servers");
return servers.getString(0);
}

private String wrapForJsonp(Object response, String callback) {
String objString = null;
if(response instanceof String) {
Expand Down

0 comments on commit 3e33342

Please sign in to comment.