feat: Add support for ARK: Survival Ascended using EOS protocol (#402)
* Add epic protocol * Add support for ARK: Survival Ascended - Using epic protocol * Fix online player count * Final cleanup
This commit is contained in:
parent
c49d463858
commit
a8bc7521f6
|
@ -23,6 +23,7 @@
|
|||
* Added Deno support: the library and CLI can now be experimentally used with the [Deno runtime](https://deno.com)
|
||||
* `deno run --allow-net --allow-read=. bin/gamedig.js --type tf2 127.0.0.1`
|
||||
* Added code examples.
|
||||
* Added Epic Online Services protocol.
|
||||
|
||||
#### Games
|
||||
* Added support by @dgibbs64: Eco (2018), Core Keeper (2022), ARMA: Reforger (2022),
|
||||
|
@ -39,6 +40,7 @@ San Andreas OpenMP.
|
|||
a placeholder in the `players` field.
|
||||
* Fixed wrong field being parsed for `maxplayers` on Doom3.
|
||||
* Stabilized field `numplayers`.
|
||||
* Added support by @GuilhermeWerner: ARK: Survival Ascended (2023).
|
||||
|
||||
### 4.1.0
|
||||
* Replace `compressjs` dependency by `seek-bzip` to solve some possible import issues.
|
||||
|
|
|
@ -8,6 +8,7 @@ aoe2|Age of Empires 2 (1999)|ase|port_query=27224
|
|||
alienarena|Alien Arena (2004)|quake2|port_query=27910
|
||||
alienswarm|Alien Swarm (2010)|valve|port=27015
|
||||
arkse|Ark: Survival Evolved (2017)|valve|port=7777,port_query=27015
|
||||
asa|Ark: Survival Ascended (2023)|asa|port=7777
|
||||
assettocorsa|Assetto Corsa (2014)|assettocorsa|port=9610
|
||||
atlas|Atlas (2018)|valve|port=5761,port_query_offset=51800
|
||||
avorion|Avorion (2020)|valve|port=27000,port_query_offset=20
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"version": "4.1.0",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"axios": "^1.6.1",
|
||||
"cheerio": "^1.0.0-rc.12",
|
||||
"gbxremote": "^0.2.1",
|
||||
"got": "^13.0.0",
|
||||
|
@ -396,6 +397,11 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"node_modules/available-typed-arrays": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
|
||||
|
@ -408,6 +414,16 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz",
|
||||
"integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.15.0",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
|
@ -578,6 +594,17 @@
|
|||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dependencies": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
|
@ -716,6 +743,14 @@
|
|||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/doctrine": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
||||
|
@ -1366,6 +1401,25 @@
|
|||
"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.3",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
||||
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||
}
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"debug": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/for-each": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
||||
|
@ -1375,6 +1429,19 @@
|
|||
"is-callable": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"dependencies": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/form-data-encoder": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz",
|
||||
|
@ -2118,6 +2185,25 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"dependencies": {
|
||||
"mime-db": "1.52.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.6"
|
||||
}
|
||||
},
|
||||
"node_modules/mimic-response": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz",
|
||||
|
@ -2411,6 +2497,11 @@
|
|||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
||||
|
@ -3353,12 +3444,27 @@
|
|||
"is-shared-array-buffer": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="
|
||||
},
|
||||
"available-typed-arrays": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
|
||||
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "1.6.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz",
|
||||
"integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.15.0",
|
||||
"form-data": "^4.0.0",
|
||||
"proxy-from-env": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
|
@ -3495,6 +3601,14 @@
|
|||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
|
@ -3591,6 +3705,11 @@
|
|||
"object-keys": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="
|
||||
},
|
||||
"doctrine": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
|
||||
|
@ -4064,6 +4183,11 @@
|
|||
"integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==",
|
||||
"dev": true
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.15.3",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
||||
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q=="
|
||||
},
|
||||
"for-each": {
|
||||
"version": "0.3.3",
|
||||
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
|
||||
|
@ -4073,6 +4197,16 @@
|
|||
"is-callable": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"form-data": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.8",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"form-data-encoder": {
|
||||
"version": "2.1.4",
|
||||
"resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz",
|
||||
|
@ -4596,6 +4730,19 @@
|
|||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.52.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
|
||||
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.35",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
|
||||
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
|
||||
"requires": {
|
||||
"mime-db": "1.52.0"
|
||||
}
|
||||
},
|
||||
"mimic-response": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz",
|
||||
|
@ -4805,6 +4952,11 @@
|
|||
"resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="
|
||||
},
|
||||
"proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
||||
|
|
|
@ -52,6 +52,7 @@
|
|||
"README.md"
|
||||
],
|
||||
"dependencies": {
|
||||
"axios": "^1.6.1",
|
||||
"cheerio": "^1.0.0-rc.12",
|
||||
"gbxremote": "^0.2.1",
|
||||
"got": "^13.0.0",
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
import Epic from './epic.js'
|
||||
|
||||
export default class asa extends Epic {
|
||||
constructor () {
|
||||
super()
|
||||
|
||||
// OAuth2 credentials extracted from ARK: Survival Ascended files.
|
||||
this.clientId = 'xyza7891muomRmynIIHaJB9COBKkwj6n'
|
||||
this.clientSecret = 'PP5UGxysEieNfSrEicaD1N2Bb3TdXuD7xHYcsdUHZ7s'
|
||||
this.deploymentId = 'ad9a8feffb3b4b2ca315546f038c3ae2'
|
||||
}
|
||||
}
|
|
@ -0,0 +1,107 @@
|
|||
import Core from './core.js'
|
||||
import axios from 'axios'
|
||||
|
||||
export default class Epic extends Core {
|
||||
constructor () {
|
||||
super()
|
||||
|
||||
/**
|
||||
* To get information about game servers using Epic's EOS, you need some credentials to authenticate using OAuth2.
|
||||
*
|
||||
* https://dev.epicgames.com/docs/web-api-ref/authentication
|
||||
*
|
||||
* These credentials can be provided by the game developers or extracted from the game's files.
|
||||
*/
|
||||
this.clientId = null
|
||||
this.clientSecret = null
|
||||
this.deploymentId = null
|
||||
this.epicApi = 'https://api.epicgames.dev'
|
||||
this.accessToken = null
|
||||
}
|
||||
|
||||
async run (state) {
|
||||
await this.getAccessToken()
|
||||
await this.queryInfo(state)
|
||||
await this.cleanup(state)
|
||||
}
|
||||
|
||||
async getAccessToken () {
|
||||
this.logger.debug('Requesting acess token ...')
|
||||
|
||||
const url = `${this.epicApi}/auth/v1/oauth/token`
|
||||
const body = `grant_type=client_credentials&deployment_id=${this.deploymentId}`
|
||||
const headers = {
|
||||
Authorization: `Basic ${Buffer.from(`${this.clientId}:${this.clientSecret}`).toString('base64')}`,
|
||||
'Content-Type': 'application/x-www-form-urlencoded'
|
||||
}
|
||||
|
||||
this.logger.debug(`POST: ${url}`)
|
||||
const response = await axios.post(url, body, { headers })
|
||||
if (response.status !== 200) {
|
||||
throw new Error('Failed to get OAuth token')
|
||||
}
|
||||
|
||||
this.accessToken = response.data.access_token
|
||||
}
|
||||
|
||||
async queryInfo (state) {
|
||||
const url = `${this.epicApi}/matchmaking/v1/${this.deploymentId}/filter`
|
||||
const body = {
|
||||
criteria: [
|
||||
{
|
||||
key: 'attributes.ADDRESS_s',
|
||||
op: 'EQUAL',
|
||||
value: this.options.address
|
||||
}
|
||||
]
|
||||
}
|
||||
const headers = {
|
||||
'Content-Type': 'application/json',
|
||||
Accept: 'application/json',
|
||||
Authorization: `Bearer ${this.accessToken}`
|
||||
}
|
||||
|
||||
this.logger.debug(`POST: ${url}`)
|
||||
const response = await axios.post(url, body, { headers })
|
||||
if (response.status !== 200) {
|
||||
throw new Error('Failed to get server info')
|
||||
}
|
||||
|
||||
const reader = response.data
|
||||
|
||||
// Epic returns a list of sessions, we need to find the one with the desired port.
|
||||
const hasDesiredPort = (session) => session.attributes.ADDRESSBOUND_s === `0.0.0.0:${this.options.port}` ||
|
||||
session.attributes.ADDRESSBOUND_s === `${this.options.address}:${this.options.port}`
|
||||
|
||||
const desiredServer = reader.sessions.find(hasDesiredPort)
|
||||
|
||||
if (!desiredServer) {
|
||||
throw new Error('Server not found')
|
||||
}
|
||||
|
||||
state.name = desiredServer.attributes.CUSTOMSERVERNAME_s
|
||||
state.map = desiredServer.attributes.MAPNAME_s
|
||||
state.password = desiredServer.attributes.SERVERPASSWORD_b
|
||||
state.maxplayers = desiredServer.settings.maxPublicPlayers
|
||||
|
||||
// If the game returns the player list, we can use it otherwise we use the total players.
|
||||
if (desiredServer.totalPlayers === desiredServer.publicPlayers.length) {
|
||||
for (const player of desiredServer.publicPlayers) {
|
||||
state.players.push({
|
||||
name: player.name,
|
||||
raw: player
|
||||
})
|
||||
}
|
||||
} else {
|
||||
for (let i = 0; i < desiredServer.totalPlayers; i++) {
|
||||
state.players.push('')
|
||||
}
|
||||
}
|
||||
|
||||
state.raw = desiredServer
|
||||
}
|
||||
|
||||
async cleanup (state) {
|
||||
this.accessToken = null
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import armagetron from './armagetron.js'
|
||||
import ase from './ase.js'
|
||||
import asa from './asa.js'
|
||||
import assettocorsa from './assettocorsa.js'
|
||||
import battlefield from './battlefield.js'
|
||||
import buildandshoot from './buildandshoot.js'
|
||||
|
@ -7,6 +8,7 @@ import cs2d from './cs2d.js'
|
|||
import discord from './discord.js'
|
||||
import doom3 from './doom3.js'
|
||||
import eco from './eco.js'
|
||||
import epic from './epic.js'
|
||||
import ffow from './ffow.js'
|
||||
import fivem from './fivem.js'
|
||||
import gamespy1 from './gamespy1.js'
|
||||
|
@ -46,10 +48,10 @@ import vcmp from './vcmp.js'
|
|||
import ventrilo from './ventrilo.js'
|
||||
import warsow from './warsow.js'
|
||||
|
||||
export {
|
||||
armagetron, ase, assettocorsa, battlefield, buildandshoot, cs2d, discord, doom3, eco, ffow, fivem, gamespy1,
|
||||
export {
|
||||
armagetron, ase, asa, assettocorsa, battlefield, buildandshoot, cs2d, discord, doom3, eco, epic, ffow, fivem, gamespy1,
|
||||
gamespy2, gamespy3, geneshift, goldsrc, hexen2, jc2mp, kspdmp, mafia2mp, mafia2online, minecraft,
|
||||
minecraftbedrock, minecraftvanilla, mumble, mumbleping, nadeo, openttd, quake1, quake2, quake3, rfactor, samp,
|
||||
savage2, starmade, starsiege, teamspeak2, teamspeak3, terraria, tribes1, tribes1master, unreal2, ut3, valve,
|
||||
vcmp, ventrilo, warsow
|
||||
vcmp, ventrilo, warsow
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue