├── IPCloneDetectorAndASNAnalyzer ├── README.md ├── screenshots │ ├── screenshot.png │ └── statistics.svg ├── users_by_asn.php ├── users_by_country.php ├── search.php ├── badasn │ └── list.txt ├── IPCloneDetectorAndASNAnalyzer.php └── index.php ├── emoji_trail ├── README.md ├── screenshots │ └── emoji-trail.png └── emoji_trail.php ├── live_map ├── README.md ├── live_map.php ├── index.php └── leaflet.css ├── example_plugin ├── screenshots │ ├── example_icon.png │ ├── example_plugin.jpg │ └── example_plugin2.jpg ├── README.md ├── example.php └── example_plugin.php ├── mute ├── README.md ├── mute.php └── index.php ├── php_mailer ├── README.md ├── mail-settings.php └── php_mailer.php └── README.md /IPCloneDetectorAndASNAnalyzer/README.md: -------------------------------------------------------------------------------- 1 | Displays some statistics about ASNs, IPs, and clones. -------------------------------------------------------------------------------- /emoji_trail/README.md: -------------------------------------------------------------------------------- 1 | Makes an emoji trail from your mouse cursor, an example how to easily add your own JavaScript to any page. 2 | -------------------------------------------------------------------------------- /live_map/README.md: -------------------------------------------------------------------------------- 1 | This plugin adds a live map to your webpanel, allowing you to see new connections and where it comes from on the map. 2 | -------------------------------------------------------------------------------- /emoji_trail/screenshots/emoji-trail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unrealircd/unrealircd-webpanel-plugins/main/emoji_trail/screenshots/emoji-trail.png -------------------------------------------------------------------------------- /example_plugin/screenshots/example_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unrealircd/unrealircd-webpanel-plugins/main/example_plugin/screenshots/example_icon.png -------------------------------------------------------------------------------- /example_plugin/screenshots/example_plugin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unrealircd/unrealircd-webpanel-plugins/main/example_plugin/screenshots/example_plugin.jpg -------------------------------------------------------------------------------- /example_plugin/screenshots/example_plugin2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unrealircd/unrealircd-webpanel-plugins/main/example_plugin/screenshots/example_plugin2.jpg -------------------------------------------------------------------------------- /mute/README.md: -------------------------------------------------------------------------------- 1 | Used in conjunction with the 'mute' third-party module for UnrealIRCd, this plugin adds a new page into your "Server Bans" tab, letting you view and remove. 2 | -------------------------------------------------------------------------------- /IPCloneDetectorAndASNAnalyzer/screenshots/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/unrealircd/unrealircd-webpanel-plugins/main/IPCloneDetectorAndASNAnalyzer/screenshots/screenshot.png -------------------------------------------------------------------------------- /example_plugin/README.md: -------------------------------------------------------------------------------- 1 | This plugin adds a new page which is accessible via the navigation panel on the left. 2 | 3 | The page contains a heading saying "Example Page", followed by some random Latin. 4 |

5 | This writing is generated from the README.md file in the base directory of the plugin. 6 |

7 | I hope this inspires someone to see what they can make. There are plenty of hooks and many ways you can make something awesome and powerful. 8 |


9 | Good luck, adventurer! 10 | -------------------------------------------------------------------------------- /php_mailer/README.md: -------------------------------------------------------------------------------- 1 | Complete your Panel - Get email notifications about logins and login attempts on your admin panel. 2 |

3 | Quick and easy, all you need to know is your email details and you can start automating right away. 4 |

5 | Your panel will let you know when there are any login attempts and valid logins. 6 |

7 | Users who specified an email will get a notification about logins and login attempts, and so will the master email address. 8 |

9 | Make your Panel Professional with PHPMailer(). 10 | -------------------------------------------------------------------------------- /example_plugin/example.php: -------------------------------------------------------------------------------- 1 | Example Page"; 5 | echo "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; 6 | require_once "../../inc/footer.php"; 7 | -------------------------------------------------------------------------------- /IPCloneDetectorAndASNAnalyzer/users_by_asn.php: -------------------------------------------------------------------------------- 1 | user()->getAll(); 6 | 7 | header('Content-Type: application/json'); 8 | 9 | usort($users, function ($a, $b) { 10 | return strcasecmp($a->name, $b->name); 11 | }); 12 | 13 | $asnFilter = htmlentities($_GET['asn']); 14 | 15 | // Filtrer les utilisateurs en fonction du numéro ASN 16 | $filteredUsers = array_filter($users, function ($entry) use ($asnFilter) { 17 | return isset($entry->geoip->asn) && $entry->geoip->asn == $asnFilter; 18 | }); 19 | 20 | $foundObjects = []; 21 | 22 | if (!empty($filteredUsers)) { 23 | foreach ($filteredUsers as $entry) { 24 | $asn = htmlspecialchars($entry->geoip->asn); 25 | $asname = htmlspecialchars($entry->geoip->asname); 26 | $country_code = htmlspecialchars($entry->geoip->country_code); 27 | $nickname = htmlspecialchars($entry->name); 28 | 29 | $foundObjects[] = $entry; 30 | } 31 | } 32 | echo json_encode($foundObjects); 33 | -------------------------------------------------------------------------------- /IPCloneDetectorAndASNAnalyzer/users_by_country.php: -------------------------------------------------------------------------------- 1 | user()->getAll(); 6 | 7 | header('Content-Type: application/json'); 8 | 9 | usort($users, function ($a, $b) { 10 | return strcasecmp($a->name, $b->name); 11 | }); 12 | 13 | $countryFilter = htmlentities($_GET['country']); 14 | 15 | // Filtrer les utilisateurs en fonction du pays 16 | $filteredUsers = array_filter($users, function ($entry) use ($countryFilter) { 17 | return isset($entry->geoip->country_code) && $entry->geoip->country_code == $countryFilter; 18 | }); 19 | 20 | $foundObjects = []; 21 | 22 | if (!empty($filteredUsers)) { 23 | foreach ($filteredUsers as $entry) { 24 | $account = ($entry->user->account ? htmlspecialchars($entry->user->account) : null); 25 | $country_code = htmlspecialchars($entry->geoip->country_code); 26 | $nickname = htmlspecialchars($entry->name); 27 | $foundObjects[] = $entry; 28 | } 29 | } 30 | echo json_encode($foundObjects); 31 | -------------------------------------------------------------------------------- /IPCloneDetectorAndASNAnalyzer/screenshots/statistics.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 21 | -------------------------------------------------------------------------------- /IPCloneDetectorAndASNAnalyzer/search.php: -------------------------------------------------------------------------------- 1 | user()->getAll(4); 6 | ?> 7 | user->channels, 'name')); 17 | }); 18 | } 19 | usort($users, function ($a, $b) { 20 | return strcmp($a->name, $b->name); 21 | }); 22 | 23 | function searchInArray($array, $searchValue, &$foundObjects, $currentObject) 24 | { 25 | global $modeStrict; 26 | foreach ($array as $key => $value) { 27 | if (is_array($value)) { 28 | searchInArray($value, $searchValue, $foundObjects, $currentObject); 29 | } elseif (is_object($value)) { 30 | searchInArray((array) $value, $searchValue, $foundObjects, $currentObject); 31 | } elseif ($value == $searchValue || !$modeStrict && is_string($value) && stripos($value, $searchValue) !== false) { 32 | $foundObjects[] = $currentObject; 33 | return; 34 | } 35 | } 36 | } 37 | 38 | foreach ($users as $obj) { 39 | searchInArray((array) $obj, $searchValue, $foundObjects, $obj); 40 | } 41 | 42 | echo json_encode($foundObjects); 43 | -------------------------------------------------------------------------------- /IPCloneDetectorAndASNAnalyzer/badasn/list.txt: -------------------------------------------------------------------------------- 1 | 174 2 | 701 3 | 812 4 | 852 5 | 1299 6 | 1680 7 | 2516 8 | 2609 9 | 3223 10 | 3257 11 | 3356 12 | 4785 13 | 4808 14 | 5089 15 | 5384 16 | 5606 17 | 6327 18 | 6461 19 | 6640 20 | 6696 21 | 6830 22 | 7489 23 | 7552 24 | 7765 25 | 8075 26 | 8100 27 | 8151 28 | 8399 29 | 8473 30 | 8560 31 | 8708 32 | 9009 33 | 10439 34 | 10796 35 | 11878 36 | 12400 37 | 12874 38 | 12876 39 | 13213 40 | 13335 41 | 13552 42 | 14061 43 | 15169 44 | 15830 45 | 16276 46 | 16347 47 | 16509 48 | 17676 49 | 18126 50 | 19148 51 | 19969 52 | 20001 53 | 20115 54 | 20473 55 | 20860 56 | 20940 57 | 21003 58 | 21100 59 | 21724 60 | 21859 61 | 22363 62 | 23969 63 | 24875 64 | 24940 65 | 24961 66 | 25369 67 | 27176 68 | 27323 69 | 28708 70 | 28753 71 | 29066 72 | 29075 73 | 30781 74 | 30889 75 | 31245 76 | 31404 77 | 31898 78 | 33387 79 | 34305 80 | 35625 81 | 36183 82 | 37705 83 | 39405 84 | 40021 85 | 40676 86 | 41564 87 | 41745 88 | 41798 89 | 42390 90 | 42473 91 | 43350 92 | 44066 93 | 44217 94 | 44477 95 | 44679 96 | 46475 97 | 46562 98 | 46844 99 | 49419 100 | 49981 101 | 51167 102 | 51765 103 | 51852 104 | 53667 105 | 54113 106 | 54203 107 | 54614 108 | 55081 109 | 55286 110 | 57169 111 | 57172 112 | 58065 113 | 60068 114 | 60404 115 | 60555 116 | 60781 117 | 60804 118 | 61317 119 | 62240 120 | 62563 121 | 63018 122 | 63023 123 | 63949 124 | 132933 125 | 133480 126 | 136787 127 | 137409 128 | 138915 129 | 147049 130 | 197706 131 | 197922 132 | 198605 133 | 198890 134 | 201011 135 | 202422 136 | 203020 137 | 205016 138 | 205544 139 | 206092 140 | 206804 141 | 207137 142 | 207713 143 | 209181 144 | 209854 145 | 210164 146 | 210558 147 | 211476 148 | 212238 149 | 262191 150 | 327989 151 | 393544 152 | 396356 153 | 397423 154 | -------------------------------------------------------------------------------- /mute/mute.php: -------------------------------------------------------------------------------- 1 | $page_link, "no_irc_server_required" => true]; 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /live_map/live_map.php: -------------------------------------------------------------------------------- 1 | $page_link, "no_irc_server_required" => false]; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /IPCloneDetectorAndASNAnalyzer/IPCloneDetectorAndASNAnalyzer.php: -------------------------------------------------------------------------------- 1 | $page_link, "no_irc_server_required" => true]; 56 | } 57 | } 58 | 59 | -------------------------------------------------------------------------------- /example_plugin/example_plugin.php: -------------------------------------------------------------------------------- 1 | $page_link, "no_irc_server_required" => true]; 67 | } 68 | } 69 | 70 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnrealIRCd WebPanel Plugins 2 | 3 | ## WARNING: USE AT YOUR OWN RISK 4 | 5 | ### Overview 6 | Welcome to the UnrealIRCd WebPanel Plugins repository. This repository contains a collection of plugins for the UnrealIRCd WebPanel, made by the community with love, designed to enhance your experience and extend the functionality of your UnrealIRCd WebPanel. 7 | 8 | ### Important Notice 9 | **WARNING: USE AT YOUR OWN RISK** 10 | 11 | These plugins are provided as-is and come with no guarantees or warranties. By using these plugins, you acknowledge and accept the potential risks involved. The developers and contributors of this repository are not responsible for any damages or issues that may arise from the use of these plugins. 12 | 13 | ### Potential Risks 14 | 1. **Security Vulnerabilities**: Plugins may introduce security vulnerabilities that could be exploited by malicious actors. 15 | 2. **Data Loss**: Improper use or bugs within the plugins could result in loss of data. 16 | 3. **System Instability**: Plugins might cause your UnrealIRCd WebPanel or the underlying UnrealIRCd server to become unstable or crash. 17 | 4. **Compatibility Issues**: Not all plugins may be compatible with every version of UnrealIRCd WebPanel or UnrealIRCd. 18 | 19 | ### Recommendations 20 | - **Thoroughly Test**: Before deploying any plugin to a production environment, thoroughly test it in a development or staging environment. 21 | - **Backup Your Data**: Always make sure to backup your data and configuration files before installing any new plugins. 22 | - **Review Code**: If possible, review the source code of the plugins to understand their functionality and potential risks. 23 | - **Stay Updated**: Keep your UnrealIRCd WebPanel, UnrealIRCd server, and plugins updated to the latest versions to mitigate known issues and vulnerabilities. 24 | 25 | ### Installation 26 | To install a plugin from the repository, you can find the "Add New" button in the Plugins section on the webpanel. If you are creating your own plugin, generally this involves copying the plugin files to the appropriate directory and configuring the UnrealIRCd WebPanel to recognize and use the plugin (`config/config.php`) 27 | 28 | ### Contributing 29 | If you would like to contribute to this repository, please fork the repo, make your changes, and submit a pull request. Contributions are welcome but please ensure that your code is well-documented and tested. 30 | 31 | ### License 32 | This repository is licensed under the GPLv3 License. All contributions to this repository must also be GPLv3 or later. 33 | 34 | ### Disclaimer 35 | The use of these plugins is entirely at your own risk. The maintainers of this repository are not liable for any negative consequences resulting from the use of these plugins. Always exercise caution and make informed decisions when integrating third-party plugins into your systems. 36 | 37 | For any issues or questions, please open an issue in this repository or contact the maintainers directly. 38 | 39 | Thank you for using UnrealIRCd WebPanel Plugins. Stay safe and happy coding! 40 | -------------------------------------------------------------------------------- /mute/index.php: -------------------------------------------------------------------------------- 1 | query("mute.list")->list; 21 | foreach($users as $user) 22 | { 23 | if ($rpc->query("mute.remove", ["nick" => $user->name])) 24 | $unmuted[] = $user->name; 25 | else 26 | $e_unmuted[] = $user->name; 27 | } 28 | } 29 | else 30 | { 31 | if ($rpc->query("mute.remove", ["nick" => $_GET['unmute']])) 32 | $unmuted[] = $_GET['unmute']; 33 | else 34 | $e_unmuted[] = $_GET['unmute']; 35 | } 36 | if (!empty($unmuted)) 37 | Message::Success("Unmuted ".count($unmuted)." users"); 38 | if (!empty($e_unmuted)) 39 | Message::Fail("Could not unmute ".count($e_unmuted)." users"); 40 | } 41 | function get_mute_version() : float|NULL 42 | { 43 | global $rpc; 44 | if (!$rpc) 45 | return NULL; 46 | $mods = $rpc->server()->module_list()->list; 47 | foreach ($mods as $m) 48 | { 49 | if ($m->name != "third/mute2" && $m->name != "third/mute") 50 | continue; 51 | 52 | return (float)$m->version; 53 | } 54 | return NULL; 55 | } 56 | 57 | $users = $rpc->query("mute.list"); 58 | if (get_mute_version() < 1.4) 59 | Message::Fail("Need to be using module third/mute version 1.4 or later for this plugin to work"); 60 | ?> 61 |

Muted Users

62 | A list of muted users (third/mute) 63 |
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | list as $user) 74 | { 75 | $securitygroups = ""; 76 | foreach ($user->user->{"security-groups"} as $sg) 77 | { 78 | $securitygroups .= "$sg"; 79 | } 80 | echo " 81 | 82 | 83 | 84 | 85 | "; 86 | } 87 | ?> 88 | 89 |
NickHost/IPSecurity Groups
id."\">".$user->name."ip."\">".$user->ip."$securitygroups
90 |
91 | Access denied"; 8 | require_once "../../inc/footer.php"; 9 | die(); 10 | } 11 | global $config; 12 | foreach($_POST as $key => $value) 13 | { 14 | if ($key == "fromEmail") 15 | $config['smtp']["username"] = $value; 16 | elseif ($key == "smtpPass") 17 | $config['smtp']['password'] = $value; 18 | elseif ($key == "fromName") 19 | $config['smtp']['from_name'] = $value; 20 | elseif ($key == "smtpHost") 21 | $config['smtp']['host'] = $value; 22 | elseif ($key == "smtpPort") 23 | $config['smtp']['port'] = $value; 24 | elseif ($key == "smtpEnc") 25 | $config['smtp']['encryption'] = $value; 26 | 27 | write_config(); 28 | } 29 | ?> 30 | 31 | 32 |

Mail Settings

33 |
34 |
35 |
36 | 37 |
38 | "> 39 |
40 |
41 |
42 | 43 |
44 | "> 45 |
46 |
47 |
48 | 49 |
50 | "> 51 |
52 |
53 |
54 | 55 |
56 | "> 57 |
58 |
59 |
60 | 61 |
62 | "> 63 |
64 |
65 |
66 |
67 | 68 | 71 |
72 |
73 | 74 | 77 |
78 |
79 |
80 |
81 | 82 |
83 |
84 |
85 |
86 | 39 | 71 | 106 | SMTPDebug = 2; 38 | $mail->isSMTP(); // Send using SMTP 39 | $mail->Host = get_config("smtp::host"); // Set the SMTP server to send through 40 | $mail->SMTPAuth = true; // Enable SMTP authentication 41 | $mail->Username = get_config("smtp::username"); // SMTP username 42 | $mail->Password = get_config("smtp::password"); // SMTP password 43 | $mail->SMTPSecure = get_config("smtp::encryption"); // Enable implicit TLS encryption 44 | $mail->Port = get_config("smtp::port"); // TCP port to connect to; use 587 if you have set `SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS` 45 | 46 | //Recipients 47 | $mail->setFrom(get_config("smtp::username"), get_config("smtp::from_name")); 48 | $mail->addAddress($to['email'], $to['name']); // Add a recipient 49 | 50 | //Content 51 | $mail->isHTML(true); // Set email format to HTML 52 | $mail->Subject = $subject; 53 | $mail->Body = $body . "

Thank you for using UnrealIRCd!"; 54 | $mail->AltBody = 'This is the body in plain text for non-HTML mail clients'; 55 | 56 | $mail->send(); 57 | } catch (Exception $e) { 58 | die("Could not send mail:". $e); 59 | } 60 | } 61 | 62 | /** 63 | * Send a login notification to the admin (note-to-self) 64 | * @param mixed $user 65 | * @return void 66 | */ 67 | public static function user_login_notif($user) 68 | { 69 | self::send_mail( 70 | ["email" => get_config("smtp::username"), "name" => get_config("smtp::from_name")], 71 | "New login to Unreal Admin Panel", 72 | "There was a new login to the admin panel.
User: \"$user->username\"
IP: \"".$_SERVER['REMOTE_ADDR']."\" (".$_SERVER['HTTP_CF_IPCOUNTRY'].")
". 73 | "User Agent: ".$_SERVER['HTTP_USER_AGENT'] 74 | ); 75 | 76 | if ($user->email) 77 | self::send_mail( 78 | ["email" => $user->email, "name" => $user->first_name . " " . $user->last_name], 79 | "New login to your account", 80 | "Dear $user->first_name,

". 81 | "There was a new login to account: \"$user->username\"

". 82 | "Details:
". 83 | "IP: ".$_SERVER['REMOTE_ADDR']." (".$_SERVER['HTTP_CF_IPCOUNTRY'].")
". 84 | "User Agent: ".$_SERVER['HTTP_USER_AGENT']."

". 85 | "If this was not you, please contact your Panel Administrator." 86 | ); 87 | } 88 | 89 | /** 90 | * Send a notification about the failed attempt 91 | */ 92 | public static function user_login_fail_notif($user) 93 | { 94 | self::send_mail( 95 | ["email" => get_config("smtp::username"), "name" => get_config("smtp::from_name")], 96 | "Failed login attempt - Unreal Admin Panel", 97 | "-- ADMIN NOTIFICATION --,

". 98 | "There was failed login attempt to account: \"$user->username\"

". 99 | "Details:
". 100 | "IP: ".$_SERVER['REMOTE_ADDR']." (".$_SERVER['HTTP_CF_IPCOUNTRY'].")
". 101 | "User Agent: ".$_SERVER['HTTP_USER_AGENT']."

" 102 | ); 103 | $user = new PanelUser($user['login']); 104 | if ($user->email) 105 | self::send_mail( 106 | ["email" => $user->email, "name" => $user->first_name . " " . $user->last_name], 107 | "Failed login attempt to your account", 108 | "Dear $user->first_name,

". 109 | "There was failed login attempt to your account: \"$user->username\"

". 110 | "Details:
". 111 | "IP: ".$_SERVER['REMOTE_ADDR']." (".$_SERVER['HTTP_CF_IPCOUNTRY'].")
". 112 | "User Agent: ".$_SERVER['HTTP_USER_AGENT']."

". 113 | "If this was not you, please contact your Panel Administrator." 114 | ); 115 | } 116 | 117 | public static function navbar_hook(&$pages) 118 | { 119 | $page_name = "Mail"; 120 | $page_link = "plugins/php_mailer/mail-settings.php"; 121 | $pages["Settings"][$page_name] = ["script" => $page_link]; 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /live_map/index.php: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 |

Live Map

11 |
12 | 38 | 39 |
40 | 333 | svg, 9 | .leaflet-pane > canvas, 10 | .leaflet-zoom-box, 11 | .leaflet-image-layer, 12 | .leaflet-layer { 13 | position: absolute; 14 | left: 0; 15 | top: 0; 16 | } 17 | .leaflet-container { 18 | overflow: hidden; 19 | } 20 | .leaflet-tile, 21 | .leaflet-marker-icon, 22 | .leaflet-marker-shadow { 23 | -webkit-user-select: none; 24 | -moz-user-select: none; 25 | user-select: none; 26 | -webkit-user-drag: none; 27 | } 28 | /* Prevents IE11 from highlighting tiles in blue */ 29 | .leaflet-tile::selection { 30 | background: transparent; 31 | } 32 | /* Safari renders non-retina tile on retina better with this, but Chrome is worse */ 33 | .leaflet-safari .leaflet-tile { 34 | image-rendering: -webkit-optimize-contrast; 35 | } 36 | /* hack that prevents hw layers "stretching" when loading new tiles */ 37 | .leaflet-safari .leaflet-tile-container { 38 | width: 1600px; 39 | height: 1600px; 40 | -webkit-transform-origin: 0 0; 41 | } 42 | .leaflet-marker-icon, 43 | .leaflet-marker-shadow { 44 | display: block; 45 | } 46 | /* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ 47 | /* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ 48 | .leaflet-container .leaflet-overlay-pane svg { 49 | max-width: none !important; 50 | max-height: none !important; 51 | } 52 | .leaflet-container .leaflet-marker-pane img, 53 | .leaflet-container .leaflet-shadow-pane img, 54 | .leaflet-container .leaflet-tile-pane img, 55 | .leaflet-container img.leaflet-image-layer, 56 | .leaflet-container .leaflet-tile { 57 | max-width: none !important; 58 | max-height: none !important; 59 | width: auto; 60 | padding: 0; 61 | } 62 | 63 | .leaflet-container img.leaflet-tile { 64 | /* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */ 65 | mix-blend-mode: plus-lighter; 66 | } 67 | 68 | .leaflet-container.leaflet-touch-zoom { 69 | -ms-touch-action: pan-x pan-y; 70 | touch-action: pan-x pan-y; 71 | } 72 | .leaflet-container.leaflet-touch-drag { 73 | -ms-touch-action: pinch-zoom; 74 | /* Fallback for FF which doesn't support pinch-zoom */ 75 | touch-action: none; 76 | touch-action: pinch-zoom; 77 | } 78 | .leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { 79 | -ms-touch-action: none; 80 | touch-action: none; 81 | } 82 | .leaflet-container { 83 | -webkit-tap-highlight-color: transparent; 84 | } 85 | .leaflet-container a { 86 | -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); 87 | } 88 | .leaflet-tile { 89 | filter: inherit; 90 | visibility: hidden; 91 | } 92 | .leaflet-tile-loaded { 93 | visibility: inherit; 94 | } 95 | .leaflet-zoom-box { 96 | width: 0; 97 | height: 0; 98 | -moz-box-sizing: border-box; 99 | box-sizing: border-box; 100 | z-index: 800; 101 | } 102 | /* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ 103 | .leaflet-overlay-pane svg { 104 | -moz-user-select: none; 105 | } 106 | 107 | .leaflet-pane { z-index: 400; } 108 | 109 | .leaflet-tile-pane { z-index: 200; } 110 | .leaflet-overlay-pane { z-index: 400; } 111 | .leaflet-shadow-pane { z-index: 500; } 112 | .leaflet-marker-pane { z-index: 600; } 113 | .leaflet-tooltip-pane { z-index: 650; } 114 | .leaflet-popup-pane { z-index: 700; } 115 | 116 | .leaflet-map-pane canvas { z-index: 100; } 117 | .leaflet-map-pane svg { z-index: 200; } 118 | 119 | .leaflet-vml-shape { 120 | width: 1px; 121 | height: 1px; 122 | } 123 | .lvml { 124 | behavior: url(#default#VML); 125 | display: inline-block; 126 | position: absolute; 127 | } 128 | 129 | 130 | /* control positioning */ 131 | 132 | .leaflet-control { 133 | position: relative; 134 | z-index: 800; 135 | pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ 136 | pointer-events: auto; 137 | } 138 | .leaflet-top, 139 | .leaflet-bottom { 140 | position: absolute; 141 | z-index: 1000; 142 | pointer-events: none; 143 | } 144 | .leaflet-top { 145 | top: 0; 146 | } 147 | .leaflet-right { 148 | right: 0; 149 | } 150 | .leaflet-bottom { 151 | bottom: 0; 152 | } 153 | .leaflet-left { 154 | left: 0; 155 | } 156 | .leaflet-control { 157 | float: left; 158 | clear: both; 159 | } 160 | .leaflet-right .leaflet-control { 161 | float: right; 162 | } 163 | .leaflet-top .leaflet-control { 164 | margin-top: 10px; 165 | } 166 | .leaflet-bottom .leaflet-control { 167 | margin-bottom: 10px; 168 | } 169 | .leaflet-left .leaflet-control { 170 | margin-left: 10px; 171 | } 172 | .leaflet-right .leaflet-control { 173 | margin-right: 10px; 174 | } 175 | 176 | 177 | /* zoom and fade animations */ 178 | 179 | .leaflet-fade-anim .leaflet-popup { 180 | opacity: 0; 181 | -webkit-transition: opacity 0.2s linear; 182 | -moz-transition: opacity 0.2s linear; 183 | transition: opacity 0.2s linear; 184 | } 185 | .leaflet-fade-anim .leaflet-map-pane .leaflet-popup { 186 | opacity: 1; 187 | } 188 | .leaflet-zoom-animated { 189 | -webkit-transform-origin: 0 0; 190 | -ms-transform-origin: 0 0; 191 | transform-origin: 0 0; 192 | } 193 | svg.leaflet-zoom-animated { 194 | will-change: transform; 195 | } 196 | 197 | .leaflet-zoom-anim .leaflet-zoom-animated { 198 | -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); 199 | -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); 200 | transition: transform 0.25s cubic-bezier(0,0,0.25,1); 201 | } 202 | .leaflet-zoom-anim .leaflet-tile, 203 | .leaflet-pan-anim .leaflet-tile { 204 | -webkit-transition: none; 205 | -moz-transition: none; 206 | transition: none; 207 | } 208 | 209 | .leaflet-zoom-anim .leaflet-zoom-hide { 210 | visibility: hidden; 211 | } 212 | 213 | 214 | /* cursors */ 215 | 216 | .leaflet-interactive { 217 | cursor: pointer; 218 | } 219 | .leaflet-grab { 220 | cursor: -webkit-grab; 221 | cursor: -moz-grab; 222 | cursor: grab; 223 | } 224 | .leaflet-crosshair, 225 | .leaflet-crosshair .leaflet-interactive { 226 | cursor: crosshair; 227 | } 228 | .leaflet-popup-pane, 229 | .leaflet-control { 230 | cursor: auto; 231 | } 232 | .leaflet-dragging .leaflet-grab, 233 | .leaflet-dragging .leaflet-grab .leaflet-interactive, 234 | .leaflet-dragging .leaflet-marker-draggable { 235 | cursor: move; 236 | cursor: -webkit-grabbing; 237 | cursor: -moz-grabbing; 238 | cursor: grabbing; 239 | } 240 | 241 | /* marker & overlays interactivity */ 242 | .leaflet-marker-icon, 243 | .leaflet-marker-shadow, 244 | .leaflet-image-layer, 245 | .leaflet-pane > svg path, 246 | .leaflet-tile-container { 247 | pointer-events: none; 248 | } 249 | 250 | .leaflet-marker-icon.leaflet-interactive, 251 | .leaflet-image-layer.leaflet-interactive, 252 | .leaflet-pane > svg path.leaflet-interactive, 253 | svg.leaflet-image-layer.leaflet-interactive path { 254 | pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ 255 | pointer-events: auto; 256 | } 257 | 258 | /* visual tweaks */ 259 | 260 | .leaflet-container { 261 | background: #ddd; 262 | outline-offset: 1px; 263 | } 264 | .leaflet-container a { 265 | color: #0078A8; 266 | } 267 | .leaflet-zoom-box { 268 | border: 2px dotted #38f; 269 | background: rgba(255,255,255,0.5); 270 | } 271 | 272 | 273 | /* general typography */ 274 | .leaflet-container { 275 | font-family: "Helvetica Neue", Arial, Helvetica, sans-serif; 276 | font-size: 12px; 277 | font-size: 0.75rem; 278 | line-height: 1.5; 279 | } 280 | 281 | 282 | /* general toolbar styles */ 283 | 284 | .leaflet-bar { 285 | box-shadow: 0 1px 5px rgba(0,0,0,0.65); 286 | border-radius: 4px; 287 | } 288 | .leaflet-bar a { 289 | background-color: #fff; 290 | border-bottom: 1px solid #ccc; 291 | width: 26px; 292 | height: 26px; 293 | line-height: 26px; 294 | display: block; 295 | text-align: center; 296 | text-decoration: none; 297 | color: black; 298 | } 299 | .leaflet-bar a, 300 | .leaflet-control-layers-toggle { 301 | background-position: 50% 50%; 302 | background-repeat: no-repeat; 303 | display: block; 304 | } 305 | .leaflet-bar a:hover, 306 | .leaflet-bar a:focus { 307 | background-color: #f4f4f4; 308 | } 309 | .leaflet-bar a:first-child { 310 | border-top-left-radius: 4px; 311 | border-top-right-radius: 4px; 312 | } 313 | .leaflet-bar a:last-child { 314 | border-bottom-left-radius: 4px; 315 | border-bottom-right-radius: 4px; 316 | border-bottom: none; 317 | } 318 | .leaflet-bar a.leaflet-disabled { 319 | cursor: default; 320 | background-color: #f4f4f4; 321 | color: #bbb; 322 | } 323 | 324 | .leaflet-touch .leaflet-bar a { 325 | width: 30px; 326 | height: 30px; 327 | line-height: 30px; 328 | } 329 | .leaflet-touch .leaflet-bar a:first-child { 330 | border-top-left-radius: 2px; 331 | border-top-right-radius: 2px; 332 | } 333 | .leaflet-touch .leaflet-bar a:last-child { 334 | border-bottom-left-radius: 2px; 335 | border-bottom-right-radius: 2px; 336 | } 337 | 338 | /* zoom control */ 339 | 340 | .leaflet-control-zoom-in, 341 | .leaflet-control-zoom-out { 342 | font: bold 18px 'Lucida Console', Monaco, monospace; 343 | text-indent: 1px; 344 | } 345 | 346 | .leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { 347 | font-size: 22px; 348 | } 349 | 350 | 351 | /* layers control */ 352 | 353 | .leaflet-control-layers { 354 | box-shadow: 0 1px 5px rgba(0,0,0,0.4); 355 | background: #fff; 356 | border-radius: 5px; 357 | } 358 | .leaflet-control-layers-toggle { 359 | background-image: url(images/layers.png); 360 | width: 36px; 361 | height: 36px; 362 | } 363 | .leaflet-retina .leaflet-control-layers-toggle { 364 | background-image: url(images/layers-2x.png); 365 | background-size: 26px 26px; 366 | } 367 | .leaflet-touch .leaflet-control-layers-toggle { 368 | width: 44px; 369 | height: 44px; 370 | } 371 | .leaflet-control-layers .leaflet-control-layers-list, 372 | .leaflet-control-layers-expanded .leaflet-control-layers-toggle { 373 | display: none; 374 | } 375 | .leaflet-control-layers-expanded .leaflet-control-layers-list { 376 | display: block; 377 | position: relative; 378 | } 379 | .leaflet-control-layers-expanded { 380 | padding: 6px 10px 6px 6px; 381 | color: #333; 382 | background: #fff; 383 | } 384 | .leaflet-control-layers-scrollbar { 385 | overflow-y: scroll; 386 | overflow-x: hidden; 387 | padding-right: 5px; 388 | } 389 | .leaflet-control-layers-selector { 390 | margin-top: 2px; 391 | position: relative; 392 | top: 1px; 393 | } 394 | .leaflet-control-layers label { 395 | display: block; 396 | font-size: 13px; 397 | font-size: 1.08333em; 398 | } 399 | .leaflet-control-layers-separator { 400 | height: 0; 401 | border-top: 1px solid #ddd; 402 | margin: 5px -10px 5px -6px; 403 | } 404 | 405 | /* Default icon URLs */ 406 | .leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */ 407 | background-image: url(images/marker-icon.png); 408 | } 409 | 410 | 411 | /* attribution and scale controls */ 412 | 413 | .leaflet-container .leaflet-control-attribution { 414 | background: #fff; 415 | background: rgba(255, 255, 255, 0.8); 416 | margin: 0; 417 | } 418 | .leaflet-control-attribution, 419 | .leaflet-control-scale-line { 420 | padding: 0 5px; 421 | color: #333; 422 | line-height: 1.4; 423 | } 424 | .leaflet-control-attribution a { 425 | text-decoration: none; 426 | } 427 | .leaflet-control-attribution a:hover, 428 | .leaflet-control-attribution a:focus { 429 | text-decoration: underline; 430 | } 431 | .leaflet-attribution-flag { 432 | display: inline !important; 433 | vertical-align: baseline !important; 434 | width: 1em; 435 | height: 0.6669em; 436 | } 437 | .leaflet-left .leaflet-control-scale { 438 | margin-left: 5px; 439 | } 440 | .leaflet-bottom .leaflet-control-scale { 441 | margin-bottom: 5px; 442 | } 443 | .leaflet-control-scale-line { 444 | border: 2px solid #777; 445 | border-top: none; 446 | line-height: 1.1; 447 | padding: 2px 5px 1px; 448 | white-space: nowrap; 449 | -moz-box-sizing: border-box; 450 | box-sizing: border-box; 451 | background: rgba(255, 255, 255, 0.8); 452 | text-shadow: 1px 1px #fff; 453 | } 454 | .leaflet-control-scale-line:not(:first-child) { 455 | border-top: 2px solid #777; 456 | border-bottom: none; 457 | margin-top: -2px; 458 | } 459 | .leaflet-control-scale-line:not(:first-child):not(:last-child) { 460 | border-bottom: 2px solid #777; 461 | } 462 | 463 | .leaflet-touch .leaflet-control-attribution, 464 | .leaflet-touch .leaflet-control-layers, 465 | .leaflet-touch .leaflet-bar { 466 | box-shadow: none; 467 | } 468 | .leaflet-touch .leaflet-control-layers, 469 | .leaflet-touch .leaflet-bar { 470 | border: 2px solid rgba(0,0,0,0.2); 471 | background-clip: padding-box; 472 | } 473 | 474 | 475 | /* popup */ 476 | 477 | .leaflet-popup { 478 | position: absolute; 479 | text-align: center; 480 | margin-bottom: 20px; 481 | } 482 | .leaflet-popup-content-wrapper { 483 | padding: 1px; 484 | text-align: left; 485 | border-radius: 12px; 486 | } 487 | .leaflet-popup-content { 488 | margin: 13px 24px 13px 20px; 489 | line-height: 1.3; 490 | font-size: 13px; 491 | font-size: 1.08333em; 492 | min-height: 1px; 493 | } 494 | .leaflet-popup-content p { 495 | margin: 17px 0; 496 | margin: 1.3em 0; 497 | } 498 | .leaflet-popup-tip-container { 499 | width: 40px; 500 | height: 20px; 501 | position: absolute; 502 | left: 50%; 503 | margin-top: -1px; 504 | margin-left: -20px; 505 | overflow: hidden; 506 | pointer-events: none; 507 | } 508 | .leaflet-popup-tip { 509 | width: 17px; 510 | height: 17px; 511 | padding: 1px; 512 | 513 | margin: -10px auto 0; 514 | pointer-events: auto; 515 | 516 | -webkit-transform: rotate(45deg); 517 | -moz-transform: rotate(45deg); 518 | -ms-transform: rotate(45deg); 519 | transform: rotate(45deg); 520 | } 521 | .leaflet-popup-content-wrapper, 522 | .leaflet-popup-tip { 523 | background: white; 524 | color: #333; 525 | box-shadow: 0 3px 14px rgba(0,0,0,0.4); 526 | } 527 | .leaflet-container a.leaflet-popup-close-button { 528 | position: absolute; 529 | top: 0; 530 | right: 0; 531 | border: none; 532 | text-align: center; 533 | width: 24px; 534 | height: 24px; 535 | font: 16px/24px Tahoma, Verdana, sans-serif; 536 | color: #757575; 537 | text-decoration: none; 538 | background: transparent; 539 | } 540 | .leaflet-container a.leaflet-popup-close-button:hover, 541 | .leaflet-container a.leaflet-popup-close-button:focus { 542 | color: #585858; 543 | } 544 | .leaflet-popup-scrolled { 545 | overflow: auto; 546 | } 547 | 548 | .leaflet-oldie .leaflet-popup-content-wrapper { 549 | -ms-zoom: 1; 550 | } 551 | .leaflet-oldie .leaflet-popup-tip { 552 | width: 24px; 553 | margin: 0 auto; 554 | 555 | -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; 556 | filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); 557 | } 558 | 559 | .leaflet-oldie .leaflet-control-zoom, 560 | .leaflet-oldie .leaflet-control-layers, 561 | .leaflet-oldie .leaflet-popup-content-wrapper, 562 | .leaflet-oldie .leaflet-popup-tip { 563 | border: 1px solid #999; 564 | } 565 | 566 | 567 | /* div icon */ 568 | 569 | .leaflet-div-icon { 570 | background: #fff; 571 | border: 1px solid #666; 572 | } 573 | 574 | 575 | /* Tooltip */ 576 | /* Base styles for the element that has a tooltip */ 577 | .leaflet-tooltip { 578 | position: absolute; 579 | padding: 6px; 580 | background-color: #fff; 581 | border: 1px solid #fff; 582 | border-radius: 3px; 583 | color: #222; 584 | white-space: nowrap; 585 | -webkit-user-select: none; 586 | -moz-user-select: none; 587 | -ms-user-select: none; 588 | user-select: none; 589 | pointer-events: none; 590 | box-shadow: 0 1px 3px rgba(0,0,0,0.4); 591 | } 592 | .leaflet-tooltip.leaflet-interactive { 593 | cursor: pointer; 594 | pointer-events: auto; 595 | } 596 | .leaflet-tooltip-top:before, 597 | .leaflet-tooltip-bottom:before, 598 | .leaflet-tooltip-left:before, 599 | .leaflet-tooltip-right:before { 600 | position: absolute; 601 | pointer-events: none; 602 | border: 6px solid transparent; 603 | background: transparent; 604 | content: ""; 605 | } 606 | 607 | /* Directions */ 608 | 609 | .leaflet-tooltip-bottom { 610 | margin-top: 6px; 611 | } 612 | .leaflet-tooltip-top { 613 | margin-top: -6px; 614 | } 615 | .leaflet-tooltip-bottom:before, 616 | .leaflet-tooltip-top:before { 617 | left: 50%; 618 | margin-left: -6px; 619 | } 620 | .leaflet-tooltip-top:before { 621 | bottom: 0; 622 | margin-bottom: -12px; 623 | border-top-color: #fff; 624 | } 625 | .leaflet-tooltip-bottom:before { 626 | top: 0; 627 | margin-top: -12px; 628 | margin-left: -6px; 629 | border-bottom-color: #fff; 630 | } 631 | .leaflet-tooltip-left { 632 | margin-left: -6px; 633 | } 634 | .leaflet-tooltip-right { 635 | margin-left: 6px; 636 | } 637 | .leaflet-tooltip-left:before, 638 | .leaflet-tooltip-right:before { 639 | top: 50%; 640 | margin-top: -6px; 641 | } 642 | .leaflet-tooltip-left:before { 643 | right: 0; 644 | margin-right: -12px; 645 | border-left-color: #fff; 646 | } 647 | .leaflet-tooltip-right:before { 648 | left: 0; 649 | margin-left: -12px; 650 | border-right-color: #fff; 651 | } 652 | 653 | /* Printing */ 654 | 655 | @media print { 656 | /* Prevent printers from removing background-images of controls. */ 657 | .leaflet-control { 658 | -webkit-print-color-adjust: exact; 659 | print-color-adjust: exact; 660 | } 661 | } 662 | -------------------------------------------------------------------------------- /IPCloneDetectorAndASNAnalyzer/index.php: -------------------------------------------------------------------------------- 1 | 'Afghanistan', 14 | 'AL' => 'Albania', 15 | 'DZ' => 'Algeria', 16 | 'AS' => 'American Samoa', 17 | 'AD' => 'Andorra', 18 | 'AO' => 'Angola', 19 | 'AI' => 'Anguilla', 20 | 'AG' => 'Antigua and Barbuda', 21 | 'AR' => 'Argentina', 22 | 'AM' => 'Armenia', 23 | 'AW' => 'Aruba', 24 | 'AU' => 'Australia', 25 | 'AT' => 'Austria', 26 | 'AZ' => 'Azerbaijan', 27 | 'BS' => 'Bahamas', 28 | 'BH' => 'Bahrain', 29 | 'BD' => 'Bangladesh', 30 | 'BB' => 'Barbados', 31 | 'BY' => 'Belarus', 32 | 'BE' => 'Belgium', 33 | 'BZ' => 'Belize', 34 | 'BJ' => 'Benin', 35 | 'BT' => 'Bhutan', 36 | 'BO' => 'Bolivia', 37 | 'BA' => 'Bosnia and Herzegovina', 38 | 'BW' => 'Botswana', 39 | 'BR' => 'Brazil', 40 | 'BN' => 'Brunei Darussalam', 41 | 'BG' => 'Bulgaria', 42 | 'BF' => 'Burkina Faso', 43 | 'BI' => 'Burundi', 44 | 'CV' => 'Cabo Verde', 45 | 'KH' => 'Cambodia', 46 | 'CM' => 'Cameroon', 47 | 'CA' => 'Canada', 48 | 'KY' => 'Cayman Islands', 49 | 'CF' => 'Central African Republic', 50 | 'TD' => 'Chad', 51 | 'CL' => 'Chile', 52 | 'CN' => 'China', 53 | 'CO' => 'Colombia', 54 | 'KM' => 'Comoros', 55 | 'CG' => 'Congo', 56 | 'CD' => 'Congo, Democratic Republic of the', 57 | 'CK' => 'Cook Islands', 58 | 'CR' => 'Costa Rica', 59 | 'CI' => 'Côte d\'Ivoire', 60 | 'HR' => 'Croatia', 61 | 'CU' => 'Cuba', 62 | 'CW' => 'Curaçao', 63 | 'CY' => 'Cyprus', 64 | 'CZ' => 'Czech Republic', 65 | 'DK' => 'Denmark', 66 | 'DJ' => 'Djibouti', 67 | 'DM' => 'Dominica', 68 | 'DO' => 'Dominican Republic', 69 | 'EC' => 'Ecuador', 70 | 'EG' => 'Egypt', 71 | 'SV' => 'El Salvador', 72 | 'GQ' => 'Equatorial Guinea', 73 | 'ER' => 'Eritrea', 74 | 'EE' => 'Estonia', 75 | 'SZ' => 'Eswatini', 76 | 'ET' => 'Ethiopia', 77 | 'FK' => 'Falkland Islands', 78 | 'FO' => 'Faroe Islands', 79 | 'FJ' => 'Fiji', 80 | 'FI' => 'Finland', 81 | 'FR' => 'France', 82 | 'GF' => 'French Guiana', 83 | 'PF' => 'French Polynesia', 84 | 'GA' => 'Gabon', 85 | 'GM' => 'Gambia', 86 | 'GE' => 'Georgia', 87 | 'DE' => 'Germany', 88 | 'GH' => 'Ghana', 89 | 'GI' => 'Gibraltar', 90 | 'GR' => 'Greece', 91 | 'GL' => 'Greenland', 92 | 'GD' => 'Grenada', 93 | 'GP' => 'Guadeloupe', 94 | 'GU' => 'Guam', 95 | 'GT' => 'Guatemala', 96 | 'GG' => 'Guernsey', 97 | 'GN' => 'Guinea', 98 | 'GW' => 'Guinea-Bissau', 99 | 'GY' => 'Guyana', 100 | 'HT' => 'Haiti', 101 | 'HM' => 'Heard Island and McDonald Islands', 102 | 'VA' => 'Holy See', 103 | 'HN' => 'Honduras', 104 | 'HK' => 'Hong Kong', 105 | 'HU' => 'Hungary', 106 | 'IS' => 'Iceland', 107 | 'IN' => 'India', 108 | 'ID' => 'Indonesia', 109 | 'IR' => 'Iran', 110 | 'IQ' => 'Iraq', 111 | 'IE' => 'Ireland', 112 | 'IM' => 'Isle of Man', 113 | 'IL' => 'Israel', 114 | 'IT' => 'Italy', 115 | 'JM' => 'Jamaica', 116 | 'JP' => 'Japan', 117 | 'JE' => 'Jersey', 118 | 'JO' => 'Jordan', 119 | 'KZ' => 'Kazakhstan', 120 | 'KE' => 'Kenya', 121 | 'KI' => 'Kiribati', 122 | 'KP' => 'Korea, Democratic People\'s Republic of', 123 | 'KR' => 'Korea, Republic of', 124 | 'KW' => 'Kuwait', 125 | 'KG' => 'Kyrgyzstan', 126 | 'LA' => 'Lao People\'s Democratic Republic', 127 | 'LV' => 'Latvia', 128 | 'LB' => 'Lebanon', 129 | 'LS' => 'Lesotho', 130 | 'LR' => 'Liberia', 131 | 'LY' => 'Libya', 132 | 'LI' => 'Liechtenstein', 133 | 'LT' => 'Lithuania', 134 | 'LU' => 'Luxembourg', 135 | 'MO' => 'Macao', 136 | 'MK' => 'North Macedonia', 137 | 'MG' => 'Madagascar', 138 | 'MW' => 'Malawi', 139 | 'MY' => 'Malaysia', 140 | 'MV' => 'Maldives', 141 | 'ML' => 'Mali', 142 | 'MT' => 'Malta', 143 | 'MH' => 'Marshall Islands', 144 | 'MQ' => 'Martinique', 145 | 'MR' => 'Mauritania', 146 | 'MU' => 'Mauritius', 147 | 'YT' => 'Mayotte', 148 | 'MX' => 'Mexico', 149 | 'FM' => 'Micronesia (Federated States of)', 150 | 'MD' => 'Moldova', 151 | 'MC' => 'Monaco', 152 | 'MN' => 'Mongolia', 153 | 'MM' => 'Myanmar', 154 | 'MA' => 'Morocco', 155 | 'MZ' => 'Mozambique', 156 | 'NA' => 'Namibia', 157 | 'NR' => 'Nauru', 158 | 'NP' => 'Nepal', 159 | 'NL' => 'Netherlands', 160 | 'NC' => 'New Caledonia', 161 | 'NZ' => 'New Zealand', 162 | 'NI' => 'Nicaragua', 163 | 'NE' => 'Niger', 164 | 'NG' => 'Nigeria', 165 | 'NU' => 'Niue', 166 | 'NF' => 'Norfolk Island', 167 | 'MP' => 'Northern Mariana Islands', 168 | 'NO' => 'Norway', 169 | 'OM' => 'Oman', 170 | 'PK' => 'Pakistan', 171 | 'PW' => 'Palau', 172 | 'PS' => 'Palestine, State of', 173 | 'PA' => 'Panama', 174 | 'PG' => 'Papua New Guinea', 175 | 'PY' => 'Paraguay', 176 | 'PE' => 'Peru', 177 | 'PH' => 'Philippines', 178 | 'PN' => 'Pitcairn', 179 | 'PL' => 'Poland', 180 | 'PT' => 'Portugal', 181 | 'PR' => 'Puerto Rico', 182 | 'QA' => 'Qatar', 183 | 'RE' => 'Réunion', 184 | 'RO' => 'Romania', 185 | 'RU' => 'Russian Federation', 186 | 'RW' => 'Rwanda', 187 | 'BL' => 'Saint Barthélemy', 188 | 'SH' => 'Saint Helena', 189 | 'KN' => 'Saint Kitts and Nevis', 190 | 'LC' => 'Saint Lucia', 191 | 'MF' => 'Saint Martin', 192 | 'PM' => 'Saint Pierre and Miquelon', 193 | 'VC' => 'Saint Vincent and the Grenadines', 194 | 'WS' => 'Samoa', 195 | 'SM' => 'San Marino', 196 | 'ST' => 'Sao Tome and Principe', 197 | 'SA' => 'Saudi Arabia', 198 | 'SN' => 'Senegal', 199 | 'RS' => 'Serbia', 200 | 'SC' => 'Seychelles', 201 | 'SL' => 'Sierra Leone', 202 | 'SG' => 'Singapore', 203 | 'SX' => 'Sint Maarten', 204 | 'SK' => 'Slovakia', 205 | 'SI' => 'Slovenia', 206 | 'SB' => 'Solomon Islands', 207 | 'SO' => 'Somalia', 208 | 'ZA' => 'South Africa', 209 | 'GS' => 'South Georgia and the South Sandwich Islands', 210 | 'SS' => 'South Sudan', 211 | 'ES' => 'Spain', 212 | 'LK' => 'Sri Lanka', 213 | 'SD' => 'Sudan', 214 | 'SR' => 'Suriname', 215 | 'SJ' => 'Svalbard and Jan Mayen', 216 | 'SZ' => 'Eswatini', 217 | 'SE' => 'Sweden', 218 | 'CH' => 'Switzerland', 219 | 'SY' => 'Syrian Arab Republic', 220 | 'TW' => 'Taiwan', 221 | 'TJ' => 'Tajikistan', 222 | 'TZ' => 'Tanzania, United Republic of', 223 | 'TH' => 'Thailand', 224 | 'TL' => 'Timor-Leste', 225 | 'TG' => 'Togo', 226 | 'TK' => 'Tokelau', 227 | 'TO' => 'Tonga', 228 | 'TT' => 'Trinidad and Tobago', 229 | 'TN' => 'Tunisia', 230 | 'TR' => 'Turkey', 231 | 'TM' => 'Turkmenistan', 232 | 'TC' => 'Turks and Caicos Islands', 233 | 'TV' => 'Tuvalu', 234 | 'UG' => 'Uganda', 235 | 'UA' => 'Ukraine', 236 | 'AE' => 'United Arab Emirates', 237 | 'GB' => 'United Kingdom', 238 | 'US' => 'United States', 239 | 'UY' => 'Uruguay', 240 | 'UZ' => 'Uzbekistan', 241 | 'VU' => 'Vanuatu', 242 | 'VE' => 'Venezuela', 243 | 'VN' => 'Viet Nam', 244 | 'VG' => 'British Virgin Islands', 245 | 'VI' => 'United States Virgin Islands', 246 | 'WF' => 'Wallis and Futuna', 247 | 'EH' => 'Western Sahara', 248 | 'YE' => 'Yemen', 249 | 'ZM' => 'Zambia', 250 | 'ZW' => 'Zimbabwe', 251 | ]; 252 | } 253 | 254 | // Function to get the country name from the code 255 | function getCountryName($code) 256 | { 257 | $countries = getCountryNames(); 258 | return isset($countries[$code]) ? $countries[$code] : 'Unknown country code'; 259 | } 260 | 261 | 262 | require_once(UPATH . "/inc/connection.php"); 263 | global $rpc; 264 | $users = $rpc->user()->getAll(); 265 | $server_ban = $rpc->serverban()->getAll(); 266 | 267 | function readFileContent($filePath) 268 | { 269 | $content = file($filePath, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES); 270 | if ($content === false) { 271 | echo "Impossible to open the file."; 272 | return []; 273 | } 274 | return $content; 275 | } 276 | 277 | if ($asnIsGood) 278 | $asnFileContent = readFileContent('badasn/list.txt'); 279 | 280 | function asnExists($asn, $fileContent) 281 | { 282 | foreach ($fileContent as $line) { 283 | if (trim($line) == $asn) { 284 | return true; 285 | } 286 | } 287 | return false; 288 | } 289 | 290 | function ipFromAsn($v, $asn) 291 | { 292 | global $users; 293 | $count = 0; 294 | $ipv4Count = 0; 295 | $ipv6Count = 0; 296 | $totalIpCount = 0; 297 | 298 | foreach ($users as $obj) { 299 | if (isset($obj->geoip->asn) && $obj->geoip->asn == $asn && isset($obj->ip)) { 300 | $totalIpCount++; 301 | if (filter_var($obj->ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { 302 | $ipv4Count++; 303 | } elseif (filter_var($obj->ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { 304 | $ipv6Count++; 305 | } 306 | } 307 | } 308 | 309 | $ipv4Percentage = ($totalIpCount > 0) ? ($ipv4Count / $totalIpCount) * 100 : 0; 310 | $ipv6Percentage = ($totalIpCount > 0) ? ($ipv6Count / $totalIpCount) * 100 : 0; 311 | 312 | $css = ''; 313 | if ($ipv4Percentage > $ipv6Percentage) { 314 | $css = ($v == 4) ? ' bg-success' : ' bg-danger'; 315 | } elseif ($ipv6Percentage > $ipv4Percentage) { 316 | $css = ($v == 6) ? ' bg-success' : ' bg-danger'; 317 | } 318 | 319 | if ($v == 4) { 320 | $count = $ipv4Count; 321 | $percentage = $ipv4Percentage; 322 | } else if ($v == 6) { 323 | $count = $ipv6Count; 324 | $percentage = $ipv6Percentage; 325 | } 326 | 327 | return "$count" . round($percentage, 2) . "%"; 328 | } 329 | 330 | 331 | //print_r($users); 332 | 333 | // Attempt to display an alert if no GeoIP item is found 334 | foreach ($users as $entry) { 335 | if (!isset($entry->geoip)) { 336 | echo ' 337 | '; 340 | } 341 | break; 342 | } 343 | 344 | ?> 345 | 375 | 376 | 377 | 378 |
379 | 380 |
381 | 382 |
383 |
384 |
385 |

Number of ASN duplicates sorted from largest to smallest

386 | geoip; 391 | $asn = $geoip->asn ?? ""; 392 | $asname = $geoip->asname ?? "localhost ?"; 393 | $country_code = $geoip->country_code ?? ""; 394 | 395 | if (!isset($asnCounts[$asn])) { 396 | $asnCounts[$asn] = [ 397 | 'asn' => $asn, 398 | 'asname' => $asname, 399 | 'country_code' => $country_code, 400 | 'count' => 0 401 | ]; 402 | $asnCount++; 403 | } 404 | $asnCounts[$asn]['count']++; 405 | } 406 | 407 | // Convertir en tableau indexé 408 | $asnCounts = array_values($asnCounts); 409 | 410 | // Trier par nombre d'occurrences en ordre décroissant 411 | usort($asnCounts, function ($a, $b) { 412 | return $b['count'] - $a['count']; 413 | }); 414 | 415 | 416 | echo ""; 417 | echo "" . ($asnIsGood ? "" : "") . ""; 418 | 419 | foreach ($asnCounts as $info) { 420 | echo ""; 421 | echo ""; 422 | echo ""; 423 | echo ""; 424 | echo ""; 425 | echo ""; 426 | echo ""; 427 | if ($asnIsGood) 428 | echo ""; 429 | echo ""; 430 | } 431 | 432 | echo "
ASNASNameCountry CodeCountIPv4IPv6Good ASN
" . (empty($info['asn']) ? '-' : '' . $info['asn'] . '') . "" . (empty($info['asname']) ? 'Localhost ?' : '' . $info['asname']) . '' . "" . (empty($info['country_code']) ? '-' : "{$info['country_code']} ") . "" . (empty($info['asn']) ? $info['count'] : '') . "" . (empty($info['asn']) ? '-' : ipFromAsn(4, $info['asn'])) . "" . (empty($info['asn']) ? '-' : ipFromAsn(6, $info['asn'])) . "" . (empty($info['asn']) ? '-' : (asnExists($info['asn'], $asnFileContent) ? '⚠️' : '✅')) . "
"; 433 | echo "$asnCount different ASNs found"; 434 | 435 | if ($asnIsGood) 436 | echo "

