Linux multi-monitor fullscreen support
[ryzomcore.git] / nelns / admin / public_html / request_interface.php
blob7b76ab1dbdb11724cbfab221f90f2dd189d10fcb
1 <?php
2 // NeL - MMORPG Framework <http://dev.ryzom.com/projects/nel/>
3 // Copyright (C) 2010 Winch Gate Property Limited
4 //
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Affero General Public License as
7 // published by the Free Software Foundation, either version 3 of the
8 // License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Affero General Public License for more details.
15 // You should have received a copy of the GNU Affero General Public License
16 // along with this program. If not, see <http://www.gnu.org/licenses/>.
18 class CMemStream
20 var $Buffer;
21 var $InputStream;
22 var $Pos;
24 function CMemStream ()
26 $this->InputStream = false;
27 $this->Pos = 0;
30 function setBuffer ($buffer)
32 $this->InputStream = true;
33 $this->Buffer = $buffer;
34 $this->Pos = 0;
37 function isReading () { return $this->InputStream; }
40 function serialuint8 (&$val)
42 if ($this->isReading())
44 $val = ord($this->Buffer{$this->Pos++});
45 //printf ("read uint8 '%d'<br>", $val);
47 else
49 $this->Buffer .= chr($val & 0xFF);
50 $this->Pos++;
51 //printf ("write uint8 '%d' %d<br>", $val, $this->Pos);
55 function serialuint32 (&$val)
57 if ($this->isReading())
59 $val = ord($this->Buffer{$this->Pos++});
60 $val += ord($this->Buffer{$this->Pos++})<<8;
61 $val += ord($this->Buffer{$this->Pos++})<<16;
62 $val += ord($this->Buffer{$this->Pos++})<<32;
63 //printf ("read uint32 '%d'<br>", $val);
65 else
67 $this->Buffer .= chr($val & 0xFF);
68 $this->Buffer .= chr(($val>>8) & 0xFF);
69 $this->Buffer .= chr(($val>>16) & 0xFF);
70 $this->Buffer .= chr(($val>>24) & 0xFF);
71 $this->Pos += 4;
72 //printf ("write uint32 '%d' %d<br>", $val, $this->Pos);
76 function serialstring (&$val)
78 if ($this->isReading())
80 $this->serialuint32($size);
81 $val = substr ($this->Buffer, $this->Pos, $size);
82 //printf ("read string '%s'<br>", $val);
83 $this->Pos += strlen($val);
85 else
87 $this->serialuint32(strlen($val));
88 $this->Buffer .= $val;
89 $this->Pos += strlen($val);
90 //printf ("write string '%s' %d<br>", $val, $this->Pos);
95 function serialuint8 (&$val)
97 if ($this->isReading())
99 if ($this->Pos+1 > strlen($this->Buffer))
100 return false;
102 $val = ord($this->Buffer{$this->Pos++});
103 //printf ("read uint8 '%d'<br>", $val);
105 else
107 $this->Buffer .= chr($val & 0xFF);
108 $this->Pos++;
109 //printf ("write uint8 '%d' %d<br>", $val, $this->Pos);
111 return true;
114 function serialuint32 (&$val)
116 if ($this->isReading())
118 if ($this->Pos+4 > strlen($this->Buffer))
119 return false;
121 $val = ord($this->Buffer{$this->Pos++});
122 $val += ord($this->Buffer{$this->Pos++})<<8;
123 $val += ord($this->Buffer{$this->Pos++})<<16;
124 $val += ord($this->Buffer{$this->Pos++})<<32;
125 //printf ("read uint32 '%d'<br>", $val);
127 else
129 $this->Buffer .= chr($val & 0xFF);
130 $this->Buffer .= chr(($val>>8) & 0xFF);
131 $this->Buffer .= chr(($val>>16) & 0xFF);
132 $this->Buffer .= chr(($val>>24) & 0xFF);
133 $this->Pos += 4;
134 //printf ("write uint32 '%d' %d<br>", $val, $this->Pos);
136 return true;
139 function serialstring (&$val)
141 if ($this->isReading())
143 if (!$this->serialuint32($size))
144 return false;
146 if ($this->Pos+$size > strlen($this->Buffer))
147 return false;
149 $val = substr ($this->Buffer, $this->Pos, $size);
150 //printf ("read string '%s'<br>", $val);
151 $this->Pos += strlen($val);
153 else
155 $this->serialuint32(strlen($val));
156 $this->Buffer .= $val;
157 $this->Pos += strlen($val);
158 //printf ("write string '%s' %d<br>", $val, $this->Pos);
160 return true;
165 // This function connect to the AS.
166 // If true, $res contains the url to connect.
167 // If false, $res contains the reason why it s not okay.
169 function connectToAS(&$fp, &$res, $asHost, $asPort)
171 // connect to the login service that must be $ASHost:$ASPort
172 $fp = fsockopen ($asHost, $asPort, $errno, $errstr, 30);
173 if (!$fp)
175 $res = "Can't connect to the admin service '$ASHost:$ASPort' ($errno: $errstr)";
177 else
179 $res = "";
183 function disconnectFromAS(&$fp)
185 fclose($fp);
188 function sendMessage ($fp, $msgout)
190 $size = $msgout->Pos;
191 $buffer = chr(($size>>24)&0xFF);
192 $buffer .= chr(($size>>16)&0xFF);
193 $buffer .= chr(($size>>8)&0xFF);
194 $buffer .= chr($size&0xFF);
195 $buffer .= $msgout->Buffer;
197 fwrite ($fp, $buffer);
199 fflush ($fp);
201 return true;
204 function logToFile($msg)
206 $f = fopen("../log_admin_tool.txt", "a");
207 if ($f)
209 fwrite($f, "$msg\n");
210 fflush($f);
211 fclose($f);
215 function waitMessage ($fp, &$msgin)
217 $size = 0;
218 $val = fread ($fp, 1);
219 $size = ord($val) << 24;
220 $val = fread ($fp, 1);
221 $size = ord($val) << 16;
222 $val = fread ($fp, 1);
223 $size += ord($val) << 8;
224 $val = fread ($fp, 1);
225 $size += ord($val);
226 $fake = fread ($fp, 4);
227 $size -= 4; // remove the fake
229 $buffer = '';
232 $buffer .= fread ($fp, $size);
233 //logToFile("read ".strlen($buffer)." bytes...");
234 if (feof($fp))
235 break;
237 while (strlen($buffer) != $size);
239 //logToFile("finished read ".strlen($buffer)." bytes!!");
241 $msgin = new CMemStream;
242 $msgin->setBuffer ($buffer);
244 //logToFile("leave wait message");
245 return true;
248 function waitMessage ($fp, &$msgin)
250 //echo "waiting a message";
251 $size = 0;
252 $val = fread ($fp, 1);
253 if (feof ($fp)) return false;
254 $size = ord($val) << 24;
255 $val = fread ($fp, 1);
256 if (feof ($fp)) return false;
257 $size = ord($val) << 16;
258 $val = fread ($fp, 1);
259 if (feof ($fp)) return false;
260 $size += ord($val) << 8;
261 $val = fread ($fp, 1);
262 if (feof ($fp)) return false;
263 $size += ord($val);
264 //printf ("receive packet size '%d'<br>", $size);
265 $fake = fread ($fp, 4);
266 if (feof ($fp)) return false;
267 $size -= 4; // remove the fake
269 $buffer = '';
270 while (($stillNotRead = $size-strlen($buffer)) > 0)
272 $buffer .= fread ($fp, $stillNotRead);
273 if (feof ($fp)) return false;
276 $msgin = new CMemStream;
277 $msgin->setBuffer ($buffer);
279 return true;
282 function logNelQuery($query)
284 global $uid;
286 $f = fopen("./nel_queries.log", "a");
287 fwrite($f, date("Y/m/d H:i:s")." ".sprintf("%-16s", $admlogin)." $query\n");
288 fclose($f);
290 logUser($uid, "QUERY=".$query);
294 function queryToAS($rawvarpath, &$result, $asAddr, $asPort)
296 global $nel_queries;
298 $nel_queries[] = $rawvarpath;
299 $ok = false;
301 connectToAS($fp, $result, $asAddr, $asPort);
302 if(strlen($result) != 0)
303 return $ok;
305 // send the message that say that we want to add a user
306 $msgout = new CMemStream;
307 $fake = 0;
308 $msgout->serialuint32 ($fake); // fake used to number the packet
309 $messageType = 0;
310 $msgout->serialuint8 ($messageType);
311 $msgout->serialstring ($rawvarpath);
313 sendMessage ($fp, $msgout);
315 waitMessage ($fp, $msgin);
317 $msgin->serialstring($result);
319 if(strlen($result) == 0)
321 // it failed
323 else
325 // it's ok
326 $ok = true;
329 disconnectFromAS(&$fp);
331 return $ok;
335 function nel_query($rawvarpath, &$result)
337 global $ASHost, $ASPort;
339 $shards = getShardListFromQuery($rawvarpath);
340 $as = getASList($shards);
342 if (count($as) <= 1)
344 $asHost = $ASHost;
345 $asPort = $ASPort;
347 if (count($as) > 0)
349 foreach ($as as $asHost)
351 $pos = strpos($asHost, ':');
352 if (pos != FALSE)
354 $asPort = substr($asHost, $pos+1);
355 $asHost = substr($asHost, 0, $pos);
360 $res = queryToAS($rawvarpath, $result, $asHost, $asPort);
362 else
364 $resCols = array();
365 $resArray = array();
367 $res = false;
369 foreach ($as as $asHost)
371 $asPort = $ASPort;
372 $pos = strpos($asHost, ':');
373 if (pos != FALSE)
375 $asPort = substr($asHost, $pos+1);
376 $asHost = substr($asHost, 0, $pos);
379 $tmp = queryToAS($rawvarpath, $qres, $asHost, $asPort);
380 if ($tmp)
382 $res = true;
383 mergeResult($qres, $resCols, $resArray);
387 //print_r($resCols);echo '<br>';
388 //print_r($resArray);echo '<br>';
389 $result = rebuildResult($resCols, $resArray);
392 return res;
396 function getShardFromSimpleQuery($query, $startpos=0)
398 $pos = $startpos;
399 while ($pos < strlen($query) && $query[$pos] != '.' && $query[$pos] != ']' && $query[$pos] != ',')
400 ++$pos;
401 //echo 'getShardFromSimpleQuery: '.substr($query, $startpos, $pos-$startpos).'<br>';
402 return substr($query, $startpos, $pos-$startpos);
405 function getShardListFromQuery($query, $startpos=0)
407 $shards = array();
409 if ($query[$startpos] != '[')
411 $shards[] = getShardFromSimpleQuery($query, $startpos);
412 return $shards;
415 $pos = $startpos+1;
416 $lvl = 0;
418 while (true)
420 //echo 'getShardListFromQuery in '.substr($query, $pos).'<br>';
421 $shards = array_merge($shards, getShardListFromQuery($query, $pos));
423 while ($pos<strlen($query) && ($query[$pos]!=',' || $lvl>0))
425 if ($query[$pos] == '[') ++$lvl;
426 if ($query[$pos] == ']') --$lvl;
427 ++$pos;
430 if ($query[$pos] != ',')
431 break;
433 ++$pos;
436 return array_unique($shards);
439 function selectAllAS()
441 global $ASHost, $ASPort;
443 $as[] = $ASHost.':'.$ASPort;
445 foreach($shardLockState as $shard)
446 if ($shard['ASAddr'] != '')
447 $as[] = $shard[ASAddr];
449 return array_unique($as);
452 function getASList($shards)
454 global $ASHost, $ASPort, $shardLockState;
456 if (count($shards) == 0)
457 return;
459 if (array_search('*', $shards) != FALSE)
460 return selectAllAS();
462 foreach($shards as $shard)
463 if ($shardLockState[$shard]['ASAddr'] != '')
464 $as[$shard] = $shardLockState[$shard]['ASAddr'];
465 else
466 $as[$shard] = $ASHost.':'.$ASPort;
468 return array_unique($as);
471 function mergeResult(&$res, &$resCols, &$resArray)
473 $resV = explode(' ', $res);
475 $i = 0;
476 $numCols = $resV[$i++];
477 for ($i=1; $i<=$numCols; ++$i)
478 if (!isset($resCols[$resV[$i]]))
479 $resCols[$resV[$i]] = count($resCols);
481 while ($i < count($resV))
483 //echo 'examine i='.$i.', resv='.count($resV).'<br>';
485 $line = array();
486 for ($j=0; $j<$numCols; ++$j)
488 $line[ $resCols[$resV[$j+1]] ] = $resV[$i++];
490 if ($i > count($resV))
491 break;
493 if ($j>=$numCols)
494 $resArray[] = $line;
498 function rebuildResult(&$resCols, &$resArray)
500 $numCols = count($resCols);
502 $res = $numCols;
504 foreach($resCols as $col => $id)
505 $res .= ' '.$col;
507 //$res .= join(' ', $resCols);
509 $numRows = count($resArray);
510 if ($numRows == 0)
511 return $res;
513 for ($i=0; $i<$numRows; ++$i)
515 $line = &$resArray[$i];
516 //print_r($line); echo '<br>';
517 if (count($line) == 0)
518 continue;
520 foreach ($resCols as $col => $id)
522 $v = &$line[$id];
523 if (!isset($v) || $v == '')
524 $res .= ' ???';
525 else
526 $res .= ' '.$v;
530 return $res;