Skip to content

Commit c8bc102

Browse files
authored
Merge pull request #36 from Taraman17/dev
Initial support for CS2
2 parents 3fa7a09 + 2986011 commit c8bc102

11 files changed

Lines changed: 189 additions & 482 deletions

File tree

‎README.MD‎

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,41 @@
1-
# CS:GO Server Control with a Nodejs-powered web-API (LINUX only)
2-
3-
## Request for your opinion
4-
Please let me know, If I should work on the installation process:
5-
[Poll on Installation](https://github.com/Taraman17/nodejs-csgo-api/discussions/31)
1+
# CS2 Server Control with a Nodejs-powered web-API (LINUX only)
62

73
## Disclaimer
84
The use of this software is at your own risk.
95
It exposes control of your server and shell functions to the internet. Although I did everything to secure the API, any bugs may lead to security breaches on your server.
106
I strongly adivise to use secure connections to prevent possible man-in-the-middle attacks.
117

12-
## NOTE:
13-
Release 1.0 changed structure of the code to enable further development.
14-
See below for changes.
15-
16-
### Breaking changes:
17-
- Config logic has been separated from configClass - make sure to backup your config! You can copy the config part from the old file to the new "./config.js"
18-
- steam account used for updating the server has been deleted from the config - it has to go in your update-Script.
19-
- login code has been seperated from the api calls. New location is "http://{your-servers-address}:{your-port}/csgoapi/login" ISO "http://{your-servers-address}:{your-port}/csgoapi/v1.0/login"
8+
## CS2 Beta Info
9+
This is the intial beta release for CS2. It has the following changes to previous functionality
10+
- Changed Log-reception to http logs, since UDP is not supported anymore in new server. Unnecessary library source-log-receiver removed.
11+
- Maplist loading is still bugged in CS2 Server - therefore working with a static Maplist. Also this has to be loaded with the "relaodMaplist" endpoint.
12+
- Still working with the old CS_GO map-pictures, since the new ones are not yet available in the workshop
13+
- Went back to the original rcon-srcds library instead of my patched one, since the new server seems to behave more standard-like.
14+
- API calls are unchanged.
2015

2116
## Prerequisites
2217
- steam CLI
23-
- CS:GO dedicated server
24-
- NodeJS 13.X or higher
18+
- CS2 dedicated server
19+
- NodeJS 14.X or higher
2520

2621
## Install
2722
Download the nodejs-csgo-api-vX.X.zip and unpack.
2823

2924
**OR**
3025
download the script files to and install the dependencies for nodejs
3126
```console
32-
npm install --save srcds-log-receiver local-ip express express-session express-rate-limit cors passport passport-steam node-pty ws winston winston-daily-rotate-file
33-
```
34-
If you want to use http authentication, add
35-
```console
36-
npm install --save passport-http
27+
npm install
3728
```
3829

3930
## Configuration
40-
The CS:GO Server must be configured to send logs to the local IP (not 127.0.0.1): on port 9871
31+
The CS:GO Server must be configured to send logs to the local IP (not 127.0.0.1): on port 8092 (or the one you specified in config.js)
4132
```
4233
log on
4334
sv_logecho 1
4435
mp_logfile 1
4536
mp_logdetail 3
4637
mp_logmessages 1
47-
logaddress_add xxx.xxx.xxx.xxx:9871
38+
logaddress_add_http "http://xxx.xxx.xxx.xxx:8092"
4839
```
4940
- Edit the settings in config.js. Most of them are explained in the sourcecode.
5041
- The API uses steam authentication which returns a Steam ID as URL (https://steamcommunity.com/openid/id/{steamid}). The last part is the SteamID64, which can be calculated from the other SteamID formats - various online tools are available. In the configuration, an array needs to be filled with the comma separated IDs of your intended admins as strings (e.g. ['{steamid-1}', '{steamid-2}'].

‎config.js‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
"webSockets": false,
2727
// Port, the websocket is listening on.
2828
"socketPort": 8091,
29+
// Port the Logreceiver listens on.
30+
'logPort': 8092,
2931
// https settings
3032
"useHttps": false,
3133
// Optional: If you use https, add the path to the certificate files here.

‎modules/apiV10.js‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -384,11 +384,11 @@ router.get('/control/stop', (req, res) => {
384384
* { "error": "Could not find csgo server process" }
385385
*/
386386
router.get('/control/kill', (req, res) => {
387-
exec('/bin/ps -a |grep srcds_linux', (error, stdout, stderr) => {
387+
exec('/bin/ps -A |grep cs2', (error, stdout, stderr) => {
388388
if (error) {
389389
logger.error(`exec error: ${error}`);
390390
res.status(501).json({ "error": "Could not find csgo server process" });
391-
} else if (stdout.match(/srcds_linux/) != null) {
391+
} else if (stdout.match(/cs2/) != null) {
392392
let pid = stdout.split(/\s+/)[1];
393393
exec(`/bin/kill ${pid}`, (error, stdout, stderr) => {
394394
if (error) {

‎modules/configClass.js‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ class config {
66
this._userOptions = require('../config.js');
77

88
this.screenCommand = `${this._userOptions.screen} -L -Logfile ${this._userOptions.screenLog} -dmS ${this._userOptions.screenName}`;
9-
this.csgoCommand = `${this._userOptions.csgoDir}/srcds_run`;
10-
this.csgoArgs = `-game csgo -console -usercon +sv_setsteamaccount ${this._userOptions.serverToken} ${this._userOptions.csgoOptionalArgs}`;
9+
this.csgoCommand = `${this._userOptions.csgoDir}/cs2 -dedicated`;
10+
this.csgoArgs = `-console -usercon +sv_setsteamaccount ${this._userOptions.serverToken} ${this._userOptions.csgoOptionalArgs}`;
1111
}
1212

1313
get rconPass() {
@@ -47,6 +47,9 @@ class config {
4747
get socketPort() {
4848
return this._userOptions.socketPort;
4949
}
50+
get logPort() {
51+
return this._userOptions.logPort;
52+
}
5053

5154
get serverCommandline() {
5255
return `${this.screenCommand} ${this.csgoCommand} ${this.csgoArgs}`;

‎modules/logreceive.js‎

Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
const express = require('express');
2+
var router = express.Router();
3+
const { exec } = require('child_process');
4+
var controlEmitter = require('./controlEmitter.js');
5+
const logger = require('./logger.js');
6+
var serverInfo = require('./serverInfo.js');
7+
const sf = require('./sharedFunctions.js');
8+
var cfg = require('./configClass.js');
9+
10+
router.post('/log', (req, res) => {
11+
const data = req.body;
12+
var logs = data.split(/\r\n|\r|\n/);
13+
14+
logs.forEach(line => {
15+
if (line.length >= 20) {
16+
// Start authentication, when not authenticated.
17+
if ((line.indexOf('Log file started') != -1) && !serverInfo.serverState.authenticated) {
18+
// Start of logfile
19+
// L 08/13/2020 - 21:48:49: Log file started (file "logs/L000_000_000_000_27015_202008132148_000.log") (game "/home/user/csgo_ds/csgo") (version "7929")
20+
logger.verbose('start authenticating RCON');
21+
// Since authentication is a vital step for the API to work, we start it automatically
22+
// once the server runs.
23+
sf.authenticate().then((data) => {
24+
logger.verbose(`authentication ${data.authenticated}`);
25+
}).catch((data) => {
26+
logger.verbose(`authentication ${data.authenticated}`);
27+
});
28+
if (cfg.script('logStart') != '') {
29+
exec(cfg.script('logStart'));
30+
}
31+
} else if (line.indexOf('Loading map ') != -1) {
32+
// Start of map.
33+
// L 10/13/2023 - 14:28:38: Loading map "de_anubis"
34+
let rex = /Loading map \"(\S+)\"/g;
35+
let matches = rex.exec(line);
36+
let mapstring = matches[1];
37+
mapstring = sf.cutMapName(mapstring);
38+
serverInfo.map = mapstring;
39+
// since 'started map' is also reported on server-start, only emit on mapchange.
40+
if (serverInfo.serverState.operationPending == 'mapchange') {
41+
controlEmitter.emit('exec', 'mapchange', 'end');
42+
}
43+
logger.verbose(`Started map: ${mapstring}`);
44+
serverInfo.clearPlayers();
45+
serverInfo.newMatch();
46+
if (cfg.script('mapStart') != '') {
47+
exec(cfg.script('mapStart'));
48+
}
49+
} else if (line.indexOf('World triggered "Match_Start" on') != -1) {
50+
// Start of a new match.
51+
// L 08/13/2020 - 21:49:26: World triggered "Match_Start" on "de_nuke"
52+
logger.verbose('Detected match start.');
53+
sf.queryMaxRounds();
54+
serverInfo.newMatch();
55+
let rex = /World triggered "Match_Start" on "(.+)"/
56+
let matches = rex.exec(line)
57+
serverInfo.map = matches[1];
58+
if (cfg.script('matchStart') != '') {
59+
exec(cfg.script('matchStart'));
60+
}
61+
} else if (line.indexOf('World triggered "Round_Start"') != -1) {
62+
// Start of round.
63+
// L 08/13/2020 - 21:49:28: World triggered "Round_Start"
64+
if (cfg.script('roundStart') != '') {
65+
exec(cfg.script('roundStart'));
66+
}
67+
} else if (/Team \"\S+\" scored/.test(line)) {
68+
// Team scores at end of round.
69+
// L 02/10/2019 - 21:31:15: Team "CT" scored "1" with "2" players
70+
// L 02/10/2019 - 21:31:15: Team "TERRORIST" scored "1" with "2" players
71+
rex = /Team \"(\S)\S+\" scored \"(\d+)\"/g;
72+
let matches = rex.exec(line);
73+
serverInfo.score = matches;
74+
} else if (line.indexOf('World triggered "Round_End"') != -1) {
75+
// End of round.
76+
// L 08/13/2020 - 22:24:22: World triggered "Round_End"
77+
if (cfg.script('roundEnd') != '') {
78+
exec(cfg.script('roundEnd'));
79+
}
80+
} else if (line.indexOf("Game Over:") != -1) {
81+
// End of match.
82+
// L 08/13/2020 - 22:24:22: Game Over: competitive 131399785 de_nuke score 16:9 after 35 min
83+
if (cfg.script('matchEnd') != '') {
84+
exec(cfg.script('matchEnd'));
85+
}
86+
} else if (/\".+<\d+><\[U:\d:\d+\]>/.test(line)) {
87+
// Player join or teamchange.
88+
// L 10/12/2023 - 16:06:38: "[Klosser] Taraman<2><[U:1:12610374]><>" entered the game
89+
// L 10/12/2023 - 18:57:47: "[Klosser] Taraman<2><[U:1:12610374]>" switched from team <Unassigned> to <CT>
90+
// L 10/12/2023 - 18:59:25: "[Klosser] Taraman<2><[U:1:12610374]>" switched from team <TERRORIST> to <Spectator>
91+
let rex = /\"(.+)<\d+><\[(U:\d+:\d+)\]><>\"/g;
92+
let matches = rex.exec(line);
93+
if (line.indexOf('entered the game') != -1) {
94+
serverInfo.addPlayer({ 'name': matches[1], 'steamID': matches[2] });
95+
} else if (line.search(/disconnected \(reason/) != -1) {
96+
logger.debug(line);
97+
serverInfo.removePlayer(matches[2]);
98+
} else if (line.indexOf('switched from team') != -1) {
99+
rex = /<\[(U:\d+:\d+)\]>.*switched from team <\S+> to <(\S+)>/g;
100+
matches = rex.exec(line);
101+
serverInfo.assignPlayer(matches[1], matches[2]);
102+
}
103+
} else if (line.indexOf('Log file closed') != -1) {
104+
// end of current log file. (Usually on mapchange or server quit.)
105+
// L 08/13/2020 - 22:25:00: Log file closed
106+
logger.verbose('logfile closed!');
107+
if (cfg.script('logEnd') != '') {
108+
exec(cfg.script('logEnd'));
109+
}
110+
}
111+
}
112+
});
113+
114+
res.status(200).send("Receiving logs");
115+
});
116+
117+
module.exports = router;

‎modules/rcon-srcds/LICENSE‎

Lines changed: 0 additions & 21 deletions
This file was deleted.

‎modules/rcon-srcds/packet.js‎

Lines changed: 0 additions & 37 deletions
This file was deleted.

‎modules/rcon-srcds/protocol.js‎

Lines changed: 0 additions & 17 deletions
This file was deleted.

0 commit comments

Comments
 (0)