Created
November 30, 2017 22:52
-
-
Save itsfolf/2be40e7aad30fdddd4b8679d10baff26 to your computer and use it in GitHub Desktop.
Discord spotify bridge
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package ga.olympiccode.vhack.api; | |
import net.arikia.dev.drpc.*; | |
import net.arikia.dev.drpc.callbacks.*; | |
import okhttp3.*; | |
import org.json.JSONObject; | |
import javax.imageio.ImageIO; | |
import javax.swing.*; | |
import java.awt.*; | |
import java.awt.event.ActionEvent; | |
import java.awt.event.ActionListener; | |
import java.awt.event.ItemEvent; | |
import java.awt.event.ItemListener; | |
import java.io.*; | |
import java.net.URL; | |
import java.nio.charset.Charset; | |
import java.util.Random; | |
import java.util.Timer; | |
import java.util.TimerTask; | |
import java.util.concurrent.TimeUnit; | |
public class idk { | |
static OkHttpClient.Builder builder = new OkHttpClient.Builder(); | |
static OkHttpClient client = builder.readTimeout(5, TimeUnit.SECONDS).connectTimeout(2, TimeUnit.MINUTES).build(); | |
static idk instance; | |
static boolean enabled = true; | |
public static void main(String[] args) { | |
idk idk = new idk(); | |
DiscordEventHandlers handlers = new DiscordEventHandlers(); | |
ReadyCallback readyCallback = new ReadyCallback() { | |
public void apply() { | |
System.out.println("Discord ready"); | |
schedule(); | |
} | |
}; | |
ErroredCallback erroredCallback = new ErroredCallback() { | |
public void apply(int i, String s) { | |
System.out.println("Errored: [" + i + "] " + s); | |
} | |
}; | |
DisconnectedCallback disconnectedCallback = new DisconnectedCallback() { | |
public void apply(int i, String s) { | |
System.out.println("Disconnected: [" + i + "] " + s); | |
} | |
}; | |
JoinGameCallback joinGameCallback = new JoinGameCallback() { | |
public void apply(String s) { | |
System.out.println("Join game: " + s); | |
} | |
}; | |
SpectateGameCallback spectateGameCallback = new SpectateGameCallback() { | |
public void apply(String s) { | |
System.out.println("Spectate game: " + s); | |
} | |
}; | |
JoinRequestCallback joinRequestCallback = new JoinRequestCallback() { | |
public void apply(DiscordJoinRequest discordJoinRequest) { | |
System.out.println("Join request:\nUsername:" + discordJoinRequest.username + "\nUserID:" + discordJoinRequest.userId + "\nAvatar:" + discordJoinRequest.avatar + "\n--"); | |
} | |
}; | |
handlers.ready = readyCallback; | |
handlers.errored = erroredCallback; | |
handlers.joinGame = joinGameCallback; | |
handlers.disconnected = disconnectedCallback; | |
handlers.spectateGame = spectateGameCallback; | |
handlers.joinRequest = joinRequestCallback; | |
DiscordRPC.DiscordInitialize("385898222595342336", handlers, true); | |
Runtime.getRuntime().addShutdownHook(new Thread() { | |
public void run() { | |
DiscordRPC.DiscordShutdown(); | |
System.out.println("Out"); | |
} | |
}); | |
ImageIcon image = null; | |
image = new ImageIcon("http://marilynscott.com/wp-content/uploads/2016/03/spotify-icon-22.png"); | |
final PopupMenu popup = new PopupMenu(); | |
Image iconimg = Toolkit.getDefaultToolkit().getImage("src/resources/discordify.gif"); | |
TrayIcon icon = new TrayIcon(idk.createImage("discordify.gif", "Discordify")); | |
icon.setImageAutoSize(true); | |
final SystemTray tray = SystemTray.getSystemTray(); | |
CheckboxMenuItem enable = new CheckboxMenuItem("Enable"); | |
MenuItem exitItem = new MenuItem("Exit"); | |
enable.setState(true); | |
popup.add(enable); | |
popup.add(exitItem); | |
icon.setPopupMenu(popup); | |
try { | |
tray.add(icon); | |
} catch (AWTException e) { | |
e.printStackTrace(); | |
} | |
enable.addItemListener(new ItemListener() { | |
public void itemStateChanged(ItemEvent e) { | |
int cb1Id = e.getStateChange(); | |
if (cb1Id == ItemEvent.SELECTED){ | |
enabled = true; | |
} else { | |
enabled = false; | |
} | |
} | |
}); | |
exitItem.addActionListener(new ActionListener() { | |
public void actionPerformed(ActionEvent e) { | |
System.exit(0); | |
} | |
}); | |
JFrame frame = new JFrame("Discordify"); | |
frame.show(); | |
frame.hide(); | |
new Timer().scheduleAtFixedRate(new TimerTask() { | |
public void run() { | |
DiscordRPC.DiscordRunCallbacks(); | |
} | |
}, 0, 1000); | |
} | |
static String song = ""; | |
static boolean playing = false; | |
public static void schedule() { | |
new Timer().scheduleAtFixedRate(new TimerTask() { | |
public void run() { | |
update(); | |
} | |
}, 0, 1000); | |
} | |
static String oauth2 = readJsonFromUrl("https://open.spotify.com/token").getString("t"); | |
static String csrf = readJsonFromUrl("http://127.0.0.1:4381/simplecsrf/token.json").getString("token"); | |
static long last = System.currentTimeMillis(); | |
public static void update() { | |
DiscordRPC.DiscordRunCallbacks(); | |
if (enabled) { | |
try { | |
/* HttpUrl url = new HttpUrl.Builder().scheme("http").host("127.0.0.1").port(4381).addPathSegments("remote/status.json") | |
.addQueryParameter("oauth", oauth2) | |
.addQueryParameter("csrf", csrf) | |
.addQueryParameter("returnafter", "59") | |
.addQueryParameter("returnon", "login,logout,play,pause,error,api").build(); | |
Response response = client.newCall(new Request.Builder() | |
.url(url) | |
.addHeader("Origin", "https://open.spotify.com") | |
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101 Firefox/19.0") | |
.build()).execute(); | |
response.close();*/ | |
InputStream is = new URL("http://127.0.0.1:4381/remote/status.json?csrf=" + csrf + "&oauth=" + oauth2).openStream(); | |
BufferedReader rd = new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8"))); | |
String jsonText = readAll(rd); | |
JSONObject object = new JSONObject(jsonText); | |
is.close(); | |
JSONObject track = object.getJSONObject("track"); | |
if (!track.getJSONObject("track_resource").getString("name").equals(song) || object.getBoolean("playing") != playing || last < System.currentTimeMillis() - 20000) { | |
last = System.currentTimeMillis(); | |
song = track.getJSONObject("track_resource").getString("name"); | |
playing = object.getBoolean("playing"); | |
// JSONObject object = new JSONObject(response.body().string()); | |
String state = (object.getBoolean("playing") ? "Playing" : "Paused"); | |
String name = "\uD83C\uDFB5 " + track.getJSONObject("track_resource").getString("name"); | |
int lenght = track.getInt("length"); | |
int current = object.getInt("playing_position"); | |
Random rand = new Random(); | |
long end = (long) (((System.currentTimeMillis() / 1000l) + (lenght - current)) + Math.random()); | |
long start = (System.currentTimeMillis() / 1000l) - current; | |
if (start == end) update(); | |
updatePresence(state, name, end, start); | |
} | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
} | |
} | |
public static void updatePresence(String state, String name, long stamp, long start) { | |
DiscordRichPresence presence = new DiscordRichPresence(); | |
System.out.println(stamp); | |
presence.state = state; | |
presence.details = name; | |
if (state != "Paused") { | |
presence.startTimestamp = start; | |
presence.endTimestamp = stamp; | |
} | |
presence.largeImageKey = "spotify"; | |
presence.smallImageKey = (state.equals("Playing") ? "playing" : "paused"); | |
presence.smallImageText = (state.equals("Playing") ? "Playing" : "Paused"); | |
DiscordRPC.DiscordUpdatePresence(presence); | |
} | |
public static JSONObject readJsonFromUrl(String urls) { | |
try { | |
URL url = new URL(urls); | |
Response response = client.newCall(new Request.Builder() | |
.url(urls) | |
.addHeader("Origin", "https://open.spotify.com") | |
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 5.1; rv:19.0) Gecko/20100101 Firefox/19.0") | |
.build()).execute(); | |
String jsonText = response.body().string(); | |
System.out.println(jsonText); | |
JSONObject json = new JSONObject(jsonText); | |
return json; | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
private static String readAll(Reader rd) throws IOException { | |
StringBuilder sb = new StringBuilder(); | |
int cp; | |
while ((cp = rd.read()) != -1) { | |
sb.append((char) cp); | |
} | |
return sb.toString(); | |
} | |
protected Image createImage(String path, String description) { | |
URL imageURL = getClass().getClassLoader().getResource("discordify.gif"); | |
Image image = null; | |
try { | |
image = ImageIO.read(new URL("https://i.imgur.com/MsYUIgm.png")); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
return (new ImageIcon(image, description)).getImage(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment