forked from commandblockguy/EigenBot
-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
13 changed files
with
934 additions
and
3 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
config.json | ||
whitelist.json | ||
usercache.json | ||
|
||
package-lock.json | ||
node_modules/ |
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import fs from 'fs/promises' | ||
|
||
export async function sendCommands(pipe, ...commands) { | ||
await fs.writeFile(pipe, commands.map(cmd => cmd + '\n').join(), {flag: 'a'}) | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import util from 'minecraft-server-util' | ||
|
||
const {RCON} = util | ||
|
||
const connections = {} | ||
const TIMEOUT = Symbol() | ||
|
||
export async function sendCommands(params, ...commands) { | ||
const connection = await ensureConnection(params) | ||
const results = [] | ||
for (const command of commands) { | ||
results.push(await connection.execute(command)) | ||
} | ||
return results | ||
} | ||
|
||
async function ensureConnection(params) { | ||
const key = params.host + ':' + params.port | ||
let connection = connections[key] | ||
if (!connection) { | ||
connection = new RCON(params.host, {port: params.port, password: params.password}) | ||
await connection.connect() | ||
connections[key] = connection | ||
} | ||
connection[TIMEOUT] = Math.max(Date.now() + 5000, connection[TIMEOUT] || 0) | ||
setTimeout(checkRemoveConnection.bind(null, key), 5100) | ||
return connection | ||
} | ||
|
||
async function checkRemoveConnection(key) { | ||
const connection = connections[key] | ||
if (connection[TIMEOUT] <= Date.now()) { | ||
delete connections[key] | ||
try { | ||
await connection.close() | ||
} catch (e) { | ||
console.error(e) | ||
} | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import fs, { read } from 'fs' | ||
import { getUUID } from './usercache.js' | ||
|
||
export class Database { | ||
#file | ||
#users = {} | ||
#removed = new Set() | ||
|
||
constructor(file) { | ||
this.#file = file | ||
this.load() | ||
this.save() | ||
} | ||
|
||
load() { | ||
if (!fs.existsSync(this.#file)) return | ||
const data = JSON.parse(fs.readFileSync(this.#file)) | ||
this.#users = data.users | ||
for (const user in this.#users) { | ||
this.#users[user].uuids = this.#users[user].uuids || [] | ||
} | ||
this.#removed = new Set(data.removed || []) | ||
} | ||
|
||
save() { | ||
fs.writeFileSync(this.#file, JSON.stringify(this.dump(), null, 2)) | ||
} | ||
|
||
dump() { | ||
return { | ||
users: this.#users, | ||
removed: [...this.#removed] | ||
} | ||
} | ||
|
||
async convertNamesToUuids() { | ||
const names = new Set() | ||
for (const user in this.#users) { | ||
for (const name of this.#users[user].names || []) { | ||
names.add(name) | ||
} | ||
} | ||
if (!names.size) return false | ||
const uuids = await getUUID([...names]) | ||
for (const user in this.#users) { | ||
const userUuids = new Set(this.#users[user].uuids) | ||
for (const name of this.#users[user].names || []) { | ||
const uuidForName = uuids[name.toLowerCase()] | ||
if (!uuidForName) { | ||
console.warn('Invalid username ' + name + ', skipping') | ||
} else { | ||
userUuids.add(uuidForName) | ||
} | ||
} | ||
this.#users[user].uuids = [...userUuids] | ||
delete this.#users[user].names | ||
} | ||
for (const name in uuids) this.#removed.delete(uuids[name]) | ||
this.save() | ||
return true | ||
} | ||
|
||
getUser(id) { | ||
return this.#users[id] || {uuids: []} | ||
} | ||
|
||
getAllByUUID() { | ||
const byUuid = {} | ||
for (const id in this.#users) { | ||
for (const uuid of this.#users[id].uuids) { | ||
byUuid[uuid] = id | ||
} | ||
} | ||
return byUuid | ||
} | ||
|
||
getBannedUUIDs() { | ||
const banned = new Set() | ||
for (const user of Object.values(this.#users)) { | ||
if (!user.banned) continue | ||
for (const uuid of user.uuids) { | ||
banned.add(uuid) | ||
} | ||
} | ||
return banned | ||
} | ||
|
||
getLinkedUser(uuid) { | ||
for (const id in this.#users) { | ||
if (this.#users[id].uuids.includes(uuid)) return {id, user: this.#users[id]} | ||
} | ||
} | ||
|
||
linkUser(id, uuid) { | ||
const user = this.getUser(id) | ||
user.uuids = [...new Set([...user.uuids, uuid])] | ||
this.#users[id] = user | ||
this.#removed.delete(uuid) | ||
this.save() | ||
return user | ||
} | ||
|
||
unlinkUser(id, uuid) { | ||
const user = this.getUser(id) | ||
const uuids = new Set(user.uuids) | ||
uuids.delete(uuid) | ||
user.uuids = [...uuids] | ||
if (user.uuids.length) { | ||
this.#users[id] = user | ||
} else { | ||
delete this.#users[id] | ||
} | ||
this.#removed.add(uuid) | ||
this.save() | ||
return user | ||
} | ||
|
||
removeUser(id) { | ||
const user = this.#users[id] | ||
delete this.#users[id] | ||
for (const uuid of user.uuids) { | ||
this.#removed.add(uuid) | ||
} | ||
this.save() | ||
return user | ||
} | ||
|
||
get removed() { | ||
return [...this.#removed] | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
import path from 'path' | ||
import Client from 'ftp' | ||
import {readFully} from '../../../utils.js' | ||
|
||
export class FTPFileManager { | ||
#params | ||
|
||
constructor(params) { | ||
this.#params = params | ||
} | ||
|
||
async #connect() { | ||
return new Promise((resolve, reject) => { | ||
const c = new Client() | ||
c.on('ready', () => resolve(c)) | ||
c.on('error', reject) | ||
c.connect({ | ||
host: this.#params.host, | ||
port: this.#params.port || 21, | ||
user: this.#params.username, | ||
password: this.#params.password | ||
}) | ||
}) | ||
} | ||
|
||
async readFile(file) { | ||
const c = await this.#connect() | ||
return new Promise((resolve, reject) => { | ||
c.get(path.resolve('/', this.#params.path, file), async (err, stream) => { | ||
if (err) { | ||
reject(err) | ||
return | ||
} | ||
const data = await readFully(stream) | ||
c.end() | ||
resolve(data) | ||
}) | ||
}) | ||
} | ||
|
||
async writeFile(file, data) { | ||
const c = await this.#connect() | ||
return new Promise((resolve, reject) => { | ||
c.put(data, path.resolve('/', this.#params.path, file), err => { | ||
if (err) { | ||
reject(err) | ||
} else { | ||
resolve() | ||
} | ||
}) | ||
}) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import fs from 'fs/promises' | ||
import path from 'path' | ||
|
||
export class LocalFileManager { | ||
#path | ||
|
||
constructor(params) { | ||
this.#path = params.path | ||
} | ||
|
||
async readFile(file) { | ||
return fs.readFile(path.resolve(this.#path, file)) | ||
} | ||
|
||
async writeFile(file, data) { | ||
return fs.writeFile(path.resolve(this.#path, file), data) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
import fs from 'fs' | ||
import path from 'path' | ||
import {Client} from 'ssh2' | ||
import {readFully} from '../../../utils.js' | ||
|
||
export class SFTPFileManager { | ||
#params | ||
|
||
constructor(params) { | ||
this.#params = { | ||
...params, | ||
privateKey: params.privateKey && fs.readFileSync(params.privateKey) | ||
} | ||
} | ||
|
||
async readFile(file) { | ||
const fullPath = path.resolve(this.#params.path, file) | ||
return new Promise((resolve, reject) => { | ||
const conn = new Client() | ||
conn.on('ready', () => { | ||
conn.sftp((err, sftp) => { | ||
if (err) return reject(err) | ||
readFully(sftp.createReadStream(fullPath, {encoding: 'utf8'})).then(data => { | ||
conn.end() | ||
resolve(data) | ||
}).catch(reject) | ||
}) | ||
}).connect(this.#params) | ||
}) | ||
} | ||
|
||
async writeFile(file, data) { | ||
const fullPath = path.resolve(this.#params.path, file) | ||
return new Promise((resolve, reject) => { | ||
const conn = new Client() | ||
conn.on('ready', () => { | ||
conn.sftp((err, sftp) => { | ||
if (err) return reject(err) | ||
const stream = sftp.createWriteStream(fullPath, {encoding: 'utf8'}) | ||
stream.on('error', reject) | ||
stream.end(data, () => { | ||
conn.end() | ||
resolve() | ||
}) | ||
}) | ||
}).connect(this.#params) | ||
}) | ||
} | ||
} |
Oops, something went wrong.