Skip to content

SimpleHomes v2.0.0#5

Draft
Peashooter101 wants to merge 2 commits intomasterfrom
brigadier
Draft

SimpleHomes v2.0.0#5
Peashooter101 wants to merge 2 commits intomasterfrom
brigadier

Conversation

@Peashooter101
Copy link
Copy Markdown
Member

@Peashooter101 Peashooter101 commented Apr 7, 2026

SimpleHomes v2.0.0 Design Specifications

Overview

User facing design changes have been reflected on the README.md file, including permission reworks and configuration changes.

Anything that is less obvious or technical will be in this document.

Note

This is likely to change as decisions are made and this is refined.

Warning

We will be breaking things for this update to ultimately provide a more sensible experience in the long run. Although, part of the goal is to ensure that the only things we break is configuration / permission nodes that currently exist and we offer documentation to help Server Administrators swap over from v1.3.1 to v2.0.0.

There should be no technical aspect (SQL, Brigadier, etc) that breaks and requires manual fixing by Server Administrators.

Important

Sections marked with this Alert are parts where design is not fleshed out and needs additional review or consideration.

Brigadier

Commands are being moved to the Brigadier system.

Permissions are being reworked as commands are being moved around. Permissions can be viewed on the README.md.

homes.count will be removed as a result of this update. We will utilize a similar system to SimpleChat, which utilizes a permission registration system on reload.

  • This will allow a server admin to choose whatever permission they want for the node, we recommend simplehomes.count.<rank>.
  • This will allow the node to be configurable, so later on if players deserve more homes, instead of changing a permission or having some weird adjustments, they can just change a config file.
  • They can create as many or as few permissions or groups as they need.
  • They can still use the number system, they would just have to manually create it themselves.
  • Removes parsing on our end.
  • homes.count.bypass will ignore whatever homes permission is applied.
  • Highest configured value at the same permission level will be prioritized, so if you have 10, 20, 15 > 20.

An example of this configuration would look something like:

homes-configuration:
  admin:
    permission: "homes.count.admin"
    homes: 10
  player:
    permission: "homes.count.player"
    homes: 3

There is also a configuration option that currently exists with a default number of homes. This will be kept in the event that no permission is specified.

Command Layout

The primary commands will be:

Command Description
/home Automatically sends you to:
/home home
/home bed (if enabled)
or your only home if just one exists.
/home <home_name> Teleports you to the specified home.
/sethome <home_name> Sets a home with the given name.
/delhome <home_name> Deletes the specified home.
Command Description
/homes Lists all your homes.
/homes admin Help screen for /homes admin subcommands.
/homes admin list <player> Lists all homes belonging to a specific player.
/homes admin tp <player> <home_name> Teleports to a player's specific home.
/homes admin reload Reloads the plugin configuration.
Command Description
/homes admin import all <plugin> Console Only
Imports all players' homes from another plugin.
/homes admin import <player> <plugin> Console Only
Imports homes for a specific player from another plugin.

Command overrides with -o will be kept on /sethome and /home allowing users to overwrite an existing home (/sethome) and teleport to a home that may fail it's safety checks (/home).

Command Validation

Currently homes are not validated against any RegEx. Homes should be alphanumeric with underscores and dashes only.

This validation should only be applied when a home is being set.

Imported homes will contain a colon delimiter.

This setting is not configurable.

Home Routing Order

/home has a default routing order. If a home is not specified:

  1. A home named home.
  2. A home if this is the only home other than the bed home.
  3. A bed home.

So for example...

Homes Routed Home
home, bed home
home, base home
base, bed base
base, farm, bed bed
base, farm null

SQL

Currently the SQL table is:

CREATE TABLE IF NOT EXISTS homes (
    player_uuid_and_name VARCHAR (255) PRIMARY KEY,
    player_uuid VARCHAR(36),
    home_name VARCHAR(255),
    world_uuid VARCHAR(255),
    world_name VARCHAR(255),
    location_x DOUBLE,
    location_y DOUBLE,
    location_z DOUBLE,
    yaw FLOAT,
    pitch FLOAT
);

Propose to have it changed into

CREATE TABLE IF NOT EXISTS homes (
    player_uuid VARCHAR(36) NOT NULL,
    home_name VARCHAR(255) NOT NULL COLLATE NOCASE,
    world_uuid VARCHAR(36) NOT NULL,
    x DOUBLE NOT NULL,
    y DOUBLE NOT NULL,
    z DOUBLE NOT NULL,
    yaw FLOAT,
    pitch FLOAT,
    PRIMARY KEY (player_uuid, home_name)
);

CREATE INDEX IF NOT EXISTS idx_homes_name ON homes(home_name);

Because:

  • Primary Key should be a composite key, rather than a single column acting as a composite key.
  • COLLATE NOCASE allows for comparisons to be done case-insensitive, including on insert and select without specifying COLLATE NOCASE in the query.
    • It is important to note that COLLATE NOCASE only works on ASCII only characters. Unicode will fail to be case-insensitive on this. Is this important?
  • world_name is not necessary. If a world gets deleted, assume that the home is invalid.
    • If world_name is needed for any reason (like a message), generally retrieving the world from world_uuid will yield the world alongside the name information.
  • Index has to be created since player_uuid + home_name (and consequently player_uuid) won't have performance impacts when searching on them since Primary Key creates the index. home_name is not indexed on it's own so a separate index needs to be defined.
  • world_uuid, x, y, and z are all marked as NOT NULL as well. These should never be null. yaw and pitch should never be null arguably but I am not sure that really matters. Enforce NOT NULL if there really isn't a reason they should be null so we don't insert invalid data, but we can still teleport when only given the world, x, y, and z.

To do this:

There should be an additional table keeping track of the table version.

CREATE TABLE IF NOT EXISTS version (
    schema_version INTEGER NOT NULL PRIMARY KEY
);

Table existence (for Version 1) can be checked using

SELECT name FROM sqlite_master WHERE type='table' AND name='version';

Any subsequent version should check the version number which can be done with

SELECT schema_version FROM version;

This should always return a single row (or empty for version 1).
When migrating, drop the row and insert a new one with the new migration number.

Important

Do we want to add additional logging such as when migrations ran instead of just keeping the current version in there?

Bear in mind that these instructions are for SQLite. MySQL utilizes utf8mb4_unicode_ci instead of SQLite's COLLATE NOCASE.

Homes Table Migration Strategy (v1 > v2)

Approach: Create > Copy > Drop > Rename

SQLite does not support dropping columns or redefining primary keys via ALTER TABLE, so both backends use the same approach for consistency.

Steps (run on startup if schema_version = 1 or no version table exists):

  1. Rename existing homes to homes_v1
  2. Create new homes table with the v2 schema (composite PK, COLLATE NOCASE, no
    world_name, NOT NULL constraints, index)
  3. Copy data:
INSERT OR IGNORE INTO homes (player_uuid, home_name, world_uuid, x, y, z, yaw, pitch)
SELECT player_uuid, home_name, world_uuid, x, y, z, yaw, pitch                       
FROM homes_v1

For MySQL, it is INSERT IGNORE instead of INSERT OR IGNORE

  1. Drop homes_v1
  2. Insert or update schema_version to 2

Edge Case: Case-Insensitive Duplicates

A player could have both Home and home in v1, valid under the old schema, but a PK collision under COLLATE NOCASE. Rather than skipping duplicates, conflicting homes are renamed by appending an incrementing number until a unique name is found (e.g., home > home_1 > home_2).

Log every rename using the import-log format:

RENAMED: <player_uuid> | <old_home_name> > <new_home_name> (case-insensitive duplicate)

This ensures no homes are lost during migration.

Failure Handling

If any step fails mid-migration:

  • homes_v1 still exists, so no data is lost
  • If homes_v1 exists during startup, assume migration failed and reattempt migration, regardless of the state of homes.
  • Log the failure clearly so admins are aware

Existing Features

The following features will be kept, but the internal code / logic may change.

  • Safety Checks: All safety checks will remain as is.
  • Teleport Delay: Teleport delay and bypass permission will remain.
  • Lockout System: Lockout system will be adjusted to only lockout the command /home.
    • /sethome already prevents you from oversetting homes.
    • /delhome should be allowed so you can delete homes to remove lockout.
    • Any subsequent permissions will be removed.
  • Bed Home: Bed homes will remain as is.
  • Placeholder API Hook: PAPI Hook will remain as is.

Migration

Overview

Migration from another plugin should not ultimately cause destruction to existing data.

Currently, it appears it may overwrite existing data if the plugin we are importing data from has the same home name.

Solution

We will use a special delimiter that generally would not be accepted by /sethome to indicate the plugin name and home name, similar to how Essentials handles homes from another player.

So for an Essentials home named jared, it may import into SimpleHomes with the name: essentials:jared.

This should prevent any data overwrite unless a home already exists in SimpleHomes with the name essentials:jared, which would usually mean it was already imported prior and is likely the same data.

This should also bypass any sethome limitations as it should only invoke the save homes directly (it does not need to go through any validation checks). There should be no corruption that happens even if a player is online.

Import Logging

Import logging should go to a .log file instead of to the console to allow for someone to go through the errors more concisely. Console spam would not be helpful. Logging should go to ./plugins/SimpleHomes/import-logs/{timestamp}{_player}{_plugin}.log where {_player} is populated if only a specific player was imported.

Example file names are 2026-01-31_13-55-55_Peashooter101_Essentials.log and 2026-01-31_13-55-55_Essentials.log.

It should log every success and failure consistently at the start of a line. For example:

SUCCESS: Imported 'home' for player nil (00000000-0000-0000-0000-000000000000) from Essentials.
FAILURE: Could not find world 'missing-world' for 'home' for player one (00000000-0000-0000-0000-000000000001) from Essentials.
SKIPPED: Player two (00000000-0000-0000-0000-000000000002) already has 'home' from Essentials.

Import Logging Methodology

We should always import by player. So, we can retrieve all the homes of a player first that start with our plugin name.

SELECT * FROM homes WHERE player_uuid='00000000-0000-0000-0000-000000000000' AND name LIKE 'essentials:%'

This will simplify our search by allowing us to match names from the home names in a plugin.

If two names match, log it as skipped and move on.

Otherwise attempt import and log success or failure.

This will also have no negative impact on users who already have homes with a colon in the name as it will skip over those names that match, rather than overwriting it. Users who realize that imported homes they have were not imported can rename their homes and then contact a Server Admin to have their player specifically imported again.

Metrics

We should use both bStats and FastStats.

bStats allows for the general tracking of usage.

FastStats allows for reporting on errors.

Separation of Logic and Code Cleanup

Code needs to be separated based on their uses (ie: Home methods into a HomeHandler, Teleport methods in a TeleportHandler, etc).

We will follow coding standards as closely as we can to our CONTRIBUTING.md as well as from well established development projects such as SimpleNicks.

@Peashooter101 Peashooter101 self-assigned this Apr 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant