diff --git a/assets/osu!nppp.svg b/assets/osu!nppp.svg
new file mode 100644
index 0000000..0848958
--- /dev/null
+++ b/assets/osu!nppp.svg
@@ -0,0 +1,173 @@
+
+
+
+
diff --git a/auth.js b/auth.js
new file mode 100644
index 0000000..5ec95a0
--- /dev/null
+++ b/auth.js
@@ -0,0 +1,64 @@
+const CLIENT_ID = 'dl6k4oj0aiuyymn19opsclt6xyykbc';
+const OAUTH_TOKEN = window.location.hash.split('access_token=')[1] ? window.location.hash.split('access_token=')[1].split('&')[0] : "";
+
+var BOT_USER_ID; // This is the User ID of the chat bot
+var CHAT_CHANNEL_USER_ID; // This is the User ID of the channel that the bot will join and listen to chat messages of
+
+async function getAuth(token) {
+ // https://dev.twitch.tv/docs/authentication/validate-tokens/#how-to-validate-a-token
+ let response = await fetch('https://id.twitch.tv/oauth2/validate', {
+ method: 'GET',
+ headers: {
+ 'Authorization': 'OAuth ' + OAUTH_TOKEN
+ }
+ });
+
+ if (response.status != 200) {
+ let data = await response.json();
+ throw new Error("Token is not valid. /oauth2/validate returned status code " + response.status);
+ };
+
+ console.log("Validated token.");
+};
+
+async function getUserId() {
+ const response = await fetch(`https://api.twitch.tv/helix/users?login=${document.getElementById("username").value}`, {
+ method: 'GET',
+ headers: {
+ 'Client-Id': CLIENT_ID,
+ 'Authorization': 'Bearer ' + OAUTH_TOKEN
+ }
+ });
+
+ let data = await response.json();
+ if (response.status == 401) {
+ throw new Error("No OAuth token provided");
+ };
+ try {
+ CHAT_CHANNEL_USER_ID = data.data[0].id;
+ console.log("Channel ID: ", CHAT_CHANNEL_USER_ID);
+ } catch (error) {
+ throw new Error("Invalid username, " + error);
+ };
+};
+
+async function getBotId() {
+ const response = await fetch('https://api.twitch.tv/helix/users', {
+ method: 'GET',
+ headers: {
+ 'Client-Id': CLIENT_ID,
+ 'Authorization': 'Bearer ' + OAUTH_TOKEN
+ }
+ });
+
+ let data = await response.json();
+ if (response.status == 401) {
+ throw new Error("No OAuth token provided");
+ }
+ try {
+ BOT_USER_ID = data.data[0].id;
+ console.log("Bot ID: ", BOT_USER_ID);
+ } catch (error) {
+ throw new Error(error);
+ };
+};
\ No newline at end of file
diff --git a/bot.js b/bot.js
deleted file mode 100644
index 3c07039..0000000
--- a/bot.js
+++ /dev/null
@@ -1,340 +0,0 @@
-const CLIENT_ID = 'dl6k4oj0aiuyymn19opsclt6xyykbc';
-
-var BOT_USER_ID; // This is the User ID of the chat bot
-var CHAT_CHANNEL_USER_ID; // This is the User ID of the channel that the bot will join and listen to chat messages of
-
-function verifyUrl() {
- let hash;
- try {
- hash = window.location.hash.split('access_token=')[1].split('&')[0];
- } catch (error) {
- hash = ""
- }
- return hash;
-}
-
-const OAUTH_TOKEN = verifyUrl();
-
-document.getElementById("token").value = OAUTH_TOKEN;
-console.log("OAuth Token: ", OAUTH_TOKEN);
-
-const EVENTSUB_WEBSOCKET_URL = 'wss://eventsub.wss.twitch.tv/ws';
-var websocketClient;
-var websocketSessionID;
-var timeThen;
-
-// Start executing the bot from here
-function connectBot() {
- document.getElementById("token").disabled = true;
- document.getElementById("authorize").disabled = true;
- document.getElementById("username").disabled = true;
- document.getElementById("connect").disabled = true;
- document.getElementById("connect").innerHTML = "Connecting";
- if (OAUTH_TOKEN) {
- (async () => {
- // Verify that the authentication is valid
- await getAuth();
- await getUserId();
- await getBotId();
-
- // Start WebSocket client and register handlers
- startWebSocketClient();
- })();
- } else {
- console.error("No token provided")
- disconnectBot();
- }
-
- // WebSocket will persist the application loop until you exit the program forcefully
-
- async function getUserId() {
- const response = await fetch(`https://api.twitch.tv/helix/users?login=${document.getElementById("username").value}`, {
- method: 'GET',
- headers: {
- 'Client-Id': CLIENT_ID,
- 'Authorization': 'Bearer ' + OAUTH_TOKEN
- }
- });
-
- let data = await response.json();
- if (response.status == 401) {
- console.error("No OAuth token provided");
- disconnectBot();
- };
- try {
- CHAT_CHANNEL_USER_ID = data.data[0].id;
- console.log("Channel ID: ", CHAT_CHANNEL_USER_ID);
- } catch (error) {
- console.error("Invalid username, " + error);
- disconnectBot();
- };
- };
-
- async function getBotId() {
- const response = await fetch('https://api.twitch.tv/helix/users', {
- method: 'GET',
- headers: {
- 'Client-Id': CLIENT_ID,
- 'Authorization': 'Bearer ' + OAUTH_TOKEN
- }
- });
-
- let data = await response.json();
- if (response.status == 401) {
- console.error("No OAuth token provided");
- disconnectBot();
- }
- try {
- BOT_USER_ID = data.data[0].id;
- console.log("Bot ID: ", BOT_USER_ID);
- } catch (error) {
- console.error(error);
- disconnectBot();
- }
- }
-
- async function getAuth(token) {
- // https://dev.twitch.tv/docs/authentication/validate-tokens/#how-to-validate-a-token
- let response = await fetch('https://id.twitch.tv/oauth2/validate', {
- method: 'GET',
- headers: {
- 'Authorization': 'OAuth ' + OAUTH_TOKEN
- }
- });
-
- if (response.status != 200) {
- let data = await response.json();
- console.error("Token is not valid. /oauth2/validate returned status code " + response.status);
- console.error(data);
- disconnectBot();
- }
-
- console.log("Validated token.");
- }
-
- function startWebSocketClient() {
- websocketClient = new WebSocket(EVENTSUB_WEBSOCKET_URL);
-
- websocketClient.onerror = (console.error);
-
- websocketClient.onopen = () => {
- console.log('WebSocket connection opened to ' + EVENTSUB_WEBSOCKET_URL);
- };
-
- websocketClient.onmessage = (data) => {
- console.log(data);
- try {
- handleWebSocketMessage(JSON.parse(data.data.toString()));
- } catch (error) {
- console.error("yo error")
- console.error(data.toString());
- }
- };
- }
-
- async function fetchData(type) {
- try {
- const url = "http://127.0.0.1:24050/json/v2"
- const response = await fetch(url)
-
- if (!response.ok) {
- throw new Error('it brokey', response.status);
- }
-
- const data = await response.json();
- const beatmap = await data.beatmap;
- const play = await data.play;
- const state = await data.state;
- const profile = await data.profile;
-
- switch (type) {
- case ("mode"):
- let mode = beatmap.mode.number
- if (beatmap.mode.number == 0) {
- mode = profile.mode.number;
- }
- return mode;
- break;
- case ("map"):
- let modsName = "";
- if (play.mods.name) {
- modsName = ` +${play.mods.name}`
- }
- let id = "(private map)";
- if (beatmap.id) {
- id = `osu.ppy.sh/b/${beatmap.id}`
- }
- let modeName = ""
- let modeNumber = beatmap.mode.number
- if (beatmap.mode.number == 0) {
- modeNumber = profile.mode.number;
- }
- switch (modeNumber) {
- case 0:
- modeName = ""
- break;
- case 1:
- modeName = "
- format: artist - title [difficulty] (mapper) <mode>* | osu.ppy.sh/b/beatmapid | ###pp** / 100%: ###pp, 99%: ###pp, 98%: ###pp, 95%: ###pp, 90%: ###pp
@@ -31,5 +32,9 @@ osu!nppp - osu! twitch bot
+ format: artist - title [difficulty] (mapper) <mode>* +mods** | osu.ppy.sh/b/beatmapid | ###pp*** / 100%: ###pp, 99%: ###pp, 98%: ###pp, 95%: ###pp, 90%: ###pp
- *only appears when not osu!standard
- **only appears when playing a map (not song select)
+ *Mode is only visible if it is not osu!standard.
+ **Mods are only visible if any are selected.
+ ***Current pp, only visible if the player is currently playing a map.
tosu must be running for this to work