Module: RconCs::Utils::Parsers
- Included in:
- Servers::SourceServer
- Defined in:
- lib/rcon_cs/utils/parsers.rb
Overview
Utility parser methods
Instance Method Summary collapse
Instance Method Details
#parse_players(data) ⇒ Object
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/rcon_cs/utils/parsers.rb', line 87 def parse_players(data) body = data[4..] raise "Invalid packet type: #{body[0]}" unless body[0] == "D" num_of_players = body[1].ord body = body[2..] result = [] offset = 0 num_of_players.times do |player_idx| # Ensure enough data remains raise "Insufficient data for player #{player_idx}" if offset >= body.length offset += 1 name_end = body[offset..].index("\x00") raise "No null terminator for player #{player_idx} name" unless name_end name = body[offset...(offset + name_end)].force_encoding("UTF-8") offset += name_end + 1 # Ensure enough bytes for score and duration (4 each) raise "Missing score/duration for player #{player_idx}" if offset + 8 > body.length # Score (4 bytes, little-endian long) score = body[offset...(offset + 4)].unpack1("l<") offset += 4 # Duration (4 bytes, little-endian float) duration = body[offset...(offset + 4)].unpack1("e") offset += 4 result << { name: name, score: score, duration: duration } end warn "Extra data after parsing: #{body[offset..].bytes}" if offset < body.length result end |
#parse_server_info(data) ⇒ Object
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/rcon_cs/utils/parsers.rb', line 8 def parse_server_info(data) body = data[4..] result = {} result[:protocol] = body[1].ord server_name_end = body[2..].index("\x00") + 2 result[:server_name] = body[2...server_name_end].force_encoding("UTF-8") body = body[server_name_end + 1..] map_name_end = body.index("\x00") result[:map_name] = body[0...map_name_end] body = body[map_name_end + 1..] game_folder_end = body.index("\x00") result[:game_folder] = body[0...game_folder_end] body = body[game_folder_end + 1..] game_name_end = body.index("\x00") result[:game_name] = body[0...game_name_end] body = body[game_name_end + 1..] result[:app_id] = body[0..1].unpack1("S<") body = body[2..] result[:players] = body[0].ord body = body[1..] result[:max_players] = body[0].ord body = body[1..] result[:bots] = body[0].ord body = body[1..] result[:server_type] = body[0] body = body[1..] result[:environment] = body[0] body = body[1..] result[:visibility] = body[0].ord body = body[1..] result[:vac] = body[0].ord body = body[1..] version_end = body.index("\x00") result[:version] = body[0...version_end] body = body[version_end + 1..] edf = body[0].ord body = body[1..] if edf & 0x80 result[:port] = body[0..1].unpack1("S<") body = body[2..] end if edf & 0x10 result[:steam_id] = body[0..7].unpack1("Q<") body = body[8..] end # SourceTV port and name (not present in this case) if edf & 0x40 # Skip if present end if edf & 0x20 keywords_end = body.index("\x00") result[:keywords] = body[0...keywords_end] body = body[keywords_end + 1..] end result[:game_id] = body[0..7].unpack1("Q<") if edf & 0x01 result end |