Minecraft Region Manager

This **project** is intended to ease builds backup/restore during Lord Of The Ring mod map resets, but has no dependency with this mod, and thus will operate perfectly on servers not using it.

While it would have been more universal to do it as a server-sided mod, I'm making it as a plugin as most LOTR servers are already using some version of Bukkit server software and the official server has its own world reset organization. Furthermore, the Bukkit API is better documented.

The documentation below outlines available functions, as well as not yet implemented ones, in order to give you an idea of future directions.

It is organised around several functional layers:

## Marking places

All the following commands are user accessible.

They are intended for a player to manage his own "places to backup" list.

The resulting lists are saved in a per player UUID named file in the "userdata" plugin subdirectory.

Note that this two step process (marking/backuping) is intentional: players would be able to cheat (duplicating items and entities) if they had direct saving command access (by saving a region with their valuables then moving them in another region to be saved).

**/showlocation** or **/hsl**: display the player's location in block, chunk and region coordinates, the dimension where (s)he is, the distance to the chunk/region borders in the four polar directions, and if that chunk and region are marked (for operators, it will analyse all players marks).

**/markregion** or **/hmr**: mark the world/region file you are in and name it (for player convenience).

**/markchunk** or **/hmc**: mark the world/region file/chunk you are in and name it.

**/markarea** or **/hma**: mark the world/region file/chunks between the 2 opposite corners you call the command from and name it (you can provide the name at first, second or both call). By default, the length and width of the area you mark are limited to 320 chunks (more than 5000 blocks), of course in the same dimension. This limit is tunable in the plugin's config.yml file.

**/unmarkregion** or **/hur**: unmark the world/region file you are in.

**/unmarkchunk** or **/huc**: unmark the world/region file/chunk you are in.

**/unmarkarea** or **/hua**: unmark all marked areas you are in.

**/unmarkeverything** or **/hue**: unmark everything you marked, whether regions, chunks or areas.

**/listmarks** or **/hlm**: list all regions/chunks/areas you have marked.

**/showmarks** or **/hsm**: use a Minecraft map or perhaps some visual effects on the borders, to show marked places.

## Reporting things to the admins

#### User accessible commands

**/reportregion** or **/hrr**: mark the world/region file you are in in a separate admin targeted list, along with a reason:

* generation - for reporting a generation issue (cliff at the border, wrong biome)
* griefing - for reporting a griefing issue (vandalism)
* offensive - for reporting an offensive build / sign issue
* corruption - for a corrupted region issue (crash, fall in the void)

**/reportchunk** or **/hrc**: same at the chunk level.

#### Operator accessible commands

**/listreports** or **/hlr**: list all regions/chunks that have been reported.

*No-op concept*. My goal as an admin is to automate things as much as possible. In order to achieve that, I'm thinking about defining a (configurable) reporting threshold which would cause a necessary action to be automatically triggered. Reports made by operators would also immediately trigger the action.

The automatable actions would be:

* border smoothing for a generation report
* restoration for a griefing report
* deletion for a corruption report

Offensive things would still need a human evaluation before any correction.

*Reputation concept*. Users won't be all equals. They would gain reputation for relevant reports, and lose reputation for unnecessary or misleading reports. This would influence the threshold above. The **/listreports** command would need to be modified, to order the list by decreasing (reporters x reputation) score.

The following operator accessible commands would need to be added:

**/clearregion** or **/hcr**: would remove the report from the list after admin or automated action. A reputation modifier would be given as a parameter. For example, /clearregion 1 would add 1 to the reputation score of reporters. /clearregion -5 would substract 5 to the reputation of reporters.

**/clearchunk** or **/hcc**: same at the chunk level.

**/deleteregion** or **/hdr**: after a validation prompt, delete the region file at the given region coordinates (after verifying nobody is inside and successfully unloading any included chunk).

**/deletechunk** or **/hdc**: same at the chunk level (with a modification of the region file).

**/restoreregion** or **/hrtr**: after a validation prompt, use an available backup to restore the region file at the given region coordinates (after verifying nobody is inside and successfully unloading any included chunk). This would be a nice anti-griefing tool, probably only for spawns or special buildings, as otherwise there would be a risk of cheating by malicious users (duplicating items in chests...).

**/restorechunk** or **/hrtc**: same at the chunk level (with a modification of the region file).

**/restorearea** or **/hrta**: although I won't provide a /reportarea command, this command would probably be better than the 2 previous ones. This requires some additional thinking...

**/smoothregion** or **/hsr**: after a validation prompt, load the region at the given coordinates and modify its borders to fit better with its neighbors.

**/smoothchunk** or **/hsc**: same at the chunk level.

## Managing Points of Interest

#### User accessible commands

**/namepoi** or **/hnp** : name a Point of Interest (x/z chunk coordinate) to be displayed in some cartography software such as the Minecraft Overviewer. Recalling the command in the same chunk with a different name would rename the POI, or would delete it with an empty name.

## Backuping / restoring places

#### User accessible commands

**/backuparea**: independently of the lists of marks, immediately backup the specified object. For later restoration, you need to provide a name for the area.

#### Operator accessible commands

**/backupregion**, **/backupchunk**: independently of the lists of marks, immediately backup the specified object.

The corresponding **/restoreregion**, **/restorechunk** and **/restorearea** commands have been outlined in the "Reporting things to the admins" chapter. They will also be accessible from the console.

#### Console commands

The following command is accessible only from the console, preferably on a whitelisted server, without any player connected in the dimension you want to reset:

**/resetmap**: you'll have to call that command twice. The first time it will list the worlds (dimensions) that you have and what is marked inside them. It will peculiarly give you their world UID, which you'll use as a parameter to the second command call if you want to reset that world (that complex string will serve as a confirmation token of your acceptance of possible consequences!). Even for huge worlds, the command should complete in a couple of minutes...

An example run:

```
resetmap
BEFORE RESETTING A WORLD MAKE SURE NO ONE IS CONNECTED (WHITELIST YOUR SERVER!)

Worlds list:
  world
  - UID                = 51e4f694-bbc8-422d-829a-32577a453aeb
  - Environment        = NORMAL
  - Logged players     = 0
  - Loaded chunks      = 257
  - Regions            = 3.456 (2.547.638.272 bytes)
  - Marked regions     = 14
    - Whole regions    = 7
    - Partial regions  = 7 (195 isolated chunks)
  In case of map reset, 0.20805642% of this world would be preserved.

  world/DIM101
  - UID                = 0748a973-fe30-4ebd-9294-b539d2a08de4
  - Environment        = LOTRUTUMNO
  - Logged players     = 0
  - Loaded chunks      = 0
  - Regions            = 189 (456.282.112 bytes)
  - Marked regions     = 0

  world/DIM100
  - UID                = 211e6fca-6bad-4032-8bf7-60e2de1af1ca
  - Environment        = LOTRMIDDLEEARTH
  - Logged players     = 0
  - Loaded chunks      = 0
  - Regions            = 48.297 (145.366.765.568 bytes)
  - Marked regions     = 409
    - Whole regions    = 133
    - Partial regions  = 276 (33.978 isolated chunks)
  In case of map reset, 0.34408274% of this world would be preserved.

  world/DIM-1
  - UID                = 4ec0ea6f-143a-4964-8bdf-75ad109de91b
  - Environment        = NETHER
  - Logged players     = 0
  - Loaded chunks      = 0
  - Regions            = 319 (379.514.880 bytes)
  - Marked regions     = 2
    - Whole regions    = 1
    - Partial regions  = 1 (19 isolated chunks)
  In case of map reset, 0.31929615% of this world would be preserved.

resetmap 211e6fca-6bad-4032-8bf7-60e2de1af1ca
Resetting map world/DIM100:
Step 1: Unload and save loaded chunks.
- Unloaded and saved 0 chunks out of 0.
Step 2: Create backup and pruned subdirectories.
Step 3: Move the existing region files in the backup directory.
Step 4: Copy back the wholly marked region files.
- Copied 133 files.
Step 5: Prune the partial region files.
- Pruned 276 files.
  - Preserved 33.978 chunks.
  - Deleted 227.926 chunks.
  - Left out 20.720 empty chunks.
Step 6: Copy back the pruned region files.
- Copied 276 files.
Done!

```
As you can see above, the command will make a backup directory with all of your previous region files. If it needs to delete chunks in some of them, it will do so in a copy located in the pruned directory. If there are any peculiar issues, you'll be told if you need to fix things manually. In most cases, that would mean copying files still loaded in Minecraft (for example, a permanently loaded spawn area). Should you run that command several times on the same world, it would rename any previously found backup and pruned directories, so you won't lose anything...

## Using region files repositories

The goal of these functions is to allow the distribution and automated insertion of massive structures in your servers (for example, Minas Tirith in LOTR servers).

