diff --git a/core/config/filter.php b/core/config/filter.php index 0ca22bf..b5c2b88 100644 --- a/core/config/filter.php +++ b/core/config/filter.php @@ -9,8 +9,8 @@ */ 'pre' => [ '\\Filter\\Pre\\Trim', - '\\Filter\\Pre\\Length', '\\Filter\\Pre\\Lines', + '\\Filter\\Pre\\Length', '\\Filter\\Pre\\Ip', '\\Filter\\Pre\\Username', '\\Filter\\Pre\\AccessToken' diff --git a/core/src/Filter/Pre/Lines.php b/core/src/Filter/Pre/Lines.php index 01eb5fb..f175fa5 100644 --- a/core/src/Filter/Pre/Lines.php +++ b/core/src/Filter/Pre/Lines.php @@ -15,6 +15,24 @@ class Lines implements PreFilterInterface { public static function Filter(string $data): string { $config = \Config::Get('storage'); - return implode("\n", array_slice(explode("\n", $data), 0, $config["maxLines"])); + $limit = $config["maxLines"]; + + $lines = explode("\n", $data); + $count = count($lines); + + if ($count <= $limit) { + return $data; + } + + $removed = $count - $limit + 3; + $message = "Truncated " . $removed . " line" . ($removed > 1 ? "s" : ""); + + array_splice($lines, $limit / 2, $removed, [ + str_repeat("=", strlen($message)), + $message, + str_repeat("=", strlen($message)), + ]); + + return implode("\n", $lines); } } \ No newline at end of file diff --git a/web/public/js/mclogs.js b/web/public/js/mclogs.js index 78b3f42..1375c26 100644 --- a/web/public/js/mclogs.js +++ b/web/public/js/mclogs.js @@ -46,6 +46,40 @@ document.addEventListener('keydown', event => { return true; }) +/** + * Limit the number of characters in a string by removing the end + * @param {string} string + * @param {number} limit + * @returns {string} + */ +function limitLength(string, limit = parseInt(pasteArea.dataset.maxLength)) { + return string.substring(0, limit); +} + +/** + * Limit the number of lines in a string by truncating the middle + * @param {string} string + * @param {number} limit + * @returns {string} + */ +function limitLines(string, limit = parseInt(pasteArea.dataset.maxLines)) { + let lines = string.split('\n'); + if (lines.length <= limit) { + return string; + } + + let removed = lines.length - limit + 3; + let message = 'Truncated ' + removed + ' line' + (removed > 1 ? 's' : ''); + + lines.splice(limit / 2, removed, + "=".repeat(message.length), + message, + "=".repeat(message.length) + ); + + return lines.join('\n') +} + /** * Save the log to the API * @returns {Promise} @@ -58,9 +92,9 @@ async function sendLog() { pasteSaveButtons.forEach(button => button.classList.add("btn-working")); try { - let log = pasteArea.value - .substring(0, parseInt(pasteArea.dataset.maxLength)) - .split('\n').slice(0, parseInt(pasteArea.dataset.maxLines)).join('\n'); + let log = pasteArea.value; + log = limitLines(log); + log = limitLength(log); const response = await fetch(`${location.protocol}//api.${location.host}/1/log`, { method: "POST",