root/dev/common/sync_server.php @ 176

Revision 176, 5.3 KB (checked in by exi, 14 years ago)

Changes to sync_server.php to reduce the memory load during script execution.

Line 
1<?php
2require_once('db.php');
3
4// modify the header here so the client gets our version
5header('X-KBVersion: '.KB_VERSION);
6
7if (!strstr($_SERVER['HTTP_USER_AGENT'], 'EVE-KB SYNC'))
8{
9    echo 'Current version is '.KB_VERSION.'.<br>';
10    echo 'You should not call this file directly unless you\'re told to<br>';
11    return;
12}
13
14// this is an example for version checking with client ban
15// in case we change the protocol/data format
16preg_match("^\(VER (.*?)\)^", $_SERVER['HTTP_USER_AGENT'], $match);
17$version = explode('.', $match[1]);
18if ($version[0] <= 1 && $version[1] < 1)
19{
20    echo "Your Killboard is too old, please upgrade to 1.2.2 or newer<br>\n";
21    return;
22}
23
24if (!function_exists('apache_request_headers'))
25{
26    function apache_request_headers()
27    {
28        return getallheaders();
29    }
30}
31$header = apache_request_headers();
32foreach ($header as $key => $value)
33{
34    if ($key == 'X-KBHost')
35    {
36        $host = base64_decode($value);
37    }
38}
39
40// check if we got a file named 'data' supplied with the request
41if (!file_exists($_FILES['data']['tmp_name']))
42{
43    var_dump($_REQUEST);
44    var_dump($_FILES);
45    echo "malformed request, expecting data-file<br>\n";
46    return;
47}
48
49// we got our file, process
50$data = gzinflate(file_get_contents($_FILES['data']['tmp_name']));
51
52// get all names we'll find
53preg_match_all("^!(.*?)\|(.*?)-^", &$data, $matches);
54$data = strstr($data, 'ITEMS_START');
55$results = count($matches[1]);
56if ($results == 0)
57{
58    // if we got no ids from the client we won't send him ours
59    // bad idea for new installations
60    //echo "malformed request<br>\n";
61    //return;
62}
63
64$s_data = array();
65// construct an array with name as key and id as value
66for ($i = 0; $i<$results; $i++)
67{
68    $s_data[$matches[1][$i]] = $matches[2][$i];
69}
70unset($matches);
71
72if ($host)
73{
74    $qry = new DBQuery();
75    $qry->execute("show tables like '%item_%'");
76    while ($row = $qry->getRow())
77    {
78        $tables .= array_pop($row);
79    }
80    if (!strstr($tables, 'kb3_item_stats'))
81    {
82        $qry->execute("CREATE TABLE `kb3_item_stats` (\n `itm_name` varchar(128) NOT NULL,\n `kb_host` int(11) NOT NULL,\n `itm_externalid` int(11) NOT NULL,\n `itm_value` bigint(4) NOT NULL,\n PRIMARY KEY (`itm_name`,`kb_host`)\n) TYPE=MyISAM");
83        $qry->execute("CREATE TABLE `kb3_item_hosts` (\n `kb_host` int(11) NOT NULL,\n `kb_name` varchar(255) NOT NULL,\n `itm_update` timestamp NOT NULL default '0000-00-00 00:00:00',\n RPIMARY KEY (`kb_host`)\n) TYPE=MyISAM");
84    }
85    preg_match_all('^§(.*?)\|(.*?)\|(.*?)-^', &$data, $matches);
86
87    $hostid = abs(crc32($host));
88    $qry->execute('replace into kb3_item_hosts (kb_host, kb_name, itm_update) VALUES (\''.$hostid.'\',\''.addslashes($host).'\',\''.date('Y-m-d H:i:s').'\')');
89
90    $results = count($matches[1]);
91    for ($i = 0; $i<$results; $i++)
92    {
93        $qry->execute("replace into kb3_item_stats (itm_name,kb_host,itm_externalid,itm_value) VALUES ('".addslashes($matches[1][$i])."','".$hostid."','".addslashes($matches[2][$i])."','".addslashes($matches[3][$i])."')");
94    }
95    unset($matches);
96}
97unset($data);
98
99// now get our list from the database
100$qry = new DBQuery();
101$qry->execute("select plt_name, plt_externalid from kb3_pilots where plt_externalid != 0");
102while ($data = $qry->getRow())
103{
104    $data_array[$data['plt_name']] = $data['plt_externalid'];
105}
106$update = new DBQuery();
107
108// compare the entries supplied with our own
109foreach ($s_data as $name => $id)
110{
111    if (!$data_array[$name])
112    {
113        // we dont got that one in our database, update
114        // TODO: we don't care about missing pilots yet
115        $update->execute("update kb3_pilots set plt_externalid='".addslashes($id)."' where plt_name='".addslashes($name)."' limit 1");
116    }
117    else
118    {
119        // unset to save comparison time, we know the client has it
120        unset($data_array[$name]);
121    }
122}
123
124// $data_array now contains only unknown ids to the client
125$content_file = 'DATA_START';
126foreach ($data_array as $name => $id)
127{
128    $content_file .= '!'.$name.'|'.$id.'-';
129}
130
131$data_array = $data_values = array();
132$lastname = '';
133$qry->execute('select itm_name, itm_externalid, itm_value from kb3_item_stats order by itm_name asc, itm_value asc');
134while ($data = $qry->getRow())
135{
136    // looks like we hit the memory limit so median extraction has to happen here
137    if ($lastname != $data['itm_name'])
138    {
139        // check for lastname due to initialisation
140        if ($lastname)
141        {
142            // get the median value for the item
143            $val_cnt = count($data_values[$lastname]);
144            $val_cnt = min(ceil($val_cnt/2), $val_cnt)-1;
145            $value = $data_values[$lastname][$val_cnt];
146
147            $data_array[$lastname]['itm_value'] = $data;
148            unset($data_values[$lastname]);
149        }
150        $lastname = $data['itm_name'];
151    }
152    $data_array[$data['itm_name']] = $data;
153    $data_values[$data['itm_name']][] = $data['itm_value'];
154}
155unset($data_values);
156
157$content_file .= 'ITEMS_START';
158foreach ($data_array as $data)
159{
160    $content_file .= '§'.$data['itm_name'].'|'.$data['itm_externalid'].'|'.$data['itm_value'].'-';
161}
162unset($data_array);
163
164// return the compressed data back to the client
165echo gzdeflate($content_file);
166?>
Note: See TracBrowser for help on using the browser.