Skip to content

Making Protections

Sergiu Muresan edited this page Sep 22, 2015 · 36 revisions

The reasons:

Protections are a big part of the MyTown2 project and is something incredibly difficult to maintain due to the everchanging environment of Minecraft and its modding community.

There are two reasons we have created the current protection system:

  1. The difficulty of maintaining a protection system that takes into account basically any mod.
  2. Not many people know how to program in Java (at least not in the Minecraft community). This system requires minimal knowledge of Java.

Introduction:

The protection system is based on reading a set of files, each file representing a protection "dictionary" for a mod, we'll call those protections or protection files.

Each of the file is broken down into, so called, segments. Each segment represents something in the mod (entity, tile entity, item, block etc.). The segments tell the protection system what each thing does.

Example: a segment can tell the system that the Creeper from vanilla Minecraft is a hostile mob that will attack the player when it sees it. The system can use this information to control exactly which mob can spawn in Towns or Plots.

Protection files

  • Each protection file is in json format (more information about the format can be found HERE) and needs to be saved as (any_name).json
  • There are only three elements that are needed in each of the protection files:
    • modid (of type STRING) is the unique identifier of the mod you want to protect against
    • version (of type STRING) is the minimum version to which this mod is compatible. The system simply performs a startsWith check against the mod version.

Example: if the version that is specified is 0.1 and the mod's actual version is 0.1.10b the protection will initialize, but if the mod's version is 0.2.20 it will not because 0.2.20 does not start with 0.1. * segments (of type ARRAY) which represents an array of all the segments.

Types of data in the JSON files:

  • STRING - a sequence of characters surrounded by "" or by '' when used inside the condition element
  • INTEGER - an integer
  • ARRAY of SOMETHING - a sequence of things surrounded by [] and the character , between each of them
  • OBJECT - a set of elements and values surrounded by {} and the character , between each element-value pair.
  • ELEMENT - an identifier for the information given after it surrouonded by "" and followed by the character :
  • CALLER - essentially an OBJECT but with the properties of having the elements:
    • type (of type STRING) represents the type of information that needs to be called. This can have the values:
      • METHOD - represents a method
      • FIELD - represents a field
      • FORMULA - represents a formula (it can only return something of type INTEGER)
      • NBT - represents an NBT tag to get the information
    • element (of type STRING) represents the name of the element
    • valueType (of type STRING) [OPTIONAL] represents the class of the object that is should be returned.
  • GETTER - essentially an ARRAY of CALLERS. Uses the first caller on the BASE object given by the type of the segment then all the other callers will be used on the returned object of the previous one. Simply put it's cascading through all the callers.

Example: if we have this getter

"getterExample": [{
  "element":"getName",
  "type":"METHOD"
},
{
  "element":"getFirstCharacter",
  "type":"METHOD"
}]

When this getter is used:

  • the first caller will get the name of the given BASE object
  • the first will give the result to the next one in line, the second caller
  • the second caller will use the name given to it and will return the first character in that line of text
  • the second caller, which is last in line, will return the result to the protection system which then can be used in various ways

Segments

Generic elements for all types of segments:

  • class (of type STRING) represents the class to the object you want to protect against. If the object is an item or block you can use the command /ta debug itemClass while holding it to find its class.
  • type (of type STRING) represents what this segment is supposed to protect. This can have the values: entity, tileEntity, item or block
  • flags (of type STRING or ARRAY of STRING) represents what flag is the segment supposed to check against.

Example: let's say the object we want to protect against is a block breaker in which case the most reasonable flag to set to is modify

  • condition (of type STRING) [OPTIONAL] - a string using the getters that acts as a condition of when the segment should be checked. If this condition returns true the segment is checked.

    • the format of a single condition is getter SIGN value where SIGN can have the values: ==, !=, <, <=, >=, > for the desired mathematical condition (note that the last 4 can only be used for INTEGER types)
    • multiple conditions can be specified with the string AND or OR in between for the desired logical gate.
    • the format of a condition string with multiple conditions should be CONDITION1 AND CONDITION2 or CONDITION1 OR CONDITION2

    Example: let's say we have the getter isActive which determines whether or not the tool is able to break blocks in a 5x5 area or not. We don't want to check to occur when the tool can only break one block (since that is taken care of automatically). Therefore a reasonable condition string would be: isActive == true

Elements for entity segments:

  • actions (of type STRING or ARRAY of STRING) represents how the entity should be handled, the valid values are:
    • TRACKED - marks the entity for being checked every tick (should be used for hostile mobs to stop them from entering/exist in certain towns)
    • PROTECT - marks the entity for being checked whenever a player tries to interact with it (right/left click etc.)
    • PVP - marks the entity for being checked whenever a player is hit by it.
    • if no value is specified it will default to TRACKED

Elements for item segments:

  • actions (of type STRING or ARRAY of STRING) represents how the item should be handled, the valid values are:
    • BREAK_BLOCK - marks the item for being checked when a block is broken with it
    • RIGHT_CLICK_BLOCK - marks the item for being checked when a block is right clicked with it
    • RIGHT_CLICK_AIR - marks the item for being checked when air is right clicked with it
    • RIGHT_CLICK_ENTITY - marks the item for being checked when an entity is right clicked with it
    • LEFT_CLICK_BLOCK - marks the item for being checked when a block is left clicked with it
  • isAdjacent (of type BOOLEAN) represents whether it should check against the block right/left clicked or the one adjacent to it (as if placing the block and checking against that placed block instead of the one that was placed on) (TODO: better explanation)
  • clientUpdate (of type OBJECT) certain actions in the world are not updated properly when denied through the protection. This represents the area in which the server should send a block update event to prevent de-syncs between the client and the server. This object can have two elements:
    • coords (of type ARRAY of 6 INTEGERS) - represents the rectangular box around the coords of the object. All the integers are relative to the block and should be defined in this order: xMin, yMin, zMin, xMax, yMax, zMax
    • directional (of type BOOLEAN) - represents if the client update volume should be translated based on the direction the player is looking.

Elements for block segments:

  • actions (of type STRING or ARRAY of STRING) - represents how the block should be handled, the valid values are:
    • LEFT_CLICK - marks the block for being checked when the block is left clicked
    • RIGHT_CLICK - marks the block for being checked when the block is right clicked
    • ANY_CLICK - marks the block for being checked when the block is left/right clicked
  • meta (of type INTEGER) - represents which meta of the given block this should be checked against.
    • -1 value will ignore the meta of the blocks.
    • if no value is specified it will default to -1
  • clientUpdate (of type OBJECT) certain actions in the world are not updated properly when denied through the protection. This represents the area in which the server should send a block update event to prevent de-syncs between the client and the server. This object can have two elements:
    • coords (of type ARRAY of 6 INTEGERS) - represents the rectangular box around the coords of the clicked block. All the integers are relative to the block and should be defined in this order: xMin, yMin, zMin, xMax, yMax, zMax

Elements for tile entity segments:

  • retainsOwner (of type BOOLEAN) - represents whether or not the protection system should retain the owner of the tile entity (when the block containing that tile entity is placed) and check against the retained player.

Example: let's say we are making a segment for a quarry, if retainsOwner flag is set to true, the quarry will be able to bypass permission based on the owner's permissions.

  • xMin, yMin, zMin, xMax, yMax, zMax (of type GETTERS) - represents the rectangular box in which the check should occur. * if not specified the system will use the range set in the config: defaultProtectionSize