screepsmod-admin-utils
Version:
## This is a Collection of utilities for Screeps Private Server admins
172 lines (167 loc) • 6.21 kB
JavaScript
const EventEmitter = require('events').EventEmitter
const utils = require('@screeps/backend/lib/utils.js')
const YAML = require('yamljs')
const fs = require('fs')
const util = require('util')
const readFile = util.promisify(fs.readFile)
module.exports = (config) => {
const { storage: { db, env, pubsub }, constants: C } = config.common
Object.assign(env.keys, {
SHARD_NAME: 'shardName',
TICK_RATE: 'tickRate',
TICK_TIMING: 'tickTiming',
SOCKET_UPDATE_RATE: 'socketUpdateRate',
LAST_TICKS: 'lastTicks'
})
config.utils = new EventEmitter()
Object.assign(config.utils, {
tickTiming: [],
test () {
console.log('Testing!')
},
errCatch (fn) {
return (req, res) => {
fn(req, res).catch(err => {
console.error(req.url, err)
res.status(500).send({ error: err.stack })
})
}
},
async addNPCTerminals (interval = 10) {
interval = Math.max(interval, 1)
let count = 0
const rooms = await db.rooms.find({ bus: true })
const roomNames = rooms.map(r => r._id)
const ps = roomNames.map(async room => {
let [x, y] = utils.roomNameToXY(room)
if (x < 0) x = 1 + x
if (y < 0) y = 1 + y
if (x % interval === 0 && y % interval === 0) {
const res = await db['rooms.objects'].findOne({ type: 'terminal', room })
if (res) return
count++
await db['rooms.objects'].insert({
type: 'terminal',
room,
x: 0,
y: 0,
npc: true,
store: {},
storeCapacity: C.TERMINAL_CAPACITY
})
}
})
await Promise.all(ps)
return `Added ${count} terminals`
},
removeNPCTerminals () {
return db['rooms.objects'].removeWhere({ type: 'terminal', npc: true })
},
removeBots () {
return db.users.find()
.then(users => {
const ids = users.filter(u => u.bot).map(u => u._id)
const ps = []
ps.push(...ids.map(utils.respawnUser))
ps.push(db.users.removeWhere({ _id: { $in: ids } }))
ps.push(db['users.code'].removeWhere({ user: { $in: ids } }))
ps.push(...ids.map(id => env.del(env.keys.MEMORY + id)))
ps.push(...ids.map(id => env.del(env.keys.MEMORY_SEGMENTS + id)))
return Promise.all(ps)
.then(() => 'Bots removed successfully')
})
},
setTickRate (value) {
return 'setTickRate has been deprecated and will be removed in future versions, please use system.setTickDuration instead.'
},
getTickRate () {
return 'getTickRate has been deprecated and will be removed in future versions, please use system.getTickDuration instead.'
},
setSocketUpdateRate (value) {
if (!value) return 'Value required'
config.common.storage.pubsub.publish('setSocketUpdateRate', value)
return 'Socket update rate set to ' + value + 'ms'
},
getSocketUpdateRate () {
return env.get(env.keys.SOCKET_UPDATE_RATE).then(value => `Socket update rate is ${value}ms`)
},
async setShardName (value) {
await env.set(env.keys.SHARD_NAME, value)
pubsub.publish('setShardName', value)
},
async reloadConfig () {
let filename
const configFiles = ['config.yml', 'config.yaml']
for (const file of configFiles) {
try {
fs.statSync(file)
filename = file
} catch (_) { }
}
if (!filename) return
console.log(`Loading config from ${filename}`)
try {
const { serverConfig = {} } = YAML.parse(await readFile(filename, 'utf8'))
const conf = serverConfig
console.log('Applying config', conf)
const { common: { storage: { env, pubsub } } } = config
const { constants, shardName, socketUpdateRate, tickRate, welcomeText, whitelist, statsToken } = conf
if (config.backend) {
if (welcomeText) {
config.backend.welcomeText = welcomeText
}
}
if (config.common) {
if (constants) {
const consts = Object.assign({}, config.common.constants, constants)
pubsub.publish('setConstants', JSON.stringify(consts))
}
}
if (tickRate) {
env.set(env.keys.MAIN_LOOP_MIN_DURATION, tickRate)
pubsub.publish('setTickRate', tickRate)
}
if (socketUpdateRate) {
pubsub.publish('setSocketUpdateRate', socketUpdateRate)
}
if (whitelist) {
env.set(env.keys.WHITELIST, JSON.stringify(Array.from(whitelist)))
}
if (shardName) {
await env.set(env.keys.SHARD_NAME, shardName)
pubsub.publish('setShardName', shardName)
}
if (statsToken) {
config.utils.statsToken = statsToken
}
const lastConfig = config.utils.config || {}
config.utils.config = conf
config.utils.emit('config', conf)
for (const [k, v] of Object.entries(conf)) {
if (lastConfig[k] !== v) {
config.utils.emit(`config:update:${k}`, v)
}
}
} catch (err) {
}
}
})
config.utils.addNPCTerminals._help = 'addNPCTerminals(interval = 10)'
config.utils.removeNPCTerminals._help = 'removeNPCTerminals()'
config.utils.removeBots._help = 'removeBots()'
config.utils.setTickRate._help = 'setTickRate(value) Sets tick rate (in ms)'
config.utils.getTickRate._help = 'getTickRate() Returns current tick rate'
config.utils.setSocketUpdateRate._help = 'setSocketUpdateRate(value) Sets socket update rate (in ms)'
config.utils.getSocketUpdateRate._help = 'getSocketUpdateRate() Returns current socket update rate'
config.utils.setShardName._help = 'setShardName(value) Sets the shard name'
Object.defineProperty(config.utils, '_help', {
get () { // Using a getter here so that loaded services are also included
const funcs = []
for (const k in config.utils) {
const help = config.utils[k] && config.utils[k]._help
if (help) funcs.push(help)
}
return `Admin Utilities\n${funcs.map(f => `* ${f}`).join('\n')}`
}
})
}