Advertisement
Guest User

Untitled

a guest
Apr 6th, 2020
42
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.50 KB | None | 0 0
  1. /**********************************************************************************************
  2. * Serverinfo 1.10, by p3tsin
  3. *
  4. ***********************************************************************************************
  5. *
  6. * Description:
  7. * Get status of defined servers (server name, current map, players/maxplayers, etc)
  8. *
  9. *
  10. * Settings:
  11. * Place serverlist.ini in amxmodx/data directory and add the addresses you want.
  12. * (Note MAX_SERVERS definition!)
  13. *
  14. *
  15. * Cvars & Commands:
  16. * srv_format response format for queries
  17. * srv_format2 response format when couldn't get server status
  18. *
  19. * say /servers prints the status of servers defined in serverlist.ini
  20. *
  21. *
  22. * Response format variables:
  23. * $type HL1 / HL2
  24. * $ip ip address
  25. * $host hostname
  26. * $map current map
  27. * $mod modname (e.g. Counter-Strike)
  28. * $players players/maxplayers
  29. * $pw password protected? (Yes/No)
  30. *
  31. * $timeleft time remaining on current map
  32. * $nextmap next map
  33. *
  34. * Changelog:
  35. * 1.00 - Initial release
  36. * 1.01 - Fixed maxplayers showing as 0 when there are no players
  37. * 1.10 - Added $timeleft and $nextmap
  38. * - Improved speed
  39. *
  40. *
  41. * Thanks to:
  42. * Kraugh for helping me with the byte values in the response
  43. *
  44. ***********************************************************************************************/
  45.  
  46.  
  47. #include <amxmodx>
  48. #include <sockets>
  49.  
  50. #define MAX_SERVERS 5 //max. number of servers the plugin can handle
  51. #define DELAY_SHOW 0.5 //delay before showing the results
  52. #define COOLDOWN 3.0 //antiflood for /servers
  53. #define TASK_RECV 321897 //task id for receive_info()
  54.  
  55. new bool:plugin_enabled
  56. new bool:allow_query
  57. new sockets[MAX_SERVERS]
  58. new server_address[MAX_SERVERS][32]
  59. new server_port[MAX_SERVERS]
  60. new servernum
  61.  
  62. new response[MAX_SERVERS][192]
  63. new rules[MAX_SERVERS][2][32] //0: timeleft, 1: nextmap
  64. new rulesgot[MAX_SERVERS]
  65. new totalpackets[MAX_SERVERS]
  66. new part[MAX_SERVERS]
  67.  
  68.  
  69. public plugin_init() {
  70. register_plugin("Serverinfo", "1.10", "p3tsin")
  71. register_clcmd("say /servers", "cmd_servers")
  72.  
  73. register_cvar("srv_format", "* $host .:. $map $players (Timeleft: $timeleft) .:. $ip")
  74. register_cvar("srv_format2","* No response .:. $ip")
  75. }
  76.  
  77. public plugin_cfg() {
  78. new filename[256], datadir[192]
  79. get_localinfo("amxx_datadir", datadir,191)
  80. format(filename,255, "%s/serverlist.ini", datadir)
  81.  
  82. if(file_exists(filename)) {
  83. new line, data[64], txt, address[64]
  84. while(read_file(filename,line++,data,63,txt) > 0) {
  85. if(data[0] == ';' || !txt) continue
  86. else if(servernum == MAX_SERVERS) break
  87. strbreak(data, address,63, data,63)
  88.  
  89. strtok(address, server_address[servernum],31, data,63, ':',1)
  90. server_port[servernum] = str_to_num(data)
  91. servernum++
  92. }
  93. if(servernum > 0) {
  94. plugin_enabled = true
  95. allow_query = true
  96. }
  97. else plugin_enabled = false
  98. }
  99. else {
  100. log_amx("%s not found!", filename)
  101. plugin_enabled = false
  102. }
  103. }
  104.  
  105. public client_putinserver(id) {
  106. if(plugin_enabled) set_task(15.0, "advert",id)
  107. }
  108.  
  109. public advert(id) {
  110. client_print(id,print_chat, "Say /servers to get status of other servers")
  111. return PLUGIN_HANDLED
  112. }
  113.  
  114. public cmd_servers(id) {
  115. if(plugin_enabled) {
  116. if(!allow_query) {
  117. client_print(id,print_chat, "Someone just used this function, please wait a while..")
  118. return PLUGIN_HANDLED
  119. }
  120. else if(connect_servers()) {
  121. allow_query = false
  122. send_info_request()
  123. set_task(COOLDOWN, "antiflood_off")
  124. set_task(DELAY_SHOW, "show_results")
  125. }
  126. else client_print(0,print_chat, "Couldn't connect to server(s)")
  127. return PLUGIN_CONTINUE
  128. }
  129. else client_print(id,print_chat, "No servers defined in serverlist")
  130. return PLUGIN_HANDLED
  131. }
  132.  
  133. public antiflood_off() {
  134. allow_query = true
  135. return PLUGIN_HANDLED
  136. }
  137.  
  138. public show_results() {
  139. remove_task(TASK_RECV)
  140. new message[192]
  141. for(new i = 0; i < servernum; i++) {
  142. if(!strlen(response[i])) {
  143. new address[32]
  144. get_cvar_string("srv_format2", message,191)
  145. format(address,31, "%s:%d", server_address[i], server_port[i])
  146. while(contain(message,"$ip") > -1) replace(message,191, "$ip", address)
  147. }
  148. else {
  149. copy(message,191, response[i])
  150. while(contain(message,"$timeleft") > -1) replace(message,191, "$timeleft", rules[i][0])
  151. while(contain(message,"$nextmap") > -1) replace(message,191, "$nextmap", rules[i][1])
  152. }
  153. client_print(0,print_chat, "%s",message)
  154. }
  155. disconnect_servers()
  156. return PLUGIN_HANDLED
  157. }
  158.  
  159. connect_servers() {
  160. new error, err[40], srv, i
  161. for(i = 0; i < servernum; i++) {
  162. if(sockets[i] > 0) { //already connected
  163. srv++
  164. continue
  165. }
  166.  
  167. sockets[i] = socket_open(server_address[i],server_port[i], SOCKET_UDP,error)
  168. if(sockets[i] <= 0 || error) {
  169. switch(error) {
  170. case 0: err = "no error"
  171. case 1: err = "error while creating socket"
  172. case 2: err = "couldn't resolve hostname"
  173. case 3: err = "couldn't connect to given hostname:port"
  174. }
  175. log_amx("Couldn't connect to %s:%d, error: %s",server_address[i],server_port[i],err)
  176. continue
  177. }
  178. srv++
  179. }
  180. return srv
  181. }
  182.  
  183. disconnect_servers() {
  184. for(new i = 0; i < servernum; i++) {
  185. if(sockets[i] <= 0) continue
  186. socket_close(sockets[i])
  187. sockets[i] = 0
  188. }
  189. return
  190. }
  191.  
  192. public send_info_request() {
  193. new cmd[32], i
  194. setc(cmd,4,0xFF)
  195. format(cmd[4],31,"TSource Engine Query")
  196. setc(cmd[24],1,0x00)
  197. for(i = 0; i < servernum; i++) {
  198. if(sockets[i] <= 0) continue
  199. socket_send(sockets[i], cmd,25)
  200. response[i][0] = 0
  201. }
  202.  
  203. new form[256], bool:req_rules
  204. get_cvar_string("srv_format",form,255)
  205. if(contain(form,"$timeleft") > -1) req_rules = true
  206. else if(contain(form,"$nextmap") > -1) req_rules = true
  207.  
  208. if(req_rules) {
  209. setc(cmd,4,0xFF)
  210. format(cmd[4],31,"W")
  211. setc(cmd[5],1,0x00)
  212. for(i = 0; i < servernum; i++) {
  213. if(sockets[i] <= 0) continue
  214. socket_send(sockets[i], cmd,6)
  215. rules[i][0] = "--:--", rules[i][1] = "-"
  216. part[i] = 0, totalpackets[i] = 0, rulesgot[i] = 0
  217. }
  218. }
  219. set_task(0.1, "receive_info", TASK_RECV, "",0, "b")
  220. return PLUGIN_HANDLED
  221. }
  222.  
  223. public receive_info() {
  224. new recv[1450], len
  225. for(new i = 0; i < servernum; i++) {
  226. if(sockets[i] <= 0) continue
  227. else if(socket_change(sockets[i],1)) {
  228. len = socket_recv(sockets[i], recv,1449)
  229. parse_response(recv,i,len)
  230. }
  231. }
  232. return PLUGIN_HANDLED
  233. }
  234.  
  235. parse_response(text[],id,len) {
  236. new end = strlen(text)+1
  237. new type = text[4], i
  238.  
  239. switch(type) {
  240. case 'A': { //challenge
  241. new cmd[10]
  242. setc(cmd,4,0xFF)
  243. cmd[4] = 'V'
  244. for(i = 0; i < 4; i++) cmd[5+i] = text[5+i]
  245. socket_send(sockets[id], cmd,9)
  246. }
  247. case 'm', 'I': { //status: m = hl1, I = hl2
  248. new info[6][64]
  249. copy(info[0],63, text[5]) //data till the first null
  250. for(i = 1; i < 6; i++) { //last value is for password, no more needed
  251. copy(info[i],63, text[end])
  252. end += strlen(info[i])+1
  253. }
  254.  
  255. if(!info[5][0]) { //no players on the server, info[5][0] == null
  256. info[5][1] = text[end]
  257. info[5][5] = text[end+4]
  258. }
  259.  
  260. new message[192], players[10], game[10]
  261. get_cvar_string("srv_format", message,191)
  262. format(players,9, "%d/%d", info[5][0], info[5][1])
  263. format(game,9, "HL%d", type == 'm' ? 1 : 2)
  264.  
  265. while(contain(message,"$type") > -1) replace(message,191, "$type", game)
  266. while(contain(message,"$ip") > -1) replace(message,191, "$ip", info[0])
  267. while(contain(message,"$host") > -1) replace(message,191, "$host", info[1])
  268. while(contain(message,"$map") > -1) replace(message,191, "$map", info[2])
  269. while(contain(message,"$mod") > -1) replace(message,191, "$mod", info[4])
  270. while(contain(message,"$players") > -1) replace(message,191, "$players", players)
  271. while(contain(message,"$pw") > -1) replace(message,191, "$pw", info[5][5] ? "Yes" : "No")
  272.  
  273. copy(response[id],191, message)
  274. }
  275. default: { //rules
  276. if(rulesgot[id] == 2) return //already got both values, skip the packet
  277. else if(text[0] == -2) {
  278. if(!part[id]) totalpackets[id] = text[8]
  279. if(0 < part[id] < totalpackets[id]) end = 0
  280. else end = 16
  281. }
  282. else end = 7
  283.  
  284. new name[64], rlen
  285. while(end < len) {
  286. rlen = copy(name,63, text[end])
  287. if(equal(name,"amx_timeleft")) {
  288. end += 13, rulesgot[id]++
  289. copy(rules[id][0],31, text[end])
  290. }
  291. else if(equal(name,"amx_nextmap")) {
  292. end += 12, rulesgot[id]++
  293. copy(rules[id][1],31, text[end])
  294. }
  295. else end += rlen+1 //skip cvar name
  296. end += strlen(text[end])+1 //skip cvar value
  297.  
  298. if(rulesgot[id] == 2) break //got both values, ignore rest
  299. }
  300. part[id]++
  301. }
  302. }
  303. return
  304. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement