Last active
August 17, 2019 20:03
-
-
Save faogustavo/9285969f5a200e0f9007bad2f13547bb to your computer and use it in GitHub Desktop.
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
<html> | |
<script type="text/javascript"> | |
const KEY_START = "CURRENT_STATE" | |
const KEY_AUTH = "AUTHENTICATE" | |
const KEY_PAINT = "PAINT" | |
const KEY_MY_ID = "e4bd5af89ee5f4ed" | |
const isMine = (data) => data.painterId == KEY_MY_ID | |
const log = (className = "", message, complement) => { | |
const date = new Date() | |
const hour = prettyfyNumber(date.getHours()) | |
const minute = prettyfyNumber(date.getMinutes()) | |
const seconds = prettyfyNumber(date.getSeconds()) | |
const newChild = document.createElement("p") | |
newChild.className = className | |
newChild.innerHTML = `[${hour}:${minute}:${seconds}] ${message} ${complement}` | |
const container = document.getElementById("output") | |
container.insertBefore(newChild, container.firstChild) | |
} | |
const prettyfyNumber = (number) => { | |
if (+number < 10) { | |
return `0${number}` | |
} else { | |
return number | |
} | |
} | |
console.log = (message, complement) => { | |
log("", message, complement || "") | |
} | |
console.warn = (message, complement) => { | |
log('warn', message, complement || "") | |
} | |
console.error = (message, complement) => { | |
log('error', message, complement || "") | |
} | |
const seconds = (val) => (+val) * 1000 | |
const getAction = (data) => { | |
try { | |
const finalData = data.split(/ /) | |
return { | |
action: finalData[0], | |
data: JSON.parse(finalData[1]) | |
} | |
} catch (e) { | |
return null | |
} | |
} | |
const makeAction = (data) => [ data.action, JSON.stringify(data.data) ].join(" ") | |
const updateScore = (board) => { | |
const myItems = board.filter(isMine).length | |
const missingItems = board.length - myItems | |
document.getElementById("mine").innerHTML = `${myItems}` | |
document.getElementById("missing").innerHTML = `${missingItems}` | |
const count = board.reduce((acc, item) => { | |
return { | |
...acc, | |
[item.painterId]:(acc[item.painterId] || 0) + 1 | |
} | |
}, {}) | |
const sortedCount = Object.keys(count) | |
.map((key) => ([key, count[key]])) | |
.sort((a, b) => b[1] - a[1]) | |
.map((item) => `<ul>${item.join(" - ")}</ul>`) | |
.slice(0, 5) | |
document.getElementById("ranking").innerHTML = sortedCount.join("") | |
} | |
const start = (appUrl) => { | |
console.log("trying to connect") | |
document.cookie = "SESSION=id%3D%2523s85f8219c5c909169; path=/" | |
let rows = 0 | |
let columns = 0 | |
let board = [] | |
let auth = false | |
let lastPaintedPosition = [-1, -1] | |
let mineIsScheduled = false | |
const ws = new WebSocket(appUrl) | |
const send = (message) => { | |
console.log("Sending -> ", message) | |
ws.send(message) | |
} | |
ws.onclose = () => { | |
console.log("The connection was closed. ") | |
console.log("Reconnecting in 5 seconds..") | |
setTimeout(() => { | |
start(appUrl) | |
}, seconds(5)) | |
} | |
ws.onopen = () => { | |
document.getElementById("btn").remove() | |
console.log('Service started') | |
const sendColor = ({ row, col, hexColor }) => { | |
const finalRow = row || parseInt(Math.random() * rows) | |
const finalCol = col || parseInt(Math.random() * columns) | |
const finalHexColor = hexColor || "#999999" | |
lastPaintedPosition = [ row, col ] | |
send(makeAction({ | |
action: KEY_PAINT, | |
data: { | |
row: finalRow, | |
col: finalCol, | |
hexColor: finalHexColor | |
} | |
})) | |
} | |
const findSquareToPaint = () => { | |
const othersSquares = board.filter((item) => !item.isMine) | |
if (othersSquares.length == 0) { | |
console.log("No more squares to paint. Waiting new changes.") | |
return | |
} | |
sendColor(othersSquares[parseInt(Math.random() * othersSquares.length)]) | |
} | |
const indexOfItem = (col, row) => board.findIndex((item) => item.col == col && item.row == row) | |
const markItem = (data) => { | |
const index = indexOfItem(data.col, data.row) | |
board[index] = { | |
...board[index], | |
hexColor: `#${data.color}` | |
} | |
updateScore(board) | |
} | |
const normalizeSquare = (item) => ({ | |
row: item.row, | |
col: item.col, | |
painterId: item.painterId, | |
hexColor: `#${item.color}` | |
}) | |
const scheduleNext = () => { | |
mineIsScheduled = true | |
setTimeout(() => { | |
mineIsScheduled = false | |
findSquareToPaint() | |
}, seconds(12)) | |
} | |
const keepAliveBot = () => { | |
setTimeout(() => { | |
if (!mineIsScheduled) { | |
findSquareToPaint() | |
} | |
keepAliveBot() | |
}, 30000); | |
} | |
const onConnect = (data) => { | |
rows = data.rowsCount | |
columns = data.colsCount | |
board = data.cells.map(normalizeSquare) | |
updateScore(board) | |
send(makeAction({ | |
action: KEY_AUTH, | |
data: { | |
name: "" | |
} | |
})) | |
} | |
const onAuth = (data) => { | |
if (data.success) { | |
findSquareToPaint() | |
} else { | |
console.log("You were not able to authenticate"); | |
ws.close() | |
} | |
} | |
const onPaint = (data) => { | |
markItem(data) | |
if (isMine(data)) { | |
lastPaintedPosition = [-1, -1] | |
scheduleNext() | |
} else { | |
if (!mineIsScheduled) scheduleNext() | |
} | |
} | |
ws.onmessage = (data) => { | |
const action = getAction(data.data) | |
if (!action) return | |
if (action.action != KEY_START) { | |
console.log("Received Action", JSON.stringify(action)) | |
} | |
switch(action.action) { | |
case KEY_START: | |
onConnect(action.data.data) | |
break | |
case KEY_AUTH: | |
onAuth(action.data) | |
break | |
case KEY_PAINT: | |
onPaint(action.data.data) | |
break | |
} | |
} | |
} | |
} | |
const appStart = () => start("wss://kotlin-kolors.herokuapp.com:443/interact/") | |
</script> | |
<style> | |
.error { color: red; } | |
.warn { color: darkgoldenrod; } | |
#header { | |
position: absolute; | |
top: 0; | |
font-size: 48px; | |
} | |
ul { font-size: 20px; } | |
#output { | |
margin-top: 400px; | |
} | |
</style> | |
<body> | |
<div id="header"> | |
<p>My items <span id="mine">0</span> </p> | |
<p>Missing items <span id="missing">0</span> </p> | |
<ul id="ranking"></ul> | |
<button onclick="javascript:appStart()" id="btn">Run We socket</button> | |
</div> | |
<div id="output" /> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment