-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
87 lines (70 loc) · 2.53 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
const { program } = require('commander');
const Bot = require('./Bot')
const { Socket } = require("phoenix")
require('websocket-polyfill')
const DEFAULT_BASE_URL = "wss://jdis-ia.dinf.usherbrooke.ca/socket"
const MIN_TICKS_PER_SECOND = 3
const q = require('queue')({ autostart: true, concurrency: 1, timeout: 1000 / MIN_TICKS_PER_SECOND })
function getGameName(isRanked) {
if (isRanked) {
return 'main_game'
}
return 'secondary_game'
}
function handleError(e) {
console.error(e)
process.exit()
}
async function initializeChannel(socketEndpoint, socketOptions, channelTopic, backendUrl) {
return new Promise((resolve) => {
const url = `${backendUrl}/${socketEndpoint}`
const socket = new Socket(url, socketOptions)
socket.onError(handleError)
socket.connect()
const channel = socket.channel(channelTopic)
channel
.join()
.receive('ok', () => {
console.log(`Successfully joined channel ${channel.topic}`)
resolve(channel)
})
.receive('error', handleError)
.receive('timeout', handleError)
})
}
async function initializeActionChannel(secret, isRanked, backendUrl) {
const channel = await initializeChannel('bot', { params: { secret }}, `action:${getGameName(isRanked)}`, backendUrl)
channel.onError((reason) => {
console.error(`Channel encountered an error: ${JSON.stringify(reason)}`);
process.exit();
})
return channel
}
async function initializeGameStateChannel(isRanked, backendUrl) {
return await initializeChannel('spectate', { }, `game_state:${getGameName(isRanked)}`, backendUrl)
}
async function start({ secret, isRanked, backendUrl }) {
const [actionChannel, gameStateChannel] = await Promise.all([
initializeActionChannel(secret, isRanked, backendUrl),
initializeGameStateChannel(isRanked, backendUrl)
])
actionChannel.push("get_id").receive('ok', ({ id }) => {
const bot = new Bot(id)
gameStateChannel.on('new_state', (state) => {
if (q.length > 0) {
q.shift(0, q.length - 1)
}
q.push(() => {
const action = bot.tick(state)
actionChannel.push("new", action)
})
})
})
}
program
.requiredOption('-s, --secret <secret>', 'The secret which authenticates your bot')
.option('-r, --no-ranked', 'Connects to the secondary game instead of the ranked one')
.option('-u, --backend_url <url>', 'The url of the backend server', DEFAULT_BASE_URL)
program.parse()
const options = program.opts()
start({ secret: options.secret, isRanked: options.ranked, backendUrl: options.backend_url })