Update script.sh for new host.
Disable !lotr and !lotrOld Re-enable API and make some tweaks to clean up responses Move saveDir to /hvacker-saves Disable API rate limit
This commit is contained in:
parent
f5277ae9de
commit
edfea51bfa
|
@ -2,11 +2,13 @@
|
||||||
export NVM_DIR="$HOME/.nvm"
|
export NVM_DIR="$HOME/.nvm"
|
||||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
|
||||||
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion" # This loads nvm bash_completion
|
||||||
cd /home/sagevaillancourt/git/hvacker
|
cd /home/sage/projects/hvacker || exit 1
|
||||||
whereis npm
|
whereis npm
|
||||||
npm start | while read line; do
|
npm start | while read line; do
|
||||||
echo "$line"
|
echo "$line"
|
||||||
if [[ "$line" == *"app http request failed getaddrinfo ENOTFOUND slack.com"* ]]; then
|
if [[ "$line" == *"app http request failed getaddrinfo ENOTFOUND slack.com"* ]] ||
|
||||||
|
[[ "$line" == *"node:internal/errors"* ]] ||
|
||||||
|
[[ "$line" == *"Cannot set headers after"* ]]; then
|
||||||
systemctl restart hvacker
|
systemctl restart hvacker
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -210,38 +210,38 @@ const cardGames = {
|
||||||
getCardName: card => card.name,
|
getCardName: card => card.name,
|
||||||
getCardImageUrl: card => card.card_images[0].image_url
|
getCardImageUrl: card => card.card_images[0].image_url
|
||||||
},
|
},
|
||||||
lotrOld: {
|
// lotrOld: {
|
||||||
names: ['!lotrOld'],
|
// names: ['!lotrOld'],
|
||||||
help: 'Search for Lord of the Rings cards: !lotrOld <card name>',
|
// help: 'Search for Lord of the Rings cards: !lotrOld <card name>',
|
||||||
cards: async () => JSON.parse(readFileSync('lotrOld/lotr_cards.json').toString()),
|
// cards: async () => JSON.parse(readFileSync('lotrOld/lotr_cards.json').toString()),
|
||||||
fetch: async name => ({ json: () => {
|
// fetch: async name => ({ json: () => {
|
||||||
const matcher = fuzzyMatcher(name?.toLowerCase())
|
// const matcher = fuzzyMatcher(name?.toLowerCase())
|
||||||
const exact = cardGames.lotrOld.cards.filter(card => card.name?.toLowerCase() === name.toLowerCase())
|
// const exact = cardGames.lotrOld.cards.filter(card => card.name?.toLowerCase() === name.toLowerCase())
|
||||||
if (exact.length) {
|
// if (exact.length) {
|
||||||
return exact
|
// return exact
|
||||||
}
|
// }
|
||||||
return cardGames.lotrOld.cards.filter(card => matcher.test(card.name))
|
// return cardGames.lotrOld.cards.filter(card => matcher.test(card.name))
|
||||||
} }),
|
// } }),
|
||||||
getCardData: data => data,
|
// getCardData: data => data,
|
||||||
getCardName: card => card.name,
|
// getCardName: card => card.name,
|
||||||
getCardImageUrl: card => 'https://ringsdb.com' + card.imagesrc
|
// getCardImageUrl: card => 'https://ringsdb.com' + card.imagesrc
|
||||||
},
|
// },
|
||||||
lotr: {
|
// lotr: {
|
||||||
names: ['!lotr'],
|
// names: ['!lotr'],
|
||||||
help: 'Search for Lord of the Rings cards: !lotr <card name>',
|
// help: 'Search for Lord of the Rings cards: !lotr <card name>',
|
||||||
cards: async () => JSON.parse(readFileSync('lotr/cards.json').toString()),
|
// cards: async () => JSON.parse(readFileSync('lotr/cards.json').toString()),
|
||||||
fetch: async name => ({ json: () => {
|
// fetch: async name => ({ json: () => {
|
||||||
const matcher = fuzzyMatcher(name?.toLowerCase())
|
// const matcher = fuzzyMatcher(name?.toLowerCase())
|
||||||
const exact = cardGames.lotr.cards.filter(card => card.name?.toLowerCase() === name.toLowerCase())
|
// const exact = cardGames.lotr.cards.filter(card => card.name?.toLowerCase() === name.toLowerCase())
|
||||||
if (exact.length) {
|
// if (exact.length) {
|
||||||
return [exact[0]]
|
// return [exact[0]]
|
||||||
}
|
// }
|
||||||
return cardGames.lotr.cards.filter(card => matcher.test(card.name)).filter(card => !card.name.includes('('))
|
// return cardGames.lotr.cards.filter(card => matcher.test(card.name)).filter(card => !card.name.includes('('))
|
||||||
} }),
|
// } }),
|
||||||
getCardData: data => data,
|
// getCardData: data => data,
|
||||||
getCardName: card => card.name,
|
// getCardName: card => card.name,
|
||||||
getCardImageUrl: card => 'https://lotrtcgwiki.com/wiki/_media/cards:' + card.id + '.jpg'
|
// getCardImageUrl: card => 'https://lotrtcgwiki.com/wiki/_media/cards:' + card.id + '.jpg'
|
||||||
},
|
// },
|
||||||
playingCards: {
|
playingCards: {
|
||||||
names: ['!playing', '!pc'],
|
names: ['!playing', '!pc'],
|
||||||
help: 'Search for playing cards cards: !pc <card name>',
|
help: 'Search for playing cards cards: !pc <card name>',
|
||||||
|
@ -1122,7 +1122,7 @@ command(
|
||||||
'Mine HVAC coins',
|
'Mine HVAC coins',
|
||||||
async ({ say, user, userId }) => {
|
async ({ say, user, userId }) => {
|
||||||
await say(await doMine({ user, userId, say }))
|
await say(await doMine({ user, userId, say }))
|
||||||
if ((lbIndex++) % 5 == 0) {
|
if ((lbIndex++) % 20 == 0) {
|
||||||
return updateAllLeaderboards()
|
return updateAllLeaderboards()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1573,7 +1573,10 @@ command(
|
||||||
const last = gifted.pop()
|
const last = gifted.pop()
|
||||||
recipients = gifted.map(t => users[t].name).join(', ') + ', and ' + users[last].name
|
recipients = gifted.map(t => users[t].name).join(', ') + ', and ' + users[last].name
|
||||||
} else {
|
} else {
|
||||||
recipients = users[recipients[0]].name
|
console.log('gifted', gifted)
|
||||||
|
console.log('users[gifted[0]]', users[gifted[0]])
|
||||||
|
recipients = users[gifted[0]].name
|
||||||
|
console.log('recipients', recipients)
|
||||||
}
|
}
|
||||||
await say(`Gifted ${commas(individualAmount)} HVAC to ${recipients}`)
|
await say(`Gifted ${commas(individualAmount)} HVAC to ${recipients}`)
|
||||||
}
|
}
|
||||||
|
@ -2257,7 +2260,7 @@ command(
|
||||||
adminOnly
|
adminOnly
|
||||||
)
|
)
|
||||||
|
|
||||||
//webapi.launch()
|
webapi.launch()
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
command,
|
command,
|
||||||
|
|
|
@ -5,17 +5,22 @@ const buyableItems = require('./buyableItems')
|
||||||
const { quackStore, getChaos } = require('./quackstore')
|
const { quackStore, getChaos } = require('./quackstore')
|
||||||
const slack = require("../../slack");
|
const slack = require("../../slack");
|
||||||
|
|
||||||
|
let slackUsers
|
||||||
|
const setSlackUsers = users => {
|
||||||
|
slackUsers = users
|
||||||
|
}
|
||||||
let upgrades
|
let upgrades
|
||||||
const setUpgrades = upg => {
|
const setUpgrades = upg => {
|
||||||
upgrades = upg
|
upgrades = upg
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveFile = 'hvacoins.json'
|
const saveFile = 'hvacoins.json'
|
||||||
|
const saveDir = '/hvacker-saves/'
|
||||||
|
|
||||||
const logError = msg => msg ? console.error('logError: ', msg) : () => { /* Don't log empty message */ }
|
const logError = msg => msg ? console.error('logError: ', msg) : () => { /* Don't log empty message */ }
|
||||||
|
|
||||||
const loadGame = () => {
|
const loadGame = () => {
|
||||||
const game = parseOr(fs.readFileSync('./' + saveFile, 'utf-8'),
|
const game = parseOr(fs.readFileSync(saveDir + saveFile, 'utf-8'),
|
||||||
() => ({
|
() => ({
|
||||||
users: {},
|
users: {},
|
||||||
nfts: [],
|
nfts: [],
|
||||||
|
@ -55,7 +60,7 @@ const parseOr = (parseable, fallback) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const makeBackup = () => {
|
const makeBackup = () => {
|
||||||
const fileName = './backups/' + saveFile + new Date().toLocaleString().replace(/[^a-z0-9]/gi, '_')
|
const fileName = saveDir + 'backups/' + saveFile + new Date().toLocaleString().replace(/[^a-z0-9]/gi, '_')
|
||||||
console.log(`Making backup file: ${fileName}`)
|
console.log(`Making backup file: ${fileName}`)
|
||||||
fs.writeFileSync(fileName, JSON.stringify(game))
|
fs.writeFileSync(fileName, JSON.stringify(game))
|
||||||
}
|
}
|
||||||
|
@ -73,7 +78,7 @@ const saveGame = (after, force = true) => {
|
||||||
console.log('SAVING GAME')
|
console.log('SAVING GAME')
|
||||||
}
|
}
|
||||||
|
|
||||||
fs.writeFileSync('./' + saveFile, JSON.stringify(game, null, 2))
|
fs.writeFileSync(saveDir + saveFile, JSON.stringify(game, null, 2))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -258,6 +263,7 @@ const getUser = (userId, updateCoins = false) => {
|
||||||
users[userId].coinsAllTime ??= users[userId].coins
|
users[userId].coinsAllTime ??= users[userId].coins
|
||||||
users[userId].prestige ??= 0
|
users[userId].prestige ??= 0
|
||||||
users[userId].startDate ??= new Date()
|
users[userId].startDate ??= new Date()
|
||||||
|
// users[userId].name ??= slack.users[userId]
|
||||||
if (updateCoins) {
|
if (updateCoins) {
|
||||||
users[userId].coins = getCoins(userId)
|
users[userId].coins = getCoins(userId)
|
||||||
}
|
}
|
||||||
|
@ -610,5 +616,6 @@ module.exports = {
|
||||||
petBoost,
|
petBoost,
|
||||||
updateAll,
|
updateAll,
|
||||||
setSlackAppClientChatUpdate: update => slackAppClientChatUpdate = update,
|
setSlackAppClientChatUpdate: update => slackAppClientChatUpdate = update,
|
||||||
setUpgrades
|
setUpgrades,
|
||||||
|
setSlackUsers
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,48 +17,97 @@ const makeHash = pw =>
|
||||||
.update(pw)
|
.update(pw)
|
||||||
.digest('hex')
|
.digest('hex')
|
||||||
|
|
||||||
const illegalCommands = ['!', '!b']
|
const emojiMaps = [
|
||||||
|
['mouse2', '🐭'],
|
||||||
|
['male-office-worker', '🧑💼'],
|
||||||
|
['whale', '🐋'],
|
||||||
|
['train2', '🚂'],
|
||||||
|
['fire', '🔥'],
|
||||||
|
['boomerang', '🪃'],
|
||||||
|
['new_moon_with_face', '🌚'],
|
||||||
|
['butterfly', '🦋'],
|
||||||
|
['mirror', '🪞'],
|
||||||
|
['quade', '🧔♂️'],
|
||||||
|
['hvacker_angery', '🦆'],
|
||||||
|
['grey_question', '❓'],
|
||||||
|
['convenience_store', '🏪'],
|
||||||
|
['office', '🏢'],
|
||||||
|
['japanese_castle', '🏯']
|
||||||
|
]
|
||||||
|
|
||||||
|
app.get('/alive', (req, res) => {
|
||||||
|
res.send('OK')
|
||||||
|
})
|
||||||
|
|
||||||
|
const illegalCommands = ['!', '!c', '!coin', '!mine']
|
||||||
const lastCalls = {}
|
const lastCalls = {}
|
||||||
const addCommand = ({ commandNames, helpText, action, condition, hidden }) => {
|
const addCommand = ({ commandNames, helpText, action, condition, hidden }) => {
|
||||||
if (illegalCommands.find(command => commandNames.includes(command))) {
|
|
||||||
commandNames.forEach(name =>
|
|
||||||
app.get('/' + name.replace(/!/gi, ''), async (req, res) => res.send('Command is illegal over the web api.'))
|
|
||||||
)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const route = async (req, res) => {
|
const route = async (req, res) => {
|
||||||
const say = async msg => res.send(msg + '\n')
|
let sent
|
||||||
|
const say = async msg => {
|
||||||
|
if (sent) {
|
||||||
|
console.log('attempted double-send of', { msg })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const isObj = typeof msg === 'object'
|
||||||
|
if (isObj) {
|
||||||
|
msg = JSON.stringify(msg, null, 2)
|
||||||
|
}
|
||||||
|
for (const entry of emojiMaps) {
|
||||||
|
msg = msg.replaceAll(`:${entry[0]}:`, entry[1])
|
||||||
|
}
|
||||||
|
msg = msg.replaceAll(/\*([^*]+)\*/g, '$1')
|
||||||
|
.replaceAll(/_([^_]+)_/g, '$1')
|
||||||
|
res.send((typeof msg === 'object' ? JSON.stringify(msg, null, 2) : msg) + '\n')
|
||||||
|
sent = true
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
const words = ['', ...Object.keys(req.query)]
|
const keys = [...Object.keys(req.query)]
|
||||||
|
keys.reverse()
|
||||||
|
const words = [commandNames[0], ...keys]
|
||||||
|
console.log({ words })
|
||||||
const [commandName, ...args] = words
|
const [commandName, ...args] = words
|
||||||
console.log('INCOMING API CALL:', commandName, words)
|
console.log('INCOMING API CALL:', commandName, words)
|
||||||
const encoded = req.header('Authorization').substring(5)
|
const encoded = req.header('Authorization').substring(5)
|
||||||
const decoded = base64.decode(encoded).substring(1)
|
const decoded = base64.decode(encoded).substring(1)
|
||||||
|
const hash = makeHash(decoded)
|
||||||
|
console.log({ hash })
|
||||||
const event = {
|
const event = {
|
||||||
user: apiGetUserId(makeHash(decoded))
|
user: apiGetUserId(hash)
|
||||||
|
}
|
||||||
|
const user = getUser(event.user)
|
||||||
|
if (user.name !== 'TEST-USER' && illegalCommands.includes(commandName?.toLowerCase())) {
|
||||||
|
res.send('Command is illegal over the web api!')
|
||||||
|
return
|
||||||
}
|
}
|
||||||
if (!event.user) {
|
if (!event.user) {
|
||||||
res.status(400)
|
res.status(400)
|
||||||
res.send(
|
res.send(
|
||||||
'User does not exist, or does not have a password.\n' +
|
'User with that password does not exist, or user does not have a password.\n' +
|
||||||
'See \'!setpw help\' for assistance.'
|
'See \'!setpw help\' for assistance.\n'
|
||||||
)
|
)
|
||||||
console.log(' bad password')
|
console.log(' bad password')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const lastCall = lastCalls[event.user] || 0
|
// const lastCall = lastCalls[event.user] || 0
|
||||||
const secondsBetweenCalls = 30
|
// const secondsBetweenCalls = 2
|
||||||
const currentTime = Math.floor(new Date().getTime() / 1000)
|
// const currentTime = Math.floor(new Date().getTime() / 1000)
|
||||||
if (lastCall + secondsBetweenCalls > currentTime) {
|
// if (lastCall + secondsBetweenCalls > currentTime) {
|
||||||
res.status(400)
|
// res.status(400)
|
||||||
res.send(`Must have at least ${secondsBetweenCalls}s between api calls`)
|
// res.send(`Must have at least ${secondsBetweenCalls}s between api calls`)
|
||||||
console.log(' rate limited')
|
// console.log(' rate limited')
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
// console.log(` went through for ${slack.users[event.user]}`)
|
||||||
|
// lastCalls[event.user] = currentTime
|
||||||
|
|
||||||
|
if (words[1] === 'help') {
|
||||||
|
await say(commandNames.map(name => `\`${name}\``).join(', ') + ': ' + helpText)
|
||||||
|
if (commandNames.includes('!coin')) {
|
||||||
|
addAchievement(user, 'weAllNeedHelp', say)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
console.log(` went through for ${slack.users[event.user]}`)
|
|
||||||
lastCalls[event.user] = currentTime
|
|
||||||
|
|
||||||
const user = getUser(event.user)
|
|
||||||
const haunted = false
|
const haunted = false
|
||||||
//await action({ event, say, words, args, commandName })
|
//await action({ event, say, words, args, commandName })
|
||||||
const canUse = await condition({ event, say, words, commandName, args, user, userId: event.user, isAdmin: event.user.includes(slack.users.Admin) })
|
const canUse = await condition({ event, say, words, commandName, args, user, userId: event.user, isAdmin: event.user.includes(slack.users.Admin) })
|
||||||
|
@ -69,12 +118,14 @@ const addCommand = ({ commandNames, helpText, action, condition, hidden }) => {
|
||||||
await action({ event, say, trueSay: say, words, args, commandName, user, userId: event.user, haunted })
|
await action({ event, say, trueSay: say, words, args, commandName, user, userId: event.user, haunted })
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('route error', e)
|
console.error('route error', e)
|
||||||
|
const example = "`curl --location-trusted -u ':your-pw' quacker.sagev.space/lb`"
|
||||||
await say(`Routing error. Make sure you've set up API access with the !setpw command in slack!\n` +
|
await say(`Routing error. Make sure you've set up API access with the !setpw command in slack!\n` +
|
||||||
'Then you can use calls like `curl -u ":yourpw" \'http://10.3.0.48:3001/stonks\'`')
|
`Then you can use calls like ${example}\n` +
|
||||||
|
`N.b. --location-trusted is needed because quacker.sagev.space is technically a redirect, and your headers need to be forwarded.`)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commandNames.forEach(name =>
|
commandNames.forEach(name => name !== '!!help' &&
|
||||||
app.get('/' + name.replace(/!/gi, ''), route)
|
app.get('/' + name.replace(/!/gi, ''), async (req, res) => console.log('route', name.replace('/' + /!/gi, '')) || await route(req, res))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
const { App: SlackApp } = require('@slack/bolt')
|
const { App: SlackApp } = require('@slack/bolt')
|
||||||
const config = require('../config')
|
const config = require('../config')
|
||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const { addReactions, saveGame, setSlackAppClientChatUpdate, parseOr } = require('../games/hvacoins/utils')
|
const { addReactions, saveGame, setSlackAppClientChatUpdate, parseOr, setSlackUsers } = require('../games/hvacoins/utils')
|
||||||
|
|
||||||
const temperatureChannelId = 'C034156CE03'
|
const temperatureChannelId = 'C034156CE03'
|
||||||
const dailyStandupChannelId = 'C03L533AU3Z'
|
const dailyStandupChannelId = 'C03L533AU3Z'
|
||||||
|
@ -333,6 +333,7 @@ onReaction(async ({ event }) => {
|
||||||
})
|
})
|
||||||
|
|
||||||
setSlackAppClientChatUpdate(app.client.chat.update)
|
setSlackAppClientChatUpdate(app.client.chat.update)
|
||||||
|
setSlackUsers(users)
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
app,
|
app,
|
||||||
|
|
Loading…
Reference in New Issue