|   1:  | <?php | 
|   2:  |  | 
|   3:  |  | 
|   4:  |  | 
|   5:  |  | 
|   6:  |  | 
|   7:  |  | 
|   8:  |  | 
|   9:  |  | 
|  10:  |  | 
|  11:  |  | 
|  12:  |  | 
|  13:  |  | 
|  14:  |  | 
|  15:  |  | 
|  16:  |  | 
|  17:  |  | 
|  18:  |  | 
|  19:  | namespace GameQ\Protocols; | 
|  20:  |  | 
|  21:  | use GameQ\Buffer; | 
|  22:  | use GameQ\Exception\Protocol as Exception; | 
|  23:  | use GameQ\Protocol; | 
|  24:  | use GameQ\Result; | 
|  25:  |  | 
|  26:  |  | 
|  27:  |  | 
|  28:  |  | 
|  29:  |  | 
|  30:  |  | 
|  31:  |  | 
|  32:  |  | 
|  33:  |  | 
|  34:  | class Teeworlds extends Protocol | 
|  35:  | { | 
|  36:  |      | 
|  37:  |  | 
|  38:  |  | 
|  39:  |  | 
|  40:  |  | 
|  41:  |  | 
|  42:  |     protected $packets = [ | 
|  43:  |         self::PACKET_ALL => "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x67\x69\x65\x33\x05", | 
|  44:  |          | 
|  45:  |          | 
|  46:  |     ]; | 
|  47:  |  | 
|  48:  |      | 
|  49:  |  | 
|  50:  |  | 
|  51:  |  | 
|  52:  |  | 
|  53:  |     protected $responses = [ | 
|  54:  |         "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffinf35" => "processAll", | 
|  55:  |     ]; | 
|  56:  |  | 
|  57:  |      | 
|  58:  |  | 
|  59:  |  | 
|  60:  |  | 
|  61:  |  | 
|  62:  |     protected $protocol = 'teeworlds'; | 
|  63:  |  | 
|  64:  |      | 
|  65:  |  | 
|  66:  |  | 
|  67:  |  | 
|  68:  |  | 
|  69:  |     protected $name = 'teeworlds'; | 
|  70:  |  | 
|  71:  |      | 
|  72:  |  | 
|  73:  |  | 
|  74:  |  | 
|  75:  |  | 
|  76:  |     protected $name_long = "Teeworlds Server"; | 
|  77:  |  | 
|  78:  |      | 
|  79:  |  | 
|  80:  |  | 
|  81:  |  | 
|  82:  |  | 
|  83:  |     protected $join_link = "steam://connect/%s:%d/"; | 
|  84:  |  | 
|  85:  |      | 
|  86:  |  | 
|  87:  |  | 
|  88:  |  | 
|  89:  |  | 
|  90:  |     protected $normalize = [ | 
|  91:  |          | 
|  92:  |         'general' => [ | 
|  93:  |              | 
|  94:  |             'dedicated'  => 'dedicated', | 
|  95:  |             'hostname'   => 'hostname', | 
|  96:  |             'mapname'    => 'map', | 
|  97:  |             'maxplayers' => 'num_players_total', | 
|  98:  |         ], | 
|  99:  |          | 
| 100:  |         'player'  => [ | 
| 101:  |             'name'  => 'name', | 
| 102:  |             'score' => 'score', | 
| 103:  |         ], | 
| 104:  |     ]; | 
| 105:  |  | 
| 106:  |      | 
| 107:  |  | 
| 108:  |  | 
| 109:  |  | 
| 110:  |  | 
| 111:  |  | 
| 112:  |  | 
| 113:  |     public function processResponse() | 
| 114:  |     { | 
| 115:  |          | 
| 116:  |         $results = []; | 
| 117:  |  | 
| 118:  |          | 
| 119:  |         foreach ($this->packets_response as $response) { | 
| 120:  |              | 
| 121:  |             $buffer = new Buffer($response); | 
| 122:  |  | 
| 123:  |              | 
| 124:  |             $header = $buffer->readString(); | 
| 125:  |  | 
| 126:  |              | 
| 127:  |             if (!array_key_exists($header, $this->responses)) { | 
| 128:  |                 throw new Exception(__METHOD__ . " response type '" . bin2hex($header) . "' is not valid"); | 
| 129:  |             } | 
| 130:  |  | 
| 131:  |              | 
| 132:  |             $results = array_merge( | 
| 133:  |                 $results, | 
| 134:  |                 call_user_func_array([$this, $this->responses[$header]], [$buffer]) | 
| 135:  |             ); | 
| 136:  |         } | 
| 137:  |  | 
| 138:  |         unset($buffer); | 
| 139:  |  | 
| 140:  |         return $results; | 
| 141:  |     } | 
| 142:  |  | 
| 143:  |      | 
| 144:  |  | 
| 145:  |  | 
| 146:  |  | 
| 147:  |  | 
| 148:  |  | 
| 149:  |  | 
| 150:  |     protected function processAll(Buffer $buffer) | 
| 151:  |     { | 
| 152:  |          | 
| 153:  |         $result = new Result(); | 
| 154:  |  | 
| 155:  |          | 
| 156:  |         $result->add('dedicated', 1); | 
| 157:  |  | 
| 158:  |         $result->add('version', $buffer->readString()); | 
| 159:  |         $result->add('hostname', $buffer->readString()); | 
| 160:  |         $result->add('map', $buffer->readString()); | 
| 161:  |         $result->add('game_descr', $buffer->readString()); | 
| 162:  |         $result->add('flags', $buffer->readString());  | 
| 163:  |         $result->add('num_players', $buffer->readString()); | 
| 164:  |         $result->add('maxplayers', $buffer->readString()); | 
| 165:  |         $result->add('num_players_total', $buffer->readString()); | 
| 166:  |         $result->add('maxplayers_total', $buffer->readString()); | 
| 167:  |  | 
| 168:  |          | 
| 169:  |         while ($buffer->getLength()) { | 
| 170:  |             $result->addPlayer('name', $buffer->readString()); | 
| 171:  |             $result->addPlayer('clan', $buffer->readString()); | 
| 172:  |             $result->addPlayer('flag', $buffer->readString()); | 
| 173:  |             $result->addPlayer('score', $buffer->readString()); | 
| 174:  |             $result->addPlayer('team', $buffer->readString()); | 
| 175:  |         } | 
| 176:  |  | 
| 177:  |         unset($buffer); | 
| 178:  |  | 
| 179:  |         return $result->fetch(); | 
| 180:  |     } | 
| 181:  | } | 
| 182:  |  |