ddmaster 2.6.1 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ddmaster",
3
- "version": "2.6.1",
3
+ "version": "3.1.0",
4
4
  "description": "Позволяет опрашивать мастер-сервер дднета",
5
5
  "main": "index.js",
6
6
  "scripts": {
@@ -13,7 +13,8 @@
13
13
  "author": "0374flop",
14
14
  "license": "MIT",
15
15
  "type": "commonjs",
16
- "dependencies": {
17
- "loger0374": "^0.2.0"
16
+ "bin": "./bin.js",
17
+ "devDependencies": {
18
+ "@types/node": "^25.2.3"
18
19
  }
19
20
  }
package/src/bin.ts ADDED
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+
3
+ const ddmaster = require('./index.js');
4
+
5
+
6
+ const [command, ...args] = process.argv.slice(2);
7
+
8
+ if (command === "find") {
9
+ ddmaster.findDDNetPlayerByName(args.join(" ")).then(async (servers: import('./types').DDNetServer[]) => {
10
+ if (servers.length === 0) {
11
+ console.log("Player not found on any server.");
12
+ return;
13
+ }
14
+
15
+ console.log(`Count of servers: ${servers.length}`);
16
+ console.log((await ddmaster.getDDNetServers(servers)).join("\n"));
17
+ }).catch((err: Error) => {
18
+ console.error('Error:', err);
19
+ });
20
+ } else if (command === "list") {
21
+ ddmaster.getDDNetServers().then((servers: string[]) => {
22
+ console.log(servers.join("\n"));
23
+ }).catch((err: Error) => {
24
+ console.error('Error:', err);
25
+ });
26
+ } else if (command === "raw") {
27
+ ddmaster.getrawDDNetServers().then((servers: import('./types').DDNetServer[]) => {
28
+ console.log(JSON.stringify(servers, null, 2));
29
+ }).catch((err: Error) => {
30
+ console.error('Error:', err);
31
+ });
32
+ } else if (command === "info") {
33
+ ddmaster.getinfoserver(args[0]).then((server: import('./types').DDNetServer) => {
34
+ console.log(JSON.stringify(server, null, 2));
35
+ }).catch((err: Error) => {
36
+ console.error('Error:', err);
37
+ });
38
+ } else {
39
+ console.log("Usage:");
40
+ console.log(" find <playerName> - Найти сервера с игроком");
41
+ console.log(" list - Получить список всех серверов");
42
+ console.log(" raw - Получить сырые данные серверов");
43
+ console.log(" info <address> - Получить информацию о сервере по адресу");
44
+ }
@@ -1,8 +1,7 @@
1
1
  /**
2
2
  * ddmaster
3
3
  */
4
- const lib = require('./serverlist');
5
- // по моему такое декларирование не работает.
4
+ const lib = require('./serverlist.js');
6
5
 
7
6
  module.exports = lib;
8
7
 
@@ -3,34 +3,29 @@
3
3
 
4
4
  "use strict";
5
5
 
6
- const DebugLoger = require('loger0374');
7
- const loger = new DebugLoger('ddmaster', false, true, null, true);
8
-
9
6
  if (typeof fetch === 'undefined') {
10
7
  try {
11
8
  require.resolve('node-fetch');
12
- loger.log('Using node-fetch polyfill');
13
9
  } catch (e) {
14
10
  throw new Error('Node.js <18, npm install node-fetch');
15
11
  }
16
12
 
17
13
  const nodeFetch = require('node-fetch');
18
14
  global.fetch = nodeFetch.default || nodeFetch;
19
- loger.log('Polyfilled fetch with node-fetch');
20
15
  }
21
16
 
22
17
  /**
23
18
  * Делает запрос на мастер сервер ДДНета.
24
19
  * @returns Сервера ДДНета но в сыром виде.
25
20
  */
26
- async function getrawDDNetServers() {
21
+ async function getrawDDNetServers(): Promise<{ servers: import('./types').DDNetServer[] } | null> {
27
22
  try {
28
23
  const response = await fetch('https://master1.ddnet.org/ddnet/15/servers.json');
29
24
  if (!response.ok) throw new Error(`Ошибка при запросе: ${response.status}`);
30
25
  const data = await response.json();
31
26
  return data;
32
27
  } catch (error) {
33
- loger.error(error);
28
+ console.error(error);
34
29
  return null;
35
30
  }
36
31
  }
@@ -40,10 +35,9 @@ async function getrawDDNetServers() {
40
35
  * @param {string} addr - берёт примерно такое "tw-0.7+udp://152.89.254.27:8310"
41
36
  * @returns {string|null} 152.89.254.27:8310 возвращает чистый адрес (если addr не валидный то null)
42
37
  */
43
- function convertudptw(addr) {
38
+ function convertudptw(addr: string) {
44
39
  if (typeof addr !== 'string') return null;
45
40
  const match = addr.match(/(\d{1,3}(\.\d{1,3}){3}:\d+)/);
46
- loger.log('convertudptw', addr, '->', match ? match[1] : null);
47
41
  return match ? match[1] : null;
48
42
  }
49
43
 
@@ -54,16 +48,15 @@ function convertudptw(addr) {
54
48
  */
55
49
  async function getDDNetServers(data = null) {
56
50
  try {
57
- const servers = data || (await getrawDDNetServers()).servers;
51
+ const servers = data || (await getrawDDNetServers())?.servers;
58
52
  if (!servers) {
59
- loger.error('Нет серверов в данных');
60
53
  return [];
61
54
  }
62
55
 
63
- const ipv4WithPorts = [];
56
+ const ipv4WithPorts: string[] = [];
64
57
 
65
58
  for (const server of servers) {
66
- server.addresses.forEach(addr => {
59
+ server.addresses.forEach((addr: string) => {
67
60
  const converted = convertudptw(addr);
68
61
  if (converted == null) return;
69
62
  ipv4WithPorts.push(converted);
@@ -71,7 +64,7 @@ async function getDDNetServers(data = null) {
71
64
  }
72
65
  return [...new Set(ipv4WithPorts)];
73
66
  } catch (err) {
74
- loger.error('Ошибка getDDNetServers:', err.message);
67
+ console.error(err);
75
68
  return [];
76
69
  }
77
70
  }
@@ -86,7 +79,7 @@ async function getDDNetServers(data = null) {
86
79
  * @returns {Promise<Array>} Массив серверов (как в getrawDDNetServers().servers),
87
80
  * на которых найден игрок.
88
81
  */
89
- async function findDDNetPlayerByName(playerName, data = null) {
82
+ async function findDDNetPlayerByName(playerName: string, data = null) {
90
83
  if (typeof playerName !== 'string') {
91
84
  throw new TypeError('playerName должен быть строкой');
92
85
  }
@@ -94,7 +87,6 @@ async function findDDNetPlayerByName(playerName, data = null) {
94
87
  try {
95
88
  const raw = data || await getrawDDNetServers();
96
89
  if (!raw || !Array.isArray(raw.servers)) {
97
- loger.error('Некорректные данные серверов');
98
90
  return [];
99
91
  }
100
92
 
@@ -104,36 +96,37 @@ async function findDDNetPlayerByName(playerName, data = null) {
104
96
  const info = server.info;
105
97
  if (!info || !Array.isArray(info.clients)) continue;
106
98
 
107
- const hasPlayer = info.clients.some(client => client.name === playerName);
99
+ const hasPlayer = info.clients.some((client: import('./types').ServerClient) => client.name === playerName);
108
100
  if (hasPlayer) {
109
101
  resultServers.push(server);
110
102
  }
111
103
  }
112
104
  return resultServers;
113
105
  } catch (err) {
114
- loger.error('Ошибка при поиске игрока:', err);
106
+ console.error(err);
115
107
  return [];
116
108
  }
117
109
  }
118
110
 
119
- function filterbycommunity(servers, community) {
111
+ function filterbycommunity(servers: import('./types').DDNetServer[], community: string) {
120
112
  return servers.filter(server => server.community === community);
121
113
  }
122
114
 
123
- function filterbylocation(servers, location) {
115
+ function filterbylocation(servers: import('./types').DDNetServer[], location: string) {
124
116
  return servers.filter(server => server.location?.toLowerCase() === location?.toLowerCase());
125
117
  }
126
118
 
127
- function filterbylocationincludes(servers, location) {
119
+ function filterbylocationincludes(servers: import('./types').DDNetServer[], location: string) {
128
120
  return servers.filter(server => server.location?.toLowerCase().includes(location?.toLowerCase()));
129
121
  }
130
122
 
131
- async function getinfoserver(address) {
123
+ async function getinfoserver(address: string) {
132
124
  const servers = await getrawDDNetServers();
133
- const server = servers.servers.find(server =>
134
- convertudptw(server.addresses[0]) === address
135
- );
125
+ const server = servers?.servers.find((server: import('./types').DDNetServer) => {
126
+ if (server.addresses) return false;
127
+ return convertudptw(server.addresses[0]) === address;
128
+ });
136
129
  return server;
137
130
  }
138
131
 
139
- module.exports = { getDDNetServers, getrawDDNetServers, convertudptw, findDDNetPlayerByName, filterbycommunity, filterbylocation, filterbylocationincludes, loger, getinfoserver };
132
+ module.exports = { getDDNetServers, getrawDDNetServers, convertudptw, findDDNetPlayerByName, filterbycommunity, filterbylocation, filterbylocationincludes, getinfoserver };
package/src/types.ts ADDED
@@ -0,0 +1,43 @@
1
+ export interface DDNetServer {
2
+ addresses: string[];
3
+ community: string;
4
+ location: string;
5
+ info: ServerInfo;
6
+ }
7
+
8
+ export interface ServerInfo {
9
+ max_clients: number;
10
+ max_players: number;
11
+ passworded: boolean;
12
+ game_type: string;
13
+ flag: number;
14
+ name: string;
15
+ map: ServerMap;
16
+ version: string;
17
+ client_score_kind: string;
18
+ requires_login: boolean;
19
+ clients: ServerClient[];
20
+ }
21
+
22
+ export interface ServerMap {
23
+ name: string;
24
+ sha256: string;
25
+ size: number;
26
+ }
27
+
28
+ export interface ServerClient {
29
+ name: string;
30
+ clan: string;
31
+ country: number;
32
+ score: number;
33
+ is_player: boolean;
34
+ skin: ClientSkin;
35
+ afk: boolean;
36
+ team: number;
37
+ }
38
+
39
+ export interface ClientSkin {
40
+ name: string;
41
+ color_body?: number;
42
+ color_feet?: number;
43
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ // Visit https://aka.ms/tsconfig to read more about this file
3
+ "compilerOptions": {
4
+ // File Layout
5
+ "rootDir": "./src",
6
+ "outDir": "./lib",
7
+
8
+ // Environment Settings
9
+ // See also https://aka.ms/tsconfig/module
10
+ "module": "nodenext",
11
+ "target": "esnext",
12
+ "types": ["node"],
13
+ // For nodejs:
14
+ // "lib": ["esnext"],
15
+ // "types": ["node"],
16
+ // and npm install -D @types/node
17
+
18
+ // Other Outputs
19
+ "sourceMap": false,
20
+ "declaration": true,
21
+ "declarationMap": false,
22
+
23
+ // Stricter Typechecking Options
24
+ "noUncheckedIndexedAccess": true,
25
+ "exactOptionalPropertyTypes": true,
26
+
27
+ // Style Options
28
+ // "noImplicitReturns": true,
29
+ // "noImplicitOverride": true,
30
+ // "noUnusedLocals": true,
31
+ // "noUnusedParameters": true,
32
+ // "noFallthroughCasesInSwitch": true,
33
+ // "noPropertyAccessFromIndexSignature": true,
34
+
35
+ // Recommended Options
36
+ "strict": true,
37
+ "verbatimModuleSyntax": true,
38
+ "isolatedModules": true,
39
+ "noUncheckedSideEffectImports": true,
40
+ "moduleDetection": "force",
41
+ "skipLibCheck": true,
42
+ }
43
+ }