Skip to content

Commit e3d8c9b

Browse files
committed
Merge branch 'develop'
2 parents fb19ccc + 502a74d commit e3d8c9b

28 files changed

+502
-96
lines changed

Dockerfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,17 @@ RUN apt-get update && \
88
docker-php-ext-enable zip && \
99
rm -rf /var/lib/apt/lists/*
1010

11+
# Accept X-Forwarded-For as real client ip from a TRUSTED PROXY.
12+
# Set the "Server" header to production (e.g. to "Apache") and
13+
# remove apache version information. Build the ETAG from
14+
# last modified and size only.
1115
RUN a2enmod remoteip && \
1216
( \
1317
echo "RemoteIPHeader X-Forwarded-For" && \
18+
echo "ServerTokens Prod" && \
19+
echo "ServerSignature Off" && \
20+
echo "TraceEnable off" && \
21+
echo "FileETag MTime Size" && \
1422
echo "ErrorLog /dev/null" && \
1523
echo "CustomLog /dev/null combined" \
1624
) >>/etc/apache2/apache2.conf

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55

66
System that automatically grants ranks in the form of server groups for online time or online activity to users, using the given server groups of the TS3 server.
77

8-
This is a modified fork of the TSN-Ranksystem which is updated irregularly to a stable version. It is intended to be fully compatible to TSN-Ranksystem at all times. The changeset on branch `develop` is always rebased onto TSN-Ranksystem and later on merged into `master`.
8+
This is a modified fork of the TSN-Ranksystem which is updated irregularly to a stable version (currently **1.3.17**) . It is intended to be fully compatible to TSN-Ranksystem at all times. The changeset on branch `develop` is always rebased onto TSN-Ranksystem and later on merged into `master`.
99

10-
Please make sure that your TSN-Ranksystem database version is not above the database version of this fork (downgrade).
10+
Please make sure that your TSN-Ranksystem (database) version is not above the (database) version of this fork (downgrade).
1111

1212
## Docker
1313
You can find the docker images on [docker hub](https://hub.docker.com/r/jvmerkle/ts3-ranksystem).
@@ -19,8 +19,8 @@ Enable the `INSTALL_MODE=1` in the file `docker-compose.yml` by uncommenting the
1919
```sh
2020
docker-compose up
2121
```
22-
Navigate to [http://localhost:8080/install.php](http://localhost:8080/install.php) and set up the rank system.
23-
After performing the first time setup re-edit the `docker-compose.yml` by commenting or removing the `INSTALL_MODE`.
22+
Navigate to [http://localhost:8080/install.php](http://localhost:8080/install.php) and set up the rank system.
23+
After performing the first time setup re-edit the `docker-compose.yml` by commenting or removing the `INSTALL_MODE`.
2424
Then start the docker containers in daemon mode:
2525
```sh
2626
docker-compose up -d

api/index.php

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -170,8 +170,18 @@
170170
}
171171
if(isset($_GET['groupid'])) {
172172
$groupid = htmlspecialchars_decode($_GET['groupid']);
173+
$explode_groupid = explode(',', $groupid);
173174
if($filter != ' WHERE') $filter .= " AND";
174-
$filter .= " (`cldgroup` = :groupid OR `cldgroup` LIKE (:groupid0) OR `cldgroup` LIKE (:groupid1) OR `cldgroup` LIKE (:groupid2))";
175+
$filter .= " (";
176+
$cnt = 0;
177+
foreach($explode_groupid as $groupid) {
178+
if($cnt > 0) $filter .= " OR ";
179+
$filter .= "`cldgroup` = :groupid".$cnt; $cnt++;
180+
$filter .= " OR `cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
181+
$filter .= " OR `cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
182+
$filter .= " OR `cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
183+
}
184+
$filter .= ")";
175185
}
176186
if(isset($_GET['name'])) {
177187
$name = htmlspecialchars_decode($_GET['name']);
@@ -208,8 +218,17 @@
208218
),
209219
"groupid" => array(
210220
"desc" => "Get only user, which are in the given servergroup database ID",
211-
"usage" => "Use \$_GET parameter 'groupid' and add as value a database ID of a servergroup",
212-
"example" => "/api/?user&groupid=6"
221+
"usage" => "Use \$_GET parameter 'groupid' and add as value a database ID of a servergroup. Multiple servergroups can be specified comma-separated.",
222+
"example" => array(
223+
"1" => array(
224+
"desc" => "Filter by a single servergroup database ID",
225+
"url" => "/api/?userstats&groupid=6"
226+
),
227+
"2" => array(
228+
"desc" => "Filter by multiple servergroup database IDs. Only one of the specified groups must apply to get the concerned user.",
229+
"url" => "/api/?userstats&groupid=6,9,48"
230+
)
231+
)
213232
),
214233
"limit" => array(
215234
"desc" => "Define a number that limits the number of results. Maximum value is 1000. Default is 100.",
@@ -273,10 +292,17 @@
273292
} else {
274293
$dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`user` {$filter} ORDER BY {$sort} {$order} LIMIT :start, :limit");
275294
if(isset($_GET['cldbid'])) $dbdata->bindValue(':cldbid', (int) $cldbid, PDO::PARAM_INT);
276-
if(isset($_GET['groupid'])) $dbdata->bindValue(':groupid', $groupid, PDO::PARAM_STR);
277-
if(isset($_GET['groupid'])) $dbdata->bindValue(':groupid0', $groupid.'%', PDO::PARAM_STR);
278-
if(isset($_GET['groupid'])) $dbdata->bindValue(':groupid1', '%'.$groupid.'%', PDO::PARAM_STR);
279-
if(isset($_GET['groupid'])) $dbdata->bindValue(':groupid2', '%'.$groupid, PDO::PARAM_STR);
295+
if(isset($_GET['groupid'])) {
296+
$groupid = htmlspecialchars_decode($_GET['groupid']);
297+
$explode_groupid = explode(',', $groupid);
298+
$cnt = 0;
299+
foreach($explode_groupid as $groupid) {
300+
$dbdata->bindValue(':groupid'.$cnt, $groupid, PDO::PARAM_STR); $cnt++;
301+
$dbdata->bindValue(':groupid'.$cnt, $groupid.',%', PDO::PARAM_STR); $cnt++;
302+
$dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid.',%', PDO::PARAM_STR); $cnt++;
303+
$dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid, PDO::PARAM_STR); $cnt++;
304+
}
305+
}
280306
if(isset($_GET['name'])) $dbdata->bindValue(':name', '%'.$name.'%', PDO::PARAM_STR);
281307
if(isset($_GET['uuid'])) $dbdata->bindValue(':uuid', '%'.$uuid.'%', PDO::PARAM_STR);
282308

@@ -294,8 +320,18 @@
294320
}
295321
if(isset($_GET['groupid'])) {
296322
$groupid = htmlspecialchars_decode($_GET['groupid']);
323+
$explode_groupid = explode(',', $groupid);
297324
if($filter != ' WHERE') $filter .= " AND";
298-
$filter .= " (`user`.`cldgroup` = :groupid OR `user`.`cldgroup` LIKE (:groupid0) OR `user`.`cldgroup` LIKE (:groupid1) OR `user`.`cldgroup` LIKE (:groupid2))";
325+
$filter .= " (";
326+
$cnt = 0;
327+
foreach($explode_groupid as $groupid) {
328+
if($cnt > 0) $filter .= " OR ";
329+
$filter .= "`user`.`cldgroup` = :groupid".$cnt; $cnt++;
330+
$filter .= " OR `user`.`cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
331+
$filter .= " OR `user`.`cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
332+
$filter .= " OR `user`.`cldgroup` LIKE (:groupid".$cnt.")"; $cnt++;
333+
}
334+
$filter .= ")";
299335
}
300336
if(isset($_GET['name'])) {
301337
$name = htmlspecialchars_decode($_GET['name']);
@@ -332,8 +368,17 @@
332368
),
333369
"groupid" => array(
334370
"desc" => "Get only user, which are in the given servergroup database ID",
335-
"usage" => "Use \$_GET parameter 'groupid' and add as value a database ID of a servergroup",
336-
"example" => "/api/?userstats&groupid=6"
371+
"usage" => "Use \$_GET parameter 'groupid' and add as value a database ID of a servergroup. Multiple servergroups can be specified comma-separated.",
372+
"example" => array(
373+
"1" => array(
374+
"desc" => "Filter by a single servergroup database ID",
375+
"url" => "/api/?userstats&groupid=6"
376+
),
377+
"2" => array(
378+
"desc" => "Filter by multiple servergroup database IDs. Only one of the specified groups must apply to get the concerned user.",
379+
"url" => "/api/?userstats&groupid=6,9,48"
380+
)
381+
)
337382
),
338383
"limit" => array(
339384
"desc" => "Define a number that limits the number of results. Maximum value is 1000. Default is 100.",
@@ -397,10 +442,17 @@
397442
} else {
398443
$dbdata = $mysqlcon->prepare("SELECT * FROM `$dbname`.`stats_user` INNER JOIN `$dbname`.`user` ON `user`.`uuid` = `stats_user`.`uuid` {$filter} ORDER BY {$sort} {$order} LIMIT :start, :limit");
399444
if(isset($_GET['cldbid'])) $dbdata->bindValue(':cldbid', (int) $cldbid, PDO::PARAM_INT);
400-
if(isset($_GET['groupid'])) $dbdata->bindValue(':groupid', $groupid, PDO::PARAM_STR);
401-
if(isset($_GET['groupid'])) $dbdata->bindValue(':groupid0', $groupid.'%', PDO::PARAM_STR);
402-
if(isset($_GET['groupid'])) $dbdata->bindValue(':groupid1', '%'.$groupid.'%', PDO::PARAM_STR);
403-
if(isset($_GET['groupid'])) $dbdata->bindValue(':groupid2', '%'.$groupid, PDO::PARAM_STR);
445+
if(isset($_GET['groupid'])) {
446+
$groupid = htmlspecialchars_decode($_GET['groupid']);
447+
$explode_groupid = explode(',', $groupid);
448+
$cnt = 0;
449+
foreach($explode_groupid as $groupid) {
450+
$dbdata->bindValue(':groupid'.$cnt, $groupid, PDO::PARAM_STR); $cnt++;
451+
$dbdata->bindValue(':groupid'.$cnt, $groupid.',%', PDO::PARAM_STR); $cnt++;
452+
$dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid.',%', PDO::PARAM_STR); $cnt++;
453+
$dbdata->bindValue(':groupid'.$cnt, '%,'.$groupid, PDO::PARAM_STR); $cnt++;
454+
}
455+
}
404456
if(isset($_GET['name'])) $dbdata->bindValue(':name', '%'.$name.'%', PDO::PARAM_STR);
405457
if(isset($_GET['uuid'])) $dbdata->bindValue(':uuid', '%'.$uuid.'%', PDO::PARAM_STR);
406458

install.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?PHP
2-
$rsversion = '1.3.15';
2+
$rsversion = '1.3.17';
33

44
require_once('other/_functions.php');
55
require_once('other/config.php');
@@ -168,7 +168,7 @@ function install($type, $host, $user, $pass, $dbname, $lang, $mysqlcon, &$err_ms
168168
$count++;
169169
}
170170

171-
if($mysqlcon->exec("INSERT INTO `$dbname`.`job_check` (`job_name`) VALUES ('calc_user_limit'),('calc_user_lastscan'),('check_update'),('database_export'),('get_version'),('clean_db'),('clean_clients'),('calc_donut_chars'),('calc_server_stats'),('get_avatars'),('last_snapshot_id'),('last_snapshot_time'),('last_update'),('reload_trigger'),('reset_user_time'),('reset_user_delete'),('reset_group_withdraw'),('reset_webspace_cache'),('reset_usage_graph'),('reset_stop_after'),('runtime_check'),('update_groups')") === false) {
171+
if($mysqlcon->exec("INSERT INTO `$dbname`.`job_check` (`job_name`) VALUES ('calc_user_limit'),('calc_user_lastscan'),('calc_user_removed'),('check_update'),('database_export'),('get_version'),('clean_db'),('clean_clients'),('calc_donut_chars'),('calc_server_stats'),('get_avatars'),('last_snapshot_id'),('last_snapshot_time'),('last_update'),('reload_trigger'),('reset_user_time'),('reset_user_delete'),('reset_group_withdraw'),('reset_webspace_cache'),('reset_usage_graph'),('reset_stop_after'),('runtime_check'),('update_groups')") === false) {
172172
$err_msg .= $lang['isntwidbmsg'].$mysqlcon->errorCode()." ".print_r($mysqlcon->errorInfo(), true).'<br>'; $err_lvl = 2;
173173
$count++;
174174
}

jobs/bot.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
ini_set("log_errors", 1);
1818

1919
require_once(substr(__DIR__,0,-4).'other/_functions.php');
20+
$persistent = 1;
2021
require_once(substr(__DIR__,0,-4).'other/config.php');
2122
$lang = set_language(get_language($cfg));
2223

@@ -71,6 +72,17 @@
7172
}
7273
enter_logfile($cfg,9,"Database Version: ".$mysqlcon->getAttribute(PDO::ATTR_SERVER_VERSION));
7374

75+
// enter_logfile($cfg,9,"Starting connection test to the Ranksystem update-server (may need a few seconds)...");
76+
// $update_server = fsockopen('193.70.102.252', 443, $errno, $errstr, 10);
77+
// if(!$update_server) {
78+
// enter_logfile($cfg,2," Connection to Ranksystem update-server failed: $errstr ($errno)");
79+
// enter_logfile($cfg,3," This connection is neccessary to receive updates for the Ranksystem!");
80+
// enter_logfile($cfg,3," Please whitelist the IP 193.70.102.252 (TCP port 443) on your network (firewall)");
81+
// } else {
82+
// enter_logfile($cfg,9," Connection test successful");
83+
// }
84+
// enter_logfile($cfg,9,"Starting connection test to the Ranksystem update-server [done]");
85+
7486
check_db($mysqlcon,$lang,$cfg,$dbname);
7587
$cfg['temp_db_version'] = $mysqlcon->getAttribute(PDO::ATTR_SERVER_VERSION);
7688
$cfg['temp_last_botstart'] = time();

jobs/calc_user.php

Lines changed: 40 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -33,38 +33,53 @@ function calc_user($ts3,$mysqlcon,$lang,$cfg,$dbname,$allclients,$phpcommand,&$d
3333
$temp_cldbid = $client['client_database_id'];
3434
}
3535
}
36-
$db_cache['all_user'][$uuid]['count'] += $value['timecount'];
37-
if($db_cache['all_user'][$uuid]['count'] < 0) {
38-
$db_cache['all_user'][$uuid]['count'] = $db_cache['all_user'][$uuid]['idle'] = 0;
39-
} elseif ($db_cache['all_user'][$uuid]['idle'] > $db_cache['all_user'][$uuid]['count']) {
40-
$db_cache['all_user'][$uuid]['idle'] = $db_cache['all_user'][$uuid]['count'];
41-
}
42-
if($isonline != 1) {
43-
if(($user = $mysqlcon->query("SELECT `uuid`,`cldbid` FROM `$dbname`.`user` WHERE `uuid`='{$uuid}'")->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE)) === false) {
44-
enter_logfile($cfg,2,"Database error on selecting user (admin function remove/add time): ".print_r($mysqlcon->errorInfo(), true));
36+
if($value['timecount'] == 0 && $value['timestamp'] == 4273093200) {
37+
//remove user
38+
if(($user = $mysqlcon->query("SELECT `uuid`,`cldbid`,`name` FROM `$dbname`.`user` WHERE `uuid`='{$uuid}'")->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE)) === false) {
39+
enter_logfile($cfg,2,"Database error on selecting user (admin function remove user): ".print_r($mysqlcon->errorInfo(), true));
4540
} else {
4641
$temp_cldbid = $user[$uuid]['cldbid'];
47-
$sqlexec .= "UPDATE `$dbname`.`user` SET `count`='{$db_cache['all_user'][$uuid]['count']}', `idle`='{$db_cache['all_user'][$uuid]['idle']}' WHERE `uuid`='{$uuid}';\n";
42+
$sqlexec .= "DELETE FROM `$dbname`.`addon_assign_groups` WHERE `uuid`='{$uuid}';\nDELETE FROM `$dbname`.`admin_addtime` WHERE `uuid`='{$uuid}';\nDELETE FROM `$dbname`.`stats_user` WHERE `uuid`='{$uuid}';\nDELETE FROM `$dbname`.`user` WHERE `uuid`='{$uuid}';\nDELETE FROM `$dbname`.`user_iphash` WHERE `uuid`='{$uuid}';\nDELETE FROM `$dbname`.`user_snapshot` WHERE `cldbid`='{$temp_cldbid}';\n";
43+
enter_logfile($cfg,4,sprintf($lang['wihladm45'],$user[$uuid]['name'],$uuid,$temp_cldbid).' ('.$lang['wihladm46'].')');
44+
if(isset($db_cache['all_user'][$uuid])) unset($db_cache['all_user'][$uuid]);
45+
if(isset($db_cache['admin_addtime'][$uuid])) unset($db_cache['admin_addtime'][$uuid]);
46+
if(isset($db_cache['addon_assign_groups'][$uuid])) unset($db_cache['addon_assign_groups'][$uuid]);
4847
}
49-
}
50-
if($mysqlcon->exec("DELETE FROM `$dbname`.`admin_addtime` WHERE `timestamp`=".$value['timestamp']." AND `uuid`='$uuid';") === false) {
51-
enter_logfile($cfg,2,"Database error on updating user (admin function remove/add time): ".print_r($mysqlcon->errorInfo(), true));
52-
}
53-
if(($usersnap = $mysqlcon->query("SELECT `id`,`cldbid`,`count`,`idle` FROM `$dbname`.`user_snapshot` WHERE `cldbid`={$temp_cldbid}")->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE)) === false) {
54-
enter_logfile($cfg,2,"Database error on selecting user (admin function remove/add time): ".print_r($mysqlcon->errorInfo(), true));
48+
unset($user);
5549
} else {
56-
foreach($usersnap as $id => $valuesnap) {
57-
$valuesnap['count'] += $value['timecount'];
58-
if($valuesnap['count'] < 0) {
59-
$valuesnap['count'] = $valuesnap['idle'] = 0;
60-
} elseif ($valuesnap['idle'] > $valuesnap['count']) {
61-
$valuesnap['idle'] = $valuesnap['count'];
50+
$db_cache['all_user'][$uuid]['count'] += $value['timecount'];
51+
if($db_cache['all_user'][$uuid]['count'] < 0) {
52+
$db_cache['all_user'][$uuid]['count'] = $db_cache['all_user'][$uuid]['idle'] = 0;
53+
} elseif ($db_cache['all_user'][$uuid]['idle'] > $db_cache['all_user'][$uuid]['count']) {
54+
$db_cache['all_user'][$uuid]['idle'] = $db_cache['all_user'][$uuid]['count'];
55+
}
56+
if($isonline != 1) {
57+
if(($user = $mysqlcon->query("SELECT `uuid`,`cldbid` FROM `$dbname`.`user` WHERE `uuid`='{$uuid}'")->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE)) === false) {
58+
enter_logfile($cfg,2,"Database error on selecting user (admin function remove/add time): ".print_r($mysqlcon->errorInfo(), true));
59+
} else {
60+
$temp_cldbid = $user[$uuid]['cldbid'];
61+
$sqlexec .= "UPDATE `$dbname`.`user` SET `count`='{$db_cache['all_user'][$uuid]['count']}', `idle`='{$db_cache['all_user'][$uuid]['idle']}' WHERE `uuid`='{$uuid}';\n";
62+
}
63+
}
64+
if($mysqlcon->exec("DELETE FROM `$dbname`.`admin_addtime` WHERE `timestamp`=".$value['timestamp']." AND `uuid`='$uuid';") === false) {
65+
enter_logfile($cfg,2,"Database error on updating user (admin function remove/add time): ".print_r($mysqlcon->errorInfo(), true));
66+
}
67+
if(($usersnap = $mysqlcon->query("SELECT `id`,`cldbid`,`count`,`idle` FROM `$dbname`.`user_snapshot` WHERE `cldbid`={$temp_cldbid}")->fetchAll(PDO::FETCH_ASSOC|PDO::FETCH_UNIQUE)) === false) {
68+
enter_logfile($cfg,2,"Database error on selecting user (admin function remove/add time): ".print_r($mysqlcon->errorInfo(), true));
69+
} else {
70+
foreach($usersnap as $id => $valuesnap) {
71+
$valuesnap['count'] += $value['timecount'];
72+
if($valuesnap['count'] < 0) {
73+
$valuesnap['count'] = $valuesnap['idle'] = 0;
74+
} elseif ($valuesnap['idle'] > $valuesnap['count']) {
75+
$valuesnap['idle'] = $valuesnap['count'];
76+
}
77+
$sqlexec .= "UPDATE `$dbname`.`user_snapshot` SET `count`='{$valuesnap['count']}', `idle`='{$valuesnap['idle']}' WHERE `cldbid`='{$temp_cldbid}' AND `id`='{$id}';\n";
6278
}
63-
$sqlexec .= "UPDATE `$dbname`.`user_snapshot` SET `count`='{$valuesnap['count']}', `idle`='{$valuesnap['idle']}' WHERE `cldbid`='{$temp_cldbid}' AND `id`='{$id}';\n";
6479
}
80+
enter_logfile($cfg,4,sprintf($lang['sccupcount2'],$value['timecount'],$uuid).' ('.$lang['wihladm46'].')');
81+
unset($user, $usersnap);
6582
}
66-
enter_logfile($cfg,4,sprintf($lang['sccupcount2'],$value['timecount'],$uuid));
67-
unset($user, $usersnap);
6883
}
6984
}
7085
unset($db_cache['admin_addtime']);

jobs/calc_userstats.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,12 @@ function calc_userstats($ts3,$mysqlcon,$cfg,$dbname,&$db_cache) {
134134
$sqlexec .= "UPDATE `$dbname`.`job_check` SET `timestamp`=$job_end WHERE `job_name`='calc_user_limit';\n";
135135
}
136136
}
137+
138+
if ($db_cache['job_check']['calc_user_removed']['timestamp'] < ($nowtime - 1800)) {
139+
$db_cache['job_check']['calc_user_removed']['timestamp'] = $nowtime;
140+
$atime = $nowtime - 3600;
141+
$sqlexec .= "UPDATE `$dbname`.`stats_user` AS `s` INNER JOIN `$dbname`.`user` AS `u` ON `s`.`uuid`=`u`.`uuid` SET `s`.`removed`='0' WHERE `s`.`removed`='1' AND `u`.`lastseen`>{$atime};\nUPDATE `$dbname`.`job_check` SET `timestamp`='{$nowtime}' WHERE `job_name`='calc_user_removed';\n";
142+
}
137143

138144
enter_logfile($cfg,6,"calc_userstats needs: ".(number_format(round((microtime(true) - $starttime), 5),5)));
139145
return($sqlexec);

0 commit comments

Comments
 (0)