0 Members and 1 Guest are viewing this topic.
#=============================================================================== def parse(self,server=0,version=265):#=============================================================================== '''Returns class Refresh() with all of the parsed information''' self.SolSock[server].send("REFRESHX\r\n") self.SolSock[server].recv(10)##Recieve the command first. ##Then the packet. if version == 265: packed = self.SolSock[server].recv(1608) refreshx = struct.unpack('= 800B 32B 32H 32B 32H 32l 32B 32B 32B 32B 32B 32f 32f ffff HHHH 17B 2l H 3B B 17B',packed) ##offsets for parsing offset = [25,800,832,864,896,928,960,992,1120,1152,1184,1185,1186, 1187,1188,1192,1209,1210,1211,1212,1213,1214,1215,1216] if version == 270: packed = self.SolSock[server].recv(1992) ##Assuming HWID is an unsigned char, will parse as such refreshx = struct.unpack('= 800B 32B 32H 32B 32H 32l 32B 32B 32B 32B 32B 32f 32f 384B ffff HHHH 17B 2l H 3B B 17B',packed) ##Change the offsets here, and add HWID offset at the end, ##so none of the other code gets broken or needs to be changed. offset = [25,800,832,864,896,928,960,992,1120,1152,1568,1567,1568, 1569,1570,1574,1591,1592,1593,1594,1595,1596,1597,1598,1184] self.refresh = Refresh() for i in range(32): temp = "" nicklen = refreshx[offset[0]*i] if nicklen > 0: for x in range(nicklen): if x == 0: temp += chr(refreshx[offset[0]*i+1]) else: temp += chr(refreshx[offset[0]*i+x+1]) self.refresh.names.append(temp) self.refresh.teams.append(refreshx[offset[1]+i]) self.refresh.kills.append(refreshx[offset[2]+i]) self.refresh.caps.append(refreshx[offset[3]+i]) self.refresh.deaths.append(refreshx[offset[4]+i]) self.refresh.pings.append(refreshx[offset[5]+i]) self.refresh.ids.append(refreshx[offset[6]+i]) t="" for j in range(4): t+=str(refreshx[offset[7]+i+j])+"." t.rstrip('.') self.refresh.ips.append(t) self.refresh.xlocs.append(refreshx[offset[8]+i]) self.refresh.ylocs.append(refreshx[offset[9]+i]) if version == 270: t="" for j in range(12): ##Assuming HWID is an unsigned byte ##Parsing it as a unicode char t+=chr(refreshx[offset[23]+i+j]) self.refresh.HWIDs.append(t) self.refresh.redFX = refreshx[offset[10]] self.refresh.redFY = refreshx[offset[11]] self.refresh.blueFX = refreshx[offset[12]] self.refresh.blueFY = refreshx[offset[13]] for i in range(4): self.refresh.scores.append(refreshx[offset[14]+i]) temp = "" maplen = refreshx[offset[15]] maplen = int(maplen) for i in range(maplen): temp += chr(refreshx[offset[15]+i+1]) self.refresh.map = temp self.refresh.limit = refreshx[offset[16]] self.refresh.timeleft = refreshx[offset[17]] self.refresh.games = refreshx[offset[18]] self.refresh.maxp = refreshx[offset[19]] self.refresh.maxs = refreshx[offset[20]] self.refresh.passw = refreshx[offset[21]] temp = "" maplen = refreshx[offset[22]] maplen = int(maplen) for i in range(maplen): temp += chr(refreshx[offset[22]+i+1]) self.refresh.nexm = temp return(self.refresh) class Refresh(): def __init__(self): self.names = [] self.teams = [] self.kills = [] self.caps = [] self.deaths = [] self.pings = [] self.ids = [] self.ips = [] self.xlocs = [] self.ylocs = [] self.HWIDs = [] self.redFX = None self.redFY = None self.blueFX = None self.blueFY = None self.scores = [] self.map = None self.timemax = None self.timeleft = None self.limit = None self.games = None self.maxp = None self.maxs = None self.passw = None self.nextm = None
#ifndef _H_SOLDATINFOX_#define _H_SOLDATINFOX_// Comment out this line if you want to compile for 1.5.1//#define OLDSOLDAT// soldatinfo.h originally by ramirez// modified constructor to 'default'// defined REFRESH parsing as a method (for multiple acc)#include <vector>#include <string>#include <sstream>#include <stdexcept>#ifndef OLDSOLDAT#define REFRESHX_PACKET_SIZE 1992#else#define REFRESHX_PACKET_SIZE 1608#endifstruct playerX{ unsigned char namelen; // 1 char name[25]; // 24 unsigned char hwidlen; // 1 char hwid[12]; // 11 unsigned char team; // 1 unsigned short kills; // 2 unsigned char caps; // 1 unsigned short deaths; // 2 signed long ping; // 4 unsigned char id; // 1 unsigned char ip[4]; // 4 float x; // 4 float y; // 4 // 1 + 24 + 1 + 2 + 1 + 2 + 4 + 1 + 4 + 4 + 4 = 48};struct refreshX{ struct playerX players[32]; float redflagx; float redflagy; float blueflagx; float blueflagy; unsigned short alphascore; unsigned short bravoscore; unsigned short charliescore; unsigned short deltascore; unsigned char currentmaplen; char currentmap[17]; unsigned long timelimit; unsigned long timeleft; unsigned int limit; unsigned char gamestyle; unsigned char maxplayers; unsigned char maxspectators; unsigned char password; unsigned char nextmaplen; char nextmap[17]; bool check;};// players * 32/*# Player (1856 Bytes) * Names (32*25 Bytes; first Byte (unsigned char) indicates length of the nick) * Tagid (32*10 Bytes; char) * Teams (32*1 Byte; 0=DM Team, 1..4=Alpha..Delta, 5=Spectator) * Kills (32*2 Bytes; unsigned short) * Caps (32*1 Byte; unsigned char) * Deaths (32*2 Bytes; unsigned short) * Pings (32*4 Bytes; signed long) * IDs (32*1 Byte; unsigned char) * IPs (32*4 Bytes; each byte can be decoded as unsigned char then put together in the given order to a 0.0.0.0 format; or unpack as unsigned long (big endian) and use long2ip()) * X Locations (32*4 Bytes; float) * Y Locations (32*4 Bytes; float) */#ifndef OLDSOLDAT#define XNAMELEN_OFFSET 0#define XNAMELEN_SIZE 1#define XNAME_OFFSET 1#define XNAME_SIZE 24#define XHWIDLEN_OFFSET 25*32#define XHWIDLEN_SIZE 1#define XHWID_OFFSET 1#define XHWID_SIZE 11#define XTEAM_OFFSET 37*32#define XTEAM_SIZE 1#define XKILLS_OFFSET 38*32#define XKILLS_SIZE 2#define XCAPS_OFFSET 49*32#define XCAPS_SIZE 1#define XDEATHS_OFFSET 41*32#define XDEATHS_SIZE 2#define XPINGS_OFFSET 43*32#define XPINGS_SIZE 4#define XID_OFFSET 47*32#define XID_SIZE 1#define XIP_OFFSET 48*32#define XIP_SIZE 4#define XLOCX_OFFSET 52*32#define XLOCX_SIZE 4#define XLOCY_OFFSET 56*32#define XLOCY_SIZE 4// Rest/*# Red Flag X Location (4 Bytes; float)# Red Flag Y Location (4 Bytes; float)# Blue Flag X Location (4 Bytes; float)# Blue Flag Y Location (4 Bytes; float)# Team Scores (4*2 Bytes; unsigned short)# Map Name (17 Bytes; first Byte (unsigned char) indicates length)# Time Limit (4 Bytes; unsigned long; in Ticks)# Time Left (4 Bytes; unsigned long; in Ticks)# Cap/Kill Limit (2 Bytes; unsigned short)# Gamestyle (1 Byte; unsigned char; 0=DM, 1=PM, 2=TM, 3=CTF, 4=RM, 5=INF, 6=HTF)# Max Players (1 Byte; unsigned char)# Max Spectators (1 Byte; unsigned char)# Game Passworded? (1 Byte; boolean)# Next Map (17 Bytes; first Byte (unsigned char) indicates length) */#define XREDFLAGX_OFFSET 1920#define XREDFLAGX_SIZE 4#define XREDFLAGY_OFFSET 1924#define XREDFLAGY_SIZE 4#define XBLUEFLAGX_OFFSET 1928#define XBLUEFLAGX_SIZE 4#define XBLUEFLAGY_OFFSET 1932#define XBLUEFLAGY_SIZE 4#define XALPHATEAMSCORE_OFFSET 1936#define XALPHATEAMSCORE_SIZE 2#define XBRAVOTEAMSCORE_OFFSET 1938#define XBRAVOTEAMSCORE_SIZE 2#define XCHARLIETEAMSCORE_OFFSET 1940#define XCHARLIETEAMSCORE_SIZE 2#define XDELTATEAMSCORE_OFFSET 1942#define XDELTATEAMSCORE_SIZE 2#define XCURRENTMAPLEN_OFFSET 1944#define XCURRENTMAPLEN_SIZE 1#define XCURRENTMAP_OFFSET 1945#define XCURRENTMAP_SIZE 16#define XTIMELIMIT_OFFSET 1961#define XTIMELIMIT_SIZE 4#define XTIMELEFT_OFFSET 1965#define XTIMELEFT_SIZE 4#define XLIMIT_OFFSET 1969#define XLIMIT_SIZE 2#define XGAMESTYLE_OFFSET 1971#define XGAMESTYLE_SIZE 1#define XMAXPLAYERS_OFFSET 1972#define XMAXPLAYERS_SIZE 1#define XMAXSPECTATORS_OFFSET 1973#define XMAXSPECTATORS_SIZE 1#define XPASSWORD_OFFSET 1974#define XPASSWORD_SIZE 1#define XNEXTMAPLEN_OFFSET 1975#define XNEXTMAPLEN_SIZE 1#define XNEXTMAP_OFFSET 1976#define XNEXTMAP_SIZE 16#else// players * 32/*# Player (1536 Bytes) * Names (32*25 Bytes; first Byte (unsigned char) indicates length of the nick) * hwid (32*12 Bytes; first Byte (unsigned char) indicates length of the nick) * Teams (32*1 Byte; 0=DM Team, 1..4=Alpha..Delta, 5=Spectator) * Kills (32*2 Bytes; unsigned short) * Caps (32*1 Byte; unsigned char) * Deaths (32*2 Bytes; unsigned short) * Pings (32*4 Bytes; signed long) * IDs (32*1 Byte; unsigned char) * IPs (32*4 Bytes; each byte can be decoded as unsigned char then put together in the given order to a 0.0.0.0 format; or unpack as unsigned long (big endian) and use long2ip()) * X Locations (32*4 Bytes; float) * Y Locations (32*4 Bytes; float) */#define XNAMELEN_OFFSET 0#define XNAMELEN_SIZE 1#define XNAME_OFFSET 1#define XNAME_SIZE 24#define XTEAM_OFFSET 25*32#define XTEAM_SIZE 1#define XKILLS_OFFSET 26*32#define XKILLS_SIZE 2#define XCAPS_OFFSET 28*32#define XCAPS_SIZE 1#define XDEATHS_OFFSET 29*32#define XDEATHS_SIZE 2#define XPINGS_OFFSET 31*32#define XPINGS_SIZE 4#define XID_OFFSET 35*32#define XID_SIZE 1#define XIP_OFFSET 36*32#define XIP_SIZE 4#define XLOCX_OFFSET 40*32#define XLOCX_SIZE 4#define XLOCY_OFFSET 44*32#define XLOCY_SIZE 4// Rest/*# Red Flag X Location (4 Bytes; float)# Red Flag Y Location (4 Bytes; float)# Blue Flag X Location (4 Bytes; float)# Blue Flag Y Location (4 Bytes; float)# Team Scores (4*2 Bytes; unsigned short)# Map Name (17 Bytes; first Byte (unsigned char) indicates length)# Time Limit (4 Bytes; unsigned long; in Ticks)# Time Left (4 Bytes; unsigned long; in Ticks)# Cap/Kill Limit (2 Bytes; unsigned short)# Gamestyle (1 Byte; unsigned char; 0=DM, 1=PM, 2=TM, 3=CTF, 4=RM, 5=INF, 6=HTF)# Max Players (1 Byte; unsigned char)# Max Spectators (1 Byte; unsigned char)# Game Passworded? (1 Byte; boolean)# Next Map (17 Bytes; first Byte (unsigned char) indicates length) */#define XREDFLAGX_OFFSET 1536#define XREDFLAGX_SIZE 4#define XREDFLAGY_OFFSET 1540#define XREDFLAGY_SIZE 4#define XBLUEFLAGX_OFFSET 1544#define XBLUEFLAGX_SIZE 4#define XBLUEFLAGY_OFFSET 1548#define XBLUEFLAGY_SIZE 4#define XALPHATEAMSCORE_OFFSET 1552#define XALPHATEAMSCORE_SIZE 2#define XBRAVOTEAMSCORE_OFFSET 1554#define XBRAVOTEAMSCORE_SIZE 2#define XCHARLIETEAMSCORE_OFFSET 1556#define XCHARLIETEAMSCORE_SIZE 2#define XDELTATEAMSCORE_OFFSET 1558#define XDELTATEAMSCORE_SIZE 2#define XCURRENTMAPLEN_OFFSET 1560#define XCURRENTMAPLEN_SIZE 1#define XCURRENTMAP_OFFSET 1561#define XCURRENTMAP_SIZE 16#define XTIMELIMIT_OFFSET 1577#define XTIMELIMIT_SIZE 4#define XTIMELEFT_OFFSET 1581#define XTIMELEFT_SIZE 4#define XLIMIT_OFFSET 1585#define XLIMIT_SIZE 2#define XGAMESTYLE_OFFSET 1587#define XGAMESTYLE_SIZE 1#define XMAXPLAYERS_OFFSET 1588#define XMAXPLAYERS_SIZE 1#define XMAXSPECTATORS_OFFSET 1589#define XMAXSPECTATORS_SIZE 1#define XPASSWORD_OFFSET 1590#define XPASSWORD_SIZE 1#define XNEXTMAPLEN_OFFSET 1591#define XNEXTMAPLEN_SIZE 1#define XNEXTMAP_OFFSET 1592#define XNEXTMAP_SIZE 16#endifclass SoldatInfoX{ public: struct refreshX packet; SoldatInfoX(void) { memset(&packet, '\0', sizeof(struct refreshX)); } SoldatInfoX(char * buffer) { memset(&packet, '\0', sizeof(struct refreshX)); int loop=0; for(loop=0;loop < 32;loop++) { // name length memcpy(&packet.players[loop].namelen,buffer+(loop*(XNAME_SIZE+XNAMELEN_SIZE)+XNAMELEN_OFFSET), XNAMELEN_SIZE); // name memcpy(&packet.players[loop].name,buffer+(loop*(XNAME_SIZE+XNAMELEN_SIZE)+XNAME_OFFSET), XNAME_SIZE);#ifndef OLDSOLDAT // hwid length memcpy(&packet.players[loop].hwidlen,buffer+(loop*(XHWID_SIZE+XHWIDLEN_SIZE)+XHWIDLEN_OFFSET), XHWIDLEN_SIZE); // hwid memcpy(&packet.players[loop].hwid,buffer+(loop*(XHWID_SIZE+XHWIDLEN_SIZE)+XHWID_OFFSET+XHWIDLEN_OFFSET), XHWID_SIZE);#endif // team memcpy(&packet.players[loop].team,buffer+(loop*XTEAM_SIZE+XTEAM_OFFSET), XTEAM_SIZE); // kills memcpy(&packet.players[loop].kills,buffer+(loop*XKILLS_SIZE+XKILLS_OFFSET), XKILLS_SIZE); // caps memcpy(&packet.players[loop].caps,buffer+(loop*XCAPS_SIZE+XCAPS_OFFSET), XCAPS_SIZE); // Deaths memcpy(&packet.players[loop].deaths,buffer+(loop*XDEATHS_SIZE+XDEATHS_OFFSET), XDEATHS_SIZE); // ping memcpy(&packet.players[loop].ping,buffer+(loop*XPINGS_SIZE+XPINGS_OFFSET), XPINGS_SIZE); // id memcpy(&packet.players[loop].id,buffer+(loop*XID_SIZE+XID_OFFSET), XID_SIZE); // ip memcpy(&packet.players[loop].ip,buffer+(loop*XIP_SIZE+XIP_OFFSET), XIP_SIZE); // X location memcpy(&packet.players[loop].x,buffer+(loop*XLOCX_SIZE+XLOCX_OFFSET), XLOCX_SIZE); // y location memcpy(&packet.players[loop].y,buffer+(loop*XLOCY_SIZE+XLOCY_OFFSET), XLOCY_SIZE); } // red flag x memcpy(&packet.redflagx,buffer+(XREDFLAGX_OFFSET), XREDFLAGX_SIZE); // red flag y memcpy(&packet.redflagx,buffer+(XREDFLAGY_OFFSET), XREDFLAGY_SIZE); // blue flag x memcpy(&packet.blueflagx,buffer+(XBLUEFLAGX_OFFSET), XBLUEFLAGX_SIZE); // blue flag y memcpy(&packet.blueflagx,buffer+(XBLUEFLAGY_OFFSET), XBLUEFLAGY_SIZE); // Alpha team score memcpy(&packet.alphascore,buffer+(XALPHATEAMSCORE_OFFSET), XALPHATEAMSCORE_SIZE); // Bravo team score memcpy(&packet.bravoscore,buffer+(XBRAVOTEAMSCORE_OFFSET), XBRAVOTEAMSCORE_SIZE); // Charlie team score memcpy(&packet.charliescore,buffer+(XCHARLIETEAMSCORE_OFFSET), XCHARLIETEAMSCORE_SIZE); // Delta team score memcpy(&packet.deltascore,buffer+(XDELTATEAMSCORE_OFFSET), XDELTATEAMSCORE_SIZE); // Current map length memcpy(&packet.currentmaplen,buffer+(XCURRENTMAPLEN_OFFSET), XCURRENTMAPLEN_SIZE); // Current map memcpy(&packet.currentmap,buffer+(XCURRENTMAP_OFFSET), XCURRENTMAP_SIZE); // Time limit memcpy(&packet.timelimit,buffer+(XTIMELIMIT_OFFSET), XTIMELIMIT_SIZE); // Time left memcpy(&packet.timeleft,buffer+(XTIMELEFT_OFFSET), XTIMELEFT_SIZE); // Cap/kill limit memcpy(&packet.limit,buffer+(XLIMIT_OFFSET), XLIMIT_SIZE); // Game style memcpy(&packet.gamestyle,buffer+(XGAMESTYLE_OFFSET), XGAMESTYLE_SIZE); // Max Players memcpy(&packet.maxplayers,buffer+(XMAXPLAYERS_OFFSET), XMAXPLAYERS_SIZE); // Max Spectators memcpy(&packet.maxspectators,buffer+(XMAXSPECTATORS_OFFSET), XMAXSPECTATORS_SIZE); // Password ? memcpy(&packet.password,buffer+(XPASSWORD_OFFSET), XPASSWORD_SIZE); // Next map length memcpy(&packet.nextmaplen,buffer+(XNEXTMAPLEN_OFFSET), XNEXTMAPLEN_SIZE); // Next map memcpy(&packet.nextmap,buffer+(XNEXTMAP_OFFSET), XNEXTMAP_SIZE); // internal check we will set check to false if it fails otherwise true packet.check = true; if(packet.limit > 65535) packet.check = false; if(packet.gamestyle > 6) packet.check = false; if(packet.maxplayers > 32) packet.check = false; if(packet.nextmaplen > 16) packet.check = false; if(packet.currentmaplen > 16) packet.check = false; } };#endif
$map = unpack('Clen/A16name', substr($packet, $pos, 17)); $pos += 17;
$limit = unpack('v', substr($packet, $pos, 2)); $pos += 2;
module Soldat class PlayerStat def initialize() @name = '' @hwid = '' @team = 0 @kill = 0 @flag = 0 @death = 0 @ping = 0 @id = 0 @ips = Array.new( 4, 0 ) @x = 0 @y = 0 end attr_accessor :name, :hwid, :team, :kill, :flag, :death, :ping, :id, :ips, :x, :y def ip return @ips.join( '.' ) end end class FlagXY def initialize() @x = 0 @y = 0 end attr_accessor :x, :y end class RefreshX def initialize( refreshx ) raise unless refreshx.size == 1992 info = refreshx.unpack( 'CA24'*32 + 'CA11'*32 + 'C32S32C32S32L32C32' + 'C32'*4 + 'e32e32eeeeS4CA16llSCCCCCA16' ) @players = Array.new( 32, {} ) 32.times do |i| @players[i] = PlayerStat.new @players[i].name = info[2*i+1].to_s[0, info[2*i]] @players[i].hwid = info[2*i+65].to_s[0, info[2*i+64]] @players[i].team = info[i+128] @players[i].kill = info[i+160] @players[i].flag = info[i+192] @players[i].death = info[i+224] @players[i].ping = info[i+256] @players[i].id = info[i+288] 4.times do |j| @players[i].ips[j] = info[i*4+j+320] end @players[i].x = info[i+448] @players[i].y = info[i+480] end @redflag = FlagXY.new @redflag.x = info[512] @redflag.y = info[513] @blueflag = FlagXY.new @blueflag.x = info[514] @blueflag.y = info[515] @teamscore = Array.new( 4, 0 ) 4.times do |i| @teamscore[i] = info[i+516] end @mapname = info[521].to_s[0, info[520]] @timelimit = info[522] @currenttime = info[523] @scorelimit = info[524] @gamestyle = info[525] @maxplayers = info[526] @maxspectators = info[527] @passworded = info[528] @nextmap = info[530].to_s[0, info[529]] end attr_reader :players, :redflag, :blueflag, :teamscore, :mapname, :timelimit, :currenttime, :scorelimit, :gamestyle, :maxplayers, :maxspectators, :passworded, :nextmap endend
type playerX = record namelen: byte; name: Array[1..24] of char; tagidlen: byte; tagid: Array[1..11] of char; team: byte; kills: word; caps: byte; deaths: word; ping: cardinal; id: byte; ip: Array[1..4] of byte; x: single; y: single;end;type refreshX = record players: Array[0..31] of playerX; redflagx: single; redflagy: single; blueflagx: single; blueflagy: single; alphascore: word; bravoscore: word; charliescore: word; deltascore: word; currentmaplen: byte; currentmap: Array[1..16] of char; timelimit: longint; timeleft: longint; limit: byte; gamestyle: byte; maxplayers: byte; maxspectators: byte; password: byte; nextmaplen: byte; nextmap: Array[1..16] of char;end;var packet: ^refreshX;procedure RefreshX(buffer: array of byte);var i: byte;begin GetMem(packet,sizeof(refreshX)); for i := 0 to 31 do begin move(buffer[i*25],packet^.players[i].namelen, 1); move(buffer[i*25+1],packet^.players[i].name, 24); move(buffer[i+800],packet^.players[i].tagidlen, 1); move(buffer[i*12+801], packet^.players[i].tagid, 11); move(buffer[i+1184], packet^.players[i].team, 1); move(buffer[i*2+1216], packet^.players[i].kills, 2); move(buffer[i+1280], packet^.players[i].caps, 1); move(buffer[i*2+1312], packet^.players[i].deaths, 2); move(buffer[i*4+1376], packet^.players[i].ping, 4); move(buffer[i+1504], packet^.players[i].id, 1); move(buffer[i*4+1536], packet^.players[i].ip, 4); move(buffer[i*4+1664], packet^.players[i].x, 4); move(buffer[i*4+1792], packet^.players[i].y, 4); end; move(buffer[1920], packet^.redflagx, 4); move(buffer[1924], packet^.redflagy, 4); move(buffer[1928], packet^.blueflagx, 4); move(buffer[1932], packet^.blueflagy, 4); move(buffer[1936], packet^.alphascore, 2); move(buffer[1938], packet^.bravoscore, 2); move(buffer[1940], packet^.charliescore, 2); move(buffer[1942], packet^.deltascore, 2); move(buffer[1944], packet^.currentmaplen, 1); move(buffer[1945], packet^.currentmap, 16); move(buffer[1961], packet^.timelimit, 4); move(buffer[1965], packet^.timeleft, 4); move(buffer[1969], packet^.limit, 2); move(buffer[1971], packet^.gamestyle, 1); move(buffer[1972], packet^.maxplayers, 1); move(buffer[1973], packet^.maxspectators, 1); move(buffer[1974], packet^.password, 1); move(buffer[1975], packet^.nextmaplen, 1); move(buffer[1976], packet^.nextmap, 16);end;