Skip to content

Commit eb66964

Browse files
committed
moved steam accs from config to db
1 parent 00cc7fb commit eb66964

File tree

8 files changed

+179
-139
lines changed

8 files changed

+179
-139
lines changed

cmd.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@ const commands = [
99
file: 'skins/update',
1010
},
1111
{
12-
name: 'accounts:encrypt',
13-
description: 'Encrypt the password and shared secret of a Steam account.',
14-
file: 'accounts/encrypt',
12+
name: 'account:create',
13+
description: 'Add a new Steam account to the database.',
14+
file: 'account/create',
15+
},
16+
{
17+
name: 'account:destroy',
18+
description: 'Remove an existing Steam account from the database.',
19+
file: 'account/destroy',
1520
},
1621
];
1722

commands/account/create.js

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
const path = require('path');
2+
require('dotenv').config({ path: path.join(__dirname, './.env') });
3+
const { program } = require('commander');
4+
5+
require('../../database');
6+
const SteamAccount = require('../../database/models/SteamAccount');
7+
const Encryption = require('../../modules/Encryption');
8+
const logger = require('../../modules/Logger');
9+
10+
program
11+
.requiredOption('-u, --username <string>', 'The username of the Steam account')
12+
.requiredOption('-p, --password <string>', 'The password of the Steam account')
13+
.requiredOption('-s, --secret <string>', 'The shared secret of the Steam account');
14+
15+
program.parse(process.argv);
16+
17+
(async () => {
18+
const steamAccount = await SteamAccount.query().insert({
19+
username: program.username,
20+
password: Encryption.encrypt(program.password),
21+
shared_secret: Encryption.encrypt(program.secret),
22+
});
23+
24+
logger.info(`Successfully created Steam account with username ${steamAccount.username}`);
25+
26+
process.exit();
27+
})();

commands/account/destroy.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const path = require('path');
2+
require('dotenv').config({ path: path.join(__dirname, './.env') });
3+
const { program } = require('commander');
4+
5+
require('../../database');
6+
const SteamAccount = require('../../database/models/SteamAccount');
7+
const logger = require('../../modules/Logger');
8+
9+
program.requiredOption('-u, --username <string>', 'The username of the Steam account');
10+
11+
program.parse(process.argv);
12+
13+
(async () => {
14+
const [steamAccount] = await SteamAccount.query()
15+
.where('username', program.username)
16+
.delete()
17+
.returning('*');
18+
19+
if (!steamAccount) {
20+
logger.error(`The Steam account with username ${program.username} does not exist.`);
21+
} else {
22+
logger.info(`Successfully deleted Steam account with username ${steamAccount.username}`);
23+
}
24+
25+
process.exit();
26+
})();

commands/accounts/encrypt.js

-21
This file was deleted.

config/default.js

-27
Original file line numberDiff line numberDiff line change
@@ -23,33 +23,6 @@ module.exports = {
2323

2424
steam: {
2525
apiKey: env.STEAM_API_KEY,
26-
accounts: [
27-
{
28-
username: 'chesc0s42',
29-
password: '5ab2581b4330cfb5562de8c617ba7874:84c6383ae47a9c27bc22ce92',
30-
sharedSecret: 'cde28d858c317fd519111d0a342caefc:f77f2c8574d6ef1bb6b6be344cf2188ab04f974b17217091661406a0',
31-
},
32-
{
33-
username: 'chesc0s43',
34-
password: '388e3021f49fd7a5b9b57f53e1567044:71136d6eeef21a8baab6b494',
35-
sharedSecret: 'c9dc335b72f9b464625e78a79eda3d58:a35a92a4a2748ed7c3838cf03a7bdad72bb776c8cabf7c5c766ca062',
36-
},
37-
{
38-
username: 'chesc0s44',
39-
password: '528cdd041fb0d61cfd8300d35e8b9c04:efa6fa7c69827cdd3f2635c5',
40-
sharedSecret: '28cfbba74e17f2deb343c3f138ce802a:295b120e360ddee22a1f0ba637c989abc5edd0cc5bd4901679afb57d',
41-
},
42-
{
43-
username: 'chesc0s45',
44-
password: 'e685454a7a0840676e0b9412b95c3e2d:13c0f48ed136c61b7ef0bfcc',
45-
sharedSecret: '8475a0ec96e9448dd7d6ee1fa3fbddaa:e2882b30e899caaf3aaf901fc1dbcc16e3b2ee11d1a7c34b45a16924',
46-
},
47-
{
48-
username: 'chesc0s46',
49-
password: 'c72231b81da5cd3d025212ed25e8857a:16527f928feeb0805aef95bc',
50-
sharedSecret: 'e0c5bbaf5f6a330b4135592b5cd60aa2:97ce5e245e82c900d6fcc65158eabc09e98c50275463e7e5daea3525',
51-
},
52-
],
5326
},
5427

5528
inspect: {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
exports.up = async (knex) => {
2+
await knex.schema.createTable('steam_accounts', (table) => {
3+
table.increments('id');
4+
table.string('username').notNullable().unique();
5+
table.string('password').notNullable();
6+
table.string('shared_secret').notNullable();
7+
table.timestamps(false, true);
8+
});
9+
};
10+
11+
exports.down = async (knex) => {
12+
await knex.schema.dropTable('steam_accounts');
13+
};

database/models/SteamAccount.js

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const Model = require('../base/BaseModel');
2+
3+
class SteamAccount extends Model {
4+
static get tableName() {
5+
return 'steam_accounts';
6+
}
7+
8+
static get idColumn() {
9+
return 'id';
10+
}
11+
}
12+
13+
module.exports = SteamAccount;

modules/Inspector.js

+92-88
Original file line numberDiff line numberDiff line change
@@ -1,98 +1,100 @@
1-
const config = require('config');
21
const SteamUser = require('steam-user');
32
const GlobalOffensive = require('globaloffensive');
43
const SteamTotp = require('steam-totp');
54
const async = require('async');
65
const logger = require('./Logger');
76
const Encryption = require('./Encryption');
7+
const SteamAccount = require('../database/models/SteamAccount');
88

9-
const accounts = config.get('steam.accounts').map((account) => ({
10-
username: account.username,
11-
password: Encryption.decrypt(account.password),
12-
sharedSecret: Encryption.decrypt(account.sharedSecret),
13-
}));
14-
15-
const clients = [];
16-
17-
accounts.forEach((account) => {
18-
const client = new SteamUser({
19-
// This is necessary for `ownsApp` to work.
20-
enablePicsCache: true,
21-
});
22-
23-
const csgo = new GlobalOffensive(client);
24-
25-
client.logOn({
26-
accountName: account.username,
27-
password: account.password,
28-
twoFactorCode: SteamTotp.getAuthCode(account.sharedSecret),
29-
});
30-
31-
client.on('loggedOn', () => {
32-
logger.info(`Logged into Steam as ${client.steamID.getSteam3RenderedID()}`);
33-
client.setPersona(SteamUser.EPersonaState.Online);
34-
client.gamesPlayed(730, true);
35-
});
36-
37-
client.on('appOwnershipCached', () => {
38-
// If the account does not own CS:GO yet, claim the free license first.
39-
// This is necessary to connect to the game coordinator via `gamesPlayed`,
40-
// and `gamesPlayed` is necessary to inspect skins.
41-
if (!client.ownsApp(730)) {
42-
client.requestFreeLicense(730, (err) => {
43-
if (err) {
44-
logger.warn('Failed to acquire lisence for CS:GO');
45-
logger.error(err);
46-
} else {
47-
logger.info('Successfully acquired license for CS:GO');
48-
client.gamesPlayed(730, true);
49-
}
9+
class Inspector {
10+
constructor() {
11+
this.clients = [];
12+
13+
SteamAccount.query().then((steamAccounts) => {
14+
steamAccounts.forEach((steamAccount) => {
15+
this.addClient(
16+
steamAccount.username,
17+
Encryption.decrypt(steamAccount.password),
18+
Encryption.decrypt(steamAccount.shared_secret),
19+
);
5020
});
51-
}
52-
});
53-
54-
client.on('error', (e) => {
55-
// Some error occurred during logon
56-
logger.error('Client error');
57-
logger.error(e);
58-
});
59-
60-
client.on('webSession', () => {
61-
logger.info('Got web session');
62-
// Do something with these cookies if you wish
63-
});
64-
65-
csgo.on('connectedToGC', () => {
66-
logger.info('Connected to CS:GO game coordinator');
67-
});
68-
69-
csgo.on('inspectItemTimedOut', (assetid) => {
70-
logger.warn(`Inspect timed out for assetid ${assetid}`);
71-
});
72-
73-
clients.push({
74-
client,
75-
csgo,
76-
busySince: null,
77-
});
78-
});
79-
80-
setInterval(() => {
81-
for (let i = 0; i < clients.length; i += 1) {
82-
// Mark clients as not busy if they have been busy for more than 10 seconds.
83-
if (clients[i].busySince && Date.now() > (clients[i].busySince + 10000)) {
84-
clients[i].busySince = null;
85-
logger.info(`Marked client ${i} as not busy after 10 second timeout`);
86-
}
21+
});
22+
23+
setInterval(() => {
24+
for (let i = 0; i < this.clients.length; i += 1) {
25+
// Mark clients as not busy if they have been busy for more than 10 seconds.
26+
if (this.clients[i].busySince && Date.now() > (this.clients[i].busySince + 10000)) {
27+
this.clients[i].busySince = null;
28+
logger.info(`Marked client ${i} as not busy after 10 second timeout`);
29+
}
30+
}
31+
}, 1000);
8732
}
88-
}, 1000);
8933

90-
class Inspector {
91-
static getClients() {
92-
return clients;
34+
addClient(username, password, sharedSecret) {
35+
const client = new SteamUser({
36+
// This is necessary for `ownsApp` to work.
37+
enablePicsCache: true,
38+
});
39+
40+
const csgo = new GlobalOffensive(client);
41+
42+
client.logOn({
43+
accountName: username,
44+
password,
45+
twoFactorCode: SteamTotp.getAuthCode(sharedSecret),
46+
});
47+
48+
client.on('loggedOn', () => {
49+
logger.info(`Logged into Steam as ${client.steamID.getSteam3RenderedID()}`);
50+
client.setPersona(SteamUser.EPersonaState.Online);
51+
client.gamesPlayed(730, true);
52+
});
53+
54+
client.on('appOwnershipCached', () => {
55+
// If the account does not own CS:GO yet, claim the free license first.
56+
// This is necessary to connect to the game coordinator via `gamesPlayed`,
57+
// and `gamesPlayed` is necessary to inspect skins.
58+
if (!client.ownsApp(730)) {
59+
client.requestFreeLicense(730, (err) => {
60+
if (err) {
61+
logger.warn('Failed to acquire lisence for CS:GO');
62+
logger.error(err);
63+
} else {
64+
logger.info('Successfully acquired license for CS:GO');
65+
client.gamesPlayed(730, true);
66+
}
67+
});
68+
}
69+
});
70+
71+
client.on('error', (e) => {
72+
// Some error occurred during logon
73+
logger.error('Client error');
74+
logger.error(e);
75+
});
76+
77+
client.on('webSession', () => {
78+
logger.info('Got web session');
79+
// Do something with these cookies if you wish
80+
});
81+
82+
csgo.on('connectedToGC', () => {
83+
logger.info('Connected to CS:GO game coordinator');
84+
});
85+
86+
csgo.on('inspectItemTimedOut', (assetid) => {
87+
logger.warn(`Inspect timed out for assetid ${assetid}`);
88+
});
89+
90+
this.clients.push({
91+
client,
92+
csgo,
93+
busySince: null,
94+
});
9395
}
9496

95-
static inspect(url, timeoutMs = 3000) {
97+
inspect(url, timeoutMs = 3000) {
9698
return new Promise((resolve, reject) => {
9799
// We'll want a timeout of at least 1500 ms.
98100
if (timeoutMs < 1500) {
@@ -113,7 +115,7 @@ class Inspector {
113115
// Find an index of a client that is currently not busy and has a GC connection.
114116
async
115117
.retry({ times: retryTimes, interval: retryInterval }, async () => {
116-
const index = clients.findIndex(
118+
const index = this.clients.findIndex(
117119
(client) => client.busySince === null && client.csgo.haveGCSession,
118120
);
119121

@@ -130,15 +132,17 @@ class Inspector {
130132
// If the inspection succeeds, `busySince` will be cleared immediately.
131133
// If the inspection times out, `busySince` will be cleared after within
132134
// 1 second after the timeout.
133-
clients[index].busySince = Date.now();
135+
this.clients[index].busySince = Date.now();
134136

135-
clients[index].csgo.inspectItem(url, (item) => {
136-
clients[index].busySince = null;
137+
this.clients[index].csgo.inspectItem(url, (item) => {
138+
this.clients[index].busySince = null;
137139
resolve(item);
138140
});
139141
});
140142
});
141143
}
142144
}
143145

144-
module.exports = Inspector;
146+
const inspector = new Inspector();
147+
148+
module.exports = inspector;

0 commit comments

Comments
 (0)