Compare commits
17 Commits
bf3870ccca
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 240635d30c | |||
| 47303d6812 | |||
| aeef6bc0cd | |||
| 415324f340 | |||
| 21aaeac884 | |||
| 4d0d98c604 | |||
| cc1e853f89 | |||
| 0282ab594e | |||
| 8437d62394 | |||
| 4fced60a83 | |||
| 33fcd0d81f | |||
| f72e2d0936 | |||
| 3e03f81e74 | |||
| 94326d5a19 | |||
| 6724320c9a | |||
| 8f0b067e38 | |||
| 4aeebf3732 |
@@ -2,8 +2,9 @@ FROM dunglas/frankenphp:1-php8.5
|
|||||||
|
|
||||||
# System Setup
|
# System Setup
|
||||||
RUN install-php-extensions mongodb zip
|
RUN install-php-extensions mongodb zip
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates && rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
ARG USER=mclogs
|
ARG USER=iblogs
|
||||||
RUN useradd ${USER} && \
|
RUN useradd ${USER} && \
|
||||||
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp
|
setcap CAP_NET_BIND_SERVICE=+eip /usr/local/bin/frankenphp
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ RUN --mount=type=cache,target=/tmp/cache/composer \
|
|||||||
|
|
||||||
# Application Setup
|
# Application Setup
|
||||||
COPY docker/Caddyfile /etc/frankenphp/Caddyfile
|
COPY docker/Caddyfile /etc/frankenphp/Caddyfile
|
||||||
COPY docker/mclogs.ini /usr/local/etc/php/conf.d/mclogs.ini
|
COPY docker/iblogs.ini /usr/local/etc/php/conf.d/iblogs.ini
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
|||||||
42
README.md
42
README.md
@@ -13,7 +13,7 @@
|
|||||||
* Syntax highlighting
|
* Syntax highlighting
|
||||||
* Line numbers
|
* Line numbers
|
||||||
* Direct links to specific lines
|
* Direct links to specific lines
|
||||||
* Analysis and parsing using [codex](https://github.com/aternosorg/codex-minecraft)
|
* Analysis and parsing using [indifferentketchup/codex](https://git.indifferentketchup.com/indifferentketchup/ik-codex), forked from [aternos/codex-minecraft](https://github.com/aternosorg/codex-minecraft)
|
||||||
|
|
||||||
### For developers
|
### For developers
|
||||||
* Upload your logs using the API
|
* Upload your logs using the API
|
||||||
@@ -22,34 +22,34 @@
|
|||||||
* Open source and self-hostable
|
* Open source and self-hostable
|
||||||
|
|
||||||
## Self-hosting
|
## Self-hosting
|
||||||
You can self-host mclogs using Docker. A [docker image](https://github.com/aternosorg/mclogs/pkgs/container/mclogs) is available in the GitHub Container Registry: `ghcr.io/aternosorg/mclogs`.
|
You can self-host iblogs using Docker. A [docker image](https://github.com/indifferentketchup/iblogs/pkgs/container/iblogs) is available in the GitHub Container Registry: `ghcr.io/indifferentketchup/iblogs`.
|
||||||
A MongoDB instance is also required to run mclogs.
|
A MongoDB instance is also required to run iblogs.
|
||||||
|
|
||||||
An example docker compose files for self-hosting can be found here: [docker/compose.production.yaml](docker/compose.production.yaml).
|
An example docker compose files for self-hosting can be found here: [docker/compose.production.yaml](docker/compose.production.yaml).
|
||||||
|
|
||||||
### Config
|
### Config
|
||||||
You can configure mclogs by creating a `config.json` file in the root directory, see [example.config.json](example.config.json) or by setting
|
You can configure iblogs by creating a `config.json` file in the root directory, see [example.config.json](example.config.json) or by setting
|
||||||
environment variables. Environment variables override settings in the config file.
|
environment variables. Environment variables override settings in the config file.
|
||||||
|
|
||||||
Here is a list of all available config options:
|
Here is a list of all available config options:
|
||||||
|
|
||||||
| Variable / JSON Path | Default | Description |
|
| Variable / JSON Path | Default | Description |
|
||||||
|:--------------------------------------------------------------------|:--------------------|:--------------------------------------------|
|
|:--------------------------------------------------------------------|:--------------------|:--------------------------------------------|
|
||||||
| `MCLOGS_STORAGE_TTL` <br> `storage.ttl` | `7776000` (90d) | Time until logs are deleted after last view |
|
| `IBLOGS_STORAGE_TTL` <br> `storage.ttl` | `7776000` (90d) | Time until logs are deleted after last view |
|
||||||
| `MCLOGS_STORAGE_LIMIT_BYTES` <br> `storage.limit.bytes` | `10485760` (10 MiB) | Maximum size of a log in bytes |
|
| `IBLOGS_STORAGE_LIMIT_BYTES` <br> `storage.limit.bytes` | `10485760` (10 MiB) | Maximum size of a log in bytes |
|
||||||
| `MCLOGS_STORAGE_LIMIT_LINES` <br> `storage.limit.lines` | `25000` | Maximum number of lines in a log |
|
| `IBLOGS_STORAGE_LIMIT_LINES` <br> `storage.limit.lines` | `25000` | Maximum number of lines in a log |
|
||||||
| `MCLOGS_MONGODB_URL` <br> `mongodb.url` | `"mongodb://mongo"` | MongoDB connection URL |
|
| `IBLOGS_MONGODB_URL` <br> `mongodb.url` | `"mongodb://mongo"` | MongoDB connection URL |
|
||||||
| `MCLOGS_MONGODB_DATABASE` <br> `mongodb.database` | `"mclogs"` | Name of the MongoDB database |
|
| `IBLOGS_MONGODB_DATABASE` <br> `mongodb.database` | `"iblogs"` | Name of the MongoDB database |
|
||||||
| `MCLOGS_ID_LENGTH` <br> `id.length` | `7` | The default length for new IDs |
|
| `IBLOGS_ID_LENGTH` <br> `id.length` | `7` | The default length for new IDs |
|
||||||
| `MCLOGS_LEGAL_ABUSE` <br> `legal.abuse` | `null` | Public email address to report abuse |
|
| `IBLOGS_LEGAL_ABUSE` <br> `legal.abuse` | `null` | Public email address to report abuse |
|
||||||
| `MCLOGS_LEGAL_IMPRINT` <br> `legal.imprint` | `null` | The imprint URL |
|
| `IBLOGS_LEGAL_IMPRINT` <br> `legal.imprint` | `null` | The imprint URL |
|
||||||
| `MCLOGS_LEGAL_PRIVACY` <br> `legal.privacy` | `null` | The privacy policy URL |
|
| `IBLOGS_LEGAL_PRIVACY` <br> `legal.privacy` | `null` | The privacy policy URL |
|
||||||
| `MCLOGS_FRONTEND_NAME` <br> `frontend.name` | `null` | Instance name (defaults to domain) |
|
| `IBLOGS_FRONTEND_NAME` <br> `frontend.name` | `null` | Instance name (defaults to domain) |
|
||||||
| `MCLOGS_FRONTEND_COLOR_ACCENT` <br> `frontend.color.accent` | `#5cb85c` | The accent/primary color |
|
| `IBLOGS_FRONTEND_COLOR_ACCENT` <br> `frontend.color.accent` | `#5cb85c` | The accent/primary color |
|
||||||
| `MCLOGS_FRONTEND_COLOR_BACKGROUND` <br> `frontend.color.background` | `#1a1a1a` | The background color |
|
| `IBLOGS_FRONTEND_COLOR_BACKGROUND` <br> `frontend.color.background` | `#1a1a1a` | The background color |
|
||||||
| `MCLOGS_FRONTEND_COLOR_TEXT` <br> `frontend.color.text` | `#e8e8e8` | The text color |
|
| `IBLOGS_FRONTEND_COLOR_TEXT` <br> `frontend.color.text` | `#e8e8e8` | The text color |
|
||||||
| `MCLOGS_FRONTEND_COLOR_ERROR` <br> `frontend.color.error` | `#f62451` | The error color |
|
| `IBLOGS_FRONTEND_COLOR_ERROR` <br> `frontend.color.error` | `#f62451` | The error color |
|
||||||
| `MCLOGS_WORKER_REQUESTS` <br> `worker.requests` | `500` | Max requests per single worker |
|
| `IBLOGS_WORKER_REQUESTS` <br> `worker.requests` | `500` | Max requests per single worker |
|
||||||
|
|
||||||
There are a few more environment variables that can be set to modify the FrankenPHP/Caddy setup directly:
|
There are a few more environment variables that can be set to modify the FrankenPHP/Caddy setup directly:
|
||||||
|
|
||||||
@@ -69,10 +69,10 @@ There are a few more environment variables that can be set to modify the Franken
|
|||||||
### Installation
|
### Installation
|
||||||
```bash
|
```bash
|
||||||
# clone repository
|
# clone repository
|
||||||
git clone git@github.com:aternosorg/mclogs.git
|
git clone git@github.com:indifferentketchup/iblogs.git
|
||||||
|
|
||||||
# install composer dependencies
|
# install composer dependencies
|
||||||
cd mclogs
|
cd iblogs
|
||||||
composer install
|
composer install
|
||||||
|
|
||||||
# start development environment
|
# start development environment
|
||||||
|
|||||||
@@ -2,4 +2,4 @@
|
|||||||
|
|
||||||
require_once __DIR__ . '/vendor/autoload.php';
|
require_once __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
\Aternos\Mclogs\Frontend\Assets\AssetLoader::getInstance()->writeCache();
|
\IndifferentKetchup\Iblogs\Frontend\Assets\AssetLoader::getInstance()->writeCache();
|
||||||
@@ -1,10 +1,16 @@
|
|||||||
{
|
{
|
||||||
"name": "aternos/mclogs",
|
"name": "indifferentketchup/iblogs",
|
||||||
"description": "Paste, share and analyse Minecraft logs",
|
"description": "Paste, share, and analyse game-server logs.",
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Matthias Neid",
|
"name": "indifferentketchup",
|
||||||
"email": "matthias@aternos.org"
|
"email": "samkintop@gmail.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"repositories": [
|
||||||
|
{
|
||||||
|
"type": "vcs",
|
||||||
|
"url": "https://git.indifferentketchup.com/indifferentketchup/ik-codex"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
@@ -15,14 +21,12 @@
|
|||||||
"ext-mongodb": "*",
|
"ext-mongodb": "*",
|
||||||
"ext-uri": "*",
|
"ext-uri": "*",
|
||||||
"ext-zlib": "*",
|
"ext-zlib": "*",
|
||||||
"aternos/codex-hytale": "^2.0",
|
"indifferentketchup/codex": "^0.3.0",
|
||||||
"aternos/codex-minecraft": "^5.0.1",
|
|
||||||
"aternos/sherlock": "^1.0.2",
|
|
||||||
"mongodb/mongodb": "2.1.2"
|
"mongodb/mongodb": "2.1.2"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Aternos\\Mclogs\\": "src/"
|
"IndifferentKetchup\\Iblogs\\": "src/"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
184
composer.lock
generated
184
composer.lock
generated
@@ -4,21 +4,15 @@
|
|||||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||||
"This file is @generated automatically"
|
"This file is @generated automatically"
|
||||||
],
|
],
|
||||||
"content-hash": "a570f76a4698742115ca4d1d4113a836",
|
"content-hash": "c970170e823f1c31130ee1eec742a090",
|
||||||
"packages": [
|
"packages": [
|
||||||
{
|
{
|
||||||
"name": "aternos/codex",
|
"name": "indifferentketchup/codex",
|
||||||
"version": "v4.1.0",
|
"version": "v0.3.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/aternosorg/codex.git",
|
"url": "https://git.indifferentketchup.com/indifferentketchup/ik-codex",
|
||||||
"reference": "2d0b1930464d9c5129e90c5e69314b1da22c7c4a"
|
"reference": "656142dbf8979da7d5f06908e5dd53afa1b5e56d"
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/aternosorg/codex/zipball/2d0b1930464d9c5129e90c5e69314b1da22c7c4a",
|
|
||||||
"reference": "2d0b1930464d9c5129e90c5e69314b1da22c7c4a",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.4"
|
"php": ">=8.4"
|
||||||
@@ -29,161 +23,31 @@
|
|||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Aternos\\Codex\\": "src/"
|
"IndifferentKetchup\\Codex\\": "src/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"autoload-dev": {
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Matthias Neid",
|
|
||||||
"email": "matthias@aternos.org"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "PHP library to read, parse, print and analyse log files.",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/aternosorg/codex/issues",
|
|
||||||
"source": "https://github.com/aternosorg/codex/tree/v4.1.0"
|
|
||||||
},
|
|
||||||
"time": "2026-01-21T14:12:19+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "aternos/codex-hytale",
|
|
||||||
"version": "v2.0.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/aternosorg/codex-hytale.git",
|
|
||||||
"reference": "9b48e2d0fa4b82a3f10c8833a766b7e76e233271"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/aternosorg/codex-hytale/zipball/9b48e2d0fa4b82a3f10c8833a766b7e76e233271",
|
|
||||||
"reference": "9b48e2d0fa4b82a3f10c8833a766b7e76e233271",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"aternos/codex": "^v4.1.0",
|
|
||||||
"ext-json": "*",
|
|
||||||
"php": ">=8.4.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^12.4"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
"psr-4": {
|
||||||
"Aternos\\Codex\\Hytale\\": "src/"
|
"IndifferentKetchup\\Codex\\Test\\Src\\": "test/src/",
|
||||||
|
"IndifferentKetchup\\Codex\\Test\\Tests\\": "test/tests/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
"scripts": {
|
||||||
|
"test": [
|
||||||
|
"phpunit test/tests"
|
||||||
|
]
|
||||||
|
},
|
||||||
"license": [
|
"license": [
|
||||||
"MIT"
|
"MIT"
|
||||||
],
|
],
|
||||||
"authors": [
|
"authors": [
|
||||||
{
|
{
|
||||||
"name": "Matthias",
|
"name": "indifferentketchup",
|
||||||
"email": "matthias@aternos.org"
|
"email": "samkintop@gmail.com"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"description": "PHP library to read, parse, print and analyse Hytale log files.",
|
"description": "Generic PHP log parsing and analysis framework.",
|
||||||
"support": {
|
"time": "2026-05-06T19:04:37+00:00"
|
||||||
"issues": "https://github.com/aternosorg/codex-hytale/issues",
|
|
||||||
"source": "https://github.com/aternosorg/codex-hytale/tree/v2.0.0"
|
|
||||||
},
|
|
||||||
"time": "2026-01-23T12:25:09+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "aternos/codex-minecraft",
|
|
||||||
"version": "v5.1.0",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/aternosorg/codex-minecraft.git",
|
|
||||||
"reference": "f921d0277449af04a72c3dbb784e37b5fa4934b1"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/aternosorg/codex-minecraft/zipball/f921d0277449af04a72c3dbb784e37b5fa4934b1",
|
|
||||||
"reference": "f921d0277449af04a72c3dbb784e37b5fa4934b1",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"aternos/codex": "^v4.1.0",
|
|
||||||
"ext-json": "*",
|
|
||||||
"php": ">=8.4.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^12"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Aternos\\Codex\\Minecraft\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Matthias",
|
|
||||||
"email": "matthias@aternos.org"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "PHP library to read, parse, print and analyse Minecraft log files.",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/aternosorg/codex-minecraft/issues",
|
|
||||||
"source": "https://github.com/aternosorg/codex-minecraft/tree/v5.1.0"
|
|
||||||
},
|
|
||||||
"time": "2026-03-30T18:21:47+00:00"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "aternos/sherlock",
|
|
||||||
"version": "v1.1.3",
|
|
||||||
"source": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/aternosorg/sherlock.git",
|
|
||||||
"reference": "2bfb6427790b24df860f20905b76f09978a7df3a"
|
|
||||||
},
|
|
||||||
"dist": {
|
|
||||||
"type": "zip",
|
|
||||||
"url": "https://api.github.com/repos/aternosorg/sherlock/zipball/2bfb6427790b24df860f20905b76f09978a7df3a",
|
|
||||||
"reference": "2bfb6427790b24df860f20905b76f09978a7df3a",
|
|
||||||
"shasum": ""
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"ext-curl": "*",
|
|
||||||
"ext-simplexml": "*",
|
|
||||||
"ext-zlib": "*",
|
|
||||||
"php": ">=8.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"phpunit/phpunit": "^9.5"
|
|
||||||
},
|
|
||||||
"type": "library",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Aternos\\Sherlock\\": "src/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"notification-url": "https://packagist.org/downloads/",
|
|
||||||
"license": [
|
|
||||||
"MIT"
|
|
||||||
],
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Julian Vennen",
|
|
||||||
"email": "julian@aternos.org"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"description": "PHP library to apply minecraft mappings to log files",
|
|
||||||
"support": {
|
|
||||||
"issues": "https://github.com/aternosorg/sherlock/issues",
|
|
||||||
"source": "https://github.com/aternosorg/sherlock/tree/v1.1.3"
|
|
||||||
},
|
|
||||||
"time": "2026-02-09T10:37:21+00:00"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "mongodb/mongodb",
|
"name": "mongodb/mongodb",
|
||||||
@@ -314,16 +178,16 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/polyfill-php85",
|
"name": "symfony/polyfill-php85",
|
||||||
"version": "v1.33.0",
|
"version": "v1.37.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/polyfill-php85.git",
|
"url": "https://github.com/symfony/polyfill-php85.git",
|
||||||
"reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91"
|
"reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91",
|
"url": "https://api.github.com/repos/symfony/polyfill-php85/zipball/fcfa4973a9917cef23f2e38774da74a2b7d115ee",
|
||||||
"reference": "d4e5fcd4ab3d998ab16c0db48e6cbb9a01993f91",
|
"reference": "fcfa4973a9917cef23f2e38774da74a2b7d115ee",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
@@ -370,7 +234,7 @@
|
|||||||
"shim"
|
"shim"
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/polyfill-php85/tree/v1.33.0"
|
"source": "https://github.com/symfony/polyfill-php85/tree/v1.37.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
@@ -390,7 +254,7 @@
|
|||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2025-06-23T16:12:55+00:00"
|
"time": "2026-04-26T13:10:57+00:00"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"packages-dev": [],
|
"packages-dev": [],
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
name: "mclogs"
|
name: "iblogs"
|
||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
build:
|
build:
|
||||||
context: ..
|
context: ..
|
||||||
dockerfile: ./Dockerfile
|
dockerfile: ./Dockerfile
|
||||||
environment:
|
environment:
|
||||||
- MCLOGS_WORKER_REQUESTS=1
|
- IBLOGS_WORKER_REQUESTS=1
|
||||||
- FRANKENPHP_WORKERS=4
|
- FRANKENPHP_WORKERS=4
|
||||||
ports:
|
ports:
|
||||||
- "80:80"
|
- "4217:80"
|
||||||
volumes:
|
volumes:
|
||||||
- ../:/app
|
- ../:/app
|
||||||
- ./dev.ini:/usr/local/etc/php/conf.d/dev.ini
|
- ./dev.ini:/usr/local/etc/php/conf.d/dev.ini
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
services:
|
services:
|
||||||
web:
|
web:
|
||||||
image: ghcr.io/aternosorg/mclogs:2
|
image: ghcr.io/indifferentketchup/iblogs:2
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
# Expose HTTP (80) and HTTPS (443)
|
# Expose HTTP (80) and HTTPS (443)
|
||||||
@@ -9,16 +9,16 @@ services:
|
|||||||
- "443:443"
|
- "443:443"
|
||||||
- "443:443/udp"
|
- "443:443/udp"
|
||||||
environment:
|
environment:
|
||||||
# Set this to your domain (e.g., mclogs.example.com) to enable Auto-SSL.
|
# Set this to your domain (e.g., iblogs.example.com) to enable Auto-SSL.
|
||||||
# If running behind a proxy (Cloudflare/Nginx), set to ":80" to disable Auto-SSL.
|
# If running behind a proxy (Cloudflare/Nginx), set to ":80" to disable Auto-SSL.
|
||||||
SERVER_NAME: :80
|
SERVER_NAME: :80
|
||||||
|
|
||||||
MCLOGS_MONGODB_URL: mongodb://mongo:27017
|
IBLOGS_MONGODB_URL: mongodb://mongo:27017
|
||||||
MCLOGS_MONGODB_DATABASE: mclogs
|
IBLOGS_MONGODB_DATABASE: iblogs
|
||||||
|
|
||||||
# Optional MCLOGS configuration
|
# Optional IBLOGS configuration
|
||||||
# See README.md for full list of available options
|
# See README.md for full list of available options
|
||||||
# MCLOGS_FRONTEND_NAME: "mclogs"
|
# IBLOGS_FRONTEND_NAME: "iblogs"
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
# For caddy cache (SSL certificates)
|
# For caddy cache (SSL certificates)
|
||||||
|
|||||||
@@ -8,18 +8,18 @@
|
|||||||
},
|
},
|
||||||
"mongodb": {
|
"mongodb": {
|
||||||
"url": "mongodb://127.0.0.1:27017",
|
"url": "mongodb://127.0.0.1:27017",
|
||||||
"database": "mclogs"
|
"database": "iblogs"
|
||||||
},
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"length": 7
|
"length": 7
|
||||||
},
|
},
|
||||||
"legal": {
|
"legal": {
|
||||||
"abuse": "abuse@aternos.org",
|
"abuse": "samkintop@gmail.com",
|
||||||
"imprint": "https://aternos.gmbh/imprint/",
|
"imprint": "https://indifferentketchup.com/imprint",
|
||||||
"privacy": "https://aternos.gmbh/en/mclogs/privacy"
|
"privacy": "https://indifferentketchup.com/iblogs/privacy"
|
||||||
},
|
},
|
||||||
"frontend": {
|
"frontend": {
|
||||||
"name": "mclo.gs",
|
"name": "iblogs.example",
|
||||||
"assets": {
|
"assets": {
|
||||||
"integrity": true
|
"integrity": true
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\LogContentParser;
|
use IndifferentKetchup\Iblogs\Api\LogContentParser;
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Api\Response\CodexLogResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\CodexLogResponse;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
|
|
||||||
class AnalyseLogAction extends ApiAction
|
class AnalyseLogAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\ContentParser;
|
use IndifferentKetchup\Iblogs\Api\ContentParser;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Router\Action;
|
use IndifferentKetchup\Iblogs\Router\Action;
|
||||||
|
|
||||||
abstract class ApiAction extends Action
|
abstract class ApiAction extends Action
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\ContentParser;
|
use IndifferentKetchup\Iblogs\Api\ContentParser;
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Api\Response\MultiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\MultiResponse;
|
||||||
use Aternos\Mclogs\Id;
|
use IndifferentKetchup\Iblogs\Id;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
use Aternos\Mclogs\Storage\MongoDBClient;
|
use IndifferentKetchup\Iblogs\Storage\MongoDBClient;
|
||||||
|
|
||||||
class BulkDeleteLogsAction extends ApiAction
|
class BulkDeleteLogsAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\LogContentParser;
|
use IndifferentKetchup\Iblogs\Api\LogContentParser;
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Api\Response\LogResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\LogResponse;
|
||||||
use Aternos\Mclogs\Data\MetadataEntry;
|
use IndifferentKetchup\Iblogs\Data\MetadataEntry;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
|
|
||||||
class CreateLogAction extends ApiAction
|
class CreateLogAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Id;
|
use IndifferentKetchup\Iblogs\Id;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
class DeleteLogAction extends ApiAction
|
class DeleteLogAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Router\Action;
|
use IndifferentKetchup\Iblogs\Router\Action;
|
||||||
|
|
||||||
class EmptyAction extends Action
|
class EmptyAction extends Action
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
|
|
||||||
class EndpointNotFoundAction extends ApiAction
|
class EndpointNotFoundAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Api\Response\FiltersResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\FiltersResponse;
|
||||||
|
|
||||||
class GetFiltersAction extends ApiAction
|
class GetFiltersAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Api\Response\LimitsResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\LimitsResponse;
|
||||||
|
|
||||||
class GetLimitsAction extends ApiAction
|
class GetLimitsAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Api\Response\LogResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\LogResponse;
|
||||||
use Aternos\Mclogs\Id;
|
use IndifferentKetchup\Iblogs\Id;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
class LogInfoAction extends ApiAction
|
class LogInfoAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Api\Response\CodexLogResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\CodexLogResponse;
|
||||||
use Aternos\Mclogs\Id;
|
use IndifferentKetchup\Iblogs\Id;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
class LogInsightsAction extends ApiAction
|
class LogInsightsAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
|
|
||||||
class RateLimitErrorAction extends ApiAction
|
class RateLimitErrorAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Action;
|
namespace IndifferentKetchup\Iblogs\Api\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Api\Response\RawLogResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\RawLogResponse;
|
||||||
use Aternos\Mclogs\Id;
|
use IndifferentKetchup\Iblogs\Id;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
class RawLogAction extends ApiAction
|
class RawLogAction extends ApiAction
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api;
|
namespace IndifferentKetchup\Iblogs\Api;
|
||||||
|
|
||||||
use Aternos\Mclogs\Router\Router;
|
use IndifferentKetchup\Iblogs\Router\Router;
|
||||||
use Aternos\Mclogs\Frontend;
|
use IndifferentKetchup\Iblogs\Frontend;
|
||||||
use Aternos\Mclogs\Id;
|
use IndifferentKetchup\Iblogs\Id;
|
||||||
use Aternos\Mclogs\Router\Method;
|
use IndifferentKetchup\Iblogs\Router\Method;
|
||||||
|
|
||||||
class ApiRouter extends Router
|
class ApiRouter extends Router
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api;
|
namespace IndifferentKetchup\Iblogs\Api;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for reading log content from the http request
|
* Utility class for reading log content from the http request
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api;
|
namespace IndifferentKetchup\Iblogs\Api;
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
|
|
||||||
class LogContentParser extends ContentParser
|
class LogContentParser extends ContentParser
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Response;
|
namespace IndifferentKetchup\Iblogs\Api\Response;
|
||||||
|
|
||||||
class ApiError extends ApiResponse
|
class ApiError extends ApiResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Response;
|
namespace IndifferentKetchup\Iblogs\Api\Response;
|
||||||
|
|
||||||
class ApiResponse implements \JsonSerializable
|
class ApiResponse implements \JsonSerializable
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Response;
|
namespace IndifferentKetchup\Iblogs\Api\Response;
|
||||||
|
|
||||||
use Aternos\Codex\Log\LogInterface;
|
use IndifferentKetchup\Codex\Log\LogInterface;
|
||||||
|
|
||||||
class CodexLogResponse extends ApiResponse
|
class CodexLogResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Response;
|
namespace IndifferentKetchup\Iblogs\Api\Response;
|
||||||
|
|
||||||
use Aternos\Mclogs\Filter\Filter;
|
use IndifferentKetchup\Iblogs\Filter\Filter;
|
||||||
|
|
||||||
class FiltersResponse extends ApiResponse
|
class FiltersResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Response;
|
namespace IndifferentKetchup\Iblogs\Api\Response;
|
||||||
|
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
|
|
||||||
class LimitsResponse extends ApiResponse
|
class LimitsResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Response;
|
namespace IndifferentKetchup\Iblogs\Api\Response;
|
||||||
|
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
class LogResponse extends ApiResponse
|
class LogResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Response;
|
namespace IndifferentKetchup\Iblogs\Api\Response;
|
||||||
|
|
||||||
class MultiResponse extends ApiResponse
|
class MultiResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Api\Response;
|
namespace IndifferentKetchup\Iblogs\Api\Response;
|
||||||
|
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
|
|
||||||
class RawLogResponse extends ApiResponse
|
class RawLogResponse extends ApiResponse
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Cache;
|
namespace IndifferentKetchup\Iblogs\Cache;
|
||||||
|
|
||||||
use Aternos\Mclogs\Storage\MongoDBClient;
|
use IndifferentKetchup\Iblogs\Storage\MongoDBClient;
|
||||||
use MongoDB\BSON\UTCDateTime;
|
use MongoDB\BSON\UTCDateTime;
|
||||||
|
|
||||||
class CacheEntry
|
class CacheEntry
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Config;
|
namespace IndifferentKetchup\Iblogs\Config;
|
||||||
|
|
||||||
use Aternos\Mclogs\Util\Singleton;
|
use IndifferentKetchup\Iblogs\Util\Singleton;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
class Config
|
class Config
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Config;
|
namespace IndifferentKetchup\Iblogs\Config;
|
||||||
|
|
||||||
enum ConfigKey
|
enum ConfigKey
|
||||||
{
|
{
|
||||||
@@ -40,7 +40,7 @@ enum ConfigKey
|
|||||||
ConfigKey::STORAGE_LIMIT_LINES => 25000,
|
ConfigKey::STORAGE_LIMIT_LINES => 25000,
|
||||||
|
|
||||||
ConfigKey::MONGODB_URL => 'mongodb://mongo:27017',
|
ConfigKey::MONGODB_URL => 'mongodb://mongo:27017',
|
||||||
ConfigKey::MONGODB_DATABASE => 'mclogs',
|
ConfigKey::MONGODB_DATABASE => 'iblogs',
|
||||||
|
|
||||||
ConfigKey::ID_LENGTH => 7,
|
ConfigKey::ID_LENGTH => 7,
|
||||||
|
|
||||||
@@ -66,7 +66,7 @@ enum ConfigKey
|
|||||||
*/
|
*/
|
||||||
public function getEnvironmentVariable(): string
|
public function getEnvironmentVariable(): string
|
||||||
{
|
{
|
||||||
return "MCLOGS_" . $this->name;
|
return "IBLOGS_" . $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,28 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Data;
|
namespace IndifferentKetchup\Iblogs\Data;
|
||||||
|
|
||||||
use Aternos\Codex\Analysis\Information;
|
use IndifferentKetchup\Codex\Log\LogInterface;
|
||||||
use Aternos\Codex\Log\AnalysableLog;
|
|
||||||
use Aternos\Codex\Log\LogInterface;
|
|
||||||
use Aternos\Codex\Minecraft\Analysis\Information\Vanilla\VanillaVersionInformation;
|
|
||||||
use Aternos\Codex\Minecraft\Log\Minecraft\Vanilla\Fabric\FabricLog;
|
|
||||||
use Aternos\Codex\Minecraft\Log\Minecraft\Vanilla\VanillaClientLog;
|
|
||||||
use Aternos\Codex\Minecraft\Log\Minecraft\Vanilla\VanillaCrashReportLog;
|
|
||||||
use Aternos\Codex\Minecraft\Log\Minecraft\Vanilla\VanillaLog;
|
|
||||||
use Aternos\Codex\Minecraft\Log\Minecraft\Vanilla\VanillaNetworkProtocolErrorReportLog;
|
|
||||||
use Aternos\Codex\Minecraft\Log\Minecraft\Vanilla\VanillaServerLog;
|
|
||||||
use Aternos\Mclogs\Cache\CacheEntry;
|
|
||||||
use Aternos\Sherlock\MapLocator\FabricMavenMapLocator;
|
|
||||||
use Aternos\Sherlock\MapLocator\LauncherMetaMapLocator;
|
|
||||||
use Aternos\Sherlock\Maps\GZURLYarnMap;
|
|
||||||
use Aternos\Sherlock\Maps\ObfuscationMap;
|
|
||||||
use Aternos\Sherlock\Maps\URLVanillaObfuscationMap;
|
|
||||||
use Aternos\Sherlock\Maps\VanillaObfuscationMap;
|
|
||||||
use Aternos\Sherlock\Maps\YarnMap;
|
|
||||||
use Aternos\Sherlock\ObfuscatedString;
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stub for v1 — `mclogs` used `aternos/sherlock` plus the Vanilla / Fabric
|
||||||
|
* Minecraft codex log subclasses to deobfuscate Mojang and Yarn mappings
|
||||||
|
* in stack traces. iblogs targets Project Zomboid, which uses no such
|
||||||
|
* mapping scheme, so the deobfuscator is a no-op until iblogs gains
|
||||||
|
* Minecraft support.
|
||||||
|
*
|
||||||
|
* Restore the original mapping flow (Sherlock map locators + obfuscation
|
||||||
|
* maps) when re-introducing Minecraft logs. The historical implementation
|
||||||
|
* lives in mclogs upstream commits prior to the iblogs fork.
|
||||||
|
*/
|
||||||
class Deobfuscator
|
class Deobfuscator
|
||||||
{
|
{
|
||||||
public function __construct(protected LogInterface $codexLog)
|
public function __construct(protected LogInterface $codexLog)
|
||||||
@@ -31,108 +23,6 @@ class Deobfuscator
|
|||||||
|
|
||||||
public function deobfuscate(): ?string
|
public function deobfuscate(): ?string
|
||||||
{
|
{
|
||||||
if (!$this->codexLog instanceof AnalysableLog) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
if (!$this->codexLog instanceof VanillaLog) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$analysis = $this->codexLog->analyse();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var ?Information $version
|
|
||||||
*/
|
|
||||||
$version = $analysis->getFilteredInsights(VanillaVersionInformation::class)[0] ?? null;
|
|
||||||
if (!$version) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
$version = $version->getValue();
|
|
||||||
|
|
||||||
try {
|
|
||||||
$map = $this->getObfuscationMap($version);
|
|
||||||
} catch (Exception) {
|
|
||||||
$map = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($map === null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$obfuscatedContent = new ObfuscatedString($this->codexLog->getLogFile()->getContent(), $map);
|
|
||||||
if ($content = $obfuscatedContent->getMappedContent()) {
|
|
||||||
return $content;
|
|
||||||
}
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Get the obfuscation map matching this log
|
|
||||||
*
|
|
||||||
* @param $version
|
|
||||||
* @return ObfuscationMap|null
|
|
||||||
* @throws Exception
|
|
||||||
*/
|
|
||||||
protected function getObfuscationMap($version): ?ObfuscationMap
|
|
||||||
{
|
|
||||||
if (in_array(get_class($this->codexLog), [
|
|
||||||
VanillaServerLog::class,
|
|
||||||
VanillaClientLog::class,
|
|
||||||
VanillaCrashReportLog::class,
|
|
||||||
VanillaNetworkProtocolErrorReportLog::class
|
|
||||||
])) {
|
|
||||||
$urlCache = new CacheEntry("sherlock:vanilla:$version:client");
|
|
||||||
|
|
||||||
$mapURL = $urlCache->get();
|
|
||||||
if (!$mapURL) {
|
|
||||||
$mapURL = new LauncherMetaMapLocator($version, "client")->findMappingURL();
|
|
||||||
|
|
||||||
if (!$mapURL) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$urlCache->set($mapURL, 30 * 24 * 60 * 60);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$mapCache = new CacheEntry("sherlock:$mapURL");
|
|
||||||
if ($mapContent = $mapCache->get()) {
|
|
||||||
$map = new VanillaObfuscationMap($mapContent);
|
|
||||||
} else {
|
|
||||||
$map = new URLVanillaObfuscationMap($mapURL);
|
|
||||||
$mapCache->set($map->getContent());
|
|
||||||
}
|
|
||||||
} catch (Exception) {
|
|
||||||
}
|
|
||||||
return $map ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->codexLog instanceof FabricLog) {
|
|
||||||
$urlCache = new CacheEntry("sherlock:yarn:$version:server");
|
|
||||||
|
|
||||||
$mapURL = $urlCache->get();
|
|
||||||
if (!$mapURL) {
|
|
||||||
$mapURL = new FabricMavenMapLocator($version)->findMappingURL();
|
|
||||||
|
|
||||||
if (!$mapURL) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
$urlCache->set($mapURL, 24 * 60 * 60);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
$mapCache = new CacheEntry("sherlock:$mapURL");
|
|
||||||
if ($mapContent = $mapCache->get()) {
|
|
||||||
$map = new YarnMap($mapContent);
|
|
||||||
} else {
|
|
||||||
$map = new GZURLYarnMap($mapURL);
|
|
||||||
$mapCache->set($map->getContent());
|
|
||||||
}
|
|
||||||
} catch (Exception) {
|
|
||||||
}
|
|
||||||
return $map ?? null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Data;
|
namespace IndifferentKetchup\Iblogs\Data;
|
||||||
|
|
||||||
use MongoDB\BSON\Serializable;
|
use MongoDB\BSON\Serializable;
|
||||||
use MongoDB\Model\BSONDocument;
|
use MongoDB\Model\BSONDocument;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Data;
|
namespace IndifferentKetchup\Iblogs\Data;
|
||||||
|
|
||||||
use Random\RandomException;
|
use Random\RandomException;
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs;
|
namespace IndifferentKetchup\Iblogs;
|
||||||
|
|
||||||
use Aternos\Codex\Minecraft\Log\Minecraft\MinecraftLog;
|
use IndifferentKetchup\Codex\Detective\ProjectZomboid\ProjectZomboidDetective;
|
||||||
|
|
||||||
class Detective extends \Aternos\Codex\Detective\Detective
|
class Detective extends \IndifferentKetchup\Codex\Detective\Detective
|
||||||
{
|
{
|
||||||
protected string $defaultLogClass = MinecraftLog::class;
|
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
$this->addDetective(new \Aternos\Codex\Minecraft\Detective\Detective())
|
$this->addDetective(new ProjectZomboidDetective());
|
||||||
->addDetective(new \Aternos\Codex\Hytale\Detective\Detective());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter;
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
use Aternos\Mclogs\Filter\Pattern\PatternWithReplacement;
|
use IndifferentKetchup\Iblogs\Filter\Pattern\PatternWithReplacement;
|
||||||
|
|
||||||
class AccessTokenFilter extends RegexFilter
|
class AccessTokenFilter extends RegexFilter
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter;
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
abstract class Filter implements \JsonSerializable
|
abstract class Filter implements \JsonSerializable
|
||||||
{
|
{
|
||||||
@@ -23,8 +23,7 @@ abstract class Filter implements \JsonSerializable
|
|||||||
new TrimFilter(),
|
new TrimFilter(),
|
||||||
new LimitBytesFilter(),
|
new LimitBytesFilter(),
|
||||||
new LimitLinesFilter(),
|
new LimitLinesFilter(),
|
||||||
new IPv4Filter(),
|
new ProjectZomboidRedactorFilter(),
|
||||||
new IPv6Filter(),
|
|
||||||
new UsernameFilter(),
|
new UsernameFilter(),
|
||||||
new AccessTokenFilter(),
|
new AccessTokenFilter(),
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter;
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
enum FilterType: string
|
enum FilterType: string
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter;
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
use Aternos\Mclogs\Filter\Pattern\Pattern;
|
use IndifferentKetchup\Iblogs\Filter\Pattern\Pattern;
|
||||||
use Aternos\Mclogs\Filter\Pattern\PatternWithReplacement;
|
use IndifferentKetchup\Iblogs\Filter\Pattern\PatternWithReplacement;
|
||||||
|
|
||||||
class IPv4Filter extends RegexFilter
|
class IPv4Filter extends RegexFilter
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter;
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
use Aternos\Mclogs\Filter\Pattern\Pattern;
|
use IndifferentKetchup\Iblogs\Filter\Pattern\Pattern;
|
||||||
use Aternos\Mclogs\Filter\Pattern\PatternWithReplacement;
|
use IndifferentKetchup\Iblogs\Filter\Pattern\PatternWithReplacement;
|
||||||
|
|
||||||
class IPv6Filter extends RegexFilter
|
class IPv6Filter extends RegexFilter
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter;
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
|
|
||||||
class LimitBytesFilter extends Filter
|
class LimitBytesFilter extends Filter
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter;
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
|
|
||||||
class LimitLinesFilter extends Filter
|
class LimitLinesFilter extends Filter
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter\Pattern;
|
namespace IndifferentKetchup\Iblogs\Filter\Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
|
* https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter\Pattern;
|
namespace IndifferentKetchup\Iblogs\Filter\Pattern;
|
||||||
|
|
||||||
class Pattern implements \JsonSerializable
|
class Pattern implements \JsonSerializable
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter\Pattern;
|
namespace IndifferentKetchup\Iblogs\Filter\Pattern;
|
||||||
|
|
||||||
class PatternWithReplacement extends Pattern
|
class PatternWithReplacement extends Pattern
|
||||||
{
|
{
|
||||||
|
|||||||
45
src/Filter/ProjectZomboidRedactorFilter.php
Normal file
45
src/Filter/ProjectZomboidRedactorFilter.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
|
use IndifferentKetchup\Codex\Util\ProjectZomboid\ProjectZomboidRedactor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save-time wrapper that delegates to codex's ProjectZomboidRedactor.
|
||||||
|
*
|
||||||
|
* Codex owns the canonical Project Zomboid PII patterns (Steam IDs, player
|
||||||
|
* names, world coordinates, plus IPv4 / IPv6 addresses with the v0.3.0
|
||||||
|
* release). This filter is the single point at which PZ-shaped PII is
|
||||||
|
* scrubbed on save; it replaces the previous IPv4Filter + IPv6Filter
|
||||||
|
* stage (whose IP-only matches left port suffixes intact) and adds the
|
||||||
|
* PZ-specific Steam ID, player-name, and coordinate redaction the generic
|
||||||
|
* filters never touched.
|
||||||
|
*
|
||||||
|
* Codex's IPv4 / IPv6 regexes are generic and apply to non-PZ pastes too;
|
||||||
|
* the PZ-specific regexes (Steam ID, player name, coords) mostly no-op on
|
||||||
|
* non-PZ content because they rely on PZ-specific anchors (`76561198`,
|
||||||
|
* the Steam-ID placeholder, `Combat:` / `Safety:` prefixes, `at` / `[`
|
||||||
|
* coord wrappers + trailing PvP verbs).
|
||||||
|
*
|
||||||
|
* Patterns are encapsulated inside the codex redactor and are not exposed
|
||||||
|
* to the client-side preview JS (`getData()` returns an empty array).
|
||||||
|
* Server-side redaction on save is the privacy guarantee; the preview is
|
||||||
|
* only a UX hint for users about what gets scrubbed.
|
||||||
|
*/
|
||||||
|
class ProjectZomboidRedactorFilter extends Filter
|
||||||
|
{
|
||||||
|
public function getType(): FilterType
|
||||||
|
{
|
||||||
|
return FilterType::REGEX;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getData(): array
|
||||||
|
{
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function filter(string $data): string
|
||||||
|
{
|
||||||
|
return new ProjectZomboidRedactor()->redact($data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter;
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
use Aternos\Mclogs\Filter\Pattern\Pattern;
|
use IndifferentKetchup\Iblogs\Filter\Pattern\Pattern;
|
||||||
use Aternos\Mclogs\Filter\Pattern\PatternWithReplacement;
|
use IndifferentKetchup\Iblogs\Filter\Pattern\PatternWithReplacement;
|
||||||
|
|
||||||
abstract class RegexFilter extends Filter
|
abstract class RegexFilter extends Filter
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter;
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
class TrimFilter extends Filter
|
class TrimFilter extends Filter
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Filter;
|
namespace IndifferentKetchup\Iblogs\Filter;
|
||||||
|
|
||||||
use Aternos\Mclogs\Filter\Pattern\PatternWithReplacement;
|
use IndifferentKetchup\Iblogs\Filter\Pattern\PatternWithReplacement;
|
||||||
|
|
||||||
class UsernameFilter extends RegexFilter
|
class UsernameFilter extends RegexFilter
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Action;
|
namespace IndifferentKetchup\Iblogs\Frontend\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Router\Action;
|
use IndifferentKetchup\Iblogs\Router\Action;
|
||||||
|
|
||||||
class ApiDocsAction extends Action
|
class ApiDocsAction extends Action
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Action;
|
namespace IndifferentKetchup\Iblogs\Frontend\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
class CreateLogAction extends \Aternos\Mclogs\Api\Action\CreateLogAction
|
class CreateLogAction extends \IndifferentKetchup\Iblogs\Api\Action\CreateLogAction
|
||||||
{
|
{
|
||||||
protected bool $includeCookie = true;
|
protected bool $includeCookie = true;
|
||||||
protected bool $includeToken = false;
|
protected bool $includeToken = false;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Action;
|
namespace IndifferentKetchup\Iblogs\Frontend\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Frontend\Cookie\TokenCookie;
|
use IndifferentKetchup\Iblogs\Frontend\Cookie\TokenCookie;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
class DeleteLogAction extends \Aternos\Mclogs\Api\Action\DeleteLogAction
|
class DeleteLogAction extends \IndifferentKetchup\Iblogs\Api\Action\DeleteLogAction
|
||||||
{
|
{
|
||||||
protected function getAllowedOrigin(): string
|
protected function getAllowedOrigin(): string
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Action;
|
namespace IndifferentKetchup\Iblogs\Frontend\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Router\Action;
|
use IndifferentKetchup\Iblogs\Router\Action;
|
||||||
|
|
||||||
class FaviconAction extends Action
|
class FaviconAction extends Action
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Action;
|
namespace IndifferentKetchup\Iblogs\Frontend\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Router\Action;
|
use IndifferentKetchup\Iblogs\Router\Action;
|
||||||
|
|
||||||
class NotFoundAction extends Action
|
class NotFoundAction extends Action
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Action;
|
namespace IndifferentKetchup\Iblogs\Frontend\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Router\Action;
|
use IndifferentKetchup\Iblogs\Router\Action;
|
||||||
|
|
||||||
class StartAction extends Action
|
class StartAction extends Action
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Action;
|
namespace IndifferentKetchup\Iblogs\Frontend\Action;
|
||||||
|
|
||||||
use Aternos\Mclogs\Id;
|
use IndifferentKetchup\Iblogs\Id;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
use Aternos\Mclogs\Router\Action;
|
use IndifferentKetchup\Iblogs\Router\Action;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
class ViewLogAction extends Action
|
class ViewLogAction extends Action
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Assets;
|
namespace IndifferentKetchup\Iblogs\Frontend\Assets;
|
||||||
|
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
|
|
||||||
class Asset implements \JsonSerializable
|
class Asset implements \JsonSerializable
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Assets;
|
namespace IndifferentKetchup\Iblogs\Frontend\Assets;
|
||||||
|
|
||||||
use Aternos\Mclogs\Util\Singleton;
|
use IndifferentKetchup\Iblogs\Util\Singleton;
|
||||||
|
|
||||||
class AssetLoader
|
class AssetLoader
|
||||||
{
|
{
|
||||||
@@ -90,7 +90,7 @@ class AssetLoader
|
|||||||
public function writeCache(): void
|
public function writeCache(): void
|
||||||
{
|
{
|
||||||
$assets = [
|
$assets = [
|
||||||
new Asset(AssetType::CSS, "css/mclogs.css"),
|
new Asset(AssetType::CSS, "css/iblogs.css"),
|
||||||
new Asset(AssetType::JS, "js/start.js"),
|
new Asset(AssetType::JS, "js/start.js"),
|
||||||
new Asset(AssetType::JS, "js/log.js"),
|
new Asset(AssetType::JS, "js/log.js"),
|
||||||
new Asset(AssetType::CSS, "vendor/fontawesome/css/fontawesome.min.css")
|
new Asset(AssetType::CSS, "vendor/fontawesome/css/fontawesome.min.css")
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Assets;
|
namespace IndifferentKetchup\Iblogs\Frontend\Assets;
|
||||||
|
|
||||||
enum AssetType: string
|
enum AssetType: string
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Cookie;
|
namespace IndifferentKetchup\Iblogs\Frontend\Cookie;
|
||||||
|
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
abstract class Cookie
|
abstract class Cookie
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Cookie;
|
namespace IndifferentKetchup\Iblogs\Frontend\Cookie;
|
||||||
|
|
||||||
class SettingsCookie extends Cookie
|
class SettingsCookie extends Cookie
|
||||||
{
|
{
|
||||||
@@ -9,6 +9,6 @@ class SettingsCookie extends Cookie
|
|||||||
*/
|
*/
|
||||||
protected function getKey(): string
|
protected function getKey(): string
|
||||||
{
|
{
|
||||||
return "MCLOGS_SETTINGS";
|
return "IBLOGS_SETTINGS";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Cookie;
|
namespace IndifferentKetchup\Iblogs\Frontend\Cookie;
|
||||||
|
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
|
|
||||||
class TokenCookie extends Cookie
|
class TokenCookie extends Cookie
|
||||||
{
|
{
|
||||||
@@ -23,7 +23,7 @@ class TokenCookie extends Cookie
|
|||||||
*/
|
*/
|
||||||
protected function getKey(): string
|
protected function getKey(): string
|
||||||
{
|
{
|
||||||
return "MCLOGS_LOG_TOKEN";
|
return "IBLOGS_LOG_TOKEN";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend;
|
namespace IndifferentKetchup\Iblogs\Frontend;
|
||||||
|
|
||||||
use Aternos\Mclogs\Router\Router;
|
use IndifferentKetchup\Iblogs\Router\Router;
|
||||||
use Aternos\Mclogs\Id;
|
use IndifferentKetchup\Iblogs\Id;
|
||||||
use Aternos\Mclogs\Router\Method;
|
use IndifferentKetchup\Iblogs\Router\Method;
|
||||||
|
|
||||||
class FrontendRouter extends Router
|
class FrontendRouter extends Router
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Settings;
|
namespace IndifferentKetchup\Iblogs\Frontend\Settings;
|
||||||
|
|
||||||
enum Setting: string
|
enum Setting: string
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Frontend\Settings;
|
namespace IndifferentKetchup\Iblogs\Frontend\Settings;
|
||||||
|
|
||||||
use Aternos\Mclogs\Frontend\Cookie\SettingsCookie;
|
use IndifferentKetchup\Iblogs\Frontend\Cookie\SettingsCookie;
|
||||||
|
|
||||||
class Settings
|
class Settings
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs;
|
namespace IndifferentKetchup\Iblogs;
|
||||||
|
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
|
|
||||||
class Id implements \JsonSerializable
|
class Id implements \JsonSerializable
|
||||||
{
|
{
|
||||||
@@ -26,7 +26,7 @@ class Id implements \JsonSerializable
|
|||||||
*/
|
*/
|
||||||
protected function generate(): string
|
protected function generate(): string
|
||||||
{
|
{
|
||||||
$config = \Aternos\Mclogs\Config\Config::getInstance();
|
$config = \IndifferentKetchup\Iblogs\Config\Config::getInstance();
|
||||||
$idLength = $config->get(ConfigKey::ID_LENGTH);
|
$idLength = $config->get(ConfigKey::ID_LENGTH);
|
||||||
|
|
||||||
$newId = "";
|
$newId = "";
|
||||||
|
|||||||
32
src/Log.php
32
src/Log.php
@@ -1,21 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs;
|
namespace IndifferentKetchup\Iblogs;
|
||||||
|
|
||||||
use Aternos\Codex\Analysis\Analysis;
|
use IndifferentKetchup\Codex\Analysis\Analysis;
|
||||||
use Aternos\Codex\Log\AnalysableLogInterface;
|
use IndifferentKetchup\Codex\Log\AnalysableLogInterface;
|
||||||
use Aternos\Codex\Log\File\StringLogFile;
|
use IndifferentKetchup\Codex\Log\File\StringLogFile;
|
||||||
use Aternos\Codex\Log\Level;
|
use IndifferentKetchup\Codex\Log\Level;
|
||||||
use Aternos\Codex\Log\LogInterface;
|
use IndifferentKetchup\Codex\Log\LogInterface;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
use Aternos\Mclogs\Data\Deobfuscator;
|
use IndifferentKetchup\Iblogs\Data\Deobfuscator;
|
||||||
use Aternos\Mclogs\Data\MetadataEntry;
|
use IndifferentKetchup\Iblogs\Data\MetadataEntry;
|
||||||
use Aternos\Mclogs\Data\Token;
|
use IndifferentKetchup\Iblogs\Data\Token;
|
||||||
use Aternos\Mclogs\Filter\Filter;
|
use IndifferentKetchup\Iblogs\Filter\Filter;
|
||||||
use Aternos\Mclogs\Frontend\Cookie\TokenCookie;
|
use IndifferentKetchup\Iblogs\Frontend\Cookie\TokenCookie;
|
||||||
use Aternos\Mclogs\Printer\Printer;
|
use IndifferentKetchup\Iblogs\Printer\Printer;
|
||||||
use Aternos\Mclogs\Storage\MongoDBClient;
|
use IndifferentKetchup\Iblogs\Storage\MongoDBClient;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
use MongoDB\BSON\UTCDateTime;
|
use MongoDB\BSON\UTCDateTime;
|
||||||
use Uri\Rfc3986\Uri;
|
use Uri\Rfc3986\Uri;
|
||||||
|
|
||||||
@@ -371,7 +371,7 @@ class Log
|
|||||||
*/
|
*/
|
||||||
protected function getExpiryTimestamp(): UTCDateTime
|
protected function getExpiryTimestamp(): UTCDateTime
|
||||||
{
|
{
|
||||||
$ttl = \Aternos\Mclogs\Config\Config::getInstance()->get(ConfigKey::STORAGE_TTL);
|
$ttl = \IndifferentKetchup\Iblogs\Config\Config::getInstance()->get(ConfigKey::STORAGE_TTL);
|
||||||
$expires = time() + $ttl;
|
$expires = time() + $ttl;
|
||||||
return new UTCDateTime($expires * 1000);
|
return new UTCDateTime($expires * 1000);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Printer;
|
namespace IndifferentKetchup\Iblogs\Printer;
|
||||||
|
|
||||||
|
use IndifferentKetchup\Codex\Printer\Modification;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class FormatModification
|
* Stub for v1 — `mclogs` extended `Aternos\Codex\Minecraft\Printer\FormatModification`
|
||||||
|
* to translate Minecraft section-sign format codes into HTML format spans
|
||||||
|
* (`format-black`, `format-darkblue`, etc., backed by the format-colors block
|
||||||
|
* in the iblogs CSS). Project Zomboid logs do not carry these codes, so this
|
||||||
|
* Modification is a pass-through under iblogs.
|
||||||
*
|
*
|
||||||
* @package Printer
|
* The CSS `format-*` color classes are retained so re-introducing a real
|
||||||
|
* Minecraft FormatModification later (or any other game with its own
|
||||||
|
* format-code scheme) can reuse the existing styling.
|
||||||
*/
|
*/
|
||||||
class FormatModification extends \Aternos\Codex\Minecraft\Printer\FormatModification
|
class FormatModification extends Modification
|
||||||
{
|
{
|
||||||
/**
|
public function modify(string $text): string
|
||||||
* @param string $format
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function getClasses(string $format): string
|
|
||||||
{
|
{
|
||||||
return "format format-" . $format;
|
return $text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Printer;
|
namespace IndifferentKetchup\Iblogs\Printer;
|
||||||
|
|
||||||
use Aternos\Codex\Log\Entry;
|
use IndifferentKetchup\Codex\Log\Entry;
|
||||||
use Aternos\Codex\Log\EntryInterface;
|
use IndifferentKetchup\Codex\Log\EntryInterface;
|
||||||
use Aternos\Codex\Log\Level;
|
use IndifferentKetchup\Codex\Log\Level;
|
||||||
use Aternos\Codex\Log\LineInterface;
|
use IndifferentKetchup\Codex\Log\LineInterface;
|
||||||
use Aternos\Codex\Printer\ModifiableDefaultPrinter;
|
use IndifferentKetchup\Codex\Printer\ModifiableDefaultPrinter;
|
||||||
use Aternos\Mclogs\Id;
|
use IndifferentKetchup\Iblogs\Id;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class Printer
|
* Class Printer
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Router;
|
namespace IndifferentKetchup\Iblogs\Router;
|
||||||
|
|
||||||
abstract class Action
|
abstract class Action
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Router;
|
namespace IndifferentKetchup\Iblogs\Router;
|
||||||
|
|
||||||
enum Method: string
|
enum Method: string
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Router;
|
namespace IndifferentKetchup\Iblogs\Router;
|
||||||
|
|
||||||
class Route
|
class Route
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Router;
|
namespace IndifferentKetchup\Iblogs\Router;
|
||||||
|
|
||||||
use Aternos\Mclogs\Util\Singleton;
|
use IndifferentKetchup\Iblogs\Util\Singleton;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
class Router
|
class Router
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Storage;
|
namespace IndifferentKetchup\Iblogs\Storage;
|
||||||
|
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
use Aternos\Mclogs\Util\Singleton;
|
use IndifferentKetchup\Iblogs\Util\Singleton;
|
||||||
use MongoDB\BSON\UTCDateTime;
|
use MongoDB\BSON\UTCDateTime;
|
||||||
use MongoDB\Client;
|
use MongoDB\Client;
|
||||||
use MongoDB\Collection;
|
use MongoDB\Collection;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Util;
|
namespace IndifferentKetchup\Iblogs\Util;
|
||||||
|
|
||||||
trait Singleton
|
trait Singleton
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Util;
|
namespace IndifferentKetchup\Iblogs\Util;
|
||||||
|
|
||||||
class TimeInterval
|
class TimeInterval
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Aternos\Mclogs\Util;
|
namespace IndifferentKetchup\Iblogs\Util;
|
||||||
|
|
||||||
use Uri\Rfc3986\Uri;
|
use Uri\Rfc3986\Uri;
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\Action\BulkDeleteLogsAction;
|
use IndifferentKetchup\Iblogs\Api\Action\BulkDeleteLogsAction;
|
||||||
use Aternos\Mclogs\Api\Response\ApiError;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiError;
|
||||||
use Aternos\Mclogs\Api\Response\ApiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\ApiResponse;
|
||||||
use Aternos\Mclogs\Api\Response\MultiResponse;
|
use IndifferentKetchup\Iblogs\Api\Response\MultiResponse;
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
$config = Config::getInstance();
|
$config = Config::getInstance();
|
||||||
?>
|
?>
|
||||||
@@ -433,8 +433,8 @@ $config = Config::getInstance();
|
|||||||
{
|
{
|
||||||
"message": "Label: value",
|
"message": "Label: value",
|
||||||
"counter": 1,
|
"counter": 1,
|
||||||
"label": "The label of this information, e.g. Minecraft version",
|
"label": "The label of this information, e.g. Engine version",
|
||||||
"value": "The value of this information, e.g. 1.12.2",
|
"value": "The value of this information, e.g. 42.16.3",
|
||||||
"entry": {
|
"entry": {
|
||||||
"level": 6,
|
"level": 6,
|
||||||
"time": null,
|
"time": null,
|
||||||
@@ -515,8 +515,8 @@ $config = Config::getInstance();
|
|||||||
{
|
{
|
||||||
"message": "Label: value",
|
"message": "Label: value",
|
||||||
"counter": 1,
|
"counter": 1,
|
||||||
"label": "The label of this information, e.g. Minecraft version",
|
"label": "The label of this information, e.g. Engine version",
|
||||||
"value": "The value of this information, e.g. 1.12.2",
|
"value": "The value of this information, e.g. 42.16.3",
|
||||||
"entry": {
|
"entry": {
|
||||||
"level": 6,
|
"level": 6,
|
||||||
"time": null,
|
"time": null,
|
||||||
@@ -586,7 +586,7 @@ $config = Config::getInstance();
|
|||||||
</div>
|
</div>
|
||||||
<h3>Success <span class="content-type">application/json</span></h3>
|
<h3>Success <span class="content-type">application/json</span></h3>
|
||||||
<pre class="api-code">
|
<pre class="api-code">
|
||||||
<?=htmlspecialchars(json_encode(\Aternos\Mclogs\Filter\Filter::getAll(), JSON_PRETTY_PRINT)); ?></pre>
|
<?=htmlspecialchars(json_encode(\IndifferentKetchup\Iblogs\Filter\Filter::getAll(), JSON_PRETTY_PRINT)); ?></pre>
|
||||||
<h3>Filter types</h3>
|
<h3>Filter types</h3>
|
||||||
<table class="api-table">
|
<table class="api-table">
|
||||||
<tr>
|
<tr>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Aternos\Mclogs\Frontend\Assets\AssetLoader;
|
use IndifferentKetchup\Iblogs\Frontend\Assets\AssetLoader;
|
||||||
use Aternos\Mclogs\Frontend\Assets\AssetType;
|
use IndifferentKetchup\Iblogs\Frontend\Assets\AssetType;
|
||||||
use Aternos\Mclogs\Log;
|
use IndifferentKetchup\Iblogs\Log;
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
use Aternos\Mclogs\Frontend\Settings\Setting;
|
use IndifferentKetchup\Iblogs\Frontend\Settings\Setting;
|
||||||
use Aternos\Mclogs\Frontend\Settings\Settings;
|
use IndifferentKetchup\Iblogs\Frontend\Settings\Settings;
|
||||||
use Aternos\Mclogs\Util\TimeInterval;
|
use IndifferentKetchup\Iblogs\Util\TimeInterval;
|
||||||
|
|
||||||
/** @var Log $log */
|
/** @var Log $log */
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<svg width="41" height="42" viewBox="0 0 41 42" fill="<?=htmlspecialchars(\Aternos\Mclogs\Config\Config::getInstance()->get(\Aternos\Mclogs\Config\ConfigKey::FRONTEND_COLOR_ACCENT)); ?>" xmlns="http://www.w3.org/2000/svg">
|
<svg width="41" height="42" viewBox="0 0 41 42" fill="<?=htmlspecialchars(\IndifferentKetchup\Iblogs\Config\Config::getInstance()->get(\IndifferentKetchup\Iblogs\Config\ConfigKey::FRONTEND_COLOR_ACCENT)); ?>" xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect width="41" height="5" rx="2"/>
|
<rect width="41" height="5" rx="2"/>
|
||||||
<rect y="9.25" width="33" height="5" rx="2"/>
|
<rect y="9.25" width="33" height="5" rx="2"/>
|
||||||
<rect y="18.5" width="19" height="5" rx="2"/>
|
<rect y="18.5" width="19" height="5" rx="2"/>
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 470 B After Width: | Height: | Size: 492 B |
@@ -1,5 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
use Aternos\Mclogs\Config\Config;use Aternos\Mclogs\Config\ConfigKey;use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Config\Config;use IndifferentKetchup\Iblogs\Config\ConfigKey;use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
$imprintUrl = Config::getInstance()->get(ConfigKey::LEGAL_IMPRINT);
|
$imprintUrl = Config::getInstance()->get(ConfigKey::LEGAL_IMPRINT);
|
||||||
$privacyUrl = Config::getInstance()->get(ConfigKey::LEGAL_PRIVACY);
|
$privacyUrl = Config::getInstance()->get(ConfigKey::LEGAL_PRIVACY);
|
||||||
@@ -19,10 +19,9 @@ $privacyUrl = Config::getInstance()->get(ConfigKey::LEGAL_PRIVACY);
|
|||||||
</nav>
|
</nav>
|
||||||
<?php endif; ?>
|
<?php endif; ?>
|
||||||
<nav class="footer-nav">
|
<nav class="footer-nav">
|
||||||
<a href="https://github.com/aternosorg/mclogs" title="mclo.gs on Github" target="_blank"><i class="fa-brands fa-github"></i>GitHub</a>
|
<a href="https://github.com/indifferentketchup/iblogs" title="iblogs on Github" target="_blank"><i class="fa-brands fa-github"></i>GitHub</a>
|
||||||
<a href="https://modrinth.com/plugin/mclogs" title="Download mclo.gs Mod/Plugin" target="_blank"><i class="fa-solid fa-cube"></i>Mod/Plugin</a>
|
<a href="<?=htmlspecialchars(URL::getApi()->toString()); ?>" title="iblogs API"><i class="fa-solid fa-code"></i>API</a>
|
||||||
<a href="<?=htmlspecialchars(URL::getApi()->toString()); ?>" title="mclo.gs API"><i class="fa-solid fa-code"></i>API</a>
|
|
||||||
</nav>
|
</nav>
|
||||||
<span class="footer-text">developed by <a href="https://aternos.org" target="_blank" title="Aternos website">Aternos</a>
|
<span class="footer-text">based on <a href="https://github.com/aternosorg/mclogs" target="_blank" title="Original mclogs project">mclogs</a> by <a href="https://github.com/aternosorg" target="_blank" title="Aternos on GitHub"><i class="fa-brands fa-github"></i> Aternos</a>
|
||||||
</span>
|
</span>
|
||||||
</footer>
|
</footer>
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
use Aternos\Mclogs\Frontend\Assets\AssetLoader;
|
use IndifferentKetchup\Iblogs\Frontend\Assets\AssetLoader;
|
||||||
use Aternos\Mclogs\Frontend\Assets\AssetType;
|
use IndifferentKetchup\Iblogs\Frontend\Assets\AssetType;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
?>
|
?>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
|
|
||||||
<base href="/"/>
|
<base href="/"/>
|
||||||
<?= AssetLoader::getInstance()->getHTML(AssetType::CSS, "vendor/fontawesome/css/fontawesome.min.css"); ?>
|
<?= AssetLoader::getInstance()->getHTML(AssetType::CSS, "vendor/fontawesome/css/fontawesome.min.css"); ?>
|
||||||
<?= AssetLoader::getInstance()->getHTML(AssetType::CSS, "css/mclogs.css"); ?>
|
<?= AssetLoader::getInstance()->getHTML(AssetType::CSS, "css/iblogs.css"); ?>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
:root {
|
:root {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<header>
|
<header>
|
||||||
<a href="<?=htmlspecialchars(\Aternos\Mclogs\Util\URL::getBase()->toString()); ?>" class="logo">
|
<a href="<?=htmlspecialchars(\IndifferentKetchup\Iblogs\Util\URL::getBase()->toString()); ?>" class="logo">
|
||||||
<svg class="logo-icon" width="41" height="42" viewBox="0 0 41 42" fill="none"
|
<svg class="logo-icon" width="41" height="42" viewBox="0 0 41 42" fill="none"
|
||||||
xmlns="http://www.w3.org/2000/svg">
|
xmlns="http://www.w3.org/2000/svg">
|
||||||
<rect width="41" height="5" rx="2" fill="currentColor"/>
|
<rect width="41" height="5" rx="2" fill="currentColor"/>
|
||||||
@@ -8,11 +8,11 @@
|
|||||||
<rect y="27.75" width="33" height="5" rx="2" fill="currentColor"/>
|
<rect y="27.75" width="33" height="5" rx="2" fill="currentColor"/>
|
||||||
<rect y="37" width="41" height="5" rx="2" fill="currentColor"/>
|
<rect y="37" width="41" height="5" rx="2" fill="currentColor"/>
|
||||||
</svg>
|
</svg>
|
||||||
<span class="logo-text"><?= htmlspecialchars(\Aternos\Mclogs\Config\Config::getInstance()->getName()); ?></span>
|
<span class="logo-text"><?= htmlspecialchars(\IndifferentKetchup\Iblogs\Config\Config::getInstance()->getName()); ?></span>
|
||||||
</a>
|
</a>
|
||||||
<div class="tagline">
|
<div class="tagline">
|
||||||
<h1 class="tagline-main"><span class="title-verb">Paste</span> your logs.</h1>
|
<h1 class="tagline-main"><span class="title-verb">Paste</span> your logs.</h1>
|
||||||
<div class="tagline-sub">Built for Minecraft & Hytale</div>
|
<div class="tagline-sub">Built for game-server logs</div>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
const titles = ["Paste", "Share", "Analyse"];
|
const titles = ["Paste", "Share", "Analyse"];
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Filter\Filter;
|
use IndifferentKetchup\Iblogs\Filter\Filter;
|
||||||
use Aternos\Mclogs\Frontend\Assets\AssetLoader;
|
use IndifferentKetchup\Iblogs\Frontend\Assets\AssetLoader;
|
||||||
use Aternos\Mclogs\Frontend\Assets\AssetType;
|
use IndifferentKetchup\Iblogs\Frontend\Assets\AssetType;
|
||||||
?><!DOCTYPE html>
|
?><!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<?php include __DIR__ . '/parts/head.php'; ?>
|
<?php include __DIR__ . '/parts/head.php'; ?>
|
||||||
<title><?= htmlspecialchars(Config::getInstance()->getName()); ?> - Paste, share & analyse your logs</title>
|
<title><?= htmlspecialchars(Config::getInstance()->getName()); ?> - Paste, share & analyse your logs</title>
|
||||||
<meta name="description" content="Easily paste your Minecraft & Hytale logs to share and analyse them." />
|
<meta name="description" content="Easily paste your game-server logs to share and analyse them." />
|
||||||
</head>
|
</head>
|
||||||
<body data-name="<?=htmlspecialchars(Config::getInstance()->getName()); ?>">
|
<body data-name="<?=htmlspecialchars(Config::getInstance()->getName()); ?>">
|
||||||
<?php include __DIR__ . '/parts/header.php'; ?>
|
<?php include __DIR__ . '/parts/header.php'; ?>
|
||||||
|
|||||||
@@ -950,6 +950,24 @@ main {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip layout / paint of off-screen log cells until they scroll into
|
||||||
|
* view. With logs running up to ~25 000 entries the eager render of
|
||||||
|
* every cell is what causes the multi-second freeze on initial load.
|
||||||
|
*
|
||||||
|
* `.entry` itself is `display: contents` (no box), so the rule has to
|
||||||
|
* land on the actual grid items it produces. `contain-intrinsic-size:
|
||||||
|
* auto 1.5em` lets the browser remember measured heights after first
|
||||||
|
* paint and falls back to ~one line tall as the placeholder for
|
||||||
|
* never-seen cells. Multi-line stack traces correct on first pass; the
|
||||||
|
* scroll position adjusts once.
|
||||||
|
*/
|
||||||
|
.log-inner .line-number-container,
|
||||||
|
.log-inner .line-content {
|
||||||
|
content-visibility: auto;
|
||||||
|
contain-intrinsic-size: auto 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
.log-inner .entry.entry-error .line-content,
|
.log-inner .entry.entry-error .line-content,
|
||||||
.log-inner .entry.entry-error .line-number-container{
|
.log-inner .entry.entry-error .line-number-container{
|
||||||
background-color: var(--error-bg);
|
background-color: var(--error-bg);
|
||||||
@@ -1088,6 +1106,82 @@ main {
|
|||||||
color: var(--accent);
|
color: var(--accent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Foldable variant — generated by the smart "errors + 25 context" toggle in
|
||||||
|
* log.js. The bar is draggable: vertical pointer drag reveals or re-hides
|
||||||
|
* lines from the top of the hidden range. Visual cues:
|
||||||
|
* - ns-resize cursor announces the drag direction.
|
||||||
|
* - Faint horizontal hatch hints at compressed content underneath.
|
||||||
|
* - Hover and drag states intensify the hatch toward --accent so the
|
||||||
|
* bar reads as an interactive separator, not decorative chrome.
|
||||||
|
*/
|
||||||
|
.collapsed-lines-foldable {
|
||||||
|
cursor: ns-resize;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed-lines-foldable .collapsed-lines-count {
|
||||||
|
background:
|
||||||
|
repeating-linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent 0,
|
||||||
|
transparent 3px,
|
||||||
|
color-mix(in srgb, var(--border) 60%, transparent) 3px,
|
||||||
|
color-mix(in srgb, var(--border) 60%, transparent) 4px
|
||||||
|
),
|
||||||
|
var(--surface);
|
||||||
|
border-top: 1px solid var(--border);
|
||||||
|
border-bottom: 1px solid var(--border);
|
||||||
|
transition:
|
||||||
|
background-color 0.12s ease,
|
||||||
|
color 0.12s ease,
|
||||||
|
border-color 0.12s ease,
|
||||||
|
box-shadow 0.12s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed-lines-foldable:hover .collapsed-lines-count,
|
||||||
|
.collapsed-lines-dragging .collapsed-lines-count {
|
||||||
|
background:
|
||||||
|
repeating-linear-gradient(
|
||||||
|
to bottom,
|
||||||
|
transparent 0,
|
||||||
|
transparent 3px,
|
||||||
|
color-mix(in srgb, var(--accent) 35%, transparent) 3px,
|
||||||
|
color-mix(in srgb, var(--accent) 35%, transparent) 4px
|
||||||
|
),
|
||||||
|
var(--accent-bg);
|
||||||
|
border-top-color: color-mix(in srgb, var(--accent) 60%, transparent);
|
||||||
|
border-bottom-color: color-mix(in srgb, var(--accent) 60%, transparent);
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed-lines-foldable:hover .collapsed-lines-count i,
|
||||||
|
.collapsed-lines-dragging .collapsed-lines-count i {
|
||||||
|
color: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed-lines-dragging {
|
||||||
|
cursor: grabbing;
|
||||||
|
}
|
||||||
|
|
||||||
|
.collapsed-lines-dragging .collapsed-lines-count {
|
||||||
|
box-shadow:
|
||||||
|
inset 0 0 0 1px color-mix(in srgb, var(--accent) 70%, transparent),
|
||||||
|
0 6px 16px color-mix(in srgb, var(--accent) 25%, transparent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The header error-count chip is informational only — the smart fold is
|
||||||
|
* applied automatically on page load and folds can only be expanded
|
||||||
|
* individually. Strip the .btn cursor / hover affordance so the chip
|
||||||
|
* doesn't read as interactive.
|
||||||
|
*/
|
||||||
|
#error-toggle {
|
||||||
|
cursor: default;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.log-inner .level {
|
.log-inner .level {
|
||||||
display: block;
|
display: block;
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
@@ -1145,7 +1239,7 @@ main {
|
|||||||
color: #A4A4A4;
|
color: #A4A4A4;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Minecraft Format Colors **/
|
/** Format colors (legacy mclogs syntax-highlighting palette) **/
|
||||||
|
|
||||||
.format-black {
|
.format-black {
|
||||||
color: #000;
|
color: #000;
|
||||||
@@ -47,93 +47,155 @@ function scrollToHeight(top, smoothScrollLimit = 10000) {
|
|||||||
window.scrollTo({left: 0, top, behavior});
|
window.scrollTo({left: 0, top, behavior});
|
||||||
}
|
}
|
||||||
|
|
||||||
/* error collapse toggle */
|
/*
|
||||||
const toggleErrorsButton = document.getElementById("error-toggle");
|
* Smart fold around errors.
|
||||||
if (toggleErrorsButton) {
|
*
|
||||||
toggleErrorsButton.addEventListener("click", toggleErrors);
|
* Every entry within ±ERROR_WINDOW_SIZE of an error stays visible; runs of
|
||||||
}
|
* non-error entries with no nearby errors collapse into a draggable fold
|
||||||
|
* bar. Vertical drag on the bar progressively reveals or re-hides lines;
|
||||||
|
* a click without drag reveals the next DEFAULT_CLICK_REVEAL lines.
|
||||||
|
*
|
||||||
|
* The fold is applied automatically on page load when the log contains
|
||||||
|
* errors. Folds can only be expanded individually — there is no
|
||||||
|
* "unfold everything" path. The error-count chip in the header is purely
|
||||||
|
* informational; it is not interactive.
|
||||||
|
*/
|
||||||
|
const ERROR_WINDOW_SIZE = 25;
|
||||||
|
const PIXELS_PER_LINE_DRAG = 6;
|
||||||
|
const DEFAULT_CLICK_REVEAL = 25;
|
||||||
|
const DRAG_PIXEL_THRESHOLD = 3;
|
||||||
|
|
||||||
function toggleErrors() {
|
applySmartFold();
|
||||||
if (toggleErrorsButton.classList.contains("toggled")) {
|
|
||||||
toggleErrorsButton.classList.remove("toggled");
|
|
||||||
uncollapseAllErrors();
|
|
||||||
} else {
|
|
||||||
toggleErrorsButton.classList.add("toggled");
|
|
||||||
collapseAllErrors();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function collapseAllErrors() {
|
function applySmartFold() {
|
||||||
let firstNoErrorLine = false;
|
const lines = Array.from(document.querySelectorAll('.log-inner > .entry'));
|
||||||
let lines = document.querySelectorAll('.log-inner > .entry');
|
const total = lines.length;
|
||||||
let totalLines = lines.length;
|
if (!total) return;
|
||||||
for (const [i, line] of lines.entries()) {
|
|
||||||
let lineNumber = line.querySelector(".line-number").innerHTML;
|
|
||||||
if (line.classList.contains("entry-no-error")) {
|
|
||||||
line.style.display = "none";
|
|
||||||
|
|
||||||
if (firstNoErrorLine === false) {
|
// Pass 1: mark entries within ±ERROR_WINDOW_SIZE of any error. If the
|
||||||
firstNoErrorLine = lineNumber;
|
// log has no errors, every entry stays visible (we never produce one
|
||||||
}
|
// giant fold spanning the whole log).
|
||||||
|
const mustShow = new Array(total).fill(false);
|
||||||
if (i + 1 === totalLines && firstNoErrorLine) {
|
let sawError = false;
|
||||||
line.insertAdjacentElement("afterend", generateCollapsedLines(firstNoErrorLine, lineNumber));
|
for (let i = 0; i < total; i++) {
|
||||||
}
|
if (lines[i].classList.contains("entry-error")) {
|
||||||
} else {
|
sawError = true;
|
||||||
if (firstNoErrorLine) {
|
const lo = Math.max(0, i - ERROR_WINDOW_SIZE);
|
||||||
line.insertAdjacentElement("beforebegin", generateCollapsedLines(firstNoErrorLine, lineNumber - 1));
|
const hi = Math.min(total - 1, i + ERROR_WINDOW_SIZE);
|
||||||
firstNoErrorLine = false;
|
for (let j = lo; j <= hi; j++) mustShow[j] = true;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!sawError) return;
|
||||||
|
|
||||||
|
// Pass 2: hide unmarked entries; emit a fold bar at the START of each run.
|
||||||
|
let runEntries = [];
|
||||||
|
const flushRun = () => {
|
||||||
|
if (!runEntries.length) return;
|
||||||
|
const bar = createFoldBar(runEntries);
|
||||||
|
runEntries[0].insertAdjacentElement("beforebegin", bar);
|
||||||
|
runEntries = [];
|
||||||
|
};
|
||||||
|
for (let i = 0; i < total; i++) {
|
||||||
|
if (!mustShow[i]) {
|
||||||
|
lines[i].style.display = "none";
|
||||||
|
runEntries.push(lines[i]);
|
||||||
|
} else {
|
||||||
|
flushRun();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
flushRun();
|
||||||
}
|
}
|
||||||
|
|
||||||
function uncollapseAllErrors() {
|
function createFoldBar(entries) {
|
||||||
document.querySelectorAll('.entry-no-error').forEach(line => line.style.removeProperty("display"));
|
const bar = document.createElement("div");
|
||||||
document.querySelectorAll('.collapsed-lines').forEach(collapsed => collapsed.remove());
|
bar.classList.add("collapsed-lines", "collapsed-lines-foldable");
|
||||||
|
bar.appendChild(document.createElement("div")); // line-number column slot
|
||||||
|
|
||||||
|
const count = document.createElement("div");
|
||||||
|
count.classList.add("collapsed-lines-count");
|
||||||
|
bar.appendChild(count);
|
||||||
|
|
||||||
|
bar._hiddenEntries = entries;
|
||||||
|
bar._revealedCount = 0;
|
||||||
|
renderFoldLabel(bar);
|
||||||
|
attachFoldDragHandler(bar);
|
||||||
|
return bar;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCollapsedClick(e) {
|
function renderFoldLabel(bar) {
|
||||||
let collapsed = e.currentTarget;
|
const entries = bar._hiddenEntries;
|
||||||
let positionElement = document.getElementById(`L${parseInt(collapsed.dataset.end) + 1}`);
|
const total = entries.length;
|
||||||
let position;
|
const revealed = bar._revealedCount;
|
||||||
if (positionElement) {
|
const remaining = total - revealed;
|
||||||
position = positionElement.getBoundingClientRect().top - window.scrollY;
|
const count = bar.querySelector(".collapsed-lines-count");
|
||||||
}
|
count.replaceChildren();
|
||||||
for (let i = parseInt(collapsed.dataset.start); i <= parseInt(collapsed.dataset.end); i++) {
|
|
||||||
document.getElementById(`L${i}`).parentElement.parentElement.style.removeProperty("display");
|
if (remaining <= 0) return;
|
||||||
}
|
|
||||||
if (positionElement) {
|
const firstHiddenLine = parseInt(entries[revealed].querySelector(".line-number").innerHTML, 10);
|
||||||
window.scrollTo({
|
const lastHiddenLine = parseInt(entries[total - 1].querySelector(".line-number").innerHTML, 10);
|
||||||
left: 0,
|
const word = remaining === 1 ? "line" : "lines";
|
||||||
top: positionElement.getBoundingClientRect().top - position - collapsed.offsetHeight,
|
|
||||||
behavior: "instant"
|
const grip = document.createElement("i");
|
||||||
});
|
grip.className = "fa-solid fa-grip-lines";
|
||||||
}
|
count.appendChild(grip);
|
||||||
collapsed.remove();
|
count.append(` ${remaining} ${word} hidden · ${firstHiddenLine}–${lastHiddenLine} · drag to reveal `);
|
||||||
|
count.appendChild(grip.cloneNode());
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateCollapsedLines(start, end) {
|
function applyFoldReveal(bar, n) {
|
||||||
let count = end - start + 1;
|
const entries = bar._hiddenEntries;
|
||||||
let string = count === 1 ? "line" : "lines";
|
n = Math.max(0, Math.min(entries.length, n));
|
||||||
|
if (n === bar._revealedCount) return;
|
||||||
|
for (let i = 0; i < entries.length; i++) {
|
||||||
|
if (i < n) entries[i].style.removeProperty("display");
|
||||||
|
else entries[i].style.display = "none";
|
||||||
|
}
|
||||||
|
bar._revealedCount = n;
|
||||||
|
renderFoldLabel(bar);
|
||||||
|
}
|
||||||
|
|
||||||
let collapsedRow = document.createElement("div");
|
function attachFoldDragHandler(bar) {
|
||||||
collapsedRow.classList.add("collapsed-lines");
|
let dragging = false;
|
||||||
collapsedRow.dataset.start = start;
|
let dragStartY = 0;
|
||||||
collapsedRow.dataset.end = end;
|
let dragStartReveal = 0;
|
||||||
collapsedRow.appendChild(document.createElement("div"));
|
let didDrag = false;
|
||||||
collapsedRow.addEventListener("click", handleCollapsedClick);
|
|
||||||
|
|
||||||
let collapsedLinesCount = document.createElement("div");
|
bar.addEventListener("pointerdown", (e) => {
|
||||||
collapsedLinesCount.classList.add("collapsed-lines-count");
|
if (e.button !== 0) return;
|
||||||
let icon = document.createElement("i");
|
dragging = true;
|
||||||
icon.classList.add("fa-solid", "fa-angle-up");
|
didDrag = false;
|
||||||
collapsedLinesCount.appendChild(icon);
|
dragStartY = e.clientY;
|
||||||
collapsedLinesCount.append(` ${count} ${string} `);
|
dragStartReveal = bar._revealedCount;
|
||||||
collapsedLinesCount.append(icon.cloneNode());
|
bar.setPointerCapture(e.pointerId);
|
||||||
collapsedRow.appendChild(collapsedLinesCount);
|
bar.classList.add("collapsed-lines-dragging");
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
return collapsedRow;
|
bar.addEventListener("pointermove", (e) => {
|
||||||
|
if (!dragging) return;
|
||||||
|
const dy = e.clientY - dragStartY;
|
||||||
|
if (Math.abs(dy) >= DRAG_PIXEL_THRESHOLD) didDrag = true;
|
||||||
|
const target = dragStartReveal + Math.round(dy / PIXELS_PER_LINE_DRAG);
|
||||||
|
applyFoldReveal(bar, target);
|
||||||
|
});
|
||||||
|
|
||||||
|
const finish = (e) => {
|
||||||
|
if (!dragging) return;
|
||||||
|
dragging = false;
|
||||||
|
try { bar.releasePointerCapture(e.pointerId); } catch {}
|
||||||
|
bar.classList.remove("collapsed-lines-dragging");
|
||||||
|
|
||||||
|
if (!didDrag) {
|
||||||
|
// Plain click: reveal the next chunk of lines.
|
||||||
|
applyFoldReveal(bar, bar._revealedCount + DEFAULT_CLICK_REVEAL);
|
||||||
|
}
|
||||||
|
if (bar._revealedCount >= bar._hiddenEntries.length) {
|
||||||
|
bar.remove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
bar.addEventListener("pointerup", finish);
|
||||||
|
bar.addEventListener("pointercancel", finish);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* convert timestamps */
|
/* convert timestamps */
|
||||||
@@ -203,7 +265,7 @@ function saveSettings() {
|
|||||||
for (const checkbox of settingCheckboxes) {
|
for (const checkbox of settingCheckboxes) {
|
||||||
data[checkbox.dataset.key] = checkbox.checked;
|
data[checkbox.dataset.key] = checkbox.checked;
|
||||||
}
|
}
|
||||||
document.cookie = "MCLOGS_SETTINGS=" + encodeURIComponent(JSON.stringify(data)) + ";path=/;expires=" + new Date(new Date().getTime() + 100 * 365 * 24 * 60 * 60 * 1000).toUTCString();
|
document.cookie = "IBLOGS_SETTINGS=" + encodeURIComponent(JSON.stringify(data)) + ";path=/;expires=" + new Date(new Date().getTime() + 100 * 365 * 24 * 60 * 60 * 1000).toUTCString();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy to clipboard */
|
/* copy to clipboard */
|
||||||
|
|||||||
@@ -7,8 +7,27 @@ const fileSelectButton = document.getElementById('paste-select-file');
|
|||||||
const pasteClipboardButton = document.getElementById('paste-clipboard');
|
const pasteClipboardButton = document.getElementById('paste-clipboard');
|
||||||
const pasteError = document.getElementById('paste-error');
|
const pasteError = document.getElementById('paste-error');
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Large-paste buffering. <textarea> rendering is the bottleneck once content
|
||||||
|
* crosses a few hundred KB; the browser locks up while it lays out millions
|
||||||
|
* of characters. For pastes / file loads above the threshold, we hold the
|
||||||
|
* full content in `bufferedContent` and only render a small preview into the
|
||||||
|
* textarea. The save path uses `bufferedContent` when set.
|
||||||
|
*/
|
||||||
|
const PASTE_BUFFER_THRESHOLD_BYTES = 256 * 1024; // 256 KB
|
||||||
|
const PASTE_PREVIEW_LINES = 50;
|
||||||
|
let bufferedContent = null;
|
||||||
|
|
||||||
pasteArea.focus();
|
pasteArea.focus();
|
||||||
pasteArea.addEventListener('input', reevaluateContentStatus);
|
pasteArea.addEventListener('input', () => {
|
||||||
|
// User-typed input invalidates the buffer (the textarea is now the
|
||||||
|
// source of truth). The buffer is only set programmatically, so a
|
||||||
|
// user-driven `input` event always means edit-from-preview.
|
||||||
|
if (bufferedContent !== null) {
|
||||||
|
clearBuffer();
|
||||||
|
}
|
||||||
|
reevaluateContentStatus();
|
||||||
|
});
|
||||||
pasteArea.addEventListener('paste', handlePasteEvent);
|
pasteArea.addEventListener('paste', handlePasteEvent);
|
||||||
pasteSaveButtons.forEach(button => button.addEventListener('click', sendLog));
|
pasteSaveButtons.forEach(button => button.addEventListener('click', sendLog));
|
||||||
fileSelectButton.addEventListener('click', selectLogFile);
|
fileSelectButton.addEventListener('click', selectLogFile);
|
||||||
@@ -39,7 +58,7 @@ async function sendLog() {
|
|||||||
pasteSaveButtons.forEach(button => button.classList.add("btn-working"));
|
pasteSaveButtons.forEach(button => button.classList.add("btn-working"));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let log = pasteArea.value;
|
let log = bufferedContent ?? pasteArea.value;
|
||||||
log = applyFilters(log);
|
log = applyFilters(log);
|
||||||
|
|
||||||
const bodyData = {
|
const bodyData = {
|
||||||
@@ -149,13 +168,56 @@ async function pasteFromClipboard() {
|
|||||||
showError("Clipboard is empty.");
|
showError("Clipboard is empty.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pasteArea.value = content;
|
loadContent(content);
|
||||||
reevaluateContentStatus();
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showError("Clipboard is empty or not accessible.");
|
showError("Clipboard is empty or not accessible.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Single entry point for "place this string in the editor."
|
||||||
|
* Routes large content into the buffer + preview; small content goes into
|
||||||
|
* the textarea normally so the user can keep editing it.
|
||||||
|
*/
|
||||||
|
function loadContent(text) {
|
||||||
|
if (text.length > PASTE_BUFFER_THRESHOLD_BYTES) {
|
||||||
|
loadIntoBuffer(text);
|
||||||
|
} else {
|
||||||
|
clearBuffer();
|
||||||
|
pasteArea.value = text;
|
||||||
|
reevaluateContentStatus();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadIntoBuffer(text) {
|
||||||
|
bufferedContent = text;
|
||||||
|
const lines = text.split('\n');
|
||||||
|
const sizeMb = (text.length / 1024 / 1024).toFixed(2);
|
||||||
|
if (lines.length <= PASTE_PREVIEW_LINES) {
|
||||||
|
pasteArea.value = text;
|
||||||
|
} else {
|
||||||
|
const preview = lines.slice(0, PASTE_PREVIEW_LINES).join('\n');
|
||||||
|
const remaining = lines.length - PASTE_PREVIEW_LINES;
|
||||||
|
pasteArea.value =
|
||||||
|
`[Large paste buffered: ${lines.length.toLocaleString()} lines, ${sizeMb} MB.\n` +
|
||||||
|
` Full content uploads on Save. Edit this textarea to clear the buffer.]\n` +
|
||||||
|
`\n` +
|
||||||
|
`--- preview: first ${PASTE_PREVIEW_LINES} of ${lines.length.toLocaleString()} lines ---\n` +
|
||||||
|
preview +
|
||||||
|
`\n--- ${remaining.toLocaleString()} more lines hidden ---\n`;
|
||||||
|
}
|
||||||
|
pasteArea.readOnly = true;
|
||||||
|
reevaluateContentStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function clearBuffer() {
|
||||||
|
if (bufferedContent === null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bufferedContent = null;
|
||||||
|
pasteArea.readOnly = false;
|
||||||
|
}
|
||||||
|
|
||||||
function reevaluateContentStatus() {
|
function reevaluateContentStatus() {
|
||||||
clearError();
|
clearError();
|
||||||
if (pasteArea.value.length > 0) {
|
if (pasteArea.value.length > 0) {
|
||||||
@@ -184,6 +246,14 @@ async function handlePasteEvent(e) {
|
|||||||
if (e.clipboardData?.files?.length > 0) {
|
if (e.clipboardData?.files?.length > 0) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
await loadFileContents(e.clipboardData.files[0]);
|
await loadFileContents(e.clipboardData.files[0]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Intercept large text pastes before the browser commits them to the
|
||||||
|
// textarea — assigning multi-MB strings to a <textarea> freezes the page.
|
||||||
|
const text = e.clipboardData?.getData('text');
|
||||||
|
if (text && text.length > PASTE_BUFFER_THRESHOLD_BYTES) {
|
||||||
|
e.preventDefault();
|
||||||
|
loadIntoBuffer(text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -220,8 +290,7 @@ async function loadFileContents(file) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
pasteArea.value = new TextDecoder().decode(content);
|
loadContent(new TextDecoder().decode(content));
|
||||||
reevaluateContentStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function selectLogFile() {
|
function selectLogFile() {
|
||||||
@@ -355,8 +424,7 @@ async function handleDropEvent(e) {
|
|||||||
let files = e.dataTransfer.files;
|
let files = e.dataTransfer.files;
|
||||||
if (files.length !== 1) {
|
if (files.length !== 1) {
|
||||||
if (Array.from(e.dataTransfer.types).includes('text/plain')) {
|
if (Array.from(e.dataTransfer.types).includes('text/plain')) {
|
||||||
pasteArea.value = e.dataTransfer.getData('text/plain');
|
loadContent(e.dataTransfer.getData('text/plain'));
|
||||||
reevaluateContentStatus();
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
12
worker.php
12
worker.php
@@ -1,11 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
use Aternos\Mclogs\Api\ApiRouter;
|
use IndifferentKetchup\Iblogs\Api\ApiRouter;
|
||||||
use Aternos\Mclogs\Config\Config;
|
use IndifferentKetchup\Iblogs\Config\Config;
|
||||||
use Aternos\Mclogs\Config\ConfigKey;
|
use IndifferentKetchup\Iblogs\Config\ConfigKey;
|
||||||
use Aternos\Mclogs\Frontend\FrontendRouter;
|
use IndifferentKetchup\Iblogs\Frontend\FrontendRouter;
|
||||||
use Aternos\Mclogs\Storage\MongoDBClient;
|
use IndifferentKetchup\Iblogs\Storage\MongoDBClient;
|
||||||
use Aternos\Mclogs\Util\URL;
|
use IndifferentKetchup\Iblogs\Util\URL;
|
||||||
|
|
||||||
require_once __DIR__ . '/vendor/autoload.php';
|
require_once __DIR__ . '/vendor/autoload.php';
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user