diff --git a/.bin/geoip2-csv-converter b/.bin/geoip2-csv-converter new file mode 100755 index 0000000..957bd0f Binary files /dev/null and b/.bin/geoip2-csv-converter differ diff --git a/app/LoginWatch.php b/app/LoginWatch.php index cf91e5a..386462a 100644 --- a/app/LoginWatch.php +++ b/app/LoginWatch.php @@ -200,7 +200,7 @@ class LoginWatch extends Base { (ip.FromIP IS NOT NULL) AS banned FROM login_attempts w LEFT JOIN users_main um ON (um.ID = w.UserID) - LEFT JOIN ip_bans ip ON (ip.FromIP = inet_aton(w.IP)) + LEFT JOIN ip_bans ip ON (ip.FromIP = inet6_aton(w.IP)) WHERE (w.BannedUntil > now() OR w.LastAttempt > now() - INTERVAL 6 HOUR) ORDER BY $orderBy $orderWay "); @@ -219,9 +219,9 @@ class LoginWatch extends Base { $reason = trim($reason); $n = 0; foreach ($list as $id) { - $ipv4 = $this->db->scalar( + $ip = $this->db->scalar( " - SELECT inet_aton(IP) FROM login_attempts WHERE ID = ? + SELECT inet6_aton(IP) FROM login_attempts WHERE ID = ? ", $id ); @@ -233,8 +233,8 @@ class LoginWatch extends Base { ", $userId, $reason, - $ipv4, - $ipv4 + $ip, + $ip ); $n += $this->db->affected_rows(); } diff --git a/app/Manager/IPv4.php b/app/Manager/IPv4.php index cfe7073..0531445 100644 --- a/app/Manager/IPv4.php +++ b/app/Manager/IPv4.php @@ -2,55 +2,9 @@ namespace Gazelle\Manager; -class IPv4 extends \Gazelle\Base { +class IP extends \Gazelle\Base { - const CACHE_KEY = 'ipv4_bans_'; - - /** - * Returns the unsigned 32bit form of an IPv4 address - * - * @param string $ipv4 The IP address x.x.x.x - * @return string the long it represents. - */ - public function ip2ulong(string $ipv4) { - return sprintf('%u', ip2long($ipv4)); - } - - /** - * Returns true if given IP is banned. - * TODO: This looks really braindead. Why not compare the 32bit address - * directly BETWEEN FromIP AND ToIP? Apart from dubious merits of - * caching? - * - * @param string $IP - * @return bool True if banned - */ - public function isBanned(string $IP) { - $A = substr($IP, 0, strcspn($IP, '.')); - $key = self::CACHE_KEY . $A; - $IPBans = $this->cache->get_value($key); - if (!is_array($IPBans)) { - $this->db->prepared_query( - " - SELECT FromIP, ToIP, ID - FROM ip_bans - WHERE FromIP BETWEEN ? << 24 AND (? << 24) - 1 - ", - $A, - $A + 1 - ); - $IPBans = $this->db->to_array(0, MYSQLI_NUM); - $this->cache->cache_value($key, $IPBans, 0); - } - $IPNum = $this->ip2ulong($IP); - foreach ($IPBans as $IPBan) { - list($FromIP, $ToIP) = $IPBan; - if ($IPNum >= $FromIP && $IPNum <= $ToIP) { - return true; - } - } - return false; - } + const CACHE_KEY = 'ip_bans_'; /** * Create an ip address ban over a range of addresses. Will append @@ -61,16 +15,14 @@ class IPv4 extends \Gazelle\Base { * @param string $to The last adddress in the range (may equal $from) * @param string $reason Why ban? */ - public function createBan(int $userId, $ipv4From, string $ipv4To, string $reason) { - $from = $this->ip2ulong($ipv4From); - $to = $this->ip2ulong($ipv4To); + public function createBan(int $userId, $ipFrom, string $ipTo, string $reason) { $current = $this->db->scalar( ' SELECT Reason FROM ip_bans - WHERE ? BETWEEN FromIP AND ToIP + WHERE INET6_ATON(?) BETWEEN FromIP AND ToIP ', - $from + $ipFrom ); if ($current) { @@ -81,13 +33,13 @@ class IPv4 extends \Gazelle\Base { Reason = concat(?, ' AND ', Reason), user_id = ?, created = now() - WHERE FromIP = ? - AND ToIP = ? + WHERE FromIP = INET6_ATON(?) + AND ToIP = INET6_ATON(?) ", $reason, $userId, - $from, - $to + $ipFrom, + $ipTo ); } } else { // Not yet banned @@ -95,15 +47,15 @@ class IPv4 extends \Gazelle\Base { " INSERT INTO ip_bans (Reason, FromIP, ToIP, user_id) - VALUES (?, ?, ?, ?) + VALUES (?, ?, INET6_ATON(?), INET6_ATON(?)) ", $reason, - $from, - $to, + $ipFrom, + $ipTo, $userId ); $this->cache->delete_value( - self::CACHE_KEY . substr($ipv4From, 0, strcspn($ipv4From, '.')) + self::CACHE_KEY . substr($ipFrom, 0, strcspn($ipFrom, '.')) ); } } @@ -116,7 +68,7 @@ class IPv4 extends \Gazelle\Base { public function removeBan(int $id) { $fromClassA = $this->db->scalar( " - SELECT FromIP >> 24 FROM ip_bans WHERE ID = ? + SELECT INET6_NTOA(FromIP) FROM ip_bans WHERE ID = ? ", $id ); diff --git a/classes/donationsview.class.php b/classes/donationsview.class.php index 2b862e4..bb21a41 100644 --- a/classes/donationsview.class.php +++ b/classes/donationsview.class.php @@ -32,10 +32,10 @@ class DonationsView {
UserID; ?> -
+
query(" SELECT TreePosition, TreeID, TreeLevel @@ -113,11 +113,14 @@ class INVITE_TREE { if ($Donor) { $DonorCount++; } - // Manage tree depth if ($TreeLevel > $PreviousTreeLevel) { for ($i = 0; $i < $TreeLevel - $PreviousTreeLevel; $i++) { - echo "\n\n
+
+
set_query_id($QueryID); diff --git a/classes/tools.class.php b/classes/tools.class.php index b460f8a..55de4f7 100644 --- a/classes/tools.class.php +++ b/classes/tools.class.php @@ -6,41 +6,13 @@ class Tools { * @param string $IP */ public static function site_ban_ip($IP) { - global $Debug; - $A = substr($IP, 0, strcspn($IP, '.')); - $IPNum = Tools::ip_to_unsigned($IP); - $IPBans = G::$Cache->get_value('ip_bans_' . $A); - if (!is_array($IPBans)) { - $SQL = sprintf(" - SELECT ID, FromIP, ToIP - FROM ip_bans - WHERE FromIP BETWEEN %d << 24 AND (%d << 24) - 1", $A, $A + 1); - $QueryID = G::$DB->get_query_id(); - G::$DB->query($SQL); - $IPBans = G::$DB->to_array(0, MYSQLI_NUM); - G::$DB->set_query_id($QueryID); - G::$Cache->cache_value('ip_bans_' . $A, $IPBans, 0); + G::$DB->prepared_query('SELECT ID FROM ip_bans WHERE INET6_ATON(?) BETWEEN FromIP and ToIP', $IP); + if (G::$DB->has_results() > 0) { + return true; } - foreach ($IPBans as $Index => $IPBan) { - list($ID, $FromIP, $ToIP) = $IPBan; - if ($IPNum >= $FromIP && $IPNum <= $ToIP) { - return true; - } - } - return false; } - /** - * Returns the unsigned form of an IP address. - * - * @param string $IP The IP address x.x.x.x - * @return string the long it represents. - */ - public static function ip_to_unsigned($IP) { - return sprintf('%u', ip2long($IP)); - } - /** * Geolocate an IP address using the database * @@ -52,22 +24,14 @@ class Tools { if (isset($IPs[$IP])) { return $IPs[$IP]; } - if (is_number($IP)) { - $Long = $IP; - } else { - $Long = Tools::ip_to_unsigned($IP); - } - if (!$Long || $Long == 2130706433) { // No need to check cc for 127.0.0.1 - return false; - } $QueryID = G::$DB->get_query_id(); G::$DB->query(" - SELECT EndIP, Code + SELECT Code FROM geoip_country - WHERE $Long >= StartIP + WHERE INET6_ATON('$IP')>= StartIP and INET6_ATON('$IP') < EndIP ORDER BY StartIP DESC LIMIT 1"); - if ((!list($EndIP, $Country) = G::$DB->next_record()) || $EndIP < $Long) { + if ((!list($Country) = G::$DB->next_record())) { $Country = '?'; } G::$DB->set_query_id($QueryID); @@ -151,7 +115,7 @@ class Tools { */ public static function display_ip($IP) { $Line = display_str($IP) . ' (' . Tools::get_country_code_by_ajax($IP) . ') '; - $Line .= '' . t('server.common.search') . ''; + $Line .= '' . S . ''; return $Line; } @@ -299,18 +263,4 @@ class Tools { WHERE UserID = \'' . db_string($UserID) . '\''); G::$DB->set_query_id($QueryID); } - - /** - * Check if an IP address is part of a given CIDR range. - * @param string $CheckIP the IP address to be looked up - * @param string $Subnet the CIDR subnet to be checked against - */ - public static function check_cidr_range($CheckIP, $Subnet) { - $IP = ip2long($CheckIP); - $CIDR = split('/', $Subnet); - $SubnetIP = ip2long($CIDR[0]); - $SubnetMaskBits = 32 - $CIDR[1]; - - return (($IP >> $SubnetMaskBits) == ($SubnetIP >> $SubnetMaskBits)); - } } diff --git a/db/migrations/20221205120723_ipv6.php b/db/migrations/20221205120723_ipv6.php new file mode 100644 index 0000000..c8631c1 --- /dev/null +++ b/db/migrations/20221205120723_ipv6.php @@ -0,0 +1,85 @@ +table('ip_bans') + ->renameColumn('FromIP', 'FromIP_Old') + ->renameColumn('ToIP', 'ToIP_Old') + ->addColumn('FromIP', 'varbinary', ['length' => 16]) + ->addColumn('ToIP', 'varbinary', ['length' => 16]) + ->save(); + $this->execute('UPDATE ip_bans SET FromIP=INET6_ATON(INET_NTOA(FromIP_Old)), ToIP=INET6_ATON(INET_NTOA(ToIP_Old));'); + + $this->table('geoip_country') + ->renameColumn('StartIP', 'StartIP_Old') + ->renameColumn('EndIP', 'EndIP_Old') + ->addColumn('StartIP', 'varbinary', ['length' => 16]) + ->addColumn('EndIP', 'varbinary', ['length' => 16]) + ->save(); + $this->execute('UPDATE geoip_country SET StartIP=INET6_ATON(INET_NTOA(StartIP_Old)), EndIP=INET6_ATON(INET_NTOA(EndIP_Old));'); + + $this->table('login_attempts') + ->changeColumn('IP', 'string', ['length' => 45]) + ->save(); + $this->table('users_history_ips') + ->changeColumn('IP', 'string', ['length' => 45]) + ->save(); + $this->table('users_main') + ->changeColumn('IP', 'string', ['length' => 45]) + ->save(); + $this->table('users_history_ips') + ->changeColumn('IP', 'string', ['length' => 45]) + ->save(); + $this->table('users_history_emails') + ->changeColumn('IP', 'string', ['length' => 45]) + ->save(); + $this->table('users_history_passkeys') + ->changeColumn('ChangerIP', 'string', ['length' => 45]) + ->save(); + $this->table('users_history_passkeys') + ->changeColumn('ChangerIP', 'string', ['length' => 45]) + ->save(); + $this->table('users_sessions') + ->changeColumn('IP', 'string', ['length' => 45]) + ->save(); + $this->table('apply_user') + ->changeColumn('IP', 'string', ['length' => 45]) + ->save(); + $this->table('ip_lock') + ->changeColumn('IPs', 'string', ['length' => 255]) + ->save(); + $this->table('register_apply_link') + ->changeColumn('IP', 'string', ['length' => 45]) + ->save(); + $this->table('users_enable_requests') + ->changeColumn('IP', 'string', ['length' => 45]) + ->save(); + } +} diff --git a/db/migrations/20221205144841_ipv6_index.php b/db/migrations/20221205144841_ipv6_index.php new file mode 100644 index 0000000..e3ead4c --- /dev/null +++ b/db/migrations/20221205144841_ipv6_index.php @@ -0,0 +1,35 @@ +table('ip_bans')->removeIndexByName('FromIP_2')->removeIndexByName('ToIP')->addIndex(['FromIP', 'ToIP'], ['unique' => true])->save(); + $this->table('geoip_country')->changePrimaryKey(['StartIP', 'EndIP'])->save(); + } +} diff --git a/public/static/functions/reports.js b/public/static/functions/reports.js index e7377ee..6092dec 100644 --- a/public/static/functions/reports.js +++ b/public/static/functions/reports.js @@ -33,8 +33,9 @@ function claim(id) { } if (json['status'] == 'success') { var username = json['username'] - $('#claim_' + id).raw().innerHTML = - 'Claimed by ' + username + '' + $('#claim_' + id).ghide() + $('#unclaim_' + id).gshow() + $('#claimer_' + id).raw().innerHTML = username } }) } @@ -46,12 +47,9 @@ function unClaim(id) { ajax.post('reports.php?action=unclaim', post, function (response) { var json = JSON.parse(response) if (json['status'] == 'success') { - $('#claimed_' + id).raw().innerHTML = - 'Claim' + $('#claim_' + id).gshow() + $('#unclaim_' + id).ghide() + $('#claimer_' + id).raw().innerHTML = '' } }) } @@ -60,26 +58,20 @@ function resolve(id, claimer) { var answer = true if (!claimer) { if ($('#claimed_' + id).raw()) { - var answer = confirm( - 'This is a claimed report. Are you sure you want to resolve it?' - ) + var answer = confirm('This is a claimed report. Are you sure you want to resolve it?') if (answer) answer = true else answer = false } } if (answer) { - ajax.post( - 'reports.php?action=resolve', - 'report_form_' + id, - function (response) { - var json = JSON.parse(response) - if (json['status'] == 'success') { - $('#report_' + id).remove() - } else { - alert(json['status']) - } + ajax.post('reports.php?action=resolve', 'report_form_' + id, function (response) { + var json = JSON.parse(response) + if (json['status'] == 'success') { + $('#report_' + id).remove() + } else { + alert(json['status']) } - ) + }) } return false } diff --git a/sections/bonus/bprates.php b/sections/bonus/bprates.php index 4f1e17c..575bf12 100644 --- a/sections/bonus/bprates.php +++ b/sections/bonus/bprates.php @@ -64,7 +64,42 @@ $TotalMonthlyPoints = $TotalDailyPoints * 30.436875; $TotalYearlyPoints = $TotalDailyPoints * 365.2425; $Pages = Format::get_pages($Page, $TotalTorrents, CONFIG['TORRENTS_PER_PAGE']); +if ($TotalTorrents > 0) { + $DB->prepared_query(" + SELECT + t.ID, + t.GroupID, + t.Size, + t.Size / (1024 * 1024 * 1024) as CorrectSize, + t.Codec, + t.Source, + t.Processing, + t.Container, + t.Resolution, + t.Scene, + t.RemasterYear, + t.RemasterTitle, + t.Slot, + GREATEST(t.Seeders, 1) AS Seeders, + xfh.seedtime AS Seedtime, + (t.Size / (1024 * 1024 * 1024) * 1 *( + 0.025 + ( + (0.06 * LN(1 + (xfh.seedtime / (24)))) / (POW(GREATEST(t.Seeders, 1), 0.6)) + ) + )) AS HourlyPoints + FROM + (SELECT DISTINCT uid,fid FROM xbt_files_users WHERE active=1 AND remaining=0 AND mtime > unix_timestamp(NOW() - INTERVAL 1 HOUR) AND uid = ?) AS xfu + JOIN xbt_files_history AS xfh ON xfh.uid = xfu.uid AND xfh.fid = xfu.fid + JOIN torrents AS t ON t.ID = xfu.fid + WHERE + xfu.uid = ? + $OrderBy + LIMIT ? + OFFSET ?", $UserID, $UserID, $Limit, $Offset); + $GroupIDs = $DB->collect('GroupID'); + $Groups = Torrents::get_groups($GroupIDs, true, true, false); +} ?>
@@ -134,59 +169,26 @@ $Pages = Format::get_pages($Page, $TotalTorrents, CONFIG['TORRENTS_PER_PAGE']); -
- - - - - - - - - - - - - - - - 0) { - $DB->prepared_query(" - SELECT - t.ID, - t.GroupID, - t.Size, - t.Size / (1024 * 1024 * 1024) as CorrectSize, - t.Codec, - t.Source, - t.Processing, - t.Container, - t.Resolution, - t.Scene, - t.RemasterYear, - t.RemasterTitle, - t.Slot, - GREATEST(t.Seeders, 1) AS Seeders, - xfh.seedtime AS Seedtime, - (t.Size / (1024 * 1024 * 1024) * 1 *( - 0.025 + ( - (0.06 * LN(1 + (xfh.seedtime / (24)))) / (POW(GREATEST(t.Seeders, 1), 0.6)) - ) - )) AS HourlyPoints - FROM - (SELECT DISTINCT uid,fid FROM xbt_files_users WHERE active=1 AND remaining=0 AND mtime > unix_timestamp(NOW() - INTERVAL 1 HOUR) AND uid = ?) AS xfu - JOIN xbt_files_history AS xfh ON xfh.uid = xfu.uid AND xfh.fid = xfu.fid - JOIN torrents AS t ON t.ID = xfu.fid - WHERE - xfu.uid = ? - $OrderBy - LIMIT ? - OFFSET ?", $UserID, $UserID, $Limit, $Offset); - - $GroupIDs = $DB->collect('GroupID'); - $Groups = Torrents::get_groups($GroupIDs, true, true, false); + 0) { + ?> +
+
">">">">
+ + + + + + + + + + + + + + + next_record(MYSQLI_ASSOC)) { $Size = intval($Torrent['Size']); $CorrectSize = $Torrent['CorrectSize']; @@ -201,7 +203,7 @@ $Pages = Format::get_pages($Page, $TotalTorrents, CONFIG['TORRENTS_PER_PAGE']); 'SettingTorrentTitle' => G::$LoggedUser['SettingTorrentTitle'], ]); $DisplayName = '' . $Name . ''; - ?> + ?> @@ -213,22 +215,12 @@ $Pages = Format::get_pages($Page, $TotalTorrents, CONFIG['TORRENTS_PER_PAGE']); - - - - - - - -
">">">">
-
+ + + +
+
- \ No newline at end of file diff --git a/sections/bonus/index.php b/sections/bonus/index.php index 6396723..b4173ce 100644 --- a/sections/bonus/index.php +++ b/sections/bonus/index.php @@ -13,6 +13,7 @@ if (isset($_GET['action'])) { switch ($_GET['action']) { case 'purchase': /* handle validity and cost as early as possible */ + if (isset($_REQUEST['label']) && preg_match('/^[a-z]{1,15}(-\w{1,15}){0,4}/', $_REQUEST['label'])) { $Label = $_REQUEST['label']; $Item = $Bonus->getItem($Label); diff --git a/sections/bonus/store.php b/sections/bonus/store.php index b48351f..472c216 100644 --- a/sections/bonus/store.php +++ b/sections/bonus/store.php @@ -5,12 +5,12 @@ View::show_header('积分商城', 'bonus', 'PageBonusStore'); if (isset($_GET['complete'])) { $label = $_GET['complete']; $item = $Bonus->getItem($label); + $Items = $Bonus->getList(); ?> -
- " -
+ getList(); ?>
@@ -24,66 +24,74 @@ if (isset($_GET['complete'])) {
-
- - - - - - - - - - - + ""  + + 0) { ?> +
+
#
+ + + + + + + + + + getList(); + $Cnt = 0; - foreach ($Items as $Label => $Item) { - /* + foreach ($Items as $Label => $Item) { + /* if ($Item['MinClass'] > G::$LoggedUser['EffectiveClass']) { continue; } */ - $Cnt++; - $Price = $Bonus->getEffectivePrice($Label, G::$LoggedUser['EffectiveClass']); - $FormattedPrice = number_format($Price); - ?> - - - - - + + + + HTML; - } - ?> - -
#
- $LoggedUser['EffectiveClass']) { - ?> - + $Cnt++; + $Price = $Bonus->getEffectivePrice($Label, G::$LoggedUser['EffectiveClass']); + $FormattedPrice = number_format($Price); + ?> +
= $Price) { - $NextFunction = preg_match('/^other-\d$/', $Label) ? 'ConfirmOther' : 'null'; - $OnClick = preg_match('/^title-bbcode-[yn]$/', $Label) ? "NoOp" : "ConfirmPurchase"; + if ($Item['MinClass'] > $LoggedUser['EffectiveClass']) { ?> - - + - - = $Price) { + $NextFunction = preg_match('/^other-\d$/', $Label) ? 'ConfirmOther' : 'null'; + $OnClick = preg_match('/^title-bbcode-[yn]$/', $Label) ? "NoOp" : "ConfirmPurchase"; + ?> + + + +
-
+ } + ?> + + +
+
+ channel('Gazelle Change Log', 'RSS feed for Gazelle\'s changelog.'); if (!$Changelog = $Cache->get_value('changelog')) { require(CONFIG['SERVER_ROOT'] . '/classes/mysql.class.php'); - require(CONFIG['SERVER_ROOT'] . '/classes/misc.class.php'); $DB = new DB_MYSQL; $DB->query(" diff --git a/sections/forums/search.php b/sections/forums/search.php index 5c84ef0..3c2caf6 100644 --- a/sections/forums/search.php +++ b/sections/forums/search.php @@ -93,126 +93,128 @@ View::show_header(t('server.forums.forums_greater_than_search'), 'bbcode,forum_s
- - - - - - - - - - - - - - +
+
: - -
: - -
: - : - - : - -
- + - - + + + + + + - - - - -
:: -
- /> - -
-
- /> - -
+
:
: + +
: : - + : - +
: - - - - - - + + + + + + + + + + + - - - + + +
: +
+ /> + +
+
+ /> + +
+
: + : + + : + +
: + + - - + + + + + + + + + + + + - - - - - - - - - - - -
- - + + $Columns++; + + if ($Forum['CategoryID'] != $LastCategoryID) { + $LastCategoryID = $Forum['CategoryID']; + if ($Open) { + if ($Columns % 5) { ?> +
+ + +
+
+ /> + +
-
- /> - -
-
- - - -
- + +
+ + +
+ + + +
+
+ +
+
query(" @@ -81,31 +87,40 @@ $Owner = display_str($Owner); ORDER BY Reports DESC"); $Results = $DB->to_array(); ?> -

-
- - - - - - - - - +
+
+
+ +
+
+
+
+ + + - -
+ + + + + + + +
+ + +
query(" SELECT @@ -119,32 +134,39 @@ $Owner = display_str($Owner); ORDER BY Reports DESC"); $Results = $DB->to_array(); ?> -

-
- - - - - - - - - +
+
+
+ +
+
+
+
+ + + - -
+ + + + + + + +
query(" SELECT um.ID, @@ -156,33 +178,39 @@ $Owner = display_str($Owner); ORDER BY Reports DESC"); $Results = $DB->to_array(); ?> -

-
- - - - - - - - - +
+
+
+ +
+
+
+
+ + + - -
+ + + + + + + +
-
+
query(" SELECT @@ -196,72 +224,84 @@ $Owner = display_str($Owner); $Staff = $DB->to_array(); ?> -

-
- - - - - - - - - +
+
+
+ +
+
+
+
- -
+ + + - -
+ + + + + + + + + +
-

- query(" +
+
+
+ +
+
+
+ query(" SELECT Type, COUNT(ID) AS Count FROM reportsv2 WHERE Status = 'New' GROUP BY Type"); - $Current = $DB->to_array(); - if (!empty($Current)) { - ?> -
- - - - - - - > - - - - to_array(); + if (!empty($Current)) { ?> -
- - - -
+ + + + + + + > + + + + +
+ + + +
+
diff --git a/sections/requests/request.php b/sections/requests/request.php index 0d1134b..047b053 100644 --- a/sections/requests/request.php +++ b/sections/requests/request.php @@ -91,7 +91,7 @@ View::show_header(t('server.requests.view_request') . ": $FullName", 'comments,b diff --git a/sections/schedule/disabled/update_geoip.php b/sections/schedule/disabled/update_geoip.php index fdbffb0..28fdff2 100644 --- a/sections/schedule/disabled/update_geoip.php +++ b/sections/schedule/disabled/update_geoip.php @@ -4,7 +4,7 @@ $DB->query("INSERT INTO users_geodistribution (Code, Users) SELECT g.Code, COUNT(u.ID) AS Users FROM geoip_country AS g - JOIN users_main AS u ON INET_ATON(u.IP) BETWEEN g.StartIP AND g.EndIP + JOIN users_main AS u ON INET6_ATON(u.IP) BETWEEN g.StartIP AND g.EndIP WHERE u.Enabled = '1' GROUP BY g.Code ORDER BY Users DESC"); diff --git a/sections/staffpm/scoreboard.php b/sections/staffpm/scoreboard.php index 58d91b3..f8ac437 100644 --- a/sections/staffpm/scoreboard.php +++ b/sections/staffpm/scoreboard.php @@ -74,116 +74,123 @@ View::show_header('Staff Inbox', 'PageStaffPMScoreboard'); $DB->prepared_query($BaseSQL, 1, 1, $LoggedUser['Class'], ...$SupportStaff); $Results = $DB->to_array(); ?> -
-
-
+
+
+
+
+
+
+
+ + + + + + + + + + + + + +
+
+
+
+
+
+
+
+ + + + + + + + + + + + + +
+
+
-
- - - - - - - - - - - - - -
+ prepared_query($BaseSQL, 7, 7, $LoggedUser['Class'], ...$SupportStaff); + $Results = $DB->to_array(); + ?> +
+
+
+
+
+
+ + + + + + + + + + + + + +
+
+
-
- prepared_query($BaseSQL, 7, 7, $LoggedUser['Class'], ...$SupportStaff); - $Results = $DB->to_array(); - ?> -
-
-
-
-
- - - - - - - - - - - - - -
-
-
- prepared_query($BaseSQL, 30, 30, $LoggedUser['Class'], ...$SupportStaff); - $Results = $DB->to_array(); - ?> -
-
-
-
-
- - - - - - - - - - - - - -
-
-
- prepared_query($BaseSQL, 365000, 365000, $LoggedUser['Class'], ...$SupportStaff); - $Results = $DB->to_array(); - ?> -
-
-
-
-
- - - - - - - - - - - - - -
+ prepared_query($BaseSQL, 30, 30, $LoggedUser['Class'], ...$SupportStaff); + $Results = $DB->to_array(); + ?> +
+
+
+
+
+
+ + + + + + + + + + + + + +
+
+
+ prepared_query($BaseSQL, 365000, 365000, $LoggedUser['Class'], ...$SupportStaff); + $Results = $DB->to_array(); + ?>
-
- () - H S WI
+ H S WI
( ) - H S WI
+ H S WI
diff --git a/sections/tools/development/service_stats.php b/sections/tools/development/service_stats.php index 0b78023..b21efe0 100644 --- a/sections/tools/development/service_stats.php +++ b/sections/tools/development/service_stats.php @@ -26,9 +26,9 @@ View::show_header(t('server.tools.service_stats'), '', 'PageToolSericeStat');
-
-
diff --git a/sections/tools/managers/award.php b/sections/tools/managers/award.php index 654a23c..688b13b 100644 --- a/sections/tools/managers/award.php +++ b/sections/tools/managers/award.php @@ -1,6 +1,6 @@ -

- - -
+
+
+

+
- 0, - 'UploadCount' => 0, - 'CheckCount' => 0, - 'RSReportCount' => 0, - 'RPReportCount' => 0, - 'EditCount' => 0, - 'PostCount' => 0, - 'SendJF' => 0, - 'Point' => 0, - 'ApplyCount' => 0, -]; -makePoint($AwardDatas, $Bases, $PointRadios, $MaxValue); -//print_r ($AwardDatas); -?> - -

[$Year]]) . ($Month ? t('server.tools.month', ['Values' => [$Month]]) : "") . ($Quarter ? "$QUARTER[$Quarter]" : "") ?>

-

-
-
-
-
- " . Users::format_username($User['UserID'], false, false, false) . "
"; - } - } - if (!$first) { - $GroupNameMap = ['Moderator' => 'Mod', 'Torrent Moderator' => 'TM', 'Forum Moderator' => 'FM', 'Torrent Inspector' => 'TI', 'First Line Support' => 'FLS', 'Interviewer' => 'IN', 'Translators' => 'TL', 'Senior Moderator' => 'SM', 'Developer' => 'Dev', 'Administrator' => 'AD']; - if (isset($GroupNameMap[$data['GroupName']])) { - echo "
" . $GroupNameMap[$data['GroupName']] . "
"; - } else { - echo "
" . $data['GroupName'] . "
"; - } - echo $headLeftUsers; - } - } - ?> -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
+
+
+
+
-
>
-
>
-
>
-
>
-
>
-
>
-
>
-
>
-
-
-
>
-
>
-
-
-
- " . Users::format_username($User['UserID'], false, false, false) . "
"; } } + if (!$first) { + $GroupNameMap = ['Moderator' => 'Mod', 'Torrent Moderator' => 'TM', 'Forum Moderator' => 'FM', 'Torrent Inspector' => 'TI', 'First Line Support' => 'FLS', 'Interviewer' => 'IN', 'Translators' => 'TL', 'Senior Moderator' => 'SM', 'Developer' => 'Dev', 'Administrator' => 'AD']; + if (isset($GroupNameMap[$data['GroupName']])) { + echo "
" . $GroupNameMap[$data['GroupName']] . "
"; + } else { + echo "
" . $data['GroupName'] . "
"; + } + echo $headLeftUsers; + } } ?>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ +
+
+ +
>
+
>
+
>
+
>
+
>
+
>
+
>
+
>
+
+
+
>
+
>
+
+
+
+ +
+
+
-
+
+ + + -
@@ -1147,7 +1174,7 @@ WHERE xs.uid =" . $UserID . " and xs.tstamp >= unix_timestamp(date_format(now(),
- +
diff --git a/sections/userhistory/copypaste.php b/sections/userhistory/copypaste.php index 9234409..a65de10 100644 --- a/sections/userhistory/copypaste.php +++ b/sections/userhistory/copypaste.php @@ -32,7 +32,7 @@ $DB->prepared_query(" u.IP, c.Code FROM users_main AS u - LEFT JOIN geoip_country AS c ON INET_ATON(u.IP) BETWEEN c.StartIP AND c.EndIP + LEFT JOIN geoip_country AS c ON INET6_ATON(u.IP) BETWEEN c.StartIP AND c.EndIP WHERE u.ID = ? UNION SELECT @@ -41,7 +41,7 @@ $DB->prepared_query(" h.IP, c.Code FROM users_history_emails AS h - LEFT JOIN geoip_country AS c ON INET_ATON(h.IP) BETWEEN c.StartIP AND c.EndIP + LEFT JOIN geoip_country AS c ON INET6_ATON(h.IP) BETWEEN c.StartIP AND c.EndIP WHERE UserID = ? " /*AND Time != '0000-00-00 00:00:00'*/ . " ORDER BY Time DESC", sqltime(), $UserID, $UserID); diff --git a/sections/userhistory/email_history.php b/sections/userhistory/email_history.php index f86ea24..f7042c9 100644 --- a/sections/userhistory/email_history.php +++ b/sections/userhistory/email_history.php @@ -47,7 +47,7 @@ if ($UsersOnly == 1) { c.Code FROM users_main AS u LEFT JOIN users_main AS u2 ON u2.Email = u.Email AND u2.ID != '$UserID' - LEFT JOIN geoip_country AS c ON INET_ATON(u.IP) BETWEEN c.StartIP AND c.EndIP + LEFT JOIN geoip_country AS c ON INET6_ATON(u.IP) BETWEEN c.StartIP AND c.EndIP WHERE u.ID = '$UserID' AND u2.ID > 0 UNION @@ -58,7 +58,7 @@ if ($UsersOnly == 1) { c.Code FROM users_history_emails AS h LEFT JOIN users_history_emails AS h2 ON h2.email = h.email and h2.UserID != '$UserID' - LEFT JOIN geoip_country AS c ON INET_ATON(h.IP) BETWEEN c.StartIP AND c.EndIP + LEFT JOIN geoip_country AS c ON INET6_ATON(h.IP) BETWEEN c.StartIP AND c.EndIP WHERE h.UserID = '$UserID' AND h2.UserID > 0" /*AND Time != '0000-00-00 00:00:00'*/ . " @@ -71,7 +71,7 @@ if ($UsersOnly == 1) { u.IP, c.Code FROM users_main AS u - LEFT JOIN geoip_country AS c ON INET_ATON(u.IP) BETWEEN c.StartIP AND c.EndIP + LEFT JOIN geoip_country AS c ON INET6_ATON(u.IP) BETWEEN c.StartIP AND c.EndIP WHERE u.ID = '$UserID' UNION SELECT @@ -80,7 +80,7 @@ if ($UsersOnly == 1) { h.IP, c.Code FROM users_history_emails AS h - LEFT JOIN geoip_country AS c ON INET_ATON(h.IP) BETWEEN c.StartIP AND c.EndIP + LEFT JOIN geoip_country AS c ON INET6_ATON(h.IP) BETWEEN c.StartIP AND c.EndIP WHERE UserID = '$UserID' " /*AND Time != '0000-00-00 00:00:00'*/ . " ORDER BY Time DESC"); diff --git a/sections/userhistory/email_history2.php b/sections/userhistory/email_history2.php index 1c1d63f..4e4f2ab 100644 --- a/sections/userhistory/email_history2.php +++ b/sections/userhistory/email_history2.php @@ -176,7 +176,7 @@ if ($Old) {

[ - "${Username}" + Users::format_username($UserID) ]]) ?>

@@ -197,7 +197,7 @@ if ($Old) { () S - WI + WI
@@ -205,7 +205,7 @@ if ($Old) { () S - WI + WI
@@ -224,17 +224,24 @@ if ($Old) { () S - WI + WI
- + ?> + +
+ +
+ + @@ -265,7 +272,7 @@ if ($Old) { () S - WI + WI
@@ -288,12 +295,12 @@ if ($Old) { () S - WI + WI
- 0) { if (isset($Matches)) { echo $Matches; @@ -302,9 +309,15 @@ if ($Old) { } } } - } - // Invite email (always there) - ?> + ?> +
+
+ +
+ @@ -331,7 +344,7 @@ if ($Old) { () S - WI + WI
@@ -353,7 +366,7 @@ if ($Old) { () S - WI + WI
diff --git a/sections/userhistory/index.php b/sections/userhistory/index.php index 3e73bad..4d64aab 100644 --- a/sections/userhistory/index.php +++ b/sections/userhistory/index.php @@ -89,7 +89,7 @@ if ($_GET['action']) { users_history_ips: id (auto_increment, index) userid (index) - ip (stored using ip2long()) + ip timestamp users_history_passwd: diff --git a/sections/userhistory/ip_history.php b/sections/userhistory/ip_history.php index 87bdbe2..0992fb2 100644 --- a/sections/userhistory/ip_history.php +++ b/sections/userhistory/ip_history.php @@ -175,47 +175,59 @@ $Pages = Format::get_pages($Page, $NumResults, IPS_PER_PAGE, 9);

[ - "${UserInfo['Username']}" + Users::format_username($UserID) ]]) ?>

- - - -
-
- - - - - - -
-
- - - - - - - - -
-
+
+ + + + + +
+
+ + + / + + + / + +
+
+
+ +
+
+ + + + + +
+ + + +
+
+
+
+ +
+
+
+ + +
- +
- - + + @@ -297,7 +309,7 @@ $Pages = Format::get_pages($Page, $NumResults, IPS_PER_PAGE, 9); $OtherUser['EndTime'] = sqltime(); } ?> - + + + + + + +
+ ()
+ WI +
+
+ +
query(" ORDER BY ChangeTime DESC"); ?> -
-

- [ - "${Username}" - ]]) ?> -

-
-
- - - - - - - - next_record()) { ?> - - - - - +
+
+

+ [ + Users::format_username($UserID) + ]]) ?> +

+
+
+
IP H
S
+ + + + + - -
IP H
+ next_record()) { ?> + + + + + S
+ + + +
\ No newline at end of file diff --git a/sections/userhistory/password_history.php b/sections/userhistory/password_history.php index 054bac0..e3f8a0f 100644 --- a/sections/userhistory/password_history.php +++ b/sections/userhistory/password_history.php @@ -40,25 +40,27 @@ $DB->query(" ORDER BY ChangeTime DESC"); ?> -
-

- [ - "${Username}" - ]]) ?> -

-
-
- - - - - - next_record()) { ?> - - - +
+
+

+ [ + "${Username}" + ]]) ?> +

+
+
+
IP H
S
+ + + - -
IP H
+ next_record()) { ?> + + + S
+ + + +
\ No newline at end of file diff --git a/sections/userhistory/post_history.php b/sections/userhistory/post_history.php index d1e8282..1981283 100644 --- a/sections/userhistory/post_history.php +++ b/sections/userhistory/post_history.php @@ -163,15 +163,15 @@ if ($ShowGrouped) { echo t('server.userhistory.grouped') . ($ShowUnread ? t('server.userhistory.unread') : '') . t('server.userhistory.post_history_for', ['Values' => [ - "${Username}" + Users::format_username($UserID) ]]); } elseif ($ShowUnread) { echo t('server.userhistory.unread_post_history_for', ['Values' => [ - "${Username}" + Users::format_username($UserID) ]]); } else { echo t('server.userhistory.post_history_for', ['Values' => [ - "${Username}" + Users::format_username($UserID) ]]); } ?> diff --git a/sections/userhistory/token_history.php b/sections/userhistory/token_history.php index f25a3b1..2fa5c95 100644 --- a/sections/userhistory/token_history.php +++ b/sections/userhistory/token_history.php @@ -90,53 +90,58 @@ $Pages = Format::get_pages($Page, $NumResults, 25);
-
- - - - - - - - - - - $Name"; - } else { - $Name = "(Deleted torrent $TorrentID)"; - } - $ArtistName = Artists::display_artists($Artists[$GroupID]); - if ($ArtistName) { - $Name = $ArtistName . $Name; - } - - ?> - - - - + 0) { ?> +
+
" . t('server.userhistory.expire_button') . "" : ''; ?>
+ + + + - - - + + + - -
-
+ $Name"; + } else { + $Name = "(Deleted torrent $TorrentID)"; + } + $ArtistName = Artists::display_artists($Artists[$GroupID]); + if ($ArtistName) { + $Name = $ArtistName . $Name; + } + + ?> + + + + " . t('server.userhistory.expire_button') . "" : ''; ?> + + + + + + + + + + set_query_id($QueryID);

[ - "${Username}" + Users::format_username($UserID) ]]) ?>

diff --git a/src/css/default/components/Form/Form.css b/src/css/default/components/Form/Form.css index 563ed0b..463af44 100644 --- a/src/css/default/components/Form/Form.css +++ b/src/css/default/components/Form/Form.css @@ -109,9 +109,6 @@ FormOneLine Search } } @media (max-width: 767px) { - .SearchUserAdvanced .Form-row { - flex-wrap: wrap; - } .Form.is-longLabel .Form-row { flex-direction: column; } @@ -133,9 +130,6 @@ FormOneLine Search .LayoutMainSidebar-main .Form-label { width: 18%; } - .SearchUserAdvanced .Form-label { - width: 8%; - } } @media (max-width: 767px) { .Form.is-longLabel .Form-label { @@ -177,10 +171,6 @@ FormOneLine Search :is(.LayoutMainSidebar-main, .TorrentNotifyForm) .Form-inputs { width: 78%; } - .SearchUserAdvanced .Form-inputs { - width: 24%; - align-items: start; - } } /* input */ diff --git a/src/css/default/components/List.css b/src/css/default/components/List.css index 326810d..45538bc 100644 --- a/src/css/default/components/List.css +++ b/src/css/default/components/List.css @@ -1,10 +1,29 @@ -.List { - list-style-type: unset; - list-style-position: inside; +.MenuList { + list-style: none; } -.List li { - padding-top: var(--global-space-sm); - padding-left: var(--global-space-lg); - padding-right: 0; - padding-bottom: 0; + +.MenuList.SubMenu { + position: relative; + margin-left: 20px; + padding-top: 5px; +} + +.MenuList li { + position: relative; + padding: 5px; +} + +.MenuList.SubMenu li::before { + content: ''; + height: 100%; + width: 12px; + border-bottom: 2px solid var(--global-color-border); + border-left: 2px solid var(--global-color-border); + position: absolute; + bottom: 12px; + left: -10px; +} + +.MenuList.SubMenu li:first-child::before { + height: 70%; } diff --git a/src/css/default/components/TorrentDetail.css b/src/css/default/components/TorrentDetail.css index ec7d916..e4aa918 100644 --- a/src/css/default/components/TorrentDetail.css +++ b/src/css/default/components/TorrentDetail.css @@ -128,10 +128,6 @@ TorrentDetail margin-left: auto; } -.TorrentDetailfileListItem-fileListItem { - padding: 0px 0px 0px 12px; -} - .TorrentDetailfileListItem-fileListItem[variant='root'] { padding-left: 0px; } diff --git a/src/locales/en/en.yaml b/src/locales/en/en.yaml index e1beb99..5db948f 100644 --- a/src/locales/en/en.yaml +++ b/src/locales/en/en.yaml @@ -1078,11 +1078,11 @@ server.common.error: |- server.common.error_403_description: |- You just tried to go to a page that you don't have enough permission to view. server.common.error_403_title: |- - Error 403 + Permission denied server.common.error_404_description: |- You just tried to go to a page that doesn't exist. server.common.error_404_title: |- - Error 404 + Page not found server.common.external_subtitles: |- External server.common.feature_film: |- @@ -7598,9 +7598,9 @@ server.userhistory.unread: |- server.userhistory.unread_post_history_for: |- Unread post history for %s server.userhistory.view_all_ip_address: |- - View all IP addresses + All server.userhistory.view_ip_addresses_with_users: |- - View IP addresses with users + Users only server.userhistory.wildcard_search_examples: |- Wildcard (*) search examples: 127.0.* or 1*2.0.*.1 or *.*.*.* server.userhistory.with_new_additions: |- @@ -8318,4 +8318,16 @@ server.tools.total_value: |- server.tools.timestamps: |- Timestamps server.common.see_full: |- - See full \ No newline at end of file + See full +server.user.simple_info: |- + Profile +server.user.consumed_history: |- + History +server.user.user_basic: |- + Basic info +server.user.account_info: |- + Account info +server.common.time_format: |- + Time format +server.user.logout_all: |- + Logout all diff --git a/src/locales/zh-Hans/zh-Hans.yaml b/src/locales/zh-Hans/zh-Hans.yaml index 623fe0b..32b5e73 100644 --- a/src/locales/zh-Hans/zh-Hans.yaml +++ b/src/locales/zh-Hans/zh-Hans.yaml @@ -1046,11 +1046,11 @@ server.common.error: |- server.common.error_403_description: |- 你刚刚试图查看你无权访问的页面。 server.common.error_403_title: |- - 错误 403 + 无权限 server.common.error_404_description: |- 你刚刚试图查看不存在的页面。 server.common.error_404_title: |- - 错误 404 + 页面不存在 server.common.external_subtitles: |- 外挂 server.common.feature_film: |- @@ -2225,7 +2225,7 @@ server.pub.space_new_torrent_notification_one: |- server.pub.space_new_torrent_notification_other: |-  条新种推送 server.pub.statistics: |- - 统计面板 + 工资统计 server.pub.toolbox: |- 管理面板 server.pub.user_manage: |- @@ -2337,7 +2337,7 @@ server.register.you_did_not_select_wiki: |- server.register.your_passwords_do_not_match: |- 两次输入的密码不一致 server.reports.active_reports: |- - 未处理的报告 + 其他报告 server.reports.body: |- 内容 server.reports.claim: |- @@ -2483,7 +2483,7 @@ server.reports.sth_was_reported_by_user_sometime: |- server.reports.subject: |- 主题 server.reports.threads_trashed_since_the_beginning_of_time: |- - 所有被删除的主题 + 所有被删除的帖子 server.reports.title: |- 标题 server.reports.toggle_notes: |- @@ -6200,7 +6200,7 @@ server.user.community_topic: |- server.user.compose: |- 发送私信 server.user.copypaste: |- - 复制访问日志 + 复制用户信息 server.user.country_code: |- 国家代码 server.user.country_code_title: |- @@ -6626,7 +6626,7 @@ server.user.p_host: |- server.user.p_inviter: |- 邀请人 server.user.p_invites: |- - 邀请数量 + 邀请数 server.user.p_ip: |- IP server.user.p_irc: |- @@ -6846,7 +6846,7 @@ server.user.send_hacked_account_email_to: |- server.user.session: |- 访问终端 server.user.sessions: |- - 访问终端列表 + 登录记录 server.user.setting: |- 设置 server.user.show_bounty: |- @@ -6868,7 +6868,7 @@ server.user.space_and_space: |- server.user.space_are: |-  的 server.user.space_bigger_than_sessions: |- -  > 访问记录 + 的登录记录 server.user.space_expired: |-  到期) server.user.space_is: |- @@ -7130,7 +7130,7 @@ server.user.to_fuzzy_search_for_a_block_of_addresses_title: |- server.user.token: |- 令牌 server.user.token_history: |- - 免费令牌历史 + 令牌消费历史 server.user.token_number: |- 令牌 server.user.too_paranoid_to_have_their_stats_shown_here_and: |- @@ -7462,9 +7462,9 @@ server.userhistory.unread: |- server.userhistory.unread_post_history_for: |- 未读的 %s 的发帖历史 server.userhistory.view_all_ip_address: |- - 查看所有 IP 地址 + 所有 server.userhistory.view_ip_addresses_with_users: |- - 查看有用户使用的 IP 地址 + 用户在使用 server.userhistory.wildcard_search_examples: |- 通配符(*)搜索示例:127.0.* 或 1*2.0.*.1 或 *.*.*.* server.userhistory.with_new_additions: |- @@ -8183,3 +8183,15 @@ server.tool.timestamps: |- 时间戳 server.common.see_full: |- 查看全部 +server.user.simple_info: |- + 简介 +server.user.consumed_history: |- + 消费历史 +server.user.user_basic: |- + 基本信息 +server.user.account_info: |- + 账号情况 +server.common.time_format: |- + 时间格式 +server.user.logout_all: |- + 注销所有