Schematics files are not appropriate for this as the surrounding countryside is often as important as the builds themselves (imagine Rivendell without the scenery...).

Region files are more interesting but not sufficient, as the blocks identifiers they contain may be specific to the server they come from. In games like the Minecraft LOTR mod, they are positional: a peculiar location always has the same region coordinates, which makes things easier.

Zip files containing region files with just the relevant chunks generated PLUS the server level.dat file for information on the original block identifiers MINUS the world seed are the way to go!

(to be done. Admin only: /addrepository /removerepository /listrepositories /searchrepository /importfromrepository : the last one would restore a specific region file and merge a partial one with the existing one (with prior confirmation in this case)

## Terrain smoothing

This would essentially be needed in 3 cases:

* After a map reset, when the server would start regenerating chunks around restored regions/chunks, IF the generation algorithm for this area has changed
* After deleting a region/chunk, when the server would start regenerating it, IF the generation algorithm for this area has changed
* After importing a region from a repository, that region having been generated on another server with a different world seed

(to be done)

## Other ideas

#### Console commands

The following command is currently accessible only from the console:

**/verifyregion** or **/hvr**: test if the region file you specify is valid (ie. it exists, has a valid structure, a correct file size, doesn't contain empty chunks (though ungenerated chunks are OK), has correct chunks length, compression types and compressed data, a valid NBT structure in uncompressed data, no unknown blocks and items IDs in chunks). You can either specify a region file with a {world name, region x, region z} triplet, or just provide a world name in order to test all the region files in a dimension.

(to be done. Admin only: region analysis ((un)generated - (un)loaded - (un)marked chunks), block distribution, chests / beds / spawners / blocks locator, entities counter / lister / clearer, ...)

## Discarded ideas & design notes

At first, I thought about providing regions/chunks border/center highlighting (with a beacon like effect), but there are already existing mods to do that (for example, the Chunk Highlighter mod, although it is not for MC 1.7.10), and there was (apparently) no way to do that with the Bukkit API as it is only server side. It was still possible to use particles effects visible only to the requesting player, but without control on their duration. I also considered displaying minimaps (32x32 for region's chunks, and 16x16 for chunk's blocks) to show the player's location, but the Minecraft chat is limited to 20 lines and it is difficult to use special characters for a more satisfying rendition (though not impossible, at the price of linking to the Craftbukkit jar).

=> I finally provided the /ShowLocation command to display the player's location in the 3 sets of coordinates (block/chunk/region) and its distance to the chunk/region borders in all polar directions.

=> I kept the possibility of making a /ShowMarks command using Minecraft Maps (which I have no experience with, yet) or the interesting PlayEffect plugin.

I thought about providing a way to automatically mark every (player?) LOTR custom waypoint, but this would introduce a little dependancy between this plugin and the LOTR mod, and probably mark numerous useless spots...

=> Anyway, this would be better done through a system level command to be used for the first map reset before players make an habit of marking their builds.

For area marks, my first thought was to use some kind of special corner block, but this is unneeded, and 2 corner marks are enough.

For reported areas, I thought about providing an additional parameter indicating an action request (smooth, restore, delete) but this was unnecessary as these actions were implicit.

For the backup & restore commands, they would have been more efficient and reliable if done outside Minecraft in an external utility, but I decided to include them in this plugin for the many people without command line access to their servers (or rather, hosting solutions).

## Similar projects

Apart from Mevans' Joetater (look here for a detailed comparison), I found an unfinished project called Static Chunk Manager with similar objectives. However, they both only cover the backup part of the process.

For border smoothing, there are 2 tools available: BestOfBoth and MCMerge (a followup to the first one. Check this tutorial). They both work by placing a river at the boundaries between the old and new map areas, and smoothing the surrounding valley seamlessly together with adjacent chunks. This is not the way I want to go. I'm rather thinking of adjusting the terrain to level height differences between regions and chunks at their borders.

## Project origin

The design outlined above has been defined and refined through several discussions:

* Massive structures now!
* Joetater: A Region Saver
* Help/Regenerating chunks
* It's a hARDA world LOTR Server on the LOTR wikia

## Download and contribution

The plugin binary Jar file is available for download and comment on Bukkit Dev and Curse.

This plugin's source code is available on GitHub for download or community improvement. Create a *new branch* with your edits and ask for a *pull request* to merge them in the *master branch* (check this tutorial to understand GitHub concepts).