The \"Good ASN\" column is experimental. By default, all ASNs are considered good, but special attention is given to those listed in the file plugins/IPCloneDetectorAndASNAnalyzer/badasn/list.txt.

"; 437 | ?> 438 | 439 | 440 |
441 |
442 | 443 | 444 | 587 | 590 | 591 | Country 592 | Online number 593 | Percentage 594 | "; 595 | 596 | foreach ($countryCounts as $countryCode => $count) { 597 | $percentage = $totalUsers > 0 ? ($count / $totalUsers) * 100 : 0; 598 | //echo "Country Code: $countryCode - Count: $count\n"; 599 | $countries[] = $countryCode; 600 | $counts[] = $count; 601 | $country = getCountryName($countryCode); 602 | echo " 603 | " . (empty($countryCode) ? '' : "") . " " . (!empty($countryCode) ? getCountryName($countryCode) : 'localhost') . " 604 | 605 | " . number_format($percentage, 2) . "% 606 | "; 607 | } 608 | 609 | echo " 610 | Total 611 | " . count($users) . " 612 | 613 | "; 614 | 615 | echo ""; 616 | 617 | ?> 618 | 619 | 620 |

Show clones on IP

621 | $obj) { 624 | if (isset($obj->ip)) { 625 | $ip = $obj->ip; 626 | if (array_key_exists($ip, $ipList)) { 627 | $ipList[$ip]['count']++; 628 | $ipList[$ip]['names'][] = $obj->name; 629 | } else { 630 | $ipList[$ip] = [ 631 | 'count' => 1, 632 | 'names' => [$obj->name] 633 | ]; 634 | } 635 | } 636 | } 637 | 638 | $duplicateList = []; 639 | foreach ($ipList as $ip => $info) { 640 | if ($info['count'] > 1) { 641 | $duplicateList[] = [ 642 | 'ip' => $ip, 643 | 'count' => $info['count'], 644 | 'names' => implode(', ', $info['names']) 645 | ]; 646 | } 647 | } 648 | 649 | echo " 650 | 651 | 652 | 653 | 654 | "; 655 | 656 | foreach ($duplicateList as $entry) { 657 | echo " 658 | 659 | 660 | 661 | "; 662 | } 663 | 664 | echo "
IPNumber
of
duplicates
List of names
{$entry['ip']}{$entry['count']}{$entry['names']}
"; 665 | ?> 666 |
667 |

Show clones based on the first 4 segments of IPv6 addresses

668 | $obj) { 671 | if (isset($obj->ip) && strpos($obj->ip, ':') !== false) { 672 | // Extraire les quatre premiers segments de l'IPv6 673 | $ipSegments = explode(':', $obj->ip); 674 | $shortIp = implode(':', array_slice($ipSegments, 0, 4)); 675 | 676 | if (array_key_exists($shortIp, $ipList)) { 677 | $ipList[$shortIp]['count']++; 678 | $ipList[$shortIp]['names'][] = $obj->name; 679 | } else { 680 | $ipList[$shortIp] = [ 681 | 'count' => 1, 682 | 'names' => [$obj->name] 683 | ]; 684 | } 685 | } 686 | } 687 | 688 | $duplicateList = []; 689 | foreach ($ipList as $ip => $info) { 690 | if ($info['count'] > 1) { 691 | $duplicateList[] = [ 692 | 'ip' => $ip, 693 | 'count' => $info['count'], 694 | 'names' => implode(', ', $info['names']) 695 | ]; 696 | } 697 | } 698 | 699 | echo " 700 | 701 | 702 | 703 | 704 | "; 705 | 706 | foreach ($duplicateList as $entry) { 707 | echo " 708 | 709 | 710 | 711 | "; 712 | } 713 | 714 | echo "
IPNumber
of
duplicates
List of names
{$entry['ip']}{$entry['count']}{$entry['names']}
"; 715 | ?> 716 | 717 |
718 |

Statistics Users

719 | ip)) { 729 | if (filter_var($obj->ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { 730 | $ipv4Count++; 731 | } elseif (filter_var($obj->ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { 732 | $ipv6Count++; 733 | } 734 | } 735 | if (isset($obj->user)) { 736 | if (isset($obj->user->account)) { 737 | $accountCount++; 738 | } else { 739 | $noAccountCount++; 740 | } 741 | } 742 | } 743 | 744 | echo " 745 | 746 | 747 | 748 | 749 | 750 | 751 | 752 | 753 | 754 | 755 | 756 | 757 | 758 | 759 | 760 | 761 | 762 | 763 | 764 | 765 | 766 | 767 | 768 | 769 |
TypeOnline number
Number of total users{$usersCount}
Number of IPv4{$ipv4Count}
Number of IPv6{$ipv6Count}
Number of account{$accountCount}
Number of no account{$noAccountCount}
"; 770 | ?> 771 | 772 | 773 |

Bans server corresponding to '~asn:'

774 | 776 | 777 | Type ban 778 | Found 779 | Affected users 780 | duration 781 | 782 | "; 783 | foreach ($server_ban as $obj) { 784 | $usersCount++; 785 | if (isset($obj->name)) { 786 | if (strpos($obj->name, "~asn:") !== false && preg_match('/^\%/', $obj->name, $matches) === 1) { 787 | echo " 788 | {$obj->type} 789 | {$obj->name} 790 | unregistered 791 | {$obj->duration_string} 792 | "; 793 | } else if (strpos($obj->name, "~asn:") !== false) { 794 | echo " 795 | {$obj->type} 796 | {$obj->name} 797 | all 798 | {$obj->duration_string} 799 | "; 800 | } 801 | } 802 | } 803 | echo ""; 804 | ?> 805 | 806 | 807 |

Bans server corresponding to other type of '~'

808 | 811 | 812 | Type ban 813 | Found 814 | Affected users 815 | duration 816 | 817 | "; 818 | foreach ($server_ban as $obj) { 819 | $usersCount++; 820 | if (isset($obj->name)) { 821 | if (strpos($obj->name, "~asn:") === false && strpos($obj->name, "~") !== false && preg_match('/^\%/', $obj->name, $matches) === 1) { 822 | echo " 823 | {$obj->type} 824 | {$obj->name} 825 | unregistered 826 | {$obj->duration_string} 827 | "; 828 | } else if (strpos($obj->name, "~asn:") === false && strpos($obj->name, "~") !== false) { 829 | echo " 830 | {$obj->type} 831 | {$obj->name} 832 | all 833 | {$obj->duration_string} 834 | "; 835 | } 836 | } 837 | } 838 | echo ""; 839 | ?> 840 |
841 |
842 |
843 | 844 | 845 | 885 | 886 | 901 | 902 | 1072 | 1073 | 1079 | --------------------------------------------------------------------------------