Skip to content

Commit f9ab24f

Browse files
committed
🔧 Added promises and removed callbacks
1 parent e9b0c91 commit f9ab24f

File tree

2 files changed

+125
-170
lines changed

2 files changed

+125
-170
lines changed

best-samp-query.js

Lines changed: 124 additions & 169 deletions
Original file line numberDiff line numberDiff line change
@@ -1,192 +1,147 @@
11
const dgram = require("dgram");
22
const iconv = require("iconv-lite")
33

4-
const error = (text) => {
5-
new Error(text);
6-
}
4+
function query (options) {
5+
return new Promise((resolve, reject) => {
6+
let response = { online: 0 };
77

8-
const query = async function (options, callback) {
9-
let self = this;
10-
let response = { online: 0 };
8+
options.port = options.port || 7777;
9+
options.timeout = options.timeout || 1000;
1110

12-
options.port = options.port || 7777;
13-
options.timeout = options.timeout || 1000;
11+
if(!options.host) return reject("Invalid \"host\" passed");
12+
if(!isFinite(options.port) || options.port < 1 || options.port > 65535) return reject(`Invalid port "${options.port}". Port mus"t be larger than 1 and less than 65535`);
1413

15-
if(!options.host) return callback.apply(options, [ "Invalid \"host\" passed" ]);
16-
if(!isFinite(options.port) || options.port < 1 || options.port > 65535) return callback.apply(options, [ `Invalid port "${options.port}". Port mus"t be larger than 1 and less than 65535` ]);
17-
18-
request.call(self, options, "i", async function (error, information) {
19-
if(error) return callback.apply(options, [ error ])
20-
21-
response.address = options.host;
22-
response.port = options.port;
23-
response.hostname = information.hostname;
24-
response.gamemode = information.gamemode;
25-
response.mapname = information.mapname;
26-
response.passworded = Boolean(information.passworded);
27-
response.maxplayers = information.maxplayers;
28-
response.online = information.players;
29-
30-
request.call(self, options, "r", async function (error, rules) {
31-
if(error) return callback.apply(options, [ error ])
32-
33-
rules.lagcomp = rules.lagcomp === "On" ? true : false;
34-
rules.weather = parseInt(rules.weather, 10);
35-
response.rules = rules;
36-
37-
if(response.online > 100) {
38-
response.players = []
39-
40-
return callback.apply(options, [ false, response ])
41-
}
42-
else {
43-
request.call(self, options, "d", function(error, players) {
44-
if(error) return callback.apply(options, [ error ])
45-
46-
response.players = players;
14+
request(options, "i").then((information) => {
15+
response.address = options.host;
16+
response.port = options.port;
17+
response.hostname = information.hostname;
18+
response.gamemode = information.gamemode;
19+
response.mapname = information.mapname;
20+
response.passworded = Boolean(information.passworded);
21+
response.maxplayers = information.maxplayers;
22+
response.online = information.players;
23+
24+
request(options, "r").then((rules) => {
25+
rules.lagcomp = rules.lagcomp === "On" ? true : false;
26+
rules.weather = parseInt(rules.weather, 10);
27+
response.rules = rules;
4728

48-
return callback.apply(options, [ false, response ])
49-
});
50-
}
29+
if(response.online > 100) {
30+
response.players = []
31+
return resolve(response);
32+
}
33+
else {
34+
request(options, "d").then((players) => {
35+
response.players = players;
36+
return resolve(response);
37+
}).catch((e) => {
38+
return reject(e);
39+
});
40+
}
41+
}).catch((e) => {
42+
return reject(e);
43+
});
44+
}).catch((e) => {
45+
return reject(e);
5146
});
5247
});
5348
};
5449

55-
const request = function (options, opcode, callback) {
56-
let socket = dgram.createSocket("udp4");
57-
let packet = Buffer.alloc(11);
58-
59-
packet.write("SAMP");
60-
61-
for(let i = 0; i < 4; ++i) packet[i + 4] = options.host.split(".")[i];
62-
63-
packet[8] = options.port & 0xff;
64-
packet[9] = (options.port >> 8) & 0xff;
65-
packet[10] = opcode.charCodeAt(0);
66-
67-
try {
68-
socket.send(packet, 0, packet.length, options.port, options.host, function (error, bytes) {
69-
if(error) return callback.apply(options, [error]);
70-
});
71-
} catch (error) {
72-
return callback.apply(options, [error]);
73-
}
74-
75-
let controller = undefined;
76-
77-
let onTimeOut = () => {
78-
socket.close();
79-
return callback.apply(options, ["Socket timed out."]);
80-
};
81-
82-
controller = setTimeout(onTimeOut, options.timeout);
83-
84-
socket.on("message", function (message) {
85-
if(controller) clearTimeout(controller);
86-
if(message.length < 11) return callback.apply(options, ["Socket invalid"]);
87-
else {
50+
function request (options, opcode) {
51+
return new Promise((resolve, reject) => {
52+
let socket = dgram.createSocket("udp4");
53+
let packet = Buffer.alloc(11);
54+
55+
packet.write("SAMP");
56+
57+
for(let i = 0; i < 4; ++i) packet[i + 4] = options.host.split(".")[i];
58+
59+
packet[8] = options.port & 0xff;
60+
packet[9] = (options.port >> 8) & 0xff;
61+
packet[10] = opcode.charCodeAt(0);
62+
63+
try {
64+
socket.send(packet, 0, packet.length, options.port, options.host, function (error, bytes) {
65+
if(error) return reject(error);
66+
});
67+
} catch (error) {
68+
return reject(error);
69+
}
70+
71+
let controller = undefined;
72+
73+
let onTimeOut = () => {
8874
socket.close();
89-
90-
message = message.slice(11);
91-
92-
let object = {};
93-
let array = [];
94-
let strlen = 0;
95-
let offset = 0;
96-
97-
try {
98-
if(opcode == "i") {
99-
object.passworded = message.readUInt8(offset);
100-
offset += 1;
101-
102-
object.players = message.readUInt16LE(offset);
103-
offset += 2;
104-
105-
object.maxplayers = message.readUInt16LE(offset);
106-
offset += 2;
107-
108-
strlen = message.readUInt16LE(offset);
109-
offset += 4;
110-
111-
object.hostname = decode(message.slice(offset, (offset += strlen)));
112-
113-
strlen = message.readUInt16LE(offset);
114-
offset += 4;
115-
116-
object.gamemode = decode(message.slice(offset, (offset += strlen)));
117-
118-
strlen = message.readUInt16LE(offset);
119-
offset += 4;
120-
121-
object.mapname = decode(message.slice(offset, (offset += strlen)));
122-
123-
return callback.apply(options, [false, object]);
124-
}
125-
126-
if(opcode == "r") {
127-
let rulecount = message.readUInt16LE(offset);
128-
offset += 2;
129-
130-
let property,
131-
value = undefined;
132-
133-
while(rulecount) {
134-
strlen = message.readUInt8(offset);
135-
++offset;
136-
137-
property = decode(message.slice(offset, (offset += strlen)));
138-
139-
strlen = message.readUInt8(offset);
140-
++offset;
141-
142-
value = decode(message.slice(offset, (offset += strlen)));
143-
144-
object[property] = value;
145-
146-
--rulecount;
75+
return reject("Socket timed out.");
76+
};
77+
78+
controller = setTimeout(onTimeOut, options.timeout);
79+
80+
socket.on("message", function (message) {
81+
if(controller) clearTimeout(controller);
82+
if(message.length < 11) return reject("Socket invalid");
83+
else {
84+
socket.close();
85+
86+
message = message.slice(11);
87+
88+
let object = {};
89+
let array = [];
90+
let strlen = 0;
91+
let offset = 0;
92+
93+
try {
94+
if(opcode == "i") {
95+
object.passworded = message.readUInt8(offset); offset += 1;
96+
object.players = message.readUInt16LE(offset); offset += 2;
97+
object.maxplayers = message.readUInt16LE(offset); offset += 2;
98+
strlen = message.readUInt16LE(offset); offset += 4;
99+
object.hostname = decode(message.slice(offset, (offset += strlen)));
100+
strlen = message.readUInt16LE(offset); offset += 4;
101+
object.gamemode = decode(message.slice(offset, (offset += strlen)));
102+
strlen = message.readUInt16LE(offset); offset += 4;
103+
object.mapname = decode(message.slice(offset, (offset += strlen)));
104+
return resolve(object);
147105
}
148-
149-
return callback.apply(options, [false, object]);
150-
}
151-
152-
if (opcode == "d") {
153-
let playercount = message.readUInt16LE(offset);
154-
offset += 2;
155-
156-
let player = undefined;
157-
158-
while(playercount) {
159-
player = {};
160-
161-
player.id = message.readUInt8(offset);
162-
++offset;
163-
164-
strlen = message.readUInt8(offset);
165-
++offset;
166-
167-
player.name = decode(message.slice(offset, (offset += strlen)));
168-
169-
player.score = message.readUInt32LE(offset);
170-
offset += 4;
171-
172-
player.ping = message.readUInt16LE(offset);
173-
offset += 4;
174-
175-
array.push(player);
176-
177-
--playercount;
106+
if(opcode == "r") {
107+
let rulecount = message.readUInt16LE(offset); offset += 2;
108+
let property, value = undefined;
109+
110+
while(rulecount) {
111+
strlen = message.readUInt8(offset); ++offset;
112+
property = decode(message.slice(offset, (offset += strlen)));
113+
strlen = message.readUInt8(offset); ++offset;
114+
value = decode(message.slice(offset, (offset += strlen)));
115+
object[property] = value;
116+
--rulecount;
117+
}
118+
return resolve(object);
178119
}
179120

180-
return callback.apply(options, [false, array]);
121+
if (opcode == "d") {
122+
let playercount = message.readUInt16LE(offset); offset += 2;
123+
let player = undefined;
124+
125+
while(playercount) {
126+
player = {};
127+
player.id = message.readUInt8(offset); ++offset;
128+
strlen = message.readUInt8(offset); ++offset;
129+
player.name = decode(message.slice(offset, (offset += strlen)));
130+
player.score = message.readUInt32LE(offset); offset += 4;
131+
player.ping = message.readUInt16LE(offset); offset += 4;
132+
array.push(player); --playercount;
133+
}
134+
return resolve(array);
135+
}
136+
} catch (exception) {
137+
return reject(exception);
181138
}
182-
} catch (exception) {
183-
return callback.apply(options, [exception]);
184139
}
185-
}
140+
});
186141
});
187142
};
188143

189-
const decode = (buffer) => {
144+
function decode (buffer) {
190145
return iconv.decode(buffer, "win1251");
191146
};
192147

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "best-samp-query",
33
"description": "Simplified Query API for SAMP: Efficient and easy retrieval of information from the server 🔥",
4-
"version": "1.0.0",
4+
"version": "1.1.0",
55
"main": "best-samp-query.js",
66
"license": "MIT",
77
"author": "daniscript18",

0 commit comments

Comments
 (0)