{
  "_comment": "Classic v7 / ClassiCube protocol definition. Single source of truth for all packet schemas.",
  "version": 7,
  "stringLength": 64,

  "server": {
    "toClient": {
      "identification": {
        "id": 0,
        "fields": [
          { "name": "protocolVersion", "type": "u8" },
          { "name": "serverName",      "type": "string" },
          { "name": "motd",            "type": "string" },
          { "name": "userType",        "type": "u8" }
        ]
      },
      "ping": {
        "id": 1,
        "fields": []
      },
      "levelInitialize": {
        "id": 2,
        "fields": []
      },
      "levelDataChunk": {
        "id": 3,
        "fields": [
          { "name": "chunkLength",     "type": "i16" },
          { "name": "chunkData",       "type": "bytes", "length": 1024 },
          { "name": "percentComplete", "type": "u8" }
        ]
      },
      "levelFinalize": {
        "id": 4,
        "fields": [
          { "name": "xSize", "type": "i16" },
          { "name": "ySize", "type": "i16" },
          { "name": "zSize", "type": "i16" }
        ]
      },
      "setBlock": {
        "id": 6,
        "fields": [
          { "name": "x",         "type": "i16" },
          { "name": "y",         "type": "i16" },
          { "name": "z",         "type": "i16" },
          { "name": "blockType", "type": "u8" }
        ]
      },
      "spawnPlayer": {
        "id": 7,
        "fields": [
          { "name": "playerId",   "type": "i8" },
          { "name": "playerName", "type": "string" },
          { "name": "x",         "type": "i16" },
          { "name": "y",         "type": "i16" },
          { "name": "z",         "type": "i16" },
          { "name": "yaw",       "type": "u8" },
          { "name": "pitch",     "type": "u8" }
        ]
      },
      "position": {
        "id": 8,
        "fields": [
          { "name": "playerId", "type": "u8" },
          { "name": "x",       "type": "i16" },
          { "name": "y",       "type": "i16" },
          { "name": "z",       "type": "i16" },
          { "name": "yaw",     "type": "u8" },
          { "name": "pitch",   "type": "u8" }
        ]
      },
      "positionOrientation": {
        "id": 9,
        "fields": [
          { "name": "playerId", "type": "u8" },
          { "name": "dx",      "type": "i8" },
          { "name": "dy",      "type": "i8" },
          { "name": "dz",      "type": "i8" },
          { "name": "yaw",     "type": "u8" },
          { "name": "pitch",   "type": "u8" }
        ]
      },
      "positionUpdate": {
        "id": 10,
        "fields": [
          { "name": "playerId", "type": "u8" },
          { "name": "dx",      "type": "i8" },
          { "name": "dy",      "type": "i8" },
          { "name": "dz",      "type": "i8" }
        ]
      },
      "orientationUpdate": {
        "id": 11,
        "fields": [
          { "name": "playerId", "type": "u8" },
          { "name": "yaw",     "type": "u8" },
          { "name": "pitch",   "type": "u8" }
        ]
      },
      "despawnPlayer": {
        "id": 12,
        "fields": [
          { "name": "playerId", "type": "u8" }
        ]
      },
      "message": {
        "id": 13,
        "fields": [
          { "name": "playerId", "type": "u8" },
          { "name": "message",  "type": "string" }
        ]
      },
      "disconnect": {
        "id": 14,
        "fields": [
          { "name": "reason", "type": "string" }
        ]
      },
      "updateUserType": {
        "id": 15,
        "fields": [
          { "name": "userType", "type": "u8" }
        ]
      }
    }
  },

  "client": {
    "toServer": {
      "identification": {
        "id": 0,
        "fields": [
          { "name": "protocolVersion",  "type": "u8" },
          { "name": "username",         "type": "string" },
          { "name": "verificationKey",  "type": "string" },
          { "name": "unused",           "type": "u8", "default": 0 }
        ]
      },
      "setBlock": {
        "id": 5,
        "fields": [
          { "name": "x",         "type": "i16" },
          { "name": "y",         "type": "i16" },
          { "name": "z",         "type": "i16" },
          { "name": "mode",      "type": "u8" },
          { "name": "blockType", "type": "u8" }
        ]
      },
      "position": {
        "id": 8,
        "fields": [
          { "name": "playerId", "type": "u8", "default": 255 },
          { "name": "x",       "type": "i16" },
          { "name": "y",       "type": "i16" },
          { "name": "z",       "type": "i16" },
          { "name": "yaw",     "type": "u8" },
          { "name": "pitch",   "type": "u8" }
        ]
      },
      "message": {
        "id": 13,
        "fields": [
          { "name": "unused",  "type": "u8", "default": 255 },
          { "name": "message", "type": "string" }
        ]
      }
    }
  },

  "cpe": {
    "_comment": "CPE (Classic Protocol Extension) packets. Both directions share some IDs.",

    "server": {
      "extInfo": {
        "id": 16,
        "fields": [
          { "name": "appName",        "type": "string" },
          { "name": "extensionCount", "type": "i16" }
        ]
      },
      "extEntry": {
        "id": 17,
        "fields": [
          { "name": "extName", "type": "string" },
          { "name": "version", "type": "i32" }
        ]
      },
      "setClickDistance": {
        "id": 18,
        "fields": [
          { "name": "distance", "type": "i16" }
        ]
      },
      "customBlockSupportLevel": {
        "id": 19,
        "fields": [
          { "name": "supportLevel", "type": "u8" }
        ]
      },
      "holdThis": {
        "id": 20,
        "fields": [
          { "name": "blockToHold",   "type": "u8" },
          { "name": "preventChange", "type": "u8", "default": 0 }
        ]
      },
      "setTextHotKey": {
        "id": 21,
        "fields": [
          { "name": "label",   "type": "string" },
          { "name": "action",  "type": "string" },
          { "name": "keyCode", "type": "i32" },
          { "name": "keyMods", "type": "u8", "default": 0 }
        ]
      },
      "extAddPlayerName": {
        "id": 22,
        "fields": [
          { "name": "nameId",     "type": "i16" },
          { "name": "playerName", "type": "string" },
          { "name": "listName",   "type": "string" },
          { "name": "groupName",  "type": "string" },
          { "name": "groupRank",  "type": "u8" }
        ]
      },
      "extRemovePlayerName": {
        "id": 24,
        "fields": [
          { "name": "nameId", "type": "i16" }
        ]
      },
      "envSetColor": {
        "id": 25,
        "fields": [
          { "name": "variable", "type": "u8" },
          { "name": "r",        "type": "i16" },
          { "name": "g",        "type": "i16" },
          { "name": "b",        "type": "i16" }
        ]
      },
      "makeSelection": {
        "id": 26,
        "fields": [
          { "name": "selectionId", "type": "u8" },
          { "name": "label",       "type": "string" },
          { "name": "startX",      "type": "i16" },
          { "name": "startY",      "type": "i16" },
          { "name": "startZ",      "type": "i16" },
          { "name": "endX",        "type": "i16" },
          { "name": "endY",        "type": "i16" },
          { "name": "endZ",        "type": "i16" },
          { "name": "r",           "type": "i16" },
          { "name": "g",           "type": "i16" },
          { "name": "b",           "type": "i16" },
          { "name": "a",           "type": "i16" }
        ]
      },
      "removeSelection": {
        "id": 27,
        "fields": [
          { "name": "selectionId", "type": "u8" }
        ]
      },
      "setBlockPermission": {
        "id": 28,
        "fields": [
          { "name": "blockType",    "type": "u8" },
          { "name": "allowPlace",   "type": "u8" },
          { "name": "allowDestroy", "type": "u8" }
        ]
      },
      "extAddEntity2": {
        "id": 29,
        "_comment": "Shares ID 0x1D with changeModel (66 bytes). Disambiguated by packet size.",
        "fields": [
          { "name": "entityId",    "type": "i8" },
          { "name": "inGameName",  "type": "string" },
          { "name": "skinName",    "type": "string" },
          { "name": "x",          "type": "i16" },
          { "name": "y",          "type": "i16" },
          { "name": "z",          "type": "i16" },
          { "name": "yaw",        "type": "u8" },
          { "name": "pitch",      "type": "u8" }
        ]
      },
      "changeModel": {
        "id": 29,
        "_comment": "Shares ID 0x1D with extAddEntity2 (138 bytes). Disambiguated by packet size (66).",
        "size": 66,
        "fields": [
          { "name": "entityId",  "type": "u8" },
          { "name": "modelName", "type": "string" }
        ]
      },
      "setMapEnvAppearance": {
        "id": 30,
        "fields": [
          { "name": "textureUrl", "type": "string" },
          { "name": "sideBlock",  "type": "u8" },
          { "name": "edgeBlock",  "type": "u8" },
          { "name": "sideLevel",  "type": "i16" }
        ]
      },
      "envSetWeatherType": {
        "id": 31,
        "fields": [
          { "name": "weatherType", "type": "u8" }
        ]
      },
      "hackControl": {
        "id": 32,
        "fields": [
          { "name": "flying",          "type": "u8" },
          { "name": "noClip",          "type": "u8" },
          { "name": "speeding",        "type": "u8" },
          { "name": "spawnControl",    "type": "u8" },
          { "name": "thirdPersonView", "type": "u8" },
          { "name": "jumpHeight",      "type": "i16" }
        ]
      },
      "defineBlock": {
        "id": 35,
        "_comment": "80 bytes. Byte 79 is reserved for future fogDensity (v2 uses it, v1 sends 0).",
        "fields": [
          { "name": "blockId",        "type": "u8" },
          { "name": "blockName",      "type": "string" },
          { "name": "solidity",       "type": "u8" },
          { "name": "movementSpeed",  "type": "u8" },
          { "name": "topTexture",     "type": "u8" },
          { "name": "leftTexture",    "type": "u8" },
          { "name": "rightTexture",   "type": "u8" },
          { "name": "frontTexture",   "type": "u8" },
          { "name": "backTexture",    "type": "u8" },
          { "name": "bottomTexture",  "type": "u8" },
          { "name": "transmitsLight", "type": "u8" },
          { "name": "walkSound",      "type": "u8" },
          { "name": "fullBright",     "type": "u8" },
          { "name": "shape",          "type": "u8" },
          { "name": "blockDraw",      "type": "u8" },
          { "name": "fogDensity",     "type": "u8", "default": 0 }
        ]
      },
      "removeBlockDefinition": {
        "id": 36,
        "fields": [
          { "name": "blockId", "type": "u8" }
        ]
      },
      "defineBlockExt": {
        "id": 37,
        "_comment": "85 bytes. fog RGB not included in this 85-byte variant (available in later extended variants).",
        "fields": [
          { "name": "blockId",        "type": "u8" },
          { "name": "blockName",      "type": "string" },
          { "name": "solidity",       "type": "u8" },
          { "name": "movementSpeed",  "type": "u8" },
          { "name": "topTexture",     "type": "u8" },
          { "name": "leftTexture",    "type": "u8" },
          { "name": "rightTexture",   "type": "u8" },
          { "name": "frontTexture",   "type": "u8" },
          { "name": "backTexture",    "type": "u8" },
          { "name": "bottomTexture",  "type": "u8" },
          { "name": "transmitsLight", "type": "u8" },
          { "name": "walkSound",      "type": "u8" },
          { "name": "fullBright",     "type": "u8" },
          { "name": "minX",           "type": "u8" },
          { "name": "minY",           "type": "u8" },
          { "name": "minZ",           "type": "u8" },
          { "name": "maxX",           "type": "u8" },
          { "name": "maxY",           "type": "u8" },
          { "name": "maxZ",           "type": "u8" },
          { "name": "blockDraw",      "type": "u8" },
          { "name": "fogDensity",     "type": "u8", "default": 0 }
        ]
      },
      "bulkBlockUpdate": {
        "id": 38,
        "_comment": "1282 bytes. count is 0-indexed (0 = 1 update). indices and blockTypes are always 256-element fixed arrays.",
        "fields": [
          { "name": "count",      "type": "u8" },
          { "name": "indices",    "type": "i32array", "count": 256 },
          { "name": "blockTypes", "type": "u8array",  "count": 256 }
        ]
      },
      "setTextColor": {
        "id": 39,
        "fields": [
          { "name": "r",    "type": "u8" },
          { "name": "g",    "type": "u8" },
          { "name": "b",    "type": "u8" },
          { "name": "a",    "type": "u8" },
          { "name": "code", "type": "u8" }
        ]
      },
      "setMapEnvUrl": {
        "id": 40,
        "fields": [
          { "name": "textureUrl", "type": "string" }
        ]
      },
      "setMapEnvProperty": {
        "id": 41,
        "fields": [
          { "name": "property", "type": "u8" },
          { "name": "value",    "type": "i32" }
        ]
      },
      "setEntityProperty": {
        "id": 42,
        "fields": [
          { "name": "entityId",     "type": "u8" },
          { "name": "propertyType", "type": "u8" },
          { "name": "value",        "type": "i32" }
        ]
      },
      "twoWayPing": {
        "id": 43,
        "fields": [
          { "name": "direction", "type": "u8" },
          { "name": "data",      "type": "u8" }
        ]
      },
      "setInventoryOrder": {
        "id": 44,
        "fields": [
          { "name": "order",     "type": "u8" },
          { "name": "blockType", "type": "u8" }
        ]
      }
    },

    "client": {
      "extInfo": {
        "id": 16,
        "fields": [
          { "name": "appName",        "type": "string" },
          { "name": "extensionCount", "type": "i16" }
        ]
      },
      "extEntry": {
        "id": 17,
        "fields": [
          { "name": "extName", "type": "string" },
          { "name": "version", "type": "i32" }
        ]
      },
      "customBlockSupportLevel": {
        "id": 19,
        "fields": [
          { "name": "supportLevel", "type": "u8" }
        ]
      },
      "playerClicked": {
        "id": 34,
        "fields": [
          { "name": "button",     "type": "u8" },
          { "name": "action",     "type": "u8" },
          { "name": "yaw",        "type": "u16" },
          { "name": "pitch",      "type": "i16" },
          { "name": "targetId",   "type": "u8" },
          { "name": "targetX",    "type": "i16" },
          { "name": "targetY",    "type": "i16" },
          { "name": "targetZ",    "type": "i16" },
          { "name": "targetFace", "type": "u8" }
        ]
      },
      "twoWayPing": {
        "id": 43,
        "fields": [
          { "name": "direction", "type": "u8" },
          { "name": "data",      "type": "u8" }
        ]
      }
    }
  }
}
