Initial Commit
Initial Commit
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
|
||||
import request from 'request';
|
||||
import WebSocket from 'ws';
|
||||
|
||||
export default class Account {
|
||||
constructor({
|
||||
accessToken,
|
||||
admin,
|
||||
authToken,
|
||||
avatarUrl,
|
||||
guest,
|
||||
loginToken,
|
||||
userId,
|
||||
username,
|
||||
tester,
|
||||
}) {
|
||||
this.accessToken = accessToken;
|
||||
this.admin = admin;
|
||||
this.authToken = authToken;
|
||||
this.avatarUrl = avatarUrl;
|
||||
this.guest = guest;
|
||||
this.loginToken = loginToken;
|
||||
this.userId = userId;
|
||||
this.username = username;
|
||||
this.tester = tester;
|
||||
this.broadcastId = null;
|
||||
this.socket = null;
|
||||
this.lastAnswerId = null;
|
||||
}
|
||||
|
||||
activate(broadcastId, socket) {
|
||||
this.broadcastId = broadcastId;
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
sendAnswer(questionId, answerId) {
|
||||
const answerPackage = {
|
||||
type: 'answer',
|
||||
broadcastId: this.broadcastId,
|
||||
questionId,
|
||||
answerId,
|
||||
};
|
||||
this.lastAnswerId = answerId;
|
||||
this.socket.send(JSON.stringify(answerPackage));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
export default class HQSchedule {
|
||||
constructor({
|
||||
active,
|
||||
atCapacity,
|
||||
showId,
|
||||
showType,
|
||||
startTime,
|
||||
nextShowTime,
|
||||
nextShowPrize,
|
||||
upcoming,
|
||||
prize,
|
||||
broadcast,
|
||||
gameKey,
|
||||
broadcastFull,
|
||||
}) {
|
||||
this.active = active;
|
||||
this.atCapacity = atCapacity;
|
||||
this.showId = showId;
|
||||
this.showType = showType;
|
||||
this.startTime = startTime;
|
||||
this.nextShowTime = nextShowTime;
|
||||
this.nextShowPrize = nextShowPrize;
|
||||
this.upcoming = upcoming;
|
||||
this.prize = prize;
|
||||
this.broadcast = broadcast;
|
||||
this.gameKey = gameKey;
|
||||
this.broadcastFull = broadcastFull;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
import https from 'https';
|
||||
import Account from './Account';
|
||||
|
||||
const HOST = 'api-quiz.hype.space';
|
||||
const headers = {
|
||||
'x-hq-client': 'Android/1.6.2',
|
||||
'content-type': 'application/json; charset=UTF-8',
|
||||
'user-agent': 'okhttp/3.8.0',
|
||||
};
|
||||
|
||||
export default class Verification {
|
||||
constructor({
|
||||
callsEnabled,
|
||||
expires,
|
||||
phone,
|
||||
retrySeconds,
|
||||
verificationId,
|
||||
}) {
|
||||
this.callsEnabled = callsEnabled;
|
||||
this.expires = expires;
|
||||
this.phone = phone;
|
||||
this.retrySeconds = retrySeconds;
|
||||
this.verificationId = verificationId;
|
||||
}
|
||||
|
||||
/*
|
||||
* confirm(string code)
|
||||
*
|
||||
* Confirmed phone number (sms code) and returns an authentication token.
|
||||
*
|
||||
*/
|
||||
confirm(code, callback) {
|
||||
let account;
|
||||
let error;
|
||||
|
||||
const body = {
|
||||
code,
|
||||
};
|
||||
|
||||
const options = {
|
||||
host: HOST,
|
||||
path: '/verifications/' + this.verificationId,
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...headers,
|
||||
'content-length': JSON.stringify(body).length,
|
||||
},
|
||||
};
|
||||
|
||||
const req = https.request(options, (res, err) => {
|
||||
if (err) {
|
||||
return { response: null, error: err };
|
||||
}
|
||||
|
||||
res.on('data', (data) => {
|
||||
account = JSON.parse(data);
|
||||
console.log('account data', account);
|
||||
|
||||
if (!account.accessToken) {
|
||||
if (account.error) {
|
||||
error = account.error;
|
||||
} else {
|
||||
error = data;
|
||||
}
|
||||
} else {
|
||||
account = new Account(account);
|
||||
}
|
||||
|
||||
callback({ response: account, error });
|
||||
});
|
||||
});
|
||||
|
||||
req.write(JSON.stringify(body));
|
||||
req.end();
|
||||
}
|
||||
|
||||
/*
|
||||
* create(Verification verification, string username, string referrer, string region)
|
||||
*
|
||||
* Creates a new user and returns its account info.
|
||||
*
|
||||
* Account: {
|
||||
* userId,
|
||||
* username,
|
||||
* admin,
|
||||
* tester,
|
||||
* guest,
|
||||
* avatarUrl,
|
||||
* loginToken,
|
||||
* accessToken,
|
||||
* authToken,
|
||||
* };
|
||||
*
|
||||
*/
|
||||
create(username, referrer, callback) {
|
||||
let account;
|
||||
let error;
|
||||
|
||||
const body = {
|
||||
country: 'US',
|
||||
language: 'en',
|
||||
referringUsername: referrer,
|
||||
username,
|
||||
verificationId: this.verificationId,
|
||||
};
|
||||
|
||||
const options = {
|
||||
host: HOST,
|
||||
path: '/users',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...headers,
|
||||
'content-length': JSON.stringify(body).length,
|
||||
},
|
||||
};
|
||||
|
||||
const req = https.request(options, (res, err) => {
|
||||
if (err) {
|
||||
return { response: null, error: err };
|
||||
}
|
||||
|
||||
res.on('data', (data) => {
|
||||
account = JSON.parse(data);
|
||||
|
||||
if (!account.accessToken) {
|
||||
if (account.error) {
|
||||
error = account.error;
|
||||
} else {
|
||||
error = data;
|
||||
}
|
||||
account = null;
|
||||
} else {
|
||||
account = new Account(account);
|
||||
}
|
||||
|
||||
callback({ response: account, error });
|
||||
});
|
||||
});
|
||||
|
||||
req.write(JSON.stringify(body));
|
||||
req.end();
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"mainBearerToken": "yourMainAccessToken",
|
||||
"players": [
|
||||
{
|
||||
"accessToken": "accessToken1",
|
||||
"admin": false,
|
||||
"authToken": "authToken1",
|
||||
"avatarUrl": "https://d2xu1hdomh3nrx.cloudfront.net/default_avatars/Untitled-1_0003_red.png",
|
||||
"guest": false,
|
||||
"loginToken": "loginToken1",
|
||||
"userId": 123456,
|
||||
"username": "username1",
|
||||
"tester": false
|
||||
},
|
||||
{
|
||||
"accessToken": "accessToken2",
|
||||
"admin": false,
|
||||
"authToken": "authToken2",
|
||||
"avatarUrl": "https://d2xu1hdomh3nrx.cloudfront.net/default_avatars/Untitled-1_0003_red.png",
|
||||
"guest": false,
|
||||
"loginToken": "loginToken2",
|
||||
"userId": 123457,
|
||||
"username": "username2",
|
||||
"tester": false
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
import https from 'https';
|
||||
import prompt from 'prompt';
|
||||
import Moniker from 'moniker';
|
||||
|
||||
import { mainBearerToken } from './config.json';
|
||||
import Account from './classes/Account';
|
||||
import HQSchedule from './classes/HQSchedule';
|
||||
import Verification from './classes/Verification';
|
||||
|
||||
const HOST = 'api-quiz.hype.space';
|
||||
const INIT_TOKEN = mainBearerToken;
|
||||
const headers = {
|
||||
'x-hq-client': 'Android/1.6.2',
|
||||
'content-type': 'application/json; charset=UTF-8',
|
||||
'user-agent': 'okhttp/3.8.0',
|
||||
};
|
||||
|
||||
const verify = (number, callback) => {
|
||||
let verification;
|
||||
let error;
|
||||
|
||||
const body = {
|
||||
method: 'sms',
|
||||
phone: number,
|
||||
};
|
||||
|
||||
const options = {
|
||||
host: HOST,
|
||||
path: '/verifications',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...headers,
|
||||
'content-length': JSON.stringify(body).length,
|
||||
},
|
||||
};
|
||||
|
||||
const req = https.request(options, (res, err) => {
|
||||
if (err) {
|
||||
console.log(`Error occured verifying ${number}:`, err);
|
||||
return { response: null, error: err };
|
||||
}
|
||||
|
||||
res.on('data', (data) => {
|
||||
verification = JSON.parse(data);
|
||||
|
||||
if (!verification.verificationId) {
|
||||
if (verification.error) {
|
||||
error = verification.error;
|
||||
} else {
|
||||
error = data;
|
||||
}
|
||||
} else {
|
||||
verification = new Verification(verification);
|
||||
}
|
||||
|
||||
callback({ response: verification, error });
|
||||
});
|
||||
});
|
||||
|
||||
req.write(JSON.stringify(body));
|
||||
req.end();
|
||||
};
|
||||
|
||||
const connect = (broadcastId, callback) => {
|
||||
let verification;
|
||||
let error;
|
||||
|
||||
const body = {
|
||||
method: 'sms',
|
||||
phone: number,
|
||||
};
|
||||
|
||||
const options = {
|
||||
host: HOST,
|
||||
path: '/verifications',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
...headers,
|
||||
'content-length': JSON.stringify(body).length,
|
||||
},
|
||||
};
|
||||
|
||||
const req = https.request(options, (res, err) => {
|
||||
if (err) {
|
||||
console.log(`Error occured verifying ${number}:`, err);
|
||||
return { response: null, error: err };
|
||||
}
|
||||
|
||||
res.on('data', (data) => {
|
||||
verification = JSON.parse(data);
|
||||
|
||||
if (!verification.verificationId) {
|
||||
if (verification.error) {
|
||||
error = verification.error;
|
||||
} else {
|
||||
error = data;
|
||||
}
|
||||
} else {
|
||||
verification = new Verification(verification);
|
||||
}
|
||||
|
||||
callback({ response: verification, error });
|
||||
});
|
||||
});
|
||||
|
||||
req.write(JSON.stringify(body));
|
||||
req.end();
|
||||
};
|
||||
|
||||
const getSchedule = (callback) => {
|
||||
let schedule;
|
||||
let error;
|
||||
|
||||
const options = {
|
||||
host: HOST,
|
||||
path: '/shows/now?type=hq',
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'authorization': `Bearer ${INIT_TOKEN}`,
|
||||
},
|
||||
};
|
||||
|
||||
const req = https.request(options, (res, err) => {
|
||||
if (err) {
|
||||
console.log(`Error occured getting game schedule:`, err);
|
||||
return { response: null, error: err };
|
||||
}
|
||||
|
||||
res.on('data', (data) => {
|
||||
schedule = JSON.parse(data);
|
||||
|
||||
if (!schedule) {
|
||||
if (schedule.error) {
|
||||
error = schedule.error;
|
||||
} else {
|
||||
error = data;
|
||||
}
|
||||
} else {
|
||||
schedule = new HQSchedule(schedule);
|
||||
}
|
||||
|
||||
callback({ response: schedule, error });
|
||||
});
|
||||
});
|
||||
|
||||
req.write(JSON.stringify({}));
|
||||
req.end();
|
||||
}
|
||||
|
||||
const names = Moniker.generator([Moniker.adjective, Moniker.noun], { glue: 'a', maxSize: 4 });
|
||||
const newUser = `${names.choose()}${Number.parseInt(Math.random()*100)}`;
|
||||
console.log('Creating user:', newUser);
|
||||
|
||||
prompt.start();
|
||||
prompt.get(['number', 'referral'], (err, res) => {
|
||||
const referral = res.referral;
|
||||
console.log('Verifying with referral: ', res.number, referral);
|
||||
verify(`+1${res.number}`, (result) => {
|
||||
if (result.response) {
|
||||
const verification = result.response;
|
||||
console.log('Verified phone number with result:', verification);
|
||||
prompt.start();
|
||||
prompt.get(['code'], (err, res) => {
|
||||
verification.confirm(res.code, (confirmResult) => {
|
||||
if (confirmResult.response) {
|
||||
const auth = confirmResult.response;
|
||||
if (!auth.auth) {
|
||||
verification.create(newUser, referral, (createResult) => {
|
||||
console.log('createResult', createResult);
|
||||
if (createResult.response) {
|
||||
const account = createResult.response;
|
||||
console.log('Creation result:', account);
|
||||
} else if (createResult.error) console.log('Error creating account:', createResult.error);
|
||||
});
|
||||
} else {
|
||||
console.log('This account already exists?', auth);
|
||||
}
|
||||
} else if (confirmResult.error) console.log('Error confirming code:', confirmResult.error);
|
||||
});
|
||||
});
|
||||
} else if (result.error) console.log('Error verifying phone:', result.error);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,117 @@
|
||||
import request from 'request';
|
||||
import WebSocket from 'ws';
|
||||
|
||||
import { mainBearerToken, players } from './config.json';
|
||||
import Account from './classes/Account';
|
||||
|
||||
const HOST = 'api-quiz.hype.space';
|
||||
const INIT_TOKEN = mainBearerToken;
|
||||
const headers = {
|
||||
'x-hq-client': 'Android/1.6.2',
|
||||
'content-type': 'application/json; charset=UTF-8',
|
||||
'user-agent': 'okhttp/3.8.0',
|
||||
};
|
||||
|
||||
let playersInGame = players.map((player) => new Account(player));
|
||||
|
||||
const removePlayer = (userId) => {
|
||||
playersInGame = players.filter((player) => player.userId !== userId);
|
||||
}
|
||||
|
||||
request('https://api-quiz.hype.space/shows/now', (error, response, body) => {
|
||||
const result = JSON.parse(body);
|
||||
|
||||
if (!result.active) {
|
||||
console.log('Game Not Active; Using debug server instead...');
|
||||
}
|
||||
const { broadcastId = 44433, socketUrl = 'wss://hqecho.herokuapp.com/' } = result.broadcast || {};
|
||||
const options = {
|
||||
headers: {
|
||||
Authorization: `Bearer ${INIT_TOKEN}`,
|
||||
},
|
||||
};
|
||||
const ws = new WebSocket(socketUrl, options);
|
||||
|
||||
ws.on('open', () => {
|
||||
console.log('Master connected to websocket');
|
||||
playersInGame.forEach((player) => {
|
||||
const playerOptions = {
|
||||
headers: {
|
||||
Authorization: `Bearer ${player.accessToken}`,
|
||||
},
|
||||
};
|
||||
const pws = new WebSocket(socketUrl, playerOptions);
|
||||
pws.on('open', () => {
|
||||
console.log(`Player ${player.username} has connected to websocket`);
|
||||
pws.send(JSON.stringify({ type:'subscribe', broadcastId }), () => {
|
||||
console.log(`\tPlayer ${player.username} has subscribed to game`);
|
||||
player.activate(broadcastId, pws);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
ws.on('message', (data) => {
|
||||
const { answers = [], type = null } = JSON.parse(data);
|
||||
|
||||
// check if data type is a question not just like chat messages
|
||||
if (type === 'questionFinished') {
|
||||
console.log(`You have ${playersInGame.length} players still in game.`);
|
||||
}
|
||||
if (type === 'questionSummary') {
|
||||
const questionSummary = JSON.parse(data);
|
||||
const correctAnswer = questionSummary.answerCounts.filter(answer => answer.correct).answerId;
|
||||
|
||||
playersInGame.forEach((player) => {
|
||||
if (player.lastAnswerId !== correctAnswer) {
|
||||
console.log(`Player ${player.username} has been eliminated.`);
|
||||
removePlayer(player.userId);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (type !== 'question') return;
|
||||
const { questionNumber, question: theQuestion, questionId } = JSON.parse(data);
|
||||
|
||||
console.log(`Question #${questionNumber}: ${theQuestion}`);
|
||||
console.log(`Choice 1: ${answers[0].text}`);
|
||||
console.log(`Choice 2: ${answers[1].text}`);
|
||||
console.log(`Choice 3: ${answers[2].text}`);
|
||||
|
||||
prompt.start();
|
||||
prompt.get(['answer'], (err, res) => {
|
||||
const input = res.answer.split(',');
|
||||
switch (input.length) {
|
||||
case 1:
|
||||
playersInGame.forEach((player, index) => {
|
||||
console.log(`Player ${player.username} sent answer ${input[0]}`);
|
||||
const callback = (correct) => {
|
||||
if (!correct) playersInGame.splice(index, 1);
|
||||
};
|
||||
player.sendAnswer(questionId, answers[input[0] - 1].answerId);
|
||||
});
|
||||
break;
|
||||
case 2:
|
||||
playersInGame.forEach((player, index) => {
|
||||
console.log(`Player ${player.username} sent answer ${input[index % 2]}`);
|
||||
const callback = (correct) => {
|
||||
if (!correct) playersInGame.splice(index, 1);
|
||||
};
|
||||
player.sendAnswer(questionId, answers[input[index % 2] - 1].answerId)
|
||||
});
|
||||
break;
|
||||
case 3:
|
||||
playersInGame.forEach((player, index) => {
|
||||
console.log(`Player ${player.username} sent answer ${input[index % 3]}`);
|
||||
const callback = (correct) => {
|
||||
if (!correct) playersInGame.splice(index, 1);
|
||||
};
|
||||
player.sendAnswer(questionId, answers[input[index % 3] - 1].answerId)
|
||||
});
|
||||
break;
|
||||
default:
|
||||
console.log('ERROR: you sent too many answer choices');
|
||||
break;
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "hqbot",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "hqnode.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1",
|
||||
"start": "babel-node hqnode.js --presets env,es2016,stage-2",
|
||||
"create": "babel-node createAccount.js --presets env,es2016,stage-2"
|
||||
},
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"devDependencies": {
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"babel-preset-es2016": "^6.24.1",
|
||||
"babel-preset-stage-2": "^6.24.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"http": "0.0.0",
|
||||
"https": "^1.0.0",
|
||||
"moniker": "^0.1.2",
|
||||
"prompt": "^1.0.0",
|
||||
"request": "^2.87.0",
|
||||
"ws": "^5.2.1"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user