mirror of
https://github.com/Abdess/retroarch_system.git
synced 2026-10-23 20:29:06 -05:00
docs: explain setups without a ZIP
FAQ entry, the release_pack field and how to revisit it from download counts, the get/ pages, and RetroPie 4.8 now installs from a computer with the Pi's network folder as --dest. The start pages are back under their word ceilings.
This commit is contained in:
1 parent
a2fc09a89e
commit
ba3d519189
9 files changed
+101
-57
No files matched your search
@@ -160,6 +160,7 @@ platforms:
|
||||
myplatform:
|
||||
config: myplatform.yml # platform YAML filename in platforms/
|
||||
status: active # active or archived
|
||||
release_pack: true # optional: a release publishes its ZIP
|
||||
device_group: handheld # computer, gaming-os, handheld, fpga or server
|
||||
scraper: myplatform # matches PLATFORM_NAME, null if hand-maintained
|
||||
schedule: weekly # re-scrape cadence, run by hand: weekly, monthly, or null
|
||||
@@ -682,6 +683,12 @@ A new platform is archived-by-default nowhere: `status: active` puts it in
|
||||
`status: archived` to keep the configuration without the automation. Archived
|
||||
platforms are excluded unless `--all` or `--include-archived` is passed.
|
||||
|
||||
A new platform has no release ZIP: `release_pack: true` is set for the setups
|
||||
most people download, and the installer serves every other one from its
|
||||
manifest. `generate_pack.py --platform myplatform` still builds its pack.
|
||||
[Which platforms get a pack](release-process.md#which-platforms-get-a-pack)
|
||||
says how the list is read from download counts.
|
||||
|
||||
Check the output for:
|
||||
|
||||
- The new platform appears in verify results
|
||||
|
||||
+24
-22
@@ -9,13 +9,13 @@ order: 50
|
||||
|
||||
- **Yes** for PlayStation 1 and 2, Saturn and Neo Geo.
|
||||
- **Better with it** for Dreamcast: some games need it.
|
||||
- **Usually not** for NES or Super Nintendo cartridges.
|
||||
- **Usually not** for NES or Super Nintendo.
|
||||
|
||||
[What is a BIOS?](what-are-bios-files.md)
|
||||
|
||||
## How do I know which BIOS I need?
|
||||
|
||||
Run the command with `--dry-run`. It lists the files, changing nothing.
|
||||
Add `--dry-run`. It lists the files, changing nothing.
|
||||
|
||||
<!-- os-tabs -->
|
||||
```sh
|
||||
@@ -24,23 +24,21 @@ curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh |
|
||||
|
||||
## Do I need every file of a console?
|
||||
|
||||
No. A console often has one BIOS per region. To keep only yours, add your
|
||||
region, like `--region us`.
|
||||
No. To keep only your region's BIOS, add it, like `--region us`.
|
||||
|
||||
## Does the BIOS set the game's language?
|
||||
|
||||
Rarely. It comes from the game. Some games follow the console's setting, like
|
||||
Flycast's **Language** option.
|
||||
Rarely. It comes from the game. Some games follow the console's setting, like Flycast's **Language**
|
||||
option.
|
||||
|
||||
## Zip or unzip? { #zip-or-unzip }
|
||||
|
||||
Unzip the ZIP you downloaded into the folder your setup's page names. Keep
|
||||
Unzip it into the folder your setup's page names. Leave
|
||||
the ZIPs inside zipped, like `neogeo.zip`.
|
||||
|
||||
## Does a BIOS work on every setup?
|
||||
|
||||
Usually. The command installs the version each setup expects, like its
|
||||
`neogeo.zip`.
|
||||
Usually. The command installs each setup's own version, like its `neogeo.zip`.
|
||||
|
||||
## My arcade game does not start
|
||||
|
||||
@@ -50,35 +48,39 @@ Reference: [Which version each emulator reads](technical-faq.md#which-mame-versi
|
||||
## Keys, firmware or BIOS?
|
||||
|
||||
- **BIOS** or **firmware**: the console's own program, like `scph5501.bin`.
|
||||
- Some newer consoles need a system update, like `PS3UPDAT.PUP`, installed from the
|
||||
- Newer consoles need a system update, like `PS3UPDAT.PUP`, installed from the
|
||||
emulator's menu.
|
||||
- **Keys** unlock encrypted games, like `prod.keys` for Switch.
|
||||
|
||||
## Can I play without the BIOS?
|
||||
|
||||
Sometimes. Some emulators carry a stand-in, and some games then fail.
|
||||
Sometimes, with an emulator's stand-in, but some games fail.
|
||||
|
||||
## Is the command safe? { #is-piping-the-installer-into-a-shell-safe }
|
||||
|
||||
- It stops if the installer does not match its expected fingerprint, then
|
||||
checks each file before saving it.
|
||||
- It writes in your BIOS folder, and for some emulators in your save folder.
|
||||
- It stops if the installer does not match its expected fingerprint, and checks
|
||||
each file.
|
||||
- It writes in your BIOS folder, and for some emulators your save folder.
|
||||
- It never touches a game or a save.
|
||||
- It keeps any file it replaces in `retrobios-backup`, next to your BIOS
|
||||
folder. `--restore` puts it back.
|
||||
- It keeps each file it replaces in `retrobios-backup`. `--restore` puts it
|
||||
back.
|
||||
|
||||
Read them first: [install.sh](https://github.com/Abdess/retrobios/blob/main/install.sh),
|
||||
[install.ps1](https://github.com/Abdess/retrobios/blob/main/install.ps1),
|
||||
[install.py](https://github.com/Abdess/retrobios/blob/main/install.py).
|
||||
[How the installer checks itself](installer.md#what-the-bootstrap-does).
|
||||
|
||||
## Windows or my antivirus blocks the command
|
||||
|
||||
Download your setup's ZIP from [Get your files](../which-pack.md) instead.
|
||||
Use your setup's ZIP, if it has one: [Get your files](../which-pack.md).
|
||||
|
||||
## Why is there no ZIP for my setup?
|
||||
|
||||
ZIPs are made for the setups most people download. The command installs every
|
||||
setup's files and checks each one. `--dry-run` shows the list first.
|
||||
|
||||
## Fill an SD card from a computer?
|
||||
|
||||
Yes. Name your setup and the BIOS folder on the card. For RetroArch on a Switch
|
||||
Yes. Name your setup and the card's BIOS folder. For RetroArch on a Switch
|
||||
card in drive `E:`:
|
||||
|
||||
<!-- os-tabs windows: --platform retroarch --dest E:\retroarch\cores\system -->
|
||||
@@ -89,7 +91,7 @@ curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh \
|
||||
|
||||
## No internet on the device?
|
||||
|
||||
Unzip your setup's ZIP into the folder its page names. To check each file, use
|
||||
Fill its folder from a computer, as above, or unzip your ZIP and check it with
|
||||
`--from-pack`: [Without a network](installer.md#without-a-network-offline-install).
|
||||
|
||||
## My setup is not in the list
|
||||
@@ -100,11 +102,11 @@ Unzip your setup's ZIP into the folder its page names. To check each file, use
|
||||
|
||||
## Why is a file missing from the ZIP?
|
||||
|
||||
Some come with the emulator, so the ZIP leaves them out.
|
||||
Some come with the emulator, so the ZIP skips them.
|
||||
|
||||
## My game shows a black screen
|
||||
|
||||
A BIOS file is often missing: [When a game does not start](troubleshooting.md).
|
||||
Often a missing BIOS: [When a game does not start](troubleshooting.md).
|
||||
|
||||
## Is this legal?
|
||||
|
||||
|
||||
+8
-10
@@ -97,7 +97,7 @@ curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh |
|
||||
|
||||
## 4. Wait
|
||||
|
||||
You can stop with Ctrl+C at any time. Run the command again to carry on.
|
||||
Ctrl+C stops it. Run the command again to carry on.
|
||||
|
||||
## 5. Read the last line
|
||||
|
||||
@@ -120,7 +120,7 @@ Add `--check` to the same command. It changes nothing.
|
||||
curl -fsSL https://raw.githubusercontent.com/Abdess/retrobios/main/install.sh | sh -s -- --check
|
||||
```
|
||||
|
||||
All good when every file is present and none is wrong:
|
||||
All good:
|
||||
|
||||
```
|
||||
109/109 present (109 verified, 0 wrong hash)
|
||||
@@ -130,8 +130,8 @@ An empty folder also shows `0 wrong hash`, with `0/109 present`.
|
||||
|
||||
## Undo
|
||||
|
||||
It keeps every file it replaces in a `retrobios-backup` folder, next to your
|
||||
BIOS folder. The end of the run prints the line that puts them back.
|
||||
Every file it replaces goes to a `retrobios-backup` folder next to your BIOS
|
||||
folder. The last lines say how to put them back.
|
||||
|
||||
## If it stops
|
||||
|
||||
@@ -150,8 +150,8 @@ The message shows the command that installs Python. Run it, then run the
|
||||
installer again.
|
||||
|
||||
A RetroPie 4.8 image has Python 3.7.3, and its update command finds nothing
|
||||
newer. Use the [RetroPie ZIP](../platforms/retropie.md#download) there,
|
||||
unzipped into `~/RetroPie/BIOS/`.
|
||||
newer. Run the command on a computer, with
|
||||
`--platform retropie --dest \\RETROPIE\bios\`.
|
||||
|
||||
### Error: the downloaded installer does not match its expected fingerprint.
|
||||
|
||||
@@ -159,13 +159,11 @@ The download was cut short. Nothing was changed. Run the command again.
|
||||
|
||||
### Cannot create ...
|
||||
|
||||
You do not have the right to write there. Do what the message says. It names
|
||||
what to run.
|
||||
You cannot write there. Do what the message says.
|
||||
|
||||
### Not enough space on the drive holding ...
|
||||
|
||||
It stopped before writing. Free some space, or use `--dest` to pick another
|
||||
drive.
|
||||
Nothing was written. Free some space, or pick another drive with `--dest`.
|
||||
|
||||
### The game still does not start
|
||||
|
||||
|
||||
+2
-1
@@ -22,7 +22,8 @@ order: 60
|
||||
: The folder where your setup looks for BIOS files.
|
||||
|
||||
**Pack**
|
||||
: The ZIP file with every BIOS file for one setup.
|
||||
: The ZIP file with every BIOS file for one setup. Made for the setups most
|
||||
people download.
|
||||
|
||||
**Platform**
|
||||
: A setup, as the project's data calls it.
|
||||
|
||||
+6
-6
@@ -992,8 +992,8 @@ file rather than followed.
|
||||
`install.py` runs on the user's machine, often an older handheld, so it stays
|
||||
on Python 3.8 and the standard library alone. The RetroPie 4.8 images
|
||||
(`retropie-buster-4.8-*.img.gz`) are Debian Buster, whose `python3` is 3.7.3:
|
||||
there the bootstrap stops before running anything, and the RetroPie pack from
|
||||
the releases page is the way to install
|
||||
there the bootstrap stops before running anything, and the way to install is
|
||||
the command run on a computer with the Pi's network folder as `--dest`
|
||||
([first install](first-install.md#error-python-38-or-newer-is-required)).
|
||||
Tests refuse any 3.9 syntax or API, and one runs the installer end to end under
|
||||
a real 3.8 interpreter, which CI installs beside 3.12 so the check cannot skip.
|
||||
@@ -1167,10 +1167,10 @@ left out.
|
||||
|
||||
`scripts/download.py --list` and `scripts/download.sh --list` print the packs of
|
||||
a release. A pack's name lists every platform it serves. Releases up to
|
||||
v2026.10.10 ship RetroArch and Lakka as one `RetroArch_Lakka` pack, and the
|
||||
next ones give Lakka its own, since Lakka runs on Linux where two names that
|
||||
differ by case are two files. The installer and the download scripts find the
|
||||
right pack either way.
|
||||
v2026.10.10 ship RetroArch and Lakka as one `RetroArch_Lakka` pack. Later
|
||||
releases publish packs only for the setups most people download, so Lakka,
|
||||
which runs on Linux where two names that differ by case are two files, is
|
||||
served by the installer. The download scripts name the installer for a setup without a pack.
|
||||
|
||||
Parts named `Pack.part1of2.zip` are ordinary ZIPs: unzip each one into the same
|
||||
folder, and check that all of them were downloaded. The name says how many
|
||||
|
||||
@@ -14,7 +14,8 @@ everyday words (BIOS, emulator, core, hash) are in the [glossary](glossary.md).
|
||||
|
||||
**Pack**
|
||||
: One ZIP file with every BIOS file a setup uses. A pack over 2 GB comes in
|
||||
several parts, and every part is needed.
|
||||
several parts, and every part is needed. A release publishes packs for the
|
||||
setups the registry marks `release_pack`, and the installer serves the rest.
|
||||
|
||||
**Profile and source_ref**
|
||||
: A profile records which files one emulator opens, read from its code.
|
||||
|
||||
+42
-4
@@ -206,8 +206,9 @@ pipeline runs here, the archives are checked here, and `gh` uploads them.
|
||||
|
||||
```bash
|
||||
# 1. Full pipeline, online, so data directories and MAME/FBNeo hashes are
|
||||
# fresh. --include-archived builds RetroPie too, archived but still served,
|
||||
# and holds its pack to the same consistency and integrity checks.
|
||||
# fresh. It builds the packs of the platforms marked release_pack (see
|
||||
# "Which platforms get a pack" below) and the install manifests of every
|
||||
# platform, RetroPie included with --include-archived.
|
||||
python scripts/pipeline.py --include-archived
|
||||
|
||||
# 2. A release file must be under 2 GiB. A larger pack becomes parts that are
|
||||
@@ -276,6 +277,43 @@ gh release list --json tagName,createdAt \
|
||||
| tail -n +2 | while read tag; do gh release delete "$tag" --yes --cleanup-tag; done
|
||||
```
|
||||
|
||||
## Which platforms get a pack { #which-platforms-get-a-pack }
|
||||
|
||||
`release_pack: true` in `platforms/_registry.yml` is the list. `generate_pack.py
|
||||
--all` builds those packs and no other, `--verify-packs` and the consistency
|
||||
step of the pipeline check those, `release_record.py` refuses any other pack
|
||||
in `dist/`, and `check_release.py` reports a marked platform without a pack.
|
||||
The README, the download page, each setup page and the release notes read the
|
||||
same field: a platform without it shows "No ZIP" and the command. Its install
|
||||
manifest is written all the same, and `generate_pack.py --platform NAME` still
|
||||
builds its pack for anyone who wants one.
|
||||
|
||||
The list follows downloads. In v2026.10.10, part 1 of each pack was fetched
|
||||
7,251 times for RetroArch, 2,909 for EmuDeck, 1,988 for RetroBat, 1,933 for
|
||||
Batocera and 1,003 for RomM, then 751 for RetroPie, 642 for Recalbox, 516 for
|
||||
RetroDECK, 450 for MiSTer, 386 for ROCKNIX and 361 for BizHawk. The first five
|
||||
are 83% of downloads for 17 GB of the 35 GB all packs weighed. MiSTer stays
|
||||
for its 17 MB. To revisit the list, read the counts of the latest release,
|
||||
counting a whole pack or the first part of a split one, so each download
|
||||
counts once:
|
||||
|
||||
```bash
|
||||
gh api repos/Abdess/retrobios/releases/latest --jq '.assets[]
|
||||
| select(.name | test("_BIOS_Pack(\\.part1of[0-9]+)?\\.zip$"))
|
||||
| "\(.download_count)\t\(.name)"' | sort -rn
|
||||
```
|
||||
|
||||
Then add or remove the field and regenerate the README and the site.
|
||||
|
||||
Every platform has a page at `get/<platform>/` on the site, its permanent
|
||||
download address. It lists the files of the pack the latest release holds,
|
||||
read from `release.json`, or gives the command when there is no pack. The
|
||||
README, the setup pages and the release notes link it, never an asset URL:
|
||||
step 6 deletes the previous tag, and with it every link to its assets. Six of
|
||||
the eight links one community wiki had to our packs answered 404 that way.
|
||||
Committing `release.json` in step 5 rebuilds these pages, so the release
|
||||
never touches them.
|
||||
|
||||
## Verifying a release
|
||||
|
||||
`SHA256SUMS.txt` is signed with a key used for nothing else. Its public half
|
||||
@@ -320,8 +358,8 @@ fingerprint, `SHA256:jUcTBhDS5DhmheXuVhAzh3pb04uI0caOAaiZzWXvrk4`.
|
||||
Rotating the key means committing the new public half to `allowed_signers`
|
||||
and keeping the retired line, so signatures on past releases keep verifying.
|
||||
|
||||
One pack per platform, the full one: the platform's list plus everything its
|
||||
cores load. Platform-only and per-emulator packs are build options, not
|
||||
One pack per platform marked `release_pack`, the full one: the platform's list
|
||||
plus everything its cores load. Platform-only and per-emulator packs are build options, not
|
||||
release assets, since a lighter pack means a core that fails with no message.
|
||||
The release notes are written by `release_notes.py`: the install commands,
|
||||
the pack table and its parts sentence come from `release.json`, then what
|
||||
|
||||
@@ -48,7 +48,7 @@ Every module in `tests/`, by the area it guards.
|
||||
| Core regression suites | synthetic | `test_e2e`, `test_audit_regressions`, `test_tool_messages` |
|
||||
| File resolution and identity | synthetic + collection | `test_adler32_resolution`, `test_agnostic_scan`, `test_agnostic_scan_mode`, `test_agnostic_scope`, `test_agnostic_substitute`, `test_archive_choice`, `test_archive_recipes`, `test_bios_companions`, `test_bundled_identity`, `test_casefold_cache`, `test_db_aliases`, `test_declared_names`, `test_derivations`, `test_directory_entries`, `test_extra_identity`, `test_foreign_tree`, `test_foreign_tree_names`, `test_frontend_digest`, `test_game_data_homonyms`, `test_hashing`, `test_identity`, `test_md5_pack_context`, `test_name_tiebreak`, `test_nec_filing`, `test_owner_resolution`, `test_path_suffix`, `test_resolution_evidence`, `test_sega_filing`, `test_shipped_content`, `test_twin_declarations`, `test_validated_choice`, `test_variant_choice`, `test_variant_identity`, `test_zipped_member` |
|
||||
| Verification, cross-reference and profile checks | synthetic + profiles | `test_bios_layout`, `test_cache_independent_counts`, `test_case_insensitive_platforms`, `test_checks_have_values`, `test_core_file_fills_declaration`, `test_core_size_refusal`, `test_cross_reference_sources`, `test_crypto_aes`, `test_crypto_unique_data`, `test_crypto_verify`, `test_entry_categories`, `test_file_consumers`, `test_fileless_audit`, `test_flycast_layout`, `test_gap_settlement`, `test_hidden_extras`, `test_launcher_aliases`, `test_launcher_layer`, `test_native_mode`, `test_no_case_collisions`, `test_path_conflict_status`, `test_path_null_copies`, `test_profile_checks`, `test_profile_repositories`, `test_romm_hash_rule`, `test_shared_groups`, `test_standalone_links`, `test_standalone_mode`, `test_undeclared_dedup`, `test_unplaced_extras`, `test_validation_scope`, `test_verify_all_dir`, `test_verify_emulator_evidence`, `test_verify_listing`, `test_verify_pack_choice`, `test_verify_release_asset` |
|
||||
| Packs and manifests | synthetic + real packs | `test_artifact_lock`, `test_atomic_artifacts`, `test_batocera_cores`, `test_deterministic_zip`, `test_emulator_pack_counts`, `test_finalize_pack_names`, `test_large_file_cache`, `test_libretro_layout`, `test_manifest_entry`, `test_minui_platform`, `test_no_game_data`, `test_pack_conformance_dirs`, `test_pack_core_extras`, `test_pack_counts`, `test_pack_destinations`, `test_pack_failures`, `test_pack_file_names`, `test_pack_grouping`, `test_pack_integrity`, `test_pack_member_identity`, `test_pack_readme`, `test_platform_inheritance`, `test_platform_keys`, `test_required_only_archives`, `test_required_only_twins`, `test_save_root`, `test_split_extras`, `test_split_names`, `test_split_pack`, `test_system_pack_extras`, `test_system_pack_parity`, `test_torrentzip`, `test_which_pack` |
|
||||
| Packs and manifests | synthetic + real packs | `test_artifact_lock`, `test_atomic_artifacts`, `test_batocera_cores`, `test_deterministic_zip`, `test_emulator_pack_counts`, `test_finalize_pack_names`, `test_large_file_cache`, `test_libretro_layout`, `test_manifest_entry`, `test_minui_platform`, `test_no_game_data`, `test_pack_conformance_dirs`, `test_pack_core_extras`, `test_pack_counts`, `test_pack_destinations`, `test_pack_failures`, `test_pack_file_names`, `test_pack_grouping`, `test_pack_integrity`, `test_pack_member_identity`, `test_pack_readme`, `test_platform_inheritance`, `test_platform_keys`, `test_release_packs`, `test_required_only_archives`, `test_required_only_twins`, `test_save_root`, `test_split_extras`, `test_split_names`, `test_split_pack`, `test_system_pack_extras`, `test_system_pack_parity`, `test_torrentzip`, `test_which_pack` |
|
||||
| Slots and regions | synthetic + profiles | `test_region`, `test_region_agnostic_scan`, `test_region_groups`, `test_region_held`, `test_region_platform_index`, `test_region_required_only`, `test_slot`, `test_slots`, `test_slots_shipped_file` |
|
||||
| Hardware targets and systems | synthetic + target files | `test_extract_targets`, `test_lakka_targets`, `test_libretro_slugs`, `test_system_ids`, `test_system_selection`, `test_target_names`, `test_target_scrapers`, `test_target_systems`, `test_target_verify` |
|
||||
| Installer and downloads | loopback server | `test_check_release`, `test_download`, `test_install`, `test_install_cores`, `test_install_experience`, `test_install_offline`, `test_install_selection` |
|
||||
|
||||
+9
-12
@@ -24,25 +24,23 @@ Read the count line:
|
||||
1/109 present (0 verified, 1 wrong hash)
|
||||
```
|
||||
|
||||
- **`wrong hash`**: another region, model, or damaged. Batocera says
|
||||
`UNTESTED`.
|
||||
- **`wrong hash`**: another region or model, or damaged.
|
||||
- **Fewer present than the total**: files are missing.
|
||||
- **A line under a file**, like `still zipped`, says what to fix.
|
||||
- **`0 wrong hash`, all present**: go to step 3.
|
||||
|
||||
## 2. Fix the files
|
||||
|
||||
Run it again without `--check`. It adds missing files and replaces wrong ones.
|
||||
Run it without `--check`. It adds missing files and replaces wrong ones.
|
||||
|
||||
## 3. Check the folder and the names
|
||||
|
||||
- **Right folder?** [Get your files](../which-pack.md) names the one your setup
|
||||
reads.
|
||||
- **Right folder?** [Get your files](../which-pack.md) names it.
|
||||
- **Exact name?** `scph5501.bin` and `SCPH-5501.BIN` differ. On Linux,
|
||||
capitals count too.
|
||||
- **A `bios` folder inside your BIOS folder?** Move its files up one level.
|
||||
- **Unzipped by hand on Linux?** Run the command once. It adds names that
|
||||
differ by capitals only.
|
||||
- **Unzipped by hand on Linux?** The command adds names that differ by
|
||||
capitals.
|
||||
- **A ZIP in parts, like `Pack.part1of2.zip`?** Unzip every part into one
|
||||
folder.
|
||||
|
||||
@@ -58,17 +56,16 @@ version.
|
||||
|
||||
## The BIOS is fine, the game still fails
|
||||
|
||||
- **Another emulator?** Each one reads its own files. Its page lists them.
|
||||
- **Another emulator?** Each reads its own files, listed on its page.
|
||||
- **A BIOS setting?** Some emulators can skip the BIOS. In PCSX ReARMed, set
|
||||
**BIOS Selection** to **Auto**.
|
||||
- **A disc game in several files?** Open its `.cue` or `.m3u` file, not a
|
||||
`.bin`.
|
||||
- **A disc in several files?** Open its `.cue` or `.m3u`, not a `.bin`.
|
||||
|
||||
## If the command fails { #installation-script-fails }
|
||||
|
||||
- **Network error:** try again once github.com opens.
|
||||
- **`The clock reads ...`:** the date is wrong. Let it sync over Wi-Fi, or set
|
||||
it, then run again.
|
||||
- **`The clock reads ...`:** the date is wrong. Sync it over Wi-Fi or set it,
|
||||
then run again.
|
||||
- **Permission denied:** do what the message says. It names what to run.
|
||||
- **No setup found:** name it and its folder:
|
||||
|
||||
|
||||
Reference in new issue
Block a user